anentrypoint-design 0.0.205 → 0.0.206
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/app-shell.css +52 -23
- package/dist/247420.css +52 -23
- package/dist/247420.js +13 -13
- package/package.json +1 -1
- package/src/components/community.js +8 -1
- package/src/components/content.js +6 -2
- package/src/markdown.js +10 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "anentrypoint-design",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.206",
|
|
4
4
|
"description": "247420 design system SDK — webjsx + modified ripple-ui, single-file ESM bundle for reproducible use of the AnEntrypoint design.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/247420.js",
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
import * as webjsx from '../../vendor/webjsx/index.js';
|
|
4
4
|
import { Icon } from './shell.js';
|
|
5
|
+
import { sanitizeHtml } from '../markdown.js';
|
|
5
6
|
const h = webjsx.createElement;
|
|
6
7
|
|
|
7
8
|
// Clamp a count to a compact badge string (matches the rail's 99+ convention),
|
|
@@ -391,7 +392,13 @@ export function PageView({ title = '', html = '', isAdmin = false, onEdit } = {}
|
|
|
391
392
|
),
|
|
392
393
|
h('div', {
|
|
393
394
|
class: 'cm-page-body',
|
|
394
|
-
|
|
395
|
+
// Page bodies are host/user-authored HTML, so they pass through the
|
|
396
|
+
// DOMPurify gate before innerHTML — never injected raw (stored-XSS gate).
|
|
397
|
+
ref: (el) => {
|
|
398
|
+
if (!el) return;
|
|
399
|
+
if (!html) { el.innerHTML = '<p class="cm-page-empty">This page is empty.</p>'; return; }
|
|
400
|
+
sanitizeHtml(html).then((clean) => { el.innerHTML = clean; });
|
|
401
|
+
}
|
|
395
402
|
})
|
|
396
403
|
);
|
|
397
404
|
}
|
|
@@ -53,7 +53,11 @@ export function Row({ code, rank, title, sub, meta, active, state = 'default', o
|
|
|
53
53
|
const isLink = kind === 'link' || (href != null && !onClick);
|
|
54
54
|
const isButton = !isLink && !!onClick;
|
|
55
55
|
const stateCls = state === 'disabled' ? ' row-state-disabled' : (state === 'error' ? ' row-state-error' : '');
|
|
56
|
-
|
|
56
|
+
// With no leading/code, the title would otherwise land in the narrow code
|
|
57
|
+
// column and wrap; `row-nocode` collapses that column so the title gets the
|
|
58
|
+
// full width (meta still pinned right).
|
|
59
|
+
const noLead = codeVal == null && leading == null;
|
|
60
|
+
const cls = 'row' + (isActive ? ' active' : '') + stateCls + (cols ? ' row-grid' : '') + (noLead && !cols ? ' row-nocode' : '') + (rail ? ' rail-' + rail : '');
|
|
57
61
|
const isDisabled = state === 'disabled';
|
|
58
62
|
const props = { key, class: cls, style: cols ? `${style ? style + ';' : ''}grid-template-columns:${cols}` : style };
|
|
59
63
|
if (isLink) {
|
|
@@ -168,7 +172,7 @@ export function WorksList({ works = [], openedIndex = -1, onToggle }) {
|
|
|
168
172
|
// Expand affordance: a chevron icon (down when open, right when
|
|
169
173
|
// collapsed) separated from the meta text by a CSS gap, not a
|
|
170
174
|
// literal +/- with a double-space.
|
|
171
|
-
meta: h('span', { class: 'ds-works-meta'
|
|
175
|
+
meta: h('span', { class: 'ds-works-meta' },
|
|
172
176
|
w.meta != null ? h('span', {}, w.meta) : null,
|
|
173
177
|
Icon(isOpen ? 'chevron-down' : 'chevron-right')),
|
|
174
178
|
active: isOpen,
|
package/src/markdown.js
CHANGED
|
@@ -52,3 +52,13 @@ export async function renderMarkdown(src) {
|
|
|
52
52
|
const raw = _marked.parse(String(src));
|
|
53
53
|
return _purify.sanitize(raw);
|
|
54
54
|
}
|
|
55
|
+
|
|
56
|
+
// Sanitize already-rendered HTML before it touches innerHTML. For any surface
|
|
57
|
+
// that injects host/user-authored HTML (e.g. a wiki page body), this is the
|
|
58
|
+
// single XSS gate — DOMPurify strips scripts/handlers. If the purifier hasn't
|
|
59
|
+
// loaded, we safe-fail by escaping (raw tags show as text, never execute).
|
|
60
|
+
export async function sanitizeHtml(html) {
|
|
61
|
+
const ok = await ensureReady();
|
|
62
|
+
if (!ok) return escapeHtml(html);
|
|
63
|
+
return _purify.sanitize(String(html));
|
|
64
|
+
}
|