@refinitiv-ui/efx-grid 6.0.40 → 6.0.41

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 (30) hide show
  1. package/lib/column-selection-dialog/lib/column-selection-dialog.d.ts +2 -1
  2. package/lib/column-selection-dialog/lib/column-selection-dialog.js +23 -7
  3. package/lib/core/dist/core.js +25 -26
  4. package/lib/core/dist/core.min.js +1 -1
  5. package/lib/core/es6/grid/Core.js +25 -26
  6. package/lib/grid/index.js +1 -1
  7. package/lib/rt-grid/dist/rt-grid.js +2083 -1753
  8. package/lib/rt-grid/dist/rt-grid.min.js +1 -1
  9. package/lib/rt-grid/es6/Grid.js +55 -7
  10. package/lib/rt-grid/es6/RowDefinition.d.ts +2 -2
  11. package/lib/rt-grid/es6/RowDefinition.js +37 -18
  12. package/lib/tr-grid-column-grouping/es6/ColumnGrouping.js +26 -40
  13. package/lib/tr-grid-util/es6/CellPainter.d.ts +2 -1
  14. package/lib/tr-grid-util/es6/CellPainter.js +6 -4
  15. package/lib/tr-grid-util/es6/ExpressionParser.d.ts +10 -0
  16. package/lib/tr-grid-util/es6/ExpressionParser.js +366 -0
  17. package/lib/tr-grid-util/es6/FilterBuilder.d.ts +10 -6
  18. package/lib/tr-grid-util/es6/FilterBuilder.js +264 -234
  19. package/lib/tr-grid-util/es6/FilterOperators.d.ts +3 -1
  20. package/lib/tr-grid-util/es6/FilterOperators.js +51 -2
  21. package/lib/tr-grid-util/es6/Util.d.ts +0 -3
  22. package/lib/tr-grid-util/es6/Util.js +0 -53
  23. package/lib/tr-grid-util/es6/formula/Formula.js +3 -3
  24. package/lib/types/es6/ColumnDragging.d.ts +51 -0
  25. package/lib/types/es6/ExtensionOptions.d.ts +2 -0
  26. package/lib/types/es6/Extensions.d.ts +3 -1
  27. package/lib/types/es6/RealtimeGrid/RowDefinition.d.ts +2 -2
  28. package/lib/types/es6/index.d.ts +1 -0
  29. package/lib/versions.json +3 -3
  30. package/package.json +1 -1
@@ -1,11 +1,13 @@
1
- import { parseCondition } from "./Util.js";
2
- import { DateTime } from "./DateTime.js";
3
- import { FilterOperators } from "./FilterOperators.js";
1
+ import { FilterOperators, OperatorFunctions } from "./FilterOperators.js";
2
+ import { ExpressionParser } from "./ExpressionParser.js";
4
3
 
5
4
  /** @typedef {Object} FilterBuilder~Options
6
- * @property {string} field
7
- * @property {Function=} formatter
8
- * @property {string=} formattedField
5
+ * @property {(string|null)=} field=null
6
+ * @property {Function=} formatter=null
7
+ * @property {string=} formattedField=""
8
+ * @property {boolean=} useUTCTime=false A flag used for selecting time between local time and UTC time from the given input in a filter condition. This flag does not apply to Date objects stored in a grid
9
+ * @property {Function=} rawDataAccessor=null
10
+ * @property {Function=} formattedDataAccessor=null
9
11
  */
10
12
 
11
13
  /** @typedef {Array} FilterBuilder~Condition
@@ -20,7 +22,7 @@ import { FilterOperators } from "./FilterOperators.js";
20
22
  */
21
23
 
22
24
  /** @private
23
- * @type {Object.<string, string>}
25
+ * @type {Object.<string, number>}
24
26
  * @const
25
27
  */
