UNPKG

khufu

Version:

A template language for incremental-dom or DSL for javascript views

415 lines (358 loc) 19.9 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.BUILTINS = undefined; var _slicedToArray = function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"]) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError("Invalid attempt to destructure non-iterable instance"); } }; }(); exports.compile_string = compile_string; exports.join_key = join_key; exports.compile_body = compile_body; exports.compile = compile; var _babelTypes = require("babel-types"); var T = _interopRequireWildcard(_babelTypes); var _compile_element = require("./compile_element"); var element = _interopRequireWildcard(_compile_element); var _compile_expression = require("./compile_expression.js"); var expression = _interopRequireWildcard(_compile_expression); var _compile_expression2 = require("./compile_expression"); var _compile_lval = require("./compile_lval"); var lval = _interopRequireWildcard(_compile_lval); var _compiler = require("./compiler"); var _babelUtil = require("./babel-util"); var _vars = require("./vars"); function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } } var DOM_FUNCTIONS = ['elementVoid', 'elementOpen', 'elementClose', 'text', 'item']; var BUILTINS = exports.BUILTINS = DOM_FUNCTIONS.concat(['SuppressedError']); function compile_string(item, path, opt, key) { var _item = _slicedToArray(item, 2), _expression = _item[0], value = _item[1]; var expr = (0, _compile_expression2.compile)(value, path, opt); if (value[0] == 'call') { (0, _babelUtil.push_to_body)(path, T.expressionStatement(T.callExpression(T.identifier('item'), [expr, key]))); } else { (0, _babelUtil.push_to_body)(path, T.expressionStatement(T.callExpression(T.identifier('text'), [expr]))); } } function join_key(x, y) { // Optimizes "a" + "b" -> "ab" if (T.isStringLiteral(x) && T.isStringLiteral(y)) { return T.stringLiteral(x.value + y.value); } // Optimizes "" + "b" -> "b" if (x.value === '') return y; // Optimizes "a" + "" -> "a" if (y.value === '') return x; // Optimizes (N + "a") + "b" -> N + "ab" if (T.isBinaryExpression(x) && T.isStringLiteral(x.right) && T.isStringLiteral(y)) { return T.binaryExpression("+", x.left, T.stringLiteral(x.right.value + y.value)); } return T.binaryExpression("+", x, y); } function compile_body(body, path, opt) { var key = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : T.stringLiteral(''); var elements = 0; var _iteratorNormalCompletion = true; var _didIteratorError = false; var _iteratorError = undefined; try { for (var _iterator = body[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) { var item = _step.value; switch (item[0]) { case 'element': { elements += 1; element.compile(item, path, opt, join_key(key, T.stringLiteral('-' + elements))); break; } case 'expression': { elements += 1; compile_string(item, path, opt, join_key(key, T.stringLiteral('-' + elements))); break; } case 'block_call': { elements += 1; var subkey = join_key(key, T.stringLiteral('-' + elements)); var _item2 = _slicedToArray(item, 3), _block_call = _item2[0], _expression2 = _item2[1], kwargs = _item2[2]; var expr = (0, _compile_expression2.compile)(_expression2, path, opt); var kwarg_items = []; var _iteratorNormalCompletion2 = true; var _didIteratorError2 = false; var _iteratorError2 = undefined; try { for (var _iterator2 = kwargs[Symbol.iterator](), _step2; !(_iteratorNormalCompletion2 = (_step2 = _iterator2.next()).done); _iteratorNormalCompletion2 = true) { var _step2$value = _slicedToArray(_step2.value, 2), name = _step2$value[0], block = _step2$value[1]; kwarg_items.push(T.objectProperty(T.identifier(name), T.functionExpression(null, [], T.blockStatement([T.returnStatement(T.functionExpression(null, [T.identifier('key')], T.blockStatement([]), false, false))])))); } } catch (err) { _didIteratorError2 = true; _iteratorError2 = err; } finally { try { if (!_iteratorNormalCompletion2 && _iterator2.return) { _iterator2.return(); } } finally { if (_didIteratorError2) { throw _iteratorError2; } } } var callpath = (0, _babelUtil.push_to_body)(path, T.expressionStatement(T.callExpression(expr, [subkey, T.objectExpression(kwarg_items)]))); var argpath = callpath.get('expression.arguments')[1].get('properties'); for (var i = 0; i < kwargs.length; ++i) { compile_body(kwargs[i][1], argpath[i].get('value.body.body')[0].get('argument.body'), opt, T.identifier('key')); } break; } case 'assign': { var _item3 = _slicedToArray(item, 3), _assign = _item3[0], target = _item3[1], value = _item3[2]; var _expr = (0, _compile_expression2.compile)(value, path, opt); var decl = lval.compile(target, path, opt); path.scope.push({ id: decl, init: _expr, kind: 'let' }); break; } case 'for': { elements += 1; var _item4 = _slicedToArray(item, 5), _for = _item4[0], assign = _item4[1], source = _item4[2], loopkey = _item4[3], block = _item4[4]; var stmt = T.forOfStatement(T.variableDeclaration("let", []), (0, _compile_expression2.compile)(source, path, opt), T.blockStatement([])); var npath = (0, _babelUtil.push_to_body)(path, stmt); var _decl = lval.compile(assign, npath, opt); npath.get('left').replaceWith(T.variableDeclaration("let", [T.variableDeclarator(_decl)])); compile_body(block, npath.get('body'), opt, join_key(join_key(key, T.stringLiteral('-' + elements)), (0, _compile_expression2.compile)(loopkey, npath, opt))); break; } case 'if': { elements += 1; var _item5 = _slicedToArray(item, 4), _if = _item5[0], _item5$ = _slicedToArray(_item5[1], 2), condition = _item5$[0], _block = _item5$[1], elifblocks = _item5[2], elseblk = _item5[3]; var ifblock = void 0; if (condition[0] == 'let') { var _decl2 = path.scope.generateUidIdentifier('if_let_cond'); var _expr2 = (0, _compile_expression2.compile)(condition[2], path, opt); path.scope.push({ id: _decl2, kind: 'let' }); var _cond = T.assignmentExpression('=', _decl2, _expr2); var con = T.ifStatement(_cond, T.blockStatement([]), null); ifblock = (0, _babelUtil.push_to_body)(path, con); var inner_path = ifblock.get('consequent'); var in_decl = lval.compile(condition[1], inner_path, opt); inner_path.scope.push({ id: in_decl, init: _decl2, kind: 'let' }); } else { var _con = T.ifStatement((0, _compile_expression2.compile)(condition, path, opt), T.blockStatement([]), null); ifblock = (0, _babelUtil.push_to_body)(path, _con); } compile_body(_block, ifblock.get('consequent'), opt, join_key(key, T.stringLiteral("-" + elements + "if0"))); var _iteratorNormalCompletion3 = true; var _didIteratorError3 = false; var _iteratorError3 = undefined; try { for (var _iterator3 = elifblocks.entries()[Symbol.iterator](), _step3; !(_iteratorNormalCompletion3 = (_step3 = _iterator3.next()).done); _iteratorNormalCompletion3 = true) { var _step3$value = _slicedToArray(_step3.value, 2), idx = _step3$value[0], _step3$value$ = _slicedToArray(_step3$value[1], 2), cond = _step3$value$[0], blk = _step3$value$[1]; if (cond[0] == 'let') { var _decl3 = path.scope.generateUidIdentifier('if_let_cond'); var _expr3 = (0, _compile_expression2.compile)(cond[2], path, opt); path.scope.push({ id: _decl3, kind: 'let' }); var _stmt = T.ifStatement(T.assignmentExpression('=', _decl3, _expr3), T.blockStatement([]), null); ifblock = ifblock.get('alternate'); ifblock.replaceWith(_stmt); var _inner_path = ifblock.get('consequent'); var _in_decl = lval.compile(cond[1], _inner_path, opt); _inner_path.scope.push({ id: _in_decl, init: _decl3, kind: 'let' }); } else { ifblock = ifblock.get('alternate'); ifblock.replaceWith(T.ifStatement((0, _compile_expression2.compile)(cond, path, opt), T.blockStatement([]), null)); } compile_body(blk, ifblock.get('consequent'), opt, join_key(key, T.stringLiteral("-" + elements + "if" + (idx + 1)))); } } catch (err) { _didIteratorError3 = true; _iteratorError3 = err; } finally { try { if (!_iteratorNormalCompletion3 && _iterator3.return) { _iterator3.return(); } } finally { if (_didIteratorError3) { throw _iteratorError3; } } } if (elseblk) { var elseblock = ifblock.get('alternate'); elseblock.replaceWith(T.blockStatement([])); compile_body(elseblk, elseblock, opt, join_key(key, T.StringLiteral("-" + elements + "els"))); } break; } case 'catch': { elements += 1; var _item6 = _slicedToArray(item, 5), _catch = _item6[0], pattern = _item6[1], action = _item6[2], _target = _item6[3], _block2 = _item6[4]; var name = path.scope.generateUidIdentifier('error'); var _stmt2 = (0, _babelUtil.push_to_body)(path, T.tryStatement(T.blockStatement([]), T.catchClause(name, T.blockStatement([])))); var handler = _stmt2.get("handler").get("body"); var if_stmt = (0, _babelUtil.push_to_body)(handler, T.ifStatement(T.unaryExpression('!', T.binaryExpression('instanceof', name, T.identifier("SuppressedError")), true), T.blockStatement([]))).get("consequent"); var store = (0, _vars.get_var)(path, _target[1], _target); (0, _vars.set_var)(if_stmt, 'this', T.identifier('this')); (0, _vars.set_var)(if_stmt, 'error', name); (0, _babelUtil.push_to_body)(if_stmt, T.callExpression(T.memberExpression(store, T.identifier('dispatch')), [expression.compile(action, if_stmt, opt)])); (0, _babelUtil.push_to_body)(if_stmt, T.throwStatement(T.newExpression(T.identifier("SuppressedError"), [name]))); (0, _babelUtil.push_to_body)(handler, T.throwStatement(name)); compile_body(_block2, _stmt2.get("block"), opt, join_key(key, T.StringLiteral("-" + elements + "catch"))); break; } default: throw (0, _compiler.parse_tree_error)("Bad element", item); } } } catch (err) { _didIteratorError = true; _iteratorError = err; } finally { try { if (!_iteratorNormalCompletion && _iterator.return) { _iterator.return(); } } finally { if (_didIteratorError) { throw _iteratorError; } } } } function compile(view, path, opt) { var _view2 = _slicedToArray(view, 5), _view = _view2[0], name = _view2[1], params = _view2[2], kwargs = _view2[3], body = _view2[4]; if (!path.scope.getData('khufu:dom-imported')) { path.unshiftContainer("body", T.importDeclaration(BUILTINS.map(function (x) { return T.importSpecifier(T.identifier(x), T.identifier(x)); }), T.stringLiteral('khufu-runtime'))); path.scope.setData('khufu:dom-imported', true); } var kwarg_nodes = []; if (kwargs.length) { kwarg_nodes.push(T.objectPattern(kwargs.map(function (_ref) { var _ref2 = _slicedToArray(_ref, 2), _name = _ref2[0], name = _ref2[1]; return T.objectProperty(T.identifier(name), T.identifier(name)); }))); } var ident = name.replace(/\./g, '_'); var block_node = T.blockStatement([T.returnStatement(T.functionExpression(T.identifier(ident + '$'), [T.identifier('key')].concat(kwarg_nodes), T.blockStatement([]), false, false))]); var ext_fun = void 0; if (name.indexOf('.') >= 0) { var _name$split = name.split('.'), _name$split2 = _slicedToArray(_name$split, 2), varname = _name$split2[0], key = _name$split2[1]; var binding = (0, _vars.get_var)(path, varname); if (!binding) { binding = path.scope.generateUidIdentifier(varname); (0, _vars.set_var)(path, varname, binding); path.scope.push({ id: binding, init: T.objectExpression([]), kind: 'let' }); if (varname[0] != '_') { (0, _babelUtil.push_to_body)(path, T.exportNamedDeclaration(null, [T.exportSpecifier(binding, T.identifier(varname))], null)); } } var assign = T.assignmentExpression('=', T.memberExpression(binding, T.identifier(key), false), T.functionExpression(T.identifier(ident), [], block_node, false, false)); var ext_node = T.expressionStatement(assign); ext_fun = (0, _babelUtil.push_to_body)(path, ext_node).get('expression.right'); } else if (name[0] != '_') { var func_decl = T.functionDeclaration(T.identifier(ident), [], block_node, false, false); var _ext_node = T.exportNamedDeclaration(func_decl, []); ext_fun = (0, _babelUtil.push_to_body)(path, _ext_node).get('declaration'); } else { var _ext_node2 = T.functionDeclaration(T.identifier(ident), [], block_node, false, false); ext_fun = (0, _babelUtil.push_to_body)(path, _ext_node2); } var child_path = ext_fun.get('body.body')[0].get('argument.body'); var _iteratorNormalCompletion4 = true; var _didIteratorError4 = false; var _iteratorError4 = undefined; try { for (var _iterator4 = params[Symbol.iterator](), _step4; !(_iteratorNormalCompletion4 = (_step4 = _iterator4.next()).done); _iteratorNormalCompletion4 = true) { var param = _step4.value; ext_fun.node.params.push(lval.compile(param, child_path, opt)); } } catch (err) { _didIteratorError4 = true; _iteratorError4 = err; } finally { try { if (!_iteratorNormalCompletion4 && _iterator4.return) { _iterator4.return(); } } finally { if (_didIteratorError4) { throw _iteratorError4; } } } var _iteratorNormalCompletion5 = true; var _didIteratorError5 = false; var _iteratorError5 = undefined; try { for (var _iterator5 = kwargs[Symbol.iterator](), _step5; !(_iteratorNormalCompletion5 = (_step5 = _iterator5.next()).done); _iteratorNormalCompletion5 = true) { var _step5$value = _slicedToArray(_step5.value, 2), _name = _step5$value[0], kwarg = _step5$value[1]; (0, _vars.set_var)(child_path, kwarg, T.identifier(kwarg)); } } catch (err) { _didIteratorError5 = true; _iteratorError5 = err; } finally { try { if (!_iteratorNormalCompletion5 && _iterator5.return) { _iterator5.return(); } } finally { if (_didIteratorError5) { throw _iteratorError5; } } } compile_body(body, child_path, opt, T.identifier('key')); }