UNPKG

vue-files-preview-inno

Version:

A tool for previewing files such as doc, excel, pdf, image, markdown, txt, audio, and video and so on.

254 lines (253 loc) 14.6 kB
import g from "../../../../event-emitter/index.mjs"; import { extend as y, uuid as v, bounds as f, borders as u, isNumber as m, defer as c, createBlobUrl as w, revokeBlobUrl as E } from "../../utils/core.mjs"; import b from "../../epubcfi.mjs"; import x from "../../contents.mjs"; import { EVENTS as a } from "../../utils/constants.mjs"; import { Pane as p, Highlight as k, Underline as L } from "../../../../marks-pane/lib/marks.mjs"; class W { constructor(e, t) { this.settings = y({ ignoreClass: "", axis: void 0, //options.layout && options.layout.props.flow === "scrolled" ? "vertical" : "horizontal", direction: void 0, width: 0, height: 0, layout: void 0, globalLayoutProperties: {}, method: void 0, forceRight: !1, allowScriptedContent: !1, allowPopups: !1 }, t || {}), this.id = "epubjs-view-" + v(), this.section = e, this.index = e.index, this.element = this.container(this.settings.axis), this.added = !1, this.displayed = !1, this.rendered = !1, this.fixedWidth = 0, this.fixedHeight = 0, this.epubcfi = new b(), this.layout = this.settings.layout, this.pane = void 0, this.highlights = {}, this.underlines = {}, this.marks = {}; } container(e) { var t = document.createElement("div"); return t.classList.add("epub-view"), t.style.height = "0px", t.style.width = "0px", t.style.overflow = "hidden", t.style.position = "relative", t.style.display = "block", e && e == "horizontal" ? t.style.flex = "none" : t.style.flex = "initial", t; } create() { return this.iframe ? this.iframe : (this.element || (this.element = this.createContainer()), this.iframe = document.createElement("iframe"), this.iframe.id = this.id, this.iframe.scrolling = "no", this.iframe.style.overflow = "hidden", this.iframe.seamless = "seamless", this.iframe.style.border = "none", this.iframe.sandbox = "allow-same-origin", this.settings.allowScriptedContent && (this.iframe.sandbox += " allow-scripts"), this.settings.allowPopups && (this.iframe.sandbox += " allow-popups"), this.iframe.setAttribute("enable-annotation", "true"), this.resizing = !0, this.element.style.visibility = "hidden", this.iframe.style.visibility = "hidden", this.iframe.style.width = "0", this.iframe.style.height = "0", this._width = 0, this._height = 0, this.element.setAttribute("ref", this.index), this.added = !0, this.elementBounds = f(this.element), "srcdoc" in this.iframe ? this.supportsSrcdoc = !0 : this.supportsSrcdoc = !1, this.settings.method || (this.settings.method = this.supportsSrcdoc ? "srcdoc" : "write"), this.iframe); } render(e, t) { return this.create(), this.size(), this.sectionRender || (this.sectionRender = this.section.render(e)), this.sectionRender.then((function(i) { return this.load(i); }).bind(this)).then((function() { let i = this.contents.writingMode(), s; return this.settings.flow === "scrolled" ? s = i.indexOf("vertical") === 0 ? "horizontal" : "vertical" : s = i.indexOf("vertical") === 0 ? "vertical" : "horizontal", i.indexOf("vertical") === 0 && this.settings.flow === "paginated" && (this.layout.delta = this.layout.height), this.setAxis(s), this.emit(a.VIEWS.AXIS, s), this.setWritingMode(i), this.emit(a.VIEWS.WRITING_MODE, i), this.layout.format(this.contents, this.section, this.axis), this.addListeners(), new Promise((n, o) => { this.expand(), this.settings.forceRight && (this.element.style.marginLeft = this.width() + "px"), n(); }); }).bind(this), (function(i) { return this.emit(a.VIEWS.LOAD_ERROR, i), new Promise((s, n) => { n(i); }); }).bind(this)).then((function() { this.emit(a.VIEWS.RENDERED, this.section); }).bind(this)); } reset() { this.iframe && (this.iframe.style.width = "0", this.iframe.style.height = "0", this._width = 0, this._height = 0, this._textWidth = void 0, this._contentWidth = void 0, this._textHeight = void 0, this._contentHeight = void 0), this._needsReframe = !0; } // Determine locks base on settings size(e, t) { var i = e || this.settings.width, s = t || this.settings.height; this.layout.name === "pre-paginated" ? this.lock("both", i, s) : this.settings.axis === "horizontal" ? this.lock("height", i, s) : this.lock("width", i, s), this.settings.width = i, this.settings.height = s; } // Lock an axis to element dimensions, taking borders into account lock(e, t, i) { var s = u(this.element), n; this.iframe ? n = u(this.iframe) : n = { width: 0, height: 0 }, e == "width" && m(t) && (this.lockedWidth = t - s.width - n.width), e == "height" && m(i) && (this.lockedHeight = i - s.height - n.height), e === "both" && m(t) && m(i) && (this.lockedWidth = t - s.width - n.width, this.lockedHeight = i - s.height - n.height), this.displayed && this.iframe && this.expand(); } // Resize a single axis based on content dimensions expand(e) { var t = this.lockedWidth, i = this.lockedHeight, s; !this.iframe || this._expanding || (this._expanding = !0, this.layout.name === "pre-paginated" ? (t = this.layout.columnWidth, i = this.layout.height) : this.settings.axis === "horizontal" ? (t = this.contents.textWidth(), t % this.layout.pageWidth > 0 && (t = Math.ceil(t / this.layout.pageWidth) * this.layout.pageWidth), this.settings.forceEvenPages && (s = t / this.layout.pageWidth, this.layout.divisor > 1 && this.layout.name === "reflowable" && s % 2 > 0 && (t += this.layout.pageWidth))) : this.settings.axis === "vertical" && (i = this.contents.textHeight(), this.settings.flow === "paginated" && i % this.layout.height > 0 && (i = Math.ceil(i / this.layout.height) * this.layout.height)), (this._needsReframe || t != this._width || i != this._height) && this.reframe(t, i), this._expanding = !1); } reframe(e, t) { var i; m(e) && (this.element.style.width = e + "px", this.iframe.style.width = e + "px", this._width = e), m(t) && (this.element.style.height = t + "px", this.iframe.style.height = t + "px", this._height = t); let s = this.prevBounds ? e - this.prevBounds.width : e, n = this.prevBounds ? t - this.prevBounds.height : t; i = { width: e, height: t, widthDelta: s, heightDelta: n }, this.pane && this.pane.render(), requestAnimationFrame(() => { let o; for (let l in this.marks) this.marks.hasOwnProperty(l) && (o = this.marks[l], this.placeMark(o.element, o.range)); }), this.onResize(this, i), this.emit(a.VIEWS.RESIZED, i), this.prevBounds = i, this.elementBounds = f(this.element); } load(e) { var t = new c(), i = t.promise; if (!this.iframe) return t.reject(new Error("No Iframe Available")), i; if (this.iframe.onload = (function(n) { this.onLoad(n, t); }).bind(this), this.settings.method === "blobUrl") this.blobUrl = w(e, "application/xhtml+xml"), this.iframe.src = this.blobUrl, this.element.appendChild(this.iframe); else if (this.settings.method === "srcdoc") this.iframe.srcdoc = e, this.element.appendChild(this.iframe); else { if (this.element.appendChild(this.iframe), this.document = this.iframe.contentDocument, !this.document) return t.reject(new Error("No Document Available")), i; if (this.iframe.contentDocument.open(), window.MSApp && MSApp.execUnsafeLocalFunction) { var s = this; MSApp.execUnsafeLocalFunction(function() { s.iframe.contentDocument.write(e); }); } else this.iframe.contentDocument.write(e); this.iframe.contentDocument.close(); } return i; } onLoad(e, t) { this.window = this.iframe.contentWindow, this.document = this.iframe.contentDocument, this.contents = new x(this.document, this.document.body, this.section.cfiBase, this.section.index), this.rendering = !1; var i = this.document.querySelector("link[rel='canonical']"); i ? i.setAttribute("href", this.section.canonical) : (i = this.document.createElement("link"), i.setAttribute("rel", "canonical"), i.setAttribute("href", this.section.canonical), this.document.querySelector("head").appendChild(i)), this.contents.on(a.CONTENTS.EXPAND, () => { this.displayed && this.iframe && (this.expand(), this.contents && this.layout.format(this.contents)); }), this.contents.on(a.CONTENTS.RESIZE, (s) => { this.displayed && this.iframe && (this.expand(), this.contents && this.layout.format(this.contents)); }), t.resolve(this.contents); } setLayout(e) { this.layout = e, this.contents && (this.layout.format(this.contents), this.expand()); } setAxis(e) { this.settings.axis = e, e == "horizontal" ? this.element.style.flex = "none" : this.element.style.flex = "initial", this.size(); } setWritingMode(e) { this.writingMode = e; } addListeners() { } removeListeners(e) { } display(e) { var t = new c(); return this.displayed ? t.resolve(this) : this.render(e).then((function() { this.emit(a.VIEWS.DISPLAYED, this), this.onDisplayed(this), this.displayed = !0, t.resolve(this); }).bind(this), function(i) { t.reject(i, this); }), t.promise; } show() { this.element.style.visibility = "visible", this.iframe && (this.iframe.style.visibility = "visible", this.iframe.style.transform = "translateZ(0)", this.iframe.offsetWidth, this.iframe.style.transform = null), this.emit(a.VIEWS.SHOWN, this); } hide() { this.element.style.visibility = "hidden", this.iframe.style.visibility = "hidden", this.stopExpanding = !0, this.emit(a.VIEWS.HIDDEN, this); } offset() { return { top: this.element.offsetTop, left: this.element.offsetLeft }; } width() { return this._width; } height() { return this._height; } position() { return this.element.getBoundingClientRect(); } locationOf(e) { this.iframe.getBoundingClientRect(); var t = this.contents.locationOf(e, this.settings.ignoreClass); return { left: t.left, top: t.top }; } onDisplayed(e) { } onResize(e, t) { } bounds(e) { return (e || !this.elementBounds) && (this.elementBounds = f(this.element)), this.elementBounds; } highlight(e, t = {}, i, s = "epubjs-hl", n = {}) { if (!this.contents) return; const o = Object.assign({ fill: "yellow", "fill-opacity": "0.3", "mix-blend-mode": "multiply" }, n); let l = this.contents.range(e), h = () => { this.emit(a.VIEWS.MARK_CLICKED, e, t); }; t.epubcfi = e, this.pane || (this.pane = new p(this.iframe, this.element)); let d = new k(l, s, t, o), r = this.pane.addMark(d); return this.highlights[e] = { mark: r, element: r.element, listeners: [h, i] }, r.element.setAttribute("ref", s), r.element.addEventListener("click", h), r.element.addEventListener("touchstart", h), i && (r.element.addEventListener("click", i), r.element.addEventListener("touchstart", i)), r; } underline(e, t = {}, i, s = "epubjs-ul", n = {}) { if (!this.contents) return; const o = Object.assign({ stroke: "black", "stroke-opacity": "0.3", "mix-blend-mode": "multiply" }, n); let l = this.contents.range(e), h = () => { this.emit(a.VIEWS.MARK_CLICKED, e, t); }; t.epubcfi = e, this.pane || (this.pane = new p(this.iframe, this.element)); let d = new L(l, s, t, o), r = this.pane.addMark(d); return this.underlines[e] = { mark: r, element: r.element, listeners: [h, i] }, r.element.setAttribute("ref", s), r.element.addEventListener("click", h), r.element.addEventListener("touchstart", h), i && (r.element.addEventListener("click", i), r.element.addEventListener("touchstart", i)), r; } mark(e, t = {}, i) { if (!this.contents) return; if (e in this.marks) return this.marks[e]; let s = this.contents.range(e); if (!s) return; let n = s.commonAncestorContainer, o = n.nodeType === 1 ? n : n.parentNode, l = (d) => { this.emit(a.VIEWS.MARK_CLICKED, e, t); }; s.collapsed && n.nodeType === 1 ? (s = new Range(), s.selectNodeContents(n)) : s.collapsed && (s = new Range(), s.selectNodeContents(o)); let h = this.document.createElement("a"); return h.setAttribute("ref", "epubjs-mk"), h.style.position = "absolute", h.dataset.epubcfi = e, t && Object.keys(t).forEach((d) => { h.dataset[d] = t[d]; }), i && (h.addEventListener("click", i), h.addEventListener("touchstart", i)), h.addEventListener("click", l), h.addEventListener("touchstart", l), this.placeMark(h, s), this.element.appendChild(h), this.marks[e] = { element: h, range: s, listeners: [l, i] }, o; } placeMark(e, t) { let i, s, n; if (this.layout.name === "pre-paginated" || this.settings.axis !== "horizontal") { let l = t.getBoundingClientRect(); i = l.top, s = l.right; } else { let l = t.getClientRects(), h; for (var o = 0; o != l.length; o++) h = l[o], (!n || h.left < n) && (n = h.left, s = Math.ceil(n / this.layout.props.pageWidth) * this.layout.props.pageWidth - this.layout.gap / 2, i = h.top); } e.style.top = `${i}px`, e.style.left = `${s}px`; } unhighlight(e) { let t; e in this.highlights && (t = this.highlights[e], this.pane.removeMark(t.mark), t.listeners.forEach((i) => { i && (t.element.removeEventListener("click", i), t.element.removeEventListener("touchstart", i)); }), delete this.highlights[e]); } ununderline(e) { let t; e in this.underlines && (t = this.underlines[e], this.pane.removeMark(t.mark), t.listeners.forEach((i) => { i && (t.element.removeEventListener("click", i), t.element.removeEventListener("touchstart", i)); }), delete this.underlines[e]); } unmark(e) { let t; e in this.marks && (t = this.marks[e], this.element.removeChild(t.element), t.listeners.forEach((i) => { i && (t.element.removeEventListener("click", i), t.element.removeEventListener("touchstart", i)); }), delete this.marks[e]); } destroy() { for (let e in this.highlights) this.unhighlight(e); for (let e in this.underlines) this.ununderline(e); for (let e in this.marks) this.unmark(e); this.blobUrl && E(this.blobUrl), this.displayed && (this.displayed = !1, this.removeListeners(), this.contents.destroy(), this.stopExpanding = !0, this.element.removeChild(this.iframe), this.pane && (this.pane.element.remove(), this.pane = void 0), this.iframe = void 0, this.contents = void 0, this._textWidth = null, this._textHeight = null, this._width = null, this._height = null); } } g(W.prototype); export { W as default }; //# sourceMappingURL=iframe.mjs.map