Skip to content

Commit eec4cde

Browse files
fix(run-plugin): narrow accept/reject guard to actually-removed keys (#2786)
The previous fix skipped the SD-2517 lost-keys preservation for every inline key whenever an accept/reject transaction ran. That was too broad: in imported docs where explicit w:rPr keys may drop out of computed inline props via style-equivalence, an unrelated accept/reject on the same run stripped those keys from runProperties, losing inline formatting on export. Collect the specific keys removed in this batch instead — mark type name for standalone marks, and each truthy attr key for removed textStyle marks — and only block preservation for those keys. Unrelated inline keys on the same run keep their import-time fallback. Replaces the blanket !isAcceptReject guard introduced in 4537381. Co-authored-by: Caio Pizzol <caiopizzol@icloud.com>
1 parent 4537381 commit eec4cde

File tree

1 file changed

+18
-19
lines changed

1 file changed

+18
-19
lines changed

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

Lines changed: 18 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -51,20 +51,21 @@ 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();
54+
// Collect keys the user (or accept/reject) explicitly removed in this batch so the
55+
// SD-2517 lost-keys preservation below doesn't re-apply their stale run.runProperties.
56+
// - standalone marks (bold, italic, …): the mark's type name is the key.
57+
// - textStyle: each truthy attr on the removed mark is a key (fontFamily, color, …).
58+
const removedKeys = new Set();
6359
transactions.forEach((t) => {
6460
t.steps.forEach((step) => {
6561
const jsonStep = step.toJSON?.();
66-
if (jsonStep?.stepType === 'removeMark' && jsonStep.mark?.type) {
67-
removedMarkTypes.add(jsonStep.mark.type);
62+
if (jsonStep?.stepType !== 'removeMark' || !jsonStep.mark?.type) return;
63+
if (jsonStep.mark.type === 'textStyle') {
64+
Object.entries(jsonStep.mark.attrs || {}).forEach(([key, value]) => {
65+
if (value != null) removedKeys.add(key);
66+
});
67+
} else {
68+
removedKeys.add(jsonStep.mark.type);
6869
}
6970
});
7071
});
@@ -173,19 +174,17 @@ export const calculateInlineRunPropertiesPlugin = (editor) =>
173174
// mark round-trip comparison), preserve the original keys. The importer saw
174175
// explicit w:rPr in the XML and that decision is authoritative. (SD-2517)
175176
//
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) {
177+
// Skip per-key when this batch removed that exact key (toggleItalic off,
178+
// reject of a fontFamily suggestion, etc.) — otherwise we'd re-apply a stale
179+
// value the user just asked us to drop. Unrelated inline keys on the same run
180+
// are left alone so imported w:rPr still survives accept/reject round-trips.
181+
if (hadInlineKeys) {
179182
const computedKeys = new Set(runProperties ? Object.keys(runProperties) : []);
180183
const lostKeys = existingInlineKeys.filter((k) => !computedKeys.has(k));
181184
if (lostKeys.length > 0) {
182185
if (!runProperties) runProperties = {};
183186
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;
187+
if (removedKeys.has(k)) return;
189188
if (runNode.attrs?.runProperties?.[k] !== undefined) {
190189
runProperties[k] = runNode.attrs.runProperties[k];
191190
}

0 commit comments

Comments
 (0)