Webby thoughts, most about around interesting applications of ecmascript in relation to other open web standards. I live in Mountain View, California, and spend some of my spare time co-maintaining Greasemonkey together with Anthony Lieuallen.

2008-12-11

I attended Add-on-con's open house meetup at Mozilla headquarters here in Mountain View earlier tonight, airing a wish list item of mine in the trailing discussion about what we want from Firefox, after some talks about what's coming up next, and where Mozilla want to go at the moment. It was a good session meeting friends and new acquaintances, and I even recognized a few faces from Mashup Camp a few weeks ago. Being the season for wishlists, I thought I'd sum up some of mine, on a more interesting scope than those we might share with our friends and family about items, activities and whatnot. Anything goes, high and low -- I even mention the point I brought up earlier during the evening.

This is a rather scattered list of stuff I want, and would find most incredibly practical, useful, powerful extensions of will, mind and capability. Consider it food for thought, if you will, or inspiration to wild, liberating, wonderful hackery, or even for being my Santa this year. If neither, please post your own, to your own blog. I've tagged mine "tech_wishlist" on Del.icio.us, and encourage you to do the same (both tagging your own post with it, and any other person's post that contains items that you want, too). That's a powerful way of connecting brains, folks, sharing and taking inspiration and cooperation to pretty wild levels. We owe it to ourselves and humanity to make the most of the tools and ideas we generate and adopt, and one very important aspect of that is sharing them.

(This also includes music and other media, by the way, but those industries are too busy not understanding how to monetize it right, and doing all they can to tie us up in pre-wired ages where distribution and marketing cost money, to notice. But I digress.)

I want file system access to the web

File systems are often conceived of a way of organizing information on disk, when the important part of them really is a way of accessing information. You'd be surprised how powerful an augmentation tool file systems are, and how easy it is today to write one today, as compared to the old bad days, now that we have great things like FUSE or MacFUSE. File systems let us reach data and resources in a heavily standardized fashion using all the computing tools there is, whether made for the web, desktop, or any other conceivable environment. The entire web is a walled garden not available to all the tooling there is. We should do something about this.

I want XPath file system access to nodes in XML and HTML documents

File system paths don't have to have any posix semantics built into them by any necessity; they are identifiers that discern data storage location, or reference particular information, if you will. The file system is as little bound to following specific conventions about what a path means as a web server is forced to pick any particular semantics to how it interprets path and query segments of its URLs. In practice, this means that a file system path can very well contain an XPath expression digging out information of a web document, serving a smaller document than accessing the document itself would, after filtering out all the junk you were not interested in. Similarly, a file system path can contain SQL queries or poke search words into google. Doing these kinds of operations has historically locked you into particular tool chains, programming languages/environments and whatnot, for no good reason. Computers are here to liberate and augment our will, not force it into constraining walled gardens.

I want file system access to my running browser session

