proxmox-widget-toolkit/mixin/CBind.js
Dominik Csapak c33f087874 skip config property for cbind mixin
if we use a component with cbind in a static declaration,
we do not want to traverse the 'config' property, as this can lead
to properties of base classes which produce errors on copying

Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
2018-02-22 10:14:58 +01:00

149 lines
3.3 KiB
JavaScript

Ext.define('Proxmox.Mixin.CBind', {
extend: 'Ext.Mixin',
mixinConfig: {
before: {
initComponent: 'cloneTemplates'
}
},
cloneTemplates: function() {
var me = this;
if (typeof(me.cbindData) == "function") {
me.cbindData = me.cbindData(me.initialConfig) || {};
}
var getConfigValue = function(cname) {
if (cname in me.initialConfig) {
return me.initialConfig[cname];
}
if (cname in me.cbindData) {
return me.cbindData[cname];
}
if (cname in me) {
return me[cname];
}
throw "unable to get cbind data for '" + cname + "'";
};
var applyCBind = function(obj) {
var cbind = obj.cbind, prop, cdata, cvalue, match, found;
if (!cbind) return;
for (prop in cbind) {
cdata = cbind[prop];
found = false;
if (match = /^\{(!)?([a-z_][a-z0-9_]*)\}$/i.exec(cdata)) {
var cvalue = getConfigValue(match[2]);
if (match[1]) cvalue = !cvalue;
obj[prop] = cvalue;
found = true;
} else if (match = /^\{(!)?([a-z_][a-z0-9_]*(\.[a-z_][a-z0-9_]*)+)\}$/i.exec(cdata)) {
var keys = match[2].split('.');
var cvalue = getConfigValue(keys.shift());
keys.forEach(function(k) {
if (k in cvalue) {
cvalue = cvalue[k];
} else {
throw "unable to get cbind data for '" + match[2] + "'";
}
});
if (match[1]) cvalue = !cvalue;
obj[prop] = cvalue;
found = true;
} else {
obj[prop] = cdata.replace(/{([a-z_][a-z0-9_]*)\}/ig, function(match, cname) {
var cvalue = getConfigValue(cname);
found = true;
return cvalue;
});
}
if (!found) {
throw "unable to parse cbind template '" + cdata + "'";
}
}
};
if (me.cbind) {
applyCBind(me);
}
var cloneTemplateArray = function(org) {
var copy, i, found, el, elcopy, arrayLength;
arrayLength = org.length;
found = false;
for (i = 0; i < arrayLength; i++) {
el = org[i];
if (el.constructor == Object && el.xtype) {
found = true;
break;
}
}
if (!found) return org; // no need to copy
copy = [];
for (i = 0; i < arrayLength; i++) {
el = org[i];
if (el.constructor == Object && el.xtype) {
elcopy = cloneTemplateObject(el);
if (elcopy.cbind) {
applyCBind(elcopy);
}
copy.push(elcopy);
} else if (el.constructor == Array) {
elcopy = cloneTemplateArray(el);
copy.push(elcopy);
} else {
copy.push(el);
}
}
return copy;
};
var cloneTemplateObject = function(org) {
var res = {}, prop, el, copy;
for (prop in org) {
el = org[prop];
if (el.constructor == Object && el.xtype) {
copy = cloneTemplateObject(el);
if (copy.cbind) {
applyCBind(copy);
}
res[prop] = copy;
} else if (el.constructor == Array) {
copy = cloneTemplateArray(el);
res[prop] = copy;
} else {
res[prop] = el;
}
}
return res;
};
var condCloneProperties = function() {
var prop, el, i, tmp;
for (prop in me) {
el = me[prop];
if (el === undefined || el === null) continue;
if (typeof(el) === 'object' && el.constructor == Object) {
if (el.xtype && prop != 'config') {
me[prop] = cloneTemplateObject(el);
}
} else if (el.constructor == Array) {
tmp = cloneTemplateArray(el);
me[prop] = tmp;
}
}
};
condCloneProperties();
}
});