/**
* @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
* For licensing, see LICENSE.md.
*/
/* globals document */
import ViewDocument from '../../../src/view/document';
import UIElement from '../../../src/view/uielement';
import ViewContainerElement from '../../../src/view/containerelement';
import ViewAttribtueElement from '../../../src/view/attributeelement';
import ViewText from '../../../src/view/text';
import ViewRange from '../../../src/view/range';
import { keyCodes } from '@ckeditor/ckeditor5-utils/src/keyboard';
import createElement from '@ckeditor/ckeditor5-utils/src/dom/createelement';
import { setData as setViewData } from '../../../src/dev-utils/view';
import testUtils from '@ckeditor/ckeditor5-core/tests/_utils/utils';
describe( 'Document', () => {
let viewDocument, domRoot, domSelection, viewRoot, foo, bar, ui, ui2;
class MyUIElement extends UIElement {
render( domDocument ) {
const element = super.render( domDocument );
element.innerText = this.contents;
return element;
}
}
beforeEach( () => {
domRoot = createElement( document, 'div', {
contenteditable: 'true'
} );
document.body.appendChild( domRoot );
viewDocument = new ViewDocument();
viewRoot = viewDocument.createRoot( domRoot );
domSelection = document.getSelection();
domSelection.removeAllRanges();
viewDocument.isFocused = true;
foo = new ViewText( 'foo' );
bar = new ViewText( 'bar' );
ui = new MyUIElement( 'span' );
ui.contents = 'xxx';
ui2 = new MyUIElement( 'span' );
ui2.contents = 'yyy';
} );
afterEach( () => {
viewDocument.destroy();
domRoot.parentElement.removeChild( domRoot );
} );
function renderAndFireKeydownEvent( options ) {
viewDocument.render();
const eventData = Object.assign( { keyCode: keyCodes.arrowright, domTarget: viewDocument.domRoots.get( 'main' ) }, options );
viewDocument.fire( 'keydown', eventData );
}
function check( anchorNode, anchorOffset, focusNode, focusOffset ) {
const anchor = domSelection.anchorNode.data ? domSelection.anchorNode.data : domSelection.anchorNode.nodeName.toUpperCase();
expect( anchor, 'anchorNode' ).to.equal( anchorNode );
expect( domSelection.anchorOffset, 'anchorOffset' ).to.equal( anchorOffset );
if ( focusNode ) {
const focus = domSelection.focusNode.data ? domSelection.focusNode.data : domSelection.focusNode.nodeName.toUpperCase();
expect( focus, 'focusNode' ).to.equal( focusNode );
expect( domSelection.focusOffset, 'focusOffset' ).to.equal( focusOffset );
} else {
expect( domSelection.isCollapsed, 'isCollapsed' ).to.be.true;
}
}
describe( 'jump over ui element handler', () => {
describe( 'collapsed selection', () => {
it( 'do nothing when another key is pressed', () => {
//
fooxxx[]bar
() => check( 'P', 2 ), // Safari renders selection at the end of the text node. //fooxxx{}bar
() => check( 'xxx', 3 ) ); } ); it( 'jump over ui element when right arrow is pressed before ui element - not directly before ui element', () => { //fooxxx[]bar
() => check( 'P', 2 ), // Safari renders selection at the end of the text node. //fooxxx{}bar
() => check( 'xxx', 3 ) ); } ); it( 'jump over multiple ui elements when right arrow is pressed before ui element', () => { //fooxxxyyy[]bar
() => check( 'P', 3 ), // Safari renders selection at the end of the text node. //fooxxxyyy{}bar
() => check( 'yyy', 3 ) ); } ); it( 'jump over ui elements at the end of container element', () => { //fooxxxyyy[]
() => check( 'P', 3 ), // Safari renders selection at the end of the text node. //fooxxxyyy{}
() => check( 'yyy', 3 ) ); } ); it( 'jump over ui element if selection is in attribute element - case 1', () => { //fooxxx[]bar
() => check( 'P', 2 ), // Safari renders selection at the end of the text node. //fooxxx{}bar
() => check( 'xxx', 3 ) ); } ); it( 'jump over ui element if selection is in attribute element - case 2', () => { //fooxxx[]bar
() => check( 'P', 2 ), // Safari renders selection at the end of the text node. //fooxxx{}bar
() => check( 'xxx', 3 ) ); } ); it( 'jump over ui element if selection is in multiple attribute elements', () => { //fooxxx[]bar
() => check( 'P', 2 ), // Safari renders selection at the end of the text node. //fooxxx{}bar
() => check( 'xxx', 3 ) ); } ); it( 'jump over empty attribute elements and ui elements', () => { //fooxxxyyy[]bar
() => check( 'P', 5 ), // Safari renders selection at the end of the text node. //fooxxxyyy{}bar
() => check( 'yyy', 3 ) ); } ); it( 'jump over empty attribute elements and ui elements if shift key is pressed', () => { //fooxxxyyy[]bar
() => check( 'P', 5 ), // Safari renders selection at the end of the text node. //fooxxxyyy{}bar
() => check( 'yyy', 3 ) ); } ); it( 'do nothing if selection is not directly before ui element', () => { setViewData( viewDocument, 'fo{oxxx]bar
() => check( 'foo', 2, 'P', 2 ), // Safari renders selection at the end of the previous text node. //fo{oxxx}bar
() => check( 'foo', 2, 'xxx', 3 ) ); } ); it( 'jump over ui element if selection is in multiple attribute elements', () => { //fo{oxxx]bar
() => check( 'foo', 2, 'P', 2 ), // Safari renders selection at the end of the previous text node. //fo{oxxx}bar
() => check( 'foo', 2, 'xxx', 3 ) ); } ); it( 'jump over empty attribute elements and ui elements if shift key is pressed', () => { //fo{oxxxyyy]bar
() => check( 'foo', 2, 'P', 5 ), // Safari renders selection at the end of the previous text node. //fo{oxxxyyy}bar
() => check( 'foo', 2, 'yyy', 3 ) ); } ); } ); it( 'should do nothing if dom position cannot be converted to view position', () => { const newDiv = document.createElement( 'div' ); const domSelection = document.getSelection(); document.body.appendChild( newDiv ); domSelection.collapse( newDiv, 0 ); viewDocument.fire( 'keydown', { keyCode: keyCodes.arrowright, domTarget: viewDocument.domRoots.get( 'main' ) } ); } ); } ); } );