Add per filter stub setting.

Change succesful filter return type to an object instead of an array.
Probably fix some filtering issues.

Close #339.
This commit is contained in:
Nicolas Stepien 2012-05-29 13:48:23 +02:00
parent 45edc5c4bf
commit 295764beb6
3 changed files with 111 additions and 93 deletions

View File

@ -511,7 +511,7 @@
Filter = { Filter = {
filters: {}, filters: {},
init: function() { 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) { for (key in Config.filter) {
this.filters[key] = []; this.filters[key] = [];
_ref = Conf[key].split('\n'); _ref = Conf[key].split('\n');
@ -538,13 +538,15 @@
alert(e.message); alert(e.message);
continue; 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)) { if (hl = /highlight/.test(filter)) {
hl = ((_ref3 = filter.match(/highlight:(\w+)/)) != null ? _ref3[1].toLowerCase() : void 0) || 'filter_highlight'; hl = ((_ref4 = filter.match(/highlight:(\w+)/)) != null ? _ref4[1] : void 0) || 'filter_highlight';
top = ((_ref4 = filter.match(/top:(yes|no)/)) != null ? _ref4[1].toLowerCase() : void 0) || 'yes'; top = ((_ref5 = filter.match(/top:(yes|no)/)) != null ? _ref5[1] : void 0) || 'yes';
top = top === '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) { if (!this.filters[key].length) {
delete this.filters[key]; delete this.filters[key];
@ -554,13 +556,19 @@
return Main.callbacks.push(this.node); return Main.callbacks.push(this.node);
} }
}, },
createFilter: function(regexp, op, hl, top) { createFilter: function(regexp, op, stub, hl, top) {
var test; var settings, test;
test = typeof regexp === 'string' ? function(value) { test = typeof regexp === 'string' ? function(value) {
return regexp === value; return regexp === value;
} : function(value) { } : function(value) {
return regexp.test(value); return regexp.test(value);
}; };
settings = {
hide: !hl,
stub: stub,
"class": hl,
top: top
};
return function(value, isOP) { return function(value, isOP) {
if (isOP && op === 'no' || !isOP && op === 'only') { if (isOP && op === 'no' || !isOP && op === 'only') {
return false; return false;
@ -568,10 +576,7 @@
if (!test(value)) { if (!test(value)) {
return false; return false;
} }
if (hl) { return settings;
return [hl, top];
}
return true;
}; };
}, },
node: function(post) { node: function(post) {
@ -592,20 +597,20 @@
if (!(result = filter(value, isOP))) { if (!(result = filter(value, isOP))) {
continue; continue;
} }
if (result === true) { if (result.hide) {
if (isOP) { if (isOP) {
if (!g.REPLY) { if (!g.REPLY) {
ThreadHiding.hide(root.parentNode); ThreadHiding.hide(root.parentNode, result.stub);
} else { } else {
continue; continue;
} }
} else { } else {
ReplyHiding.hide(root); ReplyHiding.hide(root, result.stub);
} }
return; return;
} }
$.addClass(root, result[0]); $.addClass(root, result["class"]);
if (isOP && result[1] && !g.REPLY) { if (isOP && result.top && !g.REPLY) {
thisThread = root.parentNode; thisThread = root.parentNode;
if (firstThread = $('div[class="postContainer opContainer"]').parentNode) { if (firstThread = $('div[class="postContainer opContainer"]').parentNode) {
$.before(firstThread, [thisThread, thisThread.nextElementSibling]); $.before(firstThread, [thisThread, thisThread.nextElementSibling]);
@ -920,14 +925,14 @@
} }
return $.set("hiddenThreads/" + g.BOARD + "/", hiddenThreads); return $.set("hiddenThreads/" + g.BOARD + "/", hiddenThreads);
}, },
hide: function(thread) { hide: function(thread, invert_stub_conf) {
var a, num, opInfo, span, text; var a, num, opInfo, span, text;
if (!Conf['Show Stubs']) { if (Conf['Show Stubs'] === invert_stub_conf) {
thread.hidden = true; thread.hidden = true;
thread.nextElementSibling.hidden = true; thread.nextElementSibling.hidden = true;
return; return;
} }
if (thread.firstChild.className === 'hide_thread_button hidden_thread') { if (/\bhidden_thread\b/.test(thread.firstChild.className)) {
return; return;
} }
num = 0; num = 0;
@ -937,16 +942,20 @@
num += $$('.opContainer ~ .replyContainer', thread).length; num += $$('.opContainer ~ .replyContainer', thread).length;
text = num === 1 ? '1 reply' : "" + num + " replies"; text = num === 1 ? '1 reply' : "" + num + " replies";
opInfo = $('.op > .postInfo > .nameBlock', thread).textContent; opInfo = $('.op > .postInfo > .nameBlock', thread).textContent;
a = $('.hide_thread_button', thread); a = $.el('a', {
$.addClass(a, 'hidden_thread'); className: 'hide_thread_button hidden_thread',
a.firstChild.textContent = '[ + ]'; innerHTML: '<span>[ + ]</span>',
return $.add(a, $.tn(" " + opInfo + " (" + text + ")")); href: 'javascript:;'
});
$.add(a, $.tn(" " + opInfo + " (" + text + ")"));
$.on(a, 'click', ThreadHiding.cb);
return $.prepend(thread, a);
}, },
show: function(thread) { show: function(thread) {
var a; var a;
a = $('.hide_thread_button', thread); if (a = $('.hidden_thread', thread)) {
$.removeClass(a, 'hidden_thread'); $.rm(a);
a.innerHTML = '<span>[ - ]</span>'; }
thread.hidden = false; thread.hidden = false;
return thread.nextElementSibling.hidden = false; return thread.nextElementSibling.hidden = false;
} }
@ -957,14 +966,14 @@
return Main.callbacks.push(this.node); return Main.callbacks.push(this.node);
}, },
node: function(post) { node: function(post) {
var button; var side;
if (post.isInlined || /\bop\b/.test(post["class"])) { if (post.isInlined || /\bop\b/.test(post["class"])) {
return; return;
} }
button = post.root.firstElementChild; side = $('.sideArrows', post.root);
$.addClass(button, 'hide_reply_button'); $.addClass(side, 'hide_reply_button');
button.innerHTML = '<a href="javascript:;"><span>[ - ]</span></a>'; side.innerHTML = '<a href="javascript:;"><span>[ - ]</span></a>';
$.on(button.firstChild, 'click', ReplyHiding.toggle); $.on(side.firstChild, 'click', ReplyHiding.toggle);
if (post.id in g.hiddenReplies) { if (post.id in g.hiddenReplies) {
return ReplyHiding.hide(post.root); return ReplyHiding.hide(post.root);
} }
@ -992,36 +1001,34 @@
} }
return $.set("hiddenReplies/" + g.BOARD + "/", g.hiddenReplies); return $.set("hiddenReplies/" + g.BOARD + "/", g.hiddenReplies);
}, },
hide: function(root) { hide: function(root, invert_stub_conf) {
var button, el, stub; var a, el, side, stub;
button = root.firstElementChild; side = $('.sideArrows', root);
if (button.hidden) { if (side.hidden) {
return; return;
} }
button.hidden = true; side.hidden = true;
el = root.lastElementChild; el = side.nextElementSibling;
el.hidden = true; el.hidden = true;
if (!Conf['Show Stubs']) { if (Conf['Show Stubs'] === invert_stub_conf) {
return; return;
} }
stub = $.el('div', { stub = $.el('div', {
className: 'hide_reply_button stub', className: 'hide_reply_button stub',
innerHTML: '<a href="javascript:;"><span>[ + ]</span> </a>' innerHTML: '<a href="javascript:;"><span>[ + ]</span> </a>'
}); });
$.add(stub.firstChild, $.tn($('.nameBlock', el).textContent)); a = stub.firstChild;
$.on(stub.firstChild, 'click', ReplyHiding.toggle); $.add(a, $.tn($('.nameBlock', el).textContent));
return $.after(button, stub); $.on(a, 'click', ReplyHiding.toggle);
return $.prepend(root, stub);
}, },
show: function(root) { show: function(root) {
var button, el; var stub;
el = root.lastElementChild; if (stub = $('.stub', root)) {
button = root.firstElementChild; $.rm(stub);
el.hidden = false;
button.hidden = false;
if (!Conf['Show Stubs']) {
return;
} }
return $.rm(button.nextElementSibling); $('.sideArrows', root).hidden = false;
return $('.post', root).hidden = false;
} }
}; };
@ -2205,6 +2212,7 @@
<ul>You can use these settings with each regular expression, separate them with semicolons:\ <ul>You can use these settings with each regular expression, separate them with semicolons:\
<li>Per boards, separate them with commas. It is global if not specified.<br>For example: <code>boards:a,jp;</code>.</li>\ <li>Per boards, separate them with commas. It is global if not specified.<br>For example: <code>boards:a,jp;</code>.</li>\
<li>Filter OPs only along with their threads (`only`), replies only (`no`, this is default), or both (`yes`).<br>For example: <code>op:only;</code>, <code>op:no;</code> or <code>op:yes;</code>.</li>\ <li>Filter OPs only along with their threads (`only`), replies only (`no`, this is default), or both (`yes`).<br>For example: <code>op:only;</code>, <code>op:no;</code> or <code>op:yes;</code>.</li>\
<li>Overrule the `Show Stubs` setting if specified: create a stub (`yes`) or not (`no`).<br>For example: <code>stub:yes;</code> or <code>stub:no;</code></li>\
<li>Highlight instead of hiding. You can specify a class name to use with a userstyle.<br>For example: <code>highlight;</code> or <code>highlight:wallpaper;</code>.</li>\ <li>Highlight instead of hiding. You can specify a class name to use with a userstyle.<br>For example: <code>highlight;</code> or <code>highlight:wallpaper;</code>.</li>\
<li>Highlighted OPs will have their threads put on top of board pages by default.<br>For example: <code>top:yes</code> or <code>top:no</code>.</li>\ <li>Highlighted OPs will have their threads put on top of board pages by default.<br>For example: <code>top:yes</code> or <code>top:no</code>.</li>\
</ul>\ </ul>\

