feat(block-api): the new dispatchChange() method (#1794)

The new `dispatchChange()` method allows to manually trigger the 'onChange' callback. Useful when Tool made a state mutation that is invisible for editor core.
This commit is contained in:
Peter Savchenko 2021-10-05 23:41:03 +03:00 committed by GitHub
parent 4f15bbc0cb
commit 9c0fc48d89
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 89 additions and 1 deletions

View file

@ -3,6 +3,7 @@
### 2.23.0
- `Improvement` — The `onChange` callback now accepts two arguments: EditorJS API and the CustomEvent with `type` and `detail` allowing to determine what happened with a Block
- `New` *Block API* — The new `dispatchChange()` method allows to manually trigger the 'onChange' callback. Useful when Tool made a state mutation that is invisible for editor core.
### 2.22.3

View file

@ -35,6 +35,8 @@ API for certain Block methods and properties. You can access it through `editor.
`validate(data: BlockToolData): Promise<boolean>` — calls Tool's validate method if exists
`dispatchChange(): void` - Allows to say Editor that Block was changed. Used to manually trigger Editor's 'onChange' callback. Can be useful for block changes invisible for editor core.
## Api object description
Common API interface.

View file

@ -116,6 +116,14 @@ function BlockAPI(
validate(data: BlockToolData): Promise<boolean> {
return block.validate(data);
},
/**
* Allows to say Editor that Block was changed. Used to manually trigger Editor's 'onChange' callback
* Can be useful for block changes invisible for editor core.
*/
dispatchChange(): void {
block.dispatchChange();
},
};
Object.setPrototypeOf(this, blockAPI);

View file

@ -201,7 +201,7 @@ export default class Block extends EventsDispatcher<BlockEvents> {
/**
* Is fired when DOM mutation has been happened
*/
private didMutated = _.debounce((mutations: MutationRecord[]): void => {
private didMutated = _.debounce((mutations: MutationRecord[] = []): void => {
const shouldFireUpdate = !mutations.some(({ addedNodes = [], removedNodes }) => {
return [...Array.from(addedNodes), ...Array.from(removedNodes)]
.some(node => $.isElement(node) && (node as HTMLElement).dataset.mutationFree === 'true');
@ -702,6 +702,14 @@ export default class Block extends EventsDispatcher<BlockEvents> {
this.removeInputEvents();
}
/**
* Allows to say Editor that Block was changed. Used to manually trigger Editor's 'onChange' callback
* Can be useful for block changes invisible for editor core.
*/
public dispatchChange(): void{
this.didMutated();
}
/**
* Call Tool instance destroy method
*/

View file

@ -0,0 +1,63 @@
import { BlockMutationType } from '../../../../types/events/block/mutation-type';
/**
* There will be described test cases of BlockAPI
*/
describe('BlockAPI', () => {
const firstBlock = {
id: 'bwnFX5LoX7',
type: 'paragraph',
data: {
text: 'The first block content mock.',
},
};
const editorDataMock = {
blocks: [
firstBlock,
],
};
/**
* EditorJS API is passed as the first parameter of the onChange callback
*/
const EditorJSApiMock = Cypress.sinon.match.any;
beforeEach(() => {
if (this && this.editorInstance) {
this.editorInstance.destroy();
} else {
const config = {
data: editorDataMock,
onChange: (): void => { console.log('something changed'); },
};
cy.createEditor(config).as('editorInstance');
cy.spy(config, 'onChange').as('onChange');
}
});
/**
* block.dispatchChange();
*/
describe('.dispatchChange()', () => {
/**
* Check that blocks.dispatchChange() triggers Editor 'onChange' callback
*/
it('should trigger onChange with corresponded block', () => {
cy.get('@editorInstance').then(async (editor: any) => {
const block = editor.blocks.getById(firstBlock.id);
block.dispatchChange();
cy.get('@onChange').should('be.calledWithMatch', EditorJSApiMock, Cypress.sinon.match({
type: BlockMutationType.Changed,
detail: {
index: 0,
},
}));
});
});
});
});

View file

@ -67,4 +67,10 @@ export interface BlockAPI {
* @return {Promise<boolean>}
*/
validate(data: BlockToolData): Promise<boolean>;
/**
* Allows to say Editor that Block was changed. Used to manually trigger Editor's 'onChange' callback
* Can be useful for block changes invisible for editor core.
*/
dispatchChange(): void;
}