Re: XBL2 Comments

On Wed, 21 Feb 2007, Jonas Sicking wrote:
> 
> 1)
> The second example needs phase="target" on the mutation handlers.

Fixed.


> 1.4.2)
> Why are selectors case insensitive?

That's a question for the CSS working group.


> That'll be a decently big performance hit. It also makes it impossible 
> to implement one element without implementing others of different 
> casing.

Element names and attribute names and values in CSS are case-sensitive 
when the element in question is an XML element.


> Or does the text simply mean to say that they can be case insensitive? 
> If so, is that really the case in any currently existing document format 
> since HTML can't contain namespaced nodes and therefor not XBL.

Namespace prefixes in CSS are case-insensitive. Also, HTML documents can 
contain namespaced content (via DOM manipulation).


> 1.4.3)
> Why is tab not considered whitespace?

They are.


> 2.3)
> I see only one property in the first example but the text mentions two.

The second is "state".


> 2.5)
> setInsertionPoint sounds like it would be called on the inserted
> element. setAsInsertionPointFor seems like a better name, though a bit long.

setAsInsertionPointFor() is too long. If you have a better name, it's 
definitely something we'd consider. setInsertionPoint() is the least bad 
so far, though.


> Why [doesn't] removing the locked attribute reset the list of included 
> children?

Why should it?


> And does the includes attribute have any effect when locked is true?

Yes. See later in the spec, where this is covered in detail.


> 2.13)
> Seems very complicated that <style> elements affect the bound element.
> Which binding to apply, and thus which <style> elements to apply won't
> be known until after style resolution, requiring a second pass.

Correct. However, it is really required for many use cases.


> 3)
> "the binding must be applied such that to any running scripts it appears
> that the binding was applied immediately". When is that in relation to
> mutation events? It may be better to say that the binding is applied
> before the mutating function returns. It seems like this only applies to
> element attribute attached bindings? If so it would be good to state
> explicitly

Yeah, this is something that there are known issues with. I'd actually
really like implementation feedback on this. I've fixed this a bit.


> "Bindings must be detached as soon as it is known that the binding no
> longer applies to the element." Add that if the binding is added using
> the -xbl-binding property the binding will not be removed until style
> resolution happens.

Done.


> 3.1)
> Does the xbl-bindings-are-ready event fire again if bindings are
> attached asynchronously?

No. Made it clearer in the spec.


> 3.2.1)
> Why are xbl-PIs inserted in the DOM in error? That runs contrary to most
> things where the current state of the DOM is what matters, not how that
> state was reached. Scripts are so far the only exception to this. Same
> thing applies to dynamic changes to the PI.

Because otherwise interfaces implemented by elements in the document
could change dynamically. There is already a separate API for doing
this in dynamic environments (loadBindingDocument()).


> Is it really a good idea to implicitly apply bindings into the
> document in which they live? This seems wasteful at the least. Might
> be better to only do this when the <xbl> is not the root element?
> Even then you could require an xbl PI containing just a fragment
> identifier. A use case might be if want to override the look of <h1>
> by wrapping some elements around it. You could do that using a
> template like <template><div class=...><div
> class=...><h1><content/></h1></div></div></template>.  However that
> would create a recursive situation if the binding applied to the
> <h1> in the shadow tree.

I could see an argument for special-casing <xbl> being the root
element, but that seems like a can of worms that we'd want to avoid.

In the case of your example with the <h1>, why would you put an <h1>
again in the template? Consider a <button> binding. You wouldn't put a
<button> in the implementation of <button>, right?


> 3.3.1)
> Why do -xbl-binding bound bindings not affect the bindings-are-ready
> counter?

I couldn't see a good way to make this work, especially given things
like :hover { binding } during page load.


> The fact that explicitly inherited bindings are attached at the same
> time as the base binding forces all referenced binding documents to be
> loaded whenever a binding document is imported, whether the bindings are
> ever used or not. This might be good to state. In fact the imported
> document can not be considered loaded until this is done which means
> that .loadBindingDocument must wait until all inherited binding
> documents have been loaded.

This is an interesting point. I'm not really sure how this works with
mutations of the binding document, though. I've changed
loadBindingDocument() to require that all dependencies be fetched
(well, not all dependencies; I guess stylesheet @imports and such like
wouldn't actually be found unless needed later... this could be
messy).

What else needs changing?

Based on implementation feedback we might have to revamp the way
binding document loads are done.


