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

Improve selection.isCollapsed #337

Open
abhish-shrivastava opened this issue Oct 7, 2024 · 4 comments
Open

Improve selection.isCollapsed #337

abhish-shrivastava opened this issue Oct 7, 2024 · 4 comments

Comments

@abhish-shrivastava
Copy link

The selection.isCollapsed works by detecting start and end nodes and their offsets. This sometimes leads to inconsistencies because of different implementations by different browsers (especially on mobiles, tested this on chrome). Here is what happens-

  1. When a cursor is placed at the beginning of a list, the selection.isCollapsed should ideally return true and selection.type as 'cursor'.
  2. However, if there is text (say a paragraph block previously to the list), then it still gives false because startContainer is then taken as the previous text block (while end container points correctly to the list item, li of the list). So even though nothing is selected and it is just a cursor, selection.isCollapsed returns false and selection.type as 'range'.
@rniwa
Copy link
Contributor

rniwa commented Oct 7, 2024

Could you provide a sample HTML? It's hard to discuss this without a concrete DOM tree.

@abhish-shrivastava
Copy link
Author

abhish-shrivastava commented Oct 7, 2024

Sure, here is a simple example-

<p>....some text...</p>
<ul>
<li>list 1....</li>
<li>list 2...</li>
.
.
.
</ul>

When a cursor is placed at the start of 1st li (list 1), ideally the startContainer should point to that li with offset 0, Same for endContainer. And that is how it is on desktop browsers. But on mobile (checked this on android/chrome), endContainer points correctly but startContainer points to the text from the previous paragraph block and takes offset from there.

Just like that if I place cursor at the beginning of the second li (list 2), startContainer this time points to the 1st list item and takes offset from there.

Thus wrongly, selection.isCollapsed returns false and selection.type as 'range'. Also selection's range object's range.collapsed also returns wrongly as false.
This is due to faulty implementation by browsers.

Here can be an alternate solution to address this. To find isCollapsed property, instead of checking startContainer and endContainer and their offsets-

  1. We can check selection's range object's range.getBoundingClientRect().width. If it is 0 then it is a cursor else it is a range.

or

  1. To be more comprehensive, we can get selected contents using selection's range objects range.cloneContents() and check if it is empty (not containing any text or image etc.).

@rniwa
Copy link
Contributor

rniwa commented Oct 7, 2024

That sounds like a bug on Chrome / Android.

@abhish-shrivastava
Copy link
Author

abhish-shrivastava commented Oct 9, 2024

I respectfully disagree. While a case can be stated that mobile browsers need to work on implementing correct startContainer but still, if nothing is selected and what is blinking on my screen in an editor is a cursor, then selection.type should return 'cursor' and selection.isCollapsed as true, irrespective of from where start and end container references and their offsets are taken.

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

No branches or pull requests

2 participants