XBL2 Comments

Hi All,

Here's my unfortunately very late comments to the XBL2 spec. All in all 
it looks great, but of course there are some things here and there that 
would be great to get clarified and/or changed.

I'm still reading the backlog for this list, so apologies if some of 
these comments have already been raised. The comments are ordered by the 
section in the spec they address.

1)
The second example needs phase="target" on the mutation handlers.

1.4.2)
Why are selectors case insensitive? That'll be a decently big 
performance hit. It also makes it impossible to implement one element 
without implementing others of different casing. 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.

1.4.3)
Why is tab not considered whitespace?

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

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

Why does not removing the locked attribute reset the list of included 
children? And does the includes attribute have any effect when locked is 
true?

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.

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

"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.

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

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.

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.

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

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.

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.

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

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

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

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

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

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

Why does setting the xml:data not cause a mutation event?

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

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.

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 '='.

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.

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

4.4)
What is the use case for sticky insertion points? Aren't locked 
insertion points enough? What happens if you call A.setInsertionPoint 
with a node that doesn't match A? Additionally, this doesn't match the 
steps in 4.4.1

4.4.1)
The first example says that A is an explicit child of my:T which is 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?

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>? Same thing with <inherits> inside 
<content> and <content> inside <inherits>. In other words, what does the 
following three templates do? <inherited><content/></inherited>, 
<content includes="a"><content/></content> and 
<content><inherited/></content><div/><inherited/>

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>.

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".

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

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?

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.

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?

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

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?

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.

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.

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.

"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?

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

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

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.

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.

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 my calling these methods directly.

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

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

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?

"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.

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.

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?

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? That seems to contradict 
the paragraph above.

"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?

"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.

"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?

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?

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

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.

Too many details of the event propagation is defined by the example 
rather than by the detailed text. Would be good to have a list of 
exactly what the implementation should do, sort of like the list in 
section 3.5.

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

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.

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

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

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.

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

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

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.

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.

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".

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.

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.


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>.

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.

Best Regards,
/ Jonas

Received on Wednesday, 21 February 2007 20:28:07 UTC