Skip to content

Commit 4537381

Browse files
fix(behavior-tests): unblock main by fixing 3 failing specs (#2785)
* fix(tests): use findFirstSelectionTarget and drop missing click() call in extract.spec - Line 40: removed superdoc.click() — the method doesn't exist on the fixture and the fixture already focuses the editor on setup. - Line 95: replaceText expects a SelectionTarget; findFirstTextRange returns a TextAddress, which fails doc.replace() validation. Switch to findFirstSelectionTarget. * fix(run-plugin): skip stale lost-keys preservation on accept/reject and mark removal The SD-2517 lost-keys preservation was re-applying values from runNode.attrs.runProperties whenever a key in runPropertiesInlineKeys dropped out of the computed inline props. Two scenarios left stale values in place: 1. Track-change accept/reject: the restored marks are canonical but runNode.runProperties still reflects the pre-resolution (suggested) state, so preservation re-injected the rejected fontFamily/color/etc. 2. User toggles a standalone mark off (bold, italic, underline): the removed mark's value stayed in the run node's runProperties and preservation brought it back, causing new paragraphs created via Enter to inherit stale formatting (SD-2228). Skip preservation during 'acceptReject' transactions, and skip per-key when the transaction batch contains a RemoveMarkStep for that mark type. The SD-2517 heading round-trip case is unaffected (no mark changes occur during zero-edit import → export). --------- Co-authored-by: Caio Pizzol <caiopizzol@icloud.com>
1 parent 262b6a6 commit 4537381

2 files changed

Lines changed: 30 additions & 4 deletions

File tree

packages/super-editor/src/editors/v1/extensions/run/calculateInlineRunPropertiesPlugin.js

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,24 @@ export const calculateInlineRunPropertiesPlugin = (editor) =>
5151
const runType = newState.schema.nodes.run;
5252
if (!runType) return null;
5353

54+
// Track-change accept/reject rewrites marks to a canonical state. Inline-key metadata
55+
// and run.runProperties from the prior (suggested) state are stale and must not be
56+
// re-applied by the SD-2517 lost-keys preservation below.
57+
const isAcceptReject = transactions.some((t) => t.getMeta('inputType') === 'acceptReject');
58+
59+
// Collect mark types the user explicitly removed in this batch — for these, the
60+
// lost-keys preservation must NOT re-apply values from stale run.runProperties.
61+
// Map textStyle attr-keys to 'textStyle' for comparison.
62+
const removedMarkTypes = new Set();
63+
transactions.forEach((t) => {
64+
t.steps.forEach((step) => {
65+
const jsonStep = step.toJSON?.();
66+
if (jsonStep?.stepType === 'removeMark' && jsonStep.mark?.type) {
67+
removedMarkTypes.add(jsonStep.mark.type);
68+
}
69+
});
70+
});
71+
5472
const preservedDerivedKeys = new Set();
5573
const preferExistingKeys = new Set();
5674
transactions.forEach((transaction) => {
@@ -154,16 +172,25 @@ export const calculateInlineRunPropertiesPlugin = (editor) =>
154172
// dropped some of those keys (e.g. fontFamily "matches" the style due to
155173
// mark round-trip comparison), preserve the original keys. The importer saw
156174
// explicit w:rPr in the XML and that decision is authoritative. (SD-2517)
157-
if (hadInlineKeys) {
175+
//
176+
// Skip entirely during accept/reject: the restored marks are canonical, and
177+
// existing run.runProperties still reflect the pre-resolution (suggested) state.
178+
if (hadInlineKeys && !isAcceptReject) {
158179
const computedKeys = new Set(runProperties ? Object.keys(runProperties) : []);
159180
const lostKeys = existingInlineKeys.filter((k) => !computedKeys.has(k));
160181
if (lostKeys.length > 0) {
161182
if (!runProperties) runProperties = {};
162183
lostKeys.forEach((k) => {
184+
// If the user just removed the standalone mark for this key, don't
185+
// preserve the stale value from the run node's runProperties.
186+
// (For textStyle-derived keys, preserve — the import w:rPr is authoritative
187+
// and in-batch textStyle rewrites replace the mark rather than strip a single attr.)
188+
if (removedMarkTypes.has(k)) return;
163189
if (runNode.attrs?.runProperties?.[k] !== undefined) {
164190
runProperties[k] = runNode.attrs.runProperties[k];
165191
}
166192
});
193+
if (runProperties && Object.keys(runProperties).length === 0) runProperties = null;
167194
}
168195
}
169196
const { inlineKeys: newInlineKeys, overrideKeys: newOverrideKeys } = computeSegmentKeys(

tests/behavior/tests/navigation/extract.spec.ts

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { test, expect } from '../../fixtures/superdoc.js';
2-
import { addCommentByText, replaceText, findFirstTextRange } from '../../helpers/document-api.js';
2+
import { addCommentByText, replaceText, findFirstSelectionTarget } from '../../helpers/document-api.js';
33

44
test('@behavior SD-2525: doc.extract returns blocks with nodeIds and full text', async ({ superdoc }) => {
55
await superdoc.type('Hello world');
@@ -37,7 +37,6 @@ test('@behavior SD-2525: doc.extract returns empty arrays when no comments or tr
3737
});
3838

3939
test('@behavior SD-2525: doc.extract returns full text not truncated', async ({ superdoc }) => {
40-
await superdoc.click();
4140
const longText =
4241
'This is a long paragraph that exceeds eighty characters to verify text is not truncated like textPreview is.';
4342
await superdoc.type(longText);
@@ -93,7 +92,7 @@ test('@behavior SD-2525: doc.extract returns comments with entityId and blockId'
9392
test('@behavior SD-2525: doc.extract returns tracked changes', async ({ superdoc }) => {
9493
await superdoc.type('Original text here');
9594

96-
const target = await findFirstTextRange(superdoc.page, 'Original');
95+
const target = await findFirstSelectionTarget(superdoc.page, 'Original');
9796
if (!target) throw new Error('Could not find text range');
9897
await replaceText(superdoc.page, { target, text: 'Modified' }, { changeMode: 'tracked' });
9998

0 commit comments

Comments
 (0)