View File

@ -1,4 +1,6 @@
master master
- Mayhem
Add a per filter stub setting.
2.30.8 2.30.8
- Mayhem - Mayhem

View File

@ -419,19 +419,24 @@ Filter =
# Filter OPs along with their threads, replies only, or both. # Filter OPs along with their threads, replies only, or both.
# Defaults to replies only. # 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. # Highlight the post, or hide it.
# If not specified, the highlight class will be filter_highlight. # If not specified, the highlight class will be filter_highlight.
# Defaults to post hiding. # Defaults to post hiding.
if hl = /highlight/.test filter 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. # Put highlighted OP's thread on top of the board page or not.
# Defaults to on top. # 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 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. # Only execute filter types that contain valid filters.
unless @filters[key].length unless @filters[key].length
@ -440,21 +445,24 @@ Filter =
if Object.keys(@filters).length if Object.keys(@filters).length
Main.callbacks.push @node Main.callbacks.push @node
createFilter: (regexp, op, hl, top) -> createFilter: (regexp, op, stub, hl, top) ->
test = test =
if typeof regexp is 'string' if typeof regexp is 'string'
# MD5 checking # MD5 checking
(value) -> regexp is value (value) -> regexp is value
else else
(value) -> regexp.test value (value) -> regexp.test value
settings =
hide: !hl
stub: stub
class: hl
top: top
(value, isOP) -> (value, isOP) ->
if isOP and op is 'no' or !isOP and op is 'only' if isOP and op is 'no' or !isOP and op is 'only'
return false return false
unless test value unless test value
return false return false
if hl settings
return [hl, top]
true
node: (post) -> node: (post) ->
return if post.isInlined return if post.isInlined
@ -470,19 +478,19 @@ Filter =
continue continue
# Hide # Hide
if result is true if result.hide
if isOP if isOP
unless g.REPLY unless g.REPLY
ThreadHiding.hide root.parentNode ThreadHiding.hide root.parentNode, result.stub
else else
continue continue
else else
ReplyHiding.hide root ReplyHiding.hide root, result.stub
return return
# Highlight # Highlight
$.addClass root, result[0] $.addClass root, result.class
if isOP and result[1] and not g.REPLY if isOP and result.top and not g.REPLY
# Put the highlighted OPs' thread on top of the board page... # Put the highlighted OPs' thread on top of the board page...
thisThread = root.parentNode thisThread = root.parentNode
# ...before the first non highlighted thread. # ...before the first non highlighted thread.
@ -670,7 +678,7 @@ ThreadHiding =
init: -> init: ->
hiddenThreads = $.get "hiddenThreads/#{g.BOARD}/", {} hiddenThreads = $.get "hiddenThreads/#{g.BOARD}/", {}
for thread in $$ '.thread' for thread in $$ '.thread'
a = $.el 'a', a = $.el 'a',
className: 'hide_thread_button' className: 'hide_thread_button'
innerHTML: '<span>[ - ]</span>' innerHTML: '<span>[ - ]</span>'
href: 'javascript:;' href: 'javascript:;'
@ -695,13 +703,13 @@ ThreadHiding =
hiddenThreads[id] = Date.now() hiddenThreads[id] = Date.now()
$.set "hiddenThreads/#{g.BOARD}/", hiddenThreads $.set "hiddenThreads/#{g.BOARD}/", hiddenThreads
hide: (thread) -> hide: (thread, invert_stub_conf) ->
unless Conf['Show Stubs'] unless Conf['Show Stubs'] isnt invert_stub_conf
thread.hidden = true thread.hidden = true
thread.nextElementSibling.hidden = true thread.nextElementSibling.hidden = true
return 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 num = 0
if span = $ '.summary', thread if span = $ '.summary', thread
@ -710,15 +718,17 @@ ThreadHiding =
text = if num is 1 then '1 reply' else "#{num} replies" text = if num is 1 then '1 reply' else "#{num} replies"
opInfo = $('.op > .postInfo > .nameBlock', thread).textContent opInfo = $('.op > .postInfo > .nameBlock', thread).textContent
a = $ '.hide_thread_button', thread a = $.el 'a',
$.addClass a, 'hidden_thread' className: 'hide_thread_button hidden_thread'
a.firstChild.textContent = '[ + ]' innerHTML: '<span>[ + ]</span>'
href: 'javascript:;'
$.add a, $.tn " #{opInfo} (#{text})" $.add a, $.tn " #{opInfo} (#{text})"
$.on a, 'click', ThreadHiding.cb
$.prepend thread, a
show: (thread) -> show: (thread) ->
a = $ '.hide_thread_button', thread if a = $ '.hidden_thread', thread
$.removeClass a, 'hidden_thread' $.rm a
a.innerHTML = '<span>[ - ]</span>'
thread.hidden = false thread.hidden = false
thread.nextElementSibling.hidden = false thread.nextElementSibling.hidden = false
@ -728,10 +738,10 @@ ReplyHiding =
node: (post) -> node: (post) ->
return if post.isInlined or /\bop\b/.test post.class return if post.isInlined or /\bop\b/.test post.class
button = post.root.firstElementChild side = $ '.sideArrows', post.root
$.addClass button, 'hide_reply_button' $.addClass side, 'hide_reply_button'
button.innerHTML = '<a href="javascript:;"><span>[ - ]</span></a>' side.innerHTML = '<a href="javascript:;"><span>[ - ]</span></a>'
$.on button.firstChild, 'click', ReplyHiding.toggle $.on side.firstChild, 'click', ReplyHiding.toggle
if post.id of g.hiddenReplies if post.id of g.hiddenReplies
ReplyHiding.hide post.root ReplyHiding.hide post.root
@ -753,31 +763,28 @@ ReplyHiding =
g.hiddenReplies[id] = Date.now() g.hiddenReplies[id] = Date.now()
$.set "hiddenReplies/#{g.BOARD}/", g.hiddenReplies $.set "hiddenReplies/#{g.BOARD}/", g.hiddenReplies
hide: (root) -> hide: (root, invert_stub_conf) ->
button = root.firstElementChild side = $ '.sideArrows', root
return if button.hidden # already hidden once by filter return if side.hidden # already hidden once by the filter
button.hidden = true side.hidden = true
el = root.lastElementChild el = side.nextElementSibling
el.hidden = true el.hidden = true
return unless Conf['Show Stubs'] return unless Conf['Show Stubs'] isnt invert_stub_conf
stub = $.el 'div', stub = $.el 'div',
className: 'hide_reply_button stub' className: 'hide_reply_button stub'
innerHTML: '<a href="javascript:;"><span>[ + ]</span> </a>' innerHTML: '<a href="javascript:;"><span>[ + ]</span> </a>'
$.add stub.firstChild, $.tn $('.nameBlock', el).textContent a = stub.firstChild
$.on stub.firstChild, 'click', ReplyHiding.toggle $.add a, $.tn $('.nameBlock', el).textContent
$.after button, stub $.on a, 'click', ReplyHiding.toggle
$.prepend root, stub
show: (root) -> show: (root) ->
el = root.lastElementChild if stub = $ '.stub', root
button = root.firstElementChild $.rm stub
el.hidden = false $('.sideArrows', root).hidden = false
button.hidden = false $('.post', root).hidden = false
return unless Conf['Show Stubs']
$.rm button.nextElementSibling
Keybinds = Keybinds =
init: -> init: ->
@ -1692,6 +1699,7 @@ Options =
<ul>You can use these settings with each regular expression, separate them with semicolons: <ul>You can use these settings with each regular expression, separate them with semicolons:
<li>Per boards, separate them with commas. It is global if not specified.<br>For example: <code>boards:a,jp;</code>.</li> <li>Per boards, separate them with commas. It is global if not specified.<br>For example: <code>boards:a,jp;</code>.</li>
<li>Filter OPs only along with their threads (`only`), replies only (`no`, this is default), or both (`yes`).<br>For example: <code>op:only;</code>, <code>op:no;</code> or <code>op:yes;</code>.</li> <li>Filter OPs only along with their threads (`only`), replies only (`no`, this is default), or both (`yes`).<br>For example: <code>op:only;</code>, <code>op:no;</code> or <code>op:yes;</code>.</li>
<li>Overrule the `Show Stubs` setting if specified: create a stub (`yes`) or not (`no`).<br>For example: <code>stub:yes;</code> or <code>stub:no;</code></li>
<li>Highlight instead of hiding. You can specify a class name to use with a userstyle.<br>For example: <code>highlight;</code> or <code>highlight:wallpaper;</code>.</li> <li>Highlight instead of hiding. You can specify a class name to use with a userstyle.<br>For example: <code>highlight;</code> or <code>highlight:wallpaper;</code>.</li>
<li>Highlighted OPs will have their threads put on top of board pages by default.<br>For example: <code>top:yes</code> or <code>top:no</code>.</li> <li>Highlighted OPs will have their threads put on top of board pages by default.<br>For example: <code>top:yes</code> or <code>top:no</code>.</li>
</ul> </ul>