> 3.5)
> It is unclear to me if it currently is allowed to call the
> xblBindingAttached/xblEnteredDocument functions after all bindings have
> been constructed and attached for a subtree. This is vital for styling
> performance since we don't want to have to return to the main event loop
> for each bound element during layout.

I wouldn't attach during layout. I would just make a note of what
bindings need to be applied, and when you have finished your style
pass, apply those bindings and then do layout again.


> Note that it isn't explicit in the DOM-Core spec that
> compareDocumentPosition always orders disconnected nodes.

True.


> 3.6)
> What functions should be called if the xblEnteredDocument function
> implementation moves the bound element to a different document?

An xblLeftDocument and an xblEnteredDocument. These methods are called
when everything else is stable. So nothing would happen until the
first xblEnteredDocument function returned, then, after everything has
settled down, the UA would fire an xblLeftDocument, and if nothing
changed in that time, an xblEnteredDocument. Does that make sense?


> 3.9)
> What happens if a binding document has already started loaded and the
> user then calls loadBindingDocument with the same URI?

See 8.1.1.


> Is .loadBindingDocument allowed to return even if the loaded
> document contains xbl PIs that imports other binding documents that
> have not yet loaded?

As defined today, yes.


> 4)
> Wouldn't having more than one template element in a binding make the
> binding in error?

Yes, this is already defined.


> 4.1)
> What is "xml:base data"? Same thing as the xml:base attribute?

It's the data resulting from the use of xml:base. So in your
implementation, probably just the attribute, yes.


> Why does setting the [xml:base] not cause a mutation event?

No mutation events must be fired at all during the entire cloning
process, because there didn't seem like a good reason to have them
fire and it would allow performance improvements to block them.


> 4.3.1)
> Why can xbl:text not appear by itself as a shorthand for xbl:text=xbl:text

What's the use case for that? Why not just use <content>?


> Why not insert an explicit child text child under the element when
> xbl:text is on the left hand side of the '='. That is more in line
> with how attributes are explicitly mutated when on the left hand
> side of the '='. It also makes it clearer and more easily
> implementable how the inserted child interacts with bindings on the
> element.

Because the element may have other children in the Core DOM that we
wouldn't want to blow away.


> Why are not all explicit text descendants (rather than just children) be
> taken into account when xbl:text appears on the right hand side of the '='.

Because doing that could result in broken renderings (e.g. losing text
direction information if one of the children is an <html:bdo>
element) in cases the author did not consider.


> 4.3.6)
> Could be clearer what element is the "element to which the attributes
> are forwarded", e.g. by stating that it's the element with the xbl:attr
> attribute.

Done.


> Why the waste of CPU to forward all attributes, including ones that
> haven't changed when any attribute is mutated.

That's an implementation detail. The spec doesn't require you to
implement this inefficiently if you can think of better ways to do it
than have the same effect. :-)


> 4.4)
> What is the use case for sticky insertion points?
> Aren't locked insertion points enough?
> Additionally, this doesn't match the steps in 4.4.1

I've removed the offending paragraph, which was out of date.


> What happens if you call A.setInsertionPoint with a node that
> doesn't match A?

See the definition of setInsertionPoint.


> 4.4.1)
> The first example says that A is an explicit child of my:T which is not
> the case.

How is it not the case?


> "Matching of the elements to the selector is done without taking into
> account the shadow tree in which the content element itself is found".
> Are other bindings on the bound element taken into account? In general
> this part feels too vaguely defined, what if there are implicitly or
> explicitly derived bindings, are they taken into account?

I don't understand the question. Could you give an example that you
believe is ambiguous?


> Can a node match a <content> element that is a child of another
> <content> element, even if the parent <content> element matches nodes
> and thereby hides the child <content>?

No. Such a <content> element wouldn't be "correct" and so would not be
selected by the algorithm.


> Same thing with <inherits> inside <content> and <content> inside
> <inherits>. In other words, what does the following three templates
> do? <inherited><content/></inherited>

The <inherited> element contents are used when there is no base
binding. If a node is assigned to a <content> element that doesn't end
up in the final flattened tree, well, it doesn't end up in the final
flattened tree.


> <content includes="a"><content/></content> and

The inner <content> element is in error and is ignored.


> <content><inherited/></content><div/><inherited/>

