fix:修复Collabora组件高亮传入页码时失效的问题,增强两种高亮方法的兼容性
This commit is contained in:
@@ -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 };
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user