Procházet zdrojové kódy

Merge pull request #300 from ckeditor/t/299

Fix: Improved stability of ImageTextAlternative balloon used in rotator.
Kacper Tomporowski před 6 roky
rodič
revize
82f5ff71c0

+ 16 - 4
packages/ckeditor5-image/src/imagetextalternative/imagetextalternativeui.js

@@ -163,7 +163,7 @@ export default class ImageTextAlternativeUI extends Plugin {
 		const command = editor.commands.get( 'imageTextAlternative' );
 		const labeledInput = this._form.labeledInput;
 
-		if ( !this._balloon.hasView( this._form ) ) {
+		if ( !this._isInBalloon ) {
 			this._balloon.add( {
 				view: this._form,
 				position: getBalloonPositionData( editor )
@@ -187,13 +187,15 @@ export default class ImageTextAlternativeUI extends Plugin {
 	 * @private
 	 */
 	_hideForm( focusEditable ) {
-		if ( !this._isVisible ) {
+		if ( !this._isInBalloon ) {
 			return;
 		}
 
 		// Blur the input element before removing it from DOM to prevent issues in some browsers.
 		// See https://github.com/ckeditor/ckeditor5/issues/1501.
-		this._form.saveButtonView.focus();
+		if ( this._form.focusTracker.isFocused ) {
+			this._form.saveButtonView.focus();
+		}
 
 		this._balloon.remove( this._form );
 
@@ -209,6 +211,16 @@ export default class ImageTextAlternativeUI extends Plugin {
 	 * @type {Boolean}
 	 */
 	get _isVisible() {
-		return this._balloon.visibleView == this._form;
+		return this._balloon.visibleView === this._form;
+	}
+
+	/**
+	 * Returns `true` when the {@link #_form} is in the {@link #_balloon}.
+	 *
+	 * @private
+	 * @type {Boolean}
+	 */
+	get _isInBalloon() {
+		return this._balloon.hasView( this._form );
 	}
 }

+ 43 - 1
packages/ckeditor5-image/tests/imagetextalternative/imagetextalternativeui.js

@@ -9,6 +9,7 @@ import ClassicTestEditor from '@ckeditor/ckeditor5-core/tests/_utils/classictest
 import Image from '../../src/image';
 import ImageTextAlternativeEditing from '../../src/imagetextalternative/imagetextalternativeediting';
 import ImageTextAlternativeUI from '../../src/imagetextalternative/imagetextalternativeui';
+import Paragraph from '@ckeditor/ckeditor5-paragraph/src/paragraph';
 import ButtonView from '@ckeditor/ckeditor5-ui/src/button/buttonview';
 import View from '@ckeditor/ckeditor5-ui/src/view';
 import global from '@ckeditor/ckeditor5-utils/src/dom/global';
@@ -24,7 +25,7 @@ describe( 'ImageTextAlternativeUI', () => {
 
 		return ClassicTestEditor
 			.create( editorElement, {
-				plugins: [ ImageTextAlternativeEditing, ImageTextAlternativeUI, Image ]
+				plugins: [ ImageTextAlternativeEditing, ImageTextAlternativeUI, Image, Paragraph ]
 			} )
 			.then( newEditor => {
 				editor = newEditor;
@@ -169,11 +170,52 @@ describe( 'ImageTextAlternativeUI', () => {
 			const editableFocusSpy = sinon.spy( editor.editing.view, 'focus' );
 			const buttonFocusSpy = sinon.spy( form.saveButtonView, 'focus' );
 
+			form.focusTracker.isFocused = true;
+
 			form.fire( 'submit' );
 
 			expect( buttonFocusSpy.calledBefore( editableFocusSpy ) ).to.equal( true );
 		} );
 
+		// https://github.com/ckeditor/ckeditor5-image/issues/299
+		it( 'should not blur url input element before hiding the view when view was not focused', () => {
+			setData( model, '[<image src="" alt="foo bar"></image>]' );
+
+			editor.ui.componentFactory.create( 'imageTextAlternative' ).fire( 'execute' );
+
+			const buttonFocusSpy = sinon.spy( form.saveButtonView, 'focus' );
+
+			form.focusTracker.isFocused = false;
+
+			form.fire( 'cancel' );
+
+			sinon.assert.notCalled( buttonFocusSpy );
+		} );
+
+		it( 'should be removed from balloon when is in not visible stack', () => {
+			setData( model, '<paragraph>foo</paragraph>[<image src="" alt="foo bar"></image>]' );
+
+			editor.ui.componentFactory.create( 'imageTextAlternative' ).fire( 'execute' );
+
+			const customView = new View();
+
+			balloon.add( {
+				view: customView,
+				position: { target: {} },
+				stackId: 'custom'
+			} );
+
+			balloon.showStack( 'custom' );
+
+			model.change( writer => {
+				const root = model.document.getRoot();
+
+				writer.setSelection( root.getChild( 0 ), 0 );
+			} );
+
+			expect( balloon.hasView( form ) ).to.equal( false );
+		} );
+
 		describe( 'integration with the editor selection (ui#update event)', () => {
 			it( 'should re-position the form', () => {
 				setData( model, '[<image src=""></image>]' );