From 745ac1ec19805fce781157ea0a86a040d290a914 Mon Sep 17 00:00:00 2001 From: Nicolas Stepien Date: Fri, 14 Oct 2011 16:29:34 +0200 Subject: [PATCH 001/169] Only listen to resize events with fitheight enabled. --- 4chan_x.user.js | 27 +++++++++++++++++---------- script.coffee | 21 +++++++++++++-------- 2 files changed, 30 insertions(+), 18 deletions(-) diff --git a/4chan_x.user.js b/4chan_x.user.js index 28820f6d7..e96860077 100644 --- a/4chan_x.user.js +++ b/4chan_x.user.js @@ -2803,10 +2803,7 @@ imgExpand = { init: function() { g.callbacks.push(imgExpand.node); - imgExpand.dialog(); - $.bind(window, 'resize', imgExpand.resize); - imgExpand.style = $.addStyle(''); - return imgExpand.resize(); + return imgExpand.dialog(); }, node: function(root) { var a, thumb; @@ -2849,7 +2846,7 @@ } }, typeChange: function(e) { - var klass; + var form, klass; switch (this.value) { case 'full': klass = ''; @@ -2863,7 +2860,17 @@ case 'fit screen': klass = 'fitwidth fitheight'; } - return d.body.className = klass; + form = $('body > form'); + form.className = klass; + if (form.classList.contains('fitheight')) { + $.bind(window, 'resize', imgExpand.resize); + if (!imgExpand.style) { + imgExpand.style = $.addStyle(''); + return imgExpand.resize(); + } + } else if (imgExpand.style) { + return $.unbind(window, 'resize', imgExpand.resize); + } } }, toggle: function(a) { @@ -2937,8 +2944,8 @@ delform = $('form[name=delform]'); return $.prepend(delform, controls); }, - resize: function(e) { - return imgExpand.style.innerHTML = ".fitheight img[md5] + img {max-height:" + d.body.clientHeight + "px;}"; + resize: function() { + return imgExpand.style.innerHTML = ".fitheight img + img {max-height:" + innerHeight + "px;}"; } }; firstRun = { @@ -3157,10 +3164,10 @@ float: left;\ pointer-events: none;\ }\ - img[md5], img[md5] + img {\ + img[md5], img + img {\ pointer-events: all;\ }\ - body.fitwidth img[md5] + img {\ + .fitwidth img + img {\ max-width: 100%;\ width: -moz-calc(100%); /* hack so only firefox sees this */\ }\ diff --git a/script.coffee b/script.coffee index ea8eb5f4a..de282e58b 100644 --- a/script.coffee +++ b/script.coffee @@ -2062,9 +2062,6 @@ imgExpand = init: -> g.callbacks.push imgExpand.node imgExpand.dialog() - $.bind window, 'resize', imgExpand.resize - imgExpand.style = $.addStyle '' - imgExpand.resize() node: (root) -> return unless thumb = $ 'img[md5]', root @@ -2094,7 +2091,15 @@ imgExpand = klass = 'fitheight' when 'fit screen' klass = 'fitwidth fitheight' - d.body.className = klass + form = $('body > form') + form.className = klass + if form.classList.contains 'fitheight' + $.bind window, 'resize', imgExpand.resize + unless imgExpand.style + imgExpand.style = $.addStyle '' + imgExpand.resize() + else if imgExpand.style + $.unbind window, 'resize', imgExpand.resize toggle: (a) -> thumb = a.firstChild @@ -2151,8 +2156,8 @@ imgExpand = delform = $ 'form[name=delform]' $.prepend delform, controls - resize: (e) -> - imgExpand.style.innerHTML = ".fitheight img[md5] + img {max-height:#{d.body.clientHeight}px;}" + resize: -> + imgExpand.style.innerHTML = ".fitheight img + img {max-height:#{innerHeight}px;}" firstRun = init: -> @@ -2418,10 +2423,10 @@ Main = float: left; pointer-events: none; } - img[md5], img[md5] + img { + img[md5], img + img { pointer-events: all; } - body.fitwidth img[md5] + img { + .fitwidth img + img { max-width: 100%; width: -moz-calc(100%); /* hack so only firefox sees this */ } From 99a2786c5cd00b03c94ea21bfed33c41d7786c78 Mon Sep 17 00:00:00 2001 From: Nicolas Stepien Date: Sat, 15 Oct 2011 00:19:13 +0200 Subject: [PATCH 002/169] d.body.clientHeight to fit with vertical/horizontal scrollbars. --- script.coffee | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/script.coffee b/script.coffee index de282e58b..112c4f2f2 100644 --- a/script.coffee +++ b/script.coffee @@ -2157,7 +2157,7 @@ imgExpand = $.prepend delform, controls resize: -> - imgExpand.style.innerHTML = ".fitheight img + img {max-height:#{innerHeight}px;}" + imgExpand.style.innerHTML = ".fitheight img + img {max-height:#{d.body.clientHeight}px;}" firstRun = init: -> From c38b07a0550fbcbeed76304d9e7a16ab592bffe4 Mon Sep 17 00:00:00 2001 From: Nicolas Stepien Date: Sat, 15 Oct 2011 00:20:38 +0200 Subject: [PATCH 003/169] Compile. --- 4chan_x.user.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/4chan_x.user.js b/4chan_x.user.js index 9f3d860ff..99792b06c 100644 --- a/4chan_x.user.js +++ b/4chan_x.user.js @@ -2866,8 +2866,8 @@ $.bind(window, 'resize', imgExpand.resize); if (!imgExpand.style) { imgExpand.style = $.addStyle(''); - return imgExpand.resize(); } + return imgExpand.resize(); } else if (imgExpand.style) { return $.unbind(window, 'resize', imgExpand.resize); } @@ -2945,7 +2945,7 @@ return $.prepend(delform, controls); }, resize: function() { - return imgExpand.style.innerHTML = ".fitheight img + img {max-height:" + innerHeight + "px;}"; + return imgExpand.style.innerHTML = ".fitheight img + img {max-height:" + d.body.clientHeight + "px;}"; } }; firstRun = { From d131621b9efbba06036ea7858ef3a6c81e507986 Mon Sep 17 00:00:00 2001 From: Nicolas Stepien Date: Tue, 18 Oct 2011 16:09:34 +0200 Subject: [PATCH 004/169] Init time offset and g.hiddenReplies earlier. --- 4chan_x.user.js | 13 ++++++------- script.coffee | 12 ++++++------ 2 files changed, 12 insertions(+), 13 deletions(-) diff --git a/4chan_x.user.js b/4chan_x.user.js index 3e674a0d6..a521120e1 100644 --- a/4chan_x.user.js +++ b/4chan_x.user.js @@ -518,6 +518,11 @@ } else { g.PAGENUM = parseInt(temp) || 0; } + g.hiddenReplies = $.get("hiddenReplies/" + g.BOARD + "/", {}); + g.chanOffset = 5 - new Date().getTimezoneOffset() / 60; + if ($.isDST()) { + g.chanOffset--; + } $$ = function(selector, root) { if (root == null) { root = d.body; @@ -2963,7 +2968,7 @@ }; Main = { init: function() { - var cutoff, hiddenThreads, id, lastChecked, nodes, now, timestamp, tzOffset, _ref; + var cutoff, hiddenThreads, id, lastChecked, nodes, now, timestamp, _ref; $.unbind(document, 'DOMContentLoaded', Main.init); if (location.hostname === 'sys.4chan.org') { QR.sys(); @@ -2978,12 +2983,6 @@ } $.bind(window, 'message', Main.message); Favicon.init(); - g.hiddenReplies = $.get("hiddenReplies/" + g.BOARD + "/", {}); - tzOffset = (new Date()).getTimezoneOffset() / 60; - g.chanOffset = 5 - tzOffset; - if ($.isDST()) { - g.chanOffset--; - } lastChecked = $.get('lastChecked', 0); now = Date.now(); if (lastChecked < now - 1 * DAY) { diff --git a/script.coffee b/script.coffee index e13e34908..01bba707c 100644 --- a/script.coffee +++ b/script.coffee @@ -378,6 +378,12 @@ if temp is 'res' else g.PAGENUM = parseInt(temp) or 0 +g.hiddenReplies = $.get "hiddenReplies/#{g.BOARD}/", {} +# GMT -8 is given as +480; would GMT +8 be -480 ? +g.chanOffset = 5 - new Date().getTimezoneOffset() / 60 +# 4chan = EST = GMT -5 +g.chanOffset-- if $.isDST() + $$ = (selector, root=d.body) -> Array::slice.call root.querySelectorAll selector @@ -2248,12 +2254,6 @@ Main = $.bind window, 'message', Main.message Favicon.init() - g.hiddenReplies = $.get "hiddenReplies/#{g.BOARD}/", {} - tzOffset = (new Date()).getTimezoneOffset() / 60 - # GMT -8 is given as +480; would GMT +8 be -480 ? - g.chanOffset = 5 - tzOffset - # 4chan = EST = GMT -5 - g.chanOffset-- if $.isDST() lastChecked = $.get 'lastChecked', 0 now = Date.now() From b3c4dc3d8b3c40fb9a29af7f4993bbd7f2529355 Mon Sep 17 00:00:00 2001 From: Nicolas Stepien Date: Tue, 18 Oct 2011 18:03:46 +0200 Subject: [PATCH 005/169] Remove unnecessary (e)s. --- 4chan_x.user.js | 36 ++++++++++++++++++------------------ script.coffee | 36 ++++++++++++++++++------------------ 2 files changed, 36 insertions(+), 36 deletions(-) diff --git a/4chan_x.user.js b/4chan_x.user.js index a521120e1..c56782b70 100644 --- a/4chan_x.user.js +++ b/4chan_x.user.js @@ -275,7 +275,7 @@ return style.right = clientWidth - clientX + 45; } }, - hoverend: function(e) { + hoverend: function() { return ui.el.parentNode.removeChild(ui.el); } }; @@ -689,7 +689,7 @@ return _results; }, cb: { - toggle: function(e) { + toggle: function() { var thread; thread = this.parentNode; return expandThread.toggle(thread); @@ -799,12 +799,12 @@ }); }, cb: { - hide: function(e) { + hide: function() { var reply; reply = this.parentNode.nextSibling; return replyHiding.hide(reply); }, - show: function(e) { + show: function() { var div, table; div = this.parentNode; table = div.nextSibling; @@ -1360,7 +1360,7 @@ options.time.call(time); return options.backlink.call(back); }, - clearHidden: function(e) { + clearHidden: function() { $["delete"]("hiddenReplies/" + g.BOARD + "/"); $["delete"]("hiddenThreads/" + g.BOARD + "/"); this.textContent = "hidden: 0"; @@ -1376,14 +1376,14 @@ $.set(this.name, key); return conf[this.name] = key; }, - time: function(e) { + time: function() { $.set('time', this.value); conf['time'] = this.value; Time.foo(); Time.date = new Date(); return $('#timePreview').textContent = Time.funk(Time); }, - backlink: function(e) { + backlink: function() { $.set('backlink', this.value); conf['backlink'] = this.value; return $('#backlinkPreview').textContent = conf['backlink'].replace(/%id/, '123456789'); @@ -1827,12 +1827,12 @@ return _results; }, cb: { - hide: function(e) { + hide: function() { var thread; thread = this.parentNode.parentNode; return threadHiding.hide(thread); }, - show: function(e) { + show: function() { var thread; thread = this.parentNode.parentNode; return threadHiding.show(thread); @@ -2099,10 +2099,10 @@ return _results; }, cb: { - toggle: function(e) { + toggle: function() { return watcher.toggle(this.parentNode); }, - x: function(e) { + x: function() { var board, id, _, _ref; _ref = this.nextElementSibling.getAttribute('href').substring(1).split('/'), board = _ref[0], _ = _ref[1], id = _ref[2]; return watcher.unwatch(board, id); @@ -2664,7 +2664,7 @@ return Favicon.update(); } }, - scroll: function(e) { + scroll: function() { var bottom, height, i, reply, _len, _ref; updater.focus = true; height = d.body.clientHeight; @@ -2769,7 +2769,7 @@ return $.bind(thumb, 'mouseout', ui.hoverend); }); }, - mouseover: function(e) { + mouseover: function() { ui.el = $.el('img', { id: 'iHover', src: this.parentNode.href @@ -2832,7 +2832,7 @@ e.preventDefault(); return imgExpand.toggle(this); }, - all: function(e) { + all: function() { var thumb, _i, _j, _len, _len2, _ref, _ref2, _results, _results2; imgExpand.on = this.checked; if (imgExpand.on) { @@ -2853,7 +2853,7 @@ return _results2; } }, - typeChange: function(e) { + typeChange: function() { var klass; switch (this.value) { case 'full': @@ -2899,13 +2899,13 @@ thumb.hidden = true; return $.add(a, img); }, - error: function(e) { + error: function() { var req, thumb; thumb = this.previousSibling; imgExpand.contract(thumb); if (navigator.appName !== 'Opera') { req = $.ajax(this.src, null, 'head'); - return req.onreadystatechange = function(e) { + return req.onreadystatechange = function() { if (this.status !== 404) { return setTimeout(imgExpand.retry, 10000, thumb); } @@ -2942,7 +2942,7 @@ delform = $('form[name=delform]'); return $.prepend(delform, controls); }, - resize: function(e) { + resize: function() { return imgExpand.style.innerHTML = ".fitheight img[md5] + img {max-height:" + d.body.clientHeight + "px;}"; } }; diff --git a/script.coffee b/script.coffee index 01bba707c..ec8467fff 100644 --- a/script.coffee +++ b/script.coffee @@ -197,7 +197,7 @@ ui = style.left = null style.right = clientWidth - clientX + 45 - hoverend: (e) -> + hoverend: -> ui.el.parentNode.removeChild ui.el ### @@ -486,7 +486,7 @@ expandThread = $.replace span, a cb: - toggle: (e) -> + toggle: -> thread = @parentNode expandThread.toggle thread @@ -566,11 +566,11 @@ replyHiding = replyHiding.hide reply cb: - hide: (e) -> + hide: -> reply = @parentNode.nextSibling replyHiding.hide reply - show: (e) -> + show: -> div = @parentNode table = div.nextSibling replyHiding.show table @@ -994,7 +994,7 @@ options = options.time.call time options.backlink.call back - clearHidden: (e) -> + clearHidden: -> #'hidden' might be misleading; it's the number of IDs we're *looking* for, # not the number of posts actually hidden on the page. $.delete "hiddenReplies/#{g.BOARD}/" @@ -1008,13 +1008,13 @@ options = @value = key $.set @name, key conf[@name] = key - time: (e) -> + time: -> $.set 'time', @value conf['time'] = @value Time.foo() Time.date = new Date() $('#timePreview').textContent = Time.funk Time - backlink: (e) -> + backlink: -> $.set 'backlink', @value conf['backlink'] = @value $('#backlinkPreview').textContent = conf['backlink'].replace /%id/, '123456789' @@ -1367,10 +1367,10 @@ threadHiding = threadHiding.hideHide thread cb: - hide: (e) -> + hide: -> thread = @parentNode.parentNode threadHiding.hide thread - show: (e) -> + show: -> thread = @parentNode.parentNode threadHiding.show thread @@ -1596,9 +1596,9 @@ watcher = favicon.src = Favicon.empty cb: - toggle: (e) -> + toggle: -> watcher.toggle @parentNode - x: (e) -> + x: -> [board, _, id] = @nextElementSibling .getAttribute('href').substring(1).split('/') watcher.unwatch board, id @@ -1971,7 +1971,7 @@ unread = if unread.replies.length is 1 Favicon.update() - scroll: (e) -> + scroll: -> updater.focus = true height = d.body.clientHeight for reply, i in unread.replies @@ -2043,7 +2043,7 @@ imgHover = $.bind thumb, 'mouseover', imgHover.mouseover $.bind thumb, 'mousemove', ui.hover $.bind thumb, 'mouseout', ui.hoverend - mouseover: (e) -> + mouseover: -> ui.el = $.el 'img' id: 'iHover' src: @parentNode.href @@ -2082,7 +2082,7 @@ imgExpand = return if e.shiftKey or e.altKey or e.ctrlKey or e.button isnt 0 e.preventDefault() imgExpand.toggle @ - all: (e) -> + all: -> imgExpand.on = @checked if imgExpand.on #expand for thumb in $$ 'img[md5]:not([hidden])' @@ -2090,7 +2090,7 @@ imgExpand = else #contract for thumb in $$ 'img[md5][hidden]' imgExpand.contract thumb - typeChange: (e) -> + typeChange: -> switch @value when 'full' klass = '' @@ -2125,13 +2125,13 @@ imgExpand = thumb.hidden = true $.add a, img - error: (e) -> + error: -> thumb = @previousSibling imgExpand.contract thumb #navigator.online is not x-browser/os yet if navigator.appName isnt 'Opera' req = $.ajax @src, null, 'head' - req.onreadystatechange = (e) -> setTimeout imgExpand.retry, 10000, thumb if @status isnt 404 + req.onreadystatechange = -> setTimeout imgExpand.retry, 10000, thumb if @status isnt 404 else unless g.dead setTimeout imgExpand.retry, 10000, thumb retry: (thumb) -> @@ -2157,7 +2157,7 @@ imgExpand = delform = $ 'form[name=delform]' $.prepend delform, controls - resize: (e) -> + resize: -> imgExpand.style.innerHTML = ".fitheight img[md5] + img {max-height:#{d.body.clientHeight}px;}" firstRun = From b48130433918a4f44b5ed1cc298be561b9841a7d Mon Sep 17 00:00:00 2001 From: Nicolas Stepien Date: Tue, 18 Oct 2011 19:07:40 +0200 Subject: [PATCH 006/169] Less declarations in ui.drag(e) --- 4chan_x.user.js | 16 ++++------------ script.coffee | 16 ++++++++++------ 2 files changed, 14 insertions(+), 18 deletions(-) diff --git a/4chan_x.user.js b/4chan_x.user.js index c56782b70..4f9661067 100644 --- a/4chan_x.user.js +++ b/4chan_x.user.js @@ -232,19 +232,11 @@ drag: function(e) { var bottom, left, right, style, top; left = e.clientX - ui.dx; - if (left < 10) { - left = '0'; - } else if (ui.width - left < 10) { - left = null; - } - right = left ? null : 0; top = e.clientY - ui.dy; - if (top < 10) { - top = '0'; - } else if (ui.height - top < 10) { - top = null; - } - bottom = top ? null : 0; + left = left < 10 ? 0 : ui.width - left < 10 ? null : left; + top = top < 10 ? 0 : ui.height - top < 10 ? null : top; + right = left === null ? 0 : null; + bottom = top === null ? 0 : null; style = ui.el.style; style.top = top; style.right = right; diff --git a/script.coffee b/script.coffee index ec8467fff..0db57fb60 100644 --- a/script.coffee +++ b/script.coffee @@ -152,13 +152,17 @@ ui = ui.height = d.body.clientHeight - el.offsetHeight drag: (e) -> left = e.clientX - ui.dx - if left < 10 then left = '0' - else if ui.width - left < 10 then left = null - right = if left then null else 0 top = e.clientY - ui.dy - if top < 10 then top = '0' - else if ui.height - top < 10 then top = null - bottom = if top then null else 0 + left = + if left < 10 then 0 + else if ui.width - left < 10 then null + else left + top = + if top < 10 then 0 + else if ui.height - top < 10 then null + else top + right = if left is null then 0 else null + bottom = if top is null then 0 else null #using null instead of '' is 4% faster #these 4 statements are 40% faster than 1 style.cssText {style} = ui.el From 28e0b834662d25ed4dac53be8a6704bec9780ca4 Mon Sep 17 00:00:00 2001 From: Nicolas Stepien Date: Thu, 27 Oct 2011 20:45:04 +0200 Subject: [PATCH 007/169] Init features ASAP. --- 4chan_x.user.js | 132 +++++++++++++++++++++++++----------------------- script.coffee | 125 ++++++++++++++++++++++++--------------------- 2 files changed, 138 insertions(+), 119 deletions(-) diff --git a/4chan_x.user.js b/4chan_x.user.js index 2d257d664..a913b3611 100644 --- a/4chan_x.user.js +++ b/4chan_x.user.js @@ -61,7 +61,7 @@ */ (function() { - var $, $$, DAY, Favicon, HOUR, MINUTE, Main, NAMESPACE, QR, SECOND, Time, anonymize, conf, config, d, expandComment, expandThread, filter, firstRun, flatten, g, getTitle, imgExpand, imgGif, imgHover, imgPreloading, key, keybinds, log, nav, options, pathname, quoteBacklink, quoteInline, quoteOP, quotePreview, redirect, replyHiding, reportButton, revealSpoilers, sauce, temp, 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, filter, firstRun, flatten, g, getTitle, imgExpand, imgGif, imgHover, imgPreloading, key, keybinds, log, nav, options, quoteBacklink, quoteInline, quoteOP, quotePreview, redirect, replyHiding, reportButton, revealSpoilers, sauce, threadHiding, threadStats, threading, titlePost, ui, unread, updater, val, watcher; var __slice = Array.prototype.slice; config = { main: { @@ -502,19 +502,6 @@ val = conf[key]; conf[key] = $.get(key, val); } - pathname = location.pathname.substring(1).split('/'); - g.BOARD = pathname[0], temp = pathname[1]; - if (temp === 'res') { - g.REPLY = temp; - g.THREAD_ID = pathname[2]; - } else { - g.PAGENUM = parseInt(temp) || 0; - } - g.hiddenReplies = $.get("hiddenReplies/" + g.BOARD + "/", {}); - g.chanOffset = 5 - new Date().getTimezoneOffset() / 60; - if ($.isDST()) { - g.chanOffset--; - } $$ = function(selector, root) { if (root == null) { root = d.body; @@ -688,7 +675,7 @@ } }, toggle: function(thread) { - var a, backlink, num, prev, table, threadID, _i, _len, _ref, _ref2, _results; + var a, backlink, num, pathname, prev, table, threadID, _i, _len, _ref, _ref2, _results; threadID = thread.firstChild.id; pathname = "/" + g.BOARD + "/res/" + threadID; a = $('.omittedposts', thread); @@ -1803,7 +1790,7 @@ init: function() { var a, hiddenThreads, op, thread, _i, _len, _ref, _results; hiddenThreads = $.get("hiddenThreads/" + g.BOARD + "/", {}); - _ref = $$('div.thread'); + _ref = $$('.thread'); _results = []; for (_i = 0, _len = _ref.length; _i < _len; _i++) { thread = _ref[_i]; @@ -2188,15 +2175,20 @@ }; Time = { init: function() { + var chanOffset; Time.foo(); + chanOffset = 5 - new Date().getTimezoneOffset() / 60; + if ($.isDST()) { + chanOffset--; + } this.parse = Date.parse('10/11/11(Tue)18:53') ? function(node) { - return new Date(Date.parse(node.textContent) + g.chanOffset * HOUR); + return new Date(Date.parse(node.textContent) + chanOffset * HOUR); } : function(node) { var day, hour, min, month, year, _, _ref; _ref = node.textContent.match(/(\d+)\/(\d+)\/(\d+)\(\w+\)(\d+):(\d+)/), _ = _ref[0], month = _ref[1], day = _ref[2], year = _ref[3], hour = _ref[4], min = _ref[5]; year = "20" + year; month -= 1; - hour = g.chanOffset + Number(hour); + hour = chanOffset + Number(hour); return new Date(year, month, day, hour, min); }; return g.callbacks.push(Time.node); @@ -2397,7 +2389,7 @@ return this.classList.toggle('inlined'); }, add: function(q, id) { - var el, inline, root, threadID; + var el, inline, pathname, root, threadID; root = q.parentNode.nodeName === 'FONT' ? q.parentNode : q.nextSibling ? q.nextSibling : q; if (el = $.id(id)) { inline = quoteInline.table(id, el.innerHTML); @@ -2961,24 +2953,25 @@ }; Main = { init: function() { - var cutoff, hiddenThreads, id, lastChecked, nodes, now, timestamp, _ref; - $.unbind(document, 'DOMContentLoaded', Main.init); + var cutoff, hiddenThreads, id, lastChecked, now, pathname, reqUpdate, temp, timestamp, _ref; if (location.hostname === 'sys.4chan.org') { QR.sys(); return; } - if (conf['404 Redirect'] && d.title === '4chan - 404' && /^\d+$/.test(g.THREAD_ID)) { - redirect(); - return; - } - if (!$('#navtopr')) { - return; - } $.bind(window, 'message', Main.message); - Favicon.init(); + pathname = location.pathname.substring(1).split('/'); + g.BOARD = pathname[0], temp = pathname[1]; + if (temp === 'res') { + g.REPLY = temp; + g.THREAD_ID = pathname[2]; + } else { + g.PAGENUM = parseInt(temp) || 0; + } + g.hiddenReplies = $.get("hiddenReplies/" + g.BOARD + "/", {}); lastChecked = $.get('lastChecked', 0); now = Date.now(); - if (lastChecked < now - 1 * DAY) { + reqUpdate = lastChecked < now - 1 * DAY; + if (reqUpdate) { $.set('lastChecked', now); cutoff = now - 7 * DAY; hiddenThreads = $.get("hiddenThreads/" + g.BOARD + "/", {}); @@ -2998,19 +2991,14 @@ $.set("hiddenThreads/" + g.BOARD + "/", hiddenThreads); $.set("hiddenReplies/" + g.BOARD + "/", g.hiddenReplies); } - $.addStyle(Main.css); - threading.init(); if (conf['Filter']) { filter.init(); } if (conf['Reply Hiding']) { replyHiding.init(); } - if (conf['Image Expansion']) { - imgExpand.init(); - } - if (conf['Image Auto-Gif']) { - imgGif.init(); + if (conf['Anonymize']) { + anonymize.init(); } if (conf['Time Formatting']) { Time.init(); @@ -3018,18 +3006,12 @@ if (conf['Sauce']) { sauce.init(); } - if (conf['Reveal Spoilers'] && $('.postarea label')) { - revealSpoilers.init(); - } - if (conf['Anonymize']) { - anonymize.init(); + if (conf['Image Auto-Gif']) { + imgGif.init(); } if (conf['Image Hover']) { imgHover.init(); } - if (conf['Quick Reply']) { - QR.init(); - } if (conf['Report Button']) { reportButton.init(); } @@ -3045,6 +3027,39 @@ if (conf['Indicate OP quote']) { quoteOP.init(); } + if (g.REPLY) { + if (conf['Image Preloading']) { + imgPreloading.init(); + } + } + if (d.body) { + return Main.onLoad(); + } else { + return $.bind(d, 'DOMContentLoaded', Main.onLoad); + } + }, + onLoad: function() { + var nodes; + $.unbind(document, 'DOMContentLoaded', Main.onLoad); + if (conf['404 Redirect'] && d.title === '4chan - 404' && /^\d+$/.test(g.THREAD_ID)) { + redirect(); + return; + } + if (!$('#navtopr')) { + return; + } + $.addStyle(Main.css); + threading.init(); + Favicon.init(); + if (conf['Image Expansion']) { + imgExpand.init(); + } + if (conf['Reveal Spoilers'] && $('.postarea label')) { + revealSpoilers.init(); + } + if (conf['Quick Reply']) { + QR.init(); + } if (conf['Thread Watcher']) { watcher.init(); } @@ -3055,34 +3070,31 @@ if (conf['Thread Updater']) { updater.init(); } - if (conf['Image Preloading']) { - imgPreloading.init(); - } - if (conf['Post in Title']) { - titlePost.init(); - } if (conf['Thread Stats']) { threadStats.init(); } - if (conf['Unread Count']) { - unread.init(); - } if (conf['Reply Navigation']) { nav.init(); } + if (conf['Post in Title']) { + titlePost.init(); + } + if (conf['Unread Count']) { + unread.init(); + } } else { if (conf['Thread Hiding']) { threadHiding.init(); } - if (conf['Index Navigation']) { - nav.init(); - } if (conf['Thread Expansion']) { expandThread.init(); } if (conf['Comment Expansion']) { expandComment.init(); } + if (conf['Index Navigation']) { + nav.init(); + } } nodes = $$('.op, a + table'); g.callbacks.forEach(function(callback) { @@ -3380,9 +3392,5 @@ }\ ' }; - if (d.body) { - Main.init(); - } else { - $.bind(d, 'DOMContentLoaded', Main.init); - } + Main.init(); }).call(this); diff --git a/script.coffee b/script.coffee index ec126ce42..7ef332b3a 100644 --- a/script.coffee +++ b/script.coffee @@ -374,20 +374,6 @@ else for key, val of conf conf[key] = $.get key, val -pathname = location.pathname.substring(1).split('/') -[g.BOARD, temp] = pathname -if temp is 'res' - g.REPLY = temp - g.THREAD_ID = pathname[2] -else - g.PAGENUM = parseInt(temp) or 0 - -g.hiddenReplies = $.get "hiddenReplies/#{g.BOARD}/", {} -# GMT -8 is given as +480; would GMT +8 be -480 ? -g.chanOffset = 5 - new Date().getTimezoneOffset() / 60 -# 4chan = EST = GMT -5 -g.chanOffset-- if $.isDST() - $$ = (selector, root=d.body) -> Array::slice.call root.querySelectorAll selector @@ -1359,7 +1345,7 @@ threading = threadHiding = init: -> hiddenThreads = $.get "hiddenThreads/#{g.BOARD}/", {} - for thread in $$ 'div.thread' + for thread in $$ '.thread' op = thread.firstChild a = $.el 'a', textContent: '[ - ]' @@ -1669,16 +1655,21 @@ Time = init: -> Time.foo() + # GMT -8 is given as +480; would GMT +8 be -480 ? + chanOffset = 5 - new Date().getTimezoneOffset() / 60 + # 4chan = EST = GMT -5 + chanOffset-- if $.isDST() + @parse = if Date.parse '10/11/11(Tue)18:53' - (node) -> new Date Date.parse(node.textContent) + g.chanOffset*HOUR + (node) -> new Date Date.parse(node.textContent) + chanOffset*HOUR else # Firefox the Archaic cannot parse 4chan's time (node) -> [_, month, day, year, hour, min] = node.textContent.match /(\d+)\/(\d+)\/(\d+)\(\w+\)(\d+):(\d+)/ year = "20#{year}" month -= 1 #months start at 0 - hour = g.chanOffset + Number hour + hour = chanOffset + Number hour new Date year, month, day, hour, min g.callbacks.push Time.node @@ -2245,22 +2236,27 @@ firstRun = Main = init: -> - $.unbind document, 'DOMContentLoaded', Main.init if location.hostname is 'sys.4chan.org' QR.sys() return - if conf['404 Redirect'] and d.title is '4chan - 404' and /^\d+$/.test g.THREAD_ID - redirect() - return - if not $ '#navtopr' - return $.bind window, 'message', Main.message - Favicon.init() + + pathname = location.pathname.substring(1).split('/') + [g.BOARD, temp] = pathname + if temp is 'res' + g.REPLY = temp + g.THREAD_ID = pathname[2] + else + g.PAGENUM = parseInt(temp) or 0 + + g.hiddenReplies = $.get "hiddenReplies/#{g.BOARD}/", {} lastChecked = $.get 'lastChecked', 0 now = Date.now() - if lastChecked < now - 1*DAY + reqUpdate = lastChecked < now - 1*DAY + + if reqUpdate $.set 'lastChecked', now cutoff = now - 7*DAY @@ -2277,22 +2273,16 @@ Main = $.set "hiddenThreads/#{g.BOARD}/", hiddenThreads $.set "hiddenReplies/#{g.BOARD}/", g.hiddenReplies - $.addStyle Main.css #major features - threading.init() - if conf['Filter'] filter.init() if conf['Reply Hiding'] replyHiding.init() - if conf['Image Expansion'] - imgExpand.init() - - if conf['Image Auto-Gif'] - imgGif.init() + if conf['Anonymize'] + anonymize.init() if conf['Time Formatting'] Time.init() @@ -2300,18 +2290,12 @@ Main = if conf['Sauce'] sauce.init() - if conf['Reveal Spoilers'] and $('.postarea label') - revealSpoilers.init() - - if conf['Anonymize'] - anonymize.init() + if conf['Image Auto-Gif'] + imgGif.init() if conf['Image Hover'] imgHover.init() - if conf['Quick Reply'] - QR.init() - if conf['Report Button'] reportButton.init() @@ -2327,6 +2311,38 @@ Main = if conf['Indicate OP quote'] quoteOP.init() + if g.REPLY + if conf['Image Preloading'] + imgPreloading.init() + + + if d.body + Main.onLoad() + else + $.bind d, 'DOMContentLoaded', Main.onLoad + + onLoad: -> + $.unbind document, 'DOMContentLoaded', Main.onLoad + if conf['404 Redirect'] and d.title is '4chan - 404' and /^\d+$/.test g.THREAD_ID + redirect() + return + if not $ '#navtopr' + return + $.addStyle Main.css + threading.init() + Favicon.init() + + + #major features + if conf['Image Expansion'] + imgExpand.init() + + if conf['Reveal Spoilers'] and $('.postarea label') + revealSpoilers.init() + + if conf['Quick Reply'] + QR.init() + if conf['Thread Watcher'] watcher.init() @@ -2337,34 +2353,32 @@ Main = if conf['Thread Updater'] updater.init() - if conf['Image Preloading'] - imgPreloading.init() - - if conf['Post in Title'] - titlePost.init() - if conf['Thread Stats'] threadStats.init() - if conf['Unread Count'] - unread.init() - if conf['Reply Navigation'] nav.init() + if conf['Post in Title'] + titlePost.init() + + if conf['Unread Count'] + unread.init() + else #not reply if conf['Thread Hiding'] threadHiding.init() - if conf['Index Navigation'] - nav.init() - if conf['Thread Expansion'] expandThread.init() if conf['Comment Expansion'] expandComment.init() + if conf['Index Navigation'] + nav.init() + + nodes = $$ '.op, a + table' g.callbacks.forEach (callback) -> try @@ -2652,7 +2666,4 @@ Main = } ' -if d.body - Main.init() -else - $.bind d, 'DOMContentLoaded', Main.init +Main.init() From 0400ecb42fea5e1ba1c3f7de823239ae2ee900e9 Mon Sep 17 00:00:00 2001 From: Nicolas Stepien Date: Thu, 27 Oct 2011 22:28:30 +0200 Subject: [PATCH 008/169] We'll need this for the stable branch. --- 4chan_x.user.js | 6 +++--- script.coffee | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/4chan_x.user.js b/4chan_x.user.js index a913b3611..5f760e9db 100644 --- a/4chan_x.user.js +++ b/4chan_x.user.js @@ -2953,7 +2953,7 @@ }; Main = { init: function() { - var cutoff, hiddenThreads, id, lastChecked, now, pathname, reqUpdate, temp, timestamp, _ref; + var cutoff, hiddenThreads, id, lastChecked, now, pathname, temp, timestamp, _ref; if (location.hostname === 'sys.4chan.org') { QR.sys(); return; @@ -2970,8 +2970,8 @@ g.hiddenReplies = $.get("hiddenReplies/" + g.BOARD + "/", {}); lastChecked = $.get('lastChecked', 0); now = Date.now(); - reqUpdate = lastChecked < now - 1 * DAY; - if (reqUpdate) { + Main.reqUpdate = lastChecked < now - 1 * DAY; + if (Main.reqUpdate) { $.set('lastChecked', now); cutoff = now - 7 * DAY; hiddenThreads = $.get("hiddenThreads/" + g.BOARD + "/", {}); diff --git a/script.coffee b/script.coffee index 7ef332b3a..d1fb56071 100644 --- a/script.coffee +++ b/script.coffee @@ -2254,9 +2254,9 @@ Main = lastChecked = $.get 'lastChecked', 0 now = Date.now() - reqUpdate = lastChecked < now - 1*DAY + Main.reqUpdate = lastChecked < now - 1*DAY - if reqUpdate + if Main.reqUpdate $.set 'lastChecked', now cutoff = now - 7*DAY From 3fc5d1fabd5bfe1c6b22b37ce099b126fba803d8 Mon Sep 17 00:00:00 2001 From: Nicolas Stepien Date: Thu, 27 Oct 2011 23:59:08 +0200 Subject: [PATCH 009/169] do not preload images automatically, close #188 --- 4chan_x.user.js | 52 ++++++++++++++++++++++++++++++++++++++----------- changelog | 5 +++-- script.coffee | 31 +++++++++++++++++++++++------ 3 files changed, 69 insertions(+), 19 deletions(-) diff --git a/4chan_x.user.js b/4chan_x.user.js index aa559b9c5..cedc46ccd 100644 --- a/4chan_x.user.js +++ b/4chan_x.user.js @@ -2775,15 +2775,45 @@ }; imgPreloading = { init: function() { - return g.callbacks.push(function(root) { - var el, src, thumb; - if (!(thumb = $('img[md5]', root))) { - return; - } - src = thumb.parentNode.href; - return el = $.el('img', { - src: src + var controls, form, label; + if (!(controls = $.id('imgControls'))) { + controls = $.el('div', { + id: 'imgControls' }); + form = $('body > form'); + $.prepend(form, controls); + } + label = $.el('label', { + innerHTML: 'Preload Images' + }); + $.bind($('input', label), 'click', imgPreloading.click); + $.add(controls, label); + return g.callbacks.push(imgPreloading.node); + }, + click: function() { + var thumb, _i, _len, _ref, _results; + if (imgPreloading.on = this.checked) { + _ref = $$('img[md5]:last-child'); + _results = []; + for (_i = 0, _len = _ref.length; _i < _len; _i++) { + thumb = _ref[_i]; + _results.push(imgPreloading.preload(thumb)); + } + return _results; + } + }, + node: function(root) { + var thumb; + if (!(imgPreloading.on && (thumb = $('img[md5]:last-child', root)))) { + return; + } + return imgPreloading.preload(thumb); + }, + preload: function(thumb) { + var el, src; + src = thumb.parentNode.href; + return el = $.el('img', { + src: src }); } }; @@ -2916,7 +2946,7 @@ } }, dialog: function() { - var controls, delform, imageType, option, select, _i, _len, _ref; + var controls, form, imageType, option, select, _i, _len, _ref; controls = $.el('div', { id: 'imgControls', innerHTML: " " @@ -2935,8 +2965,8 @@ $.bind(select, 'change', $.cb.value); $.bind(select, 'change', imgExpand.cb.typeChange); $.bind($('input', controls), 'click', imgExpand.cb.all); - delform = $('form[name=delform]'); - return $.prepend(delform, controls); + form = $('body > form'); + return $.prepend(form, controls); }, resize: function(e) { return imgExpand.style.innerHTML = ".fitheight img[md5] + img {max-height:" + d.body.clientHeight + "px;}"; diff --git a/changelog b/changelog index 7863bc30c..50be5269a 100644 --- a/changelog +++ b/changelog @@ -1,11 +1,12 @@ master - mayhem initiate 4chan X earlier + performance improvements + regular expressions based filter + do not preload images automatically automatically reload expanded pictures on error update archives redirections for /diy/, /pol/ and /sci/ - regular expressions based filter handle bans with the thread updater - performance improvements - aeosynth quick reply redesign diff --git a/script.coffee b/script.coffee index eca173d15..5042c5fe4 100644 --- a/script.coffee +++ b/script.coffee @@ -2044,10 +2044,29 @@ imgHover = imgPreloading = init: -> - g.callbacks.push (root) -> - return unless thumb = $ 'img[md5]', root - src = thumb.parentNode.href - el = $.el 'img', { src } + unless controls = $.id 'imgControls' + controls = $.el 'div', + id: 'imgControls' + form = $ 'body > form' + $.prepend form, controls + + label = $.el 'label', + innerHTML: 'Preload Images' + $.bind $('input', label), 'click', imgPreloading.click + $.add controls, label + + g.callbacks.push imgPreloading.node + + click: -> + if imgPreloading.on = @checked + for thumb in $$ 'img[md5]:last-child' + imgPreloading.preload thumb + node: (root) -> + return unless imgPreloading.on and thumb = $ 'img[md5]:last-child', root + imgPreloading.preload thumb + preload: (thumb) -> + src = thumb.parentNode.href + el = $.el 'img', { src } imgGif = init: -> @@ -2147,8 +2166,8 @@ imgExpand = $.bind select, 'change', imgExpand.cb.typeChange $.bind $('input', controls), 'click', imgExpand.cb.all - delform = $ 'form[name=delform]' - $.prepend delform, controls + form = $ 'body > form' + $.prepend form, controls resize: (e) -> imgExpand.style.innerHTML = ".fitheight img[md5] + img {max-height:#{d.body.clientHeight}px;}" From cd9cd822922b7a6489cf503cde26a8354fa1e00b Mon Sep 17 00:00:00 2001 From: Nicolas Stepien Date: Fri, 28 Oct 2011 00:15:38 +0200 Subject: [PATCH 010/169] Woops, don't copypaste. --- 4chan_x.user.js | 6 ++---- script.coffee | 3 +-- 2 files changed, 3 insertions(+), 6 deletions(-) diff --git a/4chan_x.user.js b/4chan_x.user.js index cedc46ccd..129a2302b 100644 --- a/4chan_x.user.js +++ b/4chan_x.user.js @@ -2810,10 +2810,8 @@ return imgPreloading.preload(thumb); }, preload: function(thumb) { - var el, src; - src = thumb.parentNode.href; - return el = $.el('img', { - src: src + return $.el('img', { + src: thumb.parentNode.href }); } }; diff --git a/script.coffee b/script.coffee index 5042c5fe4..ff3c6603a 100644 --- a/script.coffee +++ b/script.coffee @@ -2065,8 +2065,7 @@ imgPreloading = return unless imgPreloading.on and thumb = $ 'img[md5]:last-child', root imgPreloading.preload thumb preload: (thumb) -> - src = thumb.parentNode.href - el = $.el 'img', { src } + $.el 'img', src: thumb.parentNode.href imgGif = init: -> From 71cac4e7f600a0c037af317a6305018ba6f5f175 Mon Sep 17 00:00:00 2001 From: Nicolas Stepien Date: Fri, 28 Oct 2011 17:32:38 +0200 Subject: [PATCH 011/169] QR error checking fix. --- 4chan_x.user.js | 9 +++++++-- script.coffee | 8 ++++++-- 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/4chan_x.user.js b/4chan_x.user.js index 5f760e9db..54a1cd44b 100644 --- a/4chan_x.user.js +++ b/4chan_x.user.js @@ -1718,6 +1718,7 @@ }, sys: function() { var recaptcha; + $.unbind(d, 'DOMContentLoaded', QR.sys); if (recaptcha = $('#recaptcha_response_field')) { $.bind(recaptcha, 'keydown', QR.keydown); return; @@ -2955,7 +2956,11 @@ init: function() { var cutoff, hiddenThreads, id, lastChecked, now, pathname, temp, timestamp, _ref; if (location.hostname === 'sys.4chan.org') { - QR.sys(); + if (d.body) { + QR.sys(); + } else { + $.bind(d, 'DOMContentLoaded', QR.sys); + } return; } $.bind(window, 'message', Main.message); @@ -3040,7 +3045,7 @@ }, onLoad: function() { var nodes; - $.unbind(document, 'DOMContentLoaded', Main.onLoad); + $.unbind(d, 'DOMContentLoaded', Main.onLoad); if (conf['404 Redirect'] && d.title === '4chan - 404' && /^\d+$/.test(g.THREAD_ID)) { redirect(); return; diff --git a/script.coffee b/script.coffee index d1fb56071..2c17ef31a 100644 --- a/script.coffee +++ b/script.coffee @@ -1288,6 +1288,7 @@ QR = if $('img.favicon', op).src is Favicon.empty watcher.watch op, id sys: -> + $.unbind d, 'DOMContentLoaded', QR.sys if recaptcha = $ '#recaptcha_response_field' #post reporting $.bind recaptcha, 'keydown', QR.keydown return @@ -2237,7 +2238,10 @@ firstRun = Main = init: -> if location.hostname is 'sys.4chan.org' - QR.sys() + if d.body + QR.sys() + else + $.bind d, 'DOMContentLoaded', QR.sys return $.bind window, 'message', Main.message @@ -2322,7 +2326,7 @@ Main = $.bind d, 'DOMContentLoaded', Main.onLoad onLoad: -> - $.unbind document, 'DOMContentLoaded', Main.onLoad + $.unbind d, 'DOMContentLoaded', Main.onLoad if conf['404 Redirect'] and d.title is '4chan - 404' and /^\d+$/.test g.THREAD_ID redirect() return From ff3bf87589260ef351b6482069e5ad1a09308e25 Mon Sep 17 00:00:00 2001 From: James Campos Date: Fri, 28 Oct 2011 20:35:40 -0700 Subject: [PATCH 012/169] fix Object.keys shim (no one noticed it was broken...) --- 4chan_x.user.js | 5 ++--- script.coffee | 2 +- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/4chan_x.user.js b/4chan_x.user.js index f0e683707..825bb5d67 100644 --- a/4chan_x.user.js +++ b/4chan_x.user.js @@ -168,10 +168,9 @@ } if (!Object.keys) { Object.keys = function(o) { - var key, _i, _len, _results; + var key, _results; _results = []; - for (_i = 0, _len = o.length; _i < _len; _i++) { - key = o[_i]; + for (key in o) { _results.push(key); } return _results; diff --git a/script.coffee b/script.coffee index b18d2ced3..c54ec8b5f 100644 --- a/script.coffee +++ b/script.coffee @@ -102,7 +102,7 @@ if console? # XXX opera cannot into Object.keys if not Object.keys Object.keys = (o) -> - key for key in o + key for key of o # flatten the config conf = {} From 21d02ce569aa7cc7c412dc784eae4d085bf4348c Mon Sep 17 00:00:00 2001 From: James Campos Date: Fri, 28 Oct 2011 20:50:18 -0700 Subject: [PATCH 013/169] there are two "GitHub" links --- 4chan_x.user.js | 2 +- script.coffee | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/4chan_x.user.js b/4chan_x.user.js index 825bb5d67..1d18f2678 100644 --- a/4chan_x.user.js +++ b/4chan_x.user.js @@ -1199,7 +1199,7 @@
\
\ 4chan X\ - | GitHub\ + | Issues\ | Donate\
\
\ diff --git a/script.coffee b/script.coffee index c54ec8b5f..65817bfa1 100644 --- a/script.coffee +++ b/script.coffee @@ -855,7 +855,7 @@ options =
From b5bb7032880cdaed73ccd63ac204fac7bcdf817a Mon Sep 17 00:00:00 2001 From: Nicolas Stepien Date: Sun, 30 Oct 2011 17:47:27 +0100 Subject: [PATCH 014/169] Strikethrough backlinks of filtered posts. --- 4chan_x.user.js | 5 ++++- script.coffee | 5 ++++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/4chan_x.user.js b/4chan_x.user.js index 1d18f2678..6919ada61 100644 --- a/4chan_x.user.js +++ b/4chan_x.user.js @@ -2330,7 +2330,7 @@ } link = $.el('a', { href: "#" + id, - className: 'backlink', + className: root.hidden ? 'filtered backlink' : 'backlink', textContent: quoteBacklink.funk(id) }); if (conf['Quote Preview']) { @@ -3324,6 +3324,9 @@ .filetitle, .replytitle, .postername, .commentpostername, .postertrip {\ background: none;\ }\ + .filtered {\ + text-decoration: line-through;\ + }\ \ /* Firefox bug: hidden tables are not hidden. fixed in 9.0 */\ [hidden] {\ diff --git a/script.coffee b/script.coffee index 65817bfa1..fca90fd97 100644 --- a/script.coffee +++ b/script.coffee @@ -1762,7 +1762,7 @@ quoteBacklink = continue if !conf['OP Backlinks'] and el.className is 'op' link = $.el 'a', href: "##{id}" - className: 'backlink' + className: if root.hidden then 'filtered backlink' else 'backlink' textContent: quoteBacklink.funk id if conf['Quote Preview'] $.bind link, 'mouseover', quotePreview.mouseover @@ -2586,6 +2586,9 @@ Main = .filetitle, .replytitle, .postername, .commentpostername, .postertrip { background: none; } + .filtered { + text-decoration: line-through; + } /* Firefox bug: hidden tables are not hidden. fixed in 9.0 */ [hidden] { From fa83f24a09d855d043acbe31dfd009653bab1ab8 Mon Sep 17 00:00:00 2001 From: Nicolas Stepien Date: Sun, 30 Oct 2011 18:48:22 +0100 Subject: [PATCH 015/169] Strikethrough quotelinks of filtered posts. --- 4chan_x.user.js | 22 +++++++++++++++++++++- script.coffee | 12 ++++++++++++ 2 files changed, 33 insertions(+), 1 deletion(-) diff --git a/4chan_x.user.js b/4chan_x.user.js index 6919ada61..b0262358e 100644 --- a/4chan_x.user.js +++ b/4chan_x.user.js @@ -61,7 +61,7 @@ */ (function() { - var $, $$, DAY, Favicon, HOUR, MINUTE, Main, NAMESPACE, QR, SECOND, Time, anonymize, conf, config, d, expandComment, expandThread, filter, firstRun, flatten, g, getTitle, imgExpand, imgGif, imgHover, imgPreloading, key, keybinds, log, nav, 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, filter, firstRun, flatten, g, getTitle, imgExpand, imgGif, imgHover, imgPreloading, key, keybinds, log, nav, options, quoteBacklink, quoteInline, quoteOP, quotePreview, redirect, replyHiding, reportButton, revealSpoilers, sauce, strikethroughQuotes, threadHiding, threadStats, threading, titlePost, ui, unread, updater, val, watcher; var __slice = Array.prototype.slice; config = { main: { @@ -586,6 +586,23 @@ } } }; + strikethroughQuotes = { + init: function() { + return g.callbacks.push(function(root) { + var el, quote, _i, _len, _ref, _results; + if (root.className === 'inline') { + return; + } + _ref = $$('.quotelink', root); + _results = []; + for (_i = 0, _len = _ref.length; _i < _len; _i++) { + quote = _ref[_i]; + _results.push((el = $.id(quote.hash.slice(1))) ? el.parentNode.parentNode.parentNode.hidden ? $.addClass(quote, 'filtered') : void 0 : void 0); + } + return _results; + }); + } + }; expandComment = { init: function() { var a, _i, _len, _ref, _results; @@ -3036,6 +3053,9 @@ if (conf['Reply Hiding']) { replyHiding.init(); } + if (conf['Filter'] || conf['Reply Hiding']) { + strikethroughQuotes.init(); + } if (conf['Anonymize']) { anonymize.init(); } diff --git a/script.coffee b/script.coffee index fca90fd97..d993c328d 100644 --- a/script.coffee +++ b/script.coffee @@ -425,6 +425,15 @@ filter = if img = $ 'img[md5]', root filter.test 'md5', img.getAttribute('md5') +strikethroughQuotes = + init: -> + g.callbacks.push (root) -> + return if root.className is 'inline' + for quote in $$ '.quotelink', root + if el = $.id quote.hash[1..] + if el.parentNode.parentNode.parentNode.hidden + $.addClass quote, 'filtered' + expandComment = init: -> for a in $$ '.abbr a' @@ -2308,6 +2317,9 @@ Main = if conf['Reply Hiding'] replyHiding.init() + if conf['Filter'] or conf['Reply Hiding'] + strikethroughQuotes.init() + if conf['Anonymize'] anonymize.init() From 69d9986647aac320dde0613a19b323ab98bef816 Mon Sep 17 00:00:00 2001 From: Nicolas Stepien Date: Sun, 30 Oct 2011 19:43:55 +0100 Subject: [PATCH 016/169] Strikethrough quotes on user input. --- 4chan_x.user.js | 14 ++++++++++++-- script.coffee | 6 ++++++ 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/4chan_x.user.js b/4chan_x.user.js index b0262358e..27731e1b9 100644 --- a/4chan_x.user.js +++ b/4chan_x.user.js @@ -808,9 +808,14 @@ } }, hide: function(reply) { - var id; + var id, quote, _i, _len, _ref; replyHiding.hideHide(reply); id = reply.id; + _ref = $$(".quotelink[href='#" + id + "'], .backlink[href='#" + id + "']"); + for (_i = 0, _len = _ref.length; _i < _len; _i++) { + quote = _ref[_i]; + $.addClass(quote, 'filtered'); + } g.hiddenReplies[id] = Date.now(); return $.set("hiddenReplies/" + g.BOARD + "/", g.hiddenReplies); }, @@ -833,9 +838,14 @@ } }, show: function(table) { - var id; + var id, quote, _i, _len, _ref; table.hidden = false; id = $('td[id]', table).id; + _ref = $$(".quotelink[href='#" + id + "'], .backlink[href='#" + id + "']"); + for (_i = 0, _len = _ref.length; _i < _len; _i++) { + quote = _ref[_i]; + $.removeClass(quote, 'filtered'); + } delete g.hiddenReplies[id]; return $.set("hiddenReplies/" + g.BOARD + "/", g.hiddenReplies); } diff --git a/script.coffee b/script.coffee index d993c328d..9c70fd8bb 100644 --- a/script.coffee +++ b/script.coffee @@ -580,6 +580,9 @@ replyHiding = replyHiding.hideHide reply id = reply.id + for quote in $$ ".quotelink[href='##{id}'], .backlink[href='##{id}']" + $.addClass quote, 'filtered' + g.hiddenReplies[id] = Date.now() $.set "hiddenReplies/#{g.BOARD}/", g.hiddenReplies @@ -603,6 +606,9 @@ replyHiding = table.hidden = false id = $('td[id]', table).id + for quote in $$ ".quotelink[href='##{id}'], .backlink[href='##{id}']" + $.removeClass quote, 'filtered' + delete g.hiddenReplies[id] $.set "hiddenReplies/#{g.BOARD}/", g.hiddenReplies From e7e777e4c8a463d156d6efa0bae322ea32cb6ee0 Mon Sep 17 00:00:00 2001 From: Nicolas Stepien Date: Sun, 30 Oct 2011 20:33:33 +0100 Subject: [PATCH 017/169] Don't reveal hidden posts when uninlining quotes. --- 4chan_x.user.js | 13 ++++++------- script.coffee | 8 ++++---- 2 files changed, 10 insertions(+), 11 deletions(-) diff --git a/4chan_x.user.js b/4chan_x.user.js index 27731e1b9..1f5ff756a 100644 --- a/4chan_x.user.js +++ b/4chan_x.user.js @@ -2441,16 +2441,15 @@ } }, rm: function(q, id) { - var hidden, inlined, table, _i, _len, _ref; + var inlined, table, _i, _len, _ref; table = $.x("following::*[@id='i" + id + "']", q); - _ref = $$('input', table); + _ref = $$('.backlink.inlined:not(.filtered)', table); for (_i = 0, _len = _ref.length; _i < _len; _i++) { inlined = _ref[_i]; - if (hidden = $.id(inlined.name)) { - if (!hidden.classList.contains('op')) { - $.x('ancestor::table[1]', hidden).hidden = false; - } - } + $.x('ancestor::table[1]', $.id(inlined.hash.slice(1))).hidden = false; + } + if (!q.classList.contains('filtered')) { + $.x('ancestor::table[1]', $.id(id)).hidden = false; } return $.rm(table); }, diff --git a/script.coffee b/script.coffee index 9c70fd8bb..eec3c543e 100644 --- a/script.coffee +++ b/script.coffee @@ -1831,10 +1831,10 @@ quoteInline = rm: (q, id) -> #select the corresponding table or loading td table = $.x "following::*[@id='i#{id}']", q - for inlined in $$ 'input', table - if hidden = $.id inlined.name - unless hidden.classList.contains 'op' - $.x('ancestor::table[1]', hidden).hidden = false + for inlined in $$ '.backlink.inlined:not(.filtered)', table + $.x('ancestor::table[1]', $.id inlined.hash[1..]).hidden = false + unless q.classList.contains 'filtered' + $.x('ancestor::table[1]', $.id id).hidden = false $.rm table parse: (req, pathname, id, threadID, inline) -> From cd8109c986e4e2668f6d7d04e9d26fd9c71ea720 Mon Sep 17 00:00:00 2001 From: James Campos Date: Sun, 30 Oct 2011 12:39:09 -0700 Subject: [PATCH 018/169] fix #357 --- 4chan_x.user.js | 4 ++-- script.coffee | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/4chan_x.user.js b/4chan_x.user.js index 1f5ff756a..e02bbb3e8 100644 --- a/4chan_x.user.js +++ b/4chan_x.user.js @@ -1226,8 +1226,8 @@
\
\ 4chan X\ - | Issues\ - | Donate\ + | Issues\ + | Donate\
\
\ \ diff --git a/script.coffee b/script.coffee index eec3c543e..2e8a3f592 100644 --- a/script.coffee +++ b/script.coffee @@ -870,8 +870,8 @@ options =
4chan X - | Issues - | Donate + | Issues + | Donate
From 0aef4c4321d69c5b65d52717295c8bca1d3e466b Mon Sep 17 00:00:00 2001 From: James Campos Date: Sun, 30 Oct 2011 12:40:27 -0700 Subject: [PATCH 019/169] hurp --- 4chan_x.user.js | 2 +- script.coffee | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/4chan_x.user.js b/4chan_x.user.js index e02bbb3e8..3579a1d56 100644 --- a/4chan_x.user.js +++ b/4chan_x.user.js @@ -1225,7 +1225,7 @@
\
\
\ - 4chan X\ + 4chan X\ | Issues\ | Donate\
\ diff --git a/script.coffee b/script.coffee index 2e8a3f592..4ddfbb0d7 100644 --- a/script.coffee +++ b/script.coffee @@ -869,7 +869,7 @@ options =
From b73c3d11eb6b72253abc4890ca095e3df70a81d1 Mon Sep 17 00:00:00 2001 From: Nicolas Stepien Date: Sun, 30 Oct 2011 22:03:53 +0100 Subject: [PATCH 020/169] Update archive redirection: easymodo is gone, shorter url for installgentoo. --- 4chan_x.user.js | 6 ++---- script.coffee | 6 +++--- 2 files changed, 5 insertions(+), 7 deletions(-) diff --git a/4chan_x.user.js b/4chan_x.user.js index 3579a1d56..21ab732bb 100644 --- a/4chan_x.user.js +++ b/4chan_x.user.js @@ -2728,7 +2728,7 @@ case 'g': case 'pol': case 'sci': - url = "http://archive.installgentoo.net/cgi-board.pl/" + g.BOARD + "/thread/" + g.THREAD_ID; + url = "http://archive.installgentoo.net/" + g.BOARD + "/thread/" + g.THREAD_ID; break; case 'lit': case 'tv': @@ -2736,9 +2736,7 @@ break; case 'a': case 'jp': - case 'm': - case 'tg': - url = "http://archive.easymodo.net/" + g.BOARD + "/thread/" + g.THREAD_ID; + url = "http://archive.foolz.us/" + g.BOARD + "/thread/" + g.THREAD_ID; break; case '3': case 'adv': diff --git a/script.coffee b/script.coffee index 4ddfbb0d7..616d3ac5b 100644 --- a/script.coffee +++ b/script.coffee @@ -2035,11 +2035,11 @@ Favicon = redirect = -> switch g.BOARD when 'diy', 'g', 'pol', 'sci' - url = "http://archive.installgentoo.net/cgi-board.pl/#{g.BOARD}/thread/#{g.THREAD_ID}" + url = "http://archive.installgentoo.net/#{g.BOARD}/thread/#{g.THREAD_ID}" when 'lit', 'tv' url = "http://archive.gentoomen.org/cgi-board.pl/#{g.BOARD}/thread/#{g.THREAD_ID}" - when 'a', 'jp', 'm', 'tg' - url = "http://archive.easymodo.net/#{g.BOARD}/thread/#{g.THREAD_ID}" + when 'a', 'jp' + url = "http://archive.foolz.us/#{g.BOARD}/thread/#{g.THREAD_ID}" when '3', 'adv', 'an', 'ck', 'co', 'fa', 'fit', 'int', 'k', 'mu', 'n', 'o', 'p', 'po', 'soc', 'sp', 'toy', 'trv', 'v', 'vp', 'x' url = "http://archive.no-ip.org/#{g.BOARD}/thread/#{g.THREAD_ID}" else From 25dbf69dd0da8b75cb55df88353e559ce0194016 Mon Sep 17 00:00:00 2001 From: James Campos Date: Sun, 30 Oct 2011 14:30:34 -0700 Subject: [PATCH 021/169] tv too --- 4chan_x.user.js | 2 +- script.coffee | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/4chan_x.user.js b/4chan_x.user.js index 21ab732bb..df472b741 100644 --- a/4chan_x.user.js +++ b/4chan_x.user.js @@ -2731,11 +2731,11 @@ url = "http://archive.installgentoo.net/" + g.BOARD + "/thread/" + g.THREAD_ID; break; case 'lit': - case 'tv': url = "http://archive.gentoomen.org/cgi-board.pl/" + g.BOARD + "/thread/" + g.THREAD_ID; break; case 'a': case 'jp': + case 'tv': url = "http://archive.foolz.us/" + g.BOARD + "/thread/" + g.THREAD_ID; break; case '3': diff --git a/script.coffee b/script.coffee index 616d3ac5b..9c5908b79 100644 --- a/script.coffee +++ b/script.coffee @@ -2036,9 +2036,9 @@ redirect = -> switch g.BOARD when 'diy', 'g', 'pol', 'sci' url = "http://archive.installgentoo.net/#{g.BOARD}/thread/#{g.THREAD_ID}" - when 'lit', 'tv' + when 'lit' url = "http://archive.gentoomen.org/cgi-board.pl/#{g.BOARD}/thread/#{g.THREAD_ID}" - when 'a', 'jp' + when 'a', 'jp', 'tv' url = "http://archive.foolz.us/#{g.BOARD}/thread/#{g.THREAD_ID}" when '3', 'adv', 'an', 'ck', 'co', 'fa', 'fit', 'int', 'k', 'mu', 'n', 'o', 'p', 'po', 'soc', 'sp', 'toy', 'trv', 'v', 'vp', 'x' url = "http://archive.no-ip.org/#{g.BOARD}/thread/#{g.THREAD_ID}" From ee3c82707608d92425607cd58ef28d41247bc648 Mon Sep 17 00:00:00 2001 From: James Campos Date: Sun, 30 Oct 2011 15:42:05 -0700 Subject: [PATCH 022/169] don't update closed threads --- 4chan_x.user.js | 3 +++ script.coffee | 2 ++ 2 files changed, 5 insertions(+) diff --git a/4chan_x.user.js b/4chan_x.user.js index df472b741..42338d928 100644 --- a/4chan_x.user.js +++ b/4chan_x.user.js @@ -1900,6 +1900,9 @@ updater = { init: function() { var checkbox, checked, dialog, html, input, name, title, _i, _len, _ref; + if (!$('form[name=post]')) { + return; + } if (conf['Scrolling']) { if (conf['Scroll BG']) { updater.focus = true; diff --git a/script.coffee b/script.coffee index 9c5908b79..c72112c0c 100644 --- a/script.coffee +++ b/script.coffee @@ -1433,6 +1433,8 @@ threadHiding = updater = init: -> + #thread closed + return unless $ 'form[name=post]' if conf['Scrolling'] if conf['Scroll BG'] updater.focus = true From ac6aea9a232211de46ecc65455008d6590cd0f93 Mon Sep 17 00:00:00 2001 From: Nicolas Stepien Date: Mon, 31 Oct 2011 00:25:57 +0100 Subject: [PATCH 023/169] Create anchor backlinks outside of the loop. --- 4chan_x.user.js | 15 ++++++++------- script.coffee | 13 +++++++------ 2 files changed, 15 insertions(+), 13 deletions(-) diff --git a/4chan_x.user.js b/4chan_x.user.js index 42338d928..17c038894 100644 --- a/4chan_x.user.js +++ b/4chan_x.user.js @@ -2336,11 +2336,10 @@ format = conf['backlink'].replace(/%id/, "' + id + '"); quoteBacklink.funk = Function('id', "return'" + format + "'"); return g.callbacks.push(function(root) { - var container, el, id, link, qid, quote, quotes, _i, _len, _ref, _results; + var a, container, el, id, link, qid, quote, quotes, _i, _len, _ref, _results; if (root.classList.contains('inline')) { return; } - id = $('input', root).name; quotes = {}; _ref = $$('.quotelink', root); for (_i = 0, _len = _ref.length; _i < _len; _i++) { @@ -2350,6 +2349,12 @@ } quotes[qid] = quote; } + id = $('input', root).name; + a = $.el('a', { + href: "#" + id, + className: root.hidden ? 'filtered backlink' : 'backlink', + textContent: quoteBacklink.funk(id) + }); _results = []; for (qid in quotes) { if (!(el = $.id(qid))) { @@ -2358,11 +2363,7 @@ if (!conf['OP Backlinks'] && el.className === 'op') { continue; } - link = $.el('a', { - href: "#" + id, - className: root.hidden ? 'filtered backlink' : 'backlink', - textContent: quoteBacklink.funk(id) - }); + link = a.cloneNode(true); if (conf['Quote Preview']) { $.bind(link, 'mouseover', quotePreview.mouseover); $.bind(link, 'mousemove', ui.hover); diff --git a/script.coffee b/script.coffee index c72112c0c..870ee5c9e 100644 --- a/script.coffee +++ b/script.coffee @@ -1765,22 +1765,23 @@ quoteBacklink = quoteBacklink.funk = Function 'id', "return'#{format}'" g.callbacks.push (root) -> return if root.classList.contains 'inline' - # op or reply - id = $('input', root).name quotes = {} for quote in $$ '.quotelink', root #don't process >>>/b/ continue unless qid = quote.hash[1..] #duplicate quotes get overwritten quotes[qid] = quote + # op or reply + id = $('input', root).name + a = $.el 'a', + href: "##{id}" + className: if root.hidden then 'filtered backlink' else 'backlink' + textContent: quoteBacklink.funk id for qid of quotes continue unless el = $.id qid #don't backlink the op continue if !conf['OP Backlinks'] and el.className is 'op' - link = $.el 'a', - href: "##{id}" - className: if root.hidden then 'filtered backlink' else 'backlink' - textContent: quoteBacklink.funk id + link = a.cloneNode true if conf['Quote Preview'] $.bind link, 'mouseover', quotePreview.mouseover $.bind link, 'mousemove', ui.hover From f6d5c3309337cb369779036380ddec5816dda3e6 Mon Sep 17 00:00:00 2001 From: James Campos Date: Mon, 31 Oct 2011 09:18:40 -0700 Subject: [PATCH 024/169] do more outside the loop --- 4chan_x.user.js | 16 ++++++++-------- script.coffee | 12 ++++++------ 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/4chan_x.user.js b/4chan_x.user.js index 17c038894..5d5ca3abf 100644 --- a/4chan_x.user.js +++ b/4chan_x.user.js @@ -2355,6 +2355,14 @@ className: root.hidden ? 'filtered backlink' : 'backlink', textContent: quoteBacklink.funk(id) }); + if (conf['Quote Preview']) { + $.bind(a, 'mouseover', quotePreview.mouseover); + $.bind(a, 'mousemove', ui.hover); + $.bind(a, 'mouseout', quotePreview.mouseout); + } + if (conf['Quote Inline']) { + $.bind(a, 'click', quoteInline.toggle); + } _results = []; for (qid in quotes) { if (!(el = $.id(qid))) { @@ -2364,14 +2372,6 @@ continue; } link = a.cloneNode(true); - if (conf['Quote Preview']) { - $.bind(link, 'mouseover', quotePreview.mouseover); - $.bind(link, 'mousemove', ui.hover); - $.bind(link, 'mouseout', quotePreview.mouseout); - } - if (conf['Quote Inline']) { - $.bind(link, 'click', quoteInline.toggle); - } if (!((container = $('.container', el)) && container.parentNode === el)) { container = $.el('span', { className: 'container' diff --git a/script.coffee b/script.coffee index 870ee5c9e..1c459f00a 100644 --- a/script.coffee +++ b/script.coffee @@ -1777,17 +1777,17 @@ quoteBacklink = href: "##{id}" className: if root.hidden then 'filtered backlink' else 'backlink' textContent: quoteBacklink.funk id + if conf['Quote Preview'] + $.bind a, 'mouseover', quotePreview.mouseover + $.bind a, 'mousemove', ui.hover + $.bind a, 'mouseout', quotePreview.mouseout + if conf['Quote Inline'] + $.bind a, 'click', quoteInline.toggle for qid of quotes continue unless el = $.id qid #don't backlink the op continue if !conf['OP Backlinks'] and el.className is 'op' link = a.cloneNode true - if conf['Quote Preview'] - $.bind link, 'mouseover', quotePreview.mouseover - $.bind link, 'mousemove', ui.hover - $.bind link, 'mouseout', quotePreview.mouseout - if conf['Quote Inline'] - $.bind link, 'click', quoteInline.toggle unless (container = $ '.container', el) and container.parentNode is el container = $.el 'span', className: 'container' root = $('.reportbutton', el) or $('span[id]', el) From 85d612886f5142bb1e929e6a189711e26479e6d7 Mon Sep 17 00:00:00 2001 From: James Campos Date: Mon, 31 Oct 2011 09:23:38 -0700 Subject: [PATCH 025/169] Revert "do more outside the loop" This reverts commit f6d5c3309337cb369779036380ddec5816dda3e6. --- 4chan_x.user.js | 16 ++++++++-------- script.coffee | 12 ++++++------ 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/4chan_x.user.js b/4chan_x.user.js index 5d5ca3abf..17c038894 100644 --- a/4chan_x.user.js +++ b/4chan_x.user.js @@ -2355,14 +2355,6 @@ className: root.hidden ? 'filtered backlink' : 'backlink', textContent: quoteBacklink.funk(id) }); - if (conf['Quote Preview']) { - $.bind(a, 'mouseover', quotePreview.mouseover); - $.bind(a, 'mousemove', ui.hover); - $.bind(a, 'mouseout', quotePreview.mouseout); - } - if (conf['Quote Inline']) { - $.bind(a, 'click', quoteInline.toggle); - } _results = []; for (qid in quotes) { if (!(el = $.id(qid))) { @@ -2372,6 +2364,14 @@ continue; } link = a.cloneNode(true); + if (conf['Quote Preview']) { + $.bind(link, 'mouseover', quotePreview.mouseover); + $.bind(link, 'mousemove', ui.hover); + $.bind(link, 'mouseout', quotePreview.mouseout); + } + if (conf['Quote Inline']) { + $.bind(link, 'click', quoteInline.toggle); + } if (!((container = $('.container', el)) && container.parentNode === el)) { container = $.el('span', { className: 'container' diff --git a/script.coffee b/script.coffee index 1c459f00a..870ee5c9e 100644 --- a/script.coffee +++ b/script.coffee @@ -1777,17 +1777,17 @@ quoteBacklink = href: "##{id}" className: if root.hidden then 'filtered backlink' else 'backlink' textContent: quoteBacklink.funk id - if conf['Quote Preview'] - $.bind a, 'mouseover', quotePreview.mouseover - $.bind a, 'mousemove', ui.hover - $.bind a, 'mouseout', quotePreview.mouseout - if conf['Quote Inline'] - $.bind a, 'click', quoteInline.toggle for qid of quotes continue unless el = $.id qid #don't backlink the op continue if !conf['OP Backlinks'] and el.className is 'op' link = a.cloneNode true + if conf['Quote Preview'] + $.bind link, 'mouseover', quotePreview.mouseover + $.bind link, 'mousemove', ui.hover + $.bind link, 'mouseout', quotePreview.mouseout + if conf['Quote Inline'] + $.bind link, 'click', quoteInline.toggle unless (container = $ '.container', el) and container.parentNode is el container = $.el 'span', className: 'container' root = $('.reportbutton', el) or $('span[id]', el) From 4fa1ad3441025128ecd304cf57f196444e753ddb Mon Sep 17 00:00:00 2001 From: James Campos Date: Mon, 31 Oct 2011 09:24:42 -0700 Subject: [PATCH 026/169] switch order of conditionals --- 4chan_x.user.js | 2 +- script.coffee | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/4chan_x.user.js b/4chan_x.user.js index 17c038894..ac47b4ec5 100644 --- a/4chan_x.user.js +++ b/4chan_x.user.js @@ -2360,7 +2360,7 @@ if (!(el = $.id(qid))) { continue; } - if (!conf['OP Backlinks'] && el.className === 'op') { + if (el.className === 'op' && !conf['OP Backlinks']) { continue; } link = a.cloneNode(true); diff --git a/script.coffee b/script.coffee index 870ee5c9e..5c3a0bfed 100644 --- a/script.coffee +++ b/script.coffee @@ -1780,7 +1780,7 @@ quoteBacklink = for qid of quotes continue unless el = $.id qid #don't backlink the op - continue if !conf['OP Backlinks'] and el.className is 'op' + continue if el.className is 'op' and !conf['OP Backlinks'] link = a.cloneNode true if conf['Quote Preview'] $.bind link, 'mouseover', quotePreview.mouseover From 66411f0b1ff572c366953364d5b76e5d9112c9aa Mon Sep 17 00:00:00 2001 From: Nicolas Stepien Date: Mon, 31 Oct 2011 17:44:24 +0100 Subject: [PATCH 027/169] Fix #362 --- 4chan_x.user.js | 6 +++--- script.coffee | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/4chan_x.user.js b/4chan_x.user.js index ac47b4ec5..ff6f52407 100644 --- a/4chan_x.user.js +++ b/4chan_x.user.js @@ -2450,10 +2450,10 @@ _ref = $$('.backlink.inlined:not(.filtered)', table); for (_i = 0, _len = _ref.length; _i < _len; _i++) { inlined = _ref[_i]; - $.x('ancestor::table[1]', $.id(inlined.hash.slice(1))).hidden = false; + $.x('ancestor::table', $.id(inlined.hash.slice(1))).hidden = false; } - if (!q.classList.contains('filtered')) { - $.x('ancestor::table[1]', $.id(id)).hidden = false; + if (q.classList.contains('backlink') && !q.classList.contains('filtered')) { + $.x('ancestor::table', $.id(id)).hidden = false; } return $.rm(table); }, diff --git a/script.coffee b/script.coffee index 5c3a0bfed..a6b67f7db 100644 --- a/script.coffee +++ b/script.coffee @@ -1835,9 +1835,9 @@ quoteInline = #select the corresponding table or loading td table = $.x "following::*[@id='i#{id}']", q for inlined in $$ '.backlink.inlined:not(.filtered)', table - $.x('ancestor::table[1]', $.id inlined.hash[1..]).hidden = false - unless q.classList.contains 'filtered' - $.x('ancestor::table[1]', $.id id).hidden = false + $.x('ancestor::table', $.id inlined.hash[1..]).hidden = false + if q.classList.contains('backlink') and not q.classList.contains 'filtered' + $.x('ancestor::table', $.id id).hidden = false $.rm table parse: (req, pathname, id, threadID, inline) -> From 6e0dadd5ec01047005687f8a1e0d8883b7cf9771 Mon Sep 17 00:00:00 2001 From: Nicolas Stepien Date: Mon, 31 Oct 2011 17:48:07 +0100 Subject: [PATCH 028/169] Fix #361 --- 4chan_x.user.js | 8 +++----- script.coffee | 7 +++---- 2 files changed, 6 insertions(+), 9 deletions(-) diff --git a/4chan_x.user.js b/4chan_x.user.js index ff6f52407..109014712 100644 --- a/4chan_x.user.js +++ b/4chan_x.user.js @@ -3097,11 +3097,6 @@ if (conf['Indicate OP quote']) { quoteOP.init(); } - if (g.REPLY) { - if (conf['Image Preloading']) { - imgPreloading.init(); - } - } if (d.body) { return Main.onLoad(); } else { @@ -3143,6 +3138,9 @@ if (conf['Thread Stats']) { threadStats.init(); } + if (conf['Image Preloading']) { + imgPreloading.init(); + } if (conf['Reply Navigation']) { nav.init(); } diff --git a/script.coffee b/script.coffee index a6b67f7db..8b5445afa 100644 --- a/script.coffee +++ b/script.coffee @@ -2359,10 +2359,6 @@ Main = if conf['Indicate OP quote'] quoteOP.init() - if g.REPLY - if conf['Image Preloading'] - imgPreloading.init() - if d.body Main.onLoad() @@ -2404,6 +2400,9 @@ Main = if conf['Thread Stats'] threadStats.init() + if conf['Image Preloading'] + imgPreloading.init() + if conf['Reply Navigation'] nav.init() From d0da46ab82e388420491d1303ecc785792576035 Mon Sep 17 00:00:00 2001 From: Nicolas Stepien Date: Mon, 31 Oct 2011 18:54:20 +0100 Subject: [PATCH 029/169] -1 div required to center properly (options & firstrun) --- 4chan_x.user.js | 180 +++++++++++++++++++++++----------------------- script.coffee | 188 +++++++++++++++++++++++------------------------- 2 files changed, 182 insertions(+), 186 deletions(-) diff --git a/4chan_x.user.js b/4chan_x.user.js index 109014712..fc3fb2a5d 100644 --- a/4chan_x.user.js +++ b/4chan_x.user.js @@ -1221,84 +1221,83 @@ var arr, back, checked, description, dialog, hiddenNum, hiddenThreads, input, key, li, obj, overlay, ta, time, ul, _i, _j, _len, _len2, _ref, _ref2, _ref3; dialog = $.el('div', { id: 'options', + className: 'reply dialog', innerHTML: '\ -
\ -
\ -
\ - 4chan X\ - | Issues\ - | Donate\ -
\ -
\ - \ - | \ - | \ - | \ - | \ -
\ +
\ +
\ + 4chan X\ + | Issues\ + | Donate\
\ -
\ -
\ - \ -
\ - \ - \ - \ -
\ - Use regular expressions, one per line.
\ - For example, /weeaboo/i will filter posts containing `weeaboo` case-insensitive.\ -

Name:

\ -

Tripcode:

\ -

E-mail:

\ -

Subject:

\ -

Comment:

\ -

Filename:

\ -

Image MD5:

\ -
\ - \ -
\ -
    \ - Backlink formatting\ -
  • :
  • \ -
\ -
    \ - Time formatting\ -
  • :
  • \ -
  • Supported format specifiers:
  • \ -
  • Day: %a, %A, %d, %e
  • \ -
  • Month: %m, %b, %B
  • \ -
  • Year: %y
  • \ -
  • Hour: %k, %H, %l (lowercase L), %I (uppercase i), %p, %P
  • \ -
  • Minutes: %M
  • \ -
\ -
\ - \ -
\ - \ - \ - \ - \ - \ - \ - \ - \ - \ - \ - \ - \ - \ - \ - \ - \ - \ - \ - \ - \ - \ - \ - \ -
ActionsKeybinds
Close Options or QR
Quick spoiler
Open QR with post number inserted
Open QR without post number inserted
Submit post
Select next reply
Select previous reply
See next thread
See previous thread
Jump to the next page
Jump to the previous page
Jump to page 0
Open thread in current tab
Open thread in new tab
Expand thread
Watch thread
Hide thread
Expand selected image
Expand all images
Update now
Reset the unread count to 0
\ -
\ +
\ + \ + | \ + | \ + | \ + | \ +
\ +
\ +
\ +
\ + \ +
\ + \ + \ + \ +
\ + Use regular expressions, one per line.
\ + For example, /weeaboo/i will filter posts containing `weeaboo` case-insensitive.\ +

Name:

\ +

Tripcode:

\ +

E-mail:

\ +

Subject:

\ +

Comment:

\ +

Filename:

\ +

Image MD5:

\ +
\ + \ +
\ +
    \ + Backlink formatting\ +
  • :
  • \ +
\ +
    \ + Time formatting\ +
  • :
  • \ +
  • Supported format specifiers:
  • \ +
  • Day: %a, %A, %d, %e
  • \ +
  • Month: %m, %b, %B
  • \ +
  • Year: %y
  • \ +
  • Hour: %k, %H, %l (lowercase L), %I (uppercase i), %p, %P
  • \ +
  • Minutes: %M
  • \ +
\ +
\ + \ +
\ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ +
ActionsKeybinds
Close Options or QR
Quick spoiler
Open QR with post number inserted
Open QR without post number inserted
Submit post
Select next reply
Select previous reply
See next thread
See previous thread
Jump to the next page
Jump to the previous page
Jump to page 0
Open thread in current tab
Open thread in new tab
Expand thread
Watch thread
Hide thread
Expand selected image
Expand all images
Update now
Reset the unread count to 0
\
\
' }); @@ -1344,19 +1343,13 @@ input.value = conf[input.name]; $.bind(input, 'keydown', options.keybind); } - /* - Two parent divs are necessary to center on all browsers. - - Only one when Firefox and Opera will support flexboxes correctly. - https://bugzilla.mozilla.org/show_bug.cgi?id=579776 - */ overlay = $.el('div', { id: 'overlay' }); $.bind(overlay, 'click', function() { return $.rm(overlay); }); - $.bind(dialog.firstElementChild, 'click', function(e) { + $.bind(dialog, 'click', function(e) { return e.stopPropagation(); }); $.add(overlay, dialog); @@ -3002,7 +2995,12 @@ dialog = $.el('div', { id: 'overlay', className: 'firstrun', - innerHTML: "

Click the 4chan X buttons for options; they are at the top and bottom of the page.

Updater options are in the updater dialog in replies at the bottom-right corner of the window.

If you don't see the buttons, try disabling your userstyles.

" + innerHTML: '\ +
\ +

Click the 4chan X buttons for options; they are at the top and bottom of the page.

\ +

Updater options are in the updater dialog in replies at the bottom-right corner of the window.

\ +

If you don\'t see the buttons, try disabling your userstyles.

\ +
' }); $.add(d.body, dialog); return $.bind(window, 'click', firstRun.close); @@ -3253,21 +3251,25 @@ }\ \ #overlay {\ - display: table;\ position: fixed;\ top: 0;\ left: 0;\ height: 100%;\ width: 100%;\ + text-align: center;\ background: rgba(0,0,0,.5);\ }\ - #options {\ - display: table-cell;\ + #overlay::before {\ + content: "";\ + display: inline-block;\ + height: 100%;\ vertical-align: middle;\ }\ - #options .dialog {\ - margin: auto;\ + #options {\ + display: inline-block;\ padding: 5px;\ + text-align: left;\ + vertical-align: middle;\ width: 500px;\ }\ #credits {\ diff --git a/script.coffee b/script.coffee index 8b5445afa..81e9a2749 100644 --- a/script.coffee +++ b/script.coffee @@ -865,84 +865,82 @@ options = $.replace home, a dialog: -> - dialog = $.el 'div', id: 'options', innerHTML: ' -
-
-
- 4chan X - | Issues - | Donate -
-
- - | - | - | - | -
+ dialog = $.el 'div', id: 'options', className: 'reply dialog', innerHTML: ' +
+
+ 4chan X + | Issues + | Donate
-
-
- -
- - - -
- Use regular expressions, one per line.
- For example, /weeaboo/i will filter posts containing `weeaboo` case-insensitive. -

Name:

-

Tripcode:

-

E-mail:

-

Subject:

-

Comment:

-

Filename:

-

Image MD5:

-
- -
-
    - Backlink formatting -
  • :
  • -
-
    - Time formatting -
  • :
  • -
  • Supported format specifiers:
  • -
  • Day: %a, %A, %d, %e
  • -
  • Month: %m, %b, %B
  • -
  • Year: %y
  • -
  • Hour: %k, %H, %l (lowercase L), %I (uppercase i), %p, %P
  • -
  • Minutes: %M
  • -
-
- -
- - - - - - - - - - - - - - - - - - - - - - - -
ActionsKeybinds
Close Options or QR
Quick spoiler
Open QR with post number inserted
Open QR without post number inserted
Submit post
Select next reply
Select previous reply
See next thread
See previous thread
Jump to the next page
Jump to the previous page
Jump to page 0
Open thread in current tab
Open thread in new tab
Expand thread
Watch thread
Hide thread
Expand selected image
Expand all images
Update now
Reset the unread count to 0
-
+
+ + | + | + | + | +
+
+
+
+ +
+ + + +
+ Use regular expressions, one per line.
+ For example, /weeaboo/i will filter posts containing `weeaboo` case-insensitive. +

Name:

+

Tripcode:

+

E-mail:

+

Subject:

+

Comment:

+

Filename:

+

Image MD5:

+
+ +
+
    + Backlink formatting +
  • :
  • +
+
    + Time formatting +
  • :
  • +
  • Supported format specifiers:
  • +
  • Day: %a, %A, %d, %e
  • +
  • Month: %m, %b, %B
  • +
  • Year: %y
  • +
  • Hour: %k, %H, %l (lowercase L), %I (uppercase i), %p, %P
  • +
  • Minutes: %M
  • +
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + +
ActionsKeybinds
Close Options or QR
Quick spoiler
Open QR with post number inserted
Open QR without post number inserted
Submit post
Select next reply
Select previous reply
See next thread
See previous thread
Jump to the next page
Jump to the previous page
Jump to page 0
Open thread in current tab
Open thread in new tab
Expand thread
Watch thread
Hide thread
Expand selected image
Expand all images
Update now
Reset the unread count to 0
' @@ -983,15 +981,9 @@ options = input.value = conf[input.name] $.bind input, 'keydown', options.keybind - ### - Two parent divs are necessary to center on all browsers. - - Only one when Firefox and Opera will support flexboxes correctly. - https://bugzilla.mozilla.org/show_bug.cgi?id=579776 - ### overlay = $.el 'div', id: 'overlay' $.bind overlay, 'click', -> $.rm overlay - $.bind dialog.firstElementChild, 'click', (e) -> e.stopPropagation() + $.bind dialog, 'click', (e) -> e.stopPropagation() $.add overlay, dialog $.add d.body, overlay @@ -2258,14 +2250,12 @@ firstRun = dialog = $.el 'div', id: 'overlay' className: 'firstrun' - innerHTML: " -
-
-

Click the 4chan X buttons for options; they are at the top and bottom of the page.

-

Updater options are in the updater dialog in replies at the bottom-right corner of the window.

-

If you don't see the buttons, try disabling your userstyles.

-
-
" + innerHTML: ' +
+

Click the 4chan X buttons for options; they are at the top and bottom of the page.

+

Updater options are in the updater dialog in replies at the bottom-right corner of the window.

+

If you don\'t see the buttons, try disabling your userstyles.

+
' $.add d.body, dialog $.bind window, 'click', firstRun.close @@ -2506,21 +2496,25 @@ Main = } #overlay { - display: table; position: fixed; top: 0; left: 0; height: 100%; width: 100%; + text-align: center; background: rgba(0,0,0,.5); } - #options { - display: table-cell; + #overlay::before { + content: ""; + display: inline-block; + height: 100%; vertical-align: middle; } - #options .dialog { - margin: auto; + #options { + display: inline-block; padding: 5px; + text-align: left; + vertical-align: middle; width: 500px; } #credits { From 90426ea4d842f7c1b475bcba6312012b6b8ee66c Mon Sep 17 00:00:00 2001 From: James Campos Date: Mon, 31 Oct 2011 17:00:29 -0700 Subject: [PATCH 030/169] use ui.dialog --- 4chan_x.user.js | 14 ++++++-------- script.coffee | 4 ++-- 2 files changed, 8 insertions(+), 10 deletions(-) diff --git a/4chan_x.user.js b/4chan_x.user.js index fc3fb2a5d..8569a520b 100644 --- a/4chan_x.user.js +++ b/4chan_x.user.js @@ -207,13 +207,15 @@ }; ui = { dialog: function(id, position, html) { - var el, saved; + var el, saved, _ref; el = d.createElement('div'); el.className = 'reply dialog'; el.innerHTML = html; el.id = id; el.style.cssText = (saved = localStorage["" + NAMESPACE + id + ".position"]) ? saved : position; - el.querySelector('div.move').addEventListener('mousedown', ui.dragstart, false); + if ((_ref = el.querySelector('div.move')) != null) { + _ref.addEventListener('mousedown', ui.dragstart, false); + } return el; }, dragstart: function(e) { @@ -1219,10 +1221,7 @@ }, dialog: function() { var arr, back, checked, description, dialog, hiddenNum, hiddenThreads, input, key, li, obj, overlay, ta, time, ul, _i, _j, _len, _len2, _ref, _ref2, _ref3; - dialog = $.el('div', { - id: 'options', - className: 'reply dialog', - innerHTML: '\ + dialog = ui.dialog('options', '', '\
\
\ 4chan X\ @@ -1299,8 +1298,7 @@ Reset the unread count to 0\ \
\ -
' - }); +
'); _ref = config.main; for (key in _ref) { obj = _ref[key]; diff --git a/script.coffee b/script.coffee index 81e9a2749..2383d36de 100644 --- a/script.coffee +++ b/script.coffee @@ -134,7 +134,7 @@ ui = el.innerHTML = html el.id = id el.style.cssText = if saved = localStorage["#{NAMESPACE}#{id}.position"] then saved else position - el.querySelector('div.move').addEventListener 'mousedown', ui.dragstart, false + el.querySelector('div.move')?.addEventListener 'mousedown', ui.dragstart, false el dragstart: (e) -> #prevent text selection @@ -865,7 +865,7 @@ options = $.replace home, a dialog: -> - dialog = $.el 'div', id: 'options', className: 'reply dialog', innerHTML: ' + dialog = ui.dialog 'options', '', '
4chan X From 85f03df6033ec3544da0e2a3280ca3d3fc1e5150 Mon Sep 17 00:00:00 2001 From: Nicolas Stepien Date: Tue, 1 Nov 2011 04:36:43 +0100 Subject: [PATCH 031/169] foolz archive /m/ and /tg/ too now. --- 4chan_x.user.js | 2 ++ script.coffee | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/4chan_x.user.js b/4chan_x.user.js index 8569a520b..00123f105 100644 --- a/4chan_x.user.js +++ b/4chan_x.user.js @@ -2730,6 +2730,8 @@ break; case 'a': case 'jp': + case 'm': + case 'tg': case 'tv': url = "http://archive.foolz.us/" + g.BOARD + "/thread/" + g.THREAD_ID; break; diff --git a/script.coffee b/script.coffee index 2383d36de..f411ee56b 100644 --- a/script.coffee +++ b/script.coffee @@ -2033,7 +2033,7 @@ redirect = -> url = "http://archive.installgentoo.net/#{g.BOARD}/thread/#{g.THREAD_ID}" when 'lit' url = "http://archive.gentoomen.org/cgi-board.pl/#{g.BOARD}/thread/#{g.THREAD_ID}" - when 'a', 'jp', 'tv' + when 'a', 'jp', 'm', 'tg', 'tv' url = "http://archive.foolz.us/#{g.BOARD}/thread/#{g.THREAD_ID}" when '3', 'adv', 'an', 'ck', 'co', 'fa', 'fit', 'int', 'k', 'mu', 'n', 'o', 'p', 'po', 'soc', 'sp', 'toy', 'trv', 'v', 'vp', 'x' url = "http://archive.no-ip.org/#{g.BOARD}/thread/#{g.THREAD_ID}" From 7e3d36036425e6b270442256c590a00b4db1419c Mon Sep 17 00:00:00 2001 From: James Campos Date: Mon, 31 Oct 2011 20:38:42 -0700 Subject: [PATCH 032/169] sort by domain --- 4chan_x.user.js | 18 +++++++++--------- script.coffee | 8 ++++---- 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/4chan_x.user.js b/4chan_x.user.js index 00123f105..014937655 100644 --- a/4chan_x.user.js +++ b/4chan_x.user.js @@ -2719,15 +2719,6 @@ redirect = function() { var url; switch (g.BOARD) { - case 'diy': - case 'g': - case 'pol': - case 'sci': - url = "http://archive.installgentoo.net/" + g.BOARD + "/thread/" + g.THREAD_ID; - break; - case 'lit': - url = "http://archive.gentoomen.org/cgi-board.pl/" + g.BOARD + "/thread/" + g.THREAD_ID; - break; case 'a': case 'jp': case 'm': @@ -2735,6 +2726,15 @@ case 'tv': url = "http://archive.foolz.us/" + g.BOARD + "/thread/" + g.THREAD_ID; break; + case 'lit': + url = "http://archive.gentoomen.org/cgi-board.pl/" + g.BOARD + "/thread/" + g.THREAD_ID; + break; + case 'diy': + case 'g': + case 'pol': + case 'sci': + url = "http://archive.installgentoo.net/" + g.BOARD + "/thread/" + g.THREAD_ID; + break; case '3': case 'adv': case 'an': diff --git a/script.coffee b/script.coffee index f411ee56b..33ae2601f 100644 --- a/script.coffee +++ b/script.coffee @@ -2029,12 +2029,12 @@ Favicon = redirect = -> switch g.BOARD - when 'diy', 'g', 'pol', 'sci' - url = "http://archive.installgentoo.net/#{g.BOARD}/thread/#{g.THREAD_ID}" - when 'lit' - url = "http://archive.gentoomen.org/cgi-board.pl/#{g.BOARD}/thread/#{g.THREAD_ID}" when 'a', 'jp', 'm', 'tg', 'tv' url = "http://archive.foolz.us/#{g.BOARD}/thread/#{g.THREAD_ID}" + when 'lit' + url = "http://archive.gentoomen.org/cgi-board.pl/#{g.BOARD}/thread/#{g.THREAD_ID}" + when 'diy', 'g', 'pol', 'sci' + url = "http://archive.installgentoo.net/#{g.BOARD}/thread/#{g.THREAD_ID}" when '3', 'adv', 'an', 'ck', 'co', 'fa', 'fit', 'int', 'k', 'mu', 'n', 'o', 'p', 'po', 'soc', 'sp', 'toy', 'trv', 'v', 'vp', 'x' url = "http://archive.no-ip.org/#{g.BOARD}/thread/#{g.THREAD_ID}" else From a552ea843ffb444d968c41520d4512b6c9c04765 Mon Sep 17 00:00:00 2001 From: Nicolas Stepien Date: Thu, 3 Nov 2011 06:18:18 +0100 Subject: [PATCH 033/169] Do the backlinks after quote inlining/previewing. --- 4chan_x.user.js | 6 +++--- script.coffee | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/4chan_x.user.js b/4chan_x.user.js index 014937655..a4501433c 100644 --- a/4chan_x.user.js +++ b/4chan_x.user.js @@ -3083,15 +3083,15 @@ if (conf['Report Button']) { reportButton.init(); } - if (conf['Quote Backlinks']) { - quoteBacklink.init(); - } if (conf['Quote Inline']) { quoteInline.init(); } if (conf['Quote Preview']) { quotePreview.init(); } + if (conf['Quote Backlinks']) { + quoteBacklink.init(); + } if (conf['Indicate OP quote']) { quoteOP.init(); } diff --git a/script.coffee b/script.coffee index 33ae2601f..442057a24 100644 --- a/script.coffee +++ b/script.coffee @@ -2337,15 +2337,15 @@ Main = if conf['Report Button'] reportButton.init() - if conf['Quote Backlinks'] - quoteBacklink.init() - if conf['Quote Inline'] quoteInline.init() if conf['Quote Preview'] quotePreview.init() + if conf['Quote Backlinks'] + quoteBacklink.init() + if conf['Indicate OP quote'] quoteOP.init() From 61730c93cfa2b2e55f6bcd0550bbbe2faa7732da Mon Sep 17 00:00:00 2001 From: Nicolas Stepien Date: Thu, 3 Nov 2011 22:51:07 +0100 Subject: [PATCH 034/169] classList.contains() is actually really slow. --- 4chan_x.user.js | 12 ++++++------ script.coffee | 12 ++++++------ 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/4chan_x.user.js b/4chan_x.user.js index 014937655..5ef15da9c 100644 --- a/4chan_x.user.js +++ b/4chan_x.user.js @@ -1835,7 +1835,7 @@ } }, toggle: function(thread) { - if (thread.classList.contains('stub') || thread.hidden) { + if (/\bstub\b/.test(thread.className) || thread.hidden) { return threadHiding.show(thread); } else { return threadHiding.hide(thread); @@ -2328,7 +2328,7 @@ quoteBacklink.funk = Function('id', "return'" + format + "'"); return g.callbacks.push(function(root) { var a, container, el, id, link, qid, quote, quotes, _i, _len, _ref, _results; - if (root.classList.contains('inline')) { + if (/\binline\b/.test(root.className)) { return; } quotes = {}; @@ -2400,7 +2400,7 @@ } e.preventDefault(); id = this.hash.slice(1); - if (this.classList.contains('inlined')) { + if (/\binlined\b/.test(this.className)) { quoteInline.rm(this, id); } else { if ($.x("ancestor::*[@id='" + id + "']", this)) { @@ -2443,7 +2443,7 @@ inlined = _ref[_i]; $.x('ancestor::table', $.id(inlined.hash.slice(1))).hidden = false; } - if (q.classList.contains('backlink') && !q.classList.contains('filtered')) { + if (/\bbacklink\b/.test(q.className) && !/\bfiltered\b/.test(q.className)) { $.x('ancestor::table', $.id(id)).hidden = false; } return $.rm(table); @@ -2528,7 +2528,7 @@ if (conf['Quote Highlighting']) { $.addClass(el, 'qphl'); } - if (this.classList.contains('backlink')) { + if (/\bbacklink\b/.test(this.className)) { replyID = $.x('preceding::input', this).name; _ref = $$('.quotelink', qp); _results = []; @@ -2901,7 +2901,7 @@ } form = $('body > form'); form.className = klass; - if (form.classList.contains('fitheight')) { + if (/\bfitheight\b/.test(form.className)) { $.bind(window, 'resize', imgExpand.resize); if (!imgExpand.style) { imgExpand.style = $.addStyle(''); diff --git a/script.coffee b/script.coffee index 33ae2601f..82026b602 100644 --- a/script.coffee +++ b/script.coffee @@ -1372,7 +1372,7 @@ threadHiding = threadHiding.show thread toggle: (thread) -> - if thread.classList.contains('stub') or thread.hidden + if /\bstub\b/.test(thread.className) or thread.hidden threadHiding.show thread else threadHiding.hide thread @@ -1756,7 +1756,7 @@ quoteBacklink = format = conf['backlink'].replace /%id/, "' + id + '" quoteBacklink.funk = Function 'id', "return'#{format}'" g.callbacks.push (root) -> - return if root.classList.contains 'inline' + return if /\binline\b/.test root.className quotes = {} for quote in $$ '.quotelink', root #don't process >>>/b/ @@ -1797,7 +1797,7 @@ quoteInline = return if e.shiftKey or e.altKey or e.ctrlKey or e.button isnt 0 e.preventDefault() id = @hash[1..] - if @classList.contains 'inlined' + if /\binlined\b/.test @className quoteInline.rm @, id else return if $.x("ancestor::*[@id='#{id}']", @) @@ -1828,7 +1828,7 @@ quoteInline = table = $.x "following::*[@id='i#{id}']", q for inlined in $$ '.backlink.inlined:not(.filtered)', table $.x('ancestor::table', $.id inlined.hash[1..]).hidden = false - if q.classList.contains('backlink') and not q.classList.contains 'filtered' + if /\bbacklink\b/.test(q.className) and not /\bfiltered\b/.test q.className $.x('ancestor::table', $.id id).hidden = false $.rm table @@ -1884,7 +1884,7 @@ quotePreview = if el = $.id id qp.innerHTML = el.innerHTML $.addClass el, 'qphl' if conf['Quote Highlighting'] - if @classList.contains 'backlink' + if /\bbacklink\b/.test @className replyID = $.x('preceding::input', @).name for quote in $$ '.quotelink', qp if quote.hash[1..] is replyID @@ -2122,7 +2122,7 @@ imgExpand = klass = 'fitwidth fitheight' form = $('body > form') form.className = klass - if form.classList.contains 'fitheight' + if /\bfitheight\b/.test form.className $.bind window, 'resize', imgExpand.resize unless imgExpand.style imgExpand.style = $.addStyle '' From 8638a5bfabbf6251e134d9620d8a34511d05ead3 Mon Sep 17 00:00:00 2001 From: James Campos Date: Fri, 4 Nov 2011 21:09:39 -0700 Subject: [PATCH 035/169] {un,}bind -> {off,on} --- 4chan_x.user.js | 152 ++++++++++++++++++++++++------------------------ script.coffee | 152 ++++++++++++++++++++++++------------------------ 2 files changed, 152 insertions(+), 152 deletions(-) diff --git a/4chan_x.user.js b/4chan_x.user.js index 77cb43730..d9b4f93dd 100644 --- a/4chan_x.user.js +++ b/4chan_x.user.js @@ -403,10 +403,10 @@ } return el; }, - bind: function(el, eventType, handler) { + on: function(el, eventType, handler) { return el.addEventListener(eventType, handler, false); }, - unbind: function(el, eventType, handler) { + off: function(el, eventType, handler) { return el.removeEventListener(eventType, handler, false); }, isDST: function() { @@ -612,7 +612,7 @@ _results = []; for (_i = 0, _len = _ref.length; _i < _len; _i++) { a = _ref[_i]; - _results.push($.bind(a, 'click', expandComment.expand)); + _results.push($.on(a, 'click', expandComment.expand)); } return _results; }, @@ -658,12 +658,12 @@ quote.innerHTML += ' (OP)'; } if (conf['Quote Preview']) { - $.bind(quote, 'mouseover', quotePreview.mouseover); - $.bind(quote, 'mousemove', ui.hover); - $.bind(quote, 'mouseout', quotePreview.mouseout); + $.on(quote, 'mouseover', quotePreview.mouseover); + $.on(quote, 'mousemove', ui.hover); + $.on(quote, 'mouseout', quotePreview.mouseout); } if (conf['Quote Inline']) { - $.bind(quote, 'click', quoteInline.toggle); + $.on(quote, 'click', quoteInline.toggle); } } return $.replace(a.parentNode.parentNode, bq); @@ -680,7 +680,7 @@ textContent: "+ " + span.textContent, className: 'omittedposts' }); - $.bind(a, 'click', expandThread.cb.toggle); + $.on(a, 'click', expandThread.cb.toggle); _results.push($.replace(span, a)); } return _results; @@ -738,7 +738,7 @@ var body, br, href, link, next, quote, reply, table, tables, _i, _j, _k, _len, _len2, _len3, _ref, _ref2, _results; if (req.status !== 200) { a.textContent = "" + req.status + " " + req.statusText; - $.unbind(a, 'click', expandThread.cb.toggle); + $.off(a, 'click', expandThread.cb.toggle); return; } a.textContent = a.textContent.replace('X Loading...', '-'); @@ -786,7 +786,7 @@ a = $.el('a', { textContent: '[ - ]' }); - $.bind(a, 'click', replyHiding.cb.hide); + $.on(a, 'click', replyHiding.cb.hide); $.replace(dd.firstChild, a); reply = dd.nextSibling; id = reply.id; @@ -831,7 +831,7 @@ a = $.el('a', { textContent: "[ + ] " + name + " " + trip }); - $.bind(a, 'click', replyHiding.cb.show); + $.on(a, 'click', replyHiding.cb.show); div = $.el('div', { className: 'stub' }); @@ -860,7 +860,7 @@ node = _ref[_i]; node.removeAttribute('accesskey'); } - return $.bind(d, 'keydown', keybinds.keydown); + return $.on(d, 'keydown', keybinds.keydown); }, keydown: function(e) { var o, range, selEnd, selStart, ta, thread, valEnd, valMid, valStart, value, _ref, _ref2, _ref3; @@ -1139,8 +1139,8 @@ next = $.el('a', { textContent: 'â–¼' }); - $.bind(prev, 'click', nav.prev); - $.bind(next, 'click', nav.next); + $.on(prev, 'click', nav.prev); + $.on(next, 'click', nav.next); $.add(span, prev, $.tn(' '), next); return $.add(d.body, span); }, @@ -1210,13 +1210,13 @@ a = $.el('a', { textContent: '4chan X' }); - $.bind(a, 'click', options.dialog); + $.on(a, 'click', options.dialog); $.replace(home, a); home = $('#navbotr a'); a = $.el('a', { textContent: '4chan X' }); - $.bind(a, 'click', options.dialog); + $.on(a, 'click', options.dialog); return $.replace(home, a); }, dialog: function() { @@ -1312,7 +1312,7 @@ li = $.el('li', { innerHTML: ": " + description + "" }); - $.bind($('input', li), 'click', $.cb.checked); + $.on($('input', li), 'click', $.cb.checked); $.add(ul, li); } $.add($('#main', dialog), ul); @@ -1322,32 +1322,32 @@ li = $.el('li', { innerHTML: " : Forget all hidden posts. Useful if you accidentally hide a post and have `Show Stubs` disabled." }); - $.bind($('button', li), 'click', options.clearHidden); + $.on($('button', li), 'click', options.clearHidden); $.add($('ul:nth-child(2)', dialog), li); _ref2 = $$('textarea', dialog); for (_i = 0, _len = _ref2.length; _i < _len; _i++) { ta = _ref2[_i]; ta.textContent = conf[ta.name]; - $.bind(ta, 'change', $.cb.value); + $.on(ta, 'change', $.cb.value); } (back = $('[name=backlink]', dialog)).value = conf['backlink']; (time = $('[name=time]', dialog)).value = conf['time']; - $.bind(back, 'keyup', options.backlink); - $.bind(time, 'keyup', options.time); + $.on(back, 'keyup', options.backlink); + $.on(time, 'keyup', options.time); _ref3 = $$('#keybinds input', dialog); for (_j = 0, _len2 = _ref3.length; _j < _len2; _j++) { input = _ref3[_j]; input.type = 'text'; input.value = conf[input.name]; - $.bind(input, 'keydown', options.keybind); + $.on(input, 'keydown', options.keybind); } overlay = $.el('div', { id: 'overlay' }); - $.bind(overlay, 'click', function() { + $.on(overlay, 'click', function() { return $.rm(overlay); }); - $.bind(dialog, 'click', function(e) { + $.on(dialog, 'click', function(e) { return e.stopPropagation(); }); $.add(overlay, dialog); @@ -1393,7 +1393,7 @@ g.callbacks.push(function(root) { var quote; quote = $('.quotejs + a', root); - return $.bind(quote, 'click', QR.quote); + return $.on(quote, 'click', QR.quote); }); $.add(d.body, $.el('iframe', { name: 'iframe', @@ -1401,7 +1401,7 @@ })); $('#recaptcha_response_field').id = ''; holder = $('#recaptcha_challenge_field_holder'); - $.bind(holder, 'DOMNodeInserted', QR.captchaNode); + $.on(holder, 'DOMNodeInserted', QR.captchaNode); QR.captchaNode({ target: holder.firstChild }); @@ -1425,7 +1425,7 @@ } } if (conf['Cooldown']) { - return $.bind(window, 'storage', function(e) { + return $.on(window, 'storage', function(e) { if (e.key === ("" + NAMESPACE + "cooldown/" + g.BOARD)) { return QR.cooldown(); } @@ -1438,7 +1438,7 @@ box = $.el('li', { innerHTML: "X" }); - $.bind($('.x', box), 'click', QR.rmThumb); + $.on($('.x', box), 'click', QR.rmThumb); $.add(box, file); $.add(files, box); QR.stats(); @@ -1552,7 +1552,7 @@ name: 'upfile', accept: QR.accept }); - $.bind(input, 'change', QR.change); + $.on(input, 'change', QR.change); if (old) { return $.replace(old, file); } else { @@ -1571,9 +1571,9 @@ QR.cooldown(); } QR.foo(); - $.bind($('.close', qr), 'click', QR.close); - $.bind($('form', qr), 'submit', QR.submit); - $.bind($('#recaptcha_response_field', qr), 'keydown', QR.keydown); + $.on($('.close', qr), 'click', QR.close); + $.on($('form', qr), 'submit', QR.submit); + $.on($('#recaptcha_response_field', qr), 'keydown', QR.keydown); QR.captchaImg(); QR.stats(); $.add(d.body, qr); @@ -1735,9 +1735,9 @@ }, sys: function() { var recaptcha; - $.unbind(d, 'DOMContentLoaded', QR.sys); + $.off(d, 'DOMContentLoaded', QR.sys); if (recaptcha = $('#recaptcha_response_field')) { - $.bind(recaptcha, 'keydown', QR.keydown); + $.on(recaptcha, 'keydown', QR.keydown); return; } /* @@ -1816,7 +1816,7 @@ a = $.el('a', { textContent: '[ - ]' }); - $.bind(a, 'click', threadHiding.cb.hide); + $.on(a, 'click', threadHiding.cb.hide); $.prepend(op, a); _results.push(op.id in hiddenThreads ? threadHiding.hideHide(thread) : void 0); } @@ -1864,7 +1864,7 @@ a = $.el('a', { textContent: "[ + ] " + name + trip + " (" + text + ")" }); - $.bind(a, 'click', threadHiding.cb.show); + $.on(a, 'click', threadHiding.cb.show); div = $.el('div', { className: 'block' }); @@ -1898,10 +1898,10 @@ if (conf['Scroll BG']) { updater.focus = true; } else { - $.bind(window, 'focus', (function() { + $.on(window, 'focus', (function() { return updater.focus = true; })); - $.bind(window, 'blur', (function() { + $.on(window, 'blur', (function() { return updater.focus = false; })); } @@ -1923,24 +1923,24 @@ for (_i = 0, _len = _ref.length; _i < _len; _i++) { input = _ref[_i]; if (input.type === 'checkbox') { - $.bind(input, 'click', $.cb.checked); - $.bind(input, 'click', function() { + $.on(input, 'click', $.cb.checked); + $.on(input, 'click', function() { return conf[this.name] = this.checked; }); if (input.name === 'Verbose') { - $.bind(input, 'click', updater.cb.verbose); + $.on(input, 'click', updater.cb.verbose); updater.cb.verbose.call(input); } else if (input.name === 'Auto Update This') { - $.bind(input, 'click', updater.cb.autoUpdate); + $.on(input, 'click', updater.cb.autoUpdate); updater.cb.autoUpdate.call(input); } } else if (input.name === 'Interval') { - $.bind(input, 'change', function() { + $.on(input, 'change', function() { return conf['Interval'] = this.value = parseInt(this.value) || conf['Interval']; }); - $.bind(input, 'change', $.cb.value); + $.on(input, 'change', $.cb.value); } else if (input.type === 'button') { - $.bind(input, 'click', updater.update); + $.on(input, 'click', updater.update); } } return $.add(d.body, dialog); @@ -2055,11 +2055,11 @@ favicon = $.el('img', { className: 'favicon' }); - $.bind(favicon, 'click', watcher.cb.toggle); + $.on(favicon, 'click', watcher.cb.toggle); $.before(input, favicon); } watcher.refresh(); - return $.bind(window, 'storage', function(e) { + return $.on(window, 'storage', function(e) { if (e.key === ("" + NAMESPACE + "watched")) { return watcher.refresh(); } @@ -2081,7 +2081,7 @@ x = $.el('a', { textContent: 'X' }); - $.bind(x, 'click', watcher.cb.x); + $.on(x, 'click', watcher.cb.x); link = $.el('a', props); $.add(div, x, $.tn(' '), link); $.add(watcher.dialog, div); @@ -2356,12 +2356,12 @@ } link = a.cloneNode(true); if (conf['Quote Preview']) { - $.bind(link, 'mouseover', quotePreview.mouseover); - $.bind(link, 'mousemove', ui.hover); - $.bind(link, 'mouseout', quotePreview.mouseout); + $.on(link, 'mouseover', quotePreview.mouseover); + $.on(link, 'mousemove', ui.hover); + $.on(link, 'mouseout', quotePreview.mouseout); } if (conf['Quote Inline']) { - $.bind(link, 'click', quoteInline.toggle); + $.on(link, 'click', quoteInline.toggle); } if (!((container = $('.container', el)) && container.parentNode === el)) { container = $.el('span', { @@ -2388,7 +2388,7 @@ continue; } quote.removeAttribute('onclick'); - _results.push($.bind(quote, 'click', quoteInline.toggle)); + _results.push($.on(quote, 'click', quoteInline.toggle)); } return _results; }); @@ -2508,9 +2508,9 @@ if (!quote.hash) { continue; } - $.bind(quote, 'mouseover', quotePreview.mouseover); - $.bind(quote, 'mousemove', ui.hover); - _results.push($.bind(quote, 'mouseout', quotePreview.mouseout)); + $.on(quote, 'mouseover', quotePreview.mouseover); + $.on(quote, 'mousemove', ui.hover); + _results.push($.on(quote, 'mouseout', quotePreview.mouseout)); } return _results; }); @@ -2614,7 +2614,7 @@ $.after(span, a); $.after(span, $.tn(' ')); } - return $.bind(a, 'click', reportButton.report); + return $.on(a, 'click', reportButton.report); }); }, report: function() { @@ -2655,7 +2655,7 @@ init: function() { unread.replies = []; d.title = '(0) ' + d.title; - $.bind(window, 'scroll', unread.scroll); + $.on(window, 'scroll', unread.scroll); return g.callbacks.push(unread.node); }, node: function(root) { @@ -2770,9 +2770,9 @@ if (!(thumb = $('img[md5]', root))) { return; } - $.bind(thumb, 'mouseover', imgHover.mouseover); - $.bind(thumb, 'mousemove', ui.hover); - return $.bind(thumb, 'mouseout', ui.hoverend); + $.on(thumb, 'mouseover', imgHover.mouseover); + $.on(thumb, 'mousemove', ui.hover); + return $.on(thumb, 'mouseout', ui.hoverend); }); }, mouseover: function() { @@ -2796,7 +2796,7 @@ label = $.el('label', { innerHTML: 'Preload Images' }); - $.bind($('input', label), 'click', imgPreloading.click); + $.on($('input', label), 'click', imgPreloading.click); $.add(controls, label); return g.callbacks.push(imgPreloading.node); }, @@ -2850,7 +2850,7 @@ return; } a = thumb.parentNode; - $.bind(a, 'click', imgExpand.cb.toggle); + $.on(a, 'click', imgExpand.cb.toggle); if (imgExpand.on && root.className !== 'inline') { return imgExpand.expand(a.firstChild); } @@ -2902,13 +2902,13 @@ form = $('body > form'); form.className = klass; if (/\bfitheight\b/.test(form.className)) { - $.bind(window, 'resize', imgExpand.resize); + $.on(window, 'resize', imgExpand.resize); if (!imgExpand.style) { imgExpand.style = $.addStyle(''); } return imgExpand.resize(); } else if (imgExpand.style) { - return $.unbind(window, 'resize', imgExpand.resize); + return $.off(window, 'resize', imgExpand.resize); } } }, @@ -2936,7 +2936,7 @@ _ref = filesize.textContent.match(/(\d+)x/), _ = _ref[0], max = _ref[1]; img.style.maxWidth = "-moz-calc(" + max + "px)"; } - $.bind(img, 'error', imgExpand.error); + $.on(img, 'error', imgExpand.error); thumb.hidden = true; return $.add(a, img); }, @@ -2977,9 +2977,9 @@ } select = $('select', controls); imgExpand.cb.typeChange.call(select); - $.bind(select, 'change', $.cb.value); - $.bind(select, 'change', imgExpand.cb.typeChange); - $.bind($('input', controls), 'click', imgExpand.cb.all); + $.on(select, 'change', $.cb.value); + $.on(select, 'change', imgExpand.cb.typeChange); + $.on($('input', controls), 'click', imgExpand.cb.all); form = $('body > form'); return $.prepend(form, controls); }, @@ -3003,13 +3003,13 @@
' }); $.add(d.body, dialog); - return $.bind(window, 'click', firstRun.close); + return $.on(window, 'click', firstRun.close); }, close: function() { $.set('firstrun', true); $.rm($('style.firstrun', d.head)); $.rm($('#overlay')); - return $.unbind(window, 'click', firstRun.close); + return $.off(window, 'click', firstRun.close); } }; Main = { @@ -3019,11 +3019,11 @@ if (d.body) { QR.sys(); } else { - $.bind(d, 'DOMContentLoaded', QR.sys); + $.on(d, 'DOMContentLoaded', QR.sys); } return; } - $.bind(window, 'message', Main.message); + $.on(window, 'message', Main.message); pathname = location.pathname.substring(1).split('/'); g.BOARD = pathname[0], temp = pathname[1]; if (temp === 'res') { @@ -3098,12 +3098,12 @@ if (d.body) { return Main.onLoad(); } else { - return $.bind(d, 'DOMContentLoaded', Main.onLoad); + return $.on(d, 'DOMContentLoaded', Main.onLoad); } }, onLoad: function() { var nodes; - $.unbind(d, 'DOMContentLoaded', Main.onLoad); + $.off(d, 'DOMContentLoaded', Main.onLoad); if (conf['404 Redirect'] && d.title === '4chan - 404' && /^\d+$/.test(g.THREAD_ID)) { redirect(); return; @@ -3170,7 +3170,7 @@ return alert(err); } }); - $.bind($('form[name=delform]'), 'DOMNodeInserted', Main.node); + $.on($('form[name=delform]'), 'DOMNodeInserted', Main.node); options.init(); if (!$.get('firstrun')) { return firstRun.init(); diff --git a/script.coffee b/script.coffee index 3a937dda1..5e2562277 100644 --- a/script.coffee +++ b/script.coffee @@ -279,9 +279,9 @@ $.extend $, el = d.createElement tag $.extend el, properties if properties el - bind: (el, eventType, handler) -> + on: (el, eventType, handler) -> el.addEventListener eventType, handler, false - unbind: (el, eventType, handler) -> + off: (el, eventType, handler) -> el.removeEventListener eventType, handler, false isDST: -> # XXX this should check for DST in NY @@ -437,7 +437,7 @@ strikethroughQuotes = expandComment = init: -> for a in $$ '.abbr a' - $.bind a, 'click', expandComment.expand + $.on a, 'click', expandComment.expand expand: (e) -> e.preventDefault() [_, threadID, replyID] = @href.match /(\d+)#(\d+)/ @@ -468,11 +468,11 @@ expandComment = if quote.hash[1..] is threadID quote.innerHTML += ' (OP)' if conf['Quote Preview'] - $.bind quote, 'mouseover', quotePreview.mouseover - $.bind quote, 'mousemove', ui.hover - $.bind quote, 'mouseout', quotePreview.mouseout + $.on quote, 'mouseover', quotePreview.mouseover + $.on quote, 'mousemove', ui.hover + $.on quote, 'mouseout', quotePreview.mouseout if conf['Quote Inline'] - $.bind quote, 'click', quoteInline.toggle + $.on quote, 'click', quoteInline.toggle $.replace a.parentNode.parentNode, bq expandThread = @@ -481,7 +481,7 @@ expandThread = a = $.el 'a', textContent: "+ #{span.textContent}" className: 'omittedposts' - $.bind a, 'click', expandThread.cb.toggle + $.on a, 'click', expandThread.cb.toggle $.replace span, a cb: @@ -522,7 +522,7 @@ expandThread = parse: (req, pathname, thread, a) -> if req.status isnt 200 a.textContent = "#{req.status} #{req.statusText}" - $.unbind a, 'click', expandThread.cb.toggle + $.off a, 'click', expandThread.cb.toggle return a.textContent = a.textContent.replace 'X Loading...', '-' @@ -556,7 +556,7 @@ replyHiding = dd.className = 'replyhider' a = $.el 'a', textContent: '[ - ]' - $.bind a, 'click', replyHiding.cb.hide + $.on a, 'click', replyHiding.cb.hide $.replace dd.firstChild, a reply = dd.nextSibling @@ -595,7 +595,7 @@ replyHiding = trip = $('.postertrip', reply)?.textContent or '' a = $.el 'a', textContent: "[ + ] #{name} #{trip}" - $.bind a, 'click', replyHiding.cb.show + $.on a, 'click', replyHiding.cb.show div = $.el 'div', className: 'stub' @@ -616,7 +616,7 @@ keybinds = init: -> for node in $$ '[accesskey]' node.removeAttribute 'accesskey' - $.bind d, 'keydown', keybinds.keydown + $.on d, 'keydown', keybinds.keydown keydown: (e) -> updater.focus = true @@ -791,8 +791,8 @@ nav = next = $.el 'a', textContent: 'â–¼' - $.bind prev, 'click', nav.prev - $.bind next, 'click', nav.next + $.on prev, 'click', nav.prev + $.on next, 'click', nav.next $.add span, prev, $.tn(' '), next $.add d.body, span @@ -856,12 +856,12 @@ options = home = $ '#navtopr a' a = $.el 'a', textContent: '4chan X' - $.bind a, 'click', options.dialog + $.on a, 'click', options.dialog $.replace home, a home = $ '#navbotr a' a = $.el 'a', textContent: '4chan X' - $.bind a, 'click', options.dialog + $.on a, 'click', options.dialog $.replace home, a dialog: -> @@ -953,7 +953,7 @@ options = description = arr[1] li = $.el 'li', innerHTML: ": #{description}" - $.bind $('input', li), 'click', $.cb.checked + $.on $('input', li), 'click', $.cb.checked $.add ul, li $.add $('#main', dialog), ul @@ -961,29 +961,29 @@ options = hiddenNum = Object.keys(g.hiddenReplies).length + Object.keys(hiddenThreads).length li = $.el 'li', innerHTML: " : Forget all hidden posts. Useful if you accidentally hide a post and have `Show Stubs` disabled." - $.bind $('button', li), 'click', options.clearHidden + $.on $('button', li), 'click', options.clearHidden $.add $('ul:nth-child(2)', dialog), li #filter & sauce for ta in $$ 'textarea', dialog ta.textContent = conf[ta.name] - $.bind ta, 'change', $.cb.value + $.on ta, 'change', $.cb.value #rice (back = $ '[name=backlink]', dialog).value = conf['backlink'] (time = $ '[name=time]', dialog).value = conf['time'] - $.bind back, 'keyup', options.backlink - $.bind time, 'keyup', options.time + $.on back, 'keyup', options.backlink + $.on time, 'keyup', options.time #keybinds for input in $$ '#keybinds input', dialog input.type = 'text' input.value = conf[input.name] - $.bind input, 'keydown', options.keybind + $.on input, 'keydown', options.keybind overlay = $.el 'div', id: 'overlay' - $.bind overlay, 'click', -> $.rm overlay - $.bind dialog, 'click', (e) -> e.stopPropagation() + $.on overlay, 'click', -> $.rm overlay + $.on dialog, 'click', (e) -> e.stopPropagation() $.add overlay, dialog $.add d.body, overlay @@ -1024,14 +1024,14 @@ QR = return unless $('form[name=post]') and $('#recaptcha_response_field') g.callbacks.push (root) -> quote = $ '.quotejs + a', root - $.bind quote, 'click', QR.quote + $.on quote, 'click', QR.quote $.add d.body, $.el 'iframe', name: 'iframe' hidden: true # nuke id so qr's field focuses on recaptcha reload, instead of normal form's $('#recaptcha_response_field').id = '' holder = $ '#recaptcha_challenge_field_holder' - $.bind holder, 'DOMNodeInserted', QR.captchaNode + $.on holder, 'DOMNodeInserted', QR.captchaNode QR.captchaNode target: holder.firstChild QR.accept = $('.rules').textContent.match(/: (.+) /)[1].replace /\w+/g, (type) -> switch type @@ -1049,12 +1049,12 @@ QR = if conf['Auto Hide QR'] $('#autohide', QR.qr).checked = true if conf['Cooldown'] - $.bind window, 'storage', (e) -> QR.cooldown() if e.key is "#{NAMESPACE}cooldown/#{g.BOARD}" + $.on window, 'storage', (e) -> QR.cooldown() if e.key is "#{NAMESPACE}cooldown/#{g.BOARD}" attach: (file) -> files = $ '#files', QR.qr box = $.el 'li', innerHTML: "X" - $.bind $('.x', box), 'click', QR.rmThumb + $.on $('.x', box), 'click', QR.rmThumb $.add box, file $.add files, box QR.stats() @@ -1134,7 +1134,7 @@ QR = type: 'file' name: 'upfile' accept: QR.accept - $.bind input, 'change', QR.change + $.on input, 'change', QR.change if old $.replace old, file else @@ -1179,9 +1179,9 @@ QR = QR.reset() QR.cooldown() if conf['Cooldown'] QR.foo() - $.bind $('.close', qr), 'click', QR.close - $.bind $('form', qr), 'submit', QR.submit - $.bind $('#recaptcha_response_field', qr), 'keydown', QR.keydown + $.on $('.close', qr), 'click', QR.close + $.on $('form', qr), 'submit', QR.submit + $.on $('#recaptcha_response_field', qr), 'keydown', QR.keydown QR.captchaImg() QR.stats() $.add d.body, qr @@ -1295,9 +1295,9 @@ QR = if $('img.favicon', op).src is Favicon.empty watcher.watch op, id sys: -> - $.unbind d, 'DOMContentLoaded', QR.sys + $.off d, 'DOMContentLoaded', QR.sys if recaptcha = $ '#recaptcha_response_field' #post reporting - $.bind recaptcha, 'keydown', QR.keydown + $.on recaptcha, 'keydown', QR.keydown return ### http://code.google.com/p/chromium/issues/detail?id=20773 @@ -1357,7 +1357,7 @@ threadHiding = op = thread.firstChild a = $.el 'a', textContent: '[ - ]' - $.bind a, 'click', threadHiding.cb.hide + $.on a, 'click', threadHiding.cb.hide $.prepend op, a if op.id of hiddenThreads @@ -1399,7 +1399,7 @@ threadHiding = a = $.el 'a', textContent: "[ + ] #{name}#{trip} (#{text})" - $.bind a, 'click', threadHiding.cb.show + $.on a, 'click', threadHiding.cb.show div = $.el 'div', className: 'block' @@ -1431,8 +1431,8 @@ updater = if conf['Scroll BG'] updater.focus = true else - $.bind window, 'focus', (-> updater.focus = true) - $.bind window, 'blur', (-> updater.focus = false) + $.on window, 'focus', (-> updater.focus = true) + $.on window, 'blur', (-> updater.focus = false) html = "
-#{conf['Interval']}
" {checkbox} = config.updater for name of checkbox @@ -1454,19 +1454,19 @@ updater = for input in $$ 'input', dialog if input.type is 'checkbox' - $.bind input, 'click', $.cb.checked - $.bind input, 'click', -> conf[@name] = @checked + $.on input, 'click', $.cb.checked + $.on input, 'click', -> conf[@name] = @checked if input.name is 'Verbose' - $.bind input, 'click', updater.cb.verbose + $.on input, 'click', updater.cb.verbose updater.cb.verbose.call input else if input.name is 'Auto Update This' - $.bind input, 'click', updater.cb.autoUpdate + $.on input, 'click', updater.cb.autoUpdate updater.cb.autoUpdate.call input else if input.name is 'Interval' - $.bind input, 'change', -> conf['Interval'] = @value = parseInt(@value) or conf['Interval'] - $.bind input, 'change', $.cb.value + $.on input, 'change', -> conf['Interval'] = @value = parseInt(@value) or conf['Interval'] + $.on input, 'change', $.cb.value else if input.type is 'button' - $.bind input, 'click', updater.update + $.on input, 'click', updater.update $.add d.body, dialog @@ -1563,13 +1563,13 @@ watcher = for input in inputs favicon = $.el 'img', className: 'favicon' - $.bind favicon, 'click', watcher.cb.toggle + $.on favicon, 'click', watcher.cb.toggle $.before input, favicon #populate watcher, display watch buttons watcher.refresh() - $.bind window, 'storage', (e) -> watcher.refresh() if e.key is "#{NAMESPACE}watched" + $.on window, 'storage', (e) -> watcher.refresh() if e.key is "#{NAMESPACE}watched" refresh: -> watched = $.get 'watched', {} @@ -1580,7 +1580,7 @@ watcher = div = $.el 'div' x = $.el 'a', textContent: 'X' - $.bind x, 'click', watcher.cb.x + $.on x, 'click', watcher.cb.x link = $.el 'a', props $.add div, x, $.tn(' '), link @@ -1775,11 +1775,11 @@ quoteBacklink = continue if el.className is 'op' and !conf['OP Backlinks'] link = a.cloneNode true if conf['Quote Preview'] - $.bind link, 'mouseover', quotePreview.mouseover - $.bind link, 'mousemove', ui.hover - $.bind link, 'mouseout', quotePreview.mouseout + $.on link, 'mouseover', quotePreview.mouseover + $.on link, 'mousemove', ui.hover + $.on link, 'mouseout', quotePreview.mouseout if conf['Quote Inline'] - $.bind link, 'click', quoteInline.toggle + $.on link, 'click', quoteInline.toggle unless (container = $ '.container', el) and container.parentNode is el container = $.el 'span', className: 'container' root = $('.reportbutton', el) or $('span[id]', el) @@ -1792,7 +1792,7 @@ quoteInline = for quote in $$ '.quotelink, .backlink', root continue unless quote.hash quote.removeAttribute 'onclick' - $.bind quote, 'click', quoteInline.toggle + $.on quote, 'click', quoteInline.toggle toggle: (e) -> return if e.shiftKey or e.altKey or e.ctrlKey or e.button isnt 0 e.preventDefault() @@ -1871,9 +1871,9 @@ quotePreview = g.callbacks.push (root) -> for quote in $$ '.quotelink, .backlink', root continue unless quote.hash - $.bind quote, 'mouseover', quotePreview.mouseover - $.bind quote, 'mousemove', ui.hover - $.bind quote, 'mouseout', quotePreview.mouseout + $.on quote, 'mouseover', quotePreview.mouseover + $.on quote, 'mousemove', ui.hover + $.on quote, 'mouseout', quotePreview.mouseout mouseover: (e) -> qp = ui.el = $.el 'div', id: 'qp' @@ -1936,7 +1936,7 @@ reportButton = innerHTML: '[ ! ]' $.after span, a $.after span, $.tn(' ') - $.bind a, 'click', reportButton.report + $.on a, 'click', reportButton.report report: -> url = "http://sys.4chan.org/#{g.BOARD}/imgboard.php?mode=report&no=#{$.x('preceding-sibling::input', @).name}" id = "#{NAMESPACE}popup" @@ -1966,7 +1966,7 @@ unread = init: -> unread.replies = [] d.title = '(0) ' + d.title - $.bind window, 'scroll', unread.scroll + $.on window, 'scroll', unread.scroll g.callbacks.push unread.node node: (root) -> @@ -2045,9 +2045,9 @@ imgHover = init: -> g.callbacks.push (root) -> return unless thumb = $ 'img[md5]', root - $.bind thumb, 'mouseover', imgHover.mouseover - $.bind thumb, 'mousemove', ui.hover - $.bind thumb, 'mouseout', ui.hoverend + $.on thumb, 'mouseover', imgHover.mouseover + $.on thumb, 'mousemove', ui.hover + $.on thumb, 'mouseout', ui.hoverend mouseover: -> ui.el = $.el 'img' id: 'iHover' @@ -2064,7 +2064,7 @@ imgPreloading = label = $.el 'label', innerHTML: 'Preload Images' - $.bind $('input', label), 'click', imgPreloading.click + $.on $('input', label), 'click', imgPreloading.click $.add controls, label g.callbacks.push imgPreloading.node @@ -2095,7 +2095,7 @@ imgExpand = node: (root) -> return unless thumb = $ 'img[md5]', root a = thumb.parentNode - $.bind a, 'click', imgExpand.cb.toggle + $.on a, 'click', imgExpand.cb.toggle if imgExpand.on and root.className isnt 'inline' then imgExpand.expand a.firstChild cb: toggle: (e) -> @@ -2123,12 +2123,12 @@ imgExpand = form = $('body > form') form.className = klass if /\bfitheight\b/.test form.className - $.bind window, 'resize', imgExpand.resize + $.on window, 'resize', imgExpand.resize unless imgExpand.style imgExpand.style = $.addStyle '' imgExpand.resize() else if imgExpand.style - $.unbind window, 'resize', imgExpand.resize + $.off window, 'resize', imgExpand.resize toggle: (a) -> thumb = a.firstChild @@ -2149,7 +2149,7 @@ imgExpand = filesize = $ '.filesize', a.parentNode [_, max] = filesize.textContent.match /(\d+)x/ img.style.maxWidth = "-moz-calc(#{max}px)" - $.bind img, 'error', imgExpand.error + $.on img, 'error', imgExpand.error thumb.hidden = true $.add a, img @@ -2178,9 +2178,9 @@ imgExpand = break select = $ 'select', controls imgExpand.cb.typeChange.call select - $.bind select, 'change', $.cb.value - $.bind select, 'change', imgExpand.cb.typeChange - $.bind $('input', controls), 'click', imgExpand.cb.all + $.on select, 'change', $.cb.value + $.on select, 'change', imgExpand.cb.typeChange + $.on $('input', controls), 'click', imgExpand.cb.all form = $ 'body > form' $.prepend form, controls @@ -2258,13 +2258,13 @@ firstRun =
' $.add d.body, dialog - $.bind window, 'click', firstRun.close + $.on window, 'click', firstRun.close close: -> $.set 'firstrun', true $.rm $ 'style.firstrun', d.head $.rm $ '#overlay' - $.unbind window, 'click', firstRun.close + $.off window, 'click', firstRun.close Main = init: -> @@ -2272,10 +2272,10 @@ Main = if d.body QR.sys() else - $.bind d, 'DOMContentLoaded', QR.sys + $.on d, 'DOMContentLoaded', QR.sys return - $.bind window, 'message', Main.message + $.on window, 'message', Main.message pathname = location.pathname.substring(1).split('/') [g.BOARD, temp] = pathname @@ -2353,10 +2353,10 @@ Main = if d.body Main.onLoad() else - $.bind d, 'DOMContentLoaded', Main.onLoad + $.on d, 'DOMContentLoaded', Main.onLoad onLoad: -> - $.unbind d, 'DOMContentLoaded', Main.onLoad + $.off d, 'DOMContentLoaded', Main.onLoad if conf['404 Redirect'] and d.title is '4chan - 404' and /^\d+$/.test g.THREAD_ID redirect() return @@ -2422,7 +2422,7 @@ Main = nodes.forEach callback catch err alert err - $.bind $('form[name=delform]'), 'DOMNodeInserted', Main.node + $.on $('form[name=delform]'), 'DOMNodeInserted', Main.node options.init() unless $.get 'firstrun' From 59754aa16131326e6f200425693050958506270f Mon Sep 17 00:00:00 2001 From: James Campos Date: Fri, 4 Nov 2011 22:01:54 -0700 Subject: [PATCH 036/169] add link in license --- 4chan_x.user.js | 1 + Cakefile | 1 + 2 files changed, 2 insertions(+) diff --git a/4chan_x.user.js b/4chan_x.user.js index d9b4f93dd..8ee2aa3e2 100644 --- a/4chan_x.user.js +++ b/4chan_x.user.js @@ -13,6 +13,7 @@ /* LICENSE * * Copyright (c) 2009-2011 James Campos + * http://aeosynth.github.com/4chan-x/ * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation diff --git a/Cakefile b/Cakefile index 81ea76979..e6c085f77 100644 --- a/Cakefile +++ b/Cakefile @@ -18,6 +18,7 @@ HEADER = """ /* LICENSE * * Copyright (c) 2009-2011 James Campos + * http://aeosynth.github.com/4chan-x/ * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation From ee981c69fd13d1f3c12ec6f6b176cdaa1b70a3d3 Mon Sep 17 00:00:00 2001 From: Nicolas Stepien Date: Sat, 5 Nov 2011 15:18:23 +0100 Subject: [PATCH 037/169] Fix DST for two days of the year. --- 4chan_x.user.js | 4 ++-- changelog | 1 + script.coffee | 4 ++-- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/4chan_x.user.js b/4chan_x.user.js index 8ee2aa3e2..9e82f892e 100644 --- a/4chan_x.user.js +++ b/4chan_x.user.js @@ -432,7 +432,7 @@ return false; } if (sunday < 15 && date.getDay() === 0) { - if (date.getHour() < 1) { + if (date.getHours() < 1) { return false; } return true; @@ -443,7 +443,7 @@ return true; } if (sunday < 8 && date.getDay() === 0) { - if (date.getHour() < 1) { + if (date.getHours() < 1) { return true; } return false; diff --git a/changelog b/changelog index 50be5269a..88a4f9014 100644 --- a/changelog +++ b/changelog @@ -7,6 +7,7 @@ master automatically reload expanded pictures on error update archives redirections for /diy/, /pol/ and /sci/ handle bans with the thread updater + fix DST for two days of the year - aeosynth quick reply redesign diff --git a/script.coffee b/script.coffee index 5e2562277..78049db6f 100644 --- a/script.coffee +++ b/script.coffee @@ -312,7 +312,7 @@ $.extend $, #during second sunday if sunday < 15 and date.getDay() is 0 - if date.getHour() < 1 + if date.getHours() < 1 return false return true @@ -326,7 +326,7 @@ $.extend $, # during first sunday if sunday < 8 and date.getDay() is 0 - if date.getHour() < 1 + if date.getHours() < 1 return true return false From b300da1cfe83076243b74d5a3587c5d05e639718 Mon Sep 17 00:00:00 2001 From: James Campos Date: Sun, 6 Nov 2011 19:45:05 -0800 Subject: [PATCH 038/169] change --- changelog | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/changelog b/changelog index 88a4f9014..49590ee57 100644 --- a/changelog +++ b/changelog @@ -11,6 +11,17 @@ master - aeosynth quick reply redesign +2.20.3 +- mayhem + fix DST for two days of the year + +2.20.2 +- mayhem + update archive redirection +- aeosynth + hopefully fix qr error / update messages + rm support throd link + 2.20.1 - mayhem fix regression: qr not preventing errors From bc4e5a2d992aa8fbfd37e0bc6055f90dad8fcaa5 Mon Sep 17 00:00:00 2001 From: James Campos Date: Sun, 6 Nov 2011 19:51:29 -0800 Subject: [PATCH 039/169] update archives fix #379 --- 4chan_x.user.js | 2 +- script.coffee | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/4chan_x.user.js b/4chan_x.user.js index 9e82f892e..855c8d76b 100644 --- a/4chan_x.user.js +++ b/4chan_x.user.js @@ -2732,7 +2732,6 @@ break; case 'diy': case 'g': - case 'pol': case 'sci': url = "http://archive.installgentoo.net/" + g.BOARD + "/thread/" + g.THREAD_ID; break; @@ -2750,6 +2749,7 @@ case 'o': case 'p': case 'po': + case 'pol': case 'soc': case 'sp': case 'toy': diff --git a/script.coffee b/script.coffee index 78049db6f..1f7e7b52d 100644 --- a/script.coffee +++ b/script.coffee @@ -2033,9 +2033,9 @@ redirect = -> url = "http://archive.foolz.us/#{g.BOARD}/thread/#{g.THREAD_ID}" when 'lit' url = "http://archive.gentoomen.org/cgi-board.pl/#{g.BOARD}/thread/#{g.THREAD_ID}" - when 'diy', 'g', 'pol', 'sci' + when 'diy', 'g', 'sci' url = "http://archive.installgentoo.net/#{g.BOARD}/thread/#{g.THREAD_ID}" - when '3', 'adv', 'an', 'ck', 'co', 'fa', 'fit', 'int', 'k', 'mu', 'n', 'o', 'p', 'po', 'soc', 'sp', 'toy', 'trv', 'v', 'vp', 'x' + when '3', 'adv', 'an', 'ck', 'co', 'fa', 'fit', 'int', 'k', 'mu', 'n', 'o', 'p', 'po', 'pol', 'soc', 'sp', 'toy', 'trv', 'v', 'vp', 'x' url = "http://archive.no-ip.org/#{g.BOARD}/thread/#{g.THREAD_ID}" else url = "http://boards.4chan.org/#{g.BOARD}" From 892f004fd7819ae201b13f346320ff561b1a6530 Mon Sep 17 00:00:00 2001 From: James Campos Date: Sun, 6 Nov 2011 22:21:40 -0800 Subject: [PATCH 040/169] reamde --- readme.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/readme.md b/readme.md index 7b849ac02..ebb3d56b1 100644 --- a/readme.md +++ b/readme.md @@ -1,4 +1,8 @@ -# Get 4chan X [HERE](http://aeosynth.github.com/4chan-x/). +# Installing + +[stable](https://github.com/aeosynth/4chan-x/raw/stable/4chan_x.user.js) - if you don't know what you're doing, choose this + +[master](https://github.com/aeosynth/4chan-x/raw/master/4chan_x.user.js) - main development branch, turns into stable. can change frequently, so don't complain if other projects don't support this branch. # Building From 2b00be59ff4a69b30f864faf9273857aedf47ccf Mon Sep 17 00:00:00 2001 From: James Campos Date: Mon, 7 Nov 2011 00:02:44 -0800 Subject: [PATCH 041/169] add docs link --- readme.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/readme.md b/readme.md index ebb3d56b1..12f5be96a 100644 --- a/readme.md +++ b/readme.md @@ -1,3 +1,7 @@ +# Documentation + +https://aeosynth.github.com/4chan-x + # Installing [stable](https://github.com/aeosynth/4chan-x/raw/stable/4chan_x.user.js) - if you don't know what you're doing, choose this From 19da9155c907ae24a6f7fb4fc07c8f6125aa56fa Mon Sep 17 00:00:00 2001 From: James Campos Date: Mon, 7 Nov 2011 00:16:32 -0800 Subject: [PATCH 042/169] whoops --- readme.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/readme.md b/readme.md index 12f5be96a..08fdbeec0 100644 --- a/readme.md +++ b/readme.md @@ -1,13 +1,13 @@ -# Documentation - -https://aeosynth.github.com/4chan-x - # Installing [stable](https://github.com/aeosynth/4chan-x/raw/stable/4chan_x.user.js) - if you don't know what you're doing, choose this [master](https://github.com/aeosynth/4chan-x/raw/master/4chan_x.user.js) - main development branch, turns into stable. can change frequently, so don't complain if other projects don't support this branch. +# Documentation + +http://aeosynth.github.com/4chan-x + # Building [install nodejs and npm](https://github.com/joyent/node/wiki/Installation), From 21dc16ef869cffac690353756b867637a05aa872 Mon Sep 17 00:00:00 2001 From: James Campos Date: Mon, 7 Nov 2011 21:41:14 -0800 Subject: [PATCH 043/169] check for DST in NY; close #376 --- 4chan_x.user.js | 29 +++++++++++++++++------------ script.coffee | 28 ++++++++++++++++------------ 2 files changed, 33 insertions(+), 24 deletions(-) diff --git a/4chan_x.user.js b/4chan_x.user.js index 855c8d76b..f3e18e256 100644 --- a/4chan_x.user.js +++ b/4chan_x.user.js @@ -412,27 +412,32 @@ }, isDST: function() { /* - http://en.wikipedia.org/wiki/Daylight_saving_time_in_the_United_States - Since 2007, daylight saving time starts on the second Sunday of March - and ends on the first Sunday of November, with all time changes taking - place at 2:00 AM (0200) local time. + http://en.wikipedia.org/wiki/Daylight_saving_time_in_the_United_States + Since 2007, daylight saving time starts on the second Sunday of March + and ends on the first Sunday of November, with all time changes taking + place at 2:00 AM (0200) local time. + + 0200 EST (UTC -5) = 0700 UTC */ - var date, month, sunday; - date = new Date(); - month = date.getMonth(); + var D, date, day, hours, month, sunday; + D = new Date(); + date = D.getUTCDate(); + day = D.getUTCDay(); + hours = D.getUTCHours(); + month = D.getUTCMonth(); if (month < 2 || 10 < month) { return false; } if ((2 < month && month < 10)) { return true; } - sunday = date.getDate() - date.getDay(); + sunday = date - day; if (month === 2) { if (sunday < 8) { return false; } - if (sunday < 15 && date.getDay() === 0) { - if (date.getHours() < 1) { + if (sunday < 15 && day === 0) { + if (hours < 7) { return false; } return true; @@ -442,8 +447,8 @@ if (sunday < 1) { return true; } - if (sunday < 8 && date.getDay() === 0) { - if (date.getHours() < 1) { + if (sunday < 8 && day === 0) { + if (hours < 7) { return true; } return false; diff --git a/script.coffee b/script.coffee index 1f7e7b52d..8d59f0009 100644 --- a/script.coffee +++ b/script.coffee @@ -284,16 +284,20 @@ $.extend $, off: (el, eventType, handler) -> el.removeEventListener eventType, handler, false isDST: -> - # XXX this should check for DST in NY ### - http://en.wikipedia.org/wiki/Daylight_saving_time_in_the_United_States - Since 2007, daylight saving time starts on the second Sunday of March - and ends on the first Sunday of November, with all time changes taking - place at 2:00 AM (0200) local time. + http://en.wikipedia.org/wiki/Daylight_saving_time_in_the_United_States + Since 2007, daylight saving time starts on the second Sunday of March + and ends on the first Sunday of November, with all time changes taking + place at 2:00 AM (0200) local time. + + 0200 EST (UTC -5) = 0700 UTC ### - date = new Date() - month = date.getMonth() + D = new Date() + date = D.getUTCDate() + day = D.getUTCDay() + hours = D.getUTCHours() + month = D.getUTCMonth() #this is the easy part if month < 2 or 10 < month @@ -303,7 +307,7 @@ $.extend $, # (sunday's date) = (today's date) - (number of days past sunday) # date is not zero-indexed - sunday = date.getDate() - date.getDay() + sunday = date - day if month is 2 #before second sunday @@ -311,8 +315,8 @@ $.extend $, return false #during second sunday - if sunday < 15 and date.getDay() is 0 - if date.getHours() < 1 + if sunday < 15 and day is 0 + if hours < 7 return false return true @@ -325,8 +329,8 @@ $.extend $, return true # during first sunday - if sunday < 8 and date.getDay() is 0 - if date.getHours() < 1 + if sunday < 8 and day is 0 + if hours < 7 return true return false From 074a769e76c2625f388e31a0f70136203d55f09f Mon Sep 17 00:00:00 2001 From: James Campos Date: Mon, 7 Nov 2011 21:54:45 -0800 Subject: [PATCH 044/169] more correct --- 4chan_x.user.js | 12 ++++++++++-- script.coffee | 12 ++++++++++-- 2 files changed, 20 insertions(+), 4 deletions(-) diff --git a/4chan_x.user.js b/4chan_x.user.js index f3e18e256..ab0d06943 100644 --- a/4chan_x.user.js +++ b/4chan_x.user.js @@ -417,7 +417,15 @@ and ends on the first Sunday of November, with all time changes taking place at 2:00 AM (0200) local time. - 0200 EST (UTC -5) = 0700 UTC + http://en.wikipedia.org/wiki/Eastern_Time_Zone + Its UTC time offset is −5 hrs (UTC−05) during standard time and −4 + hrs (UTC−04) during daylight saving time. + + Standard time: + 0200 EST (UTC-05) = 0700 UTC + + Dalyight saving time: + 0200 EST (UTC-04) = 0600 UTC */ var D, date, day, hours, month, sunday; D = new Date(); @@ -448,7 +456,7 @@ return true; } if (sunday < 8 && day === 0) { - if (hours < 7) { + if (hours < 6) { return true; } return false; diff --git a/script.coffee b/script.coffee index 8d59f0009..a8fa44c98 100644 --- a/script.coffee +++ b/script.coffee @@ -290,7 +290,15 @@ $.extend $, and ends on the first Sunday of November, with all time changes taking place at 2:00 AM (0200) local time. - 0200 EST (UTC -5) = 0700 UTC + http://en.wikipedia.org/wiki/Eastern_Time_Zone + Its UTC time offset is −5 hrs (UTC−05) during standard time and −4 + hrs (UTC−04) during daylight saving time. + + Standard time: + 0200 EST (UTC-05) = 0700 UTC + + Dalyight saving time: + 0200 EST (UTC-04) = 0600 UTC ### D = new Date() @@ -330,7 +338,7 @@ $.extend $, # during first sunday if sunday < 8 and day is 0 - if hours < 7 + if hours < 6 return true return false From 60bddd29fd2c3fce82a641eeb336792bd9b6a7ca Mon Sep 17 00:00:00 2001 From: James Campos Date: Mon, 7 Nov 2011 22:02:11 -0800 Subject: [PATCH 045/169] comment --- 4chan_x.user.js | 14 +++++--------- script.coffee | 14 +++++--------- 2 files changed, 10 insertions(+), 18 deletions(-) diff --git a/4chan_x.user.js b/4chan_x.user.js index ab0d06943..030f9af2c 100644 --- a/4chan_x.user.js +++ b/4chan_x.user.js @@ -412,20 +412,16 @@ }, isDST: function() { /* - http://en.wikipedia.org/wiki/Daylight_saving_time_in_the_United_States - Since 2007, daylight saving time starts on the second Sunday of March - and ends on the first Sunday of November, with all time changes taking - place at 2:00 AM (0200) local time. - http://en.wikipedia.org/wiki/Eastern_Time_Zone Its UTC time offset is −5 hrs (UTC−05) during standard time and −4 hrs (UTC−04) during daylight saving time. - Standard time: - 0200 EST (UTC-05) = 0700 UTC + Since 2007, the local time changes at 02:00 EST to 03:00 EDT on the second + Sunday in March and returns at 02:00 EDT to 01:00 EST on the first Sunday + in November, in the U.S. as well as in Canada. - Dalyight saving time: - 0200 EST (UTC-04) = 0600 UTC + 0200 EST (UTC-05) = 0700 UTC + 0200 EDT (UTC-04) = 0600 UTC */ var D, date, day, hours, month, sunday; D = new Date(); diff --git a/script.coffee b/script.coffee index a8fa44c98..accbde740 100644 --- a/script.coffee +++ b/script.coffee @@ -285,20 +285,16 @@ $.extend $, el.removeEventListener eventType, handler, false isDST: -> ### - http://en.wikipedia.org/wiki/Daylight_saving_time_in_the_United_States - Since 2007, daylight saving time starts on the second Sunday of March - and ends on the first Sunday of November, with all time changes taking - place at 2:00 AM (0200) local time. - http://en.wikipedia.org/wiki/Eastern_Time_Zone Its UTC time offset is −5 hrs (UTC−05) during standard time and −4 hrs (UTC−04) during daylight saving time. - Standard time: - 0200 EST (UTC-05) = 0700 UTC + Since 2007, the local time changes at 02:00 EST to 03:00 EDT on the second + Sunday in March and returns at 02:00 EDT to 01:00 EST on the first Sunday + in November, in the U.S. as well as in Canada. - Dalyight saving time: - 0200 EST (UTC-04) = 0600 UTC + 0200 EST (UTC-05) = 0700 UTC + 0200 EDT (UTC-04) = 0600 UTC ### D = new Date() From 80bf28e6732abae13f857bd4a8f5c18a1abd338d Mon Sep 17 00:00:00 2001 From: James Campos Date: Fri, 11 Nov 2011 09:36:27 -0800 Subject: [PATCH 046/169] rm archive.installgentoo.net --- 4chan_x.user.js | 6 +----- script.coffee | 4 +--- 2 files changed, 2 insertions(+), 8 deletions(-) diff --git a/4chan_x.user.js b/4chan_x.user.js index 030f9af2c..47e137777 100644 --- a/4chan_x.user.js +++ b/4chan_x.user.js @@ -2739,16 +2739,12 @@ case 'lit': url = "http://archive.gentoomen.org/cgi-board.pl/" + g.BOARD + "/thread/" + g.THREAD_ID; break; - case 'diy': - case 'g': - case 'sci': - url = "http://archive.installgentoo.net/" + g.BOARD + "/thread/" + g.THREAD_ID; - break; case '3': case 'adv': case 'an': case 'ck': case 'co': + case 'diy': case 'fa': case 'fit': case 'int': diff --git a/script.coffee b/script.coffee index accbde740..adc012ae8 100644 --- a/script.coffee +++ b/script.coffee @@ -2041,9 +2041,7 @@ redirect = -> url = "http://archive.foolz.us/#{g.BOARD}/thread/#{g.THREAD_ID}" when 'lit' url = "http://archive.gentoomen.org/cgi-board.pl/#{g.BOARD}/thread/#{g.THREAD_ID}" - when 'diy', 'g', 'sci' - url = "http://archive.installgentoo.net/#{g.BOARD}/thread/#{g.THREAD_ID}" - when '3', 'adv', 'an', 'ck', 'co', 'fa', 'fit', 'int', 'k', 'mu', 'n', 'o', 'p', 'po', 'pol', 'soc', 'sp', 'toy', 'trv', 'v', 'vp', 'x' + when '3', 'adv', 'an', 'ck', 'co', 'diy', 'fa', 'fit', 'int', 'k', 'mu', 'n', 'o', 'p', 'po', 'pol', 'soc', 'sp', 'toy', 'trv', 'v', 'vp', 'x' url = "http://archive.no-ip.org/#{g.BOARD}/thread/#{g.THREAD_ID}" else url = "http://boards.4chan.org/#{g.BOARD}" From fdc008695863f9fc9445f0a09ec122ec743c1058 Mon Sep 17 00:00:00 2001 From: James Campos Date: Sun, 13 Nov 2011 09:22:24 -0800 Subject: [PATCH 047/169] use thumbs for sauce, close #327 --- 4chan_x.user.js | 8 ++++---- script.coffee | 5 ++--- 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/4chan_x.user.js b/4chan_x.user.js index 47e137777..5ab7f4b2f 100644 --- a/4chan_x.user.js +++ b/4chan_x.user.js @@ -126,7 +126,7 @@ file: '', md5: '' }, - flavors: ['http://iqdb.org/?url=', 'http://google.com/searchbyimage?image_url=', '#http://regex.info/exif.cgi?url=', '#http://tineye.com/search?url=', '#http://saucenao.com/search.php?db=999&url=', '#http://imgur.com/upload?url='].join('\n'), + flavors: ['http://iqdb.org/?url=', 'http://google.com/searchbyimage?image_url=', '#http://tineye.com/search?url=', '#http://saucenao.com/search.php?db=999&url=', '#http://imgur.com/upload?url='].join('\n'), time: '%m/%d/%y(%a)%H:%M', backlink: '>>%id', hotkeys: { @@ -2170,11 +2170,11 @@ return prefix.match(/(\w+)\./)[1]; }); return g.callbacks.push(function(root) { - var i, link, prefix, span, suffix, _len, _ref, _results; - if (root.className === 'inline' || !(span = $('.filesize', root))) { + var i, link, prefix, suffix, thumb, _len, _ref, _results; + if (root.className === 'inline' || !(thumb = $('img[md5]', root))) { return; } - suffix = $('a', span).href; + suffix = thumb.src; _ref = sauce.prefixes; _results = []; for (i = 0, _len = _ref.length; i < _len; i++) { diff --git a/script.coffee b/script.coffee index adc012ae8..62f1e8fd1 100644 --- a/script.coffee +++ b/script.coffee @@ -55,7 +55,6 @@ config = flavors: [ 'http://iqdb.org/?url=' 'http://google.com/searchbyimage?image_url=' - '#http://regex.info/exif.cgi?url=' '#http://tineye.com/search?url=' '#http://saucenao.com/search.php?db=999&url=' '#http://imgur.com/upload?url=' @@ -1651,8 +1650,8 @@ sauce = sauce.prefixes = conf['flavors'].match /^[^#].+$/gm sauce.names = sauce.prefixes.map (prefix) -> prefix.match(/(\w+)\./)[1] g.callbacks.push (root) -> - return if root.className is 'inline' or not span = $ '.filesize', root - suffix = $('a', span).href + return if root.className is 'inline' or not thumb = $ 'img[md5]', root + suffix = thumb.src for prefix, i in sauce.prefixes link = $.el 'a', textContent: sauce.names[i] From 9da579f2165f8936f2dfda9d011bf699dedf08a0 Mon Sep 17 00:00:00 2001 From: James Campos Date: Sun, 13 Nov 2011 10:43:18 -0800 Subject: [PATCH 048/169] coffee-script 1.1.3 --- 4chan_x.user.js | 585 ++++++++++++++++++------------------------------ 1 file changed, 214 insertions(+), 371 deletions(-) diff --git a/4chan_x.user.js b/4chan_x.user.js index 5ab7f4b2f..8c707cc43 100644 --- a/4chan_x.user.js +++ b/4chan_x.user.js @@ -64,6 +64,7 @@ (function() { var $, $$, DAY, Favicon, HOUR, MINUTE, Main, NAMESPACE, QR, SECOND, Time, anonymize, conf, config, d, expandComment, expandThread, filter, firstRun, flatten, g, getTitle, imgExpand, imgGif, imgHover, imgPreloading, key, keybinds, log, nav, options, quoteBacklink, quoteInline, quoteOP, quotePreview, redirect, replyHiding, reportButton, revealSpoilers, sauce, strikethroughQuotes, threadHiding, threadStats, threading, titlePost, ui, unread, updater, val, watcher; var __slice = Array.prototype.slice; + config = { main: { Enhancing: { @@ -162,11 +163,13 @@ 'Interval': 30 } }; + if (typeof console !== "undefined" && console !== null) { log = function(arg) { return console.log(arg); }; } + if (!Object.keys) { Object.keys = function(o) { var key, _results; @@ -177,7 +180,9 @@ return _results; }; } + conf = {}; + (flatten = function(parent, obj) { var key, val, _results; if (obj.length) { @@ -197,15 +202,23 @@ return conf[parent] = obj; } })(null, config); + NAMESPACE = 'AEOS.4chan_x.'; + SECOND = 1000; + MINUTE = 60 * SECOND; + HOUR = 60 * MINUTE; + DAY = 24 * HOUR; + d = document; + g = { callbacks: [] }; + ui = { dialog: function(id, position, html) { var el, saved, _ref; @@ -273,17 +286,18 @@ return ui.el.parentNode.removeChild(ui.el); } }; + /* loosely follows the jquery api: http://api.jquery.com/ not chainable */ + $ = function(selector, root) { - if (root == null) { - root = d.body; - } + if (root == null) root = d.body; return root.querySelector(selector); }; + $.extend = function(object, properties) { var key, val; for (key in properties) { @@ -292,6 +306,7 @@ } return object; }; + $.extend($, { id: function(id) { return d.getElementById(id); @@ -306,9 +321,7 @@ }, ajax: function(url, cb, type) { var r; - if (type == null) { - type = 'get'; - } + if (type == null) type = 'get'; r = new XMLHttpRequest(); r.onload = cb; r.open(type, url, true); @@ -357,9 +370,7 @@ return style; }, x: function(path, root) { - if (root == null) { - root = d.body; - } + if (root == null) root = d.body; return d.evaluate(path, root, null, XPathResult.ANY_UNORDERED_NODE_TYPE, null).singleNodeValue; }, tn: function(s) { @@ -399,9 +410,7 @@ el: function(tag, properties) { var el; el = d.createElement(tag); - if (properties) { - $.extend(el, properties); - } + if (properties) $.extend(el, properties); return el; }, on: function(el, eventType, handler) { @@ -422,45 +431,35 @@ 0200 EST (UTC-05) = 0700 UTC 0200 EDT (UTC-04) = 0600 UTC - */ + */ var D, date, day, hours, month, sunday; D = new Date(); date = D.getUTCDate(); day = D.getUTCDay(); hours = D.getUTCHours(); month = D.getUTCMonth(); - if (month < 2 || 10 < month) { - return false; - } - if ((2 < month && month < 10)) { - return true; - } + if (month < 2 || 10 < month) return false; + if ((2 < month && month < 10)) return true; sunday = date - day; if (month === 2) { - if (sunday < 8) { - return false; - } + if (sunday < 8) return false; if (sunday < 15 && day === 0) { - if (hours < 7) { - return false; - } + if (hours < 7) return false; return true; } return true; } - if (sunday < 1) { - return true; - } + if (sunday < 1) return true; if (sunday < 8 && day === 0) { - if (hours < 6) { - return true; - } + if (hours < 6) return true; return false; } return false; } }); + $.cache.requests = {}; + if (typeof GM_deleteValue !== "undefined" && GM_deleteValue !== null) { $.extend($, { "delete": function(name) { @@ -509,25 +508,24 @@ } }); } + for (key in conf) { val = conf[key]; conf[key] = $.get(key, val); } + $$ = function(selector, root) { - if (root == null) { - root = d.body; - } + if (root == null) root = d.body; return Array.prototype.slice.call(root.querySelectorAll(selector)); }; + filter = { regexps: {}, callbacks: [], init: function() { var f, filter, key, m, _i, _len; for (key in config.filter) { - if (!(m = conf[key].match(/^\/.+\/\w*$/gm))) { - continue; - } + if (!(m = conf[key].match(/^\/.+\/\w*$/gm))) continue; this.regexps[key] = []; for (_i = 0, _len = m.length; _i < _len; _i++) { filter = m[_i]; @@ -571,9 +569,7 @@ }, mail: function(root) { var mail; - if (mail = $('.linkmail', root)) { - return filter.test('mail', mail.href); - } + if (mail = $('.linkmail', root)) return filter.test('mail', mail.href); }, sub: function(root) { var sub; @@ -587,9 +583,7 @@ }, file: function(root) { var file; - if (file = $('.filesize span', root)) { - return filter.test('file', file.title); - } + if (file = $('.filesize span', root)) return filter.test('file', file.title); }, md5: function(root) { var img; @@ -598,23 +592,31 @@ } } }; + strikethroughQuotes = { init: function() { return g.callbacks.push(function(root) { var el, quote, _i, _len, _ref, _results; - if (root.className === 'inline') { - return; - } + if (root.className === 'inline') return; _ref = $$('.quotelink', root); _results = []; for (_i = 0, _len = _ref.length; _i < _len; _i++) { quote = _ref[_i]; - _results.push((el = $.id(quote.hash.slice(1))) ? el.parentNode.parentNode.parentNode.hidden ? $.addClass(quote, 'filtered') : void 0 : void 0); + if (el = $.id(quote.hash.slice(1))) { + if (el.parentNode.parentNode.parentNode.hidden) { + _results.push($.addClass(quote, 'filtered')); + } else { + _results.push(void 0); + } + } else { + _results.push(void 0); + } } return _results; }); } }; + expandComment = { init: function() { var a, _i, _len, _ref, _results; @@ -664,21 +666,18 @@ if (quote.getAttribute('href') === quote.hash) { quote.pathname = "/" + g.BOARD + "/res/" + threadID; } - if (quote.hash.slice(1) === threadID) { - quote.innerHTML += ' (OP)'; - } + if (quote.hash.slice(1) === threadID) quote.innerHTML += ' (OP)'; if (conf['Quote Preview']) { $.on(quote, 'mouseover', quotePreview.mouseover); $.on(quote, 'mousemove', ui.hover); $.on(quote, 'mouseout', quotePreview.mouseout); } - if (conf['Quote Inline']) { - $.on(quote, 'click', quoteInline.toggle); - } + if (conf['Quote Inline']) $.on(quote, 'click', quoteInline.toggle); } return $.replace(a.parentNode.parentNode, bq); } }; + expandThread = { init: function() { var a, span, _i, _len, _ref, _results; @@ -709,9 +708,7 @@ a = $('.omittedposts', thread); switch (a.textContent[0]) { case '+': - if ((_ref = $('.op .container', thread)) != null) { - _ref.innerHTML = ''; - } + if ((_ref = $('.op .container', thread)) != null) _ref.innerHTML = ''; a.textContent = a.textContent.replace('+', 'X Loading...'); return $.cache(pathname, (function() { return expandThread.parse(this, pathname, thread, a); @@ -739,7 +736,11 @@ _results = []; for (_i = 0, _len = _ref2.length; _i < _len; _i++) { backlink = _ref2[_i]; - _results.push(!$.id(backlink.hash.slice(1)) ? $.rm(backlink) : void 0); + if (!$.id(backlink.hash.slice(1))) { + _results.push($.rm(backlink)); + } else { + _results.push(void 0); + } } return _results; } @@ -785,13 +786,12 @@ return _results; } }; + replyHiding = { init: function() { return g.callbacks.push(function(root) { var a, dd, id, reply; - if (!(dd = $('.doubledash', root))) { - return; - } + if (!(dd = $('.doubledash', root))) return; dd.className = 'replyhider'; a = $.el('a', { textContent: '[ - ]' @@ -800,9 +800,7 @@ $.replace(dd.firstChild, a); reply = dd.nextSibling; id = reply.id; - if (id in g.hiddenReplies) { - return replyHiding.hide(reply); - } + if (id in g.hiddenReplies) return replyHiding.hide(reply); }); }, cb: { @@ -862,6 +860,7 @@ return $.set("hiddenReplies/" + g.BOARD + "/", g.hiddenReplies); } }; + keybinds = { init: function() { var node, _i, _len, _ref; @@ -878,9 +877,7 @@ if (((_ref = e.target.nodeName) === 'TEXTAREA' || _ref === 'INPUT') && !e.altKey && !e.ctrlKey && !(e.keyCode === 27)) { return; } - if (!(key = keybinds.keyCode(e))) { - return; - } + if (!(key = keybinds.keyCode(e))) return; thread = nav.getThread(); switch (key) { case conf.close: @@ -892,9 +889,7 @@ break; case conf.spoiler: ta = e.target; - if (ta.nodeName !== 'TEXTAREA') { - return; - } + if (ta.nodeName !== 'TEXTAREA') return; value = ta.value; selStart = ta.selectionStart; selEnd = ta.selectionEnd; @@ -951,14 +946,10 @@ threadHiding.toggle(thread); break; case conf.nextPage: - if ((_ref2 = $('input[value=Next]')) != null) { - _ref2.click(); - } + if ((_ref2 = $('input[value=Next]')) != null) _ref2.click(); break; case conf.previousPage: - if ((_ref3 = $('input[value=Previous]')) != null) { - _ref3.click(); - } + if ((_ref3 = $('input[value=Previous]')) != null) _ref3.click(); break; case conf.submit: if (QR.qr) { @@ -1041,12 +1032,8 @@ } })(); if (key) { - if (e.altKey) { - key = 'alt+' + key; - } - if (e.ctrlKey) { - key = 'ctrl+' + key; - } + if (e.altKey) key = 'alt+' + key; + if (e.ctrlKey) key = 'ctrl+' + key; } return key; }, @@ -1089,9 +1076,7 @@ rect = td.getBoundingClientRect(); if (rect.top > 0 && rect.bottom < d.body.clientHeight) { next = $.x('following::td[@class="reply"]', td); - if ($.x('ancestor::div[@class="thread"]', next) !== thread) { - return; - } + if ($.x('ancestor::div[@class="thread"]', next) !== thread) return; rect = next.getBoundingClientRect(); if (rect.top > 0 && rect.bottom < d.body.clientHeight) { next.className = 'replyhl'; @@ -1137,6 +1122,7 @@ } } }; + nav = { init: function() { var next, prev, span; @@ -1170,9 +1156,7 @@ rect = thread.getBoundingClientRect(); bottom = rect.bottom; if (bottom > 0) { - if (full) { - return [thread, i, rect]; - } + if (full) return [thread, i, rect]; return thread; } } @@ -1213,6 +1197,7 @@ return window.scrollBy(0, top); } }; + options = { init: function() { var a, home; @@ -1374,9 +1359,7 @@ keybind: function(e) { e.preventDefault(); e.stopPropagation(); - if ((key = keybinds.keyCode(e)) == null) { - return; - } + if ((key = keybinds.keyCode(e)) == null) return; this.value = key; $.set(this.name, key); return conf[this.name] = key; @@ -1394,12 +1377,11 @@ return $('#backlinkPreview').textContent = conf['backlink'].replace(/%id/, '123456789'); } }; + QR = { init: function() { var holder; - if (!($('form[name=post]') && $('#recaptcha_response_field'))) { - return; - } + if (!($('form[name=post]') && $('#recaptcha_response_field'))) return; g.callbacks.push(function(root) { var quote; quote = $('.quotejs + a', root); @@ -1430,9 +1412,7 @@ if (conf['Persistent QR']) { QR.dialog(); $('textarea', QR.qr).blur(); - if (conf['Auto Hide QR']) { - $('#autohide', QR.qr).checked = true; - } + if (conf['Auto Hide QR']) $('#autohide', QR.qr).checked = true; } if (conf['Cooldown']) { return $.on(window, 'storage', function(e) { @@ -1468,9 +1448,7 @@ captchaImg: function() { var c, qr; qr = QR.qr; - if (!qr) { - return; - } + if (!qr) return; c = QR.captcha.challenge; return $('#captcha img', qr).src = "http://www.google.com/recaptcha/api/image?c=" + c; }, @@ -1490,9 +1468,7 @@ captchas = $.get('captchas', []); cutoff = Date.now() - 5 * HOUR + 5 * MINUTE; while (captcha = captchas.shift()) { - if (captcha.time > cutoff) { - break; - } + if (captcha.time > cutoff) break; } $.set('captchas', captchas); QR.stats(captchas); @@ -1516,9 +1492,7 @@ QR.foo(this); return; } - if (this.parentNode.className === 'wat') { - QR.attach(this); - } + if (this.parentNode.className === 'wat') QR.attach(this); fr = new FileReader(); img = $('img', this.parentNode); fr.onload = function(e) { @@ -1532,9 +1506,7 @@ }, cooldown: function() { var b, cooldown, n, now; - if (!(g.REPLY && QR.qr)) { - return; - } + if (!(g.REPLY && QR.qr)) return; cooldown = $.get("cooldown/" + g.BOARD, 0); now = Date.now(); n = Math.ceil((cooldown - now) / 1000); @@ -1550,9 +1522,7 @@ textContent: 'Submit', disabled: false }); - if ($('#autopost', QR.qr).checked) { - return QR.submit(); - } + if ($('#autopost', QR.qr).checked) return QR.submit(); } }, foo: function(old) { @@ -1571,15 +1541,11 @@ }, dialog: function(text, tid) { var l, qr, ta; - if (text == null) { - text = ''; - } + if (text == null) text = ''; tid || (tid = g.THREAD_ID || ''); QR.qr = qr = ui.dialog('qr', 'top: 0; right: 0;', " X
    " + (g.REPLY ? "" : '') + " " + QR.spoiler + "
    "); QR.reset(); - if (conf['Cooldown']) { - QR.cooldown(); - } + if (conf['Cooldown']) QR.cooldown(); QR.foo(); $.on($('.close', qr), 'click', QR.close); $.on($('form', qr), 'submit', QR.submit); @@ -1601,27 +1567,21 @@ QR.captchaReload(); return; } - if (!(e.keyCode === 13 && v)) { - return; - } + if (!(e.keyCode === 13 && v)) return; QR.captchaPush(this); e.preventDefault(); return QR.submit(); }, quote: function(e, blank) { var bq, i, id, qr, s, sel, ss, ta, text, tid, v, _base, _ref, _ref2; - if (e != null) { - e.preventDefault(); - } + if (e != null) e.preventDefault(); tid = (_ref = $.x('ancestor::div[@class="thread"]/div', this)) != null ? _ref.id : void 0; id = this.textContent; text = ">>" + id + "\n"; sel = getSelection(); bq = $.x('ancestor::blockquote', sel.anchorNode); if (id === ((_ref2 = $.x('preceding-sibling::input', bq)) != null ? _ref2.name : void 0)) { - if (s = sel.toString().replace(/\n/g, '\n>')) { - text += ">" + s + "\n"; - } + if (s = sel.toString().replace(/\n/g, '\n>')) text += ">" + s + "\n"; } qr = QR.qr; if (!qr) { @@ -1652,9 +1612,7 @@ if (textContent) { $.extend($('a.error', qr), data); if (textContent === 'Error: Duplicate file entry detected.') { - if (row) { - $.rm(row); - } + if (row) $.rm(row); QR.stats(); setTimeout(QR.submit, 1000); } else if (textContent === 'You seem to have mistyped the verification.') { @@ -1662,9 +1620,7 @@ } return; } - if (row) { - $.rm(row); - } + if (row) $.rm(row); QR.stats(); if (conf['Persistent QR'] || ((_ref2 = $('#files input', qr)) != null ? _ref2.files.length : void 0)) { QR.reset(); @@ -1686,9 +1642,7 @@ $('[name=pwd]', qr).value = (m = c.match(/4chan_pass=([^;]+)/)) ? decodeURIComponent(m[1]) : $('input[name=pwd]').value; $('[name=sub]', qr).value = ''; if (!conf['Remember Spoiler']) { - if ((_ref = $('[name=spoiler]', qr)) != null) { - _ref.checked = false; - } + if ((_ref = $('[name=spoiler]', qr)) != null) _ref.checked = false; } return $('textarea', qr).value = ''; }, @@ -1708,34 +1662,22 @@ return; } $('.error', qr).textContent = ''; - if (e && (el = $('#recaptcha_response_field', qr)).value) { - QR.captchaPush(el); - } + if (e && (el = $('#recaptcha_response_field', qr)).value) QR.captchaPush(el); if (!(captcha = QR.captchaShift())) { alert('You forgot to type in the verification.'); - if (e != null) { - e.preventDefault(); - } + if (e != null) e.preventDefault(); return; } challenge = captcha.challenge, response = captcha.response; $('#challenge', qr).value = challenge; $('#response', qr).value = response; - if (conf['Auto Hide QR']) { - $('#autohide', qr).checked = true; - } - if (input = $('#files input', qr)) { - input.setAttribute('form', 'qr_form'); - } - if (!e) { - $('#qr_form', qr).submit(); - } + if (conf['Auto Hide QR']) $('#autohide', qr).checked = true; + if (input = $('#files input', qr)) input.setAttribute('form', 'qr_form'); + if (!e) $('#qr_form', qr).submit(); QR.sage = /sage/i.test($('[name=email]', qr).value); id = $('input[name=resto]', qr).value; QR.op = !id; - if (QR.op) { - $('[name=email]', qr).value = 'noko'; - } + if (QR.op) $('[name=email]', qr).value = 'noko'; if (conf['Thread Watcher'] && conf['Auto Watch Reply']) { op = $.id(id); if ($('img.favicon', op).src === Favicon.empty) { @@ -1756,7 +1698,7 @@ To access the parent, we have to break out of the sandbox and evaluate in the global context. - */ + */ return $.globalEval(function() { var data, href, node, textContent, _ref; $ = function(css) { @@ -1776,6 +1718,7 @@ }); } }; + threading = { init: function() { return threading.thread($('body > form').firstChild); @@ -1797,9 +1740,7 @@ thread: function(node) { var div; node = threading.op(node); - if (g.REPLY) { - return; - } + if (g.REPLY) return; div = $.el('div', { className: 'thread' }); @@ -1814,6 +1755,7 @@ } } }; + threadHiding = { init: function() { var a, hiddenThreads, op, thread, _i, _len, _ref, _results; @@ -1828,7 +1770,11 @@ }); $.on(a, 'click', threadHiding.cb.hide); $.prepend(op, a); - _results.push(op.id in hiddenThreads ? threadHiding.hideHide(thread) : void 0); + if (op.id in hiddenThreads) { + _results.push(threadHiding.hideHide(thread)); + } else { + _results.push(void 0); + } } return _results; }, @@ -1898,12 +1844,11 @@ return $.set("hiddenThreads/" + g.BOARD + "/", hiddenThreads); } }; + updater = { init: function() { var checkbox, checked, dialog, html, input, name, title, _i, _len, _ref; - if (!$('form[name=post]')) { - return; - } + if (!$('form[name=post]')) return; if (conf['Scrolling']) { if (conf['Scroll BG']) { updater.focus = true; @@ -2020,9 +1965,7 @@ while (reply = arr.pop()) { $.before(updater.br, reply); } - if (scroll) { - return scrollTo(0, d.body.scrollHeight); - } + if (scroll) return scrollTo(0, d.body.scrollHeight); } }, timeout: function() { @@ -2045,14 +1988,13 @@ update: function() { var cb, url, _ref; updater.timer.textContent = 0; - if ((_ref = updater.request) != null) { - _ref.abort(); - } + if ((_ref = updater.request) != null) _ref.abort(); url = location.pathname + '?' + Date.now(); cb = updater.cb.update; return updater.request = $.ajax(url, cb); } }; + watcher = { init: function() { var favicon, html, input, inputs, _i, _len; @@ -2070,9 +2012,7 @@ } watcher.refresh(); return $.on(window, 'storage', function(e) { - if (e.key === ("" + NAMESPACE + "watched")) { - return watcher.refresh(); - } + if (e.key === ("" + NAMESPACE + "watched")) return watcher.refresh(); }); }, refresh: function() { @@ -2103,7 +2043,11 @@ for (_j = 0, _len2 = _ref3.length; _j < _len2; _j++) { favicon = _ref3[_j]; id = favicon.nextSibling.name; - _results.push(id in watchedBoard ? favicon.src = Favicon["default"] : favicon.src = Favicon.empty); + if (id in watchedBoard) { + _results.push(favicon.src = Favicon["default"]); + } else { + _results.push(favicon.src = Favicon.empty); + } } return _results; }, @@ -2147,6 +2091,7 @@ return watcher.refresh(); } }; + anonymize = { init: function() { return g.callbacks.push(function(root) { @@ -2163,6 +2108,7 @@ }); } }; + sauce = { init: function() { sauce.prefixes = conf['flavors'].match(/^[^#].+$/gm); @@ -2171,9 +2117,7 @@ }); return g.callbacks.push(function(root) { var i, link, prefix, suffix, thumb, _len, _ref, _results; - if (root.className === 'inline' || !(thumb = $('img[md5]', root))) { - return; - } + if (root.className === 'inline' || !(thumb = $('img[md5]', root))) return; suffix = thumb.src; _ref = sauce.prefixes; _results = []; @@ -2190,6 +2134,7 @@ }); } }; + revealSpoilers = { init: function() { return g.callbacks.push(function(root) { @@ -2204,14 +2149,13 @@ }); } }; + Time = { init: function() { var chanOffset; Time.foo(); chanOffset = 5 - new Date().getTimezoneOffset() / 60; - if ($.isDST()) { - chanOffset--; - } + if ($.isDST()) chanOffset--; this.parse = Date.parse('10/11/11(Tue)18:53') ? function(node) { return new Date(Date.parse(node.textContent) + chanOffset * HOUR); } : function(node) { @@ -2226,9 +2170,7 @@ }, node: function(root) { var node, posttime, time; - if (root.className === 'inline') { - return; - } + if (root.className === 'inline') return; node = (posttime = $('.posttime', root)) ? posttime : $('span[id]', root).previousSibling; Time.date = Time.parse(node); time = $.el('time', { @@ -2312,25 +2254,26 @@ } } }; + getTitle = function(thread) { var el, span; el = $('.filetitle', thread); if (!el.textContent) { el = $('blockquote', thread); - if (!el.textContent) { - el = $('.postername', thread); - } + if (!el.textContent) el = $('.postername', thread); } span = $.el('span', { innerHTML: el.innerHTML.replace(/
    /g, ' ') }); return "/" + g.BOARD + "/ - " + span.textContent; }; + titlePost = { init: function() { return d.title = getTitle(); } }; + quoteBacklink = { init: function() { var format; @@ -2338,16 +2281,12 @@ quoteBacklink.funk = Function('id', "return'" + format + "'"); return g.callbacks.push(function(root) { var a, container, el, id, link, qid, quote, quotes, _i, _len, _ref, _results; - if (/\binline\b/.test(root.className)) { - return; - } + if (/\binline\b/.test(root.className)) return; quotes = {}; _ref = $$('.quotelink', root); for (_i = 0, _len = _ref.length; _i < _len; _i++) { quote = _ref[_i]; - if (!(qid = quote.hash.slice(1))) { - continue; - } + if (!(qid = quote.hash.slice(1))) continue; quotes[qid] = quote; } id = $('input', root).name; @@ -2358,21 +2297,15 @@ }); _results = []; for (qid in quotes) { - if (!(el = $.id(qid))) { - continue; - } - if (el.className === 'op' && !conf['OP Backlinks']) { - continue; - } + if (!(el = $.id(qid))) continue; + if (el.className === 'op' && !conf['OP Backlinks']) continue; link = a.cloneNode(true); if (conf['Quote Preview']) { $.on(link, 'mouseover', quotePreview.mouseover); $.on(link, 'mousemove', ui.hover); $.on(link, 'mouseout', quotePreview.mouseout); } - if (conf['Quote Inline']) { - $.on(link, 'click', quoteInline.toggle); - } + if (conf['Quote Inline']) $.on(link, 'click', quoteInline.toggle); if (!((container = $('.container', el)) && container.parentNode === el)) { container = $.el('span', { className: 'container' @@ -2386,6 +2319,7 @@ }); } }; + quoteInline = { init: function() { return g.callbacks.push(function(root) { @@ -2394,9 +2328,7 @@ _results = []; for (_i = 0, _len = _ref.length; _i < _len; _i++) { quote = _ref[_i]; - if (!quote.hash) { - continue; - } + if (!quote.hash) continue; quote.removeAttribute('onclick'); _results.push($.on(quote, 'click', quoteInline.toggle)); } @@ -2405,17 +2337,13 @@ }, toggle: function(e) { var id; - if (e.shiftKey || e.altKey || e.ctrlKey || e.button !== 0) { - return; - } + if (e.shiftKey || e.altKey || e.ctrlKey || e.button !== 0) return; e.preventDefault(); id = this.hash.slice(1); if (/\binlined\b/.test(this.className)) { quoteInline.rm(this, id); } else { - if ($.x("ancestor::*[@id='" + id + "']", this)) { - return; - } + if ($.x("ancestor::*[@id='" + id + "']", this)) return; quoteInline.add(this, id); } return this.classList.toggle('inlined'); @@ -2460,9 +2388,7 @@ }, parse: function(req, pathname, id, threadID, inline) { var body, href, html, link, newInline, op, quote, reply, _i, _j, _len, _len2, _ref, _ref2; - if (!inline.parentNode) { - return; - } + if (!inline.parentNode) return; if (req.status !== 200) { inline.innerHTML = "" + req.status + " " + req.statusText; return; @@ -2507,6 +2433,7 @@ }); } }; + quotePreview = { init: function() { return g.callbacks.push(function(root) { @@ -2515,9 +2442,7 @@ _results = []; for (_i = 0, _len = _ref.length; _i < _len; _i++) { quote = _ref[_i]; - if (!quote.hash) { - continue; - } + if (!quote.hash) continue; $.on(quote, 'mouseover', quotePreview.mouseover); $.on(quote, 'mousemove', ui.hover); _results.push($.on(quote, 'mouseout', quotePreview.mouseout)); @@ -2535,16 +2460,18 @@ id = this.hash.slice(1); if (el = $.id(id)) { qp.innerHTML = el.innerHTML; - if (conf['Quote Highlighting']) { - $.addClass(el, 'qphl'); - } + if (conf['Quote Highlighting']) $.addClass(el, 'qphl'); if (/\bbacklink\b/.test(this.className)) { replyID = $.x('preceding::input', this).name; _ref = $$('.quotelink', qp); _results = []; for (_i = 0, _len = _ref.length; _i < _len; _i++) { quote = _ref[_i]; - _results.push(quote.hash.slice(1) === replyID ? quote.className = 'forwardlink' : void 0); + if (quote.hash.slice(1) === replyID) { + _results.push(quote.className = 'forwardlink'); + } else { + _results.push(void 0); + } } return _results; } @@ -2559,16 +2486,12 @@ }, mouseout: function() { var el; - if (el = $.id(this.hash.slice(1))) { - $.removeClass(el, 'qphl'); - } + if (el = $.id(this.hash.slice(1))) $.removeClass(el, 'qphl'); return ui.hoverend(); }, parse: function(req, id, threadID) { var body, html, op, qp, reply, _i, _len, _ref; - if (!((qp = ui.el) && (qp.innerHTML === ("Loading " + id + "...")))) { - return; - } + if (!((qp = ui.el) && (qp.innerHTML === ("Loading " + id + "...")))) return; if (req.status !== 200) { qp.innerHTML = "" + req.status + " " + req.statusText; return; @@ -2593,24 +2516,28 @@ return Time.node(qp); } }; + quoteOP = { init: function() { return g.callbacks.push(function(root) { var quote, tid, _i, _len, _ref, _results; - if (root.className === 'inline') { - return; - } + if (root.className === 'inline') return; tid = g.THREAD_ID || $.x('ancestor::div[contains(@class,"thread")]/div', root).id; _ref = $$('.quotelink', root); _results = []; for (_i = 0, _len = _ref.length; _i < _len; _i++) { quote = _ref[_i]; - _results.push(quote.hash.slice(1) === tid ? quote.innerHTML += ' (OP)' : void 0); + if (quote.hash.slice(1) === tid) { + _results.push(quote.innerHTML += ' (OP)'); + } else { + _results.push(void 0); + } } return _results; }); } }; + reportButton = { init: function() { return g.callbacks.push(function(root) { @@ -2635,6 +2562,7 @@ return window.open(url, id, set); } }; + threadStats = { init: function() { var dialog, html; @@ -2649,9 +2577,7 @@ return g.callbacks.push(threadStats.node); }, node: function(root) { - if (root.className) { - return; - } + if (root.className) return; threadStats.postcountEl.textContent = ++threadStats.posts; if ($('img[md5]', root)) { threadStats.imagecountEl.textContent = ++threadStats.images; @@ -2661,6 +2587,7 @@ } } }; + unread = { init: function() { unread.replies = []; @@ -2669,14 +2596,10 @@ return g.callbacks.push(unread.node); }, node: function(root) { - if (root.hidden || root.className) { - return; - } + if (root.hidden || root.className) return; unread.replies.push(root); unread.updateTitle(); - if (unread.replies.length === 1) { - return Favicon.update(); - } + if (unread.replies.length === 1) return Favicon.update(); }, scroll: function() { var bottom, height, i, reply, _len, _ref; @@ -2686,23 +2609,18 @@ for (i = 0, _len = _ref.length; i < _len; i++) { reply = _ref[i]; bottom = reply.getBoundingClientRect().bottom; - if (bottom > height) { - break; - } - } - if (i === 0) { - return; + if (bottom > height) break; } + if (i === 0) return; unread.replies = unread.replies.slice(i); unread.updateTitle(); - if (unread.replies.length === 0) { - return Favicon.update(); - } + if (unread.replies.length === 0) return Favicon.update(); }, updateTitle: function() { return d.title = d.title.replace(/\d+/, unread.replies.length); } }; + Favicon = { init: function() { var favicon, href; @@ -2726,6 +2644,7 @@ return $.replace(favicon, clone); } }; + redirect = function() { var url; switch (g.BOARD) { @@ -2769,13 +2688,12 @@ } return location.href = url; }; + imgHover = { init: function() { return g.callbacks.push(function(root) { var thumb; - if (!(thumb = $('img[md5]', root))) { - return; - } + if (!(thumb = $('img[md5]', root))) return; $.on(thumb, 'mouseover', imgHover.mouseover); $.on(thumb, 'mousemove', ui.hover); return $.on(thumb, 'mouseout', ui.hoverend); @@ -2789,6 +2707,7 @@ return $.add(d.body, ui.el); } }; + imgPreloading = { init: function() { var controls, form, label; @@ -2820,9 +2739,7 @@ }, node: function(root) { var thumb; - if (!(imgPreloading.on && (thumb = $('img[md5]:last-child', root)))) { - return; - } + if (!(imgPreloading.on && (thumb = $('img[md5]:last-child', root)))) return; return imgPreloading.preload(thumb); }, preload: function(thumb) { @@ -2831,20 +2748,18 @@ }); } }; + imgGif = { init: function() { return g.callbacks.push(function(root) { var src, thumb; - if (!(thumb = $('img[md5]', root))) { - return; - } + if (!(thumb = $('img[md5]', root))) return; src = thumb.parentNode.href; - if (/gif$/.test(src)) { - return thumb.src = src; - } + if (/gif$/.test(src)) return thumb.src = src; }); } }; + imgExpand = { init: function() { g.callbacks.push(imgExpand.node); @@ -2852,9 +2767,7 @@ }, node: function(root) { var a, thumb; - if (!(thumb = $('img[md5]', root))) { - return; - } + if (!(thumb = $('img[md5]', root))) return; a = thumb.parentNode; $.on(a, 'click', imgExpand.cb.toggle); if (imgExpand.on && root.className !== 'inline') { @@ -2863,9 +2776,7 @@ }, cb: { toggle: function(e) { - if (e.shiftKey || e.altKey || e.ctrlKey || e.button !== 0) { - return; - } + if (e.shiftKey || e.altKey || e.ctrlKey || e.button !== 0) return; e.preventDefault(); return imgExpand.toggle(this); }, @@ -2909,9 +2820,7 @@ form.className = klass; if (/\bfitheight\b/.test(form.className)) { $.on(window, 'resize', imgExpand.resize); - if (!imgExpand.style) { - imgExpand.style = $.addStyle(''); - } + if (!imgExpand.style) imgExpand.style = $.addStyle(''); return imgExpand.resize(); } else if (imgExpand.style) { return $.off(window, 'resize', imgExpand.resize); @@ -2962,9 +2871,7 @@ } }, retry: function(thumb) { - if (!thumb.hidden) { - return imgExpand.expand(thumb); - } + if (!thumb.hidden) return imgExpand.expand(thumb); }, dialog: function() { var controls, form, imageType, option, select, _i, _len, _ref; @@ -2993,6 +2900,7 @@ return imgExpand.style.innerHTML = ".fitheight img + img {max-height:" + d.body.clientHeight + "px;}"; } }; + firstRun = { init: function() { var dialog, style; @@ -3018,6 +2926,7 @@ return $.off(window, 'click', firstRun.close); } }; + Main = { init: function() { var cutoff, hiddenThreads, id, lastChecked, now, pathname, temp, timestamp, _ref; @@ -3048,59 +2957,29 @@ hiddenThreads = $.get("hiddenThreads/" + g.BOARD + "/", {}); for (id in hiddenThreads) { timestamp = hiddenThreads[id]; - if (timestamp < cutoff) { - delete hiddenThreads[id]; - } + if (timestamp < cutoff) delete hiddenThreads[id]; } _ref = g.hiddenReplies; for (id in _ref) { timestamp = _ref[id]; - if (timestamp < cutoff) { - delete g.hiddenReplies[id]; - } + if (timestamp < cutoff) delete g.hiddenReplies[id]; } $.set("hiddenThreads/" + g.BOARD + "/", hiddenThreads); $.set("hiddenReplies/" + g.BOARD + "/", g.hiddenReplies); } - if (conf['Filter']) { - filter.init(); - } - if (conf['Reply Hiding']) { - replyHiding.init(); - } - if (conf['Filter'] || conf['Reply Hiding']) { - strikethroughQuotes.init(); - } - if (conf['Anonymize']) { - anonymize.init(); - } - if (conf['Time Formatting']) { - Time.init(); - } - if (conf['Sauce']) { - sauce.init(); - } - if (conf['Image Auto-Gif']) { - imgGif.init(); - } - if (conf['Image Hover']) { - imgHover.init(); - } - if (conf['Report Button']) { - reportButton.init(); - } - if (conf['Quote Inline']) { - quoteInline.init(); - } - if (conf['Quote Preview']) { - quotePreview.init(); - } - if (conf['Quote Backlinks']) { - quoteBacklink.init(); - } - if (conf['Indicate OP quote']) { - quoteOP.init(); - } + if (conf['Filter']) filter.init(); + if (conf['Reply Hiding']) replyHiding.init(); + if (conf['Filter'] || conf['Reply Hiding']) strikethroughQuotes.init(); + if (conf['Anonymize']) anonymize.init(); + if (conf['Time Formatting']) Time.init(); + if (conf['Sauce']) sauce.init(); + if (conf['Image Auto-Gif']) imgGif.init(); + if (conf['Image Hover']) imgHover.init(); + if (conf['Report Button']) reportButton.init(); + if (conf['Quote Inline']) quoteInline.init(); + if (conf['Quote Preview']) quotePreview.init(); + if (conf['Quote Backlinks']) quoteBacklink.init(); + if (conf['Indicate OP quote']) quoteOP.init(); if (d.body) { return Main.onLoad(); } else { @@ -3114,59 +2993,27 @@ redirect(); return; } - if (!$('#navtopr')) { - return; - } + if (!$('#navtopr')) return; $.addStyle(Main.css); threading.init(); Favicon.init(); - if (conf['Image Expansion']) { - imgExpand.init(); - } - if (conf['Reveal Spoilers'] && $('.postarea label')) { - revealSpoilers.init(); - } - if (conf['Quick Reply']) { - QR.init(); - } - if (conf['Thread Watcher']) { - watcher.init(); - } - if (conf['Keybinds']) { - keybinds.init(); - } + if (conf['Image Expansion']) imgExpand.init(); + if (conf['Reveal Spoilers'] && $('.postarea label')) revealSpoilers.init(); + if (conf['Quick Reply']) QR.init(); + if (conf['Thread Watcher']) watcher.init(); + if (conf['Keybinds']) keybinds.init(); if (g.REPLY) { - if (conf['Thread Updater']) { - updater.init(); - } - if (conf['Thread Stats']) { - threadStats.init(); - } - if (conf['Image Preloading']) { - imgPreloading.init(); - } - if (conf['Reply Navigation']) { - nav.init(); - } - if (conf['Post in Title']) { - titlePost.init(); - } - if (conf['Unread Count']) { - unread.init(); - } + if (conf['Thread Updater']) updater.init(); + if (conf['Thread Stats']) threadStats.init(); + if (conf['Image Preloading']) imgPreloading.init(); + if (conf['Reply Navigation']) nav.init(); + if (conf['Post in Title']) titlePost.init(); + if (conf['Unread Count']) unread.init(); } else { - if (conf['Thread Hiding']) { - threadHiding.init(); - } - if (conf['Thread Expansion']) { - expandThread.init(); - } - if (conf['Comment Expansion']) { - expandComment.init(); - } - if (conf['Index Navigation']) { - nav.init(); - } + if (conf['Thread Hiding']) threadHiding.init(); + if (conf['Thread Expansion']) expandThread.init(); + if (conf['Comment Expansion']) expandComment.init(); + if (conf['Index Navigation']) nav.init(); } nodes = $$('.op, a + table'); g.callbacks.forEach(function(callback) { @@ -3178,23 +3025,17 @@ }); $.on($('form[name=delform]'), 'DOMNodeInserted', Main.node); options.init(); - if (!$.get('firstrun')) { - return firstRun.init(); - } + if (!$.get('firstrun')) return firstRun.init(); }, message: function(e) { var data, origin; origin = e.origin, data = e.data; - if (origin === 'http://sys.4chan.org') { - return QR.receive(data); - } + if (origin === 'http://sys.4chan.org') return QR.receive(data); }, node: function(e) { var target; target = e.target; - if (target.nodeName !== 'TABLE') { - return; - } + if (target.nodeName !== 'TABLE') return; return g.callbacks.forEach(function(callback) { try { return callback(target); @@ -3471,5 +3312,7 @@ }\ ' }; + Main.init(); + }).call(this); From 949ce029843a465547b0c99a7c781bf4dc0d01e6 Mon Sep 17 00:00:00 2001 From: James Campos Date: Sun, 13 Nov 2011 10:50:13 -0800 Subject: [PATCH 049/169] fix sauce --- 4chan_x.user.js | 3 ++- script.coffee | 1 + 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/4chan_x.user.js b/4chan_x.user.js index 8c707cc43..877bb6f3a 100644 --- a/4chan_x.user.js +++ b/4chan_x.user.js @@ -2116,8 +2116,9 @@ return prefix.match(/(\w+)\./)[1]; }); return g.callbacks.push(function(root) { - var i, link, prefix, suffix, thumb, _len, _ref, _results; + var i, link, prefix, span, suffix, thumb, _len, _ref, _results; if (root.className === 'inline' || !(thumb = $('img[md5]', root))) return; + span = $('.filesize', root); suffix = thumb.src; _ref = sauce.prefixes; _results = []; diff --git a/script.coffee b/script.coffee index 62f1e8fd1..f6b2ffd5e 100644 --- a/script.coffee +++ b/script.coffee @@ -1651,6 +1651,7 @@ sauce = sauce.names = sauce.prefixes.map (prefix) -> prefix.match(/(\w+)\./)[1] g.callbacks.push (root) -> return if root.className is 'inline' or not thumb = $ 'img[md5]', root + span = $ '.filesize', root suffix = thumb.src for prefix, i in sauce.prefixes link = $.el 'a', From 24ac28a4841e3518848420820c09d12149516a01 Mon Sep 17 00:00:00 2001 From: James Campos Date: Fri, 18 Nov 2011 23:36:01 -0800 Subject: [PATCH 050/169] disable thread updater for mootykins --- 4chan_x.user.js | 2 +- script.coffee | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/4chan_x.user.js b/4chan_x.user.js index 877bb6f3a..ad14660fb 100644 --- a/4chan_x.user.js +++ b/4chan_x.user.js @@ -94,7 +94,7 @@ 'Reveal Spoilers': [false, 'Replace spoiler thumbnails by the original thumbnail'] }, Monitoring: { - 'Thread Updater': [true, 'Update threads. Has more options in its own dialog.'], + 'Thread Updater': [false, 'Update threads. Has more options in its own dialog.'], 'Unread Count': [true, 'Show unread post count in tab title'], 'Post in Title': [true, 'Show the op\'s post in the tab title'], 'Thread Stats': [true, 'Display reply and image count'], diff --git a/script.coffee b/script.coffee index f6b2ffd5e..fa87878b9 100644 --- a/script.coffee +++ b/script.coffee @@ -24,7 +24,7 @@ config = 'Sauce': [true, 'Add sauce to images'] 'Reveal Spoilers': [false, 'Replace spoiler thumbnails by the original thumbnail'] Monitoring: - 'Thread Updater': [true, 'Update threads. Has more options in its own dialog.'] + 'Thread Updater': [false, 'Update threads. Has more options in its own dialog.'] 'Unread Count': [true, 'Show unread post count in tab title'] 'Post in Title': [true, 'Show the op\'s post in the tab title'] 'Thread Stats': [true, 'Display reply and image count'] From 94d11e957007b6ab3ed5779a865cf3de3e9b3e03 Mon Sep 17 00:00:00 2001 From: James Campos Date: Sat, 19 Nov 2011 00:26:20 -0800 Subject: [PATCH 051/169] 15s min update interval --- 4chan_x.user.js | 3 ++- script.coffee | 5 ++++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/4chan_x.user.js b/4chan_x.user.js index ad14660fb..70328a4da 100644 --- a/4chan_x.user.js +++ b/4chan_x.user.js @@ -1891,7 +1891,8 @@ } } else if (input.name === 'Interval') { $.on(input, 'change', function() { - return conf['Interval'] = this.value = parseInt(this.value) || conf['Interval']; + if ((val = parseInt(this.value)) < 15) val = 15; + return conf['Interval'] = this.value = val; }); $.on(input, 'change', $.cb.value); } else if (input.type === 'button') { diff --git a/script.coffee b/script.coffee index fa87878b9..b1f7cb2e5 100644 --- a/script.coffee +++ b/script.coffee @@ -1470,7 +1470,10 @@ updater = $.on input, 'click', updater.cb.autoUpdate updater.cb.autoUpdate.call input else if input.name is 'Interval' - $.on input, 'change', -> conf['Interval'] = @value = parseInt(@value) or conf['Interval'] + $.on input, 'change', -> + if (val = parseInt @value) < 15 + val = 15 + conf['Interval'] = @value = val $.on input, 'change', $.cb.value else if input.type is 'button' $.on input, 'click', updater.update From fd74e31ecf95a30de27ba3ca9bae8a7a4836e0bf Mon Sep 17 00:00:00 2001 From: James Campos Date: Sat, 19 Nov 2011 13:42:53 -0800 Subject: [PATCH 052/169] update archives, close #401 --- 4chan_x.user.js | 4 ++++ script.coffee | 2 ++ 2 files changed, 6 insertions(+) diff --git a/4chan_x.user.js b/4chan_x.user.js index 70328a4da..c7ca64a5c 100644 --- a/4chan_x.user.js +++ b/4chan_x.user.js @@ -2660,6 +2660,10 @@ case 'lit': url = "http://archive.gentoomen.org/cgi-board.pl/" + g.BOARD + "/thread/" + g.THREAD_ID; break; + case 'g': + case 'sci': + url = "http://archive.installgentoo.net/" + g.BOARD + "/thread/" + g.THREAD_ID; + break; case '3': case 'adv': case 'an': diff --git a/script.coffee b/script.coffee index b1f7cb2e5..dc1b5346b 100644 --- a/script.coffee +++ b/script.coffee @@ -2044,6 +2044,8 @@ redirect = -> url = "http://archive.foolz.us/#{g.BOARD}/thread/#{g.THREAD_ID}" when 'lit' url = "http://archive.gentoomen.org/cgi-board.pl/#{g.BOARD}/thread/#{g.THREAD_ID}" + when 'g', 'sci' + url = "http://archive.installgentoo.net/#{g.BOARD}/thread/#{g.THREAD_ID}" when '3', 'adv', 'an', 'ck', 'co', 'diy', 'fa', 'fit', 'int', 'k', 'mu', 'n', 'o', 'p', 'po', 'pol', 'soc', 'sp', 'toy', 'trv', 'v', 'vp', 'x' url = "http://archive.no-ip.org/#{g.BOARD}/thread/#{g.THREAD_ID}" else From 1362b76dfd4743943a0cb061f5c43d20afeb729a Mon Sep 17 00:00:00 2001 From: James Campos Date: Sat, 19 Nov 2011 22:48:50 -0800 Subject: [PATCH 053/169] send diy to installgentoo --- 4chan_x.user.js | 2 +- script.coffee | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/4chan_x.user.js b/4chan_x.user.js index c7ca64a5c..6cf59d22c 100644 --- a/4chan_x.user.js +++ b/4chan_x.user.js @@ -2660,6 +2660,7 @@ case 'lit': url = "http://archive.gentoomen.org/cgi-board.pl/" + g.BOARD + "/thread/" + g.THREAD_ID; break; + case 'diy': case 'g': case 'sci': url = "http://archive.installgentoo.net/" + g.BOARD + "/thread/" + g.THREAD_ID; @@ -2669,7 +2670,6 @@ case 'an': case 'ck': case 'co': - case 'diy': case 'fa': case 'fit': case 'int': diff --git a/script.coffee b/script.coffee index dc1b5346b..59db6faf8 100644 --- a/script.coffee +++ b/script.coffee @@ -2044,9 +2044,9 @@ redirect = -> url = "http://archive.foolz.us/#{g.BOARD}/thread/#{g.THREAD_ID}" when 'lit' url = "http://archive.gentoomen.org/cgi-board.pl/#{g.BOARD}/thread/#{g.THREAD_ID}" - when 'g', 'sci' + when 'diy', 'g', 'sci' url = "http://archive.installgentoo.net/#{g.BOARD}/thread/#{g.THREAD_ID}" - when '3', 'adv', 'an', 'ck', 'co', 'diy', 'fa', 'fit', 'int', 'k', 'mu', 'n', 'o', 'p', 'po', 'pol', 'soc', 'sp', 'toy', 'trv', 'v', 'vp', 'x' + when '3', 'adv', 'an', 'ck', 'co', 'fa', 'fit', 'int', 'k', 'mu', 'n', 'o', 'p', 'po', 'pol', 'soc', 'sp', 'toy', 'trv', 'v', 'vp', 'x' url = "http://archive.no-ip.org/#{g.BOARD}/thread/#{g.THREAD_ID}" else url = "http://boards.4chan.org/#{g.BOARD}" From 95b1b718d4da1eb073017d74110e9922ba8a5b43 Mon Sep 17 00:00:00 2001 From: Nicolas Stepien Date: Thu, 24 Nov 2011 00:30:50 +0100 Subject: [PATCH 054/169] Remove image preloading --- changelog | 2 +- script.coffee | 29 ----------------------------- 2 files changed, 1 insertion(+), 30 deletions(-) diff --git a/changelog b/changelog index 49590ee57..caab61480 100644 --- a/changelog +++ b/changelog @@ -3,7 +3,7 @@ master initiate 4chan X earlier performance improvements regular expressions based filter - do not preload images automatically + remove image preloading automatically reload expanded pictures on error update archives redirections for /diy/, /pol/ and /sci/ handle bans with the thread updater diff --git a/script.coffee b/script.coffee index 59db6faf8..bb8570d7c 100644 --- a/script.coffee +++ b/script.coffee @@ -20,7 +20,6 @@ config = 'Image Auto-Gif': [false, 'Animate gif thumbnails'] 'Image Expansion': [true, 'Expand images'] 'Image Hover': [false, 'Show full image on mouseover'] - 'Image Preloading': [false, 'Preload Images'] 'Sauce': [true, 'Add sauce to images'] 'Reveal Spoilers': [false, 'Replace spoiler thumbnails by the original thumbnail'] Monitoring: @@ -2065,31 +2064,6 @@ imgHover = src: @parentNode.href $.add d.body, ui.el -imgPreloading = - init: -> - unless controls = $.id 'imgControls' - controls = $.el 'div', - id: 'imgControls' - form = $ 'body > form' - $.prepend form, controls - - label = $.el 'label', - innerHTML: 'Preload Images' - $.on $('input', label), 'click', imgPreloading.click - $.add controls, label - - g.callbacks.push imgPreloading.node - - click: -> - if imgPreloading.on = @checked - for thumb in $$ 'img[md5]:last-child' - imgPreloading.preload thumb - node: (root) -> - return unless imgPreloading.on and thumb = $ 'img[md5]:last-child', root - imgPreloading.preload thumb - preload: (thumb) -> - $.el 'img', src: thumb.parentNode.href - imgGif = init: -> g.callbacks.push (root) -> @@ -2401,9 +2375,6 @@ Main = if conf['Thread Stats'] threadStats.init() - if conf['Image Preloading'] - imgPreloading.init() - if conf['Reply Navigation'] nav.init() From 9f6c6ec1c60cd167a48fc978d93e2c94b0839b7f Mon Sep 17 00:00:00 2001 From: Nicolas Stepien Date: Thu, 24 Nov 2011 00:31:26 +0100 Subject: [PATCH 055/169] Revert "disable thread updater for mootykins" This reverts commit 24ac28a4841e3518848420820c09d12149516a01. --- 4chan_x.user.js | 2 +- script.coffee | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/4chan_x.user.js b/4chan_x.user.js index 6cf59d22c..9b15de2c0 100644 --- a/4chan_x.user.js +++ b/4chan_x.user.js @@ -94,7 +94,7 @@ 'Reveal Spoilers': [false, 'Replace spoiler thumbnails by the original thumbnail'] }, Monitoring: { - 'Thread Updater': [false, 'Update threads. Has more options in its own dialog.'], + 'Thread Updater': [true, 'Update threads. Has more options in its own dialog.'], 'Unread Count': [true, 'Show unread post count in tab title'], 'Post in Title': [true, 'Show the op\'s post in the tab title'], 'Thread Stats': [true, 'Display reply and image count'], diff --git a/script.coffee b/script.coffee index bb8570d7c..222360b43 100644 --- a/script.coffee +++ b/script.coffee @@ -23,7 +23,7 @@ config = 'Sauce': [true, 'Add sauce to images'] 'Reveal Spoilers': [false, 'Replace spoiler thumbnails by the original thumbnail'] Monitoring: - 'Thread Updater': [false, 'Update threads. Has more options in its own dialog.'] + 'Thread Updater': [true, 'Update threads. Has more options in its own dialog.'] 'Unread Count': [true, 'Show unread post count in tab title'] 'Post in Title': [true, 'Show the op\'s post in the tab title'] 'Thread Stats': [true, 'Display reply and image count'] From b7aefb71378304cce2a9206a1ea0ed98cb530968 Mon Sep 17 00:00:00 2001 From: Nicolas Stepien Date: Thu, 24 Nov 2011 00:31:36 +0100 Subject: [PATCH 056/169] Revert "15s min update interval" This reverts commit 94d11e957007b6ab3ed5779a865cf3de3e9b3e03. --- 4chan_x.user.js | 3 +-- script.coffee | 5 +---- 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/4chan_x.user.js b/4chan_x.user.js index 9b15de2c0..ad0a4d322 100644 --- a/4chan_x.user.js +++ b/4chan_x.user.js @@ -1891,8 +1891,7 @@ } } else if (input.name === 'Interval') { $.on(input, 'change', function() { - if ((val = parseInt(this.value)) < 15) val = 15; - return conf['Interval'] = this.value = val; + return conf['Interval'] = this.value = parseInt(this.value) || conf['Interval']; }); $.on(input, 'change', $.cb.value); } else if (input.type === 'button') { diff --git a/script.coffee b/script.coffee index 222360b43..c1692e92c 100644 --- a/script.coffee +++ b/script.coffee @@ -1469,10 +1469,7 @@ updater = $.on input, 'click', updater.cb.autoUpdate updater.cb.autoUpdate.call input else if input.name is 'Interval' - $.on input, 'change', -> - if (val = parseInt @value) < 15 - val = 15 - conf['Interval'] = @value = val + $.on input, 'change', -> conf['Interval'] = @value = parseInt(@value) or conf['Interval'] $.on input, 'change', $.cb.value else if input.type is 'button' $.on input, 'click', updater.update From fdf205298be69721277b3bc403cfd9d0c51883b4 Mon Sep 17 00:00:00 2001 From: Nicolas Stepien Date: Thu, 24 Nov 2011 00:40:13 +0100 Subject: [PATCH 057/169] Compile --- 4chan_x.user.js | 45 +-------------------------------------------- 1 file changed, 1 insertion(+), 44 deletions(-) diff --git a/4chan_x.user.js b/4chan_x.user.js index ad0a4d322..ecf263333 100644 --- a/4chan_x.user.js +++ b/4chan_x.user.js @@ -62,7 +62,7 @@ */ (function() { - var $, $$, DAY, Favicon, HOUR, MINUTE, Main, NAMESPACE, QR, SECOND, Time, anonymize, conf, config, d, expandComment, expandThread, filter, firstRun, flatten, g, getTitle, imgExpand, imgGif, imgHover, imgPreloading, key, keybinds, log, nav, options, quoteBacklink, quoteInline, quoteOP, quotePreview, redirect, replyHiding, reportButton, revealSpoilers, sauce, strikethroughQuotes, 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, filter, firstRun, flatten, g, getTitle, imgExpand, imgGif, imgHover, key, keybinds, log, nav, options, quoteBacklink, quoteInline, quoteOP, quotePreview, redirect, replyHiding, reportButton, revealSpoilers, sauce, strikethroughQuotes, threadHiding, threadStats, threading, titlePost, ui, unread, updater, val, watcher; var __slice = Array.prototype.slice; config = { @@ -89,7 +89,6 @@ 'Image Auto-Gif': [false, 'Animate gif thumbnails'], 'Image Expansion': [true, 'Expand images'], 'Image Hover': [false, 'Show full image on mouseover'], - 'Image Preloading': [false, 'Preload Images'], 'Sauce': [true, 'Add sauce to images'], 'Reveal Spoilers': [false, 'Replace spoiler thumbnails by the original thumbnail'] }, @@ -2713,47 +2712,6 @@ } }; - imgPreloading = { - init: function() { - var controls, form, label; - if (!(controls = $.id('imgControls'))) { - controls = $.el('div', { - id: 'imgControls' - }); - form = $('body > form'); - $.prepend(form, controls); - } - label = $.el('label', { - innerHTML: 'Preload Images' - }); - $.on($('input', label), 'click', imgPreloading.click); - $.add(controls, label); - return g.callbacks.push(imgPreloading.node); - }, - click: function() { - var thumb, _i, _len, _ref, _results; - if (imgPreloading.on = this.checked) { - _ref = $$('img[md5]:last-child'); - _results = []; - for (_i = 0, _len = _ref.length; _i < _len; _i++) { - thumb = _ref[_i]; - _results.push(imgPreloading.preload(thumb)); - } - return _results; - } - }, - node: function(root) { - var thumb; - if (!(imgPreloading.on && (thumb = $('img[md5]:last-child', root)))) return; - return imgPreloading.preload(thumb); - }, - preload: function(thumb) { - return $.el('img', { - src: thumb.parentNode.href - }); - } - }; - imgGif = { init: function() { return g.callbacks.push(function(root) { @@ -3010,7 +2968,6 @@ if (g.REPLY) { if (conf['Thread Updater']) updater.init(); if (conf['Thread Stats']) threadStats.init(); - if (conf['Image Preloading']) imgPreloading.init(); if (conf['Reply Navigation']) nav.init(); if (conf['Post in Title']) titlePost.init(); if (conf['Unread Count']) unread.init(); From fc15e91749699180c2bcda95340a4b8809591e13 Mon Sep 17 00:00:00 2001 From: Nicolas Stepien Date: Thu, 24 Nov 2011 00:40:43 +0100 Subject: [PATCH 058/169] Use full pictures for sauce --- 4chan_x.user.js | 7 +++---- script.coffee | 5 ++--- 2 files changed, 5 insertions(+), 7 deletions(-) diff --git a/4chan_x.user.js b/4chan_x.user.js index ecf263333..1bbbdb7e6 100644 --- a/4chan_x.user.js +++ b/4chan_x.user.js @@ -2115,10 +2115,9 @@ return prefix.match(/(\w+)\./)[1]; }); return g.callbacks.push(function(root) { - var i, link, prefix, span, suffix, thumb, _len, _ref, _results; - if (root.className === 'inline' || !(thumb = $('img[md5]', root))) return; - span = $('.filesize', root); - suffix = thumb.src; + var i, link, prefix, span, suffix, _len, _ref, _results; + if (root.className === 'inline' || !(span = $('.filesize', root))) return; + suffix = $('a', span).href; _ref = sauce.prefixes; _results = []; for (i = 0, _len = _ref.length; i < _len; i++) { diff --git a/script.coffee b/script.coffee index c1692e92c..5557bdf04 100644 --- a/script.coffee +++ b/script.coffee @@ -1649,9 +1649,8 @@ sauce = sauce.prefixes = conf['flavors'].match /^[^#].+$/gm sauce.names = sauce.prefixes.map (prefix) -> prefix.match(/(\w+)\./)[1] g.callbacks.push (root) -> - return if root.className is 'inline' or not thumb = $ 'img[md5]', root - span = $ '.filesize', root - suffix = thumb.src + return if root.className is 'inline' or not span = $ '.filesize', root + suffix = $('a', span).href for prefix, i in sauce.prefixes link = $.el 'a', textContent: sauce.names[i] From a235657f7304cf9257775804fb28f14b0f692f25 Mon Sep 17 00:00:00 2001 From: Nicolas Stepien Date: Thu, 24 Nov 2011 00:41:32 +0100 Subject: [PATCH 059/169] >oh god how do I manage changelogs hurp durp --- changelog | 2 -- 1 file changed, 2 deletions(-) diff --git a/changelog b/changelog index caab61480..210e3c9be 100644 --- a/changelog +++ b/changelog @@ -5,9 +5,7 @@ master regular expressions based filter remove image preloading automatically reload expanded pictures on error - update archives redirections for /diy/, /pol/ and /sci/ handle bans with the thread updater - fix DST for two days of the year - aeosynth quick reply redesign From 4bad123c328c9a81dfdf56c8146e98a3c37cf9d3 Mon Sep 17 00:00:00 2001 From: Nicolas Stepien Date: Thu, 24 Nov 2011 00:47:04 +0100 Subject: [PATCH 060/169] Do not hide posts when inlining backlinks. --- 4chan_x.user.js | 16 +--------------- script.coffee | 13 ++----------- 2 files changed, 3 insertions(+), 26 deletions(-) diff --git a/4chan_x.user.js b/4chan_x.user.js index 1bbbdb7e6..a219b3475 100644 --- a/4chan_x.user.js +++ b/4chan_x.user.js @@ -2343,7 +2343,7 @@ quoteInline.rm(this, id); } else { if ($.x("ancestor::*[@id='" + id + "']", this)) return; - quoteInline.add(this, id); + $.rm = $.x("following::*[@id='i" + id + "']", this); } return this.classList.toggle('inlined'); }, @@ -2354,7 +2354,6 @@ inline = quoteInline.table(id, el.innerHTML); if (q.className === 'backlink') { $.after(q.parentNode, inline); - $.x('ancestor::table', el).hidden = true; return; } return $.after(root, inline); @@ -2372,19 +2371,6 @@ })); } }, - rm: function(q, id) { - var inlined, table, _i, _len, _ref; - table = $.x("following::*[@id='i" + id + "']", q); - _ref = $$('.backlink.inlined:not(.filtered)', table); - for (_i = 0, _len = _ref.length; _i < _len; _i++) { - inlined = _ref[_i]; - $.x('ancestor::table', $.id(inlined.hash.slice(1))).hidden = false; - } - if (/\bbacklink\b/.test(q.className) && !/\bfiltered\b/.test(q.className)) { - $.x('ancestor::table', $.id(id)).hidden = false; - } - return $.rm(table); - }, parse: function(req, pathname, id, threadID, inline) { var body, href, html, link, newInline, op, quote, reply, _i, _j, _len, _len2, _ref, _ref2; if (!inline.parentNode) return; diff --git a/script.coffee b/script.coffee index 5557bdf04..4a4eb8429 100644 --- a/script.coffee +++ b/script.coffee @@ -1807,7 +1807,8 @@ quoteInline = quoteInline.rm @, id else return if $.x("ancestor::*[@id='#{id}']", @) - quoteInline.add @, id + # remove the corresponding table or loading td + $.rm = $.x "following::*[@id='i#{id}']", @ @classList.toggle 'inlined' add: (q, id) -> @@ -1816,7 +1817,6 @@ quoteInline = inline = quoteInline.table id, el.innerHTML if q.className is 'backlink' $.after q.parentNode, inline - $.x('ancestor::table', el).hidden = true return $.after root, inline else @@ -1829,15 +1829,6 @@ quoteInline = threadID = pathname.split('/').pop() $.cache pathname, (-> quoteInline.parse @, pathname, id, threadID, inline) - rm: (q, id) -> - #select the corresponding table or loading td - table = $.x "following::*[@id='i#{id}']", q - for inlined in $$ '.backlink.inlined:not(.filtered)', table - $.x('ancestor::table', $.id inlined.hash[1..]).hidden = false - if /\bbacklink\b/.test(q.className) and not /\bfiltered\b/.test q.className - $.x('ancestor::table', $.id id).hidden = false - $.rm table - parse: (req, pathname, id, threadID, inline) -> return unless inline.parentNode From 2146358b19d0acbb6949b9637b1e3c85a79c5393 Mon Sep 17 00:00:00 2001 From: Nicolas Stepien Date: Thu, 24 Nov 2011 00:52:21 +0100 Subject: [PATCH 061/169] Parse values as decimals, 010 -> 10 not 8. --- 4chan_x.user.js | 2 +- script.coffee | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/4chan_x.user.js b/4chan_x.user.js index a219b3475..64746ad2a 100644 --- a/4chan_x.user.js +++ b/4chan_x.user.js @@ -1890,7 +1890,7 @@ } } else if (input.name === 'Interval') { $.on(input, 'change', function() { - return conf['Interval'] = this.value = parseInt(this.value) || conf['Interval']; + return conf['Interval'] = this.value = parseInt(this.value, 10) || conf['Interval']; }); $.on(input, 'change', $.cb.value); } else if (input.type === 'button') { diff --git a/script.coffee b/script.coffee index 4a4eb8429..f448c1567 100644 --- a/script.coffee +++ b/script.coffee @@ -1469,7 +1469,7 @@ updater = $.on input, 'click', updater.cb.autoUpdate updater.cb.autoUpdate.call input else if input.name is 'Interval' - $.on input, 'change', -> conf['Interval'] = @value = parseInt(@value) or conf['Interval'] + $.on input, 'change', -> conf['Interval'] = @value = parseInt(@value, 10) or conf['Interval'] $.on input, 'change', $.cb.value else if input.type is 'button' $.on input, 'click', updater.update From 5ab9577fd72874cac148933d635dbb57fd0c48e3 Mon Sep 17 00:00:00 2001 From: Nicolas Stepien Date: Thu, 24 Nov 2011 00:59:58 +0100 Subject: [PATCH 062/169] Remove some aerosmit signatures, remove donate link. --- 4chan_x.user.js | 11 +++++------ Cakefile | 4 ++-- script.coffee | 7 +++---- 3 files changed, 10 insertions(+), 12 deletions(-) diff --git a/4chan_x.user.js b/4chan_x.user.js index 64746ad2a..c991164e6 100644 --- a/4chan_x.user.js +++ b/4chan_x.user.js @@ -7,7 +7,7 @@ // @include http://boards.4chan.org/* // @include http://sys.4chan.org/* // @run-at document-start -// @icon https://raw.github.com/aeosynth/4chan-x/gh-pages/favicon.png +// @icon https://raw.github.com/mayhemydg/4chan-x/gh-pages/favicon.png // ==/UserScript== /* LICENSE @@ -41,7 +41,7 @@ * 4chan x is written in CoffeeScript[1], and developed on github[2]. * * [1]: http://jashkenas.github.com/coffee-script/ - * [2]: http://github.com/aeosynth/4chan-x + * [2]: http://github.com/mayhemydg/4chan-x */ /* CONTRIBUTORS @@ -202,7 +202,7 @@ } })(null, config); - NAMESPACE = 'AEOS.4chan_x.'; + NAMESPACE = '4chan_x.'; SECOND = 1000; @@ -1218,9 +1218,8 @@ dialog = ui.dialog('options', '', '\
    \
    \ - 4chan X\ - | Issues\ - | Donate\ + 4chan X\ + | Issues\
    \
    \ \ diff --git a/Cakefile b/Cakefile index e6c085f77..39b1b0117 100644 --- a/Cakefile +++ b/Cakefile @@ -12,7 +12,7 @@ HEADER = """ // @include http://boards.4chan.org/* // @include http://sys.4chan.org/* // @run-at document-start -// @icon https://raw.github.com/aeosynth/4chan-x/gh-pages/favicon.png +// @icon https://raw.github.com/mayhemydg/4chan-x/gh-pages/favicon.png // ==/UserScript== /* LICENSE @@ -46,7 +46,7 @@ HEADER = """ * 4chan x is written in CoffeeScript[1], and developed on github[2]. * * [1]: http://jashkenas.github.com/coffee-script/ - * [2]: http://github.com/aeosynth/4chan-x + * [2]: http://github.com/mayhemydg/4chan-x */ /* CONTRIBUTORS diff --git a/script.coffee b/script.coffee index f448c1567..2f479cc37 100644 --- a/script.coffee +++ b/script.coffee @@ -117,7 +117,7 @@ conf = {} conf[parent] = obj ) null, config -NAMESPACE = 'AEOS.4chan_x.' +NAMESPACE = '4chan_x.' SECOND = 1000 MINUTE = 60*SECOND HOUR = 60*MINUTE @@ -874,9 +874,8 @@ options = dialog = ui.dialog 'options', '', '
    - 4chan X - | Issues - | Donate + 4chan X + | Issues
    From ec06901b4966a7ae967b8b348707913d9d49203c Mon Sep 17 00:00:00 2001 From: Nicolas Stepien Date: Thu, 24 Nov 2011 01:02:25 +0100 Subject: [PATCH 063/169] Remove the readme off master --- readme.md | 17 ----------------- 1 file changed, 17 deletions(-) delete mode 100644 readme.md diff --git a/readme.md b/readme.md deleted file mode 100644 index 08fdbeec0..000000000 --- a/readme.md +++ /dev/null @@ -1,17 +0,0 @@ -# Installing - -[stable](https://github.com/aeosynth/4chan-x/raw/stable/4chan_x.user.js) - if you don't know what you're doing, choose this - -[master](https://github.com/aeosynth/4chan-x/raw/master/4chan_x.user.js) - main development branch, turns into stable. can change frequently, so don't complain if other projects don't support this branch. - -# Documentation - -http://aeosynth.github.com/4chan-x - -# Building - -[install nodejs and npm](https://github.com/joyent/node/wiki/Installation), -install [coffee-script](https://github.com/jashkenas/coffee-script/) with -`npm install -g coffee-script`, clone 4chan x, cd into it and actually build -with `cake build`. for development (continuous builds), run `cake dev &`. -kill the process with `killall node`. From 312f0bcd34f7c43b5a8052dafdc068592ba165f6 Mon Sep 17 00:00:00 2001 From: Nicolas Stepien Date: Thu, 24 Nov 2011 01:18:27 +0100 Subject: [PATCH 064/169] Fix mistake --- 4chan_x.user.js | 4 ++-- script.coffee | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/4chan_x.user.js b/4chan_x.user.js index c991164e6..64de47864 100644 --- a/4chan_x.user.js +++ b/4chan_x.user.js @@ -2339,10 +2339,10 @@ e.preventDefault(); id = this.hash.slice(1); if (/\binlined\b/.test(this.className)) { - quoteInline.rm(this, id); + $.rm = $.x("following::*[@id='i" + id + "']", this); } else { if ($.x("ancestor::*[@id='" + id + "']", this)) return; - $.rm = $.x("following::*[@id='i" + id + "']", this); + quoteInline.add(this, id); } return this.classList.toggle('inlined'); }, diff --git a/script.coffee b/script.coffee index 2f479cc37..ed4a4b731 100644 --- a/script.coffee +++ b/script.coffee @@ -1803,11 +1803,11 @@ quoteInline = e.preventDefault() id = @hash[1..] if /\binlined\b/.test @className - quoteInline.rm @, id - else - return if $.x("ancestor::*[@id='#{id}']", @) # remove the corresponding table or loading td $.rm = $.x "following::*[@id='i#{id}']", @ + else + return if $.x("ancestor::*[@id='#{id}']", @) + quoteInline.add @, id @classList.toggle 'inlined' add: (q, id) -> From 68459914c17367bd971b512d311d6d00be5ff1e3 Mon Sep 17 00:00:00 2001 From: Nicolas Stepien Date: Thu, 24 Nov 2011 01:20:10 +0100 Subject: [PATCH 065/169] God damn. --- 4chan_x.user.js | 2 +- script.coffee | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/4chan_x.user.js b/4chan_x.user.js index 64de47864..c4de5ca96 100644 --- a/4chan_x.user.js +++ b/4chan_x.user.js @@ -2339,7 +2339,7 @@ e.preventDefault(); id = this.hash.slice(1); if (/\binlined\b/.test(this.className)) { - $.rm = $.x("following::*[@id='i" + id + "']", this); + $.rm($.x("following::*[@id='i" + id + "']", this)); } else { if ($.x("ancestor::*[@id='" + id + "']", this)) return; quoteInline.add(this, id); diff --git a/script.coffee b/script.coffee index ed4a4b731..23afbae8a 100644 --- a/script.coffee +++ b/script.coffee @@ -1804,7 +1804,7 @@ quoteInline = id = @hash[1..] if /\binlined\b/.test @className # remove the corresponding table or loading td - $.rm = $.x "following::*[@id='i#{id}']", @ + $.rm $.x "following::*[@id='i#{id}']", @ else return if $.x("ancestor::*[@id='#{id}']", @) quoteInline.add @, id From f40d40a7d6656cdc498bedb0011080d72dc12ea7 Mon Sep 17 00:00:00 2001 From: Nicolas Stepien Date: Thu, 24 Nov 2011 01:22:22 +0100 Subject: [PATCH 066/169] Remove the firstRun dialog. --- 4chan_x.user.js | 31 ++----------------- script.coffee | 81 ------------------------------------------------- 2 files changed, 2 insertions(+), 110 deletions(-) diff --git a/4chan_x.user.js b/4chan_x.user.js index c4de5ca96..7b99c6da9 100644 --- a/4chan_x.user.js +++ b/4chan_x.user.js @@ -62,7 +62,7 @@ */ (function() { - var $, $$, DAY, Favicon, HOUR, MINUTE, Main, NAMESPACE, QR, SECOND, Time, anonymize, conf, config, d, expandComment, expandThread, filter, firstRun, flatten, g, getTitle, imgExpand, imgGif, imgHover, key, keybinds, log, nav, options, quoteBacklink, quoteInline, quoteOP, quotePreview, redirect, replyHiding, reportButton, revealSpoilers, sauce, strikethroughQuotes, 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, filter, flatten, g, getTitle, imgExpand, imgGif, imgHover, key, keybinds, log, nav, options, quoteBacklink, quoteInline, quoteOP, quotePreview, redirect, replyHiding, reportButton, revealSpoilers, sauce, strikethroughQuotes, threadHiding, threadStats, threading, titlePost, ui, unread, updater, val, watcher; var __slice = Array.prototype.slice; config = { @@ -2848,32 +2848,6 @@ } }; - firstRun = { - init: function() { - var dialog, style; - style = $.addStyle(" #navtopr, #navbotr { position: relative; } #navtopr::before { content: ''; height: 50px; width: 100px; background: red; -webkit-transform: rotate(-45deg); -moz-transform: rotate(-45deg); -o-transform: rotate(-45deg); -webkit-transform-origin: 100% 200%; -moz-transform-origin: 100% 200%; -o-transform-origin: 100% 200%; position: absolute; top: 100%; right: 100%; z-index: 999; } #navtopr::after { content: ''; border-top: 100px solid red; border-left: 100px solid transparent; position: absolute; top: 100%; right: 100%; z-index: 999; } #navbotr::before { content: ''; height: 50px; width: 100px; background: red; -webkit-transform: rotate(45deg); -moz-transform: rotate(45deg); -o-transform: rotate(45deg); -webkit-transform-origin: 100% -100%; -moz-transform-origin: 100% -100%; -o-transform-origin: 100% -100%; position: absolute; bottom: 100%; right: 100%; z-index: 999; } #navbotr::after { content: ''; border-bottom: 100px solid red; border-left: 100px solid transparent; position: absolute; bottom: 100%; right: 100%; z-index: 999; } "); - style.className = 'firstrun'; - dialog = $.el('div', { - id: 'overlay', - className: 'firstrun', - innerHTML: '\ -
    \ -

    Click the 4chan X buttons for options; they are at the top and bottom of the page.

    \ -

    Updater options are in the updater dialog in replies at the bottom-right corner of the window.

    \ -

    If you don\'t see the buttons, try disabling your userstyles.

    \ -
    ' - }); - $.add(d.body, dialog); - return $.on(window, 'click', firstRun.close); - }, - close: function() { - $.set('firstrun', true); - $.rm($('style.firstrun', d.head)); - $.rm($('#overlay')); - return $.off(window, 'click', firstRun.close); - } - }; - Main = { init: function() { var cutoff, hiddenThreads, id, lastChecked, now, pathname, temp, timestamp, _ref; @@ -2970,8 +2944,7 @@ } }); $.on($('form[name=delform]'), 'DOMNodeInserted', Main.node); - options.init(); - if (!$.get('firstrun')) return firstRun.init(); + return options.init(); }, message: function(e) { var data, origin; diff --git a/script.coffee b/script.coffee index 23afbae8a..4c7313276 100644 --- a/script.coffee +++ b/script.coffee @@ -2159,84 +2159,6 @@ imgExpand = resize: -> imgExpand.style.innerHTML = ".fitheight img + img {max-height:#{d.body.clientHeight}px;}" -firstRun = - init: -> - style = $.addStyle " - #navtopr, #navbotr { - position: relative; - } - #navtopr::before { - content: ''; - height: 50px; - width: 100px; - background: red; - -webkit-transform: rotate(-45deg); - -moz-transform: rotate(-45deg); - -o-transform: rotate(-45deg); - -webkit-transform-origin: 100% 200%; - -moz-transform-origin: 100% 200%; - -o-transform-origin: 100% 200%; - position: absolute; - top: 100%; - right: 100%; - z-index: 999; - } - #navtopr::after { - content: ''; - border-top: 100px solid red; - border-left: 100px solid transparent; - position: absolute; - top: 100%; - right: 100%; - z-index: 999; - } - #navbotr::before { - content: ''; - height: 50px; - width: 100px; - background: red; - -webkit-transform: rotate(45deg); - -moz-transform: rotate(45deg); - -o-transform: rotate(45deg); - -webkit-transform-origin: 100% -100%; - -moz-transform-origin: 100% -100%; - -o-transform-origin: 100% -100%; - position: absolute; - bottom: 100%; - right: 100%; - z-index: 999; - } - #navbotr::after { - content: ''; - border-bottom: 100px solid red; - border-left: 100px solid transparent; - position: absolute; - bottom: 100%; - right: 100%; - z-index: 999; - } - " - style.className = 'firstrun' - - dialog = $.el 'div', - id: 'overlay' - className: 'firstrun' - innerHTML: ' -
    -

    Click the 4chan X buttons for options; they are at the top and bottom of the page.

    -

    Updater options are in the updater dialog in replies at the bottom-right corner of the window.

    -

    If you don\'t see the buttons, try disabling your userstyles.

    -
    ' - $.add d.body, dialog - - $.on window, 'click', firstRun.close - - close: -> - $.set 'firstrun', true - $.rm $ 'style.firstrun', d.head - $.rm $ '#overlay' - $.off window, 'click', firstRun.close - Main = init: -> if location.hostname is 'sys.4chan.org' @@ -2393,9 +2315,6 @@ Main = $.on $('form[name=delform]'), 'DOMNodeInserted', Main.node options.init() - unless $.get 'firstrun' - firstRun.init() - message: (e) -> {origin, data} = e if origin is 'http://sys.4chan.org' From 357c6155d6a020fdeb4d96673c37c936aee656b0 Mon Sep 17 00:00:00 2001 From: Nicolas Stepien Date: Thu, 24 Nov 2011 01:43:21 +0100 Subject: [PATCH 067/169] forEach is actually slow. --- 4chan_x.user.js | 27 ++++++++++++++++++--------- script.coffee | 7 ++++--- 2 files changed, 22 insertions(+), 12 deletions(-) diff --git a/4chan_x.user.js b/4chan_x.user.js index 7b99c6da9..24bfb93c4 100644 --- a/4chan_x.user.js +++ b/4chan_x.user.js @@ -2908,7 +2908,7 @@ } }, onLoad: function() { - var nodes; + var callback, node, nodes, _i, _j, _len, _len2, _ref; $.off(d, 'DOMContentLoaded', Main.onLoad); if (conf['404 Redirect'] && d.title === '4chan - 404' && /^\d+$/.test(g.THREAD_ID)) { redirect(); @@ -2936,13 +2936,18 @@ if (conf['Index Navigation']) nav.init(); } nodes = $$('.op, a + table'); - g.callbacks.forEach(function(callback) { + _ref = g.callbacks; + for (_i = 0, _len = _ref.length; _i < _len; _i++) { + callback = _ref[_i]; try { - return nodes.forEach(callback); + for (_j = 0, _len2 = nodes.length; _j < _len2; _j++) { + node = nodes[_j]; + callback(node); + } } catch (err) { - return alert(err); + alert(err); } - }); + } $.on($('form[name=delform]'), 'DOMNodeInserted', Main.node); return options.init(); }, @@ -2952,16 +2957,20 @@ if (origin === 'http://sys.4chan.org') return QR.receive(data); }, node: function(e) { - var target; + var callback, target, _i, _len, _ref, _results; target = e.target; if (target.nodeName !== 'TABLE') return; - return g.callbacks.forEach(function(callback) { + _ref = g.callbacks; + _results = []; + for (_i = 0, _len = _ref.length; _i < _len; _i++) { + callback = _ref[_i]; try { - return callback(target); + _results.push(callback(target)); } catch (err) { } - }); + } + return _results; }, css: '\ /* dialog styling */\ diff --git a/script.coffee b/script.coffee index 4c7313276..37b093f6a 100644 --- a/script.coffee +++ b/script.coffee @@ -2307,9 +2307,10 @@ Main = nodes = $$ '.op, a + table' - g.callbacks.forEach (callback) -> + for callback in g.callbacks try - nodes.forEach callback + for node in nodes + callback node catch err alert err $.on $('form[name=delform]'), 'DOMNodeInserted', Main.node @@ -2323,7 +2324,7 @@ Main = node: (e) -> {target} = e return unless target.nodeName is 'TABLE' - g.callbacks.forEach (callback) -> + for callback in g.callbacks try callback target catch err From 063d88d4a43abf024aedd9639682cc852166291f Mon Sep 17 00:00:00 2001 From: Nicolas Stepien Date: Thu, 24 Nov 2011 04:18:51 +0100 Subject: [PATCH 068/169] Add 3D iqdb. --- 4chan_x.user.js | 2 +- script.coffee | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/4chan_x.user.js b/4chan_x.user.js index 24bfb93c4..6086007d7 100644 --- a/4chan_x.user.js +++ b/4chan_x.user.js @@ -126,7 +126,7 @@ file: '', md5: '' }, - flavors: ['http://iqdb.org/?url=', 'http://google.com/searchbyimage?image_url=', '#http://tineye.com/search?url=', '#http://saucenao.com/search.php?db=999&url=', '#http://imgur.com/upload?url='].join('\n'), + flavors: ['http://iqdb.org/?url=', 'http://google.com/searchbyimage?image_url=', '#http://tineye.com/search?url=', '#http://saucenao.com/search.php?db=999&url=', '#http://3d.iqdb.org/?url=', '#http://imgur.com/upload?url='].join('\n'), time: '%m/%d/%y(%a)%H:%M', backlink: '>>%id', hotkeys: { diff --git a/script.coffee b/script.coffee index 37b093f6a..7865745be 100644 --- a/script.coffee +++ b/script.coffee @@ -56,6 +56,7 @@ config = 'http://google.com/searchbyimage?image_url=' '#http://tineye.com/search?url=' '#http://saucenao.com/search.php?db=999&url=' + '#http://3d.iqdb.org/?url=' '#http://imgur.com/upload?url=' ].join '\n' time: '%m/%d/%y(%a)%H:%M' From 4d1eb4db32e0e68cd0bf5e5449f15f983c2e1116 Mon Sep 17 00:00:00 2001 From: Shou Date: Thu, 24 Nov 2011 22:16:28 +0100 Subject: [PATCH 069/169] Add href attributes to elements to play nicer with Pentadactyl. --- 4chan_x.user.js | 33 ++++++++++++++++++++++----------- script.coffee | 11 +++++++++++ 2 files changed, 33 insertions(+), 11 deletions(-) diff --git a/4chan_x.user.js b/4chan_x.user.js index 6086007d7..4e8f7e38b 100644 --- a/4chan_x.user.js +++ b/4chan_x.user.js @@ -686,7 +686,8 @@ span = _ref[_i]; a = $.el('a', { textContent: "+ " + span.textContent, - className: 'omittedposts' + className: 'omittedposts', + href: 'javascript:;' }); $.on(a, 'click', expandThread.cb.toggle); _results.push($.replace(span, a)); @@ -793,7 +794,8 @@ if (!(dd = $('.doubledash', root))) return; dd.className = 'replyhider'; a = $.el('a', { - textContent: '[ - ]' + textContent: '[ - ]', + href: 'javascript:;' }); $.on(a, 'click', replyHiding.cb.hide); $.replace(dd.firstChild, a); @@ -836,7 +838,8 @@ name = $('.commentpostername', reply).textContent; trip = ((_ref = $('.postertrip', reply)) != null ? _ref.textContent : void 0) || ''; a = $.el('a', { - textContent: "[ + ] " + name + " " + trip + textContent: "[ + ] " + name + " " + trip, + href: 'javascript:;' }); $.on(a, 'click', replyHiding.cb.show); div = $.el('div', { @@ -1129,10 +1132,12 @@ id: 'navlinks' }); prev = $.el('a', { - textContent: 'â–²' + textContent: 'â–²', + href: 'javascript:;' }); next = $.el('a', { - textContent: 'â–¼' + textContent: 'â–¼', + href: 'javascript:;' }); $.on(prev, 'click', nav.prev); $.on(next, 'click', nav.next); @@ -1202,13 +1207,15 @@ var a, home; home = $('#navtopr a'); a = $.el('a', { - textContent: '4chan X' + textContent: '4chan X', + href: 'javascript:;' }); $.on(a, 'click', options.dialog); $.replace(home, a); home = $('#navbotr a'); a = $.el('a', { - textContent: '4chan X' + textContent: '4chan X', + href: 'javascript:;' }); $.on(a, 'click', options.dialog); return $.replace(home, a); @@ -1764,7 +1771,8 @@ thread = _ref[_i]; op = thread.firstChild; a = $.el('a', { - textContent: '[ - ]' + textContent: '[ - ]', + href: 'javascript:;' }); $.on(a, 'click', threadHiding.cb.hide); $.prepend(op, a); @@ -1816,7 +1824,8 @@ name = $('.postername', thread).textContent; trip = ((_ref = $('.postername + .postertrip', thread)) != null ? _ref.textContent : void 0) || ''; a = $.el('a', { - textContent: "[ + ] " + name + trip + " (" + text + ")" + textContent: "[ + ] " + name + trip + " (" + text + ")", + href: 'javascript:;' }); $.on(a, 'click', threadHiding.cb.show); div = $.el('div', { @@ -2027,7 +2036,8 @@ props = _ref2[id]; div = $.el('div'); x = $.el('a', { - textContent: 'X' + textContent: 'X', + href: 'javascript:;' }); $.on(x, 'click', watcher.cb.x); link = $.el('a', props); @@ -2530,7 +2540,8 @@ span = $('span[id]', root); a = $.el('a', { className: 'reportbutton', - innerHTML: '[ ! ]' + innerHTML: '[ ! ]', + href: 'javascript:;' }); $.after(span, a); $.after(span, $.tn(' ')); diff --git a/script.coffee b/script.coffee index 7865745be..fe1629a0a 100644 --- a/script.coffee +++ b/script.coffee @@ -488,6 +488,7 @@ expandThread = a = $.el 'a', textContent: "+ #{span.textContent}" className: 'omittedposts' + href: 'javascript:;' $.on a, 'click', expandThread.cb.toggle $.replace span, a @@ -563,6 +564,7 @@ replyHiding = dd.className = 'replyhider' a = $.el 'a', textContent: '[ - ]' + href: 'javascript:;' $.on a, 'click', replyHiding.cb.hide $.replace dd.firstChild, a @@ -602,6 +604,7 @@ replyHiding = trip = $('.postertrip', reply)?.textContent or '' a = $.el 'a', textContent: "[ + ] #{name} #{trip}" + href: 'javascript:;' $.on a, 'click', replyHiding.cb.show div = $.el 'div', @@ -795,8 +798,10 @@ nav = id: 'navlinks' prev = $.el 'a', textContent: 'â–²' + href: 'javascript:;' next = $.el 'a', textContent: 'â–¼' + href: 'javascript:;' $.on prev, 'click', nav.prev $.on next, 'click', nav.next @@ -863,11 +868,13 @@ options = home = $ '#navtopr a' a = $.el 'a', textContent: '4chan X' + href: 'javascript:;' $.on a, 'click', options.dialog $.replace home, a home = $ '#navbotr a' a = $.el 'a', textContent: '4chan X' + href: 'javascript:;' $.on a, 'click', options.dialog $.replace home, a @@ -1363,6 +1370,7 @@ threadHiding = op = thread.firstChild a = $.el 'a', textContent: '[ - ]' + href: 'javascript:;' $.on a, 'click', threadHiding.cb.hide $.prepend op, a @@ -1405,6 +1413,7 @@ threadHiding = a = $.el 'a', textContent: "[ + ] #{name}#{trip} (#{text})" + href: 'javascript:;' $.on a, 'click', threadHiding.cb.show div = $.el 'div', @@ -1586,6 +1595,7 @@ watcher = div = $.el 'div' x = $.el 'a', textContent: 'X' + href: 'javascript:;' $.on x, 'click', watcher.cb.x link = $.el 'a', props @@ -1931,6 +1941,7 @@ reportButton = a = $.el 'a', className: 'reportbutton' innerHTML: '[ ! ]' + href: 'javascript:;' $.after span, a $.after span, $.tn(' ') $.on a, 'click', reportButton.report From c0294019b76029476a3b579f7179b1a941726ade Mon Sep 17 00:00:00 2001 From: Nicolas Stepien Date: Fri, 25 Nov 2011 22:16:18 +0100 Subject: [PATCH 070/169] Do not waste bandwidth loading pictures of filtered posts. --- 4chan_x.user.js | 6 +++--- script.coffee | 7 ++++--- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/4chan_x.user.js b/4chan_x.user.js index 6086007d7..7bd456da4 100644 --- a/4chan_x.user.js +++ b/4chan_x.user.js @@ -2700,7 +2700,7 @@ init: function() { return g.callbacks.push(function(root) { var src, thumb; - if (!(thumb = $('img[md5]', root))) return; + if (root.hidden || !(thumb = $('img[md5]', root))) return; src = thumb.parentNode.href; if (/gif$/.test(src)) return thumb.src = src; }); @@ -2717,7 +2717,7 @@ if (!(thumb = $('img[md5]', root))) return; a = thumb.parentNode; $.on(a, 'click', imgExpand.cb.toggle); - if (imgExpand.on && root.className !== 'inline') { + if (imgExpand.on && !root.hidden && root.className !== 'inline') { return imgExpand.expand(a.firstChild); } }, @@ -2731,7 +2731,7 @@ var thumb, _i, _j, _len, _len2, _ref, _ref2, _results, _results2; imgExpand.on = this.checked; if (imgExpand.on) { - _ref = $$('img[md5]:not([hidden])'); + _ref = $$('.op > a > img[md5]:last-child, table:not([hidden]) img[md5]:last-child'); _results = []; for (_i = 0, _len = _ref.length; _i < _len; _i++) { thumb = _ref[_i]; diff --git a/script.coffee b/script.coffee index 7865745be..3b6373b1b 100644 --- a/script.coffee +++ b/script.coffee @@ -2054,7 +2054,7 @@ imgHover = imgGif = init: -> g.callbacks.push (root) -> - return unless thumb = $ 'img[md5]', root + return if root.hidden or !thumb = $ 'img[md5]', root src = thumb.parentNode.href if /gif$/.test src thumb.src = src @@ -2068,7 +2068,8 @@ imgExpand = return unless thumb = $ 'img[md5]', root a = thumb.parentNode $.on a, 'click', imgExpand.cb.toggle - if imgExpand.on and root.className isnt 'inline' then imgExpand.expand a.firstChild + if imgExpand.on and !root.hidden and root.className isnt 'inline' + imgExpand.expand a.firstChild cb: toggle: (e) -> return if e.shiftKey or e.altKey or e.ctrlKey or e.button isnt 0 @@ -2077,7 +2078,7 @@ imgExpand = all: -> imgExpand.on = @checked if imgExpand.on #expand - for thumb in $$ 'img[md5]:not([hidden])' + for thumb in $$ '.op > a > img[md5]:last-child, table:not([hidden]) img[md5]:last-child' imgExpand.expand thumb else #contract for thumb in $$ 'img[md5][hidden]' From 728473bded8af3e3250b5b817f6d2180d2b06bc8 Mon Sep 17 00:00:00 2001 From: Nicolas Stepien Date: Fri, 25 Nov 2011 22:26:39 +0100 Subject: [PATCH 071/169] Add filesize filtering; more descriptive names. --- script.coffee | 49 +++++++++++++++++++++++++++---------------------- 1 file changed, 27 insertions(+), 22 deletions(-) diff --git a/script.coffee b/script.coffee index 2c4a33883..67ed32f4f 100644 --- a/script.coffee +++ b/script.coffee @@ -44,13 +44,14 @@ config = 'Quote Preview': [true, 'Show quote content on hover'] 'Indicate OP quote': [true, 'Add \'(OP)\' to OP quotes'] filter: - name: '' - trip: '' - mail: '' - sub: '' - com: '' - file: '' - md5: '' + name: '' + tripcode: '' + email: '' + subject: '' + comment: '' + filename: '' + filesize: '' + md5: '' flavors: [ 'http://iqdb.org/?url=' 'http://google.com/searchbyimage?image_url=' @@ -414,20 +415,23 @@ filter = name: (root) -> name = if root.className is 'op' then $ '.postername', root else $ '.commentpostername', root filter.test 'name', name.textContent - trip: (root) -> + tripcode: (root) -> if trip = $ '.postertrip', root - filter.test 'trip', trip.textContent - mail: (root) -> + filter.test 'tripcode', trip.textContent + email: (root) -> if mail = $ '.linkmail', root - filter.test 'mail', mail.href - sub: (root) -> + filter.test 'email', mail.href + subject: (root) -> sub = if root.className is 'op' then $ '.filetitle', root else $ '.replytitle', root - filter.test 'sub', sub.textContent - com: (root) -> - filter.test 'com', ($.el 'a', innerHTML: $('blockquote', root).innerHTML.replace /
    /g, '\n').textContent - file: (root) -> + filter.test 'subject', sub.textContent + comment: (root) -> + filter.test 'comment', ($.el 'a', innerHTML: $('blockquote', root).innerHTML.replace /
    /g, '\n').textContent + filename: (root) -> if file = $ '.filesize span', root - filter.test 'file', file.title + filter.test 'filename', file.title + filesize: (root) -> + if img = $ 'img[md5]', root + filter.test 'filesize', img.alt md5: (root) -> if img = $ 'img[md5]', root filter.test 'md5', img.getAttribute('md5') @@ -904,11 +908,12 @@ options = Use
    regular expressions, one per line.
    For example, /weeaboo/i will filter posts containing `weeaboo` case-insensitive.

    Name:

    -

    Tripcode:

    -

    E-mail:

    -

    Subject:

    -

    Comment:

    -

    Filename:

    +

    Tripcode:

    +

    E-mail:

    +

    Subject:

    +

    Comment:

    +

    Filename:

    +

    Filename:

    Image MD5:

    From 3df0c77b1bbfac291aed686a00957106cb6584a9 Mon Sep 17 00:00:00 2001 From: Nicolas Stepien Date: Fri, 25 Nov 2011 22:27:04 +0100 Subject: [PATCH 072/169] Compile. --- 4chan_x.user.js | 48 ++++++++++++++++++++++++++++-------------------- 1 file changed, 28 insertions(+), 20 deletions(-) diff --git a/4chan_x.user.js b/4chan_x.user.js index e1c68b9a2..424e74092 100644 --- a/4chan_x.user.js +++ b/4chan_x.user.js @@ -119,11 +119,12 @@ }, filter: { name: '', - trip: '', - mail: '', - sub: '', - com: '', - file: '', + tripcode: '', + email: '', + subject: '', + comment: '', + filename: '', + filesize: '', md5: '' }, flavors: ['http://iqdb.org/?url=', 'http://google.com/searchbyimage?image_url=', '#http://tineye.com/search?url=', '#http://saucenao.com/search.php?db=999&url=', '#http://3d.iqdb.org/?url=', '#http://imgur.com/upload?url='].join('\n'), @@ -560,29 +561,35 @@ name = root.className === 'op' ? $('.postername', root) : $('.commentpostername', root); return filter.test('name', name.textContent); }, - trip: function(root) { + tripcode: function(root) { var trip; if (trip = $('.postertrip', root)) { - return filter.test('trip', trip.textContent); + return filter.test('tripcode', trip.textContent); } }, - mail: function(root) { + email: function(root) { var mail; - if (mail = $('.linkmail', root)) return filter.test('mail', mail.href); + if (mail = $('.linkmail', root)) return filter.test('email', mail.href); }, - sub: function(root) { + subject: function(root) { var sub; sub = root.className === 'op' ? $('.filetitle', root) : $('.replytitle', root); - return filter.test('sub', sub.textContent); + return filter.test('subject', sub.textContent); }, - com: function(root) { - return filter.test('com', ($.el('a', { + comment: function(root) { + return filter.test('comment', ($.el('a', { innerHTML: $('blockquote', root).innerHTML.replace(/
    /g, '\n') })).textContent); }, - file: function(root) { + filename: function(root) { var file; - if (file = $('.filesize span', root)) return filter.test('file', file.title); + if (file = $('.filesize span', root)) { + return filter.test('filename', file.title); + } + }, + filesize: function(root) { + var img; + if (img = $('img[md5]', root)) return filter.test('filesize', img.alt); }, md5: function(root) { var img; @@ -1247,11 +1254,12 @@ Use regular expressions, one per line.
    \ For example, /weeaboo/i will filter posts containing `weeaboo` case-insensitive.\

    Name:

    \ -

    Tripcode:

    \ -

    E-mail:

    \ -

    Subject:

    \ -

    Comment:

    \ -

    Filename:

    \ +

    Tripcode:

    \ +

    E-mail:

    \ +

    Subject:

    \ +

    Comment:

    \ +

    Filename:

    \ +

    Filename:

    \

    Image MD5:

    \
    \ \ From c65351d5ed547c054b208b79aea38a03cabdf167 Mon Sep 17 00:00:00 2001 From: Nicolas Stepien Date: Fri, 25 Nov 2011 22:28:13 +0100 Subject: [PATCH 073/169] Typo. --- 4chan_x.user.js | 2 +- script.coffee | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/4chan_x.user.js b/4chan_x.user.js index 424e74092..c581ee683 100644 --- a/4chan_x.user.js +++ b/4chan_x.user.js @@ -1259,7 +1259,7 @@

    Subject:

    \

    Comment:

    \

    Filename:

    \ -

    Filename:

    \ +

    Filesize:

    \

    Image MD5:

    \
    \ \ diff --git a/script.coffee b/script.coffee index 67ed32f4f..7208c8b85 100644 --- a/script.coffee +++ b/script.coffee @@ -913,7 +913,7 @@ options =

    Subject:

    Comment:

    Filename:

    -

    Filename:

    +

    Filesize:

    Image MD5:

    From 9cbc77a30bdef6f99f7db95b3c9508c123622a0a Mon Sep 17 00:00:00 2001 From: Nicolas Stepien Date: Fri, 25 Nov 2011 23:30:33 +0100 Subject: [PATCH 074/169] Use ferongr's favicons. --- 4chan_x.user.js | 8 ++++---- changelog | 1 + script.coffee | 8 ++++---- 3 files changed, 9 insertions(+), 8 deletions(-) diff --git a/4chan_x.user.js b/4chan_x.user.js index c581ee683..347b418d6 100644 --- a/4chan_x.user.js +++ b/4chan_x.user.js @@ -2633,11 +2633,11 @@ Favicon["default"] = href; return Favicon.unread = /ws/.test(href) ? Favicon.unreadSFW : Favicon.unreadNSFW; }, - dead: 'data:image/gif;base64,R0lGODlhEAAQAKECAAAAAP8AAP///////yH5BAEKAAIALAAAAAAQABAAAAIvlI+pq+D9DAgUoFkPDlbs7lFZKIJOJJ3MyraoB14jFpOcVMpzrnF3OKlZYsMWowAAOw==', empty: 'data:image/gif;base64,R0lGODlhEAAQAJEAAAAAAP///9vb2////yH5BAEAAAMALAAAAAAQABAAAAIvnI+pq+D9DBAUoFkPFnbs7lFZKIJOJJ3MyraoB14jFpOcVMpzrnF3OKlZYsMWowAAOw==', - unreadDead: 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAANhJREFUOMutU0EKwjAQzEPFgyBFei209gOKINh6tL3qO3yAB9OHWPTeMZsmJaRpiNjAkE1mMt1stgwA+wdsFgM1oHE4FXmSpWUcRzWBYtozNfKAYdCHCrQuosX9tlk+CBS7NKMMbMF7vXoJtC7Om8HwhXzbCWCSn6qBJHd74FIBVS1jm7czYFSsq7gvpY0s6+ThJwc4743EHnGkIW2YAW+AphkMPj6DJE1LXW3fFUhD2pHBsTznLKCIFCstC3nGNvQZnQa6kX4yMGfdyi7OZaB7wZy93Cx/4xfgv/s+XYFMrAAAAABJRU5ErkJggg%3D%3D', - unreadSFW: 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAN9JREFUOMtj+P//PwMlmIEqBkDBfxie2NdVVVFaMikzPXsuCIPYIDFkNWANSAb815t+GI5B/Jj8iQfjapafBWEQG5saDBegK0ja8Ok9EH/AJofXBTBFlUf+/wPi/7jkcYYBCLef/v9/9pX//+cAMYiNLo/uAgZQYMVVLzsLcnYF0GaQ5otv/v+/9BpiEEgMJAdSA1JLlAGXgAZcfoNswGfcBpQDowoW2vi8AFIDUothwOQJvVXIgYUrEEFsqFoGYqLxA7HRiNUAWEIiyQBkGpaUsclhMwCWFpBpvHJUyY0AmdYZKFRtAsoAAAAASUVORK5CYII%3D', - unreadNSFW: 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAOBJREFUOMtj+P//PwMlmIEqBkDBfxie2DWxqqykYlJ6dtZcEAaxQWLIasAakAz4n3bGGI5B/JiJ8QfjlsefBWEQG5saDBegKyj5lPQeiD9gk8PrApiinv+V/4D4Py55nGEAwrP+t/9f/X82EM8Bs9Hl0V3AAAqsuGXxZ0HO7vlf8Q+k+eb/i0B8CWwQSAwkB1IDUkuUAbeAmm/9v4ww4DMeA8pKyifBQhufF0BqQGoxDJjcO7kKObBwBSKIDVXLQEw0fiA2GrEaAEtIJBmATMOSMjY5bAbA0gIyjVeOKrkRAMefDK/b7ecEAAAAAElFTkSuQmCC', + dead: 'data:image/gif;base64,R0lGODlhEAAQAKECAAAAAP8AAP///////yH5BAEKAAIALAAAAAAQABAAAAIvlI+pq+D9DAgUoFkPDlbs7lFZKIJOJJ3MyraoB14jFpOcVMpzrnF3OKlZYsMWowAAOw==', + unreadDead: 'data:image/png;base64,R0lGODlhEAAQAOMHAOgLAnMFAL8AAOgLAukMA/+AgP+rq////////////////////////////////////yH5BAEKAAcALAAAAAAQABAAAARZ8MhJ6xwDWIBv+AM1fEEIBIVRlNKYrtpIECuGzuwpCLg974EYiXUYkUItjGbC6VQ4omXFiKROA6qSy0A8nAo9GS3YCswIWnOvLAi0be23Z1QtdSUaqXcviQAAOw==', + unreadSFW: 'data:image/png;base64,R0lGODlhEAAQAOMHAADX8QBwfgC2zADX8QDY8nnl8qLp8v///////////////////////////////////yH5BAEKAAcALAAAAAAQABAAAARZ8MhJ6xwDWIBv+AM1fEEIBIVRlNKYrtpIECuGzuwpCLg974EYiXUYkUItjGbC6VQ4omXFiKROA6qSy0A8nAo9GS3YCswIWnOvLAi0be23Z1QtdSUaqXcviQAAOw==', + unreadNSFW: 'data:image/png;base64,R0lGODlhEAAQAOMHAFT+ACh5AEncAFT+AFX/Acz/su7/5v///////////////////////////////////yH5BAEKAAcALAAAAAAQABAAAARZ8MhJ6xwDWIBv+AM1fEEIBIVRlNKYrtpIECuGzuwpCLg974EYiXUYkUItjGbC6VQ4omXFiKROA6qSy0A8nAo9GS3YCswIWnOvLAi0be23Z1QtdSUaqXcviQAAOw==', update: function() { var clone, favicon, l; l = unread.replies.length; diff --git a/changelog b/changelog index 210e3c9be..5e4949c76 100644 --- a/changelog +++ b/changelog @@ -6,6 +6,7 @@ master remove image preloading automatically reload expanded pictures on error handle bans with the thread updater + use unread favicons by ferongr - aeosynth quick reply redesign diff --git a/script.coffee b/script.coffee index 7208c8b85..6be12598b 100644 --- a/script.coffee +++ b/script.coffee @@ -2014,11 +2014,11 @@ Favicon = Favicon.default = href Favicon.unread = if /ws/.test href then Favicon.unreadSFW else Favicon.unreadNSFW - dead: 'data:image/gif;base64,R0lGODlhEAAQAKECAAAAAP8AAP///////yH5BAEKAAIALAAAAAAQABAAAAIvlI+pq+D9DAgUoFkPDlbs7lFZKIJOJJ3MyraoB14jFpOcVMpzrnF3OKlZYsMWowAAOw==' empty: 'data:image/gif;base64,R0lGODlhEAAQAJEAAAAAAP///9vb2////yH5BAEAAAMALAAAAAAQABAAAAIvnI+pq+D9DBAUoFkPFnbs7lFZKIJOJJ3MyraoB14jFpOcVMpzrnF3OKlZYsMWowAAOw==' - unreadDead: 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAANhJREFUOMutU0EKwjAQzEPFgyBFei209gOKINh6tL3qO3yAB9OHWPTeMZsmJaRpiNjAkE1mMt1stgwA+wdsFgM1oHE4FXmSpWUcRzWBYtozNfKAYdCHCrQuosX9tlk+CBS7NKMMbMF7vXoJtC7Om8HwhXzbCWCSn6qBJHd74FIBVS1jm7czYFSsq7gvpY0s6+ThJwc4743EHnGkIW2YAW+AphkMPj6DJE1LXW3fFUhD2pHBsTznLKCIFCstC3nGNvQZnQa6kX4yMGfdyi7OZaB7wZy93Cx/4xfgv/s+XYFMrAAAAABJRU5ErkJggg%3D%3D' - unreadSFW: 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAN9JREFUOMtj+P//PwMlmIEqBkDBfxie2NdVVVFaMikzPXsuCIPYIDFkNWANSAb815t+GI5B/Jj8iQfjapafBWEQG5saDBegK0ja8Ok9EH/AJofXBTBFlUf+/wPi/7jkcYYBCLef/v9/9pX//+cAMYiNLo/uAgZQYMVVLzsLcnYF0GaQ5otv/v+/9BpiEEgMJAdSA1JLlAGXgAZcfoNswGfcBpQDowoW2vi8AFIDUothwOQJvVXIgYUrEEFsqFoGYqLxA7HRiNUAWEIiyQBkGpaUsclhMwCWFpBpvHJUyY0AmdYZKFRtAsoAAAAASUVORK5CYII%3D' - unreadNSFW: 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAOBJREFUOMtj+P//PwMlmIEqBkDBfxie2DWxqqykYlJ6dtZcEAaxQWLIasAakAz4n3bGGI5B/JiJ8QfjlsefBWEQG5saDBegKyj5lPQeiD9gk8PrApiinv+V/4D4Py55nGEAwrP+t/9f/X82EM8Bs9Hl0V3AAAqsuGXxZ0HO7vlf8Q+k+eb/i0B8CWwQSAwkB1IDUkuUAbeAmm/9v4ww4DMeA8pKyifBQhufF0BqQGoxDJjcO7kKObBwBSKIDVXLQEw0fiA2GrEaAEtIJBmATMOSMjY5bAbA0gIyjVeOKrkRAMefDK/b7ecEAAAAAElFTkSuQmCC' + dead: 'data:image/gif;base64,R0lGODlhEAAQAKECAAAAAP8AAP///////yH5BAEKAAIALAAAAAAQABAAAAIvlI+pq+D9DAgUoFkPDlbs7lFZKIJOJJ3MyraoB14jFpOcVMpzrnF3OKlZYsMWowAAOw==' + unreadDead: 'data:image/png;base64,R0lGODlhEAAQAOMHAOgLAnMFAL8AAOgLAukMA/+AgP+rq////////////////////////////////////yH5BAEKAAcALAAAAAAQABAAAARZ8MhJ6xwDWIBv+AM1fEEIBIVRlNKYrtpIECuGzuwpCLg974EYiXUYkUItjGbC6VQ4omXFiKROA6qSy0A8nAo9GS3YCswIWnOvLAi0be23Z1QtdSUaqXcviQAAOw==' + unreadSFW: 'data:image/png;base64,R0lGODlhEAAQAOMHAADX8QBwfgC2zADX8QDY8nnl8qLp8v///////////////////////////////////yH5BAEKAAcALAAAAAAQABAAAARZ8MhJ6xwDWIBv+AM1fEEIBIVRlNKYrtpIECuGzuwpCLg974EYiXUYkUItjGbC6VQ4omXFiKROA6qSy0A8nAo9GS3YCswIWnOvLAi0be23Z1QtdSUaqXcviQAAOw==' + unreadNSFW: 'data:image/png;base64,R0lGODlhEAAQAOMHAFT+ACh5AEncAFT+AFX/Acz/su7/5v///////////////////////////////////yH5BAEKAAcALAAAAAAQABAAAARZ8MhJ6xwDWIBv+AM1fEEIBIVRlNKYrtpIECuGzuwpCLg974EYiXUYkUItjGbC6VQ4omXFiKROA6qSy0A8nAo9GS3YCswIWnOvLAi0be23Z1QtdSUaqXcviQAAOw==' update: -> l = unread.replies.length From 847cef2ae7729db12c84d1a29dba21c734809f6a Mon Sep 17 00:00:00 2001 From: Nicolas Stepien Date: Fri, 25 Nov 2011 23:36:01 +0100 Subject: [PATCH 075/169] Update list of contributors. --- 4chan_x.user.js | 4 +++- Cakefile | 4 +++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/4chan_x.user.js b/4chan_x.user.js index 347b418d6..ac4cb403f 100644 --- a/4chan_x.user.js +++ b/4chan_x.user.js @@ -46,6 +46,9 @@ /* CONTRIBUTORS * + * Shou- - pentadactyl fixes + * ferongr - new favicons + * xat- - new favicons * Zixaphir - fix qr textarea - captcha-image gap * Mayhem - various features / fixes * Ongpot - sfw favicon @@ -54,7 +57,6 @@ * Seiba - chrome quick reply focusing * herpaderpderp - recaptcha fixes * wakimoko - recaptcha tab order http://userscripts.org/scripts/show/82657 - * xat- new favicons * * All the people who've taken the time to write bug reports. * diff --git a/Cakefile b/Cakefile index 39b1b0117..ecdfdada0 100644 --- a/Cakefile +++ b/Cakefile @@ -51,6 +51,9 @@ HEADER = """ /* CONTRIBUTORS * + * Shou- - pentadactyl fixes + * ferongr - new favicons + * xat- - new favicons * Zixaphir - fix qr textarea - captcha-image gap * Mayhem - various features / fixes * Ongpot - sfw favicon @@ -59,7 +62,6 @@ HEADER = """ * Seiba - chrome quick reply focusing * herpaderpderp - recaptcha fixes * wakimoko - recaptcha tab order http://userscripts.org/scripts/show/82657 - * xat- new favicons * * All the people who've taken the time to write bug reports. * From 2bfc3e649c5505b9488fa71184767b4282f69604 Mon Sep 17 00:00:00 2001 From: Nicolas Stepien Date: Sat, 26 Nov 2011 04:25:06 +0100 Subject: [PATCH 076/169] Put the old QR back; this is temporary. --- 4chan_x.user.js | 791 +++++++++++++++++++++++------------------------ script.coffee | 795 ++++++++++++++++++++++++------------------------ 2 files changed, 790 insertions(+), 796 deletions(-) diff --git a/4chan_x.user.js b/4chan_x.user.js index ac4cb403f..6635bce7b 100644 --- a/4chan_x.user.js +++ b/4chan_x.user.js @@ -64,7 +64,7 @@ */ (function() { - var $, $$, DAY, Favicon, HOUR, MINUTE, Main, NAMESPACE, QR, SECOND, Time, anonymize, conf, config, d, expandComment, expandThread, filter, flatten, g, getTitle, imgExpand, imgGif, imgHover, key, keybinds, log, nav, options, quoteBacklink, quoteInline, quoteOP, quotePreview, redirect, replyHiding, reportButton, revealSpoilers, sauce, strikethroughQuotes, threadHiding, threadStats, threading, titlePost, ui, unread, updater, val, watcher; + var $, $$, DAY, Favicon, HOUR, MINUTE, Main, NAMESPACE, Recaptcha, SECOND, Time, anonymize, conf, config, cooldown, d, expandComment, expandThread, filter, flatten, g, getTitle, imgExpand, imgGif, imgHover, key, keybinds, log, nav, options, qr, quoteBacklink, quoteInline, quoteOP, quotePreview, redirect, replyHiding, reportButton, revealSpoilers, sauce, strikethroughQuotes, threadHiding, threadStats, threading, titlePost, ui, unread, updater, val, watcher; var __slice = Array.prototype.slice; config = { @@ -104,6 +104,7 @@ 'Auto Watch Reply': [false, 'Automatically watch threads that you reply to'] }, Posting: { + 'Auto Noko': [true, 'Always redirect to your post'], 'Cooldown': [true, 'Prevent `flood detected` errors'], 'Quick Reply': [true, 'Reply without leaving the page'], 'Persistent QR': [false, 'Quick reply won\'t disappear after posting. Only in replies.'], @@ -894,8 +895,8 @@ case conf.close: if (o = $('#overlay')) { $.rm(o); - } else if (QR.qr) { - QR.close(); + } else if (qr.qr) { + qr.close(); } break; case conf.spoiler: @@ -963,8 +964,8 @@ if ((_ref3 = $('input[value=Previous]')) != null) _ref3.click(); break; case conf.submit: - if (QR.qr) { - QR.submit.call($('form', QR.qr)); + if (qr.qr) { + qr.submit.call($('form', qr.qr)); } else { $('.postarea form').submit(); } @@ -1060,12 +1061,12 @@ }, qr: function(thread, quote) { if (quote) { - return QR.quote.call($('.quotejs + a', $('.replyhl', thread) || thread)); + return qr.quote.call($('.quotejs + a', $('.replyhl', thread) || thread)); } else { - if (QR.qr) { - return $('textarea', QR.qr).focus(); + if (qr.qr) { + return $('textarea', qr.qr).focus(); } else { - return QR.dialog('', thread != null ? thread.firstChild.id : void 0); + return qr.dialog('', thread != null ? thread.firstChild.id : void 0); } } }, @@ -1393,26 +1394,65 @@ } }; - QR = { + cooldown = { init: function() { - var holder; - if (!($('form[name=post]') && $('#recaptcha_response_field'))) return; - g.callbacks.push(function(root) { - var quote; - quote = $('.quotejs + a', root); - return $.on(quote, 'click', QR.quote); + var match, time, _; + if (match = location.search.match(/cooldown=(\d+)/)) { + _ = match[0], time = match[1]; + if ($.get(g.BOARD + '/cooldown', 0) < time) { + $.set(g.BOARD + '/cooldown', time); + } + } + if (Date.now() < $.get(g.BOARD + '/cooldown', 0)) cooldown.start(); + $.on(window, 'storage', function(e) { + if (e.key === ("" + NAMESPACE + g.BOARD + "/cooldown")) { + return cooldown.start(); + } }); - $.add(d.body, $.el('iframe', { - name: 'iframe', - hidden: true - })); - $('#recaptcha_response_field').id = ''; - holder = $('#recaptcha_challenge_field_holder'); - $.on(holder, 'DOMNodeInserted', QR.captchaNode); - QR.captchaNode({ - target: holder.firstChild - }); - QR.accept = $('.rules').textContent.match(/: (.+) /)[1].replace(/\w+/g, function(type) { + if (g.REPLY) return $('.postarea form').action += '?cooldown'; + }, + start: function() { + var submit, _i, _len, _ref; + cooldown.duration = Math.ceil(($.get(g.BOARD + '/cooldown', 0) - Date.now()) / 1000); + if (!(cooldown.duration > 0)) return; + _ref = $$('#com_submit'); + for (_i = 0, _len = _ref.length; _i < _len; _i++) { + submit = _ref[_i]; + submit.value = cooldown.duration; + submit.disabled = true; + } + return setTimeout(cooldown.cb, 1000); + }, + cb: function() { + var submit, submits, _i, _j, _len, _len2, _results; + submits = $$('#com_submit'); + if (--cooldown.duration) { + setTimeout(cooldown.cb, 1000); + _results = []; + for (_i = 0, _len = submits.length; _i < _len; _i++) { + submit = submits[_i]; + _results.push(submit.value = cooldown.duration); + } + return _results; + } else { + for (_j = 0, _len2 = submits.length; _j < _len2; _j++) { + submit = submits[_j]; + submit.disabled = false; + submit.value = 'Submit'; + } + return qr.autoPost(); + } + } + }; + + qr = { + init: function() { + var iframe; + g.callbacks.push(qr.node); + $.on($('#recaptcha_challenge_field_holder'), 'DOMNodeInserted', qr.captchaNode); + qr.captchaTime = Date.now(); + qr.spoiler = $('.postarea label') ? '' : ''; + qr.acceptFiles = $('.rules').textContent.match(/: (.+) /)[1].replace(/\w+/g, function(type) { switch (type) { case 'JPG': return 'image/JPEG'; @@ -1422,315 +1462,295 @@ return 'image/' + type; } }); - QR.MAX_FILE_SIZE = $('input[name=MAX_FILE_SIZE]').value; - QR.spoiler = $('.postarea label') ? ' ' : ''; - if (conf['Persistent QR']) { - QR.dialog(); - $('textarea', QR.qr).blur(); - if (conf['Auto Hide QR']) $('#autohide', QR.qr).checked = true; - } - if (conf['Cooldown']) { - return $.on(window, 'storage', function(e) { - if (e.key === ("" + NAMESPACE + "cooldown/" + g.BOARD)) { - return QR.cooldown(); - } - }); - } - }, - attach: function(file) { - var box, files; - files = $('#files', QR.qr); - box = $.el('li', { - innerHTML: "X" + iframe = $.el('iframe', { + name: 'iframe', + hidden: true }); - $.on($('.x', box), 'click', QR.rmThumb); - $.add(box, file); - $.add(files, box); - QR.stats(); - return QR.foo(); + $.add(d.body, iframe); + return $('#recaptcha_response_field').id = ''; }, - rmThumb: function() { - $.rm(this.parentNode); - return QR.stats(); + attach: function() { + var fileDiv; + fileDiv = $.el('div', { + innerHTML: "X" + }); + $.on(fileDiv.firstChild, 'change', qr.validateFileSize); + $.on(fileDiv.lastChild, 'click', (function() { + return $.rm(this.parentNode); + })); + return $.add($('#files', qr.el), fileDiv); + }, + attachNext: function() { + var file, fileDiv, oldFile; + fileDiv = $.rm($('#files div', qr.el)); + file = fileDiv.firstChild; + oldFile = $('#qr_form input[type=file]', qr.el); + return $.replace(oldFile, file); + }, + autoPost: function() { + if (qr.el && $('#auto', qr.el).checked) { + return qr.submit.call($('form', qr.el)); + } }, captchaNode: function(e) { - QR.captcha = { - challenge: e.target.value, - time: Date.now() - }; - return QR.captchaImg(); + if (!qr.el) return; + val = e.target.value; + $('img', qr.el).src = "http://www.google.com/recaptcha/api/image?c=" + val; + qr.challenge = val; + return qr.captchaTime = Date.now(); }, - captchaImg: function() { - var c, qr; - qr = QR.qr; - if (!qr) return; - c = QR.captcha.challenge; - return $('#captcha img', qr).src = "http://www.google.com/recaptcha/api/image?c=" + c; - }, - captchaPush: function(el) { - var captcha, captchas; - captcha = QR.captcha; - captcha.response = el.value; + captchaKeydown: function(e) { + var captchas; + if (!(e.keyCode === 13 && this.value)) return; captchas = $.get('captchas', []); - captchas.push(captcha); + captchas.push({ + challenge: qr.challenge, + response: this.value, + time: qr.captchaTime + }); $.set('captchas', captchas); - el.value = ''; - QR.captchaReload(); - return QR.stats(captchas); + $('#captchas', qr.el).textContent = captchas.length + ' captchas'; + Recaptcha.reload(); + this.value = ''; + if (!$('textarea', qr.el).value && !$('input[type=file]', qr.el).files.length) { + return e.preventDefault(); + } }, - captchaShift: function() { - var captcha, captchas, cutoff; - captchas = $.get('captchas', []); + close: function() { + $.rm(qr.el); + return qr.el = null; + }, + dialog: function(link) { + var THREAD_ID, c, email, html, m, name, pwd, submitDisabled, submitValue; + c = d.cookie; + name = (m = c.match(/4chan_name=([^;]+)/)) ? decodeURIComponent(m[1]) : ''; + email = (m = c.match(/4chan_email=([^;]+)/)) ? decodeURIComponent(m[1]) : ''; + pwd = (m = c.match(/4chan_pass=([^;]+)/)) ? decodeURIComponent(m[1]) : $('input[name=pwd]').value; + submitValue = $('#com_submit').value; + submitDisabled = $('#com_submit').disabled ? 'disabled' : ''; + THREAD_ID = g.THREAD_ID || $.x('ancestor::div[@class="thread"]/div', link).id; + qr.challenge = $('#recaptcha_challenge_field').value; + html = " X
    Quick Reply
    " + qr.spoiler + "
    " + ($.get('captchas', []).length) + " captchas
    "; + qr.el = ui.dialog('qr', 'top: 0; left: 0;', html); + $.on($('input[name=name]', qr.el), 'mousedown', function(e) { + return e.stopPropagation(); + }); + $.on($('input[name=upfile]', qr.el), 'change', qr.validateFileSize); + $.on($('#close', qr.el), 'click', qr.close); + $.on($('form', qr.el), 'submit', qr.submit); + $.on($('#attach', qr.el), 'click', qr.attach); + $.on($('img', qr.el), 'click', Recaptcha.reload); + $.on($('#dummy', qr.el), 'keydown', Recaptcha.listener); + $.on($('#dummy', qr.el), 'keydown', qr.captchaKeydown); + return $.add(d.body, qr.el); + }, + message: function(data) { + var duration, fileCount, tc; + $('iframe[name=iframe]').src = 'about:blank'; + fileCount = $('#files', qr.el).childElementCount; + tc = data.textContent; + if (tc) { + $.extend($('#error', qr.el), data); + $('#recaptcha_response_field', qr.el).value = ''; + $('#autohide', qr.el).checked = false; + if (tc === 'You seem to have mistyped the verification.') { + setTimeout(qr.autoPost, 1000); + } else if (tc === 'Error: Duplicate file entry detected.' && fileCount) { + $('textarea', qr.el).value += '\n' + tc + ' ' + data.href; + qr.attachNext(); + setTimeout(qr.autoPost, 1000); + } + return; + } + if (qr.el) { + if (g.REPLY && (conf['Persistent QR'] || fileCount)) { + qr.refresh(); + if (fileCount) qr.attachNext(); + } else { + qr.close(); + } + } + if (conf['Cooldown']) { + duration = qr.sage ? 60 : 30; + $.set(g.BOARD + '/cooldown', Date.now() + duration * 1000); + return cooldown.start(); + } + }, + node: function(root) { + var quote; + quote = $('a.quotejs:not(:first-child)', root); + return $.on(quote, 'click', qr.quote); + }, + postInvalid: function() { + var captcha, captchas, content, cutoff, dummy, response; + content = $('textarea', qr.el).value || $('input[type=file]', qr.el).files.length; + if (!content) return 'Error: No text entered.'; + /* + captchas expire after 5 hours (emperically verified). cutoff 5 minutes + before then, b/c posting takes time. + */ cutoff = Date.now() - 5 * HOUR + 5 * MINUTE; + captchas = $.get('captchas', []); while (captcha = captchas.shift()) { if (captcha.time > cutoff) break; } $.set('captchas', captchas); - QR.stats(captchas); - return captcha; - }, - stats: function(captchas) { - var images, qr; - qr = QR.qr; - captchas || (captchas = $.get('captchas', [])); - images = $$('#files input', qr); - return $('#qr_stats', qr).textContent = "" + images.length + " / " + captchas.length; - }, - captchaReload: function() { - return window.location = 'javascript:Recaptcha.reload()'; - }, - change: function(e) { - var file, fr, img; - file = this.files[0]; - if (file.size > QR.MAX_FILE_SIZE) { - alert('Error: File too large.'); - QR.foo(this); - return; + $('#captchas', qr.el).textContent = captchas.length + ' captchas'; + if (!captcha) { + dummy = $('#dummy', qr.el); + if (!(response = dummy.value)) { + return 'You forgot to type in the verification'; + } + captcha = { + challenge: qr.challenge, + response: response + }; + dummy.value = ''; + Recaptcha.reload(); } - if (this.parentNode.className === 'wat') QR.attach(this); - fr = new FileReader(); - img = $('img', this.parentNode); - fr.onload = function(e) { - return img.src = e.target.result; - }; - return fr.readAsDataURL(file); + $('#recaptcha_challenge_field', qr.el).value = captcha.challenge; + $('#recaptcha_response_field', qr.el).value = captcha.response; + return false; }, - close: function() { - $.rm(QR.qr); - return QR.qr = null; - }, - cooldown: function() { - var b, cooldown, n, now; - if (!(g.REPLY && QR.qr)) return; - cooldown = $.get("cooldown/" + g.BOARD, 0); - now = Date.now(); - n = Math.ceil((cooldown - now) / 1000); - b = $('form button', QR.qr); - if (n > 0) { - $.extend(b, { - textContent: n, - disabled: true - }); - return setTimeout(QR.cooldown, 1000); + quote: function(e) { + var id, s, selection, selectionID, ta, text, _ref; + if (e) e.preventDefault(); + if (qr.el) { + $('#autohide', qr.el).checked = false; } else { - $.extend(b, { - textContent: 'Submit', - disabled: false - }); - if ($('#autopost', QR.qr).checked) return QR.submit(); + qr.dialog(this); } - }, - foo: function(old) { - var input; - input = $.el('input', { - type: 'file', - name: 'upfile', - accept: QR.accept - }); - $.on(input, 'change', QR.change); - if (old) { - return $.replace(old, file); - } else { - return $.add($('.wat', QR.qr), input); - } - }, - dialog: function(text, tid) { - var l, qr, ta; - if (text == null) text = ''; - tid || (tid = g.THREAD_ID || ''); - QR.qr = qr = ui.dialog('qr', 'top: 0; right: 0;', " X
      " + (g.REPLY ? "" : '') + " " + QR.spoiler + "
      "); - QR.reset(); - if (conf['Cooldown']) QR.cooldown(); - QR.foo(); - $.on($('.close', qr), 'click', QR.close); - $.on($('form', qr), 'submit', QR.submit); - $.on($('#recaptcha_response_field', qr), 'keydown', QR.keydown); - QR.captchaImg(); - QR.stats(); - $.add(d.body, qr); - ta = $('textarea', qr); - ta.value = text; - l = text.length; - ta.setSelectionRange(l, l); - return ta.focus(); - }, - keydown: function(e) { - var kc, v; - kc = e.keyCode; - v = this.value; - if (kc === 8 && !v) { - QR.captchaReload(); - return; - } - if (!(e.keyCode === 13 && v)) return; - QR.captchaPush(this); - e.preventDefault(); - return QR.submit(); - }, - quote: function(e, blank) { - var bq, i, id, qr, s, sel, ss, ta, text, tid, v, _base, _ref, _ref2; - if (e != null) e.preventDefault(); - tid = (_ref = $.x('ancestor::div[@class="thread"]/div', this)) != null ? _ref.id : void 0; id = this.textContent; text = ">>" + id + "\n"; - sel = getSelection(); - bq = $.x('ancestor::blockquote', sel.anchorNode); - if (id === ((_ref2 = $.x('preceding-sibling::input', bq)) != null ? _ref2.name : void 0)) { - if (s = sel.toString().replace(/\n/g, '\n>')) text += ">" + s + "\n"; - } - qr = QR.qr; - if (!qr) { - QR.dialog(text, tid); - return; - } - $('#autohide', qr).checked = false; - ta = $('textarea', qr); - v = ta.value; - ss = ta.selectionStart; - ta.value = v.slice(0, ss) + text + v.slice(ss); - i = ss + text.length; - ta.setSelectionRange(i, i); - ta.focus(); - return (_base = $('[name=resto]', qr)).value || (_base.value = tid); - }, - receive: function(data) { - var cooldown, href, qr, row, textContent, _ref, _ref2; - $('iframe[name=iframe]').src = 'about:blank'; - qr = QR.qr; - row = (_ref = $('#files input[form]', qr)) != null ? _ref.parentNode : void 0; - data = JSON.parse(data); - textContent = data.textContent, href = data.href; - if (QR.op) { - window.location = href; - return; - } - if (textContent) { - $.extend($('a.error', qr), data); - if (textContent === 'Error: Duplicate file entry detected.') { - if (row) $.rm(row); - QR.stats(); - setTimeout(QR.submit, 1000); - } else if (textContent === 'You seem to have mistyped the verification.') { - setTimeout(QR.submit, 1000); + selection = window.getSelection(); + if (s = selection.toString()) { + selectionID = (_ref = $.x('preceding::input[@type="checkbox"][1]', selection.anchorNode)) != null ? _ref.name : void 0; + if (selectionID === id) { + s = s.replace(/\n/g, '\n>'); + text += ">" + s + "\n"; } - return; - } - if (row) $.rm(row); - QR.stats(); - if (conf['Persistent QR'] || ((_ref2 = $('#files input', qr)) != null ? _ref2.files.length : void 0)) { - QR.reset(); - } else { - QR.close(); - } - if (conf['Cooldown']) { - cooldown = Date.now() + (QR.sage ? 60 : 30) * SECOND; - $.set("cooldown/" + g.BOARD, cooldown); - return QR.cooldown(); } + ta = $('textarea', qr.el); + ta.focus(); + return ta.value += text; }, - reset: function() { - var c, m, qr, _ref; - qr = QR.qr; - c = d.cookie; - $('[name=name]', qr).value = (m = c.match(/4chan_name=([^;]+)/)) ? decodeURIComponent(m[1]) : ''; - $('[name=email]', qr).value = (m = c.match(/4chan_email=([^;]+)/)) ? decodeURIComponent(m[1]) : ''; - $('[name=pwd]', qr).value = (m = c.match(/4chan_pass=([^;]+)/)) ? decodeURIComponent(m[1]) : $('input[name=pwd]').value; - $('[name=sub]', qr).value = ''; + refresh: function() { + var m, newFile, oldFile, _ref; + $('[name=sub]', qr.el).value = ''; + $('[name=email]', qr.el).value = (m = d.cookie.match(/4chan_email=([^;]+)/)) ? decodeURIComponent(m[1]) : ''; + $('[name=com]', qr.el).value = ''; + $('[name=recaptcha_response_field]', qr.el).value = ''; if (!conf['Remember Spoiler']) { - if ((_ref = $('[name=spoiler]', qr)) != null) _ref.checked = false; + if ((_ref = $('[name=spoiler]', qr.el)) != null) _ref.checked = false; } - return $('textarea', qr).value = ''; + oldFile = $('[type=file]', qr.el); + newFile = $.el('input', { + type: 'file', + name: 'upfile', + accept: qr.acceptFiles + }); + return $.replace(oldFile, newFile); }, submit: function(e) { - var captcha, challenge, el, id, input, op, qr, response; - qr = QR.qr; - if ($('textarea', qr).value || $('#files', qr).childNodes.length) { - if ($('form button', qr).disabled) { - $('#autopost', qr).checked = true; - return; - } - } else { - if (e) { - alert('Error: No text entered.'); - e.preventDefault(); + var id, msg, op; + if (msg = qr.postInvalid()) { + if (typeof e.preventDefault === "function") e.preventDefault(); + alert(msg); + if (msg === 'You forgot to type in the verification.') { + $('#dummy', qr.el).focus(); } return; } - $('.error', qr).textContent = ''; - if (e && (el = $('#recaptcha_response_field', qr)).value) QR.captchaPush(el); - if (!(captcha = QR.captchaShift())) { - alert('You forgot to type in the verification.'); - if (e != null) e.preventDefault(); - return; - } - challenge = captcha.challenge, response = captcha.response; - $('#challenge', qr).value = challenge; - $('#response', qr).value = response; - if (conf['Auto Hide QR']) $('#autohide', qr).checked = true; - if (input = $('#files input', qr)) input.setAttribute('form', 'qr_form'); - if (!e) $('#qr_form', qr).submit(); - QR.sage = /sage/i.test($('[name=email]', qr).value); - id = $('input[name=resto]', qr).value; - QR.op = !id; - if (QR.op) $('[name=email]', qr).value = 'noko'; - if (conf['Thread Watcher'] && conf['Auto Watch Reply']) { - op = $.id(id); - if ($('img.favicon', op).src === Favicon.empty) { - return watcher.watch(op, id); + if (conf['Auto Watch Reply'] && conf['Thread Watcher']) { + if (g.REPLY && $('img.favicon').src === Favicon.empty) { + watcher.watch(null, g.THREAD_ID); + } else { + id = $('input[name=resto]', qr.el).value; + op = $.id(id); + if ($('img.favicon', op).src === Favicon.empty) watcher.watch(op, id); } } + if (!e) this.submit(); + $('#error', qr.el).textContent = ''; + if (conf['Auto Hide QR']) $('#autohide', qr.el).checked = true; + return qr.sage = /sage/i.test($('input[name=email]', this).value); }, sys: function() { - var recaptcha; - $.off(d, 'DOMContentLoaded', QR.sys); + var c, duration, id, noko, recaptcha, sage, search, thread, url, watch, _, _ref, _ref2; if (recaptcha = $('#recaptcha_response_field')) { - $.on(recaptcha, 'keydown', QR.keydown); + $.on(recaptcha, 'keydown', Recaptcha.listener); return; } /* - http://code.google.com/p/chromium/issues/detail?id=20773 - Let content scripts see other frames (instead of them being undefined) + http://code.google.com/p/chromium/issues/detail?id=20773 + Let content scripts see other frames (instead of them being undefined) - To access the parent, we have to break out of the sandbox and evaluate - in the global context. + To access the parent, we have to break out of the sandbox and evaluate + in the global context. */ - return $.globalEval(function() { - var data, href, node, textContent, _ref; - $ = function(css) { - return document.querySelector(css); + $.globalEval(function() { + var data, node, _ref; + data = { + to: 'qr.message' }; - if (node = (_ref = $('table font b')) != null ? _ref.firstChild : void 0) { - textContent = node.textContent, href = node.href; - } else { - node = $('meta'); - href = node.content.match(/url=(.+)/)[1]; + if (node = (_ref = document.querySelector('table font b')) != null ? _ref.firstChild : void 0) { + data.textContent = node.textContent; + data.href = node.href; } - data = JSON.stringify({ - textContent: textContent, - href: href - }); return parent.postMessage(data, '*'); }); + c = (_ref = $('b')) != null ? _ref.lastChild : void 0; + if (!(c && c.nodeType === 8)) return; + _ref2 = c.textContent.match(/thread:(\d+),no:(\d+)/), _ = _ref2[0], thread = _ref2[1], id = _ref2[2]; + search = location.search; + cooldown = /cooldown/.test(search); + noko = /noko/.test(search); + sage = /sage/.test(search); + watch = /watch/.test(search); + url = "http://boards.4chan.org/" + g.BOARD; + if (watch && thread === '0') { + url += "/res/" + id + "?watch"; + } else if (noko) { + url += '/res/'; + url += thread === '0' ? id : thread; + } + if (cooldown) { + duration = Date.now() + (sage ? 60 : 30) * 1000; + url += '?cooldown=' + duration; + } + if (noko) url += '#' + id; + return window.location = url; + }, + validateFileSize: function(e) { + var file; + if (!(this.files[0].size > $('input[name=MAX_FILE_SIZE]').value)) return; + file = $.el('input', { + type: 'file', + name: 'upfile', + accept: qr.acceptFiles + }); + $.on(file, 'change', qr.validateFileSize); + $.replace(this, file); + $('#error', qr.el).textContent = 'Error: File too large.'; + return alert('Error: File too large.'); + } + }; + + Recaptcha = { + init: function() { + var el, _i, _len, _ref; + _ref = $$('#recaptcha_table a'); + for (_i = 0, _len = _ref.length; _i < _len; _i++) { + el = _ref[_i]; + el.tabIndex = 1; + } + return $.bind($('#recaptcha_response_field'), 'keydown', Recaptcha.listener); + }, + listener: function(e) { + if (e.keyCode === 8 && this.value === '') return Recaptcha.reload(); + }, + reload: function() { + return window.location = 'javascript:Recaptcha.reload()'; } }; @@ -2872,15 +2892,6 @@ Main = { init: function() { var cutoff, hiddenThreads, id, lastChecked, now, pathname, temp, timestamp, _ref; - if (location.hostname === 'sys.4chan.org') { - if (d.body) { - QR.sys(); - } else { - $.on(d, 'DOMContentLoaded', QR.sys); - } - return; - } - $.on(window, 'message', Main.message); pathname = location.pathname.substring(1).split('/'); g.BOARD = pathname[0], temp = pathname[1]; if (temp === 'res') { @@ -2889,6 +2900,15 @@ } else { g.PAGENUM = parseInt(temp) || 0; } + if (location.hostname === 'sys.4chan.org') { + if (d.body) { + qr.sys(); + } else { + $.on(d, 'DOMContentLoaded', qr.sys); + } + return; + } + $.on(window, 'message', Main.message); g.hiddenReplies = $.get("hiddenReplies/" + g.BOARD + "/", {}); lastChecked = $.get('lastChecked', 0); now = Date.now(); @@ -2929,7 +2949,7 @@ } }, onLoad: function() { - var callback, node, nodes, _i, _j, _len, _len2, _ref; + var callback, canPost, form, node, nodes, _i, _j, _len, _len2, _ref; $.off(d, 'DOMContentLoaded', Main.onLoad); if (conf['404 Redirect'] && d.title === '4chan - 404' && /^\d+$/.test(g.THREAD_ID)) { redirect(); @@ -2939,9 +2959,21 @@ $.addStyle(Main.css); threading.init(); Favicon.init(); + if ((form = $('form[name=post]')) && (canPost = !!$('#recaptcha_response_field'))) { + Recaptcha.init(); + if (g.REPLY && conf['Auto Watch Reply'] && conf['Thread Watcher']) { + $.bind(form, 'submit', function() { + if ($('img.favicon').src === Favicon.empty) { + return watcher.watch(null, g.THREAD_ID); + } + }); + } + } + if (conf['Auto Noko'] && canPost) form.action += '?noko'; + if (conf['Cooldown'] && canPost) cooldown.init(); if (conf['Image Expansion']) imgExpand.init(); if (conf['Reveal Spoilers'] && $('.postarea label')) revealSpoilers.init(); - if (conf['Quick Reply']) QR.init(); + if (conf['Quick Reply']) qr.init(); if (conf['Thread Watcher']) watcher.init(); if (conf['Keybinds']) keybinds.init(); if (g.REPLY) { @@ -2950,6 +2982,10 @@ if (conf['Reply Navigation']) nav.init(); if (conf['Post in Title']) titlePost.init(); if (conf['Unread Count']) unread.init(); + if (conf['Quick Reply'] && conf['Persistent QR'] && canPost) { + qr.dialog(); + if (conf['Auto Hide QR']) $('#autohide', qr.el).checked = true; + } } else { if (conf['Thread Hiding']) threadHiding.init(); if (conf['Thread Expansion']) expandThread.init(); @@ -2975,7 +3011,7 @@ message: function(e) { var data, origin; origin = e.origin, data = e.data; - if (origin === 'http://sys.4chan.org') return QR.receive(data); + if (origin === 'http://sys.4chan.org') return qr.message(data); }, node: function(e) { var callback, target, _i, _len, _ref, _results; @@ -3001,7 +3037,7 @@ div.dialog > div.move {\ cursor: move;\ }\ - label, a, .favicon {\ + label, a, .favicon, #qr img {\ cursor: pointer;\ }\ \ @@ -3011,6 +3047,12 @@ .error {\ color: red;\ }\ + #error {\ + cursor: default;\ + }\ + #error[href] {\ + cursor: pointer;\ + }\ td.replyhider {\ vertical-align: top;\ }\ @@ -3091,6 +3133,47 @@ resize: vertical;\ width: 100%;\ }\ +\ + #qr {\ + position: fixed;\ + max-height: 100%;\ + overflow-x: hidden;\ + overflow-y: auto;\ + }\ + #qr > div.move {\ + text-align: right;\ + }\ + #qr input[name=name] {\ + float: left;\ + }\ + #qr_form {\ + clear: left;\ + }\ + #qr_form, #qr #com_submit, #qr input[name=upfile] {\ + margin: 0;\ + }\ + #qr textarea {\ + width: 100%;\ + height: 125px;\ + }\ + #qr #close, #qr #autohide {\ + float: right;\ + }\ + #qr:not(:hover) > #autohide:checked ~ .autohide {\ + height: 0;\ + overflow: hidden;\ + }\ + /* http://stackoverflow.com/questions/2610497/change-an-inputs-html5-placeholder-color-with-css */\ + #qr input::-webkit-input-placeholder {\ + color: grey;\ + }\ + #qr input:-moz-placeholder {\ + color: grey;\ + }\ + /* qr reCAPTCHA */\ + #qr img {\ + border: 1px solid #AAA;\ + }\ \ #updater {\ position: fixed;\ @@ -3163,102 +3246,6 @@ #files > input {\ display: block;\ }\ - #qr {\ - position: fixed;\ - }\ - #qr .close, #qr #autohide {\ - float: right;\ - }\ - #qr > .move {\ - text-align: right;\ - }\ - #qr .autohide > input {\ - width: 90px;\ - }\ - #qr #autopost {\ - width: auto;\ - }\ - #qr #recaptcha_response_field {\ - width: 100%;\ - }\ - #qr form {\ - margin: 0;\ - }\ - #qr .autohide {\ - clear: both;\ - }\ - #qr:not(:hover) #autohide:checked ~ .autohide {\ - height: 0;\ - overflow: hidden;\ - }\ - #qr textarea {\ - border: 0;\ - height: 150px;\ - width: 100%;\ - }\ - #qr #captcha {\ - position: relative;\ - }\ - #qr #files {\ - width: 300px;\ - white-space: nowrap;\ - overflow: auto;\ - margin: 0;\ - padding: 0;\ - }\ - #qr #files li {\ - position: relative;\ - display: inline-block;\ - width: 100px;\ - height: 100px;\ - overflow: hidden;\ - }\ - #qr #files a {\ - position: absolute;\ - left: 0;\ - font-size: 50px;\ - color: red;\ - z-index: 1;\ - }\ - #qr #cl {\ - right: 0;\ - padding: 2px;\ - position: absolute;\ - }\ - #qr #files input {\ - /* cannot use `display: none;`\ - https://bugs.webkit.org/show_bug.cgi?id=58208\ - http://code.google.com/p/chromium/issues/detail?id=78961\ - */\ - font-size: 100px;\ - opacity: 0;\ - }\ - #qr #files img {\ - position: absolute;\ - left: 0;\ - max-height: 100px;\ - max-width: 100px;\ - }\ - #qr input[name=resto] {\ - width: 80px;\ - }\ - #qr button + input[type=file] {\ - position: absolute;\ - opacity: 0;\ - pointer-events: none;\ - }\ - #qr .wat {\ - display: inline-block;\ - width: 16px;\ - overflow: hidden;\ - position: relative;\ - vertical-align: text-top;\ - }\ - #qr .wat input {\ - opacity: 0;\ - position: absolute;\ - left: 0;\ - }\ ' }; diff --git a/script.coffee b/script.coffee index 6be12598b..fbd6a345c 100644 --- a/script.coffee +++ b/script.coffee @@ -31,6 +31,7 @@ config = 'Auto Watch': [true, 'Automatically watch threads that you start'] 'Auto Watch Reply': [false, 'Automatically watch threads that you reply to'] Posting: + 'Auto Noko': [true, 'Always redirect to your post'] 'Cooldown': [true, 'Prevent `flood detected` errors'] 'Quick Reply': [true, 'Reply without leaving the page'] 'Persistent QR': [false, 'Quick reply won\'t disappear after posting. Only in replies.'] @@ -642,8 +643,8 @@ keybinds = when conf.close if o = $ '#overlay' $.rm o - else if QR.qr - QR.close() + else if qr.qr + qr.close() when conf.spoiler ta = e.target return unless ta.nodeName is 'TEXTAREA' @@ -694,8 +695,8 @@ keybinds = when conf.previousPage $('input[value=Previous]')?.click() when conf.submit - if QR.qr - QR.submit.call $ 'form', QR.qr + if qr.qr + qr.submit.call $ 'form', qr.qr else $('.postarea form').submit() when conf.unreadCountTo0 @@ -740,12 +741,12 @@ keybinds = qr: (thread, quote) -> if quote - QR.quote.call $ '.quotejs + a', $('.replyhl', thread) or thread + qr.quote.call $ '.quotejs + a', $('.replyhl', thread) or thread else - if QR.qr - $('textarea', QR.qr).focus() + if qr.qr + $('textarea', qr.qr).focus() else - QR.dialog '', thread?.firstChild.id + qr.dialog '', thread?.firstChild.id open: (thread, tab) -> id = thread.firstChild.id @@ -1033,25 +1034,49 @@ options = conf['backlink'] = @value $('#backlinkPreview').textContent = conf['backlink'].replace /%id/, '123456789' -QR = - #captcha caching for report form - #report queueing - #check if captchas can be reused on eg dup file error +cooldown = + #TODO merge into qr init: -> - #can't reply in some stickies, recaptcha may be blocked, eg by noscript - return unless $('form[name=post]') and $('#recaptcha_response_field') - g.callbacks.push (root) -> - quote = $ '.quotejs + a', root - $.on quote, 'click', QR.quote - $.add d.body, $.el 'iframe', - name: 'iframe' - hidden: true - # nuke id so qr's field focuses on recaptcha reload, instead of normal form's - $('#recaptcha_response_field').id = '' - holder = $ '#recaptcha_challenge_field_holder' - $.on holder, 'DOMNodeInserted', QR.captchaNode - QR.captchaNode target: holder.firstChild - QR.accept = $('.rules').textContent.match(/: (.+) /)[1].replace /\w+/g, (type) -> + if match = location.search.match /cooldown=(\d+)/ + [_, time] = match + $.set g.BOARD+'/cooldown', time if $.get(g.BOARD+'/cooldown', 0) < time + cooldown.start() if Date.now() < $.get g.BOARD+'/cooldown', 0 + $.on window, 'storage', (e) -> cooldown.start() if e.key is "#{NAMESPACE}#{g.BOARD}/cooldown" + $('.postarea form').action += '?cooldown' if g.REPLY + + start: -> + cooldown.duration = Math.ceil ($.get(g.BOARD+'/cooldown', 0) - Date.now()) / 1000 + return unless cooldown.duration > 0 + for submit in $$ '#com_submit' + submit.value = cooldown.duration + submit.disabled = true + setTimeout cooldown.cb, 1000 + + cb: -> + submits = $$ '#com_submit' + if --cooldown.duration + setTimeout cooldown.cb, 1000 + for submit in submits + submit.value = cooldown.duration + else + for submit in submits + submit.disabled = false + submit.value = 'Submit' + qr.autoPost() + +qr = + # TODO + # error handling / logging + # persistent captcha + # rm Recaptcha + # email reverts + init: -> + g.callbacks.push qr.node + $.on $('#recaptcha_challenge_field_holder'), 'DOMNodeInserted', qr.captchaNode + qr.captchaTime = Date.now() + + qr.spoiler = if $('.postarea label') then '' else '' + qr.acceptFiles = $('.rules').textContent.match(/: (.+) /)[1].replace /\w+/g, (type) -> switch type when 'JPG' 'image/JPEG' @@ -1059,281 +1084,295 @@ QR = 'application/' + type else 'image/' + type - QR.MAX_FILE_SIZE = $('input[name=MAX_FILE_SIZE]').value - QR.spoiler = if $('.postarea label') then ' ' else '' - if conf['Persistent QR'] - QR.dialog() - $('textarea', QR.qr).blur() - if conf['Auto Hide QR'] - $('#autohide', QR.qr).checked = true - if conf['Cooldown'] - $.on window, 'storage', (e) -> QR.cooldown() if e.key is "#{NAMESPACE}cooldown/#{g.BOARD}" - attach: (file) -> - files = $ '#files', QR.qr - box = $.el 'li', - innerHTML: "X" - $.on $('.x', box), 'click', QR.rmThumb - $.add box, file - $.add files, box - QR.stats() - QR.foo() - rmThumb: -> - $.rm @parentNode - QR.stats() + + iframe = $.el 'iframe', + name: 'iframe' + hidden: true + $.add d.body, iframe + + #hack - nuke id so it doesn't grab focus when reloading + $('#recaptcha_response_field').id = '' + + attach: -> + fileDiv = $.el 'div', innerHTML: "X" + $.on fileDiv.firstChild, 'change', qr.validateFileSize + $.on fileDiv.lastChild, 'click', (-> $.rm @parentNode) + $.add $('#files', qr.el), fileDiv + + attachNext: -> + fileDiv = $.rm $('#files div', qr.el) + file = fileDiv.firstChild + oldFile = $ '#qr_form input[type=file]', qr.el + $.replace oldFile, file + + autoPost: -> + if qr.el and $('#auto', qr.el).checked + qr.submit.call $ 'form', qr.el + captchaNode: (e) -> - QR.captcha = - challenge: e.target.value - time: Date.now() - QR.captchaImg() - captchaImg: -> - {qr} = QR - return unless qr - c = QR.captcha.challenge - $('#captcha img', qr).src = "http://www.google.com/recaptcha/api/image?c=#{c}" - captchaPush: (el) -> - {captcha} = QR - captcha.response = el.value + return unless qr.el + val = e.target.value + $('img', qr.el).src = "http://www.google.com/recaptcha/api/image?c=" + val + qr.challenge = val + qr.captchaTime = Date.now() + + captchaKeydown: (e) -> + return unless e.keyCode is 13 and @value #enter, captcha filled + captchas = $.get 'captchas', [] - captchas.push captcha + captchas.push + challenge: qr.challenge + response: @value + time: qr.captchaTime $.set 'captchas', captchas - el.value = '' - QR.captchaReload() - QR.stats captchas - captchaShift: -> - captchas = $.get 'captchas', [] + $('#captchas', qr.el).textContent = captchas.length + ' captchas' + Recaptcha.reload() + @value = '' + + if !$('textarea', qr.el).value and !$('input[type=file]', qr.el).files.length + e.preventDefault() + + close: -> + $.rm qr.el + qr.el = null + + dialog: (link) -> + c = d.cookie + name = if m = c.match(/4chan_name=([^;]+)/) then decodeURIComponent m[1] else '' + email = if m = c.match(/4chan_email=([^;]+)/) then decodeURIComponent m[1] else '' + pwd = if m = c.match(/4chan_pass=([^;]+)/) then decodeURIComponent m[1] else $('input[name=pwd]').value + submitValue = $('#com_submit').value + submitDisabled = if $('#com_submit').disabled then 'disabled' else '' + #FIXME inlined cross-thread quotes + THREAD_ID = g.THREAD_ID or $.x('ancestor::div[@class="thread"]/div', link).id + qr.challenge = $('#recaptcha_challenge_field').value + + html = " + X + +
      + + Quick Reply +
      +
      +
      + + + + +
      #{qr.spoiler}
      +
      +
      +
      +
      #{$.get('captchas', []).length} captchas
      +
      +
      +
      + +
      + + " + qr.el = ui.dialog 'qr', 'top: 0; left: 0;', html + + $.on $('input[name=name]', qr.el), 'mousedown', (e) -> e.stopPropagation() + $.on $('input[name=upfile]', qr.el), 'change', qr.validateFileSize + $.on $('#close', qr.el), 'click', qr.close + $.on $('form', qr.el), 'submit', qr.submit + $.on $('#attach', qr.el), 'click', qr.attach + $.on $('img', qr.el), 'click', Recaptcha.reload + $.on $('#dummy', qr.el), 'keydown', Recaptcha.listener + $.on $('#dummy', qr.el), 'keydown', qr.captchaKeydown + + $.add d.body, qr.el + + message: (data) -> + $('iframe[name=iframe]').src = 'about:blank' + fileCount = $('#files', qr.el).childElementCount + + tc = data.textContent + if tc # error message + $.extend $('#error', qr.el), data + $('#recaptcha_response_field', qr.el).value = '' + $('#autohide', qr.el).checked = false + if tc is 'You seem to have mistyped the verification.' + setTimeout qr.autoPost, 1000 + else if tc is 'Error: Duplicate file entry detected.' and fileCount + $('textarea', qr.el).value += '\n' + tc + ' ' + data.href + qr.attachNext() + setTimeout qr.autoPost, 1000 + return + + if qr.el + if g.REPLY and (conf['Persistent QR'] or fileCount) + qr.refresh() + if fileCount + qr.attachNext() + else + qr.close() + if conf['Cooldown'] + duration = if qr.sage then 60 else 30 + $.set g.BOARD+'/cooldown', Date.now() + duration * 1000 + cooldown.start() + + node: (root) -> + quote = $ 'a.quotejs:not(:first-child)', root + $.on quote, 'click', qr.quote + + postInvalid: -> + content = $('textarea', qr.el).value or $('input[type=file]', qr.el).files.length + return 'Error: No text entered.' unless content + + ### + captchas expire after 5 hours (emperically verified). cutoff 5 minutes + before then, b/c posting takes time. + ### + cutoff = Date.now() - 5*HOUR + 5*MINUTE + captchas = $.get 'captchas', [] while captcha = captchas.shift() if captcha.time > cutoff break $.set 'captchas', captchas - QR.stats captchas - captcha - stats: (captchas) -> - {qr} = QR - captchas or= $.get 'captchas', [] - images = $$ '#files input', qr - $('#qr_stats', qr).textContent = "#{images.length} / #{captchas.length}" - captchaReload: -> - window.location = 'javascript:Recaptcha.reload()' - change: (e) -> - file = @files[0] - if file.size > QR.MAX_FILE_SIZE - alert 'Error: File too large.' - QR.foo @ - return - if @parentNode.className is 'wat' - QR.attach @ - fr = new FileReader() - img = $ 'img', @parentNode - fr.onload = (e) -> - img.src = e.target.result - fr.readAsDataURL file - close: -> - $.rm QR.qr - QR.qr = null - cooldown: -> - return unless g.REPLY and QR.qr - cooldown = $.get "cooldown/#{g.BOARD}", 0 - now = Date.now() - n = Math.ceil (cooldown - now) / 1000 - b = $ 'form button', QR.qr - if n > 0 - $.extend b, - textContent: n - disabled: true - setTimeout QR.cooldown, 1000 + + $('#captchas', qr.el).textContent = captchas.length + ' captchas' + + unless captcha + dummy = $ '#dummy', qr.el + return 'You forgot to type in the verification' unless response = dummy.value + captcha = + challenge: qr.challenge + response: response + dummy.value = '' + Recaptcha.reload() + + $('#recaptcha_challenge_field', qr.el).value = captcha.challenge + $('#recaptcha_response_field', qr.el).value = captcha.response + + false + + quote: (e) -> + e.preventDefault() if e + + if qr.el + $('#autohide', qr.el).checked = false else - $.extend b, - textContent: 'Submit' - disabled: false - QR.submit() if $('#autopost', QR.qr).checked - foo: (old) -> - input = $.el 'input', - type: 'file' - name: 'upfile' - accept: QR.accept - $.on input, 'change', QR.change - if old - $.replace old, file - else - $.add $('.wat', QR.qr), input - dialog: (text='', tid) -> - tid or= g.THREAD_ID or '' - QR.qr = qr = ui.dialog 'qr', 'top: 0; right: 0;', " - X - -
      - -
      -
      - - - - -
        -
        - - -
        -
        - -
        -
        - - #{if g.REPLY then "" else ''} - - #{QR.spoiler} -
        -
        -
        - - " - #XXX use dom methods to set values instead of injecting raw user input into your html -_-; - QR.reset() - QR.cooldown() if conf['Cooldown'] - QR.foo() - $.on $('.close', qr), 'click', QR.close - $.on $('form', qr), 'submit', QR.submit - $.on $('#recaptcha_response_field', qr), 'keydown', QR.keydown - QR.captchaImg() - QR.stats() - $.add d.body, qr - ta = $ 'textarea', qr - ta.value = text - l = text.length - ta.setSelectionRange l, l - ta.focus() - keydown: (e) -> - kc = e.keyCode - v = @value - if kc is 8 and not v #backspace, empty - QR.captchaReload() - return - return unless e.keyCode is 13 and v #enter, not empty - QR.captchaPush @ - e.preventDefault() - QR.submit() #derpy, but prevents checking for content twice - quote: (e, blank) -> - e?.preventDefault() - tid = $.x('ancestor::div[@class="thread"]/div', @)?.id + qr.dialog @ + id = @textContent text = ">>#{id}\n" - sel = getSelection() - bq = $.x('ancestor::blockquote', sel.anchorNode) - if id == $.x('preceding-sibling::input', bq)?.name - if s = sel.toString().replace /\n/g, '\n>' - text += ">#{s}\n" - {qr} = QR - if not qr - QR.dialog text, tid - return - $('#autohide', qr).checked = false - ta = $ 'textarea', qr - v = ta.value - ss = ta.selectionStart - ta.value = v[0...ss] + text + v[ss..] - i = ss + text.length - ta.setSelectionRange i, i - ta.focus() - $('[name=resto]', qr).value or= tid - receive: (data) -> - $('iframe[name=iframe]').src = 'about:blank' - {qr} = QR - row = $('#files input[form]', qr)?.parentNode - data = JSON.parse data - {textContent, href} = data - if QR.op - window.location = href - return - if textContent - $.extend $('a.error', qr), data - if textContent is 'Error: Duplicate file entry detected.' - $.rm row if row - QR.stats() - setTimeout QR.submit, 1000 - else if textContent is 'You seem to have mistyped the verification.' - setTimeout QR.submit, 1000 - return - $.rm row if row - QR.stats() - if conf['Persistent QR'] or $('#files input', qr)?.files.length - QR.reset() - else - QR.close() - if conf['Cooldown'] - cooldown = Date.now() + (if QR.sage then 60 else 30)*SECOND - $.set "cooldown/#{g.BOARD}", cooldown - QR.cooldown() - reset: -> - {qr} = QR - c = d.cookie - $('[name=name]', qr).value = if m = c.match(/4chan_name=([^;]+)/) then decodeURIComponent m[1] else '' - $('[name=email]', qr).value = if m = c.match(/4chan_email=([^;]+)/) then decodeURIComponent m[1] else '' - $('[name=pwd]', qr).value = if m = c.match(/4chan_pass=([^;]+)/) then decodeURIComponent m[1] else $('input[name=pwd]').value - $('[name=sub]', qr).value = '' - $('[name=spoiler]', qr)?.checked = false unless conf['Remember Spoiler'] - $('textarea', qr).value = '' - submit: (e) -> - {qr} = QR - #XXX e is undefined if method is called explicitly, eg, from auto posting - if $('textarea', qr).value or $('#files', qr).childNodes.length - if $('form button', qr).disabled - $('#autopost', qr).checked = true - return - else - if e - alert 'Error: No text entered.' - e.preventDefault() - return - $('.error', qr).textContent = '' - if e and (el = $('#recaptcha_response_field', qr)).value - QR.captchaPush el - if not captcha = QR.captchaShift() - alert 'You forgot to type in the verification.' - e?.preventDefault() - return - {challenge, response} = captcha - $('#challenge', qr).value = challenge - $('#response', qr).value = response - $('#autohide', qr).checked = true if conf['Auto Hide QR'] - if input = $ '#files input', qr - input.setAttribute 'form', 'qr_form' - $('#qr_form', qr).submit() if not e - QR.sage = /sage/i.test $('[name=email]', qr).value - id = $('input[name=resto]', qr).value - QR.op = not id - $('[name=email]', qr).value = 'noko' if QR.op - if conf['Thread Watcher'] and conf['Auto Watch Reply'] - op = $.id id - if $('img.favicon', op).src is Favicon.empty - watcher.watch op, id - sys: -> - $.off d, 'DOMContentLoaded', QR.sys - if recaptcha = $ '#recaptcha_response_field' #post reporting - $.on recaptcha, 'keydown', QR.keydown - return - ### - http://code.google.com/p/chromium/issues/detail?id=20773 - Let content scripts see other frames (instead of them being undefined) - To access the parent, we have to break out of the sandbox and evaluate - in the global context. + selection = window.getSelection() + if s = selection.toString() + selectionID = $.x('preceding::input[@type="checkbox"][1]', selection.anchorNode)?.name + if selectionID == id + s = s.replace /\n/g, '\n>' + text += ">#{s}\n" + + ta = $ 'textarea', qr.el + ta.focus() + ta.value += text + + refresh: -> + $('[name=sub]', qr.el).value = '' + $('[name=email]', qr.el).value = if m = d.cookie.match(/4chan_email=([^;]+)/) then decodeURIComponent m[1] else '' + $('[name=com]', qr.el).value = '' + $('[name=recaptcha_response_field]', qr.el).value = '' + $('[name=spoiler]', qr.el)?.checked = false unless conf['Remember Spoiler'] + # XXX opera doesn't allow resetting file inputs w/ file.value = '' + oldFile = $ '[type=file]', qr.el + newFile = $.el 'input', type: 'file', name: 'upfile', accept: qr.acceptFiles + $.replace oldFile, newFile + + submit: (e) -> + #XXX `e` won't exist if we're here from `qr.submit.call form`. + if msg = qr.postInvalid() + e.preventDefault?() + alert msg + if msg is 'You forgot to type in the verification.' + $('#dummy', qr.el).focus() + return + + if conf['Auto Watch Reply'] and conf['Thread Watcher'] + if g.REPLY and $('img.favicon').src is Favicon.empty + watcher.watch null, g.THREAD_ID + else + id = $('input[name=resto]', qr.el).value + op = $.id id + if $('img.favicon', op).src is Favicon.empty + watcher.watch op, id + + if !e then @submit() + $('#error', qr.el).textContent = '' + $('#autohide', qr.el).checked = true if conf['Auto Hide QR'] + qr.sage = /sage/i.test $('input[name=email]', @).value + + sys: -> + if recaptcha = $ '#recaptcha_response_field' #post reporting + $.on recaptcha, 'keydown', Recaptcha.listener + return + + ### + http://code.google.com/p/chromium/issues/detail?id=20773 + Let content scripts see other frames (instead of them being undefined) + + To access the parent, we have to break out of the sandbox and evaluate + in the global context. ### $.globalEval -> - $ = (css) -> document.querySelector css - if node = $('table font b')?.firstChild - {textContent, href} = node - else - node = $ 'meta' - href = node.content.match(/url=(.+)/)[1] - data = JSON.stringify { textContent, href } + data = to: 'qr.message' + if node = document.querySelector('table font b')?.firstChild + data.textContent = node.textContent + data.href = node.href parent.postMessage data, '*' - #if we're an iframe, parent will blank us + + c = $('b')?.lastChild + + return unless c and c.nodeType is 8 #comment node + + [_, thread, id] = c.textContent.match(/thread:(\d+),no:(\d+)/) + + {search} = location + cooldown = /cooldown/.test search + noko = /noko/ .test search + sage = /sage/ .test search + watch = /watch/ .test search + + url = "http://boards.4chan.org/#{g.BOARD}" + + if watch and thread is '0' + url += "/res/#{id}?watch" + else if noko + url += '/res/' + url += if thread is '0' then id else thread + if cooldown + duration = Date.now() + (if sage then 60 else 30) * 1000 + url += '?cooldown=' + duration + if noko + url += '#' + id + + window.location = url + + validateFileSize: (e) -> + return unless @files[0].size > $('input[name=MAX_FILE_SIZE]').value + + file = $.el 'input', type: 'file', name: 'upfile', accept: qr.acceptFiles + $.on file, 'change', qr.validateFileSize + $.replace @, file + + $('#error', qr.el).textContent = 'Error: File too large.' + alert 'Error: File too large.' + +Recaptcha = + init: -> + #hack to tab from comment straight to recaptcha + for el in $$ '#recaptcha_table a' + el.tabIndex = 1 + $.bind $('#recaptcha_response_field'), 'keydown', Recaptcha.listener + listener: (e) -> + if e.keyCode is 8 and @value is '' # backspace to reload + Recaptcha.reload() + reload: -> + window.location = 'javascript:Recaptcha.reload()' threading = init: -> @@ -2179,15 +2218,6 @@ imgExpand = Main = init: -> - if location.hostname is 'sys.4chan.org' - if d.body - QR.sys() - else - $.on d, 'DOMContentLoaded', QR.sys - return - - $.on window, 'message', Main.message - pathname = location.pathname.substring(1).split('/') [g.BOARD, temp] = pathname if temp is 'res' @@ -2196,6 +2226,15 @@ Main = else g.PAGENUM = parseInt(temp) or 0 + if location.hostname is 'sys.4chan.org' + if d.body + qr.sys() + else + $.on d, 'DOMContentLoaded', qr.sys + return + + $.on window, 'message', Main.message + g.hiddenReplies = $.get "hiddenReplies/#{g.BOARD}/", {} lastChecked = $.get 'lastChecked', 0 @@ -2277,8 +2316,20 @@ Main = threading.init() Favicon.init() + #recaptcha may be blocked, eg by noscript + if (form = $ 'form[name=post]') and (canPost = !!$ '#recaptcha_response_field') + Recaptcha.init() + if g.REPLY and conf['Auto Watch Reply'] and conf['Thread Watcher'] + $.bind form, 'submit', -> if $('img.favicon').src is Favicon.empty + watcher.watch null, g.THREAD_ID #major features + if conf['Auto Noko'] and canPost + form.action += '?noko' + + if conf['Cooldown'] and canPost + cooldown.init() + if conf['Image Expansion'] imgExpand.init() @@ -2286,7 +2337,7 @@ Main = revealSpoilers.init() if conf['Quick Reply'] - QR.init() + qr.init() if conf['Thread Watcher'] watcher.init() @@ -2310,6 +2361,11 @@ Main = if conf['Unread Count'] unread.init() + if conf['Quick Reply'] and conf['Persistent QR'] and canPost + qr.dialog() + if conf['Auto Hide QR'] + $('#autohide', qr.el).checked = true + else #not reply if conf['Thread Hiding'] threadHiding.init() @@ -2337,7 +2393,7 @@ Main = message: (e) -> {origin, data} = e if origin is 'http://sys.4chan.org' - QR.receive data + qr.message data node: (e) -> {target} = e @@ -2356,7 +2412,7 @@ Main = div.dialog > div.move { cursor: move; } - label, a, .favicon { + label, a, .favicon, #qr img { cursor: pointer; } @@ -2366,6 +2422,12 @@ Main = .error { color: red; } + #error { + cursor: default; + } + #error[href] { + cursor: pointer; + } td.replyhider { vertical-align: top; } @@ -2447,6 +2509,47 @@ Main = width: 100%; } + #qr { + position: fixed; + max-height: 100%; + overflow-x: hidden; + overflow-y: auto; + } + #qr > div.move { + text-align: right; + } + #qr input[name=name] { + float: left; + } + #qr_form { + clear: left; + } + #qr_form, #qr #com_submit, #qr input[name=upfile] { + margin: 0; + } + #qr textarea { + width: 100%; + height: 125px; + } + #qr #close, #qr #autohide { + float: right; + } + #qr:not(:hover) > #autohide:checked ~ .autohide { + height: 0; + overflow: hidden; + } + /* http://stackoverflow.com/questions/2610497/change-an-inputs-html5-placeholder-color-with-css */ + #qr input::-webkit-input-placeholder { + color: grey; + } + #qr input:-moz-placeholder { + color: grey; + } + /* qr reCAPTCHA */ + #qr img { + border: 1px solid #AAA; + } + #updater { position: fixed; text-align: right; @@ -2518,102 +2621,6 @@ Main = #files > input { display: block; } - #qr { - position: fixed; - } - #qr .close, #qr #autohide { - float: right; - } - #qr > .move { - text-align: right; - } - #qr .autohide > input { - width: 90px; - } - #qr #autopost { - width: auto; - } - #qr #recaptcha_response_field { - width: 100%; - } - #qr form { - margin: 0; - } - #qr .autohide { - clear: both; - } - #qr:not(:hover) #autohide:checked ~ .autohide { - height: 0; - overflow: hidden; - } - #qr textarea { - border: 0; - height: 150px; - width: 100%; - } - #qr #captcha { - position: relative; - } - #qr #files { - width: 300px; - white-space: nowrap; - overflow: auto; - margin: 0; - padding: 0; - } - #qr #files li { - position: relative; - display: inline-block; - width: 100px; - height: 100px; - overflow: hidden; - } - #qr #files a { - position: absolute; - left: 0; - font-size: 50px; - color: red; - z-index: 1; - } - #qr #cl { - right: 0; - padding: 2px; - position: absolute; - } - #qr #files input { - /* cannot use `display: none;` - https://bugs.webkit.org/show_bug.cgi?id=58208 - http://code.google.com/p/chromium/issues/detail?id=78961 - */ - font-size: 100px; - opacity: 0; - } - #qr #files img { - position: absolute; - left: 0; - max-height: 100px; - max-width: 100px; - } - #qr input[name=resto] { - width: 80px; - } - #qr button + input[type=file] { - position: absolute; - opacity: 0; - pointer-events: none; - } - #qr .wat { - display: inline-block; - width: 16px; - overflow: hidden; - position: relative; - vertical-align: text-top; - } - #qr .wat input { - opacity: 0; - position: absolute; - left: 0; - } ' Main.init() From 3fa6bab8eda13b3714904f6de0933a12e49c6c4c Mon Sep 17 00:00:00 2001 From: Nicolas Stepien Date: Sat, 26 Nov 2011 05:09:05 +0100 Subject: [PATCH 077/169] Do not underline pentadactyled anchors. --- 4chan_x.user.js | 3 +++ script.coffee | 3 +++ 2 files changed, 6 insertions(+) diff --git a/4chan_x.user.js b/4chan_x.user.js index 6635bce7b..5bc0d2096 100644 --- a/4chan_x.user.js +++ b/4chan_x.user.js @@ -3031,6 +3031,9 @@ }, css: '\ /* dialog styling */\ + a[href="javascript:;"] {\ + text-decoration: none;\ + }\ div.dialog {\ border: 1px solid;\ }\ diff --git a/script.coffee b/script.coffee index fbd6a345c..d3ef50426 100644 --- a/script.coffee +++ b/script.coffee @@ -2406,6 +2406,9 @@ Main = css: ' /* dialog styling */ + a[href="javascript:;"] { + text-decoration: none; + } div.dialog { border: 1px solid; } From f09bfa48e261d23aec6c4664e9b53aea013a008b Mon Sep 17 00:00:00 2001 From: Nicolas Stepien Date: Sat, 26 Nov 2011 18:53:27 +0100 Subject: [PATCH 078/169] Fix forward links for Firefox. WTF is wrong with that browser, seriously. --- 4chan_x.user.js | 2 +- script.coffee | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/4chan_x.user.js b/4chan_x.user.js index 5bc0d2096..28dda4c5c 100644 --- a/4chan_x.user.js +++ b/4chan_x.user.js @@ -2486,7 +2486,7 @@ qp.innerHTML = el.innerHTML; if (conf['Quote Highlighting']) $.addClass(el, 'qphl'); if (/\bbacklink\b/.test(this.className)) { - replyID = $.x('preceding::input', this).name; + replyID = $.x('preceding-sibling::input', this.parentNode).name; _ref = $$('.quotelink', qp); _results = []; for (_i = 0, _len = _ref.length; _i < _len; _i++) { diff --git a/script.coffee b/script.coffee index d3ef50426..35fa2920c 100644 --- a/script.coffee +++ b/script.coffee @@ -1936,7 +1936,7 @@ quotePreview = qp.innerHTML = el.innerHTML $.addClass el, 'qphl' if conf['Quote Highlighting'] if /\bbacklink\b/.test @className - replyID = $.x('preceding::input', @).name + replyID = $.x('preceding-sibling::input', @parentNode).name for quote in $$ '.quotelink', qp if quote.hash[1..] is replyID quote.className = 'forwardlink' From dca9725081b2cfc00a3281730a3a6d50f606009a Mon Sep 17 00:00:00 2001 From: Nicolas Stepien Date: Sat, 26 Nov 2011 22:06:42 +0100 Subject: [PATCH 079/169] Remove redundant ids. --- 4chan_x.user.js | 12 ++++++------ script.coffee | 12 ++++++------ 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/4chan_x.user.js b/4chan_x.user.js index 28dda4c5c..8420b55f5 100644 --- a/4chan_x.user.js +++ b/4chan_x.user.js @@ -1249,11 +1249,11 @@
        \
        \ \ -
        \ +
        \ \ \ \ -
        \ +
        \ Use regular expressions, one per line.
        \ For example, /weeaboo/i will filter posts containing `weeaboo` case-insensitive.\

        Name:

        \ @@ -1266,7 +1266,7 @@

        Image MD5:

        \
        \ \ -
        \ +
        \
          \ Backlink formatting\
        • :
        • \ @@ -1283,7 +1283,7 @@
        \
        \ \ -
        \ +
        \ \ \ \ @@ -1326,7 +1326,7 @@ $.on($('input', li), 'click', $.cb.checked); $.add(ul, li); } - $.add($('#main', dialog), ul); + $.add($('#main_tab + div', dialog), ul); } hiddenThreads = $.get("hiddenThreads/" + g.BOARD + "/", {}); hiddenNum = Object.keys(g.hiddenReplies).length + Object.keys(hiddenThreads).length; @@ -1345,7 +1345,7 @@ (time = $('[name=time]', dialog)).value = conf['time']; $.on(back, 'keyup', options.backlink); $.on(time, 'keyup', options.time); - _ref3 = $$('#keybinds input', dialog); + _ref3 = $$('#keybinds_tab + div input', dialog); for (_j = 0, _len2 = _ref3.length; _j < _len2; _j++) { input = _ref3[_j]; input.type = 'text'; diff --git a/script.coffee b/script.coffee index 35fa2920c..f16aaa625 100644 --- a/script.coffee +++ b/script.coffee @@ -901,11 +901,11 @@ options =
        -
        +
        -
        +
        Use regular expressions, one per line.
        For example, /weeaboo/i will filter posts containing `weeaboo` case-insensitive.

        Name:

        @@ -918,7 +918,7 @@ options =

        Image MD5:

        -
        +
          Backlink formatting
        • :
        • @@ -935,7 +935,7 @@ options =
        -
        +
        ActionsKeybinds
        Close Options or QR
        @@ -974,7 +974,7 @@ options = innerHTML: ": #{description}" $.on $('input', li), 'click', $.cb.checked $.add ul, li - $.add $('#main', dialog), ul + $.add $('#main_tab + div', dialog), ul hiddenThreads = $.get "hiddenThreads/#{g.BOARD}/", {} hiddenNum = Object.keys(g.hiddenReplies).length + Object.keys(hiddenThreads).length @@ -995,7 +995,7 @@ options = $.on time, 'keyup', options.time #keybinds - for input in $$ '#keybinds input', dialog + for input in $$ '#keybinds_tab + div input', dialog input.type = 'text' input.value = conf[input.name] $.on input, 'keydown', options.keybind From d93860f0558d6f92f5709c344b323eec4e474b53 Mon Sep 17 00:00:00 2001 From: Nicolas Stepien Date: Sat, 26 Nov 2011 22:15:40 +0100 Subject: [PATCH 080/169] No need to fool the cache anymore. See moot's announcement: "We will also be sending proper Last-Modified headers on HTML" --- 4chan_x.user.js | 2 +- script.coffee | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/4chan_x.user.js b/4chan_x.user.js index 8420b55f5..4a9444e83 100644 --- a/4chan_x.user.js +++ b/4chan_x.user.js @@ -2026,7 +2026,7 @@ var cb, url, _ref; updater.timer.textContent = 0; if ((_ref = updater.request) != null) _ref.abort(); - url = location.pathname + '?' + Date.now(); + url = location.pathname; cb = updater.cb.update; return updater.request = $.ajax(url, cb); } diff --git a/script.coffee b/script.coffee index f16aaa625..366377a66 100644 --- a/script.coffee +++ b/script.coffee @@ -1607,7 +1607,7 @@ updater = update: -> updater.timer.textContent = 0 updater.request?.abort() - url = location.pathname + '?' + Date.now() # fool the cache + url = location.pathname cb = updater.cb.update updater.request = $.ajax url, cb From 69e465ea5b6d75e23ae5e528040430aca6ed7f4a Mon Sep 17 00:00:00 2001 From: Nicolas Stepien Date: Sat, 26 Nov 2011 22:31:15 +0100 Subject: [PATCH 081/169] Redundant braces. --- script.coffee | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/script.coffee b/script.coffee index 366377a66..aee14b183 100644 --- a/script.coffee +++ b/script.coffee @@ -1861,7 +1861,7 @@ quoteInline = # remove the corresponding table or loading td $.rm $.x "following::*[@id='i#{id}']", @ else - return if $.x("ancestor::*[@id='#{id}']", @) + return if $.x "ancestor::*[@id='#{id}']", @ quoteInline.add @, id @classList.toggle 'inlined' From 7c103f99f29fa1076423b94ea9b3a18e9032dbd4 Mon Sep 17 00:00:00 2001 From: Nicolas Stepien Date: Sat, 26 Nov 2011 22:41:29 +0100 Subject: [PATCH 082/169] Firstrun will open the options. --- 4chan_x.user.js | 6 +++++- script.coffee | 3 +++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/4chan_x.user.js b/4chan_x.user.js index 4a9444e83..637a8bdc8 100644 --- a/4chan_x.user.js +++ b/4chan_x.user.js @@ -1228,7 +1228,11 @@ href: 'javascript:;' }); $.on(a, 'click', options.dialog); - return $.replace(home, a); + $.replace(home, a); + if (!$.get('firstrun')) { + options.dialog(); + return $.set('firstrun', true); + } }, dialog: function() { var arr, back, checked, description, dialog, hiddenNum, hiddenThreads, input, key, li, obj, overlay, ta, time, ul, _i, _j, _len, _len2, _ref, _ref2, _ref3; diff --git a/script.coffee b/script.coffee index aee14b183..c591d7dd9 100644 --- a/script.coffee +++ b/script.coffee @@ -882,6 +882,9 @@ options = href: 'javascript:;' $.on a, 'click', options.dialog $.replace home, a + unless $.get 'firstrun' + options.dialog() + $.set 'firstrun', true dialog: -> dialog = ui.dialog 'options', '', ' From 8862e3dbccd24b81d4d47805914c92f49809a155 Mon Sep 17 00:00:00 2001 From: Nicolas Stepien Date: Sat, 26 Nov 2011 23:34:01 +0100 Subject: [PATCH 083/169] Bump to version 2.21.0, add stable updaptes to the master branch. --- 4chan_x.user.js | 24 +++++++++++++++++++----- Cakefile | 6 +++++- changelog | 4 ++-- script.coffee | 7 +++++++ 4 files changed, 33 insertions(+), 8 deletions(-) diff --git a/4chan_x.user.js b/4chan_x.user.js index 637a8bdc8..3d5f79048 100644 --- a/4chan_x.user.js +++ b/4chan_x.user.js @@ -1,5 +1,6 @@ // ==UserScript== // @name 4chan x +// @version 2.21.0 // @namespace aeosynth // @description Adds various features. // @copyright 2009-2011 James Campos @@ -13,7 +14,8 @@ /* LICENSE * * Copyright (c) 2009-2011 James Campos - * http://aeosynth.github.com/4chan-x/ + * http://mayhemydg.github.com/4chan-x/ + * 4chan x 2.21.0 * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation @@ -64,7 +66,7 @@ */ (function() { - var $, $$, DAY, Favicon, HOUR, MINUTE, Main, NAMESPACE, Recaptcha, SECOND, Time, anonymize, conf, config, cooldown, d, expandComment, expandThread, filter, flatten, g, getTitle, imgExpand, imgGif, imgHover, key, keybinds, log, nav, options, qr, quoteBacklink, quoteInline, quoteOP, quotePreview, redirect, replyHiding, reportButton, revealSpoilers, sauce, strikethroughQuotes, threadHiding, threadStats, threading, titlePost, ui, unread, updater, val, watcher; + var $, $$, DAY, Favicon, HOUR, MINUTE, Main, NAMESPACE, Recaptcha, SECOND, Time, VERSION, anonymize, conf, config, cooldown, d, expandComment, expandThread, filter, flatten, g, getTitle, imgExpand, imgGif, imgHover, key, keybinds, log, nav, options, qr, quoteBacklink, quoteInline, quoteOP, quotePreview, redirect, replyHiding, reportButton, revealSpoilers, sauce, strikethroughQuotes, threadHiding, threadStats, threading, titlePost, ui, unread, updater, val, watcher; var __slice = Array.prototype.slice; config = { @@ -77,7 +79,8 @@ 'Comment Expansion': [true, 'Expand too long comments'], 'Thread Expansion': [true, 'View all replies'], 'Index Navigation': [true, 'Navigate to previous / next thread'], - 'Reply Navigation': [false, 'Navigate to top / bottom of thread'] + 'Reply Navigation': [false, 'Navigate to top / bottom of thread'], + 'Check for Updates': [true, 'Check for updated versions of 4chan X'] }, Filtering: { 'Anonymize': [false, 'Make everybody anonymous'], @@ -208,6 +211,8 @@ NAMESPACE = '4chan_x.'; + VERSION = '2.21.0'; + SECOND = 1000; MINUTE = 60 * SECOND; @@ -2963,6 +2968,11 @@ $.addStyle(Main.css); threading.init(); Favicon.init(); + if (Main.reqUpdate && conf['Check for Updates']) { + $.add(d.head, $.el('script', { + src: 'https://raw.github.com/mayhemydg/4chan-x/master/latest.js' + })); + } if ((form = $('form[name=post]')) && (canPost = !!$('#recaptcha_response_field'))) { Recaptcha.init(); if (g.REPLY && conf['Auto Watch Reply'] && conf['Thread Watcher']) { @@ -3013,9 +3023,13 @@ return options.init(); }, message: function(e) { - var data, origin; + var data, location, origin; origin = e.origin, data = e.data; - if (origin === 'http://sys.4chan.org') return qr.message(data); + if (origin === 'http://sys.4chan.org') { + return qr.message(data); + } else if (data.version !== VERSION && confirm('An updated version of 4chan X is available, would you like to install it now?')) { + return location = "https://raw.github.com/mayhemydg/4chan-x/" + data.version + "/4chan_x.user.js"; + } }, node: function(e) { var callback, target, _i, _len, _ref, _results; diff --git a/Cakefile b/Cakefile index ecdfdada0..95a9112c1 100644 --- a/Cakefile +++ b/Cakefile @@ -2,9 +2,12 @@ {exec} = require 'child_process' fs = require 'fs' +VERSION = '2.21.0' + HEADER = """ // ==UserScript== // @name 4chan x +// @version #{VERSION} // @namespace aeosynth // @description Adds various features. // @copyright 2009-2011 James Campos @@ -18,7 +21,8 @@ HEADER = """ /* LICENSE * * Copyright (c) 2009-2011 James Campos - * http://aeosynth.github.com/4chan-x/ + * http://mayhemydg.github.com/4chan-x/ + * 4chan x #{VERSION} * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation diff --git a/changelog b/changelog index 5e4949c76..2ba9d2244 100644 --- a/changelog +++ b/changelog @@ -1,4 +1,6 @@ master + +2.21.0 - mayhem initiate 4chan X earlier performance improvements @@ -7,8 +9,6 @@ master automatically reload expanded pictures on error handle bans with the thread updater use unread favicons by ferongr -- aeosynth - quick reply redesign 2.20.3 - mayhem diff --git a/script.coffee b/script.coffee index c591d7dd9..7f2a580cd 100644 --- a/script.coffee +++ b/script.coffee @@ -9,6 +9,7 @@ config = 'Thread Expansion': [true, 'View all replies'] 'Index Navigation': [true, 'Navigate to previous / next thread'] 'Reply Navigation': [false, 'Navigate to top / bottom of thread'] + 'Check for Updates': [true, 'Check for updated versions of 4chan X'] Filtering: 'Anonymize': [false, 'Make everybody anonymous'] 'Filter': [false, 'Self-moderation placebo'] @@ -121,6 +122,7 @@ conf = {} ) null, config NAMESPACE = '4chan_x.' +VERSION = '2.21.0' SECOND = 1000 MINUTE = 60*SECOND HOUR = 60*MINUTE @@ -2319,6 +2321,9 @@ Main = threading.init() Favicon.init() + if Main.reqUpdate and conf['Check for Updates'] + $.add d.head, $.el 'script', src: 'https://raw.github.com/mayhemydg/4chan-x/master/latest.js' + #recaptcha may be blocked, eg by noscript if (form = $ 'form[name=post]') and (canPost = !!$ '#recaptcha_response_field') Recaptcha.init() @@ -2397,6 +2402,8 @@ Main = {origin, data} = e if origin is 'http://sys.4chan.org' qr.message data + else if data.version isnt VERSION and confirm 'An updated version of 4chan X is available, would you like to install it now?' + location = "https://raw.github.com/mayhemydg/4chan-x/#{data.version}/4chan_x.user.js" node: (e) -> {target} = e From a334f760549e08f8b45f8e39241aa82375146000 Mon Sep 17 00:00:00 2001 From: Nicolas Stepien Date: Sat, 26 Nov 2011 23:37:14 +0100 Subject: [PATCH 084/169] Add files. --- latest.js | 1 + readme.md | 9 +++++++++ 2 files changed, 10 insertions(+) create mode 100644 latest.js create mode 100644 readme.md diff --git a/latest.js b/latest.js new file mode 100644 index 000000000..129ebdc29 --- /dev/null +++ b/latest.js @@ -0,0 +1 @@ +postMessage({version:'2.21.0'},'*'); diff --git a/readme.md b/readme.md new file mode 100644 index 000000000..4aaa8c79e --- /dev/null +++ b/readme.md @@ -0,0 +1,9 @@ +# Get 4chan X [HERE](http://mayhemydg.github.com/4chan-x/). + +# Building + +[install nodejs and npm](https://github.com/joyent/node/wiki/Installation), +install [coffee-script](https://github.com/jashkenas/coffee-script/) with +`npm install -g coffee-script`, clone 4chan x, cd into it and actually build +with `cake build`. for development (continuous builds), run `cake dev &`. +kill the process with `killall node`. From 970fea92bbf4a74c5e4da742f82ac085abdc7f8d Mon Sep 17 00:00:00 2001 From: Nicolas Stepien Date: Sun, 27 Nov 2011 02:30:42 +0100 Subject: [PATCH 085/169] Fix Opera. Release 2.21.1. --- 4chan_x.user.js | 10 +++++----- Cakefile | 2 +- changelog | 4 ++++ latest.js | 2 +- script.coffee | 6 +++--- 5 files changed, 14 insertions(+), 10 deletions(-) diff --git a/4chan_x.user.js b/4chan_x.user.js index 3d5f79048..8dbd699b0 100644 --- a/4chan_x.user.js +++ b/4chan_x.user.js @@ -1,6 +1,6 @@ // ==UserScript== // @name 4chan x -// @version 2.21.0 +// @version 2.21.1 // @namespace aeosynth // @description Adds various features. // @copyright 2009-2011 James Campos @@ -15,7 +15,7 @@ * * Copyright (c) 2009-2011 James Campos * http://mayhemydg.github.com/4chan-x/ - * 4chan x 2.21.0 + * 4chan x 2.21.1 * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation @@ -211,7 +211,7 @@ NAMESPACE = '4chan_x.'; - VERSION = '2.21.0'; + VERSION = '2.21.1'; SECOND = 1000; @@ -1753,7 +1753,7 @@ el = _ref[_i]; el.tabIndex = 1; } - return $.bind($('#recaptcha_response_field'), 'keydown', Recaptcha.listener); + return $.on($('#recaptcha_response_field'), 'keydown', Recaptcha.listener); }, listener: function(e) { if (e.keyCode === 8 && this.value === '') return Recaptcha.reload(); @@ -2976,7 +2976,7 @@ if ((form = $('form[name=post]')) && (canPost = !!$('#recaptcha_response_field'))) { Recaptcha.init(); if (g.REPLY && conf['Auto Watch Reply'] && conf['Thread Watcher']) { - $.bind(form, 'submit', function() { + $.on(form, 'submit', function() { if ($('img.favicon').src === Favicon.empty) { return watcher.watch(null, g.THREAD_ID); } diff --git a/Cakefile b/Cakefile index 95a9112c1..54b0e5e7c 100644 --- a/Cakefile +++ b/Cakefile @@ -2,7 +2,7 @@ {exec} = require 'child_process' fs = require 'fs' -VERSION = '2.21.0' +VERSION = '2.21.1' HEADER = """ // ==UserScript== diff --git a/changelog b/changelog index 2ba9d2244..7369019ff 100644 --- a/changelog +++ b/changelog @@ -1,5 +1,9 @@ master +2.21.1 +- mayhem + fix Opera + 2.21.0 - mayhem initiate 4chan X earlier diff --git a/latest.js b/latest.js index 129ebdc29..d69b0c808 100644 --- a/latest.js +++ b/latest.js @@ -1 +1 @@ -postMessage({version:'2.21.0'},'*'); +postMessage({version:'2.21.1'},'*'); diff --git a/script.coffee b/script.coffee index 7f2a580cd..1c9cd7a59 100644 --- a/script.coffee +++ b/script.coffee @@ -122,7 +122,7 @@ conf = {} ) null, config NAMESPACE = '4chan_x.' -VERSION = '2.21.0' +VERSION = '2.21.1' SECOND = 1000 MINUTE = 60*SECOND HOUR = 60*MINUTE @@ -1372,7 +1372,7 @@ Recaptcha = #hack to tab from comment straight to recaptcha for el in $$ '#recaptcha_table a' el.tabIndex = 1 - $.bind $('#recaptcha_response_field'), 'keydown', Recaptcha.listener + $.on $('#recaptcha_response_field'), 'keydown', Recaptcha.listener listener: (e) -> if e.keyCode is 8 and @value is '' # backspace to reload Recaptcha.reload() @@ -2328,7 +2328,7 @@ Main = if (form = $ 'form[name=post]') and (canPost = !!$ '#recaptcha_response_field') Recaptcha.init() if g.REPLY and conf['Auto Watch Reply'] and conf['Thread Watcher'] - $.bind form, 'submit', -> if $('img.favicon').src is Favicon.empty + $.on form, 'submit', -> if $('img.favicon').src is Favicon.empty watcher.watch null, g.THREAD_ID #major features From 29ba27fc48271ae92555806e7b169bf35afd2ab8 Mon Sep 17 00:00:00 2001 From: Nicolas Stepien Date: Sun, 27 Nov 2011 03:08:40 +0100 Subject: [PATCH 086/169] Fix QR keybinds. --- 4chan_x.user.js | 10 +++++----- script.coffee | 10 +++++----- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/4chan_x.user.js b/4chan_x.user.js index 8dbd699b0..b7a0d24c7 100644 --- a/4chan_x.user.js +++ b/4chan_x.user.js @@ -900,7 +900,7 @@ case conf.close: if (o = $('#overlay')) { $.rm(o); - } else if (qr.qr) { + } else if (qr.el) { qr.close(); } break; @@ -969,8 +969,8 @@ if ((_ref3 = $('input[value=Previous]')) != null) _ref3.click(); break; case conf.submit: - if (qr.qr) { - qr.submit.call($('form', qr.qr)); + if (qr.el) { + qr.submit.call($('form', qr.el)); } else { $('.postarea form').submit(); } @@ -1068,8 +1068,8 @@ if (quote) { return qr.quote.call($('.quotejs + a', $('.replyhl', thread) || thread)); } else { - if (qr.qr) { - return $('textarea', qr.qr).focus(); + if (qr.el) { + return $('textarea', qr.el).focus(); } else { return qr.dialog('', thread != null ? thread.firstChild.id : void 0); } diff --git a/script.coffee b/script.coffee index 1c9cd7a59..c58abc191 100644 --- a/script.coffee +++ b/script.coffee @@ -645,7 +645,7 @@ keybinds = when conf.close if o = $ '#overlay' $.rm o - else if qr.qr + else if qr.el qr.close() when conf.spoiler ta = e.target @@ -697,8 +697,8 @@ keybinds = when conf.previousPage $('input[value=Previous]')?.click() when conf.submit - if qr.qr - qr.submit.call $ 'form', qr.qr + if qr.el + qr.submit.call $ 'form', qr.el else $('.postarea form').submit() when conf.unreadCountTo0 @@ -745,8 +745,8 @@ keybinds = if quote qr.quote.call $ '.quotejs + a', $('.replyhl', thread) or thread else - if qr.qr - $('textarea', qr.qr).focus() + if qr.el + $('textarea', qr.el).focus() else qr.dialog '', thread?.firstChild.id From 85c7032d55c0feef036bc2b7016cdb63637734c1 Mon Sep 17 00:00:00 2001 From: Nicolas Stepien Date: Sun, 27 Nov 2011 17:50:46 +0100 Subject: [PATCH 087/169] Fix time formatting year in Opera. --- 4chan_x.user.js | 2 +- changelog | 3 +++ script.coffee | 2 +- 3 files changed, 5 insertions(+), 2 deletions(-) diff --git a/4chan_x.user.js b/4chan_x.user.js index b7a0d24c7..23e1af561 100644 --- a/4chan_x.user.js +++ b/4chan_x.user.js @@ -2203,7 +2203,7 @@ Time.foo(); chanOffset = 5 - new Date().getTimezoneOffset() / 60; if ($.isDST()) chanOffset--; - this.parse = Date.parse('10/11/11(Tue)18:53') ? function(node) { + this.parse = Date.parse('10/11/11(Tue)18:53' === 1318351980000) ? function(node) { return new Date(Date.parse(node.textContent) + chanOffset * HOUR); } : function(node) { var day, hour, min, month, year, _, _ref; diff --git a/changelog b/changelog index 7369019ff..e40826936 100644 --- a/changelog +++ b/changelog @@ -1,4 +1,7 @@ master +- mayhem + fix time formatting year in Opera + fix QR keybinds 2.21.1 - mayhem diff --git a/script.coffee b/script.coffee index c58abc191..975ce5b3c 100644 --- a/script.coffee +++ b/script.coffee @@ -1736,7 +1736,7 @@ Time = chanOffset-- if $.isDST() @parse = - if Date.parse '10/11/11(Tue)18:53' + if Date.parse '10/11/11(Tue)18:53' is 1318351980000 (node) -> new Date Date.parse(node.textContent) + chanOffset*HOUR else # Firefox the Archaic cannot parse 4chan's time (node) -> From f57cfb1fe0807c36945b2c27512cad53b118cb71 Mon Sep 17 00:00:00 2001 From: Nicolas Stepien Date: Sun, 27 Nov 2011 18:26:44 +0100 Subject: [PATCH 088/169] Fix QR posts getting swallowed by sys.4chan.org --- 4chan_x.user.js | 11 ++++++----- changelog | 1 + script.coffee | 8 +++++--- 3 files changed, 12 insertions(+), 8 deletions(-) diff --git a/4chan_x.user.js b/4chan_x.user.js index 23e1af561..cf51a0a50 100644 --- a/4chan_x.user.js +++ b/4chan_x.user.js @@ -1558,7 +1558,10 @@ $('iframe[name=iframe]').src = 'about:blank'; fileCount = $('#files', qr.el).childElementCount; tc = data.textContent; - if (tc) { + if (tc !== "Post successful!") { + if (tc === void 0) { + data.textContent = "Connection error with sys.4chan.org."; + } $.extend($('#error', qr.el), data); $('#recaptcha_response_field', qr.el).value = ''; $('#autohide', qr.el).checked = false; @@ -1699,10 +1702,8 @@ */ $.globalEval(function() { var data, node, _ref; - data = { - to: 'qr.message' - }; - if (node = (_ref = document.querySelector('table font b')) != null ? _ref.firstChild : void 0) { + data = {}; + if (node = (_ref = document.querySelector('td b')) != null ? _ref.firstChild : void 0) { data.textContent = node.textContent; data.href = node.href; } diff --git a/changelog b/changelog index e40826936..3cafc99b6 100644 --- a/changelog +++ b/changelog @@ -2,6 +2,7 @@ master - mayhem fix time formatting year in Opera fix QR keybinds + fix QR posts getting swallowed by sys.4chan.org 2.21.1 - mayhem diff --git a/script.coffee b/script.coffee index 975ce5b3c..f48f6ac61 100644 --- a/script.coffee +++ b/script.coffee @@ -1195,7 +1195,9 @@ qr = fileCount = $('#files', qr.el).childElementCount tc = data.textContent - if tc # error message + if tc isnt "Post successful!" # error message + if tc is undefined + data.textContent = "Connection error with sys.4chan.org." $.extend $('#error', qr.el), data $('#recaptcha_response_field', qr.el).value = '' $('#autohide', qr.el).checked = false @@ -1324,8 +1326,8 @@ qr = in the global context. ### $.globalEval -> - data = to: 'qr.message' - if node = document.querySelector('table font b')?.firstChild + data = {} + if node = document.querySelector('td b')?.firstChild data.textContent = node.textContent data.href = node.href parent.postMessage data, '*' From ea01038cbc9ea6e7586353464a7777282f252d4c Mon Sep 17 00:00:00 2001 From: Nicolas Stepien Date: Sun, 27 Nov 2011 18:35:03 +0100 Subject: [PATCH 089/169] Put thread creation auto-watch back. --- 4chan_x.user.js | 7 +++++++ script.coffee | 6 ++++++ 2 files changed, 13 insertions(+) diff --git a/4chan_x.user.js b/4chan_x.user.js index cf51a0a50..4fb7aca1b 100644 --- a/4chan_x.user.js +++ b/4chan_x.user.js @@ -2058,6 +2058,13 @@ $.before(input, favicon); } watcher.refresh(); + if (conf['Auto Watch']) { + if (!g.REPLY) { + $('.postarea form').action += '?watch'; + } else if (/watch/.test(location.search) && $('img.favicon').src === Favicon.empty) { + watcher.watch(null, g.THREAD_ID); + } + } return $.on(window, 'storage', function(e) { if (e.key === ("" + NAMESPACE + "watched")) return watcher.refresh(); }); diff --git a/script.coffee b/script.coffee index f48f6ac61..d3fda7402 100644 --- a/script.coffee +++ b/script.coffee @@ -1635,6 +1635,12 @@ watcher = #populate watcher, display watch buttons watcher.refresh() + if conf['Auto Watch'] + unless g.REPLY + $('.postarea form').action += '?watch' + else if /watch/.test(location.search) and $('img.favicon').src is Favicon.empty + watcher.watch null, g.THREAD_ID + $.on window, 'storage', (e) -> watcher.refresh() if e.key is "#{NAMESPACE}watched" refresh: -> From aecf386692b7fd4be1e85319c5d11d1854579850 Mon Sep 17 00:00:00 2001 From: Nicolas Stepien Date: Sun, 27 Nov 2011 18:36:50 +0100 Subject: [PATCH 090/169] Release 2.21.2. --- 4chan_x.user.js | 6 +++--- Cakefile | 2 +- changelog | 2 ++ latest.js | 2 +- script.coffee | 2 +- 5 files changed, 8 insertions(+), 6 deletions(-) diff --git a/4chan_x.user.js b/4chan_x.user.js index 4fb7aca1b..c27d35f1e 100644 --- a/4chan_x.user.js +++ b/4chan_x.user.js @@ -1,6 +1,6 @@ // ==UserScript== // @name 4chan x -// @version 2.21.1 +// @version 2.21.2 // @namespace aeosynth // @description Adds various features. // @copyright 2009-2011 James Campos @@ -15,7 +15,7 @@ * * Copyright (c) 2009-2011 James Campos * http://mayhemydg.github.com/4chan-x/ - * 4chan x 2.21.1 + * 4chan x 2.21.2 * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation @@ -211,7 +211,7 @@ NAMESPACE = '4chan_x.'; - VERSION = '2.21.1'; + VERSION = '2.21.2'; SECOND = 1000; diff --git a/Cakefile b/Cakefile index 54b0e5e7c..b0d5fbfe3 100644 --- a/Cakefile +++ b/Cakefile @@ -2,7 +2,7 @@ {exec} = require 'child_process' fs = require 'fs' -VERSION = '2.21.1' +VERSION = '2.21.2' HEADER = """ // ==UserScript== diff --git a/changelog b/changelog index 3cafc99b6..eec6756ba 100644 --- a/changelog +++ b/changelog @@ -1,4 +1,6 @@ master + +2.21.2 - mayhem fix time formatting year in Opera fix QR keybinds diff --git a/latest.js b/latest.js index d69b0c808..103a1306e 100644 --- a/latest.js +++ b/latest.js @@ -1 +1 @@ -postMessage({version:'2.21.1'},'*'); +postMessage({version:'2.21.2'},'*'); diff --git a/script.coffee b/script.coffee index d3fda7402..2d88eb503 100644 --- a/script.coffee +++ b/script.coffee @@ -122,7 +122,7 @@ conf = {} ) null, config NAMESPACE = '4chan_x.' -VERSION = '2.21.1' +VERSION = '2.21.2' SECOND = 1000 MINUTE = 60*SECOND HOUR = 60*MINUTE From 925b7fc795da20c5f56ede19150e096e555d9d7e Mon Sep 17 00:00:00 2001 From: Nicolas Stepien Date: Sun, 27 Nov 2011 19:02:46 +0100 Subject: [PATCH 091/169] Detect browser engine. --- 4chan_x.user.js | 4 +++- script.coffee | 1 + 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/4chan_x.user.js b/4chan_x.user.js index c27d35f1e..f0c043e59 100644 --- a/4chan_x.user.js +++ b/4chan_x.user.js @@ -66,7 +66,7 @@ */ (function() { - var $, $$, DAY, Favicon, HOUR, MINUTE, Main, NAMESPACE, Recaptcha, SECOND, Time, VERSION, anonymize, conf, config, cooldown, d, expandComment, expandThread, filter, flatten, g, getTitle, imgExpand, imgGif, imgHover, key, keybinds, log, nav, options, qr, quoteBacklink, quoteInline, quoteOP, quotePreview, redirect, replyHiding, reportButton, revealSpoilers, sauce, strikethroughQuotes, threadHiding, threadStats, threading, titlePost, ui, unread, updater, val, watcher; + var $, $$, DAY, Favicon, HOUR, MINUTE, Main, NAMESPACE, Recaptcha, SECOND, Time, VERSION, anonymize, conf, config, cooldown, d, engine, expandComment, expandThread, filter, flatten, g, getTitle, imgExpand, imgGif, imgHover, key, keybinds, log, nav, options, qr, quoteBacklink, quoteInline, quoteOP, quotePreview, redirect, replyHiding, reportButton, revealSpoilers, sauce, strikethroughQuotes, threadHiding, threadStats, threading, titlePost, ui, unread, updater, val, watcher; var __slice = Array.prototype.slice; config = { @@ -221,6 +221,8 @@ DAY = 24 * HOUR; + engine = /WebKit|Presto|Gecko/.exec(navigator.userAgent)[0]; + d = document; g = { diff --git a/script.coffee b/script.coffee index 2d88eb503..fa4f0fec0 100644 --- a/script.coffee +++ b/script.coffee @@ -127,6 +127,7 @@ SECOND = 1000 MINUTE = 60*SECOND HOUR = 60*MINUTE DAY = 24*HOUR +engine = /WebKit|Presto|Gecko/.exec(navigator.userAgent)[0] d = document g = callbacks: [] From a2f1c835039f8a526b009b058876bf10caee07d6 Mon Sep 17 00:00:00 2001 From: Nicolas Stepien Date: Sun, 27 Nov 2011 19:20:35 +0100 Subject: [PATCH 092/169] Clone and replace favicon only on Firefox. --- 4chan_x.user.js | 6 ++++-- script.coffee | 5 +++-- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/4chan_x.user.js b/4chan_x.user.js index f0c043e59..cce234d7f 100644 --- a/4chan_x.user.js +++ b/4chan_x.user.js @@ -2684,8 +2684,10 @@ l = unread.replies.length; favicon = $('link[rel="shortcut icon"]', d.head); favicon.href = g.dead ? l ? Favicon.unreadDead : Favicon.dead : l ? Favicon.unread : Favicon["default"]; - clone = favicon.cloneNode(true); - return $.replace(favicon, clone); + if (engine === "Gecko") { + clone = favicon.cloneNode(true); + return $.replace(favicon, clone); + } } }; diff --git a/script.coffee b/script.coffee index fa4f0fec0..f76caa804 100644 --- a/script.coffee +++ b/script.coffee @@ -2090,8 +2090,9 @@ Favicon = Favicon.default #XXX `favicon.href = href` doesn't work on Firefox - clone = favicon.cloneNode true - $.replace favicon, clone + if engine is "Gecko" + clone = favicon.cloneNode true + $.replace favicon, clone redirect = -> switch g.BOARD From b7117afaeb26c6eff23e3df931a5f86880c51b6d Mon Sep 17 00:00:00 2001 From: Nicolas Stepien Date: Sun, 27 Nov 2011 19:23:19 +0100 Subject: [PATCH 093/169] Use the moz selector hack only on Firefox. --- 4chan_x.user.js | 2 +- script.coffee | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/4chan_x.user.js b/4chan_x.user.js index cce234d7f..2337972b5 100644 --- a/4chan_x.user.js +++ b/4chan_x.user.js @@ -2855,7 +2855,7 @@ img = $.el('img', { src: a.href }); - if (a.parentNode.className !== 'op') { + if (engine === "Gecko" && a.parentNode.className !== 'op') { filesize = $('.filesize', a.parentNode); _ref = filesize.textContent.match(/(\d+)x/), _ = _ref[0], max = _ref[1]; img.style.maxWidth = "-moz-calc(" + max + "px)"; diff --git a/script.coffee b/script.coffee index f76caa804..53129bc54 100644 --- a/script.coffee +++ b/script.coffee @@ -2188,7 +2188,7 @@ imgExpand = a = thumb.parentNode img = $.el 'img', src: a.href - unless a.parentNode.className is 'op' + if engine is "Gecko" and a.parentNode.className isnt 'op' filesize = $ '.filesize', a.parentNode [_, max] = filesize.textContent.match /(\d+)x/ img.style.maxWidth = "-moz-calc(#{max}px)" From e21df3bb60ff2659e47dac1f299eb4d204127e0d Mon Sep 17 00:00:00 2001 From: Nicolas Stepien Date: Sun, 27 Nov 2011 20:36:56 +0100 Subject: [PATCH 094/169] Fix locked threads icons with fit screen/width. --- 4chan_x.user.js | 6 +++--- changelog | 2 ++ script.coffee | 6 +++--- 3 files changed, 8 insertions(+), 6 deletions(-) diff --git a/4chan_x.user.js b/4chan_x.user.js index 2337972b5..03dd6ee8b 100644 --- a/4chan_x.user.js +++ b/4chan_x.user.js @@ -2906,7 +2906,7 @@ return $.prepend(form, controls); }, resize: function() { - return imgExpand.style.innerHTML = ".fitheight img + img {max-height:" + d.body.clientHeight + "px;}"; + return imgExpand.style.innerHTML = ".fitheight [md5] + img {max-height:" + d.body.clientHeight + "px;}"; } }; @@ -3098,10 +3098,10 @@ float: left;\ pointer-events: none;\ }\ - img[md5], img + img {\ + [md5], [md5] + img {\ pointer-events: all;\ }\ - .fitwidth img + img {\ + .fitwidth [md5] + img {\ max-width: 100%;\ width: -moz-calc(100%); /* hack so only firefox sees this */\ }\ diff --git a/changelog b/changelog index eec6756ba..ee99cdb18 100644 --- a/changelog +++ b/changelog @@ -1,4 +1,6 @@ master +- mayhem + fix locked thread icons with fit width/screen enabled on Firefox 2.21.2 - mayhem diff --git a/script.coffee b/script.coffee index 53129bc54..e8fc1c143 100644 --- a/script.coffee +++ b/script.coffee @@ -2229,7 +2229,7 @@ imgExpand = $.prepend form, controls resize: -> - imgExpand.style.innerHTML = ".fitheight img + img {max-height:#{d.body.clientHeight}px;}" + imgExpand.style.innerHTML = ".fitheight [md5] + img {max-height:#{d.body.clientHeight}px;}" Main = init: -> @@ -2463,10 +2463,10 @@ Main = float: left; pointer-events: none; } - img[md5], img + img { + [md5], [md5] + img { pointer-events: all; } - .fitwidth img + img { + .fitwidth [md5] + img { max-width: 100%; width: -moz-calc(100%); /* hack so only firefox sees this */ } From 024a6a6891eb77ae8c573ac1a1efb23c3eb7d1e6 Mon Sep 17 00:00:00 2001 From: Nicolas Stepien Date: Sun, 27 Nov 2011 21:59:18 +0100 Subject: [PATCH 095/169] Fix fit width on Opera. Make browser engine available as a body class for userstylers. --- 4chan_x.user.js | 21 ++++++++++++--------- changelog | 2 ++ script.coffee | 19 +++++++++++-------- 3 files changed, 25 insertions(+), 17 deletions(-) diff --git a/4chan_x.user.js b/4chan_x.user.js index 03dd6ee8b..e4e1a13d4 100644 --- a/4chan_x.user.js +++ b/4chan_x.user.js @@ -221,7 +221,7 @@ DAY = 24 * HOUR; - engine = /WebKit|Presto|Gecko/.exec(navigator.userAgent)[0]; + engine = /WebKit|Presto|Gecko/.exec(navigator.userAgent)[0].toLowerCase(); d = document; @@ -2684,7 +2684,7 @@ l = unread.replies.length; favicon = $('link[rel="shortcut icon"]', d.head); favicon.href = g.dead ? l ? Favicon.unreadDead : Favicon.dead : l ? Favicon.unread : Favicon["default"]; - if (engine === "Gecko") { + if (engine === "gecko") { clone = favicon.cloneNode(true); return $.replace(favicon, clone); } @@ -2811,7 +2811,7 @@ } }, typeChange: function() { - var form, klass; + var klass; switch (this.value) { case 'full': klass = ''; @@ -2825,9 +2825,8 @@ case 'fit screen': klass = 'fitwidth fitheight'; } - form = $('body > form'); - form.className = klass; - if (/\bfitheight\b/.test(form.className)) { + $('body > form').className = klass; + if (/\bfitheight\b/.test(klass)) { $.on(window, 'resize', imgExpand.resize); if (!imgExpand.style) imgExpand.style = $.addStyle(''); return imgExpand.resize(); @@ -2855,10 +2854,10 @@ img = $.el('img', { src: a.href }); - if (engine === "Gecko" && a.parentNode.className !== 'op') { + if (engine === "gecko" && a.parentNode.className !== 'op') { filesize = $('.filesize', a.parentNode); _ref = filesize.textContent.match(/(\d+)x/), _ = _ref[0], max = _ref[1]; - img.style.maxWidth = "-moz-calc(" + max + "px)"; + img.style.maxWidth = "" + max + "px"; } $.on(img, 'error', imgExpand.error); thumb.hidden = true; @@ -2977,6 +2976,7 @@ return; } if (!$('#navtopr')) return; + $.addClass(d.body, engine); $.addStyle(Main.css); threading.init(); Favicon.init(); @@ -3103,7 +3103,10 @@ }\ .fitwidth [md5] + img {\ max-width: 100%;\ - width: -moz-calc(100%); /* hack so only firefox sees this */\ + }\ + .gecko > .fitwidth [md5] + img,\ + .presto > .fitwidth [md5] + img {\ + width: 100%;\ }\ \ #qp, #iHover {\ diff --git a/changelog b/changelog index ee99cdb18..f1aaf3f01 100644 --- a/changelog +++ b/changelog @@ -1,6 +1,8 @@ master - mayhem fix locked thread icons with fit width/screen enabled on Firefox + fix fit width on Opera + for userstylers: you can use the rendering engine body class 2.21.2 - mayhem diff --git a/script.coffee b/script.coffee index e8fc1c143..7338e337e 100644 --- a/script.coffee +++ b/script.coffee @@ -127,7 +127,7 @@ SECOND = 1000 MINUTE = 60*SECOND HOUR = 60*MINUTE DAY = 24*HOUR -engine = /WebKit|Presto|Gecko/.exec(navigator.userAgent)[0] +engine = /WebKit|Presto|Gecko/.exec(navigator.userAgent)[0].toLowerCase() d = document g = callbacks: [] @@ -2090,7 +2090,7 @@ Favicon = Favicon.default #XXX `favicon.href = href` doesn't work on Firefox - if engine is "Gecko" + if engine is "gecko" clone = favicon.cloneNode true $.replace favicon, clone @@ -2163,9 +2163,8 @@ imgExpand = klass = 'fitheight' when 'fit screen' klass = 'fitwidth fitheight' - form = $('body > form') - form.className = klass - if /\bfitheight\b/.test form.className + $('body > form').className = klass + if /\bfitheight\b/.test klass $.on window, 'resize', imgExpand.resize unless imgExpand.style imgExpand.style = $.addStyle '' @@ -2188,10 +2187,10 @@ imgExpand = a = thumb.parentNode img = $.el 'img', src: a.href - if engine is "Gecko" and a.parentNode.className isnt 'op' + if engine is "gecko" and a.parentNode.className isnt 'op' filesize = $ '.filesize', a.parentNode [_, max] = filesize.textContent.match /(\d+)x/ - img.style.maxWidth = "-moz-calc(#{max}px)" + img.style.maxWidth = "#{max}px" $.on img, 'error', imgExpand.error thumb.hidden = true $.add a, img @@ -2327,6 +2326,7 @@ Main = return if not $ '#navtopr' return + $.addClass d.body, engine $.addStyle Main.css threading.init() Favicon.init() @@ -2468,7 +2468,10 @@ Main = } .fitwidth [md5] + img { max-width: 100%; - width: -moz-calc(100%); /* hack so only firefox sees this */ + } + .gecko > .fitwidth [md5] + img, + .presto > .fitwidth [md5] + img { + width: 100%; } #qp, #iHover { From a8b2b999830bd6915ca26a41c52eb7eb4ee2c5f8 Mon Sep 17 00:00:00 2001 From: Nicolas Stepien Date: Sun, 27 Nov 2011 22:06:23 +0100 Subject: [PATCH 096/169] Do not give errors on succesful uploads. --- 4chan_x.user.js | 2 +- script.coffee | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/4chan_x.user.js b/4chan_x.user.js index e4e1a13d4..84169f7cc 100644 --- a/4chan_x.user.js +++ b/4chan_x.user.js @@ -1560,7 +1560,7 @@ $('iframe[name=iframe]').src = 'about:blank'; fileCount = $('#files', qr.el).childElementCount; tc = data.textContent; - if (tc !== "Post successful!") { + if (tc !== "Post successful!" && !/uploaded!$/.test(tc)) { if (tc === void 0) { data.textContent = "Connection error with sys.4chan.org."; } diff --git a/script.coffee b/script.coffee index 7338e337e..7fb7514d2 100644 --- a/script.coffee +++ b/script.coffee @@ -1196,7 +1196,7 @@ qr = fileCount = $('#files', qr.el).childElementCount tc = data.textContent - if tc isnt "Post successful!" # error message + if tc isnt "Post successful!" and not /uploaded!$/.test tc # error message if tc is undefined data.textContent = "Connection error with sys.4chan.org." $.extend $('#error', qr.el), data From 692fae179bcc5cda7063c7cfb756e81a9140cca4 Mon Sep 17 00:00:00 2001 From: Nicolas Stepien Date: Sun, 27 Nov 2011 22:07:50 +0100 Subject: [PATCH 097/169] Release 2.21.3 --- 4chan_x.user.js | 6 +++--- Cakefile | 2 +- changelog | 2 ++ latest.js | 2 +- script.coffee | 2 +- 5 files changed, 8 insertions(+), 6 deletions(-) diff --git a/4chan_x.user.js b/4chan_x.user.js index 84169f7cc..d84b33bd6 100644 --- a/4chan_x.user.js +++ b/4chan_x.user.js @@ -1,6 +1,6 @@ // ==UserScript== // @name 4chan x -// @version 2.21.2 +// @version 2.21.3 // @namespace aeosynth // @description Adds various features. // @copyright 2009-2011 James Campos @@ -15,7 +15,7 @@ * * Copyright (c) 2009-2011 James Campos * http://mayhemydg.github.com/4chan-x/ - * 4chan x 2.21.2 + * 4chan x 2.21.3 * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation @@ -211,7 +211,7 @@ NAMESPACE = '4chan_x.'; - VERSION = '2.21.2'; + VERSION = '2.21.3'; SECOND = 1000; diff --git a/Cakefile b/Cakefile index b0d5fbfe3..586d87585 100644 --- a/Cakefile +++ b/Cakefile @@ -2,7 +2,7 @@ {exec} = require 'child_process' fs = require 'fs' -VERSION = '2.21.2' +VERSION = '2.21.3' HEADER = """ // ==UserScript== diff --git a/changelog b/changelog index f1aaf3f01..004385bde 100644 --- a/changelog +++ b/changelog @@ -1,4 +1,6 @@ master + +2.21.3 - mayhem fix locked thread icons with fit width/screen enabled on Firefox fix fit width on Opera diff --git a/latest.js b/latest.js index 103a1306e..dbf68abc1 100644 --- a/latest.js +++ b/latest.js @@ -1 +1 @@ -postMessage({version:'2.21.2'},'*'); +postMessage({version:'2.21.3'},'*'); diff --git a/script.coffee b/script.coffee index 7fb7514d2..89cb09138 100644 --- a/script.coffee +++ b/script.coffee @@ -122,7 +122,7 @@ conf = {} ) null, config NAMESPACE = '4chan_x.' -VERSION = '2.21.2' +VERSION = '2.21.3' SECOND = 1000 MINUTE = 60*SECOND HOUR = 60*MINUTE From 3c9665780b6e61e6ddafd0e555742f2075e8078a Mon Sep 17 00:00:00 2001 From: Nicolas Stepien Date: Mon, 28 Nov 2011 02:45:42 +0100 Subject: [PATCH 098/169] fix auto-updater. 2.21.4 --- 4chan_x.user.js | 10 +++++----- Cakefile | 2 +- changelog | 4 ++++ latest.js | 2 +- script.coffee | 4 ++-- 5 files changed, 13 insertions(+), 9 deletions(-) diff --git a/4chan_x.user.js b/4chan_x.user.js index d84b33bd6..c84c42e2b 100644 --- a/4chan_x.user.js +++ b/4chan_x.user.js @@ -1,6 +1,6 @@ // ==UserScript== // @name 4chan x -// @version 2.21.3 +// @version 2.21.4 // @namespace aeosynth // @description Adds various features. // @copyright 2009-2011 James Campos @@ -15,7 +15,7 @@ * * Copyright (c) 2009-2011 James Campos * http://mayhemydg.github.com/4chan-x/ - * 4chan x 2.21.3 + * 4chan x 2.21.4 * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation @@ -211,7 +211,7 @@ NAMESPACE = '4chan_x.'; - VERSION = '2.21.3'; + VERSION = '2.21.4'; SECOND = 1000; @@ -3035,12 +3035,12 @@ return options.init(); }, message: function(e) { - var data, location, origin; + var data, origin; origin = e.origin, data = e.data; if (origin === 'http://sys.4chan.org') { return qr.message(data); } else if (data.version !== VERSION && confirm('An updated version of 4chan X is available, would you like to install it now?')) { - return location = "https://raw.github.com/mayhemydg/4chan-x/" + data.version + "/4chan_x.user.js"; + return window.location = "https://raw.github.com/mayhemydg/4chan-x/" + data.version + "/4chan_x.user.js"; } }, node: function(e) { diff --git a/Cakefile b/Cakefile index 586d87585..72fb5138f 100644 --- a/Cakefile +++ b/Cakefile @@ -2,7 +2,7 @@ {exec} = require 'child_process' fs = require 'fs' -VERSION = '2.21.3' +VERSION = '2.21.4' HEADER = """ // ==UserScript== diff --git a/changelog b/changelog index 004385bde..07ba4c087 100644 --- a/changelog +++ b/changelog @@ -1,5 +1,9 @@ master +2.21.4 +- mayhem + fix auto-updater + 2.21.3 - mayhem fix locked thread icons with fit width/screen enabled on Firefox diff --git a/latest.js b/latest.js index dbf68abc1..592a4d3f5 100644 --- a/latest.js +++ b/latest.js @@ -1 +1 @@ -postMessage({version:'2.21.3'},'*'); +postMessage({version:'2.21.4'},'*'); diff --git a/script.coffee b/script.coffee index 89cb09138..fad56c7a8 100644 --- a/script.coffee +++ b/script.coffee @@ -122,7 +122,7 @@ conf = {} ) null, config NAMESPACE = '4chan_x.' -VERSION = '2.21.3' +VERSION = '2.21.4' SECOND = 1000 MINUTE = 60*SECOND HOUR = 60*MINUTE @@ -2413,7 +2413,7 @@ Main = if origin is 'http://sys.4chan.org' qr.message data else if data.version isnt VERSION and confirm 'An updated version of 4chan X is available, would you like to install it now?' - location = "https://raw.github.com/mayhemydg/4chan-x/#{data.version}/4chan_x.user.js" + window.location = "https://raw.github.com/mayhemydg/4chan-x/#{data.version}/4chan_x.user.js" node: (e) -> {target} = e From 5bc33ec8f8e7cbb5aaa2783495a054741da34321 Mon Sep 17 00:00:00 2001 From: Nicolas Stepien Date: Mon, 28 Nov 2011 16:58:30 +0100 Subject: [PATCH 099/169] Sanitize QR inputs. --- 4chan_x.user.js | 12 ++++++------ script.coffee | 18 +++++++++++------- 2 files changed, 17 insertions(+), 13 deletions(-) diff --git a/4chan_x.user.js b/4chan_x.user.js index c84c42e2b..bdef3fc5f 100644 --- a/4chan_x.user.js +++ b/4chan_x.user.js @@ -1532,17 +1532,17 @@ return qr.el = null; }, dialog: function(link) { - var THREAD_ID, c, email, html, m, name, pwd, submitDisabled, submitValue; - c = d.cookie; - name = (m = c.match(/4chan_name=([^;]+)/)) ? decodeURIComponent(m[1]) : ''; - email = (m = c.match(/4chan_email=([^;]+)/)) ? decodeURIComponent(m[1]) : ''; - pwd = (m = c.match(/4chan_pass=([^;]+)/)) ? decodeURIComponent(m[1]) : $('input[name=pwd]').value; + var THREAD_ID, c, html, m, submitDisabled, submitValue; submitValue = $('#com_submit').value; submitDisabled = $('#com_submit').disabled ? 'disabled' : ''; THREAD_ID = g.THREAD_ID || $.x('ancestor::div[@class="thread"]/div', link).id; qr.challenge = $('#recaptcha_challenge_field').value; - html = " X
        Quick Reply
        " + qr.spoiler + "
        " + ($.get('captchas', []).length) + " captchas
        "; + html = " X
        Quick Reply
        " + qr.spoiler + "
        " + ($.get('captchas', []).length) + " captchas
        "; qr.el = ui.dialog('qr', 'top: 0; left: 0;', html); + c = d.cookie; + $('input[name=name]', qr.el).value = (m = c.match(/4chan_name=([^;]+)/)) ? decodeURIComponent(m[1]) : ''; + $('input[name=email]', qr.el).value = (m = c.match(/4chan_email=([^;]+)/)) ? decodeURIComponent(m[1]) : ''; + $('input[name=pwd]', qr.el).value = (m = c.match(/4chan_pass=([^;]+)/)) ? decodeURIComponent(m[1]) : $('input[name=pwd]').value; $.on($('input[name=name]', qr.el), 'mousedown', function(e) { return e.stopPropagation(); }); diff --git a/script.coffee b/script.coffee index fad56c7a8..f792b676b 100644 --- a/script.coffee +++ b/script.coffee @@ -1143,10 +1143,6 @@ qr = qr.el = null dialog: (link) -> - c = d.cookie - name = if m = c.match(/4chan_name=([^;]+)/) then decodeURIComponent m[1] else '' - email = if m = c.match(/4chan_email=([^;]+)/) then decodeURIComponent m[1] else '' - pwd = if m = c.match(/4chan_pass=([^;]+)/) then decodeURIComponent m[1] else $('input[name=pwd]').value submitValue = $('#com_submit').value submitDisabled = if $('#com_submit').disabled then 'disabled' else '' #FIXME inlined cross-thread quotes @@ -1157,7 +1153,7 @@ qr = X
        - + Quick Reply
        @@ -1166,7 +1162,7 @@ qr = -
        #{qr.spoiler}
        +
        #{qr.spoiler}
        @@ -1174,12 +1170,20 @@ qr =
        - +
        " qr.el = ui.dialog 'qr', 'top: 0; left: 0;', html + c = d.cookie + $('input[name=name]', qr.el).value = + if m = c.match(/4chan_name=([^;]+)/) then decodeURIComponent m[1] else '' + $('input[name=email]', qr.el).value = + if m = c.match(/4chan_email=([^;]+)/) then decodeURIComponent m[1] else '' + $('input[name=pwd]', qr.el).value = + if m = c.match(/4chan_pass=([^;]+)/) then decodeURIComponent m[1] else $('input[name=pwd]').value + $.on $('input[name=name]', qr.el), 'mousedown', (e) -> e.stopPropagation() $.on $('input[name=upfile]', qr.el), 'change', qr.validateFileSize $.on $('#close', qr.el), 'click', qr.close From 0a03e393e7e45661b1480bb243461769b566e277 Mon Sep 17 00:00:00 2001 From: Nicolas Stepien Date: Mon, 28 Nov 2011 17:34:44 +0100 Subject: [PATCH 100/169] indicate duckrolls. Close #17 --- 4chan_x.user.js | 27 +++++++++++++++++++++++++-- changelog | 2 ++ script.coffee | 13 +++++++++++++ 3 files changed, 40 insertions(+), 2 deletions(-) diff --git a/4chan_x.user.js b/4chan_x.user.js index bdef3fc5f..345823581 100644 --- a/4chan_x.user.js +++ b/4chan_x.user.js @@ -66,7 +66,7 @@ */ (function() { - var $, $$, DAY, Favicon, HOUR, MINUTE, Main, NAMESPACE, Recaptcha, SECOND, Time, VERSION, anonymize, conf, config, cooldown, d, engine, expandComment, expandThread, filter, flatten, g, getTitle, imgExpand, imgGif, imgHover, key, keybinds, log, nav, options, qr, quoteBacklink, quoteInline, quoteOP, quotePreview, redirect, replyHiding, reportButton, revealSpoilers, sauce, strikethroughQuotes, threadHiding, threadStats, threading, titlePost, ui, unread, updater, val, watcher; + var $, $$, DAY, Favicon, HOUR, MINUTE, Main, NAMESPACE, Recaptcha, SECOND, Time, VERSION, anonymize, conf, config, cooldown, d, engine, expandComment, expandThread, filter, flatten, g, getTitle, imgExpand, imgGif, imgHover, key, keybinds, log, nav, options, qr, quoteBacklink, quoteDR, quoteInline, quoteOP, quotePreview, redirect, replyHiding, reportButton, revealSpoilers, sauce, strikethroughQuotes, threadHiding, threadStats, threading, titlePost, ui, unread, updater, val, watcher; var __slice = Array.prototype.slice; config = { @@ -120,7 +120,8 @@ 'Quote Highlighting': [true, 'Highlight the previewed post'], 'Quote Inline': [true, 'Show quoted post inline on quote click'], 'Quote Preview': [true, 'Show quote content on hover'], - 'Indicate OP quote': [true, 'Add \'(OP)\' to OP quotes'] + 'Indicate OP quote': [true, 'Add \'(OP)\' to OP quotes'], + 'Indicate Duckrolls': [false, 'Add \'(Duckroll)\' to cross threads quotes'] } }, filter: { @@ -2581,6 +2582,27 @@ } }; + quoteDR = { + init: function() { + return g.callbacks.push(function(root) { + var quote, tid, _i, _len, _ref, _results; + if (root.className === 'inline') return; + tid = g.THREAD_ID || $.x('ancestor::div[contains(@class,"thread")]/div', root).id; + _ref = $$('.quotelink', root); + _results = []; + for (_i = 0, _len = _ref.length; _i < _len; _i++) { + quote = _ref[_i]; + if (quote.pathname.indexOf("res/" + tid) === -1) { + _results.push(quote.innerHTML += ' (Duckroll)'); + } else { + _results.push(void 0); + } + } + return _results; + }); + } + }; + reportButton = { init: function() { return g.callbacks.push(function(root) { @@ -2962,6 +2984,7 @@ if (conf['Quote Preview']) quotePreview.init(); if (conf['Quote Backlinks']) quoteBacklink.init(); if (conf['Indicate OP quote']) quoteOP.init(); + if (conf['Indicate Duckrolls']) quoteDR.init(); if (d.body) { return Main.onLoad(); } else { diff --git a/changelog b/changelog index 07ba4c087..fcfad3c9a 100644 --- a/changelog +++ b/changelog @@ -1,4 +1,6 @@ master +- mayhem + new Indicate Duckrolls feature 2.21.4 - mayhem diff --git a/script.coffee b/script.coffee index f792b676b..3aaf29789 100644 --- a/script.coffee +++ b/script.coffee @@ -45,6 +45,7 @@ config = 'Quote Inline': [true, 'Show quoted post inline on quote click'] 'Quote Preview': [true, 'Show quote content on hover'] 'Indicate OP quote': [true, 'Add \'(OP)\' to OP quotes'] + 'Indicate Duckrolls': [false, 'Add \'(Duckroll)\' to cross threads quotes'] filter: name: '' tripcode: '' @@ -1995,6 +1996,15 @@ quoteOP = if quote.hash[1..] is tid quote.innerHTML += ' (OP)' +quoteDR = + init: -> + g.callbacks.push (root) -> + return if root.className is 'inline' + tid = g.THREAD_ID or $.x('ancestor::div[contains(@class,"thread")]/div', root).id + for quote in $$ '.quotelink', root + if quote.pathname.indexOf("res/#{tid}") is -1 + quote.innerHTML += ' (Duckroll)' + reportButton = init: -> g.callbacks.push (root) -> @@ -2317,6 +2327,9 @@ Main = if conf['Indicate OP quote'] quoteOP.init() + if conf['Indicate Duckrolls'] + quoteDR.init() + if d.body Main.onLoad() From 76e9c82a22b6265d0c981dd24e4318fb2d000925 Mon Sep 17 00:00:00 2001 From: Nicolas Stepien Date: Mon, 28 Nov 2011 17:50:49 +0100 Subject: [PATCH 101/169] Do not indicate duckrolls on >>>/v/ links. --- 4chan_x.user.js | 4 ++-- script.coffee | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/4chan_x.user.js b/4chan_x.user.js index 345823581..ae2a860da 100644 --- a/4chan_x.user.js +++ b/4chan_x.user.js @@ -121,7 +121,7 @@ 'Quote Inline': [true, 'Show quoted post inline on quote click'], 'Quote Preview': [true, 'Show quote content on hover'], 'Indicate OP quote': [true, 'Add \'(OP)\' to OP quotes'], - 'Indicate Duckrolls': [false, 'Add \'(Duckroll)\' to cross threads quotes'] + 'Indicate Duckrolls': [true, 'Add \'(Duckroll)\' to cross threads quotes'] } }, filter: { @@ -2592,7 +2592,7 @@ _results = []; for (_i = 0, _len = _ref.length; _i < _len; _i++) { quote = _ref[_i]; - if (quote.pathname.indexOf("res/" + tid) === -1) { + if (quote.hash && quote.pathname.indexOf(tid) === -1) { _results.push(quote.innerHTML += ' (Duckroll)'); } else { _results.push(void 0); diff --git a/script.coffee b/script.coffee index 3aaf29789..7502484c6 100644 --- a/script.coffee +++ b/script.coffee @@ -45,7 +45,7 @@ config = 'Quote Inline': [true, 'Show quoted post inline on quote click'] 'Quote Preview': [true, 'Show quote content on hover'] 'Indicate OP quote': [true, 'Add \'(OP)\' to OP quotes'] - 'Indicate Duckrolls': [false, 'Add \'(Duckroll)\' to cross threads quotes'] + 'Indicate Duckrolls': [true, 'Add \'(Duckroll)\' to cross threads quotes'] filter: name: '' tripcode: '' @@ -2002,7 +2002,7 @@ quoteDR = return if root.className is 'inline' tid = g.THREAD_ID or $.x('ancestor::div[contains(@class,"thread")]/div', root).id for quote in $$ '.quotelink', root - if quote.pathname.indexOf("res/#{tid}") is -1 + if quote.hash and quote.pathname.indexOf(tid) is -1 quote.innerHTML += ' (Duckroll)' reportButton = From 8b0168c556482bde389c43a8b4115b8baaac0f85 Mon Sep 17 00:00:00 2001 From: Nicolas Stepien Date: Mon, 28 Nov 2011 22:35:02 +0100 Subject: [PATCH 102/169] Don't indicate duckrolls of cross-board quotes. --- 4chan_x.user.js | 2 +- script.coffee | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/4chan_x.user.js b/4chan_x.user.js index ae2a860da..be4f8facb 100644 --- a/4chan_x.user.js +++ b/4chan_x.user.js @@ -2592,7 +2592,7 @@ _results = []; for (_i = 0, _len = _ref.length; _i < _len; _i++) { quote = _ref[_i]; - if (quote.hash && quote.pathname.indexOf(tid) === -1) { + if (quote.pathname.indexOf("res/" + tid) === -1 && !quote.pathname.indexOf("/" + g.BOARD + "/res")) { _results.push(quote.innerHTML += ' (Duckroll)'); } else { _results.push(void 0); diff --git a/script.coffee b/script.coffee index 7502484c6..dcbea2bbe 100644 --- a/script.coffee +++ b/script.coffee @@ -2002,7 +2002,8 @@ quoteDR = return if root.className is 'inline' tid = g.THREAD_ID or $.x('ancestor::div[contains(@class,"thread")]/div', root).id for quote in $$ '.quotelink', root - if quote.hash and quote.pathname.indexOf(tid) is -1 + #if quote leads to a different thread id and is located on the same board (index 0) + if quote.pathname.indexOf("res/#{tid}") is -1 and !quote.pathname.indexOf "/#{g.BOARD}/res" quote.innerHTML += ' (Duckroll)' reportButton = From 2f8ae8755cb5f5406986d896e0878eba1ff7e57a Mon Sep 17 00:00:00 2001 From: Nicolas Stepien Date: Mon, 28 Nov 2011 23:28:22 +0100 Subject: [PATCH 103/169] Fix an unharmful issue, test if the class exists correctly. --- 4chan_x.user.js | 2 +- script.coffee | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/4chan_x.user.js b/4chan_x.user.js index be4f8facb..b18e1204d 100644 --- a/4chan_x.user.js +++ b/4chan_x.user.js @@ -2411,7 +2411,7 @@ root = q.parentNode.nodeName === 'FONT' ? q.parentNode : q.nextSibling ? q.nextSibling : q; if (el = $.id(id)) { inline = quoteInline.table(id, el.innerHTML); - if (q.className === 'backlink') { + if (/\bbacklink\b/.test(q.className)) { $.after(q.parentNode, inline); return; } diff --git a/script.coffee b/script.coffee index dcbea2bbe..57146bb22 100644 --- a/script.coffee +++ b/script.coffee @@ -1888,7 +1888,7 @@ quoteInline = root = if q.parentNode.nodeName is 'FONT' then q.parentNode else if q.nextSibling then q.nextSibling else q if el = $.id id inline = quoteInline.table id, el.innerHTML - if q.className is 'backlink' + if /\bbacklink\b/.test q.className $.after q.parentNode, inline return $.after root, inline From 8a91a4e7fcad1e40f606e12c5bc35da7edff8176 Mon Sep 17 00:00:00 2001 From: Nicolas Stepien Date: Tue, 29 Nov 2011 00:32:48 +0100 Subject: [PATCH 104/169] Put regex.info sauce back. --- 4chan_x.user.js | 2 +- changelog | 1 + script.coffee | 1 + 3 files changed, 3 insertions(+), 1 deletion(-) diff --git a/4chan_x.user.js b/4chan_x.user.js index b18e1204d..6ddebda98 100644 --- a/4chan_x.user.js +++ b/4chan_x.user.js @@ -134,7 +134,7 @@ filesize: '', md5: '' }, - flavors: ['http://iqdb.org/?url=', 'http://google.com/searchbyimage?image_url=', '#http://tineye.com/search?url=', '#http://saucenao.com/search.php?db=999&url=', '#http://3d.iqdb.org/?url=', '#http://imgur.com/upload?url='].join('\n'), + flavors: ['http://iqdb.org/?url=', 'http://google.com/searchbyimage?image_url=', '#http://tineye.com/search?url=', '#http://saucenao.com/search.php?db=999&url=', '#http://3d.iqdb.org/?url=', '#http://regex.info/exif.cgi?imgurl=', '#http://imgur.com/upload?url='].join('\n'), time: '%m/%d/%y(%a)%H:%M', backlink: '>>%id', hotkeys: { diff --git a/changelog b/changelog index fcfad3c9a..6735dd549 100644 --- a/changelog +++ b/changelog @@ -1,6 +1,7 @@ master - mayhem new Indicate Duckrolls feature + put regex.info sauce back - disabled by default 2.21.4 - mayhem diff --git a/script.coffee b/script.coffee index 57146bb22..aedae8e9a 100644 --- a/script.coffee +++ b/script.coffee @@ -61,6 +61,7 @@ config = '#http://tineye.com/search?url=' '#http://saucenao.com/search.php?db=999&url=' '#http://3d.iqdb.org/?url=' + '#http://regex.info/exif.cgi?imgurl=' '#http://imgur.com/upload?url=' ].join '\n' time: '%m/%d/%y(%a)%H:%M' From 0e076a1bcfaa65866bb6afc93059e0327ba1eb82 Mon Sep 17 00:00:00 2001 From: Nicolas Stepien Date: Tue, 29 Nov 2011 07:07:21 +0100 Subject: [PATCH 105/169] Firefox returns status code 0 for cross domain requests, don't reload pictures only in 404'd threads. Close #22 --- 4chan_x.user.js | 4 ++-- changelog | 1 + script.coffee | 6 ++++-- 3 files changed, 7 insertions(+), 4 deletions(-) diff --git a/4chan_x.user.js b/4chan_x.user.js index 6ddebda98..da7a1f526 100644 --- a/4chan_x.user.js +++ b/4chan_x.user.js @@ -2876,7 +2876,7 @@ img = $.el('img', { src: a.href }); - if (engine === "gecko" && a.parentNode.className !== 'op') { + if (engine === 'gecko' && a.parentNode.className !== 'op') { filesize = $('.filesize', a.parentNode); _ref = filesize.textContent.match(/(\d+)x/), _ = _ref[0], max = _ref[1]; img.style.maxWidth = "" + max + "px"; @@ -2889,7 +2889,7 @@ var req, thumb; thumb = this.previousSibling; imgExpand.contract(thumb); - if (navigator.appName !== 'Opera') { + if (engine === 'webkit') { req = $.ajax(this.src, null, 'head'); return req.onreadystatechange = function() { if (this.status !== 404) { diff --git a/changelog b/changelog index 6735dd549..6499d7fb6 100644 --- a/changelog +++ b/changelog @@ -2,6 +2,7 @@ master - mayhem new Indicate Duckrolls feature put regex.info sauce back - disabled by default + fix for auto image reloading in 404'd threads on Firefox 2.21.4 - mayhem diff --git a/script.coffee b/script.coffee index aedae8e9a..17f2c9fc8 100644 --- a/script.coffee +++ b/script.coffee @@ -2203,7 +2203,7 @@ imgExpand = a = thumb.parentNode img = $.el 'img', src: a.href - if engine is "gecko" and a.parentNode.className isnt 'op' + if engine is 'gecko' and a.parentNode.className isnt 'op' filesize = $ '.filesize', a.parentNode [_, max] = filesize.textContent.match /(\d+)x/ img.style.maxWidth = "#{max}px" @@ -2215,9 +2215,11 @@ imgExpand = thumb = @previousSibling imgExpand.contract thumb #navigator.online is not x-browser/os yet - if navigator.appName isnt 'Opera' + if engine is 'webkit' req = $.ajax @src, null, 'head' req.onreadystatechange = -> setTimeout imgExpand.retry, 10000, thumb if @status isnt 404 + #Firefox returns a status code of 0 because of the same origin policy + #Oprah doesn't send any request else unless g.dead setTimeout imgExpand.retry, 10000, thumb retry: (thumb) -> From f924a81963a7d1c99f804eeda9191c41386a8dec Mon Sep 17 00:00:00 2001 From: Nicolas Stepien Date: Tue, 29 Nov 2011 07:42:19 +0100 Subject: [PATCH 106/169] Comment regarding issue #23 --- script.coffee | 1 + 1 file changed, 1 insertion(+) diff --git a/script.coffee b/script.coffee index 17f2c9fc8..6484a3b21 100644 --- a/script.coffee +++ b/script.coffee @@ -1577,6 +1577,7 @@ updater = body = $.el 'body', innerHTML: @responseText + #this only works on Chrome because of cross origin policy if $('title', body).textContent is '4chan - Banned' updater.count.textContent = 'banned' updater.count.className = 'error' From d92693a6026e0581e89b097b6e956d42f869e272 Mon Sep 17 00:00:00 2001 From: Nicolas Stepien Date: Tue, 29 Nov 2011 07:51:48 +0100 Subject: [PATCH 107/169] Release 2.22.0. --- 4chan_x.user.js | 6 +++--- Cakefile | 2 +- changelog | 4 +++- latest.js | 2 +- script.coffee | 2 +- 5 files changed, 9 insertions(+), 7 deletions(-) diff --git a/4chan_x.user.js b/4chan_x.user.js index da7a1f526..4194ce531 100644 --- a/4chan_x.user.js +++ b/4chan_x.user.js @@ -1,6 +1,6 @@ // ==UserScript== // @name 4chan x -// @version 2.21.4 +// @version 2.22.0 // @namespace aeosynth // @description Adds various features. // @copyright 2009-2011 James Campos @@ -15,7 +15,7 @@ * * Copyright (c) 2009-2011 James Campos * http://mayhemydg.github.com/4chan-x/ - * 4chan x 2.21.4 + * 4chan x 2.22.0 * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation @@ -212,7 +212,7 @@ NAMESPACE = '4chan_x.'; - VERSION = '2.21.4'; + VERSION = '2.22.0'; SECOND = 1000; diff --git a/Cakefile b/Cakefile index 72fb5138f..3eb187528 100644 --- a/Cakefile +++ b/Cakefile @@ -2,7 +2,7 @@ {exec} = require 'child_process' fs = require 'fs' -VERSION = '2.21.4' +VERSION = '2.22.0' HEADER = """ // ==UserScript== diff --git a/changelog b/changelog index 6499d7fb6..9daa6dd83 100644 --- a/changelog +++ b/changelog @@ -1,4 +1,6 @@ master + +2.22.0 - mayhem new Indicate Duckrolls feature put regex.info sauce back - disabled by default @@ -6,7 +8,7 @@ master 2.21.4 - mayhem - fix auto-updater + fix 4chan X version updater 2.21.3 - mayhem diff --git a/latest.js b/latest.js index 592a4d3f5..365cd42ac 100644 --- a/latest.js +++ b/latest.js @@ -1 +1 @@ -postMessage({version:'2.21.4'},'*'); +postMessage({version:'2.22.0'},'*'); diff --git a/script.coffee b/script.coffee index 6484a3b21..550f78a0b 100644 --- a/script.coffee +++ b/script.coffee @@ -124,7 +124,7 @@ conf = {} ) null, config NAMESPACE = '4chan_x.' -VERSION = '2.21.4' +VERSION = '2.22.0' SECOND = 1000 MINUTE = 60*SECOND HOUR = 60*MINUTE From ec326e7557831c758498ed3261217362b28882cf Mon Sep 17 00:00:00 2001 From: James Campos Date: Wed, 30 Nov 2011 03:36:26 -0800 Subject: [PATCH 108/169] fix #406, dupe stubs --- 4chan_x.user.js | 2 ++ script.coffee | 3 +++ 2 files changed, 5 insertions(+) diff --git a/4chan_x.user.js b/4chan_x.user.js index 4194ce531..de85e93b8 100644 --- a/4chan_x.user.js +++ b/4chan_x.user.js @@ -851,6 +851,7 @@ hideHide: function(reply) { var a, div, name, table, trip, _ref; table = reply.parentNode.parentNode.parentNode; + if (table.hidden) return; table.hidden = true; if (conf['Show Stubs']) { name = $('.commentpostername', reply).textContent; @@ -1857,6 +1858,7 @@ hideHide: function(thread) { var a, div, name, num, span, text, trip, _ref; if (conf['Show Stubs']) { + if (/stub/.test(thread.className)) return; if (span = $('.omittedposts', thread)) { num = Number(span.textContent.match(/\d+/)[0]); } else { diff --git a/script.coffee b/script.coffee index 550f78a0b..c35d949bd 100644 --- a/script.coffee +++ b/script.coffee @@ -607,6 +607,8 @@ replyHiding = hideHide: (reply) -> table = reply.parentNode.parentNode.parentNode + return if table.hidden #already hidden by filter + table.hidden = true if conf['Show Stubs'] @@ -1460,6 +1462,7 @@ threadHiding = hideHide: (thread) -> if conf['Show Stubs'] + return if /stub/.test thread.className #already hidden by filter if span = $ '.omittedposts', thread num = Number span.textContent.match(/\d+/)[0] else From ce1daf656e1876bb15e7688b00c8af439903b022 Mon Sep 17 00:00:00 2001 From: Nicolas Stepien Date: Sun, 4 Dec 2011 02:02:44 +0100 Subject: [PATCH 109/169] Rename duckrolls, see #17 --- 4chan_x.user.js | 6 ++-- changelog | 2 ++ script.coffee | 84 ++++++++++++++++++++++++------------------------- 3 files changed, 47 insertions(+), 45 deletions(-) diff --git a/4chan_x.user.js b/4chan_x.user.js index de85e93b8..a67c1bb2c 100644 --- a/4chan_x.user.js +++ b/4chan_x.user.js @@ -121,7 +121,7 @@ 'Quote Inline': [true, 'Show quoted post inline on quote click'], 'Quote Preview': [true, 'Show quote content on hover'], 'Indicate OP quote': [true, 'Add \'(OP)\' to OP quotes'], - 'Indicate Duckrolls': [true, 'Add \'(Duckroll)\' to cross threads quotes'] + 'Indicate Cross-thread Quotes': [true, 'Add \'(Cross-thread)\' to cross-threads quotes'] } }, filter: { @@ -2595,7 +2595,7 @@ for (_i = 0, _len = _ref.length; _i < _len; _i++) { quote = _ref[_i]; if (quote.pathname.indexOf("res/" + tid) === -1 && !quote.pathname.indexOf("/" + g.BOARD + "/res")) { - _results.push(quote.innerHTML += ' (Duckroll)'); + _results.push(quote.innerHTML += ' (Cross-thread)'); } else { _results.push(void 0); } @@ -2986,7 +2986,7 @@ if (conf['Quote Preview']) quotePreview.init(); if (conf['Quote Backlinks']) quoteBacklink.init(); if (conf['Indicate OP quote']) quoteOP.init(); - if (conf['Indicate Duckrolls']) quoteDR.init(); + if (conf['Indicate Cross-thread Quotes']) quoteDR.init(); if (d.body) { return Main.onLoad(); } else { diff --git a/changelog b/changelog index 9daa6dd83..66033bbdb 100644 --- a/changelog +++ b/changelog @@ -1,4 +1,6 @@ master +- mayhem + change 'Duckroll' for 'Cross-thread' 2.22.0 - mayhem diff --git a/script.coffee b/script.coffee index c35d949bd..93124fa1d 100644 --- a/script.coffee +++ b/script.coffee @@ -1,51 +1,51 @@ config = main: Enhancing: - '404 Redirect': [true, 'Redirect dead threads'] - 'Keybinds': [true, 'Binds actions to keys'] - 'Time Formatting': [true, 'Arbitrarily formatted timestamps, using your local time'] - 'Report Button': [true, 'Add report buttons'] - 'Comment Expansion': [true, 'Expand too long comments'] - 'Thread Expansion': [true, 'View all replies'] - 'Index Navigation': [true, 'Navigate to previous / next thread'] - 'Reply Navigation': [false, 'Navigate to top / bottom of thread'] - 'Check for Updates': [true, 'Check for updated versions of 4chan X'] + '404 Redirect': [true, 'Redirect dead threads'] + 'Keybinds': [true, 'Binds actions to keys'] + 'Time Formatting': [true, 'Arbitrarily formatted timestamps, using your local time'] + 'Report Button': [true, 'Add report buttons'] + 'Comment Expansion': [true, 'Expand too long comments'] + 'Thread Expansion': [true, 'View all replies'] + 'Index Navigation': [true, 'Navigate to previous / next thread'] + 'Reply Navigation': [false, 'Navigate to top / bottom of thread'] + 'Check for Updates': [true, 'Check for updated versions of 4chan X'] Filtering: - 'Anonymize': [false, 'Make everybody anonymous'] - 'Filter': [false, 'Self-moderation placebo'] - 'Filter OPs': [false, 'Filter OPs along with their threads'] - 'Reply Hiding': [true, 'Hide single replies'] - 'Thread Hiding': [true, 'Hide entire threads'] - 'Show Stubs': [true, 'Of hidden threads / replies'] + 'Anonymize': [false, 'Make everybody anonymous'] + 'Filter': [false, 'Self-moderation placebo'] + 'Filter OPs': [false, 'Filter OPs along with their threads'] + 'Reply Hiding': [true, 'Hide single replies'] + 'Thread Hiding': [true, 'Hide entire threads'] + 'Show Stubs': [true, 'Of hidden threads / replies'] Imaging: - 'Image Auto-Gif': [false, 'Animate gif thumbnails'] - 'Image Expansion': [true, 'Expand images'] - 'Image Hover': [false, 'Show full image on mouseover'] - 'Sauce': [true, 'Add sauce to images'] - 'Reveal Spoilers': [false, 'Replace spoiler thumbnails by the original thumbnail'] + 'Image Auto-Gif': [false, 'Animate gif thumbnails'] + 'Image Expansion': [true, 'Expand images'] + 'Image Hover': [false, 'Show full image on mouseover'] + 'Sauce': [true, 'Add sauce to images'] + 'Reveal Spoilers': [false, 'Replace spoiler thumbnails by the original thumbnail'] Monitoring: - 'Thread Updater': [true, 'Update threads. Has more options in its own dialog.'] - 'Unread Count': [true, 'Show unread post count in tab title'] - 'Post in Title': [true, 'Show the op\'s post in the tab title'] - 'Thread Stats': [true, 'Display reply and image count'] - 'Thread Watcher': [true, 'Bookmark threads'] - 'Auto Watch': [true, 'Automatically watch threads that you start'] - 'Auto Watch Reply': [false, 'Automatically watch threads that you reply to'] + 'Thread Updater': [true, 'Update threads. Has more options in its own dialog.'] + 'Unread Count': [true, 'Show unread post count in tab title'] + 'Post in Title': [true, 'Show the op\'s post in the tab title'] + 'Thread Stats': [true, 'Display reply and image count'] + 'Thread Watcher': [true, 'Bookmark threads'] + 'Auto Watch': [true, 'Automatically watch threads that you start'] + 'Auto Watch Reply': [false, 'Automatically watch threads that you reply to'] Posting: - 'Auto Noko': [true, 'Always redirect to your post'] - 'Cooldown': [true, 'Prevent `flood detected` errors'] - 'Quick Reply': [true, 'Reply without leaving the page'] - 'Persistent QR': [false, 'Quick reply won\'t disappear after posting. Only in replies.'] - 'Auto Hide QR': [true, 'Automatically auto-hide the quick reply when posting'] - 'Remember Spoiler': [false, 'Remember the spoiler state, instead of resetting after posting'] + 'Auto Noko': [true, 'Always redirect to your post'] + 'Cooldown': [true, 'Prevent `flood detected` errors'] + 'Quick Reply': [true, 'Reply without leaving the page'] + 'Persistent QR': [false, 'Quick reply won\'t disappear after posting. Only in replies.'] + 'Auto Hide QR': [true, 'Automatically auto-hide the quick reply when posting'] + 'Remember Spoiler': [false, 'Remember the spoiler state, instead of resetting after posting'] Quoting: - 'Quote Backlinks': [true, 'Add quote backlinks'] - 'OP Backlinks': [false, 'Add backlinks to the OP'] - 'Quote Highlighting': [true, 'Highlight the previewed post'] - 'Quote Inline': [true, 'Show quoted post inline on quote click'] - 'Quote Preview': [true, 'Show quote content on hover'] - 'Indicate OP quote': [true, 'Add \'(OP)\' to OP quotes'] - 'Indicate Duckrolls': [true, 'Add \'(Duckroll)\' to cross threads quotes'] + 'Quote Backlinks': [true, 'Add quote backlinks'] + 'OP Backlinks': [false, 'Add backlinks to the OP'] + 'Quote Highlighting': [true, 'Highlight the previewed post'] + 'Quote Inline': [true, 'Show quoted post inline on quote click'] + 'Quote Preview': [true, 'Show quote content on hover'] + 'Indicate OP quote': [true, 'Add \'(OP)\' to OP quotes'] + 'Indicate Cross-thread Quotes': [true, 'Add \'(Cross-thread)\' to cross-threads quotes'] filter: name: '' tripcode: '' @@ -2009,7 +2009,7 @@ quoteDR = for quote in $$ '.quotelink', root #if quote leads to a different thread id and is located on the same board (index 0) if quote.pathname.indexOf("res/#{tid}") is -1 and !quote.pathname.indexOf "/#{g.BOARD}/res" - quote.innerHTML += ' (Duckroll)' + quote.innerHTML += ' (Cross-thread)' reportButton = init: -> @@ -2335,7 +2335,7 @@ Main = if conf['Indicate OP quote'] quoteOP.init() - if conf['Indicate Duckrolls'] + if conf['Indicate Cross-thread Quotes'] quoteDR.init() From 688cf8aa1384d76556ff83f5c88531533c7b8143 Mon Sep 17 00:00:00 2001 From: Nicolas Stepien Date: Sun, 4 Dec 2011 17:51:58 +0100 Subject: [PATCH 110/169] Fix image expanding fitness with an inlined backlink on Firefox, close #26 --- 4chan_x.user.js | 8 ++++---- changelog | 1 + script.coffee | 6 +++--- 3 files changed, 8 insertions(+), 7 deletions(-) diff --git a/4chan_x.user.js b/4chan_x.user.js index a67c1bb2c..24c70ca1a 100644 --- a/4chan_x.user.js +++ b/4chan_x.user.js @@ -2873,15 +2873,15 @@ return $.rm(thumb.nextSibling); }, expand: function(thumb) { - var a, filesize, img, max, _, _ref; + var a, filesize, img, max; a = thumb.parentNode; img = $.el('img', { src: a.href }); if (engine === 'gecko' && a.parentNode.className !== 'op') { - filesize = $('.filesize', a.parentNode); - _ref = filesize.textContent.match(/(\d+)x/), _ = _ref[0], max = _ref[1]; - img.style.maxWidth = "" + max + "px"; + filesize = $.x('preceding-sibling::span[@class="filesize"]', a).textContent; + max = filesize.match(/(\d+)x/); + img.style.maxWidth = "" + max[1] + "px"; } $.on(img, 'error', imgExpand.error); thumb.hidden = true; diff --git a/changelog b/changelog index 66033bbdb..1f083a29e 100644 --- a/changelog +++ b/changelog @@ -1,6 +1,7 @@ master - mayhem change 'Duckroll' for 'Cross-thread' + fix image expanding fitness with an inlined backlink on Firefox 2.22.0 - mayhem diff --git a/script.coffee b/script.coffee index 93124fa1d..ed2013b20 100644 --- a/script.coffee +++ b/script.coffee @@ -2208,9 +2208,9 @@ imgExpand = img = $.el 'img', src: a.href if engine is 'gecko' and a.parentNode.className isnt 'op' - filesize = $ '.filesize', a.parentNode - [_, max] = filesize.textContent.match /(\d+)x/ - img.style.maxWidth = "#{max}px" + filesize = $.x('preceding-sibling::span[@class="filesize"]', a).textContent + max = filesize.match /(\d+)x/ + img.style.maxWidth = "#{max[1]}px" $.on img, 'error', imgExpand.error thumb.hidden = true $.add a, img From dc0386a05cb2d20b272c683c80ecd44f58288077 Mon Sep 17 00:00:00 2001 From: Nicolas Stepien Date: Sun, 4 Dec 2011 18:08:32 +0100 Subject: [PATCH 111/169] Release 2.22.1. --- 4chan_x.user.js | 6 +++--- Cakefile | 2 +- changelog | 2 ++ latest.js | 2 +- script.coffee | 2 +- 5 files changed, 8 insertions(+), 6 deletions(-) diff --git a/4chan_x.user.js b/4chan_x.user.js index 24c70ca1a..198735e08 100644 --- a/4chan_x.user.js +++ b/4chan_x.user.js @@ -1,6 +1,6 @@ // ==UserScript== // @name 4chan x -// @version 2.22.0 +// @version 2.22.1 // @namespace aeosynth // @description Adds various features. // @copyright 2009-2011 James Campos @@ -15,7 +15,7 @@ * * Copyright (c) 2009-2011 James Campos * http://mayhemydg.github.com/4chan-x/ - * 4chan x 2.22.0 + * 4chan x 2.22.1 * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation @@ -212,7 +212,7 @@ NAMESPACE = '4chan_x.'; - VERSION = '2.22.0'; + VERSION = '2.22.1'; SECOND = 1000; diff --git a/Cakefile b/Cakefile index 3eb187528..311c0dee6 100644 --- a/Cakefile +++ b/Cakefile @@ -2,7 +2,7 @@ {exec} = require 'child_process' fs = require 'fs' -VERSION = '2.22.0' +VERSION = '2.22.1' HEADER = """ // ==UserScript== diff --git a/changelog b/changelog index 1f083a29e..e8c3ed852 100644 --- a/changelog +++ b/changelog @@ -1,4 +1,6 @@ master + +2.22.1 - mayhem change 'Duckroll' for 'Cross-thread' fix image expanding fitness with an inlined backlink on Firefox diff --git a/latest.js b/latest.js index 365cd42ac..371c7c3f9 100644 --- a/latest.js +++ b/latest.js @@ -1 +1 @@ -postMessage({version:'2.22.0'},'*'); +postMessage({version:'2.22.1'},'*'); diff --git a/script.coffee b/script.coffee index ed2013b20..ee553972f 100644 --- a/script.coffee +++ b/script.coffee @@ -124,7 +124,7 @@ conf = {} ) null, config NAMESPACE = '4chan_x.' -VERSION = '2.22.0' +VERSION = '2.22.1' SECOND = 1000 MINUTE = 60*SECOND HOUR = 60*MINUTE From b85f525758a24838d93e349755dad5d671b9c4c8 Mon Sep 17 00:00:00 2001 From: Nicolas Stepien Date: Mon, 5 Dec 2011 18:37:11 +0100 Subject: [PATCH 112/169] Verify that data.version is actually sent, should resolve issue #29 --- 4chan_x.user.js | 2 +- changelog | 2 ++ script.coffee | 2 +- 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/4chan_x.user.js b/4chan_x.user.js index 198735e08..559bc8bc2 100644 --- a/4chan_x.user.js +++ b/4chan_x.user.js @@ -3064,7 +3064,7 @@ origin = e.origin, data = e.data; if (origin === 'http://sys.4chan.org') { return qr.message(data); - } else if (data.version !== VERSION && confirm('An updated version of 4chan X is available, would you like to install it now?')) { + } else if (data.version && data.version !== VERSION && confirm('An updated version of 4chan X is available, would you like to install it now?')) { return window.location = "https://raw.github.com/mayhemydg/4chan-x/" + data.version + "/4chan_x.user.js"; } }, diff --git a/changelog b/changelog index e8c3ed852..41da7637e 100644 --- a/changelog +++ b/changelog @@ -1,4 +1,6 @@ master +- mayhem + fix obscure and continuous prompts to auto update 2.22.1 - mayhem diff --git a/script.coffee b/script.coffee index ee553972f..ab0e97dd4 100644 --- a/script.coffee +++ b/script.coffee @@ -2437,7 +2437,7 @@ Main = {origin, data} = e if origin is 'http://sys.4chan.org' qr.message data - else if data.version isnt VERSION and confirm 'An updated version of 4chan X is available, would you like to install it now?' + else if data.version and data.version isnt VERSION and confirm 'An updated version of 4chan X is available, would you like to install it now?' window.location = "https://raw.github.com/mayhemydg/4chan-x/#{data.version}/4chan_x.user.js" node: (e) -> From fac47e92b0e5fb0a6baf492584cb53c85fb642d1 Mon Sep 17 00:00:00 2001 From: Nicolas Stepien Date: Mon, 5 Dec 2011 20:46:32 +0100 Subject: [PATCH 113/169] Indicate if the settings require a feature to be enabled. Close #28 --- 4chan_x.user.js | 27 ++++++++++++++++++++++++--- changelog | 1 + script.coffee | 23 +++++++++++++++++++++-- 3 files changed, 46 insertions(+), 5 deletions(-) diff --git a/4chan_x.user.js b/4chan_x.user.js index 559bc8bc2..a521350ce 100644 --- a/4chan_x.user.js +++ b/4chan_x.user.js @@ -1244,7 +1244,7 @@ } }, dialog: function() { - var arr, back, checked, description, dialog, hiddenNum, hiddenThreads, input, key, li, obj, overlay, ta, time, ul, _i, _j, _len, _len2, _ref, _ref2, _ref3; + var arr, back, checked, description, dialog, hiddenNum, hiddenThreads, indicator, indicators, input, key, li, obj, overlay, ta, time, ul, _i, _j, _k, _len, _len2, _len3, _ref, _ref2, _ref3, _ref4; dialog = ui.dialog('options', '', '\
        \
        \ @@ -1264,9 +1264,13 @@ \
        \ \ - \ +
        \ +

        Sauce is disabled.

        \ + \ +
        \ \
        \ +

        Filter is disabled.

        \ Use regular expressions, one per line.
        \ For example, /weeaboo/i will filter posts containing `weeaboo` case-insensitive.\

        Name:

        \ @@ -1280,10 +1284,12 @@
        \ \
        \ +

        Quote Backlinks are disabled.

        \
          \ Backlink formatting\
        • :
        • \
        \ +

        Time Formatting is disabled.

        \
          \ Time formatting\
        • :
        • \ @@ -1297,6 +1303,7 @@
        \ \
        \ +

        Keybinds are disabled.

        \
        ActionsKeybinds
        Close Options or QR
        \ \ \ @@ -1365,6 +1372,17 @@ input.value = conf[input.name]; $.on(input, 'keydown', options.keybind); } + indicators = {}; + _ref4 = $$('.error', dialog); + for (_k = 0, _len3 = _ref4.length; _k < _len3; _k++) { + indicator = _ref4[_k]; + key = indicator.firstChild.textContent; + indicator.hidden = conf[key]; + indicators[key] = indicator; + $.on($("[name='" + key + "']", dialog), 'click', function() { + return indicators[this.name].hidden = this.checked; + }); + } overlay = $.el('div', { id: 'overlay' }); @@ -3184,7 +3202,7 @@ #options [name=tab]:not(:checked) + * {\ display: none;\ }\ - #content > * {\ + #content > div {\ height: 450px;\ overflow: auto;\ }\ @@ -3194,6 +3212,9 @@ resize: vertical;\ width: 100%;\ }\ + #flavors {\ + height: 100%;\ + }\ \ #qr {\ position: fixed;\ diff --git a/changelog b/changelog index 41da7637e..819068c1f 100644 --- a/changelog +++ b/changelog @@ -1,5 +1,6 @@ master - mayhem + indicate if the settings require a feature to be enabled fix obscure and continuous prompts to auto update 2.22.1 diff --git a/script.coffee b/script.coffee index ab0e97dd4..e6d93d4c6 100644 --- a/script.coffee +++ b/script.coffee @@ -913,9 +913,13 @@ options =
        - +
        +

        Sauce is disabled.

        + +
        +

        Filter is disabled.

        Use regular expressions, one per line.
        For example, /weeaboo/i will filter posts containing `weeaboo` case-insensitive.

        Name:

        @@ -929,10 +933,12 @@ options =
        +

        Quote Backlinks are disabled.

          Backlink formatting
        • :
        +

        Time Formatting is disabled.

          Time formatting
        • :
        • @@ -946,6 +952,7 @@ options =
        +

        Keybinds are disabled.

        ActionsKeybinds
        Close Options or QR
        @@ -1010,6 +1017,15 @@ options = input.value = conf[input.name] $.on input, 'keydown', options.keybind + #indicate if the settings require a feature to be enabled + indicators = {} + for indicator in $$ '.error', dialog + key = indicator.firstChild.textContent + indicator.hidden = conf[key] + indicators[key] = indicator + $.on $("[name='#{key}']", dialog), 'click', -> + indicators[@name].hidden = @checked + overlay = $.el 'div', id: 'overlay' $.on overlay, 'click', -> $.rm overlay $.on dialog, 'click', (e) -> e.stopPropagation() @@ -2549,7 +2565,7 @@ Main = #options [name=tab]:not(:checked) + * { display: none; } - #content > * { + #content > div { height: 450px; overflow: auto; } @@ -2559,6 +2575,9 @@ Main = resize: vertical; width: 100%; } + #flavors { + height: 100%; + } #qr { position: fixed; From 1515cc26d73db8a402364466f5eaf35abf8e1deb Mon Sep 17 00:00:00 2001 From: Nicolas Stepien Date: Mon, 5 Dec 2011 21:40:41 +0100 Subject: [PATCH 114/169] Use DIVs instead of Ps for indicators. --- 4chan_x.user.js | 10 +++++----- script.coffee | 10 +++++----- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/4chan_x.user.js b/4chan_x.user.js index a521350ce..d01e5bb95 100644 --- a/4chan_x.user.js +++ b/4chan_x.user.js @@ -1265,12 +1265,12 @@
        \ \
        \ -

        Sauce is disabled.

        \ +
        Sauce is disabled.
        \ \
        \ \
        \ -

        Filter is disabled.

        \ +
        Filter is disabled.
        \ Use regular expressions, one per line.
        \ For example, /weeaboo/i will filter posts containing `weeaboo` case-insensitive.\

        Name:

        \ @@ -1284,12 +1284,12 @@
        \ \
        \ -

        Quote Backlinks are disabled.

        \ +
        Quote Backlinks are disabled.
        \
          \ Backlink formatting\
        • :
        • \
        \ -

        Time Formatting is disabled.

        \ +
        Time Formatting is disabled.
        \
          \ Time formatting\
        • :
        • \ @@ -1303,7 +1303,7 @@
        \ \
        \ -

        Keybinds are disabled.

        \ +
        Keybinds are disabled.
        \
        ActionsKeybinds
        Close Options or QR
        \ \ \ diff --git a/script.coffee b/script.coffee index e6d93d4c6..f5115d5fc 100644 --- a/script.coffee +++ b/script.coffee @@ -914,12 +914,12 @@ options =
        -

        Sauce is disabled.

        +
        Sauce is disabled.
        -

        Filter is disabled.

        +
        Filter is disabled.
        Use regular expressions, one per line.
        For example, /weeaboo/i will filter posts containing `weeaboo` case-insensitive.

        Name:

        @@ -933,12 +933,12 @@ options =
        -

        Quote Backlinks are disabled.

        +
        Quote Backlinks are disabled.
          Backlink formatting
        • :
        -

        Time Formatting is disabled.

        +
        Time Formatting is disabled.
          Time formatting
        • :
        • @@ -952,7 +952,7 @@ options =
        -

        Keybinds are disabled.

        +
        Keybinds are disabled.
        ActionsKeybinds
        Close Options or QR
        From c2e54a904b41465736e6949a604f974bba7723d0 Mon Sep 17 00:00:00 2001 From: Nicolas Stepien Date: Tue, 6 Dec 2011 00:53:58 +0100 Subject: [PATCH 115/169] Release 2.22.2 --- 4chan_x.user.js | 6 +++--- Cakefile | 2 +- changelog | 2 ++ latest.js | 2 +- script.coffee | 2 +- 5 files changed, 8 insertions(+), 6 deletions(-) diff --git a/4chan_x.user.js b/4chan_x.user.js index d01e5bb95..75474c209 100644 --- a/4chan_x.user.js +++ b/4chan_x.user.js @@ -1,6 +1,6 @@ // ==UserScript== // @name 4chan x -// @version 2.22.1 +// @version 2.22.2 // @namespace aeosynth // @description Adds various features. // @copyright 2009-2011 James Campos @@ -15,7 +15,7 @@ * * Copyright (c) 2009-2011 James Campos * http://mayhemydg.github.com/4chan-x/ - * 4chan x 2.22.1 + * 4chan x 2.22.2 * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation @@ -212,7 +212,7 @@ NAMESPACE = '4chan_x.'; - VERSION = '2.22.1'; + VERSION = '2.22.2'; SECOND = 1000; diff --git a/Cakefile b/Cakefile index 311c0dee6..ce4e5dc40 100644 --- a/Cakefile +++ b/Cakefile @@ -2,7 +2,7 @@ {exec} = require 'child_process' fs = require 'fs' -VERSION = '2.22.1' +VERSION = '2.22.2' HEADER = """ // ==UserScript== diff --git a/changelog b/changelog index 819068c1f..8193a1627 100644 --- a/changelog +++ b/changelog @@ -1,4 +1,6 @@ master + +2.22.2 - mayhem indicate if the settings require a feature to be enabled fix obscure and continuous prompts to auto update diff --git a/latest.js b/latest.js index 371c7c3f9..d69056e99 100644 --- a/latest.js +++ b/latest.js @@ -1 +1 @@ -postMessage({version:'2.22.1'},'*'); +postMessage({version:'2.22.2'},'*'); diff --git a/script.coffee b/script.coffee index f5115d5fc..c01cc134d 100644 --- a/script.coffee +++ b/script.coffee @@ -124,7 +124,7 @@ conf = {} ) null, config NAMESPACE = '4chan_x.' -VERSION = '2.22.1' +VERSION = '2.22.2' SECOND = 1000 MINUTE = 60*SECOND HOUR = 60*MINUTE From ea4c581d2ab4a4255b7cb202b1ad910808726b29 Mon Sep 17 00:00:00 2001 From: Nicolas Stepien Date: Tue, 6 Dec 2011 15:31:01 +0100 Subject: [PATCH 116/169] Update the captcha caching expiration date. --- 4chan_x.user.js | 4 ++-- changelog | 2 ++ script.coffee | 4 ++-- 3 files changed, 6 insertions(+), 4 deletions(-) diff --git a/4chan_x.user.js b/4chan_x.user.js index 75474c209..fc0916eea 100644 --- a/4chan_x.user.js +++ b/4chan_x.user.js @@ -1620,10 +1620,10 @@ content = $('textarea', qr.el).value || $('input[type=file]', qr.el).files.length; if (!content) return 'Error: No text entered.'; /* - captchas expire after 5 hours (emperically verified). cutoff 5 minutes + captchas expire after 30 minutes (emperically verified). cutoff 5 minutes before then, b/c posting takes time. */ - cutoff = Date.now() - 5 * HOUR + 5 * MINUTE; + cutoff = Date.now() - 25 * MINUTE; captchas = $.get('captchas', []); while (captcha = captchas.shift()) { if (captcha.time > cutoff) break; diff --git a/changelog b/changelog index 8193a1627..a63d81432 100644 --- a/changelog +++ b/changelog @@ -1,4 +1,6 @@ master +- aeosynth + update the captcha caching expiration date to 30mins 2.22.2 - mayhem diff --git a/script.coffee b/script.coffee index c01cc134d..863d8646c 100644 --- a/script.coffee +++ b/script.coffee @@ -1255,11 +1255,11 @@ qr = return 'Error: No text entered.' unless content ### - captchas expire after 5 hours (emperically verified). cutoff 5 minutes + captchas expire after 30 minutes (emperically verified). cutoff 5 minutes before then, b/c posting takes time. ### - cutoff = Date.now() - 5*HOUR + 5*MINUTE + cutoff = Date.now() - 25*MINUTE captchas = $.get 'captchas', [] while captcha = captchas.shift() if captcha.time > cutoff From 667cb36461a5ed9a46e0c92c0fb7ac565dfda0ed Mon Sep 17 00:00:00 2001 From: Nicolas Stepien Date: Tue, 6 Dec 2011 20:10:05 +0100 Subject: [PATCH 117/169] Insert quotes at caret position; replace text selection with quotes; fix an old bug. Close #24 --- 4chan_x.user.js | 6 ++++-- changelog | 3 +++ script.coffee | 10 +++++++--- 3 files changed, 14 insertions(+), 5 deletions(-) diff --git a/4chan_x.user.js b/4chan_x.user.js index fc0916eea..8ed9155e4 100644 --- a/4chan_x.user.js +++ b/4chan_x.user.js @@ -1658,15 +1658,17 @@ text = ">>" + id + "\n"; selection = window.getSelection(); if (s = selection.toString()) { - selectionID = (_ref = $.x('preceding::input[@type="checkbox"][1]', selection.anchorNode)) != null ? _ref.name : void 0; + selectionID = (_ref = $.x('ancestor::blockquote', selection.anchorNode)) != null ? _ref.parentNode.firstElementChild.name : void 0; if (selectionID === id) { s = s.replace(/\n/g, '\n>'); text += ">" + s + "\n"; } } ta = $('textarea', qr.el); + ta.value = ta.value.slice(0, ta.selectionStart) + text + ta.value.slice(ta.selectionEnd, ta.value.length); ta.focus(); - return ta.value += text; + ta.selectionEnd = ta.selectionStart + text.length; + return window.getSelection().collapseToEnd(); }, refresh: function() { var m, newFile, oldFile, _ref; diff --git a/changelog b/changelog index a63d81432..5dab58ce4 100644 --- a/changelog +++ b/changelog @@ -1,4 +1,7 @@ master +- mayhem + quotes are now inserted at the caret position in the QR + quotes also replace the text selection in the QR - aeosynth update the captcha caching expiration date to 30mins diff --git a/script.coffee b/script.coffee index 863d8646c..e1644c1bf 100644 --- a/script.coffee +++ b/script.coffee @@ -1295,14 +1295,18 @@ qr = selection = window.getSelection() if s = selection.toString() - selectionID = $.x('preceding::input[@type="checkbox"][1]', selection.anchorNode)?.name - if selectionID == id + selectionID = $.x('ancestor::blockquote', selection.anchorNode)?.parentNode.firstElementChild.name + if selectionID is id s = s.replace /\n/g, '\n>' text += ">#{s}\n" ta = $ 'textarea', qr.el + #replace selection for text + ta.value = ta.value.slice(0, ta.selectionStart) + text + ta.value.slice(ta.selectionEnd, ta.value.length) ta.focus() - ta.value += text + #move the caret to the end of the new quote + ta.selectionEnd = ta.selectionStart + text.length + window.getSelection().collapseToEnd() refresh: -> $('[name=sub]', qr.el).value = '' From ccad16264d41ac42933736c83d52f3ae45973115 Mon Sep 17 00:00:00 2001 From: Nicolas Stepien Date: Tue, 6 Dec 2011 21:19:55 +0100 Subject: [PATCH 118/169] Shave a line, fix firefox leaving the text selected when quoting opens the QR. (wtf?) --- 4chan_x.user.js | 3 +-- script.coffee | 3 +-- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/4chan_x.user.js b/4chan_x.user.js index 8ed9155e4..8d92b64c1 100644 --- a/4chan_x.user.js +++ b/4chan_x.user.js @@ -1667,8 +1667,7 @@ ta = $('textarea', qr.el); ta.value = ta.value.slice(0, ta.selectionStart) + text + ta.value.slice(ta.selectionEnd, ta.value.length); ta.focus(); - ta.selectionEnd = ta.selectionStart + text.length; - return window.getSelection().collapseToEnd(); + return ta.selectionStart = ta.selectionEnd = ta.selectionStart + text.length; }, refresh: function() { var m, newFile, oldFile, _ref; diff --git a/script.coffee b/script.coffee index e1644c1bf..afe6120dd 100644 --- a/script.coffee +++ b/script.coffee @@ -1305,8 +1305,7 @@ qr = ta.value = ta.value.slice(0, ta.selectionStart) + text + ta.value.slice(ta.selectionEnd, ta.value.length) ta.focus() #move the caret to the end of the new quote - ta.selectionEnd = ta.selectionStart + text.length - window.getSelection().collapseToEnd() + ta.selectionStart = ta.selectionEnd = ta.selectionStart + text.length refresh: -> $('[name=sub]', qr.el).value = '' From 0c56b42f37bb555f03a9eb149565da9800e4a1b9 Mon Sep 17 00:00:00 2001 From: Nicolas Stepien Date: Tue, 6 Dec 2011 21:33:31 +0100 Subject: [PATCH 119/169] Fix last Firefox issue. --- 4chan_x.user.js | 7 ++++--- script.coffee | 5 +++-- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/4chan_x.user.js b/4chan_x.user.js index 8d92b64c1..a47dcbd4e 100644 --- a/4chan_x.user.js +++ b/4chan_x.user.js @@ -1647,7 +1647,7 @@ return false; }, quote: function(e) { - var id, s, selection, selectionID, ta, text, _ref; + var caretPos, id, s, selection, selectionID, ta, text, _ref; if (e) e.preventDefault(); if (qr.el) { $('#autohide', qr.el).checked = false; @@ -1665,9 +1665,10 @@ } } ta = $('textarea', qr.el); - ta.value = ta.value.slice(0, ta.selectionStart) + text + ta.value.slice(ta.selectionEnd, ta.value.length); + caretPos = ta.selectionStart; + ta.value = ta.value.slice(0, caretPos) + text + ta.value.slice(ta.selectionEnd, ta.value.length); ta.focus(); - return ta.selectionStart = ta.selectionEnd = ta.selectionStart + text.length; + return ta.selectionStart = ta.selectionEnd = caretPos + text.length; }, refresh: function() { var m, newFile, oldFile, _ref; diff --git a/script.coffee b/script.coffee index afe6120dd..af69c225b 100644 --- a/script.coffee +++ b/script.coffee @@ -1301,11 +1301,12 @@ qr = text += ">#{s}\n" ta = $ 'textarea', qr.el + caretPos = ta.selectionStart #replace selection for text - ta.value = ta.value.slice(0, ta.selectionStart) + text + ta.value.slice(ta.selectionEnd, ta.value.length) + ta.value = ta.value.slice(0, caretPos) + text + ta.value.slice(ta.selectionEnd, ta.value.length) ta.focus() #move the caret to the end of the new quote - ta.selectionStart = ta.selectionEnd = ta.selectionStart + text.length + ta.selectionStart = ta.selectionEnd = caretPos + text.length refresh: -> $('[name=sub]', qr.el).value = '' From 6341f070bac51b99aa251133ebc154f2b8e2e760 Mon Sep 17 00:00:00 2001 From: Nicolas Stepien Date: Wed, 7 Dec 2011 11:44:44 +0100 Subject: [PATCH 120/169] Open the QR focused when using the 'Open QR without post number inserted' keybind --- 4chan_x.user.js | 7 ++----- changelog | 1 + script.coffee | 5 ++--- 3 files changed, 5 insertions(+), 8 deletions(-) diff --git a/4chan_x.user.js b/4chan_x.user.js index a47dcbd4e..c6650384b 100644 --- a/4chan_x.user.js +++ b/4chan_x.user.js @@ -1072,11 +1072,8 @@ if (quote) { return qr.quote.call($('.quotejs + a', $('.replyhl', thread) || thread)); } else { - if (qr.el) { - return $('textarea', qr.el).focus(); - } else { - return qr.dialog('', thread != null ? thread.firstChild.id : void 0); - } + if (!qr.el) qr.dialog('', thread != null ? thread.firstChild.id : void 0); + return $('textarea', qr.el).focus(); } }, open: function(thread, tab) { diff --git a/changelog b/changelog index 5dab58ce4..323fd991d 100644 --- a/changelog +++ b/changelog @@ -2,6 +2,7 @@ master - mayhem quotes are now inserted at the caret position in the QR quotes also replace the text selection in the QR + open QR focused when using the `Open QR without post number inserted` keybind - aeosynth update the captcha caching expiration date to 30mins diff --git a/script.coffee b/script.coffee index af69c225b..35ffc136d 100644 --- a/script.coffee +++ b/script.coffee @@ -750,10 +750,9 @@ keybinds = if quote qr.quote.call $ '.quotejs + a', $('.replyhl', thread) or thread else - if qr.el - $('textarea', qr.el).focus() - else + unless qr.el qr.dialog '', thread?.firstChild.id + $('textarea', qr.el).focus() open: (thread, tab) -> id = thread.firstChild.id From 9460ec715c857b09f12ffc47cdf957c7d692ffda Mon Sep 17 00:00:00 2001 From: Nicolas Stepien Date: Wed, 7 Dec 2011 21:47:19 +0100 Subject: [PATCH 121/169] Favicon customization. --- 4chan_x.user.js | 73 +++++++++++++++++++++++++++++++++++-------------- changelog | 1 + script.coffee | 60 ++++++++++++++++++++++++++++------------ 3 files changed, 95 insertions(+), 39 deletions(-) diff --git a/4chan_x.user.js b/4chan_x.user.js index c6650384b..8e038f277 100644 --- a/4chan_x.user.js +++ b/4chan_x.user.js @@ -137,6 +137,7 @@ flavors: ['http://iqdb.org/?url=', 'http://google.com/searchbyimage?image_url=', '#http://tineye.com/search?url=', '#http://saucenao.com/search.php?db=999&url=', '#http://3d.iqdb.org/?url=', '#http://regex.info/exif.cgi?imgurl=', '#http://imgur.com/upload?url='].join('\n'), time: '%m/%d/%y(%a)%H:%M', backlink: '>>%id', + favicon: 'ferongr', hotkeys: { close: 'Esc', spoiler: 'ctrl+s', @@ -1241,7 +1242,7 @@ } }, dialog: function() { - var arr, back, checked, description, dialog, hiddenNum, hiddenThreads, indicator, indicators, input, key, li, obj, overlay, ta, time, ul, _i, _j, _k, _len, _len2, _len3, _ref, _ref2, _ref3, _ref4; + var arr, back, checked, description, dialog, favicon, hiddenNum, hiddenThreads, indicator, indicators, input, key, li, obj, option, overlay, ta, time, ul, _i, _j, _k, _l, _len, _len2, _len3, _len4, _ref, _ref2, _ref3, _ref4, _ref5; dialog = ui.dialog('options', '', '\
        \
        \ @@ -1297,6 +1298,12 @@
      • Hour: %k, %H, %l (lowercase L), %I (uppercase i), %p, %P
      • \
      • Minutes: %M
      • \ \ +
        Unread Count is disabled.
        \ + \ + \
        \ \
        \ @@ -1362,17 +1369,27 @@ (time = $('[name=time]', dialog)).value = conf['time']; $.on(back, 'keyup', options.backlink); $.on(time, 'keyup', options.time); - _ref3 = $$('#keybinds_tab + div input', dialog); + favicon = $('select', dialog); + _ref3 = favicon.options; for (_j = 0, _len2 = _ref3.length; _j < _len2; _j++) { - input = _ref3[_j]; + option = _ref3[_j]; + if (option.textContent === conf['favicon']) { + option.selected = true; + break; + } + } + $.on(favicon, 'change', options.favicon); + _ref4 = $$('#keybinds_tab + div input', dialog); + for (_k = 0, _len3 = _ref4.length; _k < _len3; _k++) { + input = _ref4[_k]; input.type = 'text'; input.value = conf[input.name]; $.on(input, 'keydown', options.keybind); } indicators = {}; - _ref4 = $$('.error', dialog); - for (_k = 0, _len3 = _ref4.length; _k < _len3; _k++) { - indicator = _ref4[_k]; + _ref5 = $$('.error', dialog); + for (_l = 0, _len4 = _ref5.length; _l < _len4; _l++) { + indicator = _ref5[_l]; key = indicator.firstChild.textContent; indicator.hidden = conf[key]; indicators[key] = indicator; @@ -1391,8 +1408,9 @@ }); $.add(overlay, dialog); $.add(d.body, overlay); + options.backlink.call(back); options.time.call(time); - return options.backlink.call(back); + return options.favicon.call(favicon); }, clearHidden: function() { $["delete"]("hiddenReplies/" + g.BOARD + "/"); @@ -1405,20 +1423,23 @@ e.stopPropagation(); if ((key = keybinds.keyCode(e)) == null) return; this.value = key; - $.set(this.name, key); - return conf[this.name] = key; + return $.cb.value.call(this); }, time: function() { - $.set('time', this.value); - conf['time'] = this.value; + $.cb.value.call(this); Time.foo(); Time.date = new Date(); return $('#timePreview').textContent = Time.funk(Time); }, backlink: function() { - $.set('backlink', this.value); - conf['backlink'] = this.value; + $.cb.value.call(this); return $('#backlinkPreview').textContent = conf['backlink'].replace(/%id/, '123456789'); + }, + favicon: function() { + $.cb.value.call(this); + Favicon["switch"](); + Favicon.update(); + return this.nextElementSibling.innerHTML = ""; } }; @@ -2712,19 +2733,29 @@ favicon = $('link[rel="shortcut icon"]', d.head); favicon.type = 'image/x-icon'; href = favicon.href; - Favicon["default"] = href; - return Favicon.unread = /ws/.test(href) ? Favicon.unreadSFW : Favicon.unreadNSFW; + this.SFW = /ws.ico$/.test(href); + this["default"] = href; + return this["switch"](); + }, + "switch": function() { + switch (conf['favicon']) { + case 'ferongr': + this.unreadDead = 'data:image/gif;base64,R0lGODlhEAAQAOMHAOgLAnMFAL8AAOgLAukMA/+AgP+rq////////////////////////////////////yH5BAEKAAcALAAAAAAQABAAAARZ8MhJ6xwDWIBv+AM1fEEIBIVRlNKYrtpIECuGzuwpCLg974EYiXUYkUItjGbC6VQ4omXFiKROA6qSy0A8nAo9GS3YCswIWnOvLAi0be23Z1QtdSUaqXcviQAAOw=='; + this.unreadSFW = 'data:image/gif;base64,R0lGODlhEAAQAOMHAADX8QBwfgC2zADX8QDY8nnl8qLp8v///////////////////////////////////yH5BAEKAAcALAAAAAAQABAAAARZ8MhJ6xwDWIBv+AM1fEEIBIVRlNKYrtpIECuGzuwpCLg974EYiXUYkUItjGbC6VQ4omXFiKROA6qSy0A8nAo9GS3YCswIWnOvLAi0be23Z1QtdSUaqXcviQAAOw=='; + this.unreadNSFW = 'data:image/gif;base64,R0lGODlhEAAQAOMHAFT+ACh5AEncAFT+AFX/Acz/su7/5v///////////////////////////////////yH5BAEKAAcALAAAAAAQABAAAARZ8MhJ6xwDWIBv+AM1fEEIBIVRlNKYrtpIECuGzuwpCLg974EYiXUYkUItjGbC6VQ4omXFiKROA6qSy0A8nAo9GS3YCswIWnOvLAi0be23Z1QtdSUaqXcviQAAOw=='; + break; + case 'None': + this.unreadDead = this.unreadSFW = this.unreadNSFW = this["default"]; + } + return this.unread = this.SFW ? this.unreadSFW : this.unreadNSFW; }, empty: 'data:image/gif;base64,R0lGODlhEAAQAJEAAAAAAP///9vb2////yH5BAEAAAMALAAAAAAQABAAAAIvnI+pq+D9DBAUoFkPFnbs7lFZKIJOJJ3MyraoB14jFpOcVMpzrnF3OKlZYsMWowAAOw==', dead: 'data:image/gif;base64,R0lGODlhEAAQAKECAAAAAP8AAP///////yH5BAEKAAIALAAAAAAQABAAAAIvlI+pq+D9DAgUoFkPDlbs7lFZKIJOJJ3MyraoB14jFpOcVMpzrnF3OKlZYsMWowAAOw==', - unreadDead: 'data:image/png;base64,R0lGODlhEAAQAOMHAOgLAnMFAL8AAOgLAukMA/+AgP+rq////////////////////////////////////yH5BAEKAAcALAAAAAAQABAAAARZ8MhJ6xwDWIBv+AM1fEEIBIVRlNKYrtpIECuGzuwpCLg974EYiXUYkUItjGbC6VQ4omXFiKROA6qSy0A8nAo9GS3YCswIWnOvLAi0be23Z1QtdSUaqXcviQAAOw==', - unreadSFW: 'data:image/png;base64,R0lGODlhEAAQAOMHAADX8QBwfgC2zADX8QDY8nnl8qLp8v///////////////////////////////////yH5BAEKAAcALAAAAAAQABAAAARZ8MhJ6xwDWIBv+AM1fEEIBIVRlNKYrtpIECuGzuwpCLg974EYiXUYkUItjGbC6VQ4omXFiKROA6qSy0A8nAo9GS3YCswIWnOvLAi0be23Z1QtdSUaqXcviQAAOw==', - unreadNSFW: 'data:image/png;base64,R0lGODlhEAAQAOMHAFT+ACh5AEncAFT+AFX/Acz/su7/5v///////////////////////////////////yH5BAEKAAcALAAAAAAQABAAAARZ8MhJ6xwDWIBv+AM1fEEIBIVRlNKYrtpIECuGzuwpCLg974EYiXUYkUItjGbC6VQ4omXFiKROA6qSy0A8nAo9GS3YCswIWnOvLAi0be23Z1QtdSUaqXcviQAAOw==', update: function() { var clone, favicon, l; l = unread.replies.length; favicon = $('link[rel="shortcut icon"]', d.head); - favicon.href = g.dead ? l ? Favicon.unreadDead : Favicon.dead : l ? Favicon.unread : Favicon["default"]; + favicon.href = g.dead ? l ? this.unreadDead : this.dead : l ? this.unread : this["default"]; if (engine === "gecko") { clone = favicon.cloneNode(true); return $.replace(favicon, clone); @@ -2929,7 +2960,8 @@ innerHTML: " " }); imageType = $.get('imageType', 'full'); - _ref = $$('option', controls); + select = $('select', controls); + _ref = select.options; for (_i = 0, _len = _ref.length; _i < _len; _i++) { option = _ref[_i]; if (option.textContent === imageType) { @@ -2937,7 +2969,6 @@ break; } } - select = $('select', controls); imgExpand.cb.typeChange.call(select); $.on(select, 'change', $.cb.value); $.on(select, 'change', imgExpand.cb.typeChange); diff --git a/changelog b/changelog index 323fd991d..216864283 100644 --- a/changelog +++ b/changelog @@ -1,5 +1,6 @@ master - mayhem + multiple unread favicons to chose in the options quotes are now inserted at the caret position in the QR quotes also replace the text selection in the QR open QR focused when using the `Open QR without post number inserted` keybind diff --git a/script.coffee b/script.coffee index 35ffc136d..b0c4030df 100644 --- a/script.coffee +++ b/script.coffee @@ -66,6 +66,7 @@ config = ].join '\n' time: '%m/%d/%y(%a)%H:%M' backlink: '>>%id' + favicon: 'ferongr' hotkeys: close: 'Esc' spoiler: 'ctrl+s' @@ -948,6 +949,12 @@ options =
      • Hour: %k, %H, %l (lowercase L), %I (uppercase i), %p, %P
      • Minutes: %M
      • +
        Unread Count is disabled.
        + +
        @@ -1009,6 +1016,12 @@ options = (time = $ '[name=time]', dialog).value = conf['time'] $.on back, 'keyup', options.backlink $.on time, 'keyup', options.time + favicon = $ 'select', dialog + for option in favicon.options + if option.textContent is conf['favicon'] + option.selected = true + break + $.on favicon, 'change', options.favicon #keybinds for input in $$ '#keybinds_tab + div input', dialog @@ -1031,8 +1044,9 @@ options = $.add overlay, dialog $.add d.body, overlay - options.time.call time options.backlink.call back + options.time.call time + options.favicon.call favicon clearHidden: -> #'hidden' might be misleading; it's the number of IDs we're *looking* for, @@ -1046,18 +1060,20 @@ options = e.stopPropagation() return unless (key = keybinds.keyCode e)? @value = key - $.set @name, key - conf[@name] = key + $.cb.value.call @ time: -> - $.set 'time', @value - conf['time'] = @value + $.cb.value.call @ Time.foo() Time.date = new Date() $('#timePreview').textContent = Time.funk Time backlink: -> - $.set 'backlink', @value - conf['backlink'] = @value + $.cb.value.call @ $('#backlinkPreview').textContent = conf['backlink'].replace /%id/, '123456789' + favicon: -> + $.cb.value.call @ + Favicon.switch() + Favicon.update() + @nextElementSibling.innerHTML = "" cooldown = #TODO merge into qr @@ -2103,14 +2119,22 @@ Favicon = favicon = $ 'link[rel="shortcut icon"]', d.head favicon.type = 'image/x-icon' {href} = favicon - Favicon.default = href - Favicon.unread = if /ws/.test href then Favicon.unreadSFW else Favicon.unreadNSFW + @SFW = /ws.ico$/.test href + @default = href + @switch() + + switch: -> + switch conf['favicon'] + when 'ferongr' + @unreadDead = 'data:image/gif;base64,R0lGODlhEAAQAOMHAOgLAnMFAL8AAOgLAukMA/+AgP+rq////////////////////////////////////yH5BAEKAAcALAAAAAAQABAAAARZ8MhJ6xwDWIBv+AM1fEEIBIVRlNKYrtpIECuGzuwpCLg974EYiXUYkUItjGbC6VQ4omXFiKROA6qSy0A8nAo9GS3YCswIWnOvLAi0be23Z1QtdSUaqXcviQAAOw==' + @unreadSFW = 'data:image/gif;base64,R0lGODlhEAAQAOMHAADX8QBwfgC2zADX8QDY8nnl8qLp8v///////////////////////////////////yH5BAEKAAcALAAAAAAQABAAAARZ8MhJ6xwDWIBv+AM1fEEIBIVRlNKYrtpIECuGzuwpCLg974EYiXUYkUItjGbC6VQ4omXFiKROA6qSy0A8nAo9GS3YCswIWnOvLAi0be23Z1QtdSUaqXcviQAAOw==' + @unreadNSFW = 'data:image/gif;base64,R0lGODlhEAAQAOMHAFT+ACh5AEncAFT+AFX/Acz/su7/5v///////////////////////////////////yH5BAEKAAcALAAAAAAQABAAAARZ8MhJ6xwDWIBv+AM1fEEIBIVRlNKYrtpIECuGzuwpCLg974EYiXUYkUItjGbC6VQ4omXFiKROA6qSy0A8nAo9GS3YCswIWnOvLAi0be23Z1QtdSUaqXcviQAAOw==' + when 'None' + @unreadDead = @unreadSFW = @unreadNSFW = @default + @unread = if @SFW then @unreadSFW else @unreadNSFW empty: 'data:image/gif;base64,R0lGODlhEAAQAJEAAAAAAP///9vb2////yH5BAEAAAMALAAAAAAQABAAAAIvnI+pq+D9DBAUoFkPFnbs7lFZKIJOJJ3MyraoB14jFpOcVMpzrnF3OKlZYsMWowAAOw==' dead: 'data:image/gif;base64,R0lGODlhEAAQAKECAAAAAP8AAP///////yH5BAEKAAIALAAAAAAQABAAAAIvlI+pq+D9DAgUoFkPDlbs7lFZKIJOJJ3MyraoB14jFpOcVMpzrnF3OKlZYsMWowAAOw==' - unreadDead: 'data:image/png;base64,R0lGODlhEAAQAOMHAOgLAnMFAL8AAOgLAukMA/+AgP+rq////////////////////////////////////yH5BAEKAAcALAAAAAAQABAAAARZ8MhJ6xwDWIBv+AM1fEEIBIVRlNKYrtpIECuGzuwpCLg974EYiXUYkUItjGbC6VQ4omXFiKROA6qSy0A8nAo9GS3YCswIWnOvLAi0be23Z1QtdSUaqXcviQAAOw==' - unreadSFW: 'data:image/png;base64,R0lGODlhEAAQAOMHAADX8QBwfgC2zADX8QDY8nnl8qLp8v///////////////////////////////////yH5BAEKAAcALAAAAAAQABAAAARZ8MhJ6xwDWIBv+AM1fEEIBIVRlNKYrtpIECuGzuwpCLg974EYiXUYkUItjGbC6VQ4omXFiKROA6qSy0A8nAo9GS3YCswIWnOvLAi0be23Z1QtdSUaqXcviQAAOw==' - unreadNSFW: 'data:image/png;base64,R0lGODlhEAAQAOMHAFT+ACh5AEncAFT+AFX/Acz/su7/5v///////////////////////////////////yH5BAEKAAcALAAAAAAQABAAAARZ8MhJ6xwDWIBv+AM1fEEIBIVRlNKYrtpIECuGzuwpCLg974EYiXUYkUItjGbC6VQ4omXFiKROA6qSy0A8nAo9GS3YCswIWnOvLAi0be23Z1QtdSUaqXcviQAAOw==' update: -> l = unread.replies.length @@ -2119,14 +2143,14 @@ Favicon = favicon.href = if g.dead if l - Favicon.unreadDead + @unreadDead else - Favicon.dead + @dead else if l - Favicon.unread + @unread else - Favicon.default + @default #XXX `favicon.href = href` doesn't work on Firefox if engine is "gecko" @@ -2255,11 +2279,11 @@ imgExpand = " " imageType = $.get 'imageType', 'full' - for option in $$ 'option', controls + select = $ 'select', controls + for option in select.options if option.textContent is imageType option.selected = true break - select = $ 'select', controls imgExpand.cb.typeChange.call select $.on select, 'change', $.cb.value $.on select, 'change', imgExpand.cb.typeChange From ecf6df342bee69c048cd891e069b173904f2a488 Mon Sep 17 00:00:00 2001 From: Nicolas Stepien Date: Wed, 7 Dec 2011 22:02:34 +0100 Subject: [PATCH 122/169] Small fixes. --- 4chan_x.user.js | 3 ++- script.coffee | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/4chan_x.user.js b/4chan_x.user.js index 8e038f277..f113cbd84 100644 --- a/4chan_x.user.js +++ b/4chan_x.user.js @@ -1299,6 +1299,7 @@
      • Minutes: %M
      • \ \
        Unread Count is disabled.
        \ + Unread favicons
        \ @@ -1072,7 +1073,7 @@ options = favicon: -> $.cb.value.call @ Favicon.switch() - Favicon.update() + Favicon.update() if g.REPLY @nextElementSibling.innerHTML = "" cooldown = From cf457fa4e6f8f9ce7dd476f4fbc0916df7bccb6e Mon Sep 17 00:00:00 2001 From: Nicolas Stepien Date: Wed, 7 Dec 2011 22:09:29 +0100 Subject: [PATCH 123/169] Remove myself from the list of contributors. --- 4chan_x.user.js | 11 ++++------- Cakefile | 11 ++++------- 2 files changed, 8 insertions(+), 14 deletions(-) diff --git a/4chan_x.user.js b/4chan_x.user.js index f113cbd84..e66fbd85a 100644 --- a/4chan_x.user.js +++ b/4chan_x.user.js @@ -36,23 +36,20 @@ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR * OTHER DEALINGS IN THE SOFTWARE. - */ - -/* HACKING + * + * HACKING * * 4chan x is written in CoffeeScript[1], and developed on github[2]. * * [1]: http://jashkenas.github.com/coffee-script/ * [2]: http://github.com/mayhemydg/4chan-x - */ - -/* CONTRIBUTORS + * + * CONTRIBUTORS * * Shou- - pentadactyl fixes * ferongr - new favicons * xat- - new favicons * Zixaphir - fix qr textarea - captcha-image gap - * Mayhem - various features / fixes * Ongpot - sfw favicon * thisisanon - nsfw + 404 favicons * Anonymous - empty favicon diff --git a/Cakefile b/Cakefile index ce4e5dc40..8e7bd4803 100644 --- a/Cakefile +++ b/Cakefile @@ -43,23 +43,20 @@ HEADER = """ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR * OTHER DEALINGS IN THE SOFTWARE. - */ - -/* HACKING + * + * HACKING * * 4chan x is written in CoffeeScript[1], and developed on github[2]. * * [1]: http://jashkenas.github.com/coffee-script/ * [2]: http://github.com/mayhemydg/4chan-x - */ - -/* CONTRIBUTORS + * + * CONTRIBUTORS * * Shou- - pentadactyl fixes * ferongr - new favicons * xat- - new favicons * Zixaphir - fix qr textarea - captcha-image gap - * Mayhem - various features / fixes * Ongpot - sfw favicon * thisisanon - nsfw + 404 favicons * Anonymous - empty favicon From 24f0f3df0524d7d8851a8215314782d1700180c9 Mon Sep 17 00:00:00 2001 From: Nicolas Stepien Date: Wed, 7 Dec 2011 22:54:50 +0100 Subject: [PATCH 124/169] Add xat, mayhem and original favicons. Close #14 --- 4chan_x.user.js | 22 +++++++++++++++++++++- script.coffee | 21 +++++++++++++++++++-- 2 files changed, 40 insertions(+), 3 deletions(-) diff --git a/4chan_x.user.js b/4chan_x.user.js index e66fbd85a..30263d68e 100644 --- a/4chan_x.user.js +++ b/4chan_x.user.js @@ -1299,6 +1299,9 @@ Unread favicons
        \ \ \ @@ -2742,8 +2745,25 @@ this.unreadSFW = 'data:image/gif;base64,R0lGODlhEAAQAOMHAADX8QBwfgC2zADX8QDY8nnl8qLp8v///////////////////////////////////yH5BAEKAAcALAAAAAAQABAAAARZ8MhJ6xwDWIBv+AM1fEEIBIVRlNKYrtpIECuGzuwpCLg974EYiXUYkUItjGbC6VQ4omXFiKROA6qSy0A8nAo9GS3YCswIWnOvLAi0be23Z1QtdSUaqXcviQAAOw=='; this.unreadNSFW = 'data:image/gif;base64,R0lGODlhEAAQAOMHAFT+ACh5AEncAFT+AFX/Acz/su7/5v///////////////////////////////////yH5BAEKAAcALAAAAAAQABAAAARZ8MhJ6xwDWIBv+AM1fEEIBIVRlNKYrtpIECuGzuwpCLg974EYiXUYkUItjGbC6VQ4omXFiKROA6qSy0A8nAo9GS3YCswIWnOvLAi0be23Z1QtdSUaqXcviQAAOw=='; break; + case 'xat-': + this.unreadDead = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAA2ElEQVQ4y61TQQrCMBDMQ8WDIEV6LbT2A4og2Hq0veo7fIAH04dY9N4xmyYlpGmI2MCQTWYy3Wy2DAD7B2wWAzWgcTgVeZKlZRxHNYFi2jM18oBh0IcKtC6ixf22WT4IFLs0owxswXu9egm0Ls6bwfCFfNsJYJKfqoEkd3vgUgFVLWObtzNgVKyruC+ljSzr5OEnBzjvjcQecaQhbZgBb4CmGQw+PoMkTUtdbd8VSEPakcGxPOcsoIgUKy0LecY29BmdBrqRfjIwZ93KLs5loHvBnL3cLH/jF+C/+z5dgUysAAAAAElFTkSuQmCC'; + this.unreadSFW = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAA30lEQVQ4y2P4//8/AyWYgSoGQMF/GJ7Y11VVUVoyKTM9ey4Ig9ggMWQ1YA1IBvzXm34YjkH8mPyJB+Nqlp8FYRAbmxoMF6ArSNrw6T0Qf8Amh9cFMEWVR/7/A+L/uORxhgEIt5/+/3/2lf//5wAxiI0uj+4CBlBgxVUvOwtydgXQZpDmi2/+/7/0GmIQSAwkB1IDUkuUAZeABlx+g2zAZ9wGlAOjChba+LwAUgNSi2HA5Am9VciBhSsQQWyoWgZiovEDsdGI1QBYQiLJAGQalpSxyWEzAJYWkGm8clTJjQCZ1hkoVG0CygAAAABJRU5ErkJggg=='; + this.unreadNSFW = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAA4ElEQVQ4y2P4//8/AyWYgSoGQMF/GJ7YNbGqrKRiUnp21lwQBrFBYshqwBqQDPifdsYYjkH8mInxB+OWx58FYRAbmxoMF6ArKPmU9B6IP2CTw+sCmKKe/5X/gPg/LnmcYQDCs/63/1/9fzYQzwGz0eXRXcAACqy4ZfFnQc7u+V/xD6T55v+LQHwJbBBIDCQHUgNSS5QBt4Cab/2/jDDgMx4DykrKJ8FCG58XQGpAajEMmNw7uQo5sHAFIogNVctATDR+IDYasRoAS0gkGYBMw5IyNjlsBsDSAjKNV44quREAx58Mr9vt5wQAAAAASUVORK5CYII='; + break; + case 'Mayhem': + this.unreadDead = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAABIUlEQVQ4jZ2ScWuDMBDFgw4pIkU0WsoQkWAYIkXZH4N9/+/V3dmfXSrKYIFHwt17j8vdGWNMIkgFuaDgzgQnwRs4EQs5KdolUQtagRN0givEDBTEOjgtGs0Zq8F7cKqqusVxrMQLaDUWcjBSrXkn8gs51tpJSWLk9b3HUa0aNIL5gPBR1/V4kJvR7lTwl8GmAm1Gf9+c3S+89qBHa8502AsmSrtBaEBPbIbj0ah2madlNAPEccdgJDfAtWifBjqWKShRBT6KoiH8QlEUn/qt0CCjnNdmPUwmFWzj9Oe6LpKuZXcwqq88z78Pch3aZU3dPwwc2sWlfZKCW5tWluV8kGvXClLm6dYN4/aUqfCbnEOzNDGhGZbNargvxCzvMGfRJD8UaDVvgkzo6QAAAABJRU5ErkJggg=='; + this.unreadSFW = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAABCElEQVQ4jZ2S4crCMAxF+0OGDJEPKYrIGKOsiJSx/fJRfSAfTJNyKqXfiuDg0C25N2RJjTGmEVrhTzhw7oStsIEtsVzT4o2Jo9ALThiEM8IdHIgNaHo8mjNWg6/ske8bohPo+63QOLzmooHp8fyAICBSQkVz0QKdsFQEV6WSW/D+7+BbgbIDHcb4Kp61XyjyI16zZ8JemGltQtDBSGxB4/GoN+7TpkkjDCsFArm0IYv3U0BbnYtf8BCy+JytsE0X6VyuKhPPK/GAJ14kvZZDZVV3pZIb8MZr6n4o4PDGKn0S5SdDmyq5PnXQsk+Xbhinp03FFzmHJw6xYRiWm9VxnohZ3vOcxdO8ARmXRvbWdtzQAAAAAElFTkSuQmCC'; + this.unreadNSFW = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAABCklEQVQ4jZ2S0WrDMAxF/TBCCKWMYhZKCSGYmFJMSNjD/mhf239qJXNcjBdTWODgRLpXKJKNMaYROuFTOHEehFb4gJZYrunwxsSXMApOmIQzwgOciE1oRjyaM1aDj+yR7xuiHvT9VmgcXnPRwO/9+wWCgEgJFc1FCwzCVhFclUpuw/u3g3cFyg50GPOjePZ+ocjPeM2RCXthpbUFwQAzsQ2Nx6PeuE+bJo0w7BQI5NKGLN5XAW11LX7BQ8jia7bCLl2kc7mqTLzuxAOeeJH0Wk6VVf0oldyEN15T948CDm+sMiZRfjK0pZIbUwcd+3TphnF62lR8kXN44hAbhmG5WQNnT8zynucsnuYJhFpBfkMzqD4AAAAASUVORK5CYII='; + break; + case 'Original': + this.unreadDead = 'data:image/gif;base64,R0lGODlhEAAQAKECAAAAAP8AAP///////yH5BAEKAAMALAAAAAAQABAAAAI/nI95wsqygIRxDgGCBhTrwF3Zxowg5H1cSopS6FrGQ82PU1951ckRmYKJVCXizLRC9kAnT0aIiR6lCFT1cigAADs='; + this.unreadSFW = 'data:image/gif;base64,R0lGODlhEAAQAKECAAAAAC6Xw////////yH5BAEKAAMALAAAAAAQABAAAAI/nI95wsqygIRxDgGCBhTrwF3Zxowg5H1cSopS6FrGQ82PU1951ckRmYKJVCXizLRC9kAnT0aIiR6lCFT1cigAADs='; + this.unreadNSFW = 'data:image/gif;base64,R0lGODlhEAAQAKECAAAAAGbMM////////yH5BAEKAAMALAAAAAAQABAAAAI/nI95wsqygIRxDgGCBhTrwF3Zxowg5H1cSopS6FrGQ82PU1951ckRmYKJVCXizLRC9kAnT0aIiR6lCFT1cigAADs='; + break; case 'None': - this.unreadDead = this.unreadSFW = this.unreadNSFW = this["default"]; + this.unreadDead = this.dead; + this.unreadSFW = 'http://static.4chan.org/image/favicon-ws.ico'; + this.unreadNSFW = 'http://static.4chan.org/image/favicon.ico'; } return this.unread = this.SFW ? this.unreadSFW : this.unreadNSFW; }, diff --git a/script.coffee b/script.coffee index f601d7749..2ec53a46a 100644 --- a/script.coffee +++ b/script.coffee @@ -953,6 +953,9 @@ options = Unread favicons
        @@ -2128,10 +2131,24 @@ Favicon = switch conf['favicon'] when 'ferongr' @unreadDead = 'data:image/gif;base64,R0lGODlhEAAQAOMHAOgLAnMFAL8AAOgLAukMA/+AgP+rq////////////////////////////////////yH5BAEKAAcALAAAAAAQABAAAARZ8MhJ6xwDWIBv+AM1fEEIBIVRlNKYrtpIECuGzuwpCLg974EYiXUYkUItjGbC6VQ4omXFiKROA6qSy0A8nAo9GS3YCswIWnOvLAi0be23Z1QtdSUaqXcviQAAOw==' - @unreadSFW = 'data:image/gif;base64,R0lGODlhEAAQAOMHAADX8QBwfgC2zADX8QDY8nnl8qLp8v///////////////////////////////////yH5BAEKAAcALAAAAAAQABAAAARZ8MhJ6xwDWIBv+AM1fEEIBIVRlNKYrtpIECuGzuwpCLg974EYiXUYkUItjGbC6VQ4omXFiKROA6qSy0A8nAo9GS3YCswIWnOvLAi0be23Z1QtdSUaqXcviQAAOw==' + @unreadSFW = 'data:image/gif;base64,R0lGODlhEAAQAOMHAADX8QBwfgC2zADX8QDY8nnl8qLp8v///////////////////////////////////yH5BAEKAAcALAAAAAAQABAAAARZ8MhJ6xwDWIBv+AM1fEEIBIVRlNKYrtpIECuGzuwpCLg974EYiXUYkUItjGbC6VQ4omXFiKROA6qSy0A8nAo9GS3YCswIWnOvLAi0be23Z1QtdSUaqXcviQAAOw==' @unreadNSFW = 'data:image/gif;base64,R0lGODlhEAAQAOMHAFT+ACh5AEncAFT+AFX/Acz/su7/5v///////////////////////////////////yH5BAEKAAcALAAAAAAQABAAAARZ8MhJ6xwDWIBv+AM1fEEIBIVRlNKYrtpIECuGzuwpCLg974EYiXUYkUItjGbC6VQ4omXFiKROA6qSy0A8nAo9GS3YCswIWnOvLAi0be23Z1QtdSUaqXcviQAAOw==' + when 'xat-' + @unreadDead = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAA2ElEQVQ4y61TQQrCMBDMQ8WDIEV6LbT2A4og2Hq0veo7fIAH04dY9N4xmyYlpGmI2MCQTWYy3Wy2DAD7B2wWAzWgcTgVeZKlZRxHNYFi2jM18oBh0IcKtC6ixf22WT4IFLs0owxswXu9egm0Ls6bwfCFfNsJYJKfqoEkd3vgUgFVLWObtzNgVKyruC+ljSzr5OEnBzjvjcQecaQhbZgBb4CmGQw+PoMkTUtdbd8VSEPakcGxPOcsoIgUKy0LecY29BmdBrqRfjIwZ93KLs5loHvBnL3cLH/jF+C/+z5dgUysAAAAAElFTkSuQmCC' + @unreadSFW = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAA30lEQVQ4y2P4//8/AyWYgSoGQMF/GJ7Y11VVUVoyKTM9ey4Ig9ggMWQ1YA1IBvzXm34YjkH8mPyJB+Nqlp8FYRAbmxoMF6ArSNrw6T0Qf8Amh9cFMEWVR/7/A+L/uORxhgEIt5/+/3/2lf//5wAxiI0uj+4CBlBgxVUvOwtydgXQZpDmi2/+/7/0GmIQSAwkB1IDUkuUAZeABlx+g2zAZ9wGlAOjChba+LwAUgNSi2HA5Am9VciBhSsQQWyoWgZiovEDsdGI1QBYQiLJAGQalpSxyWEzAJYWkGm8clTJjQCZ1hkoVG0CygAAAABJRU5ErkJggg==' + @unreadNSFW = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAA4ElEQVQ4y2P4//8/AyWYgSoGQMF/GJ7YNbGqrKRiUnp21lwQBrFBYshqwBqQDPifdsYYjkH8mInxB+OWx58FYRAbmxoMF6ArKPmU9B6IP2CTw+sCmKKe/5X/gPg/LnmcYQDCs/63/1/9fzYQzwGz0eXRXcAACqy4ZfFnQc7u+V/xD6T55v+LQHwJbBBIDCQHUgNSS5QBt4Cab/2/jDDgMx4DykrKJ8FCG58XQGpAajEMmNw7uQo5sHAFIogNVctATDR+IDYasRoAS0gkGYBMw5IyNjlsBsDSAjKNV44quREAx58Mr9vt5wQAAAAASUVORK5CYII=' + when 'Mayhem' + @unreadDead = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAABIUlEQVQ4jZ2ScWuDMBDFgw4pIkU0WsoQkWAYIkXZH4N9/+/V3dmfXSrKYIFHwt17j8vdGWNMIkgFuaDgzgQnwRs4EQs5KdolUQtagRN0givEDBTEOjgtGs0Zq8F7cKqqusVxrMQLaDUWcjBSrXkn8gs51tpJSWLk9b3HUa0aNIL5gPBR1/V4kJvR7lTwl8GmAm1Gf9+c3S+89qBHa8502AsmSrtBaEBPbIbj0ah2madlNAPEccdgJDfAtWifBjqWKShRBT6KoiH8QlEUn/qt0CCjnNdmPUwmFWzj9Oe6LpKuZXcwqq88z78Pch3aZU3dPwwc2sWlfZKCW5tWluV8kGvXClLm6dYN4/aUqfCbnEOzNDGhGZbNargvxCzvMGfRJD8UaDVvgkzo6QAAAABJRU5ErkJggg==' + @unreadSFW = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAABCElEQVQ4jZ2S4crCMAxF+0OGDJEPKYrIGKOsiJSx/fJRfSAfTJNyKqXfiuDg0C25N2RJjTGmEVrhTzhw7oStsIEtsVzT4o2Jo9ALThiEM8IdHIgNaHo8mjNWg6/ske8bohPo+63QOLzmooHp8fyAICBSQkVz0QKdsFQEV6WSW/D+7+BbgbIDHcb4Kp61XyjyI16zZ8JemGltQtDBSGxB4/GoN+7TpkkjDCsFArm0IYv3U0BbnYtf8BCy+JytsE0X6VyuKhPPK/GAJ14kvZZDZVV3pZIb8MZr6n4o4PDGKn0S5SdDmyq5PnXQsk+Xbhinp03FFzmHJw6xYRiWm9VxnohZ3vOcxdO8ARmXRvbWdtzQAAAAAElFTkSuQmCC' + @unreadNSFW = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAABCklEQVQ4jZ2S0WrDMAxF/TBCCKWMYhZKCSGYmFJMSNjD/mhf239qJXNcjBdTWODgRLpXKJKNMaYROuFTOHEehFb4gJZYrunwxsSXMApOmIQzwgOciE1oRjyaM1aDj+yR7xuiHvT9VmgcXnPRwO/9+wWCgEgJFc1FCwzCVhFclUpuw/u3g3cFyg50GPOjePZ+ocjPeM2RCXthpbUFwQAzsQ2Nx6PeuE+bJo0w7BQI5NKGLN5XAW11LX7BQ8jia7bCLl2kc7mqTLzuxAOeeJH0Wk6VVf0oldyEN15T948CDm+sMiZRfjK0pZIbUwcd+3TphnF62lR8kXN44hAbhmG5WQNnT8zynucsnuYJhFpBfkMzqD4AAAAASUVORK5CYII=' + when 'Original' + @unreadDead = 'data:image/gif;base64,R0lGODlhEAAQAKECAAAAAP8AAP///////yH5BAEKAAMALAAAAAAQABAAAAI/nI95wsqygIRxDgGCBhTrwF3Zxowg5H1cSopS6FrGQ82PU1951ckRmYKJVCXizLRC9kAnT0aIiR6lCFT1cigAADs=' + @unreadSFW = 'data:image/gif;base64,R0lGODlhEAAQAKECAAAAAC6Xw////////yH5BAEKAAMALAAAAAAQABAAAAI/nI95wsqygIRxDgGCBhTrwF3Zxowg5H1cSopS6FrGQ82PU1951ckRmYKJVCXizLRC9kAnT0aIiR6lCFT1cigAADs=' + @unreadNSFW = 'data:image/gif;base64,R0lGODlhEAAQAKECAAAAAGbMM////////yH5BAEKAAMALAAAAAAQABAAAAI/nI95wsqygIRxDgGCBhTrwF3Zxowg5H1cSopS6FrGQ82PU1951ckRmYKJVCXizLRC9kAnT0aIiR6lCFT1cigAADs=' when 'None' - @unreadDead = @unreadSFW = @unreadNSFW = @default + @unreadDead = @dead + @unreadSFW = 'http://static.4chan.org/image/favicon-ws.ico' + @unreadNSFW = 'http://static.4chan.org/image/favicon.ico' @unread = if @SFW then @unreadSFW else @unreadNSFW empty: 'data:image/gif;base64,R0lGODlhEAAQAJEAAAAAAP///9vb2////yH5BAEAAAMALAAAAAAQABAAAAIvnI+pq+D9DBAUoFkPFnbs7lFZKIJOJJ3MyraoB14jFpOcVMpzrnF3OKlZYsMWowAAOw==' From 75f8ae0bd75336119b21329f42fe60a399e59451 Mon Sep 17 00:00:00 2001 From: Nicolas Stepien Date: Wed, 7 Dec 2011 23:12:53 +0100 Subject: [PATCH 125/169] Don't update the favicon if you have Unread Count when opening the options. --- 4chan_x.user.js | 2 +- script.coffee | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/4chan_x.user.js b/4chan_x.user.js index 30263d68e..5123d6158 100644 --- a/4chan_x.user.js +++ b/4chan_x.user.js @@ -1439,7 +1439,7 @@ favicon: function() { $.cb.value.call(this); Favicon["switch"](); - if (g.REPLY) Favicon.update(); + if (g.REPLY && conf['Unread Count']) Favicon.update(); return this.nextElementSibling.innerHTML = ""; } }; diff --git a/script.coffee b/script.coffee index 2ec53a46a..08a0c1ddf 100644 --- a/script.coffee +++ b/script.coffee @@ -1076,7 +1076,7 @@ options = favicon: -> $.cb.value.call @ Favicon.switch() - Favicon.update() if g.REPLY + Favicon.update() if g.REPLY and conf['Unread Count'] @nextElementSibling.innerHTML = "" cooldown = From 0be30318c0f44841e06c6b1b06e51d0668d9ab21 Mon Sep 17 00:00:00 2001 From: Nicolas Stepien Date: Wed, 7 Dec 2011 23:24:51 +0100 Subject: [PATCH 126/169] WTF OPERA??? --- 4chan_x.user.js | 2 +- script.coffee | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/4chan_x.user.js b/4chan_x.user.js index 5123d6158..6b61ab04f 100644 --- a/4chan_x.user.js +++ b/4chan_x.user.js @@ -1687,7 +1687,7 @@ caretPos = ta.selectionStart; ta.value = ta.value.slice(0, caretPos) + text + ta.value.slice(ta.selectionEnd, ta.value.length); ta.focus(); - return ta.selectionStart = ta.selectionEnd = caretPos + text.length; + return ta.selectionEnd = ta.selectionStart = caretPos + text.length; }, refresh: function() { var m, newFile, oldFile, _ref; diff --git a/script.coffee b/script.coffee index 08a0c1ddf..1b4da00f2 100644 --- a/script.coffee +++ b/script.coffee @@ -1325,7 +1325,7 @@ qr = ta.value = ta.value.slice(0, caretPos) + text + ta.value.slice(ta.selectionEnd, ta.value.length) ta.focus() #move the caret to the end of the new quote - ta.selectionStart = ta.selectionEnd = caretPos + text.length + ta.selectionEnd = ta.selectionStart = caretPos + text.length refresh: -> $('[name=sub]', qr.el).value = '' From 94ad6a590ecad1527ba94a0c8f95e49f901c140d Mon Sep 17 00:00:00 2001 From: Nicolas Stepien Date: Wed, 7 Dec 2011 23:34:52 +0100 Subject: [PATCH 127/169] Fool the cache for loloprah, fix thread updater, close #30 --- 4chan_x.user.js | 2 +- changelog | 1 + script.coffee | 3 ++- 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/4chan_x.user.js b/4chan_x.user.js index 6b61ab04f..67356c7fc 100644 --- a/4chan_x.user.js +++ b/4chan_x.user.js @@ -2080,7 +2080,7 @@ var cb, url, _ref; updater.timer.textContent = 0; if ((_ref = updater.request) != null) _ref.abort(); - url = location.pathname; + url = engine !== 'presto' ? location.pathname : location.pathname + '?' + Date.now(); cb = updater.cb.update; return updater.request = $.ajax(url, cb); } diff --git a/changelog b/changelog index 216864283..9bf1fbb53 100644 --- a/changelog +++ b/changelog @@ -4,6 +4,7 @@ master quotes are now inserted at the caret position in the QR quotes also replace the text selection in the QR open QR focused when using the `Open QR without post number inserted` keybind + fix thread updater for Opera - aeosynth update the captcha caching expiration date to 30mins diff --git a/script.coffee b/script.coffee index 1b4da00f2..3175b68b9 100644 --- a/script.coffee +++ b/script.coffee @@ -1664,7 +1664,8 @@ updater = update: -> updater.timer.textContent = 0 updater.request?.abort() - url = location.pathname + #Opera needs to fool its cache + url = if engine isnt 'presto' then location.pathname else location.pathname + '?' + Date.now() cb = updater.cb.update updater.request = $.ajax url, cb From b1131d28f80c3e387bee063072e30c6b7ee36ea4 Mon Sep 17 00:00:00 2001 From: Nicolas Stepien Date: Wed, 7 Dec 2011 23:37:27 +0100 Subject: [PATCH 128/169] Release 2.23.0 --- 4chan_x.user.js | 6 +++--- Cakefile | 2 +- changelog | 2 ++ latest.js | 2 +- script.coffee | 2 +- 5 files changed, 8 insertions(+), 6 deletions(-) diff --git a/4chan_x.user.js b/4chan_x.user.js index 67356c7fc..e71978421 100644 --- a/4chan_x.user.js +++ b/4chan_x.user.js @@ -1,6 +1,6 @@ // ==UserScript== // @name 4chan x -// @version 2.22.2 +// @version 2.23.0 // @namespace aeosynth // @description Adds various features. // @copyright 2009-2011 James Campos @@ -15,7 +15,7 @@ * * Copyright (c) 2009-2011 James Campos * http://mayhemydg.github.com/4chan-x/ - * 4chan x 2.22.2 + * 4chan x 2.23.0 * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation @@ -210,7 +210,7 @@ NAMESPACE = '4chan_x.'; - VERSION = '2.22.2'; + VERSION = '2.23.0'; SECOND = 1000; diff --git a/Cakefile b/Cakefile index 8e7bd4803..1eed99e27 100644 --- a/Cakefile +++ b/Cakefile @@ -2,7 +2,7 @@ {exec} = require 'child_process' fs = require 'fs' -VERSION = '2.22.2' +VERSION = '2.23.0' HEADER = """ // ==UserScript== diff --git a/changelog b/changelog index 9bf1fbb53..797d8ca4d 100644 --- a/changelog +++ b/changelog @@ -1,4 +1,6 @@ master + +2.23.0 - mayhem multiple unread favicons to chose in the options quotes are now inserted at the caret position in the QR diff --git a/latest.js b/latest.js index d69056e99..798de9222 100644 --- a/latest.js +++ b/latest.js @@ -1 +1 @@ -postMessage({version:'2.22.2'},'*'); +postMessage({version:'2.23.0'},'*'); diff --git a/script.coffee b/script.coffee index 3175b68b9..93e96031d 100644 --- a/script.coffee +++ b/script.coffee @@ -125,7 +125,7 @@ conf = {} ) null, config NAMESPACE = '4chan_x.' -VERSION = '2.22.2' +VERSION = '2.23.0' SECOND = 1000 MINUTE = 60*SECOND HOUR = 60*MINUTE From 3024346b94d9aeee51fff4af84e8d9ed212431cf Mon Sep 17 00:00:00 2001 From: Nicolas Stepien Date: Thu, 8 Dec 2011 02:06:23 +0100 Subject: [PATCH 129/169] Fix favicon updating on Opera. See comments, issue #30 --- 4chan_x.user.js | 3 ++- changelog | 2 ++ script.coffee | 7 +++++-- 3 files changed, 9 insertions(+), 3 deletions(-) diff --git a/4chan_x.user.js b/4chan_x.user.js index e71978421..e8cd84a83 100644 --- a/4chan_x.user.js +++ b/4chan_x.user.js @@ -2774,8 +2774,9 @@ l = unread.replies.length; favicon = $('link[rel="shortcut icon"]', d.head); favicon.href = g.dead ? l ? this.unreadDead : this.dead : l ? this.unread : this["default"]; - if (engine === "gecko") { + if (engine !== 'webkit') { clone = favicon.cloneNode(true); + favicon.href = null; return $.replace(favicon, clone); } } diff --git a/changelog b/changelog index 797d8ca4d..78618767b 100644 --- a/changelog +++ b/changelog @@ -1,4 +1,6 @@ master +- mayhem + fix favicon updating on Opera 2.23.0 - mayhem diff --git a/script.coffee b/script.coffee index 93e96031d..71fd939ad 100644 --- a/script.coffee +++ b/script.coffee @@ -2171,9 +2171,12 @@ Favicon = else @default - #XXX `favicon.href = href` doesn't work on Firefox - if engine is "gecko" + #`favicon.href = href` doesn't work on Firefox + #`favicon.href = href` isn't enough on Opera + #Opera won't always update the favicon if the href do not change + if engine isnt 'webkit' clone = favicon.cloneNode true + favicon.href = null $.replace favicon, clone redirect = -> From 4cfa27f38ce522594a6f7ca09f663f5459eb7d47 Mon Sep 17 00:00:00 2001 From: Nicolas Stepien Date: Fri, 9 Dec 2011 14:07:26 +0100 Subject: [PATCH 130/169] Fix compatibility with Tampermonkey, close #33 --- 4chan_x.user.js | 4 ++-- changelog | 1 + script.coffee | 4 ++-- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/4chan_x.user.js b/4chan_x.user.js index e8cd84a83..9fc3b82fa 100644 --- a/4chan_x.user.js +++ b/4chan_x.user.js @@ -3012,7 +3012,7 @@ g.PAGENUM = parseInt(temp) || 0; } if (location.hostname === 'sys.4chan.org') { - if (d.body) { + if (/interactive|complete/.test(d.readyState)) { qr.sys(); } else { $.on(d, 'DOMContentLoaded', qr.sys); @@ -3054,7 +3054,7 @@ if (conf['Quote Backlinks']) quoteBacklink.init(); if (conf['Indicate OP quote']) quoteOP.init(); if (conf['Indicate Cross-thread Quotes']) quoteDR.init(); - if (d.body) { + if (/interactive|complete/.test(d.readyState)) { return Main.onLoad(); } else { return $.on(d, 'DOMContentLoaded', Main.onLoad); diff --git a/changelog b/changelog index 78618767b..8bcdeccaf 100644 --- a/changelog +++ b/changelog @@ -1,6 +1,7 @@ master - mayhem fix favicon updating on Opera + fix compatibility with Tampermonkey 2.23.0 - mayhem diff --git a/script.coffee b/script.coffee index 71fd939ad..1d94e2339 100644 --- a/script.coffee +++ b/script.coffee @@ -2328,7 +2328,7 @@ Main = g.PAGENUM = parseInt(temp) or 0 if location.hostname is 'sys.4chan.org' - if d.body + if /interactive|complete/.test d.readyState qr.sys() else $.on d, 'DOMContentLoaded', qr.sys @@ -2404,7 +2404,7 @@ Main = quoteDR.init() - if d.body + if /interactive|complete/.test d.readyState Main.onLoad() else $.on d, 'DOMContentLoaded', Main.onLoad From 167acea2c2243ac9cd9487e80d26c3f18485d43e Mon Sep 17 00:00:00 2001 From: Nicolas Stepien Date: Fri, 9 Dec 2011 14:41:19 +0100 Subject: [PATCH 131/169] Set up update checking asap. --- 4chan_x.user.js | 27 +++++++++++++++++---------- script.coffee | 21 ++++++++++++--------- 2 files changed, 29 insertions(+), 19 deletions(-) diff --git a/4chan_x.user.js b/4chan_x.user.js index 9fc3b82fa..3b3d57df0 100644 --- a/4chan_x.user.js +++ b/4chan_x.user.js @@ -3002,7 +3002,7 @@ Main = { init: function() { - var cutoff, hiddenThreads, id, lastChecked, now, pathname, temp, timestamp, _ref; + var cutoff, hiddenThreads, id, now, pathname, temp, timestamp, update, _ref; pathname = location.pathname.substring(1).split('/'); g.BOARD = pathname[0], temp = pathname[1]; if (temp === 'res') { @@ -3020,11 +3020,23 @@ return; } $.on(window, 'message', Main.message); - g.hiddenReplies = $.get("hiddenReplies/" + g.BOARD + "/", {}); - lastChecked = $.get('lastChecked', 0); now = Date.now(); - Main.reqUpdate = lastChecked < now - 1 * DAY; - if (Main.reqUpdate) { + if (conf['Check for Updates'] && $.get('lastUpdate', 0) < now - 6 * HOUR) { + update = function() { + $.off(d, 'DOMContentLoaded', update); + return $.add(d.head, $.el('script', { + src: 'https://raw.github.com/mayhemydg/4chan-x/master/latest.js' + })); + }; + if (/interactive|complete/.test(d.readyState)) { + update(); + } else { + $.on(d, 'DOMContentLoaded', update); + } + $.set('lastUpdate', now); + } + g.hiddenReplies = $.get("hiddenReplies/" + g.BOARD + "/", {}); + if ($.get('lastChecked', 0) < now - 1 * DAY) { $.set('lastChecked', now); cutoff = now - 7 * DAY; hiddenThreads = $.get("hiddenThreads/" + g.BOARD + "/", {}); @@ -3072,11 +3084,6 @@ $.addStyle(Main.css); threading.init(); Favicon.init(); - if (Main.reqUpdate && conf['Check for Updates']) { - $.add(d.head, $.el('script', { - src: 'https://raw.github.com/mayhemydg/4chan-x/master/latest.js' - })); - } if ((form = $('form[name=post]')) && (canPost = !!$('#recaptcha_response_field'))) { Recaptcha.init(); if (g.REPLY && conf['Auto Watch Reply'] && conf['Thread Watcher']) { diff --git a/script.coffee b/script.coffee index 1d94e2339..018ffea55 100644 --- a/script.coffee +++ b/script.coffee @@ -1797,7 +1797,7 @@ Time = @parse = if Date.parse '10/11/11(Tue)18:53' is 1318351980000 (node) -> new Date Date.parse(node.textContent) + chanOffset*HOUR - else # Firefox the Archaic cannot parse 4chan's time + else # Firefox and Opera do not parse 4chan's time format correctly (node) -> [_, month, day, year, hour, min] = node.textContent.match /(\d+)\/(\d+)\/(\d+)\(\w+\)(\d+):(\d+)/ @@ -2336,13 +2336,19 @@ Main = $.on window, 'message', Main.message - g.hiddenReplies = $.get "hiddenReplies/#{g.BOARD}/", {} - - lastChecked = $.get 'lastChecked', 0 now = Date.now() - Main.reqUpdate = lastChecked < now - 1*DAY + if conf['Check for Updates'] and $.get('lastUpdate', 0) < now - 6*HOUR + update = -> + $.off d, 'DOMContentLoaded', update + $.add d.head, $.el 'script', src: 'https://raw.github.com/mayhemydg/4chan-x/master/latest.js' + if /interactive|complete/.test d.readyState + update() + else + $.on d, 'DOMContentLoaded', update + $.set 'lastUpdate', now - if Main.reqUpdate + g.hiddenReplies = $.get "hiddenReplies/#{g.BOARD}/", {} + if $.get('lastChecked', 0) < now - 1*DAY $.set 'lastChecked', now cutoff = now - 7*DAY @@ -2421,9 +2427,6 @@ Main = threading.init() Favicon.init() - if Main.reqUpdate and conf['Check for Updates'] - $.add d.head, $.el 'script', src: 'https://raw.github.com/mayhemydg/4chan-x/master/latest.js' - #recaptcha may be blocked, eg by noscript if (form = $ 'form[name=post]') and (canPost = !!$ '#recaptcha_response_field') Recaptcha.init() From 0a1dd64e6084f740ae2cc25524020c9d507d5d40 Mon Sep 17 00:00:00 2001 From: Nicolas Stepien Date: Fri, 9 Dec 2011 14:49:22 +0100 Subject: [PATCH 132/169] Release 2.23.1 --- 4chan_x.user.js | 6 +++--- Cakefile | 2 +- changelog | 2 ++ latest.js | 2 +- script.coffee | 2 +- 5 files changed, 8 insertions(+), 6 deletions(-) diff --git a/4chan_x.user.js b/4chan_x.user.js index 3b3d57df0..1e0eb49fa 100644 --- a/4chan_x.user.js +++ b/4chan_x.user.js @@ -1,6 +1,6 @@ // ==UserScript== // @name 4chan x -// @version 2.23.0 +// @version 2.23.1 // @namespace aeosynth // @description Adds various features. // @copyright 2009-2011 James Campos @@ -15,7 +15,7 @@ * * Copyright (c) 2009-2011 James Campos * http://mayhemydg.github.com/4chan-x/ - * 4chan x 2.23.0 + * 4chan x 2.23.1 * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation @@ -210,7 +210,7 @@ NAMESPACE = '4chan_x.'; - VERSION = '2.23.0'; + VERSION = '2.23.1'; SECOND = 1000; diff --git a/Cakefile b/Cakefile index 1eed99e27..f9ca9caf7 100644 --- a/Cakefile +++ b/Cakefile @@ -2,7 +2,7 @@ {exec} = require 'child_process' fs = require 'fs' -VERSION = '2.23.0' +VERSION = '2.23.1' HEADER = """ // ==UserScript== diff --git a/changelog b/changelog index 8bcdeccaf..f3bfbd964 100644 --- a/changelog +++ b/changelog @@ -1,4 +1,6 @@ master + +2.23.1 - mayhem fix favicon updating on Opera fix compatibility with Tampermonkey diff --git a/latest.js b/latest.js index 798de9222..76fdf91b5 100644 --- a/latest.js +++ b/latest.js @@ -1 +1 @@ -postMessage({version:'2.23.0'},'*'); +postMessage({version:'2.23.1'},'*'); diff --git a/script.coffee b/script.coffee index 018ffea55..5c63c4247 100644 --- a/script.coffee +++ b/script.coffee @@ -125,7 +125,7 @@ conf = {} ) null, config NAMESPACE = '4chan_x.' -VERSION = '2.23.0' +VERSION = '2.23.1' SECOND = 1000 MINUTE = 60*SECOND HOUR = 60*MINUTE From 732305f8487458c61a16c7abb66e20af88ae1f38 Mon Sep 17 00:00:00 2001 From: Nicolas Stepien Date: Fri, 9 Dec 2011 18:29:23 +0100 Subject: [PATCH 133/169] Fix WakiMiko's name in the contributors list. --- 4chan_x.user.js | 2 +- Cakefile | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/4chan_x.user.js b/4chan_x.user.js index 1e0eb49fa..9f70ae786 100644 --- a/4chan_x.user.js +++ b/4chan_x.user.js @@ -55,7 +55,7 @@ * Anonymous - empty favicon * Seiba - chrome quick reply focusing * herpaderpderp - recaptcha fixes - * wakimoko - recaptcha tab order http://userscripts.org/scripts/show/82657 + * WakiMiko - recaptcha tab order http://userscripts.org/scripts/show/82657 * * All the people who've taken the time to write bug reports. * diff --git a/Cakefile b/Cakefile index f9ca9caf7..dbf68be70 100644 --- a/Cakefile +++ b/Cakefile @@ -62,7 +62,7 @@ HEADER = """ * Anonymous - empty favicon * Seiba - chrome quick reply focusing * herpaderpderp - recaptcha fixes - * wakimoko - recaptcha tab order http://userscripts.org/scripts/show/82657 + * WakiMiko - recaptcha tab order http://userscripts.org/scripts/show/82657 * * All the people who've taken the time to write bug reports. * From 33cfbe82208ebf46216ef92bfe8b87df0a035c31 Mon Sep 17 00:00:00 2001 From: Nicolas Stepien Date: Fri, 9 Dec 2011 18:44:24 +0100 Subject: [PATCH 134/169] Default the QR to the right. --- 4chan_x.user.js | 2 +- script.coffee | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/4chan_x.user.js b/4chan_x.user.js index 9f70ae786..e6fba4a2f 100644 --- a/4chan_x.user.js +++ b/4chan_x.user.js @@ -1577,7 +1577,7 @@ THREAD_ID = g.THREAD_ID || $.x('ancestor::div[@class="thread"]/div', link).id; qr.challenge = $('#recaptcha_challenge_field').value; html = " X
        Quick Reply
        " + qr.spoiler + "
        " + ($.get('captchas', []).length) + " captchas
        "; - qr.el = ui.dialog('qr', 'top: 0; left: 0;', html); + qr.el = ui.dialog('qr', 'top: 0; right: 0;', html); c = d.cookie; $('input[name=name]', qr.el).value = (m = c.match(/4chan_name=([^;]+)/)) ? decodeURIComponent(m[1]) : ''; $('input[name=email]', qr.el).value = (m = c.match(/4chan_email=([^;]+)/)) ? decodeURIComponent(m[1]) : ''; diff --git a/script.coffee b/script.coffee index 5c63c4247..042cc7c7b 100644 --- a/script.coffee +++ b/script.coffee @@ -1213,7 +1213,7 @@ qr =
        " - qr.el = ui.dialog 'qr', 'top: 0; left: 0;', html + qr.el = ui.dialog 'qr', 'top: 0; right: 0;', html c = d.cookie $('input[name=name]', qr.el).value = From 2af711f8af5d5954ee92a5668f78b61fedebc546 Mon Sep 17 00:00:00 2001 From: Nicolas Stepien Date: Fri, 9 Dec 2011 20:40:46 +0100 Subject: [PATCH 135/169] Update comment. You can read the timeout in seconde in the recaptcha script/object. Unfortunately 4chan X cannot access it. --- 4chan_x.user.js | 4 ++-- script.coffee | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/4chan_x.user.js b/4chan_x.user.js index e6fba4a2f..a3954dc4c 100644 --- a/4chan_x.user.js +++ b/4chan_x.user.js @@ -1639,8 +1639,8 @@ content = $('textarea', qr.el).value || $('input[type=file]', qr.el).files.length; if (!content) return 'Error: No text entered.'; /* - captchas expire after 30 minutes (emperically verified). cutoff 5 minutes - before then, b/c posting takes time. + captchas expire after 30 minutes, see window.RecaptchaState.timeout. + cutoff 5 minutes before then, b/c posting takes time. */ cutoff = Date.now() - 25 * MINUTE; captchas = $.get('captchas', []); diff --git a/script.coffee b/script.coffee index 042cc7c7b..d2527122a 100644 --- a/script.coffee +++ b/script.coffee @@ -1274,8 +1274,8 @@ qr = return 'Error: No text entered.' unless content ### - captchas expire after 30 minutes (emperically verified). cutoff 5 minutes - before then, b/c posting takes time. + captchas expire after 30 minutes, see window.RecaptchaState.timeout. + cutoff 5 minutes before then, b/c posting takes time. ### cutoff = Date.now() - 25*MINUTE From 816576b573fa3271070dc560872df87d607f96fd Mon Sep 17 00:00:00 2001 From: James Campos Date: Sat, 3 Dec 2011 12:08:54 +0800 Subject: [PATCH 136/169] watcher title text --- 4chan_x.user.js | 6 ++++-- script.coffee | 4 +++- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/4chan_x.user.js b/4chan_x.user.js index a3954dc4c..3419f1262 100644 --- a/4chan_x.user.js +++ b/4chan_x.user.js @@ -2178,10 +2178,12 @@ return watcher.refresh(); }, watch: function(thread, id) { - var props, watched, _name; + var props, text, watched, _name; + text = getTitle(thread); props = { href: "/" + g.BOARD + "/res/" + id, - textContent: getTitle(thread) + textContent: text, + title: text }; watched = $.get('watched', {}); watched[_name = g.BOARD] || (watched[_name] = {}); diff --git a/script.coffee b/script.coffee index d2527122a..3500da8c9 100644 --- a/script.coffee +++ b/script.coffee @@ -1741,9 +1741,11 @@ watcher = watcher.refresh() watch: (thread, id) -> + text = getTitle thread props = href: "/#{g.BOARD}/res/#{id}" - textContent: getTitle(thread) + textContent: text + title: text watched = $.get 'watched', {} watched[g.BOARD] or= {} From 7dd32aba2382b21582d0e2d07f885d0566f2b86a Mon Sep 17 00:00:00 2001 From: Nicolas Stepien Date: Sat, 10 Dec 2011 18:52:09 +0100 Subject: [PATCH 137/169] Append all the new posts at once, using a documentFragment. Optimizations. --- 4chan_x.user.js | 25 +++++++++++++------------ script.coffee | 22 +++++++++++----------- 2 files changed, 24 insertions(+), 23 deletions(-) diff --git a/4chan_x.user.js b/4chan_x.user.js index 3419f1262..f744a3abc 100644 --- a/4chan_x.user.js +++ b/4chan_x.user.js @@ -2012,7 +2012,7 @@ } }, update: function() { - var arr, body, id, input, replies, reply, scroll, _i, _len, _ref, _ref2; + var body, frag, id, input, newPosts, reply, scroll, _i, _j, _len, _len2, _ref, _ref2, _ref3; if (this.status === 404) { updater.timer.textContent = ''; updater.count.textContent = 404; @@ -2038,24 +2038,25 @@ updater.count.className = 'error'; return; } - replies = $$('.reply', body); - id = Number(((_ref2 = $('td[id]', updater.br.previousElementSibling)) != null ? _ref2.id : void 0) || 0); - arr = []; - while ((reply = replies.pop()) && (reply.id > id)) { - arr.push(reply.parentNode.parentNode.parentNode); + id = ((_ref2 = $('td[id]', updater.br.previousElementSibling)) != null ? _ref2.id : void 0) || 0; + frag = d.createDocumentFragment(); + _ref3 = $$('.reply', body).reverse(); + for (_j = 0, _len2 = _ref3.length; _j < _len2; _j++) { + reply = _ref3[_j]; + if (reply.id === id) break; + $.prepend(frag, reply.parentNode.parentNode.parentNode); } - scroll = conf['Scrolling'] && updater.focus && arr.length && (d.body.scrollHeight - d.body.clientHeight - window.scrollY < 20); + newPosts = frag.childNodes.length; + scroll = conf['Scrolling'] && updater.focus && newPosts && (d.body.scrollHeight - d.body.clientHeight - window.scrollY < 20); if (conf['Verbose']) { - updater.count.textContent = '+' + arr.length; - if (arr.length === 0) { + updater.count.textContent = '+' + newPosts; + if (newPosts === 0) { updater.count.className = ''; } else { updater.count.className = 'new'; } } - while (reply = arr.pop()) { - $.before(updater.br, reply); - } + $.before(updater.br, frag); if (scroll) return scrollTo(0, d.body.scrollHeight); } }, diff --git a/script.coffee b/script.coffee index 3500da8c9..12301289b 100644 --- a/script.coffee +++ b/script.coffee @@ -1625,23 +1625,23 @@ updater = updater.count.className = 'error' return - replies = $$ '.reply', body - id = Number $('td[id]', updater.br.previousElementSibling)?.id or 0 - arr = [] - while (reply = replies.pop()) and (reply.id > id) - arr.push reply.parentNode.parentNode.parentNode #table + id = $('td[id]', updater.br.previousElementSibling)?.id or 0 + frag = d.createDocumentFragment() + for reply in $$('.reply', body).reverse() + if reply.id is id + break + $.prepend frag, reply.parentNode.parentNode.parentNode #table - scroll = conf['Scrolling'] && updater.focus && arr.length && (d.body.scrollHeight - d.body.clientHeight - window.scrollY < 20) + newPosts = frag.childNodes.length + scroll = conf['Scrolling'] && updater.focus && newPosts && (d.body.scrollHeight - d.body.clientHeight - window.scrollY < 20) if conf['Verbose'] - updater.count.textContent = '+' + arr.length - if arr.length is 0 + updater.count.textContent = '+' + newPosts + if newPosts is 0 updater.count.className = '' else updater.count.className = 'new' - #XXX add replies in correct order so backlinks resolve - while reply = arr.pop() - $.before updater.br, reply + $.before updater.br, frag if scroll scrollTo 0, d.body.scrollHeight From 0baa452a019a2dfbc03c39b9e26673de6ece6052 Mon Sep 17 00:00:00 2001 From: Nicolas Stepien Date: Sat, 10 Dec 2011 21:03:10 +0100 Subject: [PATCH 138/169] Watcher listing optimizations. Append all the DIVs at once, copy the textContent for the title instead of saving it twice. --- 4chan_x.user.js | 28 +++++++++++++++------------- script.coffee | 13 ++++++++----- 2 files changed, 23 insertions(+), 18 deletions(-) diff --git a/4chan_x.user.js b/4chan_x.user.js index f744a3abc..d55570a74 100644 --- a/4chan_x.user.js +++ b/4chan_x.user.js @@ -2115,28 +2115,31 @@ }); }, refresh: function() { - var board, div, favicon, id, link, props, watched, watchedBoard, x, _i, _j, _len, _len2, _ref, _ref2, _ref3, _results; + var board, div, favicon, frag, id, link, props, watched, watchedBoard, x, _i, _j, _len, _len2, _ref, _ref2, _ref3, _results; watched = $.get('watched', {}); - _ref = $$('div:not(.move)', watcher.dialog); - for (_i = 0, _len = _ref.length; _i < _len; _i++) { - div = _ref[_i]; - $.rm(div); - } + frag = d.createDocumentFragment(); for (board in watched) { - _ref2 = watched[board]; - for (id in _ref2) { - props = _ref2[id]; - div = $.el('div'); + _ref = watched[board]; + for (id in _ref) { + props = _ref[id]; x = $.el('a', { textContent: 'X', href: 'javascript:;' }); $.on(x, 'click', watcher.cb.x); link = $.el('a', props); + link.title = link.textContent; + div = $.el('div'); $.add(div, x, $.tn(' '), link); - $.add(watcher.dialog, div); + $.add(frag, div); } } + _ref2 = $$('div:not(.move)', watcher.dialog); + for (_i = 0, _len = _ref2.length; _i < _len; _i++) { + div = _ref2[_i]; + $.rm(div); + } + $.add(watcher.dialog, frag); watchedBoard = watched[g.BOARD] || {}; _ref3 = $$('img.favicon'); _results = []; @@ -2183,8 +2186,7 @@ text = getTitle(thread); props = { href: "/" + g.BOARD + "/res/" + id, - textContent: text, - title: text + textContent: text }; watched = $.get('watched', {}); watched[_name = g.BOARD] || (watched[_name] = {}); diff --git a/script.coffee b/script.coffee index 12301289b..7742ef1c1 100644 --- a/script.coffee +++ b/script.coffee @@ -1696,19 +1696,23 @@ watcher = refresh: -> watched = $.get 'watched', {} - for div in $$ 'div:not(.move)', watcher.dialog - $.rm div + frag = d.createDocumentFragment() for board of watched for id, props of watched[board] - div = $.el 'div' x = $.el 'a', textContent: 'X' href: 'javascript:;' $.on x, 'click', watcher.cb.x link = $.el 'a', props + link.title = link.textContent + div = $.el 'div' $.add div, x, $.tn(' '), link - $.add watcher.dialog, div + $.add frag, div + + for div in $$ 'div:not(.move)', watcher.dialog + $.rm div + $.add watcher.dialog, frag watchedBoard = watched[g.BOARD] or {} for favicon in $$ 'img.favicon' @@ -1745,7 +1749,6 @@ watcher = props = href: "/#{g.BOARD}/res/#{id}" textContent: text - title: text watched = $.get 'watched', {} watched[g.BOARD] or= {} From f0aa40597c09c1f34916959ec3d24e5ace5339ce Mon Sep 17 00:00:00 2001 From: Nicolas Stepien Date: Sat, 10 Dec 2011 21:30:49 +0100 Subject: [PATCH 139/169] Enable autoposting when submitting a captcha while on cooldown. --- 4chan_x.user.js | 1 + changelog | 2 ++ script.coffee | 2 ++ 3 files changed, 5 insertions(+) diff --git a/4chan_x.user.js b/4chan_x.user.js index d55570a74..7c0319cbd 100644 --- a/4chan_x.user.js +++ b/4chan_x.user.js @@ -1552,6 +1552,7 @@ captchaKeydown: function(e) { var captchas; if (!(e.keyCode === 13 && this.value)) return; + if (cooldown.duration) $('#auto', qr.el).checked = true; captchas = $.get('captchas', []); captchas.push({ challenge: qr.challenge, diff --git a/changelog b/changelog index f3bfbd964..97fac12b3 100644 --- a/changelog +++ b/changelog @@ -1,4 +1,6 @@ master +- mayhem + enable autoposting when submitting a captcha while on cooldown 2.23.1 - mayhem diff --git a/script.coffee b/script.coffee index 7742ef1c1..615f71850 100644 --- a/script.coffee +++ b/script.coffee @@ -1164,6 +1164,8 @@ qr = captchaKeydown: (e) -> return unless e.keyCode is 13 and @value #enter, captcha filled + $('#auto', qr.el).checked = true if cooldown.duration #enable autoposting + captchas = $.get 'captchas', [] captchas.push challenge: qr.challenge From 41ef7244dde10606c6e3849f3423d9cd71ed6db6 Mon Sep 17 00:00:00 2001 From: Nicolas Stepien Date: Sat, 10 Dec 2011 22:34:08 +0100 Subject: [PATCH 140/169] Fix #39 --- 4chan_x.user.js | 2 +- script.coffee | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/4chan_x.user.js b/4chan_x.user.js index 7c0319cbd..68e18d88d 100644 --- a/4chan_x.user.js +++ b/4chan_x.user.js @@ -1749,7 +1749,7 @@ data = {}; if (node = (_ref = document.querySelector('td b')) != null ? _ref.firstChild : void 0) { data.textContent = node.textContent; - data.href = node.href; + if (node.href) data.href = node.href; } return parent.postMessage(data, '*'); }); diff --git a/script.coffee b/script.coffee index 615f71850..6b9dce615 100644 --- a/script.coffee +++ b/script.coffee @@ -1379,7 +1379,7 @@ qr = data = {} if node = document.querySelector('td b')?.firstChild data.textContent = node.textContent - data.href = node.href + data.href = node.href if node.href parent.postMessage data, '*' c = $('b')?.lastChild From cfccab22b0373def732f13a5f3df59597e0ddc0f Mon Sep 17 00:00:00 2001 From: Nicolas Stepien Date: Sat, 10 Dec 2011 23:18:26 +0100 Subject: [PATCH 141/169] Fix #37 --- 4chan_x.user.js | 2 +- changelog | 1 + script.coffee | 2 +- 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/4chan_x.user.js b/4chan_x.user.js index 68e18d88d..b3ef0761e 100644 --- a/4chan_x.user.js +++ b/4chan_x.user.js @@ -1688,7 +1688,7 @@ caretPos = ta.selectionStart; ta.value = ta.value.slice(0, caretPos) + text + ta.value.slice(ta.selectionEnd, ta.value.length); ta.focus(); - return ta.selectionEnd = ta.selectionStart = caretPos + text.length; + return ta.selectionEnd = ta.selectionStart = caretPos + text.length + 1 * (engine === 'presto'); }, refresh: function() { var m, newFile, oldFile, _ref; diff --git a/changelog b/changelog index 97fac12b3..9461230bb 100644 --- a/changelog +++ b/changelog @@ -1,6 +1,7 @@ master - mayhem enable autoposting when submitting a captcha while on cooldown + fix caret position when quoting on Opera 2.23.1 - mayhem diff --git a/script.coffee b/script.coffee index 6b9dce615..6be3dd4cd 100644 --- a/script.coffee +++ b/script.coffee @@ -1327,7 +1327,7 @@ qr = ta.value = ta.value.slice(0, caretPos) + text + ta.value.slice(ta.selectionEnd, ta.value.length) ta.focus() #move the caret to the end of the new quote - ta.selectionEnd = ta.selectionStart = caretPos + text.length + ta.selectionEnd = ta.selectionStart = caretPos + text.length + 1*(engine is 'presto') refresh: -> $('[name=sub]', qr.el).value = '' From 19703e047d4fa38aa45010a36fd9a546faa1e20c Mon Sep 17 00:00:00 2001 From: Nicolas Stepien Date: Sun, 11 Dec 2011 00:33:02 +0100 Subject: [PATCH 142/169] Close #19 --- 4chan_x.user.js | 54 ++++++++++++++++++++++++++++--------------------- changelog | 1 + script.coffee | 47 +++++++++++++++++++++--------------------- 3 files changed, 56 insertions(+), 46 deletions(-) diff --git a/4chan_x.user.js b/4chan_x.user.js index b3ef0761e..7e5bc4b3e 100644 --- a/4chan_x.user.js +++ b/4chan_x.user.js @@ -118,7 +118,8 @@ 'Quote Inline': [true, 'Show quoted post inline on quote click'], 'Quote Preview': [true, 'Show quote content on hover'], 'Indicate OP quote': [true, 'Add \'(OP)\' to OP quotes'], - 'Indicate Cross-thread Quotes': [true, 'Add \'(Cross-thread)\' to cross-threads quotes'] + 'Indicate Cross-thread Quotes': [true, 'Add \'(Cross-thread)\' to cross-threads quotes'], + 'Forward Hiding': [true, 'Hide original posts of inlined backlinks'] } }, filter: { @@ -2446,7 +2447,7 @@ e.preventDefault(); id = this.hash.slice(1); if (/\binlined\b/.test(this.className)) { - $.rm($.x("following::*[@id='i" + id + "']", this)); + quoteInline.rm(this, id); } else { if ($.x("ancestor::*[@id='" + id + "']", this)) return; quoteInline.add(this, id); @@ -2460,6 +2461,9 @@ inline = quoteInline.table(id, el.innerHTML); if (/\bbacklink\b/.test(q.className)) { $.after(q.parentNode, inline); + if (conf['Forward Hiding']) { + $.addClass($.x('ancestor::table', el), 'forwarded'); + } return; } return $.after(root, inline); @@ -2477,6 +2481,20 @@ })); } }, + rm: function(q, id) { + var inlined, table, _i, _len, _ref; + table = $.x("following::*[@id='i" + id + "']", q); + $.rm(table); + if (!conf['Forward Hiding']) return; + _ref = $$('.backlink.inlined', table); + for (_i = 0, _len = _ref.length; _i < _len; _i++) { + inlined = _ref[_i]; + $.removeClass($.x('ancestor::table', $.id(inlined.hash.slice(1))), 'forwarded'); + } + if (/\bbacklink\b/.test(q.className)) { + return $.removeClass($.x('ancestor::table', $.id(id)), 'forwarded'); + } + }, parse: function(req, pathname, id, threadID, inline) { var body, href, html, link, newInline, op, quote, reply, _i, _j, _len, _len2, _ref, _ref2; if (!inline.parentNode) return; @@ -3166,9 +3184,6 @@ }, css: '\ /* dialog styling */\ - a[href="javascript:;"] {\ - text-decoration: none;\ - }\ div.dialog {\ border: 1px solid;\ }\ @@ -3178,6 +3193,17 @@ label, a, .favicon, #qr img {\ cursor: pointer;\ }\ + a[href="javascript:;"] {\ + text-decoration: none;\ + }\ +\ + [hidden], /* Firefox bug: hidden tables are not hidden. fixed in 9.0 */\ + .thread.stub > :not(.block),\ + #content > [name=tab]:not(:checked) + div,\ + #updater:not(:hover) > :not(.move),\ + #qp > input, #qp .inline, .forwarded {\ + display: none;\ + }\ \ .new {\ background: lime;\ @@ -3194,10 +3220,6 @@ td.replyhider {\ vertical-align: top;\ }\ -\ - div.thread.stub > *:not(.block) {\ - display: none;\ - }\ \ .filesize + br + a {\ float: left;\ @@ -3261,9 +3283,6 @@ #options label {\ text-decoration: underline;\ }\ - #options [name=tab]:not(:checked) + * {\ - display: none;\ - }\ #content > div {\ height: 450px;\ overflow: auto;\ @@ -3330,9 +3349,6 @@ border: none;\ background: transparent;\ }\ - #updater:not(:hover) > div:not(.move) {\ - display: none;\ - }\ \ #stats {\ border: none;\ @@ -3362,9 +3378,6 @@ border: 1px solid;\ padding-bottom: 5px;\ }\ - #qp input, #qp .inline {\ - display: none;\ - }\ .qphl {\ outline: 2px solid rgba(216, 94, 49, .7);\ }\ @@ -3381,11 +3394,6 @@ .filtered {\ text-decoration: line-through;\ }\ -\ - /* Firefox bug: hidden tables are not hidden. fixed in 9.0 */\ - [hidden] {\ - display: none;\ - }\ \ #files > input {\ display: block;\ diff --git a/changelog b/changelog index 9461230bb..964e8cd22 100644 --- a/changelog +++ b/changelog @@ -1,5 +1,6 @@ master - mayhem + hide original posts from inlined backlinks - optional enable autoposting when submitting a captcha while on cooldown fix caret position when quoting on Opera diff --git a/script.coffee b/script.coffee index 6be3dd4cd..1e3452372 100644 --- a/script.coffee +++ b/script.coffee @@ -46,6 +46,7 @@ config = 'Quote Preview': [true, 'Show quote content on hover'] 'Indicate OP quote': [true, 'Add \'(OP)\' to OP quotes'] 'Indicate Cross-thread Quotes': [true, 'Add \'(Cross-thread)\' to cross-threads quotes'] + 'Forward Hiding': [true, 'Hide original posts of inlined backlinks'] filter: name: '' tripcode: '' @@ -1929,8 +1930,7 @@ quoteInline = e.preventDefault() id = @hash[1..] if /\binlined\b/.test @className - # remove the corresponding table or loading td - $.rm $.x "following::*[@id='i#{id}']", @ + quoteInline.rm @, id else return if $.x "ancestor::*[@id='#{id}']", @ quoteInline.add @, id @@ -1942,6 +1942,7 @@ quoteInline = inline = quoteInline.table id, el.innerHTML if /\bbacklink\b/.test q.className $.after q.parentNode, inline + $.addClass $.x('ancestor::table', el), 'forwarded' if conf['Forward Hiding'] return $.after root, inline else @@ -1954,6 +1955,16 @@ quoteInline = threadID = pathname.split('/').pop() $.cache pathname, (-> quoteInline.parse @, pathname, id, threadID, inline) + rm: (q, id) -> + #select the corresponding table or loading td + table = $.x "following::*[@id='i#{id}']", q + $.rm table + return unless conf['Forward Hiding'] + for inlined in $$ '.backlink.inlined', table + $.removeClass $.x('ancestor::table', $.id inlined.hash[1..]), 'forwarded' + if /\bbacklink\b/.test q.className + $.removeClass $.x('ancestor::table', $.id id), 'forwarded' + parse: (req, pathname, id, threadID, inline) -> return unless inline.parentNode @@ -2526,9 +2537,6 @@ Main = css: ' /* dialog styling */ - a[href="javascript:;"] { - text-decoration: none; - } div.dialog { border: 1px solid; } @@ -2538,6 +2546,17 @@ Main = label, a, .favicon, #qr img { cursor: pointer; } + a[href="javascript:;"] { + text-decoration: none; + } + + [hidden], /* Firefox bug: hidden tables are not hidden. fixed in 9.0 */ + .thread.stub > :not(.block), + #content > [name=tab]:not(:checked) + div, + #updater:not(:hover) > :not(.move), + #qp > input, #qp .inline, .forwarded { + display: none; + } .new { background: lime; @@ -2555,10 +2574,6 @@ Main = vertical-align: top; } - div.thread.stub > *:not(.block) { - display: none; - } - .filesize + br + a { float: left; pointer-events: none; @@ -2621,9 +2636,6 @@ Main = #options label { text-decoration: underline; } - #options [name=tab]:not(:checked) + * { - display: none; - } #content > div { height: 450px; overflow: auto; @@ -2690,9 +2702,6 @@ Main = border: none; background: transparent; } - #updater:not(:hover) > div:not(.move) { - display: none; - } #stats { border: none; @@ -2722,9 +2731,6 @@ Main = border: 1px solid; padding-bottom: 5px; } - #qp input, #qp .inline { - display: none; - } .qphl { outline: 2px solid rgba(216, 94, 49, .7); } @@ -2742,11 +2748,6 @@ Main = text-decoration: line-through; } - /* Firefox bug: hidden tables are not hidden. fixed in 9.0 */ - [hidden] { - display: none; - } - #files > input { display: block; } From 898b2b0f195dc3277d37c29f10d1fdabf7a0a0e3 Mon Sep 17 00:00:00 2001 From: Nicolas Stepien Date: Sun, 11 Dec 2011 03:44:10 +0100 Subject: [PATCH 143/169] Space the favicon previews. --- 4chan_x.user.js | 2 +- script.coffee | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/4chan_x.user.js b/4chan_x.user.js index 7e5bc4b3e..4ce2378fd 100644 --- a/4chan_x.user.js +++ b/4chan_x.user.js @@ -1441,7 +1441,7 @@ $.cb.value.call(this); Favicon["switch"](); if (g.REPLY && conf['Unread Count']) Favicon.update(); - return this.nextElementSibling.innerHTML = ""; + return this.nextElementSibling.innerHTML = " "; } }; diff --git a/script.coffee b/script.coffee index 1e3452372..0c2adee42 100644 --- a/script.coffee +++ b/script.coffee @@ -1078,7 +1078,7 @@ options = $.cb.value.call @ Favicon.switch() Favicon.update() if g.REPLY and conf['Unread Count'] - @nextElementSibling.innerHTML = "" + @nextElementSibling.innerHTML = " " cooldown = #TODO merge into qr From f7af32247fc559f69effa6bbba54a994a161195a Mon Sep 17 00:00:00 2001 From: Nicolas Stepien Date: Sun, 11 Dec 2011 03:53:26 +0100 Subject: [PATCH 144/169] Only save settings on change, not when opening the options. --- 4chan_x.user.js | 6 +++--- script.coffee | 8 ++++---- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/4chan_x.user.js b/4chan_x.user.js index 4ce2378fd..7b1f2ae1b 100644 --- a/4chan_x.user.js +++ b/4chan_x.user.js @@ -1370,7 +1370,9 @@ (back = $('[name=backlink]', dialog)).value = conf['backlink']; (time = $('[name=time]', dialog)).value = conf['time']; $.on(back, 'keyup', options.backlink); + $.on(back, 'keyup', $.cb.value); $.on(time, 'keyup', options.time); + $.on(time, 'keyup', $.cb.value); favicon = $('select', dialog); _ref3 = favicon.options; for (_j = 0, _len2 = _ref3.length; _j < _len2; _j++) { @@ -1381,6 +1383,7 @@ } } $.on(favicon, 'change', options.favicon); + $.on(favicon, 'change', $.cb.value); _ref4 = $$('#keybinds_tab + div input', dialog); for (_k = 0, _len3 = _ref4.length; _k < _len3; _k++) { input = _ref4[_k]; @@ -1428,17 +1431,14 @@ return $.cb.value.call(this); }, time: function() { - $.cb.value.call(this); Time.foo(); Time.date = new Date(); return $('#timePreview').textContent = Time.funk(Time); }, backlink: function() { - $.cb.value.call(this); return $('#backlinkPreview').textContent = conf['backlink'].replace(/%id/, '123456789'); }, favicon: function() { - $.cb.value.call(this); Favicon["switch"](); if (g.REPLY && conf['Unread Count']) Favicon.update(); return this.nextElementSibling.innerHTML = " "; diff --git a/script.coffee b/script.coffee index 0c2adee42..34846bf18 100644 --- a/script.coffee +++ b/script.coffee @@ -1020,13 +1020,16 @@ options = (back = $ '[name=backlink]', dialog).value = conf['backlink'] (time = $ '[name=time]', dialog).value = conf['time'] $.on back, 'keyup', options.backlink + $.on back, 'keyup', $.cb.value $.on time, 'keyup', options.time + $.on time, 'keyup', $.cb.value favicon = $ 'select', dialog for option in favicon.options if option.textContent is conf['favicon'] option.selected = true break $.on favicon, 'change', options.favicon + $.on favicon, 'change', $.cb.value #keybinds for input in $$ '#keybinds_tab + div input', dialog @@ -1045,7 +1048,7 @@ options = overlay = $.el 'div', id: 'overlay' $.on overlay, 'click', -> $.rm overlay - $.on dialog, 'click', (e) -> e.stopPropagation() + $.on dialog, 'click', (e) -> e.stopPropagation() $.add overlay, dialog $.add d.body, overlay @@ -1067,15 +1070,12 @@ options = @value = key $.cb.value.call @ time: -> - $.cb.value.call @ Time.foo() Time.date = new Date() $('#timePreview').textContent = Time.funk Time backlink: -> - $.cb.value.call @ $('#backlinkPreview').textContent = conf['backlink'].replace /%id/, '123456789' favicon: -> - $.cb.value.call @ Favicon.switch() Favicon.update() if g.REPLY and conf['Unread Count'] @nextElementSibling.innerHTML = " " From 175001ed75a534a919cb92577e5a862dd7b140ae Mon Sep 17 00:00:00 2001 From: Nicolas Stepien Date: Sun, 11 Dec 2011 04:11:57 +0100 Subject: [PATCH 145/169] Put @updateURL back for scriptish users. Release 2.23.2. --- 4chan_x.user.js | 9 +++++---- Cakefile | 5 +++-- changelog | 2 ++ latest.js | 2 +- script.coffee | 2 +- 5 files changed, 12 insertions(+), 8 deletions(-) diff --git a/4chan_x.user.js b/4chan_x.user.js index 7b1f2ae1b..c3df38d43 100644 --- a/4chan_x.user.js +++ b/4chan_x.user.js @@ -1,6 +1,6 @@ // ==UserScript== // @name 4chan x -// @version 2.23.1 +// @version 2.23.2 // @namespace aeosynth // @description Adds various features. // @copyright 2009-2011 James Campos @@ -8,6 +8,7 @@ // @include http://boards.4chan.org/* // @include http://sys.4chan.org/* // @run-at document-start +// @updateURL https://raw.github.com/mayhemydg/4chan-x/stable/4chan_x.user.js // @icon https://raw.github.com/mayhemydg/4chan-x/gh-pages/favicon.png // ==/UserScript== @@ -15,7 +16,7 @@ * * Copyright (c) 2009-2011 James Campos * http://mayhemydg.github.com/4chan-x/ - * 4chan x 2.23.1 + * 4chan x 2.23.2 * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation @@ -39,7 +40,7 @@ * * HACKING * - * 4chan x is written in CoffeeScript[1], and developed on github[2]. + * 4chan x is written in CoffeeScript[1], and developed on GitHub[2]. * * [1]: http://jashkenas.github.com/coffee-script/ * [2]: http://github.com/mayhemydg/4chan-x @@ -211,7 +212,7 @@ NAMESPACE = '4chan_x.'; - VERSION = '2.23.1'; + VERSION = '2.23.2'; SECOND = 1000; diff --git a/Cakefile b/Cakefile index dbf68be70..569b989f5 100644 --- a/Cakefile +++ b/Cakefile @@ -2,7 +2,7 @@ {exec} = require 'child_process' fs = require 'fs' -VERSION = '2.23.1' +VERSION = '2.23.2' HEADER = """ // ==UserScript== @@ -15,6 +15,7 @@ HEADER = """ // @include http://boards.4chan.org/* // @include http://sys.4chan.org/* // @run-at document-start +// @updateURL https://raw.github.com/mayhemydg/4chan-x/stable/4chan_x.user.js // @icon https://raw.github.com/mayhemydg/4chan-x/gh-pages/favicon.png // ==/UserScript== @@ -46,7 +47,7 @@ HEADER = """ * * HACKING * - * 4chan x is written in CoffeeScript[1], and developed on github[2]. + * 4chan x is written in CoffeeScript[1], and developed on GitHub[2]. * * [1]: http://jashkenas.github.com/coffee-script/ * [2]: http://github.com/mayhemydg/4chan-x diff --git a/changelog b/changelog index 964e8cd22..858cb5d24 100644 --- a/changelog +++ b/changelog @@ -1,4 +1,6 @@ master + +2.23.2 - mayhem hide original posts from inlined backlinks - optional enable autoposting when submitting a captcha while on cooldown diff --git a/latest.js b/latest.js index 76fdf91b5..32344632d 100644 --- a/latest.js +++ b/latest.js @@ -1 +1 @@ -postMessage({version:'2.23.1'},'*'); +postMessage({version:'2.23.2'},'*'); diff --git a/script.coffee b/script.coffee index 34846bf18..fca7c1ad8 100644 --- a/script.coffee +++ b/script.coffee @@ -126,7 +126,7 @@ conf = {} ) null, config NAMESPACE = '4chan_x.' -VERSION = '2.23.1' +VERSION = '2.23.2' SECOND = 1000 MINUTE = 60*SECOND HOUR = 60*MINUTE From 4ef8cb05ee157700ec8d0006588c9bb68b7bc8b1 Mon Sep 17 00:00:00 2001 From: Nicolas Stepien Date: Sun, 11 Dec 2011 08:07:26 +0100 Subject: [PATCH 146/169] Remove dead link. --- 4chan_x.user.js | 4 ++-- script.coffee | 5 ++--- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/4chan_x.user.js b/4chan_x.user.js index c3df38d43..cbd16d96a 100644 --- a/4chan_x.user.js +++ b/4chan_x.user.js @@ -3255,9 +3255,9 @@ #overlay {\ position: fixed;\ top: 0;\ + right: 0;\ left: 0;\ - height: 100%;\ - width: 100%;\ + bottom: 0;\ text-align: center;\ background: rgba(0,0,0,.5);\ }\ diff --git a/script.coffee b/script.coffee index fca7c1ad8..bde48d9b9 100644 --- a/script.coffee +++ b/script.coffee @@ -101,7 +101,6 @@ config = # XXX chrome can't into `{log} = console` if console? # XXX scriptish - console.log.apply is not a function - # https://github.com/scriptish/scriptish/issues/3 log = (arg) -> console.log arg @@ -2607,9 +2606,9 @@ Main = #overlay { position: fixed; top: 0; + right: 0; left: 0; - height: 100%; - width: 100%; + bottom: 0; text-align: center; background: rgba(0,0,0,.5); } From 5bd3cefdbe85a3af9e3ccd54e7c1985985eed4c1 Mon Sep 17 00:00:00 2001 From: James Campos Date: Sun, 11 Dec 2011 02:07:23 -0800 Subject: [PATCH 147/169] Cakefile: invoke --- Cakefile | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/Cakefile b/Cakefile index 569b989f5..57524dd33 100644 --- a/Cakefile +++ b/Cakefile @@ -76,17 +76,14 @@ HEADER = """ INFILE = 'script.coffee' OUTFILE = '4chan_x.user.js' -build = -> +task 'build', -> exec 'coffee --print script.coffee', (err, stdout, stderr) -> throw err if err fs.writeFile OUTFILE, HEADER + stdout, (err) -> throw err if err -task 'build', -> - build() - task 'dev', -> - build() + invoke 'build' fs.watchFile INFILE, interval: 250, (curr, prev) -> if curr.mtime > prev.mtime build() From df9af7f162af058640c18f83556f3eaf61558289 Mon Sep 17 00:00:00 2001 From: James Campos Date: Sun, 11 Dec 2011 02:07:45 -0800 Subject: [PATCH 148/169] console.log.bind --- 4chan_x.user.js | 6 +----- script.coffee | 5 +---- 2 files changed, 2 insertions(+), 9 deletions(-) diff --git a/4chan_x.user.js b/4chan_x.user.js index cbd16d96a..c91612126 100644 --- a/4chan_x.user.js +++ b/4chan_x.user.js @@ -171,11 +171,7 @@ } }; - if (typeof console !== "undefined" && console !== null) { - log = function(arg) { - return console.log(arg); - }; - } + log = console.log.bind(console); if (!Object.keys) { Object.keys = function(o) { diff --git a/script.coffee b/script.coffee index bde48d9b9..1da59c13f 100644 --- a/script.coffee +++ b/script.coffee @@ -99,10 +99,7 @@ config = 'Interval': 30 # XXX chrome can't into `{log} = console` -if console? - # XXX scriptish - console.log.apply is not a function - log = (arg) -> - console.log arg +log = console.log.bind console # XXX opera cannot into Object.keys if not Object.keys From 0c1ed9e26145b0b90103846d3c8ab170faa807cb Mon Sep 17 00:00:00 2001 From: James Campos Date: Sun, 11 Dec 2011 02:14:29 -0800 Subject: [PATCH 149/169] i suck --- Cakefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cakefile b/Cakefile index 57524dd33..db7715a1b 100644 --- a/Cakefile +++ b/Cakefile @@ -86,4 +86,4 @@ task 'dev', -> invoke 'build' fs.watchFile INFILE, interval: 250, (curr, prev) -> if curr.mtime > prev.mtime - build() + invoke 'build' From 7aa148e61406995d9948f92717fea30e6671f9bc Mon Sep 17 00:00:00 2001 From: Nicolas Stepien Date: Sun, 11 Dec 2011 16:43:39 +0100 Subject: [PATCH 150/169] Do not move the options down when the screen isn't wide enough. --- 4chan_x.user.js | 2 +- script.coffee | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/4chan_x.user.js b/4chan_x.user.js index c91612126..b08a69a48 100644 --- a/4chan_x.user.js +++ b/4chan_x.user.js @@ -3257,7 +3257,7 @@ text-align: center;\ background: rgba(0,0,0,.5);\ }\ - #overlay::before {\ + #overlay::after {\ content: "";\ display: inline-block;\ height: 100%;\ diff --git a/script.coffee b/script.coffee index 1da59c13f..bee386705 100644 --- a/script.coffee +++ b/script.coffee @@ -2609,7 +2609,7 @@ Main = text-align: center; background: rgba(0,0,0,.5); } - #overlay::before { + #overlay::after { content: ""; display: inline-block; height: 100%; From 3c889374fb2f6b023d73c1ae2420df0f0c6a5683 Mon Sep 17 00:00:00 2001 From: Nicolas Stepien Date: Sun, 11 Dec 2011 17:50:48 +0100 Subject: [PATCH 151/169] Revert "console.log.bind" This reverts commit df9af7f162af058640c18f83556f3eaf61558289. --- 4chan_x.user.js | 6 +++++- script.coffee | 5 ++++- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/4chan_x.user.js b/4chan_x.user.js index b08a69a48..b62a17af0 100644 --- a/4chan_x.user.js +++ b/4chan_x.user.js @@ -171,7 +171,11 @@ } }; - log = console.log.bind(console); + if (typeof console !== "undefined" && console !== null) { + log = function(arg) { + return console.log(arg); + }; + } if (!Object.keys) { Object.keys = function(o) { diff --git a/script.coffee b/script.coffee index bee386705..be856331f 100644 --- a/script.coffee +++ b/script.coffee @@ -99,7 +99,10 @@ config = 'Interval': 30 # XXX chrome can't into `{log} = console` -log = console.log.bind console +if console? + # XXX scriptish - console.log.apply is not a function + log = (arg) -> + console.log arg # XXX opera cannot into Object.keys if not Object.keys From c590237d775765bb961069f4d024bca23abb9c0c Mon Sep 17 00:00:00 2001 From: Nicolas Stepien Date: Sun, 11 Dec 2011 17:58:01 +0100 Subject: [PATCH 152/169] Don't duplicate posts when the last post gets deleted. --- 4chan_x.user.js | 2 +- changelog | 2 ++ script.coffee | 2 +- 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/4chan_x.user.js b/4chan_x.user.js index b62a17af0..f53d3b9a0 100644 --- a/4chan_x.user.js +++ b/4chan_x.user.js @@ -2046,7 +2046,7 @@ _ref3 = $$('.reply', body).reverse(); for (_j = 0, _len2 = _ref3.length; _j < _len2; _j++) { reply = _ref3[_j]; - if (reply.id === id) break; + if (reply.id <= id) break; $.prepend(frag, reply.parentNode.parentNode.parentNode); } newPosts = frag.childNodes.length; diff --git a/changelog b/changelog index 858cb5d24..042410d54 100644 --- a/changelog +++ b/changelog @@ -1,4 +1,6 @@ master +- mayhem + fix 2.32.2 regression duplicating new posts in rare cases 2.23.2 - mayhem diff --git a/script.coffee b/script.coffee index be856331f..4e2aac204 100644 --- a/script.coffee +++ b/script.coffee @@ -1630,7 +1630,7 @@ updater = id = $('td[id]', updater.br.previousElementSibling)?.id or 0 frag = d.createDocumentFragment() for reply in $$('.reply', body).reverse() - if reply.id is id + if reply.id <= id #make sure to not insert older posts break $.prepend frag, reply.parentNode.parentNode.parentNode #table From 2ed173f0a5d6bc8f5a631ec4af9b0e15c70f8b42 Mon Sep 17 00:00:00 2001 From: Nicolas Stepien Date: Sun, 11 Dec 2011 17:59:34 +0100 Subject: [PATCH 153/169] Release 2.23.3 --- 4chan_x.user.js | 6 +++--- Cakefile | 2 +- changelog | 2 ++ latest.js | 2 +- script.coffee | 2 +- 5 files changed, 8 insertions(+), 6 deletions(-) diff --git a/4chan_x.user.js b/4chan_x.user.js index f53d3b9a0..a59a61ab3 100644 --- a/4chan_x.user.js +++ b/4chan_x.user.js @@ -1,6 +1,6 @@ // ==UserScript== // @name 4chan x -// @version 2.23.2 +// @version 2.23.3 // @namespace aeosynth // @description Adds various features. // @copyright 2009-2011 James Campos @@ -16,7 +16,7 @@ * * Copyright (c) 2009-2011 James Campos * http://mayhemydg.github.com/4chan-x/ - * 4chan x 2.23.2 + * 4chan x 2.23.3 * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation @@ -212,7 +212,7 @@ NAMESPACE = '4chan_x.'; - VERSION = '2.23.2'; + VERSION = '2.23.3'; SECOND = 1000; diff --git a/Cakefile b/Cakefile index db7715a1b..ffc1406e1 100644 --- a/Cakefile +++ b/Cakefile @@ -2,7 +2,7 @@ {exec} = require 'child_process' fs = require 'fs' -VERSION = '2.23.2' +VERSION = '2.23.3' HEADER = """ // ==UserScript== diff --git a/changelog b/changelog index 042410d54..f46ce8b9c 100644 --- a/changelog +++ b/changelog @@ -1,4 +1,6 @@ master + +2.32.3 - mayhem fix 2.32.2 regression duplicating new posts in rare cases diff --git a/latest.js b/latest.js index 32344632d..b5d5cb4ba 100644 --- a/latest.js +++ b/latest.js @@ -1 +1 @@ -postMessage({version:'2.23.2'},'*'); +postMessage({version:'2.23.3'},'*'); diff --git a/script.coffee b/script.coffee index 4e2aac204..56a5d3ad8 100644 --- a/script.coffee +++ b/script.coffee @@ -125,7 +125,7 @@ conf = {} ) null, config NAMESPACE = '4chan_x.' -VERSION = '2.23.2' +VERSION = '2.23.3' SECOND = 1000 MINUTE = 60*SECOND HOUR = 60*MINUTE From f28964138efe22b4f08f409cffc46be632224354 Mon Sep 17 00:00:00 2001 From: Nicolas Stepien Date: Sun, 11 Dec 2011 18:38:10 +0100 Subject: [PATCH 154/169] Fix quoting OP, optimize. Kill two birds with in one stone. --- 4chan_x.user.js | 2 +- script.coffee | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/4chan_x.user.js b/4chan_x.user.js index a59a61ab3..dcfc4895e 100644 --- a/4chan_x.user.js +++ b/4chan_x.user.js @@ -1680,7 +1680,7 @@ text = ">>" + id + "\n"; selection = window.getSelection(); if (s = selection.toString()) { - selectionID = (_ref = $.x('ancestor::blockquote', selection.anchorNode)) != null ? _ref.parentNode.firstElementChild.name : void 0; + selectionID = (_ref = $.x('ancestor::blockquote/preceding-sibling::input', selection.anchorNode)) != null ? _ref.name : void 0; if (selectionID === id) { s = s.replace(/\n/g, '\n>'); text += ">" + s + "\n"; diff --git a/script.coffee b/script.coffee index 56a5d3ad8..ca8a7db52 100644 --- a/script.coffee +++ b/script.coffee @@ -1316,7 +1316,7 @@ qr = selection = window.getSelection() if s = selection.toString() - selectionID = $.x('ancestor::blockquote', selection.anchorNode)?.parentNode.firstElementChild.name + selectionID = $.x('ancestor::blockquote/preceding-sibling::input', selection.anchorNode)?.name if selectionID is id s = s.replace /\n/g, '\n>' text += ">#{s}\n" From e20d07e1be9e9794577728c657853a67be36f479 Mon Sep 17 00:00:00 2001 From: Nicolas Stepien Date: Sun, 11 Dec 2011 21:04:42 +0100 Subject: [PATCH 155/169] console.log.bind --- 4chan_x.user.js | 8 ++------ script.coffee | 6 +----- 2 files changed, 3 insertions(+), 11 deletions(-) diff --git a/4chan_x.user.js b/4chan_x.user.js index dcfc4895e..ee44c4fb2 100644 --- a/4chan_x.user.js +++ b/4chan_x.user.js @@ -64,7 +64,7 @@ */ (function() { - var $, $$, DAY, Favicon, HOUR, MINUTE, Main, NAMESPACE, Recaptcha, SECOND, Time, VERSION, anonymize, conf, config, cooldown, d, engine, expandComment, expandThread, filter, flatten, g, getTitle, imgExpand, imgGif, imgHover, key, keybinds, log, nav, options, qr, quoteBacklink, quoteDR, quoteInline, quoteOP, quotePreview, redirect, replyHiding, reportButton, revealSpoilers, sauce, strikethroughQuotes, threadHiding, threadStats, threading, titlePost, ui, unread, updater, val, watcher; + var $, $$, DAY, Favicon, HOUR, MINUTE, Main, NAMESPACE, Recaptcha, SECOND, Time, VERSION, anonymize, conf, config, cooldown, d, engine, expandComment, expandThread, filter, flatten, g, getTitle, imgExpand, imgGif, imgHover, key, keybinds, log, nav, options, qr, quoteBacklink, quoteDR, quoteInline, quoteOP, quotePreview, redirect, replyHiding, reportButton, revealSpoilers, sauce, strikethroughQuotes, threadHiding, threadStats, threading, titlePost, ui, unread, updater, val, watcher, _base; var __slice = Array.prototype.slice; config = { @@ -171,11 +171,7 @@ } }; - if (typeof console !== "undefined" && console !== null) { - log = function(arg) { - return console.log(arg); - }; - } + log = typeof (_base = console.log).bind === "function" ? _base.bind(console) : void 0; if (!Object.keys) { Object.keys = function(o) { diff --git a/script.coffee b/script.coffee index ca8a7db52..6120a9072 100644 --- a/script.coffee +++ b/script.coffee @@ -98,11 +98,7 @@ config = 'Auto Update': [true, 'Automatically fetch new posts'] 'Interval': 30 -# XXX chrome can't into `{log} = console` -if console? - # XXX scriptish - console.log.apply is not a function - log = (arg) -> - console.log arg +log = console.log.bind? console # XXX opera cannot into Object.keys if not Object.keys From b8195861645071c4c7d8997fdbafd65b4db434a8 Mon Sep 17 00:00:00 2001 From: Nicolas Stepien Date: Sun, 11 Dec 2011 21:09:35 +0100 Subject: [PATCH 156/169] Note. --- script.coffee | 1 + 1 file changed, 1 insertion(+) diff --git a/script.coffee b/script.coffee index 6120a9072..4c616330d 100644 --- a/script.coffee +++ b/script.coffee @@ -98,6 +98,7 @@ config = 'Auto Update': [true, 'Automatically fetch new posts'] 'Interval': 30 +# XXX GreaseMonkey can't into console.log.bind log = console.log.bind? console # XXX opera cannot into Object.keys From 0dca954a242c92cb9c3edac0dac60b942598c692 Mon Sep 17 00:00:00 2001 From: Nicolas Stepien Date: Sun, 11 Dec 2011 17:58:01 +0100 Subject: [PATCH 157/169] Note. --- script.coffee | 1 + 1 file changed, 1 insertion(+) diff --git a/script.coffee b/script.coffee index 4c616330d..0f8f2a125 100644 --- a/script.coffee +++ b/script.coffee @@ -98,6 +98,7 @@ config = 'Auto Update': [true, 'Automatically fetch new posts'] 'Interval': 30 +# XXX Chrome can't into {log} = console # XXX GreaseMonkey can't into console.log.bind log = console.log.bind? console From faa952511c3b69e668409a0dc88d04b7665ad045 Mon Sep 17 00:00:00 2001 From: Nicolas Stepien Date: Mon, 12 Dec 2011 16:12:11 +0100 Subject: [PATCH 158/169] Oops, save then preview the changes. --- 4chan_x.user.js | 6 +++--- script.coffee | 7 ++++--- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/4chan_x.user.js b/4chan_x.user.js index ee44c4fb2..cf8637270 100644 --- a/4chan_x.user.js +++ b/4chan_x.user.js @@ -1366,10 +1366,10 @@ } (back = $('[name=backlink]', dialog)).value = conf['backlink']; (time = $('[name=time]', dialog)).value = conf['time']; - $.on(back, 'keyup', options.backlink); $.on(back, 'keyup', $.cb.value); - $.on(time, 'keyup', options.time); + $.on(back, 'keyup', options.backlink); $.on(time, 'keyup', $.cb.value); + $.on(time, 'keyup', options.time); favicon = $('select', dialog); _ref3 = favicon.options; for (_j = 0, _len2 = _ref3.length; _j < _len2; _j++) { @@ -1379,8 +1379,8 @@ break; } } - $.on(favicon, 'change', options.favicon); $.on(favicon, 'change', $.cb.value); + $.on(favicon, 'change', options.favicon); _ref4 = $$('#keybinds_tab + div input', dialog); for (_k = 0, _len3 = _ref4.length; _k < _len3; _k++) { input = _ref4[_k]; diff --git a/script.coffee b/script.coffee index 0f8f2a125..20f9f8a16 100644 --- a/script.coffee +++ b/script.coffee @@ -98,6 +98,7 @@ config = 'Auto Update': [true, 'Automatically fetch new posts'] 'Interval': 30 + # XXX Chrome can't into {log} = console # XXX GreaseMonkey can't into console.log.bind log = console.log.bind? console @@ -1016,17 +1017,17 @@ options = #rice (back = $ '[name=backlink]', dialog).value = conf['backlink'] (time = $ '[name=time]', dialog).value = conf['time'] - $.on back, 'keyup', options.backlink $.on back, 'keyup', $.cb.value - $.on time, 'keyup', options.time + $.on back, 'keyup', options.backlink $.on time, 'keyup', $.cb.value + $.on time, 'keyup', options.time favicon = $ 'select', dialog for option in favicon.options if option.textContent is conf['favicon'] option.selected = true break - $.on favicon, 'change', options.favicon $.on favicon, 'change', $.cb.value + $.on favicon, 'change', options.favicon #keybinds for input in $$ '#keybinds_tab + div input', dialog From bc57aa561f8a94546743231b899867a2254286db Mon Sep 17 00:00:00 2001 From: Nicolas Stepien Date: Tue, 13 Dec 2011 15:17:48 +0100 Subject: [PATCH 159/169] Thread expansion optimizations. --- 4chan_x.user.js | 21 ++++++++------------- script.coffee | 18 ++++++++---------- 2 files changed, 16 insertions(+), 23 deletions(-) diff --git a/4chan_x.user.js b/4chan_x.user.js index cf8637270..c6070a4f5 100644 --- a/4chan_x.user.js +++ b/4chan_x.user.js @@ -760,21 +760,18 @@ } }, parse: function(req, pathname, thread, a) { - var body, br, href, link, next, quote, reply, table, tables, _i, _j, _k, _len, _len2, _len3, _ref, _ref2, _results; + var body, br, frag, href, link, next, quote, reply, _i, _j, _len, _len2, _ref, _ref2; if (req.status !== 200) { a.textContent = "" + req.status + " " + req.statusText; $.off(a, 'click', expandThread.cb.toggle); return; } a.textContent = a.textContent.replace('X Loading...', '-'); - while ((next = a.nextSibling) && !next.clear) { - $.rm(next); - } - br = next; body = $.el('body', { innerHTML: req.responseText }); - _ref = $$('td[id]', body); + frag = d.createDocumentFragment(); + _ref = $$('.reply', body); for (_i = 0, _len = _ref.length; _i < _len; _i++) { reply = _ref[_i]; _ref2 = $$('.quotelink', reply); @@ -789,15 +786,13 @@ link = $('.quotejs', reply); link.href = "res/" + thread.firstChild.id + "#" + reply.id; link.nextSibling.href = "res/" + thread.firstChild.id + "#q" + reply.id; + $.add(frag, reply.parentNode.parentNode.parentNode); } - tables = $$('form[name=delform] table', body); - tables.pop(); - _results = []; - for (_k = 0, _len3 = tables.length; _k < _len3; _k++) { - table = tables[_k]; - _results.push($.before(br, table)); + while ((next = a.nextSibling) && !next.clear) { + $.rm(next); } - return _results; + br = next; + return $.before(br, frag); } }; diff --git a/script.coffee b/script.coffee index 20f9f8a16..ae31643ae 100644 --- a/script.coffee +++ b/script.coffee @@ -545,15 +545,11 @@ expandThread = a.textContent = a.textContent.replace 'X Loading...', '-' - # eat everything, then replace with fresh full posts - while (next = a.nextSibling) and not next.clear #br[clear] - $.rm next - br = next - body = $.el 'body', innerHTML: req.responseText - for reply in $$ 'td[id]', body + frag = d.createDocumentFragment() + for reply in $$ '.reply', body for quote in $$ '.quotelink', reply if (href = quote.getAttribute('href')) is quote.hash #add pathname to normal quotes quote.pathname = pathname @@ -562,10 +558,12 @@ expandThread = link = $ '.quotejs', reply link.href = "res/#{thread.firstChild.id}##{reply.id}" link.nextSibling.href = "res/#{thread.firstChild.id}#q#{reply.id}" - tables = $$ 'form[name=delform] table', body - tables.pop() - for table in tables - $.before br, table + $.add frag, reply.parentNode.parentNode.parentNode + # eat everything, then replace with fresh full posts + while (next = a.nextSibling) and not next.clear #br[clear] + $.rm next + br = next + $.before br, frag replyHiding = init: -> From fbfdefa3e02369282cf170341b5afd0ffc11d5b8 Mon Sep 17 00:00:00 2001 From: Nicolas Stepien Date: Tue, 13 Dec 2011 17:13:09 +0100 Subject: [PATCH 160/169] Prevent regexp errors with the filter. --- 4chan_x.user.js | 7 ++++++- changelog | 2 ++ script.coffee | 5 ++++- 3 files changed, 12 insertions(+), 2 deletions(-) diff --git a/4chan_x.user.js b/4chan_x.user.js index c6070a4f5..54fa135b6 100644 --- a/4chan_x.user.js +++ b/4chan_x.user.js @@ -537,7 +537,12 @@ for (_i = 0, _len = m.length; _i < _len; _i++) { filter = m[_i]; f = filter.match(/^\/(.+)\/(\w*)$/); - this.regexps[key].push(RegExp(f[1], f[2])); + try { + this.regexps[key].push(RegExp(f[1], f[2])); + } catch (e) { + alert(e.message); + alert(e); + } } this.callbacks.push(this[key]); } diff --git a/changelog b/changelog index f46ce8b9c..68fe864f7 100644 --- a/changelog +++ b/changelog @@ -1,4 +1,6 @@ master +- mayhem + prevent regexp errors with the filter 2.32.3 - mayhem diff --git a/script.coffee b/script.coffee index ae31643ae..2c202ca55 100644 --- a/script.coffee +++ b/script.coffee @@ -401,7 +401,10 @@ filter = @regexps[key] = [] for filter in m f = filter.match /^\/(.+)\/(\w*)$/ - @regexps[key].push RegExp f[1], f[2] + try + @regexps[key].push RegExp f[1], f[2] + catch e + alert e.message #only execute what's filterable @callbacks.push @[key] From 0a6e01accdb04ac71be0d26d4477abb7efe7a6e1 Mon Sep 17 00:00:00 2001 From: Nicolas Stepien Date: Tue, 13 Dec 2011 20:22:24 +0100 Subject: [PATCH 161/169] Send "If-Modified-Since" header, make use of the 304 status, always fool the cache, change $.ajax. Status Code 304: Not modified By sending the "If-Modified-Since" header we get a proper status code, and no response. This saves bandwidth for both the user and the servers, avoid unnecessary computation, and won't load images and scripts when parsing the response. --- 4chan_x.user.js | 43 ++++++++++++++++++++++++++++++------------- changelog | 1 + script.coffee | 40 ++++++++++++++++++++++++++++++---------- 3 files changed, 61 insertions(+), 23 deletions(-) diff --git a/4chan_x.user.js b/4chan_x.user.js index 54fa135b6..9030a0db3 100644 --- a/4chan_x.user.js +++ b/4chan_x.user.js @@ -326,13 +326,13 @@ $.add(d.head, script); return $.rm(script); }, - ajax: function(url, cb, type) { + ajax: function(url, cb, type, event) { var r; if (type == null) type = 'get'; + if (event == null) event = 'onload'; r = new XMLHttpRequest(); - r.onload = cb; + r[event] = cb; r.open(type, url, true); - r.send(); return r; }, cache: function(url, cb) { @@ -354,6 +354,7 @@ } return _results; })); + req.send(); req.callbacks = [cb]; return $.cache.requests[url] = req; } @@ -541,7 +542,6 @@ this.regexps[key].push(RegExp(f[1], f[2])); } catch (e) { alert(e.message); - alert(e); } } this.callbacks.push(this[key]); @@ -1988,7 +1988,8 @@ $.on(input, 'click', updater.update); } } - return $.add(d.body, dialog); + $.add(d.body, dialog); + return updater.lastModified = 0; }, cb: { verbose: function() { @@ -2029,6 +2030,21 @@ return; } updater.timer.textContent = '-' + conf['Interval']; + /* + Status Code 304: Not modified + By sending the `If-Modified-Since` header we get a proper status code, and no response. + This saves bandwidth for both the user and the servers, avoid unnecessary computation, + and won't load images and scripts when parsing the response. + */ + updater.lastModified = this.getResponseHeader('Last-Modified'); + console.log(this.status); + if (this.status === 304) { + if (conf['Verbose']) { + updater.count.textContent = '+0'; + updater.count.className = null; + } + return; + } body = $.el('body', { innerHTML: this.responseText }); @@ -2050,7 +2066,7 @@ if (conf['Verbose']) { updater.count.textContent = '+' + newPosts; if (newPosts === 0) { - updater.count.className = ''; + updater.count.className = null; } else { updater.count.className = 'new'; } @@ -2077,12 +2093,13 @@ return updater.update(); }, update: function() { - var cb, url, _ref; + var url, _ref; updater.timer.textContent = 0; if ((_ref = updater.request) != null) _ref.abort(); - url = engine !== 'presto' ? location.pathname : location.pathname + '?' + Date.now(); - cb = updater.cb.update; - return updater.request = $.ajax(url, cb); + url = location.pathname + '?' + Date.now(); + updater.request = $.ajax(url, updater.cb.update); + updater.request.setRequestHeader('If-Modified-Since', updater.lastModified); + return updater.request.send(); } }; @@ -2980,12 +2997,12 @@ thumb = this.previousSibling; imgExpand.contract(thumb); if (engine === 'webkit') { - req = $.ajax(this.src, null, 'head'); - return req.onreadystatechange = function() { + req = $.ajax(this.src, (function() { if (this.status !== 404) { return setTimeout(imgExpand.retry, 10000, thumb); } - }; + }), 'head', 'onreadystatechange'); + return req.send(); } else if (!g.dead) { return setTimeout(imgExpand.retry, 10000, thumb); } diff --git a/changelog b/changelog index 68fe864f7..40c8e27ae 100644 --- a/changelog +++ b/changelog @@ -1,5 +1,6 @@ master - mayhem + thread updater network optimization prevent regexp errors with the filter 2.32.3 diff --git a/script.coffee b/script.coffee index 2c202ca55..7139f1161 100644 --- a/script.coffee +++ b/script.coffee @@ -231,11 +231,10 @@ $.extend $, textContent: "(#{code})()" $.add d.head, script $.rm script - ajax: (url, cb, type='get') -> + ajax: (url, cb, type='get', event='onload') -> r = new XMLHttpRequest() - r.onload = cb + r[event] = cb r.open type, url, true - r.send() r cache: (url, cb) -> if req = $.cache.requests[url] @@ -245,6 +244,7 @@ $.extend $, req.callbacks.push cb else req = $.ajax url, (-> cb.call @ for cb in @callbacks) + req.send() req.callbacks = [cb] $.cache.requests[url] = req cb: @@ -1587,6 +1587,8 @@ updater = $.add d.body, dialog + updater.lastModified = 0 + cb: verbose: -> if conf['Verbose'] @@ -1619,8 +1621,23 @@ updater = updater.timer.textContent = '-' + conf['Interval'] + ### + Status Code 304: Not modified + By sending the `If-Modified-Since` header we get a proper status code, and no response. + This saves bandwidth for both the user and the servers, avoid unnecessary computation, + and won't load images and scripts when parsing the response. + ### + updater.lastModified = @getResponseHeader('Last-Modified') + console.log @status + if @status is 304 + if conf['Verbose'] + updater.count.textContent = '+0' + updater.count.className = null + return + body = $.el 'body', innerHTML: @responseText + #this only works on Chrome because of cross origin policy if $('title', body).textContent is '4chan - Banned' updater.count.textContent = 'banned' @@ -1639,7 +1656,7 @@ updater = if conf['Verbose'] updater.count.textContent = '+' + newPosts if newPosts is 0 - updater.count.className = '' + updater.count.className = null else updater.count.className = 'new' @@ -1666,10 +1683,11 @@ updater = update: -> updater.timer.textContent = 0 updater.request?.abort() - #Opera needs to fool its cache - url = if engine isnt 'presto' then location.pathname else location.pathname + '?' + Date.now() - cb = updater.cb.update - updater.request = $.ajax url, cb + #fool the cache + url = location.pathname + '?' + Date.now() + updater.request = $.ajax url, updater.cb.update + updater.request.setRequestHeader 'If-Modified-Since', updater.lastModified + updater.request.send() watcher = init: -> @@ -2302,8 +2320,10 @@ imgExpand = imgExpand.contract thumb #navigator.online is not x-browser/os yet if engine is 'webkit' - req = $.ajax @src, null, 'head' - req.onreadystatechange = -> setTimeout imgExpand.retry, 10000, thumb if @status isnt 404 + req = $.ajax @src, (-> + setTimeout imgExpand.retry, 10000, thumb if @status isnt 404 + ), 'head', 'onreadystatechange' + req.send() #Firefox returns a status code of 0 because of the same origin policy #Oprah doesn't send any request else unless g.dead From 1de48d21c79bae2dd240f67c6d6a8254bf08a189 Mon Sep 17 00:00:00 2001 From: Nicolas Stepien Date: Tue, 13 Dec 2011 20:36:35 +0100 Subject: [PATCH 162/169] Remove log. --- 4chan_x.user.js | 1 - script.coffee | 1 - 2 files changed, 2 deletions(-) diff --git a/4chan_x.user.js b/4chan_x.user.js index 9030a0db3..cdb41cb95 100644 --- a/4chan_x.user.js +++ b/4chan_x.user.js @@ -2037,7 +2037,6 @@ and won't load images and scripts when parsing the response. */ updater.lastModified = this.getResponseHeader('Last-Modified'); - console.log(this.status); if (this.status === 304) { if (conf['Verbose']) { updater.count.textContent = '+0'; diff --git a/script.coffee b/script.coffee index 7139f1161..7519c0dcc 100644 --- a/script.coffee +++ b/script.coffee @@ -1628,7 +1628,6 @@ updater = and won't load images and scripts when parsing the response. ### updater.lastModified = @getResponseHeader('Last-Modified') - console.log @status if @status is 304 if conf['Verbose'] updater.count.textContent = '+0' From 0bd0f50e88d6a7ac5c224a407bba11e6ac7fa566 Mon Sep 17 00:00:00 2001 From: Nicolas Stepien Date: Tue, 13 Dec 2011 20:39:56 +0100 Subject: [PATCH 163/169] Release 2.23.4 --- 4chan_x.user.js | 6 +++--- Cakefile | 2 +- changelog | 4 +++- latest.js | 2 +- script.coffee | 2 +- 5 files changed, 9 insertions(+), 7 deletions(-) diff --git a/4chan_x.user.js b/4chan_x.user.js index cdb41cb95..655d3b7f1 100644 --- a/4chan_x.user.js +++ b/4chan_x.user.js @@ -1,6 +1,6 @@ // ==UserScript== // @name 4chan x -// @version 2.23.3 +// @version 2.23.4 // @namespace aeosynth // @description Adds various features. // @copyright 2009-2011 James Campos @@ -16,7 +16,7 @@ * * Copyright (c) 2009-2011 James Campos * http://mayhemydg.github.com/4chan-x/ - * 4chan x 2.23.3 + * 4chan x 2.23.4 * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation @@ -208,7 +208,7 @@ NAMESPACE = '4chan_x.'; - VERSION = '2.23.3'; + VERSION = '2.23.4'; SECOND = 1000; diff --git a/Cakefile b/Cakefile index ffc1406e1..536a3b7e5 100644 --- a/Cakefile +++ b/Cakefile @@ -2,7 +2,7 @@ {exec} = require 'child_process' fs = require 'fs' -VERSION = '2.23.3' +VERSION = '2.23.4' HEADER = """ // ==UserScript== diff --git a/changelog b/changelog index 40c8e27ae..ea7330a4a 100644 --- a/changelog +++ b/changelog @@ -1,9 +1,11 @@ master + +2.23.4 - mayhem thread updater network optimization prevent regexp errors with the filter -2.32.3 +2.23.3 - mayhem fix 2.32.2 regression duplicating new posts in rare cases diff --git a/latest.js b/latest.js index b5d5cb4ba..2815a9c43 100644 --- a/latest.js +++ b/latest.js @@ -1 +1 @@ -postMessage({version:'2.23.3'},'*'); +postMessage({version:'2.23.4'},'*'); diff --git a/script.coffee b/script.coffee index 7519c0dcc..e71ca540e 100644 --- a/script.coffee +++ b/script.coffee @@ -124,7 +124,7 @@ conf = {} ) null, config NAMESPACE = '4chan_x.' -VERSION = '2.23.3' +VERSION = '2.23.4' SECOND = 1000 MINUTE = 60*SECOND HOUR = 60*MINUTE From c52b71742f0b460e83d447d34f2e47a284623601 Mon Sep 17 00:00:00 2001 From: James Campos Date: Tue, 13 Dec 2011 15:52:46 -0800 Subject: [PATCH 164/169] rm pig disgusting substring --- 4chan_x.user.js | 4 ++-- script.coffee | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/4chan_x.user.js b/4chan_x.user.js index 655d3b7f1..c8cf95916 100644 --- a/4chan_x.user.js +++ b/4chan_x.user.js @@ -2175,7 +2175,7 @@ }, x: function() { var board, id, _, _ref; - _ref = this.nextElementSibling.getAttribute('href').substring(1).split('/'), board = _ref[0], _ = _ref[1], id = _ref[2]; + _ref = this.nextElementSibling.getAttribute('href').slice(1).split('/'), board = _ref[0], _ = _ref[1], id = _ref[2]; return watcher.unwatch(board, id); } }, @@ -3040,7 +3040,7 @@ Main = { init: function() { var cutoff, hiddenThreads, id, now, pathname, temp, timestamp, update, _ref; - pathname = location.pathname.substring(1).split('/'); + pathname = location.pathname.slice(1).split('/'); g.BOARD = pathname[0], temp = pathname[1]; if (temp === 'res') { g.REPLY = temp; diff --git a/script.coffee b/script.coffee index e71ca540e..b40dcf2dd 100644 --- a/script.coffee +++ b/script.coffee @@ -1746,7 +1746,7 @@ watcher = watcher.toggle @parentNode x: -> [board, _, id] = @nextElementSibling - .getAttribute('href').substring(1).split('/') + .getAttribute('href')[1..].split('/') watcher.unwatch board, id toggle: (thread) -> @@ -2355,7 +2355,7 @@ imgExpand = Main = init: -> - pathname = location.pathname.substring(1).split('/') + pathname = location.pathname[1..].split('/') [g.BOARD, temp] = pathname if temp is 'res' g.REPLY = temp From bf0326f38cb098f69818561d6fffc1cd06a28d69 Mon Sep 17 00:00:00 2001 From: James Campos Date: Tue, 13 Dec 2011 17:57:25 -0800 Subject: [PATCH 165/169] move ajax code into library --- 4chan_x.user.js | 37 ++++++++++++++++++++++++------------- script.coffee | 20 +++++++++++--------- 2 files changed, 35 insertions(+), 22 deletions(-) diff --git a/4chan_x.user.js b/4chan_x.user.js index c8cf95916..37611a6b4 100644 --- a/4chan_x.user.js +++ b/4chan_x.user.js @@ -326,13 +326,21 @@ $.add(d.head, script); return $.rm(script); }, - ajax: function(url, cb, type, event) { - var r; - if (type == null) type = 'get'; - if (event == null) event = 'onload'; + ajax: function(url, cb, opts) { + var key, r, val, _ref; + opts.type || (opts.type = 'get'); + opts.event || (opts.event = 'onload'); r = new XMLHttpRequest(); - r[event] = cb; - r.open(type, url, true); + if (opts.headers) { + _ref = opts.headers; + for (key in _ref) { + val = _ref[key]; + r.setRequestHeader(key, val); + } + } + r[opts.event] = cb; + r.open(opts.type, url, true); + r.send(); return r; }, cache: function(url, cb) { @@ -354,7 +362,6 @@ } return _results; })); - req.send(); req.callbacks = [cb]; return $.cache.requests[url] = req; } @@ -2096,9 +2103,11 @@ updater.timer.textContent = 0; if ((_ref = updater.request) != null) _ref.abort(); url = location.pathname + '?' + Date.now(); - updater.request = $.ajax(url, updater.cb.update); - updater.request.setRequestHeader('If-Modified-Since', updater.lastModified); - return updater.request.send(); + return updater.request = $.ajax(url, updater.cb.update, { + headers: { + 'If-Modified-Since': updater.lastModified + } + }); } }; @@ -2996,12 +3005,14 @@ thumb = this.previousSibling; imgExpand.contract(thumb); if (engine === 'webkit') { - req = $.ajax(this.src, (function() { + return req = $.ajax(this.src, (function() { if (this.status !== 404) { return setTimeout(imgExpand.retry, 10000, thumb); } - }), 'head', 'onreadystatechange'); - return req.send(); + }), { + type: 'head', + event: 'onreadystatechange' + }); } else if (!g.dead) { return setTimeout(imgExpand.retry, 10000, thumb); } diff --git a/script.coffee b/script.coffee index b40dcf2dd..a7de9d731 100644 --- a/script.coffee +++ b/script.coffee @@ -231,10 +231,16 @@ $.extend $, textContent: "(#{code})()" $.add d.head, script $.rm script - ajax: (url, cb, type='get', event='onload') -> + ajax: (url, cb, opts) -> + opts.type or= 'get' + opts.event or= 'onload' r = new XMLHttpRequest() - r[event] = cb - r.open type, url, true + if opts.headers + for key, val of opts.headers + r.setRequestHeader key, val + r[opts.event] = cb + r.open opts.type, url, true + r.send() r cache: (url, cb) -> if req = $.cache.requests[url] @@ -244,7 +250,6 @@ $.extend $, req.callbacks.push cb else req = $.ajax url, (-> cb.call @ for cb in @callbacks) - req.send() req.callbacks = [cb] $.cache.requests[url] = req cb: @@ -1684,9 +1689,7 @@ updater = updater.request?.abort() #fool the cache url = location.pathname + '?' + Date.now() - updater.request = $.ajax url, updater.cb.update - updater.request.setRequestHeader 'If-Modified-Since', updater.lastModified - updater.request.send() + updater.request = $.ajax url, updater.cb.update, headers: 'If-Modified-Since': updater.lastModified watcher = init: -> @@ -2321,8 +2324,7 @@ imgExpand = if engine is 'webkit' req = $.ajax @src, (-> setTimeout imgExpand.retry, 10000, thumb if @status isnt 404 - ), 'head', 'onreadystatechange' - req.send() + ), type: 'head', event: 'onreadystatechange' #Firefox returns a status code of 0 because of the same origin policy #Oprah doesn't send any request else unless g.dead From 5e464b288f21be0d973d50c9275f1150995301a2 Mon Sep 17 00:00:00 2001 From: James Campos Date: Tue, 13 Dec 2011 22:08:22 -0800 Subject: [PATCH 166/169] ajax tweaks --- 4chan_x.user.js | 21 ++++++++++----------- script.coffee | 16 ++++++++-------- 2 files changed, 18 insertions(+), 19 deletions(-) diff --git a/4chan_x.user.js b/4chan_x.user.js index 37611a6b4..90d2050e5 100644 --- a/4chan_x.user.js +++ b/4chan_x.user.js @@ -327,19 +327,18 @@ return $.rm(script); }, ajax: function(url, cb, opts) { - var key, r, val, _ref; - opts.type || (opts.type = 'get'); - opts.event || (opts.event = 'onload'); + var event, headers, key, r, type, val; + if (opts == null) opts = {}; + type = opts.type, event = opts.event, headers = opts.headers; + type || (type = 'get'); + event || (event = 'onload'); r = new XMLHttpRequest(); - if (opts.headers) { - _ref = opts.headers; - for (key in _ref) { - val = _ref[key]; - r.setRequestHeader(key, val); - } + for (key in headers) { + val = headers[key]; + r.setRequestHeader(key, val); } - r[opts.event] = cb; - r.open(opts.type, url, true); + r[event] = cb; + r.open(type, url, true); r.send(); return r; }, diff --git a/script.coffee b/script.coffee index a7de9d731..a497dbe81 100644 --- a/script.coffee +++ b/script.coffee @@ -231,15 +231,15 @@ $.extend $, textContent: "(#{code})()" $.add d.head, script $.rm script - ajax: (url, cb, opts) -> - opts.type or= 'get' - opts.event or= 'onload' + ajax: (url, cb, opts={}) -> + {type, event, headers} = opts + type or= 'get' + event or= 'onload' r = new XMLHttpRequest() - if opts.headers - for key, val of opts.headers - r.setRequestHeader key, val - r[opts.event] = cb - r.open opts.type, url, true + for key, val of headers + r.setRequestHeader key, val + r[event] = cb + r.open type, url, true r.send() r cache: (url, cb) -> From 6c7d1cb4bd145ef5931d900b2291f50911a7cc99 Mon Sep 17 00:00:00 2001 From: Nicolas Stepien Date: Wed, 14 Dec 2011 09:55:32 +0100 Subject: [PATCH 167/169] Fix. You open the request, then set the headers. --- 4chan_x.user.js | 2 +- script.coffee | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/4chan_x.user.js b/4chan_x.user.js index 90d2050e5..5bccf0d6a 100644 --- a/4chan_x.user.js +++ b/4chan_x.user.js @@ -333,12 +333,12 @@ type || (type = 'get'); event || (event = 'onload'); r = new XMLHttpRequest(); + r.open(type, url, true); for (key in headers) { val = headers[key]; r.setRequestHeader(key, val); } r[event] = cb; - r.open(type, url, true); r.send(); return r; }, diff --git a/script.coffee b/script.coffee index a497dbe81..0c3e4e913 100644 --- a/script.coffee +++ b/script.coffee @@ -236,10 +236,10 @@ $.extend $, type or= 'get' event or= 'onload' r = new XMLHttpRequest() + r.open type, url, true for key, val of headers r.setRequestHeader key, val r[event] = cb - r.open type, url, true r.send() r cache: (url, cb) -> From f07da722c73a1ae0bb0bbac290e2ec0e555e5241 Mon Sep 17 00:00:00 2001 From: Nicolas Stepien Date: Wed, 14 Dec 2011 10:01:52 +0100 Subject: [PATCH 168/169] Let me tab between the keybind options. --- 4chan_x.user.js | 1 + script.coffee | 1 + 2 files changed, 2 insertions(+) diff --git a/4chan_x.user.js b/4chan_x.user.js index 5bccf0d6a..10c373759 100644 --- a/4chan_x.user.js +++ b/4chan_x.user.js @@ -1427,6 +1427,7 @@ return g.hiddenReplies = {}; }, keybind: function(e) { + if (e.keyCode === 9) return; e.preventDefault(); e.stopPropagation(); if ((key = keybinds.keyCode(e)) == null) return; diff --git a/script.coffee b/script.coffee index 0c3e4e913..0b6e4caa5 100644 --- a/script.coffee +++ b/script.coffee @@ -1068,6 +1068,7 @@ options = @textContent = "hidden: 0" g.hiddenReplies = {} keybind: (e) -> + return if e.keyCode is 9 e.preventDefault() e.stopPropagation() return unless (key = keybinds.keyCode e)? From 0e7d56b0026c9d1b7181de491749a45666a475f4 Mon Sep 17 00:00:00 2001 From: Nicolas Stepien Date: Wed, 14 Dec 2011 11:01:17 +0100 Subject: [PATCH 169/169] Increase the retry timeout value by 10 seconds at each retry, up to 120 seconds. Reset on succesful connection. --- 4chan_x.user.js | 9 ++++++--- script.coffee | 9 ++++++--- 2 files changed, 12 insertions(+), 6 deletions(-) diff --git a/4chan_x.user.js b/4chan_x.user.js index 10c373759..cbfc98cfb 100644 --- a/4chan_x.user.js +++ b/4chan_x.user.js @@ -1996,6 +1996,7 @@ } } $.add(d.body, dialog); + updater.retryCoef = 10; return updater.lastModified = 0; }, cb: { @@ -2036,6 +2037,7 @@ Favicon.update(); return; } + updater.retryCoef = 10; updater.timer.textContent = '-' + conf['Interval']; /* Status Code 304: Not modified @@ -2055,7 +2057,7 @@ innerHTML: this.responseText }); if ($('title', body).textContent === '4chan - Banned') { - updater.count.textContent = 'banned'; + updater.count.textContent = 'Banned'; updater.count.className = 'error'; return; } @@ -2087,14 +2089,15 @@ n = 1 + Number(updater.timer.textContent); if (n === 0) { return updater.update(); - } else if (n === 10) { + } else if (n === updater.retryCoef) { + updater.retryCoef += 10 * (updater.retryCoef < 120); return updater.retry(); } else { return updater.timer.textContent = n; } }, retry: function() { - updater.count.textContent = 'retry'; + updater.count.textContent = 'Retry'; updater.count.className = ''; return updater.update(); }, diff --git a/script.coffee b/script.coffee index 0b6e4caa5..b58abfb83 100644 --- a/script.coffee +++ b/script.coffee @@ -1593,6 +1593,7 @@ updater = $.add d.body, dialog + updater.retryCoef = 10 updater.lastModified = 0 cb: @@ -1625,6 +1626,7 @@ updater = Favicon.update() return + updater.retryCoef = 10 updater.timer.textContent = '-' + conf['Interval'] ### @@ -1645,7 +1647,7 @@ updater = #this only works on Chrome because of cross origin policy if $('title', body).textContent is '4chan - Banned' - updater.count.textContent = 'banned' + updater.count.textContent = 'Banned' updater.count.className = 'error' return @@ -1675,13 +1677,14 @@ updater = if n is 0 updater.update() - else if n is 10 + else if n is updater.retryCoef + updater.retryCoef += 10 * (updater.retryCoef < 120) updater.retry() else updater.timer.textContent = n retry: -> - updater.count.textContent = 'retry' + updater.count.textContent = 'Retry' updater.count.className = '' updater.update()
        ActionsKeybinds
        Close Options or QR