UNPKG

vue-book-reader

Version:

vue-book-reader is a vue wrapper for [foliate-js](https://github.com/johnfactotum/foliate-js) - library for rendering e-books in the browser. Supports EPUB, MOBI, KF8 (AZW3), FB2, CBZ, PDF (experimental; requires PDF.js), or add support for other formats

224 lines (223 loc) 9.47 kB
var K = Object.defineProperty; var Q = (r, h, t) => h in r ? K(r, h, { enumerable: !0, configurable: !0, writable: !0, value: t }) : r[h] = t; var D = (r, h, t) => (Q(r, typeof h != "symbol" ? h + "" : h, t), t), W = (r, h, t) => { if (!h.has(r)) throw TypeError("Cannot " + t); }; var n = (r, h, t) => (W(r, h, "read from private field"), t ? t.call(r) : h.get(r)), f = (r, h, t) => { if (h.has(r)) throw TypeError("Cannot add the same private member more than once"); h instanceof WeakSet ? h.add(r) : h.set(r, t); }, p = (r, h, t, e) => (W(r, h, "write to private field"), e ? e.call(r, t) : h.set(r, t), t); var c = (r, h, t) => (W(r, h, "access private method"), t); const I = (r) => { var h, t; return (t = (h = r == null ? void 0 : r.split(/[,;\s]/)) == null ? void 0 : h.filter((e) => e)) == null ? void 0 : t.map((e) => e.split("=").map((i) => i.trim())); }, U = (r, h) => { var i, s; if (r.documentElement.localName === "svg") { const [, , a, o] = ((i = r.documentElement.getAttribute("viewBox")) == null ? void 0 : i.split(/\s/)) ?? []; return { width: a, height: o }; } const t = I((s = r.querySelector('meta[name="viewport"]')) == null ? void 0 : s.getAttribute("content")); if (t) return Object.fromEntries(t); if (typeof h == "string") return I(h); if (h) return h; const e = r.querySelector("img"); return e ? { width: e.naturalWidth, height: e.naturalHeight } : (console.warn(new Error("Missing viewport properties")), { width: 1e3, height: 2e3 }); }; var k, j, x, S, L, w, y, b, v, A, H, E, C, M, N, R, P, V, G, T, z; class X extends HTMLElement { constructor() { super(); f(this, A); f(this, E); f(this, M); f(this, R); f(this, V); f(this, T); f(this, k, this.attachShadow({ mode: "closed" })); f(this, j, new ResizeObserver(() => c(this, E, C).call(this))); f(this, x, void 0); f(this, S, -1); D(this, "defaultViewport"); D(this, "spread"); f(this, L, !1); f(this, w, void 0); f(this, y, void 0); f(this, b, void 0); f(this, v, void 0); const t = new CSSStyleSheet(); n(this, k).adoptedStyleSheets = [t], t.replaceSync(`:host { width: 100%; height: 100%; display: flex; justify-content: center; align-items: center; }`), n(this, j).observe(this); } open(t) { this.book = t; const { rendition: e } = t; this.spread = e == null ? void 0 : e.spread, this.defaultViewport = e == null ? void 0 : e.viewport; const i = t.dir === "rtl", s = !i; this.rtl = i, (e == null ? void 0 : e.spread) === "none" ? p(this, x, t.sections.map((a) => ({ center: a }))) : p(this, x, t.sections.reduce((a, o) => { const l = a[a.length - 1], { linear: m, pageSpread: g } = o; if (m === "no") return a; const u = () => { const d = {}; return a.push(d), d; }; if (g === "center") { const d = l.left || l.right ? u() : l; d.center = o; } else if (g === "left") { const d = l.center || l.left || s ? u() : l; d.left = o; } else if (g === "right") { const d = l.center || l.right || i ? u() : l; d.right = o; } else s ? l.center || l.right ? u().left = o : l.left ? l.right = o : l.left = o : l.center || l.left ? u().right = o : l.right ? l.left = o : l.right = o; return a; }, [{}])); } get index() { const t = n(this, x)[n(this, S)], e = (t == null ? void 0 : t.center) ?? (this.side === "left" ? t.left ?? t.right : t.right ?? t.left); return this.book.sections.indexOf(e); } getSpreadOf(t) { const e = n(this, x); for (let i = 0; i < e.length; i++) { const { left: s, right: a, center: o } = e[i]; if (s === t) return { index: i, side: "left" }; if (a === t) return { index: i, side: "right" }; if (o === t) return { index: i, side: "center" }; } } async goToSpread(t, e, i) { var a, o, l, m, g, u; if (t < 0 || t > n(this, x).length - 1) return; if (t === n(this, S)) { c(this, E, C).call(this, e); return; } p(this, S, t); const s = n(this, x)[t]; if (s.center) { const d = this.book.sections.indexOf(s.center), O = await ((o = (a = s.center) == null ? void 0 : a.load) == null ? void 0 : o.call(a)); await c(this, M, N).call(this, { center: { index: d, src: O } }); } else { const d = this.book.sections.indexOf(s.left), O = this.book.sections.indexOf(s.right), $ = await ((m = (l = s.left) == null ? void 0 : l.load) == null ? void 0 : m.call(l)), B = await ((u = (g = s.right) == null ? void 0 : g.load) == null ? void 0 : u.call(g)), F = { index: d, src: $ }, q = { index: O, src: B }; await c(this, M, N).call(this, { left: F, right: q, side: e }); } c(this, T, z).call(this, i); } async select(t) { await this.goTo(t); } async goTo(t) { const { book: e } = this, i = await t, s = e.sections[i.index]; if (!s) return; const { index: a, side: o } = this.getSpreadOf(s); await this.goToSpread(a, o); } async next() { if (this.rtl ? c(this, R, P).call(this) : c(this, V, G).call(this)) c(this, T, z).call(this, "page"); else return this.goToSpread(n(this, S) + 1, this.rtl ? "right" : "left", "page"); } async prev() { if (this.rtl ? c(this, V, G).call(this) : c(this, R, P).call(this)) c(this, T, z).call(this, "page"); else return this.goToSpread(n(this, S) - 1, this.rtl ? "left" : "right", "page"); } getContents() { return Array.from(n(this, k).querySelectorAll("iframe"), (t) => ({ doc: t.contentDocument // TODO: index, overlayer })); } destroy() { n(this, j).unobserve(this); } } k = new WeakMap(), j = new WeakMap(), x = new WeakMap(), S = new WeakMap(), L = new WeakMap(), w = new WeakMap(), y = new WeakMap(), b = new WeakMap(), v = new WeakMap(), A = new WeakSet(), H = async function({ index: t, src: e }) { const i = document.createElement("div"), s = document.createElement("iframe"); return i.append(s), Object.assign(s.style, { border: "0", display: "none", overflow: "hidden" }), s.setAttribute("sandbox", "allow-same-origin allow-scripts"), s.setAttribute("scrolling", "no"), s.setAttribute("part", "filter"), n(this, k).append(i), e ? new Promise((a) => { const o = () => { s.removeEventListener("load", o); const l = s.contentDocument; this.dispatchEvent(new CustomEvent("load", { detail: { doc: l, index: t } })); const { width: m, height: g } = U(l, this.defaultViewport); a({ element: i, iframe: s, width: parseFloat(m), height: parseFloat(g) }); }; s.addEventListener("load", o), s.src = e; }) : { blank: !0, element: i, iframe: s }; }, E = new WeakSet(), C = function(t = n(this, v)) { if (!t) return; const e = n(this, w) ?? {}, i = n(this, b) ?? n(this, y), s = t === "left" ? e : i, { width: a, height: o } = this.getBoundingClientRect(), l = this.spread !== "both" && this.spread !== "portrait" && o > a; p(this, L, l); const m = e.width ?? i.width, g = e.height ?? i.height, u = l || n(this, b) ? Math.min( a / (s.width ?? m), o / (s.height ?? g) ) : Math.min( a / ((e.width ?? m) + (i.width ?? m)), o / Math.max( e.height ?? g, i.height ?? g ) ), d = (O) => { const { element: $, iframe: B, width: F, height: q, blank: J } = O; Object.assign(B.style, { width: `${F}px`, height: `${q}px`, transform: `scale(${u})`, transformOrigin: "top left", display: J ? "none" : "block" }), Object.assign($.style, { width: `${(F ?? m) * u}px`, height: `${(q ?? g) * u}px`, overflow: "hidden", display: "block" }), l && O !== s && ($.style.display = "none"); }; n(this, b) ? d(n(this, b)) : (d(e), d(i)); }, M = new WeakSet(), N = async function({ left: t, right: e, center: i, side: s }) { n(this, k).replaceChildren(), p(this, w, null), p(this, y, null), p(this, b, null), i ? (p(this, b, await c(this, A, H).call(this, i)), p(this, v, "center"), c(this, E, C).call(this)) : (p(this, w, await c(this, A, H).call(this, t)), p(this, y, await c(this, A, H).call(this, e)), p(this, v, n(this, w).blank ? "right" : n(this, y).blank ? "left" : s), c(this, E, C).call(this)); }, R = new WeakSet(), P = function() { var t, e, i, s; if (!(n(this, b) || (t = n(this, w)) != null && t.blank) && n(this, L) && ((s = (i = (e = n(this, w)) == null ? void 0 : e.element) == null ? void 0 : i.style) == null ? void 0 : s.display) === "none") return n(this, y).element.style.display = "none", n(this, w).element.style.display = "block", p(this, v, "left"), !0; }, V = new WeakSet(), G = function() { var t, e, i, s; if (!(n(this, b) || (t = n(this, y)) != null && t.blank) && n(this, L) && ((s = (i = (e = n(this, y)) == null ? void 0 : e.element) == null ? void 0 : i.style) == null ? void 0 : s.display) === "none") return n(this, w).element.style.display = "none", n(this, y).element.style.display = "block", p(this, v, "right"), !0; }, T = new WeakSet(), z = function(t) { this.dispatchEvent(new CustomEvent("relocate", { detail: { reason: t, range: null, index: this.index, fraction: 0, size: 1 } })); }; customElements.define("foliate-fxl", X); export { X as FixedLayout };