论坛首页 Web前端技术论坛

jCT 第三版预览,已废弃,留作历史

浏览 1605 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
作者 正文
   发表时间:2008-06-26  

重新进行了设计,抛弃了所有重新定义javascript固有语法的方法,这样也就是无招胜有招 了,

而且可方便自定义标记 ,没有精力写注解和用法了.直接贴源代码(初稿)吧:(请在FF下测试,还没有调整IE的兼容性)

细心的朋友应该可以看出来,不同标记之间是可以转换的.

/**
 * javascript Common Templates(jCT) 3(第3版)
 * http://code.google.com/p/jsct/
 *
 * licensed under the MIT license.
 *	http://www.opensource.org/licenses/mit-license.php
 *
 * Author achun (achun.shx at gmail.com)
 * Create Date: 2008-6-23
 * Last Date: 2008-6-26
 * Revision:3.8.6.26
 * 预定义变量:
 		D............用于生成函数的输入参数,表示提供给模板的数据.可以通过设置Main改变此名称
 * 保留属性:有些属性的保留纯粹是为了方便调试
		CTA..........SRC的模板数组形式表示
		CTD..........用于保留执行(Exec)模板时候传入的参数
		CTV..........在执行(Exec)模板过程当中生成结果的数组形式
		Fn...........继承自jCT的几个属性和方法
		MAIN.........Build模板的时候生成的主体过程数组形式
		PATH.........保留模板的URL路径,由调用模板的函数提供,保留这个的目的是考虑到这个参数可能会有很多的用途。
		SRC..........模板原文本,由调用模板的函数提供
		TAG..........模板标签风格,来自Fn的引用
		ERROR........Build异常时的错误信息.
 * 保留方法:
		Build........构建模板的Exec方法,参数对应属性的TAG
		Clean........清理模板,参数对应属性的TAG
		Exec.........执行模板
 * 保留字串:
		...          再使用Main时用于替换主体过程的占位符
 * 调用:
		var jct = jCT(txt,path,tag);
		txt..........对应属性SRC
		path.........对应属性PATH
		tag..........对应属性TAG
 */
