@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,411 @@
1
+ import { isUndefined, throwError, isNullOrUndefined, extend, isBlazor, getValue } from '../util';
2
+ import { NumberFormatOptions, defaultCurrencyCode } from '../internationalization';
3
+ import { IntlBase as base } from './intl-base';
4
+ import { ParserBase as parser, NumberMapper } from './parser-base';
5
+ /**
6
+ * Interface for default formatting options
7
+ *
8
+ * @private
9
+ */
10
+ export interface FormatParts extends base.NumericSkeleton, NumberFormatOptions {
11
+ groupOne?: boolean;
12
+ isPercent?: boolean;
13
+ isCurrency?: boolean;
14
+ isNegative?: boolean;
15
+ groupData?: GroupDetails;
16
+ groupSeparator?: string;
17
+ }
18
+ /**
19
+ * Interface for common formatting options
20
+ */
21
+ export interface CommonOptions {
22
+ numberMapper?: NumberMapper;
23
+ currencySymbol?: string;
24
+ percentSymbol?: string;
25
+ minusSymbol?: string;
26
+ isCustomFormat?: boolean;
27
+ }
28
+ /* eslint-disable */
29
+ /**
30
+ * Interface for currency processing
31
+ */
32
+ interface CurrencyOptions {
33
+ position?: string;
34
+ symbol?: string;
35
+ currencySpace?: boolean;
36
+ }
37
+ /* eslint-enable */
38
+ /**
39
+ * Interface for grouping process
40
+ */
41
+ export interface GroupDetails {
42
+ primary?: number;
43
+ secondary?: number;
44
+ }
45
+ const errorText: Object = {
46
+ 'ms': 'minimumSignificantDigits',
47
+ 'ls': 'maximumSignificantDigits',
48
+ 'mf': 'minimumFractionDigits',
49
+ 'lf': 'maximumFractionDigits'
50
+ };
51
+ const percentSign: string = 'percentSign';
52
+ const minusSign: string = 'minusSign';
53
+ const mapper: string[] = ['infinity', 'nan', 'group', 'decimal', 'exponential'];
54
+ /**
55
+ * Module for number formatting.
56
+ *
57
+ * @private
58
+ */
59
+ export class NumberFormat {
60
+ /**
61
+ * Returns the formatter function for given skeleton.
62
+ *
63
+ * @param {string} culture - Specifies the culture name to be which formatting.
64
+ * @param {NumberFormatOptions} option - Specific the format in which number will format.
65
+ * @param {Object} cldr - Specifies the global cldr data collection.
66
+ * @returns {Function} ?
67
+ */
68
+ public static numberFormatter(culture: string, option: NumberFormatOptions, cldr: Object): Function {
69
+ const fOptions: FormatParts = extend({}, option);
70
+ let cOptions: base.GenericFormatOptions = {};
71
+ const dOptions: CommonOptions = {};
72
+ let symbolPattern: string;
73
+ const dependable: base.Dependables = base.getDependables(cldr, culture, '', true);
74
+ const numObject: Object = dependable.numericObject;
75
+ dOptions.numberMapper = isBlazor() ? extend({}, numObject) :
76
+ parser.getNumberMapper(dependable.parserObject, parser.getNumberingSystem(cldr), true);
77
+ dOptions.currencySymbol = isBlazor() ? getValue('currencySymbol', numObject) : base.getCurrencySymbol(
78
+ dependable.numericObject, fOptions.currency || defaultCurrencyCode, option.altSymbol);
79
+ /* eslint-disable @typescript-eslint/no-explicit-any */
80
+ dOptions.percentSymbol = isBlazor() ? getValue('numberSymbols.percentSign', numObject) :
81
+ (<any>dOptions).numberMapper.numberSymbols[`${percentSign}`];
82
+ dOptions.minusSymbol = isBlazor() ? getValue('numberSymbols.minusSign', numObject) :
83
+ (<any>dOptions).numberMapper.numberSymbols[`${minusSign}`];
84
+ const symbols: any = dOptions.numberMapper.numberSymbols;
85
+ if ((option.format) && !(base.formatRegex.test(option.format))) {
86
+ cOptions = base.customFormat(option.format, dOptions, dependable.numericObject);
87
+ } else {
88
+ extend(fOptions, base.getProperNumericSkeleton(option.format || 'N'));
89
+ fOptions.isCurrency = fOptions.type === 'currency';
90
+ fOptions.isPercent = fOptions.type === 'percent';
91
+ if (!isBlazor()) {
92
+ symbolPattern = base.getSymbolPattern(
93
+ fOptions.type, dOptions.numberMapper.numberSystem, dependable.numericObject, fOptions.isAccount);
94
+ }
95
+ fOptions.groupOne = this.checkValueRange(fOptions.maximumSignificantDigits, fOptions.minimumSignificantDigits, true);
96
+ this.checkValueRange(fOptions.maximumFractionDigits, fOptions.minimumFractionDigits, false, true);
97
+ if (!isUndefined(fOptions.fractionDigits)) {
98
+ fOptions.minimumFractionDigits = fOptions.maximumFractionDigits = fOptions.fractionDigits;
99
+ }
100
+ if (isUndefined(fOptions.useGrouping)) {
101
+ fOptions.useGrouping = true;
102
+ }
103
+ if (fOptions.isCurrency && !isBlazor()) {
104
+ symbolPattern = symbolPattern.replace(/\u00A4/g, base.defaultCurrency);
105
+ }
106
+ if (!isBlazor()) {
107
+ const split: string[] = symbolPattern.split(';');
108
+ cOptions.nData = base.getFormatData(split[1] || '-' + split[0], true, dOptions.currencySymbol);
109
+ cOptions.pData = base.getFormatData(split[0], false, dOptions.currencySymbol);
110
+ if (fOptions.useGrouping) {
111
+ fOptions.groupSeparator = symbols[mapper[2]];
112
+ fOptions.groupData = this.getGroupingDetails(split[0]);
113
+ }
114
+ } else {
115
+ cOptions.nData = extend({}, {}, getValue(fOptions.type + 'nData', numObject));
116
+ cOptions.pData = extend({}, {}, getValue(fOptions.type + 'pData', numObject));
117
+ if (fOptions.type === 'currency' && option.currency) {
118
+ base.replaceBlazorCurrency([cOptions.pData, cOptions.nData], dOptions.currencySymbol, option.currency);
119
+ }
120
+ }
121
+ const minFrac: boolean = isUndefined(fOptions.minimumFractionDigits);
122
+ if (minFrac) {
123
+ fOptions.minimumFractionDigits = cOptions.nData.minimumFraction;
124
+ }
125
+ if (isUndefined(fOptions.maximumFractionDigits)) {
126
+ const mval: number = cOptions.nData.maximumFraction;
127
+ fOptions.maximumFractionDigits = isUndefined(mval) && fOptions.isPercent ? 0 : mval;
128
+ }
129
+ const mfrac: number = fOptions.minimumFractionDigits;
130
+ const lfrac: number = fOptions.maximumFractionDigits;
131
+ if (!isUndefined(mfrac) && !isUndefined(lfrac)) {
132
+ if (mfrac > lfrac) {
133
+ fOptions.maximumFractionDigits = mfrac;
134
+ }
135
+ }
136
+ }
137
+ extend(cOptions.nData, fOptions);
138
+ extend(cOptions.pData, fOptions);
139
+ return (value: number): string => {
140
+ if (isNaN(value)) {
141
+ return symbols[mapper[1]];
142
+ } else if (!isFinite(value)) {
143
+ return symbols[mapper[0]];
144
+ }
145
+ return this.intNumberFormatter(value, cOptions, dOptions, option);
146
+ };
147
+ }
148
+ /**
149
+ * Returns grouping details for the pattern provided
150
+ *
151
+ * @param {string} pattern ?
152
+ * @returns {GroupDetails} ?
153
+ */
154
+ public static getGroupingDetails(pattern: string): GroupDetails {
155
+ const ret: GroupDetails = {};
156
+ const match: string[] = pattern.match(base.negativeDataRegex);
157
+ if (match && match[4]) {
158
+ const pattern: string = match[4];
159
+ const p: number = pattern.lastIndexOf(',');
160
+ if (p !== -1) {
161
+ const temp: string = pattern.split('.')[0];
162
+ ret.primary = (temp.length - p) - 1;
163
+ const s: number = pattern.lastIndexOf(',', p - 1);
164
+ if (s !== -1) {
165
+ ret.secondary = p - 1 - s;
166
+ }
167
+ }
168
+ }
169
+ return ret;
170
+ }
171
+ /**
172
+ * Returns if the provided integer range is valid.
173
+ *
174
+ * @param {number} val1 ?
175
+ * @param {number} val2 ?
176
+ * @param {boolean} checkbothExist ?
177
+ * @param {boolean} isFraction ?
178
+ * @returns {boolean} ?
179
+ */
180
+ private static checkValueRange(val1: number, val2: number, checkbothExist: boolean, isFraction?: true): boolean {
181
+ const decide: string = isFraction ? 'f' : 's';
182
+ let dint: number = 0;
183
+ const str1: string = (<any>errorText)['l' + decide];
184
+ // eslint-disable-next-line
185
+ let str2: string = (<any>errorText)['m' + decide];
186
+ if (!isUndefined(val1)) {
187
+ this.checkRange(val1, str1, isFraction);
188
+ dint++;
189
+ }
190
+ if (!isUndefined(val2)) {
191
+ this.checkRange(val2, str2, isFraction);
192
+ dint++;
193
+ }
194
+ if (dint === 2) {
195
+ if (val1 < val2) {
196
+ throwError(str2 + 'specified must be less than the' + str1);
197
+ } else {
198
+ return true;
199
+ }
200
+ } else if (checkbothExist && dint === 1) {
201
+ throwError('Both' + str2 + 'and' + str2 + 'must be present');
202
+ }
203
+ return false;
204
+ }
205
+ /**
206
+ * Check if the provided fraction range is valid
207
+ *
208
+ * @param {number} val ?
209
+ * @param {string} text ?
210
+ * @param {boolean} isFraction ?
211
+ * @returns {void} ?
212
+ */
213
+ private static checkRange(val: number, text: string, isFraction?: boolean): void {
214
+ const range: number[] = isFraction ? [0, 20] : [1, 21];
215
+ if (val < range[0] || val > range[1]) {
216
+ throwError(text + 'value must be within the range' + range[0] + 'to' + range[1]);
217
+ }
218
+ }
219
+ /**
220
+ * Returns formatted numeric string for provided formatting options
221
+ *
222
+ * @param {number} value ?
223
+ * @param {base.GenericFormatOptions} fOptions ?
224
+ * @param {CommonOptions} dOptions ?
225
+ * @param {NumberFormatOptions} [option] ?
226
+ * @returns {string} ?
227
+ */
228
+ private static intNumberFormatter(value: number, fOptions: base.GenericFormatOptions, dOptions: CommonOptions,
229
+ option ?: NumberFormatOptions): string {
230
+ let curData: base.NegativeData;
231
+ if (isUndefined(fOptions.nData.type)) {
232
+ return undefined;
233
+ } else {
234
+ if (value < 0) {
235
+ value = value * -1;
236
+ curData = fOptions.nData;
237
+ } else if (value === 0) {
238
+ curData = fOptions.zeroData || fOptions.pData;
239
+ } else {
240
+ curData = fOptions.pData;
241
+ }
242
+ let fValue: string = '';
243
+ if (curData.isPercent) {
244
+ value = value * 100;
245
+ }
246
+ if (curData.groupOne) {
247
+ fValue = this.processSignificantDigits(value, curData.minimumSignificantDigits, curData.maximumSignificantDigits);
248
+ } else {
249
+ fValue = this.processFraction(value, curData.minimumFractionDigits, curData.maximumFractionDigits, option);
250
+ if (curData.minimumIntegerDigits) {
251
+ fValue = this.processMinimumIntegers(fValue, curData.minimumIntegerDigits);
252
+ }
253
+ if (dOptions.isCustomFormat && curData.minimumFractionDigits < curData.maximumFractionDigits
254
+ && /\d+\.\d+/.test(fValue)) {
255
+ const temp: string[] = fValue.split('.');
256
+ let decimalPart: string = temp[1];
257
+ const len: number = decimalPart.length;
258
+ for (let i: number = len - 1; i >= 0; i--) {
259
+ if (decimalPart[`${i}`] === '0' && i >= curData.minimumFractionDigits) {
260
+ decimalPart = decimalPart.slice(0, i);
261
+ } else {
262
+ break;
263
+ }
264
+ }
265
+ fValue = temp[0] + '.' + decimalPart;
266
+ }
267
+ }
268
+ if (curData.type === 'scientific') {
269
+ fValue = value.toExponential(curData.maximumFractionDigits);
270
+ fValue = fValue.replace('e', dOptions.numberMapper.numberSymbols[mapper[4]]);
271
+ }
272
+ fValue = fValue.replace('.', (<any>dOptions).numberMapper.numberSymbols[mapper[3]]);
273
+ fValue = curData.format === '#,###,,;(#,###,,)' ? this.customPivotFormat(parseInt(fValue, 10)) : fValue;
274
+ if (curData.useGrouping) {
275
+ /* eslint-disable @typescript-eslint/no-explicit-any */
276
+ fValue = this.groupNumbers(
277
+ fValue, curData.groupData.primary, curData.groupSeparator || ',',
278
+ (<any>dOptions).numberMapper.numberSymbols[mapper[3]] || '.', curData.groupData.secondary);
279
+ }
280
+ fValue = parser.convertValueParts(fValue, base.latnParseRegex, dOptions.numberMapper.mapper);
281
+ if (curData.nlead === 'N/A') {
282
+ return curData.nlead;
283
+ } else {
284
+ if (fValue === '0' && option && option.format === '0') {
285
+ return fValue + curData.nend;
286
+ }
287
+ return curData.nlead + fValue + curData.nend;
288
+ }
289
+ }
290
+ }
291
+ /**
292
+ * Returns significant digits processed numeric string
293
+ *
294
+ * @param {number} value ?
295
+ * @param {number} min ?
296
+ * @param {number} max ?
297
+ * @returns {string} ?
298
+ */
299
+ private static processSignificantDigits(value: number, min: number, max: number): string {
300
+ let temp: string = value + '';
301
+ let tn: number;
302
+ const length: number = temp.length;
303
+ if (length < min) {
304
+ return value.toPrecision(min);
305
+ } else {
306
+ temp = value.toPrecision(max);
307
+ tn = +temp;
308
+ return tn + '';
309
+ }
310
+ }
311
+ /**
312
+ * Returns grouped numeric string
313
+ *
314
+ * @param {string} val ?
315
+ * @param {number} level1 ?
316
+ * @param {string} sep ?
317
+ * @param {string} decimalSymbol ?
318
+ * @param {number} level2 ?
319
+ * @returns {string} ?
320
+ */
321
+ private static groupNumbers(val: string, level1: number, sep: string, decimalSymbol: string, level2?: number): string {
322
+ let flag: boolean = !isNullOrUndefined(level2) && level2 !== 0;
323
+ const split: string[] = val.split(decimalSymbol);
324
+ const prefix: string = split[0];
325
+ let length: number = prefix.length;
326
+ let str: string = '';
327
+ while (length > level1) {
328
+ str = prefix.slice(length - level1, length) + (str.length ?
329
+ (sep + str) : '');
330
+ length -= level1;
331
+ if (flag) {
332
+ level1 = level2;
333
+ flag = false;
334
+ }
335
+ }
336
+ split[0] = prefix.slice(0, length) + (str.length ? sep : '') + str;
337
+ return split.join(decimalSymbol);
338
+ }
339
+ /**
340
+ * Returns fraction processed numeric string
341
+ *
342
+ * @param {number} value ?
343
+ * @param {number} min ?
344
+ * @param {number} max ?
345
+ * @param {NumberFormatOptions} [option] ?
346
+ * @returns {string} ?
347
+ */
348
+ private static processFraction(value: number, min: number, max: number, option ?: NumberFormatOptions): string {
349
+ const temp: string = (value + '').split('.')[1];
350
+ const length: number = temp ? temp.length : 0;
351
+ if (min && length < min) {
352
+ let ret: string = '';
353
+ if (length === 0) {
354
+ ret = value.toFixed(min);
355
+ } else {
356
+ ret += value;
357
+ for (let j: number = 0; j < min - length; j++) {
358
+ ret += '0';
359
+ }
360
+ return ret;
361
+ }
362
+ return value.toFixed(min);
363
+ } else if (!isNullOrUndefined(max) && (length > max || max === 0)) {
364
+ return value.toFixed(max);
365
+ }
366
+ let str: string = value + '';
367
+ if (str[0] === '0' && option && option.format === '###.00')
368
+ {
369
+ str = str.slice(1);
370
+ }
371
+ return str;
372
+ }
373
+ /**
374
+ * Returns integer processed numeric string
375
+ *
376
+ * @param {string} value ?
377
+ * @param {number} min ?
378
+ * @returns {string} ?
379
+ */
380
+ private static processMinimumIntegers(value: string, min: number): string {
381
+ const temp: string[] = value.split('.');
382
+ let lead: string = temp[0];
383
+ const len: number = lead.length;
384
+ if (len < min) {
385
+ for (let i: number = 0; i < min - len; i++) {
386
+ lead = '0' + lead;
387
+ }
388
+ temp[0] = lead;
389
+ }
390
+ return temp.join('.');
391
+ }
392
+
393
+ /**
394
+ * Returns custom format for pivot table
395
+ *
396
+ * @param {number} value ?
397
+ * @returns {string} ?
398
+ */
399
+ private static customPivotFormat(value: number): string {
400
+ if (value >= 500000) {
401
+ value /= 1000000;
402
+ // eslint-disable-next-line
403
+ const [integer, decimal] = value.toString().split('.');
404
+ return decimal && +decimal.substring(0, 1) >= 5
405
+ ? Math.ceil(value).toString()
406
+ : Math.floor(value).toString();
407
+ }
408
+ return '';
409
+ }
410
+
411
+ }
@@ -0,0 +1,158 @@
1
+ import { NumberFormatOptions } from '../internationalization';
2
+ import { extend, isNullOrUndefined, isBlazor, getValue } from '../util';
3
+ import { ParserBase as parser, NumericOptions } from './parser-base';
4
+ import { IntlBase as base } from './intl-base';
5
+ const regExp: RegExpConstructor = RegExp;
6
+ // eslint-disable-next-line
7
+ const parseRegex: RegExp = new regExp('^([^0-9]*)' + '(([0-9,]*[0-9]+)(\.[0-9]+)?)' + '([Ee][+-]?[0-9]+)?([^0-9]*)$');
8
+ const groupRegex: RegExp = /,/g;
9
+
10
+ const keys: string[] = ['minusSign', 'infinity'];
11
+ /**
12
+ * interface for Numeric Formatting Parts
13
+ */
14
+ export interface NumericParts {
15
+ symbolRegex?: RegExp;
16
+ nData?: base.NegativeData;
17
+ pData?: base.NegativeData;
18
+ infinity?: string;
19
+ type?: string;
20
+ fractionDigits?: number;
21
+ isAccount?: boolean;
22
+ custom?: boolean;
23
+ maximumFractionDigits?: number;
24
+ }
25
+ /**
26
+ * interface for numeric parse options
27
+ */
28
+ // eslint-disable-next-line
29
+ interface NumberParseOptions {
30
+ parseRegex: string;
31
+ numbericMatcher: Object;
32
+ }
33
+
34
+
35
+ /**
36
+ * Module for Number Parser.
37
+ *
38
+ * @private
39
+ */
40
+ export class NumberParser {
41
+ /**
42
+ * Returns the parser function for given skeleton.
43
+ *
44
+ * @param {string} culture - Specifies the culture name to be which formatting.
45
+ * @param {NumberFormatOptions} option - Specific the format in which number will parsed.
46
+ * @param {Object} cldr - Specifies the global cldr data collection.
47
+ * @returns {Function} ?
48
+ */
49
+ public static numberParser(culture: string, option: NumberFormatOptions, cldr: Object): Function {
50
+ const dependable: base.Dependables = base.getDependables(cldr, culture, '', true);
51
+ const parseOptions: NumericParts = { custom: true };
52
+ let numOptions: NumericOptions;
53
+ if ((base.formatRegex.test(option.format)) || !(option.format)) {
54
+ extend(parseOptions, base.getProperNumericSkeleton(option.format || 'N'));
55
+ parseOptions.custom = false;
56
+ if (!parseOptions.fractionDigits) {
57
+ if (option.maximumFractionDigits) {
58
+ parseOptions.maximumFractionDigits = option.maximumFractionDigits;
59
+ }
60
+ }
61
+ } else {
62
+ extend(parseOptions, base.customFormat(option.format, null, null));
63
+ }
64
+ const numbers: Object = getValue('numbers', dependable.parserObject);
65
+ // eslint-disable-next-line
66
+ numOptions = parser.getCurrentNumericOptions(dependable.parserObject, parser.getNumberingSystem(cldr), true, isBlazor());
67
+ parseOptions.symbolRegex = parser.getSymbolRegex(Object.keys(numOptions.symbolMatch));
68
+ // eslint-disable-next-line
69
+ parseOptions.infinity = (<any>numOptions).symbolNumberSystem[keys[1]];
70
+ let symbolpattern: string;
71
+ if (!isBlazor()) {
72
+ symbolpattern = base.getSymbolPattern(
73
+ parseOptions.type, numOptions.numberSystem, dependable.numericObject, parseOptions.isAccount);
74
+ if (symbolpattern) {
75
+ symbolpattern = symbolpattern.replace(/\u00A4/g, base.defaultCurrency);
76
+ const split: string[] = symbolpattern.split(';');
77
+ parseOptions.nData = base.getFormatData(split[1] || '-' + split[0], true, '');
78
+ parseOptions.pData = base.getFormatData(split[0], true, '');
79
+ }
80
+ } else {
81
+ parseOptions.nData = extend({}, {}, getValue(parseOptions.type + 'nData', numbers));
82
+ parseOptions.pData = extend({}, {}, getValue(parseOptions.type + 'pData', numbers));
83
+ if (parseOptions.type === 'currency' && option.currency) {
84
+ base.replaceBlazorCurrency([parseOptions.pData, parseOptions.nData], getValue('currencySymbol', numbers), option.currency);
85
+ }
86
+ }
87
+
88
+ return (value: string): number => {
89
+ return this.getParsedNumber(value, parseOptions, numOptions);
90
+ };
91
+ }
92
+ /**
93
+ * Returns parsed number for the provided formatting options
94
+ *
95
+ * @param {string} value ?
96
+ * @param {NumericParts} options ?
97
+ * @param {NumericOptions} numOptions ?
98
+ * @returns {number} ?
99
+ */
100
+ private static getParsedNumber(value: string, options: NumericParts, numOptions: NumericOptions): number {
101
+ let isNegative: boolean;
102
+ let isPercent: boolean;
103
+ let tempValue: string;
104
+ let lead: string;
105
+ let end: string;
106
+ let ret: number;
107
+ if (value.indexOf(options.infinity) !== -1) {
108
+ return Infinity;
109
+ } else {
110
+ value = parser.convertValueParts(value, options.symbolRegex, numOptions.symbolMatch);
111
+ value = parser.convertValueParts(value, numOptions.numberParseRegex, numOptions.numericPair);
112
+ value = value.indexOf('-') !== -1 ? value.replace('-.', '-0.') : value;
113
+ if (value.indexOf('.') === 0) {
114
+ value = '0' + value;
115
+ }
116
+ const matches: string[] = value.match(parseRegex);
117
+ if (isNullOrUndefined(matches)) {
118
+ return NaN;
119
+ }
120
+ lead = matches[1];
121
+ tempValue = matches[2];
122
+ const exponent: string = matches[5];
123
+ end = matches[6];
124
+ isNegative = options.custom ? ((lead === options.nData.nlead) && (end === options.nData.nend)) :
125
+ ((lead.indexOf(options.nData.nlead) !== -1) && (end.indexOf(options.nData.nend) !== -1));
126
+ isPercent = isNegative ?
127
+ options.nData.isPercent :
128
+ options.pData.isPercent;
129
+ tempValue = tempValue.replace(groupRegex, '');
130
+ if (exponent) {
131
+ tempValue += exponent;
132
+ }
133
+ ret = +tempValue;
134
+ if (options.type === 'percent' || isPercent) {
135
+ ret = ret / 100;
136
+ }
137
+ if (options.custom || options.fractionDigits) {
138
+ ret = parseFloat(ret.toFixed(options.custom ?
139
+ (isNegative ? options.nData.maximumFractionDigits : options.pData.maximumFractionDigits) : options.fractionDigits));
140
+ }
141
+ if (options.maximumFractionDigits) {
142
+ ret = this.convertMaxFracDigits(tempValue, options, ret, isNegative);
143
+ }
144
+ if (isNegative) {
145
+ ret *= -1;
146
+ }
147
+ return ret;
148
+ }
149
+ }
150
+ private static convertMaxFracDigits(value: string, options: NumericParts, ret: number, isNegative: boolean): number {
151
+ const decimalSplitValue: string[] = value.split('.');
152
+ if (decimalSplitValue[1] && decimalSplitValue[1].length > options.maximumFractionDigits) {
153
+ ret = +(ret.toFixed(options.custom ?
154
+ (isNegative ? options.nData.maximumFractionDigits : options.pData.maximumFractionDigits) : options.maximumFractionDigits));
155
+ }
156
+ return ret;
157
+ }
158
+ }