clean up code

This commit is contained in:
Tony Brix 2019-11-07 12:46:32 -06:00
parent 6901937dfc
commit b01aa4f5b4

View File

@ -4,19 +4,20 @@
function escape(html, encode) { function escape(html, encode) {
if (encode) { if (encode) {
if (escape.escapeTest.test(html)) { if (escape.escapeTest.test(html)) {
return html.replace(escape.escapeReplace, function(ch) { return escape.replacements[ch]; }); return html.replace(escape.escapeReplace, escape.getReplacement);
} }
} else { } else {
if (escape.escapeTestNoEncode.test(html)) { if (escape.escapeTestNoEncode.test(html)) {
return html.replace(escape.escapeReplaceNoEncode, function(ch) { return escape.replacements[ch]; }); return html.replace(escape.escapeReplaceNoEncode, escape.getReplacement);
} }
} }
return html; return html;
} }
escape.escapeTest = /[&<>"']/; escape.escapeTest = /[&<>"']/;
escape.escapeReplace = /[&<>"']/g; escape.escapeReplace = /[&<>"']/g;
escape.escapeTestNoEncode = /[<>"']|&(?!#?\w+;)/;
escape.escapeReplaceNoEncode = /[<>"']|&(?!#?\w+;)/g;
escape.replacements = { escape.replacements = {
'&': '&amp;', '&': '&amp;',
'<': '&lt;', '<': '&lt;',
@ -24,13 +25,11 @@ escape.replacements = {
'"': '&quot;', '"': '&quot;',
"'": '&#39;' "'": '&#39;'
}; };
escape.getReplacement = (ch) => escape.replacements[ch];
escape.escapeTestNoEncode = /[<>"']|&(?!#?\w+;)/;
escape.escapeReplaceNoEncode = /[<>"']|&(?!#?\w+;)/g;
function unescape(html) { function unescape(html) {
// explicitly match decimal, hex, and named HTML entities // explicitly match decimal, hex, and named HTML entities
return html.replace(/&(#(?:\d+)|(?:#x[0-9A-Fa-f]+)|(?:\w+));?/ig, function(_, n) { return html.replace(unescape.unescapeTest, (_, n) => {
n = n.toLowerCase(); n = n.toLowerCase();
if (n === 'colon') return ':'; if (n === 'colon') return ':';
if (n.charAt(0) === '#') { if (n.charAt(0) === '#') {
@ -41,29 +40,32 @@ function unescape(html) {
return ''; return '';
}); });
} }
unescape.unescapeTest = /&(#(?:\d+)|(?:#x[0-9A-Fa-f]+)|(?:\w+));?/ig;
function edit(regex, opt) { function edit(regex, opt) {
regex = regex.source || regex; regex = regex.source || regex;
opt = opt || ''; opt = opt || '';
return { const obj = {
replace: function(name, val) { replace: (name, val) => {
val = val.source || val; val = val.source || val;
val = val.replace(/(^|[^\[])\^/g, '$1'); val = val.replace(edit.caret, '$1');
regex = regex.replace(name, val); regex = regex.replace(name, val);
return this; return obj;
}, },
getRegex: function() { getRegex: () => {
return new RegExp(regex, opt); return new RegExp(regex, opt);
} }
}; };
return obj;
} }
edit.caret = /(^|[^\[])\^/g;
function cleanUrl(sanitize, base, href) { function cleanUrl(sanitize, base, href) {
if (sanitize) { if (sanitize) {
let prot; let prot;
try { try {
prot = decodeURIComponent(unescape(href)) prot = decodeURIComponent(unescape(href))
.replace(/[^\w:]/g, '') .replace(cleanUrl.protocol, '')
.toLowerCase(); .toLowerCase();
} catch (e) { } catch (e) {
return null; return null;
@ -72,7 +74,7 @@ function cleanUrl(sanitize, base, href) {
return null; return null;
} }
} }
if (base && !originIndependentUrl.test(href)) { if (base && !cleanUrl.originIndependentUrl.test(href)) {
href = resolveUrl(base, href); href = resolveUrl(base, href);
} }
try { try {
@ -82,37 +84,41 @@ function cleanUrl(sanitize, base, href) {
} }
return href; return href;
} }
cleanUrl.protocol = /[^\w:]/g;
cleanUrl.originIndependentUrl = /^$|^[a-z][a-z0-9+.-]*:|^[?#]/i;
function resolveUrl(base, href) { function resolveUrl(base, href) {
if (!baseUrls[' ' + base]) { if (!resolveUrl.baseUrls[' ' + base]) {
// we can ignore everything in base after the last slash of its path component, // we can ignore everything in base after the last slash of its path component,
// but we might need to add _that_ // but we might need to add _that_
// https://tools.ietf.org/html/rfc3986#section-3 // https://tools.ietf.org/html/rfc3986#section-3
if (/^[^:]+:\/*[^/]*$/.test(base)) { if (resolveUrl.justDomain.test(base)) {
baseUrls[' ' + base] = base + '/'; resolveUrl.baseUrls[' ' + base] = base + '/';
} else { } else {
baseUrls[' ' + base] = rtrim(base, '/', true); resolveUrl.baseUrls[' ' + base] = rtrim(base, '/', true);
} }
} }
base = baseUrls[' ' + base]; base = resolveUrl.baseUrls[' ' + base];
const relativeBase = base.indexOf(':') === -1; const relativeBase = base.indexOf(':') === -1;
if (href.slice(0, 2) === '//') { if (href.substring(0, 2) === '//') {
if (relativeBase) { if (relativeBase) {
return href; return href;
} }
return base.replace(/^([^:]+:)[\s\S]*$/, '$1') + href; return base.replace(resolveUrl.protocol, '$1') + href;
} else if (href.charAt(0) === '/') { } else if (href.charAt(0) === '/') {
if (relativeBase) { if (relativeBase) {
return href; return href;
} }
return base.replace(/^([^:]+:\/*[^/]*)[\s\S]*$/, '$1') + href; return base.replace(resolveUrl.domain, '$1') + href;
} else { } else {
return base + href; return base + href;
} }
} }
const baseUrls = {}; resolveUrl.baseUrls = {};
const originIndependentUrl = /^$|^[a-z][a-z0-9+.-]*:|^[?#]/i; resolveUrl.justDomain = /^[^:]+:\/*[^/]*$/;
resolveUrl.protocol = /^([^:]+:)[\s\S]*$/;
resolveUrl.domain = /^([^:]+:\/*[^/]*)[\s\S]*$/;
function noop() {} function noop() {}
noop.exec = noop; noop.exec = noop;
@ -137,7 +143,7 @@ function merge(obj) {
function splitCells(tableRow, count) { function splitCells(tableRow, count) {
// ensure that every cell-delimiting pipe has a space // ensure that every cell-delimiting pipe has a space
// before it to distinguish it from an escaped pipe // before it to distinguish it from an escaped pipe
const row = tableRow.replace(/\|/g, function(match, offset, str) { const row = tableRow.replace(/\|/g, (match, offset, str) => {
let escaped = false, let escaped = false,
curr = offset; curr = offset;
while (--curr >= 0 && str[curr] === '\\') escaped = !escaped; while (--curr >= 0 && str[curr] === '\\') escaped = !escaped;