feat:完成Collabora初步集成(返回顶部、文档页数获取)
This commit is contained in:
@@ -0,0 +1,152 @@
|
||||
/**
|
||||
* Collabora 页数信息获取模块
|
||||
*
|
||||
* @encoding UTF-8
|
||||
*/
|
||||
|
||||
/**
|
||||
* 页数信息接口
|
||||
*/
|
||||
export interface PageInfo {
|
||||
totalPages: number;
|
||||
currentPage: number;
|
||||
timestamp: number;
|
||||
}
|
||||
|
||||
/**
|
||||
* Collabora PostMessage 数据类型
|
||||
*/
|
||||
interface CollaboraMessageData {
|
||||
MessageId?: string;
|
||||
msgId?: string;
|
||||
// bundle.js _postMessage 发送的格式
|
||||
Values?: {
|
||||
Command?: string;
|
||||
Status?: string;
|
||||
totalPages?: number;
|
||||
currentPage?: number;
|
||||
timestamp?: number;
|
||||
pages?: number;
|
||||
currentPage?: number;
|
||||
[key: string]: unknown;
|
||||
};
|
||||
// 原始插件返回的格式
|
||||
args?: {
|
||||
Command?: string;
|
||||
Status?: string;
|
||||
totalPages?: number;
|
||||
currentPage?: number;
|
||||
timestamp?: number;
|
||||
[key: string]: unknown;
|
||||
};
|
||||
[key: string]: unknown;
|
||||
}
|
||||
|
||||
/**
|
||||
* Collabora 全局对象类型
|
||||
*/
|
||||
interface CollaboraApp {
|
||||
map?: {
|
||||
_docLayer?: {
|
||||
_pages?: number;
|
||||
_currentPage?: number;
|
||||
[key: string]: unknown;
|
||||
};
|
||||
[key: string]: unknown;
|
||||
};
|
||||
[key: string]: unknown;
|
||||
}
|
||||
|
||||
/**
|
||||
* 扩展 Window 类型以包含 Collabora app
|
||||
*/
|
||||
interface CollaboraWindow extends Window {
|
||||
app?: CollaboraApp;
|
||||
}
|
||||
|
||||
/**
|
||||
* 解析 PostMessage 数据
|
||||
*/
|
||||
function parseMessageData(data: unknown): CollaboraMessageData {
|
||||
if (typeof data === 'string') {
|
||||
return JSON.parse(data) as CollaboraMessageData;
|
||||
}
|
||||
return data as CollaboraMessageData;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 通过 PostMessage 请求页数信息
|
||||
*
|
||||
* 使用自定义 custompostMessage 插件获取文档页数。
|
||||
* 注意: Collabora 的页码是从 0 开始的。
|
||||
*
|
||||
* @param iframeWindow - iframe 的 contentWindow
|
||||
* @returns Promise,解析为页数信息
|
||||
*
|
||||
* @example
|
||||
* ```typescript
|
||||
* const info = await requestPageInfo(iframeWindow);
|
||||
* console.log(`文档共 ${info.totalPages} 页,当前在第 ${info.currentPage + 1} 页`);
|
||||
* ```
|
||||
*/
|
||||
export async function requestPageInfo(iframeWindow: Window): Promise<PageInfo> {
|
||||
return new Promise((resolve, reject) => {
|
||||
const timeout = setTimeout(() => {
|
||||
cleanup();
|
||||
reject(new Error('请求页数信息超时'));
|
||||
}, 5000);
|
||||
|
||||
const handleMessage = (event: MessageEvent) => {
|
||||
try {
|
||||
if (event.source !== iframeWindow) {
|
||||
return;
|
||||
}
|
||||
|
||||
const data = parseMessageData(event.data);
|
||||
|
||||
// bundle.js 的 _postMessage 会将消息转换为:
|
||||
// { MessageId: 'custompostMessage_Resp', Values: { Command: 'GET_PAGE_INFO', ... } }
|
||||
// 所以我们需要监听 MessageId 而不是 msgId
|
||||
if (
|
||||
data.MessageId === 'custompostMessage_Resp' &&
|
||||
data.Values?.Command === 'GET_PAGE_INFO' &&
|
||||
data.Values?.Status === 'success'
|
||||
) {
|
||||
clearTimeout(timeout);
|
||||
cleanup();
|
||||
|
||||
const info: PageInfo = {
|
||||
totalPages: data.Values.totalPages || 0,
|
||||
currentPage: data.Values.currentPage || 0,
|
||||
timestamp: data.Values.timestamp || Date.now(),
|
||||
};
|
||||
|
||||
resolve(info);
|
||||
}
|
||||
} catch (error) {
|
||||
clearTimeout(timeout);
|
||||
cleanup();
|
||||
reject(error);
|
||||
}
|
||||
};
|
||||
|
||||
const cleanup = () => {
|
||||
window.removeEventListener('message', handleMessage);
|
||||
};
|
||||
|
||||
window.addEventListener('message', handleMessage);
|
||||
|
||||
// 发送请求消息
|
||||
const message = {
|
||||
MessageId: 'custompostMessage',
|
||||
Values: {
|
||||
Command: 'GET_PAGE_INFO',
|
||||
Args: {},
|
||||
},
|
||||
};
|
||||
|
||||
iframeWindow.postMessage(JSON.stringify(message), '*');
|
||||
});
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user