A BSON ObjectId implementation in Javascript

Recently I spent a few days implementing the BSON ObjectId data type used by MongoDB in javascript so I could generate ObjectIds in a a web browser. I originally had a specific problem to solve. However, I ended reworking my approach in that instance so I did not have to generate ObjectIds in the browser. Despite this, the code is still a valid approach to solving my original problem. The code is available on the justaprogrammer github org, The project is called ObjectId.js. Although the git repository contains a sample html file to illustrate its usage, all you need is the javascript file, and if you want to support IE6, json2.js.

How It Works

Originally, I wanted an implementation of ObjectId that could interact with the format that the WCF DataContractJsonSerializer serialized objects of the type MongoDB.Bson.ObjectId in the official 10gen MongoDB C# driver. This format looked like this:

{
    "timestamp":1298346771,
    "machine":8775338,
    "pid":20092,
    "increment":0
}

Now, it was trivial a JSON object that looked like this. The real issue was filling those 4 values in a sensible manner. I ended up settling on the following:

  • timestamp: This is supposed to be seconds since the unix epoch. Javascript represents time as milliseconds since the UNIX epoch. Therefore all I had to do was set this to Math.floor(new Date().valueOf() / 1000)
  • machine: This is normally the first three bytes of the md5 hash of the hostname. Since I can’t access that from the browser I store a random number in html5 local storage and a cookie for fallback. This makes the machine id probably consistent for a given combination of machine, logon and browser. Naturally, I could use something like evercookie to make the machine part of the object id more sticky. However, I felt this was “good enough”
  • pid: Pid is generated every time ObjectId.js is executed, so usually once per page. This means that pid changes each page load, but remains consistent across Ajax calls on a single page reload.
  • increment: This was simple. pid++ every time I generate a new ObjectId.

So if you need to generate ObjectId’s in javascript, check out this class. If you find a bug or have an improvement, fork and send a pull request. Happy coding!.

Adventures with SVG (a lessons learned post)

Go into the open dessert. Draw a circle around you. All that is inside the circle represents your knowledge. All that is outside the circle represents that which you do not know. The line represents that which you know you do not know. What happens as you make the circle bigger?
— Unknown

I don’t remember where I first read a version of the above story. However, it rings true for my recent experiences. You see I wrote a simple jQuery plugin, and decided to use inkscape to generate the graphics used by it. I then discovered it was possible to animate the SVG files with javascript. Before I knew it I found myself wandering through a dessert awaiting the promised land of SVG. I’ve yet to reach the promised land, but I’ve learned a lot in the experience.

Lesson Zero: SVG is poorly documented on the web.

I need to qualify the section header a bit. The actual standard is pretty well defined. There are examples on the web, and w3schools has a section on SVG. However, SVG is not popular enough for you to be able to steal all your code from google. You will have to experiment to do a lot of simple tasks.

Lesson One: SVG has very html like DOM.

This one was a pleasant surprise actually. SVG elements have event attributes like onload and onclick. Animating is as simple as recursively calling a function via window.setTimeout(). You could call console.log() to trace your javascript’s execution via firebug or the chrome developer console. In general I was able to leverage a lot of the javascript experience I’ve had with html.

Lesson Two: I should be animating with SMIL instead of javascript.

I’ll call this a lesson I’ve not really learned. If I truely learned my lesson I would have learned SMIL and done my animations with it instead of javascript. However, I was more concerned in exploring what could be done by combining javascript and SVG than animating SVGs.

Lesson Three: SVG is inconsistently implemented in practice.

I’m not just talking about amongsT the browsers, but that too is a problem.

First of all, you need to use one of several plugins to render SVGs in Internet Explorer. IE9 will finally rectify that. The no longer maintained Adobe SVG plugin was the most popular IE plugin. However, the still alpha flash and javascript based svgweb by google is gaining popularity. That one has the advantage of not requiring any special software besides flash, which is probably already installed. However, it seems it does not support javascript embedded in the svg file.

Second, SVG support is inconsistent amongst opera, firefox, and chrome. Chrome has a nasty habit of not rendering svg embedded in html via an <object/> tag if the mime type is not properly set. I discovered this while serving html and svg through Cassini.

(As an aside, I have made available a modified version of Cassini on github so no one will have to suffer as I have.)

Third, inkscape, the editor I use to draw my SVGs, is not a complete SVG editor, and it implents several extensions to the SVG standard. The extended elements have not prevented SVGs I drew in Inkscape from being rendered in browsers since they have different XML namespaces. While I’ve discovered how to reference external javascript files in a svg through inkscape, I have to use a separate text editor on the SVG files to embed javascript in the document.

Conclusions

My first conclusion is SVG is not quite ready for prime time as a deploy directly to the web technology. However, there is enough buzz happening that early adopting might be prudent for some scenarios. Browser support is improving, and the tools are improving.

My second conclusion is that SVG is ready as a “mastering format,” like PSD, XCF (gimp native) or Illustrator. If you want to draw with a rector tool, and then render to a bitmap, SVG is a solid format. Inkscape is a good editor.

My third and final conclusion, is that the desert of SVG is very big, and my circle in the sand is quite small.

Printf() for jquery.

I was preparing for my pre-session talk this past November at LISUG, when I determined that I needed a printf() function for jquery. To be more accurate, more accurately I needed an sprintf() implementation in javascript, and wanted to .

Google lead me to a jquery plugin that has not been updated since 2007. However, sometimes software gets to the point where it really doesn’t need to be maintained, and if it worked for me I was not going to dismiss it as abandoned software.

In the end it did require a small patch to handle %% (really print a percentage sign). Unfortunately, the maintainer has not acted on my patch. However, please apply it if you plan on using it.