@trebco/treb 25.7.7 → 25.9.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.
package/dist/treb.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- /*! API v25.7. Copyright 2018-2023 trebco, llc. All rights reserved. LGPL: https://treb.app/license */
1
+ /*! API v25.9. 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
package/esbuild-utils.mjs CHANGED
@@ -81,17 +81,25 @@ export const FormatSize = (size, precision = 1) => {
81
81
  *
82
82
  * if you import a worker script like this
83
83
  * ```
84
- * import worker_script from 'worker://path/to/worker.ts';
84
+ * import * as worker_script from 'worker:path/to/worker';
85
85
  * ```
86
86
  * the plugin will compile the target (with esbuild) and then return the
87
87
  * compiled script as a string. the child build inherits minify settings
88
88
  * from the parent build.
89
89
  *
90
+ * note the `import *` syntax; we can't just import the script, because
91
+ * tsc will complain about a missing default export (and you can't have
92
+ * a default export, or it will break when it runs).
93
+ *
90
94
  * you can then use it in the containing script by creating a worker:
91
95
  * ```
92
- * const worker = new Worker(URL.createObjectURL(new Blob([worker_script], { type: 'application/javascript' })));
96
+ * const worker = new Worker(URL.createObjectURL(new Blob([(worker_script as any).default], { type: 'application/javascript' })));
93
97
  * ```
94
98
  *
99
+ * here we have to use `any`, for the time being, because when tsc reads
100
+ * this it will note (correctly) that there's no default. but for our
101
+ * esbuild import, we will have a default string.
102
+ *
95
103
  * this might cause problems with CSP. if so, we'll sort that out separately.
96
104
  *
97
105
  */
