vue-files-preview-inno
Version:
A tool for previewing files such as doc, excel, pdf, image, markdown, txt, audio, and video and so on.
355 lines (352 loc) • 13.7 kB
JavaScript
import { extend as g, type as x, findChildren as y, isNumber as N, RangeObject as b } from "./utils/core.mjs";
const u = 1, f = 3, T = 9;
class v {
constructor(e, t, s) {
var n;
if (this.str = "", this.base = {}, this.spinePos = 0, this.range = !1, this.path = {}, this.start = null, this.end = null, !(this instanceof v))
return new v(e, t, s);
if (typeof t == "string" ? this.base = this.parseComponent(t) : typeof t == "object" && t.steps && (this.base = t), n = this.checkType(e), n === "string")
return this.str = e, g(this, this.parse(e));
if (n === "range")
return g(this, this.fromRange(e, this.base, s));
if (n === "node")
return g(this, this.fromNode(e, this.base, s));
if (n === "EpubCFI" && e.path)
return e;
if (e)
throw new TypeError("not a valid argument for EpubCFI");
return this;
}
/**
* Check the type of constructor input
* @private
*/
checkType(e) {
return this.isCfiString(e) ? "string" : e && typeof e == "object" && (x(e) === "Range" || typeof e.startContainer < "u") ? "range" : e && typeof e == "object" && typeof e.nodeType < "u" ? "node" : e && typeof e == "object" && e instanceof v ? "EpubCFI" : !1;
}
/**
* Parse a cfi string to a CFI object representation
* @param {string} cfiStr
* @returns {object} cfi
*/
parse(e) {
var t = {
spinePos: -1,
range: !1,
base: {},
path: {},
start: null,
end: null
}, s, n, r;
return typeof e != "string" ? { spinePos: -1 } : (e.indexOf("epubcfi(") === 0 && e[e.length - 1] === ")" && (e = e.slice(8, e.length - 1)), s = this.getChapterComponent(e), s ? (t.base = this.parseComponent(s), n = this.getPathComponent(e), t.path = this.parseComponent(n), r = this.getRange(e), r && (t.range = !0, t.start = this.parseComponent(r[0]), t.end = this.parseComponent(r[1])), t.spinePos = t.base.steps[1].index, t) : { spinePos: -1 });
}
parseComponent(e) {
var t = {
steps: [],
terminal: {
offset: null,
assertion: null
}
}, s = e.split(":"), n = s[0].split("/"), r;
return s.length > 1 && (r = s[1], t.terminal = this.parseTerminal(r)), n[0] === "" && n.shift(), t.steps = n.map((function(i) {
return this.parseStep(i);
}).bind(this)), t;
}
parseStep(e) {
var t, s, n, r, i;
if (r = e.match(/\[(.*)\]/), r && r[1] && (i = r[1]), s = parseInt(e), !isNaN(s))
return s % 2 === 0 ? (t = "element", n = s / 2 - 1) : (t = "text", n = (s - 1) / 2), {
type: t,
index: n,
id: i || null
};
}
parseTerminal(e) {
var t, s, n = e.match(/\[(.*)\]/);
return n && n[1] ? (t = parseInt(e.split("[")[0]), s = n[1]) : t = parseInt(e), N(t) || (t = null), {
offset: t,
assertion: s
};
}
getChapterComponent(e) {
var t = e.split("!");
return t[0];
}
getPathComponent(e) {
var t = e.split("!");
if (t[1])
return t[1].split(",")[0];
}
getRange(e) {
var t = e.split(",");
return t.length === 3 ? [
t[1],
t[2]
] : !1;
}
getCharecterOffsetComponent(e) {
var t = e.split(":");
return t[1] || "";
}
joinSteps(e) {
return e ? e.map(function(t) {
var s = "";
return t.type === "element" && (s += (t.index + 1) * 2), t.type === "text" && (s += 1 + 2 * t.index), t.id && (s += "[" + t.id + "]"), s;
}).join("/") : "";
}
segmentString(e) {
var t = "/";
return t += this.joinSteps(e.steps), e.terminal && e.terminal.offset != null && (t += ":" + e.terminal.offset), e.terminal && e.terminal.assertion != null && (t += "[" + e.terminal.assertion + "]"), t;
}
/**
* Convert CFI to a epubcfi(...) string
* @returns {string} epubcfi
*/
toString() {
var e = "epubcfi(";
return e += this.segmentString(this.base), e += "!", e += this.segmentString(this.path), this.range && this.start && (e += ",", e += this.segmentString(this.start)), this.range && this.end && (e += ",", e += this.segmentString(this.end)), e += ")", e;
}
/**
* Compare which of two CFIs is earlier in the text
* @returns {number} First is earlier = -1, Second is earlier = 1, They are equal = 0
*/
compare(e, t) {
var s, n, r, i;
if (typeof e == "string" && (e = new v(e)), typeof t == "string" && (t = new v(t)), e.spinePos > t.spinePos)
return 1;
if (e.spinePos < t.spinePos)
return -1;
e.range ? (s = e.path.steps.concat(e.start.steps), r = e.start.terminal) : (s = e.path.steps, r = e.path.terminal), t.range ? (n = t.path.steps.concat(t.start.steps), i = t.start.terminal) : (n = t.path.steps, i = t.path.terminal);
for (var a = 0; a < s.length; a++) {
if (!s[a])
return -1;
if (!n[a] || s[a].index > n[a].index)
return 1;
if (s[a].index < n[a].index)
return -1;
}
return s.length < n.length ? -1 : r.offset > i.offset ? 1 : r.offset < i.offset ? -1 : 0;
}
step(e) {
var t = e.nodeType === f ? "text" : "element";
return {
id: e.id,
tagName: e.tagName,
type: t,
index: this.position(e)
};
}
filteredStep(e, t) {
var s = this.filter(e, t), n;
if (s)
return n = s.nodeType === f ? "text" : "element", {
id: s.id,
tagName: s.tagName,
type: n,
index: this.filteredPosition(s, t)
};
}
pathTo(e, t, s) {
for (var n = {
steps: [],
terminal: {
offset: null,
assertion: null
}
}, r = e, i; r && r.parentNode && r.parentNode.nodeType != T; )
s ? i = this.filteredStep(r, s) : i = this.step(r), i && n.steps.unshift(i), r = r.parentNode;
return t != null && t >= 0 && (n.terminal.offset = t, n.steps[n.steps.length - 1].type != "text" && n.steps.push({
type: "text",
index: 0
})), n;
}
equalStep(e, t) {
return !e || !t ? !1 : e.index === t.index && e.id === t.id && e.type === t.type;
}
/**
* Create a CFI object from a Range
* @param {Range} range
* @param {string | object} base
* @param {string} [ignoreClass]
* @returns {object} cfi
*/
fromRange(e, t, s) {
var n = {
range: !1,
base: {},
path: {},
start: null,
end: null
}, r = e.startContainer, i = e.endContainer, a = e.startOffset, p = e.endOffset, l = !1;
if (s && (l = r.ownerDocument.querySelector("." + s) != null), typeof t == "string" ? (n.base = this.parseComponent(t), n.spinePos = n.base.steps[1].index) : typeof t == "object" && (n.base = t), e.collapsed)
l && (a = this.patchOffset(r, a, s)), n.path = this.pathTo(r, a, s);
else {
n.range = !0, l && (a = this.patchOffset(r, a, s)), n.start = this.pathTo(r, a, s), l && (p = this.patchOffset(i, p, s)), n.end = this.pathTo(i, p, s), n.path = {
steps: [],
terminal: null
};
var d = n.start.steps.length, o;
for (o = 0; o < d && this.equalStep(n.start.steps[o], n.end.steps[o]); o++)
o === d - 1 ? n.start.terminal === n.end.terminal && (n.path.steps.push(n.start.steps[o]), n.range = !1) : n.path.steps.push(n.start.steps[o]);
n.start.steps = n.start.steps.slice(n.path.steps.length), n.end.steps = n.end.steps.slice(n.path.steps.length);
}
return n;
}
/**
* Create a CFI object from a Node
* @param {Node} anchor
* @param {string | object} base
* @param {string} [ignoreClass]
* @returns {object} cfi
*/
fromNode(e, t, s) {
var n = {
range: !1,
base: {},
path: {},
start: null,
end: null
};
return typeof t == "string" ? (n.base = this.parseComponent(t), n.spinePos = n.base.steps[1].index) : typeof t == "object" && (n.base = t), n.path = this.pathTo(e, null, s), n;
}
filter(e, t) {
var s, n, r, i, a, p = !1;
return e.nodeType === f ? (p = !0, r = e.parentNode, s = e.parentNode.classList.contains(t)) : (p = !1, s = e.classList.contains(t)), s && p ? (i = r.previousSibling, a = r.nextSibling, i && i.nodeType === f ? n = i : a && a.nodeType === f && (n = a), n || e) : s && !p ? !1 : e;
}
patchOffset(e, t, s) {
if (e.nodeType != f)
throw new Error("Anchor must be a text node");
var n = e, r = t;
for (e.parentNode.classList.contains(s) && (n = e.parentNode); n.previousSibling; ) {
if (n.previousSibling.nodeType === u)
if (n.previousSibling.classList.contains(s))
r += n.previousSibling.textContent.length;
else
break;
else
r += n.previousSibling.textContent.length;
n = n.previousSibling;
}
return r;
}
normalizedMap(e, t, s) {
var n = {}, r = -1, i, a = e.length, p, l;
for (i = 0; i < a; i++)
p = e[i].nodeType, p === u && e[i].classList.contains(s) && (p = f), i > 0 && p === f && l === f ? n[i] = r : t === p && (r = r + 1, n[i] = r), l = p;
return n;
}
position(e) {
var t, s;
return e.nodeType === u ? (t = e.parentNode.children, t || (t = y(e.parentNode)), s = Array.prototype.indexOf.call(t, e)) : (t = this.textNodes(e.parentNode), s = t.indexOf(e)), s;
}
filteredPosition(e, t) {
var s, n, r;
return e.nodeType === u ? (s = e.parentNode.children, r = this.normalizedMap(s, u, t)) : (s = e.parentNode.childNodes, e.parentNode.classList.contains(t) && (e = e.parentNode, s = e.parentNode.childNodes), r = this.normalizedMap(s, f, t)), n = Array.prototype.indexOf.call(s, e), r[n];
}
stepsToXpath(e) {
var t = [".", "*"];
return e.forEach(function(s) {
var n = s.index + 1;
s.id ? t.push("*[position()=" + n + " and @id='" + s.id + "']") : s.type === "text" ? t.push("text()[" + n + "]") : t.push("*[" + n + "]");
}), t.join("/");
}
/*
To get the last step if needed:
// Get the terminal step
lastStep = steps[steps.length-1];
// Get the query string
query = this.stepsToQuery(steps);
// Find the containing element
startContainerParent = doc.querySelector(query);
// Find the text node within that element
if(startContainerParent && lastStep.type == "text") {
container = startContainerParent.childNodes[lastStep.index];
}
*/
stepsToQuerySelector(e) {
var t = ["html"];
return e.forEach(function(s) {
var n = s.index + 1;
s.id ? t.push("#" + s.id) : s.type === "text" || t.push("*:nth-child(" + n + ")");
}), t.join(">");
}
textNodes(e, t) {
return Array.prototype.slice.call(e.childNodes).filter(function(s) {
return s.nodeType === f ? !0 : !!(t && s.classList.contains(t));
});
}
walkToNode(e, t, s) {
var n = t || document, r = n.documentElement, i, a, p = e.length, l;
for (l = 0; l < p && (a = e[l], a.type === "element" ? a.id ? r = n.getElementById(a.id) : (i = r.children || y(r), r = i[a.index]) : a.type === "text" && (r = this.textNodes(r, s)[a.index]), !!r); l++)
;
return r;
}
findNode(e, t, s) {
var n = t || document, r, i;
return !s && typeof n.evaluate < "u" ? (i = this.stepsToXpath(e), r = n.evaluate(i, n, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue) : s ? r = this.walkToNode(e, n, s) : r = this.walkToNode(e, n), r;
}
fixMiss(e, t, s, n) {
var r = this.findNode(e.slice(0, -1), s, n), i = r.childNodes, a = this.normalizedMap(i, f, n), p, l, d = e[e.length - 1].index;
for (let o in a) {
if (!a.hasOwnProperty(o)) return;
if (a[o] === d)
if (p = i[o], l = p.textContent.length, t > l)
t = t - l;
else {
p.nodeType === u ? r = p.childNodes[0] : r = p;
break;
}
}
return {
container: r,
offset: t
};
}
/**
* Creates a DOM range representing a CFI
* @param {document} _doc document referenced in the base
* @param {string} [ignoreClass]
* @return {Range}
*/
toRange(e, t) {
var s = e || document, n, r, i, a, p, l = this, d, o, m = t ? s.querySelector("." + t) != null : !1, h;
if (typeof s.createRange < "u" ? n = s.createRange() : n = new b(), l.range ? (r = l.start, d = l.path.steps.concat(r.steps), a = this.findNode(d, s, m ? t : null), i = l.end, o = l.path.steps.concat(i.steps), p = this.findNode(o, s, m ? t : null)) : (r = l.path, d = l.path.steps, a = this.findNode(l.path.steps, s, m ? t : null)), a)
try {
r.terminal.offset != null ? n.setStart(a, r.terminal.offset) : n.setStart(a, 0);
} catch {
h = this.fixMiss(d, r.terminal.offset, s, m ? t : null), n.setStart(h.container, h.offset);
}
else
return console.log("No startContainer found for", this.toString()), null;
if (p)
try {
i.terminal.offset != null ? n.setEnd(p, i.terminal.offset) : n.setEnd(p, 0);
} catch {
h = this.fixMiss(o, l.end.terminal.offset, s, m ? t : null), n.setEnd(h.container, h.offset);
}
return n;
}
/**
* Check if a string is wrapped with "epubcfi()"
* @param {string} str
* @returns {boolean}
*/
isCfiString(e) {
return typeof e == "string" && e.indexOf("epubcfi(") === 0 && e[e.length - 1] === ")";
}
generateChapterComponent(e, t, s) {
var n = parseInt(t), r = (e + 1) * 2, i = "/" + r + "/";
return i += (n + 1) * 2, s && (i += "[" + s + "]"), i;
}
/**
* Collapse a CFI Range to a single CFI Position
* @param {boolean} [toStart=false]
*/
collapse(e) {
this.range && (this.range = !1, e ? (this.path.steps = this.path.steps.concat(this.start.steps), this.path.terminal = this.start.terminal) : (this.path.steps = this.path.steps.concat(this.end.steps), this.path.terminal = this.end.terminal));
}
}
export {
v as default
};
//# sourceMappingURL=epubcfi.mjs.map