@syncfusion/ej2-base 24.2.8 → 25.1.35-579988

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (163) hide show
  1. package/.eslintrc.json +2 -1
  2. package/CHANGELOG.md +641 -677
  3. package/{README.md → ReadMe.md} +100 -100
  4. package/dist/ej2-base.umd.min.js +1 -10
  5. package/dist/ej2-base.umd.min.js.map +1 -1
  6. package/dist/es6/ej2-base.es2015.js +178 -1025
  7. package/dist/es6/ej2-base.es2015.js.map +1 -1
  8. package/dist/es6/ej2-base.es5.js +226 -934
  9. package/dist/es6/ej2-base.es5.js.map +1 -1
  10. package/dist/global/ej2-base.min.js +1 -10
  11. package/dist/global/ej2-base.min.js.map +1 -1
  12. package/dist/global/index.d.ts +0 -9
  13. package/dist/ts/ajax.ts +236 -0
  14. package/dist/ts/animation.ts +544 -0
  15. package/dist/ts/base.ts +357 -0
  16. package/dist/ts/browser.ts +387 -0
  17. package/dist/ts/child-property.ts +192 -0
  18. package/dist/ts/component.ts +519 -0
  19. package/dist/ts/dom.ts +488 -0
  20. package/dist/ts/draggable.ts +1155 -0
  21. package/dist/ts/droppable.ts +172 -0
  22. package/dist/ts/event-handler.ts +169 -0
  23. package/dist/ts/internationalization.ts +369 -0
  24. package/dist/ts/intl/date-formatter.ts +317 -0
  25. package/dist/ts/intl/date-parser.ts +426 -0
  26. package/dist/ts/intl/intl-base.ts +1104 -0
  27. package/dist/ts/intl/number-formatter.ts +411 -0
  28. package/dist/ts/intl/number-parser.ts +158 -0
  29. package/dist/ts/intl/parser-base.ts +394 -0
  30. package/dist/ts/keyboard.ts +238 -0
  31. package/dist/ts/l10n.ts +94 -0
  32. package/dist/ts/module-loader.ts +149 -0
  33. package/dist/ts/notify-property-change.ts +726 -0
  34. package/dist/ts/observer.ts +236 -0
  35. package/dist/ts/sanitize-helper.ts +224 -0
  36. package/dist/ts/template-engine.ts +191 -0
  37. package/dist/ts/template.ts +329 -0
  38. package/dist/ts/touch.ts +544 -0
  39. package/dist/ts/util.ts +523 -0
  40. package/dist/ts/validate-lic.ts +0 -0
  41. package/e2e/crypto.js +16 -16
  42. package/e2e/m.protractor.config.js +286 -286
  43. package/e2e/modified-protractor/protractor.config.js +316 -316
  44. package/e2e/protractor.config.js +389 -332
  45. package/helpers/e2e/index.js +3 -3
  46. package/license +10 -10
  47. package/package.json +225 -174
  48. package/src/ajax.d.ts +1 -1
  49. package/src/ajax.js +3 -8
  50. package/src/animation-model.d.ts +41 -41
  51. package/src/animation.d.ts +6 -6
  52. package/src/animation.js +25 -25
  53. package/src/base.d.ts +2 -1
  54. package/src/base.js +9 -7
  55. package/src/component-model.d.ts +16 -16
  56. package/src/component.d.ts +9 -3
  57. package/src/component.js +50 -38
  58. package/src/draggable-model.d.ts +113 -113
  59. package/src/draggable.d.ts +2 -0
  60. package/src/draggable.js +45 -29
  61. package/src/droppable-model.d.ts +23 -23
  62. package/src/droppable.js +19 -19
  63. package/src/event-handler.js +2 -1
  64. package/src/index.d.ts +0 -3
  65. package/src/index.js +0 -3
  66. package/src/intl/date-formatter.js +2 -6
  67. package/src/intl/date-parser.js +1 -20
  68. package/src/intl/intl-base.js +1 -164
  69. package/src/intl/number-formatter.d.ts +3 -0
  70. package/src/intl/number-formatter.js +7 -7
  71. package/src/intl/number-parser.js +1 -0
  72. package/src/keyboard-model.d.ts +16 -16
  73. package/src/keyboard.js +19 -19
  74. package/src/module-loader.d.ts +12 -0
  75. package/src/module-loader.js +11 -0
  76. package/src/notify-property-change.js +3 -2
  77. package/src/observer.js +2 -0
  78. package/src/sanitize-helper.js +5 -0
  79. package/src/template-engine.js +1 -0
  80. package/src/template.js +3 -2
  81. package/src/touch-model.d.ts +39 -39
  82. package/src/touch.js +19 -19
  83. package/src/validate-lic.d.ts +0 -11
  84. package/src/validate-lic.js +1 -259
  85. package/styles/_all.scss +2 -2
  86. package/styles/_bds-dark-definition.scss +15 -0
  87. package/styles/_bds-definition.scss +15 -0
  88. package/styles/_bootstrap-dark-definition.scss +42 -42
  89. package/styles/_bootstrap-definition.scss +42 -42
  90. package/styles/_bootstrap4-definition.scss +11 -11
  91. package/styles/_bootstrap5-dark-definition.scss +9 -9
  92. package/styles/_bootstrap5-definition.scss +8 -8
  93. package/styles/_fabric-dark-definition.scss +42 -42
  94. package/styles/_fabric-definition.scss +42 -42
  95. package/styles/_fluent-dark-definition.scss +9 -9
  96. package/styles/_fluent-definition.scss +9 -9
  97. package/styles/_fluent2-definition.scss +9 -0
  98. package/styles/_fusionnew-dark-definition.scss +8 -8
  99. package/styles/_fusionnew-definition.scss +8 -8
  100. package/styles/_highcontrast-definition.scss +42 -42
  101. package/styles/_highcontrast-light-definition.scss +42 -42
  102. package/styles/_material-dark-definition.scss +48 -48
  103. package/styles/_material-definition.scss +49 -49
  104. package/styles/_material3-dark-definition.scss +14 -14
  105. package/styles/_material3-definition.scss +15 -15
  106. package/styles/_tailwind-dark-definition.scss +15 -15
  107. package/styles/_tailwind-definition.scss +15 -15
  108. package/styles/animation/_all.scss +560 -560
  109. package/styles/bootstrap-dark.css +10 -1
  110. package/styles/bootstrap.css +10 -1
  111. package/styles/bootstrap4.css +10 -1
  112. package/styles/bootstrap5-dark.css +10 -1
  113. package/styles/bootstrap5.css +10 -1
  114. package/styles/common/_all.scss +2 -2
  115. package/styles/common/_core.scss +117 -117
  116. package/styles/common/_mixin.scss +9 -9
  117. package/styles/definition/_bds-dark.scss +1179 -0
  118. package/styles/definition/_bds.scss +1474 -0
  119. package/styles/definition/_bootstrap-dark.scss +219 -219
  120. package/styles/definition/_bootstrap.scss +215 -215
  121. package/styles/definition/_bootstrap4.scss +167 -167
  122. package/styles/definition/_bootstrap5-dark.scss +493 -493
  123. package/styles/definition/_bootstrap5.scss +494 -494
  124. package/styles/definition/_fabric-dark.scss +200 -200
  125. package/styles/definition/_fabric.scss +198 -198
  126. package/styles/definition/_fluent-dark.scss +557 -557
  127. package/styles/definition/_fluent.scss +558 -558
  128. package/styles/definition/_fluent2.scss +2198 -0
  129. package/styles/definition/_fusionnew-dark.scss +362 -362
  130. package/styles/definition/_fusionnew.scss +363 -363
  131. package/styles/definition/_highcontrast-light.scss +193 -193
  132. package/styles/definition/_highcontrast.scss +195 -195
  133. package/styles/definition/_material-dark.scss +198 -198
  134. package/styles/definition/_material.scss +192 -192
  135. package/styles/definition/_material3-dark.scss +710 -710
  136. package/styles/definition/_material3.scss +792 -792
  137. package/styles/definition/_tailwind-dark.scss +488 -488
  138. package/styles/definition/_tailwind.scss +485 -485
  139. package/styles/fabric-dark.css +10 -1
  140. package/styles/fabric.css +10 -1
  141. package/styles/fluent-dark.css +10 -1
  142. package/styles/fluent.css +10 -1
  143. package/styles/highcontrast-light.css +10 -1
  144. package/styles/highcontrast.css +10 -1
  145. package/styles/material-dark.css +10 -1
  146. package/styles/material.css +10 -1
  147. package/styles/material3-dark.css +10 -1
  148. package/styles/material3.css +10 -1
  149. package/styles/offline-theme/material-dark.css +10 -1
  150. package/styles/offline-theme/material.css +10 -1
  151. package/styles/offline-theme/tailwind-dark.css +10 -1
  152. package/styles/offline-theme/tailwind.css +10 -1
  153. package/styles/tailwind-dark.css +10 -1
  154. package/styles/tailwind.css +10 -1
  155. package/.github/PULL_REQUEST_TEMPLATE/Bug.md +0 -60
  156. package/.github/PULL_REQUEST_TEMPLATE/feature.md +0 -42
  157. package/bin/syncfusion-license.js +0 -2
  158. package/dist/ej2-base.min.js +0 -10
  159. package/e2e/index.d.ts +0 -27
  160. package/src/fetch.d.ts +0 -114
  161. package/src/fetch.js +0 -116
  162. package/src/hijri-parser.d.ts +0 -19
  163. package/src/hijri-parser.js +0 -204
