@refinitiv-ui/efx-grid 6.0.40 → 6.0.42

Sign up to get free protection for your applications and to get access to all the features.
Files changed (44) 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 +846 -881
  4. package/lib/core/dist/core.min.js +1 -1
  5. package/lib/core/es6/grid/Core.d.ts +4 -0
  6. package/lib/core/es6/grid/Core.js +91 -27
  7. package/lib/core/es6/grid/plugins/SortableTitlePlugin.d.ts +3 -2
  8. package/lib/core/es6/grid/plugins/SortableTitlePlugin.js +26 -26
  9. package/lib/core/es6/grid/util/util.js +25 -9
  10. package/lib/grid/index.js +1 -1
  11. package/lib/rt-grid/dist/rt-grid.js +2253 -1755
  12. package/lib/rt-grid/dist/rt-grid.min.js +1 -1
  13. package/lib/rt-grid/es6/Grid.d.ts +22 -0
  14. package/lib/rt-grid/es6/Grid.js +146 -11
  15. package/lib/rt-grid/es6/RowDefinition.d.ts +2 -2
  16. package/lib/rt-grid/es6/RowDefinition.js +37 -18
  17. package/lib/tr-grid-column-grouping/es6/ColumnGrouping.d.ts +4 -0
  18. package/lib/tr-grid-column-grouping/es6/ColumnGrouping.js +60 -59
  19. package/lib/tr-grid-column-stack/es6/ColumnStack.d.ts +9 -3
  20. package/lib/tr-grid-column-stack/es6/ColumnStack.js +290 -364
  21. package/lib/tr-grid-util/es6/CellPainter.d.ts +2 -1
  22. package/lib/tr-grid-util/es6/CellPainter.js +6 -4
  23. package/lib/tr-grid-util/es6/DateTime.js +3 -3
  24. package/lib/tr-grid-util/es6/ExpressionParser.d.ts +10 -0
  25. package/lib/tr-grid-util/es6/ExpressionParser.js +366 -0
  26. package/lib/tr-grid-util/es6/FilterBuilder.d.ts +10 -6
  27. package/lib/tr-grid-util/es6/FilterBuilder.js +264 -234
  28. package/lib/tr-grid-util/es6/FilterOperators.d.ts +3 -1
  29. package/lib/tr-grid-util/es6/FilterOperators.js +51 -2
  30. package/lib/tr-grid-util/es6/GridPlugin.js +1 -1
  31. package/lib/tr-grid-util/es6/Util.d.ts +0 -3
  32. package/lib/tr-grid-util/es6/Util.js +0 -53
  33. package/lib/tr-grid-util/es6/formula/Formula.js +3 -3
  34. package/lib/types/es6/ColumnDragging.d.ts +51 -0
  35. package/lib/types/es6/ColumnGrouping.d.ts +4 -0
  36. package/lib/types/es6/ColumnStack.d.ts +9 -3
  37. package/lib/types/es6/Core/grid/Core.d.ts +4 -0
  38. package/lib/types/es6/Core/grid/plugins/SortableTitlePlugin.d.ts +3 -2
  39. package/lib/types/es6/ExtensionOptions.d.ts +2 -0
  40. package/lib/types/es6/Extensions.d.ts +3 -1
  41. package/lib/types/es6/RealtimeGrid/RowDefinition.d.ts +2 -2
  42. package/lib/types/es6/index.d.ts +1 -0
  43. package/lib/versions.json +4 -4
  44. 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 };