@canopy-iiif/app 0.6.28 → 0.7.0

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.
@@ -1,102 +0,0 @@
1
- 'use strict';
2
-
3
- const React = require('react');
4
- const fs = require('fs');
5
- const path = require('path');
6
-
7
- // Cache of index/manifests to avoid repeated disk reads during a build
8
- let CACHE = { loaded: false, byId: new Map(), bySlug: new Map() };
9
-
10
- function safeReadJson(p) {
11
- try { return JSON.parse(fs.readFileSync(p, 'utf8')); } catch (_) { return null; }
12
- }
13
-
14
- function loadIndexOnce() {
15
- if (CACHE.loaded) return CACHE;
16
- const idxPath = path.resolve('.cache/iiif/index.json');
17
- const idx = safeReadJson(idxPath);
18
- if (idx && Array.isArray(idx.byId)) {
19
- for (const e of idx.byId) {
20
- if (!e || e.type !== 'Manifest') continue;
21
- const id = String(e.id || '');
22
- const slug = String(e.slug || '');
23
- const entry = { id, slug, parent: e.parent || '', thumbnail: e.thumbnail || '' };
24
- if (id) CACHE.byId.set(id, entry);
25
- if (slug) CACHE.bySlug.set(slug, entry);
26
- }
27
- }
28
- CACHE.loaded = true;
29
- return CACHE;
30
- }
31
-
32
- function readManifestTitle(slug) {
33
- try {
34
- const p = path.resolve('.cache/iiif/manifests', `${slug}.json`);
35
- const m = safeReadJson(p);
36
- const label = m && m.label;
37
- if (!label) return null;
38
- if (typeof label === 'string') return label;
39
- const keys = Object.keys(label || {});
40
- if (!keys.length) return null;
41
- const arr = label[keys[0]];
42
- if (Array.isArray(arr) && arr.length) return String(arr[0]);
43
- return null;
44
- } catch (_) { return null; }
45
- }
46
-
47
- function deriveTitleFromSlug(slug) {
48
- try {
49
- const s = decodeURIComponent(String(slug || ''));
50
- return s.replace(/[-_]+/g, ' ').replace(/\s+/g, ' ').trim() || s;
51
- } catch (_) { return String(slug || ''); }
52
- }
53
-
54
- function IIIFCard(props) {
55
- const { id, slug, href, src, title, subtitle, alt, className, style, ...rest } = props || {};
56
- const { byId, bySlug } = loadIndexOnce();
57
- let entry = null;
58
- if (id && byId.has(String(id))) entry = byId.get(String(id));
59
- else if (slug && bySlug.has(String(slug))) entry = bySlug.get(String(slug));
60
-
61
- const resolvedSlug = (entry && entry.slug) || (slug ? String(slug) : '');
62
- const resolvedHref = href || (resolvedSlug ? `/works/${resolvedSlug}.html` : '#');
63
- const resolvedSrc = src || (entry && entry.thumbnail) || '';
64
- const resolvedTitle = title || readManifestTitle(resolvedSlug) || deriveTitleFromSlug(resolvedSlug);
65
- const resolvedAlt = alt || resolvedTitle || '';
66
-
67
- let Card = null;
68
- try {
69
- // Load the UI Card component for consistent markup/styles
70
- const ui = require('@canopy-iiif/app/ui');
71
- Card = ui && (ui.Card || ui.default && ui.default.Card) ? (ui.Card || ui.default.Card) : null;
72
- } catch (_) { Card = null; }
73
-
74
- if (Card) {
75
- return React.createElement(Card, {
76
- href: resolvedHref,
77
- src: resolvedSrc || undefined,
78
- alt: resolvedAlt,
79
- title: resolvedTitle,
80
- subtitle,
81
- className,
82
- style,
83
- ...rest,
84
- });
85
- }
86
- // Fallback minimal markup if UI is unavailable
87
- return React.createElement(
88
- 'a',
89
- { href: resolvedHref, className, style, ...rest },
90
- React.createElement(
91
- 'figure',
92
- { style: { margin: 0 } },
93
- resolvedSrc ? React.createElement('img', { src: resolvedSrc, alt: resolvedAlt, loading: 'lazy', style: { display: 'block', width: '100%', height: 'auto', borderRadius: 4 } }) : null,
94
- React.createElement('figcaption', { style: { marginTop: 8 } },
95
- resolvedTitle ? React.createElement('strong', { style: { display: 'block' } }, resolvedTitle) : null,
96
- subtitle ? React.createElement('span', { style: { display: 'block', color: '#6b7280' } }, subtitle) : null,
97
- )
98
- )
99
- );
100
- }
101
-
102
- module.exports = IIIFCard;
@@ -1,44 +0,0 @@
1
- import React from 'react';
2
- import { createRoot } from 'react-dom/client';
3
- import { CommandPaletteApp } from '@canopy-iiif/app/ui';
4
-
5
- function ready(fn) {
6
- if (document.readyState === 'loading') document.addEventListener('DOMContentLoaded', fn, { once: true });
7
- else fn();
8
- }
9
- function parseProps(el) {
10
- try { const s = el.querySelector('script[type="application/json"]'); if (s) return JSON.parse(s.textContent || '{}'); } catch {}
11
- return {};
12
- }
13
- function withBase(href) {
14
- try {
15
- const bp = (window && window.CANOPY_BASE_PATH) ? String(window.CANOPY_BASE_PATH) : '';
16
- if (!bp) return href;
17
- if (/^https?:/i.test(href)) return href;
18
- const clean = String(href || '').replace(/^\/+/, '');
19
- return (bp.endsWith('/') ? bp.slice(0, -1) : bp) + '/' + clean;
20
- } catch { return href; }
21
- }
22
- function rootBase() { try { const bp = (window && window.CANOPY_BASE_PATH) ? String(window.CANOPY_BASE_PATH) : ''; return bp && bp.endsWith('/') ? bp.slice(0, -1) : bp; } catch { return ''; } }
23
-
24
- ready(async function () {
25
- const host = document.querySelector('[data-canopy-command]');
26
- if (!host) return;
27
- const cfg = parseProps(host) || {};
28
- let records = [];
29
- let loading = true;
30
- try {
31
- let v = '';
32
- try { const m = await fetch(rootBase() + '/api/index.json').then((r) => r && r.ok ? r.json() : null).catch(() => null); v = (m && m.version) || ''; } catch {}
33
- const res = await fetch(rootBase() + '/api/search-index.json' + (v ? ('?v=' + encodeURIComponent(v)) : '')).catch(() => null);
34
- const j = res && res.ok ? await res.json().catch(() => []) : [];
35
- records = Array.isArray(j) ? j : ((j && j.records) || []);
36
- loading = false;
37
- } catch {}
38
- const ReactObj = (window && window.React) || null;
39
- const RDC = (window && window.ReactDOMClient) || null;
40
- if (!ReactObj || !RDC || !RDC.createRoot) return;
41
- const root = RDC.createRoot(host);
42
- const onSelect = (href) => { try { window.location.href = withBase(String(href || '')); } catch {} };
43
- root.render(React.createElement(CommandPaletteApp, { records, loading, config: cfg, onSelect }));
44
- });
File without changes
File without changes
File without changes