Skip to content

Latest commit

 

History

History
287 lines (187 loc) · 13.4 KB

shadow-dom-v1-in-blink.md

File metadata and controls

287 lines (187 loc) · 13.4 KB

Shadow DOM v1 in Blink

Hayato Ito hayato@google.com

This document summarizes what "Shadow DOM v1" means and its status in Blink.

Last update: <2015-11-12 Thu>

What is Shadow DOM?

Shadow DOM is one of the pieces of Web Components. Numerous online resources about Web Components are available. I recommend http://webcomponents.org/, which is well-maintained.

What is Shadow DOM v1? Does v represents for version? I thought that Shadow DOM spec is "Living Standard".

Shadow DOM spec should be considered as Living Standard. HTML Standard and DOM Standard have already adapted Living Standard model.

You could read v1 as version 1, however, please don't take it seriously. We, browser vendors, need a good terminology which represents something on which all of us can agree to implement Shadow DOM. v1 is a convenient term in a discussion.

If you are uncomfortable with v1, you can think it as p1, priority 1. I am using v1 label for an issue if the issue must be resolved asap so other browser vendors can start to implement Shadow DOM. There is no extra meaning with v1 other than that.

Relevant Links:

What is Shadow DOM v2?

As you can imagine, there is no significant meaning for v2 label. I am using v2 label for a spec issue if the issue doesn't need to be resolved soon.

You can consider v2 as "fix it later". v2 is also a convenient term in the discussion because we are already using v1. We can say something like: "Let's defer it to v2 since we can consider it later".

Now I'm focusing on solving all Shadow DOM v1 issues because it might block other vendors to implement Shadow DOM.

What's the status of Shadow DOM in Blink?

In short:

  1. Shadow DOM v0: Supported. Blink shipped Shadow DOM in M35. Let me call what Blink is shipping now v0 so we can distinguish it from v1. v0 will be deprecated once Blink supports v1.
  2. Shadow DOM v1: In development.

What's difference between v0 and v1?

TODO(hayato): This list is incomplete as of 2015-10-09. Update the list and add more links for details.

Does Blink continue to support v0? You said v0 will be deprecated. Do you have a schedule?

WARNING: Regarding with a date, the following is a very rough estimate and is likely to change. I hope I could give you more precise schedule after I finish to implement the prototype of v1.

A tentative schedule to deprecate Shadow DOM v0 is:

  1. [2015 Q3 (Done at M45)] Deprecate Multiple Shadow Roots

  2. [2015 Q3 (Done at M45)] Deprecate /deep/ and ::shadow

  3. [2016 Q1] Finish the implementation of Shadow DOM v1 (guarded by ShadowDOMV1 runtime flag) so user can experiment v1 in Blink.

    • Intent to Implement

    • TODO(hayato): Decide the mandatory features of v1 which we should ship at first. Some of the features can be implemented later as long as an interoperability risk is low.

  4. [2016 Q2] Ship (the essential parts of) Shadow DOM v1 in Blink

    • TODO(hayato): What's the criteria of shipping? How can we make sure that the spec is stable enough?
  5. Wait for major libraries, such as Polymer, to switch to use Shadow DOM v1 and be shipped.

  6. [2016 Q4 or later] Send an "Intent to Deprecate: Element.createShadowRoot()" to blink-dev.

    • TODO(hayato): Deprecate all v0 related APIs together?
      • e.g. Deprecate event.path at this timing?
  7. [2017 or later] Send an "Intent to Remove: Shadow DOM v0" to blink-dev if we can feel it's ready to remove.

How v0 and v1 can interact each other in the transition period? It looks they can not be used at the same time in the same document.

