reformat by prettier
This commit is contained in:
261
lib/default.js
261
lib/default.js
@@ -4,75 +4,75 @@
|
||||
* @author Zongmin Lei<leizongmin@gmail.com>
|
||||
*/
|
||||
|
||||
var FilterCSS = require('cssfilter').FilterCSS;
|
||||
var getDefaultCSSWhiteList = require('cssfilter').getDefaultWhiteList;
|
||||
var _ = require('./util');
|
||||
var FilterCSS = require("cssfilter").FilterCSS;
|
||||
var getDefaultCSSWhiteList = require("cssfilter").getDefaultWhiteList;
|
||||
var _ = require("./util");
|
||||
|
||||
function getDefaultWhiteList () {
|
||||
function getDefaultWhiteList() {
|
||||
return {
|
||||
a: ['target', 'href', 'title'],
|
||||
abbr: ['title'],
|
||||
a: ["target", "href", "title"],
|
||||
abbr: ["title"],
|
||||
address: [],
|
||||
area: ['shape', 'coords', 'href', 'alt'],
|
||||
area: ["shape", "coords", "href", "alt"],
|
||||
article: [],
|
||||
aside: [],
|
||||
audio: ['autoplay', 'controls', 'loop', 'preload', 'src'],
|
||||
b: [],
|
||||
bdi: ['dir'],
|
||||
bdo: ['dir'],
|
||||
big: [],
|
||||
blockquote: ['cite'],
|
||||
br: [],
|
||||
aside: [],
|
||||
audio: ["autoplay", "controls", "loop", "preload", "src"],
|
||||
b: [],
|
||||
bdi: ["dir"],
|
||||
bdo: ["dir"],
|
||||
big: [],
|
||||
blockquote: ["cite"],
|
||||
br: [],
|
||||
caption: [],
|
||||
center: [],
|
||||
cite: [],
|
||||
code: [],
|
||||
col: ['align', 'valign', 'span', 'width'],
|
||||
colgroup: ['align', 'valign', 'span', 'width'],
|
||||
dd: [],
|
||||
del: ['datetime'],
|
||||
details: ['open'],
|
||||
div: [],
|
||||
dl: [],
|
||||
dt: [],
|
||||
em: [],
|
||||
font: ['color', 'size', 'face'],
|
||||
cite: [],
|
||||
code: [],
|
||||
col: ["align", "valign", "span", "width"],
|
||||
colgroup: ["align", "valign", "span", "width"],
|
||||
dd: [],
|
||||
del: ["datetime"],
|
||||
details: ["open"],
|
||||
div: [],
|
||||
dl: [],
|
||||
dt: [],
|
||||
em: [],
|
||||
font: ["color", "size", "face"],
|
||||
footer: [],
|
||||
h1: [],
|
||||
h2: [],
|
||||
h3: [],
|
||||
h4: [],
|
||||
h5: [],
|
||||
h6: [],
|
||||
h1: [],
|
||||
h2: [],
|
||||
h3: [],
|
||||
h4: [],
|
||||
h5: [],
|
||||
h6: [],
|
||||
header: [],
|
||||
hr: [],
|
||||
i: [],
|
||||
img: ['src', 'alt', 'title', 'width', 'height'],
|
||||
ins: ['datetime'],
|
||||
li: [],
|
||||
mark: [],
|
||||
nav: [],
|
||||
ol: [],
|
||||
p: [],
|
||||
pre: [],
|
||||
s: [],
|
||||
section:[],
|
||||
small: [],
|
||||
span: [],
|
||||
sub: [],
|
||||
sup: [],
|
||||
hr: [],
|
||||
i: [],
|
||||
img: ["src", "alt", "title", "width", "height"],
|
||||
ins: ["datetime"],
|
||||
li: [],
|
||||
mark: [],
|
||||
nav: [],
|
||||
ol: [],
|
||||
p: [],
|
||||
pre: [],
|
||||
s: [],
|
||||
section: [],
|
||||
small: [],
|
||||
span: [],
|
||||
sub: [],
|
||||
sup: [],
|
||||
strong: [],
|
||||
table: ['width', 'border', 'align', 'valign'],
|
||||
tbody: ['align', 'valign'],
|
||||
td: ['width', 'rowspan', 'colspan', 'align', 'valign'],
|
||||
tfoot: ['align', 'valign'],
|
||||
th: ['width', 'rowspan', 'colspan', 'align', 'valign'],
|
||||
thead: ['align', 'valign'],
|
||||
tr: ['rowspan', 'align', 'valign'],
|
||||
tt: [],
|
||||
u: [],
|
||||
ul: [],
|
||||
video: ['autoplay', 'controls', 'loop', 'preload', 'src', 'height', 'width']
|
||||
table: ["width", "border", "align", "valign"],
|
||||
tbody: ["align", "valign"],
|
||||
td: ["width", "rowspan", "colspan", "align", "valign"],
|
||||
tfoot: ["align", "valign"],
|
||||
th: ["width", "rowspan", "colspan", "align", "valign"],
|
||||
thead: ["align", "valign"],
|
||||
tr: ["rowspan", "align", "valign"],
|
||||
tt: [],
|
||||
u: [],
|
||||
ul: [],
|
||||
video: ["autoplay", "controls", "loop", "preload", "src", "height", "width"]
|
||||
};
|
||||
}
|
||||
|
||||
@@ -86,7 +86,7 @@ var defaultCSSFilter = new FilterCSS();
|
||||
* @param {Object} options
|
||||
* @return {String}
|
||||
*/
|
||||
function onTag (tag, html, options) {
|
||||
function onTag(tag, html, options) {
|
||||
// do nothing
|
||||
}
|
||||
|
||||
@@ -98,7 +98,7 @@ function onTag (tag, html, options) {
|
||||
* @param {Object} options
|
||||
* @return {String}
|
||||
*/
|
||||
function onIgnoreTag (tag, html, options) {
|
||||
function onIgnoreTag(tag, html, options) {
|
||||
// do nothing
|
||||
}
|
||||
|
||||
@@ -110,7 +110,7 @@ function onIgnoreTag (tag, html, options) {
|
||||
* @param {String} value
|
||||
* @return {String}
|
||||
*/
|
||||
function onTagAttr (tag, name, value) {
|
||||
function onTagAttr(tag, name, value) {
|
||||
// do nothing
|
||||
}
|
||||
|
||||
@@ -122,7 +122,7 @@ function onTagAttr (tag, name, value) {
|
||||
* @param {String} value
|
||||
* @return {String}
|
||||
*/
|
||||
function onIgnoreTagAttr (tag, name, value) {
|
||||
function onIgnoreTagAttr(tag, name, value) {
|
||||
// do nothing
|
||||
}
|
||||
|
||||
@@ -131,8 +131,8 @@ function onIgnoreTagAttr (tag, name, value) {
|
||||
*
|
||||
* @param {String} html
|
||||
*/
|
||||
function escapeHtml (html) {
|
||||
return html.replace(REGEXP_LT, '<').replace(REGEXP_GT, '>');
|
||||
function escapeHtml(html) {
|
||||
return html.replace(REGEXP_LT, "<").replace(REGEXP_GT, ">");
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -144,42 +144,46 @@ function escapeHtml (html) {
|
||||
* @param {Object} cssFilter
|
||||
* @return {String}
|
||||
*/
|
||||
function safeAttrValue (tag, name, value, cssFilter) {
|
||||
function safeAttrValue(tag, name, value, cssFilter) {
|
||||
// unescape attribute value firstly
|
||||
value = friendlyAttrValue(value);
|
||||
|
||||
if (name === 'href' || name === 'src') {
|
||||
if (name === "href" || name === "src") {
|
||||
// filter `href` and `src` attribute
|
||||
// only allow the value that starts with `http://` | `https://` | `mailto:` | `/` | `#`
|
||||
value = _.trim(value);
|
||||
if (value === '#') return '#';
|
||||
if (!(value.substr(0, 7) === 'http://' ||
|
||||
value.substr(0, 8) === 'https://' ||
|
||||
value.substr(0, 7) === 'mailto:' ||
|
||||
value.substr(0, 4) === 'tel:' ||
|
||||
value[0] === '#' ||
|
||||
value[0] === '/')) {
|
||||
return '';
|
||||
if (value === "#") return "#";
|
||||
if (
|
||||
!(
|
||||
value.substr(0, 7) === "http://" ||
|
||||
value.substr(0, 8) === "https://" ||
|
||||
value.substr(0, 7) === "mailto:" ||
|
||||
value.substr(0, 4) === "tel:" ||
|
||||
value[0] === "#" ||
|
||||
value[0] === "/"
|
||||
)
|
||||
) {
|
||||
return "";
|
||||
}
|
||||
} else if (name === 'background') {
|
||||
} else if (name === "background") {
|
||||
// filter `background` attribute (maybe no use)
|
||||
// `javascript:`
|
||||
REGEXP_DEFAULT_ON_TAG_ATTR_4.lastIndex = 0;
|
||||
if (REGEXP_DEFAULT_ON_TAG_ATTR_4.test(value)) {
|
||||
return '';
|
||||
return "";
|
||||
}
|
||||
} else if (name === 'style') {
|
||||
} else if (name === "style") {
|
||||
// `expression()`
|
||||
REGEXP_DEFAULT_ON_TAG_ATTR_7.lastIndex = 0;
|
||||
if (REGEXP_DEFAULT_ON_TAG_ATTR_7.test(value)) {
|
||||
return '';
|
||||
return "";
|
||||
}
|
||||
// `url()`
|
||||
REGEXP_DEFAULT_ON_TAG_ATTR_8.lastIndex = 0;
|
||||
if (REGEXP_DEFAULT_ON_TAG_ATTR_8.test(value)) {
|
||||
REGEXP_DEFAULT_ON_TAG_ATTR_4.lastIndex = 0;
|
||||
if (REGEXP_DEFAULT_ON_TAG_ATTR_4.test(value)) {
|
||||
return '';
|
||||
return "";
|
||||
}
|
||||
}
|
||||
if (cssFilter !== false) {
|
||||
@@ -198,15 +202,15 @@ var REGEXP_LT = /</g;
|
||||
var REGEXP_GT = />/g;
|
||||
var REGEXP_QUOTE = /"/g;
|
||||
var REGEXP_QUOTE_2 = /"/g;
|
||||
var REGEXP_ATTR_VALUE_1 = /&#([a-zA-Z0-9]*);?/img;
|
||||
var REGEXP_ATTR_VALUE_COLON = /:?/img;
|
||||
var REGEXP_ATTR_VALUE_NEWLINE = /&newline;?/img;
|
||||
var REGEXP_DEFAULT_ON_TAG_ATTR_3 = /\/\*|\*\//mg;
|
||||
var REGEXP_DEFAULT_ON_TAG_ATTR_4 = /((j\s*a\s*v\s*a|v\s*b|l\s*i\s*v\s*e)\s*s\s*c\s*r\s*i\s*p\s*t\s*|m\s*o\s*c\s*h\s*a)\:/ig;
|
||||
var REGEXP_DEFAULT_ON_TAG_ATTR_5 = /^[\s"'`]*(d\s*a\s*t\s*a\s*)\:/ig;
|
||||
var REGEXP_DEFAULT_ON_TAG_ATTR_6 = /^[\s"'`]*(d\s*a\s*t\s*a\s*)\:\s*image\//ig;
|
||||
var REGEXP_DEFAULT_ON_TAG_ATTR_7 = /e\s*x\s*p\s*r\s*e\s*s\s*s\s*i\s*o\s*n\s*\(.*/ig;
|
||||
var REGEXP_DEFAULT_ON_TAG_ATTR_8 = /u\s*r\s*l\s*\(.*/ig;
|
||||
var REGEXP_ATTR_VALUE_1 = /&#([a-zA-Z0-9]*);?/gim;
|
||||
var REGEXP_ATTR_VALUE_COLON = /:?/gim;
|
||||
var REGEXP_ATTR_VALUE_NEWLINE = /&newline;?/gim;
|
||||
var REGEXP_DEFAULT_ON_TAG_ATTR_3 = /\/\*|\*\//gm;
|
||||
var REGEXP_DEFAULT_ON_TAG_ATTR_4 = /((j\s*a\s*v\s*a|v\s*b|l\s*i\s*v\s*e)\s*s\s*c\s*r\s*i\s*p\s*t\s*|m\s*o\s*c\s*h\s*a)\:/gi;
|
||||
var REGEXP_DEFAULT_ON_TAG_ATTR_5 = /^[\s"'`]*(d\s*a\s*t\s*a\s*)\:/gi;
|
||||
var REGEXP_DEFAULT_ON_TAG_ATTR_6 = /^[\s"'`]*(d\s*a\s*t\s*a\s*)\:\s*image\//gi;
|
||||
var REGEXP_DEFAULT_ON_TAG_ATTR_7 = /e\s*x\s*p\s*r\s*e\s*s\s*s\s*i\s*o\s*n\s*\(.*/gi;
|
||||
var REGEXP_DEFAULT_ON_TAG_ATTR_8 = /u\s*r\s*l\s*\(.*/gi;
|
||||
|
||||
/**
|
||||
* escape doube quote
|
||||
@@ -214,8 +218,8 @@ var REGEXP_DEFAULT_ON_TAG_ATTR_8 = /u\s*r\s*l\s*\(.*/ig;
|
||||
* @param {String} str
|
||||
* @return {String} str
|
||||
*/
|
||||
function escapeQuote (str) {
|
||||
return str.replace(REGEXP_QUOTE, '"');
|
||||
function escapeQuote(str) {
|
||||
return str.replace(REGEXP_QUOTE, """);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -224,7 +228,7 @@ function escapeQuote (str) {
|
||||
* @param {String} str
|
||||
* @return {String} str
|
||||
*/
|
||||
function unescapeQuote (str) {
|
||||
function unescapeQuote(str) {
|
||||
return str.replace(REGEXP_QUOTE_2, '"');
|
||||
}
|
||||
|
||||
@@ -234,11 +238,11 @@ function unescapeQuote (str) {
|
||||
* @param {String} str
|
||||
* @return {String}
|
||||
*/
|
||||
function escapeHtmlEntities (str) {
|
||||
return str.replace(REGEXP_ATTR_VALUE_1, function replaceUnicode (str, code) {
|
||||
return (code[0] === 'x' || code[0] === 'X')
|
||||
? String.fromCharCode(parseInt(code.substr(1), 16))
|
||||
: String.fromCharCode(parseInt(code, 10));
|
||||
function escapeHtmlEntities(str) {
|
||||
return str.replace(REGEXP_ATTR_VALUE_1, function replaceUnicode(str, code) {
|
||||
return code[0] === "x" || code[0] === "X"
|
||||
? String.fromCharCode(parseInt(code.substr(1), 16))
|
||||
: String.fromCharCode(parseInt(code, 10));
|
||||
});
|
||||
}
|
||||
|
||||
@@ -248,9 +252,10 @@ function escapeHtmlEntities (str) {
|
||||
* @param {String} str
|
||||
* @return {String}
|
||||
*/
|
||||
function escapeDangerHtml5Entities (str) {
|
||||
return str.replace(REGEXP_ATTR_VALUE_COLON, ':')
|
||||
.replace(REGEXP_ATTR_VALUE_NEWLINE, ' ');
|
||||
function escapeDangerHtml5Entities(str) {
|
||||
return str
|
||||
.replace(REGEXP_ATTR_VALUE_COLON, ":")
|
||||
.replace(REGEXP_ATTR_VALUE_NEWLINE, " ");
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -259,10 +264,10 @@ function escapeDangerHtml5Entities (str) {
|
||||
* @param {String} str
|
||||
* @return {String}
|
||||
*/
|
||||
function clearNonPrintableCharacter (str) {
|
||||
var str2 = '';
|
||||
function clearNonPrintableCharacter(str) {
|
||||
var str2 = "";
|
||||
for (var i = 0, len = str.length; i < len; i++) {
|
||||
str2 += str.charCodeAt(i) < 32 ? ' ' : str.charAt(i);
|
||||
str2 += str.charCodeAt(i) < 32 ? " " : str.charAt(i);
|
||||
}
|
||||
return _.trim(str2);
|
||||
}
|
||||
@@ -273,7 +278,7 @@ function clearNonPrintableCharacter (str) {
|
||||
* @param {String} str
|
||||
* @return {String}
|
||||
*/
|
||||
function friendlyAttrValue (str) {
|
||||
function friendlyAttrValue(str) {
|
||||
str = unescapeQuote(str);
|
||||
str = escapeHtmlEntities(str);
|
||||
str = escapeDangerHtml5Entities(str);
|
||||
@@ -287,7 +292,7 @@ function friendlyAttrValue (str) {
|
||||
* @param {String} str
|
||||
* @return {String}
|
||||
*/
|
||||
function escapeAttrValue (str) {
|
||||
function escapeAttrValue(str) {
|
||||
str = escapeQuote(str);
|
||||
str = escapeHtml(str);
|
||||
return str;
|
||||
@@ -296,8 +301,8 @@ function escapeAttrValue (str) {
|
||||
/**
|
||||
* `onIgnoreTag` function for removing all the tags that are not in whitelist
|
||||
*/
|
||||
function onIgnoreTagStripAll () {
|
||||
return '';
|
||||
function onIgnoreTagStripAll() {
|
||||
return "";
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -307,43 +312,46 @@ function onIgnoreTagStripAll () {
|
||||
* @param {array} tags
|
||||
* @param {function} next
|
||||
*/
|
||||
function StripTagBody (tags, next) {
|
||||
if (typeof(next) !== 'function') {
|
||||
next = function () {};
|
||||
function StripTagBody(tags, next) {
|
||||
if (typeof next !== "function") {
|
||||
next = function() {};
|
||||
}
|
||||
|
||||
var isRemoveAllTag = !Array.isArray(tags);
|
||||
function isRemoveTag (tag) {
|
||||
function isRemoveTag(tag) {
|
||||
if (isRemoveAllTag) return true;
|
||||
return (_.indexOf(tags, tag) !== -1);
|
||||
return _.indexOf(tags, tag) !== -1;
|
||||
}
|
||||
|
||||
var removeList = [];
|
||||
var posStart = false;
|
||||
|
||||
return {
|
||||
onIgnoreTag: function (tag, html, options) {
|
||||
onIgnoreTag: function(tag, html, options) {
|
||||
if (isRemoveTag(tag)) {
|
||||
if (options.isClosing) {
|
||||
var ret = '[/removed]';
|
||||
var ret = "[/removed]";
|
||||
var end = options.position + ret.length;
|
||||
removeList.push([posStart !== false ? posStart : options.position, end]);
|
||||
removeList.push([
|
||||
posStart !== false ? posStart : options.position,
|
||||
end
|
||||
]);
|
||||
posStart = false;
|
||||
return ret;
|
||||
} else {
|
||||
if (!posStart) {
|
||||
posStart = options.position;
|
||||
}
|
||||
return '[removed]';
|
||||
return "[removed]";
|
||||
}
|
||||
} else {
|
||||
return next(tag, html, options);
|
||||
}
|
||||
},
|
||||
remove: function (html) {
|
||||
var rethtml = '';
|
||||
remove: function(html) {
|
||||
var rethtml = "";
|
||||
var lastPos = 0;
|
||||
_.forEach(removeList, function (pos) {
|
||||
_.forEach(removeList, function(pos) {
|
||||
rethtml += html.slice(lastPos, pos[0]);
|
||||
lastPos = pos[1];
|
||||
});
|
||||
@@ -359,8 +367,8 @@ function StripTagBody (tags, next) {
|
||||
* @param {String} html
|
||||
* @return {String}
|
||||
*/
|
||||
function stripCommentTag (html) {
|
||||
return html.replace(STRIP_COMMENT_TAG_REGEXP, '');
|
||||
function stripCommentTag(html) {
|
||||
return html.replace(STRIP_COMMENT_TAG_REGEXP, "");
|
||||
}
|
||||
var STRIP_COMMENT_TAG_REGEXP = /<!--[\s\S]*?-->/g;
|
||||
|
||||
@@ -370,9 +378,9 @@ var STRIP_COMMENT_TAG_REGEXP = /<!--[\s\S]*?-->/g;
|
||||
* @param {String} html
|
||||
* @return {String}
|
||||
*/
|
||||
function stripBlankChar (html) {
|
||||
var chars = html.split('');
|
||||
chars = chars.filter(function (char) {
|
||||
function stripBlankChar(html) {
|
||||
var chars = html.split("");
|
||||
chars = chars.filter(function(char) {
|
||||
var c = char.charCodeAt(0);
|
||||
if (c === 127) return false;
|
||||
if (c <= 31) {
|
||||
@@ -381,10 +389,9 @@ function stripBlankChar (html) {
|
||||
}
|
||||
return true;
|
||||
});
|
||||
return chars.join('');
|
||||
return chars.join("");
|
||||
}
|
||||
|
||||
|
||||
exports.whiteList = getDefaultWhiteList();
|
||||
exports.getDefaultWhiteList = getDefaultWhiteList;
|
||||
exports.onTag = onTag;
|
||||
|
||||
Reference in New Issue
Block a user