fix: format each line of a multi-line selection with inline markers

MR
1d ago
+225-5

Proposed changes

Selecting several lines and pressing Bold (or Italic, Strikethrough, Inline code) wraps the whole selection in one pair of markers:

*This is
a test*

The message parser doesn't let inline markers span a line break, so that renders as plain text (*This is / a test*). Each line has to carry its own markers:

*This is*
*a test*
  • client/lib/toggleLineMarker.ts, next to toggleLinePrefix.ts:
    • getLineMarker(pattern) recognises the four inline Markdown patterns (*, _, ~, `).
    • toggleLineMarker(text, marker) wraps every non-blank line, keeping surrounding whitespace outside the markers, or unwraps them when every line is already wrapped. Pressing the button again therefore toggles the formatting off.
  • wrapSelection in both composers (createComposerAPI and createRichTextComposerAPI) uses it for a multi-line selection with one of those markers.
  • Unchanged:
    • single-line selections;
    • the existing unwrap when the markers sit just outside the selection;
    • the multi-line code block button;
    • wrapping a selection by typing (, ", [ and similar, which still wraps the selection as a whole.

Issue(s)

Closes #33065

Steps to test or reproduce

  1. Type two lines in the composer, select both, and press Bold.
  2. The composer now holds *This is* / *a test* and the sent message shows both lines in bold. Pressing Bold again removes the markers.

Tests:

  • toggleLineMarker.spec.ts: marker detection, per-line wrapping, blank lines, whitespace, toggling off.
  • createComposerAPI.spec.ts: per-line wrap, toggle off, brackets unchanged, single line unchanged.
  • createRichTextComposerAPI.spec.ts: per-line wrap (the two assertions that expected *foo\nbar* now expect the rendered form), and brackets unchanged.

Results: the composer suites pass (15 suites, 254 tests). ESLint, Prettier and tsc on the changed files are clean.

Further comments

An earlier attempt, #33288, changes MessageBox.tsx and has conflicted with develop since the composer logic moved into the composer APIs. This change works on the current APIs, covers the rich text composer too, and adds tests.

Summary by CodeRabbit

  • Bug Fixes
    • Applying inline formatting to a multiline message selection now formats each nonblank line individually, while preserving blank lines and surrounding whitespace.
    • Applying the same formatting again removes it from each line when all nonblank lines are already formatted.
    • Multiline selections wrapped with brackets continue to be treated as a single selection. Selection and cursor positions are maintained after formatting.