diff --git a/packages/layout-engine/pm-adapter/src/sdt/document-part-object.test.ts b/packages/layout-engine/pm-adapter/src/sdt/document-part-object.test.ts index 767398b0f1..72c4de5159 100644 --- a/packages/layout-engine/pm-adapter/src/sdt/document-part-object.test.ts +++ b/packages/layout-engine/pm-adapter/src/sdt/document-part-object.test.ts @@ -438,6 +438,34 @@ describe('document-part-object', () => { }); }); + // ==================== Table Children Tests ==================== + describe('Table children', () => { + it('should process tableOfContents children for non-"Table of Contents" gallery types (e.g. "Custom Table of Contents")', () => { + const tocNode: PMNode = { + type: 'tableOfContents', + content: [{ type: 'paragraph', content: [] }], + attrs: { instruction: 'TOC \\o "1-3"' }, + }; + const node: PMNode = { + type: 'documentPartObject', + content: [tocNode], + attrs: { docPartGallery: 'Custom Table of Contents' }, + }; + + vi.mocked(metadataModule.getDocPartGallery).mockReturnValue('Custom Table of Contents'); + vi.mocked(metadataModule.getDocPartObjectId).mockReturnValue('toc-1'); + vi.mocked(metadataModule.getNodeInstruction).mockReturnValue(undefined); + vi.mocked(metadataModule.resolveNodeSdtMetadata).mockReturnValue(undefined as never); + + handleDocumentPartObjectNode(node, mockContext); + + expect(tocModule.processTocChildren).toHaveBeenCalledOnce(); + const callArgs = vi.mocked(tocModule.processTocChildren).mock.calls[0]; + expect(callArgs[0]).toEqual(tocNode.content); + expect(callArgs[1]).toMatchObject({ docPartGallery: 'Custom Table of Contents' }); + }); + }); + // ==================== Edge Cases ==================== describe('Edge cases', () => { it('should handle docPartGallery with different case sensitivity', () => { diff --git a/packages/layout-engine/pm-adapter/src/sdt/document-part-object.ts b/packages/layout-engine/pm-adapter/src/sdt/document-part-object.ts index 045ca3c91b..5e54fe5a1f 100644 --- a/packages/layout-engine/pm-adapter/src/sdt/document-part-object.ts +++ b/packages/layout-engine/pm-adapter/src/sdt/document-part-object.ts @@ -75,6 +75,24 @@ export function handleDocumentPartObjectNode(node: PMNode, context: NodeHandlerC blocks.push(block); recordBlockKind?.(block.kind); } + } else if (child.type === 'tableOfContents' && Array.isArray(child.content)) { + // A nested tableOfContents node (e.g. from a "Custom Table of Contents" SDT where + // the TOC field codes were preprocessed into an sd:tableOfContents element) + processTocChildren( + child.content, + { docPartGallery: docPartGallery ?? '', docPartObjectId, tocInstruction, sdtMetadata: docPartSdtMetadata }, + { + nextBlockId, + positions, + bookmarks, + hyperlinkConfig, + enableComments, + trackedChangesConfig, + converters, + converterContext, + }, + { blocks, recordBlockKind }, + ); } } }