mirror of
				https://scm.univ-tours.fr/22107988t/rappaurio-sae501_502.git
				synced 2025-11-04 10:45:22 +01:00 
			
		
		
		
	
		
			
				
	
	
		
			482 lines
		
	
	
		
			23 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			482 lines
		
	
	
		
			23 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
 | 
						||
/*
 | 
						||
 | 
						||
********	class template		********
 | 
						||
 | 
						||
用
 | 
						||
=function(){}()
 | 
						||
似乎亦可,見 SWFObject 2.2
 | 
						||
*/
 | 
						||
 | 
						||
var ClassT={};	//	class template set	讓 addCode 也可以讀通
 | 
						||
 | 
						||
 | 
						||
 | 
						||
//	===================================================
 | 
						||
/*
 | 
						||
	** class description: class template (simple version)
 | 
						||
 | 
						||
_=this
 | 
						||
 | 
						||
TODO:
 | 
						||
 | 
						||
 | 
						||
HISTORY:
 | 
						||
2008/7/21 16:12:32	create
 | 
						||
*/
 | 
						||
var
 | 
						||
classT=
 | 
						||
 | 
						||
(ClassT.classT=function(initF){
 | 
						||
 | 
						||
var
 | 
						||
 | 
						||
//	class private	-----------------------------------
 | 
						||
 | 
						||
 | 
						||
//	instance constructor	---------------------------
 | 
						||
instanceL=[],
 | 
						||
initI=function(a){
 | 
						||
 var _t=this,_p=pv(_t);
 | 
						||
 instanceL.push(_t);	//	for destructor
 | 
						||
 //_p.vars=a
 | 
						||
 | 
						||
 //	initial instance object
 | 
						||
},_=function(){initI.apply(this,arguments);initF&&initF.apply(this,arguments);},
 | 
						||
 | 
						||
 | 
						||
//	(instance private handle)	不要 instance private 的把這函數刪掉即可。
 | 
						||
_p='_'+(''+Math.random()).replace(/\./,''),
 | 
						||
//	get private variables (instance[,destroy]), init private variables (instance[,access function list[, instance destructor]])
 | 
						||
pv=function(i,d,k){var V,K=_p('k');return arguments.callee.caller===_p('i')?(V=_p(i[K]=_p()),V.O=i,V.L={}):(K in i)&&(V=_p(i[K]))&&i===V.O?d?(_p(i[K],1),delete i[K]):V.L:{};};
 | 
						||
 | 
						||
//	class destructor	---------------------------
 | 
						||
/*
 | 
						||
please call at last (e.g., window.unload)
 | 
						||
 | 
						||
usage:
 | 
						||
classT=classT.destroy();
 | 
						||
or if you has something more to do:
 | 
						||
classT.destroy()&&classT=null;
 | 
						||
*/
 | 
						||
 | 
						||
_.destroy=function(){for(var i=0,l=instanceL.length;i<l;i++)instanceL[i].destroy();_p();};
 | 
						||
 | 
						||
//	(instance private handle, continue)
 | 
						||
eval('_p=(function(){var '+_p+'={a:pv,d:_.destroy,c:0,k:"+pv+'+Math.random()+'",i:initI};return function(i,d){var f=arguments.callee.caller;if(f==='+_p+'.a){if(!d)return i in '+_p+'?'+_p+'[i]:('+_p+'[i='+_p+'.c++]={},i);'+_p+'[i]={};}if(f==='+_p+'.d)'+_p+'={};}})();');
 | 
						||
_p.toString=function(){return'';};
 | 
						||
 | 
						||
 | 
						||
//	class public interface	---------------------------
 | 
						||
 | 
						||
//	func
 | 
						||
_.func=function(){
 | 
						||
 var _t=this;
 | 
						||
 
 | 
						||
};
 | 
						||
 | 
						||
//	class constructor	---------------------------
 | 
						||
 | 
						||
// do something others
 | 
						||
 | 
						||
 | 
						||
_.prototype={
 | 
						||
//	應該盡量把東西放在 class,instance 少一點…?
 | 
						||
//	** important ** 這邊不能作 object 之 initialization,否則因為 object 只會 copy reference,因此 new 時東西會一樣。initialization 得在 _() 中作!
 | 
						||
 | 
						||
//	instance public interface	-------------------
 | 
						||
 | 
						||
setV:function(a){
 | 
						||
 var _t=this,_p=pv(_t);
 | 
						||
 //_p.vars=a
 | 
						||
},
 | 
						||
 | 
						||
 | 
						||
//	instance destructor	---------------------------
 | 
						||
/*
 | 
						||
usage:
 | 
						||
instance=instance.destroy();
 | 
						||
or if you has something more to do:
 | 
						||
instance.destroy()&&instance=null;
 | 
						||
*/
 | 
						||
destroy:function(){pv(this,1);}
 | 
						||
};	//	_.prototype=
 | 
						||
 | 
						||
return _;
 | 
						||
})();	//	function(initF){
 | 
						||
 | 
						||
