ember-css-modules 1.6.0 → 2.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -4,12 +4,17 @@ import require from 'require';
4
4
 
5
5
  export function localClass(params, hash) {
6
6
  assert('No source specified to local-class lookup', 'from' in hash);
7
- if (!hash.from) { return ''; }
7
+ if (!hash.from) {
8
+ return '';
9
+ }
8
10
 
9
11
  let styles = resolveSource(hash.from);
10
12
  let classes = (params[0] || '').split(/\s+/);
11
13
 
12
- return classes.map(style => styles[style]).filter(Boolean).join(' ');
14
+ return classes
15
+ .map((style) => styles[style])
16
+ .filter(Boolean)
17
+ .join(' ');
13
18
  }
14
19
 
15
20
  export default helper(localClass);
@@ -19,7 +24,9 @@ function resolveSource(source) {
19
24
  if (require.has(source)) {
20
25
  return require(source).default;
21
26
  } else {
22
- throw new Error(`Unable to resolve local class names from ${source}; does the styles file exist?`);
27
+ throw new Error(
28
+ `Unable to resolve local class names from ${source}; does the styles file exist?`
29
+ );
23
30
  }
24
31
  } else {
25
32
  return source;
package/addon/index.js CHANGED
@@ -1 +0,0 @@
1
- export * from './decorators';
@@ -8,5 +8,5 @@ export default {
8
8
  // Instead, we reference it in our own template, and then import that
9
9
  // template from a file (an initializer) that we know must always
10
10
  // be loaded in order to boot the app and/or run tests.
11
- }
12
- }
11
+ },
12
+ };
@@ -1,5 +1,5 @@
1
1
  'use strict';
2
2
 
