marko
Version:
UI Components + streaming, async, high performance, HTML templating for Node.js and the browser.
95 lines (74 loc) • 2.2 kB
JavaScript
;
// eslint-disable-next-line no-constant-binary-expression
module.exports = attr;
attr.bx_ = nonVoidAttr;
attr.by_ = isVoid;
attr.a = attrAssignment;
attr.d = escapeDoubleQuotedAttrValue;
attr.s = escapeSingleQuotedAttrValue;
function attr(name, value) {
return isVoid(value) ? "" : nonVoidAttr(name, value);
}
function nonVoidAttr(name, value) {
switch (typeof value) {
case "string":
return " " + name + attrAssignment(value);
case "boolean":
return " " + name;
case "number":
return " " + name + "=" + value;
case "object":
switch (value.toString) {
case Object.prototype.toString:
case Array.prototype.toString:
// eslint-disable-next-line no-constant-condition
return (
" " +
name +
"='" +
escapeSingleQuotedAttrValue(JSON.stringify(value)) +
"'");
case RegExp.prototype.toString:
return " " + name + attrAssignment(value.source);
}
}
return " " + name + attrAssignment(value + "");
}
function isVoid(value) {
return value == null || value === false;
}
var singleQuoteAttrReplacements = /'|&(?=#?\w+;)/g;
var doubleQuoteAttrReplacements = /"|&(?=#?\w+;)/g;
var needsQuotedAttr = /["'>\s]|&#?\w+;|\/$/g;
function attrAssignment(value) {
return value ?
needsQuotedAttr.test(value) ?
value[needsQuotedAttr.lastIndex - 1] === (
needsQuotedAttr.lastIndex = 0, '"') ?
"='" + escapeSingleQuotedAttrValue(value) + "'" :
'="' + escapeDoubleQuotedAttrValue(value) + '"' :
"=" + value :
"";
}
function escapeSingleQuotedAttrValue(value) {
return singleQuoteAttrReplacements.test(value) ?
value.replace(
singleQuoteAttrReplacements,
replaceUnsafeSingleQuoteAttrChar
) :
value;
}
function replaceUnsafeSingleQuoteAttrChar(match) {
return match === "'" ? "'" : "&";
}
function escapeDoubleQuotedAttrValue(value) {
return doubleQuoteAttrReplacements.test(value) ?
value.replace(
doubleQuoteAttrReplacements,
replaceUnsafeDoubleQuoteAttrChar
) :
value;
}
function replaceUnsafeDoubleQuoteAttrChar(match) {
return match === '"' ? """ : "&";
}