PostMessage API 用于在 Collabora Online 的浏览器部分被包含在一个父框架中时,与其进行交互。这对于希望将 Collabora Online 集成到自身应用中的宿主(Host)非常有用。 此 API 主要基于 **WOPI 规范**,并带有少量扩展/修改。所有发送的消息都采用以下形式: ```plain { "MessageId": "", "SendTime": "", "Values": { "": "" } } ``` `SendTime` 是浏览器 `Date.now()` 返回的时间戳。从 WOPI 宿主发送的 Post 消息也应采用相同的格式。 需要注意的是,正如 WOPI 规范中提到的,如果尚未收到 `Host_PostmessageReady` 消息,Collabora Online 框架将忽略所有来自宿主框架的 Post 消息。此外,由于将 Collabora Online 嵌入为 iframe 必须实现 WOPI,因此要求 WOPI 宿主的 `CheckFileInfo` 响应中必须包含 `PostMessageOrigin` 属性。否则,将不会发出任何 Post 消息。 --- ## 初始化(Initialization) ### 编辑器(Editor)发送给 WOPI 宿主(WOPI Host) | MessageId | Values(值) | Description(描述) | | :--- | :--- | :--- | | **App_LoadingStatus** | `Status:`(状态) `DocumentLoadedTime:`(文档加载时间) `Features:`(功能) | **状态 (**`Status`**):** - `Frame_Ready`: Collabora Online 框架已加载,可显示 UI。 - `Document_Loaded`: 文档已完全加载,宿主可以开始使用 PostMessage API。 - `Failed`: 文档加载失败,但宿主可显示 Collabora Online 框架以呈现错误。 - `Initialized`: 编辑器中的 PostMessage 监听器已初始化。WOPI 宿主可以开始发送 Post 消息(甚至在 `Frame_Ready` 之前)。 **附加键值:** - `Features`: 此客户端的功能。支持的值包括:`VersionStates`(通知宿主客户端支持不同的版本状态)。 - `DocumentLoadedTime`: 当 Status 为 `Document_Loaded` 时可用。 | ### WOPI 宿主(WOPI Host)发送给编辑器(Editor) | MessageId | Values(值) | Description(描述) | | :--- | :--- | :--- | | **Host_PostmessageReady** | _无_ | 详情请参见 WOPI 文档。 | --- ## 查询(Query) 您可以使用 Post 消息 API 从编辑器查询数据。所有响应的 `MessageId` 都以查询消息的 `MessageId` 加上 `_Resp` 后缀返回。 ### 查询消息(WOPI 宿主发送给 Editor) | MessageId | Values(值) | Description(描述) | | :--- | :--- | :--- | | **Get_Views** | _无_ | 查询编辑器中当前活跃的文档视图。响应以 `Get_Views_Resp` 形式返回。 | | **Get_Export_Formats** | _无_ | 查询编辑器中当前打开文档支持的所有导出格式。响应以 `Get_Export_Formats_Resp` 形式返回。 | | **Get_User_State** | _无_ | 查询编辑器中当前用户活动状态(是空闲或活跃)。响应以 `Get_User_State_Resp` 形式返回。 | ### 查询响应(Editor 发送给 WOPI Host) | MessageId | Values(值) | Description(描述) | | :--- | :--- | :--- | | **Get_Views_Resp** | `ViewId:`(视图 ID) `UserId:`(用户 ID) `UserName:`(用户名) `Color:`(颜色) `ReadOnly:`(只读) `IsCurrentView:`(是否为当前视图) | 提供使用 `Get_Views` 查询时所有当前视图的详细信息。 | | **Get_Export_Formats_Resp** | `Label:`(标签) `Format:`(格式) | 对 `Get_Export_Formats` 查询的响应。 `Label` 包含解释格式的本地化字符串。 `Format` 是请求文档导出时所需的文件扩展名。 | | **Get_User_State_Resp** | `State:`(状态) `Elapsed:`(已逝时间) | 对 `Get_User_State` 查询的响应。 `State` 包含用户活动状态的非本地化字符串(“active”或“idle”)。 `Elapsed` 是用户上次活动以来的秒数。 | --- ## 会话管理(Session Management) ### WOPI 宿主发送给 Editor | MessageId | Values(值) | Description(描述) | | :--- | :--- | :--- | | **Action_RemoveView** | `ViewId:`(视图 ID) | 移除会话。 | | **Reset_Access_Token** | `token:`(令牌) | 重置访问令牌。从现在起将使用新的令牌。 | ### Editor 发送给 WOPI Host | MessageId | Values(值) | Description(描述) | | :--- | :--- | :--- | | **View_Added** | `ViewId:` `UserId:` `UserName:` `Color:` `ReadOnly:` | **已弃用 (Deprecated: true)**; 新成员已添加。 _注:此消息已弃用,请转而实现对 _`Views_List`_ 的处理,其有效载荷与 _`Get_Views_Resp`_ 相同。_ | | **View_Removed** | `ViewId:`(视图 ID) | **已弃用 (Deprecated: true)**; `ViewId` 对应的视图已关闭文档。 _注:此消息已弃用,请转而实现对 _`Get_Views_Resp`_ 或 _`Views_List`_ 的处理。_ | | **Session_Closed** | `Reason:`(原因) | 会话已关闭。`Reason` 字段详细说明了来源:`OwnerTermination` (所有者终止), `DocumentIdle` (文档空闲), `OOM` (内存不足), `ShuttingDown` (服务器维护关机), `DocumentDisconnected` (文档问题)。 | | **Views_List** | _参见 Get_Views_Resp_ | 关于当前连接视图的完整信息。 | | **User_Idle** | _无_ | 指示用户进入空闲状态。发生在配置文件 `/etc/coolwsd/coolwsd.xml` 中定义的较长非活动时间之后。 | | **User_Active** | _无_ | 指示用户再次变为活跃状态。发生在用户点击空闲屏幕之后。 | --- ## 动作(Actions) ### WOPI 宿主发送给 Editor | MessageId | Values(值) | Description(描述) | | :--- | :--- | :--- | | **Action_Save** | `DontTerminateEdit:`(不终止编辑) `DontSaveIfUnmodified:`(未修改不保存) `Notify:`(通知) `ExtendedData:`(扩展数据) | 保存文档。 - `DontTerminateEdit`: 与电子表格相关,设置 true 不会终止编辑模式。 - `DontSaveIfUnmodified`: 如果文档未修改,则阻止保存到存储。 - `Notify`: 如果为 true,则在保存文档时通知宿主(参见 `Action_Save_Resp`)。 - `ExtendedData`: 可选数据,通过 `X-COOL-WOPI-ExtendedData` 头部传递给 WOPI 宿主。 | | **Action_SaveAs** | `Filename:`(文件名) `Notify:`(通知) | 以给定 `Filename` 创建文档副本。 | | **Action_FollowUser** | `Follow:`(跟随) `ViewId:`(视图 ID) | 开启或关闭跟随用户功能。 - `Follow`: `true` 开启跟随,`false` 关闭。 - `ViewId`: 指定要跟随的用户。未定义时,跟随当前编辑器。 | | **Action_Close** | _无_ | 关闭文档。 | | **Close_Session** | _无_ | 允许在文档完全加载之前关闭会话。 | | **Action_Fullscreen** | _无_ | 切换到全屏模式。 | | **Action_FullscreenPresentation** | `StartSlideNumber:`(起始幻灯片编号) `CurrentSlide:`(当前幻灯片) | 在 Impress 中开始演示。 - `StartSlideNumber`: 可选,指定起始幻灯片(从 0 开始)。 - `CurrentSlide`: 如果为 true,则从当前幻灯片开始演示。 | | **Action_Print** | _无_ | 打印文档。 | | **Action_Export** | `Format:`(格式) `Notify:`(通知) | 以下载指定 `Format` 的文档(`Format` 必须来自 `Get_Export_Formats` 列表)。 | | **Action_InsertGraphic** | `url:` | 从 URL 下载图像并将其插入到文档中。通常是对 `UI_InsertGraphic` 的响应。 | | **Action_InsertLink** | `url:` | 在文档中插入链接。通常是对 `UI_PickLink` 的响应。 | | **Action_InsertMultimedia** | `url:` | _24.04.10 版本新增。_ 从 URL 下载多媒体并插入。可能是对 `UI_InsertFile` 的响应。 | | **Action_ShowBusy** | `Label:`(标签) | 显示一个进行中的覆盖层,带有给定的 `Label`。 | | **Action_HideBusy** | _无_ | 隐藏任何进行中的覆盖层。 | | **Action_ChangeUIMode** | `Mode:`(模式) | 更改用户界面:`'classic'` (经典工具栏) 或 `'notebookbar'` (笔记本栏)。 | | **Action_Paste** | `Mimetype:`(MIME 类型) `Data:`(数据) | 将数据直接粘贴到文档中,绕过内部粘贴机制。 示例:`{Mimetype: "text/plain;charset=utf-8", Data: "foo"}`。 | ### Editor 发送给 WOPI 宿主(响应) | MessageId | Values(值) | Description(描述) | | :--- | :--- | :--- | | **Action_Load_Resp** | `success:`(成功) `result:`(结果) `errorMsg:`(错误消息) `errorType:`(错误类型) | 加载完成时的确认。 - `success`: COOL 是否成功加载文档。 - `result`: 文档未加载的原因。 - `errorMsg`: 详细的错误消息。 - `errorType`: 可选的错误标识符。 | | **Action_Save_Resp** | `success:`(成功) `result:`(结果) `errorMsg:`(错误消息) `fileName:`(文件名) | 保存完成时的确认。仅当 `Action_Save` 包含 `Notify` 参数时发出。 - `result`: 文档未保存的原因(例如,'unmodified')。 - `fileName`: 如果成功为 true,则包含保存的文件名。 | | **FollowUser_Changed** | `FollowedViewId:`(被跟随视图 ID) `IsFollowUser:`(是否跟随用户) `IsFollowEditor:`(是否跟随编辑器) | 当前跟随状态的通知。 | | **Action_ChangeUIMode_Resp** | `Mode:`(模式) | 关于 UI 模式切换(标签式/紧凑式)的通知。 | --- ## 版本恢复(Version Restore) ### WOPI 宿主发送给 Editor | MessageId | Values(值) | Description(描述) | | :--- | :--- | :--- | | **Host_VersionRestore** | `Status:`(状态) | 唯一可能的值是 `Pre_Restore`。在实际恢复文档之前发送,以便 Online 可以在恢复前保存任何未保存的更改。 | ### Editor 发送给 WOPI Host | MessageId | Values(值) | Description(描述) | | :--- | :--- | :--- | | **App_VersionRestore** | `Status:`(状态) | 对 `Host_VersionRestore` 消息的回复。可能的值(目前)是:`Pre_Restore_Ack`。意味着宿主可以继续将文档恢复到较早的版本。 | > **注意:** 仅当 `App_LoadingStatus` 中的 `Features` 包含 `VersionStates` 时,才会发出这些消息。否则,宿主可以立即将版本恢复到较早的修订。 > --- ## 杂项(Miscellaneous) ### WOPI 宿主发送给 Editor | MessageId | Values(值) | Description(描述) | | :--- | :--- | :--- | | **Insert_Button** | `id:`(ID) `imgurl:`(图像 URL) `hint:`(提示) `accessKey:`(访问键) `mobile:`(移动端) `tablet:`(平板端) `label:`(标签) `insertBefore:`(插入到之前) `unoCommand:`(UNO 命令) | 在顶部工具栏插入一个按钮。如果未设置 `unoCommand`,则在点击时响应 `Clicked_Button` Post 消息事件。 | | **Insert_ContextualButton** | `id:` `imgurl:` `hint:` `unoCommand:` | _25.04.5.3 版本新增。_ 在上下文工具栏(选中时出现)中插入按钮。如果未设置 `unoCommand`,则在点击时响应 `Clicked_ContextualButton`。 | | **Hide_Button** | `id:`(ID) | 从工具栏隐藏按钮。 | | **Show_Button** | `id:`(ID) | 在工具栏显示按钮。 | | **Remove_Button** | `id:`(ID) | 从工具栏移除按钮。 | | **Hide_Command** | `id:`(ID) | 隐藏某个命令的 UI(包括菜单项、上下文菜单项和工具栏按钮)。 | | **Show_Command** | `id:`(ID) | 显示某个命令的 UI。 | | **Hide_NotebookTab** | `id:`(ID) | _24.04.11.1 版本新增。_ 永久隐藏特定的笔记本栏选项卡。 | | **Show_NotebookTab** | `id:`(ID) | _24.04.11.1 版本新增。_ 显示特定的笔记本栏选项卡。 | | **Collapse_Notebookbar** | _无_ | 隐藏笔记本栏按钮。 | | **Extend_Notebookbar** | _无_ | 显示笔记本栏按钮。 | | **Hide_StatusBar** | _无_ | 隐藏状态栏。 | | **Show_StatusBar** | _无_ | 显示状态栏。 | | **Remove_Statusbar_Element** | `id:`(ID) | 从状态栏移除元素。 | | **Hide_Menubar** | _无_ | 隐藏菜单栏。 | | **Show_Menubar** | _无_ | 显示菜单栏。 | | **Grab_Focus** | _无_ | 将焦点恢复到应用程序。 | | **Hide_Ruler** | _无_ | 隐藏水平文档标尺(仅限 Writer)。 | | **Show_Ruler** | _无_ | 显示水平文档标尺(仅限 Writer)。 | | **Hide_Menu_Item** | `id:`(ID) | 隐藏菜单项。`id` 在 `browser/src/control/Control.Menubar.js` 中定义。 | | **Show_Menu_Item** | `id:`(ID) | 显示菜单项。 | | **Show_Sidebar** | `id:`(ID) | _24.04.10 版本新增。_ 显示侧边栏。可选 `id`:`Navigator`, `ModifyPage`, `SlideChangeWindow`, `CustomAnimation`, `MasterSlidesPanel`。 | | **Hide_Sidebar** | _无_ | _24.04.10 版本新增。_ 隐藏侧边栏。 | | **Disable_Default_UIAction** | `action:`(动作) `disable:`(禁用) | 禁用 UI 命令的默认处理程序和动作(例如 `UI_Save`、`UI_Close`)。当 `disable` 为 true 时,仅发出 Post 消息。 | | **Send_UNO_Command** | `Command:`(命令) `Args:`(参数) | 向编辑器发送 UNO 命令。 | | **Error_Messages** | `list:`(列表) | 用于覆盖编辑器中错误消息的对象列表(`{type: , msg: }`)。 | | **Hint_OnscreenKeyboard** | _无_ | 指示设备使用屏幕键盘(例如平板)。 | | **Hint_NoOnscreenKeyboard** | _无_ | 指示设备不是平板。 | #### 查找工具栏按钮 ID 工具栏按钮 ID 在以下文件中的 `getToolItems`/`create` 函数中定义: + `Control.TopToolbar.js` (桌面/平板顶部工具栏) + `Control.MobileTopBar.ts` (智能手机顶部工具栏) + `Control.MobileBottomBar.js` (智能手机底部工具栏) + `Control.StatusBar.js` (桌面状态栏) #### 查找状态栏元素 ID 状态栏按钮 ID 在 `Control.StatusBar.js` 中的 `onDocLayerInit` 函数中定义。 ### Editor 发送给 WOPI Host | MessageId | Values(值) | Description(描述) | | :--- | :--- | :--- | | **Clicked_Button** | `id:`(ID) | 点击通过 `Insert_Button` 添加的自定义按钮时发出。 | | **Clicked_ContextualButton** | `id:`(ID) | 点击通过 `Insert_ContextualButton` 添加的自定义按钮时发出。 | | **Download_As** | `Type:`(类型) `URL:` | 当用户选择 'Print'、'Show slideshow' 或 'Download As...' 且 CheckFileInfo 中的 `DownloadAsPostMessage` 为 true 时发出。`Type` 值: `'print'`, `'slideshow'`, `'export'`。 | | **UI_OpenDocument** | _无_ | 请求 WOPI 宿主打开一个弹出窗口,用户可在其中选择要查看和编辑的另一个文档。 | | **UI_CreateFile** | `DocumentType:`(文档类型) | 请求 WOPI 宿主打开一个新浏览器标签并创建新文档。`DocumentType` 可以是 `'text'`, `'spreadsheet'`, `'presentation'` 或 `'drawing'`。 | | **UI_SaveAs** | `Args: {format: ''}`(参数) | 请求 WOPI 宿主创建相应的 UI,供用户选择路径和文件名以创建当前文件的副本。对该查询的响应通过 `Action_SaveAs` 消息发送。 | | **UI_InsertGraphic** | _无_ | 请求 WOPI 宿主打开弹出窗口供用户选择图像插入。成功后,WOPI 宿主将发送 `Action_InsertGraphic` Post 消息。 | | **UI_PickLink** | _无_ | 请求 WOPI 宿主打开弹出窗口供用户选择链接插入。成功后,WOPI 宿主将发送 `Action_InsertLink` Post 消息。 | | **UI_InsertFile** | `callback:`(回调) `mimeTypeFilter:`(MIME 类型过滤器) | _24.04.10 版本新增。_ 请求 WOPI 宿主打开弹出窗口供用户选择文件插入。成功后,WOPI 宿主将发送 `callback` 参数中定义的 Post 消息。 | | **UI_InsertAIContent** | _无_ | _24.04.12 版本新增。_ 请求 WOPI 宿主打开弹出窗口供用户选择插入 AI 生成的内容。 | | **UI_Cancel_Password** | _无_ | 通知 WOPI 宿主用户在打开受密码保护的文件时点击了“取消”。 | | **UI_Hyperlink** | _无_ | 通知 WOPI 宿主用户点击了超链接并确认要离开文档以跟随该超链接。 | | **UI_Paste** | _无_ | 在移动端请求粘贴时发送。允许嵌入的移动应用程序处理剪贴板内容。 | | **Doc_ModifiedStatus** | `Values.Modified`(已修改值) | 通知以更新文档的修改状态。`Values.Modified` 为 true 表示自上次保存以来已修改,否则为 false。 | --- ## 调用 Python 脚本(Calling Python scripts) ### WOPI 宿主发送给 Editor | MessageId | Values(值) | Description(描述) | | :--- | :--- | :--- | | **CallPythonScript** | `ScriptFile:`(脚本文件) `Function:`(函数) `Values:`(值) | 调用 Python 脚本。`Values` 包含传递给脚本的命名参数对象。 | ### Editor 发送给 WOPI Host | MessageId | Values(值) | Description(描述) | | :--- | :--- | :--- | | **CallPythonScript-Result** | `commandName:`(命令名称) `Values:`(值) | 返回结果。`commandName` 中是调用脚本的 URL。 | --- ## 提及功能(Mentions) _注意:目前提及功能仅在 Writer 中可用。_ ### Editor 发送给 WOPI Host | MessageId | Values(值) | Description(描述) | | :--- | :--- | :--- | | **UI_Mention** | `type: autocomplete`(类型: 自动完成) `text:`(文本) | 当用户输入“@”时,Collabora Online 会发送此 Post 消息,附带部分文本,以获取集成商提供的用户名列表。 | | **UI_Mention** | `type: selected`(类型: 已选择) `username:`(用户名) | 当用户从集成商提供的列表中选择一个用户名时触发此消息。 | ### WOPI 宿主发送给 Editor | MessageId | Values(值) | Description(描述) | | :--- | :--- | :--- | | **Action_Mention** | `list:`(列表) | 集成商应发送此消息作为对 `UI_Mention` (自动完成类型) 消息的响应。消息必须包含用户对象列表: `{ username: "...", profile: "...", label: "..." }` | --- ## 嵌入 Iframe(Embedding Iframe) ### Editor 发送给 WOPI Host Collabora Online 发送 `Iframe_Height` Post 消息给 WOPI 宿主,以动态调整嵌入式 iframe 的高度并防止出现滚动条。 | MessageId | Values(值) | Description(描述) | | :--- | :--- | :--- | | **Iframe_Height** | `ContentHeight:`(内容高度) | 使用 `ContentHeight` 值在 UI 中动态设置嵌入式 iframe 的高度。 |