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 clonable work in cloneNode(false)? #1249

Closed
mfreed7 opened this issue Jan 29, 2024 · 11 comments · Fixed by #1272
Closed

How should clonable work in cloneNode(false)? #1249

mfreed7 opened this issue Jan 29, 2024 · 11 comments · Fixed by #1272
Labels
topic: nodes topic: shadow Relates to shadow trees (as defined in DOM)

Comments

@mfreed7
Copy link
Contributor

mfreed7 commented Jan 29, 2024

This issue was raised as part of the Chromium review of the implementation of clonable. The question is what should happen here:

const shadow = host.attachShadow({mode: 'open', clonable: true});
shadow.innerHTML = '<div><span>what about me?</span></div>`;
const clone = host.cloneNode(false);

What should happen to the shadow root? Since it is clonable, I'd expect clone to have a shadow root, with parameters that match shadow. But should the content of that shadow root be deep-cloned from host? Or should clone.shadowRoot be empty? Both of those feel slightly odd. I think I slightly prefer deep-cloning the shadow content, but I'm not sure.

@dbaron @annevk @saschanaz

chromium-wpt-export-bot pushed a commit to web-platform-tests/wpt that referenced this issue Jan 29, 2024
This did not previously work correctly, but now, this will
work:

const shadow = host.attachShadow({mode:'open', clonable:true});
host.cloneNode(false);

See this discussion for more context:
  whatwg/dom#1249

Fixed: 1510466
Change-Id: I8a9de78044785675cd6bbac93d9b26286445ac8d
@saschanaz
Copy link
Member

cc @avandolder

@saschanaz
Copy link
Member

saschanaz commented Jan 29, 2024

