The Browser.Next List

Thanks to the Ajaxian’s for linking my last post on the topic of what we need from IE. As I’ve been responding to the comments, it occured to me that it’s not quite fair to poke IE in the eye when there are issues (like WYSIWYG) where we need the help of all the browser vendors to get something useful done. That in mind, here’s my generic Browser.Next list of 10 issues that would give Ajax libraries a break and let app authors worry less.

It should be noted, first, that these issues are designed to be small, (relatively) easily implemented point solutions to accute problems. They are intentionally not on the scale of “add a new tag for…” some feature or “standardize and implement XBL” or even “make renderers pluggable”. While those would all be good, the current pace of browser progress makes me think they’re beyond the pale.

This list also tries to avoid vendor-specific issues (of which there are a pile, and many of them may be much more pressing on a per-browser basis than the below issues). Lastly, I’m also not asking for standardization of these things in short order (although it’s clearly preferable). We DHTML hackers are hearty folk. We’ll take whatever they give us, but we could deliver much, much better developer and end-user experiences if only the browser vendors would all give us:

  • Event Opacity: we need a way to tell browsers that for some nodes in the z-index stack that events should be passed through to their background. For instance, when implementing drag-and-drop, Ajax libraries have a stark choice: attempt to calculate the locations of all drop targets to enable dragging of the source with offset (expensive hitbox calculations, ahoy!) or move the drag shadow with an offset from the cursor (efficient and what we do in 0.9, but visually unsatisfying). Yes, yes, there are WHATWG specs for drag-and-drop and various browser vendors have implemented them to some extent for some time, but what I’m asking for here is much more constrained: a single API extension that can help us deliver better experiences until all the browsers get DnD right. There are also lots of other use cases where visual decorations should be able to defer their events to underlying elements (think drop shadows, etc.)
  • Long-Lived Connections: this was on my IE7 list, but it’s still a problem nearly everywhere. The basic issue is that we can’t implement Comet reliably because if two tabs both keep a long-lived connection to the same server, no other connections can open up to that server, meaning that normal Ajax (and even style changes) will be blocked. Very often this means that an app will appear to be locked up. One solution is to provide a way to specify in an HTTP header that a connection will be long lived or to provide pages a way to request more concurrent connections be made available to a particular server (on a per-tab basis, and with a hard limit, of course). If feasible, it might just suffice to just break the global lock connection limits and make them per-tab in general. Whatever the solution, we need ways to be able to have multiple tabs each able to create Comet connections without worrying.
  • Expose [DontEnum] To Library Authors: The contortions that Ajax toolkit vendors go through to keep iteration over JavaScript objects and primitives coherent is, quite simply, insane. Much of Dojo, in particular, is designed around this problem. Giving us a way to say that a property is [DontEnum], before ES4 lands, would go a long way toward alleviating this back pressure.
  • Fast LiveCollection -> Array Transforms: That many DOM apis return live collections is a bug, but it need not be fatal. Browser vendors could start to provide a simple toArray() method on these live collections to provide a way to “fix” them in place.
  • Provided A Blessed Cache For Ajax Libraries: Long story short, Ajax libraries are going to be here for a while. The idea that a browser is going to be so good that it will remove the need for a JS library simply doesn’t hold water any more, and even if one browser was that good, the other browsers wouldn’t be and none of them would be pervasive enough given current upgrade trends. We need to be able to better support our own patches to the browsing platform, and we need the browser vendors to get on board and realize that Ajax toolkits aren’t a threat. We can’t be…we don’t have enough leverage. With all of that being true, it’s high time for the browser vendors to provide Ajax toolkit vendors a way to specify a canonical URL or hash scheme which would bypass the network entirely, cross-site. This is something of an extension to the CDN concept for Ajax toolkits, but would go a long way to fundamentally changing the way Ajax toolkits evolve. Instead of fretting about how much 10K on the wire is going to degrade the user experience, we can focus on delivering better and better tool sets, even behind the firewall or offline (where CDN usage isn’t feasible).

    Obviously, this one is going to require some vendor coordination, but it’s the kind of thing where if one vendor does it (well), everyone else should follow quickly without much risk. The Open Ajax Alliance could even function as a body to provide a list of toolkits and hashes to browser vendors should they demure from the task themselves. Lastly, before the flames start rolling in on this topic, I should note that I’m proposing this with some hesitation. Who are we (the Ajax toolkits) to suggest that our content deserves a more “blessed” cache position than site content? I’ve been wrestling with this for a long time, but now believe that we don’t have much of a choice. This solution is good for everyone and while it has the potential to create an uneven playing filed, I think that can be handled at an organizational level.
  • Mutation Events: The browsers already know when a new item is added to a DOM, why can’t they tell us, the poor toolkit/framework authors? I’m not going to suggest in this list that browser vendors should fully figure out HTML tag subclassing since it will generally require architecture changes for the least capable browsers (*cough* IE *cough*). Instead, point solutions like mutation events everywhere will go a long way to allowing us to further band-aid their brokenness and allow us to more seamlessly upgrade content while we wait for the new-tag cavalry to arrive.
  • onLayoutComplete: onDomReady doesn’t cut it. Toolkits that want to avoid FOUC when applying behaviors and progressive enhancement to pages are currently attempting to get into the page rendering stream as early as possible. The problem is that for anything that needs to manage layout of widgets on the page, we need to know the dimensions, and that also must mean that CSS has been applied and any initial flow computations have been completed. Obviously, there are issues with progressive rendering of a page, but generally speaking I beleive toolkits are looking to browser vendors for a semantic that is roughly equivalent to “after onDomReady, but potentially before all images have finished loading, inform us when the layout and geometry have stabilized.”
  • HttpOnly cookies: There’s a lot wrong with WebAppSec these days, and the traditional trust boundaries are constantly under attack. Worse, none of the browser vendors seem to feel it’s their responsibility to figure out cross-domain or JS sandboxing. This infuriating state of affairs leads directly to my next item, but the minimum any browser vendor should be required to do is to implement HttpOnly cookies. It’s no silver bullet, but it’s another tool in the toolbox and one we need badly.
  • Bundle Gears: Until it’s primary APIs are put through the standardization process and introduced in browsers natively, any browser that includes Flash support should, out of good-faith respect for the Open Source and Open Web nature of its intent, bundle Google Gears as soon as it’s stable. A commitment to do so in the future will suffice until that time.
  • Standardize on the Firebug API’s: Firebug provides great debugging and performance profiling APIs. These need to be built in so that we can stop shipping Firebug Lite around the net ad-infinitum (as we do in Dojo 0.9). Being able to have built in timing tic/tock apis and a UI to view it would be a hugely useful. This falls far short of other proposals that have been floated for unified debugging APIs and protocols, but again represents the least vendors can do to alleviate the pain.

