@trebco/treb 28.17.4 → 29.1.2

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 (87) hide show
  1. package/dist/treb-spreadsheet-light.mjs +12 -12
  2. package/dist/treb-spreadsheet.mjs +12 -12
  3. package/dist/treb.d.ts +121 -82
  4. package/eslint.config.js +21 -0
  5. package/package.json +6 -6
  6. package/treb-base-types/src/area.ts +4 -2
  7. package/treb-base-types/src/cell.ts +1 -1
  8. package/treb-base-types/src/cells.ts +16 -7
  9. package/treb-base-types/src/dom-utilities.ts +4 -2
  10. package/treb-base-types/src/import.ts +2 -2
  11. package/treb-base-types/src/rectangle.ts +5 -5
  12. package/treb-base-types/src/union.ts +6 -1
  13. package/treb-base-types/src/value-type.ts +1 -1
  14. package/treb-calculator/src/calculator.ts +114 -165
  15. package/treb-calculator/src/dag/calculation_leaf_vertex.ts +1 -2
  16. package/treb-calculator/src/dag/graph.ts +3 -3
  17. package/treb-calculator/src/dag/spreadsheet_vertex.ts +2 -2
  18. package/treb-calculator/src/dag/state_leaf_vertex.ts +2 -4
  19. package/treb-calculator/src/descriptors.ts +28 -2
  20. package/treb-calculator/src/expression-calculator.ts +25 -34
  21. package/treb-calculator/src/function-error.ts +2 -2
  22. package/treb-calculator/src/function-library.ts +16 -0
  23. package/treb-calculator/src/functions/base-functions.ts +185 -211
  24. package/treb-calculator/src/functions/checkbox.ts +0 -1
  25. package/treb-calculator/src/functions/complex-functions.ts +49 -47
  26. package/treb-calculator/src/functions/finance-functions.ts +10 -10
  27. package/treb-calculator/src/functions/function-utilities.ts +26 -0
  28. package/treb-calculator/src/functions/information-functions.ts +21 -41
  29. package/treb-calculator/src/functions/matrix-functions.ts +8 -1
  30. package/treb-calculator/src/functions/sparkline.ts +6 -4
  31. package/treb-calculator/src/functions/statistics-functions.ts +21 -17
  32. package/treb-calculator/src/functions/text-functions.ts +14 -13
  33. package/treb-calculator/src/primitives.ts +48 -37
  34. package/treb-calculator/src/utilities.ts +117 -134
  35. package/treb-charts/src/chart-functions.ts +3 -3
  36. package/treb-charts/src/chart-types.ts +42 -1
  37. package/treb-charts/src/chart-utils.ts +155 -113
  38. package/treb-charts/src/chart.ts +6 -5
  39. package/treb-charts/src/default-chart-renderer.ts +6 -5
  40. package/treb-charts/src/renderer.ts +12 -11
  41. package/treb-charts/src/util.ts +25 -36
  42. package/treb-data-model/package.json +5 -0
  43. package/{treb-grid/src/types → treb-data-model/src}/annotation.ts +2 -2
  44. package/{treb-grid/src/types → treb-data-model/src}/conditional_format.ts +20 -0
  45. package/{treb-grid/src/types → treb-data-model/src}/data_model.ts +231 -133
  46. package/treb-data-model/src/index.ts +45 -0
  47. package/{treb-grid/src/types/named_range.ts → treb-data-model/src/named.ts} +459 -376
  48. package/{treb-grid/src/types → treb-data-model/src}/sheet.ts +13 -5
  49. package/treb-data-model/src/sheet_collection.ts +114 -0
  50. package/{treb-grid/src/types → treb-data-model/src}/sheet_types.ts +6 -3
  51. package/treb-embed/modern.tsconfig.json +1 -0
  52. package/treb-embed/src/custom-element/spreadsheet-constructor.ts +2 -3
  53. package/treb-embed/src/embedded-spreadsheet.ts +125 -270
  54. package/treb-embed/src/selection-state.ts +1 -1
  55. package/treb-embed/src/toolbar-message.ts +1 -1
  56. package/treb-embed/src/types.ts +13 -5
  57. package/treb-export/src/export-worker/export-worker.ts +22 -7
  58. package/treb-export/src/export2.ts +110 -41
  59. package/treb-export/src/import2.ts +6 -5
  60. package/treb-export/src/workbook2.ts +31 -13
  61. package/treb-export/src/xml-utils.ts +5 -1
  62. package/treb-format/src/format.ts +8 -6
  63. package/treb-grid/src/editors/autocomplete.ts +2 -2
  64. package/treb-grid/src/editors/autocomplete_matcher.ts +57 -19
  65. package/treb-grid/src/editors/editor.ts +27 -25
  66. package/treb-grid/src/editors/formula_bar.ts +5 -5
  67. package/treb-grid/src/editors/overlay_editor.ts +1 -2
  68. package/treb-grid/src/index.ts +0 -11
  69. package/treb-grid/src/layout/base_layout.ts +20 -8
  70. package/treb-grid/src/layout/grid_layout.ts +2 -2
  71. package/treb-grid/src/layout/mock-layout.ts +5 -6
  72. package/treb-grid/src/render/selection-renderer.ts +2 -3
  73. package/treb-grid/src/render/tile_renderer.ts +1 -1
  74. package/treb-grid/src/types/grid.ts +95 -66
  75. package/treb-grid/src/types/grid_base.ts +76 -60
  76. package/treb-grid/src/types/grid_command.ts +3 -2
  77. package/treb-grid/src/types/grid_events.ts +12 -6
  78. package/treb-grid/src/types/tab_bar.ts +1 -2
  79. package/treb-parser/src/parser-types.ts +2 -1
  80. package/treb-parser/src/parser.ts +7 -5
  81. package/treb-utils/src/event_source.ts +1 -1
  82. package/treb-utils/src/serialize_html.ts +31 -6
  83. package/.eslintignore +0 -8
  84. package/.eslintrc.cjs +0 -168
  85. package/treb-grid/src/layout/rectangle_cache.ts +0 -86
  86. /package/{treb-grid/src/types → treb-data-model/src}/serialize_options.ts +0 -0
  87. /package/{treb-grid/src/types/grid_selection.ts → treb-data-model/src/sheet_selection.ts} +0 -0
