Skip to content

Commit 652d61f

Browse files
committedNov 23, 2018
chore(deps): update
1 parent 68affb4 commit 652d61f

File tree

7 files changed

+3001
-127
lines changed

7 files changed

+3001
-127
lines changed
 

‎.eslintrc

+3-18
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,10 @@
11
{
2-
"parser": "babel-eslint",
2+
"parserOptions": {
3+
"ecmaVersion": 2018
4+
},
35
"env": {
46
"node": true
57
},
6-
"ecmaFeatures": {
7-
"arrowFunctions": true,
8-
"blockBindings": true,
9-
"classes": true,
10-
"defaultParams": true,
11-
"destructuring": true,
12-
"forOf": true,
13-
"modules": true,
14-
"objectLiteralComputedProperties": true,
15-
"objectLiteralShorthandMethods": true,
16-
"objectLiteralShorthandProperties": true,
17-
"spread": true,
18-
"superInFunctions": true,
19-
"templateStrings": true,
20-
"unicodeCodePointEscapes": true,
21-
"jsx": true
22-
},
238
"rules": {
249
"quotes": [2, "single"]
2510
}

‎.travis.yml

+3-5
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,11 @@
11
language: node_js
22
node_js:
3-
- "4"
43
- "6"
5-
- "node"
4+
- "8"
5+
- "10"
6+
- "11"
67
script: npm run travis
78

8-
before_install:
9-
- '[ "${TRAVIS_NODE_VERSION}" != "0.10" ] || npm install -g npm'
10-
119
after_success:
1210
- cat ./coverage/lcov.info | node_modules/.bin/coveralls --verbose
1311
- cat ./coverage/coverage.json | node_modules/codecov.io/bin/codecov.io.js

‎package.json

+19-21
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,20 @@
11
{
22
"name": "postcss-modules-scope",
3-
"version": "1.1.0",
3+
"version": "2.0.0",
44
"description": "A CSS Modules transform to extract export statements from local-scope classes",
5-
"main": "lib/index.js",
5+
"main": "src/index.js",
6+
"engines": {
7+
"node": ">= 6"
8+
},
69
"scripts": {
7-
"lint": "eslint src",
8-
"build": "babel --out-dir lib src",
9-
"watch": "chokidar src -c 'npm run build'",
10-
"test": "mocha --compilers js:babel/register",
11-
"posttest": "npm run lint && npm run build",
12-
"autotest": "chokidar src test -c 'npm test'",
13-
"precover": "npm run lint && npm run build",
14-
"cover": "babel-istanbul cover node_modules/.bin/_mocha",
15-
"travis": "npm run cover -- --report lcovonly",
16-
"prepublish": "npm run build"
10+
"lint": "eslint src test",
11+
"pretest": "yarn lint",
12+
"test": "mocha",
13+
"autotest": "chokidar src test -c 'yarn test'",
14+
"precover": "yarn lint",
15+
"cover": "nyc mocha",
16+
"travis": "yarn cover",
17+
"prepublish": "yarn run test"
1718
},
1819
"repository": {
1920
"type": "git",
@@ -25,7 +26,7 @@
2526
"plugin"
2627
],
2728
"files": [
28-
"lib"
29+
"src"
2930
],
3031
"author": "Glen Maddern",
3132
"license": "ISC",
@@ -35,18 +36,15 @@
3536
"homepage": "https://github.com/css-modules/postcss-modules-scope",
3637
"dependencies": {
3738
"css-selector-tokenizer": "^0.7.0",
38-
"postcss": "^6.0.1"
39+
"postcss": "^7.0.6"
3940
},
4041
"devDependencies": {
41-
"babel": "^5.4.7",
42-
"babel-eslint": "^6.1.2",
43-
"babel-istanbul": "^0.4.0",
44-
"babelify": "^7.1.0",
4542
"chokidar-cli": "^1.0.1",
4643
"codecov.io": "^0.1.2",
47-
"coveralls": "^2.11.2",
44+
"coveralls": "^3.0.2",
4845
"css-selector-parser": "^1.0.4",
49-
"eslint": "^1.5.0",
50-
"mocha": "^3.0.1"
46+
"eslint": "^5.9.0",
47+
"nyc": "^13.1.0",
48+
"mocha": "^5.2.0"
5149
}
5250
}

‎src/index.js

+103-58
Original file line numberDiff line numberDiff line change
@@ -1,86 +1,122 @@
1-
import postcss from 'postcss';
2-
import Tokenizer from 'css-selector-tokenizer';
1+
'use strict';
32

4-
let hasOwnProperty = Object.prototype.hasOwnProperty;
3+
const postcss = require('postcss');
4+
const Tokenizer = require('css-selector-tokenizer');
5+
6+
const hasOwnProperty = Object.prototype.hasOwnProperty;
57

68
function getSingleLocalNamesForComposes(selectors) {
7-
return selectors.nodes.map((node) => {
8-
if(node.type !== 'selector' || node.nodes.length !== 1) {
9-
throw new Error('composition is only allowed when selector is single :local class name not in "' +
10-
Tokenizer.stringify(selectors) + '"');
9+
return selectors.nodes.map(node => {
10+
if (node.type !== 'selector' || node.nodes.length !== 1) {
11+
throw new Error(
12+
'composition is only allowed when selector is single :local class name not in "' +
13+
Tokenizer.stringify(selectors) +
14+
'"'
15+
);
1116
}
1217
node = node.nodes[0];
13-
if(node.type !== 'nested-pseudo-class' || node.name !== 'local' || node.nodes.length !== 1) {
14-
throw new Error('composition is only allowed when selector is single :local class name not in "' +
15-
Tokenizer.stringify(selectors) + '", "' + Tokenizer.stringify(node) + '" is weird');
18+
if (
19+
node.type !== 'nested-pseudo-class' ||
20+
node.name !== 'local' ||
21+
node.nodes.length !== 1
22+
) {
23+
throw new Error(
24+
'composition is only allowed when selector is single :local class name not in "' +
25+
Tokenizer.stringify(selectors) +
26+
'", "' +
27+
Tokenizer.stringify(node) +
28+
'" is weird'
29+
);
1630
}
1731
node = node.nodes[0];
18-
if(node.type !== 'selector' || node.nodes.length !== 1) {
19-
throw new Error('composition is only allowed when selector is single :local class name not in "' +
20-
Tokenizer.stringify(selectors) + '", "' + Tokenizer.stringify(node) + '" is weird');
32+
if (node.type !== 'selector' || node.nodes.length !== 1) {
33+
throw new Error(
34+
'composition is only allowed when selector is single :local class name not in "' +
35+
Tokenizer.stringify(selectors) +
36+
'", "' +
37+
Tokenizer.stringify(node) +
38+
'" is weird'
39+
);
2140
}
2241
node = node.nodes[0];
23-
if(node.type !== 'class') { // 'id' is not possible, because you can't compose ids
24-
throw new Error('composition is only allowed when selector is single :local class name not in "' +
25-
Tokenizer.stringify(selectors) + '", "' + Tokenizer.stringify(node) + '" is weird');
42+
if (node.type !== 'class') {
43+
// 'id' is not possible, because you can't compose ids
44+
throw new Error(
45+
'composition is only allowed when selector is single :local class name not in "' +
46+
Tokenizer.stringify(selectors) +
47+
'", "' +
48+
Tokenizer.stringify(node) +
49+
'" is weird'
50+
);
2651
}
2752
return node.name;
2853
});
2954
}
3055

3156
const processor = postcss.plugin('postcss-modules-scope', function(options) {
32-
return (css) => {
33-
let generateScopedName = options && options.generateScopedName || processor.generateScopedName;
57+
return css => {
58+
const generateScopedName =
59+
(options && options.generateScopedName) || processor.generateScopedName;
3460

35-
let exports = {};
61+
const exports = {};
3662

3763
function exportScopedName(name) {
38-
let scopedName = generateScopedName(name, css.source.input.from, css.source.input.css);
64+
const scopedName = generateScopedName(
65+
name,
66+
css.source.input.from,
67+
css.source.input.css
68+
);
3969
exports[name] = exports[name] || [];
40-
if(exports[name].indexOf(scopedName) < 0) {
70+
if (exports[name].indexOf(scopedName) < 0) {
4171
exports[name].push(scopedName);
4272
}
4373
return scopedName;
4474
}
4575

4676
function localizeNode(node) {
47-
let newNode = Object.create(node);
48-
switch(node.type) {
77+
const newNode = Object.create(node);
78+
switch (node.type) {
4979
case 'selector':
5080
newNode.nodes = node.nodes.map(localizeNode);
5181
return newNode;
5282
case 'class':
53-
case 'id':
54-
let scopedName = exportScopedName(node.name);
55-
newNode.name = scopedName;
83+
case 'id': {
84+
newNode.name = exportScopedName(node.name);
5685
return newNode;
86+
}
5787
}
58-
throw new Error(node.type + ' ("' + Tokenizer.stringify(node) + '") is not allowed in a :local block');
88+
throw new Error(
89+
node.type +
90+
' ("' +
91+
Tokenizer.stringify(node) +
92+
'") is not allowed in a :local block'
93+
);
5994
}
6095

6196
function traverseNode(node) {
62-
switch(node.type) {
97+
switch (node.type) {
6398
case 'nested-pseudo-class':
64-
if(node.name === 'local') {
65-
if(node.nodes.length !== 1) {
99+
if (node.name === 'local') {
100+
if (node.nodes.length !== 1) {
66101
throw new Error('Unexpected comma (",") in :local block');
67102
}
68103
return localizeNode(node.nodes[0]);
69104
}
70-
/* falls through */
105+
/* falls through */
71106
case 'selectors':
72-
case 'selector':
73-
let newNode = Object.create(node);
107+
case 'selector': {
108+
const newNode = Object.create(node);
74109
newNode.nodes = node.nodes.map(traverseNode);
75110
return newNode;
111+
}
76112
}
77113
return node;
78114
}
79115

80116
// Find any :import and remember imported names
81-
let importedNames = {};
117+
const importedNames = {};
82118
css.walkRules(rule => {
83-
if(/^:import\(.+\)$/.test(rule.selector)) {
119+
if (/^:import\(.+\)$/.test(rule.selector)) {
84120
rule.walkDecls(decl => {
85121
importedNames[decl.prop] = true;
86122
});
@@ -89,30 +125,32 @@ const processor = postcss.plugin('postcss-modules-scope', function(options) {
89125

90126
// Find any :local classes
91127
css.walkRules(rule => {
92-
let selector = Tokenizer.parse(rule.selector);
93-
let newSelector = traverseNode(selector);
128+
const selector = Tokenizer.parse(rule.selector);
129+
const newSelector = traverseNode(selector);
94130
rule.selector = Tokenizer.stringify(newSelector);
95131
rule.walkDecls(/composes|compose-with/, decl => {
96-
let localNames = getSingleLocalNamesForComposes(selector);
97-
let classes = decl.value.split(/\s+/);
98-
classes.forEach((className) => {
99-
let global = /^global\(([^\)]+)\)$/.exec(className);
132+
const localNames = getSingleLocalNamesForComposes(selector);
133+
const classes = decl.value.split(/\s+/);
134+
classes.forEach(className => {
135+
const global = /^global\(([^\)]+)\)$/.exec(className);
100136
if (global) {
101-
localNames.forEach((exportedName) => {
137+
localNames.forEach(exportedName => {
102138
exports[exportedName].push(global[1]);
103-
})
139+
});
104140
} else if (hasOwnProperty.call(importedNames, className)) {
105-
localNames.forEach((exportedName) => {
141+
localNames.forEach(exportedName => {
106142
exports[exportedName].push(className);
107143
});
108144
} else if (hasOwnProperty.call(exports, className)) {
109-
localNames.forEach((exportedName) => {
110-
exports[className].forEach((item) => {
145+
localNames.forEach(exportedName => {
146+
exports[className].forEach(item => {
111147
exports[exportedName].push(item);
112148
});
113149
});
114150
} else {
115-
throw decl.error(`referenced class name "${className}" in ${decl.prop} not found`);
151+
throw decl.error(
152+
`referenced class name "${className}" in ${decl.prop} not found`
153+
);
116154
}
117155
});
118156
decl.remove();
@@ -121,10 +159,14 @@ const processor = postcss.plugin('postcss-modules-scope', function(options) {
121159
rule.walkDecls(decl => {
122160
var tokens = decl.value.split(/(,|'[^']*'|"[^"]*")/);
123161
tokens = tokens.map((token, idx) => {
124-
if(idx === 0 || tokens[idx - 1] === ',') {
125-
let localMatch = /^(\s*):local\s*\((.+?)\)/.exec(token);
126-
if(localMatch) {
127-
return localMatch[1] + exportScopedName(localMatch[2]) + token.substr(localMatch[0].length);
162+
if (idx === 0 || tokens[idx - 1] === ',') {
163+
const localMatch = /^(\s*):local\s*\((.+?)\)/.exec(token);
164+
if (localMatch) {
165+
return (
166+
localMatch[1] +
167+
exportScopedName(localMatch[2]) +
168+
token.substr(localMatch[0].length)
169+
);
128170
} else {
129171
return token;
130172
}
@@ -138,19 +180,19 @@ const processor = postcss.plugin('postcss-modules-scope', function(options) {
138180

139181
// Find any :local keyframes
140182
css.walkAtRules(atrule => {
141-
if(/keyframes$/.test(atrule.name)) {
183+
if (/keyframes$/i.test(atrule.name)) {
142184
var localMatch = /^\s*:local\s*\((.+?)\)\s*$/.exec(atrule.params);
143-
if(localMatch) {
185+
if (localMatch) {
144186
atrule.params = exportScopedName(localMatch[1]);
145187
}
146188
}
147189
});
148190

149191
// If we found any :locals, insert an :export rule
150-
let exportedNames = Object.keys(exports);
192+
const exportedNames = Object.keys(exports);
151193
if (exportedNames.length > 0) {
152-
let exportRule = postcss.rule({selector: `:export`});
153-
exportedNames.forEach(exportedName =>
194+
const exportRule = postcss.rule({ selector: ':export' });
195+
exportedNames.forEach(exportedName =>
154196
exportRule.append({
155197
prop: exportedName,
156198
value: exports[exportedName].join(' '),
@@ -163,8 +205,11 @@ const processor = postcss.plugin('postcss-modules-scope', function(options) {
163205
});
164206

165207
processor.generateScopedName = function(exportedName, path) {
166-
let sanitisedPath = path.replace(/\.[^\.\/\\]+$/, '').replace(/[\W_]+/g, '_').replace(/^_|_$/g, '');
208+
const sanitisedPath = path
209+
.replace(/\.[^\.\/\\]+$/, '')
210+
.replace(/[\W_]+/g, '_')
211+
.replace(/^_|_$/g, '');
167212
return `_${sanitisedPath}__${exportedName}`;
168213
};
169214

170-
export default processor;
215+
module.exports = processor;

‎test/test-cases.js

+25-24
Original file line numberDiff line numberDiff line change
@@ -1,55 +1,56 @@
1-
"use strict";
1+
'use strict';
22

33
/*globals describe it */
44

5-
var assert = require("assert");
6-
var fs = require("fs");
7-
var path = require("path");
8-
var postcss = require("postcss");
9-
var processor = require("../src");
5+
var assert = require('assert');
6+
var fs = require('fs');
7+
var path = require('path');
8+
var postcss = require('postcss');
9+
var processor = require('../src');
1010

1111
function generateInvalidCSS(css) {
1212
css.walkDecls(function(decl) {
13-
decl.value = decl.value.replace(/_colon_/g, ":"); // because using a : in the tests would make it invalid CSS.
13+
decl.value = decl.value.replace(/_colon_/g, ':'); // because using a : in the tests would make it invalid CSS.
1414
});
1515
}
1616

1717
function normalize(str) {
18-
return str.replace(/\r\n?/g, "\n").replace(/\n$/, '');
18+
return str.replace(/\r\n?/g, '\n').replace(/\n$/, '');
1919
}
2020

2121
var generateScopedName = processor.generateScopedName;
2222

23-
describe("test-cases", function() {
24-
var testDir = path.join(__dirname, "test-cases");
23+
describe('test-cases', function() {
24+
var testDir = path.join(__dirname, 'test-cases');
2525
fs.readdirSync(testDir).forEach(function(testCase) {
26-
if(fs.existsSync(path.join(testDir, testCase, "source.css"))) {
27-
it("should " + testCase.replace(/-/g, " "), function() {
28-
var input = normalize(fs.readFileSync(path.join(testDir, testCase, "source.css"), "utf-8"));
26+
if(fs.existsSync(path.join(testDir, testCase, 'source.css'))) {
27+
it('should ' + testCase.replace(/-/g, ' '), function() {
28+
var input = normalize(fs.readFileSync(path.join(testDir, testCase, 'source.css'), 'utf-8'));
2929
var expected, expectedError;
30-
if(fs.existsSync(path.join(testDir, testCase, "expected.error.txt"))) {
31-
expectedError = normalize(fs.readFileSync(path.join(testDir, testCase, "expected.error.txt"), "utf-8"))
32-
.split("\n")[0];
30+
if(fs.existsSync(path.join(testDir, testCase, 'expected.error.txt'))) {
31+
expectedError = normalize(fs.readFileSync(path.join(testDir, testCase, 'expected.error.txt'), 'utf-8'))
32+
.split('\n')[0];
3333
} else {
34-
expected = normalize(fs.readFileSync(path.join(testDir, testCase, "expected.css"), "utf-8"));
34+
expected = normalize(fs.readFileSync(path.join(testDir, testCase, 'expected.css'), 'utf-8'));
3535
}
36-
var config = { from: "/input" };
36+
var config = { from: '/input' };
3737
var options = {
3838
generateScopedName: function(exportedName, inputPath) {
39-
var normalizedPath = inputPath.replace(/^[A-Z]:/, "");
39+
var normalizedPath = inputPath.replace(/^[A-Z]:/, '');
4040
return generateScopedName(exportedName, normalizedPath);
4141
}
4242
};
43-
if(fs.existsSync(path.join(testDir, testCase, "config.json"))) {
44-
config = JSON.parse(fs.readFileSync(path.join(testDir, testCase, "config.json"), "utf-8"));
43+
if(fs.existsSync(path.join(testDir, testCase, 'config.json'))) {
44+
config = JSON.parse(fs.readFileSync(path.join(testDir, testCase, 'config.json'), 'utf-8'));
4545
}
46-
if(fs.existsSync(path.join(testDir, testCase, "options.js"))) {
47-
options = require(path.join(testDir, testCase, "options.js"));
46+
if(fs.existsSync(path.join(testDir, testCase, 'options.js'))) {
47+
options = require(path.join(testDir, testCase, 'options.js'));
4848
}
4949
var pipeline = postcss([generateInvalidCSS, processor(options)]);
5050
if(expectedError) {
5151
assert.throws(function() {
52-
var result = pipeline.process(input, config).css;
52+
// eslint-ignore-next-line no-unused-vars
53+
const result = pipeline.process(input, config).css;
5354
}, new RegExp(expectedError));
5455
} else {
5556
assert.equal(pipeline.process(input, config).css, expected);
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
module.exports = {
22
generateScopedName: function(name, path) {
3-
return "_" + name + "_";
3+
return '_' + name + '_';
44
}
55
};

‎yarn.lock

+2,847
Large diffs are not rendered by default.

0 commit comments

Comments
 (0)
Please sign in to comment.