fix:修复Collabora组件高亮传入页码时失效的问题,增强两种高亮方法的兼容性

This commit is contained in:
PingChuan
2025-12-09 17:56:45 +08:00
parent 7ce3acd771
commit d60405ceda
+76 -32
View File
@@ -10,25 +10,25 @@
* @encoding UTF-8 * @encoding UTF-8
*/ */
import { useRef, forwardRef, useImperativeHandle, useState, useEffect } from 'react'; import { forwardRef, useEffect, useImperativeHandle, useRef, useState } from 'react';
import type { CollaboraViewerProps, CollaboraViewerHandle } from './types'; import { useCollaboraConfig, useCollaboraUnoCommands, useDocumentReady } from './hooks';
import { useCollaboraConfig, useDocumentReady, useCollaboraUnoCommands } from './hooks';
import { sendUnoCommand } from './Uno';
import { clearHighlights } from './lib/ClearHighlight';
import { import {
unoScrollToTop,
requestPageInfo,
customGotoPage, customGotoPage,
unoSearchNext, highlightText as pythonHighlightText,
unoReplaceCurrent,
unoReplaceAll,
unoCancelSearch,
replaceTextInPage, replaceTextInPage,
requestPageInfo,
unoCancelSearch,
unoHighlightText, unoHighlightText,
unoClearHighlight, unoReplaceAll,
type PageInfo, unoReplaceCurrent,
type GotoPageResponse unoScrollToTop,
unoSearchNext,
type GotoPageResponse,
type PageInfo
} from './lib'; } from './lib';
import { clearHighlights } from './lib/ClearHighlight';
import type { CollaboraViewerHandle, CollaboraViewerProps } from './types';
import { sendUnoCommand } from './Uno';
/** /**
* Collabora 文档查看器组件 * Collabora 文档查看器组件
@@ -185,7 +185,9 @@ export const CollaboraViewer = forwardRef<CollaboraViewerHandle, CollaboraViewer
}), [unoCommands, isDocumentLoaded, mode]); }), [unoCommands, isDocumentLoaded, mode]);
// 5. 监听 targetPage 和 highlightText 变化,自动跳转并高亮 // 5. 监听 targetPage 和 highlightText 变化,自动跳转并高亮
// 使用 UNO 命令实现高亮,不再使用 Python 脚本 // 根据是否有 targetPage 参数选择高亮方式:
// - 有 targetPage:使用 Python 脚本(支持跨页搜索和精确跳转)
// - 无 targetPage:使用 UNO 命令(当前页面高亮,性能更好)
useEffect(() => { useEffect(() => {
// 如果文档未加载完成,不执行跳转和高亮 // 如果文档未加载完成,不执行跳转和高亮
if (!isDocumentLoaded || !iframeRef.current?.contentWindow) { if (!isDocumentLoaded || !iframeRef.current?.contentWindow) {
@@ -199,7 +201,7 @@ export const CollaboraViewer = forwardRef<CollaboraViewerHandle, CollaboraViewer
const textToHighlight = highlightText.trim(); const textToHighlight = highlightText.trim();
try { try {
// 步骤1:清除之前的所有高亮(调用 Python 脚本) // 步骤1:清除之前的所有高亮
console.log('[CollaboraViewer] 步骤1:清除旧高亮...'); console.log('[CollaboraViewer] 步骤1:清除旧高亮...');
await clearHighlights(iframeWindow, { await clearHighlights(iframeWindow, {
color: 16776960, // 黄色 color: 16776960, // 黄色
@@ -209,18 +211,36 @@ export const CollaboraViewer = forwardRef<CollaboraViewerHandle, CollaboraViewer
// 短暂延迟,确保清除操作完成 // 短暂延迟,确保清除操作完成
await new Promise(resolve => setTimeout(resolve, 100)); await new Promise(resolve => setTimeout(resolve, 100));
// 步骤2使用 UNO 命令高亮新文本(搜索 + 设置背景色) // 步骤2根据是否有 targetPage 选择高亮方式
console.log(`[CollaboraViewer] 步骤2:高亮文本 "${textToHighlight}"`); if (targetPage !== undefined && targetPage !== null) {
// 方案A:有 targetPage - 使用 Python 脚本(跨页搜索 + 高亮 + 跳转)
console.log(`[CollaboraViewer] 步骤2A:使用 Python 脚本跳转到第 ${targetPage} 页并高亮 "${textToHighlight}"`);
const result = await pythonHighlightText(iframeWindow, textToHighlight, {
color: 16776960, // 黄色
page: targetPage,
});
if (result.success) {
console.log(`[CollaboraViewer] ✓ Python 高亮成功: "${textToHighlight}" (第${targetPage}页, 共${result.highlightedCount}处)`);
} else {
console.error('[CollaboraViewer] ✗ Python 高亮失败:', result.message);
}
} else {
// 方案B:无 targetPage - 使用 UNO 命令(当前页面高亮)
console.log(`[CollaboraViewer] 步骤2B:使用 UNO 命令在当前页高亮 "${textToHighlight}"`);
unoHighlightText(iframeWindow, textToHighlight, 16776960); // 黄色 unoHighlightText(iframeWindow, textToHighlight, 16776960); // 黄色
// 短暂延迟,确保高亮操作完成 // 短暂延迟,确保高亮操作完成
await new Promise(resolve => setTimeout(resolve, 100)); await new Promise(resolve => setTimeout(resolve, 100));
// 步骤3取消选中状态(避免高亮后文本仍被选中) // 取消选中状态(避免高亮后文本仍被选中)
console.log('[CollaboraViewer] 步骤3:取消选中状态...'); console.log('[CollaboraViewer] 步骤3:取消选中状态...');
sendUnoCommand(iframeWindow, '.uno:Escape', {}); sendUnoCommand(iframeWindow, '.uno:Escape', {});
console.log(`[CollaboraViewer] ✓ 高亮完成: "${textToHighlight}"`); console.log(`[CollaboraViewer] ✓ UNO 高亮完成: "${textToHighlight}"`);
}
} catch (error) { } catch (error) {
console.error('[CollaboraViewer] 高亮失败:', error); console.error('[CollaboraViewer] 高亮失败:', error);
} }
@@ -481,16 +501,40 @@ export const CollaboraViewer = forwardRef<CollaboraViewerHandle, CollaboraViewer
return; return;
} }
await performTextHighlight( const iframeWindow = iframeRef.current.contentWindow;
iframeRef.current.contentWindow, const textToHighlight = highlightTextInput.trim();
highlightTextInput.trim(),
{ page }
);
// 更新上一次高亮的文本 // 先清除旧高亮
setPreviousHighlightText(highlightTextInput.trim()); await clearHighlights(iframeWindow, {
const pageInfo = page ? ` (第${page}页)` : ''; color: 16776960,
setHighlightResult(`✓ 已切换高亮: ${highlightTextInput.trim()}${pageInfo}`); timeout: 5000,
});
await new Promise(resolve => setTimeout(resolve, 100));
// 根据是否有页码选择高亮方式
if (page !== undefined) {
// 使用 Python 脚本(跨页搜索 + 高亮 + 跳转)
const result = await pythonHighlightText(iframeWindow, textToHighlight, {
color: 16776960,
page: page,
});
if (result.success) {
setPreviousHighlightText(textToHighlight);
setHighlightResult(`✓ 已切换高亮: ${textToHighlight} (第${page}页, 共${result.highlightedCount}处)`);
} else {
setHighlightResult(`✗ 高亮失败: ${result.message}`);
}
} else {
// 使用 UNO 命令(当前页面高亮)
unoHighlightText(iframeWindow, textToHighlight, 16776960);
await new Promise(resolve => setTimeout(resolve, 100));
sendUnoCommand(iframeWindow, '.uno:Escape', {});
setPreviousHighlightText(textToHighlight);
setHighlightResult(`✓ 已切换高亮: ${textToHighlight} (当前页)`);
}
} catch (e) { } catch (e) {
console.error('切换高亮失败:', e); console.error('切换高亮失败:', e);
setHighlightResult(`切换失败: ${e instanceof Error ? e.message : '未知错误'}`); setHighlightResult(`切换失败: ${e instanceof Error ? e.message : '未知错误'}`);
@@ -1041,8 +1085,7 @@ export const CollaboraViewer = forwardRef<CollaboraViewerHandle, CollaboraViewer
</button> </button>
</div> </div>
{searchReplaceResult && ( {searchReplaceResult && (
<div className={`mt-2 text-xs ${ <div className={`mt-2 text-xs ${searchReplaceResult.startsWith('✓') ? 'text-green-600' :
searchReplaceResult.startsWith('✓') ? 'text-green-600' :
searchReplaceResult.startsWith('✗') ? 'text-red-600' : searchReplaceResult.startsWith('✗') ? 'text-red-600' :
'text-gray-600' 'text-gray-600'
}`}> }`}>
@@ -1144,5 +1187,6 @@ export const CollaboraViewer = forwardRef<CollaboraViewerHandle, CollaboraViewer
}); });
// 导出类型和 hook // 导出类型和 hook
export type { CollaboraViewerHandle };
export { useCollaboraUnoCommands }; export { useCollaboraUnoCommands };
export type { CollaboraViewerHandle };