@@ -25,49 +25,58 @@
25
25
  /// <reference path="./content-types.d.ts" />
26
26
 
27
27
  import type {
28
- GridEvent, SerializeOptions, Annotation,
29
- SerializedModel, FreezePane, SerializedSheet,
28
+ GridEvent,
30
29
  SheetChangeEvent, GridOptions,
31
- GridSelection, CellEvent, FunctionDescriptor,
32
- AnnotationViewData,
33
- AnnotationType,
30
+ CellEvent, FunctionDescriptor,
34
31
  ExternalEditorConfig,
35
- ConditionalFormatDuplicateValuesOptions,
36
- ConditionalFormatDuplicateValues,
37
- ConditionalFormatGradientOptions,
38
- ConditionalFormat,
39
- ConditionalFormatGradient,
40
- ConditionalFormatExpression,
41
- StandardGradient,
42
- CondifionalFormatExpressionOptions,
43
- ConditionalFormatCellMatchOptions,
44
- ConditionalFormatCellMatch,
45
- MacroFunction,
46
- SerializedNamedExpression,
47
32
  } from 'treb-grid';
48
33
 
34
+ import { DataModel, Sheet, StandardGradientsList } from 'treb-data-model';
35
+ import type {
36
+ SerializeOptions,
37
+ Annotation,
38
+ AnnotationViewData,
39
+ AnnotationType,
40
+ MacroFunction,
41
+ GridSelection,
42
+ ConnectedElementType,
43
+ SerializedModel,
44
+ SerializedSheet,
45
+ FreezePane,
46
+ ConditionalFormatDuplicateValuesOptions,
47
+ ConditionalFormatGradientOptions,
48
+ ConditionalFormat,
49
+ ConditionalFormatGradient,
50
+ ConditionalFormatExpression,
51
+ StandardGradient,
52
+ CondifionalFormatExpressionOptions,
53
+ ConditionalFormatCellMatchOptions,
54
+ ConditionalFormatCellMatch,
55
+
56
+ } from 'treb-data-model';
57
+
58
+
49
59
  import {
50
- DataModel, Grid, BorderConstants, Sheet, ErrorCode, UA,
51
- StandardGradientsList,
60
+ Grid, BorderConstants, ErrorCode, UA,
52
61
  } from 'treb-grid';
53
62
 
54
63
  import {
55
64
  Parser, DecimalMarkType,
56
65
  ArgumentSeparatorType, QuotedSheetNameRegex } from 'treb-parser';
57
66
 
58
- import { Calculator, type LeafVertex } from 'treb-calculator';
67
+ import { Calculator } from 'treb-calculator';
59
68
 
60
69
  import type {
61
70
  ICellAddress,
62
71
  EvaluateOptions,
63
72
  IArea, CellValue, Point,
64
73
  Complex, ExtendedUnion, IRectangle,
65
- AddressReference, RangeReference, TableSortOptions, Table, TableTheme, GradientStop,
74
+ AddressReference, RangeReference, TableSortOptions, Table, TableTheme,
66
75
  } from 'treb-base-types';
