Notes on GRDDL/JavaScript Development

Dan Connolly, Aug 2007

g1.js is some work toward an implementation of GRDDL in JavaScript, with an HTML form test/demo interface. It's also an expedition into the world of JavaScript by a python hacker.

Any number of times I have had an itch where scratching it involved JavaScript, so I'd google for "JavaScript tutorial". The top hits are full of suggestions to do things that no self-respecting software engineer should do:

Worst of all, why do so many tutorials fail to cite whatever sources they are based on? They don't claim to be exhaustive or authoritative, so I expected a "for more details, see ..." link. No joy. For example, the w3schools javascript tutorial says to use text/javascript but the IETF spec deprecates that in favor of application/javascript.

Last week, I finally got over the hump. (See #swig notes 2007-08-10, version control change log.) Recall from my Feb 2006 item, python, javascript, and PHP, oh my!:

Another important way that python is self-documenting is that it meets the unambiguity requirement: you can pick up any .py file and trace every identifier back to what it refers to by following your nose...

JavaScript doesn't have that nice follow-your-nose property. Douglas Crockford concurs:

JavaScript's biggest problem is its dependence on global variables, particularly on implied global variables.

JSLint -- The JavaScript Verifier, 2002

JSLint will gripe about undeclared globals and supports a "yes, I'm using this as an implicit global on purpose" syntax: /*extern functionXYZ */. So the globals I'm using are:

/*extern document */
i.e. DOM:document. The W3C DOM site presents events from 2005-06-27 as news. Who knows how much implementations have converged or diverged since then. And there's not much how-to documentation there. So I'm sticking with the mozilla docs, for now.
/*extern XMLHttpRequest */
Yay! The W3C Working Draft 18 June 2007 The XMLHttpRequest Object starts with a hello-world example. It specifies some exception conditions that I couldn't find in the mozilla docs, but I can't figure out enough about JavaScript exceptions to make use of the specification.
/*extern XPathResult, XSLTProcessor */
The XSLT/JavaScript Interface in Gecko, January 2007. An alternative is Google AJAXSLT, initially launched June 2005, but I'm OK with limiting this project to mozilla/firefox for now.
/*extern RDFIndexedFormula, RDFParser, RDFSymbol */
/*extern Util */
These are from the tabulator API. The simple demo application was once probably just what I needed to get started, but it has evidently fallen over. (See Issue235.) An Introduction and a JavaScript RDF/XML Parser, by David Sheets in July 2006 goes into detail about test suites and performance, but doesn't have much in the way of how-to documentation. So I started with rdfparser.js and followed the trail of undefined functions; this seemed to be enough:

emacs users, note: jslint recommends indenting 4 spaces, but emacs c-mode indents 2. See Karl Landström's JavaScript mode for Emacs 2006-12-26.

Security/Policy issues

I tried an XMLHttpRequest for the 1st input document from the GRDDL test cases, http://www.w3.org/2001/sw/grddl-wg/td/xmlWithGrddlAttribute.xml, but I got:

Error: uncaught exception: Permission denied to call method XMLHttpRequest.open

I found a work-around:

The same-origin policy does not apply to HTML files run from the local filesystem.

Wikipedia on Same origin policy

So I made a symlink to my local copy of the test cases and I'm using relative links, e.g. td/xmlWithGrddlAttribute.xml

Status, Future Work

The GRDDL spec has four main sections to implement:

  1. Adding GRDDL to well-formed XML, about the grddl:transformation attribute
  2. GRDDL for XML Namespaces, the recursive case for XML dialects
  3. Using GRDDL with valid XHTML, about rel="transformation", analagous to the grddl:transformation attribute
  4. GRDDL for HTML Profiles, the recursive case for XHTML dialects

After getting support for grddl:transformation working and tested fairly thoroughly, adding support for rel="transformation" was pretty easy.

But it's all synchronous. Before attacking the recursive cases, I think I'd better fix it to be asynchronous.