Java’s anonymous classes are subclasses, not instances of the class

More of a note to myself really. Anonymous classes in Java are subclasses. For whatever reason I’d led myself to believe that anonymous classes in Java are unnamed instances of classes, but they are not, they are subclasses.

this.getClass().getSimpleName() returns empty string for anonymous classes, but that doesn’t mean you can’t ever know the class name the anonymous class was created from. All you need to do is: this.getClass().getSuperclass().getSimpleName();

jQuery plugin to add a CSS class to last-child DOM elements

This has been bugging me for ages. IE < 9 does not support the CSS3 last-child pseudo class. I’ve created a _very_ simple jQuery plugin to add a CSS class “last-child” to the element that is the last child of a DOM element.

It performs this recursively, so it’ll apply the class to the last child of an element as well as to the last child of all it’s children…and so on and so forth.

It’ll perform this on each of the set of matched elements in a jQuery object. So you can have it traverse the whole, of your page by providing a jQuery object with the <body> element in it, or you can pick and choose DOM elements to apply the plugin to for efficiency. For instance, you might only need the "last-child" class to be applied to the last child of an unordered or ordered list:

    $('body').lastChild(); // Applies to all elements attached to the document.body
    $('ul, ol').lastChild(); // Applies to all elements in an unordered or ordered list

By default, the plugin applies the CSS class to a restricted set of DOM element types. You can specify the types of DOM elements to apply the class to by passing an options object to the function. In this way you can also specify the name of the CSS class that will be applied:

    $('ul, ol').lastChild({
        tags:['li'], // Only elements with the tag name 'li' will have the class applied to them
        cssClass:'ie-last-child' // The CSS class name will be 'ie-last-child'
    });

For super shorthand, you can simply pass a string to the lastChild function – which it presumes to be the CSS class you want to use:

    $('ul, ol').lastChild('ie-last-child');

You can download the plugin here.

Note, while I created this plugin to get around my IE problem, it is not built specifically for IE. If you only want IE to receive these classes, you’ll probably want to do something like:

    if($.browser.msie) {
        $('body').lastChild();
    }

…but obviously preferably using Modernizr:

    if($('.ie6, .ie7, .ie8').length) {
        $('body').lastChild();
    }

Enjoy!

Chrome

I started using chrome as my main browser. What was holding me back was that the webkit developer tools for a long time just weren’t as good as Firebug. Now they are almost on a par. So I’ve been using Chrome as my main web browser for coming up to two months now and for the most part it has been a fantastic experience. Chrome is just lightning fast, from startup to rendering to javascript performance. I don’t have any benchmarks, but everything just feels really "light".

This could be because I’m coming from Firefox with three plugins installed: Firebug, Web Developer Toolbar and Adblock Plus…but I get the feeling that if I disabled the Web Developer Toolbar and Adblock Plus, Firefox still wouldn’t feel as light. Anyway, this isn’t why I started the blog post. I really wanted to vent a couple of frustrations I have with the browser. Seemingly minor frustrations that could probably be fixed really easily. Here they are:

  1. I can’t change the default font or page background colour or if I can, I can’t find where I do it. I change the default font and background colour from black to dark red and from white to grey respectively so that when I build websites I remember to set a default font and background colour in my reset
  2. It is really hard to save a 1×1 pixel image from a website to my desktop. I have to pinpoint the exact pixel on the screen and right click on it. I haven’t figured out an easier way of doing this…if there even is one
  3. When saving an image using the network tab of the developer tools the filename becomes "download" and _not_ the filename of the image I am saving
  4. Lastly, no out-of-the-box RSS support. I really miss it, and I love Firefox’s implementation of it in the bookmarks bar. N.B. I realise there is a plugin.

Can’t access MySQL because there are no records in mysql.user? This is how you fix that.

I don’t know if it is a problem with the OSX distro of MySQL 5.1.54, but when I installed it recently I found I couldn’t login at all. Nor could I set or reset the root password. The underlying problem was that there were no records in the users table…yeah, exactly, WTF?

