explicit global-ness

This commit is contained in:
James Campos 2010-11-11 05:50:07 -08:00
parent 65f1fe3277
commit aaa06e292d
2 changed files with 292 additions and 305 deletions

View File

@ -120,6 +120,8 @@ AEOS =
GM_setValue "#{id}Top", div.style.top GM_setValue "#{id}Top", div.style.top
d = document d = document
g = {} #globals
$ = (selector, root) -> $ = (selector, root) ->
root or= d.body root or= d.body
root.querySelector selector root.querySelector selector
@ -176,39 +178,6 @@ x = (path, root) ->
d.evaluate(path, root, null, XPathResult.ANY_UNORDERED_NODE_TYPE, null). d.evaluate(path, root, null, XPathResult.ANY_UNORDERED_NODE_TYPE, null).
singleNodeValue singleNodeValue
#globals
AEOS.init() #GM wrappers
iframeLoop = false
xhrs = []
r = null
callbacks = []
hiddenThreads = JSON.parse(GM_getValue("hiddenThreads/#{BOARD}/", '[]'))
hiddenReplies = JSON.parse(GM_getValue("hiddenReplies/#{BOARD}/", '[]'))
#godammit moot
head = $('head', d)
unless favicon = $('link[rel="shortcut icon"]', head)#/f/
favicon = n 'link',
rel: 'shortcut icon'
href: 'http://static.4chan.org/image/favicon.ico'
addTo head, favicon
favNormal = favicon.href
favEmpty = 'data:image/gif;base64,R0lGODlhEAAQAJEAAAAAAP///9vb2////yH5BAEAAAMALAAAAAAQABAAAAIvnI+pq+D9DBAUoFkPFnbs7lFZKIJOJJ3MyraoB14jFpOcVMpzrnF3OKlZYsMWowAAOw=='
sauceVarieties = [
'http://regex.info/exif.cgi?url='
'http://iqdb.org/?url='
'http://saucenao.com/search.php?db=999&url='
'http://tineye.com/search?url='
].join '\n'
pathname = location.pathname.substring(1).split('/')
[BOARD, magic] = pathname
if magic is 'res'
REPLY = magic
THREAD_ID = pathname[2]
else
PAGENUM = parseInt(magic) || 0
watched = JSON.parse(GM_getValue('watched', '{}'))
#funks #funks
autohide = -> autohide = ->
qr = $ '#qr' qr = $ '#qr'
@ -222,7 +191,7 @@ autohide = ->
autoWatch = -> autoWatch = ->
#TODO look for subject #TODO look for subject
autoText = $('textarea', this).value.slice(0, 25) autoText = $('textarea', this).value.slice(0, 25)
GM_setValue('autoText', "/#{BOARD}/ - #{autoText}") GM_setValue('autoText', "/#{g.BOARD}/ - #{autoText}")
close = -> close = ->
div = this.parentNode.parentNode div = this.parentNode.parentNode
@ -231,11 +200,11 @@ close = ->
clearHidden = -> clearHidden = ->
#'hidden' might be misleading; it's the number of IDs we're *looking* for, #'hidden' might be misleading; it's the number of IDs we're *looking* for,
# not the number of posts actually hidden on the page. # not the number of posts actually hidden on the page.
GM_deleteValue("hiddenReplies/#{BOARD}/") GM_deleteValue("hiddenReplies/#{g.BOARD}/")
GM_deleteValue("hiddenThreads/#{BOARD}/") GM_deleteValue("hiddenThreads/#{g.BOARD}/")
@value = "hidden: 0" @value = "hidden: 0"
hiddenReplies = [] g.hiddenReplies = []
hiddenThreads = [] g.hiddenThreads = []
cooldown = -> cooldown = ->
submit = $ '#qr input[type=submit]' submit = $ '#qr input[type=submit]'
@ -264,7 +233,7 @@ expandComment = (e) ->
onloadComment(this.responseText, a, href) onloadComment(this.responseText, a, href)
r.open('GET', href, true) r.open('GET', href, true)
r.send() r.send()
xhrs.push { g.xhrs.push {
r: r, r: r,
id: href.match(/\d+/)[0] id: href.match(/\d+/)[0]
} }
@ -283,7 +252,7 @@ expandThread = ->
return return
span.textContent = span.textContent.replace '+', 'X Loading...' span.textContent = span.textContent.replace '+', 'X Loading...'
#load cache #load cache
for xhr in xhrs for xhr in g.xhrs
if xhr.id == id if xhr.id == id
#why can't we just xhr.r.onload()? #why can't we just xhr.r.onload()?
onloadThread xhr.r.responseText, span onloadThread xhr.r.responseText, span
@ -294,7 +263,7 @@ expandThread = ->
onloadThread this.responseText, span onloadThread this.responseText, span
r.open 'GET', "res/#{id}", true r.open 'GET', "res/#{id}", true
r.send() r.send()
xhrs.push { g.xhrs.push {
r: r, r: r,
id: id id: id
} }
@ -317,11 +286,11 @@ formSubmit = (e) ->
hideReply = (reply) -> hideReply = (reply) ->
if p = this.parentNode if p = this.parentNode
reply = p.nextSibling reply = p.nextSibling
hiddenReplies.push { g.hiddenReplies.push {
id: reply.id id: reply.id
timestamp: getTime() timestamp: getTime()
} }
GM_setValue("hiddenReplies/#{BOARD}/", JSON.stringify(hiddenReplies)) GM_setValue("hiddenReplies/#{g.BOARD}/", JSON.stringify(g.hiddenReplies))
name = $('span.commentpostername', reply).textContent name = $('span.commentpostername', reply).textContent
trip = $('span.postertrip', reply)?.textContent or '' trip = $('span.postertrip', reply)?.textContent or ''
table = x 'ancestor::table', reply table = x 'ancestor::table', reply
@ -338,11 +307,11 @@ hideReply = (reply) ->
hideThread = (div) -> hideThread = (div) ->
if p = @parentNode if p = @parentNode
div = p div = p
hiddenThreads.push { g.hiddenThreads.push {
id: div.id id: div.id
timestamp: getTime() timestamp: getTime()
} }
GM_setValue("hiddenThreads/#{BOARD}/", JSON.stringify(hiddenThreads)) GM_setValue("hiddenThreads/#{g.BOARD}/", JSON.stringify(g.hiddenThreads))
hide div hide div
if getConfig 'Show Stubs' if getConfig 'Show Stubs'
if span = $ '.omittedposts', div if span = $ '.omittedposts', div
@ -360,7 +329,7 @@ hideThread = (div) ->
inBefore div, a inBefore div, a
iframeLoad = -> iframeLoad = ->
if iframeLoop = !iframeLoop if g.iframe = !g.iframe
return return
$('iframe').src = 'about:blank' $('iframe').src = 'about:blank'
qr = $ '#qr' qr = $ '#qr'
@ -370,7 +339,7 @@ iframeLoad = ->
className: 'error' className: 'error'
addTo qr, span addTo qr, span
$('input[title=autohide]:checked', qr)?.click() $('input[title=autohide]:checked', qr)?.click()
else if REPLY and getConfig 'Persistent QR' else if g.REPLY and getConfig 'Persistent QR'
$('textarea', qr).value = '' $('textarea', qr).value = ''
$('input[name=recaptcha_response_field]', qr).value = '' $('input[name=recaptcha_response_field]', qr).value = ''
submit = $ 'input[type=submit]', qr submit = $ 'input[type=submit]', qr
@ -388,7 +357,7 @@ iframeLoad = ->
nodeInserted = (e) -> nodeInserted = (e) ->
target = e.target target = e.target
if target.nodeName is 'TABLE' if target.nodeName is 'TABLE'
for callback in callbacks for callback in g.callbacks
callback target callback target
else if target.id is 'recaptcha_challenge_field' and qr = $ '#qr' else if target.id is 'recaptcha_challenge_field' and qr = $ '#qr'
$('#recaptcha_image img', qr).src = "http://www.google.com/recaptcha/api/image?c=" + target.value $('#recaptcha_image img', qr).src = "http://www.google.com/recaptcha/api/image?c=" + target.value
@ -428,20 +397,20 @@ options = ->
remove div remove div
else else
div = AEOS.makeDialog 'options', 'center' div = AEOS.makeDialog 'options', 'center'
hiddenNum = hiddenReplies.length + hiddenThreads.length hiddenNum = g.hiddenReplies.length + g.hiddenThreads.length
html = '<div class="move">Options <a class=pointer>X</a></div><div>' html = '<div class="move">Options <a class=pointer>X</a></div><div>'
for option, value of config for option, value of config
description = value[1] description = value[1]
checked = if getConfig option then "checked" else "" checked = if getConfig option then "checked" else ""
html += "<label title=\"#{description}\">#{option}<input #{checked} name=\"#{option}\" type=\"checkbox\"></label><br>" html += "<label title=\"#{description}\">#{option}<input #{checked} name=\"#{option}\" type=\"checkbox\"></label><br>"
html += "<div><a class=sauce>Sauce Varieties</a></div>" html += "<div><a class=sauce>Flavors</a></div>"
html += "<div><textarea cols=50 rows=4 style=\"display: none;\"></textarea></div>" html += "<div><textarea cols=50 rows=4 style=\"display: none;\"></textarea></div>"
html += "<input type=\"button\" value=\"hidden: #{hiddenNum}\"><br>" html += "<input type=\"button\" value=\"hidden: #{hiddenNum}\"><br>"
div.innerHTML = html div.innerHTML = html
$('div.move', div).addEventListener 'mousedown', AEOS.move, true $('div.move', div).addEventListener 'mousedown', AEOS.move, true
$('a.pointer', div).addEventListener 'click', optionsClose, true $('a.pointer', div).addEventListener 'click', optionsClose, true
$('a.sauce', div).addEventListener 'click', editSauce, true $('a.sauce', div).addEventListener 'click', editSauce, true
$('textarea', div).value = GM_getValue 'saucePrefix', sauceVarieties $('textarea', div).value = GM_getValue 'flavors', g.flavors
$('input[type="button"]', div).addEventListener 'click', clearHidden, true $('input[type="button"]', div).addEventListener 'click', clearHidden, true
addTo d.body, div addTo d.body, div
@ -450,7 +419,7 @@ optionsClose = ->
inputs = $$ 'input', div inputs = $$ 'input', div
for input in inputs for input in inputs
GM_setValue(input.name, input.checked) GM_setValue(input.name, input.checked)
GM_setValue 'saucePrefix', $('textarea', div).value GM_setValue 'flavors', $('textarea', div).value
remove div remove div
parseResponse = (responseText) -> parseResponse = (responseText) ->
@ -489,7 +458,7 @@ quickReply = (e) ->
listener: ['keydown', recaptchaListener] listener: ['keydown', recaptchaListener]
clone.addEventListener 'submit', formSubmit, true clone.addEventListener 'submit', formSubmit, true
clone.target = 'iframe' clone.target = 'iframe'
if not REPLY if not g.REPLY
#figure out which thread we're replying to #figure out which thread we're replying to
xpath = 'preceding::span[@class="postername"][1]/preceding::input[1]' xpath = 'preceding::span[@class="postername"][1]/preceding::input[1]'
input = n 'input', input = n 'input',
@ -528,17 +497,17 @@ recaptchaReload = ->
window.location = 'javascript:Recaptcha.reload()' window.location = 'javascript:Recaptcha.reload()'
redirect = -> redirect = ->
switch BOARD switch g.BOARD
when 'a', 'g', 'lit', 'sci', 'tv' when 'a', 'g', 'lit', 'sci', 'tv'
url = "http://green-oval.net/cgi-board.pl/#{BOARD}/thread/#{THREAD_ID}#p" url = "http://green-oval.net/cgi-board.pl/#{g.BOARD}/thread/#{g.THREAD_ID}#p"
when 'cgl', 'jp', 'm', 'tg' when 'cgl', 'jp', 'm', 'tg'
url = "http://archive.easymodo.net/cgi-board.pl/#{BOARD}/thread/#{THREAD_ID}#p" url = "http://archive.easymodo.net/cgi-board.pl/#{g.BOARD}/thread/#{g.THREAD_ID}#p"
else else
url = "http://boards.4chan.org/#{BOARD}" url = "http://boards.4chan.org/#{g.BOARD}"
location.href = url location.href = url
replyNav = -> replyNav = ->
if REPLY if g.REPLY
window.location = if @textContent is '' then '#navtop' else '#navbot' window.location = if @textContent is '' then '#navtop' else '#navbot'
else else
direction = if @textContent is '' then 'preceding' else 'following' direction = if @textContent is '' then 'preceding' else 'following'
@ -557,16 +526,16 @@ showReply = ->
show(table) show(table)
remove(div) remove(div)
id = $('td.reply, td.replyhl', table).id id = $('td.reply, td.replyhl', table).id
slice(hiddenReplies, id) slice(g.hiddenReplies, id)
GM_setValue("hiddenReplies/#{BOARD}/", JSON.stringify(hiddenReplies)) GM_setValue("hiddenReplies/#{g.BOARD}/", JSON.stringify(g.hiddenReplies))
showThread = -> showThread = ->
div = @nextSibling div = @nextSibling
show div show div
hide this hide this
id = div.id id = div.id
slice hiddenThreads, id slice g.hiddenThreads, id
GM_setValue("hiddenThreads/#{BOARD}/", JSON.stringify(hiddenThreads)) GM_setValue("hiddenThreads/#{g.BOARD}/", JSON.stringify(g.hiddenThreads))
stopPropagation = (e) -> stopPropagation = (e) ->
e.stopPropagation() e.stopPropagation()
@ -588,7 +557,7 @@ threadF = (current) ->
id = $('input[value="delete"]', div).name id = $('input[value="delete"]', div).name
div.id = id div.id = id
#check if we should hide the thread #check if we should hide the thread
for hidden in hiddenThreads for hidden in g.hiddenThreads
if id == hidden.id if id == hidden.id
hideThread(div) hideThread(div)
current = current.nextSibling.nextSibling current = current.nextSibling.nextSibling
@ -598,24 +567,24 @@ threadF = (current) ->
watch = -> watch = ->
id = this.nextSibling.name id = this.nextSibling.name
if this.src[0] is 'd'#data:png if this.src[0] is 'd'#data:png
this.src = favNormal this.src = g.favNormal
text = "/#{BOARD}/ - " + text = "/#{g.BOARD}/ - " +
x('following-sibling::blockquote', this).textContent.slice(0,25) x('following-sibling::blockquote', this).textContent.slice(0,25)
watched[BOARD] or= [] g.watched[g.BOARD] or= []
watched[BOARD].push { g.watched[g.BOARD].push {
id: id, id: id,
text: text text: text
} }
else else
this.src = favEmpty this.src = g.favEmpty
watched[BOARD] = slice(watched[BOARD], id) g.watched[g.BOARD] = slice(g.watched[g.BOARD], id)
GM_setValue('watched', JSON.stringify(watched)) GM_setValue('watched', JSON.stringify(g.watched))
watcherUpdate() watcherUpdate()
watcherUpdate = -> watcherUpdate = ->
div = n 'div' div = n 'div'
for board of watched for board of g.watched
for thread in watched[board] for thread in g.watched[board]
a = n 'a', a = n 'a',
textContent: 'X' textContent: 'X'
className: 'pointer' className: 'pointer'
@ -630,14 +599,40 @@ watcherUpdate = ->
watchX = -> watchX = ->
[board, _, id] = @nextElementSibling. [board, _, id] = @nextElementSibling.
getAttribute('href').substring(1).split('/') getAttribute('href').substring(1).split('/')
watched[board] = slice(watched[board], id) g.watched[board] = slice(g.watched[board], id)
GM_setValue('watched', JSON.stringify(watched)) GM_setValue('watched', JSON.stringify(g.watched))
watcherUpdate() watcherUpdate()
if input = $("input[name=\"#{id}\"]") if input = $("input[name=\"#{id}\"]")
favicon = input.previousSibling favicon = input.previousSibling
favicon.src = favEmpty favicon.src = g.favEmpty
#main #main
AEOS.init()
g.iframe = false
g.xhrs = []
g.callbacks = []
#godammit moot
#/f/ doesn't have a favicon
g.favNormal = $('link[rel="shortcut icon"]', $('head', d))?.href or 'http://static.4chan.org/image/favicon.ico'
g.favEmpty = 'data:image/gif;base64,R0lGODlhEAAQAJEAAAAAAP///9vb2////yH5BAEAAAMALAAAAAAQABAAAAIvnI+pq+D9DBAUoFkPFnbs7lFZKIJOJJ3MyraoB14jFpOcVMpzrnF3OKlZYsMWowAAOw=='
g.flavors = [
'http://regex.info/exif.cgi?url='
'http://iqdb.org/?url='
'http://saucenao.com/search.php?db=999&url='
'http://tineye.com/search?url='
].join '\n'
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) || 0
g.watched = JSON.parse(GM_getValue('watched', '{}'))
g.hiddenThreads = JSON.parse(GM_getValue("hiddenThreads/#{g.BOARD}/", '[]'))
g.hiddenReplies = JSON.parse(GM_getValue("hiddenReplies/#{g.BOARD}/", '[]'))
if location.hostname.split('.')[0] is 'sys' if location.hostname.split('.')[0] is 'sys'
if recaptcha = $ '#recaptcha_response_field' if recaptcha = $ '#recaptcha_response_field'
m recaptcha, listener: ['keydown', recaptchaListener] m recaptcha, listener: ['keydown', recaptchaListener]
@ -650,12 +645,12 @@ if location.hostname.split('.')[0] is 'sys'
[_, thread, id] = html.match(/<!-- thread:(\d+),no:(\d+) -->/) [_, thread, id] = html.match(/<!-- thread:(\d+),no:(\d+) -->/)
if thread is '0' if thread is '0'
board = $('meta', d).content.match(/4chan.org\/(\w+)\//)[1] board = $('meta', d).content.match(/4chan.org\/(\w+)\//)[1]
watched[board] or= [] g.watched[board] or= []
watched[board].push { g.watched[board].push {
id: id, id: id,
text: GM_getValue 'autoText' text: GM_getValue 'autoText'
} }
GM_setValue 'watched', JSON.stringify watched GM_setValue 'watched', JSON.stringify g.watched
return return
lastChecked = GM_getValue('lastChecked', 0) lastChecked = GM_getValue('lastChecked', 0)
@ -663,18 +658,18 @@ now = getTime()
DAY = 24 * 60 * 60 DAY = 24 * 60 * 60
if lastChecked < now - 1*DAY if lastChecked < now - 1*DAY
cutoff = now - 7*DAY cutoff = now - 7*DAY
while hiddenThreads.length while g.hiddenThreads.length
if hiddenThreads[0].timestamp > cutoff if g.hiddenThreads[0].timestamp > cutoff
break break
hiddenThreads.shift() g.hiddenThreads.shift()
while hiddenReplies.length while g.hiddenReplies.length
if hiddenReplies[0].timestamp > cutoff if g.hiddenReplies[0].timestamp > cutoff
break break
hiddenReplies.shift() g.hiddenReplies.shift()
GM_setValue("hiddenThreads/#{BOARD}/", JSON.stringify(hiddenThreads)) GM_setValue("hiddenThreads/#{g.BOARD}/", JSON.stringify(g.hiddenThreads))
GM_setValue("hiddenReplies/#{BOARD}/", JSON.stringify(hiddenReplies)) GM_setValue("hiddenReplies/#{g.BOARD}/", JSON.stringify(g.hiddenReplies))
GM_setValue('lastChecked', now) GM_setValue('lastChecked', now)
GM_addStyle ' GM_addStyle '
@ -756,9 +751,9 @@ recaptcha.addEventListener('keydown', recaptchaListener, true)
#major features #major features
if getConfig 'Sauce' if getConfig 'Sauce'
callbacks.push (root) -> g.callbacks.push (root) ->
spans = $$ 'span.filesize', root spans = $$ 'span.filesize', root
prefixes = GM_getValue('saucePrefix', sauceVarieties).split '\n' prefixes = GM_getValue('flavors', g.flavors).split '\n'
names = prefix.match(/(\w+)\./)[1] for prefix in prefixes names = prefix.match(/(\w+)\./)[1] for prefix in prefixes
for span in spans for span in spans
suffix = $('a', span).href suffix = $('a', span).href
@ -771,7 +766,7 @@ if getConfig 'Sauce'
i++ i++
if getConfig 'Reply Hiding' if getConfig 'Reply Hiding'
callbacks.push (root) -> g.callbacks.push (root) ->
tds = $$('td.doubledash', root) tds = $$('td.doubledash', root)
for td in tds for td in tds
a = n 'a', a = n 'a',
@ -782,7 +777,7 @@ if getConfig 'Reply Hiding'
next = td.nextSibling next = td.nextSibling
id = next.id id = next.id
for obj in hiddenReplies for obj in g.hiddenReplies
if obj.id is id if obj.id is id
hideReply(next) hideReply(next)
@ -793,7 +788,7 @@ if getConfig 'Quick Reply'
hide(iframe) hide(iframe)
addTo d.body, iframe addTo d.body, iframe
callbacks.push (root) -> g.callbacks.push (root) ->
quotes = $$('a.quotejs:not(:first-child)', root) quotes = $$('a.quotejs:not(:first-child)', root)
for quote in quotes for quote in quotes
quote.addEventListener('click', quickReply, true) quote.addEventListener('click', quickReply, true)
@ -803,7 +798,7 @@ if getConfig 'Quick Reply'
if getConfig 'Quick Report' if getConfig 'Quick Report'
callbacks.push (root) -> g.callbacks.push (root) ->
arr = $$('span[id^=no]', root) arr = $$('span[id^=no]', root)
for el in arr for el in arr
a = n 'a', a = n 'a',
@ -822,7 +817,7 @@ if getConfig 'Thread Watcher'
watcherUpdate() watcherUpdate()
#add buttons #add buttons
threads = watched[BOARD] || [] threads = g.watched[g.BOARD] || []
#normal, threading #normal, threading
inputs = $$('form > input[value="delete"], div > input[value="delete"]') inputs = $$('form > input[value="delete"], div > input[value="delete"]')
for input in inputs for input in inputs
@ -830,8 +825,8 @@ if getConfig 'Thread Watcher'
src = (-> src = (->
for thread in threads for thread in threads
if id is thread.id if id is thread.id
return favNormal return g.favNormal
favEmpty g.favEmpty
)() )()
img = n 'img', img = n 'img',
src: src src: src
@ -840,7 +835,7 @@ if getConfig 'Thread Watcher'
inBefore input, img inBefore input, img
if getConfig 'Anonymize' if getConfig 'Anonymize'
callbacks.push (root) -> g.callbacks.push (root) ->
names = $$('span.postername, span.commentpostername', root) names = $$('span.postername, span.commentpostername', root)
for name in names for name in names
name.innerHTML = 'Anonymous' name.innerHTML = 'Anonymous'
@ -852,7 +847,7 @@ if getConfig 'Anonymize'
remove(trip) remove(trip)
if getConfig 'Reply Navigation' if getConfig 'Reply Navigation'
callbacks.push (root) -> g.callbacks.push (root) ->
arr = $$('span[id^=norep]', root) arr = $$('span[id^=norep]', root)
for el in arr for el in arr
span = n 'span' span = n 'span'
@ -867,7 +862,7 @@ if getConfig 'Reply Navigation'
addTo span, tn(' '), up, tn(' '), down addTo span, tn(' '), up, tn(' '), down
inAfter el, span inAfter el, span
if REPLY if g.REPLY
if getConfig('Quick Reply') and getConfig 'Persistent QR' if getConfig('Quick Reply') and getConfig 'Persistent QR'
quickReply() quickReply()
$('#qr input[title=autohide]').click() $('#qr input[title=autohide]').click()
@ -875,7 +870,7 @@ if REPLY
unless text = $('span.filetitle').textContent unless text = $('span.filetitle').textContent
text = $('blockquote').textContent text = $('blockquote').textContent
if text if text
d.title = "/#{BOARD}/ - #{text}" d.title = "/#{g.BOARD}/ - #{text}"
else else
if getConfig 'Thread Hiding' if getConfig 'Thread Hiding'
@ -898,9 +893,9 @@ else
if i isnt 0 if i isnt 0
textContent = '' textContent = ''
href = "##{i}" href = "##{i}"
else if PAGENUM isnt 0 else if g.PAGENUM isnt 0
textContent = '' textContent = ''
href = "#{PAGENUM - 1}" href = "#{g.PAGENUM - 1}"
else else
textContent = '' textContent = ''
href = "#navtop" href = "#navtop"
@ -918,7 +913,7 @@ else
className: 'pointer' className: 'pointer'
if i1 == l1 if i1 == l1
down.textContent = '' down.textContent = ''
down.href = "#{PAGENUM + 1}#1" down.href = "#{g.PAGENUM + 1}#1"
else else
down.textContent = '' down.textContent = ''
down.href = "##{i1}" down.href = "##{i1}"
@ -942,5 +937,5 @@ else
for a in as for a in as
a.addEventListener('click', expandComment, true) a.addEventListener('click', expandComment, true)
callback() for callback in callbacks callback() for callback in g.callbacks
d.body.addEventListener('DOMNodeInserted', nodeInserted, true) d.body.addEventListener('DOMNodeInserted', nodeInserted, true)

View File

@ -1,5 +1,5 @@
(function() { (function() {
var $, $$, AEOS, BOARD, DAY, PAGENUM, REPLY, THREAD_ID, _, _i, _len, _ref, a, addTo, arr, as, autoWatch, autohide, b, board, callback, callbacks, clearHidden, close, config, cooldown, cutoff, d, delform, down, editSauce, el, expandComment, expandThread, favEmpty, favNormal, favicon, formSubmit, getConfig, getTime, head, hiddenReplies, hiddenThreads, hide, hideReply, hideThread, href, html, i, i1, id, iframe, iframeLoad, iframeLoop, inAfter, inBefore, inputs, l, l1, lastChecked, m, magic, n, navbotr, navtopr, nodeInserted, now, omitted, onloadComment, onloadThread, options, optionsClose, parseResponse, pathname, quickReply, r, recaptcha, recaptchaListener, recaptchaReload, redirect, remove, replace, replyNav, report, sauceVarieties, show, showReply, showThread, slice, span, stopPropagation, text, textContent, thread, threadF, threads, tn, up, watch, watchX, watched, watcher, watcherUpdate, x, xhrs; var $, $$, AEOS, DAY, _, _i, _len, _ref, _ref2, a, addTo, arr, as, autoWatch, autohide, b, board, callback, clearHidden, close, config, cooldown, cutoff, d, delform, down, editSauce, el, expandComment, expandThread, formSubmit, g, getConfig, getTime, hide, hideReply, hideThread, href, html, i, i1, id, iframe, iframeLoad, inAfter, inBefore, inputs, l, l1, lastChecked, m, n, navbotr, navtopr, nodeInserted, now, omitted, onloadComment, onloadThread, options, optionsClose, parseResponse, pathname, quickReply, recaptcha, recaptchaListener, recaptchaReload, redirect, remove, replace, replyNav, report, show, showReply, showThread, slice, span, stopPropagation, temp, text, textContent, thread, threadF, threads, tn, up, watch, watchX, watcher, watcherUpdate, x;
var __slice = Array.prototype.slice, __hasProp = Object.prototype.hasOwnProperty; var __slice = Array.prototype.slice, __hasProp = Object.prototype.hasOwnProperty;
config = { config = {
'Thread Hiding': [true, 'Hide entire threads'], 'Thread Hiding': [true, 'Hide entire threads'],
@ -144,6 +144,7 @@
} }
}; };
d = document; d = document;
g = {};
$ = function(selector, root) { $ = function(selector, root) {
root || (root = d.body); root || (root = d.body);
return root.querySelector(selector); return root.querySelector(selector);
@ -239,35 +240,6 @@
root || (root = d.body); root || (root = d.body);
return d.evaluate(path, root, null, XPathResult.ANY_UNORDERED_NODE_TYPE, null).singleNodeValue; return d.evaluate(path, root, null, XPathResult.ANY_UNORDERED_NODE_TYPE, null).singleNodeValue;
}; };
AEOS.init();
iframeLoop = false;
xhrs = [];
r = null;
callbacks = [];
hiddenThreads = JSON.parse(GM_getValue("hiddenThreads/" + (BOARD) + "/", '[]'));
hiddenReplies = JSON.parse(GM_getValue("hiddenReplies/" + (BOARD) + "/", '[]'));
head = $('head', d);
if (!(favicon = $('link[rel="shortcut icon"]', head))) {
favicon = n('link', {
rel: 'shortcut icon',
href: 'http://static.4chan.org/image/favicon.ico'
});
addTo(head, favicon);
}
favNormal = favicon.href;
favEmpty = 'data:image/gif;base64,R0lGODlhEAAQAJEAAAAAAP///9vb2////yH5BAEAAAMALAAAAAAQABAAAAIvnI+pq+D9DBAUoFkPFnbs7lFZKIJOJJ3MyraoB14jFpOcVMpzrnF3OKlZYsMWowAAOw==';
sauceVarieties = ['http://regex.info/exif.cgi?url=', 'http://iqdb.org/?url=', 'http://saucenao.com/search.php?db=999&url=', 'http://tineye.com/search?url='].join('\n');
pathname = location.pathname.substring(1).split('/');
_ref = pathname;
BOARD = _ref[0];
magic = _ref[1];
if (magic === 'res') {
REPLY = magic;
THREAD_ID = pathname[2];
} else {
PAGENUM = parseInt(magic) || 0;
}
watched = JSON.parse(GM_getValue('watched', '{}'));
autohide = function() { autohide = function() {
var klass, qr; var klass, qr;
qr = $('#qr'); qr = $('#qr');
@ -282,7 +254,7 @@
autoWatch = function() { autoWatch = function() {
var autoText; var autoText;
autoText = $('textarea', this).value.slice(0, 25); autoText = $('textarea', this).value.slice(0, 25);
return GM_setValue('autoText', "/" + (BOARD) + "/ - " + (autoText)); return GM_setValue('autoText', "/" + (g.BOARD) + "/ - " + (autoText));
}; };
close = function() { close = function() {
var div; var div;
@ -290,11 +262,11 @@
return remove(div); return remove(div);
}; };
clearHidden = function() { clearHidden = function() {
GM_deleteValue("hiddenReplies/" + (BOARD) + "/"); GM_deleteValue("hiddenReplies/" + (g.BOARD) + "/");
GM_deleteValue("hiddenThreads/" + (BOARD) + "/"); GM_deleteValue("hiddenThreads/" + (g.BOARD) + "/");
this.value = "hidden: 0"; this.value = "hidden: 0";
hiddenReplies = []; g.hiddenReplies = [];
return (hiddenThreads = []); return (g.hiddenThreads = []);
}; };
cooldown = function() { cooldown = function() {
var auto, seconds, submit; var auto, seconds, submit;
@ -316,7 +288,7 @@
return ta.style.display ? show(ta) : hide(ta); return ta.style.display ? show(ta) : hide(ta);
}; };
expandComment = function(e) { expandComment = function(e) {
var a, href; var a, href, r;
e.preventDefault(); e.preventDefault();
a = this; a = this;
href = a.getAttribute('href'); href = a.getAttribute('href');
@ -326,13 +298,13 @@
}; };
r.open('GET', href, true); r.open('GET', href, true);
r.send(); r.send();
return xhrs.push({ return g.xhrs.push({
r: r, r: r,
id: href.match(/\d+/)[0] id: href.match(/\d+/)[0]
}); });
}; };
expandThread = function() { expandThread = function() {
var _i, _len, _ref2, id, num, prev, span, table, xhr; var _i, _len, _ref, id, num, prev, r, span, table, xhr;
id = x('preceding-sibling::input[1]', this).name; id = x('preceding-sibling::input[1]', this).name;
span = this; span = this;
if (span.textContent[0] === '-') { if (span.textContent[0] === '-') {
@ -345,9 +317,9 @@
return null; return null;
} }
span.textContent = span.textContent.replace('+', 'X Loading...'); span.textContent = span.textContent.replace('+', 'X Loading...');
_ref2 = xhrs; _ref = g.xhrs;
for (_i = 0, _len = _ref2.length; _i < _len; _i++) { for (_i = 0, _len = _ref.length; _i < _len; _i++) {
xhr = _ref2[_i]; xhr = _ref[_i];
if (xhr.id === id) { if (xhr.id === id) {
onloadThread(xhr.r.responseText, span); onloadThread(xhr.r.responseText, span);
return null; return null;
@ -359,19 +331,19 @@
}; };
r.open('GET', "res/" + (id), true); r.open('GET', "res/" + (id), true);
r.send(); r.send();
return xhrs.push({ return g.xhrs.push({
r: r, r: r,
id: id id: id
}); });
}; };
formSubmit = function(e) { formSubmit = function(e) {
var _ref2, _ref3, recaptcha, span; var _ref, _ref2, recaptcha, span;
if (span = this.nextSibling) { if (span = this.nextSibling) {
remove(span); remove(span);
} }
recaptcha = $('input[name=recaptcha_response_field]', this); recaptcha = $('input[name=recaptcha_response_field]', this);
if (recaptcha.value) { if (recaptcha.value) {
return (typeof (_ref3 = ((_ref2 = $('#qr input[title=autohide]:not(:checked)')))) === "undefined" || _ref3 === null) ? undefined : _ref3.click(); return (typeof (_ref2 = ((_ref = $('#qr input[title=autohide]:not(:checked)')))) === "undefined" || _ref2 === null) ? undefined : _ref2.click();
} else { } else {
e.preventDefault(); e.preventDefault();
span = n('span', { span = n('span', {
@ -384,17 +356,17 @@
} }
}; };
hideReply = function(reply) { hideReply = function(reply) {
var _ref2, _ref3, a, div, name, p, table, trip; var _ref, _ref2, a, div, name, p, table, trip;
if (p = this.parentNode) { if (p = this.parentNode) {
reply = p.nextSibling; reply = p.nextSibling;
hiddenReplies.push({ g.hiddenReplies.push({
id: reply.id, id: reply.id,
timestamp: getTime() timestamp: getTime()
}); });
GM_setValue("hiddenReplies/" + (BOARD) + "/", JSON.stringify(hiddenReplies)); GM_setValue("hiddenReplies/" + (g.BOARD) + "/", JSON.stringify(g.hiddenReplies));
} }
name = $('span.commentpostername', reply).textContent; name = $('span.commentpostername', reply).textContent;
trip = ((typeof (_ref3 = ((_ref2 = $('span.postertrip', reply)))) === "undefined" || _ref3 === null) ? undefined : _ref3.textContent) || ''; trip = ((typeof (_ref2 = ((_ref = $('span.postertrip', reply)))) === "undefined" || _ref2 === null) ? undefined : _ref2.textContent) || '';
table = x('ancestor::table', reply); table = x('ancestor::table', reply);
hide(table); hide(table);
if (getConfig('Show Stubs')) { if (getConfig('Show Stubs')) {
@ -409,14 +381,14 @@
} }
}; };
hideThread = function(div) { hideThread = function(div) {
var _ref2, _ref3, a, name, num, p, span, text, trip; var _ref, _ref2, a, name, num, p, span, text, trip;
if (p = this.parentNode) { if (p = this.parentNode) {
div = p; div = p;
hiddenThreads.push({ g.hiddenThreads.push({
id: div.id, id: div.id,
timestamp: getTime() timestamp: getTime()
}); });
GM_setValue("hiddenThreads/" + (BOARD) + "/", JSON.stringify(hiddenThreads)); GM_setValue("hiddenThreads/" + (g.BOARD) + "/", JSON.stringify(g.hiddenThreads));
} }
hide(div); hide(div);
if (getConfig('Show Stubs')) { if (getConfig('Show Stubs')) {
@ -428,7 +400,7 @@
num += $$('table', div).length; num += $$('table', div).length;
text = num === 1 ? "1 reply" : ("" + (num) + " replies"); text = num === 1 ? "1 reply" : ("" + (num) + " replies");
name = $('span.postername', div).textContent; name = $('span.postername', div).textContent;
trip = ((typeof (_ref3 = ((_ref2 = $('span.postername + span.postertrip', div)))) === "undefined" || _ref3 === null) ? undefined : _ref3.textContent) || ''; trip = ((typeof (_ref2 = ((_ref = $('span.postername + span.postertrip', div)))) === "undefined" || _ref2 === null) ? undefined : _ref2.textContent) || '';
a = n('a', { a = n('a', {
textContent: ("[ + ] " + (name) + (trip) + " (" + (text) + ")"), textContent: ("[ + ] " + (name) + (trip) + " (" + (text) + ")"),
className: 'pointer', className: 'pointer',
@ -438,8 +410,8 @@
} }
}; };
iframeLoad = function() { iframeLoad = function() {
var _ref2, _ref3, auto, error, qr, span, submit; var _ref, _ref2, auto, error, qr, span, submit;
if (iframeLoop = !iframeLoop) { if (g.iframe = !g.iframe) {
return null; return null;
} }
$('iframe').src = 'about:blank'; $('iframe').src = 'about:blank';
@ -450,8 +422,8 @@
className: 'error' className: 'error'
}); });
addTo(qr, span); addTo(qr, span);
(typeof (_ref3 = ((_ref2 = $('input[title=autohide]:checked', qr)))) === "undefined" || _ref3 === null) ? undefined : _ref3.click(); (typeof (_ref2 = ((_ref = $('input[title=autohide]:checked', qr)))) === "undefined" || _ref2 === null) ? undefined : _ref2.click();
} else if (REPLY && getConfig('Persistent QR')) { } else if (g.REPLY && getConfig('Persistent QR')) {
$('textarea', qr).value = ''; $('textarea', qr).value = '';
$('input[name=recaptcha_response_field]', qr).value = ''; $('input[name=recaptcha_response_field]', qr).value = '';
submit = $('input[type=submit]', qr); submit = $('input[type=submit]', qr);
@ -460,7 +432,7 @@
window.setTimeout(cooldown, 1000); window.setTimeout(cooldown, 1000);
auto = submit.previousSibling.lastChild; auto = submit.previousSibling.lastChild;
if (auto.checked) { if (auto.checked) {
(typeof (_ref3 = ((_ref2 = $('input[title=autohide]:checked', qr)))) === "undefined" || _ref3 === null) ? undefined : _ref3.click(); (typeof (_ref2 = ((_ref = $('input[title=autohide]:checked', qr)))) === "undefined" || _ref2 === null) ? undefined : _ref2.click();
} }
} else { } else {
remove(qr); remove(qr);
@ -468,12 +440,12 @@
return recaptchaReload(); return recaptchaReload();
}; };
nodeInserted = function(e) { nodeInserted = function(e) {
var _i, _len, _ref2, _result, callback, qr, target; var _i, _len, _ref, _result, callback, qr, target;
target = e.target; target = e.target;
if (target.nodeName === 'TABLE') { if (target.nodeName === 'TABLE') {
_result = []; _ref2 = callbacks; _result = []; _ref = g.callbacks;
for (_i = 0, _len = _ref2.length; _i < _len; _i++) { for (_i = 0, _len = _ref.length; _i < _len; _i++) {
callback = _ref2[_i]; callback = _ref[_i];
_result.push(callback(target)); _result.push(callback(target));
} }
return _result; return _result;
@ -483,20 +455,20 @@
} }
}; };
onloadComment = function(responseText, a, href) { onloadComment = function(responseText, a, href) {
var _, _i, _len, _ref2, bq, html, id, op, opbq, replies, reply; var _, _i, _len, _ref, bq, html, id, op, opbq, replies, reply;
_ref2 = href.match(/(\d+)#(\d+)/); _ref = href.match(/(\d+)#(\d+)/);
_ = _ref2[0]; _ = _ref[0];
op = _ref2[1]; op = _ref[1];
id = _ref2[2]; id = _ref[2];
_ref2 = parseResponse(responseText); _ref = parseResponse(responseText);
replies = _ref2[0]; replies = _ref[0];
opbq = _ref2[1]; opbq = _ref[1];
if (id === op) { if (id === op) {
html = opbq.innerHTML; html = opbq.innerHTML;
} else { } else {
_ref2 = replies; _ref = replies;
for (_i = 0, _len = _ref2.length; _i < _len; _i++) { for (_i = 0, _len = _ref.length; _i < _len; _i++) {
reply = _ref2[_i]; reply = _ref[_i];
if (reply.id === id) { if (reply.id === id) {
html = $('blockquote', reply).innerHTML; html = $('blockquote', reply).innerHTML;
} }
@ -506,70 +478,70 @@
return (bq.innerHTML = html); return (bq.innerHTML = html);
}; };
onloadThread = function(responseText, span) { onloadThread = function(responseText, span) {
var _i, _len, _ref2, _result, div, next, opbq, replies, reply; var _i, _len, _ref, _result, div, next, opbq, replies, reply;
_ref2 = parseResponse(responseText); _ref = parseResponse(responseText);
replies = _ref2[0]; replies = _ref[0];
opbq = _ref2[1]; opbq = _ref[1];
span.textContent = span.textContent.replace('X Loading...', '- '); span.textContent = span.textContent.replace('X Loading...', '- ');
span.previousSibling.innerHTML = opbq.innerHTML; span.previousSibling.innerHTML = opbq.innerHTML;
while ((next = span.nextSibling) && !next.clear) { while ((next = span.nextSibling) && !next.clear) {
remove(next); remove(next);
} }
if (next) { if (next) {
_result = []; _ref2 = replies; _result = []; _ref = replies;
for (_i = 0, _len = _ref2.length; _i < _len; _i++) { for (_i = 0, _len = _ref.length; _i < _len; _i++) {
reply = _ref2[_i]; reply = _ref[_i];
_result.push(inBefore(next, x('ancestor::table', reply))); _result.push(inBefore(next, x('ancestor::table', reply)));
} }
return _result; return _result;
} else { } else {
div = span.parentNode; div = span.parentNode;
_result = []; _ref2 = replies; _result = []; _ref = replies;
for (_i = 0, _len = _ref2.length; _i < _len; _i++) { for (_i = 0, _len = _ref.length; _i < _len; _i++) {
reply = _ref2[_i]; reply = _ref[_i];
_result.push(addTo(div, x('ancestor::table', reply))); _result.push(addTo(div, x('ancestor::table', reply)));
} }
return _result; return _result;
} }
}; };
options = function() { options = function() {
var _ref2, checked, description, div, hiddenNum, html, option, value; var _ref, checked, description, div, hiddenNum, html, option, value;
if (div = $('#options')) { if (div = $('#options')) {
return remove(div); return remove(div);
} else { } else {
div = AEOS.makeDialog('options', 'center'); div = AEOS.makeDialog('options', 'center');
hiddenNum = hiddenReplies.length + hiddenThreads.length; hiddenNum = g.hiddenReplies.length + g.hiddenThreads.length;
html = '<div class="move">Options <a class=pointer>X</a></div><div>'; html = '<div class="move">Options <a class=pointer>X</a></div><div>';
_ref2 = config; _ref = config;
for (option in _ref2) { for (option in _ref) {
if (!__hasProp.call(_ref2, option)) continue; if (!__hasProp.call(_ref, option)) continue;
value = _ref2[option]; value = _ref[option];
description = value[1]; description = value[1];
checked = getConfig(option) ? "checked" : ""; checked = getConfig(option) ? "checked" : "";
html += ("<label title=\"" + (description) + "\">" + (option) + "<input " + (checked) + " name=\"" + (option) + "\" type=\"checkbox\"></label><br>"); html += ("<label title=\"" + (description) + "\">" + (option) + "<input " + (checked) + " name=\"" + (option) + "\" type=\"checkbox\"></label><br>");
} }
html += "<div><a class=sauce>Sauce Varieties</a></div>"; html += "<div><a class=sauce>Flavors</a></div>";
html += "<div><textarea cols=50 rows=4 style=\"display: none;\"></textarea></div>"; html += "<div><textarea cols=50 rows=4 style=\"display: none;\"></textarea></div>";
html += ("<input type=\"button\" value=\"hidden: " + (hiddenNum) + "\"><br>"); html += ("<input type=\"button\" value=\"hidden: " + (hiddenNum) + "\"><br>");
div.innerHTML = html; div.innerHTML = html;
$('div.move', div).addEventListener('mousedown', AEOS.move, true); $('div.move', div).addEventListener('mousedown', AEOS.move, true);
$('a.pointer', div).addEventListener('click', optionsClose, true); $('a.pointer', div).addEventListener('click', optionsClose, true);
$('a.sauce', div).addEventListener('click', editSauce, true); $('a.sauce', div).addEventListener('click', editSauce, true);
$('textarea', div).value = GM_getValue('saucePrefix', sauceVarieties); $('textarea', div).value = GM_getValue('flavors', g.flavors);
$('input[type="button"]', div).addEventListener('click', clearHidden, true); $('input[type="button"]', div).addEventListener('click', clearHidden, true);
return addTo(d.body, div); return addTo(d.body, div);
} }
}; };
optionsClose = function() { optionsClose = function() {
var _i, _len, _ref2, div, input, inputs; var _i, _len, _ref, div, input, inputs;
div = this.parentNode.parentNode; div = this.parentNode.parentNode;
inputs = $$('input', div); inputs = $$('input', div);
_ref2 = inputs; _ref = inputs;
for (_i = 0, _len = _ref2.length; _i < _len; _i++) { for (_i = 0, _len = _ref.length; _i < _len; _i++) {
input = _ref2[_i]; input = _ref[_i];
GM_setValue(input.name, input.checked); GM_setValue(input.name, input.checked);
} }
GM_setValue('saucePrefix', $('textarea', div).value); GM_setValue('flavors', $('textarea', div).value);
return remove(div); return remove(div);
}; };
parseResponse = function(responseText) { parseResponse = function(responseText) {
@ -582,7 +554,7 @@
return [replies, opbq]; return [replies, opbq];
}; };
quickReply = function(e) { quickReply = function(e) {
var _i, _len, _ref2, _ref3, auto, autoBox, autohideB, clone, closeB, form, id, input, qr, script, selection, submit, text, textarea, titlebar, xpath; var _i, _len, _ref, _ref2, auto, autoBox, autohideB, clone, closeB, form, id, input, qr, script, selection, submit, text, textarea, titlebar, xpath;
if (!(qr = $('#qr'))) { if (!(qr = $('#qr'))) {
qr = AEOS.makeDialog('qr', 'topleft'); qr = AEOS.makeDialog('qr', 'topleft');
titlebar = n('div', { titlebar = n('div', {
@ -606,9 +578,9 @@
addTo(titlebar, autohideB, tn(' '), closeB); addTo(titlebar, autohideB, tn(' '), closeB);
form = $('form[name=post]'); form = $('form[name=post]');
clone = form.cloneNode(true); clone = form.cloneNode(true);
_ref2 = $$('script', clone); _ref = $$('script', clone);
for (_i = 0, _len = _ref2.length; _i < _len; _i++) { for (_i = 0, _len = _ref.length; _i < _len; _i++) {
script = _ref2[_i]; script = _ref[_i];
remove(script); remove(script);
} }
m($('input[name=recaptcha_response_field]', clone), { m($('input[name=recaptcha_response_field]', clone), {
@ -616,7 +588,7 @@
}); });
clone.addEventListener('submit', formSubmit, true); clone.addEventListener('submit', formSubmit, true);
clone.target = 'iframe'; clone.target = 'iframe';
if (!REPLY) { if (!g.REPLY) {
xpath = 'preceding::span[@class="postername"][1]/preceding::input[1]'; xpath = 'preceding::span[@class="postername"][1]/preceding::input[1]';
input = n('input', { input = n('input', {
type: 'hidden', type: 'hidden',
@ -640,9 +612,9 @@
} }
if (e) { if (e) {
e.preventDefault(); e.preventDefault();
(typeof (_ref3 = ((_ref2 = $('input[title=autohide]:checked', qr)))) === "undefined" || _ref3 === null) ? undefined : _ref3.click(); (typeof (_ref2 = ((_ref = $('input[title=autohide]:checked', qr)))) === "undefined" || _ref2 === null) ? undefined : _ref2.click();
selection = window.getSelection(); selection = window.getSelection();
id = (typeof (_ref3 = ((_ref2 = x('preceding::span[@id][1]', selection.anchorNode)))) === "undefined" || _ref3 === null) ? undefined : _ref3.id; id = (typeof (_ref2 = ((_ref = x('preceding::span[@id][1]', selection.anchorNode)))) === "undefined" || _ref2 === null) ? undefined : _ref2.id;
text = selection.toString(); text = selection.toString();
textarea = $('textarea', qr); textarea = $('textarea', qr);
textarea.focus(); textarea.focus();
@ -658,28 +630,28 @@
}; };
redirect = function() { redirect = function() {
var url; var url;
switch (BOARD) { switch (g.BOARD) {
case 'a': case 'a':
case 'g': case 'g':
case 'lit': case 'lit':
case 'sci': case 'sci':
case 'tv': case 'tv':
url = ("http://green-oval.net/cgi-board.pl/" + (BOARD) + "/thread/" + (THREAD_ID) + "#p"); url = ("http://green-oval.net/cgi-board.pl/" + (g.BOARD) + "/thread/" + (g.THREAD_ID) + "#p");
break; break;
case 'cgl': case 'cgl':
case 'jp': case 'jp':
case 'm': case 'm':
case 'tg': case 'tg':
url = ("http://archive.easymodo.net/cgi-board.pl/" + (BOARD) + "/thread/" + (THREAD_ID) + "#p"); url = ("http://archive.easymodo.net/cgi-board.pl/" + (g.BOARD) + "/thread/" + (g.THREAD_ID) + "#p");
break; break;
default: default:
url = ("http://boards.4chan.org/" + (BOARD)); url = ("http://boards.4chan.org/" + (g.BOARD));
} }
return (location.href = url); return (location.href = url);
}; };
replyNav = function() { replyNav = function() {
var direction, op; var direction, op;
if (REPLY) { if (g.REPLY) {
return (window.location = this.textContent === '▲' ? '#navtop' : '#navbot'); return (window.location = this.textContent === '▲' ? '#navtop' : '#navbot');
} else { } else {
direction = this.textContent === '▲' ? 'preceding' : 'following'; direction = this.textContent === '▲' ? 'preceding' : 'following';
@ -701,8 +673,8 @@
show(table); show(table);
remove(div); remove(div);
id = $('td.reply, td.replyhl', table).id; id = $('td.reply, td.replyhl', table).id;
slice(hiddenReplies, id); slice(g.hiddenReplies, id);
return GM_setValue("hiddenReplies/" + (BOARD) + "/", JSON.stringify(hiddenReplies)); return GM_setValue("hiddenReplies/" + (g.BOARD) + "/", JSON.stringify(g.hiddenReplies));
}; };
showThread = function() { showThread = function() {
var div, id; var div, id;
@ -710,14 +682,14 @@
show(div); show(div);
hide(this); hide(this);
id = div.id; id = div.id;
slice(hiddenThreads, id); slice(g.hiddenThreads, id);
return GM_setValue("hiddenThreads/" + (BOARD) + "/", JSON.stringify(hiddenThreads)); return GM_setValue("hiddenThreads/" + (g.BOARD) + "/", JSON.stringify(g.hiddenThreads));
}; };
stopPropagation = function(e) { stopPropagation = function(e) {
return e.stopPropagation(); return e.stopPropagation();
}; };
threadF = function(current) { threadF = function(current) {
var _i, _len, _ref2, a, div, hidden, id; var _i, _len, _ref, a, div, hidden, id;
div = n('div', { div = n('div', {
className: 'thread' className: 'thread'
}); });
@ -736,9 +708,9 @@
current = div.nextSibling; current = div.nextSibling;
id = $('input[value="delete"]', div).name; id = $('input[value="delete"]', div).name;
div.id = id; div.id = id;
_ref2 = hiddenThreads; _ref = g.hiddenThreads;
for (_i = 0, _len = _ref2.length; _i < _len; _i++) { for (_i = 0, _len = _ref.length; _i < _len; _i++) {
hidden = _ref2[_i]; hidden = _ref[_i];
if (id === hidden.id) { if (id === hidden.id) {
hideThread(div); hideThread(div);
} }
@ -750,30 +722,30 @@
var id, text; var id, text;
id = this.nextSibling.name; id = this.nextSibling.name;
if (this.src[0] === 'd') { if (this.src[0] === 'd') {
this.src = favNormal; this.src = g.favNormal;
text = ("/" + (BOARD) + "/ - ") + x('following-sibling::blockquote', this).textContent.slice(0, 25); text = ("/" + (g.BOARD) + "/ - ") + x('following-sibling::blockquote', this).textContent.slice(0, 25);
watched[BOARD] || (watched[BOARD] = []); g.watched[g.BOARD] || (g.watched[g.BOARD] = []);
watched[BOARD].push({ g.watched[g.BOARD].push({
id: id, id: id,
text: text text: text
}); });
} else { } else {
this.src = favEmpty; this.src = g.favEmpty;
watched[BOARD] = slice(watched[BOARD], id); g.watched[g.BOARD] = slice(g.watched[g.BOARD], id);
} }
GM_setValue('watched', JSON.stringify(watched)); GM_setValue('watched', JSON.stringify(g.watched));
return watcherUpdate(); return watcherUpdate();
}; };
watcherUpdate = function() { watcherUpdate = function() {
var _i, _j, _len, _ref2, _ref3, a, board, div, link, old, thread; var _i, _j, _len, _ref, _ref2, a, board, div, link, old, thread;
div = n('div'); div = n('div');
_ref2 = watched; _ref = g.watched;
for (board in _ref2) { for (board in _ref) {
if (!__hasProp.call(_ref2, board)) continue; if (!__hasProp.call(_ref, board)) continue;
_i = _ref2[board]; _i = _ref[board];
_ref3 = watched[board]; _ref2 = g.watched[board];
for (_j = 0, _len = _ref3.length; _j < _len; _j++) { for (_j = 0, _len = _ref2.length; _j < _len; _j++) {
thread = _ref3[_j]; thread = _ref2[_j];
a = n('a', { a = n('a', {
textContent: 'X', textContent: 'X',
className: 'pointer', className: 'pointer',
@ -790,19 +762,39 @@
return replace(old, div); return replace(old, div);
}; };
watchX = function() { watchX = function() {
var _, _ref2, board, id, input; var _, _ref, board, favicon, id, input;
_ref2 = this.nextElementSibling.getAttribute('href').substring(1).split('/'); _ref = this.nextElementSibling.getAttribute('href').substring(1).split('/');
board = _ref2[0]; board = _ref[0];
_ = _ref2[1]; _ = _ref[1];
id = _ref2[2]; id = _ref[2];
watched[board] = slice(watched[board], id); g.watched[board] = slice(g.watched[board], id);
GM_setValue('watched', JSON.stringify(watched)); GM_setValue('watched', JSON.stringify(g.watched));
watcherUpdate(); watcherUpdate();
if (input = $("input[name=\"" + (id) + "\"]")) { if (input = $("input[name=\"" + (id) + "\"]")) {
favicon = input.previousSibling; favicon = input.previousSibling;
return (favicon.src = favEmpty); return (favicon.src = g.favEmpty);
} }
}; };
AEOS.init();
g.iframe = false;
g.xhrs = [];
g.callbacks = [];
g.favNormal = ((typeof (_ref2 = ((_ref = $('link[rel="shortcut icon"]', $('head', d))))) === "undefined" || _ref2 === null) ? undefined : _ref2.href) || 'http://static.4chan.org/image/favicon.ico';
g.favEmpty = 'data:image/gif;base64,R0lGODlhEAAQAJEAAAAAAP///9vb2////yH5BAEAAAMALAAAAAAQABAAAAIvnI+pq+D9DBAUoFkPFnbs7lFZKIJOJJ3MyraoB14jFpOcVMpzrnF3OKlZYsMWowAAOw==';
g.flavors = ['http://regex.info/exif.cgi?url=', 'http://iqdb.org/?url=', 'http://saucenao.com/search.php?db=999&url=', 'http://tineye.com/search?url='].join('\n');
pathname = location.pathname.substring(1).split('/');
_ref = pathname;
g.BOARD = _ref[0];
temp = _ref[1];
if (temp === 'res') {
g.REPLY = temp;
g.THREAD_ID = pathname[2];
} else {
g.PAGENUM = parseInt(temp) || 0;
}
g.watched = JSON.parse(GM_getValue('watched', '{}'));
g.hiddenThreads = JSON.parse(GM_getValue("hiddenThreads/" + (g.BOARD) + "/", '[]'));
g.hiddenReplies = JSON.parse(GM_getValue("hiddenReplies/" + (g.BOARD) + "/", '[]'));
if (location.hostname.split('.')[0] === 'sys') { if (location.hostname.split('.')[0] === 'sys') {
if (recaptcha = $('#recaptcha_response_field')) { if (recaptcha = $('#recaptcha_response_field')) {
m(recaptcha, { m(recaptcha, {
@ -820,12 +812,12 @@
id = _ref[2]; id = _ref[2];
if (thread === '0') { if (thread === '0') {
board = $('meta', d).content.match(/4chan.org\/(\w+)\//)[1]; board = $('meta', d).content.match(/4chan.org\/(\w+)\//)[1];
watched[board] || (watched[board] = []); g.watched[board] || (g.watched[board] = []);
watched[board].push({ g.watched[board].push({
id: id, id: id,
text: GM_getValue('autoText') text: GM_getValue('autoText')
}); });
GM_setValue('watched', JSON.stringify(watched)); GM_setValue('watched', JSON.stringify(g.watched));
} }
} }
} }
@ -836,20 +828,20 @@
DAY = 24 * 60 * 60; DAY = 24 * 60 * 60;
if (lastChecked < now - 1 * DAY) { if (lastChecked < now - 1 * DAY) {
cutoff = now - 7 * DAY; cutoff = now - 7 * DAY;
while (hiddenThreads.length) { while (g.hiddenThreads.length) {
if (hiddenThreads[0].timestamp > cutoff) { if (g.hiddenThreads[0].timestamp > cutoff) {
break; break;
} }
hiddenThreads.shift(); g.hiddenThreads.shift();
} }
while (hiddenReplies.length) { while (g.hiddenReplies.length) {
if (hiddenReplies[0].timestamp > cutoff) { if (g.hiddenReplies[0].timestamp > cutoff) {
break; break;
} }
hiddenReplies.shift(); g.hiddenReplies.shift();
} }
GM_setValue("hiddenThreads/" + (BOARD) + "/", JSON.stringify(hiddenThreads)); GM_setValue("hiddenThreads/" + (g.BOARD) + "/", JSON.stringify(g.hiddenThreads));
GM_setValue("hiddenReplies/" + (BOARD) + "/", JSON.stringify(hiddenReplies)); GM_setValue("hiddenReplies/" + (g.BOARD) + "/", JSON.stringify(g.hiddenReplies));
GM_setValue('lastChecked', now); GM_setValue('lastChecked', now);
} }
GM_addStyle('\ GM_addStyle('\
@ -932,21 +924,21 @@
recaptcha = $('#recaptcha_response_field'); recaptcha = $('#recaptcha_response_field');
recaptcha.addEventListener('keydown', recaptchaListener, true); recaptcha.addEventListener('keydown', recaptchaListener, true);
if (getConfig('Sauce')) { if (getConfig('Sauce')) {
callbacks.push(function(root) { g.callbacks.push(function(root) {
var _j, _len2, _ref2, _result, _result2, i, l, link, names, prefix, prefixes, span, spans, suffix; var _j, _len2, _ref3, _result, _result2, i, l, link, names, prefix, prefixes, span, spans, suffix;
spans = $$('span.filesize', root); spans = $$('span.filesize', root);
prefixes = GM_getValue('saucePrefix', sauceVarieties).split('\n'); prefixes = GM_getValue('flavors', g.flavors).split('\n');
names = (function() { names = (function() {
_result = []; _ref2 = prefixes; _result = []; _ref3 = prefixes;
for (_j = 0, _len2 = _ref2.length; _j < _len2; _j++) { for (_j = 0, _len2 = _ref3.length; _j < _len2; _j++) {
prefix = _ref2[_j]; prefix = _ref3[_j];
_result.push(prefix.match(/(\w+)\./)[1]); _result.push(prefix.match(/(\w+)\./)[1]);
} }
return _result; return _result;
})(); })();
_result = []; _ref2 = spans; _result = []; _ref3 = spans;
for (_j = 0, _len2 = _ref2.length; _j < _len2; _j++) { for (_j = 0, _len2 = _ref3.length; _j < _len2; _j++) {
span = _ref2[_j]; span = _ref3[_j];
_result.push((function() { _result.push((function() {
suffix = $('a', span).href; suffix = $('a', span).href;
i = 0; i = 0;
@ -969,12 +961,12 @@
}); });
} }
if (getConfig('Reply Hiding')) { if (getConfig('Reply Hiding')) {
callbacks.push(function(root) { g.callbacks.push(function(root) {
var _j, _k, _len2, _len3, _ref2, _ref3, _result, _result2, next, obj, td, tds; var _j, _k, _len2, _len3, _ref3, _ref4, _result, _result2, next, obj, td, tds;
tds = $$('td.doubledash', root); tds = $$('td.doubledash', root);
_result = []; _ref2 = tds; _result = []; _ref3 = tds;
for (_j = 0, _len2 = _ref2.length; _j < _len2; _j++) { for (_j = 0, _len2 = _ref3.length; _j < _len2; _j++) {
td = _ref2[_j]; td = _ref3[_j];
_result.push((function() { _result.push((function() {
a = n('a', { a = n('a', {
textContent: '[ - ]', textContent: '[ - ]',
@ -984,9 +976,9 @@
replace(td.firstChild, a); replace(td.firstChild, a);
next = td.nextSibling; next = td.nextSibling;
id = next.id; id = next.id;
_result2 = []; _ref3 = hiddenReplies; _result2 = []; _ref4 = g.hiddenReplies;
for (_k = 0, _len3 = _ref3.length; _k < _len3; _k++) { for (_k = 0, _len3 = _ref4.length; _k < _len3; _k++) {
obj = _ref3[_k]; obj = _ref4[_k];
_result2.push(obj.id === id ? hideReply(next) : null); _result2.push(obj.id === id ? hideReply(next) : null);
} }
return _result2; return _result2;
@ -1002,12 +994,12 @@
}); });
hide(iframe); hide(iframe);
addTo(d.body, iframe); addTo(d.body, iframe);
callbacks.push(function(root) { g.callbacks.push(function(root) {
var _j, _len2, _ref2, _result, quote, quotes; var _j, _len2, _ref3, _result, quote, quotes;
quotes = $$('a.quotejs:not(:first-child)', root); quotes = $$('a.quotejs:not(:first-child)', root);
_result = []; _ref2 = quotes; _result = []; _ref3 = quotes;
for (_j = 0, _len2 = _ref2.length; _j < _len2; _j++) { for (_j = 0, _len2 = _ref3.length; _j < _len2; _j++) {
quote = _ref2[_j]; quote = _ref3[_j];
_result.push(quote.addEventListener('click', quickReply, true)); _result.push(quote.addEventListener('click', quickReply, true));
} }
return _result; return _result;
@ -1015,12 +1007,12 @@
recaptcha.id = ''; recaptcha.id = '';
} }
if (getConfig('Quick Report')) { if (getConfig('Quick Report')) {
callbacks.push(function(root) { g.callbacks.push(function(root) {
var _j, _len2, _ref2, _result, arr, el; var _j, _len2, _ref3, _result, arr, el;
arr = $$('span[id^=no]', root); arr = $$('span[id^=no]', root);
_result = []; _ref2 = arr; _result = []; _ref3 = arr;
for (_j = 0, _len2 = _ref2.length; _j < _len2; _j++) { for (_j = 0, _len2 = _ref3.length; _j < _len2; _j++) {
el = _ref2[_j]; el = _ref3[_j];
_result.push((function() { _result.push((function() {
a = n('a', { a = n('a', {
textContent: '[ ! ]', textContent: '[ ! ]',
@ -1040,7 +1032,7 @@
$('div', watcher).addEventListener('mousedown', AEOS.move, true); $('div', watcher).addEventListener('mousedown', AEOS.move, true);
addTo(d.body, watcher); addTo(d.body, watcher);
watcherUpdate(); watcherUpdate();
threads = watched[BOARD] || []; threads = g.watched[g.BOARD] || [];
inputs = $$('form > input[value="delete"], div > input[value="delete"]'); inputs = $$('form > input[value="delete"], div > input[value="delete"]');
_ref = inputs; _ref = inputs;
for (_i = 0, _len = _ref.length; _i < _len; _i++) { for (_i = 0, _len = _ref.length; _i < _len; _i++) {
@ -1049,15 +1041,15 @@
var input = _ref[_i]; var input = _ref[_i];
id = input.name; id = input.name;
src = (function() { src = (function() {
var _j, _len2, _ref2, thread; var _j, _len2, _ref3, thread;
_ref2 = threads; _ref3 = threads;
for (_j = 0, _len2 = _ref2.length; _j < _len2; _j++) { for (_j = 0, _len2 = _ref3.length; _j < _len2; _j++) {
thread = _ref2[_j]; thread = _ref3[_j];
if (id === thread.id) { if (id === thread.id) {
return favNormal; return g.favNormal;
} }
} }
return favEmpty; return g.favEmpty;
})(); })();
img = n('img', { img = n('img', {
src: src, src: src,
@ -1069,30 +1061,30 @@
} }
} }
if (getConfig('Anonymize')) { if (getConfig('Anonymize')) {
callbacks.push(function(root) { g.callbacks.push(function(root) {
var _j, _len2, _ref2, _result, name, names, trip, trips; var _j, _len2, _ref3, _result, name, names, trip, trips;
names = $$('span.postername, span.commentpostername', root); names = $$('span.postername, span.commentpostername', root);
_ref2 = names; _ref3 = names;
for (_j = 0, _len2 = _ref2.length; _j < _len2; _j++) { for (_j = 0, _len2 = _ref3.length; _j < _len2; _j++) {
name = _ref2[_j]; name = _ref3[_j];
name.innerHTML = 'Anonymous'; name.innerHTML = 'Anonymous';
} }
trips = $$('span.postertrip', root); trips = $$('span.postertrip', root);
_result = []; _ref2 = trips; _result = []; _ref3 = trips;
for (_j = 0, _len2 = _ref2.length; _j < _len2; _j++) { for (_j = 0, _len2 = _ref3.length; _j < _len2; _j++) {
trip = _ref2[_j]; trip = _ref3[_j];
_result.push(trip.parentNode.nodeName === 'A' ? remove(trip.parentNode) : remove(trip)); _result.push(trip.parentNode.nodeName === 'A' ? remove(trip.parentNode) : remove(trip));
} }
return _result; return _result;
}); });
} }
if (getConfig('Reply Navigation')) { if (getConfig('Reply Navigation')) {
callbacks.push(function(root) { g.callbacks.push(function(root) {
var _j, _len2, _ref2, _result, arr, down, el, span, up; var _j, _len2, _ref3, _result, arr, down, el, span, up;
arr = $$('span[id^=norep]', root); arr = $$('span[id^=norep]', root);
_result = []; _ref2 = arr; _result = []; _ref3 = arr;
for (_j = 0, _len2 = _ref2.length; _j < _len2; _j++) { for (_j = 0, _len2 = _ref3.length; _j < _len2; _j++) {
el = _ref2[_j]; el = _ref3[_j];
_result.push((function() { _result.push((function() {
span = n('span'); span = n('span');
up = n('a', { up = n('a', {
@ -1112,7 +1104,7 @@
return _result; return _result;
}); });
} }
if (REPLY) { if (g.REPLY) {
if (getConfig('Quick Reply') && getConfig('Persistent QR')) { if (getConfig('Quick Reply') && getConfig('Persistent QR')) {
quickReply(); quickReply();
$('#qr input[title=autohide]').click(); $('#qr input[title=autohide]').click();
@ -1122,7 +1114,7 @@
text = $('blockquote').textContent; text = $('blockquote').textContent;
} }
if (text) { if (text) {
d.title = ("/" + (BOARD) + "/ - " + (text)); d.title = ("/" + (g.BOARD) + "/ - " + (text));
} }
} }
} else { } else {
@ -1146,9 +1138,9 @@
if (i !== 0) { if (i !== 0) {
textContent = '▲'; textContent = '▲';
href = ("#" + (i)); href = ("#" + (i));
} else if (PAGENUM !== 0) { } else if (g.PAGENUM !== 0) {
textContent = '◀'; textContent = '◀';
href = ("" + (PAGENUM - 1)); href = ("" + (g.PAGENUM - 1));
} else { } else {
textContent = '▲'; textContent = '▲';
href = "#navtop"; href = "#navtop";
@ -1168,7 +1160,7 @@
}); });
if (i1 === l1) { if (i1 === l1) {
down.textContent = '▶'; down.textContent = '▶';
down.href = ("" + (PAGENUM + 1) + "#1"); down.href = ("" + (g.PAGENUM + 1) + "#1");
} else { } else {
down.textContent = '▼'; down.textContent = '▼';
down.href = ("#" + (i1)); down.href = ("#" + (i1));
@ -1202,7 +1194,7 @@
} }
} }
} }
_ref = callbacks; _ref = g.callbacks;
for (_i = 0, _len = _ref.length; _i < _len; _i++) { for (_i = 0, _len = _ref.length; _i < _len; _i++) {
callback = _ref[_i]; callback = _ref[_i];
callback(); callback();