Skip to content

Commit dfb07ec

Browse files
authored
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
1 parent 34d4b02 commit dfb07ec

File tree

7 files changed

+69
-22
lines changed

7 files changed

+69
-22
lines changed

.github/workflows/cypress.yml

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,9 @@ jobs:
77
image: cypress/browsers:node14.17.0-chrome88-ff89
88
options: --user 1001
99
steps:
10+
- uses: actions/setup-node@v3
11+
with:
12+
node-version: 16
1013
- uses: actions/checkout@v2
1114
- run: yarn ci:pull_paragraph
1215
- uses: cypress-io/github-action@v2
@@ -17,6 +20,9 @@ jobs:
1720
chrome:
1821
runs-on: ubuntu-latest
1922
steps:
23+
- uses: actions/setup-node@v3
24+
with:
25+
node-version: 16
2026
- uses: actions/checkout@v2
2127
- run: yarn ci:pull_paragraph
2228
- uses: cypress-io/github-action@v2
@@ -27,6 +33,9 @@ jobs:
2733
edge:
2834
runs-on: windows-latest
2935
steps:
36+
- uses: actions/setup-node@v3
37+
with:
38+
node-version: 16
3039
- uses: actions/checkout@v2
3140
- run: yarn ci:pull_paragraph
3241
- uses: cypress-io/github-action@v2

docs/CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
- `Refactoring` — Popover class refactored.
66
- `Improvement`*Toolbox* — Number of `close()` method calls optimized.
7+
- `Improvement` — The `onChange` callback won't be triggered only if all mutations contain nodes with the `data-mutation-free` attributes.
78

89
### 2.26.5
910

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@
5252
"@cypress/webpack-preprocessor": "^5.6.0",
5353
"@editorjs/code": "^2.7.0",
5454
"@editorjs/delimiter": "^1.2.0",
55-
"@editorjs/header": "^2.6.1",
55+
"@editorjs/header": "^2.7.0",
5656
"@editorjs/simple-image": "^1.4.1",
5757
"@types/node": "^14.14.35",
5858
"@types/webpack": "^4.41.12",

src/components/block/index.ts