I found this out because I eventually got to the end of the MySQL reference for resetting the root password where it tells you to perform a lobotomy on your mysqld and start it up using the –skip-grant-tables option. Nothing else had worked, and when I finally did then get in and SELECT * FROM mysql.user, I got no results, nadda.

The reference manual for resetting permissions starts by telling you to update the mysql.user table and set the password for the root user – but that doesn’t work if you’ve got no users in there. What to do? Well, you need to get all down and dirty and bypass CREATE USER and GRANT PRIVILEGES and simply INSERT a new user and their privileges into the mysql.user table. Simple really, and also described in the reference for adding users.

Why HTML5?

I was recently asked to qualify why I had “upgraded” a website to utilise HTML5. All I had actually done was throw in a few semantic tags where it seemed appropriate and remove some unnecessary attributes. The client was concerned that the spec wasn’t complete and even suggested using HTML5 tags with an XHTML strict doctype. This was my response:

The HTML5 specification is different to your typical software specification. The W3C is no innovator: it does not lay down rules for browser vendors to follow. Vendors lead the way and their technology ideas are ultimately accepted, rejected, or tweaked to become part of the W3C specification. It’s highly unlikely the HTML5 specification will ever be fully complete. The only point when it could happen is when vendors and the W3C draw a line in the sand and move onto HTML6 (or whatever they name the next standard). If you wait for the final HTML5 specification, you’ll miss out.

http://blogs.sitepoint.com/2010/07/20/5-reasons-why-you-can-use-html5-today/

To say it’ll never be complete is a little pessimistic. Some experts in the industry believe it could be complete as soon as 2012. You get the idea though.

In terms of what the site is doing with HTML5 we’re not actually leveraging much of what HTML5 has to offer. Firstly we’re saving bandwidth by omitting attributes that all browsers already assume default values for, like the script type=”text/javascript” and stylesheet type=”text/css” attributes. Not to mention the new doctype, which is completely backwards compatible with existing doctypes in that it invokes standards mode in all browsers. Actually, in terms of your website it would be better to use a HTML5 doctype than an XHTML strict doctype, since the page is being served as text/html content-type by Apache, which is incorrect – the correct content-type for XHTML documents being application/xhtml+xml.

The second, and only other feature of HTML5 we’re actually using is semantic tags (http://bit.ly/1CzNqy). These allow us to create a document that is more accessible, in terms of search engine optimisation and for use of assistive technologies like screen readers. By using semantic tags instead of generic containers such as the div tag, our document is easier to understand when viewed by tools that don’t “see” page styles i.e. the design and layout of the page. For example, if your business name is within a paragraph tag it is likely to get lost in other content and not be returned in search engine results. But if you put it within a heading 1 tag, search robots know to give it more importance. Obviously this example doesn’t involve any HTML5 tags, but you should easily be able to see how the same principle can be applied to the new HTML5 elements, and how this principle will gain more and more importance as HTML5 becomes more widely adopted.

…and that is really the idea behind HTML5, everything that is being proposed, is being done so in a) a backwards compatible way and b) to cement features that already exist in one form or another. Pragmatically, that is what makes it viable to use features of HTML5 right now. Most existing browsers treat unknown tags as a generic HTML inline element and they can be styled to suit purpose.

Your one and only concern should be that there is a bug in IE 6, 7 and 8 that means they don’t recognise HTML5 tags. Fortunately there is a workaround, although it requires JavaScript to be enabled. If your visitor is using IE, without JavaScript enabled, your site will look differently to how it would normally look. It won’t make the site inaccessible, but some stylistic properties won’t be applied to page elements, so the page will appear a bit more like a text document than a website. Globally, I’ve seen stats showing that between 0.4% and 7% of browsers have JavaScript turned OFF. Potentially a very small percentage of your web traffic – which will probably be even less considering it only effects IE users, but it depends on your audience. Check your webstats and make a judgement call. For the majority of the time, the benefits outweigh the cost of supporting the fringe cases and I would recommend using HTML5 on your website now, as I have done for a number of clients I have worked with recently.

Modernizr progressives or exceptions?

