This kills the script
No, seriously, this commit breaks everything if you open a reply. It's k, though, that's why this branch exists: so I can break it all without harming end users and stable development. Holy carp, though, the amount of errors thrown!
This commit is contained in:
parent
55763f4404
commit
0d29b42a02
@ -36,6 +36,7 @@ module.exports = (grunt) ->
|
|||||||
'src/Monitoring/**/*'
|
'src/Monitoring/**/*'
|
||||||
'src/Archive/**/*'
|
'src/Archive/**/*'
|
||||||
'src/Miscellaneous/**/*'
|
'src/Miscellaneous/**/*'
|
||||||
|
'src/General/Navigate.coffee'
|
||||||
'src/General/Settings.coffee'
|
'src/General/Settings.coffee'
|
||||||
'src/General/Main.coffee'
|
'src/General/Main.coffee'
|
||||||
]
|
]
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@ -102,7 +102,7 @@ Header =
|
|||||||
|
|
||||||
$.ready =>
|
$.ready =>
|
||||||
@footer = footer = $.id 'boardNavDesktopFoot'
|
@footer = footer = $.id 'boardNavDesktopFoot'
|
||||||
$.on a, 'click', Main.navigate for a in $$ 'a', footer
|
$.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'
|
||||||
|
|
||||||
@ -140,7 +140,7 @@ 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
|
||||||
$.on a, 'click', Main.navigate
|
$.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
|
||||||
@ -186,7 +186,7 @@ Header =
|
|||||||
if a.textContent is board
|
if a.textContent is board
|
||||||
a = a.cloneNode true
|
a = a.cloneNode true
|
||||||
|
|
||||||
$.on a, 'click', Main.navigate
|
$.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
|
||||||
|
|||||||
@ -146,8 +146,6 @@ Main =
|
|||||||
catch err
|
catch err
|
||||||
new Notice 'warning', 'Cookies need to be enabled on 4chan for <%= meta.name %> to operate properly.', 30
|
new Notice 'warning', 'Cookies need to be enabled on 4chan for <%= meta.name %> to operate properly.', 30
|
||||||
|
|
||||||
$.on window, 'popstate', Main.popstate
|
|
||||||
|
|
||||||
initThread: ->
|
initThread: ->
|
||||||
return unless threadRoot = $ '.thread'
|
return unless threadRoot = $ '.thread'
|
||||||
thread = new Thread +threadRoot.id[1..], g.BOARD
|
thread = new Thread +threadRoot.id[1..], g.BOARD
|
||||||
@ -321,123 +319,7 @@ Main =
|
|||||||
['Keybinds', Keybinds]
|
['Keybinds', Keybinds]
|
||||||
['Show Dice Roll', Dice]
|
['Show Dice Roll', Dice]
|
||||||
['Banner', Banner]
|
['Banner', Banner]
|
||||||
|
['Navigate', Navigate]
|
||||||
]
|
]
|
||||||
|
|
||||||
clean: ->
|
|
||||||
{posts, threads} = g
|
|
||||||
|
|
||||||
# Garbage collection
|
|
||||||
g.posts = {}
|
|
||||||
g.threads = {}
|
|
||||||
g.BOARD.posts = {}
|
|
||||||
g.BOARD.threads = {}
|
|
||||||
|
|
||||||
# Delete nodes
|
|
||||||
$.rmAll $ '.board'
|
|
||||||
|
|
||||||
disconnect: ->
|
|
||||||
if g.VIEW is 'thread'
|
|
||||||
features = [
|
|
||||||
['Thread Updater', ThreadUpdater]
|
|
||||||
['Unread Count', Unread]
|
|
||||||
['Quote Threading', QuoteThreading]
|
|
||||||
['Thread Stats', ThreadStats]
|
|
||||||
]
|
|
||||||
|
|
||||||
for [name, feature] in features
|
|
||||||
try
|
|
||||||
feature.disconnect.call feature
|
|
||||||
catch err
|
|
||||||
errors = [] unless errors
|
|
||||||
errors.push
|
|
||||||
message: "Failed to disconnect feature #{name}."
|
|
||||||
error: err
|
|
||||||
|
|
||||||
Main.handleErrors errors if errors
|
|
||||||
|
|
||||||
return
|
|
||||||
|
|
||||||
updateContext: (view) ->
|
|
||||||
$.rmClass doc, g.VIEW
|
|
||||||
$.addClass doc, view
|
|
||||||
g.VIEW = view
|
|
||||||
|
|
||||||
navigate: (e) ->
|
|
||||||
return if @hostname isnt 'boards.4chan.org' or window.location.hostname is 'rs.4chan.org'
|
|
||||||
|
|
||||||
path = @pathname.split '/'
|
|
||||||
path.shift() if path[0] is ''
|
|
||||||
[boardID, view, threadID] = path
|
|
||||||
|
|
||||||
return if view is 'catalog' or 'f' in [boardID, g.BOARD.ID]
|
|
||||||
|
|
||||||
e.preventDefault() if e
|
|
||||||
history.pushState null, '', @pathname unless @id is 'popState'
|
|
||||||
|
|
||||||
view = if threadID
|
|
||||||
'thread'
|
|
||||||
else
|
|
||||||
view or 'index' # path is "/boardID/". See the problem?
|
|
||||||
|
|
||||||
if view isnt g.VIEW
|
|
||||||
Main.disconnect()
|
|
||||||
Main.clean()
|
|
||||||
Main.updateContext view
|
|
||||||
|
|
||||||
if view is 'index'
|
|
||||||
Main.updateBoard boardID unless boardID is g.BOARD.ID
|
|
||||||
Index.update()
|
|
||||||
|
|
||||||
# Moving from index to thread or thread to thread
|
|
||||||
else
|
|
||||||
c.error 'How?'
|
|
||||||
Main.refresh {boardID, view, threadID}
|
|
||||||
|
|
||||||
Header.setBoardList()
|
|
||||||
|
|
||||||
popstate: -> <% if (type === 'crx') { %> Main.popstate = -> <% } %> # blink/webkit throw a popstate on page load. Not what we want.
|
|
||||||
a = $.el 'a',
|
|
||||||
href: window.location
|
|
||||||
id: 'popState'
|
|
||||||
|
|
||||||
Main.navigate.call a
|
|
||||||
|
|
||||||
updateBoard: (boardID) ->
|
|
||||||
g.BOARD = new Board boardID
|
|
||||||
|
|
||||||
req = null
|
|
||||||
|
|
||||||
onload = (e) ->
|
|
||||||
if e.type is 'abort'
|
|
||||||
req.onloadend = null
|
|
||||||
return
|
|
||||||
|
|
||||||
return unless req.status is 200
|
|
||||||
|
|
||||||
try
|
|
||||||
for board in JSON.parse(req.response).boards
|
|
||||||
return Main.updateTitle board if board.board is boardID
|
|
||||||
|
|
||||||
catch err
|
|
||||||
Main.handleErrors [
|
|
||||||
message: "Index Failure."
|
|
||||||
error: err
|
|
||||||
]
|
|
||||||
|
|
||||||
req = $.ajax '//a.4cdn.org/boards.json',
|
|
||||||
onabort: onload
|
|
||||||
onloadend: onload
|
|
||||||
|
|
||||||
updateTitle: (board) ->
|
|
||||||
$.rm subtitle if subtitle = $ '.boardSubtitle'
|
|
||||||
$('.boardTitle').innerHTML = d.title = "/#{board.board}/ - #{board.title}"
|
|
||||||
|
|
||||||
refresh: (context) ->
|
|
||||||
return
|
|
||||||
{boardID, view, threadID} = context
|
|
||||||
|
|
||||||
# Refresh features
|
|
||||||
feature.refresh() for [name, feature] in Main.features when feature.refresh
|
|
||||||
return
|
|
||||||
|
|
||||||
Main.init()
|
Main.init()
|
||||||
|
|||||||
212
src/General/Navigate.coffee
Normal file
212
src/General/Navigate.coffee
Normal file
@ -0,0 +1,212 @@
|
|||||||
|
Navigate =
|
||||||
|
init: ->
|
||||||
|
return if g.VIEW is 'catalog' or g.BOARD.ID is 'f'
|
||||||
|
$.on window, 'popstate', Navigate.popstate
|
||||||
|
|
||||||
|
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 exist in index view
|
||||||
|
replyLink = $ 'a.replylink', @OP.nodes.info
|
||||||
|
$.on replyLink, 'click', Navigate.navigate
|
||||||
|
|
||||||
|
post: ->
|
||||||
|
# We don't need to reload the thread inside the thread
|
||||||
|
return if g.VIEW is 'thread' and not @isClone
|
||||||
|
postLink = $ 'a[title="Highlight this post"]', @nodes.info
|
||||||
|
$.on postLink, 'click', Navigate.navigate
|
||||||
|
|
||||||
|
clean: ->
|
||||||
|
{posts, threads} = g
|
||||||
|
|
||||||
|
# Garbage collection
|
||||||
|
g.posts = {}
|
||||||
|
g.threads = {}
|
||||||
|
g.BOARD.posts = {}
|
||||||
|
g.BOARD.threads = {}
|
||||||
|
|
||||||
|
# Delete nodes
|
||||||
|
$.rmAll $ '.board'
|
||||||
|
|
||||||
|
disconnect: ->
|
||||||
|
features = if g.VIEW is 'thread'
|
||||||
|
[
|
||||||
|
['Thread Updater', ThreadUpdater]
|
||||||
|
['Unread Count', Unread]
|
||||||
|
['Quote Threading', QuoteThreading]
|
||||||
|
['Thread Stats', ThreadStats]
|
||||||
|
]
|
||||||
|
else
|
||||||
|
[]
|
||||||
|
|
||||||
|
for [name, feature] in features
|
||||||
|
try
|
||||||
|
feature.disconnect.call feature
|
||||||
|
catch err
|
||||||
|
errors = [] unless errors
|
||||||
|
errors.push
|
||||||
|
message: "Failed to disconnect feature #{name}."
|
||||||
|
error: err
|
||||||
|
|
||||||
|
Main.handleErrors errors if errors
|
||||||
|
|
||||||
|
return
|
||||||
|
|
||||||
|
updateContext: (view) ->
|
||||||
|
$.rmClass doc, g.VIEW
|
||||||
|
$.addClass doc, view
|
||||||
|
g.VIEW = view
|
||||||
|
|
||||||
|
navigate: (e) ->
|
||||||
|
return if @hostname isnt 'boards.4chan.org' or window.location.hostname is 'rs.4chan.org'
|
||||||
|
|
||||||
|
path = @pathname.split '/'
|
||||||
|
hash = @hash
|
||||||
|
path.shift() if path[0] is ''
|
||||||
|
[boardID, view, threadID] = path
|
||||||
|
|
||||||
|
return if view is 'catalog' or 'f' in [boardID, g.BOARD.ID]
|
||||||
|
|
||||||
|
e.preventDefault() if e
|
||||||
|
history.pushState null, '', @pathname unless @id is 'popState'
|
||||||
|
|
||||||
|
view = if threadID
|
||||||
|
'thread'
|
||||||
|
else
|
||||||
|
view or 'index' # path is "/boardID/". See the problem?
|
||||||
|
|
||||||
|
if view isnt g.VIEW
|
||||||
|
Navigate.disconnect()
|
||||||
|
Navigate.clean()
|
||||||
|
Navigate.updateContext view
|
||||||
|
|
||||||
|
if view is 'index'
|
||||||
|
Navigate.updateBoard boardID unless boardID is g.BOARD.ID
|
||||||
|
Index.update()
|
||||||
|
|
||||||
|
# Moving from index to thread or thread to thread
|
||||||
|
else
|
||||||
|
onload = (e) -> Navigate.load e, hash
|
||||||
|
Navigate.req = $.ajax "//a.4cdn.org/#{boardID}/res/#{threadID}.json",
|
||||||
|
onabort: onload
|
||||||
|
onloadend: onload
|
||||||
|
|
||||||
|
# Navigate.refresh {boardID, view, threadID}
|
||||||
|
|
||||||
|
load: (e) ->
|
||||||
|
$.rmClass Index.button, 'fa-spin'
|
||||||
|
{req, notice} = Navigate
|
||||||
|
delete Navigate.req
|
||||||
|
delete Navigate.notice
|
||||||
|
|
||||||
|
if e.type is 'abort'
|
||||||
|
req.onloadend = null
|
||||||
|
return
|
||||||
|
|
||||||
|
try
|
||||||
|
if req.status is 200
|
||||||
|
Navigate.parse JSON.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
|
||||||
|
|
||||||
|
Navigate.buildThread()
|
||||||
|
|
||||||
|
Header.scrollToIfNeeded $ '.board'
|
||||||
|
|
||||||
|
parse: (data) ->
|
||||||
|
threadRoot = Build.thread g.BOARD, data.shift(), true
|
||||||
|
thread = new Thread threadRoot, g.BOARD
|
||||||
|
|
||||||
|
nodes = [threadRoot]
|
||||||
|
posts = []
|
||||||
|
errors = null
|
||||||
|
|
||||||
|
makePost = (postNode) ->
|
||||||
|
try
|
||||||
|
posts.push new Post postNode, thread, g.BOARD
|
||||||
|
catch err
|
||||||
|
# Skip posts that we failed to parse.
|
||||||
|
errors = [] unless errors
|
||||||
|
errors.push
|
||||||
|
message: "Parsing of Post No.#{thread.ID} failed. Post will be skipped."
|
||||||
|
error: err
|
||||||
|
|
||||||
|
makePost $('.opContainer', threadRoot)
|
||||||
|
|
||||||
|
for obj in data
|
||||||
|
posts.push post = Build.postFromObject obj
|
||||||
|
makePost post
|
||||||
|
|
||||||
|
Main.handleErrors errors if errors
|
||||||
|
|
||||||
|
# Add the thread to a container to make sure all features work.
|
||||||
|
$.nodes Navigate.nodes = nodes
|
||||||
|
Main.callbackNodes Thread, [thread]
|
||||||
|
Main.callbackNodes Post, posts
|
||||||
|
|
||||||
|
buildThread: ->
|
||||||
|
board = $ '.board'
|
||||||
|
$.rmAll board
|
||||||
|
$.add board, Navigate.nodes
|
||||||
|
|
||||||
|
popstate: -> <% if (type === 'crx') { %> Navigate.popstate = -> <% } %> # blink/webkit throw a popstate on page load. Not what we want.
|
||||||
|
a = $.el 'a',
|
||||||
|
href: window.location
|
||||||
|
id: 'popState'
|
||||||
|
|
||||||
|
Navigate.navigate.call a
|
||||||
|
|
||||||
|
updateBoard: (boardID) ->
|
||||||
|
g.BOARD = new Board boardID
|
||||||
|
|
||||||
|
req = null
|
||||||
|
|
||||||
|
onload = (e) ->
|
||||||
|
if e.type is 'abort'
|
||||||
|
req.onloadend = null
|
||||||
|
return
|
||||||
|
|
||||||
|
return unless req.status is 200
|
||||||
|
|
||||||
|
try
|
||||||
|
for board in JSON.parse(req.response).boards
|
||||||
|
return Navigate.updateTitle board if board.board is boardID
|
||||||
|
|
||||||
|
catch err
|
||||||
|
Main.handleErrors [
|
||||||
|
message: "Navigation failed to update board name."
|
||||||
|
error: err
|
||||||
|
]
|
||||||
|
|
||||||
|
Header.setBoardList()
|
||||||
|
|
||||||
|
req = $.ajax '//a.4cdn.org/boards.json',
|
||||||
|
onabort: onload
|
||||||
|
onloadend: onload
|
||||||
|
|
||||||
|
updateTitle: (board) ->
|
||||||
|
$.rm subtitle if subtitle = $ '.boardSubtitle'
|
||||||
|
$('.boardTitle').innerHTML = d.title = "/#{board.board}/ - #{board.title}"
|
||||||
|
|
||||||
|
refresh: (context) ->
|
||||||
|
return
|
||||||
|
{boardID, view, threadID} = context
|
||||||
|
|
||||||
|
# Refresh features
|
||||||
|
feature.refresh() for [name, feature] in Main.features when feature.refresh
|
||||||
|
return
|
||||||
@ -3,24 +3,21 @@ class Callbacks
|
|||||||
@keys = []
|
@keys = []
|
||||||
|
|
||||||
push: ({name, cb}) ->
|
push: ({name, cb}) ->
|
||||||
@rm name if @[name]
|
@[name].connect() if @[name]
|
||||||
|
@keys.push name unless @[name]
|
||||||
@[name] = cb
|
@[name] = cb
|
||||||
@keys.push name
|
|
||||||
|
|
||||||
clean: ->
|
clean: ->
|
||||||
@rm name for name in @keys
|
@rm name for name in @keys
|
||||||
return
|
return
|
||||||
|
|
||||||
rm: (name) ->
|
connect: (name) -> delete @[name].disconnected if @[name]
|
||||||
return unless @[name]
|
disconnect: (name) -> @[name].disconnected = true if @[name]
|
||||||
delete @[name]
|
|
||||||
@keys.splice @keys.indexOf(name), 1 # Didn't I make this structure to avoid this? ;__;
|
|
||||||
|
|
||||||
execute: (node) ->
|
execute: (node) ->
|
||||||
for name in @keys
|
for name in @keys
|
||||||
try
|
try
|
||||||
@[name].call node
|
@[name].call node unless @[name].disconnected
|
||||||
catch err
|
catch err
|
||||||
errors = [] unless errors
|
errors = [] unless errors
|
||||||
errors.push
|
errors.push
|
||||||
|
|||||||
@ -10,7 +10,7 @@ class Thread
|
|||||||
@postLimit = false
|
@postLimit = false
|
||||||
@fileLimit = false
|
@fileLimit = false
|
||||||
|
|
||||||
g.threads[@fullID] = board.threads[@] = @
|
g.threads[@fullID] = board.threads[@ID] = @
|
||||||
|
|
||||||
setPage: (pageNum) ->
|
setPage: (pageNum) ->
|
||||||
icon = $ '.page-num', @OP.nodes.post
|
icon = $ '.page-num', @OP.nodes.post
|
||||||
|
|||||||
@ -50,7 +50,7 @@ ThreadStats =
|
|||||||
delete @fileCountEl
|
delete @fileCountEl
|
||||||
delete @pageCountEl
|
delete @pageCountEl
|
||||||
|
|
||||||
Thread.callbacks.rm 'Thread Stats'
|
Thread.callbacks.disconnect 'Thread Stats'
|
||||||
$.off d, 'ThreadUpdate', ThreadStats.onUpdate
|
$.off d, 'ThreadUpdate', ThreadStats.onUpdate
|
||||||
|
|
||||||
onUpdate: (e) ->
|
onUpdate: (e) ->
|
||||||
|
|||||||
@ -92,7 +92,7 @@ ThreadUpdater =
|
|||||||
|
|
||||||
delete @[name] for name in ['checkPostCount', 'timer', 'status', 'isUpdating', 'entry', 'dialog', 'thread', 'root', 'lastPost', 'outdateCount', 'online', 'seconds', 'timeoutID']
|
delete @[name] for name in ['checkPostCount', 'timer', 'status', 'isUpdating', 'entry', 'dialog', 'thread', 'root', 'lastPost', 'outdateCount', 'online', 'seconds', 'timeoutID']
|
||||||
|
|
||||||
Thread.callbacks.rm 'Thread Updater'
|
Thread.callbacks.disconnect 'Thread Updater'
|
||||||
|
|
||||||
node: ->
|
node: ->
|
||||||
ThreadUpdater.thread = @
|
ThreadUpdater.thread = @
|
||||||
|
|||||||
@ -28,7 +28,7 @@ Unread =
|
|||||||
$.off d, 'scroll visibilitychange', @read
|
$.off d, 'scroll visibilitychange', @read
|
||||||
$.off d, 'visibilitychange', @setLine if Conf['Unread Line']
|
$.off d, 'visibilitychange', @setLine if Conf['Unread Line']
|
||||||
|
|
||||||
Thread.callbacks.rm 'Unread'
|
Thread.callbacks.disconnect 'Unread'
|
||||||
|
|
||||||
node: ->
|
node: ->
|
||||||
Unread.thread = @
|
Unread.thread = @
|
||||||
|
|||||||
@ -34,7 +34,7 @@ QuoteThreading =
|
|||||||
delete @controls
|
delete @controls
|
||||||
delete @entry
|
delete @entry
|
||||||
|
|
||||||
Post.callbacks.rm 'Quote Threading'
|
Post.callbacks.disconnect 'Quote Threading'
|
||||||
|
|
||||||
setup: ->
|
setup: ->
|
||||||
$.off d, '4chanXInitFinished', QuoteThreading.setup
|
$.off d, '4chanXInitFinished', QuoteThreading.setup
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user