@trebco/treb 23.6.5 → 25.0.0-rc2
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/.eslintignore +8 -0
- package/.eslintrc.js +164 -0
- package/README-shadow-DOM.md +88 -0
- package/README.md +37 -130
- package/api-config.json +29 -0
- package/api-generator/api-generator-types.ts +82 -0
- package/api-generator/api-generator.ts +1172 -0
- package/api-generator/package.json +3 -0
- package/build/treb-spreadsheet.mjs +14 -0
- package/{treb.d.ts → build/treb.d.ts} +323 -271
- package/esbuild-custom-element.mjs +336 -0
- package/esbuild.js +305 -0
- package/package.json +49 -14
- package/treb-base-types/package.json +5 -0
- package/treb-base-types/src/api_types.ts +36 -0
- package/treb-base-types/src/area.ts +583 -0
- package/treb-base-types/src/basic_types.ts +45 -0
- package/treb-base-types/src/cell.ts +612 -0
- package/treb-base-types/src/cells.ts +1066 -0
- package/treb-base-types/src/color.ts +124 -0
- package/treb-base-types/src/import.ts +71 -0
- package/treb-base-types/src/index-standalone.ts +29 -0
- package/treb-base-types/src/index.ts +42 -0
- package/treb-base-types/src/layout.ts +47 -0
- package/treb-base-types/src/localization.ts +187 -0
- package/treb-base-types/src/rectangle.ts +145 -0
- package/treb-base-types/src/render_text.ts +72 -0
- package/treb-base-types/src/style.ts +545 -0
- package/treb-base-types/src/table.ts +109 -0
- package/treb-base-types/src/text_part.ts +54 -0
- package/treb-base-types/src/theme.ts +608 -0
- package/treb-base-types/src/union.ts +152 -0
- package/treb-base-types/src/value-type.ts +164 -0
- package/treb-base-types/style/resizable.css +59 -0
- package/treb-calculator/modern.tsconfig.json +11 -0
- package/treb-calculator/package.json +5 -0
- package/treb-calculator/src/calculator.ts +2546 -0
- package/treb-calculator/src/complex-math.ts +558 -0
- package/treb-calculator/src/dag/array-vertex.ts +198 -0
- package/treb-calculator/src/dag/graph.ts +951 -0
- package/treb-calculator/src/dag/leaf_vertex.ts +118 -0
- package/treb-calculator/src/dag/spreadsheet_vertex.ts +327 -0
- package/treb-calculator/src/dag/spreadsheet_vertex_base.ts +44 -0
- package/treb-calculator/src/dag/vertex.ts +352 -0
- package/treb-calculator/src/descriptors.ts +162 -0
- package/treb-calculator/src/expression-calculator.ts +1069 -0
- package/treb-calculator/src/function-error.ts +103 -0
- package/treb-calculator/src/function-library.ts +103 -0
- package/treb-calculator/src/functions/base-functions.ts +1214 -0
- package/treb-calculator/src/functions/checkbox.ts +164 -0
- package/treb-calculator/src/functions/complex-functions.ts +253 -0
- package/treb-calculator/src/functions/finance-functions.ts +399 -0
- package/treb-calculator/src/functions/information-functions.ts +102 -0
- package/treb-calculator/src/functions/matrix-functions.ts +182 -0
- package/treb-calculator/src/functions/sparkline.ts +335 -0
- package/treb-calculator/src/functions/statistics-functions.ts +350 -0
- package/treb-calculator/src/functions/text-functions.ts +298 -0
- package/treb-calculator/src/index.ts +27 -0
- package/treb-calculator/src/notifier-types.ts +59 -0
- package/treb-calculator/src/primitives.ts +428 -0
- package/treb-calculator/src/utilities.ts +305 -0
- package/treb-charts/package.json +5 -0
- package/treb-charts/src/chart-functions.ts +156 -0
- package/treb-charts/src/chart-types.ts +230 -0
- package/treb-charts/src/chart.ts +1288 -0
- package/treb-charts/src/index.ts +24 -0
- package/treb-charts/src/main.ts +37 -0
- package/treb-charts/src/rectangle.ts +52 -0
- package/treb-charts/src/renderer.ts +1841 -0
- package/treb-charts/src/util.ts +122 -0
- package/treb-charts/style/charts.scss +221 -0
- package/treb-charts/style/old-charts.scss +250 -0
- package/treb-embed/markup/layout.html +137 -0
- package/treb-embed/markup/toolbar.html +175 -0
- package/treb-embed/modern.tsconfig.json +25 -0
- package/treb-embed/src/custom-element/content-types.d.ts +18 -0
- package/treb-embed/src/custom-element/global.d.ts +11 -0
- package/treb-embed/src/custom-element/spreadsheet-constructor.ts +1228 -0
- package/treb-embed/src/custom-element/treb-global.ts +44 -0
- package/treb-embed/src/custom-element/treb-spreadsheet-element.ts +52 -0
- package/treb-embed/src/embedded-spreadsheet.ts +5358 -0
- package/treb-embed/src/index.ts +16 -0
- package/treb-embed/src/language-model.ts +41 -0
- package/treb-embed/src/options.ts +298 -0
- package/treb-embed/src/progress-dialog.ts +228 -0
- package/treb-embed/src/selection-state.ts +16 -0
- package/treb-embed/src/spinner.ts +42 -0
- package/treb-embed/src/toolbar-message.ts +96 -0
- package/treb-embed/src/types.ts +167 -0
- package/treb-embed/style/autocomplete.scss +103 -0
- package/treb-embed/style/dark-theme.scss +114 -0
- package/treb-embed/style/defaults.scss +36 -0
- package/treb-embed/style/dialog.scss +181 -0
- package/treb-embed/style/dropdown-select.scss +101 -0
- package/treb-embed/style/formula-bar.scss +193 -0
- package/treb-embed/style/grid.scss +374 -0
- package/treb-embed/style/layout.scss +424 -0
- package/treb-embed/style/mouse-mask.scss +67 -0
- package/treb-embed/style/note.scss +92 -0
- package/treb-embed/style/overlay-editor.scss +102 -0
- package/treb-embed/style/spinner.scss +92 -0
- package/treb-embed/style/tab-bar.scss +228 -0
- package/treb-embed/style/table.scss +80 -0
- package/treb-embed/style/theme-defaults.scss +444 -0
- package/treb-embed/style/toolbar.scss +416 -0
- package/treb-embed/style/tooltip.scss +68 -0
- package/treb-embed/style/treb-icons.scss +130 -0
- package/treb-embed/style/treb-spreadsheet-element.scss +20 -0
- package/treb-embed/style/z-index.scss +43 -0
- package/treb-export/docs/charts.md +68 -0
- package/treb-export/modern.tsconfig.json +19 -0
- package/treb-export/package.json +4 -0
- package/treb-export/src/address-type.ts +77 -0
- package/treb-export/src/base-template.ts +22 -0
- package/treb-export/src/column-width.ts +85 -0
- package/treb-export/src/drawing2/chart-template-components2.ts +389 -0
- package/treb-export/src/drawing2/chart2.ts +282 -0
- package/treb-export/src/drawing2/column-chart-template2.ts +521 -0
- package/treb-export/src/drawing2/donut-chart-template2.ts +296 -0
- package/treb-export/src/drawing2/drawing2.ts +355 -0
- package/treb-export/src/drawing2/embedded-image.ts +71 -0
- package/treb-export/src/drawing2/scatter-chart-template2.ts +555 -0
- package/treb-export/src/export-worker/export-worker.ts +99 -0
- package/treb-export/src/export-worker/index-modern.ts +22 -0
- package/treb-export/src/export2.ts +2204 -0
- package/treb-export/src/import2.ts +882 -0
- package/treb-export/src/relationship.ts +36 -0
- package/treb-export/src/shared-strings2.ts +128 -0
- package/treb-export/src/template-2.ts +22 -0
- package/treb-export/src/unescape_xml.ts +47 -0
- package/treb-export/src/workbook-sheet2.ts +182 -0
- package/treb-export/src/workbook-style2.ts +1285 -0
- package/treb-export/src/workbook-theme2.ts +88 -0
- package/treb-export/src/workbook2.ts +491 -0
- package/treb-export/src/xml-utils.ts +201 -0
- package/treb-export/template/base/[Content_Types].xml +2 -0
- package/treb-export/template/base/_rels/.rels +2 -0
- package/treb-export/template/base/docProps/app.xml +2 -0
- package/treb-export/template/base/docProps/core.xml +12 -0
- package/treb-export/template/base/xl/_rels/workbook.xml.rels +2 -0
- package/treb-export/template/base/xl/sharedStrings.xml +2 -0
- package/treb-export/template/base/xl/styles.xml +2 -0
- package/treb-export/template/base/xl/theme/theme1.xml +2 -0
- package/treb-export/template/base/xl/workbook.xml +2 -0
- package/treb-export/template/base/xl/worksheets/sheet1.xml +2 -0
- package/treb-export/template/base.xlsx +0 -0
- package/treb-format/package.json +8 -0
- package/treb-format/src/format.test.ts +213 -0
- package/treb-format/src/format.ts +942 -0
- package/treb-format/src/format_cache.ts +199 -0
- package/treb-format/src/format_parser.ts +723 -0
- package/treb-format/src/index.ts +25 -0
- package/treb-format/src/number_format_section.ts +100 -0
- package/treb-format/src/value_parser.ts +337 -0
- package/treb-grid/package.json +5 -0
- package/treb-grid/src/editors/autocomplete.ts +394 -0
- package/treb-grid/src/editors/autocomplete_matcher.ts +260 -0
- package/treb-grid/src/editors/formula_bar.ts +473 -0
- package/treb-grid/src/editors/formula_editor_base.ts +910 -0
- package/treb-grid/src/editors/overlay_editor.ts +511 -0
- package/treb-grid/src/index.ts +37 -0
- package/treb-grid/src/layout/base_layout.ts +2618 -0
- package/treb-grid/src/layout/grid_layout.ts +299 -0
- package/treb-grid/src/layout/rectangle_cache.ts +86 -0
- package/treb-grid/src/render/selection-renderer.ts +414 -0
- package/treb-grid/src/render/svg_header_overlay.ts +93 -0
- package/treb-grid/src/render/svg_selection_block.ts +187 -0
- package/treb-grid/src/render/tile_renderer.ts +2122 -0
- package/treb-grid/src/types/annotation.ts +216 -0
- package/treb-grid/src/types/border_constants.ts +34 -0
- package/treb-grid/src/types/clipboard_data.ts +31 -0
- package/treb-grid/src/types/data_model.ts +334 -0
- package/treb-grid/src/types/drag_mask.ts +81 -0
- package/treb-grid/src/types/grid.ts +7743 -0
- package/treb-grid/src/types/grid_base.ts +3644 -0
- package/treb-grid/src/types/grid_command.ts +470 -0
- package/treb-grid/src/types/grid_events.ts +124 -0
- package/treb-grid/src/types/grid_options.ts +97 -0
- package/treb-grid/src/types/grid_selection.ts +60 -0
- package/treb-grid/src/types/named_range.ts +369 -0
- package/treb-grid/src/types/scale-control.ts +202 -0
- package/treb-grid/src/types/serialize_options.ts +72 -0
- package/treb-grid/src/types/set_range_options.ts +52 -0
- package/treb-grid/src/types/sheet.ts +3099 -0
- package/treb-grid/src/types/sheet_types.ts +95 -0
- package/treb-grid/src/types/tab_bar.ts +464 -0
- package/treb-grid/src/types/tile.ts +59 -0
- package/treb-grid/src/types/update_flags.ts +75 -0
- package/treb-grid/src/util/dom_utilities.ts +44 -0
- package/treb-grid/src/util/fontmetrics2.ts +179 -0
- package/treb-grid/src/util/ua.ts +104 -0
- package/treb-logo.svg +18 -0
- package/treb-parser/package.json +5 -0
- package/treb-parser/src/csv-parser.ts +122 -0
- package/treb-parser/src/index.ts +25 -0
- package/treb-parser/src/md-parser.ts +526 -0
- package/treb-parser/src/parser-types.ts +397 -0
- package/treb-parser/src/parser.test.ts +298 -0
- package/treb-parser/src/parser.ts +2673 -0
- package/treb-utils/package.json +5 -0
- package/treb-utils/src/dispatch.ts +57 -0
- package/treb-utils/src/event_source.ts +147 -0
- package/treb-utils/src/ievent_source.ts +33 -0
- package/treb-utils/src/index.ts +31 -0
- package/treb-utils/src/measurement.ts +174 -0
- package/treb-utils/src/resizable.ts +160 -0
- package/treb-utils/src/scale.ts +137 -0
- package/treb-utils/src/serialize_html.ts +124 -0
- package/treb-utils/src/template.ts +70 -0
- package/treb-utils/src/validate_uri.ts +61 -0
- package/tsconfig.json +10 -0
- package/tsproject.json +30 -0
- package/util/license-plugin-esbuild.js +86 -0
- package/util/list-css-vars.sh +46 -0
- package/README-esm.md +0 -37
- package/treb-bundle.css +0 -2
- package/treb-bundle.mjs +0 -15
|
@@ -0,0 +1,612 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* This file is part of TREB.
|
|
3
|
+
*
|
|
4
|
+
* TREB is free software: you can redistribute it and/or modify it under the
|
|
5
|
+
* terms of the GNU General Public License as published by the Free Software
|
|
6
|
+
* Foundation, either version 3 of the License, or (at your option) any
|
|
7
|
+
* later version.
|
|
8
|
+
*
|
|
9
|
+
* TREB is distributed in the hope that it will be useful, but WITHOUT ANY
|
|
10
|
+
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
|
11
|
+
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
|
12
|
+
* details.
|
|
13
|
+
*
|
|
14
|
+
* You should have received a copy of the GNU General Public License along
|
|
15
|
+
* with TREB. If not, see <https://www.gnu.org/licenses/>.
|
|
16
|
+
*
|
|
17
|
+
* Copyright 2022-2023 trebco, llc.
|
|
18
|
+
* info@treb.app
|
|
19
|
+
*
|
|
20
|
+
*/
|
|
21
|
+
|
|
22
|
+
// import { Parser } from 'treb-parser';
|
|
23
|
+
|
|
24
|
+
import type { Area, IArea } from './area';
|
|
25
|
+
import type { Style } from './style';
|
|
26
|
+
import type { TextPart } from './text_part';
|
|
27
|
+
import { ValueType, GetValueType, Complex } from './value-type';
|
|
28
|
+
import type { CellValue, UnionValue } from './union';
|
|
29
|
+
import type { PreparedText } from './render_text';
|
|
30
|
+
import type { Table } from './table';
|
|
31
|
+
|
|
32
|
+
export interface RenderFunctionOptions {
|
|
33
|
+
height: number;
|
|
34
|
+
width: number;
|
|
35
|
+
context: CanvasRenderingContext2D;
|
|
36
|
+
cell: Cell;
|
|
37
|
+
style: Style.Properties;
|
|
38
|
+
scale?: number;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
export interface RenderFunctionResult {
|
|
42
|
+
handled: boolean;
|
|
43
|
+
|
|
44
|
+
/** set true to add text metrics to cell rendering data */
|
|
45
|
+
// metrics?: boolean;
|
|
46
|
+
|
|
47
|
+
/** set to add "title" (tooltip) info */
|
|
48
|
+
// title?: string;
|
|
49
|
+
|
|
50
|
+
/** override text [FIXME: union type?] */
|
|
51
|
+
// override_text?: string;
|
|
52
|
+
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
export type RenderFunction = (options: RenderFunctionOptions) => RenderFunctionResult;
|
|
56
|
+
|
|
57
|
+
export interface ClickFunctionOptions {
|
|
58
|
+
cell: Cell;
|
|
59
|
+
x?: number;
|
|
60
|
+
y?: number;
|
|
61
|
+
width?: number;
|
|
62
|
+
height?: number;
|
|
63
|
+
scale?: number;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
// I believe this was intended for hyperlinks, but they don't work that
|
|
67
|
+
// way any more; going to remove, temp, but not sure if we actually need
|
|
68
|
+
// it (not used for checkbox)
|
|
69
|
+
|
|
70
|
+
/*
|
|
71
|
+
export interface ClickFunctionEvent {
|
|
72
|
+
type: string;
|
|
73
|
+
data?: any;
|
|
74
|
+
}
|
|
75
|
+
*/
|
|
76
|
+
|
|
77
|
+
export interface ClickFunctionResult {
|
|
78
|
+
|
|
79
|
+
/**
|
|
80
|
+
* change the cell value, to the value passed here
|
|
81
|
+
*
|
|
82
|
+
* NOTE: this must be in canonical form (english), not translated.
|
|
83
|
+
*/
|
|
84
|
+
value?: CellValue;
|
|
85
|
+
|
|
86
|
+
/**
|
|
87
|
+
* set to true to block normal click handling semantics
|
|
88
|
+
* (selecting the cell, generally)
|
|
89
|
+
*/
|
|
90
|
+
block_selection?: boolean;
|
|
91
|
+
|
|
92
|
+
/**
|
|
93
|
+
* return an event that will be broadcast to listeners using the standard
|
|
94
|
+
* event dispatch
|
|
95
|
+
*/
|
|
96
|
+
// event?: ClickFunctionEvent;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
export type ClickFunction = (options: ClickFunctionOptions) => ClickFunctionResult;
|
|
100
|
+
|
|
101
|
+
|
|
102
|
+
/**
|
|
103
|
+
* restructuring from the old system, which had lots of separate arrays for
|
|
104
|
+
* things. for the most part I think having a single array (or object) with
|
|
105
|
+
* objects will be more useful (if not necessarily more efficient). the
|
|
106
|
+
* standout case where this will be inefficient is in passing data to a
|
|
107
|
+
* calculation service, where style information is not useful.
|
|
108
|
+
*
|
|
109
|
+
* things that are in the cell class:
|
|
110
|
+
* - raw data (formula or value)
|
|
111
|
+
* - formatted representation
|
|
112
|
+
* - type (data type including formula or value, implicitly)
|
|
113
|
+
* - array pointer -- if this cell is part of an array, the array object
|
|
114
|
+
*
|
|
115
|
+
* things that are NOT in the cell class:
|
|
116
|
+
* - raw per-cell style information. this is in a separate array (object).
|
|
117
|
+
*/
|
|
118
|
+
|
|
119
|
+
/**
|
|
120
|
+
* validation TODO: date, number, boolean, &c
|
|
121
|
+
*/
|
|
122
|
+
export enum ValidationType {
|
|
123
|
+
List,
|
|
124
|
+
Date,
|
|
125
|
+
Range,
|
|
126
|
+
Number,
|
|
127
|
+
Boolean,
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
export interface DataValidationBase {
|
|
131
|
+
error?: boolean;
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
export interface DataValidationRange extends DataValidationBase {
|
|
135
|
+
type: ValidationType.Range;
|
|
136
|
+
area: IArea;
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
export interface DataValidationList extends DataValidationBase {
|
|
140
|
+
type: ValidationType.List;
|
|
141
|
+
list: CellValue[];
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
export interface DataValidationDate extends DataValidationBase {
|
|
145
|
+
type: ValidationType.Date;
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
export interface DataValidationNumber extends DataValidationBase {
|
|
149
|
+
type: ValidationType.Number;
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
export interface DataValidationBoolean extends DataValidationBase {
|
|
153
|
+
type: ValidationType.Boolean;
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
export type DataValidation
|
|
157
|
+
= DataValidationList
|
|
158
|
+
| DataValidationRange
|
|
159
|
+
| DataValidationNumber
|
|
160
|
+
| DataValidationDate
|
|
161
|
+
| DataValidationBoolean;
|
|
162
|
+
|
|
163
|
+
export class Cell {
|
|
164
|
+
|
|
165
|
+
// --- static methods -------------------------------------------------------
|
|
166
|
+
|
|
167
|
+
public static StringToColumn(s: string): number{
|
|
168
|
+
let index = 0;
|
|
169
|
+
s = s.toUpperCase();
|
|
170
|
+
for ( let i = 0; i < s.length; i++ ){
|
|
171
|
+
index *= 26;
|
|
172
|
+
index += (s.charCodeAt(i) - 64);
|
|
173
|
+
}
|
|
174
|
+
return index - 1;
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
/*
|
|
178
|
+
public static FormulaDependencies(formula: string): Area[] {
|
|
179
|
+
|
|
180
|
+
const dependencies = [];
|
|
181
|
+
|
|
182
|
+
if (!formula) return []; // also matches ""
|
|
183
|
+
if (formula.trim()[0] !== '=') return [];
|
|
184
|
+
|
|
185
|
+
const results = parser.Parse(formula);
|
|
186
|
+
|
|
187
|
+
for (const key of Object.keys(results.dependencies.addresses)){
|
|
188
|
+
const address = results.dependencies.addresses[key];
|
|
189
|
+
dependencies.push(new Area(address));
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
for (const key of Object.keys(results.dependencies.ranges)){
|
|
193
|
+
const range = results.dependencies.ranges[key];
|
|
194
|
+
dependencies.push(new Area(range.start, range.end, true));
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
// dedupe (...)
|
|
198
|
+
|
|
199
|
+
return dependencies;
|
|
200
|
+
|
|
201
|
+
}
|
|
202
|
+
*/
|
|
203
|
+
|
|
204
|
+
/*
|
|
205
|
+
public static GetValueType(value: unknown): ValueType {
|
|
206
|
+
|
|
207
|
+
switch (typeof value){
|
|
208
|
+
|
|
209
|
+
case 'undefined':
|
|
210
|
+
return ValueType.undefined;
|
|
211
|
+
|
|
212
|
+
case 'number':
|
|
213
|
+
return ValueType.number;
|
|
214
|
+
|
|
215
|
+
case 'boolean':
|
|
216
|
+
return ValueType.boolean;
|
|
217
|
+
|
|
218
|
+
case 'object':
|
|
219
|
+
if (value === null) {
|
|
220
|
+
return ValueType.undefined;
|
|
221
|
+
}
|
|
222
|
+
return ValueType.object;
|
|
223
|
+
|
|
224
|
+
case 'string':
|
|
225
|
+
if (value[0] === '=') {
|
|
226
|
+
return ValueType.formula;
|
|
227
|
+
}
|
|
228
|
+
return ValueType.string;
|
|
229
|
+
|
|
230
|
+
default: // function or symbol
|
|
231
|
+
return ValueType.error;
|
|
232
|
+
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
*/
|
|
236
|
+
|
|
237
|
+
// --- class fields ---------------------------------------------------------
|
|
238
|
+
|
|
239
|
+
// the basic value, which can be omitted (in the case of an array cell)
|
|
240
|
+
public value?: CellValue; // any;
|
|
241
|
+
|
|
242
|
+
// the value type, js intrinics plus a special type for formula
|
|
243
|
+
public type: ValueType = ValueType.undefined;
|
|
244
|
+
|
|
245
|
+
// the calculated value, returned from calculation service
|
|
246
|
+
public calculated?: CellValue; // |FunctionError; // any;
|
|
247
|
+
|
|
248
|
+
// the calculated type. we're separating calculation from rendering, since
|
|
249
|
+
// we may calculate values that we don't need to render.
|
|
250
|
+
public calculated_type?: ValueType;
|
|
251
|
+
|
|
252
|
+
// the value formatted as a string, for display. this is separate from the
|
|
253
|
+
// calculated value, because the renderer might still need to check the
|
|
254
|
+
// value in the case of negative color or value-based styling.
|
|
255
|
+
public formatted?: string | TextPart[];
|
|
256
|
+
|
|
257
|
+
/**
|
|
258
|
+
* rendered type may be different than value type: could be a function
|
|
259
|
+
* returns a number, or an error. rendering an empty value should result
|
|
260
|
+
* in a string, so you can test on this type -- it should never be 0
|
|
261
|
+
* (or undefined) if the cell has been rendered.
|
|
262
|
+
*
|
|
263
|
+
* NOTE: no one really uses this. it's only read in two places -- one in
|
|
264
|
+
* grid to check if it's a number and we want to format as % (which seems
|
|
265
|
+
* wrong anyway, because what if it's a function?) -- and in sheet, as a
|
|
266
|
+
* flag indicating we have already rendered it (it gets flushed on change).
|
|
267
|
+
*
|
|
268
|
+
* so we could maybe remove it or switch to a boolean or something... is
|
|
269
|
+
* boolean any smaller than number?
|
|
270
|
+
*/
|
|
271
|
+
public rendered_type?: ValueType;
|
|
272
|
+
|
|
273
|
+
// style is an index into the style dictionary, not the actual style
|
|
274
|
+
// data (FIXME: if style is an object, this would just be a pointer, so
|
|
275
|
+
// why not just use a reference?)
|
|
276
|
+
// style:number = 0;
|
|
277
|
+
public style?: Style.Properties;
|
|
278
|
+
|
|
279
|
+
/** if this cell is part of an array, pointer to the area. */
|
|
280
|
+
public area?: Area;
|
|
281
|
+
|
|
282
|
+
/**
|
|
283
|
+
* if this cell is merged, pointer to the area
|
|
284
|
+
*/
|
|
285
|
+
public merge_area?: Area;
|
|
286
|
+
|
|
287
|
+
/** this cell is part of a table */
|
|
288
|
+
public table?: Table;
|
|
289
|
+
|
|
290
|
+
/**
|
|
291
|
+
* opaque data for cell rendering, we can cache some data
|
|
292
|
+
* that's reused frequently (is that wasting space?)
|
|
293
|
+
*
|
|
294
|
+
* render data will be flushed any time there is any change to
|
|
295
|
+
* the cell data or style.
|
|
296
|
+
*
|
|
297
|
+
* UPDATE: renderer data is no longer flushed. we set a dirty flag.
|
|
298
|
+
*/
|
|
299
|
+
public renderer_data?: {
|
|
300
|
+
text_data?: PreparedText;
|
|
301
|
+
overflowed?: boolean;
|
|
302
|
+
width?: number;
|
|
303
|
+
height?: number;
|
|
304
|
+
};
|
|
305
|
+
|
|
306
|
+
/**
|
|
307
|
+
* step 1: invert flag (dirty -> clean)
|
|
308
|
+
*/
|
|
309
|
+
public render_clean: boolean[] = [];
|
|
310
|
+
|
|
311
|
+
public note?: string;
|
|
312
|
+
|
|
313
|
+
/**
|
|
314
|
+
* moving hyperlink in here, as a cell property. hyperlink will not be
|
|
315
|
+
* removed on value change, but will be removed on clear/delete.
|
|
316
|
+
*/
|
|
317
|
+
public hyperlink?: string;
|
|
318
|
+
|
|
319
|
+
/* flag indicates do not paint */
|
|
320
|
+
public editing?: boolean;
|
|
321
|
+
|
|
322
|
+
/**
|
|
323
|
+
* TODO: add a return value which affects control flow. default/falsy should
|
|
324
|
+
* behave as now, for backwards compatibility; but it should be possible to
|
|
325
|
+
* return a value that says "don't exit the standard rendering process"
|
|
326
|
+
*
|
|
327
|
+
* UPDATE: return value now means "I have handled this", so if you paint you
|
|
328
|
+
* should return true. that's a breaking change but we should get help from
|
|
329
|
+
* tooling.
|
|
330
|
+
*/
|
|
331
|
+
public render_function?: RenderFunction; // (options: RenderFunctionOptions) => RenderFunctionResult;
|
|
332
|
+
|
|
333
|
+
public click_function?: ClickFunction; // (options: ClickFunctionOptions) => ClickFunctionResult;
|
|
334
|
+
|
|
335
|
+
/**
|
|
336
|
+
* moving locked property to style. not because it's properly a style,
|
|
337
|
+
* or not properly a property of cell, but rather because that will allow
|
|
338
|
+
* us to cascade the property over areas.
|
|
339
|
+
*/
|
|
340
|
+
|
|
341
|
+
/** not editable */
|
|
342
|
+
// public locked?: boolean;
|
|
343
|
+
|
|
344
|
+
public validation?: DataValidation;
|
|
345
|
+
|
|
346
|
+
// --- class methods --------------------------------------------------------
|
|
347
|
+
|
|
348
|
+
constructor(value?: CellValue, value_type?: ValueType){
|
|
349
|
+
if (typeof value !== 'undefined') this.Set(value, value_type);
|
|
350
|
+
}
|
|
351
|
+
|
|
352
|
+
/** type guard */
|
|
353
|
+
public ValueIsNumber() : this is { value: number } {
|
|
354
|
+
return this.type === ValueType.number;
|
|
355
|
+
}
|
|
356
|
+
|
|
357
|
+
/** type guard */
|
|
358
|
+
public ValueIsFormula() : this is { value: string } {
|
|
359
|
+
return this.type === ValueType.formula;
|
|
360
|
+
}
|
|
361
|
+
|
|
362
|
+
/** type guard */
|
|
363
|
+
public ValueIsBoolean() : this is { value: boolean } {
|
|
364
|
+
return this.type === ValueType.boolean;
|
|
365
|
+
}
|
|
366
|
+
|
|
367
|
+
/** type guard */
|
|
368
|
+
public ValueIsComplex() : this is { value: Complex } {
|
|
369
|
+
return this.type === ValueType.complex;
|
|
370
|
+
}
|
|
371
|
+
|
|
372
|
+
///
|
|
373
|
+
|
|
374
|
+
/** flush style information and things that rely on it (formatted value) */
|
|
375
|
+
public FlushStyle(): void{
|
|
376
|
+
this.formatted = this.rendered_type = this.style = undefined;
|
|
377
|
+
this.render_clean = [];
|
|
378
|
+
}
|
|
379
|
+
|
|
380
|
+
/** flush array information */
|
|
381
|
+
public FlushArray(): void{
|
|
382
|
+
this.area = undefined;
|
|
383
|
+
}
|
|
384
|
+
|
|
385
|
+
/** flush cached data: formatted and calculated */
|
|
386
|
+
public FlushCache(): void{
|
|
387
|
+
this.calculated
|
|
388
|
+
= this.calculated_type
|
|
389
|
+
= this.formatted
|
|
390
|
+
= this.rendered_type
|
|
391
|
+
= this.render_function
|
|
392
|
+
= this.click_function
|
|
393
|
+
= undefined;
|
|
394
|
+
this.render_clean = [];
|
|
395
|
+
}
|
|
396
|
+
|
|
397
|
+
public Reset(): void{
|
|
398
|
+
this.type = ValueType.undefined;
|
|
399
|
+
this.value
|
|
400
|
+
= this.note
|
|
401
|
+
= this.hyperlink
|
|
402
|
+
= this.formatted
|
|
403
|
+
= this.rendered_type
|
|
404
|
+
= this.style
|
|
405
|
+
= this.calculated
|
|
406
|
+
= this.calculated_type
|
|
407
|
+
= this.area
|
|
408
|
+
= this.renderer_data // keep here?
|
|
409
|
+
= this.render_function
|
|
410
|
+
= this.click_function
|
|
411
|
+
= undefined;
|
|
412
|
+
this.render_clean = [];
|
|
413
|
+
}
|
|
414
|
+
|
|
415
|
+
public Set(value: CellValue, type = GetValueType(value)): void {
|
|
416
|
+
this.value = value;
|
|
417
|
+
this.type = type;
|
|
418
|
+
this.formatted =
|
|
419
|
+
this.rendered_type =
|
|
420
|
+
this.style =
|
|
421
|
+
this.calculated =
|
|
422
|
+
this.calculated_type =
|
|
423
|
+
this.render_function =
|
|
424
|
+
this.click_function =
|
|
425
|
+
this.area = undefined;
|
|
426
|
+
this.render_clean = [];
|
|
427
|
+
}
|
|
428
|
+
|
|
429
|
+
/**
|
|
430
|
+
* sets calculated value and flushes cached value
|
|
431
|
+
*/
|
|
432
|
+
public SetCalculatedValue(value: CellValue, type = GetValueType(value)): void {
|
|
433
|
+
|
|
434
|
+
// is it possible to explicitly set a calculated value of undefined?
|
|
435
|
+
// that should be different from clearing. if the calculated value is
|
|
436
|
+
// undefined, we want to set it to 0.
|
|
437
|
+
|
|
438
|
+
if (value === undefined) {
|
|
439
|
+
value = 0;
|
|
440
|
+
type = ValueType.number;
|
|
441
|
+
}
|
|
442
|
+
|
|
443
|
+
if (this.calculated === value) {
|
|
444
|
+
return;
|
|
445
|
+
}
|
|
446
|
+
|
|
447
|
+
this.calculated = value;
|
|
448
|
+
this.calculated_type = type;
|
|
449
|
+
this.formatted = this.rendered_type = undefined;
|
|
450
|
+
this.render_clean = [];
|
|
451
|
+
}
|
|
452
|
+
|
|
453
|
+
/* *
|
|
454
|
+
* composite method for setting value or error, based on value
|
|
455
|
+
* not used? (...)
|
|
456
|
+
* /
|
|
457
|
+
public SetCalculatedValueOrError(value: any, type?: ValueType): void {
|
|
458
|
+
|
|
459
|
+
console.info("SCVE", value, type);
|
|
460
|
+
|
|
461
|
+
if (typeof type === 'undefined') {
|
|
462
|
+
if (typeof value === 'object' && value.error) {
|
|
463
|
+
type = ValueType.error;
|
|
464
|
+
value = value.error;
|
|
465
|
+
}
|
|
466
|
+
else {
|
|
467
|
+
type = GetValueType(value);
|
|
468
|
+
}
|
|
469
|
+
}
|
|
470
|
+
if (this.calculated === value) return;
|
|
471
|
+
this.calculated = value;
|
|
472
|
+
this.calculated_type = type;
|
|
473
|
+
this.formatted = this.rendered_type = undefined;
|
|
474
|
+
this.render_clean = [];
|
|
475
|
+
}
|
|
476
|
+
*/
|
|
477
|
+
|
|
478
|
+
/**
|
|
479
|
+
* get value -- calculation result (not formatted) or literal. for
|
|
480
|
+
* literal strings, we strip leading apostrophes (these are used to
|
|
481
|
+
* prevent parsing of literal strings that look like other things).
|
|
482
|
+
*/
|
|
483
|
+
public GetValue(): CellValue {
|
|
484
|
+
if (this.calculated_type) return this.calculated;
|
|
485
|
+
// if (this.type === ValueType.string &&
|
|
486
|
+
// this.value && this.value[0] === '\'') return this.value.slice(1);
|
|
487
|
+
|
|
488
|
+
// we maintain a type, but typescript won't associate the two so
|
|
489
|
+
// this test needs to use the actual type
|
|
490
|
+
|
|
491
|
+
if (typeof this.value === 'string' && this.value[0] === '\'') { return this.value.slice(1); }
|
|
492
|
+
|
|
493
|
+
return this.value;
|
|
494
|
+
}
|
|
495
|
+
|
|
496
|
+
/* *
|
|
497
|
+
* new version of GetValue that preserves errors. for non-errors this
|
|
498
|
+
* behaves identically to the original GetValue. for errors, returns
|
|
499
|
+
* an error object {error: string};
|
|
500
|
+
* /
|
|
501
|
+
public GetValue2(): CellValue | {error: CellValue} {
|
|
502
|
+
if (this.calculated_type) {
|
|
503
|
+
return (this.calculated_type === ValueType.error) ?
|
|
504
|
+
{ error: this.calculated } : this.calculated;
|
|
505
|
+
}
|
|
506
|
+
// if (this.type === ValueType.string &&
|
|
507
|
+
// this.value && this.value[0] === '\'') return this.value.slice(1);
|
|
508
|
+
if (typeof this.value === 'string' && this.value[0] === '\'') { return this.value.slice(1); } // @see GetValue
|
|
509
|
+
|
|
510
|
+
return this.value;
|
|
511
|
+
}
|
|
512
|
+
*/
|
|
513
|
+
|
|
514
|
+
/* *
|
|
515
|
+
* we have an issue where a reference to an empty cell winds up returning
|
|
516
|
+
* a string, goes into a numerical calculation, and slows everything down.
|
|
517
|
+
*
|
|
518
|
+
* this is kind of a corner case. it's not that there's a reference to an
|
|
519
|
+
* empty cell -- that works OK. there's a reference to a cell, which is
|
|
520
|
+
* itself a reference to an empty cell. that's why it's a function, which
|
|
521
|
+
* is being returned as a string.
|
|
522
|
+
*
|
|
523
|
+
* in this case because it's the function value, I think returning 0 is ok.
|
|
524
|
+
* BUT, it still might make sense to return undefined.
|
|
525
|
+
* /
|
|
526
|
+
public GetValue3(): CellValue|{error: string} { // |FunctionError {
|
|
527
|
+
|
|
528
|
+
// so... what is this? shouldn't this be an object? (...)
|
|
529
|
+
|
|
530
|
+
if (this.calculated_type) {
|
|
531
|
+
return (this.calculated_type === ValueType.error) ?
|
|
532
|
+
{ error: this.calculated as string } : this.calculated;
|
|
533
|
+
}
|
|
534
|
+
|
|
535
|
+
if (this.type === ValueType.formula) {
|
|
536
|
+
// formula, but no calc type... undefined or zero? (...)
|
|
537
|
+
return 0; // undefined;
|
|
538
|
+
}
|
|
539
|
+
// if (this.type === ValueType.string &&
|
|
540
|
+
// this.value && this.value[0] === '\'') return this.value.slice(1);
|
|
541
|
+
if (typeof this.value === 'string' && this.value[0] === '\'') { return this.value.slice(1); } // @see GetValue
|
|
542
|
+
|
|
543
|
+
return this.value;
|
|
544
|
+
}
|
|
545
|
+
*/
|
|
546
|
+
|
|
547
|
+
/**
|
|
548
|
+
* this function follows the rule of GetValue3, which is: if the type
|
|
549
|
+
* is a function but there is no calculated value, then return 0.
|
|
550
|
+
*/
|
|
551
|
+
public GetValue4(): UnionValue {
|
|
552
|
+
|
|
553
|
+
if (this.calculated_type) {
|
|
554
|
+
return {
|
|
555
|
+
type: this.calculated_type,
|
|
556
|
+
value: this.calculated,
|
|
557
|
+
} as UnionValue;
|
|
558
|
+
}
|
|
559
|
+
|
|
560
|
+
if (this.type === ValueType.formula) {
|
|
561
|
+
return {
|
|
562
|
+
type: ValueType.number,
|
|
563
|
+
value: 0,
|
|
564
|
+
}
|
|
565
|
+
}
|
|
566
|
+
|
|
567
|
+
return {
|
|
568
|
+
type: this.type,
|
|
569
|
+
value: (typeof this.value === 'string' && this.value[0] === '\'') ? this.value.slice(1) : this.value, // @see GetValue
|
|
570
|
+
} as UnionValue;
|
|
571
|
+
|
|
572
|
+
}
|
|
573
|
+
|
|
574
|
+
/**
|
|
575
|
+
* set note. set undefined to clear.
|
|
576
|
+
*/
|
|
577
|
+
public SetNote(note?: string): void {
|
|
578
|
+
this.note = note;
|
|
579
|
+
this.render_clean = [];
|
|
580
|
+
}
|
|
581
|
+
|
|
582
|
+
/** sets error (FIXME: error type) */
|
|
583
|
+
public SetCalculationError(err = 'ERR'): void {
|
|
584
|
+
this.SetCalculatedValue(err, ValueType.error);
|
|
585
|
+
}
|
|
586
|
+
|
|
587
|
+
public SetArray(area: Area): void {
|
|
588
|
+
this.type = ValueType.undefined;
|
|
589
|
+
this.value =
|
|
590
|
+
this.formatted =
|
|
591
|
+
this.rendered_type =
|
|
592
|
+
this.style =
|
|
593
|
+
this.hyperlink = // note?
|
|
594
|
+
this.calculated =
|
|
595
|
+
this.calculated_type = undefined;
|
|
596
|
+
this.area = area;
|
|
597
|
+
this.render_clean = [];
|
|
598
|
+
}
|
|
599
|
+
|
|
600
|
+
public SetArrayHead(area: Area, value: CellValue): void {
|
|
601
|
+
this.type = GetValueType(value);
|
|
602
|
+
this.value = value;
|
|
603
|
+
this.formatted =
|
|
604
|
+
this.rendered_type =
|
|
605
|
+
this.style =
|
|
606
|
+
this.calculated =
|
|
607
|
+
this.calculated_type = undefined;
|
|
608
|
+
this.area = area;
|
|
609
|
+
this.render_clean = [];
|
|
610
|
+
}
|
|
611
|
+
|
|
612
|
+
}
|