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