Re: [w3c/webcomponents] How should various document internal references work when SVG is being used in shadow DOM (#179)

> It is still unclear to me whether people want <svg:use xlink:href="#test"/> inside shadow DOM to be able to (A) refer test element in light DOM, or (B) test element in shadow DOM, or (C) both? (@smaug---- )

Both have their use cases (which is why I suggested the "search outwards" approach).

If I had to choose one or the other, though, I'd pick (B) for web components.  If a web component contains a complete, self-contained inline SVG within its shadow DOM, cross references within the shadow tree need to work as normal.  Anything else basically means no inline SVG inside web components.

But if hash references in the shadow tree always resolve inside that tree, there are some consequences:
_______________

Consequence 1:

If a web page author wants to use an SVG icon in their web component that references definitions in the main document (i.e., to link from shadow to light), they would need to refer to the main document by its full URL, and deal with any complications from `<base>` and location changes.

Alternatively, an `<svg><use xlink:href="#icon" /></svg>` fragment could be defined in the light tree, and pulled into the shadow tree using a `<slot>`.  I would _assume_ that in this case, since the `<use>` was defined in the light tree, it's attributes would be evaluated in the light tree, similar to how I'd expect this jump link to still work even if I pulled it into a web component shadow widget:

```
<fancy-jump-link>
<a href="#section2">Next Section</a>
</fancy-jump-link>
```

_____________________

Consequence 2:

I would expect that the same rules would apply to other (`xlink:`)`href` attributes inside the shadow DOM. So, if I wanted to generate a separate, completely shadow `<a>` element inside my `<fancy-jump-link>` that would link out to the main document, I would need to use the full document URL, including any base adjustments.

But, this may be a web compat problem of its own by now. I don't know.
_____________________

Consequence 3:

We need to add some magic to `<use>` element shadow trees to get them to work, since nested `<use>` elements that were cloned from the light document need to be able to reference the light tree, to maintain web compatibility. Specifically:

- If a use element references another element in the same document (`<use id="a" xlink:href="#b"/>`), and that second element or its child references a third element elsewhere in the document (`<g id="b"><use xlink:href="#c" /></g>`), the second reference needs to match up correctly to the element in the light document tree (`<g id="c">...</g>`).

The magic required to solve that is to make the URLs in the `<use>` element shadow tree absolute when the elements are cloned, or define a new base URL for the entire subtree. Which happens to be the magic already proposed in the spec for handling `<use>` elements cloned from other documents, so that's not too bad.

But `xlink:href` is the easy part, because it's an attribute and always attached to a specific element. So it's fairly straightforward to apply modifications to the value when the element is cloned.

The harder part will be the `url(#effect)` references in CSS, because CSS properties can inherit from light tree into shadow.

These also need to work for web compatibility:

- If a use element references another element in the same document (`<use id="a" xlink:href="#b"/>`), and that element or its child references a graphical effect elsewhere in the document (`<g id="b" filter="url(#blur)">...</g>`), then the effect needs to be applied on the cloned element.

- If a use element references another element in the same _or another_ document, and the use element has an inheritable graphical effect that references an element elsewhere in the original document  (`<use id="a" xlink:href="#b" fill="url(#pattern)" />`), then the effect needs to be applied on relevant elements in the shadow tree.

Both of those are references from the shadow tree back into the light.

The following should also work (although current web compat is sketchy):

- If a use element references another element in a different file (`<use id="a" xlink:href="icons.svg#b"/>`), and that (cloned) element references an effect elsewhere in its own file, that effect is applied. 

Which means you need to keep track of whether the style property was defined in the light tree and inherited into the shadow, or whether it was defined in a different document and cloned into the shadow tree.

Keeping track of the source file is consistent to how CSS URLs have _traditionally_ been handled, but inconsistent with the new special CSS rules for hash-only URLs. It also means that you can't just think of the use-element shadow tree as having a separate base URL and have everything fall into place.  The current SVG text says that the hash-only CSS URL defined in the other file would be made absolute relative to that file's address as part of the cloning process, so that once it gets to the shadow tree context it is no longer "hash-only".  But that does create an extra complication for implementation.

_______________________

> The question is how xlink:href works today. Does it special case values starting with # or does it parse the value against a base URL? (@annevk) 

For a use element in the light DOM, the `xlink:href` parses against the base URL. That is generally considered Not A Good Thing by web developers, as it breaks the page if you use `<base>`, but also if you push a new URL without using `<base>`. This is the same problem that prompted the new CSS rules (implemented in Chrome) for hash-only.

The [current SVG 2 spec text](https://www.w3.org/TR/SVG2/linking.html#processingURL-absolute) was an attempt to work around this, by resolving the URL against the base URL, and then comparing it against the current base URL of the document to decide whether to treat it as a same-page reference or not.  (But if that could be defined in a more authoritative spec, that would be an improvement, to me.)

Since the current spec text works with the base URL, it doesn't get any better or worse if we use base URLs to define shadow tree URL-resolution behavior.  We'd just need to rewrite it to talk about the "tree" base URL, instead of the "document" base URL.
_______________________

> Note that since `<svg:use>` is defined to use a shadow tree, if we special-case shadow trees it's going to probably behave unexpectedly for nested `<use>` elements, for example. (@emilio) 

Yes, indeed.  We need to handle both cases, and that's not easy, which is why we're talking about adding "magic" to the use-cloning process to make it all fit together.




-- 
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/w3c/webcomponents/issues/179#issuecomment-410067649

Received on Thursday, 2 August 2018 21:06:07 UTC