diff --git a/4chan_x.user.js b/4chan_x.user.js
index 1f0c22361..991de23e7 100644
--- a/4chan_x.user.js
+++ b/4chan_x.user.js
@@ -766,7 +766,7 @@
},
menu: {
init: function() {
- var apply, div, option;
+ var apply, div, makeStub;
if (g.VIEW !== 'index') {
return;
}
@@ -774,14 +774,14 @@
className: 'hide-thread-link',
textContent: 'Hide thread'
});
- option = $.el('label', {
- innerHTML: " Make stub"
- });
apply = $.el('a', {
textContent: 'Apply',
href: 'javascript:;'
});
$.on(apply, 'click', ThreadHiding.menu.hide);
+ makeStub = $.el('label', {
+ innerHTML: " Make stub"
+ });
return Menu.addEntry({
el: div,
open: function(post) {
@@ -795,9 +795,9 @@
},
children: [
{
- el: option
- }, {
el: apply
+ }, {
+ el: makeStub
}
]
});
@@ -901,13 +901,17 @@
});
},
node: function() {
- var thread, _ref;
+ var data, thread;
if (!this.isReply || this.isClone) {
return;
}
if (thread = ReplyHiding.hiddenPosts.threads[this.thread]) {
- if (_ref = this.ID, __indexOf.call(thread, _ref) >= 0) {
- ReplyHiding.hide(this);
+ if (data = thread[this]) {
+ if (data.thisPost) {
+ ReplyHiding.hide(this, data.makeStub, data.hideRecursively);
+ } else {
+ Recursive.hide(this, data.makeStub);
+ }
}
}
if (!Conf['Thread/Reply Hiding Buttons']) {
@@ -959,6 +963,67 @@
}
});
},
+ menu: {
+ init: function() {
+ var apply, div, makeStub, replies, thisPost;
+ div = $.el('div', {
+ className: 'hide-reply-link',
+ textContent: 'Hide reply'
+ });
+ apply = $.el('a', {
+ textContent: 'Apply',
+ href: 'javascript:;'
+ });
+ $.on(apply, 'click', ReplyHiding.menu.hide);
+ thisPost = $.el('label', {
+ innerHTML: ' This post'
+ });
+ replies = $.el('label', {
+ innerHTML: " Hide replies"
+ });
+ makeStub = $.el('label', {
+ innerHTML: " Make stub"
+ });
+ return Menu.addEntry({
+ el: div,
+ open: function(post) {
+ if (!post.isReply || post.isClone) {
+ return false;
+ }
+ ReplyHiding.menu.post = post;
+ return true;
+ },
+ children: [
+ {
+ el: apply
+ }, {
+ el: thisPost
+ }, {
+ el: replies
+ }, {
+ el: makeStub
+ }
+ ]
+ });
+ },
+ hide: function() {
+ var makeStub, parent, post, replies, thisPost;
+ parent = this.parentNode;
+ thisPost = $('input[name=thisPost]', parent).checked;
+ replies = $('input[name=replies]', parent).checked;
+ makeStub = $('input[name=makeStub]', parent).checked;
+ post = ReplyHiding.menu.post;
+ if (thisPost) {
+ ReplyHiding.hide(post, makeStub, replies);
+ } else if (replies) {
+ Recursive.hide(post, makeStub);
+ } else {
+ return;
+ }
+ ReplyHiding.saveHiddenState(post, true, thisPost, makeStub, replies);
+ return Menu.close();
+ }
+ },
makeButton: function(post, type) {
var a;
a = $.el('a', {
@@ -971,28 +1036,35 @@
});
return a;
},
- toggle: function(post) {
- var hiddenPosts, index, thread;
+ saveHiddenState: function(post, isHiding, thisPost, makeStub, hideRecursively) {
+ var hiddenPosts, thread;
hiddenPosts = ReplyHiding.getHiddenPosts();
- if (post.isHidden) {
- ReplyHiding.show(post);
- thread = hiddenPosts.threads[post.thread];
- if ((index = thread.indexOf(post.ID)) > -1) {
- if (thread.length === 1) {
- delete hiddenPosts.threads[post.thread];
- } else {
- thread.splice(index, 1);
- }
- }
- } else {
- ReplyHiding.hide(post);
+ if (isHiding) {
if (!(thread = hiddenPosts.threads[post.thread])) {
- thread = hiddenPosts.threads[post.thread] = [];
+ thread = hiddenPosts.threads[post.thread] = {};
+ }
+ thread[post] = {
+ thisPost: thisPost !== false,
+ makeStub: makeStub,
+ hideRecursively: hideRecursively
+ };
+ } else {
+ thread = hiddenPosts.threads[post.thread];
+ delete thread[post];
+ if (!Object.keys(thread).length) {
+ delete hiddenPosts.threads[post.thread];
}
- thread.push(post.ID);
}
return $.set("hiddenPosts." + g.BOARD, hiddenPosts);
},
+ toggle: function(post) {
+ if (post.isHidden) {
+ ReplyHiding.show(post);
+ } else {
+ ReplyHiding.hide(post);
+ }
+ return ReplyHiding.saveHiddenState(post, post.isHidden);
+ },
hide: function(post, makeStub, hideRecursively) {
var a, postInfo, quotelink, _i, _len, _ref;
if (makeStub == null) {
@@ -1014,6 +1086,7 @@
$.addClass(quotelink, 'filtered');
}
if (!makeStub) {
+ post.nodes.root.hidden = true;
return;
}
a = ReplyHiding.makeButton(post, 'show');
@@ -1033,6 +1106,8 @@
if (post.nodes.stub) {
$.rm(post.nodes.stub);
delete post.nodes.stub;
+ } else {
+ post.nodes.root.hidden = false;
}
post.isHidden = false;
_ref = Get.allQuotelinksLinkingTo(post);
@@ -1079,7 +1154,7 @@
_ref = g.posts;
for (ID in _ref) {
post = _ref[ID];
- if (!post.isReply || post.isHidden) {
+ if (!post.isReply) {
continue;
}
_ref1 = post.quotes;
@@ -3596,6 +3671,13 @@
$.log(err, 'Thread Hiding - Menu');
}
}
+ if (Conf['Reply Hiding']) {
+ try {
+ ReplyHiding.menu.init();
+ } catch (err) {
+ $.log(err, 'Reply Hiding - Menu');
+ }
+ }
if (Conf['Delete Link']) {
try {
DeleteLink.init();
diff --git a/src/features.coffee b/src/features.coffee
index 43b7d4d1f..716f51935 100644
--- a/src/features.coffee
+++ b/src/features.coffee
@@ -67,14 +67,14 @@ ThreadHiding =
className: 'hide-thread-link'
textContent: 'Hide thread'
- option = $.el 'label',
- innerHTML: " Make stub"
-
apply = $.el 'a',
textContent: 'Apply'
href: 'javascript:;'
$.on apply, 'click', ThreadHiding.menu.hide
+ makeStub = $.el 'label',
+ innerHTML: " Make stub"
+
Menu.addEntry
el: div
open: (post) ->
@@ -83,13 +83,12 @@ ThreadHiding =
return false
ThreadHiding.menu.thread = thread
true
- children: [{el: option}, {el: apply}]
+ children: [{el: apply}, {el: makeStub}]
hide: ->
makeStub = $('input', @parentNode).checked
{thread} = ThreadHiding.menu
ThreadHiding.hide thread, makeStub
ThreadHiding.saveHiddenState thread, makeStub
- # need to save if we made a stub or not
Menu.close()
makeButton: (thread, type) ->
@@ -169,8 +168,11 @@ ReplyHiding =
node: ->
return if !@isReply or @isClone
if thread = ReplyHiding.hiddenPosts.threads[@thread]
- if @ID in thread
- ReplyHiding.hide @
+ if data = thread[@]
+ if data.thisPost
+ ReplyHiding.hide @, data.makeStub, data.hideRecursively
+ else
+ Recursive.hide @, data.makeStub
return unless Conf['Thread/Reply Hiding Buttons']
$.replace $('.sideArrows', @nodes.root), ReplyHiding.makeButton @, 'hide'
@@ -203,6 +205,47 @@ ReplyHiding =
hiddenPosts.threads = threads
$.set "hiddenPosts.#{g.BOARD}", hiddenPosts
+ menu:
+ init: ->
+ div = $.el 'div',
+ className: 'hide-reply-link'
+ textContent: 'Hide reply'
+
+ apply = $.el 'a',
+ textContent: 'Apply'
+ href: 'javascript:;'
+ $.on apply, 'click', ReplyHiding.menu.hide
+
+ thisPost = $.el 'label',
+ innerHTML: ' This post'
+ replies = $.el 'label',
+ innerHTML: " Hide replies"
+ makeStub = $.el 'label',
+ innerHTML: " Make stub"
+
+ Menu.addEntry
+ el: div
+ open: (post) ->
+ if !post.isReply or post.isClone
+ return false
+ ReplyHiding.menu.post = post
+ true
+ children: [{el: apply}, {el: thisPost}, {el: replies}, {el: makeStub}]
+ hide: ->
+ parent = @parentNode
+ thisPost = $('input[name=thisPost]', parent).checked
+ replies = $('input[name=replies]', parent).checked
+ makeStub = $('input[name=makeStub]', parent).checked
+ {post} = ReplyHiding.menu
+ if thisPost
+ ReplyHiding.hide post, makeStub, replies
+ else if replies
+ Recursive.hide post, makeStub
+ else
+ return
+ ReplyHiding.saveHiddenState post, true, thisPost, makeStub, replies
+ Menu.close()
+
makeButton: (post, type) ->
a = $.el 'a',
className: "#{type}-reply-button"
@@ -211,24 +254,29 @@ ReplyHiding =
$.on a, 'click', -> ReplyHiding.toggle post
a
- toggle: (post) ->
+ saveHiddenState: (post, isHiding, thisPost, makeStub, hideRecursively) ->
# Get fresh hidden posts.
hiddenPosts = ReplyHiding.getHiddenPosts()
+ if isHiding
+ unless thread = hiddenPosts.threads[post.thread]
+ thread = hiddenPosts.threads[post.thread] = {}
+ thread[post] =
+ thisPost: thisPost isnt false # undefined -> true
+ makeStub: makeStub
+ hideRecursively: hideRecursively
+ else
+ thread = hiddenPosts.threads[post.thread]
+ delete thread[post]
+ unless Object.keys(thread).length
+ delete hiddenPosts.threads[post.thread]
+ $.set "hiddenPosts.#{g.BOARD}", hiddenPosts
+
+ toggle: (post) ->
if post.isHidden
ReplyHiding.show post
- thread = hiddenPosts.threads[post.thread]
- if (index = thread.indexOf post.ID) > -1
- # Was manually hidden, not by recursion/filtering.
- if thread.length is 1
- delete hiddenPosts.threads[post.thread]
- else
- thread.splice index, 1
else
ReplyHiding.hide post
- unless thread = hiddenPosts.threads[post.thread]
- thread = hiddenPosts.threads[post.thread] = []
- thread.push post.ID
- $.set "hiddenPosts.#{g.BOARD}", hiddenPosts
+ ReplyHiding.saveHiddenState post, post.isHidden
hide: (post, makeStub=Conf['Stubs'], hideRecursively=Conf['Recursive Hiding']) ->
return if post.isHidden
@@ -239,7 +287,10 @@ ReplyHiding =
for quotelink in Get.allQuotelinksLinkingTo post
$.addClass quotelink, 'filtered'
- return unless makeStub
+ unless makeStub
+ post.nodes.root.hidden = true
+ return
+
a = ReplyHiding.makeButton post, 'show'
postInfo =
if Conf['Anonymize']
@@ -258,6 +309,8 @@ ReplyHiding =
if post.nodes.stub
$.rm post.nodes.stub
delete post.nodes.stub
+ else
+ post.nodes.root.hidden = false
post.isHidden = false
for quotelink in Get.allQuotelinksLinkingTo post
$.rmClass quotelink, 'filtered'
@@ -288,7 +341,7 @@ Recursive =
{fullID} = post
Recursive.toHide.push fullID
for ID, post of g.posts
- continue if !post.isReply or post.isHidden
+ continue if !post.isReply
for quote in post.quotes
if quote is fullID
ReplyHiding.hide post, makeStub, true
diff --git a/src/main.coffee b/src/main.coffee
index 85a7fd72e..aaffecf9e 100644
--- a/src/main.coffee
+++ b/src/main.coffee
@@ -364,6 +364,13 @@ Main =
# 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()