SVG Cities with Greasemonkey

I've been experimenting with using Greasemonkey to rewrite the interface to a game I've been playing recently called Cities. I was trying this because I wanted to test how well a native SVG interface to a web application might work, and it was much easier to work with an existing web application - one that I use - than developing one as I go.

Here's a screenshot of the standard Cities viewport (with CSS styles by Bebe):

Cities HTML View

And this the current status of my viewport implementation:

My SVG Cities View

Cities is a browser-based MMO. It's a slightly off-beat fantasy game with some humourous elements and not very many quests. Many of the rules are based on alignment, which is one of the four classical elements: earth, air, fire and water. It's alright, and quite fun when you get a couple of the alignment quests under your belt and the game starts to open up a bit, but the design isn't very polished and much of the world is fairly large, boring and featureless.

Anyway, it's quite well developed as a web application, and I play a little bit daily, so it's a good candidate for my experiments.I decided to use Greasemonkey after trying some of the Greasemonkey scripts other people have written to add the features they wanted to Cities. The approach I wanted to use was to replace the viewport with an SVG OBJECT on my server, and configure the OBJECT with Javascript by parsing the data out of the standard viewport's DOM tree. However, Firefox's Javascript sandbox prevented me from accessing the OBJECT's .contentDocument property because the SVG was loaded from a different domain. This is to prevent cross-site scripting vulnerabilities.

The first thing that occurred to me as a workaround would be to host the SVG on the Cities Wikimedia Wiki. Then by assigning a value to document.domain (this is allowed iff you're generalising from a subdomain, which the wiki is) you can permit the XSS.

But in fact I didn't try this because this would require me to update the version on the Wiki every time I wanted to test a page load. So in fact the approach I took was to load the entire SVG with a Greasemonkey AJAX request (has to be a GM AJAX - the vanilla kind also has XSS security) and import the SVG DOM into the HTML DOM. Firefox in fact renders this combination better than it renders an SVG OBJECT, because it can use the native dimensions of the SVG from the SVG documentElement rather than you having to respecify them as attributes of the OBJECT element.

For the parsing of the DOM tree, I would have liked to have used E4X, but it doesn't appear to work. This could just be a Greasemonkey limitation, because Greasemonkey uses XPCNativeWrapper for security reasons, or it might be that E4X doesn't interoperate well with DOM yet. It didn't occur to me at the time that I could have used XSLT, but there was quite a bit of processing involved in configuring the SVG DOM tree, so although this might help it would only be of real use in reading the state of the view from the source source DOM. This would be easier than writing DOM javascript to do it, but not as easy as E4X.

Reconfiguring the DOM was mainly rewriting and adding elements to link to symbols defined within the SVG file. No SVG paths were constructed in the Javascript, only a few elements.

I've got relatively far but the thing that has halted my progress is the problem of perspective on the viewport. I could make the view isometric, but I could have done that with a collection of absolutely-positioned transparent PNGs.

I could encode some 3D information in XML and use that to lay out the artwork in the tiles with perspective correction, but that is a lot of work for what is basically an experiment.


Comments powered by Disqus