Conflicts: CHANGELOG.md CONTRIBUTING.md css/style.css html/General/Settings-section-Main.html json/archives.json package.json src/Archive/Redirect.coffee src/General/Header.coffee src/General/Main.coffee src/General/Settings.coffee src/General/lib/$.coffee src/General/lib/thread.class src/Linkification/Linkify.coffee src/Miscellaneous/AnnouncementHiding.coffee src/Monitoring/ThreadStats.coffee
103 lines
3.5 KiB
CoffeeScript
Executable File
103 lines
3.5 KiB
CoffeeScript
Executable File
ExpandThread =
|
|
statuses: {}
|
|
init: ->
|
|
return if g.VIEW is 'thread' or !Conf['Thread Expansion']
|
|
$.on d, 'IndexRefresh', @onIndexRefresh
|
|
|
|
setButton: (thread) ->
|
|
return unless a = $.x 'following-sibling::a[contains(@class,"summary")][1]', thread.OP.nodes.root
|
|
a.textContent = ExpandThread.text '+', a.textContent.match(/\d+/g)...
|
|
$.on a, 'click', ExpandThread.cbToggle
|
|
|
|
disconnect: (refresh) ->
|
|
return if g.VIEW is 'thread' or !Conf['Thread Expansion']
|
|
for threadID, status of ExpandThread.statuses
|
|
status.req?.abort()
|
|
delete ExpandThread.statuses[threadID]
|
|
|
|
$.off d, 'IndexRefresh', @onIndexRefresh unless refresh
|
|
|
|
onIndexRefresh: ->
|
|
ExpandThread.disconnect true
|
|
g.BOARD.threads.forEach (thread) ->
|
|
ExpandThread.setButton thread
|
|
|
|
text: (status, posts, files) ->
|
|
"#{status} #{posts} post#{if posts > 1 then 's' else ''}" +
|
|
(if +files then " and #{files} image repl#{if files > 1 then 'ies' else 'y'}" else "") +
|
|
" #{if status is '-' then 'shown' else 'omitted'}."
|
|
|
|
cbToggle: (e) ->
|
|
return if e.shiftKey or e.altKey or e.ctrlKey or e.metaKey or e.button isnt 0
|
|
e.preventDefault()
|
|
ExpandThread.toggle Get.threadFromNode @
|
|
|
|
toggle: (thread) ->
|
|
threadRoot = thread.OP.nodes.root.parentNode
|
|
return unless a = $ '.summary', threadRoot
|
|
if thread.ID of ExpandThread.statuses
|
|
ExpandThread.contract thread, a, threadRoot
|
|
else
|
|
ExpandThread.expand thread, a, threadRoot
|
|
expand: (thread, a, threadRoot) ->
|
|
ExpandThread.statuses[thread] = status = {}
|
|
a.textContent = ExpandThread.text '...', a.textContent.match(/\d+/g)...
|
|
status.req = $.cache "//a.4cdn.org/#{thread.board}/res/#{thread}.json", ->
|
|
delete status.req
|
|
ExpandThread.parse @, thread, a
|
|
contract: (thread, a, threadRoot) ->
|
|
status = ExpandThread.statuses[thread]
|
|
delete ExpandThread.statuses[thread]
|
|
if status.req
|
|
status.req.abort()
|
|
a.textContent = ExpandThread.text '+', a.textContent.match(/\d+/g)... if a
|
|
return
|
|
|
|
replies = $$ '.thread > .replyContainer', threadRoot
|
|
if Conf['Show Replies']
|
|
num = if thread.isSticky
|
|
1
|
|
else switch g.BOARD.ID
|
|
# XXX boards config
|
|
when 'b', 'vg' then 3
|
|
when 't' then 1
|
|
else 5
|
|
replies = replies[...-num]
|
|
postsCount = 0
|
|
filesCount = 0
|
|
for reply in replies
|
|
# rm clones
|
|
inlined.click() while inlined = $ '.inlined', reply if Conf['Quote Inlining']
|
|
postsCount++
|
|
filesCount++ if 'file' of Get.postFromRoot reply
|
|
$.rm reply
|
|
a.textContent = ExpandThread.text '+', postsCount, filesCount
|
|
parse: (req, thread, a) ->
|
|
if req.status not in [200, 304]
|
|
a.textContent = "Error #{req.statusText} (#{req.status})"
|
|
return
|
|
|
|
Build.spoilerRange[thread.board] = req.response.posts[0].custom_spoiler
|
|
|
|
posts = []
|
|
postsRoot = []
|
|
filesCount = 0
|
|
for postData in req.response.posts
|
|
continue if postData.no is thread.ID
|
|
if post = thread.posts[postData.no]
|
|
filesCount++ if 'file' of post
|
|
postsRoot.push post.nodes.root
|
|
continue
|
|
root = Build.postFromObject postData, thread.board.ID
|
|
post = new Post root, thread, thread.board
|
|
filesCount++ if 'file' of post
|
|
posts.push post
|
|
postsRoot.push root
|
|
Main.callbackNodes Post, posts
|
|
$.after a, postsRoot
|
|
|
|
postsCount = postsRoot.length
|
|
a.textContent = ExpandThread.text '-', postsCount, filesCount
|
|
|
|
Fourchan.parseThread thread.ID, 1, postsCount
|