User tests: Successful: Unsuccessful:
http://joomlacode.org/gf/project/joomla/tracker/?action=TrackerItemEdit&tracker_item_id=31791
This PR introduces a completely new approach to the email cloaking plugin.
The current core email cloaking plugin is pretty bad and has been for years.
One issue is that it uses document.write to place a javascript encoded email address. The document.write causes issues with other scripts (like inline modal scripts).
Another issue is that it also converts email addresses inside inline scripts, causing these to completely be messed up (scripts inside scripts).
These are both fixed with this new Email Cloaking plugin.
This plugin doesn't output a javascript to generate the html, but outputs a link with a series of span elements. The email address id distributed in parts over data-content attributes in these spans.
Then by using some short css and javascript the email address is displayed correctly and the mailto is added to the link.
The result is a readable email address in the browser, but a bunch of spans with unrecognisable attributes in the html.
You can test (and compare to old functionality) if the email addresses are being output correctly (together with the correct mailto link). For instance, use this as example:
<p>Email in text: my@email.com</p>
<p>Email with mailto link: <a href="mailto:my@email.com">my@email.com</a></p>
<p>Email with mailto link with an id: <a href="mailto:my@email.com" id="myid">my@email.com</a></p>
<p>Email with mailto link to other email address than text: <a href="mailto:my@email.com">someoneelse@email.com</a></p>
<p>Email with mailto link and custom text <a href="mailto:my@email.com">My Email</a></p>
Also good to test what happens when there is an email address inside a javascript block. It should be left alone.
So you can try placing this code inside an article (make sure your editor allows placing scripts):
<script language="javascript" type="text/javascript">
myemail = 'my@email.com';
document.write('<p>Email address in script: ' + myemail + '</p>');
</script>
HTML output of this PR with this input:Email in text: my@email.com
will look something like:
<p>
Email in text:
<!--- This email address is being protected from spambots. You need JavaScript enabled to view it. --->
<span class="email_address">
<span data-content-post="om" data-content-pre="my">
<span data-content-post=".c" data-content-pre="@e">
<span data-content-post="il" data-content-pre="ma"></span>
</span>
</span>
</span>
</p>
So is this PR ok? What's the status?
I like this new approach a lot.
document.write means a re-rendering for browsers, means flickering and slower (not snappy) rendering.
document.write is real aweful javascript and a shame for Joomla!
So +1 for this from me.
I liked idea about change the old email cloaking plugin.
but whether realy need such difficult front end part, with relation from jQuery?
can just:
<span id="random-id-3123123" data-pref="my-email" data-suff="example.com">
This email address is being protected from spambots. You need JavaScript enabled to view it.
</span>
<script type="text/javascript">
(function (d){
var el = d.getElementById('random-id-3123123'),
em = el.getAttribute('data-pref') + '@' + el.getAttribute('data-suff');
el.innerHTML = '<a href="mailto:' + em + '">' + em + '</a>';
})(document);
</script>
no? :)
Because that is very easy for spambots to decode. Joomla is used by millions of websites. So as soon as that is used, spambots will adapt.
The 'difficult' part is what the plugin is for: cloaking.
It makes it a lot more difficult for spambots.
In your example a simple regular expression can grab the email:data-pref="([^"]*)" data-suff="([^"]*)"
Email = $1@$2;
yes right :)
in same way spambot can parse all data-content-post
and data-content-pre
of course
but, you right, your solution more difficult for the spamboots
what about make this without jQuery and addittional css files?
<span id="random-id-3123123">
This email address is being protected from spambots. You need JavaScript enabled to view it.
<span data-content-post="om" data-content-pre="my">
<span data-content-post=".c" data-content-pre="@e">
<span data-content-post="il" data-content-pre="ma"></span>
</span>
</span>
</span>
<script type="text/javascript">
(function (d){
var el = d.getElementById('random-id-3123123'),
sp = el.getElementsByTagName('span'), p = '', s = '';
for (var i = 0, l = sp.length; i < l; i++) {
p += sp[i].getAttribute('data-content-pre');
s = sp[i].getAttribute('data-content-post') + s;
}
el.innerHTML = '<a href="mailto:' + p + s + '">' + p + s + '</a>';
})(document);
</script>
p.s. I see diference betwen media/system/js/emailcloak.js
and media/system/js/emailcloak-uncompressed.js
, looks like mistake or ?
The idea behind this is to keep the code that decodes the cloaked email outside the html output.
Also, if you have 24 email addresses on a page, you don't want 24 javascript blocks in your html output. Inline javacript sucks.
There are ways to make it even harder, but changing it later will be even better, as it will force spambots to adapt.
The important thing is that it's not document.write anymore.
Indeed, jquery is not required this, but as it's joomla standard, i see no issues in using it.
I will test it and comment on tracker as soon as i have fulfilled my other 3.2-commitments.
Also, if you have 24 email addresses on a page
right, but if I have only 1-2 emails (that in most cases) I still should do 3 additional request (jQuery,emailcloak.js, emailcloak.css) that to big price in this case
when select between 3 additional request and "Inline javacript" I would select last.
it just IMHO ;)
I can rewrite the js to not be jQuery dependant.
@nonumber for me it would be great ;)
small question between, maybe for future, what your think about random attributes?
<span id="random-id-3123123" data-randome-text-for-pref="my-email" data-randome-text-for-suff="example.com">
This email address is being protected from spambots. You need JavaScript enabled to view it.
</span>
<script type="text/javascript">
(function (d){
var el = d.getElementById('random-id-3123123'),
em = el.getAttribute('data-randome-text-for-pref') + '@' + el.getAttribute('data-randome-text-for-suff');
el.innerHTML = '<a href="mailto:' + em + '">' + em + '</a>';
})(document);
</script>
also can put the javascript in to the header (for avoid inline), something like:
// generated on first JHtml::_('email.cloak') call
var randomVariableName = {};
(function (d, $){
$(d).ready(function(){
for(var p in randomVariableName){
var el = d.getElementById(p),
em = el.getAttribute('data-' + randomVariableName[p][0]) + '@' + el.getAttribute('data-' + randomVariableName[p][1]);
el.innerHTML = '<a href="mailto:' + em + '">' + em + '</a>';
}
});
})(document, jQuery);
randomVariableName["random-element-id"] = ["randome-text-for-pref", 'randome-text-for-suff'];
//after each new call, for other emails
randomVariableName["other-random-element-id2"] = ["other-randome-text-for-pref2", 'other-randome-text-for-suff3'];
randomVariableName["other-random-element-id3"] = ["other-randome-text-for-pref2", 'other-randome-text-for-suff2'];
jQuery here just because I not know how to simple catch "domready"
just interesting your thoughts
"jQuery here just because I not know how to simple catch "domready"
That's why I wanted to use jQuery to begin with.
I am reqriting it to be plain js. Problem with the way Joomla adds scripts to the header is that it will add the script (and css if using same method) multiple times.
Looking into how to solve this...
ok, i understand :)
for check whether added, can try use a static variable in cloak function, or where you want add it :
static $script_added;
if(!$script_added)
{
// code for script
$script_added = true;
}
Yeah, I know that. But it just is a shame the same piece of code gets added multiple times.
Will either have to use external js that hold function, or use inline script without function.
Ok, rewrote the whole thing. Please check it out...
for me works good
FR has 2 successful tests and PR is in sync with master.
So good to go....
I'm done waiting, discussing and wasting my time on this. This has been lying around for 4 months now.
Even if it did get merged, it would still be an issue on Joomla 2.5. And I don't see this getting in there, let alone Joomla 3.
So I have retracted the code and will just release it as a NoNumber extension. Much more rewarding than trying to 'give back to Joomla'.
Hi there,
I've refactored the JHtml email too: JHtmlEmail Gist
It stills produces inline javascript, but XHTML mode doesn't use document.write.
When using inline code, there's no need for jQuery
The output still looks pretty nasty though :)
XHTML output
HTML output