diff --git a/blocksuite/affine/block-paragraph/src/adapters/html.ts b/blocksuite/affine/block-paragraph/src/adapters/html.ts index d5a0e4aca3..3e52c62adc 100644 --- a/blocksuite/affine/block-paragraph/src/adapters/html.ts +++ b/blocksuite/affine/block-paragraph/src/adapters/html.ts @@ -3,9 +3,10 @@ import { BlockHtmlAdapterExtension, type BlockHtmlAdapterMatcher, HastUtils, + type HtmlAST, } from '@blocksuite/affine-shared/adapters'; import type { DeltaInsert } from '@blocksuite/inline'; -import { nanoid } from '@blocksuite/store'; +import { nanoid, type NodeProps } from '@blocksuite/store'; const paragraphBlockMatchTags = new Set([ 'p', @@ -22,6 +23,20 @@ const paragraphBlockMatchTags = new Set([ 'footer', ]); +const tagsInAncestor = (o: NodeProps, tagNames: Array) => { + 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 = { flavour: ParagraphBlockSchema.model.flavour, toMatch: o => @@ -70,7 +85,7 @@ export const paragraphBlockHtmlAdapterMatcher: BlockHtmlAdapterMatcher = { case 'footer': { if ( o.parent?.node.type === 'element' && - !['li', 'p'].includes(o.parent.node.tagName) && + !tagsInAncestor(o, ['p', 'li']) && HastUtils.isParagraphLike(o.node) ) { walkerContext diff --git a/blocksuite/blocks/src/__tests__/adapters/html.unit.spec.ts b/blocksuite/blocks/src/__tests__/adapters/html.unit.spec.ts index 459be24e82..26e885a083 100644 --- a/blocksuite/blocks/src/__tests__/adapters/html.unit.spec.ts +++ b/blocksuite/blocks/src/__tests__/adapters/html.unit.spec.ts @@ -2602,4 +2602,48 @@ describe('html to snapshot', () => { }); expect(nanoidReplacement(rawBlockSnapshot)).toEqual(blockSnapshot); }); + + test('p in ancestor', async () => { + const html = template(`

aaa

`); + 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); + }); }); diff --git a/blocksuite/framework/store/src/adapter/base.ts b/blocksuite/framework/store/src/adapter/base.ts index 00c9bf0eef..adf4ca8652 100644 --- a/blocksuite/framework/store/src/adapter/base.ts +++ b/blocksuite/framework/store/src/adapter/base.ts @@ -228,6 +228,9 @@ export class ASTWalker { } if (this.context._skip) { + if (this._leave) { + await this._leave(o, this.context); + } return; }