fix(editor): enumerate ancestors (#9540)

This commit is contained in:
fourdim
2025-01-07 11:40:10 +00:00
parent 440239809c
commit ebaceb481d
3 changed files with 64 additions and 2 deletions

View File

@@ -3,9 +3,10 @@ import {
BlockHtmlAdapterExtension, BlockHtmlAdapterExtension,
type BlockHtmlAdapterMatcher, type BlockHtmlAdapterMatcher,
HastUtils, HastUtils,
type HtmlAST,
} from '@blocksuite/affine-shared/adapters'; } from '@blocksuite/affine-shared/adapters';
import type { DeltaInsert } from '@blocksuite/inline'; import type { DeltaInsert } from '@blocksuite/inline';
import { nanoid } from '@blocksuite/store'; import { nanoid, type NodeProps } from '@blocksuite/store';
const paragraphBlockMatchTags = new Set([ const paragraphBlockMatchTags = new Set([
'p', 'p',
@@ -22,6 +23,20 @@ const paragraphBlockMatchTags = new Set([
'footer', 'footer',
]); ]);
const tagsInAncestor = (o: NodeProps<HtmlAST>, tagNames: Array<string>) => {
let parent = o.parent;
while (parent) {
if (
HastUtils.isElement(parent.node) &&
tagNames.includes(parent.node.tagName)
) {
return true;
}
parent = parent.parent;
}
return false;
};
export const paragraphBlockHtmlAdapterMatcher: BlockHtmlAdapterMatcher = { export const paragraphBlockHtmlAdapterMatcher: BlockHtmlAdapterMatcher = {
flavour: ParagraphBlockSchema.model.flavour, flavour: ParagraphBlockSchema.model.flavour,
toMatch: o => toMatch: o =>
@@ -70,7 +85,7 @@ export const paragraphBlockHtmlAdapterMatcher: BlockHtmlAdapterMatcher = {
case 'footer': { case 'footer': {
if ( if (
o.parent?.node.type === 'element' && o.parent?.node.type === 'element' &&
!['li', 'p'].includes(o.parent.node.tagName) && !tagsInAncestor(o, ['p', 'li']) &&
HastUtils.isParagraphLike(o.node) HastUtils.isParagraphLike(o.node)
) { ) {
walkerContext walkerContext

View File

@@ -2602,4 +2602,48 @@ describe('html to snapshot', () => {
}); });
expect(nanoidReplacement(rawBlockSnapshot)).toEqual(blockSnapshot); expect(nanoidReplacement(rawBlockSnapshot)).toEqual(blockSnapshot);
}); });
test('p in ancestor', async () => {
const html = template(`<p><b><span>aaa</span></b></p>`);
const blockSnapshot: BlockSnapshot = {
type: 'block',
id: 'matchesReplaceMap[0]',
flavour: 'affine:note',
props: {
xywh: '[0,0,800,95]',
background: DefaultTheme.noteBackgrounColor,
index: 'a0',
hidden: false,
displayMode: NoteDisplayMode.DocAndEdgeless,
},
children: [
{
type: 'block',
id: 'matchesReplaceMap[1]',
flavour: 'affine:paragraph',
props: {
type: 'text',
text: {
'$blocksuite:internal:text$': true,
delta: [
{
attributes: {
bold: true,
},
insert: 'aaa',
},
],
},
},
children: [],
},
],
};
const htmlAdapter = new HtmlAdapter(createJob(), provider);
const rawBlockSnapshot = await htmlAdapter.toBlockSnapshot({
file: html,
});
expect(nanoidReplacement(rawBlockSnapshot)).toEqual(blockSnapshot);
});
}); });

View File

@@ -228,6 +228,9 @@ export class ASTWalker<ONode extends object, TNode extends object | never> {
} }
if (this.context._skip) { if (this.context._skip) {
if (this._leave) {
await this._leave(o, this.context);
}
return; return;
} }