- html viewer:.html/.htm 沙箱 iframe 预览(相对资源经 /sidebar/html 路径编码路由加载,CSP sandbox + 信任围栏 + cwd 边界),预览/编辑切换 - browser tab:+ 菜单多开(browser:<n>),地址栏后退/前进/刷新/在浏览器中打开(15px 图标),URL 与标题按会话持久化(patchTab + nextBrowser) - 安全:iframe 一律不透明源沙箱(无 allow-same-origin/top-navigation、no-referrer、权限策略全禁、禁 srcdoc);地址栏仅 http(s)、拒绝 localhost 等本机地址;界面实时沙箱状态(关闭红色警示)+ 临时解锁/恢复 - 设置:htmlViewerNoSandbox / htmlViewerDefaultUnsafe / browserNoSandbox / browserInterceptLinks 四个声明式二级设置(默认安全) - 外链拦截:聊天/界面 http(s) 外链默认在侧边栏打开(openTab seed.url),Ctrl/Cmd 点击放行 - 嵌入拒绝面板:browser.probe 路由探测 X-Frame-Options/frame-ancestors,被拒站点显示原因 + 在浏览器中打开/仍然加载 - 设置页可滚动;内置 7 tab + 9 viewer;新增设计文档;268 个测试全绿
61 lines
1.8 KiB
TypeScript
61 lines
1.8 KiB
TypeScript
/**
|
|
* Browser globals for specs that pull browser-bound modules. Import this
|
|
* FIRST in a spec file: unlike statements after imports (which vitest
|
|
* hoists above the module body), an import statement evaluates in order,
|
|
* so this runs before any later import's module graph (xterm's UMD wrapper
|
|
* checks `self` and its color defaults probe `document` at evaluation time;
|
|
* window/localStorage are only touched at runtime by the store).
|
|
*/
|
|
const g = globalThis as Record<string, unknown>
|
|
|
|
if (g.self === undefined) g.self = globalThis
|
|
|
|
const elementStub = (): Record<string, unknown> => ({
|
|
style: {},
|
|
classList: { add: () => {}, remove: () => {}, contains: () => false },
|
|
setAttribute: () => {},
|
|
getAttribute: () => null,
|
|
hasAttribute: () => false,
|
|
appendChild: () => {},
|
|
addEventListener: () => {},
|
|
removeEventListener: () => {},
|
|
getBoundingClientRect: () => ({ left: 0, top: 0, width: 0, height: 0 }),
|
|
// xterm's color palette probe measures a canvas context at module load.
|
|
getContext: () => null,
|
|
})
|
|
|
|
if (g.document === undefined) {
|
|
g.document = {
|
|
createElement: () => elementStub(),
|
|
createDocumentFragment: () => elementStub(),
|
|
addEventListener: () => {},
|
|
removeEventListener: () => {},
|
|
defaultView: globalThis,
|
|
body: elementStub(),
|
|
// CodeMirror's view module probes the UA and injects styles at load.
|
|
documentElement: elementStub(),
|
|
head: elementStub(),
|
|
styleSheets: [],
|
|
}
|
|
}
|
|
|
|
if (g.navigator === undefined) {
|
|
g.navigator = { userAgent: 'node', platform: 'node', vendor: '', maxTouchPoints: 0 }
|
|
}
|
|
|
|
if (g.window === undefined) {
|
|
g.window = {
|
|
clearTimeout: () => {},
|
|
setTimeout: (_fn: () => void) => 0,
|
|
innerWidth: 1024,
|
|
getComputedStyle: () => ({ getPropertyValue: () => '' }),
|
|
}
|
|
}
|
|
|
|
if (g.localStorage === undefined) {
|
|
g.localStorage = {
|
|
getItem: () => null,
|
|
setItem: () => {},
|
|
}
|
|
}
|