How to create a clickable, visible but obfuscated mailto:// link - css

I know there's already a lot about email obfuscation on this site. But recently I found this neat little CSS-trick that I hadn't encountered before.
It SHOWS the email address (here: user#domain.com), but sadly it doesn't produce a clickable mailto:// link. If one entered it as a href, of course the address would again be ready for bots to be picked up.
So I added a litte javascript routine, that adds an event listener to all .e-mail elements:
// Email de-obfuscation, start mail client, copy email to clipboard:
document.querySelectorAll('.e-mail').forEach(e => {
// get the encoded email address from ::after and decode:
function getDecodeEmail(event) {
z=event.currentTarget;
y=getComputedStyle(z,'::after');
x=y.getPropertyValue('content');
// reverse string rtl
v=x.split("").reverse().join("");
// remove all "
return v.replace(/['"]+/g, '');
};
// onClick start mail client with decoded email address:
e.addEventListener("click", event => {
// prevent href=#
event.preventDefault();
// get the (reversed) email address of the calling anchor
v=getDecodeEmail(event);
//window.location.href="mailto:"+v;
// former statement doesn't fire in SE code snippets,
// but you can try here: https://jsfiddle.net/jamacoe/Lp4bvn13/75/
// for now, let's just display the link:
alert("mailto:"+v);
});
// right mouse click copies email to clipboard:
e.addEventListener("contextmenu", event => {
// prevent href=#
event.preventDefault();
// get the (reversed) email address of the calling anchor
v=getDecodeEmail(event);
// copy v to clipboard
navigator.clipboard.writeText(v);
// just to check:
navigator.clipboard.readText().then( clipText => alert(clipText) );
// former statements don't work in SE code snippets,
// but you can try here: https://jsfiddle.net/jamacoe/Lp4bvn13/75/
});
});
.e-mail::after {
content: attr(data-mailSvr) "\0040" attr(data-mailUsr);
unicode-bidi: bidi-override;
direction: rtl;
}
<a class=e-mail data-mailUsr=resu data-mailSvr=moc.niamod href=""></a>
On the one hand side I'm very content with this solution. But on the other hand, I think my javascript spoils the elegance and simplicity of the HTML/CSS. Does anybody have an idea how to complement this approach of email obfuscation, only using pure CSS + HTML, resulting in a clickable and visable link that meets all common requirements (i.e. screen reader compatible, sufficiently obfuscated, correctly formatted, right clickable for copying)?

I have done something similar in the past. I needed a way to display my email address on one of my websites, but not get horribly spammed in the process. I implemented this 2 years ago, and I haven't received any spam. I didn't do this with CSS though... this is pure JS.
If you hover over the result, you'll see that it creates a clickable email address.
Hope this helps.
let fname = "first";
let lname = "last";
let domain = "gmail.com";
email.innerHTML = `${fname}.${lname}#${domain}`;
<span id="email"></span>

Related

Server Side Rendering HTML text (write with HTML tags in DB) as effectively html in an email

On one hand
I've a field will in a collection, where user can save html text (through a WYSIWYG editor): it works fine and users can write/save some strings like this it's<strong>bold</strong> and sometimes <i>italic</i>. Nothing crazy..
On a second hand
When a user send this field will by email (as part of emailData), rendered with meteorhacks:ssr in an html template, the field show up as it's<strong>bold</strong> and sometimes <i>italic</i>. with HTML tags as normal text.
So, anyone know the trick to render in the html email's body: 'it's bold and sometimes italic.'? Thanks.
My code is very complicated, lot of const and succession of functions, but except of html rendering, it works fine and is finally structured like this:
SSR.compileTemplate('htmlEmail', Assets.getText('replycontact.html'));
var emailData = {
message: `${message}`,
will: `${will}`,
origincontactdate: `${origincontactdate}`,
contactname: `${contactname}`,
};
//send the mail
Email.send({
to: to,
from: from,
subject: subject,
html: SSR.render('htmlEmail', emailData),
});
The problem was that Meteor was escaping the HTML string.
Therefore, the solution is to use 3 brackets {{{ }}} instead of 2 - here for the emailData in the html template : instead of {{will}}, use {{{will}}}.
The code above in the question remain as it.
source: https://stackoverflow.com/a/16565529/7281870
Your data is most likely being saved as HTML encoded in the database, eg
<b>
is saved as
<b>
If so, you simply need to unencode it using the Javascript decodeURI() function, which you can read more about here:
http://www.w3schools.com/jsref/jsref_decodeuri.asp
So your code will look like this:
var emailData = {
message: `${message}`,
will: decodeURI(${will}),
origincontactdate: `${origincontactdate}`,
contactname: `${contactname}`,
};
//send the mail
Email.send({
to: to,
from: from,
subject: subject,
html: SSR.render('htmlEmail', emailData),
});

Make a button of any language which has your user and pass embedded to make easy log in for particular website

I have 'several accounts' in a website which I always log in everyday. Now, I want it to be easy by just clicking buttons in order to log in a particular account. Is it possible? How can I do that?
If you have any experience using jQuery for DOM manipulation, it's fairly easy to do what you're asking using tampermonkey / greasemonkey
Basically you'd add a script that would trigger only on a particular domain. That script would import jQuery (just for ease of use) and append N buttons to the DOM. Using jQuery again, those buttons would have a given behavior that, in your case, fill the login and password input fields and submit the info.
// ==UserScript==
// #name Multilogin
// #version 0.1
// #match http://website.com/*
// #require http://ajax.googleapis.com/ajax/libs/jquery/2.0.3/jquery.min.js
// #run-at document-start
// ==/UserScript==
jQuery(document).ready(function() {
jQuery('body').prepend('<button id="my1stID" data-login="brian1" data-password="asdfg" value="my1stID"/>');
jQuery('body').prepend('<button id="mi2ndID" data-login="brian2" data-password="asdfg2" value="my2ndID"/>');
jQuery('body').prepen('<button id="mi3rdID"...');
jQuery(document).on('click','my1stID',function() {
var login=jQuery(this).data('login');
var password=jQuery(this).data('password');
jQuery('#login_input').val(login);
jQuery('#password_input').val(password);
jQuery('#submit').click();
});
jQuery(document).on('click','mi2ndID',function() {
....
});
jQuery(document).on('click','mi3rdID',function() {
....
});
});
Take into consideration that storing your passwords in a script is very insecure and with my answer I'm giving you enough rope to hang yourself.

Using Accounts.emailTemplates.resetPassword.html correctly in Meteor

I have no problems using Accounts.emailTemplates.resetPassword.text but if I also use Accounts.emailTemplates.resetPassword.html I don't get an HTML email.
Are there any example of how to use Accounts.emailTemplates.resetPassword.html correctly?
It is very simple to use - just like you would use text. See the example below, it will send the return value as the e-mail body. Works for all three: resetPassword, verifyEmail, and enrollAccount.
Accounts.emailTemplates.verifyEmail.html = function (user, url) {
return "<h1>Thanks for signing up!</h1>"
+ " To <strong>activate</strong> your account, click the link below:\n\n"
+ url;
};
Still, both variants are sent as e-mail: text and html. If your e-mail client defaults to display emails as text, then you will not see the HTML flavor of the message, so make sure both text and html contain the same information.

Best way to retrieve image from server using ajax [duplicate]

Is it possible to reload an image with an identical file name from a server using jQuery?
For example, I have an image on a page, however, the physical image can change based on user actions. Note, this does not mean the file name changes, but the actual file itself.
ie:
User views image on default page
User uploads new image
Default image on page does not change(I assume this is due to the file name being identical, the browser uses the cached version)
Regardless of how often the code below is called, the same issue persists.
$("#myimg").attr("src", "/myimg.jpg");
In the jQuery documentation, the "load" function would be perfect if it had a default method of firing the event as opposed to binding a callback function to a successful/complete load of an element.
Any assistance is greatly appreciated.
It sounds like it's your browser caching the image (which I now notice you wrote in your question). You can force the browser to reload the image by passing an extra variable like so:
d = new Date();
$("#myimg").attr("src", "/myimg.jpg?"+d.getTime());
It's probably not the best way, but I've solved this problem in the past by simply appending a timestamp to the image URL using JavaScript:
$("#myimg").attr("src", "/myimg.jpg?timestamp=" + new Date().getTime());
Next time it loads, the timestamp is set to the current time and the URL is different, so the browser does a GET for the image instead of using the cached version.
This could be one of the two problems you mention yourself.
The server is caching the image
The jQuery does not fire or at least doesn't update the attribute
To be honest, I think it's number two. Would be a lot easier if we could see some more jQuery. But for a start, try remove the attribute first, and then set it again. Just to see if that helps:
$("#myimg").removeAttr("src").attr("src", "/myimg.jpg");
Even if this works, post some code since this is not optimal, imo :-)
with one line with no worries about hardcoding the image src into the javascript (thanks to jeerose for the ideas:
$("#myimg").attr("src", $("#myimg").attr("src")+"?timestamp=" + new Date().getTime());
To bypass caching and avoid adding infinite timestamps to the image url, strip the previous timestamp before adding a new one, this is how I've done it.
//refresh the image every 60seconds
var xyro_refresh_timer = setInterval(xyro_refresh_function, 60000);
function xyro_refresh_function(){
//refreshes an image with a .xyro_refresh class regardless of caching
//get the src attribute
source = jQuery(".xyro_refresh").attr("src");
//remove previously added timestamps
source = source.split("?", 1);//turns "image.jpg?timestamp=1234" into "image.jpg" avoiding infinitely adding new timestamps
//prep new src attribute by adding a timestamp
new_source = source + "?timestamp=" + new Date().getTime();
//alert(new_source); //you may want to alert that during developement to see if you're getting what you wanted
//set the new src attribute
jQuery(".xyro_refresh").attr("src", new_source);
}
This works great! however if you reload the src multiple times, the timestamp gets concatenated to the url too. I've modified the accepted answer to deal with that.
$('#image_reload_button').on('click', function () {
var img = $('#your_image_selector');
var src = img.attr('src');
var i = src.indexOf('?dummy=');
src = i != -1 ? src.substring(0, i) : src;
var d = new Date();
img.attr('src', src + '?dummy=' + d.getTime());
});
Have you tried resetting the image containers html. Of course if it's the browser that is caching then this wouldn't help.
function imageUploadComplete () {
$("#image_container").html("<img src='" + newImageUrl + "'>");
}
Some times actually solution like -
$("#Image").attr("src", $('#srcVal').val()+"&"+Math.floor(Math.random()*1000));
also not refresh src properly, try out this, it worked for me ->
$("#Image").attr("src", "dummy.jpg");
$("#Image").attr("src", $('#srcVal').val()+"&"+Math.floor(Math.random()*1000));
Using "#" as a delimiter might be useful
My images are kept in a "hidden" folder above "www" so that only logged users are allowed access to them. For this reason I cannot use the ordinary <img src=/somefolder/1023.jpg> but I send requests to the server like <img src=?1023> and it responds by sending back the image kept under name '1023'.
The application is used for image cropping, so after an ajax request to crop the image, it is changed as content on the server but keeps its original name. In order to see the result of the cropping, after the ajax request has been completed, the first image is removed from the DOM and a new image is inserted with the same name <img src=?1023>.
To avoid cashing I add to the request the "time" tag prepended with "#" so it becomes like <img src=?1023#1467294764124>. The server automatically filters out the hash part of the request and responds correctly by sending back my image kept as '1023'. Thus I always get the last version of the image without much server-side decoding.
Based on #kasper Taeymans' answer.
If u simply need reload image (not replace it's src with smth new), try:
$(function() {
var img = $('#img');
var refreshImg = function(img) {
// the core of answer is 2 lines below
var dummy = '?dummy=';
img.attr('src', img.attr('src').split(dummy)[0] + dummy + (new Date()).getTime());
// remove call on production
updateImgVisualizer();
};
// for display current img url in input
// for sandbox only!
var updateImgVisualizer = function() {
$('#img-url').val(img.attr('src'));
};
// bind img reload on btn click
$('.img-reloader').click(function() {
refreshImg(img);
});
// remove call on production
updateImgVisualizer();
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<img id="img" src="http://dummyimage.com/628x150/">
<p>
<label>
Current url of img:
<input id="img-url" type="text" readonly style="width:500px">
</label>
</p>
<p>
<button class="img-reloader">Refresh</button>
</p>
I may have to reload the image source several times. I found a solution with Lodash that works well for me:
$("#myimg").attr('src', _.split($("#myimg").attr('src'), '?', 1)[0] + '?t=' + _.now());
An existing timestamp will be truncated and replaced with a new one.
If you need a refresh of the exact URL and your browser has the image cached, you can use AJAX and a request header to force your browser to download a new copy (even if it isn't stale yet). Here's how you'd do that:
var img = $("#myimg");
var url = img.attr("src");
$.ajax({
url: url,
headers: { "Cache-Control": "no-cache" }
}).done(function(){
// Refresh is complete, assign the image again
img.attr("src", url);
});
Nothing else worked for me because while appending a token to the query string would download the new image, it didn't invalidate the image in the cache at the old URL so future requests would continue to show the old image. The old URL is the only one sent to the browser, and the server was directing the client to cache the image for longer than it should.
If this still doesn't refresh the image for you, see if this answer helps. For more information, here is documentation on the Cache-Control request header.
In the html:
foreach (var item in images) {
<Img src="#Url.Content(item.ImageUrl+"?"+DateTime.Now)" >
}
I simply do this in html:
<script>
$(document).load(function () {
d = new Date();
$('#<%= imgpreview.ClientID %>').attr('src','');
});
</script>
And reload the image in code behind like this:
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
image.Src = "/image.jpg"; //url caming from database
}
}

Volume muting when player is hidden / shown with jQuery

I've coded a script for this web page.
That allows me to use the thumbnails on the right hand side in order to switch the 'main video'.
All appears to work fine, however if you play one video and then switch to another, and then switch BACK to the video that was originally playing, then the volume is muted when you continue watching it.
I have noticed that you can get around it by clicking the volume tool inside the player, but the average user most likely won't figure this out.
I've tried using the setVolume() method on something like:
$('#media video')
But FF tells me that the method doesn't exist. Could this be because I'm just trying it from within one of my other js files whereas the media player script itself is setup with Wordpress? I'm using the WP plugin you see.
Has anyone else had this issue?
Here is my .js that switches the videos if that helps:
$(document).ready(function() {
// swap media
$('#media-feed .thumb a').click(function() {
var mediaId = $(this).prev('input').val();
$('#media .content').each(function() {
if($(this).css('display') == 'block') {
$(this).fadeOut(350);
}
});
$('#media-' + mediaId).delay(500).fadeIn(350);
return false;
});
// swap sidebar detail
$('#media-feed .thumb a').mouseenter(function() {
var mediaId = $(this).prev('input').val();
$('#media-feed .detail').each(function() {
if($(this).css('display') == 'block') {
$(this).slideUp(125, function() {
var currentDetail = $('#media-detail-' + mediaId);
currentDetail.slideDown(125, function() {
currentDetail.css('display', 'block');
});
});
}
});
return false;
});
});
Also another problem I'm having is in Internet Explorer (all versions). See above, where I said about switching from one video to another, in other browsers the videos automatically pause when you click on another thumbnail. However in IE the videos continue to play. So basically, you'd have to pause the video and THEN change main video by clicking one of the thumbnails. Again, not very user friendly.
Does anyone know of a way I can get it to function like in other browsers? I can see that even IE doesn't have this problem on this page where the Fancybox plugin is used.
So that makes me think there must be a way to solve it in IE on the home page.
If anyone has any advice on this too that would be great!
Thanks.

Resources