- From: David Bruant <bruant.d@gmail.com>
- Date: Mon, 29 Apr 2013 14:44:59 +0200
- To: Glenn Maynard <glenn@zewt.org>
- Cc: WHATWG <whatwg@whatwg.org>, Robert O'Callahan <robert@ocallahan.org>
Le 29/04/2013 01:08, Glenn Maynard a écrit : > On Sun, Apr 28, 2013 at 5:39 PM, David Bruant <bruant.d@gmail.com > <mailto:bruant.d@gmail.com>> wrote: > > Le 29/04/2013 00:14, Robert O'Callahan a écrit : > > We don't want to require people to do everything in Caja just > to support composition of independent scripts. > > There are certainly more lightweight solutions than Caja to > achieve the same thing. > > > Which is exactly the problem: you're saying there are multiple > solutions, which means incompatibility. No, I meant "more lightweight solutions than Caja to achieve the same thing" (sorry for the copy/paste, I don't know how to phrase it better), so solutions that confine a widget in a div giving it the impression it's on its own full page, so using all standard APIs. A level of compatibility that's actually hard to match. I'm currently building a product on top of Google Apps Script [1][2]. The pages served on the client side are "cajoled" (processed by a deployed Caja before being sent to the browser) by Google. As a developer, I'm just coding according to standards. No specific APIs for the confined code. I haven't seen any difference besides "requestAnimationFrame" and the "performance" object being missing, but I believe this is only because they (people of Google App Script who installed and deployed their configured Caja) don't keep up with the latest browser trends and just forgot to whitelist them. My point is that Caja offer confinement and the confined code has been coded to standards, so I consider the problem of confining standard-based code solved. Really, take a look at it. Caja proves that confinment of malicious widgets within the same page is possible (!). I believe a lighter version of Caja aiming at isolating well-behaving widgets would be much lighter. Hopefully it wouldn't require the whole server-side live rewriting infrastructure (which is definitely something that shouldn't be required to run independent scripts, I can only agree). Maybe assuming widgets give up a little bit on how dynamic their JavaScript can be (maybe not even). I'm no Caja expert, but this light-Caja might be as simple as picking a few Caja libraries and wiring them a bit differently. I'll ask the Caja mailing-list. What about starting with an API à la html@loading and if devs complain it's too hard when there are independent scripts, then add a mechanism like delayLoadEvent/stopDelayingLoadEvent? (I still believe delaying the UA load event is a terrible idea. What will dev tools show? The actual load event or the delayed one? And the argument about performanceTiming, etc.). The more complex multi-call API can be later retrofitted, but please wait for devs to ask for it. Also, independent scripts loading on a page increase the probably of at least one failing. document.delayLoadEvent(); doX(function(){ doY(); document.stopDelayingLoadEvent(); }) First and foremost, let's hope the script that defines doY from your automated build process didn't end up in a SyntaxError or you'll be told soon enough that "undefined is not a function" Then maybe doY calls JSON.parse to get info from your localStorage or from the network. Too bad, you're parsing "[Object object]" because your colleague wrote localStorage.set('key', obj) instead of localStorage.set('key', JSON.stringify(obj)) doY throws, document.stopDelayingLoadEvent never gets called. Maybe doY contains a call to JSON.stringify. Few people know but this one can throw too if passed an object with a cycle. Oops, document.stopDelayingLoadEvent never gets called. And hundreds of ECMAScript/Web APIs Recently, I was working on a WebDocumentary project with lots of <video>. All was working fine on FF and Chrome. When testing on iPad, some calls to video.play were throwing INVALID_STATE_ERR for no apparent reason. Not even reliably. Maybe something due to loading speed. Maybe QuickTime was in a bad mood (apparently, on iPad, the <video> elements is an embedded QuickTime). Who knows? Anyway, if doY does this kind of things, it will throw in some platforms and document.stopDelayingLoadEvent never gets called. There are thousands of ways a you can screw up or one browser can let you down and one of your independent widget ends up not calling document.stopDelayingLoadEvent. As I explain below, when that happens, you cannot react at runtime. > > If your scripts are that independent, how do you know if one > forgets to call document.stopDelayingLoadEvent()? This is a footgun. > > > The approach I've suggested makes tracking misuse easy; just stash a > stack trace when creating the object, and provide a console API to > print the stack trace for delays that haven't been finished, or if an > object gets collected without being finished. That's a way to debug, not to react at runtime. If one of your independent script forgets to call document.stopDelayingLoadEvent(), how does the page recover to guarantee that the "load" event will happen eventually anyway? Code isn't always maintained. Even maintained code isn't even tested on all platforms it will run on. How does one guarantee a load event to be triggered eventually when scripts are independent? Lots of scripts are written with the assumption that the load event will be called. You're breaking them if document.stopDelayingLoadEvent() is not called enough (one more reason to leave the UA "load" event as it is) Also, does delaying the "load" of an iframe delays the parent? If yes, one more reason not to delay the UA "load" and leave it working as it does today. > > This is also additional surface for web browsers to mess up which > they already have enough to deal with. > > > The proposal here is trivial as web APIs go, so I don't buy this. As a web developer, I can totally imagine a web browser forgetting to fire "load" because of weird internal conditions like "one document.delayLoadEvent call was before DOMContentLoaded and another after". Browsers fail us like this *all the time* and this kind of feature is very subtle, make very hard to write test cases to reproduce reliably when there is a bug. Allowing several delayLoadEvent/stopDelayingLoadEvent (by opposition to one HTML attribute and Mutation events which are *already* in the specs and browsers) will require more spec, more spec tests, more implementation, more implementation tests. I'm not saying the feature is complicated, just that it's more complication that just an attribute and the value remain to be demonstrated. What level of testing do you think browsers will provide? I can tell in advance that few browsers (none?) will test for conditions like "one document.delayLoadEvent call was before DOMContentLoaded and another after" and that's where you're in trouble. Removing an attribute? Mutation events? Already in browsers, already used, already tested. That works. That's much less work for just everyone. > Give one way to signal that the application is ready. Devs will > figure out the rest. One way to signal that the application is > ready will serve at least 80% (maybe 90%) of the needs anyway. > > > I think every proposal so far gives exactly one way to signal, so I > don't know what this means. I didn't mean "one way" in that sense, sorry for the confusion. I meant "send one signal". If "independent scripts" can all contribute to telling when the app is ready, then, there are several signals. > > In this context, trying to support composition of independent > scripts is most likely over-engineering. Will ads care to call > document.delayLoadEvent()? Will social widgets do that? Where is > the concrete need for independent script composition? Are the rare > use cases really worth the additional complexity? > > > If I'm making part of a site use this feature, I want it to be > self-contained within the code that's actually using the feature, not > messing about with document-global attributes. This is equivalent to > why we use addEventListener in modules, rather than event handlers. How are document.delayLoadEvent and document.stopDelayingLoadEvent any less global than an attribute on <html>? That is *exactly* the same amount of globalness. The risks and consequences of bugs and malicious behavior is equivalent for both features. "I want it to be self-contained within the code that's actually using the feature, not messing about with document-global attributes." => The "self-contained" keyword makes me think that you really want Caja or some lighter version of it. David [1] https://developers.google.com/apps-script/overview [2] https://script.google.com/
Received on Monday, 29 April 2013 12:45:34 UTC