@marimo-team/frontend 0.19.7-dev31 → 0.19.7-dev33
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/assets/{JsonOutput-CaYsBlIL.js → JsonOutput-Dw_ZIGoz.js} +1 -1
- package/dist/assets/{add-cell-with-ai-DGWXuion.js → add-cell-with-ai-BHgqYu8P.js} +1 -1
- package/dist/assets/{agent-panel-C_CZ3wsS.js → agent-panel-BOEtQvcD.js} +1 -1
- package/dist/assets/{cell-editor-DrfE1YS-.js → cell-editor-Bed2HJRi.js} +1 -1
- package/dist/assets/{chat-display-BIHBJe4Q.js → chat-display-B0625p01.js} +1 -1
- package/dist/assets/{chat-panel-C4V8R2vf.js → chat-panel-CkHdco_X.js} +1 -1
- package/dist/assets/{column-preview-DfgAxcnz.js → column-preview-YJ759JhT.js} +1 -1
- package/dist/assets/{command-palette-D4dxpptj.js → command-palette-c1vQwlGd.js} +1 -1
- package/dist/assets/{dependency-graph-panel-BbRSXJOA.js → dependency-graph-panel-BWvUSpJI.js} +1 -1
- package/dist/assets/{download-Cphyle83.js → download-vBVDTXQk.js} +2 -2
- package/dist/assets/{edit-page-BiEfjNLG.js → edit-page-D-_8Dpee.js} +3 -3
- package/dist/assets/{file-explorer-panel-Dkqk7q5V.js → file-explorer-panel-Bhrg_Wb0.js} +1 -1
- package/dist/assets/hooks-CPM5R4f-.js +1 -0
- package/dist/assets/html-to-image-Cdx1xsbU.js +2 -0
- package/dist/assets/{index-0-J_BSHl.js → index-DL0FpFYQ.js} +3 -3
- package/dist/assets/index-DmMvDRRC.css +2 -0
- package/dist/assets/{layout-BJ9AHITN.js → layout-C50dPCAb.js} +1 -1
- package/dist/assets/{markdown-renderer-aprG4bjs.js → markdown-renderer-DSY-ElEE.js} +1 -1
- package/dist/assets/{panels-DDBrdHNH.js → panels-H0GWZM90.js} +1 -1
- package/dist/assets/{readonly-python-code-BwtDUnWb.js → readonly-python-code-B1UBDfCT.js} +1 -1
- package/dist/assets/{run-page-BS9QQKCJ.js → run-page-CiOYN_zF.js} +1 -1
- package/dist/assets/{scratchpad-panel-_4qqJHnW.js → scratchpad-panel-BiE33kLt.js} +1 -1
- package/dist/assets/{session-panel-sueNTZq5.js → session-panel-DCRBt85z.js} +1 -1
- package/dist/assets/{useAddCell-B7_Lgd-h.js → useAddCell-M6_IuI4C.js} +1 -1
- package/dist/assets/{useCellActionButton-BxQHrbUZ.js → useCellActionButton-Ddy42rre.js} +1 -1
- package/dist/assets/{useDependencyPanelTab-oTszzY42.js → useDependencyPanelTab-RSRpRVKD.js} +1 -1
- package/dist/assets/{useNotebookActions-DFKZ18Bu.js → useNotebookActions-C1MxSBln.js} +1 -1
- package/dist/assets/{utilities.esm-BeoTGe8r.js → utilities.esm-BsBOP1QQ.js} +1 -1
- package/dist/index.html +12 -12
- package/package.json +1 -1
- package/src/components/editor/actions/useNotebookActions.tsx +2 -2
- package/src/core/export/__tests__/hooks.test.ts +72 -33
- package/src/core/export/hooks.ts +17 -8
- package/src/utils/__tests__/download.test.tsx +18 -18
- package/src/utils/download.ts +9 -11
- package/src/utils/html-to-image.ts +139 -0
- package/dist/assets/hooks-COmcm0X5.js +0 -1
- package/dist/assets/html-to-image-DiZMGN_d.js +0 -2
- package/dist/assets/index-DHsXOI_M.css +0 -2
package/src/core/export/hooks.ts
CHANGED
|
@@ -64,9 +64,13 @@ export function useAutoExport() {
|
|
|
64
64
|
|
|
65
65
|
useInterval(
|
|
66
66
|
async () => {
|
|
67
|
+
const screenshotFn = () =>
|
|
68
|
+
takeScreenshots({
|
|
69
|
+
progress: ProgressState.indeterminate(),
|
|
70
|
+
snappy: true,
|
|
71
|
+
});
|
|
67
72
|
await updateCellOutputsWithScreenshots({
|
|
68
|
-
|
|
69
|
-
takeScreenshots,
|
|
73
|
+
takeScreenshots: screenshotFn,
|
|
70
74
|
updateCellOutputs,
|
|
71
75
|
});
|
|
72
76
|
await autoExportAsIPYNB({
|
|
@@ -107,7 +111,13 @@ export function useEnrichCellOutputs() {
|
|
|
107
111
|
const [richCellsOutput, setRichCellsOutput] = useAtom(richCellsToOutputAtom);
|
|
108
112
|
const cellRuntimes = useAtomValue(cellsRuntimeAtom);
|
|
109
113
|
|
|
110
|
-
return async (
|
|
114
|
+
return async ({
|
|
115
|
+
progress,
|
|
116
|
+
snappy,
|
|
117
|
+
}: {
|
|
118
|
+
progress: ProgressState;
|
|
119
|
+
snappy: boolean;
|
|
120
|
+
}): Promise<ScreenshotResults> => {
|
|
111
121
|
const trackedCellsOutput: Record<CellId, unknown> = {};
|
|
112
122
|
|
|
113
123
|
const cellsToCaptureScreenshot: [CellId, unknown][] = [];
|
|
@@ -138,7 +148,7 @@ export function useEnrichCellOutputs() {
|
|
|
138
148
|
const results: ScreenshotResults = {};
|
|
139
149
|
for (const [cellId] of cellsToCaptureScreenshot) {
|
|
140
150
|
try {
|
|
141
|
-
const dataUrl = await getImageDataUrlForCell(cellId,
|
|
151
|
+
const dataUrl = await getImageDataUrlForCell(cellId, snappy);
|
|
142
152
|
if (!dataUrl) {
|
|
143
153
|
Logger.error(`Failed to capture screenshot for cell ${cellId}`);
|
|
144
154
|
continue;
|
|
@@ -159,13 +169,12 @@ export function useEnrichCellOutputs() {
|
|
|
159
169
|
* Utility function to take screenshots of cells with HTML outputs and update the cell outputs.
|
|
160
170
|
*/
|
|
161
171
|
export async function updateCellOutputsWithScreenshots(opts: {
|
|
162
|
-
|
|
163
|
-
takeScreenshots: (progress: ProgressState) => Promise<ScreenshotResults>;
|
|
172
|
+
takeScreenshots: () => Promise<ScreenshotResults>;
|
|
164
173
|
updateCellOutputs: (request: UpdateCellOutputsRequest) => Promise<null>;
|
|
165
174
|
}) {
|
|
166
|
-
const {
|
|
175
|
+
const { takeScreenshots, updateCellOutputs } = opts;
|
|
167
176
|
try {
|
|
168
|
-
const cellIdsToOutput = await takeScreenshots(
|
|
177
|
+
const cellIdsToOutput = await takeScreenshots();
|
|
169
178
|
if (Objects.size(cellIdsToOutput) > 0) {
|
|
170
179
|
await updateCellOutputs({ cellIdsToOutput });
|
|
171
180
|
}
|
|
@@ -166,7 +166,7 @@ describe("getImageDataUrlForCell", () => {
|
|
|
166
166
|
);
|
|
167
167
|
});
|
|
168
168
|
|
|
169
|
-
it("should add printing classes before capture when
|
|
169
|
+
it("should add printing classes before capture when snappy is false", async () => {
|
|
170
170
|
vi.mocked(toPng).mockImplementation(async () => {
|
|
171
171
|
// Check classes are applied during capture
|
|
172
172
|
expect(mockElement.classList.contains("printing-output")).toBe(true);
|
|
@@ -175,36 +175,36 @@ describe("getImageDataUrlForCell", () => {
|
|
|
175
175
|
return mockDataUrl;
|
|
176
176
|
});
|
|
177
177
|
|
|
178
|
-
await getImageDataUrlForCell("cell-1" as CellId,
|
|
178
|
+
await getImageDataUrlForCell("cell-1" as CellId, false);
|
|
179
179
|
});
|
|
180
180
|
|
|
181
|
-
it("should remove printing classes after capture when
|
|
181
|
+
it("should remove printing classes after capture when snappy is false", async () => {
|
|
182
182
|
vi.mocked(toPng).mockResolvedValue(mockDataUrl);
|
|
183
183
|
|
|
184
|
-
await getImageDataUrlForCell("cell-1" as CellId,
|
|
184
|
+
await getImageDataUrlForCell("cell-1" as CellId, false);
|
|
185
185
|
|
|
186
186
|
expect(mockElement.classList.contains("printing-output")).toBe(false);
|
|
187
187
|
expect(document.body.classList.contains("printing")).toBe(false);
|
|
188
188
|
});
|
|
189
189
|
|
|
190
|
-
it("should add printing-output but NOT body.printing when
|
|
190
|
+
it("should add printing-output but NOT body.printing when snappy is true", async () => {
|
|
191
191
|
vi.mocked(toPng).mockImplementation(async () => {
|
|
192
192
|
// printing-output should still be added to the element
|
|
193
193
|
expect(mockElement.classList.contains("printing-output")).toBe(true);
|
|
194
|
-
// but body.printing should NOT be added
|
|
194
|
+
// but body.printing should NOT be added when snappy mode is on
|
|
195
195
|
expect(document.body.classList.contains("printing")).toBe(false);
|
|
196
196
|
expect(mockElement.style.overflow).toBe("auto");
|
|
197
197
|
return mockDataUrl;
|
|
198
198
|
});
|
|
199
199
|
|
|
200
|
-
await getImageDataUrlForCell("cell-1" as CellId,
|
|
200
|
+
await getImageDataUrlForCell("cell-1" as CellId, true);
|
|
201
201
|
});
|
|
202
202
|
|
|
203
|
-
it("should cleanup printing-output when
|
|
203
|
+
it("should cleanup printing-output when snappy is true", async () => {
|
|
204
204
|
mockElement.style.overflow = "hidden";
|
|
205
205
|
vi.mocked(toPng).mockResolvedValue(mockDataUrl);
|
|
206
206
|
|
|
207
|
-
await getImageDataUrlForCell("cell-1" as CellId,
|
|
207
|
+
await getImageDataUrlForCell("cell-1" as CellId, true);
|
|
208
208
|
|
|
209
209
|
expect(mockElement.classList.contains("printing-output")).toBe(false);
|
|
210
210
|
expect(document.body.classList.contains("printing")).toBe(false);
|
|
@@ -239,7 +239,7 @@ describe("getImageDataUrlForCell", () => {
|
|
|
239
239
|
expect(mockElement.style.overflow).toBe("scroll");
|
|
240
240
|
});
|
|
241
241
|
|
|
242
|
-
it("should maintain body.printing during concurrent captures when
|
|
242
|
+
it("should maintain body.printing during concurrent captures when snappy is false", async () => {
|
|
243
243
|
// Create a second element
|
|
244
244
|
const mockElement2 = document.createElement("div");
|
|
245
245
|
mockElement2.id = CellOutputId.create("cell-2" as CellId);
|
|
@@ -273,9 +273,9 @@ describe("getImageDataUrlForCell", () => {
|
|
|
273
273
|
return mockDataUrl;
|
|
274
274
|
});
|
|
275
275
|
|
|
276
|
-
// Start both captures concurrently with
|
|
277
|
-
const capture1 = getImageDataUrlForCell("cell-1" as CellId,
|
|
278
|
-
const capture2 = getImageDataUrlForCell("cell-2" as CellId,
|
|
276
|
+
// Start both captures concurrently with snappy = false (body.printing should be added)
|
|
277
|
+
const capture1 = getImageDataUrlForCell("cell-1" as CellId, false);
|
|
278
|
+
const capture2 = getImageDataUrlForCell("cell-2" as CellId, false);
|
|
279
279
|
|
|
280
280
|
// Let second capture complete first
|
|
281
281
|
resolveSecond!();
|
|
@@ -297,21 +297,21 @@ describe("getImageDataUrlForCell", () => {
|
|
|
297
297
|
mockElement2.remove();
|
|
298
298
|
});
|
|
299
299
|
|
|
300
|
-
it("should not interfere with body.printing during concurrent captures when
|
|
300
|
+
it("should not interfere with body.printing during concurrent captures when snappy is true", async () => {
|
|
301
301
|
// Create a second element
|
|
302
302
|
const mockElement2 = document.createElement("div");
|
|
303
303
|
mockElement2.id = CellOutputId.create("cell-2" as CellId);
|
|
304
304
|
document.body.append(mockElement2);
|
|
305
305
|
|
|
306
306
|
vi.mocked(toPng).mockImplementation(async () => {
|
|
307
|
-
// body.printing should never be added when
|
|
307
|
+
// body.printing should never be added when snappy is true
|
|
308
308
|
expect(document.body.classList.contains("printing")).toBe(false);
|
|
309
309
|
return mockDataUrl;
|
|
310
310
|
});
|
|
311
311
|
|
|
312
|
-
// Start both captures concurrently with
|
|
313
|
-
const capture1 = getImageDataUrlForCell("cell-1" as CellId,
|
|
314
|
-
const capture2 = getImageDataUrlForCell("cell-2" as CellId,
|
|
312
|
+
// Start both captures concurrently with snappy = true (body.printing should NOT be added)
|
|
313
|
+
const capture1 = getImageDataUrlForCell("cell-1" as CellId, true);
|
|
314
|
+
const capture2 = getImageDataUrlForCell("cell-2" as CellId, true);
|
|
315
315
|
|
|
316
316
|
await Promise.all([capture1, capture2]);
|
|
317
317
|
|
package/src/utils/download.ts
CHANGED
|
@@ -70,16 +70,15 @@ function releaseBodyPrinting() {
|
|
|
70
70
|
* Prepare a cell element for screenshot capture.
|
|
71
71
|
*
|
|
72
72
|
* @param element - The cell output element to prepare
|
|
73
|
-
* @param
|
|
74
|
-
* This can cause layout shifts that cause the page to scroll.
|
|
73
|
+
* @param snappy - When true, avoids layout shifts and speeds up the capture.
|
|
75
74
|
* @returns A cleanup function to restore the element's original state
|
|
76
75
|
*/
|
|
77
76
|
function prepareCellElementForScreenshot(
|
|
78
77
|
element: HTMLElement,
|
|
79
|
-
|
|
78
|
+
snappy: boolean,
|
|
80
79
|
) {
|
|
81
80
|
element.classList.add("printing-output");
|
|
82
|
-
if (
|
|
81
|
+
if (!snappy) {
|
|
83
82
|
acquireBodyPrinting();
|
|
84
83
|
}
|
|
85
84
|
const originalOverflow = element.style.overflow;
|
|
@@ -87,7 +86,7 @@ function prepareCellElementForScreenshot(
|
|
|
87
86
|
|
|
88
87
|
return () => {
|
|
89
88
|
element.classList.remove("printing-output");
|
|
90
|
-
if (
|
|
89
|
+
if (!snappy) {
|
|
91
90
|
releaseBodyPrinting();
|
|
92
91
|
}
|
|
93
92
|
element.style.overflow = originalOverflow;
|
|
@@ -100,13 +99,12 @@ const THRESHOLD_TIME_MS = 500;
|
|
|
100
99
|
* Capture a cell output as a PNG data URL.
|
|
101
100
|
*
|
|
102
101
|
* @param cellId - The ID of the cell to capture
|
|
103
|
-
* @param
|
|
104
|
-
* This can cause layout shifts that cause the page to scroll.
|
|
102
|
+
* @param snappy - When true, uses a faster method to capture the image. Avoids layout shifts.
|
|
105
103
|
* @returns The PNG as a data URL, or undefined if the cell element wasn't found
|
|
106
104
|
*/
|
|
107
105
|
export async function getImageDataUrlForCell(
|
|
108
106
|
cellId: CellId,
|
|
109
|
-
|
|
107
|
+
snappy = false,
|
|
110
108
|
): Promise<string | undefined> {
|
|
111
109
|
const element = findElementForCell(cellId);
|
|
112
110
|
if (!element) {
|
|
@@ -118,11 +116,11 @@ export async function getImageDataUrlForCell(
|
|
|
118
116
|
return iframeDataUrl;
|
|
119
117
|
}
|
|
120
118
|
|
|
121
|
-
const cleanup = prepareCellElementForScreenshot(element,
|
|
119
|
+
const cleanup = prepareCellElementForScreenshot(element, snappy);
|
|
122
120
|
|
|
123
121
|
try {
|
|
124
122
|
const startTime = Date.now();
|
|
125
|
-
const dataUrl = await toPng(element);
|
|
123
|
+
const dataUrl = await toPng(element, undefined, snappy);
|
|
126
124
|
const timeTaken = Date.now() - startTime;
|
|
127
125
|
if (timeTaken > THRESHOLD_TIME_MS) {
|
|
128
126
|
Logger.debug(
|
|
@@ -159,7 +157,7 @@ export async function downloadCellOutputAsImage(
|
|
|
159
157
|
await downloadHTMLAsImage({
|
|
160
158
|
element,
|
|
161
159
|
filename,
|
|
162
|
-
prepare: () => prepareCellElementForScreenshot(element,
|
|
160
|
+
prepare: () => prepareCellElementForScreenshot(element, false),
|
|
163
161
|
});
|
|
164
162
|
}
|
|
165
163
|
|
|
@@ -4,6 +4,143 @@ import { Logger } from "./Logger";
|
|
|
4
4
|
|
|
5
5
|
export type HtmlToImageOptions = Parameters<typeof htmlToImageToPng>[1];
|
|
6
6
|
|
|
7
|
+
// For improved performance, we include these styles that are likely to be present on the element.
|
|
8
|
+
export const necessaryStyleProperties = [
|
|
9
|
+
// Sizing
|
|
10
|
+
"width",
|
|
11
|
+
"height",
|
|
12
|
+
"min-width",
|
|
13
|
+
"min-height",
|
|
14
|
+
"max-width",
|
|
15
|
+
"max-height",
|
|
16
|
+
"box-sizing",
|
|
17
|
+
"aspect-ratio",
|
|
18
|
+
|
|
19
|
+
// Display & Layout
|
|
20
|
+
"display",
|
|
21
|
+
"position",
|
|
22
|
+
"top",
|
|
23
|
+
"left",
|
|
24
|
+
"bottom",
|
|
25
|
+
"right",
|
|
26
|
+
"z-index",
|
|
27
|
+
"float",
|
|
28
|
+
"clear",
|
|
29
|
+
|
|
30
|
+
// Flexbox
|
|
31
|
+
"flex",
|
|
32
|
+
"flex-direction",
|
|
33
|
+
"flex-wrap",
|
|
34
|
+
"flex-grow",
|
|
35
|
+
"flex-shrink",
|
|
36
|
+
"flex-basis",
|
|
37
|
+
"align-items",
|
|
38
|
+
"align-self",
|
|
39
|
+
"justify-content",
|
|
40
|
+
"gap",
|
|
41
|
+
"order",
|
|
42
|
+
|
|
43
|
+
// Grid
|
|
44
|
+
"grid-template-columns",
|
|
45
|
+
"grid-template-rows",
|
|
46
|
+
"grid-column",
|
|
47
|
+
"grid-row",
|
|
48
|
+
"row-gap",
|
|
49
|
+
"column-gap",
|
|
50
|
+
|
|
51
|
+
// Spacing
|
|
52
|
+
"margin",
|
|
53
|
+
"margin-top",
|
|
54
|
+
"margin-right",
|
|
55
|
+
"margin-bottom",
|
|
56
|
+
"margin-left",
|
|
57
|
+
"padding",
|
|
58
|
+
"padding-top",
|
|
59
|
+
"padding-right",
|
|
60
|
+
"padding-bottom",
|
|
61
|
+
"padding-left",
|
|
62
|
+
|
|
63
|
+
// Typography
|
|
64
|
+
"font",
|
|
65
|
+
"font-family",
|
|
66
|
+
"font-size",
|
|
67
|
+
"font-weight",
|
|
68
|
+
"font-style",
|
|
69
|
+
"line-height",
|
|
70
|
+
"letter-spacing",
|
|
71
|
+
"word-spacing",
|
|
72
|
+
"text-align",
|
|
73
|
+
"text-decoration",
|
|
74
|
+
"text-transform",
|
|
75
|
+
"text-indent",
|
|
76
|
+
"text-shadow",
|
|
77
|
+
"white-space",
|
|
78
|
+
"text-wrap",
|
|
79
|
+
"word-break",
|
|
80
|
+
"text-overflow",
|
|
81
|
+
"vertical-align",
|
|
82
|
+
"color",
|
|
83
|
+
|
|
84
|
+
// Background
|
|
85
|
+
"background",
|
|
86
|
+
"background-color",
|
|
87
|
+
"background-image",
|
|
88
|
+
"background-size",
|
|
89
|
+
"background-position",
|
|
90
|
+
"background-repeat",
|
|
91
|
+
"background-clip",
|
|
92
|
+
|
|
93
|
+
// Borders
|
|
94
|
+
"border",
|
|
95
|
+
"border-width",
|
|
96
|
+
"border-style",
|
|
97
|
+
"border-color",
|
|
98
|
+
"border-top",
|
|
99
|
+
"border-right",
|
|
100
|
+
"border-bottom",
|
|
101
|
+
"border-left",
|
|
102
|
+
"border-radius",
|
|
103
|
+
"outline",
|
|
104
|
+
|
|
105
|
+
// Effects
|
|
106
|
+
"box-shadow",
|
|
107
|
+
"text-shadow",
|
|
108
|
+
"opacity",
|
|
109
|
+
"filter",
|
|
110
|
+
"backdrop-filter",
|
|
111
|
+
"mix-blend-mode",
|
|
112
|
+
"transform",
|
|
113
|
+
"clip-path",
|
|
114
|
+
|
|
115
|
+
// Overflow & Visibility
|
|
116
|
+
// We don't include overflow properties because they can include scrollbars
|
|
117
|
+
// "overflow",
|
|
118
|
+
// "overflow-x",
|
|
119
|
+
// "overflow-y",
|
|
120
|
+
"visibility",
|
|
121
|
+
|
|
122
|
+
// SVG
|
|
123
|
+
"fill",
|
|
124
|
+
"stroke",
|
|
125
|
+
"stroke-width",
|
|
126
|
+
|
|
127
|
+
// Images & Objects
|
|
128
|
+
"object-fit",
|
|
129
|
+
"object-position",
|
|
130
|
+
|
|
131
|
+
// Lists
|
|
132
|
+
"list-style",
|
|
133
|
+
"list-style-type",
|
|
134
|
+
|
|
135
|
+
// Tables
|
|
136
|
+
"border-collapse",
|
|
137
|
+
"border-spacing",
|
|
138
|
+
|
|
139
|
+
// Misc
|
|
140
|
+
"content",
|
|
141
|
+
"cursor",
|
|
142
|
+
];
|
|
143
|
+
|
|
7
144
|
/**
|
|
8
145
|
* Default options for html-to-image conversions.
|
|
9
146
|
* These handle common edge cases like filtering out toolbars and logging errors.
|
|
@@ -39,9 +176,11 @@ export const defaultHtmlToImageOptions: HtmlToImageOptions = {
|
|
|
39
176
|
export async function toPng(
|
|
40
177
|
element: HTMLElement,
|
|
41
178
|
options?: HtmlToImageOptions,
|
|
179
|
+
snappy?: boolean,
|
|
42
180
|
): Promise<string> {
|
|
43
181
|
return htmlToImageToPng(element, {
|
|
44
182
|
...defaultHtmlToImageOptions,
|
|
183
|
+
includeStyleProperties: snappy ? necessaryStyleProperties : undefined,
|
|
45
184
|
...options,
|
|
46
185
|
});
|
|
47
186
|
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{l as S,p as j,u as E}from"./useEvent-DO6uJBas.js";import{o as T}from"./cells-Mf-pdsEh.js";import{t as I}from"./compiler-runtime-DeeZ7FnK.js";import{a as A,d as x}from"./hotkeys-BHHWjLlp.js";import{i as N}from"./utils-DXvhzCGS.js";import{A as _,w as F}from"./config-CIrPQIbt.js";import{r as P}from"./requests-BsVD4CdD.js";import{f as V}from"./layout-BJ9AHITN.js";import{l as D,o as $}from"./download-Cphyle83.js";import{t as z}from"./use-toast-rmUWldD_.js";import{t as C}from"./useInterval-Cu9ChZf-.js";var B=I(),k=5e3;function H(){let t=(0,B.c)(14),r=E(N),{state:d}=E(F),n=r.auto_download.includes("markdown"),o=r.auto_download.includes("html"),s=r.auto_download.includes("ipynb"),c=d===_.OPEN,l=!n||!c,p=!o||!c,u=!s||!c,{autoExportAsHTML:a,autoExportAsIPYNB:e,autoExportAsMarkdown:i,updateCellOutputs:m}=P(),b=M(),f;t[0]===i?f=t[1]:(f=async()=>{await i({download:!1})},t[0]=i,t[1]=f);let w;t[2]===l?w=t[3]:(w={delayMs:k,whenVisible:!0,disabled:l},t[2]=l,t[3]=w),C(f,w);let h;t[4]===a?h=t[5]:(h=async()=>{await a({download:!1,includeCode:!0,files:V.INSTANCE.filenames()})},t[4]=a,t[5]=h);let v;t[6]===p?v=t[7]:(v={delayMs:k,whenVisible:!0,disabled:p},t[6]=p,t[7]=v),C(h,v);let y;t[8]!==e||t[9]!==b||t[10]!==m?(y=async()=>{await O({progress:D.indeterminate(),takeScreenshots:b,updateCellOutputs:m}),await e({download:!1})},t[8]=e,t[9]=b,t[10]=m,t[11]=y):y=t[11];let g;t[12]===u?g=t[13]:(g={delayMs:k,whenVisible:!0,disabled:u,skipIfRunning:!0},t[12]=u,t[13]=g),C(y,g)}var L=j({}),R=new Set(["text/html","application/vnd.vegalite.v5+json","application/vnd.vega.v5+json","application/vnd.vegalite.v6+json","application/vnd.vega.v6+json"]);function M(){let[t,r]=S(L),d=E(T);return async n=>{var p,u;let o={},s=[];for(let[a,e]of A.entries(d)){let i=(p=e.output)==null?void 0:p.data,m=t[a]!==i;o[a]=i,(u=e.output)!=null&&u.mimetype&&R.has(e.output.mimetype)&&i&&m&&s.push([a,e])}if(r(o),s.length===0)return{};let c=s.length;n.addTotal(c);let l={};for(let[a]of s)try{let e=await $(a,!1);if(!e){x.error(`Failed to capture screenshot for cell ${a}`);continue}l[a]=["image/png",e]}catch(e){x.error(`Error screenshotting cell ${a}:`,e)}finally{n.increment(1)}return l}}async function O(t){let{progress:r,takeScreenshots:d,updateCellOutputs:n}=t;try{let o=await d(r);A.size(o)>0&&await n({cellIdsToOutput:o})}catch(o){x.error("Error updating cell outputs with screenshots:",o),z({title:"Failed to capture cell outputs",description:"Some outputs may not appear in the PDF. Continuing with export.",variant:"danger"})}}export{H as n,M as r,O as t};
|
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
import{i as B}from"./useEvent-DO6uJBas.js";import{bn as G,ri as $,y as Q}from"./cells-Mf-pdsEh.js";import{d as v}from"./hotkeys-BHHWjLlp.js";import{t as R}from"./requests-BsVD4CdD.js";function I({moduleName:e,variableName:t,onAddImport:r,appStore:n=B}){if(t in n.get(G))return!1;let{cellData:i,cellIds:a}=n.get(Q),o=RegExp(`import[ ]+${e}[ ]+as[ ]+${t}`,"g");for(let l of a.inOrderIds)if(o.test(i[l].code))return!1;return r(`import ${e} as ${t}`),!0}function X({autoInstantiate:e,createNewCell:t,fromCellId:r,before:n}){let i=R(),a=null;return I({moduleName:"marimo",variableName:"mo",onAddImport:o=>{a=$.create(),t({cellId:r??"__end__",before:n??!1,code:o,lastCodeRun:e?o:void 0,newCellId:a,skipIfCodeExists:!0,autoFocus:!1}),e&&i.sendRun({cellIds:[a],codes:[o]})}})?a:null}function J({autoInstantiate:e,createNewCell:t,fromCellId:r}){let n=R(),i=null;return I({moduleName:"altair",variableName:"alt",onAddImport:a=>{i=$.create(),t({cellId:r??"__end__",before:!1,code:a,lastCodeRun:e?a:void 0,newCellId:i,skipIfCodeExists:!0,autoFocus:!1}),e&&n.sendRun({cellIds:[i],codes:[a]})}})?i:null}function K(e,t){if(e.match(/^[a-z]+:\/\//i))return e;if(e.match(/^\/\//))return window.location.protocol+e;if(e.match(/^[a-z]+:/i))return e;let r=document.implementation.createHTMLDocument(),n=r.createElement("base"),i=r.createElement("a");return r.head.appendChild(n),r.body.appendChild(i),t&&(n.href=t),i.href=e,i.href}const Y=(()=>{let e=0,t=()=>`0000${(Math.random()*36**4<<0).toString(36)}`.slice(-4);return()=>(e+=1,`u${t()}${e}`)})();function d(e){let t=[];for(let r=0,n=e.length;r<n;r++)t.push(e[r]);return t}var g=null;function P(e={}){return g||(e.includeStyleProperties?(g=e.includeStyleProperties,g):(g=d(window.getComputedStyle(document.documentElement)),g))}function p(e,t){let r=(e.ownerDocument.defaultView||window).getComputedStyle(e).getPropertyValue(t);return r?parseFloat(r.replace("px","")):0}function Z(e){let t=p(e,"border-left-width"),r=p(e,"border-right-width");return e.clientWidth+t+r}function ee(e){let t=p(e,"border-top-width"),r=p(e,"border-bottom-width");return e.clientHeight+t+r}function N(e,t={}){return{width:t.width||Z(e),height:t.height||ee(e)}}function te(){let e,t;try{t=process}catch{}let r=t&&t.env?t.env.devicePixelRatio:null;return r&&(e=parseInt(r,10),Number.isNaN(e)&&(e=1)),e||window.devicePixelRatio||1}var c=16384;function re(e){(e.width>c||e.height>c)&&(e.width>c&&e.height>c?e.width>e.height?(e.height*=c/e.width,e.width=c):(e.width*=c/e.height,e.height=c):e.width>c?(e.height*=c/e.width,e.width=c):(e.width*=c/e.height,e.height=c))}function w(e){return new Promise((t,r)=>{let n=new Image;n.onload=()=>{n.decode().then(()=>{requestAnimationFrame(()=>t(n))})},n.onerror=r,n.crossOrigin="anonymous",n.decoding="async",n.src=e})}async function ne(e){return Promise.resolve().then(()=>new XMLSerializer().serializeToString(e)).then(encodeURIComponent).then(t=>`data:image/svg+xml;charset=utf-8,${t}`)}async function ie(e,t,r){let n="http://www.w3.org/2000/svg",i=document.createElementNS(n,"svg"),a=document.createElementNS(n,"foreignObject");return i.setAttribute("width",`${t}`),i.setAttribute("height",`${r}`),i.setAttribute("viewBox",`0 0 ${t} ${r}`),a.setAttribute("width","100%"),a.setAttribute("height","100%"),a.setAttribute("x","0"),a.setAttribute("y","0"),a.setAttribute("externalResourcesRequired","true"),i.appendChild(a),a.appendChild(e),ne(i)}const u=(e,t)=>{if(e instanceof t)return!0;let r=Object.getPrototypeOf(e);return r===null?!1:r.constructor.name===t.name||u(r,t)};function ae(e){let t=e.getPropertyValue("content");return`${e.cssText} content: '${t.replace(/'|"/g,"")}';`}function oe(e,t){return P(t).map(r=>`${r}: ${e.getPropertyValue(r)}${e.getPropertyPriority(r)?" !important":""};`).join(" ")}function le(e,t,r,n){let i=`.${e}:${t}`,a=r.cssText?ae(r):oe(r,n);return document.createTextNode(`${i}{${a}}`)}function T(e,t,r,n){let i=window.getComputedStyle(e,r),a=i.getPropertyValue("content");if(a===""||a==="none")return;let o=Y();try{t.className=`${t.className} ${o}`}catch{return}let l=document.createElement("style");l.appendChild(le(o,r,i,n)),t.appendChild(l)}function se(e,t,r){T(e,t,":before",r),T(e,t,":after",r)}var A="application/font-woff",L="image/jpeg",ce={woff:A,woff2:A,ttf:"application/font-truetype",eot:"application/vnd.ms-fontobject",png:"image/png",jpg:L,jpeg:L,gif:"image/gif",tiff:"image/tiff",svg:"image/svg+xml",webp:"image/webp"};function ue(e){let t=/\.([^./]*?)$/g.exec(e);return t?t[1]:""}function E(e){return ce[ue(e).toLowerCase()]||""}function de(e){return e.split(/,/)[1]}function S(e){return e.search(/^(data:)/)!==-1}function k(e,t){return`data:${t};base64,${e}`}async function H(e,t,r){let n=await fetch(e,t);if(n.status===404)throw Error(`Resource "${n.url}" not found`);let i=await n.blob();return new Promise((a,o)=>{let l=new FileReader;l.onerror=o,l.onloadend=()=>{try{a(r({res:n,result:l.result}))}catch(s){o(s)}},l.readAsDataURL(i)})}var C={};function he(e,t,r){let n=e.replace(/\?.*/,"");return r&&(n=e),/ttf|otf|eot|woff2?/i.test(n)&&(n=n.replace(/.*\//,"")),t?`[${t}]${n}`:n}async function x(e,t,r){let n=he(e,t,r.includeQueryParams);if(C[n]!=null)return C[n];r.cacheBust&&(e+=(/\?/.test(e)?"&":"?")+new Date().getTime());let i;try{i=k(await H(e,r.fetchRequestInit,({res:a,result:o})=>(t||(t=a.headers.get("Content-Type")||""),de(o))),t)}catch(a){i=r.imagePlaceholder||"";let o=`Failed to fetch resource: ${e}`;a&&(o=typeof a=="string"?a:a.message),o&&console.warn(o)}return C[n]=i,i}async function fe(e){let t=e.toDataURL();return t==="data:,"?e.cloneNode(!1):w(t)}async function me(e,t){if(e.currentSrc){let n=document.createElement("canvas"),i=n.getContext("2d");return n.width=e.clientWidth,n.height=e.clientHeight,i==null||i.drawImage(e,0,0,n.width,n.height),w(n.toDataURL())}let r=e.poster;return w(await x(r,E(r),t))}async function ge(e,t){var r;try{if((r=e==null?void 0:e.contentDocument)!=null&&r.body)return await y(e.contentDocument.body,t,!0)}catch{}return e.cloneNode(!1)}async function pe(e,t){return u(e,HTMLCanvasElement)?fe(e):u(e,HTMLVideoElement)?me(e,t):u(e,HTMLIFrameElement)?ge(e,t):e.cloneNode(F(e))}var we=e=>e.tagName!=null&&e.tagName.toUpperCase()==="SLOT",F=e=>e.tagName!=null&&e.tagName.toUpperCase()==="SVG";async function ye(e,t,r){if(F(t))return t;let n=[];return n=we(e)&&e.assignedNodes?d(e.assignedNodes()):d((e.shadowRoot??e).childNodes),n.length===0||u(e,HTMLVideoElement)||await n.reduce((i,a)=>i.then(()=>y(a,r)).then(o=>{o&&t.appendChild(o)}),Promise.resolve()),t}function be(e,t,r){let n=t.style;if(!n)return;let i=window.getComputedStyle(e);i.cssText?(n.cssText=i.cssText,n.transformOrigin=i.transformOrigin):P(r).forEach(a=>{let o=i.getPropertyValue(a);a==="font-size"&&o.endsWith("px")&&(o=`${Math.floor(parseFloat(o.substring(0,o.length-2)))-.1}px`),u(e,HTMLIFrameElement)&&a==="display"&&o==="inline"&&(o="block"),a==="d"&&t.getAttribute("d")&&(o=`path(${t.getAttribute("d")})`),n.setProperty(a,o,i.getPropertyPriority(a))})}function Ee(e,t){u(e,HTMLTextAreaElement)&&(t.innerHTML=e.value),u(e,HTMLInputElement)&&t.setAttribute("value",e.value)}function Se(e,t){if(u(e,HTMLSelectElement)){let r=t,n=Array.from(r.children).find(i=>e.value===i.getAttribute("value"));n&&n.setAttribute("selected","")}}function Ce(e,t,r){return u(t,Element)&&(be(e,t,r),se(e,t,r),Ee(e,t),Se(e,t)),t}async function xe(e,t){let r=e.querySelectorAll?e.querySelectorAll("use"):[];if(r.length===0)return e;let n={};for(let a=0;a<r.length;a++){let o=r[a].getAttribute("xlink:href");if(o){let l=e.querySelector(o),s=document.querySelector(o);!l&&s&&!n[o]&&(n[o]=await y(s,t,!0))}}let i=Object.values(n);if(i.length){let a="http://www.w3.org/1999/xhtml",o=document.createElementNS(a,"svg");o.setAttribute("xmlns",a),o.style.position="absolute",o.style.width="0",o.style.height="0",o.style.overflow="hidden",o.style.display="none";let l=document.createElementNS(a,"defs");o.appendChild(l);for(let s=0;s<i.length;s++)l.appendChild(i[s]);e.appendChild(o)}return e}async function y(e,t,r){return!r&&t.filter&&!t.filter(e)?null:Promise.resolve(e).then(n=>pe(n,t)).then(n=>ye(e,n,t)).then(n=>Ce(e,n,t)).then(n=>xe(n,t))}var M=/url\((['"]?)([^'"]+?)\1\)/g,$e=/url\([^)]+\)\s*format\((["']?)([^"']+)\1\)/g,ve=/src:\s*(?:url\([^)]+\)\s*format\([^)]+\)[,;]\s*)+/g;function Re(e){let t=e.replace(/([.*+?^${}()|\[\]\/\\])/g,"\\$1");return RegExp(`(url\\(['"]?)(${t})(['"]?\\))`,"g")}function Ie(e){let t=[];return e.replace(M,(r,n,i)=>(t.push(i),r)),t.filter(r=>!S(r))}async function Pe(e,t,r,n,i){try{let a=r?K(t,r):t,o=E(t),l;return l=i?k(await i(a),o):await x(a,o,n),e.replace(Re(t),`$1${l}$3`)}catch{}return e}function Ne(e,{preferredFontFormat:t}){return t?e.replace(ve,r=>{for(;;){let[n,,i]=$e.exec(r)||[];if(!i)return"";if(i===t)return`src: ${n};`}}):e}function V(e){return e.search(M)!==-1}async function D(e,t,r){if(!V(e))return e;let n=Ne(e,r);return Ie(n).reduce((i,a)=>i.then(o=>Pe(o,a,t,r)),Promise.resolve(n))}async function f(e,t,r){var i;let n=(i=t.style)==null?void 0:i.getPropertyValue(e);if(n){let a=await D(n,null,r);return t.style.setProperty(e,a,t.style.getPropertyPriority(e)),!0}return!1}async function Te(e,t){await f("background",e,t)||await f("background-image",e,t),await f("mask",e,t)||await f("-webkit-mask",e,t)||await f("mask-image",e,t)||await f("-webkit-mask-image",e,t)}async function Ae(e,t){let r=u(e,HTMLImageElement);if(!(r&&!S(e.src))&&!(u(e,SVGImageElement)&&!S(e.href.baseVal)))return;let n=r?e.src:e.href.baseVal,i=await x(n,E(n),t);await new Promise((a,o)=>{e.onload=a,e.onerror=t.onImageErrorHandler?(...s)=>{try{a(t.onImageErrorHandler(...s))}catch(h){o(h)}}:o;let l=e;l.decode&&(l.decode=a),l.loading==="lazy"&&(l.loading="eager"),r?(e.srcset="",e.src=i):e.href.baseVal=i})}async function Le(e,t){let r=d(e.childNodes).map(n=>O(n,t));await Promise.all(r).then(()=>e)}async function O(e,t){u(e,Element)&&(await Te(e,t),await Ae(e,t),await Le(e,t))}function ke(e,t){let{style:r}=e;t.backgroundColor&&(r.backgroundColor=t.backgroundColor),t.width&&(r.width=`${t.width}px`),t.height&&(r.height=`${t.height}px`);let n=t.style;return n!=null&&Object.keys(n).forEach(i=>{r[i]=n[i]}),e}var _={};async function j(e){let t=_[e];return t??(t={url:e,cssText:await(await fetch(e)).text()},_[e]=t,t)}async function U(e,t){let r=e.cssText,n=/url\(["']?([^"')]+)["']?\)/g,i=(r.match(/url\([^)]+\)/g)||[]).map(async a=>{let o=a.replace(n,"$1");return o.startsWith("https://")||(o=new URL(o,e.url).href),H(o,t.fetchRequestInit,({result:l})=>(r=r.replace(a,`url(${l})`),[a,l]))});return Promise.all(i).then(()=>r)}function q(e){if(e==null)return[];let t=[],r=e.replace(/(\/\*[\s\S]*?\*\/)/gi,""),n=RegExp("((@.*?keyframes [\\s\\S]*?){([\\s\\S]*?}\\s*?)})","gi");for(;;){let o=n.exec(r);if(o===null)break;t.push(o[0])}r=r.replace(n,"");let i=/@import[\s\S]*?url\([^)]*\)[\s\S]*?;/gi,a=RegExp("((\\s*?(?:\\/\\*[\\s\\S]*?\\*\\/)?\\s*?@media[\\s\\S]*?){([\\s\\S]*?)}\\s*?})|(([\\s\\S]*?){([\\s\\S]*?)})","gi");for(;;){let o=i.exec(r);if(o===null){if(o=a.exec(r),o===null)break;i.lastIndex=a.lastIndex}else a.lastIndex=i.lastIndex;t.push(o[0])}return t}async function He(e,t){let r=[],n=[];return e.forEach(i=>{if("cssRules"in i)try{d(i.cssRules||[]).forEach((a,o)=>{if(a.type===CSSRule.IMPORT_RULE){let l=o+1,s=a.href,h=j(s).then(m=>U(m,t)).then(m=>q(m).forEach(b=>{try{i.insertRule(b,b.startsWith("@import")?l+=1:i.cssRules.length)}catch(W){console.error("Error inserting rule from remote css",{rule:b,error:W})}})).catch(m=>{console.error("Error loading remote css",m.toString())});n.push(h)}})}catch(a){let o=e.find(l=>l.href==null)||document.styleSheets[0];i.href!=null&&n.push(j(i.href).then(l=>U(l,t)).then(l=>q(l).forEach(s=>{o.insertRule(s,o.cssRules.length)})).catch(l=>{console.error("Error loading remote stylesheet",l)})),console.error("Error inlining remote css file",a)}}),Promise.all(n).then(()=>(e.forEach(i=>{if("cssRules"in i)try{d(i.cssRules||[]).forEach(a=>{r.push(a)})}catch(a){console.error(`Error while reading CSS rules from ${i.href}`,a)}}),r))}function Fe(e){return e.filter(t=>t.type===CSSRule.FONT_FACE_RULE).filter(t=>V(t.style.getPropertyValue("src")))}async function Me(e,t){if(e.ownerDocument==null)throw Error("Provided element is not within a Document");return Fe(await He(d(e.ownerDocument.styleSheets),t))}function z(e){return e.trim().replace(/["']/g,"")}function Ve(e){let t=new Set;function r(n){(n.style.fontFamily||getComputedStyle(n).fontFamily).split(",").forEach(i=>{t.add(z(i))}),Array.from(n.children).forEach(i=>{i instanceof HTMLElement&&r(i)})}return r(e),t}async function De(e,t){let r=await Me(e,t),n=Ve(e);return(await Promise.all(r.filter(i=>n.has(z(i.style.fontFamily))).map(i=>{let a=i.parentStyleSheet?i.parentStyleSheet.href:null;return D(i.cssText,a,t)}))).join(`
|
|
2
|
-
`)}async function Oe(e,t){let r=t.fontEmbedCSS==null?t.skipFonts?null:await De(e,t):t.fontEmbedCSS;if(r){let n=document.createElement("style"),i=document.createTextNode(r);n.appendChild(i),e.firstChild?e.insertBefore(n,e.firstChild):e.appendChild(n)}}async function _e(e,t={}){let{width:r,height:n}=N(e,t),i=await y(e,t,!0);return await Oe(i,t),await O(i,t),ke(i,t),await ie(i,r,n)}async function je(e,t={}){let{width:r,height:n}=N(e,t),i=await w(await _e(e,t)),a=document.createElement("canvas"),o=a.getContext("2d"),l=t.pixelRatio||te(),s=t.canvasWidth||r,h=t.canvasHeight||n;return a.width=s*l,a.height=h*l,t.skipAutoScale||re(a),a.style.width=`${s}`,a.style.height=`${h}`,t.backgroundColor&&(o.fillStyle=t.backgroundColor,o.fillRect(0,0,a.width,a.height)),o.drawImage(i,0,0,a.width,a.height),a}async function Ue(e,t={}){return(await je(e,t)).toDataURL()}const qe={filter:e=>{try{return!("classList"in e&&(e.classList.contains("mpl-toolbar")||e.classList.contains("no-print")))}catch(t){return v.error("Error filtering node:",t),!0}},onImageErrorHandler:e=>{v.error("Error loading image:",e)}};async function ze(e,t){return Ue(e,{...qe,...t})}export{J as n,X as r,ze as t};
|