ソースを参照

Fix (link): Fixed the link balloon positioning in case of a collapsed selection in certain edge scenarios.

Marek Lewandowski 5 年 前
コミット
c98263104c
2 ファイル変更30 行追加22 行削除
  1. 15 11
      packages/ckeditor5-link/src/linkui.js
  2. 15 11
      packages/ckeditor5-link/tests/linkui.js

+ 15 - 11
packages/ckeditor5-link/src/linkui.js

@@ -589,18 +589,22 @@ export default class LinkUI extends Plugin {
 		const view = this.editor.editing.view;
 		const model = this.editor.model;
 		const viewDocument = view.document;
-		const targetLink = this._getSelectedLinkElement();
-		const range = model.markers.has( VISUAL_SELECTION_MARKER_NAME ) ?
+		let target = null;
+
+		if ( model.markers.has( VISUAL_SELECTION_MARKER_NAME ) ) {
 			// There are cases when we highlight selection using a marker (#7705, #4721).
-			this.editor.editing.mapper.toViewRange( model.markers.get( VISUAL_SELECTION_MARKER_NAME ).getRange() ) :
-			// If no markers are available refer to a regular selection.
-			viewDocument.selection.getFirstRange();
-
-		const target = targetLink ?
-			// When selection is inside link element, then attach panel to this element.
-			view.domConverter.mapViewToDom( targetLink ) :
-			// Otherwise attach panel to the selection.
-			view.domConverter.viewRangeToDom( range );
+			const markerViewElement = Array.from( this.editor.editing.mapper.markerNameToElements( VISUAL_SELECTION_MARKER_NAME ) )[ 0 ];
+			target = view.domConverter.mapViewToDom( markerViewElement );
+		} else {
+			const targetLink = this._getSelectedLinkElement();
+			const range = viewDocument.selection.getFirstRange();
+
+			target = targetLink ?
+				// When selection is inside link element, then attach panel to this element.
+				view.domConverter.mapViewToDom( targetLink ) :
+				// Otherwise attach panel to the selection.
+				view.domConverter.viewRangeToDom( range );
+		}
 
 		return { target };
 	}

+ 15 - 11
packages/ckeditor5-link/tests/linkui.js

@@ -134,30 +134,33 @@ describe( 'LinkUI', () => {
 
 		it( 'should add #formView to the balloon and attach the balloon to the selection when text fragment is selected', () => {
 			setModelData( editor.model, '<paragraph>f[o]o</paragraph>' );
-			const selectedRange = editorElement.ownerDocument.getSelection().getRangeAt( 0 );
 
 			linkUIFeature._showUI();
 
+			const markerElement = editor.ui.view.element.querySelector( '.ck-fake-link-selection' );
+
 			expect( balloon.visibleView ).to.equal( formView );
 			sinon.assert.calledWithExactly( balloonAddSpy, {
 				view: formView,
 				position: {
-					target: selectedRange
+					target: markerElement
 				}
 			} );
 		} );
 
-		it( 'should add #formView to the balloon and attach the balloon to the selection when selection is collapsed', () => {
+		it( 'should add #formView to the balloon and attach the balloon to the marker element when selection is collapsed', () => {
+			// (#7926)
 			setModelData( editor.model, '<paragraph>f[]oo</paragraph>' );
-			const selectedRange = editorElement.ownerDocument.getSelection().getRangeAt( 0 );
-
 			linkUIFeature._showUI();
 
+			const markerElement = editor.ui.view.element.querySelector( '.ck-fake-link-selection_collapsed' );
+
+			expect( markerElement ).not.to.be.null;
 			expect( balloon.visibleView ).to.equal( formView );
 			sinon.assert.calledWithExactly( balloonAddSpy, {
 				view: formView,
 				position: {
-					target: selectedRange
+					target: markerElement
 				}
 			} );
 		} );
@@ -167,14 +170,13 @@ describe( 'LinkUI', () => {
 
 			linkUIFeature._showUI();
 
-			const markerModelRange = editor.model.markers.get( 'link-ui' ).getRange();
-			const markerViewRange = editor.editing.mapper.toViewRange( markerModelRange );
-			const domRange = editor.editing.view.domConverter.viewRangeToDom( markerViewRange );
+			const markerElement = editor.ui.view.element.querySelector( '.ck-fake-link-selection' );
 
+			expect( markerElement ).not.to.be.null;
 			expect( balloonAddSpy.calledWithExactly( {
 				view: formView,
 				position: {
-					target: domRange
+					target: markerElement
 				}
 			} ), 'spy arguments' ).to.be.true;
 		} );
@@ -380,9 +382,11 @@ describe( 'LinkUI', () => {
 					writer.setSelection( text, 1, true );
 				} );
 
+				const markerElement = editor.ui.view.element.querySelector( '.ck-fake-link-selection' );
+
 				sinon.assert.calledOnce( spy );
 				sinon.assert.calledWithExactly( spy, {
-					target: editorElement.ownerDocument.getSelection().getRangeAt( 0 )
+					target: markerElement
 				} );
 			} );