/**
* MOST Web Framework
* A JavaScript Web Framework
* http://themost.io
*
* Copyright (c) 2014, Kyriakos Barbounakis k.barbounakis@gmail.com, Anthi Oikonomou anthioikonomou@gmail.com
*
* Released under the BSD3-Clause license
* Date: 2014-06-10
*/
/**
* @private
*/
var HTML_START_CHAR='<',
HTML_END_CHAR='>',
HTML_FULL_END_STRING = ' />',
HTML_SPACE_CHAR = ' ',
HTML_ATTR_STRING = '%0="%1"',
HTML_START_TAG_STRING = '<%0',
HTML_END_TAG_STRING = '</%0>';
/**
* @classdesc HtmlWriter class represents a helper class for rendering HTML content.
* @class
* @constructor
* @memberOf module:most-web.html
*/
function HtmlWriter() {
/**
* @private
* @type {Array}
*/
this.bufferedAttributes=[];
/**
* @private
* @type {Array}
*/
this.bufferedTags = [];
/**
* @private
* @type {String}
*/
this.buffer = '';
/**
* @private
* @type {Integer}
*/
this.indent = true;
};
/**
* Writes an attribute to an array of attributes that is going to be used in writeBeginTag function
* @param {String} name - The name of the HTML attribute
* @param {String} value - The value of the HTML attribute
* @returns {HtmlWriter}
*/
HtmlWriter.prototype.writeAttribute = function(name, value)
{
this.bufferedAttributes.push({name:name, value:value});
return this;
};
/**
* Writes an array of attributes to the output buffer. This attributes are going to be rendered after writeBeginTag or WriteFullBeginTag function call.
* @param {Array|Object} obj - An array of attributes or an object that represents an array of attributes
* @returns {HtmlWriter}
*/
HtmlWriter.prototype.writeAttributes = function(obj)
{
if (obj==null)
return this;
if (typeof obj === 'array') {
for (var i = 0; i < obj.length; i++) {
this.bufferedAttributes.push( { name:obj[i].name, value:obj[i].value } );
}
}
else {
for (var prop in obj)
{
if (obj.hasOwnProperty(prop)) {
if (obj[prop]!=null) {
this.bufferedAttributes.push( { name:prop, value:obj[prop] } );
}
}
}
}
return this;
};
/**
* @param {String} tag
* @returns {HtmlWriter}
*/
HtmlWriter.prototype.writeBeginTag = function(tag) {
var string = require('string');
var array = require('most-array');
//write <TAG
if (this.indent)
{
//this.buffer += '\n';
this.buffer +=string('\t').repeat(this.bufferedTags.length).s;
}
this.buffer += HTML_START_TAG_STRING.replace(/%0/, tag);
this.bufferedTags.push(tag);
if (this.bufferedAttributes.length>0)
{
var s = '';
array(this.bufferedAttributes).each(function(attr) {
//write attribute='value'
s += HTML_SPACE_CHAR;
s += HTML_ATTR_STRING.replace(/%0/,attr.name).replace(/%1/, string(attr.value).escapeHTML());
});
this.buffer += s;
}
this.bufferedAttributes.splice(0,this.bufferedAttributes.length);
this.buffer += HTML_END_CHAR;
return this;
};
/**
* Writes a full begin HTML tag (e.g <div/>).
* @param {String} tag
* @returns {HtmlWriter}
*/
HtmlWriter.prototype.writeFullBeginTag = function(tag) {
var string = require('string');
//write <TAG
if (this.indent)
{
this.buffer += '\n';
this.buffer +=string('\t').repeat(this.bufferedTags.length).s;
}
this.buffer += HTML_START_TAG_STRING.replace(/%0/, tag);
if (this.bufferedAttributes.length>0)
{
var array = require('most-array');
var string = require('string');
var s = '';
array(this.bufferedAttributes).each(function(attr) {
//write attribute='value'
s += HTML_SPACE_CHAR;
s += HTML_ATTR_STRING.replace(/%0/,attr.name).replace(/%1/, string(attr.value).escapeHTML());
});
this.buffer += s;
}
this.bufferedAttributes.splice(0,this.bufferedAttributes.length);
this.buffer += HTML_FULL_END_STRING;
return this;
};
/**
* Writes an end HTML tag (e.g </div>) based on the current buffered tags.
* @returns {HtmlWriter}
*/
HtmlWriter.prototype.writeEndTag = function()
{
var string = require('string');
var tagsLength = this.bufferedTags ? this.bufferedTags.length : 0;
if (tagsLength==0)
return this;
if (this.indent)
{
this.buffer += '\n';
this.buffer +=string('\t').repeat(tagsLength-1).s;
}
this.buffer += HTML_END_TAG_STRING.replace(/%0/,this.bufferedTags[tagsLength-1]);
this.bufferedTags.splice(tagsLength-1,1);
return this;
}
/**
*
* @param {String} s
* @returns {HtmlWriter}
*/
HtmlWriter.prototype.writeText = function(s) {
if (!s)
return this;
var string = require('string');
if (this.indent)
{
this.buffer += '\n';
this.buffer +=string('\t').repeat(this.bufferedTags.length).s;
}
this.buffer += string(s).escapeHTML();
return this;
};
/**
*
* @param {String} s
* @returns {HtmlWriter}
*/
HtmlWriter.prototype.write = function(s) {
this.buffer += s;
return this;
};
/**
* @returns {String}
*/
HtmlWriter.prototype.toString = function() {
return this.buffer;
};
/**
* @param {function} f
*/
HtmlWriter.prototype.writeTo = function(fn)
{
if (typeof fn === 'function') {
//call function
fn(this.buffer);
//and clear buffer
this.buffer='';
//and clear buffered tags
this.bufferedTags.splice(0,this.bufferedTags.length);
}
};
/**
* @namespace html
* @memberOf module:most-web
*/
var html_ = {
HtmlWriter:HtmlWriter,
/**
* Creates an HTML writer object.
* @returns {HtmlWriter}
* @memberOf module:most-web.html
*/
createInstance: function() {
return new HtmlWriter();
},
/**
* Creates an HTML writer object.
* @returns {HtmlWriter}
* @memberOf module:most-web.html
*/
createHtmlWriter: function() {
return new HtmlWriter();
}
};
if (typeof exports !== 'undefined')
{
module.exports = html_;
}