Source: kss_section.js

/**
 * The `kss/lib/kss_section` module is normally accessed via the
 * [`KssSection()`]{@link module:kss.KssSection} constructor of the `kss`
 * module:
 * ```
 * var kss = require('kss');
 * var section = new kss.KssSection(data);
 * ```
 * @private
 * @module kss/lib/kss_section
 */

var KssSection;

/**
 * An instance of this class is returned on calling `KssStyleguide.section`.
 * Exposes convenience methods for interpreting data.
 *
 * @constructor
 * @alias module:kss.KssSection
 * @param {Object} data A part of the data object passed on by `KssStyleguide`.
 */
KssSection = function(data) {
	if (!(this instanceof KssSection)) {
		return new KssSection();
	}
	this.data = data || {};
	this.styleguide = data.styleguide || null;
	this.init();
};

/**
 * Initializes the object and data passed to the constructor. Called
 * automatically from the KssSection() constructor; should not be called
 * directly.
 * @private
 */
KssSection.prototype.init = function () {
	var self = this;

	if (this.data.modifiers) {
		this.data.modifiers = this.data.modifiers.map(function(modifier) {
			modifier.data.section = self;
			return modifier;
		});
	}
	else {
		this.data.modifiers = [];
	}

	if (this.data.parameters) {
		this.data.parameters = this.data.parameters.map(function(parameter) {
			parameter.data.section = self;
			return parameter;
		});
	}
	else {
		this.data.parameters = [];
	}
};

/**
 * Return `KssSection` as a JSON object.
 *
 * @param {Array} customProperties A list of custom properties to include in the JSON.
 * @returns {Object} A JSON object representation of the KssSection.
 */
KssSection.prototype.JSON = function (customProperties) {
	var returnObject;

	customProperties = customProperties || [];

	returnObject = {
		header:       this.header(),
		description:  this.description(),
		deprecated:   this.deprecated(),
		experimental: this.experimental(),
		reference:    this.reference(),
		depth:        this.depth(),
		weight:       this.weight(),
		referenceURI: this.referenceURI(),
		markup:       this.markup
	};

	returnObject.modifiers = this.data.modifiers.map(function(modifier) {
		return {
			name: modifier.name(),
			description: modifier.description(),
			className: modifier.className()
		};
	});
	returnObject.parameters = this.data.parameters.map(function(modifier) {
		return {
			name: modifier.name(),
			description: modifier.description()
		};
	});

	// Add custom properties to the JSON object.
	for (var i = 0; i < customProperties.length; i++) {
		if (this.data[customProperties[i]]) {
			returnObject[customProperties[i]] = this.data[customProperties[i]];
		}
	}

	return returnObject;
};

/**
 * Returns the header of the section.
 * @returns {string} The header of the section.
 */
KssSection.prototype.header = function() {
	return this.data.header;
};

/**
 * Returns the description of the section.
 * @returns {string} The description of the section.
 */
KssSection.prototype.description = function() {
	return this.data.description;
};

/**
 * Returns whether the section is deprecated or not.
 * @returns {Boolean} Whether the section is deprecated or not.
 */
KssSection.prototype.deprecated = function() {
	return this.data.deprecated;
};

/**
 * Returns whether the section is experimental or not.
 * @returns {Boolean} Whether the section is experimental or not.
 */
KssSection.prototype.experimental = function() {
	return this.data.experimental;
};

/**
 * Returns the reference of the section.
 * @returns {string} The reference of the section.
 */
KssSection.prototype.reference = function() {
	return this.data.reference;
};

/**
 * Returns the depth of the section.
 * @returns {string} The depth of the section.
 */
KssSection.prototype.depth = function() {
	return this.data.depth;
};

/**
 * Returns the weight of the section.
 * @returns {string} The weight of the section.
 */
KssSection.prototype.weight = function() {
	return this.data.weight ? this.data.weight : 0;
};

/**
 * Encodes the given reference as a valid URI fragment.
 * @param {string} reference A style guide section reference.
 * @returns {string} The reference encoded as a URI.
 */
KssSection.prototype.encodeReferenceURI = function(reference) {
	return encodeURI(
		reference
			.replace(/\s+\-\s+/g, '-')
			.replace(' ', '-')
			.toLowerCase()
	);
};

/**
 * Returns the reference of the section, encoded as a valid URI fragment.
 * @returns {string} The description of the section.
 */
KssSection.prototype.referenceURI = function() {
	return this.data.referenceURI;
};

/**
 * Returns the markup of the section.
 * @returns {false|string} The markup of the section, or `false` if none.
 */
KssSection.prototype.markup = function() {
	return this.data.markup || false;
};

/**
 * Returns the requested modifier of the section.
 * @param {string|int} query The name (string) or 0-based index (int) of the requested modifier.
 * @returns {false|Array} An Array of KssModifier objects, or `false` if none.
 */
KssSection.prototype.modifiers = function(query) {
	var number, i, l;

	if (typeof query === 'string') {
		number = parseFloat(query, 10);

		// If can be converted to a number, convert and search
		// for the query by index (see below).
		if (number.toString() === query) {
			query = number;
		} else {
			// Otherwise, search for the modifier by name:
			l = this.data.modifiers.length;
			for (i = 0; i < l; i += 1) {
				if (this.data.modifiers[i].data.name === query) {
					return this.data.modifiers[i];
				}
			}
			return false;
		}
	}

	if (typeof query === 'number') {
		return this.data.modifiers.length > query ? this.data.modifiers[query] : false;
	}

	return this.data.modifiers;
};

/**
 * Returns the first modifier of the section.
 * @returns {false|string} The first modifier of the section, or `false` if none.
 */
KssSection.prototype.firstModifier = function() {
	if (this.data.modifiers.length) {
		return this.data.modifiers[0];
	} else {
		return false;
	}
};

/**
 * Returns the parameters if the section is a CSS preprocessor function/mixin.
 * @returns {Array} The parameters of the section.
 */
KssSection.prototype.parameters = function() {
	return this.data.parameters;
};

module.exports = KssSection;