mirror of
https://gerrit.wikimedia.org/r/mediawiki/extensions/VisualEditor
synced 2024-11-15 18:39:52 +00:00
Added documentation and tests for ve.dm.Document.selectNodes
Also: * Broke node lookup method out into ve.dm.example.lookupNode * Added ve.dm.example.nodeSelectionEqual Change-Id: I437cdd3f3154d10782f03f78df6d5c457ecfc845
This commit is contained in:
parent
82ef058cb7
commit
f4fcf9663e
|
@ -65,9 +65,16 @@ ve.dm.Document.prototype.rebuildNodes = function( parent, index, numNodes, offse
|
|||
return nodes;
|
||||
};
|
||||
|
||||
// TODO needs docs
|
||||
// TODO needs more modes, probably. Current implementation is for mode=='leaf'
|
||||
// TODO needs tests
|
||||
/**
|
||||
* Gets a list of nodes and the ranges within them that a selection of the document covers.
|
||||
*
|
||||
* @method
|
||||
* @param {ve.Range} range Range within document to select nodes
|
||||
* @param {String} [mode='leaf'] Type of selection to perform, currently only 'leaf' is supported
|
||||
* @returns {Array} List of objects describing nodes in the selection and the ranges therein
|
||||
* @throws 'Invalid start offset' if range.start is out of range
|
||||
* @throws 'Invalid end offset' if range.end is out of range
|
||||
*/
|
||||
ve.dm.Document.prototype.selectNodes = function( range, mode ) {
|
||||
var doc = this.getDocumentNode(),
|
||||
retval = [],
|
||||
|
@ -85,14 +92,19 @@ ve.dm.Document.prototype.selectNodes = function( range, mode ) {
|
|||
startBetween,
|
||||
endBetween;
|
||||
|
||||
if ( start < 0 || start > this.data.length ) {
|
||||
throw 'Invalid start offset ' + start;
|
||||
}
|
||||
if ( end < 0 || end > this.data.length ) {
|
||||
throw 'Invalid end offset ' + end;
|
||||
// TODO needs more modes, probably. Current implementation is only for mode == 'leaf'
|
||||
if ( mode && mode !== 'leaf') {
|
||||
throw 'Invalid mode: ' + mode;
|
||||
}
|
||||
|
||||
if ( !doc.children || doc.children.length == 0 ) {
|
||||
if ( start < 0 || start > this.data.length ) {
|
||||
throw 'Invalid start offset: ' + start;
|
||||
}
|
||||
if ( end < 0 || end > this.data.length ) {
|
||||
throw 'Invalid end offset: ' + end;
|
||||
}
|
||||
|
||||
if ( !doc.children || doc.children.length === 0 ) {
|
||||
return [];
|
||||
}
|
||||
left = doc.children[0].isWrapped() ? 1 : 0;
|
||||
|
@ -206,11 +218,10 @@ ve.dm.Document.prototype.selectNodes = function( range, mode ) {
|
|||
( node.isWrapped() ? 1 : 0 ) +
|
||||
// Skip over nextNode's opening, if present
|
||||
( nextNode.isWrapped() ? 1 : 0 );
|
||||
|
||||
} else {
|
||||
// There is no next node, move up the stack
|
||||
stack.pop();
|
||||
if ( stack.length == 0 ) {
|
||||
if ( stack.length === 0 ) {
|
||||
// This shouldn't be possible
|
||||
return retval;
|
||||
}
|
||||
|
|
|
@ -18,3 +18,20 @@ test( 'rebuildNodes', 114, function() {
|
|||
// Test count: ( ( 4 tests x 21 branch nodes ) + ( 3 tests x 10 leaf nodes ) ) = 114
|
||||
ve.dm.example.nodeTreeEqual( documentNode, ve.dm.example.tree );
|
||||
} );
|
||||
|
||||
test( 'selectNodes', 7, function() {
|
||||
var doc = new ve.dm.Document( ve.dm.example.data ),
|
||||
documentNode = doc.getDocumentNode(),
|
||||
lookup = ve.dm.example.lookupNode;
|
||||
|
||||
// Test count: ( 1 test + ( 2 tests x 2 results ) + ( 2 test + 1 result with range ) ) = 7
|
||||
ve.dm.example.nodeSelectionEqual(
|
||||
doc.selectNodes( new ve.Range( 0, 10 ) ),
|
||||
[
|
||||
// heading
|
||||
{ 'node': lookup( documentNode, 0 ) },
|
||||
// table/row/cell/paragraph/text
|
||||
{ 'node': lookup( documentNode, 1, 0, 0, 0, 0 ), 'range': new ve.Range( 9, 10 ) }
|
||||
]
|
||||
);
|
||||
} );
|
||||
|
|
|
@ -261,6 +261,42 @@ ve.dm.example.nodeTreeEqual = function( a, b ) {
|
|||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Asserts that two node selections are equavilant.
|
||||
*
|
||||
* This will perform 1 assertion to check the number of results in the selection and then 2
|
||||
* assertions on each result plus 2 more for each result with a range.
|
||||
*
|
||||
* @method
|
||||
*/
|
||||
ve.dm.example.nodeSelectionEqual = function( a, b ) {
|
||||
equal( a.length, b.length, 'length match' );
|
||||
for ( var i = 0; i < a.length; i++ ) {
|
||||
ok( a[i].node === b[i].node, 'node match' );
|
||||
ok( 'range' in a[i] === 'range' in b[i], 'range existence match' );
|
||||
if ( a[i].range ) {
|
||||
strictEqual( a[i].range.from, b[i].range.from, 'range from match' );
|
||||
strictEqual( a[i].range.to, b[i].range.to, 'range to match' );
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Looks up a value in a node tree.
|
||||
*
|
||||
* @method
|
||||
* @param {ve.Node} root Root node to lookup from
|
||||
* @param {Integer} [...] Index path
|
||||
* @param {ve.Node} Node at given path
|
||||
*/
|
||||
ve.dm.example.lookupNode = function( root ) {
|
||||
var node = root;
|
||||
for ( var i = 1; i < arguments.length; i++ ) {
|
||||
node = node.children[arguments[i]];
|
||||
}
|
||||
return node;
|
||||
};
|
||||
|
||||
/**
|
||||
* Creates an offset map that references a node tree.
|
||||
*
|
||||
|
@ -270,127 +306,114 @@ ve.dm.example.nodeTreeEqual = function( a, b ) {
|
|||
* @param {ve.dm.DocumentNode} root Document node to reference
|
||||
*/
|
||||
ve.dm.example.getOffsetMap = function( root ) {
|
||||
/**
|
||||
* Looks up a value in a node tree.
|
||||
*
|
||||
* @method
|
||||
* @param {Integer} [...] Index path
|
||||
* @param {ve.Node} Node at given path
|
||||
*/
|
||||
function lookup() {
|
||||
var node = root;
|
||||
for ( var i = 0; i < arguments.length; i++ ) {
|
||||
node = node.children[arguments[i]];
|
||||
}
|
||||
return node;
|
||||
}
|
||||
var lookup = ve.dm.example.lookupNode;
|
||||
return [
|
||||
lookup(), // 0 - document
|
||||
lookup( root ), // 0 - document
|
||||
// <h1>
|
||||
lookup( 0 ), // 1 - heading
|
||||
lookup( root, 0 ), // 1 - heading
|
||||
// a
|
||||
lookup( 0 ), // 2 - heading
|
||||
lookup( root, 0 ), // 2 - heading
|
||||
// b (bold)
|
||||
lookup( 0 ), // 3 - heading
|
||||
lookup( root, 0 ), // 3 - heading
|
||||
// c (italic)
|
||||
lookup( 0 ), // 4 - heading
|
||||
lookup( root, 0 ), // 4 - heading
|
||||
// </h1>
|
||||
lookup(), // 5 - document
|
||||
lookup( root ), // 5 - document
|
||||
// <table>
|
||||
lookup( 1 ), // 6 - table
|
||||
lookup( root, 1 ), // 6 - table
|
||||
// <tr>
|
||||
lookup( 1, 0 ), // 7 - tableRow
|
||||
lookup( root, 1, 0 ), // 7 - tableRow
|
||||
// <td>
|
||||
lookup( 1, 0, 0 ), // 8 - tableCell
|
||||
lookup( root, 1, 0, 0 ), // 8 - tableCell
|
||||
// <p>
|
||||
lookup( 1, 0, 0, 0 ), // 9 - paragraph
|
||||
lookup( root, 1, 0, 0, 0 ), // 9 - paragraph
|
||||
// d
|
||||
lookup( 1, 0, 0, 0 ), // 10 - paragraph
|
||||
lookup( root, 1, 0, 0, 0 ), // 10 - paragraph
|
||||
// </p>
|
||||
lookup( 1, 0, 0 ), // 11 - tableCell
|
||||
lookup( root, 1, 0, 0 ), // 11 - tableCell
|
||||
// <ul>
|
||||
lookup( 1, 0, 0, 1 ), // 12 - list
|
||||
lookup( root, 1, 0, 0, 1 ), // 12 - list
|
||||
// <li>
|
||||
lookup( 1, 0, 0, 1, 0 ), // 13 - listItem
|
||||
lookup( root, 1, 0, 0, 1, 0 ), // 13 - listItem
|
||||
// <p>
|
||||
lookup( 1, 0, 0, 1, 0, 0 ), // 14 - paragraph
|
||||
lookup( root, 1, 0, 0, 1, 0, 0 ), // 14 - paragraph
|
||||
// e
|
||||
lookup( 1, 0, 0, 1, 0, 0 ), // 15 - paragraph
|
||||
lookup( root, 1, 0, 0, 1, 0, 0 ), // 15 - paragraph
|
||||
// </p>
|
||||
lookup( 1, 0, 0, 1, 0 ), // 16 - listItem
|
||||
lookup( root, 1, 0, 0, 1, 0 ), // 16 - listItem
|
||||
// <ul>
|
||||
lookup( 1, 0, 0, 1, 0, 1 ), // 17 - list
|
||||
lookup( root, 1, 0, 0, 1, 0, 1 ), // 17 - list
|
||||
// <li>
|
||||
lookup( 1, 0, 0, 1, 0, 1, 0 ), // 18 - listItem
|
||||
lookup( root, 1, 0, 0, 1, 0, 1, 0 ), // 18 - listItem
|
||||
// <p>
|
||||
lookup( 1, 0, 0, 1, 0, 1, 0, 0 ), // 19 - paragraph
|
||||
lookup( root, 1, 0, 0, 1, 0, 1, 0, 0 ), // 19 - paragraph
|
||||
// f
|
||||
lookup( 1, 0, 0, 1, 0, 1, 0, 0 ), // 20 - paragraph
|
||||
lookup( root, 1, 0, 0, 1, 0, 1, 0, 0 ), // 20 - paragraph
|
||||
// </p>
|
||||
lookup( 1, 0, 0, 1, 0, 1, 0 ), // 21 - listItem
|
||||
lookup( root, 1, 0, 0, 1, 0, 1, 0 ), // 21 - listItem
|
||||
// </li>
|
||||
lookup( 1, 0, 0, 1, 0, 1 ), // 22 - list
|
||||
lookup( root, 1, 0, 0, 1, 0, 1 ), // 22 - list
|
||||
// </ul>
|
||||
lookup( 1, 0, 0, 1, 0 ), // 23 - listItem
|
||||
lookup( root, 1, 0, 0, 1, 0 ), // 23 - listItem
|
||||
// </li>
|
||||
lookup( 1, 0, 0, 1 ), // 24 - list
|
||||
lookup( root, 1, 0, 0, 1 ), // 24 - list
|
||||
// </ul>
|
||||
lookup( 1, 0, 0 ), // 25 - tableCell
|
||||
lookup( root, 1, 0, 0 ), // 25 - tableCell
|
||||
// <ul>
|
||||
lookup( 1, 0, 0, 2 ), // 26 - list
|
||||
lookup( root, 1, 0, 0, 2 ), // 26 - list
|
||||
// <li>
|
||||
lookup( 1, 0, 0, 2, 0 ), // 27 - listItem
|
||||
lookup( root, 1, 0, 0, 2, 0 ), // 27 - listItem
|
||||
// <p>
|
||||
lookup( 1, 0, 0, 2, 0, 0 ), // 28 - paragraph
|
||||
lookup( root, 1, 0, 0, 2, 0, 0 ), // 28 - paragraph
|
||||
// g
|
||||
lookup( 1, 0, 0, 2, 0, 0 ), // 29 - paragraph
|
||||
lookup( root, 1, 0, 0, 2, 0, 0 ), // 29 - paragraph
|
||||
// </p>
|
||||
lookup( 1, 0, 0, 2, 0 ), // 30 - listItem
|
||||
lookup( root, 1, 0, 0, 2, 0 ), // 30 - listItem
|
||||
// </li>
|
||||
lookup( 1, 0, 0, 2 ), // 31 - list
|
||||
lookup( root, 1, 0, 0, 2 ), // 31 - list
|
||||
// </ul>
|
||||
lookup( 1, 0, 0 ), // 32 - tableCell
|
||||
lookup( root, 1, 0, 0 ), // 32 - tableCell
|
||||
// </td>
|
||||
lookup( 1, 0 ), // 33 - tableRow
|
||||
lookup( root, 1, 0 ), // 33 - tableRow
|
||||
// </tr>
|
||||
lookup( 1 ), // 34 - table
|
||||
lookup( root, 1 ), // 34 - table
|
||||
// </table>
|
||||
lookup(), // 35- document
|
||||
lookup( root ), // 35- document
|
||||
// <pre>
|
||||
lookup( 2 ), // 36 - preformatted
|
||||
lookup( root, 2 ), // 36 - preformatted
|
||||
// h
|
||||
lookup( 2 ), // 37 - preformatted
|
||||
lookup( root, 2 ), // 37 - preformatted
|
||||
// <img>
|
||||
lookup( 2 ), // 38 - preformatted
|
||||
lookup( root, 2 ), // 38 - preformatted
|
||||
// </img>
|
||||
lookup( 2 ), // 39 - preformatted
|
||||
lookup( root, 2 ), // 39 - preformatted
|
||||
// i
|
||||
lookup( 2 ), // 40 - preformatted
|
||||
lookup( root, 2 ), // 40 - preformatted
|
||||
// </pre>
|
||||
lookup(), // 41 - document
|
||||
lookup( root ), // 41 - document
|
||||
// <dl>
|
||||
lookup( 3 ), // 42 - definitionList
|
||||
lookup( root, 3 ), // 42 - definitionList
|
||||
// <dt>
|
||||
lookup( 3, 0 ), // 43 - definitionListItem
|
||||
lookup( root, 3, 0 ), // 43 - definitionListItem
|
||||
// <p>
|
||||
lookup( 3, 0, 0 ), // 44 - paragraph
|
||||
lookup( root, 3, 0, 0 ), // 44 - paragraph
|
||||
// f
|
||||
lookup( 3, 0, 0 ), // 45 - paragraph
|
||||
lookup( root, 3, 0, 0 ), // 45 - paragraph
|
||||
// </p>
|
||||
lookup( 3, 0 ), // 46 - definitionListItem
|
||||
lookup( root, 3, 0 ), // 46 - definitionListItem
|
||||
// </dt>
|
||||
lookup( 3 ), // 47 - definitionList
|
||||
lookup( root, 3 ), // 47 - definitionList
|
||||
// <dd>
|
||||
lookup( 3, 1 ), // 48 - definitionListItem
|
||||
lookup( root, 3, 1 ), // 48 - definitionListItem
|
||||
// <p>
|
||||
lookup( 3, 1, 0 ), // 49 - paragraph
|
||||
lookup( root, 3, 1, 0 ), // 49 - paragraph
|
||||
// f
|
||||
lookup( 3, 1, 0 ), // 50 - paragraph
|
||||
lookup( root, 3, 1, 0 ), // 50 - paragraph
|
||||
// </p>
|
||||
lookup( 3, 1 ), // 51 - definitionListItem
|
||||
lookup( root, 3, 1 ), // 51 - definitionListItem
|
||||
// </dd>
|
||||
lookup( 3 ), // 52 - definitionList
|
||||
lookup( root, 3 ), // 52 - definitionList
|
||||
// </dl>
|
||||
lookup() // 53 - document
|
||||
lookup( root ) // 53 - document
|
||||
];
|
||||
};
|
||||
|
|
Loading…
Reference in a new issue