Skip to content
This repository was archived by the owner on Jun 26, 2020. It is now read-only.

Commit 714ef21

Browse files
authored
Merge pull request #386 from ckeditor/t/385
Fix: The balloon toolbar should be attached correctly in case of a multi-range selection. Closes #385.
2 parents 7f8a174 + 59d8674 commit 714ef21

File tree

6 files changed

+85
-2
lines changed

6 files changed

+85
-2
lines changed

src/toolbar/balloon/balloontoolbar.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -202,6 +202,7 @@ export default class BalloonToolbar extends Plugin {
202202
const editor = this.editor;
203203
const view = editor.editing.view;
204204
const viewDocument = view.document;
205+
const viewSelection = viewDocument.selection;
205206

206207
// Get direction of the selection.
207208
const isBackward = viewDocument.selection.isBackward;
@@ -212,7 +213,7 @@ export default class BalloonToolbar extends Plugin {
212213
// computed and hence, the target is defined as a function instead of a static value.
213214
// https://github.com/ckeditor/ckeditor5-ui/issues/195
214215
target: () => {
215-
const range = viewDocument.selection.getFirstRange();
216+
const range = isBackward ? viewSelection.getFirstRange() : viewSelection.getLastRange();
216217
const rangeRects = Rect.getDomRangeRects( view.domConverter.viewRangeToDom( range ) );
217218

218219
// Select the proper range rect depending on the direction of the selection.

tests/manual/tickets/385/1.html

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
<div id="editor">
2+
<p>This is a line of text.</p>
3+
<p>This is a line of text.</p>
4+
<p>This is a line of text.</p>
5+
<p>This is a line of text.</p>
6+
<figure class="image">
7+
<img src="sample.jpg" alt="Sample image">
8+
</figure>
9+
<p>This is a line of text.</p>
10+
<p>This is a line of text.</p>
11+
<p>This is a line of text.</p>
12+
<p>This is a line of text.</p>
13+
</div>

tests/manual/tickets/385/1.js

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
/**
2+
* @license Copyright (c) 2003-2018, CKSource - Frederico Knabben. All rights reserved.
3+
* For licensing, see LICENSE.md.
4+
*/
5+
6+
/* globals window, document, console:false */
7+
8+
import ClassicEditor from '@ckeditor/ckeditor5-editor-classic/src/classiceditor';
9+
import ArticlePluginSet from '@ckeditor/ckeditor5-core/tests/_utils/articlepluginset';
10+
import BalloonToolbar from '../../../../src/toolbar/balloon/balloontoolbar';
11+
12+
ClassicEditor
13+
.create( document.querySelector( '#editor' ), {
14+
plugins: [ ArticlePluginSet, BalloonToolbar ],
15+
toolbar: [ 'bold', 'italic', 'link', 'undo', 'redo' ],
16+
balloonToolbar: [ 'bold', 'italic', 'link' ]
17+
} )
18+
.then( editor => {
19+
window.editor = editor;
20+
} )
21+
.catch( err => {
22+
console.error( err.stack );
23+
} );

tests/manual/tickets/385/1.md

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
## Incorrect BalloonToolbar position in a case of multi-range selection [#385](https://github.com/ckeditor/ckeditor5-ui/issues/385)
2+
3+
### Use Firefox to this test, check the ticket for the explanation.
4+
5+
1. Make a forward selection that starts in the text before the image and ends in the text after the image
6+
```
7+
<p>Line of text</p>
8+
<p>Line o{f text</p>
9+
<figure>...</figure>
10+
<p>Line o}f text</p>
11+
<p>Line of text</p>
12+
```
13+
2. Check if the balloon toolbar is attached to the end of the selection
112 KB
Loading

tests/toolbar/balloon/balloontoolbar.js

Lines changed: 34 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,8 @@ import Italic from '@ckeditor/ckeditor5-basic-styles/src/italic';
1414
import Underline from '@ckeditor/ckeditor5-basic-styles/src/underline';
1515
import Paragraph from '@ckeditor/ckeditor5-paragraph/src/paragraph';
1616

17-
import { setData } from '@ckeditor/ckeditor5-engine/src/dev-utils/model.js';
17+
import { setData } from '@ckeditor/ckeditor5-engine/src/dev-utils/model';
18+
import { stringify as viewStringify } from '@ckeditor/ckeditor5-engine/src/dev-utils/view';
1819

1920
/* global document, setTimeout, window */
2021

@@ -199,6 +200,22 @@ describe( 'BalloonToolbar', () => {
199200
expect( balloonAddSpy.firstCall.args[ 0 ].position.target() ).to.deep.equal( forwardSelectionRect );
200201
} );
201202

203+
// https://github.com/ckeditor/ckeditor5-ui/issues/385
204+
it( 'should attach the #_balloon to the last range in a case of multi-range forward selection', () => {
205+
setData( model, '<paragraph>b[ar]</paragraph><paragraph>[bi]z</paragraph>' );
206+
207+
balloonToolbar.show();
208+
209+
// Because attaching and pinning BalloonPanelView is stubbed for test
210+
// we need to manually call function that counting rect.
211+
const targetRect = balloonAddSpy.firstCall.args[ 0 ].position.target();
212+
213+
const targetViewRange = editingView.domConverter.viewRangeToDom.lastCall.args[ 0 ];
214+
215+
expect( viewStringify( targetViewRange.root, targetViewRange ) ).to.equal( '<div><p>bar</p><p>{bi}z</p></div>' );
216+
expect( targetRect ).to.deep.equal( forwardSelectionRect );
217+
} );
218+
202219
// https://github.com/ckeditor/ckeditor5-ui/issues/308
203220
it( 'should ignore the zero-width orphan rect if there another one preceding it for the forward selection', () => {
204221
// Restore previous stubSelectionRects() call.
@@ -242,6 +259,22 @@ describe( 'BalloonToolbar', () => {
242259
expect( balloonAddSpy.firstCall.args[ 0 ].position.target() ).to.deep.equal( backwardSelectionRect );
243260
} );
244261

262+
// https://github.com/ckeditor/ckeditor5-ui/issues/385
263+
it( 'should attach the #_balloon to the first range in a case of multi-range backward selection', () => {
264+
setData( model, '<paragraph>b[ar]</paragraph><paragraph>[bi]z</paragraph>', { lastRangeBackward: true } );
265+
266+
balloonToolbar.show();
267+
268+
// Because attaching and pinning BalloonPanelView is stubbed for test
269+
// we need to manually call function that counting rect.
270+
const targetRect = balloonAddSpy.firstCall.args[ 0 ].position.target();
271+
272+
const targetViewRange = editingView.domConverter.viewRangeToDom.lastCall.args[ 0 ];
273+
274+
expect( viewStringify( targetViewRange.root, targetViewRange ) ).to.equal( '<div><p>b{ar}</p><p>biz</p></div>' );
275+
expect( targetRect ).to.deep.equal( backwardSelectionRect );
276+
} );
277+
245278
it( 'should update balloon position on view#change event while balloon is added to the #_balloon', () => {
246279
setData( model, '<paragraph>b[a]r</paragraph>' );
247280

0 commit comments

Comments
 (0)