Skip to content

Commit 6adc025

Browse files
committed
fix: update presentation when typing inside table in sdt
1 parent 34a68a8 commit 6adc025

File tree

3 files changed

+45
-1
lines changed

3 files changed

+45
-1
lines changed

packages/layout-engine/layout-bridge/src/cache.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,14 @@ const hashRuns = (block: FlowBlock): string => {
141141
const cellBlocks = cell.blocks ?? (cell.paragraph ? [cell.paragraph] : []);
142142

143143
for (const cellBlock of cellBlocks) {
144+
if (cellBlock?.kind === 'table') {
145+
// Nested tables inside table cells must contribute to the parent
146+
// table cache key, otherwise edits can be missed until a later
147+
// broader invalidation.
148+
cellHashes.push(`nt:${hashRuns(cellBlock as FlowBlock)}`);
149+
continue;
150+
}
151+
144152
const paragraphBlock = cellBlock as ParagraphBlock;
145153

146154
// Safety: Check that runs array exists before iterating

packages/layout-engine/painters/dom/src/renderer.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7335,6 +7335,10 @@ const deriveBlockVersion = (block: FlowBlock): string => {
73357335
hash = hashString(hash, getRunStringProp(run, 'vertAlign'));
73367336
hash = hashNumber(hash, getRunNumberProp(run, 'baselineShift'));
73377337
}
7338+
} else if (cellBlock?.kind) {
7339+
// Include nested non-paragraph blocks (notably nested tables inside
7340+
// table cells) so edits there invalidate this parent table version.
7341+
hash = hashString(hash, deriveBlockVersion(cellBlock as FlowBlock));
73387342
}
73397343
}
73407344
}

packages/super-editor/src/editors/v1/core/presentation-editor/pointer-events/EditorInputManager.ts

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1278,9 +1278,13 @@ export class EditorInputManager {
12781278
if (!handledByDepth) {
12791279
try {
12801280
// SD-1584: clicking inside a block SDT selects the node (NodeSelection).
1281+
// Exception: clicks inside tables nested in this SDT should use text
1282+
// selection so caret placement/editing inside table cells works.
12811283
const sdtBlock = clickDepth === 1 ? this.#findStructuredContentBlockAtPos(doc, hit.pos) : null;
12821284
let nextSelection: Selection;
1283-
if (sdtBlock) {
1285+
const insideTableInSdt =
1286+
!!sdtBlock && this.#isInsideTableWithinStructuredContentBlock(doc, hit.pos, sdtBlock.pos);
1287+
if (sdtBlock && !insideTableInSdt) {
12841288
nextSelection = NodeSelection.create(doc, sdtBlock.pos);
12851289
} else {
12861290
nextSelection = TextSelection.create(doc, hit.pos);
@@ -1585,6 +1589,34 @@ export class EditorInputManager {
15851589
return null;
15861590
}
15871591

1592+
#isInsideTableWithinStructuredContentBlock(doc: ProseMirrorNode, pos: number, sdtPos: number): boolean {
1593+
if (!Number.isFinite(pos) || !Number.isFinite(sdtPos)) return false;
1594+
1595+
try {
1596+
const $pos = doc.resolve(pos);
1597+
let tableDepth = -1;
1598+
let blockDepth = -1;
1599+
1600+
for (let depth = $pos.depth; depth > 0; depth--) {
1601+
const nodeName = $pos.node(depth)?.type?.name;
1602+
if (tableDepth === -1 && nodeName === 'table') {
1603+
tableDepth = depth;
1604+
}
1605+
if (nodeName === 'structuredContentBlock') {
1606+
const candidatePos = $pos.before(depth);
1607+
if (candidatePos === sdtPos) {
1608+
blockDepth = depth;
1609+
break;
1610+
}
1611+
}
1612+
}
1613+
1614+
return tableDepth !== -1 && blockDepth !== -1 && tableDepth > blockDepth;
1615+
} catch {
1616+
return false;
1617+
}
1618+
}
1619+
15881620
#findStructuredContentBlockById(doc: ProseMirrorNode, id: string): StructuredContentSelection | null {
15891621
let found: StructuredContentSelection | null = null;
15901622
doc.descendants((node, pos) => {

0 commit comments

Comments
 (0)