/
parse.ts
61 lines (61 loc) · 2.83 KB
/
parse.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
const assertOk = (ok: unknown, message: string) => {
if (!ok) {
throw new Error(message);
}
};
export type Annotation = {
note?: string;
highlight: string;
locationNumber: number;
kindleUrl: string;
};
export type ParseResult = {
title: string;
coverImageUrl: string;
asin: string;
url: string;
annotations: Annotation[];
};
export const parsePage = (window: Window): ParseResult => {
const pages = window.document.querySelectorAll<HTMLDivElement>("#a-page");
const page = pages[pages.length - 1]; // select child #a-page if nested #a-page
const title = page.querySelector("h3.kp-notebook-metadata") as HTMLHeadingElement;
const coverImage = page.querySelector(".kp-notebook-cover-image-border") as HTMLImageElement;
const asinNode = page.querySelector(`[id="kp-notebook-annotations-asin"]`) as HTMLInputElement;
const asinValue = asinNode.value;
assertOk(coverImage, "coverImage not found");
assertOk(asinNode, "ASIN not found");
assertOk(title, "title not found");
const annotationNodes = page.querySelectorAll<HTMLDivElement>("#kp-notebook-annotations > div.a-row");
assertOk(annotationNodes.length > 0, "annotations not found");
const annotations: Annotation[] = Array.from(annotationNodes)
.filter((annotation) => {
return annotation.getAttribute("id") !== "empty-annotations-pane";
})
.map((annotation) => {
const noteNode = annotation.querySelector(`[id="note"]`) as HTMLSpanElement;
const noteValue = noteNode && noteNode.textContent ? noteNode.textContent : undefined;
const locationNode = annotation.querySelector(`[id="kp-annotation-location"]`) as HTMLInputElement;
assertOk(locationNode, "locationNode is not found");
const highlightNode = annotation.querySelector(`[id="highlight"]`) as HTMLSpanElement;
// Kindle disappear the highlight, see https://github.com/azu/kindle-highlight-to-markdown/issues/3
// Sorry, we’re unable to display this type of content.
const isEmptyHighlight = highlightNode === null;
const highlightText = isEmptyHighlight ? "" : highlightNode.textContent;
assertOk(highlightText !== undefined, "highlightText is not found");
const locationNumber = Number(locationNode.value);
return {
note: noteValue,
locationNumber: locationNumber,
highlight: highlightText as string,
kindleUrl: `kindle://book?action=open&asin=${asinValue}&location=${locationNumber}`
};
});
return {
title: title.textContent?.trim() ?? "",
coverImageUrl: coverImage.src,
asin: asinValue,
url: `https://www.amazon.co.jp/dp/${asinValue}`, // TODO: hardcode
annotations
};
};