Implementing <use> without cloning

Fully implementing <use> without cloning content nodes or "render objects"
seems rather difficult. Consider this testcase:

<svg xmlns="http://www.w3.org/2000/svg"
     xmlns:xlink="http://www.w3.org/1999/xlink"
     xmlns:html="http://www.w3.org/1999/xhtml">
  <defs>
    <g id="f" style="display:inherit">
      <foreignObject width="100" height="80" style="display:inherit">
        <html:span style="display:inherit">Hello</html:span>
        <html:span style="display:inherit">Kitty</html:span>
      </foreignObject>
    </g>
  </defs>
  <use x="100" y="100" xlink:href="#f" style="display:block"/>
  <use x="100" y="200" xlink:href="#f" style="display:inline"/>
  <use x="100" y="300" xlink:href="#f" style="display:table-cell"/>
</svg>

For those of you not familiar with CSS, the correct rendering looks like
this:
  Hello
  Kitty

  Hello Kitty

  HelloKitty

The first <use> styles the spans as blocks, so they are placed on separate
lines. The second <use> styles the spans as inline elements, so they are
placed on the same line and the whitespace between them is converted to a
space. The third <use> styles the spans as table cells, and since they're
only separated by whitespace they are placed in the same anonymous table row
and the whitespace is discarded.

Firefox 3 and later display the correct rendering. Opera 10 displays the
first and third <use> as if the spans were inline. Safari 4 displays
nothing. I'd be interested to know whether any other UAs pass this test,
especially ones that claim to implement <use> without cloning.

This testcase is hard because it requires more than just re-resolving style
while painting. The different <use> instances actually need different CSS
boxes created for them. You really don't want to be creating CSS boxes on
the fly while painting ... at least, I don't. (In principle one could create
separate CSS box trees for each <use> instance without cloning content
nodes, but supporting multiple independent box trees for each content node
is a large (potentially very large) increase in complexity, and cloning the
content nodes is probably less expensive than creating the box trees, so
this approach would add a lot of complexity for little gain.)

If the spec is going to allow implementing <use> without cloning, which I
think is desirable, then how should the behaviour of this testcase be
altered? One option is to simply say that <foreignObject> in <use> instances
renders nothing. Another option is to say that the children of
<foreignObject> in a <use> instance are given the style of the original
nodes (which I think guarantees that the original CSS box tree can be used
in every instance).

Rob
-- 
"He was pierced for our transgressions, he was crushed for our iniquities;
the punishment that brought us peace was upon him, and by his wounds we are
healed. We all, like sheep, have gone astray, each of us has turned to his
own way; and the LORD has laid on him the iniquity of us all." [Isaiah
53:5-6]

Received on Wednesday, 14 October 2009 21:38:07 UTC