if(exports) { var inspect = function(obj) { require("sys").print(require("sys").inspect(obj) + "\n"); } var Handlebars = {}; Handlebars.AST = require("handlebars/ast"); Handlebars.Visitor = require("handlebars/jison_ext").Visitor; } // A Context wraps data, and makes it possible to extract a // new Context given a path. For instance, if the data // is { person: { name: "Alan" } }, a Context wrapping // "Alan" can be extracted by searching for "person/name" Handlebars.Context = function(data, fallback) { this.data = data; this.fallback = fallback; }; Handlebars.Context.prototype = { isContext: true, // Make a shallow copy of the Context clone: function() { var context = new Handlebars.Context; context.data = this.data; context.fallback = this.fallback; return context; }, // Search for an object inside the Context's data. The // path parameter is an object with parts // ("person/name" represented as ["person", "name"]), // and depth (the amount of levels to go up the stack, // originally represented as ..). The stack parameter // is the objects already searched from the root of // the original Context in order to get to this point. // // Return a new Context wrapping the data found in // the search. evaluate: function(path, stack) { var context = this.clone(); var depth = path.depth, parts = path.parts; if(depth > stack.length) { context.data = null; } else if(depth > 0) { context = stack[stack.length - depth].clone(); } for(var i=0,l=parts.length; i