<html>
<script>
//2010.4.10 第一版
(function(ns)
{
var filters = {};
var max_priority = 10;
var default_priority = 10;
var array_include = function(a, v)
{
for ( var i = 0, j = a.length; i < j; i ++ )
{
if ( a[i] == v ) return true;
}
return false;
};
var to_array = function(a)
{
var rt = [];
for ( var i = 0, j = a.length; i < j; i ++ )
{
rt.push(a[i]);
}
return rt;
};
function _set(func, tag, priority, key, value)
{
func['__filter_' + tag + '_' + priority + '_' + key] = value;
}
function _get(func, tag, priority, key)
{
return func['__filter_' + tag + '_' + priority + '_' + key];
}
ns.add_filter = ns.add_action = function(tag, func, priority, run_once)
{
run_once = run_once === undefined ? false : run_once;
priority = priority || default_priority;
if ( !filters[tag] ) filters[tag] = {};
if ( !filters[tag][priority] ) filters[tag][priority] = [];
if ( !array_include(filters[tag][priority], func) )
{
filters[tag][priority].push(func);
}
_set(func, tag, priority, 'run_once', run_once);
};
ns.add_once_filter = ns.add_once_action = function(tag, func, priority)
{
ns.add_filter(tag, func, priority, true);
};
function filter_or_action(ac, tag, value)
{
if (!filters[tag]) return value;
if ( ac == 'action' )
{
var args = to_array(arguments);
args.shift();
args.shift();
}
var _cfs = filters[tag];
var i = 1, func;
var rt = value;
while ( i <= max_priority )
{
if ( !_cfs[i] || _cfs[i].length === 0 )
{
i ++;
continue;
}
for ( var j = 0, length = _cfs[i].length; j < length; j ++ )
{
func = _cfs[i][j];
if ( ac == 'action' )
{
rt = func.apply(null, args);
}
else
{
rt = func.call(null, rt);
}
if ( _get(func, tag, i, 'run_once') )
{
_cfs[i].splice(j, 1);
j --;
length --;
}
if ( rt && rt['end'] ) return rt['value'] || null;
}
i ++;
}
return rt;
};
ns.apply_filters = function(tag, value)
{
return filter_or_action('fitler', tag, value)
};
ns.do_action = function(tag)
{
var args = to_array(arguments);
filter_or_action.apply(null, ['action'].concat(args));
};
})(window)
function log(str)
{
document.write('<p>' + str + '</p>');
}
//普通的filter
add_filter('status', function(text)
{
return text.replace(/orz/g, '超人');
});
log(apply_filters('status', 'orzorz'));
//再添加一个filter
add_filter('status', function(text)
{
return text.replace('超人', '动感');
});
log(apply_filters('status', 'orzorz'));
//添加一个优先级较高的filter,并通过返回包含end字段的对象结束过滤器
add_filter('status', function(text)
{
return {end:true, value:text};
}, 5);
log(apply_filters('status', 'orzorz'));
//但是下面这个优先级较高的会执行
add_filter('status', function(text)
{
return text + '管不着我';
}, 1);
log(apply_filters('status', 'orzorz'));
log('-----------------------------');
log('action测试');
log('-----------------------------');
//下面是action
add_action('ac_success', function(a, b, c)
{
log('返回数据:' + a + b + c);
});
//添加一个只会执行一次的action回调
add_once_action('ac_success', function(a, b, c)
{
log('我只会执行一次的');
});
add_action('ac_success', function(a, b, c)
{
log('俺的优先级比较高');
}, 5);
log('----------第一次执行----------------');
do_action('ac_success', '1', '2', '3');
log('----------第二次执行----------------');
do_action('ac_success', '4', '5', '6');
add_action('ac_success', function(a, b, c)
{
log('全部屏蔽');
return {end:true};
}, 1);
log('----------第三次执行----------------');
do_action('ac_success', '1', '2', '3');
</script>
</html>