Canvas 主题
Canvas 主题不是 HTML <canvas> 绘图库的限定名称,而是“完整页面画布”模式:主题在隔离 iframe 中自行实现 DOM、布局、交互与图表,拥有最高视觉自由度。
Manifest
json
{
"schema": "nstatus-extension-v1",
"id": "example-canvas-theme",
"name": "Example Canvas Theme",
"version": "1.0.0",
"type": "theme",
"mode": "canvas",
"entry": "index.html",
"permissions": ["status:read"],
"height": 900,
"author": "Developer",
"license": "MIT",
"files": [
"manifest.json",
"index.html",
"theme.css",
"theme.js",
"LICENSE"
]
}entry 必须指向包内 HTML,height 会被限制在 400–12000。v1 只接受 status:read,声明其他权限会拒绝上传。
最小 HTML
扩展 CSP 禁止内联脚本,因此 JavaScript 必须使用包内外部文件:
html
<!doctype html>
<html lang="zh-CN">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="theme.css">
<script type="module" src="theme.js"></script>
</head>
<body>
<main id="app" aria-live="polite">正在读取状态...</main>
</body>
</html>接收状态
js
const app = document.querySelector('#app')
window.addEventListener('message', event => {
if (event.source !== parent) return
if (!event.data || event.data.type !== 'nstatus:status') return
if (event.data.api_version !== 'v1') return
renderStatus(event.data.payload)
})
function renderStatus(payload) {
app.replaceChildren()
const heading = document.createElement('h1')
heading.textContent = payload?.name || 'NIE-SLA'
app.append(heading)
}
parent.postMessage({ type: 'nstatus:ready' }, '*')扩展 iframe 没有同源权限,因此目标 Origin 在浏览器中是 opaque。发送消息使用 *,安全性依赖两端严格验证 event.source、消息类型和白名单字段。
请求历史数据
Canvas 主题可以通过宿主代理请求 status、checks、metrics、pings 或 latency:
js
parent.postMessage({
type: 'nstatus:request',
request_id: 'metrics-vps-a-6h',
resource: 'metrics',
query: {
agent_id: 'vps-a',
hours: 6,
max_points: 360
}
}, '*')宿主只接受最多 20 个简单查询字段,键名和值长度受限;请求最终映射到无凭据的 /api/v1/*。
动态高度
js
const observer = new ResizeObserver(() => {
parent.postMessage({
type: 'nstatus:resize',
height: document.documentElement.scrollHeight
}, '*')
})
observer.observe(document.documentElement)宿主仍会把高度限制在 400–12000。主题应在手机上自然换行,不要依赖超宽固定画布。
禁止能力
Canvas 主题不能直接 fetch 外网、读取宿主 DOM、读取 Cookie 或 Web Storage、提交表单、打开顶层导航、创建 Worker 或嵌套 frame。字体、图片、代码和样式全部随 ZIP 提供。
完整消息格式见消息协议。