@refinitiv-ui/efx-grid 6.0.91 → 6.0.93
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-dragging/es6/ColumnDragging.d.ts +1 -1
- package/lib/column-dragging/es6/ColumnDragging.js +144 -34
- package/lib/core/dist/core.js +2410 -2621
- package/lib/core/dist/core.min.js +1 -1
- package/lib/core/es6/data/ColumnStats.js +14 -14
- package/lib/core/es6/data/DataCache.js +118 -118
- package/lib/core/es6/data/DataTable.d.ts +3 -1
- package/lib/core/es6/data/DataTable.js +208 -190
- package/lib/core/es6/data/DataView.d.ts +1 -1
- package/lib/core/es6/data/DataView.js +291 -291
- package/lib/core/es6/data/Segment.js +79 -79
- package/lib/core/es6/data/SegmentCollection.js +81 -81
- package/lib/core/es6/data/WrappedView.js +41 -41
- package/lib/core/es6/grid/Core.js +635 -635
- package/lib/core/es6/grid/ILayoutGrid.js +1 -1
- package/lib/core/es6/grid/LayoutGrid.js +183 -183
- package/lib/core/es6/grid/VirtualizedLayoutGrid.js +91 -91
- package/lib/core/es6/grid/components/Cell.js +29 -29
- package/lib/core/es6/grid/components/CellFloatingPanel.js +11 -11
- package/lib/core/es6/grid/components/CellSpan.js +7 -7
- package/lib/core/es6/grid/components/CellSpans.js +36 -34
- package/lib/core/es6/grid/components/Column.js +40 -40
- package/lib/core/es6/grid/components/ElementWrapper.js +17 -17
- package/lib/core/es6/grid/components/HScrollbar.js +31 -31
- package/lib/core/es6/grid/components/Scrollbar.js +77 -77
- package/lib/core/es6/grid/components/StretchedCells.js +49 -49
- package/lib/core/es6/grid/components/VScrollbar.js +11 -11
- package/lib/core/es6/grid/components/VirtualItems.js +3 -3
- package/lib/core/es6/grid/event/EventDispatcher.js +9 -9
- package/lib/core/es6/grid/event/EventListeners.js +4 -4
- package/lib/core/es6/grid/plugins/SortableTitlePlugin.js +186 -186
- package/lib/core/es6/grid/util/Conflator.js +4 -4
- package/lib/core/es6/grid/util/Reverter.js +1 -1
- package/lib/core/es6/grid/util/SectionSettings.js +20 -20
- package/lib/core/es6/grid/util/SelectionList.js +23 -23
- package/lib/core/es6/grid/util/TrackLayout.js +74 -74
- package/lib/core/es6/grid/util/Virtualizer.js +15 -15
- package/lib/core/es6/grid/util/util.js +20 -20
- package/lib/core/es6/index.d.ts +0 -2
- package/lib/core/es6/index.js +0 -3
- package/lib/filter-dialog/lib/filter-dialog.js +1 -0
- package/lib/grid/index.js +1 -1
- package/lib/rt-grid/dist/rt-grid.js +193 -70
- package/lib/rt-grid/dist/rt-grid.min.js +1 -1
- package/lib/rt-grid/es6/Grid.js +46 -30
- package/lib/rt-grid/es6/RowDefinition.d.ts +2 -1
- package/lib/rt-grid/es6/RowDefinition.js +74 -16
- package/lib/tr-grid-cell-selection/es6/CellSelection.js +56 -1
- package/lib/tr-grid-checkbox/es6/Checkbox.js +268 -268
- package/lib/tr-grid-column-grouping/es6/ColumnGrouping.d.ts +3 -2
- package/lib/tr-grid-column-grouping/es6/ColumnGrouping.js +60 -32
- package/lib/tr-grid-column-stack/es6/ColumnStack.js +279 -279
- package/lib/tr-grid-conditional-coloring/es6/ConditionalColoring.js +227 -207
- package/lib/tr-grid-in-cell-editing/es6/InCellEditing.js +11 -11
- package/lib/tr-grid-row-dragging/es6/RowDragging.d.ts +1 -2
- package/lib/tr-grid-row-dragging/es6/RowDragging.js +120 -121
- package/lib/tr-grid-util/es6/CellPainter.js +94 -104
- package/lib/tr-grid-util/es6/Conflator.js +4 -4
- package/lib/tr-grid-util/es6/CoralItems.js +6 -6
- package/lib/tr-grid-util/es6/DateTime.js +41 -41
- package/lib/tr-grid-util/es6/Deferred.js +5 -5
- package/lib/tr-grid-util/es6/Delay.d.ts +3 -3
- package/lib/tr-grid-util/es6/Delay.js +14 -3
- package/lib/tr-grid-util/es6/Dom.js +26 -26
- package/lib/tr-grid-util/es6/DragUI.js +17 -17
- package/lib/tr-grid-util/es6/ElementObserver.js +12 -12
- package/lib/tr-grid-util/es6/ElementWrapper.js +2 -2
- package/lib/tr-grid-util/es6/ElfDate.js +4 -4
- package/lib/tr-grid-util/es6/ElfUtil.js +37 -37
- package/lib/tr-grid-util/es6/EventDispatcher.js +12 -12
- package/lib/tr-grid-util/es6/ExpanderIcon.js +6 -6
- package/lib/tr-grid-util/es6/ExpressionParser.js +43 -43
- package/lib/tr-grid-util/es6/Ext.js +6 -6
- package/lib/tr-grid-util/es6/FieldFormatter.js +17 -17
- package/lib/tr-grid-util/es6/FilterBuilder.js +57 -58
- package/lib/tr-grid-util/es6/FilterOperators.d.ts +12 -1
- package/lib/tr-grid-util/es6/FilterOperators.js +13 -2
- package/lib/tr-grid-util/es6/GridPlugin.js +86 -87
- package/lib/tr-grid-util/es6/GroupDefinitions.js +90 -90
- package/lib/tr-grid-util/es6/Icon.js +4 -4
- package/lib/tr-grid-util/es6/MouseDownTrait.js +6 -6
- package/lib/tr-grid-util/es6/MultiTableManager.js +71 -80
- package/lib/tr-grid-util/es6/NumberFormatter.js +23 -23
- package/lib/tr-grid-util/es6/PercentBar.js +17 -17
- package/lib/tr-grid-util/es6/Perf.js +5 -5
- package/lib/tr-grid-util/es6/Popup.js +42 -42
- package/lib/tr-grid-util/es6/RangeBar.js +5 -5
- package/lib/tr-grid-util/es6/RequestQueue.js +5 -5
- package/lib/tr-grid-util/es6/RowPainter.js +23 -23
- package/lib/tr-grid-util/es6/SubTable.js +94 -94
- package/lib/tr-grid-util/es6/Table.js +51 -51
- package/lib/tr-grid-util/es6/TextHighlighter.js +52 -52
- package/lib/tr-grid-util/es6/TickCodes.js +2 -2
- package/lib/tr-grid-util/es6/Timer.js +2 -2
- package/lib/tr-grid-util/es6/TouchProxy.js +7 -7
- package/lib/tr-grid-util/es6/Util.js +50 -50
- package/lib/tr-grid-util/es6/formula/ADCService.js +2 -2
- package/lib/tr-grid-util/es6/formula/ADCSubscription.js +19 -19
- package/lib/tr-grid-util/es6/formula/AdFinService.js +2 -2
- package/lib/tr-grid-util/es6/formula/AdFinSubscription.js +19 -19
- package/lib/tr-grid-util/es6/formula/Engine.js +56 -56
- package/lib/tr-grid-util/es6/formula/Formula.js +62 -62
- package/lib/tr-grid-util/es6/formula/IntervalSubscription.js +3 -3
- package/lib/tr-grid-util/es6/formula/Realtime.js +15 -15
- package/lib/tr-grid-util/es6/formula/RealtimeService.js +15 -15
- package/lib/tr-grid-util/es6/formula/TSIService.js +2 -2
- package/lib/tr-grid-util/es6/formula/TSISubscription.js +104 -104
- package/lib/tr-grid-util/es6/formula/VariableToken.js +20 -20
- package/lib/tr-grid-util/es6/formula/functions/AdFin.js +10 -10
- package/lib/tr-grid-util/es6/formula/functions/Excel.js +1 -1
- package/lib/tr-grid-util/es6/formula/functions/Info.js +2 -2
- package/lib/tr-grid-util/es6/formula/functions/Internal.js +5 -5
- package/lib/tr-grid-util/es6/formula/functions/Logic.js +5 -5
- package/lib/tr-grid-util/es6/formula/functions/Math.js +46 -46
- package/lib/tr-grid-util/es6/formula/functions/Statistics.js +27 -27
- package/lib/tr-grid-util/es6/formula/functions/Text.js +19 -19
- package/lib/tr-grid-util/es6/index.js +1 -1
- package/lib/tr-grid-util/es6/jet/Adc.js +36 -36
- package/lib/tr-grid-util/es6/jet/CollectionDict.js +11 -11
- package/lib/tr-grid-util/es6/jet/DataGenerator.js +95 -95
- package/lib/tr-grid-util/es6/jet/DataSet.js +1 -1
- package/lib/tr-grid-util/es6/jet/MockArchive.js +5 -5
- package/lib/tr-grid-util/es6/jet/MockJET.js +1 -1
- package/lib/tr-grid-util/es6/jet/MockQuotes.js +13 -13
- package/lib/tr-grid-util/es6/jet/MockQuotes2.js +100 -100
- package/lib/tr-grid-util/es6/jet/MockRTK.js +4 -4
- package/lib/tr-grid-util/es6/jet/MockUtil.js +2 -2
- package/lib/tr-grid-util/es6/jet/index.js +1 -1
- package/lib/tr-grid-util/es6/jet/mockDataAPI.js +15 -15
- package/lib/tr-grid-util/es6/locale/translation-de.js +1 -1
- package/lib/tr-grid-util/es6/locale/translation-en.js +1 -1
- package/lib/tr-grid-util/es6/locale/translation-ja.js +1 -1
- package/lib/tr-grid-util/es6/locale/translation-zh-hant.js +1 -1
- package/lib/tr-grid-util/es6/locale/translation-zh.js +1 -1
- package/lib/tr-grid-util/es6/locale/translation.js +1 -1
- package/lib/types/es6/ColumnDragging.d.ts +1 -1
- package/lib/types/es6/ColumnGrouping.d.ts +3 -1
- package/lib/types/es6/Core/data/DataTable.d.ts +4 -0
- package/lib/types/es6/Core/data/DataView.d.ts +2 -0
- package/lib/types/es6/Core/data/SegmentCollection.d.ts +2 -0
- package/lib/types/es6/Core/index.d.ts +0 -2
- package/lib/types/es6/RealtimeGrid/RowDefinition.d.ts +2 -1
- package/lib/types/es6/RowDragging.d.ts +1 -2
- package/lib/versions.json +12 -12
- package/package.json +1 -1
- package/lib/core/es6/grid/util/ElementFrameWork.d.ts +0 -18
- package/lib/core/es6/grid/util/ElementFrameWork.js +0 -227
- package/lib/core/es6/grid/util/HttpRequest.d.ts +0 -53
- package/lib/core/es6/grid/util/HttpRequest.js +0 -371
- package/lib/core/es6/grid/util/PercentBar.d.ts +0 -43
- package/lib/core/es6/grid/util/PercentBar.js +0 -390
- package/lib/core/es6/grid/util/PercentBarRenderer.d.ts +0 -41
- package/lib/core/es6/grid/util/PercentBarRenderer.js +0 -316
- package/lib/core/es6/grid/util/RangeBar.d.ts +0 -25
- package/lib/core/es6/grid/util/RangeBar.js +0 -255
- package/lib/types/es6/Core/grid/util/ElementFrameWork.d.ts +0 -18
- package/lib/types/es6/Core/grid/util/HttpRequest.d.ts +0 -53
- package/lib/types/es6/Core/grid/util/PercentBar.d.ts +0 -43
- package/lib/types/es6/Core/grid/util/PercentBarRenderer.d.ts +0 -41
- package/lib/types/es6/Core/grid/util/RangeBar.d.ts +0 -25
|
@@ -13,7 +13,7 @@ import EventDispatcher from "../EventDispatcher.js";
|
|
|
13
13
|
/** @constructor
|
|
14
14
|
* @extends {EventDispatcher}
|
|
15
15
|
*/
|
|
16
|
-
|
|
16
|
+
let Engine = function() {
|
|
17
17
|
this._context = {};
|
|
18
18
|
Engine._addContext(this._context, Engine.getContext()); // Clone context for supporting more than one Engine in App
|
|
19
19
|
this._context["_DATA"] = this._getData.bind(this); // _DATA is an internal context used for getting cached data
|
|
@@ -62,7 +62,7 @@ Engine._context = null; // Static variable for all instances
|
|
|
62
62
|
* @return {!Object.<string, *>}
|
|
63
63
|
*/
|
|
64
64
|
Engine.getContext = function() {
|
|
65
|
-
|
|
65
|
+
let context = Engine._context;
|
|
66
66
|
if(!context) {
|
|
67
67
|
context = {};
|
|
68
68
|
Engine._context = context;
|
|
@@ -82,7 +82,7 @@ Engine.getContext = function() {
|
|
|
82
82
|
* @param {Object.<string, Function>} funcs
|
|
83
83
|
*/
|
|
84
84
|
Engine.addContext = function(funcs) {
|
|
85
|
-
|
|
85
|
+
let context = Engine.getContext();
|
|
86
86
|
Engine._addContext(context, funcs);
|
|
87
87
|
};
|
|
88
88
|
/** @private
|
|
@@ -90,7 +90,7 @@ Engine.addContext = function(funcs) {
|
|
|
90
90
|
* @param {Object.<string, Function>} funcs
|
|
91
91
|
*/
|
|
92
92
|
Engine._addContext = function(context, funcs) {
|
|
93
|
-
for(
|
|
93
|
+
for(let key in funcs) {
|
|
94
94
|
context[key] = funcs[key];
|
|
95
95
|
}
|
|
96
96
|
};
|
|
@@ -121,7 +121,7 @@ Engine.prototype.setFormulaDataSetter = function(func) {
|
|
|
121
121
|
*/
|
|
122
122
|
Engine.prototype._defaultFormulaDataSetter = function(formula, result, rowData, opt_changes) {
|
|
123
123
|
if(result !== "...") { // Data update is pending - do not erase previous value
|
|
124
|
-
|
|
124
|
+
let alias = formula.getAlias();
|
|
125
125
|
rowData[alias] = result;
|
|
126
126
|
if (opt_changes) {
|
|
127
127
|
opt_changes[alias] = result;
|
|
@@ -134,7 +134,7 @@ Engine.prototype._defaultFormulaDataSetter = function(formula, result, rowData,
|
|
|
134
134
|
* @return {!Formula}
|
|
135
135
|
*/
|
|
136
136
|
Engine.prototype.addFormula = function(userInput) {
|
|
137
|
-
|
|
137
|
+
let f;
|
|
138
138
|
if(userInput instanceof Formula){
|
|
139
139
|
f = userInput;
|
|
140
140
|
} else {
|
|
@@ -155,7 +155,7 @@ Engine.prototype.addFormula = function(userInput) {
|
|
|
155
155
|
* @return {!Formula}
|
|
156
156
|
*/
|
|
157
157
|
Engine.prototype.mockFormula = function(userInput) {
|
|
158
|
-
|
|
158
|
+
let f;
|
|
159
159
|
if(userInput instanceof Formula){
|
|
160
160
|
f = new Formula(userInput.getInput(), this._context);
|
|
161
161
|
} else {
|
|
@@ -173,7 +173,7 @@ Engine.prototype.removeFormula = function(ref) {
|
|
|
173
173
|
ref = this._formulas.indexOf(/** @type{Formula} */(ref));
|
|
174
174
|
}
|
|
175
175
|
|
|
176
|
-
|
|
176
|
+
let f;
|
|
177
177
|
if(typeof ref === "number") {
|
|
178
178
|
f = this._formulas[ref];
|
|
179
179
|
if(f) {
|
|
@@ -187,7 +187,7 @@ Engine.prototype.removeFormula = function(ref) {
|
|
|
187
187
|
} else if (typeof ref === "string") {
|
|
188
188
|
f = this._formulaMap[ref];
|
|
189
189
|
if(f) {
|
|
190
|
-
|
|
190
|
+
let at = this._formulas.indexOf(f);
|
|
191
191
|
if(at >= 0) {
|
|
192
192
|
this._formulas.splice(at, 1);
|
|
193
193
|
delete this._formulaMap[ref];
|
|
@@ -202,8 +202,8 @@ Engine.prototype.removeFormula = function(ref) {
|
|
|
202
202
|
/** @public
|
|
203
203
|
*/
|
|
204
204
|
Engine.prototype.removeAllFormulas = function() {
|
|
205
|
-
|
|
206
|
-
for(
|
|
205
|
+
let formulas = this._formulas;
|
|
206
|
+
for(let i = formulas.length; --i >= 0;) {
|
|
207
207
|
delete this._referenceMap[formulas[i].getReference()];
|
|
208
208
|
}
|
|
209
209
|
|
|
@@ -216,7 +216,7 @@ Engine.prototype.removeAllFormulas = function() {
|
|
|
216
216
|
* @return {Formula}
|
|
217
217
|
*/
|
|
218
218
|
Engine.prototype.getFormula = function(opt_ref) {
|
|
219
|
-
|
|
219
|
+
let f;
|
|
220
220
|
if(typeof opt_ref === "number") {
|
|
221
221
|
f = this._formulas[opt_ref];
|
|
222
222
|
} else {
|
|
@@ -229,9 +229,9 @@ Engine.prototype.getFormula = function(opt_ref) {
|
|
|
229
229
|
* @return {Formula}
|
|
230
230
|
*/
|
|
231
231
|
Engine.prototype.getFormulaByExpression = function(exp) {
|
|
232
|
-
|
|
233
|
-
for(
|
|
234
|
-
|
|
232
|
+
let len = this._formulas.length;
|
|
233
|
+
for(let i = 0; i < len; ++i) {
|
|
234
|
+
let f = this._formulas[i];
|
|
235
235
|
if(f.getInput() === exp) {
|
|
236
236
|
return f;
|
|
237
237
|
}
|
|
@@ -261,8 +261,8 @@ Engine.prototype.getFormulaCount = function() {
|
|
|
261
261
|
* @return {string}
|
|
262
262
|
*/
|
|
263
263
|
Engine.prototype._generateUniqueReference = function(ref) {
|
|
264
|
-
|
|
265
|
-
|
|
264
|
+
let uniRef = ref;
|
|
265
|
+
let index = 0;
|
|
266
266
|
while(this._referenceMap[uniRef] != null) {
|
|
267
267
|
uniRef = ref + "_" + ++index;
|
|
268
268
|
}
|
|
@@ -278,9 +278,9 @@ Engine.prototype.addReference = function(src, ref) {
|
|
|
278
278
|
return "";
|
|
279
279
|
}
|
|
280
280
|
ref = this._generateUniqueReference(ref);
|
|
281
|
-
|
|
281
|
+
let colName = "";
|
|
282
282
|
if (src instanceof Formula) {
|
|
283
|
-
|
|
283
|
+
let res = this._setFormulaReference(src, ref);
|
|
284
284
|
if (!res) {
|
|
285
285
|
return "";
|
|
286
286
|
}
|
|
@@ -303,16 +303,16 @@ Engine.prototype.renameReference = function(oldRef, newRef) {
|
|
|
303
303
|
if (!oldRef || this._referenceMap[oldRef] == null || oldRef === newRef) {
|
|
304
304
|
return false;
|
|
305
305
|
}
|
|
306
|
-
|
|
306
|
+
let f = this._formulaMap[oldRef];
|
|
307
307
|
if (f && !this.isValidReference(f, newRef)) {
|
|
308
308
|
return false;
|
|
309
309
|
}
|
|
310
310
|
|
|
311
311
|
// Change the reference being used in all formulas
|
|
312
|
-
for (
|
|
313
|
-
|
|
312
|
+
for (let i = this._formulas.length; --i >= 0;) {
|
|
313
|
+
let formula = this._formulas[i];
|
|
314
314
|
if (formula.changeField(oldRef, newRef)) {
|
|
315
|
-
|
|
315
|
+
let ref = formula.getReference();
|
|
316
316
|
if (ref) {
|
|
317
317
|
this._referenceMap[ref] = formula.getAlias();
|
|
318
318
|
}
|
|
@@ -335,7 +335,7 @@ Engine.prototype.removeReference = function(ref) {
|
|
|
335
335
|
if (!ref || this._referenceMap[ref] == null) {
|
|
336
336
|
return false;
|
|
337
337
|
}
|
|
338
|
-
|
|
338
|
+
let f = this._formulaMap[ref];
|
|
339
339
|
if (f != null) {
|
|
340
340
|
f._setReference("");
|
|
341
341
|
delete this._formulaMap[ref];
|
|
@@ -362,10 +362,10 @@ Engine.prototype._getData = function(refName, rowData) {
|
|
|
362
362
|
if (!this._rowData) {
|
|
363
363
|
return null;
|
|
364
364
|
}
|
|
365
|
-
|
|
365
|
+
let value = this._rowData[this.resolveReference(refName)];
|
|
366
366
|
|
|
367
367
|
if (value) {
|
|
368
|
-
|
|
368
|
+
let num = Number(value);
|
|
369
369
|
|
|
370
370
|
if (num === num) { // Convert text to number for formula calculation
|
|
371
371
|
value = num;
|
|
@@ -384,7 +384,7 @@ Engine.prototype._setFormulaReference = function(formula, ref) {
|
|
|
384
384
|
console.warn("Duplicate formula reference detected.");
|
|
385
385
|
return false;
|
|
386
386
|
}
|
|
387
|
-
|
|
387
|
+
let prevRef = formula.getReference();
|
|
388
388
|
if(prevRef === ref) {
|
|
389
389
|
return false;
|
|
390
390
|
}
|
|
@@ -393,7 +393,7 @@ Engine.prototype._setFormulaReference = function(formula, ref) {
|
|
|
393
393
|
this._formulaMap[ref] = formula;
|
|
394
394
|
}
|
|
395
395
|
formula._setReference(ref);
|
|
396
|
-
|
|
396
|
+
let dependencies = this._sortDependencies(this._formulas, this._formulaMap);
|
|
397
397
|
if (!dependencies) { // Circular dependencies detected
|
|
398
398
|
formula._setReference(prevRef);
|
|
399
399
|
delete this._formulaMap[ref];
|
|
@@ -413,17 +413,17 @@ Engine.prototype._setFormulaReference = function(formula, ref) {
|
|
|
413
413
|
Engine.prototype.calculate = function(rowData, opt_changes) {
|
|
414
414
|
this._rowData = rowData; // Cache for resolving reference
|
|
415
415
|
|
|
416
|
-
|
|
417
|
-
for(
|
|
418
|
-
|
|
416
|
+
let len = this._formulas.length;
|
|
417
|
+
for(let i = 0; i < len; ++i) { // This must be done in normal order
|
|
418
|
+
let f = this._formulas[i];
|
|
419
419
|
// if opt_changes is undefined then recalculate all function
|
|
420
420
|
// if opt_changes is exist then check formula need to recalculate
|
|
421
421
|
if (opt_changes) {
|
|
422
422
|
// Don't recalculate formula if fields are not changed and not update from realtime formula
|
|
423
|
-
|
|
423
|
+
let needRecalculate = (opt_changes[f.getAlias()] != null); // Update from realtime formula
|
|
424
424
|
if (!needRecalculate) {
|
|
425
|
-
|
|
426
|
-
for (
|
|
425
|
+
let fields = f.getFieldNames();
|
|
426
|
+
for (let j = fields.length; --j >= 0;) {
|
|
427
427
|
if (opt_changes[this.resolveReference(fields[j])] != null) {
|
|
428
428
|
needRecalculate = true;
|
|
429
429
|
break;
|
|
@@ -435,7 +435,7 @@ Engine.prototype.calculate = function(rowData, opt_changes) {
|
|
|
435
435
|
}
|
|
436
436
|
}
|
|
437
437
|
|
|
438
|
-
|
|
438
|
+
let result = f.calculate(rowData);
|
|
439
439
|
this._setData(f, result, rowData, opt_changes);
|
|
440
440
|
}
|
|
441
441
|
|
|
@@ -456,15 +456,15 @@ Engine.prototype.isValidReference = function(formula, ref) {
|
|
|
456
456
|
return false; // duplicate reference detected.
|
|
457
457
|
}
|
|
458
458
|
|
|
459
|
-
|
|
460
|
-
|
|
459
|
+
let prevRef = formula.getReference();
|
|
460
|
+
let parentChildrenMap = this._createParentChildrenMap(this._formulas);
|
|
461
461
|
|
|
462
462
|
// Replace the old reference with new reference
|
|
463
463
|
if (prevRef) {
|
|
464
464
|
delete parentChildrenMap[prevRef];
|
|
465
|
-
for (
|
|
466
|
-
|
|
467
|
-
|
|
465
|
+
for (let parent in parentChildrenMap) {
|
|
466
|
+
let children = parentChildrenMap[parent];
|
|
467
|
+
let index = children.indexOf(prevRef);
|
|
468
468
|
if (index !== -1) {
|
|
469
469
|
children = children.slice(0); // Clone. The orignal children is an array in formula object. We should not modify it.
|
|
470
470
|
children.splice(index, 1);
|
|
@@ -487,25 +487,25 @@ Engine.prototype.isValidReference = function(formula, ref) {
|
|
|
487
487
|
* @return {Array.<Formula>}
|
|
488
488
|
*/
|
|
489
489
|
Engine.prototype._sortDependencies = function(formulas, formulaMap) {
|
|
490
|
-
|
|
490
|
+
let formulaCount = formulas.length;
|
|
491
491
|
if (formulaCount === 1) {
|
|
492
492
|
return formulas;
|
|
493
493
|
}
|
|
494
494
|
|
|
495
|
-
|
|
496
|
-
|
|
495
|
+
let parentChildrenMap = this._createParentChildrenMap(formulas);
|
|
496
|
+
let sortedParents = this._sortParentChildrenMap(parentChildrenMap);
|
|
497
497
|
if (!sortedParents) {
|
|
498
498
|
return null;
|
|
499
499
|
}
|
|
500
500
|
|
|
501
|
-
|
|
501
|
+
let noDepFormulas = formulas.filter(function(f) {
|
|
502
502
|
return (!f.getReference());
|
|
503
503
|
});
|
|
504
504
|
|
|
505
|
-
|
|
505
|
+
let results = [];
|
|
506
506
|
if (formulaMap) {
|
|
507
|
-
for(
|
|
508
|
-
|
|
507
|
+
for(let i = sortedParents.length; --i >= 0;) {
|
|
508
|
+
let f = formulaMap[sortedParents[i]];
|
|
509
509
|
if(f) {
|
|
510
510
|
results.push(f); // The one in the back will be executed last
|
|
511
511
|
}
|
|
@@ -523,10 +523,10 @@ Engine.prototype._sortDependencies = function(formulas, formulaMap) {
|
|
|
523
523
|
* @return {Object.<string, Array.<string>>}
|
|
524
524
|
*/
|
|
525
525
|
Engine.prototype._createParentChildrenMap = function(formulas) {
|
|
526
|
-
|
|
526
|
+
let i, parentChildrenMap = {};
|
|
527
527
|
for (i = formulas.length; --i >= 0;) {
|
|
528
|
-
|
|
529
|
-
|
|
528
|
+
let f = formulas[i];
|
|
529
|
+
let ref = f.getReference();
|
|
530
530
|
if (ref) {
|
|
531
531
|
parentChildrenMap[ref] = f.getFieldNames();
|
|
532
532
|
}
|
|
@@ -540,20 +540,20 @@ Engine.prototype._createParentChildrenMap = function(formulas) {
|
|
|
540
540
|
* @return {Array.<string>}
|
|
541
541
|
*/
|
|
542
542
|
Engine.prototype._sortParentChildrenMap = function(ParentChildrenMap) {
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
543
|
+
let edges = {};
|
|
544
|
+
let i, child, children, childCount;
|
|
545
|
+
let parent;
|
|
546
546
|
for (parent in ParentChildrenMap) {
|
|
547
547
|
children = ParentChildrenMap[parent];
|
|
548
548
|
childCount = children.length;
|
|
549
|
-
for(
|
|
549
|
+
for(let j = 0; j < childCount; ++j) {
|
|
550
550
|
child = children[j];
|
|
551
551
|
edges[child] = (edges[child] + 1) || 1;
|
|
552
552
|
}
|
|
553
553
|
}
|
|
554
554
|
|
|
555
555
|
// Collect nodes with no edge (root nodes)
|
|
556
|
-
|
|
556
|
+
let rootNodes = [];
|
|
557
557
|
for(parent in ParentChildrenMap) {
|
|
558
558
|
if(!edges[parent]) {
|
|
559
559
|
rootNodes.push(parent);
|
|
@@ -561,7 +561,7 @@ Engine.prototype._sortParentChildrenMap = function(ParentChildrenMap) {
|
|
|
561
561
|
}
|
|
562
562
|
|
|
563
563
|
// Navigate from root nodes down to all the leaf nodes
|
|
564
|
-
|
|
564
|
+
let sortedParents = [];
|
|
565
565
|
while(rootNodes.length > 0) {
|
|
566
566
|
parent = rootNodes.shift();
|
|
567
567
|
sortedParents.push(parent);
|
|
@@ -11,7 +11,7 @@ import EventDispatcher from "../EventDispatcher.js";
|
|
|
11
11
|
* @param {string=} expression
|
|
12
12
|
* @param {Object=} context
|
|
13
13
|
*/
|
|
14
|
-
|
|
14
|
+
let Formula = function(expression, context) {
|
|
15
15
|
this._input = expression || "";
|
|
16
16
|
if(context != null) {
|
|
17
17
|
this._context = context;
|
|
@@ -172,7 +172,7 @@ Formula.prototype.dispose = function() {
|
|
|
172
172
|
this._rtService["dispose"]();
|
|
173
173
|
this._rtService = null;
|
|
174
174
|
}
|
|
175
|
-
for(
|
|
175
|
+
for(let serviceName in this._intervalServices) {
|
|
176
176
|
// No need to dispose the static object
|
|
177
177
|
this._intervalServices[serviceName]["removeEventListener"]("dataChanged", this.dispatchDataChanged);
|
|
178
178
|
}
|
|
@@ -187,7 +187,7 @@ Formula.prototype.dispose = function() {
|
|
|
187
187
|
Formula.prototype.calculate = function(rowData) {
|
|
188
188
|
if (this._main) {
|
|
189
189
|
this._dataLastError = ""; // Clear last realtime error message
|
|
190
|
-
|
|
190
|
+
let res = this._main(rowData);
|
|
191
191
|
switch(this._dataLastError) {
|
|
192
192
|
case "Pending data": // Don't show data if realtime data is still pending
|
|
193
193
|
res = null;
|
|
@@ -276,9 +276,9 @@ Formula.prototype.subtractFormulaCount = function() {
|
|
|
276
276
|
Formula.prototype.updateContext = function() {
|
|
277
277
|
if(!this._context) { return; }
|
|
278
278
|
|
|
279
|
-
|
|
280
|
-
for(
|
|
281
|
-
|
|
279
|
+
let len = this._fnTokens.length;
|
|
280
|
+
for(let i = 0; i < len; ++i) {
|
|
281
|
+
let fname = this._fnTokens[i].getFunctionName();
|
|
282
282
|
this["__F"][i] = this._context[fname] || Formula._emptyFunction;
|
|
283
283
|
if (Formula._isBoundFormula[fname]) {
|
|
284
284
|
this["__F"][i] = this["__F"][i].bind(this);
|
|
@@ -302,17 +302,17 @@ Formula._emptyFunction = function() {};
|
|
|
302
302
|
* @return {boolean}
|
|
303
303
|
*/
|
|
304
304
|
Formula.prototype._detectCodeInjection = function(str) {
|
|
305
|
-
|
|
305
|
+
let injection = false;
|
|
306
306
|
|
|
307
307
|
if(str.match(/\+\+|--/)) { // ++ and -- which modifies current variable is not allowed
|
|
308
308
|
injection = true;
|
|
309
309
|
}
|
|
310
310
|
|
|
311
311
|
if(!injection) {
|
|
312
|
-
|
|
313
|
-
for (
|
|
314
|
-
|
|
315
|
-
|
|
312
|
+
let matches = str.match(/([^=]=+)/g) || [];
|
|
313
|
+
for (let i = matches.length; --i >= 0;) {
|
|
314
|
+
let m = matches[i];
|
|
315
|
+
let lastTwoChars = m.substring(m.length - 2);
|
|
316
316
|
if (Formula._invalidOps[lastTwoChars]) {
|
|
317
317
|
injection = true;
|
|
318
318
|
break;
|
|
@@ -336,8 +336,8 @@ Formula.toUpperCase = function(exp) {
|
|
|
336
336
|
return exp || "";
|
|
337
337
|
}
|
|
338
338
|
|
|
339
|
-
|
|
340
|
-
|
|
339
|
+
let tokens = [];
|
|
340
|
+
let calcHierarchy = [];
|
|
341
341
|
|
|
342
342
|
// Tokenize string constants first because they has enclosure (single quotes and double quotes)
|
|
343
343
|
exp = Formula.tokenizeQuotes(exp, tokens, calcHierarchy);
|
|
@@ -385,9 +385,9 @@ Formula.tokenizeQuotes = function(exp, tokens, calcHierarchy) {
|
|
|
385
385
|
calcHierarchy = [];
|
|
386
386
|
}
|
|
387
387
|
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
388
|
+
let index;
|
|
389
|
+
let matched = false;
|
|
390
|
+
let tokenIndices = [];
|
|
391
391
|
do {
|
|
392
392
|
matched = false;
|
|
393
393
|
exp = exp.replace(/(["'])(?:(?=(\\?))\2.)*?\1/g, function(str) { // eslint-disable-line
|
|
@@ -416,9 +416,9 @@ Formula.tokenizeAdcWithParams = function(exp, tokens, calcHierarchy) {
|
|
|
416
416
|
calcHierarchy = [];
|
|
417
417
|
}
|
|
418
418
|
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
419
|
+
let index;
|
|
420
|
+
let matched = false;
|
|
421
|
+
let tokenIndices = [];
|
|
422
422
|
do {
|
|
423
423
|
matched = false;
|
|
424
424
|
exp = exp.replace(/TR\.\w+\([^\)]*\)+/g, function(str) { // eslint-disable-line
|
|
@@ -490,18 +490,18 @@ Formula.prototype._tokenizeParentheses = function(exp, tokens, calcHierarchy) {
|
|
|
490
490
|
calcHierarchy = [];
|
|
491
491
|
}
|
|
492
492
|
|
|
493
|
-
|
|
493
|
+
let fnStrToIndex = {}; // To avoid duplicate function
|
|
494
494
|
|
|
495
495
|
/**
|
|
496
496
|
* It is better to not duplicate content of regular expressions to avoid any possible typos
|
|
497
497
|
* or discrepancies.
|
|
498
498
|
* Therefore we copy existing regular expression and assign new flags to it instead.
|
|
499
499
|
*/
|
|
500
|
-
|
|
501
|
-
|
|
500
|
+
let firstMatchRE = /[\w._]*(?:=|=[\w]*)?\([^()]*\)/;
|
|
501
|
+
let globalRE = new RegExp(firstMatchRE.source, 'g');
|
|
502
502
|
|
|
503
503
|
while (exp.match(firstMatchRE)) {
|
|
504
|
-
|
|
504
|
+
let tokenIndices = [];
|
|
505
505
|
|
|
506
506
|
exp = exp.replace(globalRE, function (fnStr, group) { // eslint-disable-line
|
|
507
507
|
// Remove the first equal sign.
|
|
@@ -509,7 +509,7 @@ Formula.prototype._tokenizeParentheses = function(exp, tokens, calcHierarchy) {
|
|
|
509
509
|
fnStr = fnStr.substr(1, fnStr.length);
|
|
510
510
|
}
|
|
511
511
|
|
|
512
|
-
|
|
512
|
+
let index = fnStrToIndex[fnStr];
|
|
513
513
|
|
|
514
514
|
if (index == null) {
|
|
515
515
|
index = tokens.length;
|
|
@@ -541,12 +541,12 @@ Formula.prototype._tokenizeConstants = function(exp, tokens, calcHierarchy) {
|
|
|
541
541
|
calcHierarchy = [];
|
|
542
542
|
}
|
|
543
543
|
|
|
544
|
-
|
|
544
|
+
let tokenIndices = [];
|
|
545
545
|
exp = exp.replace(/[\w._♦]+/g, function(varStr) {
|
|
546
546
|
if (varStr.charAt(0) === "♦") {
|
|
547
547
|
return varStr;
|
|
548
548
|
}
|
|
549
|
-
|
|
549
|
+
let index = tokens.length;
|
|
550
550
|
tokens.push(new VariableToken(varStr, index));
|
|
551
551
|
tokenIndices.push(index);
|
|
552
552
|
return "♦" + index + "♦";
|
|
@@ -561,12 +561,12 @@ Formula.prototype._tokenizeConstants = function(exp, tokens, calcHierarchy) {
|
|
|
561
561
|
* @return {string}
|
|
562
562
|
*/
|
|
563
563
|
Formula.resolveTokens = function(exp, tokens, calcHierarchy) {
|
|
564
|
-
for(
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
for(
|
|
568
|
-
|
|
569
|
-
|
|
564
|
+
for(let i = calcHierarchy.length; --i >= 0;) { // Must be done in reverse order
|
|
565
|
+
let indices = calcHierarchy[i];
|
|
566
|
+
let len = indices.length;
|
|
567
|
+
for(let j = 0; j < len; ++j) {
|
|
568
|
+
let index = indices[j];
|
|
569
|
+
let token = tokens[index];
|
|
570
570
|
exp = exp.replace(new RegExp("♦" + index + "♦", "g"), function() { // eslint-disable-line
|
|
571
571
|
return token.getExpression();
|
|
572
572
|
});
|
|
@@ -582,12 +582,12 @@ Formula.resolveTokens = function(exp, tokens, calcHierarchy) {
|
|
|
582
582
|
* @return {string}
|
|
583
583
|
*/
|
|
584
584
|
Formula._getInputWithTokenField = function(exp, tokens, calcHierarchy) {
|
|
585
|
-
for(
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
for(
|
|
589
|
-
|
|
590
|
-
|
|
585
|
+
for(let i = calcHierarchy.length; --i >= 0;) { // Must be done in reverse order
|
|
586
|
+
let indices = calcHierarchy[i];
|
|
587
|
+
let len = indices.length;
|
|
588
|
+
for(let j = 0; j < len; ++j) {
|
|
589
|
+
let index = indices[j];
|
|
590
|
+
let token = tokens[index];
|
|
591
591
|
exp = exp.replace(new RegExp("♦" + index + "♦", "g"), function() { // eslint-disable-line
|
|
592
592
|
return token.getInputWithTokenField();
|
|
593
593
|
});
|
|
@@ -620,8 +620,8 @@ Formula.prototype._parse = function(exp) {
|
|
|
620
620
|
|
|
621
621
|
if(!exp || this._detectCodeInjection(exp)) { return null; }
|
|
622
622
|
|
|
623
|
-
|
|
624
|
-
|
|
623
|
+
let tokens = [];
|
|
624
|
+
let calcHierarchy = [];
|
|
625
625
|
|
|
626
626
|
exp = Formula.tokenizeQuotes(exp, tokens, calcHierarchy); // Tokenize string constants first because they has enclosure (single quotes and double quotes)
|
|
627
627
|
|
|
@@ -640,12 +640,12 @@ Formula.prototype._parse = function(exp) {
|
|
|
640
640
|
exp = Formula.resolveTokens(exp, tokens, calcHierarchy);
|
|
641
641
|
|
|
642
642
|
// Re-organize function structure and index, and retrieve field data
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
for(
|
|
646
|
-
|
|
643
|
+
let fields = {};
|
|
644
|
+
let len = tokens.length;
|
|
645
|
+
for(let i = 0; i < len; ++i) {
|
|
646
|
+
let token = tokens[i];
|
|
647
647
|
if(token.getFunctionName()) {
|
|
648
|
-
|
|
648
|
+
let fIndex = this._fnTokens.length;
|
|
649
649
|
exp = exp.replace(new RegExp("this\\.__F\\[" + i + "\\]", "g"), "this.__F[" + fIndex + "]");
|
|
650
650
|
token.setIndex(fIndex);
|
|
651
651
|
this._fnTokens.push(token);
|
|
@@ -671,7 +671,7 @@ Formula.prototype._parse = function(exp) {
|
|
|
671
671
|
* @return {Function}
|
|
672
672
|
*/
|
|
673
673
|
Formula.prototype._createFunction = function (expression) {
|
|
674
|
-
|
|
674
|
+
let func = null;
|
|
675
675
|
try {
|
|
676
676
|
func = new Function("__R", "return " + expression + ";");
|
|
677
677
|
func = func.bind(this);
|
|
@@ -718,7 +718,7 @@ Formula.prototype.addField = function(field, opt_src) {
|
|
|
718
718
|
* @return {boolean}
|
|
719
719
|
*/
|
|
720
720
|
Formula.prototype.changeField = function (oldName, newName) {
|
|
721
|
-
|
|
721
|
+
let index = this._fields.indexOf(oldName);
|
|
722
722
|
if (index < 0) {
|
|
723
723
|
return false;
|
|
724
724
|
}
|
|
@@ -726,9 +726,9 @@ Formula.prototype.changeField = function (oldName, newName) {
|
|
|
726
726
|
if (this._fields.indexOf(newName) < 0) {
|
|
727
727
|
this._fields.push(newName);
|
|
728
728
|
}
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
729
|
+
let oldInput = this._input;
|
|
730
|
+
let oldTokenField = "♠" + oldName + "♥";
|
|
731
|
+
let newTokenField = "♠" + newName + "♥";
|
|
732
732
|
this._inputWithTokenField = this._inputWithTokenField.replace(new RegExp("♠[^♠]*♥", "g"), function(str) {
|
|
733
733
|
return (str === oldTokenField) ? newTokenField : str;
|
|
734
734
|
});
|
|
@@ -754,12 +754,12 @@ Formula.prototype.changeFields = function (oldNames, newNames) {
|
|
|
754
754
|
return false;
|
|
755
755
|
}
|
|
756
756
|
|
|
757
|
-
|
|
758
|
-
for(
|
|
759
|
-
|
|
760
|
-
|
|
757
|
+
let oldInput = this._input;
|
|
758
|
+
for(let i = oldNames.length; --i >= 0;) {
|
|
759
|
+
let oldName = oldNames[i];
|
|
760
|
+
let newName = newNames[i];
|
|
761
761
|
|
|
762
|
-
|
|
762
|
+
let index = this._fields.indexOf(oldName);
|
|
763
763
|
if (index < 0) {
|
|
764
764
|
continue;
|
|
765
765
|
}
|
|
@@ -769,8 +769,8 @@ Formula.prototype.changeFields = function (oldNames, newNames) {
|
|
|
769
769
|
this._fields.push(newName);
|
|
770
770
|
}
|
|
771
771
|
|
|
772
|
-
|
|
773
|
-
|
|
772
|
+
let oldTokenField = "♠" + oldName + "♥";
|
|
773
|
+
let newTokenField = "♠" + newName + "♥";
|
|
774
774
|
|
|
775
775
|
this._inputWithTokenField = this._inputWithTokenField.replace(new RegExp("♠[^♠]*♥", "g"), function(str) { // eslint-disable-line
|
|
776
776
|
return (str === oldTokenField) ? newTokenField : str;
|
|
@@ -824,7 +824,7 @@ Formula.prototype.setIntervalService = function(funcName, newService) {
|
|
|
824
824
|
return;
|
|
825
825
|
}
|
|
826
826
|
|
|
827
|
-
|
|
827
|
+
let service = this._intervalServices[funcName];
|
|
828
828
|
if (service) {
|
|
829
829
|
service["removeEventListener"]("dataChanged", this.dispatchDataChanged); // Service will stop only if no event listener anymore
|
|
830
830
|
}
|
|
@@ -870,11 +870,11 @@ Formula.prototype.dispatchDataChanged = function(e) {
|
|
|
870
870
|
*/
|
|
871
871
|
Formula.prototype._onDataCacheChanged = function(e) {
|
|
872
872
|
// Cache data for real-time function since real-time function has its own RIC list. Then dispatch the event.
|
|
873
|
-
|
|
874
|
-
|
|
875
|
-
|
|
873
|
+
let symbol = e['ric'];
|
|
874
|
+
let values = /** @type{Object.<string, *>} */(e['values']);
|
|
875
|
+
let data = this._dataCache[symbol];
|
|
876
876
|
if (data) {
|
|
877
|
-
for (
|
|
877
|
+
for (let field in values) {
|
|
878
878
|
data[field] = values[field];
|
|
879
879
|
}
|
|
880
880
|
} else {
|
|
@@ -8,7 +8,7 @@ import {EventDispatcher} from "../EventDispatcher.js";
|
|
|
8
8
|
* @param {Function=} func
|
|
9
9
|
* @param {number=} time=3600000 Interval duration
|
|
10
10
|
*/
|
|
11
|
-
|
|
11
|
+
let IntervalSubscription = function(funcName, func, time) {
|
|
12
12
|
if(typeof func !== "function") {
|
|
13
13
|
console.warn("No function is provided");
|
|
14
14
|
return;
|
|
@@ -130,7 +130,7 @@ IntervalSubscription.prototype.removeAllEventListeners = function() {
|
|
|
130
130
|
*/
|
|
131
131
|
IntervalSubscription.prototype._start = function() {
|
|
132
132
|
if(!this._intervalId) {
|
|
133
|
-
|
|
133
|
+
let calTime = this._intervalTime - (Date.now() % this._intervalTime);
|
|
134
134
|
this._intervalId = setTimeout(this._onValueUpdate, calTime);
|
|
135
135
|
}
|
|
136
136
|
};
|
|
@@ -149,7 +149,7 @@ IntervalSubscription.prototype._stop = function() {
|
|
|
149
149
|
IntervalSubscription.prototype._onValueUpdate = function() {
|
|
150
150
|
this._value = this._func() || null;
|
|
151
151
|
|
|
152
|
-
|
|
152
|
+
let rowData = {};
|
|
153
153
|
rowData[this._funcName] = this._value;
|
|
154
154
|
this._dispatch("dataChanged", {
|
|
155
155
|
"function": this._funcName,
|