@prose-reader/enhancer-annotations 1.303.0 → 1.305.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -1,550 +1,263 @@
1
- import { setStylePropertyIfChanged, setPropertyIfChanged, DestroyableClass, ReactiveEntity, isShallowEqual } from '@prose-reader/core';
2
- import { fromEvent, map, share, shareReplay, tap, merge, takeUntil, first, withLatestFrom, switchMap, distinctUntilChanged, of, forkJoin, defaultIfEmpty, BehaviorSubject, NEVER, debounceTime, combineLatest } from 'rxjs';
3
-
4
- const createElementForRange = (range, container, color) => {
5
- const rects = Array.from(range.getClientRects());
6
- const lineGroups = /* @__PURE__ */ new Map();
7
- rects.forEach((rect) => {
8
- const lineY = Math.round(rect.top);
9
- if (!lineGroups.has(lineY)) {
10
- lineGroups.set(lineY, []);
11
- }
12
- lineGroups.get(lineY)?.push(rect);
13
- });
14
- return Array.from(lineGroups.values()).map((lineRects) => {
15
- const left = Math.min(...lineRects.map((r) => r.left));
16
- const right = Math.max(...lineRects.map((r) => r.right));
17
- const top = lineRects[0]?.top;
18
- const height = lineRects[0]?.height;
19
- const rectEltContainer = container.ownerDocument.createElement("div");
20
- const rectElt = container.ownerDocument.createElement("div");
21
- rectEltContainer.style.cssText = `
1
+ import { DestroyableClass as e, ReactiveEntity as t, isShallowEqual as n, setPropertyIfChanged as r, setStylePropertyIfChanged as i } from "@prose-reader/core";
2
+ import { BehaviorSubject as a, NEVER as o, combineLatest as s, debounceTime as c, defaultIfEmpty as l, distinctUntilChanged as u, first as d, forkJoin as f, fromEvent as p, map as m, merge as h, of as g, share as _, shareReplay as v, switchMap as y, takeUntil as b, tap as x, withLatestFrom as S } from "rxjs";
3
+ //#region src/annotations/utils.ts
4
+ var C = (e, t, n) => {
5
+ let r = Array.from(e.getClientRects()), i = /* @__PURE__ */ new Map();
6
+ return r.forEach((e) => {
7
+ let t = Math.round(e.top);
8
+ i.has(t) || i.set(t, []), i.get(t)?.push(e);
9
+ }), Array.from(i.values()).map((e) => {
10
+ let r = Math.min(...e.map((e) => e.left)), i = Math.max(...e.map((e) => e.right)), a = e[0]?.top, o = e[0]?.height, s = t.ownerDocument.createElement("div"), c = t.ownerDocument.createElement("div");
11
+ return s.style.cssText = `
22
12
  position: absolute;
23
- width: ${right - left}px;
24
- height: ${height}px;
25
- top: ${top}px;
26
- left: ${left}px;
13
+ width: ${i - r}px;
14
+ height: ${o}px;
15
+ top: ${a}px;
16
+ left: ${r}px;
27
17
  box-sizing: border-box;
28
18
  border: 3px dashed transparent;
29
- `;
30
- rectElt.style.cssText = `
19
+ `, c.style.cssText = `
31
20
  height: 100%;
32
21
  width: 100%;
33
22
  opacity: 40%;
34
- background-color: ${color}
35
- `;
36
- rectEltContainer.appendChild(rectElt);
37
- return rectEltContainer;
38
- });
39
- };
40
- const copyPositionStyle = (source, target) => {
41
- setPropertyIfChanged(target.style, `cssText`, source.style.cssText);
42
- };
43
- const createAnnotationLayer = (container, layer) => {
44
- const annotationLayer = container.ownerDocument.createElement("div");
45
- layoutAnnotationLayer(layer, annotationLayer);
46
- container.appendChild(annotationLayer);
47
- return annotationLayer;
23
+ background-color: ${n}
24
+ `, s.appendChild(c), s;
25
+ });
26
+ }, w = (e, t) => {
27
+ r(t.style, "cssText", e.style.cssText);
28
+ }, T = (e, t) => {
29
+ let n = e.ownerDocument.createElement("div");
30
+ return E(t, n), e.appendChild(n), n;
31
+ }, E = (e, t) => {
32
+ w(e, t), e.style.position === "" && (i(t.style, "position", "absolute"), i(t.style, "top", "0")), i(t.style, "opacity", "1"), i(t.style, "pointer-events", "none");
33
+ }, D = class extends e {
34
+ spineItem;
35
+ containerElement;
36
+ reader;
37
+ highlight;
38
+ isSelected;
39
+ container;
40
+ tap$;
41
+ resolvedCfi$;
42
+ constructor(e, t, n, r, i) {
43
+ super(), this.spineItem = e, this.containerElement = t, this.reader = n, this.highlight = r, this.isSelected = i, this.spineItem, this.reader, this.container = this.containerElement.ownerDocument.createElement("div"), this.container.dataset.highlightContainer = this.highlight.id, this.containerElement.appendChild(this.container), this.tap$ = p(this.container, "click").pipe(m((e) => ({
44
+ event: e,
45
+ highlight: this.highlight
46
+ })), _()), this.resolvedCfi$ = this.spineItem.watch("isLoaded").pipe(m(() => this.reader.cfi.resolveCfi({ cfi: this.highlight.cfi })), v({
47
+ refCount: !0,
48
+ bufferSize: 1
49
+ }));
50
+ let a = this.isSelected.pipe(x((e) => {
51
+ this.updateStateOnSelection(e);
52
+ }));
53
+ h(this.resolvedCfi$, a).pipe(b(this.destroy$)).subscribe();
54
+ }
55
+ updateStateOnSelection(e) {
56
+ Array.from(this.container.children).forEach((t) => {
57
+ t instanceof HTMLElement && i(t.style, "border", e ? "3px dashed red" : "3px dashed transparent");
58
+ });
59
+ }
60
+ render() {
61
+ return this.resolvedCfi$.pipe(d(), S(this.isSelected), m(([e, t]) => {
62
+ if (!e?.isCfiRange) return;
63
+ let n = e.range;
64
+ if (this.container.innerHTML = "", !n) return;
65
+ let r = C(n, this.container, this.highlight.highlightColor ?? "yellow");
66
+ r.forEach((e) => {
67
+ e.style.pointerEvents = "initial", e.style.cursor = "pointer", e.dataset.highlightRect = this.highlight.id, this.container.appendChild(e);
68
+ });
69
+ let i = r[0];
70
+ if (i && this.highlight.notes) {
71
+ let e = document.createElement("span");
72
+ e.textContent = "📝", e.style.position = "absolute", e.style.top = "0", e.style.left = "0", e.style.transform = "translate(-0%, -80%)", e.style.fontSize = "18px", e.style.opacity = "50%", i.appendChild(e);
73
+ }
74
+ return this.updateStateOnSelection(t), null;
75
+ }));
76
+ }
77
+ isWithinTarget(e) {
78
+ return this.container.contains(e);
79
+ }
80
+ destroy() {
81
+ super.destroy(), this.container.remove();
82
+ }
83
+ }, O = class extends e {
84
+ annotations$;
85
+ spineItem;
86
+ reader;
87
+ selectedHighlight;
88
+ layer;
89
+ highlights = [];
90
+ tap$;
91
+ constructor(e, t, n, r) {
92
+ super(), this.annotations$ = e, this.spineItem = t, this.reader = n, this.selectedHighlight = r;
93
+ let i = t.renderer.documentContainer ?? document.createElement("div");
94
+ this.layer = T(this.spineItem.containerElement, i);
95
+ let a = this.annotations$.pipe(y((e) => {
96
+ let t = e.filter((e) => !this.highlights.some((t) => t.highlight.id === e.id)), n = this.highlights.filter((e) => e.highlight.itemIndex !== this.spineItem.item.index);
97
+ return this.highlights.forEach((t, r) => {
98
+ let i = e.find((e) => e.id === t.highlight.id);
99
+ n.includes(t) && (t.destroy(), this.highlights = this.highlights.splice(r, 1)), i && (t.highlight = i);
100
+ }), t.forEach((e) => {
101
+ if (e.itemIndex !== this.spineItem.item.index) return;
102
+ let t = this.selectedHighlight.pipe(m((t) => t === e.id), u()), n = new D(this.spineItem, this.layer, this.reader, e, t);
103
+ this.highlights.push(n);
104
+ }), g(this.highlights);
105
+ }), v(1), b(this.destroy$));
106
+ this.tap$ = a.pipe(y((e) => h(...e.map((e) => e.tap$)))), e.subscribe();
107
+ }
108
+ layout() {
109
+ return E(this.spineItem.renderer.documentContainer ?? document.createElement("div"), this.layer), f(this.highlights.map((e) => e.render())).pipe(l(null));
110
+ }
111
+ getHighlightsForTarget(e) {
112
+ return this.highlights.filter((t) => e instanceof Node && t.isWithinTarget(e));
113
+ }
114
+ destroy() {
115
+ super.destroy(), this.layer.remove();
116
+ }
117
+ }, k = class extends e {
118
+ reader;
119
+ highlights;
120
+ selectedHighlight;
121
+ spineItemHighlights = new a([]);
122
+ tap$;
123
+ constructor(e, t, n) {
124
+ super(), this.reader = e, this.highlights = t, this.selectedHighlight = n;
125
+ let r = /* @__PURE__ */ new Map();
126
+ this.reader.hookManager.register("item.onDocumentLoad", async ({ itemId: t }) => {
127
+ r.get(t)?.(), r.delete(t);
128
+ let n = e.spineItemsManager.get(t);
129
+ if (!n) return;
130
+ let i = new O(this.highlights.pipe(m((e) => e.filter((e) => e.itemIndex === n.item.index))), n, e, this.selectedHighlight);
131
+ this.spineItemHighlights.next([...this.spineItemHighlights.getValue(), i]), r.set(t, () => {
132
+ this.spineItemHighlights.next(this.spineItemHighlights.getValue().filter((e) => e !== i)), i.destroy();
133
+ });
134
+ }), this.reader.hookManager.register("item.onDocumentUnload", async ({ itemId: e }) => {
135
+ r.get(e)?.(), r.delete(e);
136
+ }), this.tap$ = this.spineItemHighlights.pipe(y((e) => h(...e.map((e) => e.tap$))));
137
+ }
138
+ getHighlightsForTarget = (e) => this.spineItemHighlights.getValue().flatMap((t) => t.getHighlightsForTarget(e)).map((e) => e.highlight);
139
+ isTargetWithinHighlight = (e) => !!this.getHighlightsForTarget(e).length;
140
+ layout() {
141
+ return f(this.spineItemHighlights.value.map((e) => e.layout())).pipe(l(null));
142
+ }
143
+ }, A = () => {
144
+ if (!(typeof window > "u")) return window;
48
145
  };
