From 0ff8131ad5805d0e32c2b522536d30e6ba1ed6f0 Mon Sep 17 00:00:00 2001 From: Jack Terwilliger Date: Sat, 18 Jul 2026 12:15:18 -0700 Subject: [PATCH] continuation line breaks --- packages/editor/src/TranscriptEditor.svelte | 8 ++------ .../editor/src/nodeviews/UtteranceNodeView.ts | 2 +- .../editor/src/plugins/playback-plugins.ts | 18 +++++++++++++++++- 3 files changed, 20 insertions(+), 8 deletions(-) diff --git a/packages/editor/src/TranscriptEditor.svelte b/packages/editor/src/TranscriptEditor.svelte index 804d008..1d93673 100644 --- a/packages/editor/src/TranscriptEditor.svelte +++ b/packages/editor/src/TranscriptEditor.svelte @@ -1213,18 +1213,14 @@ pointer-events: none; } - :global(.utt-row[data-has-continuation] .utt-content::after) { - content: '\2060↩'; - display: inline-block; + :global(.utt-head-mark) { color: var(--color-text-muted, #bbb); - margin-left: 0.35em; + margin-left: 0.2em; user-select: none; pointer-events: none; - vertical-align: baseline; } :global(.utt-continuation-mark) { - transform: scaleY(-1); color: var(--color-text-muted, #bbb); font-weight: 400; cursor: default; diff --git a/packages/editor/src/nodeviews/UtteranceNodeView.ts b/packages/editor/src/nodeviews/UtteranceNodeView.ts index 3e23070..d5f252b 100644 --- a/packages/editor/src/nodeviews/UtteranceNodeView.ts +++ b/packages/editor/src/nodeviews/UtteranceNodeView.ts @@ -166,7 +166,7 @@ export class UtteranceNodeView implements NodeView { private _refreshSepEl(continuationOfId: string | null): void { if (continuationOfId) { this._sepEl.className = 'utt-participant-sep utt-continuation-mark' - this._sepEl.textContent = '↪' + this._sepEl.textContent = '⤤' } else { this._sepEl.className = 'utt-participant-sep' this._sepEl.textContent = ':' diff --git a/packages/editor/src/plugins/playback-plugins.ts b/packages/editor/src/plugins/playback-plugins.ts index 496b88d..981837a 100644 --- a/packages/editor/src/plugins/playback-plugins.ts +++ b/packages/editor/src/plugins/playback-plugins.ts @@ -104,6 +104,18 @@ export function buildContinuationHeadPlugin(): Plugin { }) } +function _makeHeadMarkEl(): HTMLSpanElement { + const span = document.createElement('span') + span.className = 'utt-head-mark' + // U+2060 word-joiner as first text character: the line-breaking algorithm + // processes it as real inline text in both Chrome and Firefox, so it + // suppresses the break between any preceding trailing space and this glyph. + // (A CSS ::after pseudo-element is a separate formatting object in Firefox + // and the WJ cannot cross that boundary.) + span.textContent = '⁠⤦' + return span +} + function _buildContinuationHeadDecos(doc: Parameters[0]): DecorationSet { // Collect continuations per head, in doc order (forEach is doc order) const contsByHead = new Map>() @@ -128,11 +140,15 @@ function _buildContinuationHeadDecos(doc: Parameters