Skip to content

Commit

Permalink
fix: prevent inline toolbar from closing in nested instance of editor (
Browse files Browse the repository at this point in the history
…#2780)

* fix: prevent inline toolbar from closing in nested instance of editor

* docs: updated changelog.md with fix description

* fix: fix import to use `type`

---------

Co-authored-by: Peter <[email protected]>
  • Loading branch information
gorenburg and neSpecc authored Sep 13, 2024
1 parent 2f9696a commit b6ba44d
Show file tree
Hide file tree
Showing 4 changed files with 89 additions and 2 deletions.
1 change: 1 addition & 0 deletions docs/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

`Fix` – Fix the display of ‘Convert To’ near blocks that do not have the ‘conversionConfig.export’ rule specified
`Fix` – The Plus button does not appear when the editor is loaded in an iframe in Chrome
- `Fix` - Prevent inline toolbar from closing in nested instance of editor

### 2.30.5

Expand Down
6 changes: 4 additions & 2 deletions src/components/modules/ui.ts
Original file line number Diff line number Diff line change
Expand Up @@ -847,9 +847,11 @@ export default class UI extends Module<UINodes> {

/**
* Event can be fired on clicks at non-block-content elements,
* for example, at the Inline Toolbar or some Block Tune element
* for example, at the Inline Toolbar or some Block Tune element.
* We also make sure that the closest block belongs to the current editor and not a parent
*/
const clickedOutsideBlockContent = focusedElement.closest(`.${Block.CSS.content}`) === null;
const closestBlock = focusedElement.closest(`.${Block.CSS.content}`);
const clickedOutsideBlockContent = closestBlock === null || (closestBlock.closest(`.${Selection.CSS.editorWrapper}`) !== this.nodes.wrapper);

if (clickedOutsideBlockContent) {
/**
Expand Down
31 changes: 31 additions & 0 deletions test/cypress/support/utils/nestedEditorInstance.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import type { BlockTool, BlockToolConstructorOptions } from '../../../../types';
import { createEditorWithTextBlocks } from './createEditorWithTextBlocks';

export const NESTED_EDITOR_ID = 'nested-editor';

/**
* Creates nested Editor instance with paragraph block
*/
export default class NestedEditor implements BlockTool {
private data: { text: string };

constructor(value: BlockToolConstructorOptions) {
this.data = value.data;
}

public render(): HTMLDivElement {
const editorEl = Object.assign(document.createElement('div'), {
id: NESTED_EDITOR_ID,
});

editorEl.setAttribute('data-cy', NESTED_EDITOR_ID);

createEditorWithTextBlocks([ this.data.text ], { holder: NESTED_EDITOR_ID });

return editorEl;
}

public save(): string {
return this.data.text;
}
}
53 changes: 53 additions & 0 deletions test/cypress/tests/modules/InlineToolbar.cy.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import Header from '@editorjs/header';
import NestedEditor, { NESTED_EDITOR_ID } from '../../support/utils/nestedEditorInstance';

describe('Inline Toolbar', () => {
it('should appear aligned with left coord of selection rect', () => {
Expand Down Expand Up @@ -164,4 +165,56 @@ describe('Inline Toolbar', () => {
});
});
});

describe('Nested Editor instance inline toolbar', () => {
it('should not close inline toolbar of the nested Editor instance when clicking within that toolbar', () => {
cy.createEditor({
tools: {
nestedEditor: {
class: NestedEditor,
},
},
data: {
blocks: [
{
type: 'paragraph',
data: {
text: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit.',
},
},
{
type: 'nestedEditor',
data: {
text: 'Nunc pellentesque, tortor nec luctus venenatis',
},
},
],
},
});

cy.get(`[data-cy=${NESTED_EDITOR_ID}]`)
.find('.ce-paragraph')
.selectText('tortor nec luctus');

cy.get(`[data-cy=${NESTED_EDITOR_ID}]`)
.find('[data-item-name=link]')
.click();

// `wait()` function below is required. without it the test will always pass
// because cypress types the text in the field without delay, while we need some delay (just like user)
// to test the actual case that nested editor inline toolbar is still visible and not closed

cy.get(`[data-cy=${NESTED_EDITOR_ID}]`)
.find('.ce-inline-tool-input')
.click()
.wait(100)
.type('https://editorjs.io');

cy.get(`[data-cy=${NESTED_EDITOR_ID}]`)
.find('.ce-popover__container')
.then(($toolbar) => {
expect($toolbar).to.be.visible;
});
});
});
});

0 comments on commit b6ba44d

Please sign in to comment.