@trebco/treb 23.6.2 → 25.0.0-rc1

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.
Files changed (217) hide show
  1. package/.eslintignore +8 -0
  2. package/.eslintrc.js +164 -0
  3. package/README-shadow-DOM.md +88 -0
  4. package/README.md +37 -130
  5. package/api-config.json +29 -0
  6. package/api-generator/api-generator-types.ts +82 -0
  7. package/api-generator/api-generator.ts +1172 -0
  8. package/api-generator/package.json +3 -0
  9. package/build/treb-spreadsheet.mjs +14 -0
  10. package/{treb.d.ts → build/treb.d.ts} +293 -299
  11. package/esbuild-custom-element.mjs +336 -0
  12. package/esbuild.js +305 -0
  13. package/package.json +43 -14
  14. package/treb-base-types/package.json +5 -0
  15. package/treb-base-types/src/api_types.ts +36 -0
  16. package/treb-base-types/src/area.ts +583 -0
  17. package/treb-base-types/src/basic_types.ts +45 -0
  18. package/treb-base-types/src/cell.ts +612 -0
  19. package/treb-base-types/src/cells.ts +1066 -0
  20. package/treb-base-types/src/color.ts +124 -0
  21. package/treb-base-types/src/import.ts +71 -0
  22. package/treb-base-types/src/index-standalone.ts +29 -0
  23. package/treb-base-types/src/index.ts +42 -0
  24. package/treb-base-types/src/layout.ts +47 -0
  25. package/treb-base-types/src/localization.ts +187 -0
  26. package/treb-base-types/src/rectangle.ts +145 -0
  27. package/treb-base-types/src/render_text.ts +72 -0
  28. package/treb-base-types/src/style.ts +545 -0
  29. package/treb-base-types/src/table.ts +109 -0
  30. package/treb-base-types/src/text_part.ts +54 -0
  31. package/treb-base-types/src/theme.ts +608 -0
  32. package/treb-base-types/src/union.ts +152 -0
  33. package/treb-base-types/src/value-type.ts +164 -0
  34. package/treb-base-types/style/resizable.css +59 -0
  35. package/treb-calculator/modern.tsconfig.json +11 -0
  36. package/treb-calculator/package.json +5 -0
  37. package/treb-calculator/src/calculator.ts +2546 -0
  38. package/treb-calculator/src/complex-math.ts +558 -0
  39. package/treb-calculator/src/dag/array-vertex.ts +198 -0
  40. package/treb-calculator/src/dag/graph.ts +951 -0
  41. package/treb-calculator/src/dag/leaf_vertex.ts +118 -0
  42. package/treb-calculator/src/dag/spreadsheet_vertex.ts +327 -0
  43. package/treb-calculator/src/dag/spreadsheet_vertex_base.ts +44 -0
  44. package/treb-calculator/src/dag/vertex.ts +352 -0
  45. package/treb-calculator/src/descriptors.ts +162 -0
  46. package/treb-calculator/src/expression-calculator.ts +1069 -0
  47. package/treb-calculator/src/function-error.ts +103 -0
  48. package/treb-calculator/src/function-library.ts +103 -0
  49. package/treb-calculator/src/functions/base-functions.ts +1214 -0
  50. package/treb-calculator/src/functions/checkbox.ts +164 -0
  51. package/treb-calculator/src/functions/complex-functions.ts +253 -0
  52. package/treb-calculator/src/functions/finance-functions.ts +399 -0
  53. package/treb-calculator/src/functions/information-functions.ts +102 -0
  54. package/treb-calculator/src/functions/matrix-functions.ts +182 -0
  55. package/treb-calculator/src/functions/sparkline.ts +335 -0
  56. package/treb-calculator/src/functions/statistics-functions.ts +350 -0
  57. package/treb-calculator/src/functions/text-functions.ts +298 -0
  58. package/treb-calculator/src/index.ts +27 -0
  59. package/treb-calculator/src/notifier-types.ts +59 -0
  60. package/treb-calculator/src/primitives.ts +428 -0
  61. package/treb-calculator/src/utilities.ts +305 -0
  62. package/treb-charts/package.json +5 -0
  63. package/treb-charts/src/chart-functions.ts +156 -0
  64. package/treb-charts/src/chart-types.ts +230 -0
  65. package/treb-charts/src/chart.ts +1288 -0
  66. package/treb-charts/src/index.ts +24 -0
  67. package/treb-charts/src/main.ts +37 -0
  68. package/treb-charts/src/rectangle.ts +52 -0
  69. package/treb-charts/src/renderer.ts +1841 -0
  70. package/treb-charts/src/util.ts +122 -0
  71. package/treb-charts/style/charts.scss +221 -0
  72. package/treb-charts/style/old-charts.scss +250 -0
  73. package/treb-embed/markup/layout.html +137 -0
  74. package/treb-embed/markup/toolbar.html +175 -0
  75. package/treb-embed/modern.tsconfig.json +25 -0
  76. package/treb-embed/src/custom-element/content-types.d.ts +18 -0
  77. package/treb-embed/src/custom-element/global.d.ts +11 -0
  78. package/treb-embed/src/custom-element/spreadsheet-constructor.ts +1227 -0
  79. package/treb-embed/src/custom-element/treb-global.ts +44 -0
  80. package/treb-embed/src/custom-element/treb-spreadsheet-element.ts +52 -0
  81. package/treb-embed/src/embedded-spreadsheet.ts +5362 -0
  82. package/treb-embed/src/index.ts +16 -0
  83. package/treb-embed/src/language-model.ts +41 -0
  84. package/treb-embed/src/options.ts +320 -0
  85. package/treb-embed/src/progress-dialog.ts +228 -0
  86. package/treb-embed/src/selection-state.ts +16 -0
  87. package/treb-embed/src/spinner.ts +42 -0
  88. package/treb-embed/src/toolbar-message.ts +96 -0
  89. package/treb-embed/src/types.ts +167 -0
  90. package/treb-embed/style/autocomplete.scss +103 -0
  91. package/treb-embed/style/dark-theme.scss +114 -0
  92. package/treb-embed/style/defaults.scss +36 -0
  93. package/treb-embed/style/dialog.scss +181 -0
  94. package/treb-embed/style/dropdown-select.scss +101 -0
  95. package/treb-embed/style/formula-bar.scss +193 -0
  96. package/treb-embed/style/grid.scss +374 -0
  97. package/treb-embed/style/layout.scss +424 -0
  98. package/treb-embed/style/mouse-mask.scss +67 -0
  99. package/treb-embed/style/note.scss +92 -0
  100. package/treb-embed/style/overlay-editor.scss +102 -0
  101. package/treb-embed/style/spinner.scss +92 -0
  102. package/treb-embed/style/tab-bar.scss +228 -0
  103. package/treb-embed/style/table.scss +80 -0
  104. package/treb-embed/style/theme-defaults.scss +444 -0
  105. package/treb-embed/style/toolbar.scss +416 -0
  106. package/treb-embed/style/tooltip.scss +68 -0
  107. package/treb-embed/style/treb-icons.scss +130 -0
  108. package/treb-embed/style/treb-spreadsheet-element.scss +20 -0
  109. package/treb-embed/style/z-index.scss +43 -0
  110. package/treb-export/docs/charts.md +68 -0
  111. package/treb-export/modern.tsconfig.json +19 -0
  112. package/treb-export/package.json +4 -0
  113. package/treb-export/src/address-type.ts +77 -0
  114. package/treb-export/src/base-template.ts +22 -0
  115. package/treb-export/src/column-width.ts +85 -0
  116. package/treb-export/src/drawing2/chart-template-components2.ts +389 -0
  117. package/treb-export/src/drawing2/chart2.ts +282 -0
  118. package/treb-export/src/drawing2/column-chart-template2.ts +521 -0
  119. package/treb-export/src/drawing2/donut-chart-template2.ts +296 -0
  120. package/treb-export/src/drawing2/drawing2.ts +355 -0
  121. package/treb-export/src/drawing2/embedded-image.ts +71 -0
  122. package/treb-export/src/drawing2/scatter-chart-template2.ts +555 -0
  123. package/treb-export/src/export-worker/export-worker.ts +99 -0
  124. package/treb-export/src/export-worker/index-modern.ts +22 -0
  125. package/treb-export/src/export2.ts +2204 -0
  126. package/treb-export/src/import2.ts +882 -0
  127. package/treb-export/src/relationship.ts +36 -0
  128. package/treb-export/src/shared-strings2.ts +128 -0
  129. package/treb-export/src/template-2.ts +22 -0
  130. package/treb-export/src/unescape_xml.ts +47 -0
  131. package/treb-export/src/workbook-sheet2.ts +182 -0
  132. package/treb-export/src/workbook-style2.ts +1285 -0
  133. package/treb-export/src/workbook-theme2.ts +88 -0
  134. package/treb-export/src/workbook2.ts +491 -0
  135. package/treb-export/src/xml-utils.ts +201 -0
  136. package/treb-export/template/base/[Content_Types].xml +2 -0
  137. package/treb-export/template/base/_rels/.rels +2 -0
  138. package/treb-export/template/base/docProps/app.xml +2 -0
  139. package/treb-export/template/base/docProps/core.xml +12 -0
  140. package/treb-export/template/base/xl/_rels/workbook.xml.rels +2 -0
  141. package/treb-export/template/base/xl/sharedStrings.xml +2 -0
  142. package/treb-export/template/base/xl/styles.xml +2 -0
  143. package/treb-export/template/base/xl/theme/theme1.xml +2 -0
  144. package/treb-export/template/base/xl/workbook.xml +2 -0
  145. package/treb-export/template/base/xl/worksheets/sheet1.xml +2 -0
  146. package/treb-export/template/base.xlsx +0 -0
  147. package/treb-format/package.json +8 -0
  148. package/treb-format/src/format.test.ts +213 -0
  149. package/treb-format/src/format.ts +942 -0
  150. package/treb-format/src/format_cache.ts +199 -0
  151. package/treb-format/src/format_parser.ts +723 -0
  152. package/treb-format/src/index.ts +25 -0
  153. package/treb-format/src/number_format_section.ts +100 -0
  154. package/treb-format/src/value_parser.ts +337 -0
  155. package/treb-grid/package.json +5 -0
  156. package/treb-grid/src/editors/autocomplete.ts +394 -0
  157. package/treb-grid/src/editors/autocomplete_matcher.ts +260 -0
  158. package/treb-grid/src/editors/formula_bar.ts +473 -0
  159. package/treb-grid/src/editors/formula_editor_base.ts +910 -0
  160. package/treb-grid/src/editors/overlay_editor.ts +511 -0
  161. package/treb-grid/src/index.ts +37 -0
  162. package/treb-grid/src/layout/base_layout.ts +2618 -0
  163. package/treb-grid/src/layout/grid_layout.ts +299 -0
  164. package/treb-grid/src/layout/rectangle_cache.ts +86 -0
  165. package/treb-grid/src/render/selection-renderer.ts +414 -0
  166. package/treb-grid/src/render/svg_header_overlay.ts +93 -0
  167. package/treb-grid/src/render/svg_selection_block.ts +187 -0
  168. package/treb-grid/src/render/tile_renderer.ts +2122 -0
  169. package/treb-grid/src/types/annotation.ts +216 -0
  170. package/treb-grid/src/types/border_constants.ts +34 -0
  171. package/treb-grid/src/types/clipboard_data.ts +31 -0
  172. package/treb-grid/src/types/data_model.ts +334 -0
  173. package/treb-grid/src/types/drag_mask.ts +81 -0
  174. package/treb-grid/src/types/grid.ts +7743 -0
  175. package/treb-grid/src/types/grid_base.ts +3644 -0
  176. package/treb-grid/src/types/grid_command.ts +470 -0
  177. package/treb-grid/src/types/grid_events.ts +124 -0
  178. package/treb-grid/src/types/grid_options.ts +97 -0
  179. package/treb-grid/src/types/grid_selection.ts +60 -0
  180. package/treb-grid/src/types/named_range.ts +369 -0
  181. package/treb-grid/src/types/scale-control.ts +202 -0
  182. package/treb-grid/src/types/serialize_options.ts +72 -0
  183. package/treb-grid/src/types/set_range_options.ts +52 -0
  184. package/treb-grid/src/types/sheet.ts +3099 -0
  185. package/treb-grid/src/types/sheet_types.ts +95 -0
  186. package/treb-grid/src/types/tab_bar.ts +464 -0
  187. package/treb-grid/src/types/tile.ts +59 -0
  188. package/treb-grid/src/types/update_flags.ts +75 -0
  189. package/treb-grid/src/util/dom_utilities.ts +44 -0
  190. package/treb-grid/src/util/fontmetrics2.ts +179 -0
  191. package/treb-grid/src/util/ua.ts +104 -0
  192. package/treb-logo.svg +18 -0
  193. package/treb-parser/package.json +5 -0
  194. package/treb-parser/src/csv-parser.ts +122 -0
  195. package/treb-parser/src/index.ts +25 -0
  196. package/treb-parser/src/md-parser.ts +526 -0
  197. package/treb-parser/src/parser-types.ts +397 -0
  198. package/treb-parser/src/parser.test.ts +298 -0
  199. package/treb-parser/src/parser.ts +2673 -0
  200. package/treb-utils/package.json +5 -0
  201. package/treb-utils/src/dispatch.ts +57 -0
  202. package/treb-utils/src/event_source.ts +147 -0
  203. package/treb-utils/src/ievent_source.ts +33 -0
  204. package/treb-utils/src/index.ts +31 -0
  205. package/treb-utils/src/measurement.ts +174 -0
  206. package/treb-utils/src/resizable.ts +160 -0
  207. package/treb-utils/src/scale.ts +137 -0
  208. package/treb-utils/src/serialize_html.ts +124 -0
  209. package/treb-utils/src/template.ts +70 -0
  210. package/treb-utils/src/validate_uri.ts +61 -0
  211. package/tsconfig.json +10 -0
  212. package/tsproject.json +30 -0
  213. package/util/license-plugin-esbuild.js +86 -0
  214. package/util/list-css-vars.sh +46 -0
  215. package/README-esm.md +0 -37
  216. package/treb-bundle.css +0 -2
  217. 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
+ }