mirror of
https://github.com/codex-team/editor.js
synced 2024-06-29 02:40:23 +02:00
Fire onChange event for native inputs
This commit is contained in:
parent
ff91466b14
commit
43af5a9fa1
|
@ -50,6 +50,7 @@
|
||||||
"DOMRect": true,
|
"DOMRect": true,
|
||||||
"ClientRect": true,
|
"ClientRect": true,
|
||||||
"ArrayLike": true,
|
"ArrayLike": true,
|
||||||
|
"InputEvent": true,
|
||||||
"unknown": true
|
"unknown": true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -50,6 +50,7 @@
|
||||||
"@codexteam/shortcuts": "^1.1.1",
|
"@codexteam/shortcuts": "^1.1.1",
|
||||||
"@cypress/code-coverage": "^3.9.2",
|
"@cypress/code-coverage": "^3.9.2",
|
||||||
"@cypress/webpack-preprocessor": "^5.6.0",
|
"@cypress/webpack-preprocessor": "^5.6.0",
|
||||||
|
"@editorjs/code": "^2.7.0",
|
||||||
"@editorjs/header": "^2.6.1",
|
"@editorjs/header": "^2.6.1",
|
||||||
"@editorjs/simple-image": "^1.4.1",
|
"@editorjs/simple-image": "^1.4.1",
|
||||||
"@types/node": "^14.14.35",
|
"@types/node": "^14.14.35",
|
||||||
|
|
|
@ -52,7 +52,7 @@ interface BlockConstructorOptions {
|
||||||
/**
|
/**
|
||||||
* Tunes data for current Block
|
* 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}}
|
* @returns {{wrapper: string, content: string}}
|
||||||
*/
|
*/
|
||||||
public static get CSS(): {[name: string]: string} {
|
public static get CSS(): { [name: string]: string } {
|
||||||
return {
|
return {
|
||||||
wrapper: 'ce-block',
|
wrapper: 'ce-block',
|
||||||
wrapperStretched: 'ce-block--stretched',
|
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,
|
* 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
|
* 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
|
* Editor`s API module
|
||||||
|
@ -201,11 +201,15 @@ export default class Block extends EventsDispatcher<BlockEvents> {
|
||||||
/**
|
/**
|
||||||
* Is fired when DOM mutation has been happened
|
* Is fired when DOM mutation has been happened
|
||||||
*/
|
*/
|
||||||
private didMutated = _.debounce((mutations: MutationRecord[] = []): void => {
|
private didMutated = _.debounce((mutationsOrInputEvent: MutationRecord[] | InputEvent = []): void => {
|
||||||
const shouldFireUpdate = !mutations.some(({ addedNodes = [], removedNodes }) => {
|
const shouldFireUpdate = mutationsOrInputEvent instanceof InputEvent ||
|
||||||
return [...Array.from(addedNodes), ...Array.from(removedNodes)]
|
!mutationsOrInputEvent.some(({
|
||||||
.some(node => $.isElement(node) && (node as HTMLElement).dataset.mutationFree === 'true');
|
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
|
* 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}
|
* @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 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(),
|
...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
|
* 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.
|
* Can be useful for block changes invisible for editor core.
|
||||||
*/
|
*/
|
||||||
public dispatchChange(): void{
|
public dispatchChange(): void {
|
||||||
this.didMutated();
|
this.didMutated();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -775,7 +779,7 @@ export default class Block extends EventsDispatcher<BlockEvents> {
|
||||||
* @param tunesData - current Block tunes data
|
* @param tunesData - current Block tunes data
|
||||||
* @private
|
* @private
|
||||||
*/
|
*/
|
||||||
private composeTunes(tunesData: {[name: string]: BlockTuneData}): void {
|
private composeTunes(tunesData: { [name: string]: BlockTuneData }): void {
|
||||||
Array.from(this.tunes.values()).forEach((tune) => {
|
Array.from(this.tunes.values()).forEach((tune) => {
|
||||||
const collection = tune.isInternal ? this.defaultTunesInstances : this.tunesInstances;
|
const collection = tune.isInternal ? this.defaultTunesInstances : this.tunesInstances;
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
import Header from '@editorjs/header';
|
import Header from '@editorjs/header';
|
||||||
|
import Code from '@editorjs/code';
|
||||||
import { BlockMutationType } from '../../../types/events/block/mutation-type';
|
import { BlockMutationType } from '../../../types/events/block/mutation-type';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -16,6 +17,7 @@ describe('onChange callback', () => {
|
||||||
const config = {
|
const config = {
|
||||||
tools: {
|
tools: {
|
||||||
header: Header,
|
header: Header,
|
||||||
|
code: Code,
|
||||||
},
|
},
|
||||||
onChange: (api, event): void => {
|
onChange: (api, event): void => {
|
||||||
console.log('something changed', api, event);
|
console.log('something changed', api, event);
|
||||||
|
@ -47,7 +49,7 @@ describe('onChange callback', () => {
|
||||||
type: BlockMutationType.Added,
|
type: BlockMutationType.Added,
|
||||||
detail: {
|
detail: {
|
||||||
target: {
|
target: {
|
||||||
name: 'paragraph'
|
name: 'paragraph',
|
||||||
},
|
},
|
||||||
index: 0,
|
index: 0,
|
||||||
},
|
},
|
||||||
|
@ -67,7 +69,7 @@ describe('onChange callback', () => {
|
||||||
type: BlockMutationType.Added,
|
type: BlockMutationType.Added,
|
||||||
detail: {
|
detail: {
|
||||||
target: {
|
target: {
|
||||||
name: 'paragraph'
|
name: 'paragraph',
|
||||||
},
|
},
|
||||||
index: 1,
|
index: 1,
|
||||||
},
|
},
|
||||||
|
@ -85,7 +87,7 @@ describe('onChange callback', () => {
|
||||||
cy.get('@onChange').should('be.calledWithMatch', EditorJSApiMock, Cypress.sinon.match({
|
cy.get('@onChange').should('be.calledWithMatch', EditorJSApiMock, Cypress.sinon.match({
|
||||||
type: BlockMutationType.Changed,
|
type: BlockMutationType.Changed,
|
||||||
detail: {
|
detail: {
|
||||||
index: 0
|
index: 0,
|
||||||
},
|
},
|
||||||
}));
|
}));
|
||||||
});
|
});
|
||||||
|
@ -185,7 +187,7 @@ describe('onChange callback', () => {
|
||||||
cy.get('@onChange').should('be.calledWithMatch', EditorJSApiMock, Cypress.sinon.match({
|
cy.get('@onChange').should('be.calledWithMatch', EditorJSApiMock, Cypress.sinon.match({
|
||||||
type: BlockMutationType.Removed,
|
type: BlockMutationType.Removed,
|
||||||
detail: {
|
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,
|
||||||
|
},
|
||||||
|
}));
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -1423,6 +1423,11 @@
|
||||||
debug "^3.1.0"
|
debug "^3.1.0"
|
||||||
lodash.once "^4.1.1"
|
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":
|
"@editorjs/header@^2.6.1":
|
||||||
version "2.6.1"
|
version "2.6.1"
|
||||||
resolved "https://registry.yarnpkg.com/@editorjs/header/-/header-2.6.1.tgz#454a46e4dbb32ae3aa1db4d22b0ddf2cc36c3134"
|
resolved "https://registry.yarnpkg.com/@editorjs/header/-/header-2.6.1.tgz#454a46e4dbb32ae3aa1db4d22b0ddf2cc36c3134"
|
||||||
|
|
Loading…
Reference in a new issue