Lines changed: 44 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -202,17 +202,53 @@ export default class Block extends EventsDispatcher<BlockEvents> {
202202

203203
/**
204204
* Is fired when DOM mutation has been happened
205+
*
206+
* mutationsOrInputEvent — actual changes
207+
* - MutationRecord[] - any DOM change
208+
* - InputEvent — <input> change
209+
* - undefined — manual triggering of block.dispatchChange()
205210
*/
206-
private didMutated = _.debounce((mutationsOrInputEvent: MutationRecord[] | InputEvent = []): void => {
207-
const shouldFireUpdate = mutationsOrInputEvent instanceof InputEvent ||
208-
!mutationsOrInputEvent.some(({
209-
addedNodes = [],
210-
removedNodes,
211-
}) => {
212-
return [...Array.from(addedNodes), ...Array.from(removedNodes)]
213-
.some(node => $.isElement(node) && (node as HTMLElement).dataset.mutationFree === 'true');
211+
private didMutated = _.debounce((mutationsOrInputEvent: MutationRecord[] | InputEvent = undefined): void => {
212+
/**
213+
* We won't fire a Block mutation event if mutation contain only nodes marked with 'data-mutation-free' attributes
214+
*/
215+
let shouldFireUpdate;
216+
217+
if (mutationsOrInputEvent === undefined) {
218+
shouldFireUpdate = true;
219+
} else if (mutationsOrInputEvent instanceof InputEvent) {
220+
shouldFireUpdate = true;
221+
} else {
222+
/**
223+
* Update from 2023, Feb 17:
224+
* Changed mutationsOrInputEvent.some() to mutationsOrInputEvent.every()
225+
* since there could be a real mutations same-time with mutation-free changes,
226+
* for example when Block Tune change: block is changing along with FakeCursor (mutation-free) removing
227+
* — we should fire 'didMutated' event in that case
228+
*/
229+
const everyRecordIsMutationFree = mutationsOrInputEvent.length > 0 && mutationsOrInputEvent.every((record) => {
230+
const { addedNodes, removedNodes } = record;
231+
const changedNodes = [
232+
...Array.from(addedNodes),
233+
...Array.from(removedNodes),
234+
];
235+
236+
return changedNodes.some((node) => {
237+
if ($.isElement(node) === false) {
238+
return false;
239+
}
240+
241+
return (node as HTMLElement).dataset.mutationFree === 'true';
242+
});
214243
});
215244

245+
if (everyRecordIsMutationFree) {
246+
shouldFireUpdate = false;
247+
} else {
248+
shouldFireUpdate = true;
249+
}
250+
}
251+
216252
/**
217253
* In case some mutation free elements are added or removed, do not trigger didMutated event
218254
*/

test/cypress/tests/api/tools.spec.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -512,7 +512,7 @@ describe('Editor Tools Api', () => {
512512
/** config specified handled tag */
513513
public static get pasteConfig(): PasteConfig {
514514
return {
515-
tags: ['img'], // only tag name specified. Attributes should be sanitized
515+
tags: [ 'img' ], // only tag name specified. Attributes should be sanitized
516516
};
517517
}
518518

@@ -564,7 +564,7 @@ describe('Editor Tools Api', () => {
564564
/** config specified handled tag */
565565
public static get pasteConfig(): PasteConfig {
566566
return {
567-
tags: ['img'], // only tag name specified. Attributes should be sanitized
567+
tags: [ 'img' ], // only tag name specified. Attributes should be sanitized
568568
};
569569
}
570570

test/cypress/tests/onchange.spec.ts

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -221,14 +221,7 @@ describe('onChange callback', () => {
221221
.click();
222222

223223
cy.get('[data-cy=editorjs]')
224-
.get('span.cdx-settings-button[data-level=4]')
225-
.click()
226-
/**
227-
* For some reason, the first click fires the mutation of removeFakeCursor only, so we need to click again.
228-
* Reproduced only in Cypress.
229-
*
230-
* @todo debug it later
231-
*/
224+
.get('.ce-settings .ce-popover-item:nth-child(4)')
232225
.click();
233226

234227
cy.get('@onChange').should('be.calledWithMatch', EditorJSApiMock, Cypress.sinon.match({

yarn.lock

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -857,6 +857,11 @@
857857
resolved "https://registry.yarnpkg.com/@codexteam/icons/-/icons-0.1.0.tgz#a02885fe8699f69902d05b077b5f1cd48a2ca6b9"
858858
integrity sha512-jW1fWnwtWzcP4FBGsaodbJY3s1ZaRU+IJy1pvJ7ygNQxkQinybJcwXoyt0a5mWwu/4w30A42EWhCrZn8lp4fdw==
859859

860+
"@codexteam/icons@^0.0.5":
861+
version "0.0.5"
862+
resolved "https://registry.yarnpkg.com/@codexteam/icons/-/icons-0.0.5.tgz#d17f39b6a0497c6439f57dd42711817a3dd3679c"
863+
integrity sha512-s6H2KXhLz2rgbMZSkRm8dsMJvyUNZsEjxobBEg9ztdrb1B2H3pEzY6iTwI4XUPJWJ3c3qRKwV4TrO3J5jUdoQA==
864+
860865
"@codexteam/shortcuts@^1.1.1":
861866
version "1.2.0"
862867
resolved "https://registry.yarnpkg.com/@codexteam/shortcuts/-/shortcuts-1.2.0.tgz#b8dd7396962b0bd845a5c8f8f19bc6119b520e19"
@@ -944,9 +949,12 @@
944949
version "1.2.0"
945950
resolved "https://registry.yarnpkg.com/@editorjs/delimiter/-/delimiter-1.2.0.tgz#5075f1a3e68765cfb6aec8694b316d81e2b41607"
946951

947-
"@editorjs/header@^2.6.1":
948-
version "2.6.2"
949-
resolved "https://registry.yarnpkg.com/@editorjs/header/-/header-2.6.2.tgz#523b6dda72ff882e53f64325840ee7bfc68ee6b7"
952+
"@editorjs/header@^2.7.0":
953+
version "2.7.0"
954+
resolved "https://registry.yarnpkg.com/@editorjs/header/-/header-2.7.0.tgz#755d104a9210a8e2d9ccf22b175b2a93bdbb2330"
955+
integrity sha512-4fGKGe2ZYblVqR/P/iw5ieG00uXInFgNMftBMqJRYcB2hUPD30kuu7Sn6eJDcLXoKUMOeqi8Z2AlUxYAmvw7zQ==
956+
dependencies:
957+
"@codexteam/icons" "^0.0.5"
950958

951959
"@editorjs/simple-image@^1.4.1":
952960
version "1.4.1"

0 commit comments

Comments
 (0)