//	===================================================
 | 
						||
 | 
						||
 | 
						||
 | 
						||
 | 
						||
 | 
						||
 | 
						||
//	解析
 | 
						||
 | 
						||
 | 
						||
 | 
						||
//	===================================================
 | 
						||
 | 
						||
/*
 | 
						||
	** class description: class template
 | 
						||
 | 
						||
_=this
 | 
						||
 | 
						||
TODO:
 | 
						||
.constructor 設定
 | 
						||
inherits:
 | 
						||
	http://www.cnblogs.com/birdshome/archive/2005/01/28/95933.html
 | 
						||
	http://www.blogjava.net/zkjbeyond/archive/2006/05/08/45108.html
 | 
						||
 | 
						||
 | 
						||
HISTORY:
 | 
						||
2008/7/21 16:12:32	create
 | 
						||
7/24 15:14:16	enhanced by set .toString. But.. If we use delete _p.toString, than we still can..
 | 
						||
		eval('a = pv',some_instance);
 | 
						||
		eval('var s=_p.toString;delete _p.toString;sl("** test1 _p: "+_p);_p.toString=s;sl("** test2 _p: "+_p);',a);
 | 
						||
7/26 11:38:6	className
 | 
						||
 | 
						||
TOTRY:
 | 
						||
直接對 eval 下手,使 delete 掉 eval 則 lost data
 | 
						||
*/
 | 
						||
var
 | 
						||
classT_debug=
 | 
						||
 | 
						||
//	若是不須讓 addCode 也可以讀通,不加 ClassT.~ 也沒關係。
 | 
						||
