@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.
- package/lib/column-selection-dialog/lib/column-selection-dialog.d.ts +2 -1
- package/lib/column-selection-dialog/lib/column-selection-dialog.js +23 -7
- package/lib/core/dist/core.js +25 -26
- package/lib/core/dist/core.min.js +1 -1
- package/lib/core/es6/grid/Core.js +25 -26
- package/lib/grid/index.js +1 -1
- package/lib/rt-grid/dist/rt-grid.js +2083 -1753
- package/lib/rt-grid/dist/rt-grid.min.js +1 -1
- package/lib/rt-grid/es6/Grid.js +55 -7
- package/lib/rt-grid/es6/RowDefinition.d.ts +2 -2
- package/lib/rt-grid/es6/RowDefinition.js +37 -18
- package/lib/tr-grid-column-grouping/es6/ColumnGrouping.js +26 -40
- package/lib/tr-grid-util/es6/CellPainter.d.ts +2 -1
- package/lib/tr-grid-util/es6/CellPainter.js +6 -4
- package/lib/tr-grid-util/es6/ExpressionParser.d.ts +10 -0
- package/lib/tr-grid-util/es6/ExpressionParser.js +366 -0
- package/lib/tr-grid-util/es6/FilterBuilder.d.ts +10 -6
- package/lib/tr-grid-util/es6/FilterBuilder.js +264 -234
- package/lib/tr-grid-util/es6/FilterOperators.d.ts +3 -1
- package/lib/tr-grid-util/es6/FilterOperators.js +51 -2
- package/lib/tr-grid-util/es6/Util.d.ts +0 -3
- package/lib/tr-grid-util/es6/Util.js +0 -53
- package/lib/tr-grid-util/es6/formula/Formula.js +3 -3
- package/lib/types/es6/ColumnDragging.d.ts +51 -0
- package/lib/types/es6/ExtensionOptions.d.ts +2 -0
- package/lib/types/es6/Extensions.d.ts +3 -1
- package/lib/types/es6/RealtimeGrid/RowDefinition.d.ts +2 -2
- package/lib/types/es6/index.d.ts +1 -0
- package/lib/versions.json +3 -3
- package/package.json +1 -1
@@ -0,0 +1,366 @@
|
|
1
|
+
/** @type {Object.<string, number>}
|
2
|
+
* @private
|
3
|
+
* @const
|
4
|
+
*/
|
5
|
+
var OperatorPrecedences = {
|
6
|
+
"||": 1,
|
7
|
+
"&&": 2,
|
8
|
+
"<": 3,
|
9
|
+
">": 3,
|
10
|
+
"<=": 3,
|
11
|
+
">=": 3,
|
12
|
+
"!=": 3,
|
13
|
+
"=": 3,
|
14
|
+
"==": 3,
|
15
|
+
"===": 3,
|
16
|
+
"+": 4,
|
17
|
+
"-": 4,
|
18
|
+
"*": 5,
|
19
|
+
"%": 6,
|
20
|
+
"/": 6
|
21
|
+
};
|
22
|
+
/** @type {Object.<string, Function>}
|
23
|
+
* @private
|
24
|
+
* @const
|
25
|
+
*/
|
26
|
+
var OperatorFunctions = {
|
27
|
+
"+": function(lhs, rhs){ return lhs + rhs; },
|
28
|
+
"-": function(lhs, rhs){ return lhs - rhs; },
|
29
|
+
"*": function(lhs, rhs){ return lhs * rhs; },
|
30
|
+
"/": function(lhs, rhs){ return lhs / rhs; },
|
31
|
+
"%": function(lhs, rhs){ return lhs % rhs; },
|
32
|
+
"<": function(lhs, rhs){ return lhs < rhs; },
|
33
|
+
">": function(lhs, rhs){ return lhs > rhs; },
|
34
|
+
"<=": function(lhs, rhs){ return lhs <= rhs; },
|
35
|
+
">=": function(lhs, rhs){ return lhs >= rhs; },
|
36
|
+
"==": function(lhs, rhs){ return lhs == rhs; },
|
37
|
+
"!=": function(lhs, rhs){ return lhs != rhs; },
|
38
|
+
"&&": function(lhs, rhs){ return lhs && rhs; },
|
39
|
+
"||": function(lhs, rhs){ return lhs || rhs; }
|
40
|
+
};
|
41
|
+
/** @type {Object.<string, Function>}
|
42
|
+
* @private
|
43
|
+
* @function
|
44
|
+
* @param {Array.<Object>} ary
|
45
|
+
* @param {string|number} value
|
46
|
+
* @param {string} type
|
47
|
+
* @param {string=} dataType
|
48
|
+
* @return {number}
|
49
|
+
*/
|
50
|
+
var _addToken = function(ary, value, type, dataType) {
|
51
|
+
var tok = {
|
52
|
+
value: value,
|
53
|
+
type: type
|
54
|
+
};
|
55
|
+
if(dataType) {
|
56
|
+
tok.dataType = dataType;
|
57
|
+
}
|
58
|
+
if(type === "operator") {
|
59
|
+
tok.precedence = OperatorPrecedences[value];
|
60
|
+
}
|
61
|
+
ary.push(tok);
|
62
|
+
return ary.length - 1;
|
63
|
+
};
|
64
|
+
|
65
|
+
/** @public
|
66
|
+
* @namespace
|
67
|
+
*/
|
68
|
+
var ExpressionParser = {};
|
69
|
+
/** @type {Array.<Object>}
|
70
|
+
* @private
|
71
|
+
* @const
|
72
|
+
*/
|
73
|
+
ExpressionParser._tokens = [];
|
74
|
+
|
75
|
+
|
76
|
+
/** @private
|
77
|
+
* @function
|
78
|
+
* @param {string} str
|
79
|
+
* @return {string}
|
80
|
+
*/
|
81
|
+
ExpressionParser._withString = function(str) {
|
82
|
+
var tokId = _addToken(ExpressionParser._tokens,
|
83
|
+
str.substring(1, str.length - 1),
|
84
|
+
"literal",
|
85
|
+
"string"
|
86
|
+
);
|
87
|
+
return " #" + tokId + "#";
|
88
|
+
};
|
89
|
+
/** @private
|
90
|
+
* @function
|
91
|
+
* @param {string} field
|
92
|
+
* @return {string}
|
93
|
+
*/
|
94
|
+
ExpressionParser._withField = function(field) {
|
95
|
+
var tokId = _addToken(ExpressionParser._tokens,
|
96
|
+
field,
|
97
|
+
"literal",
|
98
|
+
"variable"
|
99
|
+
);
|
100
|
+
return " #" + tokId + "#";
|
101
|
+
};
|
102
|
+
/** @private
|
103
|
+
* @function
|
104
|
+
* @param {string} field
|
105
|
+
* @return {string}
|
106
|
+
*/
|
107
|
+
ExpressionParser._withFieldInBrackets = function(field) {
|
108
|
+
return ExpressionParser._withField(field.substring(1, field.length - 1));
|
109
|
+
};
|
110
|
+
/** @private
|
111
|
+
* @function
|
112
|
+
* @param {string} numStr
|
113
|
+
* @return {string}
|
114
|
+
*/
|
115
|
+
ExpressionParser._withNegativeNumber = function(numStr) {
|
116
|
+
var num = +numStr;
|
117
|
+
if(num === num) {
|
118
|
+
var tokId = _addToken(ExpressionParser._tokens,
|
119
|
+
num,
|
120
|
+
"literal",
|
121
|
+
"number"
|
122
|
+
);
|
123
|
+
return " #" + tokId + "#";
|
124
|
+
}
|
125
|
+
return "";
|
126
|
+
};
|
127
|
+
/** @private
|
128
|
+
* @function
|
129
|
+
* @param {string} numStr
|
130
|
+
* @return {string}
|
131
|
+
*/
|
132
|
+
ExpressionParser._withPositiveNumber = function(numStr) {
|
133
|
+
if(numStr.charCodeAt(0) === 35) {
|
134
|
+
return numStr; // skip token (string with leading #)
|
135
|
+
}
|
136
|
+
return ExpressionParser._withNegativeNumber(numStr);
|
137
|
+
};
|
138
|
+
/** @private
|
139
|
+
* @function
|
140
|
+
* @param {string} opStr
|
141
|
+
* @return {string}
|
142
|
+
*/
|
143
|
+
ExpressionParser._withOperator = function(opStr) {
|
144
|
+
if(OperatorPrecedences[opStr]) {
|
145
|
+
if(opStr == "=" || opStr == "===") {
|
146
|
+
opStr = "==";
|
147
|
+
}
|
148
|
+
var tokId = _addToken(ExpressionParser._tokens, opStr, "operator");
|
149
|
+
return "#" + tokId + "#";
|
150
|
+
}
|
151
|
+
return "";
|
152
|
+
};
|
153
|
+
/** @private
|
154
|
+
* @function
|
155
|
+
* @param {string} paStr
|
156
|
+
* @return {string}
|
157
|
+
*/
|
158
|
+
ExpressionParser._withParenthesis = function(paStr) {
|
159
|
+
var tokId = _addToken(ExpressionParser._tokens, paStr, "parenthesis");
|
160
|
+
return "#" + tokId + "#";
|
161
|
+
};
|
162
|
+
|
163
|
+
|
164
|
+
/** @private
|
165
|
+
* @function
|
166
|
+
* @param {Object} ctx
|
167
|
+
* @return {boolean} Returns true if there is any error, otherwise returns false (everything is OK)
|
168
|
+
*/
|
169
|
+
ExpressionParser._tester = function(ctx) {
|
170
|
+
var rpn = ctx._rpn;
|
171
|
+
var inputCount = rpn.length;
|
172
|
+
var operandCount = 0;
|
173
|
+
var maxStack = 0;
|
174
|
+
for(var i = 0; i < inputCount; ++i) {
|
175
|
+
var tok = rpn[i];
|
176
|
+
if(tok.type !== "literal") {
|
177
|
+
if(operandCount >= 2) {
|
178
|
+
operandCount -= 2;
|
179
|
+
} else {
|
180
|
+
console.warn("Cannot parse an expression with insufficient number of operands");
|
181
|
+
return true;
|
182
|
+
}
|
183
|
+
}
|
184
|
+
operandCount++;
|
185
|
+
if(operandCount > maxStack) {
|
186
|
+
maxStack = operandCount;
|
187
|
+
}
|
188
|
+
}
|
189
|
+
|
190
|
+
if(operandCount !== 1) {
|
191
|
+
return true;
|
192
|
+
}
|
193
|
+
|
194
|
+
ctx._stackSize = maxStack;
|
195
|
+
return false;
|
196
|
+
};
|
197
|
+
/** @private
|
198
|
+
* @function
|
199
|
+
* @param {Object} ctx
|
200
|
+
* @param {Object} rowData
|
201
|
+
* @return {boolean}
|
202
|
+
*/
|
203
|
+
ExpressionParser._filter = function(ctx, rowData) {
|
204
|
+
var rpn = ctx._rpn;
|
205
|
+
var results = new Array(ctx._stackSize);
|
206
|
+
var inputCount = rpn.length;
|
207
|
+
var operandCount = 0;
|
208
|
+
var curRes;
|
209
|
+
for(var i = 0; i < inputCount; ++i) {
|
210
|
+
var tok = rpn[i];
|
211
|
+
var tokValue = tok.value;
|
212
|
+
if(tok.type === "literal") {
|
213
|
+
if(tok.dataType !== "variable") {
|
214
|
+
curRes = tokValue;
|
215
|
+
} else {
|
216
|
+
curRes = rowData ? rowData[tokValue] : null;
|
217
|
+
}
|
218
|
+
} else { // operator
|
219
|
+
curRes = OperatorFunctions[tokValue](
|
220
|
+
results[operandCount - 2],
|
221
|
+
results[operandCount - 1]
|
222
|
+
);
|
223
|
+
operandCount -= 2;
|
224
|
+
}
|
225
|
+
results[operandCount++] = curRes;
|
226
|
+
}
|
227
|
+
// return results[0];
|
228
|
+
return results[0] ? true : false;
|
229
|
+
};
|
230
|
+
|
231
|
+
/** Parse an expression into a filter function (returning boolean value)
|
232
|
+
* @public
|
233
|
+
* @param {string|Function} expression
|
234
|
+
* @return {Function}
|
235
|
+
* @example
|
236
|
+
* func = ExpressionParser.parse("field1 >= 10");
|
237
|
+
* func = ExpressionParser.parse("[field with space] != 'text'");
|
238
|
+
* func = ExpressionParser.parse("(field1 + 1) / 2 < 10 && field2 - 10 > 3");
|
239
|
+
*/
|
240
|
+
ExpressionParser.parse = function(expression) {
|
241
|
+
if(typeof expression === "function") {
|
242
|
+
return expression;
|
243
|
+
}
|
244
|
+
if(!expression || typeof expression !== "string") {
|
245
|
+
return null;
|
246
|
+
}
|
247
|
+
|
248
|
+
var tokExp = expression.trim();
|
249
|
+
if(!tokExp) {
|
250
|
+
return null;
|
251
|
+
}
|
252
|
+
ExpressionParser._tokens.length = 0;
|
253
|
+
|
254
|
+
tokExp = tokExp.replace(/".+?"/g, ExpressionParser._withString); // double quote string
|
255
|
+
tokExp = tokExp.replace(/'.+?'/g, ExpressionParser._withString); // single quote string
|
256
|
+
tokExp = tokExp.replace(/\[.+?\]/g, ExpressionParser._withFieldInBrackets); // field in square brackets
|
257
|
+
tokExp = tokExp.replace(/-[0-9.]+/g, ExpressionParser._withNegativeNumber);
|
258
|
+
tokExp = tokExp.replace(/[0-9.#]+/g, ExpressionParser._withPositiveNumber);
|
259
|
+
tokExp = tokExp.replace(/[a-zA-Z_]\w*/g, ExpressionParser._withField);
|
260
|
+
tokExp = tokExp.replace(/[\-\/+*%!=<>&|]+/g, ExpressionParser._withOperator);
|
261
|
+
tokExp = tokExp.replace(/[()]/g, ExpressionParser._withParenthesis); // round brackets
|
262
|
+
|
263
|
+
var tokens = ExpressionParser._tokens;
|
264
|
+
var tokCount = tokens.length;
|
265
|
+
if(!tokCount) {
|
266
|
+
return null; // There is no recognizable character
|
267
|
+
}
|
268
|
+
|
269
|
+
// Generate infix token list
|
270
|
+
var infixTokens = [];
|
271
|
+
var matches = tokExp.match(/#[0-9]+#/g);
|
272
|
+
var i, tok, tokType;
|
273
|
+
for(i = 0; i < tokCount; ++i) {
|
274
|
+
var tokId = matches[i];
|
275
|
+
var tokIdx = +(tokId.substring(1, tokId.length - 1));
|
276
|
+
tok = tokens[tokIdx];
|
277
|
+
tokType = tok.type;
|
278
|
+
if(tokType === "literal") {
|
279
|
+
var prevTok = infixTokens[infixTokens.length - 1];
|
280
|
+
if(prevTok && prevTok.type === "literal") { // Incorrect infix notation detected
|
281
|
+
if(tok.value < 0 && tok.dataType === "number") {
|
282
|
+
_addToken(infixTokens, "-", "operator");
|
283
|
+
tok.value *= -1;
|
284
|
+
} else {
|
285
|
+
console.warn("Cannot parse an expression with insufficient number of operators");
|
286
|
+
return null;
|
287
|
+
}
|
288
|
+
}
|
289
|
+
}
|
290
|
+
infixTokens.push(tok);
|
291
|
+
}
|
292
|
+
// TODO: Handle the case where subtraction operator is in front of a variable
|
293
|
+
ExpressionParser._tokens.length = 0;
|
294
|
+
|
295
|
+
// Convert Infix notation to Reverse Polish Notation (Postfix)
|
296
|
+
// See https://en.wikipedia.org/wiki/Shunting_yard_algorithm#The_algorithm_in_detail
|
297
|
+
tokCount = infixTokens.length;
|
298
|
+
var rpn = [];
|
299
|
+
var operators = [];
|
300
|
+
var lastOp = null;
|
301
|
+
var foundLeftPa = false;
|
302
|
+
for(i = 0; i < tokCount; ++i) {
|
303
|
+
tok = infixTokens[i];
|
304
|
+
tokType = tok.type;
|
305
|
+
|
306
|
+
if(tokType === "literal") {
|
307
|
+
rpn.push(tok);
|
308
|
+
} else if(tokType === "parenthesis") {
|
309
|
+
if(tok.value === "(") {
|
310
|
+
operators.push(tok);
|
311
|
+
} else { // When finding right parenthesis, pop all operators until left parenthesis
|
312
|
+
foundLeftPa = false;
|
313
|
+
while(operators.length) {
|
314
|
+
lastOp = operators.pop();
|
315
|
+
if(lastOp.value === "(" && lastOp.type === "parenthesis") {
|
316
|
+
foundLeftPa = true;
|
317
|
+
break;
|
318
|
+
} else {
|
319
|
+
rpn.push(lastOp);
|
320
|
+
}
|
321
|
+
}
|
322
|
+
if(!foundLeftPa) {
|
323
|
+
console.warn("No left parenthesis paired with the right one");
|
324
|
+
}
|
325
|
+
}
|
326
|
+
} else { // operator
|
327
|
+
lastOp = operators[operators.length - 1];
|
328
|
+
var prevPrecedence = lastOp ? lastOp.precedence : null;
|
329
|
+
if(prevPrecedence != null && tok.precedence <= prevPrecedence) {
|
330
|
+
rpn.push(operators.pop());
|
331
|
+
}
|
332
|
+
operators.push(tok);
|
333
|
+
}
|
334
|
+
}
|
335
|
+
|
336
|
+
foundLeftPa = false;
|
337
|
+
while(operators.length) {
|
338
|
+
lastOp = operators.pop();
|
339
|
+
if(lastOp.value === "(" && lastOp.type === "parenthesis") {
|
340
|
+
foundLeftPa = true;
|
341
|
+
} else {
|
342
|
+
rpn.push(lastOp);
|
343
|
+
}
|
344
|
+
}
|
345
|
+
if(foundLeftPa) {
|
346
|
+
console.warn("No right parenthesis paired with the left one");
|
347
|
+
}
|
348
|
+
|
349
|
+
var inputCount = rpn.length;
|
350
|
+
if(!inputCount) {
|
351
|
+
return null; // The expression contains nothing but parentheses
|
352
|
+
}
|
353
|
+
|
354
|
+
var ctx = {
|
355
|
+
_rpn: rpn
|
356
|
+
};
|
357
|
+
|
358
|
+
if(ExpressionParser._tester(ctx)) {
|
359
|
+
return null; // Insufficient number of operands
|
360
|
+
}
|
361
|
+
|
362
|
+
return ExpressionParser._filter.bind(null, ctx);
|
363
|
+
};
|
364
|
+
|
365
|
+
export default ExpressionParser;
|
366
|
+
export {ExpressionParser};
|
@@ -1,13 +1,15 @@
|
|
1
|
-
import {
|
2
|
-
import {
|
3
|
-
import { FilterOperators } from "./FilterOperators.js";
|
1
|
+
import { FilterOperators, OperatorFunctions } from "./FilterOperators.js";
|
2
|
+
import { ExpressionParser } from "./ExpressionParser.js";
|
4
3
|
|
5
4
|
declare namespace FilterBuilder {
|
6
5
|
|
7
6
|
type Options = {
|
8
|
-
field
|
7
|
+
field?: (string|null)|null,
|
9
8
|
formatter?: ((...params: any[]) => any)|null,
|
10
|
-
formattedField?: string|null
|
9
|
+
formattedField?: string|null,
|
10
|
+
useUTCTime?: boolean|null,
|
11
|
+
rawDataAccessor?: ((...params: any[]) => any)|null,
|
12
|
+
formattedDataAccessor?: ((...params: any[]) => any)|null
|
11
13
|
};
|
12
14
|
|
13
15
|
type Condition = any[]|null;
|
@@ -26,9 +28,11 @@ declare class FilterBuilder {
|
|
26
28
|
|
27
29
|
public setFieldDefinition(fieldName: string, formatter?: ((...params: any[]) => any)|null, formattedField?: string|null): void;
|
28
30
|
|
31
|
+
public setDefaultUTCUsage(useUTCTime: boolean): void;
|
32
|
+
|
29
33
|
public setDataAccessors(rawDataAccessor?: ((...params: any[]) => any)|null, formattedDataAccessor?: ((...params: any[]) => any)|null): void;
|
30
34
|
|
31
|
-
public addCondition(oper: string, value: string|number|null, connector?: string|null, useUTCTime?: boolean|null): boolean;
|
35
|
+
public addCondition(oper: string, value: string|number|Date|null, connector?: string|null, useUTCTime?: boolean|null): boolean;
|
32
36
|
|
33
37
|
public addConditions(conditions: FilterBuilder.Conditions|null): number;
|
34
38
|
|