49
- const layoutAnnotationLayer = (layer, annotationLayer) => {
50
- copyPositionStyle(layer, annotationLayer);
51
- if (layer.style.position === "") {
52
- setStylePropertyIfChanged(annotationLayer.style, `position`, `absolute`);
53
- setStylePropertyIfChanged(annotationLayer.style, `top`, `0`);
54
- }
55
- setStylePropertyIfChanged(annotationLayer.style, `opacity`, `1`);
56
- setStylePropertyIfChanged(annotationLayer.style, `pointer-events`, `none`);
57
- };
58
-
59
- class SpineItemHighlight extends DestroyableClass {
60
- constructor(spineItem, containerElement, reader, highlight, isSelected) {
61
- super();
62
- this.spineItem = spineItem;
63
- this.containerElement = containerElement;
64
- this.reader = reader;
65
- this.highlight = highlight;
66
- this.isSelected = isSelected;
67
- void this.spineItem;
68
- void this.reader;
69
- this.container = this.containerElement.ownerDocument.createElement("div");
70
- this.container.dataset.highlightContainer = this.highlight.id;
71
- this.containerElement.appendChild(this.container);
72
- this.tap$ = fromEvent(this.container, "click").pipe(
73
- map((event) => ({ event, highlight: this.highlight })),
74
- share()
75
- );
76
- this.resolvedCfi$ = this.spineItem.watch("isLoaded").pipe(
77
- map(() => this.reader.cfi.resolveCfi({ cfi: this.highlight.cfi })),
78
- shareReplay({ refCount: true, bufferSize: 1 })
79
- );
80
- const updateStateOnSelection$ = this.isSelected.pipe(
81
- tap((isSelected2) => {
82
- this.updateStateOnSelection(isSelected2);
83
- })
84
- );
85
- merge(this.resolvedCfi$, updateStateOnSelection$).pipe(takeUntil(this.destroy$)).subscribe();
86
- }
87
- spineItem;
88
- containerElement;
89
- reader;
90
- highlight;
91
- isSelected;
92
- container;
93
- tap$;
94
- resolvedCfi$;
95
- updateStateOnSelection(isSelected) {
96
- Array.from(this.container.children).forEach((child) => {
97
- if (child instanceof HTMLElement) {
98
- setStylePropertyIfChanged(
99
- child.style,
100
- `border`,
101
- isSelected ? "3px dashed red" : "3px dashed transparent"
102
- );
103
- }
104
- });
105
- }
106
- render() {
107
- return this.resolvedCfi$.pipe(
108
- first(),
109
- withLatestFrom(this.isSelected),
110
- map(([resolvedCfi, isSelected]) => {
111
- if (!resolvedCfi?.isCfiRange) return void 0;
112
- const range = resolvedCfi.range;
113
- this.container.innerHTML = "";
114
- if (!range) {
115
- return;
116
- }
117
- const rectElements = createElementForRange(
118
- range,
119
- this.container,
120
- this.highlight.highlightColor ?? "yellow"
121
- );
122
- rectElements.forEach((elt) => {
123
- elt.style.pointerEvents = "initial";
124
- elt.style.cursor = "pointer";
125
- elt.dataset.highlightRect = this.highlight.id;
126
- this.container.appendChild(elt);
127
- });
128
- const firstElement = rectElements[0];
129
- if (firstElement && this.highlight.notes) {
130
- const noteIcon = document.createElement("span");
131
- noteIcon.textContent = "📝";
132
- noteIcon.style.position = "absolute";
133
- noteIcon.style.top = "0";
134
- noteIcon.style.left = "0";
135
- noteIcon.style.transform = "translate(-0%, -80%)";
136
- noteIcon.style.fontSize = "18px";
137
- noteIcon.style.opacity = "50%";
138
- firstElement.appendChild(noteIcon);
139
- }
140
- this.updateStateOnSelection(isSelected);
141
- return null;
142
- })
143
- );
144
- }
145
- isWithinTarget(target) {
146
- return this.container.contains(target);
147
- }
148
- destroy() {
149
- super.destroy();
150
- this.container.remove();
151
- }
152
- }
153
-
154
- class SpineItemHighlights extends DestroyableClass {
155
- constructor(annotations$, spineItem, reader, selectedHighlight) {
156
- super();
157
- this.annotations$ = annotations$;
158
- this.spineItem = spineItem;
159
- this.reader = reader;
160
- this.selectedHighlight = selectedHighlight;
161
- const firstLayerElement = spineItem.renderer.documentContainer ?? document.createElement("div");
162
- this.layer = createAnnotationLayer(
163
- this.spineItem.containerElement,
164
- firstLayerElement
165
- );
166
- const itemHighlights$ = this.annotations$.pipe(
167
- switchMap((annotations) => {
168
- const newAnnotations = annotations.filter(
169
- (annotation) => !this.highlights.some(
170
- (highlight) => highlight.highlight.id === annotation.id
171
- )
172
- );
173
- const oldAnnotations = this.highlights.filter(
174
- (highlight) => highlight.highlight.itemIndex !== this.spineItem.item.index
175
- );
176
- this.highlights.forEach((highlight, index) => {
177
- const existingAnnotation = annotations.find(
178
- (annotation) => annotation.id === highlight.highlight.id
179
- );
180
- if (oldAnnotations.includes(highlight)) {
181
- highlight.destroy();
182
- this.highlights = this.highlights.splice(index, 1);
183
- }
184
- if (existingAnnotation) {
185
- highlight.highlight = existingAnnotation;
186
- }
187
- });
188
- newAnnotations.forEach((annotation) => {
189
- if (annotation.itemIndex !== this.spineItem.item.index) return;
190
- const isSelected$ = this.selectedHighlight.pipe(
191
- map((id) => id === annotation.id),
192
- distinctUntilChanged()
193
- );
194
- const spineItemHighlight = new SpineItemHighlight(
195
- this.spineItem,
196
- this.layer,
197
- this.reader,
198
- annotation,
199
- isSelected$
200
- );
201
- this.highlights.push(spineItemHighlight);
202
- });
203
- return of(this.highlights);
204
- }),
205
- shareReplay(1),
206
- takeUntil(this.destroy$)
207
- );
208
- this.tap$ = itemHighlights$.pipe(
209
- switchMap(
210
- (highlights) => merge(...highlights.map((highlight) => highlight.tap$))
211
- )
212
- );
213
- annotations$.subscribe();
214
- }
215
- annotations$;
216
- spineItem;
217
- reader;
218
- selectedHighlight;
219
- layer;
220
- highlights = [];
221
- tap$;
222
- layout() {
223
- const firstLayerElement = this.spineItem.renderer.documentContainer ?? document.createElement("div");
224
- layoutAnnotationLayer(firstLayerElement, this.layer);
225
- return forkJoin(
226
- this.highlights.map((highlight) => highlight.render())
227
- ).pipe(defaultIfEmpty(null));
228
- }
229
- getHighlightsForTarget(target) {
230
- return this.highlights.filter(
231
- (highlight) => target instanceof Node && highlight.isWithinTarget(target)
232
- );
233
- }
234
- destroy() {
235
- super.destroy();
236
- this.layer.remove();
237
- }
238
- }
239
-
240
- class ReaderHighlights extends DestroyableClass {
241
- constructor(reader, highlights, selectedHighlight) {
242
- super();
243
- this.reader = reader;
244
- this.highlights = highlights;
245
- this.selectedHighlight = selectedHighlight;
246
- const cleanupByItemId = /* @__PURE__ */ new Map();
247
- this.reader.hookManager.register(
248
- "item.onDocumentLoad",
249
- async ({ itemId }) => {
250
- cleanupByItemId.get(itemId)?.();
251
- cleanupByItemId.delete(itemId);
252
- const spineItem = reader.spineItemsManager.get(itemId);
253
- if (!spineItem) return;
254
- const spineItemHighlights$ = this.highlights.pipe(
255
- map(
256
- (highlights2) => highlights2.filter(
257
- (highlight) => highlight.itemIndex === spineItem.item.index
258
- )
259
- )
260
- );
261
- const spineItemHighlights = new SpineItemHighlights(
262
- spineItemHighlights$,
263
- spineItem,
264
- reader,
265
- this.selectedHighlight
266
- );
267
- this.spineItemHighlights.next([
268
- ...this.spineItemHighlights.getValue(),
269
- spineItemHighlights
270
- ]);
271
- const cleanup = () => {
272
- this.spineItemHighlights.next(
273
- this.spineItemHighlights.getValue().filter((layer) => layer !== spineItemHighlights)
274
- );
275
- spineItemHighlights.destroy();
276
- };
277
- cleanupByItemId.set(itemId, cleanup);
278
- }
279
- );
280
- this.reader.hookManager.register(
281
- "item.onDocumentUnload",
282
- async ({ itemId }) => {
283
- cleanupByItemId.get(itemId)?.();
284
- cleanupByItemId.delete(itemId);
285
- }
286
- );
287
- this.tap$ = this.spineItemHighlights.pipe(
288
- switchMap((layers) => merge(...layers.map((layer) => layer.tap$)))
289
- );
290
- }
291
- reader;
292
- highlights;
293
- selectedHighlight;
294
- spineItemHighlights = new BehaviorSubject([]);
295
- tap$;
296
- getHighlightsForTarget = (target) => {
297
- return this.spineItemHighlights.getValue().flatMap((layer) => layer.getHighlightsForTarget(target)).map((annotation) => annotation.highlight);
298
- };
299
- isTargetWithinHighlight = (target) => {
300
- return !!this.getHighlightsForTarget(target).length;
301
- };
302
- layout() {
303
- return forkJoin(
304
- this.spineItemHighlights.value.map((item) => item.layout())
305
- ).pipe(defaultIfEmpty(null));
306
- }
146
+ function j() {
147
+ let e = A()?.__PROSE_READER_DEBUG;
148
+ return e === !0 || e === "true";
307
149
  }
308
-
309
- const m = () => {
310
- if (!(typeof window > "u"))
311
- return window;
312
- };
313
- function b() {
314
- const e = m()?.__PROSE_READER_DEBUG;
315
- return e === true || e === "true";
316
- }
317
- const E = (e, t) => typeof e == "boolean" ? {
318
- enabled: e,
319
- options: t
150
+ var M = (e, t) => typeof e == "boolean" ? {
151
+ enabled: e,
152
+ options: t
320
153
  } : {
321
- enabled: e?.enabled,
322
- options: e ?? t
323
- }, w = (e) => e.at(-1)?.color, u = (e) => {
324
- if (!e.length)
325
- return;
326
- if (!e.some((o) => o.color))
327
- return [e.map((o) => o.label).join(" ")];
328
- let t = "";
329
- const n = [];
330
- for (const o of e)
331
- t += `%c${t ? ` ${o.label}` : o.label}`, n.push(
332
- o.color ? `color: ${o.color}` : ""
333
- );
334
- return [t, ...n];
335
- }, p = (e = [], t = b()) => {
336
- let n = t;
337
- const o = {
338
- enable: (c) => {
339
- l(c);
340
- },
341
- namespace: (c, s, a) => {
342
- const i = E(
343
- s,
344
- a
345
- ), g = i.options?.color ?? w(e);
346
- return p(
347
- [
348
- ...e,
349
- {
350
- label: `[${c}]`,
351
- color: g
352
- }
353
- ],
354
- i.enabled ?? n
355
- );
356
- },
357
- isEnabled: () => n,
358
- debug: () => {
359
- },
360
- info: () => {
361
- },
362
- log: () => {
363
- },
364
- groupCollapsed: () => {
365
- },
366
- groupEnd: () => {
367
- },
368
- getGroupArgs: (c) => {
369
- const s = u(e);
370
- if (!s)
371
- return [c];
372
- const [a, ...i] = s;
373
- return [`${a} ${c}`, ...i];
374
- },
375
- warn: () => {
376
- },
377
- error: () => {
378
- }
379
- }, r = (c) => {
380
- if (!c) {
381
- o.debug = () => {
382
- }, o.info = () => {
383
- }, o.log = () => {
384
- }, o.groupCollapsed = () => {
385
- }, o.groupEnd = () => {
386
- }, o.warn = () => {
387
- }, o.error = () => {
388
- };
389
- return;
390
- }
391
- const s = u(e) ?? [];
392
- o.debug = Function.prototype.bind.call(
393
- console.debug,
394
- console,
395
- ...s
396
- ), o.info = Function.prototype.bind.call(
397
- console.info,
398
- console,
399
- ...s
400
- ), o.log = Function.prototype.bind.call(
401
- console.log,
402
- console,
403
- ...s
404
- ), o.groupCollapsed = Function.prototype.bind.call(
405
- console.groupCollapsed,
406
- console
407
- ), o.groupEnd = Function.prototype.bind.call(console.groupEnd, console), o.warn = Function.prototype.bind.call(
408
- console.warn,
409
- console,
410
- ...s
411
- ), o.error = Function.prototype.bind.call(
412
- console.error,
413
- console,
414
- ...s
415
- );
416
- }, l = (c) => {
417
- n !== c && (n = c, r(n));
418
- };
419
- return r(n), o;
420
- }, O = p();
421
-
422
- const name = "@prose-reader/enhancer-annotations";
423
-
424
- const IS_DEBUG_ENABLED = true;
425
- const report = O.namespace(name, IS_DEBUG_ENABLED);
426
-
427
- class Settings extends ReactiveEntity {
428
- update(settings) {
429
- super.mergeCompare(settings);
430
- }
431
- }
432
-
433
- const annotationsEnhancer = (next) => (options) => {
434
- const { annotations: annotationsOptions, ...rest } = options;
435
- const settings = new Settings({
436
- annotations$: annotationsOptions?.annotations$
437
- });
438
- const reader = next(rest);
439
- const annotations$ = settings.watch("annotations$").pipe(switchMap((annotations) => annotations ?? NEVER));
440
- const runtimeAnnotations$ = annotations$.pipe(
441
- distinctUntilChanged(isShallowEqual),
442
- map((annotations) => {
443
- const runtimeAnnotations = annotations.map(
444
- (annotation) => {
445
- const { itemIndex = 0 } = reader.cfi.parseCfi(annotation.cfi ?? "");
446
- const highlight = {
447
- ...annotation,
448
- itemIndex
449
- };
450
- return highlight;
451
- }
452
- );
453
- return runtimeAnnotations;
454
- }),
455
- tap((annotations) => {
456
- report.debug("annotations", annotations);
457
- }),
458
- shareReplay({
459
- refCount: true,
460
- bufferSize: 1
461
- })
462
- );
463
- const selectedHighlight$ = runtimeAnnotations$.pipe(
464
- map(
465
- (annotations) => annotations.find((annotation) => annotation.selected)?.id
466
- ),
467
- distinctUntilChanged(),
468
- shareReplay({ refCount: true, bufferSize: 1 })
469
- );
470
- const readerHighlights = new ReaderHighlights(
471
- reader,
472
- runtimeAnnotations$,
473
- selectedHighlight$
474
- );
475
- const resolveItemInformation = (params) => {
476
- if (params.itemIndex !== void 0)
477
- return { itemIndex: params.itemIndex, pageIndex: void 0 };
478
- if (params.absolutePageIndex !== void 0) {
479
- return reader.spine.pages.fromAbsolutePageIndex(
480
- params.absolutePageIndex
481
- );
482
- }
483
- return void 0;
484
- };
485
- const createAnnotation = ({
486
- selection,
487
- ...rest2
488
- }) => {
489
- const { itemIndex, pageIndex = 0 } = resolveItemInformation(rest2) ?? {};
490
- const spineItem = reader.spineItemsManager.get(itemIndex);
491
- const id = window.crypto.randomUUID();
492
- if (!spineItem) return void 0;
493
- const range = selection ? reader.selection.createOrderedRangeFromSelection({
494
- selection,
495
- spineItem
496
- }) : void 0;
497
- const pageEntry = reader.spine.pages.fromSpineItemPageIndex(
498
- spineItem,
499
- pageIndex
500
- );
501
- const cfiWithRangeOrFirstNodeOrRoot = range ? reader.cfi.generateCfiFromRange(range, spineItem.item) : pageEntry?.firstVisibleNode ? reader.cfi.generateCfiForSpineItemPage({
502
- spineItem: spineItem.item,
503
- pageNode: pageEntry.firstVisibleNode
504
- }) : reader.cfi.generateRootCfi(spineItem.item);
505
- const highlight = {
506
- cfi: cfiWithRangeOrFirstNodeOrRoot,
507
- itemIndex: spineItem.index,
508
- id,
509
- ...rest2
510
- };
511
- return highlight;
512
- };
513
- const renderAnnotations$ = merge(runtimeAnnotations$, reader.layout$).pipe(
514
- debounceTime(50),
515
- switchMap(() => readerHighlights.layout())
516
- );
517
- const candidates$ = reader.layoutInfo$.pipe(
518
- switchMap(
519
- ({ pages }) => combineLatest(
520
- pages.map((page) => {
521
- const item = reader.spineItemsManager.get(page.itemIndex);
522
- if (!item) return of(false);
523
- if (item.renditionLayout === "pre-paginated") return of(true);
524
- if (page.firstVisibleNode) return of(true);
525
- return of(false);
526
- })
527
- )
528
- )
529
- );
530
- merge(renderAnnotations$, annotations$).pipe(takeUntil(reader.$.destroy$)).subscribe();
531
- return {
532
- ...reader,
533
- __PROSE_READER_ENHANCER_ANNOTATIONS: true,
534
- destroy: () => {
535
- readerHighlights.destroy();
536
- reader.destroy();
537
- },
538
- annotations: {
539
- annotations$: runtimeAnnotations$,
540
- highlightTap$: readerHighlights.tap$,
541
- candidates$,
542
- isTargetWithinHighlight: readerHighlights.isTargetWithinHighlight,
543
- createAnnotation,
544
- update: settings.update.bind(settings)
545
- }
546
- };
154
+ enabled: e?.enabled,
155
+ options: e ?? t
156
+ }, N = (e) => e.at(-1)?.color, P = (e) => {
157
+ if (!e.length) return;
158
+ if (!e.some((e) => e.color)) return [e.map((e) => e.label).join(" ")];
159
+ let t = "", n = [];
160
+ for (let r of e) t += `%c${t ? ` ${r.label}` : r.label}`, n.push(r.color ? `color: ${r.color}` : "");
161
+ return [t, ...n];
162
+ }, F = (e = [], t = j()) => {
163
+ let n = t, r = {
164
+ enable: (e) => {
165
+ a(e);
166
+ },
167
+ namespace: (t, r, i) => {
168
+ let a = M(r, i), o = a.options?.color ?? N(e);
169
+ return F([...e, {
170
+ label: `[${t}]`,
171
+ color: o
172
+ }], a.enabled ?? n);
173
+ },
174
+ isEnabled: () => n,
175
+ debug: () => {},
176
+ info: () => {},
177
+ log: () => {},
178
+ groupCollapsed: () => {},
179
+ groupEnd: () => {},
180
+ getGroupArgs: (t) => {
181
+ let n = P(e);
182
+ if (!n) return [t];
183
+ let [r, ...i] = n;
184
+ return [`${r} ${t}`, ...i];
185
+ },
186
+ warn: () => {},
187
+ error: () => {}
188
+ }, i = (t) => {
189
+ if (!t) {
190
+ r.debug = () => {}, r.info = () => {}, r.log = () => {}, r.groupCollapsed = () => {}, r.groupEnd = () => {}, r.warn = () => {}, r.error = () => {};
191
+ return;
192
+ }
193
+ let n = P(e) ?? [];
194
+ r.debug = Function.prototype.bind.call(console.debug, console, ...n), r.info = Function.prototype.bind.call(console.info, console, ...n), r.log = Function.prototype.bind.call(console.log, console, ...n), r.groupCollapsed = Function.prototype.bind.call(console.groupCollapsed, console), r.groupEnd = Function.prototype.bind.call(console.groupEnd, console), r.warn = Function.prototype.bind.call(console.warn, console, ...n), r.error = Function.prototype.bind.call(console.error, console, ...n);
195
+ }, a = (e) => {
196
+ n !== e && (n = e, i(n));
197
+ };
198
+ return i(n), r;
199
+ }, I = F().namespace("@prose-reader/enhancer-annotations", !0), L = class extends t {
200
+ update(e) {
201
+ super.mergeCompare(e);
202
+ }
203
+ }, R = (e) => (t) => {
204
+ let { annotations: r, ...i } = t, a = new L({ annotations$: r?.annotations$ }), l = e(i), d = a.watch("annotations$").pipe(y((e) => e ?? o)), f = d.pipe(u(n), m((e) => e.map((e) => {
205
+ let { itemIndex: t = 0 } = l.cfi.parseCfi(e.cfi ?? "");
206
+ return {
207
+ ...e,
208
+ itemIndex: t
209
+ };
210
+ })), x((e) => {
211
+ I.debug("annotations", e);
212
+ }), v({
213
+ refCount: !0,
214
+ bufferSize: 1
215
+ })), p = new k(l, f, f.pipe(m((e) => e.find((e) => e.selected)?.id), u(), v({
216
+ refCount: !0,
217
+ bufferSize: 1
218
+ }))), _ = (e) => {
219
+ if (e.itemIndex !== void 0) return {
220
+ itemIndex: e.itemIndex,
221
+ pageIndex: void 0
222
+ };
223
+ if (e.absolutePageIndex !== void 0) return l.spine.pages.fromAbsolutePageIndex(e.absolutePageIndex);
224
+ }, S = ({ selection: e, ...t }) => {
225
+ let { itemIndex: n, pageIndex: r = 0 } = _(t) ?? {}, i = l.spineItemsManager.get(n), a = window.crypto.randomUUID();
226
+ if (!i) return;
227
+ let o = e ? l.selection.createOrderedRangeFromSelection({
228
+ selection: e,
229
+ spineItem: i
230
+ }) : void 0, s = l.spine.pages.fromSpineItemPageIndex(i, r);
231
+ return {
232
+ cfi: o ? l.cfi.generateCfiFromRange(o, i.item) : s?.firstVisibleNode ? l.cfi.generateCfiForSpineItemPage({
233
+ spineItem: i.item,
234
+ pageNode: s.firstVisibleNode
235
+ }) : l.cfi.generateRootCfi(i.item),
236
+ itemIndex: i.index,
237
+ id: a,
238
+ ...t
239
+ };
240
+ }, C = h(f, l.layout$).pipe(c(50), y(() => p.layout())), w = l.layoutInfo$.pipe(y(({ pages: e }) => s(e.map((e) => {
241
+ let t = l.spineItemsManager.get(e.itemIndex);
242
+ return t && (t.renditionLayout === "pre-paginated" || e.firstVisibleNode) ? g(!0) : g(!1);
243
+ }))));
244
+ return h(C, d).pipe(b(l.$.destroy$)).subscribe(), {
245
+ ...l,
246
+ __PROSE_READER_ENHANCER_ANNOTATIONS: !0,
247
+ destroy: () => {
248
+ p.destroy(), l.destroy();
249
+ },
250
+ annotations: {
251
+ annotations$: f,
252
+ highlightTap$: p.tap$,
253
+ candidates$: w,
254
+ isTargetWithinHighlight: p.isTargetWithinHighlight,
255
+ createAnnotation: S,
256
+ update: a.update.bind(a)
257
+ }
258
+ };
547
259
  };
260
+ //#endregion
261
+ export { R as annotationsEnhancer };
548
262
 
549
- export { annotationsEnhancer };
550
- //# sourceMappingURL=index.js.map
263
+ //# sourceMappingURL=index.js.map