@trebco/treb 31.8.2 → 32.1.1

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 (43) hide show
  1. package/dist/treb-spreadsheet.mjs +8 -8
  2. package/i18n/languages/treb-i18n-da.mjs +1 -0
  3. package/i18n/languages/treb-i18n-de.mjs +1 -0
  4. package/i18n/languages/treb-i18n-es.mjs +1 -0
  5. package/i18n/languages/treb-i18n-fr.mjs +1 -0
  6. package/i18n/languages/treb-i18n-it.mjs +1 -0
  7. package/i18n/languages/treb-i18n-nl.mjs +1 -0
  8. package/i18n/languages/treb-i18n-no.mjs +1 -0
  9. package/i18n/languages/treb-i18n-pl.mjs +1 -0
  10. package/i18n/languages/treb-i18n-pt.mjs +1 -0
  11. package/i18n/languages/treb-i18n-sv.mjs +1 -0
  12. package/package.json +2 -2
  13. package/treb-base-types/src/union.ts +6 -0
  14. package/treb-base-types/src/value-type.ts +13 -0
  15. package/treb-calculator/src/calculator.ts +18 -1
  16. package/treb-calculator/src/descriptors.ts +42 -3
  17. package/treb-calculator/src/expression-calculator.ts +182 -6
  18. package/treb-calculator/src/functions/base-functions.ts +48 -0
  19. package/treb-calculator/src/functions/lambda-functions.ts +96 -0
  20. package/treb-data-model/src/data_model.ts +28 -13
  21. package/treb-data-model/src/named.ts +7 -0
  22. package/treb-data-model/src/sheet.ts +17 -0
  23. package/treb-embed/src/embedded-spreadsheet.ts +12 -3
  24. package/treb-embed/style/autocomplete.scss +4 -0
  25. package/treb-embed/style/dropdown-select.scss +3 -0
  26. package/treb-embed/style/font-stacks.scss +2 -0
  27. package/treb-embed/style/grid.scss +11 -11
  28. package/treb-embed/style/layout.scss +12 -9
  29. package/treb-embed/style/mouse-mask.scss +3 -0
  30. package/treb-embed/style/note.scss +4 -0
  31. package/treb-embed/style/overlay-editor.scss +3 -0
  32. package/treb-embed/style/tab-bar.scss +4 -0
  33. package/treb-embed/style/table.scss +3 -0
  34. package/treb-embed/style/theme-defaults.scss +2 -22
  35. package/treb-embed/style/tooltip.scss +4 -0
  36. package/treb-embed/style/treb-spreadsheet-element.scss +1 -1
  37. package/treb-export/src/workbook-style2.ts +0 -39
  38. package/treb-grid/src/render/svg_selection_block.ts +1 -37
  39. package/treb-grid/src/types/grid.ts +4 -3
  40. package/treb-parser/src/parser-types.ts +21 -0
  41. package/treb-parser/src/parser.ts +126 -218
  42. package/dist/treb-export-worker.mjs +0 -2
  43. package/dist/treb.d.ts +0 -2235
@@ -351,6 +351,54 @@ export const BaseFunctionLibrary: FunctionMap = {
351
351
  fn: () => { return { type: ValueType.number, value: Math.random() }},
352
352
  },
353
353
 
