Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 18 additions & 5 deletions nginx/app/dependencies/diva.js/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ TS_ESM_SRC := src/diva-esm.ts
TS_VE_SRC := src/viewer-element.ts
TS_FT_SRC := src/filters.ts
TS_AUTH_SRC := src/auth.ts
TS_UTILS_SRC := src/image-utils.ts
CSS_SRC := $(wildcard src/styles/*.css)
DIVA_CSS := cache/diva.css
ELM_OUT := cache/elm.js
Expand Down Expand Up @@ -38,7 +39,7 @@ define print_bundle_size
printf "%-18s %10s (%7s)\n" "Gzipped size:" "$$GZIPPED_SIZE bytes" "$$GZIPPED_HR";
endef

.PHONY: all build build-dev clean clean-cache docs docs-check release report-build-sizes test
.PHONY: all build build-dev clean clean-cache docs docs-check release report-build-sizes review serve test

all: build

Expand All @@ -53,6 +54,15 @@ build-dev:
test:
yarn test

test-browser:
yarn test:browser

serve:
python3 -m http.server 8003

format:
yarn format

docs:
yarn docs

Expand All @@ -69,14 +79,14 @@ $(ELM_ESM): $(ELM_OUT) $(ELM_ESM_SCRIPT)
$(DIVA_CSS): $(CSS_SRC) scripts/minify-css.mjs
node ./scripts/minify-css.mjs

$(DIVA_DEBUG): $(TS_SRC) $(TS_VE_SRC) $(TS_FT_SRC) $(TS_AUTH_SRC) $(DIVA_CSS) $(ELM_ESM)
$(DIVA_DEBUG): $(TS_SRC) $(TS_VE_SRC) $(TS_FT_SRC) $(TS_AUTH_SRC) $(TS_UTILS_SRC) $(DIVA_CSS) $(ELM_ESM)
mkdir -p public
$(ESBUILD) $(TS_SRC) $(ESBUILD_COMMON_FLAGS) --format=iife --outfile=$(DIVA_DEBUG)

$(DIVA_IIFE_BUNDLE): $(TS_SRC) $(TS_VE_SRC) $(TS_FT_SRC) $(TS_AUTH_SRC) $(DIVA_CSS) $(ELM_ESM)
$(DIVA_IIFE_BUNDLE): $(TS_SRC) $(TS_VE_SRC) $(TS_FT_SRC) $(TS_AUTH_SRC) $(TS_UTILS_SRC) $(DIVA_CSS) $(ELM_ESM)
@$(ESBUILD) $(TS_SRC) $(ESBUILD_COMMON_FLAGS) --format=iife --outfile=$(DIVA_IIFE_BUNDLE)

$(DIVA_ESM_BUNDLE): $(TS_ESM_SRC) $(TS_SRC) $(TS_VE_SRC) $(TS_FT_SRC) $(TS_AUTH_SRC) $(DIVA_CSS) $(ELM_ESM)
$(DIVA_ESM_BUNDLE): $(TS_ESM_SRC) $(TS_SRC) $(TS_VE_SRC) $(TS_FT_SRC) $(TS_AUTH_SRC) $(TS_UTILS_SRC) $(DIVA_CSS) $(ELM_ESM)
@$(ESBUILD) $(TS_ESM_SRC) $(ESBUILD_COMMON_FLAGS) --format=esm --outfile=$(DIVA_ESM_BUNDLE)

$(DIVA_JS): $(DIVA_IIFE_BUNDLE) .swcrc
Expand All @@ -87,7 +97,7 @@ $(DIVA_ESM): $(DIVA_ESM_BUNDLE) .swcrc
@mkdir -p build
@$(SWC) $(DIVA_ESM_BUNDLE) --out-file $(DIVA_ESM)

$(DIVA_TYPES): $(TS_ESM_SRC) $(TS_SRC) $(TS_VE_SRC) $(TS_FT_SRC) $(TS_AUTH_SRC) src/public-api.ts tsconfig.json
$(DIVA_TYPES): $(TS_ESM_SRC) $(TS_SRC) $(TS_VE_SRC) $(TS_FT_SRC) $(TS_AUTH_SRC) $(TS_UTILS_SRC) src/public-api.ts tsconfig.json
@mkdir -p build
@yarn -s tsc -p tsconfig.json --declaration --emitDeclarationOnly --outDir build

Expand Down Expand Up @@ -116,3 +126,6 @@ release: clean build build-dev

publish: clean build
npm publish

review:
elm-review --elmjson elm.json --config review
2 changes: 1 addition & 1 deletion nginx/app/dependencies/diva.js/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -174,7 +174,7 @@ both versions using local npm packages.

Diva supports the IIIF Authorization Flow API 2.0 `external` and `active` access profiles, including optional logout services. When both profiles are available, Diva first attempts the silent `external` flow and falls back to the interactive `active` flow when external authorization does not provide a usable token. Logging out clears the associated local access tokens and re-resolves affected images anonymously. The `kiosk` profile, redirects, substitutes, and tiered access are intentionally unsupported.

Static image resources must opt into cross-origin access with an appropriate CORS response header. Diva does not use a non-CORS fallback because doing so would break canvas-based image processing and could expose inconsistent behavior. Consequently, [GitHub issue #564](https://github.com/DDMAL/diva.js/issues/564) remains unresolved by policy.
Static image resources use anonymous CORS by default so their pixels remain available to Page View filters and Save view. Set `staticImageCorsPolicy: "fallback"` to retry a failed static-image request once without CORS, or `"none"` to use non-CORS loading immediately. Non-CORS static images remain viewable, but their pixels cannot be filtered or saved because the browser taints their canvas. [GitHub issue #564](https://github.com/DDMAL/diva.js/issues/564) describes this compatibility case.

## Development

Expand Down
16 changes: 8 additions & 8 deletions nginx/app/dependencies/diva.js/build/auth.d.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,6 @@
export type TileSourceDescriptor = {
sourceId: string;
url: string;
isStatic: boolean;
};
export type ResolvedTileSource = string | Record<string, unknown>;
import { type ResolvedTileSource, type TileSourceDescriptor } from "./image-utils";
import type { DivaStaticImageCorsPolicy } from "./public-api";
export type { ResolvedTileSource, TileSourceDescriptor } from "./image-utils";
type SendPort<T> = {
send: (value: T) => void;
};
Expand Down Expand Up @@ -98,11 +95,15 @@ export declare class AuthBrowser {
private nextConsumer;
private destroyed;
private readonly clickHandler;
constructor(ports: BrowserPorts, root: HTMLElement);
private readonly staticImageCorsPolicy;
constructor(ports: BrowserPorts, root: HTMLElement, staticImageCorsPolicy?: DivaStaticImageCorsPolicy);
resolve(source: TileSourceDescriptor, signal: AbortSignal): Promise<ResolvedTileSource>;
registerSources(_sources: TileSourceDescriptor[]): void;
invalidateSources(sourceIds: string[]): void;
useNonCorsStaticSource(sourceId: string): void;
destroy(): void;
private cancelBrowserWork;
private closePopups;
private succeed;
private fail;
private startResolution;
Expand All @@ -117,4 +118,3 @@ export declare class AuthBrowser {
private startFrame;
private cancelFrame;
}
export {};
71 changes: 69 additions & 2 deletions nginx/app/dependencies/diva.js/build/diva.d.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import "./viewer-element";
import type { DivaEventMap, DivaLayoutMode, DivaOptions, DivaPage, DivaPageSelector, DivaRegion, DivaState, ZoomToRegionOptions } from "./public-api";
export type { DivaEventMap, DivaImage, DivaLayoutMode, DivaOptions, DivaPage, DivaPageSelector, DivaPageTarget, DivaRegion, DivaSidebarPanel, DivaState, DivaViewingDirection, ZoomToRegionOptions } from "./public-api";
import type { DivaAnnotation, DivaEventMap, DivaLayoutMode, DivaOptions, DivaPage, DivaPageSelector, DivaRegion, DivaState, ZoomToRegionOptions } from "./public-api";
export type { DivaAnnotation, DivaEventMap, DivaImage, DivaLayoutMode, DivaOptions, DivaPage, DivaPageSelector, DivaPageTarget, DivaRegion, DivaSidebarPanel, DivaState, DivaStaticImageCorsPolicy, DivaViewingDirection, ZoomToRegionOptions, } from "./public-api";
/**
* A browser viewer for IIIF Presentation manifests and collections.
*
Expand Down Expand Up @@ -34,6 +34,7 @@ export declare class Diva extends EventTarget {
private readonly rootId;
private readonly root;
private readonly auth;
private readonly staticImageCorsPolicy;
private app;
private mainViewer;
private readonly tileSourceResolver;
Expand All @@ -44,6 +45,7 @@ export declare class Diva extends EventTarget {
private filterViewerElement;
private filterOptions;
private filterViewerFlipped;
private filterAccessBlocked;
private currentFilterSourceKey;
private pendingFilterPreview;
private filterPreviewVersion;
Expand All @@ -52,15 +54,23 @@ export declare class Diva extends EventTarget {
private filterPreviewController;
private isDestroyed;
private readonly handlePageChangeBound;
private readonly handleAnnotationSelectBound;
private readonly handlePageLoadedBound;
private readonly handleZoomChangeBound;
private readonly handleLoadingChangeBound;
private readonly handleStaticImageCorsFallbackBound;
private readonly handlePageLoadErrorBound;
private readonly handleFullscreenChangeBound;
private readonly handleRootClickBound;
private pages;
private readonly pagesByCanvasId;
private readonly pagesByLabel;
private readonly manifestAnnotationsByCanvas;
private readonly apiAnnotationsByCanvas;
private readonly clearedAnnotationCanvases;
private readonly annotationImageServicesByCanvas;
private annotationSelectionEnabled;
private annotationResourceId;
private state;
private readyResolve;
private readyReject;
Expand Down Expand Up @@ -107,6 +117,9 @@ export declare class Diva extends EventTarget {
private bindPorts;
private ensureMainViewer;
private copyPage;
private effectiveAnnotationsForCanvas;
private applyAnnotationsForCanvas;
private findStoredAnnotation;
private rebuildPageIndexes;
private pageForSelector;
private copyState;
Expand Down Expand Up @@ -157,6 +170,56 @@ export declare class Diva extends EventTarget {
* @returns Pages in zero-based display order. Auth tokens and resolved loading URLs are never included.
*/
getPages(): readonly DivaPage[];
/**
* Add or replace one API-supplied Web Annotation on a loaded Canvas.
*/
setAnnotation(annotation: DivaAnnotation): void;
/**
* Replace the API-supplied annotation set for the loaded manifest.
*/
setAnnotations(annotations: readonly DivaAnnotation[]): void;
/**
* Return defensive Web Annotation snapshots for one Canvas.
*/
getAnnotationsForCanvas(uri: string): readonly DivaAnnotation[];
/**
* Return defensive Web Annotation snapshots for the loaded manifest.
*/
getAllAnnotations(): readonly DivaAnnotation[];
/**
* Clear both manifest and API-supplied annotations for one Canvas.
*/
clearAnnotationsForCanvas(uri: string): void;
/**
* Clear both manifest and API-supplied annotations for every Canvas.
*/
clearAllAnnotations(): void;
/**
* Select an annotation and open its details panel.
*/
selectAnnotation(annotationId: string): void;
/**
* Return whether user annotation selection is enabled.
*/
getAnnotationSelectionEnabled(): boolean;
/**
* Enable or disable user annotation selection.
*/
setAnnotationSelectionEnabled(enabled: boolean): void;
/**
* Toggle user annotation selection and return the new state.
*/
toggleAnnotationSelectionEnabled(): boolean;
/**
* Return the IIIF Image API extract URL for an annotation, when available.
*
* @returns The extract URL, or `null` when the annotation is unknown or has no usable image region.
*/
getImageRegionForAnnotation(annotationId: string): string | null;
/**
* Return an annotation body's textual or HTML value, if present.
*/
getAnnotationBody(annotationId: string): string | undefined;
/**
* Find a displayed page by Canvas identifier or localized display label.
*
Expand Down Expand Up @@ -370,15 +433,19 @@ export declare class Diva extends EventTarget {
private handleRootClick;
private toggleFullscreenFromUserActivation;
private handlePageChange;
private handleAnnotationSelect;
private handlePageLoaded;
private handleZoomChange;
private handleLoadingChange;
private handleStaticImageCorsFallback;
private handlePageLoadError;
private handleFullscreenChange;
private ensureFilterViewer;
private ensureFilterViewerElement;
private applyFilterOptions;
private saveFilteredImage;
private isNonCorsStaticSource;
private setFilterAccessBlocked;
private getPort;
private callViewerMethod;
private callViewerMethodAsync;
Expand Down
Loading
Loading