67
76
 
68
77
  import {
69
78
  IsArea, ThemeColorTable, ComplexToString, Rectangle, IsComplex, type CellStyle,
70
- Localization, Style, type Color, ThemeColor2, IsCellAddress, Area, IsFlatData, IsFlatDataArray, Gradient, ValueType, DOMContext,
79
+ Localization, Style, type Color, ThemeColor2, IsCellAddress, Area, IsFlatData, IsFlatDataArray, Gradient, DOMContext,
71
80
  } from 'treb-base-types';
72
81
 
73
82
  import { EventSource, ValidateURI } from 'treb-utils';
@@ -90,7 +99,6 @@ import { Chart, ChartFunctions } from 'treb-charts';
90
99
  import type { SetRangeOptions } from 'treb-grid';
91
100
 
92
101
  import type { StateLeafVertex } from 'treb-calculator';
93
- import type { ConnectedElementType } from 'treb-grid';
94
102
 
95
103
 
96
104
  // --- worker ------------------------------------------------------------------
@@ -496,7 +504,7 @@ export class EmbeddedSpreadsheet<USER_DATA_TYPE = unknown> {
496
504
  * parameter you can set when creating the spreadsheet.
497
505
  */
498
506
  public get user_data(): USER_DATA_TYPE|undefined {
499
- return this.grid.model.user_data;
507
+ return this.grid.model.user_data as USER_DATA_TYPE;
500
508
  }
501
509
 
502
510
  /**
@@ -693,7 +701,7 @@ export class EmbeddedSpreadsheet<USER_DATA_TYPE = unknown> {
693
701
 
694
702
  if (this.options.local_storage && !options.model ) {
695
703
 
696
- window.addEventListener('visibilitychange', event => {
704
+ window.addEventListener('visibilitychange', () => {
697
705
  if (document.visibilityState === 'hidden') {
698
706
  if (this.options.local_storage && this.dirty) {
699
707
  this.SaveLocalStorage(this.options.local_storage);
@@ -784,7 +792,7 @@ export class EmbeddedSpreadsheet<USER_DATA_TYPE = unknown> {
784
792
  }
785
793
 
786
794
  if (options.model) {
787
- this.model = options.model.model;
795
+ this.model = options.model.model as DataModel;
788
796
  this.calculator = options.model.calculator; // as CalcType;
789
797
  this.DOM = options.model.DOM;
790
798
  }
@@ -946,7 +954,7 @@ export class EmbeddedSpreadsheet<USER_DATA_TYPE = unknown> {
946
954
 
947
955
  case 'style':
948
956
  this.DocumentChange();
949
- this.UpdateDocumentStyles(false);
957
+ this.UpdateDocumentStyles();
950
958
  this.UpdateSelectionStyle();
951
959
  break;
952
960
 
@@ -1297,7 +1305,8 @@ export class EmbeddedSpreadsheet<USER_DATA_TYPE = unknown> {
1297
1305
  if (event.type === 'structure') {
1298
1306
  this.grid.EnsureActiveSheet();
1299
1307
  this.grid.UpdateLayout();
1300
- (this.grid as any).tab_bar?.Update();
1308
+ // (this.grid as any).tab_bar?.Update();
1309
+ this.grid.UpdateTabBar();
1301
1310
  }
1302
1311
  });
1303
1312
 
@@ -1315,7 +1324,8 @@ export class EmbeddedSpreadsheet<USER_DATA_TYPE = unknown> {
1315
1324
  if (event.type === 'structure') {
1316
1325
  view.grid.EnsureActiveSheet();
1317
1326
  view.grid.UpdateLayout();
1318
- (view.grid as any).tab_bar?.Update();
1327
+ // (view.grid as any).tab_bar?.Update();
1328
+ view.grid.UpdateTabBar();
1319
1329
  }
1320
1330
  });
1321
1331
 
@@ -2235,7 +2245,8 @@ export class EmbeddedSpreadsheet<USER_DATA_TYPE = unknown> {
2235
2245
  const element = this.model.connected_elements.get(id);
2236
2246
  if (element) {
2237
2247
  element.formula = formula;
2238
- const internal = (element.internal) as { vertex: StateLeafVertex, state: any };
2248
+
2249
+ const internal = (element.internal) as { vertex: StateLeafVertex, state: unknown };
2239
2250
 
2240
2251
  if (internal?.state) {
2241
2252
  internal.state = undefined;
@@ -2262,8 +2273,8 @@ export class EmbeddedSpreadsheet<USER_DATA_TYPE = unknown> {
2262
2273
 
2263
2274
  // FIXME: merge w/ insert annotation?
2264
2275
 
2265
- let r1c1 = options?.r1c1 || false;
2266
- let argument_separator = options?.argument_separator || this.parser.argument_separator; // default to current
2276
+ const r1c1 = options?.r1c1 || false;
2277
+ const argument_separator = options?.argument_separator || this.parser.argument_separator; // default to current
2267
2278
 
2268
2279
  this.parser.Save();
2269
2280
  this.parser.flags.r1c1 = r1c1;
@@ -2776,7 +2787,7 @@ export class EmbeddedSpreadsheet<USER_DATA_TYPE = unknown> {
2776
2787
  }
2777
2788
 
2778
2789
  if (!this.export_worker) {
2779
- this.export_worker = await this.LoadWorker('export');
2790
+ this.export_worker = await this.LoadWorker();
2780
2791
  }
2781
2792
 
2782
2793
  return new Promise<Blob>((resolve, reject) => {
@@ -3295,7 +3306,7 @@ export class EmbeddedSpreadsheet<USER_DATA_TYPE = unknown> {
3295
3306
  }
3296
3307
 
3297
3308
  if (text && filename) {
3298
- const blob = new Blob([text as any], { type: 'text/plain;charset=utf-8' });
3309
+ const blob = new Blob([text], { type: 'text/plain;charset=utf-8' });
3299
3310
  this.SaveAs(blob, filename);
3300
3311
  }
3301
3312
 
@@ -3927,37 +3938,6 @@ export class EmbeddedSpreadsheet<USER_DATA_TYPE = unknown> {
3927
3938
 
3928
3939
  return this.calculator.Unresolve(ref, this.grid.active_sheet, qualified, named);
3929
3940
 
3930
- /*
3931
- let range = '';
3932
- const area = IsCellAddress(ref) ? new Area(ref) : new Area(ref.start, ref.end);
3933
-
3934
- if (named) {
3935
- const named_range = this.model.named_ranges.MatchSelection(area);
3936
- if (named_range) {
3937
- return named_range;
3938
- }
3939
- }
3940
-
3941
- if (area.count > 1) {
3942
- range = Area.CellAddressToLabel(area.start) + ':' + Area.CellAddressToLabel(area.end);
3943
- }
3944
- else {
3945
- range = Area.CellAddressToLabel(area.start);
3946
- }
3947
-
3948
- if (!qualified) {
3949
- return range;
3950
- }
3951
-
3952
- // is there a function to resolve sheet? actually, don't we know that
3953
- // the active selection must be on the active sheet? (...)
3954
-
3955
- const sheet_id = area.start.sheet_id || this.grid.active_sheet.id;
3956
- const sheet_name = this.calculator.ResolveSheetName(sheet_id, true);
3957
-
3958
- return sheet_name ? sheet_name + '!' + range : range;
3959
- */
3960
-
3961
3941
  }
