4chan-x/src/General/Main.coffee
2014-12-09 00:28:38 -07:00

321 lines
11 KiB
CoffeeScript

Main =
init: ->
g.threads = new SimpleDict
g.posts = new SimpleDict
pathname = location.pathname.split '/'
g.BOARD = new Board pathname[1]
return if g.BOARD.ID in ['z', 'fk']
g.VIEW =
switch pathname[2]
when 'res', 'thread'
'thread'
when 'catalog'
'catalog'
else
'index'
if g.VIEW is 'catalog'
return Index.catalogSwitch()
if g.VIEW is 'thread'
g.THREADID = +pathname[3]
g.SLUG = pathname[4] if pathname[4]?
if pathname[2] isnt 'thread'
pathname[2] = 'thread'
history.replaceState null, '', pathname.slice(0,4).join('/') + location.hash
# flatten Config into Conf
# and get saved or default values
flatten = (parent, obj) ->
if obj instanceof Array
Conf[parent] = obj[0]
else if typeof obj is 'object'
for key, val of obj
flatten key, val
else # string or number
Conf[parent] = obj
return
flatten null, Config
for db in DataBoard.keys
Conf[db] = boards: {}
$.extend Conf,
'Enabled Mascots': []
'Enabled Mascots sfw': []
'Enabled Mascots nsfw': []
'Deleted Mascots': []
'Hidden Categories': ["Custom", "Questionable"]
'userThemes': {}
'userMascots': {}
'selectedArchives': {}
'CachedTitles': {}
$.get Conf, (items) ->
$.extend Conf, items
$.asap (-> Favicon.el = $ 'link[rel="shortcut icon"]', d.head), Main.initFeatures
initFeatures: ->
# Check if the current board we're on is SFW or not, so we can handle options that need to know that.
Favicon.el.type = 'image/x-icon'
{href} = Favicon.el
Favicon.SFW = /ws\.ico$/.test href
Favicon.default = href
g.TYPE = if Favicon.SFW then 'sfw' else 'nsfw'
$.extend Themes, Conf["userThemes"]
$.extend Mascots, Conf["userMascots"]
return if g.BOARD.ID in ['z', 'fk'] then Style.init()
Main.setThemeString()
Main.setMascotString()
switch location.hostname
when '4chan.org', 'www.4chan.org'
g.TYPE = 'sfw'
g.VIEW = 'home'
Main.setThemeString()
Style.init()
return
when 'sys.4chan.org'
g.VIEW = 'report'
Style.init()
Report.init()
return
when 'i.4cdn.org'
$.ready ->
if Conf['404 Redirect'] and d.title in ['4chan - Temporarily Offline', '4chan - 404 Not Found']
Redirect.init()
pathname = location.pathname.split '/'
URL = Redirect.to 'file',
boardID: g.BOARD.ID
filename: pathname[pathname.length - 1]
location.replace URL if URL
else if Conf['Loop in New Tab'] and video = $ 'video'
Video.configure video
if !video.controls
$.on video, 'click', ->
if video.paused then video.play() else video.pause()
return
# c.time 'All initializations'
init = (name, feature) ->
# c.time "#{name} initialization"
try
feature.init()
catch err
Main.handleErrors
message: "\"#{name}\" initialization crashed."
error: err
# finally
# c.timeEnd "#{name} initialization"
# c.timeEnd 'All initializations'
init 'Style', Style
init 'Mascots', MascotTools
init 'Rice', Rice
init 'Announcements', GlobalMessage
init 'Polyfill', Polyfill
init 'Redirect', Redirect
init 'Header', Header
init 'Catalog Links', CatalogLinks
init 'Settings', Settings
init 'Index Generator', Index
init 'Announcement Hiding', PSAHiding
init 'Fourchan thingies', Fourchan
init 'Color User IDs', IDColor
init 'Custom CSS', CustomCSS
init 'Linkify', Linkify
init 'Reveal Spoilers', RemoveSpoilers
init 'Resurrect Quotes', Quotify
init 'Filter', Filter
init 'Reply Hiding Buttons', PostHiding
init 'Recursive', Recursive
init 'Strike-through Quotes', QuoteStrikeThrough
init 'Quick Reply', QR
init 'Menu', Menu
init 'Report Link', ReportLink
init 'Reply Hiding (Menu)', PostHiding.menu
init 'Delete Link', DeleteLink
init 'Filter (Menu)', Filter.menu
init 'Download Link', DownloadLink
init 'Archive Link', ArchiveLink
init 'Quote Inlining', QuoteInline
init 'Quote Previewing', QuotePreview
init 'Quote Backlinks', QuoteBacklink
init 'Quote Markers', QuoteMarkers
init 'Anonymize', Anonymize
init 'Time Formatting', Time
init 'Relative Post Dates', RelativeDates
init 'File Info Formatting', FileInfo
init 'Fappe Tyme', FappeTyme
init 'Gallery', Gallery
init 'Gallery (menu)', Gallery.menu
init 'Sauce', Sauce
init 'Image Expansion', ImageExpand
init 'Image Expansion (Menu)', ImageExpand.menu
init 'Reveal Spoiler Thumbnails', RevealSpoilers
init 'Image Loading', ImageLoader
init 'Image Hover', ImageHover
init 'Thread Expansion', ExpandThread
init 'Comment Expansion', ExpandComment
init 'Thread Excerpt', ThreadExcerpt
init 'Favicon', Favicon
init 'Unread', Unread
init 'Quote Threading', QuoteThreading
init 'Thread Stats', ThreadStats
init 'Thread Updater', ThreadUpdater
init 'Thread Watcher', ThreadWatcher
init 'Thread Watcher (Menu)', ThreadWatcher.menu
init 'Mark New IPs', MarkNewIPs
init 'Index Navigation', Nav
init 'Keybinds', Keybinds
init 'Show Dice Roll', Dice
init 'Banner', Banner
init 'Navigate', Navigate
init 'Flash Features', Flash
$.ready Main.initReady
initReady: ->
if d.title in ['4chan - Temporarily Offline', '4chan - 404 Not Found']
if Conf['404 Redirect'] and g.VIEW is 'thread'
href = Redirect.to 'thread',
boardID: g.BOARD.ID
threadID: g.THREADID
postID: +location.hash.match /\d+/ # post number or 0
location.replace href or "/#{g.BOARD}/"
return
if styleSelector = $.id 'styleSelector'
passLink = $.el 'a',
textContent: '4chan Pass'
href: 'javascript:;'
$.on passLink, 'click', ->
window.open '//sys.4chan.org/auth',
'This will steal your data.'
'left=0,top=0,width=500,height=255,toolbar=0,resizable=0'
$.before styleSelector.previousSibling, [$.tn '['; passLink, $.tn ']\u00A0\u00A0']
# Completely disable the mobile layout
$('link[href*="mobile"]', d.head).disabled = true
# Parse HTML or skip it and start building from JSON.
if !Conf['JSON Navigation'] or g.VIEW is 'thread'
Main.initThread()
# JSON Navigation may not load on a page that has flags, so force their CSS to always be available.
$.add d.head, $.el 'link',
href: "//s.4cdn.org/css/flags.556.css"
rel: "stylesheet"
$.event '4chanXInitFinished'
<% if (type === 'userscript') { %>
test = $.el 'span'
test.classList.add 'a', 'b'
if test.className isnt 'a b' and Conf['Show Support Message']
new Notice 'warning', "Your version of Firefox is outdated (v<%= meta.min.firefox %> minimum) and <%= meta.name %> may not operate correctly.", 30
GMver = GM_info.version.split '.'
for v, i in "<%= meta.min.greasemonkey %>".split '.'
continue if v is GMver[i]
(v < GMver[i]) or new Notice 'warning', "Your version of Greasemonkey is outdated (v#{GM_info.version} instead of v<%= meta.min.greasemonkey %> minimum) and <%= meta.name %> may not operate correctly.", 30
break
<% } %>
try
localStorage.getItem '4chan-settings'
catch err
new Notice 'warning', 'Cookies need to be enabled on 4chan for <%= meta.name %> to operate properly.', 30
initThread: ->
if board = $ '.board'
threads = []
posts = []
for threadRoot in $$ '.board > .thread', board
thread = new Thread +threadRoot.id[1..], g.BOARD
threads.push thread
for postRoot in $$ '.thread > .postContainer', threadRoot
try
posts.push new Post postRoot, thread, g.BOARD
catch err
# Skip posts that we failed to parse.
unless errors
errors = []
errors.push
message: "Parsing of Post No.#{postRoot.id.match(/\d+/)} failed. Post will be skipped."
error: err
Main.handleErrors errors if errors
Thread.callbacks.execute threads
Post.callbacks.execute posts
$.get 'previousversion', null, ({previousversion}) ->
return if previousversion is g.VERSION
if previousversion
changelog = '<%= meta.repo %>blob/<%= meta.mainBranch %>/CHANGELOG.md'
el = $.el 'span',
innerHTML: "<%= meta.name %> has been updated to <a href='#{changelog}' target=_blank>version #{g.VERSION}</a>."
new Notice 'info', el, 15
else
Settings.open()
$.set 'previousversion', g.VERSION
handleErrors: (errors) ->
unless errors instanceof Array
error = errors
else if errors.length is 1
error = errors[0]
if error
new Notice 'error', Main.parseError(error), 15
return
div = $.el 'div',
innerHTML: "#{errors.length} errors occurred. [<a href=javascript:;>show</a>]"
$.on div.lastElementChild, 'click', ->
[@textContent, logs.hidden] = if @textContent is 'show'
['hide', false]
else
['show', true]
logs = $.el 'div',
hidden: true
for error in errors
$.add logs, Main.parseError error
new Notice 'error', [div, logs], 30
parseError: (data) ->
c.error data.message, data.error.stack
message = $.el 'div',
textContent: data.message
error = $.el 'div',
textContent: data.error
[message, error]
isThisPageLegit: ->
# 404 error page or similar.
unless 'thisPageIsLegit' of Main
Main.thisPageIsLegit = location.hostname is 'boards.4chan.org' and
!$('link[href*="favicon-status.ico"]', d.head) and
d.title not in ['4chan - Temporarily Offline', '4chan - Error', '504 Gateway Time-out']
Main.thisPageIsLegit
setMascotString: ->
type = "Enabled Mascots"
if Conf["NSFW/SFW Mascots"]
type += " #{g.TYPE}"
g.MASCOTSTRING = type
setThemeString: ->
type = "theme"
if Conf["NSFW/SFW Themes"]
type += "_#{g.TYPE}"
g.THEMESTRING = type
Main.init()