8
0

imageresizeediting.js 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142
  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 image/imageresize/imageresizeediting
  7. */
  8. import Plugin from '@ckeditor/ckeditor5-core/src/plugin';
  9. import WidgetResize from '@ckeditor/ckeditor5-widget/src/widgetresize';
  10. import ImageResizeCommand from './imageresizecommand';
  11. /**
  12. * The image resize feature.
  13. *
  14. * It adds a possibility to resize each image using handles or manually by
  15. * {@link module:image/imageresize/imageresizeui~ImageResizeUI} buttons.
  16. *
  17. * @extends module:core/plugin~Plugin
  18. */
  19. export default class ImageResizeEditing extends Plugin {
  20. /**
  21. * @inheritDoc
  22. */
  23. static get requires() {
  24. return [ WidgetResize ];
  25. }
  26. /**
  27. * @inheritDoc
  28. */
  29. static get pluginName() {
  30. return 'ImageResizeEditing';
  31. }
  32. /**
  33. * @inheritDoc
  34. */
  35. init() {
  36. const editor = this.editor;
  37. const command = new ImageResizeCommand( editor );
  38. this._registerSchema();
  39. this._registerConverters();
  40. editor.commands.add( 'imageResize', command );
  41. editor.editing.downcastDispatcher.on( 'insert:image', ( evt, data, conversionApi ) => {
  42. const widget = conversionApi.mapper.toViewElement( data.item );
  43. const resizer = editor.plugins
  44. .get( WidgetResize )
  45. .attachTo( {
  46. unit: editor.config.get( 'image.resizeUnit' ) || '%',
  47. modelElement: data.item,
  48. viewElement: widget,
  49. editor,
  50. getHandleHost( domWidgetElement ) {
  51. return domWidgetElement.querySelector( 'img' );
  52. },
  53. getResizeHost( domWidgetElement ) {
  54. return domWidgetElement;
  55. },
  56. // TODO consider other positions.
  57. isCentered() {
  58. const imageStyle = data.item.getAttribute( 'imageStyle' );
  59. return !imageStyle || imageStyle == 'full' || imageStyle == 'alignCenter';
  60. },
  61. onCommit( newValue ) {
  62. editor.execute( 'imageResize', { width: newValue } );
  63. }
  64. } );
  65. resizer.on( 'updateSize', () => {
  66. if ( !widget.hasClass( 'image_resized' ) ) {
  67. editor.editing.view.change( writer => {
  68. writer.addClass( 'image_resized', widget );
  69. } );
  70. }
  71. } );
  72. resizer.bind( 'isEnabled' ).to( command );
  73. }, { priority: 'low' } );
  74. }
  75. /**
  76. * @private
  77. */
  78. _registerSchema() {
  79. this.editor.model.schema.extend( 'image', {
  80. allowAttributes: 'width'
  81. } );
  82. }
  83. /**
  84. * Registers image resize converters.
  85. *
  86. * @private
  87. */
  88. _registerConverters() {
  89. const editor = this.editor;
  90. // Dedicated converter to propagate image's attribute to the img tag.
  91. editor.conversion.for( 'downcast' ).add( dispatcher =>
  92. dispatcher.on( 'attribute:width:image', ( evt, data, conversionApi ) => {
  93. if ( !conversionApi.consumable.consume( data.item, evt.name ) ) {
  94. return;
  95. }
  96. const viewWriter = conversionApi.writer;
  97. const figure = conversionApi.mapper.toViewElement( data.item );
  98. if ( data.attributeNewValue !== null ) {
  99. viewWriter.setStyle( 'width', data.attributeNewValue, figure );
  100. viewWriter.addClass( 'image_resized', figure );
  101. } else {
  102. viewWriter.removeStyle( 'width', figure );
  103. viewWriter.removeClass( 'image_resized', figure );
  104. }
  105. } )
  106. );
  107. editor.conversion.for( 'upcast' )
  108. .attributeToAttribute( {
  109. view: {
  110. name: 'figure',
  111. styles: {
  112. width: /.+/
  113. }
  114. },
  115. model: {
  116. key: 'width',
  117. value: viewElement => viewElement.getStyle( 'width' )
  118. }
  119. } );
  120. }
  121. }