fakeselectionobserver.js 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149
  1. /**
  2. * @license Copyright (c) 2003-2015, CKSource - Frederico Knabben. All rights reserved.
  3. * For licensing, see LICENSE.md.
  4. */
  5. /* globals document */
  6. import createElement from 'ckeditor5/utils/dom/createelement.js';
  7. import FakeSelectionObserver from 'ckeditor5/engine/view/observer/fakeselectionobserver.js';
  8. import ViewDocument from 'ckeditor5/engine/view/document.js';
  9. import DomEventData from 'ckeditor5/engine/view/observer/domeventdata.js';
  10. import { keyCodes } from 'ckeditor5/utils/keyboard.js';
  11. import { setData, stringify } from 'ckeditor5/engine/dev-utils/view.js';
  12. describe( 'FakeSelectionObserver', () => {
  13. let observer;
  14. let viewDocument;
  15. let root;
  16. let domRoot;
  17. before( () => {
  18. domRoot = createElement( document, 'div', {
  19. contenteditable: 'true'
  20. } );
  21. document.body.appendChild( domRoot );
  22. } );
  23. after( () => {
  24. domRoot.parentElement.removeChild( domRoot );
  25. } );
  26. beforeEach( () => {
  27. viewDocument = new ViewDocument();
  28. root = viewDocument.createRoot( domRoot );
  29. observer = viewDocument.getObserver( FakeSelectionObserver );
  30. viewDocument.selection.setFake();
  31. } );
  32. it( 'should do nothing if selection is not fake', () => {
  33. viewDocument.selection.setFake( false );
  34. return checkEventPrevention( keyCodes.arrowleft, false );
  35. } );
  36. it( 'should do nothing if is disabled', () => {
  37. observer.disable();
  38. return checkEventPrevention( keyCodes.arrowleft, false );
  39. } );
  40. it( 'should prevent default for left arrow key', ( ) => {
  41. return checkEventPrevention( keyCodes.arrowleft );
  42. } );
  43. it( 'should prevent default for right arrow key', ( ) => {
  44. return checkEventPrevention( keyCodes.arrowright );
  45. } );
  46. it( 'should prevent default for up arrow key', ( ) => {
  47. return checkEventPrevention( keyCodes.arrowup );
  48. } );
  49. it( 'should prevent default for down arrow key', ( ) => {
  50. return checkEventPrevention( keyCodes.arrowdown );
  51. } );
  52. it( 'should fire selectionChange event with new selection when left arrow key is pressed', () => {
  53. return checkSelectionChange(
  54. '<container:p>foo[<strong>bar</strong>]baz</container:p>',
  55. keyCodes.arrowleft,
  56. '<container:p>foo[]<strong>bar</strong>baz</container:p>'
  57. );
  58. } );
  59. it( 'should fire selectionChange event with new selection when right arrow key is pressed', () => {
  60. return checkSelectionChange(
  61. '<container:p>foo[<strong>bar</strong>]baz</container:p>',
  62. keyCodes.arrowright,
  63. '<container:p>foo<strong>bar</strong>[]baz</container:p>'
  64. );
  65. } );
  66. it( 'should fire selectionChange event with new selection when up arrow key is pressed', () => {
  67. return checkSelectionChange(
  68. '<container:p>foo[<strong>bar</strong>]baz</container:p>',
  69. keyCodes.arrowup,
  70. '<container:p>foo[]<strong>bar</strong>baz</container:p>'
  71. );
  72. } );
  73. it( 'should fire selectionChange event with new selection when down arrow key is pressed', () => {
  74. return checkSelectionChange(
  75. '<container:p>foo[<strong>bar</strong>]baz</container:p>',
  76. keyCodes.arrowdown,
  77. '<container:p>foo<strong>bar</strong>[]baz</container:p>'
  78. );
  79. } );
  80. // Checks if preventDefault method was called by FakeSelectionObserver for specified key code.
  81. //
  82. // @param {Number} keyCode
  83. // @param {Boolean} shouldPrevent If set to true method checks if event was prevented.
  84. // @returns {Promise}
  85. function checkEventPrevention( keyCode, shouldPrevent = true ) {
  86. return new Promise( resolve => {
  87. const data = {
  88. keyCode,
  89. preventDefault: sinon.spy(),
  90. };
  91. viewDocument.once( 'keydown', () => {
  92. if ( shouldPrevent ) {
  93. sinon.assert.calledOnce( data.preventDefault );
  94. } else {
  95. sinon.assert.notCalled( data.preventDefault );
  96. }
  97. resolve();
  98. }, { priority: 'lowest' } );
  99. viewDocument.fire( 'keydown', new DomEventData( viewDocument, { target: document.body }, data ) );
  100. } );
  101. }
  102. // Checks if proper selectionChange event is fired by FakeSelectionObserver for specified key.
  103. //
  104. // @param {String} initialData
  105. // @param {Number} keyCode
  106. // @param {String} output
  107. // @returns {Promise}
  108. function checkSelectionChange( initialData, keyCode, output ) {
  109. return new Promise( resolve => {
  110. viewDocument.once( 'selectionChange', ( eventInfo, data ) => {
  111. expect( stringify( root.getChild( 0 ), data.newSelection, { showType: true } ) ).to.equal( output );
  112. resolve();
  113. } );
  114. setData( viewDocument, initialData );
  115. viewDocument.selection.setFake();
  116. const data = {
  117. keyCode,
  118. preventDefault: sinon.spy(),
  119. };
  120. viewDocument.fire( 'keydown', new DomEventData( viewDocument, { target: document.body }, data ) );
  121. } );
  122. }
  123. } );