fix(block): remember plugin's content element instead of dom search (#2311)

* fix(block): remember plugin's content element instead of dom search

* improve doc

* test case added
This commit is contained in:
Peter Savchenko 2023-03-20 23:28:17 +03:00 committed by GitHub
parent 293135a795
commit 5257b061c4
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 51 additions and 40 deletions

View file

@ -8,7 +8,7 @@
- `Fix` — Resolve compiler error from importing the BlockToolData type.
- `Fix` — Resolved a problem when document was being scrolled to the beginning after moving up a Block above the viewport.
- `Improvement` — Package size reduced by removing redundant files
- `Fix`- Entire block being deleted on backspace key press when the browser has 3rd party grammer checker extension
- `Fix`- Several bugs caused by random browser extensions
### 2.26.5

View file

@ -1,6 +1,6 @@
{
"name": "@editorjs/editorjs",
"version": "2.27.0-rc.3",
"version": "2.27.0-rc.4",
"description": "Editor.js — Native JS, based on API and Open Source",
"main": "dist/editor.js",
"types": "./types/index.d.ts",

View file

@ -153,6 +153,11 @@ export default class Block extends EventsDispatcher<BlockEvents> {
*/
private cachedInputs: HTMLElement[] = [];
/**
* We'll store a reference to the tool's rendered element to access it later
*/
private toolRenderedElement: HTMLElement | null = null;
/**
* Tool class instance
*/
@ -553,23 +558,7 @@ export default class Block extends EventsDispatcher<BlockEvents> {
* @returns {HTMLElement}
*/
public get pluginsContent(): HTMLElement {
const blockContentNodes = this.holder.querySelector(`.${Block.CSS.content}`);
if (blockContentNodes && blockContentNodes.childNodes.length) {
/**
* Editors Block content can contain different Nodes from extensions
* We use DOM isExtensionNode to ignore such Nodes and return first Block that does not match filtering list
*/
for (let child = blockContentNodes.childNodes.length - 1; child >= 0; child--) {
const contentNode = blockContentNodes.childNodes[child];
if (!$.isExtensionNode(contentNode)) {
return contentNode as HTMLElement;
}
}
}
return null;
return this.toolRenderedElement;
}
/**
@ -825,7 +814,12 @@ export default class Block extends EventsDispatcher<BlockEvents> {
contentNode = $.make('div', Block.CSS.content),
pluginsContent = this.toolInstance.render();
contentNode.appendChild(pluginsContent);
/**
* Saving a reference to plugin's content element for guaranteed accessing it later
*/
this.toolRenderedElement = pluginsContent;
contentNode.appendChild(this.toolRenderedElement);
/**
* Block Tunes might wrap Block's content node to provide any UI changes

View file

@ -550,26 +550,6 @@ export default class Dom {
return element;
}
/**
* Method checks passed Node if it is some extension Node
*
* @param {Node} node - any node
* @returns {boolean}
*/
public static isExtensionNode(node: Node): boolean {
const extensions = [
'grammarly-extension',
'mci-extension',
'gdiv',
'pwa-container-wrapper',
'pwa-editor-bar-cnt',
'editor-squiggler',
'quillbot-extension',
];
return node && extensions.includes(node.nodeName.toLowerCase());
}
/**
* Returns true if element is anchor (is A tag)
*

View file

@ -0,0 +1,37 @@
import type EditorJS from '../../../../types/index';
describe('Saver module', function () {
describe('save()', function () {
it('should correctly save block if there are some 3rd party (eg. browser extensions) nodes inserted into the layout', function () {
cy.createEditor({
data: {
blocks: [
{
type: 'paragraph',
data: {
text: 'The block with some text',
},
},
],
},
}).then((editor: EditorJS) => {
/**
* Add some node just like browser extensions doing
*/
const extensionNode = document.createElement('extension-node');
cy.get('[data-cy=editorjs]')
.find('.ce-block__content')
.then((blockContent) => {
blockContent.append(extensionNode);
})
.then(async () => {
const savedData = await editor.save();
expect(savedData.blocks.length).to.equal(1);
expect(savedData.blocks[0].data.text).to.equal('The block with some text');
});
});
});
});
});