Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How should various document internal references work when SVG is being used in shadow DOM #179

Closed
hayatoito opened this issue Jul 6, 2015 · 87 comments

Comments

@hayatoito
Copy link
Contributor

Title: [Shadow] How should various document internal references work when SVG is being used in shadow DOM (bugzilla: 27380)

Migrated from: https://www.w3.org/Bugs/Public/show_bug.cgi?id=27380


comment: 0
comment_url: https://www.w3.org/Bugs/Public/show_bug.cgi?id=27380#c0
Olli Pettay wrote on 2014-11-20 12:37:34 +0000.

@hayatoito
Copy link
Contributor Author

@smaug---- , if you have a change, could you elaborate this issue?

@annevk
Copy link
Collaborator

annevk commented Mar 17, 2016

I think this is similar to the fragment identifier issue and we should resolve it in the same way. E.g., filter: url(#element-id) should not cross the shadow boundary.

@hayatoito
Copy link
Contributor Author

I see. I think we can agree that it should not cross the shadow boundary.
If SVG spec is using a node tree correctly, I do not think we need any action.

@smaug----
Copy link

So stuff like

<defs>
    <linearGradient id="Gradient01">
      <stop offset="20%" stop-color="#39F" />
      <stop offset="90%" stop-color="#F3F" />
    </linearGradient>
  </defs>
  <rect x="1cm" y="1cm" width="6cm" height="1cm" 
        fill="url(#Gradient01)"  />

won't be possible in shadow DOM. Doesn't that make it rather hard to use any real world SVG within Shadow DOM? (perhaps that is ok?)

But yes, I guess that is the same as filter: url(#element-id) issue.

@annevk
Copy link
Collaborator

annevk commented Mar 18, 2016

As long as the SVG is inside the shadow tree, it will work, no?

@smaug----
Copy link

It does? Then I've missed some spec change which makes that fragment identifier to work.

@annevk
Copy link
Collaborator

annevk commented Mar 18, 2016

Perhaps the language in SVG assumes a document tree at the moment, but it seems reasonable for that to work in the same way that <form> can work when fully contained in a shadow tree, no?

@smaug----
Copy link

Sure. But need to make sure the specs actually end up defining that.
(though, not sure I understand where in <form> handling there are random urls being used as id refs)

@jwatt
Copy link

jwatt commented May 13, 2016

Ah, I asked about this here: http://www.w3.org/mid/89c91562-7e1b-42f3-6cfa-2e651757f32b@jwatt.org

Good to see this has already been discussed.

@devingfx
Copy link

I assume that is the same issue as inline <svg> symbol library :

<!DOCTYPE html>
<html>
	<head>
		<svg xmlns="http://www.w3.org/2000/svg" version="1.1" 
			 xmlns:xlink="http://www.w3.org/1999/xlink">
			<symbol id="icon-cog">
				<path d="...."/>
			</symbol>
			<symbol id="icon-close">
				<path d="...."/>
			</symbol>
		</svg>
	</head>
	<body>
		<custom-element>
			#shadow-root
				<svg xmlns="http://www.w3.org/2000/svg" 
					 xmlns:xlink="http://www.w3.org/1999/xlink">
					<use xlink:href="#icon-cog"/>
				</svg>
				<svg xmlns="http://www.w3.org/2000/svg" 
					 xmlns:xlink="http://www.w3.org/1999/xlink">
					<use xlink:href="#icon-close"/>
				</svg>
			/shadow-root
		</custom-element>
	</body>
</html>

I would say here that the fragment identifier should cross shadow boundary in this case.
By replacing the <svg> library by another one (loaded via xhr) following the same symbol naming,
you can swith he whole app icon set on the fly.
Theme authors can distribute several icons set this way, following the use-land library icon's namming
convention it's targetting.

The workaround to this if not crossing is to reference an external file like so:

<!DOCTYPE html>
<html>
	<head>
	</head>
	<body>
		<custom-element>
			#shadow-root
				<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 24 24"
					 onclick="root.toggleMenu( settingsMenu )">
					<use xlink:href="icons/library.svg#icon-cog"/>
				</svg>
				<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 24 24"
					 onclick="window.close()">
					<use xlink:href="icons/library.svg#icon-close"/>
				</svg>
			/shadow-root
		</custom-element>
	</body>
</html>

But if you need to change the <svg> library on the fly, you'll have to loop on each node to find shadow root to find nested <svg><use> and change the xlink:href manually, what can be a pain ...


I assume fragment identifier issue have to resolve the same way for all use cases, so maybe it's not possible to
specify that "fragment identifier don't cross boundaries, but not in case of embed svg"

I don't have recommendation here, I'm just pointing out a use case to take care of for this issue !

@rniwa
Copy link
Collaborator

rniwa commented Jan 23, 2017

SVG use element is indeed an interesting use case to consider. We probably need to come up with a new syntax / feature to make it work across shadow boundaries.

@yGuy
Copy link

yGuy commented Aug 4, 2017

With the advent of the implementations of Shadow DOM, this needs to be adressed: Devs who are trying to use the Shadow DOM cannot use non-trivial SVG at the same time, because Safari does not implement (or probably rather "actively disables") SVG Use elements inside shadow trees: https://bugs.webkit.org/show_bug.cgi?id=174977

They refer to this bug and say that it is because of the missing spec that they cannot implement svg use elements inside shadow doms.

I disagree, though and agree with @annevk that at least as long as the SVG in question is fully contained inside a shadow tree, it should work just like it would work at the root document level.
However because of the (missing clarification in the) spec, it does not work in Safari.

Could you please reconsider the priority of this bug? Because without a resolution web developers will either have to make the choice between not using Shadow Dom, not using SVG, and not using Safari. I am sure they will decide not to use Shadow Dom, which would be a pity.

@hayatoito
Copy link
Contributor Author

  1. Regarding this:

as long as the SVG in question is fully contained inside a shadow tree, it should work just like it would work at the root document level.

I think everyone would agree that this should work. What clarification is required in SVG spec?

  1. Regarding this:

I would say here that the fragment identifier should cross shadow boundary in this case.

This is questionable. I object to it.

@annevk
Copy link
Collaborator

annevk commented Aug 8, 2017

https://drafts.fxtf.org/filter-effects/#FilterProperty seems to define this property (though maybe it's defined elsewhere too?) and it's basically super vague.

@yGuy
Copy link

yGuy commented Aug 8, 2017

I think everyone would agree that this should work. What clarification is required in SVG spec?

Unfortunately the Safari team disagrees here. Their implementation does not work for the "simple" case and they say it is because of the spec not being clear enough here.

@rniwa
Copy link
Collaborator

rniwa commented Aug 8, 2017

Since filter property as well as use element use a URL to reference an element, I don't think we can make it work without defining how an element inside a shadow tree can be referenced using a URL.

@annevk
Copy link
Collaborator

annevk commented Aug 8, 2017

Does any browser actually support full URLs there or just local fragment references? I thought it is mostly the latter, but if it isn't this is indeed more complicated.

@rniwa
Copy link
Collaborator

rniwa commented Aug 9, 2017

Firefox definitely supports referencing a fragment in another file although Safari & Chrome don't support that.

@yGuy
Copy link

yGuy commented Aug 9, 2017

@rniwa - while I agree that it is not defined how it should work (and I also believe that probably the best solution would be to not make it work at all) to reference a fragment inside another document buried in a shadow dom or inside another shadow tree in the same dom, my concern right now is that the Safari/Webkit team claims that the SVG spec is not even clear enough about local fragments inside the same shadow tree dom. Please correct me (and them) if I'm wrong, but IMHO at least this should work, or shouldn't it:

anywhere on the page (be it inside a closed, or open shadow dom tree or at the top-level) this must work:

<svg width="10cm" height="3cm" viewBox="0 0 100 30" version="1.1"
     xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
  <defs>
    <rect id="MyRect" width="60" height="10"/>
  </defs>
  <use x="20" y="10" xlink:href="#MyRect" />
</svg>

(slightly stripped down version from here https://www.w3.org/TR/SVG/struct.html#UseElement )

However according to them "because of the unclear spec" this svg does not work inside Safari in a shadow DOM.

This makes all of our SVGs break if they are used inside a shadow dom in Safari, and thus all of our customers cannot use shadow dom in their products if they need to target Safari and I would greatly appreciate it if you could somehow make a clear statement that at least this use-case must work according to the spec so that they will adjust their current implementation.

Thank you!

@rniwa
Copy link
Collaborator

rniwa commented Aug 9, 2017

My concern right now is that the Safari/Webkit team claims that the SVG spec is not even clear enough about local fragments inside the same shadow tree dom. Please correct me (and them) if I'm wrong, but IMHO at least this should work, or shouldn't it:

You keep saying that this is a claim but it's not a claim. It's a fact that there is no spec at W3C that either defines or mandates the behavior you're describing. The fact Blink behaves in the way you'd like is almost a coincidence.

anywhere on the page (be it inside a closed, or open shadow dom tree or at the top-level) this must work

I'm not at all certain that everyone would agree to that proposition. xml:href in SVG use element uses an URL and an URL has a very well defined semantics. To make the behavior you're describing work, we'd have to override its semantics so that #foo references another node within the same shadow tree with the ID value of foo. If we're making this change for all fragment URLs then that would have serious implications on anchor elements and any other SVG and HTML elements that use href and xml:href attributes. On the other hand, introducing an arbitrary inconsistency like making this semantics change only to SVG use element is also bad for the Web platform as the whole.

@yGuy
Copy link

yGuy commented Aug 9, 2017

OK, thanks a lot for the clarification. So I think it should be clearly communicated and stated that SVGs and shadow DOM don't work together nicely if implemented according to the current spec and that devs cannot rely on the implementations that currently do support this "against the spec". Even Anne van Kesteren thought that this feature should work according to the current spec if I interpret this comment correctly: #179 (comment) - without a clear statement how should the majority of "normal devs" understand the current situation?

SVG 'use' elements are a very important part for SVGs, at least if you use SVG to programmatically create vector graphics. So if they don't actually work in shadow DOMs that is a huge problem for shadow doms, IMHO: Shadow doms are used for creating and encapsulating complex web components. If those components cannot use sophisticated vector graphics, then this is a blocker for many component developers (like us) and they won't be adopting shadow doms, which would be a pity because they would benefit the most from shadow doms.

I understand that it may be difficult to change the spec so that this will work formally, but I think that absolutely needs to be done (and that's basically what this ticket is all about). It's almost as if you had decided not to support a rather basic feature like background colors or margins in shadow doms - people will choose to have background colors and margins over using shadow doms if that is the only way they can get background colors and margins to work. I say that if you want shadow dom to become widely adopted, this SVG use-case absolutely needs to be supported, whatever it takes.
Thank you!

@annevk
Copy link
Collaborator

annevk commented Aug 9, 2017

The problem is that SVG uses URLs for both local and non-local references and most browsers only implement the local part. In CSS at least there was a plan to make these local reference special (URLs starting with #) and that probably applies here too given it's a CSS property. @tabatkins?

It seems that hasn't really propagated to all specifications yet.

@tabatkins
Copy link

Oh gosh, I didn't even think about the effect of scoped-IDs on frag-references. I guess it's the same issue as dealing with @font-face-defined names inside of a shadow tree.

So yeah, frag urls are special in url() - https://drafts.csswg.org/css-values/#local-urls. They stay fragments and are always treated as "local" to the referencing document no matter what the base url is.

It's a small hop from there to specifying that, within a shadow tree, they are scoped to referring only to the IDs defined in the shadow. I'm fine with that - is that how we want to proceed? If so, I can bring it to the CSSWG and get it approved.

@annevk
Copy link
Collaborator

annevk commented Aug 10, 2017

@tabatkins yeah, that's basically the proposal. Search within your tree for IDs not within your document.

@rniwa
Copy link
Collaborator

rniwa commented Aug 10, 2017

I don't think that solves SVG use element since it uses xml:href. Overriding its semantics inside a shadow tree is going to be quite ugly unless we're going to change it for everything else.

@yGuy
Copy link

yGuy commented Aug 10, 2017

:-(

Better "ugly and working" than "nice and unusable", though, IMHO.

@waterplea
Copy link

waterplea commented Jan 14, 2019

I am working on a library of UI components for Angular. I use SVG icons declared on top of the page and referenced with use tag. When I tried to convert my library components to Web Components so no Angular is required I was very sad to find that it doesn't work with Shadow DOM. I understand the concerns, but practicality of this approach is just huge. This thought first mentioned way above by @devingfx :

I assume that is the same issue as inline <svg> symbol library :

I really hope this would be resolved.

@ekashida
Copy link

Rough consensus at TPAC F2F: We would take Tab's proposal in #179 (comment) excluding (3) and have an explicit list of elements and attributes to which this behavior would apply since this would not make sense for things like href in anchor or area element.

@rniwa Was there any discussion around behavior for fragment-only url values for anchor/area href attributes? Your comment seems to imply that these could potentially reference elements outside the shadow and I'm curious if this is the case.

@rniwa
Copy link
Collaborator

rniwa commented Mar 26, 2019

@rniwa Was there any discussion around behavior for fragment-only url values for anchor/area href attributes? Your comment seems to imply that these could potentially reference elements outside the shadow and I'm curious if this is the case.

I don't think anyone thought allowing references to a node outside one's shadow tree was a good idea at least during F2F.

@yGuy
Copy link

yGuy commented Mar 28, 2019

Don't know whether this is the right place to discuss this, but I think it is at least related - sorry for the noise if this is the wrong place:

The CanvasRenderingContext#filter property can also be used to reference filters declared in SVG and it also uses the url syntax to reference filters declared in SVG.

I would hope that it works like this: at least if the canvas which provided the canvascontext lives in the same shadow DOM as the SVG filter, a relative url should resolve to the filter in the SVG. If the canvas image is currently not in the DOM, I don't see how this could ever resolve to a filter declared in a shadow tree, however.

TBH I haven't tested this, myself; it's implemented in FF and Chrome, only, so far, and I don't know whether there is a spec for this with respect to shadow dom. I just played with that feature and loved it when it works and I was hoping that it would still work inside custom components.

@annevk
Copy link
Collaborator

annevk commented Mar 28, 2019

@yGuy thanks for spotting that! Could you please file an issue against whatwg/html? It should be specified right there and currently has a rather vague "same document" sentence that is broken. I agree with you on how this should work. If you're willing to write tests per https://github.com/web-platform-tests/wpt for this that might help ensure browsers get it correct sooner. I'd be happy to help guide you in that.

@waterplea
Copy link

@rniwa maybe there could be some specific syntax allowing shadow DOM items to reach out to search segments outside their shadow tree? Seems to me that reaching out shouldn't be that bad, at least as explicitly specified intention, it's not like reaching in to mess with isolated component.

@rniwa
Copy link
Collaborator

rniwa commented Jul 18, 2019

@rniwa maybe there could be some specific syntax allowing shadow DOM items to reach out to search segments outside their shadow tree? Seems to me that reaching out shouldn't be that bad, at least as explicitly specified intention, it's not like reaching in to mess with isolated component.

Perhaps. The trick is to come up with a proposal that's backwards compatible, which might be tricky.

@devingfx
Copy link

devingfx commented Jul 20, 2019

@rniwa maybe there could be some specific syntax allowing shadow DOM items to reach out to search segments outside their shadow tree? Seems to me that reaching out shouldn't be that bad, at least as explicitly specified intention, it's not like reaching in to mess with isolated component.

Perhaps. The trick is to come up with a proposal that's backwards compatible, which might be tricky.

element.attachShadow({
    mode: 'open',
    delegatesFocus: true,
    xlink: 'parent',
    cssPassThrough: true
})

;) I donno how to write specs ...

[Edit]: Maybe just ShadowRootInit needs to be agmented...

dictionary ShadowRootInit {
  required ShadowRootMode mode;
  ShadowRootXLinkMode xlink;
  boolean ShadowRootCSSMode cssPassThrough;
  boolean ShadowRootFocusMode delegatesFocus;
};

enum ShadowRootXLinkMode { "parent", "closed" };

@rniwa
Copy link
Collaborator

rniwa commented Jul 23, 2019

Please file a new issue to discuss that kind of proposal. This issue is used as a meta bug for tracking issues pertaining internal referencing used in SVG.

moz-v2v-gh pushed a commit to mozilla/gecko-dev that referenced this issue Apr 28, 2020
…trees. r=smaug

Other UAs allow this, and it seems in the general consensus of
WICG/webcomponents#179.

This matches WebKit's behavior. Blink, for some reason shows red on the
test-case, probably because they're not doing quite this, but they
manage to render masks inside the display: none symbol element or such.

Differential Revision: https://phabricator.services.mozilla.com/D72610
xeonchen pushed a commit to xeonchen/gecko that referenced this issue Apr 28, 2020
…trees. r=smaug

Other UAs allow this, and it seems in the general consensus of
WICG/webcomponents#179.

This matches WebKit's behavior. Blink, for some reason shows red on the
test-case, probably because they're not doing quite this, but they
manage to render masks inside the display: none symbol element or such.

Differential Revision: https://phabricator.services.mozilla.com/D72610
gecko-dev-updater pushed a commit to marco-c/gecko-dev-comments-removed that referenced this issue Apr 28, 2020
…trees. r=smaug

Other UAs allow this, and it seems in the general consensus of
WICG/webcomponents#179.

This matches WebKit's behavior. Blink, for some reason shows red on the
test-case, probably because they're not doing quite this, but they
manage to render masks inside the display: none symbol element or such.

Differential Revision: https://phabricator.services.mozilla.com/D72610

UltraBlame original commit: 8efff752175e177108adceddb73a60f98f8cdd27
gecko-dev-updater pushed a commit to marco-c/gecko-dev-wordified-and-comments-removed that referenced this issue Apr 28, 2020
…trees. r=smaug

Other UAs allow this, and it seems in the general consensus of
WICG/webcomponents#179.

This matches WebKit's behavior. Blink, for some reason shows red on the
test-case, probably because they're not doing quite this, but they
manage to render masks inside the display: none symbol element or such.

Differential Revision: https://phabricator.services.mozilla.com/D72610

UltraBlame original commit: 8efff752175e177108adceddb73a60f98f8cdd27
gecko-dev-updater pushed a commit to marco-c/gecko-dev-wordified that referenced this issue Apr 28, 2020
…trees. r=smaug

Other UAs allow this, and it seems in the general consensus of
WICG/webcomponents#179.

This matches WebKit's behavior. Blink, for some reason shows red on the
test-case, probably because they're not doing quite this, but they
manage to render masks inside the display: none symbol element or such.

Differential Revision: https://phabricator.services.mozilla.com/D72610

UltraBlame original commit: 8efff752175e177108adceddb73a60f98f8cdd27
@mfreed7
Copy link

mfreed7 commented Mar 30, 2021

From #179 (comment), this issue really contains three sub-issues:

Here are the current blockers for this issue:

Of those, the first one seems to be resolved, down to actually modifying the spec. I.e. browsers agree on behavior - SVG elements can reference other elements within the same shadow tree. Is that correct?

The second one is about expanding fragment references to be able to cross shadow boundaries. I'm not sure there's appetite for that change or not, but there has been very little discussion on that issue.

The last one really isn't about SVG specifically, but is about other global name defining things (e.g. @font-face). That one is very much unsolved.

Is the above an accurate summary of the state of this issue? If so, I would propose closing this issue, since the sub-parts are well-tracked in the linked issues.

@annevk
Copy link
Collaborator

annevk commented Apr 13, 2021

That seems correct to me, thanks for summarizing. @rniwa?

@rniwa
Copy link
Collaborator

rniwa commented Apr 13, 2021

Yeah, I think that's accurate although we need some way to track all those CSS issues in this issue tracker somehow since it doesn't seem like any progress has been made in terms of spec work there.

@annevk
Copy link
Collaborator

annevk commented Apr 13, 2021

Alright, happy to keep this open with that understanding. If someone wanted to they could also create a new issue containing those pointers and we could close this. Either way.

@rniwa
Copy link
Collaborator

rniwa commented Apr 13, 2021

Yeah, we really need a better way of tracking all these issues scattered across many different WG's issue trackers.

Maybe we can have a wiki page with a list of issues instead? We won't be able to cross-reference though so it has some downsides compared to the status quo.

@rniwa
Copy link
Collaborator

rniwa commented Apr 20, 2023

Closing this in favor of #772

@rniwa rniwa closed this as completed Apr 20, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests