@prose-reader/enhancer-annotations 1.124.0 → 1.126.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js.map CHANGED
@@ -1 +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, skip, takeUntil, tap } 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 private isSelected: Observable<boolean>,\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 this.isSelected\n .pipe(\n skip(1),\n tap((isSelected) => {\n Array.from(this.container.children).forEach((child) => {\n if (child instanceof HTMLElement) {\n child.style.border = isSelected ? \"3px dashed red\" : \"none\"\n }\n })\n }),\n takeUntil(this.destroy$),\n )\n .subscribe()\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 { distinctUntilChanged, map, 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 private selectedHighlight: Observable<string | undefined>,\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 const isSelected$ = this.selectedHighlight.pipe(\n map((id) => id === annotation.id),\n distinctUntilChanged(),\n )\n\n const spineItemHighlight = new SpineItemHighlight(this.spineItem, this.layer, this.reader, annotation, isSelected$)\n\n this.highlights.push(spineItemHighlight)\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 private selectedHighlight: BehaviorSubject<string | undefined>,\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, this.selectedHighlight)\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 | { type: \"select\"; id: string | undefined }\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 public readonly select$ = this.commandSubject.pipe(filter((command) => command.type === \"select\"))\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 select = (id: string | undefined) => {\n this.commandSubject.next({ type: \"select\", id })\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 select: Commands[\"select\"]\n isTargetWithinHighlight: (target: EventTarget) => boolean\n }\n } => {\n const reader = next(options)\n const commands = new Commands()\n const highlightsSubject = new BehaviorSubject<RuntimeHighlight[]>([])\n const selectedHighlightSubject = new BehaviorSubject<string | undefined>(undefined)\n\n const readerHighlights = new ReaderHighlights(reader, highlightsSubject, selectedHighlightSubject)\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 select$ = commands.select$.pipe(\n tap(({ id }) => {\n selectedHighlightSubject.next(id)\n }),\n )\n\n const annotations$ = highlightsSubject.asObservable()\n\n merge(\n highlight$,\n add$,\n delete$,\n update$,\n select$,\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 select: commands.select,\n },\n }\n }\n"],"names":["Report","isSelected","highlights"],"mappings":"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"}
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/highlights/Highlight.ts","../src/highlights/consolidate.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","export const createElementForRange = (range: Range, container: HTMLElement, color: string) => {\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 rectEltContainer = container.ownerDocument.createElement(\"div\")\n const rectElt = container.ownerDocument.createElement(\"div\")\n rectEltContainer.style.cssText = `\n position: absolute;\n width: ${right - left}px;\n height: ${height}px;\n top: ${top}px;\n left: ${left}px;\n box-sizing: border-box;\n border: 3px dashed transparent;\n `\n rectElt.style.cssText = `\n height: 100%;\n width: 100%;\n opacity: 25%;\n background-color: ${color}\n `\n\n rectEltContainer.appendChild(rectElt)\n\n return rectEltContainer\n })\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 { createElementForRange } from \"./utils\"\nimport { fromEvent, map, Observable, share, skip, takeUntil, tap } from \"rxjs\"\nimport { Highlight } from \"./Highlight\"\n\nexport class SpineItemHighlight extends DestroyableClass {\n private container: HTMLElement\n\n public readonly tap$: Observable<{ event: Event; highlight: Highlight }>\n\n constructor(\n private spineItem: SpineItem,\n private containerElement: HTMLElement,\n private reader: Reader,\n public readonly highlight: Highlight,\n private isSelected: Observable<boolean>,\n ) {\n super()\n\n void this.spineItem\n void this.reader\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 this.isSelected\n .pipe(\n skip(1),\n tap((isSelected) => {\n Array.from(this.container.children).forEach((child) => {\n if (child instanceof HTMLElement) {\n child.style.border = isSelected ? \"3px dashed red\" : \"3px dashed transparent\"\n }\n })\n }),\n takeUntil(this.destroy$),\n )\n .subscribe()\n }\n\n public render() {\n this.container.innerHTML = \"\"\n\n const range = this.highlight.range\n\n /**\n * The nodes can be undefined if the cfi is not found.\n * This can happens if the item is not loaded (legit) or if the cfi\n * are just invalid.\n */\n if (!range) {\n return\n }\n\n const rectElements = createElementForRange(range, this.container, this.highlight.color ?? \"yellow\")\n\n rectElements.forEach((elt) => {\n elt.style.pointerEvents = \"initial\"\n elt.style.cursor = \"pointer\"\n elt.dataset[\"highlightRect\"] = this.highlight.id\n\n this.container.appendChild(elt)\n })\n\n const firstElement = rectElements[0]\n\n if (firstElement && this.highlight.contents?.length) {\n const noteIcon = document.createElement(\"span\")\n noteIcon.textContent = \"📝\"\n noteIcon.style.position = \"absolute\"\n noteIcon.style.top = \"0\"\n noteIcon.style.left = \"0\"\n noteIcon.style.transform = \"translate(-0%, -80%)\"\n noteIcon.style.fontSize = \"18px\"\n noteIcon.style.opacity = \"50%\"\n firstElement.appendChild(noteIcon)\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 { distinctUntilChanged, map, merge, Observable, of, shareReplay, switchMap, takeUntil } from \"rxjs\"\nimport { DestroyableClass, Reader, SpineItem } from \"@prose-reader/core\"\nimport { SpineItemHighlight } from \"./SpineItemHighlight\"\nimport { createAnnotationLayer, layoutAnnotationLayer } from \"./utils\"\nimport { Highlight } from \"./Highlight\"\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 highlights$: Observable<Highlight[]>,\n private spineItem: SpineItem,\n private reader: Reader,\n private selectedHighlight: Observable<string | undefined>,\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 itemHighlights$ = this.highlights$.pipe(\n switchMap((annotations) => {\n this.highlights.forEach((highlight) => highlight.destroy())\n this.highlights = []\n\n annotations.forEach((annotation) => {\n if (annotation.itemIndex !== this.spineItem.item.index) return\n\n const isSelected$ = this.selectedHighlight.pipe(\n map((id) => id === annotation.id),\n distinctUntilChanged(),\n )\n\n const spineItemHighlight = new SpineItemHighlight(this.spineItem, this.layer, this.reader, annotation, isSelected$)\n\n this.highlights.push(spineItemHighlight)\n })\n\n return of(this.highlights)\n }),\n shareReplay(1),\n takeUntil(this.destroy$),\n )\n\n this.tap$ = itemHighlights$.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 { SpineItemHighlights } from \"./SpineItemHighlights\"\nimport { Highlight } from \"./Highlight\"\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 private selectedHighlight: BehaviorSubject<string | undefined>,\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.itemIndex === spineItem.item.index)),\n )\n\n const spineItemHighlights = new SpineItemHighlights(spineItemHighlights$, spineItem, reader, this.selectedHighlight)\n\n this.spineItemHighlights.next([...this.spineItemHighlights.getValue(), spineItemHighlights])\n\n destroy(() => {\n this.spineItemHighlights.next(this.spineItemHighlights.getValue().filter((layer) => layer !== spineItemHighlights))\n\n spineItemHighlights.destroy()\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 public layout() {\n this.spineItemHighlights.getValue().forEach((item) => item.layout())\n }\n}\n","import { DestroyableClass, Reader } from \"@prose-reader/core\"\nimport { filter, ObservedValueOf, Subject } from \"rxjs\"\nimport { SerializableHighlight } from \"./types\"\n\ntype HighlightParams = ObservedValueOf<Reader[\"selection\"][\"selection$\"]> & { color?: string; contents?: string[] }\n\ntype Command =\n | { type: \"highlight\"; data: HighlightParams }\n | { type: \"add\"; data: SerializableHighlight | SerializableHighlight[] }\n | { type: \"delete\"; id: string }\n | { type: \"update\"; id: string; data: Pick<HighlightParams, \"color\" | \"contents\"> }\n | { type: \"select\"; id: string | undefined }\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 public readonly select$ = this.commandSubject.pipe(filter((command) => command.type === \"select\"))\n\n highlight = (params: HighlightParams) => {\n this.commandSubject.next({ type: \"highlight\", data: params })\n }\n\n add = (data: SerializableHighlight | SerializableHighlight[]) => {\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 select = (id: string | undefined) => {\n this.commandSubject.next({ type: \"select\", id })\n }\n\n destroy() {\n super.destroy()\n this.commandSubject.complete()\n }\n}\n","import { SerializableHighlight } from \"../types\"\n\nexport class Highlight {\n public anchorCfi: string | undefined\n public focusCfi: string | undefined\n public itemIndex?: number\n public color?: string\n public contents?: string[]\n public spineItemPageIndex?: number\n public absolutePageIndex?: number\n public range?: Range\n public lastSelectionText?: string\n /**\n * Unique local ID. This is to ensure unicity\n * for duplicate selections\n */\n public id: string\n\n constructor(params: SerializableHighlight & { itemIndex?: number }) {\n this.anchorCfi = params.anchorCfi\n this.focusCfi = params.focusCfi\n this.itemIndex = params.itemIndex\n this.color = params.color\n this.contents = params.contents\n this.id = params.id\n this.lastSelectionText = params.lastSelectionText\n }\n\n toJSON(): SerializableHighlight {\n return {\n anchorCfi: this.anchorCfi,\n focusCfi: this.focusCfi,\n color: this.color,\n contents: this.contents,\n id: this.id,\n lastSelectionText: this.lastSelectionText,\n }\n }\n}\n","import { Reader } from \"@prose-reader/core\"\nimport { Highlight } from \"./Highlight\"\n\nexport const consolidate = (highlight: Highlight, reader: Reader) => {\n const { itemIndex } = reader.cfi.parseCfi(highlight.anchorCfi ?? \"\")\n const spineItem = reader.spineItemsManager.get(itemIndex)\n const resolvedAnchorCfi = reader.cfi.resolveCfi({ cfi: highlight.anchorCfi ?? \"\" })\n const resolvedFocusCfi = reader.cfi.resolveCfi({ cfi: highlight.focusCfi ?? \"\" })\n\n if (!spineItem) return\n\n if (spineItem.item.renditionLayout === `pre-paginated`) {\n highlight.spineItemPageIndex = 0\n } else {\n if (resolvedAnchorCfi?.node) {\n highlight.spineItemPageIndex = reader.spine.locator.spineItemLocator.getSpineItemPageIndexFromNode(\n resolvedAnchorCfi.node,\n resolvedAnchorCfi.offset ?? 0,\n spineItem,\n )\n }\n }\n\n if (resolvedAnchorCfi?.node && resolvedFocusCfi?.node && spineItem.isReady) {\n const range = reader.selection.createRangeFromSelection({\n selection: {\n anchorNode: resolvedAnchorCfi.node,\n anchorOffset: resolvedAnchorCfi.offset ?? 0,\n focusNode: resolvedFocusCfi.node,\n focusOffset: resolvedFocusCfi.offset ?? 0,\n },\n spineItem,\n })\n\n highlight.range = range\n highlight.lastSelectionText = range?.toString()\n } else {\n highlight.range = undefined\n }\n\n if (highlight.spineItemPageIndex !== undefined) {\n highlight.absolutePageIndex = reader.spine.locator.getAbsolutePageIndexFromPageIndex({\n pageIndex: highlight.spineItemPageIndex,\n spineItemOrId: spineItem,\n })\n }\n}\n","import { Reader, waitForSwitch } from \"@prose-reader/core\"\nimport { BehaviorSubject, merge, takeUntil, tap, Observable, withLatestFrom, debounceTime } from \"rxjs\"\nimport { report } from \"./report\"\nimport { ReaderHighlights } from \"./highlights/ReaderHighlights\"\nimport { Commands } from \"./Commands\"\nimport { Highlight } from \"./highlights/Highlight\"\nimport { consolidate } from \"./highlights/consolidate\"\n\nexport const annotationsEnhancer =\n <InheritOptions, InheritOutput extends Reader>(next: (options: InheritOptions) => InheritOutput) =>\n (\n options: InheritOptions,\n ): InheritOutput & {\n annotations: {\n highlights$: Observable<Highlight[]>\n highlightTap$: ReaderHighlights[\"tap$\"]\n highlight: Commands[\"highlight\"]\n add: Commands[\"add\"]\n delete: Commands[\"delete\"]\n update: Commands[\"update\"]\n select: Commands[\"select\"]\n isTargetWithinHighlight: (target: EventTarget) => boolean\n }\n } => {\n const reader = next(options)\n const commands = new Commands()\n const highlightsSubject = new BehaviorSubject<Highlight[]>([])\n const selectedHighlightSubject = new BehaviorSubject<string | undefined>(undefined)\n const readerHighlights = new ReaderHighlights(reader, highlightsSubject, selectedHighlightSubject)\n\n const highlight$ = commands.highlight$.pipe(\n tap(({ data: { itemIndex, selection, ...rest } }) => {\n const item = reader.spineItemsManager.get(itemIndex)?.item\n\n if (!item) return\n\n const { anchorCfi, focusCfi } = reader.cfi.generateCfiFromSelection({ item, selection })\n\n const highlight = new Highlight({ anchorCfi, focusCfi, itemIndex, id: window.crypto.randomUUID(), ...rest })\n\n consolidate(highlight, reader)\n\n highlightsSubject.next([...highlightsSubject.getValue(), highlight])\n }),\n )\n\n const add$ = commands.add$.pipe(\n tap(({ data }) => {\n const annotations = Array.isArray(data) ? data : [data]\n\n highlightsSubject.next([\n ...highlightsSubject.getValue(),\n ...annotations.map((annotation) => {\n const { itemIndex } = reader.cfi.parseCfi(annotation.anchorCfi ?? \"\")\n\n const highlight = new Highlight({ ...annotation, itemIndex })\n\n consolidate(highlight, reader)\n\n return highlight\n }),\n ])\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\n .getValue()\n .map((highlight) => (highlight.id === id ? new Highlight({ ...highlight, ...data }) : highlight)),\n )\n }),\n )\n\n const select$ = commands.select$.pipe(\n tap(({ id }) => {\n selectedHighlightSubject.next(id)\n }),\n )\n\n const highlights$ = highlightsSubject.asObservable()\n\n /**\n * @todo consolidation should be more optimized\n */\n const highlightsConsolidation$ = reader.layout$.pipe(\n debounceTime(50),\n waitForSwitch(reader.viewportFree$),\n withLatestFrom(highlights$),\n tap(([, highlights]) => {\n highlights.forEach((highlight) => consolidate(highlight, reader))\n highlightsSubject.next(highlights)\n readerHighlights.layout()\n }),\n )\n\n merge(\n highlight$,\n add$,\n delete$,\n update$,\n select$,\n highlightsConsolidation$,\n highlights$.pipe(\n tap((annotations) => {\n report.debug(\"highlights\", 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 highlights$,\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 select: commands.select,\n },\n }\n }\n"],"names":["Report","isSelected","highlights"],"mappings":"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"}
@@ -1,8 +1,8 @@
1
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';
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
6
 
7
7
  const c = "@prose-reader", i = (e) => `[${e}]`, p = (e, n) => ({
8
8
  debug: !n || (window == null ? void 0 : window.__PROSE_READER_DEBUG) !== !0 ? () => {
@@ -19,7 +19,7 @@
19
19
  const IS_DEBUG_ENABLED = true;
20
20
  const report = $.namespace(`enhancer-annotations`, IS_DEBUG_ENABLED);
21
21
 
22
- const getElementsForRange = (range, container) => {
22
+ const createElementForRange = (range, container, color) => {
23
23
  const rects = Array.from(range.getClientRects());
24
24
  const lineGroups = /* @__PURE__ */ new Map();
25
25
  rects.forEach((rect) => {
@@ -34,39 +34,27 @@
34
34
  const right = Math.max(...lineRects.map((r) => r.right));
35
35
  const top = lineRects[0]?.top;
36
36
  const height = lineRects[0]?.height;
37
+ const rectEltContainer = container.ownerDocument.createElement("div");
37
38
  const rectElt = container.ownerDocument.createElement("div");
38
- rectElt.style.cssText = `
39
+ rectEltContainer.style.cssText = `
39
40
  position: absolute;
40
41
  width: ${right - left}px;
41
42
  height: ${height}px;
42
43
  top: ${top}px;
43
44
  left: ${left}px;
44
- opacity: 50%;
45
+ box-sizing: border-box;
46
+ border: 3px dashed transparent;
47
+ `;
48
+ rectElt.style.cssText = `
49
+ height: 100%;
50
+ width: 100%;
51
+ opacity: 25%;
52
+ background-color: ${color}
45
53
  `;
46
- return rectElt;
54
+ rectEltContainer.appendChild(rectElt);
55
+ return rectEltContainer;
47
56
  });
48
57
  };
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
58
  const copyPositionStyle = (source, target) => {
71
59
  target.style.cssText = source.style.cssText;
72
60
  };
@@ -95,6 +83,7 @@
95
83
  this.highlight = highlight;
96
84
  this.isSelected = isSelected;
97
85
  void this.spineItem;
86
+ void this.reader;
98
87
  this.container = this.containerElement.ownerDocument.createElement("div");
99
88
  this.container.dataset["highlightContainer"] = this.highlight.id;
100
89
  this.containerElement.appendChild(this.container);
@@ -108,7 +97,7 @@
108
97
  rxjs.tap((isSelected2) => {
109
98
  Array.from(this.container.children).forEach((child) => {
110
99
  if (child instanceof HTMLElement) {
111
- child.style.border = isSelected2 ? "3px dashed red" : "none";
100
+ child.style.border = isSelected2 ? "3px dashed red" : "3px dashed transparent";
112
101
  }
113
102
  });
114
103
  }),
@@ -119,25 +108,29 @@
119
108
  tap$;
120
109
  render() {
121
110
  this.container.innerHTML = "";
122
- const { node: anchorNode, offset: anchorOffset } = this.reader.cfi.resolveCfi({ cfi: this.highlight.anchorCfi ?? `` }) ?? {};
123
- const { node: focusNode, offset: focusOffset } = this.reader.cfi.resolveCfi({ cfi: this.highlight.focusCfi ?? `` }) ?? {};
124
- if (!anchorNode || !focusNode) {
125
- report.error(`Unable to resolve anchor cfi: ${this.highlight.anchorCfi}`);
111
+ const range = this.highlight.range;
112
+ if (!range) {
126
113
  return;
127
114
  }
128
- const range = getRangeFromSelection(
129
- this.containerElement,
130
- { node: anchorNode, offset: anchorOffset },
131
- { node: focusNode, offset: focusOffset }
132
- );
133
- const rectElements = getElementsForRange(range, this.container);
115
+ const rectElements = createElementForRange(range, this.container, this.highlight.color ?? "yellow");
134
116
  rectElements.forEach((elt) => {
135
117
  elt.style.pointerEvents = "initial";
136
118
  elt.style.cursor = "pointer";
137
- elt.style.backgroundColor = this.highlight.color ?? "yellow";
138
119
  elt.dataset["highlightRect"] = this.highlight.id;
139
120
  this.container.appendChild(elt);
140
121
  });
122
+ const firstElement = rectElements[0];
123
+ if (firstElement && this.highlight.contents?.length) {
124
+ const noteIcon = document.createElement("span");
125
+ noteIcon.textContent = "📝";
126
+ noteIcon.style.position = "absolute";
127
+ noteIcon.style.top = "0";
128
+ noteIcon.style.left = "0";
129
+ noteIcon.style.transform = "translate(-0%, -80%)";
130
+ noteIcon.style.fontSize = "18px";
131
+ noteIcon.style.opacity = "50%";
132
+ firstElement.appendChild(noteIcon);
133
+ }
141
134
  }
142
135
  isWithinTarget(target) {
143
136
  return this.container.contains(target);
@@ -149,20 +142,20 @@
149
142
  }
150
143
 
151
144
  class SpineItemHighlights extends core.DestroyableClass {
152
- constructor(annotations$, spineItem, reader, selectedHighlight) {
145
+ constructor(highlights$, spineItem, reader, selectedHighlight) {
153
146
  super();
154
- this.annotations$ = annotations$;
147
+ this.highlights$ = highlights$;
155
148
  this.spineItem = spineItem;
156
149
  this.reader = reader;
157
150
  this.selectedHighlight = selectedHighlight;
158
151
  const firstLayerElement = spineItem.renderer.layers[0]?.element ?? document.createElement("div");
159
152
  this.layer = createAnnotationLayer(this.spineItem.containerElement, firstLayerElement);
160
- const highlights$ = this.annotations$.pipe(
153
+ const itemHighlights$ = this.highlights$.pipe(
161
154
  rxjs.switchMap((annotations) => {
162
155
  this.highlights.forEach((highlight) => highlight.destroy());
163
156
  this.highlights = [];
164
157
  annotations.forEach((annotation) => {
165
- if (annotation.itemId !== this.spineItem.item.id) return;
158
+ if (annotation.itemIndex !== this.spineItem.item.index) return;
166
159
  const isSelected$ = this.selectedHighlight.pipe(
167
160
  rxjs.map((id) => id === annotation.id),
168
161
  rxjs.distinctUntilChanged()
@@ -175,7 +168,7 @@
175
168
  rxjs.shareReplay(1),
176
169
  rxjs.takeUntil(this.destroy$)
177
170
  );
178
- this.tap$ = highlights$.pipe(rxjs.switchMap((highlights) => rxjs.merge(...highlights.map((highlight) => highlight.tap$))));
171
+ this.tap$ = itemHighlights$.pipe(rxjs.switchMap((highlights) => rxjs.merge(...highlights.map((highlight) => highlight.tap$))));
179
172
  highlights$.subscribe();
180
173
  }
181
174
  layer;
@@ -205,18 +198,13 @@
205
198
  const spineItem = reader.spineItemsManager.get(itemId);
206
199
  if (!spineItem) return;
207
200
  const spineItemHighlights$ = this.highlights.pipe(
208
- rxjs.map((highlights2) => highlights2.filter((highlight) => highlight.itemId === itemId))
201
+ rxjs.map((highlights2) => highlights2.filter((highlight) => highlight.itemIndex === spineItem.item.index))
209
202
  );
210
203
  const spineItemHighlights = new SpineItemHighlights(spineItemHighlights$, spineItem, reader, this.selectedHighlight);
211
204
  this.spineItemHighlights.next([...this.spineItemHighlights.getValue(), spineItemHighlights]);
212
- const deregister = reader.hookManager.register("item.onAfterLayout", ({ item }) => {
213
- if (item.id !== itemId) return;
214
- spineItemHighlights.layout();
215
- });
216
205
  destroy(() => {
217
206
  this.spineItemHighlights.next(this.spineItemHighlights.getValue().filter((layer) => layer !== spineItemHighlights));
218
207
  spineItemHighlights.destroy();
219
- deregister();
220
208
  });
221
209
  });
222
210
  this.tap$ = this.spineItemHighlights.pipe(rxjs.switchMap((layers) => rxjs.merge(...layers.map((layer) => layer.tap$))));
@@ -229,6 +217,9 @@
229
217
  isTargetWithinHighlight = (target) => {
230
218
  return !!this.getHighlightsForTarget(target).length;
231
219
  };
220
+ layout() {
221
+ this.spineItemHighlights.getValue().forEach((item) => item.layout());
222
+ }
232
223
  }
233
224
 
234
225
  class Commands extends core.DestroyableClass {
@@ -259,6 +250,82 @@
259
250
  }
260
251
  }
261
252
 
253
+ class Highlight {
254
+ anchorCfi;
255
+ focusCfi;
256
+ itemIndex;
257
+ color;
258
+ contents;
259
+ spineItemPageIndex;
260
+ absolutePageIndex;
261
+ range;
262
+ lastSelectionText;
263
+ /**
264
+ * Unique local ID. This is to ensure unicity
265
+ * for duplicate selections
266
+ */
267
+ id;
268
+ constructor(params) {
269
+ this.anchorCfi = params.anchorCfi;
270
+ this.focusCfi = params.focusCfi;
271
+ this.itemIndex = params.itemIndex;
272
+ this.color = params.color;
273
+ this.contents = params.contents;
274
+ this.id = params.id;
275
+ this.lastSelectionText = params.lastSelectionText;
276
+ }
277
+ toJSON() {
278
+ return {
279
+ anchorCfi: this.anchorCfi,
280
+ focusCfi: this.focusCfi,
281
+ color: this.color,
282
+ contents: this.contents,
283
+ id: this.id,
284
+ lastSelectionText: this.lastSelectionText
285
+ };
286
+ }
287
+ }
288
+
289
+ const consolidate = (highlight, reader) => {
290
+ const { itemIndex } = reader.cfi.parseCfi(highlight.anchorCfi ?? "");
291
+ const spineItem = reader.spineItemsManager.get(itemIndex);
292
+ const resolvedAnchorCfi = reader.cfi.resolveCfi({ cfi: highlight.anchorCfi ?? "" });
293
+ const resolvedFocusCfi = reader.cfi.resolveCfi({ cfi: highlight.focusCfi ?? "" });
294
+ if (!spineItem) return;
295
+ if (spineItem.item.renditionLayout === `pre-paginated`) {
296
+ highlight.spineItemPageIndex = 0;
297
+ } else {
298
+ if (resolvedAnchorCfi?.node) {
299
+ highlight.spineItemPageIndex = reader.spine.locator.spineItemLocator.getSpineItemPageIndexFromNode(
300
+ resolvedAnchorCfi.node,
301
+ resolvedAnchorCfi.offset ?? 0,
302
+ spineItem
303
+ );
304
+ }
305
+ }
306
+ if (resolvedAnchorCfi?.node && resolvedFocusCfi?.node && spineItem.isReady) {
307
+ const range = reader.selection.createRangeFromSelection({
308
+ selection: {
309
+ anchorNode: resolvedAnchorCfi.node,
310
+ anchorOffset: resolvedAnchorCfi.offset ?? 0,
311
+ focusNode: resolvedFocusCfi.node,
312
+ focusOffset: resolvedFocusCfi.offset ?? 0
313
+ },
314
+ spineItem
315
+ });
316
+ highlight.range = range;
317
+ highlight.lastSelectionText = range?.toString();
318
+ } else {
319
+ highlight.range = void 0;
320
+ }
321
+ if (highlight.spineItemPageIndex !== void 0) {
322
+ highlight.absolutePageIndex = reader.spine.locator.getAbsolutePageIndexFromPageIndex({
323
+ pageIndex: highlight.spineItemPageIndex,
324
+ spineItemOrId: spineItem
325
+ });
326
+ }
327
+ };
328
+
262
329
  const annotationsEnhancer = (next) => (options) => {
263
330
  const reader = next(options);
264
331
  const commands = new Commands();
@@ -266,16 +333,27 @@
266
333
  const selectedHighlightSubject = new rxjs.BehaviorSubject(void 0);
267
334
  const readerHighlights = new ReaderHighlights(reader, highlightsSubject, selectedHighlightSubject);
268
335
  const highlight$ = commands.highlight$.pipe(
269
- rxjs.tap(({ data: { itemId, selection, ...rest } }) => {
270
- const { anchorCfi, focusCfi } = reader.selection.generateCfis({ itemId, selection });
271
- const annotation = { anchorCfi, focusCfi, itemId, id: window.crypto.randomUUID(), ...rest };
272
- highlightsSubject.next([...highlightsSubject.getValue(), annotation]);
336
+ rxjs.tap(({ data: { itemIndex, selection, ...rest } }) => {
337
+ const item = reader.spineItemsManager.get(itemIndex)?.item;
338
+ if (!item) return;
339
+ const { anchorCfi, focusCfi } = reader.cfi.generateCfiFromSelection({ item, selection });
340
+ const highlight = new Highlight({ anchorCfi, focusCfi, itemIndex, id: window.crypto.randomUUID(), ...rest });
341
+ consolidate(highlight, reader);
342
+ highlightsSubject.next([...highlightsSubject.getValue(), highlight]);
273
343
  })
274
344
  );
275
345
  const add$ = commands.add$.pipe(
276
346
  rxjs.tap(({ data }) => {
277
347
  const annotations = Array.isArray(data) ? data : [data];
278
- highlightsSubject.next([...highlightsSubject.getValue(), ...annotations]);
348
+ highlightsSubject.next([
349
+ ...highlightsSubject.getValue(),
350
+ ...annotations.map((annotation) => {
351
+ const { itemIndex } = reader.cfi.parseCfi(annotation.anchorCfi ?? "");
352
+ const highlight = new Highlight({ ...annotation, itemIndex });
353
+ consolidate(highlight, reader);
354
+ return highlight;
355
+ })
356
+ ]);
279
357
  })
280
358
  );
281
359
  const delete$ = commands.delete$.pipe(
@@ -286,7 +364,7 @@
286
364
  const update$ = commands.update$.pipe(
287
365
  rxjs.tap(({ id, data }) => {
288
366
  highlightsSubject.next(
289
- highlightsSubject.getValue().map((highlight) => highlight.id === id ? { ...highlight, ...data } : highlight)
367
+ highlightsSubject.getValue().map((highlight) => highlight.id === id ? new Highlight({ ...highlight, ...data }) : highlight)
290
368
  );
291
369
  })
292
370
  );
@@ -295,16 +373,27 @@
295
373
  selectedHighlightSubject.next(id);
296
374
  })
297
375
  );
298
- const annotations$ = highlightsSubject.asObservable();
376
+ const highlights$ = highlightsSubject.asObservable();
377
+ const highlightsConsolidation$ = reader.layout$.pipe(
378
+ rxjs.debounceTime(50),
379
+ core.waitForSwitch(reader.viewportFree$),
380
+ rxjs.withLatestFrom(highlights$),
381
+ rxjs.tap(([, highlights]) => {
382
+ highlights.forEach((highlight) => consolidate(highlight, reader));
383
+ highlightsSubject.next(highlights);
384
+ readerHighlights.layout();
385
+ })
386
+ );
299
387
  rxjs.merge(
300
388
  highlight$,
301
389
  add$,
302
390
  delete$,
303
391
  update$,
304
392
  select$,
305
- annotations$.pipe(
393
+ highlightsConsolidation$,
394
+ highlights$.pipe(
306
395
  rxjs.tap((annotations) => {
307
- report.debug("annotations", annotations);
396
+ report.debug("highlights", annotations);
308
397
  })
309
398
  )
310
399
  ).pipe(rxjs.takeUntil(reader.$.destroy$)).subscribe();
@@ -317,7 +406,7 @@
317
406
  reader.destroy();
318
407
  },
319
408
  annotations: {
320
- annotations$,
409
+ highlights$,
321
410
  highlightTap$: readerHighlights.tap$,
322
411
  isTargetWithinHighlight: readerHighlights.isTargetWithinHighlight,
323
412
  highlight: commands.highlight,
@@ -329,6 +418,7 @@
329
418
  };
330
419
  };
331
420
 
421
+ exports.Highlight = Highlight;
332
422
  exports.annotationsEnhancer = annotationsEnhancer;
333
423
 
334
424
  Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });