vue-book-reader 1.2.2 → 1.2.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,323 +0,0 @@
1
- const normalizeWhitespace = (str) => str ? str.replace(/[\t\n\f\r ]+/g, " ").replace(/^[\t\n\f\r ]+/, "").replace(/[\t\n\f\r ]+$/, "") : "";
2
- const getElementText = (el) => normalizeWhitespace(el == null ? void 0 : el.textContent);
3
- const NS = {
4
- XLINK: "http://www.w3.org/1999/xlink",
5
- EPUB: "http://www.idpf.org/2007/ops"
6
- };
7
- const MIME = {
8
- XML: "application/xml",
9
- XHTML: "application/xhtml+xml"
10
- };
11
- const STYLE = {
12
- "strong": ["strong", "self"],
13
- "emphasis": ["em", "self"],
14
- "style": ["span", "self"],
15
- "a": "anchor",
16
- "strikethrough": ["s", "self"],
17
- "sub": ["sub", "self"],
18
- "sup": ["sup", "self"],
19
- "code": ["code", "self"],
20
- "image": "image"
21
- };
22
- const TABLE = {
23
- "tr": ["tr", {
24
- "th": ["th", STYLE, ["colspan", "rowspan", "align", "valign"]],
25
- "td": ["td", STYLE, ["colspan", "rowspan", "align", "valign"]]
26
- }, ["align"]]
27
- };
28
- const POEM = {
29
- "epigraph": ["blockquote"],
30
- "subtitle": ["h2", STYLE],
31
- "text-author": ["p", STYLE],
32
- "date": ["p", STYLE],
33
- "stanza": "stanza"
34
- };
35
- const SECTION = {
36
- "title": ["header", {
37
- "p": ["h1", STYLE],
38
- "empty-line": ["br"]
39
- }],
40
- "epigraph": ["blockquote", "self"],
41
- "image": "image",
42
- "annotation": ["aside"],
43
- "section": ["section", "self"],
44
- "p": ["p", STYLE],
45
- "poem": ["blockquote", POEM],
46
- "subtitle": ["h2", STYLE],
47
- "cite": ["blockquote", "self"],
48
- "empty-line": ["br"],
49
- "table": ["table", TABLE],
50
- "text-author": ["p", STYLE]
51
- };
52
- POEM["epigraph"].push(SECTION);
53
- const BODY = {
54
- "image": "image",
55
- "title": ["section", {
56
- "p": ["h1", STYLE],
57
- "empty-line": ["br"]
58
- }],
59
- "epigraph": ["section", SECTION],
60
- "section": ["section", SECTION]
61
- };
62
- class FB2Converter {
63
- constructor(fb2) {
64
- this.fb2 = fb2;
65
- this.doc = document.implementation.createDocument(NS.XHTML, "html");
66
- this.bins = new Map(Array.from(
67
- this.fb2.getElementsByTagName("binary"),
68
- (el) => [el.id, el]
69
- ));
70
- }
71
- getImageSrc(el) {
72
- const href = el.getAttributeNS(NS.XLINK, "href");
73
- if (!href) return "data:,";
74
- const [, id] = href.split("#");
75
- if (!id) return href;
76
- const bin = this.bins.get(id);
77
- return bin ? `data:${bin.getAttribute("content-type")};base64,${bin.textContent}` : href;
78
- }
79
- image(node) {
80
- const el = this.doc.createElement("img");
81
- el.alt = node.getAttribute("alt");
82
- el.title = node.getAttribute("title");
83
- el.setAttribute("src", this.getImageSrc(node));
84
- return el;
85
- }
86
- anchor(node) {
87
- const el = this.convert(node, { "a": ["a", STYLE] });
88
- el.setAttribute("href", node.getAttributeNS(NS.XLINK, "href"));
89
- if (node.getAttribute("type") === "note")
90
- el.setAttributeNS(NS.EPUB, "epub:type", "noteref");
91
- return el;
92
- }
93
- stanza(node) {
94
- const el = this.convert(node, {
95
- "stanza": ["p", {
96
- "title": ["header", {
97
- "p": ["strong", STYLE],
98
- "empty-line": ["br"]
99
- }],
100
- "subtitle": ["p", STYLE]
101
- }]
102
- });
103
- for (const child of node.children) if (child.nodeName === "v") {
104
- el.append(this.doc.createTextNode(child.textContent));
105
- el.append(this.doc.createElement("br"));
106
- }
107
- return el;
108
- }
109
- convert(node, def) {
110
- if (node.nodeType === 3) return this.doc.createTextNode(node.textContent);
111
- if (node.nodeType === 4) return this.doc.createCDATASection(node.textContent);
112
- if (node.nodeType === 8) return this.doc.createComment(node.textContent);
113
- const d = def == null ? void 0 : def[node.nodeName];
114
- if (!d) return null;
115
- if (typeof d === "string") return this[d](node);
116
- const [name, opts, attrs] = d;
117
- const el = this.doc.createElement(name);
118
- if (node.id) el.id = node.id;
119
- el.classList.add(node.nodeName);
120
- if (Array.isArray(attrs)) for (const attr of attrs) {
121
- const value = node.getAttribute(attr);
122
- if (value) el.setAttribute(attr, value);
123
- }
124
- const childDef = opts === "self" ? def : opts;
125
- let child = node.firstChild;
126
- while (child) {
127
- const childEl = this.convert(child, childDef);
128
- if (childEl) el.append(childEl);
129
- child = child.nextSibling;
130
- }
131
- return el;
132
- }
133
- }
134
- const parseXML = async (blob) => {
135
- var _a;
136
- const buffer = await blob.arrayBuffer();
137
- const str = new TextDecoder("utf-8").decode(buffer);
138
- const parser = new DOMParser();
139
- const doc = parser.parseFromString(str, MIME.XML);
140
- const encoding = doc.xmlEncoding || ((_a = str.match(/^<\?xml\s+version\s*=\s*["']1.\d+"\s+encoding\s*=\s*["']([A-Za-z0-9._-]*)["']/)) == null ? void 0 : _a[1]);
141
- if (encoding && encoding.toLowerCase() !== "utf-8") {
142
- const str2 = new TextDecoder(encoding).decode(buffer);
143
- return parser.parseFromString(str2, MIME.XML);
144
- }
145
- return doc;
146
- };
147
- const style = URL.createObjectURL(new Blob([`
148
- @namespace epub "http://www.idpf.org/2007/ops";
149
- body > img, section > img {
150
- display: block;
151
- margin: auto;
152
- }
153
- .title h1 {
154
- text-align: center;
155
- }
156
- body > section > .title, body.notesBodyType > .title {
157
- margin: 3em 0;
158
- }
159
- body.notesBodyType > section .title h1 {
160
- text-align: start;
161
- }
162
- body.notesBodyType > section .title {
163
- margin: 1em 0;
164
- }
165
- p {
166
- text-indent: 1em;
167
- margin: 0;
168
- }
169
- :not(p) + p, p:first-child {
170
- text-indent: 0;
171
- }
172
- .poem p {
173
- text-indent: 0;
174
- margin: 1em 0;
175
- }
176
- .text-author, .date {
177
- text-align: end;
178
- }
179
- .text-author:before {
180
- content: "—";
181
- }
182
- table {
183
- border-collapse: collapse;
184
- }
185
- td, th {
186
- padding: .25em;
187
- }
188
- a[epub|type~="noteref"] {
189
- font-size: .75em;
190
- vertical-align: super;
191
- }
192
- body:not(.notesBodyType) > .title, body:not(.notesBodyType) > .epigraph {
193
- margin: 3em 0;
194
- }
195
- `], { type: "text/css" }));
196
- const template = (html) => `<?xml version="1.0" encoding="utf-8"?>
197
- <html xmlns="http://www.w3.org/1999/xhtml">
198
- <head><link href="${style}" rel="stylesheet" type="text/css"/></head>
199
- <body>${html}</body>
200
- </html>`;
201
- const dataID = "data-foliate-id";
202
- const makeFB2 = async (blob) => {
203
- const book = {};
204
- const doc = await parseXML(blob);
205
- const converter = new FB2Converter(doc);
206
- const $ = (x) => doc.querySelector(x);
207
- const $$ = (x) => [...doc.querySelectorAll(x)];
208
- const getPerson = (el) => {
209
- const nick = getElementText(el.querySelector("nickname"));
210
- if (nick) return nick;
211
- const first = getElementText(el.querySelector("first-name"));
212
- const middle = getElementText(el.querySelector("middle-name"));
213
- const last = getElementText(el.querySelector("last-name"));
214
- const name = [first, middle, last].filter((x) => x).join(" ");
215
- const sortAs = last ? [last, [first, middle].filter((x) => x).join(" ")].join(", ") : null;
216
- return { name, sortAs };
217
- };
218
- const getDate = (el) => (el == null ? void 0 : el.getAttribute("value")) ?? getElementText(el);
219
- const annotation = $("title-info annotation");
220
- book.metadata = {
221
- title: getElementText($("title-info book-title")),
222
- identifier: getElementText($("document-info id")),
223
- language: getElementText($("title-info lang")),
224
- author: $$("title-info author").map(getPerson),
225
- translator: $$("title-info translator").map(getPerson),
226
- contributor: $$("document-info author").map(getPerson).concat($$("document-info program-used").map(getElementText)).map((x) => Object.assign(
227
- typeof x === "string" ? { name: x } : x,
228
- { role: "bkp" }
229
- )),
230
- publisher: getElementText($("publish-info publisher")),
231
- published: getDate($("title-info date")),
232
- modified: getDate($("document-info date")),
233
- description: annotation ? converter.convert(
234
- annotation,
235
- { annotation: ["div", SECTION] }
236
- ).innerHTML : null,
237
- subject: $$("title-info genre").map(getElementText)
238
- };
239
- if ($("coverpage image")) {
240
- const src = converter.getImageSrc($("coverpage image"));
241
- book.getCover = () => fetch(src).then((res) => res.blob());
242
- } else book.getCover = () => null;
243
- const bodyData = Array.from(doc.querySelectorAll("body"), (body) => {
244
- const converted = converter.convert(body, { body: ["body", BODY] });
245
- return [Array.from(converted.children, (el) => {
246
- const ids = [el, ...el.querySelectorAll("[id]")].map((el2) => el2.id);
247
- return { el, ids };
248
- }), converted];
249
- });
250
- const urls = [];
251
- const sectionData = bodyData[0][0].map(({ el, ids }) => {
252
- const titles = Array.from(
253
- el.querySelectorAll(":scope > section > .title"),
254
- (el2, index) => {
255
- el2.setAttribute(dataID, index);
256
- return { title: getElementText(el2), index };
257
- }
258
- );
259
- return { ids, titles, el };
260
- }).concat(bodyData.slice(1).map(([sections, body]) => {
261
- const ids = sections.map((s) => s.ids).flat();
262
- body.classList.add("notesBodyType");
263
- return { ids, el: body, linear: "no" };
264
- })).map(({ ids, titles, el, linear }) => {
265
- var _a;
266
- const str = template(el.outerHTML);
267
- const blob2 = new Blob([str], { type: MIME.XHTML });
268
- const url = URL.createObjectURL(blob2);
269
- urls.push(url);
270
- const title = normalizeWhitespace(
271
- ((_a = el.querySelector(".title, .subtitle, p")) == null ? void 0 : _a.textContent) ?? (el.classList.contains("title") ? el.textContent : "")
272
- );
273
- return {
274
- ids,
275
- title,
276
- titles,
277
- load: () => url,
278
- createDocument: () => new DOMParser().parseFromString(str, MIME.XHTML),
279
- // doo't count image data as it'd skew the size too much
280
- size: blob2.size - Array.from(
281
- el.querySelectorAll("[src]"),
282
- (el2) => {
283
- var _a2;
284
- return ((_a2 = el2.getAttribute("src")) == null ? void 0 : _a2.length) ?? 0;
285
- }
286
- ).reduce((a, b) => a + b, 0),
287
- linear
288
- };
289
- });
290
- const idMap = /* @__PURE__ */ new Map();
291
- book.sections = sectionData.map((section, index) => {
292
- const { ids, load, createDocument, size, linear } = section;
293
- for (const id of ids) if (id) idMap.set(id, index);
294
- return { id: index, load, createDocument, size, linear };
295
- });
296
- book.toc = sectionData.map(({ title, titles }, index) => {
297
- const id = index.toString();
298
- return {
299
- label: title,
300
- href: id,
301
- subitems: (titles == null ? void 0 : titles.length) ? titles.map(({ title: title2, index: index2 }) => ({
302
- label: title2,
303
- href: `${id}#${index2}`
304
- })) : null
305
- };
306
- }).filter((item) => item);
307
- book.resolveHref = (href) => {
308
- const [a, b] = href.split("#");
309
- return a ? { index: Number(a), anchor: (doc2) => doc2.querySelector(`[${dataID}="${b}"]`) } : { index: idMap.get(b), anchor: (doc2) => doc2.getElementById(b) };
310
- };
311
- book.splitTOCHref = (href) => {
312
- var _a;
313
- return ((_a = href == null ? void 0 : href.split("#")) == null ? void 0 : _a.map((x) => Number(x))) ?? [];
314
- };
315
- book.getTOCFragment = (doc2, id) => doc2.querySelector(`[${dataID}="${id}"]`);
316
- book.destroy = () => {
317
- for (const url of urls) URL.revokeObjectURL(url);
318
- };
319
- return book;
320
- };
321
- export {
322
- makeFB2
323
- };
@@ -1,323 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
- const normalizeWhitespace$1 = (str) => str ? str.replace(/[\t\n\f\r ]+/g, " ").replace(/^[\t\n\f\r ]+/, "").replace(/[\t\n\f\r ]+$/, "") : "";
4
- const getElementText = (el) => normalizeWhitespace$1(el == null ? void 0 : el.textContent);
5
- const NS$1 = {
6
- XLINK: "http://www.w3.org/1999/xlink",
7
- EPUB: "http://www.idpf.org/2007/ops"
8
- };
9
- const MIME$1 = {
10
- XML: "application/xml",
11
- XHTML: "application/xhtml+xml"
12
- };
13
- const STYLE = {
14
- "strong": ["strong", "self"],
15
- "emphasis": ["em", "self"],
16
- "style": ["span", "self"],
17
- "a": "anchor",
18
- "strikethrough": ["s", "self"],
19
- "sub": ["sub", "self"],
20
- "sup": ["sup", "self"],
21
- "code": ["code", "self"],
22
- "image": "image"
23
- };
24
- const TABLE = {
25
- "tr": ["tr", {
26
- "th": ["th", STYLE, ["colspan", "rowspan", "align", "valign"]],
27
- "td": ["td", STYLE, ["colspan", "rowspan", "align", "valign"]]
28
- }, ["align"]]
29
- };
30
- const POEM = {
31
- "epigraph": ["blockquote"],
32
- "subtitle": ["h2", STYLE],
33
- "text-author": ["p", STYLE],
34
- "date": ["p", STYLE],
35
- "stanza": "stanza"
36
- };
37
- const SECTION = {
38
- "title": ["header", {
39
- "p": ["h1", STYLE],
40
- "empty-line": ["br"]
41
- }],
42
- "epigraph": ["blockquote", "self"],
43
- "image": "image",
44
- "annotation": ["aside"],
45
- "section": ["section", "self"],
46
- "p": ["p", STYLE],
47
- "poem": ["blockquote", POEM],
48
- "subtitle": ["h2", STYLE],
49
- "cite": ["blockquote", "self"],
50
- "empty-line": ["br"],
51
- "table": ["table", TABLE],
52
- "text-author": ["p", STYLE]
53
- };
54
- POEM["epigraph"].push(SECTION);
55
- const BODY = {
56
- "image": "image",
57
- "title": ["section", {
58
- "p": ["h1", STYLE],
59
- "empty-line": ["br"]
60
- }],
61
- "epigraph": ["section", SECTION],
62
- "section": ["section", SECTION]
63
- };
64
- class FB2Converter {
65
- constructor(fb2) {
66
- this.fb2 = fb2;
67
- this.doc = document.implementation.createDocument(NS$1.XHTML, "html");
68
- this.bins = new Map(Array.from(
69
- this.fb2.getElementsByTagName("binary"),
70
- (el) => [el.id, el]
71
- ));
72
- }
73
- getImageSrc(el) {
74
- const href = el.getAttributeNS(NS$1.XLINK, "href");
75
- if (!href) return "data:,";
76
- const [, id] = href.split("#");
77
- if (!id) return href;
78
- const bin = this.bins.get(id);
79
- return bin ? `data:${bin.getAttribute("content-type")};base64,${bin.textContent}` : href;
80
- }
81
- image(node) {
82
- const el = this.doc.createElement("img");
83
- el.alt = node.getAttribute("alt");
84
- el.title = node.getAttribute("title");
85
- el.setAttribute("src", this.getImageSrc(node));
86
- return el;
87
- }
88
- anchor(node) {
89
- const el = this.convert(node, { "a": ["a", STYLE] });
90
- el.setAttribute("href", node.getAttributeNS(NS$1.XLINK, "href"));
91
- if (node.getAttribute("type") === "note")
92
- el.setAttributeNS(NS$1.EPUB, "epub:type", "noteref");
93
- return el;
94
- }
95
- stanza(node) {
96
- const el = this.convert(node, {
97
- "stanza": ["p", {
98
- "title": ["header", {
99
- "p": ["strong", STYLE],
100
- "empty-line": ["br"]
101
- }],
102
- "subtitle": ["p", STYLE]
103
- }]
104
- });
105
- for (const child of node.children) if (child.nodeName === "v") {
106
- el.append(this.doc.createTextNode(child.textContent));
107
- el.append(this.doc.createElement("br"));
108
- }
109
- return el;
110
- }
111
- convert(node, def) {
112
- if (node.nodeType === 3) return this.doc.createTextNode(node.textContent);
113
- if (node.nodeType === 4) return this.doc.createCDATASection(node.textContent);
114
- if (node.nodeType === 8) return this.doc.createComment(node.textContent);
115
- const d = def == null ? void 0 : def[node.nodeName];
116
- if (!d) return null;
117
- if (typeof d === "string") return this[d](node);
118
- const [name, opts, attrs] = d;
119
- const el = this.doc.createElement(name);
120
- if (node.id) el.id = node.id;
121
- el.classList.add(node.nodeName);
122
- if (Array.isArray(attrs)) for (const attr of attrs) {
123
- const value = node.getAttribute(attr);
124
- if (value) el.setAttribute(attr, value);
125
- }
126
- const childDef = opts === "self" ? def : opts;
127
- let child = node.firstChild;
128
- while (child) {
129
- const childEl = this.convert(child, childDef);
130
- if (childEl) el.append(childEl);
131
- child = child.nextSibling;
132
- }
133
- return el;
134
- }
135
- }
136
- const parseXML = async (blob) => {
137
- var _a;
138
- const buffer = await blob.arrayBuffer();
139
- const str = new TextDecoder("utf-8").decode(buffer);
140
- const parser = new DOMParser();
141
- const doc = parser.parseFromString(str, MIME$1.XML);
142
- const encoding = doc.xmlEncoding || ((_a = str.match(/^<\?xml\s+version\s*=\s*["']1.\d+"\s+encoding\s*=\s*["']([A-Za-z0-9._-]*)["']/)) == null ? void 0 : _a[1]);
143
- if (encoding && encoding.toLowerCase() !== "utf-8") {
144
- const str2 = new TextDecoder(encoding).decode(buffer);
145
- return parser.parseFromString(str2, MIME$1.XML);
146
- }
147
- return doc;
148
- };
149
- const style = URL.createObjectURL(new Blob([`
150
- @namespace epub "http://www.idpf.org/2007/ops";
151
- body > img, section > img {
152
- display: block;
153
- margin: auto;
154
- }
155
- .title h1 {
156
- text-align: center;
157
- }
158
- body > section > .title, body.notesBodyType > .title {
159
- margin: 3em 0;
160
- }
161
- body.notesBodyType > section .title h1 {
162
- text-align: start;
163
- }
164
- body.notesBodyType > section .title {
165
- margin: 1em 0;
166
- }
167
- p {
168
- text-indent: 1em;
169
- margin: 0;
170
- }
171
- :not(p) + p, p:first-child {
172
- text-indent: 0;
173
- }
174
- .poem p {
175
- text-indent: 0;
176
- margin: 1em 0;
177
- }
178
- .text-author, .date {
179
- text-align: end;
180
- }
181
- .text-author:before {
182
- content: "—";
183
- }
184
- table {
185
- border-collapse: collapse;
186
- }
187
- td, th {
188
- padding: .25em;
189
- }
190
- a[epub|type~="noteref"] {
191
- font-size: .75em;
192
- vertical-align: super;
193
- }
194
- body:not(.notesBodyType) > .title, body:not(.notesBodyType) > .epigraph {
195
- margin: 3em 0;
196
- }
197
- `], { type: "text/css" }));
198
- const template = (html) => `<?xml version="1.0" encoding="utf-8"?>
199
- <html xmlns="http://www.w3.org/1999/xhtml">
200
- <head><link href="${style}" rel="stylesheet" type="text/css"/></head>
201
- <body>${html}</body>
202
- </html>`;
203
- const dataID = "data-foliate-id";
204
- const makeFB2 = async (blob) => {
205
- const book = {};
206
- const doc = await parseXML(blob);
207
- const converter = new FB2Converter(doc);
208
- const $ = (x) => doc.querySelector(x);
209
- const $$ = (x) => [...doc.querySelectorAll(x)];
210
- const getPerson = (el) => {
211
- const nick = getElementText(el.querySelector("nickname"));
212
- if (nick) return nick;
213
- const first = getElementText(el.querySelector("first-name"));
214
- const middle = getElementText(el.querySelector("middle-name"));
215
- const last = getElementText(el.querySelector("last-name"));
216
- const name = [first, middle, last].filter((x) => x).join(" ");
217
- const sortAs = last ? [last, [first, middle].filter((x) => x).join(" ")].join(", ") : null;
218
- return { name, sortAs };
219
- };
220
- const getDate = (el) => (el == null ? void 0 : el.getAttribute("value")) ?? getElementText(el);
221
- const annotation = $("title-info annotation");
222
- book.metadata = {
223
- title: getElementText($("title-info book-title")),
224
- identifier: getElementText($("document-info id")),
225
- language: getElementText($("title-info lang")),
226
- author: $$("title-info author").map(getPerson),
227
- translator: $$("title-info translator").map(getPerson),
228
- contributor: $$("document-info author").map(getPerson).concat($$("document-info program-used").map(getElementText)).map((x) => Object.assign(
229
- typeof x === "string" ? { name: x } : x,
230
- { role: "bkp" }
231
- )),
232
- publisher: getElementText($("publish-info publisher")),
233
- published: getDate($("title-info date")),
234
- modified: getDate($("document-info date")),
235
- description: annotation ? converter.convert(
236
- annotation,
237
- { annotation: ["div", SECTION] }
238
- ).innerHTML : null,
239
- subject: $$("title-info genre").map(getElementText)
240
- };
241
- if ($("coverpage image")) {
242
- const src = converter.getImageSrc($("coverpage image"));
243
- book.getCover = () => fetch(src).then((res) => res.blob());
244
- } else book.getCover = () => null;
245
- const bodyData = Array.from(doc.querySelectorAll("body"), (body) => {
246
- const converted = converter.convert(body, { body: ["body", BODY] });
247
- return [Array.from(converted.children, (el) => {
248
- const ids = [el, ...el.querySelectorAll("[id]")].map((el2) => el2.id);
249
- return { el, ids };
250
- }), converted];
251
- });
252
- const urls = [];
253
- const sectionData = bodyData[0][0].map(({ el, ids }) => {
254
- const titles = Array.from(
255
- el.querySelectorAll(":scope > section > .title"),
256
- (el2, index) => {
257
- el2.setAttribute(dataID, index);
258
- return { title: getElementText(el2), index };
259
- }
260
- );
261
- return { ids, titles, el };
262
- }).concat(bodyData.slice(1).map(([sections, body]) => {
263
- const ids = sections.map((s) => s.ids).flat();
264
- body.classList.add("notesBodyType");
265
- return { ids, el: body, linear: "no" };
266
- })).map(({ ids, titles, el, linear }) => {
267
- var _a;
268
- const str = template(el.outerHTML);
269
- const blob2 = new Blob([str], { type: MIME$1.XHTML });
270
- const url = URL.createObjectURL(blob2);
271
- urls.push(url);
272
- const title = normalizeWhitespace$1(
273
- ((_a = el.querySelector(".title, .subtitle, p")) == null ? void 0 : _a.textContent) ?? (el.classList.contains("title") ? el.textContent : "")
274
- );
275
- return {
276
- ids,
277
- title,
278
- titles,
279
- load: () => url,
280
- createDocument: () => new DOMParser().parseFromString(str, MIME$1.XHTML),
281
- // doo't count image data as it'd skew the size too much
282
- size: blob2.size - Array.from(
283
- el.querySelectorAll("[src]"),
284
- (el2) => {
285
- var _a2;
286
- return ((_a2 = el2.getAttribute("src")) == null ? void 0 : _a2.length) ?? 0;
287
- }
288
- ).reduce((a, b) => a + b, 0),
289
- linear
290
- };
291
- });
292
- const idMap = /* @__PURE__ */ new Map();
293
- book.sections = sectionData.map((section, index) => {
294
- const { ids, load, createDocument, size, linear } = section;
295
- for (const id of ids) if (id) idMap.set(id, index);
296
- return { id: index, load, createDocument, size, linear };
297
- });
298
- book.toc = sectionData.map(({ title, titles }, index) => {
299
- const id = index.toString();
300
- return {
301
- label: title,
302
- href: id,
303
- subitems: (titles == null ? void 0 : titles.length) ? titles.map(({ title: title2, index: index2 }) => ({
304
- label: title2,
305
- href: `${id}#${index2}`
306
- })) : null
307
- };
308
- }).filter((item) => item);
309
- book.resolveHref = (href) => {
310
- const [a, b] = href.split("#");
311
- return a ? { index: Number(a), anchor: (doc2) => doc2.querySelector(`[${dataID}="${b}"]`) } : { index: idMap.get(b), anchor: (doc2) => doc2.getElementById(b) };
312
- };
313
- book.splitTOCHref = (href) => {
314
- var _a;
315
- return ((_a = href == null ? void 0 : href.split("#")) == null ? void 0 : _a.map((x) => Number(x))) ?? [];
316
- };
317
- book.getTOCFragment = (doc2, id) => doc2.querySelector(`[${dataID}="${id}"]`);
318
- book.destroy = () => {
319
- for (const url of urls) URL.revokeObjectURL(url);
320
- };
321
- return book;
322
- };
323
- exports.makeFB2 = makeFB2;