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

87.18% Statements 34/39
77.27% Branches 17/22
60% Functions 3/5
87.18% Lines 34/39

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                                1x       1x                       1x   1x                       1x   12x 12x   12x 4x     8x 8x 8x 8x           8x 8x                 1x   39x   39x   39x 117x 117x 117x 117x 82x 82x     117x 35x       39x 35x       39x       35x 4x       4x           1x          
/*!
 * VisualEditor DataModel ClassAttribute class.
 *
 * @copyright 2011-2020 VisualEditor Team and others; see http://ve.mit-license.org
 */
 
/**
 * DataModel class-attribute node.
 *
 * Used for nodes which use classes to store attributes.
 *
 * @class
 * @abstract
 *
 * @constructor
 */
ve.dm.ClassAttributeNode = function VeDmClassAttributeNode() {};
 
/* Inheritance */
 
OO.initClass( ve.dm.ClassAttributeNode );
 
/* Static methods */
 
/**
 * Mapping from class names to attributes
 *
 * e.g. { alignLeft: { align: 'left' } } sets the align attribute to 'left'
 * if the element has the class 'alignLeft'
 *
 * @type {Object}
 */
ve.dm.ClassAttributeNode.static.classAttributes = {};
 
ve.dm.ClassAttributeNode.static.preserveHtmlAttributes = function ( attribute ) {
	return attribute !== 'class';
};
 
/**
 * Set attributes from a class attribute
 *
 * Unrecognized classes are also preserved.
 *
 * @param {Object} attributes Attributes object to modify
 * @param {string|null} classAttr Class attribute from an element
 */
ve.dm.ClassAttributeNode.static.setClassAttributes = function ( attributes, classAttr ) {
	var className, i, l,
		unrecognizedClasses = [],
		classNames = classAttr ? classAttr.trim().split( /\s+/ ) : [];
 
	if ( !classNames.length ) {
		return;
	}
 
	for ( i = 0, l = classNames.length; i < l; i++ ) {
		className = classNames[ i ];
		Eif ( Object.prototype.hasOwnProperty.call( this.classAttributes, className ) ) {
			attributes = ve.extendObject( attributes, this.classAttributes[ className ] );
		} else {
			unrecognizedClasses.push( className );
		}
	}
 
	attributes.originalClasses = classAttr;
	attributes.unrecognizedClasses = unrecognizedClasses;
};
 
/**
 * Get class attribute from element attributes
 *
 * @param {Object|undefined} attributes Element attributes
 * @return {string|null} Class name, or null if no classes to set
 */
ve.dm.ClassAttributeNode.static.getClassAttrFromAttributes = function ( attributes ) {
	var className, key, classAttributeSet, hasClass,
		classNames = [];
 
	attributes = attributes || {};
 
	for ( className in this.classAttributes ) {
		classAttributeSet = this.classAttributes[ className ];
		hasClass = true;
		for ( key in classAttributeSet ) {
			if ( attributes[ key ] !== classAttributeSet[ key ] ) {
				hasClass = false;
				break;
			}
		}
		if ( hasClass ) {
			classNames.push( className );
		}
	}
 
	if ( attributes.unrecognizedClasses ) {
		classNames = OO.simpleArrayUnion( classNames, attributes.unrecognizedClasses );
	}
 
	// If no meaningful change in classes, preserve order
	if (
		attributes.originalClasses &&
		ve.compareClassLists( attributes.originalClasses, classNames )
	) {
		return attributes.originalClasses;
	} else Iif ( classNames.length > 0 ) {
		return classNames.join( ' ' );
	}
 
	return null;
};
 
/**
 * @inheritdoc ve.dm.Node
 */
ve.dm.ClassAttributeNode.static.sanitize = function ( dataElement ) {
	if ( dataElement.attributes ) {
		delete dataElement.attributes.unrecognizedClasses;
	}
};