facebookarchive / draft-js

A React framework for building text editors.
https://draftjs.org/
MIT License
22.57k stars 2.64k forks source link

Can't select across user-select: none elements in Firefox #1789

Open sciyoshi opened 6 years ago

sciyoshi commented 6 years ago

Do you want to request a feature or report a bug? Bug

What is the current behavior?

Any elements with -moz-user-select: none or contenteditable=false inside a Draft editor prevent selections containing it in Firefox.

https://jsfiddle.net/ocgmae3q/32/

In the Draft editor (top block), you can't select across the user-select: none block. This works fine both in the Firefox contenteditable and in Chrome (Draft and native contenteditable).

bug

What is the expected behavior?

This should work the same way as it does in Chrome.

Which versions of Draft.js, and which browser / OS are affected by this issue? Did this work in previous versions of Draft.js?

Tested on latest version of Draft and Firefox.

The issue appears to be caused because Firefox will turn such selections into ones with multiple ranges (rangeCount > 1), which is not handled correctly by the logic in https://github.com/facebook/draft-js/blob/master/src/component/selection/getDraftEditorSelection.js#L36 and https://github.com/facebook/draft-js/blob/master/src/component/selection/getDraftEditorSelectionWithNodes.js. The right approach is probably to check for multiple ranges there and figure out the corresponding extent in Draft offsets.

thibaudcolas commented 6 years ago

From what I understand, the DOM selection spec now mandates that selections only have a single range (https://developer.mozilla.org/en-US/docs/Web/API/Selection#Multiple_ranges_in_a_selection, https://www.w3.org/TR/selection-api/#x3-definition). In particular, getRangeAt(index) is meant to throw if the index is anything other than 0 – I don't know if Firefox complies with that or not, but it might make the workaround trickier.

Edit: in my testing, this is ony because of user-select: none;contenteditable="false" on its own does not affect the selection ranges.

sciyoshi commented 6 years ago

Thanks @thibaudcolas, I've updated the description. Webkit ignores user-select: none unless the element also has contenteditable=false, but that's an unrelated issue. From my testing Firefox is definitely behaving differently than the spec here and returning multiple ranges.