@trebco/treb 29.3.4 → 29.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/treb-spreadsheet-light.mjs +12 -12
- package/dist/treb-spreadsheet.mjs +12 -12
- package/dist/treb.d.ts +36 -41
- package/package.json +1 -1
- package/treb-base-types/src/area.ts +7 -0
- package/treb-base-types/src/cell.ts +2 -46
- package/treb-base-types/src/cells.ts +14 -8
- package/treb-base-types/src/gradient.ts +2 -2
- package/treb-base-types/src/import.ts +2 -2
- package/treb-base-types/src/style.ts +79 -6
- package/treb-base-types/src/theme.ts +24 -15
- package/treb-calculator/src/calculator.ts +22 -12
- package/treb-calculator/src/dag/graph.ts +12 -3
- package/treb-calculator/src/expression-calculator.ts +66 -74
- package/treb-calculator/src/functions/base-functions.ts +2 -2
- package/treb-calculator/src/functions/sparkline.ts +2 -2
- package/treb-calculator/src/functions/statistics-functions.ts +31 -1
- package/treb-data-model/src/data-validation.ts +44 -0
- package/treb-data-model/src/data_model.ts +11 -7
- package/treb-data-model/src/index.ts +1 -1
- package/treb-data-model/src/named.ts +35 -10
- package/treb-data-model/src/sheet.ts +75 -15
- package/treb-data-model/src/sheet_types.ts +4 -0
- package/treb-embed/src/custom-element/spreadsheet-constructor.ts +7 -3
- package/treb-embed/src/embedded-spreadsheet.ts +50 -28
- package/treb-embed/src/progress-dialog.ts +4 -1
- package/treb-embed/src/types.ts +9 -0
- package/treb-export/src/drawing2/chart2.ts +20 -38
- package/treb-export/src/drawing2/drawing2.ts +2 -107
- package/treb-export/src/export-worker/export-worker.ts +1 -1
- package/treb-export/src/{export2.ts → export.ts} +439 -628
- package/treb-export/src/import2.ts +63 -26
- package/treb-export/src/workbook-style2.ts +16 -14
- package/treb-export/src/workbook2.ts +2 -18
- package/treb-export/src/xml-utils.ts +50 -2
- package/treb-export/src/zip-wrapper.ts +1 -1
- package/treb-grid/src/editors/overlay_editor.ts +3 -3
- package/treb-grid/src/layout/base_layout.ts +5 -14
- package/treb-grid/src/render/tile_renderer.ts +49 -48
- package/treb-grid/src/types/grid.ts +164 -26
- package/treb-grid/src/types/grid_base.ts +93 -17
- package/treb-grid/src/types/grid_command.ts +2 -1
- package/treb-parser/src/parser-types.ts +10 -0
- package/treb-parser/src/parser.ts +55 -17
|
@@ -30,16 +30,16 @@ import type { ParseResult } from 'treb-parser';
|
|
|
30
30
|
import { Parser } from 'treb-parser';
|
|
31
31
|
import type { RangeType, AddressType, HyperlinkType } from './address-type';
|
|
32
32
|
import { is_range, ShiftRange, InRange, is_address } from './address-type';
|
|
33
|
-
import type { ImportedSheetData, AnchoredAnnotation, CellParseResult, AnnotationLayout, Corner as LayoutCorner,
|
|
34
|
-
import {
|
|
33
|
+
import type { ImportedSheetData, AnchoredAnnotation, CellParseResult, AnnotationLayout, Corner as LayoutCorner, IArea, GradientStop, Color, HTMLColor, ThemeColor } from 'treb-base-types';
|
|
34
|
+
import type { SerializedValueType } from 'treb-base-types';
|
|
35
35
|
import type { Sheet} from './workbook-sheet2';
|
|
36
36
|
import { VisibleState } from './workbook-sheet2';
|
|
37
37
|
import type { CellAnchor } from './drawing2/drawing2';
|
|
38
|
-
import { XMLUtils } from './xml-utils';
|
|
38
|
+
import { type DOMContent, XMLUtils } from './xml-utils';
|
|
39
39
|
|
|
40
40
|
// import { one_hundred_pixels } from './constants';
|
|
41
41
|
import { ColumnWidthToPixels } from './column-width';
|
|
42
|
-
import type { AnnotationType } from 'treb-data-model';
|
|
42
|
+
import type { DataValidation, AnnotationType } from 'treb-data-model';
|
|
43
43
|
import { ZipWrapper } from './zip-wrapper';
|
|
44
44
|
import type { ConditionalFormat } from 'treb-data-model';
|
|
45
45
|
|
|
@@ -84,7 +84,7 @@ export class Importer {
|
|
|
84
84
|
};
|
|
85
85
|
v?: string|number|{
|
|
86
86
|
t$: string;
|
|
87
|
-
a$?:
|
|
87
|
+
a$?: DOMContent;
|
|
88
88
|
};
|
|
89
89
|
f?: string|{
|
|
90
90
|
t$: string;
|
|
@@ -99,7 +99,7 @@ export class Importer {
|
|
|
99
99
|
arrays: RangeType[],
|
|
100
100
|
merges: RangeType[],
|
|
101
101
|
links: HyperlinkType[],
|
|
102
|
-
validations: Array<{ address: ICellAddress, validation: DataValidation }>,
|
|
102
|
+
// validations: Array<{ address: ICellAddress, validation: DataValidation }>,
|
|
103
103
|
): CellParseResult | undefined {
|
|
104
104
|
|
|
105
105
|
// must have, at minimum, an address (must be a single cell? FIXME)
|
|
@@ -285,12 +285,14 @@ export class Importer {
|
|
|
285
285
|
}
|
|
286
286
|
}
|
|
287
287
|
|
|
288
|
+
/*
|
|
288
289
|
for (const validation of validations) {
|
|
289
290
|
if (validation.address.row === shifted.row && validation.address.column === shifted.col) {
|
|
290
291
|
result.validation = validation.validation;
|
|
291
292
|
break;
|
|
292
293
|
}
|
|
293
294
|
}
|
|
295
|
+
*/
|
|
294
296
|
|
|
295
297
|
for (const range of merges) {
|
|
296
298
|
if (InRange(range, shifted)) {
|
|
@@ -445,12 +447,12 @@ export class Importer {
|
|
|
445
447
|
|
|
446
448
|
const color_element = rule.colorScale.color[index];
|
|
447
449
|
if (color_element.a$.rgb) {
|
|
448
|
-
color.text = '#' + color_element.a$.rgb.substring(2);
|
|
450
|
+
(color as HTMLColor).text = '#' + color_element.a$.rgb.substring(2);
|
|
449
451
|
}
|
|
450
452
|
else if (color_element.a$.theme) {
|
|
451
|
-
color.theme = Number(color_element.a$.theme) || 0;
|
|
453
|
+
(color as ThemeColor).theme = Number(color_element.a$.theme) || 0;
|
|
452
454
|
if (color_element.a$.tint) {
|
|
453
|
-
color.tint = Math.round(color_element.a$.tint * 1000) / 1000;
|
|
455
|
+
(color as ThemeColor).tint = Math.round(color_element.a$.tint * 1000) / 1000;
|
|
454
456
|
}
|
|
455
457
|
}
|
|
456
458
|
|
|
@@ -512,10 +514,15 @@ export class Importer {
|
|
|
512
514
|
const conditional_formats: ConditionalFormat[] = [];
|
|
513
515
|
const links: HyperlinkType[] = [];
|
|
514
516
|
const row_styles: number[] = []; // may be sparse
|
|
517
|
+
|
|
518
|
+
/*
|
|
515
519
|
const validations: Array<{
|
|
516
520
|
address: ICellAddress,
|
|
517
521
|
validation: DataValidation,
|
|
518
522
|
}> = [];
|
|
523
|
+
*/
|
|
524
|
+
const validations: DataValidation[] = [];
|
|
525
|
+
|
|
519
526
|
const annotations: AnchoredAnnotation[] = [];
|
|
520
527
|
|
|
521
528
|
const FindAll: (path: string) => any[] = XMLUtils.FindAll.bind(XMLUtils, sheet.sheet_data);
|
|
@@ -569,33 +576,68 @@ export class Importer {
|
|
|
569
576
|
const formula = entry.formula1;
|
|
570
577
|
|
|
571
578
|
if (ref && formula && type === 'list') {
|
|
572
|
-
let address: ICellAddress|undefined;
|
|
579
|
+
// let address: ICellAddress|undefined;
|
|
573
580
|
let validation: DataValidation|undefined;
|
|
574
581
|
let parse_result = this.parser.Parse(ref);
|
|
582
|
+
const target: IArea[] = [];
|
|
575
583
|
|
|
576
584
|
// apparently these are encoded as ranges for merged cells...
|
|
577
585
|
|
|
586
|
+
// NOTE: actually you can have a range, then validation applies
|
|
587
|
+
// to every cell in the range. also you can have multiple ranges,
|
|
588
|
+
// apparently separated by spaces.
|
|
589
|
+
|
|
578
590
|
if (parse_result.expression) {
|
|
579
591
|
if (parse_result.expression.type === 'address') {
|
|
580
|
-
address = parse_result.expression;
|
|
592
|
+
// address = parse_result.expression;
|
|
593
|
+
target.push({start: parse_result.expression, end: parse_result.expression});
|
|
581
594
|
}
|
|
582
595
|
else if (parse_result.expression.type === 'range') {
|
|
583
|
-
address = parse_result.expression.start;
|
|
596
|
+
// address = parse_result.expression.start;
|
|
597
|
+
target.push(parse_result.expression);
|
|
584
598
|
}
|
|
585
599
|
}
|
|
586
600
|
|
|
587
601
|
parse_result = this.parser.Parse(formula);
|
|
602
|
+
|
|
588
603
|
if (parse_result.expression) {
|
|
589
604
|
if (parse_result.expression.type === 'range') {
|
|
590
605
|
validation = {
|
|
591
|
-
type:
|
|
606
|
+
type: 'range',
|
|
592
607
|
area: parse_result.expression,
|
|
608
|
+
target,
|
|
593
609
|
};
|
|
594
610
|
}
|
|
595
611
|
else if (parse_result.expression.type === 'literal') {
|
|
596
612
|
validation = {
|
|
597
|
-
type:
|
|
613
|
+
type: 'list',
|
|
614
|
+
target,
|
|
598
615
|
list: parse_result.expression.value.toString().split(/,/).map(value => {
|
|
616
|
+
|
|
617
|
+
// there are no formulas here. value is a string, separated
|
|
618
|
+
// by commas. there is no way to escape a comma (AFAICT; not
|
|
619
|
+
// official, but search). if you did want a comma, you'd need
|
|
620
|
+
// to use a range.
|
|
621
|
+
|
|
622
|
+
// but the uptake is split on commas. after that you can try
|
|
623
|
+
// to check for numbers or bools, but they will be in the string.
|
|
624
|
+
|
|
625
|
+
// I think excel might sort the entries? not sure. don't do it
|
|
626
|
+
// for now.
|
|
627
|
+
|
|
628
|
+
const num = Number(value);
|
|
629
|
+
if (!isNaN(num)) {
|
|
630
|
+
return num;
|
|
631
|
+
}
|
|
632
|
+
if (value.toLowerCase() === 'true') {
|
|
633
|
+
return true;
|
|
634
|
+
}
|
|
635
|
+
if (value.toLowerCase() === 'false') {
|
|
636
|
+
return false;
|
|
637
|
+
}
|
|
638
|
+
return value; // string
|
|
639
|
+
|
|
640
|
+
/*
|
|
599
641
|
const tmp = this.parser.Parse(value);
|
|
600
642
|
|
|
601
643
|
// if type is "group", that means we saw some spaces. this
|
|
@@ -612,13 +654,16 @@ export class Importer {
|
|
|
612
654
|
return tmp.expression.name;
|
|
613
655
|
}
|
|
614
656
|
return undefined;
|
|
657
|
+
*/
|
|
658
|
+
|
|
615
659
|
}),
|
|
616
660
|
};
|
|
617
661
|
}
|
|
618
662
|
}
|
|
619
663
|
|
|
620
|
-
if (
|
|
621
|
-
validations.push({address, validation});
|
|
664
|
+
if (target.length && validation) {
|
|
665
|
+
// validations.push({address, validation});
|
|
666
|
+
validations.push(validation);
|
|
622
667
|
}
|
|
623
668
|
|
|
624
669
|
}
|
|
@@ -717,20 +762,11 @@ export class Importer {
|
|
|
717
762
|
row_heights[row_index - 1] = height;
|
|
718
763
|
}
|
|
719
764
|
|
|
720
|
-
/*
|
|
721
|
-
if (row.a$?.ht && row.a$?.customHeight) {
|
|
722
|
-
const num = Number(row.a$.ht);
|
|
723
|
-
if (!isNaN(num)) {
|
|
724
|
-
row_heights[row_index - 1] = Math.round(num * 4 / 3); // seems to be the excel unit -> pixel ratio
|
|
725
|
-
}
|
|
726
|
-
}
|
|
727
|
-
*/
|
|
728
|
-
|
|
729
765
|
let cells = row.c || [];
|
|
730
766
|
if (!Array.isArray(cells)) { cells = [cells]; }
|
|
731
767
|
|
|
732
768
|
for (const element of cells) {
|
|
733
|
-
const cell = this.ParseCell(sheet, element, shared_formulae, arrays, merges, links, validations);
|
|
769
|
+
const cell = this.ParseCell(sheet, element, shared_formulae, arrays, merges, links); // , validations);
|
|
734
770
|
if (cell) {
|
|
735
771
|
data.push(cell);
|
|
736
772
|
}
|
|
@@ -1178,6 +1214,7 @@ export class Importer {
|
|
|
1178
1214
|
row_styles,
|
|
1179
1215
|
annotations,
|
|
1180
1216
|
conditional_formats,
|
|
1217
|
+
data_validations: validations,
|
|
1181
1218
|
styles: this.workbook?.style_cache?.CellXfToStyles() || [],
|
|
1182
1219
|
};
|
|
1183
1220
|
|
|
@@ -22,7 +22,7 @@
|
|
|
22
22
|
// import * as ElementTree from 'elementtree';
|
|
23
23
|
// import { Element, ElementTree as Tree } from 'elementtree';
|
|
24
24
|
|
|
25
|
-
import { type CompositeBorderEdge, Style, type CellStyle, type PropertyKeys, type Color } from 'treb-base-types';
|
|
25
|
+
import { type CompositeBorderEdge, Style, type CellStyle, type PropertyKeys, type Color, IsHTMLColor, IsThemeColor, type ThemeColor, type HTMLColor, ThemeColorIndex } from 'treb-base-types';
|
|
26
26
|
import { Theme } from './workbook-theme2';
|
|
27
27
|
import { NumberFormatCache } from 'treb-format';
|
|
28
28
|
import { XMLUtils } from './xml-utils';
|
|
@@ -85,12 +85,14 @@ export interface CellXf {
|
|
|
85
85
|
|
|
86
86
|
}
|
|
87
87
|
|
|
88
|
+
/*
|
|
88
89
|
interface ColorAttributes {
|
|
89
90
|
indexed?: string;
|
|
90
91
|
rgb?: string;
|
|
91
92
|
theme?: string;
|
|
92
93
|
tint?: string;
|
|
93
94
|
}
|
|
95
|
+
*/
|
|
94
96
|
|
|
95
97
|
export interface BorderEdge {
|
|
96
98
|
style?: string;
|
|
@@ -303,11 +305,11 @@ export class StyleCache {
|
|
|
303
305
|
//}
|
|
304
306
|
|
|
305
307
|
if (composite.text) {
|
|
306
|
-
if (composite.text
|
|
308
|
+
if (IsHTMLColor(composite.text)) {
|
|
307
309
|
font.color_argb = composite.text.text;
|
|
308
310
|
}
|
|
309
|
-
else if (
|
|
310
|
-
font.color_theme = composite.text
|
|
311
|
+
else if (IsThemeColor(composite.text)) {
|
|
312
|
+
font.color_theme = ThemeColorIndex(composite.text);
|
|
311
313
|
if (composite.text.tint) {
|
|
312
314
|
font.color_tint = composite.text.tint;
|
|
313
315
|
}
|
|
@@ -317,11 +319,11 @@ export class StyleCache {
|
|
|
317
319
|
const TranslateBorder = (src: CompositeBorderEdge, dest: BorderEdge) => {
|
|
318
320
|
if (src.width) {
|
|
319
321
|
dest.style = 'thin';
|
|
320
|
-
if (src.color
|
|
322
|
+
if (IsHTMLColor(src.color)) {
|
|
321
323
|
dest.rgba =src.color.text;
|
|
322
324
|
}
|
|
323
|
-
else if (
|
|
324
|
-
dest.theme = src.color
|
|
325
|
+
else if (IsThemeColor(src.color)) {
|
|
326
|
+
dest.theme = ThemeColorIndex(src.color);
|
|
325
327
|
if (src.color.tint) {
|
|
326
328
|
dest.tint = src.color.tint;
|
|
327
329
|
}
|
|
@@ -440,12 +442,12 @@ export class StyleCache {
|
|
|
440
442
|
|
|
441
443
|
if (composite.fill) {
|
|
442
444
|
fill.pattern_type = 'solid';
|
|
443
|
-
if (composite.fill
|
|
445
|
+
if (IsHTMLColor(composite.fill)) {
|
|
444
446
|
fill.fg_color = { argb: composite.fill.text };
|
|
445
447
|
options.fill = fill;
|
|
446
448
|
}
|
|
447
|
-
else if (
|
|
448
|
-
fill.fg_color = { theme: composite.fill
|
|
449
|
+
else if (IsThemeColor(composite.fill)) {
|
|
450
|
+
fill.fg_color = { theme: ThemeColorIndex(composite.fill) };
|
|
449
451
|
if (composite.fill.tint) {
|
|
450
452
|
fill.fg_color.tint = composite.fill.tint;
|
|
451
453
|
}
|
|
@@ -619,7 +621,7 @@ export class StyleCache {
|
|
|
619
621
|
};
|
|
620
622
|
|
|
621
623
|
if (fill.fg_color.tint) {
|
|
622
|
-
props.fill.tint = Math.round(fill.fg_color.tint * 1000) / 1000;
|
|
624
|
+
(props.fill as ThemeColor).tint = Math.round(fill.fg_color.tint * 1000) / 1000;
|
|
623
625
|
}
|
|
624
626
|
|
|
625
627
|
/*
|
|
@@ -1317,12 +1319,12 @@ export class StyleCache {
|
|
|
1317
1319
|
const ParseDXFColor = (element: any) => {
|
|
1318
1320
|
const color: Color = {};
|
|
1319
1321
|
if (element.a$.rgb) {
|
|
1320
|
-
color.text = '#' + element.a$.rgb.substring(2);
|
|
1322
|
+
(color as HTMLColor).text = '#' + element.a$.rgb.substring(2);
|
|
1321
1323
|
}
|
|
1322
1324
|
else if (element.a$.theme) {
|
|
1323
|
-
color.theme = Number(element.a$.theme) || 0;
|
|
1325
|
+
(color as ThemeColor).theme = Number(element.a$.theme) || 0;
|
|
1324
1326
|
if (element.a$.tint) {
|
|
1325
|
-
color.tint = Math.round(element.a$.tint * 1000) / 1000;
|
|
1327
|
+
(color as ThemeColor).tint = Math.round(element.a$.tint * 1000) / 1000;
|
|
1326
1328
|
}
|
|
1327
1329
|
}
|
|
1328
1330
|
return color;
|
|
@@ -28,33 +28,17 @@ const xmlparser2 = new XMLParser(XMLOptions2);
|
|
|
28
28
|
|
|
29
29
|
// import * as he from 'he';
|
|
30
30
|
|
|
31
|
-
//import { Drawing, TwoCellAnchor, CellAnchor } from './drawing/drawing';
|
|
32
31
|
import type { TwoCellAnchor, CellAnchor } from './drawing2/drawing2';
|
|
33
32
|
|
|
34
|
-
// import { ImportedSheetData, IArea } from 'treb-base-types/src';
|
|
35
33
|
import { SharedStrings } from './shared-strings2';
|
|
36
34
|
import { StyleCache } from './workbook-style2';
|
|
37
35
|
import { Theme } from './workbook-theme2';
|
|
38
36
|
import { Sheet, VisibleState } from './workbook-sheet2';
|
|
39
37
|
import type { RelationshipMap } from './relationship';
|
|
40
38
|
import { ZipWrapper } from './zip-wrapper';
|
|
41
|
-
import type { CellStyle } from 'treb-base-types';
|
|
39
|
+
import type { CellStyle, ThemeColor } from 'treb-base-types';
|
|
42
40
|
import type { SerializedNamed } from 'treb-data-model';
|
|
43
41
|
|
|
44
|
-
|
|
45
|
-
/*
|
|
46
|
-
const XMLTypeMap = {
|
|
47
|
-
'sheet': 'application/vnd.openxmlformats-officedocument.spreadsheetml.worksheet+xml',
|
|
48
|
-
'theme': 'application/vnd.openxmlformats-officedocument.theme+xml',
|
|
49
|
-
'drawing': 'application/vnd.openxmlformats-officedocument.drawing+xml',
|
|
50
|
-
'chart': 'application/vnd.openxmlformats-officedocument.drawingml.chart+xml',
|
|
51
|
-
'themeOverride': 'application/vnd.openxmlformats-officedocument.themeOverride+xml',
|
|
52
|
-
'ctrlProp': 'application/vnd.ms-excel.controlproperties+xml',
|
|
53
|
-
'style': 'application/vnd.ms-office.chartstyle+xml',
|
|
54
|
-
'colors': 'application/vnd.ms-office.chartcolorstyle+xml',
|
|
55
|
-
};
|
|
56
|
-
*/
|
|
57
|
-
|
|
58
42
|
export const ConditionalFormatOperators: Record<string, string> = {
|
|
59
43
|
greaterThan: '>',
|
|
60
44
|
greaterThanOrEquals: '>=',
|
|
@@ -413,7 +397,7 @@ export class Workbook {
|
|
|
413
397
|
if (fill['a:schemeClr']['a:lumOff']?.a$?.val) {
|
|
414
398
|
const num = Number(fill['a:schemeClr']['a:lumOff'].a$.val);
|
|
415
399
|
if (!isNaN(num)) {
|
|
416
|
-
style.fill.tint = num / 1e5;
|
|
400
|
+
(style.fill as ThemeColor).tint = num / 1e5;
|
|
417
401
|
}
|
|
418
402
|
}
|
|
419
403
|
}
|
|
@@ -20,14 +20,62 @@
|
|
|
20
20
|
*/
|
|
21
21
|
|
|
22
22
|
import { Unescape } from './unescape_xml';
|
|
23
|
-
import type
|
|
23
|
+
import { type X2jOptions, XMLBuilder, type XmlBuilderOptions } from 'fast-xml-parser';
|
|
24
24
|
|
|
25
25
|
export const XMLTagProcessor = (name: string, value: string): string => Unescape(value);
|
|
26
26
|
|
|
27
27
|
export interface DOMContent {
|
|
28
|
-
[index: string]: string|DOMContent|string[]|DOMContent[]|number|number[];
|
|
28
|
+
[index: string]: string|DOMContent|string[]|DOMContent[]|number|number[]|undefined;
|
|
29
29
|
}
|
|
30
30
|
|
|
31
|
+
/**
|
|
32
|
+
* not sure why we have to do this, but filter attributes that
|
|
33
|
+
* have value === undefined
|
|
34
|
+
*/
|
|
35
|
+
export const ScrubXML = (dom: DOMContent) => {
|
|
36
|
+
if (dom) {
|
|
37
|
+
if (Array.isArray(dom)) {
|
|
38
|
+
for (const entry of dom) {
|
|
39
|
+
ScrubXML(entry);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
else if (typeof dom === 'object') {
|
|
43
|
+
for (const [key, value] of Object.entries(dom)) {
|
|
44
|
+
if (key === 'a$') {
|
|
45
|
+
if (typeof value === 'object') {
|
|
46
|
+
const replacement: DOMContent = {};
|
|
47
|
+
for (const [attr_name, attr_value] of Object.entries(value)) {
|
|
48
|
+
if (attr_value !== undefined) {
|
|
49
|
+
replacement[attr_name] = attr_value;
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
dom[key] = replacement;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
else {
|
|
56
|
+
ScrubXML(value as DOMContent);
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
return dom;
|
|
62
|
+
};
|
|
63
|
+
|
|
64
|
+
export const PatchXMLBuilder = (options: Partial<XmlBuilderOptions>) => {
|
|
65
|
+
|
|
66
|
+
const builder = new XMLBuilder(options);
|
|
67
|
+
const build = builder.build;
|
|
68
|
+
|
|
69
|
+
builder.build = (arg: DOMContent) => {
|
|
70
|
+
return build.call(builder, ScrubXML(arg)); // get the "this" value right
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
return builder;
|
|
74
|
+
|
|
75
|
+
};
|
|
76
|
+
|
|
77
|
+
//////////////////
|
|
78
|
+
|
|
31
79
|
export const XMLOptions: Partial<X2jOptions> = {
|
|
32
80
|
ignoreAttributes: false,
|
|
33
81
|
attributeNamePrefix: '__',
|
|
@@ -20,7 +20,7 @@
|
|
|
20
20
|
*/
|
|
21
21
|
|
|
22
22
|
import { Editor, type NodeDescriptor } from './editor';
|
|
23
|
-
import { Area, Cell, type CellStyle, type CellValue, Rectangle, Style, type Theme,
|
|
23
|
+
import { Area, Cell, type CellStyle, type CellValue, Rectangle, Style, type Theme, ResolveThemeColor } from 'treb-base-types';
|
|
24
24
|
import { DataModel, type ViewModel, type GridSelection } from 'treb-data-model';
|
|
25
25
|
import { Autocomplete } from './autocomplete';
|
|
26
26
|
import { UA } from '../util/ua';
|
|
@@ -287,8 +287,8 @@ export class OverlayEditor extends Editor<ResetSelectionEvent> {
|
|
|
287
287
|
const style: CellStyle = cell.style || {};
|
|
288
288
|
|
|
289
289
|
this.edit_node.style.font = Style.Font(style, this.scale);
|
|
290
|
-
this.edit_node.style.color =
|
|
291
|
-
this.edit_inset.style.backgroundColor =
|
|
290
|
+
this.edit_node.style.color = ResolveThemeColor(this.theme, style.text, 1);
|
|
291
|
+
this.edit_inset.style.backgroundColor = ResolveThemeColor(this.theme, style.fill, 0);
|
|
292
292
|
|
|
293
293
|
// NOTE: now that we dropped support for IE11, we can probably
|
|
294
294
|
// remove more than one class at the same time.
|
|
@@ -24,7 +24,7 @@ import type { DataModel, ViewModel, Annotation } from 'treb-data-model';
|
|
|
24
24
|
|
|
25
25
|
import type { Tile } from '../types/tile';
|
|
26
26
|
import type { Theme, Point, Extent, Size, Position, ICellAddress, Table, IArea } from 'treb-base-types';
|
|
27
|
-
import { Style, Area, Rectangle,
|
|
27
|
+
import { Style, Area, Rectangle, ResolveThemeColor } from 'treb-base-types';
|
|
28
28
|
|
|
29
29
|
import { MouseDrag } from '../types/drag_mask';
|
|
30
30
|
import type { GridEvent } from '../types/grid_events';
|
|
@@ -1279,7 +1279,7 @@ export abstract class BaseLayout {
|
|
|
1279
1279
|
this.row_header.style.backgroundColor =
|
|
1280
1280
|
this.column_header.style.backgroundColor =
|
|
1281
1281
|
this.corner.style.backgroundColor =
|
|
1282
|
-
theme.headers?.fill ?
|
|
1282
|
+
theme.headers?.fill ? ResolveThemeColor(theme, theme.headers.fill, 0) : '';
|
|
1283
1283
|
|
|
1284
1284
|
// theme.headers?.background || '';
|
|
1285
1285
|
// theme.header_background_color || ''; // this.theme.header_background;
|
|
@@ -1291,23 +1291,12 @@ export abstract class BaseLayout {
|
|
|
1291
1291
|
|
|
1292
1292
|
for (const row of this.grid_tiles) {
|
|
1293
1293
|
for (const tile of row) {
|
|
1294
|
-
tile.style.backgroundColor =
|
|
1294
|
+
tile.style.backgroundColor = ResolveThemeColor(theme, theme.grid_cell?.fill, 0) || '#fff';
|
|
1295
1295
|
}
|
|
1296
1296
|
}
|
|
1297
1297
|
|
|
1298
|
-
/*
|
|
1299
|
-
this.tooltip.style.fontFamily = theme.tooltip_font_face || '';
|
|
1300
|
-
this.tooltip.style.fontSize = theme.tooltip_font_size ? `${theme.tooltip_font_size}pt` : '';
|
|
1301
|
-
this.tooltip.style.backgroundColor = theme.tooltip_background || '';
|
|
1302
|
-
this.tooltip.style.borderColor = theme.tooltip_background || ''; // for arrow
|
|
1303
|
-
this.tooltip.style.color = theme.tooltip_color || '';
|
|
1304
|
-
*/
|
|
1305
|
-
|
|
1306
1298
|
// TODO: dropdown caret
|
|
1307
1299
|
|
|
1308
|
-
// this.dropdown_list.style.fontFamily = theme.cell_font || '';
|
|
1309
|
-
// const font_size = (theme.cell_font_size_value || 10) * this.scale;
|
|
1310
|
-
// this.dropdown_list.style.fontSize = (font_size) + (theme.cell_font_size_unit || 'pt');
|
|
1311
1300
|
this.dropdown_list.style.font = Style.Font(theme.grid_cell || {});
|
|
1312
1301
|
|
|
1313
1302
|
}
|
|
@@ -1415,6 +1404,8 @@ export abstract class BaseLayout {
|
|
|
1415
1404
|
this.dropdown_list.style.left = `${target_rect.left + 2}px`;
|
|
1416
1405
|
this.dropdown_list.style.minWidth = `${target_rect.width}px`;
|
|
1417
1406
|
|
|
1407
|
+
this.dropdown_list.style.fontSize = (this.scale.toFixed(2) + 'em');
|
|
1408
|
+
|
|
1418
1409
|
this.dropdown_list.textContent = '';
|
|
1419
1410
|
for (const value of list) {
|
|
1420
1411
|
const entry = this.DOM.Div(undefined, this.dropdown_list);
|