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