📄 decorator-support.js
字号:
var dns = 'http://www.xidea.org/taglib/decorator';
var nsExp = /^[dD]\:/;
//buildTree for firefox
function DecoratorEngine(){
this.providerMap = {};
this.initialize();
}
DecoratorEngine.prototype.initialize = function(){
var dps = $JSI.getAttribute("decoratorProviders") || [];
for(var i = dps.length-1;i>=0;i--){
this.addProvider.apply(this,dps[i]);
}
var tag = $JSI.getAttribute('decoratorTag');
if(tag){
this.tagExp = new RegExp('^'+tag+'$','i');
}
}
DecoratorEngine.prepare = function(){
EventUtil.addDOMLoadListener (function(){
if(!DecoratorEngine.mainEngine){
DecoratorEngine.mainEngine = new DecoratorEngine();
window.setTimeout(function(){
DecoratorEngine.mainEngine.run();
},100);
}
});
}
DecoratorEngine.prototype.run = function(ele){
var root = this.buildTree(ele||document.body);
for(var i = 0;i<root.length;i++){
this.loadTree(root[i]);
}
}
DecoratorEngine.prototype.loadTree = function(node,parent){
var d = this.buildDecorator(node);
this.beforeDecorate(d);
for(var i = 0;i<node.children.length;i++){
this.loadTree(node.children[i],d);
}
this.doDecorate(d);
}
DecoratorEngine.prototype.buildTree = function(root){
var tree = {children:[]};
if(this.tagExp){
this.htmlWalk(root,tree);
return tree.children;
}
if(BrowserInfo.isIE()){
var ds = root.all.urns(dns);
}else if(document.documentElement.tagName == 'html' //xhtml
&& document.documentElement.namespaceURI == 'http://www.w3.org/1999/xhtml'){
var ds = document.getElementsByTagNameNS(dns,'*');
}else{
this.domWalk(root,tree);
return tree.children;
}
var pe = [root];
var pn = [tree];
outer:
for(var i = 0;i<ds.length;i++){
var e = ds[i];
var node = new NodeInfo(ds[i]);
while(e = e.parentNode){
for(var j = pn.length-1;j>=0;j--){
if(pe[j] == e){//找到parent
pn[j].children.push(node);
pn[j+1] = node;
pe[j+1] = e;
pe.length = pn.length = j+2;
continue outer;
}
}
}
}
delete ds;
delete pe;
delete pn;
return tree.children;
}
var typeAttr = 'd:decorator';
if(BrowserInfo.isOpera(0,8.9)){
typeAttr = 'decorator'
}
DecoratorEngine.prototype.htmlWalk = function(node,parent){
if(this.tagExp.test(node.tagName)){
var dc = node.getAttribute(typeAttr);
if(dc){
var info = new NodeInfo(node,true);
parent.children.push(info);
parent = info;
}
}
//alert(node.tagName)
var c = node.firstChild;
while(c){
if(c.nodeType == 1){
this.htmlWalk(c,parent);
}
c = c.nextSibling;
}
}
DecoratorEngine.prototype.domWalk = function(node,parent){
if(/^[dD]\:/.test(node.tagName)){
var name = node.tagName.substr(2);
var info = new NodeInfo(node);
parent.children.push(info);
parent = info;
}
//alert(node.tagName)
var c = node.firstChild;
while(c){
if(c.nodeType == 1){
this.domWalk(c,parent);
}
c = c.nextSibling;
}
}
function NodeInfo(node,nsAttr){
this.children = [];
this.id = node.id || node.uniqueID || (node.id = $puid());
if(nsAttr){
this.attrs = new Attributes(node,true);
this.cls = this.attrs.get('decorator');
}else{
this.attrs = new Attributes(node);
this.cls = node.tagName.replace(nsExp,'');
}
//alert(node.getAttribute('d:decorator'))
//alert(this.attrs.length)
}
function Attributes(node,ns){
this.valueMap = {};
//alert(attrs.getAttribute())
if(//true){//
BrowserInfo.isIE(0,5.9)){
this.initializeFromHTML(node,ns);
}else{
this.initialize(node,ns);
}
}
Attributes.prototype.initializeFromHTML=function(node,ns){
var html = node.cloneNode().outerHTML;
var matchs = html.match(/\b([\w\d_\$]+\s*=\s*("(\\.|[^\"\n\r])*"|'(\\.|[^\'\n\r])*'))/g);
for(var i = matchs.length-1;i>=0;i--){
var values = matchs[i].match(/([\w\d_\$]+)\s*=\s*['"](.*)["']$/);
this.valueMap[values[1]] = values[2];
}
//alert(this.valueMap)
}
Attributes.prototype.initialize=function(node,ns){
var attrs = node.attributes;
//ns = ns && !BrowserInfo.isOpera(0,8.9);
for(var i = attrs.length-1;i>=0;i--){
if(!attrs[i].nodeValue){
continue;
}
var name = attrs[i].nodeName;
if(ns){
if(nsExp.test(name)){
name = name.substr(2);
}else{
continue;
}
}
var node = {key:name,value:attrs[i].nodeValue};
this.valueMap[node.key] = node.value;
}
}
//object.cloneNode( [bCloneChildren])
//Attributes.prototype = [];
Attributes.prototype.get = function(key){
return this.valueMap[key]||this.valueMap[key.toUpperCase()];
}
DecoratorEngine.prototype.buildDecorator = function(info){
//
var p = info.attrs.get('provider');
var provider = this.getProvider(p);
//alert(info.cls)
var dec = provider.findDecorator(info.cls);
if(!dec){
$log.error("missed decorator:",info.cls)
return;
}
info.decorator = dec = new dec();
dec.id = info.id;
//initialize dec
if(info.parent){
dec.parent = info.parent.decorator;
(dec.parent.children||(dec.parent.children = [])).push(dec);
}
dec.attributes = info.attrs;
return dec;
}
/**
* 预装饰处理.
* @public
* @param <Decorator>dec 装饰实例
*/
DecoratorEngine.prototype.beforeDecorate = function(dec){
try{
dec.before();
}catch(e){
//dec.exception = e;
$log.info("decorator before error:",e);
}
};
/**
* 执行装饰处理
* @public
* @param <Decorator>dec 装饰实例
*/
DecoratorEngine.prototype.doDecorate = function(dec){
try{
dec.decorate();
}catch(e){
$log.info("decorator do decorate error:",e);
}
};
DecoratorEngine.prototype.addProvider = function(pkgname,alias){
var pkg = $JSI.Package.require(pkgname);
var provider = new DecoratorProvider(pkg);
this.providerMap[pkg.name] = provider;
for(var i = arguments.length-1;i>=0;i--){
this.providerMap[arguments[i]] = provider;
}
}
DecoratorEngine.prototype.getProvider = function(name){
if(this.providerMap[name]){
return this.providerMap[name];
}else{
return this.providerMap['*'];
}
}
/**
* @private
*/
function DecoratorProvider(pkg){
this.pkg = pkg;
this.decoratorMap = {};
this.initialize();
}
DecoratorProvider.prototype.initialize = function(){
var names = this.pkg.objectNames;
for(var i = 0;i<names.length;i++){
var name = names[i];
if(this.decoratorMap[name]){
this.decoratorMap[name].push(name);
}else{
this.decoratorMap[name] = [name];
}
var bn = name.toUpperCase();
if(this.decoratorMap[bn]){
this.decoratorMap[bn].push(name);
}else{
this.decoratorMap[bn] = [name];
}
}
}
DecoratorProvider.prototype.findDecorator = function(name){
var obj = this.decoratorMap[name];
if(!obj){
name = name.toUpperCase();
obj = this.decoratorMap[name];
}
if(obj){
if(obj.prototype instanceof Decorator){
return obj;
}else if(obj instanceof Array){
for(var i = 0;i<obj.length;i++){
var d = this.pkg.prepareObject(obj[i],false);
if(d.prototype instanceof Decorator){//subclassof
this.pkg.prepareObject(obj[i],true);
return this.decoratorMap[name] = d;
}
}
//not hit,remove it
delete this.decoratorMap[name];
}
}
return null;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -