Google Groups spam filter

V

VK

Jorge said:
Edit the regExp:
javascript:(function(s,i,e){i=(e=document.querySelectorAll
('.maincontoutboxatt')[0].firstElementChild.tBodies
[0].rows).length;while(i--){s.test(e.textContent)&&(e
.style.opacity='0.2');}})(/leather|wholesale|whoelsale|fjrjtrade|
peng Selina|dotradenow.com|toptradea.com/i);


Asen said:
I use similar approach, but instead querySelectorAll i use XPATH and
document.evaluate:

var dictionary = /leather|wholesale|whoelsale|fjrjtrade|peng Selina|
dotradenow.com|toptradea.com/i,
    xpath_rows = document.evaluate(
        '//div[@class="maincontoutboxatt"][1]//tr',
                document,
        null,
        XPathResult.ORDERED_NODE_SNAPSHOT_TYPE,
        null
    ),
    curr_tr;
    for (var i = 2, j = 0; curr_tr = xpath_rows.snapshotItem(i++);)
    {
            if (dictionary.test(curr_tr.textContent))
        {
                curr_tr.parentNode.removeChild(curr_tr);
        }
        else {
                    curr_tr.bgColor = j++ % 2 == 0 ? '#f7f7f7' : '#ffffff';
        }
    }

Great compacting work! But what about the Summary view? ;)

OK, I got my "IE's janitor" guy for an hour, so the next release works
for IE too. Honestly I didn't follow the IE's applied "logic"
throughout, I just said to him that this script has to do exactly the
same things as on other platforms and for the price of one Mac lunch
at Monday it does it. :)


ggNoSpam 0.6
Tested to work on: IE8, Firefox 3.5.3, Safari 4.0.3, Google Chrome
3.0.195.27, Opera 10.0
A note for purists: it doesn't mean that it doesn't work
on any other platform, it means what it means: that it was
physically seen working on the spelled platforms.

Greasemonkey script for Firefox, Safari, Google Chrome, Opera:
http://userscripts.org/scripts/show/59377

Greasemonkey add-on for Firefox:
https://addons.mozilla.org/en-US/firefox/addon/748

Greasemonkey add-on for Safari (Mac OS only):
http://8-p.info/greasekit/

Google Chrome used to have built-in support
over extra argument -enable-greasemonkey but
it seems to be blocked in the latest release.

Opera has built-in Greasemonkey support, see
http://groups.google.com/group/comp.lang.javascript/msg/65ba1be889c16a13
for details.


Greasemonkey script for IE:
http://www.iescripts.org/view-scripts-676p1.htm

Greasemonkey add-on for IE:
http://www.ie7pro.com

As usual any constructive comments and corrections are most welcome.
 
A

Asen Bozhilov

Great compacting work! But what about the Summary view? ;)

I don't like that summary view. I prefer first list of normal topic,
and after that list of spam topic. Try my implementation of that:

<code>
var DICTIONARY = /leather|wholesale|whoelsale|fjrjtrade|peng Selina|
dotradenow.com|toptradea.com/i,
SPAM_TOPICS = 'Spam Topic',
SHOW_SPAM = 'Show spam',
HIDE_SPAM = 'Hide spam';

var xpath_rows = document.evaluate(
'//div[@class="maincontoutboxatt"][1]//tr', document, null,
XPathResult.ORDERED_NODE_SNAPSHOT_TYPE,
null
),
spam_rows = [],
curr_tr;

for (var i = 2, j = 2, k = 0; curr_tr = xpath_rows.snapshotItem(i++);)
{
if (DICTIONARY.test(curr_tr.textContent))
{
curr_tr.parentNode.appendChild(curr_tr);
setEvenOddColor(curr_tr, k++ % 2);
spam_rows.push(curr_tr);
}
else {
setEvenOddColor(curr_tr, j++ % 2);
}
}

if (k)
{
var spam_butt = document.createElement('input'),
topic_tbl = xpath_rows.snapshotItem(0).parentNode.parentNode,
title_row = topic_tbl.insertRow(j),
title_cell = title_row.insertCell(0);

spam_rows.push(title_row);

title_cell.colSpan = 6;
title_cell.innerHTML = ' said:

spam_butt.type = 'button';
spam_butt.addEventListener('click', showHideSpam, false);
insertSpamButton();

showHideSpam();
}

