We use cookies to make our website more effective. By using our website you agree to our privacy policy.

Source: maps.js

/**
 * maps.js is part of Aloha Editor project http://www.alohaeditor.org
 *
 * Aloha Editor ● JavaScript Content Editing Library
 * Copyright (c) 2010-2015 Gentics Software GmbH, Vienna, Austria.
 * Contributors http://www.alohaeditor.org/docs/contributing.html
 * @namespace maps
 */
define(['arrays', 'assert'], function (Arrays, Assert) {
	'use strict';

	/**
	 * Checks whether the given object has no own or inherited properties.
	 *
	 * @param {!Object} obj
	 *        Object to check.
	 * @return {boolean}
	 *         True if the object is empty. eg: isEmpty({}) == true
	 * @memberOf maps
	 */
	function isEmpty(obj) {
		var name;
		for (name in obj) {
			if (obj.hasOwnProperty(name)) {
				return false;
			}
		}
		return true;
	}

	/**
	 * Fills the given map with the given keys mapped to the given value.
	 *
	 * @param {Object} map
	 *        The given map will have one entry added for each given key.
	 * @param {Array.<string>} keys
	 *        An array of string keys. JavaScript maps can only contain string
	 *        keys, so these must be strings or they will be cast to string.
	 * @param {string} value A single value that each given key will map to.
	 * @return {Object}
	 *         The given map.
	 * @memberOf maps
	 */
	function fillKeys(map, keys, value) {
		var i = keys.length;
		while (i--) {
			map[keys[i]] = value;
		}
		return map;
	}

	/**
	 * For each mapping, calls `cb(value, key, m)`.
	 *
	 * Like ECMAScript edition 5 Array.forEach but for Maps.
	 *
	 * Contrary to "for (key in m)" iterates only over the "hasOwnProperty"
	 * properties of the m, which is usually what you want.
	 * @memberOf maps
	 */
	function forEach(m, cb) {
		var key;
		for (key in m) {
			if (m.hasOwnProperty(key)) {
				cb(m[key], key, m);
			}
		}
	}

	/**
	 * Selects the values for the given keys in the given map.
	 *
	 * @param {!Object} m
	 * @param {!Array} ks
	 * @param {*} _default used in place of non-existing properties
	 * @return {!Array}
	 * @memberOf maps
	 */
	function selectVals(m, ks, _default) {
		return ks.map(function (k) {
			return m.hasOwnProperty(k) ? m[k] : _default;
		});
	}

	/**
	 * Same as Array.filter except for maps.
	 *
	 * The given predicate is applied to each entry in the given map,
	 * and only if the predicate returns true, will the entry appear in
	 * the result.
	 * @memberOf maps
	 */
	function filter(m, pred) {
		var result = {};
		forEach(m, function (val, key) {
			if (pred(val, key, m)) {
				result[key] = val;
			}
		});
		return result;
	}

	/**
	 * Returns an array of the map's keys.
	 *
	 * @param {!Object} m
	 * @return {!Array} The set of keys in `m`.
	 * @memberOf maps
	 */
	function keys(m) {
		var ks = [];
		forEach(m, function (value, key) {
			ks.push(key);
		});
		return ks;
	}

	/**
	 * Returns an array of the map's values.
	 *
	 * @param {!Object} m
	 * @return {!Array} The values in `m`.
	 * @memberOf maps
	 */
	function vals(m) {
		return selectVals(m, keys(m));
	}
	/**
	 * This function is missing documentation.
	 * @TODO Complete documentation.
	 *
	 * @memberOf maps
	 */
	function extend(dest) {
		var i;
		for (i = 1; i < arguments.length; i++) {
			var src = arguments[i];
			if (src) {
				forEach(src, function (value, key) {
					dest[key] = value;
				});
			}
		}
		return dest;
	}

	/**
	 * Merges one or more maps.
	 * Merging happens from left to right, which is useful for example
	 * when merging a number of given options with default options:
	 * var effectiveOptions = Maps.merge(defaults, options);
	 *
	 * @param {...Object}
	 *        A variable number of map objects.
	 * @return {Object}
	 *         A merge of all given maps in a single object.
	 * @memberOf maps
	 */
	function merge() {
		return extend.apply(null, [{}].concat(Arrays.coerce(arguments)));
	}

	/**
	 * Clones a map.
	 *
	 * @param map {!Object}
	 * @return {!Object}
	 * @memberOf maps
	 */
	function clone(map) {
		Assert.assertNotNou(map);
		return extend({}, map);
	}

	/**
	 * Sets a value on a clone of the given map and returns the clone.
	 *
	 * @param map {!Object}
	 * @param key {string}
	 * @param value {*}
	 * @return {!Object}
	 * @memberOf maps
	 */
	function cloneSet(map, key, value) {
		map = clone(map);
		map[key] = value;
		return map;
	}

	/**
	 * Deletes a key from a clone of the given map and returns the clone.
	 *
	 * @param map {!Object}
	 * @param key {string}
	 * @return {!Object}
	 * @memberOf maps
	 */
	function cloneDelete(map, key) {
		map = clone(map);
		delete map[key];
		return map;
	}

	/**
	 * Whether the given object is a map that can be operated on by
	 * other functions in this module.
	 *
	 * We exclude things like new String("..."), new Number(...),
	 * document.createElement(...), but include new MyType("...").
	 * @memberOf maps
	 */
	function isMap(obj) {
		return !!(obj
		          // On IE7 DOM Nodes are [object Object] but don't have a constructor
		          && obj.constructor
		          && Object.prototype.toString.call(obj) === '[object Object]');
	}

	/**
	 * Creates a map without inheriting from Object.
	 *
	 * Use this instead of an object literal to avoid having unwanted, inherited
	 * properties on the map.
	 *
	 * A map constructed like this allows for the
	 * ```for (var key in map) { }```
	 * pattern to be used without a hasOwnProperty check.
	 *
	 * @return {!Object}
	 * @memberOf maps
	 */
	function create() {
		return Object.create(null);
	}

	/**
	 * Converts a list of tuples into a hash map key-value pair.
	 *
	 * @param  {Array.<Array.<string, *>>} tuples
	 * @return {Object.<string, *>}
	 * @memberOf maps
	 */
	function mapTuples(tuples) {
		var map = {};
		tuples.forEach(function (tuple) {
			map[tuple[0]] = tuple[1];
		});
		return map;
	}

	return {
		isEmpty     : isEmpty,
		fillKeys    : fillKeys,
		keys        : keys,
		vals        : vals,
		selectVals  : selectVals,
		filter      : filter,
		forEach     : forEach,
		extend      : extend,
		merge       : merge,
		isMap       : isMap,
		clone       : clone,
		cloneSet    : cloneSet,
		cloneDelete : cloneDelete,
		create      : create,
		mapTuples   : mapTuples
	};
});
comments powered by Disqus