8
0
Просмотр исходного кода

Improved checking if caret sticks attribute element bounds.

Oskar Wróbel 8 лет назад
Родитель
Сommit
cbf2530442

+ 4 - 0
packages/ckeditor5-engine/src/utils/bindtwostepcarettoattribute.js

@@ -126,5 +126,9 @@ function isStickToAttribute( nextNode, prevNode, attribute ) {
 	const isAttrInNext = nextNode ? nextNode.hasAttribute( attribute ) : false;
 	const isAttrInPrev = prevNode ? prevNode.hasAttribute( attribute ) : false;
 
+	if ( isAttrInNext && isAttrInPrev && nextNode.getAttributeKeys( attribute ) !== prevNode.getAttribute( attribute ) ) {
+		return true;
+	}
+
 	return isAttrInNext && !isAttrInPrev || !isAttrInNext && isAttrInPrev;
 }

+ 35 - 1
packages/ckeditor5-engine/tests/utils/bindtwostepcarettoattribute.js

@@ -88,7 +88,7 @@ describe( 'bindTwoStepCaretToAttribute()', () => {
 				preventDefault: preventDefaultSpy
 			} ) );
 
-			// Gravity is overridden, caret movement is blocked, selection at the beginning but "outside" the text.
+			// Gravity is overridden, caret movement is blocked, selection at the end but "outside" the text.
 			expect( Array.from( selection.getAttributeKeys() ) ).to.have.members( [ 'c' ] );
 			expect( selection.isGravityOverridden ).to.true;
 			sinon.assert.calledOnce( preventDefaultSpy );
@@ -126,6 +126,23 @@ describe( 'bindTwoStepCaretToAttribute()', () => {
 			sinon.assert.notCalled( preventDefaultSpy );
 			expect( selection.isGravityOverridden ).to.false;
 		} );
+
+		it( 'should require two-steps movement when caret goes between text node with the same attribute but different value', () => {
+			setData( model, '<$text a="1">bar[]</$text><$text a="2">foo</$text>' );
+
+			// Gravity is not overridden.
+			expect( selection.isGravityOverridden ).to.false;
+
+			// Press right key.
+			viewDoc.fire( 'keydown', getEventData( {
+				keyCode: keyCodes.arrowright,
+				preventDefault: preventDefaultSpy
+			} ) );
+
+			// Gravity is overridden, caret movement is blocked.
+			expect( selection.isGravityOverridden ).to.true;
+			sinon.assert.calledOnce( preventDefaultSpy );
+		} );
 	} );
 
 	describe( 'moving left', () => {
@@ -254,6 +271,23 @@ describe( 'bindTwoStepCaretToAttribute()', () => {
 				viewDoc.fire( 'keydown', getEventData( { keyCode: keyCodes.arrowleft } ) );
 			} ).to.not.throw();
 		} );
+
+		it( 'should require two-steps movement when caret goes between text node with the same attribute but different value', () => {
+			setData( model, '<$text a="2">foo</$text><$text a="1">b[]ar</$text>' );
+
+			// Gravity is not overridden.
+			expect( selection.isGravityOverridden ).to.false;
+
+			// Press left key.
+			viewDoc.fire( 'keydown', getEventData( {
+				keyCode: keyCodes.arrowleft,
+				preventDefault: preventDefaultSpy
+			} ) );
+
+			// Gravity is overridden, caret movement was not blocked.
+			sinon.assert.notCalled( preventDefaultSpy );
+			expect( selection.isGravityOverridden ).to.true;
+		} );
 	} );
 
 	describe( 'mouse', () => {