Skip to content

Commit

Permalink
chore(ui): update current block in readonly by clicks on block (#2859)
Browse files Browse the repository at this point in the history
* chore(ui): update current block in readonly by clicks on block

* fix eslint
  • Loading branch information
neSpecc authored Nov 6, 2024
1 parent 6313409 commit 7ee0622
Show file tree
Hide file tree
Showing 3 changed files with 76 additions and 20 deletions.
1 change: 1 addition & 0 deletions docs/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
- `Fix` - Fix selection of first block in read-only initialization with "autofocus=true"
- `Fix` - Incorrect caret position after blocks merging in Safari
- `Fix` - Several toolbox items exported by the one tool have the same shortcut displayed in toolbox
- `Improvement` - The current block reference will be updated in read-only mode when blocks are clicked

### 2.30.6

Expand Down
48 changes: 28 additions & 20 deletions src/components/modules/ui.ts
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,6 @@ export default class UI extends Module<UINodes> {
this.loadStyles();
}


/**
* Toggle read-only state
*
Expand Down Expand Up @@ -244,6 +243,15 @@ export default class UI extends Module<UINodes> {
Toolbar.toolbox.close();
}

/**
* Event listener for 'mousedown' and 'touchstart' events
*
* @param event - TouchEvent or MouseEvent
*/
private documentTouchedListener = (event: Event): void => {
this.documentTouched(event);
};

/**
* Check for mobile mode and save the result
*/
Expand Down Expand Up @@ -351,6 +359,16 @@ export default class UI extends Module<UINodes> {
this.listeners.on(window, 'resize', this.resizeDebouncer, {
passive: true,
});

this.listeners.on(this.nodes.redactor, 'mousedown', this.documentTouchedListener, {
capture: true,
passive: true,
});

this.listeners.on(this.nodes.redactor, 'touchstart', this.documentTouchedListener, {
capture: true,
passive: true,
});
}

/**
Expand All @@ -359,6 +377,8 @@ export default class UI extends Module<UINodes> {
private unbindReadOnlyInsensitiveListeners(): void {
this.listeners.off(document, 'selectionchange', this.selectionChangeDebounced);
this.listeners.off(window, 'resize', this.resizeDebouncer);
this.listeners.off(this.nodes.redactor, 'mousedown', this.documentTouchedListener);
this.listeners.off(this.nodes.redactor, 'touchstart', this.documentTouchedListener);
}


Expand All @@ -370,20 +390,6 @@ export default class UI extends Module<UINodes> {
this.redactorClicked(event);
}, false);

this.readOnlyMutableListeners.on(this.nodes.redactor, 'mousedown', (event: MouseEvent | TouchEvent) => {
this.documentTouched(event);
}, {
capture: true,
passive: true,
});

this.readOnlyMutableListeners.on(this.nodes.redactor, 'touchstart', (event: MouseEvent | TouchEvent) => {
this.documentTouched(event);
}, {
capture: true,
passive: true,
});

this.readOnlyMutableListeners.on(document, 'keydown', (event: KeyboardEvent) => {
this.documentKeydown(event);
}, true);
Expand Down Expand Up @@ -709,17 +715,17 @@ export default class UI extends Module<UINodes> {
* - Move and show the Toolbar
* - Set a Caret
*
* @param {MouseEvent | TouchEvent} event - touch or mouse event
* @param event - touch or mouse event
*/
private documentTouched(event: MouseEvent | TouchEvent): void {
private documentTouched(event: Event): void {
let clickedNode = event.target as HTMLElement;

/**
* If click was fired on Editor`s wrapper, try to get clicked node by elementFromPoint method
*/
if (clickedNode === this.nodes.redactor) {
const clientX = event instanceof MouseEvent ? event.clientX : event.touches[0].clientX;
const clientY = event instanceof MouseEvent ? event.clientY : event.touches[0].clientY;
const clientX = event instanceof MouseEvent ? event.clientX : (event as TouchEvent).touches[0].clientX;
const clientY = event instanceof MouseEvent ? event.clientY : (event as TouchEvent).touches[0].clientY;

clickedNode = document.elementFromPoint(clientX, clientY) as HTMLElement;
}
Expand All @@ -742,7 +748,9 @@ export default class UI extends Module<UINodes> {
* Move and open toolbar
* (used for showing Block Settings toggler after opening and closing Inline Toolbar)
*/
this.Editor.Toolbar.moveAndOpen();
if (!this.Editor.ReadOnly.isEnabled) {
this.Editor.Toolbar.moveAndOpen();
}
}

/**
Expand Down
47 changes: 47 additions & 0 deletions test/cypress/tests/modules/Ui.cy.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { createEditorWithTextBlocks } from '../../support/utils/createEditorWithTextBlocks';
import type EditorJS from '../../../../types/index';

describe('Ui module', function () {
Expand Down Expand Up @@ -93,4 +94,50 @@ describe('Ui module', function () {
});
});
});

describe('mousedown', function () {
it('should update current block by click on block', function () {
createEditorWithTextBlocks([
'first block',
'second block',
'third block',
])
.as('editorInstance');

cy.get('[data-cy=editorjs]')
.find('.ce-paragraph')
.eq(1)
.click();

cy.get<EditorJS>('@editorInstance')
.then(async (editor) => {
const currentBlockIndex = await editor.blocks.getCurrentBlockIndex();

expect(currentBlockIndex).to.eq(1);
});
});

it('(in readonly) should update current block by click on block', function () {
createEditorWithTextBlocks([
'first block',
'second block',
'third block',
], {
readOnly: true,
})
.as('editorInstance');

cy.get('[data-cy=editorjs]')
.find('.ce-paragraph')
.eq(1)
.click();

cy.get<EditorJS>('@editorInstance')
.then(async (editor) => {
const currentBlockIndex = await editor.blocks.getCurrentBlockIndex();

expect(currentBlockIndex).to.eq(1);
});
});
});
});

0 comments on commit 7ee0622

Please sign in to comment.