Repository: postcss/postcss-color-function Branch: master Commit: f81fb376514e Files: 17 Total size: 15.6 KB Directory structure: gitextract_ry7jyxe7/ ├── .editorconfig ├── .eslintrc.yml ├── .gitignore ├── .travis.yml ├── CHANGELOG.md ├── LICENSE ├── README.md ├── index.js ├── package.json └── test/ ├── fixtures/ │ ├── color-with-custom-properties.css │ ├── color-with-custom-properties.expected.css │ ├── color.css │ ├── color.expected.css │ ├── delete-custom-properties.css │ ├── delete-custom-properties.expected.css │ └── error.css └── index.js ================================================ FILE CONTENTS ================================================ ================================================ FILE: .editorconfig ================================================ # editorconfig.org root = true [*] end_of_line = lf charset = utf-8 trim_trailing_whitespace = true insert_final_newline = true indent_style = space indent_size = 2 [*.md] trim_trailing_whitespace = false [Makefile] indent_style = tab ================================================ FILE: .eslintrc.yml ================================================ root: true extends: eslint:recommended parserOptions: ecmaVersion: 5 env: commonjs: true rules: indent: [2, 2] # 2 spaces indentation max-len: [2, 80, 2] quotes: [2, "double"] semi: [2, "never"] no-multiple-empty-lines: [2, {"max": 1}] brace-style: [2, "stroustrup"] comma-dangle: [2, "always-multiline"] comma-style: [2, "last"] dot-location: [2, "property"] one-var: [2, "never"] # no-var: [2] prefer-const: [2] no-bitwise: [2] object-curly-spacing: [2, "never"] array-bracket-spacing: [2, "never"] computed-property-spacing: [2, "never"] space-unary-ops: [2, {"words": true, "nonwords": false}] keyword-spacing: [2, {"before": true, "after": true}] space-before-blocks: [2, "always"] space-before-function-paren: [2, "never"] space-in-parens: [2, "never"] spaced-comment: [2, "always"] ================================================ FILE: .gitignore ================================================ node_modules test/fixtures/*.actual.css ================================================ FILE: .travis.yml ================================================ sudo: false language: node_js node_js: - "6" - "4" ================================================ FILE: CHANGELOG.md ================================================ # 4.1.0 - 2019-04-01 - Added: `preserveCustomProps` option to preserve custom properties - Updated: `postcss` to 6.0.23 (patch) - Updated: `postcss-value-parser` to 3.3.1 (patch) # 4.0.1 - 2017-11-03 - Fixed: bug when using the `tint`, `shade`, and `contrast` adjusters along with the `alpha` adjuster ([#33](https://github.com/postcss/postcss-color-function/pull/33) - @tylergaw) # 4.0.0 - 2017-05-15 - Added: compatibility with postcss v6.x - Updated dependencies # 3.0.0 - 2017-02-01 - Changed: send postcss warning when color function cannot be parsed instead of throwing ([#35](https://github.com/postcss/postcss-color-function/pull/35) - @drewbourne) - Changed: send a postcss message when color function contains a var() ([#36](https://github.com/postcss/postcss-color-function/pull/36) - @drewbourne) # 2.0.1 - 2016-03-15 - Fixed: whitespace are retained between color() usage. ([#27](https://github.com/postcss/postcss-color-function/pull/27)) # 2.0.0 - 2015-09-07 - Removed: compatibility with postcss v4.x ([#14](https://github.com/postcss/postcss-color-function/pull/14)) - Added: compatibility with postcss v5.x ([#14](https://github.com/postcss/postcss-color-function/pull/14)) # 1.3.2 - 2015-07-08 - Fixed: the plugin now do now transform all functions that match `*color(` but only the one that are real color function call ([#12](https://github.com/postcss/postcss-color-function/pull/12)) # 1.3.1 - 2015-07-08 **YANKED** _This was just 1.3.0._ # 1.3.0 - 2015-06-13 - Changed: upgrade to PostCSS 4.1.x # 1.2.0 - 2015-03-12 - Added: contrast() adjuster # 1.1.0 - 2014-11-25 - Added: Enhanced exceptions # 1.0.0 - 2014-10-04 ✨ Initial release from [postcss-color](https://github.com/postcss/postcss-color) ================================================ FILE: LICENSE ================================================ The MIT License (MIT) Copyright (c) 2017 Maxime Thirouin & Ian Storm Taylor Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ================================================ FILE: README.md ================================================ # postcss-color-function [![Build Status](https://travis-ci.org/postcss/postcss-color-function.svg)](https://travis-ci.org/postcss/postcss-color-function) [PostCSS](https://github.com/postcss/postcss) plugin to transform CSS color function from editor draft of 'Color Module Level 4' specification to more compatible CSS. ## Deprecated **⚠️ `color()` was changed to `color-mod()`. See [postcss-color-mod-function](https://github.com/jonathantneal/postcss-color-mod-function).** > There is a [`color-mod`](https://github.com/jonathantneal/postcss-color-mod-function) implementation. **⚠️ `color-mod()` has been removed from [Color Module Level 4 specification](https://www.w3.org/TR/css-color-4/#changes-from-20160705).** ## Installation ```console npm install postcss-color-function ``` ## Usage ```js // dependencies var fs = require("fs") var postcss = require("postcss") var colorFunction = require("postcss-color-function") // css to be processed var css = fs.readFileSync("input.css", "utf8") // process css // set preserveCustomProps to `false` by default `true` //for delete declarations with custom properties var output = postcss() .use(colorFunction({preserveCustomProps: true})) .process(css) .css ``` Using this `input.css`: ```css body { background: color(red a(90%)) } ``` you will get: ```css body { background: rgba(255, 0, 0, 0.9) } ``` Checkout [tests](test) for examples. ## Interface (according to CSS specs) ``` color( [ | ] * ) ``` ### List of `color-adjuster` - `[red( | green( | blue( | alpha( | a(] ['+' | '-']? [ | ] )` - `[red( | green( | blue( | alpha( | a(] '*' )` - ~~`rgb( ['+' | '-'] [ | ]{3} )`~~ @todo - ~~`rgb( ['+' | '-'] )`~~ @todo - ~~`rgb( '*' ) |`~~ @todo - `[hue( | h(] ['+' | '-' | '*']? )` - `[saturation( | s(] ['+' | '-' | '*']? )` - `[lightness( | l(] ['+' | '-' | '*']? )` - `[whiteness( | w(] ['+' | '-' | '*']? )` - `[blackness( | b(] ['+' | '-' | '*']? )` - `tint( )` - `shade( )` - `blend( [rgb | hsl | hwb]? )` - ~~`blenda( [rgb | hsl | hwb]? )`~~ @todo - `contrast( ? )` Notes: - some adjusts have shortcuts, - can be used on every value on any property, - some values can use add/subtract/scale modifiers or a direct value. ### Examples ```css whatever { color: color(red a(10%)); background-color: color(red lightness(50%)); /* == color(red l(50%)); */ border-color: color(hsla(125, 50%, 50%, .4) saturation(+ 10%) w(- 20%)); } ``` ## FAQ ### Can you support `currentcolor` so we can do `color(currentcolor adjuster())`? No we cannot do that. `currentcolor` depends on the cascade (so the DOM) and we can't handle that in a simple preprocessing step. You need to handle that with polyfills. ### Can we use CSS custom properties so we can do `color(var(--mainColor) adjuster())`? By using [postcss-custom-properties](https://github.com/postcss/postcss-custom-properties) before this plugin, you can do that (sort of). You have some examples in [cssnext playground](http://cssnext.io/playground/). ## Notes for former Sass users `lighten` and `darken` are Sass specific methods and not supported by native CSS specs. The same functionality can be achieved with the [tint and shade adjusters](https://drafts.csswg.org/css-color/#tint-shade-adjusters): ```css $lighten(red, 20%) /* is equivalent to */ color(red tint(20%)) $darken(red, 20%) /* is equivalent to */ color(red shade(20%)) ``` --- ## [Changelog](CHANGELOG.md) ## [License](LICENSE) ================================================ FILE: index.js ================================================ /** * Module dependencies. */ var postcss = require("postcss") var parser = require("postcss-value-parser") var colorFn = require("css-color-function") var helpers = require("postcss-message-helpers") var defaultOptions = { preserveCustomProps: true, } /** * PostCSS plugin to transform color() */ module.exports = postcss.plugin("postcss-color-function", function(options) { options = Object.assign({}, defaultOptions, options) return function(style, result) { style.walkDecls(function transformDecl(decl) { if (!decl.value || decl.value.indexOf("color(") === -1) { return } if (decl.value.indexOf("var(") !== -1) { if (!options.preserveCustomProps) { decl.remove() return } result.messages.push({ plugin: "postcss-color-function", type: "skipped-color-function-with-custom-property", word: decl.value, message: "Skipped color function with custom property `" + decl.value + "`", }) return } try { decl.value = helpers.try(function transformColorValue() { return transformColor(decl.value) }, decl.source) } catch (error) { decl.warn(result, error.message, { word: decl.value, index: decl.index, }) } }) } }) /** * Transform color() to rgb() * * @param {String} string declaration value * @return {String} converted declaration value to rgba() */ function transformColor(string) { return parser(string).walk(function(node) { if (node.type !== "function" || node.value !== "color") { return } node.value = colorFn.convert(parser.stringify(node)) node.type = "word" }).toString() } ================================================ FILE: package.json ================================================ { "name": "postcss-color-function", "version": "4.1.0", "description": "PostCSS plugin to transform W3C CSS color function to more compatible CSS.", "keywords": [ "css", "postcss", "postcss-plugin", "color", "colour", "function" ], "author": "Maxime Thirouin", "license": "MIT", "repository": "https://github.com/postcss/postcss-color-function.git", "files": [ "index.js" ], "dependencies": { "css-color-function": "~1.3.3", "postcss": "^6.0.23", "postcss-message-helpers": "^2.0.0", "postcss-value-parser": "^3.3.1" }, "devDependencies": { "eslint": "^3.19.0", "faucet": "0.0.1", "npmpub": "^3.1.0", "tape": "^4.10.1" }, "scripts": { "lint": "eslint *.js index.js ./test/", "test": "npm run lint && tape test | faucet", "release": "npmpub" } } ================================================ FILE: test/fixtures/color-with-custom-properties.css ================================================ body { color: color(var(--red)); color: color(var(--red) tint(50%)); color: color(var(--red) tint(var(--tintPercent))); color: color(rgb(255, 0, 0) tint(var(--tintPercent))); } ================================================ FILE: test/fixtures/color-with-custom-properties.expected.css ================================================ body { color: color(var(--red)); color: color(var(--red) tint(50%)); color: color(var(--red) tint(var(--tintPercent))); color: color(rgb(255, 0, 0) tint(var(--tintPercent))); } ================================================ FILE: test/fixtures/color.css ================================================ body { color: color(red); background-color: color(red tint(50%)); border-color: color(hsla(125, 50%, 50%, .4) hue(200)); border-top-color: color(hwb(270, 10%, 0%) contrast(50%)); border-bottom-color: hover-color(red); border-right-color: hover-color(color(red tint(50%))); border-color: color(#999 a(0.8)) color(#999 a(0.8)); } .withAlpha { color: color(black a(80%) contrast(99%)); background-color: color(red a(50%) shade(50%)); border-color: color(red a(80%) tint(50%)); } ================================================ FILE: test/fixtures/color.expected.css ================================================ body { color: rgb(255, 0, 0); background-color: rgb(255, 128, 128); border-color: rgba(64, 149, 191, 0.4); border-top-color: rgb(248, 240, 255); border-bottom-color: hover-color(red); border-right-color: hover-color(rgb(255, 128, 128)); border-color: rgba(153, 153, 153, 0.8) rgba(153, 153, 153, 0.8); } .withAlpha { color: rgba(255, 255, 255, 0.8); background-color: rgba(128, 0, 0, 0.5); border-color: rgba(255, 128, 128, 0.8); } ================================================ FILE: test/fixtures/delete-custom-properties.css ================================================ body { color: color(var(--red)); color: color(var(--red) tint(50%)); background-color: color(red tint(50%)); color: color(var(--red) tint(var(--tintPercent))); color: color(rgb(255, 0, 0) tint(var(--tintPercent))); } ================================================ FILE: test/fixtures/delete-custom-properties.expected.css ================================================ body { background-color: rgb(255, 128, 128); } ================================================ FILE: test/fixtures/error.css ================================================ body { background: color(blurp a(+10%)); } ================================================ FILE: test/index.js ================================================ var fs = require("fs") var test = require("tape") var postcss = require("postcss") var plugin = require("..") function filename(name) { return "test/" + name + ".css" } function read(name) { return fs.readFileSync(name, "utf8") } function compareFixtures(t, name, msg, opts, postcssOpts) { postcssOpts = postcssOpts || {} postcssOpts.from = filename("fixtures/" + name) opts = opts || {} var actual = postcss().use(plugin(opts)) .process(read(postcssOpts.from), postcssOpts).css var expected = read(filename("fixtures/" + name + ".expected")) fs.writeFileSync(filename("fixtures/" + name + ".actual"), actual) t.equal(actual, expected, msg) } test("color()", function(t) { compareFixtures(t, "color", "should transform color()") t.end() }) test("logs warning when color() value cannot be parsed", function(t) { postcss(plugin()).process(read(filename("fixtures/error"))) .then(function(result) { var warnings = result.warnings() t.equals(warnings.length, 1, "expected only 1 warning") var warning = warnings[0] t.equals( warning.plugin, "postcss-color-function", "expected `warning.plugin` to match this plugin's name" ) t.equals( warning.word, "color(blurp a(+10%))", "expected `warning.word` to match color() declaration" ) t.equals( warning.text, ":2:3: Unable to parse color from string \"blurp\"", "expected `warning.text` to contain a readable error " + "when a color can't be parsed" ) t.end() }) }) test("logs message when color() contains var() custom property", function(t) { postcss(plugin()).process( read(filename("fixtures/color-with-custom-properties")) ).then(function(result) { var expectedWords = [ "color(var(--red))", "color(var(--red) tint(50%))", "color(var(--red) tint(var(--tintPercent)))", "color(rgb(255, 0, 0) tint(var(--tintPercent)))", ] t.equal( result.messages.length, expectedWords.length, "expected a message every time a color function is skipped" ) result.messages.forEach(function(message, i) { t.equal( message.type, "skipped-color-function-with-custom-property", "expected `message.type` to indicate reason for message" ) t.equal( message.plugin, "postcss-color-function", "expected `message.plugin` to match this plugin's name" ) t.equal( message.word, expectedWords[i], "expected `message.word` to contain declaration value" ) t.equal( message.message, "Skipped color function with custom property " + "`" + expectedWords[i] + "`", "expected `message.message` to contain reason for message" ) }) t.end() }) }) test( "test delete custom properties with option preserveCustomProps `false`", function(t) { postcss(plugin({preserveCustomProps : false})).process( read(filename("fixtures/delete-custom-properties")) ).then(function(result) { var expectedDeclaration = [{ prop: "background-color", value: "rgb(255, 128, 128)", }] // check left rules in body after clear var declNodes = result.root.nodes[0].nodes t.equal( declNodes.length, expectedDeclaration.length, "expected " + expectedDeclaration.length + " declaration length but got " + declNodes.length ) t.equal( declNodes[0].prop, expectedDeclaration[0].prop, "expected declaration with "+ expectedDeclaration[0].prop + " property but got " + declNodes[0].prop ) t.equal( declNodes[0].value, expectedDeclaration[0].value, "expected declaration with "+ expectedDeclaration[0].value + " value but got " + declNodes[0].value ) t.end() }) } )