刘光辉
8 小时以前 cf11e63b659afcc9792ab3e395f1b45d844431a8
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
interface PluginInfo {
  options?: unknown;
}
 
interface PluginRuntime {
  info?: PluginInfo;
  init?: (...args: unknown[]) => void;
}
 
interface AscRuntime {
  plugin?: PluginRuntime;
}
 
function hasRuntimeOptions(options: unknown): boolean {
  return (typeof options === 'object' && options !== null)
    || (typeof options === 'string' && options.trim().length > 0);
}
 
/**
 * OnlyOffice 在调用 plugin.init 时才会将 editorConfig.plugins.options 注入 iframe。
 * 不能在 Vue mounted 时抢先读取,否则自动启动插件会拿到空上下文。
 */
export function bindPluginReady(asc: AscRuntime | undefined, onReady: () => void): () => void {
  const plugin = asc?.plugin;
  let initialized = false;
  const initialize = () => {
    if (initialized) return;
    initialized = true;
    onReady();
  };
 
  if (!plugin) {
    initialize();
    return () => undefined;
  }
 
  const originalInit = plugin.init;
  const init = (...args: unknown[]) => {
    originalInit?.(...args);
    initialize();
  };
  plugin.init = init;
 
  // Vite HMR 或手动再次打开插件时,options 可能已经可用而 init 不会再触发。
  if (hasRuntimeOptions(plugin.info?.options)) initialize();
 
  return () => {
    if (plugin.init === init) plugin.init = originalInit;
  };
}