From 0bd22c0143d2f538e30cbfcc4edc2ce96da13c23 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Oskar=20Wr=C3=B3bel?= Date: Mon, 22 Jul 2019 10:15:09 +0200 Subject: [PATCH] Improved balloon positioning when there is more than one stack in the rotator. --- package.json | 1 + src/linkui.js | 11 ++++++--- tests/linkui.js | 64 ++++++++++++++++++++++++++++++++++++++++++++++++- 3 files changed, 72 insertions(+), 4 deletions(-) diff --git a/package.json b/package.json index 99c28c8..6eade76 100644 --- a/package.json +++ b/package.json @@ -16,6 +16,7 @@ "lodash-es": "^4.17.10" }, "devDependencies": { + "@ckeditor/ckeditor5-block-quote": "^11.1.2", "@ckeditor/ckeditor5-clipboard": "^12.0.1", "@ckeditor/ckeditor5-editor-classic": "^12.1.3", "@ckeditor/ckeditor5-enter": "^11.0.4", diff --git a/src/linkui.js b/src/linkui.js index ecee3a7..2ef5245 100644 --- a/src/linkui.js +++ b/src/linkui.js @@ -414,6 +414,7 @@ export default class LinkUI extends Plugin { const editor = this.editor; this.stopListening( editor.ui, 'update' ); + this.stopListening( this._balloon, 'change:visibleView' ); // Make sure the focus always gets back to the editable _before_ removing the focused form view. // Doing otherwise causes issues in some browsers. See https://github.com/ckeditor/ckeditor5-link/issues/193. @@ -441,7 +442,7 @@ export default class LinkUI extends Plugin { let prevSelectedLink = this._getSelectedLinkElement(); let prevSelectionParent = getSelectionParent(); - this.listenTo( editor.ui, 'update', () => { + const update = () => { const selectedLink = this._getSelectedLinkElement(); const selectionParent = getSelectionParent(); @@ -460,9 +461,10 @@ export default class LinkUI extends Plugin { this._hideUI(); } // Update the position of the panel when: + // * link panel is in the visible stack // * the selection remains in the original link element, // * there was no link element in the first place, i.e. creating a new link - else { + else if ( this._isUIVisible ) { // If still in a link element, simply update the position of the balloon. // If there was no link (e.g. inserting one), the balloon must be moved // to the new position in the editing view (a new native DOM range). @@ -471,13 +473,16 @@ export default class LinkUI extends Plugin { prevSelectedLink = selectedLink; prevSelectionParent = selectionParent; - } ); + }; function getSelectionParent() { return viewDocument.selection.focus.getAncestors() .reverse() .find( node => node.is( 'element' ) ); } + + this.listenTo( editor.ui, 'update', update ); + this.listenTo( this._balloon, 'change:visibleView', update ); } /** diff --git a/tests/linkui.js b/tests/linkui.js index 452f2c6..652b2b5 100644 --- a/tests/linkui.js +++ b/tests/linkui.js @@ -12,6 +12,7 @@ import { setData as setModelData } from '@ckeditor/ckeditor5-engine/src/dev-util import { getData as getViewData } from '@ckeditor/ckeditor5-engine/src/dev-utils/view'; import Paragraph from '@ckeditor/ckeditor5-paragraph/src/paragraph'; +import BlockQuote from '@ckeditor/ckeditor5-block-quote/src/blockquote'; import LinkEditing from '../src/linkediting'; import LinkUI from '../src/linkui'; import LinkFormView from '../src/ui/linkformview'; @@ -33,7 +34,7 @@ describe( 'LinkUI', () => { return ClassicTestEditor .create( editorElement, { - plugins: [ LinkEditing, LinkUI, Paragraph ] + plugins: [ LinkEditing, LinkUI, Paragraph, BlockQuote ] } ) .then( newEditor => { editor = newEditor; @@ -269,6 +270,42 @@ describe( 'LinkUI', () => { expect( balloon.visibleView ).to.equal( formView ); } ); + // https://github.com/ckeditor/ckeditor5-link/issues/242. + it( 'should update balloon position when is switched in rotator to a visible panel', () => { + setModelData( editor.model, 'fo<$text linkHref="foo">o[] bar' ); + linkUIFeature._showUI(); + + const customView = new View(); + const linkViewElement = editor.editing.view.document.getRoot().getChild( 0 ).getChild( 1 ); + const linkDomElement = editor.editing.view.domConverter.mapViewToDom( linkViewElement ); + + expect( balloon.visibleView ).to.equal( actionsView ); + expect( balloon.view.pin.lastCall.args[ 0 ].target ).to.equal( linkDomElement ); + + balloon.add( { + stackId: 'custom', + view: customView, + position: { target: {} } + } ); + + balloon.showStack( 'custom' ); + + expect( balloon.visibleView ).to.equal( customView ); + expect( balloon.hasView( actionsView ) ).to.equal( true ); + + editor.execute( 'blockQuote' ); + balloon.showStack( 'main' ); + + expect( balloon.visibleView ).to.equal( actionsView ); + expect( balloon.hasView( customView ) ).to.equal( true ); + expect( balloon.view.pin.lastCall.args[ 0 ].target ).to.not.equal( linkDomElement ); + + const newLinkViewElement = editor.editing.view.document.getRoot().getChild( 0 ).getChild( 0 ).getChild( 1 ); + const newLinkDomElement = editor.editing.view.domConverter.mapViewToDom( newLinkViewElement ); + + expect( balloon.view.pin.lastCall.args[ 0 ].target ).to.equal( newLinkDomElement ); + } ); + describe( 'response to ui#update', () => { let view, viewDocument; @@ -337,6 +374,31 @@ describe( 'LinkUI', () => { } ); } ); + it( 'not update the position when is in not visible stack', () => { + setModelData( editor.model, '<$text linkHref="url">f[]oo' ); + + linkUIFeature._showUI(); + + const customView = new View(); + + balloon.add( { + stackId: 'custom', + view: customView, + position: { target: {} } + } ); + + balloon.showStack( 'custom' ); + + expect( balloon.visibleView ).to.equal( customView ); + expect( balloon.hasView( actionsView ) ).to.equal( true ); + + const spy = testUtils.sinon.spy( balloon, 'updatePosition' ); + + editor.ui.fire( 'update' ); + + sinon.assert.notCalled( spy ); + } ); + // https://github.com/ckeditor/ckeditor5-link/issues/113 it( 'hides of the panel – editing a link, then the selection moved out of the link', () => { setModelData( editor.model, '<$text linkHref="url">f[]oobar' );