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

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

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 110 111 112 113                              1x   2596x   2596x     2596x       2596x               1x                                         1x 20014x 20014x 350x 686x   350x 350x                 1x 1586x 72x 72x 72x 72x         1x 3x 3x                       1x 4x 36x                       1x 8x    
/*!
 * VisualEditor DataModel MetaList class.
 *
 * @copyright See AUTHORS.txt
 */
 
/**
 * DataModel meta list.
 *
 * @class
 * @mixins 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 insert
 * @param {ve.dm.MetaItem} item Item that was inserted
 */
 
/**
 * @event 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 ) {
	var offsetPath = node.getOffsetPath();
	if ( node instanceof ve.dm.MetaItem ) {
		var i = OO.binarySearch( this.items, function searchFunc( other ) {
			return 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 ) {
		var 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 ) {
	var 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( function ( item ) {
		return 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();
};