7bdd0d4abb5a82bcb73c6714d3c99d4188e3f1f95293e18ccf2ae5f025075ce0385c0cafef66e44ff389bffda52b1822aab324f6e10694ca3108d870764864 9.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357
  1. 'use strict';
  2. exports.__esModule = true;
  3. var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; };
  4. exports.duckSchema = duckSchema;
  5. exports.inherit = inherit;
  6. exports.extend = extend;
  7. exports.deepExtend = deepExtend;
  8. exports.deepClone = deepClone;
  9. exports.clone = clone;
  10. exports.mixin = mixin;
  11. exports.isObjectEquals = isObjectEquals;
  12. exports.isObject = isObject;
  13. exports.defineGetter = defineGetter;
  14. exports.objectEach = objectEach;
  15. exports.getProperty = getProperty;
  16. exports.deepObjectSize = deepObjectSize;
  17. exports.createObjectPropListener = createObjectPropListener;
  18. exports.hasOwnProperty = hasOwnProperty;
  19. var _array = require('./array');
  20. function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
  21. /**
  22. * Generate schema for passed object.
  23. *
  24. * @param {Array|Object} object
  25. * @returns {Array|Object}
  26. */
  27. function duckSchema(object) {
  28. var schema;
  29. if (Array.isArray(object)) {
  30. schema = [];
  31. } else {
  32. schema = {};
  33. objectEach(object, function (value, key) {
  34. if (key === '__children') {
  35. return;
  36. }
  37. if (value && (typeof value === 'undefined' ? 'undefined' : _typeof(value)) === 'object' && !Array.isArray(value)) {
  38. schema[key] = duckSchema(value);
  39. } else if (Array.isArray(value)) {
  40. if (value.length && _typeof(value[0]) === 'object' && !Array.isArray(value[0])) {
  41. schema[key] = [duckSchema(value[0])];
  42. } else {
  43. schema[key] = [];
  44. }
  45. } else {
  46. schema[key] = null;
  47. }
  48. });
  49. }
  50. return schema;
  51. }
  52. /**
  53. * Inherit without without calling parent constructor, and setting `Child.prototype.constructor` to `Child` instead of `Parent`.
  54. * Creates temporary dummy function to call it as constructor.
  55. * Described in ticket: https://github.com/handsontable/handsontable/pull/516
  56. *
  57. * @param {Object} Child child class
  58. * @param {Object} Parent parent class
  59. * @return {Object} extended Child
  60. */
  61. function inherit(Child, Parent) {
  62. Parent.prototype.constructor = Parent;
  63. Child.prototype = new Parent();
  64. Child.prototype.constructor = Child;
  65. return Child;
  66. }
  67. /**
  68. * Perform shallow extend of a target object with extension's own properties.
  69. *
  70. * @param {Object} target An object that will receive the new properties.
  71. * @param {Object} extension An object containing additional properties to merge into the target.
  72. */
  73. function extend(target, extension) {
  74. objectEach(extension, function (value, key) {
  75. target[key] = value;
  76. });
  77. return target;
  78. }
  79. /**
  80. * Perform deep extend of a target object with extension's own properties.
  81. *
  82. * @param {Object} target An object that will receive the new properties.
  83. * @param {Object} extension An object containing additional properties to merge into the target.
  84. */
  85. function deepExtend(target, extension) {
  86. objectEach(extension, function (value, key) {
  87. if (extension[key] && _typeof(extension[key]) === 'object') {
  88. if (!target[key]) {
  89. if (Array.isArray(extension[key])) {
  90. target[key] = [];
  91. } else if (Object.prototype.toString.call(extension[key]) === '[object Date]') {
  92. target[key] = extension[key];
  93. } else {
  94. target[key] = {};
  95. }
  96. }
  97. deepExtend(target[key], extension[key]);
  98. } else {
  99. target[key] = extension[key];
  100. }
  101. });
  102. }
  103. /**
  104. * Perform deep clone of an object.
  105. * WARNING! Only clones JSON properties. Will cause error when `obj` contains a function, Date, etc.
  106. *
  107. * @param {Object} obj An object that will be cloned
  108. * @return {Object}
  109. */
  110. function deepClone(obj) {
  111. if ((typeof obj === 'undefined' ? 'undefined' : _typeof(obj)) === 'object') {
  112. return JSON.parse(JSON.stringify(obj));
  113. }
  114. return obj;
  115. }
  116. /**
  117. * Shallow clone object.
  118. *
  119. * @param {Object} object
  120. * @returns {Object}
  121. */
  122. function clone(object) {
  123. var result = {};
  124. objectEach(object, function (value, key) {
  125. result[key] = value;
  126. });
  127. return result;
  128. }
  129. /**
  130. * Extend the Base object (usually prototype) of the functionality the `mixins` objects.
  131. *
  132. * @param {Object} Base Base object which will be extended.
  133. * @param {Object} mixins The object of the functionality will be "copied".
  134. * @returns {Object}
  135. */
  136. function mixin(Base) {
  137. if (!Base.MIXINS) {
  138. Base.MIXINS = [];
  139. }
  140. for (var _len = arguments.length, mixins = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
  141. mixins[_key - 1] = arguments[_key];
  142. }
  143. (0, _array.arrayEach)(mixins, function (mixin) {
  144. Base.MIXINS.push(mixin.MIXIN_NAME);
  145. objectEach(mixin, function (value, key) {
  146. if (Base.prototype[key] !== void 0) {
  147. throw new Error('Mixin conflict. Property \'' + key + '\' already exist and cannot be overwritten.');
  148. }
  149. if (typeof value === 'function') {
  150. Base.prototype[key] = value;
  151. } else {
  152. var getter = function _getter(propertyName, initialValue) {
  153. propertyName = '_' + propertyName;
  154. var initValue = function initValue(value) {
  155. if (Array.isArray(value) || isObject(value)) {
  156. value = deepClone(value);
  157. }
  158. return value;
  159. };
  160. return function () {
  161. if (this[propertyName] === void 0) {
  162. this[propertyName] = initValue(initialValue);
  163. }
  164. return this[propertyName];
  165. };
  166. };
  167. var setter = function _setter(propertyName) {
  168. propertyName = '_' + propertyName;
  169. return function (value) {
  170. this[propertyName] = value;
  171. };
  172. };
  173. Object.defineProperty(Base.prototype, key, {
  174. get: getter(key, value),
  175. set: setter(key),
  176. configurable: true
  177. });
  178. }
  179. });
  180. });
  181. return Base;
  182. }
  183. /**
  184. * Checks if two objects or arrays are (deep) equal
  185. *
  186. * @param {Object|Array} object1
  187. * @param {Object|Array} object2
  188. * @returns {Boolean}
  189. */
  190. function isObjectEquals(object1, object2) {
  191. return JSON.stringify(object1) === JSON.stringify(object2);
  192. }
  193. /**
  194. * Determines whether given object is a plain Object.
  195. * Note: String and Array are not plain Objects
  196. * @param {*} obj
  197. * @returns {boolean}
  198. */
  199. function isObject(obj) {
  200. return Object.prototype.toString.call(obj) == '[object Object]';
  201. }
  202. function defineGetter(object, property, value, options) {
  203. options.value = value;
  204. options.writable = options.writable !== false;
  205. options.enumerable = options.enumerable !== false;
  206. options.configurable = options.configurable !== false;
  207. Object.defineProperty(object, property, options);
  208. }
  209. /**
  210. * A specialized version of `.forEach` for objects.
  211. *
  212. * @param {Object} object The object to iterate over.
  213. * @param {Function} iteratee The function invoked per iteration.
  214. * @returns {Object} Returns `object`.
  215. */
  216. function objectEach(object, iteratee) {
  217. for (var key in object) {
  218. if (!object.hasOwnProperty || object.hasOwnProperty && Object.prototype.hasOwnProperty.call(object, key)) {
  219. if (iteratee(object[key], key, object) === false) {
  220. break;
  221. }
  222. }
  223. }
  224. return object;
  225. }
  226. /**
  227. * Get object property by its name. Access to sub properties can be achieved by dot notation (e.q. `'foo.bar.baz'`).
  228. *
  229. * @param {Object} object Object which value will be exported.
  230. * @param {String} name Object property name.
  231. * @returns {*}
  232. */
  233. function getProperty(object, name) {
  234. var names = name.split('.');
  235. var result = object;
  236. objectEach(names, function (name) {
  237. result = result[name];
  238. if (result === void 0) {
  239. result = void 0;
  240. return false;
  241. }
  242. });
  243. return result;
  244. }
  245. /**
  246. * Return object length (recursively).
  247. *
  248. * @param {*} object Object for which we want get length.
  249. * @returns {Number}
  250. */
  251. function deepObjectSize(object) {
  252. if (!isObject(object)) {
  253. return 0;
  254. }
  255. var recursObjLen = function recursObjLen(obj) {
  256. var result = 0;
  257. if (isObject(obj)) {
  258. objectEach(obj, function (key) {
  259. result += recursObjLen(key);
  260. });
  261. } else {
  262. result++;
  263. }
  264. return result;
  265. };
  266. return recursObjLen(object);
  267. }
  268. /**
  269. * Create object with property where its value change will be observed.
  270. *
  271. * @param {*} [defaultValue=undefined] Default value.
  272. * @param {String} [propertyToListen='value'] Property to listen.
  273. * @returns {Object}
  274. */
  275. function createObjectPropListener(defaultValue) {
  276. var _holder;
  277. var propertyToListen = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 'value';
  278. var privateProperty = '_' + propertyToListen;
  279. var holder = (_holder = {
  280. _touched: false
  281. }, _defineProperty(_holder, privateProperty, defaultValue), _defineProperty(_holder, 'isTouched', function isTouched() {
  282. return this._touched;
  283. }), _holder);
  284. Object.defineProperty(holder, propertyToListen, {
  285. get: function get() {
  286. return this[privateProperty];
  287. },
  288. set: function set(value) {
  289. this._touched = true;
  290. this[privateProperty] = value;
  291. },
  292. enumerable: true,
  293. configurable: true
  294. });
  295. return holder;
  296. }
  297. /**
  298. * Check if at specified `key` there is any value for `object`.
  299. *
  300. * @param {Object} object Object to search value at specyfic key.
  301. * @param {String} key String key to check.
  302. */
  303. function hasOwnProperty(object, key) {
  304. return Object.prototype.hasOwnProperty.call(object, key);
  305. }