@trebco/treb 27.9.0 → 27.11.4

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 (32) hide show
  1. package/dist/treb-spreadsheet.mjs +9 -9
  2. package/dist/treb.d.ts +8 -6
  3. package/package.json +1 -1
  4. package/{treb-grid/src/util/dom_utilities.ts → treb-base-types/src/dom-utilities.ts} +29 -20
  5. package/treb-base-types/src/index.ts +1 -0
  6. package/treb-base-types/src/theme.ts +3 -5
  7. package/treb-embed/src/custom-element/global.d.ts +3 -1
  8. package/treb-embed/src/custom-element/spreadsheet-constructor.ts +13 -19
  9. package/treb-embed/src/embedded-spreadsheet.ts +67 -93
  10. package/treb-embed/src/spinner.ts +3 -3
  11. package/treb-embed/style/layout.scss +1 -1
  12. package/treb-embed/style/overlay-editor.scss +9 -0
  13. package/treb-export/src/drawing2/chart2.ts +11 -2
  14. package/treb-export/src/export2.ts +14 -4
  15. package/treb-export/src/workbook-style2.ts +3 -2
  16. package/treb-grid/src/editors/autocomplete.ts +28 -24
  17. package/treb-grid/src/editors/editor.ts +32 -4
  18. package/treb-grid/src/editors/formula_bar.ts +1 -1
  19. package/treb-grid/src/layout/base_layout.ts +11 -16
  20. package/treb-grid/src/layout/grid_layout.ts +17 -28
  21. package/treb-grid/src/render/selection-renderer.ts +2 -3
  22. package/treb-grid/src/render/svg_header_overlay.ts +4 -11
  23. package/treb-grid/src/render/svg_selection_block.ts +27 -34
  24. package/treb-grid/src/render/tile_renderer.ts +6 -5
  25. package/treb-grid/src/types/grid.ts +32 -41
  26. package/treb-grid/src/types/grid_base.ts +2 -0
  27. package/treb-grid/src/types/scale-control.ts +2 -2
  28. package/treb-grid/src/types/sheet.ts +2 -2
  29. package/treb-grid/src/types/tab_bar.ts +4 -8
  30. package/treb-utils/src/index.ts +0 -1
  31. package/treb-utils/src/resizable.ts +26 -27
  32. package/treb-utils/src/template.ts +0 -70
@@ -1,25 +1,25 @@
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
- import { DOMUtilities } from '../util/dom_utilities';
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
+ import { DOMUtilities } from 'treb-base-types';
23
23
  import type { Theme, Rectangle } from 'treb-base-types';
24
24
  import type { AutocompleteExecResult, DescriptorType } from './autocomplete_matcher';
25
25
 
