commit
d9a1b2844e
10
CHANGELOG.md
10
CHANGELOG.md
@ -1,3 +1,13 @@
|
|||||||
|
- Thread and post hiding changes:
|
||||||
|
- The posts' menu now has a label entry listing the reasons why a post got hidden or highlighted.
|
||||||
|
- `Thread Hiding` and `Reply Hiding` settings are merged into one: `Post Hiding`.
|
||||||
|
- `Thread Hiding Link` and `Reply Hiding Link` settings are merged into one: `Post Hiding Link`.
|
||||||
|
- Hiding a thread removes it from the index in `Paged` or `All threads` modes.
|
||||||
|
<ul>
|
||||||
|
<li> Hidden threads can be seen by clicking the `[Show]` button the the top of the index.
|
||||||
|
<li> The `Anchor Hidden Threads` setting has been removed.
|
||||||
|
</ul>
|
||||||
|
|
||||||
### 3.18.1 - *2014-02-20*
|
### 3.18.1 - *2014-02-20*
|
||||||
|
|
||||||
- Fix the QR breaking after a change with 4chan.
|
- Fix the QR breaking after a change with 4chan.
|
||||||
|
|||||||
@ -368,7 +368,6 @@ a[href="javascript:;"] {
|
|||||||
: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:not(.catalog-mode) #hidden-toggle,
|
|
||||||
:root:not(.catalog-mode) #index-size {
|
:root:not(.catalog-mode) #index-size {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
@ -706,14 +705,16 @@ a.hide-announcement {
|
|||||||
border: 2px solid rgba(255, 0, 0, .5);
|
border: 2px solid rgba(255, 0, 0, .5);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Thread & Reply Hiding */
|
/* Post Hiding */
|
||||||
.hide-thread-button,
|
.hide-post-button,
|
||||||
.hide-reply-button {
|
.show-post-button {
|
||||||
float: left;
|
font-size: 14px;
|
||||||
margin-right: 2px;
|
line-height: 12px; /* Prevent the floating effect from affecting the thumbnail too */
|
||||||
}
|
}
|
||||||
.stub ~ * {
|
.opContainer > .show-post-button,
|
||||||
display: none !important;
|
.hide-post-button {
|
||||||
|
float: left;
|
||||||
|
margin-right: 3px;
|
||||||
}
|
}
|
||||||
.stub input {
|
.stub input {
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
|
|||||||
@ -57,7 +57,18 @@ Filter =
|
|||||||
top = filter.match(/top:(yes|no)/)?[1] or 'yes'
|
top = filter.match(/top:(yes|no)/)?[1] or 'yes'
|
||||||
top = top is 'yes' # Turn it into a boolean
|
top = top is 'yes' # Turn it into a boolean
|
||||||
|
|
||||||
@filters[key].push @createFilter regexp, op, stub, hl, top
|
@filters[key].push {
|
||||||
|
hide: !hl
|
||||||
|
op: op
|
||||||
|
stub: stub
|
||||||
|
class: hl
|
||||||
|
top: top
|
||||||
|
match: regexp
|
||||||
|
test: if typeof regexp is 'string'
|
||||||
|
Filter.stringTest # MD5 checking
|
||||||
|
else
|
||||||
|
Filter.regexpTest
|
||||||
|
}
|
||||||
|
|
||||||
# Only execute filter types that contain valid filters.
|
# Only execute filter types that contain valid filters.
|
||||||
unless @filters[key].length
|
unless @filters[key].length
|
||||||
@ -68,25 +79,6 @@ Filter =
|
|||||||
name: 'Filter'
|
name: 'Filter'
|
||||||
cb: @node
|
cb: @node
|
||||||
|
|
||||||
createFilter: (regexp, op, stub, hl, top) ->
|
|
||||||
test =
|
|
||||||
if typeof regexp is 'string'
|
|
||||||
# MD5 checking
|
|
||||||
(value) -> regexp is value
|
|
||||||
else
|
|
||||||
(value) -> regexp.test value
|
|
||||||
settings =
|
|
||||||
hide: !hl
|
|
||||||
stub: stub
|
|
||||||
class: hl
|
|
||||||
top: top
|
|
||||||
(value, isReply) ->
|
|
||||||
if isReply and op is 'only' or !isReply and op is 'no'
|
|
||||||
return false
|
|
||||||
unless test value
|
|
||||||
return false
|
|
||||||
settings
|
|
||||||
|
|
||||||
node: ->
|
node: ->
|
||||||
return if @isClone
|
return if @isClone
|
||||||
for key of Filter.filters
|
for key of Filter.filters
|
||||||
@ -94,27 +86,29 @@ Filter =
|
|||||||
# Continue if there's nothing to filter (no tripcode for example).
|
# Continue if there's nothing to filter (no tripcode for example).
|
||||||
continue if value is false
|
continue if value is false
|
||||||
|
|
||||||
for filter in Filter.filters[key]
|
for obj in Filter.filters[key]
|
||||||
unless result = filter value, @isReply
|
unless Filter.test obj, value, @isReply
|
||||||
continue
|
continue
|
||||||
|
|
||||||
# Hide
|
# Hide
|
||||||
if result.hide
|
if obj.hide
|
||||||
if @isReply
|
continue unless @isReply or g.VIEW is 'index'
|
||||||
PostHiding.hide @, result.stub
|
@hide "Hidden by filtering the #{key}: #{obj.match}", obj.stub
|
||||||
else if g.VIEW is 'index'
|
|
||||||
ThreadHiding.hide @thread, result.stub
|
|
||||||
else
|
|
||||||
continue
|
|
||||||
return
|
return
|
||||||
|
|
||||||
# Highlight
|
# Highlight
|
||||||
$.addClass @nodes.root, result.class
|
@highlight "Highlighted by filtering the #{key}: #{obj.match}", obj.class, obj.top
|
||||||
unless @highlights and result.class in @highlights
|
|
||||||
(@highlights or= []).push result.class
|
|
||||||
if !@isReply and result.top
|
|
||||||
@thread.isOnTop = true
|
|
||||||
|
|
||||||
|
stringTest: (string, value) ->
|
||||||
|
string is value
|
||||||
|
regexpTest: (regexp, value) ->
|
||||||
|
regexp.test value
|
||||||
|
test: ({test, match, op}, value, isReply) ->
|
||||||
|
if isReply and op is 'only' or !isReply and op is 'no'
|
||||||
|
return false
|
||||||
|
unless test match, value
|
||||||
|
return false
|
||||||
|
true
|
||||||
name: (post) ->
|
name: (post) ->
|
||||||
if 'name' of post.info
|
if 'name' of post.info
|
||||||
return post.info.name
|
return post.info.name
|
||||||
|
|||||||
@ -1,186 +1,184 @@
|
|||||||
PostHiding =
|
PostHiding =
|
||||||
init: ->
|
init: ->
|
||||||
return if !Conf['Reply Hiding'] and !Conf['Reply Hiding Link']
|
|
||||||
|
|
||||||
@db = new DataBoard 'hiddenPosts'
|
@db = new DataBoard 'hiddenPosts'
|
||||||
|
@hideButton = $.el 'a',
|
||||||
|
className: 'hide-post-button'
|
||||||
|
innerHTML: '<i class="fa fa-minus-square-o"></i>'
|
||||||
|
href: 'javascript:;'
|
||||||
|
@showButton = $.el 'a',
|
||||||
|
className: 'show-post-button'
|
||||||
|
innerHTML: '<i class="fa fa-plus-square-o"></i>'
|
||||||
|
href: 'javascript:;'
|
||||||
|
|
||||||
Post.callbacks.push
|
Post.callbacks.push
|
||||||
name: 'Reply Hiding'
|
name: 'Post Hiding'
|
||||||
cb: @node
|
cb: @node
|
||||||
|
|
||||||
|
# XXX tmp conversion
|
||||||
|
$.get 'hiddenThreads', null, ({hiddenThreads}) ->
|
||||||
|
return unless hiddenThreads
|
||||||
|
for boardID, board of hiddenThreads.boards
|
||||||
|
for threadID, val of board
|
||||||
|
((PostHiding.db.data.boards[boardID] or= {})[threadID] or= {})[threadID] = val
|
||||||
|
PostHiding.db.save()
|
||||||
|
$.delete 'hiddenThreads'
|
||||||
|
|
||||||
node: ->
|
node: ->
|
||||||
return if !@isReply or @isClone
|
return if !@isReply and g.VIEW isnt 'index' or @isClone
|
||||||
|
|
||||||
if data = PostHiding.db.get {boardID: @board.ID, threadID: @thread.ID, postID: @ID}
|
if data = PostHiding.db.get {boardID: @board.ID, threadID: @thread.ID, postID: @ID}
|
||||||
if data.thisPost
|
if data.thisPost is false
|
||||||
PostHiding.hide @, data.makeStub, data.hideRecursively
|
label = "Recursively hidden for quoting No.#{@}"
|
||||||
|
Recursive.apply 'hide', @, label, data.makeStub, true
|
||||||
|
Recursive.add 'hide', @, label, data.makeStub, true
|
||||||
else
|
else
|
||||||
Recursive.apply PostHiding.hide, @, data.makeStub, true
|
@hide 'Manually hidden', data.makeStub, data.hideRecursively
|
||||||
Recursive.add PostHiding.hide, @, data.makeStub, true
|
|
||||||
return unless Conf['Reply Hiding']
|
|
||||||
$.replace $('.sideArrows', @nodes.root), PostHiding.makeButton @, 'hide'
|
|
||||||
|
|
||||||
menu:
|
return unless Conf['Post Hiding']
|
||||||
init: ->
|
if @isReply
|
||||||
return if !Conf['Menu'] or !Conf['Reply Hiding Link']
|
a = PostHiding.makeButton true
|
||||||
|
a.hidden = true if @isHidden
|
||||||
|
$.replace $('.sideArrows', @nodes.root), a
|
||||||
|
else
|
||||||
|
$.prepend @nodes.root, PostHiding.makeButton !@isHidden
|
||||||
|
|
||||||
# Hide
|
makeButton: (hide) ->
|
||||||
div = $.el 'div',
|
a = (if hide then PostHiding.hideButton else PostHiding.showButton).cloneNode true
|
||||||
className: 'hide-reply-link'
|
$.on a, 'click', PostHiding.onToggleClick
|
||||||
textContent: 'Hide reply'
|
|
||||||
|
|
||||||
apply = $.el 'a',
|
|
||||||
textContent: 'Apply'
|
|
||||||
href: 'javascript:;'
|
|
||||||
$.on apply, 'click', PostHiding.menu.hide
|
|
||||||
|
|
||||||
thisPost = $.el 'label',
|
|
||||||
innerHTML: '<input type=checkbox name=thisPost checked> This post'
|
|
||||||
replies = $.el 'label',
|
|
||||||
innerHTML: "<input type=checkbox name=replies checked=#{Conf['Recursive Hiding']}> Hide replies"
|
|
||||||
makeStub = $.el 'label',
|
|
||||||
innerHTML: "<input type=checkbox name=makeStub checked=#{Conf['Stubs']}> Make stub"
|
|
||||||
|
|
||||||
$.event 'AddMenuEntry',
|
|
||||||
type: 'post'
|
|
||||||
el: div
|
|
||||||
order: 20
|
|
||||||
open: (post) ->
|
|
||||||
if !post.isReply or post.isClone or post.isHidden
|
|
||||||
return false
|
|
||||||
PostHiding.menu.post = post
|
|
||||||
true
|
|
||||||
subEntries: [{el: apply}, {el: thisPost}, {el: replies}, {el: makeStub}]
|
|
||||||
|
|
||||||
# Show
|
|
||||||
div = $.el 'div',
|
|
||||||
className: 'show-reply-link'
|
|
||||||
textContent: 'Show reply'
|
|
||||||
|
|
||||||
apply = $.el 'a',
|
|
||||||
textContent: 'Apply'
|
|
||||||
href: 'javascript:;'
|
|
||||||
$.on apply, 'click', PostHiding.menu.show
|
|
||||||
|
|
||||||
thisPost = $.el 'label',
|
|
||||||
innerHTML: '<input type=checkbox name=thisPost> This post'
|
|
||||||
replies = $.el 'label',
|
|
||||||
innerHTML: "<input type=checkbox name=replies> Show replies"
|
|
||||||
|
|
||||||
$.event 'AddMenuEntry',
|
|
||||||
type: 'post'
|
|
||||||
el: div
|
|
||||||
order: 20
|
|
||||||
open: (post) ->
|
|
||||||
if !post.isReply or post.isClone or !post.isHidden
|
|
||||||
return false
|
|
||||||
unless data = PostHiding.db.get {boardID: post.board.ID, threadID: post.thread.ID, postID: post.ID}
|
|
||||||
return false
|
|
||||||
PostHiding.menu.post = post
|
|
||||||
thisPost.firstChild.checked = post.isHidden
|
|
||||||
replies.firstChild.checked = if data?.hideRecursively? then data.hideRecursively else Conf['Recursive Hiding']
|
|
||||||
true
|
|
||||||
subEntries: [{el: apply}, {el: thisPost}, {el: replies}]
|
|
||||||
hide: ->
|
|
||||||
parent = @parentNode
|
|
||||||
thisPost = $('input[name=thisPost]', parent).checked
|
|
||||||
replies = $('input[name=replies]', parent).checked
|
|
||||||
makeStub = $('input[name=makeStub]', parent).checked
|
|
||||||
{post} = PostHiding.menu
|
|
||||||
if thisPost
|
|
||||||
PostHiding.hide post, makeStub, replies
|
|
||||||
else if replies
|
|
||||||
Recursive.apply PostHiding.hide, post, makeStub, true
|
|
||||||
Recursive.add PostHiding.hide, post, makeStub, true
|
|
||||||
else
|
|
||||||
return
|
|
||||||
PostHiding.saveHiddenState post, true, thisPost, makeStub, replies
|
|
||||||
$.event 'CloseMenu'
|
|
||||||
show: ->
|
|
||||||
parent = @parentNode
|
|
||||||
thisPost = $('input[name=thisPost]', parent).checked
|
|
||||||
replies = $('input[name=replies]', parent).checked
|
|
||||||
{post} = PostHiding.menu
|
|
||||||
if thisPost
|
|
||||||
PostHiding.show post, replies
|
|
||||||
else if replies
|
|
||||||
Recursive.apply PostHiding.show, post, true
|
|
||||||
Recursive.rm PostHiding.hide, post, true
|
|
||||||
else
|
|
||||||
return
|
|
||||||
if data = PostHiding.db.get {boardID: post.board.ID, threadID: post.thread.ID, postID: post.ID}
|
|
||||||
PostHiding.saveHiddenState post, !(thisPost and replies), !thisPost, data.makeStub, !replies
|
|
||||||
$.event 'CloseMenu'
|
|
||||||
|
|
||||||
makeButton: (post, type) ->
|
|
||||||
span = $.el 'span',
|
|
||||||
textContent: "[\u00A0#{if type is 'hide' then '-' else '+'}\u00A0]"
|
|
||||||
a = $.el 'a',
|
|
||||||
className: "#{type}-reply-button"
|
|
||||||
href: 'javascript:;'
|
|
||||||
$.add a, span
|
|
||||||
$.on a, 'click', PostHiding.toggle
|
|
||||||
a
|
a
|
||||||
|
|
||||||
saveHiddenState: (post, isHiding, thisPost, makeStub, hideRecursively) ->
|
onToggleClick: ->
|
||||||
|
PostHiding.toggle if $.x 'ancestor::div[contains(@class,"postContainer")][1]', @
|
||||||
|
Get.postFromNode @
|
||||||
|
else
|
||||||
|
Get.threadFromNode(@).OP
|
||||||
|
toggle: (post) ->
|
||||||
|
if post.isHidden
|
||||||
|
post.show()
|
||||||
|
else
|
||||||
|
post.hide 'Manually hidden'
|
||||||
|
PostHiding.saveHiddenState post
|
||||||
|
return if post.isReply
|
||||||
|
Index.updateHideLabel()
|
||||||
|
Index.sort()
|
||||||
|
Index.buildIndex()
|
||||||
|
|
||||||
|
saveHiddenState: (post, val) ->
|
||||||
data =
|
data =
|
||||||
boardID: post.board.ID
|
boardID: post.board.ID
|
||||||
threadID: post.thread.ID
|
threadID: post.thread.ID
|
||||||
postID: post.ID
|
postID: post.ID
|
||||||
if isHiding
|
if post.isHidden or val and !val.thisPost
|
||||||
data.val =
|
data.val = val or {}
|
||||||
thisPost: thisPost isnt false # undefined -> true
|
|
||||||
makeStub: makeStub
|
|
||||||
hideRecursively: hideRecursively
|
|
||||||
PostHiding.db.set data
|
PostHiding.db.set data
|
||||||
else
|
else if PostHiding.db.get data # unhiding a filtered post f.e.
|
||||||
PostHiding.db.delete data
|
PostHiding.db.delete data
|
||||||
|
|
||||||
toggle: ->
|
menu:
|
||||||
post = Get.postFromNode @
|
init: ->
|
||||||
if post.isHidden
|
return if !Conf['Menu'] or !Conf['Post Hiding Link']
|
||||||
PostHiding.show post
|
|
||||||
else
|
|
||||||
PostHiding.hide post
|
|
||||||
PostHiding.saveHiddenState post, post.isHidden
|
|
||||||
|
|
||||||
hide: (post, makeStub=Conf['Stubs'], hideRecursively=Conf['Recursive Hiding']) ->
|
# Hide
|
||||||
return if post.isHidden
|
apply =
|
||||||
post.isHidden = true
|
el: $.el 'a', textContent: 'Apply', href: 'javascript:;'
|
||||||
|
open: (post) ->
|
||||||
|
$.off @el, 'click', @cb if @cb
|
||||||
|
@cb = -> PostHiding.menu.hide post
|
||||||
|
$.on @el, 'click', @cb
|
||||||
|
true
|
||||||
|
thisPost =
|
||||||
|
el: $.el 'label', innerHTML: '<input type=checkbox name=thisPost checked> This post'
|
||||||
|
replies =
|
||||||
|
el: $.el 'label', innerHTML: "<input type=checkbox name=replies checked=#{Conf['Recursive Hiding']}> Hide replies"
|
||||||
|
makeStub =
|
||||||
|
el: $.el 'label', innerHTML: "<input type=checkbox name=makeStub checked=#{Conf['Stubs']}> Make stub"
|
||||||
|
|
||||||
if hideRecursively
|
$.event 'AddMenuEntry',
|
||||||
Recursive.apply PostHiding.hide, post, makeStub, true
|
type: 'post'
|
||||||
Recursive.add PostHiding.hide, post, makeStub, true
|
el: $.el 'div',
|
||||||
|
textContent: 'Hide post'
|
||||||
|
className: 'hide-post-link'
|
||||||
|
order: 20
|
||||||
|
open: (post) -> !(post.isHidden or !post.isReply or post.isClone)
|
||||||
|
subEntries: [apply, thisPost, replies, makeStub]
|
||||||
|
|
||||||
for quotelink in Get.allQuotelinksLinkingTo post
|
# Show
|
||||||
$.addClass quotelink, 'filtered'
|
apply =
|
||||||
|
el: $.el 'a', textContent: 'Apply', href: 'javascript:;'
|
||||||
|
open: (post) ->
|
||||||
|
$.off @el, 'click', @cb if @cb
|
||||||
|
@cb = -> PostHiding.menu.show post
|
||||||
|
$.on @el, 'click', @cb
|
||||||
|
true
|
||||||
|
thisPost =
|
||||||
|
el: $.el 'label', innerHTML: '<input type=checkbox name=thisPost> This post'
|
||||||
|
open: (post) ->
|
||||||
|
@el.firstChild.checked = post.isHidden
|
||||||
|
true
|
||||||
|
replies =
|
||||||
|
el: $.el 'label', innerHTML: '<input type=checkbox name=replies> Unhide replies'
|
||||||
|
open: (post) ->
|
||||||
|
data = PostHiding.db.get {boardID: post.board.ID, threadID: post.thread.ID, postID: post.ID}
|
||||||
|
@el.firstChild.checked = if 'hideRecursively' of data then data.hideRecursively else Conf['Recursive Hiding']
|
||||||
|
true
|
||||||
|
|
||||||
unless makeStub
|
$.event 'AddMenuEntry',
|
||||||
post.nodes.root.hidden = true
|
type: 'post'
|
||||||
return
|
el: $.el 'div',
|
||||||
|
textContent: 'Unhide post'
|
||||||
|
className: 'show-post-link'
|
||||||
|
order: 20
|
||||||
|
open: (post) ->
|
||||||
|
if !post.isHidden or !post.isReply or post.isClone
|
||||||
|
return false
|
||||||
|
unless PostHiding.db.get {boardID: post.board.ID, threadID: post.thread.ID, postID: post.ID}
|
||||||
|
return false
|
||||||
|
true
|
||||||
|
subEntries: [apply, thisPost, replies]
|
||||||
|
|
||||||
a = PostHiding.makeButton post, 'show'
|
return if g.VIEW isnt 'index'
|
||||||
postInfo =
|
$.event 'AddMenuEntry',
|
||||||
if Conf['Anonymize']
|
type: 'post'
|
||||||
'Anonymous'
|
el: $.el 'a', href: 'javascript:;'
|
||||||
|
order: 20
|
||||||
|
open: (post) ->
|
||||||
|
@el.textContent = if post.isHidden
|
||||||
|
'Unhide thread'
|
||||||
|
else
|
||||||
|
'Hide thread'
|
||||||
|
$.off @el, 'click', @cb if @cb
|
||||||
|
@cb = ->
|
||||||
|
$.event 'CloseMenu'
|
||||||
|
PostHiding.toggle post
|
||||||
|
$.on @el, 'click', @cb
|
||||||
|
true
|
||||||
|
|
||||||
|
hide: (post) ->
|
||||||
|
parent = @parentNode
|
||||||
|
thisPost = $('input[name=thisPost]', parent).checked
|
||||||
|
replies = $('input[name=replies]', parent).checked
|
||||||
|
makeStub = $('input[name=makeStub]', parent).checked
|
||||||
|
label = 'Manually hidden'
|
||||||
|
if thisPost
|
||||||
|
post.hide label, makeStub, replies
|
||||||
|
else if replies
|
||||||
|
Recursive.apply 'hide', post, label, makeStub, true
|
||||||
|
Recursive.add 'hide', post, label, makeStub, true
|
||||||
else
|
else
|
||||||
$('.nameBlock', post.nodes.info).textContent
|
return
|
||||||
$.add a, $.tn " #{postInfo}"
|
PostHiding.saveHiddenState post, {thisPost, hideRecursively: replies, makeStub}
|
||||||
post.nodes.stub = $.el 'div',
|
$.event 'CloseMenu'
|
||||||
className: 'stub'
|
show: (post) ->
|
||||||
$.add post.nodes.stub, a
|
parent = @parentNode
|
||||||
if Conf['Menu']
|
thisPost = $('input[name=thisPost]', parent).checked
|
||||||
$.add post.nodes.stub, Menu.makeButton()
|
replies = $('input[name=replies]', parent).checked
|
||||||
$.prepend post.nodes.root, post.nodes.stub
|
if thisPost
|
||||||
|
post.show replies
|
||||||
show: (post, showRecursively=Conf['Recursive Hiding']) ->
|
else if replies
|
||||||
if post.nodes.stub
|
Recursive.apply 'show', post, true
|
||||||
$.rm post.nodes.stub
|
Recursive.rm 'hide', post, true
|
||||||
delete post.nodes.stub
|
else
|
||||||
else
|
return
|
||||||
post.nodes.root.hidden = false
|
val = {thisPost: !thisPost, hideRecursively: !replies, makeStub: !!post.nodes.stub}
|
||||||
post.isHidden = false
|
PostHiding.saveHiddenState post, val
|
||||||
if showRecursively
|
$.event 'CloseMenu'
|
||||||
Recursive.apply PostHiding.show, post, true
|
|
||||||
Recursive.rm PostHiding.hide, post
|
|
||||||
for quotelink in Get.allQuotelinksLinkingTo post
|
|
||||||
$.rmClass quotelink, 'filtered'
|
|
||||||
return
|
|
||||||
|
|||||||
@ -7,10 +7,9 @@ Recursive =
|
|||||||
|
|
||||||
node: ->
|
node: ->
|
||||||
return if @isClone
|
return if @isClone
|
||||||
for quote in @quotes
|
for quote in @quotes when obj = Recursive.recursives[quote]
|
||||||
if obj = Recursive.recursives[quote]
|
for recursive, i in obj.recursives
|
||||||
for recursive, i in obj.recursives
|
@[recursive] obj.args[i]...
|
||||||
recursive @, obj.args[i]...
|
|
||||||
return
|
return
|
||||||
|
|
||||||
add: (recursive, post, args...) ->
|
add: (recursive, post, args...) ->
|
||||||
@ -22,15 +21,13 @@ Recursive =
|
|||||||
|
|
||||||
rm: (recursive, post) ->
|
rm: (recursive, post) ->
|
||||||
return unless obj = Recursive.recursives[post.fullID]
|
return unless obj = Recursive.recursives[post.fullID]
|
||||||
for rec, i in obj.recursives
|
for rec, i in obj.recursives when rec is recursive
|
||||||
if rec is recursive
|
obj.recursives.splice i, 1
|
||||||
obj.recursives.splice i, 1
|
obj.args.splice i, 1
|
||||||
obj.args.splice i, 1
|
|
||||||
return
|
return
|
||||||
|
|
||||||
apply: (recursive, post, args...) ->
|
apply: (recursive, post, args...) ->
|
||||||
{fullID} = post
|
{fullID} = post
|
||||||
for ID, post of g.posts
|
for ID, post of g.posts when fullID in post.quotes
|
||||||
if fullID in post.quotes
|
post[recursive] args...
|
||||||
recursive post, args...
|
|
||||||
return
|
return
|
||||||
|
|||||||
@ -1,126 +0,0 @@
|
|||||||
ThreadHiding =
|
|
||||||
init: ->
|
|
||||||
return if g.VIEW isnt 'index'
|
|
||||||
|
|
||||||
@db = new DataBoard 'hiddenThreads'
|
|
||||||
$.on d, 'IndexRefresh', @onIndexRefresh
|
|
||||||
Thread.callbacks.push
|
|
||||||
name: 'Thread Hiding'
|
|
||||||
cb: @node
|
|
||||||
|
|
||||||
node: ->
|
|
||||||
if data = ThreadHiding.db.get {boardID: @board.ID, threadID: @ID}
|
|
||||||
ThreadHiding.hide @, data.makeStub
|
|
||||||
return unless Conf['Thread Hiding']
|
|
||||||
$.prepend @OP.nodes.root, ThreadHiding.makeButton @, 'hide'
|
|
||||||
|
|
||||||
onIndexRefresh: ->
|
|
||||||
for root, i in Index.nodes by 2
|
|
||||||
thread = Get.threadFromRoot root
|
|
||||||
continue unless thread.isHidden
|
|
||||||
unless thread.stub
|
|
||||||
Index.nodes[i + 1].hidden = true
|
|
||||||
else unless root.contains thread.stub
|
|
||||||
# When we come back to a page, the stub is already there.
|
|
||||||
ThreadHiding.makeStub thread, root
|
|
||||||
return
|
|
||||||
|
|
||||||
menu:
|
|
||||||
init: ->
|
|
||||||
return if g.VIEW isnt 'index' or !Conf['Menu'] or !Conf['Thread Hiding Link']
|
|
||||||
|
|
||||||
div = $.el 'div',
|
|
||||||
className: 'hide-thread-link'
|
|
||||||
textContent: 'Hide thread'
|
|
||||||
|
|
||||||
apply = $.el 'a',
|
|
||||||
textContent: 'Apply'
|
|
||||||
href: 'javascript:;'
|
|
||||||
$.on apply, 'click', ThreadHiding.menu.hide
|
|
||||||
|
|
||||||
makeStub = $.el 'label',
|
|
||||||
innerHTML: "<input type=checkbox checked=#{Conf['Stubs']}> Make stub"
|
|
||||||
|
|
||||||
$.event 'AddMenuEntry',
|
|
||||||
type: 'post'
|
|
||||||
el: div
|
|
||||||
order: 20
|
|
||||||
open: ({thread, isReply}) ->
|
|
||||||
if isReply or thread.isHidden or Conf['Index Mode'] is 'catalog'
|
|
||||||
return false
|
|
||||||
ThreadHiding.menu.thread = thread
|
|
||||||
true
|
|
||||||
subEntries: [el: apply; el: makeStub]
|
|
||||||
hide: ->
|
|
||||||
makeStub = $('input', @parentNode).checked
|
|
||||||
{thread} = ThreadHiding.menu
|
|
||||||
ThreadHiding.hide thread, makeStub
|
|
||||||
ThreadHiding.saveHiddenState thread, makeStub
|
|
||||||
$.event 'CloseMenu'
|
|
||||||
|
|
||||||
makeButton: (thread, type) ->
|
|
||||||
a = $.el 'a',
|
|
||||||
className: "#{type}-thread-button"
|
|
||||||
innerHTML: "<span>[ #{if type is 'hide' then '-' else '+'} ]</span>"
|
|
||||||
href: 'javascript:;'
|
|
||||||
a.dataset.fullID = thread.fullID
|
|
||||||
$.on a, 'click', ThreadHiding.toggle
|
|
||||||
a
|
|
||||||
makeStub: (thread, root) ->
|
|
||||||
numReplies = $$('.thread > .replyContainer', root).length
|
|
||||||
numReplies += +summary.textContent.match /\d+/ if summary = $ '.summary', root
|
|
||||||
opInfo = if Conf['Anonymize']
|
|
||||||
'Anonymous'
|
|
||||||
else
|
|
||||||
$('.nameBlock', thread.OP.nodes.info).textContent
|
|
||||||
|
|
||||||
a = ThreadHiding.makeButton thread, 'show'
|
|
||||||
$.add a, $.tn " #{opInfo} (#{if numReplies is 1 then '1 reply' else "#{numReplies} replies"})"
|
|
||||||
thread.stub = $.el 'div',
|
|
||||||
className: 'stub'
|
|
||||||
if Conf['Menu']
|
|
||||||
$.add thread.stub, [a, Menu.makeButton()]
|
|
||||||
else
|
|
||||||
$.add thread.stub, a
|
|
||||||
$.prepend root, thread.stub
|
|
||||||
|
|
||||||
saveHiddenState: (thread, makeStub) ->
|
|
||||||
if thread.isHidden
|
|
||||||
ThreadHiding.db.set
|
|
||||||
boardID: thread.board.ID
|
|
||||||
threadID: thread.ID
|
|
||||||
val: {makeStub}
|
|
||||||
else
|
|
||||||
ThreadHiding.db.delete
|
|
||||||
boardID: thread.board.ID
|
|
||||||
threadID: thread.ID
|
|
||||||
|
|
||||||
toggle: (thread) ->
|
|
||||||
unless thread instanceof Thread
|
|
||||||
thread = g.threads[@dataset.fullID]
|
|
||||||
if thread.isHidden
|
|
||||||
ThreadHiding.show thread
|
|
||||||
else
|
|
||||||
ThreadHiding.hide thread
|
|
||||||
ThreadHiding.saveHiddenState thread
|
|
||||||
|
|
||||||
hide: (thread, makeStub=Conf['Stubs']) ->
|
|
||||||
return if thread.isHidden
|
|
||||||
threadRoot = thread.OP.nodes.root.parentNode
|
|
||||||
thread.isHidden = true
|
|
||||||
Index.updateHideLabel()
|
|
||||||
|
|
||||||
unless makeStub
|
|
||||||
threadRoot.hidden = threadRoot.nextElementSibling.hidden = true # <hr>
|
|
||||||
return
|
|
||||||
|
|
||||||
ThreadHiding.makeStub thread, threadRoot
|
|
||||||
|
|
||||||
show: (thread) ->
|
|
||||||
if thread.stub
|
|
||||||
$.rm thread.stub
|
|
||||||
delete thread.stub
|
|
||||||
threadRoot = thread.OP.nodes.root.parentNode
|
|
||||||
threadRoot.nextElementSibling.hidden =
|
|
||||||
threadRoot.hidden = thread.isHidden = false
|
|
||||||
Index.updateHideLabel()
|
|
||||||
@ -244,20 +244,20 @@ Build =
|
|||||||
|
|
||||||
if (OP = board.posts[data.no]) and root = OP.nodes.root.parentNode
|
if (OP = board.posts[data.no]) and root = OP.nodes.root.parentNode
|
||||||
$.rmAll root
|
$.rmAll root
|
||||||
|
$.add root, OP.nodes.root
|
||||||
else
|
else
|
||||||
root = $.el 'div',
|
root = $.el 'div',
|
||||||
className: 'thread'
|
className: 'thread'
|
||||||
id: "t#{data.no}"
|
id: "t#{data.no}"
|
||||||
|
$.add root, Build.postFromObject data, board.ID
|
||||||
|
|
||||||
nodes = [if OP then OP.nodes.root else Build.postFromObject data, board.ID]
|
|
||||||
if data.omitted_posts or !Conf['Show Replies'] and data.replies
|
if data.omitted_posts or !Conf['Show Replies'] and data.replies
|
||||||
[posts, files] = if Conf['Show Replies']
|
[posts, files] = if Conf['Show Replies']
|
||||||
[data.omitted_posts, data.omitted_images]
|
[data.omitted_posts, data.omitted_images]
|
||||||
else
|
else
|
||||||
[data.replies, data.images]
|
[data.replies, data.images]
|
||||||
nodes.push Build.summary board.ID, data.no, posts, files
|
$.add root, Build.summary board.ID, data.no, posts, files
|
||||||
|
|
||||||
$.add root, nodes
|
|
||||||
root
|
root
|
||||||
catalogThread: (thread) ->
|
catalogThread: (thread) ->
|
||||||
{staticPath, gifIcon} = Build
|
{staticPath, gifIcon} = Build
|
||||||
@ -279,7 +279,7 @@ Build =
|
|||||||
|
|
||||||
root.dataset.fullID = thread.fullID
|
root.dataset.fullID = thread.fullID
|
||||||
$.addClass root, 'pinned' if thread.isPinned
|
$.addClass root, 'pinned' if thread.isPinned
|
||||||
$.addClass root, thread.OP.highlights... if thread.OP.highlights
|
$.addClass root, thread.OP.highlights... if thread.OP.highlights.length
|
||||||
|
|
||||||
thumb = root.firstElementChild
|
thumb = root.firstElementChild
|
||||||
if data.spoiler and !Conf['Reveal Spoilers']
|
if data.spoiler and !Conf['Reveal Spoilers']
|
||||||
|
|||||||
@ -17,10 +17,9 @@ Config =
|
|||||||
'Filtering':
|
'Filtering':
|
||||||
'Anonymize': [false, 'Make everyone Anonymous.']
|
'Anonymize': [false, 'Make everyone Anonymous.']
|
||||||
'Filter': [true, 'Self-moderation placebo.']
|
'Filter': [true, 'Self-moderation placebo.']
|
||||||
|
'Post Hiding': [true, 'Add buttons to hide threads and replies.']
|
||||||
|
'Stubs': [true, 'Show stubs of hidden posts.']
|
||||||
'Recursive Hiding': [true, 'Hide replies of hidden posts, recursively.']
|
'Recursive Hiding': [true, 'Hide replies of hidden posts, recursively.']
|
||||||
'Thread Hiding': [true, 'Add buttons to hide entire threads.']
|
|
||||||
'Reply Hiding': [true, 'Add buttons to hide single replies.']
|
|
||||||
'Stubs': [true, 'Show stubs of hidden threads / replies.']
|
|
||||||
'Images':
|
'Images':
|
||||||
'Auto-GIF': [false, 'Animate GIF thumbnails (disabled on /gif/, /wsg/).']
|
'Auto-GIF': [false, 'Animate GIF thumbnails (disabled on /gif/, /wsg/).']
|
||||||
'Image Expansion': [true, 'Expand images inline.']
|
'Image Expansion': [true, 'Expand images inline.']
|
||||||
@ -31,8 +30,7 @@ Config =
|
|||||||
'Menu':
|
'Menu':
|
||||||
'Menu': [true, 'Add a drop-down menu to posts.']
|
'Menu': [true, 'Add a drop-down menu to posts.']
|
||||||
'Report Link': [true, 'Add a report link to the menu.']
|
'Report Link': [true, 'Add a report link to the menu.']
|
||||||
'Thread Hiding Link': [true, 'Add a link to hide entire threads.']
|
'Post Hiding Link': [true, 'Add a link to hide threads and replies.']
|
||||||
'Reply Hiding Link': [true, 'Add a link to hide single replies.']
|
|
||||||
'Delete Link': [true, 'Add post and image deletion links to the menu.']
|
'Delete Link': [true, 'Add post and image deletion links to the menu.']
|
||||||
<% if (type === 'crx') { %>
|
<% if (type === 'crx') { %>
|
||||||
'Download Link': [true, 'Add a download with original filename link to the menu.']
|
'Download Link': [true, 'Add a download with original filename link to the menu.']
|
||||||
@ -143,7 +141,6 @@ Config =
|
|||||||
'Threads per Page': 0
|
'Threads per Page': 0
|
||||||
'Open threads in a new tab': false
|
'Open threads in a new tab': false
|
||||||
'Show Replies': true
|
'Show Replies': true
|
||||||
'Anchor Hidden Threads': true
|
|
||||||
'Refreshed Navigation': false
|
'Refreshed Navigation': false
|
||||||
Header:
|
Header:
|
||||||
'Header auto-hide': false
|
'Header auto-hide': false
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
class DataBoard
|
class DataBoard
|
||||||
@keys = ['pinnedThreads', 'hiddenThreads', 'hiddenPosts', 'lastReadPosts', 'yourPosts', 'watchedThreads']
|
@keys = ['pinnedThreads', 'hiddenPosts', 'lastReadPosts', 'yourPosts', 'watchedThreads']
|
||||||
|
|
||||||
constructor: (@key, sync, dontClean) ->
|
constructor: (@key, sync, dontClean) ->
|
||||||
@data = Conf[key]
|
@data = Conf[key]
|
||||||
|
|||||||
@ -3,8 +3,7 @@ Get =
|
|||||||
{OP} = thread
|
{OP} = thread
|
||||||
excerpt = OP.info.subject?.trim() or
|
excerpt = OP.info.subject?.trim() or
|
||||||
OP.info.comment.replace(/\n+/g, ' // ') or
|
OP.info.comment.replace(/\n+/g, ' // ') or
|
||||||
Conf['Anonymize'] and 'Anonymous' or
|
OP.getNameBlock()
|
||||||
$('.nameBlock', OP.nodes.info).textContent.trim()
|
|
||||||
if excerpt.length > 70
|
if excerpt.length > 70
|
||||||
excerpt = "#{excerpt[...67]}..."
|
excerpt = "#{excerpt[...67]}..."
|
||||||
"/#{thread.board}/ - #{excerpt}"
|
"/#{thread.board}/ - #{excerpt}"
|
||||||
@ -233,6 +232,6 @@ Get =
|
|||||||
thread = g.threads["#{boardID}.#{threadID}"] or
|
thread = g.threads["#{boardID}.#{threadID}"] or
|
||||||
new Thread threadID, board
|
new Thread threadID, board
|
||||||
post = new Post Build.post(o, true), thread, board, {isArchived: true}
|
post = new Post Build.post(o, true), thread, board, {isArchived: true}
|
||||||
$('.page-num', post.nodes.info).hidden = true
|
$('.page-num', post.nodes.info)?.hidden = true
|
||||||
Main.callbackNodes Post, [post]
|
Main.callbackNodes Post, [post]
|
||||||
Get.insert post, root, context
|
Get.insert post, root, context
|
||||||
|
|||||||
@ -38,15 +38,11 @@ Index =
|
|||||||
repliesEntry =
|
repliesEntry =
|
||||||
el: $.el 'label',
|
el: $.el 'label',
|
||||||
innerHTML: '<input type=checkbox name="Show Replies"> Show replies'
|
innerHTML: '<input type=checkbox name="Show Replies"> Show replies'
|
||||||
anchorEntry =
|
|
||||||
el: $.el 'label',
|
|
||||||
innerHTML: '<input type=checkbox name="Anchor Hidden Threads"> Anchor hidden threads'
|
|
||||||
title: 'Move hidden threads at the end of the index.'
|
|
||||||
refNavEntry =
|
refNavEntry =
|
||||||
el: $.el 'label',
|
el: $.el 'label',
|
||||||
innerHTML: '<input type=checkbox name="Refreshed Navigation"> Refreshed navigation'
|
innerHTML: '<input type=checkbox name="Refreshed Navigation"> Refreshed navigation'
|
||||||
title: 'Refresh index when navigating through pages.'
|
title: 'Refresh index when navigating through pages.'
|
||||||
for label in [targetEntry, repliesEntry, anchorEntry, refNavEntry]
|
for label in [targetEntry, repliesEntry, refNavEntry]
|
||||||
input = label.el.firstChild
|
input = label.el.firstChild
|
||||||
{name} = input
|
{name} = input
|
||||||
input.checked = Conf[name]
|
input.checked = Conf[name]
|
||||||
@ -56,15 +52,13 @@ Index =
|
|||||||
$.on input, 'change', @cb.target
|
$.on input, 'change', @cb.target
|
||||||
when 'Show Replies'
|
when 'Show Replies'
|
||||||
$.on input, 'change', @cb.replies
|
$.on input, 'change', @cb.replies
|
||||||
when 'Anchor Hidden Threads'
|
|
||||||
$.on input, 'change', @cb.sort
|
|
||||||
|
|
||||||
$.event 'AddMenuEntry',
|
$.event 'AddMenuEntry',
|
||||||
type: 'header'
|
type: 'header'
|
||||||
el: $.el 'span',
|
el: $.el 'span',
|
||||||
textContent: 'Index Navigation'
|
textContent: 'Index Navigation'
|
||||||
order: 90
|
order: 90
|
||||||
subEntries: [threadNumEntry, targetEntry, repliesEntry, anchorEntry, refNavEntry]
|
subEntries: [threadNumEntry, targetEntry, repliesEntry, refNavEntry]
|
||||||
|
|
||||||
$.addClass doc, 'index-loading'
|
$.addClass doc, 'index-loading'
|
||||||
@update()
|
@update()
|
||||||
@ -124,24 +118,7 @@ Index =
|
|||||||
$.event 'AddMenuEntry',
|
$.event 'AddMenuEntry',
|
||||||
type: 'post'
|
type: 'post'
|
||||||
el: $.el 'a', href: 'javascript:;'
|
el: $.el 'a', href: 'javascript:;'
|
||||||
order: 5
|
order: 19
|
||||||
open: ({thread}) ->
|
|
||||||
return false if Conf['Index Mode'] isnt 'catalog'
|
|
||||||
@el.textContent = if thread.isHidden
|
|
||||||
'Unhide thread'
|
|
||||||
else
|
|
||||||
'Hide thread'
|
|
||||||
$.off @el, 'click', @cb if @cb
|
|
||||||
@cb = ->
|
|
||||||
$.event 'CloseMenu'
|
|
||||||
Index.toggleHide thread
|
|
||||||
$.on @el, 'click', @cb
|
|
||||||
true
|
|
||||||
|
|
||||||
$.event 'AddMenuEntry',
|
|
||||||
type: 'post'
|
|
||||||
el: $.el 'a', href: 'javascript:;'
|
|
||||||
order: 6
|
|
||||||
open: ({thread}) ->
|
open: ({thread}) ->
|
||||||
return false if Conf['Index Mode'] isnt 'catalog'
|
return false if Conf['Index Mode'] isnt 'catalog'
|
||||||
@el.textContent = if thread.isPinned
|
@el.textContent = if thread.isPinned
|
||||||
@ -166,7 +143,7 @@ Index =
|
|||||||
return if e.button isnt 0
|
return if e.button isnt 0
|
||||||
thread = g.threads[@parentNode.dataset.fullID]
|
thread = g.threads[@parentNode.dataset.fullID]
|
||||||
if e.shiftKey
|
if e.shiftKey
|
||||||
Index.toggleHide thread
|
PostHiding.toggle thread.OP
|
||||||
else if e.altKey
|
else if e.altKey
|
||||||
Index.togglePin thread
|
Index.togglePin thread
|
||||||
else
|
else
|
||||||
@ -194,15 +171,6 @@ Index =
|
|||||||
offsetX: 15
|
offsetX: 15
|
||||||
offsetY: -20
|
offsetY: -20
|
||||||
setTimeout (-> el.hidden = false if el.parentNode), .25 * $.SECOND
|
setTimeout (-> el.hidden = false if el.parentNode), .25 * $.SECOND
|
||||||
toggleHide: (thread) ->
|
|
||||||
$.rm thread.catalogView.nodes.root
|
|
||||||
if Index.showHiddenThreads
|
|
||||||
ThreadHiding.show thread
|
|
||||||
return unless ThreadHiding.db.get {boardID: thread.board.ID, threadID: thread.ID}
|
|
||||||
# Don't save when un-hiding filtered threads.
|
|
||||||
else
|
|
||||||
ThreadHiding.hide thread
|
|
||||||
ThreadHiding.saveHiddenState thread
|
|
||||||
togglePin: (thread) ->
|
togglePin: (thread) ->
|
||||||
data =
|
data =
|
||||||
boardID: thread.board.ID
|
boardID: thread.board.ID
|
||||||
@ -259,7 +227,10 @@ Index =
|
|||||||
else
|
else
|
||||||
'Show'
|
'Show'
|
||||||
Index.sort()
|
Index.sort()
|
||||||
Index.buildIndex()
|
if Conf['Index Mode'] is 'paged' and Index.getCurrentPage() > 0
|
||||||
|
Index.pageNav 0
|
||||||
|
else
|
||||||
|
Index.buildIndex()
|
||||||
mode: (e) ->
|
mode: (e) ->
|
||||||
Index.cb.toggleCatalogMode()
|
Index.cb.toggleCatalogMode()
|
||||||
Index.togglePagelist()
|
Index.togglePagelist()
|
||||||
@ -289,7 +260,6 @@ Index =
|
|||||||
Index.buildIndex() if e
|
Index.buildIndex() if e
|
||||||
threadsNum: ->
|
threadsNum: ->
|
||||||
return unless Conf['Index Mode'] is 'paged'
|
return unless Conf['Index Mode'] is 'paged'
|
||||||
Index.buildPagelist()
|
|
||||||
Index.buildIndex()
|
Index.buildIndex()
|
||||||
target: ->
|
target: ->
|
||||||
for threadID, thread of g.BOARD.threads when thread.catalogView
|
for threadID, thread of g.BOARD.threads when thread.catalogView
|
||||||
@ -367,7 +337,6 @@ Index =
|
|||||||
Index.currentPage = pageNum
|
Index.currentPage = pageNum
|
||||||
return if Conf['Index Mode'] isnt 'paged'
|
return if Conf['Index Mode'] isnt 'paged'
|
||||||
Index.buildIndex()
|
Index.buildIndex()
|
||||||
Index.setPage()
|
|
||||||
Index.scrollToIndex()
|
Index.scrollToIndex()
|
||||||
|
|
||||||
getThreadsNumPerPage: ->
|
getThreadsNumPerPage: ->
|
||||||
@ -376,11 +345,7 @@ Index =
|
|||||||
else
|
else
|
||||||
Index.threadsNumPerPage
|
Index.threadsNumPerPage
|
||||||
getPagesNum: ->
|
getPagesNum: ->
|
||||||
numThreads = if Index.isSearching
|
Math.ceil Index.sortedThreads.length / Index.getThreadsNumPerPage()
|
||||||
Index.sortedNodes.length / 2
|
|
||||||
else
|
|
||||||
Index.liveThreadIDs.length
|
|
||||||
Math.ceil numThreads / Index.getThreadsNumPerPage()
|
|
||||||
getMaxPageNum: ->
|
getMaxPageNum: ->
|
||||||
Math.max 0, Index.getPagesNum() - 1
|
Math.max 0, Index.getPagesNum() - 1
|
||||||
togglePagelist: ->
|
togglePagelist: ->
|
||||||
@ -430,7 +395,7 @@ Index =
|
|||||||
Index.cb.toggleHiddenThreads() if Index.showHiddenThreads
|
Index.cb.toggleHiddenThreads() if Index.showHiddenThreads
|
||||||
return
|
return
|
||||||
Index.hideLabel.hidden = false
|
Index.hideLabel.hidden = false
|
||||||
$('#hidden-count', Index.navLinks).textContent = if hiddenCount is 1
|
$('#hidden-count', Index.hideLabel).textContent = if hiddenCount is 1
|
||||||
'1 hidden thread'
|
'1 hidden thread'
|
||||||
else
|
else
|
||||||
"#{hiddenCount} hidden threads"
|
"#{hiddenCount} hidden threads"
|
||||||
@ -508,12 +473,10 @@ Index =
|
|||||||
Index.parseThreadList pages
|
Index.parseThreadList pages
|
||||||
Index.buildThreads()
|
Index.buildThreads()
|
||||||
Index.sort()
|
Index.sort()
|
||||||
Index.buildPagelist()
|
|
||||||
if pageNum?
|
if pageNum?
|
||||||
Index.pageNav pageNum
|
Index.pageNav pageNum
|
||||||
return
|
return
|
||||||
Index.buildIndex()
|
Index.buildIndex()
|
||||||
Index.setPage()
|
|
||||||
parseThreadList: (pages) ->
|
parseThreadList: (pages) ->
|
||||||
Index.threadsNumPerPage = pages[0].threads.length
|
Index.threadsNumPerPage = pages[0].threads.length
|
||||||
Index.liveThreadData = pages.reduce ((arr, next) -> arr.concat next.threads), []
|
Index.liveThreadData = pages.reduce ((arr, next) -> arr.concat next.threads), []
|
||||||
@ -527,7 +490,7 @@ Index =
|
|||||||
posts = []
|
posts = []
|
||||||
for threadData, i in Index.liveThreadData
|
for threadData, i in Index.liveThreadData
|
||||||
threadRoot = Build.thread g.BOARD, threadData
|
threadRoot = Build.thread g.BOARD, threadData
|
||||||
Index.nodes.push threadRoot, $.el 'hr'
|
Index.nodes.push threadRoot
|
||||||
if thread = g.BOARD.threads[threadData.no]
|
if thread = g.BOARD.threads[threadData.no]
|
||||||
thread.setPage i // Index.threadsNumPerPage
|
thread.setPage i // Index.threadsNumPerPage
|
||||||
thread.setCount 'post', threadData.replies + 1, threadData.bumplimit
|
thread.setCount 'post', threadData.replies + 1, threadData.bumplimit
|
||||||
@ -548,16 +511,18 @@ Index =
|
|||||||
error: err
|
error: err
|
||||||
Main.handleErrors errors if errors
|
Main.handleErrors errors if errors
|
||||||
|
|
||||||
# Add the threads and <hr>s in a container to make sure all features work.
|
|
||||||
$.nodes Index.nodes
|
|
||||||
Main.callbackNodes Thread, threads
|
Main.callbackNodes Thread, threads
|
||||||
Main.callbackNodes Post, posts
|
Main.callbackNodes Post, posts
|
||||||
Index.updateHideLabel()
|
Index.updateHideLabel()
|
||||||
$.event 'IndexRefresh'
|
$.event 'IndexRefresh'
|
||||||
buildReplies: (threadRoots) ->
|
buildHRs: (threadRoots) ->
|
||||||
|
for i in [0...threadRoots.length] by 1
|
||||||
|
threadRoots.splice (i * 2) + 1, 0, $.el 'hr'
|
||||||
|
return
|
||||||
|
buildReplies: (threads) ->
|
||||||
|
return unless Conf['Show Replies']
|
||||||
posts = []
|
posts = []
|
||||||
for threadRoot in threadRoots by 2
|
for thread in threads
|
||||||
thread = Get.threadFromRoot threadRoot
|
|
||||||
i = Index.liveThreadIDs.indexOf thread.ID
|
i = Index.liveThreadIDs.indexOf thread.ID
|
||||||
continue unless lastReplies = Index.liveThreadData[i].last_replies
|
continue unless lastReplies = Index.liveThreadData[i].last_replies
|
||||||
nodes = []
|
nodes = []
|
||||||
@ -574,20 +539,16 @@ Index =
|
|||||||
errors.push
|
errors.push
|
||||||
message: "Parsing of Post No.#{data.no} failed. Post will be skipped."
|
message: "Parsing of Post No.#{data.no} failed. Post will be skipped."
|
||||||
error: err
|
error: err
|
||||||
$.add threadRoot, nodes
|
$.add thread.OP.nodes.root.parentNode, nodes
|
||||||
|
|
||||||
Main.handleErrors errors if errors
|
Main.handleErrors errors if errors
|
||||||
Main.callbackNodes Post, posts
|
Main.callbackNodes Post, posts
|
||||||
buildCatalogViews: ->
|
buildCatalogViews: ->
|
||||||
threads = Index.sortedNodes
|
|
||||||
.filter (n, i) -> !(i % 2)
|
|
||||||
.map (threadRoot) -> Get.threadFromRoot threadRoot
|
|
||||||
.filter (thread) -> !thread.isHidden isnt Index.showHiddenThreads
|
|
||||||
catalogThreads = []
|
catalogThreads = []
|
||||||
for thread in threads when !thread.catalogView
|
for thread in Index.sortedThreads when !thread.catalogView
|
||||||
catalogThreads.push new CatalogThread Build.catalogThread(thread), thread
|
catalogThreads.push new CatalogThread Build.catalogThread(thread), thread
|
||||||
Main.callbackNodes CatalogThread, catalogThreads
|
Main.callbackNodes CatalogThread, catalogThreads
|
||||||
threads.map (thread) -> thread.catalogView.nodes.root
|
Index.sortedThreads.map (thread) -> thread.catalogView.nodes.root
|
||||||
sizeCatalogViews: (nodes) ->
|
sizeCatalogViews: (nodes) ->
|
||||||
# XXX When browsers support CSS3 attr(), use it instead.
|
# XXX When browsers support CSS3 attr(), use it instead.
|
||||||
size = if Conf['Index Size'] is 'small' then 150 else 250
|
size = if Conf['Index Size'] is 'small' then 150 else 250
|
||||||
@ -615,36 +576,43 @@ Index =
|
|||||||
sortedThreadIDs = [Index.liveThreadData...].sort((a, b) -> b.replies - a.replies).map (data) -> data.no
|
sortedThreadIDs = [Index.liveThreadData...].sort((a, b) -> b.replies - a.replies).map (data) -> data.no
|
||||||
when 'filecount'
|
when 'filecount'
|
||||||
sortedThreadIDs = [Index.liveThreadData...].sort((a, b) -> b.images - a.images).map (data) -> data.no
|
sortedThreadIDs = [Index.liveThreadData...].sort((a, b) -> b.images - a.images).map (data) -> data.no
|
||||||
Index.sortedNodes = []
|
Index.sortedThreads = sortedThreadIDs
|
||||||
for threadID in sortedThreadIDs
|
.map (threadID) -> Get.threadFromRoot Index.nodes[Index.liveThreadIDs.indexOf threadID]
|
||||||
i = Index.liveThreadIDs.indexOf(threadID) * 2
|
.filter (thread) -> thread.isHidden is Index.showHiddenThreads
|
||||||
Index.sortedNodes.push Index.nodes[i], Index.nodes[i + 1]
|
|
||||||
if Index.isSearching
|
if Index.isSearching
|
||||||
Index.sortedNodes = Index.querySearch(Index.searchInput.value) or Index.sortedNodes
|
Index.sortedThreads = Index.querySearch(Index.searchInput.value) or Index.sortedThreads
|
||||||
# Sticky threads
|
# Sticky threads
|
||||||
Index.sortOnTop (thread) -> thread.isSticky
|
Index.sortOnTop (thread) -> thread.isSticky
|
||||||
# Highlighted threads
|
# Highlighted threads
|
||||||
Index.sortOnTop (thread) -> thread.isOnTop or thread.isPinned
|
Index.sortOnTop (thread) -> thread.isOnTop or thread.isPinned
|
||||||
# Non-hidden threads
|
|
||||||
Index.sortOnTop((thread) -> !thread.isHidden) if Conf['Anchor Hidden Threads']
|
|
||||||
sortOnTop: (match) ->
|
sortOnTop: (match) ->
|
||||||
offset = 0
|
offset = 0
|
||||||
for threadRoot, i in Index.sortedNodes by 2 when match Get.threadFromRoot threadRoot
|
for thread, i in Index.sortedThreads when match thread
|
||||||
Index.sortedNodes.splice offset++ * 2, 0, Index.sortedNodes.splice(i, 2)...
|
Index.sortedThreads.splice offset++, 0, Index.sortedThreads.splice(i, 1)[0]
|
||||||
return
|
return
|
||||||
buildIndex: ->
|
buildIndex: ->
|
||||||
switch Conf['Index Mode']
|
switch Conf['Index Mode']
|
||||||
when 'paged'
|
when 'paged'
|
||||||
pageNum = Index.getCurrentPage()
|
pageNum = Index.getCurrentPage()
|
||||||
nodesPerPage = Index.getThreadsNumPerPage() * 2
|
if pageNum > Index.getMaxPageNum()
|
||||||
nodes = Index.sortedNodes[nodesPerPage * pageNum ... nodesPerPage * (pageNum + 1)]
|
# Go to the last available page if we were past the limit.
|
||||||
|
Index.pageNav Index.getMaxPageNum()
|
||||||
|
return
|
||||||
|
threadsPerPage = Index.getThreadsNumPerPage()
|
||||||
|
threads = Index.sortedThreads[threadsPerPage * pageNum ... threadsPerPage * (pageNum + 1)]
|
||||||
|
nodes = threads.map (thread) -> thread.OP.nodes.root.parentNode
|
||||||
|
Index.buildReplies threads
|
||||||
|
Index.buildHRs nodes
|
||||||
|
Index.buildPagelist()
|
||||||
|
Index.setPage()
|
||||||
when 'catalog'
|
when 'catalog'
|
||||||
nodes = Index.buildCatalogViews()
|
nodes = Index.buildCatalogViews()
|
||||||
Index.sizeCatalogViews nodes
|
Index.sizeCatalogViews nodes
|
||||||
else
|
else
|
||||||
nodes = Index.sortedNodes
|
nodes = Index.sortedThreads.map (thread) -> thread.OP.nodes.root.parentNode
|
||||||
|
Index.buildReplies Index.sortedThreads
|
||||||
|
Index.buildHRs nodes
|
||||||
$.rmAll Index.root
|
$.rmAll Index.root
|
||||||
Index.buildReplies nodes if Conf['Show Replies'] and Conf['Index Mode'] isnt 'catalog'
|
|
||||||
$.add Index.root, nodes
|
$.add Index.root, nodes
|
||||||
$.event 'IndexBuild', nodes
|
$.event 'IndexBuild', nodes
|
||||||
|
|
||||||
@ -672,23 +640,17 @@ Index =
|
|||||||
delete Index.searchInput.dataset.searching
|
delete Index.searchInput.dataset.searching
|
||||||
<% } %>
|
<% } %>
|
||||||
Index.sort()
|
Index.sort()
|
||||||
# Go to the last available page if we were past the limit.
|
if Conf['Index Mode'] is 'paged' and Index.currentPage isnt Math.min pageNum, Index.getMaxPageNum()
|
||||||
pageNum = Math.min pageNum, Index.getMaxPageNum() if Conf['Index Mode'] is 'paged'
|
# Go to the last available page if we were past the limit.
|
||||||
Index.buildPagelist()
|
|
||||||
if Index.currentPage is pageNum
|
|
||||||
Index.buildIndex()
|
|
||||||
Index.setPage()
|
|
||||||
else
|
|
||||||
Index.pageNav pageNum
|
Index.pageNav pageNum
|
||||||
|
else
|
||||||
|
Index.buildIndex()
|
||||||
querySearch: (query) ->
|
querySearch: (query) ->
|
||||||
return unless keywords = query.toLowerCase().match /\S+/g
|
return unless keywords = query.toLowerCase().match /\S+/g
|
||||||
Index.search keywords
|
Index.search keywords
|
||||||
search: (keywords) ->
|
search: (keywords) ->
|
||||||
found = []
|
Index.sortedThreads.filter (thread) ->
|
||||||
for threadRoot, i in Index.sortedNodes by 2
|
Index.searchMatch thread, keywords
|
||||||
if Index.searchMatch Get.threadFromRoot(threadRoot), keywords
|
|
||||||
found.push Index.sortedNodes[i], Index.sortedNodes[i + 1]
|
|
||||||
found
|
|
||||||
searchMatch: (thread, keywords) ->
|
searchMatch: (thread, keywords) ->
|
||||||
{info, file} = thread.OP
|
{info, file} = thread.OP
|
||||||
text = []
|
text = []
|
||||||
|
|||||||
@ -79,19 +79,18 @@ Main =
|
|||||||
initFeature 'Redirect', Redirect
|
initFeature 'Redirect', Redirect
|
||||||
initFeature 'Resurrect Quotes', Quotify
|
initFeature 'Resurrect Quotes', Quotify
|
||||||
initFeature 'Filter', Filter
|
initFeature 'Filter', Filter
|
||||||
initFeature 'Thread Hiding', ThreadHiding
|
initFeature 'Post Hiding', PostHiding
|
||||||
initFeature 'Reply Hiding', PostHiding
|
|
||||||
initFeature 'Recursive', Recursive
|
initFeature 'Recursive', Recursive
|
||||||
initFeature 'Strike-through Quotes', QuoteStrikeThrough
|
initFeature 'Strike-through Quotes', QuoteStrikeThrough
|
||||||
initFeature 'Quick Reply', QR
|
initFeature 'Quick Reply', QR
|
||||||
initFeature 'Menu', Menu
|
initFeature 'Menu', Menu
|
||||||
initFeature 'Index Generator (Menu)', Index.menu
|
initFeature 'Index Generator (Menu)', Index.menu
|
||||||
initFeature 'Report Link', ReportLink
|
initFeature 'Report Link', ReportLink
|
||||||
initFeature 'Thread Hiding (Menu)', ThreadHiding.menu
|
initFeature 'Post Hiding (Menu)', PostHiding.menu
|
||||||
initFeature 'Reply Hiding (Menu)', PostHiding.menu
|
|
||||||
initFeature 'Delete Link', DeleteLink
|
initFeature 'Delete Link', DeleteLink
|
||||||
initFeature 'Filter (Menu)', Filter.menu
|
initFeature 'Filter (Menu)', Filter.menu
|
||||||
initFeature 'Download Link', DownloadLink
|
initFeature 'Download Link', DownloadLink
|
||||||
|
initFeature 'Labels list', Labels
|
||||||
initFeature 'Archive Link', ArchiveLink
|
initFeature 'Archive Link', ArchiveLink
|
||||||
initFeature 'Quote Inlining', QuoteInline
|
initFeature 'Quote Inlining', QuoteInline
|
||||||
initFeature 'Quote Previewing', QuotePreview
|
initFeature 'Quote Previewing', QuotePreview
|
||||||
|
|||||||
@ -52,6 +52,8 @@ class Post
|
|||||||
@parseQuotes()
|
@parseQuotes()
|
||||||
@parseFile that
|
@parseFile that
|
||||||
|
|
||||||
|
@labels = []
|
||||||
|
@highlights = []
|
||||||
@isDead = false
|
@isDead = false
|
||||||
@isHidden = false
|
@isHidden = false
|
||||||
|
|
||||||
@ -106,7 +108,7 @@ class Post
|
|||||||
|
|
||||||
# ES6 Set when?
|
# ES6 Set when?
|
||||||
fullID = "#{match[1]}.#{match[2]}"
|
fullID = "#{match[1]}.#{match[2]}"
|
||||||
@quotes.push fullID if @quotes.indexOf(fullID) is -1
|
@quotes.push fullID unless fullID in @quotes
|
||||||
|
|
||||||
parseFile: (that) ->
|
parseFile: (that) ->
|
||||||
return unless (fileEl = $ '.file', @nodes.post) and thumb = $ 'img[data-md5]', fileEl
|
return unless (fileEl = $ '.file', @nodes.post) and thumb = $ 'img[data-md5]', fileEl
|
||||||
@ -151,6 +153,76 @@ class Post
|
|||||||
$.rmClass node, 'desktop'
|
$.rmClass node, 'desktop'
|
||||||
return
|
return
|
||||||
|
|
||||||
|
getNameBlock: ->
|
||||||
|
if Conf['Anonymize']
|
||||||
|
'Anonymous'
|
||||||
|
else
|
||||||
|
$('.nameBlock', @nodes.info).textContent.trim()
|
||||||
|
|
||||||
|
hide: (label, makeStub=Conf['Stubs'], hideRecursively=Conf['Recursive Hiding']) ->
|
||||||
|
@labels.push label unless label in @labels
|
||||||
|
return if @isHidden
|
||||||
|
@isHidden = true
|
||||||
|
|
||||||
|
for quotelink in Get.allQuotelinksLinkingTo @
|
||||||
|
$.addClass quotelink, 'filtered'
|
||||||
|
|
||||||
|
if hideRecursively
|
||||||
|
label = "Recursively hidden for quoting No.#{@}"
|
||||||
|
Recursive.apply 'hide', @, label, makeStub, true
|
||||||
|
Recursive.add 'hide', @, label, makeStub, true
|
||||||
|
|
||||||
|
if !@isReply
|
||||||
|
@thread.hide()
|
||||||
|
return
|
||||||
|
|
||||||
|
unless makeStub
|
||||||
|
@nodes.root.hidden = true
|
||||||
|
return
|
||||||
|
|
||||||
|
@nodes.post.hidden = true
|
||||||
|
@nodes.post.previousElementSibling.hidden = true
|
||||||
|
@nodes.stub = $.el 'div',
|
||||||
|
className: 'stub'
|
||||||
|
$.add @nodes.stub, [
|
||||||
|
PostHiding.makeButton false
|
||||||
|
$.tn " #{@getNameBlock()}"
|
||||||
|
]
|
||||||
|
$.add @nodes.stub, Menu.makeButton() if Conf['Menu']
|
||||||
|
$.prepend @nodes.root, @nodes.stub
|
||||||
|
show: (showRecursively=Conf['Recursive Hiding']) ->
|
||||||
|
return if !@isHidden
|
||||||
|
@isHidden = false
|
||||||
|
@labels = @labels.filter (label) ->
|
||||||
|
# This is lame.
|
||||||
|
!/^(Manually hidden|Recursively hidden|Hidden by)/.test label
|
||||||
|
|
||||||
|
for quotelink in Get.allQuotelinksLinkingTo @
|
||||||
|
$.rmClass quotelink, 'filtered'
|
||||||
|
|
||||||
|
if showRecursively
|
||||||
|
Recursive.apply 'show', @, true
|
||||||
|
Recursive.rm 'hide', @
|
||||||
|
|
||||||
|
if !@isReply
|
||||||
|
@thread.show()
|
||||||
|
return
|
||||||
|
|
||||||
|
unless @nodes.stub
|
||||||
|
@nodes.root.hidden = false
|
||||||
|
return
|
||||||
|
@nodes.post.hidden = false
|
||||||
|
@nodes.post.previousElementSibling.hidden = false
|
||||||
|
$.rm @nodes.stub
|
||||||
|
delete @nodes.stub
|
||||||
|
highlight: (label, highlight, top) ->
|
||||||
|
@labels.push label
|
||||||
|
unless highlight in @highlights
|
||||||
|
@highlights.push highlight
|
||||||
|
$.addClass @nodes.root, highlight
|
||||||
|
if !@isReply and top
|
||||||
|
@thread.isOnTop = true
|
||||||
|
|
||||||
kill: (file) ->
|
kill: (file) ->
|
||||||
if file
|
if file
|
||||||
return if @file.isDead
|
return if @file.isDead
|
||||||
|
|||||||
@ -123,18 +123,16 @@ Settings =
|
|||||||
div = $.el 'div',
|
div = $.el 'div',
|
||||||
innerHTML: "<button></button><span class=description>: Clear manually-hidden threads and posts on all boards. Reload the page to apply."
|
innerHTML: "<button></button><span class=description>: Clear manually-hidden threads and posts on all boards. Reload the page to apply."
|
||||||
button = $ 'button', div
|
button = $ 'button', div
|
||||||
$.get {hiddenThreads: {}, hiddenPosts: {}}, ({hiddenThreads, hiddenPosts}) ->
|
$.get 'hiddenPosts', {}, ({hiddenPosts}) ->
|
||||||
hiddenNum = 0
|
hiddenNum = 0
|
||||||
for ID, board of hiddenThreads.boards
|
|
||||||
hiddenNum += Object.keys(board).length
|
|
||||||
for ID, board of hiddenPosts.boards
|
for ID, board of hiddenPosts.boards
|
||||||
for ID, thread of board
|
for ID, thread of board
|
||||||
hiddenNum += Object.keys(thread).length
|
hiddenNum += Object.keys(thread).length
|
||||||
button.textContent = "Hidden: #{hiddenNum}"
|
button.textContent = "Hidden: #{hiddenNum}"
|
||||||
$.on button, 'click', ->
|
$.on button, 'click', ->
|
||||||
@textContent = 'Hidden: 0'
|
@textContent = 'Hidden: 0'
|
||||||
$.delete ['hiddenThreads', 'hiddenPosts']
|
$.delete 'hiddenPosts'
|
||||||
$.after $('input[name="Stubs"]', section).parentNode.parentNode, div
|
$.after $('input[name="Recursive Hiding"]', section).parentNode.parentNode, div
|
||||||
export: ->
|
export: ->
|
||||||
# Make sure to export the most recent data.
|
# Make sure to export the most recent data.
|
||||||
$.get Conf, (Conf) ->
|
$.get Conf, (Conf) ->
|
||||||
|
|||||||
@ -62,6 +62,17 @@ class Thread
|
|||||||
@isPinned = false
|
@isPinned = false
|
||||||
$.rmClass @catalogView.nodes.root, 'pinned' if @catalogView
|
$.rmClass @catalogView.nodes.root, 'pinned' if @catalogView
|
||||||
|
|
||||||
|
hide: ->
|
||||||
|
return if @isHidden
|
||||||
|
@isHidden = true
|
||||||
|
if button = $ '.hide-post-button', @OP.nodes.root
|
||||||
|
$.replace button, PostHiding.makeButton false
|
||||||
|
show: ->
|
||||||
|
return if !@isHidden
|
||||||
|
@isHidden = false
|
||||||
|
if button = $ '.show-post-button', @OP.nodes.root
|
||||||
|
$.replace button, PostHiding.makeButton true
|
||||||
|
|
||||||
kill: ->
|
kill: ->
|
||||||
@isDead = true
|
@isDead = true
|
||||||
|
|
||||||
|
|||||||
@ -84,7 +84,9 @@ UI = do ->
|
|||||||
|
|
||||||
insertEntry: (entry, parent, data) ->
|
insertEntry: (entry, parent, data) ->
|
||||||
if typeof entry.open is 'function'
|
if typeof entry.open is 'function'
|
||||||
return unless entry.open data
|
return unless entry.open data, (subEntry) =>
|
||||||
|
@parseEntry subEntry
|
||||||
|
entry.subEntries.push subEntry
|
||||||
$.add parent, entry.el
|
$.add parent, entry.el
|
||||||
|
|
||||||
return unless entry.subEntries
|
return unless entry.subEntries
|
||||||
|
|||||||
@ -43,7 +43,7 @@ ImageExpand =
|
|||||||
for post in [post].concat post.clones
|
for post in [post].concat post.clones
|
||||||
{file} = post
|
{file} = post
|
||||||
continue unless file and file.isImage and doc.contains post.nodes.root
|
continue unless file and file.isImage and doc.contains post.nodes.root
|
||||||
if ImageExpand.on and
|
if ImageExpand.on and !post.isHidden and
|
||||||
(!Conf['Expand spoilers'] and file.isSpoiler or
|
(!Conf['Expand spoilers'] and file.isSpoiler or
|
||||||
Conf['Expand from here'] and Header.getTopOf(file.thumb) < 0)
|
Conf['Expand from here'] and Header.getTopOf(file.thumb) < 0)
|
||||||
continue
|
continue
|
||||||
@ -76,7 +76,7 @@ ImageExpand =
|
|||||||
expand: (post, src) ->
|
expand: (post, src) ->
|
||||||
# Do not expand images of hidden/filtered replies, or already expanded pictures.
|
# Do not expand images of hidden/filtered replies, or already expanded pictures.
|
||||||
{thumb} = post.file
|
{thumb} = post.file
|
||||||
return if post.isHidden or post.file.isExpanded or $.hasClass thumb, 'expanding'
|
return if post.file.isExpanded or $.hasClass thumb, 'expanding'
|
||||||
$.addClass thumb, 'expanding'
|
$.addClass thumb, 'expanding'
|
||||||
if post.file.fullImage
|
if post.file.fullImage
|
||||||
# Expand already-loaded/ing picture.
|
# Expand already-loaded/ing picture.
|
||||||
|
|||||||
16
src/Menu/Labels.coffee
Normal file
16
src/Menu/Labels.coffee
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
Labels =
|
||||||
|
init: ->
|
||||||
|
return if !Conf['Menu']
|
||||||
|
|
||||||
|
$.event 'AddMenuEntry',
|
||||||
|
type: 'post'
|
||||||
|
el: $.el 'div', textContent: 'Labels'
|
||||||
|
order: 60
|
||||||
|
open: (post, addSubEntry) ->
|
||||||
|
{labels} = post.origin or post
|
||||||
|
return false unless labels.length
|
||||||
|
@subEntries.length = 0
|
||||||
|
for label in labels
|
||||||
|
addSubEntry el: $.el 'div', textContent: label
|
||||||
|
true
|
||||||
|
subEntries: []
|
||||||
@ -120,7 +120,7 @@ Keybinds =
|
|||||||
when Conf['Deselect reply']
|
when Conf['Deselect reply']
|
||||||
Keybinds.hl 0, threadRoot
|
Keybinds.hl 0, threadRoot
|
||||||
when Conf['Hide']
|
when Conf['Hide']
|
||||||
ThreadHiding.toggle thread if ThreadHiding.db
|
PostHiding.toggle thread.OP
|
||||||
else
|
else
|
||||||
return
|
return
|
||||||
e.preventDefault()
|
e.preventDefault()
|
||||||
|
|||||||
@ -38,8 +38,6 @@ Nav =
|
|||||||
|
|
||||||
getThread: ->
|
getThread: ->
|
||||||
for threadRoot in $$ '.thread'
|
for threadRoot in $$ '.thread'
|
||||||
thread = Get.threadFromRoot threadRoot
|
|
||||||
continue if thread.isHidden and !thread.stub
|
|
||||||
if Header.getTopOf(threadRoot) >= -threadRoot.getBoundingClientRect().height # not scrolled past
|
if Header.getTopOf(threadRoot) >= -threadRoot.getBoundingClientRect().height # not scrolled past
|
||||||
return threadRoot
|
return threadRoot
|
||||||
return $ '.board'
|
return $ '.board'
|
||||||
|
|||||||
@ -92,11 +92,7 @@ Unread =
|
|||||||
return
|
return
|
||||||
openNotification: (post) ->
|
openNotification: (post) ->
|
||||||
return unless Header.areNotificationsEnabled
|
return unless Header.areNotificationsEnabled
|
||||||
name = if Conf['Anonymize']
|
notif = new Notification "#{post.getNameBlock()} replied to you",
|
||||||
'Anonymous'
|
|
||||||
else
|
|
||||||
$('.nameBlock', post.nodes.info).textContent.trim()
|
|
||||||
notif = new Notification "#{name} replied to you",
|
|
||||||
body: post.info.comment
|
body: post.info.comment
|
||||||
icon: Favicon.logo
|
icon: Favicon.logo
|
||||||
notif.onclick = ->
|
notif.onclick = ->
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
QuoteStrikeThrough =
|
QuoteStrikeThrough =
|
||||||
init: ->
|
init: ->
|
||||||
return if !Conf['Reply Hiding'] and !Conf['Reply Hiding Link'] and !Conf['Filter']
|
return if !Conf['Post Hiding'] and !Conf['Post Hiding Link'] and !Conf['Filter']
|
||||||
|
|
||||||
Post.callbacks.push
|
Post.callbacks.push
|
||||||
name: 'Strike-through Quotes'
|
name: 'Strike-through Quotes'
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user