w3c / w3c/editing

Preserving the integrity of the contentEditable's hidden state

Open
#223 6 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
HTML
Stars
202
Forks
43
PR merge metrics
No merged PRs in 30d

Description

Context
Empirical observation of the behavior of different browsers and platforms reveals a hidden state associated with contentEditable elements. A simple example is the following:

  1. Insert a word such as "erase" by swiping on the keyboard on Android or iOS
  2. Hit backspace
  3. Reinsert the word "erase" by swiping again
  4. Insert a space
  5. Hit backspace twice

Observed behavior: Hitting backspace right after a swipe insert erases the whole word whereas hitting backspace at another time only erases a single character.

The problem
This hidden state is not preserved when the DOM is being modified programmatically. This means that programmatically modifying the contents of a contentEditable at any time may lead to inconsistencies that cannot be prevented of remediated.
Here is an example:

  1. Insert "erase" by swiping on the keyboard
  2. In the inspector, apply the following steps using the console
  3. $range = new Range()
  4. $range.selectNode(document.querySelector("[contentEditable]")
  5. $node = document.createElement("b")
  6. $range.surroundContents($node)
  7. Fix the selection's position by applying the following steps in the console
  8. document.getSelection().setBaseAndExtent($node, 1, $node, 1)
  9. Hit backspace on the device's keyboard

Observed behavior: A single character is erased.
Expected behavior: A whole word is erased.

Why is this a problem?
There are various use cases for which programmatic modification of the contents is required but unavoidably leads to interference with the user's ability to edit the contents in an intuitive way. Here are two important use cases:

  1. Range-based metadata: applying style on ranges of text to convey metadata and enable productivity features
  2. Collaborative editing: reproducing one user's changes on the other connected editors

What is the way forward?

I am not sure which is the best way forward at this point. I am bringing up those issues so that they can be discussed.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with the browser reproduction in the issue, focusing on contentEditable, Range, selection, and the Android or iOS backspace behavior. Compare the observed and expected outcomes, then investigate the two stated use cases—range-based metadata and collaborative editing; the issue does not yet define an agreed implementation or completion test.

Written by the indexing model from the issue text.

Assessment

Tech stack
html
Domain
frontend
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Stale
Clarity
Needs clarification
Newbie friendliness
20/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.