@@ -0,0 +1,387 @@
1
+ import { isUndefined } from './util';
2
+ const REGX_MOBILE: RegExp = /android|webos|iphone|ipad|ipod|blackberry|iemobile|opera mini|mobile/i;
3
+ const REGX_IE: RegExp = /msie|trident/i;
4
+ const REGX_IE11: RegExp = /Trident\/7\./;
5
+ const REGX_IOS: RegExp = /(ipad|iphone|ipod touch)/i;
6
+ const REGX_IOS7: RegExp = /(ipad|iphone|ipod touch);.*os 7_\d|(ipad|iphone|ipod touch);.*os 8_\d/i;
7
+ const REGX_ANDROID: RegExp = /android/i;
8
+ const REGX_WINDOWS: RegExp = /trident|windows phone|edge/i;
9
+ const REGX_VERSION: RegExp = /(version)[ /]([\w.]+)/i;
10
+ const REGX_BROWSER: { [key: string]: RegExp } = {
11
+ OPERA: /(opera|opr)(?:.*version|)[ /]([\w.]+)/i,
12
+ EDGE: /(edge)(?:.*version|)[ /]([\w.]+)/i,
13
+ CHROME: /(chrome|crios)[ /]([\w.]+)/i,
14
+ PANTHOMEJS: /(phantomjs)[ /]([\w.]+)/i,
15
+ SAFARI: /(safari)[ /]([\w.]+)/i,
16
+ WEBKIT: /(webkit)[ /]([\w.]+)/i,
17
+ MSIE: /(msie|trident) ([\w.]+)/i,
18
+ MOZILLA: /(mozilla)(?:.*? rv:([\w.]+)|)/i
19
+ };
20
+
21
+ interface MyWindow extends Window {
22
+ browserDetails: BrowserDetails;
23
+ cordova: Object;
24
+ PhoneGap: Object;
25
+ phonegap: Object;
26
+ forge: Object;
27
+ }
28
+ declare let window: MyWindow;
29
+
30
+ /* istanbul ignore else */
31
+ if (typeof window !== 'undefined') {
32
+ window.browserDetails = window.browserDetails || {};
33
+ }
34
+
35
+
36
+ /**
37
+ * Get configuration details for Browser
38
+ *
39
+ * @private
40
+ */
41
+ export class Browser {
42
+
43
+ /* istanbul ignore next */
44
+ private static uA: string = typeof navigator !== 'undefined' ? navigator.userAgent : '';
45
+
46
+ private static extractBrowserDetail(): BrowserInfo {
47
+ const browserInfo: BrowserInfo = { culture: {} };
48
+ const keys: string[] = Object.keys(REGX_BROWSER);
49
+ let clientInfo: string[] = [];
50
+ for (const key of keys) {
51
+ clientInfo = Browser.userAgent.match(REGX_BROWSER[`${key}`]);
52
+ if (clientInfo) {
53
+ browserInfo.name = (clientInfo[1].toLowerCase() === 'opr' ? 'opera' : clientInfo[1].toLowerCase());
54
+ browserInfo.name = (clientInfo[1].toLowerCase() === 'crios' ? 'chrome' : browserInfo.name);
55
+ browserInfo.version = clientInfo[2];
56
+ browserInfo.culture.name = browserInfo.culture.language = navigator.language;
57
+ // eslint-disable-next-line
58
+ if (!!Browser.userAgent.match(REGX_IE11)) {
59
+ browserInfo.name = 'msie';
60
+ break;
61
+ }
62
+ const version: RegExpMatchArray = Browser.userAgent.match(REGX_VERSION);
63
+ if (browserInfo.name === 'safari' && version) {
64
+ browserInfo.version = version[2];
65
+ }
66
+ break;
67
+ }
68
+ }
69
+ return browserInfo;
70
+ }
71
+
72
+ /**
73
+ * To get events from the browser
74
+ *
75
+ * @param {string} event - type of event triggered.
76
+ * @returns {boolean}
77
+ */
78
+
79
+ private static getEvent(event: string): string {
80
+ // eslint-disable-next-line
81
+ const events: { [key: string]: any } = {
82
+ start: {
83
+ isPointer: 'pointerdown', isTouch: 'touchstart', isDevice: 'mousedown'
84
+ },
85
+ move: {
86
+ isPointer: 'pointermove', isTouch: 'touchmove', isDevice: 'mousemove'
87
+ },
88
+ end: {
89
+ isPointer: 'pointerup', isTouch: 'touchend', isDevice: 'mouseup'
90
+ },
91
+ cancel: {
92
+ isPointer: 'pointercancel', isTouch: 'touchcancel', isDevice: 'mouseleave'
93
+ }
94
+ };
95
+ return (Browser.isPointer ? events[`${event}`].isPointer :
96
+ (Browser.isTouch ? events[`${event}`].isTouch + (!Browser.isDevice ? ' ' + events[`${event}`].isDevice : '')
97
+ : events[`${event}`].isDevice));
98
+ }
99
+
100
+ /**
101
+ * To get the Touch start event from browser
102
+ *
103
+ * @returns {string}
104
+ */
105
+
106
+ private static getTouchStartEvent(): string {
107
+ return Browser.getEvent('start');
108
+ }
109
+
110
+ /**
111
+ * To get the Touch end event from browser
112
+ *
113
+ * @returns {string}
114
+ */
115
+
116
+ private static getTouchEndEvent(): string {
117
+ return Browser.getEvent('end');
118
+ }
119
+
120
+ /**
121
+ * To get the Touch move event from browser
122
+ *
123
+ * @returns {string}
124
+ */
125
+
126
+ private static getTouchMoveEvent(): string {
127
+ return Browser.getEvent('move');
128
+ }
129
+
130
+ /**
131
+ * To cancel the touch event from browser
132
+ *
133
+ * @returns {string}
134
+ */
135
+
136
+ private static getTouchCancelEvent(): string {
137
+ return Browser.getEvent('cancel');
138
+ }
139
+
140
+ /**
141
+ * Check whether the browser on the iPad device is Safari or not
142
+ *
143
+ * @returns {boolean}
144
+ */
145
+
146
+ public static isSafari(): boolean {
147
+ return (Browser.isDevice && Browser.isIos && Browser.isTouch && typeof window !== 'undefined'
148
+ && window.navigator.userAgent.toLowerCase().indexOf('iphone') === -1
149
+ && window.navigator.userAgent.toLowerCase().indexOf('safari') > -1);
150
+ }
151
+
152
+ /**
153
+ * To get the value based on provided key and regX
154
+ *
155
+ * @param {string} key ?
156
+ * @param {RegExp} regX ?
157
+ * @returns {Object} ?
158
+ */
159
+
160
+ private static getValue(key: string, regX: RegExp): Object {
161
+ const browserDetails: {} = typeof window !== 'undefined' ? window.browserDetails : {};
162
+ if (typeof navigator !== 'undefined' && navigator.platform === 'MacIntel' && navigator.maxTouchPoints > 1 && Browser.isTouch === true && !REGX_BROWSER.CHROME.test(navigator.userAgent)) {
163
+ browserDetails['isIos'] = true;
164
+ browserDetails['isDevice'] = true;
165
+ browserDetails['isTouch'] = true;
166
+ browserDetails['isPointer'] = true;
167
+ }
168
+ if ('undefined' === typeof (<{ [key: string]: Object }>browserDetails)[`${key}`]) {
169
+ return (<{ [key: string]: Object }>browserDetails)[`${key}`] = regX.test(Browser.userAgent);
170
+ }
171
+ return (<{ [key: string]: Object }>browserDetails)[`${key}`];
172
+ }
173
+
174
+ //Properties
175
+
176
+ /**
177
+ * Property specifies the userAgent of the browser. Default userAgent value is based on the browser.
178
+ * Also we can set our own userAgent.
179
+ *
180
+ * @param {string} uA ?
181
+ */
182
+ static set userAgent(uA: string) {
183
+ Browser.uA = uA;
184
+ window.browserDetails = {};
185
+ }
186
+ static get userAgent(): string {
187
+ return Browser.uA;
188
+
189
+ }
190
+
191
+ //Read Only Properties
192
+
193
+ /**
194
+ * Property is to get the browser information like Name, Version and Language
195
+ *
196
+ * @returns {BrowserInfo} ?
197
+ */
198
+ static get info(): BrowserInfo {
199
+ if (isUndefined(window.browserDetails.info)) {
200
+ return window.browserDetails.info = Browser.extractBrowserDetail();
201
+ }
202
+ return window.browserDetails.info;
203
+ }
204
+
205
+ /**
206
+ * Property is to get whether the userAgent is based IE.
207
+ *
208
+ * @returns {boolean} ?
209
+ */
210
+ static get isIE(): boolean {
211
+ return <boolean>Browser.getValue('isIE', REGX_IE);
212
+ }
213
+
214
+ /**
215
+ * Property is to get whether the browser has touch support.
216
+ *
217
+ * @returns {boolean} ?
218
+ */
219
+ static get isTouch(): boolean {
220
+ if (isUndefined(window.browserDetails.isTouch)) {
221
+ return (window.browserDetails.isTouch =
222
+ ('ontouchstart' in window.navigator) ||
223
+ (window &&
224
+ window.navigator &&
225
+ (window.navigator.maxTouchPoints > 0)) || ('ontouchstart' in window));
226
+ }
227
+ return window.browserDetails.isTouch;
228
+ }
229
+
230
+ /**
231
+ * Property is to get whether the browser has Pointer support.
232
+ *
233
+ * @returns {boolean} ?
234
+ */
235
+ static get isPointer(): boolean {
236
+ if (isUndefined(window.browserDetails.isPointer)) {
237
+ return window.browserDetails.isPointer = ('pointerEnabled' in window.navigator);
238
+ }
239
+ return window.browserDetails.isPointer;
240
+ }
241
+
242
+ /**
243
+ * Property is to get whether the browser has MSPointer support.
244
+ *
245
+ * @returns {boolean} ?
246
+ */
247
+ static get isMSPointer(): boolean {
248
+ if (isUndefined(window.browserDetails.isMSPointer)) {
249
+ return window.browserDetails.isMSPointer = ('msPointerEnabled' in window.navigator);
250
+ }
251
+ return window.browserDetails.isMSPointer;
252
+ }
253
+
254
+ /**
255
+ * Property is to get whether the userAgent is device based.
256
+ *
257
+ * @returns {boolean} ?
258
+ */
259
+ static get isDevice(): boolean {
260
+ return <boolean>Browser.getValue('isDevice', REGX_MOBILE);
261
+ }
262
+
263
+ /**
264
+ * Property is to get whether the userAgent is IOS.
265
+ *
266
+ * @returns {boolean} ?
267
+ */
268
+ static get isIos(): boolean {
269
+ return <boolean>Browser.getValue('isIos', REGX_IOS);
270
+ }
271
+
272
+ /**
273
+ * Property is to get whether the userAgent is Ios7.
274
+ *
275
+ * @returns {boolean} ?
276
+ */
277
+ static get isIos7(): boolean {
278
+ return <boolean>Browser.getValue('isIos7', REGX_IOS7);
279
+ }
280
+
281
+ /**
282
+ * Property is to get whether the userAgent is Android.
283
+ *
284
+ * @returns {boolean} ?
285
+ */
286
+ static get isAndroid(): boolean {
287
+ return <boolean>Browser.getValue('isAndroid', REGX_ANDROID);
288
+ }
289
+
290
+
291
+ /**
292
+ * Property is to identify whether application ran in web view.
293
+ *
294
+ * @returns {boolean} ?
295
+ */
296
+ static get isWebView(): boolean {
297
+ if (isUndefined(window.browserDetails.isWebView)) {
298
+ window.browserDetails.isWebView = !(isUndefined(window.cordova) && isUndefined(window.PhoneGap)
299
+ && isUndefined(window.phonegap) && window.forge !== 'object');
300
+ return window.browserDetails.isWebView;
301
+ }
302
+ return window.browserDetails.isWebView;
303
+ }
304
+
305
+
306
+ /**
307
+ * Property is to get whether the userAgent is Windows.
308
+ *
309
+ * @returns {boolean} ?
310
+ */
311
+ static get isWindows(): boolean {
312
+ return <boolean>Browser.getValue('isWindows', REGX_WINDOWS);
313
+ }
314
+
315
+ /**
316
+ * Property is to get the touch start event. It returns event name based on browser.
317
+ *
318
+ * @returns {string} ?
319
+ */
320
+ static get touchStartEvent(): string {
321
+ if (isUndefined(window.browserDetails.touchStartEvent)) {
322
+ return window.browserDetails.touchStartEvent = Browser.getTouchStartEvent();
323
+ }
324
+ return window.browserDetails.touchStartEvent;
325
+ }
326
+
327
+ /**
328
+ * Property is to get the touch move event. It returns event name based on browser.
329
+ *
330
+ * @returns {string} ?
331
+ */
332
+ static get touchMoveEvent(): string {
333
+ if (isUndefined(window.browserDetails.touchMoveEvent)) {
334
+ return window.browserDetails.touchMoveEvent = Browser.getTouchMoveEvent();
335
+ }
336
+ return window.browserDetails.touchMoveEvent;
337
+ }
338
+
339
+ /**
340
+ * Property is to get the touch end event. It returns event name based on browser.
341
+ *
342
+ * @returns {string} ?
343
+ */
344
+ static get touchEndEvent(): string {
345
+ if (isUndefined(window.browserDetails.touchEndEvent)) {
346
+ return window.browserDetails.touchEndEvent = Browser.getTouchEndEvent();
347
+ }
348
+ return window.browserDetails.touchEndEvent;
349
+ }
350
+
351
+ /**
352
+ * Property is to cancel the touch end event.
353
+ *
354
+ * @returns {string} ?
355
+ */
356
+ static get touchCancelEvent(): string {
357
+ if (isUndefined(window.browserDetails.touchCancelEvent)) {
358
+ return window.browserDetails.touchCancelEvent = Browser.getTouchCancelEvent();
359
+ }
360
+ return window.browserDetails.touchCancelEvent;
361
+ }
362
+
363
+ }
364
+
365
+ export interface BrowserDetails {
366
+ isAndroid?: boolean;
367
+ isDevice?: boolean;
368
+ isIE?: boolean;
369
+ isIos?: boolean;
370
+ isIos7?: boolean;
371
+ isMSPointer?: boolean;
372
+ isPointer?: boolean;
373
+ isTouch?: boolean;
374
+ isWebView?: boolean;
375
+ isWindows?: boolean;
376
+ info?: BrowserInfo;
377
+ touchStartEvent?: string;
378
+ touchMoveEvent?: string;
379
+ touchEndEvent?: string;
380
+ touchCancelEvent?: string;
381
+ }
382
+
383
+ export interface BrowserInfo {
384
+ name?: string;
385
+ version?: string;
386
+ culture?: { name?: string, language?: string };
387
+ }
@@ -0,0 +1,192 @@
1
+ import { getValue, setValue, merge, isBlazor } from './util';
2
+ import { Base } from './base';
3
+ /**
4
+ * To detect the changes for inner properties.
5
+ *
6
+ * @private
7
+ */
8
+ export class ChildProperty<T> {
9
+ // eslint-disable-next-line
10
+ private parentObj: any;
11
+ private controlParent: ParentObject;
12
+ private propName: string;
13
+ private isParentArray: boolean;
14
+ protected isComplexArraySetter: boolean = false;
15
+ protected properties: { [key: string]: Object } = {};
16
+ protected changedProperties: { [key: string]: Object } = {};
17
+ protected childChangedProperties: { [key: string]: Object } = {};
18
+ protected oldProperties: { [key: string]: Object } = {};
19
+ // eslint-disable-next-line
20
+ protected finalUpdate: Function = (): void => { };
21
+ private callChildDataBind: Function = getValue('callChildDataBind', Base);
22
+ constructor(parent: T, propName: string, defaultValue: Object, isArray?: boolean) {
23
+ this.parentObj = <T & ParentObject>parent;
24
+ this.controlParent = this.parentObj.controlParent || this.parentObj;
25
+ this.propName = propName;
26
+ this.isParentArray = isArray;
27
+ this.setProperties(defaultValue, true);
28
+ }
29
+ /**
30
+ * Updates the property changes
31
+ *
32
+ * @param {boolean} val ?
33
+ * @param {string} propName ?
34
+ * @returns {void} ?
35
+ */
36
+ private updateChange(val: boolean, propName: string): void {
37
+ if (val === true) {
38
+ this.parentObj.childChangedProperties[`${propName}`] = val;
39
+ } else {
40
+ delete this.parentObj.childChangedProperties[`${propName}`];
41
+ }
42
+ if (this.parentObj.updateChange) {
43
+ this.parentObj.updateChange(val, this.parentObj.propName);
44
+ }
45
+ }
46
+ /**
47
+ * Updates time out duration
48
+ *
49
+ * @returns {void} ?
50
+ */
51
+ private updateTimeOut(): void {
52
+ if (this.parentObj.updateTimeOut) {
53
+ this.parentObj.finalUpdate();
54
+ this.parentObj.updateTimeOut();
55
+
56
+ } else {
57
+ const changeTime: number = setTimeout(this.parentObj.dataBind.bind(this.parentObj));
58
+ const clearUpdate: Function = () => {
59
+ clearTimeout(changeTime);
60
+ };
61
+ this.finalUpdate = clearUpdate;
62
+ }
63
+ }
64
+ /**
65
+ * Clears changed properties
66
+ *
67
+ * @returns {void} ?
68
+ */
69
+ private clearChanges(): void {
70
+ this.finalUpdate();
71
+ this.updateChange(false, this.propName);
72
+ this.oldProperties = {};
73
+ this.changedProperties = {};
74
+ }
75
+ /**
76
+ * Set property changes
77
+ *
78
+ * @param {Object} prop ?
79
+ * @param {boolean} muteOnChange ?
80
+ * @returns {void} ?
81
+ */
82
+ protected setProperties(prop: Object, muteOnChange: boolean): void {
83
+ if (muteOnChange === true) {
84
+ merge(this, prop);
85
+ this.updateChange(false, this.propName);
86
+ this.clearChanges();
87
+ } else {
88
+ merge(this, prop);
89
+ }
90
+ }
91
+ /**
92
+ * Binds data
93
+ *
94
+ * @returns {void} ?
95
+ */
96
+ protected dataBind(): void {
97
+ this.callChildDataBind(this.childChangedProperties, this);
98
+ if (this.isParentArray) {
99
+ const curIndex: number = (this.parentObj[this.propName] as Object[]).indexOf(this);
100
+ if (Object.keys(this.changedProperties).length) {
101
+ setValue(this.propName + '.' + curIndex, this.changedProperties, this.parentObj.changedProperties);
102
+ setValue(this.propName + '.' + curIndex, this.oldProperties, this.parentObj.oldProperties);
103
+ }
104
+ } else {
105
+ this.parentObj.changedProperties[this.propName] = this.changedProperties;
106
+ this.parentObj.oldProperties[this.propName] = this.oldProperties;
107
+ }
108
+ this.clearChanges();
109
+ }
110
+ /**
111
+ * Saves changes to newer values
112
+ *
113
+ * @param {string} key ?
114
+ * @param {Object} newValue ?
115
+ * @param {Object} oldValue ?
116
+ * @param {boolean} restrictServerDataBind ?
117
+ * @returns {void} ?
118
+ */
119
+ protected saveChanges(key: string, newValue: Object, oldValue: Object, restrictServerDataBind?: boolean): void {
120
+ if (this.controlParent.isProtectedOnChange) { return; }
121
+ if (!restrictServerDataBind) { this.serverDataBind(key, newValue, true); }
122
+ this.oldProperties[`${key}`] = oldValue;
123
+ this.changedProperties[`${key}`] = newValue;
124
+ this.updateChange(true, this.propName);
125
+ this.finalUpdate();
126
+ this.updateTimeOut();
127
+ }
128
+ protected serverDataBind(key: string, value: Object, isSaveChanges?: boolean, action?: string): void {
129
+ if (isBlazor() && !this.parentObj.isComplexArraySetter) {
130
+ let parent: Object;
131
+ const newChanges: Object = {};
132
+ const parentKey: string = isSaveChanges ? this.getParentKey(true) + '.' + key : key;
133
+ /* istanbul ignore else */
134
+ if (parentKey.indexOf('.') !== -1) {
135
+ const complexKeys: string[] = parentKey.split('.');
136
+ parent = newChanges;
137
+ for (let i: number = 0; i < complexKeys.length; i++) {
138
+ const isFinal: boolean = i === complexKeys.length - 1;
139
+ parent[complexKeys[parseInt(i.toString(), 10)]] = isFinal ? value : {};
140
+ parent = isFinal ? parent : parent[complexKeys[parseInt(i.toString(), 10)]];
141
+ }
142
+ } else {
143
+ newChanges[`${parentKey}`] = {};
144
+ parent = newChanges[`${parentKey}`];
145
+ newChanges[`${parentKey}`][`${key}`] = value;
146
+ }
147
+ /* istanbul ignore next */
148
+ if (this.isParentArray) {
149
+ const actionProperty: string = 'ejsAction';
150
+ parent[`${actionProperty}`] = action ? action : 'none';
151
+ }
152
+ this.controlParent.serverDataBind(newChanges);
153
+ }
154
+ }
155
+ protected getParentKey(isSaveChanges?: boolean): string {
156
+ // eslint-disable-next-line
157
+ let index: any = '';
158
+ let propName: string = this.propName;
159
+ /* istanbul ignore next */
160
+ if (this.isParentArray) {
161
+ index = this.parentObj[this.propName].indexOf(this);
162
+ let valueLength: number = this.parentObj[this.propName].length;
163
+ valueLength = isSaveChanges ? valueLength : (valueLength > 0 ? valueLength - 1 : 0);
164
+ index = index !== -1 ? '-' + index : '-' + valueLength;
165
+ propName = propName + index;
166
+ }
167
+ if (this.controlParent !== this.parentObj) {
168
+ propName = this.parentObj.getParentKey() + '.' + this.propName + index;
169
+ }
170
+ return propName;
171
+ }
172
+ }
173
+ /**
174
+ * Interface for parent object
175
+ */
176
+ interface ParentObject {
177
+ saveChanges: (key: string, newValue: Object, oldValue: Object) => void;
178
+ changedProperties: { [key: string]: Object };
179
+ childChangedProperties: { [key: string]: Object };
180
+ oldProperties: { [key: string]: Object };
181
+ parentObj: { [key: string]: Object };
182
+ updateChange: (val: boolean, prop: string) => void;
183
+ propName: string;
184
+ finalUpdate: Function;
185
+ updateTimeOut: Function;
186
+ dataBind: Function;
187
+ isProtectedOnChange: boolean;
188
+ controlParent: ParentObject;
189
+ isRendered: boolean;
190
+ // eslint-disable-next-line
191
+ serverDataBind: (newChanges?: { [key: string]: any }) => void;
192
+ }