/* Kole UI · 在线测试(独立页)
编辑 H5 演示源码 → iframe srcdoc 实时重渲染;数据与文档站同源(同目录 data.json)。
零运行时依赖。
── 预览帧的安全边界(2026-09-20 真实浏览器实测) ──────────────────────────
预览里跑的是用户随手改的代码,按「不可信内容」对待,三层隔离:
1) sandbox="allow-scripts" 且**不给** allow-same-origin —— 帧是不透明源。帧内读
parent/top、document.cookie、localStorage 全是 SecurityError;顶层跳转、
window.open、表单提交、下载全被拦;探针服务器上收不到任何帧发起的请求。
2) 帧内注入 meta CSP,**只写比父页更严的项**(connect-src / form-action / frame-src
一律 'none'):帧内彻底发不出网络请求(fetch / sendBeacon / WebSocket / 表单)。
两条策略取交集,所以这里写的每一项都只会收紧 —— 父页 CSP 继续负责"允许什么",
本页不重复声明,避免把 'self' 在不透明源下的解析差异带进来。
3) 帧内注入 :srcdoc 的基准 URL 默认是父页 /site/,
演示源码里的 "./Xxx.css" 会被解析成 /site/Xxx.css(404)→ 预览丢掉组件样式
(实测 79 个组件里 36 个命中)。钉到演示原页所在目录后,相对资源解析与
「演示原页」完全一致。
帧内的脚本报错与被沙箱拦下的请求经 postMessage 回传本页,在预览上方按纯文本提示:
预览不再静默白屏、也不静默丢样式。父页只认「来源严格等于本页预览帧」的消息,
且只取字符串渲染,预览里的代码无法借此碰到本页 DOM。
───────────────────────────────────────────────────────────────────────── */
'use strict';
(function () {
var editor = document.getElementById('pg-editor');
var frame = document.getElementById('pg-frame');
var select = document.getElementById('pg-select');
var nameEl = document.getElementById('pg-name');
var statusEl = document.getElementById('pg-status');
var errorEl = document.getElementById('pg-error');
var noteEl = document.getElementById('pg-note');
var resetBtn = document.getElementById('pg-reset');
var copyBtn = document.getElementById('pg-copy');
var reloadBtn = document.getElementById('pg-reload');
var openLink = document.getElementById('pg-open');
var backLink = document.getElementById('pg-back');
var RENDER_DELAY = 300;
var DEFAULT_SLUG = 'button';
/* 演示原页住在 /frameworks/:srcdoc 里必须以它为基准,否则 ./ 相对引用全错 */
var FRAME_BASE = '../frameworks/';
/* 只列比父页更严的三条(父页是 connect-src/form-action/frame-src 'self') */
var PREVIEW_CSP = "connect-src 'none'; form-action 'none'; frame-src 'none'; object-src 'none'";
/* 帧内上报器:跑在用户代码之前,捕获脚本报错与策略拦截 */
var REPORTER = '