libsvg.js: porting lib-gwt-svg apps to native JS and Firefox OS

I recently purchased a FirefoxOS phone and wanted to create my first application for the device. I already had a large legacy of GWT code based on lib-gwt-svg and lib-gwt-file and wondered if I would be able to reuse some of that and in what form.

I quickly realized that I would not be able to keep GWT as a framework to address FirefoxOS devices. There is no GWT plugin for FirefoxOS devices, and developing in web mode or super dev mode means several-minutes build / compile / test cycles which are just not workable for me. Furthermore, the lack of encapsulation for all the new browser APIs (IndexedDB, web activities, AppCache…) means I woudl had had to develop a GWT encapsulation layer for this before getting started.

The altenative seemed a daunting too: leaving java, Eclipse and code completion behind. I tested various JS IDEs (NetBeans, Aptana, Eclipse + JS, WebStorm) to see evaluate their code completion module.
I decided to use WebStorm as it is capable of parsing jsdoc comments to infer types of variables in a lot of cases and offers auto-completion and contextual documentation when writing code.

To leverage this, I have ported lib-gwt-svg to Javascript and called it libsvg.js. I found out there is really no need to port lib-gwt-file to Javascript, at its using the File API directly in JS is actually straighforward.

lib-gwt-svg has actually two parts: one part is GWT wrappers for the SVG Javascript API, adorned with documentation extracted from the spec and injected at the proper location as javadoc comment ; the other part consists in miscellaneous utilities for common SVG operations, such as rectangle intersection or vector normalization.

libsvg.js comes itself is made up of two files:

libsvg-ide.js

is just a collection of JavaScript prototype declarations, adorned with documentation extracted from the spec and injected at the proper location as jsdoc comment. If your IDE is smart enough (Webstorm actually is), it will be capable to infer the type of js variables and provide autocompletion and contextual documentation based on this file, as well as warn you of errors if you do not respect the method signatures. The file is not intended to ever be loaded by an actual web browser. It just lives in the IDE as a helper, you do not need or want it in actual production.
libsvg.js

contains the utilities part of lib-gwt-svg, as well as helper methods to help the IDE infer the proper type for JS variables method.

In libsvg.js, there are two main classes of helper methods provided.

Factory methods

have been added to the Document prototype to let you create SVG elements from scratch:

// Create a circle using the extra factory method added to the Document prototype.
var circle = document.createSVGCircleElement();
// Now the IDE is aware of the type of the circle variable, because it has read the prototype and javadoc of SVGCircleElement from the libsvg-ide.js file and knows createSVGCircleElement returns a SVGCircleElement. The line below is typed with autocompletion.
var circle.cx.newValueSpecifiedUnits(SVGLength.SVG_LENGTHTYPE_PX, 100);
Hinter methods

have been added to the Element prototype to let you specify the type of elements you retrieve using calls to getElementById, XPath, DOM traversal. Technically, these methods do nothing except return the element itself, but they do it with a properly crafted jsdoc comment which the IDE can use to infer the type of the element. This presents an overhead, but it is tolerable in most cases and JS optimizers are probably capable of figuring out they are useless at runtime and eliminate the extra code altogether (though I have not verified this claim !).

var circle = document.getElementById("c1").asSVGCircleElement();
// Now the IDE is aware of the type of the circle variable, because it has read the prototype and javadoc of SVGCircleElement from the libsvg-ide.js file and knows asSVGCircleElement returns a SVGCircleElement. The line below is typed with autocompletion.
var circle.cx.newValueSpecifiedUnits(SVGLength.SVG_LENGTHTYPE_PX, 100);

Using lib-gwt-svg, I was able to port the SVG part of my game fairly easily to JavaScript. The truly hard part was to redesign the game itself to turn it into an application and to make it usable on devices such as smart phones and tablets. The game is called Push Puzzle and can be run online from a FirefoxOS phone or most web browsers.

Leave a Reply

You can use these HTML tags

<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>