mirror of
https://github.com/codex-team/editor.js
synced 2024-06-19 22:25:23 +02:00
fix(tests): fire mutation event on tune activation (#2281)
* fix(onchange): fire mutation event if there are other changes along with mutation-free nodes * update header dependency * use node 16 for windows * fix onChange firing by manual dispatchChange() call * eslint * use node 16 for ci tests * Update CHANGELOG.md
This commit is contained in:
parent
34d4b028c4
commit
dfb07ec4e4
9
.github/workflows/cypress.yml
vendored
9
.github/workflows/cypress.yml
vendored
|
@ -7,6 +7,9 @@ jobs:
|
||||||
image: cypress/browsers:node14.17.0-chrome88-ff89
|
image: cypress/browsers:node14.17.0-chrome88-ff89
|
||||||
options: --user 1001
|
options: --user 1001
|
||||||
steps:
|
steps:
|
||||||
|
- uses: actions/setup-node@v3
|
||||||
|
with:
|
||||||
|
node-version: 16
|
||||||
- uses: actions/checkout@v2
|
- uses: actions/checkout@v2
|
||||||
- run: yarn ci:pull_paragraph
|
- run: yarn ci:pull_paragraph
|
||||||
- uses: cypress-io/github-action@v2
|
- uses: cypress-io/github-action@v2
|
||||||
|
@ -17,6 +20,9 @@ jobs:
|
||||||
chrome:
|
chrome:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
|
- uses: actions/setup-node@v3
|
||||||
|
with:
|
||||||
|
node-version: 16
|
||||||
- uses: actions/checkout@v2
|
- uses: actions/checkout@v2
|
||||||
- run: yarn ci:pull_paragraph
|
- run: yarn ci:pull_paragraph
|
||||||
- uses: cypress-io/github-action@v2
|
- uses: cypress-io/github-action@v2
|
||||||
|
@ -27,6 +33,9 @@ jobs:
|
||||||
edge:
|
edge:
|
||||||
runs-on: windows-latest
|
runs-on: windows-latest
|
||||||
steps:
|
steps:
|
||||||
|
- uses: actions/setup-node@v3
|
||||||
|
with:
|
||||||
|
node-version: 16
|
||||||
- uses: actions/checkout@v2
|
- uses: actions/checkout@v2
|
||||||
- run: yarn ci:pull_paragraph
|
- run: yarn ci:pull_paragraph
|
||||||
- uses: cypress-io/github-action@v2
|
- uses: cypress-io/github-action@v2
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
|
|
||||||
- `Refactoring` — Popover class refactored.
|
- `Refactoring` — Popover class refactored.
|
||||||
- `Improvement` — *Toolbox* — Number of `close()` method calls optimized.
|
- `Improvement` — *Toolbox* — Number of `close()` method calls optimized.
|
||||||
|
- `Improvement` — The `onChange` callback won't be triggered only if all mutations contain nodes with the `data-mutation-free` attributes.
|
||||||
|
|
||||||
### 2.26.5
|
### 2.26.5
|
||||||
|
|
||||||
|
|
|
@ -52,7 +52,7 @@
|
||||||
"@cypress/webpack-preprocessor": "^5.6.0",
|
"@cypress/webpack-preprocessor": "^5.6.0",
|
||||||
"@editorjs/code": "^2.7.0",
|
"@editorjs/code": "^2.7.0",
|
||||||
"@editorjs/delimiter": "^1.2.0",
|
"@editorjs/delimiter": "^1.2.0",
|
||||||
"@editorjs/header": "^2.6.1",
|
"@editorjs/header": "^2.7.0",
|
||||||
"@editorjs/simple-image": "^1.4.1",
|
"@editorjs/simple-image": "^1.4.1",
|
||||||
"@types/node": "^14.14.35",
|
"@types/node": "^14.14.35",
|
||||||
"@types/webpack": "^4.41.12",
|
"@types/webpack": "^4.41.12",
|
||||||
|
|
|
@ -202,16 +202,52 @@ export default class Block extends EventsDispatcher<BlockEvents> {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Is fired when DOM mutation has been happened
|
* Is fired when DOM mutation has been happened
|
||||||
|
*
|
||||||
|
* mutationsOrInputEvent — actual changes
|
||||||
|
* - MutationRecord[] - any DOM change
|
||||||
|
* - InputEvent — <input> change
|
||||||
|
* - undefined — manual triggering of block.dispatchChange()
|
||||||
*/
|
*/
|
||||||
private didMutated = _.debounce((mutationsOrInputEvent: MutationRecord[] | InputEvent = []): void => {
|
private didMutated = _.debounce((mutationsOrInputEvent: MutationRecord[] | InputEvent = undefined): void => {
|
||||||
const shouldFireUpdate = mutationsOrInputEvent instanceof InputEvent ||
|
/**
|
||||||
!mutationsOrInputEvent.some(({
|
* We won't fire a Block mutation event if mutation contain only nodes marked with 'data-mutation-free' attributes
|
||||||
addedNodes = [],
|
*/
|
||||||
removedNodes,
|
let shouldFireUpdate;
|
||||||
}) => {
|
|
||||||
return [...Array.from(addedNodes), ...Array.from(removedNodes)]
|
if (mutationsOrInputEvent === undefined) {
|
||||||
.some(node => $.isElement(node) && (node as HTMLElement).dataset.mutationFree === 'true');
|
shouldFireUpdate = true;
|
||||||
|
} else if (mutationsOrInputEvent instanceof InputEvent) {
|
||||||
|
shouldFireUpdate = true;
|
||||||
|
} else {
|
||||||
|
/**
|
||||||
|
* Update from 2023, Feb 17:
|
||||||
|
* Changed mutationsOrInputEvent.some() to mutationsOrInputEvent.every()
|
||||||
|
* since there could be a real mutations same-time with mutation-free changes,
|
||||||
|
* for example when Block Tune change: block is changing along with FakeCursor (mutation-free) removing
|
||||||
|
* — we should fire 'didMutated' event in that case
|
||||||
|
*/
|
||||||
|
const everyRecordIsMutationFree = mutationsOrInputEvent.length > 0 && mutationsOrInputEvent.every((record) => {
|
||||||
|
const { addedNodes, removedNodes } = record;
|
||||||
|
const changedNodes = [
|
||||||
|
...Array.from(addedNodes),
|
||||||
|
...Array.from(removedNodes),
|
||||||
|
];
|
||||||
|
|
||||||
|
return changedNodes.some((node) => {
|
||||||
|
if ($.isElement(node) === false) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (node as HTMLElement).dataset.mutationFree === 'true';
|
||||||
});
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
if (everyRecordIsMutationFree) {
|
||||||
|
shouldFireUpdate = false;
|
||||||
|
} else {
|
||||||
|
shouldFireUpdate = 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
|
||||||
|
|
|
@ -512,7 +512,7 @@ describe('Editor Tools Api', () => {
|
||||||
/** config specified handled tag */
|
/** config specified handled tag */
|
||||||
public static get pasteConfig(): PasteConfig {
|
public static get pasteConfig(): PasteConfig {
|
||||||
return {
|
return {
|
||||||
tags: ['img'], // only tag name specified. Attributes should be sanitized
|
tags: [ 'img' ], // only tag name specified. Attributes should be sanitized
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -564,7 +564,7 @@ describe('Editor Tools Api', () => {
|
||||||
/** config specified handled tag */
|
/** config specified handled tag */
|
||||||
public static get pasteConfig(): PasteConfig {
|
public static get pasteConfig(): PasteConfig {
|
||||||
return {
|
return {
|
||||||
tags: ['img'], // only tag name specified. Attributes should be sanitized
|
tags: [ 'img' ], // only tag name specified. Attributes should be sanitized
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -221,14 +221,7 @@ describe('onChange callback', () => {
|
||||||
.click();
|
.click();
|
||||||
|
|
||||||
cy.get('[data-cy=editorjs]')
|
cy.get('[data-cy=editorjs]')
|
||||||
.get('span.cdx-settings-button[data-level=4]')
|
.get('.ce-settings .ce-popover-item:nth-child(4)')
|
||||||
.click()
|
|
||||||
/**
|
|
||||||
* For some reason, the first click fires the mutation of removeFakeCursor only, so we need to click again.
|
|
||||||
* Reproduced only in Cypress.
|
|
||||||
*
|
|
||||||
* @todo debug it later
|
|
||||||
*/
|
|
||||||
.click();
|
.click();
|
||||||
|
|
||||||
cy.get('@onChange').should('be.calledWithMatch', EditorJSApiMock, Cypress.sinon.match({
|
cy.get('@onChange').should('be.calledWithMatch', EditorJSApiMock, Cypress.sinon.match({
|
||||||
|
|
14
yarn.lock
14
yarn.lock
|
@ -857,6 +857,11 @@
|
||||||
resolved "https://registry.yarnpkg.com/@codexteam/icons/-/icons-0.1.0.tgz#a02885fe8699f69902d05b077b5f1cd48a2ca6b9"
|
resolved "https://registry.yarnpkg.com/@codexteam/icons/-/icons-0.1.0.tgz#a02885fe8699f69902d05b077b5f1cd48a2ca6b9"
|
||||||
integrity sha512-jW1fWnwtWzcP4FBGsaodbJY3s1ZaRU+IJy1pvJ7ygNQxkQinybJcwXoyt0a5mWwu/4w30A42EWhCrZn8lp4fdw==
|
integrity sha512-jW1fWnwtWzcP4FBGsaodbJY3s1ZaRU+IJy1pvJ7ygNQxkQinybJcwXoyt0a5mWwu/4w30A42EWhCrZn8lp4fdw==
|
||||||
|
|
||||||
|
"@codexteam/icons@^0.0.5":
|
||||||
|
version "0.0.5"
|
||||||
|
resolved "https://registry.yarnpkg.com/@codexteam/icons/-/icons-0.0.5.tgz#d17f39b6a0497c6439f57dd42711817a3dd3679c"
|
||||||
|
integrity sha512-s6H2KXhLz2rgbMZSkRm8dsMJvyUNZsEjxobBEg9ztdrb1B2H3pEzY6iTwI4XUPJWJ3c3qRKwV4TrO3J5jUdoQA==
|
||||||
|
|
||||||
"@codexteam/shortcuts@^1.1.1":
|
"@codexteam/shortcuts@^1.1.1":
|
||||||
version "1.2.0"
|
version "1.2.0"
|
||||||
resolved "https://registry.yarnpkg.com/@codexteam/shortcuts/-/shortcuts-1.2.0.tgz#b8dd7396962b0bd845a5c8f8f19bc6119b520e19"
|
resolved "https://registry.yarnpkg.com/@codexteam/shortcuts/-/shortcuts-1.2.0.tgz#b8dd7396962b0bd845a5c8f8f19bc6119b520e19"
|
||||||
|
@ -944,9 +949,12 @@
|
||||||
version "1.2.0"
|
version "1.2.0"
|
||||||
resolved "https://registry.yarnpkg.com/@editorjs/delimiter/-/delimiter-1.2.0.tgz#5075f1a3e68765cfb6aec8694b316d81e2b41607"
|
resolved "https://registry.yarnpkg.com/@editorjs/delimiter/-/delimiter-1.2.0.tgz#5075f1a3e68765cfb6aec8694b316d81e2b41607"
|
||||||
|
|
||||||
"@editorjs/header@^2.6.1":
|
"@editorjs/header@^2.7.0":
|
||||||
version "2.6.2"
|
version "2.7.0"
|
||||||
resolved "https://registry.yarnpkg.com/@editorjs/header/-/header-2.6.2.tgz#523b6dda72ff882e53f64325840ee7bfc68ee6b7"
|
resolved "https://registry.yarnpkg.com/@editorjs/header/-/header-2.7.0.tgz#755d104a9210a8e2d9ccf22b175b2a93bdbb2330"
|
||||||
|
integrity sha512-4fGKGe2ZYblVqR/P/iw5ieG00uXInFgNMftBMqJRYcB2hUPD30kuu7Sn6eJDcLXoKUMOeqi8Z2AlUxYAmvw7zQ==
|
||||||
|
dependencies:
|
||||||
|
"@codexteam/icons" "^0.0.5"
|
||||||
|
|
||||||
"@editorjs/simple-image@^1.4.1":
|
"@editorjs/simple-image@^1.4.1":
|
||||||
version "1.4.1"
|
version "1.4.1"
|
||||||
|
|
Loading…
Reference in a new issue