The second <inherited> element has no effect (it is replaced by its
children in hte final flattened tree). If there are no explicit
children, and there is a base binding, the base binding is used
instead of the <content><inherited/></content>, otherwise the explicit
children are used.

This is all defined in 4.5. The Final Flattened Tree.


> The third paragraph says that the children of the <content> element
> should be used if no elements match the <content>. That should say that
> the children should be used if no elements are assiged to the <content>.

Fixed.


> 4.4.2)
> Should replace the last 'elements' with 'children' or 'child elements'
> in "If an element is bound to this binding while it has three elements".

Fixed.


> 4.5)
> The first two paragraphs make it sound like the DOM is mutated, which
> should not be the case.

I'm not sure how to fix this. Do you have any suggested text? Note
that there is an additional paragraph there now that should makes
things a bit clearer.


> The interaction between the locked attribute and the includes
> attribute is unclear. In section 4.6 it sounds like an element can
> be moved out of a locked content element if it no longer matches the
> includes attribute.  If that is the case then what is the difference
> between a locked and unlocked content element?

Since the bogus "sticky" stuff has now been removed, hopefully this is
clearer now.



> 4.7.1)
> It is unclear if when allow-selectors-through is true and an explicit
> child of a bound element is inserted in a binding using <content> if the
> parents of the <content> take part in parent chain as far as selector
> matching goes.

I don't understand what interpretation could lead you to assume that
it does. Could you elaborate on why you read it that way?


> does xbl:template > my:B match the B element in the following binding
> <binding><template><my:B/></template></binding>. If yes, that doesn't
> match what is stated. If no, why not?

It does not, because the ">" combinator is defined to consider the
bound element to be the parent of the shadow tree, not the <template>
element. This allows you to make stylistic choices based on the
attributes and other facets of the bound element (if you set
allow-selectors-through, anyway).


> Why does the + combinator not step in to inherited or content elements?
> Arguably it does seem like it could be hard to implement.

The current state of the combinator definitions is the result of very
long discussions. I do not remember the precise reasoning.


> 4.7.3
> The dual meaning of the :bound-element pseudo class seems like a bad
> idea from a usability point of view. It also makes it impossible to
> match a bound element inside a shadow tree. Why not split it up into two
> selectors?
> What is the usecase for matching all xbl-bound elements in general?

It isn't clear that matching a bound element in general is a useful
thing. That this is possible at all is mostly the result of defining
what should happen in the absense of a bound element, rather than the
result of an actual use case.


> 4.9.6)
> Why does references in SVG pointing to a bound element use the first
> element in the nodes shadow tree? That seems contrary to other behavior
> where references to a to a bound element still point to the bound
> element, but rendering renders both the bound element and it's
> "flattened children". Maybe this is only desired in SVG when the bound
> element is an SVG element.

It is so that you can do things like define bindings that define
gradients or fonts or whatnot.


> Shouldn't an animation element that is a child of a <template> refer
> to the bound element rather than its parent? Again, maybe that makes
> more sense only when the bound element is an SVG element. Reading
> through comments it looks like this has been brought up and
> addressed.

Animating the bound element from within the binding is not something
that IMHO makes sense. Animated elements would animate their rendering
(shadow tree), not themselves.

Note that binding SVG elements themselves is not expected to ever
be useful.


> 4.10)
> Does setting apply-binding-sheets apply the binding sheets to shadow
> content of bindings of descendants of the explicit children of the
> insertion point? It seems like the answer is yes, which could be
> clarified by changing "children" to "descendants" in "A second
> attribute, apply-binding-sheets, can be used to indicate that all
> children of the bound element" and in the description of the attribute.

apply-binding-sheets would only do this if the bindings of descendants
of the explicit children assigned to the insertion point had
apply-author-sheets set to true.

Clarified.


> "Sheets are always walked from the innermost shadow scope to the
> outermost shadow scope". How does this interact with sheets having
> different CSS origin levels, i.e. some being UA sheets and some
> being author sheets?

CSS already defines that, no?


> Should the second to last paragraph say "'-xbl-binding' property"
> rather than "'binding' property"? This appears twice.

The property has been renamed to 'binding'. Removed the last trace of
'-xbl-binding' and fixed the cross-references.


> 4.10.1)
> "The <style> is also applied to explicit children" seems like 'explicit
> children' should be 'descendants'.

Fixed.


> 5.2)
> What is the purpose of the xblImplementations property? It seems to
> defeat the purpose of hiding the shadow tree etc in that it can make
> users dependent on the internals of a binding.

