mirror of
https://gerrit.wikimedia.org/r/mediawiki/extensions/VisualEditor
synced 2024-11-24 22:35:41 +00:00
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:
commit
27dfe83e6f
|
@ -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 );
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -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 );
|
||||
}
|
||||
} );
|
||||
|
||||
|
|
Loading…
Reference in a new issue