dist/ember-template-compiler.js in ember-source-1.11.0.beta.1 vs dist/ember-template-compiler.js in ember-source-1.11.0.beta.2

- old
+ new

@@ -3,11 +3,11 @@ * @copyright Copyright 2011-2015 Tilde Inc. and contributors * Portions Copyright 2006-2011 Strobe Inc. * Portions Copyright 2008-2011 Apple Inc. All rights reserved. * @license Licensed under MIT license * See https://raw.github.com/emberjs/ember.js/master/LICENSE - * @version 1.11.0-beta.1 + * @version 1.11.0-beta.2 */ (function() { var enifed, requireModule, eriuqer, requirejs, Ember; var mainContext = this; @@ -131,11 +131,11 @@ The core Runtime framework is based on the jQuery API with a number of performance optimizations. @class Ember @static - @version 1.11.0-beta.1 + @version 1.11.0-beta.2 */ if ('undefined' === typeof Ember) { // Create core object. Make it act like an instance of Ember.Namespace so that // objects assigned to it are given a sane string representation. @@ -159,14 +159,14 @@ /** @property VERSION @type String - @default '1.11.0-beta.1' + @default '1.11.0-beta.2' @static */ - Ember.VERSION = '1.11.0-beta.1'; + Ember.VERSION = '1.11.0-beta.2'; /** Standard environmental variables. You can define these in a global `EmberENV` variable before loading Ember to control various configuration settings. @@ -207,11 +207,11 @@ */ Ember.FEATURES = Ember.ENV.FEATURES; if (!Ember.FEATURES) { - Ember.FEATURES = {"features-stripped-test":null,"ember-routing-named-substates":true,"ember-metal-injected-properties":true,"mandatory-setter":true,"ember-htmlbars":true,"ember-htmlbars-block-params":true,"ember-htmlbars-component-generation":null,"ember-htmlbars-component-helper":true,"ember-htmlbars-inline-if-helper":true,"ember-htmlbars-attribute-syntax":true,"ember-routing-transitioning-classes":true,"new-computed-syntax":null,"ember-testing-checkbox-helpers":null,"ember-metal-stream":null,"ember-htmlbars-each-with-index":true,"ember-application-instance-initializers":null,"ember-application-initializer-context":null,"ember-router-willtransition":true,"ember-application-visit":null}; //jshint ignore:line + Ember.FEATURES = {"features-stripped-test":false,"ember-routing-named-substates":true,"mandatory-setter":true,"ember-htmlbars-component-generation":false,"ember-htmlbars-component-helper":true,"ember-htmlbars-inline-if-helper":true,"ember-htmlbars-attribute-syntax":true,"ember-routing-transitioning-classes":true,"new-computed-syntax":false,"ember-testing-checkbox-helpers":false,"ember-metal-stream":false,"ember-htmlbars-each-with-index":true,"ember-application-instance-initializers":false,"ember-application-initializer-context":false,"ember-router-willtransition":true,"ember-application-visit":false}; //jshint ignore:line } /** Test that a feature is enabled. Parsed by Ember's build tools to leave experimental features out of beta/stable builds. @@ -343,19 +343,18 @@ EmberHandlebars.precompile = precompile['default']; EmberHandlebars.compile = compile['default']; EmberHandlebars.template = template['default']; }); -enifed('ember-template-compiler/compat/precompile', ['exports'], function (exports) { +enifed('ember-template-compiler/compat/precompile', ['exports', 'ember-template-compiler/system/compile_options'], function (exports, compileOptions) { 'use strict'; /** @module ember @submodule ember-template-compiler */ - var compile, compileSpec; exports['default'] = function(string) { if ((!compile || !compileSpec) && Ember.__loader.registry['htmlbars-compiler/compiler']) { var Compiler = requireModule('htmlbars-compiler/compiler'); @@ -369,11 +368,11 @@ } var asObject = arguments[1] === undefined ? true : arguments[1]; var compileFunc = asObject ? compile : compileSpec; - return compileFunc(string); + return compileFunc(string, compileOptions['default']()); } }); enifed('ember-template-compiler/plugins', ['exports'], function (exports) { @@ -592,15 +591,14 @@ @submodule ember-template-compiler */ exports['default'] = function() { var disableComponentGeneration = true; - if (Ember['default'].FEATURES.isEnabled('ember-htmlbars-component-generation')) { - disableComponentGeneration = false; - } - + return { + revision: 'Ember@1.11.0-beta.2', + disableComponentGeneration: disableComponentGeneration, plugins: plugins['default'] }; } @@ -669,24 +667,57 @@ enifed("htmlbars-compiler", ["./htmlbars-compiler/compiler","exports"], function(__dependency1__, __exports__) { "use strict"; var compile = __dependency1__.compile; - var compilerSpec = __dependency1__.compilerSpec; + var compileSpec = __dependency1__.compileSpec; + var template = __dependency1__.template; __exports__.compile = compile; - __exports__.compilerSpec = compilerSpec; + __exports__.compileSpec = compileSpec; + __exports__.template = template; }); enifed("htmlbars-compiler/compiler", ["../htmlbars-syntax/parser","./template-compiler","exports"], function(__dependency1__, __dependency2__, __exports__) { "use strict"; /*jshint evil:true*/ var preprocess = __dependency1__.preprocess; var TemplateCompiler = __dependency2__["default"]; /* + * Compile a string into a template spec string. The template spec is a string + * representation of a template. Usually, you would use compileSpec for + * pre-compilation of a template on the server. + * + * Example usage: + * + * var templateSpec = compileSpec("Howdy {{name}}"); + * // This next step is basically what plain compile does + * var template = new Function("return " + templateSpec)(); + * + * @method compileSpec + * @param {String} string An HTMLBars template string + * @return {TemplateSpec} A template spec string + */ + function compileSpec(string, options) { + var ast = preprocess(string, options); + var compiler = new TemplateCompiler(options); + var program = compiler.compile(ast); + return program; + } + + __exports__.compileSpec = compileSpec;/* + * @method template + * @param {TemplateSpec} templateSpec A precompiled template + * @return {Template} A template spec string + */ + function template(templateSpec) { + return new Function("return " + templateSpec)(); + } + + __exports__.template = template;/* * Compile a string into a template rendering function * * Example usage: * * // Template is the hydration portion of the compiled template @@ -709,17 +740,16 @@ * env = {hooks: hooks, dom: new DOMHelper()}, * contextualElement = document.body; * var domFragment = template(context, env, contextualElement); * * @method compile - * @param {String} string An htmlbars template string + * @param {String} string An HTMLBars template string * @param {Object} options A set of options to provide to the compiler - * @return {Function} A function for rendering the template + * @return {Template} A function for rendering the template */ function compile(string, options) { - var program = compileSpec(string, options); - return new Function("return " + program)(); + return template(compileSpec(string, options)); } __exports__.compile = compile;/* * Compile a string into a template spec string. The template spec is a string * representation of a template. Usually, you would use compileSpec for @@ -740,11 +770,15 @@ var compiler = new TemplateCompiler(options); var program = compiler.compile(ast); return program; } - __exports__.compileSpec = compileSpec; + __exports__.compileSpec = compileSpec;function template(program) { + return new Function("return " + program)(); + } + + __exports__.template = template; }); enifed("htmlbars-compiler/fragment-javascript-compiler", ["./utils","../htmlbars-util/quoting","exports"], function(__dependency1__, __dependency2__, __exports__) { "use strict"; @@ -873,51 +907,58 @@ FragmentOpcodeCompiler.prototype.opcode = function(type, params) { this.opcodes.push([type, params]); }; - FragmentOpcodeCompiler.prototype.text = function(text, childIndex, childCount, isSingleRoot) { + FragmentOpcodeCompiler.prototype.text = function(text) { this.opcode('createText', [text.chars]); - if (!isSingleRoot) { this.opcode('appendChild'); } + this.opcode('appendChild'); }; - FragmentOpcodeCompiler.prototype.comment = function(comment, childIndex, childCount, isSingleRoot) { + FragmentOpcodeCompiler.prototype.comment = function(comment) { this.opcode('createComment', [comment.value]); - if (!isSingleRoot) { this.opcode('appendChild'); } + this.opcode('appendChild'); }; FragmentOpcodeCompiler.prototype.openElement = function(element) { this.opcode('createElement', [element.tag]); forEach(element.attributes, this.attribute, this); }; - FragmentOpcodeCompiler.prototype.closeElement = function(element, childIndex, childCount, isSingleRoot) { - if (!isSingleRoot) { this.opcode('appendChild'); } + FragmentOpcodeCompiler.prototype.closeElement = function() { + this.opcode('appendChild'); }; - FragmentOpcodeCompiler.prototype.startProgram = function(program) { + FragmentOpcodeCompiler.prototype.startProgram = function() { this.opcodes.length = 0; - if (program.body.length !== 1) { - this.opcode('createFragment'); - } + this.opcode('createFragment'); }; - FragmentOpcodeCompiler.prototype.endProgram = function(/* program */) { + FragmentOpcodeCompiler.prototype.endProgram = function() { this.opcode('returnNode'); }; - FragmentOpcodeCompiler.prototype.mustache = function () {}; + FragmentOpcodeCompiler.prototype.mustache = function() { + this.pushMorphPlaceholderNode(); + }; - FragmentOpcodeCompiler.prototype.component = function () {}; + FragmentOpcodeCompiler.prototype.component = function() { + this.pushMorphPlaceholderNode(); + }; - FragmentOpcodeCompiler.prototype.block = function () {}; + FragmentOpcodeCompiler.prototype.block = function() { + this.pushMorphPlaceholderNode(); + }; + FragmentOpcodeCompiler.prototype.pushMorphPlaceholderNode = function() { + this.opcode('createComment', [""]); + this.opcode('appendChild'); + }; + FragmentOpcodeCompiler.prototype.attribute = function(attr) { if (attr.value.type === 'TextNode') { - var namespace = getAttrNamespace(attr.name); - this.opcode('setAttribute', [attr.name, attr.value.chars, namespace]); } }; FragmentOpcodeCompiler.prototype.setNamespace = function(namespace) { @@ -956,13 +997,23 @@ this.morphs.length = 0; this.fragmentProcessing.length = 0; this.parentCount = 0; this.indent = (options && options.indent) || ""; this.hooks = {}; + this.hasOpenBoundary = false; + this.hasCloseBoundary = false; processOpcodes(this, opcodes); + if (this.hasOpenBoundary) { + this.source.unshift(this.indent+" dom.insertBoundary(fragment, 0);\n"); + } + + if (this.hasCloseBoundary) { + this.source.unshift(this.indent+" dom.insertBoundary(fragment, null);\n"); + } + var i, l; if (this.morphs.length) { var morphs = ""; for (i = 0, l = this.morphs.length; i < l; ++i) { var morph = this.morphs[i]; @@ -1004,10 +1055,18 @@ prototype.pushRaw = function(value) { this.stack.push(value); }; + prototype.openBoundary = function() { + this.hasOpenBoundary = true; + }; + + prototype.closeBoundary = function() { + this.hasCloseBoundary = true; + }; + prototype.pushLiteral = function(value) { if (typeof value === 'string') { this.stack.push(string(value)); } else { this.stack.push(value.toString()); @@ -1262,37 +1321,36 @@ if (blankChildTextNodes.length > 0) { this.opcode('repairClonedNode', blankChildTextNodes); } }; - HydrationOpcodeCompiler.prototype.endProgram = function(/* program */) { + HydrationOpcodeCompiler.prototype.endProgram = function() { distributeMorphs(this.morphs, this.opcodes); }; - HydrationOpcodeCompiler.prototype.text = function(/* string, pos, len */) { + HydrationOpcodeCompiler.prototype.text = function() { ++this.currentDOMChildIndex; }; - HydrationOpcodeCompiler.prototype.comment = function(/* string, pos, len */) { + HydrationOpcodeCompiler.prototype.comment = function() { ++this.currentDOMChildIndex; }; - HydrationOpcodeCompiler.prototype.openElement = function(element, pos, len, isSingleRoot, mustacheCount, blankChildTextNodes) { + HydrationOpcodeCompiler.prototype.openElement = function(element, pos, len, mustacheCount, blankChildTextNodes) { distributeMorphs(this.morphs, this.opcodes); ++this.currentDOMChildIndex; this.element = this.currentDOMChildIndex; - if (!isSingleRoot) { - this.opcode('consumeParent', this.currentDOMChildIndex); + this.opcode('consumeParent', this.currentDOMChildIndex); - // If our parent reference will be used more than once, cache its reference. - if (mustacheCount > 1) { - this.opcode('shareElement', ++this.elementNum); - this.element = null; // Set element to null so we don't cache it twice - } + // If our parent reference will be used more than once, cache its reference. + if (mustacheCount > 1) { + this.opcode('shareElement', ++this.elementNum); + this.element = null; // Set element to null so we don't cache it twice } + var isElementChecked = detectIsElementChecked(element); if (blankChildTextNodes.length > 0 || isElementChecked) { this.opcode( 'repairClonedNode', blankChildTextNodes, isElementChecked ); @@ -1303,42 +1361,61 @@ forEach(element.attributes, this.attribute, this); forEach(element.helpers, this.elementHelper, this); }; - HydrationOpcodeCompiler.prototype.closeElement = function(element, pos, len, isSingleRoot) { + HydrationOpcodeCompiler.prototype.closeElement = function() { distributeMorphs(this.morphs, this.opcodes); - if (!isSingleRoot) { this.opcode('popParent'); } + this.opcode('popParent'); this.currentDOMChildIndex = this.paths.pop(); }; - HydrationOpcodeCompiler.prototype.block = function(block, childIndex, childrenLength) { - var sexpr = block.sexpr; + HydrationOpcodeCompiler.prototype.mustache = function(mustache, childIndex, childCount) { + this.pushMorphPlaceholderNode(childIndex, childCount); + + var sexpr = mustache.sexpr; - var currentDOMChildIndex = this.currentDOMChildIndex; - var start = (currentDOMChildIndex < 0) ? null : currentDOMChildIndex; - var end = (childIndex === childrenLength - 1) ? null : currentDOMChildIndex + 1; + var morphNum = this.morphNum++; + var start = this.currentDOMChildIndex; + var end = this.currentDOMChildIndex; + this.morphs.push([morphNum, this.paths.slice(), start, end, mustache.escaped]); + if (isHelper(sexpr)) { + prepareSexpr(this, sexpr); + this.opcode('printInlineHook', morphNum); + } else { + preparePath(this, sexpr.path); + this.opcode('printContentHook', morphNum); + } + }; + + HydrationOpcodeCompiler.prototype.block = function(block, childIndex, childCount) { + this.pushMorphPlaceholderNode(childIndex, childCount); + + var sexpr = block.sexpr; + var morphNum = this.morphNum++; + var start = this.currentDOMChildIndex; + var end = this.currentDOMChildIndex; this.morphs.push([morphNum, this.paths.slice(), start, end, true]); var templateId = this.templateId++; var inverseId = block.inverse === null ? null : this.templateId++; prepareSexpr(this, sexpr); this.opcode('printBlockHook', morphNum, templateId, inverseId); }; - HydrationOpcodeCompiler.prototype.component = function(component, childIndex, childrenLength) { - var currentDOMChildIndex = this.currentDOMChildIndex; + HydrationOpcodeCompiler.prototype.component = function(component, childIndex, childCount) { + this.pushMorphPlaceholderNode(childIndex, childCount); + var program = component.program || {}; var blockParams = program.blockParams || []; - var start = (currentDOMChildIndex < 0 ? null : currentDOMChildIndex), - end = (childIndex === childrenLength - 1 ? null : currentDOMChildIndex + 1); - var morphNum = this.morphNum++; + var start = this.currentDOMChildIndex; + var end = this.currentDOMChildIndex; this.morphs.push([morphNum, this.paths.slice(), start, end, true]); var attrs = component.attributes; for (var i = attrs.length - 1; i >= 0; i--) { var name = attrs[i].name; @@ -1400,27 +1477,20 @@ } this.opcode('printElementHook', this.elementNum); }; - HydrationOpcodeCompiler.prototype.mustache = function(mustache, childIndex, childrenLength) { - var sexpr = mustache.sexpr; - var currentDOMChildIndex = this.currentDOMChildIndex; - - var start = currentDOMChildIndex, - end = (childIndex === childrenLength - 1 ? -1 : currentDOMChildIndex + 1); - - var morphNum = this.morphNum++; - this.morphs.push([morphNum, this.paths.slice(), start, end, mustache.escaped]); - - if (isHelper(sexpr)) { - prepareSexpr(this, sexpr); - this.opcode('printInlineHook', morphNum); - } else { - preparePath(this, sexpr.path); - this.opcode('printContentHook', morphNum); + HydrationOpcodeCompiler.prototype.pushMorphPlaceholderNode = function(childIndex, childCount) { + if (this.paths.length === 0) { + if (childIndex === 0) { + this.opcode('openBoundary'); + } + if (childIndex === childCount - 1) { + this.opcode('closeBoundary'); + } } + this.comment(); }; HydrationOpcodeCompiler.prototype.SubExpression = function(sexpr) { prepareSexpr(this, sexpr); this.opcode('pushSexprHook'); @@ -1509,10 +1579,11 @@ var processOpcodes = __dependency6__.processOpcodes; var repeat = __dependency7__.repeat; function TemplateCompiler(options) { this.options = options || {}; + this.revision = this.options.revision || "HTMLBars@v0.11.1"; this.fragmentOpcodeCompiler = new FragmentOpcodeCompiler(); this.fragmentCompiler = new FragmentJavaScriptCompiler(); this.hydrationOpcodeCompiler = new HydrationOpcodeCompiler(); this.hydrationCompiler = new HydrationJavaScriptCompiler(); this.templates = []; @@ -1594,10 +1665,11 @@ var template = '(function() {\n' + this.getChildTemplateVars(indent + ' ') + indent+' return {\n' + indent+' isHTMLBars: true,\n' + + indent+' revision: "' + this.revision + '",\n' + indent+' blockParams: ' + blockParams.length + ',\n' + indent+' cachedFragment: null,\n' + indent+' hasRendered: false,\n' + indent+' build: ' + fragmentProgram + ',\n' + indent+' render: function render(' + templateSignature + ') {\n' + @@ -1637,18 +1709,18 @@ TemplateCompiler.prototype.closeElement = function(element, i, l, r) { this.fragmentOpcodeCompiler.closeElement(element, i, l, r); this.hydrationOpcodeCompiler.closeElement(element, i, l, r); }; - TemplateCompiler.prototype.component = function(component, i, l) { - this.fragmentOpcodeCompiler.component(component, i, l); - this.hydrationOpcodeCompiler.component(component, i, l); + TemplateCompiler.prototype.component = function(component, i, l, s) { + this.fragmentOpcodeCompiler.component(component, i, l, s); + this.hydrationOpcodeCompiler.component(component, i, l, s); }; - TemplateCompiler.prototype.block = function(block, i, l) { - this.fragmentOpcodeCompiler.block(block, i, l); - this.hydrationOpcodeCompiler.block(block, i, l); + TemplateCompiler.prototype.block = function(block, i, l, s) { + this.fragmentOpcodeCompiler.block(block, i, l, s); + this.hydrationOpcodeCompiler.block(block, i, l, s); }; TemplateCompiler.prototype.text = function(string, i, l, r) { this.fragmentOpcodeCompiler.text(string, i, l, r); this.hydrationOpcodeCompiler.text(string, i, l, r); @@ -1657,13 +1729,13 @@ TemplateCompiler.prototype.comment = function(string, i, l, r) { this.fragmentOpcodeCompiler.comment(string, i, l, r); this.hydrationOpcodeCompiler.comment(string, i, l, r); }; - TemplateCompiler.prototype.mustache = function (mustache, i, l) { - this.fragmentOpcodeCompiler.mustache(mustache, i, l); - this.hydrationOpcodeCompiler.mustache(mustache, i, l); + TemplateCompiler.prototype.mustache = function (mustache, i, l, s) { + this.fragmentOpcodeCompiler.mustache(mustache, i, l, s); + this.hydrationOpcodeCompiler.mustache(mustache, i, l, s); }; TemplateCompiler.prototype.setNamespace = function(namespace) { this.fragmentOpcodeCompiler.setNamespace(namespace); }; @@ -1777,23 +1849,21 @@ }; TemplateVisitor.prototype.ElementNode = function(element) { var parentFrame = this.getCurrentFrame(); var elementFrame = this.pushFrame(); - var parentNode = parentFrame.parentNode; elementFrame.parentNode = element; elementFrame.children = element.children; elementFrame.childCount = element.children.length; elementFrame.mustacheCount += element.helpers.length; elementFrame.blankChildTextNodes = []; var actionArgs = [ element, parentFrame.childIndex, - parentFrame.childCount, - parentNode.type === 'Program' && parentFrame.childCount === 1 + parentFrame.childCount ]; elementFrame.actions.push(['closeElement', actionArgs]); for (var i = element.attributes.length - 1; i >= 0; i--) { @@ -1821,15 +1891,14 @@ } }; TemplateVisitor.prototype.TextNode = function(text) { var frame = this.getCurrentFrame(); - var isSingleRoot = frame.parentNode.type === 'Program' && frame.childCount === 1; if (text.chars === '') { frame.blankChildTextNodes.push(domIndexOf(frame.children, text)); } - frame.actions.push(['text', [text, frame.childIndex, frame.childCount, isSingleRoot]]); + frame.actions.push(['text', [text, frame.childIndex, frame.childCount]]); }; TemplateVisitor.prototype.BlockStatement = function(node) { var frame = this.getCurrentFrame(); @@ -1856,13 +1925,11 @@ frame.actions.push(['mustache', [node, frame.childIndex, frame.childCount]]); }; TemplateVisitor.prototype.CommentStatement = function(text) { var frame = this.getCurrentFrame(); - var isSingleRoot = frame.parentNode.type === 'Program' && frame.childCount === 1; - - frame.actions.push(['comment', [text, frame.childIndex, frame.childCount, isSingleRoot]]); + frame.actions.push(['comment', [text, frame.childIndex, frame.childCount]]); }; TemplateVisitor.prototype.MustacheStatement = function(mustache) { var frame = this.getCurrentFrame(); frame.mustacheCount++; @@ -1926,10 +1993,163 @@ } } __exports__.processOpcodes = processOpcodes; }); +enifed("htmlbars-runtime", + ["htmlbars-runtime/hooks","htmlbars-runtime/helpers","exports"], + function(__dependency1__, __dependency2__, __exports__) { + "use strict"; + var hooks = __dependency1__["default"]; + var helpers = __dependency2__["default"]; + + __exports__.hooks = hooks; + __exports__.helpers = helpers; + }); +enifed("htmlbars-runtime/helpers", + ["exports"], + function(__exports__) { + "use strict"; + function partial(params, hash, options, env) { + var template = env.partials[params[0]]; + return template.render(this, env, options.morph.contextualElement); + } + + __exports__.partial = partial;__exports__["default"] = { + partial: partial + }; + }); +enifed("htmlbars-runtime/hooks", + ["exports"], + function(__exports__) { + "use strict"; + function block(env, morph, context, path, params, hash, template, inverse) { + var options = { + morph: morph, + template: template, + inverse: inverse + }; + + var helper = lookupHelper(env, context, path); + var value = helper.call(context, params, hash, options, env); + + morph.setContent(value); + } + + __exports__.block = block;function inline(env, morph, context, path, params, hash) { + var helper = lookupHelper(env, context, path); + var value = helper.call(context, params, hash, { morph: morph }, env); + + morph.setContent(value); + } + + __exports__.inline = inline;function content(env, morph, context, path) { + var helper = lookupHelper(env, context, path); + + var value; + if (helper) { + value = helper.call(context, [], {}, { morph: morph }, env); + } else { + value = get(env, context, path); + } + + morph.setContent(value); + } + + __exports__.content = content;function element(env, domElement, context, path, params, hash) { + var helper = lookupHelper(env, context, path); + if (helper) { + helper.call(context, params, hash, { element: domElement }, env); + } + } + + __exports__.element = element;function attribute(env, attrMorph, domElement, name, value) { + attrMorph.setContent(value); + } + + __exports__.attribute = attribute;function subexpr(env, context, helperName, params, hash) { + var helper = lookupHelper(env, context, helperName); + if (helper) { + return helper.call(context, params, hash, {}, env); + } else { + return get(env, context, helperName); + } + } + + __exports__.subexpr = subexpr;function get(env, context, path) { + if (path === '') { + return context; + } + + var keys = path.split('.'); + var value = context; + for (var i = 0; i < keys.length; i++) { + if (value) { + value = value[keys[i]]; + } else { + break; + } + } + return value; + } + + __exports__.get = get;function set(env, context, name, value) { + context[name] = value; + } + + __exports__.set = set;function component(env, morph, context, tagName, attrs, template) { + var helper = lookupHelper(env, context, tagName); + + var value; + if (helper) { + var options = { + morph: morph, + template: template + }; + + value = helper.call(context, [], attrs, options, env); + } else { + value = componentFallback(env, morph, context, tagName, attrs, template); + } + + morph.setContent(value); + } + + __exports__.component = component;function concat(env, params) { + var value = ""; + for (var i = 0, l = params.length; i < l; i++) { + value += params[i]; + } + return value; + } + + __exports__.concat = concat;function componentFallback(env, morph, context, tagName, attrs, template) { + var element = env.dom.createElement(tagName); + for (var name in attrs) { + element.setAttribute(name, attrs[name]); + } + element.appendChild(template.render(context, env, morph.contextualElement)); + return element; + } + + function lookupHelper(env, context, helperName) { + return env.helpers[helperName]; + } + + __exports__["default"] = { + content: content, + block: block, + inline: inline, + component: component, + element: element, + attribute: attribute, + subexpr: subexpr, + concat: concat, + get: get, + set: set + }; + }); enifed("htmlbars-syntax", ["./htmlbars-syntax/walker","./htmlbars-syntax/builders","./htmlbars-syntax/parser","exports"], function(__dependency1__, __dependency2__, __dependency3__, __exports__) { "use strict"; var Walker = __dependency1__["default"]; @@ -3354,11 +3574,10 @@ var buildProgram = __dependency1__.buildProgram; var buildBlock = __dependency1__.buildBlock; var buildHash = __dependency1__.buildHash; var forEach = __dependency2__.forEach; var appendChild = __dependency3__.appendChild; - var postprocessProgram = __dependency3__.postprocessProgram; var nodeHandlers = { Program: function(program) { var body = []; @@ -3373,12 +3592,10 @@ this.acceptNode(program.body[i]); } this.acceptToken(this.tokenizer.tokenizeEOF()); - postprocessProgram(node); - // Ensure that that the element stack is balanced properly. var poppedNode = this.elementStack.pop(); if (poppedNode !== node) { throw new Error("Unclosed element `" + poppedNode.tag + "` (on line " + poppedNode.loc.start.line + ")."); } @@ -3630,11 +3847,10 @@ var buildElement = __dependency2__.buildElement; var buildComment = __dependency2__.buildComment; var buildText = __dependency2__.buildText; var appendChild = __dependency3__.appendChild; var parseComponentBlockParams = __dependency3__.parseComponentBlockParams; - var postprocessProgram = __dependency3__.postprocessProgram; // The HTML elements in this list are speced by // http://www.w3.org/TR/html-markup/syntax.html#syntax-elements, // and will be forced to close regardless of if they have a // self-closing /> at the end. @@ -3733,11 +3949,10 @@ if (disableComponentGeneration || element.tag.indexOf("-") === -1) { appendChild(parent, element); } else { var program = buildProgram(element.children); parseComponentBlockParams(element, program); - postprocessProgram(program); var component = buildComponent(element.tag, element.attributes, program); appendChild(parent, component); } } @@ -3870,15 +4085,14 @@ } __exports__.unwrapMustache = unwrapMustache;__exports__.Tokenizer = Tokenizer; }); enifed("htmlbars-syntax/utils", - ["./builders","../htmlbars-util/array-utils","exports"], - function(__dependency1__, __dependency2__, __exports__) { + ["../htmlbars-util/array-utils","exports"], + function(__dependency1__, __exports__) { "use strict"; - var buildText = __dependency1__.buildText; - var indexOfArray = __dependency2__.indexOfArray; + var indexOfArray = __dependency1__.indexOfArray; // Regex to validate the identifier for block parameters. // Based on the ID validation regex in Handlebars. var ID_INVERSE_PATTERN = /[!"#%-,\.\/;->@\[-\^`\{-~]/; @@ -3921,54 +4135,20 @@ element.attributes = element.attributes.slice(0, asIndex); program.blockParams = params; } } - __exports__.parseComponentBlockParams = parseComponentBlockParams;// Adds an empty text node at the beginning and end of a program. - // The empty text nodes *between* nodes are handled elsewhere. - - function postprocessProgram(program) { - var body = program.body; - - if (body.length === 0) { - return; - } - - if (usesMorph(body[0])) { - body.unshift(buildText('')); - } - - if (usesMorph(body[body.length-1])) { - body.push(buildText('')); - } - } - - __exports__.postprocessProgram = postprocessProgram;function childrenFor(node) { + __exports__.parseComponentBlockParams = parseComponentBlockParams;function childrenFor(node) { if (node.type === 'Program') { return node.body; } if (node.type === 'ElementNode') { return node.children; } } - __exports__.childrenFor = childrenFor;function usesMorph(node) { - return node.type === 'MustacheStatement' || - node.type === 'BlockStatement' || - node.type === 'ComponentNode'; - } - - __exports__.usesMorph = usesMorph;function appendChild(parent, node) { - var children = childrenFor(parent); - - var len = children.length, last; - if (len > 0) { - last = children[len-1]; - if (usesMorph(last) && usesMorph(node)) { - children.push(buildText('')); - } - } - children.push(node); + __exports__.childrenFor = childrenFor;function appendChild(parent, node) { + childrenFor(parent).push(node); } __exports__.appendChild = appendChild;function isHelper(sexpr) { return (sexpr.params && sexpr.params.length > 0) || (sexpr.hash && sexpr.hash.pairs.length > 0); \ No newline at end of file