Modernizr, what an interesting tool you are. How do I use your class names in my CSS files? You’ve given me a choice and I’m not sure what to use:

.multiplebgs div p {
  /* properties for browsers that
     support multiple backgrounds */
}
.no-multiplebgs div p {
  /* optional fallback properties
     for browsers that don't */
}

There are two ways to view this, bottom up, and top down. They both have their advantages and disadvantages, and I’m going to attempt to highlight these for you, so you can make your own decision.

Bottom up

For the “bottom up” way of doing things, we define a lowest common denominator. A set of styles that will work with all the browsers your website is designed to target. The intersection of all the features of all your browsers, if you want to put it that way. From here, we use Modernizr to progressively enhance the user’s browsing experience for browsers that support particular features. An example may help:

a.btn {
  background:transparent url(../img/btn-red.gif) no-repeat scroll 0 0;
  padding:5px;
  display:inline-block;
  width:40px;
}
.borderradius a.btn {
  background-color:red;
  background-image:none;
  border-radius:5px;
}

The advantages being:

  • A clearly defined baseline that works on all browsers we’re coding for
  • If we aren’t able to determine client features (because for example, Modernizr is not available: the CDN is down, or the client doesn’t have JavaScript enabled) we know that the baseline styles will be used and will ensure the site looks acceptable regardless

The disadvantages are:

  • We end up writing more and more CSS as we utilise new features that become available
  • It doesn’t encourage a particularly forward thinking coding practice. You’re essentially coding for the browser with the lowest feature set
  • If you want to change the baseline styles because of a redesign or perhaps your baseline is raised, you’re probably going to have to change overridden styles in the progressive enhancement style blocks as well

Top down

The “top down” approach is where we define styles for new browsers, and then use the “no-” prefix classes to define exceptions for browsers that don’t support the feature we’re exploiting. e.g.

a.btn {
  border-radius:5px;
  background-color:red;
  padding:5px;
  display:inline-block;
  width:40px;
}
.no-borderradius a.btn {
  background:transparent url(../img/btn-red.gif) no-repeat scroll 0 0;
}

We’re forward thinking, assuming everyone viewing our site is using these great new features and coding in fallbacks for the exceptions to the rule. Our view is that one day, all browsers will support the styles we’re using…and we’re adding in exceptions for in the mean time. The advantages are:

  • We end up writing less CSS, as we don’t have to override properties we’ve previously declared that the browser doesn’t understand
  • Our mindset is altered slightly, encouraging us to make use of and exploit new browser features that allow us to code and prototype faster
  • As our browser baseline increases, it’s really easy to remove exceptions that are no longer used

The disadvantages are:

  • We’re totally relying on Modernizr and the browser having JavaScript enabled. Without JavaScript the “no-” prefixed classes are not added to the <html> element and the browser is left trying to style things that aren’t supported or use style declarations that don’t exist (as far as the browser knows).

Well, sort of. You could always use the “no-js” class on the <html> element which Modernizr normally removes and replaces with “js” (to indicate JavaScript is available). You’d define your styles as above, but then define a lowest common denominator style set, for when you don’t know what features a browser does or doesn’t support. That’s kind of overkill though.

So, that’s basically it. When I first thought about it my gut reaction was to sit in the bottom up camp, but after thinking about it, and considering the audience for the project I’m working on it makes more sense to use the top down approach. Especially now that I’ve written it down like this. I’m hoping it’ll help others to make the right decision.

How to use CakePHP Session data in your Model validate rules

CakePHP models don’t allow you to access the session object. It is argued that this isn’t the MVC way. I tend to agree. Your controller should really pass any needed session data to the model…somehow.

My use case is that my model needs to validate that when a new user is created, it is given a “group” with equal or lesser privileges than the creator’s group.

Whilst they wouldn’t be able to use the create user form to do this (as the form only lists groups they can assign), we still need to guard against it on the server as it would be trivial to submit a specially crafted POST request with a group ID of a group with higher privileges.

My model needed to access the logged in user’s group ID from the Auth component (which stores its data in the session). So that when my model data was validated, I could check for a valid group ID, based on the group ID of the current user.

