@trebco/treb 27.5.3 → 27.9.0
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/dist/treb-spreadsheet.mjs +14 -14
- package/dist/treb.d.ts +37 -23
- package/notes/conditional-fomratring.md +29 -0
- package/package.json +3 -3
- package/treb-base-types/src/area.ts +181 -0
- package/treb-base-types/src/evaluate-options.ts +21 -0
- package/treb-base-types/src/gradient.ts +97 -0
- package/treb-base-types/src/import.ts +2 -1
- package/treb-base-types/src/index.ts +2 -0
- package/treb-calculator/src/calculator.ts +205 -132
- package/treb-calculator/src/dag/calculation_leaf_vertex.ts +97 -0
- package/treb-calculator/src/dag/graph.ts +10 -22
- package/treb-calculator/src/dag/{leaf_vertex.ts → state_leaf_vertex.ts} +3 -3
- package/treb-calculator/src/descriptors.ts +10 -3
- package/treb-calculator/src/expression-calculator.ts +1 -1
- package/treb-calculator/src/function-library.ts +25 -22
- package/treb-calculator/src/functions/base-functions.ts +166 -5
- package/treb-calculator/src/index.ts +6 -6
- package/treb-calculator/src/notifier-types.ts +1 -1
- package/treb-calculator/src/utilities.ts +2 -2
- package/treb-charts/src/util.ts +2 -2
- package/treb-embed/src/embedded-spreadsheet.ts +382 -71
- package/treb-embed/style/formula-bar.scss +2 -0
- package/treb-embed/style/theme-defaults.scss +46 -15
- package/treb-export/src/export-worker/export-worker.ts +0 -13
- package/treb-export/src/export2.ts +187 -2
- package/treb-export/src/import2.ts +169 -4
- package/treb-export/src/workbook-style2.ts +56 -8
- package/treb-export/src/workbook2.ts +10 -1
- package/treb-grid/src/editors/editor.ts +1276 -0
- package/treb-grid/src/editors/external_editor.ts +113 -0
- package/treb-grid/src/editors/formula_bar.ts +450 -474
- package/treb-grid/src/editors/overlay_editor.ts +437 -512
- package/treb-grid/src/index.ts +2 -1
- package/treb-grid/src/layout/base_layout.ts +24 -16
- package/treb-grid/src/render/tile_renderer.ts +2 -1
- package/treb-grid/src/types/conditional_format.ts +168 -0
- package/treb-grid/src/types/data_model.ts +130 -3
- package/treb-grid/src/types/external_editor_config.ts +47 -0
- package/treb-grid/src/types/grid.ts +96 -45
- package/treb-grid/src/types/grid_base.ts +187 -35
- package/treb-grid/src/types/scale-control.ts +1 -1
- package/treb-grid/src/types/sheet.ts +330 -26
- package/treb-grid/src/types/sheet_types.ts +4 -0
- package/treb-grid/src/util/dom_utilities.ts +58 -25
- package/treb-grid/src/editors/formula_editor_base.ts +0 -912
- package/treb-grid/src/types/external_editor.ts +0 -27
- /package/{README-shadow-DOM.md → notes/shadow-DOM.md} +0 -0
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
|
|
2
|
+
import { Editor, type NodeDescriptor } from './editor';
|
|
3
|
+
|
|
4
|
+
export class ExternalEditor extends Editor {
|
|
5
|
+
|
|
6
|
+
public get active() {
|
|
7
|
+
return this.nodes.length > 0;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
public Reset() {
|
|
11
|
+
this.AttachNodes();
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* attach to a set of nodes (one is fine).
|
|
16
|
+
*
|
|
17
|
+
* FIXME: since this is not used in subclasses for ICE and formula bar,
|
|
18
|
+
* perhaps we should move it into a new subclass specifically for
|
|
19
|
+
* external editor. we can add some flags as well. TODO/FIXME
|
|
20
|
+
*
|
|
21
|
+
* update modifying how this works. we will now watch focus ourselves.
|
|
22
|
+
*/
|
|
23
|
+
public AttachNodes(nodes: HTMLElement[] = [], assume_formula = true) {
|
|
24
|
+
|
|
25
|
+
this.assume_formula = assume_formula;
|
|
26
|
+
|
|
27
|
+
// try to preserve any nodes/descriptors we've already "cooked",
|
|
28
|
+
// since this may get called multiple times when you switch between
|
|
29
|
+
// fields.
|
|
30
|
+
|
|
31
|
+
// (that's less true than before, but still might happen).
|
|
32
|
+
|
|
33
|
+
let descriptors: NodeDescriptor[] = [];
|
|
34
|
+
|
|
35
|
+
descriptors = nodes.map(node => {
|
|
36
|
+
for (const compare of this.nodes) {
|
|
37
|
+
if (compare.node === node) {
|
|
38
|
+
return compare;
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
return { node }; // not found, return a new one
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
// we should probably clean up here. if there's overlap we will just
|
|
45
|
+
// add a new one. note that we're looping over the *old* set here,
|
|
46
|
+
// so don't try to optimize by moving this into another loop.
|
|
47
|
+
|
|
48
|
+
for (const descriptor of this.nodes) {
|
|
49
|
+
if (descriptor.listeners) {
|
|
50
|
+
for (const [key, value] of descriptor.listeners.entries()) {
|
|
51
|
+
descriptor.node.removeEventListener(key, value);
|
|
52
|
+
}
|
|
53
|
+
descriptor.listeners.clear();
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
this.nodes = descriptors;
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
for (const descriptor of this.nodes) {
|
|
61
|
+
|
|
62
|
+
// check if we need to flush the cached text
|
|
63
|
+
|
|
64
|
+
if (descriptor.formatted_text === descriptor.node.textContent) {
|
|
65
|
+
const test = descriptor.node.innerHTML.length;
|
|
66
|
+
if (descriptor.check !== test) {
|
|
67
|
+
descriptor.formatted_text = undefined; // flush
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
// if it's already focused, set as active
|
|
72
|
+
|
|
73
|
+
if (document.activeElement === descriptor.node) {
|
|
74
|
+
this.active_editor = descriptor;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
// format
|
|
78
|
+
|
|
79
|
+
this.UpdateText(descriptor, { toll_events: true });
|
|
80
|
+
|
|
81
|
+
// add listeners
|
|
82
|
+
|
|
83
|
+
this.RegisterListener(descriptor, 'focusin', () => {
|
|
84
|
+
// console.info('focusin');
|
|
85
|
+
this.active_editor = descriptor;
|
|
86
|
+
});
|
|
87
|
+
|
|
88
|
+
this.RegisterListener(descriptor, 'focusout', () => {
|
|
89
|
+
// console.info('focusout');
|
|
90
|
+
this.active_editor = undefined;
|
|
91
|
+
});
|
|
92
|
+
|
|
93
|
+
this.RegisterListener(descriptor, 'input', (event: Event) => {
|
|
94
|
+
|
|
95
|
+
// we're filtering on trusted here because we send an event.
|
|
96
|
+
// but when we send that event we also trigger an update.
|
|
97
|
+
// so... why not just run through the event handler?
|
|
98
|
+
|
|
99
|
+
if (event.isTrusted) {
|
|
100
|
+
this.UpdateText(descriptor);
|
|
101
|
+
this.UpdateColors(); // will send a local event
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
});
|
|
105
|
+
|
|
106
|
+
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
this.UpdateColors(true); // always send an event, just in case
|
|
110
|
+
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
}
|