In the transition period from v0 to v1, it is highly expected that one document would happen to mix web components based on v0 and web components based on `v1. Users might want to mix third-party libraries in their web pages. To support such a situation, I've decided to support both, v0 and v1, co-exist in the same document in Blink.

Because the Shadow DOM spec is inappropriate place to explain how v0 and v1 interact each other, let me explain its behavior, as an unofficial spec, here.

Disclaimer: This is a tentative plan. If I encounter a technical difficulty to support both in the same document, I might change the plan. In any cases, I'll do the best effort to continue to support v0 in the transition time even after v1 comes to Blink.

###Rule 1) A V0 shadow tree, created by createShadowRoot, supports only an insertion point (<content>), but it doesn't support a slot.

###Rule 2) A v1 shadow tree, created by attachShadow, supports only a slot (<slot>), but it doesn't support an insertion point.

What this means is:

  • A <slot> element in v0 shadow tree never behave as a slot. That would behave as if it were a HTMLUnknownElement.
  • A <content> element in v1 shadow tree never behave as an insertion point. That would behave as if it were a HTMLUnknownElement.

Example: <slot> is used in v0 shadow tree (You shouldn't do that!):

[document tree]
<div id=host1>
  <div id="a" slot="slotA">

  [shadow tree 1] // a child tree of document tree, created by host1.createShadowRoot()
  <shadow-root>
    <slot name="slotA">   // This doesn't work as intended. Don't use <slot> in v0 shadow tree.
    <content select="#a"> // This works as intended. #a is distributed to this insertion point.

Example: <content> is used in v1 shadow tree. (You shouldn't do that!):

[document tree]
<div id=host1>
  <div id="a" slot="slotA">

  [shadow tree 1]  // a child tree of document tree, created by host1.attachShadow(..)
  <shadow-root>
    <slot name="slotA">    // This works as intended. #a is assigned to this slot.
    <content select="#a">  // This doesn't work as intended. Don't use <content> in v1 shadow tree.

I hope this is a reasonable restriction for most users. By introducing this simple restriction, we don't have to remember the order of precedence in selecting nodes if both <slot> and <content> are used in in the same shadow tree.

###Rule 3) A tree of trees supports a distribution across v0 and v1 shadow trees, called an unified distribution.

Let's explain what this means by examples.

Example): The parent tree is a v0 shadow tree, and the child tree is a v1 shadow tree.

[document tree]
<div id=host1>
  <div id="a">


  [shadow tree 1]  // a child tree of document tree, created by host1.createShadowRoot()
  <shadow-root>
    <div id=host2>
      <content id="c" select="#a" slot="slotA">


      [shadow tree 2]  // a child tree of shadow tree 1, created by host2.attachShadow(..)
      <shadow-root>
        <slot id="s" name="slotA">

The distribution would be:

c.getDistributedNodes == [a]  // As usual
c.assignedSlot == s   // content can be assigned to a slot. This won't be surprising.
// s.getDistributedNodes != [c]
s.getDistributedNodes == [a]   // If a <content> is assigned to a slot,  <content> would act like a *slot*.
a.getDestinationInsertionPoints == [c, s]  // A slot *can* appear in the getDestinationInsertionPoints. It would behave as if it were an insertion point.

Example): The parent tree is a v1 shadow tree, and the child tree is a v0 shadow tree.

[document tree]
<div id=host1>
  <div id="a" slot="slotA">

  [shadow tree 1]  //  a child tree of document tree, created by host1.attachShadow(..)
  <shadow-root>
    <div id=host2>
      <slot id="s" slot="slotA">

      [shadow tree 2]  // a child tree of shadow tree 1, created by host2.createShadowRoot()
      <shadow-root>
        <content id="c" select="#a">

The distribution would be:

a.assignedSlot == s
s.getDistributedNodes == [a]  // As usual
c.getDistributedNodes == [a]  // <content> will select a node from the distributed nodes of a slot, not a slot itself. In general, <content select="slot"> doesn't make sense in most scenes.
a.getDestinationInsertionPoints == [s, c]  // A node can be re-distributed through a slot.

I'm a Blink developer. What's the impact of v1 for our codebase?

  • I'd like to remove ElementShadow and relevant classes someday. However, we can't remove it until we drop the support of multiple shadow roots from Blink.

    - Note that Blink just deprecated the multiple shadow roots. We are still supporting it.
    - I'm afraid that Blink will have painful period since we have to support both worlds for a while. I'm looking for the best approach which makes our codebase manageable and competitive.
    
  • A StyleResolver can be simplified somehow hopefully, given that /deep/ and ::shadow are gone and the Cascading Order for Shadow Tress will be simplified.

    - There is an on-going effort to make Style Resolver more factored and get benefits from scopes style resolving.
    - Note that we have still `::content`. The situation mightn't change as I thought.
    
  • I'm adding one more kind of ShadowRoot, called ClosedShadowRoot, as a different ShadowRoot than UA ShadowRoot.

    - I've renamed `{Author,UserAgent}ShadowRoot` to `{Open,Closed}ShadowRoot` in the [CL](https://codereview.chromium.org/935283002), however, it turned out that the name of `ClosedShadowRoot` caused a lot of confusion to our codebase. So, instead of batch renaming, I'll introduce the name of "closed" in a more incremental way so that `ClosedShadowRoot` and `UserAgentShadowRoot` can co-exist, with the different meanings, which doesn't upset the existing code.
    - See the [revert patch](https://codereview.chromium.org/1091473002/) for details.