multicommand.js 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101
  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. import Command from './command';
  6. /**
  7. * @module core/multicommand
  8. */
  9. /**
  10. * A CKEditor command that aggregates other commands.
  11. *
  12. * This command is used to proxy multiple commands. The multi-command is enabled when
  13. * at least one of its registered child commands is enabled.
  14. * When executing a multi-command the first command that is enabled will be executed.
  15. *
  16. * const multiCommand = new MultiCommand( editor );
  17. *
  18. * const commandFoo = new Command( editor );
  19. * const commandBar = new Command( editor );
  20. *
  21. * // Register child commands.
  22. * multiCommand.registerChildCommand( commandFoo );
  23. * multiCommand.registerChildCommand( commandBar );
  24. *
  25. * // Enable one of the commands.
  26. * commandBar.isEnabled = true;
  27. *
  28. * multiCommand.execute(); // Will execute commandBar.
  29. *
  30. * @extends module:core/command~Command
  31. */
  32. export default class MultiCommand extends Command {
  33. /**
  34. * @inheritDoc
  35. */
  36. constructor( editor ) {
  37. super( editor );
  38. /**
  39. * Registered child commands.
  40. *
  41. * @type {Array.<module:core/command~Command>}
  42. * @private
  43. */
  44. this._childCommands = [];
  45. }
  46. /**
  47. * @inheritDoc
  48. */
  49. refresh() {
  50. // Override base command refresh(): the command's state is changed when one of child commands changes states.
  51. }
  52. /**
  53. * Executes the first of it registered child commands.
  54. *
  55. * @returns {*} The value returned by the {@link module:core/command~Command#execute `command.execute()`}.
  56. */
  57. execute( ...args ) {
  58. const command = this._getFirstEnabledCommand();
  59. return command.execute( args );
  60. }
  61. /**
  62. * Registers a child command.
  63. *
  64. * @param {module:core/command~Command} command
  65. */
  66. registerChildCommand( command ) {
  67. this._childCommands.push( command );
  68. // Change multi command enabled state when one of registered commands changes state.
  69. command.on( 'change:isEnabled', () => this._checkEnabled() );
  70. this._checkEnabled();
  71. }
  72. /**
  73. * Checks if any of child commands is enabled.
  74. *
  75. * @private
  76. */
  77. _checkEnabled() {
  78. this.isEnabled = !!this._getFirstEnabledCommand();
  79. }
  80. /**
  81. * Returns a first enabled command or undefined if none of them is enabled.
  82. *
  83. * @returns {module:core/command~Command|undefined}
  84. * @private
  85. */
  86. _getFirstEnabledCommand() {
  87. return this._childCommands.find( command => command.isEnabled );
  88. }
  89. }