浏览代码

Fixed: Handle jumping over ui element with shift key pressed.

Szymon Cofalik 8 年之前
父节点
当前提交
572b37ebd7

+ 12 - 4
packages/ckeditor5-engine/src/view/uielement.js

@@ -109,10 +109,12 @@ function getFillerOffset() {
 function jumpOverUiElement( evt, data, domConverter ) {
 	if ( data.keyCode == keyCodes.arrowright ) {
 		const domSelection = data.domTarget.ownerDocument.defaultView.getSelection();
+		const domSelectionCollapsed = domSelection.rangeCount == 1 && domSelection.getRangeAt( 0 ).collapsed;
 
-		if ( domSelection.rangeCount == 1 && domSelection.getRangeAt( 0 ).collapsed ) {
-			const domParent = domSelection.getRangeAt( 0 ).startContainer;
-			const domOffset = domSelection.getRangeAt( 0 ).startOffset;
+		// Jump over UI element if selection is collapsed or shift key is pressed. These are the cases when selection would extend.
+		if ( domSelectionCollapsed || data.shiftKey ) {
+			const domParent = domSelection.focusNode;
+			const domOffset = domSelection.focusOffset;
 
 			const viewPosition = domConverter.domPositionToView( domParent, domOffset );
 
@@ -129,7 +131,13 @@ function jumpOverUiElement( evt, data, domConverter ) {
 			if ( !viewPosition.isEqual( nextViewPosition ) ) {
 				const newDomPosition = domConverter.viewPositionToDom( nextViewPosition );
 
-				domSelection.collapse( newDomPosition.parent, newDomPosition.offset );
+				if ( domSelectionCollapsed ) {
+					// Selection was collapsed, so collapse it at further position.
+					domSelection.collapse( newDomPosition.parent, newDomPosition.offset );
+				} else {
+					// Selection was not collapse, so extend it instead of collapsing.
+					domSelection.extend( newDomPosition.parent, newDomPosition.offset );
+				}
 			}
 		}
 	}

+ 17 - 0
packages/ckeditor5-engine/tests/view/document/jumpoveruielement.js

@@ -75,6 +75,23 @@ describe( 'Document', () => {
 			expect( domSelection.isCollapsed ).to.be.false;
 		} );
 
+		it( 'jump over ui element if selection is not collapsed but shift key is pressed', () => {
+			setData( viewDocument, '<container:p>fo{o}<ui:span></ui:span>bar</container:p>' );
+			viewDocument.render();
+
+			viewDocument.fire(
+				'keydown',
+				{ keyCode: keyCodes.arrowright, shiftKey: true, domTarget: viewDocument.domRoots.get( 'main' ) }
+			);
+
+			const domSelection = document.getSelection();
+
+			expect( domSelection.anchorNode.nodeName.toUpperCase() ).to.equal( '#TEXT' );
+			expect( domSelection.anchorOffset ).to.equal( 2 );
+			expect( domSelection.focusNode.nodeName.toUpperCase() ).to.equal( 'P' );
+			expect( domSelection.focusOffset ).to.equal( 2 );
+		} );
+
 		it( 'should do nothing if caret is not directly before ui element', () => {
 			setData( viewDocument, '<container:p>fo{}o<ui:span></ui:span>bar</container:p>' );
 			viewDocument.render();