@manifest-editor/creators 1.2.0 → 1.3.1
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/dist/{iiif-browser-form.lazy-ZADCSMAN.js → chunk-KLSWX2QF.js} +11 -5
- package/dist/iiif-browser-form.lazy-3EZNJN4M.js +21 -0
- package/dist/iiif-browser-form.lazy-3YUQOIEL.js +21 -0
- package/dist/iiif-browser-form.lazy-4CDWA6JD.js +47 -0
- package/dist/iiif-browser-form.lazy-4NX7YPGK.js +57 -0
- package/dist/iiif-browser-form.lazy-4X5LD2U4.js +51 -0
- package/dist/iiif-browser-form.lazy-B2RXVKR5.js +21 -0
- package/dist/iiif-browser-form.lazy-C72INDSJ.js +57 -0
- package/dist/iiif-browser-form.lazy-DCCYGD42.js +35 -0
- package/dist/iiif-browser-form.lazy-DU2NJUCE.js +46 -0
- package/dist/iiif-browser-form.lazy-DUTUHLUT.js +50 -0
- package/dist/iiif-browser-form.lazy-EJZ754MG.js +42 -0
- package/dist/iiif-browser-form.lazy-ENQRBLTJ.js +21 -0
- package/dist/iiif-browser-form.lazy-FMKQQWDE.js +33 -0
- package/dist/iiif-browser-form.lazy-FOIWPPI7.js +47 -0
- package/dist/iiif-browser-form.lazy-G7XAQYYG.js +51 -0
- package/dist/iiif-browser-form.lazy-GO6U6NE5.js +32 -0
- package/dist/iiif-browser-form.lazy-GVEEZX37.js +33 -0
- package/dist/iiif-browser-form.lazy-HBWB7QGF.js +31 -0
- package/dist/iiif-browser-form.lazy-HZ3M2DXT.js +57 -0
- package/dist/iiif-browser-form.lazy-I7KTYV3O.js +57 -0
- package/dist/iiif-browser-form.lazy-I7ZNZHID.js +48 -0
- package/dist/iiif-browser-form.lazy-IX5DFVDG.js +47 -0
- package/dist/iiif-browser-form.lazy-JX4S6NGX.js +48 -0
- package/dist/iiif-browser-form.lazy-KPB57B25.js +21 -0
- package/dist/iiif-browser-form.lazy-KYOKLDRV.js +47 -0
- package/dist/iiif-browser-form.lazy-NDPLPCQQ.js +43 -0
- package/dist/iiif-browser-form.lazy-OMDV43NQ.js +51 -0
- package/dist/iiif-browser-form.lazy-OQLU6NDJ.js +51 -0
- package/dist/iiif-browser-form.lazy-OZNQO2OO.js +21 -0
- package/dist/iiif-browser-form.lazy-QR55LXI4.js +21 -0
- package/dist/iiif-browser-form.lazy-R5TMXUBV.js +19 -0
- package/dist/iiif-browser-form.lazy-RWEJWTIW.js +21 -0
- package/dist/iiif-browser-form.lazy-T6LT6BJD.js +48 -0
- package/dist/iiif-browser-form.lazy-TWQYATEG.js +21 -0
- package/dist/iiif-browser-form.lazy-UPZXU6JB.js +51 -0
- package/dist/iiif-browser-form.lazy-W42LJ6X2.js +47 -0
- package/dist/iiif-browser-form.lazy-WAK45BLF.js +42 -0
- package/dist/iiif-browser-form.lazy-WVCVE6XK.js +21 -0
- package/dist/index.cjs +1874 -1512
- package/dist/index.d.cts +246 -33
- package/dist/index.d.ts +246 -33
- package/dist/index.js +1673 -1291
- package/dist/{manifest-browser-form.lazy-FLU4HSPW.js → manifest-browser-form.lazy-MYI26AX4.js} +1 -2
- package/package.json +13 -12
- package/dist/chunk-YSQDPG26.js +0 -30
- package/dist/iiif-browser-form.lazy-C3VAAY7I.js +0 -34
- package/dist/iiif-browser-form.lazy-QLO62DFA.js +0 -32
package/dist/index.js
CHANGED
|
@@ -1,53 +1,308 @@
|
|
|
1
1
|
import {
|
|
2
2
|
ManifestBrowserCreatorForm
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-KLSWX2QF.js";
|
|
4
4
|
|
|
5
|
-
// src/
|
|
6
|
-
import {
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
5
|
+
// src/Annotation/AudioAnnotation/index.tsx
|
|
6
|
+
import { AudioIcon } from "@manifest-editor/components";
|
|
7
|
+
|
|
8
|
+
// src/Annotation/AudioAnnotation/create-audio-annotation.tsx
|
|
9
|
+
import { useEffect as useEffect2, useState as useState2 } from "react";
|
|
10
|
+
|
|
11
|
+
// ../ui/atoms/PaddedSidebarContainer.tsx
|
|
12
|
+
import styled from "styled-components";
|
|
13
|
+
var PaddedSidebarContainer = styled.div`
|
|
14
|
+
padding: 0 0.7em;
|
|
15
|
+
margin: 0.7em 0;
|
|
16
|
+
flex: 1;
|
|
17
|
+
overflow: visible;
|
|
18
|
+
`;
|
|
19
|
+
|
|
20
|
+
// src/Annotation/AudioAnnotation/create-audio-annotation.tsx
|
|
21
|
+
import { ErrorMessage } from "@manifest-editor/components";
|
|
22
|
+
|
|
23
|
+
// ../ui/ui/MediaControls/MediaControls.tsx
|
|
24
|
+
import { formatTime, useMediaActions, useMediaElements, useMediaState } from "react-iiif-vault";
|
|
25
|
+
import { useLayoutEffect, useState } from "react";
|
|
26
|
+
|
|
27
|
+
// ../ui/ui/MediaControls/MediaControls.icons.tsx
|
|
28
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
29
|
+
var PlayIcon = (props) => /* @__PURE__ */ jsxs("svg", { ...props, viewBox: "4 4 16 16", xmlns: "http://www.w3.org/2000/svg", height: "1em", width: "1em", children: [
|
|
30
|
+
props.title ? /* @__PURE__ */ jsx("title", { children: props.title }) : null,
|
|
31
|
+
/* @__PURE__ */ jsx("path", { d: "M0 0h24v24H0z", fill: "none" }),
|
|
32
|
+
/* @__PURE__ */ jsx("path", { d: "M8 5v14l11-7z", fill: "currentColor" })
|
|
33
|
+
] });
|
|
34
|
+
var PauseIcon = (props) => /* @__PURE__ */ jsxs("svg", { ...props, viewBox: "4 4 16 16", xmlns: "http://www.w3.org/2000/svg", height: "1em", width: "1em", children: [
|
|
35
|
+
props.title ? /* @__PURE__ */ jsx("title", { children: props.title }) : null,
|
|
36
|
+
/* @__PURE__ */ jsx("path", { d: "M0 0h24v24H0z", fill: "none" }),
|
|
37
|
+
/* @__PURE__ */ jsx("path", { fill: "currentColor", d: "M6 19h4V5H6v14zm8-14v14h4V5h-4z" })
|
|
38
|
+
] });
|
|
39
|
+
var VolumeUpIcon = ({ title, ...props }) => /* @__PURE__ */ jsxs("svg", { ...props, xmlns: "http://www.w3.org/2000/svg", height: "1em", width: "1em", viewBox: "2 2 20 20", children: [
|
|
40
|
+
title ? /* @__PURE__ */ jsx("title", { children: title }) : null,
|
|
41
|
+
/* @__PURE__ */ jsx("path", { d: "M0 0h24v24H0z", fill: "none" }),
|
|
42
|
+
/* @__PURE__ */ jsx(
|
|
43
|
+
"path",
|
|
44
|
+
{
|
|
45
|
+
fill: "currentColor",
|
|
46
|
+
d: "M3 9v6h4l5 5V4L7 9H3zm13.5 3A4.5 4.5 0 0 0 14 7.97v8.05c1.48-.73 2.5-2.25 2.5-4.02zM14 3.23v2.06c2.89.86 5 3.54 5 6.71s-2.11 5.85-5 6.71v2.06c4.01-.91 7-4.49 7-8.77s-2.99-7.86-7-8.77z"
|
|
47
|
+
}
|
|
48
|
+
)
|
|
49
|
+
] });
|
|
50
|
+
var VolumeDownIcon = ({ title, ...props }) => /* @__PURE__ */ jsxs("svg", { ...props, xmlns: "http://www.w3.org/2000/svg", height: "1em", width: "1em", viewBox: "2 2 20 20", children: [
|
|
51
|
+
title ? /* @__PURE__ */ jsx("title", { children: title }) : null,
|
|
52
|
+
/* @__PURE__ */ jsx("path", { d: "M0 0h24v24H0z", fill: "none" }),
|
|
53
|
+
/* @__PURE__ */ jsx(
|
|
54
|
+
"path",
|
|
55
|
+
{
|
|
56
|
+
fill: "currentColor",
|
|
57
|
+
d: "M18.5 12c0-1.77-1.02-3.29-2.5-4.03v8.05c1.48-.73 2.5-2.25 2.5-4.02zM5 9v6h4l5 5V4L9 9H5z"
|
|
58
|
+
}
|
|
59
|
+
)
|
|
60
|
+
] });
|
|
61
|
+
var VolumeOffIcon = ({ title, ...props }) => /* @__PURE__ */ jsxs("svg", { ...props, xmlns: "http://www.w3.org/2000/svg", height: "1em", width: "1em", viewBox: "2 2 20 20", children: [
|
|
62
|
+
title ? /* @__PURE__ */ jsx("title", { children: title }) : null,
|
|
63
|
+
/* @__PURE__ */ jsx("path", { d: "M0 0h24v24H0z", fill: "none" }),
|
|
64
|
+
/* @__PURE__ */ jsx(
|
|
65
|
+
"path",
|
|
66
|
+
{
|
|
67
|
+
fill: "currentColor",
|
|
68
|
+
d: "M16.5 12A4.5 4.5 0 0 0 14 7.97v2.21l2.45 2.45c.03-.2.05-.41.05-.63zm2.5 0c0 .94-.2 1.82-.54 2.64l1.51 1.51A8.796 8.796 0 0 0 21 12c0-4.28-2.99-7.86-7-8.77v2.06c2.89.86 5 3.54 5 6.71zM4.27 3 3 4.27 7.73 9H3v6h4l5 5v-6.73l4.25 4.25c-.67.52-1.42.93-2.25 1.18v2.06a8.99 8.99 0 0 0 3.69-1.81L19.73 21 21 19.73l-9-9L4.27 3zM12 4 9.91 6.09 12 8.18V4z"
|
|
69
|
+
}
|
|
70
|
+
)
|
|
71
|
+
] });
|
|
72
|
+
|
|
73
|
+
// ../ui/ui/MediaControls/MediaControls.styles.ts
|
|
74
|
+
import styled2, { css } from "styled-components";
|
|
75
|
+
var AudioPlayerContainer = styled2.div`
|
|
76
|
+
background: #ededed; // Not in variable.
|
|
77
|
+
display: flex;
|
|
78
|
+
padding: 0.5em;
|
|
79
|
+
align-items: center;
|
|
80
|
+
`;
|
|
81
|
+
var BaseButton = styled2.button`
|
|
82
|
+
cursor: pointer;
|
|
83
|
+
padding: 0.75em 1.5em;
|
|
84
|
+
font-size: 0.938em;
|
|
85
|
+
background: none;
|
|
86
|
+
color: inherit;
|
|
87
|
+
border: none;
|
|
88
|
+
text-decoration: none;
|
|
89
|
+
display: inline-block;
|
|
90
|
+
vertical-align: top;
|
|
91
|
+
white-space: nowrap;
|
|
92
|
+
`;
|
|
93
|
+
var PlayButton = styled2(BaseButton)`
|
|
94
|
+
width: 2em;
|
|
95
|
+
height: 2em;
|
|
96
|
+
overflow: hidden;
|
|
97
|
+
font-size: 1.1em;
|
|
98
|
+
background: #fff;
|
|
99
|
+
border-radius: 3px;
|
|
100
|
+
padding: 0;
|
|
101
|
+
margin: 0;
|
|
102
|
+
color: #000; // Not in colours
|
|
103
|
+
|
|
104
|
+
&:disabled {
|
|
105
|
+
color: #999;
|
|
19
106
|
}
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
107
|
+
`;
|
|
108
|
+
var TimeDisplay = styled2.div`
|
|
109
|
+
margin: 0 1em;
|
|
110
|
+
font-size: 0.85em;
|
|
111
|
+
color: #000;
|
|
112
|
+
`;
|
|
113
|
+
var ProgressContainer = styled2.div`
|
|
114
|
+
flex: 1 1 0px;
|
|
115
|
+
height: 6px;
|
|
116
|
+
display: flex;
|
|
117
|
+
position: relative;
|
|
118
|
+
padding: 15px 0;
|
|
119
|
+
`;
|
|
120
|
+
var ProgressCurrent = styled2.div`
|
|
121
|
+
background: #d85680;
|
|
122
|
+
height: 6px;
|
|
123
|
+
pointer-events: none;
|
|
124
|
+
position: absolute;
|
|
125
|
+
top: 13px;
|
|
126
|
+
left: 0;
|
|
127
|
+
border-radius: 3px;
|
|
128
|
+
transition: width 200ms;
|
|
129
|
+
`;
|
|
130
|
+
var ProgressBackground = styled2.div`
|
|
131
|
+
position: absolute;
|
|
132
|
+
top: 13px;
|
|
133
|
+
left: 0;
|
|
134
|
+
height: 6px;
|
|
135
|
+
border-radius: 3px;
|
|
136
|
+
width: 100%;
|
|
137
|
+
pointer-events: none;
|
|
138
|
+
background: #fff;
|
|
139
|
+
`;
|
|
140
|
+
var SoundButton = styled2(BaseButton)`
|
|
141
|
+
width: 2em;
|
|
142
|
+
height: 2em;
|
|
143
|
+
overflow: hidden;
|
|
144
|
+
font-size: 1.1em;
|
|
145
|
+
background: transparent;
|
|
146
|
+
border-radius: 3px;
|
|
147
|
+
padding: 0;
|
|
148
|
+
margin: 0;
|
|
149
|
+
`;
|
|
150
|
+
var SoundContainer = styled2.div`
|
|
151
|
+
display: flex;
|
|
152
|
+
align-items: center;
|
|
153
|
+
`;
|
|
154
|
+
var VolumeContainer = styled2.div`
|
|
155
|
+
width: 0;
|
|
156
|
+
overflow: hidden;
|
|
157
|
+
transition: width 500ms;
|
|
158
|
+
color: #4a473f; // Not in colours
|
|
159
|
+
|
|
160
|
+
${(props) => props.$isOpen && css`
|
|
161
|
+
width: 150px;
|
|
162
|
+
`}
|
|
163
|
+
`;
|
|
164
|
+
var VolumeSlider = styled2.input.attrs({ type: "range" })`
|
|
165
|
+
width: 120px;
|
|
166
|
+
margin: 0 15px;
|
|
167
|
+
`;
|
|
168
|
+
|
|
169
|
+
// ../ui/madoc/components/icons/Spinner.tsx
|
|
170
|
+
import { jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
171
|
+
function Spinner(props) {
|
|
172
|
+
return /* @__PURE__ */ jsx2("svg", { width: "1em", height: "1em", viewBox: "0 0 42 42", xmlns: "http://www.w3.org/2000/svg", stroke: "#fff", ...props, children: /* @__PURE__ */ jsxs2("g", { transform: "translate(2 2)", strokeWidth: 5, fill: "none", fillRule: "evenodd", children: [
|
|
173
|
+
/* @__PURE__ */ jsx2("circle", { strokeOpacity: 0.5, cx: 18, cy: 18, r: 18 }),
|
|
174
|
+
/* @__PURE__ */ jsx2("path", { d: "M36 18c0-9.94-8.06-18-18-18", children: /* @__PURE__ */ jsx2(
|
|
175
|
+
"animateTransform",
|
|
176
|
+
{
|
|
177
|
+
attributeName: "transform",
|
|
178
|
+
type: "rotate",
|
|
179
|
+
from: "0 18 18",
|
|
180
|
+
to: "360 18 18",
|
|
181
|
+
dur: "1s",
|
|
182
|
+
repeatCount: "indefinite"
|
|
183
|
+
}
|
|
184
|
+
) })
|
|
185
|
+
] }) });
|
|
36
186
|
}
|
|
37
187
|
|
|
38
|
-
// ../ui/
|
|
39
|
-
import {
|
|
40
|
-
var
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
188
|
+
// ../ui/atoms/VisuallHidden/VisuallHidden.tsx
|
|
189
|
+
import styled3, { css as css2 } from "styled-components";
|
|
190
|
+
var visuallyHidden = css2`
|
|
191
|
+
clip: rect(1px, 1px, 1px, 1px);
|
|
192
|
+
clip-path: inset(50%);
|
|
193
|
+
height: 1px;
|
|
194
|
+
width: 1px;
|
|
195
|
+
margin: -1px;
|
|
196
|
+
overflow: hidden;
|
|
197
|
+
padding: 0;
|
|
198
|
+
position: absolute;
|
|
199
|
+
`;
|
|
200
|
+
var VisuallyHiddenLabel = styled3.label`
|
|
201
|
+
${visuallyHidden}
|
|
202
|
+
`;
|
|
44
203
|
|
|
45
|
-
//
|
|
46
|
-
import {
|
|
204
|
+
// ../ui/ui/MediaControls/MediaControls.tsx
|
|
205
|
+
import { jsx as jsx3, jsxs as jsxs3 } from "react/jsx-runtime";
|
|
206
|
+
function MediaControls(props) {
|
|
207
|
+
const [isVolumeOpen, setIsVolumeOpen] = useState(false);
|
|
208
|
+
const { progress, currentTime, element } = useMediaElements();
|
|
209
|
+
const { duration, isMuted, volume, isPlaying, playRequested } = useMediaState();
|
|
210
|
+
const { setVolume, toggleMute, play, pause, setDurationPercent } = useMediaActions();
|
|
211
|
+
const Volume = isMuted || volume === 0 ? VolumeOffIcon : volume > 50 ? VolumeUpIcon : VolumeDownIcon;
|
|
212
|
+
useLayoutEffect(() => {
|
|
213
|
+
if (element.current) {
|
|
214
|
+
const $el = element.current;
|
|
215
|
+
if ($el.error && props.onError) {
|
|
216
|
+
props.onError($el.error?.message || "Unknown error");
|
|
217
|
+
return;
|
|
218
|
+
}
|
|
219
|
+
const onError = () => {
|
|
220
|
+
if (props.onError) {
|
|
221
|
+
props.onError($el.error?.message || "Unknown error");
|
|
222
|
+
}
|
|
223
|
+
};
|
|
224
|
+
const loadedMetadata = () => {
|
|
225
|
+
if ($el.duration && props.onDuration) {
|
|
226
|
+
props.onDuration($el.duration);
|
|
227
|
+
}
|
|
228
|
+
if (props.onDimensions && $el instanceof HTMLVideoElement) {
|
|
229
|
+
props.onDimensions($el.videoWidth, $el.videoHeight);
|
|
230
|
+
}
|
|
231
|
+
};
|
|
232
|
+
$el.addEventListener("loadedmetadata", loadedMetadata);
|
|
233
|
+
$el.addEventListener("error", onError);
|
|
234
|
+
return () => {
|
|
235
|
+
$el.removeEventListener("loadedmetadata", loadedMetadata);
|
|
236
|
+
$el.removeEventListener("error", onError);
|
|
237
|
+
};
|
|
238
|
+
}
|
|
239
|
+
}, []);
|
|
240
|
+
return /* @__PURE__ */ jsxs3(AudioPlayerContainer, { children: [
|
|
241
|
+
/* @__PURE__ */ jsx3(
|
|
242
|
+
PlayButton,
|
|
243
|
+
{
|
|
244
|
+
disabled: playRequested,
|
|
245
|
+
onClick: () => {
|
|
246
|
+
if (isPlaying) {
|
|
247
|
+
pause();
|
|
248
|
+
} else {
|
|
249
|
+
play();
|
|
250
|
+
}
|
|
251
|
+
},
|
|
252
|
+
children: playRequested ? /* @__PURE__ */ jsx3(Spinner, { stroke: "#999" }) : isPlaying ? /* @__PURE__ */ jsx3(PauseIcon, { title: "Pause" }) : /* @__PURE__ */ jsx3(PlayIcon, { title: "Play" })
|
|
253
|
+
}
|
|
254
|
+
),
|
|
255
|
+
/* @__PURE__ */ jsx3(TimeDisplay, { ref: currentTime, children: "0:00" }),
|
|
256
|
+
/* @__PURE__ */ jsxs3(
|
|
257
|
+
ProgressContainer,
|
|
258
|
+
{
|
|
259
|
+
onClick: (e) => {
|
|
260
|
+
const { left, width } = e.currentTarget.getBoundingClientRect();
|
|
261
|
+
const percent = (e.pageX - left) / width;
|
|
262
|
+
setDurationPercent(percent);
|
|
263
|
+
},
|
|
264
|
+
children: [
|
|
265
|
+
/* @__PURE__ */ jsx3(ProgressBackground, {}),
|
|
266
|
+
duration ? /* @__PURE__ */ jsx3(ProgressCurrent, { ref: progress }) : null
|
|
267
|
+
]
|
|
268
|
+
}
|
|
269
|
+
),
|
|
270
|
+
/* @__PURE__ */ jsx3(TimeDisplay, { children: formatTime(duration) }),
|
|
271
|
+
/* @__PURE__ */ jsxs3(SoundContainer, { onMouseEnter: () => setIsVolumeOpen(true), onMouseLeave: () => setIsVolumeOpen(false), children: [
|
|
272
|
+
/* @__PURE__ */ jsx3(VolumeContainer, { $isOpen: isVolumeOpen, children: /* @__PURE__ */ jsxs3("span", { children: [
|
|
273
|
+
/* @__PURE__ */ jsx3(VisuallyHiddenLabel, { htmlFor: "audio-slider", children: "Change volume" }),
|
|
274
|
+
/* @__PURE__ */ jsx3(
|
|
275
|
+
VolumeSlider,
|
|
276
|
+
{
|
|
277
|
+
id: "audio-slider",
|
|
278
|
+
role: "slider",
|
|
279
|
+
disabled: isMuted,
|
|
280
|
+
min: "0",
|
|
281
|
+
max: "100",
|
|
282
|
+
value: volume,
|
|
283
|
+
onChange: (e) => setVolume(Number(e.currentTarget.value))
|
|
284
|
+
}
|
|
285
|
+
)
|
|
286
|
+
] }) }),
|
|
287
|
+
/* @__PURE__ */ jsx3(SoundButton, { onClick: () => toggleMute(), children: /* @__PURE__ */ jsx3(Volume, { title: isMuted ? "Mute" : "Unmute" }) })
|
|
288
|
+
] })
|
|
289
|
+
] });
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
// src/Annotation/AudioAnnotation/create-audio-annotation.tsx
|
|
293
|
+
import { CanvasPanel } from "react-iiif-vault";
|
|
294
|
+
import { getValue } from "@iiif/helpers";
|
|
295
|
+
import {
|
|
296
|
+
Input,
|
|
297
|
+
InputContainer,
|
|
298
|
+
InputLabel,
|
|
299
|
+
LanguageFieldEditor,
|
|
300
|
+
FormFieldWrapper
|
|
301
|
+
} from "@manifest-editor/editors";
|
|
47
302
|
|
|
48
303
|
// ../ui/atoms/Button.tsx
|
|
49
|
-
import
|
|
50
|
-
var ButtonReset =
|
|
304
|
+
import styled4 from "styled-components";
|
|
305
|
+
var ButtonReset = styled4.button`
|
|
51
306
|
border: none;
|
|
52
307
|
outline: none;
|
|
53
308
|
background-color: transparent;
|
|
@@ -60,7 +315,7 @@ var ButtonReset = styled.button`
|
|
|
60
315
|
color: inherit;
|
|
61
316
|
}
|
|
62
317
|
`;
|
|
63
|
-
var Button =
|
|
318
|
+
var Button = styled4.button`
|
|
64
319
|
padding: 0.5rem 1rem;
|
|
65
320
|
color: ${(props) => props.theme.color.main || "none"};
|
|
66
321
|
background-color: ${(props) => props.theme.color.white || "white"};
|
|
@@ -79,12 +334,12 @@ var Button = styled.button`
|
|
|
79
334
|
background: #eee;
|
|
80
335
|
}
|
|
81
336
|
`;
|
|
82
|
-
var SmallButton =
|
|
337
|
+
var SmallButton = styled4(Button)`
|
|
83
338
|
padding: 0.25em ${(props) => props.theme.padding.xs || "0.4em"};
|
|
84
339
|
height: unset;
|
|
85
340
|
background: none;
|
|
86
341
|
`;
|
|
87
|
-
var SecondaryButton =
|
|
342
|
+
var SecondaryButton = styled4(Button)`
|
|
88
343
|
{
|
|
89
344
|
padding: 0 ${(props) => props.theme.padding.medium || "1rem"};
|
|
90
345
|
color: ${(props) => props.theme.color.main || "#B84C74;"};
|
|
@@ -104,7 +359,7 @@ var SecondaryButton = styled(Button)`
|
|
|
104
359
|
}
|
|
105
360
|
}
|
|
106
361
|
`;
|
|
107
|
-
var CalltoButton =
|
|
362
|
+
var CalltoButton = styled4(Button)`
|
|
108
363
|
padding: 0 ${(props) => props.theme.padding.medium || "1rem"};
|
|
109
364
|
color: ${(props) => props.theme.color.white || "white"};
|
|
110
365
|
background-color: ${(props) => props.theme.color.main || "#B84C74;"};
|
|
@@ -118,7 +373,7 @@ var CalltoButton = styled(Button)`
|
|
|
118
373
|
background-color: ${(props) => props.theme.color.mainHover || "#B84C74;"};
|
|
119
374
|
}
|
|
120
375
|
`;
|
|
121
|
-
var ButtonGroup =
|
|
376
|
+
var ButtonGroup = styled4.div`
|
|
122
377
|
display: flex;
|
|
123
378
|
flex-direction: row;
|
|
124
379
|
flex-wrap: wrap;
|
|
@@ -126,212 +381,171 @@ var ButtonGroup = styled.div`
|
|
|
126
381
|
justify-content: ${(props) => props.$right ? "flex-end" : "flex-start"};
|
|
127
382
|
`;
|
|
128
383
|
|
|
129
|
-
//
|
|
130
|
-
import
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
overflow: visible;
|
|
136
|
-
`;
|
|
137
|
-
|
|
138
|
-
// src/ContentResource/PlaintextCreator/create-plaintext.tsx
|
|
139
|
-
import { useState } from "react";
|
|
140
|
-
import { jsx as jsx3, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
141
|
-
async function createPlaintext(data, ctx) {
|
|
142
|
-
return ctx.embed({
|
|
143
|
-
id: data.url,
|
|
144
|
-
type: "Text",
|
|
145
|
-
label: data.label,
|
|
146
|
-
format: "text/plain"
|
|
147
|
-
});
|
|
148
|
-
}
|
|
149
|
-
function CreatePlaintextForm(props) {
|
|
150
|
-
const [label, setLabel] = useState({ en: ["View as text"] });
|
|
151
|
-
const onSubmit = (e) => {
|
|
152
|
-
e.preventDefault();
|
|
153
|
-
const data = new FormData(e.target);
|
|
154
|
-
const formData = Object.fromEntries(data.entries());
|
|
155
|
-
if (formData.url) {
|
|
156
|
-
props.runCreate({ url: formData.url, label });
|
|
157
|
-
}
|
|
384
|
+
// src/Annotation/AudioAnnotation/create-audio-annotation.tsx
|
|
385
|
+
import { jsx as jsx4, jsxs as jsxs4 } from "react/jsx-runtime";
|
|
386
|
+
async function createAudioAnnotation(data, ctx) {
|
|
387
|
+
const annotation = {
|
|
388
|
+
id: ctx.generateId("annotation"),
|
|
389
|
+
type: "Annotation"
|
|
158
390
|
};
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
LanguageFieldEditor,
|
|
162
|
-
{
|
|
163
|
-
focusId: "label",
|
|
164
|
-
label: "Label",
|
|
165
|
-
fields: label,
|
|
166
|
-
onSave: (e) => setLabel(e.toInternationalString())
|
|
167
|
-
}
|
|
168
|
-
),
|
|
169
|
-
/* @__PURE__ */ jsxs2(InputContainer, { $wide: true, children: [
|
|
170
|
-
/* @__PURE__ */ jsx3(InputLabel, { htmlFor: "id", children: "Link to plaintext" }),
|
|
171
|
-
/* @__PURE__ */ jsx3(Input, { id: "url", name: "url", defaultValue: "" })
|
|
172
|
-
] }),
|
|
173
|
-
/* @__PURE__ */ jsx3(Button, { type: "submit", children: "Create" })
|
|
174
|
-
] }) });
|
|
175
|
-
}
|
|
176
|
-
|
|
177
|
-
// src/ContentResource/PlaintextCreator/index.tsx
|
|
178
|
-
import { jsx as jsx4 } from "react/jsx-runtime";
|
|
179
|
-
var plaintextCreator = {
|
|
180
|
-
id: "@manifest-editor/plaintext-creator",
|
|
181
|
-
create: createPlaintext,
|
|
182
|
-
label: "Plaintext",
|
|
183
|
-
summary: "Add link to an plaintext",
|
|
184
|
-
icon: /* @__PURE__ */ jsx4(TextFormatIcon, {}),
|
|
185
|
-
render(ctx) {
|
|
186
|
-
return /* @__PURE__ */ jsx4(CreatePlaintextForm, { ...ctx });
|
|
187
|
-
},
|
|
188
|
-
resourceType: "ContentResource",
|
|
189
|
-
resourceFields: ["label", "format"],
|
|
190
|
-
supports: {
|
|
191
|
-
parentFields: ["seeAlso", "rendering", "homepage"]
|
|
192
|
-
},
|
|
193
|
-
staticFields: {
|
|
194
|
-
format: "text/plain"
|
|
195
|
-
}
|
|
196
|
-
};
|
|
197
|
-
|
|
198
|
-
// src/ContentResource/WebPageCreator/create-web-page.tsx
|
|
199
|
-
import { LanguageFieldEditor as LanguageFieldEditor2, InputContainer as InputContainer2, InputLabel as InputLabel2, Input as Input2 } from "@manifest-editor/editors";
|
|
200
|
-
import { useState as useState2 } from "react";
|
|
201
|
-
import { jsx as jsx5, jsxs as jsxs3 } from "react/jsx-runtime";
|
|
202
|
-
async function createWebPage(data, ctx) {
|
|
203
|
-
return ctx.embed({
|
|
391
|
+
const targetType = ctx.options.targetType;
|
|
392
|
+
const body = await ctx.embed({
|
|
204
393
|
id: data.url,
|
|
205
|
-
type: "
|
|
206
|
-
|
|
207
|
-
|
|
394
|
+
type: "Sound",
|
|
395
|
+
format: "audio/mp4",
|
|
396
|
+
duration: data.duration || 0
|
|
208
397
|
});
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
398
|
+
if (targetType === "Annotation") {
|
|
399
|
+
return ctx.embed({
|
|
400
|
+
...annotation,
|
|
401
|
+
label: getValue(data.label) && data.label,
|
|
402
|
+
motivation: data.motivation || ctx.options.initialData?.motivation || "painting",
|
|
403
|
+
body,
|
|
404
|
+
target: ctx.getTarget()
|
|
405
|
+
});
|
|
406
|
+
}
|
|
407
|
+
if (targetType === "Canvas") {
|
|
408
|
+
const canvasId = ctx.generateId("canvas");
|
|
409
|
+
const pageId = ctx.generateId("annotation-page", {
|
|
410
|
+
id: canvasId,
|
|
411
|
+
type: "Canvas"
|
|
412
|
+
});
|
|
413
|
+
const annotationResource = ctx.embed({
|
|
414
|
+
...annotation,
|
|
415
|
+
motivation: "painting",
|
|
416
|
+
body,
|
|
417
|
+
target: {
|
|
418
|
+
type: "SpecificResource",
|
|
419
|
+
source: { id: canvasId, type: "Canvas" }
|
|
228
420
|
}
|
|
229
|
-
)
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
/* @__PURE__ */ jsx6("path", { d: "M0 0h24v24H0z", fill: "none" }),
|
|
243
|
-
/* @__PURE__ */ jsx6("path", { d: "M3.9 12c0-1.71 1.39-3.1 3.1-3.1h4V7H7c-2.76 0-5 2.24-5 5s2.24 5 5 5h4v-1.9H7c-1.71 0-3.1-1.39-3.1-3.1zM8 13h8v-2H8v2zm9-6h-4v1.9h4c1.71 0 3.1 1.39 3.1 3.1s-1.39 3.1-3.1 3.1h-4V17h4c2.76 0 5-2.24 5-5s-2.24-5-5-5z" })
|
|
244
|
-
] });
|
|
245
|
-
}
|
|
246
|
-
|
|
247
|
-
// src/ContentResource/WebPageCreator/index.tsx
|
|
248
|
-
import { jsx as jsx7 } from "react/jsx-runtime";
|
|
249
|
-
var webPageCreator = {
|
|
250
|
-
id: "@manifest-editor/web-page-creator",
|
|
251
|
-
create: createWebPage,
|
|
252
|
-
label: "Web page",
|
|
253
|
-
summary: "Add link to an external web page",
|
|
254
|
-
icon: /* @__PURE__ */ jsx7(LinkIcon, {}),
|
|
255
|
-
render(ctx) {
|
|
256
|
-
return /* @__PURE__ */ jsx7(CreateWebPageForm, { ...ctx });
|
|
257
|
-
},
|
|
258
|
-
resourceType: "ContentResource",
|
|
259
|
-
resourceFields: ["label", "format"],
|
|
260
|
-
supports: {
|
|
261
|
-
parentFields: ["seeAlso", "rendering", "homepage"]
|
|
421
|
+
});
|
|
422
|
+
const page = ctx.embed({
|
|
423
|
+
id: pageId,
|
|
424
|
+
type: "AnnotationPage",
|
|
425
|
+
items: [annotationResource]
|
|
426
|
+
});
|
|
427
|
+
return ctx.embed({
|
|
428
|
+
id: canvasId,
|
|
429
|
+
type: "Canvas",
|
|
430
|
+
label: data.label || { en: ["Untitled HTML canvas"] },
|
|
431
|
+
duration: data.duration || 0,
|
|
432
|
+
items: [page]
|
|
433
|
+
});
|
|
262
434
|
}
|
|
263
|
-
};
|
|
264
|
-
|
|
265
|
-
// src/ContentResource/HTMLBodyCreator/create-html-body.tsx
|
|
266
|
-
import { InputContainer as InputContainer3, InputLabel as InputLabel3, RichTextLanguageField } from "@manifest-editor/editors";
|
|
267
|
-
import { useConfig } from "@manifest-editor/shell";
|
|
268
|
-
import { useState as useState3 } from "react";
|
|
269
|
-
import { jsx as jsx8, jsxs as jsxs5 } from "react/jsx-runtime";
|
|
270
|
-
async function createHtmlBody(data, ctx) {
|
|
271
|
-
return ctx.embed({
|
|
272
|
-
id: ctx.generateId(`html/${data.language}`),
|
|
273
|
-
language: data.language,
|
|
274
|
-
type: "TextualBody",
|
|
275
|
-
format: "text/html",
|
|
276
|
-
value: data.body || ""
|
|
277
|
-
});
|
|
278
435
|
}
|
|
279
|
-
function
|
|
280
|
-
const
|
|
281
|
-
const [
|
|
282
|
-
const [
|
|
436
|
+
function CreateAudioAnnotationForm(props) {
|
|
437
|
+
const [url, setUrl] = useState2("");
|
|
438
|
+
const [duration, setDuration] = useState2(0);
|
|
439
|
+
const [error, setError] = useState2("");
|
|
440
|
+
const [label, setLabel] = useState2({ en: [""] });
|
|
283
441
|
const onSubmit = () => {
|
|
284
442
|
props.runCreate({
|
|
285
|
-
|
|
286
|
-
|
|
443
|
+
url,
|
|
444
|
+
duration,
|
|
445
|
+
label
|
|
287
446
|
});
|
|
288
447
|
};
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
448
|
+
useEffect2(() => {
|
|
449
|
+
setError("");
|
|
450
|
+
setDuration(0);
|
|
451
|
+
if (url) {
|
|
452
|
+
const labelFromUrl = url.split("/").pop()?.split(".").shift();
|
|
453
|
+
setLabel({ en: [labelFromUrl || ""] });
|
|
454
|
+
}
|
|
455
|
+
}, [url]);
|
|
456
|
+
return /* @__PURE__ */ jsxs4(PaddedSidebarContainer, { children: [
|
|
457
|
+
error ? /* @__PURE__ */ jsx4(ErrorMessage, { children: error }) : null,
|
|
458
|
+
/* @__PURE__ */ jsxs4(InputContainer, { children: [
|
|
459
|
+
/* @__PURE__ */ jsx4(InputLabel, { htmlFor: "audio-url", children: "URL" }),
|
|
460
|
+
/* @__PURE__ */ jsx4(
|
|
461
|
+
Input,
|
|
294
462
|
{
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
onUpdate: (e) => setBodyValue(e)
|
|
463
|
+
type: "text",
|
|
464
|
+
id: "audio-url",
|
|
465
|
+
value: url,
|
|
466
|
+
onChange: (e) => setUrl(e.target.value)
|
|
300
467
|
}
|
|
301
468
|
)
|
|
302
469
|
] }),
|
|
303
|
-
/* @__PURE__ */
|
|
470
|
+
url && !error ? /* @__PURE__ */ jsx4("div", { children: /* @__PURE__ */ jsx4(
|
|
471
|
+
LanguageFieldEditor,
|
|
472
|
+
{
|
|
473
|
+
containerId: "label",
|
|
474
|
+
focusId: "label_",
|
|
475
|
+
label: "Label",
|
|
476
|
+
fields: label,
|
|
477
|
+
onSave: (e) => setLabel(e.toInternationalString())
|
|
478
|
+
},
|
|
479
|
+
url + "__" + duration
|
|
480
|
+
) }) : null,
|
|
481
|
+
url && !error ? /* @__PURE__ */ jsx4(
|
|
482
|
+
CanvasPanel.AudioHTML,
|
|
483
|
+
{
|
|
484
|
+
media: { url, duration, type: "Sound" },
|
|
485
|
+
children: /* @__PURE__ */ jsx4(
|
|
486
|
+
MediaControls,
|
|
487
|
+
{
|
|
488
|
+
onError: (error2) => setError(error2),
|
|
489
|
+
onDuration: (duration2) => setDuration(duration2)
|
|
490
|
+
},
|
|
491
|
+
url + "__" + duration
|
|
492
|
+
)
|
|
493
|
+
},
|
|
494
|
+
url + "__" + duration
|
|
495
|
+
) : null,
|
|
496
|
+
duration && !error ? /* @__PURE__ */ jsxs4(FormFieldWrapper, { children: [
|
|
497
|
+
/* @__PURE__ */ jsx4(InputLabel, { htmlFor: "duration", children: "Duration" }),
|
|
498
|
+
/* @__PURE__ */ jsx4(
|
|
499
|
+
Input,
|
|
500
|
+
{
|
|
501
|
+
type: "number",
|
|
502
|
+
id: "duration",
|
|
503
|
+
value: duration,
|
|
504
|
+
onChange: (e) => setDuration(e.target.valueAsNumber)
|
|
505
|
+
}
|
|
506
|
+
)
|
|
507
|
+
] }) : null,
|
|
508
|
+
url && !error && /* @__PURE__ */ jsx4(Button, { onClick: onSubmit, children: "Add audio" })
|
|
304
509
|
] });
|
|
305
510
|
}
|
|
306
511
|
|
|
307
|
-
// src/
|
|
308
|
-
import { jsx as
|
|
309
|
-
var
|
|
310
|
-
id: "@manifest-editor/
|
|
311
|
-
create:
|
|
312
|
-
label: "
|
|
313
|
-
summary: "
|
|
314
|
-
icon: /* @__PURE__ */
|
|
512
|
+
// src/Annotation/AudioAnnotation/index.tsx
|
|
513
|
+
import { jsx as jsx5 } from "react/jsx-runtime";
|
|
514
|
+
var audioAnnotation = {
|
|
515
|
+
id: "@manifest-editor/audio-annotation",
|
|
516
|
+
create: createAudioAnnotation,
|
|
517
|
+
label: "Audio",
|
|
518
|
+
summary: "Audio annotation",
|
|
519
|
+
icon: /* @__PURE__ */ jsx5(AudioIcon, {}),
|
|
315
520
|
render(ctx) {
|
|
316
|
-
return /* @__PURE__ */
|
|
521
|
+
return /* @__PURE__ */ jsx5(CreateAudioAnnotationForm, { ...ctx });
|
|
317
522
|
},
|
|
318
|
-
resourceType: "
|
|
319
|
-
resourceFields: ["id", "
|
|
523
|
+
resourceType: "Annotation",
|
|
524
|
+
resourceFields: ["id", "type", "motivation", "body", "target"],
|
|
525
|
+
additionalTypes: ["Canvas"],
|
|
320
526
|
supports: {
|
|
321
|
-
|
|
322
|
-
|
|
527
|
+
initialData: true,
|
|
528
|
+
parentTypes: ["AnnotationPage", "Manifest"],
|
|
529
|
+
parentFields: ["items"]
|
|
323
530
|
},
|
|
324
531
|
staticFields: {
|
|
325
|
-
type: "
|
|
326
|
-
format: "text/html"
|
|
532
|
+
type: "Annotation"
|
|
327
533
|
}
|
|
328
534
|
};
|
|
329
535
|
|
|
330
|
-
// src/Annotation/
|
|
331
|
-
import {
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
536
|
+
// src/Annotation/CaptionedImageAnnotation/index.tsx
|
|
537
|
+
import { AddImageIcon } from "@manifest-editor/components";
|
|
538
|
+
|
|
539
|
+
// src/Annotation/CaptionedImageAnnotation/create-captioned-image-annotation.tsx
|
|
540
|
+
import {
|
|
541
|
+
Input as Input2,
|
|
542
|
+
InputContainer as InputContainer2,
|
|
543
|
+
InputLabel as InputLabel2,
|
|
544
|
+
LanguageFieldEditor as LanguageFieldEditor2
|
|
545
|
+
} from "@manifest-editor/editors";
|
|
546
|
+
import { useState as useState3 } from "react";
|
|
547
|
+
import { jsx as jsx6, jsxs as jsxs5 } from "react/jsx-runtime";
|
|
548
|
+
async function createCaptionedImageAnnotation(data, ctx) {
|
|
335
549
|
const annotation = {
|
|
336
550
|
id: ctx.generateId("annotation"),
|
|
337
551
|
type: "Annotation"
|
|
@@ -354,6 +568,16 @@ async function createHtmlAnnotation(data, ctx) {
|
|
|
354
568
|
);
|
|
355
569
|
}
|
|
356
570
|
}
|
|
571
|
+
const resource = await ctx.create(
|
|
572
|
+
"@manifest-editor/image-url-creator",
|
|
573
|
+
{ url: data.imageUrl },
|
|
574
|
+
{
|
|
575
|
+
parent: { resource: annotation, property: "body" }
|
|
576
|
+
}
|
|
577
|
+
);
|
|
578
|
+
if (resource) {
|
|
579
|
+
bodies.push(resource);
|
|
580
|
+
}
|
|
357
581
|
if (targetType === "Annotation") {
|
|
358
582
|
return ctx.embed({
|
|
359
583
|
...annotation,
|
|
@@ -364,12 +588,18 @@ async function createHtmlAnnotation(data, ctx) {
|
|
|
364
588
|
}
|
|
365
589
|
if (targetType === "Canvas") {
|
|
366
590
|
const canvasId = ctx.generateId("canvas");
|
|
367
|
-
const pageId = ctx.generateId("annotation-page", {
|
|
591
|
+
const pageId = ctx.generateId("annotation-page", {
|
|
592
|
+
id: canvasId,
|
|
593
|
+
type: "Canvas"
|
|
594
|
+
});
|
|
368
595
|
const annotationResource = ctx.embed({
|
|
369
596
|
...annotation,
|
|
370
597
|
motivation: "painting",
|
|
371
598
|
body: bodies,
|
|
372
|
-
target: {
|
|
599
|
+
target: {
|
|
600
|
+
type: "SpecificResource",
|
|
601
|
+
source: { id: canvasId, type: "Canvas" }
|
|
602
|
+
}
|
|
373
603
|
});
|
|
374
604
|
const page = ctx.embed({
|
|
375
605
|
id: pageId,
|
|
@@ -386,18 +616,26 @@ async function createHtmlAnnotation(data, ctx) {
|
|
|
386
616
|
});
|
|
387
617
|
}
|
|
388
618
|
}
|
|
389
|
-
function
|
|
390
|
-
const [body, setBody] =
|
|
391
|
-
const onSubmit = () => {
|
|
619
|
+
function CreateCaptionedImageAnnotation(props) {
|
|
620
|
+
const [body, setBody] = useState3({ en: [""] });
|
|
621
|
+
const onSubmit = (e) => {
|
|
622
|
+
e.preventDefault();
|
|
623
|
+
const data = new FormData(e.target);
|
|
624
|
+
const formData = Object.fromEntries(data.entries());
|
|
392
625
|
props.runCreate({
|
|
393
|
-
body
|
|
626
|
+
body,
|
|
627
|
+
imageUrl: formData.url
|
|
394
628
|
});
|
|
395
629
|
};
|
|
396
|
-
return /* @__PURE__ */
|
|
397
|
-
/* @__PURE__ */
|
|
398
|
-
/* @__PURE__ */
|
|
399
|
-
/* @__PURE__ */
|
|
400
|
-
|
|
630
|
+
return /* @__PURE__ */ jsx6("form", { onSubmit, children: /* @__PURE__ */ jsxs5(PaddedSidebarContainer, { children: [
|
|
631
|
+
/* @__PURE__ */ jsx6(InputContainer2, { children: /* @__PURE__ */ jsxs5(InputContainer2, { $wide: true, children: [
|
|
632
|
+
/* @__PURE__ */ jsx6(InputLabel2, { htmlFor: "id", children: "Link to Image" }),
|
|
633
|
+
/* @__PURE__ */ jsx6(Input2, { id: "url", name: "url", defaultValue: "" })
|
|
634
|
+
] }) }),
|
|
635
|
+
/* @__PURE__ */ jsxs5(InputContainer2, { children: [
|
|
636
|
+
/* @__PURE__ */ jsx6(InputLabel2, { children: "Image Caption" }),
|
|
637
|
+
/* @__PURE__ */ jsx6(
|
|
638
|
+
LanguageFieldEditor2,
|
|
401
639
|
{
|
|
402
640
|
focusId: "html-content",
|
|
403
641
|
label: "HTML Content",
|
|
@@ -406,28 +644,27 @@ function CreateHTMLAnnotation(props) {
|
|
|
406
644
|
}
|
|
407
645
|
)
|
|
408
646
|
] }),
|
|
409
|
-
/* @__PURE__ */
|
|
410
|
-
] });
|
|
647
|
+
/* @__PURE__ */ jsx6(Button, { type: "submit", children: "Create" })
|
|
648
|
+
] }) });
|
|
411
649
|
}
|
|
412
650
|
|
|
413
|
-
// src/Annotation/
|
|
414
|
-
import {
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
icon: /* @__PURE__ */ jsx11(HTMLIcon, {}),
|
|
651
|
+
// src/Annotation/CaptionedImageAnnotation/index.tsx
|
|
652
|
+
import { jsx as jsx7 } from "react/jsx-runtime";
|
|
653
|
+
var captionedImageAnnotation = {
|
|
654
|
+
id: "@manifest-editor/captioned-image-annotation",
|
|
655
|
+
create: createCaptionedImageAnnotation,
|
|
656
|
+
label: "Captioned image",
|
|
657
|
+
summary: "Add an image from a URL with caption",
|
|
658
|
+
icon: /* @__PURE__ */ jsx7(AddImageIcon, {}),
|
|
422
659
|
render(ctx) {
|
|
423
|
-
return /* @__PURE__ */
|
|
660
|
+
return /* @__PURE__ */ jsx7(CreateCaptionedImageAnnotation, { ...ctx });
|
|
424
661
|
},
|
|
425
662
|
resourceType: "Annotation",
|
|
426
663
|
resourceFields: ["id", "type", "motivation", "body", "target"],
|
|
427
664
|
additionalTypes: ["Canvas"],
|
|
428
665
|
supports: {
|
|
429
666
|
initialData: true,
|
|
430
|
-
parentTypes: ["AnnotationPage"
|
|
667
|
+
parentTypes: ["AnnotationPage"],
|
|
431
668
|
parentFields: ["items"]
|
|
432
669
|
},
|
|
433
670
|
staticFields: {
|
|
@@ -435,308 +672,128 @@ var htmlAnnotation = {
|
|
|
435
672
|
}
|
|
436
673
|
};
|
|
437
674
|
|
|
438
|
-
//
|
|
439
|
-
import {
|
|
440
|
-
var ThumbnailStripIcon = () => /* @__PURE__ */ jsx12(
|
|
441
|
-
"svg",
|
|
442
|
-
{
|
|
443
|
-
xmlns: "http://www.w3.org/2000/svg",
|
|
444
|
-
height: "24px",
|
|
445
|
-
viewBox: "0 0 24 24",
|
|
446
|
-
width: "24px",
|
|
447
|
-
fill: "#000000",
|
|
448
|
-
transform: "scale(-1, 1)",
|
|
449
|
-
children: /* @__PURE__ */ jsxs7("g", { children: [
|
|
450
|
-
/* @__PURE__ */ jsx12("rect", { fill: "none", height: "24", width: "24" }),
|
|
451
|
-
/* @__PURE__ */ jsx12("path", { d: "M16,20H2V4h14V20z M18,8h4V4h-4V8z M18,20h4v-4h-4V20z M18,14h4v-4h-4V14z" })
|
|
452
|
-
] })
|
|
453
|
-
}
|
|
454
|
-
);
|
|
675
|
+
// src/Annotation/HTMLAnnotation/index.tsx
|
|
676
|
+
import { HTMLIcon as HTMLIcon2 } from "@manifest-editor/components";
|
|
455
677
|
|
|
456
|
-
// src/
|
|
457
|
-
import {
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
678
|
+
// src/Annotation/HTMLAnnotation/create-html-annotation.tsx
|
|
679
|
+
import { useState as useState4 } from "react";
|
|
680
|
+
import {
|
|
681
|
+
InputContainer as InputContainer3,
|
|
682
|
+
InputLabel as InputLabel3,
|
|
683
|
+
LanguageFieldEditor as LanguageFieldEditor3
|
|
684
|
+
} from "@manifest-editor/editors";
|
|
685
|
+
import { jsx as jsx8, jsxs as jsxs6 } from "react/jsx-runtime";
|
|
686
|
+
async function createHtmlAnnotation(data, ctx) {
|
|
687
|
+
const annotation = {
|
|
688
|
+
id: ctx.generateId("annotation"),
|
|
689
|
+
type: "Annotation"
|
|
690
|
+
};
|
|
691
|
+
const targetType = ctx.options.targetType;
|
|
692
|
+
const languages = Object.keys(data.body);
|
|
693
|
+
const bodies = [];
|
|
694
|
+
for (const language of languages) {
|
|
695
|
+
const body = data.body[language].join("\n");
|
|
696
|
+
if (body) {
|
|
697
|
+
bodies.push(
|
|
698
|
+
await ctx.create(
|
|
699
|
+
"@manifest-editor/html-body-creator",
|
|
700
|
+
{
|
|
701
|
+
language,
|
|
702
|
+
body
|
|
703
|
+
},
|
|
704
|
+
{ parent: { resource: annotation, property: "items" } }
|
|
705
|
+
)
|
|
706
|
+
);
|
|
472
707
|
}
|
|
473
708
|
}
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
}
|
|
482
|
-
|
|
483
|
-
// src/ContentResource/YouTubeCreator/index.tsx
|
|
484
|
-
import { YouTubeIcon } from "@manifest-editor/components";
|
|
485
|
-
|
|
486
|
-
// src/ContentResource/YouTubeCreator/create-youtube-body.tsx
|
|
487
|
-
import { InputContainer as InputContainer5, InputLabel as InputLabel5, Input as Input3 } from "@manifest-editor/editors";
|
|
488
|
-
import { jsx as jsx14, jsxs as jsxs8 } from "react/jsx-runtime";
|
|
489
|
-
var ytRegex = /^.*(?:(?:youtu\.be\/|v\/|vi\/|u\/\w\/|embed\/|shorts\/)|(?:(?:watch)?\?vi?=|&vi?=))([^#&?]*).*/;
|
|
490
|
-
function getYouTubeId(url) {
|
|
491
|
-
const id = (url || "").match(ytRegex);
|
|
492
|
-
return id ? id[1] : null;
|
|
493
|
-
}
|
|
494
|
-
async function createYoutubeBody(data, ctx) {
|
|
495
|
-
const id = getYouTubeId(data.youtubeUrl);
|
|
496
|
-
const body = ctx.embed({
|
|
497
|
-
id: `https://www.youtube.com/watch?v=${id}`,
|
|
498
|
-
type: "Video",
|
|
499
|
-
service: [
|
|
500
|
-
{
|
|
501
|
-
profile: "http://digirati.com/objectifier",
|
|
502
|
-
params: {
|
|
503
|
-
data: `https://www.youtube.com/embed/${id}`
|
|
504
|
-
}
|
|
505
|
-
},
|
|
506
|
-
{
|
|
507
|
-
id: `https://www.youtube.com/watch?v=${id}`,
|
|
508
|
-
profile: "https://www.youtube.com"
|
|
509
|
-
}
|
|
510
|
-
]
|
|
511
|
-
});
|
|
512
|
-
if (ctx.options.targetType === "Canvas") {
|
|
709
|
+
if (targetType === "Annotation") {
|
|
710
|
+
return ctx.embed({
|
|
711
|
+
...annotation,
|
|
712
|
+
motivation: data.motivation || ctx.options.initialData?.motivation || "painting",
|
|
713
|
+
body: bodies,
|
|
714
|
+
target: ctx.getTarget()
|
|
715
|
+
});
|
|
716
|
+
}
|
|
717
|
+
if (targetType === "Canvas") {
|
|
513
718
|
const canvasId = ctx.generateId("canvas");
|
|
514
|
-
const pageId = ctx.generateId("annotation-page", {
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
719
|
+
const pageId = ctx.generateId("annotation-page", {
|
|
720
|
+
id: canvasId,
|
|
721
|
+
type: "Canvas"
|
|
722
|
+
});
|
|
723
|
+
const annotationResource = ctx.embed({
|
|
724
|
+
...annotation,
|
|
518
725
|
motivation: "painting",
|
|
519
|
-
body:
|
|
520
|
-
target: {
|
|
726
|
+
body: bodies,
|
|
727
|
+
target: {
|
|
728
|
+
type: "SpecificResource",
|
|
729
|
+
source: { id: canvasId, type: "Canvas" }
|
|
730
|
+
}
|
|
521
731
|
});
|
|
522
732
|
const page = ctx.embed({
|
|
523
733
|
id: pageId,
|
|
524
734
|
type: "AnnotationPage",
|
|
525
|
-
items: [
|
|
735
|
+
items: [annotationResource]
|
|
526
736
|
});
|
|
527
737
|
return ctx.embed({
|
|
528
738
|
id: canvasId,
|
|
529
739
|
type: "Canvas",
|
|
530
|
-
label: data.label || { en: ["Untitled
|
|
740
|
+
label: data.label || { en: ["Untitled HTML canvas"] },
|
|
531
741
|
height: data.height || 1e3,
|
|
532
742
|
width: data.width || 1e3,
|
|
533
|
-
duration: data.duration || 1,
|
|
534
743
|
items: [page]
|
|
535
744
|
});
|
|
536
745
|
}
|
|
537
|
-
if (ctx.options.targetType === "Annotation" || ctx.options.targetType === "Canvas") {
|
|
538
|
-
return ctx.embed({
|
|
539
|
-
id: ctx.generateId("annotation"),
|
|
540
|
-
type: "Annotation",
|
|
541
|
-
motivation: "painting",
|
|
542
|
-
body: [body],
|
|
543
|
-
target: ctx.getTarget()
|
|
544
|
-
});
|
|
545
|
-
}
|
|
546
|
-
return body;
|
|
547
|
-
}
|
|
548
|
-
function YouTubeForm(props) {
|
|
549
|
-
const onSubmit = (e) => {
|
|
550
|
-
e.preventDefault();
|
|
551
|
-
const data = new FormData(e.target);
|
|
552
|
-
const formData = Object.fromEntries(data.entries());
|
|
553
|
-
if (formData.youtubeUrl) {
|
|
554
|
-
props.runCreate({ youtubeUrl: formData.youtubeUrl });
|
|
555
|
-
}
|
|
556
|
-
};
|
|
557
|
-
return /* @__PURE__ */ jsx14(PaddedSidebarContainer, { children: /* @__PURE__ */ jsxs8("form", { onSubmit, children: [
|
|
558
|
-
/* @__PURE__ */ jsxs8(InputContainer5, { $wide: true, children: [
|
|
559
|
-
/* @__PURE__ */ jsx14(InputLabel5, { htmlFor: "id", children: "Link to YouTube" }),
|
|
560
|
-
/* @__PURE__ */ jsx14(Input3, { id: "youtubeUrl", name: "youtubeUrl", defaultValue: "" })
|
|
561
|
-
] }),
|
|
562
|
-
/* @__PURE__ */ jsx14(Button, { type: "submit", children: "Create" })
|
|
563
|
-
] }) });
|
|
564
|
-
}
|
|
565
|
-
|
|
566
|
-
// src/ContentResource/YouTubeCreator/index.tsx
|
|
567
|
-
import { jsx as jsx15 } from "react/jsx-runtime";
|
|
568
|
-
var youTubeBodyCreator = {
|
|
569
|
-
id: "@manifest-editor/youtube",
|
|
570
|
-
create: createYoutubeBody,
|
|
571
|
-
label: "YouTube",
|
|
572
|
-
summary: "Embed YouTube",
|
|
573
|
-
icon: /* @__PURE__ */ jsx15(YouTubeIcon, {}),
|
|
574
|
-
resourceType: "ContentResource",
|
|
575
|
-
additionalTypes: ["Canvas", "Annotation"],
|
|
576
|
-
resourceFields: ["id", "type", "service"],
|
|
577
|
-
render: (ctx) => /* @__PURE__ */ jsx15(YouTubeForm, { ...ctx }),
|
|
578
|
-
supports: {
|
|
579
|
-
parentTypes: ["Annotation", "Manifest", "AnnotationPage"],
|
|
580
|
-
parentFieldMap: {
|
|
581
|
-
Annotation: ["body"],
|
|
582
|
-
Manifest: ["items"],
|
|
583
|
-
AnnotationPage: ["items"]
|
|
584
|
-
}
|
|
585
|
-
},
|
|
586
|
-
staticFields: {
|
|
587
|
-
type: "Video"
|
|
588
|
-
}
|
|
589
|
-
};
|
|
590
|
-
|
|
591
|
-
// src/ContentResource/ImageUrlCreator/create-image-url.tsx
|
|
592
|
-
import { InputContainer as InputContainer6, InputLabel as InputLabel6, Input as Input4 } from "@manifest-editor/editors";
|
|
593
|
-
import { getImageDimensions, getFormat } from "@manifest-editor/shell";
|
|
594
|
-
import { jsx as jsx16, jsxs as jsxs9 } from "react/jsx-runtime";
|
|
595
|
-
async function createImageUrl(data, ctx) {
|
|
596
|
-
if (!data.height || !data.width) {
|
|
597
|
-
const dimensions = await getImageDimensions(data.url);
|
|
598
|
-
if (dimensions) {
|
|
599
|
-
data.height = dimensions.height;
|
|
600
|
-
data.width = dimensions.width;
|
|
601
|
-
}
|
|
602
|
-
}
|
|
603
|
-
return ctx.embed({
|
|
604
|
-
id: data.url,
|
|
605
|
-
type: "Image",
|
|
606
|
-
format: data.format || await getFormat(data.url),
|
|
607
|
-
height: data.height,
|
|
608
|
-
width: data.width,
|
|
609
|
-
service: data.service ? Array.isArray(data.service) ? data.service : [data.service] : void 0
|
|
610
|
-
});
|
|
611
746
|
}
|
|
612
|
-
function
|
|
613
|
-
const
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
props.runCreate({ url: formData.url });
|
|
619
|
-
}
|
|
747
|
+
function CreateHTMLAnnotation(props) {
|
|
748
|
+
const [body, setBody] = useState4({ en: [""] });
|
|
749
|
+
const onSubmit = () => {
|
|
750
|
+
props.runCreate({
|
|
751
|
+
body
|
|
752
|
+
});
|
|
620
753
|
};
|
|
621
|
-
return /* @__PURE__ */
|
|
622
|
-
/* @__PURE__ */
|
|
623
|
-
/* @__PURE__ */
|
|
624
|
-
/* @__PURE__ */
|
|
754
|
+
return /* @__PURE__ */ jsxs6(PaddedSidebarContainer, { children: [
|
|
755
|
+
/* @__PURE__ */ jsxs6(InputContainer3, { children: [
|
|
756
|
+
/* @__PURE__ */ jsx8(InputLabel3, { children: "HTML Body" }),
|
|
757
|
+
/* @__PURE__ */ jsx8(
|
|
758
|
+
LanguageFieldEditor3,
|
|
759
|
+
{
|
|
760
|
+
focusId: "html-content",
|
|
761
|
+
label: "HTML Content",
|
|
762
|
+
fields: body,
|
|
763
|
+
onSave: (e) => setBody(e.toInternationalString())
|
|
764
|
+
}
|
|
765
|
+
)
|
|
625
766
|
] }),
|
|
626
|
-
/* @__PURE__ */
|
|
627
|
-
] })
|
|
767
|
+
/* @__PURE__ */ jsx8(Button, { onClick: () => onSubmit(), children: "Create" })
|
|
768
|
+
] });
|
|
628
769
|
}
|
|
629
770
|
|
|
630
|
-
// src/
|
|
631
|
-
import {
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
icon: /* @__PURE__ */ jsx17(AddImageIcon, {}),
|
|
771
|
+
// src/Annotation/HTMLAnnotation/index.tsx
|
|
772
|
+
import { jsx as jsx9 } from "react/jsx-runtime";
|
|
773
|
+
var htmlAnnotation = {
|
|
774
|
+
id: "@manifest-editor/html-annotation",
|
|
775
|
+
create: createHtmlAnnotation,
|
|
776
|
+
label: "HTML",
|
|
777
|
+
summary: "HTML annotation",
|
|
778
|
+
icon: /* @__PURE__ */ jsx9(HTMLIcon2, {}),
|
|
639
779
|
render(ctx) {
|
|
640
|
-
return /* @__PURE__ */
|
|
780
|
+
return /* @__PURE__ */ jsx9(CreateHTMLAnnotation, { ...ctx });
|
|
641
781
|
},
|
|
642
|
-
resourceType: "
|
|
643
|
-
resourceFields: ["
|
|
782
|
+
resourceType: "Annotation",
|
|
783
|
+
resourceFields: ["id", "type", "motivation", "body", "target"],
|
|
784
|
+
additionalTypes: ["Canvas"],
|
|
644
785
|
supports: {
|
|
645
|
-
|
|
786
|
+
initialData: true,
|
|
787
|
+
parentTypes: ["AnnotationPage", "Manifest"],
|
|
788
|
+
parentFields: ["items"]
|
|
646
789
|
},
|
|
647
790
|
staticFields: {
|
|
648
|
-
type: "
|
|
791
|
+
type: "Annotation"
|
|
649
792
|
}
|
|
650
793
|
};
|
|
651
794
|
|
|
652
|
-
// src/
|
|
653
|
-
import {
|
|
654
|
-
imageServiceRequestToString,
|
|
655
|
-
createImageServiceRequest,
|
|
656
|
-
canonicalServiceUrl
|
|
657
|
-
} from "@iiif/parser/image-3";
|
|
658
|
-
import { InputContainer as InputContainer7, InputLabel as InputLabel7, Input as Input5 } from "@manifest-editor/editors";
|
|
659
|
-
import { jsx as jsx18, jsxs as jsxs10 } from "react/jsx-runtime";
|
|
660
|
-
async function createImageServer(data, ctx) {
|
|
661
|
-
const request = createImageServiceRequest(data.service);
|
|
662
|
-
const imageId = imageServiceRequestToString({
|
|
663
|
-
identifier: request.identifier,
|
|
664
|
-
server: request.server,
|
|
665
|
-
scheme: request.scheme,
|
|
666
|
-
type: "image",
|
|
667
|
-
size: {
|
|
668
|
-
max: !data.size?.width && !data.size?.height,
|
|
669
|
-
confined: false,
|
|
670
|
-
upscaled: false,
|
|
671
|
-
...data.size || {}
|
|
672
|
-
},
|
|
673
|
-
format: "jpg",
|
|
674
|
-
// This isn't how it should be modelled, always full,
|
|
675
|
-
// region: data.selector ? data.selector : { full: true },
|
|
676
|
-
region: { full: true },
|
|
677
|
-
rotation: { angle: 0 },
|
|
678
|
-
quality: "default",
|
|
679
|
-
prefix: request.prefix,
|
|
680
|
-
originalPath: request.originalPath
|
|
681
|
-
});
|
|
682
|
-
const resource = ctx.embed({
|
|
683
|
-
id: imageId,
|
|
684
|
-
type: "Image",
|
|
685
|
-
format: data.format || "image/jpeg",
|
|
686
|
-
height: data.height || data.service.height,
|
|
687
|
-
width: data.width || data.service.width,
|
|
688
|
-
service: data.embedService === false ? void 0 : [data.service]
|
|
689
|
-
});
|
|
690
|
-
return resource;
|
|
691
|
-
}
|
|
692
|
-
function CreateImageServerForm(props) {
|
|
693
|
-
const onSubmit = (e) => {
|
|
694
|
-
e.preventDefault();
|
|
695
|
-
const data = new FormData(e.target);
|
|
696
|
-
const formData = Object.fromEntries(data.entries());
|
|
697
|
-
const url = formData.url;
|
|
698
|
-
if (url) {
|
|
699
|
-
const canon = canonicalServiceUrl(url);
|
|
700
|
-
fetch(canon).then((r) => r.json()).then((service) => {
|
|
701
|
-
if (service["@id"]) {
|
|
702
|
-
service.id = service["@id"];
|
|
703
|
-
}
|
|
704
|
-
if (service["@type"]) {
|
|
705
|
-
service.type = service["@type"];
|
|
706
|
-
}
|
|
707
|
-
props.runCreate({ url: formData.url, service });
|
|
708
|
-
});
|
|
709
|
-
}
|
|
710
|
-
};
|
|
711
|
-
return /* @__PURE__ */ jsx18(PaddedSidebarContainer, { children: /* @__PURE__ */ jsxs10("form", { onSubmit, children: [
|
|
712
|
-
/* @__PURE__ */ jsxs10(InputContainer7, { $wide: true, children: [
|
|
713
|
-
/* @__PURE__ */ jsx18(InputLabel7, { htmlFor: "id", children: "Link to image service" }),
|
|
714
|
-
/* @__PURE__ */ jsx18(Input5, { id: "url", name: "url", defaultValue: "" })
|
|
715
|
-
] }),
|
|
716
|
-
/* @__PURE__ */ jsx18(Button, { type: "submit", children: "Create" })
|
|
717
|
-
] }) });
|
|
718
|
-
}
|
|
719
|
-
|
|
720
|
-
// src/ContentResource/ImageServiceCreator/index.tsx
|
|
721
|
-
import { jsx as jsx19 } from "react/jsx-runtime";
|
|
722
|
-
var imageServiceCreator = {
|
|
723
|
-
id: "@manifest-editor/image-service-creator",
|
|
724
|
-
create: createImageServer,
|
|
725
|
-
label: "Image Service",
|
|
726
|
-
summary: "Add an image from Image Service",
|
|
727
|
-
icon: /* @__PURE__ */ jsx19(TextFormatIcon, {}),
|
|
728
|
-
render(ctx) {
|
|
729
|
-
return /* @__PURE__ */ jsx19(CreateImageServerForm, { ...ctx });
|
|
730
|
-
},
|
|
731
|
-
resourceType: "ContentResource",
|
|
732
|
-
resourceFields: ["id", "type", "height", "width", "format", "service"],
|
|
733
|
-
supports: {
|
|
734
|
-
parentFields: ["logo", "body", "thumbnail"]
|
|
735
|
-
},
|
|
736
|
-
staticFields: {
|
|
737
|
-
type: "Image"
|
|
738
|
-
}
|
|
739
|
-
};
|
|
795
|
+
// src/Annotation/ImageServiceAnnotation/index.tsx
|
|
796
|
+
import { IIIFLogo } from "@manifest-editor/components";
|
|
740
797
|
|
|
741
798
|
// src/side-effects/reposition-multiple-images.ts
|
|
742
799
|
import { isImageService } from "@iiif/parser/image-3";
|
|
@@ -761,7 +818,7 @@ var repositionMultipleImages = {
|
|
|
761
818
|
if (!annoPage) {
|
|
762
819
|
return;
|
|
763
820
|
}
|
|
764
|
-
if (annoPage.items.length < 2) {
|
|
821
|
+
if (annoPage.items.length < 2 && !canvas.behavior.includes("multi-image")) {
|
|
765
822
|
return;
|
|
766
823
|
}
|
|
767
824
|
const bodies = vault.get(fullAnno.body);
|
|
@@ -772,10 +829,18 @@ var repositionMultipleImages = {
|
|
|
772
829
|
if (imageService) {
|
|
773
830
|
if (imageService.width && imageService.height) {
|
|
774
831
|
if (imageService.width !== body.width) {
|
|
775
|
-
vault.modifyEntityField(
|
|
832
|
+
vault.modifyEntityField(
|
|
833
|
+
{ id: body.id, type: "ContentResource" },
|
|
834
|
+
"width",
|
|
835
|
+
imageService.width
|
|
836
|
+
);
|
|
776
837
|
}
|
|
777
838
|
if (imageService.height !== body.height) {
|
|
778
|
-
vault.modifyEntityField(
|
|
839
|
+
vault.modifyEntityField(
|
|
840
|
+
{ id: body.id, type: "ContentResource" },
|
|
841
|
+
"height",
|
|
842
|
+
imageService.height
|
|
843
|
+
);
|
|
779
844
|
}
|
|
780
845
|
}
|
|
781
846
|
}
|
|
@@ -819,6 +884,9 @@ var resizeResourceToEmptyCanvas = {
|
|
|
819
884
|
if (!canvas.items) {
|
|
820
885
|
return;
|
|
821
886
|
}
|
|
887
|
+
if (canvas.behavior.includes("multi-image")) {
|
|
888
|
+
return;
|
|
889
|
+
}
|
|
822
890
|
const annoPage = vault.get(canvas.items[0]);
|
|
823
891
|
if (!annoPage) {
|
|
824
892
|
return;
|
|
@@ -876,6 +944,9 @@ var resizeToFitService = {
|
|
|
876
944
|
if (!canvas.items) {
|
|
877
945
|
return;
|
|
878
946
|
}
|
|
947
|
+
if (canvas.behavior.includes("multi-image")) {
|
|
948
|
+
return;
|
|
949
|
+
}
|
|
879
950
|
const annoPage = vault.get(canvas.items[0]);
|
|
880
951
|
if (!annoPage) {
|
|
881
952
|
return;
|
|
@@ -891,10 +962,18 @@ var resizeToFitService = {
|
|
|
891
962
|
if (imageService) {
|
|
892
963
|
if (imageService.width && imageService.height) {
|
|
893
964
|
if (imageService.width !== body.width) {
|
|
894
|
-
vault.modifyEntityField(
|
|
965
|
+
vault.modifyEntityField(
|
|
966
|
+
{ id: body.id, type: "ContentResource" },
|
|
967
|
+
"width",
|
|
968
|
+
imageService.width
|
|
969
|
+
);
|
|
895
970
|
}
|
|
896
971
|
if (imageService.height !== body.height) {
|
|
897
|
-
vault.modifyEntityField(
|
|
972
|
+
vault.modifyEntityField(
|
|
973
|
+
{ id: body.id, type: "ContentResource" },
|
|
974
|
+
"height",
|
|
975
|
+
imageService.height
|
|
976
|
+
);
|
|
898
977
|
}
|
|
899
978
|
}
|
|
900
979
|
}
|
|
@@ -902,17 +981,89 @@ var resizeToFitService = {
|
|
|
902
981
|
}
|
|
903
982
|
};
|
|
904
983
|
|
|
984
|
+
// src/ContentResource/ImageServiceCreator/create-image-service.tsx
|
|
985
|
+
import {
|
|
986
|
+
imageServiceRequestToString,
|
|
987
|
+
createImageServiceRequest,
|
|
988
|
+
canonicalServiceUrl
|
|
989
|
+
} from "@iiif/parser/image-3";
|
|
990
|
+
import { InputContainer as InputContainer4, InputLabel as InputLabel4, Input as Input3 } from "@manifest-editor/editors";
|
|
991
|
+
import { jsx as jsx10, jsxs as jsxs7 } from "react/jsx-runtime";
|
|
992
|
+
async function createImageServer(data, ctx) {
|
|
993
|
+
const request = createImageServiceRequest(data.service);
|
|
994
|
+
const imageId = imageServiceRequestToString({
|
|
995
|
+
identifier: request.identifier,
|
|
996
|
+
server: request.server,
|
|
997
|
+
scheme: request.scheme,
|
|
998
|
+
type: "image",
|
|
999
|
+
size: {
|
|
1000
|
+
max: !data.size?.width && !data.size?.height,
|
|
1001
|
+
confined: false,
|
|
1002
|
+
upscaled: false,
|
|
1003
|
+
...data.size || {}
|
|
1004
|
+
},
|
|
1005
|
+
format: "jpg",
|
|
1006
|
+
// This isn't how it should be modelled, always full,
|
|
1007
|
+
// region: data.selector ? data.selector : { full: true },
|
|
1008
|
+
region: { full: true },
|
|
1009
|
+
rotation: { angle: 0 },
|
|
1010
|
+
quality: "default",
|
|
1011
|
+
prefix: request.prefix,
|
|
1012
|
+
originalPath: request.originalPath
|
|
1013
|
+
});
|
|
1014
|
+
const resource = ctx.embed({
|
|
1015
|
+
id: imageId,
|
|
1016
|
+
type: "Image",
|
|
1017
|
+
format: data.format || "image/jpeg",
|
|
1018
|
+
height: data.height || data.service.height,
|
|
1019
|
+
width: data.width || data.service.width,
|
|
1020
|
+
service: data.embedService === false ? void 0 : [data.service]
|
|
1021
|
+
});
|
|
1022
|
+
return resource;
|
|
1023
|
+
}
|
|
1024
|
+
function CreateImageServerForm(props) {
|
|
1025
|
+
const onSubmit = (e) => {
|
|
1026
|
+
e.preventDefault();
|
|
1027
|
+
const data = new FormData(e.target);
|
|
1028
|
+
const formData = Object.fromEntries(data.entries());
|
|
1029
|
+
const url = formData.url;
|
|
1030
|
+
if (url) {
|
|
1031
|
+
const canon = canonicalServiceUrl(url);
|
|
1032
|
+
fetch(canon).then((r) => r.json()).then((service) => {
|
|
1033
|
+
if (service["@id"]) {
|
|
1034
|
+
service.id = service["@id"];
|
|
1035
|
+
}
|
|
1036
|
+
if (service["@type"]) {
|
|
1037
|
+
service.type = service["@type"];
|
|
1038
|
+
}
|
|
1039
|
+
props.runCreate({ url: formData.url, service });
|
|
1040
|
+
});
|
|
1041
|
+
}
|
|
1042
|
+
};
|
|
1043
|
+
return /* @__PURE__ */ jsx10(PaddedSidebarContainer, { children: /* @__PURE__ */ jsxs7("form", { onSubmit, children: [
|
|
1044
|
+
/* @__PURE__ */ jsxs7(InputContainer4, { $wide: true, children: [
|
|
1045
|
+
/* @__PURE__ */ jsx10(InputLabel4, { htmlFor: "id", children: "Link to image service" }),
|
|
1046
|
+
/* @__PURE__ */ jsx10(Input3, { id: "url", name: "url", defaultValue: "" })
|
|
1047
|
+
] }),
|
|
1048
|
+
/* @__PURE__ */ jsx10(Button, { type: "submit", children: "Create" })
|
|
1049
|
+
] }) });
|
|
1050
|
+
}
|
|
1051
|
+
|
|
905
1052
|
// src/Annotation/ImageServiceAnnotation/create-service-annotation.tsx
|
|
906
|
-
import { jsx as
|
|
1053
|
+
import { jsx as jsx11 } from "react/jsx-runtime";
|
|
907
1054
|
async function createImageServiceAnnotation(data, ctx) {
|
|
908
1055
|
const annotation = {
|
|
909
1056
|
id: ctx.generateId("annotation"),
|
|
910
1057
|
type: "Annotation"
|
|
911
1058
|
};
|
|
912
1059
|
const targetType = ctx.options.targetType;
|
|
913
|
-
const resource = await ctx.create(
|
|
914
|
-
|
|
915
|
-
|
|
1060
|
+
const resource = await ctx.create(
|
|
1061
|
+
"@manifest-editor/image-service-creator",
|
|
1062
|
+
data,
|
|
1063
|
+
{
|
|
1064
|
+
parent: { resource: annotation, property: "body" }
|
|
1065
|
+
}
|
|
1066
|
+
);
|
|
916
1067
|
if (targetType === "Annotation") {
|
|
917
1068
|
return {
|
|
918
1069
|
...annotation,
|
|
@@ -923,12 +1074,18 @@ async function createImageServiceAnnotation(data, ctx) {
|
|
|
923
1074
|
}
|
|
924
1075
|
if (targetType === "Canvas") {
|
|
925
1076
|
const canvasId = ctx.generateId("canvas");
|
|
926
|
-
const pageId = ctx.generateId("annotation-page", {
|
|
1077
|
+
const pageId = ctx.generateId("annotation-page", {
|
|
1078
|
+
id: canvasId,
|
|
1079
|
+
type: "Canvas"
|
|
1080
|
+
});
|
|
927
1081
|
const annotationResource = ctx.embed({
|
|
928
1082
|
...annotation,
|
|
929
1083
|
motivation: "painting",
|
|
930
1084
|
body: [resource],
|
|
931
|
-
target: {
|
|
1085
|
+
target: {
|
|
1086
|
+
type: "SpecificResource",
|
|
1087
|
+
source: { id: canvasId, type: "Canvas" }
|
|
1088
|
+
}
|
|
932
1089
|
});
|
|
933
1090
|
const page = ctx.embed({
|
|
934
1091
|
id: pageId,
|
|
@@ -946,21 +1103,150 @@ async function createImageServiceAnnotation(data, ctx) {
|
|
|
946
1103
|
}
|
|
947
1104
|
}
|
|
948
1105
|
function CreateImageServiceAnnotationForm(props) {
|
|
949
|
-
return /* @__PURE__ */
|
|
1106
|
+
return /* @__PURE__ */ jsx11(CreateImageServerForm, { ...props });
|
|
950
1107
|
}
|
|
951
1108
|
|
|
952
1109
|
// src/Annotation/ImageServiceAnnotation/index.tsx
|
|
953
|
-
import {
|
|
954
|
-
import { jsx as jsx21 } from "react/jsx-runtime";
|
|
1110
|
+
import { jsx as jsx12 } from "react/jsx-runtime";
|
|
955
1111
|
var imageServiceAnnotation = {
|
|
956
1112
|
id: "@manifest-editor/image-service-annotation",
|
|
957
1113
|
create: createImageServiceAnnotation,
|
|
958
1114
|
label: "IIIF Image",
|
|
959
1115
|
dependencies: ["@manifest-editor/image-service-creator"],
|
|
960
1116
|
summary: "IIIF Image service",
|
|
961
|
-
|
|
1117
|
+
tags: ["image", "image-service"],
|
|
1118
|
+
icon: /* @__PURE__ */ jsx12(IIIFLogo, { style: { padding: 10 } }),
|
|
1119
|
+
render(ctx) {
|
|
1120
|
+
return /* @__PURE__ */ jsx12(CreateImageServiceAnnotationForm, { ...ctx });
|
|
1121
|
+
},
|
|
1122
|
+
resourceType: "Annotation",
|
|
1123
|
+
resourceFields: ["id", "type", "motivation", "body", "target"],
|
|
1124
|
+
additionalTypes: ["Canvas"],
|
|
1125
|
+
supports: {
|
|
1126
|
+
parentTypes: ["AnnotationPage", "Manifest"],
|
|
1127
|
+
parentFields: ["items"]
|
|
1128
|
+
},
|
|
1129
|
+
sideEffects: [
|
|
1130
|
+
resizeToFitService,
|
|
1131
|
+
resizeResourceToEmptyCanvas,
|
|
1132
|
+
repositionMultipleImages
|
|
1133
|
+
],
|
|
1134
|
+
staticFields: {
|
|
1135
|
+
type: "Annotation"
|
|
1136
|
+
}
|
|
1137
|
+
};
|
|
1138
|
+
|
|
1139
|
+
// src/Annotation/ImageUrlAnnotation/index.tsx
|
|
1140
|
+
import { AddImageIcon as AddImageIcon2 } from "@manifest-editor/components";
|
|
1141
|
+
|
|
1142
|
+
// src/ContentResource/ImageUrlCreator/create-image-url.tsx
|
|
1143
|
+
import { InputContainer as InputContainer5, InputLabel as InputLabel5, Input as Input4 } from "@manifest-editor/editors";
|
|
1144
|
+
import { getImageDimensions, getFormat } from "@manifest-editor/shell";
|
|
1145
|
+
import { jsx as jsx13, jsxs as jsxs8 } from "react/jsx-runtime";
|
|
1146
|
+
async function createImageUrl(data, ctx) {
|
|
1147
|
+
if (!data.height || !data.width) {
|
|
1148
|
+
const dimensions = await getImageDimensions(data.url);
|
|
1149
|
+
if (dimensions) {
|
|
1150
|
+
data.height = dimensions.height;
|
|
1151
|
+
data.width = dimensions.width;
|
|
1152
|
+
}
|
|
1153
|
+
}
|
|
1154
|
+
return ctx.embed({
|
|
1155
|
+
id: data.url,
|
|
1156
|
+
type: "Image",
|
|
1157
|
+
format: data.format || await getFormat(data.url),
|
|
1158
|
+
height: data.height,
|
|
1159
|
+
width: data.width,
|
|
1160
|
+
service: data.service ? Array.isArray(data.service) ? data.service : [data.service] : void 0
|
|
1161
|
+
});
|
|
1162
|
+
}
|
|
1163
|
+
function CreateImageUrlForm(props) {
|
|
1164
|
+
const onSubmit = (e) => {
|
|
1165
|
+
e.preventDefault();
|
|
1166
|
+
const data = new FormData(e.target);
|
|
1167
|
+
const formData = Object.fromEntries(data.entries());
|
|
1168
|
+
if (formData.url) {
|
|
1169
|
+
props.runCreate({ url: formData.url });
|
|
1170
|
+
}
|
|
1171
|
+
};
|
|
1172
|
+
return /* @__PURE__ */ jsx13(PaddedSidebarContainer, { children: /* @__PURE__ */ jsxs8("form", { onSubmit, children: [
|
|
1173
|
+
/* @__PURE__ */ jsxs8(InputContainer5, { $wide: true, children: [
|
|
1174
|
+
/* @__PURE__ */ jsx13(InputLabel5, { htmlFor: "id", children: "Link to Image" }),
|
|
1175
|
+
/* @__PURE__ */ jsx13(Input4, { id: "url", name: "url", defaultValue: "" })
|
|
1176
|
+
] }),
|
|
1177
|
+
/* @__PURE__ */ jsx13(Button, { type: "submit", children: "Create" })
|
|
1178
|
+
] }) });
|
|
1179
|
+
}
|
|
1180
|
+
|
|
1181
|
+
// src/Annotation/ImageUrlAnnotation/create-image-url-annotation.tsx
|
|
1182
|
+
import { jsx as jsx14 } from "react/jsx-runtime";
|
|
1183
|
+
async function createImageUrlAnnotation(data, ctx) {
|
|
1184
|
+
const annotation = {
|
|
1185
|
+
id: ctx.generateId("annotation"),
|
|
1186
|
+
type: "Annotation"
|
|
1187
|
+
};
|
|
1188
|
+
const targetType = ctx.options.targetType;
|
|
1189
|
+
const resource = await ctx.create(
|
|
1190
|
+
"@manifest-editor/image-url-creator",
|
|
1191
|
+
data,
|
|
1192
|
+
{
|
|
1193
|
+
parent: { resource: annotation, property: "body" }
|
|
1194
|
+
}
|
|
1195
|
+
);
|
|
1196
|
+
if (targetType === "Annotation") {
|
|
1197
|
+
return {
|
|
1198
|
+
...annotation,
|
|
1199
|
+
body: [resource],
|
|
1200
|
+
motivation: data.motivation || "painting",
|
|
1201
|
+
target: ctx.getTarget()
|
|
1202
|
+
};
|
|
1203
|
+
}
|
|
1204
|
+
if (targetType === "Canvas") {
|
|
1205
|
+
const canvasId = ctx.generateId("canvas");
|
|
1206
|
+
const pageId = ctx.generateId("annotation-page", {
|
|
1207
|
+
id: canvasId,
|
|
1208
|
+
type: "Canvas"
|
|
1209
|
+
});
|
|
1210
|
+
const annotationResource = ctx.embed({
|
|
1211
|
+
...annotation,
|
|
1212
|
+
motivation: "painting",
|
|
1213
|
+
body: [resource],
|
|
1214
|
+
target: {
|
|
1215
|
+
type: "SpecificResource",
|
|
1216
|
+
source: { id: canvasId, type: "Canvas" }
|
|
1217
|
+
}
|
|
1218
|
+
});
|
|
1219
|
+
const page = ctx.embed({
|
|
1220
|
+
id: pageId,
|
|
1221
|
+
type: "AnnotationPage",
|
|
1222
|
+
items: [annotationResource]
|
|
1223
|
+
});
|
|
1224
|
+
return ctx.embed({
|
|
1225
|
+
id: canvasId,
|
|
1226
|
+
type: "Canvas",
|
|
1227
|
+
label: data.label || { en: ["Untitled canvas"] },
|
|
1228
|
+
height: resource.resource.height || 1e3,
|
|
1229
|
+
width: resource.resource.width || 1e3,
|
|
1230
|
+
items: [page]
|
|
1231
|
+
});
|
|
1232
|
+
}
|
|
1233
|
+
}
|
|
1234
|
+
function CreateImageUrlAnnotationForm(props) {
|
|
1235
|
+
return /* @__PURE__ */ jsx14(CreateImageUrlForm, { ...props });
|
|
1236
|
+
}
|
|
1237
|
+
|
|
1238
|
+
// src/Annotation/ImageUrlAnnotation/index.tsx
|
|
1239
|
+
import { jsx as jsx15 } from "react/jsx-runtime";
|
|
1240
|
+
var imageUrlAnnotation = {
|
|
1241
|
+
id: "@manifest-editor/image-url-annotation",
|
|
1242
|
+
create: createImageUrlAnnotation,
|
|
1243
|
+
label: "Image",
|
|
1244
|
+
dependencies: ["@manifest-editor/image-url-creator"],
|
|
1245
|
+
summary: "Image from URL",
|
|
1246
|
+
tags: ["image"],
|
|
1247
|
+
icon: /* @__PURE__ */ jsx15(AddImageIcon2, {}),
|
|
962
1248
|
render(ctx) {
|
|
963
|
-
return /* @__PURE__ */
|
|
1249
|
+
return /* @__PURE__ */ jsx15(CreateImageUrlAnnotationForm, { ...ctx });
|
|
964
1250
|
},
|
|
965
1251
|
resourceType: "Annotation",
|
|
966
1252
|
resourceFields: ["id", "type", "motivation", "body", "target"],
|
|
@@ -969,21 +1255,25 @@ var imageServiceAnnotation = {
|
|
|
969
1255
|
parentTypes: ["AnnotationPage", "Manifest"],
|
|
970
1256
|
parentFields: ["items"]
|
|
971
1257
|
},
|
|
972
|
-
sideEffects: [
|
|
1258
|
+
sideEffects: [
|
|
1259
|
+
resizeToFitService,
|
|
1260
|
+
resizeResourceToEmptyCanvas,
|
|
1261
|
+
repositionMultipleImages
|
|
1262
|
+
],
|
|
973
1263
|
staticFields: {
|
|
974
1264
|
type: "Annotation"
|
|
975
1265
|
}
|
|
976
1266
|
};
|
|
977
1267
|
|
|
978
1268
|
// src/Annotation/NoBodyAnnotation/index.tsx
|
|
979
|
-
import { EmptyCanvasIcon
|
|
980
|
-
import { jsx as
|
|
1269
|
+
import { EmptyCanvasIcon } from "@manifest-editor/components";
|
|
1270
|
+
import { jsx as jsx16 } from "react/jsx-runtime";
|
|
981
1271
|
var noBodyAnnotation = {
|
|
982
1272
|
id: "@manifest-editor/no-body-annotation",
|
|
983
1273
|
create: createNoBodyAnnotation,
|
|
984
1274
|
label: "Annotation without body",
|
|
985
1275
|
summary: "Add an annotation that only has motivation and target",
|
|
986
|
-
icon: /* @__PURE__ */
|
|
1276
|
+
icon: /* @__PURE__ */ jsx16(EmptyCanvasIcon, {}),
|
|
987
1277
|
resourceType: "Annotation",
|
|
988
1278
|
resourceFields: ["id", "type", "motivation", "target"],
|
|
989
1279
|
supports: {
|
|
@@ -1007,201 +1297,97 @@ function createNoBodyAnnotation(data, ctx) {
|
|
|
1007
1297
|
});
|
|
1008
1298
|
}
|
|
1009
1299
|
|
|
1010
|
-
// src/
|
|
1011
|
-
import {
|
|
1012
|
-
import { lazy } from "react";
|
|
1300
|
+
// src/Annotation/VideoAnnotation/index.tsx
|
|
1301
|
+
import { VideoIcon } from "@manifest-editor/components";
|
|
1013
1302
|
|
|
1014
|
-
//
|
|
1015
|
-
|
|
1016
|
-
|
|
1017
|
-
|
|
1018
|
-
|
|
1019
|
-
|
|
1020
|
-
|
|
1021
|
-
|
|
1022
|
-
|
|
1023
|
-
|
|
1024
|
-
var provided = typeof message === "function" ? message() : message;
|
|
1025
|
-
var value = provided ? "".concat(prefix, ": ").concat(provided) : prefix;
|
|
1026
|
-
throw new Error(value);
|
|
1027
|
-
}
|
|
1303
|
+
// src/Annotation/VideoAnnotation/create-video-annotation.tsx
|
|
1304
|
+
import { getValue as getValue2 } from "@iiif/helpers";
|
|
1305
|
+
import { ErrorMessage as ErrorMessage2 } from "@manifest-editor/components";
|
|
1306
|
+
import {
|
|
1307
|
+
DimensionsTriplet,
|
|
1308
|
+
Input as Input5,
|
|
1309
|
+
InputContainer as InputContainer6,
|
|
1310
|
+
InputLabel as InputLabel6,
|
|
1311
|
+
LanguageFieldEditor as LanguageFieldEditor4
|
|
1312
|
+
} from "@manifest-editor/editors";
|
|
1028
1313
|
|
|
1029
|
-
//
|
|
1030
|
-
|
|
1031
|
-
|
|
1032
|
-
|
|
1033
|
-
|
|
1034
|
-
|
|
1035
|
-
|
|
1036
|
-
|
|
1037
|
-
|
|
1038
|
-
|
|
1039
|
-
|
|
1040
|
-
|
|
1041
|
-
|
|
1042
|
-
const type = target.source.type;
|
|
1043
|
-
const previewVault = ctx.getPreviewVault();
|
|
1044
|
-
if (targetType === "Canvas" || targetType === "Annotation") {
|
|
1045
|
-
if (type === "Canvas") {
|
|
1046
|
-
const canvasId = target.source.id;
|
|
1047
|
-
const manifestId = target.source.partOf?.find((t) => t.type === "Manifest");
|
|
1048
|
-
invariant(manifestId, "Could not load external resource without partOf");
|
|
1049
|
-
const manifest = await previewVault.loadManifest(manifestId);
|
|
1050
|
-
invariant(manifest, "Manifest not found");
|
|
1051
|
-
const canvasRef = manifest.items.find((item) => item.id === canvasId);
|
|
1052
|
-
invariant(canvasRef, "Canvas not found");
|
|
1053
|
-
const canvas = previewVault.get(canvasRef);
|
|
1054
|
-
if (targetType === "Canvas") {
|
|
1055
|
-
return ctx.embed(previewVault.toPresentation3(canvas));
|
|
1056
|
-
}
|
|
1057
|
-
const annotationPage = previewVault.get(canvas.items[0]);
|
|
1058
|
-
const annotation = previewVault.get(annotationPage.items[0]);
|
|
1059
|
-
if (targetType === "Annotation") {
|
|
1060
|
-
const fullAnnotation = previewVault.toPresentation3(annotation);
|
|
1061
|
-
if (fullAnnotation && fullAnnotation?.body?.service) {
|
|
1062
|
-
const width = fullAnnotation?.body.width;
|
|
1063
|
-
const height = fullAnnotation?.body.height;
|
|
1064
|
-
const service = Array.isArray(fullAnnotation?.body?.service) ? fullAnnotation?.body?.service[0] : fullAnnotation?.body?.service;
|
|
1065
|
-
if (!service.width || !service.height) {
|
|
1066
|
-
service.width = width;
|
|
1067
|
-
service.height = height;
|
|
1068
|
-
}
|
|
1069
|
-
}
|
|
1070
|
-
if (target.selector && target.selector.type === "BoxSelector") {
|
|
1071
|
-
const selector = {
|
|
1072
|
-
"@context": "http://iiif.io/api/annex/openannotation/context.json",
|
|
1073
|
-
type: "iiif:ImageApiSelector",
|
|
1074
|
-
region: [
|
|
1075
|
-
~~target.selector.spatial.x,
|
|
1076
|
-
~~target.selector.spatial.y,
|
|
1077
|
-
~~target.selector.spatial.width,
|
|
1078
|
-
~~target.selector.spatial.height
|
|
1079
|
-
].join(",")
|
|
1080
|
-
};
|
|
1081
|
-
fullAnnotation.body = {
|
|
1082
|
-
id: ctx.generateId("SpecificResource", annotation),
|
|
1083
|
-
type: "SpecificResource",
|
|
1084
|
-
source: fullAnnotation.body,
|
|
1085
|
-
selector
|
|
1086
|
-
};
|
|
1087
|
-
return ctx.embed({
|
|
1088
|
-
...fullAnnotation,
|
|
1089
|
-
target: ctx.getTarget()
|
|
1090
|
-
});
|
|
1091
|
-
}
|
|
1092
|
-
return ctx.embed({
|
|
1093
|
-
...previewVault.toPresentation3(annotation),
|
|
1094
|
-
target: ctx.getTarget()
|
|
1095
|
-
});
|
|
1096
|
-
}
|
|
1097
|
-
}
|
|
1098
|
-
}
|
|
1099
|
-
throw new Error("Not yet supported.");
|
|
1100
|
-
}
|
|
1101
|
-
var IIIFBrowserCreatorForm = lazy(() => import("./iiif-browser-form.lazy-PL3WMLU5.js"));
|
|
1102
|
-
|
|
1103
|
-
// src/ContentResource/IIIFBrowserCreator/index.tsx
|
|
1104
|
-
import { IIIFBrowserIcon } from "@manifest-editor/components";
|
|
1105
|
-
import { jsx as jsx23 } from "react/jsx-runtime";
|
|
1106
|
-
var iiifBrowserCreator = {
|
|
1107
|
-
id: "@manifest-editor/iiif-browser-creator",
|
|
1108
|
-
create: createFromIIIFBrowserOutput,
|
|
1109
|
-
label: "IIIF Browser",
|
|
1110
|
-
summary: "Browse IIIF Resources",
|
|
1111
|
-
icon: /* @__PURE__ */ jsx23(IIIFBrowserIcon, {}),
|
|
1112
|
-
render(ctx) {
|
|
1113
|
-
return /* @__PURE__ */ jsx23(IIIFBrowserCreatorForm, { ...ctx });
|
|
1114
|
-
},
|
|
1115
|
-
resourceType: "ContentResource",
|
|
1116
|
-
resourceFields: ["id", "language", "type", "format", "value"],
|
|
1117
|
-
additionalTypes: ["Annotation", "Canvas"],
|
|
1118
|
-
supports: {
|
|
1119
|
-
parentTypes: ["Annotation", "Manifest", "AnnotationPage"],
|
|
1120
|
-
parentFieldMap: {
|
|
1121
|
-
Annotation: ["body"],
|
|
1122
|
-
Manifest: ["items"],
|
|
1123
|
-
AnnotationPage: ["items"]
|
|
1124
|
-
}
|
|
1125
|
-
},
|
|
1126
|
-
sideEffects: [resizeToFitService, resizeResourceToEmptyCanvas, repositionMultipleImages],
|
|
1127
|
-
staticFields: {}
|
|
1128
|
-
};
|
|
1129
|
-
|
|
1130
|
-
// src/Canvas/InternalCanvas/index.tsx
|
|
1131
|
-
import { useManifest, useVault } from "react-iiif-vault";
|
|
1132
|
-
import { IIIFExplorer } from "@manifest-editor/iiif-browser";
|
|
1133
|
-
import { jsx as jsx24 } from "react/jsx-runtime";
|
|
1134
|
-
var internalCanvas = {
|
|
1135
|
-
id: "@manifest-editor/internal-canvas",
|
|
1136
|
-
create: createInternalCanvas,
|
|
1137
|
-
label: "Internal canvas link",
|
|
1138
|
-
summary: "Canvas from the same manifest",
|
|
1139
|
-
icon: /* @__PURE__ */ jsx24(ThumbnailStripIcon, {}),
|
|
1140
|
-
resourceType: "Canvas",
|
|
1141
|
-
resourceFields: ["id", "type", "label"],
|
|
1142
|
-
supports: {
|
|
1143
|
-
parentTypes: ["Manifest"],
|
|
1144
|
-
parentFields: ["start"]
|
|
1145
|
-
},
|
|
1146
|
-
render: (ctx) => /* @__PURE__ */ jsx24(InternalCanvas, { ...ctx })
|
|
1147
|
-
};
|
|
1148
|
-
function InternalCanvas(props) {
|
|
1149
|
-
const manifest = useManifest();
|
|
1150
|
-
const vault = useVault();
|
|
1151
|
-
invariant(manifest, "Manifest is not loaded");
|
|
1152
|
-
return /* @__PURE__ */ jsx24(
|
|
1153
|
-
IIIFExplorer,
|
|
1314
|
+
// ../ui/ui/VideoPlayer/VideoPlayer.tsx
|
|
1315
|
+
import { CanvasPanel as CanvasPanel2, MediaPlayerProvider, useSimpleMediaPlayer } from "react-iiif-vault";
|
|
1316
|
+
import { jsx as jsx17, jsxs as jsxs9 } from "react/jsx-runtime";
|
|
1317
|
+
function VideoPlayer({
|
|
1318
|
+
media,
|
|
1319
|
+
onError,
|
|
1320
|
+
duration,
|
|
1321
|
+
onDuration,
|
|
1322
|
+
onDimensions
|
|
1323
|
+
}) {
|
|
1324
|
+
const [{ element, currentTime, progress }, state, actions] = useSimpleMediaPlayer({ duration });
|
|
1325
|
+
return /* @__PURE__ */ jsxs9(
|
|
1326
|
+
MediaPlayerProvider,
|
|
1154
1327
|
{
|
|
1155
|
-
|
|
1156
|
-
|
|
1157
|
-
|
|
1158
|
-
|
|
1159
|
-
|
|
1160
|
-
|
|
1161
|
-
|
|
1162
|
-
|
|
1163
|
-
|
|
1164
|
-
|
|
1165
|
-
|
|
1166
|
-
|
|
1328
|
+
element,
|
|
1329
|
+
state,
|
|
1330
|
+
actions,
|
|
1331
|
+
currentTime,
|
|
1332
|
+
progress,
|
|
1333
|
+
children: [
|
|
1334
|
+
/* @__PURE__ */ jsx17(
|
|
1335
|
+
"div",
|
|
1336
|
+
{
|
|
1337
|
+
style: {
|
|
1338
|
+
maxHeight: 400,
|
|
1339
|
+
aspectRatio: `${media.width}/${media.height}`,
|
|
1340
|
+
position: "relative"
|
|
1341
|
+
},
|
|
1342
|
+
children: /* @__PURE__ */ jsx17(CanvasPanel2.VideoHTML, { element, media, playPause: actions.playPause })
|
|
1167
1343
|
}
|
|
1168
|
-
|
|
1169
|
-
|
|
1170
|
-
|
|
1344
|
+
),
|
|
1345
|
+
/* @__PURE__ */ jsx17(MediaControls, { onError, onDuration, onDimensions })
|
|
1346
|
+
]
|
|
1171
1347
|
}
|
|
1172
1348
|
);
|
|
1173
1349
|
}
|
|
1174
|
-
async function createInternalCanvas(data, ctx) {
|
|
1175
|
-
return ctx.embed({ id: data.id, type: "Canvas" });
|
|
1176
|
-
}
|
|
1177
1350
|
|
|
1178
|
-
// src/Annotation/
|
|
1179
|
-
import {
|
|
1180
|
-
|
|
1351
|
+
// src/Annotation/VideoAnnotation/create-video-annotation.tsx
|
|
1352
|
+
import { useEffect as useEffect3, useState as useState5 } from "react";
|
|
1353
|
+
import { jsx as jsx18, jsxs as jsxs10 } from "react/jsx-runtime";
|
|
1354
|
+
async function createVideoAnnotation(data, ctx) {
|
|
1181
1355
|
const annotation = {
|
|
1182
1356
|
id: ctx.generateId("annotation"),
|
|
1183
1357
|
type: "Annotation"
|
|
1184
1358
|
};
|
|
1185
1359
|
const targetType = ctx.options.targetType;
|
|
1186
|
-
const
|
|
1187
|
-
|
|
1360
|
+
const body = ctx.embed({
|
|
1361
|
+
id: data.url,
|
|
1362
|
+
type: "Video",
|
|
1363
|
+
format: "video/mp4",
|
|
1364
|
+
width: data.width,
|
|
1365
|
+
height: data.height,
|
|
1366
|
+
duration: data.duration || 0
|
|
1188
1367
|
});
|
|
1189
1368
|
if (targetType === "Annotation") {
|
|
1190
|
-
return {
|
|
1369
|
+
return ctx.embed({
|
|
1191
1370
|
...annotation,
|
|
1192
|
-
|
|
1193
|
-
motivation: data.motivation || "painting",
|
|
1371
|
+
label: getValue2(data.label) && data.label,
|
|
1372
|
+
motivation: data.motivation || ctx.options.initialData?.motivation || "painting",
|
|
1373
|
+
body,
|
|
1194
1374
|
target: ctx.getTarget()
|
|
1195
|
-
};
|
|
1375
|
+
});
|
|
1196
1376
|
}
|
|
1197
1377
|
if (targetType === "Canvas") {
|
|
1198
1378
|
const canvasId = ctx.generateId("canvas");
|
|
1199
|
-
const pageId = ctx.generateId("annotation-page", {
|
|
1379
|
+
const pageId = ctx.generateId("annotation-page", {
|
|
1380
|
+
id: canvasId,
|
|
1381
|
+
type: "Canvas"
|
|
1382
|
+
});
|
|
1200
1383
|
const annotationResource = ctx.embed({
|
|
1201
1384
|
...annotation,
|
|
1202
1385
|
motivation: "painting",
|
|
1203
|
-
body
|
|
1204
|
-
target: {
|
|
1386
|
+
body,
|
|
1387
|
+
target: {
|
|
1388
|
+
type: "SpecificResource",
|
|
1389
|
+
source: { id: canvasId, type: "Canvas" }
|
|
1390
|
+
}
|
|
1205
1391
|
});
|
|
1206
1392
|
const page = ctx.embed({
|
|
1207
1393
|
id: pageId,
|
|
@@ -1211,662 +1397,826 @@ async function createImageUrlAnnotation(data, ctx) {
|
|
|
1211
1397
|
return ctx.embed({
|
|
1212
1398
|
id: canvasId,
|
|
1213
1399
|
type: "Canvas",
|
|
1214
|
-
label: data.label || { en: ["Untitled canvas"] },
|
|
1215
|
-
|
|
1216
|
-
width:
|
|
1400
|
+
label: data.label || { en: ["Untitled HTML canvas"] },
|
|
1401
|
+
duration: data.duration || 0,
|
|
1402
|
+
width: data.width,
|
|
1403
|
+
height: data.height,
|
|
1217
1404
|
items: [page]
|
|
1218
1405
|
});
|
|
1219
1406
|
}
|
|
1220
1407
|
}
|
|
1221
|
-
function
|
|
1222
|
-
|
|
1408
|
+
function CreateVideoAnnotationForm(props) {
|
|
1409
|
+
const [url, setUrl] = useState5("");
|
|
1410
|
+
const [duration, setDuration] = useState5(0);
|
|
1411
|
+
const [width, setWidth] = useState5(0);
|
|
1412
|
+
const [height, setHeight] = useState5(0);
|
|
1413
|
+
const [error, setError] = useState5("");
|
|
1414
|
+
const [label, setLabel] = useState5({ en: [""] });
|
|
1415
|
+
const onSubmit = () => {
|
|
1416
|
+
props.runCreate({
|
|
1417
|
+
url,
|
|
1418
|
+
duration,
|
|
1419
|
+
label,
|
|
1420
|
+
width,
|
|
1421
|
+
height
|
|
1422
|
+
});
|
|
1423
|
+
};
|
|
1424
|
+
useEffect3(() => {
|
|
1425
|
+
setError("");
|
|
1426
|
+
setDuration(0);
|
|
1427
|
+
if (url) {
|
|
1428
|
+
const labelFromUrl = url.split("/").pop()?.split(".").shift();
|
|
1429
|
+
setLabel({ en: [labelFromUrl || ""] });
|
|
1430
|
+
}
|
|
1431
|
+
}, [url]);
|
|
1432
|
+
return /* @__PURE__ */ jsxs10(PaddedSidebarContainer, { children: [
|
|
1433
|
+
error ? /* @__PURE__ */ jsx18(ErrorMessage2, { children: error }) : null,
|
|
1434
|
+
/* @__PURE__ */ jsxs10(InputContainer6, { children: [
|
|
1435
|
+
/* @__PURE__ */ jsx18(InputLabel6, { htmlFor: "video-url", children: "URL" }),
|
|
1436
|
+
/* @__PURE__ */ jsx18(
|
|
1437
|
+
Input5,
|
|
1438
|
+
{
|
|
1439
|
+
type: "text",
|
|
1440
|
+
id: "video-url",
|
|
1441
|
+
value: url,
|
|
1442
|
+
onChange: (e) => setUrl(e.target.value)
|
|
1443
|
+
}
|
|
1444
|
+
)
|
|
1445
|
+
] }),
|
|
1446
|
+
url && !error ? /* @__PURE__ */ jsx18("div", { children: /* @__PURE__ */ jsx18(
|
|
1447
|
+
LanguageFieldEditor4,
|
|
1448
|
+
{
|
|
1449
|
+
containerId: "label",
|
|
1450
|
+
focusId: "label_",
|
|
1451
|
+
label: "Label",
|
|
1452
|
+
fields: label,
|
|
1453
|
+
onSave: (e) => setLabel(e.toInternationalString())
|
|
1454
|
+
},
|
|
1455
|
+
url + "__" + duration
|
|
1456
|
+
) }) : null,
|
|
1457
|
+
url && !error ? /* @__PURE__ */ jsx18(
|
|
1458
|
+
VideoPlayer,
|
|
1459
|
+
{
|
|
1460
|
+
duration,
|
|
1461
|
+
onDuration: (d) => setDuration(d),
|
|
1462
|
+
onError: (err) => setError(err),
|
|
1463
|
+
media: {
|
|
1464
|
+
url,
|
|
1465
|
+
duration,
|
|
1466
|
+
height,
|
|
1467
|
+
width,
|
|
1468
|
+
type: "Video"
|
|
1469
|
+
},
|
|
1470
|
+
onDimensions: (w, h) => {
|
|
1471
|
+
setWidth(w || 0);
|
|
1472
|
+
setHeight(h || 0);
|
|
1473
|
+
}
|
|
1474
|
+
}
|
|
1475
|
+
) : null,
|
|
1476
|
+
!error && (duration || width || height) ? /* @__PURE__ */ jsx18(InputContainer6, { $wide: true, children: /* @__PURE__ */ jsx18(
|
|
1477
|
+
DimensionsTriplet,
|
|
1478
|
+
{
|
|
1479
|
+
widthId: "width",
|
|
1480
|
+
width: width || 0,
|
|
1481
|
+
changeWidth: (v) => setWidth(v),
|
|
1482
|
+
heightId: "height",
|
|
1483
|
+
height: height || 0,
|
|
1484
|
+
changeHeight: (v) => setHeight(v),
|
|
1485
|
+
durationId: "duration",
|
|
1486
|
+
duration: duration || 0,
|
|
1487
|
+
changeDuration: (v) => setDuration(v)
|
|
1488
|
+
}
|
|
1489
|
+
) }) : null,
|
|
1490
|
+
url && !error && /* @__PURE__ */ jsx18(Button, { onClick: onSubmit, children: "Add video" })
|
|
1491
|
+
] });
|
|
1223
1492
|
}
|
|
1224
1493
|
|
|
1225
|
-
// src/Annotation/
|
|
1226
|
-
import {
|
|
1227
|
-
|
|
1228
|
-
|
|
1229
|
-
|
|
1230
|
-
|
|
1231
|
-
|
|
1232
|
-
|
|
1233
|
-
|
|
1234
|
-
|
|
1235
|
-
render(ctx) {
|
|
1236
|
-
return /* @__PURE__ */ jsx26(CreateImageUrlAnnotationForm, { ...ctx });
|
|
1494
|
+
// src/Annotation/VideoAnnotation/index.tsx
|
|
1495
|
+
import { jsx as jsx19 } from "react/jsx-runtime";
|
|
1496
|
+
var videoAnnotation = {
|
|
1497
|
+
id: "@manifest-editor/video-annotation",
|
|
1498
|
+
create: createVideoAnnotation,
|
|
1499
|
+
label: "Video",
|
|
1500
|
+
summary: "Video annotation",
|
|
1501
|
+
icon: /* @__PURE__ */ jsx19(VideoIcon, {}),
|
|
1502
|
+
render(ctx) {
|
|
1503
|
+
return /* @__PURE__ */ jsx19(CreateVideoAnnotationForm, { ...ctx });
|
|
1237
1504
|
},
|
|
1238
1505
|
resourceType: "Annotation",
|
|
1239
1506
|
resourceFields: ["id", "type", "motivation", "body", "target"],
|
|
1240
1507
|
additionalTypes: ["Canvas"],
|
|
1241
1508
|
supports: {
|
|
1509
|
+
initialData: true,
|
|
1242
1510
|
parentTypes: ["AnnotationPage", "Manifest"],
|
|
1243
1511
|
parentFields: ["items"]
|
|
1244
1512
|
},
|
|
1245
|
-
sideEffects: [resizeToFitService, resizeResourceToEmptyCanvas, repositionMultipleImages],
|
|
1246
1513
|
staticFields: {
|
|
1247
1514
|
type: "Annotation"
|
|
1248
1515
|
}
|
|
1249
1516
|
};
|
|
1250
1517
|
|
|
1251
|
-
//
|
|
1252
|
-
import {
|
|
1518
|
+
// ../ui/icons/ThumbnailStripIcon.tsx
|
|
1519
|
+
import { jsx as jsx20, jsxs as jsxs11 } from "react/jsx-runtime";
|
|
1520
|
+
var ThumbnailStripIcon = () => /* @__PURE__ */ jsx20(
|
|
1521
|
+
"svg",
|
|
1522
|
+
{
|
|
1523
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
1524
|
+
height: "24px",
|
|
1525
|
+
viewBox: "0 0 24 24",
|
|
1526
|
+
width: "24px",
|
|
1527
|
+
fill: "#000000",
|
|
1528
|
+
transform: "scale(-1, 1)",
|
|
1529
|
+
children: /* @__PURE__ */ jsxs11("g", { children: [
|
|
1530
|
+
/* @__PURE__ */ jsx20("rect", { fill: "none", height: "24", width: "24" }),
|
|
1531
|
+
/* @__PURE__ */ jsx20("path", { d: "M16,20H2V4h14V20z M18,8h4V4h-4V8z M18,20h4v-4h-4V20z M18,14h4v-4h-4V14z" })
|
|
1532
|
+
] })
|
|
1533
|
+
}
|
|
1534
|
+
);
|
|
1253
1535
|
|
|
1254
|
-
//
|
|
1255
|
-
import
|
|
1256
|
-
var
|
|
1257
|
-
|
|
1258
|
-
|
|
1259
|
-
|
|
1260
|
-
|
|
1261
|
-
|
|
1262
|
-
|
|
1263
|
-
|
|
1264
|
-
|
|
1265
|
-
|
|
1266
|
-
|
|
1536
|
+
// src/AnnotationPage/EmptyAnnotationPage/index.tsx
|
|
1537
|
+
import { jsx as jsx21 } from "react/jsx-runtime";
|
|
1538
|
+
var emptyAnnotationPage = {
|
|
1539
|
+
id: "@manifest-editor/empty-annotation-page",
|
|
1540
|
+
create: (data, ctx) => {
|
|
1541
|
+
return ctx.embed({
|
|
1542
|
+
id: ctx.generateId("annotations"),
|
|
1543
|
+
label: data.label,
|
|
1544
|
+
type: "AnnotationPage",
|
|
1545
|
+
items: []
|
|
1546
|
+
});
|
|
1547
|
+
},
|
|
1548
|
+
label: "Empty annotation page",
|
|
1549
|
+
summary: "AnnotationPage with nothing",
|
|
1550
|
+
icon: /* @__PURE__ */ jsx21(ThumbnailStripIcon, {}),
|
|
1551
|
+
resourceType: "AnnotationPage",
|
|
1552
|
+
resourceFields: ["id", "type", "items"],
|
|
1553
|
+
supports: {
|
|
1554
|
+
parentTypes: ["Manifest", "Canvas", "Range"],
|
|
1555
|
+
parentFieldMap: {
|
|
1556
|
+
Manifest: ["annotations"],
|
|
1557
|
+
Canvas: ["items", "annotations"],
|
|
1558
|
+
Range: ["annotations"]
|
|
1559
|
+
}
|
|
1267
1560
|
}
|
|
1268
|
-
|
|
1269
|
-
font-size: 0.75em;
|
|
1270
|
-
white-space: nowrap;
|
|
1271
|
-
padding: ${props.theme.padding.xs || "0.25rem"} ${props.theme.padding.small || "0.5rem"};
|
|
1272
|
-
line-height: 1.6em;
|
|
1273
|
-
width: fit-content;
|
|
1274
|
-
`}
|
|
1275
|
-
`;
|
|
1561
|
+
};
|
|
1276
1562
|
|
|
1277
|
-
//
|
|
1278
|
-
import {
|
|
1279
|
-
import {
|
|
1563
|
+
// src/Canvas/EmptyCanvas/index.tsx
|
|
1564
|
+
import { EmptyCanvasIcon as EmptyCanvasIcon2 } from "@manifest-editor/components";
|
|
1565
|
+
import { jsx as jsx22 } from "react/jsx-runtime";
|
|
1566
|
+
var emptyCanvas = {
|
|
1567
|
+
id: "@manifest-editor/empty-canvas",
|
|
1568
|
+
create: (data, ctx) => {
|
|
1569
|
+
const canvasId = ctx.generateId("canvas");
|
|
1570
|
+
const page = ctx.embed({
|
|
1571
|
+
id: ctx.generateId("annotation-page", { id: canvasId, type: "Canvas" }),
|
|
1572
|
+
type: "AnnotationPage",
|
|
1573
|
+
items: []
|
|
1574
|
+
});
|
|
1575
|
+
return {
|
|
1576
|
+
id: canvasId,
|
|
1577
|
+
type: "Canvas",
|
|
1578
|
+
label: data.label || { en: [""] },
|
|
1579
|
+
height: data.height || 1e3,
|
|
1580
|
+
width: data.width || 1e3,
|
|
1581
|
+
items: [page]
|
|
1582
|
+
};
|
|
1583
|
+
},
|
|
1584
|
+
label: "Empty canvas",
|
|
1585
|
+
summary: "No content",
|
|
1586
|
+
icon: /* @__PURE__ */ jsx22(EmptyCanvasIcon2, {}),
|
|
1587
|
+
resourceType: "Canvas",
|
|
1588
|
+
resourceFields: ["id", "type", "label", "height", "width", "items"],
|
|
1589
|
+
supports: {
|
|
1590
|
+
parentTypes: ["Manifest"],
|
|
1591
|
+
parentFields: ["items"]
|
|
1592
|
+
}
|
|
1593
|
+
};
|
|
1280
1594
|
|
|
1281
|
-
//
|
|
1282
|
-
import {
|
|
1283
|
-
|
|
1284
|
-
|
|
1285
|
-
|
|
1286
|
-
|
|
1287
|
-
|
|
1288
|
-
|
|
1289
|
-
|
|
1290
|
-
|
|
1291
|
-
|
|
1292
|
-
|
|
1293
|
-
|
|
1294
|
-
|
|
1295
|
-
|
|
1296
|
-
|
|
1297
|
-
|
|
1298
|
-
|
|
1299
|
-
|
|
1300
|
-
|
|
1301
|
-
|
|
1302
|
-
|
|
1303
|
-
|
|
1304
|
-
|
|
1305
|
-
|
|
1306
|
-
|
|
1307
|
-
/* @__PURE__ */
|
|
1308
|
-
|
|
1309
|
-
|
|
1310
|
-
|
|
1311
|
-
|
|
1312
|
-
|
|
1313
|
-
|
|
1314
|
-
|
|
1315
|
-
|
|
1316
|
-
|
|
1317
|
-
|
|
1318
|
-
|
|
1319
|
-
|
|
1595
|
+
// src/Canvas/InternalCanvas/index.tsx
|
|
1596
|
+
import { IIIFExplorer } from "@manifest-editor/iiif-browser";
|
|
1597
|
+
import { useManifest, useVault } from "react-iiif-vault";
|
|
1598
|
+
|
|
1599
|
+
// ../../node_modules/.pnpm/tiny-invariant@1.3.3/node_modules/tiny-invariant/dist/esm/tiny-invariant.js
|
|
1600
|
+
var isProduction = false;
|
|
1601
|
+
var prefix = "Invariant failed";
|
|
1602
|
+
function invariant(condition, message) {
|
|
1603
|
+
if (condition) {
|
|
1604
|
+
return;
|
|
1605
|
+
}
|
|
1606
|
+
if (isProduction) {
|
|
1607
|
+
throw new Error(prefix);
|
|
1608
|
+
}
|
|
1609
|
+
var provided = typeof message === "function" ? message() : message;
|
|
1610
|
+
var value = provided ? "".concat(prefix, ": ").concat(provided) : prefix;
|
|
1611
|
+
throw new Error(value);
|
|
1612
|
+
}
|
|
1613
|
+
|
|
1614
|
+
// src/Canvas/InternalCanvas/index.tsx
|
|
1615
|
+
import { jsx as jsx23 } from "react/jsx-runtime";
|
|
1616
|
+
var internalCanvas = {
|
|
1617
|
+
id: "@manifest-editor/internal-canvas",
|
|
1618
|
+
create: createInternalCanvas,
|
|
1619
|
+
label: "Internal canvas link",
|
|
1620
|
+
summary: "Canvas from the same manifest",
|
|
1621
|
+
icon: /* @__PURE__ */ jsx23(ThumbnailStripIcon, {}),
|
|
1622
|
+
resourceType: "Canvas",
|
|
1623
|
+
resourceFields: ["id", "type", "label"],
|
|
1624
|
+
supports: {
|
|
1625
|
+
parentTypes: ["Manifest"],
|
|
1626
|
+
parentFields: ["start"]
|
|
1627
|
+
},
|
|
1628
|
+
render: (ctx) => /* @__PURE__ */ jsx23(InternalCanvas, { ...ctx })
|
|
1629
|
+
};
|
|
1630
|
+
function InternalCanvas(props) {
|
|
1631
|
+
const manifest = useManifest();
|
|
1632
|
+
const vault = useVault();
|
|
1633
|
+
invariant(manifest, "Manifest is not loaded");
|
|
1634
|
+
return /* @__PURE__ */ jsx23(
|
|
1635
|
+
IIIFExplorer,
|
|
1320
1636
|
{
|
|
1321
|
-
|
|
1322
|
-
|
|
1637
|
+
vault,
|
|
1638
|
+
entry: manifest,
|
|
1639
|
+
window: false,
|
|
1640
|
+
hideHeader: true,
|
|
1641
|
+
hideBack: true,
|
|
1642
|
+
output: { type: "url" },
|
|
1643
|
+
outputTargets: [
|
|
1644
|
+
{
|
|
1645
|
+
type: "callback",
|
|
1646
|
+
label: "Select canvas",
|
|
1647
|
+
cb: (url) => {
|
|
1648
|
+
props.runCreate({ id: url });
|
|
1649
|
+
}
|
|
1650
|
+
}
|
|
1651
|
+
],
|
|
1652
|
+
outputTypes: ["Canvas"]
|
|
1323
1653
|
}
|
|
1324
|
-
)
|
|
1654
|
+
);
|
|
1655
|
+
}
|
|
1656
|
+
async function createInternalCanvas(data, ctx) {
|
|
1657
|
+
return ctx.embed({ id: data.id, type: "Canvas" });
|
|
1658
|
+
}
|
|
1659
|
+
|
|
1660
|
+
// ../ui/icons/TextFormatIcon.tsx
|
|
1661
|
+
import { jsx as jsx24, jsxs as jsxs12 } from "react/jsx-runtime";
|
|
1662
|
+
var TextFormatIcon = (props) => /* @__PURE__ */ jsxs12("svg", { xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 24 24", height: "1em", width: "1em", ...props, children: [
|
|
1663
|
+
/* @__PURE__ */ jsx24("path", { d: "M0 0h24v24H0z", fill: "none" }),
|
|
1664
|
+
/* @__PURE__ */ jsx24("path", { d: "M5 17v2h14v-2H5zm4.5-4.2h5l.9 2.2h2.1L12.75 4h-1.5L6.5 15h2.1l.9-2.2zM12 5.98 13.87 11h-3.74L12 5.98z" })
|
|
1325
1665
|
] });
|
|
1326
1666
|
|
|
1327
|
-
//
|
|
1328
|
-
import
|
|
1329
|
-
|
|
1330
|
-
|
|
1331
|
-
|
|
1332
|
-
|
|
1333
|
-
|
|
1334
|
-
|
|
1335
|
-
|
|
1336
|
-
|
|
1337
|
-
|
|
1338
|
-
|
|
1339
|
-
|
|
1340
|
-
|
|
1341
|
-
|
|
1342
|
-
|
|
1343
|
-
|
|
1344
|
-
|
|
1345
|
-
|
|
1346
|
-
|
|
1347
|
-
|
|
1348
|
-
|
|
1349
|
-
|
|
1350
|
-
|
|
1351
|
-
|
|
1352
|
-
|
|
1353
|
-
|
|
1354
|
-
|
|
1355
|
-
|
|
1356
|
-
|
|
1667
|
+
// src/ContentResource/HTMLBodyCreator/create-html-body.tsx
|
|
1668
|
+
import {
|
|
1669
|
+
InputContainer as InputContainer7,
|
|
1670
|
+
InputLabel as InputLabel7,
|
|
1671
|
+
RichTextLanguageField
|
|
1672
|
+
} from "@manifest-editor/editors";
|
|
1673
|
+
import { useConfig } from "@manifest-editor/shell";
|
|
1674
|
+
import { useState as useState6 } from "react";
|
|
1675
|
+
import { jsx as jsx25, jsxs as jsxs13 } from "react/jsx-runtime";
|
|
1676
|
+
async function createHtmlBody(data, ctx) {
|
|
1677
|
+
return ctx.embed({
|
|
1678
|
+
id: ctx.generateId(`html/${data.language}`),
|
|
1679
|
+
language: data.language,
|
|
1680
|
+
type: "TextualBody",
|
|
1681
|
+
format: "text/html",
|
|
1682
|
+
value: data.body || ""
|
|
1683
|
+
});
|
|
1684
|
+
}
|
|
1685
|
+
function CreateHTMLBodyForm(props) {
|
|
1686
|
+
const { i18n } = useConfig();
|
|
1687
|
+
const [body, setBodyValue] = useState6("<p></p>");
|
|
1688
|
+
const [language, setLang] = useState6(i18n.defaultLanguage);
|
|
1689
|
+
const onSubmit = () => {
|
|
1690
|
+
props.runCreate({
|
|
1691
|
+
language,
|
|
1692
|
+
body
|
|
1693
|
+
});
|
|
1694
|
+
};
|
|
1695
|
+
return /* @__PURE__ */ jsxs13(PaddedSidebarContainer, { children: [
|
|
1696
|
+
/* @__PURE__ */ jsxs13(InputContainer7, { children: [
|
|
1697
|
+
/* @__PURE__ */ jsx25(InputLabel7, { children: "HTML Body" }),
|
|
1698
|
+
/* @__PURE__ */ jsx25(
|
|
1699
|
+
RichTextLanguageField,
|
|
1700
|
+
{
|
|
1701
|
+
value: body,
|
|
1702
|
+
language,
|
|
1703
|
+
onUpdateLanguage: (lng) => setLang(lng),
|
|
1704
|
+
languages: i18n.availableLanguages,
|
|
1705
|
+
onUpdate: (e) => setBodyValue(e)
|
|
1706
|
+
}
|
|
1707
|
+
)
|
|
1708
|
+
] }),
|
|
1709
|
+
/* @__PURE__ */ jsx25(Button, { onClick: () => onSubmit(), children: "Create" })
|
|
1710
|
+
] });
|
|
1711
|
+
}
|
|
1357
1712
|
|
|
1358
|
-
|
|
1359
|
-
|
|
1713
|
+
// src/ContentResource/HTMLBodyCreator/index.tsx
|
|
1714
|
+
import { jsx as jsx26 } from "react/jsx-runtime";
|
|
1715
|
+
var htmlBodyCreator = {
|
|
1716
|
+
id: "@manifest-editor/html-body-creator",
|
|
1717
|
+
create: createHtmlBody,
|
|
1718
|
+
label: "HTML Body",
|
|
1719
|
+
summary: "Add HTML annotation body",
|
|
1720
|
+
icon: /* @__PURE__ */ jsx26(TextFormatIcon, {}),
|
|
1721
|
+
render(ctx) {
|
|
1722
|
+
return /* @__PURE__ */ jsx26(CreateHTMLBodyForm, { ...ctx });
|
|
1723
|
+
},
|
|
1724
|
+
resourceType: "ContentResource",
|
|
1725
|
+
resourceFields: ["id", "language", "type", "format", "value"],
|
|
1726
|
+
supports: {
|
|
1727
|
+
parentTypes: ["Annotation"],
|
|
1728
|
+
parentFields: ["body"]
|
|
1729
|
+
},
|
|
1730
|
+
staticFields: {
|
|
1731
|
+
type: "TextualBody",
|
|
1732
|
+
format: "text/html"
|
|
1360
1733
|
}
|
|
1361
|
-
|
|
1362
|
-
var TimeDisplay = styled4.div`
|
|
1363
|
-
margin: 0 1em;
|
|
1364
|
-
font-size: 0.85em;
|
|
1365
|
-
color: #000;
|
|
1366
|
-
`;
|
|
1367
|
-
var ProgressContainer = styled4.div`
|
|
1368
|
-
flex: 1 1 0px;
|
|
1369
|
-
height: 6px;
|
|
1370
|
-
display: flex;
|
|
1371
|
-
position: relative;
|
|
1372
|
-
padding: 15px 0;
|
|
1373
|
-
`;
|
|
1374
|
-
var ProgressCurrent = styled4.div`
|
|
1375
|
-
background: #d85680;
|
|
1376
|
-
height: 6px;
|
|
1377
|
-
pointer-events: none;
|
|
1378
|
-
position: absolute;
|
|
1379
|
-
top: 13px;
|
|
1380
|
-
left: 0;
|
|
1381
|
-
border-radius: 3px;
|
|
1382
|
-
transition: width 200ms;
|
|
1383
|
-
`;
|
|
1384
|
-
var ProgressBackground = styled4.div`
|
|
1385
|
-
position: absolute;
|
|
1386
|
-
top: 13px;
|
|
1387
|
-
left: 0;
|
|
1388
|
-
height: 6px;
|
|
1389
|
-
border-radius: 3px;
|
|
1390
|
-
width: 100%;
|
|
1391
|
-
pointer-events: none;
|
|
1392
|
-
background: #fff;
|
|
1393
|
-
`;
|
|
1394
|
-
var SoundButton = styled4(BaseButton)`
|
|
1395
|
-
width: 2em;
|
|
1396
|
-
height: 2em;
|
|
1397
|
-
overflow: hidden;
|
|
1398
|
-
font-size: 1.1em;
|
|
1399
|
-
background: transparent;
|
|
1400
|
-
border-radius: 3px;
|
|
1401
|
-
padding: 0;
|
|
1402
|
-
margin: 0;
|
|
1403
|
-
`;
|
|
1404
|
-
var SoundContainer = styled4.div`
|
|
1405
|
-
display: flex;
|
|
1406
|
-
align-items: center;
|
|
1407
|
-
`;
|
|
1408
|
-
var VolumeContainer = styled4.div`
|
|
1409
|
-
width: 0;
|
|
1410
|
-
overflow: hidden;
|
|
1411
|
-
transition: width 500ms;
|
|
1412
|
-
color: #4a473f; // Not in colours
|
|
1734
|
+
};
|
|
1413
1735
|
|
|
1414
|
-
|
|
1415
|
-
|
|
1416
|
-
`}
|
|
1417
|
-
`;
|
|
1418
|
-
var VolumeSlider = styled4.input.attrs({ type: "range" })`
|
|
1419
|
-
width: 120px;
|
|
1420
|
-
margin: 0 15px;
|
|
1421
|
-
`;
|
|
1736
|
+
// src/ContentResource/IIIFBrowserCreator/index.tsx
|
|
1737
|
+
import { IIIFBrowserIcon } from "@manifest-editor/components";
|
|
1422
1738
|
|
|
1423
|
-
//
|
|
1424
|
-
import {
|
|
1425
|
-
|
|
1426
|
-
|
|
1427
|
-
|
|
1428
|
-
|
|
1429
|
-
|
|
1430
|
-
|
|
1431
|
-
|
|
1432
|
-
|
|
1433
|
-
|
|
1434
|
-
|
|
1435
|
-
dur: "1s",
|
|
1436
|
-
repeatCount: "indefinite"
|
|
1437
|
-
}
|
|
1438
|
-
) })
|
|
1439
|
-
] }) });
|
|
1739
|
+
// src/ContentResource/IIIFBrowserCreator/iiif-browser-creator.tsx
|
|
1740
|
+
import {
|
|
1741
|
+
Vault,
|
|
1742
|
+
normaliseContentState,
|
|
1743
|
+
parseContentState
|
|
1744
|
+
} from "@iiif/helpers";
|
|
1745
|
+
import { getImageServices } from "@iiif/parser/image-3";
|
|
1746
|
+
import { lazy } from "react";
|
|
1747
|
+
function croppedRegion(imageServiceId, region, size) {
|
|
1748
|
+
return `${imageServiceId}/${Math.floor(region.x)},${Math.floor(region.y)},${Math.floor(region.width)},${Math.floor(
|
|
1749
|
+
region.height
|
|
1750
|
+
)}/${size}/0/default.jpg`;
|
|
1440
1751
|
}
|
|
1441
|
-
|
|
1442
|
-
|
|
1443
|
-
|
|
1444
|
-
|
|
1445
|
-
|
|
1446
|
-
|
|
1447
|
-
|
|
1448
|
-
|
|
1449
|
-
|
|
1450
|
-
|
|
1451
|
-
|
|
1452
|
-
|
|
1453
|
-
|
|
1454
|
-
|
|
1455
|
-
|
|
1456
|
-
|
|
1457
|
-
|
|
1458
|
-
|
|
1459
|
-
|
|
1460
|
-
|
|
1461
|
-
|
|
1462
|
-
|
|
1463
|
-
|
|
1464
|
-
|
|
1465
|
-
|
|
1466
|
-
|
|
1467
|
-
|
|
1468
|
-
|
|
1469
|
-
if ($el.error && props.onError) {
|
|
1470
|
-
props.onError($el.error?.message || "Unknown error");
|
|
1471
|
-
return;
|
|
1752
|
+
async function createFromIIIFBrowserOutput(data, ctx) {
|
|
1753
|
+
const targetType = ctx.options.targetType;
|
|
1754
|
+
if (Array.isArray(data.output)) {
|
|
1755
|
+
throw new Error("Multiple items not yet supported");
|
|
1756
|
+
}
|
|
1757
|
+
const contentState = normaliseContentState(
|
|
1758
|
+
typeof data.output === "string" ? parseContentState(data.output) : data.output
|
|
1759
|
+
);
|
|
1760
|
+
if (!contentState.target || contentState.target.length === 0) {
|
|
1761
|
+
throw new Error("No target found in content state");
|
|
1762
|
+
}
|
|
1763
|
+
const target = contentState.target[0];
|
|
1764
|
+
const type = target.source.type;
|
|
1765
|
+
const previewVault = new Vault();
|
|
1766
|
+
if (targetType === "Canvas" || targetType === "Annotation" || targetType === "ContentResource") {
|
|
1767
|
+
if (type === "Canvas") {
|
|
1768
|
+
const canvasId = target.source.id;
|
|
1769
|
+
const manifestId = target.source.partOf?.find(
|
|
1770
|
+
(t) => t.type === "Manifest"
|
|
1771
|
+
);
|
|
1772
|
+
invariant(manifestId, "Could not load external resource without partOf");
|
|
1773
|
+
const manifest = await previewVault.loadManifest(manifestId);
|
|
1774
|
+
invariant(manifest, "Manifest not found");
|
|
1775
|
+
const canvasRef = manifest.items.find((item) => item.id === canvasId);
|
|
1776
|
+
invariant(canvasRef, "Canvas not found");
|
|
1777
|
+
const canvas = previewVault.get(canvasRef);
|
|
1778
|
+
if (targetType === "Canvas" && target.selector?.type !== "BoxSelector") {
|
|
1779
|
+
return ctx.embed(previewVault.toPresentation3(canvas));
|
|
1472
1780
|
}
|
|
1473
|
-
const
|
|
1474
|
-
|
|
1475
|
-
|
|
1476
|
-
|
|
1477
|
-
|
|
1478
|
-
|
|
1479
|
-
|
|
1480
|
-
|
|
1481
|
-
|
|
1482
|
-
|
|
1483
|
-
|
|
1781
|
+
const annotationPage = previewVault.get(canvas.items[0]);
|
|
1782
|
+
const annotation = previewVault.get(annotationPage.items[0]);
|
|
1783
|
+
if (targetType === "Annotation" || targetType === "Canvas" || targetType === "ContentResource") {
|
|
1784
|
+
const fullAnnotation = previewVault.toPresentation3(annotation);
|
|
1785
|
+
fullAnnotation.id = ctx.generateId("Annotation");
|
|
1786
|
+
let service = null;
|
|
1787
|
+
const dimensions = { width: 0, height: 0 };
|
|
1788
|
+
if (fullAnnotation?.body?.service) {
|
|
1789
|
+
const width = fullAnnotation?.body.width;
|
|
1790
|
+
const height = fullAnnotation?.body.height;
|
|
1791
|
+
service = getImageServices(fullAnnotation?.body)[0];
|
|
1792
|
+
if (service && (!service.width || !service.height)) {
|
|
1793
|
+
service.width = width;
|
|
1794
|
+
service.height = height;
|
|
1795
|
+
}
|
|
1796
|
+
dimensions.width = width;
|
|
1797
|
+
dimensions.height = height;
|
|
1798
|
+
if (data.trackSize) {
|
|
1799
|
+
data.trackSize(dimensions);
|
|
1800
|
+
}
|
|
1484
1801
|
}
|
|
1485
|
-
|
|
1486
|
-
|
|
1487
|
-
|
|
1488
|
-
|
|
1489
|
-
|
|
1490
|
-
|
|
1491
|
-
|
|
1492
|
-
|
|
1493
|
-
|
|
1494
|
-
|
|
1495
|
-
|
|
1496
|
-
|
|
1497
|
-
|
|
1498
|
-
|
|
1499
|
-
|
|
1500
|
-
|
|
1501
|
-
|
|
1502
|
-
|
|
1503
|
-
|
|
1802
|
+
if (target.selector && target.selector.type === "BoxSelector") {
|
|
1803
|
+
const selector = {
|
|
1804
|
+
"@context": "http://iiif.io/api/annex/openannotation/context.json",
|
|
1805
|
+
type: "iiif:ImageApiSelector",
|
|
1806
|
+
region: [
|
|
1807
|
+
~~target.selector.spatial.x,
|
|
1808
|
+
~~target.selector.spatial.y,
|
|
1809
|
+
~~target.selector.spatial.width,
|
|
1810
|
+
~~target.selector.spatial.height
|
|
1811
|
+
].join(",")
|
|
1812
|
+
};
|
|
1813
|
+
const newBody = { ...fullAnnotation.body };
|
|
1814
|
+
let thumbnailId = "";
|
|
1815
|
+
if (service) {
|
|
1816
|
+
const id = service.id || service["@id"] || "";
|
|
1817
|
+
if (id) {
|
|
1818
|
+
newBody.id = croppedRegion(id, target.selector.spatial, "max");
|
|
1819
|
+
thumbnailId = croppedRegion(id, target.selector.spatial, "512,");
|
|
1820
|
+
}
|
|
1504
1821
|
}
|
|
1505
|
-
|
|
1506
|
-
|
|
1507
|
-
|
|
1508
|
-
|
|
1509
|
-
|
|
1510
|
-
|
|
1511
|
-
|
|
1512
|
-
|
|
1513
|
-
|
|
1514
|
-
|
|
1515
|
-
|
|
1516
|
-
setDurationPercent(percent);
|
|
1517
|
-
},
|
|
1518
|
-
children: [
|
|
1519
|
-
/* @__PURE__ */ jsx29(ProgressBackground, {}),
|
|
1520
|
-
duration ? /* @__PURE__ */ jsx29(ProgressCurrent, { ref: progress }) : null
|
|
1521
|
-
]
|
|
1522
|
-
}
|
|
1523
|
-
),
|
|
1524
|
-
/* @__PURE__ */ jsx29(TimeDisplay, { children: formatTime(duration) }),
|
|
1525
|
-
/* @__PURE__ */ jsxs13(SoundContainer, { onMouseEnter: () => setIsVolumeOpen(true), onMouseLeave: () => setIsVolumeOpen(false), children: [
|
|
1526
|
-
/* @__PURE__ */ jsx29(VolumeContainer, { $isOpen: isVolumeOpen, children: /* @__PURE__ */ jsxs13("span", { children: [
|
|
1527
|
-
/* @__PURE__ */ jsx29(VisuallyHiddenLabel, { htmlFor: "audio-slider", children: "Change volume" }),
|
|
1528
|
-
/* @__PURE__ */ jsx29(
|
|
1529
|
-
VolumeSlider,
|
|
1530
|
-
{
|
|
1531
|
-
id: "audio-slider",
|
|
1532
|
-
role: "slider",
|
|
1533
|
-
disabled: isMuted,
|
|
1534
|
-
min: "0",
|
|
1535
|
-
max: "100",
|
|
1536
|
-
value: volume,
|
|
1537
|
-
onChange: (e) => setVolume(Number(e.currentTarget.value))
|
|
1822
|
+
fullAnnotation.body = {
|
|
1823
|
+
id: ctx.generateId("SpecificResource", annotation),
|
|
1824
|
+
type: "SpecificResource",
|
|
1825
|
+
source: newBody,
|
|
1826
|
+
selector
|
|
1827
|
+
};
|
|
1828
|
+
if (data.trackSize) {
|
|
1829
|
+
data.trackSize({
|
|
1830
|
+
width: ~~target.selector.spatial.width,
|
|
1831
|
+
height: ~~target.selector.spatial.height
|
|
1832
|
+
});
|
|
1538
1833
|
}
|
|
1539
|
-
|
|
1540
|
-
|
|
1541
|
-
|
|
1542
|
-
|
|
1543
|
-
|
|
1834
|
+
if (targetType === "ContentResource") {
|
|
1835
|
+
return fullAnnotation.body;
|
|
1836
|
+
}
|
|
1837
|
+
if (targetType === "Canvas") {
|
|
1838
|
+
const canvasId2 = ctx.generateId("Canvas", annotation);
|
|
1839
|
+
fullAnnotation.target = canvasId2;
|
|
1840
|
+
const pageId = ctx.generateId("Page", annotation);
|
|
1841
|
+
const annotationPage2 = ctx.embed({
|
|
1842
|
+
id: pageId,
|
|
1843
|
+
type: "AnnotationPage",
|
|
1844
|
+
items: [fullAnnotation]
|
|
1845
|
+
});
|
|
1846
|
+
return ctx.embed({
|
|
1847
|
+
id: canvasId2,
|
|
1848
|
+
type: "Canvas",
|
|
1849
|
+
width: ~~target.selector.spatial.width,
|
|
1850
|
+
height: ~~target.selector.spatial.height,
|
|
1851
|
+
thumbnail: thumbnailId ? [
|
|
1852
|
+
ctx.embed({
|
|
1853
|
+
id: thumbnailId,
|
|
1854
|
+
type: "Image",
|
|
1855
|
+
format: "image/jpeg",
|
|
1856
|
+
width: 512,
|
|
1857
|
+
height: Math.round(
|
|
1858
|
+
target.selector.spatial.height / target.selector.spatial.width * 512
|
|
1859
|
+
)
|
|
1860
|
+
})
|
|
1861
|
+
] : void 0,
|
|
1862
|
+
items: [annotationPage2]
|
|
1863
|
+
});
|
|
1864
|
+
}
|
|
1865
|
+
return ctx.embed({
|
|
1866
|
+
...fullAnnotation,
|
|
1867
|
+
target: ctx.getTarget()
|
|
1868
|
+
});
|
|
1869
|
+
}
|
|
1870
|
+
return ctx.embed({
|
|
1871
|
+
...previewVault.toPresentation3(annotation),
|
|
1872
|
+
target: ctx.getTarget()
|
|
1873
|
+
});
|
|
1874
|
+
}
|
|
1875
|
+
}
|
|
1876
|
+
}
|
|
1877
|
+
throw new Error("Not yet supported.");
|
|
1544
1878
|
}
|
|
1879
|
+
var IIIFBrowserCreatorForm = lazy(
|
|
1880
|
+
() => import("./iiif-browser-form.lazy-HZ3M2DXT.js")
|
|
1881
|
+
);
|
|
1545
1882
|
|
|
1546
|
-
// src/
|
|
1547
|
-
import {
|
|
1548
|
-
|
|
1549
|
-
|
|
1883
|
+
// src/ContentResource/IIIFBrowserCreator/index.tsx
|
|
1884
|
+
import { jsx as jsx27 } from "react/jsx-runtime";
|
|
1885
|
+
var iiifBrowserCreator = {
|
|
1886
|
+
id: "@manifest-editor/iiif-browser-creator",
|
|
1887
|
+
create: createFromIIIFBrowserOutput,
|
|
1888
|
+
label: "IIIF Browser",
|
|
1889
|
+
summary: "Browse IIIF Resources",
|
|
1890
|
+
icon: /* @__PURE__ */ jsx27(IIIFBrowserIcon, {}),
|
|
1891
|
+
render(ctx) {
|
|
1892
|
+
return /* @__PURE__ */ jsx27(IIIFBrowserCreatorForm, { ...ctx });
|
|
1893
|
+
},
|
|
1894
|
+
hiddenModal: true,
|
|
1895
|
+
tags: ["image", "image-service"],
|
|
1896
|
+
resourceType: "ContentResource",
|
|
1897
|
+
resourceFields: ["id", "language", "type", "format", "value"],
|
|
1898
|
+
additionalTypes: ["Annotation", "Canvas"],
|
|
1899
|
+
supports: {
|
|
1900
|
+
parentTypes: ["Annotation", "Manifest", "AnnotationPage"],
|
|
1901
|
+
parentFieldMap: {
|
|
1902
|
+
Annotation: ["body"],
|
|
1903
|
+
Manifest: ["items"],
|
|
1904
|
+
AnnotationPage: ["items"]
|
|
1905
|
+
}
|
|
1906
|
+
},
|
|
1907
|
+
sideEffects: [
|
|
1908
|
+
resizeToFitService,
|
|
1909
|
+
resizeResourceToEmptyCanvas,
|
|
1910
|
+
repositionMultipleImages
|
|
1911
|
+
],
|
|
1912
|
+
staticFields: {}
|
|
1913
|
+
};
|
|
1914
|
+
|
|
1915
|
+
// src/ContentResource/ImageServiceCreator/index.tsx
|
|
1916
|
+
import { jsx as jsx28 } from "react/jsx-runtime";
|
|
1917
|
+
var imageServiceCreator = {
|
|
1918
|
+
id: "@manifest-editor/image-service-creator",
|
|
1919
|
+
create: createImageServer,
|
|
1920
|
+
label: "Image Service",
|
|
1921
|
+
summary: "Add an image from Image Service",
|
|
1922
|
+
icon: /* @__PURE__ */ jsx28(TextFormatIcon, {}),
|
|
1923
|
+
render(ctx) {
|
|
1924
|
+
return /* @__PURE__ */ jsx28(CreateImageServerForm, { ...ctx });
|
|
1925
|
+
},
|
|
1926
|
+
resourceType: "ContentResource",
|
|
1927
|
+
resourceFields: ["id", "type", "height", "width", "format", "service"],
|
|
1928
|
+
supports: {
|
|
1929
|
+
parentFields: ["logo", "body", "thumbnail"]
|
|
1930
|
+
}
|
|
1931
|
+
};
|
|
1932
|
+
|
|
1933
|
+
// src/ContentResource/ImageUrlCreator/index.tsx
|
|
1934
|
+
import { AddImageIcon as AddImageIcon3 } from "@manifest-editor/components";
|
|
1935
|
+
import { jsx as jsx29 } from "react/jsx-runtime";
|
|
1936
|
+
var imageUrlCreator = {
|
|
1937
|
+
id: "@manifest-editor/image-url-creator",
|
|
1938
|
+
create: createImageUrl,
|
|
1939
|
+
label: "Image",
|
|
1940
|
+
summary: "Image from a URL",
|
|
1941
|
+
icon: /* @__PURE__ */ jsx29(AddImageIcon3, {}),
|
|
1942
|
+
render(ctx) {
|
|
1943
|
+
return /* @__PURE__ */ jsx29(CreateImageUrlForm, { ...ctx });
|
|
1944
|
+
},
|
|
1945
|
+
resourceType: "ContentResource",
|
|
1946
|
+
resourceFields: ["format"],
|
|
1947
|
+
supports: {
|
|
1948
|
+
parentFields: ["logo", "body", "thumbnail"]
|
|
1949
|
+
},
|
|
1950
|
+
staticFields: {
|
|
1951
|
+
type: "Image"
|
|
1952
|
+
}
|
|
1953
|
+
};
|
|
1954
|
+
|
|
1955
|
+
// src/ContentResource/PlaintextCreator/create-plaintext.tsx
|
|
1956
|
+
import {
|
|
1957
|
+
LanguageFieldEditor as LanguageFieldEditor5,
|
|
1958
|
+
InputContainer as InputContainer8,
|
|
1959
|
+
InputLabel as InputLabel8,
|
|
1960
|
+
Input as Input6
|
|
1961
|
+
} from "@manifest-editor/editors";
|
|
1962
|
+
import { useState as useState7 } from "react";
|
|
1550
1963
|
import { jsx as jsx30, jsxs as jsxs14 } from "react/jsx-runtime";
|
|
1551
|
-
async function
|
|
1552
|
-
|
|
1553
|
-
id: ctx.generateId("annotation"),
|
|
1554
|
-
type: "Annotation"
|
|
1555
|
-
};
|
|
1556
|
-
const targetType = ctx.options.targetType;
|
|
1557
|
-
const body = await ctx.embed({
|
|
1964
|
+
async function createPlaintext(data, ctx) {
|
|
1965
|
+
return ctx.embed({
|
|
1558
1966
|
id: data.url,
|
|
1559
|
-
type: "
|
|
1560
|
-
|
|
1561
|
-
|
|
1967
|
+
type: "Text",
|
|
1968
|
+
label: data.label,
|
|
1969
|
+
format: "text/plain"
|
|
1562
1970
|
});
|
|
1563
|
-
if (targetType === "Annotation") {
|
|
1564
|
-
return ctx.embed({
|
|
1565
|
-
...annotation,
|
|
1566
|
-
label: getValue(data.label) && data.label,
|
|
1567
|
-
motivation: data.motivation || ctx.options.initialData?.motivation || "painting",
|
|
1568
|
-
body,
|
|
1569
|
-
target: ctx.getTarget()
|
|
1570
|
-
});
|
|
1571
|
-
}
|
|
1572
|
-
if (targetType === "Canvas") {
|
|
1573
|
-
const canvasId = ctx.generateId("canvas");
|
|
1574
|
-
const pageId = ctx.generateId("annotation-page", { id: canvasId, type: "Canvas" });
|
|
1575
|
-
const annotationResource = ctx.embed({
|
|
1576
|
-
...annotation,
|
|
1577
|
-
motivation: "painting",
|
|
1578
|
-
body,
|
|
1579
|
-
target: { type: "SpecificResource", source: { id: canvasId, type: "Canvas" } }
|
|
1580
|
-
});
|
|
1581
|
-
const page = ctx.embed({
|
|
1582
|
-
id: pageId,
|
|
1583
|
-
type: "AnnotationPage",
|
|
1584
|
-
items: [annotationResource]
|
|
1585
|
-
});
|
|
1586
|
-
return ctx.embed({
|
|
1587
|
-
id: canvasId,
|
|
1588
|
-
type: "Canvas",
|
|
1589
|
-
label: data.label || { en: ["Untitled HTML canvas"] },
|
|
1590
|
-
duration: data.duration || 0,
|
|
1591
|
-
items: [page]
|
|
1592
|
-
});
|
|
1593
|
-
}
|
|
1594
1971
|
}
|
|
1595
|
-
function
|
|
1596
|
-
const [
|
|
1597
|
-
|
|
1598
|
-
|
|
1599
|
-
const
|
|
1600
|
-
|
|
1601
|
-
|
|
1602
|
-
|
|
1603
|
-
|
|
1604
|
-
label
|
|
1605
|
-
});
|
|
1606
|
-
};
|
|
1607
|
-
useEffect2(() => {
|
|
1608
|
-
setError("");
|
|
1609
|
-
setDuration(0);
|
|
1610
|
-
if (url) {
|
|
1611
|
-
const labelFromUrl = url.split("/").pop()?.split(".").shift();
|
|
1612
|
-
setLabel({ en: [labelFromUrl || ""] });
|
|
1972
|
+
function CreatePlaintextForm(props) {
|
|
1973
|
+
const [label, setLabel] = useState7({
|
|
1974
|
+
en: ["View as text"]
|
|
1975
|
+
});
|
|
1976
|
+
const onSubmit = (e) => {
|
|
1977
|
+
e.preventDefault();
|
|
1978
|
+
const data = new FormData(e.target);
|
|
1979
|
+
const formData = Object.fromEntries(data.entries());
|
|
1980
|
+
if (formData.url) {
|
|
1981
|
+
props.runCreate({ url: formData.url, label });
|
|
1613
1982
|
}
|
|
1614
|
-
}
|
|
1615
|
-
return /* @__PURE__ */
|
|
1616
|
-
|
|
1617
|
-
|
|
1618
|
-
/* @__PURE__ */ jsx30(InputLabel8, { htmlFor: "audio-url", children: "URL" }),
|
|
1619
|
-
/* @__PURE__ */ jsx30(Input6, { type: "text", id: "audio-url", value: url, onChange: (e) => setUrl(e.target.value) })
|
|
1620
|
-
] }),
|
|
1621
|
-
url && !error ? /* @__PURE__ */ jsx30("div", { children: /* @__PURE__ */ jsx30(
|
|
1622
|
-
LanguageFieldEditor4,
|
|
1983
|
+
};
|
|
1984
|
+
return /* @__PURE__ */ jsx30(PaddedSidebarContainer, { children: /* @__PURE__ */ jsxs14("form", { onSubmit, children: [
|
|
1985
|
+
/* @__PURE__ */ jsx30(
|
|
1986
|
+
LanguageFieldEditor5,
|
|
1623
1987
|
{
|
|
1624
|
-
|
|
1625
|
-
focusId: "label_",
|
|
1988
|
+
focusId: "label",
|
|
1626
1989
|
label: "Label",
|
|
1627
1990
|
fields: label,
|
|
1628
1991
|
onSave: (e) => setLabel(e.toInternationalString())
|
|
1629
|
-
}
|
|
1630
|
-
|
|
1631
|
-
|
|
1632
|
-
|
|
1633
|
-
|
|
1634
|
-
|
|
1635
|
-
|
|
1636
|
-
|
|
1637
|
-
|
|
1638
|
-
|
|
1639
|
-
|
|
1640
|
-
|
|
1641
|
-
|
|
1642
|
-
|
|
1643
|
-
|
|
1644
|
-
|
|
1992
|
+
}
|
|
1993
|
+
),
|
|
1994
|
+
/* @__PURE__ */ jsxs14(InputContainer8, { $wide: true, children: [
|
|
1995
|
+
/* @__PURE__ */ jsx30(InputLabel8, { htmlFor: "id", children: "Link to plaintext" }),
|
|
1996
|
+
/* @__PURE__ */ jsx30(Input6, { id: "url", name: "url", defaultValue: "" })
|
|
1997
|
+
] }),
|
|
1998
|
+
/* @__PURE__ */ jsx30(Button, { type: "submit", children: "Create" })
|
|
1999
|
+
] }) });
|
|
2000
|
+
}
|
|
2001
|
+
|
|
2002
|
+
// src/ContentResource/PlaintextCreator/index.tsx
|
|
2003
|
+
import { jsx as jsx31 } from "react/jsx-runtime";
|
|
2004
|
+
var plaintextCreator = {
|
|
2005
|
+
id: "@manifest-editor/plaintext-creator",
|
|
2006
|
+
create: createPlaintext,
|
|
2007
|
+
label: "Plaintext",
|
|
2008
|
+
summary: "Add link to an plaintext",
|
|
2009
|
+
icon: /* @__PURE__ */ jsx31(TextFormatIcon, {}),
|
|
2010
|
+
render(ctx) {
|
|
2011
|
+
return /* @__PURE__ */ jsx31(CreatePlaintextForm, { ...ctx });
|
|
2012
|
+
},
|
|
2013
|
+
resourceType: "ContentResource",
|
|
2014
|
+
resourceFields: ["label", "format"],
|
|
2015
|
+
supports: {
|
|
2016
|
+
parentFields: ["seeAlso", "rendering", "homepage"]
|
|
2017
|
+
},
|
|
2018
|
+
staticFields: {
|
|
2019
|
+
format: "text/plain"
|
|
2020
|
+
}
|
|
2021
|
+
};
|
|
2022
|
+
|
|
2023
|
+
// ../ui/icons/LinkIcon.tsx
|
|
2024
|
+
import { jsx as jsx32, jsxs as jsxs15 } from "react/jsx-runtime";
|
|
2025
|
+
function LinkIcon() {
|
|
2026
|
+
return /* @__PURE__ */ jsxs15("svg", { xmlns: "http://www.w3.org/2000/svg", height: "24px", viewBox: "0 0 24 24", width: "24px", fill: "#000000", children: [
|
|
2027
|
+
/* @__PURE__ */ jsx32("path", { d: "M0 0h24v24H0z", fill: "none" }),
|
|
2028
|
+
/* @__PURE__ */ jsx32("path", { d: "M3.9 12c0-1.71 1.39-3.1 3.1-3.1h4V7H7c-2.76 0-5 2.24-5 5s2.24 5 5 5h4v-1.9H7c-1.71 0-3.1-1.39-3.1-3.1zM8 13h8v-2H8v2zm9-6h-4v1.9h4c1.71 0 3.1 1.39 3.1 3.1s-1.39 3.1-3.1 3.1h-4V17h4c2.76 0 5-2.24 5-5s-2.24-5-5-5z" })
|
|
1645
2029
|
] });
|
|
1646
2030
|
}
|
|
1647
2031
|
|
|
1648
|
-
// src/
|
|
1649
|
-
import {
|
|
1650
|
-
|
|
1651
|
-
|
|
1652
|
-
|
|
1653
|
-
|
|
1654
|
-
|
|
1655
|
-
|
|
1656
|
-
|
|
2032
|
+
// src/ContentResource/WebPageCreator/create-web-page.tsx
|
|
2033
|
+
import {
|
|
2034
|
+
LanguageFieldEditor as LanguageFieldEditor6,
|
|
2035
|
+
InputContainer as InputContainer9,
|
|
2036
|
+
InputLabel as InputLabel9,
|
|
2037
|
+
Input as Input7
|
|
2038
|
+
} from "@manifest-editor/editors";
|
|
2039
|
+
import { useState as useState8 } from "react";
|
|
2040
|
+
import { jsx as jsx33, jsxs as jsxs16 } from "react/jsx-runtime";
|
|
2041
|
+
async function createWebPage(data, ctx) {
|
|
2042
|
+
return ctx.embed({
|
|
2043
|
+
id: data.url,
|
|
2044
|
+
type: "Text",
|
|
2045
|
+
label: data.label,
|
|
2046
|
+
format: "text/html"
|
|
2047
|
+
});
|
|
2048
|
+
}
|
|
2049
|
+
function CreateWebPageForm(props) {
|
|
2050
|
+
const [label, setLabel] = useState8({ en: [""] });
|
|
2051
|
+
const onSubmit = (e) => {
|
|
2052
|
+
e.preventDefault();
|
|
2053
|
+
const data = new FormData(e.target);
|
|
2054
|
+
const formData = Object.fromEntries(data.entries());
|
|
2055
|
+
if (formData.url) {
|
|
2056
|
+
props.runCreate({ url: formData.url, label });
|
|
2057
|
+
}
|
|
2058
|
+
};
|
|
2059
|
+
return /* @__PURE__ */ jsx33(PaddedSidebarContainer, { children: /* @__PURE__ */ jsxs16("form", { onSubmit, children: [
|
|
2060
|
+
/* @__PURE__ */ jsx33(
|
|
2061
|
+
LanguageFieldEditor6,
|
|
2062
|
+
{
|
|
2063
|
+
focusId: "label",
|
|
2064
|
+
label: "Label",
|
|
2065
|
+
fields: label,
|
|
2066
|
+
onSave: (e) => setLabel(e.toInternationalString())
|
|
2067
|
+
}
|
|
2068
|
+
),
|
|
2069
|
+
/* @__PURE__ */ jsxs16(InputContainer9, { $wide: true, children: [
|
|
2070
|
+
/* @__PURE__ */ jsx33(InputLabel9, { htmlFor: "id", children: "Link" }),
|
|
2071
|
+
/* @__PURE__ */ jsx33(Input7, { id: "url", name: "url", defaultValue: "" })
|
|
2072
|
+
] }),
|
|
2073
|
+
/* @__PURE__ */ jsx33(Button, { type: "submit", children: "Create link" })
|
|
2074
|
+
] }) });
|
|
2075
|
+
}
|
|
2076
|
+
|
|
2077
|
+
// src/ContentResource/WebPageCreator/index.tsx
|
|
2078
|
+
import { jsx as jsx34 } from "react/jsx-runtime";
|
|
2079
|
+
var webPageCreator = {
|
|
2080
|
+
id: "@manifest-editor/web-page-creator",
|
|
2081
|
+
create: createWebPage,
|
|
2082
|
+
label: "Web page",
|
|
2083
|
+
summary: "Add link to an external web page",
|
|
2084
|
+
icon: /* @__PURE__ */ jsx34(LinkIcon, {}),
|
|
1657
2085
|
render(ctx) {
|
|
1658
|
-
return /* @__PURE__ */
|
|
2086
|
+
return /* @__PURE__ */ jsx34(CreateWebPageForm, { ...ctx });
|
|
1659
2087
|
},
|
|
1660
|
-
resourceType: "
|
|
1661
|
-
resourceFields: ["
|
|
1662
|
-
additionalTypes: ["Canvas"],
|
|
2088
|
+
resourceType: "ContentResource",
|
|
2089
|
+
resourceFields: ["label", "format"],
|
|
1663
2090
|
supports: {
|
|
1664
|
-
|
|
1665
|
-
parentTypes: ["AnnotationPage", "Manifest"],
|
|
1666
|
-
parentFields: ["items"]
|
|
1667
|
-
},
|
|
1668
|
-
staticFields: {
|
|
1669
|
-
type: "Annotation"
|
|
2091
|
+
parentFields: ["seeAlso", "rendering", "homepage"]
|
|
1670
2092
|
}
|
|
1671
2093
|
};
|
|
1672
2094
|
|
|
1673
|
-
// src/
|
|
1674
|
-
import {
|
|
1675
|
-
import { InputContainer as InputContainer9, InputLabel as InputLabel9, Input as Input7, LanguageFieldEditor as LanguageFieldEditor5, DimensionsTriplet } from "@manifest-editor/editors";
|
|
1676
|
-
import { useState as useState7, useEffect as useEffect3 } from "react";
|
|
2095
|
+
// src/ContentResource/YouTubeCreator/index.tsx
|
|
2096
|
+
import { YouTubeIcon } from "@manifest-editor/components";
|
|
1677
2097
|
|
|
1678
|
-
//
|
|
1679
|
-
import {
|
|
1680
|
-
import { jsx as
|
|
1681
|
-
|
|
1682
|
-
|
|
1683
|
-
|
|
1684
|
-
|
|
1685
|
-
onDuration,
|
|
1686
|
-
onDimensions
|
|
1687
|
-
}) {
|
|
1688
|
-
const [{ element, currentTime, progress }, state, actions] = useSimpleMediaPlayer({ duration });
|
|
1689
|
-
return /* @__PURE__ */ jsxs15(
|
|
1690
|
-
MediaPlayerProvider,
|
|
1691
|
-
{
|
|
1692
|
-
element,
|
|
1693
|
-
state,
|
|
1694
|
-
actions,
|
|
1695
|
-
currentTime,
|
|
1696
|
-
progress,
|
|
1697
|
-
children: [
|
|
1698
|
-
/* @__PURE__ */ jsx32(
|
|
1699
|
-
"div",
|
|
1700
|
-
{
|
|
1701
|
-
style: {
|
|
1702
|
-
maxHeight: 400,
|
|
1703
|
-
aspectRatio: `${media.width}/${media.height}`,
|
|
1704
|
-
position: "relative"
|
|
1705
|
-
},
|
|
1706
|
-
children: /* @__PURE__ */ jsx32(CanvasPanel2.VideoHTML, { element, media, playPause: actions.playPause })
|
|
1707
|
-
}
|
|
1708
|
-
),
|
|
1709
|
-
/* @__PURE__ */ jsx32(MediaControls, { onError, onDuration, onDimensions })
|
|
1710
|
-
]
|
|
1711
|
-
}
|
|
1712
|
-
);
|
|
2098
|
+
// src/ContentResource/YouTubeCreator/create-youtube-body.tsx
|
|
2099
|
+
import { Input as Input8, InputContainer as InputContainer10, InputLabel as InputLabel10 } from "@manifest-editor/editors";
|
|
2100
|
+
import { jsx as jsx35, jsxs as jsxs17 } from "react/jsx-runtime";
|
|
2101
|
+
var ytRegex = /^.*(?:(?:youtu\.be\/|v\/|vi\/|u\/\w\/|embed\/|shorts\/)|(?:(?:watch)?\?vi?=|&vi?=))([^#&?]*).*/;
|
|
2102
|
+
function getYouTubeId(url) {
|
|
2103
|
+
const id = (url || "").match(ytRegex);
|
|
2104
|
+
return id ? id[1] : null;
|
|
1713
2105
|
}
|
|
1714
|
-
|
|
1715
|
-
|
|
1716
|
-
|
|
1717
|
-
async function
|
|
1718
|
-
const
|
|
1719
|
-
|
|
1720
|
-
|
|
1721
|
-
};
|
|
1722
|
-
const targetType = ctx.options.targetType;
|
|
1723
|
-
const body = await ctx.embed({
|
|
1724
|
-
id: data.url,
|
|
2106
|
+
function validateYouTube(data) {
|
|
2107
|
+
return !!getYouTubeId(data.youtubeUrl);
|
|
2108
|
+
}
|
|
2109
|
+
async function createYoutubeBody(data, ctx) {
|
|
2110
|
+
const id = getYouTubeId(data.youtubeUrl);
|
|
2111
|
+
const body = ctx.embed({
|
|
2112
|
+
id: `https://www.youtube.com/watch?v=${id}`,
|
|
1725
2113
|
type: "Video",
|
|
1726
|
-
|
|
1727
|
-
|
|
1728
|
-
|
|
1729
|
-
|
|
2114
|
+
service: [
|
|
2115
|
+
{
|
|
2116
|
+
profile: "http://digirati.com/objectifier",
|
|
2117
|
+
params: {
|
|
2118
|
+
data: `https://www.youtube.com/embed/${id}`
|
|
2119
|
+
}
|
|
2120
|
+
},
|
|
2121
|
+
{
|
|
2122
|
+
id: `https://www.youtube.com/watch?v=${id}`,
|
|
2123
|
+
profile: "https://www.youtube.com"
|
|
2124
|
+
}
|
|
2125
|
+
]
|
|
1730
2126
|
});
|
|
1731
|
-
if (targetType === "
|
|
1732
|
-
return ctx.embed({
|
|
1733
|
-
...annotation,
|
|
1734
|
-
label: getValue2(data.label) && data.label,
|
|
1735
|
-
motivation: data.motivation || ctx.options.initialData?.motivation || "painting",
|
|
1736
|
-
body,
|
|
1737
|
-
target: ctx.getTarget()
|
|
1738
|
-
});
|
|
1739
|
-
}
|
|
1740
|
-
if (targetType === "Canvas") {
|
|
2127
|
+
if (ctx.options.targetType === "Canvas") {
|
|
1741
2128
|
const canvasId = ctx.generateId("canvas");
|
|
1742
|
-
const pageId = ctx.generateId("annotation-page", {
|
|
1743
|
-
|
|
1744
|
-
|
|
2129
|
+
const pageId = ctx.generateId("annotation-page", {
|
|
2130
|
+
id: canvasId,
|
|
2131
|
+
type: "Canvas"
|
|
2132
|
+
});
|
|
2133
|
+
const annotation = ctx.embed({
|
|
2134
|
+
id: ctx.generateId("annotation", { id: pageId, type: "AnnotationPage" }),
|
|
2135
|
+
type: "Annotation",
|
|
1745
2136
|
motivation: "painting",
|
|
1746
|
-
body,
|
|
1747
|
-
target: {
|
|
2137
|
+
body: [body],
|
|
2138
|
+
target: {
|
|
2139
|
+
type: "SpecificResource",
|
|
2140
|
+
source: { id: canvasId, type: "Canvas" }
|
|
2141
|
+
}
|
|
1748
2142
|
});
|
|
1749
2143
|
const page = ctx.embed({
|
|
1750
2144
|
id: pageId,
|
|
1751
2145
|
type: "AnnotationPage",
|
|
1752
|
-
items: [
|
|
2146
|
+
items: [annotation]
|
|
1753
2147
|
});
|
|
1754
2148
|
return ctx.embed({
|
|
1755
2149
|
id: canvasId,
|
|
1756
2150
|
type: "Canvas",
|
|
1757
|
-
label: data.label || { en: ["Untitled
|
|
1758
|
-
|
|
1759
|
-
width: data.width,
|
|
1760
|
-
|
|
2151
|
+
label: data.label || { en: ["Untitled YouTube canvas"] },
|
|
2152
|
+
height: data.height || 1e3,
|
|
2153
|
+
width: data.width || 1e3,
|
|
2154
|
+
duration: data.duration || 1,
|
|
1761
2155
|
items: [page]
|
|
1762
2156
|
});
|
|
1763
2157
|
}
|
|
1764
|
-
|
|
1765
|
-
|
|
1766
|
-
|
|
1767
|
-
|
|
1768
|
-
|
|
1769
|
-
|
|
1770
|
-
|
|
1771
|
-
const [label, setLabel] = useState7({ en: [""] });
|
|
1772
|
-
const onSubmit = () => {
|
|
1773
|
-
props.runCreate({
|
|
1774
|
-
url,
|
|
1775
|
-
duration,
|
|
1776
|
-
label,
|
|
1777
|
-
width,
|
|
1778
|
-
height
|
|
2158
|
+
if (ctx.options.targetType === "Annotation") {
|
|
2159
|
+
return ctx.embed({
|
|
2160
|
+
id: ctx.generateId("annotation"),
|
|
2161
|
+
type: "Annotation",
|
|
2162
|
+
motivation: "painting",
|
|
2163
|
+
body: [body],
|
|
2164
|
+
target: ctx.getTarget()
|
|
1779
2165
|
});
|
|
1780
|
-
}
|
|
1781
|
-
|
|
1782
|
-
|
|
1783
|
-
|
|
1784
|
-
|
|
1785
|
-
|
|
1786
|
-
|
|
2166
|
+
}
|
|
2167
|
+
return body;
|
|
2168
|
+
}
|
|
2169
|
+
function YouTubeForm(props) {
|
|
2170
|
+
const onSubmit = (e) => {
|
|
2171
|
+
e.preventDefault();
|
|
2172
|
+
const data = new FormData(e.target);
|
|
2173
|
+
const formData = Object.fromEntries(data.entries());
|
|
2174
|
+
if (formData.youtubeUrl) {
|
|
2175
|
+
props.runCreate({ youtubeUrl: formData.youtubeUrl });
|
|
1787
2176
|
}
|
|
1788
|
-
}
|
|
1789
|
-
return /* @__PURE__ */
|
|
1790
|
-
|
|
1791
|
-
|
|
1792
|
-
/* @__PURE__ */
|
|
1793
|
-
/* @__PURE__ */ jsx33(Input7, { type: "text", id: "video-url", value: url, onChange: (e) => setUrl(e.target.value) })
|
|
2177
|
+
};
|
|
2178
|
+
return /* @__PURE__ */ jsx35(PaddedSidebarContainer, { children: /* @__PURE__ */ jsxs17("form", { onSubmit, children: [
|
|
2179
|
+
/* @__PURE__ */ jsxs17(InputContainer10, { $wide: true, children: [
|
|
2180
|
+
/* @__PURE__ */ jsx35(InputLabel10, { htmlFor: "id", children: "Link to YouTube" }),
|
|
2181
|
+
/* @__PURE__ */ jsx35(Input8, { id: "youtubeUrl", name: "youtubeUrl", defaultValue: "" })
|
|
1794
2182
|
] }),
|
|
1795
|
-
|
|
1796
|
-
|
|
1797
|
-
{
|
|
1798
|
-
containerId: "label",
|
|
1799
|
-
focusId: "label_",
|
|
1800
|
-
label: "Label",
|
|
1801
|
-
fields: label,
|
|
1802
|
-
onSave: (e) => setLabel(e.toInternationalString())
|
|
1803
|
-
},
|
|
1804
|
-
url + "__" + duration
|
|
1805
|
-
) }) : null,
|
|
1806
|
-
url && !error ? /* @__PURE__ */ jsx33(
|
|
1807
|
-
VideoPlayer,
|
|
1808
|
-
{
|
|
1809
|
-
duration,
|
|
1810
|
-
onDuration: (d) => setDuration(d),
|
|
1811
|
-
onError: (err) => setError(err),
|
|
1812
|
-
media: {
|
|
1813
|
-
url,
|
|
1814
|
-
duration,
|
|
1815
|
-
height,
|
|
1816
|
-
width,
|
|
1817
|
-
type: "Video"
|
|
1818
|
-
},
|
|
1819
|
-
onDimensions: (w, h) => {
|
|
1820
|
-
setWidth(w || 0);
|
|
1821
|
-
setHeight(h || 0);
|
|
1822
|
-
}
|
|
1823
|
-
}
|
|
1824
|
-
) : null,
|
|
1825
|
-
!error && (duration || width || height) ? /* @__PURE__ */ jsx33(InputContainer9, { $wide: true, children: /* @__PURE__ */ jsx33(
|
|
1826
|
-
DimensionsTriplet,
|
|
1827
|
-
{
|
|
1828
|
-
widthId: "width",
|
|
1829
|
-
width: width || 0,
|
|
1830
|
-
changeWidth: (v) => setWidth(v),
|
|
1831
|
-
heightId: "height",
|
|
1832
|
-
height: height || 0,
|
|
1833
|
-
changeHeight: (v) => setHeight(v),
|
|
1834
|
-
durationId: "duration",
|
|
1835
|
-
duration: duration || 0,
|
|
1836
|
-
changeDuration: (v) => setDuration(v)
|
|
1837
|
-
}
|
|
1838
|
-
) }) : null,
|
|
1839
|
-
url && !error && /* @__PURE__ */ jsx33(Button, { onClick: onSubmit, children: "Add video" })
|
|
1840
|
-
] });
|
|
2183
|
+
/* @__PURE__ */ jsx35(Button, { type: "submit", children: "Create" })
|
|
2184
|
+
] }) });
|
|
1841
2185
|
}
|
|
1842
2186
|
|
|
1843
|
-
// src/
|
|
1844
|
-
import {
|
|
1845
|
-
|
|
1846
|
-
|
|
1847
|
-
|
|
1848
|
-
|
|
1849
|
-
|
|
1850
|
-
|
|
1851
|
-
|
|
1852
|
-
|
|
1853
|
-
|
|
1854
|
-
},
|
|
1855
|
-
resourceType: "Annotation",
|
|
1856
|
-
resourceFields: ["id", "type", "motivation", "body", "target"],
|
|
1857
|
-
additionalTypes: ["Canvas"],
|
|
2187
|
+
// src/ContentResource/YouTubeCreator/index.tsx
|
|
2188
|
+
import { jsx as jsx36 } from "react/jsx-runtime";
|
|
2189
|
+
var youTubeBodyCreator = {
|
|
2190
|
+
id: "@manifest-editor/youtube",
|
|
2191
|
+
create: createYoutubeBody,
|
|
2192
|
+
label: "YouTube",
|
|
2193
|
+
summary: "Embed YouTube",
|
|
2194
|
+
icon: /* @__PURE__ */ jsx36(YouTubeIcon, {}),
|
|
2195
|
+
resourceType: "ContentResource",
|
|
2196
|
+
additionalTypes: ["Canvas", "Annotation"],
|
|
2197
|
+
resourceFields: ["id", "type", "service"],
|
|
2198
|
+
render: (ctx) => /* @__PURE__ */ jsx36(YouTubeForm, { ...ctx }),
|
|
1858
2199
|
supports: {
|
|
1859
|
-
|
|
1860
|
-
|
|
1861
|
-
|
|
2200
|
+
parentTypes: ["Annotation", "Manifest", "AnnotationPage"],
|
|
2201
|
+
parentFieldMap: {
|
|
2202
|
+
Annotation: ["body"],
|
|
2203
|
+
Manifest: ["items"],
|
|
2204
|
+
AnnotationPage: ["items"]
|
|
2205
|
+
}
|
|
1862
2206
|
},
|
|
1863
2207
|
staticFields: {
|
|
1864
|
-
type: "
|
|
2208
|
+
type: "Video"
|
|
1865
2209
|
}
|
|
1866
2210
|
};
|
|
1867
2211
|
|
|
2212
|
+
// src/Manifest/ManifestBrowserCreator/index.tsx
|
|
2213
|
+
import { IIIFBrowserIcon as IIIFBrowserIcon2 } from "@manifest-editor/components";
|
|
2214
|
+
|
|
1868
2215
|
// src/Manifest/ManifestBrowserCreator/manifest-browser-creator.tsx
|
|
1869
|
-
import {
|
|
2216
|
+
import {
|
|
2217
|
+
normaliseContentState as normaliseContentState2,
|
|
2218
|
+
parseContentState as parseContentState2
|
|
2219
|
+
} from "@iiif/helpers";
|
|
1870
2220
|
import { lazy as lazy2 } from "react";
|
|
1871
2221
|
async function createFromManifestBrowserOutput(data, ctx) {
|
|
1872
2222
|
const targetType = ctx.options.targetType;
|
|
@@ -1903,19 +2253,20 @@ async function createFromManifestBrowserOutput(data, ctx) {
|
|
|
1903
2253
|
}
|
|
1904
2254
|
throw new Error("Not yet supported.");
|
|
1905
2255
|
}
|
|
1906
|
-
var ManifestBrowserCreatorForm2 = lazy2(
|
|
2256
|
+
var ManifestBrowserCreatorForm2 = lazy2(
|
|
2257
|
+
() => import("./manifest-browser-form.lazy-MYI26AX4.js")
|
|
2258
|
+
);
|
|
1907
2259
|
|
|
1908
2260
|
// src/Manifest/ManifestBrowserCreator/index.tsx
|
|
1909
|
-
import {
|
|
1910
|
-
import { jsx as jsx35 } from "react/jsx-runtime";
|
|
2261
|
+
import { jsx as jsx37 } from "react/jsx-runtime";
|
|
1911
2262
|
var manifestBrowserCreator = {
|
|
1912
2263
|
id: "@manifest-editor/manifest-browser-creator",
|
|
1913
2264
|
create: createFromManifestBrowserOutput,
|
|
1914
2265
|
label: "IIIF Browser",
|
|
1915
2266
|
summary: "Browse IIIF Resources",
|
|
1916
|
-
icon: /* @__PURE__ */
|
|
2267
|
+
icon: /* @__PURE__ */ jsx37(IIIFBrowserIcon2, {}),
|
|
1917
2268
|
render(ctx) {
|
|
1918
|
-
return /* @__PURE__ */
|
|
2269
|
+
return /* @__PURE__ */ jsx37(ManifestBrowserCreatorForm, { ...ctx });
|
|
1919
2270
|
},
|
|
1920
2271
|
resourceType: "Manifest",
|
|
1921
2272
|
resourceFields: ["id", "label"],
|
|
@@ -1948,13 +2299,43 @@ var allCreators = [
|
|
|
1948
2299
|
webPageCreator,
|
|
1949
2300
|
emptyAnnotationPage,
|
|
1950
2301
|
noBodyAnnotation,
|
|
1951
|
-
internalCanvas
|
|
2302
|
+
internalCanvas,
|
|
2303
|
+
captionedImageAnnotation
|
|
1952
2304
|
];
|
|
1953
2305
|
export {
|
|
2306
|
+
CreateAudioAnnotationForm,
|
|
2307
|
+
CreateCaptionedImageAnnotation,
|
|
2308
|
+
CreateHTMLAnnotation,
|
|
2309
|
+
CreateHTMLBodyForm,
|
|
2310
|
+
CreateImageServerForm,
|
|
2311
|
+
CreateImageServiceAnnotationForm,
|
|
2312
|
+
CreateImageUrlAnnotationForm,
|
|
2313
|
+
CreateImageUrlForm,
|
|
2314
|
+
CreatePlaintextForm,
|
|
2315
|
+
CreateVideoAnnotationForm,
|
|
2316
|
+
CreateWebPageForm,
|
|
2317
|
+
IIIFBrowserCreatorForm,
|
|
2318
|
+
YouTubeForm,
|
|
1954
2319
|
allCreators,
|
|
1955
2320
|
audioAnnotation,
|
|
2321
|
+
captionedImageAnnotation,
|
|
2322
|
+
createAudioAnnotation,
|
|
2323
|
+
createCaptionedImageAnnotation,
|
|
2324
|
+
createFromIIIFBrowserOutput,
|
|
2325
|
+
createHtmlAnnotation,
|
|
2326
|
+
createHtmlBody,
|
|
2327
|
+
createImageServer,
|
|
2328
|
+
createImageServiceAnnotation,
|
|
2329
|
+
createImageUrl,
|
|
2330
|
+
createImageUrlAnnotation,
|
|
2331
|
+
createNoBodyAnnotation,
|
|
2332
|
+
createPlaintext,
|
|
2333
|
+
createVideoAnnotation,
|
|
2334
|
+
createWebPage,
|
|
2335
|
+
createYoutubeBody,
|
|
1956
2336
|
emptyAnnotationPage,
|
|
1957
2337
|
emptyCanvas,
|
|
2338
|
+
getYouTubeId,
|
|
1958
2339
|
htmlAnnotation,
|
|
1959
2340
|
htmlBodyCreator,
|
|
1960
2341
|
iiifBrowserCreator,
|
|
@@ -1966,6 +2347,7 @@ export {
|
|
|
1966
2347
|
manifestBrowserCreator,
|
|
1967
2348
|
noBodyAnnotation,
|
|
1968
2349
|
plaintextCreator,
|
|
2350
|
+
validateYouTube,
|
|
1969
2351
|
videoAnnotation,
|
|
1970
2352
|
webPageCreator,
|
|
1971
2353
|
youTubeBodyCreator
|