w3c / w3c/editing

contentEditable: clarification of selection and typing behavior

Open
#156 9 comments 1 reaction 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

This discussion started in Blink bug 663638.

The context

Consider the following snippet:

<div id="sample" contenteditable="true" style="border-style: solid">
  abc <a href='bob'>selectMeAndTypeOver</a> def
</div>

It is not clear what the behavior should be when a user selects "selectMeAndTypeOver" (i.e. the entirety of the text node within the <a> node) and types something else.

What I could gather from Blink (M57) and Gecko (Firefox 50) so far is this:

  • Gecko

    • Double-clicking selectMeAndTypeOver:
      • document.getSelection() returns a Selection object with the <div> as both anchor and focus nodes (anchorOffset==1, focusOffset==2).
      • document.execCommand("insertText", false, "foo") replaces the entire <a> node with a new text node. That is, document.getElementById("sample").childNodes returns 3 text nodes.
      • Just typing something manually also removes the <a> node and replaces it with a text node whose contents are whatever is being typed.
    • Selecting selectMeAndTypeOver with the mouse:
      • document.getSelection() returns a Selection object with the selectMeAndTypeOver text node as the anchor (anchorOffset==0) and the def text node as the focus (focusOffset==0).
      • document.execCommand("insertText", false, "foo") replaces the contents of text node within the <a> node with "foo". That is, document.getElementById("sample").childNodes returns 3 nodes, the second being <a>.
      • Just typing something manually also causes the contents of the text node within <a> to be replaced, while <a> itself remains in the tree.
    • When moving the caret with the left and right keyboard keys and then typing, the new text may be either a child of the <a> node or a sibling text node:
      • When the caret is anywhere in electMeAndTypeOve and is moved to either |selectMeAndTypeOver or selectMeAndTypeOver|, the new text is added to the existing text node inside . In other words, the contents of the link changes, but the link remains the same.
      • When the caret is moved from "abc " towards |selectMeAndTypeOver, the new text is appended to the "abc " text node (it does not become part of the link node).
      • When the caret is moved from " def" towards selectMeAndTypeOver|, the new text is added to the " def" text node (it does not become part of the link node).
  • Blink

    • Double-clicking selectMeAndTypeOver:
      • document.getSelection() returns a Selection object with the selectMeAndTypeOver text node as both anchor and focus (anchorOffset==0, focusOffset==19).
      • document.execCommand("insertText", false, "foo") replaces the contents of the text node within the <a> node with "foo". That is, the link remains but the text is changed.
      • Just typing something manually causes the first character to become the only contents of the text node within the <a> node, while any further input is added to a new text node that is inserted right after the <a> node. That is, the first character of the input becomes the link's text and all the rest becomes a new text node adjacent to <a> (document.getElementById("sample").childNodes returns 1 text node, <a> and 2 other text nodes).
    • The behavior when selecting selectMeAndTypeOver with the mouse is identical to what was described above.
    • Typing something either before or after selectMeAndTypeOver always creates text nodes (i.e. the text node within the <a> node is never touched):
      • When the caret is at |selectMeAndTypeOver, the new contents are appended to the "abc " text node.
      • When the caret is at selectMeAndTypeOver|, the new contents are added to a new text node that is inserted between the <a> node and the " def" text node.

I wasn't able to test Edge and Safari, but GNOME Web 3.22.1 with WebKitGTK+ 2.14.11 behaved identically to Blink.

The questions

  • Once selectMeAndTypeOver is selected, what should the Selection object returned by document.getSelection() contain as focus and anchor (and respective offsets)?
  • What's the expected behavior when selectMeAndTypeOver and the user then starts typing? Should the content replace the <a> node or the contents of the text node inside the <a>? Or should Blink/WebKit's behavior of just adding the first character to the text node within <a> be followed?
  • What happens when the caret is positioned at either edge of selectMeAndTypeOver and the user types something? Should the new text be part of the <a> node or adjacent to it? If it should be adjacent to it, should it be merged into the existing nodes or should new text nodes be created?

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 by reading the linked Blink bug 663638 and the HTML contenteditable example, then compare the documented document.getSelection() and document.execCommand("insertText") results across Blink and Gecko. Done means reaching agreement on selection boundaries, typing replacement behavior, and caret-edge node placement, with those expectations recorded for the editing work.

Written by the indexing model from the issue text.

Assessment

Tech stack
html
Domain
frontend, web-dev
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.