Fire onChange event for native inputs (#1832)

* Fire onChange event for native inputs

* Add changelog
This commit is contained in:
George Berezhnoy 2022-01-13 19:12:08 +03:00 committed by GitHub
parent 95141f0a2d
commit e3db19df84
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 50 additions and 16 deletions

View file

@ -50,6 +50,7 @@
"DOMRect": true,
"ClientRect": true,
"ArrayLike": true,
"InputEvent": true,
"unknown": true
}
}

View file

@ -21,6 +21,7 @@
- `Refactoring` — Toolbox became a standalone class instead of a Module. It can be accessed only through the Toolbar module.
- `Refactoring` — CI flow optimized.
- `Fix` - Recognize async `onPaste` handlers in tools [#1803](https://github.com/codex-team/editor.js/issues/1803).
- `Fix` — Fire onChange event for native inputs [#1750](https://github.com/codex-team/editor.js/issues/1750)
### 2.22.3

View file

@ -50,6 +50,7 @@
"@codexteam/shortcuts": "^1.1.1",
"@cypress/code-coverage": "^3.9.2",
"@cypress/webpack-preprocessor": "^5.6.0",
"@editorjs/code": "^2.7.0",
"@editorjs/header": "^2.6.1",
"@editorjs/simple-image": "^1.4.1",
"@types/node": "^14.14.35",

View file

@ -52,7 +52,7 @@ interface BlockConstructorOptions {
/**
* Tunes data for current Block
*/
tunesData: {[name: string]: BlockTuneData};
tunesData: { [name: string]: BlockTuneData };
}
/**
@ -98,7 +98,7 @@ export default class Block extends EventsDispatcher<BlockEvents> {
*
* @returns {{wrapper: string, content: string}}
*/
public static get CSS(): {[name: string]: string} {
public static get CSS(): { [name: string]: string } {
return {
wrapper: 'ce-block',
wrapperStretched: 'ce-block--stretched',
@ -170,7 +170,7 @@ export default class Block extends EventsDispatcher<BlockEvents> {
* If there is saved data for Tune which is not available at the moment,
* we will store it here and provide back on save so data is not lost
*/
private unavailableTunesData: {[name: string]: BlockTuneData} = {};
private unavailableTunesData: { [name: string]: BlockTuneData } = {};
/**
* Editor`s API module
@ -201,11 +201,15 @@ export default class Block extends EventsDispatcher<BlockEvents> {
/**
* Is fired when DOM mutation has been happened
*/
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');
});
private didMutated = _.debounce((mutationsOrInputEvent: MutationRecord[] | InputEvent = []): void => {
const shouldFireUpdate = mutationsOrInputEvent instanceof InputEvent ||
!mutationsOrInputEvent.some(({
addedNodes = [],
removedNodes,
}) => {
return [...Array.from(addedNodes), ...Array.from(removedNodes)]
.some(node => $.isElement(node) && (node as HTMLElement).dataset.mutationFree === 'true');
});
/**
* In case some mutation free elements are added or removed, do not trigger didMutated event
@ -575,9 +579,9 @@ export default class Block extends EventsDispatcher<BlockEvents> {
*
* @returns {object}
*/
public async save(): Promise<void|SavedData> {
public async save(): Promise<void | SavedData> {
const extractedBlock = await this.toolInstance.save(this.pluginsContent as HTMLElement);
const tunesData: {[name: string]: BlockTuneData} = this.unavailableTunesData;
const tunesData: { [name: string]: BlockTuneData } = this.unavailableTunesData;
[
...this.tunesInstances.entries(),
@ -706,7 +710,7 @@ export default class Block extends EventsDispatcher<BlockEvents> {
* 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{
public dispatchChange(): void {
this.didMutated();
}
@ -775,7 +779,7 @@ export default class Block extends EventsDispatcher<BlockEvents> {
* @param tunesData - current Block tunes data
* @private
*/
private composeTunes(tunesData: {[name: string]: BlockTuneData}): void {
private composeTunes(tunesData: { [name: string]: BlockTuneData }): void {
Array.from(this.tunes.values()).forEach((tune) => {
const collection = tune.isInternal ? this.defaultTunesInstances : this.tunesInstances;

View file

@ -1,4 +1,5 @@
import Header from '@editorjs/header';
import Code from '@editorjs/code';
import { BlockMutationType } from '../../../types/events/block/mutation-type';
/**
@ -16,6 +17,7 @@ describe('onChange callback', () => {
const config = {
tools: {
header: Header,
code: Code,
},
onChange: (api, event): void => {
console.log('something changed', api, event);
@ -47,7 +49,7 @@ describe('onChange callback', () => {
type: BlockMutationType.Added,
detail: {
target: {
name: 'paragraph'
name: 'paragraph',
},
index: 0,
},
@ -67,7 +69,7 @@ describe('onChange callback', () => {
type: BlockMutationType.Added,
detail: {
target: {
name: 'paragraph'
name: 'paragraph',
},
index: 1,
},
@ -85,7 +87,7 @@ describe('onChange callback', () => {
cy.get('@onChange').should('be.calledWithMatch', EditorJSApiMock, Cypress.sinon.match({
type: BlockMutationType.Changed,
detail: {
index: 0
index: 0,
},
}));
});
@ -185,7 +187,7 @@ describe('onChange callback', () => {
cy.get('@onChange').should('be.calledWithMatch', EditorJSApiMock, Cypress.sinon.match({
type: BlockMutationType.Removed,
detail: {
index: 0
index: 0,
},
}));
});
@ -219,4 +221,24 @@ describe('onChange callback', () => {
},
}));
});
it('should fire onChange if something changed inside native input', () => {
createEditor([ {
type: 'code',
data: {
code: '',
},
} ]);
cy.get('[data-cy=editorjs')
.get('textarea')
.type('Some input to the textarea');
cy.get('@onChange').should('be.calledWithMatch', EditorJSApiMock, Cypress.sinon.match({
type: BlockMutationType.Changed,
detail: {
index: 0,
},
}));
});
});

View file

@ -1423,6 +1423,11 @@
debug "^3.1.0"
lodash.once "^4.1.1"
"@editorjs/code@^2.7.0":
version "2.7.0"
resolved "https://registry.yarnpkg.com/@editorjs/code/-/code-2.7.0.tgz#0a21de9ac15e4533605ffcc80969513ab2142ac5"
integrity sha512-gXtTce915fHp3H9i4IqhTxEDbbkT2heFfYiW/bhFHsCmZDpyGzfZxi94kmrEqDmbxXjV49ZZ6GZbR26If13KJw==
"@editorjs/header@^2.6.1":
version "2.6.1"
resolved "https://registry.yarnpkg.com/@editorjs/header/-/header-2.6.1.tgz#454a46e4dbb32ae3aa1db4d22b0ddf2cc36c3134"