command.js 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135
  1. /**
  2. * @license Copyright (c) 2003-2016, CKSource - Frederico Knabben. All rights reserved.
  3. * For licensing, see LICENSE.md.
  4. */
  5. 'use strict';
  6. import EmitterMixin from '../emittermixin.js';
  7. import utils from '../utils.js';
  8. /**
  9. * The base class for CKEditor commands.
  10. *
  11. * Commands are main way to manipulate editor contents and state. They are mostly used by UI elements (or by other
  12. * commands) to make changes in Tree Model. Commands are available in every part of code that has access to
  13. * {@link core.Editor} instance, since they are registered in it and executed through {@link core.Editor#execute}.
  14. * Commands instances are available through {@link core.Editor#commands}.
  15. *
  16. * This is an abstract base class for all commands.
  17. *
  18. * @memberOf core.command
  19. */
  20. export default class Command {
  21. /**
  22. * Creates a new Command instance.
  23. *
  24. * @param {core.Editor} editor Editor on which this command will be used.
  25. */
  26. constructor( editor ) {
  27. /**
  28. * Editor on which this command will be used.
  29. *
  30. * @member {core.Editor} core.command.Command#editor
  31. */
  32. this.editor = editor;
  33. /**
  34. * Flag indicating whether a command is enabled or disabled.
  35. * A disabled command should do nothing upon it's execution.
  36. *
  37. * @member {Boolean} core.command.Command#isEnabled
  38. */
  39. this.isEnabled = true;
  40. // If schema checking function is specified, add it to the `refreshState` listeners.
  41. // Feature will be disabled if it does not apply to schema requirements.
  42. if ( this.checkEnabled ) {
  43. this.on( 'refreshState', ( evt ) => {
  44. if ( !this.checkEnabled() ) {
  45. return disableCallback( evt );
  46. }
  47. } );
  48. }
  49. }
  50. /**
  51. * Checks if a command should be enabled according to its own rules. Mostly it will check schema to see if the command
  52. * is allowed to be executed in given position. This method can be defined in child class (but is not obligatory).
  53. * If it is defined, it will be added as a callback to `refreshState` event.
  54. *
  55. * @method core.command.Command#checkEnabled
  56. * @returns {Boolean} `true` if command should be enabled according to {@link core.treeModel.Document#schema}. `false` otherwise.
  57. */
  58. /**
  59. * Fires `refreshState` event and checks it's resolve value to decide whether command should be enabled or not.
  60. * Other parts of code might listen to `refreshState` event on this command and add their callbacks. This
  61. * way the responsibility of deciding whether a command should be enabled is shared.
  62. *
  63. * @fires {@link core.command.Command.refreshState refreshState}
  64. */
  65. refreshState() {
  66. this.isEnabled = this.fire( 'refreshState' ) !== false;
  67. }
  68. /**
  69. * Executes the command if it is enabled.
  70. *
  71. * @protected
  72. * @param {*} param Parameter passed to {@link core.command.Command#execute execute} method of this command.
  73. */
  74. doExecute( param ) {
  75. if ( this.isEnabled ) {
  76. this._execute( param );
  77. }
  78. }
  79. /**
  80. * Disables the command. This should be used only by the command itself. Other parts of code should add
  81. * listeners to `refreshState` event.
  82. *
  83. * @private
  84. */
  85. _disable() {
  86. this.on( 'refreshState', disableCallback );
  87. this.refreshState();
  88. }
  89. /**
  90. * Enables the command (internally). This should be used only by the command itself. Command will be enabled if
  91. * other listeners does not return false on `refreshState` event callbacks. Firing {@link core.command.Command#_enable}
  92. * does not guarantee that {@link core.command.Command#isEnabled} will be set to true, as it depends on other listeners.
  93. *
  94. * @private
  95. */
  96. _enable() {
  97. this.off( 'refreshState', disableCallback );
  98. this.refreshState();
  99. }
  100. /**
  101. * Executes command.
  102. * This is an abstract method that should be overwritten in child classes.
  103. *
  104. * @private
  105. */
  106. _execute() {
  107. }
  108. }
  109. function disableCallback( evt ) {
  110. evt.stop();
  111. return false;
  112. }
  113. utils.mix( Command, EmitterMixin );
  114. /**
  115. * Fired whenever command has to have it's {@link core.command.Command#isEnabled} property refreshed. Every feature,
  116. * command or other class which should be able to disable command (set `isEnabled` to `false`) should listen to this
  117. * event.
  118. *
  119. * @event core.command.Command.refreshState
  120. */