mirror of
https://github.com/codex-team/editor.js
synced 2024-05-04 15:43:22 +02:00
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:
parent
293135a795
commit
5257b061c4
|
@ -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
|
||||
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
*
|
||||
|
|
37
test/cypress/tests/modules/Saver.spec.ts
Normal file
37
test/cypress/tests/modules/Saver.spec.ts
Normal 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');
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
Loading…
Reference in a new issue