mirror of
https://github.com/codex-team/editor.js
synced 2024-06-15 20:25:15 +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` — 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.
|
- `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
|
- `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
|
### 2.26.5
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "@editorjs/editorjs",
|
"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",
|
"description": "Editor.js — Native JS, based on API and Open Source",
|
||||||
"main": "dist/editor.js",
|
"main": "dist/editor.js",
|
||||||
"types": "./types/index.d.ts",
|
"types": "./types/index.d.ts",
|
||||||
|
|
|
@ -153,6 +153,11 @@ export default class Block extends EventsDispatcher<BlockEvents> {
|
||||||
*/
|
*/
|
||||||
private cachedInputs: HTMLElement[] = [];
|
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
|
* Tool class instance
|
||||||
*/
|
*/
|
||||||
|
@ -553,23 +558,7 @@ export default class Block extends EventsDispatcher<BlockEvents> {
|
||||||
* @returns {HTMLElement}
|
* @returns {HTMLElement}
|
||||||
*/
|
*/
|
||||||
public get pluginsContent(): HTMLElement {
|
public get pluginsContent(): HTMLElement {
|
||||||
const blockContentNodes = this.holder.querySelector(`.${Block.CSS.content}`);
|
return this.toolRenderedElement;
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -825,7 +814,12 @@ export default class Block extends EventsDispatcher<BlockEvents> {
|
||||||
contentNode = $.make('div', Block.CSS.content),
|
contentNode = $.make('div', Block.CSS.content),
|
||||||
pluginsContent = this.toolInstance.render();
|
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
|
* Block Tunes might wrap Block's content node to provide any UI changes
|
||||||
|
|
|
@ -550,26 +550,6 @@ export default class Dom {
|
||||||
return element;
|
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)
|
* 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