ember-css-modules 2.1.0 → 3.0.0-alpha.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.
- package/addon/-runtime.js +1 -0
- package/index.js +19 -16
- package/lib/modules-preprocessor.js +5 -5
- package/package.json +19 -14
- package/addon/helpers/local-class.js +0 -34
- package/addon/index.js +0 -0
- package/addon/templates/static-helpers-hack.hbs +0 -1
- package/app/helpers/local-class.js +0 -1
- package/app/initializers/ensure-local-class-included.js +0 -12
- package/lib/htmlbars-plugin/index.js +0 -248
- package/lib/htmlbars-plugin/utils.js +0 -88
- package/lib/plugin/index.js +0 -29
- package/lib/plugin/registry.js +0 -100
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from 'glimmer-local-class-transform/-runtime';
|
package/index.js
CHANGED
|
@@ -4,10 +4,10 @@ const path = require('path');
|
|
|
4
4
|
const fs = require('fs');
|
|
5
5
|
const debug = require('debug')('ember-css-modules:addon');
|
|
6
6
|
|
|
7
|
-
const
|
|
7
|
+
const { localClassRegistryPlugin } = require('glimmer-local-class-transform');
|
|
8
8
|
const ModulesPreprocessor = require('./lib/modules-preprocessor');
|
|
9
9
|
const OutputStylesPreprocessor = require('./lib/output-styles-preprocessor');
|
|
10
|
-
const
|
|
10
|
+
const normalizePostcssPlugins = require('./lib/utils/normalize-postcss-plugins');
|
|
11
11
|
|
|
12
12
|
module.exports = {
|
|
13
13
|
name: require('./package.json').name,
|
|
@@ -18,7 +18,6 @@ module.exports = {
|
|
|
18
18
|
this.outputStylesPreprocessor = new OutputStylesPreprocessor({
|
|
19
19
|
owner: this,
|
|
20
20
|
});
|
|
21
|
-
this.plugins = new PluginRegistry(this.parent);
|
|
22
21
|
},
|
|
23
22
|
|
|
24
23
|
included(includer) {
|
|
@@ -31,9 +30,11 @@ module.exports = {
|
|
|
31
30
|
|
|
32
31
|
this._super.included.apply(this, arguments);
|
|
33
32
|
|
|
34
|
-
this.cssModulesOptions =
|
|
35
|
-
|
|
33
|
+
this.cssModulesOptions = includer.options?.cssModules ?? {};
|
|
34
|
+
this.cssModulesOptions.plugins = normalizePostcssPlugins(
|
|
35
|
+
this.cssModulesOptions.plugins
|
|
36
36
|
);
|
|
37
|
+
|
|
37
38
|
this.setupTemplateTransform();
|
|
38
39
|
},
|
|
39
40
|
|
|
@@ -61,12 +62,20 @@ module.exports = {
|
|
|
61
62
|
);
|
|
62
63
|
}
|
|
63
64
|
|
|
65
|
+
let fileExtension = `.${this.getFileExtension()}`;
|
|
66
|
+
let defaultExtension = this.includeExtensionInModulePath()
|
|
67
|
+
? fileExtension
|
|
68
|
+
: '';
|
|
69
|
+
let runtimeModule = 'ember-css-modules/-runtime';
|
|
70
|
+
let pathMapping = {
|
|
71
|
+
'/template\\.hbs$': `/styles${defaultExtension}`,
|
|
72
|
+
'/templates/(.*/)?(.*)\\.hbs$': `/styles/$1$2${defaultExtension}`,
|
|
73
|
+
'(\\.g?[tj]s|\\.hbs)+$': fileExtension,
|
|
74
|
+
};
|
|
75
|
+
|
|
64
76
|
this.parentPreprocessorRegistry.add(
|
|
65
77
|
'htmlbars-ast-plugin',
|
|
66
|
-
|
|
67
|
-
fileExtension: this.getFileExtension(),
|
|
68
|
-
includeExtensionInModulePath: this.includeExtensionInModulePath(),
|
|
69
|
-
})
|
|
78
|
+
localClassRegistryPlugin({ pathMapping, runtimeModule })
|
|
70
79
|
);
|
|
71
80
|
},
|
|
72
81
|
|
|
@@ -86,10 +95,6 @@ module.exports = {
|
|
|
86
95
|
}
|
|
87
96
|
},
|
|
88
97
|
|
|
89
|
-
notifyPlugins(event) {
|
|
90
|
-
this.plugins.notify(event);
|
|
91
|
-
},
|
|
92
|
-
|
|
93
98
|
getParentName() {
|
|
94
99
|
return this.app ? this.app.name : this.parent.name;
|
|
95
100
|
},
|
|
@@ -151,9 +156,7 @@ module.exports = {
|
|
|
151
156
|
},
|
|
152
157
|
|
|
153
158
|
getFileExtension() {
|
|
154
|
-
return (
|
|
155
|
-
(this.cssModulesOptions && this.cssModulesOptions.extension) || 'css'
|
|
156
|
-
);
|
|
159
|
+
return (this.cssModulesOptions.extension ?? 'css').replace(/^\./, '');
|
|
157
160
|
},
|
|
158
161
|
|
|
159
162
|
includeExtensionInModulePath() {
|
|
@@ -75,10 +75,6 @@ module.exports = class ModulesPreprocessor {
|
|
|
75
75
|
generateScopedName: this.scopedNameGenerator(),
|
|
76
76
|
resolvePath: this.resolveAndRecordPath.bind(this),
|
|
77
77
|
getJSFilePath: (cssPath) => this.getJSFilePath(cssPath, modulesSources),
|
|
78
|
-
onBuildStart: () => this.owner.notifyPlugins('buildStart'),
|
|
79
|
-
onBuildEnd: () => this.owner.notifyPlugins('buildEnd'),
|
|
80
|
-
onBuildSuccess: () => this.owner.notifyPlugins('buildSuccess'),
|
|
81
|
-
onBuildError: () => this.owner.notifyPlugins('buildError'),
|
|
82
78
|
onProcessFile: this.resetFileDependencies.bind(this),
|
|
83
79
|
onModuleResolutionFailure: this.onModuleResolutionFailure.bind(this),
|
|
84
80
|
onImportResolutionFailure: this.onImportResolutionFailure.bind(this),
|
|
@@ -115,7 +111,11 @@ module.exports = class ModulesPreprocessor {
|
|
|
115
111
|
''
|
|
116
112
|
);
|
|
117
113
|
|
|
118
|
-
if (
|
|
114
|
+
if (
|
|
115
|
+
['hbs', 'gjs', 'gts'].some((ext) =>
|
|
116
|
+
modulesSource.has(`${cssPathWithoutExtension}.${ext}`)
|
|
117
|
+
)
|
|
118
|
+
) {
|
|
119
119
|
return `${cssPathWithExtension}.js`;
|
|
120
120
|
} else {
|
|
121
121
|
return `${cssPathWithoutExtension}.js`;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "ember-css-modules",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "3.0.0-alpha.1",
|
|
4
4
|
"description": "CSS Modules for ambitious applications",
|
|
5
5
|
"scripts": {
|
|
6
6
|
"build": "ember build --environment=production",
|
|
@@ -17,14 +17,20 @@
|
|
|
17
17
|
"test:node": "qunit tests-node/**/*-test.js"
|
|
18
18
|
},
|
|
19
19
|
"engines": {
|
|
20
|
-
"node": "
|
|
20
|
+
"node": ">= 22.15.0"
|
|
21
21
|
},
|
|
22
22
|
"bugs": {
|
|
23
23
|
"url": "https://github.com/salsify/ember-css-modules/issues"
|
|
24
24
|
},
|
|
25
|
-
"homepage": "https://github.com/salsify/ember-css-modules
|
|
25
|
+
"homepage": "https://github.com/salsify/ember-css-modules/tree/master/packages/ember-local-class",
|
|
26
|
+
"repository": {
|
|
27
|
+
"type": "git",
|
|
28
|
+
"url": "git+ssh://git@github.com/salsify/ember-css-modules.git",
|
|
29
|
+
"directory": "packages/ember-css-modules"
|
|
30
|
+
},
|
|
26
31
|
"devDependencies": {
|
|
27
32
|
"@ember/optional-features": "^2.0.0",
|
|
33
|
+
"@ember/string": "^3.1.1",
|
|
28
34
|
"@ember/test-helpers": "^2.4.2",
|
|
29
35
|
"@embroider/test-setup": "^0.43.5",
|
|
30
36
|
"@glimmer/component": "^1.0.4",
|
|
@@ -33,15 +39,15 @@
|
|
|
33
39
|
"broccoli-plugin": "^1.3.1",
|
|
34
40
|
"console-ui": "^2.2.2",
|
|
35
41
|
"ember-auto-import": "^2.2.4",
|
|
36
|
-
"ember-cli": "~
|
|
37
|
-
"ember-cli-
|
|
42
|
+
"ember-cli": "~5.8.0",
|
|
43
|
+
"ember-cli-htmlbars": "^6.3.0",
|
|
38
44
|
"ember-cli-inject-live-reload": "^2.1.0",
|
|
39
45
|
"ember-disable-prototype-extensions": "^1.1.3",
|
|
40
46
|
"ember-load-initializers": "^2.1.2",
|
|
41
47
|
"ember-page-title": "^6.2.2",
|
|
42
48
|
"ember-qunit": "^5.1.4",
|
|
43
49
|
"ember-resolver": "^8.0.3",
|
|
44
|
-
"ember-source": "~
|
|
50
|
+
"ember-source": "~5.8.0",
|
|
45
51
|
"ember-source-channel-url": "^3.0.0",
|
|
46
52
|
"ember-template-lint": "^3.6.0",
|
|
47
53
|
"ember-try": "^1.4.0",
|
|
@@ -58,17 +64,12 @@
|
|
|
58
64
|
"qunit": "^2.17.2",
|
|
59
65
|
"qunit-dom": "^2.0.0",
|
|
60
66
|
"sinon": "^4.3.0",
|
|
61
|
-
"template-stuff": "link:tests/dummy/lib/template-stuff",
|
|
62
67
|
"webpack": "^5.64.1"
|
|
63
68
|
},
|
|
64
69
|
"keywords": [
|
|
65
70
|
"ember-addon",
|
|
66
71
|
"css-modules"
|
|
67
72
|
],
|
|
68
|
-
"repository": {
|
|
69
|
-
"type": "git",
|
|
70
|
-
"url": "git+ssh://git@github.com/salsify/ember-css-modules.git"
|
|
71
|
-
},
|
|
72
73
|
"license": "MIT",
|
|
73
74
|
"author": "Dan Freeman",
|
|
74
75
|
"dependencies": {
|
|
@@ -79,14 +80,18 @@
|
|
|
79
80
|
"broccoli-merge-trees": "^4.2.0",
|
|
80
81
|
"broccoli-postcss": "^6.0.0",
|
|
81
82
|
"debug": "^4.3.2",
|
|
82
|
-
"ember-
|
|
83
|
-
"ember-cli-
|
|
83
|
+
"ember-auto-import": "^2.7.3",
|
|
84
|
+
"ember-cli-babel": "^8.2.0",
|
|
84
85
|
"ensure-posix-path": "^1.0.2",
|
|
86
|
+
"glimmer-local-class-transform": "^1.0.0-alpha.0",
|
|
85
87
|
"hash-string": "^1.0.0",
|
|
86
88
|
"lodash.merge": "^4.6.1",
|
|
87
89
|
"postcss": "^8.0.0",
|
|
88
90
|
"toposort": "^2.0.2"
|
|
89
91
|
},
|
|
92
|
+
"peerDependencies": {
|
|
93
|
+
"@babel/core": "^7.0.0"
|
|
94
|
+
},
|
|
90
95
|
"ember": {
|
|
91
96
|
"edition": "octane"
|
|
92
97
|
},
|
|
@@ -105,6 +110,6 @@
|
|
|
105
110
|
]
|
|
106
111
|
},
|
|
107
112
|
"volta": {
|
|
108
|
-
"
|
|
113
|
+
"extends": "../../package.json"
|
|
109
114
|
}
|
|
110
115
|
}
|
|
@@ -1,34 +0,0 @@
|
|
|
1
|
-
import { helper } from '@ember/component/helper';
|
|
2
|
-
import { assert } from '@ember/debug';
|
|
3
|
-
import require from 'require';
|
|
4
|
-
|
|
5
|
-
export function localClass(params, hash) {
|
|
6
|
-
assert('No source specified to local-class lookup', 'from' in hash);
|
|
7
|
-
if (!hash.from) {
|
|
8
|
-
return '';
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
let styles = resolveSource(hash.from);
|
|
12
|
-
let classes = (params[0] || '').split(/\s+/);
|
|
13
|
-
|
|
14
|
-
return classes
|
|
15
|
-
.map((style) => styles[style])
|
|
16
|
-
.filter(Boolean)
|
|
17
|
-
.join(' ');
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
export default helper(localClass);
|
|
21
|
-
|
|
22
|
-
function resolveSource(source) {
|
|
23
|
-
if (typeof source === 'string') {
|
|
24
|
-
if (require.has(source)) {
|
|
25
|
-
return require(source).default;
|
|
26
|
-
} else {
|
|
27
|
-
throw new Error(
|
|
28
|
-
`Unable to resolve local class names from ${source}; does the styles file exist?`
|
|
29
|
-
);
|
|
30
|
-
}
|
|
31
|
-
} else {
|
|
32
|
-
return source;
|
|
33
|
-
}
|
|
34
|
-
}
|
package/addon/index.js
DELETED
|
File without changes
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{{local-class "hello"}}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export { default, localClass } from 'ember-css-modules/helpers/local-class';
|
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
import 'ember-css-modules/templates/static-helpers-hack';
|
|
2
|
-
|
|
3
|
-
export default {
|
|
4
|
-
initialize() {
|
|
5
|
-
// This file exists to support Embroider's `staticHelpers` option.
|
|
6
|
-
// ECM relies on the existence of a `local-class` helper, but that
|
|
7
|
-
// helper may never be statically referenced in an application template.
|
|
8
|
-
// Instead, we reference it in our own template, and then import that
|
|
9
|
-
// template from a file (an initializer) that we know must always
|
|
10
|
-
// be loaded in order to boot the app and/or run tests.
|
|
11
|
-
},
|
|
12
|
-
};
|
|
@@ -1,248 +0,0 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
|
|
3
|
-
const utils = require('./utils');
|
|
4
|
-
|
|
5
|
-
module.exports = class ClassTransformPlugin {
|
|
6
|
-
constructor(env, options) {
|
|
7
|
-
this.syntax = env.syntax;
|
|
8
|
-
this.builders = env.syntax.builders;
|
|
9
|
-
this.options = options;
|
|
10
|
-
this.stylesModule = this.determineStylesModule(env);
|
|
11
|
-
this.visitor = this.buildVisitor(env);
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
static instantiate(options) {
|
|
15
|
-
return {
|
|
16
|
-
name: 'ember-css-modules',
|
|
17
|
-
plugin: (env) => new this(env, options),
|
|
18
|
-
parallelBabel: {
|
|
19
|
-
requireFile: __filename,
|
|
20
|
-
buildUsing: 'instantiate',
|
|
21
|
-
params: options,
|
|
22
|
-
},
|
|
23
|
-
baseDir() {
|
|
24
|
-
return `${__dirname}/../..`;
|
|
25
|
-
},
|
|
26
|
-
};
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
determineStylesModule(env) {
|
|
30
|
-
if (!env || !env.moduleName) return;
|
|
31
|
-
|
|
32
|
-
let includeExtension = this.options.includeExtensionInModulePath;
|
|
33
|
-
let name = env.moduleName.replace(/\.\w+$/, '');
|
|
34
|
-
|
|
35
|
-
if (name.endsWith('template')) {
|
|
36
|
-
name = name.replace(/template$/, 'styles');
|
|
37
|
-
} else if (name.includes('/templates/')) {
|
|
38
|
-
name = name.replace('/templates/', '/styles/');
|
|
39
|
-
} else if (name.includes('/components/')) {
|
|
40
|
-
includeExtension = true;
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
if (includeExtension) {
|
|
44
|
-
name = `${name}.${this.options.fileExtension}`;
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
return name;
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
buildVisitor(env) {
|
|
51
|
-
if (env.moduleName === env.filename) {
|
|
52
|
-
// No-op for the stage 1 Embroider pass (which only contains relative paths)
|
|
53
|
-
return {};
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
return {
|
|
57
|
-
ElementNode: (node) => this.transformElementNode(node),
|
|
58
|
-
MustacheStatement: (node) => this.transformStatement(node),
|
|
59
|
-
BlockStatement: (node) => this.transformStatement(node),
|
|
60
|
-
SubExpression: (node) => this.transformSubexpression(node),
|
|
61
|
-
};
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
transformStatement(node) {
|
|
65
|
-
if (node.path.original === 'local-class') {
|
|
66
|
-
this.transformLocalClassHelperInvocation(node);
|
|
67
|
-
} else {
|
|
68
|
-
this.transformPossibleComponentInvocation(node);
|
|
69
|
-
}
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
transformSubexpression(node) {
|
|
73
|
-
if (node.path.original === 'local-class') {
|
|
74
|
-
this.transformLocalClassHelperInvocation(node);
|
|
75
|
-
}
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
// Transform {{local-class 'foo'}} into {{local-class 'foo' from='path/to/styles-module'}}
|
|
79
|
-
transformLocalClassHelperInvocation(node) {
|
|
80
|
-
if (utils.getPair(node, 'from')) {
|
|
81
|
-
return;
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
node.hash.pairs.push(this.builders.pair('from', this.stylesModuleNode()));
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
transformPossibleComponentInvocation(node) {
|
|
88
|
-
let localClassPair = utils.getPair(node, 'local-class');
|
|
89
|
-
if (!localClassPair) {
|
|
90
|
-
return;
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
utils.removePair(node, localClassPair);
|
|
94
|
-
|
|
95
|
-
let classPair = utils.getPair(node, 'class');
|
|
96
|
-
let params = [];
|
|
97
|
-
let concatSexpr;
|
|
98
|
-
|
|
99
|
-
if (classPair) {
|
|
100
|
-
params.push(classPair.value);
|
|
101
|
-
utils.removePair(node, classPair);
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
utils.pushAll(params, this.localToPath(localClassPair.value));
|
|
105
|
-
this.divide(params, 'string');
|
|
106
|
-
concatSexpr = this.builders.sexpr(this.builders.path('concat'), params);
|
|
107
|
-
node.hash.pairs.push(this.builders.pair('class', concatSexpr));
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
transformElementNode(node) {
|
|
111
|
-
let localClassAttr = utils.getAttr(node, 'local-class');
|
|
112
|
-
if (!localClassAttr) {
|
|
113
|
-
return;
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
utils.removeAttr(node, localClassAttr);
|
|
117
|
-
|
|
118
|
-
let classAttr = utils.getAttr(node, 'class');
|
|
119
|
-
let parts = [];
|
|
120
|
-
let classAttrValue;
|
|
121
|
-
|
|
122
|
-
if (classAttr) {
|
|
123
|
-
utils.removeAttr(node, classAttr);
|
|
124
|
-
classAttrValue = classAttr.value;
|
|
125
|
-
|
|
126
|
-
// Unwrap the original class attribute value and transform
|
|
127
|
-
// the attr value into parts that make up the ConcatStatement
|
|
128
|
-
// that is returned from this method
|
|
129
|
-
if (classAttrValue.type === 'ConcatStatement') {
|
|
130
|
-
parts.push(
|
|
131
|
-
this.builders.mustache(
|
|
132
|
-
this.builders.path('concat'),
|
|
133
|
-
utils.concatStatementToParams(this.builders, classAttrValue)
|
|
134
|
-
)
|
|
135
|
-
);
|
|
136
|
-
} else if (classAttrValue.type === 'TextNode') {
|
|
137
|
-
parts.push(this.builders.text(classAttrValue.chars));
|
|
138
|
-
} else if (classAttrValue.type === 'MustacheStatement') {
|
|
139
|
-
parts.push(classAttrValue);
|
|
140
|
-
}
|
|
141
|
-
}
|
|
142
|
-
|
|
143
|
-
utils.pushAll(parts, this.localToPath(localClassAttr.value));
|
|
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
|
-
}
|
|
157
|
-
}
|
|
158
|
-
|
|
159
|
-
localToPath(node) {
|
|
160
|
-
if (~['SubExpression', 'MustacheStatement'].indexOf(node.type)) {
|
|
161
|
-
return this.dynamicLocalPath(node);
|
|
162
|
-
} else if (node.type === 'ConcatStatement') {
|
|
163
|
-
return this.concatLocalPath(node);
|
|
164
|
-
} else if (~['TextNode', 'StringLiteral'].indexOf(node.type)) {
|
|
165
|
-
return this.staticLocalPath(node);
|
|
166
|
-
} else {
|
|
167
|
-
throw new TypeError(
|
|
168
|
-
'ember-css-modules - invalid type, ' +
|
|
169
|
-
node.type +
|
|
170
|
-
', passed to local-class attribute.'
|
|
171
|
-
);
|
|
172
|
-
}
|
|
173
|
-
}
|
|
174
|
-
|
|
175
|
-
dynamicLocalPath(node) {
|
|
176
|
-
let localClassPath = this.builders.path('local-class');
|
|
177
|
-
|
|
178
|
-
let builder;
|
|
179
|
-
if (node.type === 'SubExpression') {
|
|
180
|
-
builder = 'sexpr';
|
|
181
|
-
} else if (node.type === 'MustacheStatement') {
|
|
182
|
-
node = utils.mustacheToSexpr(this.builders, node);
|
|
183
|
-
builder = 'mustache';
|
|
184
|
-
}
|
|
185
|
-
|
|
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
|
-
);
|
|
194
|
-
|
|
195
|
-
return [localClassInvocation];
|
|
196
|
-
}
|
|
197
|
-
|
|
198
|
-
stylesModuleNode() {
|
|
199
|
-
if (!this.stylesModule) {
|
|
200
|
-
throw new Error(
|
|
201
|
-
'Unable to bind a local class in a template with an unknown moduleName'
|
|
202
|
-
);
|
|
203
|
-
}
|
|
204
|
-
|
|
205
|
-
return this.builders.string(this.stylesModule);
|
|
206
|
-
}
|
|
207
|
-
|
|
208
|
-
concatLocalPath(node) {
|
|
209
|
-
let concatPath = this.builders.path('concat');
|
|
210
|
-
let concatParts = utils.concatStatementToParams(this.builders, node);
|
|
211
|
-
let concatStatement = this.builders.mustache(concatPath, concatParts);
|
|
212
|
-
return this.dynamicLocalPath(concatStatement);
|
|
213
|
-
}
|
|
214
|
-
|
|
215
|
-
staticLocalPath(node) {
|
|
216
|
-
let locals = typeof node.chars === 'string' ? node.chars : node.value;
|
|
217
|
-
let exprBuilder = typeof node.chars === 'string' ? 'mustache' : 'sexpr';
|
|
218
|
-
|
|
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
|
-
];
|
|
228
|
-
}
|
|
229
|
-
|
|
230
|
-
divide(parts, builder) {
|
|
231
|
-
for (let i = 0; i < parts.length - 1; i++) {
|
|
232
|
-
if (~['StringLiteral', 'TextNode'].indexOf(parts[i].type)) {
|
|
233
|
-
utils.updateStringValue(parts[i], function (str) {
|
|
234
|
-
return str + ' ';
|
|
235
|
-
});
|
|
236
|
-
} else if (~['StringLiteral', 'TextNode'].indexOf(parts[i + 1].type)) {
|
|
237
|
-
utils.updateStringValue(parts[i + 1], function (str) {
|
|
238
|
-
return ' ' + str;
|
|
239
|
-
});
|
|
240
|
-
} else {
|
|
241
|
-
parts.splice(i + 1, 0, this.builders[builder](' '));
|
|
242
|
-
i++;
|
|
243
|
-
}
|
|
244
|
-
}
|
|
245
|
-
|
|
246
|
-
return parts;
|
|
247
|
-
}
|
|
248
|
-
};
|
|
@@ -1,88 +0,0 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
|
|
3
|
-
function removeAttr(node, attribute) {
|
|
4
|
-
node.attributes.splice(node.attributes.indexOf(attribute), 1);
|
|
5
|
-
}
|
|
6
|
-
|
|
7
|
-
function removePair(node, pair) {
|
|
8
|
-
node.hash.pairs.splice(node.hash.pairs.indexOf(pair), 1);
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
function getAttr(node, path) {
|
|
12
|
-
return findBy(node.attributes, 'name', path);
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
function getPair(node, path) {
|
|
16
|
-
return findBy(node.hash.pairs, 'key', path);
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
function updateStringValue(node, updater) {
|
|
20
|
-
if (node.type === 'TextNode') {
|
|
21
|
-
node.chars = updater(node.chars);
|
|
22
|
-
} else if (node.type === 'StringLiteral') {
|
|
23
|
-
node.value = updater(node.value);
|
|
24
|
-
node.original = updater(node.original);
|
|
25
|
-
} else {
|
|
26
|
-
throw new Error('Unknown node type ' + node.type + ' (not a string?)');
|
|
27
|
-
}
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
function mustacheToSexpr(builders, node) {
|
|
31
|
-
if (node.type !== 'MustacheStatement') {
|
|
32
|
-
return node;
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
var params = node.params.map(textToString.bind(null, builders));
|
|
36
|
-
return builders.sexpr(node.path, params, node.hash);
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
function textToString(builders, node) {
|
|
40
|
-
if (node.type === 'TextNode') {
|
|
41
|
-
return builders.string(node.chars);
|
|
42
|
-
} else {
|
|
43
|
-
return node;
|
|
44
|
-
}
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
function concatStatementToParams(builders, node) {
|
|
48
|
-
return node.parts.map(function (part) {
|
|
49
|
-
if (part.type === 'MustacheStatement') {
|
|
50
|
-
if (!part.params.length && !part.hash.pairs.length) {
|
|
51
|
-
return part.path;
|
|
52
|
-
} else {
|
|
53
|
-
return mustacheToSexpr(builders, part);
|
|
54
|
-
}
|
|
55
|
-
} else {
|
|
56
|
-
return textToString(builders, part);
|
|
57
|
-
}
|
|
58
|
-
});
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
function findBy(target, key, path) {
|
|
62
|
-
for (var i = 0, l = target.length; i < l; i++) {
|
|
63
|
-
if (target[i][key] === path) {
|
|
64
|
-
return target[i];
|
|
65
|
-
}
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
return false;
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
function pushAll(target, arr) {
|
|
72
|
-
for (var i = 0; i < arr.length; i++) {
|
|
73
|
-
target.push(arr[i]);
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
return target;
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
module.exports = {
|
|
80
|
-
pushAll: pushAll,
|
|
81
|
-
getPair: getPair,
|
|
82
|
-
getAttr: getAttr,
|
|
83
|
-
removePair: removePair,
|
|
84
|
-
removeAttr: removeAttr,
|
|
85
|
-
mustacheToSexpr: mustacheToSexpr,
|
|
86
|
-
updateStringValue: updateStringValue,
|
|
87
|
-
concatStatementToParams: concatStatementToParams,
|
|
88
|
-
};
|
package/lib/plugin/index.js
DELETED
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
|
|
3
|
-
const normalizePostcssPlugins = require('../utils/normalize-postcss-plugins');
|
|
4
|
-
|
|
5
|
-
module.exports = class Plugin {
|
|
6
|
-
constructor(parent) {
|
|
7
|
-
this.parent = parent;
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
isForApp() {
|
|
11
|
-
return !this.parent.parent;
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
isForAddon() {
|
|
15
|
-
return !this.isForApp();
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
addPostcssPlugin(config, type, ...plugins) {
|
|
19
|
-
config.plugins = normalizePostcssPlugins(config.plugins);
|
|
20
|
-
|
|
21
|
-
if (type === 'before') {
|
|
22
|
-
config.plugins.before.unshift(...plugins);
|
|
23
|
-
} else if (type === 'after' || type === 'postprocess') {
|
|
24
|
-
config.plugins[type].push(...plugins);
|
|
25
|
-
} else {
|
|
26
|
-
throw new Error(`Unknown plugin type '${type}'`);
|
|
27
|
-
}
|
|
28
|
-
}
|
|
29
|
-
};
|
package/lib/plugin/registry.js
DELETED
|
@@ -1,100 +0,0 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
|
|
3
|
-
// eslint-disable-next-line node/no-unpublished-require
|
|
4
|
-
const EmberApp = require('ember-cli/lib/broccoli/ember-app');
|
|
5
|
-
const Plugin = require('./index');
|
|
6
|
-
const merge = require('lodash.merge');
|
|
7
|
-
const debug = require('debug')('ember-css-modules:plugin-registry');
|
|
8
|
-
const normalizePostcssPlugins = require('../utils/normalize-postcss-plugins');
|
|
9
|
-
|
|
10
|
-
module.exports = class PluginRegistry {
|
|
11
|
-
constructor(parent) {
|
|
12
|
-
this.parent = parent;
|
|
13
|
-
this._plugins = null;
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
computeOptions(includerOptions) {
|
|
17
|
-
let env = EmberApp.env();
|
|
18
|
-
let baseOptions = merge({}, includerOptions);
|
|
19
|
-
baseOptions.plugins = normalizePostcssPlugins(baseOptions.plugins);
|
|
20
|
-
|
|
21
|
-
let pluginOptions = this._computePluginOptions(env, baseOptions);
|
|
22
|
-
return merge(pluginOptions, baseOptions);
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
notify(event) {
|
|
26
|
-
for (let plugin of this.getPlugins()) {
|
|
27
|
-
if (typeof plugin[event] === 'function') {
|
|
28
|
-
plugin[event]();
|
|
29
|
-
}
|
|
30
|
-
}
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
getPlugins() {
|
|
34
|
-
if (this._plugins === null) {
|
|
35
|
-
this._plugins = this._instantiatePlugins();
|
|
36
|
-
}
|
|
37
|
-
return this._plugins;
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
_instantiatePlugins() {
|
|
41
|
-
let plugins = this._discoverPlugins(
|
|
42
|
-
this.parent.addons,
|
|
43
|
-
'ember-css-modules-plugin'
|
|
44
|
-
);
|
|
45
|
-
|
|
46
|
-
// For addons under development, crawl the host app's available plugins for linting tools so they can be devDependencies
|
|
47
|
-
if (
|
|
48
|
-
typeof this.parent.isDevelopingAddon === 'function' &&
|
|
49
|
-
this.parent.isDevelopingAddon()
|
|
50
|
-
) {
|
|
51
|
-
let parentAddonNames = new Set(
|
|
52
|
-
this.parent.addons.map((addon) => addon.name)
|
|
53
|
-
);
|
|
54
|
-
let hostAddons = this.parent.project.addons.filter(
|
|
55
|
-
(addon) => !parentAddonNames.has(addon.name)
|
|
56
|
-
);
|
|
57
|
-
plugins = plugins.concat(
|
|
58
|
-
this._discoverPlugins(hostAddons, 'ember-css-modules-lint-plugin')
|
|
59
|
-
);
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
return plugins;
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
_discoverPlugins(addons, keyword) {
|
|
66
|
-
return addons
|
|
67
|
-
.filter((addon) => this._isPlugin(addon, keyword))
|
|
68
|
-
.map((addon) => this._instantiatePluginFor(addon));
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
_isPlugin(addon, keyword) {
|
|
72
|
-
return (
|
|
73
|
-
addon.pkg &&
|
|
74
|
-
addon.pkg.keywords &&
|
|
75
|
-
addon.pkg.keywords.indexOf(keyword) >= 0
|
|
76
|
-
);
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
_instantiatePluginFor(addon) {
|
|
80
|
-
debug('instantiating plugin %s', addon.name);
|
|
81
|
-
|
|
82
|
-
const plugin = addon.createCssModulesPlugin(this.parent);
|
|
83
|
-
if (!(plugin instanceof Plugin)) {
|
|
84
|
-
this.parent.ui.writeWarnLine(
|
|
85
|
-
`Addon ${addon.name} did not return a Plugin instance from its createCssModulesPlugin hook`
|
|
86
|
-
);
|
|
87
|
-
}
|
|
88
|
-
return plugin;
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
_computePluginOptions(env, baseOptions) {
|
|
92
|
-
let options = merge({}, baseOptions);
|
|
93
|
-
for (let plugin of this.getPlugins()) {
|
|
94
|
-
if (plugin.config) {
|
|
95
|
-
merge(options, plugin.config(env, baseOptions));
|
|
96
|
-
}
|
|
97
|
-
}
|
|
98
|
-
return options;
|
|
99
|
-
}
|
|
100
|
-
};
|