We should probably follow the expectation when cloning UA-provided elements with shadow roots, which would be the option 1; deep cloning the shadow root. (If I'm not misunderstanding how they work, cc @emilio)

@emilio
Copy link
Contributor

emilio commented Jan 30, 2024

They do not get cloned in Gecko (except for printing as a special case). A new shadow root is attached when the clone gets inserted into the document.

@annevk
Copy link
Member

annevk commented Jan 30, 2024

Cloning the shadow tree completely makes sense to me. It does make me wonder if we at some point need to provide more cloning options.

cc @rniwa

@annevk annevk added topic: shadow Relates to shadow trees (as defined in DOM) topic: nodes labels Jan 30, 2024
@mfreed7
Copy link
Contributor Author

mfreed7 commented Jan 30, 2024

Sounds like 3 votes (including myself) for deep-cloning the shadow tree, and one for not cloning it. @emilio would you be ok changing to a deep clone behavior?

chromium-wpt-export-bot pushed a commit to web-platform-tests/wpt that referenced this issue Jan 30, 2024
This did not previously work correctly, but now, this will
work:

const shadow = host.attachShadow({mode:'open', clonable:true});
host.cloneNode(false);

See this discussion for more context:
  whatwg/dom#1249

Fixed: 1510466
Change-Id: I8a9de78044785675cd6bbac93d9b26286445ac8d
@emilio
Copy link
Contributor

emilio commented Jan 30, 2024

Yeah, I don't mind either way, I'm just saying that that's not the built-in shadow tree behavior at least in Gecko.

Might be worth checking with @justinfagnani about the ergonomics of this for authors too.

E.g., code that does:

connectedCallback() {
  this.attachShadow({ ... });
}

Or so will throw after cloning if we clone the shadow tree. Maybe fine? You kinda need to deal with that for moves inside the document.

So over-all I think given ^ I'm fine with cloning the shadow tree. But hopefully I'm not missing something.

@saschanaz
Copy link
Member

Yeah, I don't mind either way, I'm just saying that that's not the built-in shadow tree behavior at least in Gecko.

Does anyone know what Blink and WebKit do?

@mfreed7
Copy link
Contributor Author

mfreed7 commented Jan 30, 2024

Does anyone know what Blink and WebKit do?

Blink does not clone the shadow root at all for cloneNode(false), at least currently.

Or so will throw after cloning if we clone the shadow tree. Maybe fine? You kinda need to deal with that for moves inside the document.

This is a good point. I'm really starting to think general clonable shadow roots in the main page might cause more problems than they solve. At the very least we need whatwg/html#10107 resolved.

But it sounds like we have rough consensus that modulo the other clonable issues, cloneNode(false) should deep-clone the shadow root. That's nice because that's actually already what the spec says:

7.3 If the clone children flag is set, then for each child child of node’s shadow root, in tree order: append the result of cloning child with document and the clone children flag set, to copy’s shadow root.

chromium-wpt-export-bot pushed a commit to web-platform-tests/wpt that referenced this issue Jan 30, 2024
This did not previously work correctly, but now, this will
work:

const shadow = host.attachShadow({mode:'open', clonable:true});
host.cloneNode(false);

The behavior is for the shadow root to be deep-cloned, even though
the `deep` argument to `cloneNode()` is `false`.

See this discussion for more context:
  whatwg/dom#1249

and this summary of the consensus:
  whatwg/dom#1249 (comment)

Fixed: 1510466
Change-Id: I8a9de78044785675cd6bbac93d9b26286445ac8d
@justinfagnani
Copy link

Yeah, I don't mind either way, I'm just saying that that's not the built-in shadow tree behavior at least in Gecko.

Might be worth checking with @justinfagnani about the ergonomics of this for authors too.

E.g., code that does:

connectedCallback() {
  this.attachShadow({ ... });
}

Or so will throw after cloning if we clone the shadow tree. Maybe fine? You kinda need to deal with that for moves inside the document.

Yes, you would never write code like that because moves are very common. You either call attachShadow() in the constructor or gate it and call it on the first connection only.

So over-all I think given ^ I'm fine with cloning the shadow tree. But hopefully I'm not missing something.

I actually don't see how cloning the shadow tree is that useful at all in the general case. It's so common that the shadow root depends on non-clonable state, that the only components this would work for would have to be completely static.

chromium-wpt-export-bot pushed a commit to web-platform-tests/wpt that referenced this issue Jan 31, 2024
This did not previously work correctly, but now, this will
work:

const shadow = host.attachShadow({mode:'open', clonable:true});
host.cloneNode(false);

The behavior is for the shadow root to be deep-cloned, even though
the `deep` argument to `cloneNode()` is `false`.

See this discussion for more context:
  whatwg/dom#1249

and this summary of the consensus:
  whatwg/dom#1249 (comment)

Bug: 1510466
Change-Id: I8a9de78044785675cd6bbac93d9b26286445ac8d
aarongable pushed a commit to chromium/chromium that referenced this issue Jan 31, 2024
This did not previously work correctly, but now, this will
work:

const shadow = host.attachShadow({mode:'open', clonable:true});
host.cloneNode(false);

The behavior is for the shadow root to be deep-cloned, even though
the `deep` argument to `cloneNode()` is `false`.

See this discussion for more context:
  whatwg/dom#1249

and this summary of the consensus:
  whatwg/dom#1249 (comment)

Bug: 1510466
Change-Id: I8a9de78044785675cd6bbac93d9b26286445ac8d
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/5242239
Reviewed-by: David Baron <dbaron@chromium.org>
Auto-Submit: Mason Freed <masonf@chromium.org>
Commit-Queue: Mason Freed <masonf@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1254312}
chromium-wpt-export-bot pushed a commit to web-platform-tests/wpt that referenced this issue Jan 31, 2024
This did not previously work correctly, but now, this will
work:

const shadow = host.attachShadow({mode:'open', clonable:true});
host.cloneNode(false);

The behavior is for the shadow root to be deep-cloned, even though
the `deep` argument to `cloneNode()` is `false`.

See this discussion for more context:
  whatwg/dom#1249

and this summary of the consensus:
  whatwg/dom#1249 (comment)

