chore:更换到主分支

This commit is contained in:
张益铭
2021-03-01 15:26:05 +08:00
parent 9064b372e8
commit 6a5f1810f9
3530 changed files with 59613 additions and 479452 deletions

View File

@@ -1,16 +1,57 @@
# Change Log
All notable changes to this project will be documented in this file.
This project adheres to [Semantic Versioning](http://semver.org/).
## [2.2.0] - 2020-03-19
## [3.0.0](https://github.com/postcss-modules-local-by-default/compare/v3.0.0-rc.2...v3.0.0) - 2020-10-13
### Fixes
- compatibility with plugins other plugins
- handle animation short name
- perf
## [3.0.0-rc.2](https://github.com/postcss-modules-local-by-default/compare/v3.0.0-rc.1...v3.0.0-rc.2) - 2020-10-11
### BREAKING CHANGE
- minimum supported `postcss` version is `^8.1.0`
### Fixes
- minimum supported `Node.js` version is `^10 || ^12 || >= 14`
- compatibility with PostCSS 8
## [3.0.0-rc.1](https://github.com/postcss-modules-local-by-default/compare/v3.0.0-rc.0...v3.0.0-rc.1) - 2020-09-22
### BREAKING CHANGE
- do not handle invalid syntax
## [3.0.0-rc.0](https://github.com/postcss-modules-local-by-default/compare/v2.2.0...v3.0.0-rc.0) - 2020-09-21
### BREAKING CHANGE
- minimum supported `Node.js` version is `>= 10.13.0 || >= 12.13.0 || >= 14`
- minimum supported `postcss` version is `^8.0.3`
- `postcss` was moved to `peerDependencies`, you need to install `postcss` in your project before use the plugin
## 2.2.0 - 2020-03-19
- added the `exportGlobals` option to export global classes and ids
## [2.1.1] - 2019-03-05
## 2.1.1 - 2019-03-05
### Fixed
- add additional space after the escape sequence (#17)
## [2.1.0] - 2019-03-05
### Fixed
- handles properly selector with escaping characters (like: `.\31 a2b3c { color: red }`)
### Feature
- `generateExportEntry` option (allow to setup key and value for `:export {}` rule)

View File

@@ -24,8 +24,8 @@ into:
so it doesn't pollute CSS global scope and can be simply used in JS like so:
```js
import styles from './buttons.css'
elem.innerHTML = `<button class="${styles.continueButton}">Continue</button>`
import styles from "./buttons.css";
elem.innerHTML = `<button class="${styles.continueButton}">Continue</button>`;
```
## Composition
@@ -77,14 +77,13 @@ npm install
npm test
```
[![Build Status](https://travis-ci.org/css-modules/postcss-modules-scope.svg?branch=master)](https://travis-ci.org/css-modules/postcss-modules-scope)
* Lines: [![Coverage Status](https://coveralls.io/repos/css-modules/postcss-modules-scope/badge.svg?branch=master)](https://coveralls.io/r/css-modules/postcss-modules-scope?branch=master)
* Statements: [![codecov.io](http://codecov.io/github/css-modules/postcss-modules-scope/coverage.svg?branch=master)](http://codecov.io/github/css-modules/postcss-modules-scope?branch=master)
- Status: [![Build Status](https://travis-ci.org/css-modules/postcss-modules-scope.svg?branch=master)](https://travis-ci.org/css-modules/postcss-modules-scope)
- Lines: [![Coverage Status](https://coveralls.io/repos/css-modules/postcss-modules-scope/badge.svg?branch=master)](https://coveralls.io/r/css-modules/postcss-modules-scope?branch=master)
- Statements: [![codecov.io](http://codecov.io/github/css-modules/postcss-modules-scope/coverage.svg?branch=master)](http://codecov.io/github/css-modules/postcss-modules-scope?branch=master)
## Development
- `npm autotest` will watch `src` and `test` for changes and run the tests, and transpile the ES6 to ES5 on success
- `npm test:watch` will watch `src` and `test` for changes and run the tests
## License
@@ -97,4 +96,5 @@ ISC
- Guy Bedford
---
Glen Maddern, 2015.

View File

@@ -1,32 +1,32 @@
{
"_args": [
[
"postcss-modules-scope@2.2.0",
"postcss-modules-scope@3.0.0",
"J:\\Github\\CURD-TS"
]
],
"_development": true,
"_from": "postcss-modules-scope@2.2.0",
"_id": "postcss-modules-scope@2.2.0",
"_from": "postcss-modules-scope@3.0.0",
"_id": "postcss-modules-scope@3.0.0",
"_inBundle": false,
"_integrity": "sha1-OFyuATzHdD9afXYC0Qc6iequYu4=",
"_integrity": "sha1-nvMVFFbTu/oSDKRImN/Kby+gHwY=",
"_location": "/postcss-modules-scope",
"_phantomChildren": {},
"_requested": {
"type": "version",
"registry": true,
"raw": "postcss-modules-scope@2.2.0",
"raw": "postcss-modules-scope@3.0.0",
"name": "postcss-modules-scope",
"escapedName": "postcss-modules-scope",
"rawSpec": "2.2.0",
"rawSpec": "3.0.0",
"saveSpec": null,
"fetchSpec": "2.2.0"
"fetchSpec": "3.0.0"
},
"_requiredBy": [
"/postcss-modules"
],
"_resolved": "http://192.168.250.101:4873/postcss-modules-scope/-/postcss-modules-scope-2.2.0.tgz",
"_spec": "2.2.0",
"_resolved": "http://192.168.250.101:4873/postcss-modules-scope/-/postcss-modules-scope-3.0.0.tgz",
"_spec": "3.0.0",
"_where": "J:\\Github\\CURD-TS",
"author": {
"name": "Glen Maddern"
@@ -35,21 +35,21 @@
"url": "https://github.com/css-modules/postcss-modules-scope/issues"
},
"dependencies": {
"postcss": "^7.0.6",
"postcss-selector-parser": "^6.0.0"
"postcss-selector-parser": "^6.0.4"
},
"description": "A CSS Modules transform to extract export statements from local-scope classes",
"devDependencies": {
"chokidar-cli": "^1.0.1",
"codecov.io": "^0.1.2",
"coveralls": "^3.0.2",
"cssesc": "^3.0.0",
"eslint": "^5.9.0",
"mocha": "^6.0.2",
"nyc": "^14.1.0"
"coveralls": "^3.1.0",
"eslint": "^7.9.0",
"eslint-config-prettier": "^6.12.0",
"husky": "^4.3.0",
"jest": "^26.4.2",
"lint-staged": "^10.4.0",
"postcss": "^8.1.0",
"prettier": "^2.1.2"
},
"engines": {
"node": ">= 6"
"node": "^10 || ^12 || >= 14"
},
"files": [
"src"
@@ -63,24 +63,23 @@
"license": "ISC",
"main": "src/index.js",
"name": "postcss-modules-scope",
"prettier": {
"semi": true,
"singleQuote": true,
"trailingComma": "es5"
"peerDependencies": {
"postcss": "^8.1.0"
},
"repository": {
"type": "git",
"url": "git+https://github.com/css-modules/postcss-modules-scope.git"
},
"scripts": {
"autotest": "chokidar src test -c 'yarn test'",
"cover": "nyc mocha",
"lint": "eslint src test",
"precover": "yarn lint",
"prepublish": "yarn run test",
"eslint": "eslint --ignore-path .gitignore .",
"lint": "yarn eslint && yarn prettier",
"prepublishOnly": "yarn test",
"pretest": "yarn lint",
"test": "mocha",
"travis": "yarn cover"
"prettier": "prettier -l --ignore-path .gitignore . \"!test/test-cases\"",
"test": "yarn test:coverage",
"test:coverage": "jest --coverage --collectCoverageFrom=\"src/**/*\"",
"test:only": "jest",
"test:watch": "jest --watch"
},
"version": "2.2.0"
"version": "3.0.0"
}

View File

@@ -1,13 +1,12 @@
'use strict';
"use strict";
const postcss = require('postcss');
const selectorParser = require('postcss-selector-parser');
const selectorParser = require("postcss-selector-parser");
const hasOwnProperty = Object.prototype.hasOwnProperty;
function getSingleLocalNamesForComposes(root) {
return root.nodes.map(node => {
if (node.type !== 'selector' || node.nodes.length !== 1) {
return root.nodes.map((node) => {
if (node.type !== "selector" || node.nodes.length !== 1) {
throw new Error(
`composition is only allowed when selector is single :local class name not in "${root}"`
);
@@ -16,8 +15,8 @@ function getSingleLocalNamesForComposes(root) {
node = node.nodes[0];
if (
node.type !== 'pseudo' ||
node.value !== ':local' ||
node.type !== "pseudo" ||
node.value !== ":local" ||
node.nodes.length !== 1
) {
throw new Error(
@@ -31,7 +30,7 @@ function getSingleLocalNamesForComposes(root) {
node = node.first;
if (node.type !== 'selector' || node.length !== 1) {
if (node.type !== "selector" || node.length !== 1) {
throw new Error(
'composition is only allowed when selector is single :local class name not in "' +
root +
@@ -43,7 +42,7 @@ function getSingleLocalNamesForComposes(root) {
node = node.first;
if (node.type !== 'class') {
if (node.type !== "class") {
// 'id' is not possible, because you can't compose ids
throw new Error(
'composition is only allowed when selector is single :local class name not in "' +
@@ -58,258 +57,262 @@ function getSingleLocalNamesForComposes(root) {
});
}
const whitespace = '[\\x20\\t\\r\\n\\f]';
const whitespace = "[\\x20\\t\\r\\n\\f]";
const unescapeRegExp = new RegExp(
'\\\\([\\da-f]{1,6}' + whitespace + '?|(' + whitespace + ')|.)',
'ig'
"\\\\([\\da-f]{1,6}" + whitespace + "?|(" + whitespace + ")|.)",
"ig"
);
function unescape(str) {
return str.replace(unescapeRegExp, (_, escaped, escapedWhitespace) => {
const high = '0x' + escaped - 0x10000;
const high = "0x" + escaped - 0x10000;
// NaN means non-codepoint
// Workaround erroneous numeric interpretation of +"0x"
return high !== high || escapedWhitespace
? escaped
: high < 0
? // BMP codepoint
String.fromCharCode(high + 0x10000)
: // Supplemental Plane codepoint (surrogate pair)
String.fromCharCode((high >> 10) | 0xd800, (high & 0x3ff) | 0xdc00);
? // BMP codepoint
String.fromCharCode(high + 0x10000)
: // Supplemental Plane codepoint (surrogate pair)
String.fromCharCode((high >> 10) | 0xd800, (high & 0x3ff) | 0xdc00);
});
}
const processor = postcss.plugin('postcss-modules-scope', function(options) {
return css => {
const generateScopedName =
(options && options.generateScopedName) || processor.generateScopedName;
const generateExportEntry =
(options && options.generateExportEntry) || processor.generateExportEntry;
const exportGlobals = options && options.exportGlobals;
const plugin = (options = {}) => {
const generateScopedName =
(options && options.generateScopedName) || plugin.generateScopedName;
const generateExportEntry =
(options && options.generateExportEntry) || plugin.generateExportEntry;
const exportGlobals = options && options.exportGlobals;
const exports = Object.create(null);
return {
postcssPlugin: "postcss-modules-scope",
Once(root, { rule }) {
const exports = Object.create(null);
function exportScopedName(name, rawName) {
const scopedName = generateScopedName(
rawName ? rawName : name,
css.source.input.from,
css.source.input.css
);
const exportEntry = generateExportEntry(
rawName ? rawName : name,
scopedName,
css.source.input.from,
css.source.input.css
);
const { key, value } = exportEntry;
function exportScopedName(name, rawName) {
const scopedName = generateScopedName(
rawName ? rawName : name,
root.source.input.from,
root.source.input.css
);
const exportEntry = generateExportEntry(
rawName ? rawName : name,
scopedName,
root.source.input.from,
root.source.input.css
);
const { key, value } = exportEntry;
exports[key] = exports[key] || [];
exports[key] = exports[key] || [];
if (exports[key].indexOf(value) < 0) {
exports[key].push(value);
}
return scopedName;
}
function localizeNode(node) {
switch (node.type) {
case 'selector':
node.nodes = node.map(localizeNode);
return node;
case 'class':
return selectorParser.className({
value: exportScopedName(
node.value,
node.raws && node.raws.value ? node.raws.value : null
),
});
case 'id': {
return selectorParser.id({
value: exportScopedName(
node.value,
node.raws && node.raws.value ? node.raws.value : null
),
});
if (exports[key].indexOf(value) < 0) {
exports[key].push(value);
}
return scopedName;
}
throw new Error(
`${node.type} ("${node}") is not allowed in a :local block`
);
}
function traverseNode(node) {
switch (node.type) {
case 'pseudo':
if (node.value === ':local') {
if (node.nodes.length !== 1) {
throw new Error('Unexpected comma (",") in :local block');
}
const selector = localizeNode(node.first, node.spaces);
// move the spaces that were around the psuedo selector to the first
// non-container node
selector.first.spaces = node.spaces;
const nextNode = node.next();
if (
nextNode &&
nextNode.type === 'combinator' &&
nextNode.value === ' ' &&
/\\[A-F0-9]{1,6}$/.test(selector.last.value)
) {
selector.last.spaces.after = ' ';
}
node.replaceWith(selector);
return;
function localizeNode(node) {
switch (node.type) {
case "selector":
node.nodes = node.map(localizeNode);
return node;
case "class":
return selectorParser.className({
value: exportScopedName(
node.value,
node.raws && node.raws.value ? node.raws.value : null
),
});
case "id": {
return selectorParser.id({
value: exportScopedName(
node.value,
node.raws && node.raws.value ? node.raws.value : null
),
});
}
/* falls through */
case 'root':
case 'selector': {
node.each(traverseNode);
break;
}
case 'id':
case 'class':
if (exportGlobals) {
exports[node.value] = [node.value];
}
break;
throw new Error(
`${node.type} ("${node}") is not allowed in a :local block`
);
}
return node;
}
// Find any :import and remember imported names
const importedNames = {};
function traverseNode(node) {
switch (node.type) {
case "pseudo":
if (node.value === ":local") {
if (node.nodes.length !== 1) {
throw new Error('Unexpected comma (",") in :local block');
}
css.walkRules(rule => {
if (/^:import\(.+\)$/.test(rule.selector)) {
rule.walkDecls(decl => {
const selector = localizeNode(node.first, node.spaces);
// move the spaces that were around the psuedo selector to the first
// non-container node
selector.first.spaces = node.spaces;
const nextNode = node.next();
if (
nextNode &&
nextNode.type === "combinator" &&
nextNode.value === " " &&
/\\[A-F0-9]{1,6}$/.test(selector.last.value)
) {
selector.last.spaces.after = " ";
}
node.replaceWith(selector);
return;
}
/* falls through */
case "root":
case "selector": {
node.each(traverseNode);
break;
}
case "id":
case "class":
if (exportGlobals) {
exports[node.value] = [node.value];
}
break;
}
return node;
}
// Find any :import and remember imported names
const importedNames = {};
root.walkRules(/^:import\(.+\)$/, (rule) => {
rule.walkDecls((decl) => {
importedNames[decl.prop] = true;
});
}
});
// Find any :local classes
css.walkRules(rule => {
if (
rule.nodes &&
rule.selector.slice(0, 2) === '--' &&
rule.selector.slice(-1) === ':'
) {
// ignore custom property set
return;
}
let parsedSelector = selectorParser().astSync(rule);
rule.selector = traverseNode(parsedSelector.clone()).toString();
rule.walkDecls(/composes|compose-with/, decl => {
const localNames = getSingleLocalNamesForComposes(parsedSelector);
const classes = decl.value.split(/\s+/);
classes.forEach(className => {
const global = /^global\(([^\)]+)\)$/.exec(className);
if (global) {
localNames.forEach(exportedName => {
exports[exportedName].push(global[1]);
});
} else if (hasOwnProperty.call(importedNames, className)) {
localNames.forEach(exportedName => {
exports[exportedName].push(className);
});
} else if (hasOwnProperty.call(exports, className)) {
localNames.forEach(exportedName => {
exports[className].forEach(item => {
exports[exportedName].push(item);
});
});
} else {
throw decl.error(
`referenced class name "${className}" in ${decl.prop} not found`
);
}
});
decl.remove();
});
rule.walkDecls(decl => {
let tokens = decl.value.split(/(,|'[^']*'|"[^"]*")/);
// Find any :local selectors
root.walkRules((rule) => {
let parsedSelector = selectorParser().astSync(rule);
tokens = tokens.map((token, idx) => {
if (idx === 0 || tokens[idx - 1] === ',') {
const localMatch = /^(\s*):local\s*\((.+?)\)/.exec(token);
rule.selector = traverseNode(parsedSelector.clone()).toString();
if (localMatch) {
return (
localMatch[1] +
exportScopedName(localMatch[2]) +
token.substr(localMatch[0].length)
rule.walkDecls(/composes|compose-with/i, (decl) => {
const localNames = getSingleLocalNamesForComposes(parsedSelector);
const classes = decl.value.split(/\s+/);
classes.forEach((className) => {
const global = /^global\(([^)]+)\)$/.exec(className);
if (global) {
localNames.forEach((exportedName) => {
exports[exportedName].push(global[1]);
});
} else if (hasOwnProperty.call(importedNames, className)) {
localNames.forEach((exportedName) => {
exports[exportedName].push(className);
});
} else if (hasOwnProperty.call(exports, className)) {
localNames.forEach((exportedName) => {
exports[className].forEach((item) => {
exports[exportedName].push(item);
});
});
} else {
throw decl.error(
`referenced class name "${className}" in ${decl.prop} not found`
);
}
});
decl.remove();
});
// Find any :local values
rule.walkDecls((decl) => {
if (!/:local\s*\((.+?)\)/.test(decl.value)) {
return;
}
let tokens = decl.value.split(/(,|'[^']*'|"[^"]*")/);
tokens = tokens.map((token, idx) => {
if (idx === 0 || tokens[idx - 1] === ",") {
let result = token;
const localMatch = /:local\s*\((.+?)\)/.exec(token);
if (localMatch) {
const input = localMatch.input;
const matchPattern = localMatch[0];
const matchVal = localMatch[1];
const newVal = exportScopedName(matchVal);
result = input.replace(matchPattern, newVal);
} else {
return token;
}
return result;
} else {
return token;
}
} else {
return token;
}
});
decl.value = tokens.join("");
});
decl.value = tokens.join('');
});
});
// Find any :local keyframes
css.walkAtRules(atrule => {
if (/keyframes$/i.test(atrule.name)) {
const localMatch = /^\s*:local\s*\((.+?)\)\s*$/.exec(atrule.params);
// Find any :local keyframes
root.walkAtRules(/keyframes$/i, (atRule) => {
const localMatch = /^\s*:local\s*\((.+?)\)\s*$/.exec(atRule.params);
if (localMatch) {
atrule.params = exportScopedName(localMatch[1]);
if (!localMatch) {
return;
}
atRule.params = exportScopedName(localMatch[1]);
});
// If we found any :locals, insert an :export rule
const exportedNames = Object.keys(exports);
if (exportedNames.length > 0) {
const exportRule = rule({ selector: ":export" });
exportedNames.forEach((exportedName) =>
exportRule.append({
prop: exportedName,
value: exports[exportedName].join(" "),
raws: { before: "\n " },
})
);
root.append(exportRule);
}
});
// If we found any :locals, insert an :export rule
const exportedNames = Object.keys(exports);
if (exportedNames.length > 0) {
const exportRule = postcss.rule({ selector: ':export' });
exportedNames.forEach(exportedName =>
exportRule.append({
prop: exportedName,
value: exports[exportedName].join(' '),
raws: { before: '\n ' },
})
);
css.append(exportRule);
}
},
};
});
};
processor.generateScopedName = function(name, path) {
plugin.postcss = true;
plugin.generateScopedName = function (name, path) {
const sanitisedPath = path
.replace(/\.[^\.\/\\]+$/, '')
.replace(/[\W_]+/g, '_')
.replace(/^_|_$/g, '');
.replace(/\.[^./\\]+$/, "")
.replace(/[\W_]+/g, "_")
.replace(/^_|_$/g, "");
return `_${sanitisedPath}__${name}`.trim();
};
processor.generateExportEntry = function(name, scopedName) {
plugin.generateExportEntry = function (name, scopedName) {
return {
key: unescape(name),
value: unescape(scopedName),
};
};
module.exports = processor;
module.exports = plugin;