function setEvenOddColor(html_el, even_odd)
{
html_el.style.backgroundColor = even_odd ? '#FFFFFF' : '#F7F7F7';
}

function showHideSpam()
{
var dspl = title_row.style.display == '' ? 'none' : '';
for (var i = 0, len = spam_rows.length; i < len; i++)
{
spam_rows.style.display = dspl;
}
spam_butt.value = (dspl ? SHOW_SPAM : HIDE_SPAM) + ' (' + k + ')';
}

function insertSpamButton()
{
var form = document.evaluate('//div[@class="maincontbox"]//form',
document, null,
XPathResult.ORDERED_NODE_SNAPSHOT_TYPE,
null
).snapshotItem(0);
form.insertBefore(spam_butt, form.firstChild);
}
As usual any constructive comments and corrections are most welcome.

Bg locale of ggNoSpam:

bg: { // Bulgarian
spam: '\u0441\u043F\u0430\u043C',
good: '\u043D\u0435 \u0435 \u0441\u043F\u0430\u043C',
rtl: false,
italic: true
}
 
V

VK

I don't like that summary view. I prefer first list of normal topic,
and after that list of spam topic. Try my implementation of that:

I definitely will. Is this an implicit permission to use any part of
your code in ggNoSpam under GPLv3? If yes and used can I add you to
the contributirs list?

As of Summary view: I don't like it neither so in the first release I
even forgot about it as I never used it myself. Yet for a public
software - not a personal script - all legitimate usage modes have to
be accounted and the Summary view is one of them.
<code>
var DICTIONARY = /leather|wholesale|whoelsale|fjrjtrade|peng Selina|
dotradenow.com|toptradea.com/i,
    SPAM_TOPICS = 'Spam Topic',
    SHOW_SPAM = 'Show spam',
    HIDE_SPAM = 'Hide spam';

var xpath_rows = document.evaluate(
        '//div[@class="maincontoutboxatt"][1]//tr', document, null,
        XPathResult.ORDERED_NODE_SNAPSHOT_TYPE,
        null
    ),
    spam_rows = [],
    curr_tr;

for (var i = 2, j = 2, k = 0; curr_tr = xpath_rows.snapshotItem(i++);)
{
    if (DICTIONARY.test(curr_tr.textContent))
    {
        curr_tr.parentNode.appendChild(curr_tr);
        setEvenOddColor(curr_tr, k++ % 2);
        spam_rows.push(curr_tr);
    }
    else {
        setEvenOddColor(curr_tr, j++ % 2);
    }

}

if (k)
{
    var spam_butt = document.createElement('input'),
        topic_tbl = xpath_rows.snapshotItem(0).parentNode.parentNode,
        title_row = topic_tbl.insertRow(j),
        title_cell = title_row.insertCell(0);

    spam_rows.push(title_row);

    title_cell.colSpan = 6;
    title_cell.innerHTML = ' said:

    spam_butt.type = 'button';
    spam_butt.addEventListener('click', showHideSpam, false);
    insertSpamButton();

    showHideSpam();

}

function setEvenOddColor(html_el, even_odd)
{
    html_el.style.backgroundColor = even_odd ? '#FFFFFF' : '#F7F7F7';

}

function showHideSpam()
{
    var dspl = title_row.style.display == '' ? 'none' : '';
    for (var i = 0, len = spam_rows.length; i < len; i++)
    {
        spam_rows.style.display = dspl;
    }
    spam_butt.value = (dspl ? SHOW_SPAM : HIDE_SPAM) + ' (' + k + ')';

}

function insertSpamButton()
{
    var form = document.evaluate('//div[@class="maincontbox"]//form',
document, null,
        XPathResult.ORDERED_NODE_SNAPSHOT_TYPE,
        null
    ).snapshotItem(0);
    form.insertBefore(spam_butt, form.firstChild);}

</code>
As usual any constructive comments and corrections are most welcome.

Bg locale of ggNoSpam:

 bg: { // Bulgarian
  spam:   '\u0441\u043F\u0430\u043C',
  good:   '\u043D\u0435 \u0435 \u0441\u043F\u0430\u043C',
  rtl:    false,
  italic: true
 }


Thank you!
 
J

Jorge

Jorge said:
javascript:(function(s,i,e){i=(e=document.querySelectorAll
('.maincontoutboxatt')[0].firstElementChild.tBodies
[0].rows).length;while(i--){s.test(e.textContent)&&(e
.style.opacity='0.2');}})(/leather|wholesale|whoelsale|fjrjtrade|
peng Selina|dotradenow.com|toptradea.com/i);


Great compacting work! But what about the Summary view? ;)


Works for both:

javascript:(function(s,i,e){i=(e=document.querySelectorAll
('.maincontoutboxatt')[0].getElementsByTagName('tr')).length;
while(i--){s.test(e.textContent)&&(e.style.opacity='0.2');}})(
/leather|wholesale|whoelsale|fjrjtrade|peng Selina|dotradenow.com|
toptradea.com/i);

(Safari, Chrome & FiereFox)
 
A

Asen Bozhilov

I definitely will. Is this an implicit permission to use any part of
your code in ggNoSpam under GPLv3? If yes and used can I add you to
the contributirs list?

Ofcourse.
 
V

VK

Works for both:

javascript:(function(s,i,e){i=(e=document.querySelectorAll
('.maincontoutboxatt')[0].getElementsByTagName('tr')).length;
while(i--){s.test(e.textContent)&&(e.style.opacity='0.2');}})(
/leather|wholesale|whoelsale|fjrjtrade|peng Selina|dotradenow.com|
toptradea.com/i);

(Safari, Chrome & FiereFox)


Wow! :)
A side note: for bookmarklets (aka favelets) it is suggested to wrap
the anonymous function expression into void():
javascript:void(function(){/*your code here*/})())
This way you are solving two problems:

1) preventing occasional return value from your function in case of a
premature termination, say
if (something_is_wrong) {
return; // ore return null;
}

2) informing the engine in advance that there will be no JavaScript-
generated content from this link so there will be no navigation - that
prevents "waiting mode" state for long-running scripts.
 
J

Jorge

A side note: for bookmarklets (aka favelets) it is suggested to wrap
the anonymous function expression into void():

The way you write it it looks like if void were a function... :)

void f();
 javascript:void(function(){/*your code here*/})())
This way you are solving two problems:

1) preventing occasional return value from your function in case of a
premature termination, say
 if (something_is_wrong) {
  return; // ore return null;
 }

In the (not many) browsers that I've tested it in, unless something !
== undefined is returned, the page won't be navigated away.

My function returns undefined (because there's not an explicit return-
anything).

So, ISTM, whether void is needed or not depends upon what would get
returned -if anything- in the event of a parse or a runtime error ?
2) informing the engine in advance that there will be no JavaScript-
generated content from this link so there will be no navigation - that
prevents "waiting mode" state for long-running scripts.

I don't know, what's 'waiting mode' ?
Why does the engine need to be informed "in advance" ?

Thanks,
 
V

VK

Jorge said:
The way you write it it looks like if void were a function... :)

void f();

:) Allowed by specs in either way. Either way SHOULD !== MUST ;) Or to
take it even more easy :) : it is an operator followed by a function
expression in parentheses:
void (function(){}())
with space after operator omitted for compactness which is allowed if
the next token is a parenthesis. I assume no one has an objection to
that?
In the (not many) browsers that I've tested it in, unless something !
== undefined is returned, the page won't be navigated away.

The problem I experienced was with good programmers used to make
premature terminations or failure exits with
return null;
rather than with just
return;
Rather than fight with every single one it was easier to add one more
wrapper.
 
J

Jorge

Jorge said:
javascript:(function(s,i,e){i=(e=document.querySelectorAll
('.maincontoutboxatt')[0].getElementsByTagName('tr')).length;

Why call `querySelectorAll` if you only need first element?

Just use `document.querySelector` ;)

You learn something new (almost) every day...

Thanks !
 
J

Jorge

Jorge wrote:
javascript:(function(s,i,e){i=(e=document.querySelectorAll
('.maincontoutboxatt')[0].getElementsByTagName('tr')).length;

Why call `querySelectorAll` if you only need first element?
Just use `document.querySelector` ;)

You learn something new (almost) every day...

What's wrong with it in Opera 10 ?

javascript:(function(s,i,e){i=(e=document.querySelector
('.maincontoutboxatt').getElementsByTagName('tr')).length;while(i--)
{s.test(e.textContent)&&(e.style.opacity='0.2')&&alert(e
.textContent+"\r\nopacity:"+e.style.opacity);}})(/leather|
wholesale|whoelsale|fjrjtrade|peng Selina|dotradenow.com|toptradea.com|
price|products/i);

Any ideas ?
 
V

VK

Jorge wrote:
javascript:(function(s,i,e){i=(e=document.querySelectorAll
('.maincontoutboxatt')[0].getElementsByTagName('tr')).length;
Why call `querySelectorAll` if you only need first element?
Just use `document.querySelector` ;)
You learn something new (almost) every day...

What's wrong with it in Opera 10 ?

javascript:(function(s,i,e){i=(e=document.querySelector
('.maincontoutboxatt').getElementsByTagName('tr')).length;while(i--)
{s.test(e.textContent)&&(e.style.opacity='0.2')&&alert(e
.textContent+"\r\nopacity:"+e.style.opacity);}})(/leather|
wholesale|whoelsale|fjrjtrade|peng Selina|dotradenow.com|toptradea.com|
price|products/i);

Any ideas ?


Quotes. ... +"\r\nopacity:" ...
Replace to ... +'\r\nopacity:' ... to make it work

The rule of thumb of an error protective typing:

1) In HTML/XHTML there are not single quotes as a reality entity, so
you are forced to use only double quotes for attribute values.
2) In JavaScript there are not double quotes as a reality entity, so
you are forced to use only single quotes for string values.

Of course it can be vice versa and overall just a game with yourself
but in my strong opinion it helps hugely a lot.
 
J

Jorge

Quotes. ... +"\r\nopacity:" ...
Replace to ... +'\r\nopacity:' ... to make it work

The rule of thumb of an error protective typing:

1) In HTML/XHTML there are not single quotes as a reality entity, so
you are forced to use only double quotes for attribute values.
2) In JavaScript there are not double quotes as a reality entity, so
you are forced to use only single quotes for string values.

Of course it can be vice versa and overall just a game with yourself
but in my strong opinion it helps hugely a lot.

Hmm, what ?
 
V

VK

Hmm, what ?

Using only single quotes for JavaScript strings and only double quotes
for HTML attributes. It can be vice versa of course (only double
quotes for JavaScript strings and only single quotes for HTML
attributes) or even no quotes whatsoever for HTML attributes and any
quotes for JavaScript strings. But by taking into account the common
usage pattern with HTML attributes placed into double quotes, for the
scripts made for the distribution on uncontrollable environments it is
better to stick to the very first option. By my 12 years experience it
eliminates a huge amount of sometimes very spurious errors. Just a
suggestion, any way.
 
J

Jorge

Using only single quotes for JavaScript strings and only double quotes
for HTML attributes. It can be vice versa of course (only double
quotes for JavaScript strings and only single quotes for HTML
attributes) or even no quotes whatsoever for HTML attributes and any
quotes for JavaScript strings. But by taking into account the common
usage pattern with HTML attributes placed into double quotes, for the
scripts made for the distribution on uncontrollable environments it is
better to stick to the very first option. By my 12 years experience it
eliminates a huge amount of sometimes very spurious errors. Just a
suggestion, any way.

Neither
e.style.opacity='0.2'
nor
e.style.opacity="0.2"
nor
e.style.opacity= 0.2

work in Opera 10 ("not work" === the change in opacity is not visible
on-screen), although the element's .style.opacity gets properly set in
both cases (to check that is what the alert(e.style.opacity) is
there for)... but why ?
 
V

VK

