All files / src/dm ve.dm.MetaList.js

100% Statements 27/27
87.5% Branches 7/8
100% Functions 8/8
100% Lines 25/25

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109                              1x   2684x   2684x     2684x       2684x               1x                                         1x 20269x 20269x 688x 357x 357x                 1x 1585x 73x 73x 73x 73x         1x 3x 3x                       1x 36x                     1x 8x    
/*!
 * VisualEditor DataModel MetaList class.
 *
 * @copyright See AUTHORS.txt
 */
 
/**
 * DataModel meta list.
 *
 * @class
 * @mixes OO.EventEmitter
 *
 * @constructor
 * @param {ve.dm.Document} doc Document model
 */
ve.dm.MetaList = function VeDmMetaList( doc ) {
	// Mixin constructors
	OO.EventEmitter.call( this );
 
	this.doc = doc;
 
	// Sorted array of attached ve.dm.MetaItem nodes in document order
	this.items = [];
 
	// The meta list is constructed before the model tree is built, so
	// we don't need to initialise this item list, just listen to changes
	this.doc.connect( this, {
		nodeAttached: 'onNodeAttached',
		nodeDetached: 'onNodeDetached'
	} );
};
 
/* Inheritance */
 
OO.mixinClass( ve.dm.MetaList, OO.EventEmitter );
 
/* Events */
 
/**
 * @event ve.dm.MetaList#insert
 * @param {ve.dm.MetaItem} item Item that was inserted
 */
 
/**
 * @event ve.dm.MetaList#remove
 * @param {ve.dm.MetaItem} item Item that was removed
 */
 
/* Methods */
 
/**
 * If a ve.dm.MetaItem was attached, insert it into items in document order
 *
 * @param {ve.dm.Node} node The node that was attached
 */
ve.dm.MetaList.prototype.onNodeAttached = function ( node ) {
	const offsetPath = node.getOffsetPath();
	if ( node instanceof ve.dm.MetaItem ) {
		const i = OO.binarySearch( this.items, ( other ) => ve.compareTuples( offsetPath, other.getOffsetPath() ), true );
		this.items.splice( i, 0, node );
		this.emit( 'insert', node );
	}
};
 
/**
 * If a ve.dm.MetaItem was detached, remove it from items
 *
 * @param {ve.dm.Node} node The node that was detached
 */
ve.dm.MetaList.prototype.onNodeDetached = function ( node ) {
	if ( node instanceof ve.dm.MetaItem ) {
		const i = this.items.indexOf( node );
		Eif ( i !== -1 ) {
			this.items.splice( i, 1 );
			this.emit( 'remove', node );
		}
	}
};
 
ve.dm.MetaList.prototype.indexOf = function ( item, group ) {
	const items = group ? this.getItemsInGroup( group ) : this.items;
	return items.indexOf( item );
};
 
/**
 * Get all items in a group.
 *
 * This function returns a shallow copy, so the array isn't returned by reference but the items
 * themselves are.
 *
 * @param {string} group
 * @return {ve.dm.MetaItem[]} Array of items in the group (shallow copy)
 */
ve.dm.MetaList.prototype.getItemsInGroup = function ( group ) {
	return this.items.filter( ( item ) => item.getGroup() === group );
};
 
/**
 * Get all items in the list.
 *
 * This function returns a shallow copy, so the array isn't returned by reference but the items
 * themselves are.
 *
 * @return {ve.dm.MetaItem[]} Array of items in the list
 */
ve.dm.MetaList.prototype.getItems = function () {
	return this.items.slice();
};