From 5cdb688903a8ba41fe78a2e5af41fd97cd1dec24 Mon Sep 17 00:00:00 2001
From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com>
Date: Wed, 24 Sep 2025 22:31:33 +0000
Subject: [PATCH 1/4] Initial plan
From 748ceade9a29aec918f0899c662e118be78cee18 Mon Sep 17 00:00:00 2001
From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com>
Date: Wed, 24 Sep 2025 22:35:43 +0000
Subject: [PATCH 2/4] Initial plan for contribution guidelines and supporting
documentation
Co-authored-by: cubap <1119165+cubap@users.noreply.github.com>
---
README.md | 144 ++++++++++++++++++
iiif-data-service.js | 349 +++++++++++++++++++++++++++++++++++++++++++
index.html | 20 +++
message-handler.js | 48 ++++++
styles.css | 102 +++++++++++++
ui-manager.js | 207 +++++++++++++++++++++++++
viewer.js | 92 ++++++++++++
7 files changed, 962 insertions(+)
create mode 100644 README.md
create mode 100644 iiif-data-service.js
create mode 100644 index.html
create mode 100644 message-handler.js
create mode 100644 styles.css
create mode 100644 ui-manager.js
create mode 100644 viewer.js
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..14c79b0
--- /dev/null
+++ b/README.md
@@ -0,0 +1,144 @@
+# IIIF Page Viewer
+
+A lightweight IIIF (International Image Interoperability Framework) image viewing tool designed for inclusion as an iframe element in other documents. This viewer displays IIIF canvases with interactive annotation overlays.
+
+## JavaScript Architecture
+
+The JavaScript is organized into four main classes:
+
+### `IIIFDataService`
+
+- Handles all IIIF-related data fetching and parsing
+- Supports both IIIF v2 and v3 manifest formats
+- Manages coordinate parsing (XYWH format)
+- Includes error handling for failed requests
+
+### `UIManager`
+
+- Manages all user interface operations
+- Handles image rendering and annotation overlay creation
+- Manages tooltips, selection states, and user interactions
+- Includes accessibility features (ARIA labels, keyboard navigation)
+
+### `MessageHandler`
+
+- Manages communication with parent windows via postMessage API
+- Handles incoming canvas URL requests
+- Extensible for additional message types
+
+### `PageViewer`
+
+- Main orchestrator class that coordinates all components
+- Provides the public API for loading canvases
+- Manages application lifecycle and initialization
+
+## Features
+
+- **Responsive Design**: Scales properly within iframe containers
+- **Accessibility**: Full keyboard navigation and screen reader support
+- **Error Handling**: Graceful degradation with user-friendly error messages
+- **Loading States**: Visual feedback during data fetching
+- **Interactive Annotations**: Clickable overlays with hover tooltips
+- **Parent Communication**: Sends annotation selection events to parent window
+- **IIIF Image API Support**: Automatically detects and handles info.json responses
+
+## Usage
+
+### As an iframe
+
+```html
+
+```
+
+### Communication with Parent Window
+
+The viewer supports multiple ways to load IIIF content via messages from the parent window:
+
+#### Direct Canvas URL
+
+```javascript
+// Send direct canvas URL to iframe
+iframe.contentWindow.postMessage({
+ type: "CANVAS_URL",
+ canvasUrl: "https://example.com/path/to/canvas/data"
+}, "*");
+```
+
+#### Manifest with Canvas Reference
+
+```javascript
+// Send manifest URL with canvas fragment identifier
+iframe.contentWindow.postMessage({
+ type: "CANVAS_URL",
+ canvasUrl: "https://example.com/manifest.json#canvas-id"
+}, "*");
+
+// Or use separate manifest and canvas ID
+iframe.contentWindow.postMessage({
+ type: "MANIFEST_CANVAS",
+ manifestUrl: "https://example.com/manifest.json",
+ canvasId: "canvas-id" // Optional - uses first canvas if omitted
+}, "*");
+```
+
+#### Listen for Events
+
+```javascript
+// Listen for annotation selection events
+window.addEventListener("message", (event) => {
+ if (event.data.type === "RETURN_LINE_ID") {
+ console.log("Selected annotation:", event.data.lineid, event.data.lineIndex);
+ }
+});
+```
+
+### Direct Canvas Loading
+
+You can also load a canvas directly via URL parameter:
+
+```text
+view-full-page-iframe.html?canvas=https://example.com/path/to/canvas/manifest
+```
+
+The canvas parameter supports:
+
+- Direct canvas data URLs
+- Manifest URLs (uses first canvas)
+- Manifest URLs with fragment identifiers: `manifest.json#canvas-id`
+
+### IIIF Image API Support
+
+The viewer automatically detects when image URLs point to IIIF Image API info.json files and constructs optimized image URLs:
+
+- **Automatic Detection**: Checks if image URLs return JSON with IIIF Image API info
+- **Size Optimization**: Calculates optimal image dimensions while maintaining aspect ratio
+- **Profile Compliance**: Respects size limitations from IIIF Image API profiles
+- **Fallback Handling**: Falls back to original URLs if IIIF Image API processing fails
+
+Example flow:
+
+1. Canvas references image: `https://example.com/iiif/image123`
+2. Viewer detects this returns info.json with IIIF Image API data
+3. Constructs optimized URL: `https://example.com/iiif/image123/full/800,600/0/default.jpg`
+
+## Browser Support
+
+- Modern browsers with ES6+ support
+- Fetch API support required
+- PostMessage API for iframe communication
+
+## IIIF Compatibility
+
+- **IIIF Presentation API** v2.x and v3.x
+- **IIIF Image API** v2.x and v3.x (automatic info.json handling)
+- Supports standard XYWH coordinate selectors
+- Automatic image URL construction from IIIF Image API info.json responses
+
+## Development
+
+The modular architecture makes it easy to:
+
+- **Extend functionality**: Add new classes or methods
+- **Modify styling**: Edit `styles.css` for visual changes
+- **Add message types**: Extend `MessageHandler` for new communication patterns
+- **Customize UI**: Modify `UIManager` for different interaction patterns
diff --git a/iiif-data-service.js b/iiif-data-service.js
new file mode 100644
index 0000000..8bd9622
--- /dev/null
+++ b/iiif-data-service.js
@@ -0,0 +1,349 @@
+/**
+ * IIIF Data Service - Handles all IIIF-related data fetching and parsing
+ * Supports IIIF Presentation API v2/v3 and IIIF Image API v2/v3
+ *
+ * @author Priyal Patel @mepripri
+ * @author Patrick Cuba @cubap
+ */
+export class IIIFDataService {
+ /**
+ * Parse XYWH coordinate string into object
+ * @param {string} target - XYWH coordinate string
+ * @returns {Object} Parsed coordinates {x, y, w, h}
+ */
+ parseXYWH(target) {
+ const xywh = target.replace("xywh=pixel:", "").split(",").map(Number)
+ return { x: xywh[0], y: xywh[1], w: xywh[2], h: xywh[3] }
+ }
+
+ /**
+ * Fetch and parse IIIF canvas data with annotations
+ * @param {string} canvasUrl - URL to the IIIF canvas or manifest containing the canvas
+ * @returns {Promise