@marimo-team/islands 0.21.1-dev7 → 0.21.1-dev8
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 +27 -27
- package/package.json +1 -1
- package/src/core/dom/outline.ts +1 -1
- package/src/plugins/core/sanitize-html.ts +50 -0
- package/src/plugins/core/sanitize.ts +3 -49
package/dist/main.js
CHANGED
|
@@ -32214,30 +32214,6 @@ ${c.sqlString}
|
|
|
32214
32214
|
afterCursorCode: getEditorCodeAsPython(e, v)
|
|
32215
32215
|
};
|
|
32216
32216
|
}
|
|
32217
|
-
require_compiler_runtime();
|
|
32218
|
-
const hasRunAnyCellAtom = atom(false);
|
|
32219
|
-
function getInitialAppMode() {
|
|
32220
|
-
let e = store.get(initialModeAtom);
|
|
32221
|
-
return assertExists(e, "internal-error: initial mode not found"), invariant(e !== "present", "internal-error: initial mode cannot be 'present'"), e;
|
|
32222
|
-
}
|
|
32223
|
-
const viewStateAtom = atom({
|
|
32224
|
-
mode: isIslands() ? "read" : "not-set",
|
|
32225
|
-
cellAnchor: null
|
|
32226
|
-
}), initialModeAtom = atom(void 0), kioskModeAtom = atom(false);
|
|
32227
|
-
var sanitizeHtmlAtom = atom((e) => {
|
|
32228
|
-
let r = e(hasRunAnyCellAtom), c = e(autoInstantiateAtom);
|
|
32229
|
-
if (r || c) return false;
|
|
32230
|
-
let d = true;
|
|
32231
|
-
try {
|
|
32232
|
-
d = getInitialAppMode() === "read";
|
|
32233
|
-
} catch {
|
|
32234
|
-
return true;
|
|
32235
|
-
}
|
|
32236
|
-
return !d;
|
|
32237
|
-
});
|
|
32238
|
-
function useSanitizeHtml() {
|
|
32239
|
-
return useAtomValue(sanitizeHtmlAtom);
|
|
32240
|
-
}
|
|
32241
32217
|
var TEMPORARY_ATTRIBUTE = "data-temp-href-target";
|
|
32242
32218
|
purify.addHook("beforeSanitizeAttributes", (e) => {
|
|
32243
32219
|
e.tagName === "A" && (e.hasAttribute("target") || e.setAttribute("target", "_self"), e.hasAttribute("target") && e.setAttribute(TEMPORARY_ATTRIBUTE, e.getAttribute("target") || ""));
|
|
@@ -37118,9 +37094,9 @@ ${c.sqlString}
|
|
|
37118
37094
|
Logger.debug(`Doc lookup failed for "${e}"`, r2);
|
|
37119
37095
|
}
|
|
37120
37096
|
}
|
|
37121
|
-
var import_compiler_runtime$
|
|
37097
|
+
var import_compiler_runtime$152 = require_compiler_runtime();
|
|
37122
37098
|
const DocHoverTarget = (e) => {
|
|
37123
|
-
let r = (0, import_compiler_runtime$
|
|
37099
|
+
let r = (0, import_compiler_runtime$152.c)(8), { qualifiedName: c, children: d } = e, f;
|
|
37124
37100
|
r[0] === c ? f = r[1] : (f = () => {
|
|
37125
37101
|
requestOutputDocumentation(c);
|
|
37126
37102
|
}, r[0] = c, r[1] = f);
|
|
@@ -37133,6 +37109,30 @@ ${c.sqlString}
|
|
|
37133
37109
|
children: d
|
|
37134
37110
|
}), r[4] = d, r[5] = _, r[6] = v, r[7] = y) : y = r[7], y;
|
|
37135
37111
|
};
|
|
37112
|
+
require_compiler_runtime();
|
|
37113
|
+
const hasRunAnyCellAtom = atom(false);
|
|
37114
|
+
function getInitialAppMode() {
|
|
37115
|
+
let e = store.get(initialModeAtom);
|
|
37116
|
+
return assertExists(e, "internal-error: initial mode not found"), invariant(e !== "present", "internal-error: initial mode cannot be 'present'"), e;
|
|
37117
|
+
}
|
|
37118
|
+
const viewStateAtom = atom({
|
|
37119
|
+
mode: isIslands() ? "read" : "not-set",
|
|
37120
|
+
cellAnchor: null
|
|
37121
|
+
}), initialModeAtom = atom(void 0), kioskModeAtom = atom(false);
|
|
37122
|
+
var sanitizeHtmlAtom = atom((e) => {
|
|
37123
|
+
let r = e(hasRunAnyCellAtom), c = e(autoInstantiateAtom);
|
|
37124
|
+
if (r || c) return false;
|
|
37125
|
+
let d = true;
|
|
37126
|
+
try {
|
|
37127
|
+
d = getInitialAppMode() === "read";
|
|
37128
|
+
} catch {
|
|
37129
|
+
return true;
|
|
37130
|
+
}
|
|
37131
|
+
return !d;
|
|
37132
|
+
});
|
|
37133
|
+
function useSanitizeHtml() {
|
|
37134
|
+
return useAtomValue(sanitizeHtmlAtom);
|
|
37135
|
+
}
|
|
37136
37136
|
var import_compiler_runtime$150 = require_compiler_runtime(), replaceValidTags = (e) => {
|
|
37137
37137
|
if (e instanceof import_lib$1.Element && !/^[A-Za-z][\w-]*$/.test(e.name)) return import_react.createElement(import_react.Fragment);
|
|
37138
37138
|
}, removeWrappingBodyTags = (e, r) => {
|
|
@@ -70720,7 +70720,7 @@ Image URL: ${r.imageUrl}`)), contextToXml({
|
|
|
70720
70720
|
return Logger.warn("Failed to get version from mount config"), null;
|
|
70721
70721
|
}
|
|
70722
70722
|
}
|
|
70723
|
-
const marimoVersionAtom = atom(getVersionFromMountConfig() || "0.21.1-
|
|
70723
|
+
const marimoVersionAtom = atom(getVersionFromMountConfig() || "0.21.1-dev8"), showCodeInRunModeAtom = atom(true);
|
|
70724
70724
|
atom(null);
|
|
70725
70725
|
var import_compiler_runtime$89 = require_compiler_runtime();
|
|
70726
70726
|
function useKeydownOnElement(e, r) {
|
package/package.json
CHANGED
package/src/core/dom/outline.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/* Copyright 2026 Marimo. All rights reserved. */
|
|
2
2
|
|
|
3
|
-
import { sanitizeHtml } from "@/plugins/core/sanitize";
|
|
3
|
+
import { sanitizeHtml } from "@/plugins/core/sanitize-html";
|
|
4
4
|
import { invariant } from "@/utils/invariant";
|
|
5
5
|
import { Logger } from "@/utils/Logger";
|
|
6
6
|
import type { Outline, OutlineItem } from "../cells/outline";
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
/* Copyright 2026 Marimo. All rights reserved. */
|
|
2
|
+
import DOMPurify, { type Config } from "dompurify";
|
|
3
|
+
|
|
4
|
+
// preserve target=_blank https://github.com/cure53/DOMPurify/issues/317#issuecomment-912474068
|
|
5
|
+
const TEMPORARY_ATTRIBUTE = "data-temp-href-target";
|
|
6
|
+
DOMPurify.addHook("beforeSanitizeAttributes", (node) => {
|
|
7
|
+
if (node.tagName === "A") {
|
|
8
|
+
if (!node.hasAttribute("target")) {
|
|
9
|
+
node.setAttribute("target", "_self");
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
if (node.hasAttribute("target")) {
|
|
13
|
+
node.setAttribute(TEMPORARY_ATTRIBUTE, node.getAttribute("target") || "");
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
});
|
|
17
|
+
|
|
18
|
+
DOMPurify.addHook("afterSanitizeAttributes", (node) => {
|
|
19
|
+
if (node.tagName === "A" && node.hasAttribute(TEMPORARY_ATTRIBUTE)) {
|
|
20
|
+
node.setAttribute("target", node.getAttribute(TEMPORARY_ATTRIBUTE) || "");
|
|
21
|
+
node.removeAttribute(TEMPORARY_ATTRIBUTE);
|
|
22
|
+
if (node.getAttribute("target") === "_blank") {
|
|
23
|
+
node.setAttribute("rel", "noopener noreferrer");
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* This removes script tags, form tags, iframe tags, and other potentially dangerous tags
|
|
30
|
+
*/
|
|
31
|
+
export function sanitizeHtml(html: string) {
|
|
32
|
+
const sanitizationOptions: Config = {
|
|
33
|
+
// Default to permit HTML, SVG and MathML, this limits to HTML only
|
|
34
|
+
USE_PROFILES: { html: true, svg: true, mathMl: true },
|
|
35
|
+
// Allow SVG <use> elements and their href attributes, which are needed
|
|
36
|
+
// for SVGs that reference <defs> (e.g., Matplotlib SVG output).
|
|
37
|
+
ADD_TAGS: ["use"],
|
|
38
|
+
ADD_ATTR: ["href", "xlink:href"],
|
|
39
|
+
// glue elements like style, script or others to document.body and prevent unintuitive browser behavior in several edge-cases
|
|
40
|
+
FORCE_BODY: true,
|
|
41
|
+
CUSTOM_ELEMENT_HANDLING: {
|
|
42
|
+
tagNameCheck: /^(marimo-[A-Za-z][\w-]*|iconify-icon)$/,
|
|
43
|
+
attributeNameCheck: /^[A-Za-z][\w-]*$/,
|
|
44
|
+
},
|
|
45
|
+
// This flag means we should sanitize such that is it safe for XML,
|
|
46
|
+
// but this is only used for HTML content.
|
|
47
|
+
SAFE_FOR_XML: !html.includes("marimo-mermaid"),
|
|
48
|
+
};
|
|
49
|
+
return DOMPurify.sanitize(html, sanitizationOptions);
|
|
50
|
+
}
|
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
/* Copyright 2026 Marimo. All rights reserved. */
|
|
2
|
-
import DOMPurify, { type Config } from "dompurify";
|
|
3
2
|
import { atom, useAtomValue } from "jotai";
|
|
4
3
|
import { hasRunAnyCellAtom } from "@/components/editor/cell/useRunCells";
|
|
5
4
|
import { autoInstantiateAtom } from "@/core/config/config";
|
|
6
5
|
import { getInitialAppMode } from "@/core/mode";
|
|
7
6
|
|
|
7
|
+
// Re-export so existing consumers don't break.
|
|
8
|
+
export { sanitizeHtml } from "./sanitize-html";
|
|
9
|
+
|
|
8
10
|
/**
|
|
9
11
|
* Whether to sanitize the html.
|
|
10
12
|
* When running as an app or with auto_instantiate enabled
|
|
@@ -42,51 +44,3 @@ const sanitizeHtmlAtom = atom<boolean>((get) => {
|
|
|
42
44
|
export function useSanitizeHtml() {
|
|
43
45
|
return useAtomValue(sanitizeHtmlAtom);
|
|
44
46
|
}
|
|
45
|
-
|
|
46
|
-
// preserve target=_blank https://github.com/cure53/DOMPurify/issues/317#issuecomment-912474068
|
|
47
|
-
const TEMPORARY_ATTRIBUTE = "data-temp-href-target";
|
|
48
|
-
DOMPurify.addHook("beforeSanitizeAttributes", (node) => {
|
|
49
|
-
if (node.tagName === "A") {
|
|
50
|
-
if (!node.hasAttribute("target")) {
|
|
51
|
-
node.setAttribute("target", "_self");
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
if (node.hasAttribute("target")) {
|
|
55
|
-
node.setAttribute(TEMPORARY_ATTRIBUTE, node.getAttribute("target") || "");
|
|
56
|
-
}
|
|
57
|
-
}
|
|
58
|
-
});
|
|
59
|
-
|
|
60
|
-
DOMPurify.addHook("afterSanitizeAttributes", (node) => {
|
|
61
|
-
if (node.tagName === "A" && node.hasAttribute(TEMPORARY_ATTRIBUTE)) {
|
|
62
|
-
node.setAttribute("target", node.getAttribute(TEMPORARY_ATTRIBUTE) || "");
|
|
63
|
-
node.removeAttribute(TEMPORARY_ATTRIBUTE);
|
|
64
|
-
if (node.getAttribute("target") === "_blank") {
|
|
65
|
-
node.setAttribute("rel", "noopener noreferrer");
|
|
66
|
-
}
|
|
67
|
-
}
|
|
68
|
-
});
|
|
69
|
-
|
|
70
|
-
/**
|
|
71
|
-
* This removes script tags, form tags, iframe tags, and other potentially dangerous tags
|
|
72
|
-
*/
|
|
73
|
-
export function sanitizeHtml(html: string) {
|
|
74
|
-
const sanitizationOptions: Config = {
|
|
75
|
-
// Default to permit HTML, SVG and MathML, this limits to HTML only
|
|
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"],
|
|
81
|
-
// glue elements like style, script or others to document.body and prevent unintuitive browser behavior in several edge-cases
|
|
82
|
-
FORCE_BODY: true,
|
|
83
|
-
CUSTOM_ELEMENT_HANDLING: {
|
|
84
|
-
tagNameCheck: /^(marimo-[A-Za-z][\w-]*|iconify-icon)$/,
|
|
85
|
-
attributeNameCheck: /^[A-Za-z][\w-]*$/,
|
|
86
|
-
},
|
|
87
|
-
// This flag means we should sanitize such that is it safe for XML,
|
|
88
|
-
// but this is only used for HTML content.
|
|
89
|
-
SAFE_FOR_XML: !html.includes("marimo-mermaid"),
|
|
90
|
-
};
|
|
91
|
-
return DOMPurify.sanitize(html, sanitizationOptions);
|
|
92
|
-
}
|