所在位置:杂记 >> javascript >> QWrap.tmpl 方法
QWrap.tmpl 方法
发表于 四年前(2014-8-27 12:14:52) | 阅读 (3455) | 评论 (1)
//tmpl by QW
    var tmpl = (function() {
        var tmplFuns={},
            sArrName = "sArrCMX",
            bsLeft = sArrName + '.push(',
            sLeft = bsLeft+'"',
            sRight = '");',
            tags = {
                '=': {
                    tagG: '=',
                    isBgn: 1,
                    isEnd: 1,
                    sBgn: '",encode4HtmlValue(',
                    sEnd: '),"'
                },
                //任意js语句, 里面如果需要输出到模板,用print("aaa");
                'js': {
                    tagG: 'js',
                    isBgn: 1,
                    isEnd: 1,
                    sBgn: sRight,
                    sEnd: ';' + sLeft
                },
                //if语句,写法为{if($a>1)},需要自带括号
                'if': {
                    tagG: 'if',
                    isBgn: 1,
                    rlt: 1,
                    sBgn: sRight+'if',
                    sEnd: '{' + sLeft
                },
                //elseif语句,写法为{elseif($a>1)},需要自带括号
                'elseif': {
                    tagG: 'if',
                    cond: 1,
                    rlt: 1,
                    sBgn: sRight+'} else if',
                    sEnd: '{' + sLeft
                },
                //else语句,写法为{else}
                'else': {
                    tagG: 'if',
                    cond: 1,
                    rlt: 2,
                    sEnd: sRight+'}else{' + sLeft
                },
                //endif语句,写法为{/if}
                '/if': {
                    tagG: 'if',
                    isEnd: 1,
                    sEnd: sRight+'}' + sLeft
                },
                //for语句,写法为{for(var i=0;i<1;i++)},需要自带括号
                'for': {
                    tagG: 'for',
                    isBgn: 1,
                    rlt: 1,
                    sBgn: sRight+'for',
                    sEnd: '{' + sLeft
                },
                //endfor语句,写法为{/for}
                '/for': {
                    tagG: 'for',
                    isEnd: 1,
                    sEnd: sRight+'}' + sLeft
                },
                //while语句,写法为{while(i-->0)},需要自带括号
                'while': {
                    tagG: 'while',
                    isBgn: 1,
                    rlt: 1,
                    sBgn: sRight+'while',
                    sEnd: '{' + sLeft
                },
                //endwhile语句, 写法为{/while}
                '/while': {
                    tagG: 'while',
                    isEnd: 1,
                    sEnd: sRight+'}' + sLeft
                }
            };
        return function(sTmpl, opts) {
            var fun  = tmplFuns[sTmpl];
            if (!fun) {
                var N = -1,
                    NStat = [], //语句堆栈;
                    ss2 = [
                        [/\\n/g, '\n'],
                        [/\\r/g, '\r'],
                        [/\\\x22/g, '"'],
                        [/\\\\/g, '\\'],
                        [/\$(\w+)/g, 'opts["$1"]'],
                        [/print\(/g, /**/ bsLeft]
                    ],
                    ss = [
                        [/\{strip\}([\s\S]*?)\{\/strip\}/g, function(a, b) {
                            return b.replace(/[\r\n]\s*\}/g, " }").replace(/[\r\n]\s*/g, "");
                        }],
                        [/\\/g, '\\\\'],
                        [/\x22/g, '\\"'],
                        [/\r/g, '\\r'],
                        [/\n/g, '\\n'], //为js作转码.
                        [
                            /\{[^\s][\s\S]*?\S\}/g, //js里使用{}时,{后要加空格。
                            function(a) {
                                a = a.substr(1, a.length - 2);
                                for (var i = 0; i < ss2.length; i++) {a = a.replace(ss2[i][0], ss2[i][1]); }
                                var tagName = a;
                                if (/^(=|.\w+)/.test(tagName)) {tagName = RegExp.$1; }
                                var tag = tags[tagName];
                                if (tag) {
                                    if (tag.isBgn) {
                                        var stat = NStat[++N] = {
                                            tagG: tag.tagG,
                                            rlt: tag.rlt
                                        };
                                    }
                                    if (tag.isEnd) {
                                        if (N < 0) {throw new Error("Unexpected Tag: " + a); }
                                        stat = NStat[N--];
                                        if (stat.tagG != tag.tagG) {throw new Error("Unmatch Tags: " + stat.tagG + "--" + tagName); }
                                    } else if (!tag.isBgn) {
                                        if (N < 0) {throw new Error("Unexpected Tag:" + a); }
                                        stat = NStat[N];
                                        if (stat.tagG != tag.tagG) {throw new Error("Unmatch Tags: " + stat.tagG + "--" + tagName); }
                                        if (tag.cond && !(tag.cond & stat.rlt)) {throw new Error("Unexpected Tag: " + tagName); }
                                        stat.rlt = tag.rlt;
                                    }
                                    return (tag.sBgn || '') + a.substr(tagName.length) + (tag.sEnd || '');
                                } else {
                                    return '",(' + a + '),"';
                                }
                            }
                        ]
                    ];
                for (var i = 0; i < ss.length; i++) {
                    sTmpl = sTmpl.replace(ss[i][0], ss[i][1]);
                }
                if (N >= 0) {throw new Error("Lose end Tag: " + NStat[N].tagG); }
                sTmpl = sTmpl.replace(/##7b/g,'{').replace(/##7d/g,'}').replace(/##23/g,'#'); //替换特殊符号{}#
                sTmpl = 'var ' + sArrName + '=[];' + sLeft + sTmpl + sRight+' return ' + sArrName + '.join("");';
                //alert('转化结果\n'+sTmpl);
                var tmplFun = new Function('opts','encode4HtmlValue','encode4Html', sTmpl);
                tmplFuns[sTmpl] = fun = function(opts){
                    return tmplFun(opts,encode4HtmlValue,encode4Html);
                };
                fun.toString = function(){ 
                    return 'function(opts){\n    '+sTmpl+'\n}';
                };
            }
            if (arguments.length > 1) {return fun(opts); }
            return fun;
        };
    })();

    //转码HTMLEncode
    function encode4Html(s) {
        var el = document.createElement('pre'); //这里要用pre,用div有时会丢失换行,例如:'a\r\n\r\nb'
        el.appendChild(document.createTextNode(s));
        return el.innerHTML;
    }
    //转码HTMLEncodeVal
    function encode4HtmlValue(s) {
        return encode4Html(s).replace(/\x22/g, """).replace(/\x27/g, "'");
    }
杂记评论(1):
回复 1楼 xxx 来自  发表于 两年前(2016-3-15 19:13:55)
支持 {=} 防XSS ... http://s4.qhimg.com/static/7ded7fa18df56124.js?$.tmpl
共1条评论  第1页/共1页  首页 上页 下页 尾页
称谓(必填):  网站(选填):
上一篇:通过等分圆周算取圆周上的热点区域  下一篇:使用nodejs批量抓取文章保存为txt文档     <<返回杂记列表