/**
* @license Copyright (c) 2003-2018, 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 createViewRoot from '../_utils/createroot';
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;
function createUIElement( name, contents ) {
const element = new UIElement( name );
element.render = function( domDocument ) {
const domElement = this.toDomElement( domDocument );
domElement.innerText = contents;
return domElement;
};
return element;
}
beforeEach( () => {
domRoot = createElement( document, 'div', {
contenteditable: 'true'
} );
document.body.appendChild( domRoot );
viewDocument = new ViewDocument();
viewRoot = createViewRoot( viewDocument );
viewDocument.attachDomRoot( domRoot );
domSelection = document.getSelection();
domSelection.removeAllRanges();
viewDocument.isFocused = true;
foo = new ViewText( 'foo' );
bar = new ViewText( 'bar' );
ui = createUIElement( 'span', 'xxx' );
ui2 = createUIElement( 'span', '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' ) } ); } ); } ); } );