2007-04-29

XPath bookmarks

The web doesn't have any good way of bookmarking any spot in a web page. With some help from the web page author, we can bookmark a specific anchor or node id in the page, but most particular spots are still not reachable for bookmarks. I just tossed up a little user script that makes any node in the page addressable by an XPath query bookmarkable. It's mostly for XPath power users, for now, but works well (and lets you load bookmarks using that technique, which you might have gotten from such people).

The source code (install from here) is extremely short:
var path, node, hash = decodeURIComponent( location.hash||'' );
if( (path = /^#xpath:(.+)/.exec( hash )) &&
(node = $X( path[1] )) )
node.scrollIntoView();

function $X( xpath ) {
return document.evaluate( xpath, document, null, 0, null ).iterateNext();
}
Having installed that, you can load bookmarks like http://tibet.dharmakara.net/TibetABC.html#xpath:/html/body/h2[3], and get zoomed in to the right part of the page immediately (here, the part featuring how the Tibetan numbers are spelled, what they look like, and approximately how to pronounce them, for us westeners).

Scope user scripts to HTML pages

Most user scripts, and especially user scripts writing the DOM (injecting a user interface of some sort, for instance) should, but don't, start with this line of code:
if( !(document.contentType||'').match( /html/i ) ) return;
Which means what? Well, it ascertains that the page loaded is HTML, which people tend to take for granted, but which is not the case for all pages on the web. Especially, it is not the case for text/plain pages, by the broad masses more commonly known as *.txt. In Firefox, text documents get rendered much like HTML pages, but in a <pre> encasing.

Saving the document will remove this "HTML enclosure", but if your script injected some other junk, like an interface of some sort with some text, for instance, the saved page also will. This is probably not what you wanted. It is at the very least certainly not what unsuspecting users of the script wanted.

Edit: a modern GM+Firefox combination gets to run at XHTML pages. (This has not always been the case. Thanks for the correction, Rod McGuire!)

But please do decorate your scripts with the above line. It's royalty and patent free software with an irrevocable, DRM free license for all time. Public domain, at its best, working for you. Cheers!

2007-04-25

Make low-tech people publishers with EditGrid

In the real world, I regularly sing (tenor) in my local choir. Choirs have some boring administrative burdens, like keeping track of what sheet music is being sung now, and what should be returned to the choir library. In our choir, it's manual labour handled by each member and coordinated by a clerk we elect every season.

Anyway, that person is typically more neat than technical. I crafted some help tooling for her (as administrator) that gives her a minimum-maintenance publishing system, to show us, right on our internal home page, what sheets we should have and what to return. She does not need to handle messy web tech, our web page needed no server side hacks, and all she does is edit what looks and feels like her old Excel document she used to keep our sheet music in, but at EditGrid:


I added another sheet for her, stating the out/in dates (to the precision she wants) and ids of the songs we sing (for her own reference, she adds some additional; names and composers, typically):


This EditGrid spreadsheet is open for public browsing. Firefox+Firebug users beware: unless you turn off Firebug for that domain, on visiting an EditGrid spreadsheet, your whole Firefox session (all tabs of all open windows) will freeze beyond salvation (due to issues with Firebug's XmlHttpRequest monitor, if I remember correctly). To avoid that issue, first go to the front page and right-click the Firebug icon, selecting "Disable Firebug for www.editgrid.com".

Then it's safe proceeding to the spreadsheet itself. The administrator of course has an account with edit rights to the data; you will only be able to browse it.

As mentioned in a previous post, EditGrid can export data in mostly any format you want, including JSON, if not out of the box yet (EditGrid devs: even if you don't support native JSONP yet, it would be helpful if you let users share their xsl transforms, so it gets easier to copy recipies such as this one). As I already had set up my account with a nice JSON data format exporter, I opted to reuse that (with the future option to make an Exhibit interface for the data set of what we sung when and the like, without any fuss).

With my data format (Exhibit JSON, actually), the file looks a little like this:

editgridCallback({"items":[
{"type":"Noter","löpnr":"M01","titel":"Beati sunt",...},
{"type":"Noter","löpnr":"M02","titel":"Partitur, Mariamusik",...},
...
{"type":"Ut/In","ut":"2006-","löpnr":"M63",...},
{"type":"Ut/In","ut":"2006-","titel":"Dobos",...},
{"type":"Ut/In","ut":"2006-","titel":"Östgötasången",...},
{"type":"Ut/In","ut":"2007-","titel":"Sånger från Taizé",...},
{"type":"Ut/In","ut":"2005-","titel":"Himlen & jorden sjuder",...},
{"type":"Ut/In","ut":"2006-","löpnr":"M90",...},
{"type":"Ut/In","ut":"2007-03-29","löpnr":"M09",...},
{"type":"Ut/In","in":"2007-04-19","löpnr":"M53",...},
...
]})

Then I wrote up some javascript for our web page that imports the data, listing works we should have and should return, depending on whether today's date is in the given date range or not. Notes past their due back date show up in the latter list, and notes that have not yet been handed out to us are not listed at all. There are some extra features for listing notes without any dates at all (meaning "you should have them, but I don't remember since how long back") and so on.

The result doesn't look much, it but does the job very nicely. See the source code, liberated of blog template cruft separately. (The bit at the end adding a timestamp to the URL is needed to prevent your browser from over-caching the data; EditGrid does not yet seem to send proper HTTP headers about content modification.)

...What we're singing now? See for yourselves (second list folded by default, to conserve space):