本页签名从公共包导出生成,中文说明与当前 JSDoc 同步校验。代码标识保持原名。
源码显露
readSourcePresentation(state) 返回 mode、selection、reveal、composing 与 selecting。
selection 是呈现使用的稳定选区,拖选期间可能与实时 state.selection 不同。
reveal 为 selection(普通 MSFE 默认)或 hidden;后者让已识别的语法在编辑中保持投影。
内置投影与组件的 ProjectionContext.active 已结合此策略,扩展优先使用 active 判断,
不要自行读取实时光标后强制显露。纯源码模式始终显示原文。
sourceRevealSetting 是公开 PresentationSetting<SourceRevealPolicy>:通过
addCodeMirrorExtensions() 安装 sourceRevealSetting.extension(() => 'hidden'),再用
sourceRevealSetting.set(editor, 'selection') 提交呈现请求。read(state) 返回已应用值,
requested(state) 返回最近请求,未安装时都返回 undefined。setter 返回 MsfeResult,
未安装时为 not-installed,无效值为 invalid-change;销毁或未挂载时也会拒绝。
请求不改变权限或源码,拖选与组合输入期间延迟生效。产品用户优先使用
MD Editor 的 view。
直接创建的替换范围在 hidden 下参与原子导航,避免光标进入不可见语法。
未知/不完整内容应继续显示源码;请勿用 CSS 让无投影合同的文本消失。
sourceRevealResolver.of(resolveOwner) 是宿主可安装的 CodeMirror facet。
resolveOwner(state, range) 返回包含原片段的规范源码范围,用来将行内标记归入段落、列表项
或单元格;范围必须是文档内的整数坐标,否则抛出 invalid-source-reveal-owner。
不安装时保留节点自身的显露范围。解析函数应只查询局部语法祖先,不读取全文、修改选区或提交事务。
MD Editor 已安装此策略,自定义节点、规范化替换和组件高度共用它。
内置投影继续读取 ProjectionContext.active。独立 CodeMirror 插件使用
isSourceRevealed(state, { from, to }) 查询同一策略;它同时检查模式、隐藏偏好和拖选稳定选区。
isSourceActive(selection, from, to) 只做范围相交判断,不应用宿主范围或模式。
规范化替换的 revealRange 先表示完整片段,再由 resolver 归入宿主语义范围;
interaction: 'atomic' 的替换仍保留显式原子交互。
可选输入代理
sourceInputProxy({ mediaQuery, modes?, revealMargin?, onSelectionTap? }) 返回可安装的 CodeMirror extension,默认仅在
live 模式匹配宿主窗口媒体条件时启用。MD Editor 已为窄屏触摸设备安装,不需宿主重复安装。
它复用 @quirekit/ime,把可编辑 textarea 放到当前 Document/ShadowRoot 的独立输入层;
正文只负责展示,文档、选区、源码规则和撤销仍使用原 CM state。取消 preedit 不删除选区,
确认只写一笔事务;权限收回、文档替换和卸载释放 native host。
可选 onSelectionTap(view, point) 返回 true 时,宿主已处理已有选区的短按,代理不移动
caret、不重新 focus;触摸结束与兼容 click 只接受一次。MD Editor 用它切换选区操作菜单。
代理有效期间原生 Selection 不得持有非 editable 正文范围,独立嵌入控件仍保留自己的选区。
revealMargin 指定 caret 揭示时额外保留的 client CSS 空间,默认 8px;MD Editor 使用
32px,为圆点及触摸热区留出空间。它不改变源位置或文档布局。
editor.focus() 会选择当前输入 owner。使用 CM escape hatch 的自定义控件应使用
focusSourceView(view)、sourceInputHasFocus(view) 和 sourceInputElement(view),不能假定
view.hasFocus 或 contentDOM 代表移动键盘焦点。sourceInputFocusChanged(update) 同时报告
原生与代理的逻辑焦点变化。几何阶段可用 sourceInputCaret(view) 读取当前 preedit 尾端的
client CSS 矩形;没有 preedit 时返回 null,继续使用 coordsAtPos。禁止每帧 focus 或清除输入。
sourceInputPosition(view, { x, y }) 接受 client CSS 命中,跳过原子替换内部与零高度源行,
将间隙吸附到最近两侧的可见边界;无法证明挂载可见时返回 null,应保留上一个端点。
不要再直接把 posAtCoords 的隐藏位置提交为移动端选区。
sourceCaretRect(view, pos, side?) 只返回具有真实行框的 mounted caret;首选关联侧
不可见时尝试另一侧,避免围栏/标题边界丢失光标。正常只读一侧,边界最多两侧;无几何时返回 null。
sourceViewport(view) 在几何阶段读取 VisualViewport、裁剪祖先和 CM scrollMargins 的
可用区域,含 offsetTop;键盘与 dock 不重复计数。sourceScrollStep(view, delta) 只测量
最近可滚动祖先的一次垂直推进,耗尽后交给外层页面;applySourceScrollStep(step) 在写阶段
执行该测量,不改变源或选区。连续拖选由消费方保留一个活动帧并重算最新端点,必须在松手、
取消、权限/模式变化和销毁时停止。代理短按、实际输入与视口 resize 会按同一边界揭示 caret;
普通手动滚动和仅恢复程序焦点不会建立持续导航锚点。已挂载的 nearest caret-scroll
委托同一揭示 owner,避免竞争滚动;可见输入零滚动写入。键盘变化时若末尾空间尚未更新,
最多八次测量等待可用布局,端点可见即结束,新的用户滚动仍立即取消。
投影声明
跨行预览使用 block;可操作示例见 图表。
@quirekit/msfe-core可组合投影层;块级输出在 CodeMirror 计算视口前提供。
export interface ProjectionLayer {
readonly key: string;
readonly placement: "inline" | "block";
readonly modes?: readonly MsfeMode[];
readonly selection?: boolean;
readonly states?: readonly StateSlot<unknown>[];
readonly suppressDuringComposition?: boolean;
readonly incremental?: boolean;
readonly references?: boolean;
readonly build: (input: ProjectionInput) => readonly ProjectionDecoration[];
}规范输入
查询有界语义,不在构建期间提交事务。
@quirekit/msfe-core投影层的有界输入,提供语义查询与类型化状态访问。
export interface ProjectionInput extends MsfeSourceRange {
readonly document: SourceDocument;
readonly selection: EditorSelection;
readonly mode: MsfeMode;
readonly readOnly: boolean;
query(name: string): SourceQuery;
getState<T>(slot: StateSlot<T>): T;
}视图描述
稳定 renderer 与不可变 props 形成可保留的组件描述。
@quirekit/msfe-core参数 renderer:类型化渲染器;props:类型化不可变输入;map:增量投影层中源码坐标属性的纯映射,不获取资源或写入源码。返回可安装的视图描述。
function componentView<Props extends object>(renderer: ComponentViewRenderer<Props>, props: Props, map?: (props: Props, offset: number) => Props): ComponentView挂载上下文
scope 是当前组件生命周期;几何变化后请求测量。
@quirekit/msfe-core通用组件挂载输入,与源码节点的持久化协议独立。
export interface ComponentViewMount<Props extends object> {
readonly dom: HTMLElement;
readonly props: Props;
readonly host: MsfeComponentHost | undefined;
readonly scope: TaskScope;
readonly requestMeasure: () => void;
}保留与清理
更新复用原入口,销毁释放宿主创建的所有资源。
@quirekit/msfe-core保留组件的更新与清理协议。
export interface ComponentViewHandle<Props extends object> {
ignoreEvent?(event: Event): boolean;
update(props: Props): void;
destroy(): void;
}代码语言
完整惰性加载目录见 代码块。
@quirekit/msfe-core宿主声明的惰性语言目录,由同一 Markdown 混合解析器使用。
export interface CodeLanguage {
readonly name: string;
readonly aliases?: readonly string[];
readonly load: (signal: AbortSignal) => Promise<LanguageSupport>;
}搜索面板
组件使用 view 属性,替换动作必须考虑权限和组合输入。
@quirekit/msfe-core替换现有搜索面板的宿主渲染器协议。
export interface SearchPanelProps {
readonly query: SearchParameters;
readonly valid: boolean;
readonly matches: SearchMatches;
readonly readOnly: boolean;
readonly composing: boolean;
readonly setQuery: (changes: Partial<SearchParameters>) => boolean;
readonly run: (action: SearchAction) => boolean;
readonly phrase: (key: string) => string;
}预览配置
Math、Mermaid 与 TextDiagrams 的公开配置用于宿主操作组件。
@quirekit/msfe-markdown-extras配置宿主预览控件,功能包不规定按钮的产品外观。
export interface PreviewOptions {
readonly controls?: ComponentViewRenderer<PreviewControlProps>;
readonly edit?: (request: PreviewEditRequest) => boolean;
readonly activation?: PreviewActivation;
readonly image?: boolean;
}edit 可将预览的编辑操作交给共享公式面板等宿主 UI。请求已经过目标和权限校验;
若异步保留草稿,须另行 captureAnchor(range),确认时检查 anchor.target(),关闭时
释放锚点。返回 true 表示接管成功;不配置时沿用源码显露。见 MD Editor。
@quirekit/msfe-markdown-extras预览映射的源码通过校验后发出的明确编辑请求。
export interface PreviewEditRequest {
readonly editor: MsfeEditor;
readonly range: MsfeSourceRange;
readonly kind: PreviewProps["kind"];
}预览操作
PlantUML/DOT 可由 TextDiagrams 安装并复用同一 PreviewOptions、编辑回调与取消生命周期。公共中立接口 renderTextDiagram(language, source, options) 位于 @quirekit/text-diagram/browser,返回绑定精确语言与源码的净化 SVG 快照;rasterizeTextDiagram(snapshot, ownerDocument, signal) 生成同一快照的 PNG。MD Editor 三语言预览、共享源码面板和 Word 图片导出使用这条路径。
renderMermaidSvg() 在浏览器中从源码生成清理后的静态 SVG,与编辑器预览共用 Mermaid
串行队列和安全配置。宿主传入取消信号与字体,可继续转成 PNG 用于文件导出;该函数不读取
编辑器 DOM,不注册 SVG 事件,也不允许外部图片或样式资源。
@quirekit/msfe-markdown-extras参数 text:完整 Mermaid 源码;signal:本次渲染的生命周期;typography:宿主字体配置。返回共享文本绘图模块净化后的 SVG,与其他 Mermaid 请求串行渲染。
function renderMermaidSvg(text: string, signal: AbortSignal, typography: PreviewTypography): Promise<string>@quirekit/msfe-markdown-extras获取新预览时解析的宿主字体配置,不依赖 UI 包。
export interface PreviewTypography {
readonly fontFamily: string;
readonly fontSize: number;
}处理加载、错误、重试和源码显露。
@quirekit/msfe-markdown-extras传给宿主组件库的预览状态与动作。
export interface PreviewControlProps {
readonly kind: PreviewProps["kind"];
readonly readOnly: boolean;
readonly status: "loading" | "ready" | "error";
readonly retry: () => void;
readonly revealSource: () => boolean;
}图片资源
源码地址先经过字段校验,再交给宿主 resolver。
@quirekit/msfe-image解析 Markdown 图片目标并保存粘贴、拖入的图片,宿主凭证不写入文档。
export interface ImageOptions {
readonly resolve?: (source: string, signal: AbortSignal) => MsfeImageResource | Promise<MsfeImageResource>;
readonly upload?: ImageUploader | false;
}块控制协议
核心管理原生命中、指针生命周期和版本化事务,宿主管理组件渲染。嵌套子流须显式声明。指针更新只查询局部祖先路径,松手或执行菜单动作时才运行命令。
@quirekit/msfe-core参数 state:已接受的源码。参数 node:候选容器。返回可编辑的子块范围;未处理语法返回 null,不完整或具有位置约束的块返回 false。
export type SourceBlockScopeResolver = (state: EditorState, node: SyntaxNode) => MsfeSourceRange | null | false;@quirekit/msfe-core扩展可声明嵌套子块范围;文档根级块不需要额外配置。
sourceBlockScopes = Facet.define<SourceBlockScopeResolver>()@quirekit/msfe-core参数 options:宿主 UI 观察回调。返回管理原生块命中、拖放和菜单意图生命周期的扩展。
function createSourceBlockControls(options: SourceBlockControlsOptions): AnyExtension@quirekit/msfe-core不依赖框架的观察回调;UI 保留在使用方的组件和 Provider 树中。
export interface SourceBlockControlsOptions {
readonly change: (controls: SourceBlockControls | null) => void;
readonly openMenu: (controls: SourceBlockControls) => void;
readonly insertionChange?: (controls: SourceInsertionControls | null) => void;
readonly openInsertionMenu?: (controls: SourceInsertionControls) => void;
}@quirekit/msfe-core供宿主渲染块手柄与菜单的小型临时快照。
export interface SourceBlockControls {
readonly editor: MsfeEditor;
readonly block: SourceBlock;
readonly rect: SourceBlockRect;
readonly firstLine: SourceBlockRect | null;
readonly target: MsfeTarget;
readonly dragging: boolean;
readonly drop: SourceBlockDrop | null;
readonly pointer: {
readonly x: number;
readonly y: number;
} | null;
press(event: PointerEvent): void;
pin(open: boolean): void;
run(command: MsfeCommand): boolean;
focus(): void;
}@quirekit/msfe-core供宿主展示空行插入入口;复用块观察器,不提供空行拖动语义。
export interface SourceInsertionControls {
readonly editor: MsfeEditor;
readonly line: SourceBlankLine;
readonly rect: SourceBlockRect;
readonly target: MsfeTarget;
pin(open: boolean): void;
focus(): void;
}@quirekit/msfe-core从当前视图读取的客户端坐标几何,不作为排版依据。
export interface SourceBlockRect {
readonly left: number;
readonly top: number;
readonly width: number;
readonly height: number;
}@quirekit/msfe-core指针手势当前校验通过的插入位置。
export interface SourceBlockDrop {
readonly block: SourceBlock;
readonly side: SourceBlockSide;
readonly rect: SourceBlockRect;
}