354
+ RandArray: {
355
+ volatile: true,
356
+ arguments: [
357
+ {name: 'rows'},
358
+ {name: 'columns'},
359
+ {name: 'min'},
360
+ {name: 'max'},
361
+ {name: 'integer'},
362
+ ],
363
+ description: 'Returns an array of uniformly-distributed random numbers',
364
+ fn: (rows = 1, columns = 1, min = 0, max = 1, integer = false) => {
365
+ const value: UnionValue[][] = [];
366
+
367
+ if (integer) {
368
+ const range = max - min + 1;
369
+ for (let i = 0; i < rows; i++) {
370
+ const row: UnionValue[] = [];
371
+ for (let j = 0; j < columns; j++) {
372
+ row.push({
373
+ type: ValueType.number,
374
+ value: Math.floor(Math.random() * range + min),
375
+ });
376
+ }
377
+ value.push(row);
378
+ }
379
+ }
380
+ else {
381
+ const range = max - min;
382
+
383
+ for (let i = 0; i < rows; i++) {
384
+ const row: UnionValue[] = [];
385
+ for (let j = 0; j < columns; j++) {
386
+ row.push({
387
+ type: ValueType.number,
388
+ value: Math.random() * range + min,
389
+ });
390
+ }
391
+ value.push(row);
392
+ }
393
+ }
394
+
395
+ return {
396
+ type: ValueType.array,
397
+ value,
398
+ }
399
+ },
400
+ },
401
+
354
402
  RandBetween: {
355
403
  arguments: [{name: 'min'}, {name: 'max'}],
356
404
  volatile: true,
@@ -0,0 +1,96 @@
1
+
2
+ import type { FunctionMap } from '../descriptors';
3
+ import type { UnionValue} from 'treb-base-types';
4
+ import { ValueType } from 'treb-base-types';
5
+ import type { ExpressionUnit } from 'treb-parser';
6
+
7
+ export const LambdaFunctionLibrary: FunctionMap = {
8
+
9
+ Lambda: {
10
+
11
+ // FIXME: we could use the create_binding_context callback
12
+ // here to validate the original parameters, might be useful
13
+
14
+ description: 'Creates a function',
15
+ arguments: [
16
+ { name: 'Argument', repeat: true, boxed: true, passthrough: true },
17
+ { name: 'Function', boxed: true, passthrough: true },
18
+ ],
19
+
20
+ fn: (...args: ExpressionUnit[]) => {
21
+ return {
22
+ type: ValueType.function,
23
+
24
+ // FIXME: lock down this type
25
+
26
+ value: {
27
+
28
+ // we should probably clone these
29
+
30
+ bindings: args.slice(0, args.length - 1),
31
+ func: args[args.length - 1],
32
+
33
+ alt: 'LAMBDA', // metadata
34
+ type: 'function', // metadata
35
+ },
36
+ };
37
+
38
+ }
39
+
40
+ },
41
+
42
+ Let: {
43
+
44
+ // this function has weird semantics we don't normally see --
45
+ // the first two arguments repeat, and the last one is constant.
46
+ // our tooltips aren't prepared for this.
47
+
48
+ // also it creates temporary names, we'll need to create some sort
49
+ // of temporary binding context. complicated!
50
+
51
+ description: 'Binds values to names for a calculation',
52
+ arguments: [
53
+ { name: 'Name', repeat: true },
54
+ { name: 'Value', repeat: true },
55
+ { name: 'Calculation', boxed: true },
56
+ ],
57
+
58
+ create_binding_context: ({args, descriptors}) => {
59
+
60
+ if (args.length % 2 !== 1) {
61
+ return undefined; // error
62
+ }
63
+
64
+ const context: Record<string, ExpressionUnit> = {};
65
+
66
+ for (let i = 0; i < args.length - 1; i += 2) {
67
+ const name = args[i];
68
+ const value = args[i+1];
69
+
70
+ if (name.type === 'identifier') {
71
+ context[name.name] = value;
72
+ }
73
+ else {
74
+ return undefined; // error
75
+ }
76
+
77
+ }
78
+
79
+ return {
80
+ context,
81
+ args: args.slice(-1),
82
+ argument_descriptors: descriptors.slice(-1),
83
+ }
84
+ },
85
+
86
+ fn: (arg?: UnionValue) => {
87
+ return arg ? arg : { type: ValueType.undefined };
88
+ },
89
+
90
+ },
91
+
92
+ };
93
+
94
+
95
+
96
+
@@ -111,13 +111,17 @@ export class DataModel {
111
111
  }
112
112
 
113
113
  /**
114
- *
114
+ * @param force_locale - always parse assuming a locale like en-us (comma
115
+ * argument separators). the current thinking is that this is required for
116
+ * XLSX import, although that might be incorrect.
115
117
  */
116
- public UnserializeNames(names: SerializedNamed[], active_sheet?: Sheet) {
118
+ public UnserializeNames(names: SerializedNamed[], active_sheet?: Sheet, force_locale = false) {
117
119
 
118
120
  this.parser.Save();
119
- this.parser.SetLocaleSettings(DecimalMarkType.Period, ArgumentSeparatorType.Comma);
120
-
121
+ if (force_locale) {
122
+ this.parser.SetLocaleSettings(DecimalMarkType.Period, ArgumentSeparatorType.Comma);
123
+ }
124
+
121
125
  //const sorted = names.map(named => {
122
126
  for (const named of names) {
123
127
 
@@ -197,6 +201,7 @@ export class DataModel {
197
201
  const named: SerializedNamed = {
198
202
  name: entry.name,
199
203
  expression: '',
204
+ type: entry.type,
200
205
  };
201
206
 
202
207
  if (entry.scope) {
@@ -239,6 +244,11 @@ export class DataModel {
239
244
  return true;
240
245
  });
241
246
 
247
+ // this is using the current locale settings, but unserialize
248
+ // assumes we are unserializing in US-style locale. I think we
249
+ // do that because excel always uses that? not sure, but we need
250
+ // to be consistent.
251
+
242
252
  named.expression = this.parser.Render(entry.expression, { missing: '' });
243
253
 
244
254
  }
@@ -601,9 +611,9 @@ export class DataModel {
601
611
  * be inlined (assuming it's only called in one place), but we are breaking
602
612
  * it out so we can develop/test/manage it.
603
613
  */
604
- public TranslateFunction(value: string): string {
614
+ public TranslateFunction(value: string, options?: { r1c1?: boolean }): string {
605
615
  if (this.language_map) {
606
- return this.TranslateInternal(value, this.language_map, this.language_model?.boolean_true, this.language_model?.boolean_false);
616
+ return this.TranslateInternal(value, this.language_map, this.language_model?.boolean_true, this.language_model?.boolean_false, options);
607
617
  }
608
618
  return value;
609
619
  }
@@ -612,14 +622,14 @@ export class DataModel {
612
622
  * translate from local language -> common (english).
613
623
  * @see TranslateFunction
614
624
  */
615
- public UntranslateFunction(value: string): string {
625
+ public UntranslateFunction(value: string, options?: { r1c1?: boolean }): string {
616
626
  if (this.reverse_language_map) {
617
- return this.TranslateInternal(value, this.reverse_language_map, 'TRUE', 'FALSE');
627
+ return this.TranslateInternal(value, this.reverse_language_map, 'TRUE', 'FALSE', options);
618
628
  }
619
629
  return value;
620
630
  }
621
631
 
622
- public UntranslateData(value: CellValue|CellValue[]|CellValue[][]): CellValue|CellValue[]|CellValue[][] {
632
+ public UntranslateData(value: CellValue|CellValue[]|CellValue[][], options?: { r1c1?: boolean }): CellValue|CellValue[]|CellValue[][] {
623
633
 
624
634
  if (Array.isArray(value)) {
625
635
 
@@ -628,7 +638,7 @@ export class DataModel {
628
638
  if (Is2DArray(value)) {
629
639
  return value.map(row => row.map(entry => {
630
640
  if (entry && typeof entry === 'string' && entry[0] === '=') {
631
- return this.UntranslateFunction(entry);
641
+ return this.UntranslateFunction(entry, options);
632
642
  }
633
643
  return entry;
634
644
  }));
@@ -636,7 +646,7 @@ export class DataModel {
636
646
  else {
637
647
  return value.map(entry => {
638
648
  if (entry && typeof entry === 'string' && entry[0] === '=') {
639
- return this.UntranslateFunction(entry);
649
+ return this.UntranslateFunction(entry, options);
640
650
  }
641
651
  return entry;
642
652
  });
@@ -646,7 +656,7 @@ export class DataModel {
646
656
  else if (value && typeof value === 'string' && value[0] === '=') {
647
657
 
648
658
  // single value
649
- value = this.UntranslateFunction(value);
659
+ value = this.UntranslateFunction(value, options);
650
660
 
651
661
  }
652
662
 
@@ -663,7 +673,10 @@ export class DataModel {
663
673
  * FIXME: it's about time we started using proper maps, we dropped
664
674
  * support for IE11 some time ago.
665
675
  */
666
- private TranslateInternal(value: string, map: Record<string, string>, boolean_true?: string, boolean_false?: string): string {
676
+ private TranslateInternal(value: string, map: Record<string, string>, boolean_true?: string, boolean_false?: string, options?: { r1c1?: boolean }): string {
677
+
678
+ this.parser.Save();
679
+ this.parser.flags.r1c1 = options?.r1c1;
667
680
 
668
681
  const parse_result = this.parser.Parse(value);
669
682
 
@@ -694,10 +707,12 @@ export class DataModel {
694
707
  if (modified) {
695
708
  return '=' + this.parser.Render(parse_result.expression, {
696
709
  missing: '', boolean_true, boolean_false,
710
+ r1c1: options?.r1c1,
697
711
  });
698
712
  }
699
713
  }
700
714
 
715
+ this.parser.Restore();
701
716
  return value;
702
717
 
703
718
  }
@@ -33,6 +33,7 @@ interface NamedRange {
33
33
  area: Area;
34
34
  }
35
35
 
36
+ /** @internal */
36
37
  export type Named = (NamedExpression | NamedRange) & {
37
38
  name: string; // canonical name
38
39
  scope?: number; // scope to sheet by ID
@@ -57,6 +58,12 @@ export interface SerializedNamed {
57
58
  /** scope is a sheet name (not ID) */
58
59
  scope?: string;
59
60
 
61
+ /**
62
+ * adding type. this is optional, it's not used by tooling. it's
63
+ * just for informational purpopses for clients.
64
+ */
65
+ type?: 'range'|'expression';
66
+
60
67
  }
61
68
 
62
69
  /**
@@ -1631,6 +1631,23 @@ export class Sheet {
1631
1631
  cell.rendered_type = ValueType.dimensioned_quantity; // who cares about rendered_type? (...)
1632
1632
 
1633
1633
  }
1634
+ else if (type === ValueType.function) {
1635
+
1636
+ /*
1637
+ // FIXME: lock down this type (function)
1638
+
1639
+ if ((cell.calculated as any)?.alt) {
1640
+ cell.formatted = (cell.calculated as any).alt.toString();
1641
+ cell.rendered_type = ValueType.string;
1642
+ }
1643
+ else
1644
+ */
1645
+
1646
+ {
1647
+ cell.formatted = '𝑓()'; // FIXME
1648
+ cell.rendered_type = ValueType.string;
1649
+ }
1650
+ }
1634
1651
  else {
1635
1652
 
1636
1653
  // why is this being treated as a number? (...)
@@ -49,9 +49,9 @@ import type {
49
49
  CondifionalFormatExpressionOptions,
50
50
  ConditionalFormatCellMatchOptions,
51
51
  ConditionalFormatCellMatch,
52
-
53
52
  LanguageModel,
54
53
  TranslatedFunctionDescriptor,
54
+ SerializedNamed,
55
55
 
56
56
  } from 'treb-data-model';
57
57
 
@@ -4172,7 +4172,7 @@ export class EmbeddedSpreadsheet<USER_DATA_TYPE = unknown> {
4172
4172
  *
4173
4173
  * @public
4174
4174
  */
4175
- public Resolve(reference: string): ICellAddress | IArea | undefined {
4175
+ public Resolve(reference: string, options?: { r1c1?: boolean }): ICellAddress | IArea | undefined {
4176
4176
 
4177
4177
  // API v1 OK
4178
4178
 
@@ -4183,7 +4183,7 @@ export class EmbeddedSpreadsheet<USER_DATA_TYPE = unknown> {
4183
4183
  // FIXME: we're using the sheet EnsureAddress method, but that should
4184
4184
  // move either in here or into some sort of helper class
4185
4185
 
4186
- const result = this.model.ResolveAddress(reference, this.grid.active_sheet);
4186
+ const result = this.model.ResolveAddress(reference, this.grid.active_sheet, options);
4187
4187
 
4188
4188
  if (IsCellAddress(result)) {
4189
4189
  return result.sheet_id ? result : undefined;
@@ -4418,6 +4418,10 @@ export class EmbeddedSpreadsheet<USER_DATA_TYPE = unknown> {
4418
4418
 
4419
4419
  }
4420
4420
 
4421
+ public ListNames(): SerializedNamed[] {
4422
+ return this.model.SerializeNames();
4423
+ }
4424
+
4421
4425
  /**
4422
4426
  * Create a named range or named expression. A named range refers to an
4423
4427
  * address or range. A named expression can be any value or formula. To set
@@ -6445,7 +6449,10 @@ export class EmbeddedSpreadsheet<USER_DATA_TYPE = unknown> {
6445
6449
  model.named.Reset();
6446
6450
 
6447
6451
  if (data.named) {
6452
+
6453
+ // use locale setting for parsing
6448
6454
  this.model.UnserializeNames(data.named, this.grid.active_sheet);
6455
+
6449
6456
  }
6450
6457
  else {
6451
6458
 
@@ -6482,6 +6489,8 @@ export class EmbeddedSpreadsheet<USER_DATA_TYPE = unknown> {
6482
6489
  if (data.named_expressions) {
6483
6490
  for (const pair of data.named_expressions) {
6484
6491
 
6492
+ // use locale setting for parsing
6493
+
6485
6494
  this.model.UnserializeNames([{
6486
6495
  name: pair.name,
6487
6496
  expression: pair.expression,
@@ -19,6 +19,10 @@
19
19
  *
20
20
  */
21
21
 
22
+ @use 'z-index.scss' as *;
23
+ @use 'defaults.scss' as *;
24
+
25
+
22
26
  /**
23
27
  * this is getting attached to the document (why? b/c fixed pos?)
24
28
  * so it inherits a lot. that's not good.
@@ -19,6 +19,9 @@
19
19
  *
20
20
  */
21
21
 
22
+ @use 'z-index.scss' as *;
23
+ @use 'defaults.scss' as *;
24
+
22
25
  .treb-main.treb-main {
23
26
 
24
27
  .treb-dropdown-caret {
@@ -19,6 +19,8 @@
19
19
  *
20
20
  */
21
21
 
22
+ @use './defaults.scss' as *;
23
+
22
24
  //
23
25
  // thanks to
24
26
  // https://modernfontstacks.com/
@@ -21,20 +21,20 @@
21
21
 
22
22
  // sass vars only
23
23
 
24
- @import 'z-index.scss';
25
- @import 'defaults.scss';
24
+ @use 'z-index.scss' as *;
25
+ @use 'defaults.scss' as *;
26
26
 
27
27
  // clean, no imports (but use sass vars)
28
28
 
29
- @import 'mouse-mask.scss';
30
- @import 'note.scss';
31
- @import 'table.scss';
32
- @import 'tooltip.scss';
33
- @import 'dropdown-select.scss';
34
- @import 'autocomplete.scss';
35
- @import 'formula-bar.scss';
36
- @import 'tab-bar.scss';
37
- @import 'overlay-editor.scss';
29
+ @use 'mouse-mask.scss';
30
+ @use 'note.scss';
31
+ @use 'table.scss';
32
+ @use 'tooltip.scss';
33
+ @use 'dropdown-select.scss';
34
+ @use 'autocomplete.scss';
35
+ @use 'formula-bar.scss';
36
+ @use 'tab-bar.scss';
37
+ @use 'overlay-editor.scss';
38
38
 
39
39
  .treb-main.treb-main {
40
40
 
@@ -1,13 +1,16 @@
1
1
 
2
- @import './grid.scss';
3
- @import './theme-defaults.scss';
4
- @import './dark-theme.scss';
5
- @import '../../treb-charts/style/charts.scss';
6
- @import './dialog.scss';
7
- @import './spinner.scss';
8
- @import './treb-icons.scss';
9
- @import './toolbar.scss';
10
- @import './font-stacks.scss';
2
+ @use './defaults.scss' as *;
3
+ @use './z-index.scss' as *;
4
+
5
+ @use './grid.scss';
6
+ @use './theme-defaults.scss';
7
+ @use './dark-theme.scss';
8
+ @use '../../treb-charts/style/charts.scss';
9
+ @use './dialog.scss';
10
+ @use './spinner.scss';
11
+ @use './treb-icons.scss';
12
+ @use './toolbar.scss';
13
+ @use './font-stacks.scss';
11
14
 
12
15
  /*
13
16
  * switching to a double-selector to increase specificity. the particular
@@ -19,6 +19,9 @@
19
19
  *
20
20
  */
21
21
 
22
+ @use 'z-index.scss' as *;
23
+ @use 'defaults.scss' as *;
24
+
22
25
  .treb-main.treb-main {
23
26
 
24
27
  /**
@@ -19,6 +19,10 @@
19
19
  *
20
20
  */
21
21
 
22
+ @use 'z-index.scss' as *;
23
+ @use 'defaults.scss' as *;
24
+
25
+
22
26
  .treb-main.treb-main {
23
27
 
24
28
  // are these exactly the same? clearly we copied-and-pasted
@@ -19,6 +19,9 @@
19
19
  *
20
20
  */
21
21
 
22
+ @use 'z-index.scss' as *;
23
+ @use 'defaults.scss' as *;
24
+
22
25
  .treb-main.treb-main {
23
26
 
24
27
  .treb-grid {
@@ -19,6 +19,10 @@
19
19
  *
20
20
  */
21
21
 
22
+ @use 'z-index.scss' as *;
23
+ @use 'defaults.scss' as *;
24
+
25
+
22
26
  .treb-main.treb-main {
23
27
 
24
28
  .treb-mouse-mask .ghost-tab {
@@ -19,6 +19,9 @@
19
19
  *
20
20
  */
21
21
 
22
+ @use 'z-index.scss' as *;
23
+ @use 'defaults.scss' as *;
24
+
22
25
  .treb-main.treb-main {
23
26
 
24
27
  .treb-sort-button {
@@ -19,6 +19,8 @@
19
19
  *
20
20
  */
21
21
 
22
+ @use './defaults.scss' as *;
23
+
22
24
  /**
23
25
  * we're using variables for selection colors because the colors are used
24
26
  * in more than one place; that's a drawback of using CSS, but I think overall
@@ -31,24 +33,6 @@
31
33
  $primary-selection-color: #4caaf1;
32
34
  $primary-selection-color-unfocused: #acc0cf;
33
35
 
34
- /*
35
- $alternate-selection-color-1: rgb(251, 177, 60);
36
- $alternate-selection-color-2: rgb(64, 192, 64);
37
- $alternate-selection-color-3: rgb(182, 109, 13);
38
- $alternate-selection-color-4: rgb(33, 118, 174);
39
- $alternate-selection-color-5: rgb(254, 104, 71);
40
-
41
- / * *
42
- * slightly darkening colors for text highlighting
43
- * algo: convert to HSL; if L > .5, regenerate with L = .5; back to RGB (why?)
44
- * /
45
- $text-reference-color-1: rgb(250, 155, 5);
46
- $text-reference-color-2: rgb(58, 173, 58);
47
- $text-reference-color-3: rgb(182, 109, 13);
48
- $text-reference-color-4: rgb(33, 118, 174);
49
- $text-reference-color-5: rgb(254, 47, 1);
50
- */
51
-
52
36
  .treb-main.treb-main {
53
37
 
54
38
  --alternate-selection-color-1: rgb(251, 177, 60);
@@ -322,25 +306,21 @@ $text-reference-color-5: rgb(254, 47, 1);
322
306
 
323
307
  /* span:nth-of-type(2n) { */
324
308
  span.highlight-2 {
325
- // color: $text-reference-color-2;
326
309
  color: var(--text-reference-color-2);
327
310
  }
328
311
 
329
312
  /* span:nth-of-type(3n) { */
330
313
  span.highlight-3 {
331
- // color: $text-reference-color-3;
332
314
  color: var(--text-reference-color-3);
333
315
  }
334
316
 
335
317
  /* span:nth-of-type(4n) { */
336
318
  span.highlight-4 {
337
- // color: $text-reference-color-4;
338
319
  color: var(--text-reference-color-4);
339
320
  }
340
321
 
341
322
  /* span:nth-of-type(5n) { */
342
323
  span.highlight-5 {
343
- // color: $text-reference-color-5;
344
324
  color: var(--text-reference-color-5);
345
325
  }
346
326
 
@@ -19,6 +19,10 @@
19
19
  *
20
20
  */
21
21
 
22
+ @use 'z-index.scss' as *;
23
+ @use 'defaults.scss' as *;
24
+
25
+
22
26
  .treb-main.treb-main {
23
27
 
24
28
  .treb-tooltip {
@@ -1,5 +1,5 @@
1
1
 
2
- @import 'layout.scss';
2
+ @use 'layout.scss';
3
3
 
4
4
  /**
5
5
  * default styles for custom element. we basically want
@@ -983,45 +983,6 @@ export class StyleCache {
983
983
  const new_fill: Fill = {...fill};
984
984
  this.fills.push(new_fill);
985
985
 
986
- /*
987
- // add the node structure
988
-
989
- if (!this.dom) throw new Error('missing dom');
990
- const fills = this.dom.find('./fills');
991
-
992
- if (!fills) throw new Error('fills not found');
993
- fills.attrib.count = (Number(fills.attrib.count || 0) + 1).toString();
994
-
995
- const new_element = Element('fill');
996
- const pattern_fill = Element('patternFill', { patternType: fill.pattern_type });
997
-
998
- switch (fill.pattern_type) {
999
- case 'none':
1000
- break;
1001
- case 'solid':
1002
- if (fill.fg_color) {
1003
- const attrs: Record<string, string> = {};
1004
-
1005
- if (fill.fg_color.argb) { attrs.rgb = fill.fg_color.argb; }
1006
- if (fill.fg_color.indexed) { attrs.indexed = fill.fg_color.indexed.toString(); }
1007
- if (fill.fg_color.tint) { attrs.tint = fill.fg_color.tint.toString(); }
1008
- if (typeof fill.fg_color.theme !== 'undefined') { attrs.theme = fill.fg_color.theme.toString(); }
1009
-
1010
- pattern_fill.append(Element('fgColor', attrs));
1011
- }
1012
- break;
1013
- case 'gray':
1014
-
1015
- // ...
1016
-
1017
- break;
1018
- }
1019
-
1020
- new_element.append(pattern_fill);
1021
-
1022
- fills.append(new_element);
1023
- */
1024
-
1025
986
  return this.fills.length - 1;
1026
987
  }
1027
988