diff --git a/docs/CHANGELOG.md b/docs/CHANGELOG.md index 2bf0d40f..55ca1e5a 100644 --- a/docs/CHANGELOG.md +++ b/docs/CHANGELOG.md @@ -18,6 +18,7 @@ - `Improvement` - The stub-block style simplified. - `Improvement` - If some Block's tool will throw an error during construction, we will show Stub block instead of skipping it during render - `Improvement` - Call of `blocks.clear()` now will trigger onChange with "block-removed" event for all removed blocks. +- `Improvement` - The `blocks.clear()` now can be awaited. - `Improvement` - `BlockMutationType` and `BlockMutationEvent` types exported - `Improvement` - `blocks.update(id, data)` now can accept partial data object — it will update only passed properties, others will remain the same. - `Improvement` - `blocks.update(id, data)` now will trigger onChange with only `block-change` event. diff --git a/src/components/modules/api/blocks.ts b/src/components/modules/api/blocks.ts index 041b8b54..1d6a782f 100644 --- a/src/components/modules/api/blocks.ts +++ b/src/components/modules/api/blocks.ts @@ -18,7 +18,7 @@ export default class BlocksAPI extends Module { */ public get methods(): Blocks { return { - clear: (): void => this.clear(), + clear: (): Promise => this.clear(), render: (data: OutputData): Promise => this.render(data), renderFromHTML: (data: string): Promise => this.renderFromHTML(data), delete: (index?: number): void => this.delete(index), @@ -172,8 +172,8 @@ export default class BlocksAPI extends Module { /** * Clear Editor's area */ - public clear(): void { - this.Editor.BlockManager.clear(true); + public async clear(): Promise { + await this.Editor.BlockManager.clear(true); this.Editor.InlineToolbar.close(); } @@ -187,9 +187,16 @@ export default class BlocksAPI extends Module { throw new Error('Incorrect data passed to the render() method'); } - await this.Editor.BlockManager.clear(); + /** + * Semantic meaning of the "render" method: "Display the new document over the existing one that stays unchanged" + * So we need to disable modifications observer temporarily + */ + this.Editor.ModificationsObserver.disable(); - return this.Editor.Renderer.render(data.blocks); + await this.Editor.BlockManager.clear(); + await this.Editor.Renderer.render(data.blocks); + + this.Editor.ModificationsObserver.enable(); } /** diff --git a/test/cypress/tests/onchange.cy.ts b/test/cypress/tests/onchange.cy.ts index 61a10d85..a1a32669 100644 --- a/test/cypress/tests/onchange.cy.ts +++ b/test/cypress/tests/onchange.cy.ts @@ -578,7 +578,7 @@ describe('onChange callback', () => { ]); }); - it('should be called on blocks.render() on non-empty editor with removed blocks', () => { + it('should not be called on blocks.render() on non-empty editor', () => { createEditor([ { type: 'paragraph', @@ -608,14 +608,7 @@ describe('onChange callback', () => { })); }); - cy.get('@onChange').should('be.calledWithBatchedEvents', [ - { - type: BlockRemovedMutationType, - }, - { - type: BlockRemovedMutationType, - }, - ]); + cy.get('@onChange').should('have.callCount', 0); }); it('should be called on blocks.update() with "block-changed" event', () => { diff --git a/types/api/blocks.d.ts b/types/api/blocks.d.ts index fdca8d55..c3bf22b1 100644 --- a/types/api/blocks.d.ts +++ b/types/api/blocks.d.ts @@ -9,7 +9,7 @@ export interface Blocks { /** * Remove all blocks from Editor zone */ - clear(): void; + clear(): Promise; /** * Render passed data