All files / src/ce/nodes ve.ce.TableRowNode.js

78.94% Statements 30/38
100% Branches 8/8
85.71% Functions 6/7
78.94% Lines 30/38

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 114 115 116 117 118 119 120 121 122 123 124 125 126                              1x   371x   371x         1x       1x   1x             1x   371x   371x           1x   535x     535x 535x     465x               1x 836x 836x   836x 836x 34x 22x     22x       22x   34x   802x             1x 1337x 80x                 1x                                               1x  
/*!
 * VisualEditor ContentEditable TableRowNode class.
 *
 * @copyright See AUTHORS.txt
 */
 
/**
 * ContentEditable table row node.
 *
 * @class
 * @extends ve.ce.BranchNode
 * @constructor
 * @param {ve.dm.TableRowNode} model Model to observe
 * @param {Object} [config] Configuration options
 */
ve.ce.TableRowNode = function VeCeTableRowNode() {
	// Parent constructor
	ve.ce.TableRowNode.super.apply( this, arguments );
 
	this.$missingCell = null;
};
 
/* Inheritance */
 
OO.inheritClass( ve.ce.TableRowNode, ve.ce.BranchNode );
 
/* Static Properties */
 
ve.ce.TableRowNode.static.name = 'tableRow';
 
ve.ce.TableRowNode.static.tagName = 'tr';
 
/* Methods */
 
/**
 * @inheritdoc
 */
ve.ce.TableRowNode.prototype.onSetup = function () {
	// Parent method
	ve.ce.TableRowNode.super.prototype.onSetup.apply( this, arguments );
 
	this.setupMissingCell();
};
 
/**
 * @inheritdoc
 */
ve.ce.TableRowNode.prototype.onSplice = function () {
	// Parent method
	ve.ce.TableRowNode.super.prototype.onSplice.apply( this, arguments );
 
	// Defer call until after other changes in this cycle have been made
	setTimeout( () => {
		if ( this.getRoot() ) {
			// It's possible for this to have been removed from the model in the last tick
			// This mostly seems to happen during cell merges
			this.setupMissingCell();
		}
	} );
};
 
/**
 * Setup a slug for a missing cell, if this row contains fewer cells than the table
 */
ve.ce.TableRowNode.prototype.setupMissingCell = function () {
	const matrix = this.findParent( ve.ce.TableNode ).getModel().getMatrix(),
		maxColCount = matrix.getMaxColCount();
 
	const row = matrix.getRowNodes().indexOf( this.model );
	if ( maxColCount > matrix.getColCount( row ) ) {
		if ( !this.$missingCell ) {
			this.$missingCell = $( '<td>' )
				.prop( 'contentEditable', 'false' )
				.addClass( 've-ce-branchNode-slug ve-ce-branchNode-blockSlug ve-ce-tableNode-missingCell' );
			const slugButton = new ve.ui.NoFocusButtonWidget( {
				icon: 'add',
				framed: false
			} ).on( 'click', this.onMissingCellClick.bind( this ) );
			this.$missingCell.append( slugButton.$element );
		}
		this.$element.append( this.$missingCell );
	} else {
		this.removeSlugs();
	}
};
 
/**
 * @inheritdoc
 */
ve.ce.TableRowNode.prototype.removeSlugs = function () {
	if ( this.$missingCell ) {
		this.$missingCell.detach();
	}
};
 
/**
 * Handle click events on the missing cell slug
 *
 * @param {jQuery.Event} e Click event
 */
ve.ce.TableRowNode.prototype.onMissingCellClick = function () {
	const surfaceModel = this.getRoot().getSurface().getModel(),
		documentModel = surfaceModel.getDocument(),
		tableModel = this.findParent( ve.ce.TableNode ).getModel(),
		matrix = tableModel.getMatrix();
 
	// Add a cell onto the end of the row
	surfaceModel.change(
		ve.dm.TransactionBuilder.static.newFromInsertion(
			documentModel, this.getModel().getRange().end,
			ve.dm.TableCellNode.static.createData()
		)
	);
 
	// Select the newly-inserted cell
	const row = matrix.getRowNodes().indexOf( this.model );
	const col = matrix.getColCount( row ) - 1;
	surfaceModel.setSelection(
		new ve.dm.TableSelection( tableModel.getOuterRange(), col, row )
	);
};
 
/* Registration */
 
ve.ce.nodeFactory.register( ve.ce.TableRowNode );