@refinitiv-ui/efx-grid 6.0.40 → 6.0.41
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
|