Merge changes I247d1b68,I5a8ca28a

* changes:
  Fix getOffsetFrom(Element|Text)Node for annotated aliens
  Add test for getOffsetFrom(Element|Text)Node
This commit is contained in:
jenkins-bot 2013-09-05 07:51:16 +00:00 committed by Gerrit Code Review
commit 27dfe83e6f
2 changed files with 88 additions and 9 deletions

View file

@ -191,13 +191,12 @@ ve.ce.getOffsetFromTextNode = function ( domNode, domOffset ) {
* @method
* @param {HTMLElement} domNode DOM node
* @param {number} domOffset DOM offset within the DOM Element
* @param {boolean} [addOuterLength] Use outer length, which includes wrappers if any exist
* @param {number} [firstRecursionDirection] Which direction the first recursive call went in (+/-1)
* @returns {number} Linear model offset
*/
ve.ce.getOffsetFromElementNode = function ( domNode, domOffset, addOuterLength ) {
var $domNode = $( domNode ),
nodeModel,
node;
ve.ce.getOffsetFromElementNode = function ( domNode, domOffset, firstRecursionDirection ) {
var direction, nodeModel, node,
$domNode = $( domNode );
if ( $domNode.hasClass( 've-ce-branchNode-slug' ) ) {
if ( $domNode.prev().length ) {
@ -211,8 +210,8 @@ ve.ce.getOffsetFromElementNode = function ( domNode, domOffset, addOuterLength )
}
// IE sometimes puts the cursor in a text node inside ce="false". BAD!
if ( domNode.contentEditable === 'false' ) {
nodeModel = $domNode.data( 'view' ).getModel();
if ( !firstRecursionDirection && !domNode.isContentEditable ) {
nodeModel = $domNode.closest( '.ve-ce-branchNode, .ve-ce-leafNode' ).data( 'view' ).getModel();
return nodeModel.getOffset() + nodeModel.getOuterLength();
}
@ -220,22 +219,30 @@ ve.ce.getOffsetFromElementNode = function ( domNode, domOffset, addOuterLength )
node = $domNode.data( 'view' );
if ( node && node instanceof ve.ce.Node ) {
nodeModel = $domNode.data( 'view' ).getModel();
if ( addOuterLength === true ) {
if ( firstRecursionDirection === -1 ) {
return nodeModel.getOffset() + nodeModel.getOuterLength();
} else if ( firstRecursionDirection === 1 ) {
return nodeModel.getOffset();
} else {
return nodeModel.getOffset() + ( nodeModel.isWrapped() ? 1 : 0 );
}
} else {
node = $domNode.contents().last()[0];
if ( !firstRecursionDirection ) {
direction = 1;
}
}
} else {
node = $domNode.contents()[ domOffset - 1 ];
if ( !firstRecursionDirection ) {
direction = -1;
}
}
if ( node.nodeType === Node.TEXT_NODE ) {
return ve.ce.getOffsetFromTextNode( node, node.length );
} else {
return ve.ce.getOffsetFromElementNode( node, 0, true );
return ve.ce.getOffsetFromElementNode( node, 0, direction );
}
};

View file

@ -29,3 +29,75 @@ QUnit.test( 'getDomHash', 1, function ( assert ) {
'<SPAN>#<B><A>#</A></B><SPAN></SPAN><I>#</I>#</SPAN>'
);
} );
QUnit.test( 'getOffsetFrom(Element|Text)Node', function ( assert ) {
var i, dom, target, surface, documentModel, documentView,
expected = 0,
testCases = [
{
'msg': 'Annotated alien',
'html': '<p>Foo<b><cite>Bar</cite></b>Baz</p>',
// CE html summary;
// <p>Foo<b><span [protectedNode]><cite>Bar</cite><img [shield]></span></b>Baz</p>
'expected': [
0,
1, 1,
2,
3,
4, 4, 4,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
7,
8,
9, 9,
10
]
}
];
for( i = 0; i < testCases.length; i++ ) {
expected += testCases[i].expected.length;
}
QUnit.expect( expected );
function testOffsets( parent, testCase, expectedIndex ) {
var i;
switch ( parent.nodeType ) {
case Node.ELEMENT_NODE:
for ( i = 0; i <= parent.childNodes.length; i++ ) {
expectedIndex++;
assert.equal(
ve.ce.getOffsetFromElementNode( parent, i ),
testCase.expected[expectedIndex],
testCase.msg + ': offset ' + i + ' in <' + parent.nodeName.toLowerCase() + '>'
);
if ( parent.childNodes[i] ) {
expectedIndex = testOffsets( parent.childNodes[i], testCase, expectedIndex );
}
}
break;
case Node.TEXT_NODE:
for ( i = 0; i <= parent.data.length; i++ ) {
expectedIndex++;
assert.equal(
ve.ce.getOffsetFromTextNode( parent, i ),
testCase.expected[expectedIndex],
testCase.msg + ': offset ' + i + ' in "' + parent.data + '"'
);
}
break;
}
return expectedIndex;
}
for( i = 0; i < testCases.length; i++ ) {
dom = ve.createDocumentFromHtml( testCases[i].html );
target = new ve.init.sa.Target( $( '#qunit-fixture' ), dom );
surface = target.surface;
documentModel = surface.getModel().getDocument();
documentView = surface.getView().getDocument();
testOffsets( documentView.documentNode.$[0], testCases[i], -1 );
}
} );