Issue with using XML Events 2 with repeated content (PR#8031)

This is a multipart message in MIME format.
--=_alternative 008189D988257333_=
Content-Type: text/plain; charset="US-ASCII"

We have had a lot of difficulty in XForms with using XML events due to 
repeated content .

We have the most problems at the join between the repeated content and the 
element doing the repeating.  A simple example should help:

...
  <icecream>
     <desired></desired>
     <flavor color="brown">chocolate</flavor>
     <flavor color="pink">strawberry</flavor>
     <flavor color="white">vanilla</flavor>
  </icecream>
...
<select1 ref="desired">
    <label>Pick one flavor:</label>
    <itemset nodeset="../flavor">
         <label ref="."/>
         <value ref="."/>
         <hint>The color will be <output ref="./@color"/></hint>
         <action ev:event="xforms-select">
           <!-- Do some stuff -->
         </action> 
    </itemset>
</select1>

Note that I could have written a "help" instead of the "message" above, 
but the help is the same as the above message, which more clearly shows 
the connection to XML events.

The itemset keyword in XForms generates, for each node of its nodeset,  a 
wrapper "item" element around a label, value and message given in the 
content of the itemset.  The XPaths within the wrapper item are evaluated 
relative to the generating node from the nodeset.  So the select1 will 
present a list of three items, chocolate, strawberry and vanilla.  When 
the user picks one, the "value" of it is placed into the node named 
desired.  If the user requests a hint on an item, they are told the color 
of the icecream represented by that item.

We cannot do this right now in XForms because elements like hint and help 
are not allowed in itemset.  We could do it with a message action instead, 
but the results across implementations are not likely to be interoperable. 
 The problem is that hint is very similar to having <message 
ev:event="xforms-hint">...</message>, which has some of the same problems 
as the action that listens for "xforms-select".

One problem is that it is unclear whether the action handler sets up a 
listener on each wrapper item generated by the itemset, or whether it sets 
up a listener on the itemset element itself, or both.

Based on having an XML events processor that is distinct from the XForms 
processor, I think we get both, which is unfortunate.  I think when the 
document is loaded, a listener for xforms-select on the itemset is 
created.  Then, when the XForms processor generates each wrapper item, 
that is a new XML document that contains an action handler, and so a new 
listener is created to listen for an xforms-select event on each wrapper 
item.

In this case, I did not intend to set the listener on the itemset but only 
on the generated items.  However, in this case, I think it doesn't hurt 
anything to have both ***unless*** events in the generated DOM are 
expected to bubble up to the generator items.  I believe the two DOMs are 
separate and that events don't bubble between them.  I also believe that 
XML Events talks about what happens within ***a*** DOM and does not define 
event bubbling between DOMs.  However, some have argued that just because 
the spec doesn't say the events bubble doesn't mean they don't bubble. 
Therefore, for the sake of clarity, please spell out the fact that the 
spec does not define any bubbling behavior between two DOMs and that 
events don't traverse more than one DOM unless a consumer of XML events 
defines a mechanism for dispatching events in one DOM based on the 
occurrence of events in another DOM.  And even then, there would be a 
problem because the join points between two DOMS would look like event 
targets when they should really be part of the capture and bubble phase of 
a multi-DOM event. 

Unfortunately, while my views above about events not bubbling between DOMs 
works out well for xforms-select, it does not work out so well in two 
other cases.

First, sometimes you do want the events to bubble out of generated content 
and into the generator.

Second, sometimes you only want the event handler to attach to the 
generator (repeater) element, not to the generated elements.

For the first case, we can amend the select1 above slightly to see the 
problem.  Suppose you have this:

<select1 ref="desired">
    <label>Pick one flavor:</label>
    <hint>The color will depend on what flavor you pick.</hint>
    <itemset nodeset="../flavor">
         <label ref="."/>
         <value ref="."/>
         <action ev:event="xforms-select">
           <!-- Do some stuff -->
         </action> 
    </itemset>
</select1>

Now, we would like to be able to say that the item element is the target 
of the xforms-hint event so that one can provide item-specific events. Yet 
clearly the second select1 above just wants to do a round-up of all 
xforms-hint events generated by all item elements and provide a more 
generic hint.  But for that to work, the xforms-hint targeted at the item 
would also need to bubble up to the select1.  We really need a fix for 
this.

For the second problem, I have to turn to the xforms repeat construct, and 
put a repeat within a repeat:

<repeat nodeset="some/nodes" id="X">
   <action ev:event="xforms-scroll-last">
         <!-- Do some stuff -->
   </action>
   <repeat nodeset="more/nodes" id="Y">
      ...
   </repeat>
</repeat>

In the above example, it is clear that I want to listen for 
xforms-scroll-last on repeat X.  However, I contend above that another 
copy of the event listener will be created to listen for 
xforms-scroll-last on each wrapper group element generated by the repeat 
to represent a "row" of the repeated content in a "table".  However, when 
an xforms-scroll-last is dispatched to an instance of repeat Y, it bubbles 
up from repeat Y to the wrapper group element, where we "Do some stuff" 
that was only intended to happen when repeat X received the event.

In this case I think it is a bit hacky but again an OK solution to 
conclude that a listener gets created both on the repeat in the original 
document and on each repeat row's wrapper group element as long as there 
is an easy way to restrict the handler to only run in the former case. And 
again, I realize there is *a* way, namely adding ev:targetid="X" but I 
only added the IDs for the purpose of discussion and I would prefer to not 
use IDs.  Fortunately, this is another case that would work out nicely if 
you added phase="target" AND made it the default.  Then, the above markup 
would look the way it acts, and it would act properly.

Cheers,
John M. Boyer, Ph.D.
STSM: Lotus Forms Architect and Researcher
Chair, W3C Forms Working Group
Workplace, Portal and Collaboration Software
IBM Victoria Software Lab
E-Mail: boyerj@ca.ibm.com 

Blog: http://www.ibm.com/developerworks/blogs/page/JohnBoyer


--=_alternative 008189D988257333_=
Content-Type: text/html; charset="US-ASCII"


<br><font size=2 face="sans-serif">We have had a lot of difficulty in XForms
with using XML events due to repeated content .</font>
<br>
<br><font size=2 face="sans-serif">We have the most problems at the join
between the repeated content and the element doing the repeating. &nbsp;A
simple example should help:</font>
<br>
<br><font size=2 face="Courier New">...</font>
<br><font size=2 face="Courier New">&nbsp; &lt;icecream&gt;</font>
<br><font size=2 face="Courier New">&nbsp; &nbsp; &nbsp;&lt;desired&gt;&lt;/desired&gt;</font>
<br><font size=2 face="Courier New">&nbsp; &nbsp; &nbsp;&lt;flavor color=&quot;brown&quot;&gt;chocolate&lt;/flavor&gt;</font>
<br><font size=2 face="Courier New">&nbsp; &nbsp; &nbsp;&lt;flavor color=&quot;pink&quot;&gt;strawberry&lt;/flavor&gt;</font>
<br><font size=2 face="Courier New">&nbsp; &nbsp; &nbsp;&lt;flavor color=&quot;white&quot;&gt;vanilla&lt;/flavor&gt;</font>
<br><font size=2 face="Courier New">&nbsp; &lt;/icecream&gt;</font>
<br><font size=2 face="Courier New">...</font>
<br><font size=2 face="Courier New">&lt;select1 ref=&quot;desired&quot;&gt;</font>
<br><font size=2 face="Courier New">&nbsp; &nbsp; &lt;label&gt;Pick one
flavor:&lt;/label&gt;</font>
<br><font size=2 face="Courier New">&nbsp; &nbsp; &lt;itemset nodeset=&quot;../flavor&quot;&gt;</font>
<br><font size=2 face="Courier New">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&lt;label
ref=&quot;.&quot;/&gt;</font>
<br><font size=2 face="Courier New">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&lt;value
ref=&quot;.&quot;/&gt;</font>
<br><font size=2 face="Courier New">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&lt;hint&gt;The
color will be &lt;output ref=&quot;./@color&quot;/&gt;&lt;/hint&gt;</font>
<br><font size=2 face="Courier New">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&lt;action
ev:event=&quot;xforms-select&quot;&gt;</font>
<br><font size=2 face="Courier New">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp;&lt;!-- Do some stuff --&gt;</font>
<br><font size=2 face="Courier New">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&lt;/action&gt;
</font>
<br><font size=2 face="Courier New">&nbsp; &nbsp; &lt;/itemset&gt;</font>
<br><font size=2 face="Courier New">&lt;/select1&gt;</font>
<br>
<br><font size=2 face="sans-serif">Note that I could have written a &quot;help&quot;
instead of the &quot;message&quot; above, but the help is the same as the
above message, which more clearly shows the connection to XML events.</font>
<br>
<br><font size=2 face="sans-serif">The itemset keyword in XForms generates,
for each node of its nodeset, &nbsp;a wrapper &quot;item&quot; element
around a label, value and message given in the content of the itemset.
&nbsp;The XPaths within the wrapper item are evaluated relative to the
generating node from the nodeset. &nbsp;So the select1 will present a list
of three items, chocolate, strawberry and vanilla. &nbsp;When the user
picks one, the &quot;value&quot; of it is placed into the node named desired.
&nbsp;If the user requests a hint on an item, they are told the color of
the icecream represented by that item.</font>
<br>
<br><font size=2 face="sans-serif">We cannot do this right now in XForms
because elements like hint and help are not allowed in itemset. &nbsp;We
could do it with a message action instead, but the results across implementations
are not likely to be interoperable. &nbsp;The problem is that hint is very
similar to having &lt;message ev:event=&quot;xforms-hint&quot;&gt;...&lt;/message&gt;,
which has some of the same problems as the action that listens for &quot;xforms-select&quot;.</font>
<br>
<br><font size=2 face="sans-serif">One problem is that it is unclear whether
the action handler sets up a listener on each wrapper item generated by
the itemset, or whether it sets up a listener on the itemset element itself,
or both.</font>
<br>
<br><font size=2 face="sans-serif">Based on having an XML events processor
that is distinct from the XForms processor, I think we get both, which
is unfortunate. &nbsp;I think when the document is loaded, a listener for
xforms-select on the itemset is created. &nbsp;Then, when the XForms processor
generates each wrapper item, that is a new XML document that contains an
action handler, and so a new listener is created to listen for an xforms-select
event on each wrapper item.</font>
<br>
<br><font size=2 face="sans-serif">In this case, I did not intend to set
the listener on the itemset but only on the generated items. &nbsp;However,
in this case, I think it doesn't hurt anything to have both ***unless***
events in the generated DOM are expected to bubble up to the generator
items. &nbsp;I believe the two DOMs are separate and that events don't
bubble between them. &nbsp;I also believe that XML Events talks about what
happens within ***a*** DOM and does not define event bubbling between DOMs.
&nbsp;However, some have argued that just because the spec doesn't say
the events bubble doesn't mean they don't bubble. &nbsp;Therefore, for
the sake of clarity, please spell out the fact that the spec does not define
any bubbling behavior between two DOMs and that events don't traverse more
than one DOM unless a consumer of XML events defines a mechanism for dispatching
events in one DOM based on the occurrence of events in another DOM. &nbsp;And
even then, there would be a problem because the join points between two
DOMS would look like event targets when they should really be part of the
capture and bubble phase of a multi-DOM event. &nbsp;</font>
<br>
<br><font size=2 face="sans-serif">Unfortunately, while my views above
about events not bubbling between DOMs works out well for xforms-select,
it does not work out so well in two other cases.</font>
<br>
<br><font size=2 face="sans-serif">First, sometimes you do want the events
to bubble out of generated content and into the generator.</font>
<br>
<br><font size=2 face="sans-serif">Second, sometimes you only want the
event handler to attach to the generator (repeater) element, not to the
generated elements.</font>
<br>
<br><font size=2 face="sans-serif">For the first case, we can amend the
select1 above slightly to see the problem. &nbsp;Suppose you have this:</font>
<br>
<br><font size=2 face="Courier New">&lt;select1 ref=&quot;desired&quot;&gt;</font>
<br><font size=2 face="Courier New">&nbsp; &nbsp; &lt;label&gt;Pick one
flavor:&lt;/label&gt;</font>
<br><font size=2 face="Courier New">&nbsp; &nbsp; &lt;hint&gt;The color
will depend on what flavor you pick.&lt;/hint&gt;</font>
<br><font size=2 face="Courier New">&nbsp; &nbsp; &lt;itemset nodeset=&quot;../flavor&quot;&gt;</font>
<br><font size=2 face="Courier New">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&lt;label
ref=&quot;.&quot;/&gt;</font>
<br><font size=2 face="Courier New">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&lt;value
ref=&quot;.&quot;/&gt;</font>
<br><font size=2 face="Courier New">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&lt;action
ev:event=&quot;xforms-select&quot;&gt;</font>
<br><font size=2 face="Courier New">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp;&lt;!-- Do some stuff --&gt;</font>
<br><font size=2 face="Courier New">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&lt;/action&gt;
</font>
<br><font size=2 face="Courier New">&nbsp; &nbsp; &lt;/itemset&gt;</font>
<br><font size=2 face="Courier New">&lt;/select1&gt;</font>
<br>
<br><font size=2 face="sans-serif">Now, we would like to be able to say
that the item element is the target of the xforms-hint event so that one
can provide item-specific events. &nbsp;Yet clearly the second select1
above just wants to do a round-up of all xforms-hint events generated by
all item elements and provide a more generic hint. &nbsp;But for that to
work, the xforms-hint targeted at the item would also need to bubble up
to the select1. &nbsp;We really need a fix for this.</font>
<br>
<br><font size=2 face="sans-serif">For the second problem, I have to turn
to the xforms repeat construct, and put a repeat within a repeat:</font>
<br>
<br><font size=2 face="Courier New">&lt;repeat nodeset=&quot;some/nodes&quot;
id=&quot;X&quot;&gt;</font>
<br><font size=2 face="Courier New">&nbsp; &nbsp;&lt;action ev:event=&quot;xforms-scroll-last&quot;&gt;</font>
<br><font size=2 face="Courier New">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&lt;!--
Do some stuff --&gt;</font>
<br><font size=2 face="Courier New">&nbsp; &nbsp;&lt;/action&gt;</font>
<br><font size=2 face="Courier New">&nbsp; &nbsp;&lt;repeat nodeset=&quot;more/nodes&quot;
id=&quot;Y&quot;&gt;</font>
<br><font size=2 face="Courier New">&nbsp; &nbsp; &nbsp; ...</font>
<br><font size=2 face="Courier New">&nbsp; &nbsp;&lt;/repeat&gt;</font>
<br><font size=2 face="Courier New">&lt;/repeat&gt;</font>
<br>
<br><font size=2 face="sans-serif">In the above example, it is clear that
I want to listen for xforms-scroll-last on repeat X. &nbsp;However, I contend
above that another copy of the event listener will be created to listen
for xforms-scroll-last on each wrapper group element generated by the repeat
to represent a &quot;row&quot; of the repeated content in a &quot;table&quot;.
&nbsp;However, when an xforms-scroll-last is dispatched to an instance
of repeat Y, it bubbles up from repeat Y to the wrapper group element,
where we &quot;Do some stuff&quot; that was only intended to happen when
repeat X received the event.</font>
<br>
<br><font size=2 face="sans-serif">In this case I think it is a bit hacky
but again an OK solution to conclude that a listener gets created both
on the repeat in the original document and on each repeat row's wrapper
group element as long as there is an easy way to restrict the handler to
only run in the former case. &nbsp;And again, I realize there is *a* way,
namely adding ev:targetid=&quot;X&quot; but I only added the IDs for the
purpose of discussion and I would prefer to not use IDs. &nbsp;Fortunately,
this is another case that would work out nicely if you added phase=&quot;target&quot;
AND made it the default. &nbsp;Then, the above markup would look the way
it acts, and it would act properly.</font>
<br>
<br><font size=2 face="sans-serif">Cheers,</font>
<br><font size=2 face="sans-serif">John M. Boyer, Ph.D.<br>
STSM: Lotus Forms Architect and Researcher<br>
Chair, W3C Forms Working Group<br>
Workplace, Portal and Collaboration Software<br>
IBM Victoria Software Lab<br>
E-Mail: boyerj@ca.ibm.com &nbsp;<br>
<br>
Blog: </font><a href=http://www.ibm.com/developerworks/blogs/page/JohnBoyer><font size=2 face="sans-serif">http://www.ibm.com/developerworks/blogs/page/JohnBoyer</font></a><font size=2 face="sans-serif"><br>
<br>
</font>
--=_alternative 008189D988257333_=--

Received on Wednesday, 14 November 2007 15:39:20 UTC