Making Deniz a single-file-app

Following up to the previous post, Deniz, the RDF browser written in HTML, Javascript & CSS, can now be distributed as one single file.

This is possible due do

The last step missing was the image embedding part which is nicely solved through https://github.com/nzakas/cssembed. In addition Deniz will now go through the Google Closure Javascript compiler and Yahoo’s YUI Compressor for CSS to save bandwidth.

Thanks to the Makefile by Benjamin Lupton (https://github.com/balupton/jquery-sparkle/blob/master/Makefile) it was easy to set the process up for Deniz.

Two steps will build the file:

$ make build-update

to download JAR dependencies, and

$ make

to finally minimize and integrate all contents.

That’s it.

Advertisements

Embedding external CSS & Javascript into the base HTML document

So I’m stuck on the train for some hours, why not solve a problem that is far from pressing?

I am developing a web application based only on HTML, CSS & Javascript, called Deniz (http://cburgmer.github.com/deniz/). It’s a browser for RDF data and only needs a browser to run in, as it will connect to public data endpoints. So while it is build up from many different sources it would be nice if the whole application could be delivered in a single file. While this could speed up loading, the main idea here is to distribute just one HTML file.

Looking around there are many services and libraries for compressing and aggregating CSS & JS files, but so far I haven’t found a solution specifically for what I try to achieve.

I’ve now come up with an implementation which parses the DOM tree and looks for elements with references to stylesheets and <script> tags
referecing external Javascript code. The program will read in the contents of the referenced files and paste it into the document. This is harder than it initially seems: XHTML which I assume here, needs to have data wrapped in a CDATA directive. I had to fight with the Python lxml library for some time to get this straight:

  1. The parser needs to be passed “strip_cdata” so that read CDATA blocks are preserved.
  2. Code needs to be wrapped in an instance of the CDATA class
  3. A dirty hack to quote the encapsulated CDATA blocks in multi-line comments to accommodate older browsers:

        html.replace('<![CDATA[', '/*<![CDATA[*/').replace(']]>', '/*]]>*/')

  4. While a proper solution would need to parse CSS & Javascript code to quote invalid HTML entities, another dirty hack makes sure that the text ‘</script>’
    in Javascript strings gets quoted:
            content = (content.replace('</script>"', '</scr" + "ipt>"')                          .replace("</script>'", "</scr' + 'ipt>'"))

Warning: This script is not suited to parse any JS & CSS. It does though work for my task.

The source can be found here: http://github.com/cburgmer/deniz/blob/master/embed_media.py

The next step will be to include images as base64 urls.