Skip to content

Commit 0802f9e

Browse files
fix(sequence-field): preserve cached numbering for lowercase seq fields
Only dispatch the SEQ pre-processor for uppercase SEQ instructions so lowercase `seq` fields keep their cached visible result runs instead of being re-resolved. Also recurse into run-wrapped content when extracting resolved text so cached numbers nested inside runs are captured.
1 parent e22088c commit 0802f9e

5 files changed

Lines changed: 60 additions & 4 deletions

File tree

packages/super-editor/src/editors/v1/core/super-converter/field-references/fld-preprocessors/index.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,9 @@ import { extractFieldKeyword } from '../field-keyword.js';
3131
* @returns {InstructionPreProcessor | null} The pre-processor function or null if not found.
3232
*/
3333
export const getInstructionPreProcessor = (instruction) => {
34+
const rawInstructionType = String(instruction ?? '')
35+
.trim()
36+
.split(/\s+/)[0];
3437
const instructionType = extractFieldKeyword(instruction);
3538
switch (instructionType) {
3639
case 'PAGE':
@@ -59,6 +62,7 @@ export const getInstructionPreProcessor = (instruction) => {
5962
case 'STYLEREF':
6063
return preProcessStylerefInstruction;
6164
case 'SEQ':
65+
if (rawInstructionType !== 'SEQ') return null;
6266
return preProcessSeqInstruction;
6367
case 'CITATION':
6468
return preProcessCitationInstruction;

packages/super-editor/src/editors/v1/core/super-converter/field-references/fld-preprocessors/index.test.js

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import { preProcessPageRefInstruction } from './page-ref-preprocessor.js';
77
import { preProcessHyperlinkInstruction } from './hyperlink-preprocessor.js';
88
import { preProcessTocInstruction } from './toc-preprocessor.js';
99
import { preProcessRefInstruction } from './ref-preprocessor.js';
10+
import { preProcessSeqInstruction } from './seq-preprocessor.js';
1011

1112
describe('getInstructionPreProcessor', () => {
1213
const mockDocx = {
@@ -67,6 +68,16 @@ describe('getInstructionPreProcessor', () => {
6768
expect(processor).toBe(expectedProcessor);
6869
});
6970

71+
it('should dispatch uppercase SEQ fields', () => {
72+
const processor = getInstructionPreProcessor('SEQ Figure \\* ARABIC');
73+
expect(processor).toBe(preProcessSeqInstruction);
74+
});
75+
76+
it('should leave lowercase seq fields unprocessed to preserve cached numbering results', () => {
77+
const processor = getInstructionPreProcessor('seq level2 \\*arabic');
78+
expect(processor).toBeNull();
79+
});
80+
7081
it('should return preProcessTocInstruction for TOC instruction', () => {
7182
const instruction = 'TOC \\o "1-3" \\h \\z \\u';
7283
const processor = getInstructionPreProcessor(instruction);

packages/super-editor/src/editors/v1/core/super-converter/field-references/preProcessNodesForFldChar.test.js

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,17 @@ describe('preProcessNodesForFldChar', () => {
120120
]);
121121
});
122122

123+
it('should preserve cached visible result runs for lowercase seq fields', () => {
124+
const { processedNodes } = preProcessNodesForFldChar(complexFieldNodes('seq level2 \\*arabic', '1'), mockDocx);
125+
126+
expect(processedNodes).toHaveLength(5);
127+
expect(processedNodes.some((node) => node.name === 'sd:sequenceField')).toBe(false);
128+
expect(processedNodes[3]).toEqual({
129+
name: 'w:r',
130+
elements: [{ name: 'w:t', elements: [{ type: 'text', text: '1' }] }],
131+
});
132+
});
133+
123134
it('should handle nested fields (PAGEREF within HYPERLINK)', () => {
124135
const nodes = [
125136
{ name: 'w:r', elements: [{ name: 'w:fldChar', attributes: { 'w:fldCharType': 'begin' } }] },

packages/super-editor/src/editors/v1/core/super-converter/v3/handlers/sd/sequenceField/sequence-field-export-routing.test.js

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import { describe, expect, it } from 'vitest';
22
import { exportSchemaToJson } from '../../../../exporter.js';
33
import { translator as runTranslator } from '../../w/r/r-translator.js';
4+
import { translator as sequenceFieldTranslator } from './sequenceField-translator.js';
45

56
const SEQUENCE_FIELD_INSTRUCTION = 'SEQ Figure \\* ARABIC';
67

@@ -30,6 +31,28 @@ function hasFieldCharType(node, fieldType) {
3031
}
3132

3233
describe('sequenceField export routing', () => {
34+
it('extracts cached result text from run-wrapped field content', () => {
35+
const encoded = sequenceFieldTranslator.encode({
36+
nodes: [
37+
{
38+
name: 'sd:sequenceField',
39+
attributes: { instruction: 'seq level2 \\*arabic' },
40+
elements: [
41+
{
42+
type: 'run',
43+
content: [{ type: 'text', text: '1', marks: [] }],
44+
},
45+
],
46+
},
47+
],
48+
nodeListHandler: {
49+
handler: () => [{ type: 'run', content: [{ type: 'text', text: '1', marks: [] }] }],
50+
},
51+
});
52+
53+
expect(encoded.attrs.resolvedNumber).toBe('1');
54+
});
55+
3356
it('exports sequenceField nodes as fldChar + instrText runs', () => {
3457
const exported = exportSchemaToJson({
3558
node: buildSequenceFieldNode(),

packages/super-editor/src/editors/v1/core/super-converter/v3/handlers/sd/sequenceField/sequenceField-translator.js

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -113,10 +113,17 @@ function parseSeqInstruction(instruction) {
113113
*/
114114
function extractResolvedText(content) {
115115
if (!Array.isArray(content)) return '';
116-
return content
117-
.filter((n) => n.type === 'text')
118-
.map((n) => n.text || '')
119-
.join('');
116+
let text = '';
117+
for (const node of content) {
118+
if (!node) continue;
119+
if (node.type === 'text') {
120+
text += node.text || '';
121+
}
122+
if (Array.isArray(node.content)) {
123+
text += extractResolvedText(node.content);
124+
}
125+
}
126+
return text;
120127
}
121128

122129
/** @type {import('@translator').NodeTranslatorConfig} */

0 commit comments

Comments
 (0)