imageediting.js 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137
  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/image/imageediting
  7. */
  8. import Plugin from '@ckeditor/ckeditor5-core/src/plugin';
  9. import ImageLoadObserver from './imageloadobserver';
  10. import {
  11. viewFigureToModel,
  12. modelToViewAttributeConverter,
  13. srcsetAttributeConverter
  14. } from './converters';
  15. import { toImageWidget } from './utils';
  16. import ImageInsertCommand from './imageinsertcommand';
  17. /**
  18. * The image engine plugin.
  19. *
  20. * It registers:
  21. *
  22. * * `<image>` as a block element in the document schema, and allows `alt`, `src` and `srcset` attributes.
  23. * * converters for editing and data pipelines.
  24. * * `'imageInsert'` command.
  25. *
  26. * @extends module:core/plugin~Plugin
  27. */
  28. export default class ImageEditing extends Plugin {
  29. /**
  30. * @inheritDoc
  31. */
  32. static get pluginName() {
  33. return 'ImageEditing';
  34. }
  35. /**
  36. * @inheritDoc
  37. */
  38. init() {
  39. const editor = this.editor;
  40. const schema = editor.model.schema;
  41. const t = editor.t;
  42. const conversion = editor.conversion;
  43. // See https://github.com/ckeditor/ckeditor5-image/issues/142.
  44. editor.editing.view.addObserver( ImageLoadObserver );
  45. // Configure schema.
  46. schema.register( 'image', {
  47. isObject: true,
  48. isBlock: true,
  49. allowWhere: '$block',
  50. allowAttributes: [ 'alt', 'src', 'srcset' ]
  51. } );
  52. conversion.for( 'dataDowncast' ).elementToElement( {
  53. model: 'image',
  54. view: ( modelElement, viewWriter ) => createImageViewElement( viewWriter )
  55. } );
  56. conversion.for( 'editingDowncast' ).elementToElement( {
  57. model: 'image',
  58. view: ( modelElement, viewWriter ) => toImageWidget( createImageViewElement( viewWriter ), viewWriter, t( 'image widget' ) )
  59. } );
  60. conversion.for( 'downcast' )
  61. .add( modelToViewAttributeConverter( 'src' ) )
  62. .add( modelToViewAttributeConverter( 'alt' ) )
  63. .add( srcsetAttributeConverter() );
  64. conversion.for( 'upcast' )
  65. .elementToElement( {
  66. view: {
  67. name: 'img',
  68. attributes: {
  69. src: true
  70. }
  71. },
  72. model: ( viewImage, modelWriter ) => modelWriter.createElement( 'image', { src: viewImage.getAttribute( 'src' ) } )
  73. } )
  74. .attributeToAttribute( {
  75. view: {
  76. name: 'img',
  77. key: 'alt'
  78. },
  79. model: 'alt'
  80. } )
  81. .attributeToAttribute( {
  82. view: {
  83. name: 'img',
  84. key: 'srcset'
  85. },
  86. model: {
  87. key: 'srcset',
  88. value: viewImage => {
  89. const value = {
  90. data: viewImage.getAttribute( 'srcset' )
  91. };
  92. if ( viewImage.hasAttribute( 'width' ) ) {
  93. value.width = viewImage.getAttribute( 'width' );
  94. }
  95. return value;
  96. }
  97. }
  98. } )
  99. .add( viewFigureToModel() );
  100. // Register imageUpload command.
  101. editor.commands.add( 'imageInsert', new ImageInsertCommand( editor ) );
  102. }
  103. }
  104. // Creates a view element representing the image.
  105. //
  106. // <figure class="image"><img></img></figure>
  107. //
  108. // Note that `alt` and `src` attributes are converted separately, so they are not included.
  109. //
  110. // @private
  111. // @param {module:engine/view/downcastwriter~DowncastWriter} writer
  112. // @returns {module:engine/view/containerelement~ContainerElement}
  113. export function createImageViewElement( writer ) {
  114. const emptyElement = writer.createEmptyElement( 'img' );
  115. const figure = writer.createContainerElement( 'figure', { class: 'image' } );
  116. writer.insert( writer.createPositionAt( figure, 0 ), emptyElement );
  117. return figure;
  118. }