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

ELEMENTS-1372: fix selection on Safari #2

Merged
merged 7 commits into from
Jun 7, 2021

Conversation

Gabez0r
Copy link

@Gabez0r Gabez0r commented Jun 1, 2021

Here we're replacing the broken shadow-selection-polyfill with an alternate polyfill. However, there are some issues with the polyfill that prevent it from correctly working OOTB with Quill:

  1. Missing the rangeCount property, a member of the public Selection API
  2. The fact that it relies on events, means that whenever you do a getSelection, you never know if you are not getting an outdated version of the selection or not, because the event might not have been fired yet.
  3. The fact that addRange doesn't actually set the range on the contenteditable element

Problem 1) is quite easy to fix, but just implementing the missing getter.

Problem 2) is quite hard to get around without proper support from Safari, or without fully controlling the component (quill in this case). Quill runs an update whenever there is a DOM mutation. In this update, it will read the selection and, based on it, explicitly set the selection in some situations, using the addRange (problem 3). Problem 3 can be worked around by explicitly setting the selection on the Window, but only if this is not being called from the polyfill, or else it can generate a loop.

Problem 2) remains unaddressed. Luckily, it only seems to happen when filling the first character of a row, probably related to how quill replaces the br element with a text node. Increasing the selection offset by 1 in this particular case seems to do the trick, but I am not sure if this will always work.

@Gabez0r Gabez0r force-pushed the fix-ELEMENTS-1372-selection branch 3 times, most recently from 8e94dc8 to aef33db Compare June 1, 2021 15:35
@Gabez0r Gabez0r marked this pull request as ready for review June 1, 2021 15:37
core/selection.js Outdated Show resolved Hide resolved
if (!this.hasFocus()) return;
const native = this.getNativeRange();
// when might need to hack the offset on Safari, when we are dealing with the first character of a row
const hackOffset = (native.start.offset === 0 &&

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

shouldn't we fix the offset in the getNativeRange() function instead where we're already "fixing" it ?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I though about that, but then getNativeRange is also used by getRange, setRange and format, which are then used in other places, so it has a greater potential to introducing side effects...

@@ -4,7 +4,7 @@ const SUPPORTS_BEFORE_INPUT = typeof window.InputEvent.prototype.getTargetRanges
const IS_FIREFOX = window.navigator.userAgent.toLowerCase().indexOf('firefox') > -1;

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we need to handle FF differently ?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Differently than Safari? Yes, it does not need to use the ShadowSelection class. It can do everything using document.getSelection().

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants