1 sc_require('ext/handlebars');
  2 
  3 SC.Handlebars.ViewHelper = SC.Object.create({
  4   helper: function(thisContext, path, options) {
  5     var inverse = options.inverse;
  6     var data = options.data;
  7     var view = data.view;
  8     var fn = options.fn;
  9     var hash = options.hash;
 10 
 11     var newView;
 12     if (path.isClass || path.isObject) {
 13       newView = path;
 14       if (!newView) {
 15         throw new Error("Null or undefined object was passed to the #view helper. Did you mean to pass a property path string?");
 16       }
 17     } else {
 18       // Path is relative, look it up with this view as the root
 19       if (path.charAt(0) === '.') {
 20         newView = SC.objectForPropertyPath(path.slice(1), view);
 21       } else {
 22         // Path is absolute, look up path on global (window) object
 23         newView = SC.getPath(thisContext, path);
 24         if (!newView) {
 25           newView = SC.getPath(path);
 26         }
 27       }
 28       if (!newView) { throw new Error("Unable to find view at path '" + path + "'"); }
 29     }
 30 
 31     if (hash.id) { hash.layerId = hash.id; }
 32     else if (path.id) { hash.id = hash.layerId = path.id; }
 33 
 34     var contextOptions = {
 35       'id': hash.id,
 36       'class': hash['class'],
 37       'classBinding': hash.classBinding
 38     };
 39     delete hash.id;
 40     delete hash['class'];
 41     delete hash.classBinding;
 42 
 43     if (newView.isClass) {
 44       newView = newView.extend(hash);
 45     } else {
 46       SC.mixin(newView, hash);
 47     }
 48 
 49     var currentView = data.view;
 50 
 51     var childViews = currentView.get('childViews');
 52     var childView = currentView.createChildView(newView);
 53 
 54     // Set the template of the view to the passed block if we got one
 55     if (fn) { childView.template = fn; }
 56 
 57     childViews.pushObject(childView);
 58 
 59     var context = SC.RenderContext(childView.get('tagName'));
 60 
 61     // Add id and class names passed to view helper
 62     this.applyAttributes(contextOptions, childView, context);
 63 
 64     // tomdale wants to make SproutCore slow
 65     childView.renderToContext(context);
 66 
 67     return new Handlebars.SafeString(context.join());
 68   },
 69 
 70   applyAttributes: function(options, childView, context) {
 71     var id = options.id;
 72     var classNames = options['class'];
 73 
 74     if (classNames) {
 75       context.addClass(classNames.split(' '));
 76     }
 77 
 78     if (id) {
 79       childView.set('layerId', id);
 80       context.id(id);
 81     }
 82 
 83     var classBindings = options.classBinding;
 84     if (classBindings) {
 85       SC.Handlebars.bindClasses(childView, classBindings, childView).forEach(function(className) {
 86         context.setClass(className, YES);
 87       });
 88     }
 89   }
 90 });
 91 
 92 
 93 Handlebars.registerHelper('view', function(path, options) {
 94   return SC.Handlebars.ViewHelper.helper(this, path, options);
 95 });
 96