lib/html/fast.js
var Html = require('./html');
function Fast(format) {
// See http://www.w3.org/html/wg/drafts/html/master/single-page.html#void-elements
this._autoclose = 'area base br col embed hr img input keygen link menuitem meta param source track wbr'.split(/\s/);
this._format = format || 'xhtml';
this._attrQuote = '"';
this._jsWrapper = ['\n//<![CDATA[\n', '\n//]]>\n'];
}
var p = Fast.prototype = new Html();
p.on_html_doctype = function(exps) {
var type = exps[2];
var html = '<!DOCTYPE html>';
var DOCTYPES = {
xml: {
'1.1' : '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">',
'5' : html,
'html' : html,
'basic' : '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML Basic 1.1//EN" "http://www.w3.org/TR/xhtml-basic/xhtml-basic11.dtd">',
'frameset' : '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Frameset//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-frameset.dtd">',
'strict' : '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">',
'svg' : '<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">',
'transitional' : '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">'
},
html: {
'5' : html,
'html' : html,
'frameset' : '<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Frameset//EN" "http://www.w3.org/TR/html4/frameset.dtd">',
'strict' : '<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">',
'transitional' : '<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">'
}
};
DOCTYPES.xhtml = DOCTYPES.xml;
type = type.toString().toLowerCase();
var m, str;
m = /^xml(\s+(.+))?$/.exec(type);
if (m) {
if (this._format === 'html') {
throw new Error('Invalid xml directive in html mode');
}
var w = this._attrQuote;
str = '<?xml version=' + w + '1.0' + w + ' encoding=' + w + (m[2] || 'utf-8') + w + ' ?>';
} else {
str = DOCTYPES[this._format][type];
if (!str) {
throw new Error('Invalid doctype ' + type);
}
}
return ['static', str];
};
p.on_html_comment = function(exps) {
return ['multi', ['static', '<!--'], this.compile(exps[2]), ['static', '-->']];
};
p.on_html_condcomment = function(exps) {
return this.on_html_comment(['html', 'comment', [
'multi',
['static', '[' + exps[2] + ']>'], exps[3], ['static', '<![endif]']]]);
};
p.on_html_tag = function(exps) {
var name = exps[2].toString(), attrs = exps[3], content = exps[4];
var closed = !content || (this._isEmptyExp(content) && (this._format === 'xml' || this._autoclose.indexOf(name) !== -1));
var res = [
'multi',
['static', '<' + name],
this.compile(attrs),
['static', (closed && this._format !== 'html' ? ' /' : '') + '>']
];
if (content) {
res.push(this.compile(content));
}
if (!closed) {
res.push(['static', '</' + name + '>']);
}
return res;
};
p.on_html_attrs = p._shiftAndCompileMulti;
p.on_html_attr = function(exps) {
var name = exps[2], value = exps[3];
if (this._format === 'html' && this._isEmptyExp(value)) {
return ['static', ' ' + name];
}
return ['multi',
['static', ' ' + name + '=' + this._attrQuote],
this.compile(value),
['static', this._attrQuote]];
};
p.on_html_js = function(exps) {
var content = exps[2];
return ['multi',
['static', this._jsWrapper[0]],
this.compile(content),
['static', this._jsWrapper[1]]];
};
module.exports = Fast;