mirror of
https://github.com/lllin000/PaperForge.git
synced 2026-07-22 06:50:53 +00:00
feat: add PDF.js internal overlay guards and tests
This commit is contained in:
parent
262541598f
commit
1b79c369ca
2 changed files with 87 additions and 0 deletions
|
|
@ -206,6 +206,43 @@ function canUseAnnotationOverlay(app, isMobile) {
|
|||
return true;
|
||||
}
|
||||
|
||||
function hasPdfJsLayerAlignment(windowObj) {
|
||||
try {
|
||||
return !!(windowObj && windowObj.pdfjsLib && typeof windowObj.pdfjsLib.setLayerDimensions === 'function');
|
||||
} catch { return false; }
|
||||
}
|
||||
|
||||
function tryResolvePdfInternalViewer(view) {
|
||||
if (!view) return null;
|
||||
try {
|
||||
// Try common internal property paths used by Obsidian's PDF viewer
|
||||
var viewerComponent = view.viewer || view.pdfViewer || view.pdfViewerComponent;
|
||||
if (!viewerComponent && view.constructor && view.constructor.prototype) {
|
||||
var proto = view.constructor.prototype;
|
||||
var desc = Object.getOwnPropertyDescriptor(proto, 'viewer')
|
||||
|| Object.getOwnPropertyDescriptor(proto, 'pdfViewer');
|
||||
if (desc) {
|
||||
viewerComponent = typeof desc.get === 'function' ? desc.get.call(view) : (desc.value || (view[desc]));
|
||||
}
|
||||
}
|
||||
if (!viewerComponent && view.pdfViewer) viewerComponent = view.pdfViewer;
|
||||
if (!viewerComponent) return null;
|
||||
// Check if pdfViewer has getPageView
|
||||
var pdfViewer = viewerComponent.pdfViewer || viewerComponent;
|
||||
if (pdfViewer && typeof pdfViewer.getPageView === 'function') return pdfViewer;
|
||||
return null;
|
||||
} catch { return null; }
|
||||
}
|
||||
|
||||
function canRenderPdfInternalOverlayHandle(handle) {
|
||||
if (!handle) return false;
|
||||
try {
|
||||
return typeof handle.getPageView === 'function'
|
||||
&& typeof handle.currentScale === 'number'
|
||||
&& typeof handle.pagesCount === 'number';
|
||||
} catch { return false; }
|
||||
}
|
||||
|
||||
// ── Bridge helpers ──
|
||||
|
||||
function runAnnotationSubprocess(vaultPath, pythonInfo, args, timeout, _spawn) {
|
||||
|
|
@ -461,6 +498,9 @@ module.exports = {
|
|||
toggleDisclosureState,
|
||||
detectConflictingPlugins,
|
||||
canUseAnnotationOverlay,
|
||||
hasPdfJsLayerAlignment,
|
||||
tryResolvePdfInternalViewer,
|
||||
canRenderPdfInternalOverlayHandle,
|
||||
runAnnotationSubprocess,
|
||||
ANNOTATION_COLORS,
|
||||
ANNOTATION_DEFAULT_COLOR,
|
||||
|
|
|
|||
|
|
@ -9,6 +9,9 @@ const {
|
|||
parseRuntimeStatus,
|
||||
detectConflictingPlugins,
|
||||
canUseAnnotationOverlay,
|
||||
hasPdfJsLayerAlignment,
|
||||
tryResolvePdfInternalViewer,
|
||||
canRenderPdfInternalOverlayHandle,
|
||||
} = await import('../src/testable.js');
|
||||
|
||||
describe('classifyError', () => {
|
||||
|
|
@ -157,3 +160,47 @@ describe('canUseAnnotationOverlay', () => {
|
|||
expect(canUseAnnotationOverlay(app, false)).toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
describe('hasPdfJsLayerAlignment', () => {
|
||||
it('returns true when setLayerDimensions exists', () => {
|
||||
expect(hasPdfJsLayerAlignment({ pdfjsLib: { setLayerDimensions: function () {} } })).toBe(true);
|
||||
});
|
||||
it('returns false when pdfjsLib is missing', () => {
|
||||
expect(hasPdfJsLayerAlignment({})).toBe(false);
|
||||
});
|
||||
it('returns false for null', () => {
|
||||
expect(hasPdfJsLayerAlignment(null)).toBe(false);
|
||||
});
|
||||
it('returns false when setLayerDimensions is not a function', () => {
|
||||
expect(hasPdfJsLayerAlignment({ pdfjsLib: { setLayerDimensions: 42 } })).toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
describe('tryResolvePdfInternalViewer', () => {
|
||||
it('returns null for null view', () => {
|
||||
expect(tryResolvePdfInternalViewer(null)).toBeNull();
|
||||
});
|
||||
it('returns null when view has no accessible pdf viewer', () => {
|
||||
expect(tryResolvePdfInternalViewer({})).toBeNull();
|
||||
});
|
||||
it('resolves getPageView from deep pdfViewer path', () => {
|
||||
var view = {
|
||||
viewer: { pdfViewer: { getPageView: function () {}, currentScale: 1, pagesCount: 10 } },
|
||||
};
|
||||
var handle = tryResolvePdfInternalViewer(view);
|
||||
expect(handle).toBeTruthy();
|
||||
expect(typeof handle.getPageView).toBe('function');
|
||||
});
|
||||
});
|
||||
|
||||
describe('canRenderPdfInternalOverlayHandle', () => {
|
||||
it('returns true for valid handle', () => {
|
||||
expect(canRenderPdfInternalOverlayHandle({ getPageView: function () {}, currentScale: 1, pagesCount: 10 })).toBe(true);
|
||||
});
|
||||
it('returns false for null', () => {
|
||||
expect(canRenderPdfInternalOverlayHandle(null)).toBe(false);
|
||||
});
|
||||
it('returns false when getPageView is missing', () => {
|
||||
expect(canRenderPdfInternalOverlayHandle({ currentScale: 1, pagesCount: 10 })).toBe(false);
|
||||
});
|
||||
});
|
||||
|
|
|
|||
Loading…
Reference in a new issue