ace/build/pilot/domtemplate.js
2011-01-10 13:17:14 +01:00

201 lines
No EOL
5.9 KiB
JavaScript

define(function(r, q) {
function g() {
this.scope = []
}
g.prototype.processNode = function(a, c) {
if(typeof a === "string") {
a = document.getElementById(a)
}if(c === null || c === undefined) {
c = {}
}this.scope.push(a.nodeName + (a.id ? "#" + a.id : ""));
try {
if(a.attributes && a.attributes.length) {
if(a.hasAttribute("foreach")) {
this.processForEach(a, c);
return
}if(a.hasAttribute("if")) {
if(!this.processIf(a, c)) {
return
}
}c.__element = a;
for(var d = Array.prototype.slice.call(a.attributes), b = 0;b < d.length;b++) {
var e = d[b].value, f = d[b].name;
this.scope.push(f);
try {
if(f === "save") {
e = this.stripBraces(e);
this.property(e, c, a);
a.removeAttribute("save")
}else {
if(f.substring(0, 2) === "on") {
e = this.stripBraces(e);
var j = this.property(e, c);
typeof j !== "function" && this.handleError("Expected " + e + " to resolve to a function, but got " + typeof j);
a.removeAttribute(f);
var n = a.hasAttribute("capture" + f.substring(2));
a.addEventListener(f.substring(2), j, n);
n && a.removeAttribute("capture" + f.substring(2))
}else {
var o = this, i = e.replace(/\$\{[^}]*\}/g, function(p) {
return o.envEval(p.slice(2, -1), c, e)
});
if(f.charAt(0) === "_") {
a.removeAttribute(f);
a.setAttribute(f.substring(1), i)
}else {
if(e !== i) {
d[b].value = i
}
}
}
}
}finally {
this.scope.pop()
}
}
}var m = Array.prototype.slice.call(a.childNodes);
for(d = 0;d < m.length;d++) {
this.processNode(m[d], c)
}a.nodeType === Node.TEXT_NODE && this.processTextNode(a, c)
}finally {
this.scope.pop()
}
};
g.prototype.processIf = function(a, c) {
this.scope.push("if");
try {
var d = a.getAttribute("if"), b = this.stripBraces(d), e = true;
try {
e = !!this.envEval(b, c, d)
}catch(f) {
this.handleError("Error with '" + b + "'", f);
e = false
}e || a.parentNode.removeChild(a);
a.removeAttribute("if");
return e
}finally {
this.scope.pop()
}
};
g.prototype.processForEach = function(a, c) {
this.scope.push("foreach");
try {
var d = a.getAttribute("foreach"), b = d, e = "param";
if(b.charAt(0) === "$") {
b = this.stripBraces(b)
}else {
var f = b.split(" in ");
e = f[0].trim();
b = this.stripBraces(f[1].trim())
}a.removeAttribute("foreach");
try {
var j = this, n = function(h, k, l) {
l.parentNode.insertBefore(k, l);
c[e] = h;
j.processNode(k, c);
delete c[e]
}, o = function(h, k) {
j.scope.push(h);
try {
if(a.nodeName === "LOOP") {
for(h = 0;h < a.childNodes.length;h++) {
var l = a.childNodes[h].cloneNode(true);
n(k, l, a)
}
}else {
l = a.cloneNode(true);
l.removeAttribute("foreach");
n(k, l, a)
}
}finally {
j.scope.pop()
}
}, i = this.envEval(b, c, d);
if(Array.isArray(i)) {
i.forEach(function(h, k) {
o("" + k, h)
}, this)
}else {
for(var m in i) {
i.hasOwnProperty(m) && o(m, m)
}
}a.parentNode.removeChild(a)
}catch(p) {
this.handleError("Error with '" + b + "'", p)
}
}finally {
this.scope.pop()
}
};
g.prototype.processTextNode = function(a, c) {
var d = a.data;
d = d.replace(/\$\{([^}]*)\}/g, "\uf001$$$1\uf002");
d = d.split(/\uF001|\uF002/);
if(d.length > 1) {
d.forEach(function(b) {
if(!(b === null || b === undefined || b === "")) {
if(b.charAt(0) === "$") {
b = this.envEval(b.slice(1), c, a.data)
}if(b === null) {
b = "null"
}if(b === undefined) {
b = "undefined"
}if(typeof b.cloneNode !== "function") {
b = a.ownerDocument.createTextNode(b.toString())
}a.parentNode.insertBefore(b, a)
}
}, this);
a.parentNode.removeChild(a)
}
};
g.prototype.stripBraces = function(a) {
if(!a.match(/\$\{.*\}/g)) {
this.handleError("Expected " + a + " to match ${...}");
return a
}return a.slice(2, -1)
};
g.prototype.property = function(a, c, d) {
this.scope.push(a);
try {
if(typeof a === "string") {
a = a.split(".")
}var b = c[a[0]];
if(a.length === 1) {
if(d !== undefined) {
c[a[0]] = d
}if(typeof b === "function") {
return function() {
return b.apply(c, arguments)
}
}return b
}if(!b) {
this.handleError("Can't find path=" + a);
return null
}return this.property(a.slice(1), b, d)
}finally {
this.scope.pop()
}
};
g.prototype.envEval = function(a, c, d) {
with(c) {
try {
this.scope.push(d);
return eval(a)
}catch(b) {
this.handleError("Template error evaluating '" + a + "'", b);
return a
}finally {
this.scope.pop()
}
}
};
g.prototype.handleError = function(a, c) {
this.logError(a);
this.logError("In: " + this.scope.join(" > "));
c && this.logError(c)
};
g.prototype.logError = function(a) {
console.log(a)
};
q.Templater = g
});