Bug: 1510466
Change-Id: I8a9de78044785675cd6bbac93d9b26286445ac8d
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/5242239
Reviewed-by: David Baron <dbaron@chromium.org>
Auto-Submit: Mason Freed <masonf@chromium.org>
Commit-Queue: Mason Freed <masonf@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1254312}
chromium-wpt-export-bot pushed a commit to web-platform-tests/wpt that referenced this issue Jan 31, 2024
This did not previously work correctly, but now, this will
work:

const shadow = host.attachShadow({mode:'open', clonable:true});
host.cloneNode(false);

The behavior is for the shadow root to be deep-cloned, even though
the `deep` argument to `cloneNode()` is `false`.

See this discussion for more context:
  whatwg/dom#1249

and this summary of the consensus:
  whatwg/dom#1249 (comment)

Bug: 1510466
Change-Id: I8a9de78044785675cd6bbac93d9b26286445ac8d
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/5242239
Reviewed-by: David Baron <dbaron@chromium.org>
Auto-Submit: Mason Freed <masonf@chromium.org>
Commit-Queue: Mason Freed <masonf@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1254312}
moz-v2v-gh pushed a commit to mozilla/gecko-dev that referenced this issue Feb 2, 2024
… true, a=testonly

Automatic update from web-platform-tests
Make shallow clone work when clonable is true

This did not previously work correctly, but now, this will
work:

const shadow = host.attachShadow({mode:'open', clonable:true});
host.cloneNode(false);

The behavior is for the shadow root to be deep-cloned, even though
the `deep` argument to `cloneNode()` is `false`.

See this discussion for more context:
  whatwg/dom#1249

and this summary of the consensus:
  whatwg/dom#1249 (comment)

Bug: 1510466
Change-Id: I8a9de78044785675cd6bbac93d9b26286445ac8d
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/5242239
Reviewed-by: David Baron <dbaron@chromium.org>
Auto-Submit: Mason Freed <masonf@chromium.org>
Commit-Queue: Mason Freed <masonf@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1254312}

--

wpt-commits: bf7b1d88809248c70531b45d7c202a1fc7993d2d
wpt-pr: 44247
ErichDonGubler pushed a commit to ErichDonGubler/firefox that referenced this issue Feb 2, 2024
… true, a=testonly

Automatic update from web-platform-tests
Make shallow clone work when clonable is true

This did not previously work correctly, but now, this will
work:

const shadow = host.attachShadow({mode:'open', clonable:true});
host.cloneNode(false);

The behavior is for the shadow root to be deep-cloned, even though
the `deep` argument to `cloneNode()` is `false`.

See this discussion for more context:
  whatwg/dom#1249

and this summary of the consensus:
  whatwg/dom#1249 (comment)

Bug: 1510466
Change-Id: I8a9de78044785675cd6bbac93d9b26286445ac8d
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/5242239
Reviewed-by: David Baron <dbaron@chromium.org>
Auto-Submit: Mason Freed <masonf@chromium.org>
Commit-Queue: Mason Freed <masonf@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1254312}

--

wpt-commits: bf7b1d88809248c70531b45d7c202a1fc7993d2d
wpt-pr: 44247
gecko-dev-updater pushed a commit to marco-c/gecko-dev-wordified-and-comments-removed that referenced this issue Feb 8, 2024
… true, a=testonly

Automatic update from web-platform-tests
Make shallow clone work when clonable is true

This did not previously work correctly, but now, this will
work:

const shadow = host.attachShadow({mode:'open', clonable:true});
host.cloneNode(false);

The behavior is for the shadow root to be deep-cloned, even though
the `deep` argument to `cloneNode()` is `false`.

See this discussion for more context:
  whatwg/dom#1249

and this summary of the consensus:
  whatwg/dom#1249 (comment)

