fakeselectionobserver.js 3.1 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697
  1. /**
  2. * @license Copyright (c) 2003-2015, CKSource - Frederico Knabben. All rights reserved.
  3. * For licensing, see LICENSE.md.
  4. */
  5. /**
  6. * @module engine/view/observer/fakeselectionobserver
  7. */
  8. import Observer from './observer.js';
  9. import ViewSelection from '../selection.js';
  10. import { keyCodes } from '../../../utils/keyboard.js';
  11. /**
  12. * Fake selection observer class. If view selection is fake it is placed in dummy DOM container. This observer listens
  13. * on {@link module:engine/view/document~Document#event:keydown keydown} events and handles moving fake view selection to the correct place
  14. * if arrow keys are pressed.
  15. * Fires {@link module:engine/view/document~Document#selectionChage selectionChange event} simulating natural behaviour of
  16. * {@link module:engine/view/observer/selectionobserver~SelectionObserver SelectionObserver}.
  17. *
  18. * @extends module:engine/view/observer/observer~Observer.Observer
  19. */
  20. export default class FakeSelectionObserver extends Observer {
  21. /**
  22. * Creates new FakeSelectionObserver instance.
  23. *
  24. * @param {module:engine/view/document~Document} document
  25. */
  26. constructor( document ) {
  27. super( document );
  28. }
  29. /**
  30. * @inheritDoc
  31. */
  32. observe() {
  33. const document = this.document;
  34. document.on( 'keydown', ( eventInfo, data ) => {
  35. const selection = document.selection;
  36. if ( selection.isFake && _isArrowKeyCode( data.keyCode ) && this.isEnabled ) {
  37. // Prevents default key down handling - no selection change will occur.
  38. data.preventDefault();
  39. this._handleSelectionMove( data.keyCode );
  40. }
  41. }, { priority: 'lowest' } );
  42. }
  43. /**
  44. * Handles collapsing view selection according to given key code. If left or up key is provided - new selection will be
  45. * collapsed to left. If right or down key is pressed - new selection will be collapsed to right.
  46. *
  47. * This method fires {@link module:engine/view/document~Document#event:selectionChange} event imitating behaviour of
  48. * {@link module:engine/view/observer/selectionobserver~SelectionObserver}.
  49. *
  50. * @private
  51. * @param {Number} keyCode
  52. * @fires module:engine/view/document~Document#selectionChage
  53. */
  54. _handleSelectionMove( keyCode ) {
  55. const selection = this.document.selection;
  56. const newSelection = ViewSelection.createFromSelection( selection );
  57. newSelection.setFake( false );
  58. // Left or up arrow pressed - move selection to start.
  59. if ( keyCode == keyCodes.arrowleft || keyCode == keyCodes.arrowup ) {
  60. newSelection.collapseToStart();
  61. }
  62. // Right or down arrow pressed - move selection to end.
  63. if ( keyCode == keyCodes.arrowright || keyCode == keyCodes.arrowdown ) {
  64. newSelection.collapseToEnd();
  65. }
  66. // Fire dummy selection change event.
  67. this.document.fire( 'selectionChange', {
  68. oldSelection: selection,
  69. newSelection: newSelection,
  70. domSelection: null
  71. } );
  72. }
  73. }
  74. // Checks if one of the arrow keys is pressed.
  75. //
  76. // @private
  77. // @param {Number} keyCode
  78. // @returns {Boolean}
  79. function _isArrowKeyCode( keyCode ) {
  80. return keyCode == keyCodes.arrowright ||
  81. keyCode == keyCodes.arrowleft ||
  82. keyCode == keyCodes.arrowup ||
  83. keyCode == keyCodes.arrowdown;
  84. }