Fixes #139 - Allow dynamic custom tags to be used with <include>

This commit is contained in:
Patrick Steele-Idem 2016-11-11 16:59:01 -07:00
parent 0ee3fdd764
commit be56ba6e8d
23 changed files with 123 additions and 30 deletions

View File

@ -1,27 +1,30 @@
function create(__markoHelpers) {
var __browser_json = require.resolve("./browser.json"),
marko_loadTag = __markoHelpers.t,
lasso_page_tag = marko_loadTag(require("lasso/taglib/page-tag")),
lasso_head_tag = marko_loadTag(require("lasso/taglib/head-tag")),
lasso_body_tag = marko_loadTag(require("lasso/taglib/body-tag"));
var template = require("marko/html").c(__filename);
return function render(data, out) {
lasso_page_tag({
packagePath: __browser_json,
dirname: __dirname,
filename: __filename
}, out);
module.exports = template;
out.w("<!DOCTYPE html><html lang=\"en\"><head><meta charset=\"UTF-8\"><title>marko-vdom benchmarks</title>");
var __browser_json = require.resolve("./browser.json"),
marko_helpers = require("marko/runtime/html/helpers"),
marko_loadTag = marko_helpers.t,
lasso_page_tag = marko_loadTag(require("lasso/taglib/page-tag")),
lasso_head_tag = marko_loadTag(require("lasso/taglib/head-tag")),
lasso_body_tag = marko_loadTag(require("lasso/taglib/body-tag"));
lasso_head_tag({}, out);
function render(data, out) {
lasso_page_tag({
packagePath: __browser_json,
dirname: __dirname,
filename: __filename
}, out);
out.w("</head><body><button type=\"button\" data-benchmark=\"walk\">Run benchmark: walk</button><button type=\"button\" data-benchmark=\"create\">Run benchmark: create</button><pre id=\"results\" style=\"width: 100%; border: 1px solid black;\">\n </pre><section id=\"todoapp\" style=\"display: none\"><div id=\"w0\"><header id=\"header\"><h1>todos</h1><form data-w-onsubmit=\"handleFormSubmit|header\"><input id=\"new-todo\" placeholder=\"What needs to be done?\"></form></header><section id=\"main\"><input id=\"toggle-all\" type=\"checkbox\" data-w-onchange=\"handleToggleAllOnChange|main\"><label for=\"toggle-all\">Mark all as complete</label><ul id=\"todo-list\"><li id=\"main-todo-0\"><div class=\"view\"><input class=\"toggle\" type=\"checkbox\" aria-label=\"Toggle todo completed\" data-w-onchange=\"handleCheckboxChange|main-todo-0\"><label data-w-ondblclick=\"handleLabelDblClick|main-todo-0\">Go to the grocery store</label><button class=\"destroy\" aria-label=\"Delete todo\" data-w-onclick=\"handleDestroyClick|main-todo-0\"></button></div><input title=\"Enter the new todo title\" type=\"text\" class=\"edit\" id=\"main-todo-0-titleInput\" data-w-onchange=\"handleInputChange|main-todo-0\" data-w-onkeydown=\"handleInputKeyDown|main-todo-0\"></li><li class=\"completed\" id=\"main-todo-1\"><div class=\"view\"><input class=\"toggle\" type=\"checkbox\" checked=\"\" aria-label=\"Toggle todo completed\" data-w-onchange=\"handleCheckboxChange|main-todo-1\"><label data-w-ondblclick=\"handleLabelDblClick|main-todo-1\">Ship item</label><button class=\"destroy\" aria-label=\"Delete todo\" data-w-onclick=\"handleDestroyClick|main-todo-1\"></button></div><input title=\"Enter the new todo title\" type=\"text\" class=\"edit\" id=\"main-todo-1-titleInput\" data-w-onchange=\"handleInputChange|main-todo-1\" data-w-onkeydown=\"handleInputKeyDown|main-todo-1\"></li><li id=\"main-todo-2\"><div class=\"view\"><input class=\"toggle\" type=\"checkbox\" aria-label=\"Toggle todo completed\" data-w-onchange=\"handleCheckboxChange|main-todo-2\"><label data-w-ondblclick=\"handleLabelDblClick|main-todo-2\">Respond to email</label><button class=\"destroy\" aria-label=\"Delete todo\" data-w-onclick=\"handleDestroyClick|main-todo-2\"></button></div><input title=\"Enter the new todo title\" type=\"text\" class=\"edit\" id=\"main-todo-2-titleInput\" data-w-onchange=\"handleInputChange|main-todo-2\" data-w-onkeydown=\"handleInputKeyDown|main-todo-2\"></li><li id=\"main-todo-3\"><div class=\"view\"><input class=\"toggle\" type=\"checkbox\" aria-label=\"Toggle todo completed\" data-w-onchange=\"handleCheckboxChange|main-todo-3\"><label data-w-ondblclick=\"handleLabelDblClick|main-todo-3\">Foo</label><button class=\"destroy\" aria-label=\"Delete todo\" data-w-onclick=\"handleDestroyClick|main-todo-3\"></button></div><input title=\"Enter the new todo title\" type=\"text\" class=\"edit\" id=\"main-todo-3-titleInput\" data-w-onchange=\"handleInputChange|main-todo-3\" data-w-onkeydown=\"handleInputKeyDown|main-todo-3\"></li><li id=\"main-todo-4\"><div class=\"view\"><input class=\"toggle\" type=\"checkbox\" aria-label=\"Toggle todo completed\" data-w-onchange=\"handleCheckboxChange|main-todo-4\"><label data-w-ondblclick=\"handleLabelDblClick|main-todo-4\">Bar</label><button class=\"destroy\" aria-label=\"Delete todo\" data-w-onclick=\"handleDestroyClick|main-todo-4\"></button></div><input title=\"Enter the new todo title\" type=\"text\" class=\"edit\" id=\"main-todo-4-titleInput\" data-w-onchange=\"handleInputChange|main-todo-4\" data-w-onkeydown=\"handleInputKeyDown|main-todo-4\"></li><li id=\"main-todo-5\"><div class=\"view\"><input class=\"toggle\" type=\"checkbox\" aria-label=\"Toggle todo completed\" data-w-onchange=\"handleCheckboxChange|main-todo-5\"><label data-w-ondblclick=\"handleLabelDblClick|main-todo-5\">Baz</label><button class=\"destroy\" aria-label=\"Delete todo\" data-w-onclick=\"handleDestroyClick|main-todo-5\"></button></div><input title=\"Enter the new todo title\" type=\"text\" class=\"edit\" id=\"main-todo-5-titleInput\" data-w-onchange=\"handleInputChange|main-todo-5\" data-w-onkeydown=\"handleInputKeyDown|main-todo-5\"></li></ul></section><footer id=\"footer\"><span id=\"todo-count\"><strong>5</strong> items left</span><ul id=\"filters\"><li><a href=\"#/\" class=\"selected\" data-w-onclick=\"handleAllFilterClick|footer\">All</a></li><li><a href=\"#/active\" data-w-onclick=\"handleActiveFilterClick|footer\">Active</a></li><li><a href=\"#/completed\" data-w-onclick=\"handleCompletedFilterClick|footer\">Completed</a></li></ul><button id=\"clear-completed\" data-w-onclick=\"handleClearCompletedClick|footer\">Clear completed (1)</button></footer></div></section>");
out.w("<!DOCTYPE html><html lang=\"en\"><head><meta charset=\"UTF-8\"><title>marko-vdom benchmarks</title>");
lasso_body_tag({}, out);
lasso_head_tag({}, out);
out.w("</body></html>");
};
out.w("</head><body><button type=\"button\" data-benchmark=\"walk\">Run benchmark: walk</button><button type=\"button\" data-benchmark=\"create\">Run benchmark: create</button><pre id=\"results\" style=\"width: 100%; border: 1px solid black;\">\n </pre><section id=\"todoapp\" style=\"display: none\"><div id=\"w0\"><header id=\"header\"><h1>todos</h1><form data-w-onsubmit=\"handleFormSubmit|header\"><input id=\"new-todo\" placeholder=\"What needs to be done?\"></form></header><section id=\"main\"><input id=\"toggle-all\" type=\"checkbox\" data-w-onchange=\"handleToggleAllOnChange|main\"><label for=\"toggle-all\">Mark all as complete</label><ul id=\"todo-list\"><li id=\"main-todo-0\"><div class=\"view\"><input class=\"toggle\" type=\"checkbox\" aria-label=\"Toggle todo completed\" data-w-onchange=\"handleCheckboxChange|main-todo-0\"><label data-w-ondblclick=\"handleLabelDblClick|main-todo-0\">Go to the grocery store</label><button class=\"destroy\" aria-label=\"Delete todo\" data-w-onclick=\"handleDestroyClick|main-todo-0\"></button></div><input title=\"Enter the new todo title\" type=\"text\" class=\"edit\" id=\"main-todo-0-titleInput\" data-w-onchange=\"handleInputChange|main-todo-0\" data-w-onkeydown=\"handleInputKeyDown|main-todo-0\"></li><li class=\"completed\" id=\"main-todo-1\"><div class=\"view\"><input class=\"toggle\" type=\"checkbox\" checked=\"\" aria-label=\"Toggle todo completed\" data-w-onchange=\"handleCheckboxChange|main-todo-1\"><label data-w-ondblclick=\"handleLabelDblClick|main-todo-1\">Ship item</label><button class=\"destroy\" aria-label=\"Delete todo\" data-w-onclick=\"handleDestroyClick|main-todo-1\"></button></div><input title=\"Enter the new todo title\" type=\"text\" class=\"edit\" id=\"main-todo-1-titleInput\" data-w-onchange=\"handleInputChange|main-todo-1\" data-w-onkeydown=\"handleInputKeyDown|main-todo-1\"></li><li id=\"main-todo-2\"><div class=\"view\"><input class=\"toggle\" type=\"checkbox\" aria-label=\"Toggle todo completed\" data-w-onchange=\"handleCheckboxChange|main-todo-2\"><label data-w-ondblclick=\"handleLabelDblClick|main-todo-2\">Respond to email</label><button class=\"destroy\" aria-label=\"Delete todo\" data-w-onclick=\"handleDestroyClick|main-todo-2\"></button></div><input title=\"Enter the new todo title\" type=\"text\" class=\"edit\" id=\"main-todo-2-titleInput\" data-w-onchange=\"handleInputChange|main-todo-2\" data-w-onkeydown=\"handleInputKeyDown|main-todo-2\"></li><li id=\"main-todo-3\"><div class=\"view\"><input class=\"toggle\" type=\"checkbox\" aria-label=\"Toggle todo completed\" data-w-onchange=\"handleCheckboxChange|main-todo-3\"><label data-w-ondblclick=\"handleLabelDblClick|main-todo-3\">Foo</label><button class=\"destroy\" aria-label=\"Delete todo\" data-w-onclick=\"handleDestroyClick|main-todo-3\"></button></div><input title=\"Enter the new todo title\" type=\"text\" class=\"edit\" id=\"main-todo-3-titleInput\" data-w-onchange=\"handleInputChange|main-todo-3\" data-w-onkeydown=\"handleInputKeyDown|main-todo-3\"></li><li id=\"main-todo-4\"><div class=\"view\"><input class=\"toggle\" type=\"checkbox\" aria-label=\"Toggle todo completed\" data-w-onchange=\"handleCheckboxChange|main-todo-4\"><label data-w-ondblclick=\"handleLabelDblClick|main-todo-4\">Bar</label><button class=\"destroy\" aria-label=\"Delete todo\" data-w-onclick=\"handleDestroyClick|main-todo-4\"></button></div><input title=\"Enter the new todo title\" type=\"text\" class=\"edit\" id=\"main-todo-4-titleInput\" data-w-onchange=\"handleInputChange|main-todo-4\" data-w-onkeydown=\"handleInputKeyDown|main-todo-4\"></li><li id=\"main-todo-5\"><div class=\"view\"><input class=\"toggle\" type=\"checkbox\" aria-label=\"Toggle todo completed\" data-w-onchange=\"handleCheckboxChange|main-todo-5\"><label data-w-ondblclick=\"handleLabelDblClick|main-todo-5\">Baz</label><button class=\"destroy\" aria-label=\"Delete todo\" data-w-onclick=\"handleDestroyClick|main-todo-5\"></button></div><input title=\"Enter the new todo title\" type=\"text\" class=\"edit\" id=\"main-todo-5-titleInput\" data-w-onchange=\"handleInputChange|main-todo-5\" data-w-onkeydown=\"handleInputKeyDown|main-todo-5\"></li></ul></section><footer id=\"footer\"><span id=\"todo-count\"><strong>5</strong> items left</span><ul id=\"filters\"><li><a href=\"#/\" class=\"selected\" data-w-onclick=\"handleAllFilterClick|footer\">All</a></li><li><a href=\"#/active\" data-w-onclick=\"handleActiveFilterClick|footer\">Active</a></li><li><a href=\"#/completed\" data-w-onclick=\"handleCompletedFilterClick|footer\">Completed</a></li></ul><button id=\"clear-completed\" data-w-onclick=\"handleClearCompletedClick|footer\">Clear completed (1)</button></footer></div></section>");
lasso_body_tag({}, out);
out.w("</body></html>");
}
module.exports = require("marko/html").c(__filename, create);
template._ = render;

View File

@ -57,13 +57,14 @@ const helpers = {
'classList': 'cl',
'const': 'const',
'createElement': 'e',
'createInlineTemplate': 'i',
'createInlineTemplate': 'inline',
'escapeXml': 'x',
'escapeXmlAttr': 'xa',
'escapeScript': 'xs',
'forEach': 'f',
'forEachProp': 'fp',
'forEachWithStatusVar': 'fv',
'include': 'i',
'loadTag': 't',
'loadTemplate': 'l',
'merge': 'm',

View File

@ -227,5 +227,19 @@ module.exports = {
/**
* Loads a template (__helpers.l --> marko_loadTemplate(path))
*/
l: load
l: load,
i: function(target, out, data) {
if (target) {
if (typeof target === 'function') {
target(out, data);
} else if (target.renderer) {
target.renderer(data, out);
} else if (target.render) {
target.render(data, out);
} else {
throw new Error('Invalid include target: ' + target);
}
}
}
};

View File

@ -116,5 +116,5 @@ module.exports = extend({
}
},
i: require('./')._inline
inline: require('./')._inline
}, commonHelpers);

