@trebco/treb 25.4.2 → 25.6.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.mjs +7 -7
- package/dist/treb.d.ts +4 -3
- package/package.json +1 -1
- package/treb-base-types/src/import.ts +23 -22
- package/treb-base-types/src/table.ts +0 -4
- package/treb-base-types/src/theme.ts +0 -11
- package/treb-calculator/src/calculator.ts +2 -2
- package/treb-embed/src/custom-element/spreadsheet-constructor.ts +47 -0
- package/treb-embed/src/embedded-spreadsheet.ts +53 -19
- package/treb-embed/src/options.ts +11 -0
- package/treb-embed/src/types.ts +1 -0
- package/treb-embed/style/theme-defaults.scss +5 -0
- package/treb-export/src/export2.ts +16 -10
- package/treb-export/src/import2.ts +2 -1
- package/treb-grid/src/index.ts +2 -1
- package/treb-grid/src/layout/base_layout.ts +16 -13
- package/treb-grid/src/types/annotation.ts +110 -82
- package/treb-grid/src/types/grid.ts +29 -29
- package/treb-grid/src/types/grid_base.ts +47 -47
- package/treb-grid/src/types/sheet.ts +9 -9
- package/treb-grid/src/types/sheet_types.ts +2 -2
package/dist/treb.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! API v25.
|
|
1
|
+
/*! API v25.6. Copyright 2018-2023 trebco, llc. All rights reserved. LGPL: https://treb.app/license */
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* add our tag to the map
|
|
@@ -367,7 +367,7 @@ export declare class EmbeddedSpreadsheet {
|
|
|
367
367
|
* @param argument_separator - the argument separator to use when evaluating
|
|
368
368
|
* the function. defaults to current locale.
|
|
369
369
|
*/
|
|
370
|
-
InsertAnnotation(formula: string, type?:
|
|
370
|
+
InsertAnnotation(formula: string, type?: AnnotationType, rect?: IRectangle | RangeReference, argument_separator?: ',' | ';'): void;
|
|
371
371
|
|
|
372
372
|
/**
|
|
373
373
|
* Insert an image. This method will open a file chooser and (if an image
|
|
@@ -952,6 +952,7 @@ export interface FreezePane {
|
|
|
952
952
|
rows: number;
|
|
953
953
|
columns: number;
|
|
954
954
|
}
|
|
955
|
+
export type AnnotationType = 'treb-chart' | 'image' | 'external';
|
|
955
956
|
export declare type BorderConstants = "none" | "all" | "outside" | "top" | "bottom" | "left" | "right";
|
|
956
957
|
|
|
957
958
|
/**
|
|
@@ -1210,7 +1211,7 @@ export interface TableSortOptions {
|
|
|
1210
1211
|
asc: boolean;
|
|
1211
1212
|
}
|
|
1212
1213
|
export type TableSortType = 'text' | 'numeric' | 'auto';
|
|
1213
|
-
export declare type LoadSource = "drag-and-drop" | "local-file" | "network-file" | "local-storage" | "undo";
|
|
1214
|
+
export declare type LoadSource = "drag-and-drop" | "local-file" | "network-file" | "local-storage" | "inline-document" | "undo";
|
|
1214
1215
|
|
|
1215
1216
|
/**
|
|
1216
1217
|
* EmbeddedSheetEvent is a discriminated union. Switch on the `type` field
|
package/package.json
CHANGED
|
@@ -1,30 +1,31 @@
|
|
|
1
|
-
/*
|
|
2
|
-
* This file is part of TREB.
|
|
3
|
-
*
|
|
4
|
-
* TREB is free software: you can redistribute it and/or modify it under the
|
|
5
|
-
* terms of the GNU General Public License as published by the Free Software
|
|
6
|
-
* Foundation, either version 3 of the License, or (at your option) any
|
|
7
|
-
* later version.
|
|
8
|
-
*
|
|
9
|
-
* TREB is distributed in the hope that it will be useful, but WITHOUT ANY
|
|
10
|
-
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
|
11
|
-
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
|
12
|
-
* details.
|
|
13
|
-
*
|
|
14
|
-
* You should have received a copy of the GNU General Public License along
|
|
15
|
-
* with TREB. If not, see <https://www.gnu.org/licenses/>.
|
|
16
|
-
*
|
|
17
|
-
* Copyright 2022-2023 trebco, llc.
|
|
18
|
-
* info@treb.app
|
|
19
|
-
*
|
|
20
|
-
*/
|
|
21
|
-
|
|
1
|
+
/*
|
|
2
|
+
* This file is part of TREB.
|
|
3
|
+
*
|
|
4
|
+
* TREB is free software: you can redistribute it and/or modify it under the
|
|
5
|
+
* terms of the GNU General Public License as published by the Free Software
|
|
6
|
+
* Foundation, either version 3 of the License, or (at your option) any
|
|
7
|
+
* later version.
|
|
8
|
+
*
|
|
9
|
+
* TREB is distributed in the hope that it will be useful, but WITHOUT ANY
|
|
10
|
+
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
|
11
|
+
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
|
12
|
+
* details.
|
|
13
|
+
*
|
|
14
|
+
* You should have received a copy of the GNU General Public License along
|
|
15
|
+
* with TREB. If not, see <https://www.gnu.org/licenses/>.
|
|
16
|
+
*
|
|
17
|
+
* Copyright 2022-2023 trebco, llc.
|
|
18
|
+
* info@treb.app
|
|
19
|
+
*
|
|
20
|
+
*/
|
|
21
|
+
|
|
22
22
|
import type { Style } from './style';
|
|
23
23
|
import type { ValueType } from './value-type';
|
|
24
24
|
import type { IArea } from './area';
|
|
25
25
|
import type { AnnotationLayout } from './layout';
|
|
26
26
|
import type { DataValidation } from './cell';
|
|
27
27
|
import type { Table } from './table';
|
|
28
|
+
import type { AnnotationType } from 'treb-grid';
|
|
28
29
|
|
|
29
30
|
export interface CellParseResult {
|
|
30
31
|
row: number,
|
|
@@ -43,7 +44,7 @@ export interface CellParseResult {
|
|
|
43
44
|
|
|
44
45
|
export interface AnchoredAnnotation {
|
|
45
46
|
layout: AnnotationLayout;
|
|
46
|
-
type?:
|
|
47
|
+
type?: AnnotationType;
|
|
47
48
|
formula?: string;
|
|
48
49
|
}
|
|
49
50
|
|
|
@@ -528,17 +528,6 @@ export const LoadThemeProperties = (container: HTMLElement): Theme => {
|
|
|
528
528
|
theme.offset_light = css.color;
|
|
529
529
|
}
|
|
530
530
|
|
|
531
|
-
/*
|
|
532
|
-
css = CSS('grid-background');
|
|
533
|
-
if (css.backgroundImage) {
|
|
534
|
-
const match = css.backgroundImage.match(/url\("*(.*?)"*\)/);
|
|
535
|
-
if (match) {
|
|
536
|
-
theme.background_image = new Image();
|
|
537
|
-
theme.background_image.src = match[1];
|
|
538
|
-
}
|
|
539
|
-
}
|
|
540
|
-
*/
|
|
541
|
-
|
|
542
531
|
// this _is_ painted, but it doesn't necessarily need to be -- we
|
|
543
532
|
// could use a node. that would require moving it around, though.
|
|
544
533
|
// let's leave it for now.
|
|
@@ -1774,13 +1774,13 @@ export class Calculator extends Graph {
|
|
|
1774
1774
|
}
|
|
1775
1775
|
|
|
1776
1776
|
for (const entry of list) {
|
|
1777
|
-
if (entry.formula) {
|
|
1777
|
+
if (entry.data.formula) {
|
|
1778
1778
|
if (!entry.temp.vertex) {
|
|
1779
1779
|
entry.temp.vertex = new LeafVertex();
|
|
1780
1780
|
}
|
|
1781
1781
|
const vertex = entry.temp.vertex as LeafVertex;
|
|
1782
1782
|
this.AddLeafVertex(vertex);
|
|
1783
|
-
this.UpdateLeafVertex(vertex, entry.formula, context);
|
|
1783
|
+
this.UpdateLeafVertex(vertex, entry.data.formula, context);
|
|
1784
1784
|
}
|
|
1785
1785
|
}
|
|
1786
1786
|
|
|
@@ -208,6 +208,10 @@ export class SpreadsheetConstructor {
|
|
|
208
208
|
case 'data-treb':
|
|
209
209
|
continue;
|
|
210
210
|
|
|
211
|
+
// has special handling as an attribute
|
|
212
|
+
case 'inline-document':
|
|
213
|
+
continue;
|
|
214
|
+
|
|
211
215
|
// special case
|
|
212
216
|
case 'src':
|
|
213
217
|
attribute_options.document = this.root.getAttribute('src') || undefined;
|
|
@@ -255,6 +259,49 @@ export class SpreadsheetConstructor {
|
|
|
255
259
|
}
|
|
256
260
|
}
|
|
257
261
|
|
|
262
|
+
// inline-document means look in the tag contents for a script
|
|
263
|
+
// element, and use that. the script must have type "application/json",
|
|
264
|
+
// and if it has a name, the name must match the value of the
|
|
265
|
+
// inline-document attribute.
|
|
266
|
+
//
|
|
267
|
+
// so either
|
|
268
|
+
//
|
|
269
|
+
// <treb-spreadsheet inline-document>
|
|
270
|
+
// <script type="application/json">{ ... }</script>
|
|
271
|
+
// </treb-spreadsheet>
|
|
272
|
+
//
|
|
273
|
+
// or
|
|
274
|
+
//
|
|
275
|
+
// <treb-spreadsheet inline-document="xyz">
|
|
276
|
+
// <script type="application/json" name="xyz">{ ... }</script>
|
|
277
|
+
// </treb-spreadsheet>
|
|
278
|
+
|
|
279
|
+
if (this.root.hasAttribute('inline-document')) {
|
|
280
|
+
const inline_name = this.root.getAttribute('inline-document') || '';
|
|
281
|
+
for (const element of Array.from(this.root.children)) {
|
|
282
|
+
if (element instanceof HTMLScriptElement) {
|
|
283
|
+
if (element.type === 'application/json') {
|
|
284
|
+
const name = element.getAttribute('name') || '';
|
|
285
|
+
if (name === inline_name) {
|
|
286
|
+
const content = element.textContent;
|
|
287
|
+
if (content) {
|
|
288
|
+
try {
|
|
289
|
+
options.inline_document = JSON.parse(content);
|
|
290
|
+
}
|
|
291
|
+
catch (err) {
|
|
292
|
+
console.error(err);
|
|
293
|
+
}
|
|
294
|
+
}
|
|
295
|
+
break;
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
if (!options.inline_document) {
|
|
301
|
+
console.warn('inline document failed');
|
|
302
|
+
}
|
|
303
|
+
}
|
|
304
|
+
|
|
258
305
|
this.root.innerHTML = html;
|
|
259
306
|
options.container = this.root.querySelector('.treb-layout-spreadsheet') as HTMLElement;
|
|
260
307
|
|
|
@@ -29,7 +29,8 @@ import type {
|
|
|
29
29
|
SerializedModel, FreezePane, SerializedSheet,
|
|
30
30
|
SheetChangeEvent, GridOptions,
|
|
31
31
|
GridSelection, CellEvent, FunctionDescriptor,
|
|
32
|
-
AnnotationViewData,
|
|
32
|
+
AnnotationViewData,
|
|
33
|
+
AnnotationType,
|
|
33
34
|
} from 'treb-grid';
|
|
34
35
|
|
|
35
36
|
import {
|
|
@@ -506,11 +507,15 @@ export class EmbeddedSpreadsheet {
|
|
|
506
507
|
}
|
|
507
508
|
}
|
|
508
509
|
|
|
510
|
+
if (this.options.document && this.options.inline_document) {
|
|
511
|
+
console.warn('both document and inline-document are provided');
|
|
512
|
+
}
|
|
513
|
+
|
|
509
514
|
const network_document = this.options.document;
|
|
510
515
|
|
|
511
516
|
// optionally data from storage, with fallback
|
|
512
517
|
|
|
513
|
-
let data: string | undefined;
|
|
518
|
+
let data: string | undefined | TREBDocument;
|
|
514
519
|
let source: LoadSource | undefined;
|
|
515
520
|
|
|
516
521
|
// don't load if we're a split view. we can also skip the
|
|
@@ -523,6 +528,14 @@ export class EmbeddedSpreadsheet {
|
|
|
523
528
|
}
|
|
524
529
|
}
|
|
525
530
|
|
|
531
|
+
// if we have an inline document, and there was nothing in local storage,
|
|
532
|
+
// load the inline document now. not for splits.
|
|
533
|
+
|
|
534
|
+
if (!data && !this.options.toll_initial_load && !options.model && options.inline_document) {
|
|
535
|
+
data = options.inline_document;
|
|
536
|
+
source = LoadSource.INLINE_DOCUMENT;
|
|
537
|
+
}
|
|
538
|
+
|
|
526
539
|
// this one should not be done for a split view, but we should still
|
|
527
540
|
// do it if the toll flag is set, and storage key is set.
|
|
528
541
|
|
|
@@ -858,8 +871,12 @@ export class EmbeddedSpreadsheet {
|
|
|
858
871
|
// FIXME: this should yield so we can subscribe to events before the initial load
|
|
859
872
|
|
|
860
873
|
if (data) {
|
|
861
|
-
|
|
862
|
-
|
|
874
|
+
if (typeof data === 'string') {
|
|
875
|
+
data = JSON.parse(data);
|
|
876
|
+
}
|
|
877
|
+
if (data) {
|
|
878
|
+
this.LoadDocument(data as TREBDocument, { recalculate: !!this.options.recalculate, source});
|
|
879
|
+
}
|
|
863
880
|
}
|
|
864
881
|
else if (!network_document) {
|
|
865
882
|
|
|
@@ -1875,7 +1892,7 @@ export class EmbeddedSpreadsheet {
|
|
|
1875
1892
|
* @param argument_separator - the argument separator to use when evaluating
|
|
1876
1893
|
* the function. defaults to current locale.
|
|
1877
1894
|
*/
|
|
1878
|
-
public InsertAnnotation(formula: string, type = 'treb-chart', rect?: IRectangle|RangeReference, argument_separator?: ','|';'): void {
|
|
1895
|
+
public InsertAnnotation(formula: string, type: AnnotationType = 'treb-chart', rect?: IRectangle|RangeReference, argument_separator?: ','|';'): void {
|
|
1879
1896
|
|
|
1880
1897
|
let target: IRectangle | Partial<Area> | undefined;
|
|
1881
1898
|
|
|
@@ -2307,6 +2324,15 @@ export class EmbeddedSpreadsheet {
|
|
|
2307
2324
|
*/
|
|
2308
2325
|
public Revert(): void {
|
|
2309
2326
|
|
|
2327
|
+
if (this.options.inline_document) {
|
|
2328
|
+
this.LoadDocument(this.options.inline_document);
|
|
2329
|
+
if (this.options.storage_key) {
|
|
2330
|
+
this.SaveLocalStorage('reverted_backup');
|
|
2331
|
+
localStorage.removeItem(this.options.storage_key);
|
|
2332
|
+
}
|
|
2333
|
+
return;
|
|
2334
|
+
}
|
|
2335
|
+
|
|
2310
2336
|
const canonical = this.options.document;
|
|
2311
2337
|
|
|
2312
2338
|
if (canonical) {
|
|
@@ -3146,7 +3172,7 @@ export class EmbeddedSpreadsheet {
|
|
|
3146
3172
|
}
|
|
3147
3173
|
|
|
3148
3174
|
for (const annotation of sheet.annotations || []) {
|
|
3149
|
-
if (annotation.type === 'image' && annotation.data
|
|
3175
|
+
if (annotation.type === 'image' && annotation.data?.src) {
|
|
3150
3176
|
annotation.data.src = Store(annotation.data.src);
|
|
3151
3177
|
}
|
|
3152
3178
|
}
|
|
@@ -4325,15 +4351,20 @@ export class EmbeddedSpreadsheet {
|
|
|
4325
4351
|
const annotation = this.grid.CreateAnnotation({
|
|
4326
4352
|
type: 'image',
|
|
4327
4353
|
formula: '',
|
|
4354
|
+
data: {
|
|
4355
|
+
scale: '',
|
|
4356
|
+
src: contents,
|
|
4357
|
+
original_size: { width: img.width || 300, height: img.height || 300 },
|
|
4358
|
+
},
|
|
4328
4359
|
}, undefined, undefined, {
|
|
4329
4360
|
top: 30,
|
|
4330
4361
|
left: 30,
|
|
4331
4362
|
width: img.width || 300,
|
|
4332
|
-
height: img.height || 300
|
|
4363
|
+
height: img.height || 300,
|
|
4333
4364
|
});
|
|
4334
4365
|
|
|
4335
|
-
annotation.data.src = contents;
|
|
4336
|
-
annotation.data.original_size = { width: img.width || 300, height: img.height || 300 };
|
|
4366
|
+
// annotation.data.src = contents;
|
|
4367
|
+
// annotation.data.original_size = { width: img.width || 300, height: img.height || 300 };
|
|
4337
4368
|
|
|
4338
4369
|
}
|
|
4339
4370
|
|
|
@@ -4588,9 +4619,12 @@ export class EmbeddedSpreadsheet {
|
|
|
4588
4619
|
annotation.dirty = false;
|
|
4589
4620
|
}
|
|
4590
4621
|
|
|
4591
|
-
|
|
4622
|
+
// why was this testing for data? that would always exist on an annotation
|
|
4623
|
+
// instance (but not in our new data type). maybe some legacy thing?
|
|
4592
4624
|
|
|
4593
|
-
|
|
4625
|
+
if (view.content_node ) { // && annotation.annotation_data.data) {
|
|
4626
|
+
|
|
4627
|
+
if (annotation.data.type === 'treb-chart') {
|
|
4594
4628
|
|
|
4595
4629
|
// if (!(self as any).TREB || !(self as any).TREB.CreateChart2) {
|
|
4596
4630
|
// console.warn('missing chart library');
|
|
@@ -4608,8 +4642,8 @@ export class EmbeddedSpreadsheet {
|
|
|
4608
4642
|
|
|
4609
4643
|
const update_chart = () => {
|
|
4610
4644
|
|
|
4611
|
-
if (annotation.formula) {
|
|
4612
|
-
const parse_result = this.parser.Parse(annotation.formula);
|
|
4645
|
+
if (annotation.data.formula) {
|
|
4646
|
+
const parse_result = this.parser.Parse(annotation.data.formula);
|
|
4613
4647
|
if (parse_result &&
|
|
4614
4648
|
parse_result.expression &&
|
|
4615
4649
|
parse_result.expression.type === 'call') {
|
|
@@ -4661,16 +4695,16 @@ export class EmbeddedSpreadsheet {
|
|
|
4661
4695
|
}
|
|
4662
4696
|
|
|
4663
4697
|
}
|
|
4664
|
-
else if (annotation.type === 'image') {
|
|
4665
|
-
if (typeof annotation.data.src === 'string') {
|
|
4698
|
+
else if (annotation.data.type === 'image') {
|
|
4699
|
+
if (typeof annotation.data.data?.src === 'string') {
|
|
4666
4700
|
|
|
4667
|
-
const reference = ValidateURI(annotation.data.src);
|
|
4701
|
+
const reference = ValidateURI(annotation.data.data.src);
|
|
4668
4702
|
if (reference) {
|
|
4669
4703
|
|
|
4670
4704
|
const img = document.createElement('img');
|
|
4671
4705
|
img.src = reference;
|
|
4672
4706
|
|
|
4673
|
-
if (annotation.data.scale === 'fixed') {
|
|
4707
|
+
if (annotation.data.data.scale === 'fixed') {
|
|
4674
4708
|
img.style.position = 'relative';
|
|
4675
4709
|
img.style.left = '50%';
|
|
4676
4710
|
img.style.top = '50%';
|
|
@@ -5019,7 +5053,7 @@ export class EmbeddedSpreadsheet {
|
|
|
5019
5053
|
for (const sheet_data of sheets) {
|
|
5020
5054
|
|
|
5021
5055
|
if (sheet_data.annotations) {
|
|
5022
|
-
for (const annotation of (sheet_data.annotations
|
|
5056
|
+
for (const annotation of (sheet_data.annotations)) {
|
|
5023
5057
|
if (annotation.formula) {
|
|
5024
5058
|
const translated = translate(annotation.formula);
|
|
5025
5059
|
if (translated) {
|
|
@@ -5136,7 +5170,7 @@ export class EmbeddedSpreadsheet {
|
|
|
5136
5170
|
sheet.background_image = Unshare(sheet.background_image);
|
|
5137
5171
|
}
|
|
5138
5172
|
for (const annotation of sheet.annotations || []) {
|
|
5139
|
-
if (annotation.type === 'image' && annotation.data
|
|
5173
|
+
if (annotation.type === 'image' && annotation.data?.src) {
|
|
5140
5174
|
annotation.data.src = Unshare(annotation.data.src);
|
|
5141
5175
|
}
|
|
5142
5176
|
}
|
|
@@ -20,6 +20,7 @@
|
|
|
20
20
|
*/
|
|
21
21
|
|
|
22
22
|
import type { ICellAddress } from 'treb-base-types';
|
|
23
|
+
import type { TREBDocument } from './types';
|
|
23
24
|
|
|
24
25
|
/**
|
|
25
26
|
* options for exporting CSV/TSV
|
|
@@ -97,6 +98,16 @@ export interface EmbeddedSpreadsheetOptions {
|
|
|
97
98
|
*/
|
|
98
99
|
document?: string;
|
|
99
100
|
|
|
101
|
+
/**
|
|
102
|
+
* @internal - testing
|
|
103
|
+
*
|
|
104
|
+
* load document directly from data. obeys the same rules as `document`
|
|
105
|
+
* regarding local storage and revert. if you provide both document and
|
|
106
|
+
* inline_document we will show a warning, but inline_document will take
|
|
107
|
+
* precedence.
|
|
108
|
+
*/
|
|
109
|
+
inline_document?: TREBDocument;
|
|
110
|
+
|
|
100
111
|
/**
|
|
101
112
|
* fetch network document (URI)
|
|
102
113
|
* @deprecated - use `document`
|
package/treb-embed/src/types.ts
CHANGED
|
@@ -182,9 +182,14 @@ $text-reference-color-5: rgb(254, 47, 1);
|
|
|
182
182
|
background: var(--treb-grid-background, #fff);
|
|
183
183
|
}
|
|
184
184
|
|
|
185
|
+
/*
|
|
186
|
+
* we stopped using this in favor of sheet backgrounds. although
|
|
187
|
+
* there's a case to be made for the static background as well.
|
|
188
|
+
*
|
|
185
189
|
.grid-background {
|
|
186
190
|
background-image: var(--treb-grid-background-image, none);
|
|
187
191
|
}
|
|
192
|
+
*/
|
|
188
193
|
|
|
189
194
|
/**
|
|
190
195
|
* this is used for freeze-area highlights
|
|
@@ -35,7 +35,7 @@ import { template } from './template-2';
|
|
|
35
35
|
import type { SerializedSheet } from 'treb-grid';
|
|
36
36
|
|
|
37
37
|
import type { IArea, ICellAddress, CellValue, DataValidation,
|
|
38
|
-
AnnotationLayout, Corner as LayoutCorner, Cell } from 'treb-base-types';
|
|
38
|
+
AnnotationLayout, Corner as LayoutCorner, Cell, Rectangle } from 'treb-base-types';
|
|
39
39
|
import { Area, Cells, ValueType, Style, ValidationType } from 'treb-base-types';
|
|
40
40
|
|
|
41
41
|
// import * as xmlparser from 'fast-xml-parser';
|
|
@@ -61,6 +61,7 @@ import type { ImageOptions } from './drawing2/embedded-image';
|
|
|
61
61
|
import type { TwoCellAnchor } from './drawing2/drawing2';
|
|
62
62
|
import { Drawing } from './drawing2/drawing2';
|
|
63
63
|
import type { TableDescription, TableFooterType } from './workbook2';
|
|
64
|
+
import type { AnnotationData } from 'treb-grid/src/types/annotation';
|
|
64
65
|
|
|
65
66
|
export class Exporter {
|
|
66
67
|
|
|
@@ -651,12 +652,7 @@ export class Exporter {
|
|
|
651
652
|
* the target units are.
|
|
652
653
|
*/
|
|
653
654
|
public AnnotationRectToAnchor(
|
|
654
|
-
|
|
655
|
-
left: number;
|
|
656
|
-
top: number;
|
|
657
|
-
width: number;
|
|
658
|
-
height: number;
|
|
659
|
-
},
|
|
655
|
+
src_rect: Partial<Rectangle>,
|
|
660
656
|
sheet: SerializedSheet): TwoCellAnchor {
|
|
661
657
|
|
|
662
658
|
const anchor: TwoCellAnchor = {
|
|
@@ -664,6 +660,11 @@ export class Exporter {
|
|
|
664
660
|
to: {row: -1, column: -1},
|
|
665
661
|
};
|
|
666
662
|
|
|
663
|
+
const annotation_rect = {
|
|
664
|
+
top: 0, left: 0, width: 301, height: 301,
|
|
665
|
+
...src_rect,
|
|
666
|
+
};
|
|
667
|
+
|
|
667
668
|
const rect = {
|
|
668
669
|
...annotation_rect, // {top, left, width, height}
|
|
669
670
|
right: annotation_rect.left + annotation_rect.width,
|
|
@@ -706,7 +707,7 @@ export class Exporter {
|
|
|
706
707
|
|
|
707
708
|
const images: Array<{ anchor: TwoCellAnchor, options: ImageOptions }> = [];
|
|
708
709
|
|
|
709
|
-
for (const annotation of sheet_source.annotations || []) {
|
|
710
|
+
for (const annotation of (sheet_source.annotations as Array<AnnotationData & {rect?: Partial<Rectangle>}>) || []) {
|
|
710
711
|
if (annotation.type === 'image' && annotation.data?.src) {
|
|
711
712
|
|
|
712
713
|
// this is (should be) a data URI in base64. at least (atm)
|
|
@@ -940,9 +941,14 @@ export class Exporter {
|
|
|
940
941
|
}
|
|
941
942
|
}
|
|
942
943
|
|
|
943
|
-
|
|
944
|
+
// FIXME: fix this type (this happened when we switched from annotation
|
|
945
|
+
// class to a data interface)
|
|
946
|
+
|
|
947
|
+
const rect = (annotation as AnnotationData & { rect?: Partial<Rectangle>}).rect;
|
|
948
|
+
|
|
949
|
+
if (rect) {
|
|
944
950
|
charts.push({
|
|
945
|
-
anchor: this.AnnotationRectToAnchor(
|
|
951
|
+
anchor: this.AnnotationRectToAnchor(rect, sheet_source), options});
|
|
946
952
|
// sheet.AddChart(this.AnnotationRectToAnchor(annotation.rect, sheet_source), options);
|
|
947
953
|
}
|
|
948
954
|
else if (annotation.layout) {
|
|
@@ -37,6 +37,7 @@ import { XMLUtils } from './xml-utils';
|
|
|
37
37
|
|
|
38
38
|
// import { one_hundred_pixels } from './constants';
|
|
39
39
|
import { ColumnWidthToPixels } from './column-width';
|
|
40
|
+
import type { AnnotationType } from 'treb-grid';
|
|
40
41
|
|
|
41
42
|
interface SharedFormula {
|
|
42
43
|
row: number;
|
|
@@ -697,7 +698,7 @@ export class Importer {
|
|
|
697
698
|
br: AnchorToCorner(descriptor.anchor.to),
|
|
698
699
|
};
|
|
699
700
|
|
|
700
|
-
let type:
|
|
701
|
+
let type: AnnotationType|undefined;
|
|
701
702
|
const args: Array<string|undefined> = [];
|
|
702
703
|
let func = '';
|
|
703
704
|
const series = descriptor.chart?.series;
|
package/treb-grid/src/index.ts
CHANGED
|
@@ -37,4 +37,5 @@ export { BorderConstants } from './types/border_constants';
|
|
|
37
37
|
export type { SerializeOptions } from './types/serialize_options';
|
|
38
38
|
export type { FunctionDescriptor, ArgumentDescriptor } from './editors/autocomplete_matcher';
|
|
39
39
|
export { UA } from './util/ua';
|
|
40
|
-
export type { SetRangeOptions } from './types/set_range_options';
|
|
40
|
+
export type { SetRangeOptions } from './types/set_range_options';
|
|
41
|
+
export type { AnnotationData, AnnotationType } from './types/annotation';
|
|
@@ -672,21 +672,21 @@ export abstract class BaseLayout {
|
|
|
672
672
|
// be persisted (assuming it's saved). eventually this should
|
|
673
673
|
// be superfluous...
|
|
674
674
|
|
|
675
|
-
if (annotation.rect && !annotation.layout) {
|
|
675
|
+
if (annotation.rect && !annotation.data.layout) {
|
|
676
676
|
|
|
677
677
|
// this is breaking on freeze when the spreadsheet is scrolled because
|
|
678
678
|
// the top-left uses the freeze panes. stop doing that.
|
|
679
679
|
|
|
680
680
|
annotation.scaled_rect = annotation.rect.Scale(this.scale);
|
|
681
|
-
annotation.layout = this.RectToAnnotationLayout(annotation.scaled_rect);
|
|
681
|
+
annotation.data.layout = this.RectToAnnotationLayout(annotation.scaled_rect);
|
|
682
682
|
}
|
|
683
683
|
|
|
684
684
|
|
|
685
685
|
// FIXME: merge cells? [...]
|
|
686
686
|
|
|
687
|
-
if (annotation.layout) {
|
|
687
|
+
if (annotation.data.layout) {
|
|
688
688
|
|
|
689
|
-
const rect = this.AnnotationLayoutToRect(annotation.layout);
|
|
689
|
+
const rect = this.AnnotationLayoutToRect(annotation.data.layout);
|
|
690
690
|
rect.ApplyStyle(view.node);
|
|
691
691
|
|
|
692
692
|
// NOTE: we still set the scaled rect, because that's used in
|
|
@@ -949,9 +949,9 @@ export abstract class BaseLayout {
|
|
|
949
949
|
}
|
|
950
950
|
|
|
951
951
|
}, () => {
|
|
952
|
-
annotation.extent = undefined; // reset
|
|
952
|
+
annotation.data.extent = undefined; // reset
|
|
953
953
|
// annotation.rect = rect.Scale(1/this.scale);
|
|
954
|
-
annotation.layout = this.RectToAnnotationLayout(rect);
|
|
954
|
+
annotation.data.layout = this.RectToAnnotationLayout(rect);
|
|
955
955
|
// this.grid_events.Publish({ type: 'annotation', annotation, event: 'move' });
|
|
956
956
|
resolve({ type: 'annotation', annotation, event: 'move' })
|
|
957
957
|
});
|
|
@@ -969,11 +969,14 @@ export abstract class BaseLayout {
|
|
|
969
969
|
node.focus();
|
|
970
970
|
|
|
971
971
|
let aspect = 0;
|
|
972
|
-
if (annotation.data
|
|
973
|
-
|
|
974
|
-
|
|
975
|
-
|
|
976
|
-
annotation.data.original_size.height
|
|
972
|
+
if (annotation.data.type === 'image') {
|
|
973
|
+
if (annotation.data.data
|
|
974
|
+
&& annotation.data.data.original_size
|
|
975
|
+
&& annotation.data.data.original_size.width
|
|
976
|
+
&& annotation.data.data.original_size.height) {
|
|
977
|
+
aspect = annotation.data.data.original_size.width /
|
|
978
|
+
annotation.data.data.original_size.height;
|
|
979
|
+
}
|
|
977
980
|
}
|
|
978
981
|
|
|
979
982
|
const bounds = node.getBoundingClientRect();
|
|
@@ -1029,9 +1032,9 @@ export abstract class BaseLayout {
|
|
|
1029
1032
|
}
|
|
1030
1033
|
|
|
1031
1034
|
}, () => {
|
|
1032
|
-
annotation.extent = undefined; // reset
|
|
1035
|
+
annotation.data.extent = undefined; // reset
|
|
1033
1036
|
// annotation.rect = rect.Scale(1/this.scale);
|
|
1034
|
-
annotation.layout = this.RectToAnnotationLayout(rect);
|
|
1037
|
+
annotation.data.layout = this.RectToAnnotationLayout(rect);
|
|
1035
1038
|
|
|
1036
1039
|
// this.grid_events.Publish({ type: 'annotation', annotation, event: 'resize' });
|
|
1037
1040
|
resolve({ type: 'annotation', annotation, event: 'resize' });
|