Bug 163921

Summary: Add selection API that works across shadow boundaries
Product: WebKit Reporter: Trey Shugart <treshugart>
Component: DOMAssignee: Nobody <webkit-unassigned>
Status: NEW ---    
Severity: Blocker CC: asci, bede.overend, cdumez, javan, rniwa, simon.fraser, vepomoc
Priority: P2    
Version: Safari 10   
Hardware: Macintosh   
OS: macOS 10.12   
Bug Depends on:    
Bug Blocks: 148695    
Attachments:
Description Flags
console tests
none
DOM and Shadow DOM selections in Safari, Chrome, and Firefox
none
Test case used to generate the attached screenshots none

Description Trey Shugart 2016-10-24 16:41:49 PDT
Created attachment 292676 [details]
console tests

We're wrapping a web component around ProseMirror that has an editor inside of a shadow root. In order to get ProseMirror working with native Shadow DOM, we made a PR that uses getSelection() on the DocumentOrShadowRoot interface (which ShadowRoot should implement). However, we've run into issues in Safari 10 where this isn't working and upon investigation it seems Safari doesn't fully implement the Shadow DOM spec here.

This is a critical issue for us. Is there somewhere we can easily find what Safari hasn't implemented yet so we don't keep running into these issues? Thanks!
Comment 1 asci 2018-07-03 06:26:17 PDT
Any updates on this?
Comment 2 Javan Makhmali 2019-05-01 09:00:38 PDT
Firefox also does not implement `getSelection()` on Shadow Root, but the document level API works (`document.getSelection().getRangeAt(0)` will return a Shadow Root's Range). Safari has no such fallback or workaround, making it impossible to programmatically work with DOM selections inside a Shadow Root.
Comment 3 Javan Makhmali 2019-05-01 09:04:56 PDT
Created attachment 368674 [details]
DOM and Shadow DOM selections in Safari, Chrome, and Firefox

In the bottom row, note that Safari is the only browser with no Shadow DOM selection.
Comment 4 Javan Makhmali 2019-05-01 09:05:36 PDT
Created attachment 368675 [details]
Test case used to generate the attached screenshots
Comment 5 Ryosuke Niwa 2019-05-02 14:01:32 PDT
This is Chrome only API. The latest proposal is to add getComposedRange which takes a list of ShadowRoots and then return a StaticRange which spans across shadow boundaries:
https://github.com/w3c/webcomponents/issues/79
Comment 6 Javan Makhmali 2019-05-02 17:03:11 PDT
> This is Chrome only API

Isn't it part of the spec (https://w3c.github.io/webcomponents/spec/shadow/#ranges-and-selections)? Or do you mean that only Chrome has implemented it?

> The latest proposal is to add getComposedRange

Interesting, thanks. It's a new API, not a replacement for getSelection(), right? https://github.com/w3c/selection-api/issues/98

---

As it stands, I'd be happy with any API for getting the Selection/Range from a Shadow Root. It's possible to do in Chrome and Firefox currently, but not Safari (unless I'm missing something?).
Comment 7 Ryosuke Niwa 2019-05-02 17:12:04 PDT
(In reply to Javan Makhmali from comment #6)
> > This is Chrome only API
> 
> Isn't it part of the spec
> (https://w3c.github.io/webcomponents/spec/shadow/#ranges-and-selections)? Or
> do you mean that only Chrome has implemented it?

That specification has been deprecated / superseded. See the warning at the very top which says:
> Shadow DOM specification is being upstreamed to DOM Standard [WHATWG-DOM], HTML Standard [HTML], CSS Scoping Module Level 1 [css-scoping-1], UI Events specification [uievents], and other relevant specifications. This specification may not accurately reflect the latest conclusion. See Issue #377 for details.


> > The latest proposal is to add getComposedRange
> 
> Interesting, thanks. It's a new API, not a replacement for getSelection(),
> right? https://github.com/w3c/selection-api/issues/98

window.getSelection() isn't going away anytime soon but no browser engine other than Blink has a plan or has demonstrated public support for having getSelection() on ShadowRoot.

> As it stands, I'd be happy with any API for getting the Selection/Range from
> a Shadow Root. It's possible to do in Chrome and Firefox currently, but not
> Safari (unless I'm missing something?).

I'm pretty sure it's not supported in Firefox. I tested 68.0a1 (2019-05-01) and 66.0.2 and both versions don't have it:

document.createElement('div').attachShadow({mode: 'open'}).getSelection()
TypeError: document.createElement(...).attachShadow(...).getSelection is not a function
Comment 8 Javan Makhmali 2019-05-02 17:22:39 PDT
Got it, thanks for the clarifications!

> I'm pretty sure it's not supported in Firefox. 

That's correct, but window.getSelection() will return a Shadow Root's selection in Firefox. Probably goes against spec, but it works at least. See the Firefox note and linked issue in the README here: https://github.com/GoogleChromeLabs/shadow-selection-polyfill

There's no such workaround in Safari.