View File

@ -85,5 +85,5 @@ module.exports = extend({
}
},
i: require('./')._inline
inline: require('./')._inline
}, commonHelpers);

View File

@ -18,12 +18,15 @@ module.exports = function codeGenerator(el, codegen) {
}
let templatePath = args[0];
let templateVar;
let targetVar;
var isTemplate = false;
if (templatePath.type === 'Literal') {
templateVar = codegen.context.importTemplate(templatePath.value);
targetVar = codegen.context.importTemplate(templatePath.value);
isTemplate = true;
} else {
templateVar = templatePath;
targetVar = templatePath;
}
let templateData = {};
@ -55,8 +58,19 @@ module.exports = function codeGenerator(el, codegen) {
templateData = builder.literal(templateData);
}
let renderMethod = builder.memberExpression(templateVar, builder.identifier('render'));
let renderArgs = [ templateData, 'out' ];
let renderFunctionCall = builder.functionCall(renderMethod, renderArgs);
return renderFunctionCall;
if (isTemplate) {
let renderMethod = builder.memberExpression(targetVar, builder.identifier('render'));
let renderArgs = [ templateData, 'out' ];
let renderFunctionCall = builder.functionCall(renderMethod, renderArgs);
return renderFunctionCall;
} else {
let includeVar = codegen.context.helper('include');
let includeArgs = [ targetVar, 'out'];
if (Object.keys(templateData).length > 0) {
includeArgs.push(templateData);
}
return builder.functionCall(includeVar, includeArgs);
}
};

