////////////////////////////////////////////////////////////////////////// // // // This is a generated file. You can view the original // // source in your browser if your browser supports source maps. // // // // If you are using Chrome, open the Developer Tools and click the gear // // icon in its lower right corner. In the General Settings panel, turn // // on 'Enable source maps'. // // // // If you are using Firefox 23, go to `about:config` and set the // // `devtools.debugger.source-maps-enabled` preference to true. // // (The preference should be on by default in Firefox 24; versions // // older than 23 do not support source maps.) // // // ////////////////////////////////////////////////////////////////////////// (function () { /* Imports */ var Meteor = Package.meteor.Meteor; var HTML = Package.htmljs.HTML; var Tracker = Package.tracker.Tracker; var Deps = Package.tracker.Deps; var Blaze = Package.blaze.Blaze; var UI = Package.blaze.UI; var Handlebars = Package.blaze.Handlebars; var ObserveSequence = Package['observe-sequence'].ObserveSequence; var Template = Package.templating.Template; var _ = Package.underscore._; /* Package-scope variables */ var Spacebars; (function () { ///////////////////////////////////////////////////////////////////////////////////////////////////////// // // // packages/spacebars/spacebars-runtime.js // // // ///////////////////////////////////////////////////////////////////////////////////////////////////////// // Spacebars = {}; // 1 // 2 var tripleEquals = function (a, b) { return a === b; }; // 3 // 4 Spacebars.include = function (templateOrFunction, contentFunc, elseFunc) { // 5 if (! templateOrFunction) // 6 return null; // 7 // 8 if (typeof templateOrFunction !== 'function') { // 9 var template = templateOrFunction; // 10 if (! Blaze.isTemplate(template)) // 11 throw new Error("Expected template or null, found: " + template); // 12 return templateOrFunction.constructView(contentFunc, elseFunc); // 13 } // 14 // 15 var templateVar = Blaze.ReactiveVar(null, tripleEquals); // 16 var view = Blaze.View('Spacebars.include', function () { // 17 var template = templateVar.get(); // 18 if (template === null) // 19 return null; // 20 // 21 if (! Blaze.isTemplate(template)) // 22 throw new Error("Expected template or null, found: " + template); // 23 // 24 return template.constructView(contentFunc, elseFunc); // 25 }); // 26 view.__templateVar = templateVar; // 27 view.onViewCreated(function () { // 28 this.autorun(function () { // 29 templateVar.set(templateOrFunction()); // 30 }); // 31 }); // 32 // 33 return view; // 34 }; // 35 // 36 // Executes `{{foo bar baz}}` when called on `(foo, bar, baz)`. // 37 // If `bar` and `baz` are functions, they are called before // 38 // `foo` is called on them. // 39 // // 40 // This is the shared part of Spacebars.mustache and // 41 // Spacebars.attrMustache, which differ in how they post-process the // 42 // result. // 43 Spacebars.mustacheImpl = function (value/*, args*/) { // 44 var args = arguments; // 45 // if we have any arguments (pos or kw), add an options argument // 46 // if there isn't one. // 47 if (args.length > 1) { // 48 var kw = args[args.length - 1]; // 49 if (! (kw instanceof Spacebars.kw)) { // 50 kw = Spacebars.kw(); // 51 // clone arguments into an actual array, then push // 52 // the empty kw object. // 53 args = Array.prototype.slice.call(arguments); // 54 args.push(kw); // 55 } else { // 56 // For each keyword arg, call it if it's a function // 57 var newHash = {}; // 58 for (var k in kw.hash) { // 59 var v = kw.hash[k]; // 60 newHash[k] = (typeof v === 'function' ? v() : v); // 61 } // 62 args[args.length - 1] = Spacebars.kw(newHash); // 63 } // 64 } // 65 // 66 return Spacebars.call.apply(null, args); // 67 }; // 68 // 69 Spacebars.mustache = function (value/*, args*/) { // 70 var result = Spacebars.mustacheImpl.apply(null, arguments); // 71 // 72 if (result instanceof Spacebars.SafeString) // 73 return HTML.Raw(result.toString()); // 74 else // 75 // map `null`, `undefined`, and `false` to null, which is important // 76 // so that attributes with nully values are considered absent. // 77 // stringify anything else (e.g. strings, booleans, numbers including 0). // 78 return (result == null || result === false) ? null : String(result); // 79 }; // 80 // 81 Spacebars.attrMustache = function (value/*, args*/) { // 82 var result = Spacebars.mustacheImpl.apply(null, arguments); // 83 // 84 if (result == null || result === '') { // 85 return null; // 86 } else if (typeof result === 'object') { // 87 return result; // 88 } else if (typeof result === 'string' && HTML.isValidAttributeName(result)) { // 89 var obj = {}; // 90 obj[result] = ''; // 91 return obj; // 92 } else { // 93 throw new Error("Expected valid attribute name, '', null, or object"); // 94 } // 95 }; // 96 // 97 Spacebars.dataMustache = function (value/*, args*/) { // 98 var result = Spacebars.mustacheImpl.apply(null, arguments); // 99 // 100 return result; // 101 }; // 102 // 103 // Idempotently wrap in `HTML.Raw`. // 104 // // 105 // Called on the return value from `Spacebars.mustache` in case the // 106 // template uses triple-stache (`{{{foo bar baz}}}`). // 107 Spacebars.makeRaw = function (value) { // 108 if (value == null) // null or undefined // 109 return null; // 110 else if (value instanceof HTML.Raw) // 111 return value; // 112 else // 113 return HTML.Raw(value); // 114 }; // 115 // 116 // If `value` is a function, called it on the `args`, after // 117 // evaluating the args themselves (by calling them if they are // 118 // functions). Otherwise, simply return `value` (and assert that // 119 // there are no args). // 120 Spacebars.call = function (value/*, args*/) { // 121 if (typeof value === 'function') { // 122 // evaluate arguments if they are functions (by calling them) // 123 var newArgs = []; // 124 for (var i = 1; i < arguments.length; i++) { // 125 var arg = arguments[i]; // 126 newArgs[i-1] = (typeof arg === 'function' ? arg() : arg); // 127 } // 128 // 129 return value.apply(null, newArgs); // 130 } else { // 131 if (arguments.length > 1) // 132 throw new Error("Can't call non-function: " + value); // 133 // 134 return value; // 135 } // 136 }; // 137 // 138 // Call this as `Spacebars.kw({ ... })`. The return value // 139 // is `instanceof Spacebars.kw`. // 140 Spacebars.kw = function (hash) { // 141 if (! (this instanceof Spacebars.kw)) // 142 // called without new; call with new // 143 return new Spacebars.kw(hash); // 144 // 145 this.hash = hash || {}; // 146 }; // 147 // 148 // Call this as `Spacebars.SafeString("some HTML")`. The return value // 149 // is `instanceof Spacebars.SafeString` (and `instanceof Handlebars.SafeString). // 150 Spacebars.SafeString = function (html) { // 151 if (! (this instanceof Spacebars.SafeString)) // 152 // called without new; call with new // 153 return new Spacebars.SafeString(html); // 154 // 155 return new Handlebars.SafeString(html); // 156 }; // 157 Spacebars.SafeString.prototype = Handlebars.SafeString.prototype; // 158 // 159 // `Spacebars.dot(foo, "bar", "baz")` performs a special kind // 160 // of `foo.bar.baz` that allows safe indexing of `null` and // 161 // indexing of functions (which calls the function). If the // 162 // result is a function, it is always a bound function (e.g. // 163 // a wrapped version of `baz` that always uses `foo.bar` as // 164 // `this`). // 165 // // 166 // In `Spacebars.dot(foo, "bar")`, `foo` is assumed to be either // 167 // a non-function value or a "fully-bound" function wrapping a value, // 168 // where fully-bound means it takes no arguments and ignores `this`. // 169 // // 170 // `Spacebars.dot(foo, "bar")` performs the following steps: // 171 // // 172 // * If `foo` is falsy, return `foo`. // 173 // // 174 // * If `foo` is a function, call it (set `foo` to `foo()`). // 175 // // 176 // * If `foo` is falsy now, return `foo`. // 177 // // 178 // * Return `foo.bar`, binding it to `foo` if it's a function. // 179 Spacebars.dot = function (value, id1/*, id2, ...*/) { // 180 if (arguments.length > 2) { // 181 // Note: doing this recursively is probably less efficient than // 182 // doing it in an iterative loop. // 183 var argsForRecurse = []; // 184 argsForRecurse.push(Spacebars.dot(value, id1)); // 185 argsForRecurse.push.apply(argsForRecurse, // 186 Array.prototype.slice.call(arguments, 2)); // 187 return Spacebars.dot.apply(null, argsForRecurse); // 188 } // 189 // 190 if (typeof value === 'function') // 191 value = value(); // 192 // 193 if (! value) // 194 return value; // falsy, don't index, pass through // 195 // 196 var result = value[id1]; // 197 if (typeof result !== 'function') // 198 return result; // 199 // `value[id1]` (or `value()[id1]`) is a function. // 200 // Bind it so that when called, `value` will be placed in `this`. // 201 return function (/*arguments*/) { // 202 return result.apply(value, arguments); // 203 }; // 204 }; // 205 // 206 // Spacebars.With implements the conditional logic of rendering // 207 // the `{{else}}` block if the argument is falsy. It combines // 208 // a Blaze.If with a Blaze.With (the latter only in the truthy // 209 // case, since the else block is evaluated without entering // 210 // a new data context). // 211 Spacebars.With = function (argFunc, contentFunc, elseFunc) { // 212 var argVar = new Blaze.ReactiveVar; // 213 var view = Blaze.View('Spacebars_with', function () { // 214 return Blaze.If(function () { return argVar.get(); }, // 215 function () { return Blaze.With(function () { // 216 return argVar.get(); }, contentFunc); }, // 217 elseFunc); // 218 }); // 219 view.onViewCreated(function () { // 220 this.autorun(function () { // 221 argVar.set(argFunc()); // 222 // 223 // This is a hack so that autoruns inside the body // 224 // of the #with get stopped sooner. It reaches inside // 225 // our ReactiveVar to access its dep. // 226 // 227 Tracker.onInvalidate(function () { // 228 argVar.dep.changed(); // 229 }); // 230 // 231 // Take the case of `{{#with A}}{{B}}{{/with}}`. The goal // 232 // is to not re-render `B` if `A` changes to become falsy // 233 // and `B` is simultaneously invalidated. // 234 // // 235 // A series of autoruns are involved: // 236 // // 237 // 1. This autorun (argument to Spacebars.With) // 238 // 2. Argument to Blaze.If // 239 // 3. Blaze.If view re-render // 240 // 4. Argument to Blaze.With // 241 // 5. The template tag `{{B}}` // 242 // // 243 // When (3) is invalidated, it immediately stops (4) and (5) // 244 // because of a Tracker.onInvalidate built into materializeView. // 245 // (When a View's render method is invalidated, it immediately // 246 // tears down all the subviews, via a Tracker.onInvalidate much // 247 // like this one. // 248 // // 249 // Suppose `A` changes to become falsy, and `B` changes at the // 250 // same time (i.e. without an intervening flush). // 251 // Without the code above, this happens: // 252 // // 253 // - (1) and (5) are invalidated. // 254 // - (1) runs, invalidating (2) and (4). // 255 // - (5) runs. // 256 // - (2) runs, invalidating (3), stopping (4) and (5). // 257 // // 258 // With the code above: // 259 // // 260 // - (1) and (5) are invalidated, invalidating (2) and (4). // 261 // - (1) runs. // 262 // - (2) runs, invalidating (3), stopping (4) and (5). // 263 // // 264 // If the re-run of (5) is originally enqueued before (1), all // 265 // bets are off, but typically that doesn't seem to be the // 266 // case. Anyway, doing this is always better than not doing it, // 267 // because it might save a bunch of DOM from being updated // 268 // needlessly. // 269 }); // 270 }); // 271 // 272 return view; // 273 }; // 274 // 275 // XXX COMPAT WITH 0.9.0 // 276 Spacebars.TemplateWith = Blaze._TemplateWith; // 277 // 278 ///////////////////////////////////////////////////////////////////////////////////////////////////////// }).call(this); (function () { ///////////////////////////////////////////////////////////////////////////////////////////////////////// // // // packages/spacebars/template.dynamic.js // // // ///////////////////////////////////////////////////////////////////////////////////////////////////////// // // 1 Template.__checkName("__dynamic"); // 2 Template["__dynamic"] = new Template("Template.__dynamic", (function() { // 3 var view = this; // 4 return [ Blaze.View("lookup:checkContext", function() { // 5 return Spacebars.mustache(view.lookup("checkContext")); // 6 }), "\n ", Blaze.If(function() { // 7 return Spacebars.call(view.lookup("dataContextPresent")); // 8 }, function() { // 9 return [ "\n ", Spacebars.include(view.lookupTemplate("__dynamicWithDataContext")), "\n " ]; // 10 }, function() { // 11 return [ "\n \n ", Blaze._TemplateWith(function() { // 12 return { // 13 template: Spacebars.call(view.lookup("template")), // 14 data: Spacebars.call(view.lookup("..")) // 15 }; // 16 }, function() { // 17 return Spacebars.include(view.lookupTemplate("__dynamicWithDataContext")); // 18 }), "\n " ]; // 19 }) ]; // 20 })); // 21 // 22 Template.__checkName("__dynamicWithDataContext"); // 23 Template["__dynamicWithDataContext"] = new Template("Template.__dynamicWithDataContext", (function() { // 24 var view = this; // 25 return Spacebars.With(function() { // 26 return Spacebars.dataMustache(view.lookup("chooseTemplate"), view.lookup("template")); // 27 }, function() { // 28 return [ "\n ", Blaze._TemplateWith(function() { // 29 return Spacebars.call(Spacebars.dot(view.lookup(".."), "data")); // 30 }, function() { // 31 return Spacebars.include(view.lookupTemplate("..")); // 32 }), " \n " ]; // 33 }); // 34 })); // 35 // 36 ///////////////////////////////////////////////////////////////////////////////////////////////////////// }).call(this); (function () { ///////////////////////////////////////////////////////////////////////////////////////////////////////// // // // packages/spacebars/dynamic.js // // // ///////////////////////////////////////////////////////////////////////////////////////////////////////// // /** // 1 * @isTemplate true // 2 * @memberOf Template // 3 * @function dynamic // 4 * @summary Choose a template to include dynamically, by name. // 5 * @locus Templates // 6 * @param {String} template The name of the template to include. // 7 * @param {Object} [data] Optional. The data context in which to include the template. // 8 */ // 9 // 10 Template.__dynamicWithDataContext.helpers({ // 11 chooseTemplate: function (name) { // 12 return Template[name] || null; // 13 } // 14 }); // 15 // 16 Template.__dynamic.helpers({ // 17 dataContextPresent: function () { // 18 return _.has(this, "data"); // 19 }, // 20 checkContext: function () { // 21 if (! _.has(this, "template")) { // 22 throw new Error("Must specify name in the 'template' argument " + // 23 "to {{> Template.dynamic}}."); // 24 } // 25 // 26 _.each(this, function (v, k) { // 27 if (k !== "template" && k !== "data") { // 28 throw new Error("Invalid argument to {{> Template.dynamic}}: " + // 29 k); // 30 } // 31 }); // 32 } // 33 }); // 34 // 35 ///////////////////////////////////////////////////////////////////////////////////////////////////////// }).call(this); /* Exports */ if (typeof Package === 'undefined') Package = {}; Package.spacebars = { Spacebars: Spacebars }; })();