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

86.84% Statements 33/38
77.27% Branches 17/22
60% Functions 3/5
86.84% Lines 33/38
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                                                                                    12×       12×                               39×     39×   39× 117× 117× 117× 117× 82× 82×     117× 35×       39× 35×       39×       35×                          
/*!
 * VisualEditor DataModel ClassAttribute class.
 *
 * @copyright 2011-2019 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;
	}
};