@prose-reader/enhancer-annotations 1.121.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/Commands.d.ts +35 -0
- package/dist/annotationsEnhancer.d.ts +16 -0
- package/dist/highlights/ReaderHighlights.d.ts +13 -0
- package/dist/highlights/SpineItemHighlight.d.ts +18 -0
- package/dist/highlights/SpineItemHighlights.d.ts +16 -0
- package/dist/highlights/utils.d.ts +11 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +299 -0
- package/dist/index.js.map +1 -0
- package/dist/index.umd.cjs +306 -0
- package/dist/index.umd.cjs.map +1 -0
- package/dist/report.d.ts +5 -0
- package/dist/types.d.ts +13 -0
- package/package.json +26 -0
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { DestroyableClass } from '@prose-reader/core';
|
|
2
|
+
import { Highlight } from './types';
|
|
3
|
+
type HighlightParams = {
|
|
4
|
+
document: Document;
|
|
5
|
+
selection: Selection;
|
|
6
|
+
itemId: string;
|
|
7
|
+
color?: string;
|
|
8
|
+
contents?: string[];
|
|
9
|
+
};
|
|
10
|
+
export declare class Commands extends DestroyableClass {
|
|
11
|
+
private commandSubject;
|
|
12
|
+
readonly highlight$: import('rxjs').Observable<{
|
|
13
|
+
type: "highlight";
|
|
14
|
+
data: HighlightParams;
|
|
15
|
+
}>;
|
|
16
|
+
readonly add$: import('rxjs').Observable<{
|
|
17
|
+
type: "add";
|
|
18
|
+
data: Highlight | Highlight[];
|
|
19
|
+
}>;
|
|
20
|
+
readonly delete$: import('rxjs').Observable<{
|
|
21
|
+
type: "delete";
|
|
22
|
+
id: string;
|
|
23
|
+
}>;
|
|
24
|
+
readonly update$: import('rxjs').Observable<{
|
|
25
|
+
type: "update";
|
|
26
|
+
id: string;
|
|
27
|
+
data: Pick<HighlightParams, "color" | "contents">;
|
|
28
|
+
}>;
|
|
29
|
+
highlight: (params: HighlightParams) => void;
|
|
30
|
+
add: (data: Highlight | Highlight[]) => void;
|
|
31
|
+
delete: (id: string) => void;
|
|
32
|
+
update: (id: string, data: Pick<HighlightParams, "color" | "contents">) => void;
|
|
33
|
+
destroy(): void;
|
|
34
|
+
}
|
|
35
|
+
export {};
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { Reader } from '@prose-reader/core';
|
|
2
|
+
import { Observable } from 'rxjs';
|
|
3
|
+
import { RuntimeHighlight } from './types';
|
|
4
|
+
import { ReaderHighlights } from './highlights/ReaderHighlights';
|
|
5
|
+
import { Commands } from './Commands';
|
|
6
|
+
export declare const annotationsEnhancer: <InheritOptions, InheritOutput extends Reader>(next: (options: InheritOptions) => InheritOutput) => (options: InheritOptions) => InheritOutput & {
|
|
7
|
+
annotations: {
|
|
8
|
+
annotations$: Observable<RuntimeHighlight[]>;
|
|
9
|
+
highlightTap$: ReaderHighlights["tap$"];
|
|
10
|
+
highlight: Commands["highlight"];
|
|
11
|
+
add: Commands["add"];
|
|
12
|
+
delete: Commands["delete"];
|
|
13
|
+
update: Commands["update"];
|
|
14
|
+
isTargetWithinHighlight: (target: EventTarget) => boolean;
|
|
15
|
+
};
|
|
16
|
+
};
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { DestroyableClass, Reader } from '@prose-reader/core';
|
|
2
|
+
import { BehaviorSubject } from 'rxjs';
|
|
3
|
+
import { Highlight } from '../types';
|
|
4
|
+
import { SpineItemHighlights } from './SpineItemHighlights';
|
|
5
|
+
export declare class ReaderHighlights extends DestroyableClass {
|
|
6
|
+
private reader;
|
|
7
|
+
private highlights;
|
|
8
|
+
private spineItemHighlights;
|
|
9
|
+
tap$: SpineItemHighlights["tap$"];
|
|
10
|
+
constructor(reader: Reader, highlights: BehaviorSubject<Highlight[]>);
|
|
11
|
+
getHighlightsForTarget: (target: EventTarget) => import('../types').RuntimeHighlight[];
|
|
12
|
+
isTargetWithinHighlight: (target: EventTarget) => boolean;
|
|
13
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { DestroyableClass, Reader, SpineItem } from '@prose-reader/core';
|
|
2
|
+
import { RuntimeHighlight } from '../types';
|
|
3
|
+
import { Observable } from 'rxjs';
|
|
4
|
+
export declare class SpineItemHighlight extends DestroyableClass {
|
|
5
|
+
private spineItem;
|
|
6
|
+
private containerElement;
|
|
7
|
+
private reader;
|
|
8
|
+
readonly highlight: RuntimeHighlight;
|
|
9
|
+
private container;
|
|
10
|
+
readonly tap$: Observable<{
|
|
11
|
+
event: Event;
|
|
12
|
+
highlight: RuntimeHighlight;
|
|
13
|
+
}>;
|
|
14
|
+
constructor(spineItem: SpineItem, containerElement: HTMLElement, reader: Reader, highlight: RuntimeHighlight);
|
|
15
|
+
render(): void;
|
|
16
|
+
isWithinTarget(target: Node): boolean;
|
|
17
|
+
destroy(): void;
|
|
18
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { Observable } from 'rxjs';
|
|
2
|
+
import { RuntimeHighlight } from '../types';
|
|
3
|
+
import { DestroyableClass, Reader, SpineItem } from '@prose-reader/core';
|
|
4
|
+
import { SpineItemHighlight } from './SpineItemHighlight';
|
|
5
|
+
export declare class SpineItemHighlights extends DestroyableClass {
|
|
6
|
+
private annotations$;
|
|
7
|
+
private spineItem;
|
|
8
|
+
private reader;
|
|
9
|
+
private layer;
|
|
10
|
+
private highlights;
|
|
11
|
+
readonly tap$: SpineItemHighlight["tap$"];
|
|
12
|
+
constructor(annotations$: Observable<RuntimeHighlight[]>, spineItem: SpineItem, reader: Reader);
|
|
13
|
+
layout(): void;
|
|
14
|
+
getHighlightsForTarget(target: EventTarget): SpineItemHighlight[];
|
|
15
|
+
destroy(): void;
|
|
16
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export declare const getElementsForRange: (range: Range, container: HTMLElement) => HTMLDivElement[];
|
|
2
|
+
export declare const getRangeFromSelection: (overlayElement: HTMLElement, anchor: {
|
|
3
|
+
node: Node;
|
|
4
|
+
offset?: number;
|
|
5
|
+
}, focus: {
|
|
6
|
+
node: Node;
|
|
7
|
+
offset?: number;
|
|
8
|
+
}) => Range;
|
|
9
|
+
export declare const copyPositionStyle: (source: HTMLElement, target: HTMLElement) => void;
|
|
10
|
+
export declare const createAnnotationLayer: (container: HTMLElement, layer: HTMLElement) => HTMLDivElement;
|
|
11
|
+
export declare const layoutAnnotationLayer: (layer: HTMLElement, annotationLayer: HTMLElement) => void;
|
package/dist/index.d.ts
ADDED
package/dist/index.js
ADDED
|
@@ -0,0 +1,299 @@
|
|
|
1
|
+
import { fromEvent, map, share, switchMap, of, shareReplay, takeUntil, merge, BehaviorSubject, Subject, filter, tap } from 'rxjs';
|
|
2
|
+
import { DestroyableClass } from '@prose-reader/core';
|
|
3
|
+
|
|
4
|
+
const c = "@prose-reader", i = (e) => `[${e}]`, p = (e, n) => ({
|
|
5
|
+
debug: !n || (window == null ? void 0 : window.__PROSE_READER_DEBUG) !== !0 ? () => {
|
|
6
|
+
} : e ? Function.prototype.bind.call(console.debug, console, i(`${c}`), i(e)) : Function.prototype.bind.call(console.debug, console, i(`${c}`)),
|
|
7
|
+
info: !n || (window == null ? void 0 : window.__PROSE_READER_DEBUG) !== !0 ? () => {
|
|
8
|
+
} : e ? Function.prototype.bind.call(console.info, console, i(`${c}`), i(e)) : Function.prototype.bind.call(console.info, console, i(`${c}`)),
|
|
9
|
+
error: !n || (window == null ? void 0 : window.__PROSE_READER_DEBUG) !== !0 ? () => {
|
|
10
|
+
} : e ? Function.prototype.bind.call(console.error, console, i(`${c}`), i(e)) : Function.prototype.bind.call(console.error, console, i(`${c}`))
|
|
11
|
+
}), $ = {
|
|
12
|
+
...p(),
|
|
13
|
+
namespace: (e, n) => p(e, n)
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
const IS_DEBUG_ENABLED = true;
|
|
17
|
+
const report = $.namespace(`enhancer-annotations`, IS_DEBUG_ENABLED);
|
|
18
|
+
|
|
19
|
+
const getElementsForRange = (range, container) => {
|
|
20
|
+
const rects = Array.from(range.getClientRects());
|
|
21
|
+
const lineGroups = /* @__PURE__ */ new Map();
|
|
22
|
+
rects.forEach((rect) => {
|
|
23
|
+
const lineY = Math.round(rect.top);
|
|
24
|
+
if (!lineGroups.has(lineY)) {
|
|
25
|
+
lineGroups.set(lineY, []);
|
|
26
|
+
}
|
|
27
|
+
lineGroups.get(lineY)?.push(rect);
|
|
28
|
+
});
|
|
29
|
+
return Array.from(lineGroups.values()).map((lineRects) => {
|
|
30
|
+
const left = Math.min(...lineRects.map((r) => r.left));
|
|
31
|
+
const right = Math.max(...lineRects.map((r) => r.right));
|
|
32
|
+
const top = lineRects[0]?.top;
|
|
33
|
+
const height = lineRects[0]?.height;
|
|
34
|
+
const rectElt = container.ownerDocument.createElement("div");
|
|
35
|
+
rectElt.style.cssText = `
|
|
36
|
+
position: absolute;
|
|
37
|
+
width: ${right - left}px;
|
|
38
|
+
height: ${height}px;
|
|
39
|
+
top: ${top}px;
|
|
40
|
+
left: ${left}px;
|
|
41
|
+
opacity: 50%;
|
|
42
|
+
`;
|
|
43
|
+
return rectElt;
|
|
44
|
+
});
|
|
45
|
+
};
|
|
46
|
+
const getRangeFromSelection = (overlayElement, anchor, focus) => {
|
|
47
|
+
const range = overlayElement.ownerDocument.createRange();
|
|
48
|
+
const comparison = anchor.node.compareDocumentPosition(focus.node);
|
|
49
|
+
try {
|
|
50
|
+
if (comparison & Node.DOCUMENT_POSITION_PRECEDING) {
|
|
51
|
+
range.setStart(focus.node, focus.offset || 0);
|
|
52
|
+
range.setEnd(anchor.node, anchor.offset || 0);
|
|
53
|
+
} else if (comparison & Node.DOCUMENT_POSITION_FOLLOWING) {
|
|
54
|
+
range.setStart(anchor.node, anchor.offset || 0);
|
|
55
|
+
range.setEnd(focus.node, focus.offset || 0);
|
|
56
|
+
} else {
|
|
57
|
+
const startOffset = Math.min(anchor.offset || 0, focus.offset || 0);
|
|
58
|
+
const endOffset = Math.max(anchor.offset || 0, focus.offset || 0);
|
|
59
|
+
range.setStart(anchor.node, startOffset);
|
|
60
|
+
range.setEnd(anchor.node, endOffset);
|
|
61
|
+
}
|
|
62
|
+
} catch (e) {
|
|
63
|
+
report.error(e);
|
|
64
|
+
}
|
|
65
|
+
return range;
|
|
66
|
+
};
|
|
67
|
+
const copyPositionStyle = (source, target) => {
|
|
68
|
+
target.style.cssText = source.style.cssText;
|
|
69
|
+
};
|
|
70
|
+
const createAnnotationLayer = (container, layer) => {
|
|
71
|
+
const annotationLayer = container.ownerDocument.createElement("div");
|
|
72
|
+
layoutAnnotationLayer(layer, annotationLayer);
|
|
73
|
+
container.appendChild(annotationLayer);
|
|
74
|
+
return annotationLayer;
|
|
75
|
+
};
|
|
76
|
+
const layoutAnnotationLayer = (layer, annotationLayer) => {
|
|
77
|
+
copyPositionStyle(layer, annotationLayer);
|
|
78
|
+
if (layer.style.position === "") {
|
|
79
|
+
annotationLayer.style.position = "absolute";
|
|
80
|
+
annotationLayer.style.top = "0";
|
|
81
|
+
}
|
|
82
|
+
annotationLayer.style.opacity = "1";
|
|
83
|
+
annotationLayer.style.pointerEvents = "none";
|
|
84
|
+
};
|
|
85
|
+
|
|
86
|
+
class SpineItemHighlight extends DestroyableClass {
|
|
87
|
+
constructor(spineItem, containerElement, reader, highlight) {
|
|
88
|
+
super();
|
|
89
|
+
this.spineItem = spineItem;
|
|
90
|
+
this.containerElement = containerElement;
|
|
91
|
+
this.reader = reader;
|
|
92
|
+
this.highlight = highlight;
|
|
93
|
+
void this.spineItem;
|
|
94
|
+
this.container = this.containerElement.ownerDocument.createElement("div");
|
|
95
|
+
this.container.dataset["highlightContainer"] = this.highlight.id;
|
|
96
|
+
this.containerElement.appendChild(this.container);
|
|
97
|
+
this.tap$ = fromEvent(this.container, "click").pipe(
|
|
98
|
+
map((event) => ({ event, highlight: this.highlight })),
|
|
99
|
+
share()
|
|
100
|
+
);
|
|
101
|
+
this.render();
|
|
102
|
+
}
|
|
103
|
+
container;
|
|
104
|
+
tap$;
|
|
105
|
+
render() {
|
|
106
|
+
this.container.innerHTML = "";
|
|
107
|
+
const { node: anchorNode, offset: anchorOffset } = this.reader.cfi.resolveCfi({ cfi: this.highlight.anchorCfi ?? `` }) ?? {};
|
|
108
|
+
const { node: focusNode, offset: focusOffset } = this.reader.cfi.resolveCfi({ cfi: this.highlight.focusCfi ?? `` }) ?? {};
|
|
109
|
+
if (!anchorNode || !focusNode) {
|
|
110
|
+
report.error(`Unable to resolve anchor cfi: ${this.highlight.anchorCfi}`);
|
|
111
|
+
return;
|
|
112
|
+
}
|
|
113
|
+
const range = getRangeFromSelection(
|
|
114
|
+
this.containerElement,
|
|
115
|
+
{ node: anchorNode, offset: anchorOffset },
|
|
116
|
+
{ node: focusNode, offset: focusOffset }
|
|
117
|
+
);
|
|
118
|
+
const rectElements = getElementsForRange(range, this.container);
|
|
119
|
+
rectElements.forEach((elt) => {
|
|
120
|
+
elt.style.pointerEvents = "initial";
|
|
121
|
+
elt.style.cursor = "pointer";
|
|
122
|
+
elt.style.backgroundColor = this.highlight.color ?? "yellow";
|
|
123
|
+
elt.dataset["highlightRect"] = this.highlight.id;
|
|
124
|
+
this.container.appendChild(elt);
|
|
125
|
+
});
|
|
126
|
+
}
|
|
127
|
+
isWithinTarget(target) {
|
|
128
|
+
return this.container.contains(target);
|
|
129
|
+
}
|
|
130
|
+
destroy() {
|
|
131
|
+
super.destroy();
|
|
132
|
+
this.container.remove();
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
class SpineItemHighlights extends DestroyableClass {
|
|
137
|
+
constructor(annotations$, spineItem, reader) {
|
|
138
|
+
super();
|
|
139
|
+
this.annotations$ = annotations$;
|
|
140
|
+
this.spineItem = spineItem;
|
|
141
|
+
this.reader = reader;
|
|
142
|
+
const firstLayerElement = spineItem.renderer.layers[0]?.element ?? document.createElement("div");
|
|
143
|
+
this.layer = createAnnotationLayer(this.spineItem.containerElement, firstLayerElement);
|
|
144
|
+
const highlights$ = this.annotations$.pipe(
|
|
145
|
+
switchMap((annotations) => {
|
|
146
|
+
this.highlights.forEach((highlight) => highlight.destroy());
|
|
147
|
+
this.highlights = [];
|
|
148
|
+
annotations.forEach((annotation) => {
|
|
149
|
+
if (annotation.itemId !== this.spineItem.item.id) return;
|
|
150
|
+
this.highlights.push(new SpineItemHighlight(this.spineItem, this.layer, this.reader, annotation));
|
|
151
|
+
});
|
|
152
|
+
return of(this.highlights);
|
|
153
|
+
}),
|
|
154
|
+
shareReplay(1),
|
|
155
|
+
takeUntil(this.destroy$)
|
|
156
|
+
);
|
|
157
|
+
this.tap$ = highlights$.pipe(switchMap((highlights) => merge(...highlights.map((highlight) => highlight.tap$))));
|
|
158
|
+
highlights$.subscribe();
|
|
159
|
+
}
|
|
160
|
+
layer;
|
|
161
|
+
highlights = [];
|
|
162
|
+
tap$;
|
|
163
|
+
layout() {
|
|
164
|
+
const firstLayerElement = this.spineItem.renderer.layers[0]?.element ?? document.createElement("div");
|
|
165
|
+
layoutAnnotationLayer(firstLayerElement, this.layer);
|
|
166
|
+
this.highlights.forEach((highlight) => highlight.render());
|
|
167
|
+
}
|
|
168
|
+
getHighlightsForTarget(target) {
|
|
169
|
+
return this.highlights.filter((highlight) => target instanceof Node && highlight.isWithinTarget(target));
|
|
170
|
+
}
|
|
171
|
+
destroy() {
|
|
172
|
+
super.destroy();
|
|
173
|
+
this.layer.remove();
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
class ReaderHighlights extends DestroyableClass {
|
|
178
|
+
constructor(reader, highlights) {
|
|
179
|
+
super();
|
|
180
|
+
this.reader = reader;
|
|
181
|
+
this.highlights = highlights;
|
|
182
|
+
this.reader.hookManager.register("item.onDocumentLoad", ({ itemId, destroy }) => {
|
|
183
|
+
const spineItem = reader.spineItemsManager.get(itemId);
|
|
184
|
+
if (!spineItem) return;
|
|
185
|
+
const spineItemHighlights$ = this.highlights.pipe(
|
|
186
|
+
map((highlights2) => highlights2.filter((highlight) => highlight.itemId === itemId))
|
|
187
|
+
);
|
|
188
|
+
const spineItemHighlights = new SpineItemHighlights(spineItemHighlights$, spineItem, reader);
|
|
189
|
+
this.spineItemHighlights.next([...this.spineItemHighlights.getValue(), spineItemHighlights]);
|
|
190
|
+
const deregister = reader.hookManager.register("item.onAfterLayout", ({ item }) => {
|
|
191
|
+
if (item.id !== itemId) return;
|
|
192
|
+
spineItemHighlights.layout();
|
|
193
|
+
});
|
|
194
|
+
destroy(() => {
|
|
195
|
+
this.spineItemHighlights.next(this.spineItemHighlights.getValue().filter((layer) => layer !== spineItemHighlights));
|
|
196
|
+
spineItemHighlights.destroy();
|
|
197
|
+
deregister();
|
|
198
|
+
});
|
|
199
|
+
});
|
|
200
|
+
this.tap$ = this.spineItemHighlights.pipe(switchMap((layers) => merge(...layers.map((layer) => layer.tap$))));
|
|
201
|
+
}
|
|
202
|
+
spineItemHighlights = new BehaviorSubject([]);
|
|
203
|
+
tap$;
|
|
204
|
+
getHighlightsForTarget = (target) => {
|
|
205
|
+
return this.spineItemHighlights.getValue().flatMap((layer) => layer.getHighlightsForTarget(target)).map((annotation) => annotation.highlight);
|
|
206
|
+
};
|
|
207
|
+
isTargetWithinHighlight = (target) => {
|
|
208
|
+
return !!this.getHighlightsForTarget(target).length;
|
|
209
|
+
};
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
class Commands extends DestroyableClass {
|
|
213
|
+
commandSubject = new Subject();
|
|
214
|
+
highlight$ = this.commandSubject.pipe(filter((command) => command.type === "highlight"));
|
|
215
|
+
add$ = this.commandSubject.pipe(filter((command) => command.type === "add"));
|
|
216
|
+
delete$ = this.commandSubject.pipe(filter((command) => command.type === "delete"));
|
|
217
|
+
update$ = this.commandSubject.pipe(filter((command) => command.type === "update"));
|
|
218
|
+
highlight = (params) => {
|
|
219
|
+
this.commandSubject.next({ type: "highlight", data: params });
|
|
220
|
+
};
|
|
221
|
+
add = (data) => {
|
|
222
|
+
this.commandSubject.next({ type: "add", data });
|
|
223
|
+
};
|
|
224
|
+
delete = (id) => {
|
|
225
|
+
this.commandSubject.next({ type: "delete", id });
|
|
226
|
+
};
|
|
227
|
+
update = (id, data) => {
|
|
228
|
+
this.commandSubject.next({ type: "update", id, data });
|
|
229
|
+
};
|
|
230
|
+
destroy() {
|
|
231
|
+
super.destroy();
|
|
232
|
+
this.commandSubject.complete();
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
const annotationsEnhancer = (next) => (options) => {
|
|
237
|
+
const reader = next(options);
|
|
238
|
+
const commands = new Commands();
|
|
239
|
+
const highlightsSubject = new BehaviorSubject([]);
|
|
240
|
+
const highlight$ = commands.highlight$.pipe(
|
|
241
|
+
tap(({ data: { itemId, selection, ...rest } }) => {
|
|
242
|
+
const { anchorCfi, focusCfi } = reader.selection.generateCfis({ itemId, selection });
|
|
243
|
+
const annotation = { anchorCfi, focusCfi, itemId, id: window.crypto.randomUUID(), ...rest };
|
|
244
|
+
highlightsSubject.next([...highlightsSubject.getValue(), annotation]);
|
|
245
|
+
})
|
|
246
|
+
);
|
|
247
|
+
const add$ = commands.add$.pipe(
|
|
248
|
+
tap(({ data }) => {
|
|
249
|
+
const annotations = Array.isArray(data) ? data : [data];
|
|
250
|
+
highlightsSubject.next([...highlightsSubject.getValue(), ...annotations]);
|
|
251
|
+
})
|
|
252
|
+
);
|
|
253
|
+
const delete$ = commands.delete$.pipe(
|
|
254
|
+
tap(({ id }) => {
|
|
255
|
+
highlightsSubject.next(highlightsSubject.getValue().filter((highlight) => highlight.id !== id));
|
|
256
|
+
})
|
|
257
|
+
);
|
|
258
|
+
const update$ = commands.update$.pipe(
|
|
259
|
+
tap(({ id, data }) => {
|
|
260
|
+
highlightsSubject.next(
|
|
261
|
+
highlightsSubject.getValue().map((highlight) => highlight.id === id ? { ...highlight, ...data } : highlight)
|
|
262
|
+
);
|
|
263
|
+
})
|
|
264
|
+
);
|
|
265
|
+
const annotations$ = highlightsSubject.asObservable();
|
|
266
|
+
const readerHighlights = new ReaderHighlights(reader, highlightsSubject);
|
|
267
|
+
merge(
|
|
268
|
+
highlight$,
|
|
269
|
+
add$,
|
|
270
|
+
delete$,
|
|
271
|
+
update$,
|
|
272
|
+
annotations$.pipe(
|
|
273
|
+
tap((annotations) => {
|
|
274
|
+
report.debug("annotations", annotations);
|
|
275
|
+
})
|
|
276
|
+
)
|
|
277
|
+
).pipe(takeUntil(reader.$.destroy$)).subscribe();
|
|
278
|
+
return {
|
|
279
|
+
...reader,
|
|
280
|
+
destroy: () => {
|
|
281
|
+
highlightsSubject.complete();
|
|
282
|
+
commands.destroy();
|
|
283
|
+
readerHighlights.destroy();
|
|
284
|
+
reader.destroy();
|
|
285
|
+
},
|
|
286
|
+
annotations: {
|
|
287
|
+
annotations$,
|
|
288
|
+
highlightTap$: readerHighlights.tap$,
|
|
289
|
+
isTargetWithinHighlight: readerHighlights.isTargetWithinHighlight,
|
|
290
|
+
highlight: commands.highlight,
|
|
291
|
+
add: commands.add,
|
|
292
|
+
delete: commands.delete,
|
|
293
|
+
update: commands.update
|
|
294
|
+
}
|
|
295
|
+
};
|
|
296
|
+
};
|
|
297
|
+
|
|
298
|
+
export { annotationsEnhancer };
|
|
299
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sources":["../../shared/dist/index.js","../src/report.ts","../src/highlights/utils.ts","../src/highlights/SpineItemHighlight.ts","../src/highlights/SpineItemHighlights.ts","../src/highlights/ReaderHighlights.ts","../src/Commands.ts","../src/annotationsEnhancer.ts"],"sourcesContent":["const f = (e) => {\n var n, t;\n return ((t = (n = e.split(/[#?]/)[0]) == null ? void 0 : n.split(\".\").pop()) == null ? void 0 : t.trim()) || \"\";\n};\nfunction a(e) {\n const n = [];\n if (e.length === 0)\n return \"\";\n if (typeof e[0] != \"string\")\n throw new TypeError(\"Url must be a string. Received \" + e[0]);\n e[0].match(/^[^/:]+:\\/*$/) && e.length > 1 && (e[0] = e.shift() + e[0]), e[0].match(/^file:\\/\\/\\//) ? e[0] = e[0].replace(/^([^/:]+):\\/*/, \"$1:///\") : e[0] = e[0].replace(/^([^/:]+):\\/*/, \"$1://\");\n for (let l = 0; l < e.length; l++) {\n let r = e[l];\n if (typeof r != \"string\")\n throw new TypeError(\"Url must be a string. Received \" + r);\n r !== \"\" && (l > 0 && (r = r.replace(/^[/]+/, \"\")), l < e.length - 1 ? r = r.replace(/[/]+$/, \"\") : r = r.replace(/[/]+$/, \"/\"), n.push(r));\n }\n let t = n.join(\"/\");\n t = t.replace(/\\/(\\?|&|#[^!])/g, \"$1\");\n const o = t.split(\"?\");\n return t = o.shift() + (o.length > 0 ? \"?\" : \"\") + o.join(\"&\"), t;\n}\nfunction d(...e) {\n const n = Array.from(Array.isArray(e[0]) ? e[0] : e);\n return a(n);\n}\nconst E = (e) => {\n switch (f(e)) {\n case \"png\":\n return \"image/png\";\n case \"jpg\":\n return \"image/jpg\";\n case \"jpeg\":\n return \"image/jpeg\";\n case \"txt\":\n return \"text/plain\";\n case \"webp\":\n return \"image/webp\";\n case \"xhtml\":\n return \"application/xhtml+xml\";\n }\n}, R = ({ mimeType: e, uri: n }) => {\n const t = e ?? E(n ?? \"\");\n return t == null ? void 0 : t.startsWith(\"application/xhtml+xml\");\n}, w = (e) => e.length ? e.indexOf(\";\") ? e.substring(0, e.indexOf(\";\")) : e : void 0, _ = \"prose-reader-resource-error\", g = Object.prototype.hasOwnProperty, h = (e, n) => e === n ? e !== 0 || n !== 0 || 1 / e === 1 / n : !1, m = (e, n, t) => {\n if (e === n)\n return !0;\n if (typeof e != \"object\" || e === null || typeof n != \"object\" || n === null)\n return !1;\n const o = Object.keys(e), l = Object.keys(n);\n if (o.length !== l.length)\n return !1;\n const r = t && typeof t.customEqual == \"function\" ? t.customEqual : h;\n for (let s = 0; s < o.length; s++) {\n const u = o[s] || \"\";\n if (!g.call(n, u) || !r(e[u], n[u]))\n return !1;\n }\n return !0;\n}, O = (e, n) => e.reduce(\n (t, o) => {\n const l = n(o);\n return t[l] || (t[l] = []), t[l].push(o), t;\n },\n {}\n);\nfunction y(e, n) {\n const t = { ...e };\n for (const o in n)\n if (Object.prototype.hasOwnProperty.call(n, o)) {\n const l = n[o];\n (l !== void 0 || !(o in e)) && (t[o] = l);\n }\n return t;\n}\nconst c = \"@prose-reader\", i = (e) => `[${e}]`, p = (e, n) => ({\n debug: !n || (window == null ? void 0 : window.__PROSE_READER_DEBUG) !== !0 ? () => {\n } : e ? Function.prototype.bind.call(console.debug, console, i(`${c}`), i(e)) : Function.prototype.bind.call(console.debug, console, i(`${c}`)),\n info: !n || (window == null ? void 0 : window.__PROSE_READER_DEBUG) !== !0 ? () => {\n } : e ? Function.prototype.bind.call(console.info, console, i(`${c}`), i(e)) : Function.prototype.bind.call(console.info, console, i(`${c}`)),\n error: !n || (window == null ? void 0 : window.__PROSE_READER_DEBUG) !== !0 ? () => {\n } : e ? Function.prototype.bind.call(console.error, console, i(`${c}`), i(e)) : Function.prototype.bind.call(console.error, console, i(`${c}`))\n}), $ = {\n ...p(),\n namespace: (e, n) => p(e, n)\n};\nexport {\n _ as PROSE_READER_RESOURCE_ERROR_INJECTED_META_NAME,\n $ as Report,\n E as detectMimeTypeFromName,\n f as getUrlExtension,\n O as groupBy,\n h as is,\n m as isShallowEqual,\n R as isXmlBasedMimeType,\n w as parseContentType,\n y as shallowMergeIfDefined,\n d as urlJoin\n};\n//# sourceMappingURL=index.js.map\n","import { Report } from \"@prose-reader/shared\"\n\nconst IS_DEBUG_ENABLED = true\n\nexport const report = Report.namespace(`enhancer-annotations`, IS_DEBUG_ENABLED)\n","import { report } from \"../report\"\n\nexport const getElementsForRange = (range: Range, container: HTMLElement) => {\n // Get all rects and group them by line (based on vertical position)\n const rects = Array.from(range.getClientRects())\n const lineGroups = new Map<number, DOMRect[]>()\n\n rects.forEach((rect) => {\n const lineY = Math.round(rect.top) // Round to handle minor pixel differences\n if (!lineGroups.has(lineY)) {\n lineGroups.set(lineY, [])\n }\n lineGroups.get(lineY)?.push(rect)\n })\n\n // Create one highlight element per line\n return Array.from(lineGroups.values()).map((lineRects) => {\n // Find the leftmost and rightmost points\n const left = Math.min(...lineRects.map((r) => r.left))\n const right = Math.max(...lineRects.map((r) => r.right))\n const top = lineRects[0]?.top\n const height = lineRects[0]?.height\n\n const rectElt = container.ownerDocument.createElement(\"div\")\n rectElt.style.cssText = `\n position: absolute;\n width: ${right - left}px;\n height: ${height}px;\n top: ${top}px;\n left: ${left}px;\n opacity: 50%;\n `\n\n return rectElt\n })\n}\n\nexport const getRangeFromSelection = (\n overlayElement: HTMLElement,\n anchor: { node: Node; offset?: number },\n focus: { node: Node; offset?: number },\n) => {\n const range = overlayElement.ownerDocument.createRange()\n const comparison = anchor.node.compareDocumentPosition(focus.node)\n\n try {\n // If focus comes before anchor in the document\n if (comparison & Node.DOCUMENT_POSITION_PRECEDING) {\n range.setStart(focus.node, focus.offset || 0)\n range.setEnd(anchor.node, anchor.offset || 0)\n // If focus comes after anchor in the document\n } else if (comparison & Node.DOCUMENT_POSITION_FOLLOWING) {\n range.setStart(anchor.node, anchor.offset || 0)\n range.setEnd(focus.node, focus.offset || 0)\n }\n // If they're the same node\n else {\n const startOffset = Math.min(anchor.offset || 0, focus.offset || 0)\n const endOffset = Math.max(anchor.offset || 0, focus.offset || 0)\n range.setStart(anchor.node, startOffset)\n range.setEnd(anchor.node, endOffset)\n }\n } catch (e) {\n report.error(e)\n }\n\n return range\n}\n\nexport const copyPositionStyle = (source: HTMLElement, target: HTMLElement) => {\n target.style.cssText = source.style.cssText\n}\n\nexport const createAnnotationLayer = (container: HTMLElement, layer: HTMLElement) => {\n const annotationLayer = container.ownerDocument.createElement(\"div\")\n\n layoutAnnotationLayer(layer, annotationLayer)\n\n container.appendChild(annotationLayer)\n\n return annotationLayer\n}\n\nexport const layoutAnnotationLayer = (layer: HTMLElement, annotationLayer: HTMLElement) => {\n copyPositionStyle(layer, annotationLayer)\n\n if (layer.style.position === \"\") {\n annotationLayer.style.position = \"absolute\"\n annotationLayer.style.top = \"0\"\n }\n\n// annotationLayer.style.backgroundColor = \"red\"\n annotationLayer.style.opacity = \"1\"\n annotationLayer.style.pointerEvents = \"none\"\n}\n","import { DestroyableClass, Reader, SpineItem } from \"@prose-reader/core\"\nimport { RuntimeHighlight } from \"../types\"\nimport { getElementsForRange, getRangeFromSelection } from \"./utils\"\nimport { report } from \"../report\"\nimport { fromEvent, map, Observable, share } from \"rxjs\"\n\nexport class SpineItemHighlight extends DestroyableClass {\n private container: HTMLElement\n\n public readonly tap$: Observable<{ event: Event; highlight: RuntimeHighlight }>\n\n constructor(\n private spineItem: SpineItem,\n private containerElement: HTMLElement,\n private reader: Reader,\n public readonly highlight: RuntimeHighlight,\n ) {\n super()\n\n void this.spineItem\n\n this.container = this.containerElement.ownerDocument.createElement(\"div\")\n this.container.dataset[\"highlightContainer\"] = this.highlight.id\n this.containerElement.appendChild(this.container)\n\n this.tap$ = fromEvent(this.container, \"click\").pipe(\n map((event) => ({ event, highlight: this.highlight })),\n share(),\n )\n\n this.render()\n }\n\n public render() {\n this.container.innerHTML = \"\"\n\n const { node: anchorNode, offset: anchorOffset } = this.reader.cfi.resolveCfi({ cfi: this.highlight.anchorCfi ?? `` }) ?? {}\n const { node: focusNode, offset: focusOffset } = this.reader.cfi.resolveCfi({ cfi: this.highlight.focusCfi ?? `` }) ?? {}\n\n if (!anchorNode || !focusNode) {\n report.error(`Unable to resolve anchor cfi: ${this.highlight.anchorCfi}`)\n\n return\n }\n\n const range = getRangeFromSelection(\n this.containerElement,\n { node: anchorNode, offset: anchorOffset },\n { node: focusNode, offset: focusOffset },\n )\n\n const rectElements = getElementsForRange(range, this.container)\n\n rectElements.forEach((elt) => {\n elt.style.pointerEvents = \"initial\"\n elt.style.cursor = \"pointer\"\n elt.style.backgroundColor = this.highlight.color ?? \"yellow\"\n elt.dataset[\"highlightRect\"] = this.highlight.id\n\n this.container.appendChild(elt)\n })\n }\n\n isWithinTarget(target: Node) {\n return this.container.contains(target)\n }\n\n public destroy() {\n super.destroy()\n\n this.container.remove()\n }\n}\n","import { merge, Observable, of, shareReplay, switchMap, takeUntil } from \"rxjs\"\nimport { RuntimeHighlight } from \"../types\"\nimport { DestroyableClass, Reader, SpineItem } from \"@prose-reader/core\"\nimport { SpineItemHighlight } from \"./SpineItemHighlight\"\nimport { createAnnotationLayer, layoutAnnotationLayer } from \"./utils\"\n\nexport class SpineItemHighlights extends DestroyableClass {\n private layer: HTMLElement\n private highlights: SpineItemHighlight[] = []\n\n public readonly tap$: SpineItemHighlight[\"tap$\"]\n\n constructor(\n private annotations$: Observable<RuntimeHighlight[]>,\n private spineItem: SpineItem,\n private reader: Reader,\n ) {\n super()\n\n const firstLayerElement = spineItem.renderer.layers[0]?.element ?? document.createElement(\"div\")\n\n this.layer = createAnnotationLayer(this.spineItem.containerElement, firstLayerElement)\n\n const highlights$ = this.annotations$.pipe(\n switchMap((annotations) => {\n this.highlights.forEach((highlight) => highlight.destroy())\n this.highlights = []\n\n annotations.forEach((annotation) => {\n if (annotation.itemId !== this.spineItem.item.id) return\n\n this.highlights.push(new SpineItemHighlight(this.spineItem, this.layer, this.reader, annotation))\n })\n\n return of(this.highlights)\n }),\n shareReplay(1),\n takeUntil(this.destroy$),\n )\n\n this.tap$ = highlights$.pipe(switchMap((highlights) => merge(...highlights.map((highlight) => highlight.tap$))))\n\n highlights$.subscribe()\n }\n\n layout() {\n const firstLayerElement = this.spineItem.renderer.layers[0]?.element ?? document.createElement(\"div\")\n\n layoutAnnotationLayer(firstLayerElement, this.layer)\n\n this.highlights.forEach((highlight) => highlight.render())\n }\n\n getHighlightsForTarget(target: EventTarget) {\n return this.highlights.filter((highlight) => target instanceof Node && highlight.isWithinTarget(target))\n }\n\n destroy() {\n super.destroy()\n\n this.layer.remove()\n }\n}\n","import { DestroyableClass, Reader } from \"@prose-reader/core\"\nimport { BehaviorSubject, map, merge, switchMap } from \"rxjs\"\nimport { Highlight } from \"../types\"\nimport { SpineItemHighlights } from \"./SpineItemHighlights\"\n\nexport class ReaderHighlights extends DestroyableClass {\n private spineItemHighlights = new BehaviorSubject<SpineItemHighlights[]>([])\n\n public tap$: SpineItemHighlights[\"tap$\"]\n\n constructor(\n private reader: Reader,\n private highlights: BehaviorSubject<Highlight[]>,\n ) {\n super()\n\n this.reader.hookManager.register(\"item.onDocumentLoad\", ({ itemId, destroy }) => {\n const spineItem = reader.spineItemsManager.get(itemId)\n\n if (!spineItem) return\n\n const spineItemHighlights$ = this.highlights.pipe(\n map((highlights) => highlights.filter((highlight) => highlight.itemId === itemId)),\n )\n\n const spineItemHighlights = new SpineItemHighlights(spineItemHighlights$, spineItem, reader)\n\n this.spineItemHighlights.next([...this.spineItemHighlights.getValue(), spineItemHighlights])\n\n const deregister = reader.hookManager.register(\"item.onAfterLayout\", ({ item }) => {\n if (item.id !== itemId) return\n\n spineItemHighlights.layout()\n })\n\n destroy(() => {\n this.spineItemHighlights.next(this.spineItemHighlights.getValue().filter((layer) => layer !== spineItemHighlights))\n\n spineItemHighlights.destroy()\n\n deregister()\n })\n })\n\n this.tap$ = this.spineItemHighlights.pipe(switchMap((layers) => merge(...layers.map((layer) => layer.tap$))))\n }\n\n getHighlightsForTarget = (target: EventTarget) => {\n return this.spineItemHighlights\n .getValue()\n .flatMap((layer) => layer.getHighlightsForTarget(target))\n .map((annotation) => annotation.highlight)\n }\n\n isTargetWithinHighlight = (target: EventTarget) => {\n return !!this.getHighlightsForTarget(target).length\n }\n}\n","import { DestroyableClass } from \"@prose-reader/core\"\nimport { filter, Subject } from \"rxjs\"\nimport { Highlight } from \"./types\"\n\ntype HighlightParams = { document: Document; selection: Selection; itemId: string; color?: string; contents?: string[] }\n\ntype Command =\n | { type: \"highlight\"; data: HighlightParams }\n | { type: \"add\"; data: Highlight | Highlight[] }\n | { type: \"delete\"; id: string }\n | { type: \"update\"; id: string; data: Pick<HighlightParams, \"color\" | \"contents\"> }\n\nexport class Commands extends DestroyableClass {\n private commandSubject = new Subject<Command>()\n\n public readonly highlight$ = this.commandSubject.pipe(filter((command) => command.type === \"highlight\"))\n public readonly add$ = this.commandSubject.pipe(filter((command) => command.type === \"add\"))\n public readonly delete$ = this.commandSubject.pipe(filter((command) => command.type === \"delete\"))\n public readonly update$ = this.commandSubject.pipe(filter((command) => command.type === \"update\"))\n\n highlight = (params: HighlightParams) => {\n this.commandSubject.next({ type: \"highlight\", data: params })\n }\n\n add = (data: Highlight | Highlight[]) => {\n this.commandSubject.next({ type: \"add\", data })\n }\n\n delete = (id: string) => {\n this.commandSubject.next({ type: \"delete\", id })\n }\n\n update = (id: string, data: Pick<HighlightParams, \"color\" | \"contents\">) => {\n this.commandSubject.next({ type: \"update\", id, data })\n }\n\n destroy() {\n super.destroy()\n this.commandSubject.complete()\n }\n}\n","import { Reader } from \"@prose-reader/core\"\nimport { BehaviorSubject, merge, takeUntil, tap, Observable } from \"rxjs\"\nimport { report } from \"./report\"\nimport { RuntimeHighlight } from \"./types\"\nimport { ReaderHighlights } from \"./highlights/ReaderHighlights\"\nimport { Commands } from \"./Commands\"\n\nexport const annotationsEnhancer =\n <InheritOptions, InheritOutput extends Reader>(next: (options: InheritOptions) => InheritOutput) =>\n (\n options: InheritOptions,\n ): InheritOutput & {\n annotations: {\n annotations$: Observable<RuntimeHighlight[]>\n highlightTap$: ReaderHighlights[\"tap$\"]\n highlight: Commands[\"highlight\"]\n add: Commands[\"add\"]\n delete: Commands[\"delete\"]\n update: Commands[\"update\"]\n isTargetWithinHighlight: (target: EventTarget) => boolean\n }\n } => {\n const reader = next(options)\n const commands = new Commands()\n const highlightsSubject = new BehaviorSubject<RuntimeHighlight[]>([])\n\n const highlight$ = commands.highlight$.pipe(\n tap(({ data: { itemId, selection, ...rest } }) => {\n const { anchorCfi, focusCfi } = reader.selection.generateCfis({ itemId, selection })\n\n const annotation = { anchorCfi, focusCfi, itemId, id: window.crypto.randomUUID(), ...rest }\n\n highlightsSubject.next([...highlightsSubject.getValue(), annotation])\n }),\n )\n\n const add$ = commands.add$.pipe(\n tap(({ data }) => {\n const annotations = Array.isArray(data) ? data : [data]\n\n highlightsSubject.next([...highlightsSubject.getValue(), ...annotations])\n }),\n )\n\n const delete$ = commands.delete$.pipe(\n tap(({ id }) => {\n highlightsSubject.next(highlightsSubject.getValue().filter((highlight) => highlight.id !== id))\n }),\n )\n\n const update$ = commands.update$.pipe(\n tap(({ id, data }) => {\n highlightsSubject.next(\n highlightsSubject.getValue().map((highlight) => (highlight.id === id ? { ...highlight, ...data } : highlight)),\n )\n }),\n )\n\n const annotations$ = highlightsSubject.asObservable()\n\n const readerHighlights = new ReaderHighlights(reader, highlightsSubject)\n\n merge(\n highlight$,\n add$,\n delete$,\n update$,\n annotations$.pipe(\n tap((annotations) => {\n report.debug(\"annotations\", annotations)\n }),\n ),\n )\n .pipe(takeUntil(reader.$.destroy$))\n .subscribe()\n\n return {\n ...reader,\n destroy: () => {\n highlightsSubject.complete()\n commands.destroy()\n readerHighlights.destroy()\n reader.destroy()\n },\n annotations: {\n annotations$,\n highlightTap$: readerHighlights.tap$,\n isTargetWithinHighlight: readerHighlights.isTargetWithinHighlight,\n highlight: commands.highlight,\n add: commands.add,\n delete: commands.delete,\n update: commands.update,\n },\n }\n }\n"],"names":["Report","highlights"],"mappings":"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"}
|
|
@@ -0,0 +1,306 @@
|
|
|
1
|
+
(function (global, factory) {
|
|
2
|
+
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('rxjs'), require('@prose-reader/core')) :
|
|
3
|
+
typeof define === 'function' && define.amd ? define(['exports', 'rxjs', '@prose-reader/core'], factory) :
|
|
4
|
+
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global["prose-reader-enhancer-annotations"] = {}, global.rxjs, global.core));
|
|
5
|
+
})(this, (function (exports, rxjs, core) { 'use strict';
|
|
6
|
+
|
|
7
|
+
const c = "@prose-reader", i = (e) => `[${e}]`, p = (e, n) => ({
|
|
8
|
+
debug: !n || (window == null ? void 0 : window.__PROSE_READER_DEBUG) !== !0 ? () => {
|
|
9
|
+
} : e ? Function.prototype.bind.call(console.debug, console, i(`${c}`), i(e)) : Function.prototype.bind.call(console.debug, console, i(`${c}`)),
|
|
10
|
+
info: !n || (window == null ? void 0 : window.__PROSE_READER_DEBUG) !== !0 ? () => {
|
|
11
|
+
} : e ? Function.prototype.bind.call(console.info, console, i(`${c}`), i(e)) : Function.prototype.bind.call(console.info, console, i(`${c}`)),
|
|
12
|
+
error: !n || (window == null ? void 0 : window.__PROSE_READER_DEBUG) !== !0 ? () => {
|
|
13
|
+
} : e ? Function.prototype.bind.call(console.error, console, i(`${c}`), i(e)) : Function.prototype.bind.call(console.error, console, i(`${c}`))
|
|
14
|
+
}), $ = {
|
|
15
|
+
...p(),
|
|
16
|
+
namespace: (e, n) => p(e, n)
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
const IS_DEBUG_ENABLED = true;
|
|
20
|
+
const report = $.namespace(`enhancer-annotations`, IS_DEBUG_ENABLED);
|
|
21
|
+
|
|
22
|
+
const getElementsForRange = (range, container) => {
|
|
23
|
+
const rects = Array.from(range.getClientRects());
|
|
24
|
+
const lineGroups = /* @__PURE__ */ new Map();
|
|
25
|
+
rects.forEach((rect) => {
|
|
26
|
+
const lineY = Math.round(rect.top);
|
|
27
|
+
if (!lineGroups.has(lineY)) {
|
|
28
|
+
lineGroups.set(lineY, []);
|
|
29
|
+
}
|
|
30
|
+
lineGroups.get(lineY)?.push(rect);
|
|
31
|
+
});
|
|
32
|
+
return Array.from(lineGroups.values()).map((lineRects) => {
|
|
33
|
+
const left = Math.min(...lineRects.map((r) => r.left));
|
|
34
|
+
const right = Math.max(...lineRects.map((r) => r.right));
|
|
35
|
+
const top = lineRects[0]?.top;
|
|
36
|
+
const height = lineRects[0]?.height;
|
|
37
|
+
const rectElt = container.ownerDocument.createElement("div");
|
|
38
|
+
rectElt.style.cssText = `
|
|
39
|
+
position: absolute;
|
|
40
|
+
width: ${right - left}px;
|
|
41
|
+
height: ${height}px;
|
|
42
|
+
top: ${top}px;
|
|
43
|
+
left: ${left}px;
|
|
44
|
+
opacity: 50%;
|
|
45
|
+
`;
|
|
46
|
+
return rectElt;
|
|
47
|
+
});
|
|
48
|
+
};
|
|
49
|
+
const getRangeFromSelection = (overlayElement, anchor, focus) => {
|
|
50
|
+
const range = overlayElement.ownerDocument.createRange();
|
|
51
|
+
const comparison = anchor.node.compareDocumentPosition(focus.node);
|
|
52
|
+
try {
|
|
53
|
+
if (comparison & Node.DOCUMENT_POSITION_PRECEDING) {
|
|
54
|
+
range.setStart(focus.node, focus.offset || 0);
|
|
55
|
+
range.setEnd(anchor.node, anchor.offset || 0);
|
|
56
|
+
} else if (comparison & Node.DOCUMENT_POSITION_FOLLOWING) {
|
|
57
|
+
range.setStart(anchor.node, anchor.offset || 0);
|
|
58
|
+
range.setEnd(focus.node, focus.offset || 0);
|
|
59
|
+
} else {
|
|
60
|
+
const startOffset = Math.min(anchor.offset || 0, focus.offset || 0);
|
|
61
|
+
const endOffset = Math.max(anchor.offset || 0, focus.offset || 0);
|
|
62
|
+
range.setStart(anchor.node, startOffset);
|
|
63
|
+
range.setEnd(anchor.node, endOffset);
|
|
64
|
+
}
|
|
65
|
+
} catch (e) {
|
|
66
|
+
report.error(e);
|
|
67
|
+
}
|
|
68
|
+
return range;
|
|
69
|
+
};
|
|
70
|
+
const copyPositionStyle = (source, target) => {
|
|
71
|
+
target.style.cssText = source.style.cssText;
|
|
72
|
+
};
|
|
73
|
+
const createAnnotationLayer = (container, layer) => {
|
|
74
|
+
const annotationLayer = container.ownerDocument.createElement("div");
|
|
75
|
+
layoutAnnotationLayer(layer, annotationLayer);
|
|
76
|
+
container.appendChild(annotationLayer);
|
|
77
|
+
return annotationLayer;
|
|
78
|
+
};
|
|
79
|
+
const layoutAnnotationLayer = (layer, annotationLayer) => {
|
|
80
|
+
copyPositionStyle(layer, annotationLayer);
|
|
81
|
+
if (layer.style.position === "") {
|
|
82
|
+
annotationLayer.style.position = "absolute";
|
|
83
|
+
annotationLayer.style.top = "0";
|
|
84
|
+
}
|
|
85
|
+
annotationLayer.style.opacity = "1";
|
|
86
|
+
annotationLayer.style.pointerEvents = "none";
|
|
87
|
+
};
|
|
88
|
+
|
|
89
|
+
class SpineItemHighlight extends core.DestroyableClass {
|
|
90
|
+
constructor(spineItem, containerElement, reader, highlight) {
|
|
91
|
+
super();
|
|
92
|
+
this.spineItem = spineItem;
|
|
93
|
+
this.containerElement = containerElement;
|
|
94
|
+
this.reader = reader;
|
|
95
|
+
this.highlight = highlight;
|
|
96
|
+
void this.spineItem;
|
|
97
|
+
this.container = this.containerElement.ownerDocument.createElement("div");
|
|
98
|
+
this.container.dataset["highlightContainer"] = this.highlight.id;
|
|
99
|
+
this.containerElement.appendChild(this.container);
|
|
100
|
+
this.tap$ = rxjs.fromEvent(this.container, "click").pipe(
|
|
101
|
+
rxjs.map((event) => ({ event, highlight: this.highlight })),
|
|
102
|
+
rxjs.share()
|
|
103
|
+
);
|
|
104
|
+
this.render();
|
|
105
|
+
}
|
|
106
|
+
container;
|
|
107
|
+
tap$;
|
|
108
|
+
render() {
|
|
109
|
+
this.container.innerHTML = "";
|
|
110
|
+
const { node: anchorNode, offset: anchorOffset } = this.reader.cfi.resolveCfi({ cfi: this.highlight.anchorCfi ?? `` }) ?? {};
|
|
111
|
+
const { node: focusNode, offset: focusOffset } = this.reader.cfi.resolveCfi({ cfi: this.highlight.focusCfi ?? `` }) ?? {};
|
|
112
|
+
if (!anchorNode || !focusNode) {
|
|
113
|
+
report.error(`Unable to resolve anchor cfi: ${this.highlight.anchorCfi}`);
|
|
114
|
+
return;
|
|
115
|
+
}
|
|
116
|
+
const range = getRangeFromSelection(
|
|
117
|
+
this.containerElement,
|
|
118
|
+
{ node: anchorNode, offset: anchorOffset },
|
|
119
|
+
{ node: focusNode, offset: focusOffset }
|
|
120
|
+
);
|
|
121
|
+
const rectElements = getElementsForRange(range, this.container);
|
|
122
|
+
rectElements.forEach((elt) => {
|
|
123
|
+
elt.style.pointerEvents = "initial";
|
|
124
|
+
elt.style.cursor = "pointer";
|
|
125
|
+
elt.style.backgroundColor = this.highlight.color ?? "yellow";
|
|
126
|
+
elt.dataset["highlightRect"] = this.highlight.id;
|
|
127
|
+
this.container.appendChild(elt);
|
|
128
|
+
});
|
|
129
|
+
}
|
|
130
|
+
isWithinTarget(target) {
|
|
131
|
+
return this.container.contains(target);
|
|
132
|
+
}
|
|
133
|
+
destroy() {
|
|
134
|
+
super.destroy();
|
|
135
|
+
this.container.remove();
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
class SpineItemHighlights extends core.DestroyableClass {
|
|
140
|
+
constructor(annotations$, spineItem, reader) {
|
|
141
|
+
super();
|
|
142
|
+
this.annotations$ = annotations$;
|
|
143
|
+
this.spineItem = spineItem;
|
|
144
|
+
this.reader = reader;
|
|
145
|
+
const firstLayerElement = spineItem.renderer.layers[0]?.element ?? document.createElement("div");
|
|
146
|
+
this.layer = createAnnotationLayer(this.spineItem.containerElement, firstLayerElement);
|
|
147
|
+
const highlights$ = this.annotations$.pipe(
|
|
148
|
+
rxjs.switchMap((annotations) => {
|
|
149
|
+
this.highlights.forEach((highlight) => highlight.destroy());
|
|
150
|
+
this.highlights = [];
|
|
151
|
+
annotations.forEach((annotation) => {
|
|
152
|
+
if (annotation.itemId !== this.spineItem.item.id) return;
|
|
153
|
+
this.highlights.push(new SpineItemHighlight(this.spineItem, this.layer, this.reader, annotation));
|
|
154
|
+
});
|
|
155
|
+
return rxjs.of(this.highlights);
|
|
156
|
+
}),
|
|
157
|
+
rxjs.shareReplay(1),
|
|
158
|
+
rxjs.takeUntil(this.destroy$)
|
|
159
|
+
);
|
|
160
|
+
this.tap$ = highlights$.pipe(rxjs.switchMap((highlights) => rxjs.merge(...highlights.map((highlight) => highlight.tap$))));
|
|
161
|
+
highlights$.subscribe();
|
|
162
|
+
}
|
|
163
|
+
layer;
|
|
164
|
+
highlights = [];
|
|
165
|
+
tap$;
|
|
166
|
+
layout() {
|
|
167
|
+
const firstLayerElement = this.spineItem.renderer.layers[0]?.element ?? document.createElement("div");
|
|
168
|
+
layoutAnnotationLayer(firstLayerElement, this.layer);
|
|
169
|
+
this.highlights.forEach((highlight) => highlight.render());
|
|
170
|
+
}
|
|
171
|
+
getHighlightsForTarget(target) {
|
|
172
|
+
return this.highlights.filter((highlight) => target instanceof Node && highlight.isWithinTarget(target));
|
|
173
|
+
}
|
|
174
|
+
destroy() {
|
|
175
|
+
super.destroy();
|
|
176
|
+
this.layer.remove();
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
class ReaderHighlights extends core.DestroyableClass {
|
|
181
|
+
constructor(reader, highlights) {
|
|
182
|
+
super();
|
|
183
|
+
this.reader = reader;
|
|
184
|
+
this.highlights = highlights;
|
|
185
|
+
this.reader.hookManager.register("item.onDocumentLoad", ({ itemId, destroy }) => {
|
|
186
|
+
const spineItem = reader.spineItemsManager.get(itemId);
|
|
187
|
+
if (!spineItem) return;
|
|
188
|
+
const spineItemHighlights$ = this.highlights.pipe(
|
|
189
|
+
rxjs.map((highlights2) => highlights2.filter((highlight) => highlight.itemId === itemId))
|
|
190
|
+
);
|
|
191
|
+
const spineItemHighlights = new SpineItemHighlights(spineItemHighlights$, spineItem, reader);
|
|
192
|
+
this.spineItemHighlights.next([...this.spineItemHighlights.getValue(), spineItemHighlights]);
|
|
193
|
+
const deregister = reader.hookManager.register("item.onAfterLayout", ({ item }) => {
|
|
194
|
+
if (item.id !== itemId) return;
|
|
195
|
+
spineItemHighlights.layout();
|
|
196
|
+
});
|
|
197
|
+
destroy(() => {
|
|
198
|
+
this.spineItemHighlights.next(this.spineItemHighlights.getValue().filter((layer) => layer !== spineItemHighlights));
|
|
199
|
+
spineItemHighlights.destroy();
|
|
200
|
+
deregister();
|
|
201
|
+
});
|
|
202
|
+
});
|
|
203
|
+
this.tap$ = this.spineItemHighlights.pipe(rxjs.switchMap((layers) => rxjs.merge(...layers.map((layer) => layer.tap$))));
|
|
204
|
+
}
|
|
205
|
+
spineItemHighlights = new rxjs.BehaviorSubject([]);
|
|
206
|
+
tap$;
|
|
207
|
+
getHighlightsForTarget = (target) => {
|
|
208
|
+
return this.spineItemHighlights.getValue().flatMap((layer) => layer.getHighlightsForTarget(target)).map((annotation) => annotation.highlight);
|
|
209
|
+
};
|
|
210
|
+
isTargetWithinHighlight = (target) => {
|
|
211
|
+
return !!this.getHighlightsForTarget(target).length;
|
|
212
|
+
};
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
class Commands extends core.DestroyableClass {
|
|
216
|
+
commandSubject = new rxjs.Subject();
|
|
217
|
+
highlight$ = this.commandSubject.pipe(rxjs.filter((command) => command.type === "highlight"));
|
|
218
|
+
add$ = this.commandSubject.pipe(rxjs.filter((command) => command.type === "add"));
|
|
219
|
+
delete$ = this.commandSubject.pipe(rxjs.filter((command) => command.type === "delete"));
|
|
220
|
+
update$ = this.commandSubject.pipe(rxjs.filter((command) => command.type === "update"));
|
|
221
|
+
highlight = (params) => {
|
|
222
|
+
this.commandSubject.next({ type: "highlight", data: params });
|
|
223
|
+
};
|
|
224
|
+
add = (data) => {
|
|
225
|
+
this.commandSubject.next({ type: "add", data });
|
|
226
|
+
};
|
|
227
|
+
delete = (id) => {
|
|
228
|
+
this.commandSubject.next({ type: "delete", id });
|
|
229
|
+
};
|
|
230
|
+
update = (id, data) => {
|
|
231
|
+
this.commandSubject.next({ type: "update", id, data });
|
|
232
|
+
};
|
|
233
|
+
destroy() {
|
|
234
|
+
super.destroy();
|
|
235
|
+
this.commandSubject.complete();
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
const annotationsEnhancer = (next) => (options) => {
|
|
240
|
+
const reader = next(options);
|
|
241
|
+
const commands = new Commands();
|
|
242
|
+
const highlightsSubject = new rxjs.BehaviorSubject([]);
|
|
243
|
+
const highlight$ = commands.highlight$.pipe(
|
|
244
|
+
rxjs.tap(({ data: { itemId, selection, ...rest } }) => {
|
|
245
|
+
const { anchorCfi, focusCfi } = reader.selection.generateCfis({ itemId, selection });
|
|
246
|
+
const annotation = { anchorCfi, focusCfi, itemId, id: window.crypto.randomUUID(), ...rest };
|
|
247
|
+
highlightsSubject.next([...highlightsSubject.getValue(), annotation]);
|
|
248
|
+
})
|
|
249
|
+
);
|
|
250
|
+
const add$ = commands.add$.pipe(
|
|
251
|
+
rxjs.tap(({ data }) => {
|
|
252
|
+
const annotations = Array.isArray(data) ? data : [data];
|
|
253
|
+
highlightsSubject.next([...highlightsSubject.getValue(), ...annotations]);
|
|
254
|
+
})
|
|
255
|
+
);
|
|
256
|
+
const delete$ = commands.delete$.pipe(
|
|
257
|
+
rxjs.tap(({ id }) => {
|
|
258
|
+
highlightsSubject.next(highlightsSubject.getValue().filter((highlight) => highlight.id !== id));
|
|
259
|
+
})
|
|
260
|
+
);
|
|
261
|
+
const update$ = commands.update$.pipe(
|
|
262
|
+
rxjs.tap(({ id, data }) => {
|
|
263
|
+
highlightsSubject.next(
|
|
264
|
+
highlightsSubject.getValue().map((highlight) => highlight.id === id ? { ...highlight, ...data } : highlight)
|
|
265
|
+
);
|
|
266
|
+
})
|
|
267
|
+
);
|
|
268
|
+
const annotations$ = highlightsSubject.asObservable();
|
|
269
|
+
const readerHighlights = new ReaderHighlights(reader, highlightsSubject);
|
|
270
|
+
rxjs.merge(
|
|
271
|
+
highlight$,
|
|
272
|
+
add$,
|
|
273
|
+
delete$,
|
|
274
|
+
update$,
|
|
275
|
+
annotations$.pipe(
|
|
276
|
+
rxjs.tap((annotations) => {
|
|
277
|
+
report.debug("annotations", annotations);
|
|
278
|
+
})
|
|
279
|
+
)
|
|
280
|
+
).pipe(rxjs.takeUntil(reader.$.destroy$)).subscribe();
|
|
281
|
+
return {
|
|
282
|
+
...reader,
|
|
283
|
+
destroy: () => {
|
|
284
|
+
highlightsSubject.complete();
|
|
285
|
+
commands.destroy();
|
|
286
|
+
readerHighlights.destroy();
|
|
287
|
+
reader.destroy();
|
|
288
|
+
},
|
|
289
|
+
annotations: {
|
|
290
|
+
annotations$,
|
|
291
|
+
highlightTap$: readerHighlights.tap$,
|
|
292
|
+
isTargetWithinHighlight: readerHighlights.isTargetWithinHighlight,
|
|
293
|
+
highlight: commands.highlight,
|
|
294
|
+
add: commands.add,
|
|
295
|
+
delete: commands.delete,
|
|
296
|
+
update: commands.update
|
|
297
|
+
}
|
|
298
|
+
};
|
|
299
|
+
};
|
|
300
|
+
|
|
301
|
+
exports.annotationsEnhancer = annotationsEnhancer;
|
|
302
|
+
|
|
303
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
304
|
+
|
|
305
|
+
}));
|
|
306
|
+
//# sourceMappingURL=index.umd.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.umd.cjs","sources":["../../shared/dist/index.js","../src/report.ts","../src/highlights/utils.ts","../src/highlights/SpineItemHighlight.ts","../src/highlights/SpineItemHighlights.ts","../src/highlights/ReaderHighlights.ts","../src/Commands.ts","../src/annotationsEnhancer.ts"],"sourcesContent":["const f = (e) => {\n var n, t;\n return ((t = (n = e.split(/[#?]/)[0]) == null ? void 0 : n.split(\".\").pop()) == null ? void 0 : t.trim()) || \"\";\n};\nfunction a(e) {\n const n = [];\n if (e.length === 0)\n return \"\";\n if (typeof e[0] != \"string\")\n throw new TypeError(\"Url must be a string. Received \" + e[0]);\n e[0].match(/^[^/:]+:\\/*$/) && e.length > 1 && (e[0] = e.shift() + e[0]), e[0].match(/^file:\\/\\/\\//) ? e[0] = e[0].replace(/^([^/:]+):\\/*/, \"$1:///\") : e[0] = e[0].replace(/^([^/:]+):\\/*/, \"$1://\");\n for (let l = 0; l < e.length; l++) {\n let r = e[l];\n if (typeof r != \"string\")\n throw new TypeError(\"Url must be a string. Received \" + r);\n r !== \"\" && (l > 0 && (r = r.replace(/^[/]+/, \"\")), l < e.length - 1 ? r = r.replace(/[/]+$/, \"\") : r = r.replace(/[/]+$/, \"/\"), n.push(r));\n }\n let t = n.join(\"/\");\n t = t.replace(/\\/(\\?|&|#[^!])/g, \"$1\");\n const o = t.split(\"?\");\n return t = o.shift() + (o.length > 0 ? \"?\" : \"\") + o.join(\"&\"), t;\n}\nfunction d(...e) {\n const n = Array.from(Array.isArray(e[0]) ? e[0] : e);\n return a(n);\n}\nconst E = (e) => {\n switch (f(e)) {\n case \"png\":\n return \"image/png\";\n case \"jpg\":\n return \"image/jpg\";\n case \"jpeg\":\n return \"image/jpeg\";\n case \"txt\":\n return \"text/plain\";\n case \"webp\":\n return \"image/webp\";\n case \"xhtml\":\n return \"application/xhtml+xml\";\n }\n}, R = ({ mimeType: e, uri: n }) => {\n const t = e ?? E(n ?? \"\");\n return t == null ? void 0 : t.startsWith(\"application/xhtml+xml\");\n}, w = (e) => e.length ? e.indexOf(\";\") ? e.substring(0, e.indexOf(\";\")) : e : void 0, _ = \"prose-reader-resource-error\", g = Object.prototype.hasOwnProperty, h = (e, n) => e === n ? e !== 0 || n !== 0 || 1 / e === 1 / n : !1, m = (e, n, t) => {\n if (e === n)\n return !0;\n if (typeof e != \"object\" || e === null || typeof n != \"object\" || n === null)\n return !1;\n const o = Object.keys(e), l = Object.keys(n);\n if (o.length !== l.length)\n return !1;\n const r = t && typeof t.customEqual == \"function\" ? t.customEqual : h;\n for (let s = 0; s < o.length; s++) {\n const u = o[s] || \"\";\n if (!g.call(n, u) || !r(e[u], n[u]))\n return !1;\n }\n return !0;\n}, O = (e, n) => e.reduce(\n (t, o) => {\n const l = n(o);\n return t[l] || (t[l] = []), t[l].push(o), t;\n },\n {}\n);\nfunction y(e, n) {\n const t = { ...e };\n for (const o in n)\n if (Object.prototype.hasOwnProperty.call(n, o)) {\n const l = n[o];\n (l !== void 0 || !(o in e)) && (t[o] = l);\n }\n return t;\n}\nconst c = \"@prose-reader\", i = (e) => `[${e}]`, p = (e, n) => ({\n debug: !n || (window == null ? void 0 : window.__PROSE_READER_DEBUG) !== !0 ? () => {\n } : e ? Function.prototype.bind.call(console.debug, console, i(`${c}`), i(e)) : Function.prototype.bind.call(console.debug, console, i(`${c}`)),\n info: !n || (window == null ? void 0 : window.__PROSE_READER_DEBUG) !== !0 ? () => {\n } : e ? Function.prototype.bind.call(console.info, console, i(`${c}`), i(e)) : Function.prototype.bind.call(console.info, console, i(`${c}`)),\n error: !n || (window == null ? void 0 : window.__PROSE_READER_DEBUG) !== !0 ? () => {\n } : e ? Function.prototype.bind.call(console.error, console, i(`${c}`), i(e)) : Function.prototype.bind.call(console.error, console, i(`${c}`))\n}), $ = {\n ...p(),\n namespace: (e, n) => p(e, n)\n};\nexport {\n _ as PROSE_READER_RESOURCE_ERROR_INJECTED_META_NAME,\n $ as Report,\n E as detectMimeTypeFromName,\n f as getUrlExtension,\n O as groupBy,\n h as is,\n m as isShallowEqual,\n R as isXmlBasedMimeType,\n w as parseContentType,\n y as shallowMergeIfDefined,\n d as urlJoin\n};\n//# sourceMappingURL=index.js.map\n","import { Report } from \"@prose-reader/shared\"\n\nconst IS_DEBUG_ENABLED = true\n\nexport const report = Report.namespace(`enhancer-annotations`, IS_DEBUG_ENABLED)\n","import { report } from \"../report\"\n\nexport const getElementsForRange = (range: Range, container: HTMLElement) => {\n // Get all rects and group them by line (based on vertical position)\n const rects = Array.from(range.getClientRects())\n const lineGroups = new Map<number, DOMRect[]>()\n\n rects.forEach((rect) => {\n const lineY = Math.round(rect.top) // Round to handle minor pixel differences\n if (!lineGroups.has(lineY)) {\n lineGroups.set(lineY, [])\n }\n lineGroups.get(lineY)?.push(rect)\n })\n\n // Create one highlight element per line\n return Array.from(lineGroups.values()).map((lineRects) => {\n // Find the leftmost and rightmost points\n const left = Math.min(...lineRects.map((r) => r.left))\n const right = Math.max(...lineRects.map((r) => r.right))\n const top = lineRects[0]?.top\n const height = lineRects[0]?.height\n\n const rectElt = container.ownerDocument.createElement(\"div\")\n rectElt.style.cssText = `\n position: absolute;\n width: ${right - left}px;\n height: ${height}px;\n top: ${top}px;\n left: ${left}px;\n opacity: 50%;\n `\n\n return rectElt\n })\n}\n\nexport const getRangeFromSelection = (\n overlayElement: HTMLElement,\n anchor: { node: Node; offset?: number },\n focus: { node: Node; offset?: number },\n) => {\n const range = overlayElement.ownerDocument.createRange()\n const comparison = anchor.node.compareDocumentPosition(focus.node)\n\n try {\n // If focus comes before anchor in the document\n if (comparison & Node.DOCUMENT_POSITION_PRECEDING) {\n range.setStart(focus.node, focus.offset || 0)\n range.setEnd(anchor.node, anchor.offset || 0)\n // If focus comes after anchor in the document\n } else if (comparison & Node.DOCUMENT_POSITION_FOLLOWING) {\n range.setStart(anchor.node, anchor.offset || 0)\n range.setEnd(focus.node, focus.offset || 0)\n }\n // If they're the same node\n else {\n const startOffset = Math.min(anchor.offset || 0, focus.offset || 0)\n const endOffset = Math.max(anchor.offset || 0, focus.offset || 0)\n range.setStart(anchor.node, startOffset)\n range.setEnd(anchor.node, endOffset)\n }\n } catch (e) {\n report.error(e)\n }\n\n return range\n}\n\nexport const copyPositionStyle = (source: HTMLElement, target: HTMLElement) => {\n target.style.cssText = source.style.cssText\n}\n\nexport const createAnnotationLayer = (container: HTMLElement, layer: HTMLElement) => {\n const annotationLayer = container.ownerDocument.createElement(\"div\")\n\n layoutAnnotationLayer(layer, annotationLayer)\n\n container.appendChild(annotationLayer)\n\n return annotationLayer\n}\n\nexport const layoutAnnotationLayer = (layer: HTMLElement, annotationLayer: HTMLElement) => {\n copyPositionStyle(layer, annotationLayer)\n\n if (layer.style.position === \"\") {\n annotationLayer.style.position = \"absolute\"\n annotationLayer.style.top = \"0\"\n }\n\n// annotationLayer.style.backgroundColor = \"red\"\n annotationLayer.style.opacity = \"1\"\n annotationLayer.style.pointerEvents = \"none\"\n}\n","import { DestroyableClass, Reader, SpineItem } from \"@prose-reader/core\"\nimport { RuntimeHighlight } from \"../types\"\nimport { getElementsForRange, getRangeFromSelection } from \"./utils\"\nimport { report } from \"../report\"\nimport { fromEvent, map, Observable, share } from \"rxjs\"\n\nexport class SpineItemHighlight extends DestroyableClass {\n private container: HTMLElement\n\n public readonly tap$: Observable<{ event: Event; highlight: RuntimeHighlight }>\n\n constructor(\n private spineItem: SpineItem,\n private containerElement: HTMLElement,\n private reader: Reader,\n public readonly highlight: RuntimeHighlight,\n ) {\n super()\n\n void this.spineItem\n\n this.container = this.containerElement.ownerDocument.createElement(\"div\")\n this.container.dataset[\"highlightContainer\"] = this.highlight.id\n this.containerElement.appendChild(this.container)\n\n this.tap$ = fromEvent(this.container, \"click\").pipe(\n map((event) => ({ event, highlight: this.highlight })),\n share(),\n )\n\n this.render()\n }\n\n public render() {\n this.container.innerHTML = \"\"\n\n const { node: anchorNode, offset: anchorOffset } = this.reader.cfi.resolveCfi({ cfi: this.highlight.anchorCfi ?? `` }) ?? {}\n const { node: focusNode, offset: focusOffset } = this.reader.cfi.resolveCfi({ cfi: this.highlight.focusCfi ?? `` }) ?? {}\n\n if (!anchorNode || !focusNode) {\n report.error(`Unable to resolve anchor cfi: ${this.highlight.anchorCfi}`)\n\n return\n }\n\n const range = getRangeFromSelection(\n this.containerElement,\n { node: anchorNode, offset: anchorOffset },\n { node: focusNode, offset: focusOffset },\n )\n\n const rectElements = getElementsForRange(range, this.container)\n\n rectElements.forEach((elt) => {\n elt.style.pointerEvents = \"initial\"\n elt.style.cursor = \"pointer\"\n elt.style.backgroundColor = this.highlight.color ?? \"yellow\"\n elt.dataset[\"highlightRect\"] = this.highlight.id\n\n this.container.appendChild(elt)\n })\n }\n\n isWithinTarget(target: Node) {\n return this.container.contains(target)\n }\n\n public destroy() {\n super.destroy()\n\n this.container.remove()\n }\n}\n","import { merge, Observable, of, shareReplay, switchMap, takeUntil } from \"rxjs\"\nimport { RuntimeHighlight } from \"../types\"\nimport { DestroyableClass, Reader, SpineItem } from \"@prose-reader/core\"\nimport { SpineItemHighlight } from \"./SpineItemHighlight\"\nimport { createAnnotationLayer, layoutAnnotationLayer } from \"./utils\"\n\nexport class SpineItemHighlights extends DestroyableClass {\n private layer: HTMLElement\n private highlights: SpineItemHighlight[] = []\n\n public readonly tap$: SpineItemHighlight[\"tap$\"]\n\n constructor(\n private annotations$: Observable<RuntimeHighlight[]>,\n private spineItem: SpineItem,\n private reader: Reader,\n ) {\n super()\n\n const firstLayerElement = spineItem.renderer.layers[0]?.element ?? document.createElement(\"div\")\n\n this.layer = createAnnotationLayer(this.spineItem.containerElement, firstLayerElement)\n\n const highlights$ = this.annotations$.pipe(\n switchMap((annotations) => {\n this.highlights.forEach((highlight) => highlight.destroy())\n this.highlights = []\n\n annotations.forEach((annotation) => {\n if (annotation.itemId !== this.spineItem.item.id) return\n\n this.highlights.push(new SpineItemHighlight(this.spineItem, this.layer, this.reader, annotation))\n })\n\n return of(this.highlights)\n }),\n shareReplay(1),\n takeUntil(this.destroy$),\n )\n\n this.tap$ = highlights$.pipe(switchMap((highlights) => merge(...highlights.map((highlight) => highlight.tap$))))\n\n highlights$.subscribe()\n }\n\n layout() {\n const firstLayerElement = this.spineItem.renderer.layers[0]?.element ?? document.createElement(\"div\")\n\n layoutAnnotationLayer(firstLayerElement, this.layer)\n\n this.highlights.forEach((highlight) => highlight.render())\n }\n\n getHighlightsForTarget(target: EventTarget) {\n return this.highlights.filter((highlight) => target instanceof Node && highlight.isWithinTarget(target))\n }\n\n destroy() {\n super.destroy()\n\n this.layer.remove()\n }\n}\n","import { DestroyableClass, Reader } from \"@prose-reader/core\"\nimport { BehaviorSubject, map, merge, switchMap } from \"rxjs\"\nimport { Highlight } from \"../types\"\nimport { SpineItemHighlights } from \"./SpineItemHighlights\"\n\nexport class ReaderHighlights extends DestroyableClass {\n private spineItemHighlights = new BehaviorSubject<SpineItemHighlights[]>([])\n\n public tap$: SpineItemHighlights[\"tap$\"]\n\n constructor(\n private reader: Reader,\n private highlights: BehaviorSubject<Highlight[]>,\n ) {\n super()\n\n this.reader.hookManager.register(\"item.onDocumentLoad\", ({ itemId, destroy }) => {\n const spineItem = reader.spineItemsManager.get(itemId)\n\n if (!spineItem) return\n\n const spineItemHighlights$ = this.highlights.pipe(\n map((highlights) => highlights.filter((highlight) => highlight.itemId === itemId)),\n )\n\n const spineItemHighlights = new SpineItemHighlights(spineItemHighlights$, spineItem, reader)\n\n this.spineItemHighlights.next([...this.spineItemHighlights.getValue(), spineItemHighlights])\n\n const deregister = reader.hookManager.register(\"item.onAfterLayout\", ({ item }) => {\n if (item.id !== itemId) return\n\n spineItemHighlights.layout()\n })\n\n destroy(() => {\n this.spineItemHighlights.next(this.spineItemHighlights.getValue().filter((layer) => layer !== spineItemHighlights))\n\n spineItemHighlights.destroy()\n\n deregister()\n })\n })\n\n this.tap$ = this.spineItemHighlights.pipe(switchMap((layers) => merge(...layers.map((layer) => layer.tap$))))\n }\n\n getHighlightsForTarget = (target: EventTarget) => {\n return this.spineItemHighlights\n .getValue()\n .flatMap((layer) => layer.getHighlightsForTarget(target))\n .map((annotation) => annotation.highlight)\n }\n\n isTargetWithinHighlight = (target: EventTarget) => {\n return !!this.getHighlightsForTarget(target).length\n }\n}\n","import { DestroyableClass } from \"@prose-reader/core\"\nimport { filter, Subject } from \"rxjs\"\nimport { Highlight } from \"./types\"\n\ntype HighlightParams = { document: Document; selection: Selection; itemId: string; color?: string; contents?: string[] }\n\ntype Command =\n | { type: \"highlight\"; data: HighlightParams }\n | { type: \"add\"; data: Highlight | Highlight[] }\n | { type: \"delete\"; id: string }\n | { type: \"update\"; id: string; data: Pick<HighlightParams, \"color\" | \"contents\"> }\n\nexport class Commands extends DestroyableClass {\n private commandSubject = new Subject<Command>()\n\n public readonly highlight$ = this.commandSubject.pipe(filter((command) => command.type === \"highlight\"))\n public readonly add$ = this.commandSubject.pipe(filter((command) => command.type === \"add\"))\n public readonly delete$ = this.commandSubject.pipe(filter((command) => command.type === \"delete\"))\n public readonly update$ = this.commandSubject.pipe(filter((command) => command.type === \"update\"))\n\n highlight = (params: HighlightParams) => {\n this.commandSubject.next({ type: \"highlight\", data: params })\n }\n\n add = (data: Highlight | Highlight[]) => {\n this.commandSubject.next({ type: \"add\", data })\n }\n\n delete = (id: string) => {\n this.commandSubject.next({ type: \"delete\", id })\n }\n\n update = (id: string, data: Pick<HighlightParams, \"color\" | \"contents\">) => {\n this.commandSubject.next({ type: \"update\", id, data })\n }\n\n destroy() {\n super.destroy()\n this.commandSubject.complete()\n }\n}\n","import { Reader } from \"@prose-reader/core\"\nimport { BehaviorSubject, merge, takeUntil, tap, Observable } from \"rxjs\"\nimport { report } from \"./report\"\nimport { RuntimeHighlight } from \"./types\"\nimport { ReaderHighlights } from \"./highlights/ReaderHighlights\"\nimport { Commands } from \"./Commands\"\n\nexport const annotationsEnhancer =\n <InheritOptions, InheritOutput extends Reader>(next: (options: InheritOptions) => InheritOutput) =>\n (\n options: InheritOptions,\n ): InheritOutput & {\n annotations: {\n annotations$: Observable<RuntimeHighlight[]>\n highlightTap$: ReaderHighlights[\"tap$\"]\n highlight: Commands[\"highlight\"]\n add: Commands[\"add\"]\n delete: Commands[\"delete\"]\n update: Commands[\"update\"]\n isTargetWithinHighlight: (target: EventTarget) => boolean\n }\n } => {\n const reader = next(options)\n const commands = new Commands()\n const highlightsSubject = new BehaviorSubject<RuntimeHighlight[]>([])\n\n const highlight$ = commands.highlight$.pipe(\n tap(({ data: { itemId, selection, ...rest } }) => {\n const { anchorCfi, focusCfi } = reader.selection.generateCfis({ itemId, selection })\n\n const annotation = { anchorCfi, focusCfi, itemId, id: window.crypto.randomUUID(), ...rest }\n\n highlightsSubject.next([...highlightsSubject.getValue(), annotation])\n }),\n )\n\n const add$ = commands.add$.pipe(\n tap(({ data }) => {\n const annotations = Array.isArray(data) ? data : [data]\n\n highlightsSubject.next([...highlightsSubject.getValue(), ...annotations])\n }),\n )\n\n const delete$ = commands.delete$.pipe(\n tap(({ id }) => {\n highlightsSubject.next(highlightsSubject.getValue().filter((highlight) => highlight.id !== id))\n }),\n )\n\n const update$ = commands.update$.pipe(\n tap(({ id, data }) => {\n highlightsSubject.next(\n highlightsSubject.getValue().map((highlight) => (highlight.id === id ? { ...highlight, ...data } : highlight)),\n )\n }),\n )\n\n const annotations$ = highlightsSubject.asObservable()\n\n const readerHighlights = new ReaderHighlights(reader, highlightsSubject)\n\n merge(\n highlight$,\n add$,\n delete$,\n update$,\n annotations$.pipe(\n tap((annotations) => {\n report.debug(\"annotations\", annotations)\n }),\n ),\n )\n .pipe(takeUntil(reader.$.destroy$))\n .subscribe()\n\n return {\n ...reader,\n destroy: () => {\n highlightsSubject.complete()\n commands.destroy()\n readerHighlights.destroy()\n reader.destroy()\n },\n annotations: {\n annotations$,\n highlightTap$: readerHighlights.tap$,\n isTargetWithinHighlight: readerHighlights.isTargetWithinHighlight,\n highlight: commands.highlight,\n add: commands.add,\n delete: commands.delete,\n update: commands.update,\n },\n }\n }\n"],"names":["Report","DestroyableClass","fromEvent","map","share","switchMap","of","shareReplay","takeUntil","merge","highlights","BehaviorSubject","Subject","filter","tap"],"mappings":"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"}
|
package/dist/report.d.ts
ADDED
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export type RuntimeHighlight = {
|
|
2
|
+
anchorCfi: string | undefined;
|
|
3
|
+
focusCfi: string | undefined;
|
|
4
|
+
itemId: string;
|
|
5
|
+
color?: string;
|
|
6
|
+
contents?: string[];
|
|
7
|
+
/**
|
|
8
|
+
* Unique local ID. This is to ensure unicity
|
|
9
|
+
* for duplicate selections
|
|
10
|
+
*/
|
|
11
|
+
id: string;
|
|
12
|
+
};
|
|
13
|
+
export type Highlight = RuntimeHighlight;
|
package/package.json
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@prose-reader/enhancer-annotations",
|
|
3
|
+
"version": "1.121.0",
|
|
4
|
+
"type": "module",
|
|
5
|
+
"main": "./dist/index.umd.cjs",
|
|
6
|
+
"module": "./dist/index.js",
|
|
7
|
+
"types": "./dist/index.d.ts",
|
|
8
|
+
"files": [
|
|
9
|
+
"/dist"
|
|
10
|
+
],
|
|
11
|
+
"exports": {
|
|
12
|
+
".": {
|
|
13
|
+
"import": "./dist/index.js",
|
|
14
|
+
"require": "./dist/index.umd.cjs"
|
|
15
|
+
}
|
|
16
|
+
},
|
|
17
|
+
"scripts": {
|
|
18
|
+
"start": "vite build --watch --mode development",
|
|
19
|
+
"build": "tsc && vite build",
|
|
20
|
+
"lint:read": "prettier --check . && eslint . --ext .ts,.tsx,.js,.jsx",
|
|
21
|
+
"lint:write": "prettier --write . && eslint --fix . --ext .ts,.tsx,.js,.jsx"
|
|
22
|
+
},
|
|
23
|
+
"peerDependencies": {
|
|
24
|
+
"@prose-reader/core": "^1.117.0"
|
|
25
|
+
}
|
|
26
|
+
}
|