8
0

keystrokehandler.js 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109
  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 './utils/emittermixin.js';
  7. import { getCode, parseKeystroke } from './utils/keyboard.js';
  8. /**
  9. * Keystroke handler. Its instance is available in {@link ckeditor5.Editor#keystrokes} so features
  10. * can register their keystrokes.
  11. *
  12. * E.g. an undo feature would do this:
  13. *
  14. * editor.keystrokes.set( 'ctrl + Z', 'undo' );
  15. * editor.keystrokes.set( 'ctrl + shift + Z', 'redo' );
  16. * editor.keystrokes.set( 'ctrl + Y', 'redo' );
  17. *
  18. * @memberOf ckeditor5
  19. */
  20. export default class KeystrokeHandler {
  21. /**
  22. * Creates an instance of the keystroke handler.
  23. *
  24. * @param {engine.treeView.TreeView} editingView
  25. */
  26. constructor( editor ) {
  27. /**
  28. * The editor instance.
  29. *
  30. * @readonly
  31. * @member {ckeditor5.Editor} ckeditor5.KeystrokeHandler#editor
  32. */
  33. this.editor = editor;
  34. /**
  35. * Listener used to listen to events for easier keystroke handler destruction.
  36. *
  37. * @private
  38. * @member {utils.Emitter} ckeditor5.KeystrokeHandler#_listener
  39. */
  40. this._listener = Object.create( EmitterMixin );
  41. /**
  42. * Map of the defined keystrokes. Keystroke codes are the keys.
  43. *
  44. * @private
  45. * @member {Map} ckeditor5.KeystrokeHandler#_keystrokes
  46. */
  47. this._keystrokes = new Map();
  48. this._listener.listenTo( editor.editing.view, 'keydown', ( evt, data ) => {
  49. const handled = this.press( data );
  50. if ( handled ) {
  51. data.preventDefault();
  52. }
  53. } );
  54. }
  55. /**
  56. * Registers a handler for the specified keystroke.
  57. *
  58. * The handler can be specified as a command name or a callback.
  59. *
  60. * @param {String|Array.<String|Number>} keystroke Keystroke defined in a format accepted by
  61. * the {@link utils.keyboard.parseKeystroke} function.
  62. * @param {String|Function} callback If a string is passed, then the keystroke will
  63. * {@link ckeditor5.Editor#execute execute a command}.
  64. * If a function, then it will be called with the
  65. * {@link engine.view.observer.keyObserver.KeyEventData key event data} object.
  66. */
  67. set( keystroke, callback ) {
  68. this._keystrokes.set( parseKeystroke( keystroke ), callback );
  69. }
  70. /**
  71. * Triggers a keystroke handler for a specified key combination, if such a keystroke was {@link #set defined}.
  72. *
  73. * @param {engine.view.observer.keyObserver.KeyEventData} keyEventData Key event data.
  74. * @returns {Boolean} Whether the keystroke was handled.
  75. */
  76. press( keyEventData ) {
  77. const keyCode = getCode( keyEventData );
  78. const callback = this._keystrokes.get( keyCode );
  79. if ( !callback ) {
  80. return false;
  81. }
  82. if ( typeof callback == 'string' ) {
  83. this.editor.execute( callback );
  84. } else {
  85. callback( keyEventData );
  86. }
  87. return true;
  88. }
  89. /**
  90. * Destroys the keystroke handler.
  91. */
  92. destroy() {
  93. this._keystrokes = new Map();
  94. this._listener.stopListening();
  95. }
  96. }