Fixes #611 - component IDs are not being assigned correctly

This commit is contained in:
Patrick Steele-Idem 2017-03-10 16:49:49 -07:00
parent 5df1f47b71
commit 02d30107e3
14 changed files with 76 additions and 41 deletions

View File

@ -77,6 +77,7 @@ const helpers = {
'loadTemplate': { module: 'marko/runtime/helper-loadTemplate' }, 'loadTemplate': { module: 'marko/runtime/helper-loadTemplate' },
'mergeNestedTagsHelper': { module: 'marko/runtime/helper-mergeNestedTags' }, 'mergeNestedTagsHelper': { module: 'marko/runtime/helper-mergeNestedTags' },
'merge': { module: 'marko/runtime/helper-merge' }, 'merge': { module: 'marko/runtime/helper-merge' },
'renderComponent': { module: 'marko/components/taglib/helpers/renderComponent' },
'str': 's', 'str': 's',
'styleAttr': { 'styleAttr': {
vdom: { module: 'marko/runtime/vdom/helper-styleAttr'}, vdom: { module: 'marko/runtime/vdom/helper-styleAttr'},

View File

@ -432,6 +432,10 @@ class CustomTag extends HtmlElement {
return this._nestedTagVar; return this._nestedTagVar;
} }
generateRenderTagCode(codegen, tagVar, tagArgs) {
return codegen.builder.functionCall(tagVar, tagArgs);
}
generateCode(codegen) { generateCode(codegen) {
if (this.type !== 'CustomTag') { if (this.type !== 'CustomTag') {
throw new Error(this.type); throw new Error(this.type);
@ -601,8 +605,7 @@ class CustomTag extends HtmlElement {
let loadTag = builder.functionCall(context.helper('loadTag'), [templateVar]); let loadTag = builder.functionCall(context.helper('loadTag'), [templateVar]);
let tagVar = codegen.addStaticVar(tagVarName, loadTag); let tagVar = codegen.addStaticVar(tagVarName, loadTag);
let tagFunctionCall = builder.functionCall(tagVar, [ inputProps, 'out' ]); finalNode = this.generateRenderTagCode(codegen, tagVar, [ inputProps, builder.identifierOut() ]);
finalNode = tagFunctionCall;
} else { } else {
if (rendererRequirePath) { if (rendererRequirePath) {
codegen.pushMeta('tags', builder.literal(rendererRequirePath), true); codegen.pushMeta('tags', builder.literal(rendererRequirePath), true);
@ -631,8 +634,11 @@ class CustomTag extends HtmlElement {
let tagVar = codegen.addStaticVar(tagVarName, loadTag); let tagVar = codegen.addStaticVar(tagVarName, loadTag);
let tagFunctionCall = builder.functionCall(tagVar, tagArgs); if (isNestedTag) {
finalNode = tagFunctionCall; finalNode = builder.functionCall(tagVar, tagArgs);
} else {
finalNode = this.generateRenderTagCode(codegen, tagVar, tagArgs);
}
} }
if (bodyOnlyIf && renderBodyFunctionVar) { if (bodyOnlyIf && renderBodyFunctionVar) {

View File

@ -52,9 +52,10 @@ function createRendererFunc(templateRenderFunc, componentProps) {
isExisting = true; isExisting = true;
outGlobal.$w = null; outGlobal.$w = null;
} else { } else {
var componentArgs = input && input.$w || out.data.$w; var componentArgs = out.$c;
if (componentArgs) { if (componentArgs) {
out.$c = null;
scope = componentArgs[0]; scope = componentArgs[0];
if (scope) { if (scope) {

View File

@ -60,11 +60,9 @@ function handleBeginAsync(event) {
var nestedComponentsContext = new ComponentsContext(asyncOut, componentStack[componentStack.length-1]); var nestedComponentsContext = new ComponentsContext(asyncOut, componentStack[componentStack.length-1]);
asyncOut.data.components = nestedComponentsContext; asyncOut.data.components = nestedComponentsContext;
} }
asyncOut.data.$w = parentOut.data.$w; asyncOut.$c = parentOut.$c;
} }
function createRendererFunc(templateRenderFunc, componentProps, renderingLogic) { function createRendererFunc(templateRenderFunc, componentProps, renderingLogic) {
if (typeof renderingLogic == 'function') { if (typeof renderingLogic == 'function') {
var ctor = renderingLogic; var ctor = renderingLogic;
@ -101,9 +99,11 @@ function createRendererFunc(templateRenderFunc, componentProps, renderingLogic)
isExisting = true; isExisting = true;
outGlobal.$w = null; outGlobal.$w = null;
} else { } else {
var componentArgs = input && input.$w || out.data.$w; var componentArgs = out.$c;
if (componentArgs) { if (componentArgs) {
out.$c = null;
scope = componentArgs[0]; scope = componentArgs[0];
if (scope) { if (scope) {
@ -116,7 +116,6 @@ function createRendererFunc(templateRenderFunc, componentProps, renderingLogic)
} }
id = id || resolveComponentKey(out, key, scope); id = id || resolveComponentKey(out, key, scope);
customEvents = componentArgs[2]; customEvents = componentArgs[2];
delete input.$w;
} }
} }

View File

@ -1,5 +1,4 @@
'use strict'; 'use strict';
class ComponentArgs { class ComponentArgs {
constructor() { constructor() {
@ -61,37 +60,34 @@ class ComponentArgs {
args.push(builder.literal(customEvents)); args.push(builder.literal(customEvents));
} }
if (el.tagDef && el.tagDef.template) { if (el.type === 'CustomTag') {
el.setAttributeValue('$w', builder.literal(args)); var renderComponentHelper = transformHelper.context.helper('renderComponent');
el.generateRenderTagCode = function(codegen, tagVar, tagArgs) {
tagArgs = [tagVar].concat(tagArgs);
tagArgs.push(builder.literal(args));
return codegen.builder.functionCall(
renderComponentHelper,
tagArgs);
};
} else { } else {
let componentArgsVar = transformHelper.context.addStaticVar('marko_componentArgs',
builder.require(builder.literal('marko/components/taglib/helpers/componentArgs')));
let componentArgsFunctionCall = builder.functionCall(componentArgsVar, [
builder.identifierOut(),
builder.literal(args)
]);
let cleanupComponentArgsFunctionCall = this.buildCleanupComponentArgsFunctionCall(transformHelper);
el.onBeforeGenerateCode((event) => { el.onBeforeGenerateCode((event) => {
event.insertCode(componentArgsFunctionCall); let lhs = builder.memberExpression(builder.identifierOut(), builder.identifier('$c'));
let rhs = builder.literal(args);
event.insertCode(builder.assignment(lhs, rhs));
}); });
el.onAfterGenerateCode((event) => { el.onAfterGenerateCode((event) => {
event.insertCode(cleanupComponentArgsFunctionCall); let lhs = builder.memberExpression(builder.identifierOut(), builder.identifier('$c'));
let rhs = builder.literalNull();
event.insertCode(builder.assignment(lhs, rhs));
}); });
} }
} }
buildCleanupComponentArgsFunctionCall(transformHelper) {
var context = transformHelper.context;
var builder = transformHelper.builder;
var cleanupComponentArgsVar = context.addStaticVar('marko_cleanupComponentArgs',
'marko_componentArgs.cleanup');
return builder.functionCall(cleanupComponentArgsVar, [builder.identifierOut()]);
}
} }
module.exports = ComponentArgs; module.exports = ComponentArgs;

View File

@ -0,0 +1,5 @@
module.exports = function renderCompontent(tagRenderer, input, out, componentArgs) {
out.$c = componentArgs;
tagRenderer(input, out);
out.$c = null;
};

View File

@ -141,6 +141,7 @@
}, },
"minprops": { "minprops": {
"exclude": [ "exclude": [
"$c",
"b", "b",
"be", "be",
"c", "c",

View File

@ -60,6 +60,8 @@ function AsyncStream(global, writer, state, shouldBuffer) {
this._node = undefined; this._node = undefined;
this._elStack = undefined; // Array this._elStack = undefined; // Array
this.$c = null; // Component args
} }
AsyncStream.DEFAULT_TIMEOUT = 10000; AsyncStream.DEFAULT_TIMEOUT = 10000;

View File

@ -40,6 +40,7 @@ function AsyncVDOMBuilder(globalData, parentNode, state) {
this.global = globalData || {}; this.global = globalData || {};
this.$__stack = [parentNode]; this.$__stack = [parentNode];
this.$__sync = false; this.$__sync = false;
this.$c = null; // Component args
} }
var proto = AsyncVDOMBuilder.prototype = { var proto = AsyncVDOMBuilder.prototype = {

View File

@ -0,0 +1,9 @@
class {
onMount() {
this.realFoo = true;
}
}
<div.real-foo>
[real-foo]
</div>

View File

@ -0,0 +1,7 @@
class {
}
<div.root>
<foo key="foo" name="Frank"/>
</div>

View File

@ -0,0 +1,7 @@
var expect = require('chai').expect;
module.exports = function(helpers) {
var component = helpers.mount(require('./index'), { });
var foo = component.getComponent('foo');
expect(foo.realFoo).to.equal(true);
};

View File

@ -9,6 +9,7 @@ var marko_template = module.exports = require("marko/html").t(__filename),
marko_componentType = marko_registerComponent("/marko-test$1.0.0/autotests/components-compilation/key/index.marko", function() { marko_componentType = marko_registerComponent("/marko-test$1.0.0/autotests/components-compilation/key/index.marko", function() {
return module.exports; return module.exports;
}), }),
marko_renderComponent = require("marko/components/taglib/helpers/renderComponent"),
marko_loadTemplate = require("marko/runtime/helper-loadTemplate"), marko_loadTemplate = require("marko/runtime/helper-loadTemplate"),
app_foo_template = marko_loadTemplate(require.resolve("./components/app-foo")), app_foo_template = marko_loadTemplate(require.resolve("./components/app-foo")),
marko_helpers = require("marko/runtime/html/helpers"), marko_helpers = require("marko/runtime/html/helpers"),
@ -23,12 +24,10 @@ function render(input, out, __component, component, state) {
marko_attr("id", __component.id) + marko_attr("id", __component.id) +
">"); ">");
app_foo_tag({ marko_renderComponent(app_foo_tag, {}, out, [
$w: [ __component,
__component, "foo"
"foo" ]);
]
}, out);
out.w("<a href=\"ebay.com\"" + out.w("<a href=\"ebay.com\"" +
marko_attr("id", __component.elId("link")) + marko_attr("id", __component.elId("link")) +