Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -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', () => {
Expand Down
18 changes: 18 additions & 0 deletions packages/layout-engine/pm-adapter/src/sdt/document-part-object.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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 },
Comment on lines +82 to +83
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Preserve nested TOC instruction when forwarding child nodes

The new non-"Table of Contents" branch calls processTocChildren with child.content instead of the tableOfContents node itself, which drops the nested node context where processTocChildren reads getNodeInstruction(child) (toc.ts). In documents where a custom gallery stores the TOC field code on the nested tableOfContents node (the case this patch targets), tocInstruction now stays undefined and paragraph TOC metadata is incomplete, so downstream TOC behavior can differ from the standard gallery path.

Useful? React with 👍 / 👎.

{
nextBlockId,
positions,
bookmarks,
hyperlinkConfig,
enableComments,
trackedChangesConfig,
converters,
converterContext,
},
{ blocks, recordBlockKind },
);
}
}
}
Expand Down
Loading