π Sync stable β main#3582
Conversation
Merge main into stable
### Bug Fixes - copy-pasted text in suggestion mode (#3576) - center virtualized matches after mount in find nav (SD-3315) - stop find navigation jumping to the reverted caret (SD-3315) - honor the focus() contract + fix dangling docs reference (SD-3312) - don't re-center visible matches on find navigation (SD-3315) - report 'zoom' not 'mixed' for a zoom repaint (SD-3311) - wire pointer-source tracking on all init paths; update export snapshot - reset state on unload, dedupe + export payload types, add core tests - skip empty block SDT content selection - type modules.contentControls exactly (no pass-through index) - allow block SDT wrapper deletion to follow lock rules - promote image-bearing inline SDT wrappers to inline-block - keep block sdt fill behind content - hide block sdt fills in output modes - paint block SDT background on chrome layer - use logical inset for inline SDT label position - anchor inline SDT label to start of chrome - route smartTag through export and preserve smartTagPr in SDT flatten (SD-2647) - include inline SDT chrome width in block SDT bounds - keep block SDT chrome at full fragment width - render and round-trip w:smartTag content (SD-2647) - decouple base64 image helper imports - preserve block ids during metadata updates - ignore covered sdt label clicks - sync block sdt label selection updates - show empty SDT placeholder text in viewing and print modes - skip empty sdt scan on arrow right - preserve permission-only sdt placeholders - preserve comment-only sdt placeholders - preserve empty sdt bookmark placeholders - collapse hidden sdt placeholder text - keep sdt placeholder pm range atomic - trust empty sdt paragraph conversion - keep vanished sdt paragraph side effects - preserve vanished block sdt paragraphs - suppress hidden block sdt chrome - keep remeasured sdt placeholder atomic - transform sdt placeholder measure - remeasure sdt placeholders - hide sdt placeholders in print - hide sdt placeholders in viewing - ignore collapsed inline sdt cut - expose block sdt appearance - hide empty block sdt placeholder - align empty block sdt caret - use measured width for empty SDT placeholders - size SDT block labels to content width - collapse selection on sdtContentLocked delete - allow history transactions through sdt lock - drop unreachable move fallback - target marker-only textblock end - ignore empty block sdt key targets - cap block sdt label width - handle sdt marker gaps and block atoms - skip hidden field annotations in sdt navigation - skip hidden metadata sdt markers - skip hidden block sdt markers - handle marker-only sdt paragraphs - keep visible atoms in sdt navigation - skip hidden sdt navigation markers - target nearest sdt cursor position - respect inline atoms in sdt navigation - handle empty block sdt navigation - avoid restoring dragged block to its source position - exclude sdt chrome labels from caret position lookup - keep text-align enabled in locked SDT paragraphs - block disabled toolbar execution - guard unlisted locked toolbar commands - block locked sdt toolbar execution - reject malformed base64 image data URIs - reuse colliding data uri media targets - enforce upload byte cap for data uris - avoid non-image data uri extensions - reject raw raster data uri dimensions - validate oversized async svg images - register preset raster data uris in place - narrow sdt metadata overrides - normalize image data uri extensions - centralize image data url policy - reuse target image relationships - validate in-place svg payloads - validate field annotation data uri exports - reject malformed data uri files - avoid duplicate image rids - block raw raster data uri exports - reject malformed svg data uri payloads - warn on skipped image exports - reject separatorless data uri files - block non-image data uri exports - read svg data uri dimensions - share data uri media parsing - skip invalid data uri image targets - normalize svg data uri filenames - validate in-place svg image data - guard non-base64 data uri exports - export field annotation svgs as svg - allow non-base64 SVG data URLs in image rendering - mirror in-place image media to parent - decode non-base64 data URI exports - extract shared hash helpers - reuse data URI image exports - support non-base64 data URI images in registration - scope inline SDT placeholder to structuredContent metadata - register sized SVG data URI images without canvas processing - persist data URI images set via setPresetContent - share SDT lock predicates - version inline image metadata - align RTL SDT chrome to text - size SDT chrome for justified lines - honor ancestor image SDT locks - dirty inline image SDT changes - align SDT chrome within paragraph width - preserve SDT chrome continuation offsets - offset block SDT chrome for indents - suppress SDT pseudo hover in viewing mode - allow top-aligned inline images - fit block SDT chrome to actual content width - bottom-align text on lines with inline images - keep block SDT chrome and inline images out of paragraph geometry - disable image resize inside content-locked SDTs - detect inline image run changes in paragraph diff - mark block SDT selected when contained image is selected - select inline SDT content as text on Delete - intercept beforeinput insertText at inline SDT boundaries - delete contentLocked SDT wrapper in one step - bump sdBlockRev on ancestors of inline edits - select inline SDT content as text on Backspace - select inline SDT on Backspace at start of following run (SD-3165) - share structured content chrome label set - resolve block labels at node boundary - use contract label selectors - clear label gesture state on cancel - scope label clicks to owning editor - defer label selection to mouseup so native drag still fires - share structured content label classes - avoid deferred block label retry - select labels with active editor - focus editor after label selection - correct cursor placement and label interactions for structured content - handle cell-level SDT in vMerge column lookup (SD-3289) - preserve cell-level SDT wrapping table cells (SD-3289) - preserve recipient identity attrs on replay (SD-3279) - accept legacy fingerprints in compare/apply (SD-3279) - drop misleading pnpm run type-check hint from audit - structural-fail on missing dist + sync check-jsdoc header - strip session-local sdBlockId from diff fingerprint (SD-3279) - autoFit table width overflow from cell preferences (#3522) - flip public-method-coverage to strict-zero gate (SD-673) - flip jsdoc-hygiene-ts to strict-zero gate (SD-673) - rename jsdoc-hygiene-ts self-tests + wire into CI (fixes vitest discovery on #3511) - jsdoc-hygiene-ts handles private-identifier symbols + README - more bugs - add ui for overlapping delete, other fixes - replacement pair - remaining collab bugs - coalesce tracked inserts across run gaps - restore tracked change comment interactions - expose tracked mark predicate option - more cases - tc fixes - collab mode bug - floating comments fixes - make jsdoc-hygiene-ts baseline key line-independent + update wrapper docs - preserve tab underline via runProperties fallback in collab ### Changes - Merge branch 'main' into caio/sd-3315-find-replace-scroll - Merge pull request #3509 from superdoc-dev/artem/SD-3232 - Merge pull request #3555 from superdoc-dev/luccas/delete-image-content-locked-sdt - Merge branch 'main' into artem/SD-3159 - Merge pull request #3550 from superdoc-dev/luccas/sd-3302-bug-sdt-in-template-builder-shows-grey-background-highlight - Merge branch 'main' into artem/SD-3159 - SD-2676 - fix: table selection not providing a feedback (#3508) - Merge pull request #3549 from superdoc-dev/luccas/left-align-inline-sdt-label - Merge pull request #3546 from superdoc-dev/caio/sd-2647-bug-render-and-round-trip-content-wrapped-in-wsmarttag - Merge remote-tracking branch 'origin/stable' into sync/stable-to-main-20260527-230540 - Merge pull request #3539 from superdoc-dev/caio-pizzol/sd-3289-preserve-cell-level-sdt - Merge pull request #3527 from superdoc-dev/caio-pizzol/sd-3279-strip-sdblockid-from-diff-fingerprint - Merge branch 'main' into caio-pizzol/SD-js-contract-owner-audit - Merge pull request #3531 from superdoc-dev/caio-pizzol/SD-docs-snippet-typecheck-2 - Merge pull request #3526 from superdoc-dev/caio-pizzol/SD-runtime-payload-tests - Merge pull request #3521 from superdoc-dev/caio-pizzol/SD-public-method-coverage-strict-zero - Merge branch 'stable' - Merge pull request #3485 from superdoc-dev/artem/SD-3200 - Merge pull request #3517 from superdoc-dev/caio-pizzol/SD-jsdoc-hygiene-zero-flip - Merge pull request #3513 from superdoc-dev/caio-pizzol/SD-jsdoc-hygiene-cleanup - Merge branch 'stable' - Merge pull request #3511 from superdoc-dev/caio-pizzol/SD-jsdoc-hygiene-scanner - Merge pull request #3435 from superdoc-dev/nick/sd-3220-overlapping-suggestion-contract - Merge pull request #3429 from superdoc-dev/artem/underlined-tab-collab ### Documentation - note content controls in entityAt hit types (SD-3313) - clarify data uri buffer conversion - document image data uri helpers - clarify image registration comments - sync README exit semantics for js contract-owner audit - clarify wrapper-stages prose + add ts-jsdoc to check:public summary ### Features - add ui.contentControls.focus to place the caret in a control (SD-3312) - add ui.viewport.observe geometry-invalidation signal (SD-3311) - add ui.contentControls.scrollIntoView (SD-3310) - add activePath (full active stack) to content-control:active-change - expose public sdt events - select adjacent block SDT content at textblock boundaries - inherit run styles in empty block SDT placeholders - render placeholder text for empty SDTs - move caret into following block sdt on delete - move caret into preceding block sdt on backspace - disable mutation toolbar controls inside content-locked SDTs - render empty inline SDTs as a visible placeholder - add modules.contentControls.chrome - js contract-owner audit, report-only (SD-673) - add snippet typecheck for editor/superdoc/** + fix stale examples (SD-673) - add non-hover field color for sdt (#3506) - comments and tc on small screen (#3446) - overlapping tracked changes - add type-bearing JSDoc hygiene gate for .ts source (SD-673) - add anchored metadata orphan status ### Tests - resolve handleBase64 source path from package or repo root - cover locked block SDT Delete selection - cover nested block SDT boundary selection - update SDT keymap chain coverage - cover contentControlsChrome plumbing; clarify chrome-none comment - assert chrome-none hover suppression and cascade order - add v2 bridge unit + round-trip behavior coverage (SD-2647) - assert smartTag child text survives export round-trip (SD-2647) - cover nested block sdt navigation - roundtrip mixed image block sdts - cover image data uri length boundary - repaint saved sdt images through painter - cover structured content image edges - cover inline image diff fields - cover locked inline SDT beforeinput - cover inline SDT Cmd+X selection - cover inline SDT content Delete flow - clarify inline SDT boundary lock comment - cover two-step inline SDT Backspace - cover inline SDT selection meta escape - use real production payload for list-definitions-change bridge (SD-673) - tighten list-definitions-change bridge assertion (SD-673) - pin list-definitions-change bridge and DELETED comments shape (SD-673) - pin runtime event payload shapes (SD-673) ### Refactoring - consolidate type imports in dom painter - share block sdt navigation helpers - share box model between block and inline sdt labels - share structured content predicates - wrap shared tryDecodeDataUriText re-export - reuse shared data uri export policy - share image relationship export lookup - centralize image data uri parsing - share data uri text decoding - trim data uri metadata fields - extract CHECKED_FILES to shared module + drop audit from wrapper - drop list-item fragment renderer (SD-2851) (#3269) - drain 85 type-bearing JSDoc entries from .ts source (SD-673) ### Performance - avoid scanning data uri media ### Chores - 1.37.0 [skip ci] - fix import breaking delinstrtext orphans (#3535) - fix tests (#3533) - fixes - more fixes - run generate:all and fixes - more fixes - soec fixes - type fixes - ui and more - fix regression - type fixes - more fixes - more fixes - ci fixes - type fixes - add dispatch test for collab bug - review fix, type fix - add tests for metadata issue - tests for review issues
### What's New
**Content Controls API** β Place the caret inside a control, scroll it into view, and track its active state across nesting.
- `ui.contentControls.focus({ id })` β Caret placement inside a control. Scrolls to the control first, then navigates inside. Returns `{ success }` with diagnostic failures like `not-ready` and `not-found`.
- `ui.contentControls.scrollIntoView(id)` β Scroll-only counterpart. Control position resolves from the document model, so off-screen controls work. Scroll-focused, separate from activation.
- `ui.contentControls.observe()` and events now expose `activePath` β Full stack of active controls (innermost first), so nested-aware custom UI only needs one API instead of combining events with observe.
**Viewport geometry observation** β Single rAF-coalesced signal for cached coordinates that may have gone stale.
- `ui.viewport.observe(listener)` β Fires with `{ reason }` (one of `'layout'`, `'zoom'`, `'scroll'`, `'resize'`, `'mixed'`) whenever getRect() results should be re-queried. Replaces hand-wiring scroll + resize + layout + zoom, which silently misses reflow.
**Responsive comments and tracked changes** β Adapt to screen size with automatic or locked display modes.
- Comments and tracked changes switch between sidebar and compact inline popovers based on container width.
- `displayMode: 'auto'` (default) β Automatic breakpoint. `'sidebar'` or `'inline'` lock the mode.
- `compactBreakpointPx` β Exact pixel width where inline mode activates (default 768px).
- `compactMeasurementSelector` β Which container to measure; defaults to the SuperDoc root.
- Inline comment popovers anchor to highlights with overflow-safe bounds and safe margins.
**Smart Tags** β Render and round-trip w:smartTag content from Word.
- Smart tag elements (countries, places, dates, names) now render visibly instead of disappearing.
- w:element, w:uri, and w:smartTagPr metadata persist on import and export.
**Cell-level Structured Document Tags** β Date pickers and other content controls that wrap table cells now import and export correctly.
- Word's `<w:sdt><w:sdtContent><w:tc>` pattern (ECMA-376 Part 1 Β§17.5.2.32) is now recognized and preserved.
- Vertical merge tracking works correctly with SDT-wrapped continuation cells.
**Non-base64 SVG data URIs** β Support inline SVG payloads encoded as URL-safe text.
- `data:image/svg+xml;charset=utf-8,<svg>...` now registers and persists in DOCX output.
- Sized SVG data URIs skip canvas processing and register in place.
### Improvements
**Find and replace** β Navigation is now smooth and predictable.
- Virtualized matches center only when off-screen, skip centering for visible results.
- Selection focus returning to the find input no longer jumps the viewport to a stale caret position.
- Copy-paste in suggestion mode now tracks SuperDoc's internal slice correctly.
**Structured content keyboard interactions** β Boundary behavior matches Word.
- Backspace/Delete at the start of a block SDT's first paragraph selects its content (one keystroke to confirm, one to delete).
- Backspace at the start of a textblock following a block SDT moves the caret inside the SDT instead of deleting across the boundary.
- Delete at the end of a textblock preceding a block SDT moves the caret inside the SDT.
- Backspace/Delete inside an empty inline SDT now selects and deletes the wrapper according to its lock mode.
**Empty structured content placeholders** β Inline and block SDTs now show visible "Click or tap here to enter text" affordances.
- Placeholder runs inherit the paragraph's resolved font, size, and color.
- Caret positioning and input handling work correctly on placeholders.
- Placeholder text is layout-only (no document text), styled via CSS pseudo-element.
**Structured content chrome** β Visual rendering is now robust across layouts and nesting.
- Block SDT background moves to a `::before` pseudo-element behind content, preventing field color from blocking hover/click.
- Block SDT borders move to a `::after` pseudo-element with `pointer-events: none`.
- Chrome sizing accounts for inline SDT wrapper chrome and image run geometry.
- RTL text aligns chrome correctly with `inset-inline-start`.
- Justified paragraphs size chrome for the full content width.
**Image-bearing inline SDTs** β Now promote to `inline-block` so images and chrome size correctly.
**Toolbar controls inside content-locked SDTs** β Mutation commands (format, paragraph, list, table, link, image, track-changes) are now disabled.
- View controls (undo/redo, ruler, zoom, document-mode, formatting marks) remain available.
**Image data URI handling** β Validation and persistence are now comprehensive.
- Malformed base64, oversized payloads, and non-image MIME types are rejected before export.
- SVG and raster data URIs register correctly as DOCX media parts.
- In-place SVG data URIs with known dimensions skip canvas processing.
- Non-base64 data URIs are decoded as text and written through on export.
**Diffing across editor instances** β Cross-editor handoff now works.
- Session-local `sdBlockId` values no longer cause PRECONDITION_FAILED errors when applying diffs to a second editor instance with the same content.
- Legacy snapshots and payloads from before this fix are accepted with fallback normalization.
**Infrastructure** β Type safety and payload correctness are now gated.
- Type-bearing JSDoc in .ts source is now forbidden (gate: strict-zero, no grandfathering).
- Runtime event payload shapes are pinned β `onReady`, `onEditorCreate`, `onLocked`, `onAwarenessUpdate`, `onCommentsUpdate` callbacks are verified against their declared types.
- Documentation examples are type-checked β All "Full Example" code blocks in the SuperDoc docs are checked with `tsc --strict`.
### What's New - **Content Controls API** β `focus()` places the caret inside a control and scrolls it into view; `scrollIntoView()` scrolls controls to a target; `observe()` exposes `activePath` (full nesting stack for nested controls) - **Viewport geometry observation** β `ui.viewport.observe()` fires when cached coordinates go stale, with reason: layout, zoom, scroll, resize, or mixed - **Responsive comments and tracked changes** β Comments and tracked changes auto-switch between sidebar and inline popovers based on screen width (default breakpoint: 768px); lock to either mode with `displayMode` - **Smart Tags** β w:smartTag elements render visibly instead of disappearing; w:element, w:uri, w:smartTagPr metadata persist through round-trip - **Cell-level Structured Document Tags** β Date pickers and content controls wrapping table cells import and export correctly - **Non-base64 SVG data URIs** β Support inline SVG via `data:image/svg+xml;charset=utf-8,<svg>...` format; sized SVGs skip canvas processing ### Improvements - **Find and replace** β Navigation centers off-screen matches only; visible results no longer jump the viewport - **Structured content keyboard behavior** β Backspace and Delete at SDT boundaries match Word behavior - **Empty SDT placeholders** β Inline and block controls show visible "Click or tap here to enter text" affordances - **Structured content rendering** β Chrome displays robustly across layouts, nesting levels, RTL text, and justified paragraphs - **Image-bearing inline SDTs** β Promoted to inline-block so images and chrome size correctly - **Content-locked toolbar** β Mutation commands disabled inside content-locked SDTs; view controls remain available - **Image data URI handling** β Validate and reject malformed base64, oversized payloads, and non-image MIME types; support non-base64 SVG - **Cross-editor diffs** β Diffs apply correctly across editor instances; session-local sdBlockId no longer causes errors - **Type system** β Type-bearing JSDoc in TypeScript source now forbidden; runtime event payload shapes pinned to types; documentation examples type-checked with tsc
### What's New - **Content control navigation** β ui.contentControls.focus() places the caret inside a control; ui.contentControls.scrollIntoView() scrolls to it - **Viewport geometry signal** β ui.viewport.observe emits a single rAF-coalesced notification when layout/zoom/scroll/resize changes - **Public content control events** β content-control:active-change and content-control:click now include full activation stack and source detection (pointer vs. keyboard) - **Chrome control** β modules.contentControls.chrome option to suppress SDT visual chrome for custom styling - **Empty SDT placeholders** β inline and block controls display "Click or tap here to enter text" with inherited paragraph styling - **Smart tags** β w:smartTag elements now render and round-trip with visible content - **Overlapping tracked changes** β multiple tracked changes can occupy the same range in collaboration - **Anchored metadata orphans** β new orphan status for anchored metadata ### Improvements - Find navigation no longer re-centers matches already on-screen - Find navigation stops jumping when focus returns to the search input - Content control navigation skips hidden markers and atoms - SDT labels anchor to the leading edge for visual consistency - Block SDT chrome extends across full fragment width - Inline images top-align with text at baseline - Block SDT backgrounds no longer interfere with hover/click placement - Inline SDT wrappers with images correctly size to content - Empty block SDT paragraphs inherit surrounding text styles - RTL SDT chrome aligns using logical positioning - Paragraph rendering unified between body and table cells - Image helpers unified across all rendering surfaces ### Fixes - Copy-pasted text in suggestion mode no longer reverts - Block SDT deletion respects SDT lock modes - Inline SDT boundaries now handle Delete correctly - Backspace at inline SDT boundaries selects content without selecting chrome - Cell-level SDTs in tables now import, export, and preserve correctly - Vertical merge cells inside SDTs marked correctly - Cross-editor diff application now works (sdBlockId stripped from fingerprint) - Undo/redo works inside content-locked SDTs - Text-align remains visible in locked SDT paragraphs - Image data URIs validated before rendering or export - SVG data URIs work without base64 encoding - Nested table SDTs preserve chrome across fragments - Pointer-source tracking works on all editor initialization paths
Perfect! I can see the release summary in the commit message. Let me refine it to match the SuperDoc voice and terminology: ### What's New - **Content control navigation** β `ui.contentControls.focus()` places the caret inside a control; `ui.contentControls.scrollIntoView()` scrolls to it - **Viewport geometry signal** β `ui.viewport.observe` emits when layout, zoom, scroll, or resize changes (single rAF-coalesced notification) - **Content control events** β `content-control:active-change` and `content-control:click` include full activation stack and source detection (pointer vs. keyboard) - **Content control chrome control** β `modules.contentControls.chrome` option suppresses visual styling for custom UI - **Empty content control placeholders** β Inline and block controls display "Click or tap here to enter text" with inherited paragraph styling - **Smart tags** β `w:smartTag` elements render and round-trip with visible content - **Overlapping tracked changes** β Multiple tracked changes can occupy the same range in collaboration - **Metadata orphan status** β Anchored metadata now reports an orphan status ### Improvements - Find navigation no longer re-centers matches already on-screen - Find navigation stops jumping when focus returns to search input - Content control navigation skips hidden markers and atoms - Content control labels anchor to the leading edge for visual consistency - Block content control chrome extends across full fragment width - Inline images top-align with text at baseline - Block content control backgrounds no longer interfere with hover and click - Inline content control wrappers with images size correctly to content - Empty block content control paragraphs inherit surrounding text styles - RTL content control chrome uses logical positioning - Paragraph rendering unified between body and table cells - Image helpers unified across all rendering surfaces ### Fixes - Copy-pasted text in suggestion mode no longer reverts - Block content control deletion respects lock modes - Inline content control boundaries handle Delete correctly - Backspace at inline content control boundaries selects content without chrome - Cell-level content controls import, export, and preserve correctly - Vertical merge cells inside content controls mark correctly - Cross-editor diff application works (session-local attributes stripped from fingerprint) - Undo/redo works inside content-locked controls - Text-align remains visible in locked content control paragraphs - Image data URIs validated before rendering or export - SVG data URIs work without base64 encoding - Nested table content controls preserve chrome across fragments - Pointer-source tracking works on all editor initialization paths
### What's New
- **Content control navigation API** β `ui.contentControls.focus({ id })` places the caret inside a control; `ui.contentControls.scrollIntoView({ id })` scrolls to it.
- **Viewport geometry signal** β `ui.viewport.observe` emits a single `requestAnimationFrame`-coalesced notification when layout, zoom, scroll, or resize changes. Payload includes the change reason.
- **Overlapping tracked changes** β Multiple tracked changes can now occupy the same range in collaboration scenarios.
- **Enhanced content control events** β `content-control:active-change` now includes `activePath` (full activation stack from innermost first) and improved source detection (pointer vs. keyboard).
- **Cell-level SDT support** β Content controls wrapping individual table cells import, export, and preserve correctly, including vertical merge handling.
- **Smart tags** β `w:smartTag` elements now render with visible content and round-trip with full property metadata.
- **Anchored metadata orphan status** β New status indicator for anchored metadata that loses its anchor point.
- **Chrome control option** β `modules.contentControls.chrome` lets you suppress built-in visual styling for custom UI responsibility.
- **Empty control placeholders** β Inline and block controls display "Click or tap here to enter text" with inherited paragraph styling.
### Improvements
- Find navigation no longer re-centers matches already on-screen, eliminating jarring viewport jumps.
- Find navigation stops jumping when focus returns to the search input during active search.
- Content control navigation skips hidden markers and atoms for more predictable boundary behavior.
- SDT labels anchor to the leading edge instead of center, providing visual consistency.
- Block SDT chrome extends across the full fragment width, maintaining click affordances across line breaks.
- Inline images top-align with text at baseline instead of centering, matching Word's behavior.
- Block SDT backgrounds no longer interfere with hover and click placement.
- Inline SDT wrappers containing images correctly size to content via `inline-block` layout.
- Empty block SDT paragraphs inherit surrounding text styles (font, size, color).
- RTL SDT chrome aligns using logical positioning, respecting document direction.
- Paragraph rendering unified between body and table cells, ensuring consistent behavior across all text containers.
- Image helpers unified across all rendering surfaces (body, tables, fields).
- Copy-pasted text in suggestion mode no longer reverts to previous state.
- Cross-editor diff application now works β session-local `sdBlockId` stripped from fingerprint.
- Malformed image data URIs rejected before rendering or export.
- SVG data URIs work without base64 encoding, preserving vector content.
- Non-base64 SVG payloads support URL-encoded alternatives via `charset=utf-8`.
- Inline SDT chrome width included in block SDT bounds, preventing clipping of nested controls.
- Undo/redo now works inside content-locked SDTs via history transaction bypass.
- Text-align state remains visible in locked SDT paragraphs as a read-only indicator.
- Toolbar mutation controls properly disabled inside content-locked SDTs.
### Fixes
- Backspace at inline SDT boundaries selects content without selecting chrome.
- Cell-level SDTs in tables import, export, and preserve correctly across round-trip.
- Vertical merge cells inside SDTs marked correctly during import.
- Block SDT deletion respects SDT lock modes instead of unconditionally blocking.
- Inline SDT content selected as text on Delete, giving explicit confirm-then-delete UX.
- Inline SDT boundaries handle Delete correctly without escaping into surrounding text.
- Nested table SDTs preserve chrome across fragmented content boundaries.
- Pointer-source tracking works on all editor initialization paths, not just deferred loads.
- Malformed base64 image data URIs now validated before creating DOCX media parts.
- Oversized async SVG images validated for export.
- Vertical merge column lookups find cell-level SDT-wrapped cells correctly.
- Diff fingerprint normalization applied uniformly to all block nodes, not just paragraphs.
- Legacy diff fingerprints accepted in compare/apply for backward compatibility with persisted snapshots.
β¦-20260529-215717
There was a problem hiding this comment.
π‘ Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 37a0e04169
βΉοΈ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with π.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
| "name": "superdoc", | ||
| "type": "module", | ||
| "version": "1.37.0", | ||
| "version": "1.38.0", |
There was a problem hiding this comment.
Regenerate this stable sync as a real merge commit
For this stableβmain sync, the commit object has only one parent (63c71beb...), so even if the PR is merged with GitHub's merge-commit option, main will only gain these copied version files and will not gain the stable branch/tag commits as ancestors. In the release path described by this commit, any prerelease calculation based on merged/reachable stable tags will still miss the latest stable release; please recreate the sync commit with stable as a second parent instead of a single-parent version bump.
Useful? React with πΒ / π.
Codecov Reportβ All modified and coverable lines are covered by tests. π’ Thoughts on this report? Let us know! |
Summary
Merges latest stable patches into main with a real merge commit so stable release tags remain reachable from main.
This keeps
@nextprerelease version calculation ahead of the latest published stable release.Merge requirement
This PR must be merged with GitHub's merge-commit option. Squash or rebase merging will discard stable ancestry and break
@nextversion calculation again.Conflict handling
Merge status:
clean.Version-only release artifact conflicts are auto-resolved to keep stable's already-published versions. Non-version conflicts fail this workflow instead of committing conflict markers.
Auto-created by sync-patches workflow.