(ClassT.classT=function(initF){	//	initF: additional initialization function
 | 
						||
 | 
						||
var
 | 
						||
 | 
						||
//	class private	-----------------------------------
 | 
						||
className='',//classT
 | 
						||
 | 
						||
//	variables
 | 
						||
vars=7,
 | 
						||
//	function
 | 
						||
doLog=function(m){
 | 
						||
 var _t=_;
 | 
						||
 sl((className?className+': ':'>> ')+m);	//	this+': '
 | 
						||
},
 | 
						||
 | 
						||
 | 
						||
 | 
						||
//	instance constructor	---------------------------
 | 
						||
instanceL=[],	// 實例 list
 | 
						||
initI=function(a){
 | 
						||
 var _t=this,//	這裡面有用的是 this,不是 arguments.callee。
 | 
						||
	_p=pv(_t);//pv(_t,[func1,func2,..],_.destroy);	//	init private variables
 | 
						||
 instanceL.push(_t);	//	for destructor
 | 
						||
 | 
						||
 //	initial instance object
 | 
						||
 _t.property1=[];
 | 
						||
 | 
						||
 _t.testV=a;
 | 
						||
 doLog('class create: '+a);
 | 
						||
 | 
						||
 //return this;
 | 
						||
},
 | 
						||
 | 
						||
//	盡量減少 instance 體積…有用嗎?
 | 
						||
_=function(){
 | 
						||
	initI.apply(this,arguments);
 | 
						||
	initF&&initF.apply(this,arguments);
 | 
						||
},
 | 
						||
 | 
						||
 | 
						||
//	(instance private handle)	不要 instance private 的把這函數刪掉即可。
 | 
						||
/*
 | 
						||
更完整的防治:比對 arguments.callee.caller 的程式碼,確定登錄過才給予存取。
 | 
						||
…在 eval() 的第二 argument 下無用武之地。
 | 
						||
*/
 | 
						||
 | 
						||
_p='_'+(''+Math.random()).replace(/\./,''),
 | 
						||
 | 
						||
pv=function(i,d,k){	//	get private variables (instance[,destroy]), init private variables (instance[,access function list[, instance destructor]])
 | 
						||
 var	V,K=_p('k');
 | 
						||
/*	V: get variables
 | 
						||
 | 
						||
V.L	variables {}
 | 
						||
V.O	instance
 | 
						||
 | 
						||
for full version:
 | 
						||
V.F	可存取函數的程式碼 list {}
 | 
						||
V.D	instance destructor
 | 
						||
*/
 | 
						||
 | 
						||
//	simple version
 | 
						||
 if(0)return arguments.callee.caller===_p('i')?
 | 
						||
	(V=_p(i[K]=_p()),V.O=i,V.L={})
 | 
						||
	:(K in i)&&(V=_p(i[K]))&&i===V.O?
 | 
						||
		d?(_p(i[K],1),delete i[K]):V.L
 | 
						||
		:{};	//	竄改就會出 trouble
 | 
						||
 | 
						||
 | 
						||
//	full version
 | 
						||
 var c=arguments.callee.caller,j=0,l;
 | 
						||
 doLog('pv: '+(c===_p('i')?'init':d?'destory':'get variables')+' by '+c);
 | 
						||
 if(c===_p('i')){
 | 
						||
  V=_p(i[K]=_p());
 | 
						||
  V.O=i;
 | 
						||
  if(k)V.D=k;	//	instance destructor
 | 
						||
  //	登錄可存取函數的程式碼。更狠的:不用 {} 而用 d,確定是 *完全相同* 的 function。
 | 
						||
  if(Array.isArray(d))	//	[]: no access!!
 | 
						||
   for(k=V.F={},l=d.length;j<l;j++)
 | 
						||
    k[d[j]]=1;
 | 
						||
  return V.L={};
 | 
						||
 }
 | 
						||
 | 
						||
 //	預防竄改,找尋本來應該的 index。
 | 
						||
 if(!(K in i)||!(V=_p(i[K]))||i!==V.O)
 | 
						||
  for(k=_p('c');j<k;j++)
 | 
						||
   if(i===_p(j).O){
 | 
						||
    doLog('pv: correct index: '+i[K]+' to '+j);
 | 
						||
    i[K]=j;
 | 
						||
    break;
 | 
						||
   }
 | 
						||
 | 
						||
 if((K in i)&&(V=_p(i[K]))&&i===V.O)
 | 
						||
  if(d){
 | 
						||
   //	call from instance destructor
 | 
						||
   if(!V.D||c===V.D)_p(i[K],1),delete i[K];
 | 
						||
   //else throw new Error(3,'Error calling to destroy.');
 | 
						||
  }else if(!V.F||V.F[c]){
 | 
						||
   doLog('pv: get index '+i[K]+'.');
 | 
						||
   //if(!V.L)throw new Error(1,'Error to get variables! Maybe it was already destroyed?');//private variables
 | 
						||
   return V.L;
 | 
						||
  }
 | 
						||
 | 
						||
 return {};	//	throw new Error(1,'Illegal access!');
 | 
						||
};	//	of pv=function(
 | 
						||
 | 
						||
 | 
						||
//	(for inherits)
 | 
						||
/*
 | 
						||
不要 inherit 的把這段刪掉即可。
 | 
						||
usage:
 | 
						||
//	模擬 inherits
 | 
						||
newClass=oldClass.clone();
 | 
						||
//	prevent re-use. 防止再造 
 | 
						||
delete oldClass.clone;
 | 
						||
*/
 | 
						||
(_.clone=arguments.callee).toString=function(){return '[class_template]';};
 | 
						||
 | 
						||
 | 
						||
//	class destructor	---------------------------
 | 
						||
/*
 | 
						||
please call at last (e.g., window.unload)
 | 
						||
 | 
						||
usage:
 | 
						||
classT=classT.destroy();
 | 
						||
or if you has something more to do:
 | 
						||
classT.destroy()&&classT=null;
 | 
						||
*/
 | 
						||
 | 
						||
_.destroy=function(){
 | 
						||
 doLog('destroy: Destroy class.');
 | 
						||
 for(var i=0,l=instanceL.length;i<l;i++)
 | 
						||
  instanceL[i].destroy();
 | 
						||
 _p();
 | 
						||
};
 | 
						||
 | 
						||
 | 
						||
//	class public interface	---------------------------
 | 
						||
 | 
						||
//	variables
 | 
						||
_.variables={};
 | 
						||
//	func
 | 
						||
_.func=function(){
 | 
						||
 var _t=this;
 | 
						||
 
 | 
						||
};
 | 
						||
 | 
						||
 | 
						||
//	(instance private handle, continue)
 | 
						||
//	.a: accessable caller function, .d: class destructor, c:count, .k: private variables keyword, .i: init function, m: accessable class members
 | 
						||
//	destructor: (index,1)	Warning: 某些環境中 Array 可能無法用 delete?
 | 
						||
eval('_p=(function(){var '+_p+'={a:pv,d:_.destroy,c:0,k:"+pv+'+Math.random()+'",i:initI,m:{_:{}}}; (function(m,i){for(i=0;i<m.length;i++)if(m[i])'+_p+'.m[m[i]]=1;})(['
 | 
						||
	//'func1,func2'	//	在這裡填上需要 call 隱藏數值的 class private function。若無,可考慮合併到 _.destroy 前。
 | 
						||
	+']); return function(i,d){var f=arguments.callee.caller;if(f==='+_p+'.a){if(!d)return i in '+_p+'?'+_p+'[i]:('+_p+'[i='+_p+'.c++]={},i);'+_p+'[i]={};}if('+_p+'.m[f])return '+_p+'.m._;if(f==='+_p+'.d)'+_p+'={};}})();');
 | 
						||
_p.toString=function(){return '';};
 | 
						||
 | 
						||
 | 
						||
//	class constructor	---------------------------
 | 
						||
 | 
						||
// do something others
 | 
						||
 | 
						||
 | 
						||
_.prototype={
 | 
						||
//	應該盡量把東西放在 class,instance 少一點…?
 | 
						||
 | 
						||
//	instance public interface	-------------------
 | 
						||
 | 
						||
//	** important ** 這邊不能作 object 之 initialization,否則因為 object 只會 copy reference,因此 new 時東西會一樣。initialization 得在 _() 中作!
 | 
						||
property1:[],
 | 
						||
 | 
						||
setV:function(m){
 | 
						||
 var _t=this,_p=pv(_t);
 | 
						||
 doLog('setV: class vars='+(vars=m)+', this.vars='+(_p.vars=m));
 | 
						||
},
 | 
						||
 | 
						||
getV:function(){
 | 
						||
 var _t=this,_p=pv(_t);
 | 
						||
 doLog('getV: class vars='+vars+', this.vars='+_p.vars);
 | 
						||
},
 | 
						||
 | 
						||
 | 
						||
//	instance destructor	---------------------------
 | 
						||
 | 
						||
/*
 | 
						||
usage:
 | 
						||
instance=instance.destroy();
 | 
						||
or if you has something more to do:
 | 
						||
instance.destroy()&&instance=null;
 | 
						||
 | 
						||
TODO: Need *auto* detect if the object is destroyed.
 | 
						||
*/
 | 
						||
destroy:function(){
 | 
						||
 //	If you need to do something (e.g, destroy sub-sub-objects) before destroy it, you need to call pv(this) first here.
 | 
						||
 pv(this,1);
 | 
						||
}
 | 
						||
 | 
						||
};	//	_.prototype=
 | 
						||
 | 
						||
//	class name	---------------------------
 | 
						||
if(className){
 | 
						||
 _.prototype.toString=_.toString=function(){return '[class '+className+']';};//classT
 | 
						||
 //eval('var className=_',this);	//	行不通
 | 
						||
}
 | 
						||
 | 
						||
return _;
 | 
						||
})();	//	(function(){
 | 
						||
 | 
						||
 | 
						||
