Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Try to Implement hbs #336

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions app/services/ember-cli.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import blueprints from '../lib/blueprints';
import config from '../config/environment';
import Ember from 'ember';
import moment from 'moment';
import htmlbarsPrecompilePlugin from "../utils/babel-htmlbars-compiler";

const { inject } = Ember;
const twiddleAppName = 'demo-app';
Expand Down Expand Up @@ -146,6 +147,13 @@ export default Ember.Service.extend({
dependencyResolver: inject.service(),
store: inject.service(),

init(...args) {
if (!Ember.testing) {
Babel.options.plugins.default.push(htmlbarsPrecompilePlugin);
}
return this._super(...args);
},

generate(type) {
return this.get('store').createRecord('gistFile', this.buildProperties(type));
},
Expand Down
81 changes: 81 additions & 0 deletions app/utils/babel-htmlbars-compiler.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
import Ember from "ember";

const compiler = Ember.HTMLBars;

export default function(babel) {

// Taken from https://github.com/pangratz/babel-plugin-htmlbars-inline-precompile/blob/master/index.js

const t = babel.types;

var replaceNodeWithPrecompiledTemplate = function(node, template) {
var compiledTemplateString = "Ember.HTMLBars.template(" + compiler.precompile(template) + ")";

// Prefer calling replaceWithSourceString if it is present.
// this prevents a deprecation warning in Babel 5.6.7+.
//
// TODO: delete the fallback once we only support babel >= 5.6.7.
if (node.replaceWithSourceString) {
node.replaceWithSourceString(compiledTemplateString);
} else {
return compiledTemplateString;
}
};


return new babel.Transformer('htmlbars-inline-precompile', {
ImportDeclaration: function(node, parent, scope, file) {
if (t.isLiteral(node.source, { value: "htmlbars-inline-precompile" })) {
var first = node.specifiers && node.specifiers[0];
if (t.isImportDefaultSpecifier(first)) {
file.importSpecifier = first.local.name;
} else {
var input = file.code;
var usedImportStatement = input.slice(node.start, node.end);
var msg = "Only `import hbs from 'htmlbars-inline-precompile'` is supported. You used: `" + usedImportStatement + "`";
throw file.errorWithNode(node, msg);
}

// Prefer calling dangerouslyRemove instead of remove (if present) to
// suppress a deprecation warning.
//
// TODO: delete the fallback once we only support babel >= 5.5.0.
if (typeof this.dangerouslyRemove === 'function') {
this.dangerouslyRemove();
} else {
this.remove();
}
}
},

CallExpression: function(node, parent, scope, file) {
if (t.isIdentifier(node.callee, { name: file.importSpecifier })) {
var argumentErrorMsg = "hbs should be invoked with a single argument: the template string";
if (node.arguments.length !== 1) {
throw file.errorWithNode(node, argumentErrorMsg);
}

var template = node.arguments[0].value;
if (typeof template !== "string") {
throw file.errorWithNode(node, argumentErrorMsg);
}

return replaceNodeWithPrecompiledTemplate(this, template);
}
},

TaggedTemplateExpression: function(node, parent, scope, file) {
if (t.isIdentifier(node.tag, { name: file.importSpecifier })) {
if (node.quasi.expressions.length) {
throw file.errorWithNode(node, "placeholders inside a tagged template string are not supported");
}

var template = node.quasi.quasis.map(function(quasi) {
return quasi.value.cooked;
}).join("");

return replaceNodeWithPrecompiledTemplate(this, template);
}
}
});
}