add support for class tag

This commit is contained in:
Michael Rawlings 2017-01-23 17:58:48 -08:00
parent 01f1182b63
commit 3bd85d0707
9 changed files with 111 additions and 0 deletions

View File

@ -0,0 +1,7 @@
module.exports = function functionCodeGenerator(el, codegen) {
if(el.parentNode.type !== 'TemplateRoot') {
codegen.addError('class is a static tag and can only be declared at the template root');
}
codegen.addStaticCode(codegen.builder.expression(el.tagString));
return null;
};

View File

@ -9,6 +9,9 @@
}
]
},
"<class>": {
"code-generator": "./class-tag"
},
"<else>": {
"node-factory": "./else-tag",
"attributes": {},

View File

@ -0,0 +1,13 @@
var marko_template = module.exports = require("marko/html").t(__filename);
class Foo {
constructor() {
}
};
function render(data, out) {
var foo = new Foo();
}
marko_template._ = render;

View File

@ -0,0 +1,7 @@
class Foo {
constructor() {
}
}
var foo = new Foo();

View File

@ -11,6 +11,7 @@
"lasso-resource",
"browser-refresh",
"assign",
"class",
"else",
"else-if",
"for",

View File

@ -18,6 +18,7 @@
"body",
"browser-refresh",
"cached-fragment",
"class",
"else",
"else-if",
"foo",

View File

@ -0,0 +1,24 @@
var marko_template = module.exports = require("marko/html").t(__filename),
marko_component = {
foo: function() {},
bar: function() {}
},
marko_widgets = require("marko/widgets"),
marko_registerWidget = marko_widgets.rw,
marko_widgetType = marko_registerWidget("/marko-test$1.0.0/autotests/widgets-compilation/component-inline-class/index.marko", function() {
return module.exports;
}),
marko_helpers = require("marko/runtime/html/helpers"),
marko_attr = marko_helpers.a;
function render(data, out, widget, state) {
out.w("<div" +
marko_attr("id", widget.id) +
"></div>");
}
marko_template._ = marko_widgets.r(render, {
type: marko_widgetType
}, marko_component);
marko_template.Widget = marko_widgets.w(marko_component, marko_template._);

View File

@ -0,0 +1,11 @@
class {
foo() {
}
bar() {
}
}
<div>
</div>

View File

@ -114,6 +114,43 @@ function handleStyleElement(styleEl, transformHelper) {
styleEl.detach();
}
function methodToProperty(method) {
return {
type: 'Property',
key: method.key,
computed: false,
value: method.value,
kind: 'init',
method: true,
shorthand: false
};
}
function classToObject(cls, transformHelper) {
return {
type: 'ObjectExpression',
properties: cls.body.body.map((method) => {
if(method.type != 'MethodDefinition') {
throw Error('Only methods are allowed on single file component class definitions.');
}
return methodToProperty(method);
})
};
}
function handleClassDeclaration(classEl, transformHelper) {
if(!/^class\s*\{/.test(classEl.tagString)) return;
let tree = esprima.parse('('+classEl.tagString+')');
let expression = tree.body[0].expression;
let object = classToObject(expression);
let componentVar = transformHelper.context.addStaticVar('marko_component', escodegen.generate(object));
transformHelper.setHasBoundWidgetForTemplate();
transformHelper.setInlineComponent(componentVar);
classEl.detach()
}
module.exports = function handleRootNodes() {
var context = this.context;
var builder = this.builder;
@ -177,9 +214,16 @@ module.exports = function handleRootNodes() {
return;
} else if (node.type === 'CustomTag') {
rootNodes.push(node);
walker.skip();
return;
} else {
var tagName = node.tagName && node.tagName.toLowerCase();
if (tagName === 'class') {
handleClassDeclaration(node, transformHelper);
}
walker.skip();
return;
}