View File

@ -0,0 +1,7 @@
module.exports = {
renderer: function(input, out) {
out.beginElement('div');
out.text(input.name.toUpperCase());
out.endElement();
}
};

View File

@ -0,0 +1 @@
<div>FRANK</div>

View File

@ -0,0 +1,5 @@
<div>
<h1>
Hello World!
</h1>
</div>

View File

@ -0,0 +1 @@
<include(data.component, {name: 'Frank'})/>

View File

@ -0,0 +1,5 @@
var myComponent = require('./components/my-component');
exports.templateData = {
component: myComponent
};

View File

@ -0,0 +1 @@
<div>foo</div>

View File

@ -0,0 +1,5 @@
<div>
<h1>
Hello World!
</h1>
</div>

View File

@ -0,0 +1 @@
<include(data.renderBody)/>

View File

@ -0,0 +1,7 @@
exports.templateData = {
renderBody(out) {
out.beginElement('div');
out.text('foo');
out.endElement();
}
};

View File

@ -0,0 +1 @@
<div>Frank</div>

View File

@ -0,0 +1,5 @@
<div>
<h1>
Hello World!
</h1>
</div>

View File

@ -0,0 +1 @@
<include(data.renderBody, 'Frank')/>

View File

@ -0,0 +1,7 @@
exports.templateData = {
renderBody(out, name) {
out.beginElement('div');
out.text(name);
out.endElement();
}
};

View File

@ -0,0 +1 @@
<div>Frank</div>

View File

@ -0,0 +1,5 @@
<div>
<h1>
Hello World!
</h1>
</div>

View File

@ -0,0 +1 @@
<include(data.renderBody, {name: 'Frank'})/>

View File

@ -0,0 +1,7 @@
exports.templateData = {
renderBody(out, data) {
out.beginElement('div');
out.text(data.name);
out.endElement();
}
};