It returns the external object, not the private object. How does it
defeat shadow tree hiding?


> 5.4)
> An alternative to having the external and the private object would be to
> allow the implementation to return a function rather than an object.
> This function would then be called in order to instantiate the prototype
> object. This would allow the prototype to use a local scope object to
> produce private properties. This would be beneficial in JS2 since it
> directly supports private members and so the internal/external
> separation isn't needed to be done as two objects. Another solution
> could be to let JS2 have a different implementation model than JS1 where
> the internal/external separation doesn't exist.

The above is true. However I am very reluctant to change this now.


> It is somewhat of a problem that xblLeftDocument etc are accessible on
> the external object since that makes it possible for authors to mess
> with the binding [by] calling these methods directly.

Not sure what to do about this.


> Properties from one external binding object needs to be forwarded to
> [external] deriving binding objects. Otherwise using the .baseBinding
> property is fairly useless in that it only contains the properties of
> the immediately inherited binding.

Not sure I understand this either.


> 6.1)
> Retargeting of events is used before it is described what it is.

This is by far not the only time this happens in this spec! :-)



> 6.2)
> What does the sentence "However, their being in error does not affect
> the processing model described above" mean? Should addEventListenerNS
> still be called? If so, why?

Yes. In the case of the event attribute being in error, it makes no
difference. In the case of the phase attribute being in error, it
seemed pointless to have the UA check that the attribute had a correct
value before going on.


> "When a handler element is invoked by the object passed to the
> addEventListenerNS() method, the user agent must check that the
> event in question was forwarded to a handlers element from a bound
> element, and that that handlers element is the parent node of the
> handler element."  When is that not the case? Especially the parent
> part since I'd assume that removing a handler from the handlers
> element would call removeEventHandlerNS.

I'm not sure, but I imagine XML Events or other such wacky mechanisms
might do it.


> When the phase attribute is not set the early paragraphs says that
> this is equivalent to having useCapture specified as false. However
> this will not cause the handler to be triggered during the capture
> phase as is specified in the second to last sentence in the
> description of the phase attribute.

That isn't what that sentence says.


> Does not setting the phase attribute cause the handler to be
> potentially triggered three times for the same even? I.e. during
> bubble, capture and default phases?

It can never trigger both during bubble and capture, since the event
is only ever registered for one or the other. It can never trigger
during both bubble and target or capture and target, since the target
element is never given the event in capture or bubble phase.

You are however correct that if it isn't specified it shouldn't
trigger the default action phase. I've fixed that.


> 6.8)
> "Events must flow through the final flattened tree" This sentence on
> it's own is very non-descriptive. Does this mean that <inherited> and
> <content> elements never see any DOM events?

Unless they are fired directly on those elements, that is correct.


> That seems to contradict the paragraph above.

Why?


> "When the event is fired for the bound element's event handlers, it does
> so in the target phase. The capture phase listeners are not fired for
> the bound element." What does this paragraph mean?

Clarified.


> "During the capture phase, the rules are exactly reversed" Reversed
> from what? The previous sentence talked about the reason for
> retargeting being hiding inner scopes from outer, which presumably
> isn't what is reversed.

Reversed from the way it's been described up to that point, which is
in terms of the bubbling phase. The rest of the paragraph describes
it.


> "The target node, when the event is passing through a node at a
> higher shadow scope than the event target, is always the bound
> element in whose shadow content the event target lies" What about
> when the next shadow scope is that of an inherited binding, is the
> target the <inherited>?  What about when the target is an explicit
> child whose insertion point is inside an inherited binding?

All the shadow tree fragments for a single bound element count as one
"scope". (Actually this section hasn't really been updated since the
inherited bindings were split up.)


> How does an event bubble when the target of an event is an explicit
> child of the bound element, but that child has no insertion point?

DOM Core.


> Would it make sense to only let events that are retargeted rather
> than stopped to bubble into deeper shadow scopes?

Why wouldn't you want stopped ones to go deeper?


> The capturing listeners on the <bound> element shouldn't fire in the
> example, i.e step 2 should be removed. This is since they wouldn't
> if there wasn't a binding attached to the element. Attaching a
> binding shouldn't affect the types of events the outside world see.

Correct. Oops. Fixed.


> Too many details of the event propagation is defined by the example
> rather than by the detailed text.

