/*
* ----------------------------------------------------------------------------------- *
* 脚本流程控制类
* Date: 2011-12-07
* 调用形式
* funFlow.call( {flow:'loginForm,loginCheck,numberChoice,color',
* delay:{loginCheck:["loginform"],color:["number"]},
* struct:{loginForm:["userForm_show"],loginCheck:["loginCheck"],numberChoice:["formNumber"],color:["colorbox"]}});
* 说明
* 中断继续 funFlow.delayConfirm("loginform");
* 除了delay参数设置的中断,函数return 'END' 也可以中断,可以用 funFlow.next()继续,next也可以带参数,指明或确定从哪里继续
*
* 参数
* flow 是流程别名,逗号隔开
* delay 是交互延时,流程别名做键名,标识做数组内容,可有多个标识,
* 当标识全部完成的时候,则执行延时操作,并自动继续操作下去
参数
delay 本身
delayHand 当前的操作别名
delayStrings 数组,延时需要确认的步骤,也就是delay的内容,当进行确认之前 ,需要复制到这里,再进行确认,当长度为0时则完成确认
* struct 流程别名做键名,数组内容对应操作的函数,做成数组便于以后扩展
* --更新记录------------------------------------------------------------------------- *
* v0.4.1 2011-12-07
* next(nextFlow, true) 函数添加参数二,用于确认跳过延时步骤,直接进入下一步,在delayConfirm中体现
* v0.4 2011-12-05
* 1. 添加了倒退功能 back() ,当操作遇到问题可以倒退到上一级
* 2. next(pos) 添加流程定位,程序可在任何一点再开始流程,只要以流程标识做参数(pos)\
* 3. delayConfirm 函数修改,添加了步骤确定,如果参数不是当前的流程,则会自动退到相应的流程进行确认,相当于next
* v0.2 2011-11-07
* 1. 添加delay参数,使程序不会立即执行,而是等待用户操作后,或是ajax返回结果后再进行下一步,
* 用字符串数组表示,当满足一个则去掉对应的一个,如果全去掉了,则执行下一步
* 2. 把所有参数改到对象当中,只传递一个参数
* delay 宗旨,delay后,本身并不执行,要先等前面的步骤确认,再执行自己,
* delay 容易犯的错误,登陆窗口,submit后再next,容易重复执行loginCheck
* ----------------------------------------------------------------------------------- *
*/
var funFlow={
flow:null,flowAll:null,struct:null,delay:null,delayHand:'',delayStrings:null,
flowList:[], flowLog:'|', args:{}, arg:null,
get_flowList:function(i){
i = i || -1;
i = i < 0 ? this.flowList.length + i : i;
if( i < 0 || i >= this.flowList.length ){
return null;
}else{
return this.flowList[i];
}
},
arrayAdd:function(arr,item){
if (arr != null && arr.length != 0 && funFlow.arrayIn(arr,item) == -1) {
arr.push(item);
}
},
arrayIn:function(arr,item){
if (!arr) return -1;
for( var i in arr){
if (arr[i] == item) return i;
}
return -1;
},
arrayDel:function(arr, item){
var index = funFlow.arrayIn(arr,item);
if( index > -1 ){
arr.splice(index,1);
return true;
}else{
return false;
}
},
delayAdd:function(val){
//if (!funFlow.delay || funFlow.delay[name] == null) return;
if (funFlow.delayStrings == null) {
return;
}
if (funFlow.arrayIn(funFlow.delayStrings, val) == -1){
funFlow.delayStrings.push(val);
}
},
delayDel:function(val){
/*
if (funFlow.delayStrings == null) {
for (var i in funFlow.delay) {
}
}
*/
return funFlow.arrayDel(funFlow.delayStrings,val);
},
//确定交互延迟操作,delayHand是正在进行的延迟,val参数是对应的延迟值,因为可有多个,所以需要确认是哪一个。
//0.4 添加了步骤确定,如果参数不是当前的流程,则会自动退到相应的流程进行确认
delayConfirm:function(val){
var nextFlow;
if (funFlow.arrayIn(funFlow.delay[funFlow.delayHand], val)==-1) {
for (var i in funFlow.delay){
if (funFlow.arrayIn(funFlow.delay[i], val) > -1) {
nextFlow = i;
funFlow.delayHand = i;//重新确认当前延时标识
break;
}
}
if (nextFlow === undefined) {
alert('流程延时确认错误');
return false;
}
}
funFlow.delayDel(val);
//funFlow.flow.shift();
if (funFlow.delayStrings == null || funFlow.delayStrings.length == 0){
funFlow.next(nextFlow, true);
}
},
/*
delayEmpty:function(name){
if ( funFlow.delay == null || funFlow.delay['name'] == null || funFlow.delay['name'].length == 0 )
return true;
else
return false;
},
*/
logIn:function(log){
if( this.flowLog.indexOf('|'+log+'|') > -1 )
return true;
else {
return false;
}
},
logAdd:function(log){
if( !this.logIn(log) )
this.flowLog += log+'|';
},
logDel:function(log){
if( this.logIn(log) ){
this.flowLog.replace(log+"|", "");
return true;
}else{
return false;
}
},
call:function(obj) {
funFlow.flowAll = obj.flow.split(',');
funFlow.flow = funFlow.flowAll.concat();
funFlow.struct = obj.struct;
funFlow.flowList = [];
funFlow.flowLog = '|';
//funFlow.args = {};
//funFlow.arg = null;
funFlow.delayHand = '';
funFlow.delayStrings = null;
if(obj.delay != undefined){
funFlow.delay = obj.delay;
}
funFlow.next();
},
next:function(pos, noDelay){
var g=funFlow, flow=g.flow, struct=g.struct;
var i,arg;
var prevHand=null, ret=null;
//如果有pos参数,则需要重新设定流程,以参数位置重新开始
if (pos != undefined) {
var allindex = g.arrayIn(g.flowAll, pos);
if (allindex!=-1) {
flow = g.flow = g.flowAll.slice(allindex);
}
}
while(true){
if (ret != null && ret != 'END') {
flow = struct[prevHand][1][ret].split(',').concat( flow );
}
prevHand = flow[0];
arg=g.arg;g.arg=null;
//如果有delay条件,则进行检测
//如果delayStrings已经清除过的话,则跳过
if (noDelay !== true && g.delay != null && g.delay[prevHand] != null && g.delay[prevHand].length > 0) {
g.delayHand = prevHand;
g.delayStrings = g.delay[prevHand].concat();
return;
}
flow.shift();
//记录当前子流程标识。
g.flowList.push(prevHand);
//执行函数
ret = window[struct[prevHand][0]]( arg );
//如果需要等待用户响应,也可以输出END强制停止,待确认后再执行next函数
if( flow.length == 0 || ret == 'END' ){
//g.flow = flow;
return true;
}
}
},
back:function(){
flow.unshift(g.flowList.pop());
}
};
* ----------------------------------------------------------------------------------- *
* 脚本流程控制类
* Date: 2011-12-07
* 调用形式
* funFlow.call( {flow:'loginForm,loginCheck,numberChoice,color',
* delay:{loginCheck:["loginform"],color:["number"]},
* struct:{loginForm:["userForm_show"],loginCheck:["loginCheck"],numberChoice:["formNumber"],color:["colorbox"]}});
* 说明
* 中断继续 funFlow.delayConfirm("loginform");
* 除了delay参数设置的中断,函数return 'END' 也可以中断,可以用 funFlow.next()继续,next也可以带参数,指明或确定从哪里继续
*
* 参数
* flow 是流程别名,逗号隔开
* delay 是交互延时,流程别名做键名,标识做数组内容,可有多个标识,
* 当标识全部完成的时候,则执行延时操作,并自动继续操作下去
参数
delay 本身
delayHand 当前的操作别名
delayStrings 数组,延时需要确认的步骤,也就是delay的内容,当进行确认之前 ,需要复制到这里,再进行确认,当长度为0时则完成确认
* struct 流程别名做键名,数组内容对应操作的函数,做成数组便于以后扩展
* --更新记录------------------------------------------------------------------------- *
* v0.4.1 2011-12-07
* next(nextFlow, true) 函数添加参数二,用于确认跳过延时步骤,直接进入下一步,在delayConfirm中体现
* v0.4 2011-12-05
* 1. 添加了倒退功能 back() ,当操作遇到问题可以倒退到上一级
* 2. next(pos) 添加流程定位,程序可在任何一点再开始流程,只要以流程标识做参数(pos)\
* 3. delayConfirm 函数修改,添加了步骤确定,如果参数不是当前的流程,则会自动退到相应的流程进行确认,相当于next
* v0.2 2011-11-07
* 1. 添加delay参数,使程序不会立即执行,而是等待用户操作后,或是ajax返回结果后再进行下一步,
* 用字符串数组表示,当满足一个则去掉对应的一个,如果全去掉了,则执行下一步
* 2. 把所有参数改到对象当中,只传递一个参数
* delay 宗旨,delay后,本身并不执行,要先等前面的步骤确认,再执行自己,
* delay 容易犯的错误,登陆窗口,submit后再next,容易重复执行loginCheck
* ----------------------------------------------------------------------------------- *
*/
var funFlow={
flow:null,flowAll:null,struct:null,delay:null,delayHand:'',delayStrings:null,
flowList:[], flowLog:'|', args:{}, arg:null,
get_flowList:function(i){
i = i || -1;
i = i < 0 ? this.flowList.length + i : i;
if( i < 0 || i >= this.flowList.length ){
return null;
}else{
return this.flowList[i];
}
},
arrayAdd:function(arr,item){
if (arr != null && arr.length != 0 && funFlow.arrayIn(arr,item) == -1) {
arr.push(item);
}
},
arrayIn:function(arr,item){
if (!arr) return -1;
for( var i in arr){
if (arr[i] == item) return i;
}
return -1;
},
arrayDel:function(arr, item){
var index = funFlow.arrayIn(arr,item);
if( index > -1 ){
arr.splice(index,1);
return true;
}else{
return false;
}
},
delayAdd:function(val){
//if (!funFlow.delay || funFlow.delay[name] == null) return;
if (funFlow.delayStrings == null) {
return;
}
if (funFlow.arrayIn(funFlow.delayStrings, val) == -1){
funFlow.delayStrings.push(val);
}
},
delayDel:function(val){
/*
if (funFlow.delayStrings == null) {
for (var i in funFlow.delay) {
}
}
*/
return funFlow.arrayDel(funFlow.delayStrings,val);
},
//确定交互延迟操作,delayHand是正在进行的延迟,val参数是对应的延迟值,因为可有多个,所以需要确认是哪一个。
//0.4 添加了步骤确定,如果参数不是当前的流程,则会自动退到相应的流程进行确认
delayConfirm:function(val){
var nextFlow;
if (funFlow.arrayIn(funFlow.delay[funFlow.delayHand], val)==-1) {
for (var i in funFlow.delay){
if (funFlow.arrayIn(funFlow.delay[i], val) > -1) {
nextFlow = i;
funFlow.delayHand = i;//重新确认当前延时标识
break;
}
}
if (nextFlow === undefined) {
alert('流程延时确认错误');
return false;
}
}
funFlow.delayDel(val);
//funFlow.flow.shift();
if (funFlow.delayStrings == null || funFlow.delayStrings.length == 0){
funFlow.next(nextFlow, true);
}
},
/*
delayEmpty:function(name){
if ( funFlow.delay == null || funFlow.delay['name'] == null || funFlow.delay['name'].length == 0 )
return true;
else
return false;
},
*/
logIn:function(log){
if( this.flowLog.indexOf('|'+log+'|') > -1 )
return true;
else {
return false;
}
},
logAdd:function(log){
if( !this.logIn(log) )
this.flowLog += log+'|';
},
logDel:function(log){
if( this.logIn(log) ){
this.flowLog.replace(log+"|", "");
return true;
}else{
return false;
}
},
call:function(obj) {
funFlow.flowAll = obj.flow.split(',');
funFlow.flow = funFlow.flowAll.concat();
funFlow.struct = obj.struct;
funFlow.flowList = [];
funFlow.flowLog = '|';
//funFlow.args = {};
//funFlow.arg = null;
funFlow.delayHand = '';
funFlow.delayStrings = null;
if(obj.delay != undefined){
funFlow.delay = obj.delay;
}
funFlow.next();
},
next:function(pos, noDelay){
var g=funFlow, flow=g.flow, struct=g.struct;
var i,arg;
var prevHand=null, ret=null;
//如果有pos参数,则需要重新设定流程,以参数位置重新开始
if (pos != undefined) {
var allindex = g.arrayIn(g.flowAll, pos);
if (allindex!=-1) {
flow = g.flow = g.flowAll.slice(allindex);
}
}
while(true){
if (ret != null && ret != 'END') {
flow = struct[prevHand][1][ret].split(',').concat( flow );
}
prevHand = flow[0];
arg=g.arg;g.arg=null;
//如果有delay条件,则进行检测
//如果delayStrings已经清除过的话,则跳过
if (noDelay !== true && g.delay != null && g.delay[prevHand] != null && g.delay[prevHand].length > 0) {
g.delayHand = prevHand;
g.delayStrings = g.delay[prevHand].concat();
return;
}
flow.shift();
//记录当前子流程标识。
g.flowList.push(prevHand);
//执行函数
ret = window[struct[prevHand][0]]( arg );
//如果需要等待用户响应,也可以输出END强制停止,待确认后再执行next函数
if( flow.length == 0 || ret == 'END' ){
//g.flow = flow;
return true;
}
}
},
back:function(){
flow.unshift(g.flowList.pop());
}
};