//	===================================================
 | 
						||
 | 
						||
 | 
						||
/*
 | 
						||
//	test suit
 | 
						||
sl('<hr />');
 | 
						||
var c1=new classT(123),c2=new classT(456);
 | 
						||
 | 
						||
c1.setV('Hello');
 | 
						||
c2.setV('World');
 | 
						||
c1.getV();
 | 
						||
c2.getV();
 | 
						||
 | 
						||
sl(c1.testV+','+c2.testV);
 | 
						||
 | 
						||
c1.destroy();
 | 
						||
c2.destroy();
 | 
						||
classT.destroy();
 | 
						||
*/
 | 
						||
 | 
						||
 | 
						||
 | 
						||
 | 
						||
 | 
						||
/*
 | 
						||
繼承
 | 
						||
http://www.cnblogs.com/birdshome/archive/2005/01/28/95933.html
 | 
						||
 | 
						||
 | 
						||
引入arguments.length:這代表傳入引數個數(長度),arguments.callee.length:這代表(function)自身定義的引數個數(長度)
 | 
						||
function fn(){
 | 
						||
 var _f=arguments.callee;	//	f: function, flag	引入arguments.callee:這代表(function)自身
 | 
						||
 //	以 _f.* 替代 fn.*
 | 
						||
 alert('fn: _f.val='+_f.val);
 | 
						||
}
 | 
						||
fn.subfn=function(){
 | 
						||
 var _f=arguments.callee;	//	function, flag
 | 
						||
 //	當不用 new 時,以 _f.* 替代 fn.subfn.*,this.* 替代 fn.*。但在 (fn.subfn=function(){ .. }) 中間就不能用 this, _f
 | 
						||
 alert('fn.subfn: this.val='+this.val);	//	*** !!WARNING!! 在 eval() 中 this 可能表示 window,這時就無法用 this 來得到 fn 了。
 | 
						||
 alert('fn.subfn: _f.val='+_f.val);
 | 
						||
};
 | 
						||
fn.subfn.val='test value: fn.subfn.val';
 | 
						||
fn.val='test value: fn.val';
 | 
						||
fn.prototype={
 | 
						||
constructor:fn,	//	need to adjust
 | 
						||
subfn:function(){
 | 
						||
 var _f=arguments.callee;	//	function, flag
 | 
						||
 //	當不用 new 時,以 _f.* 替代 fn.subfn.*,this.* 替代 fn.*
 | 
						||
 alert('fn.prototype.subfn: this.val='+this.val);
 | 
						||
 alert('fn.prototype.subfn: _f.val='+_f.val);
 | 
						||
 alert('fn.prototype.subfn: this.constructor.val='+this.constructor.val);
 | 
						||
},
 | 
						||
val:'test value: fn.prototype.val'
 | 
						||
};	//	fn.prototype={
 | 
						||
fn.prototype.subfn.val='test value: fn.prototype.subfn.val';
 | 
						||
var inst=new fn;
 | 
						||
//inst.constructor.subfn();
 | 
						||
inst.subfn();
 | 
						||
 | 
						||
 | 
						||
var obj={
 | 
						||
 val:34,
 | 
						||
 fn:function(){
 | 
						||
  var _f=arguments.callee;	//	function, flag
 | 
						||
  //	以 _f.* 替代 obj.subfn.*,this.* 替代 obj.*
 | 
						||
  alert(this.val);
 | 
						||
 }
 | 
						||
};
 | 
						||
ww.ee();
 | 
						||
 | 
						||
 | 
						||
 | 
						||
to hack @ Firefox 3.0:	https://bugzilla.mozilla.org/show_bug.cgi?id=442333
 | 
						||
假設 scope obj.fn 裡有一個 foo 變數,在 Firefox 上可以使用 var a; eval('a = foo', obj.fn) 把 foo 變數抓到 a 裡面,所以你如果有使用這種方法來放與安全性有關的東西,就得重新檢查一次程式碼:Module Pattern Provides No Privacy…at least not in JavaScript(TM)。在一陣討論後,這個功能打算在 Firefox 3.1 拿掉:Remove eval's optional second argument。
 | 
						||
 | 
						||
*/
 | 
						||
 | 
						||
 | 
						||
