UNPKG

devextreme

Version:

HTML5 JavaScript Component Suite for Responsive Web Development

190 lines (152 loc) 5.57 kB
"use strict"; var errors = require("../errors"), Class = require("../class"), objectUtils = require("./object"), typeUtils = require("./type"), each = require("./iterator").each, variableWrapper = require("./variable_wrapper"), unwrapVariable = variableWrapper.unwrap, isWrapped = variableWrapper.isWrapped, assign = variableWrapper.assign; var bracketsToDots = function bracketsToDots(expr) { return expr.replace(/\[/g, ".").replace(/\]/g, ""); }; var readPropValue = function readPropValue(obj, propName, options) { options = options || {}; if (propName === "this") { return unwrap(obj, options); } return unwrap(obj[propName], options); }; var assignPropValue = function assignPropValue(obj, propName, value, options) { if (propName === "this") { throw new errors.Error("E4016"); } var propValue = obj[propName]; if (options.unwrapObservables && isWrapped(propValue)) { assign(propValue, value); } else { obj[propName] = value; } }; var prepareOptions = function prepareOptions(options) { options = options || {}; options.unwrapObservables = options.unwrapObservables !== undefined ? options.unwrapObservables : true; return options; }; var unwrap = function unwrap(value, options) { return options.unwrapObservables ? unwrapVariable(value) : value; }; var compileGetter = function compileGetter(expr) { if (arguments.length > 1) { expr = [].slice.call(arguments); } if (!expr || expr === "this") { return function (obj) { return obj; }; } if (typeof expr === "string") { expr = bracketsToDots(expr); var path = expr.split("."); return function (obj, options) { options = prepareOptions(options); var functionAsIs = options.functionsAsIs, current = unwrap(obj, options); for (var i = 0; i < path.length; i++) { if (!current) break; var next = unwrap(current[path[i]], options); if (!functionAsIs && typeUtils.isFunction(next)) { next = next.call(current); } current = next; } return current; }; } if (Array.isArray(expr)) { return combineGetters(expr); } if (typeUtils.isFunction(expr)) { return expr; } }; var combineGetters = function combineGetters(getters) { var compiledGetters = {}; for (var i = 0, l = getters.length; i < l; i++) { var getter = getters[i]; compiledGetters[getter] = compileGetter(getter); } return function (obj, options) { var result; each(compiledGetters, function (name) { var value = this(obj, options), current, path, last, i; if (value === undefined) { return; } current = result || (result = {}); path = name.split("."); last = path.length - 1; for (i = 0; i < last; i++) { current = current[path[i]] = {}; } current[path[i]] = value; }); return result; }; }; var ensurePropValueDefined = function ensurePropValueDefined(obj, propName, value, options) { if (typeUtils.isDefined(value)) { return value; } var newValue = {}; assignPropValue(obj, propName, newValue, options); return newValue; }; var compileSetter = function compileSetter(expr) { expr = bracketsToDots(expr || "this").split("."); var lastLevelIndex = expr.length - 1; return function (obj, value, options) { options = prepareOptions(options); var currentValue = unwrap(obj, options); expr.forEach(function (propertyName, levelIndex) { var propertyValue = readPropValue(currentValue, propertyName, options), isPropertyFunc = !options.functionsAsIs && typeUtils.isFunction(propertyValue) && !isWrapped(propertyValue); if (levelIndex === lastLevelIndex) { if (options.merge && typeUtils.isPlainObject(value) && (!typeUtils.isDefined(propertyValue) || typeUtils.isPlainObject(propertyValue))) { propertyValue = ensurePropValueDefined(currentValue, propertyName, propertyValue, options); objectUtils.deepExtendArraySafe(propertyValue, value, false, true); } else if (isPropertyFunc) { currentValue[propertyName](value); } else { assignPropValue(currentValue, propertyName, value, options); } } else { propertyValue = ensurePropValueDefined(currentValue, propertyName, propertyValue, options); if (isPropertyFunc) { propertyValue = propertyValue.call(currentValue); } currentValue = propertyValue; } }); }; }; var toComparable = function toComparable(value, caseSensitive) { if (value instanceof Date) { return value.getTime(); } if (value && value instanceof Class && value.valueOf) { return value.valueOf(); } if (!caseSensitive && typeof value === "string") { return value.toLowerCase(); } return value; }; exports.compileGetter = compileGetter; exports.compileSetter = compileSetter; exports.toComparable = toComparable;