chore: harden lightrag knowledge rag runtime
This commit is contained in:
@@ -690,11 +690,18 @@ export const createResourceTabRuntime = (dependencies = {}) => {
|
||||
const entry = resourceTabRegistry.get(activeResource);
|
||||
const documentId = String(entry?.ownerDocumentId || entry?.documentId || '').trim();
|
||||
if (documentId) url.pathname = `/documents/${encodeURIComponent(documentId)}`;
|
||||
const sourceKind = String(entry?.sourceKind || currentWebShellSourceKind() || '').trim();
|
||||
const rootUri = String(entry?.rootUri || currentWebShellRootUri() || '').trim();
|
||||
const resourcePath = String(entry?.path || entry?.session?.resourcePath || '').trim();
|
||||
if (sourceKind) url.searchParams.set('sourceKind', sourceKind);
|
||||
if (rootUri) url.searchParams.set('rootUri', rootUri);
|
||||
if (resourcePath) url.searchParams.set('resourcePath', resourcePath);
|
||||
url.searchParams.set('resourceTab', activeResource);
|
||||
} else {
|
||||
const documentId = currentWebShellDocumentId();
|
||||
if (documentId) url.pathname = `/documents/${encodeURIComponent(documentId)}`;
|
||||
url.searchParams.delete('resourceTab');
|
||||
url.searchParams.delete('resourcePath');
|
||||
}
|
||||
replaceUrlState(url);
|
||||
};
|
||||
@@ -1085,6 +1092,59 @@ export const createResourceTabRuntime = (dependencies = {}) => {
|
||||
overlay.style.height = `${Math.max(1, bbox.y1 - bbox.y0)}px`;
|
||||
};
|
||||
|
||||
const applyPdfEvidenceOverlayToCanvas = (canvas, locator) => {
|
||||
if (!(canvas instanceof HTMLCanvasElement)) return null;
|
||||
const frame = canvas.parentElement instanceof HTMLElement && canvas.parentElement.hasAttribute('data-mnote-pdf-page-frame')
|
||||
? canvas.parentElement
|
||||
: null;
|
||||
if (!(frame instanceof HTMLElement)) return null;
|
||||
const bbox = normalizeEvidenceBBox(locator?.bbox);
|
||||
let overlay = frame.querySelector('[data-mnote-evidence-bbox-highlight]');
|
||||
if (!bbox) {
|
||||
if (overlay instanceof HTMLElement) overlay.hidden = true;
|
||||
return null;
|
||||
}
|
||||
const viewport = canvas.__mnotePdfViewport;
|
||||
if (!viewport || typeof viewport.convertToViewportRectangle !== 'function') return null;
|
||||
if (!(overlay instanceof HTMLElement)) {
|
||||
overlay = document.createElement('div');
|
||||
overlay.className = 'mnote-resource-tab-bbox-highlight';
|
||||
overlay.setAttribute('data-mnote-evidence-bbox-highlight', 'true');
|
||||
frame.append(overlay);
|
||||
}
|
||||
const normalizedMineruBox = bbox.x0 >= 0 && bbox.y0 >= 0 && bbox.x1 <= 1000 && bbox.y1 <= 1000;
|
||||
let x;
|
||||
let y;
|
||||
let width;
|
||||
let height;
|
||||
if (normalizedMineruBox) {
|
||||
x = Math.min(bbox.x0, bbox.x1) / 1000 * viewport.width;
|
||||
y = Math.min(bbox.y0, bbox.y1) / 1000 * viewport.height;
|
||||
width = Math.max(1, Math.abs(bbox.x1 - bbox.x0) / 1000 * viewport.width);
|
||||
height = Math.max(1, Math.abs(bbox.y1 - bbox.y0) / 1000 * viewport.height);
|
||||
} else {
|
||||
const rect = viewport.convertToViewportRectangle([bbox.x0, bbox.y0, bbox.x1, bbox.y1]);
|
||||
x = Math.min(rect[0], rect[2]);
|
||||
y = Math.min(rect[1], rect[3]);
|
||||
width = Math.max(1, Math.abs(rect[2] - rect[0]));
|
||||
height = Math.max(1, Math.abs(rect[3] - rect[1]));
|
||||
}
|
||||
overlay.hidden = false;
|
||||
overlay.style.left = `${Math.max(0, x)}px`;
|
||||
overlay.style.top = `${Math.max(0, y)}px`;
|
||||
overlay.style.width = `${width}px`;
|
||||
overlay.style.height = `${height}px`;
|
||||
return overlay;
|
||||
};
|
||||
|
||||
const scrollPdfEvidenceTargetIntoView = (canvas, overlay) => {
|
||||
const target = overlay instanceof HTMLElement && !overlay.hidden
|
||||
? overlay
|
||||
: (canvas?.parentElement instanceof HTMLElement ? canvas.parentElement : canvas);
|
||||
if (!(target instanceof HTMLElement)) return;
|
||||
window.setTimeout(() => target.scrollIntoView({ block: 'center', inline: 'nearest' }), 0);
|
||||
};
|
||||
|
||||
const applyEvidenceLocatorToTextPanel = (entry, locator) => {
|
||||
if (!(entry?.panel instanceof HTMLElement) || !locator) return;
|
||||
const root = entry.panel.querySelector('[data-testid="mnote-leptos-tiptap-island-editor-root"]');
|
||||
@@ -1119,8 +1179,12 @@ export const createResourceTabRuntime = (dependencies = {}) => {
|
||||
entry.panel.querySelectorAll('canvas.mnote-pdf-page[data-mnote-evidence-page="true"]').forEach((node) => {
|
||||
if (node instanceof HTMLElement) node.removeAttribute('data-mnote-evidence-page');
|
||||
});
|
||||
entry.panel.querySelectorAll('[data-mnote-evidence-bbox-highlight]').forEach((node) => {
|
||||
if (node instanceof HTMLElement) node.hidden = true;
|
||||
});
|
||||
canvas.setAttribute('data-mnote-evidence-page', 'true');
|
||||
canvas.scrollIntoView({ block: 'center', inline: 'nearest' });
|
||||
const overlay = applyPdfEvidenceOverlayToCanvas(canvas, locator);
|
||||
scrollPdfEvidenceTargetIntoView(canvas, overlay);
|
||||
};
|
||||
|
||||
const applyEvidenceLocatorToEntry = (entry, input = {}) => {
|
||||
@@ -1328,16 +1392,23 @@ export const createResourceTabRuntime = (dependencies = {}) => {
|
||||
const scale = Math.max(0.6, Math.min(2.4, availableWidth / baseViewport.width));
|
||||
const viewport = page.getViewport({ scale });
|
||||
const outputScale = Math.min(2.5, Math.max(2, window.devicePixelRatio || 1));
|
||||
const frame = document.createElement('div');
|
||||
frame.setAttribute('data-mnote-pdf-page-frame', 'true');
|
||||
frame.style.position = 'relative';
|
||||
frame.style.width = `${Math.floor(viewport.width)}px`;
|
||||
frame.style.maxWidth = '100%';
|
||||
frame.style.margin = '0 auto 14px';
|
||||
const canvas = document.createElement('canvas');
|
||||
canvas.className = 'mnote-pdf-page';
|
||||
canvas.setAttribute('data-page-number', String(pageNumber));
|
||||
canvas.__mnotePdfViewport = viewport;
|
||||
canvas.width = Math.floor(viewport.width * outputScale);
|
||||
canvas.height = Math.floor(viewport.height * outputScale);
|
||||
canvas.style.display = 'block';
|
||||
canvas.style.maxWidth = '100%';
|
||||
canvas.style.width = `${Math.floor(viewport.width)}px`;
|
||||
canvas.style.height = `${Math.floor(viewport.height)}px`;
|
||||
canvas.style.margin = '0 auto 14px';
|
||||
canvas.style.margin = '0';
|
||||
canvas.style.background = '#fff';
|
||||
canvas.style.border = '1px solid #d8d8d2';
|
||||
canvas.style.boxShadow = '0 2px 10px rgba(25, 25, 22, .08)';
|
||||
@@ -1351,25 +1422,12 @@ export const createResourceTabRuntime = (dependencies = {}) => {
|
||||
const evidencePage = Number(evidenceLocator?.page || 0);
|
||||
if (evidencePage === pageNumber) {
|
||||
canvas.setAttribute('data-mnote-evidence-page', 'true');
|
||||
const bbox = normalizeEvidenceBBox(evidenceLocator?.bbox);
|
||||
if (bbox) {
|
||||
const rect = viewport.convertToViewportRectangle([bbox.x0, bbox.y0, bbox.x1, bbox.y1]);
|
||||
const x = Math.min(rect[0], rect[2]);
|
||||
const y = Math.min(rect[1], rect[3]);
|
||||
const width = Math.max(1, Math.abs(rect[2] - rect[0]));
|
||||
const height = Math.max(1, Math.abs(rect[3] - rect[1]));
|
||||
context.save();
|
||||
context.scale(outputScale, outputScale);
|
||||
context.fillStyle = 'rgba(37, 99, 235, 0.18)';
|
||||
context.strokeStyle = 'rgba(37, 99, 235, 0.9)';
|
||||
context.lineWidth = 2;
|
||||
context.fillRect(x, y, width, height);
|
||||
context.strokeRect(x, y, width, height);
|
||||
context.restore();
|
||||
}
|
||||
}
|
||||
if (entry.inlinePdfDocument === pdf) viewer.append(canvas);
|
||||
if (evidencePage === pageNumber) window.setTimeout(() => canvas.scrollIntoView({ block: 'center', inline: 'nearest' }), 0);
|
||||
frame.append(canvas);
|
||||
let evidenceOverlay = null;
|
||||
if (evidencePage === pageNumber) evidenceOverlay = applyPdfEvidenceOverlayToCanvas(canvas, evidenceLocator);
|
||||
if (entry.inlinePdfDocument === pdf) viewer.append(frame);
|
||||
if (evidencePage === pageNumber) scrollPdfEvidenceTargetIntoView(canvas, evidenceOverlay);
|
||||
};
|
||||
|
||||
const openInlinePdfResourceTab = async (entry, input) => {
|
||||
|
||||
Reference in New Issue
Block a user