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
JavaScript
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