Knowing JavaScript

At my company, we’ve been interviewing people for a web developer position, with particular emphasis on programming. Something I’ve noticed is a lot of developers say: “I know JavaScript.” So a simple question I devised for testing this was, “how would you debug JavaScript?” You’d be surprised how many people don’t know the answer to this.

So, if you’re a php/perl/python/ruby/asp/etc programmer who “knows” JavaScript, here’s a few tools to help with debugging. These are Firefox extensions.

JavaScript Function to Help with Accesskeys

There’s a few little touches I like on sites I frequent: sensible tabindexes for forms, accesskeys and so on. Once I learn the accesskeys, I can fly around the main sections of a site. I apply these things to the sites I build, and the other day I realised adding accesskeys and supporting markup was no fun at all.

I wrote this JavaScript function to search for all your accesskeys and add some friendly markup. It even detects if the user is running Windows or Mac OS, to tell them to use ‘alt’ or ‘ctrl’:

function underline_accesskeys() {
  var links = document.getElementsByTagName('a');
  if (navigator.platform.match(/win/i)) {
    key = 'alt';
  }
  else if (navigator.platform.match(/mac/i)) {
    key = 'ctrl';
  }
  else {
    key = 'ctrl or alt';
  }

  for (var i=0; i< links.length; i++) {
    if (links[i].accessKey.length > 0)  {
      re = new RegExp(links[i].accessKey, 'i');
      match = links[i].innerHTML.match(re);
      links[i].innerHTML = links[i].innerHTML.replace(re, '<span style="text-decoration: underline" title="Press ' + key + '-' + String(match).toLowerCase() + ' to access this link using the keyboard">' + match + '</span>');
    }
  }
}

Read More →

Google Home API Security

If you wanted to develop a Google Home module that accesses a service using a password, you might notice a few flaws:

  1. There isn’t a password type available, so any user preferences that require a password will display the password in plain text.
  2. If you still want to store passwords in user preferences, be aware that every single time Google Home loads, it will fetch the module with the password in plain text in the GET request.

It would be nice if Google introduced a ‘password’ type, to compliment the existing types for preferences. This would at least allow you to have a starred password field in the user preferences.

Many services, such as xmlrpc used by weblogs like Wordpress, send passwords in the clear anyway. But as it stands, if a friend or colleague had a Google Home module that integrated with a third party service that required a password, I could use their browser and:

Read More →

script.aculo.us: When to Use Ajax and Effects

A few applications I’ve been developing recently have either had things from script.aculo.us applied for fun, to add effects our client would like, or they’ve been designed with Ajax and visual effects from the start.

A very beta application I’m working on is Multitap.net. Since it’s my project, and I don’t have clients to answer to, I’ve done whatever the hell I want with it. I had these things in mind when creating it:

  1. I’d use Ajax to allow users to post comments on things, to cut down on page loads. The site features screenshots from videogames as the main content, so I didn’t want to be loading a lot of images all the time.
  2. I’d use some of the transitional effects from script.aculo.us to make it obvious when new things have been added, and when hidden things appear. Visual queues can be very helpful, especially when posting comments.
  3. Being able to hide things such as settings and edit panes would keep the pages simple on the surface, and keep the focus on the content.

I have a group of friends who have been testing it and making suggestions. I found they liked the visual effects, basically for the reasons I described just there, but also because it makes the site seem quite unique.

Read More →

Carson Workshops: Get Started Using Ajax By Thomas Fuchs

I went to the Get Started Using Ajax workshop with Thomas Fuchs in London yesterday, and despite having used minimal Ajax and script.aculo.us effects before, learned quite a lot.

Thomas started off discussing the background of the technology, and wasn’t scared to dive into real examples, with PHP and Rails. He explained how the Ajax call works, and also discussed the pros and cons of using JavaScript libraries, such as Dojo and script.aculo.us, against using more lean server–oriented abstractions such as Sajax.

What was very interesting was his section on real world examples. The primary focus of this was an extensive demo of Fluxiom, where he showed how using simple effects and ajax can actually make your application behave much more like a desktop application than a web page. Fluxiom only loads images as you scroll, and uses dynamic tagging, so there’s no need to use pagination or anything messy like that. It was good to hear that Fluxiom has beta testers from all over the world, and they’ve found no latency issues when using Ajax.

Read More →

Single-table Inheritance and validates_as_unique

I had a User class, which then had a Moderator class. I was using the “type” field in my database to denote whether a user was a User or a Moderator. However, my validations weren’t working as I expected:

validates_as_unique :name, :email

Users could have the same email address as Moderators. Obviously sometimes this kind of scoping makes sense for STI classes, but it doesn’t here. I ended up writing this:

module ActiveRecord
  module Validations
    module ClassMethods
      # Intended for use with STI tables, helps ignore the type field
      def validates_overall_uniqueness_of(*attr_names)
        configuration = { :message => "must be unique" }
        configuration.update(attr_names.pop) if attr_names.last.is_a?(Hash)

        validates_each(attr_names, configuration) do |record, attr_name, value|
          records = self.find(:all, :conditions=> ["#{attr_name} = ?", value])
          record.errors.add(attr_name, configuration[:message]) if records.size > 0 and records[0].id != record.id
        end
      end
    end
  end
end

This hastily named validation keyword allows you to specify fields you want to be considered unique across the entire table, whether they be Users, Moderators, Admins or MagicalPixies. Now I just use:

Read More →

Javascript Mini Bibliography

I often annoys me when people don’t make it clear what they’re referencing in an article. Sometimes people don’t give any references at all, and when they do they use links on words that shouldn’t be links (the click here syndrome).

So I wrote this JavaScript to help out. It adds a section at the bottom of each of your Wordpress posts containing all the links you referred to in a post:

/* From Prototype */
document.getElementsByClassName = function(className) {
  var children = document.getElementsByTagName('*') || document.all;
  var elements = new Array();
  
  for (var i = 0; i < children.length; i++) {
    var child = children[i];
    var classNames = child.className.split(' ');
    for (var j = 0; j < classNames.length; j++) {
      if (classNames[j] == className) {
        elements.push(child);
        break;
      }
    }
  }
  
  return elements;
}

function post_links() {
  var posts = document.getElementsByClassName('storycontent');
  for (i = 0; i < posts.length; i++) {
    found_links = false;
    for (n = 0; n < posts[i].childNodes.length; n++) {
      for (p = 0; p < posts[i].childNodes[n].childNodes.length; p++) {
        if (posts[i].childNodes[n].childNodes[p].nodeName == 'A') {
          if (!found_links) {
            header = document.createElement('H4');
            header.innerHTML = 'Links in this post:';
            posts[i].appendChild(header);
            found_links = true;
          }
          link = document.createElement("A");
          link.href = posts[i].childNodes[n].childNodes[p].href;
          link.innerHTML = posts[i].childNodes[n].childNodes[p].innerHTML;
          posts[i].appendChild(link);
          posts[i].appendChild(document.createElement('BR')); 
        }
      }
    }
  }
}

post_links();

Read More →