"use strict";
/**
* @namespace KozUtils
* @desc Some useful function to make working with parameters more reliable and less painful in JavaScript.
* @author Kozalo <kozalo@yandex.ru>
* @copyright Kozalo.Ru, 2016
*/
let KozUtils = {
/**
* Copies given options into the defaultOptions object and returns the result.
* @memberof KozUtils
* @param {Object} options Object with user settings.
* @param {Object} defaultOptions Specify a list of default parameters here.
* @returns {Object} The members of the options object overrides ones of the defaultOptions to get the result.
*/
initOptions: function(options, defaultOptions) {
if (options === undefined)
return defaultOptions;
for (var optionName in options)
defaultOptions[optionName] = options[optionName];
return defaultOptions;
},
/**
* Checks if all required parameters have been passed into the function. Throws an exception if any of them are missing.
* @memberof KozUtils
* @param {object[]|object} parameters Either an array of variables or a variable to check.
* @param {string=|function=} funcName The name of the function. Used to make the description of an exception more detailed. If you pass a function, extracts its name automatically.
* @param {Array<string>=|string=} paramNames Either an array of strings or a string. Pass it in the same order as _parameters_! Used to make the description of the exception more detailed as well.
* @throws KozExceptions.missingArgument or a string exception.
* @example
* function foo(bar) {
* // KozUtils.checkMissingParameters(bar);
* // KozUtils.checkMissingParameters([bar], "foo");
* // KozUtils.checkMissingParameters([bar], "foo", ['bar']);
* KozUtils.checkMissingParameters(bar, "foo", "bar");
* document.writeln(bar);
* }
*/
checkMissingParameters: function(parameters, funcName, paramNames) {
if (! (parameters instanceof Array) )
parameters = [parameters];
if (! (paramNames instanceof Array) )
paramNames = [paramNames];
if (typeof(funcName) === "function")
funcName = funcName.name;
parameters.forEach(function (opt, index) {
if (opt === undefined) {
let errorObj = {
function: funcName,
parameter: {
index: index + 1,
name: paramNames[index]
}
};
if (KozExceptions != undefined)
throw new KozExceptions.missingArgument(errorObj.parameter.name, JSON.stringify(errorObj))
else
throw "Missing required parameter: " + JSON.stringify(errorObj);
}
});
},
/**
* Not only checks if all required parameters have been passed into the function, but also checks their types. Throws exceptions if any of them are missing or invalid.
* @memberof KozUtils
* @param {object[]|object} parameters Either an array of variables or a variable to check.
* @param {string[]|string} types String representations of expected types for typeof-comparison.
* @param {string=|function=} funcName The name of the function. Used to make the description of an exception more detailed. If you pass a function, extracts its name automatically.
* @param {Array<string>=|string=} paramNames Either an array of strings or a string. Pass it in the same order as _parameters_! Used to make the description of the exception more detailed as well.
* @throws KozExceptions.missingArgument, KozExceptions.invalidArgument or their equivalents.
* @example
* function foo(bar) {
* // KozUtils.checkParameters(bar, "string");
* // KozUtils.checkParameters([bar], "number", "foo");
* // KozUtils.checkParameters([bar], "string", "foo", ['bar']);
* KozUtils.checkParameters(bar, "number", "foo", "bar");
* document.writeln(bar);
* }
*/
checkParameters: function(parameters, types, funcName, paramNames) {
KozUtils.checkMissingParameters([parameters, types], funcName, [paramNames, types]);
if (! (parameters instanceof Array) )
parameters = [parameters];
if (! (types instanceof Array) )
types = [types];
if (typeof(funcName) === "function")
funcName = funcName.name;
if (paramNames == undefined)
paramNames = new Array(parameters.length);
else if (! (paramNames instanceof Array) )
paramNames = [paramNames];
for (let i in parameters) {
if (typeof(parameters[i]) !== types[i])
{
let invalidArgumentMessage;
if (paramNames[i] != undefined && funcName != undefined)
invalidArgumentMessage = funcName + ': type of "' + paramNames[i] + '" must be: "' + types[i] + '"!';
else if (paramNames[i] != undefined && funcName == undefined)
invalidArgumentMessage = 'Type of "' + paramNames[i] + '" must be: "' + types[i] + '"!';
else if (paramNames[i] == undefined && funcName != undefined)
invalidArgumentMessage = funcName + ': ' + types[i] + ' is expecting!';
else
invalidArgumentMessage = types[i][0].toUpperCase() + types[i].substr(1) + ' is expecting!';
if (typeof(KozExceptions) != undefined)
throw new KozExceptions.invalidArgument(paramNames[i], invalidArgumentMessage);
else
throw invalidArgumentMessage;
}
}
},
/**
* Gets the actual current size of an HTMLElement.
* @memberof KozUtils
* @param {HTMLElement} element Any HTMLElement.
* @throws KozExceptions.invalidArgument or a string exception.
* @returns {Object} The object has 2 fields: 'width' and 'height'.
*/
getActualSize: function(element) {
KozUtils.checkParameters(element, "HTMLElement", "getActualSize", "element");
let rect = element.getBoundingClientRect();
let width = rect.width;
let height = rect.height;
let styles = window.getComputedStyle(element);
let marginTop = parseFloat(styles.marginTop);
let marginBottom = parseFloat(styles.marginBottom);
let paddingTop = parseFloat(styles.paddingTop);
let paddingBottom = parseFloat(styles.paddingBottom);
let marginLeft = parseFloat(styles.marginLeft);
let marginRight = parseFloat(styles.marginRight);
let paddingLeft = parseFloat(styles.paddingLeft);
let paddingRight = parseFloat(styles.paddingRight);
let actualWidth = (width - marginLeft - marginRight - paddingLeft - paddingRight) + "px";
let actualHeight = (height - marginTop - marginBottom - paddingTop - paddingBottom) + "px";
return {
width: actualWidth,
height: actualHeight
};
}
};