8
0
panr 5 лет назад
Родитель
Сommit
caa896f2cc

+ 18 - 14
packages/ckeditor5-link/src/linkimageui.js

@@ -7,17 +7,16 @@
  * @module link/linkimageui
  * @module link/linkimageui
  */
  */
 
 
+import ButtonView from '@ckeditor/ckeditor5-ui/src/button/buttonview';
 import Plugin from '@ckeditor/ckeditor5-core/src/plugin';
 import Plugin from '@ckeditor/ckeditor5-core/src/plugin';
 import Image from '@ckeditor/ckeditor5-image/src/image';
 import Image from '@ckeditor/ckeditor5-image/src/image';
 import LinkUI from './linkui';
 import LinkUI from './linkui';
 import LinkEditing from './linkediting';
 import LinkEditing from './linkediting';
-
-import ButtonView from '@ckeditor/ckeditor5-ui/src/button/buttonview';
+import { isImageWidget } from '@ckeditor/ckeditor5-image/src/image/utils';
+import { LINK_KEYSTROKE } from './utils';
 
 
 import linkIcon from '../theme/icons/link.svg';
 import linkIcon from '../theme/icons/link.svg';
 
 
-const linkKeystroke = 'Ctrl+K';
-
 /**
 /**
  * The link image UI plugin.
  * The link image UI plugin.
  *
  *
@@ -62,7 +61,7 @@ export default class LinkImageUI extends Plugin {
 		const viewDocument = editor.editing.view.document;
 		const viewDocument = editor.editing.view.document;
 
 
 		this.listenTo( viewDocument, 'click', ( evt, data ) => {
 		this.listenTo( viewDocument, 'click', ( evt, data ) => {
-			const hasLink = isImageLinked( editor.model.document.selection.getSelectedElement() );
+			const hasLink = isImageLinked( viewDocument.selection.getSelectedElement() );
 
 
 			if ( hasLink ) {
 			if ( hasLink ) {
 				data.preventDefault();
 				data.preventDefault();
@@ -73,9 +72,9 @@ export default class LinkImageUI extends Plugin {
 	}
 	}
 
 
 	/**
 	/**
-	 * Creates a LinkImageUI button view.
-	 * Clicking on the button shows a {@link module:link/linkui~LinkUI#_balloon} attached to the selection.
-	 * When image is already linked, the view shows {@link module:link/linkui~LinkUI#actionsView} or
+	 * Creates a `LinkImageUI` button view.
+	 * Clicking this button shows a {@link module:link/linkui~LinkUI#_balloon} attached to the selection.
+	 * When an image is already linked, the view shows {@link module:link/linkui~LinkUI#actionsView} or
 	 * {@link module:link/linkui~LinkUI#formView} if it's not.
 	 * {@link module:link/linkui~LinkUI#formView} if it's not.
 	 *
 	 *
 	 * @private
 	 * @private
@@ -93,7 +92,7 @@ export default class LinkImageUI extends Plugin {
 				isEnabled: true,
 				isEnabled: true,
 				label: t( 'Link image' ),
 				label: t( 'Link image' ),
 				icon: linkIcon,
 				icon: linkIcon,
-				keystroke: linkKeystroke,
+				keystroke: LINK_KEYSTROKE,
 				tooltip: true,
 				tooltip: true,
 				isToggleable: true
 				isToggleable: true
 			} );
 			} );
@@ -101,13 +100,16 @@ export default class LinkImageUI extends Plugin {
 			// Bind button to the command.
 			// Bind button to the command.
 			button.bind( 'isEnabled' ).to( linkCommand, 'isEnabled' );
 			button.bind( 'isEnabled' ).to( linkCommand, 'isEnabled' );
 			button.bind( 'isOn' ).to( linkCommand, 'value', value => !!value );
 			button.bind( 'isOn' ).to( linkCommand, 'value', value => !!value );
-			button.bind( 'hasLink' ).to( this, 'hasLink' );
 
 
 			// Show the actionsView or formView (both from LinkUI) on button click depending on whether the image is linked already.
 			// Show the actionsView or formView (both from LinkUI) on button click depending on whether the image is linked already.
 			this.listenTo( button, 'execute', () => {
 			this.listenTo( button, 'execute', () => {
-				const hasLink = isImageLinked( editor.model.document.selection.getSelectedElement() );
+				const hasLink = isImageLinked( editor.editing.view.document.selection.getSelectedElement() );
 
 
-				hasLink ? plugin._addActionsView() : plugin._showUI( true );
+				if ( hasLink ) {
+					plugin._addActionsView();
+				} else {
+					plugin._showUI( true );
+				}
 			} );
 			} );
 
 
 			this.linkButtonView = button;
 			this.linkButtonView = button;
@@ -122,9 +124,11 @@ export default class LinkImageUI extends Plugin {
 // @param {module:engine/model/element~Element} element
 // @param {module:engine/model/element~Element} element
 // @returns {Boolean}
 // @returns {Boolean}
 function isImageLinked( element ) {
 function isImageLinked( element ) {
-	if ( !( element && element.is( 'image' ) ) ) {
+	const isImage = element && isImageWidget( element );
+
+	if ( !isImage ) {
 		return false;
 		return false;
 	}
 	}
 
 
-	return element && element.hasAttribute( 'linkHref' );
+	return element.getChild( 0 ).is( 'a' );
 }
 }

+ 5 - 5
packages/ckeditor5-link/src/linkui.js

@@ -9,7 +9,8 @@
 
 
 import Plugin from '@ckeditor/ckeditor5-core/src/plugin';
 import Plugin from '@ckeditor/ckeditor5-core/src/plugin';
 import ClickObserver from '@ckeditor/ckeditor5-engine/src/view/observer/clickobserver';
 import ClickObserver from '@ckeditor/ckeditor5-engine/src/view/observer/clickobserver';
-import { isLinkElement } from './utils';
+import { isLinkElement, LINK_KEYSTROKE } from './utils';
+
 import ContextualBalloon from '@ckeditor/ckeditor5-ui/src/panel/balloon/contextualballoon';
 import ContextualBalloon from '@ckeditor/ckeditor5-ui/src/panel/balloon/contextualballoon';
 
 
 import clickOutsideHandler from '@ckeditor/ckeditor5-ui/src/bindings/clickoutsidehandler';
 import clickOutsideHandler from '@ckeditor/ckeditor5-ui/src/bindings/clickoutsidehandler';
@@ -20,7 +21,6 @@ import LinkActionsView from './ui/linkactionsview';
 
 
 import linkIcon from '../theme/icons/link.svg';
 import linkIcon from '../theme/icons/link.svg';
 
 
-const linkKeystroke = 'Ctrl+K';
 const protocolRegExp = /^((\w+:(\/{2,})?)|(\W))/i;
 const protocolRegExp = /^((\w+:(\/{2,})?)|(\W))/i;
 const emailRegExp = /[\w-]+@[\w-]+\.+[\w-]+/i;
 const emailRegExp = /[\w-]+@[\w-]+\.+[\w-]+/i;
 
 
@@ -128,7 +128,7 @@ export default class LinkUI extends Plugin {
 		} );
 		} );
 
 
 		// Open the form view on Ctrl+K when the **actions have focus**..
 		// Open the form view on Ctrl+K when the **actions have focus**..
-		actionsView.keystrokes.set( linkKeystroke, ( data, cancel ) => {
+		actionsView.keystrokes.set( LINK_KEYSTROKE, ( data, cancel ) => {
 			this._addFormView();
 			this._addFormView();
 			cancel();
 			cancel();
 		} );
 		} );
@@ -197,7 +197,7 @@ export default class LinkUI extends Plugin {
 		const t = editor.t;
 		const t = editor.t;
 
 
 		// Handle the `Ctrl+K` keystroke and show the panel.
 		// Handle the `Ctrl+K` keystroke and show the panel.
-		editor.keystrokes.set( linkKeystroke, ( keyEvtData, cancel ) => {
+		editor.keystrokes.set( LINK_KEYSTROKE, ( keyEvtData, cancel ) => {
 			// Prevent focusing the search bar in FF, Chrome and Edge. See https://github.com/ckeditor/ckeditor5/issues/4811.
 			// Prevent focusing the search bar in FF, Chrome and Edge. See https://github.com/ckeditor/ckeditor5/issues/4811.
 			cancel();
 			cancel();
 
 
@@ -210,7 +210,7 @@ export default class LinkUI extends Plugin {
 			button.isEnabled = true;
 			button.isEnabled = true;
 			button.label = t( 'Link' );
 			button.label = t( 'Link' );
 			button.icon = linkIcon;
 			button.icon = linkIcon;
-			button.keystroke = linkKeystroke;
+			button.keystroke = LINK_KEYSTROKE;
 			button.tooltip = true;
 			button.tooltip = true;
 			button.isToggleable = true;
 			button.isToggleable = true;
 
 

+ 2 - 0
packages/ckeditor5-link/src/utils.js

@@ -12,6 +12,8 @@ import { upperFirst } from 'lodash-es';
 const ATTRIBUTE_WHITESPACES = /[\u0000-\u0020\u00A0\u1680\u180E\u2000-\u2029\u205f\u3000]/g; // eslint-disable-line no-control-regex
 const ATTRIBUTE_WHITESPACES = /[\u0000-\u0020\u00A0\u1680\u180E\u2000-\u2029\u205f\u3000]/g; // eslint-disable-line no-control-regex
 const SAFE_URL = /^(?:(?:https?|ftps?|mailto):|[^a-z]|[a-z+.-]+(?:[^a-z+.:-]|$))/i;
 const SAFE_URL = /^(?:(?:https?|ftps?|mailto):|[^a-z]|[a-z+.-]+(?:[^a-z+.:-]|$))/i;
 
 
+export const LINK_KEYSTROKE = 'Ctrl+K';
+
 /**
 /**
  * Returns `true` if a given view node is the link element.
  * Returns `true` if a given view node is the link element.
  *
  *

+ 21 - 10
packages/ckeditor5-link/tests/linkimageui.js

@@ -10,9 +10,9 @@ import ButtonView from '@ckeditor/ckeditor5-ui/src/button/buttonview';
 import EventInfo from '@ckeditor/ckeditor5-utils/src/eventinfo';
 import EventInfo from '@ckeditor/ckeditor5-utils/src/eventinfo';
 import DomEventData from '@ckeditor/ckeditor5-engine/src/view/observer/domeventdata';
 import DomEventData from '@ckeditor/ckeditor5-engine/src/view/observer/domeventdata';
 import Paragraph from '@ckeditor/ckeditor5-paragraph/src/paragraph';
 import Paragraph from '@ckeditor/ckeditor5-paragraph/src/paragraph';
-import { setData as setModelData } from '@ckeditor/ckeditor5-engine/src/dev-utils/model';
 import testUtils from '@ckeditor/ckeditor5-core/tests/_utils/utils';
 import testUtils from '@ckeditor/ckeditor5-core/tests/_utils/utils';
 
 
+import LinkImage from '../src/linkimage';
 import LinkImageUI from '../src/linkimageui';
 import LinkImageUI from '../src/linkimageui';
 
 
 describe( 'LinkImageUI', () => {
 describe( 'LinkImageUI', () => {
@@ -27,7 +27,7 @@ describe( 'LinkImageUI', () => {
 
 
 		return ClassicTestEditor
 		return ClassicTestEditor
 			.create( editorElement, {
 			.create( editorElement, {
-				plugins: [ LinkImageUI, Paragraph ]
+				plugins: [ LinkImageUI, LinkImage, Paragraph ]
 			} )
 			} )
 			.then( newEditor => {
 			.then( newEditor => {
 				editor = newEditor;
 				editor = newEditor;
@@ -51,8 +51,7 @@ describe( 'LinkImageUI', () => {
 
 
 	describe( 'init()', () => {
 	describe( 'init()', () => {
 		it( 'should listen to the click event on the images', () => {
 		it( 'should listen to the click event on the images', () => {
-			const linkPlugin = editor.plugins.get( 'LinkUI' );
-			const listenToSpy = sinon.stub( linkPlugin, 'listenTo' );
+			const listenToSpy = sinon.stub( plugin, 'listenTo' );
 
 
 			listenToSpy( viewDocument, 'click' );
 			listenToSpy( viewDocument, 'click' );
 
 
@@ -98,18 +97,22 @@ describe( 'LinkImageUI', () => {
 	} );
 	} );
 
 
 	describe( 'click', () => {
 	describe( 'click', () => {
-		it( 'should prevent default behavior if image has "linkHref" attribute', () => {
-			setModelData( editor.model, '[<image src="" linkHref="https://example.com"></image>]' );
+		it( 'should prevent default behavior if image is wrapped with a link', () => {
+			editor.setData( '<figure class="image"><a href="https://example.com"><img src="" /></a></figure>' );
 
 
-			const img = editor.model.document.selection.getSelectedElement();
+			editor.editing.view.change( writer => {
+				writer.setSelection( viewDocument.getRoot().getChild( 0 ), 'on' );
+			} );
+
+			const img = viewDocument.selection.getSelectedElement();
 			const data = fakeEventData();
 			const data = fakeEventData();
 			const eventInfo = new EventInfo( img, 'click' );
 			const eventInfo = new EventInfo( img, 'click' );
 			const domEventDataMock = new DomEventData( viewDocument, eventInfo, data );
 			const domEventDataMock = new DomEventData( viewDocument, eventInfo, data );
 
 
 			viewDocument.fire( 'click', domEventDataMock );
 			viewDocument.fire( 'click', domEventDataMock );
 
 
+			expect( img.getChild( 0 ).name ).to.equal( 'a' );
 			expect( data.preventDefault.called ).to.be.true;
 			expect( data.preventDefault.called ).to.be.true;
-			expect( eventInfo.source.name ).to.equal( 'image' );
 		} );
 		} );
 	} );
 	} );
 
 
@@ -117,7 +120,11 @@ describe( 'LinkImageUI', () => {
 		it( 'should show plugin#actionsView after "execute" if image is already linked', () => {
 		it( 'should show plugin#actionsView after "execute" if image is already linked', () => {
 			const linkUIPlugin = editor.plugins.get( 'LinkUI' );
 			const linkUIPlugin = editor.plugins.get( 'LinkUI' );
 
 
-			setModelData( editor.model, '[<image src="" linkHref="https://example.com"></image>]' );
+			editor.setData( '<figure class="image"><a href="https://example.com"><img src="" /></a></figure>' );
+
+			editor.editing.view.change( writer => {
+				writer.setSelection( viewDocument.getRoot().getChild( 0 ), 'on' );
+			} );
 
 
 			linkButton.fire( 'execute' );
 			linkButton.fire( 'execute' );
 
 
@@ -127,7 +134,11 @@ describe( 'LinkImageUI', () => {
 		it( 'should show plugin#formView after "execute" if image is not linked', () => {
 		it( 'should show plugin#formView after "execute" if image is not linked', () => {
 			const linkUIPlugin = editor.plugins.get( 'LinkUI' );
 			const linkUIPlugin = editor.plugins.get( 'LinkUI' );
 
 
-			setModelData( editor.model, '[<image src=""></image>]' );
+			editor.setData( '<figure class="image"><img src="" /></a>' );
+
+			editor.editing.view.change( writer => {
+				writer.setSelection( viewDocument.getRoot().getChild( 0 ), 'on' );
+			} );
 
 
 			linkButton.fire( 'execute' );
 			linkButton.fire( 'execute' );
 
 

+ 1 - 1
packages/ckeditor5-link/tests/manual/linkimage.html

@@ -5,5 +5,5 @@
 		</a>
 		</a>
 		<figcaption>CKEditor logo - caption</figcaption>
 		<figcaption>CKEditor logo - caption</figcaption>
 	</figure>
 	</figure>
-		<img alt="bar" src="sample.jpg">
+	<img alt="bar" src="sample.jpg">
 </div>
 </div>