- From: Dimitri Glazkov <dglazkov@chromium.org>
- Date: Thu, 30 Jun 2011 14:07:47 -0700
- To: Maciej Stachowiak <mjs@apple.com>
- Cc: public-webapps <public-webapps@w3.org>
On Thu, Jun 30, 2011 at 1:32 PM, Maciej Stachowiak <mjs@apple.com> wrote: > > On Jun 30, 2011, at 1:03 PM, Dimitri Glazkov wrote: > >> Maciej, as promised on #whatwg, here's a more thorough review of your >> proposal. I am in agreement in the first parts of your email, so I am >> going to skip those. >> >>> =3D=3D Are there other limitations created by the lack of encapsulation= ? =3D=3D >>> >>> My understanding is yes, there are some serious limitations: >>> >>> (1) It won't be possible (according to Dmitri) to attach a binding to a= n object that has a native shadow DOM in the implementation (e.g. form cont= rols). That's because there can only be one shadow root, and form controls = have already used it internally and made it private. This seems like a huge= limitation. The ability to attach bindings/components to form elements is = potentially a huge win - authors can use the correct semantic element inste= ad of div soup, but still have the total control over look and feel from a = custom script-based implementation. >>> >>> (2) Attaching more than one binding with this approach is a huge hazard= . You'll either inadvertently blow away the previous, or won't be able to a= ttach more than one, or if your coding is sloppy, may end up mangling both = of them. >>> >>> I think these two limitations are intrinsic to the approach, not incide= ntal. >> >> I would like to frame this problem as "multiple-vs-single shadow tree >> per element". >> >> Encapsulation is achievable with single shadow tree per element by >> removing access via webkitShadow. You can discover whether a tree >> exists (by the fact that an exception is thrown when you attempt to >> set webkitShadow), but that's hardly breaking encapsulation. >> >> The issues you've described above are indeed real -- if you view >> adding new behavior to elements a process of "binding", that is >> something added to existing elements, possibly more than once. If we >> decide that this the correct way to view attaching behavior, we >> definitely need to fix this. >> >> I attempted to articulate a different view here >> http://lists.w3.org/Archives/Public/public-webapps/2011JanMar/0941.html. >> Here, adding new behavior to elements means creating a sub-class of an >> element. This should be a very familiar programming concept, probably >> more understood than the decorator or mixin-like "binding" approach. > > How would your "subclass" idea resolve the two problems above? In the case of extending elements with native shadow DOM, you have to use composition or have something like <inherited>, where you nest native shadow tree in your own. In the case case of attaching multiple bindings -- you just can't. That's the difference between inheritance and mixins :) > >> >> For the key use case of UI widgets, sub-classing is very natural. I >> take a div, and sub-class it into a hovercard >> (http://blog.twitter.com/2010/02/flying-around-with-hovercards.html). >> I rarely bind a hovercard behavior to some random element -- not just >> because I typically don't need to, but also because I expect a certain >> behavior from the base element from which to build on. Binding a >> hovercard to an element that doesn't display its children (like img or >> input) is useless, since I want to append child nodes to display that >> user info. >> >> I could then make superhovercard by extending the hovercard. The >> single shadow DOM tree works perfectly in this case, because you >> either: >> 1) inherit the tree of the subclass and add behavior; >> 2) override it. >> >> In cases where you truly need a decorator, use composition. Once we >> have the basics going, we may contemplate concepts like <inherited> >> (http://dev.w3.org/2006/xbl2/#the-inherited-element) to make >> sub-classing more convenient. >> >> Sub-classing as a programming model is well-understood, and easy to gras= p. >> >> On the other hand, the decorators are less known and certainly carry >> hidden pains. How do you resolve API conflicts (two bindings have two >> properties/functions by the same name)? As a developer, how do you >> ensure a stable order of bindings (bindings competing for the z-index >> and depending on the order of they are initialized, for example)? > > I think decorators have valid use cases. For example, let's say I want to= make a component that extracts microformat or microdata marked up content = from an element and present hover UI to allow handy access to it. For examp= le, it could extract addresses and offer map links. I would want this to wo= rk on any element, even if the element already has an active behavior imple= mented by a component. I should not have to "subclass" every type of elemen= t I may want to apply this to. It's especially problematic if you have to "= subclass" even different kinds of built in elements. Do I need separate sub= classes for div, span, address, section p, and whatever other kind of eleme= nt I imagine this applying to? That doesn't seem so great. > > You are correct that figuring out how multiple bindings work is tricky. B= ut even if we choose not to do it, making components truly encapsulated doe= s not make it any harder to have a one-binding-only model with no inheritan= ce. > > >>> Notice that this scheme is not significantly more complex to use, spec = or implement than the shadow/shadowHost proposal. And it provides a number = of advantages: >>> >>> A) True encapsulation is possible, indeed it is the easy default path. = The component provider has to go out of its way to deliberately break encap= sulation, though of course it can if it wants to. >> >> Yup. >> >>> B) Binding is atomic - the shadow root is not built up incrementally so= you can't have a half-built binding. >> >> I am not sure what's the danger here. Are you trying to protect the >> author from displaying the shadow subtree while it's still being >> built? > > My experience with API design is: it's better to design APIs so that it's= not possible to use them wrong. It's better not to I think you fell off the bike here, but I think I understand where you were going :) > >> >>> C) Has a natural extension to allowing more than one binding on an elem= ent, having a stacking behavior like XBL. >> >> Given discussion above, I don't see this as an advantage. >> >>> D) Can readily support custom components bound to form controls, with e= ither semantics of stacking on top of the native binding or replacing it. >> >> This is where override and compose approaches work well for >> inheritance-based approach. >> >>> E) Avoids use of the jargon-ish, mysterious and potentially confusing t= erm "shadow" in favor of "binding" and "component" which are much more clea= r IMO. >> >> I agree that "shadow" is jargon-ish. I would love to have a better >> name for it that's not scary. I like "component" terminology! >> >>> F) The code to build up the DOM for the binding with raw DOM calls only= has to run once. After that it just gets cloned, which is likely faster th= an creating a whole fresh one with raw DOM calls. >> >> Right. This is good stuff. >> >>> G) Naturally extensible to other ways of creating components, perhaps o= n a declarative template a la XBL2. >> >> Ditto. >> >> Overall, aside from multiple trees and the use of bindings rather than >> object inheritance, I like this API. Without those two, it's exactly a >> superset of the my proposal, minus webkitShadow. I am a huge fan of >> being able to produce a Component object that acts like a DOM object. >> >> To make further progress, I would like to concentrate on resolving >> these two issues: >> >> 1) should we use object inheritance (one shadow subtree) or mixins >> (multiple shadow subtrees)? > > I think it's possible to partially table this issue. If mixing are requir= ed, then raw access to the shadow tree is not viable. But using inheritance= / single binding is possible with either proposal. I think that changes a lot of nomenclature though, right? You don't have "bindings" with inheritance. It's just you or your sub-class. Also, element.bindComponent doesn't make much sense if you can only inherit the relationship. > >> 2) do we need webkitShadow or similar accessor to shadow subtree(s)? > > This question is a helpful one. I haven't seen any reason articulated for= why such an accessor is required. The fact that it's not present in other = similar technologies seems like proof that it is not required. Yes, I will work on use cases. Though this concept is certainly present in other technologies. Just take a look at Silverlight and its LogicalTreeHelper (http://msdn.microsoft.com/en-us/library/ms753391.aspx). > > >> >> I think these are all resolved by supplying use cases and rationale. Rig= ht? > > If so, I think we need a real list of use cases to be addressed. The one = provided seems to bear no relationship to your original proposal (though I = believe my rough sketch satisfies more of them as-is and is more obviously = extensible to satisfying more of them). Did you mean the hovercard? I bet I can write a pretty simple bit of code that would usefully consume the API from my proposal. > > Regards, > Maciej > >
Received on Thursday, 30 June 2011 21:08:16 UTC