I knew I needed to make use of custom validation methods, but how could I get hold of the current user’s group ID? The Auth component isn’t available in the Model, so, what could I do?

Luckily, CakePHP’s AppModel defines a function called “validates”. Which allows you to check whether a model’s data is valid, but crucially it allows you to pass custom options to be made available in the “beforeValidate” callback.

So instead of simply saving my model data to the database, I call this function, passing my current user’s group ID and THEN call save (passing it a parameter to tell it not to bother validating the data again).

In my model, I overrode the “beforeValidate” callback function, which defines (on the fly) a new validation rule: a custom validation method, that takes the current user’s group ID as a parameter. My custom validation method can then check the model data against the current user’s group ID to see if it is valid. WIN.

Below I’ve included some example code to illustrate how this works. In this example I pass the whole Session object to the custom validation function. Which is slightly overkill. I think you should really just pass the data you need. Create a model that looks something like:

class MyModel extends AppModel {

    var $validate = array(
        // Your usual validation rules for all fields
    );

    function beforeValidate($options) {
        
        if(!empty($options) && isset($options['Session'])) {
            
            $this->validate['fieldName'] = array(
                'ruleName' = array(
                    'rule' => array('validationFunction', $options['Session'])
                )
                // + your default validation rule(s) for this field
            );
            
        } else {
            
            // Either...
            unset($this->validate['fieldName']);
            // If you have no normal rules for this field
            // Or...
            //$this->validate['fieldName'] = array(
                // Your default validation rule(s) for this field
            //);
        }
    }

    function validationFunction($check, $session) {
        
        // Do your checks with session data
        return true; // or false
    }
}

You use this in your controller like so:

class MyController extends AppController {

    var $uses = array('MyModel');
    var $components = array('Session');

    function action() {
		
        if(!empty($this->data)) {

            $this->MyModel->create($this->data['MyModel']);

            // Validate, passing custom options to be made available in the beforeValidate callback
            if($this->MyModel->validates(array('Session' => $this->Session)) === true) {

                // Save, without validation
                $this->MyModel->save(null, false);
            }
        }
    }
}

Highlight text using jQuery and the HTML5 mark tag

Here’s a jQuery plugin I wrote that’ll add HTML5 <mark> tags around keywords or phrases in an element’s body text.

What is mark?

a run of text in one document marked or highlighted for reference purposes, due to its relevance in another context

http://www.whatwg.org/specs/web-apps/

Usage

Add the script to your page, and then when the DOM is ready, do something like:

    $('body').mark('Lorem ipsum');

The plugin can actually be used to wrap any tag around keywords. Simply pass the tag name you want to use as an option:

    $('body').mark({
      text: 'Lorem ipsum',
      tag:  'span',
      cssClass:  'mark'
    });

The above example will wrap span elements around the words lorem and ipsum. Each span element will have the class ‘mark’. View an example implementation.

TODO

  1. Input sanitation on the text to be marked. Currently the text is dumped straight into a regular expression. It needs to be escaped so that any regular expression meta-characters are interpreted as literals.
  2. Similarly, HTML special characters in the input need to be expanded into their HTML entities.
  3. From what I can see, IE doesn’t like <mark> tags, and seems to automatically self close the opening and closing tags inserted into the DOM. WTF? Can anyone shed any light on this problem? For now, you’re going to have to use a <span> with a CSS class

If you’re interested in contributing, get in touch

Using HTML5 canvas.toDataURL to generate placeholder images

A while ago lewis had a great idea – an online tool to figure out the proportional height, when given a width and a particular proportion.

I’ve actually needed to use it 3 or 4 times since it was created around a month ago, so I was keen to get involved and implement some of the suggestions he received to make it better. One of the suggestions was that the tool should generate placeholder graphics, which developers can use whilst creating websites.

