UNPKG

4.2 kBJavaScriptView Raw
1'use strict';
2
3var path = require('path');
4var checker = require('ember-cli-version-checker');
5var utils = require('./utils');
6var hashForDep = require('hash-for-dep');
7
8module.exports = {
9 name: 'ember-cli-htmlbars',
10
11 init: function() {
12 if (this._super.init) { this._super.init.apply(this, arguments); }
13 checker.assertAbove(this, '0.1.2');
14 },
15
16 parentRegistry: null,
17
18 shouldSetupRegistryInIncluded: function() {
19 return !checker.isAbove(this, '0.2.0');
20 },
21
22 setupPreprocessorRegistry: function(type, registry) {
23 // ensure that broccoli-ember-hbs-template-compiler is not processing hbs files
24 registry.remove('template', 'broccoli-ember-hbs-template-compiler');
25
26 registry.add('template', {
27 name: 'ember-cli-htmlbars',
28 ext: 'hbs',
29 _addon: this,
30 toTree: function(tree) {
31 var htmlbarsOptions = this._addon.htmlbarsOptions();
32 return require('./index')(tree, htmlbarsOptions);
33 },
34
35 precompile: function(string) {
36 var htmlbarsOptions = this._addon.htmlbarsOptions();
37 var templateCompiler = htmlbarsOptions.templateCompiler;
38 return utils.template(templateCompiler, string);
39 }
40 });
41
42 if (type === 'parent') {
43 this.parentRegistry = registry;
44 }
45 },
46
47 included: function (app) {
48 this._super.included.apply(this, arguments);
49
50 if (this.shouldSetupRegistryInIncluded()) {
51 this.setupPreprocessorRegistry('parent', app.registry);
52 }
53 },
54
55 projectConfig: function () {
56 return this.project.config(process.env.EMBER_ENV);
57 },
58
59 templateCompilerPath: function() {
60 var config = this.projectConfig();
61 var templateCompilerPath = config['ember-cli-htmlbars'] && config['ember-cli-htmlbars'].templateCompilerPath;
62
63 var ember = this.project.findAddonByName('ember-source');
64 if (ember) {
65 return ember.absolutePaths.templateCompiler;
66 } else if (!templateCompilerPath) {
67 templateCompilerPath = this.project.bowerDirectory + '/ember/ember-template-compiler';
68 }
69
70 var absolutePath = path.resolve(this.project.root, templateCompilerPath);
71
72 if (path.extname(absolutePath) === '') {
73 absolutePath += '.js';
74 }
75
76 return absolutePath;
77 },
78
79 htmlbarsOptions: function() {
80 var projectConfig = this.projectConfig() || {};
81 var EmberENV = projectConfig.EmberENV || {};
82 var templateCompilerPath = this.templateCompilerPath();
83
84 // ensure we get a fresh templateCompilerModuleInstance per ember-addon
85 // instance NOTE: this is a quick hack, and will only work as long as
86 // templateCompilerPath is a single file bundle
87 //
88 // (╯°□°)╯︵ ɹǝqɯǝ
89 //
90 // we will also fix this in ember for future releases
91 delete require.cache[templateCompilerPath];
92
93 global.EmberENV = EmberENV; // Needed for eval time feature flag checks
94 var pluginInfo = this.astPlugins();
95
96 var htmlbarsOptions = {
97 isHTMLBars: true,
98 EmberENV: EmberENV,
99 templateCompiler: require(templateCompilerPath),
100 templateCompilerPath: templateCompilerPath,
101
102 plugins: {
103 ast: pluginInfo.plugins
104 },
105
106 pluginCacheKey: pluginInfo.cacheKeys
107 };
108
109 delete require.cache[templateCompilerPath];
110 delete global.Ember;
111 delete global.EmberENV;
112
113 return htmlbarsOptions;
114 },
115
116 astPlugins: function() {
117 var pluginWrappers = this.parentRegistry.load('htmlbars-ast-plugin');
118 var plugins = [];
119 var cacheKeys = [];
120
121 for (var i = 0; i < pluginWrappers.length; i++) {
122 var wrapper = pluginWrappers[i];
123
124 plugins.push(wrapper.plugin);
125
126 if (typeof wrapper.baseDir === 'function') {
127 var pluginHashForDep = hashForDep(wrapper.baseDir());
128 cacheKeys.push(pluginHashForDep);
129 } else {
130 // support for ember-cli < 2.2.0
131 var log = this.ui.writeDeprecateLine || this.ui.writeLine;
132
133 log.call(this.ui, 'ember-cli-htmlbars is opting out of caching due to an AST plugin that does not provide a caching strategy: `' + wrapper.name + '`.');
134 cacheKeys.push((new Date()).getTime() + '|' + Math.random());
135 }
136 }
137
138 return {
139 plugins: plugins,
140 cacheKeys: cacheKeys
141 };
142 }
143};