@@ -58,13 +58,45 @@ export class FormattingToolbarView implements PluginView {
58
58
pmView . dom . addEventListener ( "mouseup" , this . viewMouseupHandler ) ;
59
59
pmView . dom . addEventListener ( "dragstart" , this . dragHandler ) ;
60
60
pmView . dom . addEventListener ( "dragover" , this . dragHandler ) ;
61
+ pmView . dom . addEventListener ( "blur" , this . blurHandler ) ;
61
62
62
63
// Setting capture=true ensures that any parent container of the editor that
63
64
// gets scrolled will trigger the scroll event. Scroll events do not bubble
64
65
// and so won't propagate to the document by default.
65
66
pmView . root . addEventListener ( "scroll" , this . scrollHandler , true ) ;
66
67
}
67
68
69
+ blurHandler = ( event : FocusEvent ) => {
70
+ if ( this . preventHide ) {
71
+ this . preventHide = false ;
72
+
73
+ return ;
74
+ }
75
+
76
+ const editorWrapper = this . pmView . dom . parentElement ! ;
77
+
78
+ // Checks if the focus is moving to an element outside the editor. If it is,
79
+ // the toolbar is hidden.
80
+ if (
81
+ // An element is clicked.
82
+ event &&
83
+ event . relatedTarget &&
84
+ // Element is inside the editor.
85
+ ( editorWrapper === ( event . relatedTarget as Node ) ||
86
+ editorWrapper . contains ( event . relatedTarget as Node ) ||
87
+ ( event . relatedTarget as HTMLElement ) . matches (
88
+ ".bn-ui-container, .bn-ui-container *"
89
+ ) )
90
+ ) {
91
+ return ;
92
+ }
93
+
94
+ if ( this . state ?. show ) {
95
+ this . state . show = false ;
96
+ this . emitUpdate ( ) ;
97
+ }
98
+ } ;
99
+
68
100
viewMousedownHandler = ( ) => {
69
101
this . preventShow = true ;
70
102
} ;
@@ -90,6 +122,10 @@ export class FormattingToolbarView implements PluginView {
90
122
} ;
91
123
92
124
update ( view : EditorView , oldState ?: EditorState ) {
125
+ // Delays the update to handle edge case with drag and drop, where the view
126
+ // is blurred asynchronously and happens only after the state update.
127
+ // Wrapping in a setTimeout gives enough time to wait for the blur event to
128
+ // occur before updating the toolbar.
93
129
const { state, composing } = view ;
94
130
const { doc, selection } = state ;
95
131
const isSame =
@@ -146,6 +182,7 @@ export class FormattingToolbarView implements PluginView {
146
182
this . pmView . dom . removeEventListener ( "mouseup" , this . viewMouseupHandler ) ;
147
183
this . pmView . dom . removeEventListener ( "dragstart" , this . dragHandler ) ;
148
184
this . pmView . dom . removeEventListener ( "dragover" , this . dragHandler ) ;
185
+ this . pmView . dom . removeEventListener ( "blur" , this . blurHandler ) ;
149
186
150
187
this . pmView . root . removeEventListener ( "scroll" , this . scrollHandler , true ) ;
151
188
}
0 commit comments