@trebco/treb 31.4.0 → 31.7.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.
- package/dist/treb-export-worker.mjs +2 -2
- package/dist/treb-spreadsheet.mjs +12 -11
- package/dist/treb.d.ts +7 -1
- package/package.json +1 -1
- package/treb-base-types/src/color.ts +38 -5
- package/treb-base-types/src/font-stack.ts +1 -1
- package/treb-calculator/src/dag/state_leaf_vertex.ts +16 -39
- package/treb-data-model/src/annotation.ts +5 -0
- package/treb-embed/src/embedded-spreadsheet.ts +108 -55
- package/treb-embed/src/toolbar-message.ts +1 -1
- package/treb-grid/src/types/grid.ts +96 -29
- package/treb-grid/src/types/grid_base.ts +98 -7
- package/treb-grid/src/types/grid_command.ts +32 -2
- package/treb-grid/src/types/grid_events.ts +17 -1
- package/treb-grid/src/types/grid_options.ts +4 -0
- package/treb-grid/src/types/tab_bar.ts +2 -0
- package/treb-grid/src/types/update_flags.ts +6 -0
- package/treb-parser/src/md-parser.ts +23 -7
- package/test/parser.ts +0 -13
|
@@ -104,7 +104,9 @@ import type {
|
|
|
104
104
|
InsertRowsCommand, InsertColumnsCommand, SetNameCommand,
|
|
105
105
|
ActivateSheetCommand, DataValidationCommand,
|
|
106
106
|
ResizeRowsCommand, ResizeColumnsCommand,
|
|
107
|
-
SelectCommand
|
|
107
|
+
SelectCommand,
|
|
108
|
+
CreateAnnotationCommand,
|
|
109
|
+
RemoveAnnotationCommand
|
|
108
110
|
} from './grid_command';
|
|
109
111
|
import { CommandKey
|
|
110
112
|
} from './grid_command';
|
|
@@ -705,6 +707,26 @@ export class Grid extends GridBase {
|
|
|
705
707
|
return undefined;
|
|
706
708
|
}
|
|
707
709
|
|
|
710
|
+
public CreateAnnotation(
|
|
711
|
+
properties: Partial<AnnotationData> = {},
|
|
712
|
+
sheet: Sheet = this.active_sheet,
|
|
713
|
+
add_to_sheet = true,
|
|
714
|
+
offset = false,
|
|
715
|
+
target?: IArea|IRectangle,
|
|
716
|
+
focus?: boolean ) {
|
|
717
|
+
|
|
718
|
+
this.ExecCommand({
|
|
719
|
+
key: CommandKey.CreateAnnotation,
|
|
720
|
+
properties,
|
|
721
|
+
add_to_sheet,
|
|
722
|
+
offset,
|
|
723
|
+
target,
|
|
724
|
+
focus,
|
|
725
|
+
sheet,
|
|
726
|
+
});
|
|
727
|
+
|
|
728
|
+
}
|
|
729
|
+
|
|
708
730
|
/**
|
|
709
731
|
* create an annotation, with properties, without an original object.
|
|
710
732
|
* optionally (and by default) add to sheet.
|
|
@@ -716,10 +738,11 @@ export class Grid extends GridBase {
|
|
|
716
738
|
* @param target new parameter allows setting annotation as rect or as
|
|
717
739
|
* cell range
|
|
718
740
|
*/
|
|
719
|
-
|
|
720
|
-
const annotation = new Annotation(properties);
|
|
741
|
+
protected CreateAnnotationInternal(command: CreateAnnotationCommand) {
|
|
721
742
|
|
|
722
|
-
|
|
743
|
+
const annotation = new Annotation(command.properties);
|
|
744
|
+
|
|
745
|
+
if (command.offset) {
|
|
723
746
|
|
|
724
747
|
// to offset, we have to have layout (or at least scaled rect)
|
|
725
748
|
if (!annotation.data.layout && annotation.scaled_rect) {
|
|
@@ -734,7 +757,7 @@ export class Grid extends GridBase {
|
|
|
734
757
|
let recheck = true;
|
|
735
758
|
while (recheck) {
|
|
736
759
|
recheck = false;
|
|
737
|
-
for (const test of
|
|
760
|
+
for (const test of command.sheet.annotations) {
|
|
738
761
|
if (test === annotation) { continue; }
|
|
739
762
|
if (test.scaled_rect && test.scaled_rect.top === target_rect.top && test.scaled_rect.left === target_rect.left) {
|
|
740
763
|
target_rect = target_rect.Shift(20, 20);
|
|
@@ -747,28 +770,44 @@ export class Grid extends GridBase {
|
|
|
747
770
|
}
|
|
748
771
|
}
|
|
749
772
|
|
|
750
|
-
if (target) {
|
|
751
|
-
if (Rectangle.IsRectangle(target)) {
|
|
773
|
+
if (command.target) {
|
|
774
|
+
if (Rectangle.IsRectangle(command.target)) {
|
|
752
775
|
// console.info('creating from rectangle,', target);
|
|
753
776
|
annotation.data.layout = undefined;
|
|
754
|
-
annotation.rect = Rectangle.Create(target);
|
|
777
|
+
annotation.rect = Rectangle.Create(command.target);
|
|
755
778
|
}
|
|
756
|
-
else if (target.start) {
|
|
779
|
+
else if (command.target.start) {
|
|
757
780
|
annotation.rect = undefined;
|
|
758
|
-
annotation.data.layout = this.layout.AddressToAnnotationLayout(target.start, target.end||target.start);
|
|
781
|
+
annotation.data.layout = this.layout.AddressToAnnotationLayout(command.target.start, command.target.end||command.target.start);
|
|
759
782
|
}
|
|
760
783
|
}
|
|
761
784
|
|
|
762
|
-
if (add_to_sheet) {
|
|
785
|
+
if (command.add_to_sheet) {
|
|
763
786
|
|
|
764
787
|
// ensure we haven't already added this
|
|
765
|
-
if (!
|
|
766
|
-
|
|
788
|
+
if (!command.sheet.annotations.some((test) => test === annotation)) {
|
|
789
|
+
command.sheet.annotations.push(annotation);
|
|
767
790
|
}
|
|
768
791
|
|
|
769
792
|
this.AddAnnotation(annotation);
|
|
770
793
|
}
|
|
771
|
-
|
|
794
|
+
|
|
795
|
+
if (command.focus) {
|
|
796
|
+
|
|
797
|
+
// pending... we need to know which view it was pasted in. maybe this
|
|
798
|
+
// should be the index?
|
|
799
|
+
|
|
800
|
+
const view = annotation.view[this.view_index];
|
|
801
|
+
if (view && view.node) {
|
|
802
|
+
const node = view.node;
|
|
803
|
+
setTimeout(() => {
|
|
804
|
+
node.focus();
|
|
805
|
+
}, 1);
|
|
806
|
+
}
|
|
807
|
+
|
|
808
|
+
}
|
|
809
|
+
|
|
810
|
+
// return annotation;
|
|
772
811
|
}
|
|
773
812
|
|
|
774
813
|
/** placeholder */
|
|
@@ -1060,21 +1099,17 @@ export class Grid extends GridBase {
|
|
|
1060
1099
|
* the parent (although the node still exists in the annotation, if
|
|
1061
1100
|
* it existed before).
|
|
1062
1101
|
*/
|
|
1063
|
-
public RemoveAnnotation(annotation: Annotation): void {
|
|
1064
|
-
|
|
1065
|
-
|
|
1066
|
-
|
|
1067
|
-
|
|
1068
|
-
|
|
1102
|
+
public RemoveAnnotation(annotation: Annotation, sheet = this.active_sheet): void {
|
|
1103
|
+
this.ExecCommand({
|
|
1104
|
+
key: CommandKey.RemoveAnnotation,
|
|
1105
|
+
annotation,
|
|
1106
|
+
sheet,
|
|
1107
|
+
});
|
|
1108
|
+
}
|
|
1069
1109
|
|
|
1070
|
-
|
|
1071
|
-
|
|
1072
|
-
|
|
1073
|
-
event: 'delete',
|
|
1074
|
-
});
|
|
1075
|
-
return;
|
|
1076
|
-
}
|
|
1077
|
-
}
|
|
1110
|
+
protected RemoveAnnotationInternal(command: RemoveAnnotationCommand) {
|
|
1111
|
+
super.RemoveAnnotationInternal(command);
|
|
1112
|
+
this.layout.RemoveAnnotation(command.annotation);
|
|
1078
1113
|
}
|
|
1079
1114
|
|
|
1080
1115
|
/**
|
|
@@ -2442,6 +2477,15 @@ export class Grid extends GridBase {
|
|
|
2442
2477
|
this.DelayedRender(force, area);
|
|
2443
2478
|
}
|
|
2444
2479
|
|
|
2480
|
+
/**
|
|
2481
|
+
* update annotation layouts (not content)
|
|
2482
|
+
*/
|
|
2483
|
+
public UpdateAnnotations() {
|
|
2484
|
+
if (this.active_sheet.annotations.length) {
|
|
2485
|
+
this.layout.UpdateAnnotation(this.active_sheet.annotations, this.theme);
|
|
2486
|
+
}
|
|
2487
|
+
}
|
|
2488
|
+
|
|
2445
2489
|
/* *
|
|
2446
2490
|
* API method
|
|
2447
2491
|
*
|
|
@@ -2688,6 +2732,18 @@ export class Grid extends GridBase {
|
|
|
2688
2732
|
|
|
2689
2733
|
}
|
|
2690
2734
|
|
|
2735
|
+
/**
|
|
2736
|
+
* this is intended to synchronize views when annotations are added/removed.
|
|
2737
|
+
* there should be no need to call it if there's only one view.
|
|
2738
|
+
*/
|
|
2739
|
+
public RefreshAnnotations() {
|
|
2740
|
+
|
|
2741
|
+
this.RemoveAnnotationNodes();
|
|
2742
|
+
for (const element of this.active_sheet.annotations) {
|
|
2743
|
+
this.AddAnnotation(element, true, true);
|
|
2744
|
+
}
|
|
2745
|
+
|
|
2746
|
+
}
|
|
2691
2747
|
|
|
2692
2748
|
/**
|
|
2693
2749
|
* specialization for grid. note that we don't call superclass,
|
|
@@ -3946,7 +4002,14 @@ export class Grid extends GridBase {
|
|
|
3946
4002
|
if (cell?.note) {
|
|
3947
4003
|
|
|
3948
4004
|
// optional MD formatting
|
|
3949
|
-
|
|
4005
|
+
|
|
4006
|
+
// UPDATE: we should allow MD in notes irrespective of the cell
|
|
4007
|
+
// markdown setting. or maybe split the two settings? it makes
|
|
4008
|
+
// a lot of sense in comments, even if you don't want it in cells.
|
|
4009
|
+
|
|
4010
|
+
const parsed = MDParser.instance.Parse(cell.note);
|
|
4011
|
+
|
|
4012
|
+
const md = this.options.comment_markdown ? MDParser.instance.HTML(parsed, { br: false }) : undefined;
|
|
3950
4013
|
this.layout.ShowNote(cell.note, address, event, md);
|
|
3951
4014
|
|
|
3952
4015
|
this.hover_data.note = true;
|
|
@@ -7297,6 +7360,9 @@ export class Grid extends GridBase {
|
|
|
7297
7360
|
}
|
|
7298
7361
|
}
|
|
7299
7362
|
}
|
|
7363
|
+
|
|
7364
|
+
this.CreateAnnotation(composite.data, undefined, true, true, undefined, true);
|
|
7365
|
+
/*
|
|
7300
7366
|
const annotation = this.CreateAnnotation(composite.data, true, true);
|
|
7301
7367
|
const view = annotation.view[this.view_index];
|
|
7302
7368
|
if (view && view.node) {
|
|
@@ -7305,6 +7371,7 @@ export class Grid extends GridBase {
|
|
|
7305
7371
|
node.focus();
|
|
7306
7372
|
}, 1);
|
|
7307
7373
|
}
|
|
7374
|
+
*/
|
|
7308
7375
|
}
|
|
7309
7376
|
catch (e) {
|
|
7310
7377
|
console.error(e);
|
|
@@ -43,7 +43,7 @@ import type { DataModel, ConditionalFormat, // MacroFunction, SerializedModel, S
|
|
|
43
43
|
import type { Parser, UnitAddress} from 'treb-parser';
|
|
44
44
|
import { type ExpressionUnit, IllegalSheetNameRegex, ParseCSV, DecimalMarkType } from 'treb-parser';
|
|
45
45
|
import { Area, IsCellAddress, ValueType, DefaultTableSortOptions } from 'treb-base-types';
|
|
46
|
-
import type { ICellAddress, IArea, Cell, CellValue, CellStyle, Table, TableSortOptions, TableTheme, Complex, PatchOptions as PatchAreaOptions } from 'treb-base-types';
|
|
46
|
+
import type { ICellAddress, IArea, Cell, CellValue, CellStyle, Table, TableSortOptions, TableTheme, Complex, PatchOptions as PatchAreaOptions, Color } from 'treb-base-types';
|
|
47
47
|
|
|
48
48
|
import { Sheet, type SerializeOptions, type Annotation } from 'treb-data-model';
|
|
49
49
|
|
|
@@ -51,9 +51,9 @@ import type { FunctionDescriptor} from '../editors/autocomplete_matcher';
|
|
|
51
51
|
import { AutocompleteMatcher } from '../editors/autocomplete_matcher';
|
|
52
52
|
import { NumberFormat, ValueParser } from 'treb-format';
|
|
53
53
|
|
|
54
|
-
import type { GridEvent } from './grid_events';
|
|
54
|
+
import type { DataEvent, GridEvent, StyleEvent } from './grid_events';
|
|
55
55
|
import { ErrorCode } from './grid_events';
|
|
56
|
-
import type { CommandRecord, DataValidationCommand, DuplicateSheetCommand, FreezeCommand, InsertColumnsCommand, InsertRowsCommand, ResizeColumnsCommand, ResizeRowsCommand, SelectCommand, SetRangeCommand, ShowSheetCommand, SortTableCommand } from './grid_command';
|
|
56
|
+
import type { CommandRecord, CreateAnnotationCommand, DataValidationCommand, DuplicateSheetCommand, FreezeCommand, InsertColumnsCommand, InsertRowsCommand, RemoveAnnotationCommand, ResizeColumnsCommand, ResizeRowsCommand, SelectCommand, SetRangeCommand, ShowSheetCommand, SortTableCommand } from './grid_command';
|
|
57
57
|
import { DefaultGridOptions, type GridOptions } from './grid_options';
|
|
58
58
|
|
|
59
59
|
import { BorderConstants } from './border_constants';
|
|
@@ -813,6 +813,34 @@ export class GridBase {
|
|
|
813
813
|
|
|
814
814
|
}
|
|
815
815
|
|
|
816
|
+
protected RemoveAnnotationInternal(command: RemoveAnnotationCommand) {
|
|
817
|
+
|
|
818
|
+
for (let i = 0; i < command.sheet.annotations.length; i++) {
|
|
819
|
+
if (command.annotation === command.sheet.annotations[i]) {
|
|
820
|
+
command.sheet.annotations.splice(i, 1);
|
|
821
|
+
|
|
822
|
+
// subclass only // this.layout.RemoveAnnotation(annotation);
|
|
823
|
+
|
|
824
|
+
// do we still need this message? not sure
|
|
825
|
+
|
|
826
|
+
this.grid_events.Publish({
|
|
827
|
+
type: 'annotation',
|
|
828
|
+
annotation: command.annotation,
|
|
829
|
+
event: 'delete',
|
|
830
|
+
});
|
|
831
|
+
|
|
832
|
+
return;
|
|
833
|
+
}
|
|
834
|
+
}
|
|
835
|
+
|
|
836
|
+
}
|
|
837
|
+
|
|
838
|
+
/** placeholder */
|
|
839
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
840
|
+
protected CreateAnnotationInternal(command: CreateAnnotationCommand) {
|
|
841
|
+
|
|
842
|
+
}
|
|
843
|
+
|
|
816
844
|
/**
|
|
817
845
|
* resize rows. this supports auto size, but that will fail in !ui grid,
|
|
818
846
|
* because it uses HTML. also non-ui doesn't really need to worry about
|
|
@@ -1904,6 +1932,7 @@ export class GridBase {
|
|
|
1904
1932
|
|
|
1905
1933
|
// nothing
|
|
1906
1934
|
case CommandKey.Null:
|
|
1935
|
+
case CommandKey.TabColor:
|
|
1907
1936
|
case CommandKey.ShowHeaders:
|
|
1908
1937
|
case CommandKey.ShowSheet:
|
|
1909
1938
|
case CommandKey.AddSheet:
|
|
@@ -1913,6 +1942,8 @@ export class GridBase {
|
|
|
1913
1942
|
case CommandKey.RenameSheet:
|
|
1914
1943
|
case CommandKey.ReorderSheet:
|
|
1915
1944
|
case CommandKey.Reset:
|
|
1945
|
+
case CommandKey.CreateAnnotation:
|
|
1946
|
+
case CommandKey.RemoveAnnotation:
|
|
1916
1947
|
break;
|
|
1917
1948
|
|
|
1918
1949
|
/*
|
|
@@ -2009,6 +2040,14 @@ export class GridBase {
|
|
|
2009
2040
|
|
|
2010
2041
|
}
|
|
2011
2042
|
|
|
2043
|
+
public TabColor(sheet: Sheet, color?: Color) {
|
|
2044
|
+
this.ExecCommand({
|
|
2045
|
+
key: CommandKey.TabColor,
|
|
2046
|
+
sheet,
|
|
2047
|
+
color,
|
|
2048
|
+
});
|
|
2049
|
+
}
|
|
2050
|
+
|
|
2012
2051
|
/**
|
|
2013
2052
|
* add sheet. data only.
|
|
2014
2053
|
*/
|
|
@@ -4183,6 +4222,20 @@ export class GridBase {
|
|
|
4183
4222
|
flags.structure_event = true;
|
|
4184
4223
|
break;
|
|
4185
4224
|
|
|
4225
|
+
case CommandKey.TabColor:
|
|
4226
|
+
command.sheet.tab_color = command.color;
|
|
4227
|
+
|
|
4228
|
+
// NOTE: the flag.sheets originally did not update tab colors,
|
|
4229
|
+
// which were cached. we could create a new flag for that, or
|
|
4230
|
+
// we could just refresh the colors. since there aren't that
|
|
4231
|
+
// many of them, it's probably OK to just refresh the colors any
|
|
4232
|
+
// time this flag is set. if that becomes a perf issue in the
|
|
4233
|
+
// future we could add a new flag.
|
|
4234
|
+
|
|
4235
|
+
flags.sheets = true; // repaint tab bar
|
|
4236
|
+
flags.structure_event = true;
|
|
4237
|
+
break;
|
|
4238
|
+
|
|
4186
4239
|
case CommandKey.ReorderSheet:
|
|
4187
4240
|
{
|
|
4188
4241
|
// COEDITING: seems OK, irrespective of active sheet
|
|
@@ -4225,6 +4278,20 @@ export class GridBase {
|
|
|
4225
4278
|
}
|
|
4226
4279
|
break;
|
|
4227
4280
|
|
|
4281
|
+
case CommandKey.RemoveAnnotation:
|
|
4282
|
+
this.RemoveAnnotationInternal(command);
|
|
4283
|
+
flags.structure_event = true;
|
|
4284
|
+
flags.structure_rebuild_required = true;
|
|
4285
|
+
flags.annotation_event = true;
|
|
4286
|
+
break;
|
|
4287
|
+
|
|
4288
|
+
case CommandKey.CreateAnnotation:
|
|
4289
|
+
this.CreateAnnotationInternal(command);
|
|
4290
|
+
flags.structure_event = true;
|
|
4291
|
+
flags.structure_rebuild_required = true;
|
|
4292
|
+
flags.annotation_event = true;
|
|
4293
|
+
break;
|
|
4294
|
+
|
|
4228
4295
|
case CommandKey.ResizeRows:
|
|
4229
4296
|
|
|
4230
4297
|
// moving this to a method so we can specialize: non-UI grid
|
|
@@ -4458,24 +4525,47 @@ export class GridBase {
|
|
|
4458
4525
|
|
|
4459
4526
|
// consolidate events and merge areas
|
|
4460
4527
|
|
|
4528
|
+
let data_event: DataEvent|undefined;
|
|
4529
|
+
let style_event: StyleEvent|undefined;
|
|
4530
|
+
|
|
4461
4531
|
if (flags.data_area) {
|
|
4462
4532
|
if (!flags.data_area.start.sheet_id) {
|
|
4463
4533
|
flags.data_area.SetSheetID(this.active_sheet.id);
|
|
4464
4534
|
}
|
|
4465
|
-
events.push({ type: 'data', area: flags.data_area });
|
|
4535
|
+
// events.push({ type: 'data', area: flags.data_area });
|
|
4536
|
+
data_event = { type: 'data', area: flags.data_area };
|
|
4466
4537
|
}
|
|
4467
4538
|
else if (flags.data_event) {
|
|
4468
|
-
events.push({ type: 'data' });
|
|
4539
|
+
// events.push({ type: 'data' });
|
|
4540
|
+
data_event = { type: 'data' };
|
|
4469
4541
|
}
|
|
4470
4542
|
|
|
4471
4543
|
if (flags.style_area) {
|
|
4472
4544
|
if (!flags.style_area.start.sheet_id) {
|
|
4473
4545
|
flags.style_area.SetSheetID(this.active_sheet.id);
|
|
4474
4546
|
}
|
|
4475
|
-
events.push({ type: 'style', area: flags.style_area });
|
|
4547
|
+
// events.push({ type: 'style', area: flags.style_area });
|
|
4548
|
+
style_event = { type: 'style', area: flags.style_area };
|
|
4476
4549
|
}
|
|
4477
4550
|
else if (flags.style_event) {
|
|
4478
|
-
events.push({ type: 'style' });
|
|
4551
|
+
// events.push({ type: 'style' });
|
|
4552
|
+
style_event = { type: 'style' };
|
|
4553
|
+
}
|
|
4554
|
+
|
|
4555
|
+
if (data_event && style_event) {
|
|
4556
|
+
events.push({
|
|
4557
|
+
type: 'composite',
|
|
4558
|
+
data_area: data_event.area,
|
|
4559
|
+
style_area: style_event.area,
|
|
4560
|
+
});
|
|
4561
|
+
}
|
|
4562
|
+
else {
|
|
4563
|
+
if (data_event) {
|
|
4564
|
+
events.push(data_event);
|
|
4565
|
+
}
|
|
4566
|
+
if (style_event) {
|
|
4567
|
+
events.push(style_event);
|
|
4568
|
+
}
|
|
4479
4569
|
}
|
|
4480
4570
|
|
|
4481
4571
|
if (flags.structure_event) {
|
|
@@ -4483,6 +4573,7 @@ export class GridBase {
|
|
|
4483
4573
|
type: 'structure',
|
|
4484
4574
|
rebuild_required: flags.structure_rebuild_required,
|
|
4485
4575
|
conditional_format: flags.conditional_formatting_event,
|
|
4576
|
+
update_annotations: flags.annotation_event,
|
|
4486
4577
|
});
|
|
4487
4578
|
}
|
|
4488
4579
|
|
|
@@ -19,10 +19,10 @@
|
|
|
19
19
|
*
|
|
20
20
|
*/
|
|
21
21
|
|
|
22
|
-
import type { ICellAddress, IArea, CellStyle, Color, CellValue, Table, TableSortType, TableTheme } from 'treb-base-types';
|
|
22
|
+
import type { ICellAddress, IArea, CellStyle, Color, CellValue, Table, TableSortType, TableTheme, IRectangle } from 'treb-base-types';
|
|
23
23
|
import type { ExpressionUnit } from 'treb-parser';
|
|
24
24
|
import type { BorderConstants } from './border_constants';
|
|
25
|
-
import type { ConditionalFormat } from 'treb-data-model';
|
|
25
|
+
import type { Annotation, AnnotationData, ConditionalFormat, Sheet } from 'treb-data-model';
|
|
26
26
|
|
|
27
27
|
/**
|
|
28
28
|
* switching to an exec-command based model, so we can serialize
|
|
@@ -78,6 +78,27 @@ export enum CommandKey {
|
|
|
78
78
|
AddConditionalFormat,
|
|
79
79
|
RemoveConditionalFormat,
|
|
80
80
|
|
|
81
|
+
TabColor,
|
|
82
|
+
CreateAnnotation,
|
|
83
|
+
RemoveAnnotation,
|
|
84
|
+
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
export interface RemoveAnnotationCommand {
|
|
88
|
+
key: CommandKey.RemoveAnnotation;
|
|
89
|
+
sheet: Sheet;
|
|
90
|
+
annotation: Annotation;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
export interface CreateAnnotationCommand {
|
|
94
|
+
key: CommandKey.CreateAnnotation;
|
|
95
|
+
sheet: Sheet;
|
|
96
|
+
properties: Partial<AnnotationData>;
|
|
97
|
+
add_to_sheet?: boolean;
|
|
98
|
+
offset?: boolean;
|
|
99
|
+
target?: IArea|IRectangle;
|
|
100
|
+
focus?: boolean;
|
|
101
|
+
|
|
81
102
|
}
|
|
82
103
|
|
|
83
104
|
/** base type for sheet commands -- can select sheet by name, id or index */
|
|
@@ -439,6 +460,12 @@ export interface AddConditionalFormatCommand {
|
|
|
439
460
|
format: ConditionalFormat;
|
|
440
461
|
}
|
|
441
462
|
|
|
463
|
+
export interface TabColorCommand {
|
|
464
|
+
key: CommandKey.TabColor;
|
|
465
|
+
sheet: Sheet;
|
|
466
|
+
color?: Color;
|
|
467
|
+
}
|
|
468
|
+
|
|
442
469
|
/**
|
|
443
470
|
* remove conditional format, either as an object or from a target
|
|
444
471
|
* area. as an object, we'll match using object equivalence and not
|
|
@@ -480,6 +507,7 @@ export type Command =
|
|
|
480
507
|
| SetNameCommand
|
|
481
508
|
| AddSheetCommand
|
|
482
509
|
| SetRangeCommand
|
|
510
|
+
| TabColorCommand
|
|
483
511
|
| SortTableCommand
|
|
484
512
|
| ShowSheetCommand
|
|
485
513
|
| MergeCellsCommand
|
|
@@ -499,6 +527,8 @@ export type Command =
|
|
|
499
527
|
| ActivateSheetCommand
|
|
500
528
|
| DataValidationCommand
|
|
501
529
|
| DuplicateSheetCommand
|
|
530
|
+
| CreateAnnotationCommand
|
|
531
|
+
| RemoveAnnotationCommand
|
|
502
532
|
| AddConditionalFormatCommand
|
|
503
533
|
| RemoveConditionalFormatCommand
|
|
504
534
|
) ; // & Ephemeral;
|
|
@@ -83,7 +83,13 @@ export interface StructureEvent {
|
|
|
83
83
|
* we can use this when conditional formats are modified/added/removed
|
|
84
84
|
*/
|
|
85
85
|
conditional_format?: boolean;
|
|
86
|
-
|
|
86
|
+
|
|
87
|
+
/**
|
|
88
|
+
* this flag should be set if annotations have been added or removed,
|
|
89
|
+
* so parent/child views can update as necessary
|
|
90
|
+
*/
|
|
91
|
+
update_annotations?: boolean;
|
|
92
|
+
|
|
87
93
|
}
|
|
88
94
|
|
|
89
95
|
export interface AnnotationEvent {
|
|
@@ -106,6 +112,15 @@ export interface CellEvent {
|
|
|
106
112
|
data?: HyperlinkCellEventData;
|
|
107
113
|
}
|
|
108
114
|
|
|
115
|
+
/**
|
|
116
|
+
* data + style. temporary while I figure out a better solution.
|
|
117
|
+
*/
|
|
118
|
+
export interface CompositeEvent {
|
|
119
|
+
type: 'composite';
|
|
120
|
+
data_area?: Area;
|
|
121
|
+
style_area?: Area;
|
|
122
|
+
}
|
|
123
|
+
|
|
109
124
|
export interface DataEvent {
|
|
110
125
|
type: 'data';
|
|
111
126
|
area?: Area;
|
|
@@ -131,6 +146,7 @@ export type GridEvent
|
|
|
131
146
|
| StyleEvent
|
|
132
147
|
| FlushEvent
|
|
133
148
|
| ScaleEvent
|
|
149
|
+
| CompositeEvent
|
|
134
150
|
| GridErrorEvent
|
|
135
151
|
| StructureEvent
|
|
136
152
|
| AnnotationEvent
|
|
@@ -90,6 +90,9 @@ export interface GridOptions {
|
|
|
90
90
|
/** support MD formatting in text */
|
|
91
91
|
markdown?: boolean;
|
|
92
92
|
|
|
93
|
+
/** support MD formatting in comments */
|
|
94
|
+
comment_markdown?: boolean;
|
|
95
|
+
|
|
93
96
|
/** support font stacks */
|
|
94
97
|
support_font_stacks?: boolean;
|
|
95
98
|
|
|
@@ -104,6 +107,7 @@ export const DefaultGridOptions: GridOptions = {
|
|
|
104
107
|
// insert_function_button: false,
|
|
105
108
|
expand_formula_button: false,
|
|
106
109
|
expand: true,
|
|
110
|
+
comment_markdown: true,
|
|
107
111
|
repaint_on_cell_change: true,
|
|
108
112
|
grid_over_background: false, // true,
|
|
109
113
|
};
|
|
@@ -443,6 +443,8 @@ export class TabBar extends EventSource<TabEvent> {
|
|
|
443
443
|
*/
|
|
444
444
|
public Update(): void {
|
|
445
445
|
|
|
446
|
+
this.tab_color_cache.clear(); // we're setting tab color but it's not getting updated otherwise
|
|
447
|
+
|
|
446
448
|
// this is a hack to normalize behavior if you try to re-order
|
|
447
449
|
// a tab that's not the active tab. what ordinarily happens is
|
|
448
450
|
// we start the drag, but then Update is called again which rebuilds
|
|
@@ -68,6 +68,12 @@ export interface UpdateFlags {
|
|
|
68
68
|
structure_event?: boolean;
|
|
69
69
|
structure_rebuild_required?: boolean;
|
|
70
70
|
|
|
71
|
+
/**
|
|
72
|
+
* new, an indication to split views that we might need to update/reinflate
|
|
73
|
+
* annotations.
|
|
74
|
+
*/
|
|
75
|
+
annotation_event?: boolean;
|
|
76
|
+
|
|
71
77
|
render_area?: Area;
|
|
72
78
|
data_area?: Area;
|
|
73
79
|
style_area?: Area;
|
|
@@ -103,8 +103,16 @@ export class MDParser {
|
|
|
103
103
|
*
|
|
104
104
|
* also the way this works adds extra tags if you have nested styles. not
|
|
105
105
|
* an issue if it's just for testing though.
|
|
106
|
+
*
|
|
107
|
+
* update to optionally not add breaking spaces (<br/>). we need this for
|
|
108
|
+
* containers that are set to white-space: pre-line, where we will already
|
|
109
|
+
* get a linebreak.
|
|
110
|
+
*
|
|
106
111
|
*/
|
|
107
|
-
public HTML(formatted: FormattedString[][]): string {
|
|
112
|
+
public HTML(formatted: FormattedString[][], options: { br?: boolean } = {}): string {
|
|
113
|
+
|
|
114
|
+
// default options
|
|
115
|
+
options = { br: true, ...options };
|
|
108
116
|
|
|
109
117
|
const lines: string[] = [];
|
|
110
118
|
|
|
@@ -128,7 +136,7 @@ export class MDParser {
|
|
|
128
136
|
lines.push(text.join(''));
|
|
129
137
|
}
|
|
130
138
|
|
|
131
|
-
return lines.join('<br/>\n');
|
|
139
|
+
return lines.join(options.br ? '<br/>\n' : '\n');
|
|
132
140
|
|
|
133
141
|
}
|
|
134
142
|
|
|
@@ -454,7 +462,12 @@ export class MDParser {
|
|
|
454
462
|
tokens.push({ type: 'text', text: current_token });
|
|
455
463
|
}
|
|
456
464
|
|
|
457
|
-
|
|
465
|
+
tokens.push({
|
|
466
|
+
type: 'newline',
|
|
467
|
+
text: char,
|
|
468
|
+
})
|
|
469
|
+
|
|
470
|
+
let tmp = '';
|
|
458
471
|
for (;;) { // while (true) {
|
|
459
472
|
const next_char = text[index+1];
|
|
460
473
|
if (this.IsNewline(next_char)) {
|
|
@@ -465,10 +478,13 @@ export class MDParser {
|
|
|
465
478
|
break;
|
|
466
479
|
}
|
|
467
480
|
}
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
481
|
+
|
|
482
|
+
if (tmp.length) {
|
|
483
|
+
tokens.push({
|
|
484
|
+
type: 'newline',
|
|
485
|
+
text: tmp,
|
|
486
|
+
});
|
|
487
|
+
}
|
|
472
488
|
escape = false;
|
|
473
489
|
current_token = '';
|
|
474
490
|
|
package/test/parser.ts
DELETED
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
|
|
2
|
-
import { Parser } from '../treb-parser/src/parser.js';
|
|
3
|
-
|
|
4
|
-
const parser = new Parser();
|
|
5
|
-
|
|
6
|
-
let text = "=NORMDIST((LN(S/K)+(r+s^2/2)*T)/(s*SQRT(T)), 0, 1, TRUE)*S - NORMDIST((LN(S/K)+(r-s^2/2)*T)/(s*SQRT(T)), 0, 1, TRUE)*K*EXP(-r*T)";
|
|
7
|
-
let result = parser.Parse(text);
|
|
8
|
-
// console.info('valid?', result.valid, result.expression);
|
|
9
|
-
|
|
10
|
-
text = "=s*SQRT(T)";
|
|
11
|
-
result = parser.Parse(text);
|
|
12
|
-
console.info('valid?', result.valid, result.expression);
|
|
13
|
-
|