A New Library: NSFW JS — Protect Your Visitors at Work

I wrote a drop-in library in JavaScript that protects your visitors from accidentally viewing material not suitable at work.

It is based on an article about adding a new “NSFW” attribute:

I am now proposing a new attribute:

rel=”nsfw”

NSFW is an abbreviation often used to indicate that content is “not safe for work.”

Check out the demo and source code here. There are tons of examples on the page so I won’t post any sample code here. It could probably be a little more efficient, but I got lazy. But despite my “laziness,” the script does three major things:

  1. All marked <a> tags prompt the visitor
  2. Marked <img> tags are replaced with a placeholder until they are clicked on.
  3. Marked <div> and <p> tags masked so that all the text is the same color as the background until it is clicked on.

I went a step further and made it also check the CSS class name as well as use the text “adult” interchangeably with “nsfw”. Here is an example of #2 (the content is safe for work, despite the warning message):

For those of you still reading, the version I wrote took me longer than I hoped because I had one major goal in mind:

Dropping this script in should not break any site, ever.

Well, that’s difficult given the current state of the Internet: tons of links out there already have “onClick” actions. Any regular drop in script would overwrite those actions! So I had to make sure my version would work even in those situations. So, granted, it probably won’t work exactly as I’m hoping on some small percentage of sites out there (who knows), but for 99.999% of the cases, this should work.

I have appropriately called this script Nsfw JS and released it for free as usual.

Update: I plan on releasing an update to this library soon, so if you plan on adopting this now, make sure to check back later.

Dynamic Constants

Yesterday, I hit a wall in PHP that took a little brain power to solve. I posted the solution on the web for everybody to see. A little back-story:

Constants in PHP (the const keyword) can not have dynamic values. Defines can. In other words, only ONE of the two following lines is valid PHP code:

define(‘THE_CURRENT_TIME’, time()); // OKAY
const THE_CURRENT_TIME = time(); // FAIL

This gets annoying when you are building constants that are pieced together from other constants. Constants are useful because they are, essentially, a way to name two constants the same thing. For example, two classes can both have a constant called NAME, and you don’t have to worry. This is better because separate developers don’t have to know what defines are already being used.

But PHP doesn’t allow constants to have dynamic values. This is annoying. Why not? Probably so that two separate instances of a class don’t have differing values for a given constant (imagine a const with the definition equal to rand()). Sure, it makes sense, but then why aren’t there read-only variables in classes!?

Scraping my post:

In realizing it is impossible to create dynamic constants, I opted for a “read only” constants class.

<?php
abstract class aClassConstant {

    /**
     * Setting is not permitted.
     *
     * @param string constant name
     * @param mixed new value
     * @return void
     * @throws Exception
     */
    final function __set($member, $value) {
        throw new Exception(‘You cannot set a constant.’);
    }

    /**
     * Get the value of the constant
     *
     * @param string constant name
     * @return void
     */
    final function __get($member) {
        return $this->$member;
    }
}
?>

The class would be extended by another class that would compartmentalize the purpose of the constants. Thus, for example, you would extend the class with a DbConstant class for managing database related constants, that might look like this:

<?php
/**
 * Constants that deal only with the database
 */
class DbConstant extends aClassConstant {
   
    protected $host = ‘localhost';
    protected $user = ‘user';
    protected $password = ‘pass';
    protected $database = ‘db';
    protected $time;
   
    /**
     * Constructor. This is so fully dynamic values can be
     * set. This can be skipped and the values can be
     * directly assigned for non dynamic values as shown 
     * above.
     *
     * @return void
     */
    function __construct() {
        $this->time = time() + 1; // dynamic assignment
    }
}
?>

You would use the class like thus:

<?php
$dbConstant = new DbConstant();
echo $dbConstant->host;
?>

The following would cause an exception:

<?php
$dbConstant = new DbConstant();
$dbConstant->host = ‘127.0.0.1’; // EXCEPTION
?>

It’s not pretty, nor ideal, but at least you don’t pollute the global name space with long winded global names and it is relatively elegant.

Variables must be *protected*, not public. Public variables will bypass the __get and __set methods!! This class is, by design, not meant to be extended much further than one level, as it is really meant to only contain constants. By keeping the constant definition class separate from the rest of your classes (if you are calling this from a class), you minimize the possibility of accidental variable assignment.

Managing this instance may be a slight pain that requires either caching a copy of the instance in a class variable, or using the factory pattern. Unfortunately, static methods can’t detect the correct class name when the parent name is used during the call (e.g., DbConstant::instance()). Thus there is no elegant, inheriting solution to that problem. Thus, it is easier to simply manage a single instance that is declared using conventional notation (e.g., new DbConstant…).

 It’s not the best solution I’ve ever came up with, but it’s a hell of a lot better than having giant config files with 50 character long defines in it.

Why an abstract class? Well, the whole point of constants, as I mentioned, is so that you don’t have a big pile of names in one namespace (so you can have two constants called “NAME,” for example). Any benefit of constants would be lost if I made a single unified “constants class.” Thus, I made it abstract. An abstract class can not be used without first being extended. This forces a developer who might use my code to properly separate out the various constants he/she may have into their own class groupings.

Posting Arrays

While hacking away on a problem today at work, I suddenly realized my DbSafe class would trip over itself if someone tried to access a value that was an array since it would try to escape an array value as if it were a string, leaving you with the text “Array”! What should happen is you get back an actual array full of escaped values.

I’m very sorry for this simple oversight. It has now been corrected. You can get the source here. Let me know if anybody finds any other bugs.

A Brand New Way to Hide Your Email Address

If you haven’t already, I suggest you read the last article I wrote about separating your Javascript from your content. It will give you important background information needed to fully understand what I will be covering today.

Today, I’m going to show you how to embed your email address into any page of your site without fear that some bot will come along and steal it. This method is different from other ones because not only is it “backwards compatible” with older techniques, but it degrades gracefully and is straight forward to non-developers. This feature will work with all modern browsers, is human readable (no garbled text mixed in), and works when you click on it. Most importantly, it doesn’t require you to mark up your beautiful HTML.

Background

Some rogue email spammers use “bots” to automatically go through the internet and find email addresses. Once they find one, they add it to their spam list and you’re email becomes their newest indentured servant — forever. At first, people tried to trick the primitive bots by putting in spaces in their email address, such as in the following example:

some @ email . com

But bots learned to look for the @ symbol and then ignore spaces, so this quickly became obsolete.

So while some clever people think they are safe using address that look like:

some [at] email [dot] com

Or

some[nospam]@emailDOTcom

Or

someREMOVEME at email [period] com

The problem is that bots can be trained to look for these text patterns and get around them. After many programmers spent many hours mucking around with ASCII hashes and other futile measures, it became clear what the real problem was:

Bots can see and read anything a human can see and read!

The other problem is that adding in random words, brackets, and other symbols into your email address makes it very hard to read. This is very much unacceptable for people who are trying to run a business and can’t afford to have less savvy people send emails to salesREMOVE@[DONTSPAM]mybusiness.com.

I’m not going to tell you my idea is future proof. However, it’s been possible for many years now and I’ve never seen it. When and if this catches on, spammers may eventually start learning to get around it. But it won’t be easy. That’s because my method can vary wildly between implementations and can be used along side with any or all of the methods I showed above! More importantly, my method relies on the difference between bots and humans:

Humans click on stuff.

New Idea

The first and most important issue is that when a person clicks on your email link, it should let them email you. This is one of those things that has long since been lost as a readily available feature because so many people are afraid of getting spammed. Sure, maybe you can click on an email link, but you end up with something like the example below (click on it)

email me!

I’m sure you find that as annoying as I do. But what if we used Javascript to dynamically change what the href tag did? Well, the thinking-in-the-box idea would be to have this happen on the page load. That presents problems because some bots can run Javascript. The second idea is to change it if and only if someone clicks on the link. Now this makes sense. However, we reach the second problem: how do you store the email address somewhere on the page without the bot being able to see and read it?

How It Works

