diff --git a/packages/spacebars/compile_tests.js b/packages/spacebars/compile_tests.js index ca46188015..047fa2de83 100644 --- a/packages/spacebars/compile_tests.js +++ b/packages/spacebars/compile_tests.js @@ -74,11 +74,9 @@ Tinytest.add("spacebars - compiler output", function (test) { function() { var self = this; return function() { - return Spacebars.mustache2(self.lookup("foo"), { - hash: { - x: Spacebars.dot(self.lookup("bar"), "baz") - } - }); + return Spacebars.mustache2(self.lookup("foo"), Spacebars.kw({ + x: Spacebars.dot(self.lookup("bar"), "baz") + })); }; }); @@ -139,7 +137,7 @@ Tinytest.add("spacebars - compiler output", function (test) { return function() { return Spacebars.include(Template["foo"] || self.lookup("foo"), { data: function() { - return Spacebars.dot(self.lookup("bar"), "baz"); + return Spacebars.call2(Spacebars.dot(self.lookup("bar"), "baz")); } }); }; @@ -151,7 +149,7 @@ Tinytest.add("spacebars - compiler output", function (test) { return function() { return Spacebars.include(Template["foo"] || self.lookup("foo"), { x: function() { - return Spacebars.dot(self.lookup("bar"), "baz"); + return Spacebars.call2(Spacebars.dot(self.lookup("bar"), "baz")); } }); }; diff --git a/packages/spacebars/spacebars.js b/packages/spacebars/spacebars.js index 0d1803b79c..88df661b1d 100644 --- a/packages/spacebars/spacebars.js +++ b/packages/spacebars/spacebars.js @@ -1683,9 +1683,26 @@ Spacebars.combineAttributes = function (/*attrObjects*/) { // Executes `{{foo bar baz}}` when called on `(foo, bar, baz)`. // If `bar` and `baz` are functions, they are called before // `foo` is called on them. +// +// This is the shared part of Spacebars.mustache and +// Spacebars.attrMustache, which differ in how they post-process the +// result. +Spacebars.mustacheImpl = function (value/*, args*/) { + var args = arguments; + // if we have any arguments (pos or kw), add an options argument + // if there isn't one. + if (args.length > 1 && + ! (args[args.length - 1] instanceof Spacebars.kw)) { + // clone arguments into an actual array, then push. + args = Array.prototype.slice.call(arguments); + args.push(Spacebars.kw()); + } + + return Spacebars.call2.apply(null, args); +}; + Spacebars.mustache2 = function (value/*, args*/) { - var args = ensureHash(arguments); - var result = Spacebars.call2.apply(null, args); + var result = Spacebars.mustacheImpl.apply(null, arguments); if (result instanceof Handlebars.SafeString) return HTML.Raw(result.toString()); @@ -1695,6 +1712,22 @@ Spacebars.mustache2 = function (value/*, args*/) { return String(result == null ? '' : result); }; +Spacebars.attrMustache = function (value/*, args*/) { + var result = Spacebars.mustacheImpl.apply(null, arguments); + + if (result == null || result === '') { + return null; + } else if (typeof result === 'object') { + return result; + } else if (typeof result === 'string' && UI.isValidAttributeName(result)) { + var obj = {}; + obj[result] = ''; + return obj; + } else { + throw new Error("Expected valid attribute name, '', null, or object"); + } +}; + // Idempotently wrap in `HTML.Raw`. // // Called on the return value from `Spacebars.mustache2` in case the @@ -1728,35 +1761,6 @@ Spacebars.call2 = function (value/*, args*/) { } }; -// If the last element of `args` is not a `Spacebars.kw` object, -// return a new array with an appended `Spacebars.kw` object. -// Otherwise just return `args`. `args` may be an arguments -// object; we won't mutate it. -var ensureHash = function (args) { - if (! (args[args.length - 1] instanceof Spacebars.kw)) { - args = Array.prototype.slice.call(args); - args.push(Spacebars.kw()); - } - return args; -}; - -Spacebars.attrMustache = function (value/*, args*/) { - var args = ensureHash(arguments); - var result = Spacebars.call2.apply(null, args); - - if (result == null || result === '') { - return null; - } else if (typeof result === 'object') { - return result; - } else if (typeof result === 'string' && UI.isValidAttributeName(result)) { - var obj = {}; - obj[result] = ''; - return obj; - } else { - throw new Error("Expected valid attribute name, '', null, or object"); - } -}; - var codeGenMustache = function (tag, mustacheType) { var nameCode = codeGenPath2(tag.path); var argCode = codeGenArgs2(tag.args); diff --git a/packages/templating/templating_tests.js b/packages/templating/templating_tests.js index 85dcc2e258..bd45793d8b 100644 --- a/packages/templating/templating_tests.js +++ b/packages/templating/templating_tests.js @@ -187,9 +187,6 @@ Tinytest.add("templating - helpers and dots", function(test) { }; var listFour = function(a, b, c, d, options) { - // XXX this fails because `options` is sometimes undefined. on - // devel, options is always passed, with an empty hash even if - // there are no kwargs var keywordArgs = _.map(_.keys(options.hash), function(k) { var val = options.hash[k]; return k+':'+val; @@ -534,8 +531,6 @@ Tinytest.add('templating - helper typecast Issue #617', function (test) { var div = renderToDiv(Template.test_type_casting); var result = canonicalizeHtml(div.innerHTML); - // XXX this fails because of the missing last object argument. - // (see XXX comment within `listFour`) test.equal( result, // This corresponds to entries in templating_tests.html.