✨ feat(vscode): 代码阅读预览界面
Vite 加 code-reader.html 第二入口;代码块树(层级竖线、折叠、种类标签配色)、译文 / 源码按词性着色、块内直接编辑(防抖回写整行、Esc 回预览)、翻译下拉、解析失败提示;看板与代码阅读共用带类型的 acquireVsCodeApi 包装和 ErrorBoundary。
This commit is contained in:
1 parent
cab5ac0ebc
commit
af56985d9a
16 files changed
+775
-74
No files matched your search
@@ -1,39 +1,6 @@
|
||||
/**
|
||||
* Tiny typed bridge over the `acquireVsCodeApi()` postMessage channel.
|
||||
*
|
||||
* The webview gets exactly one chance to call `acquireVsCodeApi()` per
|
||||
* lifetime, so we cache the handle module-side. When running outside the
|
||||
* VS Code host (e.g. `vite dev`) we fall back to no-op stubs.
|
||||
*/
|
||||
/** 看板 webview 与扩展之间的收发。 */
|
||||
|
||||
import type { ExtensionToWebview, WebviewToExtension } from './messages'
|
||||
import { createVsCodeBridge } from './vscodeBridge'
|
||||
|
||||
interface VsCodeApi {
|
||||
postMessage: (msg: WebviewToExtension) => void
|
||||
getState: <T = unknown>() => T | undefined
|
||||
setState: <T = unknown>(state: T) => void
|
||||
}
|
||||
|
||||
declare global {
|
||||
interface Window {
|
||||
acquireVsCodeApi?: () => VsCodeApi
|
||||
}
|
||||
}
|
||||
|
||||
const api: VsCodeApi = window.acquireVsCodeApi?.() ?? {
|
||||
postMessage: () => {},
|
||||
getState: () => undefined,
|
||||
setState: () => {},
|
||||
}
|
||||
|
||||
export function postMessage(msg: WebviewToExtension): void {
|
||||
api.postMessage(msg)
|
||||
}
|
||||
|
||||
export function onMessage(handler: (msg: ExtensionToWebview) => void): () => void {
|
||||
const listener = (ev: MessageEvent): void => {
|
||||
handler(ev.data as ExtensionToWebview)
|
||||
}
|
||||
window.addEventListener('message', listener)
|
||||
return () => window.removeEventListener('message', listener)
|
||||
}
|
||||
export const { postMessage, onMessage } = createVsCodeBridge<ExtensionToWebview, WebviewToExtension>()
|
||||
@@ -0,0 +1,45 @@
|
||||
/**
|
||||
* 对 `acquireVsCodeApi()` 的一层带类型包装:看板和代码阅读各自用自己的消息类型建一个。
|
||||
*
|
||||
* 每个 webview 一生只能调用一次 `acquireVsCodeApi()`,所以每个页面只建一个桥。
|
||||
* 不在 VS Code 里跑(例如 `vite dev`)时退回空实现。
|
||||
*/
|
||||
|
||||
interface VsCodeApi {
|
||||
postMessage: (msg: unknown) => void
|
||||
getState: () => unknown
|
||||
setState: (state: unknown) => void
|
||||
}
|
||||
|
||||
declare global {
|
||||
interface Window {
|
||||
acquireVsCodeApi?: () => VsCodeApi
|
||||
}
|
||||
}
|
||||
|
||||
export interface VsCodeBridge<In, Out, State> {
|
||||
postMessage: (msg: Out) => void
|
||||
onMessage: (handler: (msg: In) => void) => () => void
|
||||
getState: () => State | undefined
|
||||
setState: (state: State) => void
|
||||
}
|
||||
|
||||
export function createVsCodeBridge<In, Out, State = never>(): VsCodeBridge<In, Out, State> {
|
||||
const api: VsCodeApi = window.acquireVsCodeApi?.() ?? {
|
||||
postMessage: () => {},
|
||||
getState: () => undefined,
|
||||
setState: () => {},
|
||||
}
|
||||
return {
|
||||
postMessage: msg => api.postMessage(msg),
|
||||
onMessage: (handler) => {
|
||||
const listener = (ev: MessageEvent): void => {
|
||||
handler(ev.data as In)
|
||||
}
|
||||
window.addEventListener('message', listener)
|
||||
return () => window.removeEventListener('message', listener)
|
||||
},
|
||||
getState: () => api.getState() as State | undefined,
|
||||
setState: state => api.setState(state),
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user