vue-files-preview-inno
Version:
A tool for previewing files such as doc, excel, pdf, image, markdown, txt, audio, and video and so on.
279 lines (278 loc) • 10.5 kB
JavaScript
import L from "./generated/decode-data-html.mjs";
import R from "./generated/decode-data-xml.mjs";
import { fromCodePoint as _, replaceCodePoint as A } from "./decode_codepoint.mjs";
var c;
(function(t) {
t[t.NUM = 35] = "NUM", t[t.SEMI = 59] = "SEMI", t[t.EQUALS = 61] = "EQUALS", t[t.ZERO = 48] = "ZERO", t[t.NINE = 57] = "NINE", t[t.LOWER_A = 97] = "LOWER_A", t[t.LOWER_F = 102] = "LOWER_F", t[t.LOWER_X = 120] = "LOWER_X", t[t.LOWER_Z = 122] = "LOWER_Z", t[t.UPPER_A = 65] = "UPPER_A", t[t.UPPER_F = 70] = "UPPER_F", t[t.UPPER_Z = 90] = "UPPER_Z";
})(c || (c = {}));
const x = 32;
var N;
(function(t) {
t[t.VALUE_LENGTH = 49152] = "VALUE_LENGTH", t[t.BRANCH_LENGTH = 16256] = "BRANCH_LENGTH", t[t.JUMP_TABLE = 127] = "JUMP_TABLE";
})(N || (N = {}));
function d(t) {
return t >= c.ZERO && t <= c.NINE;
}
function P(t) {
return t >= c.UPPER_A && t <= c.UPPER_F || t >= c.LOWER_A && t <= c.LOWER_F;
}
function I(t) {
return t >= c.UPPER_A && t <= c.UPPER_Z || t >= c.LOWER_A && t <= c.LOWER_Z || d(t);
}
function U(t) {
return t === c.EQUALS || I(t);
}
var s;
(function(t) {
t[t.EntityStart = 0] = "EntityStart", t[t.NumericStart = 1] = "NumericStart", t[t.NumericDecimal = 2] = "NumericDecimal", t[t.NumericHex = 3] = "NumericHex", t[t.NamedEntity = 4] = "NamedEntity";
})(s || (s = {}));
var E;
(function(t) {
t[t.Legacy = 0] = "Legacy", t[t.Strict = 1] = "Strict", t[t.Attribute = 2] = "Attribute";
})(E || (E = {}));
class y {
constructor(e, i, r) {
this.decodeTree = e, this.emitCodePoint = i, this.errors = r, this.state = s.EntityStart, this.consumed = 1, this.result = 0, this.treeIndex = 0, this.excess = 1, this.decodeMode = E.Strict;
}
/** Resets the instance to make it reusable. */
startEntity(e) {
this.decodeMode = e, this.state = s.EntityStart, this.result = 0, this.treeIndex = 0, this.excess = 1, this.consumed = 1;
}
/**
* Write an entity to the decoder. This can be called multiple times with partial entities.
* If the entity is incomplete, the decoder will return -1.
*
* Mirrors the implementation of `getDecoder`, but with the ability to stop decoding if the
* entity is incomplete, and resume when the next string is written.
*
* @param string The string containing the entity (or a continuation of the entity).
* @param offset The offset at which the entity begins. Should be 0 if this is not the first call.
* @returns The number of characters that were consumed, or -1 if the entity is incomplete.
*/
write(e, i) {
switch (this.state) {
case s.EntityStart:
return e.charCodeAt(i) === c.NUM ? (this.state = s.NumericStart, this.consumed += 1, this.stateNumericStart(e, i + 1)) : (this.state = s.NamedEntity, this.stateNamedEntity(e, i));
case s.NumericStart:
return this.stateNumericStart(e, i);
case s.NumericDecimal:
return this.stateNumericDecimal(e, i);
case s.NumericHex:
return this.stateNumericHex(e, i);
case s.NamedEntity:
return this.stateNamedEntity(e, i);
}
}
/**
* Switches between the numeric decimal and hexadecimal states.
*
* Equivalent to the `Numeric character reference state` in the HTML spec.
*
* @param str The string containing the entity (or a continuation of the entity).
* @param offset The current offset.
* @returns The number of characters that were consumed, or -1 if the entity is incomplete.
*/
stateNumericStart(e, i) {
return i >= e.length ? -1 : (e.charCodeAt(i) | x) === c.LOWER_X ? (this.state = s.NumericHex, this.consumed += 1, this.stateNumericHex(e, i + 1)) : (this.state = s.NumericDecimal, this.stateNumericDecimal(e, i));
}
addToNumericResult(e, i, r, n) {
if (i !== r) {
const u = r - i;
this.result = this.result * Math.pow(n, u) + parseInt(e.substr(i, u), n), this.consumed += u;
}
}
/**
* Parses a hexadecimal numeric entity.
*
* Equivalent to the `Hexademical character reference state` in the HTML spec.
*
* @param str The string containing the entity (or a continuation of the entity).
* @param offset The current offset.
* @returns The number of characters that were consumed, or -1 if the entity is incomplete.
*/
stateNumericHex(e, i) {
const r = i;
for (; i < e.length; ) {
const n = e.charCodeAt(i);
if (d(n) || P(n))
i += 1;
else
return this.addToNumericResult(e, r, i, 16), this.emitNumericEntity(n, 3);
}
return this.addToNumericResult(e, r, i, 16), -1;
}
/**
* Parses a decimal numeric entity.
*
* Equivalent to the `Decimal character reference state` in the HTML spec.
*
* @param str The string containing the entity (or a continuation of the entity).
* @param offset The current offset.
* @returns The number of characters that were consumed, or -1 if the entity is incomplete.
*/
stateNumericDecimal(e, i) {
const r = i;
for (; i < e.length; ) {
const n = e.charCodeAt(i);
if (d(n))
i += 1;
else
return this.addToNumericResult(e, r, i, 10), this.emitNumericEntity(n, 2);
}
return this.addToNumericResult(e, r, i, 10), -1;
}
/**
* Validate and emit a numeric entity.
*
* Implements the logic from the `Hexademical character reference start
* state` and `Numeric character reference end state` in the HTML spec.
*
* @param lastCp The last code point of the entity. Used to see if the
* entity was terminated with a semicolon.
* @param expectedLength The minimum number of characters that should be
* consumed. Used to validate that at least one digit
* was consumed.
* @returns The number of characters that were consumed.
*/
emitNumericEntity(e, i) {
var r;
if (this.consumed <= i)
return (r = this.errors) === null || r === void 0 || r.absenceOfDigitsInNumericCharacterReference(this.consumed), 0;
if (e === c.SEMI)
this.consumed += 1;
else if (this.decodeMode === E.Strict)
return 0;
return this.emitCodePoint(A(this.result), this.consumed), this.errors && (e !== c.SEMI && this.errors.missingSemicolonAfterCharacterReference(), this.errors.validateNumericCharacterReference(this.result)), this.consumed;
}
/**
* Parses a named entity.
*
* Equivalent to the `Named character reference state` in the HTML spec.
*
* @param str The string containing the entity (or a continuation of the entity).
* @param offset The current offset.
* @returns The number of characters that were consumed, or -1 if the entity is incomplete.
*/
stateNamedEntity(e, i) {
const { decodeTree: r } = this;
let n = r[this.treeIndex], u = (n & N.VALUE_LENGTH) >> 14;
for (; i < e.length; i++, this.excess++) {
const m = e.charCodeAt(i);
if (this.treeIndex = T(r, n, this.treeIndex + Math.max(1, u), m), this.treeIndex < 0)
return this.result === 0 || // If we are parsing an attribute
this.decodeMode === E.Attribute && // We shouldn't have consumed any characters after the entity,
(u === 0 || // And there should be no invalid characters.
U(m)) ? 0 : this.emitNotTerminatedNamedEntity();
if (n = r[this.treeIndex], u = (n & N.VALUE_LENGTH) >> 14, u !== 0) {
if (m === c.SEMI)
return this.emitNamedEntityData(this.treeIndex, u, this.consumed + this.excess);
this.decodeMode !== E.Strict && (this.result = this.treeIndex, this.consumed += this.excess, this.excess = 0);
}
}
return -1;
}
/**
* Emit a named entity that was not terminated with a semicolon.
*
* @returns The number of characters consumed.
*/
emitNotTerminatedNamedEntity() {
var e;
const { result: i, decodeTree: r } = this, n = (r[i] & N.VALUE_LENGTH) >> 14;
return this.emitNamedEntityData(i, n, this.consumed), (e = this.errors) === null || e === void 0 || e.missingSemicolonAfterCharacterReference(), this.consumed;
}
/**
* Emit a named entity.
*
* @param result The index of the entity in the decode tree.
* @param valueLength The number of bytes in the entity.
* @param consumed The number of characters consumed.
*
* @returns The number of characters consumed.
*/
emitNamedEntityData(e, i, r) {
const { decodeTree: n } = this;
return this.emitCodePoint(i === 1 ? n[e] & ~N.VALUE_LENGTH : n[e + 1], r), i === 3 && this.emitCodePoint(n[e + 2], r), r;
}
/**
* Signal to the parser that the end of the input was reached.
*
* Remaining data will be emitted and relevant errors will be produced.
*
* @returns The number of characters consumed.
*/
end() {
var e;
switch (this.state) {
case s.NamedEntity:
return this.result !== 0 && (this.decodeMode !== E.Attribute || this.result === this.treeIndex) ? this.emitNotTerminatedNamedEntity() : 0;
case s.NumericDecimal:
return this.emitNumericEntity(0, 2);
case s.NumericHex:
return this.emitNumericEntity(0, 3);
case s.NumericStart:
return (e = this.errors) === null || e === void 0 || e.absenceOfDigitsInNumericCharacterReference(this.consumed), 0;
case s.EntityStart:
return 0;
}
}
}
function o(t) {
let e = "";
const i = new y(t, (r) => e += _(r));
return function(n, u) {
let m = 0, h = 0;
for (; (h = n.indexOf("&", h)) >= 0; ) {
e += n.slice(m, h), i.startEntity(u);
const l = i.write(
n,
// Skip the "&"
h + 1
);
if (l < 0) {
m = h + i.end();
break;
}
m = h + l, h = l === 0 ? m + 1 : m;
}
const a = e + n.slice(m);
return e = "", a;
};
}
function T(t, e, i, r) {
const n = (e & N.BRANCH_LENGTH) >> 7, u = e & N.JUMP_TABLE;
if (n === 0)
return u !== 0 && r === u ? i : -1;
if (u) {
const a = r - u;
return a < 0 || a >= n ? -1 : t[i + a] - 1;
}
let m = i, h = m + n - 1;
for (; m <= h; ) {
const a = m + h >>> 1, l = t[a];
if (l < r)
m = a + 1;
else if (l > r)
h = a - 1;
else
return t[a + n];
}
return -1;
}
const H = o(L);
o(R);
function M(t, e = E.Legacy) {
return H(t, e);
}
export {
N as BinTrieFlags,
E as DecodingMode,
y as EntityDecoder,
M as decodeHTML,
T as determineBranch,
_ as fromCodePoint,
L as htmlDecodeTree,
A as replaceCodePoint,
R as xmlDecodeTree
};
//# sourceMappingURL=decode.mjs.map