Skip to content

Commit

Permalink
fix(block): remember plugin's content element instead of dom search (c…
Browse files Browse the repository at this point in the history
…odex-team#2311)

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

* improve doc

* test case added
  • Loading branch information
neSpecc authored Mar 20, 2023
1 parent 293135a commit 5257b06
Show file tree
Hide file tree
Showing 5 changed files with 51 additions and 40 deletions.
2 changes: 1 addition & 1 deletion docs/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -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",
Expand Down
30 changes: 12 additions & 18 deletions src/components/block/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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
*/
Expand Down Expand Up @@ -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;
}

/**
Expand Down Expand Up @@ -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
Expand Down
20 changes: 0 additions & 20 deletions src/components/dom.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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)
*
Expand Down
37 changes: 37 additions & 0 deletions test/cypress/tests/modules/Saver.spec.ts
Original file line number Diff line number Diff line change
@@ -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');
});
});
});
});
});

0 comments on commit 5257b06

Please sign in to comment.