26
28
  var connectorMap = {
@@ -33,11 +35,166 @@ var connectorMap = {
33
35
 
34
36
  /** @private
35
37
  * @function
36
- * @param {string|null} str
38
+ * @param {*} val
39
+ * @return {number}
40
+ */
41
+ var convertToNumber = function(val) {
42
+ if(typeof val === "number") {
43
+ return val;
44
+ }
45
+ if(val) {
46
+ // WARNING: spaces (" ") and newline ("\n") characters could be parsed as 0
47
+ // TODO: Check if we need to use parseFloat instead of Number
48
+ return Number(val); // Could return NaN. true value will be converted to 1
49
+ }
50
+ if(val === false) {
51
+ return 0;
52
+ }
53
+ return NaN; // null, NaN, undefined, empty string
54
+ };
55
+ /** @private
56
+ * @function
57
+ * @param {*} val
37
58
  * @return {string}
38
59
  */
39
- var toJsConnector = function(str) {
40
- return connectorMap[str] ? "||" : "&&";
60
+ var convertToString = function(val) {
61
+ if(typeof val === "string") {
62
+ return val;
63
+ }
64
+ if(val) {
65
+ return val + "";
66
+ }
67
+ if(val === 0) {
68
+ return "0";
69
+ }
70
+ if(val === false) {
71
+ return "false";
72
+ }
73
+ return ""; // null, NaN, undefined
74
+ };
75
+ /** Retrieve date part and ignore time part from the Date object
76
+ * @private
77
+ * @function
78
+ * @param {Date} dateObj
79
+ * @param {boolean=} useUTCTime
80
+ * @return {number}
81
+ */
82
+ var convertToDateValue = function(dateObj, useUTCTime) {
83
+ if(dateObj && dateObj.getTime) {
84
+ if(useUTCTime) {
85
+ return dateObj.getUTCFullYear() * 10000 + dateObj.getUTCMonth() * 100 + dateObj.getUTCDate();
86
+ } else {
87
+ return dateObj.getFullYear() * 10000 + dateObj.getMonth() * 100 + dateObj.getDate();
88
+ }
89
+ }
90
+ return NaN;
91
+ };
92
+ /** @private
93
+ * @function
94
+ * @param {Object} ctx
95
+ * @param {Object} rowData
96
+ * @return {boolean}
97
+ */
98
+ var _filterByConditions = function(ctx, rowData) {
99
+ var conds = ctx._conds;
100
+ var condCount = conds ? conds.length : 0;
101
+
102
+ if(!condCount) {
103
+ return true; // There is no filter condition
104
+ }
105
+
106
+ var fieldName = ctx._fieldName;
107
+ var fmtFieldName = ctx._formattedFieldName;
108
+
109
+ var val = rowData[fieldName];
110
+ if(ctx._rawDataAccessor) {
111
+ val = ctx._rawDataAccessor(val);
112
+ }
113
+ var str, num, dateVal; // intentionally left undefined
114
+ var finalResult = false;
115
+ var result = false;
116
+ for(var i = 0; i < condCount; ++i) {
117
+ var orConnector = 0;
118
+ if(i > 0) {
119
+ orConnector = connectorMap[conds[i - 1].connector];
120
+ // TODO: AND operator has higher precedence than OR operator
121
+ if(orConnector) {
122
+ if(finalResult) {
123
+ return true; // Since OR operator is performed last, it can basically override everything
124
+ }
125
+ } else if(!finalResult) { // And connector
126
+ continue; // AND operator has to be perfomed before OR operator
127
+ }
128
+ }
129
+
130
+ var cond = conds[i];
131
+ var opDef = FilterOperators[cond.operatorId];
132
+ result = false;
133
+
134
+ var opType = opDef.type;
135
+ var opId = opDef.id;
136
+ var opFunc = OperatorFunctions[opId];
137
+ if(opType === "blank") {
138
+ result = opFunc(val);
139
+ } else if(opType === "number") {
140
+ if(num == null) {
141
+ num = convertToNumber(val);
142
+ }
143
+
144
+ result = opFunc(num, cond.value);
145
+ } else if(opType === "date") {
146
+ if(dateVal == null) {
147
+ dateVal = convertToDateValue(val, false); // Even though date is stored as UTC time, we use local time for filtering
148
+ }
149
+
150
+ result = opFunc(dateVal, cond.value);
151
+ } else { // string type
152
+ if(str == null) {
153
+ if(ctx._formattedDataAccessor) {
154
+ str = ctx._formattedDataAccessor(rowData[fieldName]);
155
+ } else if(ctx._formatter) {
156
+ str = ctx._formatter(rowData);
157
+ } else if(fmtFieldName !== fieldName) {
158
+ str = rowData[fmtFieldName];
159
+ if(str == null) {
160
+ str = val;
161
+ }
162
+ } else {
163
+ str = val;
164
+ }
165
+ str = convertToString(str);
166
+ if(!opDef.caseSensitive) {
167
+ str = str.toLowerCase();
168
+ }
169
+ }
170
+
171
+ result = opFunc(str, cond.value);
172
+ }
173
+ if(i > 0) {
174
+ if(orConnector) {
175
+ finalResult = (finalResult || result);
176
+ } else {
177
+ finalResult = (finalResult && result);
178
+ }
179
+ } else {
180
+ finalResult = result;
181
+ }
182
+ }
183
+ return finalResult;
184
+ };
185
+ /** @private
186
+ * @function
187
+ * @param {Object} ctx
188
+ * @param {Object} rowData
189
+ * @return {boolean}
190
+ */
191
+ var _filterByObjectMap = function(ctx, rowData) {
192
+ var val = rowData[ctx._fieldName];
193
+ if(ctx._rawDataAccessor) {
194
+ val = ctx._rawDataAccessor(val);
195
+ }
196
+
197
+ return ctx._itemMap[val] ? true : false;
41
198
  };
42
199
 
43
200
  /** @private
@@ -48,7 +205,7 @@ var toJsConnector = function(str) {
48
205
  var conditionToArray = function(cond) {
49
206
  return [
50
207
  cond.operatorId,
51
- cond.value,
208
+ cond.origValue,
52
209
  cond.connector
53
210
  ];
54
211
  };
@@ -92,6 +249,10 @@ FilterBuilder.prototype._formattedFieldName = "";
92
249
  * @private
93
250
  */
94
251
  FilterBuilder.prototype._formatter = null;
252
+ /** @type {boolean}
253
+ * @private
254
+ */
255
+ FilterBuilder.prototype._useUTCTime = false;
95
256
  /** @type {Function}
96
257
  * @private
97
258
  */
@@ -143,6 +304,19 @@ FilterBuilder.prototype.init = function(options) {
143
304
  var field = options["field"];
144
305
  if(field) {
145
306
  this.setFieldDefinition(field, options["formatter"], options["formattedField"]);
307
+ } else if(field != null) {
308
+ this.setFieldDefinition("");
309
+ }
310
+
311
+ var useUTCTime = options["useUTCTime"];
312
+ if(useUTCTime != null) {
313
+ this._useUTCTime = useUTCTime ? true : false;
314
+ }
315
+
316
+ var rawDataAccessor = options["rawDataAccessor"];
317
+ var formattedDataAccessor = options["formattedDataAccessor"];
318
+ if(rawDataAccessor != null || formattedDataAccessor != null) {
319
+ this.setDataAccessors(rawDataAccessor, formattedDataAccessor);
146
320
  }
147
321
  };
148
322
 
@@ -152,11 +326,18 @@ FilterBuilder.prototype.init = function(options) {
152
326
  * @param {string=} formattedField
153
327
  */
154
328
  FilterBuilder.prototype.setFieldDefinition = function(fieldName, formatter, formattedField) {
155
- this._fieldName = fieldName;
156
- this._formattedFieldName = (formattedField) ? formattedField : fieldName + "_FORMATTED";
329
+ this._fieldName = fieldName; // Quote/doublequote characters don't need to be escaped as eval has been removed
330
+ this._formattedFieldName = (formattedField) ? formattedField : this._fieldName + "_FORMATTED";
157
331
  this._formatter = formatter || null;
158
332
  this._conditions.length = 0;
159
333
  };
334
+ /** Set UTC usage flag. This flag is used for selecting time between local time and UTC time from the given input in a filter condition. This flag does not apply to Date objects stored in a grid
335
+ * @public
336
+ * @param {boolean} useUTCTime
337
+ */
338
+ FilterBuilder.prototype.setDefaultUTCUsage = function(useUTCTime) {
339
+ this._useUTCTime = useUTCTime ? true : false;
340
+ };
160
341
  /** @public
161
342
  * @param {Function=} rawDataAccessor Raw data getter for custom data type
162
343
  * @param {Function=} formattedDataAccessor Formatted data getter for custom data type. If this is specified, formatter and formattedField will be overriden.
@@ -167,33 +348,35 @@ FilterBuilder.prototype.setDataAccessors = function(rawDataAccessor, formattedDa
167
348
  };
168
349
  /** @public
169
350
  * @param {string} oper Operator id (e.g., "GT", "CONT", "EQ")
170
- * @param {string|number} value
351
+ * @param {string|number|Date} value If date type operator is specified, this should be accompanied with useUTCTime flag to indicate whether local or UTC time to be used.
171
352
  * @param {string=} connector Possible values are "OR" and "AND"
172
- * @param {boolean=} useUTCTime If false use local time for filtering
353
+ * @param {boolean=} useUTCTime If the value is not specified, the default setting will be used
173
354
  * @return {boolean} Return true, if the new condition is added
174
355
  */
175
356
  FilterBuilder.prototype.addCondition = function (oper, value, connector, useUTCTime) {
176
- oper = oper ? oper.toUpperCase() : "";
177
- var opDef = FilterOperators[oper];
357
+ var opId = oper ? oper.toUpperCase() : "";
358
+ var opDef = FilterOperators[opId];
178
359
  if (!opDef) {
179
360
  return false; // Unknown operation
180
361
  }
181
362
 
182
363
  if (value === "{}" || value === "{*}") { // ignore operator if the value is BLANK or NON-BLANK
183
- oper = (opDef.positive ^ value === "{}") ? "EQ_NBLANK" : "EQ_BLANK";
184
- opDef = FilterOperators[oper];
185
- } else if (!value) {
364
+ opId = (opDef.positive ^ value === "{}") ? "EQ_NBLANK" : "EQ_BLANK";
365
+ opDef = FilterOperators[opId];
366
+ } else if (!value && opDef.type !== "blank") {
186
367
  if(value !== 0 && value !== false) {
187
368
  return false; // Invalid comparer value ("", null, undefined, NaN)
188
369
  }
189
370
  }
190
-
191
- this._conditions.push({
192
- operatorId: oper,
193
- value: value,
194
- connector: connector || "",
195
- useUTCTime: useUTCTime
196
- });
371
+ var cond = {
372
+ operatorId: opId,
373
+ origValue: value,
374
+ connector: connector || ""
375
+ };
376
+ if(useUTCTime != null) {
377
+ cond.useUTCTime = useUTCTime;
378
+ }
379
+ this._conditions.push(cond);
197
380
 
198
381
  return true;
199
382
  };
@@ -236,192 +419,65 @@ FilterBuilder.prototype.getConditions = function () {
236
419
  * @return {Function} Filter function that takes rowData object
237
420
  */
238
421
  FilterBuilder.prototype.buildFilter = function() {
239
- if (!this._fieldName) { return null; }
240
- var len = this._conditions.length;
241
- if(!len) { return null; }
242
-
243
- var i, opDef;
244
- var hasTextOp = 0; // EQ, NEQ, BEGIN, NBEGIN, END, NEND, CONT, NCONT
245
- var hasCaseInsensitiveOp = 0; // BEGIN, NBEGIN, END, NEND, CONT, NCONT
246
- var hasNumberOp = 0; // GT, GTE, LT, LTE
247
- var hasDateOp = 0;
248
- // var hasBlankOp = 0; // EQ_BLANK, EQ_NBLANK
249
-
250
- // Collect filter info
251
- for (i = 0; i < len; i++) {
252
- opDef = FilterOperators[this._conditions[i].operatorId];
253
- if(opDef.type === "string") {
254
- ++hasTextOp;
255
- }
256
- if(opDef.type === "number") {
257
- ++hasNumberOp;
258
- }
259
- if(opDef.type === "date") {
260
- ++hasDateOp;
261
- }
262
- if(!opDef.caseSensitive) {
263
- ++hasCaseInsensitiveOp;
264
- }
422
+ if (!this._fieldName) {
423
+ return null;
265
424
  }
266
- var fieldName = this._fieldName;
267
- var fmtFieldName = this._formattedFieldName;
268
- var escapedFieldName = FilterBuilder._escapeQuotes(fieldName);
269
-
270
- var contextObj = null;
271
- var filterStr = ["var val = rowData['" + escapedFieldName + "'];"];
272
-
273
- if(this._rawDataAccessor) {
274
- if(!contextObj) {
275
- contextObj = {};
276
- }
277
- contextObj["rawDataAccessor"] = this._rawDataAccessor;
278
- filterStr.push("val = this.rawDataAccessor(val);");
425
+ var condCount = this._conditions.length;
426
+ if(!condCount) {
427
+ return null;
279
428
  }
280
429
 
281
- // Prepare row-data
282
- if(hasTextOp || hasNumberOp) { // For mixed data type column
283
- filterStr.push("if(!val && val !== 0) { val = NaN; }"); // TODO: support false boolean value
284
- if(hasTextOp) {
285
- if(this._formattedDataAccessor) {
286
- if(!contextObj) {
287
- contextObj = {};
288
- }
289
- contextObj["formattedDataAccessor"] = this._formattedDataAccessor;
290
- filterStr.push("var str = this.formattedDataAccessor(rowData['" + escapedFieldName + "']);");
291
- } else if(this._formatter) {
292
- if(!contextObj) {
293
- contextObj = {};
294
- }
295
- contextObj["format"] = this._formatter;
296
- filterStr.push("var str = this.format(rowData);");
297
- } else if(fmtFieldName !== fieldName) {
298
- filterStr.push("var str = rowData['" + FilterBuilder._escapeQuotes(fmtFieldName) + "'];");
299
- filterStr.push("if(!str && str !== 0) {"); // TODO: support false boolean value
300
- filterStr.push(" str = (!val && val !== 0) ? '' : val + '';");
301
- filterStr.push("}");
302
- } else {
303
- filterStr.push("var str = (!val && val !== 0) ? '' : val + '';"); // TODO: support false boolean value
430
+ // Prepare user value to be in ready to use form to boost performance
431
+ var formatter = this._formatter;
432
+ var conds = this._conditions.slice();
433
+ for(var i = 0; i < condCount; ++i) {
434
+ var cond = conds[i];
435
+ var opDef = FilterOperators[cond.operatorId];
436
+ var opType = opDef.type;
437
+ var value = cond.origValue;
438
+
439
+ if(opType === "number") {
440
+ value = convertToNumber(value);
441
+ } else if(opType === "date") {
442
+ var dateObj = null;
443
+ if(value instanceof Date) {
444
+ dateObj = value;
445
+ } else if(typeof value === "number" || typeof value === "string") {
446
+ dateObj = new Date(value);
304
447
  }
305
-
306
- if(hasCaseInsensitiveOp) {
307
- filterStr.push("if(str) { str = str.toLowerCase(); };");
448
+ value = convertToDateValue(
449
+ dateObj,
450
+ cond.useUTCTime != null ? cond.useUTCTime : this._useUTCTime
451
+ );
452
+ } else if(opType === "string") {
453
+ if(formatter) { // WARNING: This is not in sync when _formattedDataAccessor exists
454
+ var dummyRow = {};
455
+ dummyRow[fieldName] = inputStr;
456
+ dummyRow[fmtFieldName] = inputStr;
457
+ value = formatter(dummyRow); // WARNING: dummyRow may not provide enough data for formatting correctly
308
458
  }
309
- }
310
- if (hasNumberOp && fieldName.indexOf("FREE_TEXT") !== -1) {
311
- filterStr.push("val = !isNaN(Number(val)) ? Number(val) : val;");
312
- }
313
- } else if(hasDateOp) {
314
- filterStr.push("var ts = 0;");
315
- filterStr.push("if(!val || val != val || !val.getTime) {");
316
- filterStr.push(" return false;");
317
- filterStr.push("}");
318
- }
319
-
320
- // Compose condition string
321
- var condStr = [];
322
- for (i = 0; i < len; i++) {
323
- if (i > 0) {
324
- condStr.push(toJsConnector(this._conditions[i - 1].connector));
325
- }
326
-
327
- var cond = this._conditions[i];
328
- opDef = FilterOperators[cond.operatorId];
329
-
330
- if(opDef.type === "blank") { // Blank checking operation (EQ_BLANK, and EQ_NBLANK) requires no data transformation
331
- condStr.push("(" + opDef.formula + ")");
332
- continue;
333
- }
334
-
335
- // Prepare input-value
336
- var inputVal = cond.value; // Expect input value to already be formatted value or raw value
337
- if(opDef.type === "string") {
338
- if(typeof inputVal !== "string") {
339
- if(this._formatter) {
340
- var dummyRow = {};
341
- dummyRow[fieldName] = inputVal;
342
- dummyRow[fmtFieldName] = inputVal;
343
- inputVal = this._formatter(dummyRow); // WARNING: dummyRow may not provide enough data for formatting correctly
344
- } else if(inputVal) {
345
- inputVal = inputVal + "";
346
- } else if(inputVal === 0) {
347
- inputVal = "0";
348
- } else if(inputVal === false) {
349
- inputVal = "false";
350
- }
351
-
352
- if(!inputVal) {
353
- inputVal = "";
354
- }
459
+ value = convertToString(value);
460
+ if(!opDef.caseSensitive) {
461
+ value = value.toLowerCase();
355
462
  }
356
-
357
- if(!opDef.caseSensitive && inputVal) {
358
- inputVal = inputVal.toLowerCase();
359
- }
360
-
361
- // After data type conversion, add quotes to be parsed by eval method
362
- inputVal = "'" + FilterBuilder._escapeQuotes(inputVal) + "'";
363
- } else if(opDef.type === "date") {
364
- if(DateTime.isValidDate(inputVal)) {
365
- var varName;
366
- if(!cond.useUTCTime){
367
- filterStr.push("ts = new Date(val.getFullYear(),val.getMonth(),val.getDate())");
368
- } else {
369
- filterStr.push("ts = new Date(Date.UTC(val.getUTCFullYear(),val.getUTCMonth(),val.getUTCDate()))");
370
- }
371
- filterStr.push("ts = ts.getTime()");
372
- filterStr.push("if(ts !== ts) {");
373
- filterStr.push(" return false;");
374
- filterStr.push("}");
375
-
376
- if(cond.operatorId === "DT") {
377
- varName = "ts" + (i + 1);
378
- inputVal = inputVal.getTime();
379
- } else {
380
- varName = "date" + (i + 1);
381
- }
382
- if(!contextObj) {
383
- contextObj = {};
384
- }
385
- contextObj[varName] = inputVal;
386
- inputVal = "this." + varName;
387
- } else {
388
- inputVal = NaN;
389
- }
390
- } else if(opDef.type === "number" ) {
391
- if(typeof inputVal !== "number") {
392
- if(inputVal) {
393
- if(inputVal === true) {
394
- inputVal = 1;
395
- } else {
396
- inputVal = parseFloat(inputVal);
397
- }
398
- } else if(inputVal === false) {
399
- inputVal = 0;
400
- } else { // NaN, empty string, undefined, null
401
- inputVal = NaN;
402
- }
403
- }
404
- } // else case is blank operator type which requires no input value
405
-
406
- // Build condition string
407
- condStr.push("(" + opDef.formula.replace(/input/g, inputVal) + ")");
463
+ }
464
+ cond.value = value;
408
465
  }
409
466
 
410
- filterStr.push("return " + condStr.join(" ") + ";");
411
- filterStr = filterStr.join("\n");
412
-
413
- var func = null;
414
- try {
415
- func = /** @type{Function} */ (eval("(function(rowData) {\n" + filterStr + "\n})"));
416
- if(contextObj) {
417
- func = func.bind(contextObj);
418
- }
419
- } catch(err) {} // eslint-disable-line no-empty
467
+ var ctx = {
468
+ _conds: conds,
469
+ _fieldName: this._fieldName || "",
470
+ _formatter: formatter || null,
471
+ _formattedFieldName: this._formattedFieldName || "",
472
+ _rawDataAccessor: this._rawDataAccessor || null,
473
+ _formattedDataAccessor: this._formattedDataAccessor || null
474
+ };
420
475
 
421
476
  // Release all resources after building the filter whether success or not
422
477
  this._conditions.length = 0;
423
- return func;
478
+ return _filterByConditions.bind(null, ctx);
424
479
  };
480
+
425
481
  /** @public
426
482
  * @param {string} filterStr For instance, GT♦100♦AND♣LTE♦200
427
483
  * @param {string} field
@@ -455,32 +511,15 @@ var buildFilterFromObjectMap = function(obj, field, rawDataAccessor) {
455
511
  if(!obj || !field) {
456
512
  return null;
457
513
  }
458
-
459
- var contextObj = null;
460
- var funcAry = ["(function(itemMap, rowData) {"];
461
-
462
- // TODO: Field name cannot contain double quote string. Handle this case
463
- funcAry.push(' var val = rowData["' + field + '"]');
514
+ var ctx = {
515
+ _fieldName: field,
516
+ _itemMap: obj
517
+ };
464
518
  if(rawDataAccessor) {
465
- if(!contextObj) {
466
- contextObj = {};
467
- }
468
- contextObj["rawDataAccessor"] = rawDataAccessor;
469
- funcAry.push(" val = this.rawDataAccessor(val);");
519
+ ctx._rawDataAccessor = rawDataAccessor;
470
520
  }
471
- funcAry.push(" return itemMap[val] ? true : false;");
472
- funcAry.push("})");
473
-
474
- var funcStr = funcAry.join("\n");
475
- var filterFunc = null;
476
- try {
477
- filterFunc = eval(funcStr);
478
- } catch (err) {} // eslint-disable-line
479
521
 
480
- if(filterFunc) {
481
- return filterFunc.bind(contextObj, obj);
482
- }
483
- return null;
522
+ return _filterByObjectMap.bind(null, ctx);
484
523
  };
485
524
 
486
525
  /** @public
@@ -498,7 +537,7 @@ FilterBuilder.prototype.parse = function(condition, field, formatter, formattedF
498
537
  if(condition.indexOf("♦") >= 0) {
499
538
  return this.buildMonitorFilter(condition, field, formatter, formattedField);
500
539
  } else {
501
- return parseCondition(condition);
540
+ return ExpressionParser.parse(condition);
502
541
  }
503
542
  } else if(type === "function") {
504
543
  return condition;
@@ -515,14 +554,5 @@ FilterBuilder.prototype.parse = function(condition, field, formatter, formattedF
515
554
  return null;
516
555
  };
517
556
 
518
- /** @private
519
- * @function
520
- * @param {string} str
521
- * @return {string}
522
- */
523
- FilterBuilder._escapeQuotes = function(str) {
524
- return (str + '').replace(/[\\"']/g, '\\$&').replace(/\u0000/g, '\\0'); // eslint-disable-line no-control-regex
525
- };
526
-
527
557
  export default FilterBuilder;
528
558
  export { FilterBuilder, buildFilterFromObjectMap };
@@ -37,5 +37,7 @@ declare namespace FilterOperators {
37
37
 
38
38
  }
39
39
 
40
+ declare const OperatorFunctions: { [key: string]: ((...params: any[]) => any) }|null;
41
+
40
42
  export default FilterOperators;
41
- export { FilterOperators };
43
+ export { FilterOperators, OperatorFunctions };