So that’s my list…what’s on yours? What am I forgetting? And how should we organize to ask the vendors for these in a way that will really stick?


  1. Posted September 12, 2007 at 6:28 pm | Permalink

    From the top of my head:

    XPath that works on documents created on the fly from strings as well as remotely fetched documents and the HTML DOM.
    An API that gives reliable absolute coordinates of any element relative to the upper-left corner of the document without all the current browser-specific madness.
    CSS selection APIs (those are in the process of being standardized and vendors are apparently busy implementing them).
    A reliable load event on script tags (ok, this one is really browser-specific and it’s going to be fixed).

  2. Posted September 12, 2007 at 8:20 pm | Permalink

    Hey Bertrand:

    Those are great! I was thinking of fast positioning APIs at one point but somehow got through 10 things without mentioning them.

    The lack of any such thing reliably causes no end of pain.Also, the XPath over the HTML DOM is also browser specific. Any chance it’ll be fixed? ;-)


  3. Posted September 13, 2007 at 3:11 am | Permalink

     Event OpacityThere is a third way, promotied by Peter Michaux.  You create 4 separate shadows of the drag element, and arrange them around the mouse so as to leave a little box under the mouse.   Works very well.Keyboard Events and FormsMy other wish (albeit perhaps not good for accessibility) is that browsers were more consistent with their handling of keyboard events, and in particularly the ability to override the TAB KEY and ARROW KEYS.  Internet Explorer is the best.  Opera stubbornly refuses to let me preventDefault() or return false for tab keys and arrow keys on form elements.

  4. Neil Roberts
    Posted September 13, 2007 at 6:45 am | Permalink

    Events for back/forward button handling (along with preventDefault). The ability to change the hash of the page without disrupting the page.

  5. Posted September 13, 2007 at 10:15 am | Permalink

     Alex, you’re more right than you think abou tit being browser specific ;) I’ll ask someone over at IE about XPath over the DOM, and you ask Firefox about XPath over a dynamically created document (or you tell me how to do it without hacking the HTML DOM :) ). I don’t know where Safari 3 stands with that but v2 had nothing. You know, maybe we should talk about that at the OpenAjax Interop meetings and try to coordinate some of that list and the dialog with vendors. We would probably have more weight this way.Cheers!

  6. Posted September 13, 2007 at 11:18 am | Permalink

    Re: Fast live collection -> Array transformsThere’s already a spec for this, too–the JavaScript 1.6 Array generic slice function works perfectly.  I use it all the time in Greasemonkey scripts, as it has been implemented in Firefox for some time. (Aside: I was unable to submit this comment in Firefox–the error message was "please type a comment."  When I tried in Opera this page would flash up, rendered, and then go back to a blank white screen.  I had to fire up IE7 to post this comment.  Also, it should be possible to tab to this editor.  And to link text.)

  7. Posted September 14, 2007 at 9:03 am | Permalink

    Great post! I can see how a few of those would be really beneficial.

    I think your blessed cache is interesting, but there is something I’d rather see: Site/Session persistent compiled JavaScript objects.

    We spend a lot of time optimizing the file size for our libraries; as the guys at Plexo discovered, compile time grows non-linearly with file size (complexity, minification won’t help much). It would be nice there was a way that we could store some collection of objects in such a way that they were accessible for every page load. That way we don’t have to spend processor time rebuilding our TreeViewWidget prototype every time the page loads.

    An @import for JavaScript would be great too, rather than always document.writing script tags.

  8. Rob Koberg
    Posted September 14, 2007 at 1:29 pm | Permalink

    Alex, I know you don’t care too much about this, but I would like to see browsers with XSL capabilities allow the javascript protocol in the XSL document function. For example, document(javascript:makeXmlFromJson())/*

  9. Posted September 14, 2007 at 4:20 pm | Permalink

    Here’s your toArray() for live nodeLists:

    var staticNodeList = [], 0);

  10. Posted September 15, 2007 at 9:53 pm | Permalink

    Fast LiveCollection -> Array Transforms:
    You mean Array generics in ES3?

    A prime example is Tino’s (nice work!)

    Tino, your example works in Firefox, Safari 2, and Opera 9.

    Unfortunately, browsers are not required to support Array generics on a Host object. NodeList is a host object. Considering that

    Microsoft has dragged their feet every step of the way, it’s no surprise that Array Generics don’t work with JScript.

    What’s on my list? Well, since you asked…

    Form Serialization in HTML 5

    URI in ES4

    Data Structures in ES4
    (haven’t started on this yet)

    Date Formatter in ES4
    (haven’t started on this yet)

    Fix for IE:
    replace(JScript, Tamarin);

    Regarding DontEnum, that’s an article I’m working on now.

  11. Posted September 21, 2007 at 12:14 pm | Permalink

    Nikhil Kothari’s list:

2 Trackbacks

  1. […] Alex Russell (of Dojo fame) has an good post up right now called Browser.Next in which he lists 10 key things browsers need to give us poor developers so we can do our jobs without going insane. Here’s the list, but head to his blog to read the details: […]

  2. By DHTML Kitchen News on October 21, 2007 at 4:46 pm

    Iteration, Enumeration, Primitives, and Objects

    function assertEquals( baseId ) {
    var src = document.getElementById( baseId + “-source” );
    var actual = String(eval( src.textContent || src.innerText ));
    var expectedEl = document.getElementById( baseId + “-expected” );
    var expected = exp…