diff --git a/4chan_x.user.js b/4chan_x.user.js
index 2eb1d304f..fb4ffa8b1 100644
--- a/4chan_x.user.js
+++ b/4chan_x.user.js
@@ -511,7 +511,7 @@
Filter = {
filters: {},
init: function() {
- var boards, filter, hl, key, op, regexp, top, _i, _len, _ref, _ref1, _ref2, _ref3, _ref4;
+ var boards, filter, hl, key, op, regexp, stub, top, _i, _len, _ref, _ref1, _ref2, _ref3, _ref4, _ref5;
for (key in Config.filter) {
this.filters[key] = [];
_ref = Conf[key].split('\n');
@@ -538,13 +538,15 @@
alert(e.message);
continue;
}
- op = ((_ref2 = filter.match(/[^t]op:(yes|no|only)/)) != null ? _ref2[1].toLowerCase() : void 0) || 'no';
+ op = ((_ref2 = filter.match(/[^t]op:(yes|no|only)/)) != null ? _ref2[1] : void 0) || 'no';
+ stub = (_ref3 = filter.match(/stub:(yes|no)/)) != null ? _ref3[1] : void 0;
+ stub = stub === 'yes' && !Conf['Show Stubs'] || stub === 'no' && Conf['Show Stubs'];
if (hl = /highlight/.test(filter)) {
- hl = ((_ref3 = filter.match(/highlight:(\w+)/)) != null ? _ref3[1].toLowerCase() : void 0) || 'filter_highlight';
- top = ((_ref4 = filter.match(/top:(yes|no)/)) != null ? _ref4[1].toLowerCase() : void 0) || 'yes';
+ hl = ((_ref4 = filter.match(/highlight:(\w+)/)) != null ? _ref4[1] : void 0) || 'filter_highlight';
+ top = ((_ref5 = filter.match(/top:(yes|no)/)) != null ? _ref5[1] : void 0) || 'yes';
top = top === 'yes';
}
- this.filters[key].push(this.createFilter(regexp, op, hl, top));
+ this.filters[key].push(this.createFilter(regexp, op, stub, hl, top));
}
if (!this.filters[key].length) {
delete this.filters[key];
@@ -554,13 +556,19 @@
return Main.callbacks.push(this.node);
}
},
- createFilter: function(regexp, op, hl, top) {
- var test;
+ createFilter: function(regexp, op, stub, hl, top) {
+ var settings, test;
test = typeof regexp === 'string' ? function(value) {
return regexp === value;
} : function(value) {
return regexp.test(value);
};
+ settings = {
+ hide: !hl,
+ stub: stub,
+ "class": hl,
+ top: top
+ };
return function(value, isOP) {
if (isOP && op === 'no' || !isOP && op === 'only') {
return false;
@@ -568,10 +576,7 @@
if (!test(value)) {
return false;
}
- if (hl) {
- return [hl, top];
- }
- return true;
+ return settings;
};
},
node: function(post) {
@@ -592,20 +597,20 @@
if (!(result = filter(value, isOP))) {
continue;
}
- if (result === true) {
+ if (result.hide) {
if (isOP) {
if (!g.REPLY) {
- ThreadHiding.hide(root.parentNode);
+ ThreadHiding.hide(root.parentNode, result.stub);
} else {
continue;
}
} else {
- ReplyHiding.hide(root);
+ ReplyHiding.hide(root, result.stub);
}
return;
}
- $.addClass(root, result[0]);
- if (isOP && result[1] && !g.REPLY) {
+ $.addClass(root, result["class"]);
+ if (isOP && result.top && !g.REPLY) {
thisThread = root.parentNode;
if (firstThread = $('div[class="postContainer opContainer"]').parentNode) {
$.before(firstThread, [thisThread, thisThread.nextElementSibling]);
@@ -920,14 +925,14 @@
}
return $.set("hiddenThreads/" + g.BOARD + "/", hiddenThreads);
},
- hide: function(thread) {
+ hide: function(thread, invert_stub_conf) {
var a, num, opInfo, span, text;
- if (!Conf['Show Stubs']) {
+ if (Conf['Show Stubs'] === invert_stub_conf) {
thread.hidden = true;
thread.nextElementSibling.hidden = true;
return;
}
- if (thread.firstChild.className === 'hide_thread_button hidden_thread') {
+ if (/\bhidden_thread\b/.test(thread.firstChild.className)) {
return;
}
num = 0;
@@ -937,16 +942,20 @@
num += $$('.opContainer ~ .replyContainer', thread).length;
text = num === 1 ? '1 reply' : "" + num + " replies";
opInfo = $('.op > .postInfo > .nameBlock', thread).textContent;
- a = $('.hide_thread_button', thread);
- $.addClass(a, 'hidden_thread');
- a.firstChild.textContent = '[ + ]';
- return $.add(a, $.tn(" " + opInfo + " (" + text + ")"));
+ a = $.el('a', {
+ className: 'hide_thread_button hidden_thread',
+ innerHTML: '[ + ]',
+ href: 'javascript:;'
+ });
+ $.add(a, $.tn(" " + opInfo + " (" + text + ")"));
+ $.on(a, 'click', ThreadHiding.cb);
+ return $.prepend(thread, a);
},
show: function(thread) {
var a;
- a = $('.hide_thread_button', thread);
- $.removeClass(a, 'hidden_thread');
- a.innerHTML = '[ - ]';
+ if (a = $('.hidden_thread', thread)) {
+ $.rm(a);
+ }
thread.hidden = false;
return thread.nextElementSibling.hidden = false;
}
@@ -957,14 +966,14 @@
return Main.callbacks.push(this.node);
},
node: function(post) {
- var button;
+ var side;
if (post.isInlined || /\bop\b/.test(post["class"])) {
return;
}
- button = post.root.firstElementChild;
- $.addClass(button, 'hide_reply_button');
- button.innerHTML = '[ - ]';
- $.on(button.firstChild, 'click', ReplyHiding.toggle);
+ side = $('.sideArrows', post.root);
+ $.addClass(side, 'hide_reply_button');
+ side.innerHTML = '[ - ]';
+ $.on(side.firstChild, 'click', ReplyHiding.toggle);
if (post.id in g.hiddenReplies) {
return ReplyHiding.hide(post.root);
}
@@ -992,36 +1001,34 @@
}
return $.set("hiddenReplies/" + g.BOARD + "/", g.hiddenReplies);
},
- hide: function(root) {
- var button, el, stub;
- button = root.firstElementChild;
- if (button.hidden) {
+ hide: function(root, invert_stub_conf) {
+ var a, el, side, stub;
+ side = $('.sideArrows', root);
+ if (side.hidden) {
return;
}
- button.hidden = true;
- el = root.lastElementChild;
+ side.hidden = true;
+ el = side.nextElementSibling;
el.hidden = true;
- if (!Conf['Show Stubs']) {
+ if (Conf['Show Stubs'] === invert_stub_conf) {
return;
}
stub = $.el('div', {
className: 'hide_reply_button stub',
innerHTML: '[ + ] '
});
- $.add(stub.firstChild, $.tn($('.nameBlock', el).textContent));
- $.on(stub.firstChild, 'click', ReplyHiding.toggle);
- return $.after(button, stub);
+ a = stub.firstChild;
+ $.add(a, $.tn($('.nameBlock', el).textContent));
+ $.on(a, 'click', ReplyHiding.toggle);
+ return $.prepend(root, stub);
},
show: function(root) {
- var button, el;
- el = root.lastElementChild;
- button = root.firstElementChild;
- el.hidden = false;
- button.hidden = false;
- if (!Conf['Show Stubs']) {
- return;
+ var stub;
+ if (stub = $('.stub', root)) {
+ $.rm(stub);
}
- return $.rm(button.nextElementSibling);
+ $('.sideArrows', root).hidden = false;
+ return $('.post', root).hidden = false;
}
};
@@ -2205,6 +2212,7 @@
You can use these settings with each regular expression, separate them with semicolons:\
- Per boards, separate them with commas. It is global if not specified.
For example: boards:a,jp;. \
- Filter OPs only along with their threads (`only`), replies only (`no`, this is default), or both (`yes`).
For example: op:only;, op:no; or op:yes;. \
+ - Overrule the `Show Stubs` setting if specified: create a stub (`yes`) or not (`no`).
For example: stub:yes; or stub:no; \
- Highlight instead of hiding. You can specify a class name to use with a userstyle.
For example: highlight; or highlight:wallpaper;. \
- Highlighted OPs will have their threads put on top of board pages by default.
For example: top:yes or top:no. \
\
diff --git a/changelog b/changelog
index 53ba3939d..6fb00dd04 100644
--- a/changelog
+++ b/changelog
@@ -1,4 +1,6 @@
master
+- Mayhem
+ Add a per filter stub setting.
2.30.8
- Mayhem
diff --git a/script.coffee b/script.coffee
index 6de792096..9bee54a20 100644
--- a/script.coffee
+++ b/script.coffee
@@ -419,19 +419,24 @@ Filter =
# Filter OPs along with their threads, replies only, or both.
# Defaults to replies only.
- op = filter.match(/[^t]op:(yes|no|only)/)?[1].toLowerCase() or 'no'
+ op = filter.match(/[^t]op:(yes|no|only)/)?[1] or 'no'
+
+ # Overrule the `Show Stubs` setting.
+ # Defaults to stub showing.
+ stub = filter.match(/stub:(yes|no)/)?[1]
+ stub = stub is 'yes' and !Conf['Show Stubs'] or stub is 'no' and Conf['Show Stubs']
# Highlight the post, or hide it.
# If not specified, the highlight class will be filter_highlight.
# Defaults to post hiding.
if hl = /highlight/.test filter
- hl = filter.match(/highlight:(\w+)/)?[1].toLowerCase() or 'filter_highlight'
+ hl = filter.match(/highlight:(\w+)/)?[1] or 'filter_highlight'
# Put highlighted OP's thread on top of the board page or not.
# Defaults to on top.
- top = filter.match(/top:(yes|no)/)?[1].toLowerCase() or 'yes'
+ top = filter.match(/top:(yes|no)/)?[1] or 'yes'
top = top is 'yes' # Turn it into a boolean
- @filters[key].push @createFilter regexp, op, hl, top
+ @filters[key].push @createFilter regexp, op, stub, hl, top
# Only execute filter types that contain valid filters.
unless @filters[key].length
@@ -440,21 +445,24 @@ Filter =
if Object.keys(@filters).length
Main.callbacks.push @node
- createFilter: (regexp, op, hl, top) ->
+ 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, isOP) ->
if isOP and op is 'no' or !isOP and op is 'only'
return false
unless test value
return false
- if hl
- return [hl, top]
- true
+ settings
node: (post) ->
return if post.isInlined
@@ -470,19 +478,19 @@ Filter =
continue
# Hide
- if result is true
+ if result.hide
if isOP
unless g.REPLY
- ThreadHiding.hide root.parentNode
+ ThreadHiding.hide root.parentNode, result.stub
else
continue
else
- ReplyHiding.hide root
+ ReplyHiding.hide root, result.stub
return
# Highlight
- $.addClass root, result[0]
- if isOP and result[1] and not g.REPLY
+ $.addClass root, result.class
+ if isOP and result.top and not g.REPLY
# Put the highlighted OPs' thread on top of the board page...
thisThread = root.parentNode
# ...before the first non highlighted thread.
@@ -670,7 +678,7 @@ ThreadHiding =
init: ->
hiddenThreads = $.get "hiddenThreads/#{g.BOARD}/", {}
for thread in $$ '.thread'
- a = $.el 'a',
+ a = $.el 'a',
className: 'hide_thread_button'
innerHTML: '[ - ]'
href: 'javascript:;'
@@ -695,13 +703,13 @@ ThreadHiding =
hiddenThreads[id] = Date.now()
$.set "hiddenThreads/#{g.BOARD}/", hiddenThreads
- hide: (thread) ->
- unless Conf['Show Stubs']
+ hide: (thread, invert_stub_conf) ->
+ unless Conf['Show Stubs'] isnt invert_stub_conf
thread.hidden = true
thread.nextElementSibling.hidden = true
return
- return if thread.firstChild.className is 'hide_thread_button hidden_thread' # already hidden by filter
+ return if /\bhidden_thread\b/.test thread.firstChild.className # already hidden once by the filter
num = 0
if span = $ '.summary', thread
@@ -710,15 +718,17 @@ ThreadHiding =
text = if num is 1 then '1 reply' else "#{num} replies"
opInfo = $('.op > .postInfo > .nameBlock', thread).textContent
- a = $ '.hide_thread_button', thread
- $.addClass a, 'hidden_thread'
- a.firstChild.textContent = '[ + ]'
+ a = $.el 'a',
+ className: 'hide_thread_button hidden_thread'
+ innerHTML: '[ + ]'
+ href: 'javascript:;'
$.add a, $.tn " #{opInfo} (#{text})"
+ $.on a, 'click', ThreadHiding.cb
+ $.prepend thread, a
show: (thread) ->
- a = $ '.hide_thread_button', thread
- $.removeClass a, 'hidden_thread'
- a.innerHTML = '[ - ]'
+ if a = $ '.hidden_thread', thread
+ $.rm a
thread.hidden = false
thread.nextElementSibling.hidden = false
@@ -728,10 +738,10 @@ ReplyHiding =
node: (post) ->
return if post.isInlined or /\bop\b/.test post.class
- button = post.root.firstElementChild
- $.addClass button, 'hide_reply_button'
- button.innerHTML = '[ - ]'
- $.on button.firstChild, 'click', ReplyHiding.toggle
+ side = $ '.sideArrows', post.root
+ $.addClass side, 'hide_reply_button'
+ side.innerHTML = '[ - ]'
+ $.on side.firstChild, 'click', ReplyHiding.toggle
if post.id of g.hiddenReplies
ReplyHiding.hide post.root
@@ -753,31 +763,28 @@ ReplyHiding =
g.hiddenReplies[id] = Date.now()
$.set "hiddenReplies/#{g.BOARD}/", g.hiddenReplies
- hide: (root) ->
- button = root.firstElementChild
- return if button.hidden # already hidden once by filter
- button.hidden = true
- el = root.lastElementChild
+ hide: (root, invert_stub_conf) ->
+ side = $ '.sideArrows', root
+ return if side.hidden # already hidden once by the filter
+ side.hidden = true
+ el = side.nextElementSibling
el.hidden = true
- return unless Conf['Show Stubs']
+ return unless Conf['Show Stubs'] isnt invert_stub_conf
stub = $.el 'div',
className: 'hide_reply_button stub'
innerHTML: '[ + ] '
- $.add stub.firstChild, $.tn $('.nameBlock', el).textContent
- $.on stub.firstChild, 'click', ReplyHiding.toggle
- $.after button, stub
+ a = stub.firstChild
+ $.add a, $.tn $('.nameBlock', el).textContent
+ $.on a, 'click', ReplyHiding.toggle
+ $.prepend root, stub
show: (root) ->
- el = root.lastElementChild
- button = root.firstElementChild
- el.hidden = false
- button.hidden = false
-
- return unless Conf['Show Stubs']
-
- $.rm button.nextElementSibling
+ if stub = $ '.stub', root
+ $.rm stub
+ $('.sideArrows', root).hidden = false
+ $('.post', root).hidden = false
Keybinds =
init: ->
@@ -1692,6 +1699,7 @@ Options =
You can use these settings with each regular expression, separate them with semicolons:
- Per boards, separate them with commas. It is global if not specified.
For example: boards:a,jp;.
- Filter OPs only along with their threads (`only`), replies only (`no`, this is default), or both (`yes`).
For example: op:only;, op:no; or op:yes;.
+ - Overrule the `Show Stubs` setting if specified: create a stub (`yes`) or not (`no`).
For example: stub:yes; or stub:no;
- Highlight instead of hiding. You can specify a class name to use with a userstyle.
For example: highlight; or highlight:wallpaper;.
- Highlighted OPs will have their threads put on top of board pages by default.
For example: top:yes or top:no.