Using only single quotes for JavaScript strings and only double quotes
for HTML attributes. It can be vice versa of course (only double
quotes for JavaScript strings and only single quotes for HTML
attributes) or even no quotes whatsoever for HTML attributes and any
quotes for JavaScript strings. But by taking into account the common
usage pattern with HTML attributes placed into double quotes, for the
scripts made for the distribution on uncontrollable environments it is
better to stick to the very first option. By my 12 years experience it
eliminates a huge amount of sometimes very spurious errors. Just a
suggestion, any way.

Neither
e.style.opacity='0.2'
nor
e.style.opacity="0.2"
nor
e.style.opacity= 0.2

work in Opera 10 ("not work" === the change in opacity is not visible
on-screen), although the element's .style.opacity gets properly set in
both cases (to check that is what the alert(e.style.opacity) is
there for)... but why ?


Oh, sorry. In your first post there was a quote mishmash in alert
block so it would fail to be inserted into HTML page for bookmarking,
this is what I was referring to. After the quote correction it started
to show the alert and I didn't follow the reason itself of this alert
display, sorry again, I was distracted this morning.

Currently Opera doesn't support opacity for table elements (tbody,
rows), only for the entire table. The relevant style interfaces are
provided for all elements but below TABLE these are just loopholes to
prevent possible environment detection - a stinky "programming
approach" Opera is famous for from the very beginning.

This is a part of the reasons I didn't go for opacity manipulations in
ggNoSpam - it is still too buggy if taken across all prominent
browsers.
 
V

VK

VK said:
This is a part of the reasons I didn't go for opacity manipulations in
ggNoSpam - it is still too buggy if taken across all prominent
browsers.

Not saying that table manipulations are so much better on the same
wide scale :)
 
V

VK

VK said:
Not saying that table manipulations are so much better on the same
wide scale :)

Just in case I'd like to note that I didn't watch other project
participants going opacity way until they hit the Opera's quirk. As
Opera doesn't have a commercial importance for the projects in my area
I do support checks on it only occasionally and upon my time
availability: so I simply forgot about this silly bug.
 
J

Jorge

Jorge said:
Jorge wrote:
javascript:(function(s,i,e){i=(e=document.querySelectorAll
('.maincontoutboxatt')[0].getElementsByTagName('tr')).length;
Why call `querySelectorAll` if you only need first element?
Just use `document.querySelector` ;)
You learn something new (almost) every day...
What's wrong with it in Opera 10 ?

Looks like Opera doesn't respect opacity on THEAD, TBODY and TR. TABLE,
TH and TD seem to work fine.

IIRC, Opera 10 supports RGBA format, so you can try simulating opacity
with that:

<tr style="color: rgba(0,0,0,0.2)" ...>...</tr>

No, some elements won't inherit because they've got their own colors.
Why not just — `document.querySelectorAll('.maincontoutboxatt tr')` ?

Yes, but with <td>s:

javascript:(function(s,i,e){i=(e=document.querySelectorAll
('.maincontoutboxatt td')).length;while(i--){s.test(e.textContent)&&
(e.style.opacity='0.2');}})(/leather|wholesale|whoelsale|fjrjtrade|
peng Selina|dotradenow.com|toptradea.com|price|products/i);

(Safari >= 3, Chrome, FiereFox >= 3.5, Opera >= 10, IE >= 27)

Thanks... again.
 
J

Jorge

(...)
"hover to check" means content revealing on mouse pointer hovering
(placed over) the suspected spam.
(...)

....and the respective "hover-to-check" bookmarklet version :

javascript:(function(o,s,e,t,i){i=e.length;while(i--){t.test(e
.textContent)&&(e[o]="0.3",e.onmouseover=e
.onmouseout=function(){this[o]=this[o]?"":"0.3";});}})
("opacity","style",document.querySelectorAll('.maincontoutboxatt td'),/
leather|wholesale|whoelsale|fjrjtrade|peng%20Selina|dotradenow.com|
toptradea.com|price|products|pharmacy|t-shirt|gucci/i);
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
474,085
Messages
2,570,597
Members
47,218
Latest member
GracieDebo

Latest Threads

Top