/**

 * 创建html

 * @param o

 * {tag:string,              // 元素的标记名,如果没有,默认为div

     children|cn:string|Array|json, // 子结点对应的json数组或字节点的html或单个json

     html:string,            // 对应的html,如果有cn或children属性就忽略

     style:function|string|json,   // 元素的样式,可以是函数,字符串,json对象

     cls:string,            // 元素的class属性的值

     htmlFor:string           // 元素的For属性,

     x:y                  // x表示其他名字,y表示非函数、非空内容

   }

     var spec = {

         id: 'my-ul',

         tag: 'ul',

         cls: 'my-list',

         style : {width:'20px',height:'30px'},

         // append children after creating

         children: [     // may also specify 'cn' instead of 'children'

             {tag: 'li', id: 'item0', html: 'List Item 0'},

             {tag: 'li', id: 'item1', html: 'List Item 1'},

             {tag: 'li', id: 'item2', html: 'List Item 2'}

         ]

     };

 */

function createHtml(o){

    var b = '',

        cn,

        attr,

        val,

        key;

    if(typeof o == 'string'){ // 若是 string 类型,直接返回

        b = o;

    } else if(Ice.isArray(o)){ // 若是 array 类型, 如: [{ tag: 'li', id: 'item0' }]

        for(var i=0,len=o.length; i<len; i++){

            if(o[i]){

                b += createHtml(o[i]);

            }

        }

    } else { // 若是 object 类型

        b += '<' + (o.tag = o.tag || 'div'); // 若没有 o.tag 属性,则默认为 div, 如: <div

        for (attr in o) {

            val = o[attr];

            if(!confRe.test(attr)){ // 忽略 tag|children|cn|html,这四个是需自定义属性

                if(typeof val == 'object'){ // 若是对象类型, 如: style : {width:'20px',height:'30px'}

                    b += ' ' + attr + '="'; // 如: style = "

                    for (key in val) {

                        b += key + ':' + val[key] + ';'; // 如: width=20px;height:30px

                    }

                    b += '"';

                } else { // 若不是对象类型, 如: id: 'my-ul'

                    b += ' ' + ({cls: 'class', htmlFor: 'for'}[attr] || attr) + '="' + val + '"'; // class,for对象处理

                }

            }

        }

        if(emptyTags.test(o.tag)){ // 根据xhtml规定,忽略单标签,如: <hr />, <br />等

            b += '/>';

        } else {

            b += '>'; // 如: <div sytle="width=20px;height:30px">

            if(cn = o.children){

                b += createHtml(cn); // 如: <li id="item0">List Item 0</li><li id="item1">List Item 1</li>

            }

            b += '</' + o.tag + '>'; // 如: </div>

        }

    }

    return b; // 如: <ol style="width:20px;height:80px;"><li id="item0"></li></ol>

/**

 * 向DOM中插入一个HTML片段

 * @param where 插入的html与el的位置关系--- beforeBegin, afterBegin, beforeEnd, afterEnd.

 * @param el 内容元素

 * @param html HTML片段

 */

insertHtml: function(where, el, html){

    // innerHTML是只读的:col、 colgroup、frameset、html、 head、style、table、tbody、 tfoot、 thead、    var hash = {},

        hashVal,

        rs,

        range,

        setStart,

        frag,

        rangeEl;

    where = where.toLowerCase();

    hash[beforebegin] = ['beforeBegin', 'previousSibling'];

    hash[afterend] = ['afterEnd', 'nextSibling'];

    // 为了使后面的代码更易实现,这地方成两部分实现,

    // 1. 在当前节点的外边插入,就是if外边

    // 2. 在当前节点的里边插入,在if里边做判断

    if(el.insertAdjacentHTML){ // ie

        // 对ie的table进行单独处理

        if(tableRe.test(el.tagName) && (rs = insertIntoTable(el.tagName.toLowerCase(), where, el, html))){

            return rs;

        }

        hash[afterbegin] = ['AfterBegin', 'firstChild'];

        hash[beforeend] = ['BeforeEnd', 'lastChild'];

        if((hashVal = hash[where])){

            el.insertAdjacentHTML(hashVal[0], html);

            return el[hashVal[1]];

        }

    } else { // 旧版 firefox, firefox 11 支持 insertAdjacentHTML

        range = el.ownerDocument.createRange();

        setStart = 'setStart' + (endRe.test(where) ? 'After' : 'Before');

        if(hash[where]){

            // setStartAfter() 把该范围的开始点设置为紧邻指定节点的节点之后

            // setStartBefore() 把该范围的开始点设置为紧邻指定节点之前

            el.parentNode.insertBefore(frag, (beforebegin == where ? el : el.nextSibling));

            return el[(beforebegin == where ? 'previous' : 'next') + 'Sibling'];

        } else {

            rangeEl = (afterbegin == where ? 'first' : 'last') + 'Child';

            if(el.firstChild){

                range[setStart](el[rangeEl]);

                frag = range.createContextualFragment(html);

                if(afterbegin == where){

                    el.insertBefore(frag, el.firstChild);

                } else {

                    el.appendChild(frag);

                }

            } else {

                el.innerHTML = html;

            }

            return el[rangeEl];

        }

    }

    throw '非法插入点 -> "' + where + '"';

}