UNPKG

ember-introjs

Version:
1,425 lines (1,171 loc) 634 kB
(function() { /*! * @overview Ember - JavaScript Application Framework * @copyright Copyright 2011-2018 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 3.0.0 */ /*globals process */ var enifed, requireModule, Ember; // Used in ember-environment/lib/global.js mainContext = this; // eslint-disable-line no-undef (function() { function missingModule(name, referrerName) { if (referrerName) { throw new Error('Could not find module ' + name + ' required by: ' + referrerName); } else { throw new Error('Could not find module ' + name); } } function internalRequire(_name, referrerName) { var name = _name; var mod = registry[name]; if (!mod) { name = name + '/index'; mod = registry[name]; } var exports = seen[name]; if (exports !== undefined) { return exports; } exports = seen[name] = {}; if (!mod) { missingModule(_name, referrerName); } var deps = mod.deps; var callback = mod.callback; var reified = new Array(deps.length); for (var i = 0; i < deps.length; i++) { if (deps[i] === 'exports') { reified[i] = exports; } else if (deps[i] === 'require') { reified[i] = requireModule; } else { reified[i] = internalRequire(deps[i], name); } } callback.apply(this, reified); return exports; } var isNode = typeof window === 'undefined' && typeof process !== 'undefined' && {}.toString.call(process) === '[object process]'; if (!isNode) { Ember = this.Ember = this.Ember || {}; } if (typeof Ember === 'undefined') { Ember = {}; } if (typeof Ember.__loader === 'undefined') { var registry = {}; var seen = {}; enifed = function(name, deps, callback) { var value = { }; if (!callback) { value.deps = []; value.callback = deps; } else { value.deps = deps; value.callback = callback; } registry[name] = value; }; requireModule = function(name) { return internalRequire(name, null); }; // setup `require` module requireModule['default'] = requireModule; requireModule.has = function registryHas(moduleName) { return !!registry[moduleName] || !!registry[moduleName + '/index']; }; requireModule._eak_seen = registry; Ember.__loader = { define: enifed, require: requireModule, registry: registry }; } else { enifed = Ember.__loader.define; requireModule = Ember.__loader.require; } })(); enifed('@glimmer/compiler', ['exports', 'node-module', '@glimmer/syntax', '@glimmer/util', '@glimmer/wire-format'], function (exports, _nodeModule, _syntax, _util, _wireFormat) { 'use strict'; exports.TemplateVisitor = exports.precompile = undefined; var _createClass$1 = function () { function defineProperties(target, props) { var i, descriptor; for (i = 0; i < props.length; i++) { descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false;descriptor.configurable = true;if ("value" in descriptor) descriptor.writable = true;Object.defineProperty(target, descriptor.key, descriptor); } }return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps);if (staticProps) defineProperties(Constructor, staticProps);return Constructor; }; }(); function _defaults(obj, defaults) { var keys = Object.getOwnPropertyNames(defaults), i, key, value;for (i = 0; i < keys.length; i++) { key = keys[i]; value = Object.getOwnPropertyDescriptor(defaults, key); if (value && value.configurable && obj[key] === undefined) { Object.defineProperty(obj, key, value); } }return obj; } function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); }return call && (typeof call === "object" || typeof call === "function") ? call : self; } function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); }subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } });if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : _defaults(subClass, superClass); } function _classCallCheck$1(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } var SymbolTable = function () { function SymbolTable() { _classCallCheck$1(this, SymbolTable); } SymbolTable.top = function () { return new ProgramSymbolTable(); }; SymbolTable.prototype.child = function (locals) { var _this = this; var symbols = locals.map(function (name) { return _this.allocate(name); }); return new BlockSymbolTable(this, locals, symbols); }; return SymbolTable; }(); var ProgramSymbolTable = function (_SymbolTable) { _inherits(ProgramSymbolTable, _SymbolTable); function ProgramSymbolTable() { _classCallCheck$1(this, ProgramSymbolTable); var _this2 = _possibleConstructorReturn(this, _SymbolTable.apply(this, arguments)); _this2.symbols = []; _this2.size = 1; _this2.named = (0, _util.dict)(); _this2.blocks = (0, _util.dict)(); return _this2; } ProgramSymbolTable.prototype.has = function () { return false; }; ProgramSymbolTable.prototype.get = function () { throw (0, _util.unreachable)(); }; ProgramSymbolTable.prototype.getLocalsMap = function () { return {}; }; ProgramSymbolTable.prototype.getEvalInfo = function () { return []; }; ProgramSymbolTable.prototype.allocateNamed = function (name) { var named = this.named[name]; if (!named) { named = this.named[name] = this.allocate('@' + name); } return named; }; ProgramSymbolTable.prototype.allocateBlock = function (name) { var block = this.blocks[name]; if (!block) { block = this.blocks[name] = this.allocate('&' + name); } return block; }; ProgramSymbolTable.prototype.allocate = function (identifier) { this.symbols.push(identifier); return this.size++; }; return ProgramSymbolTable; }(SymbolTable); var BlockSymbolTable = function (_SymbolTable2) { _inherits(BlockSymbolTable, _SymbolTable2); function BlockSymbolTable(parent, symbols, slots) { _classCallCheck$1(this, BlockSymbolTable); var _this3 = _possibleConstructorReturn(this, _SymbolTable2.call(this)); _this3.parent = parent; _this3.symbols = symbols; _this3.slots = slots; return _this3; } BlockSymbolTable.prototype.has = function (name) { return this.symbols.indexOf(name) !== -1 || this.parent.has(name); }; BlockSymbolTable.prototype.get = function (name) { var slot = this.symbols.indexOf(name); return slot === -1 ? this.parent.get(name) : this.slots[slot]; }; BlockSymbolTable.prototype.getLocalsMap = function () { var _this4 = this; var dict$$1 = this.parent.getLocalsMap(); this.symbols.forEach(function (symbol) { return dict$$1[symbol] = _this4.get(symbol); }); return dict$$1; }; BlockSymbolTable.prototype.getEvalInfo = function () { var locals = this.getLocalsMap(); return Object.keys(locals).map(function (symbol) { return locals[symbol]; }); }; BlockSymbolTable.prototype.allocateNamed = function (name) { return this.parent.allocateNamed(name); }; BlockSymbolTable.prototype.allocateBlock = function (name) { return this.parent.allocateBlock(name); }; BlockSymbolTable.prototype.allocate = function (identifier) { return this.parent.allocate(identifier); }; return BlockSymbolTable; }(SymbolTable); /** * Takes in an AST and outputs a list of actions to be consumed * by a compiler. For example, the template * * foo{{bar}}<div>baz</div> * * produces the actions * * [['startProgram', [programNode, 0]], * ['text', [textNode, 0, 3]], * ['mustache', [mustacheNode, 1, 3]], * ['openElement', [elementNode, 2, 3, 0]], * ['text', [textNode, 0, 1]], * ['closeElement', [elementNode, 2, 3], * ['endProgram', [programNode]]] * * This visitor walks the AST depth first and backwards. As * a result the bottom-most child template will appear at the * top of the actions list whereas the root template will appear * at the bottom of the list. For example, * * <div>{{#if}}foo{{else}}bar<b></b>{{/if}}</div> * * produces the actions * * [['startProgram', [programNode, 0]], * ['text', [textNode, 0, 2, 0]], * ['openElement', [elementNode, 1, 2, 0]], * ['closeElement', [elementNode, 1, 2]], * ['endProgram', [programNode]], * ['startProgram', [programNode, 0]], * ['text', [textNode, 0, 1]], * ['endProgram', [programNode]], * ['startProgram', [programNode, 2]], * ['openElement', [elementNode, 0, 1, 1]], * ['block', [blockNode, 0, 1]], * ['closeElement', [elementNode, 0, 1]], * ['endProgram', [programNode]]] * * The state of the traversal is maintained by a stack of frames. * Whenever a node with children is entered (either a ProgramNode * or an ElementNode) a frame is pushed onto the stack. The frame * contains information about the state of the traversal of that * node. For example, * * - index of the current child node being visited * - the number of mustaches contained within its child nodes * - the list of actions generated by its child nodes */ var Frame = function Frame() { _classCallCheck$1(this, Frame); this.parentNode = null; this.children = null; this.childIndex = null; this.childCount = null; this.childTemplateCount = 0; this.mustacheCount = 0; this.actions = []; this.blankChildTextNodes = null; this.symbols = null; }; var TemplateVisitor = function () { function TemplateVisitor() { _classCallCheck$1(this, TemplateVisitor); this.frameStack = []; this.actions = []; this.programDepth = -1; } TemplateVisitor.prototype.visit = function (node) { this[node.type](node); }; // Traversal methods TemplateVisitor.prototype.Program = function (program) { var _actions, i; this.programDepth++; var parentFrame = this.getCurrentFrame(); var programFrame = this.pushFrame(); if (!parentFrame) { program['symbols'] = SymbolTable.top(); } else { program['symbols'] = parentFrame.symbols.child(program.blockParams); } var startType = void 0, endType = void 0; if (this.programDepth === 0) { startType = 'startProgram'; endType = 'endProgram'; } else { startType = 'startBlock'; endType = 'endBlock'; } programFrame.parentNode = program; programFrame.children = program.body; programFrame.childCount = program.body.length; programFrame.blankChildTextNodes = []; programFrame.actions.push([endType, [program, this.programDepth]]); programFrame.symbols = program['symbols']; for (i = program.body.length - 1; i >= 0; i--) { programFrame.childIndex = i; this.visit(program.body[i]); } programFrame.actions.push([startType, [program, programFrame.childTemplateCount, programFrame.blankChildTextNodes.reverse()]]); this.popFrame(); this.programDepth--; // Push the completed template into the global actions list if (parentFrame) { parentFrame.childTemplateCount++; } (_actions = this.actions).push.apply(_actions, programFrame.actions.reverse()); }; TemplateVisitor.prototype.ElementNode = function (element) { var _parentFrame$actions, i, _i; var parentFrame = this.currentFrame; var elementFrame = this.pushFrame(); elementFrame.parentNode = element; elementFrame.children = element.children; elementFrame.childCount = element.children.length; elementFrame.mustacheCount += element.modifiers.length; elementFrame.blankChildTextNodes = []; elementFrame.symbols = element['symbols'] = parentFrame.symbols.child(element.blockParams); var actionArgs = [element, parentFrame.childIndex, parentFrame.childCount]; elementFrame.actions.push(['closeElement', actionArgs]); for (i = element.attributes.length - 1; i >= 0; i--) { this.visit(element.attributes[i]); } for (_i = element.children.length - 1; _i >= 0; _i--) { elementFrame.childIndex = _i; this.visit(element.children[_i]); } var open = ['openElement', [].concat(actionArgs, [elementFrame.mustacheCount, elementFrame.blankChildTextNodes.reverse()])]; elementFrame.actions.push(open); this.popFrame(); // Propagate the element's frame state to the parent frame if (elementFrame.mustacheCount > 0) { parentFrame.mustacheCount++; } parentFrame.childTemplateCount += elementFrame.childTemplateCount; (_parentFrame$actions = parentFrame.actions).push.apply(_parentFrame$actions, elementFrame.actions); }; TemplateVisitor.prototype.AttrNode = function (attr) { if (attr.value.type !== 'TextNode') { this.currentFrame.mustacheCount++; } }; TemplateVisitor.prototype.TextNode = function (text) { var frame = this.currentFrame; if (text.chars === '') { frame.blankChildTextNodes.push(domIndexOf(frame.children, text)); } frame.actions.push(['text', [text, frame.childIndex, frame.childCount]]); }; TemplateVisitor.prototype.BlockStatement = function (node) { var frame = this.currentFrame; frame.mustacheCount++; frame.actions.push(['block', [node, frame.childIndex, frame.childCount]]); if (node.inverse) { this.visit(node.inverse); } if (node.program) { this.visit(node.program); } }; TemplateVisitor.prototype.PartialStatement = function (node) { var frame = this.currentFrame; frame.mustacheCount++; frame.actions.push(['mustache', [node, frame.childIndex, frame.childCount]]); }; TemplateVisitor.prototype.CommentStatement = function (text) { var frame = this.currentFrame; frame.actions.push(['comment', [text, frame.childIndex, frame.childCount]]); }; TemplateVisitor.prototype.MustacheCommentStatement = function () { // Intentional empty: Handlebars comments should not affect output. }; TemplateVisitor.prototype.MustacheStatement = function (mustache) { var frame = this.currentFrame; frame.mustacheCount++; frame.actions.push(['mustache', [mustache, frame.childIndex, frame.childCount]]); }; // Frame helpers TemplateVisitor.prototype.getCurrentFrame = function () { return this.frameStack[this.frameStack.length - 1]; }; TemplateVisitor.prototype.pushFrame = function () { var frame = new Frame(); this.frameStack.push(frame); return frame; }; TemplateVisitor.prototype.popFrame = function () { return this.frameStack.pop(); }; _createClass$1(TemplateVisitor, [{ key: 'currentFrame', get: function () { return this.getCurrentFrame(); } }]); return TemplateVisitor; }(); function domIndexOf(nodes, domNode) { var index = -1, i, node; for (i = 0; i < nodes.length; i++) { node = nodes[i]; if (node.type !== 'TextNode' && node.type !== 'ElementNode') { continue; } else { index++; } if (node === domNode) { return index; } } return -1; } var _createClass$2 = function () { function defineProperties(target, props) { var i, descriptor; for (i = 0; i < props.length; i++) { descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false;descriptor.configurable = true;if ("value" in descriptor) descriptor.writable = true;Object.defineProperty(target, descriptor.key, descriptor); } }return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps);if (staticProps) defineProperties(Constructor, staticProps);return Constructor; }; }(); function _defaults$1(obj, defaults) { var keys = Object.getOwnPropertyNames(defaults), i, key, value;for (i = 0; i < keys.length; i++) { key = keys[i]; value = Object.getOwnPropertyDescriptor(defaults, key); if (value && value.configurable && obj[key] === undefined) { Object.defineProperty(obj, key, value); } }return obj; } function _possibleConstructorReturn$1(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); }return call && (typeof call === "object" || typeof call === "function") ? call : self; } function _inherits$1(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); }subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } });if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : _defaults$1(subClass, superClass); } function _classCallCheck$2(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } var Block = function () { function Block() { _classCallCheck$2(this, Block); this.statements = []; } Block.prototype.push = function (statement) { this.statements.push(statement); }; return Block; }(); var InlineBlock = function (_Block) { _inherits$1(InlineBlock, _Block); function InlineBlock(table) { _classCallCheck$2(this, InlineBlock); var _this = _possibleConstructorReturn$1(this, _Block.call(this)); _this.table = table; return _this; } InlineBlock.prototype.toJSON = function () { return { statements: this.statements, parameters: this.table.slots }; }; return InlineBlock; }(Block); var TemplateBlock = function (_Block2) { _inherits$1(TemplateBlock, _Block2); function TemplateBlock(symbolTable) { _classCallCheck$2(this, TemplateBlock); var _this2 = _possibleConstructorReturn$1(this, _Block2.call(this)); _this2.symbolTable = symbolTable; _this2.type = "template"; _this2.yields = new _util.DictSet(); _this2.named = new _util.DictSet(); _this2.blocks = []; _this2.hasEval = false; return _this2; } TemplateBlock.prototype.push = function (statement) { this.statements.push(statement); }; TemplateBlock.prototype.toJSON = function () { return { symbols: this.symbolTable.symbols, statements: this.statements, hasEval: this.hasEval }; }; return TemplateBlock; }(Block); var ComponentBlock = function (_Block3) { _inherits$1(ComponentBlock, _Block3); function ComponentBlock(table) { _classCallCheck$2(this, ComponentBlock); var _this3 = _possibleConstructorReturn$1(this, _Block3.call(this)); _this3.table = table; _this3.attributes = []; _this3.arguments = []; _this3.inParams = true; _this3.positionals = []; return _this3; } ComponentBlock.prototype.push = function (statement) { if (this.inParams) { if (_wireFormat.Statements.isFlushElement(statement)) { this.inParams = false; } else if (_wireFormat.Statements.isArgument(statement)) { this.arguments.push(statement); } else if (_wireFormat.Statements.isAttribute(statement)) { this.attributes.push(statement); } else if (_wireFormat.Statements.isModifier(statement)) { throw new Error('Compile Error: Element modifiers are not allowed in components'); } else { throw new Error('Compile Error: only parameters allowed before flush-element'); } } else { this.statements.push(statement); } }; ComponentBlock.prototype.toJSON = function () { var args = this.arguments; var keys = args.map(function (arg) { return arg[1]; }); var values = args.map(function (arg) { return arg[2]; }); return [this.attributes, [keys, values], { statements: this.statements, parameters: this.table.slots }]; }; return ComponentBlock; }(Block); var Template = function () { function Template(symbols, meta) { _classCallCheck$2(this, Template); this.meta = meta; this.block = new TemplateBlock(symbols); } Template.prototype.toJSON = function () { return { block: this.block.toJSON(), meta: this.meta }; }; return Template; }(); var JavaScriptCompiler = function () { function JavaScriptCompiler(opcodes, symbols, meta) { _classCallCheck$2(this, JavaScriptCompiler); this.blocks = new _util.Stack(); this.values = []; this.opcodes = opcodes; this.template = new Template(symbols, meta); } JavaScriptCompiler.process = function (opcodes, symbols, meta) { var compiler = new JavaScriptCompiler(opcodes, symbols, meta); return compiler.process(); }; JavaScriptCompiler.prototype.process = function () { var _this4 = this; this.opcodes.forEach(function (_ref) { var opcode = _ref[0], args = _ref.slice(1); if (!_this4[opcode]) { throw new Error("unimplemented " + opcode + " on JavaScriptCompiler"); } _this4[opcode].apply(_this4, args); }); return this.template; }; /// Nesting JavaScriptCompiler.prototype.startBlock = function (_ref2) { var program = _ref2[0]; var block = new InlineBlock(program['symbols']); this.blocks.push(block); }; JavaScriptCompiler.prototype.endBlock = function () { var template = this.template, blocks = this.blocks; var block = blocks.pop(); template.block.blocks.push(block.toJSON()); }; JavaScriptCompiler.prototype.startProgram = function () { this.blocks.push(this.template.block); }; JavaScriptCompiler.prototype.endProgram = function () {}; /// Statements JavaScriptCompiler.prototype.text = function (content) { this.push([_wireFormat.Ops.Text, content]); }; JavaScriptCompiler.prototype.append = function (trusted) { this.push([_wireFormat.Ops.Append, this.popValue(), trusted]); }; JavaScriptCompiler.prototype.comment = function (value) { this.push([_wireFormat.Ops.Comment, value]); }; JavaScriptCompiler.prototype.modifier = function (name) { var params = this.popValue(); var hash = this.popValue(); this.push([_wireFormat.Ops.Modifier, name, params, hash]); }; JavaScriptCompiler.prototype.block = function (name, template, inverse) { var params = this.popValue(); var hash = this.popValue(); var blocks = this.template.block.blocks; (0, _util.assert)(typeof template !== 'number' || blocks[template] !== null, 'missing block in the compiler'); (0, _util.assert)(typeof inverse !== 'number' || blocks[inverse] !== null, 'missing block in the compiler'); this.push([_wireFormat.Ops.Block, name, params, hash, blocks[template], blocks[inverse]]); }; JavaScriptCompiler.prototype.openElement = function (element) { var tag = element.tag; if (tag.indexOf('-') !== -1) { this.startComponent(element); } else if (element.blockParams.length > 0) { throw new Error("Compile Error: <" + element.tag + "> is not a component and doesn't support block parameters"); } else { this.push([_wireFormat.Ops.OpenElement, tag]); } }; JavaScriptCompiler.prototype.flushElement = function () { this.push([_wireFormat.Ops.FlushElement]); }; JavaScriptCompiler.prototype.closeElement = function (element) { var tag = element.tag, _endComponent, attrs, args, block; if (tag.indexOf('-') !== -1) { _endComponent = this.endComponent(), attrs = _endComponent[0], args = _endComponent[1], block = _endComponent[2]; this.push([_wireFormat.Ops.Component, tag, attrs, args, block]); } else { this.push([_wireFormat.Ops.CloseElement]); } }; JavaScriptCompiler.prototype.staticAttr = function (name, namespace) { var value = this.popValue(); this.push([_wireFormat.Ops.StaticAttr, name, value, namespace]); }; JavaScriptCompiler.prototype.dynamicAttr = function (name, namespace) { var value = this.popValue(); this.push([_wireFormat.Ops.DynamicAttr, name, value, namespace]); }; JavaScriptCompiler.prototype.trustingAttr = function (name, namespace) { var value = this.popValue(); this.push([_wireFormat.Ops.TrustingAttr, name, value, namespace]); }; JavaScriptCompiler.prototype.staticArg = function (name) { var value = this.popValue(); this.push([_wireFormat.Ops.StaticArg, name, value]); }; JavaScriptCompiler.prototype.dynamicArg = function (name) { var value = this.popValue(); this.push([_wireFormat.Ops.DynamicArg, name, value]); }; JavaScriptCompiler.prototype.yield = function (to) { var params = this.popValue(); this.push([_wireFormat.Ops.Yield, to, params]); }; JavaScriptCompiler.prototype.debugger = function (evalInfo) { this.push([_wireFormat.Ops.Debugger, evalInfo]); this.template.block.hasEval = true; }; JavaScriptCompiler.prototype.hasBlock = function (name) { this.pushValue([_wireFormat.Ops.HasBlock, name]); }; JavaScriptCompiler.prototype.hasBlockParams = function (name) { this.pushValue([_wireFormat.Ops.HasBlockParams, name]); }; JavaScriptCompiler.prototype.partial = function (evalInfo) { var params = this.popValue(); this.push([_wireFormat.Ops.Partial, params[0], evalInfo]); this.template.block.hasEval = true; }; /// Expressions JavaScriptCompiler.prototype.literal = function (value) { if (value === undefined) { this.pushValue([_wireFormat.Ops.Undefined]); } else { this.pushValue(value); } }; JavaScriptCompiler.prototype.unknown = function (name) { this.pushValue([_wireFormat.Ops.Unknown, name]); }; JavaScriptCompiler.prototype.get = function (head, path) { this.pushValue([_wireFormat.Ops.Get, head, path]); }; JavaScriptCompiler.prototype.maybeLocal = function (path) { this.pushValue([_wireFormat.Ops.MaybeLocal, path]); }; JavaScriptCompiler.prototype.concat = function () { this.pushValue([_wireFormat.Ops.Concat, this.popValue()]); }; JavaScriptCompiler.prototype.helper = function (name) { var params = this.popValue(); var hash = this.popValue(); this.pushValue([_wireFormat.Ops.Helper, name, params, hash]); }; /// Stack Management Opcodes JavaScriptCompiler.prototype.startComponent = function (element) { var component = new ComponentBlock(element['symbols']); this.blocks.push(component); }; JavaScriptCompiler.prototype.endComponent = function () { var component = this.blocks.pop(); (0, _util.assert)(component instanceof ComponentBlock, "Compiler bug: endComponent() should end a component"); return component.toJSON(); }; JavaScriptCompiler.prototype.prepareArray = function (size) { var values = [], i; for (i = 0; i < size; i++) { values.push(this.popValue()); } this.pushValue(values); }; JavaScriptCompiler.prototype.prepareObject = function (size) { (0, _util.assert)(this.values.length >= size, "Expected " + size + " values on the stack, found " + this.values.length); var keys = new Array(size), i; var values = new Array(size); for (i = 0; i < size; i++) { keys[i] = this.popValue(); values[i] = this.popValue(); } this.pushValue([keys, values]); }; /// Utilities JavaScriptCompiler.prototype.push = function (args) { while (args[args.length - 1] === null) { args.pop(); } this.currentBlock.push(args); }; JavaScriptCompiler.prototype.pushValue = function (val) { this.values.push(val); }; JavaScriptCompiler.prototype.popValue = function () { (0, _util.assert)(this.values.length, "No expression found on stack"); return this.values.pop(); }; _createClass$2(JavaScriptCompiler, [{ key: "currentBlock", get: function () { return this.blocks.current; } }]); return JavaScriptCompiler; }(); var _createClass = function () { function defineProperties(target, props) { var i, descriptor; for (i = 0; i < props.length; i++) { descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false;descriptor.configurable = true;if ("value" in descriptor) descriptor.writable = true;Object.defineProperty(target, descriptor.key, descriptor); } }return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps);if (staticProps) defineProperties(Constructor, staticProps);return Constructor; }; }(); function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } function isTrustedValue(value) { return value.escaped !== undefined && !value.escaped; } var TemplateCompiler = function () { function TemplateCompiler(options) { _classCallCheck(this, TemplateCompiler); this.templateId = 0; this.templateIds = []; this.symbolStack = new _util.Stack(); this.opcodes = []; this.includeMeta = false; this.options = options || {}; } TemplateCompiler.compile = function (options, ast) { var templateVisitor = new TemplateVisitor(); templateVisitor.visit(ast); var compiler = new TemplateCompiler(options); var opcodes = compiler.process(templateVisitor.actions); return JavaScriptCompiler.process(opcodes, ast['symbols'], options.meta); }; TemplateCompiler.prototype.process = function (actions) { var _this = this; actions.forEach(function (_ref) { var name = _ref[0], args = _ref.slice(1); if (!_this[name]) { throw new Error("Unimplemented " + name + " on TemplateCompiler"); } _this[name].apply(_this, args); }); return this.opcodes; }; TemplateCompiler.prototype.startProgram = function (program) { this.symbolStack.push(program[0]['symbols']); this.opcode('startProgram', program, program); }; TemplateCompiler.prototype.endProgram = function () { this.symbolStack.pop(); this.opcode('endProgram', null); }; TemplateCompiler.prototype.startBlock = function (program) { this.symbolStack.push(program[0]['symbols']); this.templateId++; this.opcode('startBlock', program, program); }; TemplateCompiler.prototype.endBlock = function () { this.symbolStack.pop(); this.templateIds.push(this.templateId - 1); this.opcode('endBlock', null); }; TemplateCompiler.prototype.text = function (_ref2) { var action = _ref2[0]; this.opcode('text', action, action.chars); }; TemplateCompiler.prototype.comment = function (_ref3) { var action = _ref3[0]; this.opcode('comment', action, action.value); }; TemplateCompiler.prototype.openElement = function (_ref4) { var action = _ref4[0], i, _i; this.opcode('openElement', action, action); for (i = 0; i < action.attributes.length; i++) { this.attribute([action.attributes[i]]); } for (_i = 0; _i < action.modifiers.length; _i++) { this.modifier([action.modifiers[_i]]); } this.opcode('flushElement', null); this.symbolStack.push(action['symbols']); }; TemplateCompiler.prototype.closeElement = function (_ref5) { var action = _ref5[0]; this.symbolStack.pop(); this.opcode('closeElement', null, action); }; TemplateCompiler.prototype.attribute = function (_ref6) { var action = _ref6[0], isTrusting; var name = action.name, value = action.value; var namespace = (0, _util.getAttrNamespace)(name); var isStatic = this.prepareAttributeValue(value); if (name.charAt(0) === '@') { // Arguments if (isStatic) { this.opcode('staticArg', action, name); } else if (action.value.type === 'MustacheStatement') { this.opcode('dynamicArg', action, name); } else { this.opcode('dynamicArg', action, name); } } else { isTrusting = isTrustedValue(value); if (isStatic) { this.opcode('staticAttr', action, name, namespace); } else if (isTrusting) { this.opcode('trustingAttr', action, name, namespace); } else if (action.value.type === 'MustacheStatement') { this.opcode('dynamicAttr', action, name); } else { this.opcode('dynamicAttr', action, name, namespace); } } }; TemplateCompiler.prototype.modifier = function (_ref7) { var action = _ref7[0]; assertIsSimplePath(action.path, action.loc, 'modifier'); var parts = action.path.parts; this.prepareHelper(action); this.opcode('modifier', action, parts[0]); }; TemplateCompiler.prototype.mustache = function (_ref8) { var action = _ref8[0], to, params; var path = action.path; if ((0, _syntax.isLiteral)(path)) { this.mustacheExpression(action); this.opcode('append', action, !action.escaped); } else if (isYield(path)) { to = assertValidYield(action); this.yield(to, action); } else if (isPartial(path)) { params = assertValidPartial(action); this.partial(params, action); } else if (isDebugger(path)) { assertValidDebuggerUsage(action); this.debugger('debugger', action); } else { this.mustacheExpression(action); this.opcode('append', action, !action.escaped); } }; TemplateCompiler.prototype.block = function (_ref9) { var action /*, index, count*/ = _ref9[0]; this.prepareHelper(action); var templateId = this.templateIds.pop(); var inverseId = action.inverse === null ? null : this.templateIds.pop(); this.opcode('block', action, action.path.parts[0], templateId, inverseId); }; /// Internal actions, not found in the original processed actions TemplateCompiler.prototype.arg = function (_ref10) { var path = _ref10[0]; var _path$parts = path.parts, head = _path$parts[0], rest = _path$parts.slice(1); var symbol = this.symbols.allocateNamed(head); this.opcode('get', path, symbol, rest); }; TemplateCompiler.prototype.mustacheExpression = function (expr) { var path = expr.path, _path$parts2, head, parts; if ((0, _syntax.isLiteral)(path)) { this.opcode('literal', expr, path.value); } else if (isBuiltInHelper(path)) { this.builtInHelper(expr); } else if (isArg(path)) { this.arg([path]); } else if (isHelperInvocation(expr)) { this.prepareHelper(expr); this.opcode('helper', expr, path.parts[0]); } else if (path.this) { this.opcode('get', expr, 0, path.parts); } else if (isLocal(path, this.symbols)) { _path$parts2 = path.parts, head = _path$parts2[0], parts = _path$parts2.slice(1); this.opcode('get', expr, this.symbols.get(head), parts); } else if (isSimplePath(path)) { this.opcode('unknown', expr, path.parts[0]); } else { this.opcode('maybeLocal', expr, path.parts); } }; /// Internal Syntax TemplateCompiler.prototype.yield = function (to, action) { this.prepareParams(action.params); this.opcode('yield', action, this.symbols.allocateBlock(to)); }; TemplateCompiler.prototype.debugger = function (_name, action) { this.opcode('debugger', action, this.symbols.getEvalInfo()); }; TemplateCompiler.prototype.hasBlock = function (name, action) { this.opcode('hasBlock', action, this.symbols.allocateBlock(name)); }; TemplateCompiler.prototype.hasBlockParams = function (name, action) { this.opcode('hasBlockParams', action, this.symbols.allocateBlock(name)); }; TemplateCompiler.prototype.partial = function (_params, action) { this.prepareParams(action.params); this.opcode('partial', action, this.symbols.getEvalInfo()); }; TemplateCompiler.prototype.builtInHelper = function (expr) { var path = expr.path, name, _name2; if (isHasBlock(path)) { name = assertValidHasBlockUsage(expr.path.original, expr); this.hasBlock(name, expr); } else if (isHasBlockParams(path)) { _name2 = assertValidHasBlockUsage(expr.path.original, expr); this.hasBlockParams(_name2, expr); } }; /// Expressions, invoked recursively from prepareParams and prepareHash TemplateCompiler.prototype.SubExpression = function (expr) { if (isBuiltInHelper(expr.path)) { this.builtInHelper(expr); } else { this.prepareHelper(expr); this.opcode('helper', expr, expr.path.parts[0]); } }; TemplateCompiler.prototype.PathExpression = function (expr) { var symbols, _expr$parts, head; if (expr.data) { this.arg([expr]); } else { symbols = this.symbols; _expr$parts = expr.parts, head = _expr$parts[0]; if (expr.this) { this.opcode('get', expr, 0, expr.parts); } else if (symbols.has(head)) { this.opcode('get', expr, symbols.get(head), expr.parts.slice(1)); } else { this.opcode('maybeLocal', expr, expr.parts); } } }; TemplateCompiler.prototype.StringLiteral = function (action) { this.opcode('literal', null, action.value); }; TemplateCompiler.prototype.BooleanLiteral = function (action) { this.opcode('literal', null, action.value); }; TemplateCompiler.prototype.NumberLiteral = function (action) { this.opcode('literal', null, action.value); }; TemplateCompiler.prototype.NullLiteral = function (action) { this.opcode('literal', null, action.value); }; TemplateCompiler.prototype.UndefinedLiteral = function (action) { this.opcode('literal', null, action.value); }; /// Utilities TemplateCompiler.prototype.opcode = function (name, action) { for (_len = arguments.length, args = Array(_len > 2 ? _len - 2 : 0), _key = 2; _key < _len; _key++) { args[_key - 2] = arguments[_key]; } var opcode = [name].concat(args), _len, args, _key; if (this.includeMeta && action) { opcode.push(this.meta(action)); } this.opcodes.push(opcode); }; TemplateCompiler.prototype.prepareHelper = function (expr) { assertIsSimplePath(expr.path, expr.loc, 'helper'); var params = expr.params, hash = expr.hash; this.prepareHash(hash); this.prepareParams(params); }; TemplateCompiler.prototype.prepareParams = function (params) { var i, param; if (!params.length) { this.opcode('literal', null, null); return; } for (i = params.length - 1; i >= 0; i--) { param = params[i]; (0, _util.assert)(this[param.type], "Unimplemented " + param.type + " on TemplateCompiler"); this[param.type](param); } this.opcode('prepareArray', null, params.length); }; TemplateCompiler.prototype.prepareHash = function (hash) { var pairs = hash.pairs, i, _pairs$i, key, value; if (!pairs.length) { this.opcode('literal', null, null); return; } for (i = pairs.length - 1; i >= 0; i--) { _pairs$i = pairs[i], key = _pairs$i.key, value = _pairs$i.value; (0, _util.assert)(this[value.type], "Unimplemented " + value.type + " on TemplateCompiler"); this[value.type](value); this.opcode('literal', null, key); } this.opcode('prepareObject', null, pairs.length); }; TemplateCompiler.prototype.prepareAttributeValue = function (value) { // returns the static value if the value is static switch (value.type) { case 'TextNode': this.opcode('literal', value, value.chars); return true; case 'MustacheStatement': this.attributeMustache([value]); return false; case 'ConcatStatement': this.prepareConcatParts(value.parts); this.opcode('concat', value); return false; } }; TemplateCompiler.prototype.prepareConcatParts = function (parts) { var i, part; for (i = parts.length - 1; i >= 0; i--) { part = parts[i]; if (part.type === 'MustacheStatement') { this.attributeMustache([part]); } else if (part.type === 'TextNode') { this.opcode('literal', null, part.chars); } } this.opcode('prepareArray', null, parts.length); }; TemplateCompiler.prototype.attributeMustache = function (_ref11) { var action = _ref11[0]; this.mustacheExpression(action); }; TemplateCompiler.prototype.meta = function (node) { var loc = node.loc; if (!loc) { return []; } var source = loc.source, start = loc.start, end = loc.end; return ['loc', [source || null, [start.line, start.column], [end.line, end.column]]]; }; _createClass(TemplateCompiler, [{ key: "symbols", get: function () { return this.symbolStack.current; } }]); return TemplateCompiler; }(); function isHelperInvocation(mustache) { return mustache.params && mustache.params.length > 0 || mustache.hash && mustache.hash.pairs.length > 0; } function isSimplePath(_ref12) { var parts = _ref12.parts; return parts.length === 1; } function isLoc