data.js 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173
  1. /**
  2. * DevExtreme (core/utils/data.js)
  3. * Version: 19.1.16
  4. * Build date: Tue Oct 18 2022
  5. *
  6. * Copyright (c) 2012 - 2022 Developer Express Inc. ALL RIGHTS RESERVED
  7. * Read about DevExtreme licensing here: https://js.devexpress.com/Licensing/
  8. */
  9. "use strict";
  10. var errors = require("../errors");
  11. var Class = require("../class");
  12. var objectUtils = require("./object");
  13. var typeUtils = require("./type");
  14. var each = require("./iterator").each;
  15. var variableWrapper = require("./variable_wrapper");
  16. var unwrapVariable = variableWrapper.unwrap;
  17. var isWrapped = variableWrapper.isWrapped;
  18. var assign = variableWrapper.assign;
  19. var bracketsToDots = function(expr) {
  20. return expr.replace(/\[/g, ".").replace(/\]/g, "")
  21. };
  22. var readPropValue = function(obj, propName, options) {
  23. options = options || {};
  24. if ("this" === propName) {
  25. return unwrap(obj, options)
  26. }
  27. return unwrap(obj[propName], options)
  28. };
  29. var assignPropValue = function(obj, propName, value, options) {
  30. if ("this" === propName) {
  31. throw new errors.Error("E4016")
  32. }
  33. var propValue = obj[propName];
  34. if (options.unwrapObservables && isWrapped(propValue)) {
  35. assign(propValue, value)
  36. } else {
  37. obj[propName] = value
  38. }
  39. };
  40. var prepareOptions = function(options) {
  41. options = options || {};
  42. options.unwrapObservables = void 0 !== options.unwrapObservables ? options.unwrapObservables : true;
  43. return options
  44. };
  45. var unwrap = function(value, options) {
  46. return options.unwrapObservables ? unwrapVariable(value) : value
  47. };
  48. var compileGetter = function(expr) {
  49. if (arguments.length > 1) {
  50. expr = [].slice.call(arguments)
  51. }
  52. if (!expr || "this" === expr) {
  53. return function(obj) {
  54. return obj
  55. }
  56. }
  57. if ("string" === typeof expr) {
  58. expr = bracketsToDots(expr);
  59. var path = expr.split(".");
  60. return function(obj, options) {
  61. options = prepareOptions(options);
  62. var functionAsIs = options.functionsAsIs;
  63. var hasDefaultValue = "defaultValue" in options;
  64. var current = unwrap(obj, options);
  65. for (var i = 0; i < path.length; i++) {
  66. if (!current) {
  67. if (null == current && hasDefaultValue) {
  68. return options.defaultValue
  69. }
  70. break
  71. }
  72. var pathPart = path[i];
  73. if (hasDefaultValue && typeUtils.isObject(current) && !(pathPart in current)) {
  74. return options.defaultValue
  75. }
  76. var next = unwrap(current[pathPart], options);
  77. if (!functionAsIs && typeUtils.isFunction(next)) {
  78. next = next.call(current)
  79. }
  80. current = next
  81. }
  82. return current
  83. }
  84. }
  85. if (Array.isArray(expr)) {
  86. return combineGetters(expr)
  87. }
  88. if (typeUtils.isFunction(expr)) {
  89. return expr
  90. }
  91. };
  92. var combineGetters = function(getters) {
  93. var compiledGetters = {};
  94. for (var i = 0, l = getters.length; i < l; i++) {
  95. var getter = getters[i];
  96. compiledGetters[getter] = compileGetter(getter)
  97. }
  98. return function(obj, options) {
  99. var result;
  100. each(compiledGetters, function(name) {
  101. var value = this(obj, options);
  102. var current;
  103. if (void 0 === value) {
  104. return
  105. }
  106. current = result || (result = {});
  107. var path = name.split(".");
  108. var last = path.length - 1;
  109. for (var _i = 0; _i < last; _i++) {
  110. var pathItem = path[_i];
  111. if (!(pathItem in current)) {
  112. current[pathItem] = {}
  113. }
  114. current = current[pathItem]
  115. }
  116. current[path[last]] = value
  117. });
  118. return result
  119. }
  120. };
  121. var ensurePropValueDefined = function(obj, propName, value, options) {
  122. if (typeUtils.isDefined(value)) {
  123. return value
  124. }
  125. var newValue = {};
  126. assignPropValue(obj, propName, newValue, options);
  127. return newValue
  128. };
  129. var compileSetter = function(expr) {
  130. expr = bracketsToDots(expr || "this").split(".");
  131. var lastLevelIndex = expr.length - 1;
  132. return function(obj, value, options) {
  133. options = prepareOptions(options);
  134. var currentValue = unwrap(obj, options);
  135. expr.forEach(function(propertyName, levelIndex) {
  136. var propertyValue = readPropValue(currentValue, propertyName, options);
  137. var isPropertyFunc = !options.functionsAsIs && typeUtils.isFunction(propertyValue) && !isWrapped(propertyValue);
  138. if (levelIndex === lastLevelIndex) {
  139. if (options.merge && typeUtils.isPlainObject(value) && (!typeUtils.isDefined(propertyValue) || typeUtils.isPlainObject(propertyValue))) {
  140. propertyValue = ensurePropValueDefined(currentValue, propertyName, propertyValue, options);
  141. objectUtils.deepExtendArraySafe(propertyValue, value, false, true)
  142. } else {
  143. if (isPropertyFunc) {
  144. currentValue[propertyName](value)
  145. } else {
  146. assignPropValue(currentValue, propertyName, value, options)
  147. }
  148. }
  149. } else {
  150. propertyValue = ensurePropValueDefined(currentValue, propertyName, propertyValue, options);
  151. if (isPropertyFunc) {
  152. propertyValue = propertyValue.call(currentValue)
  153. }
  154. currentValue = propertyValue
  155. }
  156. })
  157. }
  158. };
  159. var toComparable = function(value, caseSensitive) {
  160. if (value instanceof Date) {
  161. return value.getTime()
  162. }
  163. if (value && value instanceof Class && value.valueOf) {
  164. return value.valueOf()
  165. }
  166. if (!caseSensitive && "string" === typeof value) {
  167. return value.toLowerCase()
  168. }
  169. return value
  170. };
  171. exports.compileGetter = compileGetter;
  172. exports.compileSetter = compileSetter;
  173. exports.toComparable = toComparable;