3962
3942
 
3963
3943
  /**
@@ -4162,8 +4142,9 @@ export class EmbeddedSpreadsheet<USER_DATA_TYPE = unknown> {
4162
4142
 
4163
4143
  /**
4164
4144
  * Create a named range or named expression. A named range refers to an
4165
- * address or range. A named expression can be a value or formula, basically
4166
- * anything you would type into a cell.
4145
+ * address or range. A named expression can be any value or formula. To set
4146
+ * the value as a literal string, enclose the string in double-quotes (as
4147
+ * you would when using a string as a function argument).
4167
4148
  *
4168
4149
  * @param value range, value or expression
4169
4150
  *
@@ -4176,7 +4157,7 @@ export class EmbeddedSpreadsheet<USER_DATA_TYPE = unknown> {
4176
4157
  *
4177
4158
  * @public
4178
4159
  */
4179
- public DefineName(name: string, value: RangeReference|CellValue): void {
4160
+ public DefineName(name: string, value: RangeReference|CellValue, scope?: string|number, overwrite = false): void {
4180
4161
 
4181
4162
  // how can we unify named ranges and named expressions?
4182
4163
  //
@@ -4199,9 +4180,19 @@ export class EmbeddedSpreadsheet<USER_DATA_TYPE = unknown> {
4199
4180
  throw new Error('invalid value (null or undefined)');
4200
4181
  }
4201
4182
 
4183
+ if (typeof scope === 'string') {
4184
+ const id = this.model.sheets.ID(scope);
4185
+ if (typeof id === 'number') {
4186
+ scope = id;
4187
+ }
4188
+ else {
4189
+ throw new Error('invalid scope; use a sheet name or sheet id');
4190
+ }
4191
+ }
4192
+
4202
4193
  if (typeof value === 'object') {
4203
4194
  if (IsCellAddress(value) || IsArea(value)) {
4204
- this.grid.SetName(name, this.model.ResolveArea(value, this.grid.active_sheet));
4195
+ this.grid.SetName(name, this.model.ResolveArea(value, this.grid.active_sheet), undefined, scope, overwrite);
4205
4196
  return;
4206
4197
  }
4207
4198
  }
@@ -4218,45 +4209,17 @@ export class EmbeddedSpreadsheet<USER_DATA_TYPE = unknown> {
4218
4209
  switch (parse_result.expression.type) {
4219
4210
  case 'address':
4220
4211
  case 'range':
4221
- this.grid.SetName(name, this.model.ResolveArea(parse_result.expression, this.grid.active_sheet));
4212
+ this.grid.SetName(name, this.model.ResolveArea(parse_result.expression, this.grid.active_sheet), undefined, scope, overwrite);
4222
4213
  return;
4223
4214
  }
4224
- this.grid.SetName(name, undefined, value);
4215
+ this.grid.SetName(name, undefined, value, scope, overwrite);
4225
4216
 
4226
4217
  }
4227
4218
  else {
4228
- this.grid.SetName(name, undefined, value.toString());
4219
+ this.grid.SetName(name, undefined, value.toString(), scope, overwrite);
4229
4220
  }
4230
4221
 
4231
-
4232
- /*
4233
- // API v1 OK
4234
-
4235
- if (!range) {
4236
- const selection = this.GetSelectionReference();
4237
- if (!selection.empty) {
4238
- range = selection.area;
4239
- }
4240
- else {
4241
- throw new Error('invalid reference');
4242
- }
4243
- }
4244
-
4245
- // NOTE: AC is handled internally
4246
-
4247
- this.grid.SetName(name, this.model.ResolveArea(range, this.grid.active_sheet));
4248
- */
4249
- }
4250
-
4251
- /* *
4252
- * define a named expression
4253
- *
4254
- * @internal
4255
- * /
4256
- public DefineNamedExpression(name: string, expression: string): void {
4257
- this.grid.SetName(name, undefined, expression);
4258
4222
  }
4259
- */
4260
4223
 
4261
4224
  /**
4262
4225
  * Set or remove a link in a cell.
@@ -4297,7 +4260,7 @@ export class EmbeddedSpreadsheet<USER_DATA_TYPE = unknown> {
4297
4260
 
4298
4261
  let resolved: Area|undefined = undefined;
4299
4262
 
4300
- if (!!range) {
4263
+ if (range) {
4301
4264
  resolved = this.model.ResolveArea(range, this.grid.active_sheet);
4302
4265
  if (resolved.start.sheet_id) {
4303
4266
  if (resolved.start.sheet_id !== this.grid.active_sheet.id) {
@@ -4511,58 +4474,14 @@ export class EmbeddedSpreadsheet<USER_DATA_TYPE = unknown> {
4511
4474
  }
4512
4475
  }
4513
4476
 
4514
- // when serializing named expressions, we have to make sure
4515
- // that there's a sheet name in any address/range.
4516
-
4517
- const named_expressions: SerializedNamedExpression[] = [];
4518
- if (this.model.named_expressions) {
4519
-
4520
- for (const [name, expr] of this.model.named_expressions) {
4521
- this.parser.Walk(expr, unit => {
4522
- if (unit.type === 'address' || unit.type === 'range') {
4523
- const test = unit.type === 'range' ? unit.start : unit;
4524
-
4525
- test.absolute_column = test.absolute_row = true;
4526
-
4527
- if (!test.sheet) {
4528
- if (test.sheet_id) {
4529
- const sheet = this.model.sheets.Find(test.sheet_id);
4530
- if (sheet) {
4531
- test.sheet = sheet.name;
4532
- }
4533
- }
4534
- if (!test.sheet) {
4535
- test.sheet = active_sheet.name;
4536
- }
4537
- }
4538
-
4539
- if (unit.type === 'range') {
4540
- unit.end.absolute_column = unit.end.absolute_row = true;
4541
- }
4542
-
4543
- return false;
4544
- }
4545
- else if (unit.type === 'call' && options.export_functions) {
4546
- // ...
4547
- }
4548
- return true;
4549
- });
4550
- const rendered = this.parser.Render(expr, { missing: '' });
4551
- named_expressions.push({
4552
- name, expression: rendered
4553
- });
4554
- }
4555
- }
4477
+ const named = this.model.SerializeNames(active_sheet);
4556
4478
 
4557
4479
  return {
4558
4480
  sheet_data,
4559
4481
  active_sheet: active_sheet.id,
4560
- named_ranges: this.model.named_ranges.Count() ?
4561
- this.model.named_ranges.Serialize() :
4562
- undefined,
4482
+ named: named.length ? named : undefined,
4563
4483
  macro_functions,
4564
4484
  tables,
4565
- named_expressions: named_expressions.length ? named_expressions : undefined,
4566
4485
  };
4567
4486
 
4568
4487
  }
@@ -4677,7 +4596,7 @@ export class EmbeddedSpreadsheet<USER_DATA_TYPE = unknown> {
4677
4596
  }
4678
4597
 
4679
4598
  if (!this.export_worker) {
4680
- this.export_worker = await this.LoadWorker('export');
4599
+ this.export_worker = await this.LoadWorker();
4681
4600
  }
4682
4601
 
4683
4602
  // this originally returned a Promise<Blob> but the actual
@@ -4760,11 +4679,11 @@ export class EmbeddedSpreadsheet<USER_DATA_TYPE = unknown> {
4760
4679
 
4761
4680
  protected HandleCellEvent(event: CellEvent): void {
4762
4681
 
4763
- const type = event.data?.type;
4764
- if (type === 'hyperlink') {
4682
+ // const type = event.data?.type;
4683
+ if (event.data?.type === 'hyperlink') {
4765
4684
 
4766
4685
  const hyperlink_error = 'hyperlink invalid target';
4767
- const data = event.data.data || '';
4686
+ const data = event.data.reference || '';
4768
4687
 
4769
4688
  if (typeof data === 'string') {
4770
4689
 
@@ -4884,24 +4803,6 @@ export class EmbeddedSpreadsheet<USER_DATA_TYPE = unknown> {
4884
4803
  }
4885
4804
  }
4886
4805
 
4887
- /* *
4888
- * replacement for fetch
4889
- * FIXME: move to utils or other lib
4890
- * FIXME: we don't need to do this for ES6, presumably...
4891
- * can this move into the legacy/modern code? or is there a polyfill? (...)
4892
- * /
4893
- protected async Fetch(uri: string): Promise<string> {
4894
- return new Promise<string>((resolve, reject) => {
4895
- const xhr = new XMLHttpRequest();
4896
- xhr.onload = () => resolve(xhr.response);
4897
- xhr.onerror = () => reject('load error');
4898
- xhr.ontimeout = () => reject('timeout');
4899
- xhr.open('GET', uri);
4900
- xhr.send();
4901
- });
4902
- }
4903
- */
4904
-
4905
4806
  /**
4906
4807
  * I'm restructuring the select file routine to simplify, in service
4907
4808
  * of figuring out what's going wrong in OSX/Chrome. the current routine
@@ -5013,7 +4914,8 @@ export class EmbeddedSpreadsheet<USER_DATA_TYPE = unknown> {
5013
4914
  // probably because there are some async calls; hence the
5014
4915
  // src attribute is set before it's inflated.
5015
4916
 
5016
- const annotation = this.grid.CreateAnnotation({
4917
+ // const annotation =
4918
+ this.grid.CreateAnnotation({
5017
4919
  type: 'image',
5018
4920
  formula: '',
5019
4921
  data: {
@@ -5147,10 +5049,12 @@ export class EmbeddedSpreadsheet<USER_DATA_TYPE = unknown> {
5147
5049
  protected UpdateAnnotations(): void {
5148
5050
 
5149
5051
  for (const annotation of this.grid.active_sheet.annotations) {
5150
- if (annotation.temp.vertex) {
5151
- const vertex = annotation.temp.vertex as StateLeafVertex;
5152
- if (vertex.state_id !== annotation.temp.state) {
5153
- annotation.temp.state = vertex.state_id;
5052
+
5053
+ const vertex_data = annotation.temp as { vertex?: StateLeafVertex, state?: number };
5054
+
5055
+ if (vertex_data.vertex) {
5056
+ if (vertex_data.vertex.state_id !== vertex_data.state) {
5057
+ vertex_data.state = vertex_data.vertex.state_id;
5154
5058
 
5155
5059
  // set all views dirty in this case
5156
5060
  for (const view of annotation.view) {
@@ -5190,7 +5094,7 @@ export class EmbeddedSpreadsheet<USER_DATA_TYPE = unknown> {
5190
5094
 
5191
5095
  protected UpdateConnectedElements() {
5192
5096
  for (const element of this.model.connected_elements.values()) {
5193
- const internal = (element.internal) as { vertex: StateLeafVertex, state: any };
5097
+ const internal = (element.internal) as { vertex: StateLeafVertex, state: unknown };
5194
5098
  if (internal?.vertex && internal.vertex.state_id !== internal.state ) {
5195
5099
  internal.state = internal.vertex.state_id;
5196
5100
  const fn = element.update;
@@ -5666,7 +5570,7 @@ export class EmbeddedSpreadsheet<USER_DATA_TYPE = unknown> {
5666
5570
 
5667
5571
  }
5668
5572
 
5669
- protected UpdateDocumentStyles(update = true): void {
5573
+ protected UpdateDocumentStyles(): void {
5670
5574
 
5671
5575
  const number_format_map: Record<string, number> = {};
5672
5576
  const color_map: Record<string, number> = {};
@@ -5941,6 +5845,7 @@ export class EmbeddedSpreadsheet<USER_DATA_TYPE = unknown> {
5941
5845
 
5942
5846
  this.grid.UpdateSheets(sheets, undefined, override_sheet || data.active_sheet);
5943
5847
 
5848
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
5944
5849
  for (const [name, table] of this.model.tables.entries()) {
5945
5850
  if (table.area.start.sheet_id) {
5946
5851
  const sheet = model.sheets.Find(table.area.start.sheet_id);
@@ -5957,52 +5862,56 @@ export class EmbeddedSpreadsheet<USER_DATA_TYPE = unknown> {
5957
5862
 
5958
5863
  model.document_name = data.name;
5959
5864
  model.user_data = data.user_data;
5960
- model.named_ranges.Reset();
5961
5865
 
5962
- // old models have it in sheet, new models have at top level -- we can
5963
- // support old models, but write in the new syntax
5866
+ // resets for both named ranges and named expressions, until we consolidate
5867
+ model.named.Reset();
5964
5868
 
5965
- let named_range_data = data.named_ranges;
5966
- if (!named_range_data && sheets[0] && sheets[0].named_ranges) {
5967
- named_range_data = sheets[0].named_ranges;
5869
+ if (data.named) {
5870
+ this.model.UnserializeNames(data.named, this.grid.active_sheet);
5968
5871
  }
5872
+ else {
5969
5873
 
5970
- if (named_range_data) {
5971
- model.named_ranges.Deserialize(named_range_data);
5972
- }
5874
+ // console.info("using old-style name import")
5973
5875
 
5974
- // when importing named expressions, we have to make sure there's a
5975
- // sheet ID attached to each range/address. hopefully we have serialized
5976
- // it with a sheet name so we can look up.
5876
+ //------------------------------------------------------------------------
5877
+ //
5878
+ // old style handling of named ranges and expressions. we'll leave
5879
+ // this here for the time being. [update: rewriting slightly to share
5880
+ // some code]
5881
+ //
5882
+ //------------------------------------------------------------------------
5883
+
5884
+ // old models have it in sheet, new models have at top level -- we can
5885
+ // support old models, but write in the new syntax
5886
+
5887
+ let named_range_data = data.named_ranges;
5888
+ if (!named_range_data && sheets[0] && sheets[0].named_ranges) {
5889
+ named_range_data = sheets[0].named_ranges;
5890
+ }
5891
+
5892
+ if (named_range_data) {
5893
+ for (const [name, value] of Object.entries(named_range_data)) {
5894
+ model.named.SetNamedRange(name, new Area(value.start, value.end));
5895
+ }
5896
+ }
5897
+
5898
+ // when importing named expressions, we have to make sure there's a
5899
+ // sheet ID attached to each range/address. hopefully we have serialized
5900
+ // it with a sheet name so we can look up.
5901
+
5902
+ // model.named_expressions.clear(); // already reset (composite w/ named ranges)
5903
+
5904
+ if (data.named_expressions) {
5905
+ for (const pair of data.named_expressions) {
5906
+
5907
+ this.model.UnserializeNames([{
5908
+ name: pair.name,
5909
+ expression: pair.expression,
5910
+ }], this.grid.active_sheet);
5977
5911
 
5978
- model.named_expressions.clear(); // = {};
5979
- if (data.named_expressions) {
5980
- for (const pair of data.named_expressions) {
5981
- const parse_result = this.parser.Parse('' || pair.expression);
5982
- if (parse_result.valid && parse_result.expression) {
5983
- this.parser.Walk(parse_result.expression, unit => {
5984
- if (unit.type === 'address' || unit.type === 'range') {
5985
- if (unit.type === 'range') {
5986
- unit = unit.start;
5987
- }
5988
- if (!unit.sheet_id) {
5989
- if (unit.sheet) {
5990
- const sheet = this.model.sheets.Find(unit.sheet);
5991
- if (sheet) {
5992
- unit.sheet_id = sheet.id;
5993
- }
5994
- }
5995
- }
5996
- if (!unit.sheet_id) {
5997
- unit.sheet_id = this.grid.active_sheet.id;
5998
- }
5999
- return false; // don't continue in ranges
6000
- }
6001
- return true;
6002
- });
6003
- model.named_expressions.set(pair.name.toUpperCase(), parse_result.expression);
6004
5912
  }
6005
5913
  }
5914
+
6006
5915
  }
6007
5916
 
6008
5917
  model.macro_functions.clear();
@@ -6028,7 +5937,7 @@ export class EmbeddedSpreadsheet<USER_DATA_TYPE = unknown> {
6028
5937
  * load worker. optionally uses an ambient path as prefix; intended for
6029
5938
  * loading in different directories (or different hosts?)
6030
5939
  */
6031
- protected async LoadWorker(name: string): Promise<Worker> {
5940
+ protected async LoadWorker(): Promise<Worker> {
6032
5941
 
6033
5942
  // this is inlined to ensure the code will be tree-shaken properly
6034
5943
  // (we're trying to force it to remove the imported worker script)
@@ -6042,7 +5951,7 @@ export class EmbeddedSpreadsheet<USER_DATA_TYPE = unknown> {
6042
5951
  if (export_worker_script) {
6043
5952
  try {
6044
5953
  const worker = new Worker(
6045
- URL.createObjectURL(new Blob([(export_worker_script as any).default], { type: 'application/javascript' })));
5954
+ URL.createObjectURL(new Blob([(export_worker_script as {default: string}).default], { type: 'application/javascript' })));
6046
5955
  return worker;
6047
5956
  }
6048
5957
  catch (err) {
@@ -6058,60 +5967,6 @@ export class EmbeddedSpreadsheet<USER_DATA_TYPE = unknown> {
6058
5967
 
6059
5968
  throw new Error('creating worker failed');
6060
5969
 
6061
- /*
6062
-
6063
- if (!EmbeddedSpreadsheet.treb_base_path) {
6064
- console.warn('worker path is not set. it you are loading TREB in an ESM module, please either '
6065
- + 'include the script in a document <script/> tag, or call the method TREB.SetScriptPath() to '
6066
- + 'set the load path for workers (this should be the path to TREB script files).');
6067
- throw new Error('worker path not set');
6068
- }
6069
-
6070
- if (!/\.js$/.test(name)) name += ('-' + process.env.BUILD_VERSION + '.js');
6071
-
6072
- let worker: Worker;
6073
- let treb_path = EmbeddedSpreadsheet.treb_base_path;
6074
-
6075
- if (treb_path) {
6076
- if (!/\/$/.test(treb_path)) treb_path += '/';
6077
- name = treb_path + name;
6078
- }
6079
-
6080
- // for remote workers, fetch and construct as blob. for local
6081
- // workers we can just create.
6082
-
6083
- // actually we're now getting a fully-qualified URL, so it will
6084
- // always have a network prefix (or a file prefix)
6085
-
6086
- // FIXME: testing... in particular URL.createObjectURL and new Blob
6087
-
6088
- if (/^(http:|https:|\/\/)/.test(name)) {
6089
- const response = await fetch(name);
6090
-
6091
- if (!response.ok) {
6092
- throw new Error('Error loading worker script');
6093
- }
6094
-
6095
- const script = await response.text();
6096
-
6097
- // const script = await this.Fetch(name);
6098
- worker = new Worker(URL.createObjectURL(new Blob([script], { type: 'application/javascript' })));
6099
- }
6100
- else if (/^file:/.test(name)) {
6101
- throw new Error('invalid URI');
6102
- }
6103
- else {
6104
-
6105
- // this was intended for relative URIs but now it is applied
6106
- // to file:// URIs, which won't work anyway (in chrome, at least)
6107
-
6108
- worker = new Worker(name);
6109
-
6110
- }
6111
-
6112
- return worker;
6113
- */
6114
-
6115
5970
  }
6116
5971
 
6117
5972
  /**
@@ -1,5 +1,5 @@
1
1
 
2
- import type { GridSelection } from 'treb-grid';
2
+ import type { GridSelection } from 'treb-data-model';
3
3
  import type { CellStyle } from 'treb-base-types';
4
4
 
5
5
  /**
@@ -1,5 +1,5 @@
1
1
 
2
- import type { Style, Color } from 'treb-base-types';
2
+ import type { Color } from 'treb-base-types';
3
3
 
4
4
  /*
5
5
  * this is an attempt to lock down toolbar commands, and better