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
49 changes: 49 additions & 0 deletions packages/layout-engine/tests/src/sdt-metadata.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,55 @@ describe('SDT metadata integration', () => {
});
});

it('preserves nested block structuredContent content and metadata', () => {
const nestedBlockDoc = {
type: 'doc',
content: [
{
type: 'structuredContentBlock',
attrs: {
id: 'outer-block-sdt',
tag: 'outer_block',
alias: 'Outer Block',
},
content: [
{
type: 'paragraph',
content: [{ type: 'text', text: 'Outer paragraph' }],
},
{
type: 'structuredContentBlock',
attrs: {
id: 'inner-block-sdt',
tag: 'inner_block',
alias: 'Inner Block',
},
content: [
{
type: 'paragraph',
content: [{ type: 'text', text: 'Inner paragraph' }],
},
],
},
],
},
],
};
const { blocks: nestedBlocks } = toFlowBlocks(nestedBlockDoc);
const innerParagraph = nestedBlocks.find(
(block) => block.kind === 'paragraph' && block.runs?.some((run) => run.text === 'Inner paragraph'),
);

expect(innerParagraph).toBeDefined();
expect(innerParagraph?.attrs?.sdt).toMatchObject({
type: 'structuredContent',
scope: 'block',
id: 'inner-block-sdt',
tag: 'inner_block',
alias: 'Inner Block',
});
});

it('handles nested structuredContent (inline within inline)', () => {
const nestedBlock = summary.find((b) => b.blockId === '2-paragraph');
const outerRun = nestedBlock?.runMetadata.find((r) => r.metadata?.id === 'nested-outer');
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -232,6 +232,10 @@ export function handleStructuredContentBlockNode(node: PMNode, context: NodeHand
// inside this content control is likewise transparent here; render its entry
// paragraphs without advancing currentParagraphIndex, since
// findParagraphsWithSectPr does not recurse structuredContentBlock.
if (child.type === 'structuredContentBlock') {
handleStructuredContentBlockNode(child, context);

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 outer SDT metadata when recursing

When a block SDT directly contains another structuredContentBlock (especially outer SDT -> inner SDT -> paragraph with no direct paragraph/table children on the outer), this recursive call converts the inner subtree with only the inner node's metadata, so no emitted FlowBlock carries the outer structuredContentMetadata. The painter derives block-SDT grouping/chrome from attrs.sdt, so the outer content control effectively disappears from layout/rendering for this valid nested shape; pass the inherited metadata through or record it separately instead of dropping it at the recursion boundary.

Useful? React with 👍 / 👎.

return;
}
if (
Array.isArray(child.content) &&
(child.type === 'documentPartObject' ||
Expand Down
Loading