@openbrf/display 0.0.0-stage → 0.1.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.
Files changed (69) hide show
  1. package/LICENSE +661 -0
  2. package/LICENSE-EXCEPTION.md +28 -0
  3. package/README.md +126 -2
  4. package/dist/contract.d.ts +244 -0
  5. package/dist/contract.d.ts.map +1 -0
  6. package/dist/contract.js +54 -0
  7. package/dist/contract.js.map +1 -0
  8. package/dist/fetch-loop.d.ts +87 -0
  9. package/dist/fetch-loop.d.ts.map +1 -0
  10. package/dist/fetch-loop.js +351 -0
  11. package/dist/fetch-loop.js.map +1 -0
  12. package/dist/fit.d.ts +44 -0
  13. package/dist/fit.d.ts.map +1 -0
  14. package/dist/fit.js +257 -0
  15. package/dist/fit.js.map +1 -0
  16. package/dist/index.d.ts +23 -0
  17. package/dist/index.d.ts.map +1 -0
  18. package/dist/index.js +18 -0
  19. package/dist/index.js.map +1 -0
  20. package/dist/parse.d.ts +39 -0
  21. package/dist/parse.d.ts.map +1 -0
  22. package/dist/parse.js +494 -0
  23. package/dist/parse.js.map +1 -0
  24. package/dist/renderer.d.ts +85 -0
  25. package/dist/renderer.d.ts.map +1 -0
  26. package/dist/renderer.js +476 -0
  27. package/dist/renderer.js.map +1 -0
  28. package/dist/rotation.d.ts +129 -0
  29. package/dist/rotation.d.ts.map +1 -0
  30. package/dist/rotation.js +335 -0
  31. package/dist/rotation.js.map +1 -0
  32. package/dist/slides.d.ts +41 -0
  33. package/dist/slides.d.ts.map +1 -0
  34. package/dist/slides.js +341 -0
  35. package/dist/slides.js.map +1 -0
  36. package/dist/styles.d.ts +10 -0
  37. package/dist/styles.d.ts.map +1 -0
  38. package/dist/styles.js +107 -0
  39. package/dist/styles.js.map +1 -0
  40. package/dist/text.d.ts +16 -0
  41. package/dist/text.d.ts.map +1 -0
  42. package/dist/text.js +62 -0
  43. package/dist/text.js.map +1 -0
  44. package/dist/time.d.ts +39 -0
  45. package/dist/time.d.ts.map +1 -0
  46. package/dist/time.js +94 -0
  47. package/dist/time.js.map +1 -0
  48. package/dist/translate.d.ts +18 -0
  49. package/dist/translate.d.ts.map +1 -0
  50. package/dist/translate.js +35 -0
  51. package/dist/translate.js.map +1 -0
  52. package/dist/words.d.ts +41 -0
  53. package/dist/words.d.ts.map +1 -0
  54. package/dist/words.js +73 -0
  55. package/dist/words.js.map +1 -0
  56. package/package.json +58 -3
  57. package/src/contract.ts +279 -0
  58. package/src/fetch-loop.ts +472 -0
  59. package/src/fit.ts +348 -0
  60. package/src/index.ts +77 -0
  61. package/src/parse.ts +605 -0
  62. package/src/renderer.ts +708 -0
  63. package/src/rotation.ts +515 -0
  64. package/src/slides.ts +595 -0
  65. package/src/styles.ts +113 -0
  66. package/src/text.ts +65 -0
  67. package/src/time.ts +147 -0
  68. package/src/translate.ts +56 -0
  69. package/src/words.ts +91 -0
