Commit f3bfc71
authored
refactor(config): consolidate track-changes config under modules.trackChanges (SD-2608) (#2847)
* refactor(config): consolidate track-changes config under modules.trackChanges (SD-2608)
track-changes config lived in two places (config.trackChanges for visibility,
config.layoutEngineOptions.trackedChanges for mode/enabled), unlike every other
module which sits under config.modules.*. consumers had to learn three keys
for one module. this adds modules.trackChanges as the canonical path and
keeps both legacy keys working as deprecated aliases with one-time warnings.
- new normalizer in core/helpers resolves canonical + legacy with precedence
new > legacy > derived default, and mirrors values back to legacy paths so
the ~14 internal reads keep working untouched
- accepts all four TrackedChangesMode values (review | original | final | off)
to preserve existing pass-through of layoutEngineOptions.trackedChanges
- suppresses re-warning on a second normalization of the same config object
so write-through values don't look like new legacy usage
- JSDoc, Mintlify docs, and the one SuperDoc.test.js legacy use-site updated
* feat(track-changes): add pairReplacements mode matching Word/ECMA-376 (SD-2607) (#2849)
* feat(track-changes): add pairReplacements mode matching Word/ECMA-376 (SD-2607)
when track changes are on and a user replaces text, SuperDoc groups the
insertion and deletion under one shared id so accepting or rejecting takes
one click (Google-Docs-like). Microsoft Word and ECMA-376 §17.13.5 treat
every <w:ins> and <w:del> as an independent revision with its own required
w:id. a consumer wants their UI to match Word.
this adds modules.trackChanges.pairReplacements (default true preserves
current behaviour). when false, each insertion and each deletion is an
independent change, addressable and resolvable on its own.
- importer: buildTrackedChangeIdMap accepts { pairReplacements }; when
false, skips the adjacent w:del+w:ins pairing so each Word w:id maps to
its own UUID
- insertTrackedChange: no shared id on replacements in unpaired mode
- getChangesByIdToResolve: returns just the single matching mark in
unpaired mode (no neighbor walk)
- wiring: SuperDoc.vue -> editor.options.trackedChanges -> Editor.ts ->
SuperConverter.trackedChangesOptions -> docxImporter
no exporter change needed — <w:ins>/<w:del> are already written per-mark
with their own w:id in both modes. no public API shape change.
* fix(track-changes): address review findings on pairReplacements (SD-2607)
- always walk adjacent same-id marks in getChangesByIdToResolve so a single
logical revision split across multiple segments resolves as one unit; the
unpaired case is handled implicitly because ins/del now have distinct ids
- align changeId with the insertion mark's id so comment threads and the
optional comment reply attach to the same thread in unpaired mode
- simplify id-minting: one primary id anchors the operation; the deletion
mints its own fresh id only when unpaired AND it's a replacement. the
Document API write adapter now gets unpaired revisions when the flag is
off without any adapter-level change
- add trackedChanges?: {...} to EditorOptions so consumers don't need casts
- add an unpaired-mode example snippet to the docs
- extension test now covers the headline guarantee: in unpaired mode,
acceptTrackedChangeById(insertionId) resolves only the insertion, and the
deletion is still independently rejectable by its own id
* fix(types): tighten JSDoc signatures so type-check passes (SD-2608)
the normalizer and tracked-change mapper emit strict typedefs but several
helper signatures were relying on implicit any, and the NORMALIZED_MARKER
symbol indexed an under-typed config object. CI type-check rejected these
once @ts-check saw the full types.
- normalize-track-changes-config.js: explicit JSDoc param types on
helpers, Record<string, any> on config so module/track-chains resolve,
symbol cast for the NORMALIZED_MARKER access
- trackedChangeIdMapper.js: nested walk now propagates pairReplacements
instead of emitting an under-typed WalkContext
* refactor(track-changes): rename pairReplacements → replacements enum (SD-2608)
pairReplacements leaked editor-speak and forced consumers to mentally
invert a boolean to get the Word-style model. rename to a self-documenting
enum that sits alongside future per-behavior siblings under modules.trackChanges.
- public surface: `modules.trackChanges.replacements: 'paired' | 'independent'`
default `'paired'` (no behavior change for existing consumers)
- plumbing: Editor.options.trackedChanges.replacements → SuperConverter
trackedChangesOptions → buildTrackedChangeIdMap; parallel path through
trackedTransaction → replaceStep so user-driven replacements (the Firefox
coalescing path) also honor the flag
- replaceStep now passes id: undefined to markDeletion in 'independent'
mode so the deletion mints its own id — closing the UI-typing gap
- docs: configuration.mdx ParamField + example use the enum; track-changes
extension doc gets a new "Revision model" section explaining paired vs
independent with snippets
- tests: normalizer, mapper, extension, and a new behavior spec
(tracked-change-independent-replacement.spec.ts) exercise the enum
end-to-end across chromium/firefox/webkit; harness + fixture accept a
`replacements` URL param so tests can flip the flag
* docs(track-changes): migrate from extensions to modules (SD-2608)
with SuperDoc moving away from ProseMirror and extensions no longer
appearing in the public nav, track changes reads better as a first-class
module page alongside comments. the new modules/track-changes.mdx
consolidates what consumers actually need: configuration, revision model
(paired vs independent), the Document API (editor.doc.trackChanges.*),
editor commands, events, permissions, and DOCX import/export.
- new: apps/docs/modules/track-changes.mdx modeled on modules/comments.mdx
- nav: docs.json lists modules/track-changes after modules/comments
- redirect: /extensions/track-changes → /modules/track-changes so
bookmarked URLs and external links keep working
- deleted: apps/docs/extensions/track-changes.mdx (was hidden anyway)
- updated: modules/overview, extensions/overview, and superdoc/configuration
cross-links point at the new page
* docs(track-changes): correct docs against codebase + lead with Document API (SD-2608)
audited every claim on modules/track-changes.mdx against packages/ and fixed
the drift. the Document API is now the primary surface; legacy editor
commands are grouped under a single deprecated section.
corrections:
- event payload is flat ({ type: 'trackedChange', event, changeId, ... }),
not nested under { type, comment }. fields trackedChangeType, trackedChangeText,
deletedText, trackedChangeDisplayType, author, authorEmail, date, importedAuthor
come straight from comments-plugin.js:1134
- event values pulled from shared/common/event-types.ts: add, update, deleted,
resolved, selected, change-accepted, change-rejected
- permissions include RESOLVE_OWN / RESOLVE_OTHER (accept) alongside
REJECT_OWN / REJECT_OTHER (permission-helpers.js:3-12)
- trackChanges.list() returns .items (not .changes) per DiscoveryOutput
- removed disableTrackChangesShowFinal() — not implemented
- mark names confirmed: trackInsert / trackDelete / trackFormat
restructuring:
- Document API section moved up and gets the full TrackChangeInfo shape
- editor.commands usage moved to a "Legacy editor commands" section at the
bottom, wrapped in a Warning banner pointing at the Document API
- voice aligned with brand.md: shorter sentences, concrete examples,
"Import it. Edit it. Export it. Nothing lost." over abstract claims
no code changes.
* docs(track-changes): use Lucide play icon for the example card (SD-2608)
* docs(track-changes): use git-compare icon to match module theming (SD-2608)
* feat(dev-app): add tracked-replacements mode toggle (SD-2608)
expose modules.trackChanges.replacements in the SuperDoc dev app so
developers can test both 'paired' (Google Docs) and 'independent' (Word)
revision models without editing code.
- reads the initial value from ?replacements=independent in the URL so
test links can pin a specific mode
- switching via the header <select> updates the URL param and reloads,
same pattern used by the Layout Engine and View Layout toggles
- moved the legacy top-level trackChanges: { visible: true } config to
modules.trackChanges.{visible, replacements} so the dev app stops
triggering its own deprecation warning1 parent f778c4a commit f3bfc71
27 files changed
Lines changed: 1496 additions & 375 deletions
File tree
- apps/docs
- core/superdoc
- extensions
- modules
- packages
- super-editor/src/editors/v1
- core
- super-converter
- v2/importer
- types
- extensions/track-changes
- trackChangesHelpers
- superdoc/src
- core
- helpers
- types
- dev/components
- tests/behavior
- fixtures
- harness
- tests/comments
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
112 | 112 | | |
113 | 113 | | |
114 | 114 | | |
115 | | - | |
| 115 | + | |
116 | 116 | | |
117 | 117 | | |
118 | 118 | | |
| |||
124 | 124 | | |
125 | 125 | | |
126 | 126 | | |
127 | | - | |
128 | | - | |
| 127 | + | |
| 128 | + | |
129 | 129 | | |
130 | 130 | | |
131 | | - | |
| 131 | + | |
132 | 132 | | |
133 | 133 | | |
134 | 134 | | |
| |||
196 | 196 | | |
197 | 197 | | |
198 | 198 | | |
| 199 | + | |
| 200 | + | |
| 201 | + | |
| 202 | + | |
| 203 | + | |
| 204 | + | |
| 205 | + | |
| 206 | + | |
| 207 | + | |
| 208 | + | |
| 209 | + | |
| 210 | + | |
| 211 | + | |
| 212 | + | |
| 213 | + | |
| 214 | + | |
| 215 | + | |
| 216 | + | |
| 217 | + | |
| 218 | + | |
| 219 | + | |
| 220 | + | |
| 221 | + | |
| 222 | + | |
| 223 | + | |
| 224 | + | |
| 225 | + | |
| 226 | + | |
| 227 | + | |
| 228 | + | |
| 229 | + | |
| 230 | + | |
| 231 | + | |
| 232 | + | |
| 233 | + | |
| 234 | + | |
| 235 | + | |
| 236 | + | |
| 237 | + | |
| 238 | + | |
| 239 | + | |
| 240 | + | |
| 241 | + | |
| 242 | + | |
| 243 | + | |
| 244 | + | |
| 245 | + | |
| 246 | + | |
| 247 | + | |
| 248 | + | |
199 | 249 | | |
200 | 250 | | |
201 | 251 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
154 | 154 | | |
155 | 155 | | |
156 | 156 | | |
| 157 | + | |
157 | 158 | | |
158 | 159 | | |
159 | 160 | | |
| |||
455 | 456 | | |
456 | 457 | | |
457 | 458 | | |
| 459 | + | |
| 460 | + | |
| 461 | + | |
| 462 | + | |
458 | 463 | | |
459 | 464 | | |
460 | 465 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
53 | 53 | | |
54 | 54 | | |
55 | 55 | | |
56 | | - | |
| 56 | + | |
57 | 57 | | |
58 | 58 | | |
59 | 59 | | |
| |||
0 commit comments