3
- module.exports = function(/* environment, appConfig */) {
4
- return { };
3
+ module.exports = function (/* environment, appConfig */) {
4
+ return {};
5
5
  };
package/index.js CHANGED
@@ -3,8 +3,6 @@
3
3
  const path = require('path');
4
4
  const fs = require('fs');
5
5
  const debug = require('debug')('ember-css-modules:addon');
6
- const VersionChecker = require('ember-cli-version-checker');
7
- const MergeTrees = require('broccoli-merge-trees');
8
6
 
9
7
  const HtmlbarsPlugin = require('./lib/htmlbars-plugin');
10
8
  const ModulesPreprocessor = require('./lib/modules-preprocessor');
@@ -14,16 +12,12 @@ const PluginRegistry = require('./lib/plugin/registry');
14
12
  module.exports = {
15
13
  name: require('./package.json').name,
16
14
 
17
- shouldIncludeChildAddon(addon) {
18
- // Don't infinitely recurse – it's the dummy test app that depends on dummy-addon, not this addon itself
19
- return addon.name.indexOf('dummy') === -1;
20
- },
21
-
22
15
  init() {
23
16
  this._super.init && this._super.init.apply(this, arguments);
24
17
  this.modulesPreprocessor = new ModulesPreprocessor({ owner: this });
25
- this.outputStylesPreprocessor = new OutputStylesPreprocessor({ owner: this });
26
- this.checker = new VersionChecker(this.project);
18
+ this.outputStylesPreprocessor = new OutputStylesPreprocessor({
19
+ owner: this,
20
+ });
27
21
  this.plugins = new PluginRegistry(this.parent);
28
22
  },
29
23
 
@@ -37,33 +31,17 @@ module.exports = {
37
31
 
38
32
  this._super.included.apply(this, arguments);
39
33
 
40
- this.cssModulesOptions = this.plugins.computeOptions(includer.options && includer.options.cssModules);
34
+ this.cssModulesOptions = this.plugins.computeOptions(
35
+ includer.options && includer.options.cssModules
36
+ );
41
37
  this.setupTemplateTransform();
42
38
  },
43
39
 
44
- treeForAddon() {
45
- let addonTree = this._super.treeForAddon.apply(this, arguments);
46
-
47
- // Allow to opt-out from automatic Component.reopen()
48
- if (this.cssModulesOptions.patchClassicComponent !== false) {
49
- return new MergeTrees([addonTree, `${__dirname}/vendor`]);
50
- } else {
51
- return addonTree;
52
- }
53
- },
54
-
55
- cacheKeyForTree(treeType) {
56
- // We override treeForAddon, but the result is still stable
57
- if (treeType === 'addon') {
58
- return require('calculate-cache-key-for-tree')('addon', this);
59
- } else {
60
- return this._super.cacheKeyForTree.call(this, treeType);
61
- }
62
- },
63
-
64
40
  setupPreprocessorRegistry(type, registry) {
65
41
  // Skip if we're setting up this addon's own registry
66
- if (type !== 'parent') { return; }
42
+ if (type !== 'parent') {
43
+ return;
44
+ }
67
45
 
68
46
  this.parentPreprocessorRegistry = registry;
69
47
 
@@ -78,24 +56,32 @@ module.exports = {
78
56
  // options until our own `included()` hook, and we need those options in order
79
57
  // to configure the template transform.
80
58
  if (!this.parentPreprocessorRegistry) {
81
- throw new Error('[ember-css-modules] internal error: unable to locate parent preprocessor registry');
59
+ throw new Error(
60
+ '[ember-css-modules] internal error: unable to locate parent preprocessor registry'
61
+ );
82
62
  }
83
63
 
84
- this.parentPreprocessorRegistry.add('htmlbars-ast-plugin', HtmlbarsPlugin.instantiate({
85
- emberVersion: this.checker.forEmber().version,
86
- options: {
64
+ this.parentPreprocessorRegistry.add(
65
+ 'htmlbars-ast-plugin',
66
+ HtmlbarsPlugin.instantiate({
87
67
  fileExtension: this.getFileExtension(),
88
68
  includeExtensionInModulePath: this.includeExtensionInModulePath(),
89
- },
90
- }));
69
+ })
70
+ );
91
71
  },
92
72
 
93
73
  verifyStylesDirectory() {
94
- if (!fs.existsSync(path.join(this.parent.root, this.parent.treePaths['addon-styles']))) {
74
+ if (
75
+ !fs.existsSync(
76
+ path.join(this.parent.root, this.parent.treePaths['addon-styles'])
77
+ )
78
+ ) {
95
79
  this.ui.writeWarnLine(
96
- 'The addon ' + this.getParentName() + ' has ember-css-modules installed, but no addon styles directory. ' +
97
- 'You must have at least a placeholder file in this directory (e.g. `addon/styles/.placeholder`) in ' +
98
- 'the published addon in order for ember-cli to process its CSS modules.'
80
+ 'The addon ' +
81
+ this.getParentName() +
82
+ ' has ember-css-modules installed, but no addon styles directory. ' +
83
+ 'You must have at least a placeholder file in this directory (e.g. `addon/styles/.placeholder`) in ' +
84
+ 'the published addon in order for ember-cli to process its CSS modules.'
99
85
  );
100
86
  }
101
87
  },
@@ -117,15 +103,24 @@ module.exports = {
117
103
  },
118
104
 
119
105
  getPassthroughFileExtensions() {
120
- return this.cssModulesOptions.passthroughFileExtensions || ['css', 'scss', 'sass', 'less', 'styl'];
106
+ return (
107
+ this.cssModulesOptions.passthroughFileExtensions || [
108
+ 'css',
109
+ 'scss',
110
+ 'sass',
111
+ 'less',
112
+ 'styl',
113
+ ]
114
+ );
121
115
  },
122
116
 
123
117
  getScopedNameGenerator() {
124
118
  if (!this._scopedNameGenerator) {
125
119
  let rootOptions = this._findRootApp().options.cssModules || {};
126
- this._scopedNameGenerator = this.cssModulesOptions.generateScopedName
127
- || rootOptions.generateScopedName
128
- || require('./lib/generate-scoped-name');
120
+ this._scopedNameGenerator =
121
+ this.cssModulesOptions.generateScopedName ||
122
+ rootOptions.generateScopedName ||
123
+ require('./lib/generate-scoped-name');
129
124
  }
130
125
 
131
126
  return this._scopedNameGenerator;
@@ -156,7 +151,9 @@ module.exports = {
156
151
  },
157
152
 
158
153
  getFileExtension() {
159
- return this.cssModulesOptions && this.cssModulesOptions.extension || 'css';
154
+ return (
155
+ (this.cssModulesOptions && this.cssModulesOptions.extension) || 'css'
156
+ );
160
157
  },
161
158
 
162
159
  includeExtensionInModulePath() {
@@ -167,15 +164,6 @@ module.exports = {
167
164
  return this.cssModulesOptions.postcssOptions;
168
165
  },
169
166
 
170
- getAddonModulesRoot() {
171
- // CLI 2.12 stopped exposing addon stuff nested under `modules/`
172
- if (this.checker.for('ember-cli', 'npm').satisfies('< 2.12')) {
173
- return 'modules/';
174
- } else {
175
- return '';
176
- }
177
- },
178
-
179
167
  getParentAddonTree() {
180
168
  return path.join(this.parentAddon.root, this.parentAddon.treePaths.addon);
181
169
  },
@@ -183,13 +171,16 @@ module.exports = {
183
171
  getFixedModules(type) {
184
172
  let modules = this.cssModulesOptions[`${type}Modules`] || [];
185
173
  let extension = this.getFileExtension();
186
- return modules.map(file => file.endsWith(`.${extension}`) ? file : `${file}.${extension}`);
174
+ return modules.map((file) =>
175
+ file.endsWith(`.${extension}`) ? file : `${file}.${extension}`
176
+ );
187
177
  },
188
178
 
189
179
  enableSourceMaps() {
190
180
  if (this._enableSourceMaps === undefined) {
191
181
  var mapOptions = this._findRootApp().options.sourcemaps;
192
- this._enableSourceMaps = mapOptions.enabled && mapOptions.extensions.indexOf('css') !== -1;
182
+ this._enableSourceMaps =
183
+ mapOptions.enabled && mapOptions.extensions.indexOf('css') !== -1;
193
184
  }
194
185
 
195
186
  return this._enableSourceMaps;
@@ -205,5 +196,5 @@ module.exports = {
205
196
  current = current.parent;
206
197
  }
207
198
  return current.app;
208
- }
199
+ },
209
200
  };
@@ -1,7 +1,6 @@
1
1
  'use strict';
2
2
 
3
3
  const utils = require('./utils');
4
- const semver = require('semver');
5
4
 
6
5
  module.exports = class ClassTransformPlugin {
7
6
  constructor(env, options) {
@@ -9,27 +8,21 @@ module.exports = class ClassTransformPlugin {
9
8
  this.builders = env.syntax.builders;
10
9
  this.options = options;
11
10
  this.stylesModule = this.determineStylesModule(env);
12
- this.isGlimmer = this.detectGlimmer();
13
11
  this.visitor = this.buildVisitor(env);
14
-
15
- // Alias for 2.15 <= Ember < 3.1
16
- this.visitors = this.visitor;
17
12
  }
18
13
 
19
- static instantiate({ emberVersion, options }) {
14
+ static instantiate(options) {
20
15
  return {
21
16
  name: 'ember-css-modules',
22
- plugin: semver.lt(emberVersion, '2.15.0-alpha')
23
- ? LegacyAdapter.bind(null, this, options)
24
- : env => new this(env, options),
17
+ plugin: (env) => new this(env, options),
25
18
  parallelBabel: {
26
19
  requireFile: __filename,
27
20
  buildUsing: 'instantiate',
28
- params: { emberVersion, options },
21
+ params: options,
29
22
  },
30
23
  baseDir() {
31
24
  return `${__dirname}/../..`;
32
- }
25
+ },
33
26
  };
34
27
  }
35
28
 
@@ -54,15 +47,6 @@ module.exports = class ClassTransformPlugin {
54
47
  return name;
55
48
  }
56
49
 
57
- detectGlimmer() {
58
- if (!this.syntax.parse) { return false; }
59
-
60
- // HTMLBars builds ConcatStatements with StringLiterals + raw PathExpressions
61
- // Glimmer builds ConcatStatements with TextNodes + MustacheStatements
62
- let ast = this.syntax.parse('<div class="foo {{bar}}"></div>');
63
- return ast.body[0].attributes[0].value.parts[0].type === 'TextNode';
64
- }
65
-
66
50
  buildVisitor(env) {
67
51
  if (env.moduleName === env.filename) {
68
52
  // No-op for the stage 1 Embroider pass (which only contains relative paths)
@@ -70,10 +54,10 @@ module.exports = class ClassTransformPlugin {
70
54
  }
71
55
 
72
56
  return {
73
- ElementNode: node => this.transformElementNode(node),
74
- MustacheStatement: node => this.transformStatement(node),
75
- BlockStatement: node => this.transformStatement(node),
76
- SubExpression: node => this.transformSubexpression(node)
57
+ ElementNode: (node) => this.transformElementNode(node),
58
+ MustacheStatement: (node) => this.transformStatement(node),
59
+ BlockStatement: (node) => this.transformStatement(node),
60
+ SubExpression: (node) => this.transformSubexpression(node),
77
61
  };
78
62
  }
79
63
 
@@ -93,14 +77,18 @@ module.exports = class ClassTransformPlugin {
93
77
 
94
78
  // Transform {{local-class 'foo'}} into {{local-class 'foo' from='path/to/styles-module'}}
95
79
  transformLocalClassHelperInvocation(node) {
96
- if (utils.getPair(node, 'from')) { return; }
80
+ if (utils.getPair(node, 'from')) {
81
+ return;
82
+ }
97
83
 
98
84
  node.hash.pairs.push(this.builders.pair('from', this.stylesModuleNode()));
99
85
  }
100
86
 
101
87
  transformPossibleComponentInvocation(node) {
102
88
  let localClassPair = utils.getPair(node, 'local-class');
103
- if (!localClassPair) { return; }
89
+ if (!localClassPair) {
90
+ return;
91
+ }
104
92
 
105
93
  utils.removePair(node, localClassPair);
106
94
 
@@ -121,14 +109,15 @@ module.exports = class ClassTransformPlugin {
121
109
 
122
110
  transformElementNode(node) {
123
111
  let localClassAttr = utils.getAttr(node, 'local-class');
124
- if (!localClassAttr) { return; }
112
+ if (!localClassAttr) {
113
+ return;
114
+ }
125
115
 
126
116
  utils.removeAttr(node, localClassAttr);
127
117
 
128
- let stringBuilder = this.isGlimmer ? 'text' : 'string';
129
118
  let classAttr = utils.getAttr(node, 'class');
130
119
  let parts = [];
131
- let classAttrValue
120
+ let classAttrValue;
132
121
 
133
122
  if (classAttr) {
134
123
  utils.removeAttr(node, classAttr);
@@ -138,21 +127,33 @@ module.exports = class ClassTransformPlugin {
138
127
  // the attr value into parts that make up the ConcatStatement
139
128
  // that is returned from this method
140
129
  if (classAttrValue.type === 'ConcatStatement') {
141
- parts.push(this.builders.mustache(this.builders.path('concat'), utils.concatStatementToParams(this.builders, classAttrValue, this.isGlimmer)));
130
+ parts.push(
131
+ this.builders.mustache(
132
+ this.builders.path('concat'),
133
+ utils.concatStatementToParams(this.builders, classAttrValue)
134
+ )
135
+ );
142
136
  } else if (classAttrValue.type === 'TextNode') {
143
- parts.push(this.builders[stringBuilder](classAttrValue.chars));
137
+ parts.push(this.builders.text(classAttrValue.chars));
144
138
  } else if (classAttrValue.type === 'MustacheStatement') {
145
- if (classAttrValue.params.length || this.isGlimmer) {
146
- parts.push(classAttrValue);
147
- } else {
148
- parts.push(this.builders.path(classAttrValue.path.original));
149
- }
139
+ parts.push(classAttrValue);
150
140
  }
151
141
  }
152
142
 
153
143
  utils.pushAll(parts, this.localToPath(localClassAttr.value));
154
- this.divide(parts, this.isGlimmer ? 'text' : 'string');
155
- node.attributes.unshift(this.builders.attr('class', this.builders.concat(parts)));
144
+ this.divide(parts, 'text');
145
+
146
+ let newClassAttr = this.builders.attr('class', this.builders.concat(parts));
147
+ node.attributes.unshift(newClassAttr);
148
+
149
+ // In new-enough versions of Ember (>= 3.25 or so), we need to create a
150
+ // fake good-enough `loc` whose content will start with `class=` to avoid
151
+ // triggering https://github.com/emberjs/ember.js/issues/19392
152
+ if (typeof localClassAttr.loc.slice === 'function') {
153
+ newClassAttr.loc = localClassAttr.loc.slice({
154
+ skipStart: 'local-'.length,
155
+ });
156
+ }
156
157
  }
157
158
 
158
159
  localToPath(node) {
@@ -163,7 +164,11 @@ module.exports = class ClassTransformPlugin {
163
164
  } else if (~['TextNode', 'StringLiteral'].indexOf(node.type)) {
164
165
  return this.staticLocalPath(node);
165
166
  } else {
166
- throw new TypeError('ember-css-modules - invalid type, ' + node.type + ', passed to local-class attribute.');
167
+ throw new TypeError(
168
+ 'ember-css-modules - invalid type, ' +
169
+ node.type +
170
+ ', passed to local-class attribute.'
171
+ );
167
172
  }
168
173
  }
169
174
 
@@ -178,15 +183,23 @@ module.exports = class ClassTransformPlugin {
178
183
  builder = 'mustache';
179
184
  }
180
185
 
181
- let hash = this.builders.hash([this.builders.pair('from', this.stylesModuleNode())]);
182
- let localClassInvocation = this.builders[builder](localClassPath, [node], hash);
186
+ let hash = this.builders.hash([
187
+ this.builders.pair('from', this.stylesModuleNode()),
188
+ ]);
189
+ let localClassInvocation = this.builders[builder](
190
+ localClassPath,
191
+ [node],
192
+ hash
193
+ );
183
194
 
184
195
  return [localClassInvocation];
185
196
  }
186
197
 
187
198
  stylesModuleNode() {
188
199
  if (!this.stylesModule) {
189
- throw new Error('Unable to bind a local class in a template with an unknown moduleName');
200
+ throw new Error(
201
+ 'Unable to bind a local class in a template with an unknown moduleName'
202
+ );
190
203
  }
191
204
 
192
205
  return this.builders.string(this.stylesModule);
@@ -194,7 +207,7 @@ module.exports = class ClassTransformPlugin {
194
207
 
195
208
  concatLocalPath(node) {
196
209
  let concatPath = this.builders.path('concat');
197
- let concatParts = utils.concatStatementToParams(this.builders, node, this.isGlimmer);
210
+ let concatParts = utils.concatStatementToParams(this.builders, node);
198
211
  let concatStatement = this.builders.mustache(concatPath, concatParts);
199
212
  return this.dynamicLocalPath(concatStatement);
200
213
  }
@@ -203,41 +216,33 @@ module.exports = class ClassTransformPlugin {
203
216
  let locals = typeof node.chars === 'string' ? node.chars : node.value;
204
217
  let exprBuilder = typeof node.chars === 'string' ? 'mustache' : 'sexpr';
205
218
 
206
- return [this.builders[exprBuilder](
207
- 'local-class',
208
- [this.builders.string(locals)],
209
- this.builders.hash([this.builders.pair('from', this.stylesModuleNode())])
210
- )];
219
+ return [
220
+ this.builders[exprBuilder](
221
+ 'local-class',
222
+ [this.builders.string(locals)],
223
+ this.builders.hash([
224
+ this.builders.pair('from', this.stylesModuleNode()),
225
+ ])
226
+ ),
227
+ ];
211
228
  }
212
229
 
213
230
  divide(parts, builder) {
214
231
  for (let i = 0; i < parts.length - 1; i++) {
215
232
  if (~['StringLiteral', 'TextNode'].indexOf(parts[i].type)) {
216
- utils.updateStringValue(parts[i], function(str) { return str + ' '; });
233
+ utils.updateStringValue(parts[i], function (str) {
234
+ return str + ' ';
235
+ });
217
236
  } else if (~['StringLiteral', 'TextNode'].indexOf(parts[i + 1].type)) {
218
- utils.updateStringValue(parts[i + 1], function(str) { return ' ' + str; });
237
+ utils.updateStringValue(parts[i + 1], function (str) {
238
+ return ' ' + str;
239
+ });
219
240
  } else {
220
241
  parts.splice(i + 1, 0, this.builders[builder](' '));
221
- i++
242
+ i++;
222
243
  }
223
244
  }
224
245
 
225
246
  return parts;
226
247
  }
227
- }
228
-
229
- // For Ember < 2.15
230
- class LegacyAdapter {
231
- constructor(plugin, options, env) {
232
- this.plugin = plugin;
233
- this.options = options;
234
- this.meta = env.meta;
235
- this.syntax = null;
236
- }
237
-
238
- transform(ast) {
239
- let plugin = new this.plugin(Object.assign({ syntax: this.syntax }, this.meta), this.options);
240
- this.syntax.traverse(ast, plugin.visitor);
241
- return ast;
242
- }
243
- }
248
+ };
@@ -28,7 +28,9 @@ function updateStringValue(node, updater) {
28
28
  }
29
29
 
30
30
  function mustacheToSexpr(builders, node) {
31
- if (node.type !== 'MustacheStatement') { return node; }
31
+ if (node.type !== 'MustacheStatement') {
32
+ return node;
33
+ }
32
34
 
33
35
  var params = node.params.map(textToString.bind(null, builders));
34
36
  return builders.sexpr(node.path, params, node.hash);
@@ -42,10 +44,8 @@ function textToString(builders, node) {
42
44
  }
43
45
  }
44
46
 
45
- function concatStatementToParams(builders, node, isGlimmer) {
46
- if (!isGlimmer) { return node.parts; }
47
-
48
- return node.parts.map(function(part) {
47
+ function concatStatementToParams(builders, node) {
48
+ return node.parts.map(function (part) {
49
49
  if (part.type === 'MustacheStatement') {
50
50
  if (!part.params.length && !part.hash.pairs.length) {
51
51
  return part.path;
@@ -69,7 +69,7 @@ function findBy(target, key, path) {
69
69
  }
70
70
 
71
71
  function pushAll(target, arr) {
72
- for (var i=0;i<arr.length;i++) {
72
+ for (var i = 0; i < arr.length; i++) {
73
73
  target.push(arr[i]);
74
74
  }
75
75
 
@@ -84,5 +84,5 @@ module.exports = {
84
84
  removeAttr: removeAttr,
85
85
  mustacheToSexpr: mustacheToSexpr,
86
86
  updateStringValue: updateStringValue,
87
- concatStatementToParams: concatStatementToParams
87
+ concatStatementToParams: concatStatementToParams,
88
88
  };