Bug: 1510466
Change-Id: I8a9de78044785675cd6bbac93d9b26286445ac8d
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/5242239
Reviewed-by: David Baron <dbaronchromium.org>
Auto-Submit: Mason Freed <masonfchromium.org>
Commit-Queue: Mason Freed <masonfchromium.org>
Cr-Commit-Position: refs/heads/main{#1254312}

--

wpt-commits: bf7b1d88809248c70531b45d7c202a1fc7993d2d
wpt-pr: 44247

UltraBlame original commit: ad7d9de7a73983abcd2ba32c270f068283e5104c
gecko-dev-updater pushed a commit to marco-c/gecko-dev-comments-removed that referenced this issue Feb 8, 2024
… true, a=testonly

Automatic update from web-platform-tests
Make shallow clone work when clonable is true

This did not previously work correctly, but now, this will
work:

const shadow = host.attachShadow({mode:'open', clonable:true});
host.cloneNode(false);

The behavior is for the shadow root to be deep-cloned, even though
the `deep` argument to `cloneNode()` is `false`.

See this discussion for more context:
  whatwg/dom#1249

and this summary of the consensus:
  whatwg/dom#1249 (comment)

Bug: 1510466
Change-Id: I8a9de78044785675cd6bbac93d9b26286445ac8d
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/5242239
Reviewed-by: David Baron <dbaronchromium.org>
Auto-Submit: Mason Freed <masonfchromium.org>
Commit-Queue: Mason Freed <masonfchromium.org>
Cr-Commit-Position: refs/heads/main{#1254312}

--

wpt-commits: bf7b1d88809248c70531b45d7c202a1fc7993d2d
wpt-pr: 44247

UltraBlame original commit: ad7d9de7a73983abcd2ba32c270f068283e5104c
gecko-dev-updater pushed a commit to marco-c/gecko-dev-wordified that referenced this issue Feb 8, 2024
… true, a=testonly

Automatic update from web-platform-tests
Make shallow clone work when clonable is true

This did not previously work correctly, but now, this will
work:

const shadow = host.attachShadow({mode:'open', clonable:true});
host.cloneNode(false);

The behavior is for the shadow root to be deep-cloned, even though
the `deep` argument to `cloneNode()` is `false`.

See this discussion for more context:
  whatwg/dom#1249

and this summary of the consensus:
  whatwg/dom#1249 (comment)

Bug: 1510466
Change-Id: I8a9de78044785675cd6bbac93d9b26286445ac8d
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/5242239
Reviewed-by: David Baron <dbaronchromium.org>
Auto-Submit: Mason Freed <masonfchromium.org>
Commit-Queue: Mason Freed <masonfchromium.org>
Cr-Commit-Position: refs/heads/main{#1254312}

--

wpt-commits: bf7b1d88809248c70531b45d7c202a1fc7993d2d
wpt-pr: 44247

UltraBlame original commit: ad7d9de7a73983abcd2ba32c270f068283e5104c
@annevk
Copy link
Member

annevk commented Feb 16, 2024

I guess the main issue here is that we need better test coverage for this scenario?

@annevk annevk added the needs tests Moving the issue forward requires someone to write tests label Feb 16, 2024
marcoscaceres pushed a commit to web-platform-tests/wpt that referenced this issue Feb 23, 2024
This did not previously work correctly, but now, this will
work:

const shadow = host.attachShadow({mode:'open', clonable:true});
host.cloneNode(false);

The behavior is for the shadow root to be deep-cloned, even though
the `deep` argument to `cloneNode()` is `false`.

See this discussion for more context:
  whatwg/dom#1249

and this summary of the consensus:
  whatwg/dom#1249 (comment)

Bug: 1510466
Change-Id: I8a9de78044785675cd6bbac93d9b26286445ac8d
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/5242239
Reviewed-by: David Baron <dbaron@chromium.org>
Auto-Submit: Mason Freed <masonf@chromium.org>
Commit-Queue: Mason Freed <masonf@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1254312}
@annevk annevk removed the needs tests Moving the issue forward requires someone to write tests label Apr 3, 2024
@annevk
Copy link
Member

annevk commented Apr 3, 2024

It seems this was tested, but also required a change to the specification and that was not proposed. I created #1272 for that.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
topic: nodes topic: shadow Relates to shadow trees (as defined in DOM)
Development

Successfully merging a pull request may close this issue.

5 participants