/** * @license Copyright (c) 2003-2015, CKSource - Frederico Knabben. All rights reserved. * For licensing, see LICENSE.md. */ /* globals document */ import createElement from 'ckeditor5/utils/dom/createelement.js'; import FakeSelectionObserver from 'ckeditor5/engine/view/observer/fakeselectionobserver.js'; import ViewDocument from 'ckeditor5/engine/view/document.js'; import DomEventData from 'ckeditor5/engine/view/observer/domeventdata.js'; import { keyCodes } from 'ckeditor5/utils/keyboard.js'; import { setData, stringify } from 'ckeditor5/engine/dev-utils/view.js'; describe( 'FakeSelectionObserver', () => { let observer; let viewDocument; let root; let domRoot; before( () => { domRoot = createElement( document, 'div', { contenteditable: 'true' } ); document.body.appendChild( domRoot ); } ); after( () => { domRoot.parentElement.removeChild( domRoot ); } ); beforeEach( () => { viewDocument = new ViewDocument(); root = viewDocument.createRoot( domRoot ); observer = viewDocument.getObserver( FakeSelectionObserver ); viewDocument.selection.setFake(); } ); afterEach( () => { viewDocument.destroy(); } ); it( 'should do nothing if selection is not fake', () => { viewDocument.selection.setFake( false ); return checkEventPrevention( keyCodes.arrowleft, false ); } ); it( 'should do nothing if is disabled', () => { observer.disable(); return checkEventPrevention( keyCodes.arrowleft, false ); } ); it( 'should prevent default for left arrow key', ( ) => { return checkEventPrevention( keyCodes.arrowleft ); } ); it( 'should prevent default for right arrow key', ( ) => { return checkEventPrevention( keyCodes.arrowright ); } ); it( 'should prevent default for up arrow key', ( ) => { return checkEventPrevention( keyCodes.arrowup ); } ); it( 'should prevent default for down arrow key', ( ) => { return checkEventPrevention( keyCodes.arrowdown ); } ); it( 'should fire selectionChange event with new selection when left arrow key is pressed', () => { return checkSelectionChange( 'foo[bar]baz', keyCodes.arrowleft, 'foo[]barbaz' ); } ); it( 'should fire selectionChange event with new selection when right arrow key is pressed', () => { return checkSelectionChange( 'foo[bar]baz', keyCodes.arrowright, 'foobar[]baz' ); } ); it( 'should fire selectionChange event with new selection when up arrow key is pressed', () => { return checkSelectionChange( 'foo[bar]baz', keyCodes.arrowup, 'foo[]barbaz' ); } ); it( 'should fire selectionChange event with new selection when down arrow key is pressed', () => { return checkSelectionChange( 'foo[bar]baz', keyCodes.arrowdown, 'foobar[]baz' ); } ); // Checks if preventDefault method was called by FakeSelectionObserver for specified key code. // // @param {Number} keyCode // @param {Boolean} shouldPrevent If set to true method checks if event was prevented. // @returns {Promise} function checkEventPrevention( keyCode, shouldPrevent = true ) { return new Promise( resolve => { const data = { keyCode, preventDefault: sinon.spy(), }; viewDocument.once( 'keydown', () => { if ( shouldPrevent ) { sinon.assert.calledOnce( data.preventDefault ); } else { sinon.assert.notCalled( data.preventDefault ); } resolve(); }, { priority: 'lowest' } ); viewDocument.fire( 'keydown', new DomEventData( viewDocument, { target: document.body }, data ) ); } ); } // Checks if proper selectionChange event is fired by FakeSelectionObserver for specified key. // // @param {String} initialData // @param {Number} keyCode // @param {String} output // @returns {Promise} function checkSelectionChange( initialData, keyCode, output ) { return new Promise( resolve => { viewDocument.once( 'selectionChange', ( eventInfo, data ) => { expect( stringify( root.getChild( 0 ), data.newSelection, { showType: true } ) ).to.equal( output ); resolve(); } ); setData( viewDocument, initialData ); viewDocument.selection.setFake(); const data = { keyCode, preventDefault: sinon.spy(), }; viewDocument.fire( 'keydown', new DomEventData( viewDocument, { target: document.body }, data ) ); } ); } } );