Joel, This is definitely a can of worms! I spent some time thinking through the some of these points. Some additional comments inline...
On 17-Aug-09, at 10:02 AM, Joel Webber wrote: > > At any rate, we *do* need something like this, and now seems as good > a time as any to bring it up. In fact, there are several such > classes that need to be moved out of gwt.user.client into a more > sensible place (and others that still need to be written). What they > have in common is that they have nothing to do with widgets, but are > not "core" because they assume the existence of a real web browser > (as opposed to other potential Javascript targets such as Flash). > The ones that come to mind are: > Existing: > - Window > - Location > - Cookies (though maybe Document just needs its cookie property > implemented) > - Timer (this is implemented on top of Window.set[Interval Timeout]()) > - History (there are both the native "history" object, and the GWT > history implementation to consider) > - [Incremental Deferred]Command (Smells like core, but requires > Timer to work) One consideration this raises is that some have internal state associated with them. For instance, both the Cookies class and Location classes have precomputed maps of data. How can you ensure that a service is a singleton for a given native object (or is it best to provide this for the default window and document only)? There's also the issue with cleaning up objects when documents/windows are unloaded, since the lifetime of the GWT module may be significantly longer than the windows it references. I suppose the cleanup could be handled via some global per-window unload cleanup queue attached to a specific window's unload handler. Additionally, how can you handle multiple GWT modules that may reference the same native window or document? History and location may be useful to expose as simple JSO wrappers over the native browser's objects. The full GWT history implementation would probably be less useful on a window that didn't contain a GWT module (esp. considering that newItem() is so different on every browser). For Timer and IncrementalCommand, I suspect there wouldn't be much lost if they were left as global services. The only advantage to having per-window timers that I can think of right now would be scoping the lifetime of the timer to the window itself (is this even consistent across browsers?). I think it might be sufficient to create a rebind point for creating timers for different environments. FWIW, this is the code we use to simulate Timer when running as a Firefox extension. It would be a lot cleaner as a timer rebind and I imagine that AIR and other JS-but-not-HTML environments would be very similar: window.setTimeout = function(callback, timeout) { var timer = Components.classes["@mozilla.org/timer; 1"].createInstance(Components.interfaces.nsITimer); var handle = {timer: timer, active: 1, callback: callback}; var doNotify = function() { manag...@com.dotspots.mozilla.extensionmanager::activeOneShotTimers--; delete handle.active; delete handle.callback; delete handle.timer; manag...@com.dotspots.mozilla.extensionmanager::safeCallback(Lcom/ google/gwt/core/client/JavaScriptObject;)(callback); } timer.initWithCallback({notify: doNotify}, timeout, Components.interfaces.nsITimer.TYPE_ONE_SHOT); manag...@com.dotspots.mozilla.extensionmanager::activeOneShotTimers++; timers.push(handle); return timers.length - 1; } > New: > - Selection (this is pretty tricky, because selection on IE is so > amazingly weird) > - Others? Selection would be very useful, even if it was limited to some simple operations at first (exists, get text, delete, replace). The W3C selection API is very useful, but I'm not sure if there's a compelling use case outside of Google Wave to merit the effort required (I had experimented with this a while back, but it's difficult to get consistent results between webkit/gecko, let alone with IE in the picture :)!). There's a few miscellaneous DOM services that would be useful, such as the DOM tree walking service and xpath functions. Neither of those is complex enough to be consequential, so they probably wouldn't factor into any design. > > The main hold up for me has been figuring out how to move the > existing classes to a more sensible module, and precisely what that > module is. Selection and Window could arguably be considered par of > DOM (WebKit has a DOMWindow class, even though the W3C doesn't > consider it part of the DOM per se). It is not immediately obvious > to me where the others should live, though -- should we have a > Browser module, for example? I think that window itself is a de-facto part of the DOM. There are a few cases where a developer may have access to a "headless" document (ActiveXObject('htmlfile') for one), but those are fairly rare and advanced enough that anyone using it would be aware of the limitations. All the major browsers have some sort of DOM-like object representing it (Mozilla's nsIDOMWindow* and IE's IHTMLWindow*). > > Then there's the question of how to move them in a sensibly > backwards-compatible manner. With the DOM module's Element class, I > kept the names the same, because they have to be typed so often. I'm > still not 100% certain that was the best approach, but I guess it's > worked ok. How weird would everyone find it if Window, Cookies, > Timer, History, and DeferredCommand all showed up in two places, > with the originals eventually deprecated? It makes me a little > nervous, to be honest, but so does trying to come up with new names > for all of them and confusing matters further. Our experience was pretty positive with the com.google.gwt.user.client.Element -> com.google.gwt.dom.client.Element mapping. Most of it was handled with a search and replace to fix up import statements. Assuming the function interface doesn't change dramatically (more like the element mapping than the event overhaul), it wouldn't be much of an issue, IMO. Best, Matt. --~--~---------~--~----~------------~-------~--~----~ http://groups.google.com/group/Google-Web-Toolkit-Contributors -~----------~----~----~----~------~----~------~--~---