engineering a better experience
Monday, February 20, 2012 (Updated )

Code Review: metadash

by The Metaist

This post is based on code that was written over a weekend. Code quality may vary.


A code review is a process for finding and fixing mistakes in software often with peers. metadash is a lightweight personal dashboard that uses browser cookies to store the list of links.


(Image: Metaist)


Code Review

Last weekend I created a simple webpage called metadash that provides a list of links that are stored in a cookie. Nothing too remarkable. But it does seem like a good place to extract and discuss some common programming idioms and best practices.

HTML — the skeleton

Most of my projects start off with a bit of HTML. In general, I follow the recommendation to put styles up top right before </head> and JavaScript at the end right before </body>. This allows the browser layout engine to start parsing the stylesheets before the DOM elements to which the styles apply are loaded. Similarly, the scripts typically operate on the DOM and wait for it to load, so they might as well be loaded closer to the end when the DOM will be ready.

So overall, the HTML looks like:

<!DOCTYPE html>
  <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
  <title>metadash (metaist)</title>
  <!-- stylesheets -->
  <!-- content -->
  <!-- scripts -->

Fig 1. General HTML structure

  1. Nowadays, I use an HTML5 doctype because it's good enough for most browsers. If I really need the HTML5 elements, I'll also use HTML5Shiv so that IE will behave.

  2. It's generally a good idea to declare a charset for your documents. If you don't know anything about Unicode, read this.

While most <script> tags are fine towards the bottom of the document, some need to run right away before the DOM is loaded—like Google Analytics.

<script type="text/javascript">
  var _gaq = [['_setAccount', 'UA-XXXXXXXX-X'],['_trackPageview']];
<script type="text/javascript" src="//"></script>

Fig 2. Loading Google Analytics

I make two improvements over the loading code Google provides:

  1. Setting up the _gaq array directly. I do this because I know I'm not loading the same script more than once.

  2. Loading ga.js using a protocol-relative URL (technically called a "network-path reference") which loads using either HTTP or HTTPS depending on how the page itself was loaded.

Google writes a whole bunch of javascript to accomplish both these things, but I can only barely fathom the reasons why.

Other scripts that belong in <head> are ones that operate on stylesheets like LESS.

The main application HTML is in the middle of the <body>:

<ul id="urls"></ul>
<p id="no-results"><em>No URLs saved.</em></p>

<label for="txt-url">URL:</label>
<input id="txt-url" name="txt-url" type="text" />
<button id="btn-add">Add</button>

Fig 3. Main view and controls

CSS — the skin

metadash is not the prettiest application in the world, but I wanted to include rearranging the list which required jQuery UI— which is most of the CSS.

Instead of reproducing the entire CSS here are a few interesting snippets.

.btn-clear {
    display: inline-block;
    cursor: pointer;
    vertical-align: middle;

.url { vertical-align: middle; }

Fig 4. Inline-block display & middle vertical alignment

  1. The display: inline-block; is possibly the best finds I've had in CSS. It allows inline elements (e.g., <span>, <li>) to behave like block-level elements (e.g., <div>) so you can set their width—without creating a new line.

  2. Until recently, I feel like vertical alignment never worked the way I expected. (I'm still annoyed that I cannot align text vertically in a <div> without crazy incantations.)

JavaScript — the muscles

In a model-view-controller (MVC) paradigm, the view and model communicate via the controller. While not strictly adhering to the same paradigm, we might say the HTML is the model/view, CSS styles the view, and JavaScript acts like a controller. The reality is that the roles are rarely distinct.

There's isn't much to say about JavaScript, although I did want to highlight a pattern for creating an anonymous private scope in JavaScript (which makes due surprisingly well without many of the common object-oriented features).

(function($) {
  // anonymous, private scope
  var x = "invisible outside of this scope";

Fig 5. Anonymous private scope in JavaScript

The trick here is that the function is defined and then immediately called without being assigned to a name (hence, anonymous). The result is that any definitions that are exposed to the outside world are thereby invisible to everything outside the defined scope.

JavaScript Libraries — steriods

I make extensive use of jQuery and for this project I made use of jQuery UI to provide sorting, jQuery Cookie to store the URLs, and URI.js to normalize the URLs before storing them.

The result is a small little personal dashboard that is entirely cookie-based.

See Also