diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..e06d798 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,15 @@ +root = true + +[*] +charset = utf-8 +end_of_line = lf +indent_style = tab +insert_final_newline = true +trim_trailing_whitespace = true + +[*.md] +trim_trailing_whitespace = false + +[*.{json,md,yml}] +indent_size = 2 +indent_style = space diff --git a/.eslintrc b/.eslintrc deleted file mode 100644 index e0a2ae5..0000000 --- a/.eslintrc +++ /dev/null @@ -1,122 +0,0 @@ -{ - "rules": { - "no-shadow-restricted-names": [2], - "computed-property-spacing": [2], - "no-empty-character-class": [2], - "no-irregular-whitespace": [2], - "no-unexpected-multiline": [2], - "no-multiple-empty-lines": [2], - "space-return-throw-case": [2], - "no-constant-condition": [2], - "no-extra-boolean-cast": [2], - "no-inner-declarations": [2], - "no-this-before-super": [2], - "no-array-constructor": [2], - "object-curly-spacing": [2, "always"], - "no-floating-decimal": [2], - "no-warning-comments": [2], - "handle-callback-err": [2], - "no-unneeded-ternary": [2], - "operator-assignment": [2], - "space-before-blocks": [2], - "no-native-reassign": [2], - "no-trailing-spaces": [2], - "operator-linebreak": [2, "after"], - "consistent-return": [2], - "no-duplicate-case": [2], - "no-invalid-regexp": [2], - "no-negated-in-lhs": [2], - "constructor-super": [2], - "no-nested-ternary": [0], - "no-extend-native": [2], - "block-scoped-var": [2], - "no-control-regex": [2], - "no-sparse-arrays": [2], - "no-throw-literal": [2], - "no-return-assign": [2], - "no-const-assign": [2], - "no-class-assign": [2], - "no-extra-parens": [2], - "no-regex-spaces": [2], - "no-implied-eval": [2], - "no-useless-call": [2], - "no-self-compare": [2], - "no-octal-escape": [2], - "no-new-wrappers": [2], - "no-process-exit": [2], - "no-catch-shadow": [2], - "linebreak-style": [2], - "space-infix-ops": [2], - "space-unary-ops": [2], - "no-func-assign": [2], - "no-unreachable": [2], - "accessor-pairs": [2], - "no-empty-label": [0], - "no-fallthrough": [2], - "no-path-concat": [2], - "no-new-require": [2], - "no-spaced-func": [2], - "no-unused-vars": [2], - "spaced-comment": [2], - "no-delete-var": [2], - "comma-spacing": [2], - "no-extra-semi": [2], - "no-extra-bind": [2], - "arrow-spacing": [2], - "prefer-spread": [2], - "no-new-object": [2], - "no-multi-str": [2], - "semi-spacing": [2], - "no-lonely-if": [2], - "dot-notation": [2], - "dot-location": [2, "property"], - "comma-dangle": [2, "never"], - "no-dupe-args": [2], - "no-dupe-keys": [2], - "no-ex-assign": [2], - "no-obj-calls": [2], - "valid-typeof": [2], - "default-case": [2], - "no-redeclare": [2], - "no-div-regex": [2], - "no-sequences": [2], - "no-label-var": [2], - "comma-style": [2], - "brace-style": [2], - "no-debugger": [2], - "quote-props": [0], - "no-iterator": [2], - "no-new-func": [2], - "key-spacing": [0], - "complexity": [2], - "new-parens": [2], - "no-eq-null": [2], - "no-bitwise": [2], - "wrap-iife": [2], - "no-caller": [2], - "use-isnan": [2], - "no-labels": [0], - "no-shadow": [2], - "camelcase": [2], - "eol-last": [2], - "no-octal": [2], - "no-empty": [2], - "no-alert": [2], - "no-proto": [2], - "no-undef": [2], - "no-eval": [2], - "no-with": [2], - "no-void": [2], - "new-cap": [2], - "eqeqeq": [2], - "no-new": [2], - "quotes": [2, "single"], - "indent": [2, "tab"], - "semi": [2, "always"], - "yoda": [2, "never"] - }, - "env": { - "mocha": true, - "node": true - } -} \ No newline at end of file diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml new file mode 100644 index 0000000..674130b --- /dev/null +++ b/.github/workflows/ci.yaml @@ -0,0 +1,21 @@ +name: Node.js CI + +on: + push: + branches: master + pull_request: + +jobs: + test: + runs-on: ubuntu-latest + strategy: + matrix: + node-version: [10.x, 12.x, 14.x, 16.x, 17.x] + steps: + - uses: actions/checkout@v2 + - name: Use Node.js ${{ matrix.node-version }} + uses: actions/setup-node@v2 + with: + node-version: ${{ matrix.node-version }} + - run: npm install + - run: npm test diff --git a/.gitignore b/.gitignore index 1ca9571..910ce0f 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,10 @@ -node_modules/ -npm-debug.log +node_modules +package-lock.json +yarn.lock +.* +!.editorconfig +!.gitignore +!.tape.js +!.github +*.log* +*.result.css diff --git a/.npmignore b/.npmignore deleted file mode 100644 index 1aa2d59..0000000 --- a/.npmignore +++ /dev/null @@ -1,8 +0,0 @@ -.gitignore - -node_modules/ - -test/ -.travis.yml - -gulpfile.js diff --git a/.tape.js b/.tape.js new file mode 100644 index 0000000..b032ecc --- /dev/null +++ b/.tape.js @@ -0,0 +1,20 @@ +module.exports = { + 'basic': { + message: 'supports basic usage' + }, + 'basic:w-prefix': { + message: 'ignores basic usage when { prefix: "x" }', + options: { + prefix: 'x' + } + }, + 'prefix': { + message: 'ignores prefix usage' + }, + 'prefix:w-prefix': { + message: 'supports prefix usage when { prefix: "x" }', + options: { + prefix: 'x' + } + } +}; diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index e1bd776..0000000 --- a/.travis.yml +++ /dev/null @@ -1,5 +0,0 @@ -sudo: false -language: node_js -node_js: - - iojs - - "0.12" diff --git a/README.md b/README.md index e426b1c..4a70de5 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,9 @@ -# Short Text [![Build Status][ci-img]][ci] +# Short Text [PostCSS Logo][postcss] - +[![NPM Version][npm-img]][npm-url] +[![Build Status][cli-img]][cli-url] +[![Licensing][lic-img]][lic-url] +[![Gitter Chat][git-img]][git-url] [Short Text] is a [PostCSS] plugin that lets you use a shorthand `text` property in CSS. @@ -133,8 +136,15 @@ Default: `null` Specifies a prefix to be surrounded by dashes before the declaration (e.g. `-x-text`). -[ci]: https://travis-ci.org/jonathantneal/postcss-short-text -[ci-img]: https://travis-ci.org/jonathantneal/postcss-short-text.svg +[cli-url]: https://github.com/csstools/postcss-short-text/actions/workflows/ci.yaml +[cli-img]: https://github.com/csstools/postcss-short-text/actions/workflows/ci.yaml/badge.svg +[git-url]: https://gitter.im/postcss/postcss +[git-img]: https://img.shields.io/badge/chat-gitter-blue.svg +[lic-url]: LICENSE.md +[lic-img]: https://img.shields.io/npm/l/postcss-short-text.svg +[npm-url]: https://www.npmjs.com/package/postcss-short-text +[npm-img]: https://img.shields.io/npm/v/postcss-short-text.svg + [Gulp PostCSS]: https://github.com/postcss/gulp-postcss [Grunt PostCSS]: https://github.com/nDmitry/grunt-postcss [PostCSS]: https://github.com/postcss/postcss diff --git a/gulpfile.js b/gulpfile.js deleted file mode 100644 index 3fb1dbc..0000000 --- a/gulpfile.js +++ /dev/null @@ -1,25 +0,0 @@ -var gulp = require('gulp'); - -var files = ['index.js', 'test/*.js', 'gulpfile.js']; - -gulp.task('lint', function (done) { - var eslint = require('gulp-eslint'); - - return gulp.src(files) - .pipe(eslint()) - .pipe(eslint.format()) - .pipe(eslint.failAfterError()).on('error', done); -}); - -gulp.task('test', function (done) { - var mocha = require('gulp-mocha'); - - return gulp.src('test/*.js', { read: false }) - .pipe(mocha()).on('error', done); -}); - -gulp.task('default', ['lint', 'test']); - -gulp.task('watch', function() { - gulp.watch(files, ['lint', 'test']); -}); diff --git a/index.js b/index.js index 9aad226..b2b79ec 100644 --- a/index.js +++ b/index.js @@ -1,6 +1,6 @@ -var assign = require('object-assign'); -var postcss = require('postcss'); -var matches = [{ +const postcss = require('postcss'); + +const matches = [{ 'color': /^(\*|aliceblue|antiquewhite|aqua|aquamarine|azure|beige|bisque|black|blanchedalmond|blue|blueviolet|brown|burlywood|cadetblue|chartreuse|chocolate|coral|cornflowerblue|cornsilk|crimson|currentColor|cyan|darkblue|darkcyan|darkgoldenrod|darkgray|darkgreen|darkgrey|darkkhaki|darkmagenta|darkolivegreen|darkorange|darkorchid|darkred|darksalmon|darkseagreen|darkslateblue|darkslategray|darkslategrey|darkturquoise|darkviolet|deeppink|deepskyblue|dimgray|dimgrey|dodgerblue|firebrick|floralwhite|forestgreen|fuchsia|gainsboro|ghostwhite|gold|goldenrod|gray|green|greenyellow|grey|honeydew|hotpink|indianred|indigo|inherit|ivory|khaki|lavender|lavenderblush|lawngreen|lemonchiffon|lightblue|lightcoral|lightcyan|lightgoldenrodyellow|lightgray|lightgreen|lightgrey|lightpink|lightsalmon|lightseagreen|lightskyblue|lightslategray|lightslategrey|lightsteelblue|lightyellow|lime|limegreen|linen|magenta|maroon|mediumaquamarine|mediumblue|mediumorchid|mediumpurple|mediumseagreen|mediumslateblue|mediumspringgreen|mediumturquoise|mediumvioletred|midnightblue|mintcream|mistyrose|moccasin|navajowhite|navy|oldlace|olive|olivedrab|orange|orangered|orchid|palegoldenrod|palegreen|paleturquoise|palevioletred|papayawhip|peachpuff|peru|pink|plum|powderblue|purple|rebeccapurple|red|rosybrown|royalblue|saddlebrown|salmon|sandybrown|seagreen|seashell|sienna|silver|skyblue|slateblue|slategray|slategrey|snow|springgreen|steelblue|tan|teal|thistle|tomato|transparent|turquoise|violet|wheat|white|whitesmoke|yellow|yellowgreen|#[0-9a-f]+|(hsl|rgb)a?\(.+\))$/i }, { 'font-style': /^(\*|var\(.+\)|inherit|italic|normal|oblique)$/i, @@ -21,24 +21,27 @@ var matches = [{ 'word-spacing': /^(\*|(calc|var)\(.+\)|inherit|initial|normal|unset|0|[-+]?[0-9]*\.?[0-9]+(%|ch|cm|em|ex|in|mm|pc|pt|px|rem|vh|vmax|vmin|vw))$/i }]; -module.exports = postcss.plugin('postcss-short-text', function (opts) { - var name = opts && opts.prefix ? '-' + opts.prefix + '-text' : 'text'; +module.exports = (opts = {}) => { + const name = opts && opts.prefix ? '-' + opts.prefix + '-text' : 'text'; - return function (css) { - css.walkDecls(name, function (decl) { - var values = postcss.list.space(decl.value); - var sources = matches.slice(0).map(function (source) { - return assign({}, source); - }); + return { + postcssPlugin: 'postcss-short-text', + Declaration (decl) { + if (decl.prop !== name) { + return + } - values.forEach(function (value) { + const values = postcss.list.space(decl.value); + const sources = matches.slice(0).map((source) => Object.assign({}, source)); + + values.forEach((value) => { all: { - var source; + let source while (source = sources[0]) { source.state = source.state || 'skipped'; - for (var prop in source) { + for (const prop in source) { if (prop !== 'state' && source[prop].test(value)) { source.state = 'done'; @@ -61,6 +64,8 @@ module.exports = postcss.plugin('postcss-short-text', function (opts) { }); decl.remove(); - }); - }; -}); + } + } +} + +module.exports.postcss = true; diff --git a/package.json b/package.json index b0b52db..e12d269 100644 --- a/package.json +++ b/package.json @@ -2,6 +2,39 @@ "name": "postcss-short-text", "version": "1.1.0", "description": "Use a shorthand text property in CSS", + "author": "Jonathan Neal ", + "license": "CC0-1.0", + "repository": "csstools/postcss-short-text", + "homepage": "https://github.com/csstools/postcss-short-text#readme", + "bugs": "https://github.com/csstools/postcss-short-text/issues", + "main": "index.js", + "files": [ + "index.js" + ], + "scripts": { + "lint": "eslint . --cache", + "pretest": "npm run lint", + "test": "postcss-tape", + "prepublishOnly": "npm test" + }, + "engines": { + "node": "^10 || ^12 || >=14" + }, + "peerDependencies": { + "postcss": "^8.0.0" + }, + "devDependencies": { + "eslint": "^7.32.0", + "eslint-config-dev": "2.0.0", + "postcss": "^8.3.4", + "postcss-tape": "^6.0.1" + }, + "eslintConfig": { + "extends": "dev", + "parserOptions": { + "sourceType": "module" + } + }, "keywords": [ "postcss", "css", @@ -22,32 +55,5 @@ "letter-spacing", "word-spacing", "font-family" - ], - "author": "Jonathan Neal ", - "license": "CC0-1.0", - "repository": { - "type": "git", - "url": "https://github.com/jonathantneal/postcss-short-text.git" - }, - "bugs": { - "url": "https://github.com/jonathantneal/postcss-short-text/issues" - }, - "homepage": "https://github.com/jonathantneal/postcss-short-text", - "dependencies": { - "object-assign": "^4.0.1", - "postcss": "^5.0.4" - }, - "devDependencies": { - "chai": "^3.2.0", - "gulp": "^3.9.0", - "gulp-eslint": "^1.0.0", - "gulp-mocha": "^2.1.3" - }, - "scripts": { - "test": "gulp" - }, - "engines": { - "iojs": ">=2.0.0", - "node": ">=0.12.0" - } + ] } diff --git a/test/fixtures/basic.css b/test/basic.css similarity index 100% rename from test/fixtures/basic.css rename to test/basic.css diff --git a/test/fixtures/basic.expect.css b/test/basic.expect.css similarity index 100% rename from test/fixtures/basic.expect.css rename to test/basic.expect.css diff --git a/test/fixtures/basic.w-prefix.expect.css b/test/basic.w-prefix.css similarity index 100% rename from test/fixtures/basic.w-prefix.expect.css rename to test/basic.w-prefix.css diff --git a/test/basic.w-prefix.expect.css b/test/basic.w-prefix.expect.css new file mode 100644 index 0000000..d991783 --- /dev/null +++ b/test/basic.w-prefix.expect.css @@ -0,0 +1,7 @@ +section { + text: bold center uppercase dimgrey 1.25em 1.5 .05em; +} + +article { + text: 1.25em * .05em; +} diff --git a/test/fixtures/prefixed.css b/test/prefix.css similarity index 100% rename from test/fixtures/prefixed.css rename to test/prefix.css diff --git a/test/fixtures/prefixed.expect.css b/test/prefix.expect.css similarity index 100% rename from test/fixtures/prefixed.expect.css rename to test/prefix.expect.css diff --git a/test/prefix.w-prefix.css b/test/prefix.w-prefix.css new file mode 100644 index 0000000..c45a8f4 --- /dev/null +++ b/test/prefix.w-prefix.css @@ -0,0 +1,7 @@ +section { + -x-text: bold center uppercase dimgrey 1.25em 1.5 .05em; +} + +article { + -x-text: 1.25em * .05em; +} diff --git a/test/fixtures/prefixed.w-prefix.expect.css b/test/prefix.w-prefix.expect.css similarity index 100% rename from test/fixtures/prefixed.w-prefix.expect.css rename to test/prefix.w-prefix.expect.css diff --git a/test/test.js b/test/test.js deleted file mode 100644 index bc2082e..0000000 --- a/test/test.js +++ /dev/null @@ -1,48 +0,0 @@ -var path = require('path'); -var postcss = require('postcss'); -var expect = require('chai').expect; -var fs = require('fs'); - -var plugin = require('../'); - -function test(name, opts, done) { - var fixtureDir = './test/fixtures/'; - var baseName = name.split(':')[0]; - var testName = name.split(':').join('.'); - var inputPath = path.resolve(fixtureDir + baseName + '.css'); - var expectPath = path.resolve(fixtureDir + testName + '.expect.css'); - - var inputCSS = fs.readFileSync(inputPath, 'utf8'); - var expectCSS = fs.readFileSync(expectPath, 'utf8'); - - postcss([plugin(opts)]).process(inputCSS, { - from: inputPath - }).then(function (result) { - var actualCSS = result.css; - - expect(actualCSS).to.eql(expectCSS); - expect(result.warnings()).to.be.empty; - - done(); - }).catch(function (error) { - done(error); - }); -} - -describe('postcss-short-text', function () { - it('supports standard property', function (done) { - test('basic', {}, done); - }); - - it('ignores standard property with prefix', function (done) { - test('basic:w-prefix', { prefix: 'x' }, done); - }); - - it('ignores prefixed property', function (done) { - test('prefixed', {}, done); - }); - - it('supports prefixed property with prefix', function (done) { - test('prefixed:w-prefix', { prefix: 'x' }, done); - }); -});