@@ -99,8 +107,8 @@ export const WorkerPlugin = (options) => ({
99
107
  name: 'worker',
100
108
  setup(build) {
101
109
 
102
- build.onResolve({ filter: /^worker:\/\//}, async (args) => {
103
- args.path = args.path.substring(9);
110
+ build.onResolve({ filter: /^worker:/}, async (args) => {
111
+ args.path = args.path.substring(7);
104
112
  const result = await build.resolve(args.path, {
105
113
  kind: args.kind,
106
114
  resolveDir: args.resolveDir,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@trebco/treb",
3
- "version": "25.7.7",
3
+ "version": "25.9.1",
4
4
  "license": "LGPL-3.0-or-later",
5
5
  "homepage": "https://treb.app",
6
6
  "repository": {
@@ -26,6 +26,7 @@
26
26
  "treb-base-types": "file:treb-base-types",
27
27
  "treb-calculator": "file:treb-calculator",
28
28
  "treb-charts": "file:treb-charts",
29
+ "treb-export": "file:treb-export",
29
30
  "treb-format": "file:treb-format",
30
31
  "treb-grid": "file:treb-grid",
31
32
  "treb-parser": "file:treb-parser",
@@ -6,6 +6,7 @@
6
6
  "../treb-utils/**/*.ts",
7
7
  "../treb-grid/**/*.ts",
8
8
  "../treb-charts/**/*.ts",
9
+ "../treb-export/**/*.ts",
9
10
  "../treb-format/**/*.ts",
10
11
  "../treb-parser/**/*.ts",
11
12
  "../treb-calculator/**/*.ts",
@@ -75,17 +75,11 @@ import type { SetRangeOptions } from 'treb-grid';
75
75
  // --- worker ------------------------------------------------------------------
76
76
 
77
77
  /**
78
- * note the clumsy URI-like syntax. if typescript can see that the thing
79
- * is a ts file, even if we have a prefix and a type defined for that
80
- * prefix, it will still try to read it.
81
- *
82
- * this is not a great solution. I was thinking about letting ts read it.
83
- * That won't impact esbuild, and it has the helpful side effect of type
84
- * checking the worker when we run tsc. but it doesn't like the .ts extension.
85
- * also it actually tries to import the file, which means you have to export
86
- * some junk value.
78
+ * import the worker as a script file. tsc will read this on typecheck but
79
+ * that's actually to the good; when we build with esbuild we will inline
80
+ * the script so we can run it as a worker.
87
81
  */
88
- import export_worker_script from 'worker://../../treb-export/src/export-worker/index-modern.ts';
82
+ import * as export_worker_script from 'worker:../../treb-export/src/export-worker/index.worker';
89
83
 
90
84
  // --- types -------------------------------------------------------------------
91
85
 
@@ -653,7 +647,11 @@ export class EmbeddedSpreadsheet {
653
647
  //this.extra_calculator = //new Calculator(this.model);
654
648
  // this.CreateCalculator(this.model);
655
649
 
656
- this.grid = new Grid(grid_options, this.parser, this.model);
650
+ // update: tell the grid if we don't want to initialize the DOM,
651
+ // if we don't have a container. that's distinct (at the moment)
652
+ // from headless, which is a state that can change.
653
+
654
+ this.grid = new Grid(grid_options, this.parser, this.model, undefined, !!container);
657
655
 
658
656
  if (this.options.headless) {
659
657
  this.grid.headless = true; // FIXME: move into grid options
@@ -870,9 +868,9 @@ export class EmbeddedSpreadsheet {
870
868
  else {
871
869
  if (!EmbeddedSpreadsheet.one_time_warnings.headless) {
872
870
  EmbeddedSpreadsheet.one_time_warnings.headless = true;
873
- console.info('not initializing grid; don\'t call UI functions');
871
+ console.info('not initializing layout; don\'t call UI functions');
874
872
  }
875
- this.grid.headless = true; // ensure
873
+ // this.grid.headless = true; // ensure
876
874
  }
877
875
 
878
876
  // moved up so we can share parser w/ grid
@@ -2809,7 +2807,7 @@ export class EmbeddedSpreadsheet {
2809
2807
  }
2810
2808
 
2811
2809
  if (text && filename) {
2812
- const blob = new Blob([text], { type: 'text/plain;charset=utf-8' });
2810
+ const blob = new Blob([text as any], { type: 'text/plain;charset=utf-8' });
2813
2811
  /*
2814
2812
  // FileSaver.saveAs(blob, filename, { autoBom: false });
2815
2813
  const a = document.createElement('a');
@@ -5323,7 +5321,7 @@ export class EmbeddedSpreadsheet {
5323
5321
  if (export_worker_script) {
5324
5322
  try {
5325
5323
  const worker = new Worker(
5326
- URL.createObjectURL(new Blob([export_worker_script], { type: 'application/javascript' })));
5324
+ URL.createObjectURL(new Blob([(export_worker_script as any).default], { type: 'application/javascript' })));
5327
5325
  return worker;
5328
5326
  }
5329
5327
  catch (err) {
@@ -21,3 +21,12 @@
21
21
 
22
22
  import './export-worker';
23
23
 
24
+ /**
25
+ * default export so tsc will allow us to import it. we use a string
26
+ * because when actually running (via the esbuild build) it will be
27
+ * the code as text. HOWEVER, this will break if we actually try to
28
+ * run it in a browser, so we need to clean it up in the compiler.
29
+ */
30
+ // export default '';
31
+
32
+
@@ -122,7 +122,7 @@ export abstract class BaseLayout {
122
122
  * an event we can trap for that. it might be necessary to test this
123
123
  * periodically.
124
124
  */
125
- public dpr = Math.max(1, self.devicePixelRatio || 1);
125
+ public dpr = 1; // Math.max(1, self.devicePixelRatio || 1);
126
126
 
127
127
  /** separate scale, user-controlled (testing...) */
128
128
  public scale = 1;
@@ -151,7 +151,7 @@ export abstract class BaseLayout {
151
151
  this.scroll_reference_node.scrollTop = offset.y;
152
152
  }
153
153
 
154
- protected dropdown_caret: SVGSVGElement;
154
+ protected dropdown_caret!: SVGSVGElement;
155
155
 
156
156
  /** we have to disable mock selection for IE or it breaks key handling */
157
157
  private trident = ((typeof navigator !== 'undefined') &&
@@ -162,9 +162,9 @@ export abstract class BaseLayout {
162
162
 
163
163
  private tooltip_state?: 'up' | 'left';
164
164
 
165
- private tooltip: HTMLDivElement;
165
+ private tooltip!: HTMLDivElement;
166
166
 
167
- private dropdown_list: HTMLDivElement;
167
+ private dropdown_list!: HTMLDivElement;
168
168
  private dropdown_caret_visible = false;
169
169
  private dropdown_callback?: (value: CellValue) => void;
170
170
  private dropdown_selected?: HTMLElement;
@@ -174,10 +174,9 @@ export abstract class BaseLayout {
174
174
  // private error_highlight: HTMLDivElement;
175
175
  // private error_highlight_timeout?: any;
176
176
 
177
- private note_node: HTMLDivElement;
178
- private sort_button: HTMLButtonElement;
179
-
180
- private title_node: HTMLDivElement;
177
+ private note_node!: HTMLDivElement;
178
+ private sort_button!: HTMLButtonElement;
179
+ private title_node!: HTMLDivElement;
181
180
 
182
181
  private row_cache: number[] = [];
183
182
  private column_cache: number[] = [];
@@ -188,7 +187,13 @@ export abstract class BaseLayout {
188
187
  private initialized = false;
189
188
 
190
189
 
191
- constructor(protected model: DataModel, protected view: ViewModel) {
190
+ constructor(protected model: DataModel, protected view: ViewModel, mock = false) {
191
+
192
+ if (mock) {
193
+ return;
194
+ }
195
+
196
+ this.dpr = Math.max(1, self.devicePixelRatio || 1);
192
197
 
193
198
  // now attaching to node... no longer global
194
199
  // actually if we are not in a web component, we might as well
@@ -0,0 +1,33 @@
1
+
2
+ import type { DataModel, ViewModel } from '../types/data_model';
3
+ import type { Tile } from '../types/tile';
4
+ import { BaseLayout } from './base_layout';
5
+
6
+ export class MockLayout extends BaseLayout {
7
+
8
+ public constructor(model: DataModel, view: ViewModel) {
9
+ super(model, view, true);
10
+ }
11
+
12
+ public InitializeInternal(container: HTMLElement, scroll_callback: () => void): void {
13
+
14
+ }
15
+
16
+ protected UpdateGridTemplates(columns: boolean, rows: boolean): void {
17
+
18
+ }
19
+
20
+ protected UpdateTileGridPosition(tile: Tile): void {
21
+
22
+ }
23
+
24
+ protected UpdateContainingGrid(): void {
25
+
26
+ }
27
+
28
+ public ResizeCursor(resize?: 'row' | 'column' | undefined): void {
29
+
30
+ }
31
+
32
+ }
33
+
@@ -65,6 +65,7 @@ import { TabBar } from './tab_bar';
65
65
  import type { StatsEntry } from './tab_bar';
66
66
 
67
67
  import { Sheet } from './sheet';
68
+ import { MockLayout } from '../layout/mock-layout';
68
69
  import type { BaseLayout } from '../layout/base_layout';
69
70
  import { TileRange } from '../layout/base_layout';
70
71
 
@@ -328,10 +329,10 @@ export class Grid extends GridBase {
328
329
  private render_token = 0;
329
330
 
330
331
  /** */
331
- private tile_renderer: TileRenderer;
332
+ private tile_renderer?: TileRenderer;
332
333
 
333
334
  /** */
334
- private selection_renderer: SelectionRenderer;
335
+ private selection_renderer?: SelectionRenderer;
335
336
 
336
337
  // FIXME: move [why?]
337
338
 
@@ -346,7 +347,8 @@ export class Grid extends GridBase {
346
347
  options: GridOptions = {},
347
348
  parser: Parser,
348
349
  model: DataModel,
349
- theme: Theme = DefaultTheme) {
350
+ theme: Theme = DefaultTheme,
351
+ initialze_dom = true ) {
350
352
 
351
353
  super(options, parser, model);
352
354
 
@@ -356,6 +358,12 @@ export class Grid extends GridBase {
356
358
 
357
359
  this.theme = JSON.parse(JSON.stringify(theme));
358
360
 
361
+ if (!initialze_dom) {
362
+ this.headless = true;
363
+ this.layout = new MockLayout(this.model, this.view);
364
+ return;
365
+ }
366
+
359
367
  this.layout = new GridLayout(this.model, this.view);
360
368
 
361
369
  if (options.initial_scale) {
@@ -1226,6 +1234,10 @@ export class Grid extends GridBase {
1226
1234
  */
1227
1235
  public Initialize(view_node: HTMLElement, toll_initial_render = false): void {
1228
1236
 
1237
+ if (!this.tile_renderer || !this.selection_renderer) {
1238
+ return;
1239
+ }
1240
+
1229
1241
  // grid no longer has access to the outer container, it just has
1230
1242
  // the "view" container. so we need to move things like UA classes
1231
1243
  // outside of this class. we should move theme parsing as well, so
@@ -2125,6 +2137,10 @@ export class Grid extends GridBase {
2125
2137
 
2126
2138
  private AutoSizeColumn(sheet: Sheet, column: number, allow_shrink = true): void {
2127
2139
 
2140
+ if (!this.tile_renderer) {
2141
+ return;
2142
+ }
2143
+
2128
2144
  // const context = Sheet.measurement_canvas.getContext('2d');
2129
2145
  // if (!context) return;
2130
2146
 
@@ -2729,7 +2745,7 @@ export class Grid extends GridBase {
2729
2745
 
2730
2746
  private Repaint(force = false, full_tile = false, force_headers = false) {
2731
2747
 
2732
- if (this.headless) { return; }
2748
+ if (this.headless || !this.tile_renderer) { return; }
2733
2749
 
2734
2750
  if (this.tile_update_pending) {
2735
2751
  this.tile_update_pending = false;
@@ -3497,6 +3513,10 @@ export class Grid extends GridBase {
3497
3513
  event.stopPropagation();
3498
3514
  event.preventDefault();
3499
3515
 
3516
+ if (!this.selection_renderer) {
3517
+ return;
3518
+ }
3519
+
3500
3520
  // needed for legacy
3501
3521
 
3502
3522
  if (this.cell_resize.row >= 0 || this.cell_resize.column >= 0) {
@@ -4616,7 +4636,7 @@ export class Grid extends GridBase {
4616
4636
  const show_primary_selection = this.hide_selection ? false :
4617
4637
  (!this.editing_state) || (this.editing_cell.sheet_id === this.active_sheet.id);
4618
4638
 
4619
- this.selection_renderer.RenderSelections(show_primary_selection, rerender);
4639
+ this.selection_renderer?.RenderSelections(show_primary_selection, rerender);
4620
4640
  }
4621
4641
 
4622
4642
  /**
@@ -6876,7 +6896,7 @@ export class Grid extends GridBase {
6876
6896
  // columns. we should be able to fix this, or we can just flush
6877
6897
  // all overflows and force them to get recreated.
6878
6898
 
6879
- this.tile_renderer.FlushOverflows();
6899
+ this.tile_renderer?.FlushOverflows();
6880
6900
 
6881
6901
  // note event is sent in exec command, not implicit here
6882
6902
 
@@ -196,7 +196,7 @@ export class MDParser {
196
196
  const followed_by_punctuation = following && following.type === 'text' && /^[^\w\d]/.test(following.text);
197
197
 
198
198
  token.left_flanking = ((!followed_by_whitespace) && ((!followed_by_punctuation) || preceded_by_whitespace));
199
- token.right_flanking = ((!preceded_by_whitespace) && ((!preceded_by_punctuation) || followed_by_whitespace));
199
+ token.right_flanking = ((!preceded_by_whitespace) && ((!preceded_by_punctuation) || (followed_by_whitespace || followed_by_punctuation)));
200
200
 
201
201
  }
202
202
  }