Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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;
});
});
});
});
Loading