8
0

ckfindercommand.js 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154
  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. /* global window */
  6. /**
  7. * @module ckfinder/ckfindercommand
  8. */
  9. import Command from '@ckeditor/ckeditor5-core/src/command';
  10. import CKEditorError from '@ckeditor/ckeditor5-utils/src/ckeditorerror';
  11. /**
  12. * The CKFinder command. It is used by the {@link module:ckfinder/ckfinderediting~CKFinderEditing CKFinder editing feature}
  13. * to open the CKFinder file manager to insert an image or a link to a file into the editor content.
  14. *
  15. * editor.execute( 'ckfinder' );
  16. *
  17. * **Note:** This command uses other features to perform tasks:
  18. * - To insert images the {@link module:image/image/imageinsertcommand~ImageInsertCommand 'imageInsert'} command
  19. * from the {@link module:image/image~Image Image feature}.
  20. * - To insert links to files the {@link module:link/linkcommand~LinkCommand 'link'} command
  21. * from the {@link module:link/link~Link Link feature}.
  22. *
  23. * @extends module:core/command~Command
  24. */
  25. export default class CKFinderCommand extends Command {
  26. /**
  27. * @inheritDoc
  28. */
  29. constructor( editor ) {
  30. super( editor );
  31. // Remove default document listener to lower its priority.
  32. this.stopListening( this.editor.model.document, 'change' );
  33. // Lower this command listener priority to be sure that refresh() will be called after link & image refresh.
  34. this.listenTo( this.editor.model.document, 'change', () => this.refresh(), { priority: 'low' } );
  35. }
  36. /**
  37. * @inheritDoc
  38. */
  39. refresh() {
  40. const imageCommand = this.editor.commands.get( 'imageInsert' );
  41. const linkCommand = this.editor.commands.get( 'link' );
  42. // The CKFinder command is enabled when one of image or link command is enabled.
  43. this.isEnabled = imageCommand.isEnabled || linkCommand.isEnabled;
  44. }
  45. /**
  46. * @inheritDoc
  47. */
  48. execute() {
  49. const editor = this.editor;
  50. const openerMethod = this.editor.config.get( 'ckfinder.openerMethod' ) || 'modal';
  51. if ( openerMethod != 'popup' && openerMethod != 'modal' ) {
  52. /**
  53. * The `ckfinder.openerMethod` must be one of: "popup" or "modal".
  54. *
  55. * @error ckfinder-unknown-openermethod
  56. */
  57. throw new CKEditorError( 'ckfinder-unknown-openermethod', editor );
  58. }
  59. const options = this.editor.config.get( 'ckfinder.options' ) || {};
  60. options.chooseFiles = true;
  61. // Cache the user-defined onInit method
  62. const originalOnInit = options.onInit;
  63. // Pass the lang code to the CKFinder if not defined by user.
  64. if ( !options.language ) {
  65. options.language = editor.locale.uiLanguage;
  66. }
  67. // The onInit method allows to extend CKFinder's behavior. It is used to attach event listeners to file choosing related events.
  68. options.onInit = finder => {
  69. // Call original options.onInit if it was defined by user.
  70. if ( originalOnInit ) {
  71. originalOnInit( finder );
  72. }
  73. finder.on( 'files:choose', evt => {
  74. const files = evt.data.files.toArray();
  75. // Insert links
  76. const links = files.filter( file => !file.isImage() );
  77. const images = files.filter( file => file.isImage() );
  78. for ( const linkFile of links ) {
  79. editor.execute( 'link', linkFile.getUrl() );
  80. }
  81. const imagesUrls = [];
  82. for ( const image of images ) {
  83. const url = image.getUrl();
  84. imagesUrls.push( url ? url : finder.request( 'file:getProxyUrl', { file: image } ) );
  85. }
  86. if ( imagesUrls.length ) {
  87. insertImages( editor, imagesUrls );
  88. }
  89. } );
  90. finder.on( 'file:choose:resizedImage', evt => {
  91. const resizedUrl = evt.data.resizedUrl;
  92. if ( !resizedUrl ) {
  93. const notification = editor.plugins.get( 'Notification' );
  94. const t = editor.locale.t;
  95. notification.showWarning( t( 'Could not obtain resized image URL.' ), {
  96. title: t( 'Selecting resized image failed' ),
  97. namespace: 'ckfinder'
  98. } );
  99. return;
  100. }
  101. insertImages( editor, [ resizedUrl ] );
  102. } );
  103. };
  104. window.CKFinder[ openerMethod ]( options );
  105. }
  106. }
  107. function insertImages( editor, urls ) {
  108. const imageCommand = editor.commands.get( 'imageInsert' );
  109. // Check if inserting an image is actually possible - it might be possible to only insert a link.
  110. if ( !imageCommand.isEnabled ) {
  111. const notification = editor.plugins.get( 'Notification' );
  112. const t = editor.locale.t;
  113. notification.showWarning( t( 'Could not insert image at the current position.' ), {
  114. title: t( 'Inserting image failed' ),
  115. namespace: 'ckfinder'
  116. } );
  117. return;
  118. }
  119. editor.execute( 'imageInsert', { source: urls } );
  120. }