Comparing version 2.2.0 to 3.0.0
"use strict"; | ||
var __importDefault = (this && this.__importDefault) || function (mod) { | ||
return (mod && mod.__esModule) ? mod : { "default": mod }; | ||
}; | ||
// Adapted from https://github.com/mathiasbynens/he/blob/36afe179392226cf1b6ccdb16ebbb7a5a844d93a/src/he.js#L106-L134 | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
var decode_json_1 = __importDefault(require("./maps/decode.json")); | ||
// Adapted from https://github.com/mathiasbynens/he/blob/master/src/he.js#L94-L119 | ||
var decodeMap = new Map([ | ||
[0, 65533], | ||
[128, 8364], | ||
[130, 8218], | ||
[131, 402], | ||
[132, 8222], | ||
[133, 8230], | ||
[134, 8224], | ||
[135, 8225], | ||
[136, 710], | ||
[137, 8240], | ||
[138, 352], | ||
[139, 8249], | ||
[140, 338], | ||
[142, 381], | ||
[145, 8216], | ||
[146, 8217], | ||
[147, 8220], | ||
[148, 8221], | ||
[149, 8226], | ||
[150, 8211], | ||
[151, 8212], | ||
[152, 732], | ||
[153, 8482], | ||
[154, 353], | ||
[155, 8250], | ||
[156, 339], | ||
[158, 382], | ||
[159, 376], | ||
]); | ||
var fromCodePoint = | ||
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition | ||
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition, node/no-unsupported-features/es-builtins | ||
String.fromCodePoint || | ||
@@ -22,10 +48,8 @@ function (codePoint) { | ||
function decodeCodePoint(codePoint) { | ||
var _a; | ||
if ((codePoint >= 0xd800 && codePoint <= 0xdfff) || codePoint > 0x10ffff) { | ||
return "\uFFFD"; | ||
} | ||
if (codePoint in decode_json_1.default) { | ||
codePoint = decode_json_1.default[codePoint]; | ||
} | ||
return fromCodePoint(codePoint); | ||
return fromCodePoint((_a = decodeMap.get(codePoint)) !== null && _a !== void 0 ? _a : codePoint); | ||
} | ||
exports.default = decodeCodePoint; |
@@ -1,5 +0,27 @@ | ||
export declare const decodeXML: (str: string) => string; | ||
export declare const decodeHTMLStrict: (str: string) => string; | ||
export declare type MapType = Record<string, string>; | ||
export declare const decodeHTML: (str: string) => string; | ||
import htmlDecodeTree from "./generated/decode-data-html"; | ||
import xmlDecodeTree from "./generated/decode-data-xml"; | ||
export { htmlDecodeTree, xmlDecodeTree }; | ||
export declare enum CharCodes { | ||
NUM, | ||
SEMI, | ||
ZERO, | ||
NINE, | ||
LOWER_A, | ||
UPPER_A, | ||
LOWER_F, | ||
UPPER_F, | ||
LOWER_X, | ||
UPPER_X | ||
} | ||
export declare enum BinTrieFlags { | ||
HAS_VALUE = 32768, | ||
BRANCH_LENGTH = 32512, | ||
MULTI_BYTE = 128, | ||
JUMP_TABLE = 127 | ||
} | ||
export declare const JUMP_OFFSET_BASE: number; | ||
export declare function determineBranch(decodeTree: Uint16Array, current: number, nodeIdx: number, char: number): number; | ||
export declare function decodeHTML(str: string): string; | ||
export declare function decodeHTMLStrict(str: string): string; | ||
export declare function decodeXML(str: string): string; | ||
//# sourceMappingURL=decode.d.ts.map |
@@ -6,49 +6,155 @@ "use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.decodeHTML = exports.decodeHTMLStrict = exports.decodeXML = void 0; | ||
var entities_json_1 = __importDefault(require("./maps/entities.json")); | ||
var legacy_json_1 = __importDefault(require("./maps/legacy.json")); | ||
var xml_json_1 = __importDefault(require("./maps/xml.json")); | ||
exports.decodeXML = exports.decodeHTMLStrict = exports.decodeHTML = exports.determineBranch = exports.JUMP_OFFSET_BASE = exports.BinTrieFlags = exports.CharCodes = exports.xmlDecodeTree = exports.htmlDecodeTree = void 0; | ||
var decode_data_html_1 = __importDefault(require("./generated/decode-data-html")); | ||
exports.htmlDecodeTree = decode_data_html_1.default; | ||
var decode_data_xml_1 = __importDefault(require("./generated/decode-data-xml")); | ||
exports.xmlDecodeTree = decode_data_xml_1.default; | ||
var decode_codepoint_1 = __importDefault(require("./decode_codepoint")); | ||
var strictEntityRe = /&(?:[a-zA-Z0-9]+|#[xX][\da-fA-F]+|#\d+);/g; | ||
exports.decodeXML = getStrictDecoder(xml_json_1.default); | ||
exports.decodeHTMLStrict = getStrictDecoder(entities_json_1.default); | ||
function getStrictDecoder(map) { | ||
var replace = getReplacer(map); | ||
return function (str) { return String(str).replace(strictEntityRe, replace); }; | ||
var CharCodes; | ||
(function (CharCodes) { | ||
CharCodes[CharCodes["NUM"] = "#".charCodeAt(0)] = "NUM"; | ||
CharCodes[CharCodes["SEMI"] = ";".charCodeAt(0)] = "SEMI"; | ||
CharCodes[CharCodes["ZERO"] = "0".charCodeAt(0)] = "ZERO"; | ||
CharCodes[CharCodes["NINE"] = "9".charCodeAt(0)] = "NINE"; | ||
CharCodes[CharCodes["LOWER_A"] = "a".charCodeAt(0)] = "LOWER_A"; | ||
CharCodes[CharCodes["UPPER_A"] = "A".charCodeAt(0)] = "UPPER_A"; | ||
CharCodes[CharCodes["LOWER_F"] = "f".charCodeAt(0)] = "LOWER_F"; | ||
CharCodes[CharCodes["UPPER_F"] = "F".charCodeAt(0)] = "UPPER_F"; | ||
CharCodes[CharCodes["LOWER_X"] = "x".charCodeAt(0)] = "LOWER_X"; | ||
CharCodes[CharCodes["UPPER_X"] = "X".charCodeAt(0)] = "UPPER_X"; | ||
})(CharCodes = exports.CharCodes || (exports.CharCodes = {})); | ||
var BinTrieFlags; | ||
(function (BinTrieFlags) { | ||
BinTrieFlags[BinTrieFlags["HAS_VALUE"] = 32768] = "HAS_VALUE"; | ||
BinTrieFlags[BinTrieFlags["BRANCH_LENGTH"] = 32512] = "BRANCH_LENGTH"; | ||
BinTrieFlags[BinTrieFlags["MULTI_BYTE"] = 128] = "MULTI_BYTE"; | ||
BinTrieFlags[BinTrieFlags["JUMP_TABLE"] = 127] = "JUMP_TABLE"; | ||
})(BinTrieFlags = exports.BinTrieFlags || (exports.BinTrieFlags = {})); | ||
exports.JUMP_OFFSET_BASE = CharCodes.ZERO - 1; | ||
function getDecoder(decodeTree) { | ||
return function decodeHTMLBinary(str, strict) { | ||
var ret = ""; | ||
var lastIdx = 0; | ||
var strIdx = 0; | ||
while ((strIdx = str.indexOf("&", strIdx)) >= 0) { | ||
ret += str.slice(lastIdx, strIdx); | ||
lastIdx = strIdx; | ||
// Skip the "&" | ||
strIdx += 1; | ||
// If we have a numeric entity, handle this separately. | ||
if (str.charCodeAt(strIdx) === CharCodes.NUM) { | ||
// Skip the leading "&#". For hex entities, also skip the leading "x". | ||
var start = strIdx + 1; | ||
var base = 10; | ||
var cp = str.charCodeAt(start); | ||
if (cp === CharCodes.LOWER_X || cp === CharCodes.UPPER_X) { | ||
base = 16; | ||
strIdx += 1; | ||
start += 1; | ||
} | ||
while (((cp = str.charCodeAt(++strIdx)) >= CharCodes.ZERO && | ||
cp <= CharCodes.NINE) || | ||
(base === 16 && | ||
((cp >= CharCodes.LOWER_A && cp <= CharCodes.LOWER_F) || | ||
(cp >= CharCodes.UPPER_A && | ||
cp <= CharCodes.UPPER_F)))) | ||
; | ||
if (start !== strIdx) { | ||
var entity = str.substring(start, strIdx); | ||
var parsed = parseInt(entity, base); | ||
if (str.charCodeAt(strIdx) === CharCodes.SEMI) { | ||
strIdx += 1; | ||
} | ||
else if (strict) { | ||
continue; | ||
} | ||
ret += decode_codepoint_1.default(parsed); | ||
lastIdx = strIdx; | ||
} | ||
continue; | ||
} | ||
var result = null; | ||
var excess = 1; | ||
var treeIdx = 0; | ||
var current = decodeTree[treeIdx]; | ||
for (; strIdx < str.length; strIdx++, excess++) { | ||
treeIdx = determineBranch(decodeTree, current, treeIdx + 1, str.charCodeAt(strIdx)); | ||
if (treeIdx < 0) | ||
break; | ||
current = decodeTree[treeIdx]; | ||
// If the branch is a value, store it and continue | ||
if (current & BinTrieFlags.HAS_VALUE) { | ||
// If we have a legacy entity while parsing strictly, just skip the number of bytes | ||
if (strict && str.charCodeAt(strIdx) !== CharCodes.SEMI) { | ||
// No need to consider multi-byte values, as the legacy entity is always a single byte | ||
treeIdx += 1; | ||
} | ||
else { | ||
// If this is a surrogate pair, combine the higher bits from the node with the next byte | ||
result = | ||
current & BinTrieFlags.MULTI_BYTE | ||
? String.fromCharCode(decodeTree[++treeIdx], decodeTree[++treeIdx]) | ||
: String.fromCharCode(decodeTree[++treeIdx]); | ||
excess = 0; | ||
} | ||
} | ||
} | ||
if (result != null) { | ||
ret += result; | ||
lastIdx = strIdx - excess + 1; | ||
} | ||
} | ||
return ret + str.slice(lastIdx); | ||
}; | ||
} | ||
var sorter = function (a, b) { return (a < b ? 1 : -1); }; | ||
exports.decodeHTML = (function () { | ||
var legacy = Object.keys(legacy_json_1.default).sort(sorter); | ||
var keys = Object.keys(entities_json_1.default).sort(sorter); | ||
for (var i = 0, j = 0; i < keys.length; i++) { | ||
if (legacy[j] === keys[i]) { | ||
keys[i] += ";?"; | ||
j++; | ||
function determineBranch(decodeTree, current, nodeIdx, char) { | ||
if (current <= 128) { | ||
return char === current ? nodeIdx : -1; | ||
} | ||
var branchCount = (current & BinTrieFlags.BRANCH_LENGTH) >> 8; | ||
if (branchCount === 0) { | ||
return -1; | ||
} | ||
if (branchCount === 1) { | ||
return char === decodeTree[nodeIdx] ? nodeIdx + 1 : -1; | ||
} | ||
var jumpOffset = current & BinTrieFlags.JUMP_TABLE; | ||
if (jumpOffset) { | ||
var value = char - exports.JUMP_OFFSET_BASE - jumpOffset; | ||
return value < 0 || value > branchCount | ||
? -1 | ||
: decodeTree[nodeIdx + value] - 1; | ||
} | ||
// Binary search for the character. | ||
var lo = nodeIdx; | ||
var hi = lo + branchCount - 1; | ||
while (lo <= hi) { | ||
var mid = (lo + hi) >>> 1; | ||
var midVal = decodeTree[mid]; | ||
if (midVal < char) { | ||
lo = mid + 1; | ||
} | ||
else if (midVal > char) { | ||
hi = mid - 1; | ||
} | ||
else { | ||
keys[i] += ";"; | ||
return decodeTree[mid + branchCount]; | ||
} | ||
} | ||
var re = new RegExp("&(?:" + keys.join("|") + "|#[xX][\\da-fA-F]+;?|#\\d+;?)", "g"); | ||
var replace = getReplacer(entities_json_1.default); | ||
function replacer(str) { | ||
if (str.substr(-1) !== ";") | ||
str += ";"; | ||
return replace(str); | ||
} | ||
// TODO consider creating a merged map | ||
return function (str) { return String(str).replace(re, replacer); }; | ||
})(); | ||
function getReplacer(map) { | ||
return function replace(str) { | ||
if (str.charAt(1) === "#") { | ||
var secondChar = str.charAt(2); | ||
if (secondChar === "X" || secondChar === "x") { | ||
return decode_codepoint_1.default(parseInt(str.substr(3), 16)); | ||
} | ||
return decode_codepoint_1.default(parseInt(str.substr(2), 10)); | ||
} | ||
// eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing | ||
return map[str.slice(1, -1)] || str; | ||
}; | ||
return -1; | ||
} | ||
exports.determineBranch = determineBranch; | ||
var htmlDecoder = getDecoder(decode_data_html_1.default); | ||
var xmlDecoder = getDecoder(decode_data_xml_1.default); | ||
function decodeHTML(str) { | ||
return htmlDecoder(str, false); | ||
} | ||
exports.decodeHTML = decodeHTML; | ||
function decodeHTMLStrict(str) { | ||
return htmlDecoder(str, true); | ||
} | ||
exports.decodeHTMLStrict = decodeHTMLStrict; | ||
function decodeXML(str) { | ||
return xmlDecoder(str, true); | ||
} | ||
exports.decodeXML = decodeXML; |
@@ -8,3 +8,3 @@ /** | ||
*/ | ||
export declare const encodeXML: (data: string) => string; | ||
export declare function encodeXML(str: string): string; | ||
/** | ||
@@ -20,3 +20,3 @@ * Encodes all entities and non-ASCII characters in the input. | ||
*/ | ||
export declare const encodeHTML: (data: string) => string; | ||
export declare function encodeHTML(data: string): string; | ||
/** | ||
@@ -29,3 +29,3 @@ * Encodes all non-ASCII characters, as well as characters not valid in HTML | ||
*/ | ||
export declare const encodeNonAsciiHTML: (data: string) => string; | ||
export declare function encodeNonAsciiHTML(data: string): string; | ||
/** | ||
@@ -40,6 +40,5 @@ * Encodes all non-ASCII characters, as well as characters not valid in XML | ||
*/ | ||
export declare function escape(data: string): string; | ||
export declare const escape: typeof encodeXML; | ||
/** | ||
* Encodes all characters not valid in XML documents using numeric hexadecimal | ||
* reference (eg. `ü`). | ||
* Encodes all characters not valid in XML documents using XML entities. | ||
* | ||
@@ -46,0 +45,0 @@ * Note that the output will be character-set dependent. |
@@ -8,4 +8,11 @@ "use strict"; | ||
var xml_json_1 = __importDefault(require("./maps/xml.json")); | ||
var inverseXML = getInverseObj(xml_json_1.default); | ||
var xmlReplacer = getInverseReplacer(inverseXML); | ||
var encode_trie_1 = require("./encode-trie"); | ||
var entities_json_1 = __importDefault(require("./maps/entities.json")); | ||
var htmlReplacer = getCharRegExp(entities_json_1.default, true); | ||
var xmlReplacer = getCharRegExp(xml_json_1.default, true); | ||
var xmlInvalidChars = getCharRegExp(xml_json_1.default, false); | ||
var xmlCodeMap = new Map(Object.keys(xml_json_1.default).map(function (k) { return [ | ||
xml_json_1.default[k].charCodeAt(0), | ||
"&" + k + ";", | ||
]; })); | ||
/** | ||
@@ -18,6 +25,23 @@ * Encodes all non-ASCII characters, as well as characters not valid in XML | ||
*/ | ||
exports.encodeXML = getASCIIEncoder(inverseXML); | ||
var entities_json_1 = __importDefault(require("./maps/entities.json")); | ||
var inverseHTML = getInverseObj(entities_json_1.default); | ||
var htmlReplacer = getInverseReplacer(inverseHTML); | ||
function encodeXML(str) { | ||
var ret = ""; | ||
var lastIdx = 0; | ||
var match; | ||
while ((match = xmlReplacer.exec(str)) !== null) { | ||
var i = match.index; | ||
var char = str.charCodeAt(i); | ||
var next = xmlCodeMap.get(char); | ||
if (next) { | ||
ret += str.substring(lastIdx, i) + next; | ||
lastIdx = i + 1; | ||
} | ||
else { | ||
ret += str.substring(lastIdx, i) + "&#x" + encode_trie_1.getCodePoint(str, i).toString(16) + ";"; | ||
// Increase by 1 if we have a surrogate pair | ||
lastIdx = xmlReplacer.lastIndex += Number((char & 0xd800) === 0xd800); | ||
} | ||
} | ||
return ret + str.substr(lastIdx); | ||
} | ||
exports.encodeXML = encodeXML; | ||
/** | ||
@@ -33,3 +57,6 @@ * Encodes all entities and non-ASCII characters in the input. | ||
*/ | ||
exports.encodeHTML = getInverse(inverseHTML, htmlReplacer); | ||
function encodeHTML(data) { | ||
return encode_trie_1.encodeHTMLTrieRe(htmlReplacer, data); | ||
} | ||
exports.encodeHTML = encodeHTML; | ||
/** | ||
@@ -42,32 +69,20 @@ * Encodes all non-ASCII characters, as well as characters not valid in HTML | ||
*/ | ||
exports.encodeNonAsciiHTML = getASCIIEncoder(inverseHTML); | ||
function getInverseObj(obj) { | ||
return Object.keys(obj) | ||
.sort() | ||
.reduce(function (inverse, name) { | ||
inverse[obj[name]] = "&" + name + ";"; | ||
return inverse; | ||
}, {}); | ||
function encodeNonAsciiHTML(data) { | ||
return encode_trie_1.encodeHTMLTrieRe(xmlReplacer, data); | ||
} | ||
function getInverseReplacer(inverse) { | ||
var single = []; | ||
var multiple = []; | ||
for (var _i = 0, _a = Object.keys(inverse); _i < _a.length; _i++) { | ||
var k = _a[_i]; | ||
if (k.length === 1) { | ||
// Add value to single array | ||
single.push("\\" + k); | ||
} | ||
else { | ||
// Add value to multiple array | ||
multiple.push(k); | ||
} | ||
} | ||
exports.encodeNonAsciiHTML = encodeNonAsciiHTML; | ||
function getCharRegExp(map, nonAscii) { | ||
// Collect the start characters of all entities | ||
var chars = Object.keys(map) | ||
.map(function (k) { return "\\" + map[k].charAt(0); }) | ||
.filter(function (v) { return !nonAscii || v.charCodeAt(1) < 128; }) | ||
.sort(function (a, b) { return a.charCodeAt(1) - b.charCodeAt(1); }) | ||
// Remove duplicates | ||
.filter(function (v, i, a) { return v !== a[i + 1]; }); | ||
// Add ranges to single characters. | ||
single.sort(); | ||
for (var start = 0; start < single.length - 1; start++) { | ||
for (var start = 0; start < chars.length - 1; start++) { | ||
// Find the end of a run of characters | ||
var end = start; | ||
while (end < single.length - 1 && | ||
single[end].charCodeAt(1) + 1 === single[end + 1].charCodeAt(1)) { | ||
while (end < chars.length - 1 && | ||
chars[end].charCodeAt(1) + 1 === chars[end + 1].charCodeAt(1)) { | ||
end += 1; | ||
@@ -79,34 +94,6 @@ } | ||
continue; | ||
single.splice(start, count, single[start] + "-" + single[end]); | ||
chars.splice(start, count, chars[start] + "-" + chars[end]); | ||
} | ||
multiple.unshift("[" + single.join("") + "]"); | ||
return new RegExp(multiple.join("|"), "g"); | ||
return new RegExp("[" + chars.join("") + (nonAscii ? "\\x80-\\uFFFF" : "") + "]", "g"); | ||
} | ||
// /[^\0-\x7F]/gu | ||
var reNonASCII = /(?:[\x80-\uD7FF\uE000-\uFFFF]|[\uD800-\uDBFF][\uDC00-\uDFFF]|[\uD800-\uDBFF](?![\uDC00-\uDFFF])|(?:[^\uD800-\uDBFF]|^)[\uDC00-\uDFFF])/g; | ||
var getCodePoint = | ||
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition | ||
String.prototype.codePointAt != null | ||
? // eslint-disable-next-line @typescript-eslint/no-non-null-assertion | ||
function (str) { return str.codePointAt(0); } | ||
: // http://mathiasbynens.be/notes/javascript-encoding#surrogate-formulae | ||
function (c) { | ||
return (c.charCodeAt(0) - 0xd800) * 0x400 + | ||
c.charCodeAt(1) - | ||
0xdc00 + | ||
0x10000; | ||
}; | ||
function singleCharReplacer(c) { | ||
return "&#x" + (c.length > 1 ? getCodePoint(c) : c.charCodeAt(0)) | ||
.toString(16) | ||
.toUpperCase() + ";"; | ||
} | ||
function getInverse(inverse, re) { | ||
return function (data) { | ||
return data | ||
.replace(re, function (name) { return inverse[name]; }) | ||
.replace(reNonASCII, singleCharReplacer); | ||
}; | ||
} | ||
var reEscapeChars = new RegExp(xmlReplacer.source + "|" + reNonASCII.source, "g"); | ||
/** | ||
@@ -121,9 +108,5 @@ * Encodes all non-ASCII characters, as well as characters not valid in XML | ||
*/ | ||
function escape(data) { | ||
return data.replace(reEscapeChars, singleCharReplacer); | ||
} | ||
exports.escape = escape; | ||
exports.escape = encodeXML; | ||
/** | ||
* Encodes all characters not valid in XML documents using numeric hexadecimal | ||
* reference (eg. `ü`). | ||
* Encodes all characters not valid in XML documents using XML entities. | ||
* | ||
@@ -135,9 +118,16 @@ * Note that the output will be character-set dependent. | ||
function escapeUTF8(data) { | ||
return data.replace(xmlReplacer, singleCharReplacer); | ||
var match; | ||
var lastIdx = 0; | ||
var result = ""; | ||
while ((match = xmlInvalidChars.exec(data))) { | ||
if (lastIdx !== match.index) { | ||
result += data.substring(lastIdx, match.index); | ||
} | ||
// We know that this chararcter will be in `inverseXML` | ||
result += xmlCodeMap.get(match[0].charCodeAt(0)); | ||
// Every match will be of length 1 | ||
lastIdx = match.index + 1; | ||
} | ||
return result + data.substring(lastIdx); | ||
} | ||
exports.escapeUTF8 = escapeUTF8; | ||
function getASCIIEncoder(obj) { | ||
return function (data) { | ||
return data.replace(reEscapeChars, function (c) { return obj[c] || singleCharReplacer(c); }); | ||
}; | ||
} |
@@ -0,1 +1,52 @@ | ||
/** The level of entities to support. */ | ||
export declare enum EntityLevel { | ||
/** Support only XML entities. */ | ||
XML = 0, | ||
/** Support HTML entities, which are a superset of XML entities. */ | ||
HTML = 1 | ||
} | ||
/** Determines whether some entities are allowed to be written without a trailing `;`. */ | ||
export declare enum DecodingMode { | ||
/** Support legacy HTML entities. */ | ||
Legacy = 0, | ||
/** Do not support legacy HTML entities. */ | ||
Strict = 1 | ||
} | ||
export declare enum EncodingMode { | ||
/** | ||
* The output is UTF-8 encoded. Only characters that need escaping within | ||
* HTML will be escaped. | ||
*/ | ||
UTF8 = 0, | ||
/** | ||
* The output consists only of ASCII characters. Characters that need | ||
* escaping within HTML, and characters that aren't ASCII characters will | ||
* be escaped. | ||
*/ | ||
ASCII = 1, | ||
/** | ||
* Encode all characters that have an equivalent entity, as well as all | ||
* characters that are not ASCII characters. | ||
*/ | ||
Extensive = 2 | ||
} | ||
interface DecodingOptions { | ||
/** | ||
* The level of entities to support. | ||
* @default EntityLevel.XML | ||
*/ | ||
level?: EntityLevel; | ||
/** | ||
* Decoding mode. If `Legacy`, will support legacy entities not terminated | ||
* with a semicolon (`;`). | ||
* | ||
* Always `Strict` for XML. For HTML, set this to `true` if you are parsing | ||
* an attribute value. | ||
* | ||
* The deprecated `decodeStrict` function defaults this to `Strict`. | ||
* | ||
* @default DecodingMode.Legacy | ||
*/ | ||
mode?: DecodingMode; | ||
} | ||
/** | ||
@@ -5,6 +56,5 @@ * Decodes a string with entities. | ||
* @param data String to decode. | ||
* @param level Optional level to decode at. 0 = XML, 1 = HTML. Default is 0. | ||
* @deprecated Use `decodeXML` or `decodeHTML` directly. | ||
* @param options Decoding options. | ||
*/ | ||
export declare function decode(data: string, level?: number): string; | ||
export declare function decode(data: string, options?: DecodingOptions | EntityLevel): string; | ||
/** | ||
@@ -14,16 +64,30 @@ * Decodes a string with entities. Does not allow missing trailing semicolons for entities. | ||
* @param data String to decode. | ||
* @param level Optional level to decode at. 0 = XML, 1 = HTML. Default is 0. | ||
* @deprecated Use `decodeHTMLStrict` or `decodeXML` directly. | ||
* @param options Decoding options. | ||
* @deprecated Use `decode` with the `mode` set to `Strict`. | ||
*/ | ||
export declare function decodeStrict(data: string, level?: number): string; | ||
export declare function decodeStrict(data: string, options?: DecodingOptions | EntityLevel): string; | ||
/** | ||
* Options for `encode`. | ||
*/ | ||
export interface EncodingOptions { | ||
/** | ||
* The level of entities to support. | ||
* @default EntityLevel.XML | ||
*/ | ||
level?: EntityLevel; | ||
/** | ||
* Output format. | ||
* @default EncodingMode.Extensive | ||
*/ | ||
mode?: EncodingMode; | ||
} | ||
/** | ||
* Encodes a string with entities. | ||
* | ||
* @param data String to encode. | ||
* @param level Optional level to encode at. 0 = XML, 1 = HTML. Default is 0. | ||
* @deprecated Use `encodeHTML`, `encodeXML` or `encodeNonAsciiHTML` directly. | ||
* @param options Encoding options. | ||
*/ | ||
export declare function encode(data: string, level?: number): string; | ||
export declare function encode(data: string, options?: EncodingOptions | EntityLevel): string; | ||
export { encodeXML, encodeHTML, encodeNonAsciiHTML, escape, escapeUTF8, encodeHTML as encodeHTML4, encodeHTML as encodeHTML5, } from "./encode"; | ||
export { decodeXML, decodeHTML, decodeHTMLStrict, decodeHTML as decodeHTML4, decodeHTML as decodeHTML5, decodeHTMLStrict as decodeHTML4Strict, decodeHTMLStrict as decodeHTML5Strict, decodeXML as decodeXMLStrict, } from "./decode"; | ||
//# sourceMappingURL=index.d.ts.map |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.decodeXMLStrict = exports.decodeHTML5Strict = exports.decodeHTML4Strict = exports.decodeHTML5 = exports.decodeHTML4 = exports.decodeHTMLStrict = exports.decodeHTML = exports.decodeXML = exports.encodeHTML5 = exports.encodeHTML4 = exports.escapeUTF8 = exports.escape = exports.encodeNonAsciiHTML = exports.encodeHTML = exports.encodeXML = exports.encode = exports.decodeStrict = exports.decode = void 0; | ||
exports.decodeXMLStrict = exports.decodeHTML5Strict = exports.decodeHTML4Strict = exports.decodeHTML5 = exports.decodeHTML4 = exports.decodeHTMLStrict = exports.decodeHTML = exports.decodeXML = exports.encodeHTML5 = exports.encodeHTML4 = exports.escapeUTF8 = exports.escape = exports.encodeNonAsciiHTML = exports.encodeHTML = exports.encodeXML = exports.encode = exports.decodeStrict = exports.decode = exports.EncodingMode = exports.DecodingMode = exports.EntityLevel = void 0; | ||
var decode_1 = require("./decode"); | ||
var encode_1 = require("./encode"); | ||
/** The level of entities to support. */ | ||
var EntityLevel; | ||
(function (EntityLevel) { | ||
/** Support only XML entities. */ | ||
EntityLevel[EntityLevel["XML"] = 0] = "XML"; | ||
/** Support HTML entities, which are a superset of XML entities. */ | ||
EntityLevel[EntityLevel["HTML"] = 1] = "HTML"; | ||
})(EntityLevel = exports.EntityLevel || (exports.EntityLevel = {})); | ||
/** Determines whether some entities are allowed to be written without a trailing `;`. */ | ||
var DecodingMode; | ||
(function (DecodingMode) { | ||
/** Support legacy HTML entities. */ | ||
DecodingMode[DecodingMode["Legacy"] = 0] = "Legacy"; | ||
/** Do not support legacy HTML entities. */ | ||
DecodingMode[DecodingMode["Strict"] = 1] = "Strict"; | ||
})(DecodingMode = exports.DecodingMode || (exports.DecodingMode = {})); | ||
var EncodingMode; | ||
(function (EncodingMode) { | ||
/** | ||
* The output is UTF-8 encoded. Only characters that need escaping within | ||
* HTML will be escaped. | ||
*/ | ||
EncodingMode[EncodingMode["UTF8"] = 0] = "UTF8"; | ||
/** | ||
* The output consists only of ASCII characters. Characters that need | ||
* escaping within HTML, and characters that aren't ASCII characters will | ||
* be escaped. | ||
*/ | ||
EncodingMode[EncodingMode["ASCII"] = 1] = "ASCII"; | ||
/** | ||
* Encode all characters that have an equivalent entity, as well as all | ||
* characters that are not ASCII characters. | ||
*/ | ||
EncodingMode[EncodingMode["Extensive"] = 2] = "Extensive"; | ||
})(EncodingMode = exports.EncodingMode || (exports.EncodingMode = {})); | ||
/** | ||
@@ -10,7 +45,14 @@ * Decodes a string with entities. | ||
* @param data String to decode. | ||
* @param level Optional level to decode at. 0 = XML, 1 = HTML. Default is 0. | ||
* @deprecated Use `decodeXML` or `decodeHTML` directly. | ||
* @param options Decoding options. | ||
*/ | ||
function decode(data, level) { | ||
return (!level || level <= 0 ? decode_1.decodeXML : decode_1.decodeHTML)(data); | ||
function decode(data, options) { | ||
if (options === void 0) { options = EntityLevel.XML; } | ||
var opts = typeof options === "number" ? { level: options } : options; | ||
if (opts.level === EntityLevel.HTML) { | ||
if (opts.mode === DecodingMode.Strict) { | ||
return decode_1.decodeHTMLStrict(data); | ||
} | ||
return decode_1.decodeHTML(data); | ||
} | ||
return decode_1.decodeXML(data); | ||
} | ||
@@ -22,7 +64,15 @@ exports.decode = decode; | ||
* @param data String to decode. | ||
* @param level Optional level to decode at. 0 = XML, 1 = HTML. Default is 0. | ||
* @deprecated Use `decodeHTMLStrict` or `decodeXML` directly. | ||
* @param options Decoding options. | ||
* @deprecated Use `decode` with the `mode` set to `Strict`. | ||
*/ | ||
function decodeStrict(data, level) { | ||
return (!level || level <= 0 ? decode_1.decodeXML : decode_1.decodeHTMLStrict)(data); | ||
function decodeStrict(data, options) { | ||
if (options === void 0) { options = EntityLevel.XML; } | ||
var opts = typeof options === "number" ? { level: options } : options; | ||
if (opts.level === EntityLevel.HTML) { | ||
if (opts.mode === DecodingMode.Legacy) { | ||
return decode_1.decodeHTML(data); | ||
} | ||
return decode_1.decodeHTMLStrict(data); | ||
} | ||
return decode_1.decodeXML(data); | ||
} | ||
@@ -34,7 +84,18 @@ exports.decodeStrict = decodeStrict; | ||
* @param data String to encode. | ||
* @param level Optional level to encode at. 0 = XML, 1 = HTML. Default is 0. | ||
* @deprecated Use `encodeHTML`, `encodeXML` or `encodeNonAsciiHTML` directly. | ||
* @param options Encoding options. | ||
*/ | ||
function encode(data, level) { | ||
return (!level || level <= 0 ? encode_1.encodeXML : encode_1.encodeHTML)(data); | ||
function encode(data, options) { | ||
if (options === void 0) { options = EntityLevel.XML; } | ||
var opts = typeof options === "number" ? { level: options } : options; | ||
// Mode `UTF8` just escapes XML entities | ||
if (opts.mode === EncodingMode.UTF8) | ||
return encode_1.escapeUTF8(data); | ||
if (opts.level === EntityLevel.HTML) { | ||
if (opts.mode === EncodingMode.ASCII) { | ||
return encode_1.encodeNonAsciiHTML(data); | ||
} | ||
return encode_1.encodeHTML(data); | ||
} | ||
// ASCII and Extensive are equivalent | ||
return encode_1.encodeXML(data); | ||
} | ||
@@ -41,0 +102,0 @@ exports.encode = encode; |
{ | ||
"name": "entities", | ||
"version": "2.2.0", | ||
"version": "3.0.0", | ||
"description": "Encode & decode XML and HTML entities with ease", | ||
@@ -24,19 +24,21 @@ "author": "Felix Boehm <me@feedic.com>", | ||
], | ||
"engines": { | ||
"node": ">=0.12" | ||
}, | ||
"devDependencies": { | ||
"@types/jest": "^26.0.0", | ||
"@types/node": "^14.11.8", | ||
"@typescript-eslint/eslint-plugin": "^4.4.1", | ||
"@typescript-eslint/parser": "^4.4.1", | ||
"coveralls": "*", | ||
"eslint": "^7.11.0", | ||
"eslint-config-prettier": "^7.0.0", | ||
"@types/jest": "^26.0.24", | ||
"@types/node": "^16.4.13", | ||
"@typescript-eslint/eslint-plugin": "^4.29.0", | ||
"@typescript-eslint/parser": "^4.29.0", | ||
"eslint": "^7.32.0", | ||
"eslint-config-prettier": "^8.1.0", | ||
"eslint-plugin-node": "^11.1.0", | ||
"jest": "^26.5.3", | ||
"jest": "^27.0.3", | ||
"prettier": "^2.0.5", | ||
"ts-jest": "^26.1.0", | ||
"ts-jest": "^27.0.4", | ||
"typescript": "^4.0.2" | ||
}, | ||
"scripts": { | ||
"test": "jest --coverage && npm run lint", | ||
"coverage": "cat coverage/lcov.info | coveralls", | ||
"test": "npm run test:jest && npm run lint", | ||
"test:jest": "jest", | ||
"lint": "npm run lint:es && npm run lint:prettier", | ||
@@ -59,3 +61,4 @@ "lint:es": "eslint .", | ||
"preset": "ts-jest", | ||
"testEnvironment": "node" | ||
"testEnvironment": "node", | ||
"coverageProvider": "v8" | ||
}, | ||
@@ -62,0 +65,0 @@ "prettier": { |
@@ -31,11 +31,28 @@ # entities [![NPM version](http://img.shields.io/npm/v/entities.svg)](https://npmjs.org/package/entities) [![Downloads](https://img.shields.io/npm/dm/entities.svg)](https://npmjs.org/package/entities) [![Build Status](http://img.shields.io/travis/fb55/entities.svg)](http://travis-ci.org/fb55/entities) [![Coverage](http://img.shields.io/coveralls/fb55/entities.svg)](https://coveralls.io/r/fb55/entities) | ||
| Library | `decode` performance | `encode` performance | Bundle size | | ||
| -------------- | -------------------- | -------------------- | -------------------------------------------------------------------------- | | ||
| entities | 10.809s | 17.683s | ![npm bundle size](https://img.shields.io/bundlephobia/min/entities) | | ||
| html-entities | 14.029s | 22.670s | ![npm bundle size](https://img.shields.io/bundlephobia/min/html-entities) | | ||
| he | 16.163s | 44.010s | ![npm bundle size](https://img.shields.io/bundlephobia/min/he) | | ||
| parse-entities | 28.507s | N/A | ![npm bundle size](https://img.shields.io/bundlephobia/min/parse-entities) | | ||
| Library | `decode` perf | `encode` perf | `escape` perf | Bundle size | | ||
| -------------- | ------------- | ------------- | ------------- | -------------------------------------------------------------------------- | | ||
| entities | 1.418s | 6.786s | 2.196s | ![npm bundle size](https://img.shields.io/bundlephobia/min/entities) | | ||
| html-entities | 2.530s | 6.829s | 2.415s | ![npm bundle size](https://img.shields.io/bundlephobia/min/html-entities) | | ||
| he | 5.800s | 24.237s | 3.624s | ![npm bundle size](https://img.shields.io/bundlephobia/min/he) | | ||
| parse-entities | 9.660s | N/A | N/A | ![npm bundle size](https://img.shields.io/bundlephobia/min/parse-entities) | | ||
--- | ||
## Acknowledgements | ||
This libary wouldn't be possible without the work of these individuals. Thanks | ||
to | ||
- [@mathiasbynens](https://github.com/mathiasbynens) for his explanations | ||
about character encodings, and his library `he`, which was one of the | ||
inspirations for `entities` | ||
- [@inikulin](https://github.com/inikulin) for his work on optimized tries for | ||
decoding HTML entities for the `parse5` project | ||
- [@mdevils](https://github.com/mdevils) for taking on the challenge of | ||
producing a quick entity library with his `html-entities` library. | ||
`entities` would be quite a bit slower if there wasn't any competition. | ||
Right now `entities` is on top, but we'll see how long that lasts! | ||
--- | ||
License: BSD-2-Clause | ||
@@ -42,0 +59,0 @@ |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
172163
11
27
1166
75
1