Add Notifications.
Add error handling. I don't feel like I did a good job of it, might revisit later.
This commit is contained in:
parent
b6cf7220c4
commit
8b836aec8d
459
4chan_x.user.js
459
4chan_x.user.js
File diff suppressed because one or more lines are too long
@ -35,25 +35,28 @@ a[href="javascript:;"] {
|
|||||||
#qr, #watcher {
|
#qr, #watcher {
|
||||||
position: fixed;
|
position: fixed;
|
||||||
}
|
}
|
||||||
#qp, #ihover {
|
#notifications {
|
||||||
z-index: 100;
|
|
||||||
}
|
|
||||||
#menu {
|
|
||||||
z-index: 95;
|
|
||||||
}
|
|
||||||
#updater, #stats {
|
|
||||||
z-index: 90;
|
|
||||||
}
|
|
||||||
#header:hover {
|
|
||||||
z-index: 80;
|
z-index: 80;
|
||||||
}
|
}
|
||||||
#qr {
|
#qp, #ihover {
|
||||||
|
z-index: 70;
|
||||||
|
}
|
||||||
|
#menu {
|
||||||
|
z-index: 60;
|
||||||
|
}
|
||||||
|
#updater, #stats {
|
||||||
z-index: 50;
|
z-index: 50;
|
||||||
}
|
}
|
||||||
#watcher {
|
#header:hover {
|
||||||
|
z-index: 40;
|
||||||
|
}
|
||||||
|
#qr {
|
||||||
z-index: 30;
|
z-index: 30;
|
||||||
}
|
}
|
||||||
#header {
|
#header {
|
||||||
|
z-index: 20;
|
||||||
|
}
|
||||||
|
#watcher {
|
||||||
z-index: 10;
|
z-index: 10;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -68,7 +71,7 @@ a[href="javascript:;"] {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* header */
|
/* header */
|
||||||
body.fourchan_x {
|
.fourchan_x body {
|
||||||
margin-top: 2em;
|
margin-top: 2em;
|
||||||
}
|
}
|
||||||
#header {
|
#header {
|
||||||
@ -85,6 +88,7 @@ body.fourchan_x {
|
|||||||
-webkit-transition: all .1s ease-in-out;
|
-webkit-transition: all .1s ease-in-out;
|
||||||
}
|
}
|
||||||
#header-bar.autohide:not(:hover) {
|
#header-bar.autohide:not(:hover) {
|
||||||
|
margin-bottom: -1em;
|
||||||
transform: translateY(-100%);
|
transform: translateY(-100%);
|
||||||
-o-transform: translateY(-100%);
|
-o-transform: translateY(-100%);
|
||||||
-moz-transform: translateY(-100%);
|
-moz-transform: translateY(-100%);
|
||||||
@ -119,6 +123,51 @@ body > #boardNavDesktop,
|
|||||||
display: none !important;
|
display: none !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* notifications */
|
||||||
|
#notifications {
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
.notification {
|
||||||
|
color: #FFF;
|
||||||
|
font-weight: 700;
|
||||||
|
text-shadow: 0 1px 2px rgba(0, 0, 0, .5);
|
||||||
|
border-radius: 2px;
|
||||||
|
margin: 1px auto;
|
||||||
|
width: 500px;
|
||||||
|
max-width: 100%;
|
||||||
|
position: relative;
|
||||||
|
transition: all .25s ease-in-out;
|
||||||
|
-o-transition: all .25s ease-in-out;
|
||||||
|
-moz-transition: all .25s ease-in-out;
|
||||||
|
-webkit-transition: all .25s ease-in-out;
|
||||||
|
}
|
||||||
|
.notification.error {
|
||||||
|
background-color: hsl(0, 100%, 40%);
|
||||||
|
}
|
||||||
|
.notification.warning {
|
||||||
|
background-color: hsl(36, 100%, 40%);
|
||||||
|
}
|
||||||
|
.notification.info {
|
||||||
|
background-color: hsl(200, 100%, 40%);
|
||||||
|
}
|
||||||
|
.notification.success {
|
||||||
|
background-color: hsl(104, 100%, 40%);
|
||||||
|
}
|
||||||
|
.notification > .close {
|
||||||
|
color: white;
|
||||||
|
padding: 4px 6px;
|
||||||
|
top: 0;
|
||||||
|
right: 0;
|
||||||
|
position: absolute;
|
||||||
|
}
|
||||||
|
.message {
|
||||||
|
box-sizing: border-box;
|
||||||
|
padding: 4px 20px;
|
||||||
|
max-height: 200px;
|
||||||
|
width: 100%;
|
||||||
|
overflow: auto;
|
||||||
|
}
|
||||||
|
|
||||||
/* thread updater */
|
/* thread updater */
|
||||||
#updater {
|
#updater {
|
||||||
text-align: right;
|
text-align: right;
|
||||||
|
|||||||
@ -22,7 +22,7 @@ $.extend $,
|
|||||||
id: (id) ->
|
id: (id) ->
|
||||||
d.getElementById id
|
d.getElementById id
|
||||||
ready: (fc) ->
|
ready: (fc) ->
|
||||||
if /interactive|complete/.test d.readyState
|
if d.readyState in ['interactive', 'complete']
|
||||||
$.queueTask fc
|
$.queueTask fc
|
||||||
return
|
return
|
||||||
cb = ->
|
cb = ->
|
||||||
@ -106,9 +106,6 @@ $.extend $,
|
|||||||
tn: (s) ->
|
tn: (s) ->
|
||||||
d.createTextNode s
|
d.createTextNode s
|
||||||
nodes: (nodes) ->
|
nodes: (nodes) ->
|
||||||
# In (at least) Chrome, elements created inside different
|
|
||||||
# scripts/window contexts inherit from unequal prototypes.
|
|
||||||
# window_context1.Node !== window_context2.Node
|
|
||||||
unless nodes instanceof Array
|
unless nodes instanceof Array
|
||||||
return nodes
|
return nodes
|
||||||
frag = d.createDocumentFragment()
|
frag = d.createDocumentFragment()
|
||||||
|
|||||||
@ -57,8 +57,8 @@ Config =
|
|||||||
'Quote Preview': [true, 'Show quoted post on hover.']
|
'Quote Preview': [true, 'Show quoted post on hover.']
|
||||||
'Quote Highlighting': [true, 'Highlight the previewed post.']
|
'Quote Highlighting': [true, 'Highlight the previewed post.']
|
||||||
'Resurrect Quotes': [true, 'Linkify dead quotes to archives.']
|
'Resurrect Quotes': [true, 'Linkify dead quotes to archives.']
|
||||||
'Indicate OP Quotes': [true, 'Add \'(OP)\' to OP quotes.']
|
'Mark OP Quotes': [true, 'Add \'(OP)\' to OP quotes.']
|
||||||
'Indicate Cross-thread Quotes': [true, 'Add \'(Cross-thread)\' to cross-threads quotes.']
|
'Mark Cross-thread Quotes': [true, 'Add \'(Cross-thread)\' to cross-threads quotes.']
|
||||||
filter:
|
filter:
|
||||||
name: [
|
name: [
|
||||||
'# Filter any namefags:'
|
'# Filter any namefags:'
|
||||||
|
|||||||
@ -40,8 +40,9 @@ Header =
|
|||||||
try
|
try
|
||||||
@setBoardList()
|
@setBoardList()
|
||||||
catch err
|
catch err
|
||||||
# XXX handle error
|
Main.handleErrors
|
||||||
$.log err, 'Header - board list'
|
message: '"Header (board list)" crashed.'
|
||||||
|
error: err
|
||||||
|
|
||||||
$.asap (-> d.body), ->
|
$.asap (-> d.body), ->
|
||||||
$.prepend d.body, Header.headerEl
|
$.prepend d.body, Header.headerEl
|
||||||
@ -74,6 +75,31 @@ Header =
|
|||||||
menuToggle: (e) ->
|
menuToggle: (e) ->
|
||||||
Header.menu.toggle e, @, g
|
Header.menu.toggle e, @, g
|
||||||
|
|
||||||
|
class Notification
|
||||||
|
constructor: (@type, content, timeout) ->
|
||||||
|
@el = $.el 'div',
|
||||||
|
className: "notification #{type}"
|
||||||
|
innerHTML: '<a href=javascript:; class=close title=Close>×</a><div class=message></div>'
|
||||||
|
$.on @el.firstElementChild, 'click', @close.bind @
|
||||||
|
if typeof content is 'string'
|
||||||
|
content = $.tn content
|
||||||
|
$.add @el.lastElementChild, content
|
||||||
|
|
||||||
|
if timeout
|
||||||
|
setTimeout @close.bind(@), timeout * $.SECOND
|
||||||
|
|
||||||
|
el = @el
|
||||||
|
$.ready ->
|
||||||
|
$.add $.id('notifications'), el
|
||||||
|
|
||||||
|
setType: (type) ->
|
||||||
|
$.rmClass @el, @type
|
||||||
|
$.addClass @el, type
|
||||||
|
@type = type
|
||||||
|
|
||||||
|
close: ->
|
||||||
|
$.rm @el
|
||||||
|
|
||||||
Settings =
|
Settings =
|
||||||
init: ->
|
init: ->
|
||||||
# 4chan X settings link
|
# 4chan X settings link
|
||||||
@ -107,6 +133,8 @@ Settings =
|
|||||||
Filter =
|
Filter =
|
||||||
filters: {}
|
filters: {}
|
||||||
init: ->
|
init: ->
|
||||||
|
return if g.VIEW is 'catalog' or !Conf['Filter']
|
||||||
|
|
||||||
for key of Config.filter
|
for key of Config.filter
|
||||||
@filters[key] = []
|
@filters[key] = []
|
||||||
for filter in Conf[key].split '\n'
|
for filter in Conf[key].split '\n'
|
||||||
@ -134,8 +162,7 @@ Filter =
|
|||||||
regexp = RegExp regexp[1], regexp[2]
|
regexp = RegExp regexp[1], regexp[2]
|
||||||
catch err
|
catch err
|
||||||
# I warned you, bro.
|
# I warned you, bro.
|
||||||
# XXX handle error
|
new Notification 'warning', err.message, 60
|
||||||
alert err.message
|
|
||||||
continue
|
continue
|
||||||
|
|
||||||
# Filter OPs along with their threads, replies only, or both.
|
# Filter OPs along with their threads, replies only, or both.
|
||||||
@ -274,6 +301,8 @@ Filter =
|
|||||||
|
|
||||||
menu:
|
menu:
|
||||||
init: ->
|
init: ->
|
||||||
|
return if g.VIEW is 'catalog' or !Conf['Menu'] or !Conf['Filter']
|
||||||
|
|
||||||
div = $.el 'div',
|
div = $.el 'div',
|
||||||
textContent: 'Filter'
|
textContent: 'Filter'
|
||||||
|
|
||||||
@ -376,7 +405,8 @@ Filter =
|
|||||||
|
|
||||||
ThreadHiding =
|
ThreadHiding =
|
||||||
init: ->
|
init: ->
|
||||||
return if g.VIEW isnt 'index'
|
return if g.VIEW isnt 'index' or !Conf['Thread Hiding']
|
||||||
|
|
||||||
@getHiddenThreads()
|
@getHiddenThreads()
|
||||||
@syncFromCatalog()
|
@syncFromCatalog()
|
||||||
@clean()
|
@clean()
|
||||||
@ -438,7 +468,8 @@ ThreadHiding =
|
|||||||
|
|
||||||
menu:
|
menu:
|
||||||
init: ->
|
init: ->
|
||||||
return if g.VIEW isnt 'index'
|
return if g.VIEW isnt 'index' or !Conf['Menu'] or !Conf['Thread Hiding']
|
||||||
|
|
||||||
div = $.el 'div',
|
div = $.el 'div',
|
||||||
className: 'hide-thread-link'
|
className: 'hide-thread-link'
|
||||||
textContent: 'Hide thread'
|
textContent: 'Hide thread'
|
||||||
@ -535,6 +566,8 @@ ThreadHiding =
|
|||||||
|
|
||||||
ReplyHiding =
|
ReplyHiding =
|
||||||
init: ->
|
init: ->
|
||||||
|
return if g.VIEW is 'catalog' or !Conf['Reply Hiding']
|
||||||
|
|
||||||
@getHiddenPosts()
|
@getHiddenPosts()
|
||||||
@clean()
|
@clean()
|
||||||
Post::callbacks.push
|
Post::callbacks.push
|
||||||
@ -583,6 +616,8 @@ ReplyHiding =
|
|||||||
|
|
||||||
menu:
|
menu:
|
||||||
init: ->
|
init: ->
|
||||||
|
return if g.VIEW is 'catalog' or !Conf['Menu'] or !Conf['Reply Hiding']
|
||||||
|
|
||||||
div = $.el 'div',
|
div = $.el 'div',
|
||||||
className: 'hide-reply-link'
|
className: 'hide-reply-link'
|
||||||
textContent: 'Hide reply'
|
textContent: 'Hide reply'
|
||||||
@ -726,6 +761,8 @@ Recursive =
|
|||||||
|
|
||||||
Menu =
|
Menu =
|
||||||
init: ->
|
init: ->
|
||||||
|
return if g.VIEW is 'catalog' or !Conf['Menu']
|
||||||
|
|
||||||
@menu = new UI.Menu 'post'
|
@menu = new UI.Menu 'post'
|
||||||
Post::callbacks.push
|
Post::callbacks.push
|
||||||
name: 'Menu'
|
name: 'Menu'
|
||||||
@ -758,6 +795,8 @@ Menu =
|
|||||||
|
|
||||||
ReportLink =
|
ReportLink =
|
||||||
init: ->
|
init: ->
|
||||||
|
return if g.VIEW is 'catalog' or !Conf['Menu'] or !Conf['Report Link']
|
||||||
|
|
||||||
a = $.el 'a',
|
a = $.el 'a',
|
||||||
className: 'report-link'
|
className: 'report-link'
|
||||||
href: 'javascript:;'
|
href: 'javascript:;'
|
||||||
@ -777,6 +816,8 @@ ReportLink =
|
|||||||
|
|
||||||
DeleteLink =
|
DeleteLink =
|
||||||
init: ->
|
init: ->
|
||||||
|
return if g.VIEW is 'catalog' or !Conf['Menu'] or !Conf['Delete Link']
|
||||||
|
|
||||||
div = $.el 'div',
|
div = $.el 'div',
|
||||||
className: 'delete-link'
|
className: 'delete-link'
|
||||||
textContent: 'Delete'
|
textContent: 'Delete'
|
||||||
@ -881,6 +922,8 @@ DeleteLink =
|
|||||||
|
|
||||||
DownloadLink =
|
DownloadLink =
|
||||||
init: ->
|
init: ->
|
||||||
|
return if g.VIEW is 'catalog' or !Conf['Menu'] or !Conf['Download Link']
|
||||||
|
|
||||||
# Test for download feature support.
|
# Test for download feature support.
|
||||||
return if $.el('a').download is undefined
|
return if $.el('a').download is undefined
|
||||||
a = $.el 'a',
|
a = $.el 'a',
|
||||||
@ -896,6 +939,8 @@ DownloadLink =
|
|||||||
|
|
||||||
ArchiveLink =
|
ArchiveLink =
|
||||||
init: ->
|
init: ->
|
||||||
|
return if g.VIEW is 'catalog' or !Conf['Menu'] or !Conf['Archive Link']
|
||||||
|
|
||||||
div = $.el 'div',
|
div = $.el 'div',
|
||||||
textContent: 'Archive'
|
textContent: 'Archive'
|
||||||
|
|
||||||
@ -1554,6 +1599,8 @@ Get =
|
|||||||
|
|
||||||
Quotify =
|
Quotify =
|
||||||
init: ->
|
init: ->
|
||||||
|
return if g.VIEW is 'catalog' or !Conf['Resurrect Quotes']
|
||||||
|
|
||||||
Post::callbacks.push
|
Post::callbacks.push
|
||||||
name: 'Resurrect Quotes'
|
name: 'Resurrect Quotes'
|
||||||
cb: @node
|
cb: @node
|
||||||
@ -1621,6 +1668,8 @@ Quotify =
|
|||||||
|
|
||||||
QuoteInline =
|
QuoteInline =
|
||||||
init: ->
|
init: ->
|
||||||
|
return if g.VIEW is 'catalog' or !Conf['Quote Inline']
|
||||||
|
|
||||||
Post::callbacks.push
|
Post::callbacks.push
|
||||||
name: 'Quote Inline'
|
name: 'Quote Inline'
|
||||||
cb: @node
|
cb: @node
|
||||||
@ -1701,6 +1750,8 @@ QuoteInline =
|
|||||||
|
|
||||||
QuotePreview =
|
QuotePreview =
|
||||||
init: ->
|
init: ->
|
||||||
|
return if g.VIEW is 'catalog' or !Conf['Quote Preview']
|
||||||
|
|
||||||
Post::callbacks.push
|
Post::callbacks.push
|
||||||
name: 'Quote Preview'
|
name: 'Quote Preview'
|
||||||
cb: @node
|
cb: @node
|
||||||
@ -1767,6 +1818,8 @@ QuoteBacklink =
|
|||||||
# This is is so that fetched posts can get their backlinks,
|
# This is is so that fetched posts can get their backlinks,
|
||||||
# and that as much backlinks are appended in the background as possible.
|
# and that as much backlinks are appended in the background as possible.
|
||||||
init: ->
|
init: ->
|
||||||
|
return if g.VIEW is 'catalog' or !Conf['Quote Backlinks']
|
||||||
|
|
||||||
format = Conf['backlink'].replace /%id/g, "' + id + '"
|
format = Conf['backlink'].replace /%id/g, "' + id + '"
|
||||||
@funk = Function 'id', "return '#{format}'"
|
@funk = Function 'id', "return '#{format}'"
|
||||||
@containers = {}
|
@containers = {}
|
||||||
@ -1810,10 +1863,12 @@ QuoteBacklink =
|
|||||||
|
|
||||||
QuoteOP =
|
QuoteOP =
|
||||||
init: ->
|
init: ->
|
||||||
|
return if g.VIEW is 'catalog' or !Conf['Mark OP Quotes']
|
||||||
|
|
||||||
# \u00A0 is nbsp
|
# \u00A0 is nbsp
|
||||||
@text = '\u00A0(OP)'
|
@text = '\u00A0(OP)'
|
||||||
Post::callbacks.push
|
Post::callbacks.push
|
||||||
name: 'Indicate OP Quotes'
|
name: 'Mark OP Quotes'
|
||||||
cb: @node
|
cb: @node
|
||||||
node: ->
|
node: ->
|
||||||
# Stop there if it's a clone of a post in the same thread.
|
# Stop there if it's a clone of a post in the same thread.
|
||||||
@ -1838,10 +1893,12 @@ QuoteOP =
|
|||||||
|
|
||||||
QuoteCT =
|
QuoteCT =
|
||||||
init: ->
|
init: ->
|
||||||
|
return if g.VIEW is 'catalog' or !Conf['Mark Cross-thread Quotes']
|
||||||
|
|
||||||
# \u00A0 is nbsp
|
# \u00A0 is nbsp
|
||||||
@text = '\u00A0(Cross-thread)'
|
@text = '\u00A0(Cross-thread)'
|
||||||
Post::callbacks.push
|
Post::callbacks.push
|
||||||
name: 'Indicate Cross-thread Quotes'
|
name: 'Mark Cross-thread Quotes'
|
||||||
cb: @node
|
cb: @node
|
||||||
node: ->
|
node: ->
|
||||||
# Stop there if it's a clone of a post in the same thread.
|
# Stop there if it's a clone of a post in the same thread.
|
||||||
@ -1862,6 +1919,8 @@ QuoteCT =
|
|||||||
|
|
||||||
Anonymize =
|
Anonymize =
|
||||||
init: ->
|
init: ->
|
||||||
|
return if g.VIEW is 'catalog' or !Conf['Anonymize']
|
||||||
|
|
||||||
Post::callbacks.push
|
Post::callbacks.push
|
||||||
name: 'Anonymize'
|
name: 'Anonymize'
|
||||||
cb: @node
|
cb: @node
|
||||||
@ -1882,6 +1941,8 @@ Anonymize =
|
|||||||
|
|
||||||
Time =
|
Time =
|
||||||
init: ->
|
init: ->
|
||||||
|
return if g.VIEW is 'catalog' or !Conf['Time Formatting']
|
||||||
|
|
||||||
@funk = @createFunc Conf['time']
|
@funk = @createFunc Conf['time']
|
||||||
Post::callbacks.push
|
Post::callbacks.push
|
||||||
name: 'Time Formatting'
|
name: 'Time Formatting'
|
||||||
@ -1940,6 +2001,8 @@ Time =
|
|||||||
|
|
||||||
FileInfo =
|
FileInfo =
|
||||||
init: ->
|
init: ->
|
||||||
|
return if g.VIEW is 'catalog' or !Conf['File Info Formatting']
|
||||||
|
|
||||||
@funk = @createFunc Conf['fileInfo']
|
@funk = @createFunc Conf['fileInfo']
|
||||||
Post::callbacks.push
|
Post::callbacks.push
|
||||||
name: 'File Info Formatting'
|
name: 'File Info Formatting'
|
||||||
@ -1990,6 +2053,8 @@ FileInfo =
|
|||||||
|
|
||||||
Sauce =
|
Sauce =
|
||||||
init: ->
|
init: ->
|
||||||
|
return if g.VIEW is 'catalog' or !Conf['Sauce']
|
||||||
|
|
||||||
links = []
|
links = []
|
||||||
for link in Conf['sauces'].split '\n'
|
for link in Conf['sauces'].split '\n'
|
||||||
continue if link[0] is '#'
|
continue if link[0] is '#'
|
||||||
@ -2031,6 +2096,8 @@ Sauce =
|
|||||||
|
|
||||||
RevealSpoilers =
|
RevealSpoilers =
|
||||||
init: ->
|
init: ->
|
||||||
|
return if g.VIEW is 'catalog' or !Conf['Reveal Spoilers']
|
||||||
|
|
||||||
Post::callbacks.push
|
Post::callbacks.push
|
||||||
name: 'Reveal Spoilers'
|
name: 'Reveal Spoilers'
|
||||||
cb: @node
|
cb: @node
|
||||||
@ -2042,7 +2109,8 @@ RevealSpoilers =
|
|||||||
|
|
||||||
AutoGIF =
|
AutoGIF =
|
||||||
init: ->
|
init: ->
|
||||||
return if g.BOARD.ID in ['gif', 'wsg']
|
return if g.VIEW is 'catalog' or !Conf['Auto-GIF'] or g.BOARD.ID in ['gif', 'wsg']
|
||||||
|
|
||||||
Post::callbacks.push
|
Post::callbacks.push
|
||||||
name: 'Auto-GIF'
|
name: 'Auto-GIF'
|
||||||
cb: @node
|
cb: @node
|
||||||
@ -2062,7 +2130,8 @@ AutoGIF =
|
|||||||
|
|
||||||
ImageHover =
|
ImageHover =
|
||||||
init: ->
|
init: ->
|
||||||
return if g.BOARD.ID in ['gif', 'wsg']
|
return if g.VIEW is 'catalog' or !Conf['Image Hover']
|
||||||
|
|
||||||
Post::callbacks.push
|
Post::callbacks.push
|
||||||
name: 'Auto-GIF'
|
name: 'Auto-GIF'
|
||||||
cb: @node
|
cb: @node
|
||||||
@ -2101,7 +2170,8 @@ ImageHover =
|
|||||||
|
|
||||||
ThreadUpdater =
|
ThreadUpdater =
|
||||||
init: ->
|
init: ->
|
||||||
return if g.VIEW isnt 'thread'
|
return if g.VIEW isnt 'thread' or !Conf['Thread Updater']
|
||||||
|
|
||||||
Thread::callbacks.push
|
Thread::callbacks.push
|
||||||
name: 'Thread Updater'
|
name: 'Thread Updater'
|
||||||
cb: @node
|
cb: @node
|
||||||
|
|||||||
304
src/main.coffee
304
src/main.coffee
@ -277,211 +277,56 @@ Main =
|
|||||||
location.href = url if url
|
location.href = url if url
|
||||||
return
|
return
|
||||||
|
|
||||||
return if g.VIEW is 'catalog'
|
|
||||||
|
|
||||||
$.addStyle Main.css
|
$.addStyle Main.css
|
||||||
$.asap (-> d.body), (->
|
$.addClass d.documentElement, $.engine
|
||||||
$.addClass d.body, $.engine
|
$.addClass d.documentElement, 'fourchan_x'
|
||||||
$.addClass d.body, 'fourchan_x'
|
|
||||||
)
|
|
||||||
|
|
||||||
try
|
initFeature = (name, module) ->
|
||||||
Header.init()
|
console.time "#{name} initialization"
|
||||||
catch err
|
|
||||||
# XXX handle error
|
|
||||||
$.log err, 'Header'
|
|
||||||
|
|
||||||
try
|
|
||||||
Settings.init()
|
|
||||||
catch err
|
|
||||||
# XXX handle error
|
|
||||||
$.log err, 'Settings'
|
|
||||||
|
|
||||||
if Conf['Resurrect Quotes']
|
|
||||||
try
|
try
|
||||||
Quotify.init()
|
module.init()
|
||||||
catch err
|
catch err
|
||||||
# XXX handle error
|
Main.handleErrors
|
||||||
$.log err, 'Resurrect Quotes'
|
message: "\"#{name}\" initialization crashed."
|
||||||
|
error: err
|
||||||
|
console.timeEnd "#{name} initialization"
|
||||||
|
|
||||||
if Conf['Filter']
|
console.time 'All initializations'
|
||||||
try
|
initFeature 'Header', Header
|
||||||
Filter.init()
|
initFeature 'Settings', Settings
|
||||||
catch err
|
initFeature 'Resurrect Quotes', Quotify
|
||||||
# XXX handle error
|
initFeature 'Filter', Filter
|
||||||
$.log err, 'Filter'
|
initFeature 'Thread Hiding', ThreadHiding
|
||||||
|
initFeature 'Reply Hiding', ReplyHiding
|
||||||
if Conf['Thread Hiding']
|
initFeature 'Recursive', Recursive
|
||||||
try
|
initFeature 'Menu', Menu
|
||||||
ThreadHiding.init()
|
initFeature 'Report Link', ReportLink
|
||||||
catch err
|
initFeature 'Thread Hiding (Menu)', ThreadHiding.menu
|
||||||
# XXX handle error
|
initFeature 'Reply Hiding (Menu)', ReplyHiding.menu
|
||||||
$.log err, 'Thread Hiding'
|
initFeature 'Delete Link', DeleteLink
|
||||||
|
initFeature 'Filter (Menu)', Filter.menu
|
||||||
if Conf['Reply Hiding']
|
initFeature 'Download Link', DownloadLink
|
||||||
try
|
initFeature 'Archive Link', ArchiveLink
|
||||||
ReplyHiding.init()
|
initFeature 'Quote Inline', QuoteInline
|
||||||
catch err
|
initFeature 'Quote Preview', QuotePreview
|
||||||
# XXX handle error
|
initFeature 'Quote Backlinks', QuoteBacklink
|
||||||
$.log err, 'Reply Hiding'
|
initFeature 'Mark OP Quotes', QuoteOP
|
||||||
|
initFeature 'Mark Cross-thread Quotes', QuoteCT
|
||||||
try
|
initFeature 'Anonymize', Anonymize
|
||||||
Recursive.init()
|
initFeature 'Time Formatting', Time
|
||||||
catch err
|
initFeature 'File Info Formatting', FileInfo
|
||||||
# XXX handle error
|
initFeature 'Sauce', Sauce
|
||||||
$.log err, 'Recursive'
|
initFeature 'Reveal Spoilers', RevealSpoilers
|
||||||
|
initFeature 'Auto-GIF', AutoGIF
|
||||||
if Conf['Menu']
|
initFeature 'Image Hover', ImageHover
|
||||||
try
|
initFeature 'Thread Updater', ThreadUpdater
|
||||||
Menu.init()
|
console.timeEnd 'All initializations'
|
||||||
catch err
|
|
||||||
# XXX handle error
|
|
||||||
$.log err, 'Menu'
|
|
||||||
|
|
||||||
if Conf['Report Link']
|
|
||||||
try
|
|
||||||
ReportLink.init()
|
|
||||||
catch err
|
|
||||||
# XXX handle error
|
|
||||||
$.log err, 'Report Link'
|
|
||||||
|
|
||||||
if Conf['Thread Hiding']
|
|
||||||
try
|
|
||||||
ThreadHiding.menu.init()
|
|
||||||
catch err
|
|
||||||
# XXX handle error
|
|
||||||
$.log err, 'Thread Hiding - Menu'
|
|
||||||
|
|
||||||
if Conf['Reply Hiding']
|
|
||||||
try
|
|
||||||
ReplyHiding.menu.init()
|
|
||||||
catch err
|
|
||||||
# XXX handle error
|
|
||||||
$.log err, 'Reply Hiding - Menu'
|
|
||||||
|
|
||||||
if Conf['Delete Link']
|
|
||||||
try
|
|
||||||
DeleteLink.init()
|
|
||||||
catch err
|
|
||||||
# XXX handle error
|
|
||||||
$.log err, 'Delete Link'
|
|
||||||
|
|
||||||
if Conf['Filter']
|
|
||||||
try
|
|
||||||
Filter.menu.init()
|
|
||||||
catch err
|
|
||||||
# XXX handle error
|
|
||||||
$.log err, 'Filter - Menu'
|
|
||||||
|
|
||||||
if Conf['Download Link']
|
|
||||||
try
|
|
||||||
DownloadLink.init()
|
|
||||||
catch err
|
|
||||||
# XXX handle error
|
|
||||||
$.log err, 'Download Link'
|
|
||||||
|
|
||||||
if Conf['Archive Link']
|
|
||||||
try
|
|
||||||
ArchiveLink.init()
|
|
||||||
catch err
|
|
||||||
# XXX handle error
|
|
||||||
$.log err, 'Archive Link'
|
|
||||||
|
|
||||||
if Conf['Quote Inline']
|
|
||||||
try
|
|
||||||
QuoteInline.init()
|
|
||||||
catch err
|
|
||||||
# XXX handle error
|
|
||||||
$.log err, 'Quote Inline'
|
|
||||||
|
|
||||||
if Conf['Quote Preview']
|
|
||||||
try
|
|
||||||
QuotePreview.init()
|
|
||||||
catch err
|
|
||||||
# XXX handle error
|
|
||||||
$.log err, 'Quote Preview'
|
|
||||||
|
|
||||||
if Conf['Quote Backlinks']
|
|
||||||
try
|
|
||||||
QuoteBacklink.init()
|
|
||||||
catch err
|
|
||||||
# XXX handle error
|
|
||||||
$.log err, 'Quote Backlinks'
|
|
||||||
|
|
||||||
if Conf['Indicate OP Quotes']
|
|
||||||
try
|
|
||||||
QuoteOP.init()
|
|
||||||
catch err
|
|
||||||
# XXX handle error
|
|
||||||
$.log err, 'Indicate OP Quotes'
|
|
||||||
|
|
||||||
if Conf['Indicate Cross-thread Quotes']
|
|
||||||
try
|
|
||||||
QuoteCT.init()
|
|
||||||
catch err
|
|
||||||
# XXX handle error
|
|
||||||
$.log err, 'Indicate Cross-thread Quotes'
|
|
||||||
|
|
||||||
if Conf['Anonymize']
|
|
||||||
try
|
|
||||||
Anonymize.init()
|
|
||||||
catch e
|
|
||||||
# XXX handle error
|
|
||||||
$.log err, 'Anonymize'
|
|
||||||
|
|
||||||
if Conf['Time Formatting']
|
|
||||||
try
|
|
||||||
Time.init()
|
|
||||||
catch err
|
|
||||||
# XXX handle error
|
|
||||||
$.log err, 'Time Formatting'
|
|
||||||
|
|
||||||
if Conf['File Info Formatting']
|
|
||||||
try
|
|
||||||
FileInfo.init()
|
|
||||||
catch err
|
|
||||||
# XXX handle error
|
|
||||||
$.log err, 'File Info Formatting'
|
|
||||||
|
|
||||||
if Conf['Sauce']
|
|
||||||
try
|
|
||||||
Sauce.init()
|
|
||||||
catch err
|
|
||||||
# XXX handle error
|
|
||||||
$.log err, 'Sauce'
|
|
||||||
|
|
||||||
if Conf['Reveal Spoilers']
|
|
||||||
try
|
|
||||||
RevealSpoilers.init()
|
|
||||||
catch err
|
|
||||||
# XXX handle error
|
|
||||||
$.log err, 'Reveal Spoilers'
|
|
||||||
|
|
||||||
if Conf['Auto-GIF']
|
|
||||||
try
|
|
||||||
AutoGIF.init()
|
|
||||||
catch err
|
|
||||||
# XXX handle error
|
|
||||||
$.log err, 'Auto-GIF'
|
|
||||||
|
|
||||||
if Conf['Image Hover']
|
|
||||||
try
|
|
||||||
ImageHover.init()
|
|
||||||
catch err
|
|
||||||
# XXX handle error
|
|
||||||
$.log err, 'Image Hover'
|
|
||||||
|
|
||||||
if Conf['Thread Updater']
|
|
||||||
try
|
|
||||||
ThreadUpdater.init()
|
|
||||||
catch err
|
|
||||||
# XXX handle error
|
|
||||||
$.log err, 'Thread Updater'
|
|
||||||
|
|
||||||
$.ready Main.initReady
|
$.ready Main.initReady
|
||||||
|
|
||||||
initReady: ->
|
initReady: ->
|
||||||
if d.title is '4chan - 404 Not Found'
|
if d.title is '4chan - 404 Not Found'
|
||||||
|
$.rmClass d.documentElement, 'fourchan_x'
|
||||||
if Conf['404 Redirect'] and g.VIEW is 'thread'
|
if Conf['404 Redirect'] and g.VIEW is 'thread'
|
||||||
location.href = Redirect.to
|
location.href = Redirect.to
|
||||||
board: g.BOARD
|
board: g.BOARD
|
||||||
@ -505,25 +350,66 @@ Main =
|
|||||||
posts.push new Post threadChild, thread, g.BOARD
|
posts.push new Post threadChild, thread, g.BOARD
|
||||||
catch err
|
catch err
|
||||||
# Skip posts that we failed to parse.
|
# Skip posts that we failed to parse.
|
||||||
# XXX handle error
|
unless errors
|
||||||
# Post parser crashed for post No.#{threadChild.id[2..]}
|
errors = []
|
||||||
$.log threadChild, err
|
errors.push
|
||||||
|
message: "Parsing of Post No.#{threadChild.id.match(/\d+/)} failed. Post will be skipped."
|
||||||
|
error: err
|
||||||
|
Main.handleErrors errors if errors
|
||||||
|
|
||||||
Main.callbackNodes Thread, threads, true
|
Main.callbackNodes Thread, threads
|
||||||
Main.callbackNodes Post, posts, true
|
Main.callbackNodes Post, posts
|
||||||
|
|
||||||
callbackNodes: (klass, nodes, notify) ->
|
callbackNodes: (klass, nodes) ->
|
||||||
# get the nodes' length only once
|
# get the nodes' length only once
|
||||||
len = nodes.length
|
len = nodes.length
|
||||||
for callback in klass::callbacks
|
for callback in klass::callbacks
|
||||||
try
|
for i in [0...len]
|
||||||
for i in [0...len]
|
node = nodes[i]
|
||||||
callback.cb.call nodes[i]
|
try
|
||||||
catch err
|
callback.cb.call node
|
||||||
# XXX handle error if notify
|
catch err
|
||||||
$.log callback.name, 'crashed. error:', err.message, nodes[i]
|
unless errors
|
||||||
$.log err.stack
|
errors = []
|
||||||
return
|
errors.push
|
||||||
|
message: "\"#{callback.name}\" crashed on #{klass.name} No.#{node} (/#{node.board}/)."
|
||||||
|
error: err
|
||||||
|
Main.handleErrors errors if errors
|
||||||
|
|
||||||
|
handleErrors: (errors) ->
|
||||||
|
unless 'length' of errors
|
||||||
|
error = errors
|
||||||
|
else if errors.length is 1
|
||||||
|
error = errors[0]
|
||||||
|
if error
|
||||||
|
new Notification 'error', Main.parseError(error), 15
|
||||||
|
return
|
||||||
|
|
||||||
|
div = $.el 'div',
|
||||||
|
innerHTML: "#{errors.length} errors occured. [<a href=javascript:;>show</a>]"
|
||||||
|
$.on div.lastElementChild, 'click', ->
|
||||||
|
if @textContent is 'show'
|
||||||
|
@textContent = 'hide'
|
||||||
|
logs.hidden = false
|
||||||
|
else
|
||||||
|
@textContent = 'show'
|
||||||
|
logs.hidden = true
|
||||||
|
|
||||||
|
logs = $.el 'div',
|
||||||
|
hidden: true
|
||||||
|
for error in errors
|
||||||
|
$.add logs, Main.parseError error
|
||||||
|
|
||||||
|
new Notification 'error', [div, logs], 30
|
||||||
|
|
||||||
|
parseError: (data) ->
|
||||||
|
{message, error} = data
|
||||||
|
$.log message, error.stack
|
||||||
|
message = $.el 'div',
|
||||||
|
textContent: message
|
||||||
|
error = $.el 'div',
|
||||||
|
textContent: error
|
||||||
|
[message, error]
|
||||||
|
|
||||||
css: """<%= grunt.file.read('css/style.css') %>"""
|
css: """<%= grunt.file.read('css/style.css') %>"""
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user