Permalink
Browse files

added juicer.

  • Loading branch information...
1 parent 5657679 commit 527f9beb752852f9f8520d68fe97479532060424 @PaulGuo PaulGuo committed May 3, 2012
Showing with 381 additions and 0 deletions.
  1. +12 −0 gallery/juicer/1.0/build.xml
  2. +146 −0 gallery/juicer/1.0/demo.html
  3. +5 −0 gallery/juicer/1.0/index.js
  4. +218 −0 gallery/juicer/1.0/juicer.js
@@ -0,0 +1,12 @@
+<project name="pagination.build" default="build" basedir=".">
+ <description>Component Build File</description>
+
+ <property name="src.dir" value="."/>
+ <property name="component.name" value="juicer"/>
+ <property name="component.version" value="1.0"/>
+
+ <import file="../../common.xml"/>
+
+ <target name="build" depends="common.build">
+ </target>
+</project>
@@ -0,0 +1,146 @@
+<!doctype html>
+<html>
+<head>
+ <meta charset="utf-8"/>
+ <title>KISSY gallery - Juicer</title>
+ <link rel="shortcut icon" href="../../../../kissy-dpl/base/assets/favicon.ico"/>
+ <link rel="stylesheet" href="../../../../kissy-dpl/base/assets/reset.css"/>
+ <link rel="stylesheet" href="../../../../kissy-dpl/base/assets/kissy-docs.css"/>
+ <style>
+ h4 {
+ font-size: 14px;
+ font-weight: bold;
+ margin-bottom: 10px;
+ }
+ textarea {
+ border: 1px solid #BBBBBB;
+ font-family: Inconsolata,monaco,courier;
+ font-size: 12px;
+ height: 280px;
+ margin-bottom: 20px;
+ padding: 5px;
+ width: 800px;
+ }
+ </style>
+ <script src="http://docs.kissyui.com/kissy/build/kissy.js"></script>
+ <script>
+ KISSY.config({
+ packages:[
+ {
+ name:"gallery",
+ tag:"20120503",
+ path:"../../../", // cdn上适当修改对应路径
+ charset:"utf-8"
+ }
+ ]
+ });
+ </script>
+ <script src="../../../../kissy-dpl/base/assets/kissy-docs.js"></script>
+
+</head>
+<body>
+ <div id="header">
+ <h1 class="logo"><a alt="KISSY" href="http://kissyui.com/"><img src="../../../../kissy-dpl/base/assets/logo.png"/></a></h1>
+ <div class="sub-title">Gallery</div>
+ <ul class="navigation">
+ <li><a href="http://blog.kissyui.com/">博客</a></li>
+ <li><a href="http://github.com/kissyteam">源码</a></li>
+ </ul>
+
+ </div>
+ <div id="content">
+ <div class="s-crumbs">
+ <span>当前位置:</span>
+ <a href="http://kissyui.com/">KISSY</a>
+ <a href="../../../index.html">Gallery</a>
+ <span>Juicer</span>
+ </div>
+ <pre class="s-section">
+author: liuhuo.gk@taobao.com
+description:juicer is a lightweight javascript template engine, it’s fast and easy to use. it’s syntax like smarty, it can running either at browser or node.js
+docs : <a href="http://juicer.name/docs/docs.html">doc</a>
+source code: <a href="juicer.js">juicer.js</a></pre>
+
+ <h3 class="s-title">Demo - 使用 Juicer 渲染模版</h3>
+ <div class="s-section">
+ <div class="s-demo">
+ <div>
+
+<h4>Juicer 模版:</h4>
+
+<textarea id="template">
+<h1>${header}</h1>
+{@if bug}
+{@/if}
+{@each items as it}
+ {@if it.first}
+ <li><strong>${it.name}</strong></li>
+ {@/if}
+ {@if it.link}
+ <li><a href="${url}">${name}</a></li>
+ {@/if}
+{@/each}
+{@if empty}
+ <p>The list is empty.</p>
+{@/if}
+</textarea>
+
+<h4>JSON 数据:</h4>
+
+<textarea id="data">
+{
+ "header": "Colors",
+ "items": [
+ {"name": "red", "first": true, "url": "#Red"},
+ {"name": "green", "link": true, "url": "#Green"},
+ {"name": "blue", "link": true, "url": "#Blue"}
+ ],
+ "empty": false
+}
+</textarea>
+
+<h4>渲染结果:</h4>
+<pre id="juicer"></pre>
+
+ </div>
+
+ <script>
+ KISSY.use('gallery/juicer/1.0/',function(S, juicer){
+ var template = S.one('#template').html(),
+ data = S.JSON.parse(S.one('#data').html()),
+ html = juicer(template, data);
+
+ S.one('#juicer').html(html.replace(/^\s*/mg, ''));
+ });
+ </script>
+ </div>
+ <a class="s-view-code" href="demo.html#">显示源码</a><!--点击该链接自动帮你显示s=demo里的内容,如不需要,去除链接即可-->
+ </div>
+
+ <h3 class="s-title">API</h3>
+ <div class="s-section">
+ <h4 class="s-api-title">方法</h4>
+ <div class="s-api-method"> juicer(template,data)</div>
+ <h4 class="s-api-title">参数</h4>
+ <div class="s-api-params">
+ <ul class="s-list">
+ <li>{String} [ <em>template</em> ] 模版字符串</li>
+ <li>{JSON} [ <em>data</em> ] 模版数据</li>
+ </ul>
+ </div>
+ <h4 class="s-api-title">返回</h4>
+ <div class="s-api-return">{String} 渲染后的字符串</div>
+ </div>
+
+ <h3 class="s-title">Note</h3>
+ <div class="s-section">
+ <ul class="s-list">
+ <li>http://juicer.name/</li>
+ </ul>
+ </div>
+ </div>
+ <div id="footer">
+ &copy; Copyright 2010~2012, KISSY Team.
+ </div>
+</body>
+</html>
@@ -0,0 +1,5 @@
+KISSY.add("gallery/juicer/1.0/index",function(S, Juicer) {
+ return Juicer;
+}, {
+ requires:["./juicer"]
+});
@@ -0,0 +1,218 @@
+/*
+ @author: guokai
+ @email/gtalk: badkaikai@gmail.com
+ @blog/website: http://benben.cc
+ @license: apache license,version 2.0
+ @version: 0.3.0-dev
+*/
+
+KISSY.add('gallery/juicer/1.0/juicer',function(S) {
+ var juicer=function() {
+ var args=[].slice.call(arguments);
+ args.push(juicer.options);
+ if(arguments.length==1) return juicer.compile.apply(juicer,args);
+ if(arguments.length>=2) return juicer.to_html.apply(juicer,args);
+ };
+
+ window.__escapehtml={
+ __escapehash:{
+ '<':'&lt;',
+ '>':'&gt;',
+ '"':'&quot;',
+ '&':'&amp;'
+ },
+ __escapereplace:function(k) {
+ return __escapehtml.__escapehash[k];
+ },
+ __escape:function(str) {
+ return typeof(str)!=='string'?str:str.replace(/[&<>"]/igm,__escapehtml.__escapereplace);
+ },
+ __detection:function(data) {
+ return typeof(data)==='undefined'?'':data;
+ }
+ };
+
+ juicer.__cache={};
+ juicer.version='0.3.0-dev';
+
+ juicer.settings = {
+ forstart:/{@each\s*([\w\.]*?)\s*as\s*(\w*?)(,\w*?)?}/igm,
+ forend:/{@\/each}/igm,
+ ifstart:/{@if\s*([^}]*?)}/igm,
+ ifend:/{@\/if}/igm,
+ elsestart:/{@else}/igm,
+ interpolate:/\${([\s\S]+?)}/igm,
+ noneencode:/\$\${([\s\S]+?)}/igm,
+ inlinecomment:/{#[^}]*?}/igm,
+ rangestart:/{@each\s*(\w*?)\s*in\s*range\((\d+?),(\d+?)\)}/igm
+ };
+
+ juicer.options={
+ cache:true,
+ strip:true,
+ errorhandling:true
+ };
+
+ juicer.set=function(conf,value) {
+ this.options[conf]=value;
+ };
+
+ juicer.template=function() {
+ var __this=this;
+
+ this.__interpolate=function(varname,escape,options) {
+ var __define=varname.split('|'),fn='';
+ if(__define.length>1) {
+ varname=__define.shift();
+ fn=__define.shift();
+ }
+ return '<%= '+
+ (escape?'__escapehtml.__escape':'')+
+ '('+
+ (!options || options.detection!==false?'__escapehtml.__detection':'')+
+ '('+
+ fn+
+ '('+
+ varname+
+ ')'+
+ ')'+
+ ')'+
+ ' %>';
+ };
+
+ this.__shell=function(tpl,options) {
+ var iterate_count=0;
+ tpl=tpl
+ //for expression
+ .replace(juicer.settings.forstart,function($,varname,alias,key) {
+ var alias=alias||'value',key=key && key.substr(1);
+ var iterate_var='i'+iterate_count++;
+ return '<% for(var '+iterate_var+'=0,l='+varname+'.length;'+iterate_var+'<l;'+iterate_var+'++) {'+
+ 'var '+alias+'='+varname+'['+iterate_var+'];'+
+ (key?('var '+key+'='+iterate_var+';'):'')+
+ ' %>';
+ })
+ .replace(juicer.settings.forend,'<% } %>')
+ //if expression
+ .replace(juicer.settings.ifstart,function($,condition) {
+ return '<% if('+condition+') { %>';
+ })
+ .replace(juicer.settings.ifend,'<% } %>')
+ //else expression
+ .replace(juicer.settings.elsestart,function($) {
+ return '<% } else { %>';
+ })
+ //interpolate without escape
+ .replace(juicer.settings.noneencode,function($,varname) {
+ return __this.__interpolate(varname,false,options);
+ })
+ //interpolate with escape
+ .replace(juicer.settings.interpolate,function($,varname) {
+ return __this.__interpolate(varname,true,options);
+ })
+ //clean up comments
+ .replace(juicer.settings.inlinecomment,'')
+ //range expression
+ .replace(juicer.settings.rangestart,function($,varname,start,end) {
+ var iterate_var='j'+iterate_count++;
+ return '<% for(var '+iterate_var+'=0;'+iterate_var+'<'+(end-start)+';'+iterate_var+'++) {'+
+ 'var '+varname+'='+iterate_var+';'+
+ ' %>';
+ });
+
+ //exception handling
+ if(!options || options.errorhandling!==false) {
+ tpl='<% try { %>'+tpl+'<% } catch(e) {console && console.warn("Juicer Render Exception: "+e.message);} %>';
+ }
+
+ return tpl;
+ };
+
+ this.__pure=function(tpl,options) {
+ return this.__convert(tpl,!options || options.strip);;
+ };
+
+ this.__lexical=function(tpl) {
+ var buf=[];
+ var pre='';
+ var indexOf=function(arr,value) {
+ for(var i=0;i<arr.length;i++) {
+ if(arr[i]==value) return i;
+ }
+ return -1;
+ };
+ var memo=function($,variable) {
+ variable=variable.match(/\w+/igm)[0];
+ (buf.indexOf?buf.indexOf(variable):indexOf(buf,variable))===-1 && buf.push(variable);//fuck ie
+ };
+
+ tpl.replace(juicer.settings.forstart,memo).
+ replace(juicer.settings.interpolate,memo).
+ replace(juicer.settings.ifstart,memo);
+
+ for(var i=0;i<buf.length;i++) {
+ pre+='var '+buf[i]+'=data.'+buf[i]+';';
+ }
+ return '<% '+pre+' %>';
+ };
+
+ this.__convert=function(tpl,strip) {
+ var buf=[].join('');
+ buf+="var data=data||{};";
+ buf+="var out='';out+='";
+ if(strip!==false) {
+ buf+=tpl
+ .replace(/\\/g,"\\\\")
+ .replace(/[\r\t\n]/g," ")
+ .replace(/'(?=[^%]*%>)/g,"\t")
+ .split("'").join("\\'")
+ .split("\t").join("'")
+ .replace(/<%=(.+?)%>/g,"';out+=$1;out+='")
+ .split("<%").join("';")
+ .split("%>").join("out+='")+
+ "';return out;";
+ } else {
+ buf+=tpl
+ .replace(/\\/g,"\\\\")
+ .replace(/[\r]/g,"\\r")
+ .replace(/[\t]/g,"\\t")
+ .replace(/[\n]/g,"\\n")
+ .replace(/'(?=[^%]*%>)/g,"\t")
+ .split("'").join("\\'")
+ .split("\t").join("'")
+ .replace(/<%=(.+?)%>/g,"';out+=$1;out+='")
+ .split("<%").join("';")
+ .split("%>").join("out+='")+
+ "';return out.replace(/[\\r\\n]\\t+[\\r\\n]/g,'\\r\\n');";
+ }
+ return buf;
+ };
+
+ this.parse=function(tpl,options) {
+ if(!options || options.loose!==false) tpl=this.__lexical(tpl)+tpl;
+ tpl=this.__shell(tpl,options);
+ tpl=this.__pure(tpl,options);
+ tpl='"use strict";'+tpl; //use strict mode
+
+ this.render=new Function('data',tpl);
+ return this;
+ };
+ };
+
+ juicer.compile=function(tpl,options) {
+ try {
+ var engine=this.__cache[tpl]?this.__cache[tpl]:new this.template().parse(tpl,options);
+ if(!options || options.cache!==false) this.__cache[tpl]=engine;
+ return engine;
+ } catch(e) {
+ console && console.warn('Juicer Compile Exception: '+e.message);
+ return {render:function() {}};
+ }
+ };
+
+ juicer.to_html=function(tpl,data,options) {
+ return this.compile(tpl,options).render(data);
+ };
+
+ return juicer;
+});

0 comments on commit 527f9be

Please sign in to comment.