@canopy-iiif/app 1.4.14 → 1.4.16
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.
- package/lib/build/iiif.js +163 -39
- package/lib/common.js +22 -2
- package/package.json +1 -1
- package/ui/styles/components/_buttons.scss +29 -4
- package/ui/styles/components/_card.scss +1 -1
- package/ui/styles/index.css +17 -5
package/lib/build/iiif.js
CHANGED
|
@@ -138,6 +138,23 @@ function resolveThumbnailPreferences() {
|
|
|
138
138
|
};
|
|
139
139
|
}
|
|
140
140
|
|
|
141
|
+
function ensureThumbnailValue(target, url, width, height) {
|
|
142
|
+
if (!target) return false;
|
|
143
|
+
const current = target.thumbnail;
|
|
144
|
+
const hasCurrent =
|
|
145
|
+
typeof current === "string" ? current.trim().length > 0 : Boolean(current);
|
|
146
|
+
if (hasCurrent) return false;
|
|
147
|
+
if (!url) return false;
|
|
148
|
+
const normalized = String(url || "").trim();
|
|
149
|
+
if (!normalized) return false;
|
|
150
|
+
target.thumbnail = normalized;
|
|
151
|
+
if (typeof width === "number" && Number.isFinite(width) && width > 0)
|
|
152
|
+
target.thumbnailWidth = width;
|
|
153
|
+
if (typeof height === "number" && Number.isFinite(height) && height > 0)
|
|
154
|
+
target.thumbnailHeight = height;
|
|
155
|
+
return true;
|
|
156
|
+
}
|
|
157
|
+
|
|
141
158
|
async function resolveHeroMedia(manifest) {
|
|
142
159
|
if (!manifest) return null;
|
|
143
160
|
try {
|
|
@@ -959,6 +976,16 @@ async function ensureFeaturedInCache(cfg) {
|
|
|
959
976
|
delete entry.ogImageHeight;
|
|
960
977
|
touched = true;
|
|
961
978
|
}
|
|
979
|
+
if (
|
|
980
|
+
ensureThumbnailValue(
|
|
981
|
+
entry,
|
|
982
|
+
heroMedia && heroMedia.heroThumbnail,
|
|
983
|
+
heroMedia && heroMedia.heroThumbnailWidth,
|
|
984
|
+
heroMedia && heroMedia.heroThumbnailHeight
|
|
985
|
+
)
|
|
986
|
+
) {
|
|
987
|
+
touched = true;
|
|
988
|
+
}
|
|
962
989
|
} catch (_) {}
|
|
963
990
|
|
|
964
991
|
if (touched) await saveManifestIndex(idx);
|
|
@@ -1191,6 +1218,12 @@ async function rebuildManifestIndexFromCache() {
|
|
|
1191
1218
|
entry.ogImageWidth = OG_IMAGE_WIDTH;
|
|
1192
1219
|
entry.ogImageHeight = OG_IMAGE_HEIGHT;
|
|
1193
1220
|
}
|
|
1221
|
+
ensureThumbnailValue(
|
|
1222
|
+
entry,
|
|
1223
|
+
heroMedia.heroThumbnail,
|
|
1224
|
+
heroMedia.heroThumbnailWidth,
|
|
1225
|
+
heroMedia.heroThumbnailHeight
|
|
1226
|
+
);
|
|
1194
1227
|
}
|
|
1195
1228
|
} catch (_) {}
|
|
1196
1229
|
nextIndex.byId.push(entry);
|
|
@@ -1850,46 +1883,133 @@ async function buildIiifCollectionPages(CONFIG) {
|
|
|
1850
1883
|
thumbUrl = String(t.url);
|
|
1851
1884
|
thumbWidth = typeof t.width === "number" ? t.width : undefined;
|
|
1852
1885
|
thumbHeight = typeof t.height === "number" ? t.height : undefined;
|
|
1853
|
-
|
|
1854
|
-
|
|
1855
|
-
|
|
1856
|
-
|
|
1857
|
-
|
|
1858
|
-
|
|
1859
|
-
|
|
1860
|
-
|
|
1886
|
+
}
|
|
1887
|
+
} catch (_) {}
|
|
1888
|
+
try {
|
|
1889
|
+
const idx = await loadManifestIndex();
|
|
1890
|
+
if (Array.isArray(idx.byId)) {
|
|
1891
|
+
const entry = idx.byId.find(
|
|
1892
|
+
(e) =>
|
|
1893
|
+
e &&
|
|
1894
|
+
e.id === String(manifest.id || id) &&
|
|
1895
|
+
e.type === "Manifest"
|
|
1896
|
+
);
|
|
1861
1897
|
if (entry) {
|
|
1862
|
-
|
|
1863
|
-
if (
|
|
1864
|
-
|
|
1865
|
-
|
|
1866
|
-
|
|
1898
|
+
let touched = false;
|
|
1899
|
+
if (thumbUrl) {
|
|
1900
|
+
const nextThumb = String(thumbUrl);
|
|
1901
|
+
if (entry.thumbnail !== nextThumb) {
|
|
1902
|
+
entry.thumbnail = nextThumb;
|
|
1903
|
+
touched = true;
|
|
1904
|
+
}
|
|
1905
|
+
if (
|
|
1906
|
+
typeof thumbWidth === "number" &&
|
|
1907
|
+
entry.thumbnailWidth !== thumbWidth
|
|
1908
|
+
) {
|
|
1909
|
+
entry.thumbnailWidth = thumbWidth;
|
|
1910
|
+
touched = true;
|
|
1911
|
+
}
|
|
1912
|
+
if (
|
|
1913
|
+
typeof thumbHeight === "number" &&
|
|
1914
|
+
entry.thumbnailHeight !== thumbHeight
|
|
1915
|
+
) {
|
|
1916
|
+
entry.thumbnailHeight = thumbHeight;
|
|
1917
|
+
touched = true;
|
|
1918
|
+
}
|
|
1919
|
+
}
|
|
1867
1920
|
if (heroMedia && heroMedia.heroThumbnail) {
|
|
1868
|
-
entry.heroThumbnail
|
|
1869
|
-
|
|
1921
|
+
if (entry.heroThumbnail !== heroMedia.heroThumbnail) {
|
|
1922
|
+
entry.heroThumbnail = heroMedia.heroThumbnail;
|
|
1923
|
+
touched = true;
|
|
1924
|
+
}
|
|
1925
|
+
if (
|
|
1926
|
+
typeof heroMedia.heroThumbnailWidth === "number" &&
|
|
1927
|
+
entry.heroThumbnailWidth !== heroMedia.heroThumbnailWidth
|
|
1928
|
+
) {
|
|
1870
1929
|
entry.heroThumbnailWidth = heroMedia.heroThumbnailWidth;
|
|
1871
|
-
|
|
1930
|
+
touched = true;
|
|
1931
|
+
}
|
|
1932
|
+
if (
|
|
1933
|
+
typeof heroMedia.heroThumbnailHeight === "number" &&
|
|
1934
|
+
entry.heroThumbnailHeight !== heroMedia.heroThumbnailHeight
|
|
1935
|
+
) {
|
|
1872
1936
|
entry.heroThumbnailHeight = heroMedia.heroThumbnailHeight;
|
|
1937
|
+
touched = true;
|
|
1938
|
+
}
|
|
1873
1939
|
if (heroMedia.heroThumbnailSrcset) {
|
|
1874
|
-
|
|
1875
|
-
|
|
1940
|
+
if (
|
|
1941
|
+
entry.heroThumbnailSrcset !== heroMedia.heroThumbnailSrcset
|
|
1942
|
+
) {
|
|
1943
|
+
entry.heroThumbnailSrcset = heroMedia.heroThumbnailSrcset;
|
|
1944
|
+
touched = true;
|
|
1945
|
+
}
|
|
1946
|
+
if (entry.heroThumbnailSizes !== HERO_IMAGE_SIZES_ATTR) {
|
|
1947
|
+
entry.heroThumbnailSizes = HERO_IMAGE_SIZES_ATTR;
|
|
1948
|
+
touched = true;
|
|
1949
|
+
}
|
|
1950
|
+
}
|
|
1951
|
+
} else {
|
|
1952
|
+
if (entry.heroThumbnail !== undefined) {
|
|
1953
|
+
delete entry.heroThumbnail;
|
|
1954
|
+
touched = true;
|
|
1955
|
+
}
|
|
1956
|
+
if (entry.heroThumbnailWidth !== undefined) {
|
|
1957
|
+
delete entry.heroThumbnailWidth;
|
|
1958
|
+
touched = true;
|
|
1959
|
+
}
|
|
1960
|
+
if (entry.heroThumbnailHeight !== undefined) {
|
|
1961
|
+
delete entry.heroThumbnailHeight;
|
|
1962
|
+
touched = true;
|
|
1963
|
+
}
|
|
1964
|
+
if (entry.heroThumbnailSrcset !== undefined) {
|
|
1965
|
+
delete entry.heroThumbnailSrcset;
|
|
1966
|
+
touched = true;
|
|
1967
|
+
}
|
|
1968
|
+
if (entry.heroThumbnailSizes !== undefined) {
|
|
1969
|
+
delete entry.heroThumbnailSizes;
|
|
1970
|
+
touched = true;
|
|
1876
1971
|
}
|
|
1877
1972
|
}
|
|
1878
1973
|
if (heroMedia && heroMedia.ogImage) {
|
|
1879
|
-
entry.ogImage
|
|
1880
|
-
|
|
1881
|
-
|
|
1974
|
+
if (entry.ogImage !== heroMedia.ogImage) {
|
|
1975
|
+
entry.ogImage = heroMedia.ogImage;
|
|
1976
|
+
touched = true;
|
|
1977
|
+
}
|
|
1978
|
+
if (entry.ogImageWidth !== OG_IMAGE_WIDTH) {
|
|
1979
|
+
entry.ogImageWidth = OG_IMAGE_WIDTH;
|
|
1980
|
+
touched = true;
|
|
1981
|
+
}
|
|
1982
|
+
if (entry.ogImageHeight !== OG_IMAGE_HEIGHT) {
|
|
1983
|
+
entry.ogImageHeight = OG_IMAGE_HEIGHT;
|
|
1984
|
+
touched = true;
|
|
1985
|
+
}
|
|
1882
1986
|
} else {
|
|
1883
1987
|
try {
|
|
1884
|
-
if (entry.ogImage !== undefined)
|
|
1885
|
-
|
|
1988
|
+
if (entry.ogImage !== undefined) {
|
|
1989
|
+
delete entry.ogImage;
|
|
1990
|
+
touched = true;
|
|
1991
|
+
}
|
|
1992
|
+
if (entry.ogImageWidth !== undefined) {
|
|
1886
1993
|
delete entry.ogImageWidth;
|
|
1887
|
-
|
|
1994
|
+
touched = true;
|
|
1995
|
+
}
|
|
1996
|
+
if (entry.ogImageHeight !== undefined) {
|
|
1888
1997
|
delete entry.ogImageHeight;
|
|
1998
|
+
touched = true;
|
|
1999
|
+
}
|
|
1889
2000
|
} catch (_) {}
|
|
1890
2001
|
}
|
|
1891
|
-
|
|
1892
|
-
|
|
2002
|
+
if (
|
|
2003
|
+
ensureThumbnailValue(
|
|
2004
|
+
entry,
|
|
2005
|
+
heroMedia && heroMedia.heroThumbnail,
|
|
2006
|
+
heroMedia && heroMedia.heroThumbnailWidth,
|
|
2007
|
+
heroMedia && heroMedia.heroThumbnailHeight
|
|
2008
|
+
)
|
|
2009
|
+
) {
|
|
2010
|
+
touched = true;
|
|
2011
|
+
}
|
|
2012
|
+
if (touched) await saveManifestIndex(idx);
|
|
1893
2013
|
}
|
|
1894
2014
|
}
|
|
1895
2015
|
} catch (_) {}
|
|
@@ -1916,20 +2036,21 @@ async function buildIiifCollectionPages(CONFIG) {
|
|
|
1916
2036
|
annotationValue = "";
|
|
1917
2037
|
}
|
|
1918
2038
|
}
|
|
1919
|
-
const
|
|
1920
|
-
|
|
1921
|
-
const
|
|
1922
|
-
typeof
|
|
1923
|
-
? thumbWidth
|
|
1924
|
-
: heroMedia && typeof heroMedia.heroThumbnailWidth === "number"
|
|
2039
|
+
const fallbackThumbnail =
|
|
2040
|
+
(heroMedia && heroMedia.heroThumbnail) || "";
|
|
2041
|
+
const fallbackThumbWidth =
|
|
2042
|
+
heroMedia && typeof heroMedia.heroThumbnailWidth === "number"
|
|
1925
2043
|
? heroMedia.heroThumbnailWidth
|
|
1926
2044
|
: undefined;
|
|
1927
|
-
const
|
|
1928
|
-
typeof
|
|
1929
|
-
? thumbHeight
|
|
1930
|
-
: heroMedia && typeof heroMedia.heroThumbnailHeight === "number"
|
|
2045
|
+
const fallbackThumbHeight =
|
|
2046
|
+
heroMedia && typeof heroMedia.heroThumbnailHeight === "number"
|
|
1931
2047
|
? heroMedia.heroThumbnailHeight
|
|
1932
2048
|
: undefined;
|
|
2049
|
+
const navThumbnail = thumbUrl || fallbackThumbnail;
|
|
2050
|
+
const navThumbWidth =
|
|
2051
|
+
typeof thumbWidth === "number" ? thumbWidth : fallbackThumbWidth;
|
|
2052
|
+
const navThumbHeight =
|
|
2053
|
+
typeof thumbHeight === "number" ? thumbHeight : fallbackThumbHeight;
|
|
1933
2054
|
const navRecord = navPlace.buildManifestNavPlaceRecord({
|
|
1934
2055
|
manifest,
|
|
1935
2056
|
slug,
|
|
@@ -1942,16 +2063,19 @@ async function buildIiifCollectionPages(CONFIG) {
|
|
|
1942
2063
|
});
|
|
1943
2064
|
if (navRecord) navPlaceRecords.push(navRecord);
|
|
1944
2065
|
|
|
2066
|
+
const recordThumbnail = navThumbnail;
|
|
2067
|
+
const recordThumbWidth = navThumbWidth;
|
|
2068
|
+
const recordThumbHeight = navThumbHeight;
|
|
1945
2069
|
iiifRecords.push({
|
|
1946
2070
|
id: String(manifest.id || id),
|
|
1947
2071
|
title,
|
|
1948
2072
|
href: pageHref,
|
|
1949
2073
|
type: "work",
|
|
1950
|
-
thumbnail:
|
|
2074
|
+
thumbnail: recordThumbnail || undefined,
|
|
1951
2075
|
thumbnailWidth:
|
|
1952
|
-
typeof
|
|
2076
|
+
typeof recordThumbWidth === "number" ? recordThumbWidth : undefined,
|
|
1953
2077
|
thumbnailHeight:
|
|
1954
|
-
typeof
|
|
2078
|
+
typeof recordThumbHeight === "number" ? recordThumbHeight : undefined,
|
|
1955
2079
|
searchMetadataValues:
|
|
1956
2080
|
metadataValues && metadataValues.length
|
|
1957
2081
|
? metadataValues
|
package/lib/common.js
CHANGED
|
@@ -12,6 +12,7 @@ const { readBasePath, withBasePath } = require('./base-path');
|
|
|
12
12
|
|
|
13
13
|
const BASE_PATH = readBasePath();
|
|
14
14
|
let cachedAppearance = null;
|
|
15
|
+
let cachedAccent = null;
|
|
15
16
|
|
|
16
17
|
function resolveThemeAppearance() {
|
|
17
18
|
if (cachedAppearance) return cachedAppearance;
|
|
@@ -29,6 +30,21 @@ function resolveThemeAppearance() {
|
|
|
29
30
|
return cachedAppearance;
|
|
30
31
|
}
|
|
31
32
|
|
|
33
|
+
function resolveThemeAccent() {
|
|
34
|
+
if (cachedAccent) return cachedAccent;
|
|
35
|
+
cachedAccent = 'indigo';
|
|
36
|
+
try {
|
|
37
|
+
const { loadCanopyTheme } = require('@canopy-iiif/app/ui/theme');
|
|
38
|
+
if (typeof loadCanopyTheme === 'function') {
|
|
39
|
+
const theme = loadCanopyTheme();
|
|
40
|
+
const accent = theme && theme.accent && theme.accent.name ? String(theme.accent.name) : '';
|
|
41
|
+
const normalized = accent.trim().toLowerCase();
|
|
42
|
+
if (normalized) cachedAccent = normalized;
|
|
43
|
+
}
|
|
44
|
+
} catch (_) {}
|
|
45
|
+
return cachedAccent;
|
|
46
|
+
}
|
|
47
|
+
|
|
32
48
|
function readYamlConfigBaseUrl() {
|
|
33
49
|
try {
|
|
34
50
|
const y = require('js-yaml');
|
|
@@ -100,12 +116,16 @@ function htmlShell({ title, body, cssHref, scriptHref, headExtra, bodyClass }) {
|
|
|
100
116
|
const extra = headExtra ? String(headExtra) : '';
|
|
101
117
|
const cssTag = cssHref ? `<link rel="stylesheet" href="${cssHref}">` : '';
|
|
102
118
|
const appearance = resolveThemeAppearance();
|
|
103
|
-
const
|
|
119
|
+
const accent = resolveThemeAccent();
|
|
120
|
+
const htmlAttrs = [];
|
|
121
|
+
if (appearance === 'dark') htmlAttrs.push('class="dark"');
|
|
122
|
+
htmlAttrs.push(`data-accent="${accent || 'indigo'}"`);
|
|
123
|
+
const htmlAttr = htmlAttrs.length ? ` ${htmlAttrs.join(' ')}` : '';
|
|
104
124
|
const hasCustomTitle = /<title\b/i.test(extra);
|
|
105
125
|
const titleTag = hasCustomTitle ? '' : `<title>${title}</title>`;
|
|
106
126
|
const bodyClassName = normalizeClassList(bodyClass);
|
|
107
127
|
const bodyAttr = bodyClassName ? ` class="${bodyClassName}"` : '';
|
|
108
|
-
return `<!doctype html><html lang="en"${
|
|
128
|
+
return `<!doctype html><html lang="en"${htmlAttr}><head><meta charset="utf-8"/><meta name="viewport" content="width=device-width, initial-scale=1"/>${titleTag}${extra}${cssTag}${scriptTag}</head><body${bodyAttr}>${body}</body></html>`;
|
|
109
129
|
}
|
|
110
130
|
|
|
111
131
|
function withBase(href) {
|
package/package.json
CHANGED
|
@@ -22,8 +22,7 @@
|
|
|
22
22
|
|
|
23
23
|
&:hover,
|
|
24
24
|
&:focus-visible {
|
|
25
|
-
background-color: var(--color-accent-
|
|
26
|
-
color: var(--color-gray-50);
|
|
25
|
+
background-color: var(--color-accent-600);
|
|
27
26
|
}
|
|
28
27
|
}
|
|
29
28
|
|
|
@@ -42,10 +41,36 @@
|
|
|
42
41
|
);
|
|
43
42
|
background-color: color-mix(
|
|
44
43
|
in srgb,
|
|
45
|
-
var(--color-accent-
|
|
44
|
+
var(--color-accent-300) 25%,
|
|
46
45
|
transparent
|
|
47
46
|
);
|
|
48
|
-
color: var(--color-accent-
|
|
47
|
+
color: var(--color-accent-900);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
html[data-accent="amber"],
|
|
53
|
+
html[data-accent="yellow"],
|
|
54
|
+
html[data-accent="lime"],
|
|
55
|
+
html[data-accent="mint"],
|
|
56
|
+
html[data-accent="sky"] {
|
|
57
|
+
.canopy-button--primary {
|
|
58
|
+
color: var(--color-gray-900);
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
html.dark {
|
|
63
|
+
.canopy-button--primary {
|
|
64
|
+
color: var(--color-gray-900);
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
&[data-accent="amber"],
|
|
68
|
+
&[data-accent="yellow"],
|
|
69
|
+
&[data-accent="lime"],
|
|
70
|
+
&[data-accent="mint"],
|
|
71
|
+
&[data-accent="sky"] {
|
|
72
|
+
.canopy-button--primary {
|
|
73
|
+
color: var(--color-gray-50);
|
|
49
74
|
}
|
|
50
75
|
}
|
|
51
76
|
}
|
package/ui/styles/index.css
CHANGED
|
@@ -164,8 +164,7 @@ section[data-footnotes] ul li,
|
|
|
164
164
|
box-shadow: 0 18px 32px -22px rgba(15, 23, 42, 0.55);
|
|
165
165
|
}
|
|
166
166
|
.canopy-button--primary:hover, .canopy-button--primary:focus-visible {
|
|
167
|
-
background-color: var(--color-accent-
|
|
168
|
-
color: var(--color-gray-50);
|
|
167
|
+
background-color: var(--color-accent-600);
|
|
169
168
|
}
|
|
170
169
|
.canopy-button--secondary {
|
|
171
170
|
border: 1px solid color-mix(in srgb, var(--color-gray-300) 60%, transparent);
|
|
@@ -174,8 +173,21 @@ section[data-footnotes] ul li,
|
|
|
174
173
|
}
|
|
175
174
|
.canopy-button--secondary:hover, .canopy-button--secondary:focus-visible {
|
|
176
175
|
border-color: color-mix(in srgb, var(--color-accent-400) 65%, transparent);
|
|
177
|
-
background-color: color-mix(in srgb, var(--color-accent-
|
|
178
|
-
color: var(--color-accent-
|
|
176
|
+
background-color: color-mix(in srgb, var(--color-accent-300) 25%, transparent);
|
|
177
|
+
color: var(--color-accent-900);
|
|
178
|
+
}
|
|
179
|
+
html[data-accent=amber] .canopy-button--primary,
|
|
180
|
+
html[data-accent=yellow] .canopy-button--primary,
|
|
181
|
+
html[data-accent=lime] .canopy-button--primary,
|
|
182
|
+
html[data-accent=mint] .canopy-button--primary,
|
|
183
|
+
html[data-accent=sky] .canopy-button--primary {
|
|
184
|
+
color: var(--color-gray-900);
|
|
185
|
+
}
|
|
186
|
+
html.dark .canopy-button--primary {
|
|
187
|
+
color: var(--color-gray-900);
|
|
188
|
+
}
|
|
189
|
+
html.dark[data-accent=amber] .canopy-button--primary, html.dark[data-accent=yellow] .canopy-button--primary, html.dark[data-accent=lime] .canopy-button--primary, html.dark[data-accent=mint] .canopy-button--primary, html.dark[data-accent=sky] .canopy-button--primary {
|
|
190
|
+
color: var(--color-gray-50);
|
|
179
191
|
}
|
|
180
192
|
.canopy-button-group {
|
|
181
193
|
display: flex;
|
|
@@ -231,7 +243,7 @@ section[data-footnotes] ul li,
|
|
|
231
243
|
position: relative;
|
|
232
244
|
width: 100%;
|
|
233
245
|
padding-bottom: var(--canopy-card-padding);
|
|
234
|
-
background-color:
|
|
246
|
+
background-color: var(--color-gray-100);
|
|
235
247
|
overflow: hidden;
|
|
236
248
|
}
|
|
237
249
|
.canopy-card .canopy-card-media > img {
|