linkimageui.js 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120
  1. /**
  2. * @license Copyright (c) 2003-2020, CKSource - Frederico Knabben. All rights reserved.
  3. * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
  4. */
  5. /**
  6. * @module link/linkimageui
  7. */
  8. import ButtonView from '@ckeditor/ckeditor5-ui/src/button/buttonview';
  9. import Plugin from '@ckeditor/ckeditor5-core/src/plugin';
  10. import Image from '@ckeditor/ckeditor5-image/src/image';
  11. import LinkUI from './linkui';
  12. import LinkEditing from './linkediting';
  13. import { isImageWidget } from '@ckeditor/ckeditor5-image/src/image/utils';
  14. import { LINK_KEYSTROKE } from './utils';
  15. import linkIcon from '../theme/icons/link.svg';
  16. /**
  17. * The link image UI plugin.
  18. *
  19. * This plugin brings a `'linkImage'` button that can be displayed in the {@link module:image/imagetoolbar~ImageToolbar}
  20. * and used to wrap images in links.
  21. *
  22. * @extends module:core/plugin~Plugin
  23. */
  24. export default class LinkImageUI extends Plugin {
  25. /**
  26. * @inheritDoc
  27. */
  28. static get requires() {
  29. return [ Image, LinkEditing, LinkUI ];
  30. }
  31. /**
  32. * @inheritDoc
  33. */
  34. static get pluginName() {
  35. return 'LinkImageUI';
  36. }
  37. /**
  38. * @inheritDoc
  39. */
  40. init() {
  41. const editor = this.editor;
  42. const viewDocument = editor.editing.view.document;
  43. this.listenTo( viewDocument, 'click', ( evt, data ) => {
  44. const hasLink = isImageLinked( viewDocument.selection.getSelectedElement() );
  45. if ( hasLink ) {
  46. data.preventDefault();
  47. }
  48. } );
  49. this._createToolbarLinkImageButton();
  50. }
  51. /**
  52. * Creates a `LinkImageUI` button view.
  53. *
  54. * Clicking this button shows a {@link module:link/linkui~LinkUI#_balloon} attached to the selection.
  55. * When an image is already linked, the view shows {@link module:link/linkui~LinkUI#actionsView} or
  56. * {@link module:link/linkui~LinkUI#formView} if it's not.
  57. *
  58. * @private
  59. */
  60. _createToolbarLinkImageButton() {
  61. const editor = this.editor;
  62. const t = editor.t;
  63. editor.ui.componentFactory.add( 'linkImage', locale => {
  64. const button = new ButtonView( locale );
  65. const plugin = editor.plugins.get( 'LinkUI' );
  66. const linkCommand = editor.commands.get( 'link' );
  67. button.set( {
  68. isEnabled: true,
  69. label: t( 'Link image' ),
  70. icon: linkIcon,
  71. keystroke: LINK_KEYSTROKE,
  72. tooltip: true,
  73. isToggleable: true
  74. } );
  75. // Bind button to the command.
  76. button.bind( 'isEnabled' ).to( linkCommand, 'isEnabled' );
  77. button.bind( 'isOn' ).to( linkCommand, 'value', value => !!value );
  78. // Show the actionsView or formView (both from LinkUI) on button click depending on whether the image is linked already.
  79. this.listenTo( button, 'execute', () => {
  80. const hasLink = isImageLinked( editor.editing.view.document.selection.getSelectedElement() );
  81. if ( hasLink ) {
  82. plugin._addActionsView();
  83. } else {
  84. plugin._showUI( true );
  85. }
  86. } );
  87. return button;
  88. } );
  89. }
  90. }
  91. // A helper function that checks whether the element is a linked image.
  92. //
  93. // @param {module:engine/model/element~Element} element
  94. // @returns {Boolean}
  95. function isImageLinked( element ) {
  96. const isImage = element && isImageWidget( element );
  97. if ( !isImage ) {
  98. return false;
  99. }
  100. return element.getChild( 0 ).is( 'a' );
  101. }