@@ -0,0 +1,85 @@
1
+ /**
2
+ * The renderer: mounts on an element and shows a screen content document.
3
+ *
4
+ * It takes a document and nothing else, and fetches nothing. A picture comes
5
+ * from a function its caller hands it, so that a device token never has to be
6
+ * in a picture's URL; the caller fetches the bytes with the token in a header
7
+ * and hands back an object URL.
8
+ */
9
+ import type { PictureRef, ScreenContent, ScreenLocale } from "./contract.ts";
10
+ /** What the renderer is handed besides the element. */
11
+ export interface RendererOptions {
12
+ /**
13
+ * Hands back a URL the renderer may put in an `<img>`, or null when the
14
+ * picture cannot be had. Called once for each `mediaFileId` and `version` a
15
+ * document refers to, and the result reused while documents go on referring
16
+ * to it; a null or a failure is asked again on a document shown five or more
17
+ * minutes later. The renderer never fetches.
18
+ */
19
+ picture?: (ref: PictureRef) => Promise<string | null>;
20
+ /**
21
+ * Told when a URL `picture` handed back is no longer used: the documents
22
+ * stopped referring to it, the browser could not show it, the renderer
23
+ * showed a message, or it was destroyed. Told once for each URL each call
24
+ * of `picture` handed back, also one that arrived after it was no longer
25
+ * wanted. The place to revoke an object URL.
26
+ */
27
+ releasePicture?: (url: string, ref: PictureRef) => void;
28
+ /**
29
+ * Whether `mountRenderer` adds `DISPLAY_STYLESHEET` to the document as a
30
+ * `<style>` element; true unless set. Set it false on a page whose content
31
+ * security policy has no `'unsafe-inline'` in `style-src`, which refuses that
32
+ * element, and serve the stylesheet as a file of its own, linked as
33
+ * `<link rel="stylesheet" data-obrf-display>`. A page that has such a link
34
+ * (or a `<style data-obrf-display>`) in its head gets no second copy without
35
+ * this option.
36
+ */
37
+ stylesheet?: boolean;
38
+ /** The clock, for tests. Timers are the global `setTimeout` and `clearTimeout`. */
39
+ now?: () => Date;
40
+ }
41
+ /** How fresh the content being shown is. */
42
+ export interface DisplayStatus {
43
+ /** When the content was last fetched, or confirmed by a 304. */
44
+ fetchedAt: Date;
45
+ /** True while the instance cannot be reached and this is the last good content. */
46
+ stale: boolean;
47
+ }
48
+ /**
49
+ * A full-screen message shown instead of content, with nothing from the
50
+ * instance in it:
51
+ *
52
+ * - `loading`: no content yet.
53
+ * - `link-invalid`: the instance refused the device token; the display link
54
+ * is no longer valid.
55
+ * - `not-connected`: no content to show for 24 hours.
56
+ * - `link-missing`: the address holds no device token.
57
+ * - `paused`: the route is switched off (a plugin's device route answering 404).
58
+ */
59
+ export type DisplayMessage = "loading" | "link-invalid" | "not-connected" | "link-missing" | "paused";
60
+ /** A mounted renderer. */
61
+ export interface DisplayRenderer {
62
+ /**
63
+ * Shows a document, replacing the previous one whole. The slide on screen
64
+ * stays when the new document still has a slide with its id; otherwise the
65
+ * rotation starts from the first. With `status.stale`, a small note says
66
+ * when the content was fetched.
67
+ *
68
+ * A slide the canvas cannot hold whole, such as eight events or a long news
69
+ * item, is shown a page at a time, each page for the slide's `seconds`, and
70
+ * nothing on it is cut off.
71
+ */
72
+ show(content: ScreenContent, status?: DisplayStatus): void;
73
+ /** Shows a message instead of content, in the given language. */
74
+ message(kind: DisplayMessage, locale: ScreenLocale): void;
75
+ /** Clears every timer and empties the element. */
76
+ destroy(): void;
77
+ }
78
+ /**
79
+ * Mounts a renderer on `element`, replacing what it holds, and adds the
80
+ * stylesheet to its document once, unless `options.stylesheet` is false or the
81
+ * page already links it. Give the element a size, such as the whole
82
+ * viewport: the canvas fills it, turned by the document's orientation.
83
+ */
84
+ export declare function mountRenderer(element: HTMLElement, options?: RendererOptions): DisplayRenderer;
85
+ //# sourceMappingURL=renderer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"renderer.d.ts","sourceRoot":"","sources":["../src/renderer.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,OAAO,KAAK,EACV,UAAU,EACV,aAAa,EACb,YAAY,EAEb,MAAM,eAAe,CAAC;AAcvB,uDAAuD;AACvD,MAAM,WAAW,eAAe;IAC9B;;;;;;OAMG;IACH,OAAO,CAAC,EAAE,CAAC,GAAG,EAAE,UAAU,KAAK,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;IACtD;;;;;;OAMG;IACH,cAAc,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,UAAU,KAAK,IAAI,CAAC;IACxD;;;;;;;;OAQG;IACH,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,mFAAmF;IACnF,GAAG,CAAC,EAAE,MAAM,IAAI,CAAC;CAClB;AAED,4CAA4C;AAC5C,MAAM,WAAW,aAAa;IAC5B,gEAAgE;IAChE,SAAS,EAAE,IAAI,CAAC;IAChB,mFAAmF;IACnF,KAAK,EAAE,OAAO,CAAC;CAChB;AAED;;;;;;;;;;GAUG;AACH,MAAM,MAAM,cAAc,GACxB,SAAS,GAAG,cAAc,GAAG,eAAe,GAAG,cAAc,GAAG,QAAQ,CAAC;AAE3E,0BAA0B;AAC1B,MAAM,WAAW,eAAe;IAC9B;;;;;;;;;OASG;IACH,IAAI,CAAC,OAAO,EAAE,aAAa,EAAE,MAAM,CAAC,EAAE,aAAa,GAAG,IAAI,CAAC;IAC3D,iEAAiE;IACjE,OAAO,CAAC,IAAI,EAAE,cAAc,EAAE,MAAM,EAAE,YAAY,GAAG,IAAI,CAAC;IAC1D,kDAAkD;IAClD,OAAO,IAAI,IAAI,CAAC;CACjB;AAsBD;;;;;GAKG;AACH,wBAAgB,aAAa,CAC3B,OAAO,EAAE,WAAW,EACpB,OAAO,GAAE,eAAoB,GAC5B,eAAe,CAojBjB"}
@@ -0,0 +1,476 @@
1
+ import { capitalised, element as newElement, formatTime, inSchedule, renderSlide, replaceContent, } from "./slides.js";
2
+ import { fitSlide } from "./fit.js";
3
+ import { DISPLAY_STYLESHEET } from "./styles.js";
4
+ import { translate } from "./translate.js";
5
+ import { MINUTE, zonedDayStartAfter } from "./time.js";
6
+ const MESSAGES = {
7
+ loading: { title: "loading", detail: null },
8
+ "link-invalid": { title: "linkInvalid", detail: "linkInvalidDetail" },
9
+ "not-connected": { title: "notConnected", detail: "notConnectedDetail" },
10
+ "link-missing": { title: "linkMissing", detail: "linkMissingDetail" },
11
+ paused: { title: "paused", detail: "pausedDetail" },
12
+ };
13
+ const STYLE_ATTRIBUTE = "data-obrf-display";
14
+ const PICTURE_RETRY = 5 * MINUTE;
15
+ /**
16
+ * Mounts a renderer on `element`, replacing what it holds, and adds the
17
+ * stylesheet to its document once, unless `options.stylesheet` is false or the
18
+ * page already links it. Give the element a size, such as the whole
19
+ * viewport: the canvas fills it, turned by the document's orientation.
20
+ */
21
+ export function mountRenderer(element, options = {}) {
22
+ const document = element.ownerDocument;
23
+ const clockNow = () => (options.now ?? (() => new Date()))().getTime();
24
+ if (options.stylesheet !== false) {
25
+ addStylesheet(document);
26
+ }
27
+ const make = (tag, className, text) => newElement(document, tag, className, text);
28
+ const root = make("div", "obrf-display obrf-display--dark");
29
+ const canvas = make("div", "obrf-display-canvas");
30
+ const clock = make("div", "obrf-display-clock");
31
+ const clockDate = make("span", "obrf-display-clock-date");
32
+ const clockTime = make("span", "obrf-display-clock-time");
33
+ const stage = make("div", "obrf-display-stage");
34
+ const note = make("div", "obrf-display-note");
35
+ const off = make("div", "obrf-display-off");
36
+ clock.append(clockDate, clockTime);
37
+ canvas.append(clock, stage, note);
38
+ root.append(canvas, off);
39
+ clock.hidden = true;
40
+ note.hidden = true;
41
+ off.hidden = true;
42
+ replaceContent(element, root);
43
+ let content = null;
44
+ let status = null;
45
+ let current = null;
46
+ /** A hundredth of the canvas's shorter side, in pixels; 0 before it has a size. */
47
+ let unit = 0;
48
+ let slideTimer = null;
49
+ let minuteTimer = null;
50
+ let destroyed = false;
51
+ const pictures = new Map();
52
+ // The canvas is the element's box, turned. At 90 and 270 degrees its width
53
+ // is the element's height, so it is sized from the element in pixels.
54
+ const resizeObserver = typeof ResizeObserver === "function"
55
+ ? new ResizeObserver(() => layout())
56
+ : null;
57
+ const view = document.defaultView;
58
+ if (resizeObserver === null) {
59
+ view?.addEventListener("resize", layout);
60
+ }
61
+ else {
62
+ resizeObserver.observe(element);
63
+ }
64
+ const fonts = document.fonts;
65
+ fonts?.addEventListener("loadingdone", refit);
66
+ function layout() {
67
+ const orientation = content?.layout.orientation ?? 0;
68
+ const width = element.clientWidth;
69
+ const height = element.clientHeight;
70
+ const turned = orientation === 90 || orientation === 270;
71
+ canvas.style.transform = `translate(-50%, -50%) rotate(${orientation}deg)`;
72
+ if (turned && width > 0 && height > 0) {
73
+ canvas.style.width = `${height}px`;
74
+ canvas.style.height = `${width}px`;
75
+ }
76
+ else {
77
+ canvas.style.width = "100%";
78
+ canvas.style.height = "100%";
79
+ }
80
+ unit = width > 0 && height > 0 ? Math.min(width, height) / 100 : 0;
81
+ if (unit > 0) {
82
+ root.style.setProperty("--obrf-display-u", `${unit}px`);
83
+ }
84
+ else {
85
+ root.style.removeProperty("--obrf-display-u");
86
+ }
87
+ const portrait = turned ? width > height : height > width;
88
+ root.classList.toggle("obrf-display--portrait", portrait);
89
+ for (const degrees of [0, 90, 180, 270]) {
90
+ root.classList.toggle(`obrf-display--orientation-${degrees}`, degrees === orientation);
91
+ }
92
+ refit();
93
+ }
94
+ /**
95
+ * Fits the slide on screen again: a new size, or a typeface that has just
96
+ * loaded, holds another number of items.
97
+ */
98
+ function refit() {
99
+ const slide = stage.firstElementChild;
100
+ if (current !== null && slide?.classList.contains("obrf-display-slide")) {
101
+ const { page, pages } = fitSlide(slide, unit, current.page);
102
+ current = { ...current, page, pages };
103
+ }
104
+ }
105
+ function setTheme(theme) {
106
+ root.classList.toggle("obrf-display--light", theme === "light");
107
+ root.classList.toggle("obrf-display--dark", theme === "dark");
108
+ }
109
+ function clearSlideTimer() {
110
+ if (slideTimer !== null) {
111
+ clearTimeout(slideTimer);
112
+ slideTimer = null;
113
+ }
114
+ }
115
+ function pictureKey(ref) {
116
+ return `${ref.mediaFileId}\u0000${ref.version}`;
117
+ }
118
+ function pictureOf(slide) {
119
+ const { body } = slide;
120
+ if (body.kind === "news") {
121
+ return body.picture;
122
+ }
123
+ return body.kind === "picture" ? body.picture : null;
124
+ }
125
+ function pictureUrl(ref) {
126
+ const entry = pictures.get(pictureKey(ref));
127
+ return entry?.state === "ready" ? entry.url : null;
128
+ }
129
+ function release(entry) {
130
+ if (entry.url !== null) {
131
+ options.releasePicture?.(entry.url, entry.ref);
132
+ }
133
+ }
134
+ function releaseAllPictures() {
135
+ for (const entry of pictures.values()) {
136
+ release(entry);
137
+ }
138
+ pictures.clear();
139
+ }
140
+ /** Asks for every picture the document refers to, and lets go of the rest. */
141
+ function syncPictures(next, now) {
142
+ const wanted = new Map();
143
+ for (const slide of next.rotation) {
144
+ const ref = pictureOf(slide);
145
+ if (ref !== null) {
146
+ wanted.set(pictureKey(ref), ref);
147
+ }
148
+ }
149
+ for (const [key, entry] of pictures) {
150
+ if (!wanted.has(key)) {
151
+ release(entry);
152
+ pictures.delete(key);
153
+ }
154
+ }
155
+ for (const [key, ref] of wanted) {
156
+ const entry = pictures.get(key);
157
+ if (entry === undefined ||
158
+ (entry.state === "failed" && now - entry.askedAt >= PICTURE_RETRY)) {
159
+ ask(key, ref, now);
160
+ }
161
+ }
162
+ }
163
+ function ask(key, ref, now) {
164
+ const entry = {
165
+ ref,
166
+ state: options.picture === undefined ? "failed" : "pending",
167
+ url: null,
168
+ askedAt: now,
169
+ };
170
+ pictures.set(key, entry);
171
+ if (options.picture === undefined) {
172
+ return;
173
+ }
174
+ let request;
175
+ try {
176
+ request = options.picture(ref);
177
+ }
178
+ catch {
179
+ entry.state = "failed";
180
+ return;
181
+ }
182
+ request.then((url) => settle(key, entry, url), () => settle(key, entry, null));
183
+ }
184
+ function settle(key, entry, url) {
185
+ if (destroyed || pictures.get(key) !== entry) {
186
+ // Nobody wants it any more: hand it straight back.
187
+ if (url !== null) {
188
+ options.releasePicture?.(url, entry.ref);
189
+ }
190
+ return;
191
+ }
192
+ entry.state = url === null ? "failed" : "ready";
193
+ entry.url = url;
194
+ pictureChanged(key);
195
+ }
196
+ function pictureFailed(ref) {
197
+ const key = pictureKey(ref);
198
+ const entry = pictures.get(key);
199
+ if (entry === undefined || entry.state !== "ready") {
200
+ return;
201
+ }
202
+ release(entry);
203
+ entry.state = "failed";
204
+ entry.url = null;
205
+ pictureChanged(key);
206
+ }
207
+ /** A picture arrived or went: redraw the slide that shows it, or start the rotation it unblocks. */
208
+ function pictureChanged(key) {
209
+ if (content === null) {
210
+ return;
211
+ }
212
+ if (current === null) {
213
+ startRotation();
214
+ return;
215
+ }
216
+ const slide = content.rotation[current.index];
217
+ const ref = slide === undefined ? null : pictureOf(slide);
218
+ if (slide !== undefined && ref !== null && pictureKey(ref) === key) {
219
+ if (slide.body.kind === "picture" && pictureUrl(ref) === null) {
220
+ advance();
221
+ }
222
+ else {
223
+ draw(slide, current.index, false, clockNow(), current.endsAt, current.page);
224
+ }
225
+ }
226
+ }
227
+ function showable(slide, now) {
228
+ if (slide.until !== null && now >= Date.parse(slide.until)) {
229
+ return false;
230
+ }
231
+ if (slide.body.kind === "picture") {
232
+ return pictureUrl(slide.body.picture) !== null;
233
+ }
234
+ return true;
235
+ }
236
+ /** What a slide looks like now: redrawn only when this changes. */
237
+ function slideKey(slide, shown, now) {
238
+ const ref = pictureOf(slide);
239
+ return JSON.stringify([
240
+ slide,
241
+ shown.locale,
242
+ shown.timeZone,
243
+ ref === null ? null : pictureUrl(ref),
244
+ // Free and busy reads the clock: what has passed drops off each minute.
245
+ slide.body.kind === "availability" ? Math.floor(now / MINUTE) : null,
246
+ // The date on a news slide and the days of events are the zone's.
247
+ zonedDayStartAfter(now, 0, shown.timeZone),
248
+ ]);
249
+ }
250
+ /** Draws page `page` of a slide, or keeps it when it is already on screen. */
251
+ function draw(slide, index, enter, now, endsAt, page = 0) {
252
+ if (content === null) {
253
+ return;
254
+ }
255
+ const key = slideKey(slide, content, now);
256
+ let fit = { page, pages: current?.pages ?? 1 };
257
+ if (current === null ||
258
+ current.id !== slide.id ||
259
+ current.key !== key ||
260
+ current.page !== page) {
261
+ const context = {
262
+ document,
263
+ locale: content.locale,
264
+ timeZone: content.timeZone,
265
+ now,
266
+ pictureUrl,
267
+ pictureFailed,
268
+ };
269
+ const node = renderSlide(slide, context);
270
+ if (node === null) {
271
+ current = null;
272
+ advance();
273
+ return;
274
+ }
275
+ replaceContent(stage, node);
276
+ const fitted = fitSlide(node, unit, page);
277
+ if (enter) {
278
+ node.classList.add("obrf-display-slide--enter");
279
+ }
280
+ fit = { page: fitted.page, pages: fitted.pages };
281
+ }
282
+ current = { index, id: slide.id, key, endsAt, ...fit };
283
+ clearSlideTimer();
284
+ const until = slide.until === null ? Infinity : Date.parse(slide.until);
285
+ slideTimer = setTimeout(advance, Math.max(0, Math.min(endsAt, until) - now));
286
+ }
287
+ /** Shows the first slide that can be shown at or after `from`, looping. */
288
+ function showFrom(from, enter) {
289
+ if (content === null) {
290
+ return;
291
+ }
292
+ const now = clockNow();
293
+ const { rotation } = content;
294
+ for (let step = 0; step < rotation.length; step += 1) {
295
+ const index = (from + step) % rotation.length;
296
+ const slide = rotation[index];
297
+ if (slide !== undefined && showable(slide, now)) {
298
+ // The slide on screen goes on, unless it comes back to its first page.
299
+ const continuing = current !== null && current.id === slide.id && current.page === 0;
300
+ draw(slide, index, enter && !continuing, now, now + slide.seconds * 1000);
301
+ return;
302
+ }
303
+ }
304
+ // Nothing to show now: said quietly, so a screen just opened on a link
305
+ // does not look broken. The minute tick and an arriving picture try again.
306
+ clearSlideTimer();
307
+ current = null;
308
+ replaceContent(stage, make("p", "obrf-display-empty", translate(content.locale, "nothingToShow")));
309
+ }
310
+ function startRotation() {
311
+ showFrom(0, true);
312
+ }
313
+ /** The slide's next page, or the next slide after its last. */
314
+ function advance() {
315
+ slideTimer = null;
316
+ const slide = current === null || content === null
317
+ ? undefined
318
+ : content.rotation[current.index];
319
+ const now = clockNow();
320
+ if (current !== null &&
321
+ slide !== undefined &&
322
+ current.page + 1 < current.pages &&
323
+ showable(slide, now)) {
324
+ draw(slide, current.index, true, now, now + slide.seconds * 1000, current.page + 1);
325
+ return;
326
+ }
327
+ showFrom(current === null ? 0 : current.index + 1, true);
328
+ }
329
+ function updateClock(now) {
330
+ if (content === null || content.layout.header !== "clock") {
331
+ clock.hidden = true;
332
+ return;
333
+ }
334
+ clock.hidden = false;
335
+ clockDate.textContent = capitalised(formatTime(now, content.locale, content.timeZone, "weekdayDate"));
336
+ clockTime.textContent = formatTime(now, content.locale, content.timeZone, "time");
337
+ }
338
+ function updateNote(now) {
339
+ if (content === null || status === null || !status.stale) {
340
+ note.hidden = true;
341
+ return;
342
+ }
343
+ const fetchedAt = status.fetchedAt.getTime();
344
+ const { locale, timeZone } = content;
345
+ const sameDay = zonedDayStartAfter(fetchedAt, 0, timeZone) ===
346
+ zonedDayStartAfter(now, 0, timeZone);
347
+ const time = formatTime(fetchedAt, locale, timeZone, "time");
348
+ // The date and time in the data face, the words around them not.
349
+ const [before = "", after = ""] = translate(locale, "lastUpdated", {
350
+ time: "\u0000",
351
+ }).split("\u0000");
352
+ replaceContent(note, before, make("span", "obrf-display-data", sameDay
353
+ ? time
354
+ : `${formatTime(fetchedAt, locale, timeZone, "date")} ${time}`), after);
355
+ note.hidden = false;
356
+ }
357
+ function updateSchedule(now) {
358
+ off.hidden =
359
+ content === null ||
360
+ inSchedule(content.schedule.on, now, content.timeZone);
361
+ }
362
+ /** Each minute: the clock, the schedule, the note, and a rotation that had nothing to show. */
363
+ function tick() {
364
+ minuteTimer = null;
365
+ if (destroyed) {
366
+ return;
367
+ }
368
+ const now = clockNow();
369
+ updateClock(now);
370
+ updateSchedule(now);
371
+ updateNote(now);
372
+ if (content !== null) {
373
+ if (current === null) {
374
+ startRotation();
375
+ }
376
+ else {
377
+ const slide = content.rotation[current.index];
378
+ if (slide !== undefined &&
379
+ slideKey(slide, content, now) !== current.key) {
380
+ draw(slide, current.index, false, now, current.endsAt, current.page);
381
+ }
382
+ }
383
+ }
384
+ scheduleTick(clockNow());
385
+ }
386
+ function scheduleTick(now) {
387
+ if (minuteTimer !== null) {
388
+ clearTimeout(minuteTimer);
389
+ }
390
+ minuteTimer = setTimeout(tick, MINUTE - (now % MINUTE));
391
+ }
392
+ return {
393
+ show(next, nextStatus) {
394
+ if (destroyed) {
395
+ return;
396
+ }
397
+ const now = clockNow();
398
+ const previous = current;
399
+ content = next;
400
+ status = nextStatus ?? null;
401
+ root.lang = next.locale;
402
+ setTheme(next.layout.theme);
403
+ layout();
404
+ syncPictures(next, now);
405
+ updateClock(now);
406
+ updateSchedule(now);
407
+ updateNote(now);
408
+ const kept = previous === null
409
+ ? -1
410
+ : next.rotation.findIndex((slide) => slide.id === previous.id);
411
+ const keptSlide = kept === -1 ? undefined : next.rotation[kept];
412
+ if (previous !== null &&
413
+ keptSlide !== undefined &&
414
+ showable(keptSlide, now)) {
415
+ draw(keptSlide, kept, false, now, previous.endsAt, previous.page);
416
+ }
417
+ else {
418
+ current = null;
419
+ clearSlideTimer();
420
+ startRotation();
421
+ }
422
+ scheduleTick(now);
423
+ },
424
+ message(kind, locale) {
425
+ if (destroyed) {
426
+ return;
427
+ }
428
+ content = null;
429
+ status = null;
430
+ current = null;
431
+ clearSlideTimer();
432
+ releaseAllPictures();
433
+ root.lang = locale;
434
+ clock.hidden = true;
435
+ note.hidden = true;
436
+ off.hidden = true;
437
+ layout();
438
+ const words = MESSAGES[kind];
439
+ const box = make("div", "obrf-display-message");
440
+ box.setAttribute("role", "status");
441
+ box.append(make("p", "obrf-display-message-title", translate(locale, words.title)));
442
+ if (words.detail !== null) {
443
+ box.append(make("p", "obrf-display-message-detail", translate(locale, words.detail)));
444
+ }
445
+ replaceContent(stage, box);
446
+ },
447
+ destroy() {
448
+ if (destroyed) {
449
+ return;
450
+ }
451
+ destroyed = true;
452
+ clearSlideTimer();
453
+ if (minuteTimer !== null) {
454
+ clearTimeout(minuteTimer);
455
+ minuteTimer = null;
456
+ }
457
+ resizeObserver?.disconnect();
458
+ view?.removeEventListener("resize", layout);
459
+ fonts?.removeEventListener("loadingdone", refit);
460
+ releaseAllPictures();
461
+ content = null;
462
+ current = null;
463
+ replaceContent(element);
464
+ },
465
+ };
466
+ }
467
+ function addStylesheet(document) {
468
+ if (document.head.querySelector(`style[${STYLE_ATTRIBUTE}], link[${STYLE_ATTRIBUTE}]`) !== null) {
469
+ return;
470
+ }
471
+ const style = document.createElement("style");
472
+ style.setAttribute(STYLE_ATTRIBUTE, "");
473
+ style.textContent = DISPLAY_STYLESHEET;
474
+ document.head.append(style);
475
+ }
476
+ //# sourceMappingURL=renderer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"renderer.js","sourceRoot":"","sources":["../src/renderer.ts"],"names":[],"mappings":"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"}