Bug 15409 - [Shadow]: Consider exposing shadow DOM subtree stack in the API
[Shadow]: Consider exposing shadow DOM subtree stack in the API
Status: RESOLVED DUPLICATE of bug 19562
Product: WebAppsWG
Classification: Unclassified
Component: Component Model
unspecified
PC All
: P2 normal
: ---
Assigned To: Dimitri Glazkov
public-webapps-bugzilla
:
Depends on:
Blocks: 18428
  Show dependency treegraph
 
Reported: 2012-01-03 23:05 UTC by Dimitri Glazkov
Modified: 2012-10-16 21:16 UTC (History)
5 users (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Dimitri Glazkov 2012-01-03 23:05:32 UTC
This would enable defining decorator attachment/detachimgn purely as stack manipulation using standard API.
Comment 1 Dominic Cooney 2012-01-05 04:20:04 UTC
I think that this is a bad idea, because it means that script will be able to get a reference to shadow DOM of applied decorators, so the spec would have to specify what modifications mean (do they apply to all decorators? Just that one? Some shadow root DOM subtrees are not mutable?)
Comment 2 Dimitri Glazkov 2012-01-18 18:28:36 UTC
From bug 15611:

> Read only access to every ShadowRoot must be provided for each element to
> support tools. Without it something like Readability wouldn't be possible
> because there's no way to access the content of the page that's inside the
> shadow DOM.
> 
> This also makes tools like Google Feedback impossible to build because there's
> no way to access the nodes  in the shadow DOM for rendering in screenshots.
> Without the addition of CanvasRenderingContext2D #renderElement() this cripples
> HTML screenshot tools.
Comment 3 Dominic Cooney 2012-01-19 02:14:42 UTC
I think this question needs to be approached as a trade-off. If the API provides access to existing Shadow DOM of a host element, it permits some scenarios (mentioned above in Comment 2), it prevents or complicates other scenarios (also mentioned above, in Comment 1).

(In reply to comment #2)
> From bug 15611:
> 
> > Read only access to every ShadowRoot must be provided for each element to
> > support tools. Without it something like Readability wouldn't be possible
> > because there's no way to access the content of the page that's inside the
> > shadow DOM.

Readability seems to build another user agent inside the user agent. Whether a UA needs to access Shadow DOM depends on what the UA intends and how Shadow DOM is used. In the case of Readability, if authors use Shadow DOM for presentational aspects, or for app widgets, there’s no problem. There’s nothing to "read" in those.

Other tools, for example UI builders, could access Shadow DOM simply by arranging that the page cooperate with the tool by sticking a "shadow" property on elements with Shadow DOM when in "design mode" or something like that.

> > This also makes tools like Google Feedback impossible to build because there's
> > no way to access the nodes  in the shadow DOM for rendering in screenshots.
> > Without the addition of CanvasRenderingContext2D #renderElement() this cripples
> > HTML screenshot tools.

I would expect rendering an element that has shadow DOM to a canvas should render the shadow DOM, so that the rendering matches what is on-screen. So I don’t think the canvas aspect of this is relevant.
Comment 4 Elliott Sprehn 2012-01-19 02:52:13 UTC
(In reply to comment #3)
> 
> Readability seems to build another user agent inside the user agent. Whether a
> UA needs to access Shadow DOM depends on what the UA intends and how Shadow DOM
> is used. In the case of Readability, if authors use Shadow DOM for
> presentational aspects, or for app widgets, there’s no problem. There’s nothing
> to "read" in those.
> 
> Other tools, for example UI builders, could access Shadow DOM simply by
> arranging that the page cooperate with the tool by sticking a "shadow" property
> on elements with Shadow DOM when in "design mode" or something like that.

And what of accessibility tools that swap out parts of the page with ones that are easier to access, or change the font size of specific elements and embed a slider control?

I think assuming developers will use components only for "app widgets" is not a good assumption, and I also think the definition of "app widget" is very vague. It's not unreasonable to think the NY Times app would have an "article pane widget" that encompasses the entire story area.

I'm not sure it's reasonable to assume an unwritten standard for accessing the properties either. In a real app where you embed lots of third party widgets (ex. jQuery) many of them might not be coded to expose the shadow property, or might use an inconsistent name. 

> 
> > > This also makes tools like Google Feedback impossible to build because there's
> > > no way to access the nodes  in the shadow DOM for rendering in screenshots.
> > > Without the addition of CanvasRenderingContext2D #renderElement() this cripples
> > > HTML screenshot tools.
> 
> I would expect rendering an element that has shadow DOM to a canvas should
> render the shadow DOM, 

Exactly. :)

> so that the rendering matches what is on-screen. So I
> don’t think the canvas aspect of this is relevant.

Because the shadow DOM is not accessible there is no way to render it to a canvas. Google Feedback is implemented by walking the DOM and rendering each node one by one manually on a canvas. This is needed because drawElement() doesn't exist, and it may never exist because of security implications.

For a public example of this see: http://html2canvas.hertzen.com/

There's plenty of other implications of not exposing the DOM too. Like what happens to elementFromPoint() ? Lots of tools are built with point and click on a web page where you select a DOM node. If the shadow DOM is inaccessible then all those tools break because even though the user sees the map component in Google Maps, when we execute elementFromPoint() we get something entirely different, and there's no way to ever get to the real DOM they clicked on down there (ex. an address bubble).

For an example go to http://www.youtube.com/ and at the bottom of the page click "Report a bug". Then hover over items on the page and note the "smart" highlighting.
Comment 5 Dominic Cooney 2012-01-19 05:23:00 UTC
(In reply to comment #4)
> And what of accessibility tools that swap out parts of the page with ones that
> are easier to access, or change the font size of specific elements and embed a
> slider control?

What is the specific problem in this case?
 
> I think assuming developers will use components only for "app widgets" is not a
> good assumption, and I also think the definition of "app widget" is very vague.
> It's not unreasonable to think the NY Times app would have an "article pane
> widget" that encompasses the entire story area.

If a news site use Shadow DOM to implement an article pane widget, it would be well advised to put the content of the article in the page (as usual), put the presentation aspects in Shadow DOM, and project the content into the right place in the presentation using the <content> element at the insertion point <http://dvcs.w3.org/hg/webcomponents/raw-file/tip/spec/shadow/index.html#dfn-insertion-point>. This means that the content will be accessible to user agents that don’t understand Shadow DOM, like search engine crawlers and older browsers.

> I'm not sure it's reasonable to assume an unwritten standard for accessing the
> properties either. In a real app where you embed lots of third party widgets
> (ex. jQuery) many of them might not be coded to expose the shadow property, or
> might use an inconsistent name. 

Yes, it would rely on a convention established by the widget toolkit. Some kinds of tools—a client application which embeds a web browser for manipulating web content, for example—could use an out-of-band means to expose Shadow DOM to the tool.

> Because the shadow DOM is not accessible there is no way to render it to a
> canvas. Google Feedback is implemented by walking the DOM and rendering each
> node one by one manually on a canvas. This is needed because drawElement()
> doesn't exist, and it may never exist because of security implications.

I understand why this is an issue now. Presumably the page that is embedding this component could also allow it to hook ShadowRoot creation and hence have access to Shadow DOM that way?

> There's plenty of other implications of not exposing the DOM too. Like what
> happens to elementFromPoint() ?

I expect per upper-bound encapsulation <http://dvcs.w3.org/hg/webcomponents/raw-file/tip/spec/shadow/index.html#upper-boundary-encapsulation> means that the host element would be returned.

This is a really interesting issue—from the point of view of script defining an abstraction, it seems reasonable to expect it can do elementFromPoint() to find elements within the abstraction. The spec sometimes casually uses language like “scoped to subtrees”. Maybe this needs to be an explicit concept so some API can be shared by Document and ShadowRoot, ie permit document.elementFromPoint as well as shadowRoot.elementFromPoint, the latter of which can return elements within the shadow root.

For example:

interface TreeScope {
  Element elementFromPoint(…);
  …
}
interface Document implements TreeScope;
interface ShadowRoot implements TreeScope;

> Lots of tools are built with point and click on
> a web page where you select a DOM node. If the shadow DOM is inaccessible then
> all those tools break because even though the user sees the map component in
> Google Maps, when we execute elementFromPoint() we get something entirely
> different, and there's no way to ever get to the real DOM they clicked on down
> there (ex. an address bubble).

Shadow DOM provides an encapsulation mechanism, however the extent of encapsulation is under the control of the author:

• Use of Shadow DOM in pages is not mandated :). So this status quo will continue to work for pages that want to continue doing it that way.
• Some may make their Shadow DOM accessible though a JavaScript property.
• Another pattern is to use nested Shadow DOM and return references to elements in these “holes”, for limited access to parts of Shadow DOM.
• Some pages may want to use Shadow DOM to hide presentation aspects; they can do that.

> For an example go to http://www.youtube.com/ and at the bottom of the page
> click "Report a bug". Then hover over items on the page and note the "smart"
> highlighting.

Since the embedding page apparently completely trusts the script that does the highlighting, they could cooperate to expose the Shadow DOM of the page. For example, the script library could do something like:

var shadows = new WeakMap();
(function () {
  var realCtor = ShadowRoot;
  ShadowRoot = function (host) {
    var shadow = realCtor(host);
    var hostShadows = shadows.get(host);
    if (!hostShadows) {
      hostShadows = [];
      shadows.set(host, hostShadows);
    }
    hostShadows.push(shadow);
    return shadow;
  };
})();

and consult shadows to get the Shadow DOM of a particular element.

I understand that there’s a tradeoff here; my gut feeling is that making Shadow DOM not accessible by default does not break as many scenarios as you think, and it enables some useful scenarios too, so I think the spec as written currently gets the tradeoff right.
Comment 6 Dimitri Glazkov 2012-01-31 22:00:24 UTC
Another interesting point here is testability, such as the ability to make programmatic assertions about shadow DOM.
Comment 7 Dimitri Glazkov 2012-01-31 22:01:04 UTC
Also, being able to remove subtrees from the stack seems interesting. Needs a good use case.
Comment 8 Dimitri Glazkov 2012-10-16 21:16:41 UTC
Bug 19562 is now tracking the continuing quest.

*** This bug has been marked as a duplicate of bug 19562 ***