FIX: Use proper `iconNode` when compiling virtual dom templates

This commit is contained in:
Robin Ward 2017-09-01 11:20:14 -04:00
parent 0fb7831749
commit cb56dcdf2e
3 changed files with 20 additions and 5 deletions

View File

@ -23,6 +23,8 @@ export function iconNode(id, params) {
return renderIcon('node', id, params); return renderIcon('node', id, params);
} }
Discourse.__widget_helpers.iconNode = iconNode;
export function registerIconRenderer(renderer) { export function registerIconRenderer(renderer) {
_renderers.unshift(renderer); _renderers.unshift(renderer);
} }

View File

@ -7,6 +7,7 @@ const Discourse = Ember.Application.extend({
rootElement: '#main', rootElement: '#main',
_docTitle: document.title, _docTitle: document.title,
RAW_TEMPLATES: {}, RAW_TEMPLATES: {},
__widget_helpers: {},
getURL(url) { getURL(url) {
if (!url) return url; if (!url) return url;

View File

@ -2,7 +2,7 @@ function resolve(path) {
return (path.indexOf('settings') === 0) ? `this.${path}` : path; return (path.indexOf('settings') === 0) ? `this.${path}` : path;
} }
function mustacheValue(node) { function mustacheValue(node, state) {
let path = node.path.original; let path = node.path.original;
switch(path) { switch(path) {
@ -27,8 +27,9 @@ function mustacheValue(node) {
break; break;
case 'fa-icon': case 'fa-icon':
state.helpersUsed.iconNode = true;
let icon = node.params[0].value; let icon = node.params[0].value;
return `virtualDom.h('i.fa.fa-${icon}')`; return `__iN("${icon}")`;
break; break;
default: default:
return `${resolve(path)}`; return `${resolve(path)}`;
@ -40,6 +41,10 @@ class Compiler {
constructor(ast) { constructor(ast) {
this.idx = 0; this.idx = 0;
this.ast = ast; this.ast = ast;
this.state = {
helpersUsed: {}
};
} }
newAcc() { newAcc() {
@ -69,7 +74,7 @@ class Compiler {
node.attributes.forEach(a => { node.attributes.forEach(a => {
const name = a.name === 'class' ? 'className' : a.name; const name = a.name === 'class' ? 'className' : a.name;
if (a.value.type === "MustacheStatement") { if (a.value.type === "MustacheStatement") {
attributes.push(`"${name}":${mustacheValue(a.value)}`); attributes.push(`"${name}":${mustacheValue(a.value, this.state)}`);
} else { } else {
attributes.push(`"${name}":"${a.value.chars}"`); attributes.push(`"${name}":"${a.value.chars}"`);
} }
@ -87,7 +92,7 @@ class Compiler {
return `${parentAcc}.push(${JSON.stringify(node.chars)});`; return `${parentAcc}.push(${JSON.stringify(node.chars)});`;
case "MustacheStatement": case "MustacheStatement":
const value = mustacheValue(node); const value = mustacheValue(node, this.state);
if (value) { if (value) {
instructions.push(`${parentAcc}.push(${value})`); instructions.push(`${parentAcc}.push(${value})`);
} }
@ -139,7 +144,14 @@ function compile(template) {
const compiled = preprocessor.preprocess(template); const compiled = preprocessor.preprocess(template);
const compiler = new Compiler(compiled); const compiler = new Compiler(compiled);
return `function(attrs, state) { var _r = [];\n${compiler.compile()}\nreturn _r; }`; let code = compiler.compile();
let imports = '';
if (compiler.state.helpersUsed.iconNode) {
imports = "var __iN = Discourse.__widget_helpers.iconNode; ";
}
return `function(attrs, state) { ${imports}var _r = [];\n${code}\nreturn _r; }`;
} }
exports.compile = compile; exports.compile = compile;