Notes from a component model pow-wow

Context: Last week some Bay Area/visiting Bay Area browser hackers met
to discuss the component model
<http://wiki.whatwg.org/wiki/Component_Model> This is my unedited
transcript. I am not much of a stenographer so no doubt there are
gaps.

Cast of characters:
boris--Boris Zbarsky
dg--Dimitri Glazkov
dpc--Dominic Cooney (me)
hyatt--Dave Hyatt
jamesr--James Robinson
maciej--Maciej Stachowiak
rs--Roland Steiner
sam--Sam Weinig
sicking--Jonas Sicking
slightlyoff--Alex Russell
plus others who I failed to log--sorry

dg: wanted to implement XBL2, 2 years later, slightlyoff (dojo) had
different proposal--simple web components. 1 yr ago post to webkit-dev
about components. XBL2 seems nice because it is a written spec. What's
the shape of the problem? See whatwg wiki Component_Model (MSFT
indicated some interest at least)

GOAL: Make sure everyone understands the problem we're trying to solve.
GOAL: Get feedback on the way to solve the problem.
GOAL: Get specific ideas.

Methodology:
1. Come up with a set of use cases that capture what you want to accomplish.
2. Study use cases come up with a set of properties.
3. Design building blocks that cohere with desired properties.
... see the wiki ... Component_Model_Methodology