/*
 | 
						||
實作class:
 | 
						||
	http://www.remus.dti.ne.jp/~a-satomi/bunsyorou/ArekorePopup.html
 | 
						||
	http://www.klstudio.com/post/32.html
 | 
						||
function classA(){
 | 
						||
 //	define property
 | 
						||
 //	array
 | 
						||
 this.attrs=['title','href','cite','datetime'];
 | 
						||
 //	object
 | 
						||
 this.ns={
 | 
						||
	xhtml1:'http://www.w3.org/1999/xhtml',
 | 
						||
	xhtml2:'http://www.w3.org/2002/06/xhtml2',
 | 
						||
 };
 | 
						||
 return this;
 | 
						||
}
 | 
						||
classA.prototype={
 | 
						||
 //	function
 | 
						||
 launch:function(){},
 | 
						||
 init:function(){},
 | 
						||
 //	object
 | 
						||
 scanNode:{
 | 
						||
  recursive:function(node){}
 | 
						||
 },
 | 
						||
 //	http://dean.edwards.name/weblog/2005/10/add-event/
 | 
						||
 addEvent:function(obj,type,listener){
 | 
						||
  if (obj.addEventListener) // Std DOM Events
 | 
						||
   obj.addEventListener(type, listener, false);
 | 
						||
  else if (obj.attachEvent) // IE
 | 
						||
   obj.attachEvent(
 | 
						||
    'on' + type,
 | 
						||
    function() { listener( {
 | 
						||
     type		: window.event.type,
 | 
						||
     target		: window.event.srcElement,
 | 
						||
     currentTarget	: obj,
 | 
						||
     clientX		: window.event.clientX,
 | 
						||
     clientY		: window.event.clientY,
 | 
						||
     pageY		: document.body.scrollTop + window.event.clientY,
 | 
						||
     keyCode		: window.event?window.event.keyCode:e?e.which:0,
 | 
						||
     shiftKey		: window.event.shiftKey,
 | 
						||
     stopPropagation	: function() { window.event.cancelBubble=true; }
 | 
						||
    } ) }
 | 
						||
   );
 | 
						||
 }
 | 
						||
};
 | 
						||
var A=new classA();
 | 
						||
 | 
						||
 | 
						||
*/
 | 
						||
 | 
						||
 |