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' },
'mergeNestedTagsHelper': { module: 'marko/runtime/helper-mergeNestedTags' },
'merge': { module: 'marko/runtime/helper-merge' },
'renderComponent': { module: 'marko/components/taglib/helpers/renderComponent' },
'str': 's',
'styleAttr': {
vdom: { module: 'marko/runtime/vdom/helper-styleAttr'},

View File

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

View File

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

View File

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

View File

@ -1,5 +1,4 @@
'use strict';
class ComponentArgs {
constructor() {
@ -61,37 +60,34 @@ class ComponentArgs {
args.push(builder.literal(customEvents));
}
if (el.tagDef && el.tagDef.template) {
el.setAttributeValue('$w', builder.literal(args));
if (el.type === 'CustomTag') {
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 {
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) => {
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) => {
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": {
"exclude": [
"$c",
"b",
"be",
"c",

View File

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

View File

@ -40,6 +40,7 @@ function AsyncVDOMBuilder(globalData, parentNode, state) {
this.global = globalData || {};
this.$__stack = [parentNode];
this.$__sync = false;
this.$c = null; // Component args
}
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() {
return module.exports;
}),
marko_renderComponent = require("marko/components/taglib/helpers/renderComponent"),
marko_loadTemplate = require("marko/runtime/helper-loadTemplate"),
app_foo_template = marko_loadTemplate(require.resolve("./components/app-foo")),
marko_helpers = require("marko/runtime/html/helpers"),
@ -23,12 +24,10 @@ function render(input, out, __component, component, state) {
marko_attr("id", __component.id) +
">");
app_foo_tag({
$w: [
__component,
"foo"
]
}, out);
marko_renderComponent(app_foo_tag, {}, out, [
__component,
"foo"
]);
out.w("<a href=\"ebay.com\"" +
marko_attr("id", __component.elId("link")) +