|
7 | 7 |
|
8 | 8 | import * as debug_ from "debug";
|
9 | 9 |
|
10 |
| -import { ICssSelector, IProgressionSelector, IReadiumAnnotation, IReadiumAnnotationSet, isCssSelector, ISelector, isProgressionSelector, isTextPositionSelector, isTextQuoteSelector, ITextPositionSelector, ITextQuoteSelector } from "./annotationModel.type"; |
| 10 | +import { ICssSelector, IReadiumAnnotation, IReadiumAnnotationSet, isCssSelector, isProgressionSelector, isTextPositionSelector, isTextQuoteSelector, ITextPositionSelector, ITextQuoteSelector } from "./annotationModel.type"; |
11 | 11 | import { v4 as uuidv4 } from "uuid";
|
12 | 12 | import { _APP_NAME, _APP_VERSION } from "readium-desktop/preprocessor-directives";
|
13 | 13 | import { PublicationView } from "readium-desktop/common/views/publication";
|
14 | 14 | import { rgbToHex } from "readium-desktop/common/rgb";
|
15 | 15 | import { ICacheDocument } from "readium-desktop/common/redux/states/renderer/resourceCache";
|
16 | 16 | import { getDocumentFromICacheDocument } from "readium-desktop/utils/xmlDom";
|
17 |
| -import { createCssSelectorMatcher, createTextPositionSelectorMatcher, createTextQuoteSelectorMatcher, describeTextPosition, describeTextQuote } from "readium-desktop/third_party/apache-annotator/dom"; |
| 17 | +import { createCssSelectorMatcher, createTextPositionSelectorMatcher, createTextQuoteSelectorMatcher } from "readium-desktop/third_party/apache-annotator/dom"; |
18 | 18 | import { makeRefinable } from "readium-desktop/third_party/apache-annotator/selector";
|
19 |
| -import { convertRange, convertRangeInfo, normalizeRange } from "@r2-navigator-js/electron/renderer/webview/selection"; |
| 19 | +import { convertRange, normalizeRange } from "@r2-navigator-js/electron/renderer/webview/selection"; |
20 | 20 | import { MiniLocatorExtended } from "readium-desktop/common/redux/states/locatorInitialState";
|
21 | 21 | import { uniqueCssSelector } from "@r2-navigator-js/electron/renderer/common/cssselector3";
|
22 | 22 | import { IRangeInfo, ISelectedTextInfo, ISelectionInfo } from "@r2-navigator-js/electron/common/selection";
|
@@ -235,117 +235,19 @@ export async function convertSelectorTargetToLocatorExtended(target: IReadiumAnn
|
235 | 235 | return locatorExtended;
|
236 | 236 | }
|
237 | 237 |
|
238 |
| -export type INoteStateWithICacheDocument = INoteState & { __cacheDocument?: ICacheDocument | undefined }; |
| 238 | +// export type INoteStateWithICacheDocument = INoteState & { __cacheDocument?: ICacheDocument | undefined }; |
239 | 239 |
|
240 |
| -const describeCssSelectorWithTextPosition = async (range: Range, document: Document, root: HTMLElement): Promise<ICssSelector<ITextPositionSelector> | undefined> => { |
241 |
| - // normalizeRange can fundamentally alter the DOM Range by repositioning / snapping to Text boundaries, this is an internal implementation detail inside navigator when CREATING ranges from user document selections. |
242 |
| - // const rangeNormalize = normalizeRange(range); // from r2-nav and not from third-party/apache-annotator |
| 240 | +export function convertAnnotationStateToReadiumAnnotation(note: INoteState): IReadiumAnnotation { |
243 | 241 |
|
244 |
| - const commonAncestorHTMLElement = |
245 |
| - (range.commonAncestorContainer && range.commonAncestorContainer.nodeType === Node.ELEMENT_NODE) |
246 |
| - ? range.commonAncestorContainer as Element |
247 |
| - : (range.startContainer.parentNode && range.startContainer.parentNode.nodeType === Node.ELEMENT_NODE) |
248 |
| - ? range.startContainer.parentNode as Element |
249 |
| - : undefined; |
250 |
| - if (!commonAncestorHTMLElement) { |
251 |
| - return undefined; |
252 |
| - } |
253 |
| - |
254 |
| - return { |
255 |
| - type: "CssSelector", |
256 |
| - value: uniqueCssSelector(commonAncestorHTMLElement, document, { root }), |
257 |
| - refinedBy: await describeTextPosition( |
258 |
| - range, |
259 |
| - commonAncestorHTMLElement, |
260 |
| - ), |
261 |
| - }; |
262 |
| -}; |
263 |
| - |
264 |
| -export async function convertAnnotationStateToSelector(annotationWithCacheDoc: INoteStateWithICacheDocument, isLcp: boolean): Promise<[ISelector[], isABookmark: boolean]> { |
265 |
| - |
266 |
| - const selector: ISelector<any>[] = []; |
267 |
| - |
268 |
| - const {__cacheDocument, ...annotation} = annotationWithCacheDoc; |
269 |
| - |
270 |
| - const xmlDom = getDocumentFromICacheDocument(__cacheDocument); |
271 |
| - if (!xmlDom) { |
272 |
| - return [[], false]; |
273 |
| - } |
274 |
| - |
275 |
| - const document = xmlDom; |
276 |
| - const root = xmlDom.body; |
277 |
| - |
278 |
| - const { locatorExtended, drawType } = annotation; |
279 |
| - const { selectionInfo, locator } = locatorExtended; |
280 |
| - const { locations } = locator; |
281 |
| - const { progression } = locations; |
282 |
| - |
283 |
| - // the range start/end is guaranteed in document order (internally used in navigator whenever deserialising DOM Ranges from JSON expression) ... but DOM Ranges are always ordered anyway (only the user / document selection object can be reversed) |
284 |
| - const rangeInfo = selectionInfo?.rangeInfo || locator.locations.caretInfo?.rangeInfo; |
285 |
| - if (!rangeInfo) { |
286 |
| - debug("ERROR!! RangeInfo not defined !!!"); |
287 |
| - debug(rangeInfo); |
288 |
| - return [selector, false]; |
289 |
| - } |
290 |
| - const range = convertRangeInfo(xmlDom, rangeInfo); |
291 |
| - debug("Dump range memory found:", range); |
292 |
| - |
293 |
| - if (range.collapsed) { |
294 |
| - debug("RANGE COLLAPSED??! skipping..."); |
295 |
| - return [selector, false]; |
296 |
| - } |
297 |
| - |
298 |
| - // createTextPositionSelectorMatcher() |
299 |
| - const selectorCssSelectorWithTextPosition = await describeCssSelectorWithTextPosition(range, document, root); |
300 |
| - if (selectorCssSelectorWithTextPosition) { |
301 |
| - |
302 |
| - debug("CssWithTextPositionSelector : ", selectorCssSelectorWithTextPosition); |
303 |
| - selector.push(selectorCssSelectorWithTextPosition); |
304 |
| - } |
305 |
| - |
306 |
| - // describeTextPosition() |
307 |
| - const selectorTextPosition = await describeTextPosition(range, root); |
308 |
| - debug("TextPositionSelector : ", selectorTextPosition); |
309 |
| - selector.push(selectorTextPosition); |
310 |
| - |
311 |
| - if (!isLcp) { |
312 |
| - |
313 |
| - // describeTextQuote() |
314 |
| - const selectorTextQuote = await describeTextQuote(range, root); |
315 |
| - debug("TextQuoteSelector : ", selectorTextQuote); |
316 |
| - selector.push(selectorTextQuote); |
317 |
| - } |
318 |
| - |
319 |
| - const progressionSelector: IProgressionSelector = { |
320 |
| - type: "ProgressionSelector", |
321 |
| - value: progression || -1, |
322 |
| - }; |
323 |
| - debug("ProgressionSelector : ", progressionSelector); |
324 |
| - selector.push(progressionSelector); |
325 |
| - |
326 |
| - // Next TODO: CFI !?! |
327 |
| - |
328 |
| - // this normally occurs at import time, but let's save debugging effort by checking immediately when exporting... |
329 |
| - // errors are non-fatal, just hunt for the "IRangeInfo DIFF" console logs |
330 |
| - const isABookmark = drawType === EDrawType.bookmark; // rangeInfo.endContainerChildTextNodeIndex === rangeInfo.startContainerChildTextNodeIndex && rangeInfo.endContainerElementCssSelector === rangeInfo.startContainerElementCssSelector && rangeInfo.endOffset - rangeInfo.startOffset === 1; |
331 |
| - if (IS_DEV) { |
332 |
| - await convertSelectorTargetToLocatorExtended({ source: "", selector }, __cacheDocument, rangeInfo, isABookmark); |
333 |
| - } |
334 |
| - return [selector, isABookmark]; |
335 |
| -} |
336 |
| - |
337 |
| -export async function convertAnnotationStateToReadiumAnnotation(annotation: INoteStateWithICacheDocument, isLcp: boolean): Promise<IReadiumAnnotation> { |
338 |
| - |
339 |
| - const { uuid, color, locatorExtended: def, tags, drawType, textualValue, creator, created, modified } = annotation; |
| 242 | + const { uuid, color, locatorExtended: def, tags, drawType, textualValue, creator, created, modified, readiumAnnotation } = note; |
340 | 243 | const { locator, headings, epubPage/*, selectionInfo*/ } = def;
|
341 | 244 | const { href /*text, locations*/ } = locator;
|
342 | 245 | // const { afterRaw, beforeRaw, highlightRaw } = text || {};
|
343 | 246 | // const { rangeInfo: rangeInfoSelection } = selectionInfo || {};
|
344 | 247 | // const { progression } = locations;
|
345 | 248 |
|
346 | 249 | const highlight = (drawType === EDrawType.solid_background ? "solid" : EDrawType[drawType]) as IReadiumAnnotation["body"]["highlight"];
|
347 |
| - |
348 |
| - const [selector, isABookmark] = await convertAnnotationStateToSelector(annotation, isLcp); |
| 250 | + const isABookmark = drawType === EDrawType.bookmark; |
349 | 251 |
|
350 | 252 | return {
|
351 | 253 | "@context": "http://www.w3.org/ns/anno.jsonld",
|
@@ -374,17 +276,17 @@ export async function convertAnnotationStateToReadiumAnnotation(annotation: INot
|
374 | 276 | headings: (headings || []).map(({ txt, level }) => ({ txt, level })),
|
375 | 277 | page: epubPage || "",
|
376 | 278 | },
|
377 |
| - selector, |
| 279 | + selector: readiumAnnotation?.export?.selector || [], |
378 | 280 | },
|
379 | 281 | motivation: isABookmark ? "bookmarking" : undefined, // isABookmark = drawType === EDrawType.bookmark
|
380 | 282 | };
|
381 | 283 | }
|
382 | 284 |
|
383 |
| -export async function convertAnnotationStateArrayToReadiumAnnotationSet(locale: keyof typeof availableLanguages, annotationArray: INoteStateWithICacheDocument[], publicationView: PublicationView, label?: string): Promise<IReadiumAnnotationSet> { |
| 285 | +export function convertAnnotationStateArrayToReadiumAnnotationSet(locale: keyof typeof availableLanguages, notes: INoteState[], publicationView: PublicationView, label?: string): IReadiumAnnotationSet { |
384 | 286 |
|
385 | 287 | const currentDate = new Date();
|
386 | 288 | const dateString: string = currentDate.toISOString();
|
387 |
| - const isLcp = !!publicationView.lcp; |
| 289 | + // const iLcp = !!publicationView.lcp; |
388 | 290 |
|
389 | 291 | return {
|
390 | 292 | "@context": "http://www.w3.org/ns/anno.jsonld",
|
@@ -412,6 +314,6 @@ export async function convertAnnotationStateArrayToReadiumAnnotationSet(locale:
|
412 | 314 | }) : [],
|
413 | 315 | "dc:date": publicationView.publishedAt || "",
|
414 | 316 | },
|
415 |
| - items: await Promise.all((annotationArray || []).map(async (v) => await convertAnnotationStateToReadiumAnnotation(v, isLcp))), |
| 317 | + items: notes.map((v) => convertAnnotationStateToReadiumAnnotation(v)), |
416 | 318 | };
|
417 | 319 | }
|
0 commit comments