I was thinking PHP GD library, which could have quite easily have done the job. However, there are a few disadvantages with this:

  1. The user has to wait while the browser makes a request to the server and gets the response
  2. The server has to have the GD image library installed!
  3. The server has to do work to generate images – eating up your valuable CPU cycles
  4. The server has to temporarily store the generated image – using up disk space
  5. The request and response both use up bandwidth
  6. The tool wouldn’t work offline

All of which could be argued to be relatively inconsequential…but I wanted to do something fun. I decided to use the HTML5 canvas element to draw the placeholder graphic because, well, that sounded fun.

Canvas has a method called "toDataURL" which (as you can probably guess) encodes the content of the canvas as a data url. I spent a couple of hours in the evening knocking up a prototype utilising this functionality.

You may be thinking (when looking at the source for the prototype): "where’s the canvas"? What actually happens is that when you change the width or height using the input boxes, the page dynamically creates a canvas element, draws the placeholder graphic inside, calls toDataURL and then creates an <img> tag, whose "src" attribute is set the data url we got from the canvas. The page then removes the canvas element and the old placeholder graphic, and appends the new graphic to the DOM. The process is so fast you don’t ever see the canvas element on the page.

The reason we don’t just leave the canvas on the page is because we want users to be able to save these graphics. You can’t right click on a canvas and select "Save image as…".

The only disadvantage I can think of by using this method is that it won’t work on older browsers…or browsers without javascript enabled. Ok that is two. Other than that, it’s great:

  1. The user doesn’t have to wait for a round trip to the server to complete
  2. The server does no further work other than to serve the script file
  3. No bandwidth is consumed transferring the image
  4. The tool even works offline!

To me, that sounds like WIN.

iframe automatic height adjustment using HTML5 cross domain web messaging

Yesterday I was working on a site that needed an iframe embedded in the page whose content came from a completely different domain. I try to steer clear of iframes at all costs normally so forgive me if what I’m about to say is pretty obvious.

I didn’t want the content in the iframe to appear as though it was in an iframe, so obviously I stripped off all the default browser styles…well, the border. I wanted the iframe to be as high as the content it was containing so that no scroll bars would appear.

So what I did was just give the iframe a height, however when the user navigated to a different page within the iframe, the height I had previously set was too big or too small.

I instantly thought “right, JavaScript will sort this out for me!” and proceeded to quickly code up a function that would inspect the scrollHeight of the content in the iframe and adjust the iframe height accordingly.

No! Said cross domain policy. I had momentarily forgotten all about that. Since the iframe content came from a different domain, I wasn’t allowed to access the document object of the iframe (or vice versa).

Here is how not to do it

Firefox says “Error: Permission denied to access property ‘document’” and other browsers similar.

I started searching for some kind of workaround.  Of course there isn’t really one…except I did find an interesting hack for Firefox. Which is – an iframe document can alter the url fragment of the parent window’s location object! ha madness.

The idea is that the document in the iframe alters the url fragment to read:

http://freestyle-developments.co.uk/blog/?p=150#138

Where 138 is the height of the iframe document (obviously you could be a bit more fancy and send other parameters and name them e.g #height:138 but for simplicity I’ve just set the value). The parent then reads this value and sets the iframe height accordingly:

var iFrameHeight = parseInt(location.hash.replace('#', ''));

So…yeah, that’s pretty interesting, but not really a solution. Check out the example implementation here.

Anyway, what to do? HTML5 web messaging to the rescue! Sweet! HTML5 web messaging is cross domain messaging done right. Not only does the messenger choose who should receive messages, but the recipient also chooses who to receive messages from.

The idea is that after the iframe document has loaded, it sends a message to the parent window telling it what it’s scrollHeight is. The parent listens for messages, and sets the height of the iframe when it receives a message.

A couple of things to note:

  1. There has to be communication between the two documents. i.e. the document on the external domain needs to actively send this message. Which can be a complete show stopper if you have no control over the document on the external domain
  2. This isn’t going to work on IE < 9. I tested the implementation linked below is working on FireFox 4 (Beta 7), Safari 5.0.2, Chrome 8, Opera 10.63 and Internet Explorer 9 Platform Preview 7. Which is a pretty good spread to be honest

Check out the example HTML5 web messaging implementation here.