Our use cases: Let the things that are happening on the web already
and in web browsers already happen in a more natural fashion. A lot of
JS frameworks do a lot "wrong" (a lot of crap

sam: what is success?

dg: can accomplish the use cases. Flow from use cases to
properties. Properties are orthogonal to each other. Building blocks
satisfy properties.

use cases: layout manager, can't use components from one library in a
layout manager for another ... see the wiki
... Component_Model_Use_Cases


maciej: what happens if you attach a shadow root to an element that
has a shadow root? dg: we throw--no use cases needed multiple shadow
roots

maciej: shadow root has a constructor, but the constructor has a huge
side effect--it should be a method on element

boris+: programattically building up a shadow tree looks clunky

hyatt: if there is one thing to really look at in XBL2, it is shadow tree stuff
like basic inheritance chain and the concept of explicit children and
insertion points in the shadow tree

maciej: most use cases need a declarative template that describes how
your template is structured based on your children

sam: this is based on use cases from existing widget libraries. The
underlying problem is creating a library. Widget libraries have
imperative code, hence they are imperative. dg: it is not possible to
know until you're running what your shape can be. sicking/hyatt: form
controls or video know their shape.

dg: people will still want an imperative way to build trees--so build
the declarative version using imperative code.

boris: this relies on the component to not leak the shadow tree. It
would be easier if the script is not in the document.

hyatt: you might have script that runs on the shadow root that needs to
be structured

maciej: programmatically building can be the primitive or you could
build the template mechanism on top; if you imagine the template is
the common case, then sometimes you need the script to attach event
handlers or mutate the dom the template created. So it depends what
you think the common case is before you design your primitives.

dg: this is just like DOM--you can add methods to existing DOM tree,
you can programatically build a tree; you can declaratively build a
tree

dpc: so if you had both that would be no bad thing hyatt: but we only
see the programmatic way here

dg: <content> element--insertion point inside the shadow tree, content
element lets you control how the shadow tree is flattened.

maciej + apple: need to see details boris: devil is in the details

dg: constructable DOM types

sam: is this just slightlyoff's proposal on script-coord? dg: no, that
is just say new ...(), this is about making subtypes

maciej: three parts 1. create existing built-in types, 2. if you have
a custom element that is logically a subclass of some element you need
to be able to construct that as well (dg: that is the one!) either by
defining its own way of getting constructed or hooking into some
common mechanism. 3. you need that subclassing mechanism to let
elements get privileged access to it. Maybe the primitives are
designed in such a way that you don't need it, but just #2 doesn't let
you override behavior.

dg: you can do that (#2) today with swizzling the prototype chain, boris:
you can't create a subtype with a different tag name--there is no real
reason that has to be the case.

maciej: ... so you need to create something that subclasses div and
has its own tag name.

dg: garden-o-matic uses constructable DOM types. But when you get them
back out of the DOM tree, your proto is gone.

hyatt: that (subclassing) seems natural

boris: seems like a good idea, lets not rathole on the details just yet

dg: so how does this interact with parsing? if I round trip with
innerHTML, then the behavior is gone. Element.register.

boris: constructor may not be the right primitive to register; you want to
associate a tag name with a prototype chain and a built-in element
class. dc: why not run a constructor? boris: doesn't like
HTMLElement.call associating the element with the C++ object
post-hoc. dg: see the discussion on public-webapps. boris: should have
a declarative way of doing registration--hyatt: see XUL
extends=namespace&tag boris: you want to get a C++ object with a
different prototype chain. sam: (got behind)

dg: hot mutato boris: undesirable for lots of reasons dg: what if
element.register runs after markup is parsed? what happens to that
element? our solution is renameNode. This problem is not solvable at
the current plumbing level. If some script already grabbed this
object, you don't want to have this object change its identity. sam:
this is just like the window maciej+hyatt+boris: nasty maciej: window
has an outer and an inner object, proxies everywhere sam: OK maybe it
is too hard

dg: hot mutato reprise

boris: the problem you're trying to solve is one when registration
happens after parse; it might be simpler to just say, elements that
are created before registration are just left the way they are

maciej: it seems reasonable to say register affects future parsing,
you can reregister tag names

dg: confinement--this building block by itself says: I want to run
scripts in a confined fashion. maciej: is it just an iframe? dg: yes,
but we make it go faster. Caja has a same-origin iframe and hooks
window and document to get confinement. Can't just accept Caja as a
lump, it is too complex.

sicking: are you trying to prevent the component from reaching out to
the main page?

hyatt: there's also the opposite case

hyatt: I'm really confused with this model where the shadow nodes
really live; if you put event handlers on the shadow node and those
run script, where those runs. dg: all of the script runs in that
isolated script. But not sure of the details we need to work it
out. hyatt: you don't want to limit it to same origin. You're going to
have trusted form controls that the engine might execute.

boris: encapsulation we want in general; confinement you sometimes want

maciej: there's nothing here that allows the component to really
protect itself from the page. Pages that embed the like button in
general shouldn't have to trust FB. Likewise FB shouldn't have to
trust all embedders.

dpc: manifests (Components should have a manifest so a caller
can be confident that it doesn't squat on other element names.)

maciej: can you encapsulate video controls that attach to a video
element without having to create a x-youtube-video; if registration
allows rebinding of built-in elements ...

hyatt: you could imagine an approach there your parts are exposed as
pseudo-elements maciej: that lets you control appearance but not
behavior

boris: in +1/Like buttons you include some script and then write a tag
name, so if you could have the page do the registration maciej:
register and specify a tag name and a url which does something (ie
registration) although you could have scoped names maciej: alpha
renaming of component names

hyatt: you need to be able to style the shadow tree dg: we have been
following XBL model sicking: XBL lets you only apply styles to shadow
tree ... (discussion about selectors)

hyatt: everything is being approached very programatically; in my mind
what you have is you have this object that has a shadow tree; I
assert far more common use cases are going to have a shadow tree. On
top of that you're wanting script that you want to run. You're wanting
style from stylesheets. It seems more like a HTML file.

dg: we may have not produced use cases yet that cover this well ...

hyatt: form controls!

sam: look at common practices today of writing webapps; most are using
templating at the server level. dg: you don't have to persuade us that
templating is necessary sam: yes we do! there are no templates here!
maciej: if you made the templating thing primary and the script
secondary then you would have a different solution hyatt: once you
have the declarative side, the imperative comes for free as DOM
manipulations maciej: it seems worthwhile to design them together to
make sure that they fit together and there is no redundancy
(boris: XBL makes video declarative in mozilla!)

hyatt: there is a lot of fat to cut from XBL like implicit
inheritance; you could punt on decorator bindings; have a single
inheritance chain--you'll be in hell for form controls if you do it
programatically

dg: I want a template element that can stand by itself.

dg+slightlyoff: we need a template element that doesn't pollute styles,
doesn't run scripts

hyatt: reserve judgement need to see it

boris+sam: browsers can already do this in separate documents; we just
need to tell the browser that this subtree should be treated that way

dg: plenty of developers clone out of the DOM, so we should build it

slightlyoff: usually developers include a script tag; include stuff
that is not script but doesn't include a closing script tag and parse
it. We're going for layering. We want orthogonal primitives that add
up to a larger whole.

dglazkov: I want event handler attachment. I want to say this element
will have that event handler. I just want to attach that script and
run it when the event fires--syntax TBD.

boris: onclick sucks; the scope chain is whacky.

slightlyoff: someone other than the cloner might have the requirements

boris: (missed this)

hyatt: if you have a derived class and a base class and you want to
work the base shadow into the derived class' shadow

rs: I like composition sicking: me too

slightlyoff: You can encapsulate shadow inside your own and
forward. If you need fine grained interleaving you can use the
"lifecycle hooks???!?!" to do it.

maciej: do you have any way when you subclass something to copy its
shadow DOM?

slightlyoff: it is just a lifecycle; you can call methods or not and
do what you want.

boris: he is assuming that you're creating the shadow tree
imperatively hyatt: that is basically what XBL inherited was maciej:
so your subtype can't work with the shadows slightlyoff: unless the
parent type cooperates maciej: you can have encapsulation or
subclassing but it seems like you can't have both

sicking: why do you need to use the parent class' shadow tree? maciej:
what if I want to create a subclass of textarea that has the parent's
textarea and have some extra buttons rs+dg: just use composition
hyatt+maciej: you end up having to write a lot of forwarding dg: but
you only need 5% of that glue sam+maciej: if you want to create a
component that is a drop-in replacement for textarea then you have to
do all of the forwarding, so if you do subclassing you can't subclass
any nontrivial behavior

slightlyoff: DOM is defined with interfaces; JS objects use
mixins. DOM is unnatural. I want to make these explained using mixins
instead so you can just mix in the behavior you want. So a user object
could act like a form element by mixing in the formish trait. So
traits for composition.

maciej: how does this work for my textarea case? sicking: just use
composition and mix in the forwarding maciej: so why do you even need
subclassing at all? If so, you should get point #3 above. If not, then
you don't need subclassing.

slightlyoff: Our intent was to heal the rift between DOM and
JavaScript.

boris: You want to solve the problem of passing an extended object
like canvas+behavior to the DOM and have it treated like a canvas.

maciej: This design can subclass div or p, but not textarea, which is
a weird place to draw the line.

slightlyoff: The only reason you need forwarding is when a generic
mixin won't do what you want.

boris: most of this is implementation details.

maciej: having to lock down the structure for every form element. If
you have a future OS that has a completely different look.

boris: we added a resizer element to textarea so the shadow tree changed.

maciej: so locking down the shadow tree for built-in elements is a nonstarter.

hyatt: (paragrpahsing slightlyoff): there would be an API; you
wouldn't access the shadow tree directly

sicking: I think an inherit element would solve your problem.

boris (paragraphsing maciej): you want a use case that subtypes a textarea.

AI(hyatt): I will get you use cases. inherit is not a difficult thing
to implement.

maciej: I want to have an understanding of the big picture; the fine
details of particular things are really important. So you need to
understand the full design details of the problem. Considering other
binding systems.

slightlyoff: Current JavaScript libraries are doing what they're
doing. Those are the use cases.

hyatt: you've done a good job weeding out bad things of XBL2 (forget about
XBL.) Maybe I want to do some fancy SVG stuff to the textarea

boris: the details really matter

dg: how do we make progress? what if we posted this binary on
public-webapps? add hyatt's use cases

boris: we need to have a description fo how shadow tree and how CSS
works--inheritance, selectors; XBL2 was overcomplicated, it is OK to
punt as much as we want. We need something defined.

hyatt: there are all these subtleties like, the child selector works
on the shadow content in XBL1.

boris: so the point is so that outside the binding selectors work as
if the binding was not there

dg: roland is charged with this; he is going to be writing the spec

hyatt: I am guessing it will involve enhancing the style element with
new scoping rules

rs: (his proposal about css variables)

hyatt: sounds like a way to get things from the outside in

boris: confinement. if you have something in the prototype that calls
another method--what happens if hte page redefines one of those
methods to one it controls. Or passes in a lure. There needs to be
some kind of place for the binding to hang methods it wants to call
that is not the protototype. It needs to be failsafe.

maciej: when you say modify the prototype I can think of three
meanings: alter .prototype--boris: not that--maciej: accessing the
__proto__ property

boris: if you take some object from the page and change its properties
to point to functions of your design (via
Object.getPrototypeOf). maciej: one solution is to make that object's
prototype inaccessible. boris: gecko+spidermonkey will start throwing
when you pass in something with a platform object on the prototype
chain

dg: we should have mark miller study this he is an expert

boris: the point is the details matter a lot; I think you mostly have
the right pieces but the details matter

sam: why is the approach not to take XBL2 or XBL and remove the bad parts

hyatt: you would be changing so much--XML; boris: the syntax is different

hyatt: shadow tree stuff is relevant you can reuse that wholesale

dg: the biggest difference is that the XBL is decorator style; the
bindings change behavior

boris+sicking+sam: so rip out bindings!

dg: event retargeting is there; event forwarding is gone (hyatt, boris--OK)

sam: you're ignoring wholesale parts of XBL2, seeing only programattic.

dg: there is no such thing as only declarative

hyatt: all you're showing us is programmatic and --

(shouting match--declarative will be there)

hyatt: we really need to see concrete syntax

maciej: examples are useful; usage examples; patches to see how the
details work internally. Writing up in much more detail how these
pieces work. Doesn't necessarily need to be to spec level of detail
and precision.

Received on Tuesday, 20 September 2011 23:59:37 UTC