If you've become dependent on and enamoured with any kind of interactive command line / read-eval-print-loop environment like Firebug, favourite programming language and/or the unix shell, and do any kind of Firefox extension development, chances are you've encountered or would benefit from acquainting MozRepl, formerly part of the MozLab extension, which lets you telnet into your running Firefox session (I hear it works in most of the other stuff based the Mozilla toolkit too, but haven't tried myself). This lets you play around in chrome space as you would in the sandboxed content space with Firebug via a simple telnet session, or indeed right from inside of Emacs, if that's your fancy.

Well, I think browsers have been divorced from the unix and the rest of the tool chain for too long, and I want to operate on and work with the files I have in my brower session without any silly fuss about having me store dead documents on disk, picking a location for them, directing my tool of choice to it, and losing all the benefits of live computing and convenience of access that entails in one blow. The web is mine, and I want to interact with it in my fashion, whichever that might be at the time. I like some aspects of accessing it through the glossy chrome that is Firefox, or Google Chrome, or even the iPhone, but I don't want to be walled in there either, and getting file system access to my live session's tabs and documents means getting access to a specific view pointed at me with the cookies and other me-centric data that some random tool like wget wouldn't see without a lot of laboursome work.

And it would let me into the same walled garden that my current web browser session has already opened the doors to, when I first logged in to whichever site I am on, to do whatever I do there; socializing, shopping, blogging, banking, researching, mailing, playing, working, or whatnot. Cd:ing from window to window, tab to tab, and reaching the documents, images, audio, video and linked documents other referenced from there to do whatever my bidding. Scores of operations you wouldn't even come to think of as possible become downright simple, and useful, in an environment like this. Again, it breaks down silly walls that block our view and perception today.

I'll wager our kids and grandchildren will find the web and computing environments of the early century very backwards indeed, scoffing at the insane amounts of effort spent theming, skinning and reshaping all the walls we locked ourselves up behind, with stuff that did not evolve together as an ecosystem, but separated, and screened off from one another in different dimensions pasted together only very lightly via human-bound I/O, and the monitor/speaker-mouse-keyboard read-eval-print loop. Silly, really. But I guess we really like these walls. It's so easy thinking inside the boxes we grew up with.

Neither of these ideas are new, by the way; there have been wonderful pearls like Plan 9 in the past, but they were, you guessed it, walled away from the other stuff that was evolving at the time, and died out in niches few humans ever colonized and made their own. It's not enough making the best stuff humanity has ever seen, if humanity never sees it, for anyone but yourself, and your legacy and contribution back to the world is measured by how you both execute it, evangelize and show and tell it to others so that they, too, can benefit from it and keep evolving it, adapt and repurpose it, bring it across other walls you didn't care to cross, came up with the idea to, or even figured possible. Note also, how they tend to be orthogonal to one another, and how well they stack up when combined together again, building atop one another.

Combine with all the tooling you had which was previously prevented from being part of the ecosystem, and not even the sky is your limit. Which begs my next item:

I want file system accessible cloud storage

This already exists, but not for long enough to have been commoditized yet, the way web mail is; Amazon S3, for instance, can already be combined with S3FS (free, besides applicable S3 fees) and FUSE or MacFUSE, or SubCloud (expensive enterprise software).

I want browser standardized access to commodity cloud storage

In our walled-in browser reality of today, it would already be a big win having a user provided bucket in the sky to tie browser data to, rather than sticking the goo on local disk, and figuring out complex syncing schemes to connect one computer's local disk data with another one's. Just access the web with any device and have them all phone home to your bucket in the sky to pick up the you bound data.

Note that it should be your bucket, which you handle with ease and can transfer to some other bucket cupboard provider, should you for some reason want to; we want to avoid lock-in. Even though I kind of like the shape and sound you get from Amazon's buckets. Everybody won't. Heck, Google might give you a free bucket, some day, or at least charge you fewer bucks. Or maybe Mozilla would find some way of remaining a nonprofit by routing bucks their search engine integration, or a Mozilla held app store or market for extensions would give them, from your usage of said search engines, or a percentage of the profits of commercial apps sold through such an entity -- into the payment of your Mozilla sponsored bucket, for browsing with Firefox, when browsing the web through their particular chrome.

Which reminds me I promised to share my tech-wishlist item from earlier tonight:

I want Firefox to remember the URLs it installed extensions from

That way, us extension authors (I speak as one of the maintainers and developers of Greasemonkey and MashLogic alike) can pick up configuration data passed in, for instance, the query and/or fragment parts of that URL.

This is primarily useful for improving and streamlining a most seamless installation experience for users, so that -- in the case of Greasemonkey for instance -- a user script link, when clicked by a user that has Greasemonkey installed, installs the script, and when clicked by a user not having Greasemonkey installed, prompts with the Greasemonkey extension installation sequence, which installs Greasemonkey, which then proceeds to install the script.

Via the same link, which points to the Greasemonkey xpi parametrized with the URL for the user script to install. The same kind of streamlining and on-web-sharing of initial configuration data applies very much to other extensions too, perhaps particularly so commercial grade extensions where business models benefit from shaving down the install and setup threshold for users as much as conceivably possible, and what better way to do it than to allow the prospective user to do it on the familiar web rather than to mandate doing it within some walled-in confines of a XUL garden?

I know; I wouldn't want to have to do it on the web, but that's a familiar setting for web users, and it allows people to help one another on the web with doing actual configuration presets, rather than describing in words and pictures how to do manual labour in often contrived and messy user interfaces, which makes non-expert users feel it is way too difficult and well beyond their understanding. But clicking an install link after reading a TechCrunch or LifeHacker post about a specific use case and setup for it, shared in same post, is available to everybody. This is the kind of direction at least we at MashLogic want the web to take, but it's presently awful messy doing that kind of thing. (Not that we'll let that discourage us, but it's an unnecessary shortcoming of the platform forcing you to bring your own duct tape to do it.)

A few of these ideas probably constitute quantum leaps in computing, if or when pulled out of idea space and reshaped as implemented functionality, given more detailed shape and form, convention, and figuring out idealized notions of how to come across the many mismatched and yet unmet problems that will come along the way, as we evolve the tools of the past into the tools of the future (what we always do as wizards and programmers, somewhat romanticized, and sometimes with more or less merit than otherwise). Figuring out ideal solutions is not important upfront; getting started and making incremental improvement over the present is. Doing even a subset of even one or a few of these will enable us to do many things previously much more difficult or undoable, and you, and/or others can keep polishing it up later. That's some of what open source and publication does best.

2008-12-06

I've wanted to do this kind of hack for ages, since social software became commonplace on the web. Being both very bad at geography (even worse so, US geography, having moved here only just recently), and rather well versed with mucking about with other web developers' user interfaces, I finally took to it yesterday night (I've admittedly done a similar Greasemonkey hack for Facebook at some time, but it wasn't nearly as fun, and has most likely rotted since then, anyway).

The idea is basic: you tend to see location names (cities, addresses and the like) associated with users or events strewn out all over the place. Those don't tell me a whole lot unless I've been there, live near them, or similar. Maps do, though -- at least if I have some reference point I know to relate them to. For a site like OkCupid which is all about getting to know people (or yourself, but that's a different story), the natural point is of course home. And these days, Google Maps offers some really nifty geocoding and travel directions APIs. Add some Greasemonkey magic to the mix, and voilà -- a context sensitive map section which shows you where people are, in relation to yourself, as you hover a location name. It's quite snappy, and completely effortless from the user's point of view; no typing, clicking, dragging or otherwise involved:

This really is my favourite kind of interface: it doesn't have a learning curve, takes no clicking about, and has intuitive discovery properties; hover a place, and the same place shows up, name and all, in the map view.

It can of course use some additional polish like drag-a-corner-to-resize, a get-out-of-my-face icon to turn it off and the like, but suddenly it's a whole little software project rather than a one-nighter. That said, I think I like it well enough to want it across the entire web. Add those, a little toolbar to drag it around with and whip up geo and adr micro formats detection for it, and all of a sudden it's a neat all-round tool.

To finish off, closing the circle of the original OkCupid hack, replace that one with one that just sweeps OkCupids pages and converts its place name HTML to the adr micro format -- and the two tools snap together forming a stigmergy of cooperating Greasemonkey scripts. (It's a development pattern I really enjoy, for the unanticipated emergent bonus effects it tends to bring.)

Anyway, I thought I'd shine some light in the rest of the post on how I put it together, as it's painful doing things with Google Maps from Greasemonkey (can't inject the Maps API comfily, as its loader mucks about with document.write, which only works as intended for inline script tags, as opposed to dynamically injected code), and since my technique is rather easy to borrow.

The map area and geocoding is all done in a little iframe I load from here, starting it off with some URL encoded query parameters like at=Mountain View, California, United States (to center the initial map and put a little blob there), country=United States (which helps the geocoder, IIRC), nav=2 (if we want a medium-size zoom/pan control) and z=9 for a useful default zoom level. (The latter adapts to an appropriate scale when we ask for routes.) It will fill the whole page, or iframe, so we don't need to state any pixel dimensions.

So how do we tell it to look up places for us? This is where it's getting fun. Using window.postMessage on the iframe's window object, we send the geocoder its instructions, and using window.addEventListener("message", listener, false), we listen to whatever it figures out for us (Firefox 3+, and other modern web browsers).

For convenience, I went for a rather minimal messaging API; send it a newline-separated list of locations, optionally preceded by a "focus" (to move the view and blob there) or "route" line (to try drawing a route between the first and last address). All places in the list get geocoded, and the return value passed is a JSON structure {"coords":{"place name":[long, lat], "other place name":[long, lat], ...}, "took":t, "type":"geocode"} where t is the lookup time in milliseconds. Route requests are in addition populated with "distance" and "time" properties, either containing a "html" property (for a human readable form), and a "meters" or "seconds" property respectively.

And that's really all you need to use it.

Wanting it somewhat speedy (as the iframe only has page longevity, and thus won't learn and retain address to lat/long mappings over time), I opted to add a little local cache of places already looked up in the past with globalStorage (Firefox 2+, non-standard). Quick and dirty, but functional, it puts places in a little JSON tree indexed on country, region, city, and so on, however deeply the hierarchy goes. As OkCupid's place names are all on a tidy machine-readable comma-separated list format with consistent capitalization this is a rather small representation; place names in the wild might find it less useful, if still not worthless. As your web browser's IP might get blocked from using the Google Maps geocoder if you use it too recklessly (>15,000 requests per day -- but still), the persistence might be good to have there, just in case.

As usual, feel free to adopt, embrace, extend and hack about madly with it; code wants love too. The full source (and script, docs, et cetera) of the Greasemonkey script is on userscripts.org, and the Google Maps part is linked above. Happy hacking!