Drop navigation between threads/boards with JSON
This commit is contained in:
parent
5989c4b555
commit
722635d722
@ -37,7 +37,6 @@ module.exports = (grunt) ->
|
|||||||
'src/Monitoring/**/*.coffee'
|
'src/Monitoring/**/*.coffee'
|
||||||
'src/Archive/**/*.coffee'
|
'src/Archive/**/*.coffee'
|
||||||
'src/Miscellaneous/**/*.coffee'
|
'src/Miscellaneous/**/*.coffee'
|
||||||
'src/General/Navigate.coffee'
|
|
||||||
'src/General/Settings.coffee'
|
'src/General/Settings.coffee'
|
||||||
'src/General/Main.coffee'
|
'src/General/Main.coffee'
|
||||||
]
|
]
|
||||||
|
|||||||
@ -3,7 +3,7 @@ Config =
|
|||||||
'Miscellaneous':
|
'Miscellaneous':
|
||||||
'JSON Navigation' : [
|
'JSON Navigation' : [
|
||||||
false
|
false
|
||||||
'Use JSON for loading the Board Index and Threads. Also allows searching and sorting the board index and infinite scolling.'
|
'Use JSON for loading the Board Index. Also allows searching and sorting the board index and infinite scolling.'
|
||||||
]
|
]
|
||||||
'Catalog Links': [
|
'Catalog Links': [
|
||||||
true
|
true
|
||||||
|
|||||||
@ -94,8 +94,6 @@ Header =
|
|||||||
|
|
||||||
$.ready =>
|
$.ready =>
|
||||||
@footer = footer = $.id 'boardNavDesktopFoot'
|
@footer = footer = $.id 'boardNavDesktopFoot'
|
||||||
if Conf['JSON Navigation']
|
|
||||||
$.on a, 'click', Navigate.navigate for a in $$ 'a', footer
|
|
||||||
if a = $ "a[href*='/#{g.BOARD}/']", footer
|
if a = $ "a[href*='/#{g.BOARD}/']", footer
|
||||||
a.className = 'current'
|
a.className = 'current'
|
||||||
|
|
||||||
@ -137,8 +135,6 @@ Header =
|
|||||||
id: 'board-list'
|
id: 'board-list'
|
||||||
innerHTML: "<span id='custom-board-list'></span><span id='full-board-list' hidden><span class='hide-board-list-container brackets-wrap'><a href='javascript:;' class='hide-board-list-button'> - </a></span> #{fourchannav.innerHTML}</span>"
|
innerHTML: "<span id='custom-board-list'></span><span id='full-board-list' hidden><span class='hide-board-list-container brackets-wrap'><a href='javascript:;' class='hide-board-list-button'> - </a></span> #{fourchannav.innerHTML}</span>"
|
||||||
for a in $$ 'a', boardList
|
for a in $$ 'a', boardList
|
||||||
if Conf['JSON Navigation']
|
|
||||||
$.on a, 'click', Navigate.navigate
|
|
||||||
if a.pathname.split('/')[1] is g.BOARD.ID
|
if a.pathname.split('/')[1] is g.BOARD.ID
|
||||||
a.className = 'current'
|
a.className = 'current'
|
||||||
fullBoardList = $ '#full-board-list', boardList
|
fullBoardList = $ '#full-board-list', boardList
|
||||||
@ -184,9 +180,6 @@ Header =
|
|||||||
if a.textContent is board
|
if a.textContent is board
|
||||||
a = a.cloneNode true
|
a = a.cloneNode true
|
||||||
|
|
||||||
if Conf['JSON Navigation']
|
|
||||||
$.on a, 'click', Navigate.navigate
|
|
||||||
|
|
||||||
a.textContent = if /-title/.test(t) or /-replace/.test(t) and $.hasClass a, 'current'
|
a.textContent = if /-title/.test(t) or /-replace/.test(t) and $.hasClass a, 'current'
|
||||||
a.title
|
a.title
|
||||||
else if /-full/.test t
|
else if /-full/.test t
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
Index =
|
Index =
|
||||||
init: ->
|
init: ->
|
||||||
return if g.BOARD.ID is 'f' or g.VIEW is 'catalog' or !Conf['JSON Navigation']
|
return if g.BOARD.ID is 'f' or g.VIEW isnt 'index' or !Conf['JSON Navigation']
|
||||||
|
|
||||||
@board = "#{g.BOARD}"
|
@board = "#{g.BOARD}"
|
||||||
|
|
||||||
@ -71,20 +71,16 @@ Index =
|
|||||||
@navLinks = $.el 'div',
|
@navLinks = $.el 'div',
|
||||||
className: 'navLinks'
|
className: 'navLinks'
|
||||||
innerHTML: <%= importHTML('Features/Index-navlinks') %>
|
innerHTML: <%= importHTML('Features/Index-navlinks') %>
|
||||||
@navLinksBot = $.el 'div',
|
$('.returnlink a', @navLinks).href = "//boards.4chan.org/#{g.BOARD}/"
|
||||||
className: 'navLinks navLinksBot'
|
$('.cataloglink a', @navLinks).href = "//boards.4chan.org/#{g.BOARD}/catalog"
|
||||||
innerHTML: <%= importHTML('Features/Index-navlinksbot') %>
|
|
||||||
@searchInput = $ '#index-search', @navLinks
|
@searchInput = $ '#index-search', @navLinks
|
||||||
@currentPage = @getCurrentPage()
|
@currentPage = @getCurrentPage()
|
||||||
|
$.on window, 'popstate', @cb.popstate
|
||||||
Index.setNavLinks()
|
|
||||||
|
|
||||||
$.on d, 'scroll', Index.scroll
|
$.on d, 'scroll', Index.scroll
|
||||||
$.on @pagelist, 'click', @cb.pageNav
|
$.on @pagelist, 'click', @cb.pageNav
|
||||||
$.on @searchInput, 'input', @onSearchInput
|
$.on @searchInput, 'input', @onSearchInput
|
||||||
$.on $('#index-search-clear', @navLinks), 'click', @clearSearch
|
$.on $('#index-search-clear', @navLinks), 'click', @clearSearch
|
||||||
$.on $('.returnlink a', @navLinks), 'click', Navigate.navigate
|
|
||||||
$.on $('.returnlink a', @navLinksBot), 'click', Navigate.navigate
|
|
||||||
|
|
||||||
@update() if g.VIEW is 'index'
|
@update() if g.VIEW is 'index'
|
||||||
$.asap (-> $('.board', doc) or d.readyState isnt 'loading'), ->
|
$.asap (-> $('.board', doc) or d.readyState isnt 'loading'), ->
|
||||||
@ -100,15 +96,11 @@ Index =
|
|||||||
# Does not work on Firefox unfortunately. bugzil.la/939713
|
# Does not work on Firefox unfortunately. bugzil.la/939713
|
||||||
d.implementation.createDocument(null, null, null).appendChild board
|
d.implementation.createDocument(null, null, null).appendChild board
|
||||||
|
|
||||||
$.asap (-> $('.navLinksBot.mobile', doc) or d.readyState isnt 'loading'), ->
|
$.rm el for el in $$ '.navLinks'
|
||||||
$.rm el for el in $$ '.navLinks, .navLinksBot + hr'
|
|
||||||
$.id('search-box')?.parentNode.remove()
|
$.id('search-box')?.parentNode.remove()
|
||||||
topNavPos = $.id('delform').previousElementSibling
|
topNavPos = $.id('delform').previousElementSibling
|
||||||
botNavPos = $ '.board'
|
$.before topNavPos, $.el 'hr'
|
||||||
$.before topNavPos, $.el 'hr' if g.VIEW is 'index'
|
|
||||||
$.before topNavPos, Index.navLinks
|
$.before topNavPos, Index.navLinks
|
||||||
$.after botNavPos, $.el 'hr'
|
|
||||||
$.after botNavPos, Index.navLinksBot
|
|
||||||
|
|
||||||
$.asap (-> $('.pagelist', doc) or d.readyState isnt 'loading'), ->
|
$.asap (-> $('.pagelist', doc) or d.readyState isnt 'loading'), ->
|
||||||
if pagelist = $('.pagelist')
|
if pagelist = $('.pagelist')
|
||||||
@ -117,10 +109,6 @@ Index =
|
|||||||
$.after $.id('delform'), Index.pagelist
|
$.after $.id('delform'), Index.pagelist
|
||||||
$.rmClass doc, 'index-loading'
|
$.rmClass doc, 'index-loading'
|
||||||
|
|
||||||
setNavLinks: () ->
|
|
||||||
$('.returnlink a', Index.navLinks).href = $('.returnlink a', Index.navLinksBot).href = "//boards.4chan.org/#{g.BOARD}/"
|
|
||||||
$('.cataloglink a', Index.navLinks).href = $('.cataloglink a', Index.navLinksBot).href = "//boards.4chan.org/#{g.BOARD}/catalog"
|
|
||||||
|
|
||||||
scroll: ->
|
scroll: ->
|
||||||
return if Index.req or Conf['Index Mode'] isnt 'infinite' or (window.scrollY <= doc.scrollHeight - (300 + window.innerHeight)) or g.VIEW is 'thread'
|
return if Index.req or Conf['Index Mode'] isnt 'infinite' or (window.scrollY <= doc.scrollHeight - (300 + window.innerHeight)) or g.VIEW is 'thread'
|
||||||
Index.pageNum = Index.getCurrentPage() unless Index.pageNum? # Avoid having to pushState to keep track of the current page
|
Index.pageNum = Index.getCurrentPage() unless Index.pageNum? # Avoid having to pushState to keep track of the current page
|
||||||
@ -153,6 +141,9 @@ Index =
|
|||||||
Index.buildThreads()
|
Index.buildThreads()
|
||||||
Index.sort()
|
Index.sort()
|
||||||
Index.buildIndex()
|
Index.buildIndex()
|
||||||
|
popstate: (e) ->
|
||||||
|
pageNum = Index.getCurrentPage()
|
||||||
|
Index.pageLoad pageNum if Index.currentPage isnt pageNum
|
||||||
pageNav: (e) ->
|
pageNav: (e) ->
|
||||||
return if e.shiftKey or e.altKey or e.ctrlKey or e.metaKey or e.button isnt 0
|
return if e.shiftKey or e.altKey or e.ctrlKey or e.metaKey or e.button isnt 0
|
||||||
switch e.target.nodeName
|
switch e.target.nodeName
|
||||||
@ -172,7 +163,7 @@ Index =
|
|||||||
getCurrentPage: ->
|
getCurrentPage: ->
|
||||||
+window.location.pathname.split('/')[2] or 1
|
+window.location.pathname.split('/')[2] or 1
|
||||||
userPageNav: (pageNum) ->
|
userPageNav: (pageNum) ->
|
||||||
Navigate.pushState if pageNum is 1 then './' else pageNum
|
history.pushState null, '', if pageNum is 1 then './' else pageNum
|
||||||
if Conf['Refreshed Navigation'] and Conf['Index Mode'] isnt 'all pages'
|
if Conf['Refreshed Navigation'] and Conf['Index Mode'] isnt 'all pages'
|
||||||
Index.update pageNum
|
Index.update pageNum
|
||||||
else
|
else
|
||||||
@ -232,9 +223,6 @@ Index =
|
|||||||
|
|
||||||
update: (pageNum, forceReparse) ->
|
update: (pageNum, forceReparse) ->
|
||||||
return unless navigator.onLine
|
return unless navigator.onLine
|
||||||
if g.VIEW is 'thread'
|
|
||||||
return ThreadUpdater.update() if Conf['Thread Updater']
|
|
||||||
return
|
|
||||||
unless d.readyState is 'loading' or Index.root.parentElement
|
unless d.readyState is 'loading' or Index.root.parentElement
|
||||||
$.replace $('.board'), Index.root
|
$.replace $('.board'), Index.root
|
||||||
delete Index.pageNum
|
delete Index.pageNum
|
||||||
@ -281,8 +269,6 @@ Index =
|
|||||||
new Notice 'warning', err, 1
|
new Notice 'warning', err, 1
|
||||||
return
|
return
|
||||||
|
|
||||||
Navigate.title()
|
|
||||||
|
|
||||||
try
|
try
|
||||||
if req.status is 200
|
if req.status is 200
|
||||||
Index.parse req.response, pageNum
|
Index.parse req.response, pageNum
|
||||||
@ -498,7 +484,7 @@ Index =
|
|||||||
Index.buildIndex()
|
Index.buildIndex()
|
||||||
Index.setPage()
|
Index.setPage()
|
||||||
else
|
else
|
||||||
Navigate.pushState if pageNum is 1 then './' else pageNum
|
history.pushState null, '', if pageNum is 1 then './' else pageNum
|
||||||
Index.pageLoad pageNum
|
Index.pageLoad pageNum
|
||||||
|
|
||||||
querySearch: (query) ->
|
querySearch: (query) ->
|
||||||
|
|||||||
@ -345,7 +345,6 @@ Main =
|
|||||||
['Keybinds', Keybinds]
|
['Keybinds', Keybinds]
|
||||||
['Show Dice Roll', Dice]
|
['Show Dice Roll', Dice]
|
||||||
['Banner', Banner]
|
['Banner', Banner]
|
||||||
['Navigate', Navigate]
|
|
||||||
]
|
]
|
||||||
|
|
||||||
Main.init()
|
Main.init()
|
||||||
|
|||||||
@ -1,329 +0,0 @@
|
|||||||
Navigate =
|
|
||||||
path: window.location.pathname
|
|
||||||
init: ->
|
|
||||||
return if g.VIEW is 'catalog' or g.BOARD.ID is 'f' or !Conf['JSON Navigation']
|
|
||||||
|
|
||||||
<% if (type === 'crx') { %>
|
|
||||||
# blink/webkit throw a popstate on page load. Not what we want.
|
|
||||||
popstateHack = ->
|
|
||||||
$.off window, 'popstate', popstateHack
|
|
||||||
$.on window, 'popstate', Navigate.popstate
|
|
||||||
|
|
||||||
$.on window, 'popstate', popstateHack
|
|
||||||
<% } else { %>
|
|
||||||
$.on window, 'popstate', Navigate.popstate
|
|
||||||
<% } %>
|
|
||||||
|
|
||||||
@title = -> return
|
|
||||||
|
|
||||||
Thread.callbacks.push
|
|
||||||
name: 'Navigate'
|
|
||||||
cb: @thread
|
|
||||||
|
|
||||||
Post.callbacks.push
|
|
||||||
name: 'Navigate'
|
|
||||||
cb: @post
|
|
||||||
|
|
||||||
thread: ->
|
|
||||||
return if g.VIEW is 'thread' # The reply link only exists in index view
|
|
||||||
replyLink = $ 'a.replylink', @OP.nodes.info
|
|
||||||
$.on replyLink, 'click', Navigate.navigate
|
|
||||||
|
|
||||||
post: -> # Allows us to navigate via JSON from thread to thread by hashes and quote highlights.
|
|
||||||
# We don't need to reload the thread inside the thread
|
|
||||||
unless g.VIEW is 'thread' and @thread.ID is g.THREADID
|
|
||||||
$.on $('a[title="Link to this post"]', @nodes.info), 'click', Navigate.navigate
|
|
||||||
|
|
||||||
return unless (linktype = if Conf['Quote Inlining'] and Conf['Quote Hash Navigation']
|
|
||||||
'.hashlink'
|
|
||||||
else if !Conf['Quote Inlining']
|
|
||||||
'.quotelink'
|
|
||||||
else
|
|
||||||
null
|
|
||||||
)
|
|
||||||
|
|
||||||
Navigate.quoteLink $$ linktype, @nodes.comment
|
|
||||||
|
|
||||||
quoteLink: (links) ->
|
|
||||||
for link in links
|
|
||||||
Navigate.singleQuoteLink link
|
|
||||||
return
|
|
||||||
|
|
||||||
singleQuoteLink: (link) ->
|
|
||||||
{boardID, threadID} = Get.postDataFromLink link
|
|
||||||
if g.VIEW is 'index' or boardID isnt g.BOARD.ID or threadID isnt g.THREADID
|
|
||||||
$.on link, 'click', Navigate.navigate
|
|
||||||
|
|
||||||
clean: ->
|
|
||||||
# Garbage collection
|
|
||||||
g.threads.forEach (thread) -> thread.collect()
|
|
||||||
QuoteBacklink.containers = {}
|
|
||||||
|
|
||||||
$.rmAll $ '.board'
|
|
||||||
|
|
||||||
features: [
|
|
||||||
['Thread Excerpt', ThreadExcerpt]
|
|
||||||
['Unread Count', Unread]
|
|
||||||
['Quote Threading', QuoteThreading]
|
|
||||||
['Thread Stats', ThreadStats]
|
|
||||||
['Thread Updater', ThreadUpdater]
|
|
||||||
['Thread Expansion', ExpandThread]
|
|
||||||
]
|
|
||||||
|
|
||||||
disconnect: ->
|
|
||||||
for [name, feature] in Navigate.features
|
|
||||||
try
|
|
||||||
feature.disconnect()
|
|
||||||
catch err
|
|
||||||
errors = [] unless errors
|
|
||||||
errors.push
|
|
||||||
message: "Failed to disconnect feature #{name}."
|
|
||||||
error: err
|
|
||||||
|
|
||||||
Main.handleErrors errors if errors
|
|
||||||
|
|
||||||
return
|
|
||||||
|
|
||||||
reconnect: ->
|
|
||||||
for [name, feature] in Navigate.features
|
|
||||||
try
|
|
||||||
feature.init()
|
|
||||||
catch err
|
|
||||||
errors = [] unless errors
|
|
||||||
errors.push
|
|
||||||
message: "Failed to reconnect feature #{name}."
|
|
||||||
error: err
|
|
||||||
Main.handleErrors errors if errors
|
|
||||||
return
|
|
||||||
|
|
||||||
updateContext: (view) ->
|
|
||||||
g.DEAD = false
|
|
||||||
g.THREADID = +window.location.pathname.split('/')[3] if view is 'thread'
|
|
||||||
|
|
||||||
unless view is g.VIEW
|
|
||||||
$.rmClass doc, g.VIEW
|
|
||||||
$.addClass doc, view
|
|
||||||
|
|
||||||
delete g.THREADID if view is 'index'
|
|
||||||
|
|
||||||
origFormThread = $ 'form[name="post"] input[name="resto"]'
|
|
||||||
if view is 'thread'
|
|
||||||
unless origFormThread
|
|
||||||
origFormThread = $.el 'input',
|
|
||||||
type: 'hidden'
|
|
||||||
name: 'resto'
|
|
||||||
$.after ($.id 'postPassword'), origFormThread
|
|
||||||
origFormThread.value = g.THREADID
|
|
||||||
else
|
|
||||||
$.rm origFormThread if origFormThread
|
|
||||||
|
|
||||||
if Conf['Quick Reply']
|
|
||||||
QR.link.textContent = if view is 'thread' then 'Reply to Thread' else 'Start a Thread'
|
|
||||||
QR.status() # Re-enable the QR in the case of a 404'd thread or something.
|
|
||||||
for post in QR.posts
|
|
||||||
post.thread = g.THREADID or 'new'
|
|
||||||
|
|
||||||
g.VIEW = view
|
|
||||||
|
|
||||||
updateBoard: (boardID) ->
|
|
||||||
fullBoardList = $ '#full-board-list', Header.boardList
|
|
||||||
$.rmClass current, 'current' if current = $ '.current', fullBoardList
|
|
||||||
$.addClass current, 'current' if current = $ "a[href*='/#{boardID}/']", fullBoardList
|
|
||||||
Header.generateBoardList Conf['boardnav'].replace /(\r\n|\n|\r)/g, ' '
|
|
||||||
|
|
||||||
Index.setNavLinks()
|
|
||||||
$('form[name="post"]').action = "//sys.4chan.org/#{g.BOARD}/post"
|
|
||||||
QR.flagsInput() if Conf['Quick Reply']
|
|
||||||
|
|
||||||
$.cache '//a.4cdn.org/boards.json', ->
|
|
||||||
try
|
|
||||||
return unless @status is 200
|
|
||||||
for aboard in @response.boards when aboard.board is boardID
|
|
||||||
board = aboard
|
|
||||||
break
|
|
||||||
|
|
||||||
catch err
|
|
||||||
Main.handleErrors [
|
|
||||||
message: "Navigation failed to update board name."
|
|
||||||
error: err
|
|
||||||
]
|
|
||||||
|
|
||||||
return unless board
|
|
||||||
Navigate.updateTitle board
|
|
||||||
Navigate.updateSFW !!board.ws_board
|
|
||||||
|
|
||||||
updateSFW: (sfw) ->
|
|
||||||
Favicon.el.href = Favicon.default = "//s.4cdn.org/image/favicon#{if sfw then '-ws' else ''}.ico"
|
|
||||||
|
|
||||||
# Changing the href alone doesn't update the icon on Firefox
|
|
||||||
$.add d.head, Favicon.el
|
|
||||||
|
|
||||||
return if Favicon.SFW is sfw # Board SFW status hasn't changed
|
|
||||||
|
|
||||||
Favicon.SFW = sfw
|
|
||||||
Favicon.update()
|
|
||||||
|
|
||||||
findStyle = (type, base) ->
|
|
||||||
style = d.cookie.match new RegExp "\\b#{type}_style=([^;]+)"
|
|
||||||
return ["#{type}_style", (if style then style[1] else base)]
|
|
||||||
|
|
||||||
style = if sfw
|
|
||||||
findStyle 'ws', 'Yotsuba B New'
|
|
||||||
else
|
|
||||||
findStyle 'nws', 'Yotsuba New'
|
|
||||||
|
|
||||||
$.globalEval "var style_group = #{JSON.stringify style[0]}"
|
|
||||||
|
|
||||||
$('link[title=switch]', d.head).href = $("link[title='#{style[1]}']", d.head).href
|
|
||||||
|
|
||||||
Main.setClass()
|
|
||||||
|
|
||||||
updateTitle: ({board, title}) ->
|
|
||||||
$.rm subtitle if subtitle = $ '.boardSubtitle'
|
|
||||||
$('.boardTitle').textContent = d.title = "/#{board}/ - #{title}"
|
|
||||||
|
|
||||||
navigate: (e) ->
|
|
||||||
return if @hostname isnt 'boards.4chan.org' or window.location.hostname is 'rs.4chan.org'
|
|
||||||
if e
|
|
||||||
return if e.shiftKey or e.ctrlKey or (e.type is 'click' and e.button isnt 0) # Not simply a left click
|
|
||||||
|
|
||||||
if @pathname is Navigate.path
|
|
||||||
return if @id is 'popState'
|
|
||||||
if g.VIEW is 'thread'
|
|
||||||
ThreadUpdater.update() if Conf['Thread Updater']
|
|
||||||
else
|
|
||||||
Index.update()
|
|
||||||
e?.preventDefault()
|
|
||||||
return
|
|
||||||
|
|
||||||
$.addClass Index.button, 'fa-spin'
|
|
||||||
Index.clearSearch() if Index.isSearching
|
|
||||||
|
|
||||||
[_, boardID, view, threadID] = @pathname.split '/'
|
|
||||||
|
|
||||||
return if view is 'catalog' or 'f' in [boardID, g.BOARD.ID]
|
|
||||||
e?.preventDefault()
|
|
||||||
Navigate.title = -> return
|
|
||||||
|
|
||||||
delete Index.pageNum
|
|
||||||
$.rmAll Header.hover
|
|
||||||
|
|
||||||
if threadID
|
|
||||||
view = 'thread'
|
|
||||||
else
|
|
||||||
pageNum = +view or 1 # string to number, '' to 1
|
|
||||||
view = 'index' # path is "/boardID/". See the problem?
|
|
||||||
|
|
||||||
path = @pathname
|
|
||||||
path += @hash if @hash
|
|
||||||
|
|
||||||
history.pushState null, '', path unless @id is 'popState'
|
|
||||||
Navigate.path = @pathname
|
|
||||||
|
|
||||||
unless view is 'index' and 'index' is g.VIEW and boardID is g.BOARD.ID
|
|
||||||
Navigate.disconnect()
|
|
||||||
Navigate.updateContext view
|
|
||||||
Navigate.clean()
|
|
||||||
Navigate.reconnect()
|
|
||||||
|
|
||||||
if boardID is g.BOARD.ID
|
|
||||||
Navigate.title = -> d.title = $('.boardTitle').textContent if view is 'index'
|
|
||||||
else
|
|
||||||
g.BOARD = new Board boardID
|
|
||||||
Navigate.title = -> Navigate.updateBoard boardID
|
|
||||||
|
|
||||||
Navigate.updateSFW Favicon.SFW
|
|
||||||
|
|
||||||
if view is 'index'
|
|
||||||
return Index.update pageNum, true
|
|
||||||
|
|
||||||
# Moving from index to thread or thread to thread
|
|
||||||
{load} = Navigate
|
|
||||||
Navigate.req = $.ajax "//a.4cdn.org/#{boardID}/thread/#{threadID}.json",
|
|
||||||
onabort: load
|
|
||||||
onloadend: load
|
|
||||||
|
|
||||||
setTimeout (->
|
|
||||||
if Navigate.req and !Navigate.notice
|
|
||||||
Navigate.notice = new Notice 'info', 'Loading thread...'
|
|
||||||
), 3 * $.SECOND
|
|
||||||
|
|
||||||
load: (e) ->
|
|
||||||
$.rmClass Index.button, 'fa-spin'
|
|
||||||
{req, notice} = Navigate
|
|
||||||
notice?.close()
|
|
||||||
delete Navigate.req
|
|
||||||
delete Navigate.notice
|
|
||||||
|
|
||||||
if e.type is 'abort' or req.status isnt 200
|
|
||||||
req.onloadend = null
|
|
||||||
new Notice 'warning', "Failed to load thread.#{if req.status then " #{req.status}" else ''}"
|
|
||||||
return
|
|
||||||
|
|
||||||
Navigate.title()
|
|
||||||
|
|
||||||
try
|
|
||||||
Navigate.parse req.response.posts
|
|
||||||
catch err
|
|
||||||
console.error 'Navigate failure:'
|
|
||||||
console.log err
|
|
||||||
# network error or non-JSON content for example.
|
|
||||||
if notice
|
|
||||||
notice.setType 'error'
|
|
||||||
notice.el.lastElementChild.textContent = 'Navigation Failed.'
|
|
||||||
setTimeout notice.close, 2 * $.SECOND
|
|
||||||
else
|
|
||||||
new Notice 'error', 'Navigation Failed.', 2
|
|
||||||
return
|
|
||||||
|
|
||||||
parse: (data) ->
|
|
||||||
posts = []
|
|
||||||
errors = null
|
|
||||||
board = g.BOARD
|
|
||||||
threadRoot = Build.thread board, OP = data[0], true
|
|
||||||
thread = new Thread OP.no, board
|
|
||||||
|
|
||||||
makePost = (postNode) ->
|
|
||||||
try
|
|
||||||
posts.push new Post postNode, thread, board
|
|
||||||
catch err
|
|
||||||
# Skip posts that we failed to parse.
|
|
||||||
errors = [] unless errors
|
|
||||||
errors.push
|
|
||||||
message: "Parsing of Post No.#{postNode.ID} failed. Post will be skipped."
|
|
||||||
error: err
|
|
||||||
|
|
||||||
makePost $('.opContainer', threadRoot)
|
|
||||||
|
|
||||||
i = 0
|
|
||||||
while obj = data[++i]
|
|
||||||
post = Build.postFromObject obj, board
|
|
||||||
makePost post
|
|
||||||
$.add threadRoot, post
|
|
||||||
|
|
||||||
Main.callbackNodes Thread, [thread]
|
|
||||||
Main.callbackNodes Post, posts
|
|
||||||
|
|
||||||
QuoteThreading.force() if Conf['Quote Threading'] and not Conf['Unread Count']
|
|
||||||
|
|
||||||
board = $ '.board'
|
|
||||||
$.rmAll board
|
|
||||||
$.add board, [threadRoot, $.el 'hr']
|
|
||||||
|
|
||||||
Unread.ready() if Conf['Unread Count']
|
|
||||||
|
|
||||||
QR.generatePostableThreadsList() if Conf['Quick Reply']
|
|
||||||
Header.hashScroll.call window
|
|
||||||
|
|
||||||
Main.handleErrors errors if errors
|
|
||||||
|
|
||||||
pushState: (path) ->
|
|
||||||
history.pushState null, '', path
|
|
||||||
Navigate.path = window.location.pathname
|
|
||||||
|
|
||||||
popstate: ->
|
|
||||||
a = $.el 'a',
|
|
||||||
href: window.location
|
|
||||||
id: 'popState'
|
|
||||||
|
|
||||||
Navigate.navigate.call a
|
|
||||||
@ -471,8 +471,7 @@ div.center:not(.ad-cnt) {
|
|||||||
/* Index */
|
/* Index */
|
||||||
:root.index-loading .navLinks,
|
:root.index-loading .navLinks,
|
||||||
:root.index-loading .board,
|
:root.index-loading .board,
|
||||||
:root.index-loading .pagelist,
|
:root.index-loading .pagelist {
|
||||||
:root.thread .pagelist {
|
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
#index-search {
|
#index-search {
|
||||||
@ -498,15 +497,6 @@ div.center:not(.ad-cnt) {
|
|||||||
.summary {
|
.summary {
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
}
|
}
|
||||||
.index .returnlink,
|
|
||||||
.index .bottomlink,
|
|
||||||
.index .navLinksBot,
|
|
||||||
.index .navLinksBot + hr,
|
|
||||||
.thread #index-last-refresh,
|
|
||||||
.thread #index-search-clear,
|
|
||||||
.thread #index-search {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Announcement Hiding */
|
/* Announcement Hiding */
|
||||||
:root.hide-announcement #globalMessage {
|
:root.hide-announcement #globalMessage {
|
||||||
|
|||||||
@ -1,3 +0,0 @@
|
|||||||
<span class="brackets-wrap returnlink"><a href="javascript:;">Return</a></span>
|
|
||||||
<span class="brackets-wrap cataloglink"><a href="javascript:;">Catalog</a></span>
|
|
||||||
<span class="brackets-wrap toplink"><a href="#top">Top</a></span>
|
|
||||||
@ -25,13 +25,12 @@ ThreadUpdater =
|
|||||||
$.on @timer, 'click', @update
|
$.on @timer, 'click', @update
|
||||||
$.on @status, 'click', @update
|
$.on @status, 'click', @update
|
||||||
|
|
||||||
unless Index.navLinksBot and $ '.updatelink', Index.navLinksBot
|
updateLink = $.el 'span',
|
||||||
updateLink = $.el 'span',
|
innerHTML: '<a href="javascript:;">Update</a>'
|
||||||
innerHTML: '<a href="javascript:;">Update</a>'
|
className: 'brackets-wrap updatelink'
|
||||||
className: 'brackets-wrap updatelink'
|
$.ready ->
|
||||||
$.ready ->
|
$.add $('.navLinksBot'), [$.tn(' '), updateLink]
|
||||||
$.add (Index.navLinksBot or $('.navLinksBot')), [$.tn(' '), updateLink]
|
$.on updateLink.firstElementChild, 'click', @update
|
||||||
$.on updateLink.firstElementChild, 'click', @update
|
|
||||||
|
|
||||||
subEntries = []
|
subEntries = []
|
||||||
for name, conf of Config.updater.checkbox
|
for name, conf of Config.updater.checkbox
|
||||||
|
|||||||
@ -56,7 +56,7 @@ QR =
|
|||||||
if Conf['QR Shortcut']
|
if Conf['QR Shortcut']
|
||||||
$.rmClass $('.qr-shortcut'), 'disabled'
|
$.rmClass $('.qr-shortcut'), 'disabled'
|
||||||
|
|
||||||
if Conf['Bottom QR Link'] and (g.VIEW is 'thread' or Conf['JSON Navigation'])
|
if Conf['Bottom QR Link'] and g.VIEW is 'thread'
|
||||||
linkBot = $.el 'div',
|
linkBot = $.el 'div',
|
||||||
innerHTML: '<a href="javascript:;" class="qr-link-bottom">Reply to Thread</a>'
|
innerHTML: '<a href="javascript:;" class="qr-link-bottom">Reply to Thread</a>'
|
||||||
className: "brackets-wrap qr-link-container-bottom"
|
className: "brackets-wrap qr-link-container-bottom"
|
||||||
@ -68,7 +68,7 @@ QR =
|
|||||||
if Conf['QR Shortcut']
|
if Conf['QR Shortcut']
|
||||||
$.rmClass $('.qr-shortcut'), 'disabled'
|
$.rmClass $('.qr-shortcut'), 'disabled'
|
||||||
|
|
||||||
$.prepend (Index.navLinksBot or $('.navLinksBot')), linkBot
|
$.prepend $('.navLinksBot'), linkBot
|
||||||
|
|
||||||
$.before $.id('togglePostFormLink'), link
|
$.before $.id('togglePostFormLink'), link
|
||||||
|
|
||||||
|
|||||||
@ -43,11 +43,6 @@ QuoteBacklink =
|
|||||||
if Conf['Quote Hash Navigation']
|
if Conf['Quote Hash Navigation']
|
||||||
hash = QuoteInline.qiQuote link, $.hasClass link, 'filtered'
|
hash = QuoteInline.qiQuote link, $.hasClass link, 'filtered'
|
||||||
nodes.push hash
|
nodes.push hash
|
||||||
if Conf['JSON Navigation']
|
|
||||||
if hash
|
|
||||||
Navigate.singleQuoteLink hash
|
|
||||||
else unless Conf['Quote Inlining']
|
|
||||||
Navigate.singleQuoteLink link
|
|
||||||
$.add container, nodes
|
$.add container, nodes
|
||||||
return
|
return
|
||||||
secondNode: ->
|
secondNode: ->
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user