Primitive implementations used really ugly Javascript that would look something like this:

var myEmail = ‘so’ + ‘me’ + ‘@’ + ’email';
myEmail += ‘.com';

And then later on:

<a href=”#” onclick=”return ‘mailto:’ + myEmail”>email me</a>!

You can already see that this is violating the rule of mixing content with code. What happens if your email address changes? Do you really think your designer understands that ugly jumble of a mess? At the very end of the last article, I mentioned the possibility of parsing attributes and putting things together. Using the knowledge you gleamed from there, study the following and listen closely as you hear a lightbulb turn on. The objective is to have an email link to “some@email.com”:

<a href=”#email.com” class=”email-link” id=”some”>email me</a>!

This could have also looked like any of the following:

<a href=”@email.com” class=”email-link” id=”some”>email me</a>!
<a href=”#” class=”email-link” id=”email.com”>some</a>!
<a href=”#” class=”email-link” id=”some”>email.com</a>!
<a href=”#some@” class=”email-link” id=”email.com”>email me</a>!
<a href=”some” class=”email-link” id=”email/com”>email me</a>!

As you can see, there are many, many possibilities. And it is standards compliant and relatively straight forward (especially compared to those other solutions). Best of all, this will work in any browser that supports Javascript. Let’s focus on the first example and go over why I chose that format.

This way, if Javascript is broken, the worst thing that happens is the click does absolutely nothing. Remember, if you aren’t willing to have your email address break when Javascript is turned off then you have *no choice* but to use those HTML based tricks (that bots have already beaten). For 99.99% of the population, this is a pretty worthy sacrifice. However, for those of you who really can’t deal with that, I present you this compromise:

<a href=”#email.com” class=”email-link” id=”some”>some[REMOVE]@NOSPAMemail.com</a>!

This renders into this:

!

Now if Javascript is disabled, nothing happens but your visitors can still figure out your email address! Although you’d have to pray bots can’t. Anyway, I hope you are starting to see the power of my solution.

Seeing the Address

If we can dynamically re-write the HREF portion of the URL, what’s to stop us from rewriting the innerHTML portion (the stuff between the a tags). Nothing! And this is easily possible. And this should happen during a mouseover so that people can easily read your address if they want.

The Code

Before I give you the demo, please observe the code fragment that summarizes the gist of how this works:

  1. Look for all tags with the class “email-link”
  2. For each one create a new onMouseOver that changes the text (innerHTML) into the email address
  3. For each one create a new onClick that changes the link (href) into an email link

Now I know many of you are looking at my examples and yearning for the actual source code. Please keep in mind that the source code varies greatly depending on how you choose to obfuscate your email address. I’m also confident many of you read this and are now realizing you could dynamically search and replace the “[REMOVE]” and “NOSPAM” text. That said, here is the basic source code, using Prototype‘s getElementsByClassName function:

document.getElementsByClassName(className).each(function(element) {
var emailAddress = this.id + ‘@’ + this.href.split(‘#’).last();
element.onmouseover = function() {
this.innerHTML = emailAddress;
this.href = ‘mailto:’ + emailAddress;
};
})

Now I know some of you will complain about the each() function. As I stressed yesterday, the Prototype library provides shortcuts that make Javascript programming easier. The each method goes through an array, and for each one, passes it into a function as an argument. That function can be defined on the fly, which is what I am doing. Since the array being passed in is all the tags on the page that have “email-link” as its class, the function is then processing each link. The rest, I’m hoping makes a decent amount of sense. The part with emailAddress might be a little confusing, so I will break it down into its simplified equivalent:

var otherPart = this.href; // #mail.com
otherPart = otherPart.split(‘#’); // split it up by the # symbol
otherPart = otherPart.last(); // get the last match found
var emailAddress = this.id; // some
emailAddress = emailAddress + ‘@'; // some@
emailAddress = emailAddress + otherPart; // some@ + mail.com

Demo

If you are burning to see a demo, click here.

Parting Gift

I find that it is becoming difficult to explain my demos without giving you the real source. As such, I have written a Javascript class called CleanCSS. You may download it here.