None of the details are _defined_ by the example. The examples are all
non-normative.


> Would be good to have a list of exactly what the implementation
> should do, sort of like the list in section 3.5.

I'm not really sure it's possible, short of also defining the entire
DOM3 Events model. But I agree that "diff" specs like this are poor.


> 6.9)
> Why the random number used for eventPhase during default-action phase?
> Couldn't a more rememberable one be used?

It's not a random number (it's the string "xblD" in ASCII read as a
big-endian 32bit integer) but it _is_ an arbitrary number, in that it
shouldn't really matter what its value is -- people aren't expected to
ever look at it. The only way for code to execute when it is in the
default phase is for a <handler> to have phase=default-action, so code
always knows whether phase has this value or not.

The reason for the crazy number was to avoid clashes with anything
else.


> Wouldn't it make more sense for the default phase to go from the
> document node to the targeted node? This since the final action will
> be on the innermost node, i.e. the targeted node. Additionally, this
> allows the binding to implement a default behavior for the bound
> element without having to worry about what inner elements it is
> using and their default behavior.

Well, you want it to go inside-out because that's how default
activation behaviours work in DOM3 Events (though this may not yet
have been actually written down anywhere). But yeah, I'm still looking
at this. Implementation experience will be helpful here.


> The last sentence should also state that stopImmideatePropagation
> has no effect.

Fixed. Though I'm not sure about it.


> 6.10)
> Does the :focus handling also apply to :active? I.e. can there be a
> chain of :active elements?

If you can get the CSS working group to agree on what :active means
_outside_ of XBL, let me know and I'll update the XBL2 spec to
elaborate on what it should do when XBL is involved!


> The first sentence of 6.11 seems like it would be nice to include
> here too. I.e. that if focus is moved out of the bound element the
> event should be retargeted rather than stopped.

Fixed.


> 7.2)
> "or if the node is not an element" doesn't make any sense since the
> method is only available on elements.

Oh yeah. We changed it from NodeXBL to ElementXBL. Fixed.


> I don't understand the example for hasBinding at all, it seems to be
> missing context.

Not sure what makes you think that...?


> Can hasBinding be used to check for bindings attached though
> -xbl-binding or using the element-attribute? If so, would be good to
> state so given that that is not the case for removeBinding.

Fixed.


> 7.2.1)
> "Manipulating the DOM of a shadow content tree must directly affect the
> content under the bound element" what does 'content' refer to there? The
> rendered content? It clearly shouldn't mean the explicit content under
> the bound element.

Fixed.


> 7.3)
> Step 1 could be read to indicate that if a <content> element is created
> using createElementNS and then inserted in a shadow tree its
> setInsertionPoint method will forever be a no-op. Would be better to
> change the parenthesis to say "e.g. the content element is not located
> in a shadow tree".

Fixed.


> It seems like step 3 should do the same thing as calling the method on a
> content element that is not in the shadow tree. Either both should throw
> or neither should throw.

Fixed. Three exceptions are thrown now.


> 8.1.2)
> The requirement that two style elements with the same src can't reuse
> the same stylesheet seems to be out-of-scope for the xbl spec.

Why? It's an XBL element...?


> Finally I have two concerns without proposed solution:
> 
> The browser will behave differently if an element is implemented using
> XBL or using a native implementation when that element is further bound
> by a document author. In one case <inherited> will render content and in
> one it won't. Something that might help this is to let <inherited> in
> the base binding render the contents of the remaining (so far without
> insertion point) children. I.e. let there be an implicit binding with
> the shadow tree <template><children/></template>.

I intend at some point to work on a spec that defines how various
elements should appear to be implemented at the UA level in terms of
XBL.


> It is in some cases needed that one binding can get to the internal
> implementation object of another binding. One example of this is a
> tab-strip implementation where the binding for the <tabstrip>
> element needs to get to the internals of the individual <tab>
> bindings. One way to do this would be to make it possible for
> bindings from the same binding document to using some API be able to
> reach each others internal implementation object.

Why can't the <tabstrip> just use the <tab>'s official API?

-- 
Ian Hickson               U+1047E                )\._.,--....,'``.    fL
http://ln.hixie.ch/       U+263A                /,   _.. \   _\  ;`._ ,.
Things that are impossible just take longer.   `._.-(,_..'--(,_..'`-.;.'

Received on Thursday, 22 February 2007 02:40:59 UTC