html-maker
Version:
Yet another HTML builder
185 lines (162 loc) • 6.25 kB
JavaScript
(function() {
var Maker, SelfClosingTags, Tags, dasherize,
slice = [].slice;
SelfClosingTags = {};
'area base br col command embed hr img input keygen link meta param source track wbr'.split(/\s+/).forEach(function(tag) {
return SelfClosingTags[tag] = true;
});
Tags = 'a abbr address article aside audio b bdi bdo blockquote body button canvas caption cite code colgroup datalist dd del details dfn dialog div dl dt em fieldset figcaption figure footer form h1 h2 h3 h4 h5 h6 head header html i iframe ins kbd label legend li main map mark menu meter nav noscript object ol optgroup option output p pre progress q rp rt ruby s samp script section select small span strong style sub summary sup table tbody td textarea tfoot th thead time title tr u ul var video area base br col command embed hr img input keygen link meta param source track wbr'.split(/\s+/);
dasherize = function(string) {
if (!string) {
return '';
}
string = string[0].toLowerCase() + string.slice(1);
return string.replace(/([A-Z])|(_)/g, function(m, letter) {
if (letter) {
return "-" + letter.toLowerCase();
} else {
return "-";
}
});
};
Maker = (function() {
Maker.render = function() {
var args, builder, view;
view = arguments[0], args = 2 <= arguments.length ? slice.call(arguments, 1) : [];
builder = new this();
builder.render.apply(builder, [view].concat(slice.call(args)));
return builder.build();
};
Maker.render_external = function() {
var args, builder, view;
view = arguments[0], args = 2 <= arguments.length ? slice.call(arguments, 1) : [];
builder = new this();
view.apply(null, [builder].concat(slice.call(args)));
return builder.build();
};
Maker.prototype.render = function() {
var args, view;
view = arguments[0], args = 2 <= arguments.length ? slice.call(arguments, 1) : [];
return view.call.apply(view, [this].concat(slice.call(args)));
};
function Maker() {
this.document = [];
}
Maker.prototype.build = function() {
return this.document.join('');
};
Tags.forEach(function(tagName) {
return Maker.prototype[tagName] = function() {
var args;
args = 1 <= arguments.length ? slice.call(arguments, 0) : [];
return this.tag.apply(this, [tagName].concat(slice.call(args)));
};
});
Maker.prototype.tag = function() {
var args, name, options;
name = arguments[0], args = 2 <= arguments.length ? slice.call(arguments, 1) : [];
options = this.extractOptions(args);
this.openTag(name, options.attributes);
if (SelfClosingTags.hasOwnProperty(name)) {
if ((options.text != null) || (options.content != null)) {
throw new Error("Self-closing tag " + name + " cannot have text or content");
}
return this.endTag(name);
} else {
if (typeof options.content === "function") {
options.content();
}
if (options.text) {
this.text(options.text);
}
return this.closeTag(name);
}
};
Maker.prototype.openTag = function(name, attributes) {
var attributeName, attributePairs, attributesString, dataName, dataValue, style, value;
if (this.document.length === 0) {
if (attributes == null) {
attributes = {};
}
}
attributePairs = (function() {
var results;
results = [];
for (attributeName in attributes) {
value = attributes[attributeName];
if (value != null) {
if (attributeName === 'data' && typeof value === 'object') {
results.push(((function() {
var results1;
results1 = [];
for (dataName in value) {
dataValue = value[dataName];
if (dataValue != null) {
results1.push(attributeName + "-" + (dasherize(dataName)) + "=\"" + dataValue + "\"");
}
}
return results1;
})()).join(" "));
} else if (attributeName === 'style' && typeof value === 'object') {
style = ((function() {
var results1;
results1 = [];
for (dataName in value) {
dataValue = value[dataName];
if (dataValue != null) {
results1.push((dasherize(dataName)) + ": " + dataValue);
}
}
return results1;
})()).join("; ");
results.push("style=\"" + style + "\"");
} else {
results.push(attributeName + "=\"" + value + "\"");
}
}
}
return results;
})();
attributesString = attributePairs.length ? " " + attributePairs.join(" ") : "";
return this.document.push("<" + name + attributesString + ">");
};
Maker.prototype.closeTag = function(name) {
return this.document.push("</" + name + ">");
};
Maker.prototype.endTag = function(name) {};
Maker.prototype.rawText = function(string) {
return this.document.push(string);
};
Maker.prototype.text = function(string) {
var escapedString;
if (string) {
escapedString = string.replace(/&/g, '&').replace(/"/g, '"').replace(/'/g, ''').replace(/</g, '<').replace(/>/g, '>');
return this.rawText(escapedString);
}
};
Maker.prototype.raw = function(string) {
return this.rawText(string);
};
Maker.prototype.extractOptions = function(args) {
var arg, i, len, options;
options = {};
for (i = 0, len = args.length; i < len; i++) {
arg = args[i];
switch (typeof arg) {
case 'function':
options.content = arg;
break;
case 'string':
case 'number':
options.text = arg.toString();
break;
default:
options.attributes = arg;
}
}
return options;
};
return Maker;
})();
module.exports = Maker;
}).call(this);