@marimo-team/islands 0.20.3-dev91 → 0.20.3-dev94
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/main.js +8 -1
- package/package.json +1 -1
- package/src/components/storage/components.tsx +2 -0
- package/src/core/cells/__tests__/session.test.ts +1 -1
- package/src/core/storage/types.ts +2 -1
- package/src/plugins/core/__test__/sanitize.test.ts +47 -2
- package/src/plugins/core/sanitize.ts +4 -0
package/dist/main.js
CHANGED
|
@@ -32103,6 +32103,13 @@ ${c.sqlString}
|
|
|
32103
32103
|
svg: true,
|
|
32104
32104
|
mathMl: true
|
|
32105
32105
|
},
|
|
32106
|
+
ADD_TAGS: [
|
|
32107
|
+
"use"
|
|
32108
|
+
],
|
|
32109
|
+
ADD_ATTR: [
|
|
32110
|
+
"href",
|
|
32111
|
+
"xlink:href"
|
|
32112
|
+
],
|
|
32106
32113
|
FORCE_BODY: true,
|
|
32107
32114
|
CUSTOM_ELEMENT_HANDLING: {
|
|
32108
32115
|
tagNameCheck: /^(marimo-[A-Za-z][\w-]*|iconify-icon)$/,
|
|
@@ -70351,7 +70358,7 @@ Image URL: ${r.imageUrl}`)), contextToXml({
|
|
|
70351
70358
|
return Logger.warn("Failed to get version from mount config"), null;
|
|
70352
70359
|
}
|
|
70353
70360
|
}
|
|
70354
|
-
const marimoVersionAtom = atom(getVersionFromMountConfig() || "0.20.3-
|
|
70361
|
+
const marimoVersionAtom = atom(getVersionFromMountConfig() || "0.20.3-dev94"), showCodeInRunModeAtom = atom(true);
|
|
70355
70362
|
atom(null);
|
|
70356
70363
|
var import_compiler_runtime$88 = require_compiler_runtime();
|
|
70357
70364
|
function useKeydownOnElement(e, r) {
|
package/package.json
CHANGED
|
@@ -13,6 +13,7 @@ import {
|
|
|
13
13
|
FileSpreadsheetIcon,
|
|
14
14
|
FileTextIcon,
|
|
15
15
|
FileVideoIcon,
|
|
16
|
+
GithubIcon,
|
|
16
17
|
GlobeIcon,
|
|
17
18
|
HardDriveIcon,
|
|
18
19
|
ImageIcon,
|
|
@@ -66,6 +67,7 @@ const PROTOCOL_ICONS: Record<KnownStorageProtocol, IconEntry> = {
|
|
|
66
67
|
http: GlobeIcon,
|
|
67
68
|
file: HardDriveIcon,
|
|
68
69
|
"in-memory": DatabaseZapIcon,
|
|
70
|
+
github: GithubIcon,
|
|
69
71
|
};
|
|
70
72
|
|
|
71
73
|
export const ProtocolIcon: React.FC<{
|
|
@@ -288,9 +288,54 @@ describe("sanitizeHtml", () => {
|
|
|
288
288
|
expect(sanitizeHtml(html)).toMatchInlineSnapshot(`"<div>Text</div>"`);
|
|
289
289
|
});
|
|
290
290
|
|
|
291
|
-
test("
|
|
291
|
+
test("preserves use element in SVG", () => {
|
|
292
292
|
const html = '<svg><use xlink:href="#icon"></use></svg>';
|
|
293
|
-
expect(sanitizeHtml(html)).toMatchInlineSnapshot(
|
|
293
|
+
expect(sanitizeHtml(html)).toMatchInlineSnapshot(
|
|
294
|
+
`"<svg><use xlink:href="#icon"></use></svg>"`,
|
|
295
|
+
);
|
|
296
|
+
});
|
|
297
|
+
|
|
298
|
+
test("preserves SVG defs and use pattern", () => {
|
|
299
|
+
const html = [
|
|
300
|
+
'<svg width="60" height="60">',
|
|
301
|
+
'<circle cx="30" cy="30" r="30" fill="orange"></circle>',
|
|
302
|
+
'<defs><circle id="myCircle" cx="0" cy="0" r="10" fill="green"></circle></defs>',
|
|
303
|
+
'<use href="#myCircle" x="20" y="20"></use>',
|
|
304
|
+
"</svg>",
|
|
305
|
+
].join("");
|
|
306
|
+
expect(sanitizeHtml(html)).toMatchInlineSnapshot(
|
|
307
|
+
`"<svg width="60" height="60"><circle cx="30" cy="30" r="30" fill="orange"></circle><defs><circle id="myCircle" cx="0" cy="0" r="10" fill="green"></circle></defs><use href="#myCircle" x="20" y="20"></use></svg>"`,
|
|
308
|
+
);
|
|
309
|
+
});
|
|
310
|
+
|
|
311
|
+
test("strips javascript: href from SVG use element", () => {
|
|
312
|
+
const html = '<svg><use href="javascript:alert(1)"></use></svg>';
|
|
313
|
+
expect(sanitizeHtml(html)).toMatchInlineSnapshot(
|
|
314
|
+
`"<svg><use></use></svg>"`,
|
|
315
|
+
);
|
|
316
|
+
});
|
|
317
|
+
|
|
318
|
+
test("strips javascript: xlink:href from SVG use element", () => {
|
|
319
|
+
const html = '<svg><use xlink:href="javascript:alert(1)"></use></svg>';
|
|
320
|
+
expect(sanitizeHtml(html)).toMatchInlineSnapshot(
|
|
321
|
+
`"<svg><use></use></svg>"`,
|
|
322
|
+
);
|
|
323
|
+
});
|
|
324
|
+
|
|
325
|
+
test("preserves external href on SVG use element", () => {
|
|
326
|
+
const html =
|
|
327
|
+
'<svg><use href="https://example.com/sprite.svg#icon"></use></svg>';
|
|
328
|
+
expect(sanitizeHtml(html)).toMatchInlineSnapshot(
|
|
329
|
+
`"<svg><use href="https://example.com/sprite.svg#icon"></use></svg>"`,
|
|
330
|
+
);
|
|
331
|
+
});
|
|
332
|
+
|
|
333
|
+
test("preserves external xlink:href on SVG use element", () => {
|
|
334
|
+
const html =
|
|
335
|
+
'<svg><use xlink:href="https://example.com/sprite.svg#icon"></use></svg>';
|
|
336
|
+
expect(sanitizeHtml(html)).toMatchInlineSnapshot(
|
|
337
|
+
`"<svg><use xlink:href="https://example.com/sprite.svg#icon"></use></svg>"`,
|
|
338
|
+
);
|
|
294
339
|
});
|
|
295
340
|
|
|
296
341
|
test("removes javascript in SVG href", () => {
|
|
@@ -74,6 +74,10 @@ export function sanitizeHtml(html: string) {
|
|
|
74
74
|
const sanitizationOptions: Config = {
|
|
75
75
|
// Default to permit HTML, SVG and MathML, this limits to HTML only
|
|
76
76
|
USE_PROFILES: { html: true, svg: true, mathMl: true },
|
|
77
|
+
// Allow SVG <use> elements and their href attributes, which are needed
|
|
78
|
+
// for SVGs that reference <defs> (e.g., Matplotlib SVG output).
|
|
79
|
+
ADD_TAGS: ["use"],
|
|
80
|
+
ADD_ATTR: ["href", "xlink:href"],
|
|
77
81
|
// glue elements like style, script or others to document.body and prevent unintuitive browser behavior in several edge-cases
|
|
78
82
|
FORCE_BODY: true,
|
|
79
83
|
CUSTOM_ELEMENT_HANDLING: {
|