function jCT3(txt,path,by){
	var self=function(){
		return arguments.callee.Exec.apply(arguments.callee,arguments);
	};
	by=by||'comment';//默认的标记风格,到底是用script还是comment呢?
	self.Fn={};
	for (var prop in jCT3.Fn)
		self.Fn[prop] = jCT3.Fn[prop];
	self.SRC=txt;
	self.PATH=path;
	self.TAG=self.Fn[by];
	self.CTA=[];
	self.CTV=[];
	self.CTD={};
	self.Clean=function(){
		this.Fn.src=this.SRC;
		this.Fn.path=this.PATH;
		this.Fn.clean(this.TAG.clean);
		return this.Fn.src;
	};
	self.Build=function(){
		this.Clean();
		var fn=this.Fn;
		this.MAIN=[];
		fn.path=this.PATH;
		var ext=fn.parse(this,this.MAIN);
		var jctbody=this.MAIN.join('\n');
		if (ext.run) window.eval(ext.run);
		if (ext.main) {
			var func=ext.main.replace('{...}','\n{this.CTV=[];'+jctbody+'\n}\n');
		}else{
			var func='function(D){if(!D) D={};this.CTD=D;with(D){this.CTV=[];'+jctbody+'}\nreturn this.CTV.join("");}';
		}
		try{
			this.Exec = eval('false||'+func);
		}catch (ex){
			this.Exec = function(){return 'jCT Parse Error';};
			this.ERROR={message:ex.message + '\n'+ (ex.lineNumber || ex.number),src:func};
		}
		return this;
	};
	self.Build();
	return self;
}
jCT3.Fn={
	clean:function(tn){
		var a=[];
		var p=[0,0,0,0,0];
		var e=this.src.length;
		while (this.slice(tn,p[4],p,e))
			a.push(this.src.slice(p[0],p[1]));
		a.push(this.src.slice(p[4]));
		this.src = a.join('');
	},
	parse:function(self,jctbody){
		var tag = self.TAG;
		var cta = self.CTA;
		var p=[0,0,0,0,0];
		var e=this.src.length;
		var main='';
		var run='';
		while (this.slice(tag.tag,p[4],p,e)){//语法分2段
			var p1=[0,0,0,0,p[0]];
			while (this.slice(tag.exp,p1[4],p1,p[1])){//第1段取值表达式
				jctbody.push('this.CTV.push(this.CTA['+cta.length+']);');
				cta.push(this.src.slice(p1[0],p1[1]));
				jctbody.push('this.CTV.push('+this.src.slice(p1[2],p1[3])+');');
			}
			jctbody.push('this.CTV.push(this.CTA['+cta.length+']);');
			cta.push(this.src.slice(p1[4],p[1]));
			//处理第2段
			if (this.slice(tag.ext,p[2],p1,p[3])){///*+*/处理
				jctbody.push('this.CTV.push('+this.src.slice(p1[0],p1[1])+');');
				var str=this.src.slice(p1[2],p1[3]);
				var tmp=str.indexOf(' ');
				var par='',sta='';
				if (tmp>0){
					par=str.slice(tmp+1);
					sta=sta.slice(0,tmp);
				}else
					sta=str;
				var foo=this.src.slice(p1[4],p[3]);
				switch(sta){
					case 'Main':main=foo;break;
					case 'Run':run+=foo+"\n";break;
					case 'Child':
						var p2=[];
						var child=tag.tag.begin+'/*-'+str+'*/'+tag.tag.end;
						tmp = this.src.indexOf(child,p[4]);
						if (tmp>0){
							self[par]=jCT3(txt.slice(p[4],tmp),this.path);
							p[4] = tmp + child.length;							
						}					
						break;
				}
			}else{
				jctbody.push(this.src.slice(p[2],p[3]));
			}
		}
		var p1=[0,0,0,0,p[4]];
		while (this.slice(tag.exp,p[4],p1,e)){//第1段取值表达式
			jctbody.push('this.CTV.push(this.CTA['+cta.length+']);');
			cta.push(this.src.slice(p1[0],p1[1]));

			jctbody.push('this.CTV.push('+this.src.slice(p1[2],p1[3])+');');
		}
		jctbody.push('this.CTV.push(this.CTA['+cta.length+']);');
		cta.push(this.src.slice(p1[4]));
		return {main:main,run:run};
	},
	slice:function(tn,b1,p,max){//把string第2段分成2段
		var begin=tn.begin;
		var end=tn.end;
		var e1,b2,e2;
		e1=this.src.indexOf(begin,b1);
		if (e1<0 || e1>=max) return false;
		b2=e1+begin.length;
		if (b2<0 || b2>=max) return false;
		e2=this.src.indexOf(end,b2);
		if (e2<0 || e2>=max) return false;
		p[0]=b1;p[1]=e1;
		p[2]=b2;p[3]=e2;
		p[4]=e2+end.length;
		return true;
	},
       //下面就是几个自定义标记的配置了
	comment:{//注释标记风格
		tag:{begin:'<!---',end:'-->'},
		exp:{begin:'+-',end:'-+'},
		ext:{begin:'/*+',end:'*/'},
		clean:{begin:'<!--clean-->',end:'<!--clean -->'}
	},
	script:{//脚本标记风格
		tag:{begin:'<script type="jct">',end:'</script>'},
		exp:{begin:'+-',end:'-+'},
		ext:{begin:'/*+',end:'*/'},
		clean:{begin:'<script type="jct" />',end:'<script type="jct" />'}
	},
	code:{//code标记风格
		tag:{begin:'<code lang="jct">',end:'</code>'},
		exp:{begin:'+-',end:'-+'},
		ext:{begin:'/*+',end:'*/'},
		clean:{begin:'<code lang="jct" />',end:'<code lang="jct" />'}
	}
};
 
论坛首页 Web前端技术版

跳转论坛:
Global site tag (gtag.js) - Google Analytics