fix(tiptap): expose EditorOptions as runtime class for wasm-bindgen
EditorOptions was a TS interface (erased at runtime), but the Rust wasm-bindgen extern uses #[wasm_bindgen(constructor)] which generates 'new EditorOptions()' — requiring a global constructor. Vite 5/Rollup accidentally leaked the name into IIFE global scope, masking this. Vite 8/Rolldown strictly erases interfaces, exposing it as 'EditorOptions is not defined'. Fix: make EditorOptions a class (retains runtime constructor) and mount it on window, since the IIFE bundle name is taken by TiptapEditor.
This commit is contained in:
parent
368a651fa6
commit
fb31ecb5ae
@ -9,7 +9,16 @@ import { UploadCoordinator, UPLOAD_COORDINATOR_STORAGE_KEY, type UploadEvent } f
|
|||||||
import { UploadImage } from './upload-image'
|
import { UploadImage } from './upload-image'
|
||||||
import './style.css'
|
import './style.css'
|
||||||
|
|
||||||
export interface EditorOptions {
|
/**
|
||||||
|
* 编辑器选项。用 class 而非 interface,使其编译后保留运行时构造函数——
|
||||||
|
* Rust 侧 wasm-bindgen 的 `#[wasm_bindgen(constructor)]` 会生成 `new EditorOptions()`,
|
||||||
|
* 需要一个全局可访问的构造函数(interface 会被 TS 擦除)。
|
||||||
|
* 字段全部可选,Rust 通过 setter(set_placeholder/set_on_update/...)逐个赋值。
|
||||||
|
*
|
||||||
|
* 不用 export(避免 IIFE 的 named export 与 default 冲突),而是挂到 globalThis,
|
||||||
|
* 让 wasm-bindgen glue 里的裸标识符 `EditorOptions` 能解析到。
|
||||||
|
*/
|
||||||
|
class EditorOptions {
|
||||||
content?: string
|
content?: string
|
||||||
placeholder?: string
|
placeholder?: string
|
||||||
onUpdate?: (markdown: string) => void
|
onUpdate?: (markdown: string) => void
|
||||||
@ -24,17 +33,21 @@ export interface EditorOptions {
|
|||||||
onUploadEvent?: (event: UploadEvent) => void
|
onUploadEvent?: (event: UploadEvent) => void
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// wasm-bindgen 生成的 glue 用裸标识符 `new EditorOptions()` 从全局解析,
|
||||||
|
// IIFE 的 name 只能挂一个全局(TiptapEditor),这里手动把 EditorOptions 也挂到 window 上。
|
||||||
|
;(window as unknown as Record<string, unknown>).EditorOptions = EditorOptions
|
||||||
|
|
||||||
class TiptapEditorInstance {
|
class TiptapEditorInstance {
|
||||||
private editor: Editor | null = null
|
private editor: Editor | null = null
|
||||||
private container: HTMLElement
|
private container: HTMLElement
|
||||||
private options: EditorOptions
|
private options: EditorOptions
|
||||||
// 源码模式相关状态
|
|
||||||
private isSourceMode = false
|
private isSourceMode = false
|
||||||
private sourceTextarea: HTMLTextAreaElement | null = null
|
private sourceTextarea: HTMLTextAreaElement | null = null
|
||||||
private toggleButton: HTMLButtonElement | null = null
|
private toggleButton: HTMLButtonElement | null = null
|
||||||
private coordinator: UploadCoordinator | null = null
|
private coordinator: UploadCoordinator | null = null
|
||||||
|
|
||||||
constructor(container: HTMLElement, options: EditorOptions = {}) {
|
constructor(container: HTMLElement, options: EditorOptions = new EditorOptions()) {
|
||||||
this.container = container
|
this.container = container
|
||||||
this.options = options
|
this.options = options
|
||||||
this.init()
|
this.init()
|
||||||
@ -257,7 +270,7 @@ class TiptapEditorInstance {
|
|||||||
const TiptapEditor = {
|
const TiptapEditor = {
|
||||||
_instances: new Map<string, TiptapEditorInstance>(),
|
_instances: new Map<string, TiptapEditorInstance>(),
|
||||||
|
|
||||||
create(containerId: string, options: EditorOptions = {}): TiptapEditorInstance | null {
|
create(containerId: string, options: EditorOptions = new EditorOptions()): TiptapEditorInstance | null {
|
||||||
const container = document.getElementById(containerId)
|
const container = document.getElementById(containerId)
|
||||||
if (!container) {
|
if (!container) {
|
||||||
console.error(`[TiptapEditor] Container not found: #${containerId}`)
|
console.error(`[TiptapEditor] Container not found: #${containerId}`)
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user