1 (function(root) {
    2 	'use strict';
    3 
    4 	function _attr(e, attr, text)
    5 	{
    6 		if (null === e)
    7 			return;
    8 		e.setAttribute(attr, text);
    9 	}
   10 
   11 	function _attrcl(e, attr, name, text, inc)
   12 	{
   13 		var list, i;
   14 		if (null === e)
   15 			return;
   16 		list = _elemList(e, name, inc);
   17 		for (i = 0; i < list.length; i++)
   18 			_attr(list[i], attr, text);
   19 	}
   20 
   21 	function _elemList(e, cls, inc)
   22 	{
   23 		var a = [], list, i;
   24 		if (null === e)
   25 			return(a);
   26 		list = e.getElementsByClassName(cls);
   27 		for (i = 0; i < list.length; i++)
   28 			a.push(list[i]);
   29 		if (inc && e.classList.contains(cls))
   30 			a.push(e);
   31 		return(a);
   32 	}
   33 
   34 	function _repl(e, text)
   35 	{
   36 		if (null === e)
   37 			return;
   38 		while (e.firstChild)
   39 			e.removeChild(e.firstChild);
   40 		e.appendChild(document.createTextNode(text));
   41 	}
   42 
   43 	function _replcl(e, name, text, inc)
   44 	{
   45 		var list, i;
   46 		if (null === e)
   47 			return;
   48 		list = _elemList(e, name, inc);
   49 		for (i = 0; i < list.length; i++)
   50 			_repl(list[i], text);
   51 	}
   52 
   53 	function _hide(e)
   54 	{
   55 		if (null === e)
   56 			return(null);
   57 		if ( ! e.classList.contains('hide'))
   58 			e.classList.add('hide');
   59 		return(e);
   60 	}
   61 	
   62 	function _hidecl(e, name, inc)
   63 	{
   64 		var list, i;
   65 		if (null === e)
   66 			return;
   67 		list = _elemList(e, name, inc);
   68 		for (i = 0; i < list.length; i++)
   69 			_hide(list[i]);
   70 	}
   71 
   72 	function _show(e)
   73 	{
   74 		if (null === e)
   75 			return(null);
   76 		if (e.classList.contains('hide'))
   77 			e.classList.remove('hide');
   78 		return(e);
   79 	}
   80 	
   81 	function _showcl(e, name, inc)
   82 	{
   83 		var list, i;
   84 		if (null === e)
   85 			return;
   86 		list = _elemList(e, name, inc);
   87 		for (i = 0; i < list.length; i++)
   88 			_show(list[i]);
   89 	}
   90 
   91 	/**
   92 	 * Represent a "user" object (or array of objects) for filling into a DOM tree.
   93 	 * @constructor
   94 	 * @param {(Object|Object[])} obj - The user object, which may also be an array of objects.
   95 	 */
   96 	function user(obj)
   97 	{
   98 		this.obj = obj;
   99 
  100 		/**
  101 		 * Fill in a "user" object at the given element in the DOM tree.
  102 		 * If the object was initialised with an array, the first element is used.
  103 		 * Elements within (and including) #e having the following classes are manipulated as follows:
  104 		 * user-email-text: replace contents with email data
  105 		 * user-email-value: replace "value" attribute with email data
  106 		 * user-hash-text: replace contents with hash data
  107 		 * user-hash-value: replace "value" attribute with hash data
  108 		 * user-id-text: replace contents with id data
  109 		 * user-id-value: replace "value" attribute with id data
  110 		 * @param {Object} e - The DOM element.
  111 		 */
  112 		this.fill = function(e) {
  113 			this._fill(e, this.obj, 1);
  114 		};
  115 
  116 		/**
  117 		 * Like fill() but not including the root element #e.
  118 		 * @param {Object} e - The DOM element.
  119 		 */
  120 		this.fillInner = function(e) {
  121 			this._fill(e, this.obj, 0);
  122 		};
  123 
  124 		/**
  125 		 * Implements all fill() style functions.
  126 		 * @private
  127 		 * @param {Object} e - the DOM element.
  128 		 * @param {(Object|Object[])} o - the object (or array) to fill
  129 		 * @param {number} inc - whether to include the root or not when processing
  130 		 */
  131 		this._fill = function(e, o, inc) {
  132 			if (null === o || null === e)
  133 				return;
  134 			if (o instanceof Array) {
  135 				if (0 === o.length)
  136 					return;
  137 				o = o[0];
  138 			}
  139 			_replcl(e, 'user-email-text', o.email, inc);
  140 			_attrcl(e, 'value', 'user-email-value', o.email, inc);
  141 			_replcl(e, 'user-hash-text', o.hash, inc);
  142 			_attrcl(e, 'value', 'user-hash-value', o.hash, inc);
  143 			_replcl(e, 'user-id-text', o.id, inc);
  144 			_attrcl(e, 'value', 'user-id-value', o.id, inc);
  145 		};
  146 
  147 		/**
  148 		 * Like fill() but for an array of user.
  149 		 * This will remove the first element within #e then repeatedly clone and re-append it,
  150 		 * filling in the cloned subtree with the array.
  151 		 * If #e is not an array, it is construed as an array of one.
  152 		 * If the input array is empty, #e is hidden by using the "hide" class.
  153 		 * Otherwise, the "hide" class is removed.
  154 		 * @param {Object} e - The DOM element.
  155 		 */
  156 		this.fillArray = function(e) {
  157 			var o = this.obj;
  158 			var j, row, cln;
  159 			if (null === o || null === e)
  160 				return;
  161 			if ( ! (o instanceof Array)) {
  162 				var ar = [];
  163 				ar.push(o);
  164 				o = ar;
  165 			}
  166 			if (0 === o.length) {
  167 				_hide(e);
  168 				return;
  169 			}
  170 			_show(e);
  171 			row = e.children[0];
  172 			if (null === row)
  173 				return;
  174 			e.removeChild(row);
  175 			while (null !== e.firstChild)
  176 				e.removeChild(e.firstChild)
  177 			for (j = 0; j < o.length; j++) {
  178 				cln = row.cloneNode(true);
  179 				e.appendChild(cln);
  180 				this._fill(cln, o[j], 1);
  181 			}
  182 		};
  183 	}
  184 
  185 	/**
  186 	 * Represent a "sess" object (or array of objects) for filling into a DOM tree.
  187 	 * @constructor
  188 	 * @param {(Object|Object[])} obj - The sess object, which may also be an array of objects.
  189 	 */
  190 	function sess(obj)
  191 	{
  192 		this.obj = obj;
  193 
  194 		/**
  195 		 * Fill in a "sess" object at the given element in the DOM tree.
  196 		 * If the object was initialised with an array, the first element is used.
  197 		 * Elements within (and including) #e having the following classes are manipulated as follows:
  198 		 * sess-user-obj: invoke user.fillInner() method with user data
  199 		 * sess-userid-text: replace contents with userid data
  200 		 * sess-userid-value: replace "value" attribute with userid data
  201 		 * sess-token-text: replace contents with token data
  202 		 * sess-token-value: replace "value" attribute with token data
  203 		 * sess-id-text: replace contents with id data
  204 		 * sess-id-value: replace "value" attribute with id data
  205 		 * @param {Object} e - The DOM element.
  206 		 */
  207 		this.fill = function(e) {
  208 			this._fill(e, this.obj, 1);
  209 		};
  210 
  211 		/**
  212 		 * Like fill() but not including the root element #e.
  213 		 * @param {Object} e - The DOM element.
  214 		 */
  215 		this.fillInner = function(e) {
  216 			this._fill(e, this.obj, 0);
  217 		};
  218 
  219 		/**
  220 		 * Implements all fill() style functions.
  221 		 * @private
  222 		 * @param {Object} e - the DOM element.
  223 		 * @param {(Object|Object[])} o - the object (or array) to fill
  224 		 * @param {number} inc - whether to include the root or not when processing
  225 		 */
  226 		this._fill = function(e, o, inc) {
  227 			var list, strct, i;
  228 			if (null === o || null === e)
  229 				return;
  230 			if (o instanceof Array) {
  231 				if (0 === o.length)
  232 					return;
  233 				o = o[0];
  234 			}
  235 			list = _elemList(e, 'sess-user-obj');
  236 			strct = new user(o.user);
  237 			for (i = 0; i < list.length; i++) {
  238 				strct.fillInner(list[i]);
  239 			}
  240 			_replcl(e, 'sess-userid-text', o.userid, inc);
  241 			_attrcl(e, 'value', 'sess-userid-value', o.userid, inc);
  242 			_replcl(e, 'sess-token-text', o.token, inc);
  243 			_attrcl(e, 'value', 'sess-token-value', o.token, inc);
  244 			_replcl(e, 'sess-id-text', o.id, inc);
  245 			_attrcl(e, 'value', 'sess-id-value', o.id, inc);
  246 		};
  247 
  248 		/**
  249 		 * Like fill() but for an array of sess.
  250 		 * This will remove the first element within #e then repeatedly clone and re-append it,
  251 		 * filling in the cloned subtree with the array.
  252 		 * If #e is not an array, it is construed as an array of one.
  253 		 * If the input array is empty, #e is hidden by using the "hide" class.
  254 		 * Otherwise, the "hide" class is removed.
  255 		 * @param {Object} e - The DOM element.
  256 		 */
  257 		this.fillArray = function(e) {
  258 			var list, strct, i;
  259 			var o = this.obj;
  260 			var j, row, cln;
  261 			if (null === o || null === e)
  262 				return;
  263 			if ( ! (o instanceof Array)) {
  264 				var ar = [];
  265 				ar.push(o);
  266 				o = ar;
  267 			}
  268 			if (0 === o.length) {
  269 				_hide(e);
  270 				return;
  271 			}
  272 			_show(e);
  273 			row = e.children[0];
  274 			if (null === row)
  275 				return;
  276 			e.removeChild(row);
  277 			while (null !== e.firstChild)
  278 				e.removeChild(e.firstChild)
  279 			for (j = 0; j < o.length; j++) {
  280 				cln = row.cloneNode(true);
  281 				e.appendChild(cln);
  282 				this._fill(cln, o[j], 1);
  283 			}
  284 		};
  285 	}
  286 
  287 	root.user = user;
  288 	root.sess = sess;
  289 })(this);