@@ -76,7 +76,7 @@ export class Autocomplete {
76
76
 
77
77
  // this.scope = 'AC' + Math.round(Math.random() * Math.pow(10, 10)).toString(16);
78
78
 
79
- this.completion_list = DOMUtilities.CreateDiv(
79
+ this.completion_list = DOMUtilities.Div(
80
80
  'treb-cell-editor-ac-list treb-autocomplete',
81
81
  options.container || document.body,
82
82
  ); // this.scope);
@@ -87,7 +87,7 @@ export class Autocomplete {
87
87
 
88
88
  this.completion_list.addEventListener('mousemove', (event) => this.ListMouseMove(event));
89
89
 
90
- this.tooltip = DOMUtilities.CreateDiv('treb-cell-editor-ac-tooltip treb-autocomplete-tooltip',
90
+ this.tooltip = DOMUtilities.Div('treb-cell-editor-ac-tooltip treb-autocomplete-tooltip',
91
91
  options.container || document.body,
92
92
  ); // this.scope);
93
93
 
@@ -173,6 +173,10 @@ export class Autocomplete {
173
173
  this.active_element = undefined;
174
174
  }
175
175
 
176
+ public SetBlock(): void {
177
+ this.block = true;
178
+ }
179
+
176
180
  public ResetBlock(): void {
177
181
  this.block = false;
178
182
  }
@@ -34,7 +34,7 @@
34
34
  *
35
35
  */
36
36
 
37
- import { Area, type IArea, type ICellAddress, IsCellAddress, Localization, type Theme, Rectangle, type Cell } from 'treb-base-types';
37
+ import { Area, type IArea, type ICellAddress, IsCellAddress, Localization, type Theme, Rectangle, type Cell, DOMUtilities } from 'treb-base-types';
38
38
  import type { ExpressionUnit, ParseResult, UnitAddress, UnitRange } from 'treb-parser';
39
39
  import { Parser, QuotedSheetNameRegex } from 'treb-parser';
40
40
  import type { DataModel, ViewModel } from '../types/data_model';
@@ -291,7 +291,6 @@ export class Editor<E = FormulaEditorEvent> extends EventSource<E|FormulaEditorE
291
291
  super();
292
292
 
293
293
  this.parser = model.parser;
294
- // this.measurement_node = document.createElement('div');
295
294
 
296
295
  }
297
296
 
@@ -866,13 +865,13 @@ export class Editor<E = FormulaEditorEvent> extends EventSource<E|FormulaEditorE
866
865
 
867
866
  if (type !== 'text') {
868
867
 
869
- const span = document.createElement('span');
868
+ const span = DOMUtilities.Create('span', type);
870
869
 
871
870
  if (reference) {
872
871
  span.dataset.reference = reference;
873
872
  }
874
873
 
875
- span.className = type;
874
+ // span.className = type;
876
875
  span.appendChild(text_node);
877
876
  fragment.appendChild(span);
878
877
 
@@ -1114,6 +1113,35 @@ export class Editor<E = FormulaEditorEvent> extends EventSource<E|FormulaEditorE
1114
1113
 
1115
1114
  const Consume = (element: Node, range: Range) => {
1116
1115
 
1116
+ // it only seems to happen in firefox, but sometimes we'll get
1117
+ // a non-text node that is the start container and endcontainer.
1118
+ //
1119
+ // in that case we need to interpret the endOffset as nodes, not
1120
+ // characters. that's what's causing the firefox issues. I guess
1121
+ // that applies to startoffset as well?
1122
+
1123
+ // not sure if this is bugged or what but when we hit this case,
1124
+ // it's always "all the text in there" regardless of the offsets.
1125
+ // not sure what the offsets are even referring to, since we get
1126
+ // offsets > the number of child nodes. is this a bug in firefox?
1127
+
1128
+ if (element === range.startContainer && element === range.endContainer && !(element instanceof Text)) {
1129
+
1130
+ /*
1131
+ if (range.startOffset !== 0 || range.endOffset !== 0) {
1132
+ console.info("warn offset", range.startOffset, range.endOffset);
1133
+ console.info(element);
1134
+ }
1135
+ */
1136
+
1137
+ complete[0] = complete[1] = true;
1138
+
1139
+ result[0] += element.textContent;
1140
+ result[1] += element.textContent;
1141
+
1142
+ return;
1143
+ }
1144
+
1117
1145
  if (element === range.startContainer) {
1118
1146
  result[0] += (element.textContent || '').substring(0, range.startOffset);
1119
1147
  complete[0] = true;
@@ -25,7 +25,7 @@ import { Parser } from 'treb-parser';
25
25
  import type { DataModel, ViewModel } from '../types/data_model';
26
26
  import type { GridOptions } from '../types/grid_options';
27
27
  import { Autocomplete } from './autocomplete';
28
- import { DOMUtilities } from '../util/dom_utilities';
28
+ import { DOMUtilities } from 'treb-base-types';
29
29
 
30
30
  // --- from formula_bar ---
31
31
 
@@ -19,7 +19,7 @@
19
19
  *
20
20
  */
21
21
 
22
- import { DOMUtilities } from '../util/dom_utilities';
22
+ import { DOMUtilities } from 'treb-base-types';
23
23
  import type { DataModel, ViewModel } from '../types/data_model';
24
24
 
25
25
  import type { Tile } from '../types/tile';
@@ -46,8 +46,6 @@ import type { Annotation } from '../types/annotation';
46
46
 
47
47
  export { Area as TileRange } from 'treb-base-types';
48
48
 
49
- const SVGNS = 'http://www.w3.org/2000/svg';
50
-
51
49
  export interface TooltipOptions {
52
50
  up?: true;
53
51
  left?: true;
@@ -203,19 +201,16 @@ export abstract class BaseLayout {
203
201
  // contexts; the mask will be under the next sheet. so either
204
202
  // global in body, or instance local.
205
203
 
206
- this.mask = // document.querySelector('.treb-mouse-mask'); // ||
207
- DOMUtilities.CreateDiv('treb-mouse-mask');
208
- this.tooltip = // document.querySelector('.treb-tooltip'); // ||
209
- DOMUtilities.CreateDiv('treb-tooltip');
204
+ this.mask = DOMUtilities.Div('treb-mouse-mask');
205
+ this.tooltip = DOMUtilities.Div('treb-tooltip');
210
206
 
211
207
  // this.error_highlight = DOMUtilities.CreateDiv('treb-error-highlight');
212
208
 
213
- this.dropdown_caret = document.createElementNS(SVGNS, 'svg') as SVGSVGElement;
214
- this.dropdown_caret.setAttribute('class', 'treb-dropdown-caret');
209
+ this.dropdown_caret = DOMUtilities.SVG('svg', 'treb-dropdown-caret');
215
210
  this.dropdown_caret.setAttribute('viewBox', '0 0 24 24');
216
211
  this.dropdown_caret.tabIndex = -1;
217
212
 
218
- const caret = document.createElementNS(SVGNS, 'path');
213
+ const caret =DOMUtilities.SVG('path');
219
214
  caret.setAttribute('d', 'M5,7 L12,17 L19,7');
220
215
  this.dropdown_caret.appendChild(caret);
221
216
 
@@ -252,7 +247,7 @@ export abstract class BaseLayout {
252
247
  });
253
248
  */
254
249
 
255
- this.dropdown_list = DOMUtilities.CreateDiv('treb-dropdown-list');
250
+ this.dropdown_list = DOMUtilities.Div('treb-dropdown-list');
256
251
  this.dropdown_list.setAttribute('tabindex', '-1'); // focusable
257
252
 
258
253
  // this.dropdown_caret.addEventListener('keydown', (event) => {
@@ -351,11 +346,11 @@ export abstract class BaseLayout {
351
346
  this.dropdown_selected = target as HTMLElement;
352
347
  });
353
348
 
354
- this.mock_selection = DOMUtilities.CreateDiv('mock-selection-node');
349
+ this.mock_selection = DOMUtilities.Div('mock-selection-node');
355
350
  this.mock_selection.innerHTML = '&nbsp;';
356
351
 
357
- this.note_node = DOMUtilities.CreateDiv('treb-note');
358
- this.title_node = DOMUtilities.CreateDiv('treb-hover-title');
352
+ this.note_node = DOMUtilities.Div('treb-note');
353
+ this.title_node = DOMUtilities.Div('treb-hover-title');
359
354
 
360
355
  this.sort_button = DOMUtilities.Create(
361
356
  'button',
@@ -1199,7 +1194,7 @@ export abstract class BaseLayout {
1199
1194
  parent: HTMLElement,
1200
1195
  mark_dirty = true): Tile {
1201
1196
 
1202
- const tile = document.createElement('canvas') as Tile;
1197
+ const tile = DOMUtilities.Create('canvas') as Tile;
1203
1198
  tile.setAttribute('class', classes);
1204
1199
  tile.logical_size = size;
1205
1200
  tile.width = size.width * this.dpr;
@@ -1408,7 +1403,7 @@ export abstract class BaseLayout {
1408
1403
 
1409
1404
  this.dropdown_list.textContent = '';
1410
1405
  for (const value of list) {
1411
- const entry = DOMUtilities.CreateDiv(undefined, this.dropdown_list);
1406
+ const entry = DOMUtilities.Div(undefined, this.dropdown_list);
1412
1407
  if (current === value) {
1413
1408
  this.dropdown_selected = entry;
1414
1409
  entry.classList.add('selected');
@@ -21,10 +21,9 @@
21
21
 
22
22
  import { BaseLayout } from './base_layout';
23
23
  import type { Tile } from '../types/tile';
24
- import { DOMUtilities } from '../util/dom_utilities';
24
+ import { DOMUtilities } from 'treb-base-types';
25
25
  import type { DataModel, ViewModel } from '../types/data_model';
26
26
 
27
- const SVGNS = 'http://www.w3.org/2000/svg';
28
27
 
29
28
  /**
30
29
  * we used to have two layouts, this one and a legacy layout for IE11.
@@ -42,47 +41,37 @@ export class GridLayout extends BaseLayout {
42
41
  // mask needs to get attached to a container, when it's
43
42
  // available
44
43
 
45
- this.column_header = DOMUtilities.CreateDiv('treb-top-header');
46
- this.row_header = DOMUtilities.CreateDiv('treb-left-header');
44
+ this.column_header = DOMUtilities.Div('treb-top-header');
45
+ this.row_header = DOMUtilities.Div('treb-left-header');
47
46
 
48
- this.corner = DOMUtilities.CreateDiv('treb-corner');
49
- this.corner_canvas = document.createElement('canvas');
47
+ this.corner = DOMUtilities.Div('treb-corner');
48
+ this.corner_canvas = DOMUtilities.Create('canvas');
50
49
  this.corner.appendChild(this.corner_canvas);
51
50
 
52
- this.contents = DOMUtilities.CreateDiv('treb-contents');
51
+ this.contents = DOMUtilities.Div('treb-contents');
53
52
  this.buffer_canvas = DOMUtilities.Create('canvas', 'treb-buffer-canvas', this.contents);
54
53
 
55
54
  // selection node attached to contents
56
- this.grid_selection = document.createElementNS(SVGNS, 'svg');
57
- this.grid_selection.classList.add('treb-grid-selection');
58
- this.contents.appendChild(this.grid_selection);
55
+ this.grid_selection = DOMUtilities.SVG('svg', 'treb-grid-selection', this.contents);
59
56
 
60
57
  // selection node for frozen rows
61
- this.row_header_selection = document.createElementNS(SVGNS, 'svg');
62
- this.row_header_selection.classList.add('frozen-selection');
63
- this.row_header_selection.classList.add('frozen-selection-rows');
64
- this.column_header.appendChild(this.row_header_selection);
65
- this.row_header_annotations = DOMUtilities.CreateDiv('frozen-annotation-container frozen-annotation-container-rows', this.column_header);
58
+ this.row_header_selection = DOMUtilities.SVG('svg', ['frozen-selection', 'frozen-selection-rows'], this.column_header);
59
+ this.row_header_annotations = DOMUtilities.Div('frozen-annotation-container frozen-annotation-container-rows', this.column_header);
66
60
 
67
61
  // ...columns
68
- this.column_header_selection = document.createElementNS(SVGNS, 'svg');
69
- this.column_header_selection.classList.add('frozen-selection');
70
- this.column_header_selection.classList.add('frozen-selection-columns');
71
- this.row_header.appendChild(this.column_header_selection);
72
- this.column_header_annotations = DOMUtilities.CreateDiv('frozen-annotation-container frozen-annotation-container-columns', this.row_header);
62
+ this.column_header_selection = DOMUtilities.SVG('svg', ['frozen-selection', 'frozen-selection-columns'], this.row_header);
63
+ this.column_header_annotations = DOMUtilities.Div('frozen-annotation-container frozen-annotation-container-columns', this.row_header);
73
64
 
74
65
  // ...corner
75
- this.corner_selection = document.createElementNS(SVGNS, 'svg');
76
- this.corner_selection.classList.add('frozen-selection');
77
- this.corner.appendChild(this.corner_selection);
78
- this.corner_annotations = DOMUtilities.CreateDiv('frozen-annotation-container frozen-annotation-container-corner', this.corner);
66
+ this.corner_selection = DOMUtilities.SVG('svg', 'frozen-selection', this.corner);
67
+ this.corner_annotations = DOMUtilities.Div('frozen-annotation-container frozen-annotation-container-corner', this.corner);
79
68
 
80
69
 
81
- this.annotation_container = DOMUtilities.CreateDiv('treb-annotation-container');
70
+ this.annotation_container = DOMUtilities.Div('treb-annotation-container');
82
71
 
83
- this.grid_cover = DOMUtilities.CreateDiv('tile-cover grid-cover');
84
- this.column_header_cover = DOMUtilities.CreateDiv('tile-cover column-header-cover');
85
- this.row_header_cover = DOMUtilities.CreateDiv('tile-cover row-header-cover');
72
+ this.grid_cover = DOMUtilities.Div('tile-cover grid-cover');
73
+ this.column_header_cover = DOMUtilities.Div('tile-cover column-header-cover');
74
+ this.row_header_cover = DOMUtilities.Div('tile-cover row-header-cover');
86
75
 
87
76
  }
88
77
 
@@ -20,7 +20,7 @@
20
20
  */
21
21
 
22
22
  import type { Theme, ICellAddress } from 'treb-base-types';
23
- import { Rectangle } from 'treb-base-types';
23
+ import { DOMUtilities, Rectangle } from 'treb-base-types';
24
24
  import type { BaseLayout } from '../layout/base_layout';
25
25
  import type { SelectionOffset } from './svg_selection_block';
26
26
  import { SVGSelectionBlock } from './svg_selection_block';
@@ -302,8 +302,7 @@ export class SelectionRenderer {
302
302
 
303
303
  let group: SVGElement = node.querySelector('.alternate-selections') as SVGElement;
304
304
  if (!group) {
305
- group = document.createElementNS('http://www.w3.org/2000/svg', 'g');
306
- group.setAttribute('class', 'alternate-selections');
305
+ group = DOMUtilities.SVG('g', 'alternate-selections');
307
306
  node.appendChild(group);
308
307
  }
309
308
  group?.appendChild(selection_block.g);
@@ -19,9 +19,7 @@
19
19
  *
20
20
  */
21
21
 
22
- import type { Theme } from 'treb-base-types';
23
-
24
- const SVGNS = 'http://www.w3.org/2000/svg';
22
+ import { DOMUtilities, type Theme } from 'treb-base-types';
25
23
 
26
24
  export enum Orientation {
27
25
  Horizontal,
@@ -39,14 +37,9 @@ export class HeaderOverlay {
39
37
  private container: SVGElement,
40
38
  private orientation: Orientation) {
41
39
 
42
- this.g = document.createElementNS(SVGNS, 'g');
43
- this.g.setAttribute('class', 'treb-header-overlay');
44
-
45
- this.overlay = document.createElementNS(SVGNS, 'rect');
46
- this.overlay.setAttribute('class', 'treb-overlay');
47
-
48
- this.highlight = document.createElementNS(SVGNS, 'rect');
49
- this.highlight.setAttribute('class', 'treb-highlight');
40
+ this.g = DOMUtilities.SVG('g', 'treb-header-overlay');
41
+ this.overlay = DOMUtilities.SVG('rect', 'treb-overlay');
42
+ this.highlight = DOMUtilities.SVG('rect', 'treb-highlight');
50
43
 
51
44
  this.g.style.display = 'none';
52
45
  this.g.appendChild(this.highlight);
@@ -1,25 +1,25 @@
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
- import type { Theme, Rectangle } from 'treb-base-types';
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
+ import { type Theme, type Rectangle, DOMUtilities } from 'treb-base-types';
23
23
 
24
24
  /**
25
25
  * the original selections -- a canvas overlaid over the tile canvases --
@@ -30,8 +30,6 @@ import type { Theme, Rectangle } from 'treb-base-types';
30
30
  * attributes.
31
31
  */
32
32
 
33
- const SVGNS = 'http://www.w3.org/2000/svg';
34
-
35
33
  export interface SelectionOffset {
36
34
  x: number;
37
35
  y: number;
@@ -48,11 +46,10 @@ export class SVGSelectionBlock {
48
46
  private theme: Theme,
49
47
  private offset: SelectionOffset = {x: 0, y: 0}) {
50
48
 
51
- this.g = document.createElementNS(SVGNS, 'g');
49
+ this.g = DOMUtilities.SVG('g');
52
50
  this.g.setAttribute('transform', `translate(${offset.x}, ${offset.y})`);
53
51
 
54
- this.outline = document.createElementNS(SVGNS, 'rect');
55
- this.outline.setAttribute('class', 'outline');
52
+ this.outline = DOMUtilities.SVG('rect', 'outline');
56
53
 
57
54
  if (primary) {
58
55
 
@@ -61,11 +58,8 @@ export class SVGSelectionBlock {
61
58
  // primary selections have a separate fill, plus the nub. separate
62
59
  // fill because the "target" is unfilled.
63
60
 
64
- this.fill = document.createElementNS(SVGNS, 'path');
65
- this.fill.setAttribute('class', 'fill');
66
-
67
- this.nub = document.createElementNS(SVGNS, 'rect');
68
- this.nub.setAttribute('class', 'nub');
61
+ this.fill = DOMUtilities.SVG('path', 'fill');
62
+ this.nub = DOMUtilities.SVG('rect', 'nub');
69
63
 
70
64
  this.g.appendChild(this.fill);
71
65
  this.g.appendChild(this.outline);
@@ -81,8 +75,7 @@ export class SVGSelectionBlock {
81
75
  // and use currentColor, but we can't set opacity separately so we
82
76
  // need another node. which is a waste, but ergonomics ftw!
83
77
 
84
- this.fill = document.createElementNS(SVGNS, 'rect');
85
- this.fill.setAttribute('class', 'fill');
78
+ this.fill = DOMUtilities.SVG('rect', 'fill');
86
79
 
87
80
  // this.SetThemeColor(0);
88
81
  // if (theme.additional_selection_line_dash_array) {
@@ -99,10 +99,7 @@ export class TileRenderer {
99
99
  protected view: ViewModel,
100
100
  protected options: GridOptions, ) {
101
101
 
102
- // this.buffer_canvas = document.createElement('canvas');
103
-
104
102
  this.buffer_canvas = layout.buffer_canvas;
105
-
106
103
  this.buffer_canvas.width = this.buffer_canvas_size.width;
107
104
  this.buffer_canvas.height = this.buffer_canvas_size.height;
108
105
 
@@ -912,6 +909,8 @@ export class TileRenderer {
912
909
  line_width = test;
913
910
  words.shift();
914
911
 
912
+ max_width = Math.max(max_width, line_width);
913
+
915
914
  }
916
915
 
917
916
  // trim the last word, then insert a row (we're relying on the
@@ -920,6 +919,8 @@ export class TileRenderer {
920
919
  last.text = last.text.trim();
921
920
  last.width = last.trimmed;
922
921
 
922
+ max_width = Math.max(max_width, last.width);
923
+
923
924
  strings.push(line2.map((metric) => {
924
925
  return {
925
926
  ...metric.part,
@@ -928,11 +929,11 @@ export class TileRenderer {
928
929
  text: metric.text,
929
930
  };
930
931
  }));
931
-
932
+
932
933
  }
933
934
 
934
935
  }
935
-
936
+
936
937
  }
937
938
  else {
938
939
 
@@ -111,7 +111,7 @@ import { CommandKey
111
111
 
112
112
  import type { DataModel, SerializedModel } from './data_model';
113
113
 
114
- import { DOMUtilities } from '../util/dom_utilities';
114
+ import { DOMUtilities } from 'treb-base-types';
115
115
  import { GridBase } from './grid_base';
116
116
  import type { SetRangeOptions } from './set_range_options';
117
117
  import type { ClipboardCellData } from './clipboard_data';
@@ -262,6 +262,9 @@ export class Grid extends GridBase {
262
262
  /** new key capture overlay/ICE */
263
263
  private overlay_editor?: OverlayEditor;
264
264
 
265
+ /** moving autocomplete to a class field */
266
+ private autocomplete?: Autocomplete;
267
+
265
268
  /** formula bar editor (optional) */
266
269
  private formula_bar?: FormulaBar;
267
270
 
@@ -568,13 +571,13 @@ export class Grid extends GridBase {
568
571
 
569
572
  // FIXME: why is this not in layout? it is layout.
570
573
 
571
- view.node = document.createElement('div');
574
+ view.node = DOMUtilities.Div();
572
575
  view.node.dataset.scale = this.layout.scale.toString();
573
576
  view.node.style.fontSize = `${10 * this.layout.scale}pt`;
574
577
 
575
- view.content_node = DOMUtilities.CreateDiv('annotation-content', view.node);
576
- const move_target = DOMUtilities.CreateDiv('annotation-move-target', view.node);
577
- const resize_target = DOMUtilities.CreateDiv('annotation-resize-target', view.node);
578
+ view.content_node = DOMUtilities.Div('annotation-content', view.node);
579
+ const move_target = DOMUtilities.Div('annotation-move-target', view.node);
580
+ const resize_target = DOMUtilities.Div('annotation-resize-target', view.node);
578
581
 
579
582
  if (view.node) {
580
583
  const node = view.node;
@@ -1275,13 +1278,13 @@ export class Grid extends GridBase {
1275
1278
  const higher_level_container = view_node.querySelector('.treb-spreadsheet-body') as HTMLElement;
1276
1279
  const container = higher_level_container.querySelector('div') as HTMLElement;
1277
1280
 
1278
- let autocomplete: Autocomplete | undefined;
1281
+ // let autocomplete: Autocomplete | undefined;
1279
1282
 
1280
1283
  if (this.options.formula_bar) {
1281
- if (!autocomplete) {
1282
- autocomplete = new Autocomplete({ theme: this.theme, container });
1284
+ if (!this.autocomplete) {
1285
+ this.autocomplete = new Autocomplete({ theme: this.theme, container });
1283
1286
  }
1284
- this.InitFormulaBar(view_node, autocomplete);
1287
+ this.InitFormulaBar(view_node, this.autocomplete);
1285
1288
  }
1286
1289
 
1287
1290
  if (this.options.tab_bar) {
@@ -1408,10 +1411,10 @@ export class Grid extends GridBase {
1408
1411
 
1409
1412
  // Sheet.sheet_events.Subscribe(this.HandleSheetEvent.bind(this));
1410
1413
 
1411
- if (!autocomplete) {
1412
- autocomplete = new Autocomplete({ theme: this.theme, container });
1414
+ if (!this.autocomplete) {
1415
+ this.autocomplete = new Autocomplete({ theme: this.theme, container });
1413
1416
  }
1414
- this.InitOverlayEditor(autocomplete);
1417
+ this.InitOverlayEditor(this.autocomplete);
1415
1418
 
1416
1419
  this.AttachListeners();
1417
1420
 
@@ -2695,35 +2698,6 @@ export class Grid extends GridBase {
2695
2698
 
2696
2699
  this.OverlayKeyDown(event.event);
2697
2700
 
2698
- /*
2699
- let cloned_event: KeyboardEvent;
2700
- if (UA.trident) {
2701
- cloned_event = document.createEvent('KeyboardEvent');
2702
- const modifiers = [];
2703
- if (event.event.ctrlKey) modifiers.push('Control');
2704
- if (event.event.altKey) modifiers.push('Alt');
2705
- if (event.event.shiftKey) modifiers.push('Shift');
2706
-
2707
- // have to mask type for trident
2708
- (cloned_event as any).initKeyboardEvent(
2709
- event.event.type,
2710
- false,
2711
- false,
2712
- event.event.view,
2713
- event.event.key,
2714
- event.event.location,
2715
- modifiers.join(' '),
2716
- event.event.repeat,
2717
- Localization.locale);
2718
- }
2719
- else {
2720
- cloned_event = new KeyboardEvent(event.event.type, event.event);
2721
- }
2722
-
2723
- if (cloned_event && this.container) {
2724
- this.container.dispatchEvent(cloned_event);
2725
- }
2726
- */
2727
2701
  }
2728
2702
  break;
2729
2703
 
@@ -3763,6 +3737,17 @@ export class Grid extends GridBase {
3763
3737
 
3764
3738
  const selecting_argument = this.SelectingArgument();
3765
3739
 
3740
+ /*
3741
+ let blocking_tooltip = false;
3742
+ if (selecting_argument) {
3743
+ if (this.autocomplete?.tooltip_visible) {
3744
+ this.autocomplete.SetBlock();
3745
+ this.autocomplete.Hide();
3746
+ blocking_tooltip = true;
3747
+ }
3748
+ }
3749
+ */
3750
+
3766
3751
  if (!selecting_argument && this.additional_selections.length) {
3767
3752
  this.ClearAdditionalSelections();
3768
3753
  }
@@ -4052,6 +4037,12 @@ export class Grid extends GridBase {
4052
4037
  // console.info('end');
4053
4038
  this.UpdateAddressLabel();
4054
4039
 
4040
+ /*
4041
+ if (blocking_tooltip) {
4042
+ this.autocomplete?.ResetBlock();
4043
+ }
4044
+ */
4045
+
4055
4046
  if (selecting_argument) {
4056
4047
  if (this.overlay_editor?.editing) {
4057
4048
  // ...
@@ -2452,6 +2452,7 @@ export class GridBase {
2452
2452
  });
2453
2453
  if (transformed) {
2454
2454
 
2455
+ /*
2455
2456
  if (!this.flags.warned_r1c1) {
2456
2457
 
2457
2458
  // 1-time warning
@@ -2459,6 +2460,7 @@ export class GridBase {
2459
2460
  this.flags.warned_r1c1 = true;
2460
2461
  console.warn('NOTE: R1C1 support is experimental. the semantics may change in the future.');
2461
2462
  }
2463
+ */
2462
2464
 
2463
2465
  value = '=' + this.parser.Render(result.expression, { missing: '' });
2464
2466
  }