triiiceratops 0.16.6 → 0.16.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
|
@@ -173,6 +173,17 @@
|
|
|
173
173
|
|
|
174
174
|
OSD = osdModule.default || osdModule;
|
|
175
175
|
patchIiifLevel0ProfileCompatibility(OSD);
|
|
176
|
+
const userAgent = navigator.userAgent || '';
|
|
177
|
+
const isAndroidChrome =
|
|
178
|
+
/Android/i.test(userAgent) && /\bChrome\//i.test(userAgent);
|
|
179
|
+
const consumerOverrides = viewerState.config?.openSeadragonConfig ?? {};
|
|
180
|
+
|
|
181
|
+
// Prefer canvas first on Android Chrome unless consumer overrides drawer.
|
|
182
|
+
// This avoids known WebGL tile rendering issues on some mobile devices.
|
|
183
|
+
const defaultDrawer =
|
|
184
|
+
isAndroidChrome && consumerOverrides.drawer === undefined
|
|
185
|
+
? { drawer: ['canvas', 'webgl', 'html'] }
|
|
186
|
+
: {};
|
|
176
187
|
|
|
177
188
|
// Initialize OpenSeadragon viewer
|
|
178
189
|
viewer = OSD({
|
|
@@ -188,8 +199,9 @@
|
|
|
188
199
|
animationTime: 0.5,
|
|
189
200
|
springStiffness: 7.0,
|
|
190
201
|
zoomPerClick: 2.0,
|
|
202
|
+
...defaultDrawer,
|
|
191
203
|
// Consumer-provided OSD overrides
|
|
192
|
-
...
|
|
204
|
+
...consumerOverrides,
|
|
193
205
|
// Enable double-click to zoom, but keep clickToZoom disabled for Annotorious
|
|
194
206
|
gestureSettingsMouse: {
|
|
195
207
|
clickToZoom: false,
|
|
@@ -209,7 +221,9 @@
|
|
|
209
221
|
viewer.viewport.minZoomLevel = homeZoom * floorFactor;
|
|
210
222
|
|
|
211
223
|
if (overrides.minPixelRatio === undefined) {
|
|
212
|
-
|
|
224
|
+
// Lower threshold prevents blanking on sparse/level-0 pyramids
|
|
225
|
+
// when zooming far out (especially on small mobile viewports).
|
|
226
|
+
viewer.minPixelRatio = 0.1;
|
|
213
227
|
}
|
|
214
228
|
});
|
|
215
229
|
|
|
@@ -344,29 +358,6 @@
|
|
|
344
358
|
osd.__triiiceratopsIiifLevel0Patched = true;
|
|
345
359
|
}
|
|
346
360
|
|
|
347
|
-
function setViewerImageVisible(isVisible: boolean) {
|
|
348
|
-
if (!container) return;
|
|
349
|
-
container.style.opacity = isVisible ? '1' : '0';
|
|
350
|
-
}
|
|
351
|
-
|
|
352
|
-
function revealViewerImageAfterFirstRender(capturedKey: string) {
|
|
353
|
-
if (!viewer) return;
|
|
354
|
-
|
|
355
|
-
const reveal = () => {
|
|
356
|
-
if (capturedKey !== lastTileSourceStr) return;
|
|
357
|
-
setViewerImageVisible(true);
|
|
358
|
-
};
|
|
359
|
-
|
|
360
|
-
// WebGLDrawer in OSD 5 rejects tile-drawn/tile-drawing handlers.
|
|
361
|
-
const drawerType = viewer.drawer?.getType?.();
|
|
362
|
-
if (drawerType === 'webgl') {
|
|
363
|
-
viewer.addOnceHandler('open', reveal);
|
|
364
|
-
return;
|
|
365
|
-
}
|
|
366
|
-
|
|
367
|
-
viewer.addOnceHandler('tile-drawn', reveal);
|
|
368
|
-
}
|
|
369
|
-
|
|
370
361
|
// Pre-fetch info.json URLs to detect 401 auth errors before passing to OSD
|
|
371
362
|
async function resolveTileSources(
|
|
372
363
|
sources: any[],
|
|
@@ -415,7 +406,6 @@
|
|
|
415
406
|
// If sources are cleared/absent during a canvas/world switch, clear
|
|
416
407
|
// stale tiles immediately and allow the same source to reopen later.
|
|
417
408
|
if (!tileSources) {
|
|
418
|
-
setViewerImageVisible(false);
|
|
419
409
|
viewer.close();
|
|
420
410
|
viewerState.tileSourceError = null;
|
|
421
411
|
lastTileSourceStr = '';
|
|
@@ -449,7 +439,6 @@
|
|
|
449
439
|
: [];
|
|
450
440
|
|
|
451
441
|
if (sources.length === 0) {
|
|
452
|
-
setViewerImageVisible(false);
|
|
453
442
|
viewer.close();
|
|
454
443
|
viewerState.tileSourceError = null;
|
|
455
444
|
lastTileSourceStr = '';
|
|
@@ -460,10 +449,6 @@
|
|
|
460
449
|
const capturedKey = stateKey;
|
|
461
450
|
const overrides = viewerState.config?.openSeadragonConfig ?? {};
|
|
462
451
|
|
|
463
|
-
// Hide the previous image immediately; reveal once new tiles are drawn.
|
|
464
|
-
setViewerImageVisible(false);
|
|
465
|
-
revealViewerImageAfterFirstRender(capturedKey);
|
|
466
|
-
|
|
467
452
|
if (mode === 'continuous') {
|
|
468
453
|
// Remove current world immediately so stale canvases are not shown
|
|
469
454
|
// while async source resolution is in progress.
|
|
@@ -471,7 +456,7 @@
|
|
|
471
456
|
viewerState.tileSourceError = null;
|
|
472
457
|
|
|
473
458
|
if (overrides.minPixelRatio === undefined) {
|
|
474
|
-
viewer.minPixelRatio = 0.
|
|
459
|
+
viewer.minPixelRatio = 0.1;
|
|
475
460
|
}
|
|
476
461
|
if (overrides.minZoomImageRatio === undefined) {
|
|
477
462
|
viewer.minZoomImageRatio = 0.9;
|
|
@@ -589,7 +574,7 @@
|
|
|
589
574
|
|
|
590
575
|
// Restore less aggressive defaults outside continuous mode unless user-overridden.
|
|
591
576
|
if (overrides.minPixelRatio === undefined) {
|
|
592
|
-
viewer.minPixelRatio = 0.
|
|
577
|
+
viewer.minPixelRatio = 0.1;
|
|
593
578
|
}
|
|
594
579
|
if (overrides.minZoomImageRatio === undefined) {
|
|
595
580
|
viewer.minZoomImageRatio = 0.9;
|
|
@@ -77,8 +77,12 @@ describe('ViewerState - IIIF Search', () => {
|
|
|
77
77
|
* Helper to setup a mock manifest with canvases
|
|
78
78
|
*/
|
|
79
79
|
function setupMockManifest(manifestJson) {
|
|
80
|
-
const
|
|
81
|
-
|
|
80
|
+
const parsed = manifesto.parseManifest(manifestJson);
|
|
81
|
+
if (!parsed) {
|
|
82
|
+
throw new Error('Failed to parse mock manifest');
|
|
83
|
+
}
|
|
84
|
+
const mockManifest = parsed;
|
|
85
|
+
const mockCanvases = mockManifest.getSequences()[0]?.getCanvases() ?? [];
|
|
82
86
|
vi.mocked(manifestsState.getManifest).mockReturnValue(mockManifest);
|
|
83
87
|
vi.mocked(manifestsState.getCanvases).mockReturnValue(mockCanvases);
|
|
84
88
|
return { mockManifest, mockCanvases };
|