Skip to content

Commit 5e8fe06

Browse files
authored
fix: errors caused by events fired while editor is not initialized yet (codex-team#2532)
* fix(init): errors cause by events fired while editor is not initialized yet * Update package.json
1 parent af6b64a commit 5e8fe06

File tree

8 files changed

+47
-20
lines changed

8 files changed

+47
-20
lines changed

docs/CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
- `Fix` — When the focusing Block is out of the viewport, the page will be scrolled.
1010
- `Fix``blocks.render()` won't lead the `onChange` call in Safari
1111
- `Fix` — Editor wrapper element growing on the Inline Toolbar close
12+
- `Fix` — Fix errors thrown by clicks on a document when the editor is being initialized
1213

1314
### 2.28.2
1415

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@editorjs/editorjs",
3-
"version": "2.29.0-rc.5",
3+
"version": "2.29.0-rc.6",
44
"description": "Editor.js — Native JS, based on API and Open Source",
55
"main": "dist/editorjs.umd.js",
66
"module": "dist/editorjs.mjs",

src/components/modules/blockManager.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -744,7 +744,11 @@ export default class BlockManager extends Module {
744744
* @param {Node} childNode - node to get Block by
745745
* @returns {Block}
746746
*/
747-
public getBlockByChildNode(childNode: Node): Block {
747+
public getBlockByChildNode(childNode: Node): Block | undefined {
748+
if (!childNode || childNode instanceof Node === false) {
749+
return undefined;
750+
}
751+
748752
/**
749753
* If node is Text TextNode
750754
*/

src/components/modules/crossBlockSelection.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -187,6 +187,13 @@ export default class CrossBlockSelection extends Module {
187187
private onMouseOver = (event: MouseEvent): void => {
188188
const { BlockManager, BlockSelection } = this.Editor;
189189

190+
/**
191+
* Probably, editor is not initialized yet
192+
*/
193+
if (event.relatedTarget === null && event.target === null) {
194+
return;
195+
}
196+
190197
const relatedBlock = BlockManager.getBlockByChildNode(event.relatedTarget as Node) || this.lastSelectedBlock;
191198
const targetBlock = BlockManager.getBlockByChildNode(event.target as Node);
192199

src/components/modules/toolbar/blockSettings.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,10 @@ import Popover, { PopoverEvent } from '../../utils/popover';
1313
* HTML Elements that used for BlockSettings
1414
*/
1515
interface BlockSettingsNodes {
16-
wrapper: HTMLElement;
16+
/**
17+
* Block Settings wrapper. Undefined when before "make" method called
18+
*/
19+
wrapper: HTMLElement | undefined;
1720
}
1821

1922
/**

src/components/modules/toolbar/index.ts

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -32,12 +32,12 @@ import { BlockHovered } from '../../events/BlockHovered';
3232
* HTML Elements used for Toolbar UI
3333
*/
3434
interface ToolbarNodes {
35-
wrapper: HTMLElement;
36-
content: HTMLElement;
37-
actions: HTMLElement;
35+
wrapper: HTMLElement | undefined;
36+
content: HTMLElement | undefined;
37+
actions: HTMLElement | undefined;
3838

39-
plusButton: HTMLElement;
40-
settingsToggler: HTMLElement;
39+
plusButton: HTMLElement | undefined;
40+
settingsToggler: HTMLElement | undefined;
4141
}
4242
/**
4343
*
@@ -316,7 +316,7 @@ export default class Toolbar extends Module<ToolbarNodes> {
316316
return;
317317
}
318318

319-
this.nodes.wrapper.classList.remove(this.CSS.toolbarOpened);
319+
this.nodes.wrapper?.classList.remove(this.CSS.toolbarOpened);
320320

321321
/** Close components */
322322
this.blockActions.hide();

src/components/modules/toolbar/inline.ts

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -17,16 +17,16 @@ import { IconChevronDown } from '@codexteam/icons';
1717
* Inline Toolbar elements
1818
*/
1919
interface InlineToolbarNodes {
20-
wrapper: HTMLElement;
21-
togglerAndButtonsWrapper: HTMLElement;
22-
buttons: HTMLElement;
23-
conversionToggler: HTMLElement;
24-
conversionTogglerContent: HTMLElement;
20+
wrapper: HTMLElement | undefined;
21+
togglerAndButtonsWrapper: HTMLElement | undefined;
22+
buttons: HTMLElement | undefined;
23+
conversionToggler: HTMLElement | undefined;
24+
conversionTogglerContent: HTMLElement | undefined;
2525
/**
2626
* Zone below the buttons where Tools can create additional actions by 'renderActions()' method
2727
* For example, input for the 'link' tool or textarea for the 'comment' tool
2828
*/
29-
actions: HTMLElement;
29+
actions: HTMLElement | undefined;
3030
}
3131

3232
/**
@@ -238,6 +238,10 @@ export default class InlineToolbar extends Module<InlineToolbarNodes> {
238238
* @param {Node} node — node to check
239239
*/
240240
public containsNode(node: Node): boolean {
241+
if (this.nodes.wrapper === undefined) {
242+
return false;
243+
}
244+
241245
return this.nodes.wrapper.contains(node);
242246
}
243247

src/components/modules/ui.ts

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -150,12 +150,20 @@ export default class UI extends Module<UINodes> {
150150
*/
151151
if (!readOnlyEnabled) {
152152
/**
153-
* Unbind all events
153+
* Postpone events binding to the next tick to make sure all ui elements are ready
154154
*/
155-
this.enableModuleBindings();
155+
window.requestIdleCallback(() => {
156+
/**
157+
* Bind events for the UI elements
158+
*/
159+
this.enableModuleBindings();
160+
}, {
161+
timeout: 2000,
162+
});
156163
} else {
157164
/**
158-
* Bind events for the UI elements
165+
* Unbind all events
166+
*
159167
*/
160168
this.disableModuleBindings();
161169
}
@@ -633,8 +641,8 @@ export default class UI extends Module<UINodes> {
633641
* But allow clicking inside Block Settings.
634642
* Also, do not process clicks on the Block Settings Toggler, because it has own click listener
635643
*/
636-
const isClickedInsideBlockSettings = this.Editor.BlockSettings.nodes.wrapper.contains(target);
637-
const isClickedInsideBlockSettingsToggler = this.Editor.Toolbar.nodes.settingsToggler.contains(target);
644+
const isClickedInsideBlockSettings = this.Editor.BlockSettings.nodes.wrapper?.contains(target);
645+
const isClickedInsideBlockSettingsToggler = this.Editor.Toolbar.nodes.settingsToggler?.contains(target);
638646
const doNotProcess = isClickedInsideBlockSettings || isClickedInsideBlockSettingsToggler;
639647

640648
if (this.Editor.BlockSettings.opened && !doNotProcess) {

0 commit comments

Comments
 (0)