Proposal: `setCaretInlineOffset` API for adjusting caret visual representation
Nobody has claimed this yet.
Assessment
- Difficulty
- 5/5
- Estimated time
- Over a week
- Newbie friendliness
- 35/100
Research direction
The issue names no repository files or tests. Start by reading the Selection API's Selection interface and the proposed setCaretInlineOffset examples; done would require an agreed API design and defined specification or test changes, which the issue does not yet provide.
Written by the indexing model from the issue text.
Description
Problem
Rich text editors face challenges with caret positioning when text is broken into multiple line boxes due to responsive layouts, because a single boundary point can be visually rendered in 2 different places.
For example, a boundary-point like {node: #text, offset: 5} in the following HTML:
<p style="word-break: break-all">loremipsum</p>
When we use the browser's default event to navigate, it uses its "internal state" to know where the caret should be placed. However, if we want to implement the block-directional / inline-directional navigation manually, we have no control over the caret's visual placement.
Proposal
I'd like to propose to extend the Selection API by adding a new method that allows developers to set an inline offset for the caret’s visual appearance.
interface Selection {
setCaretInlineOffset: (offset: number) => void;
}
How would it work?
It checks if the caret should be appeared, then
if the caret can be placed in 2 different places, then
if the diff between offsetA and offset is smaller than the diff between offsetB and offset, position the caret to the place A, otherwise position it to the place B.
Example
const textNode = document.createTextNode("loremipsum");
// We get the char's left and right pos
const getCharPos = (text, index) => {
const range = new Range();
range.setStart(text, index);
range.setEnd(text, index + 1);
const { left: charLeftPos, right: charRightPos } =
range.getBoundingClientRect();
return { charLeftPos, charRightPos };
};
// We select the char m (lore[m]ipsum)
const char_M_Pos = getCharPos(textNode, 4);
// We select the char i (lorem[i]psum)
const char_I_Pos = getCharPos(textNode, 5);
const sel = getSelection();
// Set the bp to lorem|ipsum
sel.setPosition(textNode, 5);
// If we want to adjust right after lorem
sel.setCaretInlineOffset(char_M_Pos.charRightPos);
// If we want to adjust right before ipsum
sel.setCaretInlineOffset(char_I_Pos.charLeftPos);
- Dominant language
- HTML
- Stars
- 49
- Forks
- 30
- PR merge metrics
- No merged PRs in 30d
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
More from w3c/selection-api
-
Difficulty 2/5 1-3 hours Newbie friendliness 62/100
w3c/selection-api#354 ·
-
Agenda+
Difficulty 3/5 1-2 days Newbie friendliness 48/100
w3c/selection-api#361 · 2 comments ·
-
w3c/selection-api#358 · 2 comments · 1 assignee ·
-
Difficulty 5/5 Over a week Newbie friendliness 25/100
w3c/selection-api#355 ·
-
the steps of Selection.extend() does not check whether the given offset is valid in the container Open
Difficulty 1/5 Under an hour Newbie friendliness 55/100
w3c/selection-api#353 · 1 comment ·
All issues in w3c/selection-api
Similar issues
-
bug clawsweeper:linked-pr-open clawsweeper:needs-live-repro clawsweeper:no-new-fix-pr impact:message-loss issue-rating: 🐚 platinum hermit P2 regression
Difficulty 2/5 1-3 hours Newbie friendliness 78/100
-
Difficulty 1/5 Under an hour Newbie friendliness 90/100
AXERA-TECH/ax-llm#77 ·
-
Difficulty 1/5 Under an hour Newbie friendliness 90/100
games-on-whales/wolf#509 ·
-
Difficulty 2/5 1-3 hours Newbie friendliness 78/100
-
enhancement
Difficulty 2/5 1-3 hours Newbie friendliness 72/100