Skip to content

feat(studio): apply a style to a run of characters - #3142

Draft
miguel-heygen wants to merge 1 commit into
stack/rich-text-persistencefrom
stack/inline-text-styling
Draft

feat(studio): apply a style to a run of characters#3142
miguel-heygen wants to merge 1 commit into
stack/rich-text-persistencefrom
stack/inline-text-styling

Conversation

@miguel-heygen

Copy link
Copy Markdown
Collaborator

What

The engine that applies a style to selected characters inside an element. Pure logic, no UI.

Why

Wrapping a DOM range in a span is three lines, and then every interesting case is a special case: recolouring nests spans that shadow each other, removing a style cannot reach the ancestor that set it, and styling across an existing run's boundary has to split it. Each fix is a new branch and the branches interact.

How

The element is read into a flat list of styled runs, the style is applied to a span of characters in that list, and the element is rebuilt from it. Replacing, removing, splitting and merging stop being cases: the rebuild emits one span per distinct run and cannot nest or duplicate, whatever was there before.

Selection offsets count UTF-16 units, so a boundary can land between the halves of an emoji; the applied range widens to whole characters. A colour an ancestor overpaints is mirrored into the fill, because a colour that does not paint reads to the user as a colour that did not save.

Test plan

  • 44 tests covering replace, remove, split, merge, emoji boundaries and the overpainted-fill case

The toolbar that drives this arrives in the next PR.


Part of a stack re-cutting #3077, which stays open as the reference for the whole tree. The preview fixes land first; this is the feature half.

Styling text in a composition cannot be done by wrapping a DOM range in a
span. That is three lines, and then every interesting case is a special
case: recolouring nests spans that shadow each other, removing a style
cannot reach the ancestor that set it, and styling across an existing run's
boundary has to split it. Each fix is a new branch and the branches
interact.

So the element is read into a flat list of styled runs, the style is applied
to a span of characters in that list, and the element is rebuilt from it.
Replacing, removing, splitting and merging stop being cases: the rebuild
emits one span per distinct run and cannot nest or duplicate, whatever was
there before.

Selection offsets count UTF-16 units, so a boundary can land between the
halves of an emoji; the applied range widens to whole characters. A colour
an ancestor overpaints is mirrored into the fill, because a colour that does
not paint reads to the user as a colour that did not save.

The toolbar that drives this arrives with the editor in the next change.
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.

1 participant