@@ -418,30 +418,31 @@ export default class UI extends Module<UINodes> {
418418 /**
419419 * Used to not emit the same block multiple times to the 'block-hovered' event on every mousemove
420420 */
421- let blockHoveredEmitted ;
421+ let blockHoveredEmitted : Element ;
422422
423423 this . readOnlyMutableListeners . on ( this . nodes . redactor , 'mousemove' , _ . throttle ( ( event : MouseEvent | TouchEvent ) => {
424- const hoveredBlock = ( event . target as Element ) . closest ( '.ce-block' ) ;
425-
426424 /**
427425 * Do not trigger 'block-hovered' for cross-block selection
428426 */
429427 if ( this . Editor . BlockSelection . anyBlockSelected ) {
430428 return ;
431429 }
432430
431+ const hoveredElement = event . target as Element ;
432+ const hoveredBlock = this . findByNodeBlockBelongsToCurrentInstance ( hoveredElement ) ;
433+
433434 if ( ! hoveredBlock ) {
434435 return ;
435436 }
436437
437- if ( blockHoveredEmitted === hoveredBlock ) {
438+ if ( blockHoveredEmitted === hoveredBlock . holder ) {
438439 return ;
439440 }
440441
441- blockHoveredEmitted = hoveredBlock ;
442+ blockHoveredEmitted = hoveredBlock . holder ;
442443
443444 this . eventsDispatcher . emit ( BlockHovered , {
444- block : this . Editor . BlockManager . getBlockByChildNode ( hoveredBlock ) ,
445+ block : hoveredBlock ,
445446 } ) ;
446447 // eslint-disable-next-line @typescript-eslint/no-magic-numbers
447448 } , 20 ) , {
@@ -734,7 +735,12 @@ export default class UI extends Module<UINodes> {
734735 * Select clicked Block as Current
735736 */
736737 try {
737- this . Editor . BlockManager . setCurrentBlockByChildNode ( clickedNode ) ;
738+ const blockNode = this . findByNodeBlockBelongsToCurrentInstance ( clickedNode ) ;
739+ if ( ! blockNode ) {
740+ return ;
741+ }
742+
743+ this . Editor . BlockManager . setCurrentBlockByChildNode ( blockNode . holder ) ;
738744 } catch ( e ) {
739745 /**
740746 * If clicked outside first-level Blocks and it is not RectSelection, set Caret to the last empty Block
@@ -930,4 +936,32 @@ export default class UI extends Module<UINodes> {
930936 this . readOnlyMutableListeners . on ( this . nodes . wrapper , 'focusin' , handleInputOrFocusChange ) ;
931937 this . readOnlyMutableListeners . on ( this . nodes . wrapper , 'focusout' , handleInputOrFocusChange ) ;
932938 }
939+
940+ /**
941+ * Find a Block belonging to the current editor instance by element
942+ *
943+ * It is necessary for the case of nested editors.
944+ * This allows each editor to send and process events only for blocks belong the current editor.
945+ * And also allows for top level editors to identify in which block
946+ * of their instance the event occurred in a nested editor block.
947+ */
948+ private findByNodeBlockBelongsToCurrentInstance ( node : Element ) : Block | null {
949+ let blockNode ;
950+
951+ while ( blockNode = node . closest ( `.${ Block . CSS . wrapper } ` ) ) {
952+ const blockInstance = this . Editor . BlockManager . getBlockByChildNode ( blockNode ) ;
953+ if ( blockInstance ) {
954+ return blockInstance ;
955+ }
956+
957+ const editorWrapper = blockNode . closest ( `.${ this . CSS . editorWrapper } ` ) ;
958+ if ( ! editorWrapper ) {
959+ return null ;
960+ }
961+
962+ node = editorWrapper ;
963+ }
964+
965+ return null ;
966+ }
933967}
0 commit comments