@@ -8,6 +8,7 @@ import BalloonToolbar from '../../../src/toolbar/balloon/balloontoolbar';
8
8
import ContextualBalloon from '../../../src/panel/balloon/contextualballoon' ;
9
9
import BalloonPanelView from '../../../src/panel/balloon/balloonpanelview' ;
10
10
import ToolbarView from '../../../src/toolbar/toolbarview' ;
11
+ import FocusTracker from '@ckeditor/ckeditor5-utils/src/focustracker' ;
11
12
import Plugin from '@ckeditor/ckeditor5-core/src/plugin' ;
12
13
import Bold from '@ckeditor/ckeditor5-basic-styles/src/bold' ;
13
14
import Italic from '@ckeditor/ckeditor5-basic-styles/src/italic' ;
@@ -17,7 +18,7 @@ import Paragraph from '@ckeditor/ckeditor5-paragraph/src/paragraph';
17
18
import { setData } from '@ckeditor/ckeditor5-engine/src/dev-utils/model' ;
18
19
import { stringify as viewStringify } from '@ckeditor/ckeditor5-engine/src/dev-utils/view' ;
19
20
20
- /* global document, setTimeout, window */
21
+ /* global document, setTimeout, window, Event */
21
22
22
23
describe ( 'BalloonToolbar' , ( ) => {
23
24
let sandbox , editor , model , selection , editingView , balloonToolbar , balloon , editorElement ;
@@ -143,6 +144,28 @@ describe( 'BalloonToolbar', () => {
143
144
} ) ;
144
145
} ) ;
145
146
147
+ describe ( 'focusTracker' , ( ) => {
148
+ it ( 'should be defined' , ( ) => {
149
+ expect ( balloonToolbar . focusTracker ) . to . instanceof ( FocusTracker ) ;
150
+ } ) ;
151
+
152
+ it ( 'it should track the focus of the #editableElement' , ( ) => {
153
+ expect ( balloonToolbar . focusTracker . isFocused ) . to . false ;
154
+
155
+ editor . ui . view . editableElement . dispatchEvent ( new Event ( 'focus' ) ) ;
156
+
157
+ expect ( balloonToolbar . focusTracker . isFocused ) . to . true ;
158
+ } ) ;
159
+
160
+ it ( 'it should track the focus of the toolbarView#element' , ( ) => {
161
+ expect ( balloonToolbar . focusTracker . isFocused ) . to . false ;
162
+
163
+ balloonToolbar . toolbarView . element . dispatchEvent ( new Event ( 'focus' ) ) ;
164
+
165
+ expect ( balloonToolbar . focusTracker . isFocused ) . to . true ;
166
+ } ) ;
167
+ } ) ;
168
+
146
169
describe ( 'show()' , ( ) => {
147
170
let balloonAddSpy , backwardSelectionRect , forwardSelectionRect ;
148
171
@@ -275,7 +298,7 @@ describe( 'BalloonToolbar', () => {
275
298
expect ( targetRect ) . to . deep . equal ( backwardSelectionRect ) ;
276
299
} ) ;
277
300
278
- it ( 'should update balloon position on ui#update event while balloon is added to the #_balloon' , ( ) => {
301
+ it ( 'should update balloon position on ui#update event when #toolbarView is already added to the #_balloon' , ( ) => {
279
302
setData ( model , '<paragraph>b[a]r</paragraph>' ) ;
280
303
281
304
const spy = sandbox . spy ( balloon , 'updatePosition' ) ;
@@ -297,6 +320,13 @@ describe( 'BalloonToolbar', () => {
297
320
sinon . assert . calledOnce ( balloonAddSpy ) ;
298
321
} ) ;
299
322
323
+ it ( 'should not add the #toolbarView to the #_balloon when the selection is collapsed' , ( ) => {
324
+ setData ( model , '<paragraph>b[]ar</paragraph>' ) ;
325
+
326
+ balloonToolbar . show ( ) ;
327
+ sinon . assert . notCalled ( balloonAddSpy ) ;
328
+ } ) ;
329
+
300
330
it ( 'should not add #toolbarView to the #_balloon when all components inside #toolbarView are disabled' , ( ) => {
301
331
Array . from ( balloonToolbar . toolbarView . items ) . forEach ( item => {
302
332
item . isEnabled = false ;
@@ -319,37 +349,6 @@ describe( 'BalloonToolbar', () => {
319
349
balloonToolbar . show ( ) ;
320
350
sinon . assert . calledOnce ( balloonAddSpy ) ;
321
351
} ) ;
322
-
323
- describe ( 'on #_selectionChangeDebounced event' , ( ) => {
324
- let showSpy ;
325
-
326
- beforeEach ( ( ) => {
327
- showSpy = sandbox . spy ( balloonToolbar , 'show' ) ;
328
- } ) ;
329
-
330
- it ( 'should not be called when the editor is not focused' , ( ) => {
331
- setData ( model , '<paragraph>b[a]r</paragraph>' ) ;
332
- editingView . document . isFocused = false ;
333
-
334
- balloonToolbar . fire ( '_selectionChangeDebounced' ) ;
335
- sinon . assert . notCalled ( showSpy ) ;
336
- } ) ;
337
-
338
- it ( 'should not be called when the selection is collapsed' , ( ) => {
339
- setData ( model , '<paragraph>b[]ar</paragraph>' ) ;
340
-
341
- balloonToolbar . fire ( '_selectionChangeDebounced' ) ;
342
- sinon . assert . notCalled ( showSpy ) ;
343
- } ) ;
344
-
345
- it ( 'should be called when the selection is not collapsed and editor is focused' , ( ) => {
346
- setData ( model , '<paragraph>b[a]r</paragraph>' ) ;
347
- editingView . document . isFocused = true ;
348
-
349
- balloonToolbar . fire ( '_selectionChangeDebounced' ) ;
350
- sinon . assert . calledOnce ( showSpy ) ;
351
- } ) ;
352
- } ) ;
353
352
} ) ;
354
353
355
354
describe ( 'hide()' , ( ) => {
@@ -381,7 +380,7 @@ describe( 'BalloonToolbar', () => {
381
380
sinon . assert . notCalled ( spy ) ;
382
381
} ) ;
383
382
384
- it ( 'should not remove #ttolbarView when is not added to the #_balloon' , ( ) => {
383
+ it ( 'should not remove #toolbarView when is not added to the #_balloon' , ( ) => {
385
384
balloonToolbar . hide ( ) ;
386
385
387
386
sinon . assert . notCalled ( removeBalloonSpy ) ;
@@ -412,7 +411,7 @@ describe( 'BalloonToolbar', () => {
412
411
} ) ;
413
412
} ) ;
414
413
415
- describe ( 'showing and hiding ' , ( ) => {
414
+ describe ( 'show and hide triggers ' , ( ) => {
416
415
let showPanelSpy , hidePanelSpy ;
417
416
418
417
beforeEach ( ( ) => {
@@ -422,7 +421,7 @@ describe( 'BalloonToolbar', () => {
422
421
hidePanelSpy = sandbox . spy ( balloonToolbar , 'hide' ) ;
423
422
} ) ;
424
423
425
- it ( 'should open when selection stops changing' , ( ) => {
424
+ it ( 'should show when selection stops changing' , ( ) => {
426
425
sinon . assert . notCalled ( showPanelSpy ) ;
427
426
sinon . assert . notCalled ( hidePanelSpy ) ;
428
427
@@ -432,7 +431,18 @@ describe( 'BalloonToolbar', () => {
432
431
sinon . assert . notCalled ( hidePanelSpy ) ;
433
432
} ) ;
434
433
435
- it ( 'should close when selection starts changing by a directChange' , ( ) => {
434
+ it ( 'should not show when the selection stops changing when the editable is blurred' , ( ) => {
435
+ sinon . assert . notCalled ( showPanelSpy ) ;
436
+ sinon . assert . notCalled ( hidePanelSpy ) ;
437
+
438
+ editingView . document . isFocused = false ;
439
+ balloonToolbar . fire ( '_selectionChangeDebounced' ) ;
440
+
441
+ sinon . assert . notCalled ( showPanelSpy ) ;
442
+ sinon . assert . notCalled ( hidePanelSpy ) ;
443
+ } ) ;
444
+
445
+ it ( 'should hide when selection starts changing by a direct change' , ( ) => {
436
446
balloonToolbar . fire ( '_selectionChangeDebounced' ) ;
437
447
438
448
sinon . assert . calledOnce ( showPanelSpy ) ;
@@ -444,7 +454,7 @@ describe( 'BalloonToolbar', () => {
444
454
sinon . assert . calledOnce ( hidePanelSpy ) ;
445
455
} ) ;
446
456
447
- it ( 'should not close when selection starts changing by not a directChange ' , ( ) => {
457
+ it ( 'should not hide when selection starts changing by an indirect change ' , ( ) => {
448
458
balloonToolbar . fire ( '_selectionChangeDebounced' ) ;
449
459
450
460
sinon . assert . calledOnce ( showPanelSpy ) ;
@@ -456,7 +466,7 @@ describe( 'BalloonToolbar', () => {
456
466
sinon . assert . notCalled ( hidePanelSpy ) ;
457
467
} ) ;
458
468
459
- it ( 'should close when selection starts changing by not a directChange but will become collapsed' , ( ) => {
469
+ it ( 'should hide when selection starts changing by an indirect change but has changed to collapsed' , ( ) => {
460
470
balloonToolbar . fire ( '_selectionChangeDebounced' ) ;
461
471
462
472
sinon . assert . calledOnce ( showPanelSpy ) ;
@@ -472,35 +482,43 @@ describe( 'BalloonToolbar', () => {
472
482
sinon . assert . calledOnce ( hidePanelSpy ) ;
473
483
} ) ;
474
484
475
- it ( 'should hide if the editor loses focus' , ( ) => {
476
- editor . ui . focusTracker . isFocused = true ;
485
+ it ( 'should show on #focusTracker focus' , ( ) => {
486
+ balloonToolbar . focusTracker . isFocused = false ;
477
487
478
- balloonToolbar . fire ( '_selectionChangeDebounced' ) ;
488
+ sinon . assert . notCalled ( showPanelSpy ) ;
489
+ sinon . assert . notCalled ( hidePanelSpy ) ;
490
+
491
+ balloonToolbar . focusTracker . isFocused = true ;
492
+
493
+ sinon . assert . calledOnce ( showPanelSpy ) ;
494
+ sinon . assert . notCalled ( hidePanelSpy ) ;
495
+ } ) ;
496
+
497
+ it ( 'should hide on #focusTracker blur' , ( ) => {
498
+ balloonToolbar . focusTracker . isFocused = true ;
479
499
480
500
const stub = sandbox . stub ( balloon , 'visibleView' ) . get ( ( ) => balloonToolbar . toolbarView ) ;
481
501
482
502
sinon . assert . calledOnce ( showPanelSpy ) ;
483
503
sinon . assert . notCalled ( hidePanelSpy ) ;
484
504
485
- editor . ui . focusTracker . isFocused = false ;
505
+ balloonToolbar . focusTracker . isFocused = false ;
486
506
487
507
sinon . assert . calledOnce ( showPanelSpy ) ;
488
508
sinon . assert . calledOnce ( hidePanelSpy ) ;
489
509
490
510
stub . restore ( ) ;
491
511
} ) ;
492
512
493
- it ( 'should not hide if the editor loses focus and #toolbarView is not visible' , ( ) => {
494
- editor . ui . focusTracker . isFocused = true ;
495
-
496
- balloonToolbar . fire ( '_selectionChangeDebounced' ) ;
513
+ it ( 'should not hide on #focusTracker blur when toolbar is not in the balloon stack' , ( ) => {
514
+ balloonToolbar . focusTracker . isFocused = true ;
497
515
498
516
const stub = sandbox . stub ( balloon , 'visibleView' ) . get ( ( ) => null ) ;
499
517
500
518
sinon . assert . calledOnce ( showPanelSpy ) ;
501
519
sinon . assert . notCalled ( hidePanelSpy ) ;
502
520
503
- editor . ui . focusTracker . isFocused = false ;
521
+ balloonToolbar . focusTracker . isFocused = false ;
504
522
505
523
sinon . assert . calledOnce ( showPanelSpy ) ;
506
524
sinon . assert . notCalled ( hidePanelSpy ) ;
0 commit comments