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