Re: [WICG/webcomponents] Selection APIs for Shadow DOM (#79)

> That does directly against the basic feature of Shadow DOM: encapsulation. The whole point of having a Shadow DOM is to encapsulate the implementation details of a component from the rest of a web page. The idea that some scripts may need to apply new behaviors across components without those components opt'ing in goes against this basic principle.

I think it's important to point out that **open** Shadow DOM is not a security or perfect-isolation boundary. I do agree that **closed** Shadow DOM should prohibit JS from having access to inner details. But the distinction vs. **open** Shadow DOM is precisely and only that internal details **are** accessible, just not via CSS or naive `querySelector()` calls. Javascript **already can** access all of the details of any open Shadow Root. This proposal doesn't change that.

> Consider an editor component, which consists of a content editable region and a toolbar for things like bolding & italicizing text. As the user moves selection to different parts of the content editable region, the toolbar status may need to be updated. The component wants to do that by observing selection changes within the component. The proposed API which returns a node anywhere in the document will mean that this component will then have to check whether the selection resides within the content editable element of this component's shadow tree or not. This will be worse developer ergonomics than the proprietary API Blink has on ShadowRoot interface right now.

I think to actually implement this example, you'll need to handle the endpoints being anywhere in the document. For example, what happens when a user mouses-down outside the editor, drags the selection into the middle of the editor text, and mouses-up there. Then they go to click the Bold/Italic button. They should (rightly) expect the portion of the editor text that is highlighted to turn Bold/Italics. However, in this case, one endpoint of the selection is within the component and the other is outside. You can try this example right here in the Github editor, by the way. While it doesn't use Shadow DOM, the behavior is somewhat supported.


> It's unclear that `getComposedSelection(allRoots)` is something we want allow anyone to be using. Again, this goes directly against the basic idea of encapsulation.

Maybe we're misunderstanding each other, but `getComposedSelection(allRoots)` is your suggestion. I.e. [your comment above](https://github.com/WICG/webcomponents/issues/79#issuecomment-937291235) says "getComposedRange should take shadow roots as arguments regardless of whether they're open or not".


> > I'm curious why you think shadow dom is special here. The user is **already able** to select anything on the page, including inside deeply nested shadow DOM. The existing `getRangeAt()` already returns **any `Node`** on the page, not just inside some sub-tree. This new API is meant to extend that current behavior to `Node`s inside shadow trees. If you're writing some code that doesn't understand Shadow DOM, great, just keep using `getRangeAt()`.
> 
> Because the whole point of Shadow DOM is to encapsulate its contents. If there is a desire for some scripts to access anywhere in the document, then why use Shadow DOM at all? Shadow DOM isn't designed to be general purpose API that can be used for any purpose whatsoever; its primary function is to _provide encapsulation_.

See my comment above on this. But script **already has full access** to all open Shadow Roots, while only **closed** Shadow Roots are meant to fully encapsulate their contents from JS.

There are two potential reasons to want to require developers to specify all shadow roots in the call to `getComposedRange()`:
1. To help avoid accidental access to the wrong shadow root. I.e. it might be more ergonomic for most developers.
2. To prohibit access to the "wrong" shadow root. I.e. to provide security for open shadow roots.

I hope it is clear that <span>#</span>2 can't be a thing. Open shadow roots are "open" already. That leaves <span>#</span>1 - the ergonomics question - as the one we need to explore here. I'm open to the idea that it might be easier to pre-limit the shadow roots that we might receive from `getComposedRange()`, but it'd be great to hear from developers on that. Absent that, it seems like it makes the most sense to offer both ways. I.e. one calling syntax (e.g. just `getComposedRange()`) that returns endpoints anywhere, and another (e.g. `getComposedRange({onlyThese: [...roots]})`) for developers who would like to limit to just a list of shadow roots. WDYT?

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

Received on Monday, 18 October 2021 20:36:15 UTC