@gridkitjs/dom 0.4.0 → 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +38 -19
- package/dist/index.js +78 -38
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/dist/index.d.ts
CHANGED
|
@@ -96,7 +96,11 @@ interface AttachedChecklist {
|
|
|
96
96
|
* An item outside the mounted window is focused once it mounts.
|
|
97
97
|
*/
|
|
98
98
|
readonly focusItem: (index: number) => void;
|
|
99
|
-
/**
|
|
99
|
+
/**
|
|
100
|
+
* Removes every listener and observer. The items keep their `tabindex`.
|
|
101
|
+
* After it, `setCount` and `focusItem` do nothing: they neither scroll
|
|
102
|
+
* nor focus, and a move still waiting for its item is dropped.
|
|
103
|
+
*/
|
|
100
104
|
readonly detach: () => void;
|
|
101
105
|
}
|
|
102
106
|
/**
|
|
@@ -191,10 +195,11 @@ interface ColumnResizeGestureHandlers {
|
|
|
191
195
|
/** Every pointer move, with the width the column takes there. */
|
|
192
196
|
readonly onMove: (width: number) => void;
|
|
193
197
|
/**
|
|
194
|
-
* The pointer was released. `width` is the width to commit,
|
|
195
|
-
* it
|
|
196
|
-
*
|
|
197
|
-
* spurious resize on every
|
|
198
|
+
* The pointer was released. `width` is the width to commit, even when a
|
|
199
|
+
* drag brought it back to where it started, or `null` when the width never
|
|
200
|
+
* changed: a click on the handle — as each half of a double-click is — is
|
|
201
|
+
* not a resize, and reporting one would fire a spurious resize on every
|
|
202
|
+
* click.
|
|
198
203
|
*/
|
|
199
204
|
readonly onEnd: (width: number | null) => void;
|
|
200
205
|
/**
|
|
@@ -276,15 +281,22 @@ declare function writeClipboard(content: ClipboardContent): Promise<void>;
|
|
|
276
281
|
*/
|
|
277
282
|
declare function downloadBlob(blob: Blob, fileName: string): void;
|
|
278
283
|
|
|
279
|
-
/**
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
284
|
+
/**
|
|
285
|
+
* What a renderer draws for a reorder gesture: nothing while `idle`, which
|
|
286
|
+
* covers a press still short of the drag threshold, then while `dragging` the
|
|
287
|
+
* dragged item, where it would land and the ghost trailing the pointer.
|
|
288
|
+
*/
|
|
289
|
+
type DragReorderState<Target> = {
|
|
290
|
+
readonly kind: "idle";
|
|
291
|
+
} | {
|
|
292
|
+
readonly kind: "dragging";
|
|
293
|
+
/** The item being dragged. */
|
|
294
|
+
readonly draggedId: string;
|
|
283
295
|
/** Where it would land if released now, `null` for nowhere valid. */
|
|
284
296
|
readonly dropTarget: Target | null;
|
|
285
297
|
/** Where the element trailing the pointer sits, as a CSS `transform`. */
|
|
286
|
-
readonly ghostTransform: string
|
|
287
|
-
}
|
|
298
|
+
readonly ghostTransform: string;
|
|
299
|
+
};
|
|
288
300
|
/** The state while nothing is dragged — the one a drag reports when it ends. */
|
|
289
301
|
declare const NO_DRAG: DragReorderState<never>;
|
|
290
302
|
interface DragReorderHandlers<Target> {
|
|
@@ -434,7 +446,7 @@ interface GridFocusController {
|
|
|
434
446
|
* focused does nothing, which is what lets a cell's own `focus` event
|
|
435
447
|
* report a click through here without a loop.
|
|
436
448
|
*/
|
|
437
|
-
readonly focusCell: (
|
|
449
|
+
readonly focusCell: (focus: GridFocus) => void;
|
|
438
450
|
/**
|
|
439
451
|
* Moves the tab stop as `key` does — the arrows, Home, End, the page keys,
|
|
440
452
|
* with Ctrl for the grid's corners. Returns whether the key was one of
|
|
@@ -505,8 +517,9 @@ interface InfiniteScrollOptions {
|
|
|
505
517
|
/**
|
|
506
518
|
* Called at most once per approach: when the sentinel comes within
|
|
507
519
|
* `rootMargin` of the root's visible area. Not again until that load has
|
|
508
|
-
* finished (`isLoadingMore` back to `false`), `hasMore` has changed,
|
|
509
|
-
* the sentinel
|
|
520
|
+
* finished (`isLoadingMore` back to `false`), `hasMore` has changed, rows
|
|
521
|
+
* have been added or removed in front of the sentinel, or the sentinel has
|
|
522
|
+
* left `rootMargin` and come back.
|
|
510
523
|
*/
|
|
511
524
|
readonly onLoadMore?: (() => void) | undefined;
|
|
512
525
|
/** Whether a load `onLoadMore` started is still in flight. */
|
|
@@ -519,6 +532,8 @@ interface InfiniteScroll {
|
|
|
519
532
|
* Takes the current options. Cheap when nothing changed, so a renderer may
|
|
520
533
|
* call it after every render; a new sentinel or `rootMargin` restarts the
|
|
521
534
|
* observer, and a load finishing or `hasMore` changing re-checks at once.
|
|
535
|
+
* While a load it asked for has not reported `isLoadingMore`, it measures
|
|
536
|
+
* where the sentinel sits, to tell whether rows answered it.
|
|
522
537
|
*/
|
|
523
538
|
readonly update: (options: InfiniteScrollOptions) => void;
|
|
524
539
|
/** Stops watching for good: a later `update` does nothing. */
|
|
@@ -783,7 +798,11 @@ interface RowVirtualizerOptions {
|
|
|
783
798
|
interface RowVirtualizer {
|
|
784
799
|
/** How many rows there are. Measured heights of the rows that remain are kept. */
|
|
785
800
|
readonly setRowCount: (count: number) => void;
|
|
786
|
-
/**
|
|
801
|
+
/**
|
|
802
|
+
* Forgets every measured height, for rows that are no longer the ones
|
|
803
|
+
* measured. A `scrollToIndex` still waiting for its row is dropped too:
|
|
804
|
+
* the row it asked for is no longer at that index.
|
|
805
|
+
*/
|
|
787
806
|
readonly resetHeights: () => void;
|
|
788
807
|
/**
|
|
789
808
|
* A ref callback for the element of row `index` (its place among all the
|
|
@@ -796,8 +815,8 @@ interface RowVirtualizer {
|
|
|
796
815
|
* Scrolls so row `index` is in view. A mounted row is scrolled to directly;
|
|
797
816
|
* one outside the window is jumped to at its estimated offset, then
|
|
798
817
|
* scrolled to properly once it mounts and can be measured. A later call
|
|
799
|
-
* replaces one still waiting for its row
|
|
800
|
-
*
|
|
818
|
+
* replaces one still waiting for its row; a row count that no longer holds
|
|
819
|
+
* that row, or `resetHeights`, drops it.
|
|
801
820
|
*/
|
|
802
821
|
readonly scrollToIndex: (index: number, options?: ScrollIntoViewOptions) => void;
|
|
803
822
|
/**
|
|
@@ -912,8 +931,8 @@ interface PrintDocumentOptions {
|
|
|
912
931
|
* Prints a document through a hidden frame: its own page, holding only
|
|
913
932
|
* `bodyHtml` under `styles`, so what is printed is what was built — every
|
|
914
933
|
* row, not the slice of them a virtualised grid has drawn — and nothing of
|
|
915
|
-
* the page around it. The frame loads, waits for its fonts
|
|
916
|
-
* print dialog, and is removed once the dialog closes, when the promise
|
|
934
|
+
* the page around it. The frame loads, waits for its fonts (a few seconds
|
|
935
|
+
* at most), opens the print dialog, and is removed once the dialog closes, when the promise
|
|
917
936
|
* resolves; focus goes back where it was. A frame rather than a new window,
|
|
918
937
|
* which a popup blocker would stop.
|
|
919
938
|
*
|
package/dist/index.js
CHANGED
|
@@ -69,13 +69,15 @@ function bodyRowFrom(target) {
|
|
|
69
69
|
// src/checklist/attachChecklist.ts
|
|
70
70
|
var ITEM = "[data-gridkit-checklist-item]";
|
|
71
71
|
var INDEX = "data-gridkit-checklist-index";
|
|
72
|
+
var SETTLED = { kind: "settled" };
|
|
73
|
+
var DETACHED = { kind: "detached" };
|
|
72
74
|
function indexOf(item) {
|
|
73
75
|
return Number(item.getAttribute(INDEX));
|
|
74
76
|
}
|
|
75
77
|
function attachChecklist(list, options) {
|
|
76
78
|
let count = 0;
|
|
77
79
|
let active = 0;
|
|
78
|
-
let
|
|
80
|
+
let state = SETTLED;
|
|
79
81
|
function items() {
|
|
80
82
|
return Array.from(list.querySelectorAll(ITEM));
|
|
81
83
|
}
|
|
@@ -102,7 +104,7 @@ function attachChecklist(list, options) {
|
|
|
102
104
|
}
|
|
103
105
|
}
|
|
104
106
|
function moveTo(index) {
|
|
105
|
-
if (count === 0) {
|
|
107
|
+
if (state.kind === "detached" || count === 0) {
|
|
106
108
|
return;
|
|
107
109
|
}
|
|
108
110
|
const target = Math.max(0, Math.min(index, count - 1));
|
|
@@ -111,9 +113,9 @@ function attachChecklist(list, options) {
|
|
|
111
113
|
options.scrollToIndex(target);
|
|
112
114
|
const item = itemAt(target);
|
|
113
115
|
if (item === null) {
|
|
114
|
-
|
|
116
|
+
state = { kind: "awaiting-item", index: target };
|
|
115
117
|
} else {
|
|
116
|
-
|
|
118
|
+
state = SETTLED;
|
|
117
119
|
item.focus({ preventScroll: true });
|
|
118
120
|
}
|
|
119
121
|
}
|
|
@@ -163,7 +165,7 @@ function attachChecklist(list, options) {
|
|
|
163
165
|
function onFocusIn(event) {
|
|
164
166
|
const item = itemOf(event.target);
|
|
165
167
|
if (item !== null) {
|
|
166
|
-
|
|
168
|
+
state = SETTLED;
|
|
167
169
|
makeActive(indexOf(item));
|
|
168
170
|
setTabStop();
|
|
169
171
|
}
|
|
@@ -175,12 +177,12 @@ function attachChecklist(list, options) {
|
|
|
175
177
|
item.focus({ preventScroll: true });
|
|
176
178
|
}
|
|
177
179
|
}
|
|
178
|
-
function
|
|
179
|
-
const item =
|
|
180
|
+
function focusAwaitedItemIfMounted() {
|
|
181
|
+
const item = state.kind === "awaiting-item" ? itemAt(state.index) : null;
|
|
180
182
|
if (item === null) {
|
|
181
183
|
return;
|
|
182
184
|
}
|
|
183
|
-
|
|
185
|
+
state = SETTLED;
|
|
184
186
|
const focused = document.activeElement;
|
|
185
187
|
if (focused === null || focused === document.body || list.contains(focused)) {
|
|
186
188
|
item.focus({ preventScroll: true });
|
|
@@ -188,7 +190,7 @@ function attachChecklist(list, options) {
|
|
|
188
190
|
}
|
|
189
191
|
const observer = new MutationObserver(() => {
|
|
190
192
|
setTabStop();
|
|
191
|
-
|
|
193
|
+
focusAwaitedItemIfMounted();
|
|
192
194
|
});
|
|
193
195
|
observer.observe(list, {
|
|
194
196
|
childList: true,
|
|
@@ -201,17 +203,23 @@ function attachChecklist(list, options) {
|
|
|
201
203
|
list.addEventListener("click", onClick);
|
|
202
204
|
return {
|
|
203
205
|
setCount(next) {
|
|
206
|
+
if (state.kind === "detached") {
|
|
207
|
+
return;
|
|
208
|
+
}
|
|
204
209
|
count = next;
|
|
205
210
|
active = Math.max(0, Math.min(active, count - 1));
|
|
206
|
-
if (
|
|
207
|
-
|
|
211
|
+
if (state.kind === "awaiting-item") {
|
|
212
|
+
state = count === 0 ? SETTLED : {
|
|
213
|
+
kind: "awaiting-item",
|
|
214
|
+
index: Math.min(state.index, count - 1)
|
|
215
|
+
};
|
|
208
216
|
}
|
|
209
217
|
setTabStop();
|
|
210
|
-
|
|
218
|
+
focusAwaitedItemIfMounted();
|
|
211
219
|
},
|
|
212
220
|
focusItem: moveTo,
|
|
213
221
|
detach() {
|
|
214
|
-
|
|
222
|
+
state = DETACHED;
|
|
215
223
|
observer.disconnect();
|
|
216
224
|
list.removeEventListener("keydown", onKeyDown2);
|
|
217
225
|
list.removeEventListener("focusin", onFocusIn);
|
|
@@ -383,16 +391,18 @@ function startColumnResizeGesture(handle, press, session, handlers) {
|
|
|
383
391
|
}
|
|
384
392
|
press.preventDefault();
|
|
385
393
|
let width = session.startWidth;
|
|
394
|
+
let resized = false;
|
|
386
395
|
startPointerGesture(
|
|
387
396
|
handle,
|
|
388
397
|
press.pointerId,
|
|
389
398
|
{
|
|
390
399
|
onMove(event) {
|
|
391
400
|
width = applyColumnResize(session, event.clientX);
|
|
401
|
+
resized ||= width !== session.startWidth;
|
|
392
402
|
handlers.onMove(width);
|
|
393
403
|
},
|
|
394
404
|
onEnd() {
|
|
395
|
-
handlers.onEnd(
|
|
405
|
+
handlers.onEnd(resized ? width : null);
|
|
396
406
|
},
|
|
397
407
|
onCancel() {
|
|
398
408
|
handlers.onCancel();
|
|
@@ -520,11 +530,7 @@ function downloadBlob(blob, fileName) {
|
|
|
520
530
|
|
|
521
531
|
// src/dragReorder.ts
|
|
522
532
|
var DRAG_THRESHOLD = 4;
|
|
523
|
-
var NO_DRAG = {
|
|
524
|
-
draggedId: null,
|
|
525
|
-
dropTarget: null,
|
|
526
|
-
ghostTransform: null
|
|
527
|
-
};
|
|
533
|
+
var NO_DRAG = { kind: "idle" };
|
|
528
534
|
function startDragReorder(id, grabElement, press, handlers) {
|
|
529
535
|
if (!mayStartGesture(press, handlers.signal)) {
|
|
530
536
|
return false;
|
|
@@ -546,6 +552,7 @@ function startDragReorder(id, grabElement, press, handlers) {
|
|
|
546
552
|
target: handlers.resolveTarget(clientX, clientY, id)
|
|
547
553
|
};
|
|
548
554
|
handlers.onState({
|
|
555
|
+
kind: "dragging",
|
|
549
556
|
draggedId: id,
|
|
550
557
|
dropTarget: phase.target,
|
|
551
558
|
ghostTransform: `translate(${String(clientX - grabX)}px, ${String(clientY)}px)`
|
|
@@ -619,7 +626,7 @@ function observeElementWidth(element, onWidth) {
|
|
|
619
626
|
// src/gridFocus.ts
|
|
620
627
|
import {
|
|
621
628
|
clampFocus,
|
|
622
|
-
|
|
629
|
+
headerFocus,
|
|
623
630
|
nextFocusForKey
|
|
624
631
|
} from "@gridkitjs/core";
|
|
625
632
|
var FALLBACK_PAGE = 10;
|
|
@@ -629,6 +636,12 @@ function cellIn(row, columnIndex) {
|
|
|
629
636
|
}
|
|
630
637
|
return row.cells[Math.min(columnIndex, row.cells.length - 1)] ?? null;
|
|
631
638
|
}
|
|
639
|
+
function sameCell(a, b) {
|
|
640
|
+
if (a.area === "body" && b.area === "body") {
|
|
641
|
+
return a.rowIndex === b.rowIndex && a.columnIndex === b.columnIndex;
|
|
642
|
+
}
|
|
643
|
+
return a.area === b.area && a.columnIndex === b.columnIndex;
|
|
644
|
+
}
|
|
632
645
|
function findBodyRow(bodyTable, rowIndex) {
|
|
633
646
|
return bodyTable?.tBodies[0]?.querySelector(
|
|
634
647
|
`:scope > tr[data-gridkit-row-index="${String(rowIndex)}"]`
|
|
@@ -646,7 +659,7 @@ function createGridFocus(initialOptions) {
|
|
|
646
659
|
let options = initialOptions;
|
|
647
660
|
let rows = null;
|
|
648
661
|
const listeners = /* @__PURE__ */ new Set();
|
|
649
|
-
let stored =
|
|
662
|
+
let stored = headerFocus(0);
|
|
650
663
|
let snapshot = {
|
|
651
664
|
stored,
|
|
652
665
|
rowCount: options.rowCount,
|
|
@@ -684,14 +697,9 @@ function createGridFocus(initialOptions) {
|
|
|
684
697
|
root.removeEventListener("pointerdown", dropPendingMove);
|
|
685
698
|
};
|
|
686
699
|
}
|
|
687
|
-
function focusCell(
|
|
688
|
-
const next = clampFocus(
|
|
689
|
-
|
|
690
|
-
options.rowCount,
|
|
691
|
-
options.columnCount
|
|
692
|
-
);
|
|
693
|
-
const current = getFocus();
|
|
694
|
-
if (next.rowIndex === current.rowIndex && next.columnIndex === current.columnIndex) {
|
|
700
|
+
function focusCell(focus) {
|
|
701
|
+
const next = clampFocus(focus, options.rowCount, options.columnCount);
|
|
702
|
+
if (sameCell(next, getFocus())) {
|
|
695
703
|
return;
|
|
696
704
|
}
|
|
697
705
|
pendingMove = next;
|
|
@@ -725,7 +733,7 @@ function createGridFocus(initialOptions) {
|
|
|
725
733
|
if (next === null) {
|
|
726
734
|
return false;
|
|
727
735
|
}
|
|
728
|
-
focusCell(next
|
|
736
|
+
focusCell(next);
|
|
729
737
|
return true;
|
|
730
738
|
},
|
|
731
739
|
attach(next, root) {
|
|
@@ -743,7 +751,7 @@ function createGridFocus(initialOptions) {
|
|
|
743
751
|
return;
|
|
744
752
|
}
|
|
745
753
|
const cell = cellIn(
|
|
746
|
-
drawn.
|
|
754
|
+
drawn.area === "header" ? rows.getHeaderRow() : rows.getBodyRow(drawn.rowIndex),
|
|
747
755
|
drawn.columnIndex
|
|
748
756
|
);
|
|
749
757
|
if (cell !== null) {
|
|
@@ -752,7 +760,7 @@ function createGridFocus(initialOptions) {
|
|
|
752
760
|
return;
|
|
753
761
|
}
|
|
754
762
|
const range = options.virtualRange;
|
|
755
|
-
if (range != null && drawn.
|
|
763
|
+
if (range != null && drawn.area === "body" && (drawn.rowIndex < range.startIndex || drawn.rowIndex > range.endIndex)) {
|
|
756
764
|
range.scrollToIndex(drawn.rowIndex);
|
|
757
765
|
return;
|
|
758
766
|
}
|
|
@@ -763,15 +771,17 @@ function createGridFocus(initialOptions) {
|
|
|
763
771
|
|
|
764
772
|
// src/infiniteScroll.ts
|
|
765
773
|
var IDLE = { kind: "idle" };
|
|
766
|
-
var REQUESTED = { kind: "requested" };
|
|
767
774
|
var LOADING = { kind: "loading" };
|
|
768
|
-
var
|
|
775
|
+
var DETACHED2 = { kind: "detached" };
|
|
769
776
|
function afterUpdate(state, loading, hasMoreChanged) {
|
|
770
777
|
if (loading) {
|
|
771
778
|
return LOADING;
|
|
772
779
|
}
|
|
773
780
|
return state.kind === "loading" || hasMoreChanged ? IDLE : state;
|
|
774
781
|
}
|
|
782
|
+
function contentOffset(root, sentinel) {
|
|
783
|
+
return sentinel.getBoundingClientRect().top - root.getBoundingClientRect().top + root.scrollTop;
|
|
784
|
+
}
|
|
775
785
|
function attachInfiniteScroll(root, options) {
|
|
776
786
|
let latest = options;
|
|
777
787
|
let intersecting = false;
|
|
@@ -779,12 +789,22 @@ function attachInfiniteScroll(root, options) {
|
|
|
779
789
|
let observer = null;
|
|
780
790
|
let observed = null;
|
|
781
791
|
function maybeLoadMore() {
|
|
782
|
-
if (state.kind !== "idle" || !intersecting || !latest.hasMore) {
|
|
792
|
+
if (state.kind !== "idle" || !intersecting || observed === null || !latest.hasMore) {
|
|
783
793
|
return;
|
|
784
794
|
}
|
|
785
|
-
state =
|
|
795
|
+
state = {
|
|
796
|
+
kind: "requested",
|
|
797
|
+
sentinelOffset: contentOffset(root, observed.sentinel)
|
|
798
|
+
};
|
|
786
799
|
latest.onLoadMore?.();
|
|
787
800
|
}
|
|
801
|
+
function requestAnswered() {
|
|
802
|
+
if (state.kind !== "requested" || observed === null) {
|
|
803
|
+
return false;
|
|
804
|
+
}
|
|
805
|
+
const moved = contentOffset(root, observed.sentinel) - state.sentinelOffset;
|
|
806
|
+
return Math.abs(moved) >= 1;
|
|
807
|
+
}
|
|
788
808
|
function report(isIntersecting) {
|
|
789
809
|
intersecting = isIntersecting;
|
|
790
810
|
if (!intersecting && state.kind === "requested") {
|
|
@@ -830,11 +850,16 @@ function attachInfiniteScroll(root, options) {
|
|
|
830
850
|
latest = next;
|
|
831
851
|
state = afterUpdate(state, next.isLoadingMore ?? false, hasMoreChanged);
|
|
832
852
|
observe();
|
|
853
|
+
if (requestAnswered()) {
|
|
854
|
+
state = IDLE;
|
|
855
|
+
disconnect();
|
|
856
|
+
observe();
|
|
857
|
+
}
|
|
833
858
|
maybeLoadMore();
|
|
834
859
|
},
|
|
835
860
|
detach() {
|
|
836
861
|
disconnect();
|
|
837
|
-
state =
|
|
862
|
+
state = DETACHED2;
|
|
838
863
|
}
|
|
839
864
|
};
|
|
840
865
|
}
|
|
@@ -1414,6 +1439,9 @@ function createRowVirtualizer(scrollElement, options) {
|
|
|
1414
1439
|
recompute();
|
|
1415
1440
|
},
|
|
1416
1441
|
resetHeights() {
|
|
1442
|
+
if (phase.kind === "awaiting-row") {
|
|
1443
|
+
phase = READY;
|
|
1444
|
+
}
|
|
1417
1445
|
heights = new Array(heights.length).fill(void 0);
|
|
1418
1446
|
recompute();
|
|
1419
1447
|
},
|
|
@@ -1670,6 +1698,7 @@ function observeToolbarOverflow(toolbar, options) {
|
|
|
1670
1698
|
|
|
1671
1699
|
// src/print/printDocument.ts
|
|
1672
1700
|
var RETURN_EVENTS = ["pointerdown", "keydown"];
|
|
1701
|
+
var FONTS_TIMEOUT_MS = 3e3;
|
|
1673
1702
|
var printing = false;
|
|
1674
1703
|
function createFrame(bodyHtml) {
|
|
1675
1704
|
const frame = document.createElement("iframe");
|
|
@@ -1716,6 +1745,17 @@ function fill(view, { title, styles }) {
|
|
|
1716
1745
|
style.textContent = styles;
|
|
1717
1746
|
frameDocument.head.append(style);
|
|
1718
1747
|
}
|
|
1748
|
+
async function fontsLoaded(view) {
|
|
1749
|
+
let timer = 0;
|
|
1750
|
+
const timeout = new Promise((resolve) => {
|
|
1751
|
+
timer = window.setTimeout(resolve, FONTS_TIMEOUT_MS);
|
|
1752
|
+
});
|
|
1753
|
+
try {
|
|
1754
|
+
await Promise.race([view.document.fonts.ready, timeout]);
|
|
1755
|
+
} finally {
|
|
1756
|
+
window.clearTimeout(timer);
|
|
1757
|
+
}
|
|
1758
|
+
}
|
|
1719
1759
|
async function print(view) {
|
|
1720
1760
|
const listeners = [
|
|
1721
1761
|
[view, "afterprint"],
|
|
@@ -1751,7 +1791,7 @@ async function printDocument(options) {
|
|
|
1751
1791
|
try {
|
|
1752
1792
|
const view = await load(frame);
|
|
1753
1793
|
fill(view, options);
|
|
1754
|
-
await view
|
|
1794
|
+
await fontsLoaded(view);
|
|
1755
1795
|
await print(view);
|
|
1756
1796
|
} finally {
|
|
1757
1797
|
frame.remove();
|