From 35fd8f43453f7c48b818f3e852720f7f902c6e6f Mon Sep 17 00:00:00 2001 From: Maxime Thirouin Date: Fri, 1 Aug 2014 10:03:31 +0200 Subject: [PATCH 001/795] First release based on rework-vars v3.1.1 --- .gitignore | 2 + .travis.yml | 1 + CHANGELOG.md | 3 + LICENSE | 20 ++++ README.md | 43 +++++++ index.js | 119 +++++++++++++++++++ package.json | 29 +++++ test/fixtures/case-sensitive.css | 9 ++ test/fixtures/case-sensitive.out.css | 4 + test/fixtures/media-query.css | 5 + test/fixtures/media-query.out.css | 5 + test/fixtures/preserve-variables.css | 20 ++++ test/fixtures/preserve-variables.out.css | 23 ++++ test/fixtures/remove-properties.css | 13 ++ test/fixtures/remove-properties.out.css | 3 + test/fixtures/substitution-defined.css | 28 +++++ test/fixtures/substitution-defined.out.css | 22 ++++ test/fixtures/substitution-empty.css | 3 + test/fixtures/substitution-fallback.css | 22 ++++ test/fixtures/substitution-fallback.out.css | 18 +++ test/fixtures/substitution-malformed.css | 4 + test/fixtures/substitution-overwrite.css | 12 ++ test/fixtures/substitution-overwrite.out.css | 4 + test/fixtures/substitution-undefined.css | 3 + test/index.js | 79 ++++++++++++ 25 files changed, 494 insertions(+) create mode 100644 .gitignore create mode 100644 .travis.yml create mode 100755 CHANGELOG.md create mode 100644 LICENSE create mode 100755 README.md create mode 100755 index.js create mode 100755 package.json create mode 100755 test/fixtures/case-sensitive.css create mode 100755 test/fixtures/case-sensitive.out.css create mode 100755 test/fixtures/media-query.css create mode 100755 test/fixtures/media-query.out.css create mode 100755 test/fixtures/preserve-variables.css create mode 100755 test/fixtures/preserve-variables.out.css create mode 100755 test/fixtures/remove-properties.css create mode 100755 test/fixtures/remove-properties.out.css create mode 100755 test/fixtures/substitution-defined.css create mode 100755 test/fixtures/substitution-defined.out.css create mode 100755 test/fixtures/substitution-empty.css create mode 100755 test/fixtures/substitution-fallback.css create mode 100755 test/fixtures/substitution-fallback.out.css create mode 100755 test/fixtures/substitution-malformed.css create mode 100755 test/fixtures/substitution-overwrite.css create mode 100755 test/fixtures/substitution-overwrite.out.css create mode 100755 test/fixtures/substitution-undefined.css create mode 100755 test/index.js diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000000..7ab649f420 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +node_modules +test/fixtures/*.actual.css diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000000..587bd3e031 --- /dev/null +++ b/.travis.yml @@ -0,0 +1 @@ +language: node_js diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100755 index 0000000000..66c120380d --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,3 @@ +# 0.1.0 - 2014-08-01 + +First release based on [rework-vars](https://github.com/reworkcss/rework-vars) v3.1.1 diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000000..9abe4f5458 --- /dev/null +++ b/LICENSE @@ -0,0 +1,20 @@ +The MIT License (MIT) + +Copyright (c) 2014 "MoOx" Maxime Thirouin + +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. diff --git a/README.md b/README.md new file mode 100755 index 0000000000..d90dc32a71 --- /dev/null +++ b/README.md @@ -0,0 +1,43 @@ +# postcss-custom-properties [![Build Status](https://travis-ci.org/postcss/postcss-custom-properties.png)](https://travis-ci.org/postcss/postcss-custom-properties) + +A [PostCSS](https://github.com/postcss/postcss) plugin to polyfill the +[W3C-style CSS Custom Properties for cascading variables](http://www.w3.org/TR/css-variables/). + +**N.B.** For now the polyfill _is not complete_. It currently just aims to provide a future-proof way of using a _limited subset_ of the features provided by native CSS variables. + +_[Checkout opened issue to know the state of this plugin](issues)._ + +## Installation + +``` +npm install postcss-custom-properties +``` + +## Usage + +```js +// dependencies +var fs = require('fs') +var postcss = require('postcss') +var customProperties = require('postcss-custom-properties') + +// css to be processed +var css = fs.readFileSync('build/build.css', 'utf8') + +// process css using postcss-custom-properties +var out = postcss(customProperties()).process(css).css +``` + +### Options + +#### `preserve` (default: `false`) + +Allow you to preserve custom properties & var() usage in output. + +```js +var out = postcss(customProperties({preserve: true})).process(css).css +``` + +## [Changelog](CHANGELOG.md) + +## [License](LICENSE-MIT) diff --git a/index.js b/index.js new file mode 100755 index 0000000000..7b1455f55a --- /dev/null +++ b/index.js @@ -0,0 +1,119 @@ +/** + * Module dependencies. + */ + +var balanced = require('balanced-match') + +/** + * Constants. + */ + +var VAR_PROP_IDENTIFIER = '--' +var VAR_FUNC_IDENTIFIER = 'var' + +/** + * Module export. + */ + +module.exports = function (options) { + + return function(style) { + options = options || {} + var map = {} + var preserve = (options.preserve === true ? true : false) + + // define variables + style.eachRule(function (rule) { + var varNameIndices = [] + if (rule.type !== 'rule') return + + // only variables declared for `:root` are supported for now + if (rule.selectors.length !== 1 || rule.selectors[0] !== ":root" || rule.parent.type !== "root") return + + rule.each(function (decl, i) { + var prop = decl.prop + var value = decl.value + + if (prop && prop.indexOf(VAR_PROP_IDENTIFIER) === 0) { + map[prop] = value + varNameIndices.push(i) + } + }) + + // optionally remove `--*` properties from the rule + if (!preserve) { + for (var i = varNameIndices.length - 1; i >= 0; i--) { + rule.decls.splice(varNameIndices[i], 1) + } + + // remove empty :root {} + if (rule.decls.length === 0) rule.removeSelf() + } + }) + + // resolve variables + style.eachDecl(function (decl, i) { + var resolvedValue + var value = decl.value + + // skip values that don't contain variable functions + if (!value || value.indexOf(VAR_FUNC_IDENTIFIER + '(') === -1) return + + resolvedValue = resolveValue(value, map) + + if (!preserve) { + decl.value = resolvedValue + } + else { + decl.parent.insertBefore(decl, { + prop: decl.prop, + value: resolvedValue + }) + } + }) + } +} + +/** + * Resolve CSS variables in a value + * + * The second argument to a CSS variable function, if provided, is a fallback + * value, which is used as the substitution value when the referenced variable + * is invalid. + * + * var(name[, fallback]) + * + * @param {String} value A property value known to contain CSS variable functions + * @param {Object} map A map of variable names and values + * @return {String} A property value with all CSS variables substituted. + */ + +function resolveValue(value, map) { + // matches `name[, fallback]`, captures 'name' and 'fallback' + var RE_VAR = /([\w-]+)(?:\s*,\s*)?(.*)?/ + var balancedParens = balanced('(', ')', value) + var varStartIndex = value.indexOf('var(') + var varRef = balanced('(', ')', value.substring(varStartIndex)).body + + if (!balancedParens) throw new SyntaxError('postcss-custom-properties: missing closing ")" in the value "' + value + '"') + if (varRef === '') throw new Error('postcss-custom-properties: var() must contain a non-whitespace string') + + var varFunc = VAR_FUNC_IDENTIFIER + '(' + varRef + ')' + + var varResult = varRef.replace(RE_VAR, function (_, name, fallback) { + var replacement = map[name] + if (!replacement && !fallback) throw new Error('postcss-custom-properties: variable "' + name + '" is undefined') + if (!replacement && fallback) return fallback + return replacement + }) + + // resolve the variable + value = value.split(varFunc).join(varResult) + + // recursively resolve any remaining variables in the value + if (value.indexOf(VAR_FUNC_IDENTIFIER) !== -1) { + value = resolveValue(value, map) + } + + return value +} diff --git a/package.json b/package.json new file mode 100755 index 0000000000..ec4a4ef471 --- /dev/null +++ b/package.json @@ -0,0 +1,29 @@ +{ + "name": "postcss-custom-properties", + "version": "0.0.0", + "description": "PostCSS that polyfill CSS custom properties for cascading variable module", + "keywords": ["css", "postcss", "postcss-plugin", "custom-properties", "variables", "vars"], + "author": "MoOx", + "license": "MIT", + "repository": { + "type": "git", + "url": "https://github.com/postcss/postcss-custom-properties.git" + }, + "files": [ + "CHANGELOG.md", + "LICENSE", + "README.md", + "index.js" + ], + "dependencies": { + "balanced-match": "~0.1.0" + }, + "devDependencies": { + "postcss": "^2.1.0", + "tap-colorize": "^1.2.0", + "tape": "^2.13.4" + }, + "scripts": { + "test": "node test | tap-colorize" + } +} diff --git a/test/fixtures/case-sensitive.css b/test/fixtures/case-sensitive.css new file mode 100755 index 0000000000..f54b954abc --- /dev/null +++ b/test/fixtures/case-sensitive.css @@ -0,0 +1,9 @@ +:root { + --TEST-color: red; + --tESt-COLOR: green; +} + +div { + color: var(--TEST-color); + color: var(--tESt-COLOR); +} diff --git a/test/fixtures/case-sensitive.out.css b/test/fixtures/case-sensitive.out.css new file mode 100755 index 0000000000..365540a2ba --- /dev/null +++ b/test/fixtures/case-sensitive.out.css @@ -0,0 +1,4 @@ +div { + color: red; + color: green; +} diff --git a/test/fixtures/media-query.css b/test/fixtures/media-query.css new file mode 100755 index 0000000000..2ff566f020 --- /dev/null +++ b/test/fixtures/media-query.css @@ -0,0 +1,5 @@ +@media screen and (min-width: 320px) { + :root { + --error: red; + } +} diff --git a/test/fixtures/media-query.out.css b/test/fixtures/media-query.out.css new file mode 100755 index 0000000000..2ff566f020 --- /dev/null +++ b/test/fixtures/media-query.out.css @@ -0,0 +1,5 @@ +@media screen and (min-width: 320px) { + :root { + --error: red; + } +} diff --git a/test/fixtures/preserve-variables.css b/test/fixtures/preserve-variables.css new file mode 100755 index 0000000000..35849be7cc --- /dev/null +++ b/test/fixtures/preserve-variables.css @@ -0,0 +1,20 @@ +:root { + --color-one: red; + --color-two: blue; +} + +.atthebeginning { + color: var(--color-one); + prop: after; +} + +.attheend { + prop: before; + color: var(--color-two); +} + +.surrounded { + prop: before; + color: var(--undefined-color, green); + otherprop: after; +} diff --git a/test/fixtures/preserve-variables.out.css b/test/fixtures/preserve-variables.out.css new file mode 100755 index 0000000000..9e7677692d --- /dev/null +++ b/test/fixtures/preserve-variables.out.css @@ -0,0 +1,23 @@ +:root { + --color-one: red; + --color-two: blue; +} + +.atthebeginning { + color: red; + color: var(--color-one); + prop: after; +} + +.attheend { + prop: before; + color: blue; + color: var(--color-two); +} + +.surrounded { + prop: before; + color: green; + color: var(--undefined-color, green); + otherprop: after; +} diff --git a/test/fixtures/remove-properties.css b/test/fixtures/remove-properties.css new file mode 100755 index 0000000000..649e9631d8 --- /dev/null +++ b/test/fixtures/remove-properties.css @@ -0,0 +1,13 @@ +:root { + --test-one: test; + --test-two: test; +} + +div { + color: red; +} + +:root { + --test-three: test; + --test-four: test; +} diff --git a/test/fixtures/remove-properties.out.css b/test/fixtures/remove-properties.out.css new file mode 100755 index 0000000000..538fa56f4a --- /dev/null +++ b/test/fixtures/remove-properties.out.css @@ -0,0 +1,3 @@ +div { + color: red; +} diff --git a/test/fixtures/substitution-defined.css b/test/fixtures/substitution-defined.css new file mode 100755 index 0000000000..204b3e441f --- /dev/null +++ b/test/fixtures/substitution-defined.css @@ -0,0 +1,28 @@ +/** + * Test comment + */ + +:root { + --test-one: green; + --test-two: blue; + --test-three: yellow; +} + +:root, +span { + --untouched: red; +} + +div { + --untouched: red; + /* single variable */ + color: var(--test-one); + /* single variable with tail */ + color: var(--test-one) !important; + /* multiple variables */ + color: var(--test-one), var(--test-two); + /* variable with function in fallback */ + border: var(--test-one, 1px solid rgba(0, 0, 0, 0.1)); + /* multiple variables within a function */ + background: linear-gradient(to top, var(--test-one), var(--test-two)); +} diff --git a/test/fixtures/substitution-defined.out.css b/test/fixtures/substitution-defined.out.css new file mode 100755 index 0000000000..5d50ed33bf --- /dev/null +++ b/test/fixtures/substitution-defined.out.css @@ -0,0 +1,22 @@ +/** + * Test comment + */ + +:root, +span { + --untouched: red; +} + +div { + --untouched: red; + /* single variable */ + color: green; + /* single variable with tail */ + color: green !important; + /* multiple variables */ + color: green, blue; + /* variable with function in fallback */ + border: green; + /* multiple variables within a function */ + background: linear-gradient(to top, green, blue); +} diff --git a/test/fixtures/substitution-empty.css b/test/fixtures/substitution-empty.css new file mode 100755 index 0000000000..12ed84db17 --- /dev/null +++ b/test/fixtures/substitution-empty.css @@ -0,0 +1,3 @@ +div { + color: var(); +} diff --git a/test/fixtures/substitution-fallback.css b/test/fixtures/substitution-fallback.css new file mode 100755 index 0000000000..3eba4c4eac --- /dev/null +++ b/test/fixtures/substitution-fallback.css @@ -0,0 +1,22 @@ +:root { + --nested: green; +} + +div { + /* simple fallback */ + color: var(--missing, green); + /* comma-separated fallback */ + color: var(--missing, green, blue); + /* fallback is a function */ + background: var(--missing, linear-gradient(to top, #000, #111)); + /* fallback contains a function */ + background: var(--missing, 1px solid rgba(0, 0, 0, 0.1)); + /* fallback is a function containing a function */ + background: var(--missing, linear-gradient(to top, #000, rgba(0, 0, 0, 0.5))); + /* fallback contains a defined variable */ + background: var(--missing, var(--nested)); + /* fallback contains a defined variable within a function */ + background: var(--missing, linear-gradient(to top, #000, var(--nested))); + /* fallback contains an undefined variable with a fallack */ + background: var(--missing, var(--also-missing, green)); +} diff --git a/test/fixtures/substitution-fallback.out.css b/test/fixtures/substitution-fallback.out.css new file mode 100755 index 0000000000..f42ba55c6c --- /dev/null +++ b/test/fixtures/substitution-fallback.out.css @@ -0,0 +1,18 @@ +div { + /* simple fallback */ + color: green; + /* comma-separated fallback */ + color: green, blue; + /* fallback is a function */ + background: linear-gradient(to top, #000, #111); + /* fallback contains a function */ + background: 1px solid rgba(0, 0, 0, 0.1); + /* fallback is a function containing a function */ + background: linear-gradient(to top, #000, rgba(0, 0, 0, 0.5)); + /* fallback contains a defined variable */ + background: green; + /* fallback contains a defined variable within a function */ + background: linear-gradient(to top, #000, green); + /* fallback contains an undefined variable with a fallack */ + background: green; +} diff --git a/test/fixtures/substitution-malformed.css b/test/fixtures/substitution-malformed.css new file mode 100755 index 0000000000..2c13bed62b --- /dev/null +++ b/test/fixtures/substitution-malformed.css @@ -0,0 +1,4 @@ +div { + /* missing closing ')' */ + color: var(--test, rgba(0,0,0,0.5); +} diff --git a/test/fixtures/substitution-overwrite.css b/test/fixtures/substitution-overwrite.css new file mode 100755 index 0000000000..cbb937cd57 --- /dev/null +++ b/test/fixtures/substitution-overwrite.css @@ -0,0 +1,12 @@ +:root { + --test-override: red; +} + +div { + background: var(--test-override); + color: var(--test-override); +} + +:root { + --test-override: green; +} diff --git a/test/fixtures/substitution-overwrite.out.css b/test/fixtures/substitution-overwrite.out.css new file mode 100755 index 0000000000..8585a8cae5 --- /dev/null +++ b/test/fixtures/substitution-overwrite.out.css @@ -0,0 +1,4 @@ +div { + background: green; + color: green; +} diff --git a/test/fixtures/substitution-undefined.css b/test/fixtures/substitution-undefined.css new file mode 100755 index 0000000000..09859fd82d --- /dev/null +++ b/test/fixtures/substitution-undefined.css @@ -0,0 +1,3 @@ +div { + color: var(--test); +} diff --git a/test/index.js b/test/index.js new file mode 100755 index 0000000000..1d8d223f3e --- /dev/null +++ b/test/index.js @@ -0,0 +1,79 @@ +var fs = require("fs") + +var test = require("tape") + +var postcss = require("postcss") +var customProperties = require("..") + +function fixture(name) { + return fs.readFileSync("test/fixtures/" + name + ".css", "utf8").trim() +} + +function compareFixtures(t, name, options) { + var actual = postcss(customProperties(options)).process(fixture(name)).css.trim() + + // handy thing: checkout actual in the *.actual.css file + fs.writeFile("test/fixtures/" + name + ".actual.css", actual) + + var expected = fixture(name + ".out") + return t.equal(actual, expected, "processed fixture '" + name + "' should be equal to expected output") +} + +test("throws an error when a variable function is empty", function (t) { + var output = function (t) { + return postcss(customProperties()).process(fixture("substitution-empty")).css + } + t.throws(output, Error, "postcss-custom-properties: var() must contain a non-whitespace string") + t.end() +}) + +test("throws an error when a variable function is malformed", function (t) { + var output = function (t) { + return postcss(customProperties()).process(fixture("substitution-malformed")).css + } + t.throws(output, SyntaxError, "postcss-custom-properties: missing closing \")\" in the value \"var(--t, rgba(0,0,0,0.5)\"") + t.end() +}) + +test("throws an error when a variable function references an undefined variable", function (t) { + var output = function (t) { + return postcss(customProperties()).process(fixture("substitution-undefined")).css + } + t.throws(output, Error, "postcss-custom-properties: variable \"--t\" is undefined") + t.end() +}) + +test("substitutes defined variables in `:root` only", function (t) { + compareFixtures(t, "substitution-defined") + t.end() +}) + +test("removes variable properties from the output", function (t) { + compareFixtures(t, "remove-properties") + t.end() +}) + +test("ignores variables defined in a media query", function (t) { + compareFixtures(t, "media-query") + t.end() +}) + +test("overwrites variables correctly", function (t) { + compareFixtures(t, "substitution-overwrite") + t.end() +}) + +test("substitutes undefined variables if there is a fallback", function (t) { + compareFixtures(t, "substitution-fallback") + t.end() +}) + +test("supports case-sensitive variables", function (t) { + compareFixtures(t, "case-sensitive") + t.end() +}) + +test("preserves variables when `preserve` is `true`", function (t) { + compareFixtures(t, "preserve-variables", {preserve: true}) + t.end() +}) From 32189bf7ac6735fffbc91765ee28da2c791d968b Mon Sep 17 00:00:00 2001 From: Maxime Thirouin Date: Fri, 1 Aug 2014 10:05:07 +0200 Subject: [PATCH 002/795] v0.1.0 --- package.json | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index ec4a4ef471..e4bef3d626 100755 --- a/package.json +++ b/package.json @@ -1,8 +1,15 @@ { "name": "postcss-custom-properties", - "version": "0.0.0", + "version": "0.1.0", "description": "PostCSS that polyfill CSS custom properties for cascading variable module", - "keywords": ["css", "postcss", "postcss-plugin", "custom-properties", "variables", "vars"], + "keywords": [ + "css", + "postcss", + "postcss-plugin", + "custom-properties", + "variables", + "vars" + ], "author": "MoOx", "license": "MIT", "repository": { From e5fea8cfb4b7519e630eb51502fd604d0513f852 Mon Sep 17 00:00:00 2001 From: Maxime Thirouin Date: Fri, 1 Aug 2014 10:18:25 +0200 Subject: [PATCH 003/795] typo poke @_kud --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index e4bef3d626..58ca558adb 100755 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "postcss-custom-properties", "version": "0.1.0", - "description": "PostCSS that polyfill CSS custom properties for cascading variable module", + "description": "PostCSS that polyfills CSS custom properties for cascading variable module", "keywords": [ "css", "postcss", From f9b6265820d351b1c8c9e888ba621ce1e29eae1f Mon Sep 17 00:00:00 2001 From: Maxime Thirouin Date: Fri, 1 Aug 2014 10:22:14 +0200 Subject: [PATCH 004/795] Add note about `postcss-vars` --- README.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/README.md b/README.md index d90dc32a71..7621b81513 100755 --- a/README.md +++ b/README.md @@ -7,6 +7,9 @@ A [PostCSS](https://github.com/postcss/postcss) plugin to polyfill the _[Checkout opened issue to know the state of this plugin](issues)._ +Why not `postcss-vars` ? Because [there is already a plugin with this name](http://github.com/iamvdo/postcss-vars) that have severals bugs & untested code. +But I look forward to merge those 2 plugins & deprecate this one [ref](https://github.com/iamvdo/postcss-vars/issues/4). + ## Installation ``` From a0343455d45bfa6717c43e64557e3ef6a23057a9 Mon Sep 17 00:00:00 2001 From: Maxime Thirouin Date: Fri, 1 Aug 2014 10:24:26 +0200 Subject: [PATCH 005/795] Update ref for `postcss-vars` thing --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 7621b81513..19dbc36fb7 100755 --- a/README.md +++ b/README.md @@ -8,7 +8,7 @@ A [PostCSS](https://github.com/postcss/postcss) plugin to polyfill the _[Checkout opened issue to know the state of this plugin](issues)._ Why not `postcss-vars` ? Because [there is already a plugin with this name](http://github.com/iamvdo/postcss-vars) that have severals bugs & untested code. -But I look forward to merge those 2 plugins & deprecate this one [ref](https://github.com/iamvdo/postcss-vars/issues/4). +But I look forward to merge those 2 plugins & deprecate this one ([see opened issue](https://github.com/iamvdo/postcss-vars/issues/4)). ## Installation From ba9e41641362af4f8c4a062af6b01f1b382892d1 Mon Sep 17 00:00:00 2001 From: Maxime Thirouin Date: Mon, 4 Aug 2014 11:31:12 +0200 Subject: [PATCH 006/795] Add linting --- .editorconfig | 16 +++++++ .jscsrc | 130 ++++++++++++++++++++++++++++++++++++++++++++++++++ .jshintrc | 9 ++++ index.js | 61 ++++++++++++++--------- package.json | 7 ++- test/index.js | 26 +++++----- 6 files changed, 212 insertions(+), 37 deletions(-) create mode 100644 .editorconfig create mode 100644 .jscsrc create mode 100644 .jshintrc diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000000..8978b448a6 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,16 @@ +# 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 diff --git a/.jscsrc b/.jscsrc new file mode 100644 index 0000000000..29720b3791 --- /dev/null +++ b/.jscsrc @@ -0,0 +1,130 @@ +{ + "excludeFiles": [ + "node_modules/**" + ], + "fileExtensions": [ + ".js" + ], + "requireCurlyBraces": [ + "if", + "else", + "for", + "while", + "do", + "try", + "catch" + ], + "requireSpaceAfterKeywords": [ + "if", + "else", + "for", + "while", + "do", + "switch", + "return", + "try", + "catch" + ], + "requireSpaceBeforeBlockStatements": true, + "requireParenthesesAroundIIFE": true, + "requireSpacesInConditionalExpression": { + "afterTest": true, + "beforeConsequent": true, + "afterConsequent": true, + "beforeAlternate": true + }, + "requireSpacesInFunctionExpression": { + "beforeOpeningCurlyBrace": true + }, + "disallowSpacesInFunctionExpression": { + "beforeOpeningRoundBrace": true + }, + "disallowMultipleVarDecl": true, + "requireBlocksOnNewline": 1, + "disallowPaddingNewlinesInBlocks": true, + "disallowEmptyBlocks": true, + "disallowSpacesInsideObjectBrackets": true, + "disallowSpacesInsideArrayBrackets": true, + "disallowSpacesInsideParentheses": true, + "disallowQuotedKeysInObjects": "allButReserved", + "disallowSpaceAfterObjectKeys": true, + "requireCommaBeforeLineBreak": true, + "requireOperatorBeforeLineBreak": [ + "?", + "+", + "-", + "/", + "*", + "=", + "==", + "===", + "!=", + "!==", + ">", + ">=", + "<", + "<=" + ], + "disallowSpaceAfterPrefixUnaryOperators": [ + "++", + "--", + "+", + "-", + "~", + "!" + ], + "disallowSpaceBeforePostfixUnaryOperators": [ + "++", + "--" + ], + "requireSpaceBeforeBinaryOperators": [ + "+", + "-", + "/", + "*", + "=", + "==", + "===", + "!=", + "!==" + ], + "requireSpaceAfterBinaryOperators": [ + "+", + "-", + "/", + "*", + "=", + "==", + "===", + "!=", + "!==" + ], + "disallowImplicitTypeConversion": [ + "numeric", + "boolean", + "binary", + "string" + ], + "requireCamelCaseOrUpperCaseIdentifiers": "ignoreProperties", + "disallowKeywords": [ + "with" + ], + "disallowMultipleLineStrings": true, + "validateQuoteMarks": "\"", + "validateIndentation": 2, + "disallowMixedSpacesAndTabs": true, + "disallowTrailingWhitespace": true, + "requireKeywordsOnNewLine": [ + "else" + ], + "requireLineFeedAtFileEnd": true, + "requireCapitalizedConstructors": true, + "safeContextKeyword": "that", + "requireDotNotation": true, + "validateJSDoc": { + "checkParamNames": true, + "checkRedundantParams": true, + "requireParamTypes": true + }, + "requireSpaceAfterLineComment": true +} diff --git a/.jshintrc b/.jshintrc new file mode 100644 index 0000000000..9f268f76ca --- /dev/null +++ b/.jshintrc @@ -0,0 +1,9 @@ +{ + "newcap": false, + "undef": true, + "unused": true, + "asi": true, + "esnext": true, + "node": true, + "browser": true +} diff --git a/index.js b/index.js index 7b1455f55a..ee64463577 100755 --- a/index.js +++ b/index.js @@ -2,35 +2,38 @@ * Module dependencies. */ -var balanced = require('balanced-match') +var balanced = require("balanced-match") /** * Constants. */ -var VAR_PROP_IDENTIFIER = '--' -var VAR_FUNC_IDENTIFIER = 'var' +var VAR_PROP_IDENTIFIER = "--" +var VAR_FUNC_IDENTIFIER = "var" /** * Module export. */ -module.exports = function (options) { - +module.exports = function(options) { return function(style) { options = options || {} var map = {} var preserve = (options.preserve === true ? true : false) // define variables - style.eachRule(function (rule) { + style.eachRule(function(rule) { var varNameIndices = [] - if (rule.type !== 'rule') return + if (rule.type !== "rule") { + return + } // only variables declared for `:root` are supported for now - if (rule.selectors.length !== 1 || rule.selectors[0] !== ":root" || rule.parent.type !== "root") return + if (rule.selectors.length !== 1 || rule.selectors[0] !== ":root" || rule.parent.type !== "root") { + return + } - rule.each(function (decl, i) { + rule.each(function(decl, i) { var prop = decl.prop var value = decl.value @@ -47,17 +50,21 @@ module.exports = function (options) { } // remove empty :root {} - if (rule.decls.length === 0) rule.removeSelf() + if (rule.decls.length === 0) { + rule.removeSelf() + } } }) // resolve variables - style.eachDecl(function (decl, i) { + style.eachDecl(function(decl) { var resolvedValue var value = decl.value - // skip values that don't contain variable functions - if (!value || value.indexOf(VAR_FUNC_IDENTIFIER + '(') === -1) return + // skip values that don’t contain variable functions + if (!value || value.indexOf(VAR_FUNC_IDENTIFIER + "(") === -1) { + return + } resolvedValue = resolveValue(value, map) @@ -89,21 +96,29 @@ module.exports = function (options) { */ function resolveValue(value, map) { - // matches `name[, fallback]`, captures 'name' and 'fallback' + // matches `name[, fallback]`, captures "name" and "fallback" var RE_VAR = /([\w-]+)(?:\s*,\s*)?(.*)?/ - var balancedParens = balanced('(', ')', value) - var varStartIndex = value.indexOf('var(') - var varRef = balanced('(', ')', value.substring(varStartIndex)).body + var balancedParens = balanced("(", ")", value) + var varStartIndex = value.indexOf("var(") + var varRef = balanced("(", ")", value.substring(varStartIndex)).body - if (!balancedParens) throw new SyntaxError('postcss-custom-properties: missing closing ")" in the value "' + value + '"') - if (varRef === '') throw new Error('postcss-custom-properties: var() must contain a non-whitespace string') + if (!balancedParens) { + throw new SyntaxError("postcss-custom-properties: missing closing ')' in the value '" + value + "'") + } + if (varRef === "") { + throw new Error("postcss-custom-properties: var() must contain a non-whitespace string") + } - var varFunc = VAR_FUNC_IDENTIFIER + '(' + varRef + ')' + var varFunc = VAR_FUNC_IDENTIFIER + "(" + varRef + ")" - var varResult = varRef.replace(RE_VAR, function (_, name, fallback) { + var varResult = varRef.replace(RE_VAR, function(_, name, fallback) { var replacement = map[name] - if (!replacement && !fallback) throw new Error('postcss-custom-properties: variable "' + name + '" is undefined') - if (!replacement && fallback) return fallback + if (!replacement && !fallback) { + throw new Error("postcss-custom-properties: variable '" + name + "' is undefined") + } + if (!replacement && fallback) { + return fallback + } return replacement }) diff --git a/package.json b/package.json index 58ca558adb..7df3f3b1db 100755 --- a/package.json +++ b/package.json @@ -26,11 +26,16 @@ "balanced-match": "~0.1.0" }, "devDependencies": { + "jscs": "^1.5.9", + "jshint": "^2.5.2", + "jshint-stylish": "^0.4.0", "postcss": "^2.1.0", "tap-colorize": "^1.2.0", "tape": "^2.13.4" }, "scripts": { - "test": "node test | tap-colorize" + "jscs": "jscs *.js **/*.js", + "jshint": "jshint . --exclude node_modules --reporter node_modules/jshint-stylish/stylish.js", + "test": "npm run jscs && npm run jshint && tape test | tap-colorize" } } diff --git a/test/index.js b/test/index.js index 1d8d223f3e..434924a47e 100755 --- a/test/index.js +++ b/test/index.js @@ -19,61 +19,61 @@ function compareFixtures(t, name, options) { return t.equal(actual, expected, "processed fixture '" + name + "' should be equal to expected output") } -test("throws an error when a variable function is empty", function (t) { - var output = function (t) { +test("throws an error when a variable function is empty", function(t) { + var output = function() { return postcss(customProperties()).process(fixture("substitution-empty")).css } t.throws(output, Error, "postcss-custom-properties: var() must contain a non-whitespace string") t.end() }) -test("throws an error when a variable function is malformed", function (t) { - var output = function (t) { +test("throws an error when a variable function is malformed", function(t) { + var output = function() { return postcss(customProperties()).process(fixture("substitution-malformed")).css } t.throws(output, SyntaxError, "postcss-custom-properties: missing closing \")\" in the value \"var(--t, rgba(0,0,0,0.5)\"") t.end() }) -test("throws an error when a variable function references an undefined variable", function (t) { - var output = function (t) { +test("throws an error when a variable function references an undefined variable", function(t) { + var output = function() { return postcss(customProperties()).process(fixture("substitution-undefined")).css } t.throws(output, Error, "postcss-custom-properties: variable \"--t\" is undefined") t.end() }) -test("substitutes defined variables in `:root` only", function (t) { +test("substitutes defined variables in `:root` only", function(t) { compareFixtures(t, "substitution-defined") t.end() }) -test("removes variable properties from the output", function (t) { +test("removes variable properties from the output", function(t) { compareFixtures(t, "remove-properties") t.end() }) -test("ignores variables defined in a media query", function (t) { +test("ignores variables defined in a media query", function(t) { compareFixtures(t, "media-query") t.end() }) -test("overwrites variables correctly", function (t) { +test("overwrites variables correctly", function(t) { compareFixtures(t, "substitution-overwrite") t.end() }) -test("substitutes undefined variables if there is a fallback", function (t) { +test("substitutes undefined variables if there is a fallback", function(t) { compareFixtures(t, "substitution-fallback") t.end() }) -test("supports case-sensitive variables", function (t) { +test("supports case-sensitive variables", function(t) { compareFixtures(t, "case-sensitive") t.end() }) -test("preserves variables when `preserve` is `true`", function (t) { +test("preserves variables when `preserve` is `true`", function(t) { compareFixtures(t, "preserve-variables", {preserve: true}) t.end() }) From 0193beffe27417c0409c75bd197649dc7ffbd070 Mon Sep 17 00:00:00 2001 From: Maxime Thirouin Date: Wed, 6 Aug 2014 09:17:29 +0200 Subject: [PATCH 007/795] Add _Contributing_ section --- README.md | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/README.md b/README.md index 19dbc36fb7..20b2b9d66f 100755 --- a/README.md +++ b/README.md @@ -39,6 +39,18 @@ Allow you to preserve custom properties & var() usage in output. ```js var out = postcss(customProperties({preserve: true})).process(css).css + +--- + +## Contributing + +Work on a branch, install dev-dependencies, respect coding style & run tests before submitting a bug fix or a feature. + +```bash +git clone https://github.com/postcss/postcss-custom-properties.git +git checkout -b patch-1 +npm install +npm test ``` ## [Changelog](CHANGELOG.md) From 04d121b62b1d786be8578fa90518c49b6f3b9ad9 Mon Sep 17 00:00:00 2001 From: Maxime Thirouin Date: Wed, 6 Aug 2014 09:17:51 +0200 Subject: [PATCH 008/795] Show consistent API in README poke @jonathanong --- README.md | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 20b2b9d66f..578dd48cf6 100755 --- a/README.md +++ b/README.md @@ -28,7 +28,10 @@ var customProperties = require('postcss-custom-properties') var css = fs.readFileSync('build/build.css', 'utf8') // process css using postcss-custom-properties -var out = postcss(customProperties()).process(css).css +var out = postcss() + .use(customProperties()) + .process(css) + .css ``` ### Options @@ -38,7 +41,11 @@ var out = postcss(customProperties()).process(css).css Allow you to preserve custom properties & var() usage in output. ```js -var out = postcss(customProperties({preserve: true})).process(css).css +var out = postcss() + .use(customProperties({preserve: true})) + .process(css) + .css +``` --- From 7c6705ac7b665d5524990d9e133f98dc31f8ad4c Mon Sep 17 00:00:00 2001 From: Maxime Thirouin Date: Wed, 6 Aug 2014 09:32:05 +0200 Subject: [PATCH 009/795] Normalize description --- README.md | 3 +-- package.json | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 578dd48cf6..18b57341dd 100755 --- a/README.md +++ b/README.md @@ -1,7 +1,6 @@ # postcss-custom-properties [![Build Status](https://travis-ci.org/postcss/postcss-custom-properties.png)](https://travis-ci.org/postcss/postcss-custom-properties) -A [PostCSS](https://github.com/postcss/postcss) plugin to polyfill the -[W3C-style CSS Custom Properties for cascading variables](http://www.w3.org/TR/css-variables/). +> [PostCSS](https://github.com/postcss/postcss) plugin to polyfill [W3C CSS Custom Properties for cascading variables](http://www.w3.org/TR/css-variables/). **N.B.** For now the polyfill _is not complete_. It currently just aims to provide a future-proof way of using a _limited subset_ of the features provided by native CSS variables. diff --git a/package.json b/package.json index 7df3f3b1db..72e21f8000 100755 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "postcss-custom-properties", "version": "0.1.0", - "description": "PostCSS that polyfills CSS custom properties for cascading variable module", + "description": "PostCSS plugin to polyfill W3C CSS Custom Properties for cascading variables", "keywords": [ "css", "postcss", From fd3cb5244c28f4f4adebfb4b35c1a19929a6b5e5 Mon Sep 17 00:00:00 2001 From: Maxime Thirouin Date: Mon, 11 Aug 2014 13:28:51 +0200 Subject: [PATCH 010/795] Add map + refactor tests a bit --- CHANGELOG.md | 4 ++++ README.md | 4 ++++ index.js | 2 +- test/index.js | 24 ++++++++---------------- 4 files changed, 17 insertions(+), 17 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 66c120380d..52c77c246a 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,7 @@ +# unreleased + +* Add map option + # 0.1.0 - 2014-08-01 First release based on [rework-vars](https://github.com/reworkcss/rework-vars) v3.1.1 diff --git a/README.md b/README.md index 18b57341dd..ab7bf31db1 100755 --- a/README.md +++ b/README.md @@ -46,6 +46,10 @@ var out = postcss() .css ``` +#### `map` (default: `{}`) + +Allow you to pass an object of variables + --- ## Contributing diff --git a/index.js b/index.js index ee64463577..0ca7710eab 100755 --- a/index.js +++ b/index.js @@ -18,7 +18,7 @@ var VAR_FUNC_IDENTIFIER = "var" module.exports = function(options) { return function(style) { options = options || {} - var map = {} + var map = options.map || {} var preserve = (options.preserve === true ? true : false) // define variables diff --git a/test/index.js b/test/index.js index 434924a47e..91967183c7 100755 --- a/test/index.js +++ b/test/index.js @@ -19,27 +19,19 @@ function compareFixtures(t, name, options) { return t.equal(actual, expected, "processed fixture '" + name + "' should be equal to expected output") } -test("throws an error when a variable function is empty", function(t) { - var output = function() { +test("throw errors", function(t) { + t.throws(function() { return postcss(customProperties()).process(fixture("substitution-empty")).css - } - t.throws(output, Error, "postcss-custom-properties: var() must contain a non-whitespace string") - t.end() -}) + }, Error, "postcss-custom-properties: var() must contain a non-whitespace string", "throws an error when a variable function is empty") -test("throws an error when a variable function is malformed", function(t) { - var output = function() { + t.throws(function() { return postcss(customProperties()).process(fixture("substitution-malformed")).css - } - t.throws(output, SyntaxError, "postcss-custom-properties: missing closing \")\" in the value \"var(--t, rgba(0,0,0,0.5)\"") - t.end() -}) + }, SyntaxError, "postcss-custom-properties: missing closing \")\" in the value \"var(--t, rgba(0,0,0,0.5)\"", "throws an error when a variable function is malformed") -test("throws an error when a variable function references an undefined variable", function(t) { - var output = function() { + t.throws(function() { return postcss(customProperties()).process(fixture("substitution-undefined")).css - } - t.throws(output, Error, "postcss-custom-properties: variable \"--t\" is undefined") + }, Error, "postcss-custom-properties: variable \"--t\" is undefined", "throws an error when a variable function references an undefined variable") + t.end() }) From d880a832c5b4ca31b7aac03eb8f440488d2f2541 Mon Sep 17 00:00:00 2001 From: Maxime Thirouin Date: Tue, 12 Aug 2014 08:02:06 +0200 Subject: [PATCH 011/795] This is not a polyfill --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index ab7bf31db1..9c63040c5d 100755 --- a/README.md +++ b/README.md @@ -1,8 +1,8 @@ # postcss-custom-properties [![Build Status](https://travis-ci.org/postcss/postcss-custom-properties.png)](https://travis-ci.org/postcss/postcss-custom-properties) -> [PostCSS](https://github.com/postcss/postcss) plugin to polyfill [W3C CSS Custom Properties for cascading variables](http://www.w3.org/TR/css-variables/). +> [PostCSS](https://github.com/postcss/postcss) plugin to transform [W3C CSS Custom Properties for cascading variables](http://www.w3.org/TR/css-variables/) to more compatible CSS. -**N.B.** For now the polyfill _is not complete_. It currently just aims to provide a future-proof way of using a _limited subset_ of the features provided by native CSS variables. +**N.B.** For now the transformation _is not complete_. It currently just aims to provide a future-proof way of using a _limited subset_ of the features provided by native CSS variables. _[Checkout opened issue to know the state of this plugin](issues)._ From 9752c738996737b4cfa30b55df99fb8acb215158 Mon Sep 17 00:00:00 2001 From: Maxime Thirouin Date: Tue, 12 Aug 2014 14:47:32 +0200 Subject: [PATCH 012/795] normalize README --- README.md | 46 ++++++++++++++++++++++++++++++++-------------- 1 file changed, 32 insertions(+), 14 deletions(-) diff --git a/README.md b/README.md index 9c63040c5d..e295e26386 100755 --- a/README.md +++ b/README.md @@ -11,28 +11,48 @@ But I look forward to merge those 2 plugins & deprecate this one ([see opened is ## Installation -``` -npm install postcss-custom-properties -``` + $ npm install postcss-custom-properties ## Usage ```js // dependencies -var fs = require('fs') -var postcss = require('postcss') -var customProperties = require('postcss-custom-properties') +var fs = require("fs") +var postcss = require("postcss") +var customProperties = require("postcss-custom-properties") // css to be processed -var css = fs.readFileSync('build/build.css', 'utf8') +var css = fs.readFileSync("input.css", "utf8") // process css using postcss-custom-properties -var out = postcss() +var output = postcss() .use(customProperties()) .process(css) .css ``` +Using this `input.css`: + +```css +:root { + --color: red; +} + +div { + color: var(--color); +} +``` + +you will get: + +```css +div { + color: red; +} +``` + +Checkout [tests](test) for more. + ### Options #### `preserve` (default: `false`) @@ -56,12 +76,10 @@ Allow you to pass an object of variables Work on a branch, install dev-dependencies, respect coding style & run tests before submitting a bug fix or a feature. -```bash -git clone https://github.com/postcss/postcss-custom-properties.git -git checkout -b patch-1 -npm install -npm test -``` + $ git clone https://github.com/postcss/postcss-custom-properties.git + $ git checkout -b patch-1 + $ npm install + $ npm test ## [Changelog](CHANGELOG.md) From aa7cd13509aa3bde294979a837b14be7212f8b80 Mon Sep 17 00:00:00 2001 From: Maxime Thirouin Date: Tue, 12 Aug 2014 14:50:56 +0200 Subject: [PATCH 013/795] First release based on rework-custom-media v0.1.1 --- .editorconfig | 16 ++++ .gitignore | 2 + .jscsrc | 130 +++++++++++++++++++++++++++ .jshintrc | 9 ++ .travis.yml | 1 + CHANGELOG.md | 3 + LICENSE | 20 +++++ README.md | 59 ++++++++++++ index.js | 62 +++++++++++++ package.json | 38 ++++++++ test/fixtures/transform.css | 12 +++ test/fixtures/transform.expected.css | 11 +++ test/fixtures/undefined.css | 5 ++ test/fixtures/undefined.expected.css | 1 + test/index.js | 27 ++++++ 15 files changed, 396 insertions(+) create mode 100644 .editorconfig create mode 100644 .gitignore create mode 100644 .jscsrc create mode 100644 .jshintrc create mode 100644 .travis.yml create mode 100755 CHANGELOG.md create mode 100755 LICENSE create mode 100755 README.md create mode 100755 index.js create mode 100755 package.json create mode 100755 test/fixtures/transform.css create mode 100755 test/fixtures/transform.expected.css create mode 100755 test/fixtures/undefined.css create mode 100755 test/fixtures/undefined.expected.css create mode 100755 test/index.js diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000000..8978b448a6 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,16 @@ +# 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 diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000000..7ab649f420 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +node_modules +test/fixtures/*.actual.css diff --git a/.jscsrc b/.jscsrc new file mode 100644 index 0000000000..29720b3791 --- /dev/null +++ b/.jscsrc @@ -0,0 +1,130 @@ +{ + "excludeFiles": [ + "node_modules/**" + ], + "fileExtensions": [ + ".js" + ], + "requireCurlyBraces": [ + "if", + "else", + "for", + "while", + "do", + "try", + "catch" + ], + "requireSpaceAfterKeywords": [ + "if", + "else", + "for", + "while", + "do", + "switch", + "return", + "try", + "catch" + ], + "requireSpaceBeforeBlockStatements": true, + "requireParenthesesAroundIIFE": true, + "requireSpacesInConditionalExpression": { + "afterTest": true, + "beforeConsequent": true, + "afterConsequent": true, + "beforeAlternate": true + }, + "requireSpacesInFunctionExpression": { + "beforeOpeningCurlyBrace": true + }, + "disallowSpacesInFunctionExpression": { + "beforeOpeningRoundBrace": true + }, + "disallowMultipleVarDecl": true, + "requireBlocksOnNewline": 1, + "disallowPaddingNewlinesInBlocks": true, + "disallowEmptyBlocks": true, + "disallowSpacesInsideObjectBrackets": true, + "disallowSpacesInsideArrayBrackets": true, + "disallowSpacesInsideParentheses": true, + "disallowQuotedKeysInObjects": "allButReserved", + "disallowSpaceAfterObjectKeys": true, + "requireCommaBeforeLineBreak": true, + "requireOperatorBeforeLineBreak": [ + "?", + "+", + "-", + "/", + "*", + "=", + "==", + "===", + "!=", + "!==", + ">", + ">=", + "<", + "<=" + ], + "disallowSpaceAfterPrefixUnaryOperators": [ + "++", + "--", + "+", + "-", + "~", + "!" + ], + "disallowSpaceBeforePostfixUnaryOperators": [ + "++", + "--" + ], + "requireSpaceBeforeBinaryOperators": [ + "+", + "-", + "/", + "*", + "=", + "==", + "===", + "!=", + "!==" + ], + "requireSpaceAfterBinaryOperators": [ + "+", + "-", + "/", + "*", + "=", + "==", + "===", + "!=", + "!==" + ], + "disallowImplicitTypeConversion": [ + "numeric", + "boolean", + "binary", + "string" + ], + "requireCamelCaseOrUpperCaseIdentifiers": "ignoreProperties", + "disallowKeywords": [ + "with" + ], + "disallowMultipleLineStrings": true, + "validateQuoteMarks": "\"", + "validateIndentation": 2, + "disallowMixedSpacesAndTabs": true, + "disallowTrailingWhitespace": true, + "requireKeywordsOnNewLine": [ + "else" + ], + "requireLineFeedAtFileEnd": true, + "requireCapitalizedConstructors": true, + "safeContextKeyword": "that", + "requireDotNotation": true, + "validateJSDoc": { + "checkParamNames": true, + "checkRedundantParams": true, + "requireParamTypes": true + }, + "requireSpaceAfterLineComment": true +} diff --git a/.jshintrc b/.jshintrc new file mode 100644 index 0000000000..9f268f76ca --- /dev/null +++ b/.jshintrc @@ -0,0 +1,9 @@ +{ + "newcap": false, + "undef": true, + "unused": true, + "asi": true, + "esnext": true, + "node": true, + "browser": true +} diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000000..587bd3e031 --- /dev/null +++ b/.travis.yml @@ -0,0 +1 @@ +language: node_js diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100755 index 0000000000..dd8b91edc2 --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,3 @@ +# 1.0.0 - 2014-08-12 + +First release based on [rework-custom-media](https://github.com/reworkcss/rework-custom-media) diff --git a/LICENSE b/LICENSE new file mode 100755 index 0000000000..9abe4f5458 --- /dev/null +++ b/LICENSE @@ -0,0 +1,20 @@ +The MIT License (MIT) + +Copyright (c) 2014 "MoOx" Maxime Thirouin + +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. diff --git a/README.md b/README.md new file mode 100755 index 0000000000..e42ecdc854 --- /dev/null +++ b/README.md @@ -0,0 +1,59 @@ +# postcss-custom-media [![Build Status](https://travis-ci.org/postcss/postcss-custom-media.png)](https://travis-ci.org/postcss/postcss-custom-media) + +> A [PostCSS](https://github.com/postcss/postcss) plugin to transform [W3C CSS Custom Media Queries syntax](http://dev.w3.org/csswg/mediaqueries/#custom-mq) to more compatible CSS. + +## Installation + + $ npm install postcss-custom-media + +## Usage + +```js +// dependencies +var postcss = require("postcss") +var customMedia = require("postcss-custom-media") + +// css to be processed +var css = fs.readFileSync("input.css", "utf8") + +// process css using postcss-custom-media +var out = postcss() + .use(customMedia()) + .process(css) + .css +``` + +Using this `input.css`: + +```css +@custom-media --small-viewport (max-width: 30em); + +@media (--small-viewport) { + /* styles for small viewport */ +} +``` + +you will get: + +```css +@media (max-width: 30em) { + /* styles for small viewport */ +} +``` + +Checkout [tests](test) for more examples. + +--- + +## Contributing + +Work on a branch, install dev-dependencies, respect coding style & run tests before submitting a bug fix or a feature. + + $ git clone https://github.com/postcss/postcss-custom-media.git + $ git checkout -b patch-1 + $ npm install + $ npm test + +## [Changelog](CHANGELOG.md) + +## [License](LICENSE-MIT) diff --git a/index.js b/index.js new file mode 100755 index 0000000000..eb2d4001d2 --- /dev/null +++ b/index.js @@ -0,0 +1,62 @@ +/** +* Constants. +*/ +var EXTENSION_RE = /\((--[\w-]+)\)/ + +/** + * Expose the plugin. + */ +module.exports = customMedia + +/** + * read & replace custom media queries by standard media queries + */ +function customMedia() { + return function(styles) { + var map = {} + var toRemove = [] + + // read custom media queries + styles.eachAtRule(function(rule) { + if (rule.name !== "custom-media") { + return + } + + var params = rule.params.split(" ") + // @custom-media ; + // map[] = + map[params.shift()] = params.join(" ") + + toRemove.push(rule) + }) + + // transform custom media query aliases + styles.eachAtRule(function(rule) { + if (rule.name !== "media") { + return + } + + rule.params = rule.params.replace(EXTENSION_RE, function(_, name) { + if (map[name]) { + return map[name] + } + + console.warn(gnuMessage("missing @custom-media definition for '" + name + "'. The entire rule has been removed from the output.", rule.source)) + toRemove.push(rule) + }) + }) + + // remove @custom-media + toRemove.forEach(function(rule) { rule.removeSelf() }) + } +} + +/** + * return GNU style message + * + * @param {String} message + * @param {Object} source + */ +function gnuMessage(message, source) { + return (source ? (source.file ? source.file : "") + ":" + source.start.line + ":" + source.start.column : "") + " " + message +} diff --git a/package.json b/package.json new file mode 100755 index 0000000000..b5f05f7455 --- /dev/null +++ b/package.json @@ -0,0 +1,38 @@ +{ + "name": "postcss-custom-media", + "version": "0.0.0", + "description": "PostCSS plugin to import CSS files", + "keywords": [ + "css", + "postcss", + "postcss-plugins", + "media queries", + "custom-media" + ], + "author": "MoOx", + "license": "MIT", + "repository": { + "type": "git", + "url": "https://github.com/postcss/postcss-custom-media.git" + }, + "files": [ + "CHANGELOG.md", + "LICENSE", + "README.md", + "index.js" + ], + "dependencies": {}, + "devDependencies": { + "jscs": "^1.5.9", + "jshint": "^2.5.2", + "jshint-stylish": "^0.4.0", + "postcss": "^2.1.2", + "tap-colorize": "^1.2.0", + "tape": "^2.13.4" + }, + "scripts": { + "jscs": "jscs *.js **/*.js", + "jshint": "jshint . --exclude node_modules --reporter node_modules/jshint-stylish/stylish.js", + "test": "npm run jscs && npm run jshint && tape test | tap-colorize" + } +} diff --git a/test/fixtures/transform.css b/test/fixtures/transform.css new file mode 100755 index 0000000000..775cd1ccc0 --- /dev/null +++ b/test/fixtures/transform.css @@ -0,0 +1,12 @@ +@custom-media --viewport-max-s (max-width: 30em); +@custom-media --viewport-min-s (min-width: 30.01em); + +body { color: #000 } + +@media (--viewport-max-s) { + body { font-size: 1rem; } +} + +@media (--viewport-min-s) { + body { font-size: 1.2rem; } +} diff --git a/test/fixtures/transform.expected.css b/test/fixtures/transform.expected.css new file mode 100755 index 0000000000..bacf50c9a5 --- /dev/null +++ b/test/fixtures/transform.expected.css @@ -0,0 +1,11 @@ + + +body { color: #000 } + +@media (max-width: 30em) { + body { font-size: 1rem; } +} + +@media (min-width: 30.01em) { + body { font-size: 1.2rem; } +} diff --git a/test/fixtures/undefined.css b/test/fixtures/undefined.css new file mode 100755 index 0000000000..4c36cd113d --- /dev/null +++ b/test/fixtures/undefined.css @@ -0,0 +1,5 @@ +body { color: #000 } + +@media (--undefined-custom-media) { + body { font-size: 1rem; } +} diff --git a/test/fixtures/undefined.expected.css b/test/fixtures/undefined.expected.css new file mode 100755 index 0000000000..4746c8775a --- /dev/null +++ b/test/fixtures/undefined.expected.css @@ -0,0 +1 @@ +body { color: #000 } diff --git a/test/index.js b/test/index.js new file mode 100755 index 0000000000..49b120ef0f --- /dev/null +++ b/test/index.js @@ -0,0 +1,27 @@ +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.writeFile(filename("fixtures/" + name + ".actual"), actual) + t.equal(actual, expected, msg) +} + +test("@custom-media", function(t) { + compareFixtures(t, "transform", "should transform custom med") + + compareFixtures(t, "undefined", "should remove undefined @media") + + t.end() +}) From 131ec96b31b49df368db74ef995a4db25243c23a Mon Sep 17 00:00:00 2001 From: Maxime Thirouin Date: Tue, 12 Aug 2014 15:34:59 +0200 Subject: [PATCH 014/795] v1.0.0 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index b5f05f7455..1ff9fde813 100755 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "postcss-custom-media", - "version": "0.0.0", + "version": "1.0.0", "description": "PostCSS plugin to import CSS files", "keywords": [ "css", From 743a0939554f5981cd310813b9991a056843f329 Mon Sep 17 00:00:00 2001 From: Maxime Thirouin Date: Wed, 13 Aug 2014 06:41:56 +0200 Subject: [PATCH 015/795] Update short description in README --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index e42ecdc854..a619047f92 100755 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # postcss-custom-media [![Build Status](https://travis-ci.org/postcss/postcss-custom-media.png)](https://travis-ci.org/postcss/postcss-custom-media) -> A [PostCSS](https://github.com/postcss/postcss) plugin to transform [W3C CSS Custom Media Queries syntax](http://dev.w3.org/csswg/mediaqueries/#custom-mq) to more compatible CSS. +> A [PostCSS](https://github.com/postcss/postcss) plugin to transform [W3C CSS Custom Media Queries](http://dev.w3.org/csswg/mediaqueries/#custom-mq) to more compatible CSS. ## Installation From 790105c766cb80cadb1598917adc2af20f0dba95 Mon Sep 17 00:00:00 2001 From: Maxime Thirouin Date: Wed, 13 Aug 2014 08:16:01 +0200 Subject: [PATCH 016/795] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index a619047f92..b196ff632a 100755 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # postcss-custom-media [![Build Status](https://travis-ci.org/postcss/postcss-custom-media.png)](https://travis-ci.org/postcss/postcss-custom-media) -> A [PostCSS](https://github.com/postcss/postcss) plugin to transform [W3C CSS Custom Media Queries](http://dev.w3.org/csswg/mediaqueries/#custom-mq) to more compatible CSS. +> [PostCSS](https://github.com/postcss/postcss) plugin to transform [W3C CSS Custom Media Queries](http://dev.w3.org/csswg/mediaqueries/#custom-mq) to more compatible CSS. ## Installation From fce1706e736c3dae696f74bbd79fde93e98a0928 Mon Sep 17 00:00:00 2001 From: Maxime Thirouin Date: Fri, 22 Aug 2014 06:09:18 +0200 Subject: [PATCH 017/795] Fix license link in README --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index e295e26386..05915fd61f 100755 --- a/README.md +++ b/README.md @@ -83,4 +83,4 @@ Work on a branch, install dev-dependencies, respect coding style & run tests bef ## [Changelog](CHANGELOG.md) -## [License](LICENSE-MIT) +## [License](LICENSE) From 256df27a9994d7ce42875f50b06c36ccd814e6f6 Mon Sep 17 00:00:00 2001 From: Maxime Thirouin Date: Fri, 22 Aug 2014 06:09:31 +0200 Subject: [PATCH 018/795] it's about syntax --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 05915fd61f..f01d40d67c 100755 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # postcss-custom-properties [![Build Status](https://travis-ci.org/postcss/postcss-custom-properties.png)](https://travis-ci.org/postcss/postcss-custom-properties) -> [PostCSS](https://github.com/postcss/postcss) plugin to transform [W3C CSS Custom Properties for cascading variables](http://www.w3.org/TR/css-variables/) to more compatible CSS. +> [PostCSS](https://github.com/postcss/postcss) plugin to transform [W3C CSS Custom Properties for cascading variables](http://www.w3.org/TR/css-variables/) syntax to more compatible CSS. **N.B.** For now the transformation _is not complete_. It currently just aims to provide a future-proof way of using a _limited subset_ of the features provided by native CSS variables. From 34ba6357613a2f06e37ef7a52dabfc7ccbd4e505 Mon Sep 17 00:00:00 2001 From: Maxime Thirouin Date: Fri, 22 Aug 2014 06:13:58 +0200 Subject: [PATCH 019/795] gnu style message --- index.js | 24 ++++++++++++++++++------ test/index.js | 6 +++--- 2 files changed, 21 insertions(+), 9 deletions(-) diff --git a/index.js b/index.js index 0ca7710eab..7bc4f80078 100755 --- a/index.js +++ b/index.js @@ -66,7 +66,7 @@ module.exports = function(options) { return } - resolvedValue = resolveValue(value, map) + resolvedValue = resolveValue(value, map, decl.source) if (!preserve) { decl.value = resolvedValue @@ -92,21 +92,23 @@ module.exports = function(options) { * * @param {String} value A property value known to contain CSS variable functions * @param {Object} map A map of variable names and values + * @param {Object} source source object of the declaration containing the rule * @return {String} A property value with all CSS variables substituted. */ -function resolveValue(value, map) { +function resolveValue(value, map, source) { // matches `name[, fallback]`, captures "name" and "fallback" var RE_VAR = /([\w-]+)(?:\s*,\s*)?(.*)?/ var balancedParens = balanced("(", ")", value) var varStartIndex = value.indexOf("var(") - var varRef = balanced("(", ")", value.substring(varStartIndex)).body if (!balancedParens) { - throw new SyntaxError("postcss-custom-properties: missing closing ')' in the value '" + value + "'") + throw new SyntaxError(gnuMessage("missing closing ')' in the value '" + value + "'", source)) } + + var varRef = balanced("(", ")", value.substring(varStartIndex)).body if (varRef === "") { - throw new Error("postcss-custom-properties: var() must contain a non-whitespace string") + throw new Error(gnuMessage("var() must contain a non-whitespace string", source)) } var varFunc = VAR_FUNC_IDENTIFIER + "(" + varRef + ")" @@ -114,7 +116,7 @@ function resolveValue(value, map) { var varResult = varRef.replace(RE_VAR, function(_, name, fallback) { var replacement = map[name] if (!replacement && !fallback) { - throw new Error("postcss-custom-properties: variable '" + name + "' is undefined") + throw new Error(gnuMessage("variable '" + name + "' is undefined", source)) } if (!replacement && fallback) { return fallback @@ -132,3 +134,13 @@ function resolveValue(value, map) { return value } + +/** + * return GNU style message + * + * @param {String} message + * @param {Object} source + */ +function gnuMessage(message, source) { + return (source ? (source.file ? source.file : "") + ":" + source.start.line + ":" + source.start.column : "") + " " + message +} diff --git a/test/index.js b/test/index.js index 91967183c7..a6c2d8dc3e 100755 --- a/test/index.js +++ b/test/index.js @@ -22,15 +22,15 @@ function compareFixtures(t, name, options) { test("throw errors", function(t) { t.throws(function() { return postcss(customProperties()).process(fixture("substitution-empty")).css - }, Error, "postcss-custom-properties: var() must contain a non-whitespace string", "throws an error when a variable function is empty") + }, /must contain a non-whitespace string/, "throws an error when a variable function is empty") t.throws(function() { return postcss(customProperties()).process(fixture("substitution-malformed")).css - }, SyntaxError, "postcss-custom-properties: missing closing \")\" in the value \"var(--t, rgba(0,0,0,0.5)\"", "throws an error when a variable function is malformed") + }, /missing closing/, "throws an error when a variable function is malformed") t.throws(function() { return postcss(customProperties()).process(fixture("substitution-undefined")).css - }, Error, "postcss-custom-properties: variable \"--t\" is undefined", "throws an error when a variable function references an undefined variable") + }, /is undefined/, "throws an error when a variable function references an undefined variable") t.end() }) From 57762b08f6cde2433b80b0ca142251a23280d622 Mon Sep 17 00:00:00 2001 From: Maxime Thirouin Date: Fri, 22 Aug 2014 06:14:49 +0200 Subject: [PATCH 020/795] Prepare 0.2.0 --- CHANGELOG.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 52c77c246a..a99811d2b8 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,7 @@ -# unreleased +# 0.2.0 - 2014-08-212 * Add map option +* GNU style error message # 0.1.0 - 2014-08-01 From 5f23747fdaddc84dadb6b2ca55a21ad041ad2cbb Mon Sep 17 00:00:00 2001 From: Maxime Thirouin Date: Fri, 22 Aug 2014 06:15:14 +0200 Subject: [PATCH 021/795] v0.2.0 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 72e21f8000..d50902b1df 100755 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "postcss-custom-properties", - "version": "0.1.0", + "version": "0.2.0", "description": "PostCSS plugin to polyfill W3C CSS Custom Properties for cascading variables", "keywords": [ "css", From d1cb117b9a49587e176f69b29c6224e5289d79d7 Mon Sep 17 00:00:00 2001 From: Maxime Thirouin Date: Tue, 26 Aug 2014 07:53:52 +0200 Subject: [PATCH 022/795] fallback now are always added by default + rename map option see why: http://www.w3.org/TR/css-variables/#invalid-variables Close #4 --- CHANGELOG.md | 9 ++- README.md | 2 +- index.js | 77 +++++++++++---------- test/fixtures/substitution-defined.out.css | 1 + test/fixtures/substitution-fallback.css | 2 + test/fixtures/substitution-fallback.out.css | 3 + test/index.js | 10 ++- 7 files changed, 61 insertions(+), 43 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a99811d2b8..941e283b85 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,11 @@ -# 0.2.0 - 2014-08-212 +# 0.3.0 - 2014-08-25 -* Add map option +* fallback now are always added by default ([see why](http://www.w3.org/TR/css-variables/#invalid-variables)) +* `map` option renamed to `variables` + +# 0.2.0 - 2014-08-22 + +* Add `map` option * GNU style error message # 0.1.0 - 2014-08-01 diff --git a/README.md b/README.md index f01d40d67c..2976670a07 100755 --- a/README.md +++ b/README.md @@ -66,7 +66,7 @@ var out = postcss() .css ``` -#### `map` (default: `{}`) +#### `variables` (default: `{}`) Allow you to pass an object of variables diff --git a/index.js b/index.js index 7bc4f80078..e448afe62c 100755 --- a/index.js +++ b/index.js @@ -10,6 +10,7 @@ var balanced = require("balanced-match") var VAR_PROP_IDENTIFIER = "--" var VAR_FUNC_IDENTIFIER = "var" +var RE_VAR = /([\w-]+)(?:\s*,\s*)?(.*)?/ // matches `name[, fallback]`, captures "name" and "fallback" /** * Module export. @@ -18,7 +19,7 @@ var VAR_FUNC_IDENTIFIER = "var" module.exports = function(options) { return function(style) { options = options || {} - var map = options.map || {} + var variables = options.variables || {} var preserve = (options.preserve === true ? true : false) // define variables @@ -38,7 +39,7 @@ module.exports = function(options) { var value = decl.value if (prop && prop.indexOf(VAR_PROP_IDENTIFIER) === 0) { - map[prop] = value + variables[prop] = value varNameIndices.push(i) } }) @@ -58,7 +59,6 @@ module.exports = function(options) { // resolve variables style.eachDecl(function(decl) { - var resolvedValue var value = decl.value // skip values that don’t contain variable functions @@ -66,16 +66,14 @@ module.exports = function(options) { return } - resolvedValue = resolveValue(value, map, decl.source) + resolveValue(value, variables, decl.source).forEach(function(resolvedValue) { + var clone = decl.clone() + clone.value = resolvedValue + decl.parent.insertBefore(decl, clone) + }) if (!preserve) { - decl.value = resolvedValue - } - else { - decl.parent.insertBefore(decl, { - prop: decl.prop, - value: resolvedValue - }) + decl.removeSelf() } }) } @@ -91,48 +89,53 @@ module.exports = function(options) { * var(name[, fallback]) * * @param {String} value A property value known to contain CSS variable functions - * @param {Object} map A map of variable names and values + * @param {Object} variables A map of variable names and values * @param {Object} source source object of the declaration containing the rule * @return {String} A property value with all CSS variables substituted. */ -function resolveValue(value, map, source) { - // matches `name[, fallback]`, captures "name" and "fallback" - var RE_VAR = /([\w-]+)(?:\s*,\s*)?(.*)?/ - var balancedParens = balanced("(", ")", value) - var varStartIndex = value.indexOf("var(") +function resolveValue(value, variables, source) { + var results = [] + + var start = value.indexOf("var(") + if (start === -1) { + return [value] + } + + var matches = balanced("(", ")", value.substring(start)) - if (!balancedParens) { + if (!matches) { throw new SyntaxError(gnuMessage("missing closing ')' in the value '" + value + "'", source)) } - var varRef = balanced("(", ")", value.substring(varStartIndex)).body - if (varRef === "") { + if (matches.body === "") { throw new Error(gnuMessage("var() must contain a non-whitespace string", source)) } - var varFunc = VAR_FUNC_IDENTIFIER + "(" + varRef + ")" - - var varResult = varRef.replace(RE_VAR, function(_, name, fallback) { - var replacement = map[name] + matches.body.replace(RE_VAR, function(_, name, fallback) { + var replacement = variables[name] if (!replacement && !fallback) { - throw new Error(gnuMessage("variable '" + name + "' is undefined", source)) + throw new Error(gnuMessage("variable '" + name + "' is undefined & don't have any fallback", source)) } - if (!replacement && fallback) { - return fallback + if (fallback) { + // resolve the end of the expression before the rest + (matches.post ? resolveValue(matches.post, variables, source) : [""]).forEach(function(afterValue) { + // resolve fallback values + resolveValue(fallback, variables, source).forEach(function(fbValue) { + results.push(value.slice(0, start) + fbValue + afterValue) + }) + }) } - return replacement - }) - // resolve the variable - value = value.split(varFunc).join(varResult) - - // recursively resolve any remaining variables in the value - if (value.indexOf(VAR_FUNC_IDENTIFIER) !== -1) { - value = resolveValue(value, map) - } + if (replacement) { + // resolve the end of the expression + (matches.post ? resolveValue(matches.post, variables, source) : [""]).forEach(function(afterValue) { + results.push(value.slice(0, start) + replacement + afterValue) + }) + } + }) - return value + return results } /** diff --git a/test/fixtures/substitution-defined.out.css b/test/fixtures/substitution-defined.out.css index 5d50ed33bf..b995db56cf 100755 --- a/test/fixtures/substitution-defined.out.css +++ b/test/fixtures/substitution-defined.out.css @@ -16,6 +16,7 @@ div { /* multiple variables */ color: green, blue; /* variable with function in fallback */ + border: 1px solid rgba(0, 0, 0, 0.1); border: green; /* multiple variables within a function */ background: linear-gradient(to top, green, blue); diff --git a/test/fixtures/substitution-fallback.css b/test/fixtures/substitution-fallback.css index 3eba4c4eac..13b4041cf8 100755 --- a/test/fixtures/substitution-fallback.css +++ b/test/fixtures/substitution-fallback.css @@ -19,4 +19,6 @@ div { background: var(--missing, linear-gradient(to top, #000, var(--nested))); /* fallback contains an undefined variable with a fallack */ background: var(--missing, var(--also-missing, green)); + /* fallback for invalid variables http://www.w3.org/TR/css-variables/#invalid-variables */ + font-size: var(--nested, 1rem); } diff --git a/test/fixtures/substitution-fallback.out.css b/test/fixtures/substitution-fallback.out.css index f42ba55c6c..936b6d36e5 100755 --- a/test/fixtures/substitution-fallback.out.css +++ b/test/fixtures/substitution-fallback.out.css @@ -15,4 +15,7 @@ div { background: linear-gradient(to top, #000, green); /* fallback contains an undefined variable with a fallack */ background: green; + /* fallback for invalid variables http://www.w3.org/TR/css-variables/#invalid-variables */ + font-size: 1rem; + font-size: green; } diff --git a/test/index.js b/test/index.js index a6c2d8dc3e..f1ce0767d6 100755 --- a/test/index.js +++ b/test/index.js @@ -5,15 +5,19 @@ var test = require("tape") var postcss = require("postcss") var customProperties = require("..") +function fixturePath(name) { + return "test/fixtures/" + name + ".css" +} + function fixture(name) { - return fs.readFileSync("test/fixtures/" + name + ".css", "utf8").trim() + return fs.readFileSync(fixturePath(name), "utf8").trim() } function compareFixtures(t, name, options) { - var actual = postcss(customProperties(options)).process(fixture(name)).css.trim() + var actual = postcss(customProperties(options)).process(fixture(name), {from: fixturePath(name)}).css.trim() // handy thing: checkout actual in the *.actual.css file - fs.writeFile("test/fixtures/" + name + ".actual.css", actual) + fs.writeFile(fixturePath(name + ".actual"), actual) var expected = fixture(name + ".out") return t.equal(actual, expected, "processed fixture '" + name + "' should be equal to expected output") From 8508fe5f3c5a69ed121af9cbbb45074eb1c7e7b3 Mon Sep 17 00:00:00 2001 From: Maxime Thirouin Date: Tue, 26 Aug 2014 08:08:14 +0200 Subject: [PATCH 023/795] v0.3.0 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index d50902b1df..3d56e8e4ae 100755 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "postcss-custom-properties", - "version": "0.2.0", + "version": "0.3.0", "description": "PostCSS plugin to polyfill W3C CSS Custom Properties for cascading variables", "keywords": [ "css", From 48eebf0dfd5a8d27276c1dae8c38edee536cd73b Mon Sep 17 00:00:00 2001 From: Maxime Thirouin Date: Tue, 26 Aug 2014 08:31:42 +0200 Subject: [PATCH 024/795] Update link to issue & remove ref to postcss-vars (deprecated) https://github.com/iamvdo/postcss-vars/issues/4#issuecomment-52500451 --- README.md | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/README.md b/README.md index 2976670a07..f186c39562 100755 --- a/README.md +++ b/README.md @@ -4,10 +4,7 @@ **N.B.** For now the transformation _is not complete_. It currently just aims to provide a future-proof way of using a _limited subset_ of the features provided by native CSS variables. -_[Checkout opened issue to know the state of this plugin](issues)._ - -Why not `postcss-vars` ? Because [there is already a plugin with this name](http://github.com/iamvdo/postcss-vars) that have severals bugs & untested code. -But I look forward to merge those 2 plugins & deprecate this one ([see opened issue](https://github.com/iamvdo/postcss-vars/issues/4)). +_[Checkout opened issue to know the state of this plugin](https://github.com/postcss/postcss-custom-properties/issues)._ ## Installation From 2690f0f0327802efd20b269d28a50ef0d9286af8 Mon Sep 17 00:00:00 2001 From: Maxime Thirouin Date: Wed, 27 Aug 2014 08:45:13 +0200 Subject: [PATCH 025/795] fix nested custom properties usages Close https://github.com/putaindecode/cssnext/issues/25 --- CHANGELOG.md | 4 ++++ README.md | 2 +- index.js | 16 +++++++++++++++- test/fixtures/substitution-defined.css | 9 ++++++++- test/fixtures/substitution-defined.out.css | 5 +++++ test/fixtures/substitution-fallback.css | 11 +++++++++++ test/fixtures/substitution-fallback.out.css | 12 ++++++++++++ 7 files changed, 56 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 941e283b85..484a71ed8b 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,7 @@ +# 0.3.1 - 2014-08-26 + +* nested custom properties usages are now correctly resolved + # 0.3.0 - 2014-08-25 * fallback now are always added by default ([see why](http://www.w3.org/TR/css-variables/#invalid-variables)) diff --git a/README.md b/README.md index f186c39562..f23298f27c 100755 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ > [PostCSS](https://github.com/postcss/postcss) plugin to transform [W3C CSS Custom Properties for cascading variables](http://www.w3.org/TR/css-variables/) syntax to more compatible CSS. -**N.B.** For now the transformation _is not complete_. It currently just aims to provide a future-proof way of using a _limited subset_ of the features provided by native CSS variables. +**N.B.** For now the transformation _is not complete_. It currently just aims to provide a future-proof way of using a _limited subset (to `:root` selector)_ of the features provided by native CSS custom properties. _[Checkout opened issue to know the state of this plugin](https://github.com/postcss/postcss-custom-properties/issues)._ diff --git a/index.js b/index.js index e448afe62c..48ca71bcdc 100755 --- a/index.js +++ b/index.js @@ -117,6 +117,8 @@ function resolveValue(value, variables, source) { if (!replacement && !fallback) { throw new Error(gnuMessage("variable '" + name + "' is undefined & don't have any fallback", source)) } + + // prepend with fallbacks if (fallback) { // resolve the end of the expression before the rest (matches.post ? resolveValue(matches.post, variables, source) : [""]).forEach(function(afterValue) { @@ -127,10 +129,22 @@ function resolveValue(value, variables, source) { }) } + // replace with computed custom properties if (replacement) { // resolve the end of the expression (matches.post ? resolveValue(matches.post, variables, source) : [""]).forEach(function(afterValue) { - results.push(value.slice(0, start) + replacement + afterValue) + // resolve replacement if it use a custom property + resolveValue(replacement, variables, source).forEach(function(replacementValue) { + results.push(value.slice(0, start) + replacementValue + afterValue) + }) + }) + } + + // nothing, just keep original value + if (!replacement && !fallback) { + // resolve the end of the expression + (matches.post ? resolveValue(matches.post, variables, source) : [""]).forEach(function(afterValue) { + results.push(value.slice(0, start) + value + afterValue) }) } }) diff --git a/test/fixtures/substitution-defined.css b/test/fixtures/substitution-defined.css index 204b3e441f..af44bfa459 100755 --- a/test/fixtures/substitution-defined.css +++ b/test/fixtures/substitution-defined.css @@ -3,7 +3,9 @@ */ :root { - --test-one: green; + --test: green; + --test-one: var(--test); + --test-two: blue; --test-three: yellow; } @@ -15,14 +17,19 @@ span { div { --untouched: red; + /* single variable */ color: var(--test-one); + /* single variable with tail */ color: var(--test-one) !important; + /* multiple variables */ color: var(--test-one), var(--test-two); + /* variable with function in fallback */ border: var(--test-one, 1px solid rgba(0, 0, 0, 0.1)); + /* multiple variables within a function */ background: linear-gradient(to top, var(--test-one), var(--test-two)); } diff --git a/test/fixtures/substitution-defined.out.css b/test/fixtures/substitution-defined.out.css index b995db56cf..d330bfe007 100755 --- a/test/fixtures/substitution-defined.out.css +++ b/test/fixtures/substitution-defined.out.css @@ -9,15 +9,20 @@ span { div { --untouched: red; + /* single variable */ color: green; + /* single variable with tail */ color: green !important; + /* multiple variables */ color: green, blue; + /* variable with function in fallback */ border: 1px solid rgba(0, 0, 0, 0.1); border: green; + /* multiple variables within a function */ background: linear-gradient(to top, green, blue); } diff --git a/test/fixtures/substitution-fallback.css b/test/fixtures/substitution-fallback.css index 13b4041cf8..50cea75fe3 100755 --- a/test/fixtures/substitution-fallback.css +++ b/test/fixtures/substitution-fallback.css @@ -5,20 +5,31 @@ div { /* simple fallback */ color: var(--missing, green); + /* comma-separated fallback */ color: var(--missing, green, blue); + /* fallback is a function */ background: var(--missing, linear-gradient(to top, #000, #111)); + /* fallback contains a function */ background: var(--missing, 1px solid rgba(0, 0, 0, 0.1)); + /* fallback is a function containing a function */ background: var(--missing, linear-gradient(to top, #000, rgba(0, 0, 0, 0.5))); + /* fallback contains a defined variable */ background: var(--missing, var(--nested)); + /* fallback contains a defined variable within a function */ background: var(--missing, linear-gradient(to top, #000, var(--nested))); + /* fallback contains an undefined variable with a fallack */ background: var(--missing, var(--also-missing, green)); + /* fallback for invalid variables http://www.w3.org/TR/css-variables/#invalid-variables */ font-size: var(--nested, 1rem); + + /* fallback contains an defined variable with a fallack */ + font-size: var(--missing, var(--nested, 1rem)); } diff --git a/test/fixtures/substitution-fallback.out.css b/test/fixtures/substitution-fallback.out.css index 936b6d36e5..8f79a3a8f5 100755 --- a/test/fixtures/substitution-fallback.out.css +++ b/test/fixtures/substitution-fallback.out.css @@ -1,21 +1,33 @@ div { /* simple fallback */ color: green; + /* comma-separated fallback */ color: green, blue; + /* fallback is a function */ background: linear-gradient(to top, #000, #111); + /* fallback contains a function */ background: 1px solid rgba(0, 0, 0, 0.1); + /* fallback is a function containing a function */ background: linear-gradient(to top, #000, rgba(0, 0, 0, 0.5)); + /* fallback contains a defined variable */ background: green; + /* fallback contains a defined variable within a function */ background: linear-gradient(to top, #000, green); + /* fallback contains an undefined variable with a fallack */ background: green; + /* fallback for invalid variables http://www.w3.org/TR/css-variables/#invalid-variables */ font-size: 1rem; font-size: green; + + /* fallback contains an defined variable with a fallack */ + font-size: 1rem; + font-size: green; } From 833687a4bc656e38ac09d04938ac2d34a02b71dc Mon Sep 17 00:00:00 2001 From: Maxime Thirouin Date: Wed, 27 Aug 2014 08:46:20 +0200 Subject: [PATCH 026/795] undefined var doesn't throw error anymore... (just a console warning) & are kept as is in the output Close #5 --- CHANGELOG.md | 1 + index.js | 2 +- test/fixtures/substitution-undefined.css | 4 ++++ test/fixtures/substitution-undefined.out.css | 7 +++++++ test/index.js | 7 ++++--- 5 files changed, 17 insertions(+), 4 deletions(-) create mode 100644 test/fixtures/substitution-undefined.out.css diff --git a/CHANGELOG.md b/CHANGELOG.md index 484a71ed8b..58af5fdcc9 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,7 @@ # 0.3.1 - 2014-08-26 * nested custom properties usages are now correctly resolved +* undefined var doesn't throw error anymore (just a console warning) & are kept as is in the output # 0.3.0 - 2014-08-25 diff --git a/index.js b/index.js index 48ca71bcdc..dc2b524d37 100755 --- a/index.js +++ b/index.js @@ -115,7 +115,7 @@ function resolveValue(value, variables, source) { matches.body.replace(RE_VAR, function(_, name, fallback) { var replacement = variables[name] if (!replacement && !fallback) { - throw new Error(gnuMessage("variable '" + name + "' is undefined & don't have any fallback", source)) + console.warn(gnuMessage("variable '" + name + "' is undefined & don't have any fallback", source)) } // prepend with fallbacks diff --git a/test/fixtures/substitution-undefined.css b/test/fixtures/substitution-undefined.css index 09859fd82d..d6af72a5ad 100755 --- a/test/fixtures/substitution-undefined.css +++ b/test/fixtures/substitution-undefined.css @@ -1,3 +1,7 @@ div { color: var(--test); } + +div { + color: var(--test, fallback); +} diff --git a/test/fixtures/substitution-undefined.out.css b/test/fixtures/substitution-undefined.out.css new file mode 100644 index 0000000000..c845cd2578 --- /dev/null +++ b/test/fixtures/substitution-undefined.out.css @@ -0,0 +1,7 @@ +div { + color: var(--test); +} + +div { + color: fallback; +} diff --git a/test/index.js b/test/index.js index f1ce0767d6..65f0e2f161 100755 --- a/test/index.js +++ b/test/index.js @@ -32,10 +32,11 @@ test("throw errors", function(t) { return postcss(customProperties()).process(fixture("substitution-malformed")).css }, /missing closing/, "throws an error when a variable function is malformed") - t.throws(function() { - return postcss(customProperties()).process(fixture("substitution-undefined")).css - }, /is undefined/, "throws an error when a variable function references an undefined variable") + t.end() +}) +test("substitutes nothing when a variable function references an undefined variable", function(t) { + compareFixtures(t, "substitution-undefined") t.end() }) From 0a95a1c41470fd2f159ae1e49599c00f5363ed9b Mon Sep 17 00:00:00 2001 From: Maxime Thirouin Date: Wed, 27 Aug 2014 08:48:11 +0200 Subject: [PATCH 027/795] Add ref to postcss-calc in README Close #3 --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index f23298f27c..c3c3477f5c 100755 --- a/README.md +++ b/README.md @@ -6,6 +6,8 @@ _[Checkout opened issue to know the state of this plugin](https://github.com/postcss/postcss-custom-properties/issues)._ +Works great with [postcss-calc](https://github.com/postcss/postcss-calc). + ## Installation $ npm install postcss-custom-properties From 79ee18c646e16618f855d38b8d93f4b5166185e0 Mon Sep 17 00:00:00 2001 From: Maxime Thirouin Date: Wed, 27 Aug 2014 08:49:30 +0200 Subject: [PATCH 028/795] v0.3.1 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 3d56e8e4ae..f341b9d252 100755 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "postcss-custom-properties", - "version": "0.3.0", + "version": "0.3.1", "description": "PostCSS plugin to polyfill W3C CSS Custom Properties for cascading variables", "keywords": [ "css", From 6a0b3851d4e2abaef96126b813746f27c1cf1b73 Mon Sep 17 00:00:00 2001 From: Maxime Thirouin Date: Wed, 27 Aug 2014 08:58:07 +0200 Subject: [PATCH 029/795] Adjust changelog dates --- CHANGELOG.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 58af5fdcc9..64a7837905 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,9 +1,9 @@ -# 0.3.1 - 2014-08-26 +# 0.3.1 - 2014-08-27 * nested custom properties usages are now correctly resolved * undefined var doesn't throw error anymore (just a console warning) & are kept as is in the output -# 0.3.0 - 2014-08-25 +# 0.3.0 - 2014-08-26 * fallback now are always added by default ([see why](http://www.w3.org/TR/css-variables/#invalid-variables)) * `map` option renamed to `variables` From 7dcc3345b2c55e59b51aaab2697a25af8d7b8547 Mon Sep 17 00:00:00 2001 From: Maxime Thirouin Date: Tue, 16 Sep 2014 06:16:56 +0200 Subject: [PATCH 030/795] Allow whitespace around custom media name Close #2 --- CHANGELOG.md | 7 ++++++- README.md | 4 ++-- index.js | 6 +++--- test/fixtures/transform.css | 12 ++++++++++++ test/fixtures/transform.expected.css | 12 ++++++++++++ test/index.js | 2 +- 6 files changed, 36 insertions(+), 7 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index dd8b91edc2..fcf923ec66 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,8 @@ +# 1.0.1 - 2014-09-16 + +- allow whitespace around custom media name (fix [#2](https://github.com/postcss/postcss-custom-media/issues/2)) + + # 1.0.0 - 2014-08-12 -First release based on [rework-custom-media](https://github.com/reworkcss/rework-custom-media) +First release based on [rework-custom-media](https://github.com/reworkcss/rework-custom-media) v0.1.1 diff --git a/README.md b/README.md index b196ff632a..0f4bfc8167 100755 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # postcss-custom-media [![Build Status](https://travis-ci.org/postcss/postcss-custom-media.png)](https://travis-ci.org/postcss/postcss-custom-media) -> [PostCSS](https://github.com/postcss/postcss) plugin to transform [W3C CSS Custom Media Queries](http://dev.w3.org/csswg/mediaqueries/#custom-mq) to more compatible CSS. +> [PostCSS](https://github.com/postcss/postcss) plugin to transform [W3C CSS Custom Media Queries](http://dev.w3.org/csswg/mediaqueries/#custom-mq) syntax to more compatible CSS. ## Installation @@ -56,4 +56,4 @@ Work on a branch, install dev-dependencies, respect coding style & run tests bef ## [Changelog](CHANGELOG.md) -## [License](LICENSE-MIT) +## [License](LICENSE) diff --git a/index.js b/index.js index eb2d4001d2..d72fac6ced 100755 --- a/index.js +++ b/index.js @@ -1,7 +1,7 @@ /** -* Constants. -*/ -var EXTENSION_RE = /\((--[\w-]+)\)/ + * Constants. + */ +var EXTENSION_RE = /\(\s*(--[\w-]+)\s*\)/ /** * Expose the plugin. diff --git a/test/fixtures/transform.css b/test/fixtures/transform.css index 775cd1ccc0..3e08c4d7f9 100755 --- a/test/fixtures/transform.css +++ b/test/fixtures/transform.css @@ -10,3 +10,15 @@ body { color: #000 } @media (--viewport-min-s) { body { font-size: 1.2rem; } } + +@media (--viewport-min-s ) { + +} + +@media ( --viewport-min-s ) { + +} + +@media ( --viewport-min-s) { + +} diff --git a/test/fixtures/transform.expected.css b/test/fixtures/transform.expected.css index bacf50c9a5..e2dd8a3902 100755 --- a/test/fixtures/transform.expected.css +++ b/test/fixtures/transform.expected.css @@ -9,3 +9,15 @@ body { color: #000 } @media (min-width: 30.01em) { body { font-size: 1.2rem; } } + +@media (min-width: 30.01em) { + +} + +@media (min-width: 30.01em) { + +} + +@media (min-width: 30.01em) { + +} diff --git a/test/index.js b/test/index.js index 49b120ef0f..0a4ece9d4b 100755 --- a/test/index.js +++ b/test/index.js @@ -19,7 +19,7 @@ function compareFixtures(t, name, msg, opts, postcssOpts) { } test("@custom-media", function(t) { - compareFixtures(t, "transform", "should transform custom med") + compareFixtures(t, "transform", "should transform custom media") compareFixtures(t, "undefined", "should remove undefined @media") From bbecd0ca415a2de799e0ce894835b95c5203530c Mon Sep 17 00:00:00 2001 From: Maxime Thirouin Date: Tue, 16 Sep 2014 06:17:50 +0200 Subject: [PATCH 031/795] v1.0.1 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 1ff9fde813..c3bf895254 100755 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "postcss-custom-media", - "version": "1.0.0", + "version": "1.0.1", "description": "PostCSS plugin to import CSS files", "keywords": [ "css", From 9e0cf68110afa78700f6d29a486a076047122664 Mon Sep 17 00:00:00 2001 From: Maxime Thirouin Date: Fri, 26 Sep 2014 10:04:38 +0200 Subject: [PATCH 032/795] MIT license update MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit According to what I understand from the MIT license, the name of the original author in the copyright seems to be the only obligation to respect it correctly. I’m also possibly waiting for a response here http://stackoverflow.com/questions/26033524/licensing-under-mit-a-librar y-ive-rewritten-and-renamed-thats-already-under poke @necolas: Is this ok for you this way ? --- LICENSE | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/LICENSE b/LICENSE index 9abe4f5458..23eb1d3488 100755 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,6 @@ The MIT License (MIT) -Copyright (c) 2014 "MoOx" Maxime Thirouin +Copyright (c) 2014, Maxime Thirouin & Nicolas Gallagher 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 From b0a38ae50ba89f013c370d9752acec178041fbeb Mon Sep 17 00:00:00 2001 From: Maxime Thirouin Date: Fri, 26 Sep 2014 10:07:13 +0200 Subject: [PATCH 033/795] MIT license update Ref https://github.com/postcss/postcss-custom-media/commit/9e0cf68110afa7870 0f6d29a486a076047122664 poke @necolas --- LICENSE | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/LICENSE b/LICENSE index 9abe4f5458..23eb1d3488 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,6 @@ The MIT License (MIT) -Copyright (c) 2014 "MoOx" Maxime Thirouin +Copyright (c) 2014, Maxime Thirouin & Nicolas Gallagher 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 From 63110995bb04d57511d8c824ba97d78185781f70 Mon Sep 17 00:00:00 2001 From: Maxime Thirouin Date: Fri, 26 Sep 2014 17:31:02 +0200 Subject: [PATCH 034/795] MIT license update https://github.com/postcss/postcss-custom-properties/commit/b0a38ae50ba89f013c370d9752acec178041fbeb#commitcomment-7941739 --- LICENSE | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/LICENSE b/LICENSE index 23eb1d3488..c17ea507af 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,6 @@ The MIT License (MIT) -Copyright (c) 2014, Maxime Thirouin & Nicolas Gallagher +Copyright (c) 2014, Maxime Thirouin, Nicolas Gallagher & TJ Holowaychuk 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 From ad1b153549aaafe0f94d62fae6906de375d7ea8b Mon Sep 17 00:00:00 2001 From: Nicolas Gallagher Date: Sat, 27 Sep 2014 12:19:14 -0700 Subject: [PATCH 035/795] Add support for JS-defined Media Queries Fix #3 --- README.md | 6 ++++++ index.js | 9 ++++++++- test/fixtures/js-defined.css | 23 +++++++++++++++++++++++ test/fixtures/js-defined.expected.css | 23 +++++++++++++++++++++++ test/index.js | 7 +++++++ 5 files changed, 67 insertions(+), 1 deletion(-) create mode 100755 test/fixtures/js-defined.css create mode 100755 test/fixtures/js-defined.expected.css diff --git a/README.md b/README.md index 0f4bfc8167..cb3cbb2fb1 100755 --- a/README.md +++ b/README.md @@ -43,6 +43,12 @@ you will get: Checkout [tests](test) for more examples. +### Options + +#### `extensions` (default: `{}`) + +Allows you to pass an object to define the `` for each ``. These definitions will override any that exist in the CSS. + --- ## Contributing diff --git a/index.js b/index.js index d72fac6ced..015428ea46 100755 --- a/index.js +++ b/index.js @@ -11,8 +11,10 @@ module.exports = customMedia /** * read & replace custom media queries by standard media queries */ -function customMedia() { +function customMedia(options) { return function(styles) { + options = options || {} + var extensions = options.extensions || {} var map = {} var toRemove = [] @@ -30,6 +32,11 @@ function customMedia() { toRemove.push(rule) }) + // apply js-defined media queries + Object.keys(extensions).forEach(function(extension) { + map[extension] = extensions[extension] + }) + // transform custom media query aliases styles.eachAtRule(function(rule) { if (rule.name !== "media") { diff --git a/test/fixtures/js-defined.css b/test/fixtures/js-defined.css new file mode 100755 index 0000000000..8fe0815695 --- /dev/null +++ b/test/fixtures/js-defined.css @@ -0,0 +1,23 @@ +@custom-media --viewport-max-s (max-width: 50em); + +body { color: #000 } + +@media (--viewport-max-s) { + body { font-size: 1rem; } +} + +@media (--viewport-min-s) { + body { font-size: 1.2rem; } +} + +@media (--viewport-min-s ) { + +} + +@media ( --viewport-min-s ) { + +} + +@media ( --viewport-min-s) { + +} diff --git a/test/fixtures/js-defined.expected.css b/test/fixtures/js-defined.expected.css new file mode 100755 index 0000000000..e2dd8a3902 --- /dev/null +++ b/test/fixtures/js-defined.expected.css @@ -0,0 +1,23 @@ + + +body { color: #000 } + +@media (max-width: 30em) { + body { font-size: 1rem; } +} + +@media (min-width: 30.01em) { + body { font-size: 1.2rem; } +} + +@media (min-width: 30.01em) { + +} + +@media (min-width: 30.01em) { + +} + +@media (min-width: 30.01em) { + +} diff --git a/test/index.js b/test/index.js index 0a4ece9d4b..6a7f650550 100755 --- a/test/index.js +++ b/test/index.js @@ -23,5 +23,12 @@ test("@custom-media", function(t) { compareFixtures(t, "undefined", "should remove undefined @media") + compareFixtures(t, "js-defined", "should transform custom media and override local extensions", { + extensions: { + "--viewport-max-s": "(max-width: 30em)", + "--viewport-min-s": "(min-width: 30.01em)" + } + }) + t.end() }) From 2304d37b59b9ee430f1abf3c2ce5254e23e9b069 Mon Sep 17 00:00:00 2001 From: Nicolas Gallagher Date: Sun, 28 Sep 2014 11:13:58 -0700 Subject: [PATCH 036/795] JS-defined properties override CSS-defined --- index.js | 18 ++++++++++++------ test/fixtures/js-defined.css | 10 ++++++++++ test/fixtures/js-defined.out.css | 5 +++++ test/index.js | 11 +++++++++++ 4 files changed, 38 insertions(+), 6 deletions(-) create mode 100755 test/fixtures/js-defined.css create mode 100755 test/fixtures/js-defined.out.css diff --git a/index.js b/index.js index dc2b524d37..c3737ac2ba 100755 --- a/index.js +++ b/index.js @@ -21,10 +21,11 @@ module.exports = function(options) { options = options || {} var variables = options.variables || {} var preserve = (options.preserve === true ? true : false) + var map = {} // define variables style.eachRule(function(rule) { - var varNameIndices = [] + var toRemove = [] if (rule.type !== "rule") { return } @@ -39,15 +40,15 @@ module.exports = function(options) { var value = decl.value if (prop && prop.indexOf(VAR_PROP_IDENTIFIER) === 0) { - variables[prop] = value - varNameIndices.push(i) + map[prop] = value + toRemove.push(i) } }) // optionally remove `--*` properties from the rule if (!preserve) { - for (var i = varNameIndices.length - 1; i >= 0; i--) { - rule.decls.splice(varNameIndices[i], 1) + for (var i = toRemove.length - 1; i >= 0; i--) { + rule.decls.splice(toRemove[i], 1) } // remove empty :root {} @@ -57,6 +58,11 @@ module.exports = function(options) { } }) + // apply js-defined custom properties + Object.keys(variables).forEach(function(variable) { + map[variable] = variables[variable] + }) + // resolve variables style.eachDecl(function(decl) { var value = decl.value @@ -66,7 +72,7 @@ module.exports = function(options) { return } - resolveValue(value, variables, decl.source).forEach(function(resolvedValue) { + resolveValue(value, map, decl.source).forEach(function(resolvedValue) { var clone = decl.clone() clone.value = resolvedValue decl.parent.insertBefore(decl, clone) diff --git a/test/fixtures/js-defined.css b/test/fixtures/js-defined.css new file mode 100755 index 0000000000..68c6ec67df --- /dev/null +++ b/test/fixtures/js-defined.css @@ -0,0 +1,10 @@ +:root { + --test-one: local; + --test-two: local; +} + +div { + color: var(--test-one); + color: var(--test-two); + color: var(--test-three); +} diff --git a/test/fixtures/js-defined.out.css b/test/fixtures/js-defined.out.css new file mode 100755 index 0000000000..c4fcd971c6 --- /dev/null +++ b/test/fixtures/js-defined.out.css @@ -0,0 +1,5 @@ +div { + color: js-one; + color: js-two; + color: js-three; +} diff --git a/test/index.js b/test/index.js index 65f0e2f161..2b8497576b 100755 --- a/test/index.js +++ b/test/index.js @@ -45,6 +45,17 @@ test("substitutes defined variables in `:root` only", function(t) { t.end() }) +test("accepts variables defined from JavaScript, and overrides local definitions", function(t) { + compareFixtures(t, "js-defined", { + variables: { + "--test-one": "js-one", + "--test-two": "js-two", + "--test-three": "js-three" + } + }) + t.end() +}) + test("removes variable properties from the output", function(t) { compareFixtures(t, "remove-properties") t.end() From 2a886cb2e9dd9047ca6f31a7fe3dbbb409ed1a27 Mon Sep 17 00:00:00 2001 From: Maxime Thirouin Date: Tue, 30 Sep 2014 06:26:31 +0200 Subject: [PATCH 037/795] prepare 0.4.0 --- CHANGELOG.md | 4 ++++ README.md | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 64a7837905..2ee12091f0 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,7 @@ +# 0.4.0 - 2014-09-30 + +* JS-defined properties override CSS-defined + # 0.3.1 - 2014-08-27 * nested custom properties usages are now correctly resolved diff --git a/README.md b/README.md index c3c3477f5c..4a2b380821 100755 --- a/README.md +++ b/README.md @@ -67,7 +67,7 @@ var out = postcss() #### `variables` (default: `{}`) -Allow you to pass an object of variables +Allow you to pass an object of variables for `:root`. These definitions will override any that exist in the CSS. --- From bf878aec2fa61d385fda1deff39762979d9eadd2 Mon Sep 17 00:00:00 2001 From: Maxime Thirouin Date: Tue, 30 Sep 2014 06:27:02 +0200 Subject: [PATCH 038/795] v0.4.0 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index f341b9d252..7ecdc497c6 100755 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "postcss-custom-properties", - "version": "0.3.1", + "version": "0.4.0", "description": "PostCSS plugin to polyfill W3C CSS Custom Properties for cascading variables", "keywords": [ "css", From 54523695949fa886186f2f50f5955a495e35c26d Mon Sep 17 00:00:00 2001 From: Maxime Thirouin Date: Tue, 30 Sep 2014 06:37:16 +0200 Subject: [PATCH 039/795] prepare 1.1.0 --- CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index fcf923ec66..94c30cdddd 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,7 @@ +# 1.1.0 - 2014-09-30 + +- add support for js-defined media queries (fix [#3](https://github.com/postcss/postcss-custom-media/issues/3)) + # 1.0.1 - 2014-09-16 - allow whitespace around custom media name (fix [#2](https://github.com/postcss/postcss-custom-media/issues/2)) From 42dfbc30fe7929ffcd930c397bed0599da0fe0d9 Mon Sep 17 00:00:00 2001 From: Maxime Thirouin Date: Tue, 30 Sep 2014 06:37:41 +0200 Subject: [PATCH 040/795] v1.1.0 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index c3bf895254..d5e357371d 100755 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "postcss-custom-media", - "version": "1.0.1", + "version": "1.1.0", "description": "PostCSS plugin to import CSS files", "keywords": [ "css", From 6d4fad56272b01b0e98b73163d040c9753068721 Mon Sep 17 00:00:00 2001 From: Maxime Thirouin Date: Wed, 1 Oct 2014 05:52:35 +0200 Subject: [PATCH 041/795] Update README according to #1 & #9 --- README.md | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/README.md b/README.md index 4a2b380821..8a2369314c 100755 --- a/README.md +++ b/README.md @@ -2,9 +2,7 @@ > [PostCSS](https://github.com/postcss/postcss) plugin to transform [W3C CSS Custom Properties for cascading variables](http://www.w3.org/TR/css-variables/) syntax to more compatible CSS. -**N.B.** For now the transformation _is not complete_. It currently just aims to provide a future-proof way of using a _limited subset (to `:root` selector)_ of the features provided by native CSS custom properties. - -_[Checkout opened issue to know the state of this plugin](https://github.com/postcss/postcss-custom-properties/issues)._ +**N.B.** The transformation _is not complete_. It currently just aims to provide a future-proof way of using a **limited subset (to `:root` selector)** of the features provided by native CSS custom properties. Read [#1](https://github.com/postcss/postcss-custom-properties/issues/1) & [#9](https://github.com/postcss/postcss-custom-properties/issues/9) to know why this limitation exists. Works great with [postcss-calc](https://github.com/postcss/postcss-calc). From 9279bca2d356f0a6596dedbcab1d967b440e535e Mon Sep 17 00:00:00 2001 From: Maxime Thirouin Date: Wed, 1 Oct 2014 06:01:28 +0200 Subject: [PATCH 042/795] .expected is more clear than .out --- .../{case-sensitive.out.css => case-sensitive.expected.css} | 0 test/fixtures/{js-defined.out.css => js-defined.expected.css} | 0 test/fixtures/{media-query.out.css => media-query.expected.css} | 0 ...eserve-variables.out.css => preserve-variables.expected.css} | 0 ...remove-properties.out.css => remove-properties.expected.css} | 0 ...tution-defined.out.css => substitution-defined.expected.css} | 0 ...tion-fallback.out.css => substitution-fallback.expected.css} | 0 ...on-overwrite.out.css => substitution-overwrite.expected.css} | 0 ...on-undefined.out.css => substitution-undefined.expected.css} | 0 test/index.js | 2 +- 10 files changed, 1 insertion(+), 1 deletion(-) rename test/fixtures/{case-sensitive.out.css => case-sensitive.expected.css} (100%) rename test/fixtures/{js-defined.out.css => js-defined.expected.css} (100%) rename test/fixtures/{media-query.out.css => media-query.expected.css} (100%) rename test/fixtures/{preserve-variables.out.css => preserve-variables.expected.css} (100%) rename test/fixtures/{remove-properties.out.css => remove-properties.expected.css} (100%) rename test/fixtures/{substitution-defined.out.css => substitution-defined.expected.css} (100%) rename test/fixtures/{substitution-fallback.out.css => substitution-fallback.expected.css} (100%) rename test/fixtures/{substitution-overwrite.out.css => substitution-overwrite.expected.css} (100%) rename test/fixtures/{substitution-undefined.out.css => substitution-undefined.expected.css} (100%) diff --git a/test/fixtures/case-sensitive.out.css b/test/fixtures/case-sensitive.expected.css similarity index 100% rename from test/fixtures/case-sensitive.out.css rename to test/fixtures/case-sensitive.expected.css diff --git a/test/fixtures/js-defined.out.css b/test/fixtures/js-defined.expected.css similarity index 100% rename from test/fixtures/js-defined.out.css rename to test/fixtures/js-defined.expected.css diff --git a/test/fixtures/media-query.out.css b/test/fixtures/media-query.expected.css similarity index 100% rename from test/fixtures/media-query.out.css rename to test/fixtures/media-query.expected.css diff --git a/test/fixtures/preserve-variables.out.css b/test/fixtures/preserve-variables.expected.css similarity index 100% rename from test/fixtures/preserve-variables.out.css rename to test/fixtures/preserve-variables.expected.css diff --git a/test/fixtures/remove-properties.out.css b/test/fixtures/remove-properties.expected.css similarity index 100% rename from test/fixtures/remove-properties.out.css rename to test/fixtures/remove-properties.expected.css diff --git a/test/fixtures/substitution-defined.out.css b/test/fixtures/substitution-defined.expected.css similarity index 100% rename from test/fixtures/substitution-defined.out.css rename to test/fixtures/substitution-defined.expected.css diff --git a/test/fixtures/substitution-fallback.out.css b/test/fixtures/substitution-fallback.expected.css similarity index 100% rename from test/fixtures/substitution-fallback.out.css rename to test/fixtures/substitution-fallback.expected.css diff --git a/test/fixtures/substitution-overwrite.out.css b/test/fixtures/substitution-overwrite.expected.css similarity index 100% rename from test/fixtures/substitution-overwrite.out.css rename to test/fixtures/substitution-overwrite.expected.css diff --git a/test/fixtures/substitution-undefined.out.css b/test/fixtures/substitution-undefined.expected.css similarity index 100% rename from test/fixtures/substitution-undefined.out.css rename to test/fixtures/substitution-undefined.expected.css diff --git a/test/index.js b/test/index.js index 2b8497576b..9f5d949bbb 100755 --- a/test/index.js +++ b/test/index.js @@ -19,7 +19,7 @@ function compareFixtures(t, name, options) { // handy thing: checkout actual in the *.actual.css file fs.writeFile(fixturePath(name + ".actual"), actual) - var expected = fixture(name + ".out") + var expected = fixture(name + ".expected") return t.equal(actual, expected, "processed fixture '" + name + "' should be equal to expected output") } From 8fe998431e956264520f9185d94699680ff5cc55 Mon Sep 17 00:00:00 2001 From: Maxime Thirouin Date: Wed, 1 Oct 2014 07:03:15 +0200 Subject: [PATCH 043/795] Remove redundant parts in fixtures --- test/fixtures/js-defined.css | 8 -------- test/fixtures/js-defined.expected.css | 8 -------- test/fixtures/transform.css | 8 -------- test/fixtures/transform.expected.css | 8 -------- 4 files changed, 32 deletions(-) diff --git a/test/fixtures/js-defined.css b/test/fixtures/js-defined.css index 8fe0815695..46334f5173 100755 --- a/test/fixtures/js-defined.css +++ b/test/fixtures/js-defined.css @@ -13,11 +13,3 @@ body { color: #000 } @media (--viewport-min-s ) { } - -@media ( --viewport-min-s ) { - -} - -@media ( --viewport-min-s) { - -} diff --git a/test/fixtures/js-defined.expected.css b/test/fixtures/js-defined.expected.css index e2dd8a3902..b53bb468d8 100755 --- a/test/fixtures/js-defined.expected.css +++ b/test/fixtures/js-defined.expected.css @@ -13,11 +13,3 @@ body { color: #000 } @media (min-width: 30.01em) { } - -@media (min-width: 30.01em) { - -} - -@media (min-width: 30.01em) { - -} diff --git a/test/fixtures/transform.css b/test/fixtures/transform.css index 3e08c4d7f9..8114b7491f 100755 --- a/test/fixtures/transform.css +++ b/test/fixtures/transform.css @@ -14,11 +14,3 @@ body { color: #000 } @media (--viewport-min-s ) { } - -@media ( --viewport-min-s ) { - -} - -@media ( --viewport-min-s) { - -} diff --git a/test/fixtures/transform.expected.css b/test/fixtures/transform.expected.css index e2dd8a3902..b53bb468d8 100755 --- a/test/fixtures/transform.expected.css +++ b/test/fixtures/transform.expected.css @@ -13,11 +13,3 @@ body { color: #000 } @media (min-width: 30.01em) { } - -@media (min-width: 30.01em) { - -} - -@media (min-width: 30.01em) { - -} From 0c49edd0dc1b050a98a8ff276b1a2c947605a13d Mon Sep 17 00:00:00 2001 From: Maxime Thirouin Date: Wed, 1 Oct 2014 07:08:16 +0200 Subject: [PATCH 044/795] Add support for multiples media in query list Credit to @ooflorent https://github.com/reworkcss/rework-custom-media/pull/5 --- CHANGELOG.md | 8 ++++++-- index.js | 2 +- test/fixtures/transform-all.css | 8 ++++++++ test/fixtures/transform-all.expected.css | 7 +++++++ test/index.js | 2 ++ 5 files changed, 24 insertions(+), 3 deletions(-) create mode 100644 test/fixtures/transform-all.css create mode 100644 test/fixtures/transform-all.expected.css diff --git a/CHANGELOG.md b/CHANGELOG.md index 94c30cdddd..f00c615ab7 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,10 +1,14 @@ +# 1.2.0 - 2014-10-01 + +- Add support for multiples media in query list (ref [#rework-custom-media/5](https://github.com/reworkcss/rework-custom-media/pull/5)) + # 1.1.0 - 2014-09-30 -- add support for js-defined media queries (fix [#3](https://github.com/postcss/postcss-custom-media/issues/3)) +- Add support for js-defined media queries (fix [#3](https://github.com/postcss/postcss-custom-media/issues/3)) # 1.0.1 - 2014-09-16 -- allow whitespace around custom media name (fix [#2](https://github.com/postcss/postcss-custom-media/issues/2)) +- Allow whitespace around custom media name (fix [#2](https://github.com/postcss/postcss-custom-media/issues/2)) # 1.0.0 - 2014-08-12 diff --git a/index.js b/index.js index 015428ea46..a785c9c764 100755 --- a/index.js +++ b/index.js @@ -1,7 +1,7 @@ /** * Constants. */ -var EXTENSION_RE = /\(\s*(--[\w-]+)\s*\)/ +var EXTENSION_RE = /\(\s*(--[\w-]+)\s*\)/g /** * Expose the plugin. diff --git a/test/fixtures/transform-all.css b/test/fixtures/transform-all.css new file mode 100644 index 0000000000..72f8501c55 --- /dev/null +++ b/test/fixtures/transform-all.css @@ -0,0 +1,8 @@ +@custom-media --a (foo: bar); +@custom-media --b (bar: baz); + +@media (--a), (--b) { + selector { + property: value; + } +} diff --git a/test/fixtures/transform-all.expected.css b/test/fixtures/transform-all.expected.css new file mode 100644 index 0000000000..e08678c028 --- /dev/null +++ b/test/fixtures/transform-all.expected.css @@ -0,0 +1,7 @@ + + +@media (foo: bar), (bar: baz) { + selector { + property: value; + } +} diff --git a/test/index.js b/test/index.js index 6a7f650550..a909889f62 100755 --- a/test/index.js +++ b/test/index.js @@ -21,6 +21,8 @@ function compareFixtures(t, name, msg, opts, postcssOpts) { test("@custom-media", function(t) { compareFixtures(t, "transform", "should transform custom media") + compareFixtures(t, "transform-all", "should replaces all extension names") + compareFixtures(t, "undefined", "should remove undefined @media") compareFixtures(t, "js-defined", "should transform custom media and override local extensions", { From eb662898563e89f8897483e26fa9e8f50985b154 Mon Sep 17 00:00:00 2001 From: Maxime Thirouin Date: Wed, 1 Oct 2014 07:08:48 +0200 Subject: [PATCH 045/795] v1.2.0 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index d5e357371d..7eb038eeba 100755 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "postcss-custom-media", - "version": "1.1.0", + "version": "1.2.0", "description": "PostCSS plugin to import CSS files", "keywords": [ "css", From 3e695af54bae9fe00a4ebbb54b0a790fb18d673c Mon Sep 17 00:00:00 2001 From: Maxime Thirouin Date: Sat, 4 Oct 2014 08:05:25 +0200 Subject: [PATCH 046/795] Initial release from postcss-color Ref https://github.com/postcss/postcss-color/issues/4 --- .editorconfig | 16 ++++ .gitignore | 2 + .jscsrc | 130 +++++++++++++++++++++++++++ .jshintrc | 9 ++ .travis.yml | 1 + CHANGELOG.md | 3 + LICENSE | 20 +++++ README.md | 61 +++++++++++++ index.js | 101 +++++++++++++++++++++ package.json | 39 ++++++++ test/fixtures/hex-alpha.css | 8 ++ test/fixtures/hex-alpha.expected.css | 8 ++ test/index.js | 24 +++++ 13 files changed, 422 insertions(+) create mode 100644 .editorconfig create mode 100644 .gitignore create mode 100644 .jscsrc create mode 100644 .jshintrc create mode 100644 .travis.yml create mode 100755 CHANGELOG.md create mode 100755 LICENSE create mode 100755 README.md create mode 100755 index.js create mode 100644 package.json create mode 100644 test/fixtures/hex-alpha.css create mode 100644 test/fixtures/hex-alpha.expected.css create mode 100755 test/index.js diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000000..8978b448a6 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,16 @@ +# 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 diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000000..7ab649f420 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +node_modules +test/fixtures/*.actual.css diff --git a/.jscsrc b/.jscsrc new file mode 100644 index 0000000000..29720b3791 --- /dev/null +++ b/.jscsrc @@ -0,0 +1,130 @@ +{ + "excludeFiles": [ + "node_modules/**" + ], + "fileExtensions": [ + ".js" + ], + "requireCurlyBraces": [ + "if", + "else", + "for", + "while", + "do", + "try", + "catch" + ], + "requireSpaceAfterKeywords": [ + "if", + "else", + "for", + "while", + "do", + "switch", + "return", + "try", + "catch" + ], + "requireSpaceBeforeBlockStatements": true, + "requireParenthesesAroundIIFE": true, + "requireSpacesInConditionalExpression": { + "afterTest": true, + "beforeConsequent": true, + "afterConsequent": true, + "beforeAlternate": true + }, + "requireSpacesInFunctionExpression": { + "beforeOpeningCurlyBrace": true + }, + "disallowSpacesInFunctionExpression": { + "beforeOpeningRoundBrace": true + }, + "disallowMultipleVarDecl": true, + "requireBlocksOnNewline": 1, + "disallowPaddingNewlinesInBlocks": true, + "disallowEmptyBlocks": true, + "disallowSpacesInsideObjectBrackets": true, + "disallowSpacesInsideArrayBrackets": true, + "disallowSpacesInsideParentheses": true, + "disallowQuotedKeysInObjects": "allButReserved", + "disallowSpaceAfterObjectKeys": true, + "requireCommaBeforeLineBreak": true, + "requireOperatorBeforeLineBreak": [ + "?", + "+", + "-", + "/", + "*", + "=", + "==", + "===", + "!=", + "!==", + ">", + ">=", + "<", + "<=" + ], + "disallowSpaceAfterPrefixUnaryOperators": [ + "++", + "--", + "+", + "-", + "~", + "!" + ], + "disallowSpaceBeforePostfixUnaryOperators": [ + "++", + "--" + ], + "requireSpaceBeforeBinaryOperators": [ + "+", + "-", + "/", + "*", + "=", + "==", + "===", + "!=", + "!==" + ], + "requireSpaceAfterBinaryOperators": [ + "+", + "-", + "/", + "*", + "=", + "==", + "===", + "!=", + "!==" + ], + "disallowImplicitTypeConversion": [ + "numeric", + "boolean", + "binary", + "string" + ], + "requireCamelCaseOrUpperCaseIdentifiers": "ignoreProperties", + "disallowKeywords": [ + "with" + ], + "disallowMultipleLineStrings": true, + "validateQuoteMarks": "\"", + "validateIndentation": 2, + "disallowMixedSpacesAndTabs": true, + "disallowTrailingWhitespace": true, + "requireKeywordsOnNewLine": [ + "else" + ], + "requireLineFeedAtFileEnd": true, + "requireCapitalizedConstructors": true, + "safeContextKeyword": "that", + "requireDotNotation": true, + "validateJSDoc": { + "checkParamNames": true, + "checkRedundantParams": true, + "requireParamTypes": true + }, + "requireSpaceAfterLineComment": true +} diff --git a/.jshintrc b/.jshintrc new file mode 100644 index 0000000000..9f268f76ca --- /dev/null +++ b/.jshintrc @@ -0,0 +1,9 @@ +{ + "newcap": false, + "undef": true, + "unused": true, + "asi": true, + "esnext": true, + "node": true, + "browser": true +} diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000000..587bd3e031 --- /dev/null +++ b/.travis.yml @@ -0,0 +1 @@ +language: node_js diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100755 index 0000000000..30946753f7 --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,3 @@ +# 1.0.0 - 2014-10-04 + +Initial release from [postcss-color](https://github.com/postcss/postcss-color) diff --git a/LICENSE b/LICENSE new file mode 100755 index 0000000000..8b39b8f151 --- /dev/null +++ b/LICENSE @@ -0,0 +1,20 @@ +The MIT License (MIT) + +Copyright (c) 2014 Maxime Thirouin + +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. diff --git a/README.md b/README.md new file mode 100755 index 0000000000..4bf62d7ada --- /dev/null +++ b/README.md @@ -0,0 +1,61 @@ +# postcss-color-hex-alpha [![Build Status](https://travis-ci.org/postcss/postcss-color-hex-alpha.png)](https://travis-ci.org/postcss/postcss-color-hex-alpha) + +> [PostCSS](https://github.com/postcss/postcss) plugin to transform [W3C RGBA hexadecimal notations (#RRGGBBAA or #RGBA)](http://dev.w3.org/csswg/css-color/#hex-notation) to more compatible CSS (rgba()). + +## Installation + +```bash +$ npm install postcss-color-hex-alpha +``` + +## Usage + +```js +// dependencies +var fs = require("fs") +var postcss = require("postcss") +var colorHexAlpha = require("postcss-color-hex-alpha") + +// css to be processed +var css = fs.readFileSync("input.css", "utf8") + +// process css +var output = postcss() + .use(colorHexAlpha()) + .process(css) + .css +``` + +Using this `input.css`: + +```css +body { + background: #9d9c +} + +``` + +you will get: + +```css +body { + background: rgba(153, 221, 153, 0.8) +} +``` + +Checkout [tests](test) for more examples. + +--- + +## Contributing + +Work on a branch, install dev-dependencies, respect coding style & run tests before submitting a bug fix or a feature. + + $ git clone https://github.com/postcss/postcss-color-hex-alpha.git + $ git checkout -b patch-1 + $ npm install + $ npm test + +## [Changelog](CHANGELOG.md) + +## [License](LICENSE) diff --git a/index.js b/index.js new file mode 100755 index 0000000000..661f6475cd --- /dev/null +++ b/index.js @@ -0,0 +1,101 @@ +/** + * Module dependencies. + */ +var color = require("color") + +/** + * Constantes + */ +var HEX_ALPHA_RE = /#([0-9a-f]{4}(?:[0-9a-f]{4})?)\b/i +var DECIMAL_PRECISION = 100000 // 5 decimals + +/** + * PostCSS plugin to transform hexa alpha colors + */ +module.exports = function plugin() { + return function(style) { + style.eachDecl(function transformDecl(dec) { + if (!dec.value) { + return + } + + dec.value = transform(dec.value, dec.source) + }) + } +} + +/** + * Transform colors to rgb() or rgba() on a declaration value + * + * @param {String} string + * @return {String} + */ +function transform(string, source) { + // order of transformation is important + + try { + if (string.indexOf("#") > -1) { + string = transformHexAlpha(string, source) + } + } + catch (e) { + throw new Error(gnuMessage(e.message, source)) + } + + return string +} + +/** + * transform RGBA hexadecimal notations (#RRGGBBAA or #RGBA) to rgba(). + * + * @param {String} string declaration value + * @return {String} converted declaration value to rgba() + */ +function transformHexAlpha(string) { + var m = HEX_ALPHA_RE.exec(string) + if (!m) { + return string + } + + var hex = m[1] + + return string.slice(0, m.index) + hexaToRgba(hex) + transformHexAlpha(string.slice(m.index + 1 + hex.length)) +} + +/** + * transform RGBA or RRGGBBAA to rgba() + * + * @param {String} hex RGBA or RRGGBBAA + * @return {String} converted value to rgba() + */ +function hexaToRgba(hex) { + // if (hex.length === 3) { + // hex += "f" + // } + if (hex.length === 4) { + var h0 = hex.charAt(0) + var h1 = hex.charAt(1) + var h2 = hex.charAt(2) + var h3 = hex.charAt(3) + hex = h0 + h0 + h1 + h1 + h2 + h2 + h3 + h3 + } + // if (hex.length === 6) { + // hex += "ff" + // } + var rgb = [] + for (var i = 0, l = hex.length; i < l; i += 2) { + rgb.push(Math.round(parseInt(hex.substr(i, 2), 16) / (i === 6 ? 255 : 1) * DECIMAL_PRECISION) / DECIMAL_PRECISION) + } + + return color({r: rgb[0], g: rgb[1], b: rgb[2], a: rgb[3]}).rgbaString() +} + +/** + * return GNU style message + * + * @param {String} message + * @param {Object} source + */ +function gnuMessage(message, source) { + return (source ? (source.file ? source.file : "") + ":" + source.start.line + ":" + source.start.column : "") + " " + message +} diff --git a/package.json b/package.json new file mode 100644 index 0000000000..07ea15311e --- /dev/null +++ b/package.json @@ -0,0 +1,39 @@ +{ + "name": "postcss-color-hex-alpha", + "version": "0.0.0", + "description": "PostCSS plugin to transform W3C RGBA hexadecimal notations (#RRGGBBAA or #RGBA) to more compatible CSS (rgba())", + "keywords": [ + "css", + "postcss", + "postcss-plugins", + "color", + "colour", + "hexa", + "alpha" + ], + "author": "Maxime Thirouin", + "license": "MIT", + "repository": { + "type": "git", + "url": "https://github.com/postcss/postcss-color-hex-alpha.git" + }, + "files": [ + "CHANGELOG.md", + "LICENSE", + "README.md", + "index.js" + ], + "dependencies": { + "color": "^0.7.1" + }, + "devDependencies": { + "jscs": "^1.6.2", + "jshint": "^2.5.6", + "postcss": "^2.2.5", + "tape": "^3.0.0" + }, + "scripts": { + "lint": "jscs *.js **/*.js && jshint . --exclude-path .gitignore", + "test": "npm run lint && tape test" + } +} diff --git a/test/fixtures/hex-alpha.css b/test/fixtures/hex-alpha.css new file mode 100644 index 0000000000..9d91b22d70 --- /dev/null +++ b/test/fixtures/hex-alpha.css @@ -0,0 +1,8 @@ +body { + color: red; + color: #9d9; + color: #9d9c; + color: #9823f8; + color: #9823f834; + background: #9d9 linear-gradient(#9823f8a9, #9823f834); +} diff --git a/test/fixtures/hex-alpha.expected.css b/test/fixtures/hex-alpha.expected.css new file mode 100644 index 0000000000..068bd971c8 --- /dev/null +++ b/test/fixtures/hex-alpha.expected.css @@ -0,0 +1,8 @@ +body { + color: red; + color: #9d9; + color: rgba(153, 221, 153, 0.8); + color: #9823f8; + color: rgba(152, 35, 248, 0.20392); + background: #9d9 linear-gradient(rgba(152, 35, 248, 0.66275), rgba(152, 35, 248, 0.20392)); +} diff --git a/test/index.js b/test/index.js new file mode 100755 index 0000000000..e60ddbd44f --- /dev/null +++ b/test/index.js @@ -0,0 +1,24 @@ +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.writeFile(filename("fixtures/" + name + ".actual"), actual) + t.equal(actual, expected, msg) +} + +test("hex alpha (#RRGGBBAA or #RGBA)", function(t) { + compareFixtures(t, "hex-alpha", "should transform #RRGGBBAA and #RGBA") + t.end() +}) From 2e0cfc39d59b92d44e0e5b55189642049900f4d1 Mon Sep 17 00:00:00 2001 From: Maxime Thirouin Date: Sat, 4 Oct 2014 08:05:52 +0200 Subject: [PATCH 047/795] v1.0.0 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 07ea15311e..41fcc5d268 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "postcss-color-hex-alpha", - "version": "0.0.0", + "version": "1.0.0", "description": "PostCSS plugin to transform W3C RGBA hexadecimal notations (#RRGGBBAA or #RGBA) to more compatible CSS (rgba())", "keywords": [ "css", From 4316e261c7b5e9a1a7e3cffd6709eed6db8db196 Mon Sep 17 00:00:00 2001 From: Maxime Thirouin Date: Sat, 4 Oct 2014 08:11:18 +0200 Subject: [PATCH 048/795] Initial release from postcss-color Ref https://github.com/postcss/postcss-color/issues/4 --- .editorconfig | 16 ++++ .gitignore | 2 + .jscsrc | 130 +++++++++++++++++++++++++++++++++ .jshintrc | 9 +++ .travis.yml | 1 + CHANGELOG.md | 3 + LICENSE | 20 +++++ README.md | 61 ++++++++++++++++ index.js | 62 ++++++++++++++++ package.json | 40 ++++++++++ test/fixtures/hwb.css | 4 + test/fixtures/hwb.expected.css | 4 + test/index.js | 24 ++++++ 13 files changed, 376 insertions(+) create mode 100644 .editorconfig create mode 100644 .gitignore create mode 100644 .jscsrc create mode 100644 .jshintrc create mode 100644 .travis.yml create mode 100755 CHANGELOG.md create mode 100755 LICENSE create mode 100755 README.md create mode 100755 index.js create mode 100644 package.json create mode 100644 test/fixtures/hwb.css create mode 100644 test/fixtures/hwb.expected.css create mode 100755 test/index.js diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000000..8978b448a6 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,16 @@ +# 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 diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000000..7ab649f420 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +node_modules +test/fixtures/*.actual.css diff --git a/.jscsrc b/.jscsrc new file mode 100644 index 0000000000..29720b3791 --- /dev/null +++ b/.jscsrc @@ -0,0 +1,130 @@ +{ + "excludeFiles": [ + "node_modules/**" + ], + "fileExtensions": [ + ".js" + ], + "requireCurlyBraces": [ + "if", + "else", + "for", + "while", + "do", + "try", + "catch" + ], + "requireSpaceAfterKeywords": [ + "if", + "else", + "for", + "while", + "do", + "switch", + "return", + "try", + "catch" + ], + "requireSpaceBeforeBlockStatements": true, + "requireParenthesesAroundIIFE": true, + "requireSpacesInConditionalExpression": { + "afterTest": true, + "beforeConsequent": true, + "afterConsequent": true, + "beforeAlternate": true + }, + "requireSpacesInFunctionExpression": { + "beforeOpeningCurlyBrace": true + }, + "disallowSpacesInFunctionExpression": { + "beforeOpeningRoundBrace": true + }, + "disallowMultipleVarDecl": true, + "requireBlocksOnNewline": 1, + "disallowPaddingNewlinesInBlocks": true, + "disallowEmptyBlocks": true, + "disallowSpacesInsideObjectBrackets": true, + "disallowSpacesInsideArrayBrackets": true, + "disallowSpacesInsideParentheses": true, + "disallowQuotedKeysInObjects": "allButReserved", + "disallowSpaceAfterObjectKeys": true, + "requireCommaBeforeLineBreak": true, + "requireOperatorBeforeLineBreak": [ + "?", + "+", + "-", + "/", + "*", + "=", + "==", + "===", + "!=", + "!==", + ">", + ">=", + "<", + "<=" + ], + "disallowSpaceAfterPrefixUnaryOperators": [ + "++", + "--", + "+", + "-", + "~", + "!" + ], + "disallowSpaceBeforePostfixUnaryOperators": [ + "++", + "--" + ], + "requireSpaceBeforeBinaryOperators": [ + "+", + "-", + "/", + "*", + "=", + "==", + "===", + "!=", + "!==" + ], + "requireSpaceAfterBinaryOperators": [ + "+", + "-", + "/", + "*", + "=", + "==", + "===", + "!=", + "!==" + ], + "disallowImplicitTypeConversion": [ + "numeric", + "boolean", + "binary", + "string" + ], + "requireCamelCaseOrUpperCaseIdentifiers": "ignoreProperties", + "disallowKeywords": [ + "with" + ], + "disallowMultipleLineStrings": true, + "validateQuoteMarks": "\"", + "validateIndentation": 2, + "disallowMixedSpacesAndTabs": true, + "disallowTrailingWhitespace": true, + "requireKeywordsOnNewLine": [ + "else" + ], + "requireLineFeedAtFileEnd": true, + "requireCapitalizedConstructors": true, + "safeContextKeyword": "that", + "requireDotNotation": true, + "validateJSDoc": { + "checkParamNames": true, + "checkRedundantParams": true, + "requireParamTypes": true + }, + "requireSpaceAfterLineComment": true +} diff --git a/.jshintrc b/.jshintrc new file mode 100644 index 0000000000..9f268f76ca --- /dev/null +++ b/.jshintrc @@ -0,0 +1,9 @@ +{ + "newcap": false, + "undef": true, + "unused": true, + "asi": true, + "esnext": true, + "node": true, + "browser": true +} diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000000..587bd3e031 --- /dev/null +++ b/.travis.yml @@ -0,0 +1 @@ +language: node_js diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100755 index 0000000000..30946753f7 --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,3 @@ +# 1.0.0 - 2014-10-04 + +Initial release from [postcss-color](https://github.com/postcss/postcss-color) diff --git a/LICENSE b/LICENSE new file mode 100755 index 0000000000..8b39b8f151 --- /dev/null +++ b/LICENSE @@ -0,0 +1,20 @@ +The MIT License (MIT) + +Copyright (c) 2014 Maxime Thirouin + +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. diff --git a/README.md b/README.md new file mode 100755 index 0000000000..4e3bd33d61 --- /dev/null +++ b/README.md @@ -0,0 +1,61 @@ +# postcss-color-hwb [![Build Status](https://travis-ci.org/postcss/postcss-color-hwb.png)](https://travis-ci.org/postcss/postcss-color-hwb) + +> [PostCSS](https://github.com/postcss/postcss) plugin to transform [W3C CSS hwb() color](http://dev.w3.org/csswg/css-color/#the-hwb-notation) to more compatible CSS (rgb() (or rgba())). + +## Installation + +```bash +$ npm install postcss-color-hwb +``` + +## Usage + +```js +// dependencies +var fs = require("fs") +var postcss = require("postcss") +var colorHwb = require("postcss-color-hwb") + +// css to be processed +var css = fs.readFileSync("input.css", "utf8") + +// process css +var output = postcss() + .use(colorHwb()) + .process(css) + .css +``` + +Using this `input.css`: + +```css +body { + color: hwb(90, 0%, 0%, 0.5); +} + +``` + +you will get: + +```css +body { + color: rgba(128, 255, 0, 0.5); +} +``` + +Checkout [tests](test) for more examples. + +--- + +## Contributing + +Work on a branch, install dev-dependencies, respect coding style & run tests before submitting a bug fix or a feature. + + $ git clone https://github.com/postcss/postcss-color-hwb.git + $ git checkout -b patch-1 + $ npm install + $ npm test + +## [Changelog](CHANGELOG.md) + +## [License](LICENSE) diff --git a/index.js b/index.js new file mode 100755 index 0000000000..4d71de3226 --- /dev/null +++ b/index.js @@ -0,0 +1,62 @@ +/** + * Module dependencies. + */ +var color = require("color") +var reduceFunctionCall = require("reduce-function-call") + +/** + * PostCSS plugin to transform hwb() to rgb() + */ +module.exports = function plugin() { + return function(style) { + style.eachDecl(function transformDecl(dec) { + if (!dec.value) { + return + } + + dec.value = transform(dec.value, dec.source) + }) + } +} + +/** + * Transform hwb color to rgb() or rgba() + * + * @param {String} string + * @return {String} + */ +function transform(string, source) { + try { + if (string.indexOf("hwb(") > -1) { + string = transformHwb(string, source) + } + } + catch (e) { + throw new Error(gnuMessage(e.message, source)) + } + + return string +} + + +/** + * transform hwb() to rgb() (or rgba()) + * + * @param {String} string declaration value + * @return {String} converted declaration value to rgba() + */ +function transformHwb(string) { + return reduceFunctionCall(string, "hwb", function(body, fn) { + return color(fn + "(" + body + ")").rgbString() + }) +} + +/** + * return GNU style message + * + * @param {String} message + * @param {Object} source + */ +function gnuMessage(message, source) { + return (source ? (source.file ? source.file : "") + ":" + source.start.line + ":" + source.start.column : "") + " " + message +} diff --git a/package.json b/package.json new file mode 100644 index 0000000000..88780769f7 --- /dev/null +++ b/package.json @@ -0,0 +1,40 @@ +{ + "name": "postcss-color-hwb", + "version": "0.0.0", + "description": "PostCSS plugin to transform W3C CSS hwb() color to more compatible CSS (rgb() (or rgba()))", + "keywords": [ + "css", + "postcss", + "postcss-plugins", + "color", + "colour", + "rgb", + "hwb" + ], + "author": "Maxime Thirouin", + "license": "MIT", + "repository": { + "type": "git", + "url": "https://github.com/postcss/postcss-color-hwb.git" + }, + "files": [ + "CHANGELOG.md", + "LICENSE", + "README.md", + "index.js" + ], + "dependencies": { + "color": "^0.7.1", + "reduce-function-call": "^1.0.1" + }, + "devDependencies": { + "jscs": "^1.6.2", + "jshint": "^2.5.6", + "postcss": "^2.2.5", + "tape": "^3.0.0" + }, + "scripts": { + "lint": "jscs *.js **/*.js && jshint . --exclude-path .gitignore", + "test": "npm run lint && tape test" + } +} diff --git a/test/fixtures/hwb.css b/test/fixtures/hwb.css new file mode 100644 index 0000000000..eff18620e7 --- /dev/null +++ b/test/fixtures/hwb.css @@ -0,0 +1,4 @@ +body { + color: hwb(90, 0%, 0%, 0.5); + background: linear-gradient(hwb(190, 50%, 0%), hwb(190, 50%, 10%, .2)); +} diff --git a/test/fixtures/hwb.expected.css b/test/fixtures/hwb.expected.css new file mode 100644 index 0000000000..01427e0cbe --- /dev/null +++ b/test/fixtures/hwb.expected.css @@ -0,0 +1,4 @@ +body { + color: rgba(128, 255, 0, 0.5); + background: linear-gradient(rgb(128, 234, 255), rgba(128, 212, 230, 0.2)); +} diff --git a/test/index.js b/test/index.js new file mode 100755 index 0000000000..dbe273acc3 --- /dev/null +++ b/test/index.js @@ -0,0 +1,24 @@ +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.writeFile(filename("fixtures/" + name + ".actual"), actual) + t.equal(actual, expected, msg) +} + +test("hwb", function(t) { + compareFixtures(t, "hwb", "should transform hwb") + t.end() +}) From c589cfd4de272a20c949f3c93747a90d15c5532a Mon Sep 17 00:00:00 2001 From: Maxime Thirouin Date: Sat, 4 Oct 2014 08:11:52 +0200 Subject: [PATCH 049/795] v1.0.0 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 88780769f7..cfee860775 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "postcss-color-hwb", - "version": "0.0.0", + "version": "1.0.0", "description": "PostCSS plugin to transform W3C CSS hwb() color to more compatible CSS (rgb() (or rgba()))", "keywords": [ "css", From 73ad2b75dda15981326296cc7a75fae330928eb0 Mon Sep 17 00:00:00 2001 From: Maxime Thirouin Date: Sat, 4 Oct 2014 08:18:16 +0200 Subject: [PATCH 050/795] Initial release from postcss-color Close https://github.com/postcss/postcss-color/issues/4 --- .editorconfig | 16 +++ .gitignore | 2 + .jscsrc | 130 +++++++++++++++++++++++ .jshintrc | 9 ++ .travis.yml | 1 + CHANGELOG.md | 3 + LICENSE | 20 ++++ README.md | 61 +++++++++++ index.js | 68 ++++++++++++ package.json | 39 +++++++ test/fixtures/rebeccapurple.css | 4 + test/fixtures/rebeccapurple.expected.css | 4 + test/index.js | 24 +++++ 13 files changed, 381 insertions(+) create mode 100644 .editorconfig create mode 100644 .gitignore create mode 100644 .jscsrc create mode 100644 .jshintrc create mode 100644 .travis.yml create mode 100755 CHANGELOG.md create mode 100755 LICENSE create mode 100755 README.md create mode 100755 index.js create mode 100755 package.json create mode 100644 test/fixtures/rebeccapurple.css create mode 100644 test/fixtures/rebeccapurple.expected.css create mode 100755 test/index.js diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000000..8978b448a6 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,16 @@ +# 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 diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000000..7ab649f420 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +node_modules +test/fixtures/*.actual.css diff --git a/.jscsrc b/.jscsrc new file mode 100644 index 0000000000..29720b3791 --- /dev/null +++ b/.jscsrc @@ -0,0 +1,130 @@ +{ + "excludeFiles": [ + "node_modules/**" + ], + "fileExtensions": [ + ".js" + ], + "requireCurlyBraces": [ + "if", + "else", + "for", + "while", + "do", + "try", + "catch" + ], + "requireSpaceAfterKeywords": [ + "if", + "else", + "for", + "while", + "do", + "switch", + "return", + "try", + "catch" + ], + "requireSpaceBeforeBlockStatements": true, + "requireParenthesesAroundIIFE": true, + "requireSpacesInConditionalExpression": { + "afterTest": true, + "beforeConsequent": true, + "afterConsequent": true, + "beforeAlternate": true + }, + "requireSpacesInFunctionExpression": { + "beforeOpeningCurlyBrace": true + }, + "disallowSpacesInFunctionExpression": { + "beforeOpeningRoundBrace": true + }, + "disallowMultipleVarDecl": true, + "requireBlocksOnNewline": 1, + "disallowPaddingNewlinesInBlocks": true, + "disallowEmptyBlocks": true, + "disallowSpacesInsideObjectBrackets": true, + "disallowSpacesInsideArrayBrackets": true, + "disallowSpacesInsideParentheses": true, + "disallowQuotedKeysInObjects": "allButReserved", + "disallowSpaceAfterObjectKeys": true, + "requireCommaBeforeLineBreak": true, + "requireOperatorBeforeLineBreak": [ + "?", + "+", + "-", + "/", + "*", + "=", + "==", + "===", + "!=", + "!==", + ">", + ">=", + "<", + "<=" + ], + "disallowSpaceAfterPrefixUnaryOperators": [ + "++", + "--", + "+", + "-", + "~", + "!" + ], + "disallowSpaceBeforePostfixUnaryOperators": [ + "++", + "--" + ], + "requireSpaceBeforeBinaryOperators": [ + "+", + "-", + "/", + "*", + "=", + "==", + "===", + "!=", + "!==" + ], + "requireSpaceAfterBinaryOperators": [ + "+", + "-", + "/", + "*", + "=", + "==", + "===", + "!=", + "!==" + ], + "disallowImplicitTypeConversion": [ + "numeric", + "boolean", + "binary", + "string" + ], + "requireCamelCaseOrUpperCaseIdentifiers": "ignoreProperties", + "disallowKeywords": [ + "with" + ], + "disallowMultipleLineStrings": true, + "validateQuoteMarks": "\"", + "validateIndentation": 2, + "disallowMixedSpacesAndTabs": true, + "disallowTrailingWhitespace": true, + "requireKeywordsOnNewLine": [ + "else" + ], + "requireLineFeedAtFileEnd": true, + "requireCapitalizedConstructors": true, + "safeContextKeyword": "that", + "requireDotNotation": true, + "validateJSDoc": { + "checkParamNames": true, + "checkRedundantParams": true, + "requireParamTypes": true + }, + "requireSpaceAfterLineComment": true +} diff --git a/.jshintrc b/.jshintrc new file mode 100644 index 0000000000..9f268f76ca --- /dev/null +++ b/.jshintrc @@ -0,0 +1,9 @@ +{ + "newcap": false, + "undef": true, + "unused": true, + "asi": true, + "esnext": true, + "node": true, + "browser": true +} diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000000..587bd3e031 --- /dev/null +++ b/.travis.yml @@ -0,0 +1 @@ +language: node_js diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100755 index 0000000000..30946753f7 --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,3 @@ +# 1.0.0 - 2014-10-04 + +Initial release from [postcss-color](https://github.com/postcss/postcss-color) diff --git a/LICENSE b/LICENSE new file mode 100755 index 0000000000..8b39b8f151 --- /dev/null +++ b/LICENSE @@ -0,0 +1,20 @@ +The MIT License (MIT) + +Copyright (c) 2014 Maxime Thirouin + +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. diff --git a/README.md b/README.md new file mode 100755 index 0000000000..0f702e96a7 --- /dev/null +++ b/README.md @@ -0,0 +1,61 @@ +# postcss-color-rebeccapurple [![Build Status](https://travis-ci.org/postcss/postcss-color-rebeccapurple.png)](https://travis-ci.org/postcss/postcss-color-rebeccapurple) + +> [PostCSS](https://github.com/postcss/postcss) plugin to transform [W3C CSS `rebeccapurple` color](http://dev.w3.org/csswg/css-color/#valuedef-color-rebeccapurple) to more compatible CSS (rgb()). + +## Installation + +```bash +$ npm install postcss-color-rebeccapurple +``` + +## Usage + +```js +// dependencies +var fs = require("fs") +var postcss = require("postcss") +var colorRebeccapurple = require("postcss-color-rebeccapurple") + +// css to be processed +var css = fs.readFileSync("input.css", "utf8") + +// process css +var output = postcss() + .use(colorRebeccapurple()) + .process(css) + .css +``` + +Using this `input.css`: + +```css +body { + color: rebeccapurple +} + +``` + +you will get: + +```css +body { + color: rgb(102, 51, 153); +} +``` + +Checkout [tests](test) for more examples. + +--- + +## Contributing + +Work on a branch, install dev-dependencies, respect coding style & run tests before submitting a bug fix or a feature. + + $ git clone https://github.com/postcss/postcss-color-rebeccapurple.git + $ git checkout -b patch-1 + $ npm install + $ npm test + +## [Changelog](CHANGELOG.md) + +## [License](LICENSE) diff --git a/index.js b/index.js new file mode 100755 index 0000000000..984bbc6063 --- /dev/null +++ b/index.js @@ -0,0 +1,68 @@ +/** + * Module dependencies. + */ +var color = require("color") + +/** + * PostCSS plugin to convert colors + * + * @param {Object} options + */ +module.exports = function plugin(options) { + options = options || {} + options.rebeccapurple = options.rebeccapurple !== undefined ? options.rebeccapurple : true + options.hwb = options.hwb !== undefined ? options.hwb : true + options.hexAlpha = options.hexAlpha !== undefined ? options.hexAlpha : true + options.color = options.color !== undefined ? options.color : true + + return function(style) { + style.eachDecl(function transformDecl(dec) { + if (!dec.value) { + return + } + + dec.value = transform(dec.value, dec.source, options) + }) + } +} + +/** + * Transform colors to rgb() or rgba() on a declaration value + * + * @param {String} string + * @return {String} + */ +function transform(string, source, options) { + // order of transformation is important + + try { + if (options.rebeccapurple && string.indexOf("rebeccapurple") > -1) { + string = transformRebeccapurple(string, source) + } + } + catch (e) { + throw new Error(gnuMessage(e.message, source)) + } + + return string +} + +/** + * Transform rebeccapurple color to rgb() + * + * @param {String} string declaration value + * @return {String} converted declaration value to rgba() + */ +function transformRebeccapurple(string) { + return string.replace(/(rebeccapurple)\b/gi, color("rebeccapurple").rgbString()) +} + +/** + * return GNU style message + * + * @param {String} message + * @param {Object} source + */ +function gnuMessage(message, source) { + return (source ? (source.file ? source.file : "") + ":" + source.start.line + ":" + source.start.column : "") + " " + message +} diff --git a/package.json b/package.json new file mode 100755 index 0000000000..ce356e1851 --- /dev/null +++ b/package.json @@ -0,0 +1,39 @@ +{ + "name": "postcss-color-rebeccapurple", + "version": "0.0.0", + "description": "PostCSS plugin to transform W3C CSS rebeccapurple color to more compatible CSS (rgb())", + "keywords": [ + "css", + "postcss", + "postcss-plugins", + "color", + "colour", + "rgb", + "rebeccapurple" + ], + "author": "Maxime Thirouin", + "license": "MIT", + "repository": { + "type": "git", + "url": "https://github.com/postcss/postcss-color-rebeccapurple.git" + }, + "files": [ + "CHANGELOG.md", + "LICENSE", + "README.md", + "index.js" + ], + "dependencies": { + "color": "^0.7.1" + }, + "devDependencies": { + "jscs": "^1.6.2", + "jshint": "^2.5.6", + "postcss": "^2.2.5", + "tape": "^3.0.0" + }, + "scripts": { + "lint": "jscs *.js **/*.js && jshint . --exclude-path .gitignore", + "test": "npm run lint && tape test" + } +} diff --git a/test/fixtures/rebeccapurple.css b/test/fixtures/rebeccapurple.css new file mode 100644 index 0000000000..27b88a4b80 --- /dev/null +++ b/test/fixtures/rebeccapurple.css @@ -0,0 +1,4 @@ +body { + color: rebeccapurple; + background: linear-gradient(rebeccapurple, blue 50%, rebeccapurple); +} diff --git a/test/fixtures/rebeccapurple.expected.css b/test/fixtures/rebeccapurple.expected.css new file mode 100644 index 0000000000..00f9305064 --- /dev/null +++ b/test/fixtures/rebeccapurple.expected.css @@ -0,0 +1,4 @@ +body { + color: rgb(102, 51, 153); + background: linear-gradient(rgb(102, 51, 153), blue 50%, rgb(102, 51, 153)); +} diff --git a/test/index.js b/test/index.js new file mode 100755 index 0000000000..650439b713 --- /dev/null +++ b/test/index.js @@ -0,0 +1,24 @@ +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.writeFile(filename("fixtures/" + name + ".actual"), actual) + t.equal(actual, expected, msg) +} + +test("rebeccapurple", function(t) { + compareFixtures(t, "rebeccapurple", "should transform rebeccapurple") + t.end() +}) From 5f024a60befce1db7458172ae006a369327db2d1 Mon Sep 17 00:00:00 2001 From: Maxime Thirouin Date: Sat, 4 Oct 2014 08:18:35 +0200 Subject: [PATCH 051/795] v1.0.0 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index ce356e1851..b6b999adea 100755 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "postcss-color-rebeccapurple", - "version": "0.0.0", + "version": "1.0.0", "description": "PostCSS plugin to transform W3C CSS rebeccapurple color to more compatible CSS (rgb())", "keywords": [ "css", From 4a8a46c51a86817459cd7945a856118ddc6c0dc5 Mon Sep 17 00:00:00 2001 From: Maxime Thirouin Date: Tue, 7 Oct 2014 08:24:41 +0200 Subject: [PATCH 052/795] Close #2 --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index 0f702e96a7..c0471289ac 100755 --- a/README.md +++ b/README.md @@ -2,6 +2,8 @@ > [PostCSS](https://github.com/postcss/postcss) plugin to transform [W3C CSS `rebeccapurple` color](http://dev.w3.org/csswg/css-color/#valuedef-color-rebeccapurple) to more compatible CSS (rgb()). +_[Why this plugin ?](http://meyerweb.com/eric/thoughts/2014/06/19/rebeccapurple/)_ + ## Installation ```bash From f8cae4a457dea16e228b31a74e5141b8b7d3544e Mon Sep 17 00:00:00 2001 From: Maxime Thirouin Date: Wed, 8 Oct 2014 08:03:36 +0200 Subject: [PATCH 053/795] Better "why this plugin" section Ref #2 poke @ai --- README.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index c0471289ac..e9439021e9 100755 --- a/README.md +++ b/README.md @@ -2,7 +2,10 @@ > [PostCSS](https://github.com/postcss/postcss) plugin to transform [W3C CSS `rebeccapurple` color](http://dev.w3.org/csswg/css-color/#valuedef-color-rebeccapurple) to more compatible CSS (rgb()). -_[Why this plugin ?](http://meyerweb.com/eric/thoughts/2014/06/19/rebeccapurple/)_ +## Why this plugin ? + +If you did some CSS, I'm sure you know who [Eric Meyer](https://en.wikipedia.org/wiki/Eric_A._Meyer) is, & what he did for this language. +In memory of [Eric Meyer’s daughter](http://meyerweb.com/eric/thoughts/2014/06/09/in-memoriam-2/), [W3C added new color rebeccapurple to CSS 4 Color Module](http://lists.w3.org/Archives/Public/www-style/2014Jun/0312.html). ## Installation From d169f613545ecda88a8d76cc56e985948f6327c7 Mon Sep 17 00:00:00 2001 From: Maxime Thirouin Date: Thu, 9 Oct 2014 09:47:03 +0200 Subject: [PATCH 054/795] update license format --- LICENSE | 2 +- package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/LICENSE b/LICENSE index c17ea507af..5a95722180 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,6 @@ The MIT License (MIT) -Copyright (c) 2014, Maxime Thirouin, Nicolas Gallagher & TJ Holowaychuk +Copyright (c) 2014 Maxime Thirouin, Nicolas Gallagher & TJ Holowaychuk 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 diff --git a/package.json b/package.json index 7ecdc497c6..1aee428166 100755 --- a/package.json +++ b/package.json @@ -10,7 +10,7 @@ "variables", "vars" ], - "author": "MoOx", + "author": "Maxime Thirouin", "license": "MIT", "repository": { "type": "git", From 62bee9aca9a7383147d8cc2857576170cf4c669b Mon Sep 17 00:00:00 2001 From: Maxime Thirouin Date: Thu, 9 Oct 2014 09:47:19 +0200 Subject: [PATCH 055/795] less dev deps --- package.json | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/package.json b/package.json index 1aee428166..93dc23d220 100755 --- a/package.json +++ b/package.json @@ -26,16 +26,13 @@ "balanced-match": "~0.1.0" }, "devDependencies": { - "jscs": "^1.5.9", - "jshint": "^2.5.2", - "jshint-stylish": "^0.4.0", - "postcss": "^2.1.0", - "tap-colorize": "^1.2.0", - "tape": "^2.13.4" + "jscs": "^1.6.2", + "jshint": "^2.5.6", + "postcss": "^2.2.5", + "tape": "^3.0.0" }, "scripts": { - "jscs": "jscs *.js **/*.js", - "jshint": "jshint . --exclude node_modules --reporter node_modules/jshint-stylish/stylish.js", - "test": "npm run jscs && npm run jshint && tape test | tap-colorize" + "lint": "jscs *.js **/*.js && jshint . --exclude-path .gitignore", + "test": "npm run lint && tape test" } } From a2fbc7a13bfd4043fd80d114892ca97e343faf65 Mon Sep 17 00:00:00 2001 From: Nicolas Gallagher Date: Fri, 24 Oct 2014 16:01:51 -0700 Subject: [PATCH 056/795] Fix grammar of warning message --- index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/index.js b/index.js index c3737ac2ba..1972d4320e 100755 --- a/index.js +++ b/index.js @@ -121,7 +121,7 @@ function resolveValue(value, variables, source) { matches.body.replace(RE_VAR, function(_, name, fallback) { var replacement = variables[name] if (!replacement && !fallback) { - console.warn(gnuMessage("variable '" + name + "' is undefined & don't have any fallback", source)) + console.warn(gnuMessage("variable '" + name + "' is undefined and used without a fallback", source)) } // prepend with fallbacks From 8c9ff4fba43d2cbfeb391cacc49640f03dc5aaf2 Mon Sep 17 00:00:00 2001 From: Shinnosuke Watanabe Date: Wed, 29 Oct 2014 15:58:33 +0900 Subject: [PATCH 057/795] init --- .editorconfig | 12 ++++++++ .eslintrc | 10 +++++++ .gitattributes | 1 + .gitignore | 2 ++ .jscs.json | 4 +++ .travis.yml | 8 +++++ LICENSE | 20 +++++++++++++ README.md | 81 ++++++++++++++++++++++++++++++++++++++++++++++++++ appveyor.yml | 20 +++++++++++++ index.js | 57 +++++++++++++++++++++++++++++++++++ package.json | 50 +++++++++++++++++++++++++++++++ test.js | 63 +++++++++++++++++++++++++++++++++++++++ 12 files changed, 328 insertions(+) create mode 100755 .editorconfig create mode 100755 .eslintrc create mode 100755 .gitattributes create mode 100755 .gitignore create mode 100755 .jscs.json create mode 100755 .travis.yml create mode 100755 LICENSE create mode 100755 README.md create mode 100755 appveyor.yml create mode 100755 index.js create mode 100644 package.json create mode 100755 test.js diff --git a/.editorconfig b/.editorconfig new file mode 100755 index 0000000000..8c52ff9378 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,12 @@ +root = true + +[*] +charset = utf-8 +end_of_line = lf +indent_style = space +indent_size = 2 +insert_final_newline = true +trim_trailing_whitespace = true + +[*.md] +trim_trailing_whitespace = false diff --git a/.eslintrc b/.eslintrc new file mode 100755 index 0000000000..13e5d61f1e --- /dev/null +++ b/.eslintrc @@ -0,0 +1,10 @@ +env: + browser: false + node: true +rules: + no-extra-parens: 2 + eqeqeq: 2 + block-scoped-var: 2 + quotes: + - 2 + - single diff --git a/.gitattributes b/.gitattributes new file mode 100755 index 0000000000..176a458f94 --- /dev/null +++ b/.gitattributes @@ -0,0 +1 @@ +* text=auto diff --git a/.gitignore b/.gitignore new file mode 100755 index 0000000000..62562b74a3 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +coverage +node_modules diff --git a/.jscs.json b/.jscs.json new file mode 100755 index 0000000000..920932259b --- /dev/null +++ b/.jscs.json @@ -0,0 +1,4 @@ +{ + "preset": "google", + "maximumLineLength": 98 +} diff --git a/.travis.yml b/.travis.yml new file mode 100755 index 0000000000..3f62a435e5 --- /dev/null +++ b/.travis.yml @@ -0,0 +1,8 @@ +language: node_js +node_js: + - '0.10' + - '0.11' +notifications: + email: false +after_script: + - npm run-script coveralls diff --git a/LICENSE b/LICENSE new file mode 100755 index 0000000000..81395e4213 --- /dev/null +++ b/LICENSE @@ -0,0 +1,20 @@ +The MIT License (MIT) + +Copyright (c) 2014 Shinnosuke Watanabe + +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. diff --git a/README.md b/README.md new file mode 100755 index 0000000000..21102b4a61 --- /dev/null +++ b/README.md @@ -0,0 +1,81 @@ +# postcss-color-gray + +[![Build Status](https://travis-ci.org/shinnn/postcss-color-gray.svg?branch=master)](https://travis-ci.org/shinnn/postcss-color-gray) +[![Build status](https://ci.appveyor.com/api/projects/status/elxtp9r45rr73cbj?svg=true)](https://ci.appveyor.com/project/ShinnosukeWatanabe/postcss-color-gray) +[![Coverage Status](https://img.shields.io/coveralls/shinnn/postcss-color-gray.svg)](https://coveralls.io/r/shinnn/postcss-color-gray) +[![Dependency Status](https://david-dm.org/shinnn/postcss-color-gray.svg)](https://david-dm.org/shinnn/postcss-color-gray) +[![devDependency Status](https://david-dm.org/shinnn/postcss-color-gray/dev-status.svg)](https://david-dm.org/shinnn/postcss-color-gray#info=devDependencies) + +[PostCSS](https://github.com/postcss/postcss) plugin to transform [gray()](http://dev.w3.org/csswg/css-color/#grays) function to today's CSS + +```css +.foo { + color: gray(0); +} + +.bar { + color: gray(255, 50%); +} + +.baz { + color: gray; +} +``` + +↓ + +```css +.foo { + color: rgb(0, 0, 0); +} + +.bar { + color: rgba(255, 255, 255, 0.5); +} + +.baz { + color: gray; +} +``` + +## Installation + +[![NPM version](https://badge.fury.io/js/postcss-color-gray.svg)](https://www.npmjs.org/package/postcss-color-gray) + +[Use npm](https://www.npmjs.org/doc/cli/npm-install.html). + +``` +npm install postcss-color-gray +``` + +## API + +```javascript +var postcssColorGray = require('postcss-color-gray'); +``` + +### postcssColorGray() + +*options*: `Object` +Return: `Function` + +It converts `gray(A)` to `rgb(A,A,A)`, and converts `gray(A,B)` to `rgba(A,A,A,B)`. + +```javascript +var postcss = require('postcss'); +var colorGray = require('postcss-color-gray'); + +postcss() + .use(colorGray()) + .process('a {color: gray(85); background-color: gray(10%, .25)}') + .css; +//=> 'a {color: rgb(85, 85, 85); background-color: rgba(26, 26, 26, 0.25)}' +``` + +*Note that [gray() may have a keyword argument to specify a color via "luminance"](http://dev.w3.org/csswg/css-color/#issue-658bb235). Current version of this plugin doesn't support this feature.* + +## License + +Copyright (c) 2014 [Shinnosuke Watanabe](https://github.com/shinnn) + +Licensed under [the MIT License](./LICENSE). diff --git a/appveyor.yml b/appveyor.yml new file mode 100755 index 0000000000..eb6da0ec1e --- /dev/null +++ b/appveyor.yml @@ -0,0 +1,20 @@ +init: + - git config --global core.autocrlf input + +version: '{build}' + +environment: + matrix: + - nodejs_version: '0.10' + - nodejs_version: '0.11' + +install: + - ps: Install-Product node $env:nodejs_version + - npm install --production + - npm install postcss tape + +build: off + +test_script: + - ps: node test.js + - cmd: node test.js diff --git a/index.js b/index.js new file mode 100755 index 0000000000..436e66795a --- /dev/null +++ b/index.js @@ -0,0 +1,57 @@ +/*! + * postcss-filter-declarations | MIT (c) Shinnosuke Watanabe + * https://github.com/shinnn/postcss-filter-declarations +*/ + +'use strict'; + +var color = require('color'); +var reduceFunctionCall = require('reduce-function-call'); + +function gnuMessage(message, source) { + var fileName = source.file || ''; + return fileName + ':' + source.start.line + ':' + source.start.column + ' ' + message; +} + +function parseGray(value, source) { + return reduceFunctionCall(value, 'gray', function(argString) { + var args = argString.split(','); + + var rgb = args[0] + ',' + args[0] + ',' + args[0]; + var alpha = args[1]; + if (alpha) { + alpha = alpha.trim(); + var match = alpha.match(/^[1-9](\d|\.)+?%$/); + if (match && match[0] === alpha) { + alpha = parseFloat(alpha) * 0.01; + } + } + + var parsedColor; + + try { + if (alpha === undefined) { + parsedColor = color('rgb' + '(' + rgb + ')'); + } else { + parsedColor = color('rgba' + '(' + rgb + ',' + alpha + ')'); + } + return parsedColor.rgbString(); + + } catch (e) { + e.message = e.message.replace(/rgba?\(.*\)/, 'gray(' + args + ')'); + throw new Error(gnuMessage(e.message, source)); + } + }); +} + +function transformDecl(decl) { + if (decl.value && decl.value.indexOf('gray(') !== -1) { + decl.value = parseGray(decl.value, decl.source); + } +} + +module.exports = function pluginColorGray() { + return function(style) { + style.eachDecl(transformDecl); + }; +}; diff --git a/package.json b/package.json new file mode 100644 index 0000000000..31c239fe2c --- /dev/null +++ b/package.json @@ -0,0 +1,50 @@ +{ + "name": "postcss-color-gray", + "version": "0.0.0", + "description": "PostCSS plugin to transform gray() function to today's CSS", + "repository": "shinnn/postcss-color-gray", + "author": { + "name": "Shinnosuke Watanabe", + "url": "https://github.com/shinnn" + }, + "scripts": { + "pretest": "eslint *.js & jscs *.js", + "test": "node test.js | tap-spec", + "coverage": "istanbul cover test.js", + "coveralls": "${npm_package_scripts_coverage} && istanbul-coveralls" + }, + "licenses": [ + { + "type": "MIT", + "url": "https://github.com/shinnn/postcss-color-gray/blob/master/LICENSE" + } + ], + "files": [ + "index.js", + "LICENSE" + ], + "keywords": [ + "css", + "css4", + "style", + "stylesheet", + "postcss", + "postcss-plugins", + "color", + "gray", + "function" + ], + "dependencies": { + "color": "^0.7.3", + "reduce-function-call": "^1.0.1" + }, + "devDependencies": { + "eslint": "^0.9.1", + "istanbul": "^0.3.2", + "istanbul-coveralls": "^1.0.1", + "jscs": "^1.7.3", + "postcss": "^2.2.5", + "tap-spec": "^1.0.1", + "tape": "^3.0.1" + } +} diff --git a/test.js b/test.js new file mode 100755 index 0000000000..78b8ccb746 --- /dev/null +++ b/test.js @@ -0,0 +1,63 @@ +'use strict'; + +var postcss = require('postcss'); +var colorGray = require('./'); +var test = require('tape'); + +function useGray() { + return postcss().use(colorGray()); +} + +test('filterDeclarations()', function(t) { + t.plan(7); + + t.equal( + useGray().process('a {color: gray(200); background: gray(34%)}').css, + 'a {color: rgb(200, 200, 200); background: rgb(87, 87, 87)}', + 'should convert gray(A) to rgb(A,A,A).' + ); + + t.equal( + useGray().process('a {color: gray( 1, 4.5%)}; b {color: gray(030%,0.75 \t)}').css, + 'a {color: rgba(1, 1, 1, 0.045)}; b {color: rgba(77, 77, 77, 0.75)}', + 'should convert gray(A,B) to rgba(A,A,A,B).' + ); + + t.equal( + useGray().process('a {border-color: gray;}').css, + 'a {border-color: gray;}', + 'should not modify original CSS when gray() is not used.' + ); + + t.throws( + function() { + useGray().process('a {color: gray()}'); + }, + /Unable to parse color from string "gray\(\)"/, + 'should throw an error when gray() doesn\'t take any arguments.' + ); + + t.throws( + function() { + useGray().process('a {color: gray(,foo)}'); + }, + /:1:4 Unable to parse color from string "gray\(,foo\)"/, + 'should throw an error when gray() takes invalid argument.' + ); + + t.throws( + function() { + useGray().process('a {color: gray(red)}', {from: 'fixture.css'}); + }, + /fixture\.css:1:4 Unable to parse color from string "gray\(red\)"/, + 'should throw a detailed error when a source file is specified.' + ); + + t.throws( + function() { + console.log(useGray().process('a {color: gray(,)}', {map: true}).css); + }, + /:1:4 Unable to parse color from string "gray\(,\)"/, + 'should throw a detailed error when source map is enabled but file isn\'t specified.' + ); +}); From 1df0a92938b050801dac0e7d5361f6b56f034eb9 Mon Sep 17 00:00:00 2001 From: Shinnosuke Watanabe Date: Wed, 29 Oct 2014 15:59:28 +0900 Subject: [PATCH 058/795] fix license comment --- index.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/index.js b/index.js index 436e66795a..050bf927fb 100755 --- a/index.js +++ b/index.js @@ -1,6 +1,6 @@ /*! - * postcss-filter-declarations | MIT (c) Shinnosuke Watanabe - * https://github.com/shinnn/postcss-filter-declarations + * postcss-color-gray | MIT (c) Shinnosuke Watanabe + * https://github.com/shinnn/postcss-color-gray */ 'use strict'; From b24ece7e34f9581f8a42261cd163e0c7b648a0c5 Mon Sep 17 00:00:00 2001 From: Shinnosuke Watanabe Date: Wed, 29 Oct 2014 16:42:44 +0900 Subject: [PATCH 059/795] move repository to postcss organization New URL: https://github.com/postcss/postcss-color-gray --- README.md | 10 +++++----- package.json | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 21102b4a61..1962a821e4 100755 --- a/README.md +++ b/README.md @@ -1,10 +1,10 @@ # postcss-color-gray -[![Build Status](https://travis-ci.org/shinnn/postcss-color-gray.svg?branch=master)](https://travis-ci.org/shinnn/postcss-color-gray) -[![Build status](https://ci.appveyor.com/api/projects/status/elxtp9r45rr73cbj?svg=true)](https://ci.appveyor.com/project/ShinnosukeWatanabe/postcss-color-gray) -[![Coverage Status](https://img.shields.io/coveralls/shinnn/postcss-color-gray.svg)](https://coveralls.io/r/shinnn/postcss-color-gray) -[![Dependency Status](https://david-dm.org/shinnn/postcss-color-gray.svg)](https://david-dm.org/shinnn/postcss-color-gray) -[![devDependency Status](https://david-dm.org/shinnn/postcss-color-gray/dev-status.svg)](https://david-dm.org/shinnn/postcss-color-gray#info=devDependencies) +[![Build Status](https://travis-ci.org/postcss/postcss-color-gray.svg?branch=master)](https://travis-ci.org/postcss/postcss-color-gray) +[![Build status](https://ci.appveyor.com/api/projects/status/190t5i4f23r49345?svg=true)](https://ci.appveyor.com/project/ShinnosukeWatanabe/postcss-color-gray) +[![Coverage Status](https://img.shields.io/coveralls/postcss/postcss-color-gray.svg)](https://coveralls.io/r/postcss/postcss-color-gray) +[![Dependency Status](https://david-dm.org/postcss/postcss-color-gray.svg)](https://david-dm.org/postcss/postcss-color-gray) +[![devDependency Status](https://david-dm.org/postcss/postcss-color-gray/dev-status.svg)](https://david-dm.org/postcss/postcss-color-gray#info=devDependencies) [PostCSS](https://github.com/postcss/postcss) plugin to transform [gray()](http://dev.w3.org/csswg/css-color/#grays) function to today's CSS diff --git a/package.json b/package.json index 31c239fe2c..bc947933cc 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "name": "postcss-color-gray", "version": "0.0.0", "description": "PostCSS plugin to transform gray() function to today's CSS", - "repository": "shinnn/postcss-color-gray", + "repository": "postcss/postcss-color-gray", "author": { "name": "Shinnosuke Watanabe", "url": "https://github.com/shinnn" From 3ad6b928c32205de3673acc3c0c545c75941ee5a Mon Sep 17 00:00:00 2001 From: Shinnosuke Watanabe Date: Wed, 29 Oct 2014 16:52:04 +0900 Subject: [PATCH 060/795] release v0.1.0 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index bc947933cc..e461cab04b 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "postcss-color-gray", - "version": "0.0.0", + "version": "0.1.0", "description": "PostCSS plugin to transform gray() function to today's CSS", "repository": "postcss/postcss-color-gray", "author": { From 4e3f758fa07605dcce48747ffbd60f5597172cdb Mon Sep 17 00:00:00 2001 From: Shinnosuke Watanabe Date: Wed, 29 Oct 2014 18:46:11 +0900 Subject: [PATCH 061/795] remove wrong API information --- README.md | 1 - 1 file changed, 1 deletion(-) diff --git a/README.md b/README.md index 1962a821e4..deb936cb62 100755 --- a/README.md +++ b/README.md @@ -56,7 +56,6 @@ var postcssColorGray = require('postcss-color-gray'); ### postcssColorGray() -*options*: `Object` Return: `Function` It converts `gray(A)` to `rgb(A,A,A)`, and converts `gray(A,B)` to `rgba(A,A,A,B)`. From 7854627fc55387b7bb6d635819c2b71d58aa307c Mon Sep 17 00:00:00 2001 From: shinnn Date: Sat, 1 Nov 2014 17:16:14 +0900 Subject: [PATCH 062/795] Accept percentage values beginning with `0` --- index.js | 2 +- test.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/index.js b/index.js index 050bf927fb..6290242b61 100755 --- a/index.js +++ b/index.js @@ -21,7 +21,7 @@ function parseGray(value, source) { var alpha = args[1]; if (alpha) { alpha = alpha.trim(); - var match = alpha.match(/^[1-9](\d|\.)+?%$/); + var match = alpha.match(/^[0-9](\d|\.)+?%$/); if (match && match[0] === alpha) { alpha = parseFloat(alpha) * 0.01; } diff --git a/test.js b/test.js index 78b8ccb746..cccaae9449 100755 --- a/test.js +++ b/test.js @@ -12,7 +12,7 @@ test('filterDeclarations()', function(t) { t.plan(7); t.equal( - useGray().process('a {color: gray(200); background: gray(34%)}').css, + useGray().process('a {color: gray(200); background: gray(00000034%)}').css, 'a {color: rgb(200, 200, 200); background: rgb(87, 87, 87)}', 'should convert gray(A) to rgb(A,A,A).' ); From 975dd4286c4a2df9a0da87d5aaffd5a4eece799f Mon Sep 17 00:00:00 2001 From: shinnn Date: Sat, 1 Nov 2014 17:16:29 +0900 Subject: [PATCH 063/795] fix URLs --- index.js | 2 +- package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/index.js b/index.js index 6290242b61..4135e6e3f2 100755 --- a/index.js +++ b/index.js @@ -1,6 +1,6 @@ /*! * postcss-color-gray | MIT (c) Shinnosuke Watanabe - * https://github.com/shinnn/postcss-color-gray + * https://github.com/postcss/postcss-color-gray */ 'use strict'; diff --git a/package.json b/package.json index e461cab04b..3975cedf3c 100644 --- a/package.json +++ b/package.json @@ -16,7 +16,7 @@ "licenses": [ { "type": "MIT", - "url": "https://github.com/shinnn/postcss-color-gray/blob/master/LICENSE" + "url": "https://github.com/postcss/postcss-color-gray/blob/master/LICENSE" } ], "files": [ From a595284cdd03ea176adc8cf468c4b259fe7cdaa8 Mon Sep 17 00:00:00 2001 From: shinnn Date: Sat, 1 Nov 2014 17:18:50 +0900 Subject: [PATCH 064/795] tweak readme --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index deb936cb62..d6a7152711 100755 --- a/README.md +++ b/README.md @@ -71,7 +71,7 @@ postcss() //=> 'a {color: rgb(85, 85, 85); background-color: rgba(26, 26, 26, 0.25)}' ``` -*Note that [gray() may have a keyword argument to specify a color via "luminance"](http://dev.w3.org/csswg/css-color/#issue-658bb235). Current version of this plugin doesn't support this feature.* +*Note that [gray() may have a keyword argument to specify a color via "luminance"](http://dev.w3.org/csswg/css-color/#issue-658bb235). Current version of postcss-color-gray doesn't support this feature.* ## License From 5044fed5db17900e0499e6e10ac0f9c8b3fdec86 Mon Sep 17 00:00:00 2001 From: shinnn Date: Sat, 1 Nov 2014 17:44:56 +0900 Subject: [PATCH 065/795] release v1.0.0 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 3975cedf3c..e922407717 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "postcss-color-gray", - "version": "0.1.0", + "version": "1.0.0", "description": "PostCSS plugin to transform gray() function to today's CSS", "repository": "postcss/postcss-color-gray", "author": { From d39303bbd75ed961662a764f7a086cbe1f3f49a9 Mon Sep 17 00:00:00 2001 From: Maxime Thirouin Date: Sun, 2 Nov 2014 07:27:29 +0100 Subject: [PATCH 066/795] Add warning when a custom prop is used in another place that :root Close #13 --- CHANGELOG.md | 18 +++++++++++------- index.js | 3 ++- 2 files changed, 13 insertions(+), 8 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2ee12091f0..0d3fd5493f 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,21 +1,25 @@ +# unreleased + +- Add warning when a custom prop is used in another place that :root + # 0.4.0 - 2014-09-30 -* JS-defined properties override CSS-defined +- JS-defined properties override CSS-defined # 0.3.1 - 2014-08-27 -* nested custom properties usages are now correctly resolved -* undefined var doesn't throw error anymore (just a console warning) & are kept as is in the output +- Nested custom properties usages are now correctly resolved +- Undefined var doesn't throw error anymore (just a console warning) & are kept as is in the output # 0.3.0 - 2014-08-26 -* fallback now are always added by default ([see why](http://www.w3.org/TR/css-variables/#invalid-variables)) -* `map` option renamed to `variables` +- Fallback now are always added by default ([see why](http://www.w3.org/TR/css-variables/#invalid-variables)) +- `map` option renamed to `variables` # 0.2.0 - 2014-08-22 -* Add `map` option -* GNU style error message +- Add `map` option +- GNU style error message # 0.1.0 - 2014-08-01 diff --git a/index.js b/index.js index 1972d4320e..4eba302ff8 100755 --- a/index.js +++ b/index.js @@ -32,6 +32,7 @@ module.exports = function(options) { // only variables declared for `:root` are supported for now if (rule.selectors.length !== 1 || rule.selectors[0] !== ":root" || rule.parent.type !== "root") { + console.warn(gnuMessage("Non :root only custom properties in non root level are not supported (" + rule.selectors + ")")) return } @@ -165,5 +166,5 @@ function resolveValue(value, variables, source) { * @param {Object} source */ function gnuMessage(message, source) { - return (source ? (source.file ? source.file : "") + ":" + source.start.line + ":" + source.start.column : "") + " " + message + return (source ? (source.file ? source.file : "") + ":" + source.start.line + ":" + source.start.column + " " : "") + message } From b4935663fa924a32473c5103a14a831ad0ba36a3 Mon Sep 17 00:00:00 2001 From: Maxime Thirouin Date: Sun, 2 Nov 2014 07:47:21 +0100 Subject: [PATCH 067/795] handle !important Close #12 --- CHANGELOG.md | 3 ++- index.js | 8 +++++--- test/fixtures/important.css | 16 ++++++++++++++++ test/fixtures/important.expected.css | 5 +++++ test/index.js | 5 +++++ 5 files changed, 33 insertions(+), 4 deletions(-) create mode 100644 test/fixtures/important.css create mode 100644 test/fixtures/important.expected.css diff --git a/CHANGELOG.md b/CHANGELOG.md index 0d3fd5493f..40dbd4aa52 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,7 @@ -# unreleased +# 1.0.0 - 2014-11-02 - Add warning when a custom prop is used in another place that :root +- handle !important # 0.4.0 - 2014-09-30 diff --git a/index.js b/index.js index 4eba302ff8..65b837bdfa 100755 --- a/index.js +++ b/index.js @@ -22,6 +22,7 @@ module.exports = function(options) { var variables = options.variables || {} var preserve = (options.preserve === true ? true : false) var map = {} + var importantMap = {} // define variables style.eachRule(function(rule) { @@ -38,10 +39,11 @@ module.exports = function(options) { rule.each(function(decl, i) { var prop = decl.prop - var value = decl.value - if (prop && prop.indexOf(VAR_PROP_IDENTIFIER) === 0) { - map[prop] = value + if (!map[prop] || !importantMap[prop] || decl.important) { + map[prop] = decl.value + importantMap[prop] = decl.important + } toRemove.push(i) } }) diff --git a/test/fixtures/important.css b/test/fixtures/important.css new file mode 100644 index 0000000000..f0172f2051 --- /dev/null +++ b/test/fixtures/important.css @@ -0,0 +1,16 @@ +:root { + --one: not important; + --one: important !important; + + --two: important !important; + --two: not important; + + --three: important !important; + --three: more important !important; +} + +selector { + one: var(--one); + two: var(--two); + three: var(--three); +} diff --git a/test/fixtures/important.expected.css b/test/fixtures/important.expected.css new file mode 100644 index 0000000000..0439cf8b3d --- /dev/null +++ b/test/fixtures/important.expected.css @@ -0,0 +1,5 @@ +selector { + one: important; + two: important; + three: more important; +} diff --git a/test/index.js b/test/index.js index 9f5d949bbb..b6953b1a6b 100755 --- a/test/index.js +++ b/test/index.js @@ -81,6 +81,11 @@ test("supports case-sensitive variables", function(t) { t.end() }) +test("supports !important", function(t) { + compareFixtures(t, "important") + t.end() +}) + test("preserves variables when `preserve` is `true`", function(t) { compareFixtures(t, "preserve-variables", {preserve: true}) t.end() From f35b3efd9147b24c651df270964f4f5c0b9087ba Mon Sep 17 00:00:00 2001 From: Maxime Thirouin Date: Sun, 2 Nov 2014 07:47:42 +0100 Subject: [PATCH 068/795] v1.0.0 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 93dc23d220..656ccd2cd4 100755 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "postcss-custom-properties", - "version": "0.4.0", + "version": "1.0.0", "description": "PostCSS plugin to polyfill W3C CSS Custom Properties for cascading variables", "keywords": [ "css", From 86498f9eb5f0fa0cfcba1dc50efa92a9c2f4f7be Mon Sep 17 00:00:00 2001 From: Maxime Thirouin Date: Mon, 3 Nov 2014 06:09:01 +0100 Subject: [PATCH 069/795] fix warning about custom prop used in non :root --- CHANGELOG.md | 6 +++++- index.js | 7 ++++++- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 40dbd4aa52..e608391fc2 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,10 @@ +# 1.0.1 - 2014-11-03 + +- fix warning about custom prop used in non :root + # 1.0.0 - 2014-11-02 -- Add warning when a custom prop is used in another place that :root +- Add warning when a custom prop is used in another place than :root - handle !important # 0.4.0 - 2014-09-30 diff --git a/index.js b/index.js index 65b837bdfa..1e54840b16 100755 --- a/index.js +++ b/index.js @@ -33,7 +33,12 @@ module.exports = function(options) { // only variables declared for `:root` are supported for now if (rule.selectors.length !== 1 || rule.selectors[0] !== ":root" || rule.parent.type !== "root") { - console.warn(gnuMessage("Non :root only custom properties in non root level are not supported (" + rule.selectors + ")")) + rule.each(function(decl) { + var prop = decl.prop + if (prop && prop.indexOf(VAR_PROP_IDENTIFIER) === 0) { + console.warn(gnuMessage("Custom property ignored: found in another place than top level :root (" + rule.selectors + " { ... " + prop + ": ... })" + (rule.parent.type !== "root" ? ", in " + rule.parent.type : ""))) + } + }) return } From 3437f748940bf4efdf22c37eb04c130b20598716 Mon Sep 17 00:00:00 2001 From: Maxime Thirouin Date: Mon, 3 Nov 2014 06:10:00 +0100 Subject: [PATCH 070/795] v1.0.1 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 656ccd2cd4..50a9436b50 100755 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "postcss-custom-properties", - "version": "1.0.0", + "version": "1.0.1", "description": "PostCSS plugin to polyfill W3C CSS Custom Properties for cascading variables", "keywords": [ "css", From 1c90a45ba79cae09888ea51df3b0171cba5d3ca1 Mon Sep 17 00:00:00 2001 From: Maxime Thirouin Date: Tue, 4 Nov 2014 06:58:30 +0100 Subject: [PATCH 071/795] More clear message for warning about custom prop used in non top-level :root Ref https://github.com/postcss/postcss-custom-properties/commit/d39303bbd75e d961662a764f7a086cbe1f3f49a9#commitcomment-8418027 --- CHANGELOG.md | 4 ++++ README.md | 17 +++++++++++------ index.js | 2 +- 3 files changed, 16 insertions(+), 7 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e608391fc2..67ba5455f4 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,7 @@ +# 1.0.2 - 2014-11-04 + +- More clear message for warning about custom prop used in non top-level :root + # 1.0.1 - 2014-11-03 - fix warning about custom prop used in non :root diff --git a/README.md b/README.md index 8a2369314c..f097715a50 100755 --- a/README.md +++ b/README.md @@ -2,13 +2,16 @@ > [PostCSS](https://github.com/postcss/postcss) plugin to transform [W3C CSS Custom Properties for cascading variables](http://www.w3.org/TR/css-variables/) syntax to more compatible CSS. -**N.B.** The transformation _is not complete_. It currently just aims to provide a future-proof way of using a **limited subset (to `:root` selector)** of the features provided by native CSS custom properties. Read [#1](https://github.com/postcss/postcss-custom-properties/issues/1) & [#9](https://github.com/postcss/postcss-custom-properties/issues/9) to know why this limitation exists. +**N.B.** The transformation _is not complete_. It currently just aims to provide a future-proof way of using a **limited subset (to top-level `:root` selector)** of the features provided by native CSS custom properties. +Read [#1](https://github.com/postcss/postcss-custom-properties/issues/1) & [#9](https://github.com/postcss/postcss-custom-properties/issues/9) to know why this limitation exists. Works great with [postcss-calc](https://github.com/postcss/postcss-calc). ## Installation - $ npm install postcss-custom-properties +```console +$ npm install postcss-custom-properties +``` ## Usage @@ -73,10 +76,12 @@ Allow you to pass an object of variables for `:root`. These definitions will ove Work on a branch, install dev-dependencies, respect coding style & run tests before submitting a bug fix or a feature. - $ git clone https://github.com/postcss/postcss-custom-properties.git - $ git checkout -b patch-1 - $ npm install - $ npm test +```console +$ git clone https://github.com/postcss/postcss-custom-properties.git +$ git checkout -b patch-1 +$ npm install +$ npm test +``` ## [Changelog](CHANGELOG.md) diff --git a/index.js b/index.js index 1e54840b16..20b4207e95 100755 --- a/index.js +++ b/index.js @@ -36,7 +36,7 @@ module.exports = function(options) { rule.each(function(decl) { var prop = decl.prop if (prop && prop.indexOf(VAR_PROP_IDENTIFIER) === 0) { - console.warn(gnuMessage("Custom property ignored: found in another place than top level :root (" + rule.selectors + " { ... " + prop + ": ... })" + (rule.parent.type !== "root" ? ", in " + rule.parent.type : ""))) + console.warn(gnuMessage("Custom property ignored: not scoped to the top-level :root element (" + rule.selectors + " { ... " + prop + ": ... })" + (rule.parent.type !== "root" ? ", in " + rule.parent.type : ""))) } }) return From 80119d39ede1b590b4c9ab347f791fee08d9d7bb Mon Sep 17 00:00:00 2001 From: Maxime Thirouin Date: Tue, 4 Nov 2014 06:58:49 +0100 Subject: [PATCH 072/795] v1.0.2 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 50a9436b50..6c96e480ee 100755 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "postcss-custom-properties", - "version": "1.0.1", + "version": "1.0.2", "description": "PostCSS plugin to polyfill W3C CSS Custom Properties for cascading variables", "keywords": [ "css", From 9867cc8f78edfd16cdc441fade42518bc4a1a10e Mon Sep 17 00:00:00 2001 From: Maxime Thirouin Date: Sun, 9 Nov 2014 07:28:31 +0100 Subject: [PATCH 073/795] less dev deps --- package.json | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/package.json b/package.json index 7eb038eeba..04d9e072b7 100755 --- a/package.json +++ b/package.json @@ -23,16 +23,13 @@ ], "dependencies": {}, "devDependencies": { - "jscs": "^1.5.9", - "jshint": "^2.5.2", - "jshint-stylish": "^0.4.0", - "postcss": "^2.1.2", - "tap-colorize": "^1.2.0", - "tape": "^2.13.4" + "jscs": "^1.6.2", + "jshint": "^2.5.6", + "postcss": "^2.2.5", + "tape": "^3.0.0" }, "scripts": { - "jscs": "jscs *.js **/*.js", - "jshint": "jshint . --exclude node_modules --reporter node_modules/jshint-stylish/stylish.js", - "test": "npm run jscs && npm run jshint && tape test | tap-colorize" + "lint": "jscs *.js **/*.js && jshint . --exclude-path .gitignore", + "test": "npm run lint && tape test" } } From ceae7e241f5fd1799ee0cdf51a6050c30120a767 Mon Sep 17 00:00:00 2001 From: Maxime Thirouin Date: Sun, 9 Nov 2014 07:29:10 +0100 Subject: [PATCH 074/795] Fix npm description --- CHANGELOG.md | 5 ++++- LICENSE | 2 +- package.json | 5 ++--- 3 files changed, 7 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f00c615ab7..9810cc53f0 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,7 @@ +# 1.2.1 - 2014-10-09 + +- Fix npm description + # 1.2.0 - 2014-10-01 - Add support for multiples media in query list (ref [#rework-custom-media/5](https://github.com/reworkcss/rework-custom-media/pull/5)) @@ -10,7 +14,6 @@ - Allow whitespace around custom media name (fix [#2](https://github.com/postcss/postcss-custom-media/issues/2)) - # 1.0.0 - 2014-08-12 First release based on [rework-custom-media](https://github.com/reworkcss/rework-custom-media) v0.1.1 diff --git a/LICENSE b/LICENSE index 23eb1d3488..e8f6c97582 100755 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,6 @@ The MIT License (MIT) -Copyright (c) 2014, Maxime Thirouin & Nicolas Gallagher +Copyright (c) 2014 Maxime Thirouin & Nicolas Gallagher 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 diff --git a/package.json b/package.json index 04d9e072b7..febf3d7c53 100755 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "postcss-custom-media", "version": "1.2.0", - "description": "PostCSS plugin to import CSS files", + "description": " PostCSS plugin to transform W3C CSS Custom Media Queries to more compatible CSS", "keywords": [ "css", "postcss", @@ -9,7 +9,7 @@ "media queries", "custom-media" ], - "author": "MoOx", + "author": "Maxime Thirouin", "license": "MIT", "repository": { "type": "git", @@ -18,7 +18,6 @@ "files": [ "CHANGELOG.md", "LICENSE", - "README.md", "index.js" ], "dependencies": {}, From 87067cecdc13025865512f287ddfc55624a8e9b8 Mon Sep 17 00:00:00 2001 From: Maxime Thirouin Date: Sun, 9 Nov 2014 07:29:25 +0100 Subject: [PATCH 075/795] Adjust gnuMessage if no source available --- index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/index.js b/index.js index a785c9c764..fb385ae85b 100755 --- a/index.js +++ b/index.js @@ -65,5 +65,5 @@ function customMedia(options) { * @param {Object} source */ function gnuMessage(message, source) { - return (source ? (source.file ? source.file : "") + ":" + source.start.line + ":" + source.start.column : "") + " " + message + return (source ? (source.file ? source.file : "") + ":" + source.start.line + ":" + source.start.column + " " : "") + message } From eb883df80504c641673cf69aa4d3e41e20d2e043 Mon Sep 17 00:00:00 2001 From: Maxime Thirouin Date: Sun, 9 Nov 2014 07:29:42 +0100 Subject: [PATCH 076/795] v1.2.1 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index febf3d7c53..b139a06b2b 100755 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "postcss-custom-media", - "version": "1.2.0", + "version": "1.2.1", "description": " PostCSS plugin to transform W3C CSS Custom Media Queries to more compatible CSS", "keywords": [ "css", From bdbe496a2bc70e1eaa381b5f6f194dbc49352fb7 Mon Sep 17 00:00:00 2001 From: Maxime Thirouin Date: Sun, 9 Nov 2014 08:03:01 +0100 Subject: [PATCH 077/795] v1 from rework-font-variant --- .editorconfig | 16 +++ .gitignore | 2 + .jscsrc | 130 ++++++++++++++++++++++++ .jshintrc | 9 ++ .travis.yml | 1 + CHANGELOG.md | 3 + LICENSE | 20 ++++ README.md | 70 +++++++++++++ index.js | 84 +++++++++++++++ package.json | 35 +++++++ test/fixtures/font-variant.css | 8 ++ test/fixtures/font-variant.expected.css | 14 +++ test/index.js | 25 +++++ 13 files changed, 417 insertions(+) create mode 100644 .editorconfig create mode 100644 .gitignore create mode 100644 .jscsrc create mode 100644 .jshintrc create mode 100644 .travis.yml create mode 100755 CHANGELOG.md create mode 100755 LICENSE create mode 100755 README.md create mode 100755 index.js create mode 100755 package.json create mode 100644 test/fixtures/font-variant.css create mode 100644 test/fixtures/font-variant.expected.css create mode 100755 test/index.js diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000000..8978b448a6 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,16 @@ +# 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 diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000000..7ab649f420 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +node_modules +test/fixtures/*.actual.css diff --git a/.jscsrc b/.jscsrc new file mode 100644 index 0000000000..29720b3791 --- /dev/null +++ b/.jscsrc @@ -0,0 +1,130 @@ +{ + "excludeFiles": [ + "node_modules/**" + ], + "fileExtensions": [ + ".js" + ], + "requireCurlyBraces": [ + "if", + "else", + "for", + "while", + "do", + "try", + "catch" + ], + "requireSpaceAfterKeywords": [ + "if", + "else", + "for", + "while", + "do", + "switch", + "return", + "try", + "catch" + ], + "requireSpaceBeforeBlockStatements": true, + "requireParenthesesAroundIIFE": true, + "requireSpacesInConditionalExpression": { + "afterTest": true, + "beforeConsequent": true, + "afterConsequent": true, + "beforeAlternate": true + }, + "requireSpacesInFunctionExpression": { + "beforeOpeningCurlyBrace": true + }, + "disallowSpacesInFunctionExpression": { + "beforeOpeningRoundBrace": true + }, + "disallowMultipleVarDecl": true, + "requireBlocksOnNewline": 1, + "disallowPaddingNewlinesInBlocks": true, + "disallowEmptyBlocks": true, + "disallowSpacesInsideObjectBrackets": true, + "disallowSpacesInsideArrayBrackets": true, + "disallowSpacesInsideParentheses": true, + "disallowQuotedKeysInObjects": "allButReserved", + "disallowSpaceAfterObjectKeys": true, + "requireCommaBeforeLineBreak": true, + "requireOperatorBeforeLineBreak": [ + "?", + "+", + "-", + "/", + "*", + "=", + "==", + "===", + "!=", + "!==", + ">", + ">=", + "<", + "<=" + ], + "disallowSpaceAfterPrefixUnaryOperators": [ + "++", + "--", + "+", + "-", + "~", + "!" + ], + "disallowSpaceBeforePostfixUnaryOperators": [ + "++", + "--" + ], + "requireSpaceBeforeBinaryOperators": [ + "+", + "-", + "/", + "*", + "=", + "==", + "===", + "!=", + "!==" + ], + "requireSpaceAfterBinaryOperators": [ + "+", + "-", + "/", + "*", + "=", + "==", + "===", + "!=", + "!==" + ], + "disallowImplicitTypeConversion": [ + "numeric", + "boolean", + "binary", + "string" + ], + "requireCamelCaseOrUpperCaseIdentifiers": "ignoreProperties", + "disallowKeywords": [ + "with" + ], + "disallowMultipleLineStrings": true, + "validateQuoteMarks": "\"", + "validateIndentation": 2, + "disallowMixedSpacesAndTabs": true, + "disallowTrailingWhitespace": true, + "requireKeywordsOnNewLine": [ + "else" + ], + "requireLineFeedAtFileEnd": true, + "requireCapitalizedConstructors": true, + "safeContextKeyword": "that", + "requireDotNotation": true, + "validateJSDoc": { + "checkParamNames": true, + "checkRedundantParams": true, + "requireParamTypes": true + }, + "requireSpaceAfterLineComment": true +} diff --git a/.jshintrc b/.jshintrc new file mode 100644 index 0000000000..9f268f76ca --- /dev/null +++ b/.jshintrc @@ -0,0 +1,9 @@ +{ + "newcap": false, + "undef": true, + "unused": true, + "asi": true, + "esnext": true, + "node": true, + "browser": true +} diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000000..587bd3e031 --- /dev/null +++ b/.travis.yml @@ -0,0 +1 @@ +language: node_js diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100755 index 0000000000..4b7da8ed3b --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,3 @@ +# 1.0.0 - 2014-10-09 + +First release based on [rework-font-variant](https://github.com/ianstormtaylor/rework-font-variant) v1.0.1 diff --git a/LICENSE b/LICENSE new file mode 100755 index 0000000000..efbafd76b2 --- /dev/null +++ b/LICENSE @@ -0,0 +1,20 @@ +The MIT License (MIT) + +Copyright (c) 2014 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. diff --git a/README.md b/README.md new file mode 100755 index 0000000000..4017d695bf --- /dev/null +++ b/README.md @@ -0,0 +1,70 @@ +# postcss-font-variant [![Build Status](https://travis-ci.org/postcss/postcss-font-variant.png)](https://travis-ci.org/postcss/postcss-font-variant) + +> [PostCSS](https://github.com/postcss/postcss) plugin to transform [W3C CSS font variant](http://dev.w3.org/csswg/css-fonts/#propdef-font-variant) properties to more compatible CSS (font-feature-settings). + +## Installation + +```console +$ npm install postcss-font-variant +``` + +## Usage + +```js +// dependencies +var postcss = require("postcss") +var fontVariant = require("postcss-font-variant") + +// css to be processed +var css = fs.readFileSync("input.css", "utf8") + +// process css using postcss-font-variant +var out = postcss() + .use(fontVariant()) + .process(css) + .css +``` + +Using this `input.css`: + +```css +h2 { + font-variant-caps: small-caps; +} + +table { + font-variant-numeric: lining-nums; +} +``` + +you will get: + +```css +h2 { + font-feature-settings: "c2sc"; + font-variant-caps: small-caps; +} + +table { + font-feature-settings: "lnum"; + font-variant-numeric: lining-nums; +} + +``` + +Checkout [tests](test) for more examples. + +--- + +## Contributing + +Work on a branch, install dev-dependencies, respect coding style & run tests before submitting a bug fix or a feature. + + $ git clone https://github.com/postcss/postcss-font-variant.git + $ git checkout -b patch-1 + $ npm install + $ npm test + +## [Changelog](CHANGELOG.md) + +## [License](LICENSE) diff --git a/index.js b/index.js new file mode 100755 index 0000000000..1e7de58fd9 --- /dev/null +++ b/index.js @@ -0,0 +1,84 @@ +/** + * font variant convertion map + * + * @type {Object} + */ +var fontVariantProperties = { + "font-variant-ligatures": { + "common-ligatures": "\"liga\", \"clig\"", + "no-common-ligatures": "\"liga\", \"clig off\"", + "discretionary-ligatures": "\"dlig\"", + "no-discretionary-ligatures": "\"dlig\" off", + "historical-ligatures": "\"hlig\"", + "no-historical-ligatures": "\"hlig\" off", + contextual: "\"calt\"", + "no-contextual": "\"calt\" off" + }, + + "font-variant-position": { + sub: "\"subs\"", + "super": "\"sups\"" + }, + + "font-variant-caps": { + "small-caps": "\"c2sc\"", + "all-small-caps": "\"smcp\", \"c2sc\"", + "petite-caps": "\"pcap\"", + "all-petite-caps": "\"pcap\", \"c2pc\"", + unicase: "\"unic\"", + "titling-caps": "\"titl\"" + }, + + "font-variant-numeric": { + "lining-nums": "\"lnum\"", + "oldstyle-nums": "\"onum\"", + "proportional-nums": "\"pnum\"", + "tabular-nums": "\"tnum\"", + "diagonal-fractions": "\"frac\"", + "stacked-fractions": "\"afrc\"", + ordinal: "\"ordn\"", + "slashed-zero": "\"zero\"" + }, + + "font-variant": { + normal: "normal", + inherit: "inherit" + } +} + +// The `font-variant` property is a shorthand for all the others. +for (var prop in fontVariantProperties) { + var keys = fontVariantProperties[prop] + for (var key in keys) { + fontVariantProperties["font-variant"][key] = keys[key] + } +} + +/** + * Expose the font-variant plugin. + */ +module.exports = function postcssFontVariant() { + return function(styles) { + // read custom media queries + styles.eachDecl(function(decl) { + if (!fontVariantProperties[decl.prop]) { + return null + } + + var newValue = decl.value + if (decl.prop === "font-variant") { + newValue = decl.value.split(/\s+/g).map(function(val) { + return fontVariantProperties["font-variant"][val] + }).join(", ") + } + else if (fontVariantProperties[decl.prop][decl.value]) { + newValue = fontVariantProperties[decl.prop][decl.value] + } + + var newDecl = decl.clone() + newDecl.prop = "font-feature-settings" + newDecl.value = newValue + decl.parent.insertBefore(decl, newDecl) + }) + } +} diff --git a/package.json b/package.json new file mode 100755 index 0000000000..39bf72c622 --- /dev/null +++ b/package.json @@ -0,0 +1,35 @@ +{ + "name": "postcss-font-variant", + "version": "0.0.0", + "description": "PostCSS plugin to transform W3C font-variant properties to more compatible CSS (font-feature-settings)", + "keywords": [ + "css", + "postcss", + "postcss-plugins", + "font", + "variant", + "font-variant" + ], + "author": "Maxime Thirouin", + "license": "MIT", + "repository": { + "type": "git", + "url": "https://github.com/postcss/postcss-font-variant.git" + }, + "files": [ + "CHANGELOG.md", + "LICENSE", + "index.js" + ], + "dependencies": {}, + "devDependencies": { + "jscs": "^1.6.2", + "jshint": "^2.5.6", + "postcss": "^2.2.5", + "tape": "^3.0.0" + }, + "scripts": { + "lint": "jscs *.js **/*.js && jshint . --exclude-path .gitignore", + "test": "npm run lint && tape test" + } +} diff --git a/test/fixtures/font-variant.css b/test/fixtures/font-variant.css new file mode 100644 index 0000000000..10fa7bd50f --- /dev/null +++ b/test/fixtures/font-variant.css @@ -0,0 +1,8 @@ +selector { + font-variant-numeric: tabular-nums; + font-variant-caps: all-small-caps; + font-variant: normal; + font-variant: inherit; + font-variant: all-small-caps oldstyle-nums; + font-variant-position: normal; +} diff --git a/test/fixtures/font-variant.expected.css b/test/fixtures/font-variant.expected.css new file mode 100644 index 0000000000..ba9ae6a836 --- /dev/null +++ b/test/fixtures/font-variant.expected.css @@ -0,0 +1,14 @@ +selector { + font-feature-settings: "tnum"; + font-variant-numeric: tabular-nums; + font-feature-settings: "smcp", "c2sc"; + font-variant-caps: all-small-caps; + font-feature-settings: normal; + font-variant: normal; + font-feature-settings: inherit; + font-variant: inherit; + font-feature-settings: "smcp", "c2sc", "onum"; + font-variant: all-small-caps oldstyle-nums; + font-feature-settings: normal; + font-variant-position: normal; +} diff --git a/test/index.js b/test/index.js new file mode 100755 index 0000000000..793659bc7b --- /dev/null +++ b/test/index.js @@ -0,0 +1,25 @@ +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.writeFile(filename("fixtures/" + name + ".actual"), actual) + t.equal(actual, expected, msg) +} + +test("@custom-media", function(t) { + compareFixtures(t, "font-variant", "should transform font-variant") + + t.end() +}) From 3a44bf90da164614594de78bbc0d34efa67111a3 Mon Sep 17 00:00:00 2001 From: Maxime Thirouin Date: Sun, 9 Nov 2014 08:06:15 +0100 Subject: [PATCH 078/795] oups --- test/index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/index.js b/test/index.js index 793659bc7b..ba3d60a103 100755 --- a/test/index.js +++ b/test/index.js @@ -18,7 +18,7 @@ function compareFixtures(t, name, msg, opts, postcssOpts) { t.equal(actual, expected, msg) } -test("@custom-media", function(t) { +test("font-variant", function(t) { compareFixtures(t, "font-variant", "should transform font-variant") t.end() From 239567ca9530610612d8a8b8b5bb8f58678ab44f Mon Sep 17 00:00:00 2001 From: Maxime Thirouin Date: Sun, 9 Nov 2014 08:06:27 +0100 Subject: [PATCH 079/795] v1.0.0 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 39bf72c622..d96bfb9801 100755 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "postcss-font-variant", - "version": "0.0.0", + "version": "1.0.0", "description": "PostCSS plugin to transform W3C font-variant properties to more compatible CSS (font-feature-settings)", "keywords": [ "css", From 23d520ea668ee85719389a9657466ef65dfb514e Mon Sep 17 00:00:00 2001 From: Maxime Thirouin Date: Tue, 11 Nov 2014 18:29:53 +0100 Subject: [PATCH 080/795] fix wrong space char that breaks on some environnements --- CHANGELOG.md | 4 ++++ index.js | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4b7da8ed3b..ecb08149da 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,7 @@ +# 1.0.1 - 2014-11-11 + +- fix wrong space char that breaks on some environnements + # 1.0.0 - 2014-10-09 First release based on [rework-font-variant](https://github.com/ianstormtaylor/rework-font-variant) v1.0.1 diff --git a/index.js b/index.js index 1e7de58fd9..c2d9e2a43d 100755 --- a/index.js +++ b/index.js @@ -71,7 +71,7 @@ module.exports = function postcssFontVariant() { return fontVariantProperties["font-variant"][val] }).join(", ") } - else if (fontVariantProperties[decl.prop][decl.value]) { + else if (fontVariantProperties[decl.prop][decl.value]) { newValue = fontVariantProperties[decl.prop][decl.value] } From 454347ff9787d1274de1b064f1b795d3a70cb020 Mon Sep 17 00:00:00 2001 From: Maxime Thirouin Date: Tue, 11 Nov 2014 18:30:24 +0100 Subject: [PATCH 081/795] v1.0.1 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index d96bfb9801..232423dc03 100755 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "postcss-font-variant", - "version": "1.0.0", + "version": "1.0.1", "description": "PostCSS plugin to transform W3C font-variant properties to more compatible CSS (font-feature-settings)", "keywords": [ "css", From d5d24f4082972cd09326d10c7129c86cedc3b178 Mon Sep 17 00:00:00 2001 From: Maxime Thirouin Date: Wed, 12 Nov 2014 15:42:14 +0100 Subject: [PATCH 082/795] Upgrade to postcss 3 --- CHANGELOG.md | 4 ++++ index.js | 4 ++-- package.json | 3 +-- 3 files changed, 7 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 67ba5455f4..f742e9c93d 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,7 @@ +# 2.0.0 - 2014-11-12 + +- Upgrade to postcss 3 + # 1.0.2 - 2014-11-04 - More clear message for warning about custom prop used in non top-level :root diff --git a/index.js b/index.js index 20b4207e95..9a2083df0a 100755 --- a/index.js +++ b/index.js @@ -56,11 +56,11 @@ module.exports = function(options) { // optionally remove `--*` properties from the rule if (!preserve) { for (var i = toRemove.length - 1; i >= 0; i--) { - rule.decls.splice(toRemove[i], 1) + rule.childs.splice(toRemove[i], 1) } // remove empty :root {} - if (rule.decls.length === 0) { + if (rule.childs.length === 0) { rule.removeSelf() } } diff --git a/package.json b/package.json index 6c96e480ee..47218654b9 100755 --- a/package.json +++ b/package.json @@ -19,7 +19,6 @@ "files": [ "CHANGELOG.md", "LICENSE", - "README.md", "index.js" ], "dependencies": { @@ -28,7 +27,7 @@ "devDependencies": { "jscs": "^1.6.2", "jshint": "^2.5.6", - "postcss": "^2.2.5", + "postcss": "^3.0.0", "tape": "^3.0.0" }, "scripts": { From 08d19b4782fed1b48126cc38b15b5efc9571a027 Mon Sep 17 00:00:00 2001 From: Maxime Thirouin Date: Wed, 12 Nov 2014 15:42:26 +0100 Subject: [PATCH 083/795] v2.0.0 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 47218654b9..0ced6eb5a9 100755 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "postcss-custom-properties", - "version": "1.0.2", + "version": "2.0.0", "description": "PostCSS plugin to polyfill W3C CSS Custom Properties for cascading variables", "keywords": [ "css", From 685ad389801b474da83233b1f9eaa8740d7ed671 Mon Sep 17 00:00:00 2001 From: Maxime Thirouin Date: Wed, 12 Nov 2014 15:45:37 +0100 Subject: [PATCH 084/795] Udpate gnuMessage function when no source available --- index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/index.js b/index.js index 661f6475cd..cf161c7023 100755 --- a/index.js +++ b/index.js @@ -97,5 +97,5 @@ function hexaToRgba(hex) { * @param {Object} source */ function gnuMessage(message, source) { - return (source ? (source.file ? source.file : "") + ":" + source.start.line + ":" + source.start.column : "") + " " + message + return (source ? (source.file ? source.file : "") + ":" + source.start.line + ":" + source.start.column + " " : "") + message } From 203395ec0802043e98ec1c3bb4d6fd1cdc3b5153 Mon Sep 17 00:00:00 2001 From: Maxime Thirouin Date: Wed, 12 Nov 2014 15:45:50 +0100 Subject: [PATCH 085/795] update test to ensure postcss 3.0 compatibility --- package.json | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/package.json b/package.json index 41fcc5d268..ffb11ff966 100644 --- a/package.json +++ b/package.json @@ -20,7 +20,6 @@ "files": [ "CHANGELOG.md", "LICENSE", - "README.md", "index.js" ], "dependencies": { @@ -29,7 +28,7 @@ "devDependencies": { "jscs": "^1.6.2", "jshint": "^2.5.6", - "postcss": "^2.2.5", + "postcss": "^3.0.0", "tape": "^3.0.0" }, "scripts": { From 8cad8d449f03a7e111887754318dc7a6a4ff2e8d Mon Sep 17 00:00:00 2001 From: Maxime Thirouin Date: Wed, 12 Nov 2014 15:51:39 +0100 Subject: [PATCH 086/795] Udpate gnuMessage function when no source available --- index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/index.js b/index.js index 4d71de3226..15b03b63cc 100755 --- a/index.js +++ b/index.js @@ -58,5 +58,5 @@ function transformHwb(string) { * @param {Object} source */ function gnuMessage(message, source) { - return (source ? (source.file ? source.file : "") + ":" + source.start.line + ":" + source.start.column : "") + " " + message + return (source ? (source.file ? source.file : "") + ":" + source.start.line + ":" + source.start.column + " " : "") + message } From 1e72de21acec0778e7e9201d08b2fb02fa734939 Mon Sep 17 00:00:00 2001 From: Maxime Thirouin Date: Wed, 12 Nov 2014 15:51:50 +0100 Subject: [PATCH 087/795] update test to ensure postcss 3.0 compatibility --- package.json | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/package.json b/package.json index cfee860775..f396133c06 100644 --- a/package.json +++ b/package.json @@ -20,7 +20,6 @@ "files": [ "CHANGELOG.md", "LICENSE", - "README.md", "index.js" ], "dependencies": { @@ -30,7 +29,7 @@ "devDependencies": { "jscs": "^1.6.2", "jshint": "^2.5.6", - "postcss": "^2.2.5", + "postcss": "^3.0.0", "tape": "^3.0.0" }, "scripts": { From 2369ab2ae79a8b9eb1d594464f19a5532d2ed1b9 Mon Sep 17 00:00:00 2001 From: Maxime Thirouin Date: Wed, 12 Nov 2014 15:53:02 +0100 Subject: [PATCH 088/795] Udpate gnuMessage function when no source available --- index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/index.js b/index.js index 984bbc6063..3cef3b270b 100755 --- a/index.js +++ b/index.js @@ -64,5 +64,5 @@ function transformRebeccapurple(string) { * @param {Object} source */ function gnuMessage(message, source) { - return (source ? (source.file ? source.file : "") + ":" + source.start.line + ":" + source.start.column : "") + " " + message + return (source ? (source.file ? source.file : "") + ":" + source.start.line + ":" + source.start.column + " " : "") + message } From dc8c03bf88d7bb19dcc16cc48157729b68b1e739 Mon Sep 17 00:00:00 2001 From: Maxime Thirouin Date: Wed, 12 Nov 2014 15:53:12 +0100 Subject: [PATCH 089/795] update test to ensure postcss 3.0 compatibility --- package.json | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/package.json b/package.json index b6b999adea..83a15e26ff 100755 --- a/package.json +++ b/package.json @@ -20,7 +20,6 @@ "files": [ "CHANGELOG.md", "LICENSE", - "README.md", "index.js" ], "dependencies": { @@ -29,7 +28,7 @@ "devDependencies": { "jscs": "^1.6.2", "jshint": "^2.5.6", - "postcss": "^2.2.5", + "postcss": "^3.0.0", "tape": "^3.0.0" }, "scripts": { From 4427bb7acf8b56e78c33579f7c51a746abc460d0 Mon Sep 17 00:00:00 2001 From: Maxime Thirouin Date: Wed, 12 Nov 2014 15:56:10 +0100 Subject: [PATCH 090/795] update test to ensure postcss 3.0 compatibility --- package.json | 2 +- test/index.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index b139a06b2b..75b06556a7 100755 --- a/package.json +++ b/package.json @@ -24,7 +24,7 @@ "devDependencies": { "jscs": "^1.6.2", "jshint": "^2.5.6", - "postcss": "^2.2.5", + "postcss": "^3.0.0", "tape": "^3.0.0" }, "scripts": { diff --git a/test/index.js b/test/index.js index a909889f62..a7e5d35c93 100755 --- a/test/index.js +++ b/test/index.js @@ -15,7 +15,7 @@ function compareFixtures(t, name, msg, opts, postcssOpts) { var actual = postcss().use(plugin(opts)).process(read(postcssOpts.from), postcssOpts).css var expected = read(filename("fixtures/" + name + ".expected")) fs.writeFile(filename("fixtures/" + name + ".actual"), actual) - t.equal(actual, expected, msg) + t.equal(actual.trim(), expected.trim(), msg) } test("@custom-media", function(t) { From 8edf41f474dc321a626367450b9cdc739e0c062e Mon Sep 17 00:00:00 2001 From: Maxime Thirouin Date: Wed, 12 Nov 2014 15:58:32 +0100 Subject: [PATCH 091/795] update test to ensure postcss 3.0 compatibility --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 232423dc03..1a90024fc9 100755 --- a/package.json +++ b/package.json @@ -25,7 +25,7 @@ "devDependencies": { "jscs": "^1.6.2", "jshint": "^2.5.6", - "postcss": "^2.2.5", + "postcss": "^3.0.0", "tape": "^3.0.0" }, "scripts": { From 1c85cec41f5f697811bb0816c4d889cc60641076 Mon Sep 17 00:00:00 2001 From: Maxime Thirouin Date: Tue, 25 Nov 2014 08:40:30 +0100 Subject: [PATCH 092/795] Enhanced exceptions --- CHANGELOG.md | 4 ++++ index.js | 53 ++++++++-------------------------------------------- package.json | 1 + 3 files changed, 13 insertions(+), 45 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 30946753f7..f4168db2ff 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,7 @@ +# 1.1.0 - 2014-11-25 + +- Enhanced exceptions + # 1.0.0 - 2014-10-04 Initial release from [postcss-color](https://github.com/postcss/postcss-color) diff --git a/index.js b/index.js index 15b03b63cc..724ce14423 100755 --- a/index.js +++ b/index.js @@ -3,60 +3,23 @@ */ var color = require("color") var reduceFunctionCall = require("reduce-function-call") +var helpers = require("postcss-message-helpers") /** * PostCSS plugin to transform hwb() to rgb() */ module.exports = function plugin() { return function(style) { - style.eachDecl(function transformDecl(dec) { - if (!dec.value) { + style.eachDecl(function transformDecl(decl) { + if (!decl.value || decl.value.indexOf("hwb(") === -1) { return } - dec.value = transform(dec.value, dec.source) + decl.value = helpers.try(function transformHwb() { + return reduceFunctionCall(decl.value, "hwb", function reduceHwb(body, fn) { + return color(fn + "(" + body + ")").rgbString() + }) + }, decl.source) }) } } - -/** - * Transform hwb color to rgb() or rgba() - * - * @param {String} string - * @return {String} - */ -function transform(string, source) { - try { - if (string.indexOf("hwb(") > -1) { - string = transformHwb(string, source) - } - } - catch (e) { - throw new Error(gnuMessage(e.message, source)) - } - - return string -} - - -/** - * transform hwb() to rgb() (or rgba()) - * - * @param {String} string declaration value - * @return {String} converted declaration value to rgba() - */ -function transformHwb(string) { - return reduceFunctionCall(string, "hwb", function(body, fn) { - return color(fn + "(" + body + ")").rgbString() - }) -} - -/** - * return GNU style message - * - * @param {String} message - * @param {Object} source - */ -function gnuMessage(message, source) { - return (source ? (source.file ? source.file : "") + ":" + source.start.line + ":" + source.start.column + " " : "") + message -} diff --git a/package.json b/package.json index f396133c06..ef35f0ac34 100644 --- a/package.json +++ b/package.json @@ -24,6 +24,7 @@ ], "dependencies": { "color": "^0.7.1", + "postcss-message-helpers": "^1.1.0", "reduce-function-call": "^1.0.1" }, "devDependencies": { From 9131296cdd865c69c3ab03d7005c80ebc0e112b7 Mon Sep 17 00:00:00 2001 From: Maxime Thirouin Date: Tue, 25 Nov 2014 08:40:42 +0100 Subject: [PATCH 093/795] v1.1.0 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index ef35f0ac34..3400d122b8 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "postcss-color-hwb", - "version": "1.0.0", + "version": "1.1.0", "description": "PostCSS plugin to transform W3C CSS hwb() color to more compatible CSS (rgb() (or rgba()))", "keywords": [ "css", From 584656d40e35c74572bf337fbacf24aedcf29dfe Mon Sep 17 00:00:00 2001 From: Maxime Thirouin Date: Tue, 25 Nov 2014 08:45:30 +0100 Subject: [PATCH 094/795] Enhanced exceptions --- CHANGELOG.md | 4 ++++ index.js | 40 ++++++---------------------------------- package.json | 3 ++- 3 files changed, 12 insertions(+), 35 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 30946753f7..f4168db2ff 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,7 @@ +# 1.1.0 - 2014-11-25 + +- Enhanced exceptions + # 1.0.0 - 2014-10-04 Initial release from [postcss-color](https://github.com/postcss/postcss-color) diff --git a/index.js b/index.js index cf161c7023..750ae6478d 100755 --- a/index.js +++ b/index.js @@ -2,6 +2,7 @@ * Module dependencies. */ var color = require("color") +var helpers = require("postcss-message-helpers") /** * Constantes @@ -14,37 +15,18 @@ var DECIMAL_PRECISION = 100000 // 5 decimals */ module.exports = function plugin() { return function(style) { - style.eachDecl(function transformDecl(dec) { - if (!dec.value) { + style.eachDecl(function transformDecl(decl) { + if (!decl.value || decl.value.indexOf("#") === -1) { return } - dec.value = transform(dec.value, dec.source) + decl.value = helpers.try(function transformHexAlphaValue() { + return transformHexAlpha(decl.value, decl.source) + }, decl.source) }) } } -/** - * Transform colors to rgb() or rgba() on a declaration value - * - * @param {String} string - * @return {String} - */ -function transform(string, source) { - // order of transformation is important - - try { - if (string.indexOf("#") > -1) { - string = transformHexAlpha(string, source) - } - } - catch (e) { - throw new Error(gnuMessage(e.message, source)) - } - - return string -} - /** * transform RGBA hexadecimal notations (#RRGGBBAA or #RGBA) to rgba(). * @@ -89,13 +71,3 @@ function hexaToRgba(hex) { return color({r: rgb[0], g: rgb[1], b: rgb[2], a: rgb[3]}).rgbaString() } - -/** - * return GNU style message - * - * @param {String} message - * @param {Object} source - */ -function gnuMessage(message, source) { - return (source ? (source.file ? source.file : "") + ":" + source.start.line + ":" + source.start.column + " " : "") + message -} diff --git a/package.json b/package.json index ffb11ff966..ced45022db 100644 --- a/package.json +++ b/package.json @@ -23,7 +23,8 @@ "index.js" ], "dependencies": { - "color": "^0.7.1" + "color": "^0.7.1", + "postcss-message-helpers": "^1.1.0" }, "devDependencies": { "jscs": "^1.6.2", From 9aeffad2616ceeb3b59017b88ebe287c3818f1c1 Mon Sep 17 00:00:00 2001 From: Maxime Thirouin Date: Tue, 25 Nov 2014 08:45:46 +0100 Subject: [PATCH 095/795] v1.1.0 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index ced45022db..ea51571040 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "postcss-color-hex-alpha", - "version": "1.0.0", + "version": "1.1.0", "description": "PostCSS plugin to transform W3C RGBA hexadecimal notations (#RRGGBBAA or #RGBA) to more compatible CSS (rgba())", "keywords": [ "css", From 25c836c2df5f962bb529091f67bac446c2574ccd Mon Sep 17 00:00:00 2001 From: Maxime Thirouin Date: Tue, 25 Nov 2014 08:59:37 +0100 Subject: [PATCH 096/795] Enhanced exceptions --- CHANGELOG.md | 4 ++++ README.md | 12 +++++++----- index.js | 49 +++++++------------------------------------------ package.json | 3 ++- 4 files changed, 20 insertions(+), 48 deletions(-) mode change 100755 => 100644 package.json diff --git a/CHANGELOG.md b/CHANGELOG.md index 30946753f7..f4168db2ff 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,7 @@ +# 1.1.0 - 2014-11-25 + +- Enhanced exceptions + # 1.0.0 - 2014-10-04 Initial release from [postcss-color](https://github.com/postcss/postcss-color) diff --git a/README.md b/README.md index e9439021e9..0309c1e716 100755 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ In memory of [Eric Meyer’s daughter](http://meyerweb.com/eric/thoughts/2014/06 ## Installation -```bash +```console $ npm install postcss-color-rebeccapurple ``` @@ -56,10 +56,12 @@ Checkout [tests](test) for more examples. Work on a branch, install dev-dependencies, respect coding style & run tests before submitting a bug fix or a feature. - $ git clone https://github.com/postcss/postcss-color-rebeccapurple.git - $ git checkout -b patch-1 - $ npm install - $ npm test +```console +$ git clone https://github.com/postcss/postcss-color-rebeccapurple.git +$ git checkout -b patch-1 +$ npm install +$ npm test +``` ## [Changelog](CHANGELOG.md) diff --git a/index.js b/index.js index 3cef3b270b..d5c72d2ad7 100755 --- a/index.js +++ b/index.js @@ -2,50 +2,25 @@ * Module dependencies. */ var color = require("color") +var helpers = require("postcss-message-helpers") /** * PostCSS plugin to convert colors - * - * @param {Object} options */ -module.exports = function plugin(options) { - options = options || {} - options.rebeccapurple = options.rebeccapurple !== undefined ? options.rebeccapurple : true - options.hwb = options.hwb !== undefined ? options.hwb : true - options.hexAlpha = options.hexAlpha !== undefined ? options.hexAlpha : true - options.color = options.color !== undefined ? options.color : true - +module.exports = function plugin() { return function(style) { - style.eachDecl(function transformDecl(dec) { - if (!dec.value) { + style.eachDecl(function transformDecl(decl) { + if (!decl.value || decl.value.indexOf("rebeccapurple") === -1) { return } - dec.value = transform(dec.value, dec.source, options) + decl.value = helpers.try(function transformRebeccapurpleValue() { + return transformRebeccapurple(decl.value) + }, decl.source) }) } } -/** - * Transform colors to rgb() or rgba() on a declaration value - * - * @param {String} string - * @return {String} - */ -function transform(string, source, options) { - // order of transformation is important - - try { - if (options.rebeccapurple && string.indexOf("rebeccapurple") > -1) { - string = transformRebeccapurple(string, source) - } - } - catch (e) { - throw new Error(gnuMessage(e.message, source)) - } - - return string -} /** * Transform rebeccapurple color to rgb() @@ -56,13 +31,3 @@ function transform(string, source, options) { function transformRebeccapurple(string) { return string.replace(/(rebeccapurple)\b/gi, color("rebeccapurple").rgbString()) } - -/** - * return GNU style message - * - * @param {String} message - * @param {Object} source - */ -function gnuMessage(message, source) { - return (source ? (source.file ? source.file : "") + ":" + source.start.line + ":" + source.start.column + " " : "") + message -} diff --git a/package.json b/package.json old mode 100755 new mode 100644 index 83a15e26ff..458d23b5ff --- a/package.json +++ b/package.json @@ -23,7 +23,8 @@ "index.js" ], "dependencies": { - "color": "^0.7.1" + "color": "^0.7.1", + "postcss-message-helpers": "^1.1.0" }, "devDependencies": { "jscs": "^1.6.2", From 49f0e87207d3c69042a21c88c3f6db3e5ae20c2a Mon Sep 17 00:00:00 2001 From: Maxime Thirouin Date: Tue, 25 Nov 2014 08:59:47 +0100 Subject: [PATCH 097/795] v1.1.0 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 458d23b5ff..03dff19619 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "postcss-color-rebeccapurple", - "version": "1.0.0", + "version": "1.1.0", "description": "PostCSS plugin to transform W3C CSS rebeccapurple color to more compatible CSS (rgb())", "keywords": [ "css", From ffd375b6dbc2a5314aa556c24f7e4d1b94010db3 Mon Sep 17 00:00:00 2001 From: Maxime Thirouin Date: Tue, 25 Nov 2014 09:02:34 +0100 Subject: [PATCH 098/795] Better gnu message --- CHANGELOG.md | 4 ++++ index.js | 17 ++++++----------- package.json | 4 +++- 3 files changed, 13 insertions(+), 12 deletions(-) mode change 100755 => 100644 package.json diff --git a/CHANGELOG.md b/CHANGELOG.md index 9810cc53f0..cf703f5c25 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,7 @@ +# 1.3.0 - 2014-11-25 + +- Better gnu message + # 1.2.1 - 2014-10-09 - Fix npm description diff --git a/index.js b/index.js index fb385ae85b..ac706a9c57 100755 --- a/index.js +++ b/index.js @@ -1,3 +1,8 @@ +/** + * Module dependencies + */ +var helpers = require("postcss-message-helpers") + /** * Constants. */ @@ -48,7 +53,7 @@ function customMedia(options) { return map[name] } - console.warn(gnuMessage("missing @custom-media definition for '" + name + "'. The entire rule has been removed from the output.", rule.source)) + console.warn(helpers.message("missing @custom-media definition for '" + name + "'. The entire rule has been removed from the output.", rule.source)) toRemove.push(rule) }) }) @@ -57,13 +62,3 @@ function customMedia(options) { toRemove.forEach(function(rule) { rule.removeSelf() }) } } - -/** - * return GNU style message - * - * @param {String} message - * @param {Object} source - */ -function gnuMessage(message, source) { - return (source ? (source.file ? source.file : "") + ":" + source.start.line + ":" + source.start.column + " " : "") + message -} diff --git a/package.json b/package.json old mode 100755 new mode 100644 index 75b06556a7..6a7ec841eb --- a/package.json +++ b/package.json @@ -20,7 +20,9 @@ "LICENSE", "index.js" ], - "dependencies": {}, + "dependencies": { + "postcss-message-helpers": "^1.1.0" + }, "devDependencies": { "jscs": "^1.6.2", "jshint": "^2.5.6", From 028466a914a9a10c6a901c5db1bba37e1d047c98 Mon Sep 17 00:00:00 2001 From: Maxime Thirouin Date: Tue, 25 Nov 2014 09:02:48 +0100 Subject: [PATCH 099/795] v1.3.0 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 6a7ec841eb..9ae2910f57 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "postcss-custom-media", - "version": "1.2.1", + "version": "1.3.0", "description": " PostCSS plugin to transform W3C CSS Custom Media Queries to more compatible CSS", "keywords": [ "css", From 7d3a6dd1850828e80904b8d21f98074e016441e2 Mon Sep 17 00:00:00 2001 From: Maxime Thirouin Date: Tue, 25 Nov 2014 09:09:41 +0100 Subject: [PATCH 100/795] Enhanced exceptions & messages --- CHANGELOG.md | 4 ++++ index.js | 31 ++++++++++++------------------- package.json | 3 ++- 3 files changed, 18 insertions(+), 20 deletions(-) mode change 100755 => 100644 package.json diff --git a/CHANGELOG.md b/CHANGELOG.md index f742e9c93d..5f499ab769 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,7 @@ +# 2.1.0 - 2014-11-25 + +- Enhanced exceptions & messages + # 2.0.0 - 2014-11-12 - Upgrade to postcss 3 diff --git a/index.js b/index.js index 9a2083df0a..902f897d80 100755 --- a/index.js +++ b/index.js @@ -3,6 +3,7 @@ */ var balanced = require("balanced-match") +var helpers = require("postcss-message-helpers") /** * Constants. @@ -36,7 +37,7 @@ module.exports = function(options) { rule.each(function(decl) { var prop = decl.prop if (prop && prop.indexOf(VAR_PROP_IDENTIFIER) === 0) { - console.warn(gnuMessage("Custom property ignored: not scoped to the top-level :root element (" + rule.selectors + " { ... " + prop + ": ... })" + (rule.parent.type !== "root" ? ", in " + rule.parent.type : ""))) + console.warn(helpers.message("Custom property ignored: not scoped to the top-level :root element (" + rule.selectors + " { ... " + prop + ": ... })" + (rule.parent.type !== "root" ? ", in " + rule.parent.type : ""), decl.source)) } }) return @@ -80,11 +81,13 @@ module.exports = function(options) { return } - resolveValue(value, map, decl.source).forEach(function(resolvedValue) { - var clone = decl.clone() - clone.value = resolvedValue - decl.parent.insertBefore(decl, clone) - }) + helpers.try(function resolve() { + resolveValue(value, map, decl.source).forEach(function(resolvedValue) { + var clone = decl.clone() + clone.value = resolvedValue + decl.parent.insertBefore(decl, clone) + }) + }, decl.source) if (!preserve) { decl.removeSelf() @@ -119,17 +122,17 @@ function resolveValue(value, variables, source) { var matches = balanced("(", ")", value.substring(start)) if (!matches) { - throw new SyntaxError(gnuMessage("missing closing ')' in the value '" + value + "'", source)) + throw new SyntaxError("missing closing ')' in the value '" + value + "'") } if (matches.body === "") { - throw new Error(gnuMessage("var() must contain a non-whitespace string", source)) + throw new Error("var() must contain a non-whitespace string") } matches.body.replace(RE_VAR, function(_, name, fallback) { var replacement = variables[name] if (!replacement && !fallback) { - console.warn(gnuMessage("variable '" + name + "' is undefined and used without a fallback", source)) + console.warn(helpers.message("variable '" + name + "' is undefined and used without a fallback", source)) } // prepend with fallbacks @@ -165,13 +168,3 @@ function resolveValue(value, variables, source) { return results } - -/** - * return GNU style message - * - * @param {String} message - * @param {Object} source - */ -function gnuMessage(message, source) { - return (source ? (source.file ? source.file : "") + ":" + source.start.line + ":" + source.start.column + " " : "") + message -} diff --git a/package.json b/package.json old mode 100755 new mode 100644 index 0ced6eb5a9..e9d139705f --- a/package.json +++ b/package.json @@ -22,7 +22,8 @@ "index.js" ], "dependencies": { - "balanced-match": "~0.1.0" + "balanced-match": "~0.1.0", + "postcss-message-helpers": "^1.1.0" }, "devDependencies": { "jscs": "^1.6.2", From 83f6dda366ccd4ef178fa5671bef1a8de823eeee Mon Sep 17 00:00:00 2001 From: Maxime Thirouin Date: Tue, 25 Nov 2014 09:09:54 +0100 Subject: [PATCH 101/795] v2.1.0 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index e9d139705f..f1be7b3131 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "postcss-custom-properties", - "version": "2.0.0", + "version": "2.1.0", "description": "PostCSS plugin to polyfill W3C CSS Custom Properties for cascading variables", "keywords": [ "css", From 38e7a3d9f7d907db63cf3e8785f98f5684290383 Mon Sep 17 00:00:00 2001 From: Maxime Thirouin Date: Tue, 25 Nov 2014 10:14:38 +0100 Subject: [PATCH 102/795] Enhanced exceptions This commit also contains: - eslint + jscs break the process as they should if there is an error - test should fail if no error is thrown on each t.throws tests --- CHANGELOG.md | 7 +++++++ index.js | 14 ++++++-------- package.json | 3 ++- test.js | 8 ++++---- 4 files changed, 19 insertions(+), 13 deletions(-) create mode 100644 CHANGELOG.md diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000000..ae078d9d35 --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,7 @@ +# 1.1.0 - 2014-11-25 + +- Enhanced exceptions + +# 1.0.0 - 2014-11-01 + +Initial release diff --git a/index.js b/index.js index 4135e6e3f2..da8e41248c 100755 --- a/index.js +++ b/index.js @@ -7,13 +7,9 @@ var color = require('color'); var reduceFunctionCall = require('reduce-function-call'); +var helpers = require('postcss-message-helpers'); -function gnuMessage(message, source) { - var fileName = source.file || ''; - return fileName + ':' + source.start.line + ':' + source.start.column + ' ' + message; -} - -function parseGray(value, source) { +function parseGray(value) { return reduceFunctionCall(value, 'gray', function(argString) { var args = argString.split(','); @@ -39,14 +35,16 @@ function parseGray(value, source) { } catch (e) { e.message = e.message.replace(/rgba?\(.*\)/, 'gray(' + args + ')'); - throw new Error(gnuMessage(e.message, source)); + throw e; } }); } function transformDecl(decl) { if (decl.value && decl.value.indexOf('gray(') !== -1) { - decl.value = parseGray(decl.value, decl.source); + decl.value = helpers.try(function transformGrayValue() { + return parseGray(decl.value); + }, decl.source); } } diff --git a/package.json b/package.json index e922407717..b8f8c9b850 100644 --- a/package.json +++ b/package.json @@ -8,7 +8,7 @@ "url": "https://github.com/shinnn" }, "scripts": { - "pretest": "eslint *.js & jscs *.js", + "pretest": "eslint *.js && jscs *.js", "test": "node test.js | tap-spec", "coverage": "istanbul cover test.js", "coveralls": "${npm_package_scripts_coverage} && istanbul-coveralls" @@ -36,6 +36,7 @@ ], "dependencies": { "color": "^0.7.3", + "postcss-message-helpers": "^1.1.1", "reduce-function-call": "^1.0.1" }, "devDependencies": { diff --git a/test.js b/test.js index cccaae9449..6457aab0fb 100755 --- a/test.js +++ b/test.js @@ -41,7 +41,7 @@ test('filterDeclarations()', function(t) { function() { useGray().process('a {color: gray(,foo)}'); }, - /:1:4 Unable to parse color from string "gray\(,foo\)"/, + /:1:4: Unable to parse color from string "gray\(,foo\)"/, 'should throw an error when gray() takes invalid argument.' ); @@ -49,15 +49,15 @@ test('filterDeclarations()', function(t) { function() { useGray().process('a {color: gray(red)}', {from: 'fixture.css'}); }, - /fixture\.css:1:4 Unable to parse color from string "gray\(red\)"/, + /fixture\.css:1:4: Unable to parse color from string "gray\(red\)"/, 'should throw a detailed error when a source file is specified.' ); t.throws( function() { - console.log(useGray().process('a {color: gray(,)}', {map: true}).css); + useGray().process('a {color: gray(,)}', {map: true}); }, - /:1:4 Unable to parse color from string "gray\(,\)"/, + /:1:4: Unable to parse color from string "gray\(,\)"/, 'should throw a detailed error when source map is enabled but file isn\'t specified.' ); }); From 7968120be4788d90aca4aafda31d4a7c46632150 Mon Sep 17 00:00:00 2001 From: Shinnosuke Watanabe Date: Tue, 25 Nov 2014 23:32:11 +0900 Subject: [PATCH 103/795] update devDependencies --- index.js | 2 +- package.json | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/index.js b/index.js index da8e41248c..1b761e6ca4 100755 --- a/index.js +++ b/index.js @@ -6,8 +6,8 @@ 'use strict'; var color = require('color'); -var reduceFunctionCall = require('reduce-function-call'); var helpers = require('postcss-message-helpers'); +var reduceFunctionCall = require('reduce-function-call'); function parseGray(value) { return reduceFunctionCall(value, 'gray', function(argString) { diff --git a/package.json b/package.json index b8f8c9b850..6505f8255e 100644 --- a/package.json +++ b/package.json @@ -40,12 +40,12 @@ "reduce-function-call": "^1.0.1" }, "devDependencies": { - "eslint": "^0.9.1", + "eslint": "^0.9.2", "istanbul": "^0.3.2", "istanbul-coveralls": "^1.0.1", "jscs": "^1.7.3", - "postcss": "^2.2.5", - "tap-spec": "^1.0.1", - "tape": "^3.0.1" + "postcss": "^3.0.4", + "tap-spec": "^2.1.0", + "tape": "^3.0.3" } } From e9c7c984cfccdae671f3c93caa8d16abad64d6f2 Mon Sep 17 00:00:00 2001 From: Shinnosuke Watanabe Date: Tue, 25 Nov 2014 23:32:29 +0900 Subject: [PATCH 104/795] update appveyor.yml --- appveyor.yml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/appveyor.yml b/appveyor.yml index eb6da0ec1e..e6c2422fa4 100755 --- a/appveyor.yml +++ b/appveyor.yml @@ -16,5 +16,8 @@ install: build: off test_script: - - ps: node test.js + - ps: 'node test.js #PowerShell' - cmd: node test.js + +cache: + - node_modules From fb8fcf27f19ecaab9a88468c128aed074a755be4 Mon Sep 17 00:00:00 2001 From: Shinnosuke Watanabe Date: Tue, 25 Nov 2014 23:36:04 +0900 Subject: [PATCH 105/795] release v1.1.0 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 6505f8255e..3dc49b6ef1 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "postcss-color-gray", - "version": "1.0.0", + "version": "1.1.0", "description": "PostCSS plugin to transform gray() function to today's CSS", "repository": "postcss/postcss-color-gray", "author": { From 93f0d5b3fdaeed7ed9d62723bb10c5496724b2d1 Mon Sep 17 00:00:00 2001 From: Maxime Thirouin Date: Tue, 2 Dec 2014 16:25:46 +0100 Subject: [PATCH 106/795] fix issue when multiples undefined values are referenced Close # --- CHANGELOG.md | 4 ++++ index.js | 4 ++-- test/fixtures/substitution-undefined.css | 9 +++++++-- test/fixtures/substitution-undefined.expected.css | 7 ++++--- 4 files changed, 17 insertions(+), 7 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5f499ab769..9b5fd290c0 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,7 @@ +# 2.1.1 - 2014-12-02 + +- Fix issue when multiples undefined custom properties are referenced ([#16](https://github.com/postcss/postcss-custom-properties/issues/16)) + # 2.1.0 - 2014-11-25 - Enhanced exceptions & messages diff --git a/index.js b/index.js index 902f897d80..0e99c1aaca 100755 --- a/index.js +++ b/index.js @@ -114,7 +114,7 @@ module.exports = function(options) { function resolveValue(value, variables, source) { var results = [] - var start = value.indexOf("var(") + var start = value.indexOf(VAR_FUNC_IDENTIFIER + "(") if (start === -1) { return [value] } @@ -161,7 +161,7 @@ function resolveValue(value, variables, source) { if (!replacement && !fallback) { // resolve the end of the expression (matches.post ? resolveValue(matches.post, variables, source) : [""]).forEach(function(afterValue) { - results.push(value.slice(0, start) + value + afterValue) + results.push(value.slice(0, start) + VAR_FUNC_IDENTIFIER + "(" + name + ")" + afterValue) }) } }) diff --git a/test/fixtures/substitution-undefined.css b/test/fixtures/substitution-undefined.css index d6af72a5ad..718af2745c 100755 --- a/test/fixtures/substitution-undefined.css +++ b/test/fixtures/substitution-undefined.css @@ -1,7 +1,12 @@ -div { - color: var(--test); +:root { + --defined: true } div { + color: var(--test); color: var(--test, fallback); + background: linear-gradient(var(--a), var(--b)); + background: linear-gradient(var(--a), var(--b), var(--defined)); + background: linear-gradient(var(--a), var(--defined) , var(--b)); + background: linear-gradient(var(--a), var(--defined) , var(--b), var(--defined)); } diff --git a/test/fixtures/substitution-undefined.expected.css b/test/fixtures/substitution-undefined.expected.css index c845cd2578..a7f4a9b252 100644 --- a/test/fixtures/substitution-undefined.expected.css +++ b/test/fixtures/substitution-undefined.expected.css @@ -1,7 +1,8 @@ div { color: var(--test); -} - -div { color: fallback; + background: linear-gradient(var(--a), var(--b)); + background: linear-gradient(var(--a), var(--b), true); + background: linear-gradient(var(--a), true , var(--b)); + background: linear-gradient(var(--a), true , var(--b), true); } From b5e0821b25e2d6fefa42965fb70a94da3803184b Mon Sep 17 00:00:00 2001 From: Maxime Thirouin Date: Tue, 2 Dec 2014 16:26:06 +0100 Subject: [PATCH 107/795] More readable console.warn --- index.js | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/index.js b/index.js index 0e99c1aaca..09422d66f4 100755 --- a/index.js +++ b/index.js @@ -37,7 +37,14 @@ module.exports = function(options) { rule.each(function(decl) { var prop = decl.prop if (prop && prop.indexOf(VAR_PROP_IDENTIFIER) === 0) { - console.warn(helpers.message("Custom property ignored: not scoped to the top-level :root element (" + rule.selectors + " { ... " + prop + ": ... })" + (rule.parent.type !== "root" ? ", in " + rule.parent.type : ""), decl.source)) + console.warn( + helpers.message( + "Custom property ignored: not scoped to the top-level :root element (" + + rule.selectors + + " { ... " + prop + ": ... })" + + (rule.parent.type !== "root" ? ", in " + rule.parent.type : ""), + decl.source) + ) } }) return From bbe182b5814597db69702129ceecfb28a66ac1a2 Mon Sep 17 00:00:00 2001 From: Maxime Thirouin Date: Tue, 2 Dec 2014 16:27:22 +0100 Subject: [PATCH 108/795] v2.1.1 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index f1be7b3131..8e064cedf6 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "postcss-custom-properties", - "version": "2.1.0", + "version": "2.1.1", "description": "PostCSS plugin to polyfill W3C CSS Custom Properties for cascading variables", "keywords": [ "css", From ab85244e2f2cf317869faf6e396fcc4581a5efe4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=B8=80=E4=B8=9D?= Date: Thu, 4 Dec 2014 14:55:00 +0800 Subject: [PATCH 109/795] Initial commit --- LICENSE | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) create mode 100644 LICENSE diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000000..9d10f01975 --- /dev/null +++ b/LICENSE @@ -0,0 +1,22 @@ +The MIT License (MIT) + +Copyright (c) 2014 PostCSS + +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. + From 7cf1085d91d8a304f0b3d5554c74bf416df9e779 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D2=BC=CB=BF?= Date: Thu, 4 Dec 2014 19:52:24 +0800 Subject: [PATCH 110/795] first commit --- .editorconfig | 13 ++ .gitignore | 5 + .travis.yml | 1 + CHANGELOG.md | 3 + README.md | 201 +++++++++++++++++++++++++++ index.js | 75 ++++++++++ package.json | 30 ++++ test/fixtures/extension.css | 10 ++ test/fixtures/extension.expected.css | 7 + test/fixtures/heading.css | 5 + test/fixtures/heading.expected.css | 3 + test/fixtures/pseudo.css | 5 + test/fixtures/pseudo.expected.css | 3 + test/index.js | 33 +++++ 14 files changed, 394 insertions(+) create mode 100644 .editorconfig create mode 100644 .gitignore create mode 100644 .travis.yml create mode 100644 CHANGELOG.md create mode 100644 README.md create mode 100644 index.js create mode 100644 package.json create mode 100644 test/fixtures/extension.css create mode 100644 test/fixtures/extension.expected.css create mode 100644 test/fixtures/heading.css create mode 100644 test/fixtures/heading.expected.css create mode 100644 test/fixtures/pseudo.css create mode 100644 test/fixtures/pseudo.expected.css create mode 100644 test/index.js diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000000..dffb18adfb --- /dev/null +++ b/.editorconfig @@ -0,0 +1,13 @@ +# editorconfig.org +root = true + +[*] +charset = utf-8 +indent_style = space +indent_size = 2 +end_of_line = lf +trim_trailing_whitespace = true +insert_final_newline = true + +[*.md] +trim_trailing_whitespace = false diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000000..bf008057d6 --- /dev/null +++ b/.gitignore @@ -0,0 +1,5 @@ +.DS_Store +node_modules +test/fixtures/*.actual.css +*.sublime-workspace + diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000000..587bd3e031 --- /dev/null +++ b/.travis.yml @@ -0,0 +1 @@ +language: node_js diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000000..2b2be502ad --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,3 @@ +# 1.0.0 - 2014-12-04 + +First release diff --git a/README.md b/README.md new file mode 100644 index 0000000000..444dc5092d --- /dev/null +++ b/README.md @@ -0,0 +1,201 @@ +# PostCSS Custom Selector [![Build Status](https://travis-ci.org/postcss/postcss-custom-selector.png)](https://travis-ci.org/postcss/postcss-custom-selector) + +> [PostCSS](https://github.com/postcss/postcss) 实现 [W3C CSS Extensions(Custom Selectors)](http://dev.w3.org/csswg/css-extensions/#custom-selectors) 的插件。 + + + +## 安装(暂未发布) + + $ npm install postcss-custom-selector + +## 快速开始 + +```js +// dependencies +var fs = require('fs') +var postcss = require('postcss') +var selector = require('postcss-custom-selector') + +// css to be processed +var css = fs.readFileSync('input.css', 'utf8') + +// process css using postcss-custom-selector +var output = postcss() + .use(selector()) + .process(css) + .css + +console.log('\n\n ====>Output CSS:\n',output) +``` + +或者: + +```js +var output = postcss(selector()) + .process(css) + .css +``` + +input.css: + +```css +@custom-selector --heading h1, h2, h3, h4, h5, h6; + +article --heading + p{ + margin-top: 0; +} +``` + +你将得到: + +```css +article h1 + p, article h2 + p, article h3 + p, article h4 + p, article h5 + p, article h6 + p{ + margin-top: 0; +} +``` + +## CSS 语法 + +A custom selector is defined with the `@custom-selector` rule: + + @custom-selector = @custom-selector ; + +This defines a custom selector which is written as a pseudo-class with the given ``, and represents a `:matches()` selector using the provided `` as its argument. + + +For example, if an author wanted to easily refer to all heading elements in their HTML document, they could create an alias: + +```css +@custom-selector :--heading h1, h2, h3, h4, h5, h6; + +:--heading { /* styles for all headings */ } +:--heading + p { /* more styles */ } +/* etc */ +``` + +## 如何使用 + +### 伪元素/伪类 + +你可以使用 + +* `:` 自定义一个伪类。 +* `::`自定义一个伪元素。 + +例如,模拟一个 :any-link 选择器: + +input.css: + +```css +@custom-selector :--any-link :link, :visited; + +a:--any-link { + color: blue; +} +``` + +output: + +```css +a:link, a:visited { + color: blue; +} +``` +### 多个选择器 + +`@custom-selector` 类似 CSS [`:matches()`](http://dev.w3.org/csswg/selectors-4/#matches) 选择器,但是目前**不支持**在同一个选择器中调用多个自定义选择器,例如: + +```css +@custom-selector --heading h1, h2, h3, h4, h5, h6; +@custom-selector :--any-link :link, :visited; + +.demo --heading, a:--any-link { + font-size: 32px; +} +``` +将会输出错误的 CSS 代码。 + +### Grunt + +```js +grunt.initConfig({ + postcss: { + options: { + processors: [require('postcss-custom-selector').postcss] + }, + dist: { + src: 'css/*.css' + } + } +}); + +grunt.loadNpmTasks('grunt-postcss'); +``` + +### Gulp + +```js +var gulp = require('gulp'); +var postcss = require('gulp-postcss'); + +gulp.task('css', function() { + return gulp.src('./src/*.css') + .pipe(postcss([require('postcss-custom-selector')])) + .pipe(gulp.dest('./dest')); +}); +``` + + + +### 选项 + +**`extensions`** (默认: `{}`) + +该选项允许你自定义一个对象来设置 ``(选择器别名)和 ``,这些定义将覆盖 CSS 中相同别名的 `@custom-selector`。 + +```js +var options = { + extensions: { + ':--any' : 'section, article, aside, nav' + } +} + +var output = postcss(selector(options)) + .process(css) + .css; +``` + +input.css + +```css +@custom-selector :--any .foo, .bar; /* 不会生效 */ +:--any h1 { + margin-top: 16px; +} +``` + +output: + +```css +section h1, article h1, aside h1, nav h1 { + margin-top: 16px; +} +``` + + +## 贡献 + +* 安装相关依赖模块 +* 尊重编码风格(安装) +* 运行测试 + +``` +$ git clone https://github.com/postcss/postcss-custom-selector.git +$ git checkout -b patch +$ npm install +$ npm test +``` + +## [Changelog](CHANGELOG.md) + +## [License](LICENSE) diff --git a/index.js b/index.js new file mode 100644 index 0000000000..05588d0bd0 --- /dev/null +++ b/index.js @@ -0,0 +1,75 @@ +/** + * 匹配自定义选择器 + * --foo, :--foo, ::--foo 三种类型 + * 注意:CSS 选择器区分大小写 + */ +var re_CUSTOM_SELECTOR = /([^,]*?)((?::|::)?(?:--[\w-]+))([^,]*)/g + +/** + * 暴露插件 + */ +module.exports = customSelector + +/** + * 读取和替换自定义选择器 + */ +function customSelector(options) { + return function(styles) { + options = options || {} + var extensions = options.extensions || {} + var map = {} + var toRemove = [] + var customSelectors = {} + + // 读取自定义选择器 + styles.eachAtRule(function(rule) { + if (rule.name !== "custom-selector") { + return + } + + var params = rule.params.split(" ") + // @custom-selector = @custom-selector + // map[] = + + var customName = params.shift() + var string = rule.params + string = string.replace(customName, "") + customSelectors[customName] = string + + map[params.shift()] = params.join(" ") + + toRemove.push(rule) + }) + + // JS 中设置一个自定义选择器 + Object.keys(extensions).forEach(function(extension) { + map[extension] = extensions[extension] + customSelectors[extension] = extensions[extension] + }) + + // 转换自定义的选择器别名 + styles.eachRule(function(rule) { + for (var prop in customSelectors) { + if (rule.selector.indexOf(prop) >= 0) { + customSelector = customSelectors[prop] + + // $2 = (自定义的选择器名称) + rule.selector = rule.selector.replace(re_CUSTOM_SELECTOR, function($0, $1, $2, $3) { + if ($2 == prop) { + return customSelector.split(",").map(function(selector) { + return $1 + selector.trim() + $3 + }).join(", ") + } + }) + + } + } + }) + + // 删除 @custom-selector + toRemove.forEach(function(rule) { + rule.removeSelf() + }) + + } +} diff --git a/package.json b/package.json new file mode 100644 index 0000000000..e92bd62e52 --- /dev/null +++ b/package.json @@ -0,0 +1,30 @@ +{ + "name": "postcss-custom-selector", + "version": "1.0.0", + "description": "PostCSS plugin", + "keywords": [ + "css", + "postcss", + "postcss-plugins", + "selector", + "custom selector" + ], + "author": "yisi", + "license": "MIT", + "repository": { + "type": "git", + "url": "https://github.com/postcss/postcss-custom-selector.git" + }, + "files": [ + "CHANGELOG.md", + "LICENSE", + "index.js" + ], + "devDependencies": { + "postcss": "^3.0.0", + "tape": "^3.0.0" + }, + "scripts": { + "test": "tape test" + } +} diff --git a/test/fixtures/extension.css b/test/fixtures/extension.css new file mode 100644 index 0000000000..95b234e9a9 --- /dev/null +++ b/test/fixtures/extension.css @@ -0,0 +1,10 @@ +@custom-selector :--any .foo, .bar; +@custom-selector --foo .baz; + +:--any h1 { + margin-top: 16px; +} + +main --foo + p { + margin-top: 16px; +} diff --git a/test/fixtures/extension.expected.css b/test/fixtures/extension.expected.css new file mode 100644 index 0000000000..c9752cba5c --- /dev/null +++ b/test/fixtures/extension.expected.css @@ -0,0 +1,7 @@ +section h1, article h1, aside h1, nav h1 { + margin-top: 16px; +} + +main input[type="text"] > section + p, main #nav .bar + p { + margin-top: 16px; +} diff --git a/test/fixtures/heading.css b/test/fixtures/heading.css new file mode 100644 index 0000000000..2394abfe4f --- /dev/null +++ b/test/fixtures/heading.css @@ -0,0 +1,5 @@ +@custom-selector --heading h1, h2, h3, h4, h5, h6; + +article --heading + p{ + margin-top: 0; +} diff --git a/test/fixtures/heading.expected.css b/test/fixtures/heading.expected.css new file mode 100644 index 0000000000..0123afc237 --- /dev/null +++ b/test/fixtures/heading.expected.css @@ -0,0 +1,3 @@ +article h1 + p, article h2 + p, article h3 + p, article h4 + p, article h5 + p, article h6 + p{ + margin-top: 0; +} diff --git a/test/fixtures/pseudo.css b/test/fixtures/pseudo.css new file mode 100644 index 0000000000..8ab7951a25 --- /dev/null +++ b/test/fixtures/pseudo.css @@ -0,0 +1,5 @@ +@custom-selector ::--pseudo ::before, ::after; + +.foo > a::--pseudo img { + display: block; +} diff --git a/test/fixtures/pseudo.expected.css b/test/fixtures/pseudo.expected.css new file mode 100644 index 0000000000..64b516a74a --- /dev/null +++ b/test/fixtures/pseudo.expected.css @@ -0,0 +1,3 @@ +.foo > a::before img, .foo > a::after img { + display: block; +} diff --git a/test/index.js b/test/index.js new file mode 100644 index 0000000000..f71e113cd0 --- /dev/null +++ b/test/index.js @@ -0,0 +1,33 @@ +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.writeFile(filename("fixtures/" + name + ".actual"), actual) + t.equal(actual.trim(), expected.trim(), msg) +} + +test("@custom-selector", function(t) { + compareFixtures(t, "heading", "should transform custom selector") + compareFixtures(t, "pseudo", "should transform custom selector") + + compareFixtures(t, "extension", "local extensions", { + extensions: { + ':--any' : 'section, article, aside, nav', + '--foo': 'input[type="text"] > section, #nav .bar' + } + }) + + t.end() +}) From f757fc28f7006c85e1b18dcd654b6c415618a878 Mon Sep 17 00:00:00 2001 From: Shinnosuke Watanabe Date: Thu, 4 Dec 2014 21:59:01 +0900 Subject: [PATCH 111/795] Use SVG badge instead of PNG badge SVG badges look beautiful on retina displays. --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 444dc5092d..cef200f431 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# PostCSS Custom Selector [![Build Status](https://travis-ci.org/postcss/postcss-custom-selector.png)](https://travis-ci.org/postcss/postcss-custom-selector) +# PostCSS Custom Selector [![Build Status](https://travis-ci.org/postcss/postcss-custom-selector.svg)](https://travis-ci.org/postcss/postcss-custom-selector) > [PostCSS](https://github.com/postcss/postcss) 实现 [W3C CSS Extensions(Custom Selectors)](http://dev.w3.org/csswg/css-extensions/#custom-selectors) 的插件。 From 2a9c152f87173f33c10d373d1eaadbc00d613b5c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D2=BC=CB=BF?= Date: Fri, 5 Dec 2014 17:04:02 +0800 Subject: [PATCH 112/795] Modify the project name #3, update Gulp / Grunt document --- README.md | 63 ++++++++++++++++++++++++++++++++++++------------------- 1 file changed, 41 insertions(+), 22 deletions(-) diff --git a/README.md b/README.md index cef200f431..71a6c860aa 100644 --- a/README.md +++ b/README.md @@ -1,12 +1,12 @@ -# PostCSS Custom Selector [![Build Status](https://travis-ci.org/postcss/postcss-custom-selector.svg)](https://travis-ci.org/postcss/postcss-custom-selector) +# PostCSS Custom Selectors [![Build Status](https://travis-ci.org/postcss/postcss-custom-selector.svg)](https://travis-ci.org/postcss/postcss-custom-selector) > [PostCSS](https://github.com/postcss/postcss) 实现 [W3C CSS Extensions(Custom Selectors)](http://dev.w3.org/csswg/css-extensions/#custom-selectors) 的插件。 -## 安装(暂未发布) +## 安装 - $ npm install postcss-custom-selector + $ npm install postcss-custom-selectors ## 快速开始 @@ -14,12 +14,12 @@ // dependencies var fs = require('fs') var postcss = require('postcss') -var selector = require('postcss-custom-selector') +var selector = require('postcss-custom-selectors') // css to be processed var css = fs.readFileSync('input.css', 'utf8') -// process css using postcss-custom-selector +// process css using postcss-custom-selectors var output = postcss() .use(selector()) .process(css) @@ -118,31 +118,50 @@ a:link, a:visited { ### Grunt ```js -grunt.initConfig({ - postcss: { - options: { - processors: [require('postcss-custom-selector').postcss] - }, - dist: { - src: 'css/*.css' +module.exports = function(grunt) { + grunt.initConfig({ + pkg: grunt.file.readJSON('package.json'), + postcss: { + options: { + processors: [ + require('autoprefixer-core')({ browsers: ['> 0%'] }).postcss, //Other plugin + require('postcss-custom-selector')(), + ] + }, + dist: { + src: ['src/*.css'], + dest: 'build/grunt.css' + } } - } -}); + }); + + grunt.loadNpmTasks('grunt-contrib-uglify'); + grunt.loadNpmTasks('grunt-postcss'); -grunt.loadNpmTasks('grunt-postcss'); + grunt.registerTask('default', ['postcss']); +} ``` ### Gulp ```js var gulp = require('gulp'); +var rename = require('gulp-rename'); var postcss = require('gulp-postcss'); - -gulp.task('css', function() { - return gulp.src('./src/*.css') - .pipe(postcss([require('postcss-custom-selector')])) - .pipe(gulp.dest('./dest')); +var selector = require('postcss-custom-selector') +var autoprefixer = require('autoprefixer-core') + +gulp.task('default', function () { + var processors = [ + autoprefixer({ browsers: ['> 0%'] }), //Other plugin + selector() + ]; + gulp.src('src/*.css') + .pipe(postcss(processors)) + .pipe(rename('gulp.css')) + .pipe(gulp.dest('build')) }); +gulp.watch('src/*.css', ['default']); ``` @@ -186,11 +205,11 @@ section h1, article h1, aside h1, nav h1 { ## 贡献 * 安装相关依赖模块 -* 尊重编码风格(安装) +* 尊重编码风格(安装 [EditorConfig](http://editorconfig.org/)) * 运行测试 ``` -$ git clone https://github.com/postcss/postcss-custom-selector.git +$ git clone https://github.com/postcss/postcss-custom-selectors.git $ git checkout -b patch $ npm install $ npm test From 73873d709f1ca4c12e04a6174132870c35ef9341 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D2=BC=CB=BF?= Date: Fri, 5 Dec 2014 22:38:26 +0800 Subject: [PATCH 113/795] Update and improve English document --- README-zh.md | 241 +++++++++++++++++++++++++++++++++++++++++++++++++++ README.md | 100 ++++++++++++--------- package.json | 10 ++- 3 files changed, 307 insertions(+), 44 deletions(-) create mode 100644 README-zh.md diff --git a/README-zh.md b/README-zh.md new file mode 100644 index 0000000000..67da4074a3 --- /dev/null +++ b/README-zh.md @@ -0,0 +1,241 @@ +# PostCSS Custom Selectors [![Build Status](https://travis-ci.org/postcss/postcss-custom-selectors.svg)](https://travis-ci.org/postcss/postcss-custom-selectors) + +> [PostCSS](https://github.com/postcss/postcss) 实现 [W3C CSS Extensions(Custom Selectors)](http://dev.w3.org/csswg/css-extensions/#custom-selectors) 的插件。 + +[English](README.md) + +## 安装 + + $ npm install postcss-custom-selectors + +## 快速开始 + +示例1: + +```js +// dependencies +var fs = require('fs') +var postcss = require('postcss') +var selector = require('postcss-custom-selectors') + +// css to be processed +var css = fs.readFileSync('input.css', 'utf8') + +// process css using postcss-custom-selectors +var output = postcss() + .use(selector()) + .process(css) + .css + +console.log('\n====>Output CSS:\n', output) +``` + +或者: + +```js +var output = postcss(selector()) + .process(css) + .css +``` + +input.css: + +```css +@custom-selector --heading h1, h2, h3, h4, h5, h6; + +article --heading + p { + margin-top: 0; +} +``` + +你将得到: + +```css +article h1 + p, article h2 + p, article h3 + p, article h4 + p, article h5 + p, article h6 + p { + margin-top: 0; +} +``` + +## CSS 语法 + + @custom-selector = @custom-selector ; + + +## 如何使用 + +### 伪元素/伪类 + +你可以使用 + +* `:` 自定义一个伪类。 +* `::`自定义一个伪元素。 + +例如,模拟一个 [:any-link](http://dev.w3.org/csswg/selectors/#the-any-link-pseudo) 选择器: + +示例2: + +input.css: + +```css +@custom-selector :--any-link :link, :visited; + +a:--any-link { + color: blue; +} +``` + +output: + +```css +a:link, a:visited { + color: blue; +} +``` +### 多个选择器 + +`@custom-selector` 类似 CSS [`:matches()`](http://dev.w3.org/csswg/selectors-4/#matches) ([`-moz-any()`](https://developer.mozilla.org/en-US/docs/Web/CSS/:any)/[`-webkit-any()`](http://css-tricks.com/almanac/selectors/m/matches/))选择器,但是目前**不支持**在同一个选择器中调用多个自定义选择器,例如: + +示例3: + +```css +@custom-selector --heading h1, h2, h3, h4, h5, h6; +@custom-selector :--any-link :link, :visited; + +.demo --heading, a:--any-link { + font-size: 32px; +} +``` +将会输出错误的 CSS 代码。 + +### Node Watch + +依赖 [chokidar](#) 模块。 + +```js +var fs = require('fs') +var chokidar = require('chokidar') +var postcss = require('postcss') +var selector = require('postcss-custom-selector') + +var src = 'input.css' + +console.info('Watching…\nModify the input.css and save.') + +chokidar.watch(src, { + ignored: /[\/\\]\./, + persistent: true +}).on('all', + function(event, path, stats) { + var css = fs.readFileSync(src, 'utf8') + var output = postcss(selector()) + .process(css) + .css + fs.writeFileSync('output.css', output) + }) +``` +index.css 文件中的改动保存后将转换到 output.css + +### Grunt + +```js +module.exports = function(grunt) { + grunt.initConfig({ + pkg: grunt.file.readJSON('package.json'), + postcss: { + options: { + processors: [ + require('autoprefixer-core')({ browsers: ['> 0%'] }).postcss, //Other plugin + require('postcss-custom-selector')(), + ] + }, + dist: { + src: ['src/*.css'], + dest: 'build/grunt.css' + } + } + }); + + grunt.loadNpmTasks('grunt-contrib-uglify'); + grunt.loadNpmTasks('grunt-postcss'); + + grunt.registerTask('default', ['postcss']); +} +``` + +### Gulp + +```js +var gulp = require('gulp'); +var rename = require('gulp-rename'); +var postcss = require('gulp-postcss'); +var selector = require('postcss-custom-selector') +var autoprefixer = require('autoprefixer-core') + +gulp.task('default', function () { + var processors = [ + autoprefixer({ browsers: ['> 0%'] }), //Other plugin + selector() + ]; + gulp.src('src/*.css') + .pipe(postcss(processors)) + .pipe(rename('gulp.css')) + .pipe(gulp.dest('build')) +}); +gulp.watch('src/*.css', ['default']); +``` + + + +### 选项 + +**`extensions`** (default: `{}`) + +该选项允许你自定义一个对象来设置 ``(选择器别名)和 ``,这些定义将覆盖 CSS 中相同别名的 `@custom-selector`。 + +```js +var options = { + extensions: { + ':--any' : 'section, article, aside, nav' + } +} + +var output = postcss(selector(options)) + .process(css) + .css; +``` + +input.css + +```css +@custom-selector :--any .foo, .bar; /* 不会生效 */ +:--any h1 { + margin-top: 16px; +} +``` + +output: + +```css +section h1, article h1, aside h1, nav h1 { + margin-top: 16px; +} +``` + + +## 贡献 + +* 安装相关的依赖模块。 +* 尊重编码风格(安装 [EditorConfig](http://editorconfig.org/))。 +* 在[test](test)目录添加测试用例。 +* 运行测试。 + +``` +$ git clone https://github.com/postcss/postcss-custom-selectors.git +$ git checkout -b patch +$ npm install +$ npm test +``` + +## [Changelog](CHANGELOG.md) + +## [License](LICENSE) diff --git a/README.md b/README.md index 71a6c860aa..9a108fd2d7 100644 --- a/README.md +++ b/README.md @@ -1,14 +1,16 @@ -# PostCSS Custom Selectors [![Build Status](https://travis-ci.org/postcss/postcss-custom-selector.svg)](https://travis-ci.org/postcss/postcss-custom-selector) +# PostCSS Custom Selectors [![Build Status](https://travis-ci.org/postcss/postcss-custom-selectors.svg)](https://travis-ci.org/postcss/postcss-custom-selectors) -> [PostCSS](https://github.com/postcss/postcss) 实现 [W3C CSS Extensions(Custom Selectors)](http://dev.w3.org/csswg/css-extensions/#custom-selectors) 的插件。 +> [PostCSS](https://github.com/postcss/postcss) plugin to transform [W3C CSS Extensions(Custom Selectors)](http://dev.w3.org/csswg/css-extensions/#custom-selectors) to more compatible CSS. +[简体中文](README-zh.md) - -## 安装 +## Install $ npm install postcss-custom-selectors -## 快速开始 +## Quick Start + +Example 1: ```js // dependencies @@ -25,10 +27,10 @@ var output = postcss() .process(css) .css -console.log('\n\n ====>Output CSS:\n',output) +console.log('\n====>Output CSS:\n', output) ``` -或者: +Or just: ```js var output = postcss(selector()) @@ -41,48 +43,36 @@ input.css: ```css @custom-selector --heading h1, h2, h3, h4, h5, h6; -article --heading + p{ +article --heading + p { margin-top: 0; } ``` -你将得到: +You will get: ```css -article h1 + p, article h2 + p, article h3 + p, article h4 + p, article h5 + p, article h6 + p{ +article h1 + p, article h2 + p, article h3 + p, article h4 + p, article h5 + p, article h6 + p { margin-top: 0; } ``` -## CSS 语法 - -A custom selector is defined with the `@custom-selector` rule: +## CSS syntax @custom-selector = @custom-selector ; -This defines a custom selector which is written as a pseudo-class with the given ``, and represents a `:matches()` selector using the provided `` as its argument. +## How to use it -For example, if an author wanted to easily refer to all heading elements in their HTML document, they could create an alias: +### Pseudo-element/Pseudo-class -```css -@custom-selector :--heading h1, h2, h3, h4, h5, h6; +You can use -:--heading { /* styles for all headings */ } -:--heading + p { /* more styles */ } -/* etc */ -``` +* `:` to customise a class. +* `::`to customise a Pseudo-element. -## 如何使用 +For example to simulate [:any-link](http://dev.w3.org/csswg/selectors/#the-any-link-pseudo) selector: -### 伪元素/伪类 - -你可以使用 - -* `:` 自定义一个伪类。 -* `::`自定义一个伪元素。 - -例如,模拟一个 :any-link 选择器: +Example 2: input.css: @@ -101,9 +91,11 @@ a:link, a:visited { color: blue; } ``` -### 多个选择器 +### Multiples selectors + +`@custom-selector` similar to CSS [`:matches()`](http://dev.w3.org/csswg/selectors-4/#matches) ([`-moz-any()`](https://developer.mozilla.org/en-US/docs/Web/CSS/:any)/[`-webkit-any()`](http://css-tricks.com/almanac/selectors/m/matches/))selector,But it **doesn’t support** call multiple custom selector in the same selector, e.g. -`@custom-selector` 类似 CSS [`:matches()`](http://dev.w3.org/csswg/selectors-4/#matches) 选择器,但是目前**不支持**在同一个选择器中调用多个自定义选择器,例如: +Example 3: ```css @custom-selector --heading h1, h2, h3, h4, h5, h6; @@ -113,7 +105,34 @@ a:link, a:visited { font-size: 32px; } ``` -将会输出错误的 CSS 代码。 +This will throw an error CSS code. + +### Node Watch + +Dependence [chokidar](#) module. + +```js +var fs = require('fs') +var chokidar = require('chokidar') +var postcss = require('postcss') +var selector = require('postcss-custom-selector') + +var src = 'input.css' + +console.info('Watching…\nModify the input.css and save.') + +chokidar.watch(src, { + ignored: /[\/\\]\./, + persistent: true +}).on('all', + function(event, path, stats) { + var css = fs.readFileSync(src, 'utf8') + var output = postcss(selector()) + .process(css) + .css + fs.writeFileSync('output.css', output) + }) +``` ### Grunt @@ -166,11 +185,11 @@ gulp.watch('src/*.css', ['default']); -### 选项 +### Options -**`extensions`** (默认: `{}`) +**`extensions`** (default: `{}`) -该选项允许你自定义一个对象来设置 ``(选择器别名)和 ``,这些定义将覆盖 CSS 中相同别名的 `@custom-selector`。 +This option allows you to customize an object to set the `` (selector alias) and ``, these definitions will cover the same alias of `@custom-selector` in CSS. ```js var options = { @@ -202,11 +221,12 @@ section h1, article h1, aside h1, nav h1 { ``` -## 贡献 +## Contribution -* 安装相关依赖模块 -* 尊重编码风格(安装 [EditorConfig](http://editorconfig.org/)) -* 运行测试 +* Install the relevant dependent module. +* Respect coding style(Install [EditorConfig](http://editorconfig.org/)). +* Adding test cases in the [test](test) directory. +* Run tests. ``` $ git clone https://github.com/postcss/postcss-custom-selectors.git diff --git a/package.json b/package.json index e92bd62e52..e71788bd8b 100644 --- a/package.json +++ b/package.json @@ -1,22 +1,24 @@ { - "name": "postcss-custom-selector", + "name": "postcss-custom-selectors", "version": "1.0.0", - "description": "PostCSS plugin", + "description": "PostCSS plugin to transform W3C CSS Extensions(Custom Selectors) to more compatible CSS", "keywords": [ "css", + "css3" "postcss", "postcss-plugins", "selector", - "custom selector" + "custom-selector" ], "author": "yisi", "license": "MIT", "repository": { "type": "git", - "url": "https://github.com/postcss/postcss-custom-selector.git" + "url": "https://github.com/postcss/postcss-custom-selectors.git" }, "files": [ "CHANGELOG.md", + "README-zh.md", "LICENSE", "index.js" ], From 5e6e69f68a9f6e8c63442cd3a2c325d19a019d94 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D2=BC=CB=BF?= Date: Fri, 5 Dec 2014 22:48:37 +0800 Subject: [PATCH 114/795] Updated translation --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 9a108fd2d7..69cb8ab35c 100644 --- a/README.md +++ b/README.md @@ -206,7 +206,7 @@ var output = postcss(selector(options)) input.css ```css -@custom-selector :--any .foo, .bar; /* 不会生效 */ +@custom-selector :--any .foo, .bar; /* No effect */ :--any h1 { margin-top: 16px; } @@ -228,7 +228,7 @@ section h1, article h1, aside h1, nav h1 { * Adding test cases in the [test](test) directory. * Run tests. -``` +```console $ git clone https://github.com/postcss/postcss-custom-selectors.git $ git checkout -b patch $ npm install From 42c7d98d44ab576237d09445d8cc79454a1a761f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D2=BC=CB=BF?= Date: Fri, 5 Dec 2014 22:51:58 +0800 Subject: [PATCH 115/795] update doc --- README-zh.md | 2 +- README.md | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/README-zh.md b/README-zh.md index 67da4074a3..6dd0ef4079 100644 --- a/README-zh.md +++ b/README-zh.md @@ -109,7 +109,7 @@ a:link, a:visited { ### Node Watch -依赖 [chokidar](#) 模块。 +依赖 [chokidar](https://github.com/paulmillr/chokidar) 模块。 ```js var fs = require('fs') diff --git a/README.md b/README.md index 69cb8ab35c..1d1b36f8ec 100644 --- a/README.md +++ b/README.md @@ -93,7 +93,7 @@ a:link, a:visited { ``` ### Multiples selectors -`@custom-selector` similar to CSS [`:matches()`](http://dev.w3.org/csswg/selectors-4/#matches) ([`-moz-any()`](https://developer.mozilla.org/en-US/docs/Web/CSS/:any)/[`-webkit-any()`](http://css-tricks.com/almanac/selectors/m/matches/))selector,But it **doesn’t support** call multiple custom selector in the same selector, e.g. +`@custom-selector` similar to CSS [`:matches()`](http://dev.w3.org/csswg/selectors-4/#matches)([`-moz-any()`](https://developer.mozilla.org/en-US/docs/Web/CSS/:any)/[`-webkit-any()`](http://css-tricks.com/almanac/selectors/m/matches/))selector,but it **doesn’t support** call multiple custom selector in the same selector, e.g. Example 3: @@ -109,7 +109,7 @@ This will throw an error CSS code. ### Node Watch -Dependence [chokidar](#) module. +Dependence [chokidar](https://github.com/paulmillr/chokidar) module. ```js var fs = require('fs') From 59102f13a99c018ccb0675cb7f35186952a5729a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D2=BC=CB=BF?= Date: Fri, 5 Dec 2014 23:03:27 +0800 Subject: [PATCH 116/795] add gif --- README-zh.md | 2 ++ README.md | 2 ++ 2 files changed, 4 insertions(+) diff --git a/README-zh.md b/README-zh.md index 6dd0ef4079..0c653c127b 100644 --- a/README-zh.md +++ b/README-zh.md @@ -4,6 +4,8 @@ [English](README.md) +![GIF Demo](http://v2.freep.cn/3tb_141205230116f6ky512293.gif) + ## 安装 $ npm install postcss-custom-selectors diff --git a/README.md b/README.md index 1d1b36f8ec..058c98d1d4 100644 --- a/README.md +++ b/README.md @@ -4,6 +4,8 @@ [简体中文](README-zh.md) +![GIF Demo](http://v2.freep.cn/3tb_141205230116f6ky512293.gif) + ## Install $ npm install postcss-custom-selectors From de408abadf3baf2c8bd8925b457a2c44022da89f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D2=BC=CB=BF?= Date: Fri, 5 Dec 2014 23:13:19 +0800 Subject: [PATCH 117/795] update gif url --- README-zh.md | 2 +- README.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/README-zh.md b/README-zh.md index 0c653c127b..3e6687fafe 100644 --- a/README-zh.md +++ b/README-zh.md @@ -4,7 +4,7 @@ [English](README.md) -![GIF Demo](http://v2.freep.cn/3tb_141205230116f6ky512293.gif) +![GIF Demo](http://gtms01.alicdn.com/tps/i1/TB1ZCe3GVXXXXbzXFXXRi48IXXX-780-610.gif) ## 安装 diff --git a/README.md b/README.md index 058c98d1d4..e5e319b6ec 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@ [简体中文](README-zh.md) -![GIF Demo](http://v2.freep.cn/3tb_141205230116f6ky512293.gif) +![GIF Demo](http://gtms01.alicdn.com/tps/i1/TB1ZCe3GVXXXXbzXFXXRi48IXXX-780-610.gif) ## Install From 9988e49fab48e617b2d0570f9be0428441861ac7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=B8=80=E4=B8=9D?= Date: Fri, 5 Dec 2014 23:34:47 +0800 Subject: [PATCH 118/795] Update package.json --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index e71788bd8b..a6e7f319de 100644 --- a/package.json +++ b/package.json @@ -4,7 +4,7 @@ "description": "PostCSS plugin to transform W3C CSS Extensions(Custom Selectors) to more compatible CSS", "keywords": [ "css", - "css3" + "css3", "postcss", "postcss-plugins", "selector", From 1df6d6fcb3ea4bdaaf281b545d37dfa4cf3294f2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=B8=80=E4=B8=9D?= Date: Fri, 5 Dec 2014 23:54:14 +0800 Subject: [PATCH 119/795] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index e5e319b6ec..8fb2e762b8 100644 --- a/README.md +++ b/README.md @@ -93,7 +93,7 @@ a:link, a:visited { color: blue; } ``` -### Multiples selectors +### Multiple selectors `@custom-selector` similar to CSS [`:matches()`](http://dev.w3.org/csswg/selectors-4/#matches)([`-moz-any()`](https://developer.mozilla.org/en-US/docs/Web/CSS/:any)/[`-webkit-any()`](http://css-tricks.com/almanac/selectors/m/matches/))selector,but it **doesn’t support** call multiple custom selector in the same selector, e.g. From 4813a5b9b455fd5ef6e07d4adbac9ac62f9d7f81 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D2=BC=CB=BF?= Date: Sat, 6 Dec 2014 12:08:21 +0800 Subject: [PATCH 120/795] Add lineBreak option --- CHANGELOG.md | 4 ++-- README-zh.md | 26 +++++++++++++++++++++++++- README.md | 26 +++++++++++++++++++++++++- index.js | 8 +++++++- 4 files changed, 59 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2b2be502ad..e4719cd822 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,3 @@ -# 1.0.0 - 2014-12-04 +# 1.0.0 - 2014-12-06 -First release +First release diff --git a/README-zh.md b/README-zh.md index 3e6687fafe..150fd3b295 100644 --- a/README-zh.md +++ b/README-zh.md @@ -190,7 +190,31 @@ gulp.watch('src/*.css', ['default']); ### 选项 -**`extensions`** (default: `{}`) +#### 1. **`lineBreak`**(default: `true`) + +设置多个选择器是否换行,默认开启换行。 + +关闭换行: + +```js +var options = { + lineBreak: false +} + +var output = postcss(selector(options)) + .process(css) + .css +``` + +「示例1」中的 `input.css` 将输出为: + +```css +article h1 + p, article h2 + p, article h3 + p, article h4 + p, article h5 + p, article h6 + p { + margin-top: 0; +} +``` + +#### 2. **`extensions`** (default: `{}`) 该选项允许你自定义一个对象来设置 ``(选择器别名)和 ``,这些定义将覆盖 CSS 中相同别名的 `@custom-selector`。 diff --git a/README.md b/README.md index e5e319b6ec..e7f60789bf 100644 --- a/README.md +++ b/README.md @@ -189,7 +189,31 @@ gulp.watch('src/*.css', ['default']); ### Options -**`extensions`** (default: `{}`) +#### 1. **`lineBreak`**(default: `true`) + +Setting multiple selector whether wrap. + +Close the line breaks. + +```js +var options = { + lineBreak: false +} + +var output = postcss(selector(options)) + .process(css) + .css +``` + +In the 'Example 1' `input.css` will output: + +```css +article h1 + p, article h2 + p, article h3 + p, article h4 + p, article h5 + p, article h6 + p { + margin-top: 0; +} +``` + +#### 2. **`extensions`** (default: `{}`) This option allows you to customize an object to set the `` (selector alias) and ``, these definitions will cover the same alias of `@custom-selector` in CSS. diff --git a/index.js b/index.js index 05588d0bd0..93e670f780 100644 --- a/index.js +++ b/index.js @@ -17,6 +17,7 @@ function customSelector(options) { return function(styles) { options = options || {} var extensions = options.extensions || {} + var line_break = '\n' var map = {} var toRemove = [] var customSelectors = {} @@ -47,6 +48,11 @@ function customSelector(options) { customSelectors[extension] = extensions[extension] }) + //控制选择器是否换行 + if (!options.lineBreak && options.lineBreak == false) { + line_break = ' ' + } + // 转换自定义的选择器别名 styles.eachRule(function(rule) { for (var prop in customSelectors) { @@ -58,7 +64,7 @@ function customSelector(options) { if ($2 == prop) { return customSelector.split(",").map(function(selector) { return $1 + selector.trim() + $3 - }).join(", ") + }).join("," + line_break) } }) From cc35989547e9dd09501eb58cf2c513b2ebd32fa5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D2=BC=CB=BF?= Date: Sat, 6 Dec 2014 14:50:10 +0800 Subject: [PATCH 121/795] Because the default wrap, modify the document and test file. --- README-zh.md | 29 +++++++++++++++++++++----- README.md | 31 +++++++++++++++++++++++----- test/fixtures/extension.expected.css | 8 +++++-- test/fixtures/heading.css | 2 +- test/fixtures/heading.expected.css | 7 ++++++- test/fixtures/pseudo.expected.css | 3 ++- 6 files changed, 65 insertions(+), 15 deletions(-) diff --git a/README-zh.md b/README-zh.md index 150fd3b295..113d4ad332 100644 --- a/README-zh.md +++ b/README-zh.md @@ -53,7 +53,12 @@ article --heading + p { 你将得到: ```css -article h1 + p, article h2 + p, article h3 + p, article h4 + p, article h5 + p, article h6 + p { +article h1 + p, +article h2 + p, +article h3 + p, +article h4 + p, +article h5 + p, +article h6 + p { margin-top: 0; } ``` @@ -89,7 +94,8 @@ a:--any-link { output: ```css -a:link, a:visited { +a:link, +a:visited { color: blue; } ``` @@ -109,6 +115,17 @@ a:link, a:visited { ``` 将会输出错误的 CSS 代码。 +```css +.demo h1, +.demo h2, +.demo h3, +.demo h4, +.demo h5, +.demo h6,undefined { + font-size: 32px; +} +``` + ### Node Watch 依赖 [chokidar](https://github.com/paulmillr/chokidar) 模块。 @@ -135,7 +152,6 @@ chokidar.watch(src, { fs.writeFileSync('output.css', output) }) ``` -index.css 文件中的改动保存后将转换到 output.css ### Grunt @@ -233,8 +249,11 @@ var output = postcss(selector(options)) input.css ```css -@custom-selector :--any .foo, .bar; /* 不会生效 */ -:--any h1 { +/* 不会生效 */ +section h1, +article h1, +aside h1, +nav h1 { margin-top: 16px; } ``` diff --git a/README.md b/README.md index ef9e5ebc92..74c3c4958f 100644 --- a/README.md +++ b/README.md @@ -53,7 +53,12 @@ article --heading + p { You will get: ```css -article h1 + p, article h2 + p, article h3 + p, article h4 + p, article h5 + p, article h6 + p { +article h1 + p, +article h2 + p, +article h3 + p, +article h4 + p, +article h5 + p, +article h6 + p { margin-top: 0; } ``` @@ -63,7 +68,7 @@ article h1 + p, article h2 + p, article h3 + p, article h4 + p, article h5 + p, @custom-selector = @custom-selector ; -## How to use it +## How to use ### Pseudo-element/Pseudo-class @@ -89,7 +94,8 @@ a:--any-link { output: ```css -a:link, a:visited { +a:link, +a:visited { color: blue; } ``` @@ -109,6 +115,17 @@ Example 3: ``` This will throw an error CSS code. +```css +.demo h1, +.demo h2, +.demo h3, +.demo h4, +.demo h5, +.demo h6,undefined { + font-size: 32px; +} +``` + ### Node Watch Dependence [chokidar](https://github.com/paulmillr/chokidar) module. @@ -191,7 +208,7 @@ gulp.watch('src/*.css', ['default']); #### 1. **`lineBreak`**(default: `true`) -Setting multiple selector whether wrap. +Set whether multiple selector wrap.The default is turning on to be a newline. Close the line breaks. @@ -241,7 +258,11 @@ input.css output: ```css -section h1, article h1, aside h1, nav h1 { +/* No effect */ +section h1, +article h1, +aside h1, +nav h1 { margin-top: 16px; } ``` diff --git a/test/fixtures/extension.expected.css b/test/fixtures/extension.expected.css index c9752cba5c..6cff275e56 100644 --- a/test/fixtures/extension.expected.css +++ b/test/fixtures/extension.expected.css @@ -1,7 +1,11 @@ -section h1, article h1, aside h1, nav h1 { +section h1, +article h1, +aside h1, +nav h1 { margin-top: 16px; } -main input[type="text"] > section + p, main #nav .bar + p { +main input[type="text"] > section + p, +main #nav .bar + p { margin-top: 16px; } diff --git a/test/fixtures/heading.css b/test/fixtures/heading.css index 2394abfe4f..5f0a1b5616 100644 --- a/test/fixtures/heading.css +++ b/test/fixtures/heading.css @@ -1,5 +1,5 @@ @custom-selector --heading h1, h2, h3, h4, h5, h6; -article --heading + p{ +article --heading + p { margin-top: 0; } diff --git a/test/fixtures/heading.expected.css b/test/fixtures/heading.expected.css index 0123afc237..a7ea6b4854 100644 --- a/test/fixtures/heading.expected.css +++ b/test/fixtures/heading.expected.css @@ -1,3 +1,8 @@ -article h1 + p, article h2 + p, article h3 + p, article h4 + p, article h5 + p, article h6 + p{ +article h1 + p, +article h2 + p, +article h3 + p, +article h4 + p, +article h5 + p, +article h6 + p { margin-top: 0; } diff --git a/test/fixtures/pseudo.expected.css b/test/fixtures/pseudo.expected.css index 64b516a74a..69a6404172 100644 --- a/test/fixtures/pseudo.expected.css +++ b/test/fixtures/pseudo.expected.css @@ -1,3 +1,4 @@ -.foo > a::before img, .foo > a::after img { +.foo > a::before img, +.foo > a::after img { display: block; } From 67fcda48f4a1f822278be639baf00f02569691da Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D2=BC=CB=BF?= Date: Sat, 6 Dec 2014 15:00:21 +0800 Subject: [PATCH 122/795] Release 1.1.0 --- CHANGELOG.md | 4 ++++ package.json | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e4719cd822..809d294036 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,7 @@ +# 1.1.0 - 2014-12-06 + +Add "lineBreak" option + # 1.0.0 - 2014-12-06 First release diff --git a/package.json b/package.json index a6e7f319de..c9228d58c5 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "postcss-custom-selectors", - "version": "1.0.0", + "version": "1.1.0", "description": "PostCSS plugin to transform W3C CSS Extensions(Custom Selectors) to more compatible CSS", "keywords": [ "css", From 9fcb5ce57a264592121f13bc5cf14bf2b9e62b89 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=B8=80=E4=B8=9D?= Date: Sat, 6 Dec 2014 20:11:21 +0800 Subject: [PATCH 123/795] Update README.md --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 74c3c4958f..9b8673dcb0 100644 --- a/README.md +++ b/README.md @@ -268,12 +268,12 @@ nav h1 { ``` -## Contribution +## Contributing * Install the relevant dependent module. * Respect coding style(Install [EditorConfig](http://editorconfig.org/)). * Adding test cases in the [test](test) directory. -* Run tests. +* Run test. ```console $ git clone https://github.com/postcss/postcss-custom-selectors.git From adf671e0b14fba70b303977482a1fb493cb87b7a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=B8=80=E4=B8=9D?= Date: Sat, 6 Dec 2014 20:26:25 +0800 Subject: [PATCH 124/795] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 9b8673dcb0..d12185edbe 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,7 @@ ![GIF Demo](http://gtms01.alicdn.com/tps/i1/TB1ZCe3GVXXXXbzXFXXRi48IXXX-780-610.gif) -## Install +## Installation $ npm install postcss-custom-selectors From dbaacb2f36a2bf717e1ff1099cdeb5063cf132af Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=B8=80=E4=B8=9D?= Date: Sun, 7 Dec 2014 23:41:16 +0800 Subject: [PATCH 125/795] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index d12185edbe..0f6ce43587 100644 --- a/README.md +++ b/README.md @@ -272,7 +272,7 @@ nav h1 { * Install the relevant dependent module. * Respect coding style(Install [EditorConfig](http://editorconfig.org/)). -* Adding test cases in the [test](test) directory. +* Add test cases in the [test](test) directory. * Run test. ```console From c874fe1859747cd38aa53f8b1e490fbd0ff2609f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=B8=80=E4=B8=9D?= Date: Thu, 11 Dec 2014 19:12:09 +0800 Subject: [PATCH 126/795] Initial commit --- LICENSE | 22 ++++++++++++++++++++++ README.md | 4 ++++ 2 files changed, 26 insertions(+) create mode 100644 LICENSE create mode 100644 README.md diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000000..9d10f01975 --- /dev/null +++ b/LICENSE @@ -0,0 +1,22 @@ +The MIT License (MIT) + +Copyright (c) 2014 PostCSS + +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. + diff --git a/README.md b/README.md new file mode 100644 index 0000000000..896a935715 --- /dev/null +++ b/README.md @@ -0,0 +1,4 @@ +postcss-media-minmax +==================== + +Media Queries min/max prefix shorthand From ba3927bdd6a5da61f827d7bdb30b98dc0c15f569 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=B8=80=E4=B8=9D?= Date: Thu, 11 Dec 2014 19:34:27 +0800 Subject: [PATCH 127/795] first commit --- .editorconfig | 13 +++++++++++++ .gitignore | 5 +++++ .travis.yml | 1 + README-zh.md | 7 +++++++ README.md | 7 +++++-- 5 files changed, 31 insertions(+), 2 deletions(-) create mode 100644 .editorconfig create mode 100644 .gitignore create mode 100644 .travis.yml create mode 100644 README-zh.md diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000000..dffb18adfb --- /dev/null +++ b/.editorconfig @@ -0,0 +1,13 @@ +# editorconfig.org +root = true + +[*] +charset = utf-8 +indent_style = space +indent_size = 2 +end_of_line = lf +trim_trailing_whitespace = true +insert_final_newline = true + +[*.md] +trim_trailing_whitespace = false diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000000..bf008057d6 --- /dev/null +++ b/.gitignore @@ -0,0 +1,5 @@ +.DS_Store +node_modules +test/fixtures/*.actual.css +*.sublime-workspace + diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000000..587bd3e031 --- /dev/null +++ b/.travis.yml @@ -0,0 +1 @@ +language: node_js diff --git a/README-zh.md b/README-zh.md new file mode 100644 index 0000000000..a99b2f668e --- /dev/null +++ b/README-zh.md @@ -0,0 +1,7 @@ +# PostCSS Media Minmax + +----- + +Media Queries min/max prefix shorthand + +![Gif Demo](http://gtms02.alicdn.com/tps/i2/TB1UIjyGVXXXXcCaXXXx274FpXX-877-339.gif) diff --git a/README.md b/README.md index 896a935715..a99b2f668e 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,7 @@ -postcss-media-minmax -==================== +# PostCSS Media Minmax + +----- Media Queries min/max prefix shorthand + +![Gif Demo](http://gtms02.alicdn.com/tps/i2/TB1UIjyGVXXXXcCaXXXx274FpXX-877-339.gif) From d3301a04f1321ada0805133ae16773321579d058 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=B8=80=E4=B8=9D?= Date: Sat, 13 Dec 2014 22:03:00 +0800 Subject: [PATCH 128/795] add doc and index.js --- CHANGELOG.md | 0 README-zh.md | 255 +++++++++++++++++++++++++++++++++++++++++++++++++- README.md | 260 ++++++++++++++++++++++++++++++++++++++++++++++++++- index.js | 73 +++++++++++++++ package.json | 36 +++++++ 5 files changed, 620 insertions(+), 4 deletions(-) create mode 100644 CHANGELOG.md create mode 100644 index.js create mode 100644 package.json diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000000..e69de29bb2 diff --git a/README-zh.md b/README-zh.md index a99b2f668e..94bdde16af 100644 --- a/README-zh.md +++ b/README-zh.md @@ -1,7 +1,258 @@ # PostCSS Media Minmax ------ +> 写简单优雅的 Media Queries! + +Media Queries 中的 `min-width` 和 `max-width` 等属性非常容易混淆,每次看到他们,我都想哭。现在[新的规范](http://dev.w3.org/csswg/mediaqueries/#mq-min-max)中,可以使用更加直观的 `>=`或`<=` 替代 media queries 中的 min-/max- 前缀。 + +这是一个实现 CSS Media Queries Level 4 Polyfill 的插件,让你现在就可以使用这些特性,妈妈再也不用担心我记不住了,鹅妹子嘤! + + +[English](README.md) -Media Queries min/max prefix shorthand +----- ![Gif Demo](http://gtms02.alicdn.com/tps/i2/TB1UIjyGVXXXXcCaXXXx274FpXX-877-339.gif) + + +## 安装 + + $ npm install postcss-media-minmax + +## 快速开始 + +示例 1: + +```js +var fs = require('fs') +var postcss = require('postcss') +var minmax = require('postcss-media-minmax') + +var css = fs.readFileSync('input.css', 'utf8') + +var output = postcss() + .use(minmax()) + .process(css) + .css + +console.log('\n====>Output CSS:\n', output) +``` + +或者只需: + +```js +var output = postcss(minmax()) + .process(css) + .css +``` + +input.css: + +```css +@media screen and (width >= 500px) and (width <= 1200px) { + .bar { + display: block; + } +} +``` + +你将得到: + +```css +@media screen and (min-width: 500px) and (max-width: 1200px) { + .bar { + display: block; + } +} +``` + +## CSS 语法 + +``` + = [ '<' | '>' ]? '='? + | [ '<' | '>' ]? '='? + | '<' '='? '<' '='? + | '>' '='? '>' '='? +``` + + +## 如何使用 + +### 简写 + +示例 1中同一个 feature name 同时存在 `>=` 和 `<=` 时,可以简写为: + +```css +@media screen and (500px <= width <= 1200px) { + .bar { + display: block; + } +} +/* 或者 */ +@media screen and (1200px >= width >= 500px) { + .bar { + display: block; + } +} +``` + +都会得到一样的输出结果: + +```css +@media screen and (min-width: 500px) and (max-width: 1200px) { + .bar { + display: block; + } +} +``` +**注意**:当 feature name 在中间的时候,一定要保证两个 `<=` 或 `>=` 的方向一致,否则不会转换。 + +例如在下面的示例中,width 大于等于 500px 同时又大于等于 1200px,这在语法和逻辑上都是错误的。 + +```css +@media screen and (1200px <= width >= 500px) { + .bar { + display: block; + } +} +``` + +### 支持的 feature name + +规范中目前以下属性支持 min-/max 前缀,PostCSS Media Minmax 全部支持自动转换。 + +* `width` +* `height` +* `device-width` +* `device-height` +* `aspect-ratio` +* `device-aspect-ratio` +* `color` +* `color-index` +* `monochrome` +* `resolution` + + + +### 支持在 `@custom-media` 中使用 & Node Watch + +```js +var fs = require('fs') +var chokidar = require('chokidar') +var postcss = require('postcss') +var minmax = require('minmax') +var customMedia = require('postcss-custom-media') + +var src = 'input.css' + +console.info('Watching…\nModify the input.css and save.') + + +chokidar.watch(src, { + ignored: /[\/\\]\./, + persistent: true +}).on('all', + function(event, path, stats) { + var css = fs.readFileSync(src, 'utf8') + var output = postcss() + .use(customMedia()) + .use(minmax()) + .process(css) + .css; + fs.writeFileSync('output.css', output) + }) + +``` + + +input.css: + +```css +@custom-media --foo (width >= 20em) and (width <= 50em); +@custom-media --bar (height >= 300px) and (height <= 600px); + +@media (--foo) and (--bar) { + +} +``` + +output.css: + +```css +@media (min-width: 20em) and (max-width: 50em) and (min-height: 300px) and (max-height: 600px) { + +} +``` + +### Grunt + +```js +module.exports = function(grunt) { + grunt.initConfig({ + pkg: grunt.file.readJSON('package.json'), + postcss: { + options: { + processors: [ + require('autoprefixer-core')({ browsers: ['> 0%'] }).postcss, //Other plugin + require('postcss-media-minmax')(), + ] + }, + dist: { + src: ['src/*.css'], + dest: 'build/grunt.css' + } + } + }); + + grunt.loadNpmTasks('grunt-contrib-uglify'); + grunt.loadNpmTasks('grunt-postcss'); + + grunt.registerTask('default', ['postcss']); +} +``` + +### Gulp + +```js +var gulp = require('gulp'); +var rename = require('gulp-rename'); +var postcss = require('gulp-postcss'); +var selector = require('postcss-media-minmax') +var autoprefixer = require('autoprefixer-core') + +gulp.task('default', function () { + var processors = [ + autoprefixer({ browsers: ['> 0%'] }), //Other plugin + minmax() + ]; + gulp.src('src/*.css') + .pipe(postcss(processors)) + .pipe(rename('gulp.css')) + .pipe(gulp.dest('build')) +}); +gulp.watch('src/*.css', ['default']); +``` + + +## 贡献 + +* 安装相关的依赖模块。 +* 尊重编码风格(安装 [EditorConfig](http://editorconfig.org/))。 +* 在[test](test)目录添加测试用例。 +* 运行测试。 + +``` +$ git clone https://github.com/postcss/postcss-media-minmaxs.git +$ git checkout -b patch +$ npm install +$ npm test +``` + +## 致谢 + +* 感谢 PostCSS 作者 [Andrey Sitnik](https://github.com/ai),带给我们如此简单易用的 CSS 语法解析工具。 +* 感谢 [Tab Atkins Jr.](http://xanthir.com/contact/) 辛苦编写了 Media Queries Level 4 规范。 +* 感谢 [@紫云飞](http://weibo.com/p/1005051708684567) 对本插件的建议和帮助。 + +## [Changelog](CHANGELOG.md) + +## [License](LICENSE) diff --git a/README.md b/README.md index a99b2f668e..f60cd84581 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,263 @@ # PostCSS Media Minmax ------ +> Writing simple and graceful Media Queries! + +The `min-width`,`max-width` and so on propertys of Media Queries is really easy to confuse, every time I see them, I want to cry. Right now in the new specs, you can use more intuitive <= or >= to instead of the min-/max- prefix of media queries. + +This is a supporting CSS Media Queries Level 4 Polyfill plugin,which let you can ues these features right now. Mom won't never worry about my study, so amazing! -Media Queries min/max prefix shorthand + +[简体中文](README-zh.md) + +----- ![Gif Demo](http://gtms02.alicdn.com/tps/i2/TB1UIjyGVXXXXcCaXXXx274FpXX-877-339.gif) + + +## Installation + + $ npm install postcss-media-minmax + +## Quick Start + +Example 1: + +```js +var fs = require('fs') +var postcss = require('postcss') +var minmax = require('postcss-media-minmax') + +var css = fs.readFileSync('input.css', 'utf8') + +var output = postcss() + .use(minmax()) + .process(css) + .css + +console.log('\n====>Output CSS:\n', output) +``` + +Or just: + +```js +var output = postcss(minmax()) + .process(css) + .css +``` + +input.css: + +```css +@media screen and (width >= 500px) and (width <= 1200px) { + .bar { + display: block; + } +} +``` + +You will get: + +```css +@media screen and (min-width: 500px) and (max-width: 1200px) { + .bar { + display: block; + } +} +``` + +## CSS syntax + +``` + = [ '<' | '>' ]? '='? + | [ '<' | '>' ]? '='? + | '<' '='? '<' '='? + | '>' '='? '>' '='? +``` + + +## How to use + +### Shorthand + +In Example 1, the same feature name is `>=` and `<=`, which will be abbreviated as the following: + +```css +@media screen and (500px <= width <= 1200px) { + .bar { + display: block; + } +} +/* Or */ +@media screen and (1200px >= width >= 500px) { + .bar { + display: block; + } +} +``` + +Will get the same output results: + +```css +@media screen and (min-width: 500px) and (max-width: 1200px) { + .bar { + display: block; + } +} +``` + +**Note**: when the feature name in the middle, we must ensure that two `<=` or `>=` in the same direction, otherwise which will not be converted. + +E.g. in the example below, width is greater than or equal to 500px and is greater than or equal to 1200px, this is the wrong in grammar and logic. + + +```css +@media screen and (1200px <= width >= 500px) { + .bar { + display: block; + } +} +``` + +### feature name + +The following property supports the min-/max prefix in specification at present, which will be automatically converted by PostCSS Media Minmax. + +* `width` +* `height` +* `device-width` +* `device-height` +* `aspect-ratio` +* `device-aspect-ratio` +* `color` +* `color-index` +* `monochrome` +* `resolution` + + + +### Support for use in `@custom-media` & Node Watch + +```js +var fs = require('fs') +var chokidar = require('chokidar') +var postcss = require('postcss') +var minmax = require('minmax') +var customMedia = require('postcss-custom-media') + +var src = 'input.css' + +console.info('Watching…\nModify the input.css and save.') + + +chokidar.watch(src, { + ignored: /[\/\\]\./, + persistent: true +}).on('all', + function(event, path, stats) { + var css = fs.readFileSync(src, 'utf8') + var output = postcss() + .use(customMedia()) + .use(minmax()) + .process(css) + .css; + fs.writeFileSync('output.css', output) + }) + +``` + + +input.css: + +```css +@custom-media --foo (width >= 20em) and (width <= 50em); +@custom-media --bar (height >= 300px) and (height <= 600px); + +@media (--foo) and (--bar) { + +} +``` + +output.css: + +```css +@media (min-width: 20em) and (max-width: 50em) and (min-height: 300px) and (max-height: 600px) { + +} +``` + +### Grunt + +```js +module.exports = function(grunt) { + grunt.initConfig({ + pkg: grunt.file.readJSON('package.json'), + postcss: { + options: { + processors: [ + require('autoprefixer-core')({ browsers: ['> 0%'] }).postcss, //Other plugin + require('postcss-media-minmax')(), + ] + }, + dist: { + src: ['src/*.css'], + dest: 'build/grunt.css' + } + } + }); + + grunt.loadNpmTasks('grunt-contrib-uglify'); + grunt.loadNpmTasks('grunt-postcss'); + + grunt.registerTask('default', ['postcss']); +} +``` + +### Gulp + +```js +var gulp = require('gulp'); +var rename = require('gulp-rename'); +var postcss = require('gulp-postcss'); +var selector = require('postcss-media-minmax') +var autoprefixer = require('autoprefixer-core') + +gulp.task('default', function () { + var processors = [ + autoprefixer({ browsers: ['> 0%'] }), //Other plugin + minmax() + ]; + gulp.src('src/*.css') + .pipe(postcss(processors)) + .pipe(rename('gulp.css')) + .pipe(gulp.dest('build')) +}); +gulp.watch('src/*.css', ['default']); +``` + + +## Contributing + +* Install the relevant dependent module. +* Respect coding style(Use [EditorConfig](http://editorconfig.org/)). +* Add test cases in the [test](test) directory. +* Run test. + +``` +$ git clone https://github.com/postcss/postcss-media-minmaxs.git +$ git checkout -b patch +$ npm install +$ npm test +``` + +## Acknowledgements + +* Thank the author of PostCSS [Andrey Sitnik](https://github.com/ai) for giving us so simple and easy CSS syntax analysis tools. + +* Thank [Tab Atkins Jr.](http://xanthir.com/contact/) for writing the specs of Media Queries Level 4. + +* Thank [ziyunfei](http://weibo.com/p/1005051708684567) for suggestion and help of this plugin. + + +## [Changelog](CHANGELOG.md) + +## [License](LICENSE) diff --git a/index.js b/index.js new file mode 100644 index 0000000000..1c411149fd --- /dev/null +++ b/index.js @@ -0,0 +1,73 @@ +module.exports = mediaMinmax + + +function mediaMinmax() { + return function(css) { + //支持 min-/max- 前缀的属性 + var feature_name = [ + 'width', + 'height', + 'device-width', + 'device-height', + 'aspect-ratio', + 'device-aspect-ratio', + 'color', + 'color-index', + 'monochrome', + 'resolution' + ] + + // 读取 media-feature + css.eachAtRule(function(rule, i) { + if (rule.name !== "media" && rule.name !== "custom-media") { + return + } + + /** + * 转换 <=|>= + * $1 $2 $3 + * (width >= 300px) => (min-width: 300px) + * (width <= 900px) => (max-width: 900px) + */ + + rule.params = rule.params.replace(/\(\s*([a-z-]+?)\s*([<>]=)\s*((?:-?\d*\.?\d+[a-z]*)?)\s*\)/gi, function($0, $1, $2, $3) { + + var params = ''; + + if (feature_name.indexOf($1) > -1) { + if ($2 === '<=') { + params = '(' + 'max-' + $1 + ': ' + $3 + ')'; + } + if ($2 === '>=') { + params += '(' + 'min-' + $1 + ': ' + $3 + ')'; + } + return params; + } + //如果不是指定的属性,不做替换 + return $0; + }) + + /** + * 转换 <=|>= <=|>= + * $1 $2 $3 $4 $5 + * (500px <= width <= 1200px) => (min-width: 500px) and (max-width: 1200px) + * (900px >= width >= 300px) => (min-width: 300px) and (max-width: 900px) + */ + + rule.params = rule.params.replace(/\(\s*((?:-?\d*\.?\d+[a-z]*)?)\s*(<=|>=)\s*([a-z-]+)\s*(<=|>=)\s*((?:-?\d*\.?\d+[a-z]*)?)\s*\)/gi, function($0, $1, $2, $3, $4, $5) { + + if (feature_name.indexOf($3) > -1) { + if ($2 === '<=' && $4 === '<=' || $2 === '>=' && $4 === '>=') { + var min = ($2 === '<=') ? $1 : $5; + var max = ($2 === '<=') ? $5 : $1; + return '(' + 'min-' + $3 + ': ' + min + ') and (' + 'max-' + $3 + ': ' + max + ')'; + } + } + //如果不是指定的属性,不做替换 + return $0; + + }); + }); + + } +} diff --git a/package.json b/package.json new file mode 100644 index 0000000000..153d978ac2 --- /dev/null +++ b/package.json @@ -0,0 +1,36 @@ +{ + "name": "postcss-media-minmax", + "version": "1.0.0", + "description": "Writing simple and graceful Media Queries!Using more intuitive `>=` or `<=` instead of media queries min/max prefix.", + "main": "index.js", + "scripts": { + "test": "tape test" + }, + "repository": { + "type": "git", + "url": "https://github.com/postcss/postcss-media-minmax.git" + }, + "keywords": [ + "css", + "css3", + "postcss", + "postcss-plugins", + "Media Queries" + ], + "author": "yisi", + "license": "MIT", + "files": [ + "CHANGELOG.md", + "README-zh.md", + "LICENSE", + "index.js" + ], + "devDependencies": { + "postcss": "^3.0.7", + "tape": "^3.0.0" + }, + "bugs": { + "url": "https://github.com/postcss/postcss-media-minmax/issues" + }, + "homepage": "https://github.com/postcss/postcss-media-minmax" +} From 69faf71d64780aac78b92d2cebf20f5cb38c7e8e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=B8=80=E4=B8=9D?= Date: Sun, 14 Dec 2014 15:33:52 +0800 Subject: [PATCH 129/795] Add test #2, Fix unit(16/9) --- README-zh.md | 47 +++++++++++++++++--- README.md | 3 +- index.js | 8 +++- test/fixtures/aspect-ratio.css | 14 ++++++ test/fixtures/aspect-ratio.output.css | 14 ++++++ test/fixtures/color-index.css | 11 +++++ test/fixtures/color-index.output.css | 11 +++++ test/fixtures/color.css | 11 +++++ test/fixtures/color.output.css | 11 +++++ test/fixtures/comment.css | 11 +++++ test/fixtures/comment.output.css | 11 +++++ test/fixtures/device-aspect-ratio.css | 14 ++++++ test/fixtures/device-aspect-ratio.output.css | 14 ++++++ test/fixtures/device-width-height.css | 30 +++++++++++++ test/fixtures/device-width-height.output.css | 30 +++++++++++++ test/fixtures/line-break.css | 19 ++++++++ test/fixtures/line-break.output.css | 19 ++++++++ test/fixtures/monochrome.css | 11 +++++ test/fixtures/monochrome.output.css | 11 +++++ test/fixtures/more-units.css | 14 ++++++ test/fixtures/more-units.output.css | 14 ++++++ test/fixtures/other-name.css | 23 ++++++++++ test/fixtures/other-name.output.css | 23 ++++++++++ test/fixtures/resolution.css | 15 +++++++ test/fixtures/resolution.output.css | 15 +++++++ test/fixtures/width-height.css | 30 +++++++++++++ test/fixtures/width-height.output.css | 30 +++++++++++++ test/index.js | 45 +++++++++++++++++++ 28 files changed, 500 insertions(+), 9 deletions(-) create mode 100644 test/fixtures/aspect-ratio.css create mode 100644 test/fixtures/aspect-ratio.output.css create mode 100644 test/fixtures/color-index.css create mode 100644 test/fixtures/color-index.output.css create mode 100644 test/fixtures/color.css create mode 100644 test/fixtures/color.output.css create mode 100644 test/fixtures/comment.css create mode 100644 test/fixtures/comment.output.css create mode 100644 test/fixtures/device-aspect-ratio.css create mode 100644 test/fixtures/device-aspect-ratio.output.css create mode 100644 test/fixtures/device-width-height.css create mode 100644 test/fixtures/device-width-height.output.css create mode 100644 test/fixtures/line-break.css create mode 100644 test/fixtures/line-break.output.css create mode 100644 test/fixtures/monochrome.css create mode 100644 test/fixtures/monochrome.output.css create mode 100644 test/fixtures/more-units.css create mode 100644 test/fixtures/more-units.output.css create mode 100644 test/fixtures/other-name.css create mode 100644 test/fixtures/other-name.output.css create mode 100644 test/fixtures/resolution.css create mode 100644 test/fixtures/resolution.output.css create mode 100644 test/fixtures/width-height.css create mode 100644 test/fixtures/width-height.output.css create mode 100644 test/index.js diff --git a/README-zh.md b/README-zh.md index 94bdde16af..849decfaf0 100644 --- a/README-zh.md +++ b/README-zh.md @@ -1,10 +1,10 @@ -# PostCSS Media Minmax +# PostCSS Media Minmax [![Build Status](https://travis-ci.org/postcss/postcss-media-minmax.svg)](https://travis-ci.org/postcss/postcss-media-minmax) > 写简单优雅的 Media Queries! Media Queries 中的 `min-width` 和 `max-width` 等属性非常容易混淆,每次看到他们,我都想哭。现在[新的规范](http://dev.w3.org/csswg/mediaqueries/#mq-min-max)中,可以使用更加直观的 `>=`或`<=` 替代 media queries 中的 min-/max- 前缀。 -这是一个实现 CSS Media Queries Level 4 Polyfill 的插件,让你现在就可以使用这些特性,妈妈再也不用担心我记不住了,鹅妹子嘤! +这是一个实现 [CSS Media Queries Level 4](http://dev.w3.org/csswg/mediaqueries/) Polyfill 的插件,让你现在就可以使用这些特性,妈妈再也不用担心我记不住了,鹅妹子嘤! [English](README.md) @@ -67,6 +67,8 @@ input.css: ## CSS 语法 +### [语法](http://dev.w3.org/csswg/mediaqueries/#mq-syntax) + ``` = [ '<' | '>' ]? '='? | [ '<' | '>' ]? '='? @@ -74,12 +76,45 @@ input.css: | '>' '='? '>' '='? ``` +## [取值(Values)](http://dev.w3.org/csswg/mediaqueries/#values) + +**The special values:** + +* [](http://dev.w3.org/csswg/mediaqueries/#typedef-ratio) + + The value type is a positive (not zero or negative) followed by optional whitespace, followed by a solidus ('/'), followed by optional whitespace, followed by a positive . s can be ordered or compared by transforming them into the number obtained by dividing their first by their second . + + ```css + @media screen and (device-aspect-ratio: 16 / 9) { + /* rules */ + } + + /* equivalent to */ + @media screen and (device-aspect-ratio: 16/9) { + /* rules */ + } + ``` + +* [](http://dev.w3.org/csswg/mediaqueries/#typedef-mq-boolean) + + The value type is an with the value 0 or 1. Any other integer value is invalid. Note that -0 is always equivalent to 0 in CSS, and so is also accepted as a valid value. + + ```css + @media screen and (grid: -0) { + /* rules */ + } + + /* equivalent to */ + @media screen and (grid: 0) { + /* rules */ + } + ``` ## 如何使用 ### 简写 -示例 1中同一个 feature name 同时存在 `>=` 和 `<=` 时,可以简写为: +示例 1中同一个 Media features name 同时存在 `>=` 和 `<=` 时,可以简写为: ```css @media screen and (500px <= width <= 1200px) { @@ -104,7 +139,7 @@ input.css: } } ``` -**注意**:当 feature name 在中间的时候,一定要保证两个 `<=` 或 `>=` 的方向一致,否则不会转换。 +**注意**:当 Media features name 在中间的时候,一定要保证两个 `<=` 或 `>=` 的方向一致,否则不会转换。 例如在下面的示例中,width 大于等于 500px 同时又大于等于 1200px,这在语法和逻辑上都是错误的。 @@ -116,7 +151,7 @@ input.css: } ``` -### 支持的 feature name +### 支持的 Media features name 规范中目前以下属性支持 min-/max 前缀,PostCSS Media Minmax 全部支持自动转换。 @@ -139,7 +174,7 @@ input.css: var fs = require('fs') var chokidar = require('chokidar') var postcss = require('postcss') -var minmax = require('minmax') +var minmax = require('postcss-media-minmax') var customMedia = require('postcss-custom-media') var src = 'input.css' diff --git a/README.md b/README.md index f60cd84581..43302b7185 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,5 @@ -# PostCSS Media Minmax +# PostCSS Media Minmax [![Build Status](https://travis-ci.org/postcss/postcss-media-minmax.svg)](https://travis-ci.org/postcss/postcss-media-minmax) + > Writing simple and graceful Media Queries! diff --git a/index.js b/index.js index 1c411149fd..11bcb5e63b 100644 --- a/index.js +++ b/index.js @@ -30,7 +30,10 @@ function mediaMinmax() { * (width <= 900px) => (max-width: 900px) */ - rule.params = rule.params.replace(/\(\s*([a-z-]+?)\s*([<>]=)\s*((?:-?\d*\.?\d+[a-z]*)?)\s*\)/gi, function($0, $1, $2, $3) { + //取值不支持负值 + //But -0 is always equivalent to 0 in CSS, and so is also accepted as a valid value. + + rule.params = rule.params.replace(/\(\s*([a-z-]+?)\s*([<>]=)\s*((?:-?\d*\.?(?:\s*\/?\s*)?\d+[a-z]*)?)\s*\)/gi, function($0, $1, $2, $3) { var params = ''; @@ -54,7 +57,7 @@ function mediaMinmax() { * (900px >= width >= 300px) => (min-width: 300px) and (max-width: 900px) */ - rule.params = rule.params.replace(/\(\s*((?:-?\d*\.?\d+[a-z]*)?)\s*(<=|>=)\s*([a-z-]+)\s*(<=|>=)\s*((?:-?\d*\.?\d+[a-z]*)?)\s*\)/gi, function($0, $1, $2, $3, $4, $5) { + rule.params = rule.params.replace(/\(\s*((?:-?\d*\.?(?:\s*\/?\s*)?\d+[a-z]*)?)\s*(<=|>=)\s*([a-z-]+)\s*(<=|>=)\s*((?:-?\d*\.?(?:\s*\/?\s*)?\d+[a-z]*)?)\s*\)/gi, function($0, $1, $2, $3, $4, $5) { if (feature_name.indexOf($3) > -1) { if ($2 === '<=' && $4 === '<=' || $2 === '>=' && $4 === '>=') { @@ -67,6 +70,7 @@ function mediaMinmax() { return $0; }); + }); } diff --git a/test/fixtures/aspect-ratio.css b/test/fixtures/aspect-ratio.css new file mode 100644 index 0000000000..670630303b --- /dev/null +++ b/test/fixtures/aspect-ratio.css @@ -0,0 +1,14 @@ +@media screen and (aspect-ratio >= 1/1000) and (aspect-ratio <= 16/9) { + +} + +@media screen and (1 / 1000 <= aspect-ratio <= 16 / 9) { + +} + +@media screen and (0/0 <= aspect-ratio <= 16/9) { +} + +@media screen and (aspect-ratio) and (1 / 1000 <= aspect-ratio <= 16 / 9) { + +} \ No newline at end of file diff --git a/test/fixtures/aspect-ratio.output.css b/test/fixtures/aspect-ratio.output.css new file mode 100644 index 0000000000..9d4c6494eb --- /dev/null +++ b/test/fixtures/aspect-ratio.output.css @@ -0,0 +1,14 @@ +@media screen and (min-aspect-ratio: 1/1000) and (max-aspect-ratio: 16/9) { + +} + +@media screen and (min-aspect-ratio: 1 / 1000) and (max-aspect-ratio: 16 / 9) { + +} + +@media screen and (min-aspect-ratio: 0/0) and (max-aspect-ratio: 16/9) { +} + +@media screen and (aspect-ratio) and (min-aspect-ratio: 1 / 1000) and (max-aspect-ratio: 16 / 9) { + +} \ No newline at end of file diff --git a/test/fixtures/color-index.css b/test/fixtures/color-index.css new file mode 100644 index 0000000000..5a1712d162 --- /dev/null +++ b/test/fixtures/color-index.css @@ -0,0 +1,11 @@ +@media screen and (color-index >= 0) and (color-index <= 8) { + +} + +@media screen and (0 <= color-index <= 8) { + +} + +@media screen and (color-index) and (6 <= color-index <= 256) { + +} \ No newline at end of file diff --git a/test/fixtures/color-index.output.css b/test/fixtures/color-index.output.css new file mode 100644 index 0000000000..35765efe90 --- /dev/null +++ b/test/fixtures/color-index.output.css @@ -0,0 +1,11 @@ +@media screen and (min-color-index: 0) and (max-color-index: 8) { + +} + +@media screen and (min-color-index: 0) and (max-color-index: 8) { + +} + +@media screen and (color-index) and (min-color-index: 6) and (max-color-index: 256) { + +} \ No newline at end of file diff --git a/test/fixtures/color.css b/test/fixtures/color.css new file mode 100644 index 0000000000..a97cb19e3b --- /dev/null +++ b/test/fixtures/color.css @@ -0,0 +1,11 @@ +@media screen and (color >= 0) and (color <= 8) { + +} + +@media screen and (0 <= color <= 8) { + +} + +@media screen and (color) and (6 <= color <= 256) { + +} \ No newline at end of file diff --git a/test/fixtures/color.output.css b/test/fixtures/color.output.css new file mode 100644 index 0000000000..e185cf7323 --- /dev/null +++ b/test/fixtures/color.output.css @@ -0,0 +1,11 @@ +@media screen and (min-color: 0) and (max-color: 8) { + +} + +@media screen and (min-color: 0) and (max-color: 8) { + +} + +@media screen and (color) and (min-color: 6) and (max-color: 256) { + +} \ No newline at end of file diff --git a/test/fixtures/comment.css b/test/fixtures/comment.css new file mode 100644 index 0000000000..a865ea8c1c --- /dev/null +++ b/test/fixtures/comment.css @@ -0,0 +1,11 @@ +@media screen and /* comment */ (/* comment */width >= 500px) /* comment */ and (width/* comment */ <= 1200px) /* comment */{ + .bar { + display: block; + } +} + +@media screen and /* comment */(500px/* comment */ <= /* comment */width <= 1200px/* comment */) /* comment */{ + .bar { + display: block; + } +} diff --git a/test/fixtures/comment.output.css b/test/fixtures/comment.output.css new file mode 100644 index 0000000000..fc0d86f105 --- /dev/null +++ b/test/fixtures/comment.output.css @@ -0,0 +1,11 @@ +@media screen and (min-width: 500px) and (max-width: 1200px)/* comment */ { + .bar { + display: block; + } +} + +@media screen and (min-width: 500px) and (max-width: 1200px)/* comment */ { + .bar { + display: block; + } +} diff --git a/test/fixtures/device-aspect-ratio.css b/test/fixtures/device-aspect-ratio.css new file mode 100644 index 0000000000..10c85d73f8 --- /dev/null +++ b/test/fixtures/device-aspect-ratio.css @@ -0,0 +1,14 @@ +@media screen and (device-aspect-ratio >= 1/1000) and (device-aspect-ratio <= 16/9) { + +} + +@media screen and (1 / 1000 <= device-aspect-ratio <= 16 / 9) { + +} + +@media screen and (0/0 <= device-aspect-ratio <= 16/9) { +} + +@media screen and (device-aspect-ratio) and (1 / 1000 <= device-aspect-ratio <= 16 / 9) { + +} \ No newline at end of file diff --git a/test/fixtures/device-aspect-ratio.output.css b/test/fixtures/device-aspect-ratio.output.css new file mode 100644 index 0000000000..1037c9d10f --- /dev/null +++ b/test/fixtures/device-aspect-ratio.output.css @@ -0,0 +1,14 @@ +@media screen and (min-device-aspect-ratio: 1/1000) and (max-device-aspect-ratio: 16/9) { + +} + +@media screen and (min-device-aspect-ratio: 1 / 1000) and (max-device-aspect-ratio: 16 / 9) { + +} + +@media screen and (min-device-aspect-ratio: 0/0) and (max-device-aspect-ratio: 16/9) { +} + +@media screen and (device-aspect-ratio) and (min-device-aspect-ratio: 1 / 1000) and (max-device-aspect-ratio: 16 / 9) { + +} \ No newline at end of file diff --git a/test/fixtures/device-width-height.css b/test/fixtures/device-width-height.css new file mode 100644 index 0000000000..45b6b81349 --- /dev/null +++ b/test/fixtures/device-width-height.css @@ -0,0 +1,30 @@ +@media screen and (device-width >= 500px) and (device-width <= 1200px) { + +} + +@media screen and (500px <= device-width <= 1200px) { + +} + +@media screen and (0 <= device-width <= 500.58px) { +} + +@media screen and (device-width) and (.08px <= device-width <= 0.68px) { + +} + +/* device-height */ +@media screen and (device-height >= 500px) and (device-height <= 1200px) { + +} + +@media screen and (500px <= device-height <= 1200px) { + +} + +@media screen and (0 <= device-height <= 500.58px) { +} + +@media screen and (device-height) and (.08px <= device-height <= 0.68px) { + +} \ No newline at end of file diff --git a/test/fixtures/device-width-height.output.css b/test/fixtures/device-width-height.output.css new file mode 100644 index 0000000000..c2ef956394 --- /dev/null +++ b/test/fixtures/device-width-height.output.css @@ -0,0 +1,30 @@ +@media screen and (min-device-width: 500px) and (max-device-width: 1200px) { + +} + +@media screen and (min-device-width: 500px) and (max-device-width: 1200px) { + +} + +@media screen and (min-device-width: 0) and (max-device-width: 500.58px) { +} + +@media screen and (device-width) and (min-device-width: .08px) and (max-device-width: 0.68px) { + +} + +/* device-height */ +@media screen and (min-device-height: 500px) and (max-device-height: 1200px) { + +} + +@media screen and (min-device-height: 500px) and (max-device-height: 1200px) { + +} + +@media screen and (min-device-height: 0) and (max-device-height: 500.58px) { +} + +@media screen and (device-height) and (min-device-height: .08px) and (max-device-height: 0.68px) { + +} \ No newline at end of file diff --git a/test/fixtures/line-break.css b/test/fixtures/line-break.css new file mode 100644 index 0000000000..318ad2a41f --- /dev/null +++ b/test/fixtures/line-break.css @@ -0,0 +1,19 @@ +@media screen and + +(width >= 500px) +and +(width <= 1200px) { + .foo { + display: block; + } +} + +@media screen and + +(1200px <= width <= 500px) +and +(hover) { + .bar { + display: block; + } +} diff --git a/test/fixtures/line-break.output.css b/test/fixtures/line-break.output.css new file mode 100644 index 0000000000..86ef1e882e --- /dev/null +++ b/test/fixtures/line-break.output.css @@ -0,0 +1,19 @@ +@media screen and + +(min-width: 500px) +and +(max-width: 1200px) { + .foo { + display: block; + } +} + +@media screen and + +(min-width: 1200px) and (max-width: 500px) +and +(hover) { + .bar { + display: block; + } +} \ No newline at end of file diff --git a/test/fixtures/monochrome.css b/test/fixtures/monochrome.css new file mode 100644 index 0000000000..69c50ecdb5 --- /dev/null +++ b/test/fixtures/monochrome.css @@ -0,0 +1,11 @@ +@media screen and (monochrome >= 0) and (monochrome <= 1000) { + +} + +@media screen and (0 <= monochrome <= 1000) { + +} + +@media screen and (monochrome) and (1 <= monochrome <= 300) { + +} \ No newline at end of file diff --git a/test/fixtures/monochrome.output.css b/test/fixtures/monochrome.output.css new file mode 100644 index 0000000000..5923e5dff2 --- /dev/null +++ b/test/fixtures/monochrome.output.css @@ -0,0 +1,11 @@ +@media screen and (min-monochrome: 0) and (max-monochrome: 1000) { + +} + +@media screen and (min-monochrome: 0) and (max-monochrome: 1000) { + +} + +@media screen and (monochrome) and (min-monochrome: 1) and (max-monochrome: 300) { + +} \ No newline at end of file diff --git a/test/fixtures/more-units.css b/test/fixtures/more-units.css new file mode 100644 index 0000000000..377ff4b5cd --- /dev/null +++ b/test/fixtures/more-units.css @@ -0,0 +1,14 @@ +@media screen and (color-index) { } +@media screen and (color-index >= 0) and (color-index <= 1000) { } +@media screen and (monochrome >= 0) and (monochrome <= 1000) { } + + +@media screen and (resolution >= 96dpi) and (resolution <= 3dppx) { } +@media screen and (width >= -200px) and (width <= 900.56px) { } +@media screen and (width >= -0.58px) and (width <= .99px) { } + + +@media screen and (resolution) { } +@media screen and (resolution >= 1000dpi) and (resolution <= 3dppx) { } +@media screen and (1000000dpi <= resolution <= 1000000dpcm) { } +@media screen and (1 / 1000 <= resolution <= 16 /9) { } \ No newline at end of file diff --git a/test/fixtures/more-units.output.css b/test/fixtures/more-units.output.css new file mode 100644 index 0000000000..95cc716504 --- /dev/null +++ b/test/fixtures/more-units.output.css @@ -0,0 +1,14 @@ +@media screen and (color-index) { } +@media screen and (min-color-index: 0) and (max-color-index: 1000) { } +@media screen and (min-monochrome: 0) and (max-monochrome: 1000) { } + + +@media screen and (min-resolution: 96dpi) and (max-resolution: 3dppx) { } +@media screen and (min-width: -200px) and (max-width: 900.56px) { } +@media screen and (min-width: -0.58px) and (max-width: .99px) { } + + +@media screen and (resolution) { } +@media screen and (min-resolution: 1000dpi) and (max-resolution: 3dppx) { } +@media screen and (min-resolution: 1000000dpi) and (max-resolution: 1000000dpcm) { } +@media screen and (min-resolution: 1 / 1000) and (max-resolution: 16 /9) { } \ No newline at end of file diff --git a/test/fixtures/other-name.css b/test/fixtures/other-name.css new file mode 100644 index 0000000000..0c6b1158cc --- /dev/null +++ b/test/fixtures/other-name.css @@ -0,0 +1,23 @@ +@media screen and (width >= 500px) and (height) { + .bar { + display: block; + } +} + +@media screen and (500px <= width <= 1200px) and (height) { + .bar { + display: block; + } +} + +@media screen and (any-hover) and (width >= 500px) and (device-width) { + .bar { + display: block; + } +} + +@media screen and (any-hover) and (width >= 500px) and (device-width) { + .bar { + display: block; + } +} \ No newline at end of file diff --git a/test/fixtures/other-name.output.css b/test/fixtures/other-name.output.css new file mode 100644 index 0000000000..39957656f9 --- /dev/null +++ b/test/fixtures/other-name.output.css @@ -0,0 +1,23 @@ +@media screen and (min-width: 500px) and (height) { + .bar { + display: block; + } +} + +@media screen and (min-width: 500px) and (max-width: 1200px) and (height) { + .bar { + display: block; + } +} + +@media screen and (any-hover) and (min-width: 500px) and (device-width) { + .bar { + display: block; + } +} + +@media screen and (any-hover) and (min-width: 500px) and (device-width) { + .bar { + display: block; + } +} \ No newline at end of file diff --git a/test/fixtures/resolution.css b/test/fixtures/resolution.css new file mode 100644 index 0000000000..e55a7cbba3 --- /dev/null +++ b/test/fixtures/resolution.css @@ -0,0 +1,15 @@ +@media screen and (resolution >= 1dpi) and (resolution <= 192dpi) { + +} + +@media screen and (1.5dppx <= resolution <= 3dppx) { + +} + +@media screen and (.5dppx <= resolution <= 2.5dppx) { + +} + +@media screen and (resolution) and (10dpi <= resolution <= 118dpcm) { + +} \ No newline at end of file diff --git a/test/fixtures/resolution.output.css b/test/fixtures/resolution.output.css new file mode 100644 index 0000000000..5acccc57a5 --- /dev/null +++ b/test/fixtures/resolution.output.css @@ -0,0 +1,15 @@ +@media screen and (min-resolution: 1dpi) and (max-resolution: 192dpi) { + +} + +@media screen and (min-resolution: 1.5dppx) and (max-resolution: 3dppx) { + +} + +@media screen and (min-resolution: .5dppx) and (max-resolution: 2.5dppx) { + +} + +@media screen and (resolution) and (min-resolution: 10dpi) and (max-resolution: 118dpcm) { + +} \ No newline at end of file diff --git a/test/fixtures/width-height.css b/test/fixtures/width-height.css new file mode 100644 index 0000000000..7ea2b6900c --- /dev/null +++ b/test/fixtures/width-height.css @@ -0,0 +1,30 @@ +@media screen and (width >= 500px) and (width <= 1200px) { + +} + +@media screen and (500px <= width <= 1200px) { + +} + +@media screen and (0 <= width <= 500.58px) { +} + +@media screen and (width) and (.08px <= width <= 0.68px) { + +} + +/* height */ +@media screen and (height >= 500px) and (height <= 1200px) { + +} + +@media screen and (500px <= height <= 1200px) { + +} + +@media screen and (0 <= height <= 500.58px) { +} + +@media screen and (height) and (.08px <= height <= 0.68px) { + +} \ No newline at end of file diff --git a/test/fixtures/width-height.output.css b/test/fixtures/width-height.output.css new file mode 100644 index 0000000000..097e0fb24a --- /dev/null +++ b/test/fixtures/width-height.output.css @@ -0,0 +1,30 @@ +@media screen and (min-width: 500px) and (max-width: 1200px) { + +} + +@media screen and (min-width: 500px) and (max-width: 1200px) { + +} + +@media screen and (min-width: 0) and (max-width: 500.58px) { +} + +@media screen and (width) and (min-width: .08px) and (max-width: 0.68px) { + +} + +/* height */ +@media screen and (min-height: 500px) and (max-height: 1200px) { + +} + +@media screen and (min-height: 500px) and (max-height: 1200px) { + +} + +@media screen and (min-height: 0) and (max-height: 500.58px) { +} + +@media screen and (height) and (min-height: .08px) and (max-height: 0.68px) { + +} \ No newline at end of file diff --git a/test/index.js b/test/index.js new file mode 100644 index 0000000000..a148787887 --- /dev/null +++ b/test/index.js @@ -0,0 +1,45 @@ +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 + ".output")) + fs.writeFile(filename("fixtures/" + name + ".actual"), actual) + t.equal(actual.trim(), expected.trim(), msg) +} + +test("@media", function(t) { + compareFixtures(t, "width-height", "should transform") + compareFixtures(t, "device-width-height", "should transform") + compareFixtures(t, "aspect-ratio", "should transform") + compareFixtures(t, "device-aspect-ratio", "should transform") + compareFixtures(t, "color", "should transform") + compareFixtures(t, "color-index", "should transform") + compareFixtures(t, "monochrome", "should transform") + compareFixtures(t, "resolution", "should transform") + + compareFixtures(t, "comment", "should transform") + compareFixtures(t, "comment", "should transform") + compareFixtures(t, "line-break", "should transform") + compareFixtures(t, "other-name", "should transform") + compareFixtures(t, "more-units", "should transform") + + // compareFixtures(t, "extension", "local extensions", { + // extensions: { + // ':--any' : 'section, article, aside, nav', + // '--foo': 'input[type="text"] > section, #nav .bar' + // } + // }) + + t.end() +}) From 6d9f888c1b64e8ee6bf7bbba73c5c8b76c6c6ee2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=B8=80=E4=B8=9D?= Date: Mon, 15 Dec 2014 11:21:16 +0800 Subject: [PATCH 130/795] Update docs, Remove the redundant code --- README-zh.md | 6 ++++-- README.md | 49 +++++++++++++++++++++++++++++++++++++++++++------ package.json | 7 ++++--- test/index.js | 14 +++----------- 4 files changed, 54 insertions(+), 22 deletions(-) diff --git a/README-zh.md b/README-zh.md index 849decfaf0..1471d52ba3 100644 --- a/README-zh.md +++ b/README-zh.md @@ -76,13 +76,15 @@ input.css: | '>' '='? '>' '='? ``` +PostCSS Media Minmax 目前并没有实现 `200px >= width` 或者 `200px <= width` 这样的语法,因为这样的语法可读性并不不是太好。 + ## [取值(Values)](http://dev.w3.org/csswg/mediaqueries/#values) **The special values:** * [](http://dev.w3.org/csswg/mediaqueries/#typedef-ratio) - The value type is a positive (not zero or negative) followed by optional whitespace, followed by a solidus ('/'), followed by optional whitespace, followed by a positive . s can be ordered or compared by transforming them into the number obtained by dividing their first by their second . + 是一个正(非零非负)的 (整型)取值,其后跟随0个或多个空白,接着跟随一个斜线(“/”),再跟随0个或多个空白,最后跟随一个正。 ```css @media screen and (device-aspect-ratio: 16 / 9) { @@ -97,7 +99,7 @@ input.css: * [](http://dev.w3.org/csswg/mediaqueries/#typedef-mq-boolean) - The value type is an with the value 0 or 1. Any other integer value is invalid. Note that -0 is always equivalent to 0 in CSS, and so is also accepted as a valid value. + 值是一个 0 或 1 的 (整型)取值。其他任何整数无效。注意, 在 CSS 中 -0 总是等价于 0 的,所以也作为一种有效的 取值。 ```css @media screen and (grid: -0) { diff --git a/README.md b/README.md index 43302b7185..0db75051bc 100644 --- a/README.md +++ b/README.md @@ -3,9 +3,9 @@ > Writing simple and graceful Media Queries! -The `min-width`,`max-width` and so on propertys of Media Queries is really easy to confuse, every time I see them, I want to cry. Right now in the new specs, you can use more intuitive <= or >= to instead of the min-/max- prefix of media queries. +The `min-width`,`max-width` and many other propertys of Media Queries are really confused, every time I see them, I want to cry. Right now in the new specs, you can use more intuitive <= or >= to instead of the min-/max- prefix of media queries. -This is a supporting CSS Media Queries Level 4 Polyfill plugin,which let you can ues these features right now. Mom won't never worry about my study, so amazing! +This is a supporting [CSS Media Queries Level 4](http://dev.w3.org/csswg/mediaqueries/) Polyfill plugin,which let you can ues these features right now. Mom won't never worry about my study, so amazing! [简体中文](README-zh.md) @@ -68,6 +68,8 @@ You will get: ## CSS syntax +### [Syntax](http://dev.w3.org/csswg/mediaqueries/#mq-syntax) + ``` = [ '<' | '>' ]? '='? | [ '<' | '>' ]? '='? @@ -75,12 +77,47 @@ You will get: | '>' '='? '>' '='? ``` +PostCSS Media Minmax is currently doesn't implement the `200px > = width` or `200px < = width` such a grammar, because the syntax readability this not too good. + +## [Values](http://dev.w3.org/csswg/mediaqueries/#values) + +**The special values:** + +* [](http://dev.w3.org/csswg/mediaqueries/#typedef-ratio) + + The value type is a positive (not zero or negative) followed by optional whitespace, followed by a solidus ('/'), followed by optional whitespace, followed by a positive . s can be ordered or compared by transforming them into the number obtained by dividing their first by their second . + + ```css + @media screen and (device-aspect-ratio: 16 / 9) { + /* rules */ + } + + /* equivalent to */ + @media screen and (device-aspect-ratio: 16/9) { + /* rules */ + } + ``` + +* [](http://dev.w3.org/csswg/mediaqueries/#typedef-mq-boolean) + + The value type is an with the value 0 or 1. Any other integer value is invalid. Note that -0 is always equivalent to 0 in CSS, and so is also accepted as a valid value. + + ```css + @media screen and (grid: -0) { + /* rules */ + } + + /* equivalent to */ + @media screen and (grid: 0) { + /* rules */ + } + ``` ## How to use ### Shorthand -In Example 1, the same feature name is `>=` and `<=`, which will be abbreviated as the following: +In Example 1, the same feature name is >= and <=, which will be abbreviated as the following: ```css @media screen and (500px <= width <= 1200px) { @@ -106,7 +143,7 @@ Will get the same output results: } ``` -**Note**: when the feature name in the middle, we must ensure that two `<=` or `>=` in the same direction, otherwise which will not be converted. +**Note**: When the Media features name in the middle, we must ensure that two `<=` or `>=` in the same direction, otherwise which will not be converted. E.g. in the example below, width is greater than or equal to 500px and is greater than or equal to 1200px, this is the wrong in grammar and logic. @@ -119,7 +156,7 @@ E.g. in the example below, width is greater than or equal to 500px and is greate } ``` -### feature name +### Media features name The following property supports the min-/max prefix in specification at present, which will be automatically converted by PostCSS Media Minmax. @@ -142,7 +179,7 @@ The following property supports the min-/max prefix in specification at present, var fs = require('fs') var chokidar = require('chokidar') var postcss = require('postcss') -var minmax = require('minmax') +var minmax = require('postcss-media-minmax') var customMedia = require('postcss-custom-media') var src = 'input.css' diff --git a/package.json b/package.json index 153d978ac2..f5a0f6ba46 100644 --- a/package.json +++ b/package.json @@ -1,8 +1,7 @@ { "name": "postcss-media-minmax", "version": "1.0.0", - "description": "Writing simple and graceful Media Queries!Using more intuitive `>=` or `<=` instead of media queries min/max prefix.", - "main": "index.js", + "description": "Using more intuitive `>=` or `<=` instead of media queries min/max prefix.", "scripts": { "test": "tape test" }, @@ -15,12 +14,14 @@ "css3", "postcss", "postcss-plugins", - "Media Queries" + "media querie", + "media queries" ], "author": "yisi", "license": "MIT", "files": [ "CHANGELOG.md", + "README.md", "README-zh.md", "LICENSE", "index.js" diff --git a/test/index.js b/test/index.js index a148787887..3491397f2b 100644 --- a/test/index.js +++ b/test/index.js @@ -20,7 +20,7 @@ function compareFixtures(t, name, msg, opts, postcssOpts) { test("@media", function(t) { compareFixtures(t, "width-height", "should transform") - compareFixtures(t, "device-width-height", "should transform") + compareFixtures(t, "device-width-height", "should transform") compareFixtures(t, "aspect-ratio", "should transform") compareFixtures(t, "device-aspect-ratio", "should transform") compareFixtures(t, "color", "should transform") @@ -29,17 +29,9 @@ test("@media", function(t) { compareFixtures(t, "resolution", "should transform") compareFixtures(t, "comment", "should transform") - compareFixtures(t, "comment", "should transform") - compareFixtures(t, "line-break", "should transform") + compareFixtures(t, "line-break", "should transform") compareFixtures(t, "other-name", "should transform") - compareFixtures(t, "more-units", "should transform") - - // compareFixtures(t, "extension", "local extensions", { - // extensions: { - // ':--any' : 'section, article, aside, nav', - // '--foo': 'input[type="text"] > section, #nav .bar' - // } - // }) + compareFixtures(t, "more-units", "should transform") t.end() }) From c337ab59f4853dc56f83bc66e21d1753a1805935 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=B8=80=E4=B8=9D?= Date: Mon, 15 Dec 2014 11:41:09 +0800 Subject: [PATCH 131/795] v1.1.0 --- CHANGELOG.md | 7 +++++++ README.md | 2 +- package.json | 2 +- 3 files changed, 9 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e69de29bb2..1c7b68395d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -0,0 +1,7 @@ +# 1.1.0 + +Add `( 300px <= width <= 900px)` or `( 900px >= width >= 300px)` syntax. + +# 1.0.0 + +The first release. diff --git a/README.md b/README.md index 0db75051bc..a59586f4b1 100644 --- a/README.md +++ b/README.md @@ -77,7 +77,7 @@ You will get: | '>' '='? '>' '='? ``` -PostCSS Media Minmax is currently doesn't implement the `200px > = width` or `200px < = width` such a grammar, because the syntax readability this not too good. +PostCSS Media Minmax doesn't implement such syntax as `200px > = width` or `200px < = width` currently, because the syntax readability is not good enough. ## [Values](http://dev.w3.org/csswg/mediaqueries/#values) diff --git a/package.json b/package.json index f5a0f6ba46..efe73ae07e 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "postcss-media-minmax", - "version": "1.0.0", + "version": "1.1.0", "description": "Using more intuitive `>=` or `<=` instead of media queries min/max prefix.", "scripts": { "test": "tape test" From eea905d9786dd260880d2cd795f6924a8f6c2de4 Mon Sep 17 00:00:00 2001 From: GU Yiling Date: Mon, 15 Dec 2014 14:30:09 +0800 Subject: [PATCH 132/795] Better English translation --- README.md | 34 +++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/README.md b/README.md index a59586f4b1..8d902cde73 100644 --- a/README.md +++ b/README.md @@ -1,11 +1,11 @@ # PostCSS Media Minmax [![Build Status](https://travis-ci.org/postcss/postcss-media-minmax.svg)](https://travis-ci.org/postcss/postcss-media-minmax) -> Writing simple and graceful Media Queries! +> Writing simple and graceful media queries! -The `min-width`,`max-width` and many other propertys of Media Queries are really confused, every time I see them, I want to cry. Right now in the new specs, you can use more intuitive <= or >= to instead of the min-/max- prefix of media queries. +The `min-width`, `max-width` and many other properties of media queries are really confusing. I want to cry every time I see them. But right now according to the new specs, you can use more intuitive `<=` or `>=` to replace the `min-`/`max-` prefixes in media queries. -This is a supporting [CSS Media Queries Level 4](http://dev.w3.org/csswg/mediaqueries/) Polyfill plugin,which let you can ues these features right now. Mom won't never worry about my study, so amazing! +This is a polyfill plugin which supports [CSS Media Queries Level 4](http://dev.w3.org/csswg/mediaqueries/) and gives you access to the new features right away. Mom will never worry about my study any more. So amazing! [简体中文](README-zh.md) @@ -77,7 +77,7 @@ You will get: | '>' '='? '>' '='? ``` -PostCSS Media Minmax doesn't implement such syntax as `200px > = width` or `200px < = width` currently, because the syntax readability is not good enough. +PostCSS Media Minmax hasn't implemented syntax such as `200px > = width` or `200px < = width` currently because its readability is not good enough yet. ## [Values](http://dev.w3.org/csswg/mediaqueries/#values) @@ -117,7 +117,7 @@ PostCSS Media Minmax doesn't implement such syntax as `200px > = width` or `200p ### Shorthand -In Example 1, the same feature name is >= and <=, which will be abbreviated as the following: +In Example 1, if a feature has both `>=` and `<=` logic, it can be written as follows: ```css @media screen and (500px <= width <= 1200px) { @@ -133,7 +133,7 @@ In Example 1, the same feature name is >= and <=, which will be abbreviated as t } ``` -Will get the same output results: +Which will output: ```css @media screen and (min-width: 500px) and (max-width: 1200px) { @@ -143,9 +143,9 @@ Will get the same output results: } ``` -**Note**: When the Media features name in the middle, we must ensure that two `<=` or `>=` in the same direction, otherwise which will not be converted. +**Note**: When the media feature name is in the middle, we must ensure that two `<=` or `>=` are in the same direction, otherwise which will not be converted. -E.g. in the example below, width is greater than or equal to 500px and is greater than or equal to 1200px, this is the wrong in grammar and logic. +E.g. in the example below, `width` is greater than or equal to 500px and is greater than or equal to 1200px, which is the wrong in both grammar and logic. ```css @@ -156,9 +156,9 @@ E.g. in the example below, width is greater than or equal to 500px and is greate } ``` -### Media features name +### Media feature names -The following property supports the min-/max prefix in specification at present, which will be automatically converted by PostCSS Media Minmax. +The following properties support the `min-`/`max-` prefixes in the specifications at present, and will be automatically converted by PostCSS Media Minmax. * `width` * `height` @@ -173,7 +173,7 @@ The following property supports the min-/max prefix in specification at present, -### Support for use in `@custom-media` & Node Watch +### Using with `@custom-media` & Node Watch ```js var fs = require('fs') @@ -275,10 +275,10 @@ gulp.watch('src/*.css', ['default']); ## Contributing -* Install the relevant dependent module. -* Respect coding style(Use [EditorConfig](http://editorconfig.org/)). +* Install all the dependent modules. +* Respect the coding style (Use [EditorConfig](http://editorconfig.org/)). * Add test cases in the [test](test) directory. -* Run test. +* Run the test cases. ``` $ git clone https://github.com/postcss/postcss-media-minmaxs.git @@ -289,11 +289,11 @@ $ npm test ## Acknowledgements -* Thank the author of PostCSS [Andrey Sitnik](https://github.com/ai) for giving us so simple and easy CSS syntax analysis tools. +* Thank the author of PostCSS [Andrey Sitnik](https://github.com/ai) for giving us such simple and easy CSS syntax analysis tools. -* Thank [Tab Atkins Jr.](http://xanthir.com/contact/) for writing the specs of Media Queries Level 4. +* Thank [Tab Atkins Jr.](http://xanthir.com/contact/) for writing the specs of Media Queries Level 4. -* Thank [ziyunfei](http://weibo.com/p/1005051708684567) for suggestion and help of this plugin. +* Thank [ziyunfei](http://weibo.com/p/1005051708684567) for suggestions and help of this plugin. ## [Changelog](CHANGELOG.md) From b7575df8d7f18408c58b88cbf5680e261d7c769a Mon Sep 17 00:00:00 2001 From: Maxime Thirouin Date: Mon, 15 Dec 2014 19:34:30 +0100 Subject: [PATCH 133/795] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 0309c1e716..c73bb40afa 100755 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # postcss-color-rebeccapurple [![Build Status](https://travis-ci.org/postcss/postcss-color-rebeccapurple.png)](https://travis-ci.org/postcss/postcss-color-rebeccapurple) -> [PostCSS](https://github.com/postcss/postcss) plugin to transform [W3C CSS `rebeccapurple` color](http://dev.w3.org/csswg/css-color/#valuedef-color-rebeccapurple) to more compatible CSS (rgb()). +> [PostCSS](https://github.com/postcss/postcss) plugin to transform [W3C CSS `rebeccapurple` color](http://dev.w3.org/csswg/css-color/#valdef-color-rebeccapurple) to more compatible CSS (rgb()). ## Why this plugin ? From 3ed94651294f50b7ad9d28baff0ac2fb02f96428 Mon Sep 17 00:00:00 2001 From: Shinnosuke Watanabe Date: Fri, 19 Dec 2014 00:07:40 +0900 Subject: [PATCH 134/795] use faster way to build on Travis CI http://blog.travis-ci.com/2014-12-17-faster-builds-with-container-based- infrastructure/ --- .travis.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.travis.yml b/.travis.yml index 3f62a435e5..548be277b9 100755 --- a/.travis.yml +++ b/.travis.yml @@ -1,3 +1,6 @@ +sudo: false +git: + depth: 2 language: node_js node_js: - '0.10' From 7364879ecabdd5c075a098a59ba228a170053a36 Mon Sep 17 00:00:00 2001 From: Shinnosuke Watanabe Date: Fri, 19 Dec 2014 00:09:04 +0900 Subject: [PATCH 135/795] update devDependencies --- package.json | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/package.json b/package.json index 3dc49b6ef1..df0d5d2b8d 100644 --- a/package.json +++ b/package.json @@ -40,11 +40,11 @@ "reduce-function-call": "^1.0.1" }, "devDependencies": { - "eslint": "^0.9.2", - "istanbul": "^0.3.2", + "eslint": "^0.10.2", + "istanbul": "^0.3.5", "istanbul-coveralls": "^1.0.1", - "jscs": "^1.7.3", - "postcss": "^3.0.4", + "jscs": "^1.8.1", + "postcss": "^3.0.7", "tap-spec": "^2.1.0", "tape": "^3.0.3" } From 5f10e21af6e20a231cee366bd76cd18fb21c6f88 Mon Sep 17 00:00:00 2001 From: David Clark Date: Sat, 17 Jan 2015 15:57:22 -0700 Subject: [PATCH 136/795] Upgrade to postcss 4 --- index.js | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/index.js b/index.js index 09422d66f4..c321ec6f6c 100755 --- a/index.js +++ b/index.js @@ -64,11 +64,11 @@ module.exports = function(options) { // optionally remove `--*` properties from the rule if (!preserve) { for (var i = toRemove.length - 1; i >= 0; i--) { - rule.childs.splice(toRemove[i], 1) + rule.nodes.splice(toRemove[i], 1) } // remove empty :root {} - if (rule.childs.length === 0) { + if (rule.nodes.length === 0) { rule.removeSelf() } } diff --git a/package.json b/package.json index 8e064cedf6..abfc30a6fb 100644 --- a/package.json +++ b/package.json @@ -28,7 +28,7 @@ "devDependencies": { "jscs": "^1.6.2", "jshint": "^2.5.6", - "postcss": "^3.0.0", + "postcss": "^4.0.0", "tape": "^3.0.0" }, "scripts": { From 16ff3c22fe0563a1283411d7866791966fff4c58 Mon Sep 17 00:00:00 2001 From: Maxime Thirouin Date: Tue, 20 Jan 2015 08:25:25 +0100 Subject: [PATCH 137/795] Remove useless test about rule being a rule rule (eachRule) are obviously rule right? --- index.js | 3 --- 1 file changed, 3 deletions(-) diff --git a/index.js b/index.js index c321ec6f6c..babcce64e8 100755 --- a/index.js +++ b/index.js @@ -28,9 +28,6 @@ module.exports = function(options) { // define variables style.eachRule(function(rule) { var toRemove = [] - if (rule.type !== "rule") { - return - } // only variables declared for `:root` are supported for now if (rule.selectors.length !== 1 || rule.selectors[0] !== ":root" || rule.parent.type !== "root") { From 604168e4e28379c3a42c8a8255957a65ec6b2c27 Mon Sep 17 00:00:00 2001 From: Maxime Thirouin Date: Tue, 20 Jan 2015 08:32:48 +0100 Subject: [PATCH 138/795] Use a new postcss 4 method `cloneBefore` --- index.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/index.js b/index.js index babcce64e8..8e9f681902 100755 --- a/index.js +++ b/index.js @@ -87,9 +87,8 @@ module.exports = function(options) { helpers.try(function resolve() { resolveValue(value, map, decl.source).forEach(function(resolvedValue) { - var clone = decl.clone() + var clone = decl.cloneBefore() clone.value = resolvedValue - decl.parent.insertBefore(decl, clone) }) }, decl.source) From d8e7598ce9f99124cc815d11603355d426831731 Mon Sep 17 00:00:00 2001 From: Maxime Thirouin Date: Tue, 20 Jan 2015 08:35:37 +0100 Subject: [PATCH 139/795] prepare v3.0.0 --- CHANGELOG.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9b5fd290c0..c0d6e93dce 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,9 @@ +# 3.0.0 - 2015-01-20 + +- Upgrade to postcss 4 ([#18](https://github.com/postcss/postcss-custom-properties/pull/18)) +- Remove some code that seems to be useless ([16ff3c2](https://github.com/postcss/postcss-custom-properties/commit/16ff3c22fe0563a1283411d7866791966fff4c58)) +- Use a new postcss 4 method `cloneBefore` ([604168e](https://github.com/postcss/postcss-custom-properties/commit/604168e4e28379c3a42c8a8255957a65ec6b2c27)) + # 2.1.1 - 2014-12-02 - Fix issue when multiples undefined custom properties are referenced ([#16](https://github.com/postcss/postcss-custom-properties/issues/16)) From 51598c5b035cca63725345d5aadca722f01588e2 Mon Sep 17 00:00:00 2001 From: Maxime Thirouin Date: Wed, 21 Jan 2015 09:05:28 +0100 Subject: [PATCH 140/795] v3.0.0 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index abfc30a6fb..27d5a1bfdf 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "postcss-custom-properties", - "version": "2.1.1", + "version": "3.0.0", "description": "PostCSS plugin to polyfill W3C CSS Custom Properties for cascading variables", "keywords": [ "css", From a2a136f227ecc707e1d30955d4199c0795ebbced Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marek=20=E2=80=98saji=E2=80=99=20Augustynowicz?= Date: Thu, 22 Jan 2015 11:29:09 +0100 Subject: [PATCH 141/795] =?UTF-8?q?Re=E2=80=93use=20existing=20font-featur?= =?UTF-8?q?e-settings=20declarations?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- index.js | 63 ++++++++++++++++++------- test/fixtures/font-variant.css | 12 +++++ test/fixtures/font-variant.expected.css | 15 +++++- 3 files changed, 70 insertions(+), 20 deletions(-) diff --git a/index.js b/index.js index c2d9e2a43d..11010aac01 100755 --- a/index.js +++ b/index.js @@ -54,31 +54,58 @@ for (var prop in fontVariantProperties) { } } +// Find font-feature-settings declaration before given declaration, +// create if does not exist +function getFontFeatureSettingsPrevTo(decl) { + var fontFeatureSettings = null; + decl.parent.eachDecl(function(decl) { + if (decl.prop === "font-feature-settings") { + fontFeatureSettings = decl; + } + }) + + if (fontFeatureSettings === null) { + fontFeatureSettings = decl.clone() + fontFeatureSettings.prop = "font-feature-settings" + fontFeatureSettings.value = "" + decl.parent.insertBefore(decl, fontFeatureSettings) + } + return fontFeatureSettings +} + /** * Expose the font-variant plugin. */ module.exports = function postcssFontVariant() { return function(styles) { - // read custom media queries - styles.eachDecl(function(decl) { - if (!fontVariantProperties[decl.prop]) { - return null - } + styles.eachRule(function(rule) { + var fontFeatureSettings = null + // read custom media queries + rule.eachDecl(function(decl) { + if (!fontVariantProperties[decl.prop]) { + return null + } - var newValue = decl.value - if (decl.prop === "font-variant") { - newValue = decl.value.split(/\s+/g).map(function(val) { - return fontVariantProperties["font-variant"][val] - }).join(", ") - } - else if (fontVariantProperties[decl.prop][decl.value]) { - newValue = fontVariantProperties[decl.prop][decl.value] - } + var newValue = decl.value + if (decl.prop === "font-variant") { + newValue = decl.value.split(/\s+/g).map(function(val) { + return fontVariantProperties["font-variant"][val] + }).join(", ") + } + else if (fontVariantProperties[decl.prop][decl.value]) { + newValue = fontVariantProperties[decl.prop][decl.value] + } - var newDecl = decl.clone() - newDecl.prop = "font-feature-settings" - newDecl.value = newValue - decl.parent.insertBefore(decl, newDecl) + if (fontFeatureSettings === null) { + fontFeatureSettings = getFontFeatureSettingsPrevTo(decl); + } + if (fontFeatureSettings.value) { + fontFeatureSettings.value += ", " + newValue; + } + else { + fontFeatureSettings.value = newValue; + } + }) }) } } diff --git a/test/fixtures/font-variant.css b/test/fixtures/font-variant.css index 10fa7bd50f..37f1f0ccf9 100644 --- a/test/fixtures/font-variant.css +++ b/test/fixtures/font-variant.css @@ -1,8 +1,20 @@ selector { font-variant-numeric: tabular-nums; font-variant-caps: all-small-caps; +} +selector { font-variant: normal; +} +selector { font-variant: inherit; +} +selector { font-variant: all-small-caps oldstyle-nums; +} +selector { + font-feature-settings: "onum"; + font-variant: all-small-caps; +} +selector { font-variant-position: normal; } diff --git a/test/fixtures/font-variant.expected.css b/test/fixtures/font-variant.expected.css index ba9ae6a836..48658080fc 100644 --- a/test/fixtures/font-variant.expected.css +++ b/test/fixtures/font-variant.expected.css @@ -1,14 +1,25 @@ selector { - font-feature-settings: "tnum"; + font-feature-settings: "tnum", "smcp", "c2sc"; font-variant-numeric: tabular-nums; - font-feature-settings: "smcp", "c2sc"; font-variant-caps: all-small-caps; +} +selector { font-feature-settings: normal; font-variant: normal; +} +selector { font-feature-settings: inherit; font-variant: inherit; +} +selector { font-feature-settings: "smcp", "c2sc", "onum"; font-variant: all-small-caps oldstyle-nums; +} +selector { + font-feature-settings: "onum", "smcp", "c2sc"; + font-variant: all-small-caps; +} +selector { font-feature-settings: normal; font-variant-position: normal; } From cff4124ac3e8b97406d3fb2409c9a4b90a9e3876 Mon Sep 17 00:00:00 2001 From: Maxime Thirouin Date: Tue, 27 Jan 2015 07:42:19 +0100 Subject: [PATCH 142/795] prepare 1.0.2 --- CHANGELOG.md | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ecb08149da..b45da1b421 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,7 +1,11 @@ +# 1.0.2 - 2015-01-27 + +- Fixed: Re–use existing font-feature-settings declarations to avoid creating multiples that override themselves ([#1](https://github.com/postcss/postcss-font-variant/pull/1)) + # 1.0.1 - 2014-11-11 -- fix wrong space char that breaks on some environnements +- Fixed: wrong space char that breaks on some environnements # 1.0.0 - 2014-10-09 -First release based on [rework-font-variant](https://github.com/ianstormtaylor/rework-font-variant) v1.0.1 +✨ First release based on [rework-font-variant](https://github.com/ianstormtaylor/rework-font-variant) v1.0.1 From f3de05f663c25854ba6e34428b17b23529fd5640 Mon Sep 17 00:00:00 2001 From: Maxime Thirouin Date: Tue, 27 Jan 2015 07:42:36 +0100 Subject: [PATCH 143/795] v1.0.2 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 1a90024fc9..c5583245a4 100755 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "postcss-font-variant", - "version": "1.0.1", + "version": "1.0.2", "description": "PostCSS plugin to transform W3C font-variant properties to more compatible CSS (font-feature-settings)", "keywords": [ "css", From 6bf2819159a72e60916b21e3005c441d154a5f2a Mon Sep 17 00:00:00 2001 From: Maxime Thirouin Date: Tue, 27 Jan 2015 07:45:19 +0100 Subject: [PATCH 144/795] ensure compatibility with postcss v4.x --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index c5583245a4..39dcda5fe0 100755 --- a/package.json +++ b/package.json @@ -25,7 +25,7 @@ "devDependencies": { "jscs": "^1.6.2", "jshint": "^2.5.6", - "postcss": "^3.0.0", + "postcss": "^4.0.2", "tape": "^3.0.0" }, "scripts": { From 610bcd3364accf19b2ac407515ce8c7ddf4e1f3d Mon Sep 17 00:00:00 2001 From: Maxime Thirouin Date: Tue, 27 Jan 2015 07:47:40 +0100 Subject: [PATCH 145/795] ensure compatibility with postcss v4.x --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 9ae2910f57..ab858fcab3 100644 --- a/package.json +++ b/package.json @@ -26,7 +26,7 @@ "devDependencies": { "jscs": "^1.6.2", "jshint": "^2.5.6", - "postcss": "^3.0.0", + "postcss": "^4.0.2", "tape": "^3.0.0" }, "scripts": { From b8d95ddb901ac6fe7601dbcf31de49d0fcf3bca6 Mon Sep 17 00:00:00 2001 From: Maxime Thirouin Date: Tue, 27 Jan 2015 07:51:50 +0100 Subject: [PATCH 146/795] ensure compatibility with postcss v4.x --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 03dff19619..4cece28885 100644 --- a/package.json +++ b/package.json @@ -29,7 +29,7 @@ "devDependencies": { "jscs": "^1.6.2", "jshint": "^2.5.6", - "postcss": "^3.0.0", + "postcss": "^4.0.2", "tape": "^3.0.0" }, "scripts": { From 698990babd6a9a4c51dab874967ada8694c48d93 Mon Sep 17 00:00:00 2001 From: Maxime Thirouin Date: Tue, 27 Jan 2015 07:52:37 +0100 Subject: [PATCH 147/795] ensure compatibility with postcss v4.x --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 3400d122b8..73064a0820 100644 --- a/package.json +++ b/package.json @@ -30,7 +30,7 @@ "devDependencies": { "jscs": "^1.6.2", "jshint": "^2.5.6", - "postcss": "^3.0.0", + "postcss": "^4.0.2", "tape": "^3.0.0" }, "scripts": { From 3079b4691090ded25ccc603eac053117deeacf6c Mon Sep 17 00:00:00 2001 From: Maxime Thirouin Date: Tue, 27 Jan 2015 07:53:22 +0100 Subject: [PATCH 148/795] ensure compatibility with postcss v4.x --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index ea51571040..3f2fcad82b 100644 --- a/package.json +++ b/package.json @@ -29,7 +29,7 @@ "devDependencies": { "jscs": "^1.6.2", "jshint": "^2.5.6", - "postcss": "^3.0.0", + "postcss": "^4.0.2", "tape": "^3.0.0" }, "scripts": { From df3253774d5ba02b92c8c4519884e7a846a5ec13 Mon Sep 17 00:00:00 2001 From: Maxime Thirouin Date: Tue, 27 Jan 2015 07:57:01 +0100 Subject: [PATCH 149/795] ensure compatibility with postcss v4.x poke @yisibl --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index efe73ae07e..03f706ebad 100644 --- a/package.json +++ b/package.json @@ -27,7 +27,7 @@ "index.js" ], "devDependencies": { - "postcss": "^3.0.7", + "postcss": "^4.0.2", "tape": "^3.0.0" }, "bugs": { From c1ececdc5f48c9a94d3e4fe8b3ae907e5b60f6d8 Mon Sep 17 00:00:00 2001 From: Maxime Thirouin Date: Tue, 27 Jan 2015 08:05:46 +0100 Subject: [PATCH 150/795] compatibility with postcss v4.x --- CHANGELOG.md | 7 ++++++- package.json | 4 ++-- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ae078d9d35..8f991d9506 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,11 @@ +# 2.0.0 - 2015-01-26 + +- Added: compatibility with postcss v4.x +- Removed: compatiblity with postcss v3.x + # 1.1.0 - 2014-11-25 -- Enhanced exceptions +- Changed: Enhanced exceptions # 1.0.0 - 2014-11-01 diff --git a/package.json b/package.json index df0d5d2b8d..e902bdd118 100644 --- a/package.json +++ b/package.json @@ -36,7 +36,7 @@ ], "dependencies": { "color": "^0.7.3", - "postcss-message-helpers": "^1.1.1", + "postcss-message-helpers": "^2.0.0", "reduce-function-call": "^1.0.1" }, "devDependencies": { @@ -44,7 +44,7 @@ "istanbul": "^0.3.5", "istanbul-coveralls": "^1.0.1", "jscs": "^1.8.1", - "postcss": "^3.0.7", + "postcss": "^4.0.2", "tap-spec": "^2.1.0", "tape": "^3.0.3" } From 4757f9dda1d7202d904802d1a04efe0856da303d Mon Sep 17 00:00:00 2001 From: Maxime Thirouin Date: Tue, 27 Jan 2015 08:06:10 +0100 Subject: [PATCH 151/795] v2.0.0 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index e902bdd118..0876448486 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "postcss-color-gray", - "version": "1.1.0", + "version": "2.0.0", "description": "PostCSS plugin to transform gray() function to today's CSS", "repository": "postcss/postcss-color-gray", "author": { From 1ec7ea8ec71a5b05c6f257009cf043bbd3ba1d6a Mon Sep 17 00:00:00 2001 From: Maxime Thirouin Date: Tue, 27 Jan 2015 08:07:44 +0100 Subject: [PATCH 152/795] provide full repository url --- package.json | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/package.json b/package.json index 0876448486..bb3b5f4689 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,10 @@ "name": "postcss-color-gray", "version": "2.0.0", "description": "PostCSS plugin to transform gray() function to today's CSS", - "repository": "postcss/postcss-color-gray", + "repository": { + "type": "git", + "url": "https://github.com/postcss/postcss-color-gray.git" + }, "author": { "name": "Shinnosuke Watanabe", "url": "https://github.com/shinnn" From 8904062209aa9364f88c6f34b2fd6d238951bdb5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marek=20=E2=80=98saji=E2=80=99=20Augustynowicz?= Date: Thu, 22 Jan 2015 12:16:12 +0100 Subject: [PATCH 153/795] Properly handle font-variant-position:normal It has been interpreted same as font-variant:normal, which is not the case: - `font-variant: normal` Resets all `font-variant-*`: https://developer.mozilla.org/en-US/docs/Web/CSS/font-variant#Values - `font-variant-position: normal` Displays text as nighter subscript, nor superscript https://developer.mozilla.org/en-US/docs/Web/CSS/font-variant-position#Values --- index.js | 7 +++++-- test/fixtures/font-variant.expected.css | 2 +- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/index.js b/index.js index 11010aac01..4f52b37499 100755 --- a/index.js +++ b/index.js @@ -17,7 +17,8 @@ var fontVariantProperties = { "font-variant-position": { sub: "\"subs\"", - "super": "\"sups\"" + "super": "\"sups\"", + normal: "\"subs\" off, \"sups\" off" }, "font-variant-caps": { @@ -50,7 +51,9 @@ var fontVariantProperties = { for (var prop in fontVariantProperties) { var keys = fontVariantProperties[prop] for (var key in keys) { - fontVariantProperties["font-variant"][key] = keys[key] + if (!(key in fontVariantProperties["font-variant"])) { + fontVariantProperties["font-variant"][key] = keys[key] + } } } diff --git a/test/fixtures/font-variant.expected.css b/test/fixtures/font-variant.expected.css index 48658080fc..a2c897f8ca 100644 --- a/test/fixtures/font-variant.expected.css +++ b/test/fixtures/font-variant.expected.css @@ -20,6 +20,6 @@ selector { font-variant: all-small-caps; } selector { - font-feature-settings: normal; + font-feature-settings: "subs" off, "sups" off; font-variant-position: normal; } From 16dc97ae0cb00ffd06bcb3e5d127471733f584fd Mon Sep 17 00:00:00 2001 From: Maxime Thirouin Date: Wed, 28 Jan 2015 14:07:45 +0100 Subject: [PATCH 154/795] Update Changelog #3 https://github.com/postcss/postcss-font-variant/pull/3 --- CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index b45da1b421..5befbd8941 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,7 @@ +# Unreleased + +- Fixed: Properly handle font-variant-position:normal ([#3](https://github.com/postcss/postcss-font-variant/pull/3)) + # 1.0.2 - 2015-01-27 - Fixed: Re–use existing font-feature-settings declarations to avoid creating multiples that override themselves ([#1](https://github.com/postcss/postcss-font-variant/pull/1)) From e4a9088642efcba438af1dda80d9ec66b3033d4e Mon Sep 17 00:00:00 2001 From: Maxime Thirouin Date: Wed, 28 Jan 2015 21:30:09 +0100 Subject: [PATCH 155/795] compatibility with postcss v4.x Close #5 --- CHANGELOG.md | 17 +++++++++++------ package.json | 2 +- 2 files changed, 12 insertions(+), 7 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index cf703f5c25..5ba7030480 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,23 +1,28 @@ +# 2.0.0 - 2015-01-28 + +- Added: compatibility with postcss v4.x +- Removed: compatibility with postcss v3.x + # 1.3.0 - 2014-11-25 -- Better gnu message +- Changed: better gnu message # 1.2.1 - 2014-10-09 -- Fix npm description +- Fixed: npm description # 1.2.0 - 2014-10-01 -- Add support for multiples media in query list (ref [#rework-custom-media/5](https://github.com/reworkcss/rework-custom-media/pull/5)) +- Added: support for multiples media in query list (ref [#rework-custom-media/5](https://github.com/reworkcss/rework-custom-media/pull/5)) # 1.1.0 - 2014-09-30 -- Add support for js-defined media queries (fix [#3](https://github.com/postcss/postcss-custom-media/issues/3)) +- Added: support for js-defined media queries (fix [#3](https://github.com/postcss/postcss-custom-media/issues/3)) # 1.0.1 - 2014-09-16 -- Allow whitespace around custom media name (fix [#2](https://github.com/postcss/postcss-custom-media/issues/2)) +- Added: Allow whitespace around custom media name (fix [#2](https://github.com/postcss/postcss-custom-media/issues/2)) # 1.0.0 - 2014-08-12 -First release based on [rework-custom-media](https://github.com/reworkcss/rework-custom-media) v0.1.1 +✨ First release based on [rework-custom-media](https://github.com/reworkcss/rework-custom-media) v0.1.1 diff --git a/package.json b/package.json index ab858fcab3..049d6877b7 100644 --- a/package.json +++ b/package.json @@ -21,7 +21,7 @@ "index.js" ], "dependencies": { - "postcss-message-helpers": "^1.1.0" + "postcss-message-helpers": "^2.0.0" }, "devDependencies": { "jscs": "^1.6.2", From 01c277848c48a60bf1f96ca117ce063d2f849ef7 Mon Sep 17 00:00:00 2001 From: Maxime Thirouin Date: Wed, 28 Jan 2015 21:30:32 +0100 Subject: [PATCH 156/795] v2.0.0 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 049d6877b7..9a1a9591af 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "postcss-custom-media", - "version": "1.3.0", + "version": "2.0.0", "description": " PostCSS plugin to transform W3C CSS Custom Media Queries to more compatible CSS", "keywords": [ "css", From 10e526604f07ac9873b158d53924f52e9aa16f91 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marek=20=E2=80=98saji=E2=80=99=20Augustynowicz?= Date: Thu, 22 Jan 2015 12:34:39 +0100 Subject: [PATCH 157/795] Support font-kerning --- index.js | 5 +++++ test/fixtures/font-variant.css | 3 +++ test/fixtures/font-variant.expected.css | 4 ++++ 3 files changed, 12 insertions(+) diff --git a/index.js b/index.js index 4f52b37499..902218729f 100755 --- a/index.js +++ b/index.js @@ -41,6 +41,11 @@ var fontVariantProperties = { "slashed-zero": "\"zero\"" }, + "font-kerning": { + normal: "\"kern\"", + none: "\"kern\" off" + }, + "font-variant": { normal: "normal", inherit: "inherit" diff --git a/test/fixtures/font-variant.css b/test/fixtures/font-variant.css index 37f1f0ccf9..efe6dc5f2d 100644 --- a/test/fixtures/font-variant.css +++ b/test/fixtures/font-variant.css @@ -18,3 +18,6 @@ selector { selector { font-variant-position: normal; } +selector { + font-kerning: normal; +} diff --git a/test/fixtures/font-variant.expected.css b/test/fixtures/font-variant.expected.css index a2c897f8ca..1a0f5a9bce 100644 --- a/test/fixtures/font-variant.expected.css +++ b/test/fixtures/font-variant.expected.css @@ -23,3 +23,7 @@ selector { font-feature-settings: "subs" off, "sups" off; font-variant-position: normal; } +selector { + font-feature-settings: "kern"; + font-kerning: normal; +} From 38db16b34dd6dfe6aea0af3052e8365373a8139c Mon Sep 17 00:00:00 2001 From: Maxime Thirouin Date: Thu, 29 Jan 2015 07:21:13 +0100 Subject: [PATCH 158/795] 2.0.0 was just 1.0 :/ Close #6 --- CHANGELOG.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5ba7030480..7cfd94823b 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,8 +1,12 @@ -# 2.0.0 - 2015-01-28 +# 3.0.0 - 2015-01-29 - Added: compatibility with postcss v4.x - Removed: compatibility with postcss v3.x +# 2.0.0 [Yanked] + +_You never saw this version (this is a bad release that points to 1.0.0)._ + # 1.3.0 - 2014-11-25 - Changed: better gnu message From 177c593c18b5594a65e6d731b6e906e80b4e88fd Mon Sep 17 00:00:00 2001 From: Maxime Thirouin Date: Thu, 29 Jan 2015 07:21:42 +0100 Subject: [PATCH 159/795] v3.0.0 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 9a1a9591af..58b177ca65 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "postcss-custom-media", - "version": "2.0.0", + "version": "3.0.0", "description": " PostCSS plugin to transform W3C CSS Custom Media Queries to more compatible CSS", "keywords": [ "css", From a73ff8db545e7b60bb6df89a9f9cccc48ba2ce00 Mon Sep 17 00:00:00 2001 From: Maxime Thirouin Date: Thu, 29 Jan 2015 15:35:47 +0100 Subject: [PATCH 160/795] prepare 1.1.0 --- CHANGELOG.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5befbd8941..e48d3f3234 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,7 @@ -# Unreleased +# 1.1.0 - 2015-01-29 - Fixed: Properly handle font-variant-position:normal ([#3](https://github.com/postcss/postcss-font-variant/pull/3)) +- Added: support font-kerning ([#2](https://github.com/postcss/postcss-font-variant/pull/2)) # 1.0.2 - 2015-01-27 From 30c93bc184998b3f9f1bfa98b9bc9af32cfe97ac Mon Sep 17 00:00:00 2001 From: Maxime Thirouin Date: Thu, 29 Jan 2015 15:41:06 +0100 Subject: [PATCH 161/795] v1.1.0 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 39dcda5fe0..f906e4d3a9 100755 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "postcss-font-variant", - "version": "1.0.2", + "version": "1.1.0", "description": "PostCSS plugin to transform W3C font-variant properties to more compatible CSS (font-feature-settings)", "keywords": [ "css", From 8bba058fa92a1a197040c5e7fd7a4d68d4f33695 Mon Sep 17 00:00:00 2001 From: Maxime Thirouin Date: Fri, 6 Feb 2015 07:30:30 +0100 Subject: [PATCH 162/795] Fixed: logs now have filename back (3.0.1) Close #19 --- CHANGELOG.md | 39 +++++++++++++++++++++------------------ package.json | 4 ++-- 2 files changed, 23 insertions(+), 20 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c0d6e93dce..b40d6777ef 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,53 +1,56 @@ +# 3.0.1 - 2015-02-06 + +- Fixed: logs now have filename back ([#19](https://github.com/postcss/postcss-custom-properties/issues/19)) + # 3.0.0 - 2015-01-20 -- Upgrade to postcss 4 ([#18](https://github.com/postcss/postcss-custom-properties/pull/18)) -- Remove some code that seems to be useless ([16ff3c2](https://github.com/postcss/postcss-custom-properties/commit/16ff3c22fe0563a1283411d7866791966fff4c58)) -- Use a new postcss 4 method `cloneBefore` ([604168e](https://github.com/postcss/postcss-custom-properties/commit/604168e4e28379c3a42c8a8255957a65ec6b2c27)) +- Changed: upgrade to postcss 4 ([#18](https://github.com/postcss/postcss-custom-properties/pull/18)) +- Removed: some code that seems to be useless ([16ff3c2](https://github.com/postcss/postcss-custom-properties/commit/16ff3c22fe0563a1283411d7866791966fff4c58)) # 2.1.1 - 2014-12-02 -- Fix issue when multiples undefined custom properties are referenced ([#16](https://github.com/postcss/postcss-custom-properties/issues/16)) +- Fixed: issue when multiples undefined custom properties are referenced ([#16](https://github.com/postcss/postcss-custom-properties/issues/16)) # 2.1.0 - 2014-11-25 -- Enhanced exceptions & messages +- Added: enhanced exceptions & messages # 2.0.0 - 2014-11-12 -- Upgrade to postcss 3 +- Changed: upgrade to postcss 3 # 1.0.2 - 2014-11-04 -- More clear message for warning about custom prop used in non top-level :root +- Fixed: more clear message for warning about custom prop used in non top-level :root # 1.0.1 - 2014-11-03 -- fix warning about custom prop used in non :root +- Fixed: warning about custom prop used in non :root # 1.0.0 - 2014-11-02 -- Add warning when a custom prop is used in another place than :root -- handle !important +- Added: warning when a custom prop is used in another place than :root +- Added: handle !important # 0.4.0 - 2014-09-30 -- JS-defined properties override CSS-defined +- Added: JS-defined properties override CSS-defined # 0.3.1 - 2014-08-27 -- Nested custom properties usages are now correctly resolved -- Undefined var doesn't throw error anymore (just a console warning) & are kept as is in the output +- Added: nested custom properties usages are now correctly resolved +- Changed: undefined var doesn't throw error anymore (just a console warning) & are kept as is in the output # 0.3.0 - 2014-08-26 -- Fallback now are always added by default ([see why](http://www.w3.org/TR/css-variables/#invalid-variables)) -- `map` option renamed to `variables` +- Changed: fallback now are always added by default ([see why](http://www.w3.org/TR/css-variables/#invalid-variables)) +- Changed: `map` option renamed to `variables` # 0.2.0 - 2014-08-22 -- Add `map` option -- GNU style error message +- Added: `map` option +- Changed: GNU style error message # 0.1.0 - 2014-08-01 -First release based on [rework-vars](https://github.com/reworkcss/rework-vars) v3.1.1 +✨ First release based on [rework-vars](https://github.com/reworkcss/rework-vars) v3.1.1 diff --git a/package.json b/package.json index 27d5a1bfdf..13ecb8c944 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "postcss-custom-properties", - "version": "3.0.0", + "version": "3.0.1", "description": "PostCSS plugin to polyfill W3C CSS Custom Properties for cascading variables", "keywords": [ "css", @@ -23,7 +23,7 @@ ], "dependencies": { "balanced-match": "~0.1.0", - "postcss-message-helpers": "^1.1.0" + "postcss-message-helpers": "^2.0.0" }, "devDependencies": { "jscs": "^1.6.2", From 6b2259c47b9a749552b543b0f0c25bd392e7c8c5 Mon Sep 17 00:00:00 2001 From: vlad saling Date: Sun, 22 Feb 2015 23:30:11 +0100 Subject: [PATCH 163/795] fixing typo in grunt config example --- README-zh.md | 2 +- README.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/README-zh.md b/README-zh.md index 113d4ad332..32e204f5fc 100644 --- a/README-zh.md +++ b/README-zh.md @@ -163,7 +163,7 @@ module.exports = function(grunt) { options: { processors: [ require('autoprefixer-core')({ browsers: ['> 0%'] }).postcss, //Other plugin - require('postcss-custom-selector')(), + require('postcss-custom-selectors')(), ] }, dist: { diff --git a/README.md b/README.md index 0f6ce43587..de62ed6583 100644 --- a/README.md +++ b/README.md @@ -163,7 +163,7 @@ module.exports = function(grunt) { options: { processors: [ require('autoprefixer-core')({ browsers: ['> 0%'] }).postcss, //Other plugin - require('postcss-custom-selector')(), + require('postcss-custom-selectors')(), ] }, dist: { From 0691784ed2218d7e6b16da8c4df03e2ca0c4798c Mon Sep 17 00:00:00 2001 From: Matthias Le Brun Date: Mon, 16 Mar 2015 13:43:28 +0100 Subject: [PATCH 164/795] added automatic variabled prefixing --- index.js | 11 ++++++++++- test/fixtures/automatic-variable-prefix.css | 4 ++++ test/fixtures/automatic-variable-prefix.expected.css | 4 ++++ test/index.js | 10 ++++++++++ 4 files changed, 28 insertions(+), 1 deletion(-) create mode 100644 test/fixtures/automatic-variable-prefix.css create mode 100644 test/fixtures/automatic-variable-prefix.expected.css diff --git a/index.js b/index.js index 8e9f681902..78f1d14200 100755 --- a/index.js +++ b/index.js @@ -20,7 +20,16 @@ var RE_VAR = /([\w-]+)(?:\s*,\s*)?(.*)?/ // matches `name[, fallback]`, captures module.exports = function(options) { return function(style) { options = options || {} - var variables = options.variables || {} + var userVariables = options.variables || {} + var variables = + Object.keys(userVariables) + .reduce(function(acc, key) { + if (key.indexOf("--") !== 0) { + acc["--" + key] = userVariables[key] + } + acc[key] = userVariables[key] + return acc + }, {}) var preserve = (options.preserve === true ? true : false) var map = {} var importantMap = {} diff --git a/test/fixtures/automatic-variable-prefix.css b/test/fixtures/automatic-variable-prefix.css new file mode 100644 index 0000000000..bf61e60b57 --- /dev/null +++ b/test/fixtures/automatic-variable-prefix.css @@ -0,0 +1,4 @@ +div { + color: var(--unprefixed); + background: var(--prefixed); +} diff --git a/test/fixtures/automatic-variable-prefix.expected.css b/test/fixtures/automatic-variable-prefix.expected.css new file mode 100644 index 0000000000..b9f2fdb43f --- /dev/null +++ b/test/fixtures/automatic-variable-prefix.expected.css @@ -0,0 +1,4 @@ +div { + color: blue; + background: white; +} diff --git a/test/index.js b/test/index.js index b6953b1a6b..d2ba9be249 100755 --- a/test/index.js +++ b/test/index.js @@ -56,6 +56,16 @@ test("accepts variables defined from JavaScript, and overrides local definitions t.end() }) +test("prefixes js defined variabled with a double dash automatically", function(t) { + compareFixtures(t, "automatic-variable-prefix", { + variables: { + unprefixed: "blue", + "--prefixed": "white" + } + }) + t.end() +}) + test("removes variable properties from the output", function(t) { compareFixtures(t, "remove-properties") t.end() From c1e190715ea23a86be85cdd6f2df95b05a15c524 Mon Sep 17 00:00:00 2001 From: Matthias Le Brun Date: Mon, 16 Mar 2015 13:48:53 +0100 Subject: [PATCH 165/795] documented JS keys auto-prefixing --- CHANGELOG.md | 5 +++++ README.md | 2 ++ package.json | 2 +- 3 files changed, 8 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b40d6777ef..7f336d27c7 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,8 @@ +# 3.1.0 - 2015-03-16 + +- Added: variables defined in JS are now automatically prefixed with `--` + ([0691784](https://github.com/postcss/postcss-custom-properties/commit/0691784ed2218d7e6b16da8c4df03e2ca0c4798c)) + # 3.0.1 - 2015-02-06 - Fixed: logs now have filename back ([#19](https://github.com/postcss/postcss-custom-properties/issues/19)) diff --git a/README.md b/README.md index f097715a50..076835a7e0 100755 --- a/README.md +++ b/README.md @@ -69,6 +69,8 @@ var out = postcss() #### `variables` (default: `{}`) Allow you to pass an object of variables for `:root`. These definitions will override any that exist in the CSS. +The keys are automatically prefixed with the CSS `--` to make it easier to share +variables in your codebase. --- diff --git a/package.json b/package.json index 13ecb8c944..0c290f4720 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "postcss-custom-properties", - "version": "3.0.1", + "version": "3.1.0", "description": "PostCSS plugin to polyfill W3C CSS Custom Properties for cascading variables", "keywords": [ "css", From 78e550eb0e60c00f7430c70f5285872c2c8d1a40 Mon Sep 17 00:00:00 2001 From: Maxime Thirouin Date: Tue, 31 Mar 2015 10:00:18 +0200 Subject: [PATCH 166/795] Replace jscs+jshint by eslint --- .eslintrc | 26 +++++++++ index.js | 150 +++++++++++++++++++++++++------------------------- package.json | 6 +- test/index.js | 8 +-- 4 files changed, 107 insertions(+), 83 deletions(-) create mode 100644 .eslintrc diff --git a/.eslintrc b/.eslintrc new file mode 100644 index 0000000000..db389353cb --- /dev/null +++ b/.eslintrc @@ -0,0 +1,26 @@ +--- +ecmaFeatures: + modules: true + +env: + es6: true + browser: true + node: true + +# 0: off, 1: warning, 2: error +rules: + # semicolons are useless + semi: [2, "never"] + + quotes: [2, "double"] + + # 2 spaces indentation + indent: [2, 2] + + # trailing coma are cool for diff + comma-dangle: [2, "always-multiline"] + + # enforce comma at eol (never before) + comma-style: [2, "last"] + + valid-jsdoc: 2 diff --git a/index.js b/index.js index 78f1d14200..cf6896cd61 100755 --- a/index.js +++ b/index.js @@ -13,6 +13,79 @@ var VAR_PROP_IDENTIFIER = "--" var VAR_FUNC_IDENTIFIER = "var" var RE_VAR = /([\w-]+)(?:\s*,\s*)?(.*)?/ // matches `name[, fallback]`, captures "name" and "fallback" +/** + * Resolve CSS variables in a value + * + * The second argument to a CSS variable function, if provided, is a fallback + * value, which is used as the substitution value when the referenced variable + * is invalid. + * + * var(name[, fallback]) + * + * @param {String} value A property value known to contain CSS variable functions + * @param {Object} variables A map of variable names and values + * @param {Object} source source object of the declaration containing the rule + * @return {String} A property value with all CSS variables substituted. + */ + +function resolveValue(value, variables, source) { + var results = [] + + var start = value.indexOf(VAR_FUNC_IDENTIFIER + "(") + if (start === -1) { + return [value] + } + + var matches = balanced("(", ")", value.substring(start)) + + if (!matches) { + throw new SyntaxError("missing closing ')' in the value '" + value + "'") + } + + if (matches.body === "") { + throw new Error("var() must contain a non-whitespace string") + } + + matches.body.replace(RE_VAR, function(_, name, fallback) { + var replacement = variables[name] + if (!replacement && !fallback) { + console.warn(helpers.message("variable '" + name + "' is undefined and used without a fallback", source)) + } + + // prepend with fallbacks + if (fallback) { + // resolve the end of the expression before the rest + (matches.post ? resolveValue(matches.post, variables, source) : [""]).forEach(function(afterValue) { + // resolve fallback values + resolveValue(fallback, variables, source).forEach(function(fbValue) { + results.push(value.slice(0, start) + fbValue + afterValue) + }) + }) + } + + // replace with computed custom properties + if (replacement) { + // resolve the end of the expression + (matches.post ? resolveValue(matches.post, variables, source) : [""]).forEach(function(afterValue) { + // resolve replacement if it use a custom property + resolveValue(replacement, variables, source).forEach(function(replacementValue) { + results.push(value.slice(0, start) + replacementValue + afterValue) + }) + }) + } + + // nothing, just keep original value + if (!replacement && !fallback) { + // resolve the end of the expression + (matches.post ? resolveValue(matches.post, variables, source) : [""]).forEach(function(afterValue) { + results.push(value.slice(0, start) + VAR_FUNC_IDENTIFIER + "(" + name + ")" + afterValue) + }) + } + }) + + return results +} + /** * Module export. */ @@ -56,14 +129,14 @@ module.exports = function(options) { return } - rule.each(function(decl, i) { + rule.each(function(decl, index) { var prop = decl.prop if (prop && prop.indexOf(VAR_PROP_IDENTIFIER) === 0) { if (!map[prop] || !importantMap[prop] || decl.important) { map[prop] = decl.value importantMap[prop] = decl.important } - toRemove.push(i) + toRemove.push(index) } }) @@ -107,76 +180,3 @@ module.exports = function(options) { }) } } - -/** - * Resolve CSS variables in a value - * - * The second argument to a CSS variable function, if provided, is a fallback - * value, which is used as the substitution value when the referenced variable - * is invalid. - * - * var(name[, fallback]) - * - * @param {String} value A property value known to contain CSS variable functions - * @param {Object} variables A map of variable names and values - * @param {Object} source source object of the declaration containing the rule - * @return {String} A property value with all CSS variables substituted. - */ - -function resolveValue(value, variables, source) { - var results = [] - - var start = value.indexOf(VAR_FUNC_IDENTIFIER + "(") - if (start === -1) { - return [value] - } - - var matches = balanced("(", ")", value.substring(start)) - - if (!matches) { - throw new SyntaxError("missing closing ')' in the value '" + value + "'") - } - - if (matches.body === "") { - throw new Error("var() must contain a non-whitespace string") - } - - matches.body.replace(RE_VAR, function(_, name, fallback) { - var replacement = variables[name] - if (!replacement && !fallback) { - console.warn(helpers.message("variable '" + name + "' is undefined and used without a fallback", source)) - } - - // prepend with fallbacks - if (fallback) { - // resolve the end of the expression before the rest - (matches.post ? resolveValue(matches.post, variables, source) : [""]).forEach(function(afterValue) { - // resolve fallback values - resolveValue(fallback, variables, source).forEach(function(fbValue) { - results.push(value.slice(0, start) + fbValue + afterValue) - }) - }) - } - - // replace with computed custom properties - if (replacement) { - // resolve the end of the expression - (matches.post ? resolveValue(matches.post, variables, source) : [""]).forEach(function(afterValue) { - // resolve replacement if it use a custom property - resolveValue(replacement, variables, source).forEach(function(replacementValue) { - results.push(value.slice(0, start) + replacementValue + afterValue) - }) - }) - } - - // nothing, just keep original value - if (!replacement && !fallback) { - // resolve the end of the expression - (matches.post ? resolveValue(matches.post, variables, source) : [""]).forEach(function(afterValue) { - results.push(value.slice(0, start) + VAR_FUNC_IDENTIFIER + "(" + name + ")" + afterValue) - }) - } - }) - - return results -} diff --git a/package.json b/package.json index 0c290f4720..5c30b8092b 100644 --- a/package.json +++ b/package.json @@ -26,13 +26,11 @@ "postcss-message-helpers": "^2.0.0" }, "devDependencies": { - "jscs": "^1.6.2", - "jshint": "^2.5.6", + "eslint": "^0.18.0", "postcss": "^4.0.0", "tape": "^3.0.0" }, "scripts": { - "lint": "jscs *.js **/*.js && jshint . --exclude-path .gitignore", - "test": "npm run lint && tape test" + "test": "eslint . && tape test" } } diff --git a/test/index.js b/test/index.js index d2ba9be249..0820bf98eb 100755 --- a/test/index.js +++ b/test/index.js @@ -50,8 +50,8 @@ test("accepts variables defined from JavaScript, and overrides local definitions variables: { "--test-one": "js-one", "--test-two": "js-two", - "--test-three": "js-three" - } + "--test-three": "js-three", + }, }) t.end() }) @@ -60,8 +60,8 @@ test("prefixes js defined variabled with a double dash automatically", function( compareFixtures(t, "automatic-variable-prefix", { variables: { unprefixed: "blue", - "--prefixed": "white" - } + "--prefixed": "white", + }, }) t.end() }) From a5aa2bfe92d7b5414a9037efa3da95609f2ffdff Mon Sep 17 00:00:00 2001 From: Maxime Thirouin Date: Tue, 31 Mar 2015 10:09:14 +0200 Subject: [PATCH 167/795] Added: JS defined variables are now resolved too (3.2.0) --- CHANGELOG.md | 4 ++++ index.js | 2 +- package.json | 2 +- test/fixtures/js-defined.css | 8 +++++--- test/fixtures/js-defined.expected.css | 8 +++++--- test/index.js | 2 ++ 6 files changed, 18 insertions(+), 8 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7f336d27c7..beb3db5ebd 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,7 @@ +# 3.2.0 - 2015-03-31 + +- Added: JS defined variables are now resolved too ([#22](https://github.com/postcss/postcss-custom-properties/issues/22)) + # 3.1.0 - 2015-03-16 - Added: variables defined in JS are now automatically prefixed with `--` diff --git a/index.js b/index.js index cf6896cd61..adbd9877bb 100755 --- a/index.js +++ b/index.js @@ -155,7 +155,7 @@ module.exports = function(options) { // apply js-defined custom properties Object.keys(variables).forEach(function(variable) { - map[variable] = variables[variable] + map[variable] = resolveValue(variables[variable], map) }) // resolve variables diff --git a/package.json b/package.json index 5c30b8092b..92ee6afb02 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "postcss-custom-properties", - "version": "3.1.0", + "version": "3.2.0", "description": "PostCSS plugin to polyfill W3C CSS Custom Properties for cascading variables", "keywords": [ "css", diff --git a/test/fixtures/js-defined.css b/test/fixtures/js-defined.css index 68c6ec67df..0a90407c68 100755 --- a/test/fixtures/js-defined.css +++ b/test/fixtures/js-defined.css @@ -4,7 +4,9 @@ } div { - color: var(--test-one); - color: var(--test-two); - color: var(--test-three); + p: var(--test-one); + p: var(--test-two); + p: var(--test-three); + p: var(--test-varception); + p: var(--test-jsception); } diff --git a/test/fixtures/js-defined.expected.css b/test/fixtures/js-defined.expected.css index c4fcd971c6..79a663e0b0 100755 --- a/test/fixtures/js-defined.expected.css +++ b/test/fixtures/js-defined.expected.css @@ -1,5 +1,7 @@ div { - color: js-one; - color: js-two; - color: js-three; + p: js-one; + p: js-two; + p: js-three; + p: js-one; + p: js-one; } diff --git a/test/index.js b/test/index.js index 0820bf98eb..b7836d0929 100755 --- a/test/index.js +++ b/test/index.js @@ -51,6 +51,8 @@ test("accepts variables defined from JavaScript, and overrides local definitions "--test-one": "js-one", "--test-two": "js-two", "--test-three": "js-three", + "--test-varception": "var(--test-one)", + "--test-jsception": "var(--test-varception)", }, }) t.end() From fd915ff7436ccbc1ffc0180e18c4cf87c1216170 Mon Sep 17 00:00:00 2001 From: Glen Huang Date: Thu, 2 Apr 2015 17:35:11 +0800 Subject: [PATCH 168/795] Not resolve values while copying --- index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/index.js b/index.js index adbd9877bb..cf6896cd61 100755 --- a/index.js +++ b/index.js @@ -155,7 +155,7 @@ module.exports = function(options) { // apply js-defined custom properties Object.keys(variables).forEach(function(variable) { - map[variable] = resolveValue(variables[variable], map) + map[variable] = variables[variable] }) // resolve variables From 014fff81c7a581942683d7a94ba9ac1b3d0b4a75 Mon Sep 17 00:00:00 2001 From: Glen Huang Date: Fri, 3 Apr 2015 22:03:30 +0800 Subject: [PATCH 169/795] Throw error for self-referential variables --- index.js | 23 ++++++++++++++++------- 1 file changed, 16 insertions(+), 7 deletions(-) diff --git a/index.js b/index.js index cf6896cd61..5b4a63a266 100755 --- a/index.js +++ b/index.js @@ -24,11 +24,16 @@ var RE_VAR = /([\w-]+)(?:\s*,\s*)?(.*)?/ // matches `name[, fallback]`, captures * * @param {String} value A property value known to contain CSS variable functions * @param {Object} variables A map of variable names and values + * @param {Array} deps An array of variable names the current variable depends on * @param {Object} source source object of the declaration containing the rule * @return {String} A property value with all CSS variables substituted. */ -function resolveValue(value, variables, source) { +function resolveValue(value, variables, deps, source) { + if (!deps) { + deps = [] + } + var results = [] var start = value.indexOf(VAR_FUNC_IDENTIFIER + "(") @@ -47,6 +52,9 @@ function resolveValue(value, variables, source) { } matches.body.replace(RE_VAR, function(_, name, fallback) { + if (deps.indexOf(name) !== -1) { + throw new Error("self-referential variable: " + name) + } var replacement = variables[name] if (!replacement && !fallback) { console.warn(helpers.message("variable '" + name + "' is undefined and used without a fallback", source)) @@ -55,9 +63,9 @@ function resolveValue(value, variables, source) { // prepend with fallbacks if (fallback) { // resolve the end of the expression before the rest - (matches.post ? resolveValue(matches.post, variables, source) : [""]).forEach(function(afterValue) { + (matches.post ? resolveValue(matches.post, variables, [], source) : [""]).forEach(function(afterValue) { // resolve fallback values - resolveValue(fallback, variables, source).forEach(function(fbValue) { + resolveValue(fallback, variables, [], source).forEach(function(fbValue) { results.push(value.slice(0, start) + fbValue + afterValue) }) }) @@ -65,10 +73,11 @@ function resolveValue(value, variables, source) { // replace with computed custom properties if (replacement) { + deps.push(name); // resolve the end of the expression - (matches.post ? resolveValue(matches.post, variables, source) : [""]).forEach(function(afterValue) { + (matches.post ? resolveValue(matches.post, variables, [], source) : [""]).forEach(function(afterValue) { // resolve replacement if it use a custom property - resolveValue(replacement, variables, source).forEach(function(replacementValue) { + resolveValue(replacement, variables, deps, source).forEach(function(replacementValue) { results.push(value.slice(0, start) + replacementValue + afterValue) }) }) @@ -77,7 +86,7 @@ function resolveValue(value, variables, source) { // nothing, just keep original value if (!replacement && !fallback) { // resolve the end of the expression - (matches.post ? resolveValue(matches.post, variables, source) : [""]).forEach(function(afterValue) { + (matches.post ? resolveValue(matches.post, variables, [], source) : [""]).forEach(function(afterValue) { results.push(value.slice(0, start) + VAR_FUNC_IDENTIFIER + "(" + name + ")" + afterValue) }) } @@ -168,7 +177,7 @@ module.exports = function(options) { } helpers.try(function resolve() { - resolveValue(value, map, decl.source).forEach(function(resolvedValue) { + resolveValue(value, map, [], decl.source).forEach(function(resolvedValue) { var clone = decl.cloneBefore() clone.value = resolvedValue }) From ec028ab59c8e650ebf46f57590c0cbd02a01e3e5 Mon Sep 17 00:00:00 2001 From: Glen Huang Date: Fri, 3 Apr 2015 23:33:07 +0800 Subject: [PATCH 170/795] Cache resolved variables --- index.js | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/index.js b/index.js index 5b4a63a266..7f37695b97 100755 --- a/index.js +++ b/index.js @@ -73,11 +73,16 @@ function resolveValue(value, variables, deps, source) { // replace with computed custom properties if (replacement) { - deps.push(name); + deps.push(name) + // resolve replacement if it use a custom property + if (!Array.isArray(replacement)) { + replacement = resolveValue(replacement, variables, deps, source) + variables[name] = replacement + } // resolve the end of the expression - (matches.post ? resolveValue(matches.post, variables, [], source) : [""]).forEach(function(afterValue) { - // resolve replacement if it use a custom property - resolveValue(replacement, variables, deps, source).forEach(function(replacementValue) { + var post = matches.post ? resolveValue(matches.post, variables, [], source) : [""] + replacement.forEach(function(replacementValue) { + post.forEach(function(afterValue) { results.push(value.slice(0, start) + replacementValue + afterValue) }) }) From e6f1f8281b7f61452989244d6c67c09a8774b5d1 Mon Sep 17 00:00:00 2001 From: Glen Huang Date: Sat, 4 Apr 2015 09:54:38 +0800 Subject: [PATCH 171/795] Reword circular reference error messages --- index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/index.js b/index.js index 7f37695b97..66e34c52c4 100755 --- a/index.js +++ b/index.js @@ -53,7 +53,7 @@ function resolveValue(value, variables, deps, source) { matches.body.replace(RE_VAR, function(_, name, fallback) { if (deps.indexOf(name) !== -1) { - throw new Error("self-referential variable: " + name) + throw new Error("circular variable reference: " + name) } var replacement = variables[name] if (!replacement && !fallback) { From 0f78590ea213c57ba0ec9b0e263a19c2d231cf91 Mon Sep 17 00:00:00 2001 From: Glen Huang Date: Sat, 4 Apr 2015 09:59:26 +0800 Subject: [PATCH 172/795] Refactor variable resolutions --- index.js | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/index.js b/index.js index 66e34c52c4..dfc2356a5d 100755 --- a/index.js +++ b/index.js @@ -59,13 +59,15 @@ function resolveValue(value, variables, deps, source) { if (!replacement && !fallback) { console.warn(helpers.message("variable '" + name + "' is undefined and used without a fallback", source)) } - + var resolved, post // prepend with fallbacks if (fallback) { + // resolve fallback values + resolved = resolveValue(fallback, variables, [], source) // resolve the end of the expression before the rest - (matches.post ? resolveValue(matches.post, variables, [], source) : [""]).forEach(function(afterValue) { - // resolve fallback values - resolveValue(fallback, variables, [], source).forEach(function(fbValue) { + post = matches.post ? resolveValue(matches.post, variables, [], source) : [""] + resolved.forEach(function(fbValue) { + post.forEach(function(afterValue) { results.push(value.slice(0, start) + fbValue + afterValue) }) }) @@ -80,7 +82,7 @@ function resolveValue(value, variables, deps, source) { variables[name] = replacement } // resolve the end of the expression - var post = matches.post ? resolveValue(matches.post, variables, [], source) : [""] + post = matches.post ? resolveValue(matches.post, variables, [], source) : [""] replacement.forEach(function(replacementValue) { post.forEach(function(afterValue) { results.push(value.slice(0, start) + replacementValue + afterValue) @@ -90,8 +92,9 @@ function resolveValue(value, variables, deps, source) { // nothing, just keep original value if (!replacement && !fallback) { + resolved = matches.post ? resolveValue(matches.post, variables, [], source) : [""] // resolve the end of the expression - (matches.post ? resolveValue(matches.post, variables, [], source) : [""]).forEach(function(afterValue) { + resolved.forEach(function(afterValue) { results.push(value.slice(0, start) + VAR_FUNC_IDENTIFIER + "(" + name + ")" + afterValue) }) } From d0082b22cda86be288c3e56d5d9c991626801f46 Mon Sep 17 00:00:00 2001 From: Glen Huang Date: Sat, 4 Apr 2015 14:01:55 +0800 Subject: [PATCH 173/795] Add unit tests for circular variable references --- test/fixtures/circular-reference.css | 4 ++++ test/fixtures/self-reference.css | 3 +++ test/index.js | 16 +++++++++++++++- 3 files changed, 22 insertions(+), 1 deletion(-) create mode 100644 test/fixtures/circular-reference.css create mode 100644 test/fixtures/self-reference.css diff --git a/test/fixtures/circular-reference.css b/test/fixtures/circular-reference.css new file mode 100644 index 0000000000..e49b0adcbf --- /dev/null +++ b/test/fixtures/circular-reference.css @@ -0,0 +1,4 @@ +:root { + --color: var(--bg-color); + --bg-color: var(--color); +} diff --git a/test/fixtures/self-reference.css b/test/fixtures/self-reference.css new file mode 100644 index 0000000000..adf6bde3f7 --- /dev/null +++ b/test/fixtures/self-reference.css @@ -0,0 +1,3 @@ +:root { + --color: var(--color); +} diff --git a/test/index.js b/test/index.js index b7836d0929..777ea3a6a2 100755 --- a/test/index.js +++ b/test/index.js @@ -13,8 +13,12 @@ function fixture(name) { return fs.readFileSync(fixturePath(name), "utf8").trim() } +function resolveFixture(name, options) { + return postcss(customProperties(options)).process(fixture(name), {from: fixturePath(name)}).css.trim() +} + function compareFixtures(t, name, options) { - var actual = postcss(customProperties(options)).process(fixture(name), {from: fixturePath(name)}).css.trim() + var actual = resolveFixture(name, options) // handy thing: checkout actual in the *.actual.css file fs.writeFile(fixturePath(name + ".actual"), actual) @@ -102,3 +106,13 @@ test("preserves variables when `preserve` is `true`", function(t) { compareFixtures(t, "preserve-variables", {preserve: true}) t.end() }) + +test("throw error for circular variable references", function(t) { + t.throws(function() { + resolveFixture("self-reference", {preserve: true}) + }, Error, "should throw error for self-referential variables") + t.throws(function() { + resolveFixture("circular-reference", {preserve: true}) + }, Error, "should throw error for circular variable references") + t.end() +}) From e99892845db0562b995c535e6d698db733e4bcdf Mon Sep 17 00:00:00 2001 From: Glen Huang Date: Sat, 4 Apr 2015 18:24:09 +0800 Subject: [PATCH 174/795] Not throw error for circular variable references --- index.js | 97 +++++++++++-------- test/fixtures/circular-reference.css | 3 + test/fixtures/circular-reference.expected.css | 3 + .../self-reference-double-fallback.css | 6 ++ ...elf-reference-double-fallback.expected.css | 4 + test/fixtures/self-reference-fallback.css | 6 ++ .../self-reference-fallback.expected.css | 3 + test/fixtures/self-reference.css | 3 + test/fixtures/self-reference.expected.css | 3 + test/index.js | 16 +-- 10 files changed, 98 insertions(+), 46 deletions(-) create mode 100644 test/fixtures/circular-reference.expected.css create mode 100644 test/fixtures/self-reference-double-fallback.css create mode 100644 test/fixtures/self-reference-double-fallback.expected.css create mode 100644 test/fixtures/self-reference-fallback.css create mode 100644 test/fixtures/self-reference-fallback.expected.css create mode 100644 test/fixtures/self-reference.expected.css diff --git a/index.js b/index.js index dfc2356a5d..3a92397f6c 100755 --- a/index.js +++ b/index.js @@ -24,16 +24,11 @@ var RE_VAR = /([\w-]+)(?:\s*,\s*)?(.*)?/ // matches `name[, fallback]`, captures * * @param {String} value A property value known to contain CSS variable functions * @param {Object} variables A map of variable names and values - * @param {Array} deps An array of variable names the current variable depends on * @param {Object} source source object of the declaration containing the rule * @return {String} A property value with all CSS variables substituted. */ -function resolveValue(value, variables, deps, source) { - if (!deps) { - deps = [] - } - +function resolveValue(value, variables, source) { var results = [] var start = value.indexOf(VAR_FUNC_IDENTIFIER + "(") @@ -52,52 +47,66 @@ function resolveValue(value, variables, deps, source) { } matches.body.replace(RE_VAR, function(_, name, fallback) { - if (deps.indexOf(name) !== -1) { - throw new Error("circular variable reference: " + name) - } - var replacement = variables[name] - if (!replacement && !fallback) { + var variable = variables[name] + var post + // undefined and without fallback, just keep original value + if (!variable && !fallback) { console.warn(helpers.message("variable '" + name + "' is undefined and used without a fallback", source)) + post = matches.post ? resolveValue(matches.post, variables, source) : [""] + // resolve the end of the expression + post.forEach(function(afterValue) { + results.push(value.slice(0, start) + VAR_FUNC_IDENTIFIER + "(" + name + ")" + afterValue) + }) + return } - var resolved, post + // prepend with fallbacks if (fallback) { // resolve fallback values - resolved = resolveValue(fallback, variables, [], source) + fallback = resolveValue(fallback, variables, source) // resolve the end of the expression before the rest - post = matches.post ? resolveValue(matches.post, variables, [], source) : [""] - resolved.forEach(function(fbValue) { + post = matches.post ? resolveValue(matches.post, variables, source) : [""] + fallback.forEach(function(fbValue) { post.forEach(function(afterValue) { results.push(value.slice(0, start) + fbValue + afterValue) }) }) } + if (!variable) { + return + } + // replace with computed custom properties - if (replacement) { - deps.push(name) - // resolve replacement if it use a custom property - if (!Array.isArray(replacement)) { - replacement = resolveValue(replacement, variables, deps, source) - variables[name] = replacement + if (!variable.resolved) { + // circular reference encountered + if (variable.deps.indexOf(name) !== -1) { + if (!fallback) { + console.warn(helpers.message("circular variable reference: " + name, source)) + variable.value = [variable.value] + variable.circular = true + } + else { + variable.value = fallback + return + } } - // resolve the end of the expression - post = matches.post ? resolveValue(matches.post, variables, [], source) : [""] - replacement.forEach(function(replacementValue) { - post.forEach(function(afterValue) { - results.push(value.slice(0, start) + replacementValue + afterValue) - }) - }) + else { + variable.deps.push(name) + variable.value = resolveValue(variable.value, variables, source) + } + variable.resolved = true } - - // nothing, just keep original value - if (!replacement && !fallback) { - resolved = matches.post ? resolveValue(matches.post, variables, [], source) : [""] - // resolve the end of the expression - resolved.forEach(function(afterValue) { - results.push(value.slice(0, start) + VAR_FUNC_IDENTIFIER + "(" + name + ")" + afterValue) - }) + if (variable.circular && fallback) { + return } + // resolve the end of the expression + post = matches.post ? resolveValue(matches.post, variables, source) : [""] + variable.value.forEach(function(replacementValue) { + post.forEach(function(afterValue) { + results.push(value.slice(0, start) + replacementValue + afterValue) + }) + }) }) return results @@ -150,7 +159,12 @@ module.exports = function(options) { var prop = decl.prop if (prop && prop.indexOf(VAR_PROP_IDENTIFIER) === 0) { if (!map[prop] || !importantMap[prop] || decl.important) { - map[prop] = decl.value + map[prop] = { + value: decl.value, + deps: [], + circular: false, + resolved: false, + } importantMap[prop] = decl.important } toRemove.push(index) @@ -172,7 +186,12 @@ module.exports = function(options) { // apply js-defined custom properties Object.keys(variables).forEach(function(variable) { - map[variable] = variables[variable] + map[variable] = { + value: variables[variable], + deps: [], + circular: false, + resolved: false, + } }) // resolve variables @@ -185,7 +204,7 @@ module.exports = function(options) { } helpers.try(function resolve() { - resolveValue(value, map, [], decl.source).forEach(function(resolvedValue) { + resolveValue(value, map, decl.source).forEach(function(resolvedValue) { var clone = decl.cloneBefore() clone.value = resolvedValue }) diff --git a/test/fixtures/circular-reference.css b/test/fixtures/circular-reference.css index e49b0adcbf..d1ae2d5e01 100644 --- a/test/fixtures/circular-reference.css +++ b/test/fixtures/circular-reference.css @@ -2,3 +2,6 @@ --color: var(--bg-color); --bg-color: var(--color); } +body { + color: var(--color); +} diff --git a/test/fixtures/circular-reference.expected.css b/test/fixtures/circular-reference.expected.css new file mode 100644 index 0000000000..c04ff5b60b --- /dev/null +++ b/test/fixtures/circular-reference.expected.css @@ -0,0 +1,3 @@ +body { + color: var(--bg-color); +} diff --git a/test/fixtures/self-reference-double-fallback.css b/test/fixtures/self-reference-double-fallback.css new file mode 100644 index 0000000000..1476ad8428 --- /dev/null +++ b/test/fixtures/self-reference-double-fallback.css @@ -0,0 +1,6 @@ +:root { + --color: var(--color, #aaa); +} +body { + color: var(--color, #bbb); +} diff --git a/test/fixtures/self-reference-double-fallback.expected.css b/test/fixtures/self-reference-double-fallback.expected.css new file mode 100644 index 0000000000..67a9b3beb4 --- /dev/null +++ b/test/fixtures/self-reference-double-fallback.expected.css @@ -0,0 +1,4 @@ +body { + color: #bbb; + color: #aaa; +} diff --git a/test/fixtures/self-reference-fallback.css b/test/fixtures/self-reference-fallback.css new file mode 100644 index 0000000000..b585bb8564 --- /dev/null +++ b/test/fixtures/self-reference-fallback.css @@ -0,0 +1,6 @@ +:root { + --color: var(--color); +} +body { + color: var(--color, #aaa); +} diff --git a/test/fixtures/self-reference-fallback.expected.css b/test/fixtures/self-reference-fallback.expected.css new file mode 100644 index 0000000000..8c9a1c831d --- /dev/null +++ b/test/fixtures/self-reference-fallback.expected.css @@ -0,0 +1,3 @@ +body { + color: #aaa; +} diff --git a/test/fixtures/self-reference.css b/test/fixtures/self-reference.css index adf6bde3f7..a5b8489f26 100644 --- a/test/fixtures/self-reference.css +++ b/test/fixtures/self-reference.css @@ -1,3 +1,6 @@ :root { --color: var(--color); } +body { + color: var(--color); +} diff --git a/test/fixtures/self-reference.expected.css b/test/fixtures/self-reference.expected.css new file mode 100644 index 0000000000..6f6d04fee9 --- /dev/null +++ b/test/fixtures/self-reference.expected.css @@ -0,0 +1,3 @@ +body { + color: var(--color); +} diff --git a/test/index.js b/test/index.js index 777ea3a6a2..06c4c51d39 100755 --- a/test/index.js +++ b/test/index.js @@ -107,12 +107,14 @@ test("preserves variables when `preserve` is `true`", function(t) { t.end() }) -test("throw error for circular variable references", function(t) { - t.throws(function() { - resolveFixture("self-reference", {preserve: true}) - }, Error, "should throw error for self-referential variables") - t.throws(function() { - resolveFixture("circular-reference", {preserve: true}) - }, Error, "should throw error for circular variable references") +test("circular variable references", function(t) { + compareFixtures(t, "self-reference") + compareFixtures(t, "circular-reference") + t.end() +}) + +test("circular variable references with fallback", function(t) { + compareFixtures(t, "self-reference-fallback") + compareFixtures(t, "self-reference-double-fallback") t.end() }) From 085f5ac8e59b88e161774eedbde3f59f79ae9feb Mon Sep 17 00:00:00 2001 From: Glen Huang Date: Mon, 6 Apr 2015 10:59:47 +0800 Subject: [PATCH 175/795] Add preserve option --- index.js | 5 ++++- test/fixtures/preserve.css | 4 ++++ test/fixtures/preserve.expected.css | 4 ++++ test/index.js | 2 ++ 4 files changed, 14 insertions(+), 1 deletion(-) create mode 100644 test/fixtures/preserve.css create mode 100644 test/fixtures/preserve.expected.css diff --git a/index.js b/index.js index ac706a9c57..b15d6bef1f 100755 --- a/index.js +++ b/index.js @@ -20,6 +20,7 @@ function customMedia(options) { return function(styles) { options = options || {} var extensions = options.extensions || {} + var preserve = options.preserve var map = {} var toRemove = [] @@ -34,7 +35,9 @@ function customMedia(options) { // map[] = map[params.shift()] = params.join(" ") - toRemove.push(rule) + if (!preserve) { + toRemove.push(rule) + } }) // apply js-defined media queries diff --git a/test/fixtures/preserve.css b/test/fixtures/preserve.css new file mode 100644 index 0000000000..46a14f7b16 --- /dev/null +++ b/test/fixtures/preserve.css @@ -0,0 +1,4 @@ +@custom-media --viewport-max-s (max-width: 30em); +@media (--viewport-max-s) { + body { font-size: 1rem; } +} diff --git a/test/fixtures/preserve.expected.css b/test/fixtures/preserve.expected.css new file mode 100644 index 0000000000..5bfb3c8eb5 --- /dev/null +++ b/test/fixtures/preserve.expected.css @@ -0,0 +1,4 @@ +@custom-media --viewport-max-s (max-width: 30em); +@media (max-width: 30em) { + body { font-size: 1rem; } +} diff --git a/test/index.js b/test/index.js index a7e5d35c93..313dff843e 100755 --- a/test/index.js +++ b/test/index.js @@ -32,5 +32,7 @@ test("@custom-media", function(t) { } }) + compareFixtures(t, "preserve", "should preserve custom media", {preserve: true}) + t.end() }) From a09bfb31b28ef494991db3739fd3ba4801c6eeae Mon Sep 17 00:00:00 2001 From: Glen Huang Date: Mon, 6 Apr 2015 11:27:41 +0800 Subject: [PATCH 176/795] Add append option --- index.js | 24 +++++++++++++++++++++--- package.json | 4 ++-- test/fixtures/append.css | 3 +++ test/fixtures/append.expected.css | 4 ++++ test/index.js | 7 +++++++ 5 files changed, 37 insertions(+), 5 deletions(-) create mode 100644 test/fixtures/append.css create mode 100644 test/fixtures/append.expected.css diff --git a/index.js b/index.js index b15d6bef1f..e74d88c878 100755 --- a/index.js +++ b/index.js @@ -1,6 +1,7 @@ /** * Module dependencies */ +var postcss = require("postcss") var helpers = require("postcss-message-helpers") /** @@ -20,7 +21,8 @@ function customMedia(options) { return function(styles) { options = options || {} var extensions = options.extensions || {} - var preserve = options.preserve + var append = options.append + var preserve = append || options.preserve var map = {} var toRemove = [] @@ -41,8 +43,8 @@ function customMedia(options) { }) // apply js-defined media queries - Object.keys(extensions).forEach(function(extension) { - map[extension] = extensions[extension] + Object.keys(extensions).forEach(function(name) { + map[name] = extensions[name] }) // transform custom media query aliases @@ -61,6 +63,22 @@ function customMedia(options) { }) }) + if (append) { + var names = Object.keys(map) + if (names.length) { + names.forEach(function(name) { + var atRule = postcss.atRule({ + name: "custom-media", + afterName: " ", + params: name + " " + map[name], + }) + styles.append(atRule) + }) + styles.semicolon = true + styles.after = "\n" + } + } + // remove @custom-media toRemove.forEach(function(rule) { rule.removeSelf() }) } diff --git a/package.json b/package.json index 58b177ca65..37897bb553 100644 --- a/package.json +++ b/package.json @@ -21,12 +21,12 @@ "index.js" ], "dependencies": { - "postcss-message-helpers": "^2.0.0" + "postcss-message-helpers": "^2.0.0", + "postcss": "^4.0.2" }, "devDependencies": { "jscs": "^1.6.2", "jshint": "^2.5.6", - "postcss": "^4.0.2", "tape": "^3.0.0" }, "scripts": { diff --git a/test/fixtures/append.css b/test/fixtures/append.css new file mode 100644 index 0000000000..945cc118d0 --- /dev/null +++ b/test/fixtures/append.css @@ -0,0 +1,3 @@ +@media (--viewport-max-s) { + body { font-size: 1rem; } +} diff --git a/test/fixtures/append.expected.css b/test/fixtures/append.expected.css new file mode 100644 index 0000000000..6c44041f98 --- /dev/null +++ b/test/fixtures/append.expected.css @@ -0,0 +1,4 @@ +@media (max-width: 30em) { + body { font-size: 1rem; } +} +@custom-media --viewport-max-s (max-width: 30em); diff --git a/test/index.js b/test/index.js index 313dff843e..efd36d3536 100755 --- a/test/index.js +++ b/test/index.js @@ -34,5 +34,12 @@ test("@custom-media", function(t) { compareFixtures(t, "preserve", "should preserve custom media", {preserve: true}) + compareFixtures(t, "append", "should append custom media", { + extensions: { + "--viewport-max-s": "(max-width: 30em)", + }, + append: true, + }) + t.end() }) From 1ff31a2c7daeaa90e022a6fda5524caa5a150934 Mon Sep 17 00:00:00 2001 From: Glen Huang Date: Mon, 6 Apr 2015 22:56:02 +0800 Subject: [PATCH 177/795] Not leave unprefixed variables in map --- index.js | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) diff --git a/index.js b/index.js index 3a92397f6c..8a0e899dab 100755 --- a/index.js +++ b/index.js @@ -119,16 +119,13 @@ function resolveValue(value, variables, source) { module.exports = function(options) { return function(style) { options = options || {} - var userVariables = options.variables || {} - var variables = - Object.keys(userVariables) - .reduce(function(acc, key) { - if (key.indexOf("--") !== 0) { - acc["--" + key] = userVariables[key] - } - acc[key] = userVariables[key] - return acc - }, {}) + var variables = options.variables || {} + Object.keys(variables).forEach(function(name) { + if (name.slice(0, 2) !== "--") { + variables["--" + name] = variables[name] + delete variables[name] + } + }) var preserve = (options.preserve === true ? true : false) var map = {} var importantMap = {} From 2dea507ab5b792e5366763f42d74bfb7c3defcc3 Mon Sep 17 00:00:00 2001 From: Glen Huang Date: Mon, 6 Apr 2015 12:46:03 +0800 Subject: [PATCH 178/795] Add automatic custom media prefixing --- index.js | 6 ++++++ test/index.js | 7 +++++++ 2 files changed, 13 insertions(+) diff --git a/index.js b/index.js index e74d88c878..87b4bc1bf7 100755 --- a/index.js +++ b/index.js @@ -21,6 +21,12 @@ function customMedia(options) { return function(styles) { options = options || {} var extensions = options.extensions || {} + Object.keys(extensions).forEach(function(name) { + if (name.slice(0, 2) !== "--") { + extensions["--" + name] = extensions[name] + delete extensions[name] + } + }) var append = options.append var preserve = append || options.preserve var map = {} diff --git a/test/index.js b/test/index.js index efd36d3536..92abeffc83 100755 --- a/test/index.js +++ b/test/index.js @@ -32,6 +32,13 @@ test("@custom-media", function(t) { } }) + compareFixtures(t, "js-defined", "should transform custom media and override local unprefixed extensions", { + extensions: { + "viewport-max-s": "(max-width: 30em)", + "viewport-min-s": "(min-width: 30.01em)" + } + }) + compareFixtures(t, "preserve", "should preserve custom media", {preserve: true}) compareFixtures(t, "append", "should append custom media", { From 22794f1a30325ba092ae69a1983388dde4fd138d Mon Sep 17 00:00:00 2001 From: Glen Huang Date: Mon, 6 Apr 2015 23:01:02 +0800 Subject: [PATCH 179/795] Add append option --- index.js | 35 ++++++++++++++++++++++++++++++- test/fixtures/append.css | 3 +++ test/fixtures/append.expected.css | 8 +++++++ test/index.js | 11 ++++++++++ 4 files changed, 56 insertions(+), 1 deletion(-) create mode 100644 test/fixtures/append.css create mode 100644 test/fixtures/append.expected.css diff --git a/index.js b/index.js index 8a0e899dab..d86225aee6 100755 --- a/index.js +++ b/index.js @@ -2,6 +2,7 @@ * Module dependencies. */ +var postcss = require("postcss") var balanced = require("balanced-match") var helpers = require("postcss-message-helpers") @@ -126,7 +127,8 @@ module.exports = function(options) { delete variables[name] } }) - var preserve = (options.preserve === true ? true : false) + var append = options.append + var preserve = append || options.preserve var map = {} var importantMap = {} @@ -191,6 +193,16 @@ module.exports = function(options) { } }) + if (append) { + Object.keys(map).forEach(function(name) { + var variable = map[name] + if (!variable.resolved) { + variable.value = resolveValue(variable.value, map) + variable.resolved = true + } + }) + } + // resolve variables style.eachDecl(function(decl) { var value = decl.value @@ -211,5 +223,26 @@ module.exports = function(options) { decl.removeSelf() } }) + + if (append) { + var names = Object.keys(map) + if (names.length) { + var container = postcss.rule({ + selector: ":root", + semicolon: true, + }) + names.forEach(function(name) { + var variable = map[name] + var val = variable.value + if (variable.resolved) { val = val[val.length - 1] } + var decl = postcss.decl({ + prop: name, + value: val, + }) + container.append(decl) + }) + style.append(container) + } + } } } diff --git a/test/fixtures/append.css b/test/fixtures/append.css new file mode 100644 index 0000000000..6da553d015 --- /dev/null +++ b/test/fixtures/append.css @@ -0,0 +1,3 @@ +div { + p: var(--test-one); +} diff --git a/test/fixtures/append.expected.css b/test/fixtures/append.expected.css new file mode 100644 index 0000000000..f84a78a787 --- /dev/null +++ b/test/fixtures/append.expected.css @@ -0,0 +1,8 @@ +div { + p: js-one; + p: var(--test-one); +} +:root { + --test-one: js-one; + --test-two: js-two; +} diff --git a/test/index.js b/test/index.js index 06c4c51d39..774956cf41 100755 --- a/test/index.js +++ b/test/index.js @@ -118,3 +118,14 @@ test("circular variable references with fallback", function(t) { compareFixtures(t, "self-reference-double-fallback") t.end() }) + +test("append variables", function(t) { + compareFixtures(t, "append", { + variables: { + "--test-one": "js-one", + "test-two": "js-two", + }, + append: true, + }) + t.end() +}) From 8378dfc15878da8572c70e5406da727f4ef5c330 Mon Sep 17 00:00:00 2001 From: Glen Huang Date: Wed, 8 Apr 2015 10:14:49 +0800 Subject: [PATCH 180/795] Add `preserve: "computed"` option --- index.js | 8 ++++---- test/fixtures/append.expected.css | 2 +- test/fixtures/preserve-computed.css | 21 ++++++++++++++++++++ test/fixtures/preserve-computed.expected.css | 21 ++++++++++++++++++++ test/index.js | 7 +++++++ 5 files changed, 54 insertions(+), 5 deletions(-) create mode 100755 test/fixtures/preserve-computed.css create mode 100755 test/fixtures/preserve-computed.expected.css diff --git a/index.js b/index.js index d86225aee6..9eabc0e37a 100755 --- a/index.js +++ b/index.js @@ -128,7 +128,7 @@ module.exports = function(options) { } }) var append = options.append - var preserve = append || options.preserve + var preserve = options.preserve var map = {} var importantMap = {} @@ -193,7 +193,7 @@ module.exports = function(options) { } }) - if (append) { + if (preserve) { Object.keys(map).forEach(function(name) { var variable = map[name] if (!variable.resolved) { @@ -219,12 +219,12 @@ module.exports = function(options) { }) }, decl.source) - if (!preserve) { + if (!preserve || preserve === "computed") { decl.removeSelf() } }) - if (append) { + if (preserve && append) { var names = Object.keys(map) if (names.length) { var container = postcss.rule({ diff --git a/test/fixtures/append.expected.css b/test/fixtures/append.expected.css index f84a78a787..8b22df0494 100644 --- a/test/fixtures/append.expected.css +++ b/test/fixtures/append.expected.css @@ -1,8 +1,8 @@ div { p: js-one; - p: var(--test-one); } :root { --test-one: js-one; --test-two: js-two; + --test-three: js-one js-two; } diff --git a/test/fixtures/preserve-computed.css b/test/fixtures/preserve-computed.css new file mode 100755 index 0000000000..58a256a46b --- /dev/null +++ b/test/fixtures/preserve-computed.css @@ -0,0 +1,21 @@ +:root { + --color-one: red; + --color-two: blue; + --color-three: var(--color-two); +} + +.atthebeginning { + color: var(--color-one); + prop: after; +} + +.attheend { + prop: before; + color: var(--color-two); +} + +.surrounded { + prop: before; + color: var(--undefined-color, green); + otherprop: after; +} diff --git a/test/fixtures/preserve-computed.expected.css b/test/fixtures/preserve-computed.expected.css new file mode 100755 index 0000000000..7fe1e4f6bb --- /dev/null +++ b/test/fixtures/preserve-computed.expected.css @@ -0,0 +1,21 @@ +:root { + --color-one: red; + --color-two: blue; + --color-three: blue; +} + +.atthebeginning { + color: red; + prop: after; +} + +.attheend { + prop: before; + color: blue; +} + +.surrounded { + prop: before; + color: green; + otherprop: after; +} diff --git a/test/index.js b/test/index.js index 774956cf41..26b78a5d7a 100755 --- a/test/index.js +++ b/test/index.js @@ -107,6 +107,11 @@ test("preserves variables when `preserve` is `true`", function(t) { t.end() }) +test("preserves computed value when `preserve` is `\"computed\"`", function(t) { + compareFixtures(t, "preserve-computed", {preserve: "computed"}) + t.end() +}) + test("circular variable references", function(t) { compareFixtures(t, "self-reference") compareFixtures(t, "circular-reference") @@ -124,8 +129,10 @@ test("append variables", function(t) { variables: { "--test-one": "js-one", "test-two": "js-two", + "test-three": "var(--test-one, one) var(--test-two, two)", }, append: true, + preserve: "computed", }) t.end() }) From b45e18e06deb47574038b6c46f89d9fec9f484b7 Mon Sep 17 00:00:00 2001 From: Glen Huang Date: Wed, 8 Apr 2015 10:23:52 +0800 Subject: [PATCH 181/795] Add postcss to package.json --- package.json | 1 + 1 file changed, 1 insertion(+) diff --git a/package.json b/package.json index 92ee6afb02..e07d7accfb 100644 --- a/package.json +++ b/package.json @@ -23,6 +23,7 @@ ], "dependencies": { "balanced-match": "~0.1.0", + "postcss": "^4.1.4", "postcss-message-helpers": "^2.0.0" }, "devDependencies": { From 6828438cd26283bdd2d26eecc4b120155f7e9b25 Mon Sep 17 00:00:00 2001 From: Maxime Thirouin Date: Wed, 8 Apr 2015 06:50:39 +0200 Subject: [PATCH 182/795] Rename `append` option to `appendVariables` To make it clear. --- index.js | 4 ++-- test/index.js | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/index.js b/index.js index 9eabc0e37a..0c1e25106a 100755 --- a/index.js +++ b/index.js @@ -127,7 +127,7 @@ module.exports = function(options) { delete variables[name] } }) - var append = options.append + var appendVariables = options.appendVariables var preserve = options.preserve var map = {} var importantMap = {} @@ -224,7 +224,7 @@ module.exports = function(options) { } }) - if (preserve && append) { + if (preserve && appendVariables) { var names = Object.keys(map) if (names.length) { var container = postcss.rule({ diff --git a/test/index.js b/test/index.js index 26b78a5d7a..61d534fce2 100755 --- a/test/index.js +++ b/test/index.js @@ -131,8 +131,8 @@ test("append variables", function(t) { "test-two": "js-two", "test-three": "var(--test-one, one) var(--test-two, two)", }, - append: true, preserve: "computed", + appendVariables: true, }) t.end() }) From d01bae5f5e2eaec53993d05391621080300c8336 Mon Sep 17 00:00:00 2001 From: Maxime Thirouin Date: Wed, 8 Apr 2015 06:51:35 +0200 Subject: [PATCH 183/795] Update README according to recent changes --- README.md | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 076835a7e0..93235c7d11 100755 --- a/README.md +++ b/README.md @@ -57,7 +57,7 @@ Checkout [tests](test) for more. #### `preserve` (default: `false`) -Allow you to preserve custom properties & var() usage in output. +Allows you to preserve custom properties & var() usage in output. ```js var out = postcss() @@ -66,12 +66,19 @@ var out = postcss() .css ``` +You can also set `preserve: "computed"` to get computed resolved custom properties in the final output. +Handy to make them available to your JavaScript. + #### `variables` (default: `{}`) -Allow you to pass an object of variables for `:root`. These definitions will override any that exist in the CSS. +Allows you to pass an object of variables for `:root`. These definitions will override any that exist in the CSS. The keys are automatically prefixed with the CSS `--` to make it easier to share variables in your codebase. +### `appendVariables` (default: `false`) + +If `preserve` is set to `true` (or `"computed"`), allows you to append your variables at then of your CSS. + --- ## Contributing From edb250466fbd81de046abdc40fbbb761cc530539 Mon Sep 17 00:00:00 2001 From: Maxime Thirouin Date: Wed, 8 Apr 2015 06:52:03 +0200 Subject: [PATCH 184/795] Prevent mutability issue --- index.js | 3 ++- package.json | 1 + 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/index.js b/index.js index 0c1e25106a..438533aee0 100755 --- a/index.js +++ b/index.js @@ -2,6 +2,7 @@ * Module dependencies. */ +var assign = require("object-assign") var postcss = require("postcss") var balanced = require("balanced-match") var helpers = require("postcss-message-helpers") @@ -120,7 +121,7 @@ function resolveValue(value, variables, source) { module.exports = function(options) { return function(style) { options = options || {} - var variables = options.variables || {} + var variables = assign({}, options.variables || {}) Object.keys(variables).forEach(function(name) { if (name.slice(0, 2) !== "--") { variables["--" + name] = variables[name] diff --git a/package.json b/package.json index e07d7accfb..4670d57547 100644 --- a/package.json +++ b/package.json @@ -23,6 +23,7 @@ ], "dependencies": { "balanced-match": "~0.1.0", + "object-assign": "^2.0.0", "postcss": "^4.1.4", "postcss-message-helpers": "^2.0.0" }, From 2125844b295db5f3fcbaabf766801e8173f15c4b Mon Sep 17 00:00:00 2001 From: Maxime Thirouin Date: Wed, 8 Apr 2015 06:52:42 +0200 Subject: [PATCH 185/795] Remove duplicated dep --- package.json | 1 - 1 file changed, 1 deletion(-) diff --git a/package.json b/package.json index 4670d57547..d743b6dd6e 100644 --- a/package.json +++ b/package.json @@ -29,7 +29,6 @@ }, "devDependencies": { "eslint": "^0.18.0", - "postcss": "^4.0.0", "tape": "^3.0.0" }, "scripts": { From 480240cf15097df2f716036493f3cf6d9da2d468 Mon Sep 17 00:00:00 2001 From: Maxime Thirouin Date: Wed, 8 Apr 2015 06:52:59 +0200 Subject: [PATCH 186/795] Upgrade tape to 4.x --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index d743b6dd6e..99ac6b6482 100644 --- a/package.json +++ b/package.json @@ -29,7 +29,7 @@ }, "devDependencies": { "eslint": "^0.18.0", - "tape": "^3.0.0" + "tape": "^4.0.0" }, "scripts": { "test": "eslint . && tape test" From 03bbae7d6d914e475b6a8141343507ecf277c91e Mon Sep 17 00:00:00 2001 From: Maxime Thirouin Date: Wed, 8 Apr 2015 07:13:32 +0200 Subject: [PATCH 187/795] Added: strict option Close #14 --- README.md | 6 ++++++ index.js | 7 ++++++- test/fixtures/substitution-strict.css | 10 ++++++++++ test/fixtures/substitution-strict.expected.css | 5 +++++ test/index.js | 8 ++++++++ 5 files changed, 35 insertions(+), 1 deletion(-) create mode 100755 test/fixtures/substitution-strict.css create mode 100755 test/fixtures/substitution-strict.expected.css diff --git a/README.md b/README.md index 93235c7d11..e382c1fc58 100755 --- a/README.md +++ b/README.md @@ -55,6 +55,12 @@ Checkout [tests](test) for more. ### Options +#### `strict` (default: `true`) + +Per specifications, all fallbacks should be added since we can't verify if a +computed value is valid or not. +This option allows you to avoid adding too many fallback values in your CSS. + #### `preserve` (default: `false`) Allows you to preserve custom properties & var() usage in output. diff --git a/index.js b/index.js index 438533aee0..fbfbbe46e5 100755 --- a/index.js +++ b/index.js @@ -128,6 +128,7 @@ module.exports = function(options) { delete variables[name] } }) + var strict = options.strict === undefined ? true : options.strict var appendVariables = options.appendVariables var preserve = options.preserve var map = {} @@ -214,7 +215,11 @@ module.exports = function(options) { } helpers.try(function resolve() { - resolveValue(value, map, decl.source).forEach(function(resolvedValue) { + var resolved = resolveValue(value, map, decl.source) + if (!strict) { + resolved = [resolved.pop()] + } + resolved.forEach(function(resolvedValue) { var clone = decl.cloneBefore() clone.value = resolvedValue }) diff --git a/test/fixtures/substitution-strict.css b/test/fixtures/substitution-strict.css new file mode 100755 index 0000000000..f13b196758 --- /dev/null +++ b/test/fixtures/substitution-strict.css @@ -0,0 +1,10 @@ +:root { + --a: "a"; + --b: var(--bUndef, bFallback); +} + +div { + aProp: var(--a, aPropFallback); + bProp: var(--b, bPropFallback); + bProp: var(--cUndef, cPropFallback); +} diff --git a/test/fixtures/substitution-strict.expected.css b/test/fixtures/substitution-strict.expected.css new file mode 100755 index 0000000000..ed8e05e70b --- /dev/null +++ b/test/fixtures/substitution-strict.expected.css @@ -0,0 +1,5 @@ +div { + aProp: "a"; + bProp: bFallback; + bProp: cPropFallback; +} diff --git a/test/index.js b/test/index.js index 61d534fce2..7564f99c77 100755 --- a/test/index.js +++ b/test/index.js @@ -136,3 +136,11 @@ test("append variables", function(t) { }) t.end() }) + +test("strict option", function(t) { + compareFixtures(t, "substitution-strict", { + strict: false, + }) + + t.end() +}) From d8c4db5f94fcea5421e4a5bacd9e60f7d3d18bb8 Mon Sep 17 00:00:00 2001 From: Maxime Thirouin Date: Wed, 8 Apr 2015 07:13:46 +0200 Subject: [PATCH 188/795] 3.3.0 --- CHANGELOG.md | 6 ++++++ package.json | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index beb3db5ebd..2d69071555 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,9 @@ +# 3.3.0 - 2015-04-0 + +- Added: `preserve` now support `"computed"` so only preserve resolved custom properties (see new option below) +- Added: `appendVariables` allows you (when `preserve` is trulthy) to append your variables as custom properties +- Added: `strict: false` allows your to avoid too many fallbacks added in your CSS. + # 3.2.0 - 2015-03-31 - Added: JS defined variables are now resolved too ([#22](https://github.com/postcss/postcss-custom-properties/issues/22)) diff --git a/package.json b/package.json index 99ac6b6482..752cc1e5fc 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "postcss-custom-properties", - "version": "3.2.0", + "version": "3.3.0", "description": "PostCSS plugin to polyfill W3C CSS Custom Properties for cascading variables", "keywords": [ "css", From 387df9a651e948b99c5304461775ce8b529d5436 Mon Sep 17 00:00:00 2001 From: Maxime Thirouin Date: Wed, 8 Apr 2015 08:47:47 +0200 Subject: [PATCH 189/795] Changed: messages and exceptions are now using postcss API. Messages are not outputted by default to console anymore. --- CHANGELOG.md | 5 +++++ index.js | 60 ++++++++++++++++++++++++--------------------------- package.json | 5 ++--- test/index.js | 18 ++++++++++------ 4 files changed, 47 insertions(+), 41 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2d69071555..76e991b81b 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,8 @@ +# 4.0.0 - Unreleased + +- Changed: upgade to postcss ^4.1.x +- Changed: messages and exceptions are now using postcss API. +Messages are not outputted by default to console anymore. # 3.3.0 - 2015-04-0 - Added: `preserve` now support `"computed"` so only preserve resolved custom properties (see new option below) diff --git a/index.js b/index.js index fbfbbe46e5..576b6e5b3f 100755 --- a/index.js +++ b/index.js @@ -5,7 +5,6 @@ var assign = require("object-assign") var postcss = require("postcss") var balanced = require("balanced-match") -var helpers = require("postcss-message-helpers") /** * Constants. @@ -30,7 +29,7 @@ var RE_VAR = /([\w-]+)(?:\s*,\s*)?(.*)?/ // matches `name[, fallback]`, captures * @return {String} A property value with all CSS variables substituted. */ -function resolveValue(value, variables, source) { +function resolveValue(value, variables, result, decl) { var results = [] var start = value.indexOf(VAR_FUNC_IDENTIFIER + "(") @@ -41,11 +40,11 @@ function resolveValue(value, variables, source) { var matches = balanced("(", ")", value.substring(start)) if (!matches) { - throw new SyntaxError("missing closing ')' in the value '" + value + "'") + throw decl.error("missing closing ')' in the value '" + value + "'") } if (matches.body === "") { - throw new Error("var() must contain a non-whitespace string") + throw decl.error("var() must contain a non-whitespace string") } matches.body.replace(RE_VAR, function(_, name, fallback) { @@ -53,8 +52,8 @@ function resolveValue(value, variables, source) { var post // undefined and without fallback, just keep original value if (!variable && !fallback) { - console.warn(helpers.message("variable '" + name + "' is undefined and used without a fallback", source)) - post = matches.post ? resolveValue(matches.post, variables, source) : [""] + result.warn("variable '" + name + "' is undefined and used without a fallback", {node: decl}) + post = matches.post ? resolveValue(matches.post, variables, result, decl) : [""] // resolve the end of the expression post.forEach(function(afterValue) { results.push(value.slice(0, start) + VAR_FUNC_IDENTIFIER + "(" + name + ")" + afterValue) @@ -65,9 +64,9 @@ function resolveValue(value, variables, source) { // prepend with fallbacks if (fallback) { // resolve fallback values - fallback = resolveValue(fallback, variables, source) + fallback = resolveValue(fallback, variables, result, decl) // resolve the end of the expression before the rest - post = matches.post ? resolveValue(matches.post, variables, source) : [""] + post = matches.post ? resolveValue(matches.post, variables, result, decl) : [""] fallback.forEach(function(fbValue) { post.forEach(function(afterValue) { results.push(value.slice(0, start) + fbValue + afterValue) @@ -84,7 +83,7 @@ function resolveValue(value, variables, source) { // circular reference encountered if (variable.deps.indexOf(name) !== -1) { if (!fallback) { - console.warn(helpers.message("circular variable reference: " + name, source)) + result.warn("Circular variable reference: " + name, {node: decl}) variable.value = [variable.value] variable.circular = true } @@ -95,7 +94,7 @@ function resolveValue(value, variables, source) { } else { variable.deps.push(name) - variable.value = resolveValue(variable.value, variables, source) + variable.value = resolveValue(variable.value, variables, result, decl) } variable.resolved = true } @@ -103,7 +102,7 @@ function resolveValue(value, variables, source) { return } // resolve the end of the expression - post = matches.post ? resolveValue(matches.post, variables, source) : [""] + post = matches.post ? resolveValue(matches.post, variables, result, decl) : [""] variable.value.forEach(function(replacementValue) { post.forEach(function(afterValue) { results.push(value.slice(0, start) + replacementValue + afterValue) @@ -118,8 +117,8 @@ function resolveValue(value, variables, source) { * Module export. */ -module.exports = function(options) { - return function(style) { +module.exports = postcss.plugin("postcss-custom-properties", function(options) { + return function(style, result) { options = options || {} var variables = assign({}, options.variables || {}) Object.keys(variables).forEach(function(name) { @@ -143,13 +142,12 @@ module.exports = function(options) { rule.each(function(decl) { var prop = decl.prop if (prop && prop.indexOf(VAR_PROP_IDENTIFIER) === 0) { - console.warn( - helpers.message( - "Custom property ignored: not scoped to the top-level :root element (" + - rule.selectors + - " { ... " + prop + ": ... })" + - (rule.parent.type !== "root" ? ", in " + rule.parent.type : ""), - decl.source) + result.warn( + "Custom property ignored: not scoped to the top-level :root element (" + + rule.selectors + + " { ... " + prop + ": ... })" + + (rule.parent.type !== "root" ? ", in " + rule.parent.type : ""), + {node: decl} ) } }) @@ -199,7 +197,7 @@ module.exports = function(options) { Object.keys(map).forEach(function(name) { var variable = map[name] if (!variable.resolved) { - variable.value = resolveValue(variable.value, map) + variable.value = resolveValue(variable.value, map, result) variable.resolved = true } }) @@ -214,16 +212,14 @@ module.exports = function(options) { return } - helpers.try(function resolve() { - var resolved = resolveValue(value, map, decl.source) - if (!strict) { - resolved = [resolved.pop()] - } - resolved.forEach(function(resolvedValue) { - var clone = decl.cloneBefore() - clone.value = resolvedValue - }) - }, decl.source) + var resolved = resolveValue(value, map, result, decl) + if (!strict) { + resolved = [resolved.pop()] + } + resolved.forEach(function(resolvedValue) { + var clone = decl.cloneBefore() + clone.value = resolvedValue + }) if (!preserve || preserve === "computed") { decl.removeSelf() @@ -251,4 +247,4 @@ module.exports = function(options) { } } } -} +}) diff --git a/package.json b/package.json index 752cc1e5fc..c81045f38d 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "postcss-custom-properties", - "version": "3.3.0", + "version": "4.0.0", "description": "PostCSS plugin to polyfill W3C CSS Custom Properties for cascading variables", "keywords": [ "css", @@ -24,8 +24,7 @@ "dependencies": { "balanced-match": "~0.1.0", "object-assign": "^2.0.0", - "postcss": "^4.1.4", - "postcss-message-helpers": "^2.0.0" + "postcss": "^4.1.4" }, "devDependencies": { "eslint": "^0.18.0", diff --git a/test/index.js b/test/index.js index 7564f99c77..46d5841db2 100755 --- a/test/index.js +++ b/test/index.js @@ -14,17 +14,20 @@ function fixture(name) { } function resolveFixture(name, options) { - return postcss(customProperties(options)).process(fixture(name), {from: fixturePath(name)}).css.trim() + return postcss(customProperties(options)).process(fixture(name), {from: fixturePath(name)}) } function compareFixtures(t, name, options) { - var actual = resolveFixture(name, options) + var postcssResult = resolveFixture(name, options) + var actual = postcssResult.css.trim() // handy thing: checkout actual in the *.actual.css file fs.writeFile(fixturePath(name + ".actual"), actual) var expected = fixture(name + ".expected") - return t.equal(actual, expected, "processed fixture '" + name + "' should be equal to expected output") + t.equal(actual, expected, "processed fixture '" + name + "' should be equal to expected output") + + return postcssResult } test("throw errors", function(t) { @@ -40,12 +43,14 @@ test("throw errors", function(t) { }) test("substitutes nothing when a variable function references an undefined variable", function(t) { - compareFixtures(t, "substitution-undefined") + var result = compareFixtures(t, "substitution-undefined") + t.equal(result.warnings()[0].text, "variable '--test' is undefined and used without a fallback", "should add a warning for undefined variable") t.end() }) test("substitutes defined variables in `:root` only", function(t) { - compareFixtures(t, "substitution-defined") + var result = compareFixtures(t, "substitution-defined") + t.ok(result.warnings()[0].text.match(/^Custom property ignored/), "should add a warning for non root custom properties") t.end() }) @@ -114,7 +119,8 @@ test("preserves computed value when `preserve` is `\"computed\"`", function(t) { test("circular variable references", function(t) { compareFixtures(t, "self-reference") - compareFixtures(t, "circular-reference") + var result = compareFixtures(t, "circular-reference") + t.equal(result.warnings()[0].text, "Circular variable reference: --color", "should add a warning for circular reference") t.end() }) From 8f03ebe94ea29304d2e38334ec66f2fcae0860b5 Mon Sep 17 00:00:00 2001 From: Glen Huang Date: Thu, 9 Apr 2015 13:09:50 +0800 Subject: [PATCH 190/795] Refactor --- index.js | 23 +++++++++++++---------- test/index.js | 2 +- 2 files changed, 14 insertions(+), 11 deletions(-) diff --git a/index.js b/index.js index 87b4bc1bf7..007ea58bde 100755 --- a/index.js +++ b/index.js @@ -20,15 +20,18 @@ module.exports = customMedia function customMedia(options) { return function(styles) { options = options || {} - var extensions = options.extensions || {} - Object.keys(extensions).forEach(function(name) { - if (name.slice(0, 2) !== "--") { - extensions["--" + name] = extensions[name] - delete extensions[name] - } - }) - var append = options.append - var preserve = append || options.preserve + var extensions = {} + if (options.extensions) { + Object.keys(options.extensions).forEach(function(name) { + var val = options.extensions[name] + if (name.slice(0, 2) !== "--") { + name = "--" + name + } + extensions[name] = val + }) + } + var appendExtensions = options.appendExtensions + var preserve = options.preserve var map = {} var toRemove = [] @@ -69,7 +72,7 @@ function customMedia(options) { }) }) - if (append) { + if (appendExtensions) { var names = Object.keys(map) if (names.length) { names.forEach(function(name) { diff --git a/test/index.js b/test/index.js index 92abeffc83..2a40677125 100755 --- a/test/index.js +++ b/test/index.js @@ -45,7 +45,7 @@ test("@custom-media", function(t) { extensions: { "--viewport-max-s": "(max-width: 30em)", }, - append: true, + appendExtensions: true, }) t.end() From 8052b3b6fde9e318f8748b472eb5ce12301ecb57 Mon Sep 17 00:00:00 2001 From: Glen Huang Date: Thu, 9 Apr 2015 13:10:16 +0800 Subject: [PATCH 191/795] Update README and CHANGELOG --- CHANGELOG.md | 5 +++++ README.md | 8 ++++++++ 2 files changed, 13 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7cfd94823b..ad99f95579 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,8 @@ +# Unrelease + +- Added: `preserve` allows you to preserve custom media query defintions +- Added: `appendExtensions` allows you (when `preserve` is truthy) to append your extensions as media queries + # 3.0.0 - 2015-01-29 - Added: compatibility with postcss v4.x diff --git a/README.md b/README.md index cb3cbb2fb1..6351e90e00 100755 --- a/README.md +++ b/README.md @@ -49,6 +49,14 @@ Checkout [tests](test) for more examples. Allows you to pass an object to define the `` for each ``. These definitions will override any that exist in the CSS. +#### `preserve` (default: `false`) + +Allows you to preserve custom media query definitions in output. + +### `appendExtensions` (default: `false`) + +If `preserve` is set to `true`, allows you to append your extensions at end of your CSS. + --- ## Contributing From b9788ed36944ad9aad4109661b61460b952b07c5 Mon Sep 17 00:00:00 2001 From: Maxime Thirouin Date: Thu, 9 Apr 2015 08:01:07 +0200 Subject: [PATCH 192/795] Replace jscs+jshint by eslint --- .eslintrc | 26 ++++++++++ .jscsrc | 130 -------------------------------------------------- .jshintrc | 9 ---- index.js | 2 +- package.json | 7 +-- test/index.js | 8 ++-- 6 files changed, 33 insertions(+), 149 deletions(-) create mode 100644 .eslintrc delete mode 100644 .jscsrc delete mode 100644 .jshintrc diff --git a/.eslintrc b/.eslintrc new file mode 100644 index 0000000000..db389353cb --- /dev/null +++ b/.eslintrc @@ -0,0 +1,26 @@ +--- +ecmaFeatures: + modules: true + +env: + es6: true + browser: true + node: true + +# 0: off, 1: warning, 2: error +rules: + # semicolons are useless + semi: [2, "never"] + + quotes: [2, "double"] + + # 2 spaces indentation + indent: [2, 2] + + # trailing coma are cool for diff + comma-dangle: [2, "always-multiline"] + + # enforce comma at eol (never before) + comma-style: [2, "last"] + + valid-jsdoc: 2 diff --git a/.jscsrc b/.jscsrc deleted file mode 100644 index 29720b3791..0000000000 --- a/.jscsrc +++ /dev/null @@ -1,130 +0,0 @@ -{ - "excludeFiles": [ - "node_modules/**" - ], - "fileExtensions": [ - ".js" - ], - "requireCurlyBraces": [ - "if", - "else", - "for", - "while", - "do", - "try", - "catch" - ], - "requireSpaceAfterKeywords": [ - "if", - "else", - "for", - "while", - "do", - "switch", - "return", - "try", - "catch" - ], - "requireSpaceBeforeBlockStatements": true, - "requireParenthesesAroundIIFE": true, - "requireSpacesInConditionalExpression": { - "afterTest": true, - "beforeConsequent": true, - "afterConsequent": true, - "beforeAlternate": true - }, - "requireSpacesInFunctionExpression": { - "beforeOpeningCurlyBrace": true - }, - "disallowSpacesInFunctionExpression": { - "beforeOpeningRoundBrace": true - }, - "disallowMultipleVarDecl": true, - "requireBlocksOnNewline": 1, - "disallowPaddingNewlinesInBlocks": true, - "disallowEmptyBlocks": true, - "disallowSpacesInsideObjectBrackets": true, - "disallowSpacesInsideArrayBrackets": true, - "disallowSpacesInsideParentheses": true, - "disallowQuotedKeysInObjects": "allButReserved", - "disallowSpaceAfterObjectKeys": true, - "requireCommaBeforeLineBreak": true, - "requireOperatorBeforeLineBreak": [ - "?", - "+", - "-", - "/", - "*", - "=", - "==", - "===", - "!=", - "!==", - ">", - ">=", - "<", - "<=" - ], - "disallowSpaceAfterPrefixUnaryOperators": [ - "++", - "--", - "+", - "-", - "~", - "!" - ], - "disallowSpaceBeforePostfixUnaryOperators": [ - "++", - "--" - ], - "requireSpaceBeforeBinaryOperators": [ - "+", - "-", - "/", - "*", - "=", - "==", - "===", - "!=", - "!==" - ], - "requireSpaceAfterBinaryOperators": [ - "+", - "-", - "/", - "*", - "=", - "==", - "===", - "!=", - "!==" - ], - "disallowImplicitTypeConversion": [ - "numeric", - "boolean", - "binary", - "string" - ], - "requireCamelCaseOrUpperCaseIdentifiers": "ignoreProperties", - "disallowKeywords": [ - "with" - ], - "disallowMultipleLineStrings": true, - "validateQuoteMarks": "\"", - "validateIndentation": 2, - "disallowMixedSpacesAndTabs": true, - "disallowTrailingWhitespace": true, - "requireKeywordsOnNewLine": [ - "else" - ], - "requireLineFeedAtFileEnd": true, - "requireCapitalizedConstructors": true, - "safeContextKeyword": "that", - "requireDotNotation": true, - "validateJSDoc": { - "checkParamNames": true, - "checkRedundantParams": true, - "requireParamTypes": true - }, - "requireSpaceAfterLineComment": true -} diff --git a/.jshintrc b/.jshintrc deleted file mode 100644 index 9f268f76ca..0000000000 --- a/.jshintrc +++ /dev/null @@ -1,9 +0,0 @@ -{ - "newcap": false, - "undef": true, - "unused": true, - "asi": true, - "esnext": true, - "node": true, - "browser": true -} diff --git a/index.js b/index.js index 007ea58bde..dc64a3cddc 100755 --- a/index.js +++ b/index.js @@ -14,7 +14,7 @@ var EXTENSION_RE = /\(\s*(--[\w-]+)\s*\)/g */ module.exports = customMedia -/** +/* * read & replace custom media queries by standard media queries */ function customMedia(options) { diff --git a/package.json b/package.json index 37897bb553..bd23728887 100644 --- a/package.json +++ b/package.json @@ -25,12 +25,9 @@ "postcss": "^4.0.2" }, "devDependencies": { - "jscs": "^1.6.2", - "jshint": "^2.5.6", - "tape": "^3.0.0" + "eslint": "^0.18.0", }, "scripts": { - "lint": "jscs *.js **/*.js && jshint . --exclude-path .gitignore", - "test": "npm run lint && tape test" + "test": "eslint . && tape test" } } diff --git a/test/index.js b/test/index.js index 2a40677125..22c5534f44 100755 --- a/test/index.js +++ b/test/index.js @@ -28,15 +28,15 @@ test("@custom-media", function(t) { compareFixtures(t, "js-defined", "should transform custom media and override local extensions", { extensions: { "--viewport-max-s": "(max-width: 30em)", - "--viewport-min-s": "(min-width: 30.01em)" - } + "--viewport-min-s": "(min-width: 30.01em)", + }, }) compareFixtures(t, "js-defined", "should transform custom media and override local unprefixed extensions", { extensions: { "viewport-max-s": "(max-width: 30em)", - "viewport-min-s": "(min-width: 30.01em)" - } + "viewport-min-s": "(min-width: 30.01em)", + }, }) compareFixtures(t, "preserve", "should preserve custom media", {preserve: true}) From 0b36054dd4ad88fb3b35ae219c77ee72b6d3846f Mon Sep 17 00:00:00 2001 From: Maxime Thirouin Date: Thu, 9 Apr 2015 08:02:07 +0200 Subject: [PATCH 193/795] Changed: warning messages are not sent via postcss API --- CHANGELOG.md | 3 ++- index.js | 7 +++---- package.json | 6 +++--- test/index.js | 8 ++++++-- 4 files changed, 14 insertions(+), 10 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ad99f95579..fa6561ce9b 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,6 @@ -# Unrelease +# 4.0.0 - Unrelease +- Changed: warning messages are not sent via postcss API (^4.1.0) - Added: `preserve` allows you to preserve custom media query defintions - Added: `appendExtensions` allows you (when `preserve` is truthy) to append your extensions as media queries diff --git a/index.js b/index.js index dc64a3cddc..13bc19ce83 100755 --- a/index.js +++ b/index.js @@ -2,7 +2,6 @@ * Module dependencies */ var postcss = require("postcss") -var helpers = require("postcss-message-helpers") /** * Constants. @@ -12,13 +11,13 @@ var EXTENSION_RE = /\(\s*(--[\w-]+)\s*\)/g /** * Expose the plugin. */ -module.exports = customMedia +module.exports = postcss.plugin("postcss-custom-media", customMedia) /* * read & replace custom media queries by standard media queries */ function customMedia(options) { - return function(styles) { + return function(styles, result) { options = options || {} var extensions = {} if (options.extensions) { @@ -67,7 +66,7 @@ function customMedia(options) { return map[name] } - console.warn(helpers.message("missing @custom-media definition for '" + name + "'. The entire rule has been removed from the output.", rule.source)) + result.warn("Missing @custom-media definition for '" + name + "'. The entire rule has been removed from the output.", {node: rule}) toRemove.push(rule) }) }) diff --git a/package.json b/package.json index bd23728887..503a9be82f 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "postcss-custom-media", - "version": "3.0.0", + "version": "4.0.0", "description": " PostCSS plugin to transform W3C CSS Custom Media Queries to more compatible CSS", "keywords": [ "css", @@ -21,11 +21,11 @@ "index.js" ], "dependencies": { - "postcss-message-helpers": "^2.0.0", - "postcss": "^4.0.2" + "postcss": "^4.1.4" }, "devDependencies": { "eslint": "^0.18.0", + "tape": "^4.0.0" }, "scripts": { "test": "eslint . && tape test" diff --git a/test/index.js b/test/index.js index 22c5534f44..3e641b73c9 100755 --- a/test/index.js +++ b/test/index.js @@ -12,10 +12,13 @@ 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 result = postcss().use(plugin(opts)).process(read(postcssOpts.from), postcssOpts) + var actual = result.css var expected = read(filename("fixtures/" + name + ".expected")) fs.writeFile(filename("fixtures/" + name + ".actual"), actual) t.equal(actual.trim(), expected.trim(), msg) + + return result } test("@custom-media", function(t) { @@ -23,7 +26,8 @@ test("@custom-media", function(t) { compareFixtures(t, "transform-all", "should replaces all extension names") - compareFixtures(t, "undefined", "should remove undefined @media") + var undefinedRes = compareFixtures(t, "undefined", "should remove undefined @media") + t.ok(undefinedRes.warnings()[0].text.match(/Missing @custom-media/), "should send warning to postcss") compareFixtures(t, "js-defined", "should transform custom media and override local extensions", { extensions: { From 084eeca93f706c11a75c6e1be6cc6af75cc0f8cf Mon Sep 17 00:00:00 2001 From: Maxime Thirouin Date: Thu, 9 Apr 2015 08:11:45 +0200 Subject: [PATCH 194/795] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 6351e90e00..bbc416a3b3 100755 --- a/README.md +++ b/README.md @@ -53,7 +53,7 @@ Allows you to pass an object to define the `` for each ` Date: Wed, 22 Apr 2015 10:19:40 +0200 Subject: [PATCH 195/795] fixed typo in example gulp config --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index de62ed6583..1d9cccadb4 100644 --- a/README.md +++ b/README.md @@ -186,7 +186,7 @@ module.exports = function(grunt) { var gulp = require('gulp'); var rename = require('gulp-rename'); var postcss = require('gulp-postcss'); -var selector = require('postcss-custom-selector') +var selector = require('postcss-custom-selectors') var autoprefixer = require('autoprefixer-core') gulp.task('default', function () { From ecbae8d9976150087edf51aba9cdbb86c0af6a79 Mon Sep 17 00:00:00 2001 From: Maxime Thirouin Date: Thu, 30 Apr 2015 07:23:28 +0200 Subject: [PATCH 196/795] Initial release --- .babelrc | 3 +++ .editorconfig | 13 +++++++++++ .eslintignore | 1 + .eslintrc | 27 +++++++++++++++++++++++ .gitignore | 1 + .travis.yml | 3 +++ CHANGELOG.md | 3 +++ LICENSE | 20 +++++++++++++++++ README.md | 45 ++++++++++++++++++++++++++++++++++++++ package.json | 44 +++++++++++++++++++++++++++++++++++++ src/index.js | 40 ++++++++++++++++++++++++++++++++++ test/index.js | 60 +++++++++++++++++++++++++++++++++++++++++++++++++++ 12 files changed, 260 insertions(+) create mode 100644 .babelrc create mode 100644 .editorconfig create mode 120000 .eslintignore create mode 100644 .eslintrc create mode 100644 .gitignore create mode 100644 .travis.yml create mode 100755 CHANGELOG.md create mode 100755 LICENSE create mode 100644 README.md create mode 100644 package.json create mode 100644 src/index.js create mode 100644 test/index.js diff --git a/.babelrc b/.babelrc new file mode 100644 index 0000000000..b0b9a96ef0 --- /dev/null +++ b/.babelrc @@ -0,0 +1,3 @@ +{ + "stage": 0 +} diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000000..fa5dd91d55 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,13 @@ +root = true + +[*] +end_of_line = lf +charset = utf-8 +trim_trailing_whitespace = true +insert_final_newline = true +indent_style = space +indent_size = 2 + +[*.{md,markdown}] +# Allow
from Markdown +trim_trailing_whitespace = false diff --git a/.eslintignore b/.eslintignore new file mode 120000 index 0000000000..3e4e48b0b5 --- /dev/null +++ b/.eslintignore @@ -0,0 +1 @@ +.gitignore \ No newline at end of file diff --git a/.eslintrc b/.eslintrc new file mode 100644 index 0000000000..98388d0232 --- /dev/null +++ b/.eslintrc @@ -0,0 +1,27 @@ +--- +# babel support more syntax stuff than eslint for now +parser: babel-eslint + +ecmaFeatures: + modules: true + +env: + es6: true + browser: true + node: true + +# 0: off, 1: warning, 2: error +rules: + # semicolons are useless + semi: [2, "never"] + + quotes: [2, "double"] + + # 2 spaces indentation + indent: [2, 2] + + # trailing coma are cool for diff + comma-dangle: [2, "always-multiline"] + + # enforce comma at eol (never before) + comma-style: [2, "last"] diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000000..1521c8b765 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +dist diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000000..76b2bb53ec --- /dev/null +++ b/.travis.yml @@ -0,0 +1,3 @@ +sudo: false + +language: node_js diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100755 index 0000000000..31bf78366d --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,3 @@ +# 1.0.0 - 2015-04-30 + +✨ First release diff --git a/LICENSE b/LICENSE new file mode 100755 index 0000000000..8b39b8f151 --- /dev/null +++ b/LICENSE @@ -0,0 +1,20 @@ +The MIT License (MIT) + +Copyright (c) 2014 Maxime Thirouin + +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. diff --git a/README.md b/README.md new file mode 100644 index 0000000000..7b9b318d6f --- /dev/null +++ b/README.md @@ -0,0 +1,45 @@ +# postcss-selector-matches [![Build Status](https://travis-ci.org/postcss/postcss-selector-matches.svg?branch=master)](https://travis-ci.org/postcss/postcss-selector-matches) + +> PostCSS plugin to transform `:matches()` W3C CSS pseudo class to more compatible CSS selectors + +## Installation + +```console +$ npm install postcss-selector-matches +``` + +## Usage + +```js +var postcss = require("postcss") + +var output = postcss() + .use(require("postcss-selector-matches")) + .process(require("fs").readFileSync("input.css", "utf8")) + .css +``` + +Using this `input.css`: + +```css +p:matches(:first-child, .special) { + color: red; +} +``` + +you will get: + +```css +p:first-child, p.special { + color: red; +} +``` + +**Note that if you are doing crazy selector like `p:matches(a) {}` you are likely to get crazy results (like `pa {}`)**. + + +--- + +## [Changelog](CHANGELOG.md) + +## [License](LICENSE) diff --git a/package.json b/package.json new file mode 100644 index 0000000000..aeb2e2ca14 --- /dev/null +++ b/package.json @@ -0,0 +1,44 @@ +{ + "name": "postcss-selector-matches", + "version": "1.0.0", + "description": "PostCSS plugin to transform :matches() W3C CSS pseudo class to more compatible CSS selectors", + "keywords": [ + "postcss", + "selectors", + "selector", + "matches" + ], + "author": "Maxime Thirouin", + "license": "MIT", + "repository": { + "type": "git", + "url": "https://github.com/postcss/postcss-selector-matches.git" + }, + "homepage": "https://github.com/postcss/postcss-selector-matches", + "bugs": { + "url": "https://github.com/postcss/postcss-selector-matches/issues" + }, + "files": [ + "CHANGELOG.md", + "LICENSE", + "dist" + ], + "main": "dist/index.js", + "dependencies": { + "balanced-match": "^0.2.0", + "postcss": "^4.1.7" + }, + "devDependencies": { + "babel": "^5.1.13", + "babel-eslint": "^3.0.1", + "babel-tape-runner": "^1.1.0", + "eslint": "^0.20.0", + "tape": "^4.0.0" + }, + "scripts": { + "lint": "eslint .", + "tape": "babel-tape-runner 'test/*.js'", + "test": "npm run lint && npm run tape", + "prepublish": "babel src --out-dir dist" + } +} diff --git a/src/index.js b/src/index.js new file mode 100644 index 0000000000..a40183bb40 --- /dev/null +++ b/src/index.js @@ -0,0 +1,40 @@ +import postcss from "postcss" +import list from "postcss/lib/list" + +import balancedMatch from "balanced-match" + +function explodeSelector(pseudoClass, selector) { + if (selector && selector.indexOf(pseudoClass) > -1) { + const start = `${pseudoClass}(` + const end = ")" + const matches = balancedMatch(start, end, selector) + const selectors = [] + const bodySelectors = matches.body ? + list + .comma(matches.body) + .reduce((acc, s) => [...acc, ...explodeSelector(pseudoClass, s)], {}) + : [""] + const postSelectors = matches.post ? explodeSelector(pseudoClass, matches.post) : [""] + postSelectors.forEach(postSelector => { + bodySelectors.forEach(bodySelector => { + selectors.push(matches.pre + bodySelector + postSelector) + }) + }) + return selectors + } + return [selector] +} + +function explodeSelectors(pseudoClass) { + return () => { + return (css) => { + css.eachRule(rule => { + if (rule.selector && rule.selector.indexOf(pseudoClass) > -1) { + rule.selector = explodeSelector(pseudoClass, rule.selector).join(", ") + } + }) + } + } +} + +export default postcss.plugin("postcss-selector-matches", explodeSelectors(":matches")) diff --git a/test/index.js b/test/index.js new file mode 100644 index 0000000000..794a4dfc50 --- /dev/null +++ b/test/index.js @@ -0,0 +1,60 @@ +import tape from "tape" + +import postcss from "postcss" +import selectorMatches from "../src/index.js" + +function transform(css) { + return postcss(selectorMatches).process(css).css +} + +tape("postcss-selector-matches", t => { + t.equal( + transform("body {}"), + "body {}", + "should do nothing if there is no :matches" + ) + + t.equal( + transform("body, matches {}"), + "body, matches {}", + "should really do nothing if there is no :matches" + ) + + t.equal( + transform(":matches(a, b) {}"), + "a, b {}", + "should transform simple :matches()" + ) + + t.equal( + transform("tag:matches(.class, .class2) {}"), + "tag.class, tag.class2 {}", + "should transform directes :matches()" + ) + + t.equal( + transform("tag :matches(tag2, tag3) {}"), + "tag tag2, tag tag3 {}", + "should transform :matches()" + ) + + t.equal( + transform("tag :matches(tag2, tag3) :matches(tag4, tag5) {}"), + "tag tag2 tag4, tag tag3 tag4, tag tag2 tag5, tag tag3 tag5 {}", + "should transform mutltiples :matches()" + ) + + t.equal( + transform("tag :matches(tag2 :matches(tag4, tag5), tag3) {}"), + "tag tag2 tag4, tag tag2 tag5, tag tag3 {}", + "should transform :matches() recursively" + ) + + t.equal( + transform("p:matches(a, span) {}"), + "pa, pspan {}", + "should transform shit if you ask for shit ?" + ) + + t.end() +}) From 4c10c837e22e8ba939a35042634ce6f4a8a46eee Mon Sep 17 00:00:00 2001 From: Maxime Thirouin Date: Thu, 30 Apr 2015 07:29:21 +0200 Subject: [PATCH 197/795] Travis, wake up ! --- .travis.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 76b2bb53ec..31e6113ac4 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,3 +1,2 @@ sudo: false - language: node_js From e578324d4ca403b59905f445a521aa2b3756a54a Mon Sep 17 00:00:00 2001 From: Maxime Thirouin Date: Thu, 30 Apr 2015 07:40:49 +0200 Subject: [PATCH 198/795] Initial release --- .babelrc | 3 +++ .editorconfig | 13 +++++++++++++ .eslintignore | 1 + .eslintrc | 27 ++++++++++++++++++++++++++ .gitignore | 1 + .travis.yml | 2 ++ CHANGELOG.md | 3 +++ LICENSE | 20 +++++++++++++++++++ README.md | 42 +++++++++++++++++++++++++++++++++++++++ package.json | 44 +++++++++++++++++++++++++++++++++++++++++ src/index.js | 40 ++++++++++++++++++++++++++++++++++++++ test/index.js | 54 +++++++++++++++++++++++++++++++++++++++++++++++++++ 12 files changed, 250 insertions(+) create mode 100644 .babelrc create mode 100644 .editorconfig create mode 120000 .eslintignore create mode 100644 .eslintrc create mode 100644 .gitignore create mode 100644 .travis.yml create mode 100755 CHANGELOG.md create mode 100755 LICENSE create mode 100644 README.md create mode 100644 package.json create mode 100644 src/index.js create mode 100644 test/index.js diff --git a/.babelrc b/.babelrc new file mode 100644 index 0000000000..b0b9a96ef0 --- /dev/null +++ b/.babelrc @@ -0,0 +1,3 @@ +{ + "stage": 0 +} diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000000..fa5dd91d55 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,13 @@ +root = true + +[*] +end_of_line = lf +charset = utf-8 +trim_trailing_whitespace = true +insert_final_newline = true +indent_style = space +indent_size = 2 + +[*.{md,markdown}] +# Allow
from Markdown +trim_trailing_whitespace = false diff --git a/.eslintignore b/.eslintignore new file mode 120000 index 0000000000..3e4e48b0b5 --- /dev/null +++ b/.eslintignore @@ -0,0 +1 @@ +.gitignore \ No newline at end of file diff --git a/.eslintrc b/.eslintrc new file mode 100644 index 0000000000..98388d0232 --- /dev/null +++ b/.eslintrc @@ -0,0 +1,27 @@ +--- +# babel support more syntax stuff than eslint for now +parser: babel-eslint + +ecmaFeatures: + modules: true + +env: + es6: true + browser: true + node: true + +# 0: off, 1: warning, 2: error +rules: + # semicolons are useless + semi: [2, "never"] + + quotes: [2, "double"] + + # 2 spaces indentation + indent: [2, 2] + + # trailing coma are cool for diff + comma-dangle: [2, "always-multiline"] + + # enforce comma at eol (never before) + comma-style: [2, "last"] diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000000..1521c8b765 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +dist diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000000..31e6113ac4 --- /dev/null +++ b/.travis.yml @@ -0,0 +1,2 @@ +sudo: false +language: node_js diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100755 index 0000000000..31bf78366d --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,3 @@ +# 1.0.0 - 2015-04-30 + +✨ First release diff --git a/LICENSE b/LICENSE new file mode 100755 index 0000000000..8b39b8f151 --- /dev/null +++ b/LICENSE @@ -0,0 +1,20 @@ +The MIT License (MIT) + +Copyright (c) 2014 Maxime Thirouin + +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. diff --git a/README.md b/README.md new file mode 100644 index 0000000000..c581001b00 --- /dev/null +++ b/README.md @@ -0,0 +1,42 @@ +# postcss-selector-not [![Build Status](https://travis-ci.org/postcss/postcss-selector-not.svg?branch=master)](https://travis-ci.org/postcss/postcss-selector-not) + +> PostCSS plugin to transform `:not()` W3C CSS leve 4 pseudo class to :not() CSS level 3 selectors + +## Installation + +```console +$ npm install postcss-selector-not +``` + +## Usage + +```js +var postcss = require("postcss") + +var output = postcss() + .use(require("postcss-selector-not")) + .process(require("fs").readFileSync("input.css", "utf8")) + .css +``` + +Using this `input.css`: + +```css +p:not(:first-child, .special) { + color: red; +} +``` + +you will get: + +```css +p:not(:first-child), p:not(.special) { + color: red; +} +``` + +--- + +## [Changelog](CHANGELOG.md) + +## [License](LICENSE) diff --git a/package.json b/package.json new file mode 100644 index 0000000000..853549174d --- /dev/null +++ b/package.json @@ -0,0 +1,44 @@ +{ + "name": "postcss-selector-not", + "version": "1.0.0", + "description": "PostCSS plugin to transform :not() W3C CSS leve 4 pseudo class to :not() CSS level 3 selectors", + "keywords": [ + "postcss", + "selectors", + "selector", + "Not" + ], + "author": "Maxime Thirouin", + "license": "MIT", + "repository": { + "type": "git", + "url": "https://github.com/postcss/postcss-selector-not.git" + }, + "homepage": "https://github.com/postcss/postcss-selector-not", + "bugs": { + "url": "https://github.com/postcss/postcss-selector-not/issues" + }, + "files": [ + "CHANGELOG.md", + "LICENSE", + "dist" + ], + "main": "dist/index.js", + "dependencies": { + "balanced-match": "^0.2.0", + "postcss": "^4.1.7" + }, + "devDependencies": { + "babel": "^5.1.13", + "babel-eslint": "^3.0.1", + "babel-tape-runner": "^1.1.0", + "eslint": "^0.20.0", + "tape": "^4.0.0" + }, + "scripts": { + "lint": "eslint .", + "tape": "babel-tape-runner 'test/*.js'", + "test": "npm run lint && npm run tape", + "prepublish": "babel src --out-dir dist" + } +} diff --git a/src/index.js b/src/index.js new file mode 100644 index 0000000000..250a1ebb14 --- /dev/null +++ b/src/index.js @@ -0,0 +1,40 @@ +import postcss from "postcss" +import list from "postcss/lib/list" + +import balancedMatch from "balanced-match" + +function explodeSelector(pseudoClass, selector) { + if (selector && selector.indexOf(pseudoClass) > -1) { + const start = `${pseudoClass}(` + const end = ")" + const matches = balancedMatch(start, end, selector) + const selectors = [] + const bodySelectors = matches.body ? + list + .comma(matches.body) + .reduce((acc, s) => [...acc, ...explodeSelector(pseudoClass, s)], {}) + : [""] + const postSelectors = matches.post ? explodeSelector(pseudoClass, matches.post) : [""] + postSelectors.forEach(postSelector => { + bodySelectors.forEach(bodySelector => { + selectors.push(`${matches.pre}${pseudoClass}(${bodySelector})${postSelector}`) + }) + }) + return selectors + } + return [selector] +} + +function explodeSelectors(pseudoClass) { + return () => { + return (css) => { + css.eachRule(rule => { + if (rule.selector && rule.selector.indexOf(pseudoClass) > -1) { + rule.selector = explodeSelector(pseudoClass, rule.selector).join(", ") + } + }) + } + } +} + +export default postcss.plugin("postcss-selector-not", explodeSelectors(":not")) diff --git a/test/index.js b/test/index.js new file mode 100644 index 0000000000..17bd590fec --- /dev/null +++ b/test/index.js @@ -0,0 +1,54 @@ +import tape from "tape" + +import postcss from "postcss" +import selectorNot from "../src/index.js" + +function transform(css) { + return postcss(selectorNot).process(css).css +} + +tape("postcss-selector-not", t => { + t.equal( + transform("body {}"), + "body {}", + "should do nothing if there is no :not" + ) + + t.equal( + transform("body, Not {}"), + "body, Not {}", + "should really do nothing if there is no :not" + ) + + t.equal( + transform(":not(a, b) {}"), + ":not(a), :not(b) {}", + "should transform simple :not()" + ) + + t.equal( + transform("tag:not(.class, .class2) {}"), + "tag:not(.class), tag:not(.class2) {}", + "should transform directes :not()" + ) + + t.equal( + transform("tag :not(tag2, tag3) {}"), + "tag :not(tag2), tag :not(tag3) {}", + "should transform :not()" + ) + + t.equal( + transform("tag :not(tag2, tag3) :not(tag4, tag5) {}"), + "tag :not(tag2) :not(tag4), tag :not(tag3) :not(tag4), tag :not(tag2) :not(tag5), tag :not(tag3) :not(tag5) {}", + "should transform mutltiples :not()" + ) + + t.equal( + transform("tag :not(tag2 :not(tag4, tag5), tag3) {}"), + "tag :not(tag2 :not(tag4)), tag :not(tag2 :not(tag5)), tag :not(tag3) {}", + "should transform :not() recursively" + ) + + t.end() +}) From aed7ee51b8e223ff915ddf22375354d3a9dd8391 Mon Sep 17 00:00:00 2001 From: Maxime Thirouin Date: Thu, 30 Apr 2015 07:53:15 +0200 Subject: [PATCH 199/795] Update README.md --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index 7b9b318d6f..d7efac26c4 100644 --- a/README.md +++ b/README.md @@ -2,6 +2,8 @@ > PostCSS plugin to transform `:matches()` W3C CSS pseudo class to more compatible CSS selectors +http://dev.w3.org/csswg/selectors-4/#matches + ## Installation ```console From a84b04195d1f8e5b85c53f83b52be77d5699713e Mon Sep 17 00:00:00 2001 From: Maxime Thirouin Date: Thu, 30 Apr 2015 07:54:50 +0200 Subject: [PATCH 200/795] Update README.md --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index c581001b00..9c097ca131 100644 --- a/README.md +++ b/README.md @@ -2,6 +2,8 @@ > PostCSS plugin to transform `:not()` W3C CSS leve 4 pseudo class to :not() CSS level 3 selectors +http://dev.w3.org/csswg/selectors-4/#negation + ## Installation ```console From c49bc108a010e432b040152bd1b3ffda5bb2195b Mon Sep 17 00:00:00 2001 From: Maxime Thirouin Date: Thu, 30 Apr 2015 08:44:06 +0200 Subject: [PATCH 201/795] Fixed: the module now works in non babel environments --- CHANGELOG.md | 4 ++++ package.json | 2 +- src/index.js | 2 +- 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 31bf78366d..ac7b7b5688 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,7 @@ +# 1.0.1 - 2015-04-30 + +- Fixed: the module now works in non babel environments + # 1.0.0 - 2015-04-30 ✨ First release diff --git a/package.json b/package.json index 853549174d..a8aa5a7dff 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "postcss-selector-not", - "version": "1.0.0", + "version": "1.0.1", "description": "PostCSS plugin to transform :not() W3C CSS leve 4 pseudo class to :not() CSS level 3 selectors", "keywords": [ "postcss", diff --git a/src/index.js b/src/index.js index 250a1ebb14..ce262d2c12 100644 --- a/src/index.js +++ b/src/index.js @@ -12,7 +12,7 @@ function explodeSelector(pseudoClass, selector) { const bodySelectors = matches.body ? list .comma(matches.body) - .reduce((acc, s) => [...acc, ...explodeSelector(pseudoClass, s)], {}) + .reduce((acc, s) => [...acc, ...explodeSelector(pseudoClass, s)], []) : [""] const postSelectors = matches.post ? explodeSelector(pseudoClass, matches.post) : [""] postSelectors.forEach(postSelector => { From 8b042a8844b5de8baf62107abee61f2b55824fbd Mon Sep 17 00:00:00 2001 From: Maxime Thirouin Date: Thu, 30 Apr 2015 08:46:47 +0200 Subject: [PATCH 202/795] Fixed: the module now works in non babel environments --- CHANGELOG.md | 4 ++++ package.json | 2 +- src/index.js | 2 +- 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 31bf78366d..ac7b7b5688 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,7 @@ +# 1.0.1 - 2015-04-30 + +- Fixed: the module now works in non babel environments + # 1.0.0 - 2015-04-30 ✨ First release diff --git a/package.json b/package.json index aeb2e2ca14..a933bfd361 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "postcss-selector-matches", - "version": "1.0.0", + "version": "1.0.1", "description": "PostCSS plugin to transform :matches() W3C CSS pseudo class to more compatible CSS selectors", "keywords": [ "postcss", diff --git a/src/index.js b/src/index.js index a40183bb40..b0f428c19d 100644 --- a/src/index.js +++ b/src/index.js @@ -12,7 +12,7 @@ function explodeSelector(pseudoClass, selector) { const bodySelectors = matches.body ? list .comma(matches.body) - .reduce((acc, s) => [...acc, ...explodeSelector(pseudoClass, s)], {}) + .reduce((acc, s) => [...acc, ...explodeSelector(pseudoClass, s)], []) : [""] const postSelectors = matches.post ? explodeSelector(pseudoClass, matches.post) : [""] postSelectors.forEach(postSelector => { From 43851207cf8a2ac3a3d5c29ad0b6df80d8329458 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Vaux?= Date: Wed, 6 May 2015 00:41:20 +0200 Subject: [PATCH 203/795] Split rules on whitespace, not only on spaces --- index.js | 2 +- test/fixtures/multiline.css | 7 +++++++ test/fixtures/multiline.expected.css | 3 +++ test/index.js | 1 + 4 files changed, 12 insertions(+), 1 deletion(-) create mode 100644 test/fixtures/multiline.css create mode 100644 test/fixtures/multiline.expected.css diff --git a/index.js b/index.js index 93e670f780..231b2e0d42 100644 --- a/index.js +++ b/index.js @@ -28,7 +28,7 @@ function customSelector(options) { return } - var params = rule.params.split(" ") + var params = rule.params.split(/\s+/) // @custom-selector = @custom-selector // map[] = diff --git a/test/fixtures/multiline.css b/test/fixtures/multiline.css new file mode 100644 index 0000000000..a2e76322dc --- /dev/null +++ b/test/fixtures/multiline.css @@ -0,0 +1,7 @@ +@custom-selector :--multiline + .foo + ; + +:--multiline { + display: block; +} diff --git a/test/fixtures/multiline.expected.css b/test/fixtures/multiline.expected.css new file mode 100644 index 0000000000..40167adc18 --- /dev/null +++ b/test/fixtures/multiline.expected.css @@ -0,0 +1,3 @@ +.foo { + display: block; +} diff --git a/test/index.js b/test/index.js index f71e113cd0..2d3c3973aa 100644 --- a/test/index.js +++ b/test/index.js @@ -21,6 +21,7 @@ function compareFixtures(t, name, msg, opts, postcssOpts) { test("@custom-selector", function(t) { compareFixtures(t, "heading", "should transform custom selector") compareFixtures(t, "pseudo", "should transform custom selector") + compareFixtures(t, "multiline", "should transform custom selector") compareFixtures(t, "extension", "local extensions", { extensions: { From 6e0c90c4312c9ea030e9bc80baf97c6e3f12bf77 Mon Sep 17 00:00:00 2001 From: Maxime Thirouin Date: Wed, 6 May 2015 06:46:04 +0200 Subject: [PATCH 204/795] 1.1.1 --- CHANGELOG.md | 8 ++++++-- package.json | 2 +- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 809d294036..b438f96536 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,7 +1,11 @@ +# 1.1.1 - 2015-04-06 + +- Fixed: add support for multilines definition + # 1.1.0 - 2014-12-06 -Add "lineBreak" option +- Added: "lineBreak" option # 1.0.0 - 2014-12-06 -First release +✨ First release diff --git a/package.json b/package.json index c9228d58c5..36fe717d2d 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "postcss-custom-selectors", - "version": "1.1.0", + "version": "1.1.1", "description": "PostCSS plugin to transform W3C CSS Extensions(Custom Selectors) to more compatible CSS", "keywords": [ "css", From d4580b003a17672bc6a7a51126e05666b218f4bc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=B8=80=E4=B8=9D?= Date: Thu, 7 May 2015 11:31:52 +0800 Subject: [PATCH 205/795] fix doc, add more test --- README-zh.md | 4 ++-- README.md | 2 +- test/fixtures/multiline.css | 4 ++-- test/fixtures/multiline.expected.css | 3 ++- 4 files changed, 7 insertions(+), 6 deletions(-) diff --git a/README-zh.md b/README-zh.md index 32e204f5fc..0680984ecc 100644 --- a/README-zh.md +++ b/README-zh.md @@ -134,7 +134,7 @@ a:visited { var fs = require('fs') var chokidar = require('chokidar') var postcss = require('postcss') -var selector = require('postcss-custom-selector') +var selector = require('postcss-custom-selectors') var src = 'input.css' @@ -186,7 +186,7 @@ module.exports = function(grunt) { var gulp = require('gulp'); var rename = require('gulp-rename'); var postcss = require('gulp-postcss'); -var selector = require('postcss-custom-selector') +var selector = require('postcss-custom-selectors') var autoprefixer = require('autoprefixer-core') gulp.task('default', function () { diff --git a/README.md b/README.md index 1d9cccadb4..91bd215f02 100644 --- a/README.md +++ b/README.md @@ -134,7 +134,7 @@ Dependence [chokidar](https://github.com/paulmillr/chokidar) module. var fs = require('fs') var chokidar = require('chokidar') var postcss = require('postcss') -var selector = require('postcss-custom-selector') +var selector = require('postcss-custom-selectors') var src = 'input.css' diff --git a/test/fixtures/multiline.css b/test/fixtures/multiline.css index a2e76322dc..c1f640292f 100644 --- a/test/fixtures/multiline.css +++ b/test/fixtures/multiline.css @@ -1,6 +1,6 @@ @custom-selector :--multiline - .foo - ; + .foo, + .bar > .baz; :--multiline { display: block; diff --git a/test/fixtures/multiline.expected.css b/test/fixtures/multiline.expected.css index 40167adc18..8eca97dbb9 100644 --- a/test/fixtures/multiline.expected.css +++ b/test/fixtures/multiline.expected.css @@ -1,3 +1,4 @@ -.foo { +.foo, +.bar > .baz { display: block; } From e504f08e43ed03bc89ef376b07df59b4e671f23a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=B8=80=E4=B8=9D?= Date: Fri, 29 May 2015 23:19:25 +0800 Subject: [PATCH 206/795] No longer support `::` or `--` to defined a custom selectors and fixed #14 --- CHANGELOG.md | 12 +++++++--- README-zh.md | 24 +++++++++---------- README.md | 22 ++++++++--------- index.js | 12 ++++++---- package.json | 2 +- test/fixtures/extension.css | 4 ++-- test/fixtures/heading.css | 4 ++-- test/fixtures/pseudo.css | 4 ++-- test/fixtures/some-hyphen-selector.css | 10 ++++++++ .../some-hyphen-selector.expected.css | 11 +++++++++ test/index.js | 16 ++++++++----- 11 files changed, 76 insertions(+), 45 deletions(-) create mode 100644 test/fixtures/some-hyphen-selector.css create mode 100644 test/fixtures/some-hyphen-selector.expected.css diff --git a/CHANGELOG.md b/CHANGELOG.md index b438f96536..60b8ab1109 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,11 +1,17 @@ +# 2.0.0 - 2015-05-29 + +* x Remove: no longer support `::` or `--` to defined a custom selectors, we must use the `:--` to defined it. + +* - Fixed: two or more consecutive hyphens in selector outputs is "undefined". + # 1.1.1 - 2015-04-06 -- Fixed: add support for multilines definition +* - Fixed: add support for multilines definition # 1.1.0 - 2014-12-06 -- Added: "lineBreak" option +* - Added: "lineBreak" option # 1.0.0 - 2014-12-06 -✨ First release +* First release diff --git a/README-zh.md b/README-zh.md index 0680984ecc..a2d24350a4 100644 --- a/README-zh.md +++ b/README-zh.md @@ -43,9 +43,9 @@ var output = postcss(selector()) input.css: ```css -@custom-selector --heading h1, h2, h3, h4, h5, h6; +@custom-selector :--heading h1, h2, h3, h4, h5, h6; -article --heading + p { +article :--heading + p { margin-top: 0; } ``` @@ -65,17 +65,13 @@ article h6 + p { ## CSS 语法 - @custom-selector = @custom-selector ; + @custom-selector = @custom-selector : ; ## 如何使用 -### 伪元素/伪类 +自定义选择器是一个伪类,所以必须使用 `:--`来定义。 -你可以使用 - -* `:` 自定义一个伪类。 -* `::`自定义一个伪元素。 例如,模拟一个 [:any-link](http://dev.w3.org/csswg/selectors/#the-any-link-pseudo) 选择器: @@ -99,20 +95,22 @@ a:visited { color: blue; } ``` + ### 多个选择器 -`@custom-selector` 类似 CSS [`:matches()`](http://dev.w3.org/csswg/selectors-4/#matches) ([`-moz-any()`](https://developer.mozilla.org/en-US/docs/Web/CSS/:any)/[`-webkit-any()`](http://css-tricks.com/almanac/selectors/m/matches/))选择器,但是目前**不支持**在同一个选择器中调用多个自定义选择器,例如: +`@custom-selector` 目前**不支持**在同一个选择器中调用多个自定义选择器,例如: 示例3: ```css -@custom-selector --heading h1, h2, h3, h4, h5, h6; +@custom-selector :--heading h1, h2, h3, h4, h5, h6; @custom-selector :--any-link :link, :visited; -.demo --heading, a:--any-link { +.demo :--heading, a:--any-link { font-size: 32px; } ``` + 将会输出错误的 CSS 代码。 ```css @@ -121,11 +119,13 @@ a:visited { .demo h3, .demo h4, .demo h5, -.demo h6,undefined { +.demo h6,:link, +:visited { font-size: 32px; } ``` + ### Node Watch 依赖 [chokidar](https://github.com/paulmillr/chokidar) 模块。 diff --git a/README.md b/README.md index 91bd215f02..b8401e6ea3 100644 --- a/README.md +++ b/README.md @@ -43,9 +43,9 @@ var output = postcss(selector()) input.css: ```css -@custom-selector --heading h1, h2, h3, h4, h5, h6; +@custom-selector :--heading h1, h2, h3, h4, h5, h6; -article --heading + p { +article :--heading + p { margin-top: 0; } ``` @@ -65,17 +65,12 @@ article h6 + p { ## CSS syntax - @custom-selector = @custom-selector ; + @custom-selector = @custom-selector : ; ## How to use -### Pseudo-element/Pseudo-class - -You can use - -* `:` to customise a class. -* `::`to customise a Pseudo-element. +The custom selector is a pseudo-class, so we must use the `:--` to defined it. For example to simulate [:any-link](http://dev.w3.org/csswg/selectors/#the-any-link-pseudo) selector: @@ -99,20 +94,22 @@ a:visited { color: blue; } ``` + ### Multiple selectors -`@custom-selector` similar to CSS [`:matches()`](http://dev.w3.org/csswg/selectors-4/#matches)([`-moz-any()`](https://developer.mozilla.org/en-US/docs/Web/CSS/:any)/[`-webkit-any()`](http://css-tricks.com/almanac/selectors/m/matches/))selector,but it **doesn’t support** call multiple custom selector in the same selector, e.g. +`@custom-selector` it **doesn’t support** call multiple custom selector in the same selector, e.g. Example 3: ```css -@custom-selector --heading h1, h2, h3, h4, h5, h6; +@custom-selector :--heading h1, h2, h3, h4, h5, h6; @custom-selector :--any-link :link, :visited; .demo --heading, a:--any-link { font-size: 32px; } ``` + This will throw an error CSS code. ```css @@ -121,7 +118,8 @@ This will throw an error CSS code. .demo h3, .demo h4, .demo h5, -.demo h6,undefined { +.demo h6,:link, +:visited { font-size: 32px; } ``` diff --git a/index.js b/index.js index 231b2e0d42..84dcb4accd 100644 --- a/index.js +++ b/index.js @@ -1,9 +1,9 @@ /** * 匹配自定义选择器 - * --foo, :--foo, ::--foo 三种类型 + * :--foo * 注意:CSS 选择器区分大小写 */ -var re_CUSTOM_SELECTOR = /([^,]*?)((?::|::)?(?:--[\w-]+))([^,]*)/g +var re_CUSTOM_SELECTOR = /([^,]*?)(:-{2,}[\w-]+)([^,]*)/g /** * 暴露插件 @@ -58,16 +58,18 @@ function customSelector(options) { for (var prop in customSelectors) { if (rule.selector.indexOf(prop) >= 0) { customSelector = customSelectors[prop] - // $2 = (自定义的选择器名称) + rule.selector = rule.selector.replace(re_CUSTOM_SELECTOR, function($0, $1, $2, $3) { - if ($2 == prop) { + if ($2 === prop) { return customSelector.split(",").map(function(selector) { return $1 + selector.trim() + $3 }).join("," + line_break) + } else if ($2 !== prop){ + console.log("Warning: The selector '" + $2 + "' is undefined in CSS!") + return $2 } }) - } } }) diff --git a/package.json b/package.json index 36fe717d2d..b08f3d1bf7 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "postcss-custom-selectors", - "version": "1.1.1", + "version": "2.0.0", "description": "PostCSS plugin to transform W3C CSS Extensions(Custom Selectors) to more compatible CSS", "keywords": [ "css", diff --git a/test/fixtures/extension.css b/test/fixtures/extension.css index 95b234e9a9..d6fbcf7670 100644 --- a/test/fixtures/extension.css +++ b/test/fixtures/extension.css @@ -1,10 +1,10 @@ @custom-selector :--any .foo, .bar; -@custom-selector --foo .baz; +@custom-selector :--foo .baz; :--any h1 { margin-top: 16px; } -main --foo + p { +main :--foo + p { margin-top: 16px; } diff --git a/test/fixtures/heading.css b/test/fixtures/heading.css index 5f0a1b5616..dbc7695ae3 100644 --- a/test/fixtures/heading.css +++ b/test/fixtures/heading.css @@ -1,5 +1,5 @@ -@custom-selector --heading h1, h2, h3, h4, h5, h6; +@custom-selector :--heading h1, h2, h3, h4, h5, h6; -article --heading + p { +article :--heading + p { margin-top: 0; } diff --git a/test/fixtures/pseudo.css b/test/fixtures/pseudo.css index 8ab7951a25..b8feddc099 100644 --- a/test/fixtures/pseudo.css +++ b/test/fixtures/pseudo.css @@ -1,5 +1,5 @@ -@custom-selector ::--pseudo ::before, ::after; +@custom-selector :--pseudo ::before, ::after; -.foo > a::--pseudo img { +.foo > a:--pseudo img { display: block; } diff --git a/test/fixtures/some-hyphen-selector.css b/test/fixtures/some-hyphen-selector.css new file mode 100644 index 0000000000..c69585eee5 --- /dev/null +++ b/test/fixtures/some-hyphen-selector.css @@ -0,0 +1,10 @@ +@custom-selector :--foo h1, h2, h3; +@custom-selector :--ba-----r h4, h5, h6; + +.fo--oo > :--foo { + margin: auto; +} + +:--ba-----r:hover .ba--z { + display: block; +} diff --git a/test/fixtures/some-hyphen-selector.expected.css b/test/fixtures/some-hyphen-selector.expected.css new file mode 100644 index 0000000000..f545bd2cd0 --- /dev/null +++ b/test/fixtures/some-hyphen-selector.expected.css @@ -0,0 +1,11 @@ +.fo--oo > h1, +.fo--oo > h2, +.fo--oo > h3 { + margin: auto; +} + +h4:hover .ba--z, +h5:hover .ba--z, +h6:hover .ba--z { + display: block; +} diff --git a/test/index.js b/test/index.js index 2d3c3973aa..34c24ba47a 100644 --- a/test/index.js +++ b/test/index.js @@ -4,6 +4,7 @@ var test = require("tape") var postcss = require("postcss") var plugin = require("..") +var matches = require("postcss-selector-matches") function filename(name) { return "test/" + name + ".css" } function read(name) { return fs.readFileSync(name, "utf8") } @@ -12,21 +13,24 @@ 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 actual = postcss() + .use(plugin(opts)) + .process(read(postcssOpts.from), postcssOpts).css var expected = read(filename("fixtures/" + name + ".expected")) fs.writeFile(filename("fixtures/" + name + ".actual"), actual) t.equal(actual.trim(), expected.trim(), msg) } test("@custom-selector", function(t) { - compareFixtures(t, "heading", "should transform custom selector") - compareFixtures(t, "pseudo", "should transform custom selector") - compareFixtures(t, "multiline", "should transform custom selector") + compareFixtures(t, "heading", "should transform heading") + compareFixtures(t, "pseudo", "should transform pseudo") + compareFixtures(t, "multiline", "should transform multiline") + compareFixtures(t, "some-hyphen-selector", "should transform some-hyphen-selector") - compareFixtures(t, "extension", "local extensions", { + compareFixtures(t, "extension", "should transform local extensions", { extensions: { ':--any' : 'section, article, aside, nav', - '--foo': 'input[type="text"] > section, #nav .bar' + ':--foo': 'input[type="text"] > section, #nav .bar' } }) From 04db227ffb609735c0f3ead890096f45799bb31b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=B8=80=E4=B8=9D?= Date: Fri, 29 May 2015 23:23:32 +0800 Subject: [PATCH 207/795] Add badges --- README-zh.md | 7 ++++++- README.md | 7 ++++++- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/README-zh.md b/README-zh.md index a2d24350a4..7145d5baae 100644 --- a/README-zh.md +++ b/README-zh.md @@ -1,4 +1,9 @@ -# PostCSS Custom Selectors [![Build Status](https://travis-ci.org/postcss/postcss-custom-selectors.svg)](https://travis-ci.org/postcss/postcss-custom-selectors) +# PostCSS Custom Selectors + +[![Build Status](https://travis-ci.org/postcss/postcss-custom-selectors.svg?branch=master)](https://travis-ci.org/postcss/postcss-custom-selectors) +[![NPM Downloads](https://img.shields.io/npm/dm/postcss-custom-selectors.svg?style=flat)](https://www.npmjs.com/package/postcss-custom-selectors) +[![NPM Version](http://img.shields.io/npm/v/postcss-custom-selectors.svg?style=flat)](https://www.npmjs.com/package/postcss-custom-selectors) +[![License](https://img.shields.io/npm/l/postcss-custom-selectors.svg?style=flat)](http://opensource.org/licenses/MIT) > [PostCSS](https://github.com/postcss/postcss) 实现 [W3C CSS Extensions(Custom Selectors)](http://dev.w3.org/csswg/css-extensions/#custom-selectors) 的插件。 diff --git a/README.md b/README.md index b8401e6ea3..602e95f381 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,9 @@ -# PostCSS Custom Selectors [![Build Status](https://travis-ci.org/postcss/postcss-custom-selectors.svg)](https://travis-ci.org/postcss/postcss-custom-selectors) +# PostCSS Custom Selectors + +[![Build Status](https://travis-ci.org/postcss/postcss-custom-selectors.svg?branch=master)](https://travis-ci.org/postcss/postcss-custom-selectors) +[![NPM Downloads](https://img.shields.io/npm/dm/postcss-custom-selectors.svg?style=flat)](https://www.npmjs.com/package/postcss-custom-selectors) +[![NPM Version](http://img.shields.io/npm/v/postcss-custom-selectors.svg?style=flat)](https://www.npmjs.com/package/postcss-custom-selectors) +[![License](https://img.shields.io/npm/l/postcss-custom-selectors.svg?style=flat)](http://opensource.org/licenses/MIT) > [PostCSS](https://github.com/postcss/postcss) plugin to transform [W3C CSS Extensions(Custom Selectors)](http://dev.w3.org/csswg/css-extensions/#custom-selectors) to more compatible CSS. From 45a848053177c46b9dd16c71982b6791c9a6089f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=B8=80=E4=B8=9D?= Date: Mon, 1 Jun 2015 11:33:23 +0800 Subject: [PATCH 208/795] Add node.js 0.12 and iojs to Travis CI --- .travis.yml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/.travis.yml b/.travis.yml index 587bd3e031..ffb8b3996f 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1 +1,6 @@ +sudo: false language: node_js +node_js: + - iojs + - "0.12" + - "0.10" From f43a62c4ed1526f3e50a4046dcf5041ef555faa9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=B8=80=E4=B8=9D?= Date: Mon, 1 Jun 2015 11:34:03 +0800 Subject: [PATCH 209/795] Remove postcss-selector-matches --- test/index.js | 1 - 1 file changed, 1 deletion(-) diff --git a/test/index.js b/test/index.js index 34c24ba47a..b343735805 100644 --- a/test/index.js +++ b/test/index.js @@ -4,7 +4,6 @@ var test = require("tape") var postcss = require("postcss") var plugin = require("..") -var matches = require("postcss-selector-matches") function filename(name) { return "test/" + name + ".css" } function read(name) { return fs.readFileSync(name, "utf8") } From 9d337b6f148e595add605a527d0a84e5535ebd6a Mon Sep 17 00:00:00 2001 From: Jared Wyles Date: Wed, 3 Jun 2015 08:34:07 +1000 Subject: [PATCH 210/795] By matching anything after the custom selector we avoid a potential problem with commas. We should trust postcss to not give us multiple selectors in its array --- index.js | 4 ++-- test/fixtures/matches.css | 11 +++++++++++ test/fixtures/matches.expected.css | 11 +++++++++++ test/index.js | 1 + 4 files changed, 25 insertions(+), 2 deletions(-) create mode 100644 test/fixtures/matches.css create mode 100644 test/fixtures/matches.expected.css diff --git a/index.js b/index.js index 84dcb4accd..72c35700b3 100644 --- a/index.js +++ b/index.js @@ -3,7 +3,8 @@ * :--foo * 注意:CSS 选择器区分大小写 */ -var re_CUSTOM_SELECTOR = /([^,]*?)(:-{2,}[\w-]+)([^,]*)/g +//var re_CUSTOM_SELECTOR = /([^,]*?)(:-{2,}[\w-]+)([^,]*)/g +var re_CUSTOM_SELECTOR = /([^,]*?)(:-{2,}[\w-]+)(.*)/g /** * 暴露插件 @@ -52,7 +53,6 @@ function customSelector(options) { if (!options.lineBreak && options.lineBreak == false) { line_break = ' ' } - // 转换自定义的选择器别名 styles.eachRule(function(rule) { for (var prop in customSelectors) { diff --git a/test/fixtures/matches.css b/test/fixtures/matches.css new file mode 100644 index 0000000000..70390fb953 --- /dev/null +++ b/test/fixtures/matches.css @@ -0,0 +1,11 @@ +@custom-selector :--buttons button, .button; + +:--buttons:matches(:focus) { + border: red; + display: block; +} + +:--buttons:matches(:focus, .is-focused) { + border: red; + display: block; +} \ No newline at end of file diff --git a/test/fixtures/matches.expected.css b/test/fixtures/matches.expected.css new file mode 100644 index 0000000000..eaa6cae1f5 --- /dev/null +++ b/test/fixtures/matches.expected.css @@ -0,0 +1,11 @@ +button:matches(:focus), +.button:matches(:focus) { + border: red; + display: block; +} + +button:matches(:focus, .is-focused), +.button:matches(:focus, .is-focused) { + border: red; + display: block; +} \ No newline at end of file diff --git a/test/index.js b/test/index.js index b343735805..625746580a 100644 --- a/test/index.js +++ b/test/index.js @@ -25,6 +25,7 @@ test("@custom-selector", function(t) { compareFixtures(t, "pseudo", "should transform pseudo") compareFixtures(t, "multiline", "should transform multiline") compareFixtures(t, "some-hyphen-selector", "should transform some-hyphen-selector") + compareFixtures(t, "matches", "should transform matches selector") compareFixtures(t, "extension", "should transform local extensions", { extensions: { From e0b2578306b0740758caa3da062f485040727274 Mon Sep 17 00:00:00 2001 From: Jared Wyles Date: Wed, 3 Jun 2015 10:18:32 +1000 Subject: [PATCH 211/795] Removing the old regex, and adding some white space back in i appeared to have removed --- index.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/index.js b/index.js index 72c35700b3..0e9430591c 100644 --- a/index.js +++ b/index.js @@ -3,7 +3,6 @@ * :--foo * 注意:CSS 选择器区分大小写 */ -//var re_CUSTOM_SELECTOR = /([^,]*?)(:-{2,}[\w-]+)([^,]*)/g var re_CUSTOM_SELECTOR = /([^,]*?)(:-{2,}[\w-]+)(.*)/g /** @@ -53,13 +52,14 @@ function customSelector(options) { if (!options.lineBreak && options.lineBreak == false) { line_break = ' ' } + // 转换自定义的选择器别名 styles.eachRule(function(rule) { for (var prop in customSelectors) { if (rule.selector.indexOf(prop) >= 0) { customSelector = customSelectors[prop] + // $2 = (自定义的选择器名称) - rule.selector = rule.selector.replace(re_CUSTOM_SELECTOR, function($0, $1, $2, $3) { if ($2 === prop) { return customSelector.split(",").map(function(selector) { From d8455e7f852a127c216cfa9b814e9eb43f026e2f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=B8=80=E4=B8=9D?= Date: Wed, 3 Jun 2015 14:46:48 +0800 Subject: [PATCH 212/795] Format code --- index.js | 8 ++++---- test/fixtures/matches.css | 2 +- test/fixtures/matches.expected.css | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/index.js b/index.js index 0e9430591c..1847f3bbb2 100644 --- a/index.js +++ b/index.js @@ -49,8 +49,8 @@ function customSelector(options) { }) //控制选择器是否换行 - if (!options.lineBreak && options.lineBreak == false) { - line_break = ' ' + if (!options.lineBreak && options.lineBreak == false) { + line_break = ' ' } // 转换自定义的选择器别名 @@ -58,14 +58,14 @@ function customSelector(options) { for (var prop in customSelectors) { if (rule.selector.indexOf(prop) >= 0) { customSelector = customSelectors[prop] - + // $2 = (自定义的选择器名称) rule.selector = rule.selector.replace(re_CUSTOM_SELECTOR, function($0, $1, $2, $3) { if ($2 === prop) { return customSelector.split(",").map(function(selector) { return $1 + selector.trim() + $3 }).join("," + line_break) - } else if ($2 !== prop){ + } else if ($2 !== prop) { console.log("Warning: The selector '" + $2 + "' is undefined in CSS!") return $2 } diff --git a/test/fixtures/matches.css b/test/fixtures/matches.css index 70390fb953..46545493ba 100644 --- a/test/fixtures/matches.css +++ b/test/fixtures/matches.css @@ -8,4 +8,4 @@ :--buttons:matches(:focus, .is-focused) { border: red; display: block; -} \ No newline at end of file +} diff --git a/test/fixtures/matches.expected.css b/test/fixtures/matches.expected.css index eaa6cae1f5..7f93f4e2a3 100644 --- a/test/fixtures/matches.expected.css +++ b/test/fixtures/matches.expected.css @@ -8,4 +8,4 @@ button:matches(:focus, .is-focused), .button:matches(:focus, .is-focused) { border: red; display: block; -} \ No newline at end of file +} From 1ca1db3b441238c8448630f55e9a00141a68f460 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=B8=80=E4=B8=9D?= Date: Wed, 3 Jun 2015 16:44:52 +0800 Subject: [PATCH 213/795] Modify the test file as an independent directory. --- .gitignore | 2 +- .../{extension.css => extension/input.css} | 0 .../output.css} | 0 test/fixtures/{heading.css => heading/input.css} | 0 .../{heading.expected.css => heading/output.css} | 0 test/fixtures/{matches.css => matches/input.css} | 0 .../{matches.expected.css => matches/output.css} | 0 .../{multiline.css => multiline/input.css} | 0 .../output.css} | 0 test/fixtures/{pseudo.css => pseudo/input.css} | 0 .../{pseudo.expected.css => pseudo/output.css} | 0 .../input.css} | 0 .../output.css} | 0 test/index.js | 14 +++++++++----- 14 files changed, 10 insertions(+), 6 deletions(-) rename test/fixtures/{extension.css => extension/input.css} (100%) rename test/fixtures/{extension.expected.css => extension/output.css} (100%) rename test/fixtures/{heading.css => heading/input.css} (100%) rename test/fixtures/{heading.expected.css => heading/output.css} (100%) rename test/fixtures/{matches.css => matches/input.css} (100%) rename test/fixtures/{matches.expected.css => matches/output.css} (100%) rename test/fixtures/{multiline.css => multiline/input.css} (100%) rename test/fixtures/{multiline.expected.css => multiline/output.css} (100%) rename test/fixtures/{pseudo.css => pseudo/input.css} (100%) rename test/fixtures/{pseudo.expected.css => pseudo/output.css} (100%) rename test/fixtures/{some-hyphen-selector.css => some-hyphen/input.css} (100%) rename test/fixtures/{some-hyphen-selector.expected.css => some-hyphen/output.css} (100%) diff --git a/.gitignore b/.gitignore index bf008057d6..a3e84c1f3d 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,5 @@ .DS_Store node_modules -test/fixtures/*.actual.css +test/fixtures/*/actual.css *.sublime-workspace diff --git a/test/fixtures/extension.css b/test/fixtures/extension/input.css similarity index 100% rename from test/fixtures/extension.css rename to test/fixtures/extension/input.css diff --git a/test/fixtures/extension.expected.css b/test/fixtures/extension/output.css similarity index 100% rename from test/fixtures/extension.expected.css rename to test/fixtures/extension/output.css diff --git a/test/fixtures/heading.css b/test/fixtures/heading/input.css similarity index 100% rename from test/fixtures/heading.css rename to test/fixtures/heading/input.css diff --git a/test/fixtures/heading.expected.css b/test/fixtures/heading/output.css similarity index 100% rename from test/fixtures/heading.expected.css rename to test/fixtures/heading/output.css diff --git a/test/fixtures/matches.css b/test/fixtures/matches/input.css similarity index 100% rename from test/fixtures/matches.css rename to test/fixtures/matches/input.css diff --git a/test/fixtures/matches.expected.css b/test/fixtures/matches/output.css similarity index 100% rename from test/fixtures/matches.expected.css rename to test/fixtures/matches/output.css diff --git a/test/fixtures/multiline.css b/test/fixtures/multiline/input.css similarity index 100% rename from test/fixtures/multiline.css rename to test/fixtures/multiline/input.css diff --git a/test/fixtures/multiline.expected.css b/test/fixtures/multiline/output.css similarity index 100% rename from test/fixtures/multiline.expected.css rename to test/fixtures/multiline/output.css diff --git a/test/fixtures/pseudo.css b/test/fixtures/pseudo/input.css similarity index 100% rename from test/fixtures/pseudo.css rename to test/fixtures/pseudo/input.css diff --git a/test/fixtures/pseudo.expected.css b/test/fixtures/pseudo/output.css similarity index 100% rename from test/fixtures/pseudo.expected.css rename to test/fixtures/pseudo/output.css diff --git a/test/fixtures/some-hyphen-selector.css b/test/fixtures/some-hyphen/input.css similarity index 100% rename from test/fixtures/some-hyphen-selector.css rename to test/fixtures/some-hyphen/input.css diff --git a/test/fixtures/some-hyphen-selector.expected.css b/test/fixtures/some-hyphen/output.css similarity index 100% rename from test/fixtures/some-hyphen-selector.expected.css rename to test/fixtures/some-hyphen/output.css diff --git a/test/index.js b/test/index.js index 625746580a..1b466a08db 100644 --- a/test/index.js +++ b/test/index.js @@ -10,21 +10,25 @@ function read(name) { return fs.readFileSync(name, "utf8") } function compareFixtures(t, name, msg, opts, postcssOpts) { postcssOpts = postcssOpts || {} - postcssOpts.from = filename("fixtures/" + name) + //input + postcssOpts.from = filename("fixtures/" + name + "/input") + console.log('postcssOpts.from', postcssOpts.from) opts = opts || {} var actual = postcss() .use(plugin(opts)) .process(read(postcssOpts.from), postcssOpts).css - var expected = read(filename("fixtures/" + name + ".expected")) - fs.writeFile(filename("fixtures/" + name + ".actual"), actual) - t.equal(actual.trim(), expected.trim(), msg) + //output + var output = read(filename("fixtures/" + name + "/output")) + //actual + fs.writeFile(filename("fixtures/" + name + "/actual"), actual) + t.equal(actual.trim(), output.trim(), msg) } test("@custom-selector", function(t) { compareFixtures(t, "heading", "should transform heading") compareFixtures(t, "pseudo", "should transform pseudo") compareFixtures(t, "multiline", "should transform multiline") - compareFixtures(t, "some-hyphen-selector", "should transform some-hyphen-selector") + compareFixtures(t, "some-hyphen", "should transform some hyphen") compareFixtures(t, "matches", "should transform matches selector") compareFixtures(t, "extension", "should transform local extensions", { From 8953a20e54539cbfa263c130788f33b7cea1f242 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=B8=80=E4=B8=9D?= Date: Wed, 3 Jun 2015 16:50:48 +0800 Subject: [PATCH 214/795] Fixed doc --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 602e95f381..125b337623 100644 --- a/README.md +++ b/README.md @@ -110,7 +110,7 @@ Example 3: @custom-selector :--heading h1, h2, h3, h4, h5, h6; @custom-selector :--any-link :link, :visited; -.demo --heading, a:--any-link { +.demo :--heading, a:--any-link { font-size: 32px; } ``` From f6034c5f92234d08828a0b161963312cecb40c5b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=B8=80=E4=B8=9D?= Date: Wed, 3 Jun 2015 16:58:23 +0800 Subject: [PATCH 215/795] Publish 2.0.1 --- CHANGELOG.md | 12 ++++++++---- package.json | 2 +- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 60b8ab1109..f5e9fee1f1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,16 +1,20 @@ +# 2.0.1 - 2015-06-03 + +* \- Fixed: `(foo, bar)` conversion error exists in the selector(See also [:matches() test](test/fixtures/matches/input.css)). + # 2.0.0 - 2015-05-29 -* x Remove: no longer support `::` or `--` to defined a custom selectors, we must use the `:--` to defined it. +* \x Remove: no longer support `::` or `--` to defined a custom selectors, we must use the `:--` to defined it. -* - Fixed: two or more consecutive hyphens in selector outputs is "undefined". +* \- Fixed: two or more consecutive hyphens in selector outputs is "undefined". # 1.1.1 - 2015-04-06 -* - Fixed: add support for multilines definition +* \- Fixed: add support for multilines definition # 1.1.0 - 2014-12-06 -* - Added: "lineBreak" option +* \- Added: "lineBreak" option # 1.0.0 - 2014-12-06 diff --git a/package.json b/package.json index b08f3d1bf7..da70c74aa5 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "postcss-custom-selectors", - "version": "2.0.0", + "version": "2.0.1", "description": "PostCSS plugin to transform W3C CSS Extensions(Custom Selectors) to more compatible CSS", "keywords": [ "css", From e020e3220644d1975b4dc7102d1acb1e0bec38a0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=B8=80=E4=B8=9D?= Date: Thu, 4 Jun 2015 11:10:42 +0800 Subject: [PATCH 216/795] Use PostCSS 4.1 plugin API --- index.js | 28 +++++++++++++++------------- package.json | 7 ++++--- test/index.js | 4 ++-- 3 files changed, 21 insertions(+), 18 deletions(-) diff --git a/index.js b/index.js index 1847f3bbb2..d0ead53086 100644 --- a/index.js +++ b/index.js @@ -1,3 +1,4 @@ +var postcss = require("postcss") /** * 匹配自定义选择器 * :--foo @@ -8,20 +9,21 @@ var re_CUSTOM_SELECTOR = /([^,]*?)(:-{2,}[\w-]+)(.*)/g /** * 暴露插件 */ -module.exports = customSelector +module.exports = postcss.plugin("postcss-custom-selectors", function(options) { + /** + * 插件配置 + */ + options = options || {} + var extensions = options.extensions || {} + var line_break = '\n' + var map = {} + var toRemove = [] + var customSelectors = {} -/** - * 读取和替换自定义选择器 - */ -function customSelector(options) { + /** + * 读取和替换自定义选择器 + */ return function(styles) { - options = options || {} - var extensions = options.extensions || {} - var line_break = '\n' - var map = {} - var toRemove = [] - var customSelectors = {} - // 读取自定义选择器 styles.eachAtRule(function(rule) { if (rule.name !== "custom-selector") { @@ -80,4 +82,4 @@ function customSelector(options) { }) } -} +}) diff --git a/package.json b/package.json index da70c74aa5..c909227ba0 100644 --- a/package.json +++ b/package.json @@ -8,7 +8,8 @@ "postcss", "postcss-plugins", "selector", - "custom-selector" + "custom-selector", + "custom selector" ], "author": "yisi", "license": "MIT", @@ -23,8 +24,8 @@ "index.js" ], "devDependencies": { - "postcss": "^3.0.0", - "tape": "^3.0.0" + "postcss": "^4.1.11", + "tape": "^4.0.0" }, "scripts": { "test": "tape test" diff --git a/test/index.js b/test/index.js index 1b466a08db..7816c0e947 100644 --- a/test/index.js +++ b/test/index.js @@ -12,11 +12,11 @@ function compareFixtures(t, name, msg, opts, postcssOpts) { postcssOpts = postcssOpts || {} //input postcssOpts.from = filename("fixtures/" + name + "/input") - console.log('postcssOpts.from', postcssOpts.from) opts = opts || {} var actual = postcss() .use(plugin(opts)) - .process(read(postcssOpts.from), postcssOpts).css + .process(read(postcssOpts.from), postcssOpts) + .css //output var output = read(filename("fixtures/" + name + "/output")) //actual From 675bad97f1014bb770a1ebca2d744cd54cc2cb9d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=B8=80=E4=B8=9D?= Date: Thu, 4 Jun 2015 14:17:36 +0800 Subject: [PATCH 217/795] Publish 2.1.0 --- CHANGELOG.md | 4 ++++ package.json | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f5e9fee1f1..897aaf8851 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,7 @@ +# 2.1.0 - 2015-06-04 + +* \- Fixed: Use PostCSS 4.1 plugin API. + # 2.0.1 - 2015-06-03 * \- Fixed: `(foo, bar)` conversion error exists in the selector(See also [:matches() test](test/fixtures/matches/input.css)). diff --git a/package.json b/package.json index c909227ba0..63b1fc627e 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "postcss-custom-selectors", - "version": "2.0.1", + "version": "2.1.0", "description": "PostCSS plugin to transform W3C CSS Extensions(Custom Selectors) to more compatible CSS", "keywords": [ "css", From 759c7d984500ecdff564bf49f40880d2912cd51b Mon Sep 17 00:00:00 2001 From: Maxime Thirouin Date: Sat, 13 Jun 2015 08:06:51 +0200 Subject: [PATCH 218/795] Fixed: support of pseudo classes that use parenthesis Close #2 --- CHANGELOG.md | 5 +++++ package.json | 2 +- src/index.js | 10 +++++----- test/index.js | 6 ++++++ 4 files changed, 17 insertions(+), 6 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ac7b7b5688..59cf2b4dca 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,8 @@ +# 1.0.2 - 2015-06-13 + +- Fixed: support of pseudo classes that use parenthesis +([#2](https://github.com/postcss/postcss-selector-matches/issues/2)) + # 1.0.1 - 2015-04-30 - Fixed: the module now works in non babel environments diff --git a/package.json b/package.json index a933bfd361..0f12da5a88 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "postcss-selector-matches", - "version": "1.0.1", + "version": "1.0.2", "description": "PostCSS plugin to transform :matches() W3C CSS pseudo class to more compatible CSS selectors", "keywords": [ "postcss", diff --git a/src/index.js b/src/index.js index b0f428c19d..17ca06c090 100644 --- a/src/index.js +++ b/src/index.js @@ -4,10 +4,10 @@ import list from "postcss/lib/list" import balancedMatch from "balanced-match" function explodeSelector(pseudoClass, selector) { - if (selector && selector.indexOf(pseudoClass) > -1) { - const start = `${pseudoClass}(` - const end = ")" - const matches = balancedMatch(start, end, selector) + const position = selector.indexOf(pseudoClass) + if (selector && position > -1) { + const pre = selector.slice(0, position) + const matches = balancedMatch("(", ")", selector.slice(position)) const selectors = [] const bodySelectors = matches.body ? list @@ -17,7 +17,7 @@ function explodeSelector(pseudoClass, selector) { const postSelectors = matches.post ? explodeSelector(pseudoClass, matches.post) : [""] postSelectors.forEach(postSelector => { bodySelectors.forEach(bodySelector => { - selectors.push(matches.pre + bodySelector + postSelector) + selectors.push(pre + bodySelector + postSelector) }) }) return selectors diff --git a/test/index.js b/test/index.js index 794a4dfc50..68f6222b7d 100644 --- a/test/index.js +++ b/test/index.js @@ -56,5 +56,11 @@ tape("postcss-selector-matches", t => { "should transform shit if you ask for shit ?" ) + t.equal( + transform(".foo:matches(:nth-child(-n+2), .bar) {}"), + ".foo:nth-child(-n+2), .foo.bar {}", + "should transform childs with parenthesis" + ) + t.end() }) From 115133031ecd45cc209fd6718d609c082a3acb69 Mon Sep 17 00:00:00 2001 From: Maxime Thirouin Date: Sat, 13 Jun 2015 08:26:50 +0200 Subject: [PATCH 219/795] Added: `lineBreak` option Close #1 --- CHANGELOG.md | 5 +++++ README.md | 8 ++++++++ package.json | 2 +- src/index.js | 5 +++-- test/index.js | 25 +++++++++++++++++++++++-- 5 files changed, 40 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 59cf2b4dca..0893b525c2 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,8 @@ +# 1.1.0 - 2015-06-13 + +- Added: `lineBreak` option +([#1](https://github.com/postcss/postcss-selector-matches/issues/1)) + # 1.0.2 - 2015-06-13 - Fixed: support of pseudo classes that use parenthesis diff --git a/README.md b/README.md index d7efac26c4..fe7577d136 100644 --- a/README.md +++ b/README.md @@ -40,6 +40,14 @@ p:first-child, p.special { **Note that if you are doing crazy selector like `p:matches(a) {}` you are likely to get crazy results (like `pa {}`)**. +## Options + +### `lineBreak` + +(default: `false`) + +Allows you to introduce a line break between generated selectors. + --- ## [Changelog](CHANGELOG.md) diff --git a/package.json b/package.json index 0f12da5a88..fcf6cdcbf0 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "postcss-selector-matches", - "version": "1.0.2", + "version": "1.1.0", "description": "PostCSS plugin to transform :matches() W3C CSS pseudo class to more compatible CSS selectors", "keywords": [ "postcss", diff --git a/src/index.js b/src/index.js index 17ca06c090..1d16bddb1d 100644 --- a/src/index.js +++ b/src/index.js @@ -26,11 +26,12 @@ function explodeSelector(pseudoClass, selector) { } function explodeSelectors(pseudoClass) { - return () => { + return (options = {}) => { return (css) => { css.eachRule(rule => { if (rule.selector && rule.selector.indexOf(pseudoClass) > -1) { - rule.selector = explodeSelector(pseudoClass, rule.selector).join(", ") + rule.selector = explodeSelector(pseudoClass, rule.selector) + .join("," + (options.lineBreak ? "\n" + rule.before : " ")) } }) } diff --git a/test/index.js b/test/index.js index 68f6222b7d..dcca39b7f2 100644 --- a/test/index.js +++ b/test/index.js @@ -3,8 +3,8 @@ import tape from "tape" import postcss from "postcss" import selectorMatches from "../src/index.js" -function transform(css) { - return postcss(selectorMatches).process(css).css +function transform(css, options = {}) { + return postcss(selectorMatches(options)).process(css).css } tape("postcss-selector-matches", t => { @@ -62,5 +62,26 @@ tape("postcss-selector-matches", t => { "should transform childs with parenthesis" ) + t.equal( + transform(`a:matches( + .b, + .c +) {}`), + "a.b, a.c {}", + "should works with lots of whitespace" + ) + + t.equal( + transform(".foo:matches(:nth-child(-n+2), .bar) {}", {lineBreak: true}), + ".foo:nth-child(-n+2),\n.foo.bar {}", + "should add line break if asked too" + ) + + t.equal( + transform(" .foo:matches(:nth-child(-n+2), .bar) {}", {lineBreak: true}), + " .foo:nth-child(-n+2),\n .foo.bar {}", + "should add line break if asked too, and respect indentation" + ) + t.end() }) From b06a327d9dd553333a2a1ce9cc8e061c96357998 Mon Sep 17 00:00:00 2001 From: Maxime Thirouin Date: Sat, 13 Jun 2015 08:31:21 +0200 Subject: [PATCH 220/795] Fixed: support of pseudo classes that use parenthesis Ref https://github.com/postcss/postcss-selector-matches/issues/2 --- CHANGELOG.md | 4 ++++ package.json | 2 +- src/index.js | 10 +++++----- test/index.js | 6 ++++++ 4 files changed, 16 insertions(+), 6 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ac7b7b5688..9a685aac54 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,7 @@ +# 1.0.2 - 2015-06-13 + +- Fixed: support of pseudo classes that use parenthesis + # 1.0.1 - 2015-04-30 - Fixed: the module now works in non babel environments diff --git a/package.json b/package.json index a8aa5a7dff..af25926fba 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "postcss-selector-not", - "version": "1.0.1", + "version": "1.0.2", "description": "PostCSS plugin to transform :not() W3C CSS leve 4 pseudo class to :not() CSS level 3 selectors", "keywords": [ "postcss", diff --git a/src/index.js b/src/index.js index ce262d2c12..bbc775c73b 100644 --- a/src/index.js +++ b/src/index.js @@ -4,10 +4,10 @@ import list from "postcss/lib/list" import balancedMatch from "balanced-match" function explodeSelector(pseudoClass, selector) { - if (selector && selector.indexOf(pseudoClass) > -1) { - const start = `${pseudoClass}(` - const end = ")" - const matches = balancedMatch(start, end, selector) + const position = selector.indexOf(pseudoClass) + if (selector && position > -1) { + const pre = selector.slice(0, position) + const matches = balancedMatch("(", ")", selector.slice(position)) const selectors = [] const bodySelectors = matches.body ? list @@ -17,7 +17,7 @@ function explodeSelector(pseudoClass, selector) { const postSelectors = matches.post ? explodeSelector(pseudoClass, matches.post) : [""] postSelectors.forEach(postSelector => { bodySelectors.forEach(bodySelector => { - selectors.push(`${matches.pre}${pseudoClass}(${bodySelector})${postSelector}`) + selectors.push(`${pre}${pseudoClass}(${bodySelector})${postSelector}`) }) }) return selectors diff --git a/test/index.js b/test/index.js index 17bd590fec..5aeee21716 100644 --- a/test/index.js +++ b/test/index.js @@ -50,5 +50,11 @@ tape("postcss-selector-not", t => { "should transform :not() recursively" ) + t.equal( + transform(".foo:not(:nth-child(-n+2), .bar) {}"), + ".foo:not(:nth-child(-n+2)), .foo:not(.bar) {}", + "should transform childs with parenthesis" + ) + t.end() }) From cef5755a413d5b78f31239b3f08366c589429b7d Mon Sep 17 00:00:00 2001 From: Maxime Thirouin Date: Sat, 13 Jun 2015 08:37:39 +0200 Subject: [PATCH 221/795] Added: `lineBreak` option Ref: https://github.com/postcss/postcss-selector-matches/issues/1 --- CHANGELOG.md | 4 ++++ README.md | 8 ++++++++ package.json | 2 +- src/index.js | 6 ++++-- test/index.js | 25 +++++++++++++++++++++++-- 5 files changed, 40 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9a685aac54..36d56c8380 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,7 @@ +# 1.1.0 - 2015-06-13 + +- Added: `lineBreak` option + # 1.0.2 - 2015-06-13 - Fixed: support of pseudo classes that use parenthesis diff --git a/README.md b/README.md index 9c097ca131..a228b676d5 100644 --- a/README.md +++ b/README.md @@ -37,6 +37,14 @@ p:not(:first-child), p:not(.special) { } ``` +## Options + +### `lineBreak` + +(default: `false`) + +Allows you to introduce a line break between generated selectors. + --- ## [Changelog](CHANGELOG.md) diff --git a/package.json b/package.json index af25926fba..65d41de7a3 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "postcss-selector-not", - "version": "1.0.2", + "version": "1.1.0", "description": "PostCSS plugin to transform :not() W3C CSS leve 4 pseudo class to :not() CSS level 3 selectors", "keywords": [ "postcss", diff --git a/src/index.js b/src/index.js index bbc775c73b..e50babbdf4 100644 --- a/src/index.js +++ b/src/index.js @@ -26,15 +26,17 @@ function explodeSelector(pseudoClass, selector) { } function explodeSelectors(pseudoClass) { - return () => { + return (options = {}) => { return (css) => { css.eachRule(rule => { if (rule.selector && rule.selector.indexOf(pseudoClass) > -1) { - rule.selector = explodeSelector(pseudoClass, rule.selector).join(", ") + rule.selector = explodeSelector(pseudoClass, rule.selector) + .join("," + (options.lineBreak ? "\n" + rule.before : " ")) } }) } } } + export default postcss.plugin("postcss-selector-not", explodeSelectors(":not")) diff --git a/test/index.js b/test/index.js index 5aeee21716..3dbe62bb8a 100644 --- a/test/index.js +++ b/test/index.js @@ -3,8 +3,8 @@ import tape from "tape" import postcss from "postcss" import selectorNot from "../src/index.js" -function transform(css) { - return postcss(selectorNot).process(css).css +function transform(css, options = {}) { + return postcss(selectorNot(options)).process(css).css } tape("postcss-selector-not", t => { @@ -56,5 +56,26 @@ tape("postcss-selector-not", t => { "should transform childs with parenthesis" ) + t.equal( + transform(`a:not( + .b, + .c +) {}`), + "a:not(.b), a:not(.c) {}", + "should works with lots of whitespace" + ) + + t.equal( + transform(".foo:not(:nth-child(-n+2), .bar) {}", {lineBreak: true}), + ".foo:not(:nth-child(-n+2)),\n.foo:not(.bar) {}", + "should add line break if asked too" + ) + + t.equal( + transform(" .foo:not(:nth-child(-n+2), .bar) {}", {lineBreak: true}), + " .foo:not(:nth-child(-n+2)),\n .foo:not(.bar) {}", + "should add line break if asked too, and respect indentation" + ) + t.end() }) From af2d72e2f2db95ef6fe2d6806a0de970989f9e93 Mon Sep 17 00:00:00 2001 From: Jonathan Neal Date: Sun, 14 Jun 2015 20:33:21 -0400 Subject: [PATCH 222/795] Update project scaffolding --- .eslintrc | 21 +++++++++++++++++++++ .gitignore | 2 ++ .npmignore | 8 ++++++++ .travis.yml | 6 ++++++ 4 files changed, 37 insertions(+) create mode 100644 .eslintrc create mode 100644 .gitignore create mode 100644 .npmignore create mode 100644 .travis.yml diff --git a/.eslintrc b/.eslintrc new file mode 100644 index 0000000000..1031b9da3c --- /dev/null +++ b/.eslintrc @@ -0,0 +1,21 @@ +{ + "rules": { + "no-unused-expressions": [0], + "no-underscore-dangle": [0], + "no-reserved-keys": [2], + "no-multi-spaces": [0], + "no-extra-parens": [2], + "no-unused-vars": [2], + "no-loop-func": [0], + "key-spacing": [0], + "max-len": [2], + "strict": [0], + "indent": [1, "tab"], + "quotes": [2, "single", "avoid-escape"], + "curly": [0] + }, + "env": { + "mocha": true, + "node": true + } +} diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000000..1ca957177f --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +node_modules/ +npm-debug.log diff --git a/.npmignore b/.npmignore new file mode 100644 index 0000000000..1aa2d59e25 --- /dev/null +++ b/.npmignore @@ -0,0 +1,8 @@ +.gitignore + +node_modules/ + +test/ +.travis.yml + +gulpfile.js diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000000..ffb8b3996f --- /dev/null +++ b/.travis.yml @@ -0,0 +1,6 @@ +sudo: false +language: node_js +node_js: + - iojs + - "0.12" + - "0.10" From 4b6ec6ddeb2ba5b0ff6927e56b70db7df31f5d1c Mon Sep 17 00:00:00 2001 From: Jonathan Neal Date: Sun, 14 Jun 2015 20:33:40 -0400 Subject: [PATCH 223/795] Update package.json Initial release --- package.json | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) create mode 100644 package.json diff --git a/package.json b/package.json new file mode 100644 index 0000000000..9e73ca5d27 --- /dev/null +++ b/package.json @@ -0,0 +1,28 @@ +{ + "name": "postcss-pseudo-class-any-link", + "version": "0.1.0", + "description": "Use the proposed :any-link pseudo-class in CSS", + "keywords": ["postcss", "css", "postcss-plugin", "link", "visited", "any-link", "a", "area", "hyperlink", "href"], + "author": "Jonathan Neal ", + "license": "CC0-1.0", + "bugs": { + "url": "https://github.com/jonathantneal/postcss-pseudo-class-any-link/issues" + }, + "homepage": "https://github.com/jonathantneal/postcss-pseudo-class-any-link", + "repository": { + "type": "git", + "url": "https://github.com/jonathantneal/postcss-pseudo-class-any-link.git" + }, + "dependencies": { + "postcss": "^4.1.9" + }, + "devDependencies": { + "chai": "^2.3.0", + "gulp": "^3.8.11", + "gulp-eslint": "^0.12.0", + "gulp-mocha": "^2.0.1" + }, + "scripts": { + "test": "gulp" + } +} From e5b560669b85e79363117549074a2ce576016a65 Mon Sep 17 00:00:00 2001 From: Jonathan Neal Date: Sun, 14 Jun 2015 20:34:00 -0400 Subject: [PATCH 224/795] Update functionality Initial release --- index.js | 15 +++++++++++++++ 1 file changed, 15 insertions(+) create mode 100644 index.js diff --git a/index.js b/index.js new file mode 100644 index 0000000000..cf24648cc4 --- /dev/null +++ b/index.js @@ -0,0 +1,15 @@ +var postcss = require('postcss'); + +module.exports = postcss.plugin('postcss-pseudo-class-any-link', function (opts) { + var match = new RegExp(':' + (opts && opts.prefix ? '-' + opts.prefix + '-' : '') + 'any-link\\b', 'g'); + + return function (css) { + css.eachRule(function (rule) { + if (match.test(rule.selector)) { + rule.selector = ['link', 'visited'].map(function (replacement) { + return rule.selector.replace(match, ':' + replacement); + }).join(', '); + } + }); + }; +}); From 5c3953503681b0acd8136597206fc71f3701e657 Mon Sep 17 00:00:00 2001 From: Jonathan Neal Date: Sun, 14 Jun 2015 20:34:11 -0400 Subject: [PATCH 225/795] Update test --- gulpfile.js | 18 ++++++++++++++++++ test/test.js | 32 ++++++++++++++++++++++++++++++++ 2 files changed, 50 insertions(+) create mode 100644 gulpfile.js create mode 100644 test/test.js diff --git a/gulpfile.js b/gulpfile.js new file mode 100644 index 0000000000..04d7d79d37 --- /dev/null +++ b/gulpfile.js @@ -0,0 +1,18 @@ +var gulp = require('gulp'); + +gulp.task('lint', function () { + var eslint = require('gulp-eslint'); + + return gulp.src(['index.js', 'test/*.js', 'gulpfile.js']) + .pipe(eslint()) + .pipe(eslint.format()) + .pipe(eslint.failAfterError()); +}); + +gulp.task('test', function () { + var mocha = require('gulp-mocha'); + + return gulp.src('test/*.js', { read: false }).pipe(mocha()); +}); + +gulp.task('default', ['lint', 'test']); diff --git a/test/test.js b/test/test.js new file mode 100644 index 0000000000..2bbd4326d4 --- /dev/null +++ b/test/test.js @@ -0,0 +1,32 @@ +var postcss = require('postcss'); +var expect = require('chai').expect; + +var plugin = require('../'); + +var test = function (input, output, opts, done) { + postcss([ plugin(opts) ]).process(input).then(function (result) { + expect(result.css).to.eql(output); + expect(result.warnings()).to.be.empty; + done(); + }).catch(function (error) { + done(error); + }); +}; + +describe('postcss-pseudo-class-any-link', function () { + it(':any-link transforms to :link and :visited', function (done) { + test('ul a:any-link > span { background: yellow; }', 'ul a:link > span, ul a:visited > span { background: yellow; }', {}, done); + }); + + it(':any-link remains :any-link { prefix: "foo" }', function (done) { + test('ul a:any-link > span { background: yellow; }', 'ul a:any-link > span { background: yellow; }', { + prefix: 'foo' + }, done); + }); + + it(':-foo-any-link transforms to :link and :visited { prefix: "foo" }', function (done) { + test('ul a:-foo-any-link > span { background: yellow; }', 'ul a:link > span, ul a:visited > span { background: yellow; }', { + prefix: 'foo' + }, done); + }); +}); From a3d1d88872e52a361e1fb1a428696732f57f9f92 Mon Sep 17 00:00:00 2001 From: Jonathan Neal Date: Sun, 14 Jun 2015 20:34:18 -0400 Subject: [PATCH 226/795] Update LICENSE.md --- LICENSE.md | 15 +++++++++++++++ 1 file changed, 15 insertions(+) create mode 100644 LICENSE.md diff --git a/LICENSE.md b/LICENSE.md new file mode 100644 index 0000000000..565f84e33c --- /dev/null +++ b/LICENSE.md @@ -0,0 +1,15 @@ +# CC0 1.0 Universal License + +Public Domain Dedication + +The person(s) who associated a work with this deed has dedicated the work to the public domain by waiving all of his or her rights to the work worldwide under copyright law, including all related and neighboring rights, to the extent allowed by law. + +You can copy, modify, distribute and perform the work, even for commercial purposes, all without asking permission. + +In no way are the patent or trademark rights of any person affected by CC0, nor are the rights that other persons may have in the work or in how the work is used, such as publicity or privacy rights. + +Unless expressly stated otherwise, the person(s) who associated a work with this deed makes no warranties about the work, and disclaims liability for all uses of the work, to the fullest extent permitted by applicable law. + +When using or citing the work, you should not imply endorsement by the author or the affirmer. + +This is a [human-readable summary of the Legal Code](https://creativecommons.org/publicdomain/zero/1.0/) ([read the full text](https://creativecommons.org/publicdomain/zero/1.0/legalcode)). From 2a12ff48652b0515ebe4f293b2c30062d0205a64 Mon Sep 17 00:00:00 2001 From: Jonathan Neal Date: Sun, 14 Jun 2015 20:34:28 -0400 Subject: [PATCH 227/795] Update CHANGELOG.md --- CHANGELOG.md | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 CHANGELOG.md diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000000..abaa1d5f2a --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,3 @@ +## 0.1.1 (2015-06-14) + +Initial release From c489a1f0fbf0732927671661c67ed84ce81cee31 Mon Sep 17 00:00:00 2001 From: Jonathan Neal Date: Sun, 14 Jun 2015 20:34:35 -0400 Subject: [PATCH 228/795] Update README.md --- README.md | 108 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 108 insertions(+) create mode 100644 README.md diff --git a/README.md b/README.md new file mode 100644 index 0000000000..0ec0cee0b1 --- /dev/null +++ b/README.md @@ -0,0 +1,108 @@ +# PostCSS Pseudo-Class Any-Link [![Build Status][ci-img]][ci] + + + +[PostCSS Pseudo-Class Any-Link] is a [PostCSS] plugin that allows you to use the proposed [`:any-link`] pseudo-class in CSS. + +`:any-link` simplifies selectors targeting links, since the naming of `:link` is misleading; it specifically means unvisited links only, rather than all links. + +```css +/* before */ + +nav :any-link > span { + background-color: yellow; +} + +/* after */ + +nav :link > span, +nav :visited > span { + background-color: yellow; +} +``` + +From the [proposal]: + +> The [`:any-link`] pseudo-class represents an element that acts as the source anchor of a hyperlink. It matches an element if the element would match [`:link`] or [`:visited`]. + +## Usage + +You just need to follow these two steps to use [PostCSS Pseudo-Class Any-Link]: + +1. Add [PostCSS] to your build tool. +2. Add [PostCSS Pseudo-Class Any-Link] as a PostCSS process. + +```sh +npm install postcss-pseudo-class-any-link --save-dev +``` + +### Node + +```js +postcss([ require('postcss-pseudo-class-any-link')({ /* options */ }) ]) +``` + +### Grunt + +Add [Grunt PostCSS] to your build tool: + +```sh +npm install postcss-pseudo-class-any-link --save-dev +``` + +Enable [PostCSS Pseudo-Class Any-Link] within your Gruntfile: + +```js +grunt.loadNpmTasks('grunt-postcss'); + +grunt.initConfig({ + postcss: { + options: { + processors: [ + require('postcss-pseudo-class-any-link')({ /* options */ }) + ] + }, + dist: { + src: 'css/*.css' + } + } +}); +``` + +### Options + +**prefix** (string): prepends a prefix (surrounded by dashes) to the pseudo-class, preventing any clash with native syntax. + +```js +{ + prefix: 'foo' // pseudo-class becomes :-foo-any-link +} +``` + +### Alternatives + +```css +/* Using @custom-selector; supported nowhere yet */ + +@custom-selector :--any-link :link, :visited; + +:--any-link { /* ... */ } + +/* Using :matches; supported in Firefox 4+, Chrome 12+, Opera 15+, Safari 5.1+ */ + +:matches(:link, :visited) { /* ... */ } + +/* Using :link and :visited; supported everywhere */ + +:link, :visited { /* ... */ } +``` + +[`:any-link`]: http://http://dev.w3.org/csswg/selectors/#any-link-pseudo +[`:link`]: http://dev.w3.org/csswg/selectors/#link-pseudo +[`:visited`]: http://dev.w3.org/csswg/selectors/#visited-pseudo +[ci]: https://travis-ci.org/jonathantneal/postcss-pseudo-class-any-link +[ci-img]: https://travis-ci.org/jonathantneal/postcss-pseudo-class-any-link.svg +[Grunt PostCSS]: https://github.com/nDmitry/grunt-postcss +[PostCSS]: https://github.com/postcss/postcss +[PostCSS Pseudo-Class Any-Link]: https://github.com/jonathantneal/postcss-pseudo-class-any-link +[proposal]: http://dev.w3.org/csswg/selectors/ From 4031e178f990669a927008584d5bf821ab24d54c Mon Sep 17 00:00:00 2001 From: Jonathan Neal Date: Mon, 15 Jun 2015 09:12:02 -0400 Subject: [PATCH 229/795] Update version Update index.js: use postcss-selector-parser Update package.json: use postcss-selector-parser and bump version Update tests.js: postcss-selector-parser preserves selector separators --- index.js | 36 ++++++++++++++++++++++++++++-------- package.json | 5 +++-- test/test.js | 4 ++-- 3 files changed, 33 insertions(+), 12 deletions(-) diff --git a/index.js b/index.js index cf24648cc4..6f17ba65df 100644 --- a/index.js +++ b/index.js @@ -1,15 +1,35 @@ var postcss = require('postcss'); +var postcssSelectorParser = require('postcss-selector-parser'); module.exports = postcss.plugin('postcss-pseudo-class-any-link', function (opts) { - var match = new RegExp(':' + (opts && opts.prefix ? '-' + opts.prefix + '-' : '') + 'any-link\\b', 'g'); + var pseudoValue = ':' + (opts && opts.prefix ? '-' + opts.prefix + '-' : '') + 'any-link'; + var pseudoFallbackValues = [':link', ':visited']; + + function eachRule(rule) { + rule.selector = postcssSelectorParser(function (selectors) { + selectors.each(function (selector, index) { + var originalIndex = index; + + pseudoFallbackValues.forEach(function (pseudoFallbackValue) { + var clone = selector.clone(); + + clone.eachPseudo(function (pseudo) { + if (pseudo.value === pseudoValue) { + pseudo.value = pseudoFallbackValue; + + selectors.nodes.splice(++index, 0, clone); + } + }); + }); + + if (originalIndex !== index) { + selector.removeSelf(); + } + }); + }).process(rule.selector).result; + } return function (css) { - css.eachRule(function (rule) { - if (match.test(rule.selector)) { - rule.selector = ['link', 'visited'].map(function (replacement) { - return rule.selector.replace(match, ':' + replacement); - }).join(', '); - } - }); + css.eachRule(eachRule); }; }); diff --git a/package.json b/package.json index 9e73ca5d27..56ba8f8b6c 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "postcss-pseudo-class-any-link", - "version": "0.1.0", + "version": "0.2.0", "description": "Use the proposed :any-link pseudo-class in CSS", "keywords": ["postcss", "css", "postcss-plugin", "link", "visited", "any-link", "a", "area", "hyperlink", "href"], "author": "Jonathan Neal ", @@ -20,7 +20,8 @@ "chai": "^2.3.0", "gulp": "^3.8.11", "gulp-eslint": "^0.12.0", - "gulp-mocha": "^2.0.1" + "gulp-mocha": "^2.0.1", + "postcss-selector-parser": "^1.0.0" }, "scripts": { "test": "gulp" diff --git a/test/test.js b/test/test.js index 2bbd4326d4..ae93d07942 100644 --- a/test/test.js +++ b/test/test.js @@ -15,7 +15,7 @@ var test = function (input, output, opts, done) { describe('postcss-pseudo-class-any-link', function () { it(':any-link transforms to :link and :visited', function (done) { - test('ul a:any-link > span { background: yellow; }', 'ul a:link > span, ul a:visited > span { background: yellow; }', {}, done); + test('ul a:any-link > span { background: yellow; }', 'ul a:link > span,ul a:visited > span { background: yellow; }', {}, done); }); it(':any-link remains :any-link { prefix: "foo" }', function (done) { @@ -25,7 +25,7 @@ describe('postcss-pseudo-class-any-link', function () { }); it(':-foo-any-link transforms to :link and :visited { prefix: "foo" }', function (done) { - test('ul a:-foo-any-link > span { background: yellow; }', 'ul a:link > span, ul a:visited > span { background: yellow; }', { + test('ul a:-foo-any-link > span { background: yellow; }', 'ul a:link > span,ul a:visited > span { background: yellow; }', { prefix: 'foo' }, done); }); From 60c06fc12c00b038669a127613f8891e6b0dffab Mon Sep 17 00:00:00 2001 From: Jonathan Neal Date: Mon, 15 Jun 2015 09:25:03 -0400 Subject: [PATCH 230/795] Update README.md Update wording in rationale. Update description of alternatives --- README.md | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 0ec0cee0b1..bd5f97b045 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@ [PostCSS Pseudo-Class Any-Link] is a [PostCSS] plugin that allows you to use the proposed [`:any-link`] pseudo-class in CSS. -`:any-link` simplifies selectors targeting links, since the naming of `:link` is misleading; it specifically means unvisited links only, rather than all links. +`:any-link` simplifies selectors targeting links, as the naming of `:link` is misleading; it specifically means unvisited links only, rather than all links. ```css /* before */ @@ -81,18 +81,20 @@ grunt.initConfig({ ### Alternatives +Here are a few other ways to simulate the effect of [PostCSS Pseudo-Class Any-Link]. + ```css -/* Using @custom-selector; supported nowhere yet */ +/* Use @custom-selector; supported nowhere yet */ @custom-selector :--any-link :link, :visited; :--any-link { /* ... */ } -/* Using :matches; supported in Firefox 4+, Chrome 12+, Opera 15+, Safari 5.1+ */ +/* Use :matches; supported in Firefox 4+, Chrome 12+, Opera 15+, Safari 5.1+ */ :matches(:link, :visited) { /* ... */ } -/* Using :link and :visited; supported everywhere */ +/* Use :link and :visited; supported everywhere */ :link, :visited { /* ... */ } ``` From a398e0d39ece7b34df96ab7ceecaf0f2d693e4cd Mon Sep 17 00:00:00 2001 From: Maxime Thirouin Date: Tue, 16 Jun 2015 00:12:24 +0200 Subject: [PATCH 231/795] Fix spec link --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index bd5f97b045..1c1b68ddfa 100644 --- a/README.md +++ b/README.md @@ -99,7 +99,7 @@ Here are a few other ways to simulate the effect of [PostCSS Pseudo-Class Any-Li :link, :visited { /* ... */ } ``` -[`:any-link`]: http://http://dev.w3.org/csswg/selectors/#any-link-pseudo +[`:any-link`]: http://dev.w3.org/csswg/selectors/#any-link-pseudo [`:link`]: http://dev.w3.org/csswg/selectors/#link-pseudo [`:visited`]: http://dev.w3.org/csswg/selectors/#visited-pseudo [ci]: https://travis-ci.org/jonathantneal/postcss-pseudo-class-any-link From cee7e7c3f4bcd819c8770b6d2319ee47e789b5e1 Mon Sep 17 00:00:00 2001 From: Maxime Thirouin Date: Tue, 16 Jun 2015 00:28:18 +0200 Subject: [PATCH 232/795] postcss-selector-parser is a dependency, not a dev dependency --- package.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/package.json b/package.json index 56ba8f8b6c..b398e3b731 100644 --- a/package.json +++ b/package.json @@ -14,14 +14,14 @@ "url": "https://github.com/jonathantneal/postcss-pseudo-class-any-link.git" }, "dependencies": { - "postcss": "^4.1.9" + "postcss": "^4.1.9", + "postcss-selector-parser": "^1.0.0" }, "devDependencies": { "chai": "^2.3.0", "gulp": "^3.8.11", "gulp-eslint": "^0.12.0", - "gulp-mocha": "^2.0.1", - "postcss-selector-parser": "^1.0.0" + "gulp-mocha": "^2.0.1" }, "scripts": { "test": "gulp" From 779e044fe0ddddbd4bb058de08031ae823752f18 Mon Sep 17 00:00:00 2001 From: Maxime Thirouin Date: Tue, 16 Jun 2015 00:34:05 +0200 Subject: [PATCH 233/795] 0.2.1 --- CHANGELOG.md | 8 ++++++++ package.json | 2 +- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index abaa1d5f2a..0b80fcd3fc 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,11 @@ +## 0.2.1 (2015-06-16) + +- Fixed: postcss-selector-parser is included as a dependency + +## 0.2.0 (2015-06-15) + +- Changed: use postcss-selector-parser + ## 0.1.1 (2015-06-14) Initial release diff --git a/package.json b/package.json index b398e3b731..3f6ff7717b 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "postcss-pseudo-class-any-link", - "version": "0.2.0", + "version": "0.2.1", "description": "Use the proposed :any-link pseudo-class in CSS", "keywords": ["postcss", "css", "postcss-plugin", "link", "visited", "any-link", "a", "area", "hyperlink", "href"], "author": "Jonathan Neal ", From 5684177a527724a174c5c35a6bd42704942aba5d Mon Sep 17 00:00:00 2001 From: Jonathan Neal Date: Mon, 15 Jun 2015 23:40:12 -0400 Subject: [PATCH 234/795] Update plugin Added: Support for complex uses Added: Code documentation Changed: Coding conventions --- .eslintrc | 2 -- index.js | 62 +++++++++++++++++++++++++++++++++------------------- test/test.js | 40 ++++++++++++++++++++++++++++----- 3 files changed, 73 insertions(+), 31 deletions(-) diff --git a/.eslintrc b/.eslintrc index 1031b9da3c..45b5afc50c 100644 --- a/.eslintrc +++ b/.eslintrc @@ -4,11 +4,9 @@ "no-underscore-dangle": [0], "no-reserved-keys": [2], "no-multi-spaces": [0], - "no-extra-parens": [2], "no-unused-vars": [2], "no-loop-func": [0], "key-spacing": [0], - "max-len": [2], "strict": [0], "indent": [1, "tab"], "quotes": [2, "single", "avoid-escape"], diff --git a/index.js b/index.js index 6f17ba65df..36bf7896aa 100644 --- a/index.js +++ b/index.js @@ -2,34 +2,50 @@ var postcss = require('postcss'); var postcssSelectorParser = require('postcss-selector-parser'); module.exports = postcss.plugin('postcss-pseudo-class-any-link', function (opts) { - var pseudoValue = ':' + (opts && opts.prefix ? '-' + opts.prefix + '-' : '') + 'any-link'; - var pseudoFallbackValues = [':link', ':visited']; + // cache the any-link value + var valueAnyLink = ':' + (opts && opts.prefix ? '-' + opts.prefix + '-' : '') + 'any-link'; - function eachRule(rule) { - rule.selector = postcssSelectorParser(function (selectors) { - selectors.each(function (selector, index) { - var originalIndex = index; + return function (css) { + // for each rule + css.eachRule(function (rule) { + // update the selector + rule.selector = postcssSelectorParser(function (selectors) { + // cache variables + var node; + var nodeIndex; + var selector; + var selectorLink; + var selectorVisited; - pseudoFallbackValues.forEach(function (pseudoFallbackValue) { - var clone = selector.clone(); + // cache the selector index + var selectorIndex = -1; - clone.eachPseudo(function (pseudo) { - if (pseudo.value === pseudoValue) { - pseudo.value = pseudoFallbackValue; + // for each selector + while ((selector = selectors.nodes[++selectorIndex])) { + // reset the node index + nodeIndex = -1; - selectors.nodes.splice(++index, 0, clone); - } - }); - }); + // for each node + while ((node = selector.nodes[++nodeIndex])) { + // if the node value matches the any-link value + if (node.value === valueAnyLink) { + // clone the selector + selectorLink = selector.clone(); + selectorVisited = selector.clone(); - if (originalIndex !== index) { - selector.removeSelf(); - } - }); - }).process(rule.selector).result; - } + // update the matching clone values + selectorLink.nodes[nodeIndex].value = ':link'; + selectorVisited.nodes[nodeIndex].value = ':visited'; - return function (css) { - css.eachRule(eachRule); + // replace the selector with the clones and roll back the selector index + selectors.nodes.splice(selectorIndex--, 1, selectorLink, selectorVisited); + + // stop updating the selector + break; + } + } + } + }).process(rule.selector).result; + }); }; }); diff --git a/test/test.js b/test/test.js index ae93d07942..a0d1b78585 100644 --- a/test/test.js +++ b/test/test.js @@ -14,6 +14,40 @@ var test = function (input, output, opts, done) { }; describe('postcss-pseudo-class-any-link', function () { + // standard tests + it(':any-link', function (done) { + test(':any-link { background: blue; }', ':link,:visited { background: blue; }', {}, done); + }); + + it(':any-link, ul a:any-link > span', function (done) { + test(':any-link, ul a:any-link > span { background: blue; }', ':link,:visited, ul a:link > span, ul a:visited > span { background: blue; }', {}, done); + }); + + it(':any-link :any-link', function (done) { + test(':any-link :any-link { background: blue; }', ':link :link,:link :visited,:visited :link,:visited :visited { background: blue; }', {}, done); + }); + + // custom prefix tests + it(':any-link (with "foo" prefix)', function (done) { + test(':any-link { background: blue; }', ':any-link { background: blue; }', { prefix: 'foo' }, done); + }); + + it(':-foo-any-link (with no prefix)', function (done) { + test(':-foo-any-link { background: blue; }', ':-foo-any-link { background: blue; }', {}, done); + }); + + it(':-foo-any-link (with "foo" prefix)', function (done) { + test(':-foo-any-link { background: blue; }', ':link,:visited { background: blue; }', { prefix: 'foo' }, done); + }); + + it(':-foo-any-link, ul a:-foo-any-link > span (with "foo" prefix)', function (done) { + test(':-foo-any-link, ul a:-foo-any-link > span { background: blue; }', ':link,:visited, ul a:link > span, ul a:visited > span { background: blue; }', { prefix: 'foo' }, done); + }); + + it(':-foo-any-link :-foo-any-link (with "foo" prefix)', function (done) { + test(':-foo-any-link :-foo-any-link { background: blue; }', ':link :link,:link :visited,:visited :link,:visited :visited { background: blue; }', { prefix: 'foo' }, done); + }); + it(':any-link transforms to :link and :visited', function (done) { test('ul a:any-link > span { background: yellow; }', 'ul a:link > span,ul a:visited > span { background: yellow; }', {}, done); }); @@ -23,10 +57,4 @@ describe('postcss-pseudo-class-any-link', function () { prefix: 'foo' }, done); }); - - it(':-foo-any-link transforms to :link and :visited { prefix: "foo" }', function (done) { - test('ul a:-foo-any-link > span { background: yellow; }', 'ul a:link > span,ul a:visited > span { background: yellow; }', { - prefix: 'foo' - }, done); - }); }); From 71472948206e164f679f55bb2e224b29feb948b2 Mon Sep 17 00:00:00 2001 From: Jonathan Neal Date: Mon, 15 Jun 2015 23:41:15 -0400 Subject: [PATCH 235/795] 0.3.0 --- CHANGELOG.md | 6 ++++++ package.json | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0b80fcd3fc..7c4a795729 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,9 @@ +## 0.3.0 (2015-06-16) + +- Added: Support for complex uses +- Added: Code documentation +- Changed: Coding conventions + ## 0.2.1 (2015-06-16) - Fixed: postcss-selector-parser is included as a dependency diff --git a/package.json b/package.json index 3f6ff7717b..35703d07bf 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "postcss-pseudo-class-any-link", - "version": "0.2.1", + "version": "0.3.0", "description": "Use the proposed :any-link pseudo-class in CSS", "keywords": ["postcss", "css", "postcss-plugin", "link", "visited", "any-link", "a", "area", "hyperlink", "href"], "author": "Jonathan Neal ", From 2cfd6148ee9dcf06d96166eeb16c912624bcc2bf Mon Sep 17 00:00:00 2001 From: Maxime Thirouin Date: Tue, 16 Jun 2015 08:14:28 +0200 Subject: [PATCH 236/795] Bump eslint --- .eslintrc | 30 ++++++++++++++++++++---------- package.json | 4 ++-- 2 files changed, 22 insertions(+), 12 deletions(-) diff --git a/.eslintrc b/.eslintrc index 98388d0232..c8a232b7da 100644 --- a/.eslintrc +++ b/.eslintrc @@ -10,18 +10,28 @@ env: browser: true node: true -# 0: off, 1: warning, 2: error rules: - # semicolons are useless - semi: [2, "never"] - + indent: [2, 2] # 2 spaces indentation + max-len: [2, 80, 4] quotes: [2, "double"] + semi: [2, "never"] + no-multiple-empty-lines: [2, {"max": 1}] - # 2 spaces indentation - indent: [2, 2] - - # trailing coma are cool for diff + brace-style: [2, "stroustrup"] comma-dangle: [2, "always-multiline"] - - # enforce comma at eol (never before) comma-style: [2, "last"] + computed-property-spacing: [2, "never"] + dot-location: [2, "property"] + + one-var: [2, "never"] + no-var: [2] + prefer-const: [2] + no-bitwise: [2] + + object-shorthand: [2, "methods"] + space-after-keywords: [2, "always"] + space-before-blocks: [2, "always"] + space-before-function-paren: [2, "never"] + space-in-brackets: [2, "never"] + space-in-parens: [2, "never"] + spaced-line-comment: [2, "always"] diff --git a/package.json b/package.json index 65d41de7a3..bf38ca658c 100644 --- a/package.json +++ b/package.json @@ -30,9 +30,9 @@ }, "devDependencies": { "babel": "^5.1.13", - "babel-eslint": "^3.0.1", + "babel-eslint": "^3.1.15", "babel-tape-runner": "^1.1.0", - "eslint": "^0.20.0", + "eslint": "^0.23.0", "tape": "^4.0.0" }, "scripts": { From 297488a39bfb3da5c4ca0198941b1e63ed8c18bd Mon Sep 17 00:00:00 2001 From: Maxime Thirouin Date: Tue, 16 Jun 2015 08:15:40 +0200 Subject: [PATCH 237/795] Fixed: spec has been previously misinterpreted and now transform correctly `:not()` level 4 to collapsed level 3 Close #1 --- CHANGELOG.md | 7 +++++++ LICENSE | 2 +- README.md | 8 -------- package.json | 2 +- src/index.js | 25 +++++++++++-------------- test/index.js | 26 +++++++------------------- 6 files changed, 27 insertions(+), 43 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 36d56c8380..67c8c0f3ad 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,10 @@ +# 1.2.0 - 2015-06-13 + +- Fixed: spec has been previously misinterpreted and now transform correctly +`:not()` level 4 to collapsed level 3 +([#1](https://github.com/postcss/postcss-selector-not/issues/1)) +- Removed: `lineBreak` option (useless now) + # 1.1.0 - 2015-06-13 - Added: `lineBreak` option diff --git a/LICENSE b/LICENSE index 8b39b8f151..372f03009a 100755 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,6 @@ The MIT License (MIT) -Copyright (c) 2014 Maxime Thirouin +Copyright (c) 2015 Maxime Thirouin 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 diff --git a/README.md b/README.md index a228b676d5..9c097ca131 100644 --- a/README.md +++ b/README.md @@ -37,14 +37,6 @@ p:not(:first-child), p:not(.special) { } ``` -## Options - -### `lineBreak` - -(default: `false`) - -Allows you to introduce a line break between generated selectors. - --- ## [Changelog](CHANGELOG.md) diff --git a/package.json b/package.json index bf38ca658c..2e654c8c1b 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "postcss-selector-not", - "version": "1.1.0", + "version": "1.2.0", "description": "PostCSS plugin to transform :not() W3C CSS leve 4 pseudo class to :not() CSS level 3 selectors", "keywords": [ "postcss", diff --git a/src/index.js b/src/index.js index e50babbdf4..f8bccd8e9a 100644 --- a/src/index.js +++ b/src/index.js @@ -9,34 +9,31 @@ function explodeSelector(pseudoClass, selector) { const pre = selector.slice(0, position) const matches = balancedMatch("(", ")", selector.slice(position)) const selectors = [] - const bodySelectors = matches.body ? - list + const bodySelectors = matches.body + ? list .comma(matches.body) - .reduce((acc, s) => [...acc, ...explodeSelector(pseudoClass, s)], []) - : [""] - const postSelectors = matches.post ? explodeSelector(pseudoClass, matches.post) : [""] - postSelectors.forEach(postSelector => { - bodySelectors.forEach(bodySelector => { - selectors.push(`${pre}${pseudoClass}(${bodySelector})${postSelector}`) - }) - }) + .map(s => explodeSelector(pseudoClass, s)) + .join(`)${pseudoClass}(`) + : "" + const postSelectors = matches.post + ? explodeSelector(pseudoClass, matches.post) + : "" + selectors.push(`${pre}${pseudoClass}(${bodySelectors})${postSelectors}`) return selectors } - return [selector] + return selector } function explodeSelectors(pseudoClass) { - return (options = {}) => { + return () => { return (css) => { css.eachRule(rule => { if (rule.selector && rule.selector.indexOf(pseudoClass) > -1) { rule.selector = explodeSelector(pseudoClass, rule.selector) - .join("," + (options.lineBreak ? "\n" + rule.before : " ")) } }) } } } - export default postcss.plugin("postcss-selector-not", explodeSelectors(":not")) diff --git a/test/index.js b/test/index.js index 3dbe62bb8a..110a3b12fc 100644 --- a/test/index.js +++ b/test/index.js @@ -22,37 +22,37 @@ tape("postcss-selector-not", t => { t.equal( transform(":not(a, b) {}"), - ":not(a), :not(b) {}", + ":not(a):not(b) {}", "should transform simple :not()" ) t.equal( transform("tag:not(.class, .class2) {}"), - "tag:not(.class), tag:not(.class2) {}", + "tag:not(.class):not(.class2) {}", "should transform directes :not()" ) t.equal( transform("tag :not(tag2, tag3) {}"), - "tag :not(tag2), tag :not(tag3) {}", + "tag :not(tag2):not(tag3) {}", "should transform :not()" ) t.equal( transform("tag :not(tag2, tag3) :not(tag4, tag5) {}"), - "tag :not(tag2) :not(tag4), tag :not(tag3) :not(tag4), tag :not(tag2) :not(tag5), tag :not(tag3) :not(tag5) {}", + "tag :not(tag2):not(tag3) :not(tag4):not(tag5) {}", "should transform mutltiples :not()" ) t.equal( transform("tag :not(tag2 :not(tag4, tag5), tag3) {}"), - "tag :not(tag2 :not(tag4)), tag :not(tag2 :not(tag5)), tag :not(tag3) {}", + "tag :not(tag2 :not(tag4):not(tag5)):not(tag3) {}", "should transform :not() recursively" ) t.equal( transform(".foo:not(:nth-child(-n+2), .bar) {}"), - ".foo:not(:nth-child(-n+2)), .foo:not(.bar) {}", + ".foo:not(:nth-child(-n+2)):not(.bar) {}", "should transform childs with parenthesis" ) @@ -61,21 +61,9 @@ tape("postcss-selector-not", t => { .b, .c ) {}`), - "a:not(.b), a:not(.c) {}", + "a:not(.b):not(.c) {}", "should works with lots of whitespace" ) - t.equal( - transform(".foo:not(:nth-child(-n+2), .bar) {}", {lineBreak: true}), - ".foo:not(:nth-child(-n+2)),\n.foo:not(.bar) {}", - "should add line break if asked too" - ) - - t.equal( - transform(" .foo:not(:nth-child(-n+2), .bar) {}", {lineBreak: true}), - " .foo:not(:nth-child(-n+2)),\n .foo:not(.bar) {}", - "should add line break if asked too, and respect indentation" - ) - t.end() }) From 4ef33271e0926993d3983b5330bdbd235352366a Mon Sep 17 00:00:00 2001 From: Maxime Thirouin Date: Tue, 16 Jun 2015 14:33:58 +0200 Subject: [PATCH 238/795] Fixed: selector was updated as an array, which is wrong. --- CHANGELOG.md | 6 +++++- package.json | 2 +- src/index.js | 5 ++--- 3 files changed, 8 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 67c8c0f3ad..3d246384d2 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,8 @@ -# 1.2.0 - 2015-06-13 +# 1.2.1 - 2015-06-16 + +- Fixed: selector was updated as an array, which is wrong. + +# 1.2.0 - 2015-06-16 - Fixed: spec has been previously misinterpreted and now transform correctly `:not()` level 4 to collapsed level 3 diff --git a/package.json b/package.json index 2e654c8c1b..5ab0d5c926 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "postcss-selector-not", - "version": "1.2.0", + "version": "1.2.1", "description": "PostCSS plugin to transform :not() W3C CSS leve 4 pseudo class to :not() CSS level 3 selectors", "keywords": [ "postcss", diff --git a/src/index.js b/src/index.js index f8bccd8e9a..38a61d5bab 100644 --- a/src/index.js +++ b/src/index.js @@ -8,7 +8,6 @@ function explodeSelector(pseudoClass, selector) { if (selector && position > -1) { const pre = selector.slice(0, position) const matches = balancedMatch("(", ")", selector.slice(position)) - const selectors = [] const bodySelectors = matches.body ? list .comma(matches.body) @@ -18,8 +17,8 @@ function explodeSelector(pseudoClass, selector) { const postSelectors = matches.post ? explodeSelector(pseudoClass, matches.post) : "" - selectors.push(`${pre}${pseudoClass}(${bodySelectors})${postSelectors}`) - return selectors + + return `${pre}${pseudoClass}(${bodySelectors})${postSelectors}` } return selector } From fcd0a36a9f9c9cdc67c3683fae95302d4544816c Mon Sep 17 00:00:00 2001 From: Maxime Thirouin Date: Wed, 17 Jun 2015 08:31:21 +0200 Subject: [PATCH 239/795] Fixed: no more duplicates in generated selector (1.1.1) Close #3 --- .eslintrc | 30 ++++++++++++++++-------- CHANGELOG.md | 5 ++++ package.json | 8 +++---- src/index.js | 63 +++++++++++++++++++++++++++++++++++---------------- test/index.js | 9 ++++++++ 5 files changed, 82 insertions(+), 33 deletions(-) diff --git a/.eslintrc b/.eslintrc index 98388d0232..c8a232b7da 100644 --- a/.eslintrc +++ b/.eslintrc @@ -10,18 +10,28 @@ env: browser: true node: true -# 0: off, 1: warning, 2: error rules: - # semicolons are useless - semi: [2, "never"] - + indent: [2, 2] # 2 spaces indentation + max-len: [2, 80, 4] quotes: [2, "double"] + semi: [2, "never"] + no-multiple-empty-lines: [2, {"max": 1}] - # 2 spaces indentation - indent: [2, 2] - - # trailing coma are cool for diff + brace-style: [2, "stroustrup"] comma-dangle: [2, "always-multiline"] - - # enforce comma at eol (never before) comma-style: [2, "last"] + computed-property-spacing: [2, "never"] + dot-location: [2, "property"] + + one-var: [2, "never"] + no-var: [2] + prefer-const: [2] + no-bitwise: [2] + + object-shorthand: [2, "methods"] + space-after-keywords: [2, "always"] + space-before-blocks: [2, "always"] + space-before-function-paren: [2, "never"] + space-in-brackets: [2, "never"] + space-in-parens: [2, "never"] + spaced-line-comment: [2, "always"] diff --git a/CHANGELOG.md b/CHANGELOG.md index 0893b525c2..c417f891d1 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,8 @@ +# 1.1.1 - 2015-06-17 + +- Fixed: no more duplicates in generated selector +([#3](https://github.com/postcss/postcss-selector-matches/issues/3)) + # 1.1.0 - 2015-06-13 - Added: `lineBreak` option diff --git a/package.json b/package.json index fcf6cdcbf0..ba4487e783 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "postcss-selector-matches", - "version": "1.1.0", + "version": "1.1.1", "description": "PostCSS plugin to transform :matches() W3C CSS pseudo class to more compatible CSS selectors", "keywords": [ "postcss", @@ -29,10 +29,10 @@ "postcss": "^4.1.7" }, "devDependencies": { - "babel": "^5.1.13", - "babel-eslint": "^3.0.1", + "babel": "^5.5.8", + "babel-eslint": "^3.1.15", "babel-tape-runner": "^1.1.0", - "eslint": "^0.20.0", + "eslint": "^0.23.0", "tape": "^4.0.0" }, "scripts": { diff --git a/src/index.js b/src/index.js index 1d16bddb1d..b3fac25532 100644 --- a/src/index.js +++ b/src/index.js @@ -3,24 +3,46 @@ import list from "postcss/lib/list" import balancedMatch from "balanced-match" -function explodeSelector(pseudoClass, selector) { - const position = selector.indexOf(pseudoClass) - if (selector && position > -1) { - const pre = selector.slice(0, position) - const matches = balancedMatch("(", ")", selector.slice(position)) - const selectors = [] - const bodySelectors = matches.body ? - list - .comma(matches.body) - .reduce((acc, s) => [...acc, ...explodeSelector(pseudoClass, s)], []) - : [""] - const postSelectors = matches.post ? explodeSelector(pseudoClass, matches.post) : [""] - postSelectors.forEach(postSelector => { - bodySelectors.forEach(bodySelector => { - selectors.push(pre + bodySelector + postSelector) - }) +function explodeSelector(pseudoClass, selector, options) { + if (selector && selector.indexOf(pseudoClass) > -1) { + let newSelectors = [] + const selectorPart = list.comma(selector) + selectorPart.forEach(part => { + const position = part.indexOf(pseudoClass) + const pre = part.slice(0, position) + const matches = balancedMatch("(", ")", part.slice(position)) + + const bodySelectors = matches.body ? + list + .comma(matches.body) + .reduce((acc, s) => [ + ...acc, + ...explodeSelector(pseudoClass, s, options), + ], []) + : [] + const postSelectors = matches.post + ? explodeSelector(pseudoClass, matches.post, options) + : [] + + let newParts + if (postSelectors.length === 0) { + newParts = bodySelectors.map((s) => pre + s) + } + else { + newParts = [] + postSelectors.forEach(postS => { + bodySelectors.forEach(s => { + newParts.push(pre + s + " " + postS) + }) + }) + } + newSelectors = [ + ...newSelectors, + ...newParts, + ] }) - return selectors + + return newSelectors } return [selector] } @@ -30,7 +52,7 @@ function explodeSelectors(pseudoClass) { return (css) => { css.eachRule(rule => { if (rule.selector && rule.selector.indexOf(pseudoClass) > -1) { - rule.selector = explodeSelector(pseudoClass, rule.selector) + rule.selector = explodeSelector(pseudoClass, rule.selector, options) .join("," + (options.lineBreak ? "\n" + rule.before : " ")) } }) @@ -38,4 +60,7 @@ function explodeSelectors(pseudoClass) { } } -export default postcss.plugin("postcss-selector-matches", explodeSelectors(":matches")) +export default postcss.plugin( + "postcss-selector-matches", + explodeSelectors(":matches") +) diff --git a/test/index.js b/test/index.js index dcca39b7f2..da12ebbc70 100644 --- a/test/index.js +++ b/test/index.js @@ -83,5 +83,14 @@ tape("postcss-selector-matches", t => { "should add line break if asked too, and respect indentation" ) + t.equal( + transform(` +button:matches(:hover, :active), +.button:matches(:hover, :active) {}`), + ` +button:hover, button:active, .button:hover, .button:active {}`, + "should avoid duplicates" + ) + t.end() }) From 2c8f2538088be18c64d66f70f6803cb6ffb28896 Mon Sep 17 00:00:00 2001 From: Maxime Thirouin Date: Wed, 17 Jun 2015 08:45:03 +0200 Subject: [PATCH 240/795] 4.0.0 --- .eslintrc | 28 +++++++------ CHANGELOG.md | 6 ++- README.md | 29 +++++++------- index.js | 23 +++++------ package.json | 2 +- test/index.js | 106 +++++++++++++++++++++++++++++++++++--------------- 6 files changed, 121 insertions(+), 73 deletions(-) diff --git a/.eslintrc b/.eslintrc index db389353cb..da2592a767 100644 --- a/.eslintrc +++ b/.eslintrc @@ -7,20 +7,26 @@ env: browser: true node: true -# 0: off, 1: warning, 2: error rules: - # semicolons are useless - semi: [2, "never"] - + indent: [2, 2] # 2 spaces indentation + max-len: [2, 80, 4] quotes: [2, "double"] + semi: [2, "never"] + no-multiple-empty-lines: [2, {"max": 1}] - # 2 spaces indentation - indent: [2, 2] - - # trailing coma are cool for diff + brace-style: [2, "stroustrup"] comma-dangle: [2, "always-multiline"] - - # enforce comma at eol (never before) comma-style: [2, "last"] + computed-property-spacing: [2, "never"] + dot-location: [2, "property"] + + one-var: [2, "never"] + no-bitwise: [2] - valid-jsdoc: 2 + object-shorthand: [2, "methods"] + space-after-keywords: [2, "always"] + space-before-blocks: [2, "always"] + space-before-function-paren: [2, "never"] + space-in-brackets: [2, "never"] + space-in-parens: [2, "never"] + spaced-line-comment: [2, "always"] diff --git a/CHANGELOG.md b/CHANGELOG.md index fa6561ce9b..86b28097e4 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,8 @@ -# 4.0.0 - Unrelease +# 4.0.0 - 2015-05-17 -- Changed: warning messages are not sent via postcss API (^4.1.0) +- Changed: warning messages are now sent via postcss messages api (^4.1.0) +- Added: automatic custom media `--` prefixing +([#11](https://github.com/postcss/postcss-custom-media/issues/11)) - Added: `preserve` allows you to preserve custom media query defintions - Added: `appendExtensions` allows you (when `preserve` is truthy) to append your extensions as media queries diff --git a/README.md b/README.md index bbc416a3b3..60a89a35b9 100755 --- a/README.md +++ b/README.md @@ -4,7 +4,9 @@ ## Installation - $ npm install postcss-custom-media +```console +$ npm install postcss-custom-media +``` ## Usage @@ -45,28 +47,27 @@ Checkout [tests](test) for more examples. ### Options -#### `extensions` (default: `{}`) +#### `extensions` -Allows you to pass an object to define the `` for each ``. These definitions will override any that exist in the CSS. +(default: `{}`) -#### `preserve` (default: `false`) +Allows you to pass an object to define the `` for each +``. These definitions will override any that exist in the CSS. -Allows you to preserve custom media query definitions in output. +#### `preserve` -#### `appendExtensions` (default: `false`) +(default: `false`) -If `preserve` is set to `true`, allows you to append your extensions at end of your CSS. +Allows you to preserve custom media query definitions in output. ---- +#### `appendExtensions` -## Contributing +(default: `false`) -Work on a branch, install dev-dependencies, respect coding style & run tests before submitting a bug fix or a feature. +**This option only works if `preserve` is truthy**. +Allows you to append your extensions at end of your CSS. - $ git clone https://github.com/postcss/postcss-custom-media.git - $ git checkout -b patch-1 - $ npm install - $ npm test +--- ## [Changelog](CHANGELOG.md) diff --git a/index.js b/index.js index 13bc19ce83..4f7153d876 100755 --- a/index.js +++ b/index.js @@ -1,18 +1,7 @@ -/** - * Module dependencies - */ var postcss = require("postcss") -/** - * Constants. - */ var EXTENSION_RE = /\(\s*(--[\w-]+)\s*\)/g -/** - * Expose the plugin. - */ -module.exports = postcss.plugin("postcss-custom-media", customMedia) - /* * read & replace custom media queries by standard media queries */ @@ -66,7 +55,11 @@ function customMedia(options) { return map[name] } - result.warn("Missing @custom-media definition for '" + name + "'. The entire rule has been removed from the output.", {node: rule}) + result.warn( + "Missing @custom-media definition for '" + name + + "'. The entire rule has been removed from the output.", + {node: rule} + ) toRemove.push(rule) }) }) @@ -88,6 +81,10 @@ function customMedia(options) { } // remove @custom-media - toRemove.forEach(function(rule) { rule.removeSelf() }) + toRemove.forEach(function(rule) { + rule.removeSelf() + }) } } + +module.exports = postcss.plugin("postcss-custom-media", customMedia) diff --git a/package.json b/package.json index 503a9be82f..8d5ad43ad3 100644 --- a/package.json +++ b/package.json @@ -24,7 +24,7 @@ "postcss": "^4.1.4" }, "devDependencies": { - "eslint": "^0.18.0", + "eslint": "^0.23.0", "tape": "^4.0.0" }, "scripts": { diff --git a/test/index.js b/test/index.js index 3e641b73c9..b73efe27d8 100755 --- a/test/index.js +++ b/test/index.js @@ -5,14 +5,20 @@ 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 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 result = postcss().use(plugin(opts)).process(read(postcssOpts.from), postcssOpts) + var result = postcss() + .use(plugin(opts)) + .process(read(postcssOpts.from), postcssOpts) var actual = result.css var expected = read(filename("fixtures/" + name + ".expected")) fs.writeFile(filename("fixtures/" + name + ".actual"), actual) @@ -22,35 +28,71 @@ function compareFixtures(t, name, msg, opts, postcssOpts) { } test("@custom-media", function(t) { - compareFixtures(t, "transform", "should transform custom media") - - compareFixtures(t, "transform-all", "should replaces all extension names") - - var undefinedRes = compareFixtures(t, "undefined", "should remove undefined @media") - t.ok(undefinedRes.warnings()[0].text.match(/Missing @custom-media/), "should send warning to postcss") - - compareFixtures(t, "js-defined", "should transform custom media and override local extensions", { - extensions: { - "--viewport-max-s": "(max-width: 30em)", - "--viewport-min-s": "(min-width: 30.01em)", - }, - }) - - compareFixtures(t, "js-defined", "should transform custom media and override local unprefixed extensions", { - extensions: { - "viewport-max-s": "(max-width: 30em)", - "viewport-min-s": "(min-width: 30.01em)", - }, - }) - - compareFixtures(t, "preserve", "should preserve custom media", {preserve: true}) - - compareFixtures(t, "append", "should append custom media", { - extensions: { - "--viewport-max-s": "(max-width: 30em)", - }, - appendExtensions: true, - }) + compareFixtures( + t, + "transform", + "should transform custom media" + ) + + compareFixtures( + t, + "transform-all", + "should replaces all extension names" + ) + + var undefinedRes = compareFixtures( + t, + "undefined", + "should remove undefined @media" + ) + + t.ok( + undefinedRes.warnings()[0].text.match(/Missing @custom-media/), + "should send warning to postcss" + ) + + compareFixtures( + t, + "js-defined", + "should transform custom media and override local extensions", + { + extensions: { + "--viewport-max-s": "(max-width: 30em)", + "--viewport-min-s": "(min-width: 30.01em)", + }, + } + ) + + compareFixtures( + t, + "js-defined", + "should transform custom media and override local unprefixed extensions", + { + extensions: { + "viewport-max-s": "(max-width: 30em)", + "viewport-min-s": "(min-width: 30.01em)", + }, + } + ) + + compareFixtures( + t, + "preserve", + "should preserve custom media", + {preserve: true} + ) + + compareFixtures( + t, + "append", + "should append custom media", + { + extensions: { + "--viewport-max-s": "(max-width: 30em)", + }, + appendExtensions: true, + } + ) t.end() }) From 442612b5f294cdfa1a4d4f9d9f974c7d9a5d5fac Mon Sep 17 00:00:00 2001 From: Glen Huang Date: Wed, 8 Apr 2015 17:15:24 +0800 Subject: [PATCH 241/795] Not using object-assign --- index.js | 18 ++++++++++-------- package.json | 1 - 2 files changed, 10 insertions(+), 9 deletions(-) diff --git a/index.js b/index.js index 576b6e5b3f..79065a16b0 100755 --- a/index.js +++ b/index.js @@ -2,7 +2,6 @@ * Module dependencies. */ -var assign = require("object-assign") var postcss = require("postcss") var balanced = require("balanced-match") @@ -120,13 +119,16 @@ function resolveValue(value, variables, result, decl) { module.exports = postcss.plugin("postcss-custom-properties", function(options) { return function(style, result) { options = options || {} - var variables = assign({}, options.variables || {}) - Object.keys(variables).forEach(function(name) { - if (name.slice(0, 2) !== "--") { - variables["--" + name] = variables[name] - delete variables[name] - } - }) + var variables = {} + if (options.variables) { + Object.keys(options.variables).forEach(function(name) { + var val = options.variables[name] + if (name.slice(0, 2) !== "--") { + name = "--" + name + } + variables[name] = val + }) + } var strict = options.strict === undefined ? true : options.strict var appendVariables = options.appendVariables var preserve = options.preserve diff --git a/package.json b/package.json index c81045f38d..8819739422 100644 --- a/package.json +++ b/package.json @@ -23,7 +23,6 @@ ], "dependencies": { "balanced-match": "~0.1.0", - "object-assign": "^2.0.0", "postcss": "^4.1.4" }, "devDependencies": { From df43c890646e2d878f1a002e8d1d2d4ea7060f4b Mon Sep 17 00:00:00 2001 From: Glen Huang Date: Thu, 9 Apr 2015 12:40:03 +0800 Subject: [PATCH 242/795] Update README.md Fix typo --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index e382c1fc58..1f023b0544 100755 --- a/README.md +++ b/README.md @@ -83,7 +83,7 @@ variables in your codebase. ### `appendVariables` (default: `false`) -If `preserve` is set to `true` (or `"computed"`), allows you to append your variables at then of your CSS. +If `preserve` is set to `true` (or `"computed"`), allows you to append your variables at the end of your CSS. --- From ade56a08ab38fda217f208f802582a457365c164 Mon Sep 17 00:00:00 2001 From: Glen Huang Date: Thu, 9 Apr 2015 13:14:14 +0800 Subject: [PATCH 243/795] Update CHANGELOG.md Fix typo. --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 76e991b81b..1f7dc91d0b 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,7 +6,7 @@ Messages are not outputted by default to console anymore. # 3.3.0 - 2015-04-0 - Added: `preserve` now support `"computed"` so only preserve resolved custom properties (see new option below) -- Added: `appendVariables` allows you (when `preserve` is trulthy) to append your variables as custom properties +- Added: `appendVariables` allows you (when `preserve` is truthy) to append your variables as custom properties - Added: `strict: false` allows your to avoid too many fallbacks added in your CSS. # 3.2.0 - 2015-03-31 From 78ca1e36445265d14abf9f56d070dbe12721f12b Mon Sep 17 00:00:00 2001 From: Maxime Thirouin Date: Thu, 9 Apr 2015 08:12:06 +0200 Subject: [PATCH 244/795] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 1f023b0544..9999e1ffd8 100755 --- a/README.md +++ b/README.md @@ -81,7 +81,7 @@ Allows you to pass an object of variables for `:root`. These definitions will ov The keys are automatically prefixed with the CSS `--` to make it easier to share variables in your codebase. -### `appendVariables` (default: `false`) +#### `appendVariables` (default: `false`) If `preserve` is set to `true` (or `"computed"`), allows you to append your variables at the end of your CSS. From 5b22a25af110e7bd322398c69332e2629cdd9f94 Mon Sep 17 00:00:00 2001 From: Glen Huang Date: Thu, 9 Apr 2015 16:27:22 +0800 Subject: [PATCH 245/795] Convert js defined variables to strings --- index.js | 2 +- test/fixtures/js-defined.css | 1 + test/fixtures/js-defined.expected.css | 1 + test/index.js | 1 + 4 files changed, 4 insertions(+), 1 deletion(-) diff --git a/index.js b/index.js index 79065a16b0..79f8b027fb 100755 --- a/index.js +++ b/index.js @@ -126,7 +126,7 @@ module.exports = postcss.plugin("postcss-custom-properties", function(options) { if (name.slice(0, 2) !== "--") { name = "--" + name } - variables[name] = val + variables[name] = String(val) }) } var strict = options.strict === undefined ? true : options.strict diff --git a/test/fixtures/js-defined.css b/test/fixtures/js-defined.css index 0a90407c68..8c4fedc728 100755 --- a/test/fixtures/js-defined.css +++ b/test/fixtures/js-defined.css @@ -9,4 +9,5 @@ div { p: var(--test-three); p: var(--test-varception); p: var(--test-jsception); + p: var(--test-num); } diff --git a/test/fixtures/js-defined.expected.css b/test/fixtures/js-defined.expected.css index 79a663e0b0..d043e0bf13 100755 --- a/test/fixtures/js-defined.expected.css +++ b/test/fixtures/js-defined.expected.css @@ -4,4 +4,5 @@ div { p: js-three; p: js-one; p: js-one; + p: 1; } diff --git a/test/index.js b/test/index.js index 46d5841db2..fe44c19261 100755 --- a/test/index.js +++ b/test/index.js @@ -62,6 +62,7 @@ test("accepts variables defined from JavaScript, and overrides local definitions "--test-three": "js-three", "--test-varception": "var(--test-one)", "--test-jsception": "var(--test-varception)", + "--test-num": 1, }, }) t.end() From 9059a509c3864881377545c7a420a88eda0c67c4 Mon Sep 17 00:00:00 2001 From: Maxime Thirouin Date: Tue, 5 May 2015 15:22:32 +0200 Subject: [PATCH 246/795] Add a note about postcss-css-variables --- README.md | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 9999e1ffd8..48cf32a274 100755 --- a/README.md +++ b/README.md @@ -2,10 +2,14 @@ > [PostCSS](https://github.com/postcss/postcss) plugin to transform [W3C CSS Custom Properties for cascading variables](http://www.w3.org/TR/css-variables/) syntax to more compatible CSS. -**N.B.** The transformation _is not complete_. It currently just aims to provide a future-proof way of using a **limited subset (to top-level `:root` selector)** of the features provided by native CSS custom properties. -Read [#1](https://github.com/postcss/postcss-custom-properties/issues/1) & [#9](https://github.com/postcss/postcss-custom-properties/issues/9) to know why this limitation exists. +**N.B.** The transformation _is not complete and **cannot be** (dynamic variables based on custom properties relies on the DOM tree)_. It currently just aims to provide a future-proof way of using a **limited subset (to top-level `:root` selector)** of the features provided by native CSS custom properties. +_Read [#1](https://github.com/postcss/postcss-custom-properties/issues/1) & [#9](https://github.com/postcss/postcss-custom-properties/issues/9) to know why this limitation exists._ -Works great with [postcss-calc](https://github.com/postcss/postcss-calc). +_If you are looking for a full support of CSS custom properties, please follow [the opened issue for runtime support](https://github.com/postcss/postcss-custom-properties/issues/32)._ + +**N.B.²** If you are wondering why there is a different plugin ([`postcss-css-variables`](https://github.com/MadLittleMods/postcss-css-variables)) that claims to do the more than this plugin be sure to understand the explanation above about limitation. You should also check the [issues of this plugin](https://github.com/MadLittleMods/postcss-css-variables/issues?q=is%3Aissue). + +_This plugin works great with [postcss-calc](https://github.com/postcss/postcss-calc)._ ## Installation From f85a59abab062724debf0efe313dd9882dce9003 Mon Sep 17 00:00:00 2001 From: Maxime Thirouin Date: Tue, 5 May 2015 15:30:48 +0200 Subject: [PATCH 247/795] typo --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 48cf32a274..1795139a8c 100755 --- a/README.md +++ b/README.md @@ -7,7 +7,7 @@ _Read [#1](https://github.com/postcss/postcss-custom-properties/issues/1) & [#9] _If you are looking for a full support of CSS custom properties, please follow [the opened issue for runtime support](https://github.com/postcss/postcss-custom-properties/issues/32)._ -**N.B.²** If you are wondering why there is a different plugin ([`postcss-css-variables`](https://github.com/MadLittleMods/postcss-css-variables)) that claims to do the more than this plugin be sure to understand the explanation above about limitation. You should also check the [issues of this plugin](https://github.com/MadLittleMods/postcss-css-variables/issues?q=is%3Aissue). +**N.B.²** If you are wondering why there is a different plugin ([`postcss-css-variables`](https://github.com/MadLittleMods/postcss-css-variables)) that claims to do more than this plugin, be sure to understand the explanation above about limitation. You should also check the [issues of this plugin](https://github.com/MadLittleMods/postcss-css-variables/issues?q=is%3Aissue). _This plugin works great with [postcss-calc](https://github.com/postcss/postcss-calc)._ From 996d39aaa0610b2519ba6f400021967e0c64c874 Mon Sep 17 00:00:00 2001 From: Maxime Thirouin Date: Sat, 9 May 2015 05:49:11 +0200 Subject: [PATCH 248/795] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 1795139a8c..636301f626 100755 --- a/README.md +++ b/README.md @@ -7,7 +7,7 @@ _Read [#1](https://github.com/postcss/postcss-custom-properties/issues/1) & [#9] _If you are looking for a full support of CSS custom properties, please follow [the opened issue for runtime support](https://github.com/postcss/postcss-custom-properties/issues/32)._ -**N.B.²** If you are wondering why there is a different plugin ([`postcss-css-variables`](https://github.com/MadLittleMods/postcss-css-variables)) that claims to do more than this plugin, be sure to understand the explanation above about limitation. You should also check the [issues of this plugin](https://github.com/MadLittleMods/postcss-css-variables/issues?q=is%3Aissue). +**N.B.²** If you are wondering why there is a different plugin ([`postcss-css-variables`](https://github.com/MadLittleMods/postcss-css-variables)) that claims to do more than this plugin, be sure to understand the explanation above about limitation. This plugins have a behavior that is not reflecting the specifications. [You should check some (closed) issues of this plugin](https://github.com/MadLittleMods/postcss-css-variables/issues?utf8=%E2%9C%93&q=is%3Aissue+is%3Aclosed+-label%3Ainvalid+author%3AMoOx+). _This plugin works great with [postcss-calc](https://github.com/postcss/postcss-calc)._ From b843b93f6e4eca396c34872329da21c131e31d2f Mon Sep 17 00:00:00 2001 From: Maxime Thirouin Date: Wed, 17 Jun 2015 09:18:34 +0200 Subject: [PATCH 249/795] 4.0.0 --- .eslintrc | 28 ++++++----- .jscsrc | 130 -------------------------------------------------- .jshintrc | 9 ---- CHANGELOG.md | 9 ++-- index.js | 43 ++++++++++++----- package.json | 2 +- test/index.js | 120 ++++++++++++++++++++++++++++++---------------- 7 files changed, 131 insertions(+), 210 deletions(-) delete mode 100644 .jscsrc delete mode 100644 .jshintrc diff --git a/.eslintrc b/.eslintrc index db389353cb..da2592a767 100644 --- a/.eslintrc +++ b/.eslintrc @@ -7,20 +7,26 @@ env: browser: true node: true -# 0: off, 1: warning, 2: error rules: - # semicolons are useless - semi: [2, "never"] - + indent: [2, 2] # 2 spaces indentation + max-len: [2, 80, 4] quotes: [2, "double"] + semi: [2, "never"] + no-multiple-empty-lines: [2, {"max": 1}] - # 2 spaces indentation - indent: [2, 2] - - # trailing coma are cool for diff + brace-style: [2, "stroustrup"] comma-dangle: [2, "always-multiline"] - - # enforce comma at eol (never before) comma-style: [2, "last"] + computed-property-spacing: [2, "never"] + dot-location: [2, "property"] + + one-var: [2, "never"] + no-bitwise: [2] - valid-jsdoc: 2 + object-shorthand: [2, "methods"] + space-after-keywords: [2, "always"] + space-before-blocks: [2, "always"] + space-before-function-paren: [2, "never"] + space-in-brackets: [2, "never"] + space-in-parens: [2, "never"] + spaced-line-comment: [2, "always"] diff --git a/.jscsrc b/.jscsrc deleted file mode 100644 index 29720b3791..0000000000 --- a/.jscsrc +++ /dev/null @@ -1,130 +0,0 @@ -{ - "excludeFiles": [ - "node_modules/**" - ], - "fileExtensions": [ - ".js" - ], - "requireCurlyBraces": [ - "if", - "else", - "for", - "while", - "do", - "try", - "catch" - ], - "requireSpaceAfterKeywords": [ - "if", - "else", - "for", - "while", - "do", - "switch", - "return", - "try", - "catch" - ], - "requireSpaceBeforeBlockStatements": true, - "requireParenthesesAroundIIFE": true, - "requireSpacesInConditionalExpression": { - "afterTest": true, - "beforeConsequent": true, - "afterConsequent": true, - "beforeAlternate": true - }, - "requireSpacesInFunctionExpression": { - "beforeOpeningCurlyBrace": true - }, - "disallowSpacesInFunctionExpression": { - "beforeOpeningRoundBrace": true - }, - "disallowMultipleVarDecl": true, - "requireBlocksOnNewline": 1, - "disallowPaddingNewlinesInBlocks": true, - "disallowEmptyBlocks": true, - "disallowSpacesInsideObjectBrackets": true, - "disallowSpacesInsideArrayBrackets": true, - "disallowSpacesInsideParentheses": true, - "disallowQuotedKeysInObjects": "allButReserved", - "disallowSpaceAfterObjectKeys": true, - "requireCommaBeforeLineBreak": true, - "requireOperatorBeforeLineBreak": [ - "?", - "+", - "-", - "/", - "*", - "=", - "==", - "===", - "!=", - "!==", - ">", - ">=", - "<", - "<=" - ], - "disallowSpaceAfterPrefixUnaryOperators": [ - "++", - "--", - "+", - "-", - "~", - "!" - ], - "disallowSpaceBeforePostfixUnaryOperators": [ - "++", - "--" - ], - "requireSpaceBeforeBinaryOperators": [ - "+", - "-", - "/", - "*", - "=", - "==", - "===", - "!=", - "!==" - ], - "requireSpaceAfterBinaryOperators": [ - "+", - "-", - "/", - "*", - "=", - "==", - "===", - "!=", - "!==" - ], - "disallowImplicitTypeConversion": [ - "numeric", - "boolean", - "binary", - "string" - ], - "requireCamelCaseOrUpperCaseIdentifiers": "ignoreProperties", - "disallowKeywords": [ - "with" - ], - "disallowMultipleLineStrings": true, - "validateQuoteMarks": "\"", - "validateIndentation": 2, - "disallowMixedSpacesAndTabs": true, - "disallowTrailingWhitespace": true, - "requireKeywordsOnNewLine": [ - "else" - ], - "requireLineFeedAtFileEnd": true, - "requireCapitalizedConstructors": true, - "safeContextKeyword": "that", - "requireDotNotation": true, - "validateJSDoc": { - "checkParamNames": true, - "checkRedundantParams": true, - "requireParamTypes": true - }, - "requireSpaceAfterLineComment": true -} diff --git a/.jshintrc b/.jshintrc deleted file mode 100644 index 9f268f76ca..0000000000 --- a/.jshintrc +++ /dev/null @@ -1,9 +0,0 @@ -{ - "newcap": false, - "undef": true, - "unused": true, - "asi": true, - "esnext": true, - "node": true, - "browser": true -} diff --git a/CHANGELOG.md b/CHANGELOG.md index 1f7dc91d0b..2ad2b552d0 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,9 +1,8 @@ -# 4.0.0 - Unreleased +# 4.0.0 - 2015-06-17 -- Changed: upgade to postcss ^4.1.x -- Changed: messages and exceptions are now using postcss API. -Messages are not outputted by default to console anymore. -# 3.3.0 - 2015-04-0 +- Changed: messages and exceptions are now sent using postcss message API. + +# 3.3.0 - 2015-04-08 - Added: `preserve` now support `"computed"` so only preserve resolved custom properties (see new option below) - Added: `appendVariables` allows you (when `preserve` is truthy) to append your variables as custom properties diff --git a/index.js b/index.js index 79f8b027fb..8205c0b125 100755 --- a/index.js +++ b/index.js @@ -11,7 +11,8 @@ var balanced = require("balanced-match") var VAR_PROP_IDENTIFIER = "--" var VAR_FUNC_IDENTIFIER = "var" -var RE_VAR = /([\w-]+)(?:\s*,\s*)?(.*)?/ // matches `name[, fallback]`, captures "name" and "fallback" +// matches `name[, fallback]`, captures "name" and "fallback" +var RE_VAR = /([\w-]+)(?:\s*,\s*)?(.*)?/ /** * Resolve CSS variables in a value @@ -22,7 +23,8 @@ var RE_VAR = /([\w-]+)(?:\s*,\s*)?(.*)?/ // matches `name[, fallback]`, captures * * var(name[, fallback]) * - * @param {String} value A property value known to contain CSS variable functions + * @param {String} value A property value known to contain CSS variable + * functions * @param {Object} variables A map of variable names and values * @param {Object} source source object of the declaration containing the rule * @return {String} A property value with all CSS variables substituted. @@ -51,11 +53,19 @@ function resolveValue(value, variables, result, decl) { var post // undefined and without fallback, just keep original value if (!variable && !fallback) { - result.warn("variable '" + name + "' is undefined and used without a fallback", {node: decl}) - post = matches.post ? resolveValue(matches.post, variables, result, decl) : [""] + result.warn( + "variable '" + name + "' is undefined and used without a fallback", + {node: decl} + ) + post = matches.post + ? resolveValue(matches.post, variables, result, decl) + : [""] // resolve the end of the expression post.forEach(function(afterValue) { - results.push(value.slice(0, start) + VAR_FUNC_IDENTIFIER + "(" + name + ")" + afterValue) + results.push( + value.slice(0, start) + + VAR_FUNC_IDENTIFIER + "(" + name + ")" + afterValue + ) }) return } @@ -65,7 +75,9 @@ function resolveValue(value, variables, result, decl) { // resolve fallback values fallback = resolveValue(fallback, variables, result, decl) // resolve the end of the expression before the rest - post = matches.post ? resolveValue(matches.post, variables, result, decl) : [""] + post = matches.post + ? resolveValue(matches.post, variables, result, decl) + : [""] fallback.forEach(function(fbValue) { post.forEach(function(afterValue) { results.push(value.slice(0, start) + fbValue + afterValue) @@ -101,7 +113,9 @@ function resolveValue(value, variables, result, decl) { return } // resolve the end of the expression - post = matches.post ? resolveValue(matches.post, variables, result, decl) : [""] + post = matches.post + ? resolveValue(matches.post, variables, result, decl) + : [""] variable.value.forEach(function(replacementValue) { post.forEach(function(afterValue) { results.push(value.slice(0, start) + replacementValue + afterValue) @@ -140,14 +154,17 @@ module.exports = postcss.plugin("postcss-custom-properties", function(options) { var toRemove = [] // only variables declared for `:root` are supported for now - if (rule.selectors.length !== 1 || rule.selectors[0] !== ":root" || rule.parent.type !== "root") { + if ( + rule.selectors.length !== 1 || + rule.selectors[0] !== ":root" || + rule.parent.type !== "root" + ) { rule.each(function(decl) { var prop = decl.prop if (prop && prop.indexOf(VAR_PROP_IDENTIFIER) === 0) { result.warn( - "Custom property ignored: not scoped to the top-level :root element (" + - rule.selectors + - " { ... " + prop + ": ... })" + + "Custom property ignored: not scoped to the top-level :root " + + "element (" + rule.selectors + " { ... " + prop + ": ... })" + (rule.parent.type !== "root" ? ", in " + rule.parent.type : ""), {node: decl} ) @@ -238,7 +255,9 @@ module.exports = postcss.plugin("postcss-custom-properties", function(options) { names.forEach(function(name) { var variable = map[name] var val = variable.value - if (variable.resolved) { val = val[val.length - 1] } + if (variable.resolved) { + val = val[val.length - 1] + } var decl = postcss.decl({ prop: name, value: val, diff --git a/package.json b/package.json index 8819739422..e1f78b4b5b 100644 --- a/package.json +++ b/package.json @@ -26,7 +26,7 @@ "postcss": "^4.1.4" }, "devDependencies": { - "eslint": "^0.18.0", + "eslint": "^0.23.0", "tape": "^4.0.0" }, "scripts": { diff --git a/test/index.js b/test/index.js index fe44c19261..bcba3608ac 100755 --- a/test/index.js +++ b/test/index.js @@ -14,7 +14,8 @@ function fixture(name) { } function resolveFixture(name, options) { - return postcss(customProperties(options)).process(fixture(name), {from: fixturePath(name)}) + return postcss(customProperties(options)) + .process(fixture(name), {from: fixturePath(name)}) } function compareFixtures(t, name, options) { @@ -25,58 +26,89 @@ function compareFixtures(t, name, options) { fs.writeFile(fixturePath(name + ".actual"), actual) var expected = fixture(name + ".expected") - t.equal(actual, expected, "processed fixture '" + name + "' should be equal to expected output") + t.equal( + actual, expected, + "processed fixture '" + name + "' should be equal to expected output" + ) return postcssResult } test("throw errors", function(t) { - t.throws(function() { - return postcss(customProperties()).process(fixture("substitution-empty")).css - }, /must contain a non-whitespace string/, "throws an error when a variable function is empty") - - t.throws(function() { - return postcss(customProperties()).process(fixture("substitution-malformed")).css - }, /missing closing/, "throws an error when a variable function is malformed") + t.throws( + function() { + return postcss(customProperties()) + .process(fixture("substitution-empty")) + .css + }, + /must contain a non-whitespace string/, + "throws an error when a variable function is empty" + ) + + t.throws( + function() { + return postcss(customProperties()) + .process(fixture("substitution-malformed")) + .css + }, + /missing closing/, + "throws an error when a variable function is malformed" + ) t.end() }) -test("substitutes nothing when a variable function references an undefined variable", function(t) { - var result = compareFixtures(t, "substitution-undefined") - t.equal(result.warnings()[0].text, "variable '--test' is undefined and used without a fallback", "should add a warning for undefined variable") - t.end() -}) +test( + "substitutes nothing when a variable function references an undefined var", + function(t) { + var result = compareFixtures(t, "substitution-undefined") + t.equal( + result.warnings()[0].text, + "variable '--test' is undefined and used without a fallback", + "should add a warning for undefined variable" + ) + t.end() + } +) test("substitutes defined variables in `:root` only", function(t) { var result = compareFixtures(t, "substitution-defined") - t.ok(result.warnings()[0].text.match(/^Custom property ignored/), "should add a warning for non root custom properties") - t.end() -}) - -test("accepts variables defined from JavaScript, and overrides local definitions", function(t) { - compareFixtures(t, "js-defined", { - variables: { - "--test-one": "js-one", - "--test-two": "js-two", - "--test-three": "js-three", - "--test-varception": "var(--test-one)", - "--test-jsception": "var(--test-varception)", - "--test-num": 1, - }, - }) - t.end() -}) - -test("prefixes js defined variabled with a double dash automatically", function(t) { - compareFixtures(t, "automatic-variable-prefix", { - variables: { - unprefixed: "blue", - "--prefixed": "white", - }, - }) - t.end() -}) + t.ok( + result.warnings()[0].text.match(/^Custom property ignored/), + "should add a warning for non root custom properties" + ) + t.end() +}) + +test( + "accepts variables defined from JavaScript, and overrides local definitions", + function(t) { + compareFixtures(t, "js-defined", { + variables: { + "--test-one": "js-one", + "--test-two": "js-two", + "--test-three": "js-three", + "--test-varception": "var(--test-one)", + "--test-jsception": "var(--test-varception)", + "--test-num": 1, + }, + }) + t.end() + } +) + +test( + "prefixes js defined variabled with a double dash automatically", + function(t) { + compareFixtures(t, "automatic-variable-prefix", { + variables: { + unprefixed: "blue", + "--prefixed": "white", + }, + }) + t.end() + } +) test("removes variable properties from the output", function(t) { compareFixtures(t, "remove-properties") @@ -121,7 +153,11 @@ test("preserves computed value when `preserve` is `\"computed\"`", function(t) { test("circular variable references", function(t) { compareFixtures(t, "self-reference") var result = compareFixtures(t, "circular-reference") - t.equal(result.warnings()[0].text, "Circular variable reference: --color", "should add a warning for circular reference") + t.equal( + result.warnings()[0].text, + "Circular variable reference: --color", + "should add a warning for circular reference" + ) t.end() }) From c53c861c7462849c2fce053da9823dad555cbbc2 Mon Sep 17 00:00:00 2001 From: Jonathan Neal Date: Wed, 17 Jun 2015 12:08:22 -0400 Subject: [PATCH 250/795] Project scaffolding --- .eslintrc | 19 +++++++++++++++++++ .gitignore | 2 ++ .npmignore | 8 ++++++++ .travis.yml | 6 ++++++ gulpfile.js | 16 ++++++++++++++++ 5 files changed, 51 insertions(+) create mode 100644 .eslintrc create mode 100644 .gitignore create mode 100644 .npmignore create mode 100644 .travis.yml create mode 100644 gulpfile.js diff --git a/.eslintrc b/.eslintrc new file mode 100644 index 0000000000..8966b851d8 --- /dev/null +++ b/.eslintrc @@ -0,0 +1,19 @@ +{ + "rules": { + "no-unused-expressions": [0], + "no-underscore-dangle": [0], + "no-reserved-keys": [2], + "no-multi-spaces": [0], + "no-unused-vars": [2], + "no-loop-func": [0], + "key-spacing": [0], + "max-len": [2], + "strict": [0], + "quotes": [2, "single", "avoid-escape"], + "curly": [0] + }, + "env": { + "mocha": true, + "node": true + } +} diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000000..1ca957177f --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +node_modules/ +npm-debug.log diff --git a/.npmignore b/.npmignore new file mode 100644 index 0000000000..1aa2d59e25 --- /dev/null +++ b/.npmignore @@ -0,0 +1,8 @@ +.gitignore + +node_modules/ + +test/ +.travis.yml + +gulpfile.js diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000000..ffb8b3996f --- /dev/null +++ b/.travis.yml @@ -0,0 +1,6 @@ +sudo: false +language: node_js +node_js: + - iojs + - "0.12" + - "0.10" diff --git a/gulpfile.js b/gulpfile.js new file mode 100644 index 0000000000..1fc565b0b9 --- /dev/null +++ b/gulpfile.js @@ -0,0 +1,16 @@ +var gulp = require('gulp'); + +gulp.task('lint', function () { + var eslint = require('gulp-eslint'); + return gulp.src(['index.js', 'test/*.js', 'gulpfile.js']) + .pipe(eslint()) + .pipe(eslint.format()) + .pipe(eslint.failAfterError()); +}); + +gulp.task('test', function () { + var mocha = require('gulp-mocha'); + return gulp.src('test/*.js', { read: false }).pipe(mocha()); +}); + +gulp.task('default', ['lint', 'test']); From 6afef4e5ec528ef3ff2a90356efe71fc0dfc0635 Mon Sep 17 00:00:00 2001 From: Jonathan Neal Date: Wed, 17 Jun 2015 12:09:34 -0400 Subject: [PATCH 251/795] Update LICENSE.md CC0 1.0 --- LICENSE.md | 15 +++++++++++++++ 1 file changed, 15 insertions(+) create mode 100644 LICENSE.md diff --git a/LICENSE.md b/LICENSE.md new file mode 100644 index 0000000000..565f84e33c --- /dev/null +++ b/LICENSE.md @@ -0,0 +1,15 @@ +# CC0 1.0 Universal License + +Public Domain Dedication + +The person(s) who associated a work with this deed has dedicated the work to the public domain by waiving all of his or her rights to the work worldwide under copyright law, including all related and neighboring rights, to the extent allowed by law. + +You can copy, modify, distribute and perform the work, even for commercial purposes, all without asking permission. + +In no way are the patent or trademark rights of any person affected by CC0, nor are the rights that other persons may have in the work or in how the work is used, such as publicity or privacy rights. + +Unless expressly stated otherwise, the person(s) who associated a work with this deed makes no warranties about the work, and disclaims liability for all uses of the work, to the fullest extent permitted by applicable law. + +When using or citing the work, you should not imply endorsement by the author or the affirmer. + +This is a [human-readable summary of the Legal Code](https://creativecommons.org/publicdomain/zero/1.0/) ([read the full text](https://creativecommons.org/publicdomain/zero/1.0/legalcode)). From c11bde1ebdadb04c10127086273bf5e9ffb803e5 Mon Sep 17 00:00:00 2001 From: Jonathan Neal Date: Wed, 17 Jun 2015 12:26:35 -0400 Subject: [PATCH 252/795] Update plugin Initial release --- index.js | 117 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 117 insertions(+) create mode 100644 index.js diff --git a/index.js b/index.js new file mode 100644 index 0000000000..636afc215d --- /dev/null +++ b/index.js @@ -0,0 +1,117 @@ +var postcss = require('postcss'); +var parser = require('postcss-selector-parser'); + +function parse(selector) { + return parser().process(selector).res; +} + +function isNestingRule(rule) { + return rule && !rule.selector && rule.parent && rule.parent.type === 'rule'; +} + +function hasParentReference(node) { + if (node.type === 'tag') { + return node.value === '&'; + } + + for (var index in node.nodes) { + if (hasParentReference(node.nodes[index])) { + return true; + } + } + + return false; +} + +module.exports = postcss.plugin('postcss-nesting', function (opts) { + opts = opts || {}; + + return function (css) { + // for each rule in css + css.eachRule(function (nestingRule) { + // if the rule is a nesting rule + if (isNestingRule(nestingRule)) { + // cache parent selectors + var parentSelectors = nestingRule.parent.selector; + var parentSelectorsObject = parse(parentSelectors); + + // for each rule in the nesting rule + nestingRule.eachRule(function (rule, ruleIndex) { + var newSelectors = parser.root(); + + // for each selector in the rule + parse(rule.selector).each(function (selector) { + // if the selector has a parent reference + if (hasParentReference(selector)) { + // HINT: selectors = parent selectors × parent references + + var cloneSelectorList = parser.root(); + + cloneSelectorList.append(selector.clone()); + + while (hasParentReference(cloneSelectorList)) { + var cloneSelector; + var cloneSelectorIndex = -1; + var cloneNode; + var cloneNodeIndex; + var parentSelector2; + var parentSelectorIndex; + + while ((cloneSelector = cloneSelectorList.nodes[++cloneSelectorIndex])) { + cloneNodeIndex = -1; + + while ((cloneNode = cloneSelector.nodes[++cloneNodeIndex])) { + if (hasParentReference(cloneNode)) { + parentSelectorIndex = -1; + + while ((parentSelector2 = parentSelectorsObject.nodes[++parentSelectorIndex])) { + cloneSelector.nodes.splice(cloneNodeIndex, 1, parentSelector2); + + cloneSelectorList.nodes.splice(cloneSelectorIndex + parentSelectorIndex + 1, 0, cloneSelector.clone()); + } + + cloneSelectorList.nodes.splice(cloneSelectorIndex, 1); + + break; + } + } + } + } + + newSelectors.append(cloneSelectorList); + } + // if the selector does not have a parent reference + else { + // for each parent selector + parse(parentSelectors).each(function (parentSelector) { + // create a new selector + var newSelector = parser.selector(); + + // append the parent selector to the new selector + newSelector.append(parentSelector); + + // append a combinator to the new selector + newSelector.append(parser.combinator({ value: ' ' })); + + // append the selector to the new selector + newSelector.append(selector); + + // append the new selector to the new selectors + newSelectors.append(newSelector); + }); + } + }); + + // replace the rule selector with the new selectors + rule.selector = newSelectors.toString(); + + // append the rule after the nesting rule + nestingRule.parent.parent.nodes.splice(nestingRule.parent.parent.nodes.indexOf(nestingRule.parent) + ruleIndex + 1, 0, rule); + }); + + // remove original nesting rule + nestingRule.removeSelf(); + } + }); + }; +}); From c6c44139bb889386d9a6589a5d7cfe5127aeff26 Mon Sep 17 00:00:00 2001 From: Jonathan Neal Date: Wed, 17 Jun 2015 12:26:40 -0400 Subject: [PATCH 253/795] Update tests --- test/test.js | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) create mode 100644 test/test.js diff --git a/test/test.js b/test/test.js new file mode 100644 index 0000000000..6f457b94dc --- /dev/null +++ b/test/test.js @@ -0,0 +1,24 @@ +var postcss = require('postcss'); +var expect = require('chai').expect; + +var plugin = require('../'); + +var test = function (input, output, opts, done) { + postcss([ plugin(opts) ]).process(input).then(function (result) { + expect(result.css).to.eql(output); + expect(result.warnings()).to.be.empty; + done(); + }).catch(function (error) { + done(error); + }); +}; + +describe('postcss-nesting', function () { + it('basic usage', function (done) { + test( + 'a,b{color:red;{c,d{color:white;}& &{color:blue;}&:hover{color:white;}}}', + 'a,b{color:red}a c,b c,a d,b d{color:white;}a a,a b,b a,b b{color:blue;}a:hover,b:hover{color:white;}', + {}, + done); + }); +}); From 37ca9e28202c62eedf0ce39d1b663ecbcec8a54b Mon Sep 17 00:00:00 2001 From: Jonathan Neal Date: Wed, 17 Jun 2015 12:26:48 -0400 Subject: [PATCH 254/795] Update README.md --- README.md | 98 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 98 insertions(+) create mode 100644 README.md diff --git a/README.md b/README.md new file mode 100644 index 0000000000..76ce83a9e3 --- /dev/null +++ b/README.md @@ -0,0 +1,98 @@ +# PostCSS Nesting [![Build Status][ci-img]][ci] + + + +[PostCSS Nesting] is a [PostCSS] plugin that allows you nest one style rule inside another. + +```css +/* before */ + +a, b { + color: red; + + { + c, d { + color: white; + } + + & & { + color: blue; + } + + &:hover { + color: white; + } + } +} + +/* after */ + +a, b { + color: red; +} + +a c, b c, a d, b d { + color: white; +} + +a a, a b, b a, b b { + color: blue; +} + +a:hover, b:hover { + color: white; +} +``` + +From [CSS Nesting Module Level 3]: +> This module introduces the ability to nest one style rule inside another, with the selector of the child rule relative to the selector of the parent rule. This increase the modularity and maintainability of CSS stylesheets. + +## Usage + +You just need to follow these two steps to use [PostCSS Nesting]: + +1. Add [PostCSS] to your build tool. +2. Add [PostCSS Nesting] as a PostCSS process. + +```sh +npm install postcss-nesting --save-dev +``` + +### Node + +```js +postcss([ require('postcss-nesting')({ /* options */ }) ]) +``` + +### Grunt + +Install [Grunt PostCSS]: + +```shell +npm install postcss-nesting --save-dev +``` + +Enable [PostCSS Nesting] within your Gruntfile: + +```js +grunt.loadNpmTasks('grunt-postcss'); + +grunt.initConfig({ + postcss: { + options: { + processors: [ + require('postcss-nesting')({ /* options */ }) + ] + }, + dist: { + src: 'css/*.css' + } + } +}); +``` + +[ci]: https://travis-ci.org/jonathantneal/postcss-nesting +[ci-img]: https://travis-ci.org/jonathantneal/postcss-nesting.svg +[CSS Nesting Module Level 3]: http://tabatkins.github.io/specs/css-nesting/ +[PostCSS]: https://github.com/postcss/postcss +[PostCSS Nesting]: https://github.com/jonathantneal/postcss-nesting From d63f6b6b1efef37c11d86a84de23fe901f74123a Mon Sep 17 00:00:00 2001 From: Jonathan Neal Date: Wed, 17 Jun 2015 12:27:09 -0400 Subject: [PATCH 255/795] 0.1.0 --- CHANGELOG.md | 3 +++ package.json | 26 ++++++++++++++++++++++++++ 2 files changed, 29 insertions(+) create mode 100644 CHANGELOG.md create mode 100644 package.json diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000000..f3bfd0f08b --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,3 @@ +## 0.1.0 (2015-06-17) + +- Added: Initial release diff --git a/package.json b/package.json new file mode 100644 index 0000000000..478e9c8026 --- /dev/null +++ b/package.json @@ -0,0 +1,26 @@ +{ + "name": "postcss-nesting", + "version": "0.1.0", + "description": "PostCSS plugin ability to nest one style rule inside another", + "keywords": ["postcss", "css", "postcss-plugin", "nesting", "selector", "rule"], + "author": "Jonathan Neal ", + "license": "MIT", + "repository": { + "type": "git", + "url": "https://github.com/jonathantneal/postcss-nesting.git" + }, + "dependencies": { + "postcss": "^4.1.9", + "postcss-selector-parser": "^1.0.0" + }, + "devDependencies": { + "gulp-eslint": "^0.12.0", + "gulp-mocha": "^2.0.1", + "chai": "^2.3.0", + "gulp": "^3.8.11", + "gulp-watch": "^4.2.4" + }, + "scripts": { + "test": "gulp" + } +} From d07a7323ac4d9a6a4cdf92359f69c92b78164f31 Mon Sep 17 00:00:00 2001 From: Jonathan Neal Date: Wed, 17 Jun 2015 12:28:54 -0400 Subject: [PATCH 256/795] Update README.md --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 76ce83a9e3..2dae9f77b3 100644 --- a/README.md +++ b/README.md @@ -94,5 +94,6 @@ grunt.initConfig({ [ci]: https://travis-ci.org/jonathantneal/postcss-nesting [ci-img]: https://travis-ci.org/jonathantneal/postcss-nesting.svg [CSS Nesting Module Level 3]: http://tabatkins.github.io/specs/css-nesting/ +[Grunt PostCSS]: https://github.com/nDmitry/grunt-postcss [PostCSS]: https://github.com/postcss/postcss [PostCSS Nesting]: https://github.com/jonathantneal/postcss-nesting From 13dc1d395f6a04e1ddbc67f3de00e9b8f61e8d6a Mon Sep 17 00:00:00 2001 From: Maxime Thirouin Date: Wed, 17 Jun 2015 18:58:35 +0200 Subject: [PATCH 257/795] More clear short description in the README Close #1 --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 2dae9f77b3..73584a03ae 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ -[PostCSS Nesting] is a [PostCSS] plugin that allows you nest one style rule inside another. +[PostCSS Nesting] is a [PostCSS] plugin that transform W3C [CSS Nesting Module Level 3] syntax (@tabatkins proposal) to more compatible CSS. ```css /* before */ From d29cf2639e8a38347ce230bccaffb806b5738b68 Mon Sep 17 00:00:00 2001 From: Jonathan Neal Date: Wed, 17 Jun 2015 13:06:08 -0400 Subject: [PATCH 258/795] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 73584a03ae..49cd76bf30 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ -[PostCSS Nesting] is a [PostCSS] plugin that transform W3C [CSS Nesting Module Level 3] syntax (@tabatkins proposal) to more compatible CSS. +[PostCSS Nesting] is a [PostCSS] plugin that transforms W3C [CSS Nesting Module Level 3] syntax (@tabatkins’ proposal) to more compatible CSS. ```css /* before */ From 00382925f5638196d6ad165c3cb155172b6222ee Mon Sep 17 00:00:00 2001 From: Nicola Molinari Date: Sat, 27 Jun 2015 16:00:32 +0200 Subject: [PATCH 259/795] Add test to reproduce warnings --- test/fixtures/similar-matches/input.css | 20 ++++++++++++++++++++ test/fixtures/similar-matches/output.css | 15 +++++++++++++++ test/index.js | 1 + 3 files changed, 36 insertions(+) create mode 100644 test/fixtures/similar-matches/input.css create mode 100644 test/fixtures/similar-matches/output.css diff --git a/test/fixtures/similar-matches/input.css b/test/fixtures/similar-matches/input.css new file mode 100644 index 0000000000..e41b411345 --- /dev/null +++ b/test/fixtures/similar-matches/input.css @@ -0,0 +1,20 @@ +@custom-selector :--foo .foo; +@custom-selector :--foo-bar .foo .bar; +@custom-selector :--foo-baz .foo .baz; +@custom-selector :--foo-bar-baz .foo .bar .baz; + +:--foo { + color: red; +} + +:--foo-bar { + color: green; +} + +:--foo-baz { + color: black; +} + +:--foo-bar-baz { + color: blue; +} diff --git a/test/fixtures/similar-matches/output.css b/test/fixtures/similar-matches/output.css new file mode 100644 index 0000000000..55362469cc --- /dev/null +++ b/test/fixtures/similar-matches/output.css @@ -0,0 +1,15 @@ +.foo { + color: red; +} + +.foo .bar { + color: green; +} + +.foo .baz { + color: black; +} + +.foo .bar .baz { + color: blue; +} diff --git a/test/index.js b/test/index.js index 7816c0e947..ff8283dc47 100644 --- a/test/index.js +++ b/test/index.js @@ -30,6 +30,7 @@ test("@custom-selector", function(t) { compareFixtures(t, "multiline", "should transform multiline") compareFixtures(t, "some-hyphen", "should transform some hyphen") compareFixtures(t, "matches", "should transform matches selector") + compareFixtures(t, "similar-matches", "should transform matches selector") compareFixtures(t, "extension", "should transform local extensions", { extensions: { From 3883f7198928d0c62a934db4eaf485006248718b Mon Sep 17 00:00:00 2001 From: Maxime Thirouin Date: Mon, 29 Jun 2015 10:50:02 +0200 Subject: [PATCH 260/795] Fixed: support pseudo-element that might be collapsed to :matches() (1.1.2) Close #4 --- CHANGELOG.md | 6 ++++++ package.json | 2 +- src/index.js | 16 +++++++++++----- test/index.js | 12 ++++++++++++ 4 files changed, 30 insertions(+), 6 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c417f891d1..f1034b616c 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,9 @@ +# 1.1.2 - 2015-06-29 + +- Fixed: support pseudo-element that might be collapsed to :matches() +([#4](https://github.com/postcss/postcss-selector-matches/issues/4)) +- Fixed: doesn't drop selectors parts that do not have :matches() in them + # 1.1.1 - 2015-06-17 - Fixed: no more duplicates in generated selector diff --git a/package.json b/package.json index ba4487e783..355dd6939f 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "postcss-selector-matches", - "version": "1.1.1", + "version": "1.1.2", "description": "PostCSS plugin to transform :matches() W3C CSS pseudo class to more compatible CSS selectors", "keywords": [ "postcss", diff --git a/src/index.js b/src/index.js index b3fac25532..4b3c765d52 100644 --- a/src/index.js +++ b/src/index.js @@ -10,17 +10,19 @@ function explodeSelector(pseudoClass, selector, options) { selectorPart.forEach(part => { const position = part.indexOf(pseudoClass) const pre = part.slice(0, position) - const matches = balancedMatch("(", ")", part.slice(position)) + const body = part.slice(position) + const matches = balancedMatch("(", ")", body) - const bodySelectors = matches.body ? + const bodySelectors = matches && matches.body ? list .comma(matches.body) .reduce((acc, s) => [ ...acc, ...explodeSelector(pseudoClass, s, options), ], []) - : [] - const postSelectors = matches.post + : [body] + + const postSelectors = matches && matches.post ? explodeSelector(pseudoClass, matches.post, options) : [] @@ -29,10 +31,14 @@ function explodeSelector(pseudoClass, selector, options) { newParts = bodySelectors.map((s) => pre + s) } else { + const postWhitespaceMatches = matches.post.match(/^\s+/) + const postWhitespace = postWhitespaceMatches + ? postWhitespaceMatches[0] + : "" newParts = [] postSelectors.forEach(postS => { bodySelectors.forEach(s => { - newParts.push(pre + s + " " + postS) + newParts.push(pre + s + postWhitespace + postS) }) }) } diff --git a/test/index.js b/test/index.js index da12ebbc70..895fff483b 100644 --- a/test/index.js +++ b/test/index.js @@ -44,6 +44,12 @@ tape("postcss-selector-matches", t => { "should transform mutltiples :matches()" ) + t.equal( + transform("tag :matches(tag2, tag3) :matches(tag4, tag5), test {}"), + "tag tag2 tag4, tag tag3 tag4, tag tag2 tag5, tag tag3 tag5, test {}", + "should transform mutltiples :matches() with stuff after" + ) + t.equal( transform("tag :matches(tag2 :matches(tag4, tag5), tag3) {}"), "tag tag2 tag4, tag tag2 tag5, tag tag3 {}", @@ -92,5 +98,11 @@ button:hover, button:active, .button:hover, .button:active {}`, "should avoid duplicates" ) + t.equal( + transform(`.foo:matches(:hover, :focus)::before {}`), + `.foo:hover::before, .foo:focus::before {}`, + "should work with something after :matches()" + ) + t.end() }) From 9774424b1b872daa54d2793defd676fbf6fba746 Mon Sep 17 00:00:00 2001 From: Maxime Thirouin Date: Mon, 29 Jun 2015 11:00:26 +0200 Subject: [PATCH 261/795] Add more tests (just in case) --- test/index.js | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/test/index.js b/test/index.js index 110a3b12fc..727878635f 100644 --- a/test/index.js +++ b/test/index.js @@ -44,6 +44,12 @@ tape("postcss-selector-not", t => { "should transform mutltiples :not()" ) + t.equal( + transform("tag :not(tag2, tag3) :not(tag4, tag5), test {}"), + "tag :not(tag2):not(tag3) :not(tag4):not(tag5), test {}", + "should transform mutltiples :not() with stuff after" + ) + t.equal( transform("tag :not(tag2 :not(tag4, tag5), tag3) {}"), "tag :not(tag2 :not(tag4):not(tag5)):not(tag3) {}", @@ -65,5 +71,11 @@ tape("postcss-selector-not", t => { "should works with lots of whitespace" ) + t.equal( + transform(`.foo:not(:hover, :focus)::before {}`), + `.foo:not(:hover):not(:focus)::before {}`, + "should work with something after :not()" + ) + t.end() }) From 74ee82ee7dd668466c2af2ee44ffa2cd2ef11ce5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=B8=80=E4=B8=9D?= Date: Tue, 30 Jun 2015 11:52:19 +0800 Subject: [PATCH 262/795] Fix the lineBreak option keeping the selectors indent --- index.js | 22 +++++++++++++++------- test/fixtures/comment/input.css | 11 +++++++++++ test/fixtures/comment/output.css | 8 ++++++++ test/fixtures/line-break/input.css | 6 ++++++ test/fixtures/line-break/output.css | 5 +++++ test/index.js | 16 ++++++++++------ 6 files changed, 55 insertions(+), 13 deletions(-) create mode 100644 test/fixtures/comment/input.css create mode 100644 test/fixtures/comment/output.css create mode 100644 test/fixtures/line-break/input.css create mode 100644 test/fixtures/line-break/output.css diff --git a/index.js b/index.js index d0ead53086..5ee8e425c0 100644 --- a/index.js +++ b/index.js @@ -6,6 +6,9 @@ var postcss = require("postcss") */ var re_CUSTOM_SELECTOR = /([^,]*?)(:-{2,}[\w-]+)(.*)/g +// 匹配换行符与空白 +var reBLANK_LINE = /(\r\n|\n|\r)(\s*?\1)+/gi + /** * 暴露插件 */ @@ -50,11 +53,6 @@ module.exports = postcss.plugin("postcss-custom-selectors", function(options) { customSelectors[extension] = extensions[extension] }) - //控制选择器是否换行 - if (!options.lineBreak && options.lineBreak == false) { - line_break = ' ' - } - // 转换自定义的选择器别名 styles.eachRule(function(rule) { for (var prop in customSelectors) { @@ -64,9 +62,19 @@ module.exports = postcss.plugin("postcss-custom-selectors", function(options) { // $2 = (自定义的选择器名称) rule.selector = rule.selector.replace(re_CUSTOM_SELECTOR, function($0, $1, $2, $3) { if ($2 === prop) { - return customSelector.split(",").map(function(selector) { + var newSelector = customSelector.split(",").map(function(selector) { return $1 + selector.trim() + $3 - }).join("," + line_break) + }) + + // 选择器不换行 + if (!options.lineBreak && options.lineBreak === false) { + line_break = " " + newSelector = newSelector.join("," + line_break) + } else { + // 选择器换行,同时替换多个换行为一个 + newSelector = newSelector.join("," + line_break + rule.before).replace(reBLANK_LINE, line_break) + } + return newSelector } else if ($2 !== prop) { console.log("Warning: The selector '" + $2 + "' is undefined in CSS!") return $2 diff --git a/test/fixtures/comment/input.css b/test/fixtures/comment/input.css new file mode 100644 index 0000000000..c1fc9a9cff --- /dev/null +++ b/test/fixtures/comment/input.css @@ -0,0 +1,11 @@ +/* comment */ +@custom-selector :--foo + /* comment */ + .foo, + .bar > .baz; + + +/* comment */ + :--foo + p { + display: block; + } diff --git a/test/fixtures/comment/output.css b/test/fixtures/comment/output.css new file mode 100644 index 0000000000..f9df1ea227 --- /dev/null +++ b/test/fixtures/comment/output.css @@ -0,0 +1,8 @@ +/* comment */ + + +/* comment */ + .foo + p, + .bar > .baz + p { + display: block; + } diff --git a/test/fixtures/line-break/input.css b/test/fixtures/line-break/input.css new file mode 100644 index 0000000000..e166077b4b --- /dev/null +++ b/test/fixtures/line-break/input.css @@ -0,0 +1,6 @@ +@custom-selector :--heading h1, h2, h3, h4, h5, h6; +/* comment */ + + article :--heading + p { + margin-top: 0; + } diff --git a/test/fixtures/line-break/output.css b/test/fixtures/line-break/output.css new file mode 100644 index 0000000000..c78f0e8783 --- /dev/null +++ b/test/fixtures/line-break/output.css @@ -0,0 +1,5 @@ +/* comment */ + + article h1 + p, article h2 + p, article h3 + p, article h4 + p, article h5 + p, article h6 + p { + margin-top: 0; + } diff --git a/test/index.js b/test/index.js index ff8283dc47..4efdc6cd69 100644 --- a/test/index.js +++ b/test/index.js @@ -31,13 +31,17 @@ test("@custom-selector", function(t) { compareFixtures(t, "some-hyphen", "should transform some hyphen") compareFixtures(t, "matches", "should transform matches selector") compareFixtures(t, "similar-matches", "should transform matches selector") - - compareFixtures(t, "extension", "should transform local extensions", { - extensions: { - ':--any' : 'section, article, aside, nav', - ':--foo': 'input[type="text"] > section, #nav .bar' - } + compareFixtures(t, "comment", "should transform comment") + compareFixtures(t, "line-break", "should transform line break", { + lineBreak: false }) + // compareFixtures(t, "extension", "should transform local extensions", { + // extensions: { + // ':--any' : 'section, article, aside, nav', + // ':--foo': 'input[type="text"] > section, #nav .bar' + // } + // }) + t.end() }) From 47c800c8b66b4421cbfddae4a985f5f878b1ca4e Mon Sep 17 00:00:00 2001 From: Glen Huang Date: Tue, 21 Apr 2015 00:01:55 +0800 Subject: [PATCH 263/795] Allow custom media to reference each other --- index.js | 61 +++++++++++++++++-- .../fixtures/transform-circular-reference.css | 10 +++ .../transform-circular-reference.expected.css | 1 + test/fixtures/transform-reference.css | 8 +++ .../fixtures/transform-reference.expected.css | 7 +++ test/fixtures/transform-self-reference.css | 9 +++ .../transform-self-reference.expected.css | 1 + test/index.js | 19 ++++++ 8 files changed, 112 insertions(+), 4 deletions(-) create mode 100644 test/fixtures/transform-circular-reference.css create mode 100644 test/fixtures/transform-circular-reference.expected.css create mode 100644 test/fixtures/transform-reference.css create mode 100644 test/fixtures/transform-reference.expected.css create mode 100644 test/fixtures/transform-self-reference.css create mode 100644 test/fixtures/transform-self-reference.expected.css diff --git a/index.js b/index.js index 4f7153d876..be6f8d2c55 100755 --- a/index.js +++ b/index.js @@ -2,6 +2,33 @@ var postcss = require("postcss") var EXTENSION_RE = /\(\s*(--[\w-]+)\s*\)/g +/* + * Resolve custom media values. + */ +function resolveValue(value, map, result) { + if (!EXTENSION_RE.test(value)) { + return value + } + return value.replace(EXTENSION_RE, function(orig, name) { + if (!map[name]) { + return orig + } + + var mq = map[name] + if (mq.resolved) { + return mq.value + } + + if (mq.deps.indexOf(name) !== -1) { + mq.circular = true + return orig + } + mq.deps.push(name) + mq.value = resolveValue(mq.value, map, result) + return mq.value + }) +} + /* * read & replace custom media queries by standard media queries */ @@ -32,7 +59,12 @@ function customMedia(options) { var params = rule.params.split(" ") // @custom-media ; // map[] = - map[params.shift()] = params.join(" ") + map[params.shift()] = { + value: params.join(" "), + deps: [], + circular: false, + resolved: false, + } if (!preserve) { toRemove.push(rule) @@ -41,7 +73,17 @@ function customMedia(options) { // apply js-defined media queries Object.keys(extensions).forEach(function(name) { - map[name] = extensions[name] + map[name] = { + value: extensions[name], + deps: [], + circular: false, + resolved: false, + } + }) + + Object.keys(map).forEach(function(name) { + map[name].value = resolveValue(map[name].value, map, result) + map[name].resolved = true }) // transform custom media query aliases @@ -52,7 +94,15 @@ function customMedia(options) { rule.params = rule.params.replace(EXTENSION_RE, function(_, name) { if (map[name]) { - return map[name] + if (map[name].circular) { + result.warn( + "Circular @custom-media definition for '" + name + + "'. The entire rule has been removed from the output.", + {node: rule} + ) + toRemove.push(rule) + } + return map[name].value } result.warn( @@ -68,10 +118,13 @@ function customMedia(options) { var names = Object.keys(map) if (names.length) { names.forEach(function(name) { + if (map[name].circular) { + return + } var atRule = postcss.atRule({ name: "custom-media", afterName: " ", - params: name + " " + map[name], + params: name + " " + map[name].value, }) styles.append(atRule) }) diff --git a/test/fixtures/transform-circular-reference.css b/test/fixtures/transform-circular-reference.css new file mode 100644 index 0000000000..5de94623d9 --- /dev/null +++ b/test/fixtures/transform-circular-reference.css @@ -0,0 +1,10 @@ +body { color: #000 } + +@custom-media --a (--b); +@custom-media --b (--a); + +@media (--b) { + selector { + property: value; + } +} diff --git a/test/fixtures/transform-circular-reference.expected.css b/test/fixtures/transform-circular-reference.expected.css new file mode 100644 index 0000000000..4746c8775a --- /dev/null +++ b/test/fixtures/transform-circular-reference.expected.css @@ -0,0 +1 @@ +body { color: #000 } diff --git a/test/fixtures/transform-reference.css b/test/fixtures/transform-reference.css new file mode 100644 index 0000000000..e5e8a5b3e5 --- /dev/null +++ b/test/fixtures/transform-reference.css @@ -0,0 +1,8 @@ +@custom-media --a (foo: bar); +@custom-media --b (--a); + +@media (--b) { + selector { + property: value; + } +} diff --git a/test/fixtures/transform-reference.expected.css b/test/fixtures/transform-reference.expected.css new file mode 100644 index 0000000000..c949741814 --- /dev/null +++ b/test/fixtures/transform-reference.expected.css @@ -0,0 +1,7 @@ + + +@media (foo: bar) { + selector { + property: value; + } +} diff --git a/test/fixtures/transform-self-reference.css b/test/fixtures/transform-self-reference.css new file mode 100644 index 0000000000..7907752313 --- /dev/null +++ b/test/fixtures/transform-self-reference.css @@ -0,0 +1,9 @@ +body { color: #000 } + +@custom-media --a (--a); + +@media (--a) { + selector { + property: value; + } +} diff --git a/test/fixtures/transform-self-reference.expected.css b/test/fixtures/transform-self-reference.expected.css new file mode 100644 index 0000000000..4746c8775a --- /dev/null +++ b/test/fixtures/transform-self-reference.expected.css @@ -0,0 +1 @@ +body { color: #000 } diff --git a/test/index.js b/test/index.js index b73efe27d8..a11c177234 100755 --- a/test/index.js +++ b/test/index.js @@ -40,6 +40,24 @@ test("@custom-media", function(t) { "should replaces all extension names" ) + compareFixtures( + t, + "transform-reference", + "should transform custom media referencing another custom media" + ) + + compareFixtures( + t, + "transform-self-reference", + "should transform custom media with self reference" + ) + + compareFixtures( + t, + "transform-circular-reference", + "should transform custom media with circular reference" + ) + var undefinedRes = compareFixtures( t, "undefined", @@ -89,6 +107,7 @@ test("@custom-media", function(t) { { extensions: { "--viewport-max-s": "(max-width: 30em)", + "--a": "(--a)", }, appendExtensions: true, } From 7c1c36a18b70b2691f4ca86fadac5ccccbedc09d Mon Sep 17 00:00:00 2001 From: Maxime Thirouin Date: Tue, 30 Jun 2015 07:28:01 +0200 Subject: [PATCH 264/795] 4.1.0 --- CHANGELOG.md | 5 +++++ package.json | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 86b28097e4..36d2ca386e 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,8 @@ +# 4.1.0 - 2015-06-30 + +- Added: Allow custom media to reference each other +([#10](https://github.com/postcss/postcss-custom-media/pull/10)) + # 4.0.0 - 2015-05-17 - Changed: warning messages are now sent via postcss messages api (^4.1.0) diff --git a/package.json b/package.json index 8d5ad43ad3..dcd419bdc9 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "postcss-custom-media", - "version": "4.0.0", + "version": "4.1.0", "description": " PostCSS plugin to transform W3C CSS Custom Media Queries to more compatible CSS", "keywords": [ "css", From c19ff8ffbf8817abeafde72451670b10e30810b0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=B8=80=E4=B8=9D?= Date: Tue, 30 Jun 2015 22:38:05 +0800 Subject: [PATCH 265/795] Fixed the tip of an undefined selector --- index.js | 14 ++++++++++---- test/fixtures/similar-matches/input.css | 20 +++++++------------- test/fixtures/similar-matches/output.css | 16 ++++++---------- test/index.js | 12 ++++++------ 4 files changed, 29 insertions(+), 33 deletions(-) diff --git a/index.js b/index.js index 5ee8e425c0..2917e0eb20 100644 --- a/index.js +++ b/index.js @@ -26,7 +26,7 @@ module.exports = postcss.plugin("postcss-custom-selectors", function(options) { /** * 读取和替换自定义选择器 */ - return function(styles) { + return function(styles, result) { // 读取自定义选择器 styles.eachAtRule(function(rule) { if (rule.name !== "custom-selector") { @@ -54,13 +54,15 @@ module.exports = postcss.plugin("postcss-custom-selectors", function(options) { }) // 转换自定义的选择器别名 - styles.eachRule(function(rule) { + styles.eachRule(function(rule, result) { + var flag = 0 for (var prop in customSelectors) { if (rule.selector.indexOf(prop) >= 0) { customSelector = customSelectors[prop] // $2 = (自定义的选择器名称) rule.selector = rule.selector.replace(re_CUSTOM_SELECTOR, function($0, $1, $2, $3) { + if ($2 === prop) { var newSelector = customSelector.split(",").map(function(selector) { return $1 + selector.trim() + $3 @@ -74,14 +76,18 @@ module.exports = postcss.plugin("postcss-custom-selectors", function(options) { // 选择器换行,同时替换多个换行为一个 newSelector = newSelector.join("," + line_break + rule.before).replace(reBLANK_LINE, line_break) } + flag ++ return newSelector - } else if ($2 !== prop) { - console.log("Warning: The selector '" + $2 + "' is undefined in CSS!") + } + else if ($2 !== prop) { return $2 } }) } } + if(flag === 0){ + console.log("Warning: The selector '" + rule.selector + "' is undefined in CSS!") + } }) // 删除 @custom-selector diff --git a/test/fixtures/similar-matches/input.css b/test/fixtures/similar-matches/input.css index e41b411345..9ed53695a5 100644 --- a/test/fixtures/similar-matches/input.css +++ b/test/fixtures/similar-matches/input.css @@ -1,20 +1,14 @@ -@custom-selector :--foo .foo; -@custom-selector :--foo-bar .foo .bar; -@custom-selector :--foo-baz .foo .baz; -@custom-selector :--foo-bar-baz .foo .bar .baz; +@custom-selector :--foo h1; +@custom-selector :--foo-bar-baz h4 h5 h6; :--foo { - color: red; + color: red; } -:--foo-bar { - color: green; -} - -:--foo-baz { - color: black; +:--foo-bar-baz { + color: blue; } -:--foo-bar-baz { - color: blue; +:--test p { + display: block; } diff --git a/test/fixtures/similar-matches/output.css b/test/fixtures/similar-matches/output.css index 55362469cc..adff0a191b 100644 --- a/test/fixtures/similar-matches/output.css +++ b/test/fixtures/similar-matches/output.css @@ -1,15 +1,11 @@ -.foo { - color: red; +h1 { + color: red; } -.foo .bar { - color: green; +h4 h5 h6 { + color: blue; } -.foo .baz { - color: black; -} - -.foo .bar .baz { - color: blue; +:--test p { + display: block; } diff --git a/test/index.js b/test/index.js index 4efdc6cd69..bba9e1a6ad 100644 --- a/test/index.js +++ b/test/index.js @@ -36,12 +36,12 @@ test("@custom-selector", function(t) { lineBreak: false }) - // compareFixtures(t, "extension", "should transform local extensions", { - // extensions: { - // ':--any' : 'section, article, aside, nav', - // ':--foo': 'input[type="text"] > section, #nav .bar' - // } - // }) + compareFixtures(t, "extension", "should transform local extensions", { + extensions: { + ':--any' : 'section, article, aside, nav', + ':--foo': 'input[type="text"] > section, #nav .bar' + } + }) t.end() }) From 4a38cb16e1a1b496abd6399d1528ab417bc6d9b9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=B8=80=E4=B8=9D?= Date: Tue, 30 Jun 2015 22:41:50 +0800 Subject: [PATCH 266/795] remove result --- index.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/index.js b/index.js index 2917e0eb20..a13c860041 100644 --- a/index.js +++ b/index.js @@ -26,7 +26,7 @@ module.exports = postcss.plugin("postcss-custom-selectors", function(options) { /** * 读取和替换自定义选择器 */ - return function(styles, result) { + return function(styles) { // 读取自定义选择器 styles.eachAtRule(function(rule) { if (rule.name !== "custom-selector") { @@ -54,7 +54,7 @@ module.exports = postcss.plugin("postcss-custom-selectors", function(options) { }) // 转换自定义的选择器别名 - styles.eachRule(function(rule, result) { + styles.eachRule(function(rule) { var flag = 0 for (var prop in customSelectors) { if (rule.selector.indexOf(prop) >= 0) { From 5529d29c6b655ff445c6056c20887684e7b1bc89 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=B8=80=E4=B8=9D?= Date: Tue, 30 Jun 2015 22:44:16 +0800 Subject: [PATCH 267/795] styles to css --- index.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/index.js b/index.js index a13c860041..17ee6149c0 100644 --- a/index.js +++ b/index.js @@ -26,9 +26,9 @@ module.exports = postcss.plugin("postcss-custom-selectors", function(options) { /** * 读取和替换自定义选择器 */ - return function(styles) { + return function(css) { // 读取自定义选择器 - styles.eachAtRule(function(rule) { + css.eachAtRule(function(rule) { if (rule.name !== "custom-selector") { return } @@ -54,7 +54,7 @@ module.exports = postcss.plugin("postcss-custom-selectors", function(options) { }) // 转换自定义的选择器别名 - styles.eachRule(function(rule) { + css.eachRule(function(rule) { var flag = 0 for (var prop in customSelectors) { if (rule.selector.indexOf(prop) >= 0) { From e202b8b2d78fa270ba61add39045a2f22f7cd807 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=B8=80=E4=B8=9D?= Date: Tue, 30 Jun 2015 23:02:24 +0800 Subject: [PATCH 268/795] Publish 2.1.1 --- CHANGELOG.md | 7 ++++++- package.json | 2 +- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 897aaf8851..91a415c364 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,11 @@ +# 2.1.0 - 2015-06-30 + +* \- Fixed: the lineBreak option keeping the selectors indent #18. +* \- Fixed: the tip of an undefined selector #20. + # 2.1.0 - 2015-06-04 -* \- Fixed: Use PostCSS 4.1 plugin API. +* \- Fixed: use PostCSS 4.1 plugin API. # 2.0.1 - 2015-06-03 diff --git a/package.json b/package.json index 63b1fc627e..93561d0d59 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "postcss-custom-selectors", - "version": "2.1.0", + "version": "2.1.1", "description": "PostCSS plugin to transform W3C CSS Extensions(Custom Selectors) to more compatible CSS", "keywords": [ "css", From 721c576757c8b89b6960300b46c06ddfc5f54f85 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=B8=80=E4=B8=9D?= Date: Tue, 30 Jun 2015 23:10:33 +0800 Subject: [PATCH 269/795] Update CHANGELOG.md --- CHANGELOG.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 91a415c364..f94f66bee5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,7 +1,7 @@ # 2.1.0 - 2015-06-30 -* \- Fixed: the lineBreak option keeping the selectors indent #18. -* \- Fixed: the tip of an undefined selector #20. +* \- Fixed: the lineBreak option keeping the selectors indent [#18](https://github.com/postcss/postcss-custom-selectors/issues/18). +* \- Fixed: the tip of an undefined selector [#20](https://github.com/postcss/postcss-custom-selectors/issues/20). # 2.1.0 - 2015-06-04 From ac9a18c7c3bf542f12e17447e7094074101f7577 Mon Sep 17 00:00:00 2001 From: Maxime Thirouin Date: Tue, 30 Jun 2015 22:47:49 +0200 Subject: [PATCH 270/795] Fixed: No more useless warnings for undefined non custom selectors Also: - Changed: simpler message when a custom selector is undefined - Changed: warnings now use PostCSS message API - Some fixes in the Changelog + simpler formatting - Added some references in the Changelog Prepared as 2.2.0 Close #22 --- CHANGELOG.md | 31 +++++++++---- index.js | 56 ++++++++++++------------ package.json | 2 +- test/fixtures/similar-matches/input.css | 4 ++ test/fixtures/similar-matches/output.css | 4 ++ test/index.js | 16 +++++-- 6 files changed, 72 insertions(+), 41 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f94f66bee5..6b1494b750 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,29 +1,42 @@ -# 2.1.0 - 2015-06-30 +# 2.2.0 - 2015-06-30 -* \- Fixed: the lineBreak option keeping the selectors indent [#18](https://github.com/postcss/postcss-custom-selectors/issues/18). -* \- Fixed: the tip of an undefined selector [#20](https://github.com/postcss/postcss-custom-selectors/issues/20). +* Fixed: No more useless warnings for undefined non custom selectors +([#22](https://github.com/postcss/postcss-custom-selectors/issues/22)) +* Changed: warnings now use PostCSS message API + +# 2.1.1 - 2015-06-30 + +* Fixed: the lineBreak option keeping the selectors indent +([#18](https://github.com/postcss/postcss-custom-selectors/issues/18)) +* Fixed: the tip of an undefined selector +([#20](https://github.com/postcss/postcss-custom-selectors/issues/20)) # 2.1.0 - 2015-06-04 -* \- Fixed: use PostCSS 4.1 plugin API. +* Changed: use PostCSS 4.1 plugin API +([#13](https://github.com/postcss/postcss-custom-selectors/issues/13)) # 2.0.1 - 2015-06-03 -* \- Fixed: `(foo, bar)` conversion error exists in the selector(See also [:matches() test](test/fixtures/matches/input.css)). +* Fixed: `(foo, bar)` conversion error exists in the selector +(See also [:matches() test](test/fixtures/matches/input.css)) # 2.0.0 - 2015-05-29 -* \x Remove: no longer support `::` or `--` to defined a custom selectors, we must use the `:--` to defined it. +* Removed: no longer support `::` or `--` to defined a custom selectors, +you must use the syntax `:--` to define it. +([#6](https://github.com/postcss/postcss-custom-selectors/issues/6)) +* Fixed: two or more consecutive hyphens in selector don't output `undefined` +([#14](https://github.com/postcss/postcss-custom-selectors/issues/14)) -* \- Fixed: two or more consecutive hyphens in selector outputs is "undefined". # 1.1.1 - 2015-04-06 -* \- Fixed: add support for multilines definition +* Fixed: add support for multilines definition # 1.1.0 - 2014-12-06 -* \- Added: "lineBreak" option +* Added: "lineBreak" option # 1.0.0 - 2014-12-06 diff --git a/index.js b/index.js index 17ee6149c0..4140454e91 100644 --- a/index.js +++ b/index.js @@ -26,7 +26,7 @@ module.exports = postcss.plugin("postcss-custom-selectors", function(options) { /** * 读取和替换自定义选择器 */ - return function(css) { + return function(css, result) { // 读取自定义选择器 css.eachAtRule(function(rule) { if (rule.name !== "custom-selector") { @@ -55,39 +55,41 @@ module.exports = postcss.plugin("postcss-custom-selectors", function(options) { // 转换自定义的选择器别名 css.eachRule(function(rule) { - var flag = 0 - for (var prop in customSelectors) { - if (rule.selector.indexOf(prop) >= 0) { - customSelector = customSelectors[prop] + if (rule.selector.indexOf(":--") > -1) { + var flag = 0 + for (var prop in customSelectors) { + if (rule.selector.indexOf(prop) >= 0) { + customSelector = customSelectors[prop] - // $2 = (自定义的选择器名称) - rule.selector = rule.selector.replace(re_CUSTOM_SELECTOR, function($0, $1, $2, $3) { + // $2 = (自定义的选择器名称) + rule.selector = rule.selector.replace(re_CUSTOM_SELECTOR, function($0, $1, $2, $3) { - if ($2 === prop) { - var newSelector = customSelector.split(",").map(function(selector) { - return $1 + selector.trim() + $3 - }) + if ($2 === prop) { + var newSelector = customSelector.split(",").map(function(selector) { + return $1 + selector.trim() + $3 + }) - // 选择器不换行 - if (!options.lineBreak && options.lineBreak === false) { - line_break = " " - newSelector = newSelector.join("," + line_break) - } else { - // 选择器换行,同时替换多个换行为一个 - newSelector = newSelector.join("," + line_break + rule.before).replace(reBLANK_LINE, line_break) + // 选择器不换行 + if (!options.lineBreak && options.lineBreak === false) { + line_break = " " + newSelector = newSelector.join("," + line_break) + } else { + // 选择器换行,同时替换多个换行为一个 + newSelector = newSelector.join("," + line_break + rule.before).replace(reBLANK_LINE, line_break) + } + flag ++ + return newSelector } - flag ++ - return newSelector - } - else if ($2 !== prop) { - return $2 + else if ($2 !== prop) { + return $2 + } + }) + if(flag === 0){ + result.warn("The selector '" + rule.selector + "' is undefined", {node: rule}) } - }) + } } } - if(flag === 0){ - console.log("Warning: The selector '" + rule.selector + "' is undefined in CSS!") - } }) // 删除 @custom-selector diff --git a/package.json b/package.json index 93561d0d59..e1432720ef 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "postcss-custom-selectors", - "version": "2.1.1", + "version": "2.2.0", "description": "PostCSS plugin to transform W3C CSS Extensions(Custom Selectors) to more compatible CSS", "keywords": [ "css", diff --git a/test/fixtures/similar-matches/input.css b/test/fixtures/similar-matches/input.css index 9ed53695a5..dbc7543142 100644 --- a/test/fixtures/similar-matches/input.css +++ b/test/fixtures/similar-matches/input.css @@ -12,3 +12,7 @@ :--test p { display: block; } + +whatever { + display: block; +} diff --git a/test/fixtures/similar-matches/output.css b/test/fixtures/similar-matches/output.css index adff0a191b..1b86cc7595 100644 --- a/test/fixtures/similar-matches/output.css +++ b/test/fixtures/similar-matches/output.css @@ -9,3 +9,7 @@ h4 h5 h6 { :--test p { display: block; } + +whatever { + display: block; +} diff --git a/test/index.js b/test/index.js index bba9e1a6ad..f443bb2bec 100644 --- a/test/index.js +++ b/test/index.js @@ -13,15 +13,18 @@ function compareFixtures(t, name, msg, opts, postcssOpts) { //input postcssOpts.from = filename("fixtures/" + name + "/input") opts = opts || {} - var actual = postcss() + var result = postcss() .use(plugin(opts)) .process(read(postcssOpts.from), postcssOpts) - .css + + var actual = result.css //output var output = read(filename("fixtures/" + name + "/output")) //actual fs.writeFile(filename("fixtures/" + name + "/actual"), actual) t.equal(actual.trim(), output.trim(), msg) + + return result } test("@custom-selector", function(t) { @@ -30,10 +33,15 @@ test("@custom-selector", function(t) { compareFixtures(t, "multiline", "should transform multiline") compareFixtures(t, "some-hyphen", "should transform some hyphen") compareFixtures(t, "matches", "should transform matches selector") - compareFixtures(t, "similar-matches", "should transform matches selector") + var similarMatchesResult = compareFixtures(t, "similar-matches", "should transform matches selector") + t.ok( + similarMatchesResult.messages && similarMatchesResult.messages.length === 1, + "should add a message when a custom selectors is undefined" + ) + compareFixtures(t, "comment", "should transform comment") compareFixtures(t, "line-break", "should transform line break", { - lineBreak: false + lineBreak: false }) compareFixtures(t, "extension", "should transform local extensions", { From 2aee21d2ed06337e98192dbade2782a94614b738 Mon Sep 17 00:00:00 2001 From: Bogdan Chadkin Date: Wed, 1 Jul 2015 03:22:34 +0300 Subject: [PATCH 271/795] Upgrade to PostCSS 4.1.x --- CHANGELOG.md | 4 ++++ README.md | 2 +- index.js | 31 +++++++++---------------------- package.json | 11 +++++------ 4 files changed, 19 insertions(+), 29 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f4168db2ff..5f634b71aa 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,7 @@ +# 1.2.0 - 2015-07-01 + +- Upgrade to PostCSS 4.1.x + # 1.1.0 - 2014-11-25 - Enhanced exceptions diff --git a/README.md b/README.md index c73bb40afa..f8c56fd2f3 100755 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@ ## Why this plugin ? -If you did some CSS, I'm sure you know who [Eric Meyer](https://en.wikipedia.org/wiki/Eric_A._Meyer) is, & what he did for this language. +If you did some CSS, I'm sure you know who [Eric Meyer](https://en.wikipedia.org/wiki/Eric_A._Meyer) is, & what he did for this language. In memory of [Eric Meyer’s daughter](http://meyerweb.com/eric/thoughts/2014/06/09/in-memoriam-2/), [W3C added new color rebeccapurple to CSS 4 Color Module](http://lists.w3.org/Archives/Public/www-style/2014Jun/0312.html). ## Installation diff --git a/index.js b/index.js index d5c72d2ad7..7a36d07867 100755 --- a/index.js +++ b/index.js @@ -1,33 +1,20 @@ /** * Module dependencies. */ -var color = require("color") -var helpers = require("postcss-message-helpers") +var postcss = require("postcss") +var color = require("color")("rebeccapurple").rgbString() /** * PostCSS plugin to convert colors */ -module.exports = function plugin() { +module.exports = postcss.plugin("postcss-color-rebeccapurple", function() { return function(style) { - style.eachDecl(function transformDecl(decl) { - if (!decl.value || decl.value.indexOf("rebeccapurple") === -1) { - return - } + style.eachDecl(function(decl) { + var value = decl.value; - decl.value = helpers.try(function transformRebeccapurpleValue() { - return transformRebeccapurple(decl.value) - }, decl.source) + if (value && value.indexOf("rebeccapurple") !== -1) { + decl.value = value.replace(/(rebeccapurple)\b/gi, color) + } }) } -} - - -/** - * Transform rebeccapurple color to rgb() - * - * @param {String} string declaration value - * @return {String} converted declaration value to rgba() - */ -function transformRebeccapurple(string) { - return string.replace(/(rebeccapurple)\b/gi, color("rebeccapurple").rgbString()) -} +}) diff --git a/package.json b/package.json index 4cece28885..d8e58f2c0d 100644 --- a/package.json +++ b/package.json @@ -1,11 +1,11 @@ { "name": "postcss-color-rebeccapurple", - "version": "1.1.0", + "version": "1.2.0", "description": "PostCSS plugin to transform W3C CSS rebeccapurple color to more compatible CSS (rgb())", "keywords": [ "css", "postcss", - "postcss-plugins", + "postcss-plugin", "color", "colour", "rgb", @@ -23,14 +23,13 @@ "index.js" ], "dependencies": { - "color": "^0.7.1", - "postcss-message-helpers": "^1.1.0" + "color": "^0.9.0", + "postcss": "^4.1.13" }, "devDependencies": { "jscs": "^1.6.2", "jshint": "^2.5.6", - "postcss": "^4.0.2", - "tape": "^3.0.0" + "tape": "^4.0.0" }, "scripts": { "lint": "jscs *.js **/*.js && jshint . --exclude-path .gitignore", From 01c316292df75a25a71efb1552fbb92e0f35f6e7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=B8=80=E4=B8=9D?= Date: Wed, 1 Jul 2015 10:25:54 +0800 Subject: [PATCH 272/795] Format --- test/fixtures/similar-matches/input.css | 2 +- test/fixtures/similar-matches/output.css | 2 +- test/index.js | 49 +++++++++++++----------- 3 files changed, 28 insertions(+), 25 deletions(-) diff --git a/test/fixtures/similar-matches/input.css b/test/fixtures/similar-matches/input.css index dbc7543142..2703673796 100644 --- a/test/fixtures/similar-matches/input.css +++ b/test/fixtures/similar-matches/input.css @@ -13,6 +13,6 @@ display: block; } -whatever { +.whatever { display: block; } diff --git a/test/fixtures/similar-matches/output.css b/test/fixtures/similar-matches/output.css index 1b86cc7595..2213e6b08b 100644 --- a/test/fixtures/similar-matches/output.css +++ b/test/fixtures/similar-matches/output.css @@ -10,6 +10,6 @@ h4 h5 h6 { display: block; } -whatever { +.whatever { display: block; } diff --git a/test/index.js b/test/index.js index f443bb2bec..15e6143760 100644 --- a/test/index.js +++ b/test/index.js @@ -1,26 +1,29 @@ -var fs = require("fs") - -var test = require("tape") - +var fs = require("fs") +var test = require("tape") var postcss = require("postcss") -var plugin = require("..") +var plugin = require("..") -function filename(name) { return "test/" + name + ".css" } -function read(name) { return fs.readFileSync(name, "utf8") } +function filename(name) { + return "test/" + name + ".css" +} + +function read(name) { + return fs.readFileSync(name, "utf8") +} function compareFixtures(t, name, msg, opts, postcssOpts) { postcssOpts = postcssOpts || {} - //input + //input postcssOpts.from = filename("fixtures/" + name + "/input") opts = opts || {} var result = postcss() - .use(plugin(opts)) - .process(read(postcssOpts.from), postcssOpts) + .use(plugin(opts)) + .process(read(postcssOpts.from), postcssOpts) var actual = result.css - //output + //output var output = read(filename("fixtures/" + name + "/output")) - //actual + //actual fs.writeFile(filename("fixtures/" + name + "/actual"), actual) t.equal(actual.trim(), output.trim(), msg) @@ -28,25 +31,25 @@ function compareFixtures(t, name, msg, opts, postcssOpts) { } test("@custom-selector", function(t) { - compareFixtures(t, "heading", "should transform heading") - compareFixtures(t, "pseudo", "should transform pseudo") - compareFixtures(t, "multiline", "should transform multiline") - compareFixtures(t, "some-hyphen", "should transform some hyphen") - compareFixtures(t, "matches", "should transform matches selector") - var similarMatchesResult = compareFixtures(t, "similar-matches", "should transform matches selector") + compareFixtures(t, "heading", "Should transform heading") + compareFixtures(t, "pseudo", "Should transform pseudo") + compareFixtures(t, "multiline", "Should transform multiline") + compareFixtures(t, "some-hyphen", "Should transform some hyphen") + compareFixtures(t, "matches", "Should transform matches selector") + var similarMatchesResult = compareFixtures(t, "similar-matches", "Should transform matches selector") t.ok( similarMatchesResult.messages && similarMatchesResult.messages.length === 1, - "should add a message when a custom selectors is undefined" + "Should add a message when a custom selectors is undefined" ) - compareFixtures(t, "comment", "should transform comment") - compareFixtures(t, "line-break", "should transform line break", { + compareFixtures(t, "comment", "Should transform comment") + compareFixtures(t, "line-break", "Should transform line break", { lineBreak: false }) - compareFixtures(t, "extension", "should transform local extensions", { + compareFixtures(t, "extension", "Should transform local extensions", { extensions: { - ':--any' : 'section, article, aside, nav', + ':--any': 'section, article, aside, nav', ':--foo': 'input[type="text"] > section, #nav .bar' } }) From d4a9e2d168fb346b7e23f47f7254c74a13a57896 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=B8=80=E4=B8=9D?= Date: Wed, 1 Jul 2015 10:33:25 +0800 Subject: [PATCH 273/795] Add contributor --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6b1494b750..7752d6bd45 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,4 @@ -# 2.2.0 - 2015-06-30 +# 2.2.0 - 2015-06-30 (By @MoOx) * Fixed: No more useless warnings for undefined non custom selectors ([#22](https://github.com/postcss/postcss-custom-selectors/issues/22)) From f8f3d8d91dcbb0c3d50a949f331a5eaf76161913 Mon Sep 17 00:00:00 2001 From: Maxime Thirouin Date: Fri, 3 Jul 2015 11:16:08 +0200 Subject: [PATCH 274/795] Update README.md --- README.md | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 636301f626..0befc98033 100755 --- a/README.md +++ b/README.md @@ -1,13 +1,17 @@ # postcss-custom-properties [![Build Status](https://travis-ci.org/postcss/postcss-custom-properties.png)](https://travis-ci.org/postcss/postcss-custom-properties) -> [PostCSS](https://github.com/postcss/postcss) plugin to transform [W3C CSS Custom Properties for cascading variables](http://www.w3.org/TR/css-variables/) syntax to more compatible CSS. +> [PostCSS](https://github.com/postcss/postcss) plugin to transform [W3C CSS Custom Properties for ~~cascading~~ variables](http://www.w3.org/TR/css-variables/) syntax to more compatible CSS. -**N.B.** The transformation _is not complete and **cannot be** (dynamic variables based on custom properties relies on the DOM tree)_. It currently just aims to provide a future-proof way of using a **limited subset (to top-level `:root` selector)** of the features provided by native CSS custom properties. -_Read [#1](https://github.com/postcss/postcss-custom-properties/issues/1) & [#9](https://github.com/postcss/postcss-custom-properties/issues/9) to know why this limitation exists._ +_Per w3c specifications, the usage of `var()` is limited to property values. Do not expect the plugin to transform `var()` in media queries or in selectors._ + +**N.B.** The transformation _is not complete and **cannot be** (dynamic _cascading_ variables based on custom properties relies on the DOM tree)_. +It currently just aims to provide a future-proof way of using a **limited subset (to `:root` selector)** of the features provided by native CSS custom properties. +_Since we do not know the DOM in the context of this plugin, we cannot produce safe output_. +Read [#1](https://github.com/postcss/postcss-custom-properties/issues/1) & [#9](https://github.com/postcss/postcss-custom-properties/issues/9) to know why this limitation exists. _If you are looking for a full support of CSS custom properties, please follow [the opened issue for runtime support](https://github.com/postcss/postcss-custom-properties/issues/32)._ -**N.B.²** If you are wondering why there is a different plugin ([`postcss-css-variables`](https://github.com/MadLittleMods/postcss-css-variables)) that claims to do more than this plugin, be sure to understand the explanation above about limitation. This plugins have a behavior that is not reflecting the specifications. [You should check some (closed) issues of this plugin](https://github.com/MadLittleMods/postcss-css-variables/issues?utf8=%E2%9C%93&q=is%3Aissue+is%3Aclosed+-label%3Ainvalid+author%3AMoOx+). +**N.B.²** If you are wondering why there is a different plugin ([`postcss-css-variables`](https://github.com/MadLittleMods/postcss-css-variables)) that claims to do more than this plugin, be sure to understand the explanation above about limitation. This plugins have a behavior that is not [reflecting the specifications](https://github.com/MadLittleMods/postcss-css-variables/issues/4). _This plugin works great with [postcss-calc](https://github.com/postcss/postcss-calc)._ From d56541bf2c59693be89fc3a4156d43a36621f16e Mon Sep 17 00:00:00 2001 From: Maxime Thirouin Date: Fri, 3 Jul 2015 11:16:38 +0200 Subject: [PATCH 275/795] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 0befc98033..93fd03ac86 100755 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@ _Per w3c specifications, the usage of `var()` is limited to property values. Do not expect the plugin to transform `var()` in media queries or in selectors._ -**N.B.** The transformation _is not complete and **cannot be** (dynamic _cascading_ variables based on custom properties relies on the DOM tree)_. +**N.B.** The transformation _is not complete and **cannot be** (dynamic *cascading* variables based on custom properties relies on the DOM tree)_. It currently just aims to provide a future-proof way of using a **limited subset (to `:root` selector)** of the features provided by native CSS custom properties. _Since we do not know the DOM in the context of this plugin, we cannot produce safe output_. Read [#1](https://github.com/postcss/postcss-custom-properties/issues/1) & [#9](https://github.com/postcss/postcss-custom-properties/issues/9) to know why this limitation exists. From 83301e7ae5327a37491e33ff718aae87bb261cfb Mon Sep 17 00:00:00 2001 From: Maxime Thirouin Date: Fri, 3 Jul 2015 11:16:59 +0200 Subject: [PATCH 276/795] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 93fd03ac86..705798941c 100755 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@ _Per w3c specifications, the usage of `var()` is limited to property values. Do not expect the plugin to transform `var()` in media queries or in selectors._ -**N.B.** The transformation _is not complete and **cannot be** (dynamic *cascading* variables based on custom properties relies on the DOM tree)_. +**N.B.** The transformation _is not complete_ and **cannot be** (dynamic *cascading* variables based on custom properties relies on the DOM tree). It currently just aims to provide a future-proof way of using a **limited subset (to `:root` selector)** of the features provided by native CSS custom properties. _Since we do not know the DOM in the context of this plugin, we cannot produce safe output_. Read [#1](https://github.com/postcss/postcss-custom-properties/issues/1) & [#9](https://github.com/postcss/postcss-custom-properties/issues/9) to know why this limitation exists. From cb25d8f1b8a8f4a91460be31c65407df927bcc72 Mon Sep 17 00:00:00 2001 From: Andrey Sitnik Date: Mon, 6 Jul 2015 11:06:31 +0300 Subject: [PATCH 277/795] Use PostCSS 4.1 API --- index.js | 7 +++---- package.json | 6 ++++-- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/index.js b/index.js index 11bcb5e63b..46875f34f8 100644 --- a/index.js +++ b/index.js @@ -1,7 +1,6 @@ -module.exports = mediaMinmax +var postcss = require('postcss'); - -function mediaMinmax() { +module.exports = postcss.plugin('postcss-media-minmax', function () { return function(css) { //支持 min-/max- 前缀的属性 var feature_name = [ @@ -74,4 +73,4 @@ function mediaMinmax() { }); } -} +}); diff --git a/package.json b/package.json index 03f706ebad..aa0a13be38 100644 --- a/package.json +++ b/package.json @@ -13,7 +13,7 @@ "css", "css3", "postcss", - "postcss-plugins", + "postcss-plugin", "media querie", "media queries" ], @@ -26,8 +26,10 @@ "LICENSE", "index.js" ], + "dependencies": { + "postcss": "^4.1.14" + }, "devDependencies": { - "postcss": "^4.0.2", "tape": "^3.0.0" }, "bugs": { From 4ca6eebd33c91d274ac8a17bb7131c6bdb5198f0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=B8=80=E4=B8=9D?= Date: Mon, 6 Jul 2015 19:15:34 +0800 Subject: [PATCH 278/795] add more shields --- README-zh.md | 7 ++++++- README.md | 6 +++++- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/README-zh.md b/README-zh.md index 1471d52ba3..2ed34a69af 100644 --- a/README-zh.md +++ b/README-zh.md @@ -1,4 +1,9 @@ -# PostCSS Media Minmax [![Build Status](https://travis-ci.org/postcss/postcss-media-minmax.svg)](https://travis-ci.org/postcss/postcss-media-minmax) +# PostCSS Media Minmax + +[![Build Status](https://travis-ci.org/postcss/postcss-media-minmax.svg?branch=master)](https://travis-ci.org/postcss/postcss-media-minmax) +[![NPM Downloads](https://img.shields.io/npm/dm/postcss-media-minmax.svg?style=flat)](https://www.npmjs.com/package/postcss-media-minmax) +[![NPM Version](http://img.shields.io/npm/v/postcss-media-minmax.svg?style=flat)](https://www.npmjs.com/package/postcss-media-minmax) +[![License](https://img.shields.io/npm/l/postcss-media-minmax.svg?style=flat)](http://opensource.org/licenses/MIT) > 写简单优雅的 Media Queries! diff --git a/README.md b/README.md index 8d902cde73..339210c9e6 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,9 @@ -# PostCSS Media Minmax [![Build Status](https://travis-ci.org/postcss/postcss-media-minmax.svg)](https://travis-ci.org/postcss/postcss-media-minmax) +# PostCSS Media Minmax +[![Build Status](https://travis-ci.org/postcss/postcss-media-minmax.svg?branch=master)](https://travis-ci.org/postcss/postcss-media-minmax) +[![NPM Downloads](https://img.shields.io/npm/dm/postcss-media-minmax.svg?style=flat)](https://www.npmjs.com/package/postcss-media-minmax) +[![NPM Version](http://img.shields.io/npm/v/postcss-media-minmax.svg?style=flat)](https://www.npmjs.com/package/postcss-media-minmax) +[![License](https://img.shields.io/npm/l/postcss-media-minmax.svg?style=flat)](http://opensource.org/licenses/MIT) > Writing simple and graceful media queries! From f8b784171a8712847f32c365737942941af7609a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=B8=80=E4=B8=9D?= Date: Mon, 6 Jul 2015 19:18:30 +0800 Subject: [PATCH 279/795] release 1.2.0 --- CHANGELOG.md | 6 +++++- package.json | 2 +- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1c7b68395d..29104f332f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,8 @@ -# 1.1.0 +# 1.2.0 2015-07-06 + +Use PostCSS 4.1 plugin API. + +# 1.1.0 2014-12-15 Add `( 300px <= width <= 900px)` or `( 900px >= width >= 300px)` syntax. diff --git a/package.json b/package.json index aa0a13be38..22a6959f62 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "postcss-media-minmax", - "version": "1.1.0", + "version": "1.2.0", "description": "Using more intuitive `>=` or `<=` instead of media queries min/max prefix.", "scripts": { "test": "tape test" From ee42cbb5c95ef2fa9792a8e1803d306cd6c3ec37 Mon Sep 17 00:00:00 2001 From: Semigradsky Date: Thu, 9 Jul 2015 10:28:52 +0300 Subject: [PATCH 280/795] Changed `similar-matches` test. Added `multiple` test. --- test/fixtures/multiple/input.css | 5 +++++ test/fixtures/multiple/output.css | 3 +++ test/fixtures/similar-matches/input.css | 4 ++-- test/fixtures/similar-matches/output.css | 2 +- test/index.js | 2 ++ 5 files changed, 13 insertions(+), 3 deletions(-) create mode 100644 test/fixtures/multiple/input.css create mode 100644 test/fixtures/multiple/output.css diff --git a/test/fixtures/multiple/input.css b/test/fixtures/multiple/input.css new file mode 100644 index 0000000000..75fe80324a --- /dev/null +++ b/test/fixtures/multiple/input.css @@ -0,0 +1,5 @@ +@custom-selector :--foo .foo; + +:--foo, :--foo.bar { + color: white; +} diff --git a/test/fixtures/multiple/output.css b/test/fixtures/multiple/output.css new file mode 100644 index 0000000000..3da3e23292 --- /dev/null +++ b/test/fixtures/multiple/output.css @@ -0,0 +1,3 @@ +.foo, .foo.bar { + color: white; +} diff --git a/test/fixtures/similar-matches/input.css b/test/fixtures/similar-matches/input.css index 2703673796..afa9056b16 100644 --- a/test/fixtures/similar-matches/input.css +++ b/test/fixtures/similar-matches/input.css @@ -1,11 +1,11 @@ @custom-selector :--foo h1; -@custom-selector :--foo-bar-baz h4 h5 h6; +@custom-selector :--foo-bar-baz h4, h5, h6; :--foo { color: red; } -:--foo-bar-baz { +:--foo-bar-baz > span { color: blue; } diff --git a/test/fixtures/similar-matches/output.css b/test/fixtures/similar-matches/output.css index 2213e6b08b..f4b0f33603 100644 --- a/test/fixtures/similar-matches/output.css +++ b/test/fixtures/similar-matches/output.css @@ -2,7 +2,7 @@ h1 { color: red; } -h4 h5 h6 { +h4 > span, h5 > span, h6 > span { color: blue; } diff --git a/test/index.js b/test/index.js index 15e6143760..8b9a240df7 100644 --- a/test/index.js +++ b/test/index.js @@ -54,5 +54,7 @@ test("@custom-selector", function(t) { } }) + compareFixtures(t, "multiple", "Should transform multiple selectors") + t.end() }) From e209388a2705cd83e439f5ac75dfa670ac6f99a5 Mon Sep 17 00:00:00 2001 From: Joey Baker Date: Mon, 13 Jul 2015 09:44:06 -0700 Subject: [PATCH 281/795] add: ability to set variables after initial load When using this module as part of a live-reload system, devs might change the variable list after the module has been loaded. This adds a `setVariables` method on the plugin to enable that functionality. --- index.js | 42 ++++++++++++++++++-------- test/fixtures/js-override.css | 13 ++++++++ test/fixtures/js-override.expected.css | 8 +++++ test/index.js | 27 +++++++++++++++++ 4 files changed, 78 insertions(+), 12 deletions(-) create mode 100755 test/fixtures/js-override.css create mode 100755 test/fixtures/js-override.expected.css diff --git a/index.js b/index.js index 8205c0b125..6c702a23fb 100755 --- a/index.js +++ b/index.js @@ -126,23 +126,37 @@ function resolveValue(value, variables, result, decl) { return results } +function prefixVariables(variables) { + var prefixedVariables = {} + + if (!variables) { + return prefixVariables + } + + Object.keys(variables).forEach(function(name) { + var val = variables[name] + if (name.slice(0, 2) !== "--") { + name = "--" + name + } + prefixedVariables[name] = String(val) + }) + + return prefixedVariables +} + /** * Module export. */ module.exports = postcss.plugin("postcss-custom-properties", function(options) { - return function(style, result) { - options = options || {} - var variables = {} - if (options.variables) { - Object.keys(options.variables).forEach(function(name) { - var val = options.variables[name] - if (name.slice(0, 2) !== "--") { - name = "--" + name - } - variables[name] = String(val) - }) - } + options = options || {} + + function setVariables(variables) { + options.variables = prefixVariables(variables) + } + + function plugin(style, result) { + var variables = prefixVariables(options.variables) var strict = options.strict === undefined ? true : options.strict var appendVariables = options.appendVariables var preserve = options.preserve @@ -268,4 +282,8 @@ module.exports = postcss.plugin("postcss-custom-properties", function(options) { } } } + + plugin.setVariables = setVariables + + return plugin }) diff --git a/test/fixtures/js-override.css b/test/fixtures/js-override.css new file mode 100755 index 0000000000..8c4fedc728 --- /dev/null +++ b/test/fixtures/js-override.css @@ -0,0 +1,13 @@ +:root { + --test-one: local; + --test-two: local; +} + +div { + p: var(--test-one); + p: var(--test-two); + p: var(--test-three); + p: var(--test-varception); + p: var(--test-jsception); + p: var(--test-num); +} diff --git a/test/fixtures/js-override.expected.css b/test/fixtures/js-override.expected.css new file mode 100755 index 0000000000..d043e0bf13 --- /dev/null +++ b/test/fixtures/js-override.expected.css @@ -0,0 +1,8 @@ +div { + p: js-one; + p: js-two; + p: js-three; + p: js-one; + p: js-one; + p: 1; +} diff --git a/test/index.js b/test/index.js index bcba3608ac..ca0547798e 100755 --- a/test/index.js +++ b/test/index.js @@ -110,6 +110,33 @@ test( } ) +test("allows users to programatically change the variables", function(t) { + var variables = { + "--test-one": "js-one", + "--test-two": "js-two", + "--test-three": "js-three", + "--test-varception": "var(--test-one)", + "--test-jsception": "var(--test-varception)", + "--test-num": 1, + } + var plugin = customProperties() + var name = "js-override" + var expected = fs.readFileSync(fixturePath(name + ".expected"), "utf8").trim() + var actual + + plugin.setVariables(variables) + + actual = postcss(plugin) + .process(fixture(name), {from: fixturePath(name)}).css.trim() + + t.equal( + actual, expected, + "processed fixture '" + name + "' should be equal to expected output" + ) + + t.end() +}) + test("removes variable properties from the output", function(t) { compareFixtures(t, "remove-properties") t.end() From 36a25f73cd5b48b580719b01ac22d23d08fbce60 Mon Sep 17 00:00:00 2001 From: Maxime Thirouin Date: Tue, 14 Jul 2015 07:26:56 +0200 Subject: [PATCH 282/795] Added: plugin now expose `replaceRuleSelector` to make it easy to reuse in some others plugins (like `postcss-custom-selectors`) (1.2.0) - Fixed: indentation adjustment doesn't contain useless new lines - Fixed: transformation doesn't add some useless whitespace --- CHANGELOG.md | 7 ++++++ package.json | 2 +- src/index.js | 60 +++++++++++++++++++++++++++++++++------------------ test/index.js | 30 ++++++++++++++++++++++++-- 4 files changed, 75 insertions(+), 24 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f1034b616c..92832c37b6 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,10 @@ +# 1.2.0 - 2015-07-14 + +- Fixed: indentation adjustment doesn't contain useless new lines +- Fixed: transformation doesn't add some useless whitespace +- Added: plugin now expose `replaceRuleSelector` to make it easy to reuse in +some others plugins (like `postcss-custom-selectors`). + # 1.1.2 - 2015-06-29 - Fixed: support pseudo-element that might be collapsed to :matches() diff --git a/package.json b/package.json index 355dd6939f..3b392066e7 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "postcss-selector-matches", - "version": "1.1.2", + "version": "1.2.0", "description": "PostCSS plugin to transform :matches() W3C CSS pseudo class to more compatible CSS selectors", "keywords": [ "postcss", diff --git a/src/index.js b/src/index.js index 4b3c765d52..451736977c 100644 --- a/src/index.js +++ b/src/index.js @@ -3,9 +3,15 @@ import list from "postcss/lib/list" import balancedMatch from "balanced-match" -function explodeSelector(pseudoClass, selector, options) { +const pseudoClass = ":matches" + +function explodeSelector(selector, options) { if (selector && selector.indexOf(pseudoClass) > -1) { let newSelectors = [] + const preWhitespaceMatches = selector.match(/^\s+/) + const preWhitespace = preWhitespaceMatches + ? preWhitespaceMatches[0] + : "" const selectorPart = list.comma(selector) selectorPart.forEach(part => { const position = part.indexOf(pseudoClass) @@ -18,27 +24,23 @@ function explodeSelector(pseudoClass, selector, options) { .comma(matches.body) .reduce((acc, s) => [ ...acc, - ...explodeSelector(pseudoClass, s, options), + ...explodeSelector(s, options), ], []) : [body] const postSelectors = matches && matches.post - ? explodeSelector(pseudoClass, matches.post, options) + ? explodeSelector(matches.post, options) : [] let newParts if (postSelectors.length === 0) { - newParts = bodySelectors.map((s) => pre + s) + newParts = bodySelectors.map((s) => preWhitespace + pre + s) } else { - const postWhitespaceMatches = matches.post.match(/^\s+/) - const postWhitespace = postWhitespaceMatches - ? postWhitespaceMatches[0] - : "" newParts = [] postSelectors.forEach(postS => { bodySelectors.forEach(s => { - newParts.push(pre + s + postWhitespace + postS) + newParts.push(pre + s + postS) }) }) } @@ -53,20 +55,36 @@ function explodeSelector(pseudoClass, selector, options) { return [selector] } -function explodeSelectors(pseudoClass) { - return (options = {}) => { - return (css) => { - css.eachRule(rule => { - if (rule.selector && rule.selector.indexOf(pseudoClass) > -1) { - rule.selector = explodeSelector(pseudoClass, rule.selector, options) - .join("," + (options.lineBreak ? "\n" + rule.before : " ")) - } - }) - } +function replaceRuleSelector(rule, options) { + const indentation = rule.before + ? rule.before.split("\n").pop() + : "" + return ( + explodeSelector(rule.selector, options) + .join("," + (options.lineBreak ? "\n" + indentation : " ")) + ) + +} + +function explodeSelectors(options = {}) { + return (css) => { + css.eachRule(rule => { + if (rule.selector && rule.selector.indexOf(pseudoClass) > -1) { + rule.selector = replaceRuleSelector(rule, options) + } + }) } + } -export default postcss.plugin( +const plugin = postcss.plugin( "postcss-selector-matches", - explodeSelectors(":matches") + explodeSelectors ) + +// expose for postcss-custom-selectors +export {replaceRuleSelector} +// old school fallback +plugin.replaceRuleSelector = replaceRuleSelector + +export default plugin diff --git a/test/index.js b/test/index.js index 895fff483b..6d6daa63d8 100644 --- a/test/index.js +++ b/test/index.js @@ -1,13 +1,19 @@ import tape from "tape" import postcss from "postcss" -import selectorMatches from "../src/index.js" +import plugin, {replaceRuleSelector} from "../src" function transform(css, options = {}) { - return postcss(selectorMatches(options)).process(css).css + return postcss(plugin(options)).process(css).css } tape("postcss-selector-matches", t => { + t.ok( + typeof replaceRuleSelector === "function" && + typeof plugin.replaceRuleSelector === "function", + "expose 'replaceRuleSelector' function (for postcss-custom-selectors)" + ) + t.equal( transform("body {}"), "body {}", @@ -89,6 +95,12 @@ tape("postcss-selector-matches", t => { "should add line break if asked too, and respect indentation" ) + t.equal( + transform("\n .foo:matches(:nth-child(-n+2), .bar) {}", {lineBreak: true}), + "\n .foo:nth-child(-n+2),\n .foo.bar {}", + "should add line break if asked too, and respect indentation even with \n" + ) + t.equal( transform(` button:matches(:hover, :active), @@ -104,5 +116,19 @@ button:hover, button:active, .button:hover, .button:active {}`, "should work with something after :matches()" ) + t.equal( + transform(`article :matches(h1, h2, h3) + p {}`), + `article h1 + p, article h2 + p, article h3 + p {}`, + "should works correctly with adjacent selectors" + ) + + t.equal( + transform(`article :matches(h1, h2, h3) + p {}`, {lineBreak: true}), + `article h1 + p, +article h2 + p, +article h3 + p {}`, + "should works correctly with adjacent selectors and line break" + ) + t.end() }) From 6ccf4a98ad45288fea6fe61c2bab1859915dd9d6 Mon Sep 17 00:00:00 2001 From: Maxime Thirouin Date: Tue, 14 Jul 2015 07:52:08 +0200 Subject: [PATCH 283/795] 4.1.0 --- CHANGELOG.md | 6 ++++++ README.md | 16 ++++++++++++++++ package.json | 2 +- test/index.js | 2 +- 4 files changed, 24 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2ad2b552d0..b221624692 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,9 @@ +# 4.1.0 - 2015-07-14 + +- Added: plugin now returns itself in order to expose a `setVariables` function +that allow you to programmatically change the variables. +([#35](https://github.com/postcss/postcss-custom-properties/pull/35)) + # 4.0.0 - 2015-06-17 - Changed: messages and exceptions are now sent using postcss message API. diff --git a/README.md b/README.md index 705798941c..8fc199fb9a 100755 --- a/README.md +++ b/README.md @@ -59,6 +59,22 @@ div { } ``` +Note that plugin returns itself in order to expose a `setVariables` function +that allow you to programmatically change the variables. + +```js +var variables = { + "--a": "b", +} +var plugin = customProperties() +plugin.setVariables(variables) +var result = postcss() + .use(plugin) + .process(input) +``` + +This might help for dynamic live/hot reloading. + Checkout [tests](test) for more. ### Options diff --git a/package.json b/package.json index e1f78b4b5b..15226d129e 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "postcss-custom-properties", - "version": "4.0.0", + "version": "4.1.0", "description": "PostCSS plugin to polyfill W3C CSS Custom Properties for cascading variables", "keywords": [ "css", diff --git a/test/index.js b/test/index.js index ca0547798e..5c713ad437 100755 --- a/test/index.js +++ b/test/index.js @@ -110,7 +110,7 @@ test( } ) -test("allows users to programatically change the variables", function(t) { +test("allows users to programmatically change the variables", function(t) { var variables = { "--test-one": "js-one", "--test-two": "js-two", From afe918c5c5fa4eacb3d49eb9864207b02bda97c7 Mon Sep 17 00:00:00 2001 From: Maxime Thirouin Date: Tue, 14 Jul 2015 10:32:52 +0200 Subject: [PATCH 284/795] Fixed: plugin is correctly exposed for normal commonjs environments (!babel) (1.2.1) Close #5 --- CHANGELOG.md | 5 +++ package.json | 2 +- src/index.js | 78 ++------------------------------------ src/replaceRuleSelector.js | 65 +++++++++++++++++++++++++++++++ test/index.js | 6 +-- 5 files changed, 77 insertions(+), 79 deletions(-) create mode 100644 src/replaceRuleSelector.js diff --git a/CHANGELOG.md b/CHANGELOG.md index 92832c37b6..4fe4430f29 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,8 @@ +# 1.2.1 - 2015-07-14 + +- Fixed: plugin is correctly exposed for normal commonjs environments (!babel) +([#5](https://github.com/postcss/postcss-selector-matches/issues/5)) + # 1.2.0 - 2015-07-14 - Fixed: indentation adjustment doesn't contain useless new lines diff --git a/package.json b/package.json index 3b392066e7..402b7cdec5 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "postcss-selector-matches", - "version": "1.2.0", + "version": "1.2.1", "description": "PostCSS plugin to transform :matches() W3C CSS pseudo class to more compatible CSS selectors", "keywords": [ "postcss", diff --git a/src/index.js b/src/index.js index 451736977c..b701ca79bc 100644 --- a/src/index.js +++ b/src/index.js @@ -1,75 +1,10 @@ import postcss from "postcss" -import list from "postcss/lib/list" - -import balancedMatch from "balanced-match" - -const pseudoClass = ":matches" - -function explodeSelector(selector, options) { - if (selector && selector.indexOf(pseudoClass) > -1) { - let newSelectors = [] - const preWhitespaceMatches = selector.match(/^\s+/) - const preWhitespace = preWhitespaceMatches - ? preWhitespaceMatches[0] - : "" - const selectorPart = list.comma(selector) - selectorPart.forEach(part => { - const position = part.indexOf(pseudoClass) - const pre = part.slice(0, position) - const body = part.slice(position) - const matches = balancedMatch("(", ")", body) - - const bodySelectors = matches && matches.body ? - list - .comma(matches.body) - .reduce((acc, s) => [ - ...acc, - ...explodeSelector(s, options), - ], []) - : [body] - - const postSelectors = matches && matches.post - ? explodeSelector(matches.post, options) - : [] - - let newParts - if (postSelectors.length === 0) { - newParts = bodySelectors.map((s) => preWhitespace + pre + s) - } - else { - newParts = [] - postSelectors.forEach(postS => { - bodySelectors.forEach(s => { - newParts.push(pre + s + postS) - }) - }) - } - newSelectors = [ - ...newSelectors, - ...newParts, - ] - }) - - return newSelectors - } - return [selector] -} - -function replaceRuleSelector(rule, options) { - const indentation = rule.before - ? rule.before.split("\n").pop() - : "" - return ( - explodeSelector(rule.selector, options) - .join("," + (options.lineBreak ? "\n" + indentation : " ")) - ) - -} +import replaceRuleSelector from "./replaceRuleSelector" function explodeSelectors(options = {}) { return (css) => { css.eachRule(rule => { - if (rule.selector && rule.selector.indexOf(pseudoClass) > -1) { + if (rule.selector && rule.selector.indexOf(":matches") > -1) { rule.selector = replaceRuleSelector(rule, options) } }) @@ -77,14 +12,7 @@ function explodeSelectors(options = {}) { } -const plugin = postcss.plugin( +export default postcss.plugin( "postcss-selector-matches", explodeSelectors ) - -// expose for postcss-custom-selectors -export {replaceRuleSelector} -// old school fallback -plugin.replaceRuleSelector = replaceRuleSelector - -export default plugin diff --git a/src/replaceRuleSelector.js b/src/replaceRuleSelector.js new file mode 100644 index 0000000000..1f02b0bd2d --- /dev/null +++ b/src/replaceRuleSelector.js @@ -0,0 +1,65 @@ +import list from "postcss/lib/list" + +import balancedMatch from "balanced-match" + +const pseudoClass = ":matches" + +function explodeSelector(selector, options) { + if (selector && selector.indexOf(pseudoClass) > -1) { + let newSelectors = [] + const preWhitespaceMatches = selector.match(/^\s+/) + const preWhitespace = preWhitespaceMatches + ? preWhitespaceMatches[0] + : "" + const selectorPart = list.comma(selector) + selectorPart.forEach(part => { + const position = part.indexOf(pseudoClass) + const pre = part.slice(0, position) + const body = part.slice(position) + const matches = balancedMatch("(", ")", body) + + const bodySelectors = matches && matches.body ? + list + .comma(matches.body) + .reduce((acc, s) => [ + ...acc, + ...explodeSelector(s, options), + ], []) + : [body] + + const postSelectors = matches && matches.post + ? explodeSelector(matches.post, options) + : [] + + let newParts + if (postSelectors.length === 0) { + newParts = bodySelectors.map((s) => preWhitespace + pre + s) + } + else { + newParts = [] + postSelectors.forEach(postS => { + bodySelectors.forEach(s => { + newParts.push(pre + s + postS) + }) + }) + } + newSelectors = [ + ...newSelectors, + ...newParts, + ] + }) + + return newSelectors + } + return [selector] +} + +export default function replaceRuleSelector(rule, options) { + const indentation = rule.before + ? rule.before.split("\n").pop() + : "" + return ( + explodeSelector(rule.selector, options) + .join("," + (options.lineBreak ? "\n" + indentation : " ")) + ) +} diff --git a/test/index.js b/test/index.js index 6d6daa63d8..da65fab245 100644 --- a/test/index.js +++ b/test/index.js @@ -1,7 +1,8 @@ import tape from "tape" import postcss from "postcss" -import plugin, {replaceRuleSelector} from "../src" +import plugin from "../src" +import replaceRuleSelector from "../src/replaceRuleSelector" function transform(css, options = {}) { return postcss(plugin(options)).process(css).css @@ -9,8 +10,7 @@ function transform(css, options = {}) { tape("postcss-selector-matches", t => { t.ok( - typeof replaceRuleSelector === "function" && - typeof plugin.replaceRuleSelector === "function", + typeof replaceRuleSelector === "function", "expose 'replaceRuleSelector' function (for postcss-custom-selectors)" ) From cfa6e226269658c8f5e8d31cb819a726f8892fde Mon Sep 17 00:00:00 2001 From: Maxime Thirouin Date: Tue, 14 Jul 2015 07:35:38 +0200 Subject: [PATCH 285/795] Fixed: Nested/mixed selectors now works correctly MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This commit include a refactoring based on postcss-selector-matches and add the ability to limit the transformation to :matches() usage. Also in this commit: - add eslint - rewrite using babel (es6/7) - fixtures files removed in favor of es6 template string - should also fix some weird “undefined” warnings Close #19 --- .babelrc | 3 + .eslintignore | 1 + .eslintrc | 37 +++ .gitignore | 5 +- CHANGELOG.md | 9 +- README.md | 198 ++++++++------- index.js | 101 -------- package.json | 39 ++- src/index.js | 78 ++++++ test/fixtures/comment/input.css | 11 - test/fixtures/comment/output.css | 8 - test/fixtures/extension/input.css | 10 - test/fixtures/extension/output.css | 11 - test/fixtures/heading/input.css | 5 - test/fixtures/heading/output.css | 8 - test/fixtures/line-break/input.css | 6 - test/fixtures/line-break/output.css | 5 - test/fixtures/matches/input.css | 11 - test/fixtures/matches/output.css | 11 - test/fixtures/multiline/input.css | 7 - test/fixtures/multiline/output.css | 4 - test/fixtures/multiple/input.css | 5 - test/fixtures/multiple/output.css | 3 - test/fixtures/pseudo/input.css | 5 - test/fixtures/pseudo/output.css | 4 - test/fixtures/similar-matches/input.css | 18 -- test/fixtures/similar-matches/output.css | 15 -- test/fixtures/some-hyphen/input.css | 10 - test/fixtures/some-hyphen/output.css | 11 - test/index.js | 295 +++++++++++++++++++---- 30 files changed, 507 insertions(+), 427 deletions(-) create mode 100644 .babelrc create mode 120000 .eslintignore create mode 100644 .eslintrc delete mode 100644 index.js create mode 100644 src/index.js delete mode 100644 test/fixtures/comment/input.css delete mode 100644 test/fixtures/comment/output.css delete mode 100644 test/fixtures/extension/input.css delete mode 100644 test/fixtures/extension/output.css delete mode 100644 test/fixtures/heading/input.css delete mode 100644 test/fixtures/heading/output.css delete mode 100644 test/fixtures/line-break/input.css delete mode 100644 test/fixtures/line-break/output.css delete mode 100644 test/fixtures/matches/input.css delete mode 100644 test/fixtures/matches/output.css delete mode 100644 test/fixtures/multiline/input.css delete mode 100644 test/fixtures/multiline/output.css delete mode 100644 test/fixtures/multiple/input.css delete mode 100644 test/fixtures/multiple/output.css delete mode 100644 test/fixtures/pseudo/input.css delete mode 100644 test/fixtures/pseudo/output.css delete mode 100644 test/fixtures/similar-matches/input.css delete mode 100644 test/fixtures/similar-matches/output.css delete mode 100644 test/fixtures/some-hyphen/input.css delete mode 100644 test/fixtures/some-hyphen/output.css diff --git a/.babelrc b/.babelrc new file mode 100644 index 0000000000..b0b9a96ef0 --- /dev/null +++ b/.babelrc @@ -0,0 +1,3 @@ +{ + "stage": 0 +} diff --git a/.eslintignore b/.eslintignore new file mode 120000 index 0000000000..3e4e48b0b5 --- /dev/null +++ b/.eslintignore @@ -0,0 +1 @@ +.gitignore \ No newline at end of file diff --git a/.eslintrc b/.eslintrc new file mode 100644 index 0000000000..cb88f61c2e --- /dev/null +++ b/.eslintrc @@ -0,0 +1,37 @@ +--- +# babel support more syntax stuff than eslint for now +parser: babel-eslint + +ecmaFeatures: + modules: true + +env: + es6: true + browser: true + node: true + +rules: + indent: [2, 2] # 2 spaces indentation + max-len: [2, 80, 4] + 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"] + computed-property-spacing: [2, "never"] + dot-location: [2, "property"] + + one-var: [2, "never"] + #no-var: [2] + prefer-const: [2] + no-bitwise: [2] + + object-shorthand: [2, "methods"] + space-after-keywords: [2, "always"] + space-before-blocks: [2, "always"] + space-before-function-paren: [2, "never"] + space-in-brackets: [2, "never"] + space-in-parens: [2, "never"] + spaced-line-comment: [2, "always"] diff --git a/.gitignore b/.gitignore index a3e84c1f3d..9d0bd2bf07 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,6 @@ .DS_Store -node_modules -test/fixtures/*/actual.css *.sublime-workspace +node_modules +test/fixtures/*/actual.css +dist diff --git a/CHANGELOG.md b/CHANGELOG.md index 7752d6bd45..3fad364779 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,11 @@ -# 2.2.0 - 2015-06-30 (By @MoOx) +# 2.3.0 - 2015-07-14 + +* Fixed: Nested/mixed selectors now works correctly +([#19](https://github.com/postcss/postcss-custom-selectors/issues/19)) +* Added: `transformMatches` option to limit transformation to :matches() +replacements. + +# 2.2.0 - 2015-06-30 * Fixed: No more useless warnings for undefined non custom selectors ([#22](https://github.com/postcss/postcss-custom-selectors/issues/22)) diff --git a/README.md b/README.md index 125b337623..3b27d76d36 100644 --- a/README.md +++ b/README.md @@ -1,9 +1,9 @@ -# PostCSS Custom Selectors +# PostCSS Custom Selectors -[![Build Status](https://travis-ci.org/postcss/postcss-custom-selectors.svg?branch=master)](https://travis-ci.org/postcss/postcss-custom-selectors) -[![NPM Downloads](https://img.shields.io/npm/dm/postcss-custom-selectors.svg?style=flat)](https://www.npmjs.com/package/postcss-custom-selectors) -[![NPM Version](http://img.shields.io/npm/v/postcss-custom-selectors.svg?style=flat)](https://www.npmjs.com/package/postcss-custom-selectors) -[![License](https://img.shields.io/npm/l/postcss-custom-selectors.svg?style=flat)](http://opensource.org/licenses/MIT) +[![Build Status](https://travis-ci.org/postcss/postcss-custom-selectors.svg?branch=master)](https://travis-ci.org/postcss/postcss-custom-selectors) +[![NPM Downloads](https://img.shields.io/npm/dm/postcss-custom-selectors.svg?style=flat)](https://www.npmjs.com/package/postcss-custom-selectors) +[![NPM Version](http://img.shields.io/npm/v/postcss-custom-selectors.svg?style=flat)](https://www.npmjs.com/package/postcss-custom-selectors) +[![License](https://img.shields.io/npm/l/postcss-custom-selectors.svg?style=flat)](http://opensource.org/licenses/MIT) > [PostCSS](https://github.com/postcss/postcss) plugin to transform [W3C CSS Extensions(Custom Selectors)](http://dev.w3.org/csswg/css-extensions/#custom-selectors) to more compatible CSS. @@ -13,12 +13,12 @@ ## Installation - $ npm install postcss-custom-selectors +```console +$ npm install postcss-custom-selectors +``` ## Quick Start -Example 1: - ```js // dependencies var fs = require('fs') @@ -33,7 +33,7 @@ var output = postcss() .use(selector()) .process(css) .css - + console.log('\n====>Output CSS:\n', output) ``` @@ -50,7 +50,7 @@ input.css: ```css @custom-selector :--heading h1, h2, h3, h4, h5, h6; -article :--heading + p { +article :--heading + p { margin-top: 0; } ``` @@ -63,25 +63,22 @@ article h2 + p, article h3 + p, article h4 + p, article h5 + p, -article h6 + p { +article h6 + p { margin-top: 0; } ``` ## CSS syntax - @custom-selector = @custom-selector : ; - +```css +@custom-selector = @custom-selector : ; +``` ## How to use -The custom selector is a pseudo-class, so we must use the `:--` to defined it. - -For example to simulate [:any-link](http://dev.w3.org/csswg/selectors/#the-any-link-pseudo) selector: - -Example 2: +The custom selector is a pseudo-class, so you must use `:--` to define it. -input.css: +For example to simulate [:any-link](http://dev.w3.org/csswg/selectors/#the-any-link-pseudo) selector: ```css @custom-selector :--any-link :link, :visited; @@ -100,35 +97,100 @@ a:visited { } ``` -### Multiple selectors +## Options -`@custom-selector` it **doesn’t support** call multiple custom selector in the same selector, e.g. +### `lineBreak` -Example 3: +_(default: `true`)_ + +Set whether multiple selector wrap.The default is turning on to be a newline. + +Close the line breaks. + +```js +var options = { + lineBreak: false +} + +var output = postcss(selector(options)) + .process(css) + .css +``` + +With the first example, the output will be: ```css -@custom-selector :--heading h1, h2, h3, h4, h5, h6; -@custom-selector :--any-link :link, :visited; +article h1 + p, article h2 + p, article h3 + p, article h4 + p, article h5 + p, article h6 + p { + margin-top: 0; +} +``` + +### `extensions` + +_(default: `{}`)_ + +This option allows you to customize an object to set the `` (selector alias) and ``, these definitions will cover the same alias of `@custom-selector` in CSS. + +```js +var options = { + extensions: { + ':--any' : 'section, article, aside, nav' + } +} + +var output = postcss(selector(options)) + .process(css) + .css; +``` + +input.css + +```css +@custom-selector :--any .foo, .bar; /* No effect */ +:--any h1 { + margin-top: 16px; +} +``` + +output: + +```css +/* No effect */ +section h1, +article h1, +aside h1, +nav h1 { + margin-top: 16px; +} +``` + +### `transformMatches` + +_(default: `true`)_ -.demo :--heading, a:--any-link { - font-size: 32px; +Allows you to limit transformation to `:matches()` usage +If set to false: + +input + +```css +@custom-selector :--foo .bar, .baz; +.foo:--foo { + margin-top: 16px; } ``` -This will throw an error CSS code. +output ```css -.demo h1, -.demo h2, -.demo h3, -.demo h4, -.demo h5, -.demo h6,:link, -:visited { - font-size: 32px; +.foo:matches(.bar, .baz) { + margin-top: 16px; } ``` + +## Usage + ### Node Watch Dependence [chokidar](https://github.com/paulmillr/chokidar) module. @@ -205,72 +267,6 @@ gulp.task('default', function () { gulp.watch('src/*.css', ['default']); ``` - - -### Options - -#### 1. **`lineBreak`**(default: `true`) - -Set whether multiple selector wrap.The default is turning on to be a newline. - -Close the line breaks. - -```js -var options = { - lineBreak: false -} - -var output = postcss(selector(options)) - .process(css) - .css -``` - -In the 'Example 1' `input.css` will output: - -```css -article h1 + p, article h2 + p, article h3 + p, article h4 + p, article h5 + p, article h6 + p { - margin-top: 0; -} -``` - -#### 2. **`extensions`** (default: `{}`) - -This option allows you to customize an object to set the `` (selector alias) and ``, these definitions will cover the same alias of `@custom-selector` in CSS. - -```js -var options = { - extensions: { - ':--any' : 'section, article, aside, nav' - } -} - -var output = postcss(selector(options)) - .process(css) - .css; -``` - -input.css - -```css -@custom-selector :--any .foo, .bar; /* No effect */ -:--any h1 { - margin-top: 16px; -} -``` - -output: - -```css -/* No effect */ -section h1, -article h1, -aside h1, -nav h1 { - margin-top: 16px; -} -``` - - ## Contributing * Install the relevant dependent module. diff --git a/index.js b/index.js deleted file mode 100644 index 4140454e91..0000000000 --- a/index.js +++ /dev/null @@ -1,101 +0,0 @@ -var postcss = require("postcss") -/** - * 匹配自定义选择器 - * :--foo - * 注意:CSS 选择器区分大小写 - */ -var re_CUSTOM_SELECTOR = /([^,]*?)(:-{2,}[\w-]+)(.*)/g - -// 匹配换行符与空白 -var reBLANK_LINE = /(\r\n|\n|\r)(\s*?\1)+/gi - -/** - * 暴露插件 - */ -module.exports = postcss.plugin("postcss-custom-selectors", function(options) { - /** - * 插件配置 - */ - options = options || {} - var extensions = options.extensions || {} - var line_break = '\n' - var map = {} - var toRemove = [] - var customSelectors = {} - - /** - * 读取和替换自定义选择器 - */ - return function(css, result) { - // 读取自定义选择器 - css.eachAtRule(function(rule) { - if (rule.name !== "custom-selector") { - return - } - - var params = rule.params.split(/\s+/) - // @custom-selector = @custom-selector - // map[] = - - var customName = params.shift() - var string = rule.params - string = string.replace(customName, "") - customSelectors[customName] = string - - map[params.shift()] = params.join(" ") - - toRemove.push(rule) - }) - - // JS 中设置一个自定义选择器 - Object.keys(extensions).forEach(function(extension) { - map[extension] = extensions[extension] - customSelectors[extension] = extensions[extension] - }) - - // 转换自定义的选择器别名 - css.eachRule(function(rule) { - if (rule.selector.indexOf(":--") > -1) { - var flag = 0 - for (var prop in customSelectors) { - if (rule.selector.indexOf(prop) >= 0) { - customSelector = customSelectors[prop] - - // $2 = (自定义的选择器名称) - rule.selector = rule.selector.replace(re_CUSTOM_SELECTOR, function($0, $1, $2, $3) { - - if ($2 === prop) { - var newSelector = customSelector.split(",").map(function(selector) { - return $1 + selector.trim() + $3 - }) - - // 选择器不换行 - if (!options.lineBreak && options.lineBreak === false) { - line_break = " " - newSelector = newSelector.join("," + line_break) - } else { - // 选择器换行,同时替换多个换行为一个 - newSelector = newSelector.join("," + line_break + rule.before).replace(reBLANK_LINE, line_break) - } - flag ++ - return newSelector - } - else if ($2 !== prop) { - return $2 - } - }) - if(flag === 0){ - result.warn("The selector '" + rule.selector + "' is undefined", {node: rule}) - } - } - } - } - }) - - // 删除 @custom-selector - toRemove.forEach(function(rule) { - rule.removeSelf() - }) - - } -}) diff --git a/package.json b/package.json index e1432720ef..e4a37ac80b 100644 --- a/package.json +++ b/package.json @@ -1,33 +1,50 @@ { "name": "postcss-custom-selectors", - "version": "2.2.0", + "version": "2.3.0", "description": "PostCSS plugin to transform W3C CSS Extensions(Custom Selectors) to more compatible CSS", "keywords": [ - "css", - "css3", "postcss", - "postcss-plugins", + "postcss-plugin", + "css", "selector", - "custom-selector", - "custom selector" + "custom-selector" + ], + "authors": [ + "yisi", + "Maxime Thirouin" ], - "author": "yisi", "license": "MIT", "repository": { "type": "git", "url": "https://github.com/postcss/postcss-custom-selectors.git" }, + "homepage": "https://github.com/postcss/postcss-custom-selectors", + "bugs": { + "url": "https://github.com/postcss/postcss-custom-selectors/issues" + }, "files": [ "CHANGELOG.md", - "README-zh.md", "LICENSE", - "index.js" + "dist", + "README-zh.md" ], + "main": "dist/index.js", + "dependencies": { + "balanced-match": "^0.2.0", + "postcss": "^4.1.7", + "postcss-selector-matches": "^1.2.1" + }, "devDependencies": { - "postcss": "^4.1.11", + "babel": "^5.5.8", + "babel-eslint": "^3.1.15", + "babel-tape-runner": "^1.1.0", + "eslint": "^0.23.0", "tape": "^4.0.0" }, "scripts": { - "test": "tape test" + "prepublish": "babel src --out-dir dist", + "lint": "eslint .", + "tape": "babel-tape-runner 'test/*.js'", + "test": "npm run lint && npm run tape" } } diff --git a/src/index.js b/src/index.js new file mode 100644 index 0000000000..19c712116e --- /dev/null +++ b/src/index.js @@ -0,0 +1,78 @@ +import postcss from "postcss" +import replaceRuleSelector + from "postcss-selector-matches/dist/replaceRuleSelector" + +const CUSTOM_SELECTOR_RE = /:--[\w-]+/g + +export default postcss.plugin("postcss-custom-selectors", function(options) { + const { + extensions, + lineBreak, + transformMatches, + } = { + extensions: {}, + lineBreak: true, + transformMatches: true, + ...options || {}, + } + + const transformMatchesOnRule = transformMatches + ? (rule) => replaceRuleSelector(rule, { + lineBreak, + }) + : (rule) => rule.selector + + return function(css, result) { + const toRemove = [] + const customSelectors = {} + + // first, read custom selectors + css.eachAtRule(function(rule) { + if (rule.name !== "custom-selector") { + return + } + + // @custom-selector = @custom-selector + const params = rule.params.split(/\s/) + const customName = params.shift() + const customList = rule.params.replace(customName, "").trim() + customSelectors[customName] = customList + + toRemove.push(rule) + }) + + // Add JS defined selectors + Object.keys(extensions).forEach(function(extension) { + customSelectors[extension] = extensions[extension] + }) + + // Convert those selectors to :matches() + css.eachRule(function(rule) { + if (rule.selector.indexOf(":--") > -1) { + rule.selector = rule.selector.replace( + CUSTOM_SELECTOR_RE, + function(extensionName, matches, selector) { + + if (!customSelectors[extensionName]) { + result.warn( + "The selector '" + rule.selector + "' is undefined", + {node: rule} + ) + + return selector + } + + return ":matches(" + customSelectors[extensionName] + ")" + } + ) + + rule.selector = transformMatchesOnRule(rule) + } + }) + + toRemove.forEach(function(rule) { + rule.removeSelf() + }) + + } +}) diff --git a/test/fixtures/comment/input.css b/test/fixtures/comment/input.css deleted file mode 100644 index c1fc9a9cff..0000000000 --- a/test/fixtures/comment/input.css +++ /dev/null @@ -1,11 +0,0 @@ -/* comment */ -@custom-selector :--foo - /* comment */ - .foo, - .bar > .baz; - - -/* comment */ - :--foo + p { - display: block; - } diff --git a/test/fixtures/comment/output.css b/test/fixtures/comment/output.css deleted file mode 100644 index f9df1ea227..0000000000 --- a/test/fixtures/comment/output.css +++ /dev/null @@ -1,8 +0,0 @@ -/* comment */ - - -/* comment */ - .foo + p, - .bar > .baz + p { - display: block; - } diff --git a/test/fixtures/extension/input.css b/test/fixtures/extension/input.css deleted file mode 100644 index d6fbcf7670..0000000000 --- a/test/fixtures/extension/input.css +++ /dev/null @@ -1,10 +0,0 @@ -@custom-selector :--any .foo, .bar; -@custom-selector :--foo .baz; - -:--any h1 { - margin-top: 16px; -} - -main :--foo + p { - margin-top: 16px; -} diff --git a/test/fixtures/extension/output.css b/test/fixtures/extension/output.css deleted file mode 100644 index 6cff275e56..0000000000 --- a/test/fixtures/extension/output.css +++ /dev/null @@ -1,11 +0,0 @@ -section h1, -article h1, -aside h1, -nav h1 { - margin-top: 16px; -} - -main input[type="text"] > section + p, -main #nav .bar + p { - margin-top: 16px; -} diff --git a/test/fixtures/heading/input.css b/test/fixtures/heading/input.css deleted file mode 100644 index dbc7695ae3..0000000000 --- a/test/fixtures/heading/input.css +++ /dev/null @@ -1,5 +0,0 @@ -@custom-selector :--heading h1, h2, h3, h4, h5, h6; - -article :--heading + p { - margin-top: 0; -} diff --git a/test/fixtures/heading/output.css b/test/fixtures/heading/output.css deleted file mode 100644 index a7ea6b4854..0000000000 --- a/test/fixtures/heading/output.css +++ /dev/null @@ -1,8 +0,0 @@ -article h1 + p, -article h2 + p, -article h3 + p, -article h4 + p, -article h5 + p, -article h6 + p { - margin-top: 0; -} diff --git a/test/fixtures/line-break/input.css b/test/fixtures/line-break/input.css deleted file mode 100644 index e166077b4b..0000000000 --- a/test/fixtures/line-break/input.css +++ /dev/null @@ -1,6 +0,0 @@ -@custom-selector :--heading h1, h2, h3, h4, h5, h6; -/* comment */ - - article :--heading + p { - margin-top: 0; - } diff --git a/test/fixtures/line-break/output.css b/test/fixtures/line-break/output.css deleted file mode 100644 index c78f0e8783..0000000000 --- a/test/fixtures/line-break/output.css +++ /dev/null @@ -1,5 +0,0 @@ -/* comment */ - - article h1 + p, article h2 + p, article h3 + p, article h4 + p, article h5 + p, article h6 + p { - margin-top: 0; - } diff --git a/test/fixtures/matches/input.css b/test/fixtures/matches/input.css deleted file mode 100644 index 46545493ba..0000000000 --- a/test/fixtures/matches/input.css +++ /dev/null @@ -1,11 +0,0 @@ -@custom-selector :--buttons button, .button; - -:--buttons:matches(:focus) { - border: red; - display: block; -} - -:--buttons:matches(:focus, .is-focused) { - border: red; - display: block; -} diff --git a/test/fixtures/matches/output.css b/test/fixtures/matches/output.css deleted file mode 100644 index 7f93f4e2a3..0000000000 --- a/test/fixtures/matches/output.css +++ /dev/null @@ -1,11 +0,0 @@ -button:matches(:focus), -.button:matches(:focus) { - border: red; - display: block; -} - -button:matches(:focus, .is-focused), -.button:matches(:focus, .is-focused) { - border: red; - display: block; -} diff --git a/test/fixtures/multiline/input.css b/test/fixtures/multiline/input.css deleted file mode 100644 index c1f640292f..0000000000 --- a/test/fixtures/multiline/input.css +++ /dev/null @@ -1,7 +0,0 @@ -@custom-selector :--multiline - .foo, - .bar > .baz; - -:--multiline { - display: block; -} diff --git a/test/fixtures/multiline/output.css b/test/fixtures/multiline/output.css deleted file mode 100644 index 8eca97dbb9..0000000000 --- a/test/fixtures/multiline/output.css +++ /dev/null @@ -1,4 +0,0 @@ -.foo, -.bar > .baz { - display: block; -} diff --git a/test/fixtures/multiple/input.css b/test/fixtures/multiple/input.css deleted file mode 100644 index 75fe80324a..0000000000 --- a/test/fixtures/multiple/input.css +++ /dev/null @@ -1,5 +0,0 @@ -@custom-selector :--foo .foo; - -:--foo, :--foo.bar { - color: white; -} diff --git a/test/fixtures/multiple/output.css b/test/fixtures/multiple/output.css deleted file mode 100644 index 3da3e23292..0000000000 --- a/test/fixtures/multiple/output.css +++ /dev/null @@ -1,3 +0,0 @@ -.foo, .foo.bar { - color: white; -} diff --git a/test/fixtures/pseudo/input.css b/test/fixtures/pseudo/input.css deleted file mode 100644 index b8feddc099..0000000000 --- a/test/fixtures/pseudo/input.css +++ /dev/null @@ -1,5 +0,0 @@ -@custom-selector :--pseudo ::before, ::after; - -.foo > a:--pseudo img { - display: block; -} diff --git a/test/fixtures/pseudo/output.css b/test/fixtures/pseudo/output.css deleted file mode 100644 index 69a6404172..0000000000 --- a/test/fixtures/pseudo/output.css +++ /dev/null @@ -1,4 +0,0 @@ -.foo > a::before img, -.foo > a::after img { - display: block; -} diff --git a/test/fixtures/similar-matches/input.css b/test/fixtures/similar-matches/input.css deleted file mode 100644 index afa9056b16..0000000000 --- a/test/fixtures/similar-matches/input.css +++ /dev/null @@ -1,18 +0,0 @@ -@custom-selector :--foo h1; -@custom-selector :--foo-bar-baz h4, h5, h6; - -:--foo { - color: red; -} - -:--foo-bar-baz > span { - color: blue; -} - -:--test p { - display: block; -} - -.whatever { - display: block; -} diff --git a/test/fixtures/similar-matches/output.css b/test/fixtures/similar-matches/output.css deleted file mode 100644 index f4b0f33603..0000000000 --- a/test/fixtures/similar-matches/output.css +++ /dev/null @@ -1,15 +0,0 @@ -h1 { - color: red; -} - -h4 > span, h5 > span, h6 > span { - color: blue; -} - -:--test p { - display: block; -} - -.whatever { - display: block; -} diff --git a/test/fixtures/some-hyphen/input.css b/test/fixtures/some-hyphen/input.css deleted file mode 100644 index c69585eee5..0000000000 --- a/test/fixtures/some-hyphen/input.css +++ /dev/null @@ -1,10 +0,0 @@ -@custom-selector :--foo h1, h2, h3; -@custom-selector :--ba-----r h4, h5, h6; - -.fo--oo > :--foo { - margin: auto; -} - -:--ba-----r:hover .ba--z { - display: block; -} diff --git a/test/fixtures/some-hyphen/output.css b/test/fixtures/some-hyphen/output.css deleted file mode 100644 index f545bd2cd0..0000000000 --- a/test/fixtures/some-hyphen/output.css +++ /dev/null @@ -1,11 +0,0 @@ -.fo--oo > h1, -.fo--oo > h2, -.fo--oo > h3 { - margin: auto; -} - -h4:hover .ba--z, -h5:hover .ba--z, -h6:hover .ba--z { - display: block; -} diff --git a/test/index.js b/test/index.js index 8b9a240df7..02a2bd898a 100644 --- a/test/index.js +++ b/test/index.js @@ -1,60 +1,269 @@ -var fs = require("fs") -var test = require("tape") +var test = require("tape") var postcss = require("postcss") -var plugin = require("..") +var plugin = require("../src") -function filename(name) { - return "test/" + name + ".css" +function transform(input, opts = {}, postcssOpts = {}) { + return postcss() + .use(plugin(opts)) + .process(input, postcssOpts) } -function read(name) { - return fs.readFileSync(name, "utf8") +test("@custom-selector", function(t) { + t.equal( + transform( + `` + ).css, + ``, + "should works with nothing" + ) + + const undefinedResult = transform(":--undef {}") + t.ok( + undefinedResult.messages && undefinedResult.messages.length === 1, + "should add a message when a custom selectors is undefined" + ) + + t.equal( + transform( + `@custom-selector :--foo .bar, .baz; +.foo:--foo { + margin-top: 16px; +}`, + {transformMatches: false} + ).css, + `.foo:matches(.bar, .baz) { + margin-top: 16px; +}`, + "should works be able to limit transformation to :matches()" + ) + + t.equal( + transform( + `@custom-selector :--heading h1, h2, h3, h4, h5, h6; + +article :--heading + p {}` + ).css, + `article h1 + p, +article h2 + p, +article h3 + p, +article h4 + p, +article h5 + p, +article h6 + p {}`, + "should transform heading" + ) + + t.equal( + transform( + `@custom-selector :--foobar .foo, .bar; +@custom-selector :--baz .baz; +@custom-selector :--fizzbuzz .fizz, .buzz; +@custom-selector :--button-types + .btn-primary, + .btn-success, + .btn-info, + .btn-warning, + .btn-danger; + +:--foobar > :--baz {} + +:--fizzbuzz > :--foobar {} + +:--button-types, :--button-types:active {}` + ).css, + `.foo > .baz, +.bar > .baz {} + +.fizz > .foo, +.buzz > .foo, +.fizz > .bar, +.buzz > .bar {} + +.btn-primary, +.btn-success, +.btn-info, +.btn-warning, +.btn-danger, +.btn-primary:active, +.btn-success:active, +.btn-info:active, +.btn-warning:active, +.btn-danger:active {}`, + "should work with a complicated example" + ) + + t.equal( + transform( + `/* comment */ +@custom-selector :--foo + /* comment */ + .foo, + .bar > .baz; + + +/* comment */ + :--foo + p { + display: block; + }` + ).css, + `/* comment */ + + +/* comment */ + .foo + p, + .bar > .baz + p { + display: block; + }`, + "should works with comments" + ) + + t.equal( + transform( + `@custom-selector :--pseudo ::before, ::after; + +.foo > a:--pseudo img { + display: block; } +` + ).css, + `.foo > a::before img, +.foo > a::after img { + display: block; +} +`, + "should works with pseudo elements" + ) -function compareFixtures(t, name, msg, opts, postcssOpts) { - postcssOpts = postcssOpts || {} - //input - postcssOpts.from = filename("fixtures/" + name + "/input") - opts = opts || {} - var result = postcss() - .use(plugin(opts)) - .process(read(postcssOpts.from), postcssOpts) + t.equal( + transform( + `@custom-selector :--foo .foo; - var actual = result.css - //output - var output = read(filename("fixtures/" + name + "/output")) - //actual - fs.writeFile(filename("fixtures/" + name + "/actual"), actual) - t.equal(actual.trim(), output.trim(), msg) +:--foo, :--foo.bar { + color: white; +} +` + ).css, + `.foo, +.foo.bar { + color: white; +} +`, + "should works handle multiples combined selectors" + ) + + t.equal( + transform( + `@custom-selector :--foo h1, h2, h3; +@custom-selector :--ba-----r h4, h5, h6; - return result +.fo--oo > :--foo { + margin: auto; } -test("@custom-selector", function(t) { - compareFixtures(t, "heading", "Should transform heading") - compareFixtures(t, "pseudo", "Should transform pseudo") - compareFixtures(t, "multiline", "Should transform multiline") - compareFixtures(t, "some-hyphen", "Should transform some hyphen") - compareFixtures(t, "matches", "Should transform matches selector") - var similarMatchesResult = compareFixtures(t, "similar-matches", "Should transform matches selector") - t.ok( - similarMatchesResult.messages && similarMatchesResult.messages.length === 1, - "Should add a message when a custom selectors is undefined" +:--ba-----r:hover .ba--z { + display: block; +} +` + ).css, + `.fo--oo > h1, +.fo--oo > h2, +.fo--oo > h3 { + margin: auto; +} + +h4:hover .ba--z, +h5:hover .ba--z, +h6:hover .ba--z { + display: block; +} +`, + "should works with weird identifiers" ) - compareFixtures(t, "comment", "Should transform comment") - compareFixtures(t, "line-break", "Should transform line break", { - lineBreak: false - }) + t.equal( + transform( + `@custom-selector :--heading h1, h2, h3, h4, h5, h6; +/* comment */ - compareFixtures(t, "extension", "Should transform local extensions", { - extensions: { - ':--any': 'section, article, aside, nav', - ':--foo': 'input[type="text"] > section, #nav .bar' - } - }) + article :--heading + p { + margin-top: 0; + } +`, + {lineBreak: false} + ).css, + `/* comment */ + + article h1 + p, article h2 + p, article h3 + p, article h4 + p, ` + + `article h5 + p, article h6 + p { + margin-top: 0; + } +`, + "should works works with no line breaks" + ) - compareFixtures(t, "multiple", "Should transform multiple selectors") + t.equal( + transform( + `@custom-selector :--multiline + .foo, + .bar > .baz; + +:--multiline { + display: block; +} +` + ).css, + `.foo, +.bar > .baz { + display: block; +} +`, + "should works with multilines definition" + ) + + t.equal( + transform( + `@custom-selector :--any .foo, .bar; +@custom-selector :--foo .baz; + +:--any h1 { + margin-top: 16px; +} + +main :--foo + p { + margin-top: 16px; +} +`, + { + extensions: { + ":--any": "section, article, aside, nav", + ":--foo": "input[type=\"text\"] > section, #nav .bar", + }, + } + ).css, + `section h1, +article h1, +aside h1, +nav h1 { + margin-top: 16px; +} + +main input[type="text"] > section + p, +main #nav .bar + p { + margin-top: 16px; +} +`, + "should transform local extensions" + ) + + var postcssPlugin = postcss().use(plugin()) + t.ok( + postcssPlugin.process("@custom-selector :--foobar .foo;:--foobar{}").css, + "should not create a memory" + ) + t.equal( + postcssPlugin.process(":--foobar{}").css, + ":--foobar{}", + "should have no memory about previous processing" + ) t.end() }) From 5c3f7113fe271c2d7b617a7e5411671329de717f Mon Sep 17 00:00:00 2001 From: Maxime Thirouin Date: Wed, 15 Jul 2015 19:17:15 +0200 Subject: [PATCH 286/795] Add smarter example with a combo --- README.md | 26 ++++++++++++++++++++++++-- test/index.js | 14 ++++++++++++++ 2 files changed, 38 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 3b27d76d36..4f09621c25 100644 --- a/README.md +++ b/README.md @@ -37,7 +37,7 @@ var output = postcss() console.log('\n====>Output CSS:\n', output) ``` -Or just: +Or just: ```js var output = postcss(selector()) @@ -45,7 +45,7 @@ var output = postcss(selector()) .css ``` -input.css: +input: ```css @custom-selector :--heading h1, h2, h3, h4, h5, h6; @@ -97,6 +97,28 @@ a:visited { } ``` +You can even make some smart use like this: + +```css +@custom-selector :--button button, .button; +@custom-selector :--enter :hover, :focus; + +:--button:--enter { + +} +``` + +output + +```css +button:hover, +.button:hover, +button:focus, +.button:focus { + +} +``` + ## Options ### `lineBreak` diff --git a/test/index.js b/test/index.js index 02a2bd898a..6f894ae898 100644 --- a/test/index.js +++ b/test/index.js @@ -219,6 +219,20 @@ h6:hover .ba--z { "should works with multilines definition" ) + t.equal( + transform( + `@custom-selector :--button button, .button; +@custom-selector :--enter :hover, :focus; + +:--button:--enter {}` + ).css, + `button:hover, +.button:hover, +button:focus, +.button:focus {}`, + "should works with collapsed custom selectors" + ) + t.equal( transform( `@custom-selector :--any .foo, .bar; From ae55769f675d20172d9727b62c098f21613306cf Mon Sep 17 00:00:00 2001 From: Maxime Thirouin Date: Tue, 21 Jul 2015 16:08:24 +0200 Subject: [PATCH 287/795] Added: `warnings` option allows you to disable warnings. Close https://github.com/cssnext/cssnext/issues/186 --- CHANGELOG.md | 5 +++++ README.md | 38 +++++++++++++++++++++++++++++--------- index.js | 13 +++++++++---- package.json | 2 +- test/index.js | 20 +++++++++++++++++--- 5 files changed, 61 insertions(+), 17 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b221624692..83f42f7bda 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,8 @@ +# 4.2.0 - 2015-07-21 + +- Added: `warnings` option allows you to disable warnings. +([cssnext#186](https://github.com/cssnext/cssnext/issues/186)) + # 4.1.0 - 2015-07-14 - Added: plugin now returns itself in order to expose a `setVariables` function diff --git a/README.md b/README.md index 8fc199fb9a..8cc7f75d0f 100755 --- a/README.md +++ b/README.md @@ -79,13 +79,17 @@ Checkout [tests](test) for more. ### Options -#### `strict` (default: `true`) +#### `strict` + +Default: `true` Per specifications, all fallbacks should be added since we can't verify if a computed value is valid or not. This option allows you to avoid adding too many fallback values in your CSS. -#### `preserve` (default: `false`) +#### `preserve` + +Default: `false` Allows you to preserve custom properties & var() usage in output. @@ -96,27 +100,43 @@ var out = postcss() .css ``` -You can also set `preserve: "computed"` to get computed resolved custom properties in the final output. +You can also set `preserve: "computed"` to get computed resolved custom +properties in the final output. Handy to make them available to your JavaScript. -#### `variables` (default: `{}`) +#### `variables` -Allows you to pass an object of variables for `:root`. These definitions will override any that exist in the CSS. +Default: `{}` + +Allows you to pass an object of variables for `:root`. These definitions will +override any that exist in the CSS. The keys are automatically prefixed with the CSS `--` to make it easier to share variables in your codebase. -#### `appendVariables` (default: `false`) +#### `appendVariables` + +Default: `false` + +If `preserve` is set to `true` (or `"computed"`), allows you to append your +variables at the end of your CSS. + +#### `warnings` + +Default: `true` +Type: `Boolean|Object` -If `preserve` is set to `true` (or `"computed"`), allows you to append your variables at the end of your CSS. +Allows you to enable/disable warnings. If true, will enable all warnings. +For now, it only allow to disable messages about custom properties definition +not scoped in a `:root` selector. --- ## Contributing -Work on a branch, install dev-dependencies, respect coding style & run tests before submitting a bug fix or a feature. +Fork, work on a branch, install dependencies & run tests before submitting a PR. ```console -$ git clone https://github.com/postcss/postcss-custom-properties.git +$ git clone https://github.com/YOU/postcss-custom-properties.git $ git checkout -b patch-1 $ npm install $ npm test diff --git a/index.js b/index.js index 6c702a23fb..bed6859a17 100755 --- a/index.js +++ b/index.js @@ -156,6 +156,7 @@ module.exports = postcss.plugin("postcss-custom-properties", function(options) { } function plugin(style, result) { + var warnings = options.warnings === undefined ? true : options.warnings var variables = prefixVariables(options.variables) var strict = options.strict === undefined ? true : options.strict var appendVariables = options.appendVariables @@ -169,13 +170,17 @@ module.exports = postcss.plugin("postcss-custom-properties", function(options) { // only variables declared for `:root` are supported for now if ( - rule.selectors.length !== 1 || - rule.selectors[0] !== ":root" || - rule.parent.type !== "root" + rule.selectors.length !== 1 || + rule.selectors[0] !== ":root" || + rule.parent.type !== "root" ) { rule.each(function(decl) { var prop = decl.prop - if (prop && prop.indexOf(VAR_PROP_IDENTIFIER) === 0) { + if ( + warnings && + prop && + prop.indexOf(VAR_PROP_IDENTIFIER) === 0 + ) { result.warn( "Custom property ignored: not scoped to the top-level :root " + "element (" + rule.selectors + " { ... " + prop + ": ... })" + diff --git a/package.json b/package.json index 15226d129e..ac5a963ab3 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "postcss-custom-properties", - "version": "4.1.0", + "version": "4.2.0", "description": "PostCSS plugin to polyfill W3C CSS Custom Properties for cascading variables", "keywords": [ "css", diff --git a/test/index.js b/test/index.js index 5c713ad437..104ea43074 100755 --- a/test/index.js +++ b/test/index.js @@ -63,7 +63,7 @@ test( function(t) { var result = compareFixtures(t, "substitution-undefined") t.equal( - result.warnings()[0].text, + result.messages[0].text, "variable '--test' is undefined and used without a fallback", "should add a warning for undefined variable" ) @@ -74,12 +74,26 @@ test( test("substitutes defined variables in `:root` only", function(t) { var result = compareFixtures(t, "substitution-defined") t.ok( - result.warnings()[0].text.match(/^Custom property ignored/), + result.messages[0].text.match(/^Custom property ignored/), "should add a warning for non root custom properties" ) t.end() }) +test("allow to hide warnings", function(t) { + var result = compareFixtures( + t, + "substitution-defined", + {warnings: false} + ) + t.equal( + result.messages.length, + 0, + "should not add warnings if option set to false" + ) + t.end() +}) + test( "accepts variables defined from JavaScript, and overrides local definitions", function(t) { @@ -181,7 +195,7 @@ test("circular variable references", function(t) { compareFixtures(t, "self-reference") var result = compareFixtures(t, "circular-reference") t.equal( - result.warnings()[0].text, + result.messages[0].text, "Circular variable reference: --color", "should add a warning for circular reference" ) From 51e2257bfad0e1ec2220e5b9da56e297c5fc01b8 Mon Sep 17 00:00:00 2001 From: Bogdan Chadkin Date: Wed, 12 Aug 2015 16:10:01 +0300 Subject: [PATCH 288/795] Upgrade to PostCSS 4.1.x --- .jscsrc | 5 ----- index.js | 6 ++++-- package.json | 13 +++++++------ 3 files changed, 11 insertions(+), 13 deletions(-) diff --git a/.jscsrc b/.jscsrc index 29720b3791..9afb9dd75d 100644 --- a/.jscsrc +++ b/.jscsrc @@ -121,10 +121,5 @@ "requireCapitalizedConstructors": true, "safeContextKeyword": "that", "requireDotNotation": true, - "validateJSDoc": { - "checkParamNames": true, - "checkRedundantParams": true, - "requireParamTypes": true - }, "requireSpaceAfterLineComment": true } diff --git a/index.js b/index.js index 902218729f..61894f8fe3 100755 --- a/index.js +++ b/index.js @@ -1,3 +1,5 @@ +var postcss = require("postcss"); + /** * font variant convertion map * @@ -84,7 +86,7 @@ function getFontFeatureSettingsPrevTo(decl) { /** * Expose the font-variant plugin. */ -module.exports = function postcssFontVariant() { +module.exports = postcss.plugin("postcss-font-variant", function() { return function(styles) { styles.eachRule(function(rule) { var fontFeatureSettings = null @@ -116,4 +118,4 @@ module.exports = function postcssFontVariant() { }) }) } -} +}) diff --git a/package.json b/package.json index f906e4d3a9..914e9f8ea2 100755 --- a/package.json +++ b/package.json @@ -5,7 +5,7 @@ "keywords": [ "css", "postcss", - "postcss-plugins", + "postcss-plugin", "font", "variant", "font-variant" @@ -21,12 +21,13 @@ "LICENSE", "index.js" ], - "dependencies": {}, + "dependencies": { + "postcss": "^4.1.16" + }, "devDependencies": { - "jscs": "^1.6.2", - "jshint": "^2.5.6", - "postcss": "^4.0.2", - "tape": "^3.0.0" + "jscs": "^2.1.0", + "jshint": "^2.8.0", + "tape": "^4.0.3" }, "scripts": { "lint": "jscs *.js **/*.js && jshint . --exclude-path .gitignore", From fe869d7e0f6fe2c154c189cec2115c01f75dfe6c Mon Sep 17 00:00:00 2001 From: Bogdan Chadkin Date: Wed, 12 Aug 2015 16:52:45 +0300 Subject: [PATCH 289/795] Upgrade to PostCSS 4.1.x --- .jscsrc | 5 ----- index.js | 7 ++++--- package.json | 14 +++++++------- 3 files changed, 11 insertions(+), 15 deletions(-) diff --git a/.jscsrc b/.jscsrc index 29720b3791..9afb9dd75d 100644 --- a/.jscsrc +++ b/.jscsrc @@ -121,10 +121,5 @@ "requireCapitalizedConstructors": true, "safeContextKeyword": "that", "requireDotNotation": true, - "validateJSDoc": { - "checkParamNames": true, - "checkRedundantParams": true, - "requireParamTypes": true - }, "requireSpaceAfterLineComment": true } diff --git a/index.js b/index.js index 724ce14423..39e628a62e 100755 --- a/index.js +++ b/index.js @@ -1,14 +1,15 @@ /** * Module dependencies. */ +var postcss = require("postcss") +var helpers = require("postcss-message-helpers") var color = require("color") var reduceFunctionCall = require("reduce-function-call") -var helpers = require("postcss-message-helpers") /** * PostCSS plugin to transform hwb() to rgb() */ -module.exports = function plugin() { +module.exports = postcss.plugin("postcss-color-hwb", function() { return function(style) { style.eachDecl(function transformDecl(decl) { if (!decl.value || decl.value.indexOf("hwb(") === -1) { @@ -22,4 +23,4 @@ module.exports = function plugin() { }, decl.source) }) } -} +}) diff --git a/package.json b/package.json index 73064a0820..029bfbffa0 100644 --- a/package.json +++ b/package.json @@ -5,7 +5,7 @@ "keywords": [ "css", "postcss", - "postcss-plugins", + "postcss-plugin", "color", "colour", "rgb", @@ -23,15 +23,15 @@ "index.js" ], "dependencies": { - "color": "^0.7.1", - "postcss-message-helpers": "^1.1.0", + "color": "^0.10.1", + "postcss": "^4.1.16", + "postcss-message-helpers": "^2.0.0", "reduce-function-call": "^1.0.1" }, "devDependencies": { - "jscs": "^1.6.2", - "jshint": "^2.5.6", - "postcss": "^4.0.2", - "tape": "^3.0.0" + "jscs": "^2.1.0", + "jshint": "^2.8.0", + "tape": "^4.0.3" }, "scripts": { "lint": "jscs *.js **/*.js && jshint . --exclude-path .gitignore", From 2cb5ec018f677b767eeb02fedc38010cc38b5955 Mon Sep 17 00:00:00 2001 From: Bogdan Chadkin Date: Wed, 12 Aug 2015 17:00:35 +0300 Subject: [PATCH 290/795] Upgrade to PostCSS 4.1.x --- .jscsrc | 5 ----- index.js | 7 ++++--- package.json | 14 +++++++------- 3 files changed, 11 insertions(+), 15 deletions(-) diff --git a/.jscsrc b/.jscsrc index 29720b3791..9afb9dd75d 100644 --- a/.jscsrc +++ b/.jscsrc @@ -121,10 +121,5 @@ "requireCapitalizedConstructors": true, "safeContextKeyword": "that", "requireDotNotation": true, - "validateJSDoc": { - "checkParamNames": true, - "checkRedundantParams": true, - "requireParamTypes": true - }, "requireSpaceAfterLineComment": true } diff --git a/index.js b/index.js index 750ae6478d..13507fd27f 100755 --- a/index.js +++ b/index.js @@ -1,8 +1,9 @@ /** * Module dependencies. */ -var color = require("color") +var postcss = require("postcss") var helpers = require("postcss-message-helpers") +var color = require("color") /** * Constantes @@ -13,7 +14,7 @@ var DECIMAL_PRECISION = 100000 // 5 decimals /** * PostCSS plugin to transform hexa alpha colors */ -module.exports = function plugin() { +module.exports = postcss.plugin("postcss-color-hex-alpha", function() { return function(style) { style.eachDecl(function transformDecl(decl) { if (!decl.value || decl.value.indexOf("#") === -1) { @@ -25,7 +26,7 @@ module.exports = function plugin() { }, decl.source) }) } -} +}) /** * transform RGBA hexadecimal notations (#RRGGBBAA or #RGBA) to rgba(). diff --git a/package.json b/package.json index 3f2fcad82b..f78c9c0a8a 100644 --- a/package.json +++ b/package.json @@ -5,7 +5,7 @@ "keywords": [ "css", "postcss", - "postcss-plugins", + "postcss-plugin", "color", "colour", "hexa", @@ -23,14 +23,14 @@ "index.js" ], "dependencies": { - "color": "^0.7.1", - "postcss-message-helpers": "^1.1.0" + "color": "^0.10.1", + "postcss": "^4.1.16", + "postcss-message-helpers": "^2.0.0" }, "devDependencies": { - "jscs": "^1.6.2", - "jshint": "^2.5.6", - "postcss": "^4.0.2", - "tape": "^3.0.0" + "jscs": "^2.1.0", + "jshint": "^2.8.0", + "tape": "^4.0.3" }, "scripts": { "lint": "jscs *.js **/*.js && jshint . --exclude-path .gitignore", From a1eb51df62b626ebb59d28f34465d3f19ab3d670 Mon Sep 17 00:00:00 2001 From: Maxime Thirouin Date: Thu, 13 Aug 2015 09:26:33 +0200 Subject: [PATCH 291/795] 1.3.0 --- CHANGELOG.md | 9 +++++++++ package.json | 2 +- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f4168db2ff..c6a725d421 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,12 @@ +# 1.3.0 - 2015-08-13 + +- Added: compatibility with postcss v4.1.x +([#3](https://github.com/postcss/postcss-calc/pull/3)) + +# 1.2.0 - ? + +1.1.0 ? + # 1.1.0 - 2014-11-25 - Enhanced exceptions diff --git a/package.json b/package.json index f78c9c0a8a..83306ba298 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "postcss-color-hex-alpha", - "version": "1.1.0", + "version": "1.3.0", "description": "PostCSS plugin to transform W3C RGBA hexadecimal notations (#RRGGBBAA or #RGBA) to more compatible CSS (rgba())", "keywords": [ "css", From bd90eacd07135e5fa5560065baaba6d8394f6ece Mon Sep 17 00:00:00 2001 From: Maxime Thirouin Date: Thu, 13 Aug 2015 09:29:51 +0200 Subject: [PATCH 292/795] 1.2.0 --- CHANGELOG.md | 5 +++++ package.json | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f4168db2ff..c4f7ad33aa 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,8 @@ +# 1.2.0 - 2015-08-13 + +- Added: compatibility with postcss v4.1.x +([#4](https://github.com/postcss/postcss-calc/pull/4)) + # 1.1.0 - 2014-11-25 - Enhanced exceptions diff --git a/package.json b/package.json index 029bfbffa0..3b41e7bf5c 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "postcss-color-hwb", - "version": "1.1.0", + "version": "1.2.0", "description": "PostCSS plugin to transform W3C CSS hwb() color to more compatible CSS (rgb() (or rgba()))", "keywords": [ "css", From 4ba0ec6c5301268a16efb1800c9a9683c5ebc765 Mon Sep 17 00:00:00 2001 From: Maxime Thirouin Date: Thu, 13 Aug 2015 09:32:00 +0200 Subject: [PATCH 293/795] oups --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c6a725d421..1961215118 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,7 +1,7 @@ # 1.3.0 - 2015-08-13 - Added: compatibility with postcss v4.1.x -([#3](https://github.com/postcss/postcss-calc/pull/3)) +([#3](https://github.com/postcss/postcss-color-hex-alpha/pull/3)) # 1.2.0 - ? From b8d0dac137a8d71a9584dc9d66725e2f8e8e0265 Mon Sep 17 00:00:00 2001 From: Maxime Thirouin Date: Thu, 13 Aug 2015 09:32:15 +0200 Subject: [PATCH 294/795] oups --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c4f7ad33aa..d62ebd79f8 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,7 +1,7 @@ # 1.2.0 - 2015-08-13 - Added: compatibility with postcss v4.1.x -([#4](https://github.com/postcss/postcss-calc/pull/4)) +([#4](https://github.com/postcss/postcss-color-hwb/pull/4)) # 1.1.0 - 2014-11-25 From 6757cb768947e63a1321511b20ea5903be3871ff Mon Sep 17 00:00:00 2001 From: Maxime Thirouin Date: Thu, 13 Aug 2015 09:32:57 +0200 Subject: [PATCH 295/795] update changelog for 1.2.0 --- CHANGELOG.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5f634b71aa..44788998d0 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,7 @@ # 1.2.0 - 2015-07-01 -- Upgrade to PostCSS 4.1.x +- Added: compatibility with postcss v4.1.x +([#4](https://github.com/postcss/postcss-color-rebeccapurple/pull/4)) # 1.1.0 - 2014-11-25 From 67cc9c9dcec6a261cbeaef6257419e92706168ad Mon Sep 17 00:00:00 2001 From: Maxime Thirouin Date: Thu, 13 Aug 2015 10:23:56 +0200 Subject: [PATCH 296/795] 1.2.0 --- CHANGELOG.md | 5 +++++ package.json | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e48d3f3234..e0265d637f 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,8 @@ +# 1.2.0 - 2015-08-13 + +- Added: compatibility with postcss v4.1.x +([#5](https://github.com/postcss/postcss-font-variant/pull/5)) + # 1.1.0 - 2015-01-29 - Fixed: Properly handle font-variant-position:normal ([#3](https://github.com/postcss/postcss-font-variant/pull/3)) diff --git a/package.json b/package.json index 914e9f8ea2..a7c9b47207 100755 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "postcss-font-variant", - "version": "1.1.0", + "version": "1.2.0", "description": "PostCSS plugin to transform W3C font-variant properties to more compatible CSS (font-feature-settings)", "keywords": [ "css", From 136250ad63ea395d8cc3201bd5a2e7797d2f689a Mon Sep 17 00:00:00 2001 From: Maxime Thirouin Date: Tue, 25 Aug 2015 06:47:08 +0200 Subject: [PATCH 297/795] 5.0.0 (switch to postcss 5.x) --- .eslintrc | 21 ++++++++++++++------- CHANGELOG.md | 5 +++++ index.js | 10 +++++----- package.json | 8 +++----- 4 files changed, 27 insertions(+), 17 deletions(-) diff --git a/.eslintrc b/.eslintrc index da2592a767..18d7c97bd3 100644 --- a/.eslintrc +++ b/.eslintrc @@ -1,9 +1,12 @@ --- -ecmaFeatures: - modules: true +root: true +extends: eslint:recommended + +#ecmaFeatures: +# modules: true env: - es6: true +# es6: true browser: true node: true @@ -17,16 +20,20 @@ rules: brace-style: [2, "stroustrup"] comma-dangle: [2, "always-multiline"] comma-style: [2, "last"] - computed-property-spacing: [2, "never"] dot-location: [2, "property"] one-var: [2, "never"] +# no-var: [2] +# prefer-const: [2] no-bitwise: [2] - object-shorthand: [2, "methods"] + object-curly-spacing: [2, "never"] + array-bracket-spacing: [2, "never"] + computed-property-spacing: [2, "never"] + + space-unary-ops: [2, {"words": true, "nonwords": false}] space-after-keywords: [2, "always"] space-before-blocks: [2, "always"] space-before-function-paren: [2, "never"] - space-in-brackets: [2, "never"] space-in-parens: [2, "never"] - spaced-line-comment: [2, "always"] + spaced-comment: [2, "always"] diff --git a/CHANGELOG.md b/CHANGELOG.md index 83f42f7bda..57165c4c3f 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,8 @@ +# 5.0.0 - 2015-08-25 + +- Removed: compatibility with postcss v4.x +- Added: compatibility with postcss v5.x + # 4.2.0 - 2015-07-21 - Added: `warnings` option allows you to disable warnings. diff --git a/index.js b/index.js index bed6859a17..598fdfc1f1 100755 --- a/index.js +++ b/index.js @@ -165,7 +165,7 @@ module.exports = postcss.plugin("postcss-custom-properties", function(options) { var importantMap = {} // define variables - style.eachRule(function(rule) { + style.walkRules(function(rule) { var toRemove = [] // only variables declared for `:root` are supported for now @@ -216,7 +216,7 @@ module.exports = postcss.plugin("postcss-custom-properties", function(options) { // remove empty :root {} if (rule.nodes.length === 0) { - rule.removeSelf() + rule.remove() } } }) @@ -242,7 +242,7 @@ module.exports = postcss.plugin("postcss-custom-properties", function(options) { } // resolve variables - style.eachDecl(function(decl) { + style.walkDecls(function(decl) { var value = decl.value // skip values that don’t contain variable functions @@ -260,7 +260,7 @@ module.exports = postcss.plugin("postcss-custom-properties", function(options) { }) if (!preserve || preserve === "computed") { - decl.removeSelf() + decl.remove() } }) @@ -269,7 +269,7 @@ module.exports = postcss.plugin("postcss-custom-properties", function(options) { if (names.length) { var container = postcss.rule({ selector: ":root", - semicolon: true, + raws: {semicolon: true}, }) names.forEach(function(name) { var variable = map[name] diff --git a/package.json b/package.json index ac5a963ab3..4ccdf2fcbf 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "postcss-custom-properties", - "version": "4.2.0", + "version": "5.0.0", "description": "PostCSS plugin to polyfill W3C CSS Custom Properties for cascading variables", "keywords": [ "css", @@ -17,16 +17,14 @@ "url": "https://github.com/postcss/postcss-custom-properties.git" }, "files": [ - "CHANGELOG.md", - "LICENSE", "index.js" ], "dependencies": { "balanced-match": "~0.1.0", - "postcss": "^4.1.4" + "postcss": "^5.0.0" }, "devDependencies": { - "eslint": "^0.23.0", + "eslint": "^1.0.0", "tape": "^4.0.0" }, "scripts": { From 4fc56724a73d54d803301a6a3004c97995a4aa92 Mon Sep 17 00:00:00 2001 From: Maxime Thirouin Date: Tue, 25 Aug 2015 06:55:30 +0200 Subject: [PATCH 298/795] 5.0.0 (switch to postcss 5.x) --- .eslintrc | 21 ++++++++++++++------- CHANGELOG.md | 5 +++++ index.js | 14 ++++++++------ package.json | 12 +++++------- 4 files changed, 32 insertions(+), 20 deletions(-) diff --git a/.eslintrc b/.eslintrc index da2592a767..18d7c97bd3 100644 --- a/.eslintrc +++ b/.eslintrc @@ -1,9 +1,12 @@ --- -ecmaFeatures: - modules: true +root: true +extends: eslint:recommended + +#ecmaFeatures: +# modules: true env: - es6: true +# es6: true browser: true node: true @@ -17,16 +20,20 @@ rules: brace-style: [2, "stroustrup"] comma-dangle: [2, "always-multiline"] comma-style: [2, "last"] - computed-property-spacing: [2, "never"] dot-location: [2, "property"] one-var: [2, "never"] +# no-var: [2] +# prefer-const: [2] no-bitwise: [2] - object-shorthand: [2, "methods"] + object-curly-spacing: [2, "never"] + array-bracket-spacing: [2, "never"] + computed-property-spacing: [2, "never"] + + space-unary-ops: [2, {"words": true, "nonwords": false}] space-after-keywords: [2, "always"] space-before-blocks: [2, "always"] space-before-function-paren: [2, "never"] - space-in-brackets: [2, "never"] space-in-parens: [2, "never"] - spaced-line-comment: [2, "always"] + spaced-comment: [2, "always"] diff --git a/CHANGELOG.md b/CHANGELOG.md index 36d2ca386e..f83ce47aa4 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,8 @@ +# 5.0.0 - 2015-08-25 + +- Removed: compatibility with postcss v4.x +- Added: compatibility with postcss v5.x + # 4.1.0 - 2015-06-30 - Added: Allow custom media to reference each other diff --git a/index.js b/index.js index be6f8d2c55..cd0b178270 100755 --- a/index.js +++ b/index.js @@ -51,7 +51,7 @@ function customMedia(options) { var toRemove = [] // read custom media queries - styles.eachAtRule(function(rule) { + styles.walkAtRules(function(rule) { if (rule.name !== "custom-media") { return } @@ -87,7 +87,7 @@ function customMedia(options) { }) // transform custom media query aliases - styles.eachAtRule(function(rule) { + styles.walkAtRules(function(rule) { if (rule.name !== "media") { return } @@ -123,19 +123,21 @@ function customMedia(options) { } var atRule = postcss.atRule({ name: "custom-media", - afterName: " ", params: name + " " + map[name].value, + raws: { + afterName: " ", + }, }) styles.append(atRule) }) - styles.semicolon = true - styles.after = "\n" + styles.raws.semicolon = true + styles.raws.after = "\n" } } // remove @custom-media toRemove.forEach(function(rule) { - rule.removeSelf() + rule.remove() }) } } diff --git a/package.json b/package.json index dcd419bdc9..2af41a55e6 100644 --- a/package.json +++ b/package.json @@ -1,11 +1,11 @@ { "name": "postcss-custom-media", - "version": "4.1.0", - "description": " PostCSS plugin to transform W3C CSS Custom Media Queries to more compatible CSS", + "version": "5.0.0", + "description": "PostCSS plugin to transform W3C CSS Custom Media Queries to more compatible CSS", "keywords": [ "css", "postcss", - "postcss-plugins", + "postcss-plugin", "media queries", "custom-media" ], @@ -16,15 +16,13 @@ "url": "https://github.com/postcss/postcss-custom-media.git" }, "files": [ - "CHANGELOG.md", - "LICENSE", "index.js" ], "dependencies": { - "postcss": "^4.1.4" + "postcss": "^5.0.0" }, "devDependencies": { - "eslint": "^0.23.0", + "eslint": "^1.0.0", "tape": "^4.0.0" }, "scripts": { From 0e01475f580f0d22c22710524c6d03a8118f901d Mon Sep 17 00:00:00 2001 From: Maxime Thirouin Date: Tue, 25 Aug 2015 07:07:57 +0200 Subject: [PATCH 299/795] 2.0.0 (switch to postcss 5.x) --- .eslintrc | 13 +++++++++---- CHANGELOG.md | 5 +++++ package.json | 15 +++++---------- src/index.js | 2 +- src/replaceRuleSelector.js | 4 ++-- 5 files changed, 22 insertions(+), 17 deletions(-) diff --git a/.eslintrc b/.eslintrc index c8a232b7da..db21f05621 100644 --- a/.eslintrc +++ b/.eslintrc @@ -2,6 +2,9 @@ # babel support more syntax stuff than eslint for now parser: babel-eslint +root: true +extends: eslint:recommended + ecmaFeatures: modules: true @@ -20,7 +23,6 @@ rules: brace-style: [2, "stroustrup"] comma-dangle: [2, "always-multiline"] comma-style: [2, "last"] - computed-property-spacing: [2, "never"] dot-location: [2, "property"] one-var: [2, "never"] @@ -28,10 +30,13 @@ rules: prefer-const: [2] no-bitwise: [2] - object-shorthand: [2, "methods"] + object-curly-spacing: [2, "never"] + array-bracket-spacing: [2, "never"] + computed-property-spacing: [2, "never"] + + space-unary-ops: [2, {"words": true, "nonwords": false}] space-after-keywords: [2, "always"] space-before-blocks: [2, "always"] space-before-function-paren: [2, "never"] - space-in-brackets: [2, "never"] space-in-parens: [2, "never"] - spaced-line-comment: [2, "always"] + spaced-comment: [2, "always"] diff --git a/CHANGELOG.md b/CHANGELOG.md index 4fe4430f29..7eed078e6f 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,8 @@ +# 2.0.0 - 2015-08-25 + +- Removed: compatibility with postcss v4.x +- Added: compatibility with postcss v5.x + # 1.2.1 - 2015-07-14 - Fixed: plugin is correctly exposed for normal commonjs environments (!babel) diff --git a/package.json b/package.json index 402b7cdec5..e0d06779f0 100644 --- a/package.json +++ b/package.json @@ -1,9 +1,10 @@ { "name": "postcss-selector-matches", - "version": "1.2.1", + "version": "2.0.0", "description": "PostCSS plugin to transform :matches() W3C CSS pseudo class to more compatible CSS selectors", "keywords": [ "postcss", + "postcss-plugin", "selectors", "selector", "matches" @@ -14,25 +15,19 @@ "type": "git", "url": "https://github.com/postcss/postcss-selector-matches.git" }, - "homepage": "https://github.com/postcss/postcss-selector-matches", - "bugs": { - "url": "https://github.com/postcss/postcss-selector-matches/issues" - }, + "main": "dist/index.js", "files": [ - "CHANGELOG.md", - "LICENSE", "dist" ], - "main": "dist/index.js", "dependencies": { "balanced-match": "^0.2.0", - "postcss": "^4.1.7" + "postcss": "^5.0.0" }, "devDependencies": { "babel": "^5.5.8", "babel-eslint": "^3.1.15", "babel-tape-runner": "^1.1.0", - "eslint": "^0.23.0", + "eslint": "^1.0.0", "tape": "^4.0.0" }, "scripts": { diff --git a/src/index.js b/src/index.js index b701ca79bc..3d80034745 100644 --- a/src/index.js +++ b/src/index.js @@ -3,7 +3,7 @@ import replaceRuleSelector from "./replaceRuleSelector" function explodeSelectors(options = {}) { return (css) => { - css.eachRule(rule => { + css.walkRules(rule => { if (rule.selector && rule.selector.indexOf(":matches") > -1) { rule.selector = replaceRuleSelector(rule, options) } diff --git a/src/replaceRuleSelector.js b/src/replaceRuleSelector.js index 1f02b0bd2d..6d759bf627 100644 --- a/src/replaceRuleSelector.js +++ b/src/replaceRuleSelector.js @@ -55,8 +55,8 @@ function explodeSelector(selector, options) { } export default function replaceRuleSelector(rule, options) { - const indentation = rule.before - ? rule.before.split("\n").pop() + const indentation = rule.raws && rule.raws.before + ? rule.raws.before.split("\n").pop() : "" return ( explodeSelector(rule.selector, options) From cd6e2bf06e735127a61e1c831d281d3456da59a3 Mon Sep 17 00:00:00 2001 From: Maxime Thirouin Date: Tue, 25 Aug 2015 07:13:14 +0200 Subject: [PATCH 300/795] 2.0.0 (switch to postcss 5.x) --- .eslintrc | 13 +++++++++---- CHANGELOG.md | 5 +++++ package.json | 15 +++++---------- src/index.js | 2 +- 4 files changed, 20 insertions(+), 15 deletions(-) diff --git a/.eslintrc b/.eslintrc index c8a232b7da..db21f05621 100644 --- a/.eslintrc +++ b/.eslintrc @@ -2,6 +2,9 @@ # babel support more syntax stuff than eslint for now parser: babel-eslint +root: true +extends: eslint:recommended + ecmaFeatures: modules: true @@ -20,7 +23,6 @@ rules: brace-style: [2, "stroustrup"] comma-dangle: [2, "always-multiline"] comma-style: [2, "last"] - computed-property-spacing: [2, "never"] dot-location: [2, "property"] one-var: [2, "never"] @@ -28,10 +30,13 @@ rules: prefer-const: [2] no-bitwise: [2] - object-shorthand: [2, "methods"] + object-curly-spacing: [2, "never"] + array-bracket-spacing: [2, "never"] + computed-property-spacing: [2, "never"] + + space-unary-ops: [2, {"words": true, "nonwords": false}] space-after-keywords: [2, "always"] space-before-blocks: [2, "always"] space-before-function-paren: [2, "never"] - space-in-brackets: [2, "never"] space-in-parens: [2, "never"] - spaced-line-comment: [2, "always"] + spaced-comment: [2, "always"] diff --git a/CHANGELOG.md b/CHANGELOG.md index 3d246384d2..0fbb5e6964 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,8 @@ +# 2.0.0 - 2015-08-25 + +- Removed: compatibility with postcss v4.x +- Added: compatibility with postcss v5.x + # 1.2.1 - 2015-06-16 - Fixed: selector was updated as an array, which is wrong. diff --git a/package.json b/package.json index 5ab0d5c926..6f6441fee4 100644 --- a/package.json +++ b/package.json @@ -1,9 +1,10 @@ { "name": "postcss-selector-not", - "version": "1.2.1", + "version": "2.0.0", "description": "PostCSS plugin to transform :not() W3C CSS leve 4 pseudo class to :not() CSS level 3 selectors", "keywords": [ "postcss", + "postcss-plugin", "selectors", "selector", "Not" @@ -14,25 +15,19 @@ "type": "git", "url": "https://github.com/postcss/postcss-selector-not.git" }, - "homepage": "https://github.com/postcss/postcss-selector-not", - "bugs": { - "url": "https://github.com/postcss/postcss-selector-not/issues" - }, + "main": "dist/index.js", "files": [ - "CHANGELOG.md", - "LICENSE", "dist" ], - "main": "dist/index.js", "dependencies": { "balanced-match": "^0.2.0", - "postcss": "^4.1.7" + "postcss": "^5.0.0" }, "devDependencies": { "babel": "^5.1.13", "babel-eslint": "^3.1.15", "babel-tape-runner": "^1.1.0", - "eslint": "^0.23.0", + "eslint": "^1.0.0", "tape": "^4.0.0" }, "scripts": { diff --git a/src/index.js b/src/index.js index 38a61d5bab..b6f1530cff 100644 --- a/src/index.js +++ b/src/index.js @@ -26,7 +26,7 @@ function explodeSelector(pseudoClass, selector) { function explodeSelectors(pseudoClass) { return () => { return (css) => { - css.eachRule(rule => { + css.walkRules(rule => { if (rule.selector && rule.selector.indexOf(pseudoClass) > -1) { rule.selector = explodeSelector(pseudoClass, rule.selector) } From a96a66012344e922399107fd0770f75672b608a2 Mon Sep 17 00:00:00 2001 From: Maxime Thirouin Date: Tue, 25 Aug 2015 07:23:03 +0200 Subject: [PATCH 301/795] 3.0.0 (switch to postcss 5.x) --- .eslintrc | 15 ++++++++++----- CHANGELOG.md | 5 +++++ package.json | 16 +++++----------- src/index.js | 10 +++++----- test/index.js | 8 ++++---- 5 files changed, 29 insertions(+), 25 deletions(-) diff --git a/.eslintrc b/.eslintrc index cb88f61c2e..db21f05621 100644 --- a/.eslintrc +++ b/.eslintrc @@ -2,6 +2,9 @@ # babel support more syntax stuff than eslint for now parser: babel-eslint +root: true +extends: eslint:recommended + ecmaFeatures: modules: true @@ -20,18 +23,20 @@ rules: brace-style: [2, "stroustrup"] comma-dangle: [2, "always-multiline"] comma-style: [2, "last"] - computed-property-spacing: [2, "never"] dot-location: [2, "property"] one-var: [2, "never"] - #no-var: [2] + no-var: [2] prefer-const: [2] no-bitwise: [2] - object-shorthand: [2, "methods"] + object-curly-spacing: [2, "never"] + array-bracket-spacing: [2, "never"] + computed-property-spacing: [2, "never"] + + space-unary-ops: [2, {"words": true, "nonwords": false}] space-after-keywords: [2, "always"] space-before-blocks: [2, "always"] space-before-function-paren: [2, "never"] - space-in-brackets: [2, "never"] space-in-parens: [2, "never"] - spaced-line-comment: [2, "always"] + spaced-comment: [2, "always"] diff --git a/CHANGELOG.md b/CHANGELOG.md index 3fad364779..53643bc26a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,8 @@ +# 3.0.0 - 2015-08-25 + +- Removed: compatibility with postcss v4.x +- Added: compatibility with postcss v5.x + # 2.3.0 - 2015-07-14 * Fixed: Nested/mixed selectors now works correctly diff --git a/package.json b/package.json index e4a37ac80b..12c204c2de 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "postcss-custom-selectors", - "version": "2.3.0", + "version": "3.0.0", "description": "PostCSS plugin to transform W3C CSS Extensions(Custom Selectors) to more compatible CSS", "keywords": [ "postcss", @@ -18,27 +18,21 @@ "type": "git", "url": "https://github.com/postcss/postcss-custom-selectors.git" }, - "homepage": "https://github.com/postcss/postcss-custom-selectors", - "bugs": { - "url": "https://github.com/postcss/postcss-custom-selectors/issues" - }, + "main": "dist/index.js", "files": [ - "CHANGELOG.md", - "LICENSE", "dist", "README-zh.md" ], - "main": "dist/index.js", "dependencies": { "balanced-match": "^0.2.0", - "postcss": "^4.1.7", - "postcss-selector-matches": "^1.2.1" + "postcss": "^5.0.0", + "postcss-selector-matches": "^2.0.0" }, "devDependencies": { "babel": "^5.5.8", "babel-eslint": "^3.1.15", "babel-tape-runner": "^1.1.0", - "eslint": "^0.23.0", + "eslint": "^1.0.0", "tape": "^4.0.0" }, "scripts": { diff --git a/src/index.js b/src/index.js index 19c712116e..bed17313c7 100644 --- a/src/index.js +++ b/src/index.js @@ -18,8 +18,8 @@ export default postcss.plugin("postcss-custom-selectors", function(options) { const transformMatchesOnRule = transformMatches ? (rule) => replaceRuleSelector(rule, { - lineBreak, - }) + lineBreak, + }) : (rule) => rule.selector return function(css, result) { @@ -27,7 +27,7 @@ export default postcss.plugin("postcss-custom-selectors", function(options) { const customSelectors = {} // first, read custom selectors - css.eachAtRule(function(rule) { + css.walkAtRules(function(rule) { if (rule.name !== "custom-selector") { return } @@ -47,7 +47,7 @@ export default postcss.plugin("postcss-custom-selectors", function(options) { }) // Convert those selectors to :matches() - css.eachRule(function(rule) { + css.walkRules(function(rule) { if (rule.selector.indexOf(":--") > -1) { rule.selector = rule.selector.replace( CUSTOM_SELECTOR_RE, @@ -71,7 +71,7 @@ export default postcss.plugin("postcss-custom-selectors", function(options) { }) toRemove.forEach(function(rule) { - rule.removeSelf() + rule.remove() }) } diff --git a/test/index.js b/test/index.js index 6f894ae898..9c7fac8e07 100644 --- a/test/index.js +++ b/test/index.js @@ -1,6 +1,6 @@ -var test = require("tape") -var postcss = require("postcss") -var plugin = require("../src") +import test from "tape" +import postcss from "postcss" +import plugin from "../src" function transform(input, opts = {}, postcssOpts = {}) { return postcss() @@ -268,7 +268,7 @@ main #nav .bar + p { "should transform local extensions" ) - var postcssPlugin = postcss().use(plugin()) + const postcssPlugin = postcss().use(plugin()) t.ok( postcssPlugin.process("@custom-selector :--foobar .foo;:--foobar{}").css, "should not create a memory" From 54e8aa45fce71075a9e5e587ea891c0d57bf740b Mon Sep 17 00:00:00 2001 From: Jonathan Neal Date: Mon, 31 Aug 2015 18:32:36 -0400 Subject: [PATCH 302/795] 1.0.0 --- .eslintrc | 128 ++++++++++++++++++++++++++++++++++++++++++++++----- .travis.yml | 1 - CHANGELOG.md | 6 +++ index.js | 6 +-- package.json | 14 +++--- 5 files changed, 132 insertions(+), 23 deletions(-) diff --git a/.eslintrc b/.eslintrc index 45b5afc50c..8e89382520 100644 --- a/.eslintrc +++ b/.eslintrc @@ -1,19 +1,123 @@ { "rules": { - "no-unused-expressions": [0], - "no-underscore-dangle": [0], - "no-reserved-keys": [2], - "no-multi-spaces": [0], - "no-unused-vars": [2], - "no-loop-func": [0], - "key-spacing": [0], - "strict": [0], - "indent": [1, "tab"], - "quotes": [2, "single", "avoid-escape"], - "curly": [0] + "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-use-before-define": [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": [2], + "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": [2], + "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": [2, "as-needed"], + "no-iterator": [2], + "no-new-func": [2], + "key-spacing": [2, { "align": "value" }], + "complexity": [2], + "new-parens": [2], + "no-eq-null": [2], + "no-bitwise": [2], + "wrap-iife": [2], + "no-caller": [2], + "use-isnan": [2], + "no-labels": [2], + "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/.travis.yml b/.travis.yml index ffb8b3996f..e1bd776499 100644 --- a/.travis.yml +++ b/.travis.yml @@ -3,4 +3,3 @@ language: node_js node_js: - iojs - "0.12" - - "0.10" diff --git a/CHANGELOG.md b/CHANGELOG.md index 7c4a795729..d7e43b69c0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,9 @@ +## 1.0.0 (2015-09-01) + +- Updated: PostCSS 5 +- Updated: Develop dependencies +- Updated: ESLint configuration + ## 0.3.0 (2015-06-16) - Added: Support for complex uses diff --git a/index.js b/index.js index 36bf7896aa..99dcc3249d 100644 --- a/index.js +++ b/index.js @@ -7,7 +7,7 @@ module.exports = postcss.plugin('postcss-pseudo-class-any-link', function (opts) return function (css) { // for each rule - css.eachRule(function (rule) { + css.walkRules(function (rule) { // update the selector rule.selector = postcssSelectorParser(function (selectors) { // cache variables @@ -21,12 +21,12 @@ module.exports = postcss.plugin('postcss-pseudo-class-any-link', function (opts) var selectorIndex = -1; // for each selector - while ((selector = selectors.nodes[++selectorIndex])) { + while (selector = selectors.nodes[++selectorIndex]) { // reset the node index nodeIndex = -1; // for each node - while ((node = selector.nodes[++nodeIndex])) { + while (node = selector.nodes[++nodeIndex]) { // if the node value matches the any-link value if (node.value === valueAnyLink) { // clone the selector diff --git a/package.json b/package.json index 35703d07bf..09df941df7 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "postcss-pseudo-class-any-link", - "version": "0.3.0", + "version": "1.0.0", "description": "Use the proposed :any-link pseudo-class in CSS", "keywords": ["postcss", "css", "postcss-plugin", "link", "visited", "any-link", "a", "area", "hyperlink", "href"], "author": "Jonathan Neal ", @@ -14,14 +14,14 @@ "url": "https://github.com/jonathantneal/postcss-pseudo-class-any-link.git" }, "dependencies": { - "postcss": "^4.1.9", - "postcss-selector-parser": "^1.0.0" + "postcss": "^5.0.3", + "postcss-selector-parser": "^1.1.4" }, "devDependencies": { - "chai": "^2.3.0", - "gulp": "^3.8.11", - "gulp-eslint": "^0.12.0", - "gulp-mocha": "^2.0.1" + "chai": "^3.2.0", + "gulp": "^3.9.0", + "gulp-eslint": "^1.0.0", + "gulp-mocha": "^2.1.3" }, "scripts": { "test": "gulp" From a605b317d1e46be87e1f1b8b55c858e382d2e0cb Mon Sep 17 00:00:00 2001 From: Ivan Vlasenko Date: Fri, 4 Sep 2015 08:32:04 +0300 Subject: [PATCH 303/795] Use postcss 5.0 --- index.js | 2 +- package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/index.js b/index.js index 46875f34f8..bee1d27047 100644 --- a/index.js +++ b/index.js @@ -17,7 +17,7 @@ module.exports = postcss.plugin('postcss-media-minmax', function () { ] // 读取 media-feature - css.eachAtRule(function(rule, i) { + css.walkAtRules(function(rule, i) { if (rule.name !== "media" && rule.name !== "custom-media") { return } diff --git a/package.json b/package.json index 22a6959f62..9606c93d74 100644 --- a/package.json +++ b/package.json @@ -27,7 +27,7 @@ "index.js" ], "dependencies": { - "postcss": "^4.1.14" + "postcss": "^5.0.4" }, "devDependencies": { "tape": "^3.0.0" From cb38acfcdff0ef3de185b3d341e6e2999b88c30c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=B8=80=E4=B8=9D?= Date: Sat, 5 Sep 2015 15:42:15 +0800 Subject: [PATCH 304/795] Use PostCSS 5.0 API --- CHANGELOG.md | 6 +++++- README-zh.md | 2 ++ README.md | 6 ++++-- package.json | 2 +- 4 files changed, 12 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 29104f332f..d6494f7bf8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,10 @@ +# 2.0.0 2015-09-05 + +Change: Use PostCSS 5.0 API. + # 1.2.0 2015-07-06 -Use PostCSS 4.1 plugin API. +Change: Use PostCSS 4.1 plugin API. # 1.1.0 2014-12-15 diff --git a/README-zh.md b/README-zh.md index 2ed34a69af..d82ab4c3e8 100644 --- a/README-zh.md +++ b/README-zh.md @@ -81,6 +81,8 @@ input.css: | '>' '='? '>' '='? ``` +![syntax](http://gtms03.alicdn.com/tps/i3/TB1Rje0HXXXXXXeXpXXccZJ0FXX-640-290.png) + PostCSS Media Minmax 目前并没有实现 `200px >= width` 或者 `200px <= width` 这样的语法,因为这样的语法可读性并不不是太好。 ## [取值(Values)](http://dev.w3.org/csswg/mediaqueries/#values) diff --git a/README.md b/README.md index 339210c9e6..2baf5e52e2 100644 --- a/README.md +++ b/README.md @@ -50,7 +50,7 @@ var output = postcss(minmax()) .css ``` -input.css: +input.css: ```css @media screen and (width >= 500px) and (width <= 1200px) { @@ -60,7 +60,7 @@ input.css: } ``` -You will get: +You will get: ```css @media screen and (min-width: 500px) and (max-width: 1200px) { @@ -81,6 +81,8 @@ You will get: | '>' '='? '>' '='? ``` +![syntax](http://gtms03.alicdn.com/tps/i3/TB1Rje0HXXXXXXeXpXXccZJ0FXX-640-290.png) + PostCSS Media Minmax hasn't implemented syntax such as `200px > = width` or `200px < = width` currently because its readability is not good enough yet. ## [Values](http://dev.w3.org/csswg/mediaqueries/#values) diff --git a/package.json b/package.json index 9606c93d74..b24e6c2d56 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "postcss-media-minmax", - "version": "1.2.0", + "version": "2.0.0", "description": "Using more intuitive `>=` or `<=` instead of media queries min/max prefix.", "scripts": { "test": "tape test" From d668a8959160e7ac56dbbbb3249c7ad5fc709c4a Mon Sep 17 00:00:00 2001 From: Jonathan Neal Date: Sat, 5 Sep 2015 17:31:15 -0400 Subject: [PATCH 305/795] Support for < and > without = --- CHANGELOG.md | 4 ++ index.js | 75 ++++++++++++++++++----------- package.json | 2 +- test/fixtures/min-max.css | 46 ++++++++++++++++++ test/fixtures/min-max.output.css | 46 ++++++++++++++++++ test/fixtures/monochrome.output.css | 2 +- test/index.js | 2 + 7 files changed, 146 insertions(+), 31 deletions(-) create mode 100644 test/fixtures/min-max.css create mode 100644 test/fixtures/min-max.output.css diff --git a/CHANGELOG.md b/CHANGELOG.md index d6494f7bf8..cae4169df5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,7 @@ +# 2.1.0 2015-09-05 + +Add: Support for `<` and `>` without `=`. + # 2.0.0 2015-09-05 Change: Use PostCSS 5.0 API. diff --git a/index.js b/index.js index bee1d27047..ed2f5802c1 100644 --- a/index.js +++ b/index.js @@ -2,19 +2,41 @@ var postcss = require('postcss'); module.exports = postcss.plugin('postcss-media-minmax', function () { return function(css) { + var feature_unit = { + 'width': 'px', + 'height': 'px', + 'device-width': 'px', + 'device-height': 'px', + 'aspect-ratio': '', + 'device-aspect-ratio': '', + 'color': '', + 'color-index': '', + 'monochrome': '', + 'resolution': 'dpi' + }; + //支持 min-/max- 前缀的属性 - var feature_name = [ - 'width', - 'height', - 'device-width', - 'device-height', - 'aspect-ratio', - 'device-aspect-ratio', - 'color', - 'color-index', - 'monochrome', - 'resolution' - ] + var feature_name = Object.keys(feature_unit); + + var step = .001; // smallest even number that won’t break complex queries (1in = 96px) + + var power = { + '>': 1, + '<': -1 + }; + + var minmax = { + '>': 'min', + '<': 'max' + }; + + function create_query(name, gtlt, eq, value, params) { + return value.replace(/([-\d\.]+)(.*)/, function (match, number, unit) { + number = parseFloat(number) || eq ? eq ? number : parseFloat(number) + step * power[gtlt] : power[gtlt] + feature_unit[name]; + + return '(' + minmax[gtlt] + '-' + name + ': ' + number + unit + ')'; + }); + } // 读取 media-feature css.walkAtRules(function(rule, i) { @@ -23,7 +45,7 @@ module.exports = postcss.plugin('postcss-media-minmax', function () { } /** - * 转换 <=|>= + * 转换 <|>= * $1 $2 $3 * (width >= 300px) => (min-width: 300px) * (width <= 900px) => (max-width: 900px) @@ -32,37 +54,32 @@ module.exports = postcss.plugin('postcss-media-minmax', function () { //取值不支持负值 //But -0 is always equivalent to 0 in CSS, and so is also accepted as a valid value. - rule.params = rule.params.replace(/\(\s*([a-z-]+?)\s*([<>]=)\s*((?:-?\d*\.?(?:\s*\/?\s*)?\d+[a-z]*)?)\s*\)/gi, function($0, $1, $2, $3) { + rule.params = rule.params.replace(/\(\s*([a-z-]+?)\s*([<>])(=?)\s*((?:-?\d*\.?(?:\s*\/?\s*)?\d+[a-z]*)?)\s*\)/gi, function($0, $1, $2, $3, $4) { var params = ''; if (feature_name.indexOf($1) > -1) { - if ($2 === '<=') { - params = '(' + 'max-' + $1 + ': ' + $3 + ')'; - } - if ($2 === '>=') { - params += '(' + 'min-' + $1 + ': ' + $3 + ')'; - } - return params; + return create_query($1, $2, $3, $4, rule.params); } //如果不是指定的属性,不做替换 return $0; }) /** - * 转换 <=|>= <=|>= - * $1 $2 $3 $4 $5 + * 转换 <|>= <|>= + * $1 $2 $3 $4$5 $5 * (500px <= width <= 1200px) => (min-width: 500px) and (max-width: 1200px) * (900px >= width >= 300px) => (min-width: 300px) and (max-width: 900px) */ - rule.params = rule.params.replace(/\(\s*((?:-?\d*\.?(?:\s*\/?\s*)?\d+[a-z]*)?)\s*(<=|>=)\s*([a-z-]+)\s*(<=|>=)\s*((?:-?\d*\.?(?:\s*\/?\s*)?\d+[a-z]*)?)\s*\)/gi, function($0, $1, $2, $3, $4, $5) { + rule.params = rule.params.replace(/\(\s*((?:-?\d*\.?(?:\s*\/?\s*)?\d+[a-z]*)?)\s*(<|>)(=?)\s*([a-z-]+)\s*(<|>)(=?)\s*((?:-?\d*\.?(?:\s*\/?\s*)?\d+[a-z]*)?)\s*\)/gi, function($0, $1, $2, $3, $4, $5, $6, $7) { + + if (feature_name.indexOf($4) > -1) { + if ($2 === '<' && $5 === '<' || $2 === '>' && $5 === '>') { + var min = ($2 === '<') ? $1 : $7; + var max = ($2 === '<') ? $7 : $1; - if (feature_name.indexOf($3) > -1) { - if ($2 === '<=' && $4 === '<=' || $2 === '>=' && $4 === '>=') { - var min = ($2 === '<=') ? $1 : $5; - var max = ($2 === '<=') ? $5 : $1; - return '(' + 'min-' + $3 + ': ' + min + ') and (' + 'max-' + $3 + ': ' + max + ')'; + return create_query($4, '>', $3, min) + ' and ' + create_query($4, '<', $6, max); } } //如果不是指定的属性,不做替换 diff --git a/package.json b/package.json index b24e6c2d56..2a67cb1d46 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "postcss-media-minmax", - "version": "2.0.0", + "version": "2.1.0", "description": "Using more intuitive `>=` or `<=` instead of media queries min/max prefix.", "scripts": { "test": "tape test" diff --git a/test/fixtures/min-max.css b/test/fixtures/min-max.css new file mode 100644 index 0000000000..f426d9e442 --- /dev/null +++ b/test/fixtures/min-max.css @@ -0,0 +1,46 @@ +@media screen and (width > 500px) and (width < 1200px) { + +} + +@media screen and (500px < width < 1200px) { + +} + +@media screen and (40em < width < 60em) { + +} + +@media screen and (6in < width < 9in) { + +} + +@media screen and (0 < width < 500.58px) { +} + +@media screen and (width) and (.08px < width < 0.68px) { + +} + +/* height */ +@media screen and (height > 500px) and (height < 1200px) { + +} + +@media screen and (500px < height < 1200px) { + +} + +@media screen and (40em < height < 60em) { + +} + +@media screen and (6in < height < 9in) { + +} + +@media screen and (0 < height < 500.58px) { +} + +@media screen and (height) and (.08px < height < 0.68px) { + +} diff --git a/test/fixtures/min-max.output.css b/test/fixtures/min-max.output.css new file mode 100644 index 0000000000..c088d64551 --- /dev/null +++ b/test/fixtures/min-max.output.css @@ -0,0 +1,46 @@ +@media screen and (min-width: 500.001px) and (max-width: 1199.999px) { + +} + +@media screen and (min-width: 500.001px) and (max-width: 1199.999px) { + +} + +@media screen and (min-width: 40.001em) and (max-width: 59.999em) { + +} + +@media screen and (min-width: 6.001in) and (max-width: 8.999in) { + +} + +@media screen and (min-width: 1px) and (max-width: 500.579px) { +} + +@media screen and (width) and (min-width: 0.081px) and (max-width: 0.679px) { + +} + +/* height */ +@media screen and (min-height: 500.001px) and (max-height: 1199.999px) { + +} + +@media screen and (min-height: 500.001px) and (max-height: 1199.999px) { + +} + +@media screen and (min-height: 40.001em) and (max-height: 59.999em) { + +} + +@media screen and (min-height: 6.001in) and (max-height: 8.999in) { + +} + +@media screen and (min-height: 1px) and (max-height: 500.579px) { +} + +@media screen and (height) and (min-height: 0.081px) and (max-height: 0.679px) { + +} diff --git a/test/fixtures/monochrome.output.css b/test/fixtures/monochrome.output.css index 5923e5dff2..0aaa9f8fd0 100644 --- a/test/fixtures/monochrome.output.css +++ b/test/fixtures/monochrome.output.css @@ -8,4 +8,4 @@ @media screen and (monochrome) and (min-monochrome: 1) and (max-monochrome: 300) { -} \ No newline at end of file +} diff --git a/test/index.js b/test/index.js index 3491397f2b..91b204ae42 100644 --- a/test/index.js +++ b/test/index.js @@ -33,5 +33,7 @@ test("@media", function(t) { compareFixtures(t, "other-name", "should transform") compareFixtures(t, "more-units", "should transform") + compareFixtures(t, "min-max", "should transform") + t.end() }) From 40495416bc2da46e485b3ebef8c7f1c42ab83045 Mon Sep 17 00:00:00 2001 From: Jed Mao Date: Mon, 7 Sep 2015 01:47:14 -0500 Subject: [PATCH 306/795] Fix scripts on Windows --- package.json | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/package.json b/package.json index 83306ba298..f659e66657 100644 --- a/package.json +++ b/package.json @@ -33,7 +33,9 @@ "tape": "^4.0.3" }, "scripts": { - "lint": "jscs *.js **/*.js && jshint . --exclude-path .gitignore", + "lint": "npm run jscs && npm run jshint", + "jscs": "jscs index.js test/index.js", + "jshint": "jshint . --exclude-path .gitignore", "test": "npm run lint && tape test" } } From f9b15338ef9367906b61ed39dc69cc50210647dd Mon Sep 17 00:00:00 2001 From: Jed Mao Date: Mon, 7 Sep 2015 01:48:20 -0500 Subject: [PATCH 307/795] Upgrade to Postcss 5.x --- index.js | 2 +- package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/index.js b/index.js index 13507fd27f..cbb5acadde 100755 --- a/index.js +++ b/index.js @@ -16,7 +16,7 @@ var DECIMAL_PRECISION = 100000 // 5 decimals */ module.exports = postcss.plugin("postcss-color-hex-alpha", function() { return function(style) { - style.eachDecl(function transformDecl(decl) { + style.walkDecls(function transformDecl(decl) { if (!decl.value || decl.value.indexOf("#") === -1) { return } diff --git a/package.json b/package.json index f659e66657..9972cd06f1 100644 --- a/package.json +++ b/package.json @@ -24,7 +24,7 @@ ], "dependencies": { "color": "^0.10.1", - "postcss": "^4.1.16", + "postcss": "^5.0.4", "postcss-message-helpers": "^2.0.0" }, "devDependencies": { From 6d1d3998e5fe2243694297d6a4221a0333a4ac0d Mon Sep 17 00:00:00 2001 From: Jed Mao Date: Mon, 7 Sep 2015 01:54:51 -0500 Subject: [PATCH 308/795] Fix scripts on Windows --- package.json | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/package.json b/package.json index 3b41e7bf5c..964b19632e 100644 --- a/package.json +++ b/package.json @@ -34,7 +34,9 @@ "tape": "^4.0.3" }, "scripts": { - "lint": "jscs *.js **/*.js && jshint . --exclude-path .gitignore", + "lint": "npm run jscs && npm run jshint", + "jscs": "jscs index.js test/index.js", + "jshint": "jshint . --exclude-path .gitignore", "test": "npm run lint && tape test" } } From 1965fb024c22d88423565a7d77de7f6c2fdb59d9 Mon Sep 17 00:00:00 2001 From: Jed Mao Date: Mon, 7 Sep 2015 01:56:16 -0500 Subject: [PATCH 309/795] Upgrade to PostCSS 5.x --- index.js | 2 +- package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/index.js b/index.js index 39e628a62e..c053e35ea0 100755 --- a/index.js +++ b/index.js @@ -11,7 +11,7 @@ var reduceFunctionCall = require("reduce-function-call") */ module.exports = postcss.plugin("postcss-color-hwb", function() { return function(style) { - style.eachDecl(function transformDecl(decl) { + style.walkDecls(function transformDecl(decl) { if (!decl.value || decl.value.indexOf("hwb(") === -1) { return } diff --git a/package.json b/package.json index 964b19632e..0b8ac739da 100644 --- a/package.json +++ b/package.json @@ -24,7 +24,7 @@ ], "dependencies": { "color": "^0.10.1", - "postcss": "^4.1.16", + "postcss": "^5.0.4", "postcss-message-helpers": "^2.0.0", "reduce-function-call": "^1.0.1" }, From afb814675673542eacd9df9454e365ef8a5f8e3b Mon Sep 17 00:00:00 2001 From: Jed Mao Date: Mon, 7 Sep 2015 02:00:40 -0500 Subject: [PATCH 310/795] Fix scripts on Windows --- package.json | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/package.json b/package.json index d8e58f2c0d..c568c11d09 100644 --- a/package.json +++ b/package.json @@ -32,7 +32,9 @@ "tape": "^4.0.0" }, "scripts": { - "lint": "jscs *.js **/*.js && jshint . --exclude-path .gitignore", + "lint": "npm run jscs && npm run jshint", + "jscs": "jscs index.js test/index.js", + "jshint": "jshint . --exclude-path .gitignore", "test": "npm run lint && tape test" } } From 25258bf31f01803abfbfc6ea94095b4cfa8a2fe5 Mon Sep 17 00:00:00 2001 From: Jed Mao Date: Mon, 7 Sep 2015 02:01:18 -0500 Subject: [PATCH 311/795] Upgrade to PostCSS 5.x --- index.js | 2 +- package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/index.js b/index.js index 7a36d07867..8908522038 100755 --- a/index.js +++ b/index.js @@ -9,7 +9,7 @@ var color = require("color")("rebeccapurple").rgbString() */ module.exports = postcss.plugin("postcss-color-rebeccapurple", function() { return function(style) { - style.eachDecl(function(decl) { + style.walkDecls(function(decl) { var value = decl.value; if (value && value.indexOf("rebeccapurple") !== -1) { diff --git a/package.json b/package.json index c568c11d09..7aef2c2ea6 100644 --- a/package.json +++ b/package.json @@ -24,7 +24,7 @@ ], "dependencies": { "color": "^0.9.0", - "postcss": "^4.1.13" + "postcss": "^5.0.4" }, "devDependencies": { "jscs": "^1.6.2", From 29c4b4674e06b0b56f1c0cf8174344fb2d6359f6 Mon Sep 17 00:00:00 2001 From: Jed Mao Date: Mon, 7 Sep 2015 02:05:41 -0500 Subject: [PATCH 312/795] Fix scripts on Windows --- package.json | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/package.json b/package.json index a7c9b47207..5e80ea78d5 100755 --- a/package.json +++ b/package.json @@ -30,7 +30,9 @@ "tape": "^4.0.3" }, "scripts": { - "lint": "jscs *.js **/*.js && jshint . --exclude-path .gitignore", + "lint": "npm run jscs && npm run jshint", + "jscs": "jscs index.js test/index.js", + "jshint": "jshint . --exclude-path .gitignore", "test": "npm run lint && tape test" } } From e1a86cdf4a9266807e263a7892630e7d479a2416 Mon Sep 17 00:00:00 2001 From: Jed Mao Date: Mon, 7 Sep 2015 02:06:37 -0500 Subject: [PATCH 313/795] Upgrade to PostCSS 5.x --- index.js | 6 +++--- package.json | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/index.js b/index.js index 61894f8fe3..69563f3e4a 100755 --- a/index.js +++ b/index.js @@ -68,7 +68,7 @@ for (var prop in fontVariantProperties) { // create if does not exist function getFontFeatureSettingsPrevTo(decl) { var fontFeatureSettings = null; - decl.parent.eachDecl(function(decl) { + decl.parent.walkDecls(function(decl) { if (decl.prop === "font-feature-settings") { fontFeatureSettings = decl; } @@ -88,10 +88,10 @@ function getFontFeatureSettingsPrevTo(decl) { */ module.exports = postcss.plugin("postcss-font-variant", function() { return function(styles) { - styles.eachRule(function(rule) { + styles.walkRules(function(rule) { var fontFeatureSettings = null // read custom media queries - rule.eachDecl(function(decl) { + rule.walkDecls(function(decl) { if (!fontVariantProperties[decl.prop]) { return null } diff --git a/package.json b/package.json index 5e80ea78d5..d7270b98f0 100755 --- a/package.json +++ b/package.json @@ -22,7 +22,7 @@ "index.js" ], "dependencies": { - "postcss": "^4.1.16" + "postcss": "^5.0.4" }, "devDependencies": { "jscs": "^2.1.0", From c0053830589d1b087c19e7b1cc0447ce536eb296 Mon Sep 17 00:00:00 2001 From: Jed Mao Date: Mon, 7 Sep 2015 01:21:43 -0500 Subject: [PATCH 314/795] Upgrade to PostCSS 5.x, fix specs --- .travis.yml | 2 +- appveyor.yml | 2 +- index.js | 75 ++++++++++++++++++++++++++++------------------------ package.json | 6 +++-- test.js | 20 +++++++++----- 5 files changed, 60 insertions(+), 45 deletions(-) diff --git a/.travis.yml b/.travis.yml index 548be277b9..1feff23f3b 100755 --- a/.travis.yml +++ b/.travis.yml @@ -4,7 +4,7 @@ git: language: node_js node_js: - '0.10' - - '0.11' + - '0.12' notifications: email: false after_script: diff --git a/appveyor.yml b/appveyor.yml index e6c2422fa4..a0bbbda61f 100755 --- a/appveyor.yml +++ b/appveyor.yml @@ -6,7 +6,7 @@ version: '{build}' environment: matrix: - nodejs_version: '0.10' - - nodejs_version: '0.11' + - nodejs_version: '0.12' install: - ps: Install-Product node $env:nodejs_version diff --git a/index.js b/index.js index 1b761e6ca4..bfbb08bcb9 100755 --- a/index.js +++ b/index.js @@ -6,50 +6,55 @@ 'use strict'; var color = require('color'); +var postcss = require('postcss'); var helpers = require('postcss-message-helpers'); var reduceFunctionCall = require('reduce-function-call'); -function parseGray(value) { - return reduceFunctionCall(value, 'gray', function(argString) { - var args = argString.split(','); +var pluginName = 'postcss-color-gray'; +var errorContext = {plugin: pluginName}; - var rgb = args[0] + ',' + args[0] + ',' + args[0]; - var alpha = args[1]; - if (alpha) { - alpha = alpha.trim(); - var match = alpha.match(/^[0-9](\d|\.)+?%$/); - if (match && match[0] === alpha) { - alpha = parseFloat(alpha) * 0.01; - } +function parseAlpha(alpha) { + if (alpha) { + var match = alpha.match(/^\d(\d|\.)+?%$/); + if (match && match[0] === alpha) { + return parseFloat(alpha) * 0.01; } + } + return alpha; +} - var parsedColor; - +function parseGray(decl) { + return reduceFunctionCall(decl.value, 'gray', function(body) { + if (/^,/.test(body) || /,$/.test(body)) { + throw decl.error( + 'Unable to parse color from string "gray(' + body + ')"', + errorContext + ); + } + var fn = 'rgb'; + var args = postcss.list.comma(body); + var lightness = args[0]; + var rgb = [lightness, lightness, lightness]; + var alpha = parseAlpha(args[1]); + if (alpha) { + fn += 'a'; + rgb.push(alpha); + } try { - if (alpha === undefined) { - parsedColor = color('rgb' + '(' + rgb + ')'); - } else { - parsedColor = color('rgba' + '(' + rgb + ',' + alpha + ')'); - } - return parsedColor.rgbString(); - - } catch (e) { - e.message = e.message.replace(/rgba?\(.*\)/, 'gray(' + args + ')'); - throw e; + return color(fn + '(' + rgb + ')').rgbString(); + } catch (err) { + var message = err.message.replace(/rgba?\(.*\)/, 'gray(' + args + ')'); + throw decl.error(message, errorContext); } }); } -function transformDecl(decl) { - if (decl.value && decl.value.indexOf('gray(') !== -1) { - decl.value = helpers.try(function transformGrayValue() { - return parseGray(decl.value); - }, decl.source); - } -} - -module.exports = function pluginColorGray() { - return function(style) { - style.eachDecl(transformDecl); +module.exports = postcss.plugin(pluginName, function() { + return function(root) { + root.walkDecls(function(decl) { + if (decl.value && decl.value.indexOf('gray(') !== -1) { + decl.value = helpers.try(parseGray.bind(this, decl), decl.source); + } + }); }; -}; +}); diff --git a/package.json b/package.json index bb3b5f4689..8d159026d7 100644 --- a/package.json +++ b/package.json @@ -11,7 +11,9 @@ "url": "https://github.com/shinnn" }, "scripts": { - "pretest": "eslint *.js && jscs *.js", + "pretest": "npm run eslint && npm run jscs", + "eslint": "eslint index.js test.js", + "jscs": "jscs index.js test.js", "test": "node test.js | tap-spec", "coverage": "istanbul cover test.js", "coveralls": "${npm_package_scripts_coverage} && istanbul-coveralls" @@ -39,6 +41,7 @@ ], "dependencies": { "color": "^0.7.3", + "postcss": "^5.0.4", "postcss-message-helpers": "^2.0.0", "reduce-function-call": "^1.0.1" }, @@ -47,7 +50,6 @@ "istanbul": "^0.3.5", "istanbul-coveralls": "^1.0.1", "jscs": "^1.8.1", - "postcss": "^4.0.2", "tap-spec": "^2.1.0", "tape": "^3.0.3" } diff --git a/test.js b/test.js index 6457aab0fb..9dc53483a8 100755 --- a/test.js +++ b/test.js @@ -9,7 +9,7 @@ function useGray() { } test('filterDeclarations()', function(t) { - t.plan(7); + t.plan(8); t.equal( useGray().process('a {color: gray(200); background: gray(00000034%)}').css, @@ -31,7 +31,7 @@ test('filterDeclarations()', function(t) { t.throws( function() { - useGray().process('a {color: gray()}'); + return useGray().process('a {color: gray()}').css; }, /Unable to parse color from string "gray\(\)"/, 'should throw an error when gray() doesn\'t take any arguments.' @@ -39,15 +39,23 @@ test('filterDeclarations()', function(t) { t.throws( function() { - useGray().process('a {color: gray(,foo)}'); + return useGray().process('a {color: gray(,foo)}').css; }, /:1:4: Unable to parse color from string "gray\(,foo\)"/, - 'should throw an error when gray() takes invalid argument.' + 'should throw an error when gray() args start with a comma.' ); t.throws( function() { - useGray().process('a {color: gray(red)}', {from: 'fixture.css'}); + return useGray().process('a {color: gray(foo,)}').css; + }, + /:1:4: Unable to parse color from string "gray\(foo,\)"/, + 'should throw an error when gray() args end with a comma.' + ); + + t.throws( + function() { + return useGray().process('a {color: gray(red)}', {from: 'fixture.css'}).css; }, /fixture\.css:1:4: Unable to parse color from string "gray\(red\)"/, 'should throw a detailed error when a source file is specified.' @@ -55,7 +63,7 @@ test('filterDeclarations()', function(t) { t.throws( function() { - useGray().process('a {color: gray(,)}', {map: true}); + return useGray().process('a {color: gray(,)}', {map: true}).css; }, /:1:4: Unable to parse color from string "gray\(,\)"/, 'should throw a detailed error when source map is enabled but file isn\'t specified.' From 4d9bf3be4d78fec9eeff25a868c5ed53ab4a7a32 Mon Sep 17 00:00:00 2001 From: Maxime Thirouin Date: Tue, 8 Sep 2015 06:21:30 +0200 Subject: [PATCH 315/795] 3.0.0 (switch to postcss v5.x) --- CHANGELOG.md | 5 +++++ package.json | 7 +++---- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8f991d9506..7f5ba18221 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,8 @@ +# 3.0.0 - 2015-09-08 + +- Added: compatibility with postcss v5.x +- Removed: compatiblity with postcss v4.x + # 2.0.0 - 2015-01-26 - Added: compatibility with postcss v4.x diff --git a/package.json b/package.json index 8d159026d7..e1df3112be 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "postcss-color-gray", - "version": "2.0.0", + "version": "3.0.0", "description": "PostCSS plugin to transform gray() function to today's CSS", "repository": { "type": "git", @@ -25,8 +25,7 @@ } ], "files": [ - "index.js", - "LICENSE" + "index.js" ], "keywords": [ "css", @@ -34,7 +33,7 @@ "style", "stylesheet", "postcss", - "postcss-plugins", + "postcss-plugin", "color", "gray", "function" From 382fd873556753edf890250100058942cba5b507 Mon Sep 17 00:00:00 2001 From: Maxime Thirouin Date: Tue, 8 Sep 2015 06:24:25 +0200 Subject: [PATCH 316/795] 2.0.0 (switch to postcss v5.x) --- CHANGELOG.md | 5 +++++ package.json | 4 +--- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1961215118..11aa4be506 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,8 @@ +# 2.0.0 - 2015-09-08 + +- Added: compatibility with postcss v5.x +- Removed: compatiblity with postcss v4.x + # 1.3.0 - 2015-08-13 - Added: compatibility with postcss v4.1.x diff --git a/package.json b/package.json index 9972cd06f1..8b25823af0 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "postcss-color-hex-alpha", - "version": "1.3.0", + "version": "2.0.0", "description": "PostCSS plugin to transform W3C RGBA hexadecimal notations (#RRGGBBAA or #RGBA) to more compatible CSS (rgba())", "keywords": [ "css", @@ -18,8 +18,6 @@ "url": "https://github.com/postcss/postcss-color-hex-alpha.git" }, "files": [ - "CHANGELOG.md", - "LICENSE", "index.js" ], "dependencies": { From d9240647217e9c36f77f03baecc8f5f557693419 Mon Sep 17 00:00:00 2001 From: Maxime Thirouin Date: Tue, 8 Sep 2015 06:33:51 +0200 Subject: [PATCH 317/795] 2.0.0 (switch to postcss v5.x) --- CHANGELOG.md | 5 +++++ package.json | 4 +--- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d62ebd79f8..aa3efff052 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,8 @@ +# 2.0.0 - 2015-09-08 + +- Added: compatibility with postcss v5.x +- Removed: compatiblity with postcss v4.x + # 1.2.0 - 2015-08-13 - Added: compatibility with postcss v4.1.x diff --git a/package.json b/package.json index 0b8ac739da..52761b2976 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "postcss-color-hwb", - "version": "1.2.0", + "version": "2.0.0", "description": "PostCSS plugin to transform W3C CSS hwb() color to more compatible CSS (rgb() (or rgba()))", "keywords": [ "css", @@ -18,8 +18,6 @@ "url": "https://github.com/postcss/postcss-color-hwb.git" }, "files": [ - "CHANGELOG.md", - "LICENSE", "index.js" ], "dependencies": { From c4bc1c89bff406154167963244695bccb3d61f98 Mon Sep 17 00:00:00 2001 From: Maxime Thirouin Date: Tue, 8 Sep 2015 06:35:27 +0200 Subject: [PATCH 318/795] 2.0.0 (switch to postcss v5.x) --- CHANGELOG.md | 7 ++++++- package.json | 4 +--- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 44788998d0..9dffdb1623 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,9 @@ -# 1.2.0 - 2015-07-01 +# 2.0.0 - 2015-09-08 + +- Added: compatibility with postcss v5.x +- Removed: compatiblity with postcss v4.x + +# 1.2.0 - 2015-08-13 - Added: compatibility with postcss v4.1.x ([#4](https://github.com/postcss/postcss-color-rebeccapurple/pull/4)) diff --git a/package.json b/package.json index 7aef2c2ea6..c3a9bb8809 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "postcss-color-rebeccapurple", - "version": "1.2.0", + "version": "2.0.0", "description": "PostCSS plugin to transform W3C CSS rebeccapurple color to more compatible CSS (rgb())", "keywords": [ "css", @@ -18,8 +18,6 @@ "url": "https://github.com/postcss/postcss-color-rebeccapurple.git" }, "files": [ - "CHANGELOG.md", - "LICENSE", "index.js" ], "dependencies": { From d864dd073b3e4ea7b8e74a0cf64a37bfd541c29a Mon Sep 17 00:00:00 2001 From: Maxime Thirouin Date: Tue, 8 Sep 2015 06:45:19 +0200 Subject: [PATCH 319/795] 2.0.0 (switch to postcss v5.x) --- CHANGELOG.md | 5 +++++ package.json | 4 +--- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e0265d637f..edc2c46bce 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,8 @@ +# 2.0.0 - 2015-09-08 + +- Added: compatibility with postcss v5.x +- Removed: compatiblity with postcss v4.x + # 1.2.0 - 2015-08-13 - Added: compatibility with postcss v4.1.x diff --git a/package.json b/package.json index d7270b98f0..7366a01dc8 100755 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "postcss-font-variant", - "version": "1.2.0", + "version": "2.0.0", "description": "PostCSS plugin to transform W3C font-variant properties to more compatible CSS (font-feature-settings)", "keywords": [ "css", @@ -17,8 +17,6 @@ "url": "https://github.com/postcss/postcss-font-variant.git" }, "files": [ - "CHANGELOG.md", - "LICENSE", "index.js" ], "dependencies": { From d2efd496fd0e17ae596bea6add2b004b3c2e1130 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=B8=80=E4=B8=9D?= Date: Tue, 8 Sep 2015 22:00:12 +0800 Subject: [PATCH 320/795] Update docs --- CHANGELOG.md | 4 ++-- README-zh.md | 2 ++ README.md | 2 ++ package.json | 2 +- 4 files changed, 7 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index cae4169df5..972aa1f299 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,4 @@ -# 2.1.0 2015-09-05 +# 2.1.0 2015-09-08 Add: Support for `<` and `>` without `=`. @@ -12,7 +12,7 @@ Change: Use PostCSS 4.1 plugin API. # 1.1.0 2014-12-15 -Add `( 300px <= width <= 900px)` or `( 900px >= width >= 300px)` syntax. +Add: `( 300px <= width <= 900px)` or `( 900px >= width >= 300px)` syntax. # 1.0.0 diff --git a/README-zh.md b/README-zh.md index d82ab4c3e8..63689216cf 100644 --- a/README-zh.md +++ b/README-zh.md @@ -9,6 +9,8 @@ Media Queries 中的 `min-width` 和 `max-width` 等属性非常容易混淆,每次看到他们,我都想哭。现在[新的规范](http://dev.w3.org/csswg/mediaqueries/#mq-min-max)中,可以使用更加直观的 `>=`或`<=` 替代 media queries 中的 min-/max- 前缀。 +**V2.1.0 开始支持 `>` 或 `<` 符号。** + 这是一个实现 [CSS Media Queries Level 4](http://dev.w3.org/csswg/mediaqueries/) Polyfill 的插件,让你现在就可以使用这些特性,妈妈再也不用担心我记不住了,鹅妹子嘤! diff --git a/README.md b/README.md index 2baf5e52e2..8683f6b26c 100644 --- a/README.md +++ b/README.md @@ -9,6 +9,8 @@ The `min-width`, `max-width` and many other properties of media queries are really confusing. I want to cry every time I see them. But right now according to the new specs, you can use more intuitive `<=` or `>=` to replace the `min-`/`max-` prefixes in media queries. +V2.1.0 began to support `>` or `<` symbol. + This is a polyfill plugin which supports [CSS Media Queries Level 4](http://dev.w3.org/csswg/mediaqueries/) and gives you access to the new features right away. Mom will never worry about my study any more. So amazing! diff --git a/package.json b/package.json index 2a67cb1d46..85023e1f06 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "postcss-media-minmax", "version": "2.1.0", - "description": "Using more intuitive `>=` or `<=` instead of media queries min/max prefix.", + "description": "Using more intuitive `>=`, `<=`, `>`, `<` instead of media queries min/max prefix.", "scripts": { "test": "tape test" }, From d431f74646397002cf3611c75e0f7dae8f3263d1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=B8=80=E4=B8=9D?= Date: Tue, 8 Sep 2015 22:05:58 +0800 Subject: [PATCH 321/795] Add rem test case --- test/fixtures/min-max.css | 8 ++++++++ test/fixtures/min-max.output.css | 8 ++++++++ 2 files changed, 16 insertions(+) diff --git a/test/fixtures/min-max.css b/test/fixtures/min-max.css index f426d9e442..5c4f39b772 100644 --- a/test/fixtures/min-max.css +++ b/test/fixtures/min-max.css @@ -10,6 +10,10 @@ } +@media screen and (13.8rem < width <= 51.2rem) { + +} + @media screen and (6in < width < 9in) { } @@ -34,6 +38,10 @@ } +@media screen and (13.8rem <= height < 51.2rem) { + +} + @media screen and (6in < height < 9in) { } diff --git a/test/fixtures/min-max.output.css b/test/fixtures/min-max.output.css index c088d64551..cc8784dd8d 100644 --- a/test/fixtures/min-max.output.css +++ b/test/fixtures/min-max.output.css @@ -10,6 +10,10 @@ } +@media screen and (min-width: 13.801rem) and (max-width: 51.2rem) { + +} + @media screen and (min-width: 6.001in) and (max-width: 8.999in) { } @@ -34,6 +38,10 @@ } +@media screen and (min-height: 13.8rem) and (max-height: 51.199000000000005rem) { + +} + @media screen and (min-height: 6.001in) and (max-height: 8.999in) { } From a3f04a9408ad6845b2409b349bbf88c74ccd7af7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=B8=80=E4=B8=9D?= Date: Tue, 8 Sep 2015 22:13:11 +0800 Subject: [PATCH 322/795] Change to right float number --- test/fixtures/min-max.output.css | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/fixtures/min-max.output.css b/test/fixtures/min-max.output.css index cc8784dd8d..5c962ae7ea 100644 --- a/test/fixtures/min-max.output.css +++ b/test/fixtures/min-max.output.css @@ -38,7 +38,7 @@ } -@media screen and (min-height: 13.8rem) and (max-height: 51.199000000000005rem) { +@media screen and (min-height: 13.8rem) and (max-height: 51.199rem) { } From 934eeb80202aeb17c317caf18640dbf1365d0bdd Mon Sep 17 00:00:00 2001 From: Jonathan Neal Date: Tue, 8 Sep 2015 10:39:48 -0400 Subject: [PATCH 323/795] Prevent rounding errors on floats --- index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/index.js b/index.js index ed2f5802c1..9db473e4ec 100644 --- a/index.js +++ b/index.js @@ -32,7 +32,7 @@ module.exports = postcss.plugin('postcss-media-minmax', function () { function create_query(name, gtlt, eq, value, params) { return value.replace(/([-\d\.]+)(.*)/, function (match, number, unit) { - number = parseFloat(number) || eq ? eq ? number : parseFloat(number) + step * power[gtlt] : power[gtlt] + feature_unit[name]; + number = parseFloat(number) || eq ? eq ? number : Number(Math.round(parseFloat(number) + step * power[gtlt] + 'e6')+'e-6') : power[gtlt] + feature_unit[name]; return '(' + minmax[gtlt] + '-' + name + ': ' + number + unit + ')'; }); From c1436d9a3e83cb12fb5130dabbd46dcfc4b745f1 Mon Sep 17 00:00:00 2001 From: Jonathan Neal Date: Tue, 15 Sep 2015 09:14:53 -0400 Subject: [PATCH 324/795] Update plugin Refactor based on Tab Atkins new syntax --- index.js | 180 +++++++++++++++++++++++++------------------------------ 1 file changed, 80 insertions(+), 100 deletions(-) diff --git a/index.js b/index.js index 636afc215d..490226af39 100644 --- a/index.js +++ b/index.js @@ -1,117 +1,97 @@ +var bubble = ['media']; var postcss = require('postcss'); -var parser = require('postcss-selector-parser'); -function parse(selector) { - return parser().process(selector).res; +function transpileSelectors(fromRule, toRule) { + var selectors = []; + + fromRule.selectors.forEach(function (fromSelector) { + toRule.selectors.forEach(function (toSelector) { + if (toSelector.indexOf('&') === -1) { + selectors.push(fromSelector + ' ' + toSelector); + } else { + selectors.push(toSelector.replace(/&/g, fromSelector)); + } + }); + }); + + return selectors; } -function isNestingRule(rule) { - return rule && !rule.selector && rule.parent && rule.parent.type === 'rule'; +function transpileNestRule(fromRule, toRule, atRule) { + var parent = fromRule.parent; + + if (!('nestedIndex' in parent)) { + parent.nestedIndex = parent.nodes.indexOf(fromRule); + } + + fromRule.nodes.splice(fromRule.nodes.indexOf(atRule), 1); + + toRule.nodes = atRule.nodes.splice(0); + toRule.parent = parent; + toRule.selector = atRule.params; + toRule.selectors = transpileSelectors(fromRule, toRule); + + parent.nodes.splice(++parent.nestedIndex, 0, toRule); } -function hasParentReference(node) { - if (node.type === 'tag') { - return node.value === '&'; +function transpileAtRule(fromRule, toRule, atRule) { + var parent = fromRule.parent; + + if (!('nestedIndex' in parent)) { + parent.nestedIndex = parent.nodes.indexOf(fromRule); } - for (var index in node.nodes) { - if (hasParentReference(node.nodes[index])) { - return true; + fromRule.nodes.splice(fromRule.nodes.indexOf(atRule), 1); + + toRule.nodes = atRule.nodes.splice(0); + toRule.parent = atRule; + toRule.selector = fromRule.selector; + + atRule.nodes = [toRule]; + atRule.parent = parent; + + parent.nodes.splice(++parent.nestedIndex, 0, atRule); +} + +function transpileRule(rule) { + var nodes = rule.nodes; + var index = -1; + var child; + + // for each node + while (child = nodes[++index]) { + // if node is atrule + if (child.type === 'atrule') { + var newRule = postcss.rule(); + + // if atrule is nest + if (child.name === 'nest') { + transpileNestRule(rule, newRule, child); + + transpileRule(newRule); + } else if (bubble.indexOf(child.name) !== -1) { + transpileAtRule(rule, newRule, child); + + transpileRule(newRule); + + --index; + } } } - - return false; } -module.exports = postcss.plugin('postcss-nesting', function (opts) { - opts = opts || {}; +module.exports = postcss.plugin('postcss-nested', function (opts) { + if (opts && opts.bubble) bubble = bubble.concat(opts.bubble); return function (css) { - // for each rule in css - css.eachRule(function (nestingRule) { - // if the rule is a nesting rule - if (isNestingRule(nestingRule)) { - // cache parent selectors - var parentSelectors = nestingRule.parent.selector; - var parentSelectorsObject = parse(parentSelectors); - - // for each rule in the nesting rule - nestingRule.eachRule(function (rule, ruleIndex) { - var newSelectors = parser.root(); - - // for each selector in the rule - parse(rule.selector).each(function (selector) { - // if the selector has a parent reference - if (hasParentReference(selector)) { - // HINT: selectors = parent selectors × parent references - - var cloneSelectorList = parser.root(); - - cloneSelectorList.append(selector.clone()); - - while (hasParentReference(cloneSelectorList)) { - var cloneSelector; - var cloneSelectorIndex = -1; - var cloneNode; - var cloneNodeIndex; - var parentSelector2; - var parentSelectorIndex; - - while ((cloneSelector = cloneSelectorList.nodes[++cloneSelectorIndex])) { - cloneNodeIndex = -1; - - while ((cloneNode = cloneSelector.nodes[++cloneNodeIndex])) { - if (hasParentReference(cloneNode)) { - parentSelectorIndex = -1; - - while ((parentSelector2 = parentSelectorsObject.nodes[++parentSelectorIndex])) { - cloneSelector.nodes.splice(cloneNodeIndex, 1, parentSelector2); - - cloneSelectorList.nodes.splice(cloneSelectorIndex + parentSelectorIndex + 1, 0, cloneSelector.clone()); - } - - cloneSelectorList.nodes.splice(cloneSelectorIndex, 1); - - break; - } - } - } - } - - newSelectors.append(cloneSelectorList); - } - // if the selector does not have a parent reference - else { - // for each parent selector - parse(parentSelectors).each(function (parentSelector) { - // create a new selector - var newSelector = parser.selector(); - - // append the parent selector to the new selector - newSelector.append(parentSelector); - - // append a combinator to the new selector - newSelector.append(parser.combinator({ value: ' ' })); - - // append the selector to the new selector - newSelector.append(selector); - - // append the new selector to the new selectors - newSelectors.append(newSelector); - }); - } - }); - - // replace the rule selector with the new selectors - rule.selector = newSelectors.toString(); - - // append the rule after the nesting rule - nestingRule.parent.parent.nodes.splice(nestingRule.parent.parent.nodes.indexOf(nestingRule.parent) + ruleIndex + 1, 0, rule); - }); - - // remove original nesting rule - nestingRule.removeSelf(); + var nodes = css.nodes; + var index = -1; + var child; + + while (child = nodes[++index]) { + if (child.type === 'rule') { + transpileRule(child); } - }); + } }; }); From 11a47039e77d05a16adf97e2b23bc6190b66db23 Mon Sep 17 00:00:00 2001 From: Jonathan Neal Date: Tue, 15 Sep 2015 09:22:39 -0400 Subject: [PATCH 325/795] Update tests Follow Tab Atkins new syntax Update to PostCSS 5 and PostCSS 5 best practices --- .eslintrc | 2 +- .travis.yml | 1 - gulpfile.js | 11 ++++++++-- package.json | 61 +++++++++++++++++++++++++++++++--------------------- test/test.js | 44 +++++++++++++++++++++++-------------- 5 files changed, 75 insertions(+), 44 deletions(-) diff --git a/.eslintrc b/.eslintrc index 8966b851d8..23ac9db96c 100644 --- a/.eslintrc +++ b/.eslintrc @@ -6,8 +6,8 @@ "no-multi-spaces": [0], "no-unused-vars": [2], "no-loop-func": [0], + "no-cond-assign": [0], "key-spacing": [0], - "max-len": [2], "strict": [0], "quotes": [2, "single", "avoid-escape"], "curly": [0] diff --git a/.travis.yml b/.travis.yml index ffb8b3996f..e1bd776499 100644 --- a/.travis.yml +++ b/.travis.yml @@ -3,4 +3,3 @@ language: node_js node_js: - iojs - "0.12" - - "0.10" diff --git a/gulpfile.js b/gulpfile.js index 1fc565b0b9..33bd8cf5ca 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -1,8 +1,10 @@ var gulp = require('gulp'); +var files = ['index.js', 'test/*.js', 'gulpfile.js']; + gulp.task('lint', function () { var eslint = require('gulp-eslint'); - return gulp.src(['index.js', 'test/*.js', 'gulpfile.js']) + return gulp.src(files) .pipe(eslint()) .pipe(eslint.format()) .pipe(eslint.failAfterError()); @@ -10,7 +12,12 @@ gulp.task('lint', function () { gulp.task('test', function () { var mocha = require('gulp-mocha'); - return gulp.src('test/*.js', { read: false }).pipe(mocha()); + return gulp.src('test/*.js', { read: false }) + .pipe(mocha()); }); gulp.task('default', ['lint', 'test']); + +gulp.task('watch', function () { + gulp.watch(files, ['lint', 'test']); +}); diff --git a/package.json b/package.json index 478e9c8026..89ae782438 100644 --- a/package.json +++ b/package.json @@ -1,26 +1,39 @@ { - "name": "postcss-nesting", - "version": "0.1.0", - "description": "PostCSS plugin ability to nest one style rule inside another", - "keywords": ["postcss", "css", "postcss-plugin", "nesting", "selector", "rule"], - "author": "Jonathan Neal ", - "license": "MIT", - "repository": { - "type": "git", - "url": "https://github.com/jonathantneal/postcss-nesting.git" - }, - "dependencies": { - "postcss": "^4.1.9", - "postcss-selector-parser": "^1.0.0" - }, - "devDependencies": { - "gulp-eslint": "^0.12.0", - "gulp-mocha": "^2.0.1", - "chai": "^2.3.0", - "gulp": "^3.8.11", - "gulp-watch": "^4.2.4" - }, - "scripts": { - "test": "gulp" - } + "name": "postcss-nesting", + "version": "0.1.0", + "description": "Transpiles nested rules according to CSS Nesting Module Level 3", + "keywords": [ + "postcss", + "css", + "postcss-plugin", + "nestings", + "selectors", + "rules" + ], + "author": "Jonathan Neal ", + "license": "CC0-1.0", + "repository": { + "type": "git", + "url": "https://github.com/jonathantneal/postcss-nesting.git" + }, + "bugs": { + "url": "https://github.com/jonathantneal/postcss-nesting/issues" + }, + "homepage": "https://github.com/jonathantneal/postcss-nesting", + "dependencies": { + "postcss": "^5.0.5" + }, + "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/test.js b/test/test.js index 6f457b94dc..020d60bd8f 100644 --- a/test/test.js +++ b/test/test.js @@ -1,24 +1,36 @@ var postcss = require('postcss'); +var nested = require('../'); var expect = require('chai').expect; -var plugin = require('../'); +var check = function (input, output, opts) { + var processor = postcss([ nested(opts) ]); + expect( processor.process(input).css ).to.equal(output); +}; -var test = function (input, output, opts, done) { - postcss([ plugin(opts) ]).process(input).then(function (result) { - expect(result.css).to.eql(output); - expect(result.warnings()).to.be.empty; - done(); - }).catch(function (error) { - done(error); +describe('postcss-nested', function () { + it('ignores sass nesting', function () { + check('z { color: red } a, b { color: white; & c, & d { color: blue } }', + 'z { color: red } a, b { color: white; & c, & d { color: blue } }'); + }); + + it('unwraps css nesting', function () { + check('z { color: red } a, b { color: white; @nest & c, & d { color: blue } }', + 'z { color: red } a, b { color: white } a c, a d, b c, b d { color: blue }'); + }); + + it('unwraps css deep nesting', function () { + check('z { color: red } a, b { color: white; @nest & c, & d { color: blue; @nest & e, & f { color: black } } }', + 'z { color: red } a, b { color: white } a c, a d, b c, b d { color: blue } a c e, a c f, a d e, a d f, b c e, b c f, b d e, b d f { color: black }'); + }); + + it('unwraps mixed nesting', function () { + check('a { color: red; @media { color: white; @nest b { color: blue } } }', + 'a { color: red } @media { a { color: white } a b { color: blue } }'); }); -}; -describe('postcss-nesting', function () { - it('basic usage', function (done) { - test( - 'a,b{color:red;{c,d{color:white;}& &{color:blue;}&:hover{color:white;}}}', - 'a,b{color:red}a c,b c,a d,b d{color:white;}a a,a b,b a,b b{color:blue;}a:hover,b:hover{color:white;}', - {}, - done); + it('unwraps specified at-rules', function () { + check('a { color: red; @unknown test { color: white } } b { color: white; @phone { color: blue } @media { color: black; @nest c { color: yellow } } }', + 'a { color: red; @unknown test { color: white } } b { color: white } @phone { b { color: blue } } @media { b { color: black } b c { color: yellow } }', + { bubble: ['phone'] }); }); }); From 60dd7b0fcc559df45764b305db40a9a99a232ae8 Mon Sep 17 00:00:00 2001 From: Jonathan Neal Date: Tue, 15 Sep 2015 09:22:54 -0400 Subject: [PATCH 326/795] 1.0.0 --- .eslintrc | 125 ++++++++++++++++++++++++++++++++++++++++++++++----- CHANGELOG.md | 6 +++ package.json | 2 +- 3 files changed, 121 insertions(+), 12 deletions(-) diff --git a/.eslintrc b/.eslintrc index 23ac9db96c..c6fb69a980 100644 --- a/.eslintrc +++ b/.eslintrc @@ -1,16 +1,119 @@ { "rules": { - "no-unused-expressions": [0], - "no-underscore-dangle": [0], - "no-reserved-keys": [2], - "no-multi-spaces": [0], - "no-unused-vars": [2], - "no-loop-func": [0], - "no-cond-assign": [0], - "key-spacing": [0], - "strict": [0], - "quotes": [2, "single", "avoid-escape"], - "curly": [0] + "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": [2], + "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": [2, "as-needed"], + "no-iterator": [2], + "no-new-func": [2], + "key-spacing": [2, { "align": "value" }], + "complexity": [2], + "new-parens": [2], + "no-eq-null": [2], + "no-bitwise": [2], + "wrap-iife": [2], + "no-caller": [2], + "use-isnan": [2], + "no-labels": [2], + "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, diff --git a/CHANGELOG.md b/CHANGELOG.md index f3bfd0f08b..ecaba1d829 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,9 @@ +## 1.0.0 (2015-09-15) + +- Added: New `@nest` at-rule syntax +- Updated: PostCSS 5 +- Removed: Old inner bracket syntax + ## 0.1.0 (2015-06-17) - Added: Initial release diff --git a/package.json b/package.json index 89ae782438..564315628b 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "postcss-nesting", - "version": "0.1.0", + "version": "1.0.0", "description": "Transpiles nested rules according to CSS Nesting Module Level 3", "keywords": [ "postcss", From 1931fbbd6a1e3ecf5aea1c73fed37307937544a3 Mon Sep 17 00:00:00 2001 From: Jonathan Neal Date: Tue, 15 Sep 2015 09:27:52 -0400 Subject: [PATCH 327/795] Update documentation --- README.md | 103 +++++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 74 insertions(+), 29 deletions(-) diff --git a/README.md b/README.md index 49cd76bf30..ac870ab490 100644 --- a/README.md +++ b/README.md @@ -1,8 +1,10 @@ -# PostCSS Nesting [![Build Status][ci-img]][ci] +# CSS Nesting [![Build Status][ci-img]][ci] -[PostCSS Nesting] is a [PostCSS] plugin that transforms W3C [CSS Nesting Module Level 3] syntax (@tabatkins’ proposal) to more compatible CSS. +[CSS Nesting] is a [PostCSS] plugin that allows you to nest one style rule inside another, similar to Sass, but following the [CSS Nesting Module Level 3] specification. + +This greatly increases the modularity and maintainability of CSS stylesheets. ```css /* before */ @@ -10,18 +12,19 @@ a, b { color: red; - { - c, d { - color: white; - } + @nest c, d { + color: white; - & & { - color: blue; - } + @nest & & { + color: blue; + } - &:hover { - color: white; - } + @nest &:hover { + color: black; + } + + @media (min-width: 30em) { + color: yellow; } } @@ -40,39 +43,81 @@ a a, a b, b a, b b { } a:hover, b:hover { - color: white; + color: black; } -``` -From [CSS Nesting Module Level 3]: -> This module introduces the ability to nest one style rule inside another, with the selector of the child rule relative to the selector of the parent rule. This increase the modularity and maintainability of CSS stylesheets. +@media (min-width: 30em) { + a, b { + color: yellow; + } +} +``` ## Usage -You just need to follow these two steps to use [PostCSS Nesting]: +Follow these steps to use [CSS Nesting]. -1. Add [PostCSS] to your build tool. -2. Add [PostCSS Nesting] as a PostCSS process. +Add [CSS Nesting] to your build tool: -```sh +```bash npm install postcss-nesting --save-dev ``` -### Node +#### Node ```js -postcss([ require('postcss-nesting')({ /* options */ }) ]) +require('postcss-nesting')({ /* options */ }).process(YOUR_CSS); ``` -### Grunt +#### PostCSS -Install [Grunt PostCSS]: +Add [PostCSS] to your build tool: -```shell -npm install postcss-nesting --save-dev +```bash +npm install postcss --save-dev +``` + +Load [CSS Nesting] as a PostCSS plugin: + +```js +postcss([ + require('postcss-nesting')({ /* options */ }) +]); +``` + +#### Gulp + +Add [Gulp PostCSS] to your build tool: + +```bash +npm install gulp-postcss --save-dev +``` + +Enable [CSS Nesting] within your Gulpfile: + +```js +var postcss = require('gulp-postcss'); + +gulp.task('css', function () { + return gulp.src('./css/src/*.css').pipe( + postcss([ + require('postcss-nesting')({ /* options */ }) + ]) + ).pipe( + gulp.dest('./css') + ); +}); +``` + +#### Grunt + +Add [Grunt PostCSS] to your build tool: + +```bash +npm install grunt-postcss --save-dev ``` -Enable [PostCSS Nesting] within your Gruntfile: +Enable [CSS Nesting] within your Gruntfile: ```js grunt.loadNpmTasks('grunt-postcss'); @@ -93,7 +138,7 @@ grunt.initConfig({ [ci]: https://travis-ci.org/jonathantneal/postcss-nesting [ci-img]: https://travis-ci.org/jonathantneal/postcss-nesting.svg -[CSS Nesting Module Level 3]: http://tabatkins.github.io/specs/css-nesting/ +[Gulp PostCSS]: https://github.com/postcss/gulp-postcss [Grunt PostCSS]: https://github.com/nDmitry/grunt-postcss +[CSS Nesting]: https://github.com/jonathantneal/postcss-nesting [PostCSS]: https://github.com/postcss/postcss -[PostCSS Nesting]: https://github.com/jonathantneal/postcss-nesting From ccf223b424b296f9e4937906ca8a3c40dd467f35 Mon Sep 17 00:00:00 2001 From: Jonathan Neal Date: Tue, 15 Sep 2015 19:12:40 -0400 Subject: [PATCH 328/795] Update plugin Support prefix option Add document and supports to bubbles Update documentation --- README.md | 17 +++++++++++++++++ index.js | 7 +++++-- 2 files changed, 22 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index ac870ab490..85f43869ef 100644 --- a/README.md +++ b/README.md @@ -136,6 +136,23 @@ grunt.initConfig({ }); ``` + +## Options + +#### `bubble` + +Type: `Array` +Default: `['document', 'media', 'supports']` + +Specifies additional at-rules whose contents should be transpiled so that the at-rule comes first. By default, `@media`, `@supports` and `@document` will do this. + +#### `prefix` + +Type: `String` +Default: `null` + +Specifies a prefix to be surrounded by dashes before the `@nest` at-rule (e.g. `@-x-nest`). + [ci]: https://travis-ci.org/jonathantneal/postcss-nesting [ci-img]: https://travis-ci.org/jonathantneal/postcss-nesting.svg [Gulp PostCSS]: https://github.com/postcss/gulp-postcss diff --git a/index.js b/index.js index 490226af39..e6ba6fd27b 100644 --- a/index.js +++ b/index.js @@ -1,5 +1,6 @@ -var bubble = ['media']; +var bubble = ['document', 'media', 'supports']; var postcss = require('postcss'); +var prefix = ''; function transpileSelectors(fromRule, toRule) { var selectors = []; @@ -56,6 +57,7 @@ function transpileAtRule(fromRule, toRule, atRule) { function transpileRule(rule) { var nodes = rule.nodes; var index = -1; + var name = prefix ? '-' + prefix + '-nest' : 'nest'; var child; // for each node @@ -65,7 +67,7 @@ function transpileRule(rule) { var newRule = postcss.rule(); // if atrule is nest - if (child.name === 'nest') { + if (child.name === name) { transpileNestRule(rule, newRule, child); transpileRule(newRule); @@ -82,6 +84,7 @@ function transpileRule(rule) { module.exports = postcss.plugin('postcss-nested', function (opts) { if (opts && opts.bubble) bubble = bubble.concat(opts.bubble); + if (opts && opts.prefix) prefix = opts.prefix; return function (css) { var nodes = css.nodes; From ef27dceb2e76399767608d1cc8e9cb2c6f68153c Mon Sep 17 00:00:00 2001 From: Jonathan Neal Date: Tue, 15 Sep 2015 19:51:59 -0400 Subject: [PATCH 329/795] Require & in selector --- index.js | 2 +- test/test.js | 9 +++++++-- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/index.js b/index.js index e6ba6fd27b..e0182aaaf6 100644 --- a/index.js +++ b/index.js @@ -67,7 +67,7 @@ function transpileRule(rule) { var newRule = postcss.rule(); // if atrule is nest - if (child.name === name) { + if (child.name === name && child.params.indexOf('&') !== -1) { transpileNestRule(rule, newRule, child); transpileRule(newRule); diff --git a/test/test.js b/test/test.js index 020d60bd8f..8d51ce837d 100644 --- a/test/test.js +++ b/test/test.js @@ -18,18 +18,23 @@ describe('postcss-nested', function () { 'z { color: red } a, b { color: white } a c, a d, b c, b d { color: blue }'); }); + it('requires &', function () { + check('z { color: red } a, b { color: white; @nest c, d { color: blue } }', + 'z { color: red } a, b { color: white; @nest c, d { color: blue } }'); + }); + it('unwraps css deep nesting', function () { check('z { color: red } a, b { color: white; @nest & c, & d { color: blue; @nest & e, & f { color: black } } }', 'z { color: red } a, b { color: white } a c, a d, b c, b d { color: blue } a c e, a c f, a d e, a d f, b c e, b c f, b d e, b d f { color: black }'); }); it('unwraps mixed nesting', function () { - check('a { color: red; @media { color: white; @nest b { color: blue } } }', + check('a { color: red; @media { color: white; @nest & b { color: blue } } }', 'a { color: red } @media { a { color: white } a b { color: blue } }'); }); it('unwraps specified at-rules', function () { - check('a { color: red; @unknown test { color: white } } b { color: white; @phone { color: blue } @media { color: black; @nest c { color: yellow } } }', + check('a { color: red; @unknown test { color: white } } b { color: white; @phone { color: blue } @media { color: black; @nest & c { color: yellow } } }', 'a { color: red; @unknown test { color: white } } b { color: white } @phone { b { color: blue } } @media { b { color: black } b c { color: yellow } }', { bubble: ['phone'] }); }); From 4cd52b65701557878a5d7f294182b2f276b5b5c0 Mon Sep 17 00:00:00 2001 From: Jonathan Neal Date: Tue, 15 Sep 2015 19:58:27 -0400 Subject: [PATCH 330/795] 2.0.0 --- CHANGELOG.md | 7 +++++++ package.json | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ecaba1d829..a4e0651f80 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,10 @@ +## 2.0.0 (2015-09-16) + +- Added: Requirement of `&` per the specification +- Added: New prefix option +- Added: `@document` and `@supports` as bubbles +- Updated: Documentation + ## 1.0.0 (2015-09-15) - Added: New `@nest` at-rule syntax diff --git a/package.json b/package.json index 564315628b..ecdf5b511d 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "postcss-nesting", - "version": "1.0.0", + "version": "2.0.0", "description": "Transpiles nested rules according to CSS Nesting Module Level 3", "keywords": [ "postcss", From 1504f28d5a853051e1752aa2ded7c73df71857e9 Mon Sep 17 00:00:00 2001 From: Jonathan Neal Date: Wed, 16 Sep 2015 02:08:19 -0400 Subject: [PATCH 331/795] Update plugin Fix bug where `@next` rule followed by `@media` rule did not bubble --- index.js | 2 ++ test/test.js | 4 ++-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/index.js b/index.js index e0182aaaf6..ca130aaaa3 100644 --- a/index.js +++ b/index.js @@ -71,6 +71,8 @@ function transpileRule(rule) { transpileNestRule(rule, newRule, child); transpileRule(newRule); + + --index; } else if (bubble.indexOf(child.name) !== -1) { transpileAtRule(rule, newRule, child); diff --git a/test/test.js b/test/test.js index 8d51ce837d..75e55b8d1c 100644 --- a/test/test.js +++ b/test/test.js @@ -29,8 +29,8 @@ describe('postcss-nested', function () { }); it('unwraps mixed nesting', function () { - check('a { color: red; @media { color: white; @nest & b { color: blue } } }', - 'a { color: red } @media { a { color: white } a b { color: blue } }'); + check('a { color: red; @nest & b { color: white; @media { color: blue; } } @media { color: black; @nest & c { color: yellow } } }', + 'a { color: red } a b { color: white } @media { a b { color: blue } } @media { a { color: black } a c { color: yellow } }'); }); it('unwraps specified at-rules', function () { From f97cb2b985aef07994342d3a05d1bc884ed55607 Mon Sep 17 00:00:00 2001 From: Jonathan Neal Date: Wed, 16 Sep 2015 02:11:05 -0400 Subject: [PATCH 332/795] Update CONTRIBUTING.md --- CONTRIBUTING.md | 60 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 60 insertions(+) create mode 100644 CONTRIBUTING.md diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 0000000000..a33aec25a1 --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,60 @@ +You want to help? You rock! Now, take a moment to be sure your contributions make sense to everyone else. + +## Reporting Issues + +Found a problem? Want a new feature? + +- See if your issue or idea has [already been reported]. +- Provide a [reduced test case] or a [live example]. + +Remember, a bug is a _demonstrable problem_ caused by _our_ code. + +## Submitting Pull Requests + +Pull requests are the greatest contributions, so be sure they are focused in scope, and do avoid unrelated commits. + +1. To begin, [fork this project], clone your fork, and add our upstream. + ```bash + # Clone your fork of the repo into the current directory + git clone https://github.com//postcss-nesting + # Navigate to the newly cloned directory + cd postcss-nesting + # Assign the original repo to a remote called "upstream" + git remote add upstream https://github.com/jonathantneal/postcss-nesting + # Install the tools necessary for development + npm install + ``` + +2. Create a branch for your feature or fix: + ```bash + # Move into a new branch for a feature + git checkout -b feature/thing + ``` + ```bash + # Move into a new branch for a fix + git checkout -b fix/something + ``` + +3. Be sure your code follows our practices. + ```bash + # Test current code + npm run test + ``` + +4. Push your branch up to your fork: + ```bash + # Push a feature branch + git push origin feature/thing + ``` + ```bash + # Push a fix branch + git push origin fix/something + ``` + +5. Now [open a pull request] with a clear title and description. + +[already been reported]: issues +[fork this project]: fork +[live example]: http://codepen.io/pen +[open a pull request]: https://help.github.com/articles/using-pull-requests/ +[reduced test case]: https://css-tricks.com/reduced-test-cases/ From 7e8e81a9f8f543a0ff49aba1e70d40009e17ddc3 Mon Sep 17 00:00:00 2001 From: Jonathan Neal Date: Wed, 16 Sep 2015 02:13:16 -0400 Subject: [PATCH 333/795] 2.0.1 --- CHANGELOG.md | 5 +++++ package.json | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a4e0651f80..f470b488a6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,8 @@ +## 2.0.1 (2015-09-16) + +- Fixed: Issue where a `@nest` rule followed by another bubbling at-rule would not bubble +- Added: CONTRIBUTING.md + ## 2.0.0 (2015-09-16) - Added: Requirement of `&` per the specification diff --git a/package.json b/package.json index ecdf5b511d..549009cf21 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "postcss-nesting", - "version": "2.0.0", + "version": "2.0.1", "description": "Transpiles nested rules according to CSS Nesting Module Level 3", "keywords": [ "postcss", From 1998709bbb6bca8aa40f11629d877d0c5e415755 Mon Sep 17 00:00:00 2001 From: Jonathan Neal Date: Wed, 16 Sep 2015 03:20:40 -0400 Subject: [PATCH 334/795] Update plugin MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Normalize toRule’s appended children for mapping --- index.js | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/index.js b/index.js index ca130aaaa3..7520e38370 100644 --- a/index.js +++ b/index.js @@ -2,6 +2,15 @@ var bubble = ['document', 'media', 'supports']; var postcss = require('postcss'); var prefix = ''; +function normalizeNodes(node) { + var index = -1; + var child; + + while (child = node.nodes[++index]) { + child.parent = node; + } +} + function transpileSelectors(fromRule, toRule) { var selectors = []; @@ -32,6 +41,8 @@ function transpileNestRule(fromRule, toRule, atRule) { toRule.selector = atRule.params; toRule.selectors = transpileSelectors(fromRule, toRule); + normalizeNodes(toRule); + parent.nodes.splice(++parent.nestedIndex, 0, toRule); } @@ -48,6 +59,8 @@ function transpileAtRule(fromRule, toRule, atRule) { toRule.parent = atRule; toRule.selector = fromRule.selector; + normalizeNodes(toRule); + atRule.nodes = [toRule]; atRule.parent = parent; From e1ae8c0f1c9bbe48634da0d2953dd60570ac2356 Mon Sep 17 00:00:00 2001 From: Jonathan Neal Date: Wed, 16 Sep 2015 03:22:28 -0400 Subject: [PATCH 335/795] 2.0.2 --- CHANGELOG.md | 4 ++++ package.json | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f470b488a6..ae2b3c3564 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,7 @@ +## 2.0.2 (2015-09-16) + +- Fixed: Issue where the new rule’s children were not mapped to the parent internally + ## 2.0.1 (2015-09-16) - Fixed: Issue where a `@nest` rule followed by another bubbling at-rule would not bubble diff --git a/package.json b/package.json index 549009cf21..31276623f7 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "postcss-nesting", - "version": "2.0.1", + "version": "2.0.2", "description": "Transpiles nested rules according to CSS Nesting Module Level 3", "keywords": [ "postcss", From e30c992c4f4d2b2dac1386fc6d75581bd4d25217 Mon Sep 17 00:00:00 2001 From: Jonathan Neal Date: Thu, 17 Sep 2015 08:13:57 -0400 Subject: [PATCH 336/795] Update CONTRIBUTING.md --- CONTRIBUTING.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index a33aec25a1..d4c8b8e086 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -7,7 +7,7 @@ Found a problem? Want a new feature? - See if your issue or idea has [already been reported]. - Provide a [reduced test case] or a [live example]. -Remember, a bug is a _demonstrable problem_ caused by _our_ code. +Remember, a bug is a _demonstrable problem_ caused by _our_ code. Please use this [demo] as a testing platform. You can share code entered here at any time by pressing the Meta and S keys (`⌘S`) to save the current code as a URL. ## Submitting Pull Requests @@ -54,7 +54,8 @@ Pull requests are the greatest contributions, so be sure they are focused in sco 5. Now [open a pull request] with a clear title and description. [already been reported]: issues +[demo]: http://jonathantneal.github.io/postcss-nesting/ [fork this project]: fork [live example]: http://codepen.io/pen [open a pull request]: https://help.github.com/articles/using-pull-requests/ -[reduced test case]: https://css-tricks.com/reduced-test-cases/ +[reduced test case]: https://css-tricks.com/reduced-test-cases/ \ No newline at end of file From 648dc418e0fb5b46386b3412d5008f099e0bc5c2 Mon Sep 17 00:00:00 2001 From: Jonathan Neal Date: Thu, 17 Sep 2015 08:15:05 -0400 Subject: [PATCH 337/795] Update README.md --- README.md | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index 85f43869ef..f1630095b5 100644 --- a/README.md +++ b/README.md @@ -2,9 +2,7 @@ -[CSS Nesting] is a [PostCSS] plugin that allows you to nest one style rule inside another, similar to Sass, but following the [CSS Nesting Module Level 3] specification. - -This greatly increases the modularity and maintainability of CSS stylesheets. +[CSS Nesting] is a [PostCSS] plugin that allows you to nest one style rule inside another, following the [CSS Nesting Module Level 3] specification. ```css /* before */ @@ -65,6 +63,8 @@ npm install postcss-nesting --save-dev #### Node +Use [CSS Nesting] directly: + ```js require('postcss-nesting')({ /* options */ }).process(YOUR_CSS); ``` @@ -77,7 +77,7 @@ Add [PostCSS] to your build tool: npm install postcss --save-dev ``` -Load [CSS Nesting] as a PostCSS plugin: +Use [CSS Nesting] as a PostCSS plugin: ```js postcss([ @@ -93,7 +93,7 @@ Add [Gulp PostCSS] to your build tool: npm install gulp-postcss --save-dev ``` -Enable [CSS Nesting] within your Gulpfile: +Use [CSS Nesting] within your Gulpfile: ```js var postcss = require('gulp-postcss'); @@ -117,7 +117,7 @@ Add [Grunt PostCSS] to your build tool: npm install grunt-postcss --save-dev ``` -Enable [CSS Nesting] within your Gruntfile: +Use [CSS Nesting] within your Gruntfile: ```js grunt.loadNpmTasks('grunt-postcss'); @@ -155,7 +155,8 @@ Specifies a prefix to be surrounded by dashes before the `@nest` at-rule (e.g. ` [ci]: https://travis-ci.org/jonathantneal/postcss-nesting [ci-img]: https://travis-ci.org/jonathantneal/postcss-nesting.svg +[CSS Nesting]: https://github.com/jonathantneal/postcss-nesting +[CSS Nesting Module Level 3]: http://tabatkins.github.io/specs/css-nesting/ [Gulp PostCSS]: https://github.com/postcss/gulp-postcss [Grunt PostCSS]: https://github.com/nDmitry/grunt-postcss -[CSS Nesting]: https://github.com/jonathantneal/postcss-nesting [PostCSS]: https://github.com/postcss/postcss From e5333a29c3037120d945888f5cc06547f88a49ac Mon Sep 17 00:00:00 2001 From: Jonathan Neal Date: Tue, 22 Sep 2015 08:59:11 -0400 Subject: [PATCH 338/795] Update plugin Updated: Refactored plugin --- CHANGELOG.md | 4 ++ index.js | 117 ++++++++++++++------------------------------------- 2 files changed, 36 insertions(+), 85 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ae2b3c3564..8960fd65e6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,7 @@ +## 2.0.3 (2015-09-22) + +- Updated: Refactored plugin + ## 2.0.2 (2015-09-16) - Fixed: Issue where the new rule’s children were not mapped to the parent internally diff --git a/index.js b/index.js index 7520e38370..5c5c02f622 100644 --- a/index.js +++ b/index.js @@ -1,115 +1,62 @@ -var bubble = ['document', 'media', 'supports']; var postcss = require('postcss'); -var prefix = ''; - -function normalizeNodes(node) { - var index = -1; - var child; - - while (child = node.nodes[++index]) { - child.parent = node; - } -} function transpileSelectors(fromRule, toRule) { var selectors = []; fromRule.selectors.forEach(function (fromSelector) { toRule.selectors.forEach(function (toSelector) { - if (toSelector.indexOf('&') === -1) { - selectors.push(fromSelector + ' ' + toSelector); - } else { - selectors.push(toSelector.replace(/&/g, fromSelector)); - } + selectors.push(toSelector.replace(/&/g, fromSelector)); }); }); - return selectors; -} - -function transpileNestRule(fromRule, toRule, atRule) { - var parent = fromRule.parent; - - if (!('nestedIndex' in parent)) { - parent.nestedIndex = parent.nodes.indexOf(fromRule); - } - - fromRule.nodes.splice(fromRule.nodes.indexOf(atRule), 1); - - toRule.nodes = atRule.nodes.splice(0); - toRule.parent = parent; - toRule.selector = atRule.params; - toRule.selectors = transpileSelectors(fromRule, toRule); - - normalizeNodes(toRule); - - parent.nodes.splice(++parent.nestedIndex, 0, toRule); + toRule.selectors = selectors; } -function transpileAtRule(fromRule, toRule, atRule) { - var parent = fromRule.parent; +module.exports = postcss.plugin('postcss-nested', function (opts) { + var bubble = ['document', 'media', 'supports']; + var name = 'nest'; - if (!('nestedIndex' in parent)) { - parent.nestedIndex = parent.nodes.indexOf(fromRule); - } + if (opts && opts.bubble) bubble = bubble.concat(opts.bubble); + if (opts && opts.prefix) name = '-' + opts.prefix + '-' + name; - fromRule.nodes.splice(fromRule.nodes.indexOf(atRule), 1); + return function (css) { + css.walkAtRules(function (atrule) { + var rule = atrule.parent; + var root = rule && rule.parent; - toRule.nodes = atRule.nodes.splice(0); - toRule.parent = atRule; - toRule.selector = fromRule.selector; + if (root && rule.type === 'rule') { + var newrule = postcss.rule({ + raws: atrule.raws + }); - normalizeNodes(toRule); + if (atrule.name === name && atrule.params.indexOf('&') !== -1) { + atrule.remove(); - atRule.nodes = [toRule]; - atRule.parent = parent; + newrule.selector = atrule.params; - parent.nodes.splice(++parent.nestedIndex, 0, atRule); -} + newrule.append(atrule.nodes); -function transpileRule(rule) { - var nodes = rule.nodes; - var index = -1; - var name = prefix ? '-' + prefix + '-nest' : 'nest'; - var child; + transpileSelectors(rule, newrule); - // for each node - while (child = nodes[++index]) { - // if node is atrule - if (child.type === 'atrule') { - var newRule = postcss.rule(); + root.insertAfter(rule.insertAfterNode || rule, newrule); - // if atrule is nest - if (child.name === name && child.params.indexOf('&') !== -1) { - transpileNestRule(rule, newRule, child); + rule.insertAfterNode = newrule; + } else if (bubble.indexOf(atrule.name) !== -1) { + atrule.remove(); - transpileRule(newRule); + newrule.selector = rule.selector; - --index; - } else if (bubble.indexOf(child.name) !== -1) { - transpileAtRule(rule, newRule, child); + newrule.append(atrule.nodes); - transpileRule(newRule); + atrule.removeAll(); - --index; - } - } - } -} + atrule.append(newrule); -module.exports = postcss.plugin('postcss-nested', function (opts) { - if (opts && opts.bubble) bubble = bubble.concat(opts.bubble); - if (opts && opts.prefix) prefix = opts.prefix; + root.insertAfter(rule.insertAfterNode || rule, atrule); - return function (css) { - var nodes = css.nodes; - var index = -1; - var child; - - while (child = nodes[++index]) { - if (child.type === 'rule') { - transpileRule(child); + rule.insertAfterNode = atrule; + } } - } + }); }; }); From 6a208c2a0639b13fe87c46e014eb7c35ed81d66d Mon Sep 17 00:00:00 2001 From: Jonathan Neal Date: Tue, 22 Sep 2015 08:59:25 -0400 Subject: [PATCH 339/795] Update tests Updated: tests --- CHANGELOG.md | 1 + test/test.js | 5 +++++ 2 files changed, 6 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8960fd65e6..90a31c36e2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,7 @@ ## 2.0.3 (2015-09-22) - Updated: Refactored plugin +- Updated: Tests ## 2.0.2 (2015-09-16) diff --git a/test/test.js b/test/test.js index 75e55b8d1c..202382a7ca 100644 --- a/test/test.js +++ b/test/test.js @@ -28,6 +28,11 @@ describe('postcss-nested', function () { 'z { color: red } a, b { color: white } a c, a d, b c, b d { color: blue } a c e, a c f, a d e, a d f, b c e, b c f, b d e, b d f { color: black }'); }); + it('unwraps bubble nesting', function () { + check('a { color: red; @media { color: white } }', + 'a { color: red } @media { a { color: white } }'); + }); + it('unwraps mixed nesting', function () { check('a { color: red; @nest & b { color: white; @media { color: blue; } } @media { color: black; @nest & c { color: yellow } } }', 'a { color: red } a b { color: white } @media { a b { color: blue } } @media { a { color: black } a c { color: yellow } }'); From 4444fd983705fd9d71322667251d305d43a6bcfc Mon Sep 17 00:00:00 2001 From: Jonathan Neal Date: Tue, 22 Sep 2015 09:06:42 -0400 Subject: [PATCH 340/795] Update packages Updated: PostCSS 5.0.6 --- CHANGELOG.md | 1 + package.json | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 90a31c36e2..3be3e24e9d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,7 @@ - Updated: Refactored plugin - Updated: Tests +- Updated: PostCSS 5.0.6 ## 2.0.2 (2015-09-16) diff --git a/package.json b/package.json index 31276623f7..d922f67fcd 100644 --- a/package.json +++ b/package.json @@ -21,10 +21,10 @@ }, "homepage": "https://github.com/jonathantneal/postcss-nesting", "dependencies": { - "postcss": "^5.0.5" + "postcss": "^5.0.6" }, "devDependencies": { - "chai": "^3.2.0", + "chai": "^3.3.0", "gulp": "^3.9.0", "gulp-eslint": "^1.0.0", "gulp-mocha": "^2.1.3" From 837cddccd3a410762241b61e40f6a1138e40c0bf Mon Sep 17 00:00:00 2001 From: Jonathan Neal Date: Tue, 22 Sep 2015 09:06:58 -0400 Subject: [PATCH 341/795] 2.0.3 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index d922f67fcd..020f9e16c6 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "postcss-nesting", - "version": "2.0.2", + "version": "2.0.3", "description": "Transpiles nested rules according to CSS Nesting Module Level 3", "keywords": [ "postcss", From 922094cd1264aa503f9d64271c1e09be655a9731 Mon Sep 17 00:00:00 2001 From: Jonathan Neal Date: Tue, 22 Sep 2015 09:37:09 -0400 Subject: [PATCH 342/795] Update plugin Updated: Map source raws --- CHANGELOG.md | 4 ++++ index.js | 15 ++++++++++++++- 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3be3e24e9d..cc145f950e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,7 @@ +## 2.0.4 (2015-09-23) + +- Updated: Map source raws + ## 2.0.3 (2015-09-22) - Updated: Refactored plugin diff --git a/index.js b/index.js index 5c5c02f622..61031bd99a 100644 --- a/index.js +++ b/index.js @@ -12,6 +12,11 @@ function transpileSelectors(fromRule, toRule) { toRule.selectors = selectors; } +function cleanNode(node) { + if (!('before' in node.raws)) node.raws.before = node.parent.raws.before || ''; + if (!('after' in node.raws)) node.raws.after = node.parent.raws.after || ''; +} + module.exports = postcss.plugin('postcss-nested', function (opts) { var bubble = ['document', 'media', 'supports']; var name = 'nest'; @@ -26,7 +31,11 @@ module.exports = postcss.plugin('postcss-nested', function (opts) { if (root && rule.type === 'rule') { var newrule = postcss.rule({ - raws: atrule.raws + raws: { + before: atrule.raws.before, + between: atrule.raws.between, + after: atrule.raws.after + } }); if (atrule.name === name && atrule.params.indexOf('&') !== -1) { @@ -36,6 +45,8 @@ module.exports = postcss.plugin('postcss-nested', function (opts) { newrule.append(atrule.nodes); + newrule.nodes.forEach(cleanNode); + transpileSelectors(rule, newrule); root.insertAfter(rule.insertAfterNode || rule, newrule); @@ -48,6 +59,8 @@ module.exports = postcss.plugin('postcss-nested', function (opts) { newrule.append(atrule.nodes); + newrule.nodes.forEach(cleanNode); + atrule.removeAll(); atrule.append(newrule); From 3d2c0b64d816226d7fa60aa4dcd53f04adf355db Mon Sep 17 00:00:00 2001 From: Jonathan Neal Date: Tue, 22 Sep 2015 09:37:25 -0400 Subject: [PATCH 343/795] 2.0.4 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 020f9e16c6..bb23216e68 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "postcss-nesting", - "version": "2.0.3", + "version": "2.0.4", "description": "Transpiles nested rules according to CSS Nesting Module Level 3", "keywords": [ "postcss", From 63e3cb360c3f9aa9d8b431c012c9a8bd76561cef Mon Sep 17 00:00:00 2001 From: Tommi Finnilae Date: Mon, 12 Oct 2015 12:54:37 +0300 Subject: [PATCH 344/795] Update README.md Add missing parenthesis --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index f1630095b5..29b6cd55cc 100644 --- a/README.md +++ b/README.md @@ -12,6 +12,7 @@ a, b { @nest c, d { color: white; + } @nest & & { color: blue; From bc1e73c7c82f09f754b61436a606ce5c92478c89 Mon Sep 17 00:00:00 2001 From: Tommi Finnilae Date: Mon, 12 Oct 2015 13:02:50 +0300 Subject: [PATCH 345/795] Update README.md fix example code --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 29b6cd55cc..e7a5ef09ac 100644 --- a/README.md +++ b/README.md @@ -10,7 +10,7 @@ a, b { color: red; - @nest c, d { + @nest & c, & d { color: white; } From ff04ca4e069851b0bb4bbcfca23bb1d2d7f77920 Mon Sep 17 00:00:00 2001 From: Jonathan Neal Date: Mon, 12 Oct 2015 09:34:41 -0400 Subject: [PATCH 346/795] 2.0.5 - Updated: Nested rules source map to the parent rule - Updated: PostCSS 5.0.9 - Updated: Tests and documentation - Updated: Project configuration --- .editorconfig | 14 +++++ .eslintrc | 4 +- .gitignore | 1 + .npmignore | 8 +-- .travis.yml | 2 +- CHANGELOG.md | 7 +++ README.md | 2 +- gulpfile.js | 23 --------- index.js | 19 ++----- package.json | 15 +++--- test/fixtures/basic.css | 79 ++++++++++++++++++++++++++++ test/fixtures/basic.expect.css | 91 +++++++++++++++++++++++++++++++++ test/fixtures/ignore.css | 15 ++++++ test/fixtures/ignore.expect.css | 15 ++++++ test/index.js | 55 ++++++++++++++++++++ test/test.js | 46 ----------------- 16 files changed, 293 insertions(+), 103 deletions(-) create mode 100644 .editorconfig delete mode 100644 gulpfile.js create mode 100644 test/fixtures/basic.css create mode 100644 test/fixtures/basic.expect.css create mode 100644 test/fixtures/ignore.css create mode 100644 test/fixtures/ignore.expect.css create mode 100644 test/index.js delete mode 100644 test/test.js diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000000..7843e7d086 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,14 @@ +root = true + +[*] +indent_style = tab +end_of_line = lf +charset = utf-8 +trim_trailing_whitespace = true +insert_final_newline = true + +[*.md] +trim_trailing_whitespace = false + +[*.{json,yml}] +indent_size = 2 diff --git a/.eslintrc b/.eslintrc index c6fb69a980..d85f6967e9 100644 --- a/.eslintrc +++ b/.eslintrc @@ -84,14 +84,14 @@ "comma-style": [2], "brace-style": [2], "no-debugger": [2], - "quote-props": [2, "as-needed"], + "quote-props": [0], "no-iterator": [2], "no-new-func": [2], "key-spacing": [2, { "align": "value" }], "complexity": [2], "new-parens": [2], "no-eq-null": [2], - "no-bitwise": [2], + "no-bitwise": [0], "wrap-iife": [2], "no-caller": [2], "use-isnan": [2], diff --git a/.gitignore b/.gitignore index 1ca957177f..4dd3d0638a 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ node_modules/ npm-debug.log +test/fixtures/*.actual.css diff --git a/.npmignore b/.npmignore index 1aa2d59e25..1ca957177f 100644 --- a/.npmignore +++ b/.npmignore @@ -1,8 +1,2 @@ -.gitignore - node_modules/ - -test/ -.travis.yml - -gulpfile.js +npm-debug.log diff --git a/.travis.yml b/.travis.yml index e1bd776499..c8d066397a 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,5 +1,5 @@ sudo: false language: node_js node_js: - - iojs + - stable - "0.12" diff --git a/CHANGELOG.md b/CHANGELOG.md index cc145f950e..ca3c51ac63 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,10 @@ +## 2.0.5 (2015-10-12) + +- Updated: Nested rules source map to the parent rule +- Updated: PostCSS 5.0.9 +- Updated: Tests and documentation +- Updated: Project configuration + ## 2.0.4 (2015-09-23) - Updated: Map source raws diff --git a/README.md b/README.md index e7a5ef09ac..c3be78ed81 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ -[CSS Nesting] is a [PostCSS] plugin that allows you to nest one style rule inside another, following the [CSS Nesting Module Level 3] specification. +[CSS Nesting] allows you to nest one style rule inside another, following the [CSS Nesting Module Level 3] specification. ```css /* before */ diff --git a/gulpfile.js b/gulpfile.js deleted file mode 100644 index 33bd8cf5ca..0000000000 --- a/gulpfile.js +++ /dev/null @@ -1,23 +0,0 @@ -var gulp = require('gulp'); - -var files = ['index.js', 'test/*.js', 'gulpfile.js']; - -gulp.task('lint', function () { - var eslint = require('gulp-eslint'); - return gulp.src(files) - .pipe(eslint()) - .pipe(eslint.format()) - .pipe(eslint.failAfterError()); -}); - -gulp.task('test', function () { - var mocha = require('gulp-mocha'); - return gulp.src('test/*.js', { read: false }) - .pipe(mocha()); -}); - -gulp.task('default', ['lint', 'test']); - -gulp.task('watch', function () { - gulp.watch(files, ['lint', 'test']); -}); diff --git a/index.js b/index.js index 61031bd99a..7a71de0357 100644 --- a/index.js +++ b/index.js @@ -12,11 +12,6 @@ function transpileSelectors(fromRule, toRule) { toRule.selectors = selectors; } -function cleanNode(node) { - if (!('before' in node.raws)) node.raws.before = node.parent.raws.before || ''; - if (!('after' in node.raws)) node.raws.after = node.parent.raws.after || ''; -} - module.exports = postcss.plugin('postcss-nested', function (opts) { var bubble = ['document', 'media', 'supports']; var name = 'nest'; @@ -30,13 +25,9 @@ module.exports = postcss.plugin('postcss-nested', function (opts) { var root = rule && rule.parent; if (root && rule.type === 'rule') { - var newrule = postcss.rule({ - raws: { - before: atrule.raws.before, - between: atrule.raws.between, - after: atrule.raws.after - } - }); + var newrule = rule.clone().removeAll(); + + newrule.source = atrule.source; if (atrule.name === name && atrule.params.indexOf('&') !== -1) { atrule.remove(); @@ -45,8 +36,6 @@ module.exports = postcss.plugin('postcss-nested', function (opts) { newrule.append(atrule.nodes); - newrule.nodes.forEach(cleanNode); - transpileSelectors(rule, newrule); root.insertAfter(rule.insertAfterNode || rule, newrule); @@ -59,8 +48,6 @@ module.exports = postcss.plugin('postcss-nested', function (opts) { newrule.append(atrule.nodes); - newrule.nodes.forEach(cleanNode); - atrule.removeAll(); atrule.append(newrule); diff --git a/package.json b/package.json index bb23216e68..a669b13ba8 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "postcss-nesting", - "version": "2.0.4", + "version": "2.0.5", "description": "Transpiles nested rules according to CSS Nesting Module Level 3", "keywords": [ "postcss", @@ -21,16 +21,17 @@ }, "homepage": "https://github.com/jonathantneal/postcss-nesting", "dependencies": { - "postcss": "^5.0.6" + "postcss": "^5.0.9" }, "devDependencies": { - "chai": "^3.3.0", - "gulp": "^3.9.0", - "gulp-eslint": "^1.0.0", - "gulp-mocha": "^2.1.3" + "eslint": "^1.6.0", + "tap-spec": "^4.1.0", + "tape": "^4.2.1" }, "scripts": { - "test": "gulp" + "lint": "eslint . --ignore-path .gitignore", + "test-fixtures": "tape test/*.js | tap-spec", + "test": "npm run lint && npm run test-fixtures" }, "engines": { "iojs": ">=2.0.0", diff --git a/test/fixtures/basic.css b/test/fixtures/basic.css new file mode 100644 index 0000000000..def35db245 --- /dev/null +++ b/test/fixtures/basic.css @@ -0,0 +1,79 @@ +a, b { + color: white; + + @nest & c, & d { + color: blue; + } +} + +a, b { + color: white; + + @nest & c, & d { + color: blue; + + @nest & e, & f { + color: black; + } + } +} + +a, b { + color: red; + + @nest & & { + color: white; + } +} + +a { + color: red; + + @media { + color: white; + } +} + +a { + color: red; + + @nest & b { + color: white; + + @media { + color: blue; + } + } + + @media { + color: black; + + @nest & c { + color: yellow; + } + } +} + +a { + color: red; + + @unknown test { + color: white; + } +} + +b { + color: white; + + @phone { + color: blue; + } + + @media { + color: black; + + @nest & c { + color: yellow; + } + } +} diff --git a/test/fixtures/basic.expect.css b/test/fixtures/basic.expect.css new file mode 100644 index 0000000000..655ef234c6 --- /dev/null +++ b/test/fixtures/basic.expect.css @@ -0,0 +1,91 @@ +a, b { + color: white +} + +a c, a d, b c, b d { + color: blue +} + +a, b { + color: white +} + +a c, a d, b c, b d { + color: blue +} + +a c e, a c f, a d e, a d f, b c e, b c f, b d e, b d f { + color: black +} + +a, b { + color: red +} + +a a, b b { + color: white +} + +a { + color: red +} + +@media { + + a { + color: white + } + } + +a { + color: red +} + +a b { + color: white +} + +@media { + + a b { + color: blue + } +} + +@media { + + a c { + color: yellow + } + + a { + color: black + } + } + +a { + color: red; + + @unknown test { + color: white; + } +} + +b { + color: white; + + @phone { + color: blue; + } +} + +@media { + + b { + color: black + } + + b c { + color: yellow + } + } diff --git a/test/fixtures/ignore.css b/test/fixtures/ignore.css new file mode 100644 index 0000000000..5d6091a757 --- /dev/null +++ b/test/fixtures/ignore.css @@ -0,0 +1,15 @@ +a, b { + color: white; + + & c, & d { + color: blue; + } +} + +a, b { + color: white; + + @nest c, d { + color: blue; + } +} diff --git a/test/fixtures/ignore.expect.css b/test/fixtures/ignore.expect.css new file mode 100644 index 0000000000..5d6091a757 --- /dev/null +++ b/test/fixtures/ignore.expect.css @@ -0,0 +1,15 @@ +a, b { + color: white; + + & c, & d { + color: blue; + } +} + +a, b { + color: white; + + @nest c, d { + color: blue; + } +} diff --git a/test/index.js b/test/index.js new file mode 100644 index 0000000000..73e9b06b74 --- /dev/null +++ b/test/index.js @@ -0,0 +1,55 @@ +var tests = { + 'postcss-nesting': { + 'basic': { + message: 'supports basic usage' + }, + 'ignore': { + message: 'ignores invalid syntax' + } + } +}; + +var debug = true; +var dir = './test/fixtures/'; + +var fs = require('fs'); +var path = require('path'); +var plugin = require('../'); +var test = require('tape'); + +Object.keys(tests).forEach(function (name) { + var parts = tests[name]; + + test(name, function (t) { + var fixtures = Object.keys(parts); + + t.plan(fixtures.length * 2); + + fixtures.forEach(function (fixture) { + var message = parts[fixture].message; + var options = parts[fixture].options; + var warning = parts[fixture].warning || 0; + var warningMsg = message + ' (# of warnings)'; + + var baseName = fixture.split(':')[0]; + var testName = fixture.split(':').join('.'); + + var inputPath = path.resolve(dir + baseName + '.css'); + var expectPath = path.resolve(dir + testName + '.expect.css'); + var actualPath = path.resolve(dir + testName + '.actual.css'); + + var inputCSS = fs.readFileSync(inputPath, 'utf8'); + var expectCSS = fs.readFileSync(expectPath, 'utf8'); + + plugin.process(inputCSS, options).then(function (result) { + var actualCSS = result.css; + + if (debug) fs.writeFileSync(actualPath, actualCSS); + + t.equal(actualCSS, expectCSS, message); + + t.equal(result.warnings().length, warning, warningMsg); + }); + }); + }); +}); diff --git a/test/test.js b/test/test.js deleted file mode 100644 index 202382a7ca..0000000000 --- a/test/test.js +++ /dev/null @@ -1,46 +0,0 @@ -var postcss = require('postcss'); -var nested = require('../'); -var expect = require('chai').expect; - -var check = function (input, output, opts) { - var processor = postcss([ nested(opts) ]); - expect( processor.process(input).css ).to.equal(output); -}; - -describe('postcss-nested', function () { - it('ignores sass nesting', function () { - check('z { color: red } a, b { color: white; & c, & d { color: blue } }', - 'z { color: red } a, b { color: white; & c, & d { color: blue } }'); - }); - - it('unwraps css nesting', function () { - check('z { color: red } a, b { color: white; @nest & c, & d { color: blue } }', - 'z { color: red } a, b { color: white } a c, a d, b c, b d { color: blue }'); - }); - - it('requires &', function () { - check('z { color: red } a, b { color: white; @nest c, d { color: blue } }', - 'z { color: red } a, b { color: white; @nest c, d { color: blue } }'); - }); - - it('unwraps css deep nesting', function () { - check('z { color: red } a, b { color: white; @nest & c, & d { color: blue; @nest & e, & f { color: black } } }', - 'z { color: red } a, b { color: white } a c, a d, b c, b d { color: blue } a c e, a c f, a d e, a d f, b c e, b c f, b d e, b d f { color: black }'); - }); - - it('unwraps bubble nesting', function () { - check('a { color: red; @media { color: white } }', - 'a { color: red } @media { a { color: white } }'); - }); - - it('unwraps mixed nesting', function () { - check('a { color: red; @nest & b { color: white; @media { color: blue; } } @media { color: black; @nest & c { color: yellow } } }', - 'a { color: red } a b { color: white } @media { a b { color: blue } } @media { a { color: black } a c { color: yellow } }'); - }); - - it('unwraps specified at-rules', function () { - check('a { color: red; @unknown test { color: white } } b { color: white; @phone { color: blue } @media { color: black; @nest & c { color: yellow } } }', - 'a { color: red; @unknown test { color: white } } b { color: white } @phone { b { color: blue } } @media { b { color: black } b c { color: yellow } }', - { bubble: ['phone'] }); - }); -}); From b5d4428cb2700cee50cac2621deae417f8ef5b5c Mon Sep 17 00:00:00 2001 From: Jonathan Neal Date: Mon, 12 Oct 2015 09:45:54 -0400 Subject: [PATCH 347/795] Update README.md --- README.md | 67 +++++++++++++++++++++++++++---------------------------- 1 file changed, 33 insertions(+), 34 deletions(-) diff --git a/README.md b/README.md index c3be78ed81..5c4f8c618f 100644 --- a/README.md +++ b/README.md @@ -8,23 +8,23 @@ /* before */ a, b { - color: red; + color: red; - @nest & c, & d { - color: white; - } + @nest & c, & d { + color: white; + } - @nest & & { - color: blue; - } + @nest & & { + color: blue; + } - @nest &:hover { - color: black; - } + @nest &:hover { + color: black; + } - @media (min-width: 30em) { - color: yellow; - } + @media (min-width: 30em) { + color: yellow; + } } /* after */ @@ -33,11 +33,11 @@ a, b { color: red; } -a c, b c, a d, b d { +a c, a d, b c, b d { color: white; } -a a, a b, b a, b b { +a a, b b { color: blue; } @@ -82,7 +82,7 @@ Use [CSS Nesting] as a PostCSS plugin: ```js postcss([ - require('postcss-nesting')({ /* options */ }) + require('postcss-nesting')({ /* options */ }) ]); ``` @@ -100,13 +100,13 @@ Use [CSS Nesting] within your Gulpfile: var postcss = require('gulp-postcss'); gulp.task('css', function () { - return gulp.src('./css/src/*.css').pipe( - postcss([ - require('postcss-nesting')({ /* options */ }) - ]) - ).pipe( - gulp.dest('./css') - ); + return gulp.src('./css/src/*.css').pipe( + postcss([ + require('postcss-nesting')({ /* options */ }) + ]) + ).pipe( + gulp.dest('./css') + ); }); ``` @@ -124,20 +124,19 @@ Use [CSS Nesting] within your Gruntfile: grunt.loadNpmTasks('grunt-postcss'); grunt.initConfig({ - postcss: { - options: { - processors: [ - require('postcss-nesting')({ /* options */ }) - ] - }, - dist: { - src: 'css/*.css' - } - } + postcss: { + options: { + processors: [ + require('postcss-nesting')({ /* options */ }) + ] + }, + dist: { + src: 'css/*.css' + } + } }); ``` - ## Options #### `bubble` From e6c056f17d36c259356b1cd1f69d44e928fb0fd2 Mon Sep 17 00:00:00 2001 From: Jonathan Neal Date: Thu, 15 Oct 2015 01:30:23 -0400 Subject: [PATCH 348/795] 2.0.6 --- CHANGELOG.md | 4 ++++ index.js | 10 +++++----- package.json | 2 +- test/fixtures/basic.expect.css | 8 ++++---- 4 files changed, 14 insertions(+), 10 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ca3c51ac63..c829217f41 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,7 @@ +## 2.0.6 (2015-10-15) + +- Fixed: Issue with new PostCSS rules + ## 2.0.5 (2015-10-12) - Updated: Nested rules source map to the parent rule diff --git a/index.js b/index.js index 7a71de0357..82ad356050 100644 --- a/index.js +++ b/index.js @@ -25,11 +25,11 @@ module.exports = postcss.plugin('postcss-nested', function (opts) { var root = rule && rule.parent; if (root && rule.type === 'rule') { - var newrule = rule.clone().removeAll(); + var newrule = postcss.rule({ + source: atrule.source + }); - newrule.source = atrule.source; - - if (atrule.name === name && atrule.params.indexOf('&') !== -1) { + if (atrule.name === name && ~atrule.params.indexOf('&')) { atrule.remove(); newrule.selector = atrule.params; @@ -41,7 +41,7 @@ module.exports = postcss.plugin('postcss-nested', function (opts) { root.insertAfter(rule.insertAfterNode || rule, newrule); rule.insertAfterNode = newrule; - } else if (bubble.indexOf(atrule.name) !== -1) { + } else if (~bubble.indexOf(atrule.name)) { atrule.remove(); newrule.selector = rule.selector; diff --git a/package.json b/package.json index a669b13ba8..929e9dc97d 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "postcss-nesting", - "version": "2.0.5", + "version": "2.0.6", "description": "Transpiles nested rules according to CSS Nesting Module Level 3", "keywords": [ "postcss", diff --git a/test/fixtures/basic.expect.css b/test/fixtures/basic.expect.css index 655ef234c6..b53627634f 100644 --- a/test/fixtures/basic.expect.css +++ b/test/fixtures/basic.expect.css @@ -54,13 +54,13 @@ a b { @media { - a c { - color: yellow - } - a { color: black } + + a c { + color: yellow + } } a { From bd2ca643a8113e7832894fcde4bd950d84c09da3 Mon Sep 17 00:00:00 2001 From: Jonathan Kingston Date: Mon, 26 Oct 2015 17:37:11 +0000 Subject: [PATCH 349/795] Fixed pseudo selectors with multiple matches in a selector --- CHANGELOG.md | 3 +++ package.json | 2 +- src/replaceRuleSelector.js | 2 +- test/index.js | 6 ++++++ 4 files changed, 11 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7eed078e6f..cf0e364cde 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,6 @@ +# 2.0.1 - 2015-10-26 +- Fixed: pseudo selectors with multiple matches in a selector + # 2.0.0 - 2015-08-25 - Removed: compatibility with postcss v4.x diff --git a/package.json b/package.json index e0d06779f0..ef7b502900 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "postcss-selector-matches", - "version": "2.0.0", + "version": "2.0.1", "description": "PostCSS plugin to transform :matches() W3C CSS pseudo class to more compatible CSS selectors", "keywords": [ "postcss", diff --git a/src/replaceRuleSelector.js b/src/replaceRuleSelector.js index 6d759bf627..b2fa7250d5 100644 --- a/src/replaceRuleSelector.js +++ b/src/replaceRuleSelector.js @@ -39,7 +39,7 @@ function explodeSelector(selector, options) { newParts = [] postSelectors.forEach(postS => { bodySelectors.forEach(s => { - newParts.push(pre + s + postS) + newParts.push(preWhitespace + pre + s + postS) }) }) } diff --git a/test/index.js b/test/index.js index da65fab245..d5bde5c4b0 100644 --- a/test/index.js +++ b/test/index.js @@ -56,6 +56,12 @@ tape("postcss-selector-matches", t => { "should transform mutltiples :matches() with stuff after" ) + t.equal( + transform(":matches(tag) :matches(tag2, tag3):hover {}"), + "tag tag2:hover, tag tag3:hover {}", + "should transform mutltiples :matches() with pseudo after" + ) + t.equal( transform("tag :matches(tag2 :matches(tag4, tag5), tag3) {}"), "tag tag2 tag4, tag tag2 tag5, tag tag3 {}", From cf0f7dcb82797f3d3475efd431b48ff273abbec2 Mon Sep 17 00:00:00 2001 From: Jonathan Kingston Date: Mon, 26 Oct 2015 22:04:00 +0000 Subject: [PATCH 350/795] Adding in test for multiple selectors with a pseudo class --- test/index.js | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/test/index.js b/test/index.js index 9c7fac8e07..8dc2e093dc 100644 --- a/test/index.js +++ b/test/index.js @@ -150,6 +150,22 @@ article h6 + p {}`, "should works handle multiples combined selectors" ) + t.equal( + transform( + `@custom-selector :--foo .foo; + +:--foo :--foo:hover { + color: white; +} +` + ).css, + `.foo .foo:hover { + color: white; +} +`, + "should works handle multiples combined selectors with pseudo classes" + ) + t.equal( transform( `@custom-selector :--foo h1, h2, h3; From 9311892398aa2ff63adcb1437603e4d15520ac51 Mon Sep 17 00:00:00 2001 From: Tom Bremer Date: Mon, 9 Nov 2015 15:14:19 -0600 Subject: [PATCH 351/795] Support direct nesting, add walkRules method, update ignore tests, add direct nesting test. This resolves jonathantneal/postcss-nesting#10 --- index.js | 12 +++++ test/fixtures/direct.css | 79 ++++++++++++++++++++++++++++ test/fixtures/direct.expect.css | 91 +++++++++++++++++++++++++++++++++ test/fixtures/ignore.css | 6 ++- test/fixtures/ignore.expect.css | 6 ++- test/index.js | 3 ++ 6 files changed, 195 insertions(+), 2 deletions(-) create mode 100644 test/fixtures/direct.css create mode 100644 test/fixtures/direct.expect.css diff --git a/index.js b/index.js index 82ad356050..3b7d36ddb9 100644 --- a/index.js +++ b/index.js @@ -58,5 +58,17 @@ module.exports = postcss.plugin('postcss-nested', function (opts) { } } }); + + css.walkRules(function (rule) { + if (rule.parent.type === 'root' || rule.selector.indexOf('&') === -1) return; + + transpileSelectors(rule.parent, rule); + + rule.moveAfter(rule.parent); + + if (!rule.prev().nodes.length) { + rule.prev().remove(); + } + }); }; }); diff --git a/test/fixtures/direct.css b/test/fixtures/direct.css new file mode 100644 index 0000000000..f48fdc1db0 --- /dev/null +++ b/test/fixtures/direct.css @@ -0,0 +1,79 @@ +a, b { + color: white; + + & c, & d { + color: blue + } +} + +a, b { + color: white; + + & c, & d { + color: blue; + + & e, & f { + color: black + } + } +} + +a, b { + color: red; + + & & { + color: white + } +} + +a { + color: red; + + @media { + color: white + } +} + +a { + color: red; + + & b { + color: white; + + @media { + color: blue + } + } + + @media { + color: black; + + & c { + color: yellow + } + } +} + +a { + color: red; + + @unknown test { + color: white + } +} + +b { + color: white; + + @phone { + color: blue + } + + @media { + color: black; + + & c { + color: yellow + } + } +} diff --git a/test/fixtures/direct.expect.css b/test/fixtures/direct.expect.css new file mode 100644 index 0000000000..f83a98f67c --- /dev/null +++ b/test/fixtures/direct.expect.css @@ -0,0 +1,91 @@ +a, b { + color: white +} + +a c, a d, b c, b d { + color: blue +} + +a, b { + color: white +} + +a c, a d, b c, b d { + color: blue +} + +a c e, a c f, a d e, a d f, b c e, b c f, b d e, b d f { + color: black +} + +a, b { + color: red +} + +a a, b b { + color: white +} + +a { + color: red +} + +@media { + + a { + color: white + } + } + +a { + color: red +} + +a b { + color: white +} + +@media { + + a b { + color: blue + } + } + +@media { + + a { + color: black + } + + a c { + color: yellow + } + } + +a { + color: red; + + @unknown test { + color: white + } +} + +b { + color: white; + + @phone { + color: blue + } +} + +@media { + + b { + color: black + } + + b c { + color: yellow + } + } diff --git a/test/fixtures/ignore.css b/test/fixtures/ignore.css index 5d6091a757..ec65a94f19 100644 --- a/test/fixtures/ignore.css +++ b/test/fixtures/ignore.css @@ -1,7 +1,7 @@ a, b { color: white; - & c, & d { + c, d { color: blue; } } @@ -13,3 +13,7 @@ a, b { color: blue; } } + +& a { + color: white; +} diff --git a/test/fixtures/ignore.expect.css b/test/fixtures/ignore.expect.css index 5d6091a757..ec65a94f19 100644 --- a/test/fixtures/ignore.expect.css +++ b/test/fixtures/ignore.expect.css @@ -1,7 +1,7 @@ a, b { color: white; - & c, & d { + c, d { color: blue; } } @@ -13,3 +13,7 @@ a, b { color: blue; } } + +& a { + color: white; +} diff --git a/test/index.js b/test/index.js index 73e9b06b74..566f50d4b5 100644 --- a/test/index.js +++ b/test/index.js @@ -3,6 +3,9 @@ var tests = { 'basic': { message: 'supports basic usage' }, + 'direct': { + message: 'supports direct nesting' + }, 'ignore': { message: 'ignores invalid syntax' } From 179a8452b5f49630247f0f18f7f0deaeb47260f5 Mon Sep 17 00:00:00 2001 From: Tom Bremer Date: Mon, 9 Nov 2015 15:45:31 -0600 Subject: [PATCH 352/795] Update readme --- README.md | 25 ++++++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 5c4f8c618f..ed7480a7e4 100644 --- a/README.md +++ b/README.md @@ -4,8 +4,9 @@ [CSS Nesting] allows you to nest one style rule inside another, following the [CSS Nesting Module Level 3] specification. +### At Rule Nesting ```css -/* before */ +/* at rule nesting */ a, b { color: red; @@ -27,6 +28,28 @@ a, b { } } +/* direct nesting */ + +a, b { + color: red; + + & c, & d { + color: white; + } + + & & { + color: blue; + } + + &:hover { + color: black; + } + + @media (min-width: 30em) { + color: yellow; + } +} + /* after */ a, b { From 0d59080f03644b1f71f088d17372a7dd4ba5cc7d Mon Sep 17 00:00:00 2001 From: Aleks Hudochenkov Date: Wed, 25 Nov 2015 23:32:00 +0300 Subject: [PATCH 353/795] Simplify create_query function --- index.js | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/index.js b/index.js index 9db473e4ec..4e0a10c1b0 100644 --- a/index.js +++ b/index.js @@ -32,7 +32,15 @@ module.exports = postcss.plugin('postcss-media-minmax', function () { function create_query(name, gtlt, eq, value, params) { return value.replace(/([-\d\.]+)(.*)/, function (match, number, unit) { - number = parseFloat(number) || eq ? eq ? number : Number(Math.round(parseFloat(number) + step * power[gtlt] + 'e6')+'e-6') : power[gtlt] + feature_unit[name]; + + if (parseFloat(number) || eq) { + // if eq is true, then number remains same + if (!eq) { + number = Number(Math.round(parseFloat(number) + step * power[gtlt] + 'e6')+'e-6'); + } + } else { + number = power[gtlt] + feature_unit[name]; + } return '(' + minmax[gtlt] + '-' + name + ': ' + number + unit + ')'; }); From 557506db9e723f8d64d1cdc9b8d6f3fc3a305975 Mon Sep 17 00:00:00 2001 From: Aleks Hudochenkov Date: Thu, 26 Nov 2015 00:40:51 +0300 Subject: [PATCH 354/795] Change integer pixels value only on integer pixel --- index.js | 8 +++++++- test/fixtures/min-max.output.css | 8 ++++---- 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/index.js b/index.js index 4e0a10c1b0..f03f38c067 100644 --- a/index.js +++ b/index.js @@ -32,11 +32,17 @@ module.exports = postcss.plugin('postcss-media-minmax', function () { function create_query(name, gtlt, eq, value, params) { return value.replace(/([-\d\.]+)(.*)/, function (match, number, unit) { + var initialNumber = parseFloat(number); if (parseFloat(number) || eq) { // if eq is true, then number remains same if (!eq) { - number = Number(Math.round(parseFloat(number) + step * power[gtlt] + 'e6')+'e-6'); + // change integer pixels value only on integer pixel + if (unit === 'px' && initialNumber === parseInt(number, 10)) { + number = initialNumber + power[gtlt]; + } else { + number = Number(Math.round(parseFloat(number) + step * power[gtlt] + 'e6')+'e-6'); + } } } else { number = power[gtlt] + feature_unit[name]; diff --git a/test/fixtures/min-max.output.css b/test/fixtures/min-max.output.css index 5c962ae7ea..b19bdcd31b 100644 --- a/test/fixtures/min-max.output.css +++ b/test/fixtures/min-max.output.css @@ -1,8 +1,8 @@ -@media screen and (min-width: 500.001px) and (max-width: 1199.999px) { +@media screen and (min-width: 501px) and (max-width: 1199px) { } -@media screen and (min-width: 500.001px) and (max-width: 1199.999px) { +@media screen and (min-width: 501px) and (max-width: 1199px) { } @@ -26,11 +26,11 @@ } /* height */ -@media screen and (min-height: 500.001px) and (max-height: 1199.999px) { +@media screen and (min-height: 501px) and (max-height: 1199px) { } -@media screen and (min-height: 500.001px) and (max-height: 1199.999px) { +@media screen and (min-height: 501px) and (max-height: 1199px) { } From 12c39814d53d76372499731adc37bc8656843dcd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=B8=80=E4=B8=9D?= Date: Thu, 26 Nov 2015 23:00:20 +0800 Subject: [PATCH 355/795] V2.1.1 --- CHANGELOG.md | 4 ++++ package.json | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 972aa1f299..c67b00508b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,7 @@ +# 2.1.1 2015-11-26 + +Fix: Pixels rounding errors in fractional pixels media queries. + # 2.1.0 2015-09-08 Add: Support for `<` and `>` without `=`. diff --git a/package.json b/package.json index 85023e1f06..fe3f68fbc1 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "postcss-media-minmax", - "version": "2.1.0", + "version": "2.1.1", "description": "Using more intuitive `>=`, `<=`, `>`, `<` instead of media queries min/max prefix.", "scripts": { "test": "tape test" From 658b8b7e5b76c49a4d7752f3136247a2173b5b7a Mon Sep 17 00:00:00 2001 From: Jonathan Neal Date: Sun, 3 Jan 2016 23:41:09 -0500 Subject: [PATCH 356/795] 2.1.0 --- CHANGELOG.md | 4 ++++ index.js | 6 +++++- package.json | 2 +- test/fixtures/direct.css | 10 +++++++++- test/fixtures/direct.expect.css | 16 ++++++++++++---- 5 files changed, 31 insertions(+), 7 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c829217f41..f31bbb926b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,7 @@ +## 2.1.0 (2016-01-03) + +- Added: Support for valid direct nesting + ## 2.0.6 (2015-10-15) - Fixed: Issue with new PostCSS rules diff --git a/index.js b/index.js index 3b7d36ddb9..4a1623722c 100644 --- a/index.js +++ b/index.js @@ -60,7 +60,11 @@ module.exports = postcss.plugin('postcss-nested', function (opts) { }); css.walkRules(function (rule) { - if (rule.parent.type === 'root' || rule.selector.indexOf('&') === -1) return; + if (rule.parent.type === 'root') return; + + if (rule.selectors.filter(function (selector) { + return selector.lastIndexOf('&') !== 0; + }).length) return; transpileSelectors(rule.parent, rule); diff --git a/package.json b/package.json index 929e9dc97d..4ce816ea67 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "postcss-nesting", - "version": "2.0.6", + "version": "2.1.0", "description": "Transpiles nested rules according to CSS Nesting Module Level 3", "keywords": [ "postcss", diff --git a/test/fixtures/direct.css b/test/fixtures/direct.css index f48fdc1db0..b59eea380c 100644 --- a/test/fixtures/direct.css +++ b/test/fixtures/direct.css @@ -22,7 +22,15 @@ a, b { color: red; & & { - color: white + color: white; + } + + c & { + color: blue; + } + + & c, c & { + color: black; } } diff --git a/test/fixtures/direct.expect.css b/test/fixtures/direct.expect.css index f83a98f67c..08b6eeef62 100644 --- a/test/fixtures/direct.expect.css +++ b/test/fixtures/direct.expect.css @@ -19,11 +19,19 @@ a c e, a c f, a d e, a d f, b c e, b c f, b d e, b d f { } a, b { - color: red -} + color: red; -a a, b b { - color: white + & & { + color: white; + } + + c & { + color: blue; + } + + & c, c & { + color: black; + } } a { From 08bcbc85735d370fc912d61ce1109dd8451a75fc Mon Sep 17 00:00:00 2001 From: Jonathan Neal Date: Sun, 3 Jan 2016 23:56:45 -0500 Subject: [PATCH 357/795] 2.1.1 --- .editorconfig | 8 ++-- .gitignore | 2 +- .travis.yml | 2 +- CHANGELOG.md | 4 ++ CONTRIBUTING.md | 65 +++++++++++++-------------- README.md | 46 ++++++++++--------- index.js | 24 +++++----- package.json | 25 +++++------ test/index.js => test.js | 20 +++++++-- test/{fixtures => }/basic.css | 0 test/{fixtures => }/basic.expect.css | 0 test/{fixtures => }/direct.css | 0 test/{fixtures => }/direct.expect.css | 0 test/{fixtures => }/ignore.css | 0 test/{fixtures => }/ignore.expect.css | 0 15 files changed, 105 insertions(+), 91 deletions(-) rename test/index.js => test.js (77%) rename test/{fixtures => }/basic.css (100%) rename test/{fixtures => }/basic.expect.css (100%) rename test/{fixtures => }/direct.css (100%) rename test/{fixtures => }/direct.expect.css (100%) rename test/{fixtures => }/ignore.css (100%) rename test/{fixtures => }/ignore.expect.css (100%) diff --git a/.editorconfig b/.editorconfig index 7843e7d086..d3093817e5 100644 --- a/.editorconfig +++ b/.editorconfig @@ -1,14 +1,16 @@ root = true [*] -indent_style = tab -end_of_line = lf charset = utf-8 -trim_trailing_whitespace = true +end_of_line = lf +indent_style = tab insert_final_newline = true +trim_trailing_whitespace = true [*.md] trim_trailing_whitespace = false [*.{json,yml}] indent_size = 2 +indent_style = space +insert_final_newline = false diff --git a/.gitignore b/.gitignore index 4dd3d0638a..ca9ef401c6 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,3 @@ node_modules/ npm-debug.log -test/fixtures/*.actual.css +test/*.actual.css diff --git a/.travis.yml b/.travis.yml index c8d066397a..33612fd414 100644 --- a/.travis.yml +++ b/.travis.yml @@ -2,4 +2,4 @@ sudo: false language: node_js node_js: - stable - - "0.12" + - "0.12" \ No newline at end of file diff --git a/CHANGELOG.md b/CHANGELOG.md index f31bbb926b..dbf2dee590 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,7 @@ +## 2.1.1 (2016-01-03) + +- Updated: Project conventions + ## 2.1.0 (2016-01-03) - Added: Support for valid direct nesting diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index d4c8b8e086..ed4bd6063f 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -7,55 +7,54 @@ Found a problem? Want a new feature? - See if your issue or idea has [already been reported]. - Provide a [reduced test case] or a [live example]. -Remember, a bug is a _demonstrable problem_ caused by _our_ code. Please use this [demo] as a testing platform. You can share code entered here at any time by pressing the Meta and S keys (`⌘S`) to save the current code as a URL. +Remember, a bug is a _demonstrable problem_ caused by _our_ code. ## Submitting Pull Requests Pull requests are the greatest contributions, so be sure they are focused in scope, and do avoid unrelated commits. 1. To begin, [fork this project], clone your fork, and add our upstream. - ```bash - # Clone your fork of the repo into the current directory - git clone https://github.com//postcss-nesting - # Navigate to the newly cloned directory - cd postcss-nesting - # Assign the original repo to a remote called "upstream" - git remote add upstream https://github.com/jonathantneal/postcss-nesting - # Install the tools necessary for development - npm install - ``` + ```bash + # Clone your fork of the repo into the current directory + git clone https://github.com//postcss-nesting + # Navigate to the newly cloned directory + cd postcss-nesting + # Assign the original repo to a remote called "upstream" + git remote add upstream https://github.com/jonathantneal/postcss-nesting + # Install the tools necessary for development + npm install + ``` 2. Create a branch for your feature or fix: - ```bash - # Move into a new branch for a feature - git checkout -b feature/thing - ``` - ```bash - # Move into a new branch for a fix - git checkout -b fix/something - ``` + ```bash + # Move into a new branch for a feature + git checkout -b feature/thing + ``` + ```bash + # Move into a new branch for a fix + git checkout -b fix/something + ``` 3. Be sure your code follows our practices. - ```bash - # Test current code - npm run test - ``` + ```bash + # Test current code + npm run test + ``` 4. Push your branch up to your fork: - ```bash - # Push a feature branch - git push origin feature/thing - ``` - ```bash - # Push a fix branch - git push origin fix/something - ``` + ```bash + # Push a feature branch + git push origin feature/thing + ``` + ```bash + # Push a fix branch + git push origin fix/something + ``` 5. Now [open a pull request] with a clear title and description. [already been reported]: issues -[demo]: http://jonathantneal.github.io/postcss-nesting/ [fork this project]: fork [live example]: http://codepen.io/pen [open a pull request]: https://help.github.com/articles/using-pull-requests/ -[reduced test case]: https://css-tricks.com/reduced-test-cases/ \ No newline at end of file +[reduced test case]: https://css-tricks.com/reduced-test-cases/ diff --git a/README.md b/README.md index ed7480a7e4..3d96f4b69d 100644 --- a/README.md +++ b/README.md @@ -1,10 +1,11 @@ -# CSS Nesting [![Build Status][ci-img]][ci] +# CSS Nesting - +PostCSS Logo + +[![NPM Version][npm-img]][npm] [![Build Status][ci-img]][ci] [CSS Nesting] allows you to nest one style rule inside another, following the [CSS Nesting Module Level 3] specification. -### At Rule Nesting ```css /* at rule nesting */ @@ -77,8 +78,6 @@ a:hover, b:hover { ## Usage -Follow these steps to use [CSS Nesting]. - Add [CSS Nesting] to your build tool: ```bash @@ -87,10 +86,8 @@ npm install postcss-nesting --save-dev #### Node -Use [CSS Nesting] directly: - ```js -require('postcss-nesting')({ /* options */ }).process(YOUR_CSS); +require('postcss-nesting').process(YOUR_CSS, { /* options */ }); ``` #### PostCSS @@ -101,12 +98,12 @@ Add [PostCSS] to your build tool: npm install postcss --save-dev ``` -Use [CSS Nesting] as a PostCSS plugin: +Load [CSS Nesting] as a PostCSS plugin: ```js postcss([ require('postcss-nesting')({ /* options */ }) -]); +]).process(YOUR_CSS, /* options */); ``` #### Gulp @@ -117,18 +114,18 @@ Add [Gulp PostCSS] to your build tool: npm install gulp-postcss --save-dev ``` -Use [CSS Nesting] within your Gulpfile: +Enable [CSS Nesting] within your Gulpfile: ```js var postcss = require('gulp-postcss'); gulp.task('css', function () { - return gulp.src('./css/src/*.css').pipe( + return gulp.src('./src/*.css').pipe( postcss([ require('postcss-nesting')({ /* options */ }) ]) ).pipe( - gulp.dest('./css') + gulp.dest('.') ); }); ``` @@ -141,7 +138,7 @@ Add [Grunt PostCSS] to your build tool: npm install grunt-postcss --save-dev ``` -Use [CSS Nesting] within your Gruntfile: +Enable [CSS Nesting] within your Gruntfile: ```js grunt.loadNpmTasks('grunt-postcss'); @@ -149,12 +146,12 @@ grunt.loadNpmTasks('grunt-postcss'); grunt.initConfig({ postcss: { options: { - processors: [ + use: [ require('postcss-nesting')({ /* options */ }) ] }, dist: { - src: 'css/*.css' + src: '*.css' } } }); @@ -176,10 +173,15 @@ Default: `null` Specifies a prefix to be surrounded by dashes before the `@nest` at-rule (e.g. `@-x-nest`). -[ci]: https://travis-ci.org/jonathantneal/postcss-nesting -[ci-img]: https://travis-ci.org/jonathantneal/postcss-nesting.svg -[CSS Nesting]: https://github.com/jonathantneal/postcss-nesting -[CSS Nesting Module Level 3]: http://tabatkins.github.io/specs/css-nesting/ -[Gulp PostCSS]: https://github.com/postcss/gulp-postcss +[ci]: https://travis-ci.org/jonathantneal/postcss-nesting +[ci-img]: https://img.shields.io/travis/jonathantneal/postcss-nesting.svg +[npm]: https://www.npmjs.com/package/postcss-nesting +[npm-img]: https://img.shields.io/npm/v/postcss-nesting.svg + +[Gulp PostCSS]: https://github.com/postcss/gulp-postcss [Grunt PostCSS]: https://github.com/nDmitry/grunt-postcss -[PostCSS]: https://github.com/postcss/postcss +[PostCSS]: https://github.com/postcss/postcss + +[CSS Nesting Module Level 3]: http://tabatkins.github.io/specs/css-nesting/ + +[CSS Nesting]: https://github.com/jonathantneal/postcss-nesting diff --git a/index.js b/index.js index 4a1623722c..aeb629e811 100644 --- a/index.js +++ b/index.js @@ -1,17 +1,5 @@ var postcss = require('postcss'); -function transpileSelectors(fromRule, toRule) { - var selectors = []; - - fromRule.selectors.forEach(function (fromSelector) { - toRule.selectors.forEach(function (toSelector) { - selectors.push(toSelector.replace(/&/g, fromSelector)); - }); - }); - - toRule.selectors = selectors; -} - module.exports = postcss.plugin('postcss-nested', function (opts) { var bubble = ['document', 'media', 'supports']; var name = 'nest'; @@ -76,3 +64,15 @@ module.exports = postcss.plugin('postcss-nested', function (opts) { }); }; }); + +function transpileSelectors(fromRule, toRule) { + var selectors = []; + + fromRule.selectors.forEach(function (fromSelector) { + toRule.selectors.forEach(function (toSelector) { + selectors.push(toSelector.replace(/&/g, fromSelector)); + }); + }); + + toRule.selectors = selectors; +} diff --git a/package.json b/package.json index 4ce816ea67..6db1771d51 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "postcss-nesting", - "version": "2.1.0", + "version": "2.1.1", "description": "Transpiles nested rules according to CSS Nesting Module Level 3", "keywords": [ "postcss", @@ -12,29 +12,24 @@ ], "author": "Jonathan Neal ", "license": "CC0-1.0", - "repository": { - "type": "git", - "url": "https://github.com/jonathantneal/postcss-nesting.git" - }, - "bugs": { - "url": "https://github.com/jonathantneal/postcss-nesting/issues" - }, + "repository": "jonathantneal/postcss-nesting", + "bugs": "https://github.com/jonathantneal/postcss-nesting/issues", "homepage": "https://github.com/jonathantneal/postcss-nesting", "dependencies": { - "postcss": "^5.0.9" + "postcss": "^5.0.14" }, "devDependencies": { - "eslint": "^1.6.0", - "tap-spec": "^4.1.0", - "tape": "^4.2.1" + "eslint": "^1.10.3", + "tap-spec": "^4.1.1", + "tape": "^4.4.0" }, "scripts": { "lint": "eslint . --ignore-path .gitignore", - "test-fixtures": "tape test/*.js | tap-spec", - "test": "npm run lint && npm run test-fixtures" + "tape": "tape test.js | tap-spec", + "test": "npm run lint && npm run tape" }, "engines": { "iojs": ">=2.0.0", "node": ">=0.12.0" } -} +} \ No newline at end of file diff --git a/test/index.js b/test.js similarity index 77% rename from test/index.js rename to test.js index 566f50d4b5..11827dc9c6 100644 --- a/test/index.js +++ b/test.js @@ -13,11 +13,11 @@ var tests = { }; var debug = true; -var dir = './test/fixtures/'; +var dir = './test/'; var fs = require('fs'); var path = require('path'); -var plugin = require('../'); +var plugin = require('./'); var test = require('tape'); Object.keys(tests).forEach(function (name) { @@ -41,8 +41,20 @@ Object.keys(tests).forEach(function (name) { var expectPath = path.resolve(dir + testName + '.expect.css'); var actualPath = path.resolve(dir + testName + '.actual.css'); - var inputCSS = fs.readFileSync(inputPath, 'utf8'); - var expectCSS = fs.readFileSync(expectPath, 'utf8'); + var inputCSS = ''; + var expectCSS = ''; + + try { + inputCSS = fs.readFileSync(inputPath, 'utf8'); + } catch (error) { + fs.writeFileSync(inputPath, inputCSS); + } + + try { + expectCSS = fs.readFileSync(expectPath, 'utf8'); + } catch (error) { + fs.writeFileSync(expectPath, expectCSS); + } plugin.process(inputCSS, options).then(function (result) { var actualCSS = result.css; 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/direct.css b/test/direct.css similarity index 100% rename from test/fixtures/direct.css rename to test/direct.css diff --git a/test/fixtures/direct.expect.css b/test/direct.expect.css similarity index 100% rename from test/fixtures/direct.expect.css rename to test/direct.expect.css diff --git a/test/fixtures/ignore.css b/test/ignore.css similarity index 100% rename from test/fixtures/ignore.css rename to test/ignore.css diff --git a/test/fixtures/ignore.expect.css b/test/ignore.expect.css similarity index 100% rename from test/fixtures/ignore.expect.css rename to test/ignore.expect.css From 75a69152aa48de26283df101a4537a403da7f5e1 Mon Sep 17 00:00:00 2001 From: Tyler Buck Date: Sat, 30 Jan 2016 01:07:57 -0500 Subject: [PATCH 358/795] Properly detect circular dependencies Fixes #16 --- index.js | 22 ++++++++++--------- .../fixtures/transform-circular-reference.css | 6 +++++ 2 files changed, 18 insertions(+), 10 deletions(-) diff --git a/index.js b/index.js index cd0b178270..737035c419 100755 --- a/index.js +++ b/index.js @@ -5,11 +5,11 @@ var EXTENSION_RE = /\(\s*(--[\w-]+)\s*\)/g /* * Resolve custom media values. */ -function resolveValue(value, map, result) { - if (!EXTENSION_RE.test(value)) { - return value +function resolveValue(query, depChain, map, result) { + if (!EXTENSION_RE.test(query.value)) { + return query.value } - return value.replace(EXTENSION_RE, function(orig, name) { + var val = query.value.replace(EXTENSION_RE, function(orig, name) { if (!map[name]) { return orig } @@ -19,14 +19,18 @@ function resolveValue(value, map, result) { return mq.value } - if (mq.deps.indexOf(name) !== -1) { + if (depChain.indexOf(name) !== -1) { mq.circular = true return orig } - mq.deps.push(name) - mq.value = resolveValue(mq.value, map, result) + depChain.push(name) + mq.value = resolveValue(mq, depChain, map, result) return mq.value }) + if (val === query.value) { + query.circular = true + } + return val } /* @@ -61,7 +65,6 @@ function customMedia(options) { // map[] = map[params.shift()] = { value: params.join(" "), - deps: [], circular: false, resolved: false, } @@ -75,14 +78,13 @@ function customMedia(options) { Object.keys(extensions).forEach(function(name) { map[name] = { value: extensions[name], - deps: [], circular: false, resolved: false, } }) Object.keys(map).forEach(function(name) { - map[name].value = resolveValue(map[name].value, map, result) + map[name].value = resolveValue(map[name], [name], map, result) map[name].resolved = true }) diff --git a/test/fixtures/transform-circular-reference.css b/test/fixtures/transform-circular-reference.css index 5de94623d9..48b1f3cfc1 100644 --- a/test/fixtures/transform-circular-reference.css +++ b/test/fixtures/transform-circular-reference.css @@ -3,6 +3,12 @@ body { color: #000 } @custom-media --a (--b); @custom-media --b (--a); +@media (--a) { + selector { + property: value; + } +} + @media (--b) { selector { property: value; From ef0b764fc9eeccff9d1157ebd94127894030af86 Mon Sep 17 00:00:00 2001 From: Jonathan Neal Date: Sat, 30 Jan 2016 01:32:10 -0500 Subject: [PATCH 359/795] 2.2.0 - Added: Nesting of all at-rules - Updated: Direct nesting order maintains order - Updated: Tests and documentation --- CHANGELOG.md | 6 ++++ README.md | 8 ++++++ index.js | 64 ++++++++++++++++++++++++------------------ package.json | 7 +++-- test.js | 3 ++ test/direct.expect.css | 2 +- test/media.css | 17 +++++++++++ test/media.expect.css | 26 +++++++++++++++++ 8 files changed, 103 insertions(+), 30 deletions(-) create mode 100644 test/media.css create mode 100644 test/media.expect.css diff --git a/CHANGELOG.md b/CHANGELOG.md index dbf2dee590..f1a1b00f21 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,9 @@ +## 2.2.0 (2016-01-30) + +- Added: Nesting of all at-rules +- Updated: Direct nesting order maintains order +- Updated: Tests and documentation + ## 2.1.1 (2016-01-03) - Updated: Project conventions diff --git a/README.md b/README.md index 3d96f4b69d..d0f01d9a1e 100644 --- a/README.md +++ b/README.md @@ -48,6 +48,10 @@ a, b { @media (min-width: 30em) { color: yellow; + + @media (min-device-pixel-ratio: 1.5) { + color: green; + } } } @@ -74,6 +78,10 @@ a:hover, b:hover { color: yellow; } } + +@media (min-width: 30em) and (min-device-pixel-ratio: 1.5) { + color: green; +} ``` ## Usage diff --git a/index.js b/index.js index aeb629e811..ac1cc647ea 100644 --- a/index.js +++ b/index.js @@ -8,58 +8,68 @@ module.exports = postcss.plugin('postcss-nested', function (opts) { if (opts && opts.prefix) name = '-' + opts.prefix + '-' + name; return function (css) { - css.walkAtRules(function (atrule) { - var rule = atrule.parent; + css.walk(function (target) { + var rule = target.parent; var root = rule && rule.parent; + var isAtRule = target.type === 'atrule'; + var isRule = target.type === 'rule'; + if (root && rule.type === 'rule') { var newrule = postcss.rule({ - source: atrule.source + source: target.source }); - if (atrule.name === name && ~atrule.params.indexOf('&')) { - atrule.remove(); + if (isRule && target.selectors.every(function (selector) { + return selector.lastIndexOf('&') === 0; + })) { + target.remove(); - newrule.selector = atrule.params; + newrule.selector = target.selector; - newrule.append(atrule.nodes); + newrule.append(target.nodes); transpileSelectors(rule, newrule); root.insertAfter(rule.insertAfterNode || rule, newrule); rule.insertAfterNode = newrule; - } else if (~bubble.indexOf(atrule.name)) { - atrule.remove(); + } else if (isAtRule && target.name === name && ~target.params.indexOf('&')) { + target.remove(); - newrule.selector = rule.selector; + newrule.selector = target.params; - newrule.append(atrule.nodes); + newrule.append(target.nodes); - atrule.removeAll(); + transpileSelectors(rule, newrule); - atrule.append(newrule); + root.insertAfter(rule.insertAfterNode || rule, newrule); - root.insertAfter(rule.insertAfterNode || rule, atrule); + rule.insertAfterNode = newrule; + } else if (isAtRule && ~bubble.indexOf(target.name)) { + var selector = rule.selector; - rule.insertAfterNode = atrule; - } - } - }); + if (root.type === 'atrule' && root.name === target.name && root.parent) { + target.params = root.params + ' and ' + target.params; + + rule = root; + root = root.parent; + } + + target.remove(); - css.walkRules(function (rule) { - if (rule.parent.type === 'root') return; + newrule.selector = selector; - if (rule.selectors.filter(function (selector) { - return selector.lastIndexOf('&') !== 0; - }).length) return; + newrule.append(target.nodes); - transpileSelectors(rule.parent, rule); + target.removeAll(); - rule.moveAfter(rule.parent); + target.append(newrule); - if (!rule.prev().nodes.length) { - rule.prev().remove(); + root.insertAfter(rule.insertAfterNode || rule, target); + + rule.insertAfterNode = target; + } } }); }; diff --git a/package.json b/package.json index 6db1771d51..0866c47a7e 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "postcss-nesting", - "version": "2.1.1", + "version": "2.2.0", "description": "Transpiles nested rules according to CSS Nesting Module Level 3", "keywords": [ "postcss", @@ -8,7 +8,10 @@ "postcss-plugin", "nestings", "selectors", - "rules" + "rules", + "specs", + "specifications", + "cssnext" ], "author": "Jonathan Neal ", "license": "CC0-1.0", diff --git a/test.js b/test.js index 11827dc9c6..b919681a84 100644 --- a/test.js +++ b/test.js @@ -8,6 +8,9 @@ var tests = { }, 'ignore': { message: 'ignores invalid syntax' + }, + 'media': { + message: 'supports nested media queries' } } }; diff --git a/test/direct.expect.css b/test/direct.expect.css index 08b6eeef62..4bd6a506b1 100644 --- a/test/direct.expect.css +++ b/test/direct.expect.css @@ -58,7 +58,7 @@ a b { a b { color: blue } - } +} @media { diff --git a/test/media.css b/test/media.css new file mode 100644 index 0000000000..6e8af9b0bc --- /dev/null +++ b/test/media.css @@ -0,0 +1,17 @@ +.main { + color: blue; + + @media (min-width: 100px) { + color: white; + + @media (max-width: 200px) { + color: red; + } + + & .child { + @media (max-width: 200px) { + color: green; + } + } + } +} diff --git a/test/media.expect.css b/test/media.expect.css new file mode 100644 index 0000000000..c59823b8e7 --- /dev/null +++ b/test/media.expect.css @@ -0,0 +1,26 @@ +.main { + color: blue +} + + @media (min-width: 100px) { + + .main { + color: white + } + + .main .child {} + } + + @media (min-width: 100px) and (max-width: 200px) { + + .main { + color: red + } +} + + @media (min-width: 100px) and (max-width: 200px) { + + .main .child { + color: green + } +} From c1bfe9fd04c66da6f86072f063c3539b061344b4 Mon Sep 17 00:00:00 2001 From: Maxime Thirouin Date: Wed, 3 Feb 2016 07:54:27 +0100 Subject: [PATCH 360/795] 5.0.1 --- .eslintrc | 39 --------------------------------------- .travis.yml | 7 +++++++ CHANGELOG.md | 5 +++++ index.js | 6 +++--- package.json | 14 +++++++++++--- test/index.js | 2 +- 6 files changed, 27 insertions(+), 46 deletions(-) delete mode 100644 .eslintrc diff --git a/.eslintrc b/.eslintrc deleted file mode 100644 index 18d7c97bd3..0000000000 --- a/.eslintrc +++ /dev/null @@ -1,39 +0,0 @@ ---- -root: true -extends: eslint:recommended - -#ecmaFeatures: -# modules: true - -env: -# es6: true - browser: true - node: true - -rules: - indent: [2, 2] # 2 spaces indentation - max-len: [2, 80, 4] - 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}] - space-after-keywords: [2, "always"] - space-before-blocks: [2, "always"] - space-before-function-paren: [2, "never"] - space-in-parens: [2, "never"] - spaced-comment: [2, "always"] diff --git a/.travis.yml b/.travis.yml index 587bd3e031..dd60f935ee 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1 +1,8 @@ language: node_js + +node_js: + - 4 + - 5 + +matrix: + fast_finish: true diff --git a/CHANGELOG.md b/CHANGELOG.md index f83ce47aa4..06051ddb58 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,8 @@ +# 5.0.1 - 2016-02-03 + +- Fixed: circular dependencies are properly detected +([#17](https://github.com/postcss/postcss-custom-media/pull/17)) + # 5.0.0 - 2015-08-25 - Removed: compatibility with postcss v4.x diff --git a/index.js b/index.js index 737035c419..5531f7589a 100755 --- a/index.js +++ b/index.js @@ -84,7 +84,7 @@ function customMedia(options) { }) Object.keys(map).forEach(function(name) { - map[name].value = resolveValue(map[name], [name], map, result) + map[name].value = resolveValue(map[name], [ name ], map, result) map[name].resolved = true }) @@ -100,7 +100,7 @@ function customMedia(options) { result.warn( "Circular @custom-media definition for '" + name + "'. The entire rule has been removed from the output.", - {node: rule} + { node: rule } ) toRemove.push(rule) } @@ -110,7 +110,7 @@ function customMedia(options) { result.warn( "Missing @custom-media definition for '" + name + "'. The entire rule has been removed from the output.", - {node: rule} + { node: rule } ) toRemove.push(rule) }) diff --git a/package.json b/package.json index 2af41a55e6..a316688652 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "postcss-custom-media", - "version": "5.0.0", + "version": "5.0.1", "description": "PostCSS plugin to transform W3C CSS Custom Media Queries to more compatible CSS", "keywords": [ "css", @@ -22,10 +22,18 @@ "postcss": "^5.0.0" }, "devDependencies": { - "eslint": "^1.0.0", + "eslint": "^1.10.3", + "eslint-config-i-am-meticulous": "^2.0.0", + "npmpub": "^3.0.1", "tape": "^4.0.0" }, "scripts": { - "test": "eslint . && tape test" + "lint": "eslint --fix .", + "tests": "tape test", + "test": "npm run lint && npm run tests", + "release": "npmpub" + }, + "eslintConfig": { + "extends": "eslint-config-i-am-meticulous/es5" } } diff --git a/test/index.js b/test/index.js index a11c177234..55801e0c0c 100755 --- a/test/index.js +++ b/test/index.js @@ -97,7 +97,7 @@ test("@custom-media", function(t) { t, "preserve", "should preserve custom media", - {preserve: true} + { preserve: true } ) compareFixtures( From 94858d5e20bbf665d0a22d43993f165cfa7aef77 Mon Sep 17 00:00:00 2001 From: Anton Wilhelm Date: Thu, 11 Feb 2016 18:02:40 +0100 Subject: [PATCH 361/795] typo fix --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 6f6441fee4..3c2296d199 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "postcss-selector-not", "version": "2.0.0", - "description": "PostCSS plugin to transform :not() W3C CSS leve 4 pseudo class to :not() CSS level 3 selectors", + "description": "PostCSS plugin to transform :not() W3C CSS level 4 pseudo class to :not() CSS level 3 selectors", "keywords": [ "postcss", "postcss-plugin", From 1bfd17af8b4f80f58c655671a9dfeeb69f9d6315 Mon Sep 17 00:00:00 2001 From: David Clark Date: Thu, 18 Feb 2016 19:45:07 -0700 Subject: [PATCH 362/795] Change plugin name to postcss-nesting I found it very confusing when I saw that this plugin was registering its name as postcss-nested instead of postcss-nesting. Does this seem like a reasonable change to you? --- index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/index.js b/index.js index ac1cc647ea..d3e984a426 100644 --- a/index.js +++ b/index.js @@ -1,6 +1,6 @@ var postcss = require('postcss'); -module.exports = postcss.plugin('postcss-nested', function (opts) { +module.exports = postcss.plugin('postcss-nesting', function (opts) { var bubble = ['document', 'media', 'supports']; var name = 'nest'; From ed6da54914635f13147218b6e047cdbd5b4f3f16 Mon Sep 17 00:00:00 2001 From: Jonathan Neal Date: Sat, 20 Feb 2016 23:00:45 -0500 Subject: [PATCH 363/795] Use explicit indexOf --- index.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/index.js b/index.js index d3e984a426..1ae04c30ac 100644 --- a/index.js +++ b/index.js @@ -34,7 +34,7 @@ module.exports = postcss.plugin('postcss-nesting', function (opts) { root.insertAfter(rule.insertAfterNode || rule, newrule); rule.insertAfterNode = newrule; - } else if (isAtRule && target.name === name && ~target.params.indexOf('&')) { + } else if (isAtRule && target.name === name && target.params.indexOf('&') !== -1) { target.remove(); newrule.selector = target.params; @@ -46,7 +46,7 @@ module.exports = postcss.plugin('postcss-nesting', function (opts) { root.insertAfter(rule.insertAfterNode || rule, newrule); rule.insertAfterNode = newrule; - } else if (isAtRule && ~bubble.indexOf(target.name)) { + } else if (isAtRule && bubble.indexOf(target.name) !== -1) { var selector = rule.selector; if (root.type === 'atrule' && root.name === target.name && root.parent) { From f53deb8c2bc402b8574b47c12686e8d122f704cb Mon Sep 17 00:00:00 2001 From: Jonathan Neal Date: Sat, 20 Feb 2016 23:01:31 -0500 Subject: [PATCH 364/795] Properly concatenate at-rules --- index.js | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/index.js b/index.js index 1ae04c30ac..63299f526c 100644 --- a/index.js +++ b/index.js @@ -1,4 +1,5 @@ var postcss = require('postcss'); +var comma = postcss.list.comma; module.exports = postcss.plugin('postcss-nesting', function (opts) { var bubble = ['document', 'media', 'supports']; @@ -50,7 +51,11 @@ module.exports = postcss.plugin('postcss-nesting', function (opts) { var selector = rule.selector; if (root.type === 'atrule' && root.name === target.name && root.parent) { - target.params = root.params + ' and ' + target.params; + target.params = comma(root.params).map(function (params1) { + return comma(target.params).map(function (params2) { + return params1 + ' and ' + params2; + }).join(', '); + }).join(', '); rule = root; root = root.parent; From c45f5713792b179fd8e738cf4f752f42a70b8445 Mon Sep 17 00:00:00 2001 From: Jonathan Neal Date: Sat, 20 Feb 2016 23:06:28 -0500 Subject: [PATCH 365/795] Use curly braces in conditionals --- index.js | 9 +++++++-- test.js | 4 +++- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/index.js b/index.js index 63299f526c..12b0b5544a 100644 --- a/index.js +++ b/index.js @@ -5,8 +5,13 @@ module.exports = postcss.plugin('postcss-nesting', function (opts) { var bubble = ['document', 'media', 'supports']; var name = 'nest'; - if (opts && opts.bubble) bubble = bubble.concat(opts.bubble); - if (opts && opts.prefix) name = '-' + opts.prefix + '-' + name; + if (opts && opts.bubble) { + bubble = bubble.concat(opts.bubble); + } + + if (opts && opts.prefix) { + name = '-' + opts.prefix + '-' + name; + } return function (css) { css.walk(function (target) { diff --git a/test.js b/test.js index b919681a84..7f57984ca5 100644 --- a/test.js +++ b/test.js @@ -62,7 +62,9 @@ Object.keys(tests).forEach(function (name) { plugin.process(inputCSS, options).then(function (result) { var actualCSS = result.css; - if (debug) fs.writeFileSync(actualPath, actualCSS); + if (debug) { + fs.writeFileSync(actualPath, actualCSS); + } t.equal(actualCSS, expectCSS, message); From f582a24ceceabe61c0b5a0a975c49de1d34466c3 Mon Sep 17 00:00:00 2001 From: Jonathan Neal Date: Sat, 20 Feb 2016 23:11:32 -0500 Subject: [PATCH 366/795] 2.3.0 --- .editorconfig | 1 - .eslintrc | 267 +++++++++++++++++++++++------------------- .jscsrc | 102 ++++++++++++++++ .travis.yml | 2 +- CHANGELOG.md | 6 + README.md | 24 ++-- package.json | 20 ++-- test/media.css | 8 ++ test/media.expect.css | 19 ++- 9 files changed, 309 insertions(+), 140 deletions(-) create mode 100644 .jscsrc diff --git a/.editorconfig b/.editorconfig index d3093817e5..5a40119853 100644 --- a/.editorconfig +++ b/.editorconfig @@ -13,4 +13,3 @@ trim_trailing_whitespace = false [*.{json,yml}] indent_size = 2 indent_style = space -insert_final_newline = false diff --git a/.eslintrc b/.eslintrc index d85f6967e9..33ed8c1f4f 100644 --- a/.eslintrc +++ b/.eslintrc @@ -1,122 +1,153 @@ { - "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": [2], - "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": [2, { "align": "value" }], - "complexity": [2], - "new-parens": [2], - "no-eq-null": [2], - "no-bitwise": [0], - "wrap-iife": [2], - "no-caller": [2], - "use-isnan": [2], - "no-labels": [2], - "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 + "node": true + }, + "rules": { + "accessor-pairs": [2], + "block-scoped-var": [2], + "callback-return": [2], + "complexity": [2, 20], + "consistent-return": [2], + "consistent-this": [2, "self"], + "constructor-super": [2], + "default-case": [2], + "eqeqeq": [2], + "func-style": [0], + "global-require": [2], + "guard-for-in": [0], + "handle-callback-err": [2, "^err(or)?$"], + "id-length": [0], + "id-match": [0], + "init-declarations": [0], + "max-depth": [2, 6], + "max-nested-callbacks": [0], + "max-params": [2, 3], + "max-statements": [0], + "new-parens": [0], + "no-alert": [2], + "no-array-constructor": [0], + "no-bitwise": [0], + "no-caller": [2], + "no-case-declarations": [2], + "no-catch-shadow": [2], + "no-class-assign": [2], + "no-cond-assign": [2], + "no-console": [0], + "no-const-assign": [2], + "no-constant-condition": [0], + "no-continue": [0], + "no-control-regex": [2], + "no-debugger": [2], + "no-delete-var": [2], + "no-div-regex": [0], + "no-dupe-args": [2], + "no-dupe-class-members": [2], + "no-dupe-keys": [2], + "no-duplicate-case": [2], + "no-else-return": [0], + "no-empty-character-class": [2], + "no-empty-label": [2], + "no-empty-pattern": [2], + "no-empty": [2], + "no-eq-null": [2], + "no-eval": [2], + "no-ex-assign": [2], + "no-extend-native": [0], + "no-extra-bind": [2], + "no-extra-boolean-cast": [2], + "no-extra-parens": [2], + "no-extra-semi": [2], + "no-fallthrough": [2], + "no-floating-decimal": [2], + "no-func-assign": [2], + "no-implicit-coercion": [2], + "no-implicit-globals": [0], + "no-implied-eval": [2], + "no-inline-comments": [0], + "no-inner-declarations": [2], + "no-invalid-regexp": [2], + "no-invalid-this": [0], + "no-irregular-whitespace": [2], + "no-iterator": [2], + "no-label-var": [2], + "no-labels": [0], + "no-lone-blocks": [2], + "no-lonely-if": [2], + "no-loop-func": [2], + "no-magic-numbers": [0], + "no-mixed-requires": [0], + "no-multi-str": [2], + "no-native-reassign": [2], + "no-negated-condition": [0], + "no-negated-in-lhs": [2], + "no-nested-ternary": [0], + "no-new-func": [0], + "no-new-object": [2], + "no-new-require": [0], + "no-new-wrappers": [2], + "no-new": [2], + "no-obj-calls": [2], + "no-octal-escape": [2], + "no-octal": [2], + "no-param-reassign": [2], + "no-path-concat": [2], + "no-plusplus": [0], + "no-process-env": [2], + "no-process-exit": [0], + "no-proto": [2], + "no-redeclare": [2], + "no-regex-spaces": [0], + "no-restricted-imports": [0], + "no-restricted-syntax": [0], + "no-return-assign": [2], + "no-script-url": [0], + "no-self-compare": [2], + "no-sequences": [2], + "no-shadow-restricted-names": [2], + "no-shadow": [2], + "no-sparse-arrays": [2], + "no-sync": [0], + "no-ternary": [0], + "no-this-before-super": [2], + "no-throw-literal": [2], + "no-undef-init": [0], + "no-undef": [2], + "no-undefined": [0], + "no-unneeded-ternary": [2], + "no-unreachable": [2], + "no-unused-expressions": [2], + "no-unused-vars": [2], + "no-use-before-define": [0], + "no-useless-call": [2], + "no-useless-concat": [2], + "no-var": [0], + "no-void": [0], + "no-with": [2], + "object-shorthand": [0], + "one-var": [0], + "operator-assignment": [2, "always"], + "prefer-arrow-callback": [0], + "prefer-const": [0], + "prefer-reflect": [0], + "prefer-rest-params": [0], + "prefer-spread": [0], + "prefer-template": [0], + "quotes": [0], + "radix": [2, "as-needed"], + "require-yield": [0], + "sort-imports": [0], + "sort-vars": [0], + "strict": [0], + "use-isnan": [2], + "valid-typeof": [2], + "vars-on-top": [0], + "wrap-iife": [2, "inside"], + "wrap-regex": [0], + "yoda": [0], + + "camelcase": [0], + "key-spacing": [0], + "quote-props": [0], + "spaced-comment": [0] } } diff --git a/.jscsrc b/.jscsrc new file mode 100644 index 0000000000..66d97a3327 --- /dev/null +++ b/.jscsrc @@ -0,0 +1,102 @@ +{ + "disallowKeywords": [ + "with" + ], + "disallowKeywordsOnNewLine": [ + "else" + ], + "disallowMultipleSpaces": false, + "disallowMixedSpacesAndTabs": true, + "disallowMultipleLineBreaks": true, + "disallowMultipleLineStrings": true, + "disallowMultipleVarDecl": true, + "disallowNewlineBeforeBlockStatements": true, + "disallowSpaceAfterObjectKeys": true, + "disallowSpaceAfterPrefixUnaryOperators": true, + "disallowSpacesInCallExpression": true, + "disallowSpacesInFunctionDeclaration": { + "beforeOpeningRoundBrace": true + }, + "disallowSpacesInsideArrayBrackets": "all", + "disallowSpacesInsideObjectBrackets": "all", + "disallowSpacesInsideParentheses": true, + "disallowTrailingWhitespace": true, + "maximumLineLength": null, + "requireCamelCaseOrUpperCaseIdentifiers": true, + "requireCapitalizedConstructors": true, + "requireCurlyBraces": [ + "if", + "else", + "for", + "while", + "do", + "try", + "catch" + ], + "requireDotNotation": true, + "requireLineFeedAtFileEnd": true, + "requireOperatorBeforeLineBreak": true, + "requireSemicolons": true, + "requireSpaceAfterBinaryOperators": true, + "requireSpaceAfterKeywords": [ + "if", + "else", + "for", + "while", + "do", + "switch", + "return", + "try", + "catch" + ], + "requireSpaceBeforeBinaryOperators": [ + "=", + "+=", + "-=", + "*=", + "/=", + "%=", + "<<=", + ">>=", + ">>>=", + "&=", + "|=", + "^=", + "+=", + "+", + "-", + "*", + "/", + "%", + "<<", + ">>", + ">>>", + "&", + "|", + "^", + "&&", + "||", + "===", + "==", + ">=", + "<=", + "<", + ">", + "!=", + "!==" + ], + "requireSpaceBeforeBlockStatements": true, + "requireSpaceBeforeObjectValues": true, + "requireSpacesInAnonymousFunctionExpression": { + "beforeOpeningCurlyBrace": true, + "beforeOpeningRoundBrace": true + }, + "requireSpacesInConditionalExpression": true, + "requireSpacesInForStatement": true, + "requireSpacesInFunctionDeclaration": { + "beforeOpeningCurlyBrace": true + }, + "validateIndentation": "\t", + "validateParameterSeparator": ", ", + "validateQuoteMarks": "'" +} diff --git a/.travis.yml b/.travis.yml index 33612fd414..c8d066397a 100644 --- a/.travis.yml +++ b/.travis.yml @@ -2,4 +2,4 @@ sudo: false language: node_js node_js: - stable - - "0.12" \ No newline at end of file + - "0.12" diff --git a/CHANGELOG.md b/CHANGELOG.md index f1a1b00f21..6cefb3f861 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,9 @@ +## 2.3.0 (2016-02-20) + +- Updated: JavaScript formatting, linting, tests, and documentation +- Updated: Properly concatenate at-rules with or expressions +- Updated: Update internal plugin name to postcss-nesting + ## 2.2.0 (2016-01-30) - Added: Nesting of all at-rules diff --git a/README.md b/README.md index d0f01d9a1e..8b068d9482 100644 --- a/README.md +++ b/README.md @@ -7,51 +7,51 @@ [CSS Nesting] allows you to nest one style rule inside another, following the [CSS Nesting Module Level 3] specification. ```css -/* at rule nesting */ +/* direct nesting */ a, b { color: red; - @nest & c, & d { + & c, & d { color: white; } - @nest & & { + & & { color: blue; } - @nest &:hover { + &:hover { color: black; } @media (min-width: 30em) { color: yellow; + + @media (min-device-pixel-ratio: 1.5) { + color: green; + } } } -/* direct nesting */ +/* or at-rule nesting */ a, b { color: red; - & c, & d { + @nest & c, & d { color: white; } - & & { + @nest & & { color: blue; } - &:hover { + @nest &:hover { color: black; } @media (min-width: 30em) { color: yellow; - - @media (min-device-pixel-ratio: 1.5) { - color: green; - } } } diff --git a/package.json b/package.json index 0866c47a7e..014ba86aa6 100644 --- a/package.json +++ b/package.json @@ -1,17 +1,22 @@ { "name": "postcss-nesting", - "version": "2.2.0", + "version": "2.3.0", "description": "Transpiles nested rules according to CSS Nesting Module Level 3", "keywords": [ "postcss", "css", "postcss-plugin", + "atrules", + "child", + "children", + "cssnext", + "nested", "nestings", - "selectors", "rules", - "specs", + "selectors", "specifications", - "cssnext" + "specs", + "w3c" ], "author": "Jonathan Neal ", "license": "CC0-1.0", @@ -19,15 +24,16 @@ "bugs": "https://github.com/jonathantneal/postcss-nesting/issues", "homepage": "https://github.com/jonathantneal/postcss-nesting", "dependencies": { - "postcss": "^5.0.14" + "postcss": "^5.0.16" }, "devDependencies": { "eslint": "^1.10.3", + "jscs": "^2.10.1", "tap-spec": "^4.1.1", "tape": "^4.4.0" }, "scripts": { - "lint": "eslint . --ignore-path .gitignore", + "lint": "eslint *.js --ignore-path .gitignore && jscs *.js", "tape": "tape test.js | tap-spec", "test": "npm run lint && npm run tape" }, @@ -35,4 +41,4 @@ "iojs": ">=2.0.0", "node": ">=0.12.0" } -} \ No newline at end of file +} diff --git a/test/media.css b/test/media.css index 6e8af9b0bc..39cf0523aa 100644 --- a/test/media.css +++ b/test/media.css @@ -15,3 +15,11 @@ } } } + +.main { + @media screen, print and speech { + @media (max-width: 300px), (min-aspect-ratio: 16/9) { + color: black; + } + } +} diff --git a/test/media.expect.css b/test/media.expect.css index c59823b8e7..05858b3cf1 100644 --- a/test/media.expect.css +++ b/test/media.expect.css @@ -8,7 +8,8 @@ color: white } - .main .child {} + .main .child { +} } @media (min-width: 100px) and (max-width: 200px) { @@ -24,3 +25,19 @@ color: green } } + +.main { +} + +@media screen, print and speech { + + .main { +} + } + +@media screen and (max-width: 300px), screen and (min-aspect-ratio: 16/9), print and speech and (max-width: 300px), print and speech and (min-aspect-ratio: 16/9) { + + .main { + color: black + } +} From fc78f491ee760b8f3b03bf7fc233d0e7be2c0090 Mon Sep 17 00:00:00 2001 From: Aleks Hudochenkov Date: Sat, 27 Feb 2016 17:36:46 +0300 Subject: [PATCH 367/795] Fix incorrect output when using both > and >= (or similar) #12 --- index.js | 24 +++++++++++++++++++----- test/fixtures/shorthands.css | 11 +++++++++++ test/fixtures/shorthands.output.css | 11 +++++++++++ test/index.js | 1 + 4 files changed, 42 insertions(+), 5 deletions(-) create mode 100644 test/fixtures/shorthands.css create mode 100644 test/fixtures/shorthands.output.css diff --git a/index.js b/index.js index f03f38c067..666f7ff514 100644 --- a/index.js +++ b/index.js @@ -80,9 +80,11 @@ module.exports = postcss.plugin('postcss-media-minmax', function () { }) /** - * 转换 <|>= <|>= - * $1 $2 $3 $4$5 $5 + * 转换 <|<= <|<= + * 转换 >|>= >|>= + * $1 $2$3 $4 $5$6 $7 * (500px <= width <= 1200px) => (min-width: 500px) and (max-width: 1200px) + * (500px < width <= 1200px) => (min-width: 501px) and (max-width: 1200px) * (900px >= width >= 300px) => (min-width: 300px) and (max-width: 900px) */ @@ -90,10 +92,22 @@ module.exports = postcss.plugin('postcss-media-minmax', function () { if (feature_name.indexOf($4) > -1) { if ($2 === '<' && $5 === '<' || $2 === '>' && $5 === '>') { - var min = ($2 === '<') ? $1 : $7; - var max = ($2 === '<') ? $7 : $1; + var min = ($2 === '<') ? $1 : $7; + var max = ($2 === '<') ? $7 : $1; + + // output differently depended on expression direction + // <|<= <|<= + // or + // >|>= >|>= + var equals_for_min = $3; + var equals_for_max = $6; + + if ($2 === '>') { + equals_for_min = $6; + equals_for_max = $3; + } - return create_query($4, '>', $3, min) + ' and ' + create_query($4, '<', $6, max); + return create_query($4, '>', equals_for_min, min) + ' and ' + create_query($4, '<', equals_for_max, max); } } //如果不是指定的属性,不做替换 diff --git a/test/fixtures/shorthands.css b/test/fixtures/shorthands.css new file mode 100644 index 0000000000..4212ca8b67 --- /dev/null +++ b/test/fixtures/shorthands.css @@ -0,0 +1,11 @@ +@media (1024px > width >= 768px) {} +@media (768px <= width < 1024px) {} + +@media (1024px >= width > 768px) {} +@media (768px < width <= 1024px) {} + +@media (1024px >= width >= 768px) {} +@media (768px <= width <= 1024px) {} + +@media (1024px > width > 768px) {} +@media (768px < width < 1024px) {} diff --git a/test/fixtures/shorthands.output.css b/test/fixtures/shorthands.output.css new file mode 100644 index 0000000000..dbc2542743 --- /dev/null +++ b/test/fixtures/shorthands.output.css @@ -0,0 +1,11 @@ +@media (min-width: 768px) and (max-width: 1023px) {} +@media (min-width: 768px) and (max-width: 1023px) {} + +@media (min-width: 769px) and (max-width: 1024px) {} +@media (min-width: 769px) and (max-width: 1024px) {} + +@media (min-width: 768px) and (max-width: 1024px) {} +@media (min-width: 768px) and (max-width: 1024px) {} + +@media (min-width: 769px) and (max-width: 1023px) {} +@media (min-width: 769px) and (max-width: 1023px) {} diff --git a/test/index.js b/test/index.js index 91b204ae42..b0ef75e111 100644 --- a/test/index.js +++ b/test/index.js @@ -34,6 +34,7 @@ test("@media", function(t) { compareFixtures(t, "more-units", "should transform") compareFixtures(t, "min-max", "should transform") + compareFixtures(t, "shorthands", "should transform shorthands") t.end() }) From 36bf8a1ff3833bde08dad2c3402a45168063e83b Mon Sep 17 00:00:00 2001 From: Jonathan Neal Date: Wed, 16 Mar 2016 15:20:16 -0400 Subject: [PATCH 368/795] 2.3.1 --- .eslintrc | 39 +++++++++++++++---------------------- .gitignore | 2 +- .npmignore | 2 +- CHANGELOG.md | 8 ++++++++ index.js | 2 +- package.json | 10 +++++----- test/direct.css | 42 ++++++++++++++++++++-------------------- test/direct.expect.css | 44 +++++++++++++++++++++--------------------- 8 files changed, 75 insertions(+), 74 deletions(-) diff --git a/.eslintrc b/.eslintrc index 33ed8c1f4f..ee0ecdd672 100644 --- a/.eslintrc +++ b/.eslintrc @@ -1,5 +1,8 @@ { + "root": true, "env": { + "browser": true, + "es6": true, "node": true }, "rules": { @@ -12,27 +15,26 @@ "constructor-super": [2], "default-case": [2], "eqeqeq": [2], - "func-style": [0], "global-require": [2], "guard-for-in": [0], "handle-callback-err": [2, "^err(or)?$"], "id-length": [0], - "id-match": [0], - "init-declarations": [0], + "init-declarations": [2, "always"], "max-depth": [2, 6], "max-nested-callbacks": [0], "max-params": [2, 3], "max-statements": [0], - "new-parens": [0], + "new-cap": [2], + "new-parens": [2], "no-alert": [2], - "no-array-constructor": [0], + "no-array-constructor": [2], "no-bitwise": [0], "no-caller": [2], "no-case-declarations": [2], "no-catch-shadow": [2], "no-class-assign": [2], "no-cond-assign": [2], - "no-console": [0], + "no-console": [2], "no-const-assign": [2], "no-constant-condition": [0], "no-continue": [0], @@ -46,7 +48,6 @@ "no-duplicate-case": [2], "no-else-return": [0], "no-empty-character-class": [2], - "no-empty-label": [2], "no-empty-pattern": [2], "no-empty": [2], "no-eq-null": [2], @@ -80,7 +81,7 @@ "no-native-reassign": [2], "no-negated-condition": [0], "no-negated-in-lhs": [2], - "no-nested-ternary": [0], + "no-nested-ternary": [2], "no-new-func": [0], "no-new-object": [2], "no-new-require": [0], @@ -89,18 +90,18 @@ "no-obj-calls": [2], "no-octal-escape": [2], "no-octal": [2], - "no-param-reassign": [2], + "no-param-reassign": [0], "no-path-concat": [2], "no-plusplus": [0], "no-process-env": [2], "no-process-exit": [0], "no-proto": [2], "no-redeclare": [2], - "no-regex-spaces": [0], + "no-regex-spaces": [2], "no-restricted-imports": [0], "no-restricted-syntax": [0], "no-return-assign": [2], - "no-script-url": [0], + "no-script-url": [2], "no-self-compare": [2], "no-sequences": [2], "no-shadow-restricted-names": [2], @@ -110,7 +111,7 @@ "no-ternary": [0], "no-this-before-super": [2], "no-throw-literal": [2], - "no-undef-init": [0], + "no-undef-init": [2], "no-undef": [2], "no-undefined": [0], "no-unneeded-ternary": [2], @@ -132,22 +133,14 @@ "prefer-rest-params": [0], "prefer-spread": [0], "prefer-template": [0], - "quotes": [0], "radix": [2, "as-needed"], "require-yield": [0], - "sort-imports": [0], - "sort-vars": [0], "strict": [0], "use-isnan": [2], "valid-typeof": [2], "vars-on-top": [0], - "wrap-iife": [2, "inside"], - "wrap-regex": [0], - "yoda": [0], - - "camelcase": [0], - "key-spacing": [0], - "quote-props": [0], - "spaced-comment": [0] + "wrap-iife": [2, "any"], + "wrap-regex": [2], + "yoda": [0] } } diff --git a/.gitignore b/.gitignore index ca9ef401c6..ef0a70e834 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,3 @@ -node_modules/ +node_modules npm-debug.log test/*.actual.css diff --git a/.npmignore b/.npmignore index 1ca957177f..93f1361991 100644 --- a/.npmignore +++ b/.npmignore @@ -1,2 +1,2 @@ -node_modules/ +node_modules npm-debug.log diff --git a/CHANGELOG.md b/CHANGELOG.md index 6cefb3f861..438eca3a59 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,11 @@ +## 2.3.1 (2016-03-16) + +- Updated: Allow any direct nesting that follows the syntactic constraints +- Updated: PostCSS 5.0.6 +- Updated: Tests +- Updated: Dependencies +- Updated: Project configuration + ## 2.3.0 (2016-02-20) - Updated: JavaScript formatting, linting, tests, and documentation diff --git a/index.js b/index.js index 12b0b5544a..eef9b5af80 100644 --- a/index.js +++ b/index.js @@ -27,7 +27,7 @@ module.exports = postcss.plugin('postcss-nesting', function (opts) { }); if (isRule && target.selectors.every(function (selector) { - return selector.lastIndexOf('&') === 0; + return selector.indexOf('&') === 0; })) { target.remove(); diff --git a/package.json b/package.json index 014ba86aa6..d9287394db 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "postcss-nesting", - "version": "2.3.0", + "version": "2.3.1", "description": "Transpiles nested rules according to CSS Nesting Module Level 3", "keywords": [ "postcss", @@ -24,13 +24,13 @@ "bugs": "https://github.com/jonathantneal/postcss-nesting/issues", "homepage": "https://github.com/jonathantneal/postcss-nesting", "dependencies": { - "postcss": "^5.0.16" + "postcss": "^5.0.19" }, "devDependencies": { - "eslint": "^1.10.3", - "jscs": "^2.10.1", + "eslint": "^2.4.0", + "jscs": "^2.11.0", "tap-spec": "^4.1.1", - "tape": "^4.4.0" + "tape": "^4.5.1" }, "scripts": { "lint": "eslint *.js --ignore-path .gitignore && jscs *.js", diff --git a/test/direct.css b/test/direct.css index b59eea380c..2591c0ba89 100644 --- a/test/direct.css +++ b/test/direct.css @@ -1,87 +1,87 @@ a, b { - color: white; + color: blue; & c, & d { - color: blue + color: blue; } } a, b { - color: white; + color: blue; & c, & d { color: blue; & e, & f { - color: black + color: blue; } } } a, b { - color: red; + color: blue; & & { - color: white; + color: blue; } c & { - color: blue; + color: red; } & c, c & { - color: black; + color: red; } } a { - color: red; + color: blue; @media { - color: white + color: blue; } } a { - color: red; + color: blue; & b { - color: white; + color: blue; @media { - color: blue + color: blue; } } @media { - color: black; + color: blue; & c { - color: yellow + color: blue; } } } a { - color: red; + color: blue; @unknown test { - color: white + color: red; } } b { - color: white; + color: blue; @phone { - color: blue + color: red; } @media { - color: black; + color: blue; & c { - color: yellow + color: blue; } } } diff --git a/test/direct.expect.css b/test/direct.expect.css index 4bd6a506b1..2054a81780 100644 --- a/test/direct.expect.css +++ b/test/direct.expect.css @@ -1,5 +1,5 @@ a, b { - color: white + color: blue } a c, a d, b c, b d { @@ -7,7 +7,7 @@ a c, a d, b c, b d { } a, b { - color: white + color: blue } a c, a d, b c, b d { @@ -15,42 +15,42 @@ a c, a d, b c, b d { } a c e, a c f, a d e, a d f, b c e, b c f, b d e, b d f { - color: black + color: blue } a, b { - color: red; - - & & { - color: white; - } + color: blue; c & { - color: blue; + color: red; } & c, c & { - color: black; + color: red; } } +a a, b b { + color: blue +} + a { - color: red + color: blue } @media { a { - color: white + color: blue } } a { - color: red + color: blue } a b { - color: white + color: blue } @media { @@ -63,37 +63,37 @@ a b { @media { a { - color: black + color: blue } a c { - color: yellow + color: blue } } a { - color: red; + color: blue; @unknown test { - color: white + color: red; } } b { - color: white; + color: blue; @phone { - color: blue + color: red; } } @media { b { - color: black + color: blue } b c { - color: yellow + color: blue } } From a692a5c426c1cf85b01efb193621cf140694f3c5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=B8=80=E4=B8=9D?= Date: Fri, 1 Apr 2016 11:06:16 +0800 Subject: [PATCH 369/795] Format --- test/fixtures/aspect-ratio.css | 2 +- test/fixtures/color-index.css | 2 +- test/fixtures/color-index.output.css | 2 +- test/fixtures/color.css | 2 +- test/fixtures/color.output.css | 2 +- test/fixtures/device-aspect-ratio.css | 2 +- test/fixtures/device-aspect-ratio.output.css | 2 +- test/fixtures/device-width-height.css | 2 +- test/fixtures/device-width-height.output.css | 2 +- test/fixtures/line-break.css | 2 +- test/fixtures/line-break.output.css | 4 ++-- test/fixtures/monochrome.css | 2 +- test/fixtures/more-units.css | 2 +- test/fixtures/more-units.output.css | 2 +- test/fixtures/other-name.css | 2 +- test/fixtures/other-name.output.css | 2 +- test/fixtures/resolution.css | 2 +- test/fixtures/resolution.output.css | 2 +- test/fixtures/width-height.css | 2 +- test/fixtures/width-height.output.css | 2 +- 20 files changed, 21 insertions(+), 21 deletions(-) diff --git a/test/fixtures/aspect-ratio.css b/test/fixtures/aspect-ratio.css index 670630303b..5d6c74aa2f 100644 --- a/test/fixtures/aspect-ratio.css +++ b/test/fixtures/aspect-ratio.css @@ -11,4 +11,4 @@ @media screen and (aspect-ratio) and (1 / 1000 <= aspect-ratio <= 16 / 9) { -} \ No newline at end of file +} diff --git a/test/fixtures/color-index.css b/test/fixtures/color-index.css index 5a1712d162..43f5807169 100644 --- a/test/fixtures/color-index.css +++ b/test/fixtures/color-index.css @@ -8,4 +8,4 @@ @media screen and (color-index) and (6 <= color-index <= 256) { -} \ No newline at end of file +} diff --git a/test/fixtures/color-index.output.css b/test/fixtures/color-index.output.css index 35765efe90..86d1f7281a 100644 --- a/test/fixtures/color-index.output.css +++ b/test/fixtures/color-index.output.css @@ -8,4 +8,4 @@ @media screen and (color-index) and (min-color-index: 6) and (max-color-index: 256) { -} \ No newline at end of file +} diff --git a/test/fixtures/color.css b/test/fixtures/color.css index a97cb19e3b..e7a0defa8c 100644 --- a/test/fixtures/color.css +++ b/test/fixtures/color.css @@ -8,4 +8,4 @@ @media screen and (color) and (6 <= color <= 256) { -} \ No newline at end of file +} diff --git a/test/fixtures/color.output.css b/test/fixtures/color.output.css index e185cf7323..65b02f8a33 100644 --- a/test/fixtures/color.output.css +++ b/test/fixtures/color.output.css @@ -8,4 +8,4 @@ @media screen and (color) and (min-color: 6) and (max-color: 256) { -} \ No newline at end of file +} diff --git a/test/fixtures/device-aspect-ratio.css b/test/fixtures/device-aspect-ratio.css index 10c85d73f8..d45ff2d0ca 100644 --- a/test/fixtures/device-aspect-ratio.css +++ b/test/fixtures/device-aspect-ratio.css @@ -11,4 +11,4 @@ @media screen and (device-aspect-ratio) and (1 / 1000 <= device-aspect-ratio <= 16 / 9) { -} \ No newline at end of file +} diff --git a/test/fixtures/device-aspect-ratio.output.css b/test/fixtures/device-aspect-ratio.output.css index 1037c9d10f..40465ef07e 100644 --- a/test/fixtures/device-aspect-ratio.output.css +++ b/test/fixtures/device-aspect-ratio.output.css @@ -11,4 +11,4 @@ @media screen and (device-aspect-ratio) and (min-device-aspect-ratio: 1 / 1000) and (max-device-aspect-ratio: 16 / 9) { -} \ No newline at end of file +} diff --git a/test/fixtures/device-width-height.css b/test/fixtures/device-width-height.css index 45b6b81349..080a7bf433 100644 --- a/test/fixtures/device-width-height.css +++ b/test/fixtures/device-width-height.css @@ -27,4 +27,4 @@ @media screen and (device-height) and (.08px <= device-height <= 0.68px) { -} \ No newline at end of file +} diff --git a/test/fixtures/device-width-height.output.css b/test/fixtures/device-width-height.output.css index c2ef956394..c0209e909c 100644 --- a/test/fixtures/device-width-height.output.css +++ b/test/fixtures/device-width-height.output.css @@ -27,4 +27,4 @@ @media screen and (device-height) and (min-device-height: .08px) and (max-device-height: 0.68px) { -} \ No newline at end of file +} diff --git a/test/fixtures/line-break.css b/test/fixtures/line-break.css index 318ad2a41f..7e1287f1ec 100644 --- a/test/fixtures/line-break.css +++ b/test/fixtures/line-break.css @@ -9,7 +9,7 @@ and } @media screen and - + (1200px <= width <= 500px) and (hover) { diff --git a/test/fixtures/line-break.output.css b/test/fixtures/line-break.output.css index 86ef1e882e..0b64c1b8d7 100644 --- a/test/fixtures/line-break.output.css +++ b/test/fixtures/line-break.output.css @@ -9,11 +9,11 @@ and } @media screen and - + (min-width: 1200px) and (max-width: 500px) and (hover) { .bar { display: block; } -} \ No newline at end of file +} diff --git a/test/fixtures/monochrome.css b/test/fixtures/monochrome.css index 69c50ecdb5..78127a4be4 100644 --- a/test/fixtures/monochrome.css +++ b/test/fixtures/monochrome.css @@ -8,4 +8,4 @@ @media screen and (monochrome) and (1 <= monochrome <= 300) { -} \ No newline at end of file +} diff --git a/test/fixtures/more-units.css b/test/fixtures/more-units.css index 377ff4b5cd..319a4e8efe 100644 --- a/test/fixtures/more-units.css +++ b/test/fixtures/more-units.css @@ -11,4 +11,4 @@ @media screen and (resolution) { } @media screen and (resolution >= 1000dpi) and (resolution <= 3dppx) { } @media screen and (1000000dpi <= resolution <= 1000000dpcm) { } -@media screen and (1 / 1000 <= resolution <= 16 /9) { } \ No newline at end of file +@media screen and (1 / 1000 <= resolution <= 16 /9) { } diff --git a/test/fixtures/more-units.output.css b/test/fixtures/more-units.output.css index 95cc716504..515bc92c1f 100644 --- a/test/fixtures/more-units.output.css +++ b/test/fixtures/more-units.output.css @@ -11,4 +11,4 @@ @media screen and (resolution) { } @media screen and (min-resolution: 1000dpi) and (max-resolution: 3dppx) { } @media screen and (min-resolution: 1000000dpi) and (max-resolution: 1000000dpcm) { } -@media screen and (min-resolution: 1 / 1000) and (max-resolution: 16 /9) { } \ No newline at end of file +@media screen and (min-resolution: 1 / 1000) and (max-resolution: 16 /9) { } diff --git a/test/fixtures/other-name.css b/test/fixtures/other-name.css index 0c6b1158cc..64dd032f9e 100644 --- a/test/fixtures/other-name.css +++ b/test/fixtures/other-name.css @@ -20,4 +20,4 @@ .bar { display: block; } -} \ No newline at end of file +} diff --git a/test/fixtures/other-name.output.css b/test/fixtures/other-name.output.css index 39957656f9..c92af15ff6 100644 --- a/test/fixtures/other-name.output.css +++ b/test/fixtures/other-name.output.css @@ -20,4 +20,4 @@ .bar { display: block; } -} \ No newline at end of file +} diff --git a/test/fixtures/resolution.css b/test/fixtures/resolution.css index e55a7cbba3..adeb338e06 100644 --- a/test/fixtures/resolution.css +++ b/test/fixtures/resolution.css @@ -12,4 +12,4 @@ @media screen and (resolution) and (10dpi <= resolution <= 118dpcm) { -} \ No newline at end of file +} diff --git a/test/fixtures/resolution.output.css b/test/fixtures/resolution.output.css index 5acccc57a5..71e084f59e 100644 --- a/test/fixtures/resolution.output.css +++ b/test/fixtures/resolution.output.css @@ -12,4 +12,4 @@ @media screen and (resolution) and (min-resolution: 10dpi) and (max-resolution: 118dpcm) { -} \ No newline at end of file +} diff --git a/test/fixtures/width-height.css b/test/fixtures/width-height.css index 7ea2b6900c..fe61656c27 100644 --- a/test/fixtures/width-height.css +++ b/test/fixtures/width-height.css @@ -27,4 +27,4 @@ @media screen and (height) and (.08px <= height <= 0.68px) { -} \ No newline at end of file +} diff --git a/test/fixtures/width-height.output.css b/test/fixtures/width-height.output.css index 097e0fb24a..e97de682ae 100644 --- a/test/fixtures/width-height.output.css +++ b/test/fixtures/width-height.output.css @@ -27,4 +27,4 @@ @media screen and (height) and (min-height: .08px) and (max-height: 0.68px) { -} \ No newline at end of file +} From 4def793c6d16180a60dc398f95a92633fd368419 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=B8=80=E4=B8=9D?= Date: Fri, 1 Apr 2016 11:16:06 +0800 Subject: [PATCH 370/795] Update spec url --- README-zh.md | 2 +- README.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/README-zh.md b/README-zh.md index 63689216cf..ab15347d19 100644 --- a/README-zh.md +++ b/README-zh.md @@ -7,7 +7,7 @@ > 写简单优雅的 Media Queries! -Media Queries 中的 `min-width` 和 `max-width` 等属性非常容易混淆,每次看到他们,我都想哭。现在[新的规范](http://dev.w3.org/csswg/mediaqueries/#mq-min-max)中,可以使用更加直观的 `>=`或`<=` 替代 media queries 中的 min-/max- 前缀。 +Media Queries 中的 `min-width` 和 `max-width` 等属性非常容易混淆,每次看到他们,我都想哭。现在[新的规范](https://drafts.csswg.org/mediaqueries/#mq-range-context)中,可以使用更加直观的 `>=`或`<=` 替代 media queries 中的 min-/max- 前缀。 **V2.1.0 开始支持 `>` 或 `<` 符号。** diff --git a/README.md b/README.md index 8683f6b26c..49c109cbfb 100644 --- a/README.md +++ b/README.md @@ -11,7 +11,7 @@ The `min-width`, `max-width` and many other properties of media queries are real V2.1.0 began to support `>` or `<` symbol. -This is a polyfill plugin which supports [CSS Media Queries Level 4](http://dev.w3.org/csswg/mediaqueries/) and gives you access to the new features right away. Mom will never worry about my study any more. So amazing! +This is a polyfill plugin which supports [CSS Media Queries Level 4](https://drafts.csswg.org/mediaqueries/#mq-range-context) and gives you access to the new features right away. Mom will never worry about my study any more. So amazing! [简体中文](README-zh.md) From 247886ff579af04e586bc4932ed6e64b534e48e6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=B8=80=E4=B8=9D?= Date: Fri, 1 Apr 2016 11:24:02 +0800 Subject: [PATCH 371/795] 2.1.2 --- CHANGELOG.md | 4 ++++ package.json | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c67b00508b..3cafbc0f6b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,7 @@ +# 2.1.2 2016-04-01 + +Fix: incorrect output when using both > and >= (or similar).(#12) + # 2.1.1 2015-11-26 Fix: Pixels rounding errors in fractional pixels media queries. diff --git a/package.json b/package.json index fe3f68fbc1..516fcdc067 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "postcss-media-minmax", - "version": "2.1.1", + "version": "2.1.2", "description": "Using more intuitive `>=`, `<=`, `>`, `<` instead of media queries min/max prefix.", "scripts": { "test": "tape test" From 5366045b7ac9d7a16c2b83489b4fbf2d58c522b7 Mon Sep 17 00:00:00 2001 From: Ryan Fitzer Date: Fri, 22 Apr 2016 12:49:13 -0700 Subject: [PATCH 372/795] Fixed: trailing space after custom property name causes duplicate empty property (#43) * Fix issue where trailing space causes duplicate empty property when using `var()`. * Adding test for trailing space. --- index.js | 2 +- test/fixtures/substitution-trailing-space.css | 7 +++++++ test/fixtures/substitution-trailing-space.expected.css | 3 +++ test/index.js | 5 +++++ 4 files changed, 16 insertions(+), 1 deletion(-) create mode 100755 test/fixtures/substitution-trailing-space.css create mode 100755 test/fixtures/substitution-trailing-space.expected.css diff --git a/index.js b/index.js index 598fdfc1f1..7dd8afa225 100755 --- a/index.js +++ b/index.js @@ -12,7 +12,7 @@ var balanced = require("balanced-match") var VAR_PROP_IDENTIFIER = "--" var VAR_FUNC_IDENTIFIER = "var" // matches `name[, fallback]`, captures "name" and "fallback" -var RE_VAR = /([\w-]+)(?:\s*,\s*)?(.*)?/ +var RE_VAR = /([\w-]+)(?:\s*,\s*)?\s*(.*)?/ /** * Resolve CSS variables in a value diff --git a/test/fixtures/substitution-trailing-space.css b/test/fixtures/substitution-trailing-space.css new file mode 100755 index 0000000000..62a577fdcd --- /dev/null +++ b/test/fixtures/substitution-trailing-space.css @@ -0,0 +1,7 @@ +:root { + --test-trailing-space: red; +} + +div { + color: var( --test-trailing-space ); +} diff --git a/test/fixtures/substitution-trailing-space.expected.css b/test/fixtures/substitution-trailing-space.expected.css new file mode 100755 index 0000000000..c4f8827f1f --- /dev/null +++ b/test/fixtures/substitution-trailing-space.expected.css @@ -0,0 +1,3 @@ +div { + color: red; +} \ No newline at end of file diff --git a/test/index.js b/test/index.js index 104ea43074..003919a5b9 100755 --- a/test/index.js +++ b/test/index.js @@ -228,3 +228,8 @@ test("strict option", function(t) { t.end() }) + +test("ignores trailing space after variable", function(t) { + compareFixtures(t, "substitution-trailing-space") + t.end() +}) \ No newline at end of file From 12ad2bf75c40338f629f8b3d47c921ba30a5f98a Mon Sep 17 00:00:00 2001 From: Maxime Thirouin Date: Fri, 22 Apr 2016 21:57:23 +0200 Subject: [PATCH 373/795] 5.0.1 --- CHANGELOG.md | 6 ++++++ package.json | 11 +++++------ 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 57165c4c3f..86c460a4a5 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,9 @@ +# 5.0.1 - 2016-04-22 + +- Fixed: trailing space after custom property name causes duplicate empty + property + ([#43](https://github.com/postcss/postcss-custom-properties/pull/43)) + # 5.0.0 - 2015-08-25 - Removed: compatibility with postcss v4.x diff --git a/package.json b/package.json index 4ccdf2fcbf..6db90bce27 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "postcss-custom-properties", - "version": "5.0.0", + "version": "5.0.1", "description": "PostCSS plugin to polyfill W3C CSS Custom Properties for cascading variables", "keywords": [ "css", @@ -12,10 +12,7 @@ ], "author": "Maxime Thirouin", "license": "MIT", - "repository": { - "type": "git", - "url": "https://github.com/postcss/postcss-custom-properties.git" - }, + "repository": "https://github.com/postcss/postcss-custom-properties.git", "files": [ "index.js" ], @@ -25,9 +22,11 @@ }, "devDependencies": { "eslint": "^1.0.0", + "npmpub": "^3.1.0", "tape": "^4.0.0" }, "scripts": { - "test": "eslint . && tape test" + "test": "eslint . && tape test", + "release": "npmpub" } } From 0e8c8d844d51adc164c296c4456627bd2959e147 Mon Sep 17 00:00:00 2001 From: Texas Toland Date: Wed, 29 Jun 2016 14:37:21 -0600 Subject: [PATCH 374/795] Support postcss-apply (#5) * Add failing test * Pass test Fix #4. See postcss/postcss-selector-parser#28. --- index.js | 7 ++++++- test/test.js | 5 +++++ 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/index.js b/index.js index 99dcc3249d..653f405ecf 100644 --- a/index.js +++ b/index.js @@ -8,6 +8,11 @@ module.exports = postcss.plugin('postcss-pseudo-class-any-link', function (opts) return function (css) { // for each rule css.walkRules(function (rule) { + var rawSelector = rule.raws.selector && rule.raws.selector.raw || rule.selector; + // workaround for https://github.com/postcss/postcss-selector-parser/issues/28#issuecomment-171910556 + if (rawSelector[rawSelector.length - 1] === ':') { + return; + } // update the selector rule.selector = postcssSelectorParser(function (selectors) { // cache variables @@ -45,7 +50,7 @@ module.exports = postcss.plugin('postcss-pseudo-class-any-link', function (opts) } } } - }).process(rule.selector).result; + }).process(rawSelector).result; }); }; }); diff --git a/test/test.js b/test/test.js index a0d1b78585..08070e5f59 100644 --- a/test/test.js +++ b/test/test.js @@ -57,4 +57,9 @@ describe('postcss-pseudo-class-any-link', function () { prefix: 'foo' }, done); }); + + // regression tests + it('--any-link remains --any-link', function (done) { + test('--any-link: { background: blue; }', '--any-link: { background: blue; }', {}, done); + }); }); From 31cf78201cdd40b2c2fe9120ec562836c6385166 Mon Sep 17 00:00:00 2001 From: Ephraim Gregor Date: Fri, 8 Jul 2016 00:28:07 -0400 Subject: [PATCH 375/795] Fixed: existing font-feature-settings being duplicated. (#8) --- index.js | 2 +- test/fixtures/font-variant.css | 4 ++++ test/fixtures/font-variant.expected.css | 4 ++++ 3 files changed, 9 insertions(+), 1 deletion(-) diff --git a/index.js b/index.js index 69563f3e4a..6ff158c1a3 100755 --- a/index.js +++ b/index.js @@ -109,7 +109,7 @@ module.exports = postcss.plugin("postcss-font-variant", function() { if (fontFeatureSettings === null) { fontFeatureSettings = getFontFeatureSettingsPrevTo(decl); } - if (fontFeatureSettings.value) { + if (fontFeatureSettings.value && fontFeatureSettings.value !== newValue) { fontFeatureSettings.value += ", " + newValue; } else { diff --git a/test/fixtures/font-variant.css b/test/fixtures/font-variant.css index efe6dc5f2d..a412aabaaa 100644 --- a/test/fixtures/font-variant.css +++ b/test/fixtures/font-variant.css @@ -5,6 +5,10 @@ selector { selector { font-variant: normal; } +selector { + font-feature-settings: normal; + font-variant: normal; +} selector { font-variant: inherit; } diff --git a/test/fixtures/font-variant.expected.css b/test/fixtures/font-variant.expected.css index 1a0f5a9bce..82e59f740e 100644 --- a/test/fixtures/font-variant.expected.css +++ b/test/fixtures/font-variant.expected.css @@ -7,6 +7,10 @@ selector { font-feature-settings: normal; font-variant: normal; } +selector { + font-feature-settings: normal; + font-variant: normal; +} selector { font-feature-settings: inherit; font-variant: inherit; From fa992b214e898074c065374a15372ad08002e8a8 Mon Sep 17 00:00:00 2001 From: Maxime Thirouin Date: Fri, 8 Jul 2016 06:30:47 +0200 Subject: [PATCH 376/795] 2.0.1 --- CHANGELOG.md | 11 ++++++++--- package.json | 6 ++++-- 2 files changed, 12 insertions(+), 5 deletions(-) mode change 100755 => 100644 package.json diff --git a/CHANGELOG.md b/CHANGELOG.md index edc2c46bce..2c6a4c2b59 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,8 @@ +# 2.0.1 - 2016-07-08 + +- Fixed: existing font-feature-settings being duplicated. + ([#8](https://github.com/postcss/postcss-font-variant/pull/8) - @ChaosExAnima) + # 2.0.0 - 2015-09-08 - Added: compatibility with postcss v5.x @@ -6,12 +11,12 @@ # 1.2.0 - 2015-08-13 - Added: compatibility with postcss v4.1.x -([#5](https://github.com/postcss/postcss-font-variant/pull/5)) + ([#5](https://github.com/postcss/postcss-font-variant/pull/5)) # 1.1.0 - 2015-01-29 -- Fixed: Properly handle font-variant-position:normal ([#3](https://github.com/postcss/postcss-font-variant/pull/3)) -- Added: support font-kerning ([#2](https://github.com/postcss/postcss-font-variant/pull/2)) + - Fixed: Properly handle font-variant-position:normal ([#3](https://github.com/postcss/postcss-font-variant/pull/3)) + - Added: support font-kerning ([#2](https://github.com/postcss/postcss-font-variant/pull/2)) # 1.0.2 - 2015-01-27 diff --git a/package.json b/package.json old mode 100755 new mode 100644 index 7366a01dc8..55f642d6c3 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "postcss-font-variant", - "version": "2.0.0", + "version": "2.0.1", "description": "PostCSS plugin to transform W3C font-variant properties to more compatible CSS (font-feature-settings)", "keywords": [ "css", @@ -25,12 +25,14 @@ "devDependencies": { "jscs": "^2.1.0", "jshint": "^2.8.0", + "npmpub": "^3.1.0", "tape": "^4.0.3" }, "scripts": { "lint": "npm run jscs && npm run jshint", "jscs": "jscs index.js test/index.js", "jshint": "jshint . --exclude-path .gitignore", - "test": "npm run lint && tape test" + "test": "npm run lint && tape test", + "release": "npmpub" } } From 4f4e1a6f180ba97462b2c9f27560a86240fdea6d Mon Sep 17 00:00:00 2001 From: Kenan Yildirim Date: Sat, 23 Jul 2016 20:22:28 -0400 Subject: [PATCH 377/795] update color from v0.7.x to v0.11.x Pull Request URL: https://github.com/postcss/postcss-color-gray/pull/8 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index e1df3112be..48adb01f0d 100644 --- a/package.json +++ b/package.json @@ -39,7 +39,7 @@ "function" ], "dependencies": { - "color": "^0.7.3", + "color": "^0.11.3", "postcss": "^5.0.4", "postcss-message-helpers": "^2.0.0", "reduce-function-call": "^1.0.1" From 9949a6db00ae8907fcae9a2d141ea312dfd827d7 Mon Sep 17 00:00:00 2001 From: Yordis Prieto Date: Tue, 6 Sep 2016 01:36:40 -0400 Subject: [PATCH 378/795] Fixed: .class:matches(element) now produce element.class (#8) * Add node_modules to git ignore * Add log to git ignore * Update packages * Fix eslint keyword spacing changes * Update eslint confi * Fix babel config * Fix class + element matches Related to #7 * Fix Travis config * Fix eslint * Fix consistency * Fix eslint * Fix normalization when there is not selector?!?! * Remove unnecesary code * Fix babel config --- .babelrc | 5 ++++- .eslintrc | 10 +++++----- .gitignore | 2 ++ .travis.yml | 3 +++ package.json | 11 ++++++----- src/replaceRuleSelector.js | 19 ++++++++++++++++++- test/index.js | 6 ++++++ 7 files changed, 44 insertions(+), 12 deletions(-) diff --git a/.babelrc b/.babelrc index b0b9a96ef0..9e3d2741fd 100644 --- a/.babelrc +++ b/.babelrc @@ -1,3 +1,6 @@ { - "stage": 0 + "presets": [ + "es2015", + "stage-2" + ] } diff --git a/.eslintrc b/.eslintrc index db21f05621..2746c02b60 100644 --- a/.eslintrc +++ b/.eslintrc @@ -1,13 +1,13 @@ --- -# babel support more syntax stuff than eslint for now -parser: babel-eslint - root: true extends: eslint:recommended ecmaFeatures: modules: true +parserOptions: + sourceType: module + env: es6: true browser: true @@ -16,7 +16,7 @@ env: rules: indent: [2, 2] # 2 spaces indentation max-len: [2, 80, 4] - quotes: [2, "double"] + quotes: [2, "double", {"allowTemplateLiterals": true}] semi: [2, "never"] no-multiple-empty-lines: [2, {"max": 1}] @@ -35,7 +35,7 @@ rules: computed-property-spacing: [2, "never"] space-unary-ops: [2, {"words": true, "nonwords": false}] - space-after-keywords: [2, "always"] + keyword-spacing: [2, {"before": true, "after": true}] space-before-blocks: [2, "always"] space-before-function-paren: [2, "never"] space-in-parens: [2, "never"] diff --git a/.gitignore b/.gitignore index 1521c8b765..2f7b1b9090 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,3 @@ dist +node_modules +npm-debug.log diff --git a/.travis.yml b/.travis.yml index 31e6113ac4..10e9429ed5 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,2 +1,5 @@ sudo: false language: node_js +node_js: + - "6" + - "4" diff --git a/package.json b/package.json index ef7b502900..ccf29b77c3 100644 --- a/package.json +++ b/package.json @@ -20,14 +20,15 @@ "dist" ], "dependencies": { - "balanced-match": "^0.2.0", + "balanced-match": "^0.4.2", "postcss": "^5.0.0" }, "devDependencies": { - "babel": "^5.5.8", - "babel-eslint": "^3.1.15", - "babel-tape-runner": "^1.1.0", - "eslint": "^1.0.0", + "babel-cli": "^6.14.0", + "babel-preset-es2015": "^6.14.0", + "babel-preset-stage-2": "^6.13.0", + "babel-tape-runner": "^2.0.1", + "eslint": "^3.4.0", "tape": "^4.0.0" }, "scripts": { diff --git a/src/replaceRuleSelector.js b/src/replaceRuleSelector.js index b2fa7250d5..72eec65dad 100644 --- a/src/replaceRuleSelector.js +++ b/src/replaceRuleSelector.js @@ -4,6 +4,21 @@ import balancedMatch from "balanced-match" const pseudoClass = ":matches" +function isElementSelector(selector) { + return !selector.match(/(\:|\.)/g) +} + +function normalizeSelector(selector, preWhitespace, pre) { + const selectorIsElement = isElementSelector(selector) + const preIsElement = isElementSelector(pre) + + if (selectorIsElement && !preIsElement) { + return `${preWhitespace}${selector}${pre}` + } + + return `${preWhitespace}${pre}${selector}` +} + function explodeSelector(selector, options) { if (selector && selector.indexOf(pseudoClass) > -1) { let newSelectors = [] @@ -33,7 +48,9 @@ function explodeSelector(selector, options) { let newParts if (postSelectors.length === 0) { - newParts = bodySelectors.map((s) => preWhitespace + pre + s) + newParts = bodySelectors.map((s) => { + return normalizeSelector(s, preWhitespace, pre) + }) } else { newParts = [] diff --git a/test/index.js b/test/index.js index d5bde5c4b0..82e09182bc 100644 --- a/test/index.js +++ b/test/index.js @@ -136,5 +136,11 @@ article h3 + p {}`, "should works correctly with adjacent selectors and line break" ) + t.equal( + transform(`.foo:matches(p) {color: red;}`), + `p.foo {color: red;}`, + "should works correctly with a class and an element" + ) + t.end() }) From 8a902dc6b63244409b6c9dc3efe2c09f32a52f81 Mon Sep 17 00:00:00 2001 From: Maxime Thirouin Date: Tue, 6 Sep 2016 07:58:12 +0200 Subject: [PATCH 379/795] 2.0.2 --- CHANGELOG.md | 6 ++++++ package.json | 11 +++++------ 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index cf0e364cde..a83fcb49bc 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,10 @@ +# 2.0.2 - 2016-09-06 + +- Fixed: .class:matches(element) now produce element.class + ([#8](https://github.com/postcss/postcss-selector-matches/pull/8) - @yordis) + # 2.0.1 - 2015-10-26 + - Fixed: pseudo selectors with multiple matches in a selector # 2.0.0 - 2015-08-25 diff --git a/package.json b/package.json index ccf29b77c3..ba45731a6c 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "postcss-selector-matches", - "version": "2.0.1", + "version": "2.0.2", "description": "PostCSS plugin to transform :matches() W3C CSS pseudo class to more compatible CSS selectors", "keywords": [ "postcss", @@ -11,10 +11,7 @@ ], "author": "Maxime Thirouin", "license": "MIT", - "repository": { - "type": "git", - "url": "https://github.com/postcss/postcss-selector-matches.git" - }, + "repository": "https://github.com/postcss/postcss-selector-matches.git", "main": "dist/index.js", "files": [ "dist" @@ -29,12 +26,14 @@ "babel-preset-stage-2": "^6.13.0", "babel-tape-runner": "^2.0.1", "eslint": "^3.4.0", + "npmpub": "^3.1.0", "tape": "^4.0.0" }, "scripts": { "lint": "eslint .", "tape": "babel-tape-runner 'test/*.js'", "test": "npm run lint && npm run tape", - "prepublish": "babel src --out-dir dist" + "prepublish": "babel src --out-dir dist", + "release": "npmpub" } } From d6ce44b7091884f831f5b56ddc42c2b30aa35c3d Mon Sep 17 00:00:00 2001 From: Maxime Thirouin Date: Tue, 6 Sep 2016 09:07:34 +0200 Subject: [PATCH 380/795] 2.0.3 --- CHANGELOG.md | 5 +++++ package.json | 2 +- src/index.js | 2 +- 3 files changed, 7 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a83fcb49bc..773287c794 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,8 @@ +# 2.0.3 - 2016-09-06 + +- Fixed: regression of 2.0.2 due to a transpilation upgrade + (@MoOx) + # 2.0.2 - 2016-09-06 - Fixed: .class:matches(element) now produce element.class diff --git a/package.json b/package.json index ba45731a6c..11457c8074 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "postcss-selector-matches", - "version": "2.0.2", + "version": "2.0.3", "description": "PostCSS plugin to transform :matches() W3C CSS pseudo class to more compatible CSS selectors", "keywords": [ "postcss", diff --git a/src/index.js b/src/index.js index 3d80034745..4aedb708bd 100644 --- a/src/index.js +++ b/src/index.js @@ -12,7 +12,7 @@ function explodeSelectors(options = {}) { } -export default postcss.plugin( +module.exports = postcss.plugin( "postcss-selector-matches", explodeSelectors ) From c719a9571e6a23fa26e05160b9c2cba7b34e6bd4 Mon Sep 17 00:00:00 2001 From: Maxime Thirouin Date: Tue, 6 Sep 2016 23:31:20 +0200 Subject: [PATCH 381/795] Fixed: another regression of 2.0.2 Closes #10 Closes #11 Closes https://github.com/MoOx/postcss-cssnext/issues/315 --- CHANGELOG.md | 3 +++ src/replaceRuleSelector.js | 27 +++++++++++++++++---------- test/index.js | 16 ++++++++++++++-- 3 files changed, 34 insertions(+), 12 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 773287c794..30ed4a9695 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,6 @@ +- Fixed: another regression of 2.0.2 + ([#10](https://github.com/postcss/postcss-selector-matches/pull/10) - @MoOx) + # 2.0.3 - 2016-09-06 - Fixed: regression of 2.0.2 due to a transpilation upgrade diff --git a/src/replaceRuleSelector.js b/src/replaceRuleSelector.js index 72eec65dad..9fb756c7e2 100644 --- a/src/replaceRuleSelector.js +++ b/src/replaceRuleSelector.js @@ -3,20 +3,20 @@ import list from "postcss/lib/list" import balancedMatch from "balanced-match" const pseudoClass = ":matches" +const selectorElementRE = /^[a-zA-Z]/ function isElementSelector(selector) { - return !selector.match(/(\:|\.)/g) + const matches = selectorElementRE.exec(selector) + // console.log({selector, matches}) + return matches } function normalizeSelector(selector, preWhitespace, pre) { - const selectorIsElement = isElementSelector(selector) - const preIsElement = isElementSelector(pre) - - if (selectorIsElement && !preIsElement) { - return `${preWhitespace}${selector}${pre}` + if (isElementSelector(selector) && !isElementSelector(pre)) { + return `${ preWhitespace}${ selector }${ pre }` } - return `${preWhitespace}${pre}${selector}` + return `${ preWhitespace }${ pre }${ selector }` } function explodeSelector(selector, options) { @@ -48,9 +48,16 @@ function explodeSelector(selector, options) { let newParts if (postSelectors.length === 0) { - newParts = bodySelectors.map((s) => { - return normalizeSelector(s, preWhitespace, pre) - }) + // the test below is a poor way to try we are facing a piece of a + // selector... + if (pre.indexOf(" ") > -1) { + newParts = bodySelectors.map((s) => preWhitespace + pre + s) + } + else { + newParts = bodySelectors.map((s) => ( + normalizeSelector(s, preWhitespace, pre) + )) + } } else { newParts = [] diff --git a/test/index.js b/test/index.js index 82e09182bc..e7704ee616 100644 --- a/test/index.js +++ b/test/index.js @@ -137,10 +137,22 @@ article h3 + p {}`, ) t.equal( - transform(`.foo:matches(p) {color: red;}`), - `p.foo {color: red;}`, + transform(".foo:matches(p) {color: red;}"), + "p.foo {color: red;}", "should works correctly with a class and an element" ) + t.equal( + transform(".fo--oo > :matches(h1, h2, h3) {}"), + ".fo--oo > h1, .fo--oo > h2, .fo--oo > h3 {}", + "regression https://github.com/postcss/postcss-selector-matches/issues/10" + ) + + t.equal( + transform(":matches(h4, h5, h6):hover .ba--z {}"), + "h4:hover .ba--z, h5:hover .ba--z, h6:hover .ba--z {}", + "regression https://github.com/postcss/postcss-selector-matches/issues/10" + ) + t.end() }) From d310509324a23038cda9f5cacdfeb72d8202d899 Mon Sep 17 00:00:00 2001 From: Maxime Thirouin Date: Tue, 6 Sep 2016 23:31:26 +0200 Subject: [PATCH 382/795] 2.0.4 --- CHANGELOG.md | 2 ++ package.json | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 30ed4a9695..7e69c748d9 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,5 @@ +# 2.0.4 - 2016-09-06 + - Fixed: another regression of 2.0.2 ([#10](https://github.com/postcss/postcss-selector-matches/pull/10) - @MoOx) diff --git a/package.json b/package.json index 11457c8074..7f8ea66dd4 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "postcss-selector-matches", - "version": "2.0.3", + "version": "2.0.4", "description": "PostCSS plugin to transform :matches() W3C CSS pseudo class to more compatible CSS selectors", "keywords": [ "postcss", From 08594e7f1a2c1ceda477cb86f4c27ba6f0a899b6 Mon Sep 17 00:00:00 2001 From: Ryan Grove Date: Mon, 12 Sep 2016 23:35:48 -0700 Subject: [PATCH 383/795] Fixed: Don't mangle selector parts that don't contain `:matches` (#13) Fixes #10 even harder. --- src/replaceRuleSelector.js | 2 +- test/index.js | 6 ++++++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/src/replaceRuleSelector.js b/src/replaceRuleSelector.js index 9fb756c7e2..118b51e92c 100644 --- a/src/replaceRuleSelector.js +++ b/src/replaceRuleSelector.js @@ -50,7 +50,7 @@ function explodeSelector(selector, options) { if (postSelectors.length === 0) { // the test below is a poor way to try we are facing a piece of a // selector... - if (pre.indexOf(" ") > -1) { + if (position === -1 || pre.indexOf(" ") > -1) { newParts = bodySelectors.map((s) => preWhitespace + pre + s) } else { diff --git a/test/index.js b/test/index.js index e7704ee616..e9f793c4a6 100644 --- a/test/index.js +++ b/test/index.js @@ -154,5 +154,11 @@ article h3 + p {}`, "regression https://github.com/postcss/postcss-selector-matches/issues/10" ) + t.equal( + transform(":matches(a, b).foo, .bar {}"), + "a.foo, b.foo, .bar {}", + "regression https://github.com/postcss/postcss-selector-matches/issues/10" + ) + t.end() }) From 126391f4174c35687489c0247c5e2a1572e67d7d Mon Sep 17 00:00:00 2001 From: Maxime Thirouin Date: Tue, 13 Sep 2016 08:37:07 +0200 Subject: [PATCH 384/795] 2.0.5 --- CHANGELOG.md | 6 ++++++ package.json | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7e69c748d9..4dac5f1246 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,9 @@ +# 2.0.5 - 2016-09-13 + +- Fixed: another regression of 2.0.2 + (don't mangle selector parts that don't contain `:matches`) + ([#13](https://github.com/postcss/postcss-selector-matches/pull/13) - @rgrove) + # 2.0.4 - 2016-09-06 - Fixed: another regression of 2.0.2 diff --git a/package.json b/package.json index 7f8ea66dd4..dc61e38cc2 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "postcss-selector-matches", - "version": "2.0.4", + "version": "2.0.5", "description": "PostCSS plugin to transform :matches() W3C CSS pseudo class to more compatible CSS selectors", "keywords": [ "postcss", From bfe055b02c155c8be5e697cf25923d93dd0b1f14 Mon Sep 17 00:00:00 2001 From: Jonathan Neal Date: Sat, 26 Nov 2016 08:37:56 -0500 Subject: [PATCH 385/795] 1.0.0 --- .gitignore | 3 + .travis.yml | 3 + CHANGELOG.md | 5 ++ CONTRIBUTING.md | 64 ++++++++++++++++++++ LICENSE.md | 106 +++++++++++++++++++++++++++++++++ README.md | 134 ++++++++++++++++++++++++++++++++++++++++++ index.js | 41 +++++++++++++ package.json | 53 +++++++++++++++++ test.js | 81 +++++++++++++++++++++++++ test/basic.css | 23 ++++++++ test/basic.expect.css | 35 +++++++++++ 11 files changed, 548 insertions(+) create mode 100644 .gitignore create mode 100644 .travis.yml create mode 100644 CHANGELOG.md create mode 100644 CONTRIBUTING.md create mode 100644 LICENSE.md create mode 100644 README.md create mode 100644 index.js create mode 100644 package.json create mode 100644 test.js create mode 100644 test/basic.css create mode 100644 test/basic.expect.css diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000000..091413ef02 --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +node_modules +npm-debug.log +test/*.result.css diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000000..833d09d149 --- /dev/null +++ b/.travis.yml @@ -0,0 +1,3 @@ +language: node_js +node_js: + - stable diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000000..29f298b243 --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,5 @@ +# Changes to Place + +### 1.0.0 (November 25, 2016) + +- Initial version diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 0000000000..5e65704b72 --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,64 @@ +# Contributing to Place + +You want to help? You rock! Now, take a moment to be sure your contributions +make sense to everyone else. + +## Reporting Issues + +Found a problem? Want a new feature? + +- See if your issue or idea has [already been reported]. +- Provide a [reduced test case] or a [live example]. + +Remember, a bug is a _demonstrable problem_ caused by _our_ code. + +## Submitting Pull Requests + +Pull requests are the greatest contributions, so be sure they are focused in +scope, and do avoid unrelated commits. + +1. To begin, [fork this project], clone your fork, and add our upstream. + ```bash + # Clone your fork of the repo into the current directory + git clone https://github.com//postcss-place + # Navigate to the newly cloned directory + cd postcss-place + # Assign the original repo to a remote called "upstream" + git remote add upstream https://github.com/jonathantneal/postcss-place + # Install the tools necessary for development + npm install + ``` + +2. Create a branch for your feature or fix: + ```bash + # Move into a new branch for a feature + git checkout -b feature/thing + ``` + ```bash + # Move into a new branch for a fix + git checkout -b fix/something + ``` + +3. Be sure your code follows our practices. + ```bash + # Test current code + npm run test + ``` + +4. Push your branch up to your fork: + ```bash + # Push a feature branch + git push origin feature/thing + ``` + ```bash + # Push a fix branch + git push origin fix/something + ``` + +5. Now [open a pull request] with a clear title and description. + +[already been reported]: issues +[fork this project]: fork +[live example]: http://codepen.io/pen +[open a pull request]: https://help.github.com/articles/using-pull-requests/ +[reduced test case]: https://css-tricks.com/reduced-test-cases/ diff --git a/LICENSE.md b/LICENSE.md new file mode 100644 index 0000000000..34f902f6c4 --- /dev/null +++ b/LICENSE.md @@ -0,0 +1,106 @@ +# CC0 1.0 Universal + +## Statement of Purpose + +The laws of most jurisdictions throughout the world automatically confer +exclusive Copyright and Related Rights (defined below) upon the creator and +subsequent owner(s) (each and all, an “owner”) of an original work of +authorship and/or a database (each, a “Work”). + +Certain owners wish to permanently relinquish those rights to a Work for the +purpose of contributing to a commons of creative, cultural and scientific works +(“Commons”) that the public can reliably and without fear of later claims of +infringement build upon, modify, incorporate in other works, reuse and +redistribute as freely as possible in any form whatsoever and for any purposes, +including without limitation commercial purposes. These owners may contribute +to the Commons to promote the ideal of a free culture and the further +production of creative, cultural and scientific works, or to gain reputation or +greater distribution for their Work in part through the use and efforts of +others. + +For these and/or other purposes and motivations, and without any expectation of +additional consideration or compensation, the person associating CC0 with a +Work (the “Affirmer”), to the extent that he or she is an owner of Copyright +and Related Rights in the Work, voluntarily elects to apply CC0 to the Work and +publicly distribute the Work under its terms, with knowledge of his or her +Copyright and Related Rights in the Work and the meaning and intended legal +effect of CC0 on those rights. + +1. Copyright and Related Rights. A Work made available under CC0 may be + protected by copyright and related or neighboring rights (“Copyright and + Related Rights”). Copyright and Related Rights include, but are not limited + to, the following: + 1. the right to reproduce, adapt, distribute, perform, display, + communicate, and translate a Work; + 2. moral rights retained by the original author(s) and/or performer(s); + 3. publicity and privacy rights pertaining to a person’s image or likeness + depicted in a Work; + 4. rights protecting against unfair competition in regards to a Work, + subject to the limitations in paragraph 4(i), below; + 5. rights protecting the extraction, dissemination, use and reuse of data + in a Work; + 6. database rights (such as those arising under Directive 96/9/EC of the + European Parliament and of the Council of 11 March 1996 on the legal + protection of databases, and under any national implementation thereof, + including any amended or successor version of such directive); and + 7. other similar, equivalent or corresponding rights throughout the world + based on applicable law or treaty, and any national implementations + thereof. + +2. Waiver. To the greatest extent permitted by, but not in contravention of, +applicable law, Affirmer hereby overtly, fully, permanently, irrevocably and +unconditionally waives, abandons, and surrenders all of Affirmer’s Copyright +and Related Rights and associated claims and causes of action, whether now +known or unknown (including existing as well as future claims and causes of +action), in the Work (i) in all territories worldwide, (ii) for the maximum +duration provided by applicable law or treaty (including future time +extensions), (iii) in any current or future medium and for any number of +copies, and (iv) for any purpose whatsoever, including without limitation +commercial, advertising or promotional purposes (the “Waiver”). Affirmer makes +the Waiver for the benefit of each member of the public at large and to the +detriment of Affirmer’s heirs and successors, fully intending that such Waiver +shall not be subject to revocation, rescission, cancellation, termination, or +any other legal or equitable action to disrupt the quiet enjoyment of the Work +by the public as contemplated by Affirmer’s express Statement of Purpose. + +3. Public License Fallback. Should any part of the Waiver for any reason be +judged legally invalid or ineffective under applicable law, then the Waiver +shall be preserved to the maximum extent permitted taking into account +Affirmer’s express Statement of Purpose. In addition, to the extent the Waiver +is so judged Affirmer hereby grants to each affected person a royalty-free, non +transferable, non sublicensable, non exclusive, irrevocable and unconditional +license to exercise Affirmer’s Copyright and Related Rights in the Work (i) in +all territories worldwide, (ii) for the maximum duration provided by applicable +law or treaty (including future time extensions), (iii) in any current or +future medium and for any number of copies, and (iv) for any purpose +whatsoever, including without limitation commercial, advertising or promotional +purposes (the “License”). The License shall be deemed effective as of the date +CC0 was applied by Affirmer to the Work. Should any part of the License for any +reason be judged legally invalid or ineffective under applicable law, such +partial invalidity or ineffectiveness shall not invalidate the remainder of the +License, and in such case Affirmer hereby affirms that he or she will not (i) +exercise any of his or her remaining Copyright and Related Rights in the Work +or (ii) assert any associated claims and causes of action with respect to the +Work, in either case contrary to Affirmer’s express Statement of Purpose. + +4. Limitations and Disclaimers. + 1. No trademark or patent rights held by Affirmer are waived, abandoned, + surrendered, licensed or otherwise affected by this document. + 2. Affirmer offers the Work as-is and makes no representations or + warranties of any kind concerning the Work, express, implied, statutory + or otherwise, including without limitation warranties of title, + merchantability, fitness for a particular purpose, non infringement, or + the absence of latent or other defects, accuracy, or the present or + absence of errors, whether or not discoverable, all to the greatest + extent permissible under applicable law. + 3. Affirmer disclaims responsibility for clearing rights of other persons + that may apply to the Work or any use thereof, including without + limitation any person’s Copyright and Related Rights in the Work. + Further, Affirmer disclaims responsibility for obtaining any necessary + consents, permissions or other rights required for any use of the Work. + 4. Affirmer understands and acknowledges that Creative Commons is not a + party to this document and has no duty or obligation with respect to + this CC0 or use of the Work. + +For more information, please see +http://creativecommons.org/publicdomain/zero/1.0/. diff --git a/README.md b/README.md new file mode 100644 index 0000000000..6ed097b0c9 --- /dev/null +++ b/README.md @@ -0,0 +1,134 @@ +# Place PostCSS Logo + +[![NPM Version][npm-img]][npm-url] +[![Build Status][cli-img]][cli-url] +[![Licensing][lic-image]][lic-url] +[![Changelog][log-image]][log-url] +[![Gitter Chat][git-image]][git-url] + +[Place] lets you use `place-*` properties as shorthands for `align-*` and `justify-*` per the [CSS Box Alignment Module Level 3]. + +```css +/* before */ + +.example { + place-self: center; + place-content: space-between center; +} + +/* after */ + +.example { + align-self: center; + justify-self: center; + align-content: space-between; + justify-content: center; +} +``` + +## Usage + +Add [Place] to your build tool: + +```bash +npm install jonathantneal/postcss-place --save-dev +``` + +#### Node + +```js +require('postcss-place').process(YOUR_CSS, { /* options */ }); +``` + +#### PostCSS + +Add [PostCSS] to your build tool: + +```bash +npm install postcss --save-dev +``` + +Load [Place] as a PostCSS plugin: + +```js +postcss([ + require('postcss-place')({ /* options */ }) +]).process(YOUR_CSS, /* options */); +``` + +#### Gulp + +Add [Gulp PostCSS] to your build tool: + +```bash +npm install gulp-postcss --save-dev +``` + +Enable [Place] within your Gulpfile: + +```js +var postcss = require('gulp-postcss'); + +gulp.task('css', function () { + return gulp.src('./src/*.css').pipe( + postcss([ + require('postcss-place')({ /* options */ }) + ]) + ).pipe( + gulp.dest('.') + ); +}); +``` + +#### Grunt + +Add [Grunt PostCSS] to your build tool: + +```bash +npm install grunt-postcss --save-dev +``` + +Enable [Place] within your Gruntfile: + +```js +grunt.loadNpmTasks('grunt-postcss'); + +grunt.initConfig({ + postcss: { + options: { + use: [ + require('postcss-place')({ /* options */ }) + ] + }, + dist: { + src: '*.css' + } + } +}); +``` + +## Options + +#### `prefix` + +Type: `String` +Default: `null` + +Specifies a prefix to be surrounded by dashes before the declaration (e.g. `prefix: 'x'` changes the detected property to `-x-place-content`). + +[npm-url]: https://www.npmjs.com/package/postcss-place +[npm-img]: https://img.shields.io/npm/v/postcss-place.svg +[cli-url]: https://travis-ci.org/jonathantneal/postcss-place +[cli-img]: https://img.shields.io/travis/jonathantneal/postcss-place.svg +[lic-url]: LICENSE.md +[lic-image]: https://img.shields.io/npm/l/postcss-place.svg +[log-url]: CHANGELOG.md +[log-image]: https://img.shields.io/badge/changelog-md-blue.svg +[git-url]: https://gitter.im/postcss/postcss +[git-image]: https://img.shields.io/badge/chat-gitter-blue.svg + +[Place]: https://github.com/jonathantneal/postcss-place +[CSS Box Alignment Module Level 3]: https://drafts.csswg.org/css-align/#propdef-place-content +[PostCSS]: https://github.com/postcss/postcss +[Gulp PostCSS]: https://github.com/postcss/gulp-postcss +[Grunt PostCSS]: https://github.com/nDmitry/grunt-postcss diff --git a/index.js b/index.js new file mode 100644 index 0000000000..b1cf577945 --- /dev/null +++ b/index.js @@ -0,0 +1,41 @@ +// tooling +const postcss = require('postcss'); +const parser = require('postcss-value-parser'); + +// plugin +module.exports = postcss.plugin('postcss-place', ({ + prefix +} = {}) => (root) => { + // property + const prop = new RegExp(prefix ? '^-' + prefix + '-(content|items|self)' : '^place-(content|items|self)'); + + root.walkDecls(prop, (decl) => { + // alignment + const alignment = decl.prop.match(prop)[1]; + + // value + const value = parser(decl.value); + + // divider position + const index = value.nodes.map( + (node) => node.type + ).indexOf('space'); + + // new justify-[alignment] and align-[alignment] declarations + const alignValue = index === -1 ? decl.value : parser.stringify(value.nodes.slice(0, index)); + const justifyValue = index === -1 ? decl.value : parser.stringify(value.nodes.slice(index + 1)); + + decl.cloneBefore({ + prop: 'align-' + alignment, + value: alignValue + }); + + decl.cloneBefore({ + prop: 'justify-' + alignment, + value: justifyValue + }); + + // remove place-[alignment] + decl.remove(); + }); +}); diff --git a/package.json b/package.json new file mode 100644 index 0000000000..7e7262fa61 --- /dev/null +++ b/package.json @@ -0,0 +1,53 @@ +{ + "name": "postcss-place", + "version": "1.0.0", + "description": "`place-[alignment] shorthand for align-[alignment] and justify-[alignment]", + "author": "Jonathan Neal (http://jonathantneal.com)", + "license": "CC0-1.0", + "repository": "jonathantneal/postcss-place", + "homepage": "https://github.com/jonathantneal/postcss-place#readme", + "bugs": "https://github.com/jonathantneal/postcss-place/issues", + "main": "index.js", + "files": [ + "index.js" + ], + "scripts": { + "lint": "eslint index.js && jscs index.js", + "tape": "node test", + "test": "npm run lint && node test" + }, + "engines": { + "node": ">=6.9.1" + }, + "dependencies": { + "postcss": "^5.2.5", + "postcss-value-parser": "^3.3.0" + }, + "devDependencies": { + "eslint": "^3.10.2", + "eslint-config-10up": "github:jonathantneal/eslint-config-10up", + "jscs": "^3.0.7", + "jscs-config-10up": "github:jonathantneal/jscs-config-10up" + }, + "eslintConfig": { + "extends": "10up", + "parserOptions": { + "sourceType": "module" + } + }, + "jscsConfig": { + "preset": "10up" + }, + "keywords": [ + "postcss", + "css", + "postcss-plugin", + "shorthands", + "alignments", + "justifies", + "justify", + "aligns", + "contents", + "selfs" + ] +} diff --git a/test.js b/test.js new file mode 100644 index 0000000000..5fcb605efd --- /dev/null +++ b/test.js @@ -0,0 +1,81 @@ +// tests +var tests = { + 'postcss-place': { + 'basic': { + message: 'supports basic usage' + } + } +}; + +// tooling +const fs = require('fs'); +const path = require('path'); +const plugin = require('.'); + +// error symbols +const pass = '\x1b[32m\✔\x1b[0m'; +const fail = '\x1b[31m\✖\x1b[0m'; + +// runner +Promise.all(Object.keys(tests).map( + (section) => Promise.all( + Object.keys(tests[section]).map( + (name) => { + const baseName = name.split(':')[0]; + const testName = name.split(':').join('.'); + const warnings = tests[section][name].warning || 0; + + return Promise.all([ + readFile(path.resolve(__dirname, 'test', baseName + '.css'), 'utf8'), + readFile(path.resolve(__dirname, 'test', testName + '.expect.css'), 'utf8') + ]).then( + ([actualCSS, expectCSS]) => plugin.process(actualCSS, tests[section][name].options || {}).then( + (result) => writeFile(path.resolve(__dirname, 'test', testName + '.result.css'), result.css).then( + () => { + if (result.css !== expectCSS) { + throw new Error(` ${ fail } ${ tests[section][name].message }\n${ JSON.stringify({ + expect: expectCSS, + result: result.css + }, null, ' ') }`); + } else if (result.warnings().length !== warnings) { + throw Error(` ${ fail } ${ tests[section][name].message } (${ result.warnings().length } warnings, expected ${ warnings })`); + } else { + return ` ${ pass } ${ tests[section][name].message }`; + } + } + ) + ) + ); + } + ) + ).then( + (messages) => console.log(`${ pass } ${ section }\n${ messages.join('\n') }`) + ).catch( + (error) => { + console.log(`${ fail } ${ section }\n${ error.message }`); + + throw Error; + } + ) +)).then( + () => console.log(`\n${ pass } Test passed`) && process.exit(0), + () => console.log(`\n${ fail } Test failed`) && process.exit(1) +); + +// Promise fs.readFile +function readFile(filename) { + return new Promise( + (resolve, reject) => fs.readFile(filename, 'utf8', + (error, data) => error ? reject(error) : resolve(data) + ) + ); +} + +// Promise fs.writeFile +function writeFile(filename, data) { + return new Promise( + (resolve, reject) => fs.writeFile(filename, data, + (error) => error ? reject(error) : resolve() + ) + ); +} diff --git a/test/basic.css b/test/basic.css new file mode 100644 index 0000000000..a760709662 --- /dev/null +++ b/test/basic.css @@ -0,0 +1,23 @@ +a { + place-content: first second; + place-items: first second; + place-self: first second; +} + +b { + place-content: first; + place-items: first; + place-self: first; +} + +c { + place-content: var(--first) second; + place-items: var(--first) second; + place-self: var(--first) second; +} + +d { + place-content: first var(--second); + place-items: first var(--second); + place-self: first var(--second); +} diff --git a/test/basic.expect.css b/test/basic.expect.css new file mode 100644 index 0000000000..92214f4558 --- /dev/null +++ b/test/basic.expect.css @@ -0,0 +1,35 @@ +a { + align-content: first; + justify-content: second; + align-items: first; + justify-items: second; + align-self: first; + justify-self: second; +} + +b { + align-content: first; + justify-content: first; + align-items: first; + justify-items: first; + align-self: first; + justify-self: first; +} + +c { + align-content: var(--first); + justify-content: second; + align-items: var(--first); + justify-items: second; + align-self: var(--first); + justify-self: second; +} + +d { + align-content: first; + justify-content: var(--second); + align-items: first; + justify-items: var(--second); + align-self: first; + justify-self: var(--second); +} From 88f8f84412eb434f604bfd90d3984bc34d8c89bf Mon Sep 17 00:00:00 2001 From: CS Merritt Date: Sun, 27 Nov 2016 23:38:20 -0600 Subject: [PATCH 386/795] Update README - missing selectors (#25) --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index 8b068d9482..cc10beaf77 100644 --- a/README.md +++ b/README.md @@ -80,7 +80,9 @@ a:hover, b:hover { } @media (min-width: 30em) and (min-device-pixel-ratio: 1.5) { + a, b { color: green; + } } ``` From bdf9f888eb513159d5ec0dd3b3e7328cfdcebdc7 Mon Sep 17 00:00:00 2001 From: wtgtybhertgeghgtwtg Date: Mon, 28 Nov 2016 00:04:11 -0700 Subject: [PATCH 387/795] Bump `color` dependency version. (#7) --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index c3a9bb8809..19ebf1e758 100644 --- a/package.json +++ b/package.json @@ -21,7 +21,7 @@ "index.js" ], "dependencies": { - "color": "^0.9.0", + "color": "^0.11.4", "postcss": "^5.0.4" }, "devDependencies": { From f22f965ea2d2a0e6f1ecc13e68cec60f7b0987b8 Mon Sep 17 00:00:00 2001 From: Maxime Thirouin Date: Mon, 28 Nov 2016 08:08:30 +0100 Subject: [PATCH 388/795] 2.0.1 --- CHANGELOG.md | 5 +++++ package.json | 6 ++++-- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9dffdb1623..3be46c3989 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,8 @@ +# 2.0.1 - 2016-11-28 + +- Bump `color` dependency version +([postcss-cssnext/#327](https://github.com/MoOx/postcss-cssnext/issues/327) - @wtgtybhertgeghgtwtg). + # 2.0.0 - 2015-09-08 - Added: compatibility with postcss v5.x diff --git a/package.json b/package.json index 19ebf1e758..46fe2b3417 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "postcss-color-rebeccapurple", - "version": "2.0.0", + "version": "2.0.1", "description": "PostCSS plugin to transform W3C CSS rebeccapurple color to more compatible CSS (rgb())", "keywords": [ "css", @@ -27,12 +27,14 @@ "devDependencies": { "jscs": "^1.6.2", "jshint": "^2.5.6", + "npmpub": "^3.1.0", "tape": "^4.0.0" }, "scripts": { "lint": "npm run jscs && npm run jshint", "jscs": "jscs index.js test/index.js", "jshint": "jshint . --exclude-path .gitignore", - "test": "npm run lint && tape test" + "test": "npm run lint && tape test", + "release": "npmpub" } } From 851e41f3b4f82a6875f8c96c7c9626ab6dd99098 Mon Sep 17 00:00:00 2001 From: wtgtybhertgeghgtwtg Date: Mon, 28 Nov 2016 00:10:16 -0700 Subject: [PATCH 389/795] Bump `color` dependency version. (#7) --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 52761b2976..2c179123ac 100644 --- a/package.json +++ b/package.json @@ -21,7 +21,7 @@ "index.js" ], "dependencies": { - "color": "^0.10.1", + "color": "^0.11.4", "postcss": "^5.0.4", "postcss-message-helpers": "^2.0.0", "reduce-function-call": "^1.0.1" From baa608ed45dc8bb0262dd91e98a7bf792e319bf6 Mon Sep 17 00:00:00 2001 From: Maxime Thirouin Date: Mon, 28 Nov 2016 08:14:43 +0100 Subject: [PATCH 390/795] 2.0.1 --- CHANGELOG.md | 5 +++++ package.json | 6 ++++-- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index aa3efff052..b2fca9a982 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,8 @@ +# 2.0.1 - 2016-11-28 + +- Bump `color` dependency version +([postcss-cssnext/#327](https://github.com/MoOx/postcss-cssnext/issues/327) - @wtgtybhertgeghgtwtg) + # 2.0.0 - 2015-09-08 - Added: compatibility with postcss v5.x diff --git a/package.json b/package.json index 2c179123ac..d13ff02388 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "postcss-color-hwb", - "version": "2.0.0", + "version": "2.0.1", "description": "PostCSS plugin to transform W3C CSS hwb() color to more compatible CSS (rgb() (or rgba()))", "keywords": [ "css", @@ -29,12 +29,14 @@ "devDependencies": { "jscs": "^2.1.0", "jshint": "^2.8.0", + "npmpub": "^3.1.0", "tape": "^4.0.3" }, "scripts": { "lint": "npm run jscs && npm run jshint", "jscs": "jscs index.js test/index.js", "jshint": "jshint . --exclude-path .gitignore", - "test": "npm run lint && tape test" + "test": "npm run lint && tape test", + "release": "npmpub" } } From f5d57345499861f24f5a54e773b6eb102d58edb7 Mon Sep 17 00:00:00 2001 From: Maxime Thirouin Date: Mon, 28 Nov 2016 08:33:03 +0100 Subject: [PATCH 391/795] 3.0.1 --- CHANGELOG.md | 5 +++++ package.json | 11 +++++------ 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7f5ba18221..c807312c78 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,8 @@ +# 3.0.1 - 2016-11-28 + +- Bump `color` dependency version +(@KenanY) + # 3.0.0 - 2015-09-08 - Added: compatibility with postcss v5.x diff --git a/package.json b/package.json index 48adb01f0d..69e7f8a407 100644 --- a/package.json +++ b/package.json @@ -1,11 +1,8 @@ { "name": "postcss-color-gray", - "version": "3.0.0", + "version": "3.0.1", "description": "PostCSS plugin to transform gray() function to today's CSS", - "repository": { - "type": "git", - "url": "https://github.com/postcss/postcss-color-gray.git" - }, + "repository": "https://github.com/postcss/postcss-color-gray.git", "author": { "name": "Shinnosuke Watanabe", "url": "https://github.com/shinnn" @@ -16,7 +13,8 @@ "jscs": "jscs index.js test.js", "test": "node test.js | tap-spec", "coverage": "istanbul cover test.js", - "coveralls": "${npm_package_scripts_coverage} && istanbul-coveralls" + "coveralls": "${npm_package_scripts_coverage} && istanbul-coveralls", + "release": "npmpub" }, "licenses": [ { @@ -49,6 +47,7 @@ "istanbul": "^0.3.5", "istanbul-coveralls": "^1.0.1", "jscs": "^1.8.1", + "npmpub": "^3.1.0", "tap-spec": "^2.1.0", "tape": "^3.0.3" } From 005682de7e15f42d3f706040cbae7f469a4fe0e9 Mon Sep 17 00:00:00 2001 From: Jonathan Neal Date: Tue, 6 Dec 2016 14:08:53 -0500 Subject: [PATCH 392/795] 1.0.1 - Updated: boilerplate conventions (`postcss-tape`) --- .tape.js | 7 +++++ CHANGELOG.md | 4 +++ README.md | 18 ++++++------ package.json | 27 +++++++++++------- test.js | 81 ---------------------------------------------------- 5 files changed, 37 insertions(+), 100 deletions(-) create mode 100644 .tape.js delete mode 100644 test.js diff --git a/.tape.js b/.tape.js new file mode 100644 index 0000000000..44e3eb54e0 --- /dev/null +++ b/.tape.js @@ -0,0 +1,7 @@ +module.exports = { + 'postcss-place': { + 'basic': { + message: 'supports basic usage' + } + } +}; diff --git a/CHANGELOG.md b/CHANGELOG.md index 29f298b243..071bbeb147 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # Changes to Place +### 1.0.1 (December 6, 2016) + +- Updated: boilerplate conventions (`postcss-tape`) + ### 1.0.0 (November 25, 2016) - Initial version diff --git a/README.md b/README.md index 6ed097b0c9..191d189872 100644 --- a/README.md +++ b/README.md @@ -26,6 +26,15 @@ } ``` +## Options + +#### `prefix` + +Type: `String` +Default: `null` + +Specifies a prefix to be surrounded by dashes before the declaration (e.g. `prefix: 'x'` changes the detected property to `-x-place-content`). + ## Usage Add [Place] to your build tool: @@ -107,15 +116,6 @@ grunt.initConfig({ }); ``` -## Options - -#### `prefix` - -Type: `String` -Default: `null` - -Specifies a prefix to be surrounded by dashes before the declaration (e.g. `prefix: 'x'` changes the detected property to `-x-place-content`). - [npm-url]: https://www.npmjs.com/package/postcss-place [npm-img]: https://img.shields.io/npm/v/postcss-place.svg [cli-url]: https://travis-ci.org/jonathantneal/postcss-place diff --git a/package.json b/package.json index 7e7262fa61..13113b2049 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "postcss-place", - "version": "1.0.0", + "version": "1.0.1", "description": "`place-[alignment] shorthand for align-[alignment] and justify-[alignment]", "author": "Jonathan Neal (http://jonathantneal.com)", "license": "CC0-1.0", @@ -12,31 +12,38 @@ "index.js" ], "scripts": { - "lint": "eslint index.js && jscs index.js", - "tape": "node test", - "test": "npm run lint && node test" + "lint": "echint && eslint index.js && jscs index.js", + "prepublish": "npm test", + "tape": "postcss-tape", + "test": "npm run lint && postcss-tape" }, "engines": { "node": ">=6.9.1" }, "dependencies": { - "postcss": "^5.2.5", + "postcss": "^5.2.6", "postcss-value-parser": "^3.3.0" }, "devDependencies": { - "eslint": "^3.10.2", - "eslint-config-10up": "github:jonathantneal/eslint-config-10up", + "echint": "^2.1.0", + "echint-config-dev": "1.0.0", + "eslint": "^3.11.1", + "eslint-config-dev": "1.0.0", "jscs": "^3.0.7", - "jscs-config-10up": "github:jonathantneal/jscs-config-10up" + "jscs-config-dev": "1.0.1", + "postcss-tape": "1.0.1" + }, + "echint": { + "extends": "dev" }, "eslintConfig": { - "extends": "10up", + "extends": "dev", "parserOptions": { "sourceType": "module" } }, "jscsConfig": { - "preset": "10up" + "preset": "dev" }, "keywords": [ "postcss", diff --git a/test.js b/test.js deleted file mode 100644 index 5fcb605efd..0000000000 --- a/test.js +++ /dev/null @@ -1,81 +0,0 @@ -// tests -var tests = { - 'postcss-place': { - 'basic': { - message: 'supports basic usage' - } - } -}; - -// tooling -const fs = require('fs'); -const path = require('path'); -const plugin = require('.'); - -// error symbols -const pass = '\x1b[32m\✔\x1b[0m'; -const fail = '\x1b[31m\✖\x1b[0m'; - -// runner -Promise.all(Object.keys(tests).map( - (section) => Promise.all( - Object.keys(tests[section]).map( - (name) => { - const baseName = name.split(':')[0]; - const testName = name.split(':').join('.'); - const warnings = tests[section][name].warning || 0; - - return Promise.all([ - readFile(path.resolve(__dirname, 'test', baseName + '.css'), 'utf8'), - readFile(path.resolve(__dirname, 'test', testName + '.expect.css'), 'utf8') - ]).then( - ([actualCSS, expectCSS]) => plugin.process(actualCSS, tests[section][name].options || {}).then( - (result) => writeFile(path.resolve(__dirname, 'test', testName + '.result.css'), result.css).then( - () => { - if (result.css !== expectCSS) { - throw new Error(` ${ fail } ${ tests[section][name].message }\n${ JSON.stringify({ - expect: expectCSS, - result: result.css - }, null, ' ') }`); - } else if (result.warnings().length !== warnings) { - throw Error(` ${ fail } ${ tests[section][name].message } (${ result.warnings().length } warnings, expected ${ warnings })`); - } else { - return ` ${ pass } ${ tests[section][name].message }`; - } - } - ) - ) - ); - } - ) - ).then( - (messages) => console.log(`${ pass } ${ section }\n${ messages.join('\n') }`) - ).catch( - (error) => { - console.log(`${ fail } ${ section }\n${ error.message }`); - - throw Error; - } - ) -)).then( - () => console.log(`\n${ pass } Test passed`) && process.exit(0), - () => console.log(`\n${ fail } Test failed`) && process.exit(1) -); - -// Promise fs.readFile -function readFile(filename) { - return new Promise( - (resolve, reject) => fs.readFile(filename, 'utf8', - (error, data) => error ? reject(error) : resolve(data) - ) - ); -} - -// Promise fs.writeFile -function writeFile(filename, data) { - return new Promise( - (resolve, reject) => fs.writeFile(filename, data, - (error) => error ? reject(error) : resolve() - ) - ); -} From 3b8eaa5783d68b1e8032a1e51c7d59727de34cc8 Mon Sep 17 00:00:00 2001 From: Jonathan Neal Date: Tue, 6 Dec 2016 14:08:53 -0500 Subject: [PATCH 393/795] 3.0.0 --- .eslintrc | 123 -------------------------------- .gitignore | 3 +- .npmignore | 8 --- .tape.js | 22 ++++++ .travis.yml | 4 +- CHANGELOG.md | 16 +++-- CONTRIBUTING.md | 64 +++++++++++++++++ LICENSE.md | 107 ++++++++++++++++++++++++--- README.md | 115 ++++++++++++++++++++--------- gulpfile.js | 18 ----- index.js | 44 +++++++----- package.json | 85 +++++++++++++++------- test/basic.css | 12 ++++ test/basic.expect.css | 13 ++++ test/basic.w-prefix.expect.css | 12 ++++ test/prefix.css | 12 ++++ test/prefix.expect.css | 12 ++++ test/prefix.w-prefix.expect.css | 13 ++++ test/test.js | 65 ----------------- 19 files changed, 442 insertions(+), 306 deletions(-) delete mode 100644 .eslintrc delete mode 100644 .npmignore create mode 100644 .tape.js create mode 100644 CONTRIBUTING.md delete mode 100644 gulpfile.js create mode 100644 test/basic.css create mode 100644 test/basic.expect.css create mode 100644 test/basic.w-prefix.expect.css create mode 100644 test/prefix.css create mode 100644 test/prefix.expect.css create mode 100644 test/prefix.w-prefix.expect.css delete mode 100644 test/test.js diff --git a/.eslintrc b/.eslintrc deleted file mode 100644 index 8e89382520..0000000000 --- a/.eslintrc +++ /dev/null @@ -1,123 +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-use-before-define": [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": [2], - "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": [2], - "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": [2, "as-needed"], - "no-iterator": [2], - "no-new-func": [2], - "key-spacing": [2, { "align": "value" }], - "complexity": [2], - "new-parens": [2], - "no-eq-null": [2], - "no-bitwise": [2], - "wrap-iife": [2], - "no-caller": [2], - "use-isnan": [2], - "no-labels": [2], - "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/.gitignore b/.gitignore index 1ca957177f..091413ef02 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ -node_modules/ +node_modules npm-debug.log +test/*.result.css diff --git a/.npmignore b/.npmignore deleted file mode 100644 index 1aa2d59e25..0000000000 --- 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 0000000000..a3959eed6c --- /dev/null +++ b/.tape.js @@ -0,0 +1,22 @@ +module.exports = { + 'postcss-pseudo-class-any-link': { + 'basic': { + message: 'supports basic usage' + }, + 'basic:w-prefix': { + message: 'ignores basic usage when { prefix: "x" }', + options: { + prefix: 'x' + } + }, + 'prefix': { + message: 'supports prefix usage' + }, + 'prefix:w-prefix': { + message: 'supports prefix usage when { prefix: "x" }', + options: { + prefix: 'x' + } + } + } +}; diff --git a/.travis.yml b/.travis.yml index e1bd776499..833d09d149 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,5 +1,3 @@ -sudo: false language: node_js node_js: - - iojs - - "0.12" + - stable diff --git a/CHANGELOG.md b/CHANGELOG.md index d7e43b69c0..cff52aa2b2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,23 +1,29 @@ -## 1.0.0 (2015-09-01) +# Changes to :any-link + +### 3.0.0 (December 5, 2016) + +- Updated: boilerplate conventions (Node v6.9.1 LTS) + +### 1.0.0 (September 1, 2015) - Updated: PostCSS 5 - Updated: Develop dependencies - Updated: ESLint configuration -## 0.3.0 (2015-06-16) +### 0.3.0 (June 16, 2015) - Added: Support for complex uses - Added: Code documentation - Changed: Coding conventions -## 0.2.1 (2015-06-16) +### 0.2.1 (June 16, 2015) - Fixed: postcss-selector-parser is included as a dependency -## 0.2.0 (2015-06-15) +### 0.2.0 (June 15, 2015) - Changed: use postcss-selector-parser -## 0.1.1 (2015-06-14) +### 0.1.1 (June 14, 2015) Initial release diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 0000000000..d245cc3d1b --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,64 @@ +# Contributing to :any-link + +You want to help? You rock! Now, take a moment to be sure your contributions +make sense to everyone else. + +## Reporting Issues + +Found a problem? Want a new feature? + +- See if your issue or idea has [already been reported]. +- Provide a [reduced test case] or a [live example]. + +Remember, a bug is a _demonstrable problem_ caused by _our_ code. + +## Submitting Pull Requests + +Pull requests are the greatest contributions, so be sure they are focused in +scope, and do avoid unrelated commits. + +1. To begin, [fork this project], clone your fork, and add our upstream. + ```bash + # Clone your fork of the repo into the current directory + git clone https://github.com//postcss-pseudo-class-any-link + # Navigate to the newly cloned directory + cd postcss-pseudo-class-any-link + # Assign the original repo to a remote called "upstream" + git remote add upstream https://github.com/jonathantneal/postcss-pseudo-class-any-link + # Install the tools necessary for development + npm install + ``` + +2. Create a branch for your feature or fix: + ```bash + # Move into a new branch for a feature + git checkout -b feature/thing + ``` + ```bash + # Move into a new branch for a fix + git checkout -b fix/something + ``` + +3. Be sure your code follows our practices. + ```bash + # Test current code + npm run test + ``` + +4. Push your branch up to your fork: + ```bash + # Push a feature branch + git push origin feature/thing + ``` + ```bash + # Push a fix branch + git push origin fix/something + ``` + +5. Now [open a pull request] with a clear title and description. + +[already been reported]: issues +[fork this project]: fork +[live example]: http://codepen.io/pen +[open a pull request]: https://help.github.com/articles/using-pull-requests/ +[reduced test case]: https://css-tricks.com/reduced-test-cases/ diff --git a/LICENSE.md b/LICENSE.md index 565f84e33c..34f902f6c4 100644 --- a/LICENSE.md +++ b/LICENSE.md @@ -1,15 +1,106 @@ -# CC0 1.0 Universal License +# CC0 1.0 Universal -Public Domain Dedication +## Statement of Purpose -The person(s) who associated a work with this deed has dedicated the work to the public domain by waiving all of his or her rights to the work worldwide under copyright law, including all related and neighboring rights, to the extent allowed by law. +The laws of most jurisdictions throughout the world automatically confer +exclusive Copyright and Related Rights (defined below) upon the creator and +subsequent owner(s) (each and all, an “owner”) of an original work of +authorship and/or a database (each, a “Work”). -You can copy, modify, distribute and perform the work, even for commercial purposes, all without asking permission. +Certain owners wish to permanently relinquish those rights to a Work for the +purpose of contributing to a commons of creative, cultural and scientific works +(“Commons”) that the public can reliably and without fear of later claims of +infringement build upon, modify, incorporate in other works, reuse and +redistribute as freely as possible in any form whatsoever and for any purposes, +including without limitation commercial purposes. These owners may contribute +to the Commons to promote the ideal of a free culture and the further +production of creative, cultural and scientific works, or to gain reputation or +greater distribution for their Work in part through the use and efforts of +others. -In no way are the patent or trademark rights of any person affected by CC0, nor are the rights that other persons may have in the work or in how the work is used, such as publicity or privacy rights. +For these and/or other purposes and motivations, and without any expectation of +additional consideration or compensation, the person associating CC0 with a +Work (the “Affirmer”), to the extent that he or she is an owner of Copyright +and Related Rights in the Work, voluntarily elects to apply CC0 to the Work and +publicly distribute the Work under its terms, with knowledge of his or her +Copyright and Related Rights in the Work and the meaning and intended legal +effect of CC0 on those rights. -Unless expressly stated otherwise, the person(s) who associated a work with this deed makes no warranties about the work, and disclaims liability for all uses of the work, to the fullest extent permitted by applicable law. +1. Copyright and Related Rights. A Work made available under CC0 may be + protected by copyright and related or neighboring rights (“Copyright and + Related Rights”). Copyright and Related Rights include, but are not limited + to, the following: + 1. the right to reproduce, adapt, distribute, perform, display, + communicate, and translate a Work; + 2. moral rights retained by the original author(s) and/or performer(s); + 3. publicity and privacy rights pertaining to a person’s image or likeness + depicted in a Work; + 4. rights protecting against unfair competition in regards to a Work, + subject to the limitations in paragraph 4(i), below; + 5. rights protecting the extraction, dissemination, use and reuse of data + in a Work; + 6. database rights (such as those arising under Directive 96/9/EC of the + European Parliament and of the Council of 11 March 1996 on the legal + protection of databases, and under any national implementation thereof, + including any amended or successor version of such directive); and + 7. other similar, equivalent or corresponding rights throughout the world + based on applicable law or treaty, and any national implementations + thereof. -When using or citing the work, you should not imply endorsement by the author or the affirmer. +2. Waiver. To the greatest extent permitted by, but not in contravention of, +applicable law, Affirmer hereby overtly, fully, permanently, irrevocably and +unconditionally waives, abandons, and surrenders all of Affirmer’s Copyright +and Related Rights and associated claims and causes of action, whether now +known or unknown (including existing as well as future claims and causes of +action), in the Work (i) in all territories worldwide, (ii) for the maximum +duration provided by applicable law or treaty (including future time +extensions), (iii) in any current or future medium and for any number of +copies, and (iv) for any purpose whatsoever, including without limitation +commercial, advertising or promotional purposes (the “Waiver”). Affirmer makes +the Waiver for the benefit of each member of the public at large and to the +detriment of Affirmer’s heirs and successors, fully intending that such Waiver +shall not be subject to revocation, rescission, cancellation, termination, or +any other legal or equitable action to disrupt the quiet enjoyment of the Work +by the public as contemplated by Affirmer’s express Statement of Purpose. -This is a [human-readable summary of the Legal Code](https://creativecommons.org/publicdomain/zero/1.0/) ([read the full text](https://creativecommons.org/publicdomain/zero/1.0/legalcode)). +3. Public License Fallback. Should any part of the Waiver for any reason be +judged legally invalid or ineffective under applicable law, then the Waiver +shall be preserved to the maximum extent permitted taking into account +Affirmer’s express Statement of Purpose. In addition, to the extent the Waiver +is so judged Affirmer hereby grants to each affected person a royalty-free, non +transferable, non sublicensable, non exclusive, irrevocable and unconditional +license to exercise Affirmer’s Copyright and Related Rights in the Work (i) in +all territories worldwide, (ii) for the maximum duration provided by applicable +law or treaty (including future time extensions), (iii) in any current or +future medium and for any number of copies, and (iv) for any purpose +whatsoever, including without limitation commercial, advertising or promotional +purposes (the “License”). The License shall be deemed effective as of the date +CC0 was applied by Affirmer to the Work. Should any part of the License for any +reason be judged legally invalid or ineffective under applicable law, such +partial invalidity or ineffectiveness shall not invalidate the remainder of the +License, and in such case Affirmer hereby affirms that he or she will not (i) +exercise any of his or her remaining Copyright and Related Rights in the Work +or (ii) assert any associated claims and causes of action with respect to the +Work, in either case contrary to Affirmer’s express Statement of Purpose. + +4. Limitations and Disclaimers. + 1. No trademark or patent rights held by Affirmer are waived, abandoned, + surrendered, licensed or otherwise affected by this document. + 2. Affirmer offers the Work as-is and makes no representations or + warranties of any kind concerning the Work, express, implied, statutory + or otherwise, including without limitation warranties of title, + merchantability, fitness for a particular purpose, non infringement, or + the absence of latent or other defects, accuracy, or the present or + absence of errors, whether or not discoverable, all to the greatest + extent permissible under applicable law. + 3. Affirmer disclaims responsibility for clearing rights of other persons + that may apply to the Work or any use thereof, including without + limitation any person’s Copyright and Related Rights in the Work. + Further, Affirmer disclaims responsibility for obtaining any necessary + consents, permissions or other rights required for any use of the Work. + 4. Affirmer understands and acknowledges that Creative Commons is not a + party to this document and has no duty or obligation with respect to + this CC0 or use of the Work. + +For more information, please see +http://creativecommons.org/publicdomain/zero/1.0/. diff --git a/README.md b/README.md index 1c1b68ddfa..8b0685192e 100644 --- a/README.md +++ b/README.md @@ -1,8 +1,12 @@ -# PostCSS Pseudo-Class Any-Link [![Build Status][ci-img]][ci] +# :any-link PostCSS Logo - +[![NPM Version][npm-img]][npm-url] +[![Build Status][cli-img]][cli-url] +[![Licensing][lic-image]][lic-url] +[![Changelog][log-image]][log-url] +[![Gitter Chat][git-image]][git-url] -[PostCSS Pseudo-Class Any-Link] is a [PostCSS] plugin that allows you to use the proposed [`:any-link`] pseudo-class in CSS. +[:any-link] lets you to use the proposed [`:any-link`] pseudo-class in CSS. `:any-link` simplifies selectors targeting links, as the naming of `:link` is misleading; it specifically means unvisited links only, rather than all links. @@ -25,32 +29,79 @@ From the [proposal]: > The [`:any-link`] pseudo-class represents an element that acts as the source anchor of a hyperlink. It matches an element if the element would match [`:link`] or [`:visited`]. +## Options + +**prefix** (string): prepends a prefix (surrounded by dashes) to the pseudo-class, preventing any clash with native syntax. + +```js +{ + prefix: 'foo' // pseudo-class becomes :-foo-any-link +} +``` + ## Usage -You just need to follow these two steps to use [PostCSS Pseudo-Class Any-Link]: +Add [:any-link] to your build tool: + +```bash +npm install :any-link --save-dev +``` + +#### Node + +```js +require(':any-link').process(YOUR_CSS, { /* options */ }); +``` + +#### PostCSS + +Add [PostCSS] to your build tool: + +```bash +npm install postcss --save-dev +``` + +Load [:any-link] as a PostCSS plugin: + +```js +postcss([ + require(':any-link')({ /* options */ }) +]).process(YOUR_CSS, /* options */); +``` + +#### Gulp -1. Add [PostCSS] to your build tool. -2. Add [PostCSS Pseudo-Class Any-Link] as a PostCSS process. +Add [Gulp PostCSS] to your build tool: -```sh -npm install postcss-pseudo-class-any-link --save-dev +```bash +npm install gulp-postcss --save-dev ``` -### Node +Enable [:any-link] within your Gulpfile: ```js -postcss([ require('postcss-pseudo-class-any-link')({ /* options */ }) ]) +var postcss = require('gulp-postcss'); + +gulp.task('css', function () { + return gulp.src('./src/*.css').pipe( + postcss([ + require(':any-link')({ /* options */ }) + ]) + ).pipe( + gulp.dest('.') + ); +}); ``` -### Grunt +#### Grunt Add [Grunt PostCSS] to your build tool: -```sh -npm install postcss-pseudo-class-any-link --save-dev +```bash +npm install grunt-postcss --save-dev ``` -Enable [PostCSS Pseudo-Class Any-Link] within your Gruntfile: +Enable [:any-link] within your Gruntfile: ```js grunt.loadNpmTasks('grunt-postcss'); @@ -58,27 +109,17 @@ grunt.loadNpmTasks('grunt-postcss'); grunt.initConfig({ postcss: { options: { - processors: [ - require('postcss-pseudo-class-any-link')({ /* options */ }) + use: [ + require(':any-link')({ /* options */ }) ] }, dist: { - src: 'css/*.css' + src: '*.css' } } }); ``` -### Options - -**prefix** (string): prepends a prefix (surrounded by dashes) to the pseudo-class, preventing any clash with native syntax. - -```js -{ - prefix: 'foo' // pseudo-class becomes :-foo-any-link -} -``` - ### Alternatives Here are a few other ways to simulate the effect of [PostCSS Pseudo-Class Any-Link]. @@ -99,12 +140,22 @@ Here are a few other ways to simulate the effect of [PostCSS Pseudo-Class Any-Li :link, :visited { /* ... */ } ``` +[npm-url]: https://www.npmjs.com/package/postcss-pseudo-class-any-link +[npm-img]: https://img.shields.io/npm/v/postcss-pseudo-class-any-link.svg +[cli-url]: https://travis-ci.org/jonathantneal/postcss-pseudo-class-any-link +[cli-img]: https://img.shields.io/travis/jonathantneal/postcss-pseudo-class-any-link.svg +[lic-url]: LICENSE.md +[lic-image]: https://img.shields.io/npm/l/postcss-pseudo-class-any-link.svg +[log-url]: CHANGELOG.md +[log-image]: https://img.shields.io/badge/changelog-md-blue.svg +[git-url]: https://gitter.im/postcss/postcss +[git-image]: https://img.shields.io/badge/chat-gitter-blue.svg + +[:any-link]: https://github.com/jonathantneal/postcss-pseudo-class-any-link [`:any-link`]: http://dev.w3.org/csswg/selectors/#any-link-pseudo [`:link`]: http://dev.w3.org/csswg/selectors/#link-pseudo [`:visited`]: http://dev.w3.org/csswg/selectors/#visited-pseudo -[ci]: https://travis-ci.org/jonathantneal/postcss-pseudo-class-any-link -[ci-img]: https://travis-ci.org/jonathantneal/postcss-pseudo-class-any-link.svg -[Grunt PostCSS]: https://github.com/nDmitry/grunt-postcss -[PostCSS]: https://github.com/postcss/postcss -[PostCSS Pseudo-Class Any-Link]: https://github.com/jonathantneal/postcss-pseudo-class-any-link [proposal]: http://dev.w3.org/csswg/selectors/ +[PostCSS]: https://github.com/postcss/postcss +[Gulp PostCSS]: https://github.com/postcss/gulp-postcss +[Grunt PostCSS]: https://github.com/nDmitry/grunt-postcss diff --git a/gulpfile.js b/gulpfile.js deleted file mode 100644 index 04d7d79d37..0000000000 --- a/gulpfile.js +++ /dev/null @@ -1,18 +0,0 @@ -var gulp = require('gulp'); - -gulp.task('lint', function () { - var eslint = require('gulp-eslint'); - - return gulp.src(['index.js', 'test/*.js', 'gulpfile.js']) - .pipe(eslint()) - .pipe(eslint.format()) - .pipe(eslint.failAfterError()); -}); - -gulp.task('test', function () { - var mocha = require('gulp-mocha'); - - return gulp.src('test/*.js', { read: false }).pipe(mocha()); -}); - -gulp.task('default', ['lint', 'test']); diff --git a/index.js b/index.js index 653f405ecf..2a9c3b7554 100644 --- a/index.js +++ b/index.js @@ -1,29 +1,41 @@ -var postcss = require('postcss'); -var postcssSelectorParser = require('postcss-selector-parser'); +// tooling +const postcss = require('postcss'); +const parser = require('postcss-selector-parser'); -module.exports = postcss.plugin('postcss-pseudo-class-any-link', function (opts) { - // cache the any-link value - var valueAnyLink = ':' + (opts && opts.prefix ? '-' + opts.prefix + '-' : '') + 'any-link'; +// plugin +module.exports = postcss.plugin('postcss-pseudo-class-any-link', ({ + prefix = '' +}) => { + // dashed prefix + const dashedPrefix = prefix ? '-' + prefix + '-' : ''; - return function (css) { + // any-link value + const anyLinkValue = `:${ dashedPrefix }any-link`; + + // selector pattern + const selectorMatch = new RegExp(`${ dashedPrefix }any-link`); + + return (css) => { // for each rule - css.walkRules(function (rule) { - var rawSelector = rule.raws.selector && rule.raws.selector.raw || rule.selector; + css.walkRules(selectorMatch, (rule) => { + const rawSelector = rule.raws.selector && rule.raws.selector.raw || rule.selector; + // workaround for https://github.com/postcss/postcss-selector-parser/issues/28#issuecomment-171910556 if (rawSelector[rawSelector.length - 1] === ':') { return; } + // update the selector - rule.selector = postcssSelectorParser(function (selectors) { + rule.selector = parser((selectors) => { // cache variables - var node; - var nodeIndex; - var selector; - var selectorLink; - var selectorVisited; + let node; + let nodeIndex; + let selector; + let selectorLink; + let selectorVisited; // cache the selector index - var selectorIndex = -1; + let selectorIndex = -1; // for each selector while (selector = selectors.nodes[++selectorIndex]) { @@ -33,7 +45,7 @@ module.exports = postcss.plugin('postcss-pseudo-class-any-link', function (opts) // for each node while (node = selector.nodes[++nodeIndex]) { // if the node value matches the any-link value - if (node.value === valueAnyLink) { + if (node.value === anyLinkValue) { // clone the selector selectorLink = selector.clone(); selectorVisited = selector.clone(); diff --git a/package.json b/package.json index 09df941df7..10ab136c65 100644 --- a/package.json +++ b/package.json @@ -1,29 +1,60 @@ { - "name": "postcss-pseudo-class-any-link", - "version": "1.0.0", - "description": "Use the proposed :any-link pseudo-class in CSS", - "keywords": ["postcss", "css", "postcss-plugin", "link", "visited", "any-link", "a", "area", "hyperlink", "href"], - "author": "Jonathan Neal ", - "license": "CC0-1.0", - "bugs": { - "url": "https://github.com/jonathantneal/postcss-pseudo-class-any-link/issues" - }, - "homepage": "https://github.com/jonathantneal/postcss-pseudo-class-any-link", - "repository": { - "type": "git", - "url": "https://github.com/jonathantneal/postcss-pseudo-class-any-link.git" - }, - "dependencies": { - "postcss": "^5.0.3", - "postcss-selector-parser": "^1.1.4" - }, - "devDependencies": { - "chai": "^3.2.0", - "gulp": "^3.9.0", - "gulp-eslint": "^1.0.0", - "gulp-mocha": "^2.1.3" - }, - "scripts": { - "test": "gulp" - } + "name": "postcss-pseudo-class-any-link", + "version": "3.0.0", + "description": "Use the proposed :any-link pseudo-class in CSS", + "author": "Jonathan Neal ", + "license": "CC0-1.0", + "repository": "jonathantneal/postcss-pseudo-class-any-link", + "homepage": "https://github.com/jonathantneal/postcss-pseudo-class-any-link#readme", + "bugs": "https://github.com/jonathantneal/postcss-pseudo-class-any-link/issues", + "main": "index.js", + "files": [ + "index.js" + ], + "scripts": { + "lint": "echint && eslint index.js && jscs index.js", + "prepublish": "npm test", + "tape": "postcss-tape", + "test": "npm run lint && postcss-tape" + }, + "engines": { + "node": ">=6.9.1" + }, + "dependencies": { + "postcss": "^5.2.6", + "postcss-selector-parser": "^2.2.2" + }, + "devDependencies": { + "echint": "^2.1.0", + "echint-config-dev": "1.0.0", + "eslint": "^3.11.1", + "eslint-config-dev": "1.0.0", + "jscs": "^3.0.7", + "jscs-config-dev": "1.0.1", + "postcss-tape": "1.0.1" + }, + "echint": { + "extends": "dev" + }, + "eslintConfig": { + "extends": "dev", + "parserOptions": { + "sourceType": "module" + } + }, + "jscsConfig": { + "preset": "dev" + }, + "keywords": [ + "postcss", + "css", + "postcss-plugin", + "link", + "visited", + "any-link", + "a", + "area", + "hyperlink", + "href" + ] } diff --git a/test/basic.css b/test/basic.css new file mode 100644 index 0000000000..e0ca56047b --- /dev/null +++ b/test/basic.css @@ -0,0 +1,12 @@ +:any-link { + background: blue; +} + +:any-link, +ul a:any-link > span { + background: blue; +} + +:any-link :any-link { + background: blue; +} diff --git a/test/basic.expect.css b/test/basic.expect.css new file mode 100644 index 0000000000..806a50e056 --- /dev/null +++ b/test/basic.expect.css @@ -0,0 +1,13 @@ +:link,:visited { + background: blue; +} + +:link,:visited, +ul a:link > span, +ul a:visited > span { + background: blue; +} + +:link :link,:link :visited,:visited :link,:visited :visited { + background: blue; +} diff --git a/test/basic.w-prefix.expect.css b/test/basic.w-prefix.expect.css new file mode 100644 index 0000000000..e0ca56047b --- /dev/null +++ b/test/basic.w-prefix.expect.css @@ -0,0 +1,12 @@ +:any-link { + background: blue; +} + +:any-link, +ul a:any-link > span { + background: blue; +} + +:any-link :any-link { + background: blue; +} diff --git a/test/prefix.css b/test/prefix.css new file mode 100644 index 0000000000..d8c7ac8a11 --- /dev/null +++ b/test/prefix.css @@ -0,0 +1,12 @@ +:-x-any-link { + background: blue; +} + +:-x-any-link, +ul a:-x-any-link > span { + background: blue; +} + +:-x-any-link :-x-any-link { + background: blue; +} diff --git a/test/prefix.expect.css b/test/prefix.expect.css new file mode 100644 index 0000000000..d8c7ac8a11 --- /dev/null +++ b/test/prefix.expect.css @@ -0,0 +1,12 @@ +:-x-any-link { + background: blue; +} + +:-x-any-link, +ul a:-x-any-link > span { + background: blue; +} + +:-x-any-link :-x-any-link { + background: blue; +} diff --git a/test/prefix.w-prefix.expect.css b/test/prefix.w-prefix.expect.css new file mode 100644 index 0000000000..806a50e056 --- /dev/null +++ b/test/prefix.w-prefix.expect.css @@ -0,0 +1,13 @@ +:link,:visited { + background: blue; +} + +:link,:visited, +ul a:link > span, +ul a:visited > span { + background: blue; +} + +:link :link,:link :visited,:visited :link,:visited :visited { + background: blue; +} diff --git a/test/test.js b/test/test.js deleted file mode 100644 index 08070e5f59..0000000000 --- a/test/test.js +++ /dev/null @@ -1,65 +0,0 @@ -var postcss = require('postcss'); -var expect = require('chai').expect; - -var plugin = require('../'); - -var test = function (input, output, opts, done) { - postcss([ plugin(opts) ]).process(input).then(function (result) { - expect(result.css).to.eql(output); - expect(result.warnings()).to.be.empty; - done(); - }).catch(function (error) { - done(error); - }); -}; - -describe('postcss-pseudo-class-any-link', function () { - // standard tests - it(':any-link', function (done) { - test(':any-link { background: blue; }', ':link,:visited { background: blue; }', {}, done); - }); - - it(':any-link, ul a:any-link > span', function (done) { - test(':any-link, ul a:any-link > span { background: blue; }', ':link,:visited, ul a:link > span, ul a:visited > span { background: blue; }', {}, done); - }); - - it(':any-link :any-link', function (done) { - test(':any-link :any-link { background: blue; }', ':link :link,:link :visited,:visited :link,:visited :visited { background: blue; }', {}, done); - }); - - // custom prefix tests - it(':any-link (with "foo" prefix)', function (done) { - test(':any-link { background: blue; }', ':any-link { background: blue; }', { prefix: 'foo' }, done); - }); - - it(':-foo-any-link (with no prefix)', function (done) { - test(':-foo-any-link { background: blue; }', ':-foo-any-link { background: blue; }', {}, done); - }); - - it(':-foo-any-link (with "foo" prefix)', function (done) { - test(':-foo-any-link { background: blue; }', ':link,:visited { background: blue; }', { prefix: 'foo' }, done); - }); - - it(':-foo-any-link, ul a:-foo-any-link > span (with "foo" prefix)', function (done) { - test(':-foo-any-link, ul a:-foo-any-link > span { background: blue; }', ':link,:visited, ul a:link > span, ul a:visited > span { background: blue; }', { prefix: 'foo' }, done); - }); - - it(':-foo-any-link :-foo-any-link (with "foo" prefix)', function (done) { - test(':-foo-any-link :-foo-any-link { background: blue; }', ':link :link,:link :visited,:visited :link,:visited :visited { background: blue; }', { prefix: 'foo' }, done); - }); - - it(':any-link transforms to :link and :visited', function (done) { - test('ul a:any-link > span { background: yellow; }', 'ul a:link > span,ul a:visited > span { background: yellow; }', {}, done); - }); - - it(':any-link remains :any-link { prefix: "foo" }', function (done) { - test('ul a:any-link > span { background: yellow; }', 'ul a:any-link > span { background: yellow; }', { - prefix: 'foo' - }, done); - }); - - // regression tests - it('--any-link remains --any-link', function (done) { - test('--any-link: { background: blue; }', '--any-link: { background: blue; }', {}, done); - }); -}); From 20213fc0fc63adf13c23c6d82d2c51cbb6a8d233 Mon Sep 17 00:00:00 2001 From: David Clark Date: Fri, 9 Dec 2016 11:47:09 -0500 Subject: [PATCH 394/795] Fix broken link to spec draft The existing link does not seem to work anymore, so I substituted a Working Draft link that does. --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 60a89a35b9..98c34d1a2c 100755 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # postcss-custom-media [![Build Status](https://travis-ci.org/postcss/postcss-custom-media.png)](https://travis-ci.org/postcss/postcss-custom-media) -> [PostCSS](https://github.com/postcss/postcss) plugin to transform [W3C CSS Custom Media Queries](http://dev.w3.org/csswg/mediaqueries/#custom-mq) syntax to more compatible CSS. +> [PostCSS](https://github.com/postcss/postcss) plugin to transform [W3C CSS Custom Media Queries](https://www.w3.org/TR/2016/WD-mediaqueries-4-20160126/#custom-mq) syntax to more compatible CSS. ## Installation From c28c91d8acf9b935c02138368e72952fb231caa1 Mon Sep 17 00:00:00 2001 From: Jonathan Neal Date: Wed, 14 Dec 2016 10:14:07 -0800 Subject: [PATCH 395/795] 1.0.2 --- CHANGELOG.md | 5 ++++ index.js | 79 ++++++++++++++++++++++++++++++---------------------- package.json | 6 ++-- 3 files changed, 54 insertions(+), 36 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 071bbeb147..3274032868 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,10 @@ # Changes to Place +### 1.0.2 (December 8, 2016) + +- Updated: Use destructing assignment on plugin options +- Updated: Use template literals + ### 1.0.1 (December 6, 2016) - Updated: boilerplate conventions (`postcss-tape`) diff --git a/index.js b/index.js index b1cf577945..21a0e34f06 100644 --- a/index.js +++ b/index.js @@ -4,38 +4,51 @@ const parser = require('postcss-value-parser'); // plugin module.exports = postcss.plugin('postcss-place', ({ - prefix -} = {}) => (root) => { - // property - const prop = new RegExp(prefix ? '^-' + prefix + '-(content|items|self)' : '^place-(content|items|self)'); - - root.walkDecls(prop, (decl) => { - // alignment - const alignment = decl.prop.match(prop)[1]; - - // value - const value = parser(decl.value); - - // divider position - const index = value.nodes.map( - (node) => node.type - ).indexOf('space'); - - // new justify-[alignment] and align-[alignment] declarations - const alignValue = index === -1 ? decl.value : parser.stringify(value.nodes.slice(0, index)); - const justifyValue = index === -1 ? decl.value : parser.stringify(value.nodes.slice(index + 1)); - - decl.cloneBefore({ - prop: 'align-' + alignment, - value: alignValue + prefix = '' +} = {}) => { + // dashed prefix + const dashedPrefix = prefix ? `-${ prefix }-` : ''; + + // property matcher + const propertyMatch = new RegExp(`^${ dashedPrefix }place-(content|items|self)`); + + return (root) => { + // walk each matching declaration + root.walkDecls(propertyMatch, (decl) => { + // alignment + const alignment = decl.prop.match(propertyMatch)[1]; + + // value + const value = parser(decl.value); + + // divider position + const index = value.nodes.map( + (node) => node.type + ).indexOf('space'); + + // new justify-[alignment] and align-[alignment] declarations + const alignValue = index === -1 ? decl.value : parser.stringify(value.nodes.slice(0, index)); + const justifyValue = index === -1 ? decl.value : parser.stringify(value.nodes.slice(index + 1)); + + decl.cloneBefore({ + prop: `align-${ alignment }`, + value: alignValue + }); + + decl.cloneBefore({ + prop: `justify-${ alignment }`, + value: justifyValue + }); + + // remove place-[alignment] + decl.remove(); }); - - decl.cloneBefore({ - prop: 'justify-' + alignment, - value: justifyValue - }); - - // remove place-[alignment] - decl.remove(); - }); + }; }); + +// override plugin#process +module.exports.process = function (cssString, pluginOptions, processOptions) { + return postcss([ + 0 in arguments ? module.exports(pluginOptions) : module.exports() + ]).process(cssString, processOptions); +}; diff --git a/package.json b/package.json index 13113b2049..38c510ec6a 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "postcss-place", - "version": "1.0.1", + "version": "1.0.2", "description": "`place-[alignment] shorthand for align-[alignment] and justify-[alignment]", "author": "Jonathan Neal (http://jonathantneal.com)", "license": "CC0-1.0", @@ -27,11 +27,11 @@ "devDependencies": { "echint": "^2.1.0", "echint-config-dev": "1.0.0", - "eslint": "^3.11.1", + "eslint": "^3.12.1", "eslint-config-dev": "1.0.0", "jscs": "^3.0.7", "jscs-config-dev": "1.0.1", - "postcss-tape": "1.0.1" + "postcss-tape": "1.3.0" }, "echint": { "extends": "dev" From c2ac7986239e9f447808b16fd211654b09918a7f Mon Sep 17 00:00:00 2001 From: Jonathan Neal Date: Wed, 14 Dec 2016 10:14:10 -0800 Subject: [PATCH 396/795] 3.0.1 --- CHANGELOG.md | 5 ++++ index.js | 81 ++++++++++++++++++++++++++++------------------------ package.json | 6 ++-- 3 files changed, 51 insertions(+), 41 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index cff52aa2b2..b8c66696e9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,10 @@ # Changes to :any-link +### 3.0.1 (December 8, 2016) + +- Updated: Use destructing assignment on plugin options +- Updated: Use template literals + ### 3.0.0 (December 5, 2016) - Updated: boilerplate conventions (Node v6.9.1 LTS) diff --git a/index.js b/index.js index 2a9c3b7554..27df8f2608 100644 --- a/index.js +++ b/index.js @@ -5,64 +5,69 @@ const parser = require('postcss-selector-parser'); // plugin module.exports = postcss.plugin('postcss-pseudo-class-any-link', ({ prefix = '' -}) => { +} = {}) => { // dashed prefix - const dashedPrefix = prefix ? '-' + prefix + '-' : ''; + const dashedPrefix = prefix ? `-${ prefix }-` : ''; // any-link value const anyLinkValue = `:${ dashedPrefix }any-link`; - // selector pattern + // selector matcher const selectorMatch = new RegExp(`${ dashedPrefix }any-link`); return (css) => { - // for each rule + // walk each matching rule css.walkRules(selectorMatch, (rule) => { const rawSelector = rule.raws.selector && rule.raws.selector.raw || rule.selector; // workaround for https://github.com/postcss/postcss-selector-parser/issues/28#issuecomment-171910556 - if (rawSelector[rawSelector.length - 1] === ':') { - return; - } - - // update the selector - rule.selector = parser((selectors) => { - // cache variables - let node; - let nodeIndex; - let selector; - let selectorLink; - let selectorVisited; + if (rawSelector[rawSelector.length - 1] !== ':') { + // update the selector + rule.selector = parser((selectors) => { + // cache variables + let node; + let nodeIndex; + let selector; + let selectorLink; + let selectorVisited; - // cache the selector index - let selectorIndex = -1; + // cache the selector index + let selectorIndex = -1; - // for each selector - while (selector = selectors.nodes[++selectorIndex]) { - // reset the node index - nodeIndex = -1; + // for each selector + while (selector = selectors.nodes[++selectorIndex]) { + // reset the node index + nodeIndex = -1; - // for each node - while (node = selector.nodes[++nodeIndex]) { - // if the node value matches the any-link value - if (node.value === anyLinkValue) { - // clone the selector - selectorLink = selector.clone(); - selectorVisited = selector.clone(); + // for each node + while (node = selector.nodes[++nodeIndex]) { + // if the node value matches the any-link value + if (node.value === anyLinkValue) { + // clone the selector + selectorLink = selector.clone(); + selectorVisited = selector.clone(); - // update the matching clone values - selectorLink.nodes[nodeIndex].value = ':link'; - selectorVisited.nodes[nodeIndex].value = ':visited'; + // update the matching clone values + selectorLink.nodes[nodeIndex].value = ':link'; + selectorVisited.nodes[nodeIndex].value = ':visited'; - // replace the selector with the clones and roll back the selector index - selectors.nodes.splice(selectorIndex--, 1, selectorLink, selectorVisited); + // replace the selector with the clones and roll back the selector index + selectors.nodes.splice(selectorIndex--, 1, selectorLink, selectorVisited); - // stop updating the selector - break; + // stop updating the selector + break; + } } } - } - }).process(rawSelector).result; + }).process(rawSelector).result; + } }); }; }); + +// override plugin#process +module.exports.process = function (cssString, pluginOptions, processOptions) { + return postcss([ + 1 in arguments ? module.exports(pluginOptions) : module.exports() + ]).process(cssString, processOptions); +}; diff --git a/package.json b/package.json index 10ab136c65..8db6daefc4 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "postcss-pseudo-class-any-link", - "version": "3.0.0", + "version": "3.0.1", "description": "Use the proposed :any-link pseudo-class in CSS", "author": "Jonathan Neal ", "license": "CC0-1.0", @@ -27,11 +27,11 @@ "devDependencies": { "echint": "^2.1.0", "echint-config-dev": "1.0.0", - "eslint": "^3.11.1", + "eslint": "^3.12.1", "eslint-config-dev": "1.0.0", "jscs": "^3.0.7", "jscs-config-dev": "1.0.1", - "postcss-tape": "1.0.1" + "postcss-tape": "1.3.0" }, "echint": { "extends": "dev" From 41c1a5045f328eb064428da6dc30640768c991ee Mon Sep 17 00:00:00 2001 From: Jiayi Hu Date: Mon, 2 Jan 2017 10:04:17 +0100 Subject: [PATCH 397/795] docs: explain better usage of extensions option (#23) --- README.md | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/README.md b/README.md index 98c34d1a2c..bcf5a79940 100755 --- a/README.md +++ b/README.md @@ -54,6 +54,15 @@ Checkout [tests](test) for more examples. Allows you to pass an object to define the `` for each ``. These definitions will override any that exist in the CSS. +```javascript +{ + '--phone': '(min-width: 544px)', + '--tablet': '(min-width: 768px)', + '--desktop': '(min-width: 992px)', + '--large-desktop': '(min-width: 1200px)', +} +``` + #### `preserve` (default: `false`) From 2819d55da4385e46819e2feda4964a52709773d8 Mon Sep 17 00:00:00 2001 From: wtgtybhertgeghgtwtg Date: Tue, 31 Jan 2017 23:22:13 -0700 Subject: [PATCH 398/795] Bump `balanced-match`. (#57) --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 6db90bce27..425d40bad3 100644 --- a/package.json +++ b/package.json @@ -17,7 +17,7 @@ "index.js" ], "dependencies": { - "balanced-match": "~0.1.0", + "balanced-match": "^0.4.2", "postcss": "^5.0.0" }, "devDependencies": { From aeec09fad25c6117bc59cb9b19aac0389719631b Mon Sep 17 00:00:00 2001 From: Aleksey Shvayka Date: Wed, 1 Feb 2017 08:33:42 +0200 Subject: [PATCH 399/795] README Use vector Travis badge (#55) PNG does not look nice on Retina --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 8cc7f75d0f..154ebeb7e8 100755 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# postcss-custom-properties [![Build Status](https://travis-ci.org/postcss/postcss-custom-properties.png)](https://travis-ci.org/postcss/postcss-custom-properties) +# postcss-custom-properties [![Build Status](https://travis-ci.org/postcss/postcss-custom-properties.svg)](https://travis-ci.org/postcss/postcss-custom-properties) > [PostCSS](https://github.com/postcss/postcss) plugin to transform [W3C CSS Custom Properties for ~~cascading~~ variables](http://www.w3.org/TR/css-variables/) syntax to more compatible CSS. From 317d7387ac262dce0a134a352532e6f2b01034b4 Mon Sep 17 00:00:00 2001 From: Maxime Thirouin Date: Wed, 1 Feb 2017 07:35:25 +0100 Subject: [PATCH 400/795] 5.0.2 --- CHANGELOG.md | 5 +++++ package.json | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 86c460a4a5..230df82876 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,8 @@ +# 5.0.2 - 2017-02-01 + +- Minor dependency update + ([#57](https://github.com/postcss/postcss-custom-properties/pull/57)) + # 5.0.1 - 2016-04-22 - Fixed: trailing space after custom property name causes duplicate empty diff --git a/package.json b/package.json index 425d40bad3..c761c9a6a8 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "postcss-custom-properties", - "version": "5.0.1", + "version": "5.0.2", "description": "PostCSS plugin to polyfill W3C CSS Custom Properties for cascading variables", "keywords": [ "css", From 70adb94bea5b3396f1d4c9012e761dcb09b2b1a6 Mon Sep 17 00:00:00 2001 From: semigradsky Date: Sun, 5 Feb 2017 15:02:02 +0300 Subject: [PATCH 401/795] Fix `npm test` error --- .eslintignore | 3 ++- .eslintrc | 13 ++++++------- package.json | 6 ++---- test/index.js | 4 ++-- 4 files changed, 12 insertions(+), 14 deletions(-) diff --git a/.eslintignore b/.eslintignore index 3e4e48b0b5..3eb98cd3f3 120000 --- a/.eslintignore +++ b/.eslintignore @@ -1 +1,2 @@ -.gitignore \ No newline at end of file +.gitignore +dist \ No newline at end of file diff --git a/.eslintrc b/.eslintrc index db21f05621..8fb0de30fd 100644 --- a/.eslintrc +++ b/.eslintrc @@ -1,16 +1,15 @@ --- -# babel support more syntax stuff than eslint for now -parser: babel-eslint root: true extends: eslint:recommended -ecmaFeatures: - modules: true +parserOptions: + sourceType: "module" + ecmaVersion: 6 + ecmaFeatures: + experimentalObjectRestSpread: true env: - es6: true - browser: true node: true rules: @@ -35,7 +34,7 @@ rules: computed-property-spacing: [2, "never"] space-unary-ops: [2, {"words": true, "nonwords": false}] - space-after-keywords: [2, "always"] + keyword-spacing: [2, {"before": true, "after": true}] space-before-blocks: [2, "always"] space-before-function-paren: [2, "never"] space-in-parens: [2, "never"] diff --git a/package.json b/package.json index 12c204c2de..bc92f04032 100644 --- a/package.json +++ b/package.json @@ -24,21 +24,19 @@ "README-zh.md" ], "dependencies": { - "balanced-match": "^0.2.0", "postcss": "^5.0.0", "postcss-selector-matches": "^2.0.0" }, "devDependencies": { "babel": "^5.5.8", - "babel-eslint": "^3.1.15", "babel-tape-runner": "^1.1.0", - "eslint": "^1.0.0", + "eslint": "^3.15.0", "tape": "^4.0.0" }, "scripts": { "prepublish": "babel src --out-dir dist", "lint": "eslint .", - "tape": "babel-tape-runner 'test/*.js'", + "tape": "babel-tape-runner test/*.js", "test": "npm run lint && npm run tape" } } diff --git a/test/index.js b/test/index.js index 8dc2e093dc..5fadaec395 100644 --- a/test/index.js +++ b/test/index.js @@ -11,9 +11,9 @@ function transform(input, opts = {}, postcssOpts = {}) { test("@custom-selector", function(t) { t.equal( transform( - `` + "" ).css, - ``, + "", "should works with nothing" ) From 62ca821a4ba19ced444bad42e95aef15ad0d54f4 Mon Sep 17 00:00:00 2001 From: semigradsky Date: Sun, 5 Feb 2017 15:48:40 +0300 Subject: [PATCH 402/795] Fix travis config --- .eslintignore | 2 -- .travis.yml | 6 +++--- package.json | 2 +- 3 files changed, 4 insertions(+), 6 deletions(-) delete mode 120000 .eslintignore diff --git a/.eslintignore b/.eslintignore deleted file mode 120000 index 3eb98cd3f3..0000000000 --- a/.eslintignore +++ /dev/null @@ -1,2 +0,0 @@ -.gitignore -dist \ No newline at end of file diff --git a/.travis.yml b/.travis.yml index ffb8b3996f..39024ba818 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,6 +1,6 @@ sudo: false language: node_js node_js: - - iojs - - "0.12" - - "0.10" + - stable + - "6" + - "4" diff --git a/package.json b/package.json index bc92f04032..fcf7c978b7 100644 --- a/package.json +++ b/package.json @@ -35,7 +35,7 @@ }, "scripts": { "prepublish": "babel src --out-dir dist", - "lint": "eslint .", + "lint": "eslint src test", "tape": "babel-tape-runner test/*.js", "test": "npm run lint && npm run tape" } From 7f02aee850dc3d225a9e8600ceaaa87bb7ea2fd5 Mon Sep 17 00:00:00 2001 From: Ole Ersoy Date: Mon, 20 Feb 2017 04:52:25 -0600 Subject: [PATCH 403/795] Updated resolveValue comment (#65) --- index.js | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/index.js b/index.js index 7dd8afa225..7d8e3d2913 100755 --- a/index.js +++ b/index.js @@ -15,18 +15,15 @@ var VAR_FUNC_IDENTIFIER = "var" var RE_VAR = /([\w-]+)(?:\s*,\s*)?\s*(.*)?/ /** - * Resolve CSS variables in a value + * Resolve CSS variables. * - * The second argument to a CSS variable function, if provided, is a fallback - * value, which is used as the substitution value when the referenced variable - * is invalid. + * The second argument to the CSS variable function, var(name[, fallback]), + * is used in the event that first argument cannot be resolved. * - * var(name[, fallback]) - * - * @param {String} value A property value known to contain CSS variable - * functions + * @param {String} value May contain the CSS variable function * @param {Object} variables A map of variable names and values - * @param {Object} source source object of the declaration containing the rule + * @param {Object} result The PostCSS result object + * @param {Object} decl The declaration containing the rule * @return {String} A property value with all CSS variables substituted. */ From 7b1760be1d611da2f96558a4ca3ff036f14e6d33 Mon Sep 17 00:00:00 2001 From: Jonathan Neal Date: Thu, 4 May 2017 10:38:53 -0400 Subject: [PATCH 404/795] 1.0.0 --- .gitignore | 8 + .tape.js | 19 ++ .travis.yml | 3 + CHANGELOG.md | 5 + CONTRIBUTING.md | 64 +++++ LICENSE.md | 106 ++++++++ README.md | 120 +++++++++ index.js | 44 ++++ lib/json-to-ast.js | 14 + lib/normalize-browser-list.json | 72 +++++ lib/normalize-css-to-json.js | 74 ++++++ lib/normalize.css | 454 ++++++++++++++++++++++++++++++++ package.json | 54 ++++ test/basic.css | 3 + test/basic.expect.css | 93 +++++++ test/basic.last-1.expect.css | 86 ++++++ test/basic.last-2.expect.css | 93 +++++++ 17 files changed, 1312 insertions(+) create mode 100644 .gitignore create mode 100644 .tape.js create mode 100644 .travis.yml create mode 100644 CHANGELOG.md create mode 100644 CONTRIBUTING.md create mode 100644 LICENSE.md create mode 100644 README.md create mode 100644 index.js create mode 100644 lib/json-to-ast.js create mode 100644 lib/normalize-browser-list.json create mode 100644 lib/normalize-css-to-json.js create mode 100644 lib/normalize.css create mode 100644 package.json create mode 100644 test/basic.css create mode 100644 test/basic.expect.css create mode 100644 test/basic.last-1.expect.css create mode 100644 test/basic.last-2.expect.css diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000000..7a85c88ad1 --- /dev/null +++ b/.gitignore @@ -0,0 +1,8 @@ +node_modules +.* +!.gitignore +!.tape.js +!.travis.yml +*.log* +*.result.css +/lib/normalize.json diff --git a/.tape.js b/.tape.js new file mode 100644 index 0000000000..7594d96570 --- /dev/null +++ b/.tape.js @@ -0,0 +1,19 @@ +module.exports = { + 'postcss-normalize': { + 'basic': { + message: 'supports basic usage' + }, + 'basic:last-2': { + message: 'supports { browsers: "last 2 versions" } usage', + options: { + browsers: 'last 2 versions' + } + }, + 'basic:last-1': { + message: 'supports { browsers: "last 1 versions" } usage', + options: { + browsers: 'last 1 versions' + } + } + } +}; diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000000..833d09d149 --- /dev/null +++ b/.travis.yml @@ -0,0 +1,3 @@ +language: node_js +node_js: + - stable diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000000..57fe94a375 --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,5 @@ +# Changes to PostCSS Normalize + +### 1.0.0 (May 2, 2017) + +- Initial version diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 0000000000..d280ee89d4 --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,64 @@ +# Contributing to PostCSS Normalize + +You want to help? You rock! Now, take a moment to be sure your contributions +make sense to everyone else. + +## Reporting Issues + +Found a problem? Want a new feature? + +- See if your issue or idea has [already been reported]. +- Provide a [reduced test case] or a [live example]. + +Remember, a bug is a _demonstrable problem_ caused by _our_ code. + +## Submitting Pull Requests + +Pull requests are the greatest contributions, so be sure they are focused in +scope, and do avoid unrelated commits. + +1. To begin, [fork this project], clone your fork, and add our upstream. + ```bash + # Clone your fork of the repo into the current directory + git clone https://github.com//postcss-normalize + # Navigate to the newly cloned directory + cd postcss-normalize + # Assign the original repo to a remote called "upstream" + git remote add upstream https://github.com/jonathantneal/postcss-normalize + # Install the tools necessary for development + npm install + ``` + +2. Create a branch for your feature or fix: + ```bash + # Move into a new branch for a feature + git checkout -b feature/thing + ``` + ```bash + # Move into a new branch for a fix + git checkout -b fix/something + ``` + +3. Be sure your code follows our practices. + ```bash + # Test current code + npm run test + ``` + +4. Push your branch up to your fork: + ```bash + # Push a feature branch + git push origin feature/thing + ``` + ```bash + # Push a fix branch + git push origin fix/something + ``` + +5. Now [open a pull request] with a clear title and description. + +[already been reported]: issues +[fork this project]: fork +[live example]: http://codepen.io/pen +[open a pull request]: https://help.github.com/articles/using-pull-requests/ +[reduced test case]: https://css-tricks.com/reduced-test-cases/ diff --git a/LICENSE.md b/LICENSE.md new file mode 100644 index 0000000000..34f902f6c4 --- /dev/null +++ b/LICENSE.md @@ -0,0 +1,106 @@ +# CC0 1.0 Universal + +## Statement of Purpose + +The laws of most jurisdictions throughout the world automatically confer +exclusive Copyright and Related Rights (defined below) upon the creator and +subsequent owner(s) (each and all, an “owner”) of an original work of +authorship and/or a database (each, a “Work”). + +Certain owners wish to permanently relinquish those rights to a Work for the +purpose of contributing to a commons of creative, cultural and scientific works +(“Commons”) that the public can reliably and without fear of later claims of +infringement build upon, modify, incorporate in other works, reuse and +redistribute as freely as possible in any form whatsoever and for any purposes, +including without limitation commercial purposes. These owners may contribute +to the Commons to promote the ideal of a free culture and the further +production of creative, cultural and scientific works, or to gain reputation or +greater distribution for their Work in part through the use and efforts of +others. + +For these and/or other purposes and motivations, and without any expectation of +additional consideration or compensation, the person associating CC0 with a +Work (the “Affirmer”), to the extent that he or she is an owner of Copyright +and Related Rights in the Work, voluntarily elects to apply CC0 to the Work and +publicly distribute the Work under its terms, with knowledge of his or her +Copyright and Related Rights in the Work and the meaning and intended legal +effect of CC0 on those rights. + +1. Copyright and Related Rights. A Work made available under CC0 may be + protected by copyright and related or neighboring rights (“Copyright and + Related Rights”). Copyright and Related Rights include, but are not limited + to, the following: + 1. the right to reproduce, adapt, distribute, perform, display, + communicate, and translate a Work; + 2. moral rights retained by the original author(s) and/or performer(s); + 3. publicity and privacy rights pertaining to a person’s image or likeness + depicted in a Work; + 4. rights protecting against unfair competition in regards to a Work, + subject to the limitations in paragraph 4(i), below; + 5. rights protecting the extraction, dissemination, use and reuse of data + in a Work; + 6. database rights (such as those arising under Directive 96/9/EC of the + European Parliament and of the Council of 11 March 1996 on the legal + protection of databases, and under any national implementation thereof, + including any amended or successor version of such directive); and + 7. other similar, equivalent or corresponding rights throughout the world + based on applicable law or treaty, and any national implementations + thereof. + +2. Waiver. To the greatest extent permitted by, but not in contravention of, +applicable law, Affirmer hereby overtly, fully, permanently, irrevocably and +unconditionally waives, abandons, and surrenders all of Affirmer’s Copyright +and Related Rights and associated claims and causes of action, whether now +known or unknown (including existing as well as future claims and causes of +action), in the Work (i) in all territories worldwide, (ii) for the maximum +duration provided by applicable law or treaty (including future time +extensions), (iii) in any current or future medium and for any number of +copies, and (iv) for any purpose whatsoever, including without limitation +commercial, advertising or promotional purposes (the “Waiver”). Affirmer makes +the Waiver for the benefit of each member of the public at large and to the +detriment of Affirmer’s heirs and successors, fully intending that such Waiver +shall not be subject to revocation, rescission, cancellation, termination, or +any other legal or equitable action to disrupt the quiet enjoyment of the Work +by the public as contemplated by Affirmer’s express Statement of Purpose. + +3. Public License Fallback. Should any part of the Waiver for any reason be +judged legally invalid or ineffective under applicable law, then the Waiver +shall be preserved to the maximum extent permitted taking into account +Affirmer’s express Statement of Purpose. In addition, to the extent the Waiver +is so judged Affirmer hereby grants to each affected person a royalty-free, non +transferable, non sublicensable, non exclusive, irrevocable and unconditional +license to exercise Affirmer’s Copyright and Related Rights in the Work (i) in +all territories worldwide, (ii) for the maximum duration provided by applicable +law or treaty (including future time extensions), (iii) in any current or +future medium and for any number of copies, and (iv) for any purpose +whatsoever, including without limitation commercial, advertising or promotional +purposes (the “License”). The License shall be deemed effective as of the date +CC0 was applied by Affirmer to the Work. Should any part of the License for any +reason be judged legally invalid or ineffective under applicable law, such +partial invalidity or ineffectiveness shall not invalidate the remainder of the +License, and in such case Affirmer hereby affirms that he or she will not (i) +exercise any of his or her remaining Copyright and Related Rights in the Work +or (ii) assert any associated claims and causes of action with respect to the +Work, in either case contrary to Affirmer’s express Statement of Purpose. + +4. Limitations and Disclaimers. + 1. No trademark or patent rights held by Affirmer are waived, abandoned, + surrendered, licensed or otherwise affected by this document. + 2. Affirmer offers the Work as-is and makes no representations or + warranties of any kind concerning the Work, express, implied, statutory + or otherwise, including without limitation warranties of title, + merchantability, fitness for a particular purpose, non infringement, or + the absence of latent or other defects, accuracy, or the present or + absence of errors, whether or not discoverable, all to the greatest + extent permissible under applicable law. + 3. Affirmer disclaims responsibility for clearing rights of other persons + that may apply to the Work or any use thereof, including without + limitation any person’s Copyright and Related Rights in the Work. + Further, Affirmer disclaims responsibility for obtaining any necessary + consents, permissions or other rights required for any use of the Work. + 4. Affirmer understands and acknowledges that Creative Commons is not a + party to this document and has no duty or obligation with respect to + this CC0 or use of the Work. + +For more information, please see +http://creativecommons.org/publicdomain/zero/1.0/. diff --git a/README.md b/README.md new file mode 100644 index 0000000000..8b8c13ee76 --- /dev/null +++ b/README.md @@ -0,0 +1,120 @@ +# PostCSS Normalize [PostCSS Logo][postcss] + +[![NPM Version][npm-img]][npm-url] +[![Build Status][cli-img]][cli-url] +[![Licensing][lic-img]][lic-url] +[![Changelog][log-img]][log-url] +[![Gitter Chat][git-img]][git-url] + +[PostCSS Normalize] lets you automatically include the parts of [normalize.css] +you need, based upon your project’s [browserlist]. + +## Usage + +Add [PostCSS Normalize] to your build tool: + +```bash +npm install postcss-normalize --save-dev +``` + +Add a [browserlist] entry in your package.json: + +```json +{ + "browserslist": "last 2 versions" +} +``` + +#### Node + +Use [PostCSS Normalize] to process your CSS: + +```js +require('postcss-normalize').process(YOUR_CSS, { /* options */ }); +``` + +#### PostCSS + +Add [PostCSS] to your build tool: + +```bash +npm install postcss --save-dev +``` + +Use [PostCSS Normalize] as a plugin: + +```js +postcss([ + require('postcss-normalize')({ /* options */ }) +]).process(YOUR_CSS, /* options */); +``` + +#### Gulp + +Add [Gulp PostCSS] to your build tool: + +```bash +npm install gulp-postcss --save-dev +``` + +Use [PostCSS Normalize] in your Gulpfile: + +```js +var postcss = require('gulp-postcss'); + +gulp.task('css', function () { + return gulp.src('./src/*.css').pipe( + postcss([ + require('postcss-normalize')({ /* options */ }) + ]) + ).pipe( + gulp.dest('.') + ); +}); +``` + +#### Grunt + +Add [Grunt PostCSS] to your build tool: + +```bash +npm install grunt-postcss --save-dev +``` + +Use [PostCSS Normalize] in your Gruntfile: + +```js +grunt.loadNpmTasks('grunt-postcss'); + +grunt.initConfig({ + postcss: { + options: { + use: [ + require('postcss-normalize')({ /* options */ }) + ] + }, + dist: { + src: '*.css' + } + } +}); +``` + +[npm-url]: https://www.npmjs.com/package/postcss-normalize +[npm-img]: https://img.shields.io/npm/v/postcss-normalize.svg +[cli-url]: https://travis-ci.org/jonathantneal/postcss-normalize +[cli-img]: https://img.shields.io/travis/jonathantneal/postcss-normalize.svg +[lic-url]: LICENSE.md +[lic-img]: https://img.shields.io/npm/l/postcss-normalize.svg +[log-url]: CHANGELOG.md +[log-img]: https://img.shields.io/badge/changelog-md-blue.svg +[git-url]: https://gitter.im/postcss/postcss +[git-img]: https://img.shields.io/badge/chat-gitter-blue.svg + +[PostCSS Normalize]: https://github.com/jonathantneal/postcss-normalize +[PostCSS]: https://github.com/postcss/postcss +[Gulp PostCSS]: https://github.com/postcss/gulp-postcss +[Grunt PostCSS]: https://github.com/nDmitry/grunt-postcss + +[browserlist]: http://browserl.ist/ +[normalize.css]: https://github.com/jonathantneal/normalize.css diff --git a/index.js b/index.js new file mode 100644 index 0000000000..3e36ee2404 --- /dev/null +++ b/index.js @@ -0,0 +1,44 @@ +// tooling +const browserslist = require('browserslist'); +const jsonToAst = require('./lib/json-to-ast'); +const normalizeJSON = require('./lib/normalize.json'); +const postcss = require('postcss'); + +// plugin +module.exports = postcss.plugin('postcss-normalize', ({ browsers } = {}) => { + const normalizeAST = jsonToAst(normalizeJSON); + + return (root) => { + // client browser list + const clientBrowserList = browserslist(browsers, { + path: root.source && root.source.input && root.source.input.file + }); + + // required normalize rules + const normalizeRules = normalizeAST.nodes.filter( + (rule) => { + // required normalize declarations + rule.nodes = rule.nodes.filter( + (decl) => { + // whether the declaration browser list matches the client browser list + const declIsUsed = clientBrowserList.some( + (clientBrowser) => browserslist(decl.browserList).some( + (declBrowser) => declBrowser === clientBrowser + ) + ); + + // restore source mapping + decl.source.input = normalizeJSON.source.input; + + return declIsUsed; + } + ); + + return rule.nodes.length; + } + ); + + // prepend required normalize rules + root.prepend(normalizeRules); + }; +}); diff --git a/lib/json-to-ast.js b/lib/json-to-ast.js new file mode 100644 index 0000000000..73deb2371c --- /dev/null +++ b/lib/json-to-ast.js @@ -0,0 +1,14 @@ +// tooling +const postcss = require('postcss'); + +// convert a json object into a postcss object +module.exports = (json) => { + // if the object has a nodes array + if (Array.isArray(json.nodes)) { + // convert the objects in that array into postcss objects + json.nodes = json.nodes.map(module.exports); + } + + // return the current object into a postcss object + return json.type in postcss ? postcss[json.type](json) : null; +}; diff --git a/lib/normalize-browser-list.json b/lib/normalize-browser-list.json new file mode 100644 index 0000000000..97e739fe7b --- /dev/null +++ b/lib/normalize-browser-list.json @@ -0,0 +1,72 @@ +[ + ["> 0%"], + ["ie > 0"], + ["ios > 0"], + ["ie <= 9"], + ["chrome > 0", "ff > 0", "safari > 0"], + ["chrome > 0", "ff > 0", "safari > 0"], + ["ie <= 9"], + ["ie > 0"], + ["ie <= 8"], + ["ff > 0"], + ["ff > 0"], + ["edge > 0", "ie > 0"], + ["> 0%"], + ["> 0%"], + ["ie <= 10"], + ["ios > 0", "safari > 0"], + ["chrome <= 57", "ff <= 39"], + ["chrome > 0", "edge > 0", "ie > 0", "opera > 0", "safari > 0"], + ["chrome > 0", "edge > 0", "ie > 0", "opera > 0", "safari > 0"], + ["safari <= 6"], + ["chrome > 0", "edge > 0", "safari > 0"], + ["> 0%"], + ["> 0%"], + ["android <= 4.3"], + ["ie <= 9"], + ["ie <= 9"], + ["> 0%"], + ["> 0%"], + ["> 0%"], + ["> 0%"], + ["> 0%"], + ["> 0%"], + ["> 0%"], + ["ie <= 9"], + ["ios <= 7"], + ["ios <= 7"], + ["ie <= 10"], + ["ie > 0"], + ["ff > 0", "safari > 0"], + ["edge > 0", "ie > 0"], + ["edge > 0", "ff > 0", "ie > 0"], + ["ios > 0", "safari > 0"], + ["android <= 4"], + ["ff > 0"], + ["ff > 0"], + ["ff > 0"], + ["ff > 0"], + ["edge > 0", "ie > 0"], + ["edge > 0", "ie > 0"], + ["edge > 0", "ie > 0"], + ["edge > 0", "ie > 0"], + ["edge > 0", "ie > 0"], + ["edge > 0", "ie > 0"], + ["ie <= 9"], + ["chrome > 0", "ff > 0", "opera > 0"], + ["ie > 0"], + ["ie <= 10"], + ["ie <= 10"], + ["chrome > 0"], + ["chrome > 0", "safari > 0"], + ["safari > 0"], + ["chrome > 0", "safari > 0"], + ["ios > 0", "safari > 0"], + ["safari > 0"], + ["edge > 0", "ie > 0", "ff > 0"], + ["ie <= 9"], + ["> 0%"], + ["ie <= 9"], + ["ie > 0"], + ["ie <= 10"] +] diff --git a/lib/normalize-css-to-json.js b/lib/normalize-css-to-json.js new file mode 100644 index 0000000000..65478e07ed --- /dev/null +++ b/lib/normalize-css-to-json.js @@ -0,0 +1,74 @@ +// tooling +const fs = require('fse'); +const path = require('path'); +const postcss = require('postcss'); +const normalizeBrowserList = require('./normalize-browser-list.json'); + +// paths to normalize.css and normalize.json +const pathToNormalizeCSS = path.resolve(__dirname, 'normalize.css'); +const pathToNormalizeJSON = path.resolve(__dirname, 'normalize.json'); + +Promise.resolve().then( + // parse normalize.css + () => fs.readFile(pathToNormalizeCSS, 'utf8').then( + (normalizeCSS) => postcss.parse( + normalizeCSS, + { + from: pathToNormalizeCSS + } + ) + ) +).then( + // add browserlist to each declaration + (normalizeAST) => { + // preserve sourcemap + const sourceInput = { + css: normalizeAST.source.input.css, + file: 'https://jonathantneal.github.io/normalize.css/6.0.0/normalize.css' + }; + + // filter rules + let normalizeBrowserListIndex = -1; + + normalizeAST.nodes = normalizeAST.nodes.filter( + (node) => node.type === 'rule' + ).filter( + (rule) => { + // filter declarations + rule.nodes = rule.nodes.filter( + (node) => node.type === 'decl' + ).map( + (decl) => { + // copy raw browserlist + decl.browserList = normalizeBrowserList[++normalizeBrowserListIndex]; + + // clear raws and input + delete decl.raws; + + decl.source.input = {}; + + return decl; + } + ); + + // clear raws and input + delete rule.raws; + + rule.source.input = {}; + + return rule; + } + ); + + // preserve sourcemap + normalizeAST.source.input = sourceInput; + + return normalizeAST; + } +).then( + // stringify json + (json) => JSON.stringify(json) +).then( + // write stringified json + (json) => fs.writeFile(pathToNormalizeJSON, json) +); diff --git a/lib/normalize.css b/lib/normalize.css new file mode 100644 index 0000000000..0e1d3e6164 --- /dev/null +++ b/lib/normalize.css @@ -0,0 +1,454 @@ +/*! normalize.css v6.0.0 | MIT License | github.com/jonathantneal/normalize.css */ + +/* Document + ========================================================================== */ + +/** + * 1. Correct the line height in all browsers. + * 2. Prevent adjustments of font size after orientation changes in + * IE on Windows Phone and in iOS. + */ + +html { + line-height: 1.15; /* 1 */ + -ms-text-size-adjust: 100%; /* 2 */ + -webkit-text-size-adjust: 100%; /* 2 */ +} + +/* Sections + ========================================================================== */ + +/** + * Add the correct display in IE 9-. + */ + +article, +aside, +footer, +header, +nav, +section { + display: block; +} + +/** + * Correct the font size and margin on `h1` elements within `section` and + * `article` contexts in Chrome, Firefox, and Safari. + */ + +h1 { + font-size: 2em; + margin: 0.67em 0; +} + +/* Grouping content + ========================================================================== */ + +/** + * Add the correct display in IE 9-. + */ + +figcaption, +figure { + display: block; +} + +/** + * Add the correct display in IE. + */ + +main { + display: block; +} + +/** + * Add the correct margin in IE 8. + */ + +figure { + margin: 1em 40px; +} + +/** + * 1. Add the correct box sizing in Firefox. + * 2. Show the overflow in Edge and IE. + */ + +hr { + box-sizing: content-box; /* 1 */ + height: 0; /* 1 */ + overflow: visible; /* 2 */ +} + +/** + * 1. Correct the inheritance and scaling of font size in all browsers. + * 2. Correct the odd `em` font sizing in all browsers. + */ + +pre { + font-family: monospace, monospace; /* 1 */ + font-size: 1em; /* 2 */ +} + +/* Text-level semantics + ========================================================================== */ + +/** + * 1. Remove the gray background on active links in IE 10. + * 2. Remove gaps in links underline in iOS 8+ and Safari 8+. + */ + +a { + background-color: transparent; /* 1 */ + -webkit-text-decoration-skip: objects; /* 2 */ +} + +/** + * 1. Remove the bottom border in Chrome 57- and Firefox 39-. + * 2. Add the correct text decoration in Chrome, Edge, IE, Opera, and Safari. + */ + +abbr[title] { + border-bottom: none; /* 1 */ + text-decoration: underline; /* 2 */ + text-decoration: underline dotted; /* 2 */ +} + +/** + * Prevent the duplicate application of `bolder` by the next rule in Safari 6. + */ + +b, +strong { + font-weight: inherit; +} + +/** + * Add the correct font weight in Chrome, Edge, and Safari. + */ + +b, +strong { + font-weight: bolder; +} + +/** + * 1. Correct the inheritance and scaling of font size in all browsers. + * 2. Correct the odd `em` font sizing in all browsers. + */ + +code, +kbd, +samp { + font-family: monospace, monospace; /* 1 */ + font-size: 1em; /* 2 */ +} + +/** + * Add the correct font style in Android 4.3-. + */ + +dfn { + font-style: italic; +} + +/** + * Add the correct background and color in IE 9-. + */ + +mark { + background-color: #ff0; + color: #000; +} + +/** + * Add the correct font size in all browsers. + */ + +small { + font-size: 80%; +} + +/** + * Prevent `sub` and `sup` elements from affecting the line height in + * all browsers. + */ + +sub, +sup { + font-size: 75%; + line-height: 0; + position: relative; + vertical-align: baseline; +} + +sub { + bottom: -0.25em; +} + +sup { + top: -0.5em; +} + +/* Embedded content + ========================================================================== */ + +/** + * Add the correct display in IE 9-. + */ + +audio, +video { + display: inline-block; +} + +/** + * Add the correct display in iOS 4-7. + */ + +audio:not([controls]) { + display: none; + height: 0; +} + +/** + * Remove the border on images inside links in IE 10-. + */ + +img { + border-style: none; +} + +/** + * Hide the overflow in IE. + */ + +svg:not(:root) { + overflow: hidden; +} + +/* Forms + ========================================================================== */ + +/** + * Remove the margin in Firefox and Safari. + */ + +button, +input, +optgroup, +select, +textarea { + margin: 0; +} + +/** + * Show the overflow in IE. + * 1. Show the overflow in Edge. + */ + +button, +input { /* 1 */ + overflow: visible; +} + +/** + * Remove the inheritance of text transform in Edge, Firefox, and IE. + * 1. Remove the inheritance of text transform in Firefox. + */ + +button, +select { /* 1 */ + text-transform: none; +} + +/** + * Correct the inability to style clickable types in iOS and Safari. + */ + +button, +[type="button"], +[type="reset"], +[type="submit"] { + -webkit-appearance: button; +} + +/** + * Prevent a WebKit bug where (2) destroys native `audio` and `video` controls + * in Android 4. + */ + +html [type="button"] { + -webkit-appearance: button; +} + +/** + * Remove the inner border and padding in Firefox. + */ + +button::-moz-focus-inner, +[type="button"]::-moz-focus-inner, +[type="reset"]::-moz-focus-inner, +[type="submit"]::-moz-focus-inner { + border-style: none; + padding: 0; +} + +/** + * Restore the focus styles unset by the previous rule. + */ + +button:-moz-focusring, +[type="button"]:-moz-focusring, +[type="reset"]:-moz-focusring, +[type="submit"]:-moz-focusring { + outline: 1px dotted ButtonText; +} + +/** + * Correct the padding in Firefox. + */ + +fieldset { + padding: 0.35em 0.75em 0.625em; +} + +/** + * 1. Correct the text wrapping in Edge and IE. + * 2. Correct the color inheritance from `fieldset` elements in IE. + * 3. Remove the padding so developers are not caught out when they zero out + * `fieldset` elements in all browsers. + */ + +legend { + box-sizing: border-box; /* 1 */ + color: inherit; /* 2 */ + display: table; /* 1 */ + max-width: 100%; /* 1 */ + padding: 0; /* 3 */ + white-space: normal; /* 1 */ +} + +/** + * 1. Add the correct display in IE 9-. + * 2. Add the correct vertical alignment in Chrome, Firefox, and Opera. + */ + +progress { + display: inline-block; /* 1 */ + vertical-align: baseline; /* 2 */ +} + +/** + * Remove the default vertical scrollbar in IE. + */ + +textarea { + overflow: auto; +} + +/** + * 1. Add the correct box sizing in IE 10-. + * 2. Remove the padding in IE 10-. + */ + +[type="checkbox"], +[type="radio"] { + box-sizing: border-box; /* 1 */ + padding: 0; /* 2 */ +} + +/** + * Correct the cursor style of increment and decrement buttons in Chrome. + */ + +[type="number"]::-webkit-inner-spin-button, +[type="number"]::-webkit-outer-spin-button { + height: auto; +} + +/** + * 1. Correct the odd appearance in Chrome and Safari. + * 2. Correct the outline style in Safari. + */ + +[type="search"] { + -webkit-appearance: textfield; /* 1 */ + outline-offset: -2px; /* 2 */ +} + +/** + * Remove the inner padding and cancel buttons in Chrome and Safari on macOS. + */ + +[type="search"]::-webkit-search-cancel-button, +[type="search"]::-webkit-search-decoration { + -webkit-appearance: none; +} + +/** + * 1. Correct the inability to style clickable types in iOS and Safari. + * 2. Change font properties to `inherit` in Safari. + */ + +::-webkit-file-upload-button { + -webkit-appearance: button; /* 1 */ + font: inherit; /* 2 */ +} + +/* Interactive + ========================================================================== */ + +/* + * Add the correct display in Edge, IE, and Firefox. + */ + +details { + display: block; +} + +/* + * Add the correct display in IE 9-. + */ + +menu { + display: block; +} + +/* + * Add the correct display in all browsers. + */ + +summary { + display: list-item; +} + +/* Scripting + ========================================================================== */ + +/** + * Add the correct display in IE 9-. + */ + +canvas { + display: inline-block; +} + +/** + * Add the correct display in IE. + */ + +template { + display: none; +} + +/* Hidden + ========================================================================== */ + +/** + * Add the correct display in IE 10-. + */ + +[hidden] { + display: none; +} diff --git a/package.json b/package.json new file mode 100644 index 0000000000..322e5fb087 --- /dev/null +++ b/package.json @@ -0,0 +1,54 @@ +{ + "name": "postcss-normalize", + "version": "1.0.0", + "description": "Use the parts of normalize.css you need from your browserlist", + "author": "Jonathan Neal ", + "license": "CC0-1.0", + "repository": "jonathantneal/postcss-normalize", + "homepage": "https://github.com/jonathantneal/postcss-normalize#readme", + "bugs": "https://github.com/jonathantneal/postcss-normalize/issues", + "main": "index.js", + "files": [ + "index.js", + "lib/json-to-ast.js", + "lib/normalize.json" + ], + "scripts": { + "clean": "git clean -X -d -f", + "prepublish": "npm test", + "test": "echo 'Running tests...'; npm run test:setup && npm run test:js && npm run test:tape", + "test:js": "eslint *.js --cache --ignore-pattern .gitignore", + "test:setup": "node lib/normalize-css-to-json", + "test:tape": "postcss-tape" + }, + "engines": { + "node": ">=6.5.0" + }, + "dependencies": { + "browserslist": "^2.1.1", + "postcss": "^5.2.17" + }, + "devDependencies": { + "eslint": "^3.19.0", + "eslint-config-dev": "2.0.0", + "fse": "^2.0.0", + "postcss-tape": "1.3.1", + "pre-commit": "^1.2.2" + }, + "eslintConfig": { + "extends": "dev" + }, + "keywords": [ + "postcss", + "css", + "postcss-plugin", + "normalize.css", + "normalize", + "browsers", + "bugs", + "fixes", + "usability", + "browserslist", + "browserlist" + ] +} diff --git a/test/basic.css b/test/basic.css new file mode 100644 index 0000000000..a326381313 --- /dev/null +++ b/test/basic.css @@ -0,0 +1,3 @@ +body { + font-family: sans-serif; +} diff --git a/test/basic.expect.css b/test/basic.expect.css new file mode 100644 index 0000000000..4733f8ab42 --- /dev/null +++ b/test/basic.expect.css @@ -0,0 +1,93 @@ +html {line-height: 1.15;-ms-text-size-adjust: 100%;-webkit-text-size-adjust: 100%; +} +h1 {font-size: 2em;margin: 0.67em 0; +} +main {display: block; +} +hr {box-sizing: content-box;height: 0;overflow: visible; +} +pre {font-family: monospace, monospace;font-size: 1em; +} +a {background-color: transparent;-webkit-text-decoration-skip: objects; +} +abbr[title] {border-bottom: none;text-decoration: underline;text-decoration: underline dotted; +} +b, +strong {font-weight: bolder; +} +code, +kbd, +samp {font-family: monospace, monospace;font-size: 1em; +} +small {font-size: 80%; +} +sub, +sup {font-size: 75%;line-height: 0;position: relative;vertical-align: baseline; +} +sub {bottom: -0.25em; +} +sup {top: -0.5em; +} +img {border-style: none; +} +svg:not(:root) {overflow: hidden; +} +button, +input, +optgroup, +select, +textarea {margin: 0; +} +button, +input {overflow: visible; +} +button, +select {text-transform: none; +} +button, +[type="button"], +[type="reset"], +[type="submit"] {-webkit-appearance: button; +} +button::-moz-focus-inner, +[type="button"]::-moz-focus-inner, +[type="reset"]::-moz-focus-inner, +[type="submit"]::-moz-focus-inner {border-style: none;padding: 0; +} +button:-moz-focusring, +[type="button"]:-moz-focusring, +[type="reset"]:-moz-focusring, +[type="submit"]:-moz-focusring {outline: 1px dotted ButtonText; +} +fieldset {padding: 0.35em 0.75em 0.625em; +} +legend {box-sizing: border-box;color: inherit;display: table;max-width: 100%;padding: 0;white-space: normal; +} +progress {vertical-align: baseline; +} +textarea {overflow: auto; +} +[type="checkbox"], +[type="radio"] {box-sizing: border-box;padding: 0; +} +[type="number"]::-webkit-inner-spin-button, +[type="number"]::-webkit-outer-spin-button {height: auto; +} +[type="search"] {-webkit-appearance: textfield;outline-offset: -2px; +} +[type="search"]::-webkit-search-cancel-button, +[type="search"]::-webkit-search-decoration {-webkit-appearance: none; +} +::-webkit-file-upload-button {-webkit-appearance: button;font: inherit; +} +details {display: block; +} +summary {display: list-item; +} +template {display: none; +} +[hidden] {display: none; +} +body { + font-family: sans-serif; +} diff --git a/test/basic.last-1.expect.css b/test/basic.last-1.expect.css new file mode 100644 index 0000000000..0d056f3d64 --- /dev/null +++ b/test/basic.last-1.expect.css @@ -0,0 +1,86 @@ +html {line-height: 1.15;-ms-text-size-adjust: 100%;-webkit-text-size-adjust: 100%; +} +h1 {font-size: 2em;margin: 0.67em 0; +} +main {display: block; +} +hr {box-sizing: content-box;height: 0;overflow: visible; +} +pre {font-family: monospace, monospace;font-size: 1em; +} +a {-webkit-text-decoration-skip: objects; +} +abbr[title] {text-decoration: underline;text-decoration: underline dotted; +} +b, +strong {font-weight: bolder; +} +code, +kbd, +samp {font-family: monospace, monospace;font-size: 1em; +} +small {font-size: 80%; +} +sub, +sup {font-size: 75%;line-height: 0;position: relative;vertical-align: baseline; +} +sub {bottom: -0.25em; +} +sup {top: -0.5em; +} +svg:not(:root) {overflow: hidden; +} +button, +input, +optgroup, +select, +textarea {margin: 0; +} +button, +input {overflow: visible; +} +button, +select {text-transform: none; +} +button, +[type="button"], +[type="reset"], +[type="submit"] {-webkit-appearance: button; +} +button::-moz-focus-inner, +[type="button"]::-moz-focus-inner, +[type="reset"]::-moz-focus-inner, +[type="submit"]::-moz-focus-inner {border-style: none;padding: 0; +} +button:-moz-focusring, +[type="button"]:-moz-focusring, +[type="reset"]:-moz-focusring, +[type="submit"]:-moz-focusring {outline: 1px dotted ButtonText; +} +fieldset {padding: 0.35em 0.75em 0.625em; +} +legend {box-sizing: border-box;color: inherit;display: table;max-width: 100%;padding: 0;white-space: normal; +} +progress {vertical-align: baseline; +} +textarea {overflow: auto; +} +[type="number"]::-webkit-inner-spin-button, +[type="number"]::-webkit-outer-spin-button {height: auto; +} +[type="search"] {-webkit-appearance: textfield;outline-offset: -2px; +} +[type="search"]::-webkit-search-cancel-button, +[type="search"]::-webkit-search-decoration {-webkit-appearance: none; +} +::-webkit-file-upload-button {-webkit-appearance: button;font: inherit; +} +details {display: block; +} +summary {display: list-item; +} +template {display: none; +} +body { + font-family: sans-serif; +} diff --git a/test/basic.last-2.expect.css b/test/basic.last-2.expect.css new file mode 100644 index 0000000000..4733f8ab42 --- /dev/null +++ b/test/basic.last-2.expect.css @@ -0,0 +1,93 @@ +html {line-height: 1.15;-ms-text-size-adjust: 100%;-webkit-text-size-adjust: 100%; +} +h1 {font-size: 2em;margin: 0.67em 0; +} +main {display: block; +} +hr {box-sizing: content-box;height: 0;overflow: visible; +} +pre {font-family: monospace, monospace;font-size: 1em; +} +a {background-color: transparent;-webkit-text-decoration-skip: objects; +} +abbr[title] {border-bottom: none;text-decoration: underline;text-decoration: underline dotted; +} +b, +strong {font-weight: bolder; +} +code, +kbd, +samp {font-family: monospace, monospace;font-size: 1em; +} +small {font-size: 80%; +} +sub, +sup {font-size: 75%;line-height: 0;position: relative;vertical-align: baseline; +} +sub {bottom: -0.25em; +} +sup {top: -0.5em; +} +img {border-style: none; +} +svg:not(:root) {overflow: hidden; +} +button, +input, +optgroup, +select, +textarea {margin: 0; +} +button, +input {overflow: visible; +} +button, +select {text-transform: none; +} +button, +[type="button"], +[type="reset"], +[type="submit"] {-webkit-appearance: button; +} +button::-moz-focus-inner, +[type="button"]::-moz-focus-inner, +[type="reset"]::-moz-focus-inner, +[type="submit"]::-moz-focus-inner {border-style: none;padding: 0; +} +button:-moz-focusring, +[type="button"]:-moz-focusring, +[type="reset"]:-moz-focusring, +[type="submit"]:-moz-focusring {outline: 1px dotted ButtonText; +} +fieldset {padding: 0.35em 0.75em 0.625em; +} +legend {box-sizing: border-box;color: inherit;display: table;max-width: 100%;padding: 0;white-space: normal; +} +progress {vertical-align: baseline; +} +textarea {overflow: auto; +} +[type="checkbox"], +[type="radio"] {box-sizing: border-box;padding: 0; +} +[type="number"]::-webkit-inner-spin-button, +[type="number"]::-webkit-outer-spin-button {height: auto; +} +[type="search"] {-webkit-appearance: textfield;outline-offset: -2px; +} +[type="search"]::-webkit-search-cancel-button, +[type="search"]::-webkit-search-decoration {-webkit-appearance: none; +} +::-webkit-file-upload-button {-webkit-appearance: button;font: inherit; +} +details {display: block; +} +summary {display: list-item; +} +template {display: none; +} +[hidden] {display: none; +} +body { + font-family: sans-serif; +} From 87f2c08c20cafcdd3aa99a3a285ee1ebe4f99760 Mon Sep 17 00:00:00 2001 From: Tom Bremer Date: Sat, 6 May 2017 10:40:53 -0500 Subject: [PATCH 405/795] remove-empty-rules initial push (#23) --- index.js | 14 ++++++++++++++ test.js | 3 +++ test/empty.css | 26 ++++++++++++++++++++++++++ test/empty.expect.css | 23 +++++++++++++++++++++++ test/media.expect.css | 12 ------------ 5 files changed, 66 insertions(+), 12 deletions(-) create mode 100644 test/empty.css create mode 100644 test/empty.expect.css diff --git a/index.js b/index.js index eef9b5af80..e0a2cd9736 100644 --- a/index.js +++ b/index.js @@ -81,6 +81,20 @@ module.exports = postcss.plugin('postcss-nesting', function (opts) { rule.insertAfterNode = target; } } + + if (!rule.nodes.length) { + rule.remove(); + } else { + rule.nodes.forEach(function (n) { + var isRuleOrAtRule = (/rule$/).test(n.type); + + if (!isRuleOrAtRule || n.nodes.length) { + return; + } + + n.remove(); + }); + } }); }; }); diff --git a/test.js b/test.js index 7f57984ca5..cc99402fe4 100644 --- a/test.js +++ b/test.js @@ -11,6 +11,9 @@ var tests = { }, 'media': { message: 'supports nested media queries' + }, + 'empty': { + message: 'ensure empty rules are removed' } } }; diff --git a/test/empty.css b/test/empty.css new file mode 100644 index 0000000000..85fd7b54da --- /dev/null +++ b/test/empty.css @@ -0,0 +1,26 @@ +a { + & b { + prop: val; + } + + & c { + prop: val; + } +} + +d { + @nest & e { + prop: val; + + @nest & f { + prop: val; + } + } +} + +g { + prop: val; + & h { + prop: val + } +} diff --git a/test/empty.expect.css b/test/empty.expect.css new file mode 100644 index 0000000000..5482c0940e --- /dev/null +++ b/test/empty.expect.css @@ -0,0 +1,23 @@ +a b { + prop: val +} + +a c { + prop: val +} + +d e { + prop: val +} + +d e f { + prop: val +} + +g { + prop: val +} + +g h { + prop: val +} diff --git a/test/media.expect.css b/test/media.expect.css index 05858b3cf1..2686f9ffe3 100644 --- a/test/media.expect.css +++ b/test/media.expect.css @@ -7,9 +7,6 @@ .main { color: white } - - .main .child { -} } @media (min-width: 100px) and (max-width: 200px) { @@ -26,15 +23,6 @@ } } -.main { -} - -@media screen, print and speech { - - .main { -} - } - @media screen and (max-width: 300px), screen and (min-aspect-ratio: 16/9), print and speech and (max-width: 300px), print and speech and (min-aspect-ratio: 16/9) { .main { From c260886eaf53a4d540f8a87be16c097f925df697 Mon Sep 17 00:00:00 2001 From: semigradsky Date: Tue, 9 May 2017 17:36:56 +0300 Subject: [PATCH 406/795] Update dependencies --- .babelrc | 8 +++++++- .eslintignore | 2 +- .eslintrc => .eslintrc.yml | 16 ++++------------ .gitignore | 1 + .travis.yml | 4 ++++ package.json | 23 ++++++++++++----------- test/index.js | 4 ++-- 7 files changed, 31 insertions(+), 27 deletions(-) rename .eslintrc => .eslintrc.yml (78%) diff --git a/.babelrc b/.babelrc index b0b9a96ef0..f0ab75d429 100644 --- a/.babelrc +++ b/.babelrc @@ -1,3 +1,9 @@ { - "stage": 0 + "presets": [ + ["env", { + "targets": { + "node": 4 + } + }] + ] } diff --git a/.eslintignore b/.eslintignore index 3e4e48b0b5..1521c8b765 120000 --- a/.eslintignore +++ b/.eslintignore @@ -1 +1 @@ -.gitignore \ No newline at end of file +dist diff --git a/.eslintrc b/.eslintrc.yml similarity index 78% rename from .eslintrc rename to .eslintrc.yml index db21f05621..ec22acd0a3 100644 --- a/.eslintrc +++ b/.eslintrc.yml @@ -1,17 +1,9 @@ ---- -# babel support more syntax stuff than eslint for now -parser: babel-eslint - root: true extends: eslint:recommended -ecmaFeatures: - modules: true - -env: - es6: true - browser: true - node: true +parserOptions: + ecmaVersion: 6 + sourceType: "module" rules: indent: [2, 2] # 2 spaces indentation @@ -35,7 +27,7 @@ rules: computed-property-spacing: [2, "never"] space-unary-ops: [2, {"words": true, "nonwords": false}] - space-after-keywords: [2, "always"] + keyword-spacing: [2, {"before": true, "after": true}] space-before-blocks: [2, "always"] space-before-function-paren: [2, "never"] space-in-parens: [2, "never"] diff --git a/.gitignore b/.gitignore index 1521c8b765..f06235c460 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,2 @@ +node_modules dist diff --git a/.travis.yml b/.travis.yml index 31e6113ac4..4c4eac6fc3 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,2 +1,6 @@ sudo: false language: node_js +node_js: + - "6" + - "4" + - "stable" diff --git a/package.json b/package.json index 3c2296d199..f9f9bd05fc 100644 --- a/package.json +++ b/package.json @@ -20,20 +20,21 @@ "dist" ], "dependencies": { - "balanced-match": "^0.2.0", - "postcss": "^5.0.0" + "balanced-match": "^0.4.2", + "postcss": "^6.0.1" }, "devDependencies": { - "babel": "^5.1.13", - "babel-eslint": "^3.1.15", - "babel-tape-runner": "^1.1.0", - "eslint": "^1.0.0", - "tape": "^4.0.0" + "babel-cli": "^6.24.1", + "babel-preset-env": "^1.4.0", + "babel-register": "^6.24.1", + "eslint": "^3.19.0", + "tape": "^4.6.3" }, "scripts": { - "lint": "eslint .", - "tape": "babel-tape-runner 'test/*.js'", - "test": "npm run lint && npm run tape", - "prepublish": "babel src --out-dir dist" + "lint": "eslint *.js ./src/ ./test/", + "tape": "tape -r babel-register test/*.js", + "test": "npm run lint && npm run babelify && npm run tape", + "babelify": "babel src --out-dir dist", + "prepublish": "npm run babelify" } } diff --git a/test/index.js b/test/index.js index 727878635f..cd145e6d60 100644 --- a/test/index.js +++ b/test/index.js @@ -72,8 +72,8 @@ tape("postcss-selector-not", t => { ) t.equal( - transform(`.foo:not(:hover, :focus)::before {}`), - `.foo:not(:hover):not(:focus)::before {}`, + transform(".foo:not(:hover, :focus)::before {}"), + ".foo:not(:hover):not(:focus)::before {}", "should work with something after :not()" ) From 2ae0263b0cfe22fb0cb288c45bf4088308983187 Mon Sep 17 00:00:00 2001 From: Jonathan Neal Date: Mon, 8 May 2017 15:43:54 -0400 Subject: [PATCH 407/795] 3.0.0 --- .eslintrc | 146 ------------------------------- .gitignore | 9 +- .jscsrc | 102 --------------------- .npmignore | 2 - .tape.js | 19 ++++ .travis.yml | 4 +- CHANGELOG.md | 37 +++++--- CONTRIBUTING.md | 10 ++- LICENSE.md | 107 ++++++++++++++++++++-- README.md | 134 +++++++--------------------- index.js | 134 +++++++--------------------- lib/clean-node.js | 6 ++ lib/merge-params.js | 9 ++ lib/merge-selectors.js | 12 +++ lib/transform-after-nodes.js | 18 ++++ lib/transform-bubbling-atrule.js | 52 +++++++++++ lib/transform-nesting-atrule.js | 43 +++++++++ lib/transform-nesting-rule.js | 29 ++++++ package.json | 65 ++++++++------ test.js | 78 ----------------- test/basic.css | 92 ++++--------------- test/basic.expect.css | 102 +++++---------------- test/direct.css | 93 ++++---------------- test/direct.expect.css | 107 ++++++---------------- test/empty.css | 42 +++++---- test/empty.expect.css | 39 +++++---- test/ignore.css | 19 ++-- test/ignore.expect.css | 19 ++-- test/media.css | 43 ++++++--- test/media.expect.css | 63 ++++++++----- 30 files changed, 649 insertions(+), 986 deletions(-) delete mode 100644 .eslintrc delete mode 100644 .jscsrc delete mode 100644 .npmignore create mode 100644 .tape.js create mode 100644 lib/clean-node.js create mode 100644 lib/merge-params.js create mode 100644 lib/merge-selectors.js create mode 100644 lib/transform-after-nodes.js create mode 100644 lib/transform-bubbling-atrule.js create mode 100644 lib/transform-nesting-atrule.js create mode 100644 lib/transform-nesting-rule.js delete mode 100644 test.js diff --git a/.eslintrc b/.eslintrc deleted file mode 100644 index ee0ecdd672..0000000000 --- a/.eslintrc +++ /dev/null @@ -1,146 +0,0 @@ -{ - "root": true, - "env": { - "browser": true, - "es6": true, - "node": true - }, - "rules": { - "accessor-pairs": [2], - "block-scoped-var": [2], - "callback-return": [2], - "complexity": [2, 20], - "consistent-return": [2], - "consistent-this": [2, "self"], - "constructor-super": [2], - "default-case": [2], - "eqeqeq": [2], - "global-require": [2], - "guard-for-in": [0], - "handle-callback-err": [2, "^err(or)?$"], - "id-length": [0], - "init-declarations": [2, "always"], - "max-depth": [2, 6], - "max-nested-callbacks": [0], - "max-params": [2, 3], - "max-statements": [0], - "new-cap": [2], - "new-parens": [2], - "no-alert": [2], - "no-array-constructor": [2], - "no-bitwise": [0], - "no-caller": [2], - "no-case-declarations": [2], - "no-catch-shadow": [2], - "no-class-assign": [2], - "no-cond-assign": [2], - "no-console": [2], - "no-const-assign": [2], - "no-constant-condition": [0], - "no-continue": [0], - "no-control-regex": [2], - "no-debugger": [2], - "no-delete-var": [2], - "no-div-regex": [0], - "no-dupe-args": [2], - "no-dupe-class-members": [2], - "no-dupe-keys": [2], - "no-duplicate-case": [2], - "no-else-return": [0], - "no-empty-character-class": [2], - "no-empty-pattern": [2], - "no-empty": [2], - "no-eq-null": [2], - "no-eval": [2], - "no-ex-assign": [2], - "no-extend-native": [0], - "no-extra-bind": [2], - "no-extra-boolean-cast": [2], - "no-extra-parens": [2], - "no-extra-semi": [2], - "no-fallthrough": [2], - "no-floating-decimal": [2], - "no-func-assign": [2], - "no-implicit-coercion": [2], - "no-implicit-globals": [0], - "no-implied-eval": [2], - "no-inline-comments": [0], - "no-inner-declarations": [2], - "no-invalid-regexp": [2], - "no-invalid-this": [0], - "no-irregular-whitespace": [2], - "no-iterator": [2], - "no-label-var": [2], - "no-labels": [0], - "no-lone-blocks": [2], - "no-lonely-if": [2], - "no-loop-func": [2], - "no-magic-numbers": [0], - "no-mixed-requires": [0], - "no-multi-str": [2], - "no-native-reassign": [2], - "no-negated-condition": [0], - "no-negated-in-lhs": [2], - "no-nested-ternary": [2], - "no-new-func": [0], - "no-new-object": [2], - "no-new-require": [0], - "no-new-wrappers": [2], - "no-new": [2], - "no-obj-calls": [2], - "no-octal-escape": [2], - "no-octal": [2], - "no-param-reassign": [0], - "no-path-concat": [2], - "no-plusplus": [0], - "no-process-env": [2], - "no-process-exit": [0], - "no-proto": [2], - "no-redeclare": [2], - "no-regex-spaces": [2], - "no-restricted-imports": [0], - "no-restricted-syntax": [0], - "no-return-assign": [2], - "no-script-url": [2], - "no-self-compare": [2], - "no-sequences": [2], - "no-shadow-restricted-names": [2], - "no-shadow": [2], - "no-sparse-arrays": [2], - "no-sync": [0], - "no-ternary": [0], - "no-this-before-super": [2], - "no-throw-literal": [2], - "no-undef-init": [2], - "no-undef": [2], - "no-undefined": [0], - "no-unneeded-ternary": [2], - "no-unreachable": [2], - "no-unused-expressions": [2], - "no-unused-vars": [2], - "no-use-before-define": [0], - "no-useless-call": [2], - "no-useless-concat": [2], - "no-var": [0], - "no-void": [0], - "no-with": [2], - "object-shorthand": [0], - "one-var": [0], - "operator-assignment": [2, "always"], - "prefer-arrow-callback": [0], - "prefer-const": [0], - "prefer-reflect": [0], - "prefer-rest-params": [0], - "prefer-spread": [0], - "prefer-template": [0], - "radix": [2, "as-needed"], - "require-yield": [0], - "strict": [0], - "use-isnan": [2], - "valid-typeof": [2], - "vars-on-top": [0], - "wrap-iife": [2, "any"], - "wrap-regex": [2], - "yoda": [0] - } -} diff --git a/.gitignore b/.gitignore index ef0a70e834..b8fc2cda3a 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,8 @@ node_modules -npm-debug.log -test/*.actual.css +.* +!.gitignore +!.tape.js +!.travis.yml +*.log* +*.result.css +package-lock.json diff --git a/.jscsrc b/.jscsrc deleted file mode 100644 index 66d97a3327..0000000000 --- a/.jscsrc +++ /dev/null @@ -1,102 +0,0 @@ -{ - "disallowKeywords": [ - "with" - ], - "disallowKeywordsOnNewLine": [ - "else" - ], - "disallowMultipleSpaces": false, - "disallowMixedSpacesAndTabs": true, - "disallowMultipleLineBreaks": true, - "disallowMultipleLineStrings": true, - "disallowMultipleVarDecl": true, - "disallowNewlineBeforeBlockStatements": true, - "disallowSpaceAfterObjectKeys": true, - "disallowSpaceAfterPrefixUnaryOperators": true, - "disallowSpacesInCallExpression": true, - "disallowSpacesInFunctionDeclaration": { - "beforeOpeningRoundBrace": true - }, - "disallowSpacesInsideArrayBrackets": "all", - "disallowSpacesInsideObjectBrackets": "all", - "disallowSpacesInsideParentheses": true, - "disallowTrailingWhitespace": true, - "maximumLineLength": null, - "requireCamelCaseOrUpperCaseIdentifiers": true, - "requireCapitalizedConstructors": true, - "requireCurlyBraces": [ - "if", - "else", - "for", - "while", - "do", - "try", - "catch" - ], - "requireDotNotation": true, - "requireLineFeedAtFileEnd": true, - "requireOperatorBeforeLineBreak": true, - "requireSemicolons": true, - "requireSpaceAfterBinaryOperators": true, - "requireSpaceAfterKeywords": [ - "if", - "else", - "for", - "while", - "do", - "switch", - "return", - "try", - "catch" - ], - "requireSpaceBeforeBinaryOperators": [ - "=", - "+=", - "-=", - "*=", - "/=", - "%=", - "<<=", - ">>=", - ">>>=", - "&=", - "|=", - "^=", - "+=", - "+", - "-", - "*", - "/", - "%", - "<<", - ">>", - ">>>", - "&", - "|", - "^", - "&&", - "||", - "===", - "==", - ">=", - "<=", - "<", - ">", - "!=", - "!==" - ], - "requireSpaceBeforeBlockStatements": true, - "requireSpaceBeforeObjectValues": true, - "requireSpacesInAnonymousFunctionExpression": { - "beforeOpeningCurlyBrace": true, - "beforeOpeningRoundBrace": true - }, - "requireSpacesInConditionalExpression": true, - "requireSpacesInForStatement": true, - "requireSpacesInFunctionDeclaration": { - "beforeOpeningCurlyBrace": true - }, - "validateIndentation": "\t", - "validateParameterSeparator": ", ", - "validateQuoteMarks": "'" -} diff --git a/.npmignore b/.npmignore deleted file mode 100644 index 93f1361991..0000000000 --- a/.npmignore +++ /dev/null @@ -1,2 +0,0 @@ -node_modules -npm-debug.log diff --git a/.tape.js b/.tape.js new file mode 100644 index 0000000000..88def0a631 --- /dev/null +++ b/.tape.js @@ -0,0 +1,19 @@ +module.exports = { + 'postcss-nesting': { + 'basic': { + message: 'supports basic usage' + }, + 'direct': { + message: 'supports direct usage' + }, + 'empty': { + message: 'removes empty rules' + }, + 'ignore': { + message: 'ignores invalid entries' + }, + 'media': { + message: 'supports nested media' + } + } +}; diff --git a/.travis.yml b/.travis.yml index c8d066397a..85242354aa 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,5 +1,3 @@ -sudo: false language: node_js node_js: - - stable - - "0.12" + - 4 diff --git a/CHANGELOG.md b/CHANGELOG.md index 438eca3a59..d8a636dcf9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,13 @@ -## 2.3.1 (2016-03-16) +# Changes to PostCSS Nesting + +### 3.0.0 (May 8, 2017) + +- Added: Node 4.x support +- Added: PostCSS 6 support +- Added: Preserved ordering +- Removed: Node 0.12 support + +### 2.3.1 (March 16, 2016) - Updated: Allow any direct nesting that follows the syntactic constraints - Updated: PostCSS 5.0.6 @@ -6,69 +15,69 @@ - Updated: Dependencies - Updated: Project configuration -## 2.3.0 (2016-02-20) +### 2.3.0 (February 20, 2016) - Updated: JavaScript formatting, linting, tests, and documentation - Updated: Properly concatenate at-rules with or expressions - Updated: Update internal plugin name to postcss-nesting -## 2.2.0 (2016-01-30) +### 2.2.0 (January 30, 2016) - Added: Nesting of all at-rules - Updated: Direct nesting order maintains order - Updated: Tests and documentation -## 2.1.1 (2016-01-03) +### 2.1.1 (January 3, 2016) - Updated: Project conventions -## 2.1.0 (2016-01-03) +### 2.1.0 (January 3, 2016) - Added: Support for valid direct nesting -## 2.0.6 (2015-10-15) +### 2.0.6 (October 15, 2015) - Fixed: Issue with new PostCSS rules -## 2.0.5 (2015-10-12) +### 2.0.5 (October 12, 2015) - Updated: Nested rules source map to the parent rule - Updated: PostCSS 5.0.9 - Updated: Tests and documentation - Updated: Project configuration -## 2.0.4 (2015-09-23) +### 2.0.4 (September 23, 2015) - Updated: Map source raws -## 2.0.3 (2015-09-22) +### 2.0.3 (September 22, 2015) - Updated: Refactored plugin - Updated: Tests - Updated: PostCSS 5.0.6 -## 2.0.2 (2015-09-16) +### 2.0.2 (September 16, 2015) - Fixed: Issue where the new rule’s children were not mapped to the parent internally -## 2.0.1 (2015-09-16) +### 2.0.1 (September 16, 2015) - Fixed: Issue where a `@nest` rule followed by another bubbling at-rule would not bubble - Added: CONTRIBUTING.md -## 2.0.0 (2015-09-16) +### 2.0.0 (September 16, 2015) - Added: Requirement of `&` per the specification - Added: New prefix option - Added: `@document` and `@supports` as bubbles - Updated: Documentation -## 1.0.0 (2015-09-15) +### 1.0.0 (September 15, 2015) - Added: New `@nest` at-rule syntax - Updated: PostCSS 5 - Removed: Old inner bracket syntax -## 0.1.0 (2015-06-17) +### 0.1.0 (June 17, 2015) - Added: Initial release diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index ed4bd6063f..104bbe13ee 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,4 +1,7 @@ -You want to help? You rock! Now, take a moment to be sure your contributions make sense to everyone else. +# Contributing to PostCSS Nesting + +You want to help? You rock! Now, take a moment to be sure your contributions +make sense to everyone else. ## Reporting Issues @@ -11,12 +14,13 @@ Remember, a bug is a _demonstrable problem_ caused by _our_ code. ## Submitting Pull Requests -Pull requests are the greatest contributions, so be sure they are focused in scope, and do avoid unrelated commits. +Pull requests are the greatest contributions, so be sure they are focused in +scope, and do avoid unrelated commits. 1. To begin, [fork this project], clone your fork, and add our upstream. ```bash # Clone your fork of the repo into the current directory - git clone https://github.com//postcss-nesting + git clone https://github.com//postcss-nesting # Navigate to the newly cloned directory cd postcss-nesting # Assign the original repo to a remote called "upstream" diff --git a/LICENSE.md b/LICENSE.md index 565f84e33c..34f902f6c4 100644 --- a/LICENSE.md +++ b/LICENSE.md @@ -1,15 +1,106 @@ -# CC0 1.0 Universal License +# CC0 1.0 Universal -Public Domain Dedication +## Statement of Purpose -The person(s) who associated a work with this deed has dedicated the work to the public domain by waiving all of his or her rights to the work worldwide under copyright law, including all related and neighboring rights, to the extent allowed by law. +The laws of most jurisdictions throughout the world automatically confer +exclusive Copyright and Related Rights (defined below) upon the creator and +subsequent owner(s) (each and all, an “owner”) of an original work of +authorship and/or a database (each, a “Work”). -You can copy, modify, distribute and perform the work, even for commercial purposes, all without asking permission. +Certain owners wish to permanently relinquish those rights to a Work for the +purpose of contributing to a commons of creative, cultural and scientific works +(“Commons”) that the public can reliably and without fear of later claims of +infringement build upon, modify, incorporate in other works, reuse and +redistribute as freely as possible in any form whatsoever and for any purposes, +including without limitation commercial purposes. These owners may contribute +to the Commons to promote the ideal of a free culture and the further +production of creative, cultural and scientific works, or to gain reputation or +greater distribution for their Work in part through the use and efforts of +others. -In no way are the patent or trademark rights of any person affected by CC0, nor are the rights that other persons may have in the work or in how the work is used, such as publicity or privacy rights. +For these and/or other purposes and motivations, and without any expectation of +additional consideration or compensation, the person associating CC0 with a +Work (the “Affirmer”), to the extent that he or she is an owner of Copyright +and Related Rights in the Work, voluntarily elects to apply CC0 to the Work and +publicly distribute the Work under its terms, with knowledge of his or her +Copyright and Related Rights in the Work and the meaning and intended legal +effect of CC0 on those rights. -Unless expressly stated otherwise, the person(s) who associated a work with this deed makes no warranties about the work, and disclaims liability for all uses of the work, to the fullest extent permitted by applicable law. +1. Copyright and Related Rights. A Work made available under CC0 may be + protected by copyright and related or neighboring rights (“Copyright and + Related Rights”). Copyright and Related Rights include, but are not limited + to, the following: + 1. the right to reproduce, adapt, distribute, perform, display, + communicate, and translate a Work; + 2. moral rights retained by the original author(s) and/or performer(s); + 3. publicity and privacy rights pertaining to a person’s image or likeness + depicted in a Work; + 4. rights protecting against unfair competition in regards to a Work, + subject to the limitations in paragraph 4(i), below; + 5. rights protecting the extraction, dissemination, use and reuse of data + in a Work; + 6. database rights (such as those arising under Directive 96/9/EC of the + European Parliament and of the Council of 11 March 1996 on the legal + protection of databases, and under any national implementation thereof, + including any amended or successor version of such directive); and + 7. other similar, equivalent or corresponding rights throughout the world + based on applicable law or treaty, and any national implementations + thereof. -When using or citing the work, you should not imply endorsement by the author or the affirmer. +2. Waiver. To the greatest extent permitted by, but not in contravention of, +applicable law, Affirmer hereby overtly, fully, permanently, irrevocably and +unconditionally waives, abandons, and surrenders all of Affirmer’s Copyright +and Related Rights and associated claims and causes of action, whether now +known or unknown (including existing as well as future claims and causes of +action), in the Work (i) in all territories worldwide, (ii) for the maximum +duration provided by applicable law or treaty (including future time +extensions), (iii) in any current or future medium and for any number of +copies, and (iv) for any purpose whatsoever, including without limitation +commercial, advertising or promotional purposes (the “Waiver”). Affirmer makes +the Waiver for the benefit of each member of the public at large and to the +detriment of Affirmer’s heirs and successors, fully intending that such Waiver +shall not be subject to revocation, rescission, cancellation, termination, or +any other legal or equitable action to disrupt the quiet enjoyment of the Work +by the public as contemplated by Affirmer’s express Statement of Purpose. -This is a [human-readable summary of the Legal Code](https://creativecommons.org/publicdomain/zero/1.0/) ([read the full text](https://creativecommons.org/publicdomain/zero/1.0/legalcode)). +3. Public License Fallback. Should any part of the Waiver for any reason be +judged legally invalid or ineffective under applicable law, then the Waiver +shall be preserved to the maximum extent permitted taking into account +Affirmer’s express Statement of Purpose. In addition, to the extent the Waiver +is so judged Affirmer hereby grants to each affected person a royalty-free, non +transferable, non sublicensable, non exclusive, irrevocable and unconditional +license to exercise Affirmer’s Copyright and Related Rights in the Work (i) in +all territories worldwide, (ii) for the maximum duration provided by applicable +law or treaty (including future time extensions), (iii) in any current or +future medium and for any number of copies, and (iv) for any purpose +whatsoever, including without limitation commercial, advertising or promotional +purposes (the “License”). The License shall be deemed effective as of the date +CC0 was applied by Affirmer to the Work. Should any part of the License for any +reason be judged legally invalid or ineffective under applicable law, such +partial invalidity or ineffectiveness shall not invalidate the remainder of the +License, and in such case Affirmer hereby affirms that he or she will not (i) +exercise any of his or her remaining Copyright and Related Rights in the Work +or (ii) assert any associated claims and causes of action with respect to the +Work, in either case contrary to Affirmer’s express Statement of Purpose. + +4. Limitations and Disclaimers. + 1. No trademark or patent rights held by Affirmer are waived, abandoned, + surrendered, licensed or otherwise affected by this document. + 2. Affirmer offers the Work as-is and makes no representations or + warranties of any kind concerning the Work, express, implied, statutory + or otherwise, including without limitation warranties of title, + merchantability, fitness for a particular purpose, non infringement, or + the absence of latent or other defects, accuracy, or the present or + absence of errors, whether or not discoverable, all to the greatest + extent permissible under applicable law. + 3. Affirmer disclaims responsibility for clearing rights of other persons + that may apply to the Work or any use thereof, including without + limitation any person’s Copyright and Related Rights in the Work. + Further, Affirmer disclaims responsibility for obtaining any necessary + consents, permissions or other rights required for any use of the Work. + 4. Affirmer understands and acknowledges that Creative Commons is not a + party to this document and has no duty or obligation with respect to + this CC0 or use of the Work. + +For more information, please see +http://creativecommons.org/publicdomain/zero/1.0/. diff --git a/README.md b/README.md index cc10beaf77..bf60e14151 100644 --- a/README.md +++ b/README.md @@ -1,94 +1,37 @@ -# CSS Nesting +# PostCSS Nesting [PostCSS Logo][postcss] -PostCSS Logo +[![NPM Version][npm-img]][npm-url] +[![Build Status][cli-img]][cli-url] +[![Licensing][lic-img]][lic-url] +[![Changelog][log-img]][log-url] +[![Gitter Chat][git-img]][git-url] -[![NPM Version][npm-img]][npm] [![Build Status][ci-img]][ci] - -[CSS Nesting] allows you to nest one style rule inside another, following the [CSS Nesting Module Level 3] specification. +[PostCSS Nesting] lets you nest style rules inside each other, following the +[CSS Nesting Module Level 3] specification. ```css -/* direct nesting */ - -a, b { - color: red; - - & c, & d { - color: white; - } - - & & { - color: blue; - } - - &:hover { - color: black; - } - - @media (min-width: 30em) { - color: yellow; - - @media (min-device-pixel-ratio: 1.5) { - color: green; - } - } -} - -/* or at-rule nesting */ - a, b { - color: red; - - @nest & c, & d { - color: white; - } - - @nest & & { - color: blue; - } - - @nest &:hover { - color: black; - } + color: red; - @media (min-width: 30em) { - color: yellow; - } + & c, & d { + color: white; + } } -/* after */ +/* after postcss-nesting */ a, b { - color: red; + color: red; } a c, a d, b c, b d { - color: white; -} - -a a, b b { - color: blue; -} - -a:hover, b:hover { - color: black; -} - -@media (min-width: 30em) { - a, b { - color: yellow; - } -} - -@media (min-width: 30em) and (min-device-pixel-ratio: 1.5) { - a, b { - color: green; - } + color: white; } ``` ## Usage -Add [CSS Nesting] to your build tool: +Add [PostCSS Nesting] to your build tool: ```bash npm install postcss-nesting --save-dev @@ -96,6 +39,8 @@ npm install postcss-nesting --save-dev #### Node +Use [PostCSS Nesting] to process your CSS: + ```js require('postcss-nesting').process(YOUR_CSS, { /* options */ }); ``` @@ -108,7 +53,7 @@ Add [PostCSS] to your build tool: npm install postcss --save-dev ``` -Load [CSS Nesting] as a PostCSS plugin: +Use [PostCSS Nesting] as a plugin: ```js postcss([ @@ -124,7 +69,7 @@ Add [Gulp PostCSS] to your build tool: npm install gulp-postcss --save-dev ``` -Enable [CSS Nesting] within your Gulpfile: +Use [PostCSS Nesting] in your Gulpfile: ```js var postcss = require('gulp-postcss'); @@ -148,7 +93,7 @@ Add [Grunt PostCSS] to your build tool: npm install grunt-postcss --save-dev ``` -Enable [CSS Nesting] within your Gruntfile: +Use [PostCSS Nesting] in your Gruntfile: ```js grunt.loadNpmTasks('grunt-postcss'); @@ -167,31 +112,20 @@ grunt.initConfig({ }); ``` -## Options - -#### `bubble` - -Type: `Array` -Default: `['document', 'media', 'supports']` - -Specifies additional at-rules whose contents should be transpiled so that the at-rule comes first. By default, `@media`, `@supports` and `@document` will do this. - -#### `prefix` - -Type: `String` -Default: `null` - -Specifies a prefix to be surrounded by dashes before the `@nest` at-rule (e.g. `@-x-nest`). - -[ci]: https://travis-ci.org/jonathantneal/postcss-nesting -[ci-img]: https://img.shields.io/travis/jonathantneal/postcss-nesting.svg -[npm]: https://www.npmjs.com/package/postcss-nesting +[npm-url]: https://www.npmjs.com/package/postcss-nesting [npm-img]: https://img.shields.io/npm/v/postcss-nesting.svg - -[Gulp PostCSS]: https://github.com/postcss/gulp-postcss +[cli-url]: https://travis-ci.org/jonathantneal/postcss-nesting +[cli-img]: https://img.shields.io/travis/jonathantneal/postcss-nesting.svg +[lic-url]: LICENSE.md +[lic-img]: https://img.shields.io/npm/l/postcss-nesting.svg +[log-url]: CHANGELOG.md +[log-img]: https://img.shields.io/badge/changelog-md-blue.svg +[git-url]: https://gitter.im/postcss/postcss +[git-img]: https://img.shields.io/badge/chat-gitter-blue.svg + +[PostCSS Nesting]: https://github.com/jonathantneal/postcss-nesting +[PostCSS]: https://github.com/postcss/postcss +[Gulp PostCSS]: https://github.com/postcss/gulp-postcss [Grunt PostCSS]: https://github.com/nDmitry/grunt-postcss -[PostCSS]: https://github.com/postcss/postcss [CSS Nesting Module Level 3]: http://tabatkins.github.io/specs/css-nesting/ - -[CSS Nesting]: https://github.com/jonathantneal/postcss-nesting diff --git a/index.js b/index.js index e0a2cd9736..a4627d325b 100644 --- a/index.js +++ b/index.js @@ -1,112 +1,38 @@ -var postcss = require('postcss'); -var comma = postcss.list.comma; +'use strict'; -module.exports = postcss.plugin('postcss-nesting', function (opts) { - var bubble = ['document', 'media', 'supports']; - var name = 'nest'; +// tooling +const postcss = require('postcss'); +const transformBubblingAtrule = require('./lib/transform-bubbling-atrule'); +const transformNestingAtRule = require('./lib/transform-nesting-atrule'); +const transformNestingRule = require('./lib/transform-nesting-rule'); - if (opts && opts.bubble) { - bubble = bubble.concat(opts.bubble); - } +// plugin +module.exports = postcss.plugin('postcss-nesting', () => { + return walk; +}); - if (opts && opts.prefix) { - name = '-' + opts.prefix + '-' + name; +function walk(node) { + // console.log('walk', [node.type], [node.name || node.selector || node.prop || 'root'], node.nodes ? `length: ${node.nodes.length}` : `value: "${node.value}"`); + + if (transformBubblingAtrule.test(node)) { + // conditionally transform a bubbling atrule + transformBubblingAtrule(node); + } else if (transformNestingAtRule.test(node)) { + // conditionally transform a nesting atrule + node = transformNestingAtRule(node); // eslint-disable-line no-param-reassign + } else if (transformNestingRule.test(node)) { + // conditionally transform a nesting rule + transformNestingRule(node); } - return function (css) { - css.walk(function (target) { - var rule = target.parent; - var root = rule && rule.parent; - - var isAtRule = target.type === 'atrule'; - var isRule = target.type === 'rule'; - - if (root && rule.type === 'rule') { - var newrule = postcss.rule({ - source: target.source - }); - - if (isRule && target.selectors.every(function (selector) { - return selector.indexOf('&') === 0; - })) { - target.remove(); - - newrule.selector = target.selector; - - newrule.append(target.nodes); - - transpileSelectors(rule, newrule); - - root.insertAfter(rule.insertAfterNode || rule, newrule); - - rule.insertAfterNode = newrule; - } else if (isAtRule && target.name === name && target.params.indexOf('&') !== -1) { - target.remove(); - - newrule.selector = target.params; - - newrule.append(target.nodes); - - transpileSelectors(rule, newrule); - - root.insertAfter(rule.insertAfterNode || rule, newrule); - - rule.insertAfterNode = newrule; - } else if (isAtRule && bubble.indexOf(target.name) !== -1) { - var selector = rule.selector; + if (node.nodes) { + // conditionally walk the children of the node + let childNode = node.nodes[0]; - if (root.type === 'atrule' && root.name === target.name && root.parent) { - target.params = comma(root.params).map(function (params1) { - return comma(target.params).map(function (params2) { - return params1 + ' and ' + params2; - }).join(', '); - }).join(', '); + while (childNode) { + walk(childNode); - rule = root; - root = root.parent; - } - - target.remove(); - - newrule.selector = selector; - - newrule.append(target.nodes); - - target.removeAll(); - - target.append(newrule); - - root.insertAfter(rule.insertAfterNode || rule, target); - - rule.insertAfterNode = target; - } - } - - if (!rule.nodes.length) { - rule.remove(); - } else { - rule.nodes.forEach(function (n) { - var isRuleOrAtRule = (/rule$/).test(n.type); - - if (!isRuleOrAtRule || n.nodes.length) { - return; - } - - n.remove(); - }); - } - }); - }; -}); - -function transpileSelectors(fromRule, toRule) { - var selectors = []; - - fromRule.selectors.forEach(function (fromSelector) { - toRule.selectors.forEach(function (toSelector) { - selectors.push(toSelector.replace(/&/g, fromSelector)); - }); - }); - - toRule.selectors = selectors; + childNode = childNode.parent && childNode.parent.nodes[childNode.parent.nodes.indexOf(childNode) + 1]; + } + } } diff --git a/lib/clean-node.js b/lib/clean-node.js new file mode 100644 index 0000000000..1ceb3428ed --- /dev/null +++ b/lib/clean-node.js @@ -0,0 +1,6 @@ +// clean the raws of the node +module.exports = (node) => { + node.raws = {}; + + return node; +}; diff --git a/lib/merge-params.js b/lib/merge-params.js new file mode 100644 index 0000000000..b270a957ed --- /dev/null +++ b/lib/merge-params.js @@ -0,0 +1,9 @@ +// tooling +const comma = require('postcss').list.comma; + +// merge params +module.exports = (fromParams, toParams) => comma(fromParams).map( + (params1) => comma(toParams).map( + (params2) => params1 + ' and ' + params2 + ).join(', ') +).join(', '); diff --git a/lib/merge-selectors.js b/lib/merge-selectors.js new file mode 100644 index 0000000000..376a5ce645 --- /dev/null +++ b/lib/merge-selectors.js @@ -0,0 +1,12 @@ +// tooling +const comma = require('postcss').list.comma; + +// merge selectors +module.exports = (fromSelectors, toSelectors) => (typeof fromSelectors === 'string' ? comma(fromSelectors) : fromSelectors).reduce( + (selectors, fromSelector) => selectors.concat( + (typeof toSelectors === 'string' ? comma(toSelectors) : toSelectors).map( + (toSelector) => toSelector.replace(/&/g, fromSelector) + ) + ), + [] +); diff --git a/lib/transform-after-nodes.js b/lib/transform-after-nodes.js new file mode 100644 index 0000000000..ba2acd68bc --- /dev/null +++ b/lib/transform-after-nodes.js @@ -0,0 +1,18 @@ +// tooling +const cleanNode = require('./clean-node'); + +// move nodes after the current node into a cloned parent node +module.exports = (node) => { + // affected nodes after the current node + const affectedNodes = node.parent.nodes.slice(node.parent.nodes.indexOf(node) + 1).map(cleanNode); + + if (affectedNodes.length) { + // insert an empty parent clone after the parent + const emptyParentClone = cleanNode(node.parent.clone()).removeAll(); + + node.parent.after(emptyParentClone); + + // append the affected nodes to the empty parent clone + emptyParentClone.append(affectedNodes); + } +}; diff --git a/lib/transform-bubbling-atrule.js b/lib/transform-bubbling-atrule.js new file mode 100644 index 0000000000..3dccec7e9d --- /dev/null +++ b/lib/transform-bubbling-atrule.js @@ -0,0 +1,52 @@ +// tooling +const cleanNode = require('./clean-node'); +const mergeParams = require('./merge-params'); +const transformAfterNodes = require('./transform-after-nodes'); + +// transform a bubbling atrule (e.g. @document, @media, @supports) +module.exports = (node) => { + // clean node + cleanNode(node); + + // affected nodes after the current node moved into a cloned parent node + transformAfterNodes(node); + + // inner nodes within the current node + const innerNodes = node.nodes.slice(0).map(cleanNode); + + // prepend an empty parent clone to the node + const parentCloneForNodesWithinAtrule = cleanNode(node.parent.clone()).removeAll(); + + node.prepend(parentCloneForNodesWithinAtrule); + + // append the inner nodes to the empty parent clone + parentCloneForNodesWithinAtrule.append(innerNodes); + + // move the node after the parent + const parent = node.parent.after(node); + + if (!parent.nodes.length) { + // conditionally remove the original empty parent + parent.remove(); + } + + // if the node and the parent are both media atrules + if (node.parent.type === 'atrule' && node.name === node.parent.name) { + // affected nodes after the current node moved into a cloned parent node + transformAfterNodes(node); + + // merge media params + node.params = mergeParams(node.parent.params, node.params); + + // move the node after the parent + const subparent = node.parent.after(node); + + if (!subparent.nodes.length) { + // conditionally remove the original empty parent + subparent.remove(); + } + } +}; + +// whether the node is a bubbling atrule (e.g. @document, @media, @supports) +module.exports.test = (node, bubbles) => node.type === 'atrule' && ['document', 'media', 'supports'].indexOf(node.name) !== -1 && node.parent && node.parent.type === 'rule'; diff --git a/lib/transform-nesting-atrule.js b/lib/transform-nesting-atrule.js new file mode 100644 index 0000000000..413801d04c --- /dev/null +++ b/lib/transform-nesting-atrule.js @@ -0,0 +1,43 @@ +// tooling +const cleanNode = require('./clean-node'); +const comma = require('postcss').list.comma; +const mergeSelectors = require('./merge-selectors'); +const postcss = require('postcss'); +const transformAfterNodes = require('./transform-after-nodes'); + +// transform a nesting atrule (e.g. @nest .something &) +module.exports = (node) => { + // clean node and child nodes + cleanNode(node).nodes.forEach(cleanNode); + + // affected nodes after the current node moved into a cloned parent node + transformAfterNodes(node); + + // clone of the atrule as a rule + const rule = postcss.rule({ + // merge selectors + selectors: mergeSelectors(node.parent.selectors, node.params), + source: node.source + }); + + // move the clone after the parent + const parent = node.parent.after(rule); + + // remove the original node + node.remove(); + + // move child nodes into the clone + rule.append(node.nodes); + + if (!parent.nodes.length) { + // conditionally remove the original empty parent + parent.remove(); + } + + return rule; +}; + +// whether the node is a nesting atrule (e.g. @nest .something &) +module.exports.test = (node) => node.type === 'atrule' && node.name === 'nest' && node.parent && node.parent.type === 'rule' && comma(node.params).every( + (childNode) => childNode.indexOf('&') !== -1 +); diff --git a/lib/transform-nesting-rule.js b/lib/transform-nesting-rule.js new file mode 100644 index 0000000000..2161eb322c --- /dev/null +++ b/lib/transform-nesting-rule.js @@ -0,0 +1,29 @@ +// tooling +const cleanNode = require('./clean-node'); +const mergeSelectors = require('./merge-selectors'); +const transformAfterNodes = require('./transform-after-nodes'); + +// transform a nesting rule (e.g. &.something) +module.exports = (node) => { + // clean node and child nodes + cleanNode(node).nodes.forEach(cleanNode); + + // move nodes after the current node into a cloned parent node + transformAfterNodes(node); + + // merge selectors + node.selectors = mergeSelectors(node.parent.selectors, node.selectors); + + // move the node after the parent + const parent = node.parent.after(node); + + if (!parent.nodes.length) { + // conditionally remove the original empty parent + parent.remove(); + } +}; + +// whether the node is a nesting rule (e.g. &.something) +module.exports.test = (node) => node.type === 'rule' && node.parent && node.parent.type === 'rule' && node.selectors.every( + (childNode) => childNode.trim()[0] === '&' +); diff --git a/package.json b/package.json index d9287394db..247ff41a97 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,39 @@ { "name": "postcss-nesting", - "version": "2.3.1", - "description": "Transpiles nested rules according to CSS Nesting Module Level 3", + "version": "3.0.0", + "description": "Nest style and media rules inside each another, following the CSS Nesting Module Level 3 specification", + "author": "Jonathan Neal ", + "license": "CC0-1.0", + "repository": "jonathantneal/postcss-nesting", + "homepage": "https://github.com/jonathantneal/postcss-nesting#readme", + "bugs": "https://github.com/jonathantneal/postcss-nesting/issues", + "main": "index.js", + "files": [ + "index.js", + "lib" + ], + "scripts": { + "clean": "git clean -X -d -f", + "prepublish": "npm test", + "test": "echo 'Running tests...'; npm run test:js && npm run test:tape", + "test:js": "eslint *.js --cache --ignore-pattern .gitignore", + "test:tape": "postcss-tape" + }, + "engines": { + "node": ">=4.0.0" + }, + "dependencies": { + "postcss": "^6.0.1" + }, + "devDependencies": { + "eslint": "^3.19.0", + "eslint-config-dev": "^2.0.0", + "postcss-tape": "^2.0.1", + "pre-commit": "^1.2.2" + }, + "eslintConfig": { + "extends": "dev" + }, "keywords": [ "postcss", "css", @@ -14,31 +46,10 @@ "nestings", "rules", "selectors", + "syntax", "specifications", "specs", - "w3c" - ], - "author": "Jonathan Neal ", - "license": "CC0-1.0", - "repository": "jonathantneal/postcss-nesting", - "bugs": "https://github.com/jonathantneal/postcss-nesting/issues", - "homepage": "https://github.com/jonathantneal/postcss-nesting", - "dependencies": { - "postcss": "^5.0.19" - }, - "devDependencies": { - "eslint": "^2.4.0", - "jscs": "^2.11.0", - "tap-spec": "^4.1.1", - "tape": "^4.5.1" - }, - "scripts": { - "lint": "eslint *.js --ignore-path .gitignore && jscs *.js", - "tape": "tape test.js | tap-spec", - "test": "npm run lint && npm run tape" - }, - "engines": { - "iojs": ">=2.0.0", - "node": ">=0.12.0" - } + "w3c", + "csswg" + ] } diff --git a/test.js b/test.js deleted file mode 100644 index cc99402fe4..0000000000 --- a/test.js +++ /dev/null @@ -1,78 +0,0 @@ -var tests = { - 'postcss-nesting': { - 'basic': { - message: 'supports basic usage' - }, - 'direct': { - message: 'supports direct nesting' - }, - 'ignore': { - message: 'ignores invalid syntax' - }, - 'media': { - message: 'supports nested media queries' - }, - 'empty': { - message: 'ensure empty rules are removed' - } - } -}; - -var debug = true; -var dir = './test/'; - -var fs = require('fs'); -var path = require('path'); -var plugin = require('./'); -var test = require('tape'); - -Object.keys(tests).forEach(function (name) { - var parts = tests[name]; - - test(name, function (t) { - var fixtures = Object.keys(parts); - - t.plan(fixtures.length * 2); - - fixtures.forEach(function (fixture) { - var message = parts[fixture].message; - var options = parts[fixture].options; - var warning = parts[fixture].warning || 0; - var warningMsg = message + ' (# of warnings)'; - - var baseName = fixture.split(':')[0]; - var testName = fixture.split(':').join('.'); - - var inputPath = path.resolve(dir + baseName + '.css'); - var expectPath = path.resolve(dir + testName + '.expect.css'); - var actualPath = path.resolve(dir + testName + '.actual.css'); - - var inputCSS = ''; - var expectCSS = ''; - - try { - inputCSS = fs.readFileSync(inputPath, 'utf8'); - } catch (error) { - fs.writeFileSync(inputPath, inputCSS); - } - - try { - expectCSS = fs.readFileSync(expectPath, 'utf8'); - } catch (error) { - fs.writeFileSync(expectPath, expectCSS); - } - - plugin.process(inputCSS, options).then(function (result) { - var actualCSS = result.css; - - if (debug) { - fs.writeFileSync(actualPath, actualCSS); - } - - t.equal(actualCSS, expectCSS, message); - - t.equal(result.warnings().length, warning, warningMsg); - }); - }); - }); -}); diff --git a/test/basic.css b/test/basic.css index def35db245..df6cafdff6 100644 --- a/test/basic.css +++ b/test/basic.css @@ -1,79 +1,19 @@ -a, b { - color: white; - - @nest & c, & d { - color: blue; - } -} - -a, b { - color: white; - - @nest & c, & d { - color: blue; - - @nest & e, & f { - color: black; - } - } -} - -a, b { - color: red; - - @nest & & { - color: white; - } -} - -a { - color: red; - - @media { - color: white; - } -} - -a { - color: red; - - @nest & b { - color: white; - - @media { - color: blue; - } - } - - @media { - color: black; - - @nest & c { - color: yellow; - } - } -} - -a { - color: red; - - @unknown test { - color: white; - } -} - -b { - color: white; - - @phone { - color: blue; - } - - @media { - color: black; - - @nest & c { - color: yellow; +.rule-1 { + order: 1; + @media screen, print { + order: 2; + &.rule-2 { + order: 3; + @media (max-width: 30em) { + order: 4; + @nest .rule-prefix & { + order: 5; + } + order: 6; + } + order: 7; } + order: 8; } + order: 9; } diff --git a/test/basic.expect.css b/test/basic.expect.css index b53627634f..aefc97b7f0 100644 --- a/test/basic.expect.css +++ b/test/basic.expect.css @@ -1,91 +1,33 @@ -a, b { - color: white +.rule-1 { + order: 1; } - -a c, a d, b c, b d { - color: blue -} - -a, b { - color: white -} - -a c, a d, b c, b d { - color: blue -} - -a c e, a c f, a d e, a d f, b c e, b c f, b d e, b d f { - color: black -} - -a, b { - color: red -} - -a a, b b { - color: white -} - -a { - color: red -} - -@media { - - a { - color: white +@media screen, print { + .rule-1 { + order: 2; } + .rule-1.rule-2 { + order: 3; } - -a { - color: red } - -a b { - color: white -} - -@media { - - a b { - color: blue +@media screen and (max-width: 30em), print and (max-width: 30em) { + .rule-1.rule-2 { + order: 4; } -} - -@media { - - a { - color: black + .rule-prefix .rule-1.rule-2 { + order: 5; } - - a c { - color: yellow + .rule-1.rule-2 { + order: 6; } +} +@media screen, print { + .rule-1.rule-2 { + order: 7; } - -a { - color: red; - - @unknown test { - color: white; + .rule-1 { + order: 8; } } - -b { - color: white; - - @phone { - color: blue; - } +.rule-1 { + order: 9; } - -@media { - - b { - color: black - } - - b c { - color: yellow - } - } diff --git a/test/direct.css b/test/direct.css index 2591c0ba89..af39d6e363 100644 --- a/test/direct.css +++ b/test/direct.css @@ -1,87 +1,30 @@ a, b { - color: blue; - + order: 1; & c, & d { - color: blue; - } -} - -a, b { - color: blue; - - & c, & d { - color: blue; - + order: 2; & e, & f { - color: blue; + order: 3; } + order: 4; } -} - -a, b { - color: blue; - + order: 5; & & { - color: blue; - } - - c & { - color: red; - } - - & c, c & { - color: red; - } -} - -a { - color: blue; - - @media { - color: blue; + order: 6; } + order: 7; } - -a { - color: blue; - - & b { - color: blue; - - @media { - color: blue; - } - } - - @media { - color: blue; - - & c { - color: blue; +a, b { + order: 1; + @nest & c, & d { + order: 2; + @nest & e, & f { + order: 3; } + order: 4; } -} - -a { - color: blue; - - @unknown test { - color: red; - } -} - -b { - color: blue; - - @phone { - color: red; - } - - @media { - color: blue; - - & c { - color: blue; - } + order: 5; + @nest & & { + order: 6; } + order: 7; } diff --git a/test/direct.expect.css b/test/direct.expect.css index 2054a81780..d64cb3900e 100644 --- a/test/direct.expect.css +++ b/test/direct.expect.css @@ -1,99 +1,42 @@ a, b { - color: blue + order: 1; } - a c, a d, b c, b d { - color: blue + order: 2; } - -a, b { - color: blue +a c e, a c f, a d e, a d f, b c e, b c f, b d e, b d f { + order: 3; } - a c, a d, b c, b d { - color: blue -} - -a c e, a c f, a d e, a d f, b c e, b c f, b d e, b d f { - color: blue + order: 4; } - a, b { - color: blue; - - c & { - color: red; - } - - & c, c & { - color: red; - } + order: 5; } - a a, b b { - color: blue + order: 6; +} +a, b { + order: 7; +} +a, b { + order: 1; } - -a { - color: blue +a c, a d, b c, b d { + order: 2; } - -@media { - - a { - color: blue - } - } - -a { - color: blue +a c e, a c f, a d e, a d f, b c e, b c f, b d e, b d f { + order: 3; } - -a b { - color: blue +a c, a d, b c, b d { + order: 4; } - -@media { - - a b { - color: blue - } +a, b { + order: 5; } - -@media { - - a { - color: blue - } - - a c { - color: blue - } - } - -a { - color: blue; - - @unknown test { - color: red; - } +a a, b b { + order: 6; } - -b { - color: blue; - - @phone { - color: red; - } +a, b { + order: 7; } - -@media { - - b { - color: blue - } - - b c { - color: blue - } - } diff --git a/test/empty.css b/test/empty.css index 85fd7b54da..fb5988fe57 100644 --- a/test/empty.css +++ b/test/empty.css @@ -1,26 +1,38 @@ a { & b { - prop: val; + & c { + order: 1; + } + } +} +d { + order: 2; + & e { + order: 3; + } +} +f { + & g { + order: 4; } - - & c { - prop: val; + order: 5; +} +a { + @nest & b { + @nest & c { + order: 1; + } } } - d { + order: 2; @nest & e { - prop: val; - - @nest & f { - prop: val; - } + order: 3; } } - -g { - prop: val; - & h { - prop: val +f { + @nest & g { + order: 4; } + order: 5; } diff --git a/test/empty.expect.css b/test/empty.expect.css index 5482c0940e..1bc7d62443 100644 --- a/test/empty.expect.css +++ b/test/empty.expect.css @@ -1,23 +1,30 @@ -a b { - prop: val +a b c { + order: 1 } - -a c { - prop: val +d { + order: 2 } - d e { - prop: val + order: 3 } - -d e f { - prop: val +f g { + order: 4 } - -g { - prop: val +f { + order: 5 } - -g h { - prop: val +a b c { + order: 1 +} +d { + order: 2 +} +d e { + order: 3 +} +f g { + order: 4 +} +f { + order: 5 } diff --git a/test/ignore.css b/test/ignore.css index ec65a94f19..e8de19a875 100644 --- a/test/ignore.css +++ b/test/ignore.css @@ -1,19 +1,18 @@ a, b { - color: white; - + order: 1; c, d { - color: blue; + order: 2; } } - +& e { + order: 3; +} a, b { - color: white; - + order: 1; @nest c, d { - color: blue; + order: 2; } } - -& a { - color: white; +@nest & e { + order: 3; } diff --git a/test/ignore.expect.css b/test/ignore.expect.css index ec65a94f19..e8de19a875 100644 --- a/test/ignore.expect.css +++ b/test/ignore.expect.css @@ -1,19 +1,18 @@ a, b { - color: white; - + order: 1; c, d { - color: blue; + order: 2; } } - +& e { + order: 3; +} a, b { - color: white; - + order: 1; @nest c, d { - color: blue; + order: 2; } } - -& a { - color: white; +@nest & e { + order: 3; } diff --git a/test/media.css b/test/media.css index 39cf0523aa..d8714e90a4 100644 --- a/test/media.css +++ b/test/media.css @@ -1,25 +1,44 @@ -.main { - color: blue; - +a { + order: 1; @media (min-width: 100px) { - color: white; - + order: 2; @media (max-width: 200px) { - color: red; + order: 3; } - - & .child { + & b { @media (max-width: 200px) { - color: green; + order: 4; + } + } + } + @media screen, print and speech { + @media (max-width: 300px), (min-aspect-ratio: 16/9) { + order: 5; + & c { + order: 6; } } } } - -.main { +a { + order: 1; + @media (min-width: 100px) { + order: 2; + @media (max-width: 200px) { + order: 3; + } + @nest & b { + @media (max-width: 200px) { + order: 4; + } + } + } @media screen, print and speech { @media (max-width: 300px), (min-aspect-ratio: 16/9) { - color: black; + order: 5; + @nest & c { + order: 6; + } } } } diff --git a/test/media.expect.css b/test/media.expect.css index 2686f9ffe3..19c7006bbd 100644 --- a/test/media.expect.css +++ b/test/media.expect.css @@ -1,31 +1,52 @@ -.main { - color: blue +a { + order: 1 } - - @media (min-width: 100px) { - - .main { - color: white +@media (min-width: 100px) { + a { + order: 2 } +} +@media (min-width: 100px) and (max-width: 200px) { + a { + order: 3 + } +} +@media (min-width: 100px) and (max-width: 200px) { + a b { + order: 4 + } +} +@media screen and (max-width: 300px), screen and (min-aspect-ratio: 16/9), print and speech and (max-width: 300px), print and speech and (min-aspect-ratio: 16/9) { + a { + order: 5 } - - @media (min-width: 100px) and (max-width: 200px) { - - .main { - color: red + a c { + order: 6 } } - - @media (min-width: 100px) and (max-width: 200px) { - - .main .child { - color: green +a { + order: 1 +} +@media (min-width: 100px) { + a { + order: 2 + } +} +@media (min-width: 100px) and (max-width: 200px) { + a { + order: 3 + } +} +@media (min-width: 100px) and (max-width: 200px) { + a b { + order: 4 } } - @media screen and (max-width: 300px), screen and (min-aspect-ratio: 16/9), print and speech and (max-width: 300px), print and speech and (min-aspect-ratio: 16/9) { - - .main { - color: black + a { + order: 5 + } + a c { + order: 6 } } From 64eb63c035279d67ca782e3b13c3ca73a0b06422 Mon Sep 17 00:00:00 2001 From: Jonathan Neal Date: Wed, 10 May 2017 15:35:27 -0400 Subject: [PATCH 408/795] 3.0.0 --- CHANGELOG.md | 4 ++++ package.json | 4 ++-- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3be46c3989..9b508ddf3d 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,7 @@ +# 3.0.0 - 2016-05-10 + +- Added: compatibility with postcss v6.x + # 2.0.1 - 2016-11-28 - Bump `color` dependency version diff --git a/package.json b/package.json index 46fe2b3417..5f6f9bc75c 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "postcss-color-rebeccapurple", - "version": "2.0.1", + "version": "3.0.0", "description": "PostCSS plugin to transform W3C CSS rebeccapurple color to more compatible CSS (rgb())", "keywords": [ "css", @@ -22,7 +22,7 @@ ], "dependencies": { "color": "^0.11.4", - "postcss": "^5.0.4" + "postcss": "^6.0.1" }, "devDependencies": { "jscs": "^1.6.2", From 932246cd51918540fdc390787467df0a79e018a2 Mon Sep 17 00:00:00 2001 From: Jonathan Neal Date: Wed, 10 May 2017 15:39:05 -0400 Subject: [PATCH 409/795] Drop color dependency for simple #639 --- index.js | 2 +- package.json | 1 - test/fixtures/rebeccapurple.expected.css | 4 ++-- 3 files changed, 3 insertions(+), 4 deletions(-) diff --git a/index.js b/index.js index 8908522038..a0f724338e 100755 --- a/index.js +++ b/index.js @@ -2,7 +2,7 @@ * Module dependencies. */ var postcss = require("postcss") -var color = require("color")("rebeccapurple").rgbString() +var color = "#639" /** * PostCSS plugin to convert colors diff --git a/package.json b/package.json index 5f6f9bc75c..9777677ebc 100644 --- a/package.json +++ b/package.json @@ -21,7 +21,6 @@ "index.js" ], "dependencies": { - "color": "^0.11.4", "postcss": "^6.0.1" }, "devDependencies": { diff --git a/test/fixtures/rebeccapurple.expected.css b/test/fixtures/rebeccapurple.expected.css index 00f9305064..b6cd293224 100644 --- a/test/fixtures/rebeccapurple.expected.css +++ b/test/fixtures/rebeccapurple.expected.css @@ -1,4 +1,4 @@ body { - color: rgb(102, 51, 153); - background: linear-gradient(rgb(102, 51, 153), blue 50%, rgb(102, 51, 153)); + color: #639; + background: linear-gradient(#639, blue 50%, #639); } From 8c8f8135f7344702035729f998e9c66a57be7521 Mon Sep 17 00:00:00 2001 From: Jonathan Neal Date: Wed, 10 May 2017 15:55:52 -0400 Subject: [PATCH 410/795] Update JSCS and drop invalid JSCS options --- .jscsrc | 5 ----- package.json | 6 +++--- 2 files changed, 3 insertions(+), 8 deletions(-) diff --git a/.jscsrc b/.jscsrc index 29720b3791..9afb9dd75d 100644 --- a/.jscsrc +++ b/.jscsrc @@ -121,10 +121,5 @@ "requireCapitalizedConstructors": true, "safeContextKeyword": "that", "requireDotNotation": true, - "validateJSDoc": { - "checkParamNames": true, - "checkRedundantParams": true, - "requireParamTypes": true - }, "requireSpaceAfterLineComment": true } diff --git a/package.json b/package.json index 9777677ebc..697ee8ad4e 100644 --- a/package.json +++ b/package.json @@ -24,10 +24,10 @@ "postcss": "^6.0.1" }, "devDependencies": { - "jscs": "^1.6.2", - "jshint": "^2.5.6", + "jscs": "^3.0.7", + "jshint": "^2.9.4", "npmpub": "^3.1.0", - "tape": "^4.0.0" + "tape": "^4.6.3" }, "scripts": { "lint": "npm run jscs && npm run jshint", From caf793e40f5b12fab4c9b265f44a85b0a10812ca Mon Sep 17 00:00:00 2001 From: Jonathan Neal Date: Wed, 10 May 2017 15:57:28 -0400 Subject: [PATCH 411/795] Accurately parse the rebeccapurple word using postcss-value-parser --- index.js | 7 ++++++- package.json | 3 ++- test/fixtures/rebeccapurple.css | 4 ++++ test/fixtures/rebeccapurple.expected.css | 4 ++++ 4 files changed, 16 insertions(+), 2 deletions(-) diff --git a/index.js b/index.js index a0f724338e..49c4bf6400 100755 --- a/index.js +++ b/index.js @@ -2,6 +2,7 @@ * Module dependencies. */ var postcss = require("postcss") +var valueParser = require("postcss-value-parser") var color = "#639" /** @@ -13,7 +14,11 @@ module.exports = postcss.plugin("postcss-color-rebeccapurple", function() { var value = decl.value; if (value && value.indexOf("rebeccapurple") !== -1) { - decl.value = value.replace(/(rebeccapurple)\b/gi, color) + decl.value = valueParser(value).walk(function(node) { + if (node.type === "word" && node.value === "rebeccapurple") { + node.value = color + } + }).toString() } }) } diff --git a/package.json b/package.json index 697ee8ad4e..683d4c2c47 100644 --- a/package.json +++ b/package.json @@ -21,7 +21,8 @@ "index.js" ], "dependencies": { - "postcss": "^6.0.1" + "postcss": "^6.0.1", + "postcss-value-parser": "^3.3.0" }, "devDependencies": { "jscs": "^3.0.7", diff --git a/test/fixtures/rebeccapurple.css b/test/fixtures/rebeccapurple.css index 27b88a4b80..ebd14a9e48 100644 --- a/test/fixtures/rebeccapurple.css +++ b/test/fixtures/rebeccapurple.css @@ -2,3 +2,7 @@ body { color: rebeccapurple; background: linear-gradient(rebeccapurple, blue 50%, rebeccapurple); } + +a { + color: oldrebeccapurple; +} diff --git a/test/fixtures/rebeccapurple.expected.css b/test/fixtures/rebeccapurple.expected.css index b6cd293224..e9838f2ae4 100644 --- a/test/fixtures/rebeccapurple.expected.css +++ b/test/fixtures/rebeccapurple.expected.css @@ -2,3 +2,7 @@ body { color: #639; background: linear-gradient(#639, blue 50%, #639); } + +a { + color: oldrebeccapurple; +} From 99053e64c232118584c55dd4be5e5fd314cbd03d Mon Sep 17 00:00:00 2001 From: Jonathan Neal Date: Wed, 10 May 2017 15:57:57 -0400 Subject: [PATCH 412/795] Use Node v4 syntax - Also update .travis.yml to use Node v4 --- .travis.yml | 2 ++ index.js | 30 ++++++++++++++---------------- 2 files changed, 16 insertions(+), 16 deletions(-) diff --git a/.travis.yml b/.travis.yml index 587bd3e031..85242354aa 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1 +1,3 @@ language: node_js +node_js: + - 4 diff --git a/index.js b/index.js index 49c4bf6400..11cde582aa 100755 --- a/index.js +++ b/index.js @@ -1,25 +1,23 @@ /** * Module dependencies. */ -var postcss = require("postcss") -var valueParser = require("postcss-value-parser") -var color = "#639" +const postcss = require("postcss") +const valueParser = require("postcss-value-parser") +const color = "#639" /** * PostCSS plugin to convert colors */ -module.exports = postcss.plugin("postcss-color-rebeccapurple", function() { - return function(style) { - style.walkDecls(function(decl) { - var value = decl.value; +module.exports = postcss.plugin("postcss-color-rebeccapurple", () => (style) => { + style.walkDecls((decl) => { + const value = decl.value; - if (value && value.indexOf("rebeccapurple") !== -1) { - decl.value = valueParser(value).walk(function(node) { - if (node.type === "word" && node.value === "rebeccapurple") { - node.value = color - } - }).toString() - } - }) - } + if (value && value.indexOf("rebeccapurple") !== -1) { + decl.value = valueParser(value).walk((node) => { + if (node.type === "word" && node.value === "rebeccapurple") { + node.value = color + } + }).toString() + } + }) }) From 877bfc48f6b7ab46f76cc8dd92476585f6ee6287 Mon Sep 17 00:00:00 2001 From: Jonathan Neal Date: Wed, 10 May 2017 17:35:18 -0400 Subject: [PATCH 413/795] 4.0.0 - Added: Support for PostCSS v6 - Added: Support for Node v4 - Removed: `prefix` option, as that would be non-spec --- .gitignore | 8 ++- .tape.js | 15 ----- .travis.yml | 2 +- CHANGELOG.md | 6 ++ README.md | 51 ++++++--------- index.js | 112 ++++++++++++++------------------ package.json | 32 ++++----- test/basic.w-prefix.expect.css | 12 ---- test/prefix.css | 12 ---- test/prefix.expect.css | 12 ---- test/prefix.w-prefix.expect.css | 13 ---- 11 files changed, 92 insertions(+), 183 deletions(-) delete mode 100644 test/basic.w-prefix.expect.css delete mode 100644 test/prefix.css delete mode 100644 test/prefix.expect.css delete mode 100644 test/prefix.w-prefix.expect.css diff --git a/.gitignore b/.gitignore index 091413ef02..0de7b9c259 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,7 @@ node_modules -npm-debug.log -test/*.result.css +.* +!.gitignore +!.tape.js +!.travis.yml +*.log* +*.result.css diff --git a/.tape.js b/.tape.js index a3959eed6c..15007b941a 100644 --- a/.tape.js +++ b/.tape.js @@ -2,21 +2,6 @@ module.exports = { 'postcss-pseudo-class-any-link': { 'basic': { message: 'supports basic usage' - }, - 'basic:w-prefix': { - message: 'ignores basic usage when { prefix: "x" }', - options: { - prefix: 'x' - } - }, - 'prefix': { - message: 'supports prefix usage' - }, - 'prefix:w-prefix': { - message: 'supports prefix usage when { prefix: "x" }', - options: { - prefix: 'x' - } } } }; diff --git a/.travis.yml b/.travis.yml index 833d09d149..85242354aa 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,3 +1,3 @@ language: node_js node_js: - - stable + - 4 diff --git a/CHANGELOG.md b/CHANGELOG.md index b8c66696e9..24f5a6d61a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,11 @@ # Changes to :any-link +### 4.0.0 (May 10, 2017) + +- Added: Support for PostCSS v6 +- Added: Support for Node v4 +- Removed: `prefix` option, as that would be non-spec + ### 3.0.1 (December 8, 2016) - Updated: Use destructing assignment on plugin options diff --git a/README.md b/README.md index 8b0685192e..aaea603d38 100644 --- a/README.md +++ b/README.md @@ -1,26 +1,23 @@ -# :any-link PostCSS Logo +# :any-link [PostCSS Logo][postcss] [![NPM Version][npm-img]][npm-url] [![Build Status][cli-img]][cli-url] -[![Licensing][lic-image]][lic-url] -[![Changelog][log-image]][log-url] -[![Gitter Chat][git-image]][git-url] +[![Licensing][lic-img]][lic-url] +[![Changelog][log-img]][log-url] +[![Gitter Chat][git-img]][git-url] [:any-link] lets you to use the proposed [`:any-link`] pseudo-class in CSS. `:any-link` simplifies selectors targeting links, as the naming of `:link` is misleading; it specifically means unvisited links only, rather than all links. ```css -/* before */ - nav :any-link > span { background-color: yellow; } -/* after */ +/* becomes */ -nav :link > span, -nav :visited > span { +nav :link > span, nav :visited > span { background-color: yellow; } ``` @@ -29,28 +26,20 @@ From the [proposal]: > The [`:any-link`] pseudo-class represents an element that acts as the source anchor of a hyperlink. It matches an element if the element would match [`:link`] or [`:visited`]. -## Options - -**prefix** (string): prepends a prefix (surrounded by dashes) to the pseudo-class, preventing any clash with native syntax. - -```js -{ - prefix: 'foo' // pseudo-class becomes :-foo-any-link -} -``` - ## Usage Add [:any-link] to your build tool: ```bash -npm install :any-link --save-dev +npm install postcss-pseudo-class-any-link --save-dev ``` #### Node +Use [:any-link] to process your CSS: + ```js -require(':any-link').process(YOUR_CSS, { /* options */ }); +require('postcss-pseudo-class-any-link').process(YOUR_CSS); ``` #### PostCSS @@ -61,12 +50,12 @@ Add [PostCSS] to your build tool: npm install postcss --save-dev ``` -Load [:any-link] as a PostCSS plugin: +Use [:any-link] as a plugin: ```js postcss([ - require(':any-link')({ /* options */ }) -]).process(YOUR_CSS, /* options */); + require('postcss-pseudo-class-any-link')() +]).process(YOUR_CSS); ``` #### Gulp @@ -77,7 +66,7 @@ Add [Gulp PostCSS] to your build tool: npm install gulp-postcss --save-dev ``` -Enable [:any-link] within your Gulpfile: +Use [:any-link] in your Gulpfile: ```js var postcss = require('gulp-postcss'); @@ -85,7 +74,7 @@ var postcss = require('gulp-postcss'); gulp.task('css', function () { return gulp.src('./src/*.css').pipe( postcss([ - require(':any-link')({ /* options */ }) + require('postcss-pseudo-class-any-link')() ]) ).pipe( gulp.dest('.') @@ -101,7 +90,7 @@ Add [Grunt PostCSS] to your build tool: npm install grunt-postcss --save-dev ``` -Enable [:any-link] within your Gruntfile: +Use [:any-link] in your Gruntfile: ```js grunt.loadNpmTasks('grunt-postcss'); @@ -110,7 +99,7 @@ grunt.initConfig({ postcss: { options: { use: [ - require(':any-link')({ /* options */ }) + require('postcss-pseudo-class-any-link')() ] }, dist: { @@ -145,11 +134,11 @@ Here are a few other ways to simulate the effect of [PostCSS Pseudo-Class Any-Li [cli-url]: https://travis-ci.org/jonathantneal/postcss-pseudo-class-any-link [cli-img]: https://img.shields.io/travis/jonathantneal/postcss-pseudo-class-any-link.svg [lic-url]: LICENSE.md -[lic-image]: https://img.shields.io/npm/l/postcss-pseudo-class-any-link.svg +[lic-img]: https://img.shields.io/npm/l/postcss-pseudo-class-any-link.svg [log-url]: CHANGELOG.md -[log-image]: https://img.shields.io/badge/changelog-md-blue.svg +[log-img]: https://img.shields.io/badge/changelog-md-blue.svg [git-url]: https://gitter.im/postcss/postcss -[git-image]: https://img.shields.io/badge/chat-gitter-blue.svg +[git-img]: https://img.shields.io/badge/chat-gitter-blue.svg [:any-link]: https://github.com/jonathantneal/postcss-pseudo-class-any-link [`:any-link`]: http://dev.w3.org/csswg/selectors/#any-link-pseudo diff --git a/index.js b/index.js index 27df8f2608..94d3f59d5b 100644 --- a/index.js +++ b/index.js @@ -1,73 +1,55 @@ +'use strict'; + // tooling const postcss = require('postcss'); const parser = require('postcss-selector-parser'); // plugin -module.exports = postcss.plugin('postcss-pseudo-class-any-link', ({ - prefix = '' -} = {}) => { - // dashed prefix - const dashedPrefix = prefix ? `-${ prefix }-` : ''; - - // any-link value - const anyLinkValue = `:${ dashedPrefix }any-link`; - - // selector matcher - const selectorMatch = new RegExp(`${ dashedPrefix }any-link`); - - return (css) => { - // walk each matching rule - css.walkRules(selectorMatch, (rule) => { - const rawSelector = rule.raws.selector && rule.raws.selector.raw || rule.selector; - - // workaround for https://github.com/postcss/postcss-selector-parser/issues/28#issuecomment-171910556 - if (rawSelector[rawSelector.length - 1] !== ':') { - // update the selector - rule.selector = parser((selectors) => { - // cache variables - let node; - let nodeIndex; - let selector; - let selectorLink; - let selectorVisited; - - // cache the selector index - let selectorIndex = -1; - - // for each selector - while (selector = selectors.nodes[++selectorIndex]) { - // reset the node index - nodeIndex = -1; - - // for each node - while (node = selector.nodes[++nodeIndex]) { - // if the node value matches the any-link value - if (node.value === anyLinkValue) { - // clone the selector - selectorLink = selector.clone(); - selectorVisited = selector.clone(); - - // update the matching clone values - selectorLink.nodes[nodeIndex].value = ':link'; - selectorVisited.nodes[nodeIndex].value = ':visited'; - - // replace the selector with the clones and roll back the selector index - selectors.nodes.splice(selectorIndex--, 1, selectorLink, selectorVisited); - - // stop updating the selector - break; - } +module.exports = postcss.plugin('postcss-pseudo-class-any-link', () => (css) => { + // walk each matching rule + css.walkRules(/:any-link/, (rule) => { + const rawSelector = rule.raws.selector && rule.raws.selector.raw || rule.selector; + + // workaround for https://github.com/postcss/postcss-selector-parser/issues/28#issuecomment-171910556 + if (rawSelector[rawSelector.length - 1] !== ':') { + // update the selector + rule.selector = parser((selectors) => { + // cache variables + let node; + let nodeIndex; + let selector; + let selectorLink; + let selectorVisited; + + // cache the selector index + let selectorIndex = -1; + + // for each selector + while (selector = selectors.nodes[++selectorIndex]) { + // reset the node index + nodeIndex = -1; + + // for each node + while (node = selector.nodes[++nodeIndex]) { + // if the node value matches the any-link value + if (node.value === ':any-link') { + // clone the selector + selectorLink = selector.clone(); + selectorVisited = selector.clone(); + + // update the matching clone values + selectorLink.nodes[nodeIndex].value = ':link'; + selectorVisited.nodes[nodeIndex].value = ':visited'; + + // replace the selector with the clones and roll back the selector index + selectors.nodes.splice(selectorIndex--, 1, selectorLink, selectorVisited); + + // stop updating the selector + break; } } - }).process(rawSelector).result; - } - }); - }; + } + }).process(rawSelector).result; + } + }); }); - -// override plugin#process -module.exports.process = function (cssString, pluginOptions, processOptions) { - return postcss([ - 1 in arguments ? module.exports(pluginOptions) : module.exports() - ]).process(cssString, processOptions); -}; diff --git a/package.json b/package.json index 8db6daefc4..9a1778c13e 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "postcss-pseudo-class-any-link", - "version": "3.0.1", + "version": "4.0.0", "description": "Use the proposed :any-link pseudo-class in CSS", "author": "Jonathan Neal ", "license": "CC0-1.0", @@ -12,29 +12,24 @@ "index.js" ], "scripts": { - "lint": "echint && eslint index.js && jscs index.js", + "clean": "git clean -X -d -f", "prepublish": "npm test", - "tape": "postcss-tape", - "test": "npm run lint && postcss-tape" + "test": "echo 'Running tests...'; npm run test:js && npm run test:tape", + "test:js": "eslint *.js --cache --ignore-pattern .gitignore", + "test:tape": "postcss-tape" }, "engines": { - "node": ">=6.9.1" + "node": ">=4.0.0" }, "dependencies": { - "postcss": "^5.2.6", - "postcss-selector-parser": "^2.2.2" + "postcss": "^6.0.1", + "postcss-selector-parser": "^2.2.3" }, "devDependencies": { - "echint": "^2.1.0", - "echint-config-dev": "1.0.0", - "eslint": "^3.12.1", - "eslint-config-dev": "1.0.0", - "jscs": "^3.0.7", - "jscs-config-dev": "1.0.1", - "postcss-tape": "1.3.0" - }, - "echint": { - "extends": "dev" + "eslint": "^3.19.0", + "eslint-config-dev": "2.0.0", + "postcss-tape": "2.0.1", + "pre-commit": "^1.2.2" }, "eslintConfig": { "extends": "dev", @@ -42,9 +37,6 @@ "sourceType": "module" } }, - "jscsConfig": { - "preset": "dev" - }, "keywords": [ "postcss", "css", diff --git a/test/basic.w-prefix.expect.css b/test/basic.w-prefix.expect.css deleted file mode 100644 index e0ca56047b..0000000000 --- a/test/basic.w-prefix.expect.css +++ /dev/null @@ -1,12 +0,0 @@ -:any-link { - background: blue; -} - -:any-link, -ul a:any-link > span { - background: blue; -} - -:any-link :any-link { - background: blue; -} diff --git a/test/prefix.css b/test/prefix.css deleted file mode 100644 index d8c7ac8a11..0000000000 --- a/test/prefix.css +++ /dev/null @@ -1,12 +0,0 @@ -:-x-any-link { - background: blue; -} - -:-x-any-link, -ul a:-x-any-link > span { - background: blue; -} - -:-x-any-link :-x-any-link { - background: blue; -} diff --git a/test/prefix.expect.css b/test/prefix.expect.css deleted file mode 100644 index d8c7ac8a11..0000000000 --- a/test/prefix.expect.css +++ /dev/null @@ -1,12 +0,0 @@ -:-x-any-link { - background: blue; -} - -:-x-any-link, -ul a:-x-any-link > span { - background: blue; -} - -:-x-any-link :-x-any-link { - background: blue; -} diff --git a/test/prefix.w-prefix.expect.css b/test/prefix.w-prefix.expect.css deleted file mode 100644 index 806a50e056..0000000000 --- a/test/prefix.w-prefix.expect.css +++ /dev/null @@ -1,13 +0,0 @@ -:link,:visited { - background: blue; -} - -:link,:visited, -ul a:link > span, -ul a:visited > span { - background: blue; -} - -:link :link,:link :visited,:visited :link,:visited :visited { - background: blue; -} From 712582a5a4dd3a7094b47981bcf7fa0e12c62f98 Mon Sep 17 00:00:00 2001 From: Jonathan Neal Date: Wed, 10 May 2017 19:43:46 -0400 Subject: [PATCH 414/795] Use PostCSS 6 - Update .travis.yml to test against Node 4 --- .travis.yml | 2 ++ package.json | 4 ++-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index 587bd3e031..85242354aa 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1 +1,3 @@ language: node_js +node_js: + - 4 diff --git a/package.json b/package.json index 516fcdc067..d460998b90 100644 --- a/package.json +++ b/package.json @@ -27,10 +27,10 @@ "index.js" ], "dependencies": { - "postcss": "^5.0.4" + "postcss": "^6.0.1" }, "devDependencies": { - "tape": "^3.0.0" + "tape": "^4.6.3" }, "bugs": { "url": "https://github.com/postcss/postcss-media-minmax/issues" From 470737f36d4d6fbee19028e10e57293a63f59d59 Mon Sep 17 00:00:00 2001 From: Jonathan Neal Date: Wed, 10 May 2017 19:44:18 -0400 Subject: [PATCH 415/795] Update comment test PostCSS 6 gets the whitespace here correctly now --- test/fixtures/comment.output.css | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/fixtures/comment.output.css b/test/fixtures/comment.output.css index fc0d86f105..8f1637b562 100644 --- a/test/fixtures/comment.output.css +++ b/test/fixtures/comment.output.css @@ -1,10 +1,10 @@ -@media screen and (min-width: 500px) and (max-width: 1200px)/* comment */ { +@media screen and (min-width: 500px) and (max-width: 1200px) /* comment */{ .bar { display: block; } } -@media screen and (min-width: 500px) and (max-width: 1200px)/* comment */ { +@media screen and (min-width: 500px) and (max-width: 1200px) /* comment */{ .bar { display: block; } From 97e08611f65a7344691ac8372472bb14574e3f96 Mon Sep 17 00:00:00 2001 From: Jonathan Neal Date: Wed, 10 May 2017 19:47:55 -0400 Subject: [PATCH 416/795] 3.0.0 --- CHANGELOG.md | 4 ++++ package.json | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3cafbc0f6b..7a70463673 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,7 @@ +# 3.0.0 2017-05-10 + +Change: Use PostCSS 6 API. + # 2.1.2 2016-04-01 Fix: incorrect output when using both > and >= (or similar).(#12) diff --git a/package.json b/package.json index d460998b90..37d140b94d 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "postcss-media-minmax", - "version": "2.1.2", + "version": "3.0.0", "description": "Using more intuitive `>=`, `<=`, `>`, `<` instead of media queries min/max prefix.", "scripts": { "test": "tape test" From 00291bb8a709a6e1236b4e48fa8e613f94fe3a3e Mon Sep 17 00:00:00 2001 From: Maxime Thirouin Date: Thu, 11 May 2017 06:28:28 +0200 Subject: [PATCH 417/795] chore: add npmpub for release --- package.json | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) diff --git a/package.json b/package.json index 37d140b94d..2e22b64729 100644 --- a/package.json +++ b/package.json @@ -3,12 +3,10 @@ "version": "3.0.0", "description": "Using more intuitive `>=`, `<=`, `>`, `<` instead of media queries min/max prefix.", "scripts": { - "test": "tape test" - }, - "repository": { - "type": "git", - "url": "https://github.com/postcss/postcss-media-minmax.git" + "test": "tape test", + "release": "npmpub" }, + "repository": "https://github.com/postcss/postcss-media-minmax.git", "keywords": [ "css", "css3", @@ -30,10 +28,7 @@ "postcss": "^6.0.1" }, "devDependencies": { + "npmpub": "^3.1.0", "tape": "^4.6.3" - }, - "bugs": { - "url": "https://github.com/postcss/postcss-media-minmax/issues" - }, - "homepage": "https://github.com/postcss/postcss-media-minmax" + } } From 83b15566e9d3d623fe982092ee55b4639946d19e Mon Sep 17 00:00:00 2001 From: Jonathan Neal Date: Thu, 11 May 2017 00:37:50 -0400 Subject: [PATCH 418/795] Changed: Use PostCSS 6 (#9) - Also, update jscs, jshint, and tape --- .travis.yml | 2 ++ package.json | 8 ++++---- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/.travis.yml b/.travis.yml index 587bd3e031..85242354aa 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1 +1,3 @@ language: node_js +node_js: + - 4 diff --git a/package.json b/package.json index 55f642d6c3..dc9ca324f0 100644 --- a/package.json +++ b/package.json @@ -20,13 +20,13 @@ "index.js" ], "dependencies": { - "postcss": "^5.0.4" + "postcss": "^6.0.1" }, "devDependencies": { - "jscs": "^2.1.0", - "jshint": "^2.8.0", + "jscs": "^3.0.7", + "jshint": "^2.9.4", "npmpub": "^3.1.0", - "tape": "^4.0.3" + "tape": "^4.6.3" }, "scripts": { "lint": "npm run jscs && npm run jshint", From da76fb0fec87ed0e40286a77860fc9fa026eb3b7 Mon Sep 17 00:00:00 2001 From: Maxime Thirouin Date: Thu, 11 May 2017 06:40:20 +0200 Subject: [PATCH 419/795] 3.0.0 --- CHANGELOG.md | 4 ++++ package.json | 7 ++----- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2c6a4c2b59..f984a47fb2 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,7 @@ +# 3.0.0 - 2017-05-11 + +- Changed: use PostCSS 6 API + # 2.0.1 - 2016-07-08 - Fixed: existing font-feature-settings being duplicated. diff --git a/package.json b/package.json index dc9ca324f0..46ce82d6a9 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "postcss-font-variant", - "version": "2.0.1", + "version": "3.0.0", "description": "PostCSS plugin to transform W3C font-variant properties to more compatible CSS (font-feature-settings)", "keywords": [ "css", @@ -12,10 +12,7 @@ ], "author": "Maxime Thirouin", "license": "MIT", - "repository": { - "type": "git", - "url": "https://github.com/postcss/postcss-font-variant.git" - }, + "repository": "https://github.com/postcss/postcss-font-variant.git", "files": [ "index.js" ], From efa6b4db7d1298e9956f4d380f4bb23cb1a05460 Mon Sep 17 00:00:00 2001 From: Dmitry Semigradsky Date: Thu, 11 May 2017 09:42:41 +0300 Subject: [PATCH 420/795] 3.0.0 --- CHANGELOG.md | 4 ++++ LICENSE | 2 +- package.json | 2 +- 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0fbb5e6964..8a43031f3e 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,7 @@ +# 3.0.0 - 2017-05-11 + +- Added: compatibility with postcss v6.x + # 2.0.0 - 2015-08-25 - Removed: compatibility with postcss v4.x diff --git a/LICENSE b/LICENSE index 372f03009a..b75f6e61cd 100755 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,6 @@ The MIT License (MIT) -Copyright (c) 2015 Maxime Thirouin +Copyright (c) 2017 Maxime Thirouin 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 diff --git a/package.json b/package.json index f9f9bd05fc..402f8e8f8f 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "postcss-selector-not", - "version": "2.0.0", + "version": "3.0.0", "description": "PostCSS plugin to transform :not() W3C CSS level 4 pseudo class to :not() CSS level 3 selectors", "keywords": [ "postcss", From 0206644c957fc5daa7c39b72aa1355a94e208ff2 Mon Sep 17 00:00:00 2001 From: Dmitry Semigradsky Date: Thu, 11 May 2017 16:55:51 +0300 Subject: [PATCH 421/795] Update dependencies --- .babelrc | 7 +++++-- .eslintignore | 2 +- .eslintrc => .eslintrc.yml | 14 +++----------- package.json | 20 +++++++++++--------- src/index.js | 5 +---- test/index.js | 10 +++++----- 6 files changed, 26 insertions(+), 32 deletions(-) rename .eslintrc => .eslintrc.yml (82%) diff --git a/.babelrc b/.babelrc index 9e3d2741fd..6e6df8faf2 100644 --- a/.babelrc +++ b/.babelrc @@ -1,6 +1,9 @@ { "presets": [ - "es2015", - "stage-2" + ["env", { + "targets": { + "node": 4 + } + }] ] } diff --git a/.eslintignore b/.eslintignore index 3e4e48b0b5..1521c8b765 120000 --- a/.eslintignore +++ b/.eslintignore @@ -1 +1 @@ -.gitignore \ No newline at end of file +dist diff --git a/.eslintrc b/.eslintrc.yml similarity index 82% rename from .eslintrc rename to .eslintrc.yml index 2746c02b60..ec22acd0a3 100644 --- a/.eslintrc +++ b/.eslintrc.yml @@ -1,22 +1,14 @@ ---- root: true extends: eslint:recommended -ecmaFeatures: - modules: true - parserOptions: - sourceType: module - -env: - es6: true - browser: true - node: true + ecmaVersion: 6 + sourceType: "module" rules: indent: [2, 2] # 2 spaces indentation max-len: [2, 80, 4] - quotes: [2, "double", {"allowTemplateLiterals": true}] + quotes: [2, "double"] semi: [2, "never"] no-multiple-empty-lines: [2, {"max": 1}] diff --git a/package.json b/package.json index dc61e38cc2..4088ac7839 100644 --- a/package.json +++ b/package.json @@ -18,22 +18,24 @@ ], "dependencies": { "balanced-match": "^0.4.2", - "postcss": "^5.0.0" + "postcss": "^6.0.1" }, "devDependencies": { - "babel-cli": "^6.14.0", + "babel-cli": "^6.24.1", + "babel-preset-env": "^1.4.0", "babel-preset-es2015": "^6.14.0", "babel-preset-stage-2": "^6.13.0", - "babel-tape-runner": "^2.0.1", - "eslint": "^3.4.0", + "babel-register": "^6.24.1", + "eslint": "^3.19.0", "npmpub": "^3.1.0", - "tape": "^4.0.0" + "tape": "^4.6.3" }, "scripts": { - "lint": "eslint .", - "tape": "babel-tape-runner 'test/*.js'", - "test": "npm run lint && npm run tape", - "prepublish": "babel src --out-dir dist", + "lint": "eslint *.js ./src/ ./test/", + "tape": "tape -r babel-register test/*.js", + "test": "npm run lint && npm run babelify && npm run tape", + "babelify": "babel src --out-dir dist", + "prepublish": "npm run babelify", "release": "npmpub" } } diff --git a/src/index.js b/src/index.js index 4aedb708bd..7e5f6f946b 100644 --- a/src/index.js +++ b/src/index.js @@ -12,7 +12,4 @@ function explodeSelectors(options = {}) { } -module.exports = postcss.plugin( - "postcss-selector-matches", - explodeSelectors -) +export default postcss.plugin("postcss-selector-matches", explodeSelectors) diff --git a/test/index.js b/test/index.js index e9f793c4a6..77d9def725 100644 --- a/test/index.js +++ b/test/index.js @@ -117,19 +117,19 @@ button:hover, button:active, .button:hover, .button:active {}`, ) t.equal( - transform(`.foo:matches(:hover, :focus)::before {}`), - `.foo:hover::before, .foo:focus::before {}`, + transform(".foo:matches(:hover, :focus)::before {}"), + ".foo:hover::before, .foo:focus::before {}", "should work with something after :matches()" ) t.equal( - transform(`article :matches(h1, h2, h3) + p {}`), - `article h1 + p, article h2 + p, article h3 + p {}`, + transform("article :matches(h1, h2, h3) + p {}"), + "article h1 + p, article h2 + p, article h3 + p {}", "should works correctly with adjacent selectors" ) t.equal( - transform(`article :matches(h1, h2, h3) + p {}`, {lineBreak: true}), + transform("article :matches(h1, h2, h3) + p {}", {lineBreak: true}), `article h1 + p, article h2 + p, article h3 + p {}`, From b701fa61e39bec9547006c76eee6c9657f3a7892 Mon Sep 17 00:00:00 2001 From: Dmitry Semigradsky Date: Thu, 11 May 2017 17:20:01 +0300 Subject: [PATCH 422/795] 3.0.0 --- CHANGELOG.md | 4 ++++ LICENSE | 2 +- package.json | 2 +- 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4dac5f1246..aa23fdc3f5 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,7 @@ +# 3.0.0 - 2017-05-11 + +- Added: compatibility with postcss v6.x + # 2.0.5 - 2016-09-13 - Fixed: another regression of 2.0.2 diff --git a/LICENSE b/LICENSE index 8b39b8f151..b75f6e61cd 100755 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,6 @@ The MIT License (MIT) -Copyright (c) 2014 Maxime Thirouin +Copyright (c) 2017 Maxime Thirouin 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 diff --git a/package.json b/package.json index 4088ac7839..3e53e0eac5 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "postcss-selector-matches", - "version": "2.0.5", + "version": "3.0.0", "description": "PostCSS plugin to transform :matches() W3C CSS pseudo class to more compatible CSS selectors", "keywords": [ "postcss", From fb5c00753fcf175ef7bc8b8eefa76293191ed0f0 Mon Sep 17 00:00:00 2001 From: Dmitry Semigradsky Date: Fri, 12 May 2017 11:16:44 +0300 Subject: [PATCH 423/795] Update dependencies --- .babelrc | 9 ++++++++- .eslintignore | 1 + .eslintrc => .eslintrc.yml | 7 +------ package.json | 22 +++++++++++++--------- 4 files changed, 23 insertions(+), 16 deletions(-) create mode 100644 .eslintignore rename .eslintrc => .eslintrc.yml (97%) diff --git a/.babelrc b/.babelrc index b0b9a96ef0..9fdb6b51d8 100644 --- a/.babelrc +++ b/.babelrc @@ -1,3 +1,10 @@ { - "stage": 0 + "presets": [ + ["env", { + "targets": { + "node": 4 + } + }] + ], + "plugins": ["transform-object-rest-spread"] } diff --git a/.eslintignore b/.eslintignore new file mode 100644 index 0000000000..1521c8b765 --- /dev/null +++ b/.eslintignore @@ -0,0 +1 @@ +dist diff --git a/.eslintrc b/.eslintrc.yml similarity index 97% rename from .eslintrc rename to .eslintrc.yml index 8fb0de30fd..39a8cb81ad 100644 --- a/.eslintrc +++ b/.eslintrc.yml @@ -1,17 +1,12 @@ ---- - root: true extends: eslint:recommended parserOptions: - sourceType: "module" ecmaVersion: 6 + sourceType: "module" ecmaFeatures: experimentalObjectRestSpread: true -env: - node: true - rules: indent: [2, 2] # 2 spaces indentation max-len: [2, 80, 4] diff --git a/package.json b/package.json index fcf7c978b7..298519432c 100644 --- a/package.json +++ b/package.json @@ -24,19 +24,23 @@ "README-zh.md" ], "dependencies": { - "postcss": "^5.0.0", - "postcss-selector-matches": "^2.0.0" + "postcss": "^6.0.1", + "postcss-selector-matches": "^3.0.0" }, "devDependencies": { - "babel": "^5.5.8", + "babel-cli": "^6.24.1", + "babel-plugin-transform-object-rest-spread": "^6.23.0", + "babel-preset-env": "^1.4.0", + "babel-register": "^6.24.1", "babel-tape-runner": "^1.1.0", - "eslint": "^3.15.0", - "tape": "^4.0.0" + "eslint": "^3.19.0", + "tape": "^4.6.3" }, "scripts": { - "prepublish": "babel src --out-dir dist", - "lint": "eslint src test", - "tape": "babel-tape-runner test/*.js", - "test": "npm run lint && npm run tape" + "babelify": "babel src --out-dir dist", + "prepublish": "npm run babelify", + "lint": "eslint *.js ./src/ ./test/", + "tape": "tape -r babel-register test/*.js", + "test": "npm run lint && npm run babelify && npm run tape" } } From dbfa0b3ed42be73cd36fb25d7a74785b8b7af33a Mon Sep 17 00:00:00 2001 From: Dmitry Semigradsky Date: Fri, 12 May 2017 11:20:00 +0300 Subject: [PATCH 424/795] 4.0.0 --- CHANGELOG.md | 4 ++++ LICENSE | 2 +- package.json | 2 +- 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 53643bc26a..1b46be9f2e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,7 @@ +# 4.0.0 - 2017-05-12 + +- Added: compatibility with postcss v6.x + # 3.0.0 - 2015-08-25 - Removed: compatibility with postcss v4.x diff --git a/LICENSE b/LICENSE index 9d10f01975..3c9a87231c 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,6 @@ The MIT License (MIT) -Copyright (c) 2014 PostCSS +Copyright (c) 2017 PostCSS Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/package.json b/package.json index 298519432c..6432a56449 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "postcss-custom-selectors", - "version": "3.0.0", + "version": "4.0.0", "description": "PostCSS plugin to transform W3C CSS Extensions(Custom Selectors) to more compatible CSS", "keywords": [ "postcss", From a8025c458560747a045c4dd1a49c0c5213678ff4 Mon Sep 17 00:00:00 2001 From: Dmitry Semigradsky Date: Fri, 12 May 2017 11:42:01 +0300 Subject: [PATCH 425/795] Update dependencies --- .babelrc | 9 +++ .eslintignore | 1 + .eslintrc => .eslintrc.yml | 17 ++---- .gitignore | 1 + .travis.yml | 5 ++ index.js | 109 +++++++++++++++++-------------------- package.json | 18 ++++-- test/index.js | 37 +++++++------ 8 files changed, 103 insertions(+), 94 deletions(-) create mode 100644 .babelrc create mode 100644 .eslintignore rename .eslintrc => .eslintrc.yml (81%) diff --git a/.babelrc b/.babelrc new file mode 100644 index 0000000000..6e6df8faf2 --- /dev/null +++ b/.babelrc @@ -0,0 +1,9 @@ +{ + "presets": [ + ["env", { + "targets": { + "node": 4 + } + }] + ] +} diff --git a/.eslintignore b/.eslintignore new file mode 100644 index 0000000000..1521c8b765 --- /dev/null +++ b/.eslintignore @@ -0,0 +1 @@ +dist diff --git a/.eslintrc b/.eslintrc.yml similarity index 81% rename from .eslintrc rename to .eslintrc.yml index 18d7c97bd3..ec22acd0a3 100644 --- a/.eslintrc +++ b/.eslintrc.yml @@ -1,14 +1,9 @@ ---- root: true extends: eslint:recommended -#ecmaFeatures: -# modules: true - -env: -# es6: true - browser: true - node: true +parserOptions: + ecmaVersion: 6 + sourceType: "module" rules: indent: [2, 2] # 2 spaces indentation @@ -23,8 +18,8 @@ rules: dot-location: [2, "property"] one-var: [2, "never"] -# no-var: [2] -# prefer-const: [2] + no-var: [2] + prefer-const: [2] no-bitwise: [2] object-curly-spacing: [2, "never"] @@ -32,7 +27,7 @@ rules: computed-property-spacing: [2, "never"] space-unary-ops: [2, {"words": true, "nonwords": false}] - space-after-keywords: [2, "always"] + keyword-spacing: [2, {"before": true, "after": true}] space-before-blocks: [2, "always"] space-before-function-paren: [2, "never"] space-in-parens: [2, "never"] diff --git a/.gitignore b/.gitignore index 7ab649f420..319d993c5f 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ +dist node_modules test/fixtures/*.actual.css diff --git a/.travis.yml b/.travis.yml index 587bd3e031..6e538237ad 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1 +1,6 @@ +sudo: false language: node_js +node_js: + - "stable" + - "6" + - "4" diff --git a/index.js b/index.js index 7d8e3d2913..5e98545765 100755 --- a/index.js +++ b/index.js @@ -1,23 +1,15 @@ -/** - * Module dependencies. - */ - -var postcss = require("postcss") -var balanced = require("balanced-match") +import postcss from "postcss" +import balanced from "balanced-match" -/** - * Constants. - */ - -var VAR_PROP_IDENTIFIER = "--" -var VAR_FUNC_IDENTIFIER = "var" +const VAR_PROP_IDENTIFIER = "--" +const VAR_FUNC_IDENTIFIER = "var" // matches `name[, fallback]`, captures "name" and "fallback" -var RE_VAR = /([\w-]+)(?:\s*,\s*)?\s*(.*)?/ +const RE_VAR = /([\w-]+)(?:\s*,\s*)?\s*(.*)?/ /** * Resolve CSS variables. * - * The second argument to the CSS variable function, var(name[, fallback]), + * The second argument to the CSS variable function, var(name[, fallback]), * is used in the event that first argument cannot be resolved. * * @param {String} value May contain the CSS variable function @@ -26,19 +18,18 @@ var RE_VAR = /([\w-]+)(?:\s*,\s*)?\s*(.*)?/ * @param {Object} decl The declaration containing the rule * @return {String} A property value with all CSS variables substituted. */ - function resolveValue(value, variables, result, decl) { - var results = [] + const results = [] - var start = value.indexOf(VAR_FUNC_IDENTIFIER + "(") + const start = value.indexOf(VAR_FUNC_IDENTIFIER + "(") if (start === -1) { return [value] } - var matches = balanced("(", ")", value.substring(start)) + const matches = balanced("(", ")", value.substring(start)) if (!matches) { - throw decl.error("missing closing ')' in the value '" + value + "'") + throw decl.error(`missing closing ')' in the value '${value}'`) } if (matches.body === "") { @@ -46,8 +37,8 @@ function resolveValue(value, variables, result, decl) { } matches.body.replace(RE_VAR, function(_, name, fallback) { - var variable = variables[name] - var post + const variable = variables[name] + let post // undefined and without fallback, just keep original value if (!variable && !fallback) { result.warn( @@ -75,8 +66,8 @@ function resolveValue(value, variables, result, decl) { post = matches.post ? resolveValue(matches.post, variables, result, decl) : [""] - fallback.forEach(function(fbValue) { - post.forEach(function(afterValue) { + fallback.forEach((fbValue) => { + post.forEach((afterValue) => { results.push(value.slice(0, start) + fbValue + afterValue) }) }) @@ -113,8 +104,8 @@ function resolveValue(value, variables, result, decl) { post = matches.post ? resolveValue(matches.post, variables, result, decl) : [""] - variable.value.forEach(function(replacementValue) { - post.forEach(function(afterValue) { + variable.value.forEach((replacementValue) => { + post.forEach((afterValue) => { results.push(value.slice(0, start) + replacementValue + afterValue) }) }) @@ -124,14 +115,14 @@ function resolveValue(value, variables, result, decl) { } function prefixVariables(variables) { - var prefixedVariables = {} + const prefixedVariables = {} if (!variables) { return prefixVariables } - Object.keys(variables).forEach(function(name) { - var val = variables[name] + Object.keys(variables).forEach((name) => { + const val = variables[name] if (name.slice(0, 2) !== "--") { name = "--" + name } @@ -144,26 +135,24 @@ function prefixVariables(variables) { /** * Module export. */ - -module.exports = postcss.plugin("postcss-custom-properties", function(options) { - options = options || {} +export default postcss.plugin("postcss-custom-properties", (options = {}) => { function setVariables(variables) { options.variables = prefixVariables(variables) } function plugin(style, result) { - var warnings = options.warnings === undefined ? true : options.warnings - var variables = prefixVariables(options.variables) - var strict = options.strict === undefined ? true : options.strict - var appendVariables = options.appendVariables - var preserve = options.preserve - var map = {} - var importantMap = {} + const warnings = options.warnings === undefined ? true : options.warnings + const variables = prefixVariables(options.variables) + const strict = options.strict === undefined ? true : options.strict + const appendVariables = options.appendVariables + const preserve = options.preserve + const map = {} + const importantMap = {} // define variables - style.walkRules(function(rule) { - var toRemove = [] + style.walkRules((rule) => { + const toRemove = [] // only variables declared for `:root` are supported for now if ( @@ -171,8 +160,8 @@ module.exports = postcss.plugin("postcss-custom-properties", function(options) { rule.selectors[0] !== ":root" || rule.parent.type !== "root" ) { - rule.each(function(decl) { - var prop = decl.prop + rule.each((decl) => { + const prop = decl.prop if ( warnings && prop && @@ -180,7 +169,7 @@ module.exports = postcss.plugin("postcss-custom-properties", function(options) { ) { result.warn( "Custom property ignored: not scoped to the top-level :root " + - "element (" + rule.selectors + " { ... " + prop + ": ... })" + + `element (${rule.selectors} { ... ${prop}: ... })` + (rule.parent.type !== "root" ? ", in " + rule.parent.type : ""), {node: decl} ) @@ -189,8 +178,8 @@ module.exports = postcss.plugin("postcss-custom-properties", function(options) { return } - rule.each(function(decl, index) { - var prop = decl.prop + rule.each((decl, index) => { + const prop = decl.prop if (prop && prop.indexOf(VAR_PROP_IDENTIFIER) === 0) { if (!map[prop] || !importantMap[prop] || decl.important) { map[prop] = { @@ -207,7 +196,7 @@ module.exports = postcss.plugin("postcss-custom-properties", function(options) { // optionally remove `--*` properties from the rule if (!preserve) { - for (var i = toRemove.length - 1; i >= 0; i--) { + for (let i = toRemove.length - 1; i >= 0; i--) { rule.nodes.splice(toRemove[i], 1) } @@ -219,7 +208,7 @@ module.exports = postcss.plugin("postcss-custom-properties", function(options) { }) // apply js-defined custom properties - Object.keys(variables).forEach(function(variable) { + Object.keys(variables).forEach((variable) => { map[variable] = { value: variables[variable], deps: [], @@ -229,8 +218,8 @@ module.exports = postcss.plugin("postcss-custom-properties", function(options) { }) if (preserve) { - Object.keys(map).forEach(function(name) { - var variable = map[name] + Object.keys(map).forEach((name) => { + const variable = map[name] if (!variable.resolved) { variable.value = resolveValue(variable.value, map, result) variable.resolved = true @@ -239,20 +228,20 @@ module.exports = postcss.plugin("postcss-custom-properties", function(options) { } // resolve variables - style.walkDecls(function(decl) { - var value = decl.value + style.walkDecls((decl) => { + const value = decl.value // skip values that don’t contain variable functions if (!value || value.indexOf(VAR_FUNC_IDENTIFIER + "(") === -1) { return } - var resolved = resolveValue(value, map, result, decl) + let resolved = resolveValue(value, map, result, decl) if (!strict) { resolved = [resolved.pop()] } - resolved.forEach(function(resolvedValue) { - var clone = decl.cloneBefore() + resolved.forEach((resolvedValue) => { + const clone = decl.cloneBefore() clone.value = resolvedValue }) @@ -262,19 +251,19 @@ module.exports = postcss.plugin("postcss-custom-properties", function(options) { }) if (preserve && appendVariables) { - var names = Object.keys(map) + const names = Object.keys(map) if (names.length) { - var container = postcss.rule({ + const container = postcss.rule({ selector: ":root", raws: {semicolon: true}, }) - names.forEach(function(name) { - var variable = map[name] - var val = variable.value + names.forEach((name) => { + const variable = map[name] + let val = variable.value if (variable.resolved) { val = val[val.length - 1] } - var decl = postcss.decl({ + const decl = postcss.decl({ prop: name, value: val, }) diff --git a/package.json b/package.json index c761c9a6a8..bffa068ae6 100644 --- a/package.json +++ b/package.json @@ -13,20 +13,28 @@ "author": "Maxime Thirouin", "license": "MIT", "repository": "https://github.com/postcss/postcss-custom-properties.git", + "main": "dist/index.js", "files": [ - "index.js" + "dist" ], "dependencies": { "balanced-match": "^0.4.2", - "postcss": "^5.0.0" + "postcss": "^6.0.1" }, "devDependencies": { - "eslint": "^1.0.0", + "babel-cli": "^6.24.1", + "babel-preset-env": "^1.4.0", + "babel-register": "^6.24.1", + "eslint": "^3.19.0", "npmpub": "^3.1.0", - "tape": "^4.0.0" + "tape": "^4.6.3" }, "scripts": { - "test": "eslint . && tape test", + "lint": "eslint *.js index.js ./test/", + "tape": "tape -r babel-register test/*.js", + "test": "npm run lint && npm run babelify && npm run tape", + "babelify": "babel index.js --out-dir dist", + "prepublish": "npm run babelify", "release": "npmpub" } } diff --git a/test/index.js b/test/index.js index 003919a5b9..1978b84f3e 100755 --- a/test/index.js +++ b/test/index.js @@ -1,9 +1,9 @@ -var fs = require("fs") +import fs from "fs" -var test = require("tape") +import test from "tape" -var postcss = require("postcss") -var customProperties = require("..") +import postcss from "postcss" +import customProperties from ".." function fixturePath(name) { return "test/fixtures/" + name + ".css" @@ -19,13 +19,13 @@ function resolveFixture(name, options) { } function compareFixtures(t, name, options) { - var postcssResult = resolveFixture(name, options) - var actual = postcssResult.css.trim() + const postcssResult = resolveFixture(name, options) + const actual = postcssResult.css.trim() // handy thing: checkout actual in the *.actual.css file fs.writeFile(fixturePath(name + ".actual"), actual) - var expected = fixture(name + ".expected") + const expected = fixture(name + ".expected") t.equal( actual, expected, "processed fixture '" + name + "' should be equal to expected output" @@ -61,7 +61,7 @@ test("throw errors", function(t) { test( "substitutes nothing when a variable function references an undefined var", function(t) { - var result = compareFixtures(t, "substitution-undefined") + const result = compareFixtures(t, "substitution-undefined") t.equal( result.messages[0].text, "variable '--test' is undefined and used without a fallback", @@ -72,7 +72,7 @@ test( ) test("substitutes defined variables in `:root` only", function(t) { - var result = compareFixtures(t, "substitution-defined") + const result = compareFixtures(t, "substitution-defined") t.ok( result.messages[0].text.match(/^Custom property ignored/), "should add a warning for non root custom properties" @@ -81,7 +81,7 @@ test("substitutes defined variables in `:root` only", function(t) { }) test("allow to hide warnings", function(t) { - var result = compareFixtures( + const result = compareFixtures( t, "substitution-defined", {warnings: false} @@ -125,7 +125,7 @@ test( ) test("allows users to programmatically change the variables", function(t) { - var variables = { + const variables = { "--test-one": "js-one", "--test-two": "js-two", "--test-three": "js-three", @@ -133,14 +133,15 @@ test("allows users to programmatically change the variables", function(t) { "--test-jsception": "var(--test-varception)", "--test-num": 1, } - var plugin = customProperties() - var name = "js-override" - var expected = fs.readFileSync(fixturePath(name + ".expected"), "utf8").trim() - var actual + const plugin = customProperties() + const name = "js-override" + const expected = fs.readFileSync( + fixturePath(name + ".expected"), "utf8" + ).trim() plugin.setVariables(variables) - actual = postcss(plugin) + const actual = postcss(plugin) .process(fixture(name), {from: fixturePath(name)}).css.trim() t.equal( @@ -193,7 +194,7 @@ test("preserves computed value when `preserve` is `\"computed\"`", function(t) { test("circular variable references", function(t) { compareFixtures(t, "self-reference") - var result = compareFixtures(t, "circular-reference") + const result = compareFixtures(t, "circular-reference") t.equal( result.messages[0].text, "Circular variable reference: --color", @@ -232,4 +233,4 @@ test("strict option", function(t) { test("ignores trailing space after variable", function(t) { compareFixtures(t, "substitution-trailing-space") t.end() -}) \ No newline at end of file +}) From d4c1e10acda12778b7a32fb0c857aba938c14ac3 Mon Sep 17 00:00:00 2001 From: Dmitry Semigradsky Date: Fri, 12 May 2017 11:46:31 +0300 Subject: [PATCH 426/795] 6.0.0 --- CHANGELOG.md | 4 ++++ LICENSE | 2 +- package.json | 2 +- 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 230df82876..0638680e7e 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,7 @@ +# 6.0.0 - 2017-05-12 + +- Added: compatibility with postcss v6.x + # 5.0.2 - 2017-02-01 - Minor dependency update diff --git a/LICENSE b/LICENSE index 5a95722180..84a7d54928 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,6 @@ The MIT License (MIT) -Copyright (c) 2014 Maxime Thirouin, Nicolas Gallagher & TJ Holowaychuk +Copyright (c) 2017 Maxime Thirouin, Nicolas Gallagher & TJ Holowaychuk 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 diff --git a/package.json b/package.json index bffa068ae6..34de0cd5cc 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "postcss-custom-properties", - "version": "5.0.2", + "version": "6.0.0", "description": "PostCSS plugin to polyfill W3C CSS Custom Properties for cascading variables", "keywords": [ "css", From 20c908d3d79434d4d2e1f9489b3591040fc805cb Mon Sep 17 00:00:00 2001 From: Dmitry Semigradsky Date: Fri, 12 May 2017 11:57:20 +0300 Subject: [PATCH 427/795] Update dependencies --- .travis.yml | 10 ++++------ package.json | 11 ++++++----- test/index.js | 2 +- 3 files changed, 11 insertions(+), 12 deletions(-) diff --git a/.travis.yml b/.travis.yml index dd60f935ee..6e538237ad 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,8 +1,6 @@ +sudo: false language: node_js - node_js: - - 4 - - 5 - -matrix: - fast_finish: true + - "stable" + - "6" + - "4" diff --git a/package.json b/package.json index a316688652..6fa6152990 100644 --- a/package.json +++ b/package.json @@ -19,13 +19,14 @@ "index.js" ], "dependencies": { - "postcss": "^5.0.0" + "postcss": "^6.0.1" }, "devDependencies": { - "eslint": "^1.10.3", - "eslint-config-i-am-meticulous": "^2.0.0", - "npmpub": "^3.0.1", - "tape": "^4.0.0" + "eslint": "^3.19.0", + "eslint-config-i-am-meticulous": "^6.0.1", + "eslint-plugin-import": "^1.7.0", + "npmpub": "^3.1.0", + "tape": "^4.6.3" }, "scripts": { "lint": "eslint --fix .", diff --git a/test/index.js b/test/index.js index 55801e0c0c..043a83d8ce 100755 --- a/test/index.js +++ b/test/index.js @@ -1,8 +1,8 @@ var fs = require("fs") var test = require("tape") - var postcss = require("postcss") + var plugin = require("..") function filename(name) { From c9192e5fbac7b34af9e3b9cf79a16e58f231d09c Mon Sep 17 00:00:00 2001 From: Dmitry Semigradsky Date: Fri, 12 May 2017 12:23:51 +0300 Subject: [PATCH 428/795] 6.0.0 --- CHANGELOG.md | 4 ++++ LICENSE | 2 +- package.json | 2 +- 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 06051ddb58..70d4c04ab8 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,7 @@ +# 6.0.0 - 2017-05-12 + +- Added: compatibility with postcss v6.x + # 5.0.1 - 2016-02-03 - Fixed: circular dependencies are properly detected diff --git a/LICENSE b/LICENSE index e8f6c97582..f559d05e10 100755 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,6 @@ The MIT License (MIT) -Copyright (c) 2014 Maxime Thirouin & Nicolas Gallagher +Copyright (c) 2017 Maxime Thirouin & Nicolas Gallagher 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 diff --git a/package.json b/package.json index 6fa6152990..9bf0f8279d 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "postcss-custom-media", - "version": "5.0.1", + "version": "6.0.0", "description": "PostCSS plugin to transform W3C CSS Custom Media Queries to more compatible CSS", "keywords": [ "css", From 4c3a10ccb2639725ed47ee02a9c9296958b4396b Mon Sep 17 00:00:00 2001 From: Dmitry Semigradsky Date: Mon, 15 May 2017 09:50:38 +0300 Subject: [PATCH 429/795] Fix incorrect export (#69) --- .babelrc | 3 +++ package.json | 1 + 2 files changed, 4 insertions(+) diff --git a/.babelrc b/.babelrc index 6e6df8faf2..f36920318c 100644 --- a/.babelrc +++ b/.babelrc @@ -5,5 +5,8 @@ "node": 4 } }] + ], + "plugins": [ + "add-module-exports" ] } diff --git a/package.json b/package.json index 34de0cd5cc..09211478a6 100644 --- a/package.json +++ b/package.json @@ -23,6 +23,7 @@ }, "devDependencies": { "babel-cli": "^6.24.1", + "babel-plugin-add-module-exports": "^0.2.1", "babel-preset-env": "^1.4.0", "babel-register": "^6.24.1", "eslint": "^3.19.0", From 8e74957bbcbc69acfff039b6a00a804e99b2c232 Mon Sep 17 00:00:00 2001 From: Dmitry Semigradsky Date: Mon, 15 May 2017 09:52:08 +0300 Subject: [PATCH 430/795] 6.0.1 --- CHANGELOG.md | 4 ++++ package.json | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0638680e7e..c987daaf27 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,7 @@ +# 6.0.1 - 2017-05-15 + +- Fixed: incorrect export ([#69](https://github.com/postcss/postcss-custom-properties/issues/69)) + # 6.0.0 - 2017-05-12 - Added: compatibility with postcss v6.x diff --git a/package.json b/package.json index 09211478a6..f3be783a98 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "postcss-custom-properties", - "version": "6.0.0", + "version": "6.0.1", "description": "PostCSS plugin to polyfill W3C CSS Custom Properties for cascading variables", "keywords": [ "css", From e9ecf0836404d67d2a6a8105c55406e422976f86 Mon Sep 17 00:00:00 2001 From: Dmitry Semigradsky Date: Mon, 15 May 2017 09:58:08 +0300 Subject: [PATCH 431/795] Fix incorrect export --- .babelrc | 3 +++ package.json | 1 + 2 files changed, 4 insertions(+) diff --git a/.babelrc b/.babelrc index 6e6df8faf2..f36920318c 100644 --- a/.babelrc +++ b/.babelrc @@ -5,5 +5,8 @@ "node": 4 } }] + ], + "plugins": [ + "add-module-exports" ] } diff --git a/package.json b/package.json index 3e53e0eac5..9b424050d4 100644 --- a/package.json +++ b/package.json @@ -22,6 +22,7 @@ }, "devDependencies": { "babel-cli": "^6.24.1", + "babel-plugin-add-module-exports": "^0.2.1", "babel-preset-env": "^1.4.0", "babel-preset-es2015": "^6.14.0", "babel-preset-stage-2": "^6.13.0", From d3370bca0ffb3517b2bec1457b4f6cba20ab6bb6 Mon Sep 17 00:00:00 2001 From: Dmitry Semigradsky Date: Mon, 15 May 2017 09:58:48 +0300 Subject: [PATCH 432/795] 3.0.1 --- CHANGELOG.md | 4 ++++ package.json | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index aa23fdc3f5..6f58527735 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,7 @@ +# 3.0.1 - 2017-05-15 + +- Fixed: incorrect export + # 3.0.0 - 2017-05-11 - Added: compatibility with postcss v6.x diff --git a/package.json b/package.json index 9b424050d4..e8639a9a1e 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "postcss-selector-matches", - "version": "3.0.0", + "version": "3.0.1", "description": "PostCSS plugin to transform :matches() W3C CSS pseudo class to more compatible CSS selectors", "keywords": [ "postcss", From 83f3c8e3e781a88ee2306841fee250c58c757e74 Mon Sep 17 00:00:00 2001 From: Dmitry Semigradsky Date: Mon, 15 May 2017 10:03:52 +0300 Subject: [PATCH 433/795] Fix incorrect export (#8) --- .babelrc | 15 +++++++++------ package.json | 1 + 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/.babelrc b/.babelrc index f0ab75d429..f36920318c 100644 --- a/.babelrc +++ b/.babelrc @@ -1,9 +1,12 @@ { "presets": [ - ["env", { - "targets": { - "node": 4 - } - }] - ] + ["env", { + "targets": { + "node": 4 + } + }] + ], + "plugins": [ + "add-module-exports" + ] } diff --git a/package.json b/package.json index 402f8e8f8f..b5d9b22e2b 100644 --- a/package.json +++ b/package.json @@ -25,6 +25,7 @@ }, "devDependencies": { "babel-cli": "^6.24.1", + "babel-plugin-add-module-exports": "^0.2.1", "babel-preset-env": "^1.4.0", "babel-register": "^6.24.1", "eslint": "^3.19.0", From a85a52f651833c8848cc233be8e1d07a24ddfb1f Mon Sep 17 00:00:00 2001 From: Dmitry Semigradsky Date: Mon, 15 May 2017 10:04:47 +0300 Subject: [PATCH 434/795] 3.0.1 --- CHANGELOG.md | 4 ++++ package.json | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8a43031f3e..a833d1b87d 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,7 @@ +# 3.0.1 - 2017-05-15 + +- Fixed: incorrect export ([#69](https://github.com/postcss/postcss-selector-not/issues/8)) + # 3.0.0 - 2017-05-11 - Added: compatibility with postcss v6.x diff --git a/package.json b/package.json index b5d9b22e2b..7197895d58 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "postcss-selector-not", - "version": "3.0.0", + "version": "3.0.1", "description": "PostCSS plugin to transform :not() W3C CSS level 4 pseudo class to :not() CSS level 3 selectors", "keywords": [ "postcss", From e8656036bb6e4f3f38c898234c1c1c11b2f77f94 Mon Sep 17 00:00:00 2001 From: Dmitry Semigradsky Date: Mon, 15 May 2017 10:08:55 +0300 Subject: [PATCH 435/795] Fix incorrect export --- .babelrc | 5 ++++- package.json | 1 + 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/.babelrc b/.babelrc index 9fdb6b51d8..dd69366430 100644 --- a/.babelrc +++ b/.babelrc @@ -6,5 +6,8 @@ } }] ], - "plugins": ["transform-object-rest-spread"] + "plugins": [ + "transform-object-rest-spread", + "add-module-exports" + ] } diff --git a/package.json b/package.json index 6432a56449..c82de1eca3 100644 --- a/package.json +++ b/package.json @@ -29,6 +29,7 @@ }, "devDependencies": { "babel-cli": "^6.24.1", + "babel-plugin-add-module-exports": "^0.2.1", "babel-plugin-transform-object-rest-spread": "^6.23.0", "babel-preset-env": "^1.4.0", "babel-register": "^6.24.1", From cd71c8f150f939c3efb9c15849720c6afcf11648 Mon Sep 17 00:00:00 2001 From: Dmitry Semigradsky Date: Mon, 15 May 2017 10:09:27 +0300 Subject: [PATCH 436/795] 4.0.1 --- CHANGELOG.md | 4 ++++ package.json | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1b46be9f2e..0debc9eed9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,7 @@ +# 4.0.1 - 2017-05-15 + +- Fixed: incorrect export + # 4.0.0 - 2017-05-12 - Added: compatibility with postcss v6.x diff --git a/package.json b/package.json index c82de1eca3..d34a197542 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "postcss-custom-selectors", - "version": "4.0.0", + "version": "4.0.1", "description": "PostCSS plugin to transform W3C CSS Extensions(Custom Selectors) to more compatible CSS", "keywords": [ "postcss", From 877342dc342f2a85ef23b16d44f53cc7e7b15dfc Mon Sep 17 00:00:00 2001 From: Dmitry Semigradsky Date: Mon, 15 May 2017 11:21:46 +0300 Subject: [PATCH 437/795] Update dependencies --- .eslintrc.yml | 36 ++++++++++ .jscsrc | 125 --------------------------------- .jshintrc | 9 --- .travis.yml | 4 ++ index.js | 8 ++- package.json | 15 ++-- test/fixtures/hwb.expected.css | 2 +- test/index.js | 16 ++++- 8 files changed, 65 insertions(+), 150 deletions(-) create mode 100644 .eslintrc.yml delete mode 100644 .jscsrc delete mode 100644 .jshintrc diff --git a/.eslintrc.yml b/.eslintrc.yml new file mode 100644 index 0000000000..40483cca86 --- /dev/null +++ b/.eslintrc.yml @@ -0,0 +1,36 @@ +root: true +extends: eslint:recommended + +parserOptions: + ecmaVersion: 5 + +env: + commonjs: true + +rules: + indent: [2, 2] # 2 spaces indentation + max-len: [2, 80, 4] + 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"] diff --git a/.jscsrc b/.jscsrc deleted file mode 100644 index 9afb9dd75d..0000000000 --- a/.jscsrc +++ /dev/null @@ -1,125 +0,0 @@ -{ - "excludeFiles": [ - "node_modules/**" - ], - "fileExtensions": [ - ".js" - ], - "requireCurlyBraces": [ - "if", - "else", - "for", - "while", - "do", - "try", - "catch" - ], - "requireSpaceAfterKeywords": [ - "if", - "else", - "for", - "while", - "do", - "switch", - "return", - "try", - "catch" - ], - "requireSpaceBeforeBlockStatements": true, - "requireParenthesesAroundIIFE": true, - "requireSpacesInConditionalExpression": { - "afterTest": true, - "beforeConsequent": true, - "afterConsequent": true, - "beforeAlternate": true - }, - "requireSpacesInFunctionExpression": { - "beforeOpeningCurlyBrace": true - }, - "disallowSpacesInFunctionExpression": { - "beforeOpeningRoundBrace": true - }, - "disallowMultipleVarDecl": true, - "requireBlocksOnNewline": 1, - "disallowPaddingNewlinesInBlocks": true, - "disallowEmptyBlocks": true, - "disallowSpacesInsideObjectBrackets": true, - "disallowSpacesInsideArrayBrackets": true, - "disallowSpacesInsideParentheses": true, - "disallowQuotedKeysInObjects": "allButReserved", - "disallowSpaceAfterObjectKeys": true, - "requireCommaBeforeLineBreak": true, - "requireOperatorBeforeLineBreak": [ - "?", - "+", - "-", - "/", - "*", - "=", - "==", - "===", - "!=", - "!==", - ">", - ">=", - "<", - "<=" - ], - "disallowSpaceAfterPrefixUnaryOperators": [ - "++", - "--", - "+", - "-", - "~", - "!" - ], - "disallowSpaceBeforePostfixUnaryOperators": [ - "++", - "--" - ], - "requireSpaceBeforeBinaryOperators": [ - "+", - "-", - "/", - "*", - "=", - "==", - "===", - "!=", - "!==" - ], - "requireSpaceAfterBinaryOperators": [ - "+", - "-", - "/", - "*", - "=", - "==", - "===", - "!=", - "!==" - ], - "disallowImplicitTypeConversion": [ - "numeric", - "boolean", - "binary", - "string" - ], - "requireCamelCaseOrUpperCaseIdentifiers": "ignoreProperties", - "disallowKeywords": [ - "with" - ], - "disallowMultipleLineStrings": true, - "validateQuoteMarks": "\"", - "validateIndentation": 2, - "disallowMixedSpacesAndTabs": true, - "disallowTrailingWhitespace": true, - "requireKeywordsOnNewLine": [ - "else" - ], - "requireLineFeedAtFileEnd": true, - "requireCapitalizedConstructors": true, - "safeContextKeyword": "that", - "requireDotNotation": true, - "requireSpaceAfterLineComment": true -} diff --git a/.jshintrc b/.jshintrc deleted file mode 100644 index 9f268f76ca..0000000000 --- a/.jshintrc +++ /dev/null @@ -1,9 +0,0 @@ -{ - "newcap": false, - "undef": true, - "unused": true, - "asi": true, - "esnext": true, - "node": true, - "browser": true -} diff --git a/.travis.yml b/.travis.yml index 587bd3e031..10e9429ed5 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1 +1,5 @@ +sudo: false language: node_js +node_js: + - "6" + - "4" diff --git a/index.js b/index.js index c053e35ea0..78c6f45c35 100755 --- a/index.js +++ b/index.js @@ -6,6 +6,10 @@ var helpers = require("postcss-message-helpers") var color = require("color") var reduceFunctionCall = require("reduce-function-call") +function reduceHwb(body) { + return color("hwb(" + body + ")").rgb().string() +} + /** * PostCSS plugin to transform hwb() to rgb() */ @@ -17,9 +21,7 @@ module.exports = postcss.plugin("postcss-color-hwb", function() { } decl.value = helpers.try(function transformHwb() { - return reduceFunctionCall(decl.value, "hwb", function reduceHwb(body, fn) { - return color(fn + "(" + body + ")").rgbString() - }) + return reduceFunctionCall(decl.value, "hwb", reduceHwb) }, decl.source) }) } diff --git a/package.json b/package.json index d13ff02388..4d9e5e391a 100644 --- a/package.json +++ b/package.json @@ -21,21 +21,18 @@ "index.js" ], "dependencies": { - "color": "^0.11.4", - "postcss": "^5.0.4", + "color": "^1.0.3", + "postcss": "^6.0.1", "postcss-message-helpers": "^2.0.0", - "reduce-function-call": "^1.0.1" + "reduce-function-call": "^1.0.2" }, "devDependencies": { - "jscs": "^2.1.0", - "jshint": "^2.8.0", + "eslint": "^3.19.0", "npmpub": "^3.1.0", - "tape": "^4.0.3" + "tape": "^4.6.3" }, "scripts": { - "lint": "npm run jscs && npm run jshint", - "jscs": "jscs index.js test/index.js", - "jshint": "jshint . --exclude-path .gitignore", + "lint": "eslint *.js index.js ./test/", "test": "npm run lint && tape test", "release": "npmpub" } diff --git a/test/fixtures/hwb.expected.css b/test/fixtures/hwb.expected.css index 01427e0cbe..7aa69dffd3 100644 --- a/test/fixtures/hwb.expected.css +++ b/test/fixtures/hwb.expected.css @@ -1,4 +1,4 @@ body { color: rgba(128, 255, 0, 0.5); - background: linear-gradient(rgb(128, 234, 255), rgba(128, 212, 230, 0.2)); + background: linear-gradient(rgb(128, 234, 255), rgba(128, 213, 230, 0.2)); } diff --git a/test/index.js b/test/index.js index dbe273acc3..e72c2375e3 100755 --- a/test/index.js +++ b/test/index.js @@ -5,14 +5,24 @@ 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 filename(name) { + return "test/" + name + ".css" +} + +function read(name) { + return fs.readFileSync(name, "utf8") +} + +function transform(css, options) { + return postcss(plugin(options)).process(css).css +} 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 actual = transform(read(postcssOpts.from), postcssOpts) var expected = read(filename("fixtures/" + name + ".expected")) fs.writeFile(filename("fixtures/" + name + ".actual"), actual) t.equal(actual, expected, msg) From 2260586d09c94db0b954ea83e56593438d9b68fb Mon Sep 17 00:00:00 2001 From: Dmitry Semigradsky Date: Mon, 15 May 2017 11:25:49 +0300 Subject: [PATCH 438/795] 3.0.0 --- CHANGELOG.md | 5 +++++ package.json | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b2fca9a982..2a33d6a2e8 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,8 @@ +# 3.0.0 - 2017-05-15 + +- Added: compatibility with postcss v6.x +- Uodated dependencies + # 2.0.1 - 2016-11-28 - Bump `color` dependency version diff --git a/package.json b/package.json index 4d9e5e391a..4c5c7f9189 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "postcss-color-hwb", - "version": "2.0.1", + "version": "3.0.0", "description": "PostCSS plugin to transform W3C CSS hwb() color to more compatible CSS (rgb() (or rgba()))", "keywords": [ "css", From ac6f3a617065ae9cd192092d59105fe5361c00e0 Mon Sep 17 00:00:00 2001 From: Dmitry Semigradsky Date: Mon, 15 May 2017 12:38:42 +0300 Subject: [PATCH 439/795] Update dependencies --- .eslintrc.yml | 36 +++++++++++++++ .jscsrc | 125 -------------------------------------------------- .jshintrc | 9 ---- .travis.yml | 4 ++ index.js | 12 +++-- package.json | 16 +++---- test/index.js | 15 ++++-- 7 files changed, 68 insertions(+), 149 deletions(-) create mode 100644 .eslintrc.yml delete mode 100644 .jscsrc delete mode 100644 .jshintrc diff --git a/.eslintrc.yml b/.eslintrc.yml new file mode 100644 index 0000000000..40483cca86 --- /dev/null +++ b/.eslintrc.yml @@ -0,0 +1,36 @@ +root: true +extends: eslint:recommended + +parserOptions: + ecmaVersion: 5 + +env: + commonjs: true + +rules: + indent: [2, 2] # 2 spaces indentation + max-len: [2, 80, 4] + 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"] diff --git a/.jscsrc b/.jscsrc deleted file mode 100644 index 9afb9dd75d..0000000000 --- a/.jscsrc +++ /dev/null @@ -1,125 +0,0 @@ -{ - "excludeFiles": [ - "node_modules/**" - ], - "fileExtensions": [ - ".js" - ], - "requireCurlyBraces": [ - "if", - "else", - "for", - "while", - "do", - "try", - "catch" - ], - "requireSpaceAfterKeywords": [ - "if", - "else", - "for", - "while", - "do", - "switch", - "return", - "try", - "catch" - ], - "requireSpaceBeforeBlockStatements": true, - "requireParenthesesAroundIIFE": true, - "requireSpacesInConditionalExpression": { - "afterTest": true, - "beforeConsequent": true, - "afterConsequent": true, - "beforeAlternate": true - }, - "requireSpacesInFunctionExpression": { - "beforeOpeningCurlyBrace": true - }, - "disallowSpacesInFunctionExpression": { - "beforeOpeningRoundBrace": true - }, - "disallowMultipleVarDecl": true, - "requireBlocksOnNewline": 1, - "disallowPaddingNewlinesInBlocks": true, - "disallowEmptyBlocks": true, - "disallowSpacesInsideObjectBrackets": true, - "disallowSpacesInsideArrayBrackets": true, - "disallowSpacesInsideParentheses": true, - "disallowQuotedKeysInObjects": "allButReserved", - "disallowSpaceAfterObjectKeys": true, - "requireCommaBeforeLineBreak": true, - "requireOperatorBeforeLineBreak": [ - "?", - "+", - "-", - "/", - "*", - "=", - "==", - "===", - "!=", - "!==", - ">", - ">=", - "<", - "<=" - ], - "disallowSpaceAfterPrefixUnaryOperators": [ - "++", - "--", - "+", - "-", - "~", - "!" - ], - "disallowSpaceBeforePostfixUnaryOperators": [ - "++", - "--" - ], - "requireSpaceBeforeBinaryOperators": [ - "+", - "-", - "/", - "*", - "=", - "==", - "===", - "!=", - "!==" - ], - "requireSpaceAfterBinaryOperators": [ - "+", - "-", - "/", - "*", - "=", - "==", - "===", - "!=", - "!==" - ], - "disallowImplicitTypeConversion": [ - "numeric", - "boolean", - "binary", - "string" - ], - "requireCamelCaseOrUpperCaseIdentifiers": "ignoreProperties", - "disallowKeywords": [ - "with" - ], - "disallowMultipleLineStrings": true, - "validateQuoteMarks": "\"", - "validateIndentation": 2, - "disallowMixedSpacesAndTabs": true, - "disallowTrailingWhitespace": true, - "requireKeywordsOnNewLine": [ - "else" - ], - "requireLineFeedAtFileEnd": true, - "requireCapitalizedConstructors": true, - "safeContextKeyword": "that", - "requireDotNotation": true, - "requireSpaceAfterLineComment": true -} diff --git a/.jshintrc b/.jshintrc deleted file mode 100644 index 9f268f76ca..0000000000 --- a/.jshintrc +++ /dev/null @@ -1,9 +0,0 @@ -{ - "newcap": false, - "undef": true, - "unused": true, - "asi": true, - "esnext": true, - "node": true, - "browser": true -} diff --git a/.travis.yml b/.travis.yml index 587bd3e031..10e9429ed5 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1 +1,5 @@ +sudo: false language: node_js +node_js: + - "6" + - "4" diff --git a/index.js b/index.js index cbb5acadde..dee51a4dac 100755 --- a/index.js +++ b/index.js @@ -42,7 +42,11 @@ function transformHexAlpha(string) { var hex = m[1] - return string.slice(0, m.index) + hexaToRgba(hex) + transformHexAlpha(string.slice(m.index + 1 + hex.length)) + return string.slice(0, m.index) + + hexaToRgba(hex) + + transformHexAlpha( + string.slice(m.index + 1 + hex.length) + ) } /** @@ -67,8 +71,10 @@ function hexaToRgba(hex) { // } var rgb = [] for (var i = 0, l = hex.length; i < l; i += 2) { - rgb.push(Math.round(parseInt(hex.substr(i, 2), 16) / (i === 6 ? 255 : 1) * DECIMAL_PRECISION) / DECIMAL_PRECISION) + var isAlpha = i === 6 + var value = parseInt(hex.substr(i, 2), 16) / (isAlpha ? 255 : 1) + rgb.push(Math.round(value * DECIMAL_PRECISION) / DECIMAL_PRECISION) } - return color({r: rgb[0], g: rgb[1], b: rgb[2], a: rgb[3]}).rgbaString() + return color.rgb(rgb).string() } diff --git a/package.json b/package.json index 8b25823af0..bc5b0a87a6 100644 --- a/package.json +++ b/package.json @@ -21,19 +21,17 @@ "index.js" ], "dependencies": { - "color": "^0.10.1", - "postcss": "^5.0.4", + "color": "^1.0.3", + "postcss": "^6.0.1", "postcss-message-helpers": "^2.0.0" }, "devDependencies": { - "jscs": "^2.1.0", - "jshint": "^2.8.0", - "tape": "^4.0.3" + "eslint": "^3.19.0", + "tape": "^4.6.3" }, "scripts": { - "lint": "npm run jscs && npm run jshint", - "jscs": "jscs index.js test/index.js", - "jshint": "jshint . --exclude-path .gitignore", - "test": "npm run lint && tape test" + "lint": "eslint *.js index.js ./test/", + "test": "npm run lint && tape test", + "release": "npmpub" } } diff --git a/test/index.js b/test/index.js index e60ddbd44f..b16a67d7a8 100755 --- a/test/index.js +++ b/test/index.js @@ -5,14 +5,23 @@ 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 filename(name) { + return "test/" + name + ".css" +} + +function read(name) { + return fs.readFileSync(name, "utf8") +} + +function transform(css, options) { + return postcss(plugin(options)).process(css).css +} 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 actual = transform(read(postcssOpts.from), postcssOpts) var expected = read(filename("fixtures/" + name + ".expected")) fs.writeFile(filename("fixtures/" + name + ".actual"), actual) t.equal(actual, expected, msg) From 7192cc004172abca87810d15307bec194e74cea5 Mon Sep 17 00:00:00 2001 From: Dmitry Semigradsky Date: Mon, 15 May 2017 12:43:06 +0300 Subject: [PATCH 440/795] 3.0.0 --- CHANGELOG.md | 5 +++++ package.json | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 11aa4be506..7fa75320d7 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,8 @@ +# 3.0.0 - 2017-05-15 + +- Added: compatibility with postcss v6.x +- Uodated dependencies + # 2.0.0 - 2015-09-08 - Added: compatibility with postcss v5.x diff --git a/package.json b/package.json index bc5b0a87a6..48336b2bd8 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "postcss-color-hex-alpha", - "version": "2.0.0", + "version": "3.0.0", "description": "PostCSS plugin to transform W3C RGBA hexadecimal notations (#RRGGBBAA or #RGBA) to more compatible CSS (rgba())", "keywords": [ "css", From 60db5cc54fd9023f17debabc02bc28e1063b8f87 Mon Sep 17 00:00:00 2001 From: Dmitry Semigradsky Date: Mon, 15 May 2017 13:26:52 +0300 Subject: [PATCH 441/795] Update dependencies --- .eslintrc | 10 ---------- .eslintrc.yml | 35 +++++++++++++++++++++++++++++++++++ .jscs.json | 4 ---- .travis.yml | 4 ++-- appveyor.yml | 4 ++-- index.js | 8 +++++--- package.json | 19 +++++++++---------- 7 files changed, 53 insertions(+), 31 deletions(-) delete mode 100755 .eslintrc create mode 100644 .eslintrc.yml delete mode 100755 .jscs.json diff --git a/.eslintrc b/.eslintrc deleted file mode 100755 index 13e5d61f1e..0000000000 --- a/.eslintrc +++ /dev/null @@ -1,10 +0,0 @@ -env: - browser: false - node: true -rules: - no-extra-parens: 2 - eqeqeq: 2 - block-scoped-var: 2 - quotes: - - 2 - - single diff --git a/.eslintrc.yml b/.eslintrc.yml new file mode 100644 index 0000000000..003b54272b --- /dev/null +++ b/.eslintrc.yml @@ -0,0 +1,35 @@ +root: true +extends: eslint:recommended + +parserOptions: + ecmaVersion: 5 + +env: + commonjs: true + +rules: + indent: [2, 2] # 2 spaces indentation + max-len: [2, 80, 4, { "ignoreStrings": true }] + quotes: [2, "single"] + semi: [2, "always"] + no-multiple-empty-lines: [2, {"max": 1}] + + brace-style: [2, "1tbs"] + 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"] diff --git a/.jscs.json b/.jscs.json deleted file mode 100755 index 920932259b..0000000000 --- a/.jscs.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "preset": "google", - "maximumLineLength": 98 -} diff --git a/.travis.yml b/.travis.yml index 1feff23f3b..0204bbebe8 100755 --- a/.travis.yml +++ b/.travis.yml @@ -3,8 +3,8 @@ git: depth: 2 language: node_js node_js: - - '0.10' - - '0.12' + - '4' + - '6' notifications: email: false after_script: diff --git a/appveyor.yml b/appveyor.yml index a0bbbda61f..4c66cc7c36 100755 --- a/appveyor.yml +++ b/appveyor.yml @@ -5,8 +5,8 @@ version: '{build}' environment: matrix: - - nodejs_version: '0.10' - - nodejs_version: '0.12' + - nodejs_version: '4' + - nodejs_version: '6' install: - ps: Install-Product node $env:nodejs_version diff --git a/index.js b/index.js index bfbb08bcb9..386760d9d6 100755 --- a/index.js +++ b/index.js @@ -41,10 +41,12 @@ function parseGray(decl) { rgb.push(alpha); } try { - return color(fn + '(' + rgb + ')').rgbString(); + return color(fn + '(' + rgb + ')').rgb().string(); } catch (err) { - var message = err.message.replace(/rgba?\(.*\)/, 'gray(' + args + ')'); - throw decl.error(message, errorContext); + throw decl.error( + 'Unable to parse color from string "gray(' + args + ')"', + errorContext + ); } }); } diff --git a/package.json b/package.json index 69e7f8a407..c60adde3d2 100644 --- a/package.json +++ b/package.json @@ -8,7 +8,7 @@ "url": "https://github.com/shinnn" }, "scripts": { - "pretest": "npm run eslint && npm run jscs", + "pretest": "npm run eslint", "eslint": "eslint index.js test.js", "jscs": "jscs index.js test.js", "test": "node test.js | tap-spec", @@ -37,18 +37,17 @@ "function" ], "dependencies": { - "color": "^0.11.3", - "postcss": "^5.0.4", + "color": "^1.0.3", + "postcss": "^6.0.1", "postcss-message-helpers": "^2.0.0", - "reduce-function-call": "^1.0.1" + "reduce-function-call": "^1.0.2" }, "devDependencies": { - "eslint": "^0.10.2", - "istanbul": "^0.3.5", - "istanbul-coveralls": "^1.0.1", - "jscs": "^1.8.1", + "eslint": "^3.19.0", + "istanbul": "^0.4.5", + "istanbul-coveralls": "^1.0.3", "npmpub": "^3.1.0", - "tap-spec": "^2.1.0", - "tape": "^3.0.3" + "tap-spec": "^4.1.1", + "tape": "^4.6.3" } } From 5d7e37ae89ab312b273bd1312569d6fdb2dbbd70 Mon Sep 17 00:00:00 2001 From: Dmitry Semigradsky Date: Mon, 15 May 2017 13:31:23 +0300 Subject: [PATCH 442/795] 4.0.0 --- CHANGELOG.md | 5 +++++ LICENSE | 2 +- README.md | 2 +- package.json | 2 +- 4 files changed, 8 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c807312c78..34de8f031b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,8 @@ +# 4.0.0 - 2017-05-15 + + - Added: compatibility with postcss v6.x + - Updated dependencies + # 3.0.1 - 2016-11-28 - Bump `color` dependency version diff --git a/LICENSE b/LICENSE index 81395e4213..0b0cb16d89 100755 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,6 @@ The MIT License (MIT) -Copyright (c) 2014 Shinnosuke Watanabe +Copyright (c) 2017 Shinnosuke Watanabe 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 diff --git a/README.md b/README.md index d6a7152711..65adcf0d13 100755 --- a/README.md +++ b/README.md @@ -75,6 +75,6 @@ postcss() ## License -Copyright (c) 2014 [Shinnosuke Watanabe](https://github.com/shinnn) +Copyright (c) 2017 [Shinnosuke Watanabe](https://github.com/shinnn) Licensed under [the MIT License](./LICENSE). diff --git a/package.json b/package.json index c60adde3d2..ae2e205397 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "postcss-color-gray", - "version": "3.0.1", + "version": "4.0.0", "description": "PostCSS plugin to transform gray() function to today's CSS", "repository": "https://github.com/postcss/postcss-color-gray.git", "author": { From 52c41acc3d87238a0de7f9e2ad380ac819db754c Mon Sep 17 00:00:00 2001 From: Jonathan Neal Date: Wed, 17 May 2017 22:05:54 -0400 Subject: [PATCH 443/795] 2.0.0 - Support PostCSS 6 - Support Node 4 --- .travis.yml | 4 +++- CHANGELOG.md | 5 +++++ index.js | 4 ++-- lib/json-to-ast.js | 4 ++-- lib/normalize-css-to-json.js | 2 ++ package.json | 12 ++++++------ 6 files changed, 20 insertions(+), 11 deletions(-) diff --git a/.travis.yml b/.travis.yml index 833d09d149..4feb3dc027 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,3 +1,5 @@ +# https://docs.travis-ci.com/user/travis-lint + language: node_js node_js: - - stable + - 4 diff --git a/CHANGELOG.md b/CHANGELOG.md index 57fe94a375..67798b9ed8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,10 @@ # Changes to PostCSS Normalize +### 2.0.0 (May 17, 2017) + +- Support PostCSS 6 +- Support Node 4 + ### 1.0.0 (May 2, 2017) - Initial version diff --git a/index.js b/index.js index 3e36ee2404..3cc4c88644 100644 --- a/index.js +++ b/index.js @@ -5,12 +5,12 @@ const normalizeJSON = require('./lib/normalize.json'); const postcss = require('postcss'); // plugin -module.exports = postcss.plugin('postcss-normalize', ({ browsers } = {}) => { +module.exports = postcss.plugin('postcss-normalize', (opts) => { const normalizeAST = jsonToAst(normalizeJSON); return (root) => { // client browser list - const clientBrowserList = browserslist(browsers, { + const clientBrowserList = browserslist(opts && opts.browsers, { path: root.source && root.source.input && root.source.input.file }); diff --git a/lib/json-to-ast.js b/lib/json-to-ast.js index 73deb2371c..f16df72262 100644 --- a/lib/json-to-ast.js +++ b/lib/json-to-ast.js @@ -9,6 +9,6 @@ module.exports = (json) => { json.nodes = json.nodes.map(module.exports); } - // return the current object into a postcss object - return json.type in postcss ? postcss[json.type](json) : null; + // return a clone of the current object into a postcss object + return json.type in postcss ? Object.assign({}, postcss[json.type](json)) : null; }; diff --git a/lib/normalize-css-to-json.js b/lib/normalize-css-to-json.js index 65478e07ed..a09534cade 100644 --- a/lib/normalize-css-to-json.js +++ b/lib/normalize-css-to-json.js @@ -1,3 +1,5 @@ +'use strict'; + // tooling const fs = require('fse'); const path = require('path'); diff --git a/package.json b/package.json index 322e5fb087..c9d984da1a 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "postcss-normalize", - "version": "1.0.0", + "version": "2.0.0", "description": "Use the parts of normalize.css you need from your browserlist", "author": "Jonathan Neal ", "license": "CC0-1.0", @@ -22,17 +22,17 @@ "test:tape": "postcss-tape" }, "engines": { - "node": ">=6.5.0" + "node": ">=4.0.0" }, "dependencies": { - "browserslist": "^2.1.1", - "postcss": "^5.2.17" + "browserslist": "^2.1.2", + "postcss": "^6.0.1" }, "devDependencies": { "eslint": "^3.19.0", "eslint-config-dev": "2.0.0", - "fse": "^2.0.0", - "postcss-tape": "1.3.1", + "fse": "^3.0.0", + "postcss-tape": "2.0.1", "pre-commit": "^1.2.2" }, "eslintConfig": { From ac7675141eeb243e120ec0b968ee656724cbd3f2 Mon Sep 17 00:00:00 2001 From: Jonathan Neal Date: Wed, 17 May 2017 22:18:07 -0400 Subject: [PATCH 444/795] Update README.md Include examples --- README.md | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/README.md b/README.md index 8b8c13ee76..4c90926d2b 100644 --- a/README.md +++ b/README.md @@ -9,6 +9,43 @@ [PostCSS Normalize] lets you automatically include the parts of [normalize.css] you need, based upon your project’s [browserlist]. +```css +/* { "browserlist": ["last 3 versions"] } */ + +/** + * Add the correct display in IE 9-. + */ + +article, +aside, +footer, +header, +nav, +section { + display: block; +} + +/** + * Remove the border on images inside links in IE 10-. + */ + +img { + border-style: none; +} +``` + +```css +/* { "browserlist": ["last 2 versions"] } */ + +/** + * Remove the border on images inside links in IE 10-. + */ + +img { + border-style: none; +} +``` + ## Usage Add [PostCSS Normalize] to your build tool: From bb1e77219245ba920797fa844e1128e8563a2be0 Mon Sep 17 00:00:00 2001 From: Jonathan Neal Date: Sat, 20 May 2017 21:13:11 -0400 Subject: [PATCH 445/795] Preserve more raws formatting --- lib/clean-node.js | 6 +++++- lib/transform-bubbling-atrule.js | 6 ++++++ 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/lib/clean-node.js b/lib/clean-node.js index 1ceb3428ed..9d430e9b59 100644 --- a/lib/clean-node.js +++ b/lib/clean-node.js @@ -1,6 +1,10 @@ // clean the raws of the node module.exports = (node) => { - node.raws = {}; + node.raws = Object.assign( + node.raws.between ? { between: node.raws.between } : {}, + node.raws.semicolon ? { semicolon: true } : {}, + node.raws.important ? { important: node.raws.important } : {} + ); return node; }; diff --git a/lib/transform-bubbling-atrule.js b/lib/transform-bubbling-atrule.js index 3dccec7e9d..bf8e358892 100644 --- a/lib/transform-bubbling-atrule.js +++ b/lib/transform-bubbling-atrule.js @@ -22,6 +22,12 @@ module.exports = (node) => { // append the inner nodes to the empty parent clone parentCloneForNodesWithinAtrule.append(innerNodes); + // swap semicolon raws + const semicolon = node.raws.semicolon; + + node.raws.semicolon = node.parent.raws.semicolon; + node.parent.raws.semicolon = semicolon; + // move the node after the parent const parent = node.parent.after(node); From 47280dd2f3b24d73a78a24db218f0baa5bcdbf75 Mon Sep 17 00:00:00 2001 From: Jonathan Neal Date: Sat, 20 May 2017 21:13:23 -0400 Subject: [PATCH 446/795] Transform only compliant nesting --- lib/transform-nesting-atrule.js | 2 +- lib/transform-nesting-rule.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/transform-nesting-atrule.js b/lib/transform-nesting-atrule.js index 413801d04c..a7f954e5aa 100644 --- a/lib/transform-nesting-atrule.js +++ b/lib/transform-nesting-atrule.js @@ -39,5 +39,5 @@ module.exports = (node) => { // whether the node is a nesting atrule (e.g. @nest .something &) module.exports.test = (node) => node.type === 'atrule' && node.name === 'nest' && node.parent && node.parent.type === 'rule' && comma(node.params).every( - (childNode) => childNode.indexOf('&') !== -1 + (selector) => selector.split('&').length === 2 && /&([^A-z]|$)/.test(selector) ); diff --git a/lib/transform-nesting-rule.js b/lib/transform-nesting-rule.js index 2161eb322c..40ee9c8d7e 100644 --- a/lib/transform-nesting-rule.js +++ b/lib/transform-nesting-rule.js @@ -25,5 +25,5 @@ module.exports = (node) => { // whether the node is a nesting rule (e.g. &.something) module.exports.test = (node) => node.type === 'rule' && node.parent && node.parent.type === 'rule' && node.selectors.every( - (childNode) => childNode.trim()[0] === '&' + (selector) => selector.trim().lastIndexOf('&') === 0 && /^&([^A-z]|$)/.test(selector) ); From 08c712bd362fe37158fd46d7b828a725879aeaf2 Mon Sep 17 00:00:00 2001 From: Jonathan Neal Date: Sat, 20 May 2017 21:13:31 -0400 Subject: [PATCH 447/795] Update tests --- .tape.js | 6 +++--- test/direct.css | 8 -------- test/direct.expect.css | 12 ------------ test/empty.expect.css | 16 ++++++++-------- test/ignore.css | 16 ++++++++++++++++ test/ignore.expect.css | 16 ++++++++++++++++ test/media.expect.css | 24 ++++++++++++------------ 7 files changed, 55 insertions(+), 43 deletions(-) diff --git a/.tape.js b/.tape.js index 88def0a631..442ed52ff1 100644 --- a/.tape.js +++ b/.tape.js @@ -9,11 +9,11 @@ module.exports = { 'empty': { message: 'removes empty rules' }, - 'ignore': { - message: 'ignores invalid entries' - }, 'media': { message: 'supports nested media' + }, + 'ignore': { + message: 'ignores invalid entries' } } }; diff --git a/test/direct.css b/test/direct.css index af39d6e363..5875d05ba8 100644 --- a/test/direct.css +++ b/test/direct.css @@ -8,10 +8,6 @@ a, b { order: 4; } order: 5; - & & { - order: 6; - } - order: 7; } a, b { order: 1; @@ -23,8 +19,4 @@ a, b { order: 4; } order: 5; - @nest & & { - order: 6; - } - order: 7; } diff --git a/test/direct.expect.css b/test/direct.expect.css index d64cb3900e..07c4bdfa09 100644 --- a/test/direct.expect.css +++ b/test/direct.expect.css @@ -13,12 +13,6 @@ a c, a d, b c, b d { a, b { order: 5; } -a a, b b { - order: 6; -} -a, b { - order: 7; -} a, b { order: 1; } @@ -34,9 +28,3 @@ a c, a d, b c, b d { a, b { order: 5; } -a a, b b { - order: 6; -} -a, b { - order: 7; -} diff --git a/test/empty.expect.css b/test/empty.expect.css index 1bc7d62443..a2423bc723 100644 --- a/test/empty.expect.css +++ b/test/empty.expect.css @@ -1,30 +1,30 @@ a b c { - order: 1 + order: 1; } d { order: 2 } d e { - order: 3 + order: 3; } f g { - order: 4 + order: 4; } f { - order: 5 + order: 5; } a b c { - order: 1 + order: 1; } d { order: 2 } d e { - order: 3 + order: 3; } f g { - order: 4 + order: 4; } f { - order: 5 + order: 5; } diff --git a/test/ignore.css b/test/ignore.css index e8de19a875..3829c74064 100644 --- a/test/ignore.css +++ b/test/ignore.css @@ -7,6 +7,14 @@ a, b { & e { order: 3; } +f { + & g & { + order: 4; + } + &h { + order: 5; + } +} a, b { order: 1; @nest c, d { @@ -16,3 +24,11 @@ a, b { @nest & e { order: 3; } +f { + @nest & g & { + order: 4; + } + @nest &h { + order: 5; + } +} diff --git a/test/ignore.expect.css b/test/ignore.expect.css index e8de19a875..3829c74064 100644 --- a/test/ignore.expect.css +++ b/test/ignore.expect.css @@ -7,6 +7,14 @@ a, b { & e { order: 3; } +f { + & g & { + order: 4; + } + &h { + order: 5; + } +} a, b { order: 1; @nest c, d { @@ -16,3 +24,11 @@ a, b { @nest & e { order: 3; } +f { + @nest & g & { + order: 4; + } + @nest &h { + order: 5; + } +} diff --git a/test/media.expect.css b/test/media.expect.css index 19c7006bbd..b3e80c929d 100644 --- a/test/media.expect.css +++ b/test/media.expect.css @@ -1,52 +1,52 @@ a { - order: 1 + order: 1; } @media (min-width: 100px) { a { - order: 2 + order: 2; } } @media (min-width: 100px) and (max-width: 200px) { a { - order: 3 + order: 3; } } @media (min-width: 100px) and (max-width: 200px) { a b { - order: 4 + order: 4; } } @media screen and (max-width: 300px), screen and (min-aspect-ratio: 16/9), print and speech and (max-width: 300px), print and speech and (min-aspect-ratio: 16/9) { a { - order: 5 + order: 5; } a c { - order: 6 + order: 6; } } a { - order: 1 + order: 1; } @media (min-width: 100px) { a { - order: 2 + order: 2; } } @media (min-width: 100px) and (max-width: 200px) { a { - order: 3 + order: 3; } } @media (min-width: 100px) and (max-width: 200px) { a b { - order: 4 + order: 4; } } @media screen and (max-width: 300px), screen and (min-aspect-ratio: 16/9), print and speech and (max-width: 300px), print and speech and (min-aspect-ratio: 16/9) { a { - order: 5 + order: 5; } a c { - order: 6 + order: 6; } } From 82c52e2f78d5f6aa4f9accacfd066497615d5c7f Mon Sep 17 00:00:00 2001 From: Jonathan Neal Date: Sat, 20 May 2017 21:14:50 -0400 Subject: [PATCH 448/795] Update README.md spacing --- README.md | 36 ++++++++++++++++++------------------ 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/README.md b/README.md index bf60e14151..a4f34f9150 100644 --- a/README.md +++ b/README.md @@ -57,7 +57,7 @@ Use [PostCSS Nesting] as a plugin: ```js postcss([ - require('postcss-nesting')({ /* options */ }) + require('postcss-nesting')({ /* options */ }) ]).process(YOUR_CSS, /* options */); ``` @@ -75,13 +75,13 @@ Use [PostCSS Nesting] in your Gulpfile: var postcss = require('gulp-postcss'); gulp.task('css', function () { - return gulp.src('./src/*.css').pipe( - postcss([ - require('postcss-nesting')({ /* options */ }) - ]) - ).pipe( - gulp.dest('.') - ); + return gulp.src('./src/*.css').pipe( + postcss([ + require('postcss-nesting')({ /* options */ }) + ]) + ).pipe( + gulp.dest('.') + ); }); ``` @@ -99,16 +99,16 @@ Use [PostCSS Nesting] in your Gruntfile: grunt.loadNpmTasks('grunt-postcss'); grunt.initConfig({ - postcss: { - options: { - use: [ - require('postcss-nesting')({ /* options */ }) - ] - }, - dist: { - src: '*.css' - } - } + postcss: { + options: { + use: [ + require('postcss-nesting')({ /* options */ }) + ] + }, + dist: { + src: '*.css' + } + } }); ``` From c1cd77faa0ab436ff1a4593ace19c635f0dc989b Mon Sep 17 00:00:00 2001 From: Jonathan Neal Date: Sat, 20 May 2017 21:15:00 -0400 Subject: [PATCH 449/795] 4.0.0 --- CHANGELOG.md | 5 +++++ package.json | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d8a636dcf9..81a2ed8258 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,10 @@ # Changes to PostCSS Nesting +### 4.0.0 (May 20, 2017) + +- Transform only compliant nesting +- Preserve more raws formatting + ### 3.0.0 (May 8, 2017) - Added: Node 4.x support diff --git a/package.json b/package.json index 247ff41a97..3aca9e0ae6 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "postcss-nesting", - "version": "3.0.0", + "version": "4.0.0", "description": "Nest style and media rules inside each another, following the CSS Nesting Module Level 3 specification", "author": "Jonathan Neal ", "license": "CC0-1.0", From 4b783f94345cde3e21322e27e30696d28f0796f3 Mon Sep 17 00:00:00 2001 From: Jonathan Neal Date: Sat, 20 May 2017 21:16:32 -0400 Subject: [PATCH 450/795] Update .travis.yml --- .travis.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.travis.yml b/.travis.yml index 85242354aa..d75992d613 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,3 +1,7 @@ +# https://docs.travis-ci.com/user/travis-lint + language: node_js node_js: - 4 +install: + - npm install --ignore-scripts From df2a134d7a4835ad245cc04bd4fa03d18d493990 Mon Sep 17 00:00:00 2001 From: Jonathan Neal Date: Sun, 21 May 2017 21:14:09 -0400 Subject: [PATCH 451/795] Update tree creation to avoid AST issues with other PostCSS plugins --- index.js | 5 ++ lib/json-to-ast.js | 24 +++++-- test/basic.expect.css | 124 +++++++++++++++++++++++++---------- test/basic.last-1.expect.css | 112 ++++++++++++++++++++++--------- test/basic.last-2.expect.css | 124 +++++++++++++++++++++++++---------- 5 files changed, 284 insertions(+), 105 deletions(-) diff --git a/index.js b/index.js index 3cc4c88644..70ed7a8852 100644 --- a/index.js +++ b/index.js @@ -34,8 +34,13 @@ module.exports = postcss.plugin('postcss-normalize', (opts) => { } ); + // restore source mapping + rule.source.input = normalizeJSON.source.input; + return rule.nodes.length; } + ).map( + (rule) => rule.clone() ); // prepend required normalize rules diff --git a/lib/json-to-ast.js b/lib/json-to-ast.js index f16df72262..0d96a5d6f7 100644 --- a/lib/json-to-ast.js +++ b/lib/json-to-ast.js @@ -3,12 +3,24 @@ const postcss = require('postcss'); // convert a json object into a postcss object module.exports = (json) => { - // if the object has a nodes array - if (Array.isArray(json.nodes)) { - // convert the objects in that array into postcss objects - json.nodes = json.nodes.map(module.exports); + // convert the current object into a postcss object + const node = postcss[json.type]( + // use the cloned json + Object.assign( + {}, + json, + json.nodes ? { nodes: [] } : {} + ) + ); + + // if the json object has nodes + if (json.nodes) { + // append the nodes as postcss objects + node.append( + json.nodes.map(module.exports) + ); } - // return a clone of the current object into a postcss object - return json.type in postcss ? Object.assign({}, postcss[json.type](json)) : null; + // return the postcss object + return node; }; diff --git a/test/basic.expect.css b/test/basic.expect.css index 4733f8ab42..737218fd34 100644 --- a/test/basic.expect.css +++ b/test/basic.expect.css @@ -1,92 +1,148 @@ -html {line-height: 1.15;-ms-text-size-adjust: 100%;-webkit-text-size-adjust: 100%; +html { + line-height: 1.15; + -ms-text-size-adjust: 100%; + -webkit-text-size-adjust: 100%; } -h1 {font-size: 2em;margin: 0.67em 0; +h1 { + font-size: 2em; + margin: 0.67em 0; } -main {display: block; +main { + display: block; } -hr {box-sizing: content-box;height: 0;overflow: visible; +hr { + box-sizing: content-box; + height: 0; + overflow: visible; } -pre {font-family: monospace, monospace;font-size: 1em; +pre { + font-family: monospace, monospace; + font-size: 1em; } -a {background-color: transparent;-webkit-text-decoration-skip: objects; +a { + background-color: transparent; + -webkit-text-decoration-skip: objects; } -abbr[title] {border-bottom: none;text-decoration: underline;text-decoration: underline dotted; +abbr[title] { + border-bottom: none; + text-decoration: underline; + text-decoration: underline dotted; } b, -strong {font-weight: bolder; +strong { + font-weight: bolder; } code, kbd, -samp {font-family: monospace, monospace;font-size: 1em; +samp { + font-family: monospace, monospace; + font-size: 1em; } -small {font-size: 80%; +small { + font-size: 80%; } sub, -sup {font-size: 75%;line-height: 0;position: relative;vertical-align: baseline; +sup { + font-size: 75%; + line-height: 0; + position: relative; + vertical-align: baseline; } -sub {bottom: -0.25em; +sub { + bottom: -0.25em; } -sup {top: -0.5em; +sup { + top: -0.5em; } -img {border-style: none; +img { + border-style: none; } -svg:not(:root) {overflow: hidden; +svg:not(:root) { + overflow: hidden; } button, input, optgroup, select, -textarea {margin: 0; +textarea { + margin: 0; } button, -input {overflow: visible; +input { + overflow: visible; } button, -select {text-transform: none; +select { + text-transform: none; } button, [type="button"], [type="reset"], -[type="submit"] {-webkit-appearance: button; +[type="submit"] { + -webkit-appearance: button; } button::-moz-focus-inner, [type="button"]::-moz-focus-inner, [type="reset"]::-moz-focus-inner, -[type="submit"]::-moz-focus-inner {border-style: none;padding: 0; +[type="submit"]::-moz-focus-inner { + border-style: none; + padding: 0; } button:-moz-focusring, [type="button"]:-moz-focusring, [type="reset"]:-moz-focusring, -[type="submit"]:-moz-focusring {outline: 1px dotted ButtonText; +[type="submit"]:-moz-focusring { + outline: 1px dotted ButtonText; } -fieldset {padding: 0.35em 0.75em 0.625em; +fieldset { + padding: 0.35em 0.75em 0.625em; } -legend {box-sizing: border-box;color: inherit;display: table;max-width: 100%;padding: 0;white-space: normal; +legend { + box-sizing: border-box; + color: inherit; + display: table; + max-width: 100%; + padding: 0; + white-space: normal; } -progress {vertical-align: baseline; +progress { + vertical-align: baseline; } -textarea {overflow: auto; +textarea { + overflow: auto; } [type="checkbox"], -[type="radio"] {box-sizing: border-box;padding: 0; +[type="radio"] { + box-sizing: border-box; + padding: 0; } [type="number"]::-webkit-inner-spin-button, -[type="number"]::-webkit-outer-spin-button {height: auto; +[type="number"]::-webkit-outer-spin-button { + height: auto; } -[type="search"] {-webkit-appearance: textfield;outline-offset: -2px; +[type="search"] { + -webkit-appearance: textfield; + outline-offset: -2px; } [type="search"]::-webkit-search-cancel-button, -[type="search"]::-webkit-search-decoration {-webkit-appearance: none; +[type="search"]::-webkit-search-decoration { + -webkit-appearance: none; } -::-webkit-file-upload-button {-webkit-appearance: button;font: inherit; +::-webkit-file-upload-button { + -webkit-appearance: button; + font: inherit; } -details {display: block; +details { + display: block; } -summary {display: list-item; +summary { + display: list-item; } -template {display: none; +template { + display: none; } -[hidden] {display: none; +[hidden] { + display: none; } body { font-family: sans-serif; diff --git a/test/basic.last-1.expect.css b/test/basic.last-1.expect.css index 0d056f3d64..8347a18bc3 100644 --- a/test/basic.last-1.expect.css +++ b/test/basic.last-1.expect.css @@ -1,85 +1,135 @@ -html {line-height: 1.15;-ms-text-size-adjust: 100%;-webkit-text-size-adjust: 100%; +html { + line-height: 1.15; + -ms-text-size-adjust: 100%; + -webkit-text-size-adjust: 100%; } -h1 {font-size: 2em;margin: 0.67em 0; +h1 { + font-size: 2em; + margin: 0.67em 0; } -main {display: block; +main { + display: block; } -hr {box-sizing: content-box;height: 0;overflow: visible; +hr { + box-sizing: content-box; + height: 0; + overflow: visible; } -pre {font-family: monospace, monospace;font-size: 1em; +pre { + font-family: monospace, monospace; + font-size: 1em; } -a {-webkit-text-decoration-skip: objects; +a { + -webkit-text-decoration-skip: objects; } -abbr[title] {text-decoration: underline;text-decoration: underline dotted; +abbr[title] { + text-decoration: underline; + text-decoration: underline dotted; } b, -strong {font-weight: bolder; +strong { + font-weight: bolder; } code, kbd, -samp {font-family: monospace, monospace;font-size: 1em; +samp { + font-family: monospace, monospace; + font-size: 1em; } -small {font-size: 80%; +small { + font-size: 80%; } sub, -sup {font-size: 75%;line-height: 0;position: relative;vertical-align: baseline; +sup { + font-size: 75%; + line-height: 0; + position: relative; + vertical-align: baseline; } -sub {bottom: -0.25em; +sub { + bottom: -0.25em; } -sup {top: -0.5em; +sup { + top: -0.5em; } -svg:not(:root) {overflow: hidden; +svg:not(:root) { + overflow: hidden; } button, input, optgroup, select, -textarea {margin: 0; +textarea { + margin: 0; } button, -input {overflow: visible; +input { + overflow: visible; } button, -select {text-transform: none; +select { + text-transform: none; } button, [type="button"], [type="reset"], -[type="submit"] {-webkit-appearance: button; +[type="submit"] { + -webkit-appearance: button; } button::-moz-focus-inner, [type="button"]::-moz-focus-inner, [type="reset"]::-moz-focus-inner, -[type="submit"]::-moz-focus-inner {border-style: none;padding: 0; +[type="submit"]::-moz-focus-inner { + border-style: none; + padding: 0; } button:-moz-focusring, [type="button"]:-moz-focusring, [type="reset"]:-moz-focusring, -[type="submit"]:-moz-focusring {outline: 1px dotted ButtonText; +[type="submit"]:-moz-focusring { + outline: 1px dotted ButtonText; } -fieldset {padding: 0.35em 0.75em 0.625em; +fieldset { + padding: 0.35em 0.75em 0.625em; } -legend {box-sizing: border-box;color: inherit;display: table;max-width: 100%;padding: 0;white-space: normal; +legend { + box-sizing: border-box; + color: inherit; + display: table; + max-width: 100%; + padding: 0; + white-space: normal; } -progress {vertical-align: baseline; +progress { + vertical-align: baseline; } -textarea {overflow: auto; +textarea { + overflow: auto; } [type="number"]::-webkit-inner-spin-button, -[type="number"]::-webkit-outer-spin-button {height: auto; +[type="number"]::-webkit-outer-spin-button { + height: auto; } -[type="search"] {-webkit-appearance: textfield;outline-offset: -2px; +[type="search"] { + -webkit-appearance: textfield; + outline-offset: -2px; } [type="search"]::-webkit-search-cancel-button, -[type="search"]::-webkit-search-decoration {-webkit-appearance: none; +[type="search"]::-webkit-search-decoration { + -webkit-appearance: none; } -::-webkit-file-upload-button {-webkit-appearance: button;font: inherit; +::-webkit-file-upload-button { + -webkit-appearance: button; + font: inherit; } -details {display: block; +details { + display: block; } -summary {display: list-item; +summary { + display: list-item; } -template {display: none; +template { + display: none; } body { font-family: sans-serif; diff --git a/test/basic.last-2.expect.css b/test/basic.last-2.expect.css index 4733f8ab42..737218fd34 100644 --- a/test/basic.last-2.expect.css +++ b/test/basic.last-2.expect.css @@ -1,92 +1,148 @@ -html {line-height: 1.15;-ms-text-size-adjust: 100%;-webkit-text-size-adjust: 100%; +html { + line-height: 1.15; + -ms-text-size-adjust: 100%; + -webkit-text-size-adjust: 100%; } -h1 {font-size: 2em;margin: 0.67em 0; +h1 { + font-size: 2em; + margin: 0.67em 0; } -main {display: block; +main { + display: block; } -hr {box-sizing: content-box;height: 0;overflow: visible; +hr { + box-sizing: content-box; + height: 0; + overflow: visible; } -pre {font-family: monospace, monospace;font-size: 1em; +pre { + font-family: monospace, monospace; + font-size: 1em; } -a {background-color: transparent;-webkit-text-decoration-skip: objects; +a { + background-color: transparent; + -webkit-text-decoration-skip: objects; } -abbr[title] {border-bottom: none;text-decoration: underline;text-decoration: underline dotted; +abbr[title] { + border-bottom: none; + text-decoration: underline; + text-decoration: underline dotted; } b, -strong {font-weight: bolder; +strong { + font-weight: bolder; } code, kbd, -samp {font-family: monospace, monospace;font-size: 1em; +samp { + font-family: monospace, monospace; + font-size: 1em; } -small {font-size: 80%; +small { + font-size: 80%; } sub, -sup {font-size: 75%;line-height: 0;position: relative;vertical-align: baseline; +sup { + font-size: 75%; + line-height: 0; + position: relative; + vertical-align: baseline; } -sub {bottom: -0.25em; +sub { + bottom: -0.25em; } -sup {top: -0.5em; +sup { + top: -0.5em; } -img {border-style: none; +img { + border-style: none; } -svg:not(:root) {overflow: hidden; +svg:not(:root) { + overflow: hidden; } button, input, optgroup, select, -textarea {margin: 0; +textarea { + margin: 0; } button, -input {overflow: visible; +input { + overflow: visible; } button, -select {text-transform: none; +select { + text-transform: none; } button, [type="button"], [type="reset"], -[type="submit"] {-webkit-appearance: button; +[type="submit"] { + -webkit-appearance: button; } button::-moz-focus-inner, [type="button"]::-moz-focus-inner, [type="reset"]::-moz-focus-inner, -[type="submit"]::-moz-focus-inner {border-style: none;padding: 0; +[type="submit"]::-moz-focus-inner { + border-style: none; + padding: 0; } button:-moz-focusring, [type="button"]:-moz-focusring, [type="reset"]:-moz-focusring, -[type="submit"]:-moz-focusring {outline: 1px dotted ButtonText; +[type="submit"]:-moz-focusring { + outline: 1px dotted ButtonText; } -fieldset {padding: 0.35em 0.75em 0.625em; +fieldset { + padding: 0.35em 0.75em 0.625em; } -legend {box-sizing: border-box;color: inherit;display: table;max-width: 100%;padding: 0;white-space: normal; +legend { + box-sizing: border-box; + color: inherit; + display: table; + max-width: 100%; + padding: 0; + white-space: normal; } -progress {vertical-align: baseline; +progress { + vertical-align: baseline; } -textarea {overflow: auto; +textarea { + overflow: auto; } [type="checkbox"], -[type="radio"] {box-sizing: border-box;padding: 0; +[type="radio"] { + box-sizing: border-box; + padding: 0; } [type="number"]::-webkit-inner-spin-button, -[type="number"]::-webkit-outer-spin-button {height: auto; +[type="number"]::-webkit-outer-spin-button { + height: auto; } -[type="search"] {-webkit-appearance: textfield;outline-offset: -2px; +[type="search"] { + -webkit-appearance: textfield; + outline-offset: -2px; } [type="search"]::-webkit-search-cancel-button, -[type="search"]::-webkit-search-decoration {-webkit-appearance: none; +[type="search"]::-webkit-search-decoration { + -webkit-appearance: none; } -::-webkit-file-upload-button {-webkit-appearance: button;font: inherit; +::-webkit-file-upload-button { + -webkit-appearance: button; + font: inherit; } -details {display: block; +details { + display: block; } -summary {display: list-item; +summary { + display: list-item; } -template {display: none; +template { + display: none; } -[hidden] {display: none; +[hidden] { + display: none; } body { font-family: sans-serif; From 19e24de8b65a25e1e05e5a9a2a406ef0eddc1582 Mon Sep 17 00:00:00 2001 From: Jonathan Neal Date: Sun, 21 May 2017 21:15:03 -0400 Subject: [PATCH 452/795] 2.0.1 --- CHANGELOG.md | 4 ++++ package.json | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 67798b9ed8..71e1441f15 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # Changes to PostCSS Normalize +### 2.0.1 (May 21, 2017) + +- Update tree creation to avoid AST issues with other PostCSS plugins + ### 2.0.0 (May 17, 2017) - Support PostCSS 6 diff --git a/package.json b/package.json index c9d984da1a..b42c277f2f 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "postcss-normalize", - "version": "2.0.0", + "version": "2.0.1", "description": "Use the parts of normalize.css you need from your browserlist", "author": "Jonathan Neal ", "license": "CC0-1.0", From b638e5a76ebd673c95e006185a09315a78e4cb9a Mon Sep 17 00:00:00 2001 From: Jonathan Neal Date: Mon, 22 May 2017 13:24:23 -0400 Subject: [PATCH 453/795] Improve selector validity testing --- lib/transform-nesting-atrule.js | 2 +- lib/transform-nesting-rule.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/transform-nesting-atrule.js b/lib/transform-nesting-atrule.js index a7f954e5aa..08ece98db1 100644 --- a/lib/transform-nesting-atrule.js +++ b/lib/transform-nesting-atrule.js @@ -39,5 +39,5 @@ module.exports = (node) => { // whether the node is a nesting atrule (e.g. @nest .something &) module.exports.test = (node) => node.type === 'atrule' && node.name === 'nest' && node.parent && node.parent.type === 'rule' && comma(node.params).every( - (selector) => selector.split('&').length === 2 && /&([^A-z]|$)/.test(selector) + (selector) => selector.split('&').length === 2 && /&([^\w-]|$)/.test(selector) ); diff --git a/lib/transform-nesting-rule.js b/lib/transform-nesting-rule.js index 40ee9c8d7e..4ace658692 100644 --- a/lib/transform-nesting-rule.js +++ b/lib/transform-nesting-rule.js @@ -25,5 +25,5 @@ module.exports = (node) => { // whether the node is a nesting rule (e.g. &.something) module.exports.test = (node) => node.type === 'rule' && node.parent && node.parent.type === 'rule' && node.selectors.every( - (selector) => selector.trim().lastIndexOf('&') === 0 && /^&([^A-z]|$)/.test(selector) + (selector) => selector.trim().lastIndexOf('&') === 0 && /^&([^\w-]|$)/.test(selector) ); From 410cfc7f7a3fb1b5307f475a0a16eab522153ee1 Mon Sep 17 00:00:00 2001 From: Jonathan Neal Date: Mon, 22 May 2017 13:25:08 -0400 Subject: [PATCH 454/795] 4.0.1 --- CHANGELOG.md | 4 ++++ package.json | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 81a2ed8258..86d12c75a6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # Changes to PostCSS Nesting +### 4.0.1 (May 22, 2017) + +- Improve selector validity testing + ### 4.0.0 (May 20, 2017) - Transform only compliant nesting diff --git a/package.json b/package.json index 3aca9e0ae6..a70d46165b 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "postcss-nesting", - "version": "4.0.0", + "version": "4.0.1", "description": "Nest style and media rules inside each another, following the CSS Nesting Module Level 3 specification", "author": "Jonathan Neal ", "license": "CC0-1.0", From ce1e63cefefba334ea314f282275b031b91678ee Mon Sep 17 00:00:00 2001 From: Jonathan Neal Date: Tue, 23 May 2017 10:16:14 -0400 Subject: [PATCH 455/795] 1.0.0 --- .appveyor.yml | 18 ++++ .gitignore | 9 ++ .tape.js | 41 +++++++++ .travis.yml | 9 ++ CHANGELOG.md | 5 ++ CONTRIBUTING.md | 65 +++++++++++++++ LICENSE.md | 106 ++++++++++++++++++++++++ README.md | 187 ++++++++++++++++++++++++++++++++++++++++++ index.js | 63 ++++++++++++++ package.json | 56 +++++++++++++ test/basic.css | 20 +++++ test/basic.expect.css | 20 +++++ 12 files changed, 599 insertions(+) create mode 100644 .appveyor.yml create mode 100644 .gitignore create mode 100644 .tape.js create mode 100644 .travis.yml create mode 100644 CHANGELOG.md create mode 100644 CONTRIBUTING.md create mode 100644 LICENSE.md create mode 100644 README.md create mode 100644 index.js create mode 100644 package.json create mode 100644 test/basic.css create mode 100644 test/basic.expect.css diff --git a/.appveyor.yml b/.appveyor.yml new file mode 100644 index 0000000000..d6b511f500 --- /dev/null +++ b/.appveyor.yml @@ -0,0 +1,18 @@ +# https://www.appveyor.com/docs/appveyor-yml + +environment: + matrix: + - nodejs_version: 4.0 + +version: "{build}" +build: off +deploy: off + +install: + - ps: Install-Product node $env:nodejs_version + - npm install --ignore-scripts + +test_script: + - node --version + - npm --version + - cmd: "npm test" diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000000..540f9a9674 --- /dev/null +++ b/.gitignore @@ -0,0 +1,9 @@ +node_modules +.* +!.appveyor.yml +!.gitignore +!.tape.js +!.travis.yml +*.log* +*.result.css +basic.css.* diff --git a/.tape.js b/.tape.js new file mode 100644 index 0000000000..e5f4fb1ba5 --- /dev/null +++ b/.tape.js @@ -0,0 +1,41 @@ +const cache = []; + +module.exports = { + 'postcss-focus-ring': { + 'basic': { + message: 'supports basic usage' + }, + 'basic:cache': { + message: 'supports { assignTo: [] } usage', + options: { + assignTo: cache + }, + after: () => { + const expectJSON = '[".focus-ring",".focus-ring test","test .focus-ring","test test.focus-ring","test .focus-ring test","test test.focus-ring test","test .focus-ring .focus-ring test","test :matches(.focus-ring) test","test :matches(.focus-ring test) test","test :matches(test .focus-ring) test","test :matches(test test.focus-ring) test","test :matches(test .focus-ring test) test","test :matches(test test.focus-ring test) test","test :matches(test .focus-ring .focus-ring test) test"]'; + const resultJSON = JSON.stringify(cache); + + if (expectJSON !== resultJSON) { + throw new Error('JSON does not match'); + } + }, + expect: 'basic.expect.css', + result: 'basic.result.css' + }, + 'basic:exportas-js': { + message: 'supports { exportAs: "js" } usage', + options: { + exportAs: 'js' + }, + expect: 'basic.expect.css', + result: 'basic.result.css' + }, + 'basic:exportas-json': { + message: 'supports { exportAs: "json" } usage', + options: { + exportAs: 'json' + }, + expect: 'basic.expect.css', + result: 'basic.result.css' + } + } +}; diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000000..c56466446c --- /dev/null +++ b/.travis.yml @@ -0,0 +1,9 @@ +# https://docs.travis-ci.com/user/travis-lint + +language: node_js + +node_js: + - 4 + +install: + - npm install --ignore-scripts diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000000..062b0a96aa --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,5 @@ +# Changes to PostCSS Focus Ring + +### 1.0.0 (May 22, 2017) + +- Initial version diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 0000000000..41693d5f9d --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,65 @@ +# Contributing to PostCSS Focus Ring + +You want to help? You rock! Now, take a moment to be sure your contributions +make sense to everyone else. + +## Reporting Issues + +Found a problem? Want a new feature? + +- See if your issue or idea has [already been reported]. +- Provide a [reduced test case] or a [live example]. + +Remember, a bug is a _demonstrable problem_ caused by _our_ code. + +## Submitting Pull Requests + +Pull requests are the greatest contributions, so be sure they are focused in +scope and avoid unrelated commits. + +1. To begin; [fork this project], clone your fork, and add our upstream. + ```bash + # Clone your fork of the repo into the current directory + git clone git@github.com:YOUR_USER/postcss-focus-ring.git + + # Navigate to the newly cloned directory + cd postcss-focus-ring + + # Assign the original repo to a remote called "upstream" + git remote add upstream git@github.com:jonathantneal/postcss-focus-ring.git + + # Install the tools necessary for testing + npm install + ``` + +2. Create a branch for your feature or fix: + ```bash + # Move into a new branch for your feature + git checkout -b feature/thing + ``` + ```bash + # Move into a new branch for your fix + git checkout -b fix/something + ``` + +3. If your code follows our practices, then push your feature branch: + ```bash + # Test current code + npm test + ``` + ```bash + # Push the branch for your new feature + git push origin feature/thing + ``` + ```bash + # Or, push the branch for your update + git push origin update/something + ``` + +That’s it! Now [open a pull request] with a clear title and description. + +[already been reported]: issues +[fork this project]: fork +[live example]: https://codepen.io/pen +[open a pull request]: https://help.github.com/articles/using-pull-requests/ +[reduced test case]: https://css-tricks.com/reduced-test-cases/ diff --git a/LICENSE.md b/LICENSE.md new file mode 100644 index 0000000000..b5bc55c9f6 --- /dev/null +++ b/LICENSE.md @@ -0,0 +1,106 @@ +# CC0 1.0 Universal + +## Statement of Purpose + +The laws of most jurisdictions throughout the world automatically confer +exclusive Copyright and Related Rights (defined below) upon the creator and +subsequent owner(s) (each and all, an “owner”) of an original work of +authorship and/or a database (each, a “Work”). + +Certain owners wish to permanently relinquish those rights to a Work for the +purpose of contributing to a commons of creative, cultural and scientific works +(“Commons”) that the public can reliably and without fear of later claims of +infringement build upon, modify, incorporate in other works, reuse and +redistribute as freely as possible in any form whatsoever and for any purposes, +including without limitation commercial purposes. These owners may contribute +to the Commons to promote the ideal of a free culture and the further +production of creative, cultural and scientific works, or to gain reputation or +greater distribution for their Work in part through the use and efforts of +others. + +For these and/or other purposes and motivations, and without any expectation of +additional consideration or compensation, the person associating CC0 with a +Work (the “Affirmer”), to the extent that he or she is an owner of Copyright +and Related Rights in the Work, voluntarily elects to apply CC0 to the Work and +publicly distribute the Work under its terms, with knowledge of his or her +Copyright and Related Rights in the Work and the meaning and intended legal +effect of CC0 on those rights. + +1. Copyright and Related Rights. A Work made available under CC0 may be + protected by copyright and related or neighboring rights (“Copyright and + Related Rights”). Copyright and Related Rights include, but are not limited + to, the following: + 1. the right to reproduce, adapt, distribute, perform, display, + communicate, and translate a Work; + 2. moral rights retained by the original author(s) and/or performer(s); + 3. publicity and privacy rights pertaining to a person’s image or likeness + depicted in a Work; + 4. rights protecting against unfair competition in regards to a Work, + subject to the limitations in paragraph 4(i), below; + 5. rights protecting the extraction, dissemination, use and reuse of data + in a Work; + 6. database rights (such as those arising under Directive 96/9/EC of the + European Parliament and of the Council of 11 March 1996 on the legal + protection of databases, and under any national implementation thereof, + including any amended or successor version of such directive); and + 7. other similar, equivalent or corresponding rights throughout the world + based on applicable law or treaty, and any national implementations + thereof. + +2. Waiver. To the greatest extent permitted by, but not in contravention of, +applicable law, Affirmer hereby overtly, fully, permanently, irrevocably and +unconditionally waives, abandons, and surrenders all of Affirmer’s Copyright +and Related Rights and associated claims and causes of action, whether now +known or unknown (including existing as well as future claims and causes of +action), in the Work (i) in all territories worldwide, (ii) for the maximum +duration provided by applicable law or treaty (including future time +extensions), (iii) in any current or future medium and for any number of +copies, and (iv) for any purpose whatsoever, including without limitation +commercial, advertising or promotional purposes (the “Waiver”). Affirmer makes +the Waiver for the benefit of each member of the public at large and to the +detriment of Affirmer’s heirs and successors, fully intending that such Waiver +shall not be subject to revocation, rescission, cancellation, termination, or +any other legal or equitable action to disrupt the quiet enjoyment of the Work +by the public as contemplated by Affirmer’s express Statement of Purpose. + +3. Public License Fallback. Should any part of the Waiver for any reason be +judged legally invalid or ineffective under applicable law, then the Waiver +shall be preserved to the maximum extent permitted taking into account +Affirmer’s express Statement of Purpose. In addition, to the extent the Waiver +is so judged Affirmer hereby grants to each affected person a royalty-free, non +transferable, non sublicensable, non exclusive, irrevocable and unconditional +license to exercise Affirmer’s Copyright and Related Rights in the Work (i) in +all territories worldwide, (ii) for the maximum duration provided by applicable +law or treaty (including future time extensions), (iii) in any current or +future medium and for any number of copies, and (iv) for any purpose +whatsoever, including without limitation commercial, advertising or promotional +purposes (the “License”). The License shall be deemed effective as of the date +CC0 was applied by Affirmer to the Work. Should any part of the License for any +reason be judged legally invalid or ineffective under applicable law, such +partial invalidity or ineffectiveness shall not invalidate the remainder of the +License, and in such case Affirmer hereby affirms that he or she will not (i) +exercise any of his or her remaining Copyright and Related Rights in the Work +or (ii) assert any associated claims and causes of action with respect to the +Work, in either case contrary to Affirmer’s express Statement of Purpose. + +4. Limitations and Disclaimers. + 1. No trademark or patent rights held by Affirmer are waived, abandoned, + surrendered, licensed or otherwise affected by this document. + 2. Affirmer offers the Work as-is and makes no representations or + warranties of any kind concerning the Work, express, implied, statutory + or otherwise, including without limitation warranties of title, + merchantability, fitness for a particular purpose, non infringement, or + the absence of latent or other defects, accuracy, or the present or + absence of errors, whether or not discoverable, all to the greatest + extent permissible under applicable law. + 3. Affirmer disclaims responsibility for clearing rights of other persons + that may apply to the Work or any use thereof, including without + limitation any person’s Copyright and Related Rights in the Work. + Further, Affirmer disclaims responsibility for obtaining any necessary + consents, permissions or other rights required for any use of the Work. + 4. Affirmer understands and acknowledges that Creative Commons is not a + party to this document and has no duty or obligation with respect to + this CC0 or use of the Work. + +For more information, please see +https://creativecommons.org/publicdomain/zero/1.0/. diff --git a/README.md b/README.md new file mode 100644 index 0000000000..9b2d76ecd4 --- /dev/null +++ b/README.md @@ -0,0 +1,187 @@ +# PostCSS Focus Ring [PostCSS Logo][postcss] + +[![NPM Version][npm-img]][npm-url] +[![Linux Build Status][cli-img]][cli-url] +[![Windows Build Status][win-img]][win-url] +[![Gitter Chat][git-img]][git-url] + +[PostCSS Focus Ring] lets you use the `:focus-ring` pseudo-selector in CSS, +following the [Selectors Level 4] specification. + +```css +:focus:not(:focus-ring) { + outline: none; +} +``` + +Use PostCSS Focus Ring alongside the [focus-ring polyfill] to swap the +pseudo-selector for a class, which maintains the same selector weight. + +```css +:focus:not(.focus-ring) { + outline: none; +} +``` + +--- + +Additionally, transformed selectors can be exported to a JSON file. + +```js +require('postcss-focus-ring')({ + exportAs: 'json' +}); +``` + +```json +[ + ".focus-ring", + ".x-component-outside .focus-ring", + ".focus-ring .x-component-inside", +] +``` + +Or as a JavaScript export: + +```js +require('postcss-focus-ring')({ + exportAs: 'js' +}); +``` + +```js +export default [ + ".focus-ring", + ".x-component-outside .focus-ring", + ".focus-ring .x-component-inside", +]; +``` + +With these variables synchronized to JavaScript, they can be used alongside the +[focus-ring polyfill]. + +## Usage + +Add [PostCSS Focus Ring] to your build tool: + +```bash +npm install postcss-focus-ring --save-dev +``` + +#### Node + +Use [PostCSS Focus Ring] to process your CSS: + +```js +require('postcss-focus-ring').process(YOUR_CSS); +``` + +#### PostCSS + +Add [PostCSS] to your build tool: + +```bash +npm install postcss --save-dev +``` + +Use [PostCSS Focus Ring] as a plugin: + +```js +postcss([ + require('postcss-focus-ring')() +]).process(YOUR_CSS); +``` + +#### Gulp + +Add [Gulp PostCSS] to your build tool: + +```bash +npm install gulp-postcss --save-dev +``` + +Use [PostCSS Focus Ring] in your Gulpfile: + +```js +var postcss = require('gulp-postcss'); + +gulp.task('css', function () { + return gulp.src('./src/*.css').pipe( + postcss([ + require('postcss-focus-ring')() + ]) + ).pipe( + gulp.dest('.') + ); +}); +``` + +#### Grunt + +Add [Grunt PostCSS] to your build tool: + +```bash +npm install grunt-postcss --save-dev +``` + +Use [PostCSS Focus Ring] in your Gruntfile: + +```js +grunt.loadNpmTasks('grunt-postcss'); + +grunt.initConfig({ + postcss: { + options: { + use: [ + require('postcss-focus-ring')() + ] + }, + dist: { + src: '*.css' + } + } +}); +``` + +## Advanced Options + +These options may be passed directly into the plugin. + +```js +require('postcss-focus-ring')({ /* options */ }); +``` + +#### exportAs + +`exportAs` is used to export transformed selectors originally containing the +`:focus-ring` pseudo-selector. + +- If a `js` string is passed, the selectors will be exported as JavaScript. +- If a `json` string is passed, the selectors will be exported as JSON. + +#### exportTo + +`exportTo` is the path to where your JSON or JavaScript will be saved. By +default, it is the CSS source file with an additional `focus-ring-selectors` +and `.js` or `.json` extension. + +#### assignTo + +`assignTo` is an Array you may push your transformed selectors to. This can +be useful if running the plugin on the client side. + +[npm-url]: https://www.npmjs.com/package/postcss-focus-ring +[npm-img]: https://img.shields.io/npm/v/postcss-focus-ring.svg +[cli-url]: https://travis-ci.org/jonathantneal/postcss-focus-ring +[cli-img]: https://img.shields.io/travis/jonathantneal/postcss-focus-ring.svg +[win-url]: https://ci.appveyor.com/project/jonathantneal/postcss-focus-ring +[win-img]: https://img.shields.io/appveyor/ci/jonathantneal/postcss-focus-ring.svg +[git-url]: https://gitter.im/postcss/postcss +[git-img]: https://img.shields.io/badge/chat-gitter-blue.svg + +[PostCSS Focus Ring]: https://github.com/jonathantneal/postcss-focus-ring +[PostCSS]: https://github.com/postcss/postcss +[Gulp PostCSS]: https://github.com/postcss/gulp-postcss +[Grunt PostCSS]: https://github.com/nDmitry/grunt-postcss +[Selectors Level 4]: https://drafts.csswg.org/selectors-4/#the-focusring-pseudo +[focus-ring polyfill]: https://github.com/WICG/focus-ring diff --git a/index.js b/index.js new file mode 100644 index 0000000000..85715a3992 --- /dev/null +++ b/index.js @@ -0,0 +1,63 @@ +// tooling +const fs = require('fs'); +const postcss = require('postcss'); +const parser = require('postcss-selector-parser'); + +// plugin +module.exports = postcss.plugin('postcss-focus-ring', (opts) => (root) => { // eslint-disable-line consistent-return + // transformed cache + const transformed = []; + + // walk each matching rule + root.walkRules(/:focus-ring\b/, (rule) => { + // original selector + const originalSelector = rule.selector; + + // transformed selector + const transformedSelector = parser((selectors) => { + // for each selector part + selectors.walk((selector) => { + // if the selector part is a :focus-ring pseudo + if (selector.type === 'pseudo' && selector.value === ':focus-ring') { + // change it to a .focus-ring class + selector.value = '.focus-ring'; + selector.type = 'class'; + } + }); + }).process(originalSelector).result; + + // if the selector has changed + if (originalSelector !== transformedSelector) { + // update the rule’s selector + rule.selector = transformedSelector; + + // push the transformed selector into the transformed cache + transformed.push.apply(transformed, rule.selectors); + } + }); + + // filter the transformed cache of repeats + const transformedClean = transformed.filter((selector, index) => transformed.indexOf(selector) === index); + + // if the assignTo option is enabled + if (opts && opts.assignTo) { + // push the transformed cache into the assignTo option + opts.assignTo.push.apply(opts.assignTo, transformedClean); + } + + // if the exportAs option is enabled + if (opts && opts.exportAs) { + // destination path + const destination = `${ opts.destination || `${ + root.source && root.source.input && root.source.input.file && root.source.input.file || 'css' + }.focus-ring-selectors.${ opts.exportAs === 'js' ? 'js' : 'json' }` }`; + + // stringified contents + const json = JSON.stringify(transformedClean, null, ' '); + const contents = opts.exportAs === 'js' ? `export default ${ json };` : json; + + return new Promise((resolve, reject) => { + fs.writeFile(destination, contents, (error) => error ? reject(error) : resolve()); + }); + } +}); diff --git a/package.json b/package.json new file mode 100644 index 0000000000..26655147eb --- /dev/null +++ b/package.json @@ -0,0 +1,56 @@ +{ + "name": "postcss-focus-ring", + "version": "1.0.0", + "description": "Use the :focus-ring pseudo-selector in CSS", + "author": "Jonathan Neal ", + "license": "CC0-1.0", + "repository": "jonathantneal/postcss-focus-ring", + "homepage": "https://github.com/jonathantneal/postcss-focus-ring#readme", + "bugs": "https://github.com/jonathantneal/postcss-focus-ring/issues", + "main": "index.js", + "files": [ + "index.js" + ], + "scripts": { + "clean": "git clean -X -d -f", + "prepublish": "npm test", + "test": "echo 'Running tests...'; npm run test:js && npm run test:tape", + "test:js": "eslint *.js --cache --ignore-pattern .gitignore", + "test:tape": "postcss-tape" + }, + "engines": { + "node": ">=4.0.0" + }, + "dependencies": { + "postcss": "^6.0.1", + "postcss-selector-parser": "^2.2.3" + }, + "devDependencies": { + "eslint": "^3.19.0", + "eslint-config-dev": "2.0.0", + "postcss-tape": "2.0.1", + "pre-commit": "^1.2.2" + }, + "eslintConfig": { + "extends": "dev" + }, + "keywords": [ + "postcss", + "css", + "postcss-plugin", + "focus", + "ring", + "css4", + "selectors", + "accessibility", + "a11y", + "input", + "keyboard", + "mouse", + "pen", + "pointer", + "cursor", + "trackpad", + "javascript" + ] +} diff --git a/test/basic.css b/test/basic.css new file mode 100644 index 0000000000..06df6bf939 --- /dev/null +++ b/test/basic.css @@ -0,0 +1,20 @@ +:focus-ring { + order: 1; +} + +:focus-ring, +:focus-ring test, +test :focus-ring, +test test:focus-ring, +test :focus-ring test, +test test:focus-ring test, +test :focus-ring :focus-ring test, +test :matches(:focus-ring) test, +test :matches(:focus-ring test) test, +test :matches(test :focus-ring) test, +test :matches(test test:focus-ring) test, +test :matches(test :focus-ring test) test, +test :matches(test test:focus-ring test) test, +test :matches(test :focus-ring :focus-ring test) test { + order: 2; +} diff --git a/test/basic.expect.css b/test/basic.expect.css new file mode 100644 index 0000000000..5f92e4fad5 --- /dev/null +++ b/test/basic.expect.css @@ -0,0 +1,20 @@ +.focus-ring { + order: 1; +} + +.focus-ring, +.focus-ring test, +test .focus-ring, +test test.focus-ring, +test .focus-ring test, +test test.focus-ring test, +test .focus-ring .focus-ring test, +test :matches(.focus-ring) test, +test :matches(.focus-ring test) test, +test :matches(test .focus-ring) test, +test :matches(test test.focus-ring) test, +test :matches(test .focus-ring test) test, +test :matches(test test.focus-ring test) test, +test :matches(test .focus-ring .focus-ring test) test { + order: 2; +} From 12991d82b5098b0f8b3e3c103181d6161e72b1e2 Mon Sep 17 00:00:00 2001 From: Jonathan Neal Date: Fri, 26 May 2017 16:16:12 -0400 Subject: [PATCH 456/795] 2.1.0 --- .appveyor.yml | 18 ++++ .editorconfig | 15 +++ .gitignore | 3 + .tape.js | 7 ++ .travis.yml | 4 + CHANGELOG.md | 5 + README.md | 21 ++-- index.js | 52 +++++----- lib/json-to-ast.js | 26 ----- lib/normalize-css-to-json.js | 76 --------------- lib/normalize-init.js | 30 ++++++ lib/normalize.js | 36 +++++++ package.json | 9 +- test/insertion.css | 5 + test/insertion.expect.css | 183 +++++++++++++++++++++++++++++++++++ test/insertion.w-quotes.css | 5 + 16 files changed, 358 insertions(+), 137 deletions(-) create mode 100644 .appveyor.yml create mode 100644 .editorconfig delete mode 100644 lib/json-to-ast.js delete mode 100644 lib/normalize-css-to-json.js create mode 100644 lib/normalize-init.js create mode 100644 lib/normalize.js create mode 100644 test/insertion.css create mode 100644 test/insertion.expect.css create mode 100644 test/insertion.w-quotes.css diff --git a/.appveyor.yml b/.appveyor.yml new file mode 100644 index 0000000000..d6b511f500 --- /dev/null +++ b/.appveyor.yml @@ -0,0 +1,18 @@ +# https://www.appveyor.com/docs/appveyor-yml + +environment: + matrix: + - nodejs_version: 4.0 + +version: "{build}" +build: off +deploy: off + +install: + - ps: Install-Product node $env:nodejs_version + - npm install --ignore-scripts + +test_script: + - node --version + - npm --version + - cmd: "npm test" diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000000..e06d7982bc --- /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/.gitignore b/.gitignore index 7a85c88ad1..04d3d72273 100644 --- a/.gitignore +++ b/.gitignore @@ -1,8 +1,11 @@ node_modules .* +!.appveyor.yml +!.editorconfig !.gitignore !.tape.js !.travis.yml *.log* *.result.css +/index.css /lib/normalize.json diff --git a/.tape.js b/.tape.js index 7594d96570..866dcdd26a 100644 --- a/.tape.js +++ b/.tape.js @@ -14,6 +14,13 @@ module.exports = { options: { browsers: 'last 1 versions' } + }, + 'insertion': { + message: 'supports insertion usage' + }, + 'insertion:w-quotes': { + message: 'supports insertion with quotes usage', + expect: 'insertion.expect.css' } } }; diff --git a/.travis.yml b/.travis.yml index 4feb3dc027..c56466446c 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,5 +1,9 @@ # https://docs.travis-ci.com/user/travis-lint language: node_js + node_js: - 4 + +install: + - npm install --ignore-scripts diff --git a/CHANGELOG.md b/CHANGELOG.md index 71e1441f15..f0a0704bfb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,10 @@ # Changes to PostCSS Normalize +### 2.1.0 (May 26, 2017) + +- Support an insertion point via `@import postcss-normalize` +- Update tree creation to avoid AST issues with source + ### 2.0.1 (May 21, 2017) - Update tree creation to avoid AST issues with other PostCSS plugins diff --git a/README.md b/README.md index 4c90926d2b..3202b50de2 100644 --- a/README.md +++ b/README.md @@ -2,8 +2,7 @@ [![NPM Version][npm-img]][npm-url] [![Build Status][cli-img]][cli-url] -[![Licensing][lic-img]][lic-url] -[![Changelog][log-img]][log-url] +[![Windows Build Status][win-img]][win-url] [![Gitter Chat][git-img]][git-url] [PostCSS Normalize] lets you automatically include the parts of [normalize.css] @@ -46,6 +45,16 @@ img { } ``` +[PostCSS Normalize] will put itself at the beginning of your CSS file. You +may also dictate where it should be included: + +```css +@import "postcss-normalize"; +``` + +This technique is compatible with [PostCSS Import] and +[PostCSS Partial Import], regardless if they run first. + ## Usage Add [PostCSS Normalize] to your build tool: @@ -141,10 +150,8 @@ grunt.initConfig({ [npm-img]: https://img.shields.io/npm/v/postcss-normalize.svg [cli-url]: https://travis-ci.org/jonathantneal/postcss-normalize [cli-img]: https://img.shields.io/travis/jonathantneal/postcss-normalize.svg -[lic-url]: LICENSE.md -[lic-img]: https://img.shields.io/npm/l/postcss-normalize.svg -[log-url]: CHANGELOG.md -[log-img]: https://img.shields.io/badge/changelog-md-blue.svg +[win-url]: https://ci.appveyor.com/project/jonathantneal/postcss-normalize +[win-img]: https://img.shields.io/appveyor/ci/jonathantneal/postcss-normalize.svg [git-url]: https://gitter.im/postcss/postcss [git-img]: https://img.shields.io/badge/chat-gitter-blue.svg @@ -155,3 +162,5 @@ grunt.initConfig({ [browserlist]: http://browserl.ist/ [normalize.css]: https://github.com/jonathantneal/normalize.css +[PostCSS Import]: https://github.com/postcss/postcss-import +[PostCSS Partial Import]: https://github.com/jonathantneal/postcss-partial-import diff --git a/index.js b/index.js index 70ed7a8852..b032007bc0 100644 --- a/index.js +++ b/index.js @@ -1,49 +1,51 @@ // tooling -const browserslist = require('browserslist'); -const jsonToAst = require('./lib/json-to-ast'); -const normalizeJSON = require('./lib/normalize.json'); -const postcss = require('postcss'); +const browserslist = require('browserslist'); +const normalizeRules = require('./lib/normalize.js'); +const postcss = require('postcss'); // plugin module.exports = postcss.plugin('postcss-normalize', (opts) => { - const normalizeAST = jsonToAst(normalizeJSON); - return (root) => { // client browser list const clientBrowserList = browserslist(opts && opts.browsers, { path: root.source && root.source.input && root.source.input.file }); - // required normalize rules - const normalizeRules = normalizeAST.nodes.filter( + // applied rules from normalize + const appliedRules = normalizeRules.map( (rule) => { - // required normalize declarations - rule.nodes = rule.nodes.filter( - (decl) => { + const clone = rule.clone(); + + clone.nodes = clone.nodes.filter( + (decl, index) => { // whether the declaration browser list matches the client browser list - const declIsUsed = clientBrowserList.some( - (clientBrowser) => browserslist(decl.browserList).some( + return clientBrowserList.some( + (clientBrowser) => browserslist(rule.nodes[index].browserList).some( (declBrowser) => declBrowser === clientBrowser ) ); - - // restore source mapping - decl.source.input = normalizeJSON.source.input; - - return declIsUsed; } ); - // restore source mapping - rule.source.input = normalizeJSON.source.input; + return clone; + } + ).filter( + (rule) => rule.nodes.length + ); - return rule.nodes.length; + // check for an @import postcss-normalize insertion point + root.walkAtRules( + 'import', + (atrule) => { + if (atrule.params === 'postcss-normalize') { + atrule.replaceWith(appliedRules); + } } - ).map( - (rule) => rule.clone() ); - // prepend required normalize rules - root.prepend(normalizeRules); + if (!appliedRules[0].parent) { + // prepend required normalize rules + root.prepend(appliedRules); + } }; }); diff --git a/lib/json-to-ast.js b/lib/json-to-ast.js deleted file mode 100644 index 0d96a5d6f7..0000000000 --- a/lib/json-to-ast.js +++ /dev/null @@ -1,26 +0,0 @@ -// tooling -const postcss = require('postcss'); - -// convert a json object into a postcss object -module.exports = (json) => { - // convert the current object into a postcss object - const node = postcss[json.type]( - // use the cloned json - Object.assign( - {}, - json, - json.nodes ? { nodes: [] } : {} - ) - ); - - // if the json object has nodes - if (json.nodes) { - // append the nodes as postcss objects - node.append( - json.nodes.map(module.exports) - ); - } - - // return the postcss object - return node; -}; diff --git a/lib/normalize-css-to-json.js b/lib/normalize-css-to-json.js deleted file mode 100644 index a09534cade..0000000000 --- a/lib/normalize-css-to-json.js +++ /dev/null @@ -1,76 +0,0 @@ -'use strict'; - -// tooling -const fs = require('fse'); -const path = require('path'); -const postcss = require('postcss'); -const normalizeBrowserList = require('./normalize-browser-list.json'); - -// paths to normalize.css and normalize.json -const pathToNormalizeCSS = path.resolve(__dirname, 'normalize.css'); -const pathToNormalizeJSON = path.resolve(__dirname, 'normalize.json'); - -Promise.resolve().then( - // parse normalize.css - () => fs.readFile(pathToNormalizeCSS, 'utf8').then( - (normalizeCSS) => postcss.parse( - normalizeCSS, - { - from: pathToNormalizeCSS - } - ) - ) -).then( - // add browserlist to each declaration - (normalizeAST) => { - // preserve sourcemap - const sourceInput = { - css: normalizeAST.source.input.css, - file: 'https://jonathantneal.github.io/normalize.css/6.0.0/normalize.css' - }; - - // filter rules - let normalizeBrowserListIndex = -1; - - normalizeAST.nodes = normalizeAST.nodes.filter( - (node) => node.type === 'rule' - ).filter( - (rule) => { - // filter declarations - rule.nodes = rule.nodes.filter( - (node) => node.type === 'decl' - ).map( - (decl) => { - // copy raw browserlist - decl.browserList = normalizeBrowserList[++normalizeBrowserListIndex]; - - // clear raws and input - delete decl.raws; - - decl.source.input = {}; - - return decl; - } - ); - - // clear raws and input - delete rule.raws; - - rule.source.input = {}; - - return rule; - } - ); - - // preserve sourcemap - normalizeAST.source.input = sourceInput; - - return normalizeAST; - } -).then( - // stringify json - (json) => JSON.stringify(json) -).then( - // write stringified json - (json) => fs.writeFile(pathToNormalizeJSON, json) -); diff --git a/lib/normalize-init.js b/lib/normalize-init.js new file mode 100644 index 0000000000..2a4828d56f --- /dev/null +++ b/lib/normalize-init.js @@ -0,0 +1,30 @@ +'use strict'; + +// tooling +const fs = require('fse'); +const path = require('path'); +const normalizeBrowserList = require('./normalize-browser-list.json'); + +// paths to normalize.css and normalize.json +const pathToNormalizeCSS = path.resolve(__dirname, 'normalize.css'); +const pathToNormalizeJSON = path.resolve(__dirname, 'normalize.json'); +const pathToNormalizeImport = path.resolve(path.dirname(__dirname), 'index.css'); + +Promise.resolve().then( + // parse normalize.css + () => fs.readFile(pathToNormalizeCSS, 'utf8').then( + (normalizeCSS) => fs.writeFile( + pathToNormalizeJSON, + JSON.stringify({ + browserList: normalizeBrowserList, + css: normalizeCSS.replace(/\r?\n|\r/g, '\n') + }), + 'utf8' + ) + ) +).then( + fs.writeFile( + pathToNormalizeImport, + '@import postcss-normalize' + ) +); diff --git a/lib/normalize.js b/lib/normalize.js new file mode 100644 index 0000000000..05dd46be50 --- /dev/null +++ b/lib/normalize.js @@ -0,0 +1,36 @@ +'use strict'; + +// tooling +const postcss = require('postcss'); +const normalize = require('./normalize.json'); + +let browserListIndex = -1; + +// return normalize.css with browserlist +module.exports = postcss.parse(normalize.css).nodes.filter( + (rule) => { + // filter nodes to keep only rules + if (rule.type === 'rule') { + // filter nodes to keep only declarations + rule.nodes = rule.nodes.filter( + (decl) => { + // if the node is a declaration + if (decl.type === 'decl') { + // copy browserList + decl.browserList = normalize.browserList[++browserListIndex]; + + // delete raws + delete decl.raws; + + return decl; + } + } + ); + + // delete raws + delete rule.raws; + + return rule; + } + } +); diff --git a/package.json b/package.json index b42c277f2f..b1ced646ef 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "postcss-normalize", - "version": "2.0.1", + "version": "2.1.0", "description": "Use the parts of normalize.css you need from your browserlist", "author": "Jonathan Neal ", "license": "CC0-1.0", @@ -9,16 +9,17 @@ "bugs": "https://github.com/jonathantneal/postcss-normalize/issues", "main": "index.js", "files": [ + "index.css", "index.js", - "lib/json-to-ast.js", + "lib/normalize.js", "lib/normalize.json" ], "scripts": { "clean": "git clean -X -d -f", "prepublish": "npm test", - "test": "echo 'Running tests...'; npm run test:setup && npm run test:js && npm run test:tape", + "test": "npm run test:init && npm run test:js && npm run test:tape", + "test:init": "node lib/normalize-init", "test:js": "eslint *.js --cache --ignore-pattern .gitignore", - "test:setup": "node lib/normalize-css-to-json", "test:tape": "postcss-tape" }, "engines": { diff --git a/test/insertion.css b/test/insertion.css new file mode 100644 index 0000000000..40db216d80 --- /dev/null +++ b/test/insertion.css @@ -0,0 +1,5 @@ +body { + font-family: sans-serif; +} + +@import postcss-normalize; diff --git a/test/insertion.expect.css b/test/insertion.expect.css new file mode 100644 index 0000000000..4f257e3db7 --- /dev/null +++ b/test/insertion.expect.css @@ -0,0 +1,183 @@ +body { + font-family: sans-serif; +} + +html { + line-height: 1.15; + -ms-text-size-adjust: 100%; + -webkit-text-size-adjust: 100%; +} + +h1 { + font-size: 2em; + margin: 0.67em 0; +} + +main { + display: block; +} + +hr { + box-sizing: content-box; + height: 0; + overflow: visible; +} + +pre { + font-family: monospace, monospace; + font-size: 1em; +} + +a { + background-color: transparent; + -webkit-text-decoration-skip: objects; +} + +abbr[title] { + border-bottom: none; + text-decoration: underline; + text-decoration: underline dotted; +} + +b, +strong { + font-weight: bolder; +} + +code, +kbd, +samp { + font-family: monospace, monospace; + font-size: 1em; +} + +small { + font-size: 80%; +} + +sub, +sup { + font-size: 75%; + line-height: 0; + position: relative; + vertical-align: baseline; +} + +sub { + bottom: -0.25em; +} + +sup { + top: -0.5em; +} + +img { + border-style: none; +} + +svg:not(:root) { + overflow: hidden; +} + +button, +input, +optgroup, +select, +textarea { + margin: 0; +} + +button, +input { + overflow: visible; +} + +button, +select { + text-transform: none; +} + +button, +[type="button"], +[type="reset"], +[type="submit"] { + -webkit-appearance: button; +} + +button::-moz-focus-inner, +[type="button"]::-moz-focus-inner, +[type="reset"]::-moz-focus-inner, +[type="submit"]::-moz-focus-inner { + border-style: none; + padding: 0; +} + +button:-moz-focusring, +[type="button"]:-moz-focusring, +[type="reset"]:-moz-focusring, +[type="submit"]:-moz-focusring { + outline: 1px dotted ButtonText; +} + +fieldset { + padding: 0.35em 0.75em 0.625em; +} + +legend { + box-sizing: border-box; + color: inherit; + display: table; + max-width: 100%; + padding: 0; + white-space: normal; +} + +progress { + vertical-align: baseline; +} + +textarea { + overflow: auto; +} + +[type="checkbox"], +[type="radio"] { + box-sizing: border-box; + padding: 0; +} + +[type="number"]::-webkit-inner-spin-button, +[type="number"]::-webkit-outer-spin-button { + height: auto; +} + +[type="search"] { + -webkit-appearance: textfield; + outline-offset: -2px; +} + +[type="search"]::-webkit-search-cancel-button, +[type="search"]::-webkit-search-decoration { + -webkit-appearance: none; +} + +::-webkit-file-upload-button { + -webkit-appearance: button; + font: inherit; +} + +details { + display: block; +} + +summary { + display: list-item; +} + +template { + display: none; +} + +[hidden] { + display: none; +} diff --git a/test/insertion.w-quotes.css b/test/insertion.w-quotes.css new file mode 100644 index 0000000000..437d81202c --- /dev/null +++ b/test/insertion.w-quotes.css @@ -0,0 +1,5 @@ +body { + font-family: sans-serif; +} + +@import "postcss-normalize"; From 4a636aa7bbd34d8ae6049a06acd990c13c41e299 Mon Sep 17 00:00:00 2001 From: Jonathan Neal Date: Sun, 28 May 2017 21:10:24 -0400 Subject: [PATCH 457/795] 3.0.0 --- .tape.js | 14 +- CHANGELOG.md | 6 + README.md | 34 ++-- index.js | 10 +- lib/normalize-browser-list.json | 31 ++-- lib/normalize-init.js | 7 - lib/normalize.css | 100 ++++------- package.json | 3 +- test/basic.expect.css | 33 ++-- test/basic.last-1.expect.css | 32 ++-- test/basic.last-2.expect.css | 33 ++-- ...rtion.w-quotes.css => insertion-after.css} | 2 +- test/insertion-after.expect.css | 170 ++++++++++++++++++ test/insertion-duplicate.css | 7 + test/insertion-duplicate.expect.css | 170 ++++++++++++++++++ test/insertion.css | 4 +- test/insertion.expect.css | 49 ++--- 17 files changed, 493 insertions(+), 212 deletions(-) rename test/{insertion.w-quotes.css => insertion-after.css} (55%) create mode 100644 test/insertion-after.expect.css create mode 100644 test/insertion-duplicate.css create mode 100644 test/insertion-duplicate.expect.css diff --git a/.tape.js b/.tape.js index 866dcdd26a..1e7612c0ec 100644 --- a/.tape.js +++ b/.tape.js @@ -4,23 +4,25 @@ module.exports = { message: 'supports basic usage' }, 'basic:last-2': { - message: 'supports { browsers: "last 2 versions" } usage', + message: 'supports { browsers: "last 2 versions" }', options: { browsers: 'last 2 versions' } }, 'basic:last-1': { - message: 'supports { browsers: "last 1 versions" } usage', + message: 'supports { browsers: "last 1 versions" }', options: { browsers: 'last 1 versions' } }, 'insertion': { - message: 'supports insertion usage' + message: 'supports an insertion point' }, - 'insertion:w-quotes': { - message: 'supports insertion with quotes usage', - expect: 'insertion.expect.css' + 'insertion-after': { + message: 'support an insertion point (at the end of the file)' + }, + 'insertion-duplicate': { + message: 'removes duplicate insertion points' } } }; diff --git a/CHANGELOG.md b/CHANGELOG.md index f0a0704bfb..1f49295bdc 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,11 @@ # Changes to PostCSS Normalize +### 3.0.0 (May 26, 2017) + +- Use jonathantneal/normalize.css v7 +- Change the insertion point to `@import-normalize` to avoid confusion or + collision with standard import behavior + ### 2.1.0 (May 26, 2017) - Support an insertion point via `@import postcss-normalize` diff --git a/README.md b/README.md index 3202b50de2..c99fb3b77d 100644 --- a/README.md +++ b/README.md @@ -5,8 +5,10 @@ [![Windows Build Status][win-img]][win-url] [![Gitter Chat][git-img]][git-url] -[PostCSS Normalize] lets you automatically include the parts of [normalize.css] -you need, based upon your project’s [browserlist]. +[PostCSS Normalize] lets you use the parts of [normalize.css] you need, based +on your project’s [browserlist]. + +Example: ```css /* { "browserlist": ["last 3 versions"] } */ @@ -15,13 +17,9 @@ you need, based upon your project’s [browserlist]. * Add the correct display in IE 9-. */ -article, -aside, -footer, -header, -nav, -section { - display: block; +audio, +video { + display: inline-block; } /** @@ -45,15 +43,21 @@ img { } ``` -[PostCSS Normalize] will put itself at the beginning of your CSS file. You -may also dictate where it should be included: +[PostCSS Normalize] will put itself at the beginning of your CSS file, unless +you dictate where it should be included: ```css -@import "postcss-normalize"; +@import-normalize; ``` -This technique is compatible with [PostCSS Import] and -[PostCSS Partial Import], regardless if they run first. +Duplicate `@import-normalize` rules will be removed for your convenience. Only +the first instance will be replaced. + +--- + +[PostCSS Normalize] uses the non-opinionated version of [normalize.css]. + +--- ## Usage @@ -162,5 +166,3 @@ grunt.initConfig({ [browserlist]: http://browserl.ist/ [normalize.css]: https://github.com/jonathantneal/normalize.css -[PostCSS Import]: https://github.com/postcss/postcss-import -[PostCSS Partial Import]: https://github.com/jonathantneal/postcss-partial-import diff --git a/index.js b/index.js index b032007bc0..02e2cc182f 100644 --- a/index.js +++ b/index.js @@ -33,11 +33,15 @@ module.exports = postcss.plugin('postcss-normalize', (opts) => { (rule) => rule.nodes.length ); - // check for an @import postcss-normalize insertion point + // use @import postcss-normalize insertion point root.walkAtRules( - 'import', + 'import-normalize', (atrule) => { - if (atrule.params === 'postcss-normalize') { + if (appliedRules[0].parent) { + // remove duplicate insertions + atrule.remove(); + } else { + // use the first insertion point atrule.replaceWith(appliedRules); } } diff --git a/lib/normalize-browser-list.json b/lib/normalize-browser-list.json index 97e739fe7b..eab4a148fd 100644 --- a/lib/normalize-browser-list.json +++ b/lib/normalize-browser-list.json @@ -2,35 +2,29 @@ ["> 0%"], ["ie > 0"], ["ios > 0"], - ["ie <= 9"], + ["ie <= 8"], ["chrome > 0", "ff > 0", "safari > 0"], ["chrome > 0", "ff > 0", "safari > 0"], - ["ie <= 9"], - ["ie > 0"], + ["ie <= 8"], ["ie <= 8"], ["ff > 0"], ["ff > 0"], ["edge > 0", "ie > 0"], + ["ie > 0"], ["> 0%"], ["> 0%"], ["ie <= 10"], ["ios > 0", "safari > 0"], - ["chrome <= 57", "ff <= 39"], - ["chrome > 0", "edge > 0", "ie > 0", "opera > 0", "safari > 0"], - ["chrome > 0", "edge > 0", "ie > 0", "opera > 0", "safari > 0"], + ["ff <= 39"], + ["chrome <= 58", "edge > 0", "ie > 0", "opera > 0", "safari > 0"], + ["chrome <= 58", "edge > 0", "ie > 0", "opera > 0", "safari > 0"], ["safari <= 6"], ["chrome > 0", "edge > 0", "safari > 0"], ["> 0%"], ["> 0%"], ["android <= 4.3"], - ["ie <= 9"], - ["ie <= 9"], - ["> 0%"], - ["> 0%"], - ["> 0%"], - ["> 0%"], - ["> 0%"], - ["> 0%"], + ["ie <= 8"], + ["ie <= 8"], ["> 0%"], ["ie <= 9"], ["ios <= 7"], @@ -38,7 +32,7 @@ ["ie <= 10"], ["ie > 0"], ["ff > 0", "safari > 0"], - ["edge > 0", "ie > 0"], + ["ie > 0"], ["edge > 0", "ff > 0", "ie > 0"], ["ios > 0", "safari > 0"], ["android <= 4"], @@ -48,12 +42,14 @@ ["ff > 0"], ["edge > 0", "ie > 0"], ["edge > 0", "ie > 0"], + ["ie > 0"], ["edge > 0", "ie > 0"], ["edge > 0", "ie > 0"], + ["> 0%"], ["edge > 0", "ie > 0"], ["edge > 0", "ie > 0"], - ["ie <= 9"], ["chrome > 0", "ff > 0", "opera > 0"], + ["firefox > 0"], ["ie > 0"], ["ie <= 10"], ["ie <= 10"], @@ -63,8 +59,7 @@ ["chrome > 0", "safari > 0"], ["ios > 0", "safari > 0"], ["safari > 0"], - ["edge > 0", "ie > 0", "ff > 0"], - ["ie <= 9"], + ["edge > 0", "ff <= 48", "ie > 0"], ["> 0%"], ["ie <= 9"], ["ie > 0"], diff --git a/lib/normalize-init.js b/lib/normalize-init.js index 2a4828d56f..f6454d2a3e 100644 --- a/lib/normalize-init.js +++ b/lib/normalize-init.js @@ -1,5 +1,3 @@ -'use strict'; - // tooling const fs = require('fse'); const path = require('path'); @@ -22,9 +20,4 @@ Promise.resolve().then( 'utf8' ) ) -).then( - fs.writeFile( - pathToNormalizeImport, - '@import postcss-normalize' - ) ); diff --git a/lib/normalize.css b/lib/normalize.css index 0e1d3e6164..33efd60ade 100644 --- a/lib/normalize.css +++ b/lib/normalize.css @@ -1,4 +1,4 @@ -/*! normalize.css v6.0.0 | MIT License | github.com/jonathantneal/normalize.css */ +/*! normalize.css v7.0.0 | MIT License | github.com/jonathantneal/normalize.css */ /* Document ========================================================================== */ @@ -19,7 +19,7 @@ html { ========================================================================== */ /** - * Add the correct display in IE 9-. + * Add the correct display in IE 8-. */ article, @@ -45,7 +45,7 @@ h1 { ========================================================================== */ /** - * Add the correct display in IE 9-. + * Add the correct display in IE 8-. */ figcaption, @@ -54,15 +54,7 @@ figure { } /** - * Add the correct display in IE. - */ - -main { - display: block; -} - -/** - * Add the correct margin in IE 8. + * Add the correct margin in IE 8-. */ figure { @@ -80,6 +72,14 @@ hr { overflow: visible; /* 2 */ } +/** + * Add the correct display in IE. + */ + +main { + display: block; +} + /** * 1. Correct the inheritance and scaling of font size in all browsers. * 2. Correct the odd `em` font sizing in all browsers. @@ -104,8 +104,9 @@ a { } /** - * 1. Remove the bottom border in Chrome 57- and Firefox 39-. - * 2. Add the correct text decoration in Chrome, Edge, IE, Opera, and Safari. + * 1. Remove the bottom border in Firefox 39-. + * 2. Add the correct text decoration in Chrome 57-, Edge, IE, Opera, + and Safari. */ abbr[title] { @@ -153,7 +154,7 @@ dfn { } /** - * Add the correct background and color in IE 9-. + * Add the correct background and color in IE 8-. */ mark { @@ -169,27 +170,6 @@ small { font-size: 80%; } -/** - * Prevent `sub` and `sup` elements from affecting the line height in - * all browsers. - */ - -sub, -sup { - font-size: 75%; - line-height: 0; - position: relative; - vertical-align: baseline; -} - -sub { - bottom: -0.25em; -} - -sup { - top: -0.5em; -} - /* Embedded content ========================================================================== */ @@ -243,23 +223,13 @@ textarea { } /** - * Show the overflow in IE. - * 1. Show the overflow in Edge. + * 1. Show the overflow in IE. + * 2. Remove the inheritance of text transform in Edge, Firefox, and IE. */ -button, -input { /* 1 */ - overflow: visible; -} - -/** - * Remove the inheritance of text transform in Edge, Firefox, and IE. - * 1. Remove the inheritance of text transform in Firefox. - */ - -button, -select { /* 1 */ - text-transform: none; +button { + overflow: visible; /* 1 */ + text-transform: none; /* 2 */ } /** @@ -313,6 +283,14 @@ fieldset { padding: 0.35em 0.75em 0.625em; } +/** + * Show the overflow in Edge and IE. + */ + +input { + overflow: visible; +} + /** * 1. Correct the text wrapping in Edge and IE. * 2. Correct the color inheritance from `fieldset` elements in IE. @@ -330,7 +308,7 @@ legend { } /** - * 1. Add the correct display in IE 9-. + * 1. Add the correct display in Edge and IE. * 2. Add the correct vertical alignment in Chrome, Firefox, and Opera. */ @@ -339,6 +317,14 @@ progress { vertical-align: baseline; /* 2 */ } +/** + * Remove the inheritance of text transform in Firefox. + */ + +select { + text-transform: none; +} + /** * Remove the default vertical scrollbar in IE. */ @@ -400,21 +386,13 @@ textarea { ========================================================================== */ /* - * Add the correct display in Edge, IE, and Firefox. + * Add the correct display in Edge, Firefox 48-, and IE. */ details { display: block; } -/* - * Add the correct display in IE 9-. - */ - -menu { - display: block; -} - /* * Add the correct display in all browsers. */ diff --git a/package.json b/package.json index b1ced646ef..444996f7a2 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "postcss-normalize", - "version": "2.1.0", + "version": "3.0.0", "description": "Use the parts of normalize.css you need from your browserlist", "author": "Jonathan Neal ", "license": "CC0-1.0", @@ -9,7 +9,6 @@ "bugs": "https://github.com/jonathantneal/postcss-normalize/issues", "main": "index.js", "files": [ - "index.css", "index.js", "lib/normalize.js", "lib/normalize.json" diff --git a/test/basic.expect.css b/test/basic.expect.css index 737218fd34..4d3f333648 100644 --- a/test/basic.expect.css +++ b/test/basic.expect.css @@ -7,14 +7,14 @@ h1 { font-size: 2em; margin: 0.67em 0; } -main { - display: block; -} hr { box-sizing: content-box; height: 0; overflow: visible; } +main { + display: block; +} pre { font-family: monospace, monospace; font-size: 1em; @@ -24,7 +24,6 @@ a { -webkit-text-decoration-skip: objects; } abbr[title] { - border-bottom: none; text-decoration: underline; text-decoration: underline dotted; } @@ -41,19 +40,6 @@ samp { small { font-size: 80%; } -sub, -sup { - font-size: 75%; - line-height: 0; - position: relative; - vertical-align: baseline; -} -sub { - bottom: -0.25em; -} -sup { - top: -0.5em; -} img { border-style: none; } @@ -67,12 +53,8 @@ select, textarea { margin: 0; } -button, -input { +button { overflow: visible; -} -button, -select { text-transform: none; } button, @@ -97,6 +79,9 @@ button:-moz-focusring, fieldset { padding: 0.35em 0.75em 0.625em; } +input { + overflow: visible; +} legend { box-sizing: border-box; color: inherit; @@ -106,8 +91,12 @@ legend { white-space: normal; } progress { + display: inline-block; vertical-align: baseline; } +select { + text-transform: none; +} textarea { overflow: auto; } diff --git a/test/basic.last-1.expect.css b/test/basic.last-1.expect.css index 8347a18bc3..03c7093e75 100644 --- a/test/basic.last-1.expect.css +++ b/test/basic.last-1.expect.css @@ -7,14 +7,14 @@ h1 { font-size: 2em; margin: 0.67em 0; } -main { - display: block; -} hr { box-sizing: content-box; height: 0; overflow: visible; } +main { + display: block; +} pre { font-family: monospace, monospace; font-size: 1em; @@ -39,19 +39,6 @@ samp { small { font-size: 80%; } -sub, -sup { - font-size: 75%; - line-height: 0; - position: relative; - vertical-align: baseline; -} -sub { - bottom: -0.25em; -} -sup { - top: -0.5em; -} svg:not(:root) { overflow: hidden; } @@ -62,12 +49,8 @@ select, textarea { margin: 0; } -button, -input { +button { overflow: visible; -} -button, -select { text-transform: none; } button, @@ -92,6 +75,9 @@ button:-moz-focusring, fieldset { padding: 0.35em 0.75em 0.625em; } +input { + overflow: visible; +} legend { box-sizing: border-box; color: inherit; @@ -101,8 +87,12 @@ legend { white-space: normal; } progress { + display: inline-block; vertical-align: baseline; } +select { + text-transform: none; +} textarea { overflow: auto; } diff --git a/test/basic.last-2.expect.css b/test/basic.last-2.expect.css index 737218fd34..4d3f333648 100644 --- a/test/basic.last-2.expect.css +++ b/test/basic.last-2.expect.css @@ -7,14 +7,14 @@ h1 { font-size: 2em; margin: 0.67em 0; } -main { - display: block; -} hr { box-sizing: content-box; height: 0; overflow: visible; } +main { + display: block; +} pre { font-family: monospace, monospace; font-size: 1em; @@ -24,7 +24,6 @@ a { -webkit-text-decoration-skip: objects; } abbr[title] { - border-bottom: none; text-decoration: underline; text-decoration: underline dotted; } @@ -41,19 +40,6 @@ samp { small { font-size: 80%; } -sub, -sup { - font-size: 75%; - line-height: 0; - position: relative; - vertical-align: baseline; -} -sub { - bottom: -0.25em; -} -sup { - top: -0.5em; -} img { border-style: none; } @@ -67,12 +53,8 @@ select, textarea { margin: 0; } -button, -input { +button { overflow: visible; -} -button, -select { text-transform: none; } button, @@ -97,6 +79,9 @@ button:-moz-focusring, fieldset { padding: 0.35em 0.75em 0.625em; } +input { + overflow: visible; +} legend { box-sizing: border-box; color: inherit; @@ -106,8 +91,12 @@ legend { white-space: normal; } progress { + display: inline-block; vertical-align: baseline; } +select { + text-transform: none; +} textarea { overflow: auto; } diff --git a/test/insertion.w-quotes.css b/test/insertion-after.css similarity index 55% rename from test/insertion.w-quotes.css rename to test/insertion-after.css index 437d81202c..a79411112a 100644 --- a/test/insertion.w-quotes.css +++ b/test/insertion-after.css @@ -2,4 +2,4 @@ body { font-family: sans-serif; } -@import "postcss-normalize"; +@import-normalize; diff --git a/test/insertion-after.expect.css b/test/insertion-after.expect.css new file mode 100644 index 0000000000..8e1a6f289d --- /dev/null +++ b/test/insertion-after.expect.css @@ -0,0 +1,170 @@ +body { + font-family: sans-serif; +} + +html { + line-height: 1.15; + -ms-text-size-adjust: 100%; + -webkit-text-size-adjust: 100%; +} + +h1 { + font-size: 2em; + margin: 0.67em 0; +} + +hr { + box-sizing: content-box; + height: 0; + overflow: visible; +} + +main { + display: block; +} + +pre { + font-family: monospace, monospace; + font-size: 1em; +} + +a { + background-color: transparent; + -webkit-text-decoration-skip: objects; +} + +abbr[title] { + text-decoration: underline; + text-decoration: underline dotted; +} + +b, +strong { + font-weight: bolder; +} + +code, +kbd, +samp { + font-family: monospace, monospace; + font-size: 1em; +} + +small { + font-size: 80%; +} + +img { + border-style: none; +} + +svg:not(:root) { + overflow: hidden; +} + +button, +input, +optgroup, +select, +textarea { + margin: 0; +} + +button { + overflow: visible; + text-transform: none; +} + +button, +[type="button"], +[type="reset"], +[type="submit"] { + -webkit-appearance: button; +} + +button::-moz-focus-inner, +[type="button"]::-moz-focus-inner, +[type="reset"]::-moz-focus-inner, +[type="submit"]::-moz-focus-inner { + border-style: none; + padding: 0; +} + +button:-moz-focusring, +[type="button"]:-moz-focusring, +[type="reset"]:-moz-focusring, +[type="submit"]:-moz-focusring { + outline: 1px dotted ButtonText; +} + +fieldset { + padding: 0.35em 0.75em 0.625em; +} + +input { + overflow: visible; +} + +legend { + box-sizing: border-box; + color: inherit; + display: table; + max-width: 100%; + padding: 0; + white-space: normal; +} + +progress { + display: inline-block; + vertical-align: baseline; +} + +select { + text-transform: none; +} + +textarea { + overflow: auto; +} + +[type="checkbox"], +[type="radio"] { + box-sizing: border-box; + padding: 0; +} + +[type="number"]::-webkit-inner-spin-button, +[type="number"]::-webkit-outer-spin-button { + height: auto; +} + +[type="search"] { + -webkit-appearance: textfield; + outline-offset: -2px; +} + +[type="search"]::-webkit-search-cancel-button, +[type="search"]::-webkit-search-decoration { + -webkit-appearance: none; +} + +::-webkit-file-upload-button { + -webkit-appearance: button; + font: inherit; +} + +details { + display: block; +} + +summary { + display: list-item; +} + +template { + display: none; +} + +[hidden] { + display: none; +} diff --git a/test/insertion-duplicate.css b/test/insertion-duplicate.css new file mode 100644 index 0000000000..f146028f6f --- /dev/null +++ b/test/insertion-duplicate.css @@ -0,0 +1,7 @@ +@import-normalize; + +body { + font-family: sans-serif; +} + +@import-normalize; diff --git a/test/insertion-duplicate.expect.css b/test/insertion-duplicate.expect.css new file mode 100644 index 0000000000..6ef7a7ce2b --- /dev/null +++ b/test/insertion-duplicate.expect.css @@ -0,0 +1,170 @@ +html { + line-height: 1.15; + -ms-text-size-adjust: 100%; + -webkit-text-size-adjust: 100%; +} + +h1 { + font-size: 2em; + margin: 0.67em 0; +} + +hr { + box-sizing: content-box; + height: 0; + overflow: visible; +} + +main { + display: block; +} + +pre { + font-family: monospace, monospace; + font-size: 1em; +} + +a { + background-color: transparent; + -webkit-text-decoration-skip: objects; +} + +abbr[title] { + text-decoration: underline; + text-decoration: underline dotted; +} + +b, +strong { + font-weight: bolder; +} + +code, +kbd, +samp { + font-family: monospace, monospace; + font-size: 1em; +} + +small { + font-size: 80%; +} + +img { + border-style: none; +} + +svg:not(:root) { + overflow: hidden; +} + +button, +input, +optgroup, +select, +textarea { + margin: 0; +} + +button { + overflow: visible; + text-transform: none; +} + +button, +[type="button"], +[type="reset"], +[type="submit"] { + -webkit-appearance: button; +} + +button::-moz-focus-inner, +[type="button"]::-moz-focus-inner, +[type="reset"]::-moz-focus-inner, +[type="submit"]::-moz-focus-inner { + border-style: none; + padding: 0; +} + +button:-moz-focusring, +[type="button"]:-moz-focusring, +[type="reset"]:-moz-focusring, +[type="submit"]:-moz-focusring { + outline: 1px dotted ButtonText; +} + +fieldset { + padding: 0.35em 0.75em 0.625em; +} + +input { + overflow: visible; +} + +legend { + box-sizing: border-box; + color: inherit; + display: table; + max-width: 100%; + padding: 0; + white-space: normal; +} + +progress { + display: inline-block; + vertical-align: baseline; +} + +select { + text-transform: none; +} + +textarea { + overflow: auto; +} + +[type="checkbox"], +[type="radio"] { + box-sizing: border-box; + padding: 0; +} + +[type="number"]::-webkit-inner-spin-button, +[type="number"]::-webkit-outer-spin-button { + height: auto; +} + +[type="search"] { + -webkit-appearance: textfield; + outline-offset: -2px; +} + +[type="search"]::-webkit-search-cancel-button, +[type="search"]::-webkit-search-decoration { + -webkit-appearance: none; +} + +::-webkit-file-upload-button { + -webkit-appearance: button; + font: inherit; +} + +details { + display: block; +} + +summary { + display: list-item; +} + +template { + display: none; +} + +[hidden] { + display: none; +} + +body { + font-family: sans-serif; +} diff --git a/test/insertion.css b/test/insertion.css index 40db216d80..28b15407a5 100644 --- a/test/insertion.css +++ b/test/insertion.css @@ -1,5 +1,5 @@ +@import-normalize; + body { font-family: sans-serif; } - -@import postcss-normalize; diff --git a/test/insertion.expect.css b/test/insertion.expect.css index 4f257e3db7..6ef7a7ce2b 100644 --- a/test/insertion.expect.css +++ b/test/insertion.expect.css @@ -1,7 +1,3 @@ -body { - font-family: sans-serif; -} - html { line-height: 1.15; -ms-text-size-adjust: 100%; @@ -13,16 +9,16 @@ h1 { margin: 0.67em 0; } -main { - display: block; -} - hr { box-sizing: content-box; height: 0; overflow: visible; } +main { + display: block; +} + pre { font-family: monospace, monospace; font-size: 1em; @@ -34,7 +30,6 @@ a { } abbr[title] { - border-bottom: none; text-decoration: underline; text-decoration: underline dotted; } @@ -55,22 +50,6 @@ small { font-size: 80%; } -sub, -sup { - font-size: 75%; - line-height: 0; - position: relative; - vertical-align: baseline; -} - -sub { - bottom: -0.25em; -} - -sup { - top: -0.5em; -} - img { border-style: none; } @@ -87,13 +66,8 @@ textarea { margin: 0; } -button, -input { +button { overflow: visible; -} - -button, -select { text-transform: none; } @@ -123,6 +97,10 @@ fieldset { padding: 0.35em 0.75em 0.625em; } +input { + overflow: visible; +} + legend { box-sizing: border-box; color: inherit; @@ -133,9 +111,14 @@ legend { } progress { + display: inline-block; vertical-align: baseline; } +select { + text-transform: none; +} + textarea { overflow: auto; } @@ -181,3 +164,7 @@ template { [hidden] { display: none; } + +body { + font-family: sans-serif; +} From ff2c97e09abc2422c061bf08c9093df56fbbe55d Mon Sep 17 00:00:00 2001 From: Jonathan Neal Date: Tue, 30 May 2017 16:54:03 -0400 Subject: [PATCH 458/795] 1.0.0 --- .appveyor.yml | 18 +++++++ .editorconfig | 15 ++++++ .gitignore | 9 ++++ .tape.js | 7 +++ .travis.yml | 9 ++++ CHANGELOG.md | 5 ++ CONTRIBUTING.md | 65 +++++++++++++++++++++++ LICENSE.md | 106 +++++++++++++++++++++++++++++++++++++ README.md | 120 ++++++++++++++++++++++++++++++++++++++++++ index.js | 52 ++++++++++++++++++ package.json | 47 +++++++++++++++++ test/basic.css | 27 ++++++++++ test/basic.expect.css | 27 ++++++++++ 13 files changed, 507 insertions(+) create mode 100644 .appveyor.yml create mode 100644 .editorconfig create mode 100644 .gitignore create mode 100644 .tape.js create mode 100644 .travis.yml create mode 100644 CHANGELOG.md create mode 100644 CONTRIBUTING.md create mode 100644 LICENSE.md create mode 100644 README.md create mode 100644 index.js create mode 100644 package.json create mode 100644 test/basic.css create mode 100644 test/basic.expect.css diff --git a/.appveyor.yml b/.appveyor.yml new file mode 100644 index 0000000000..d6b511f500 --- /dev/null +++ b/.appveyor.yml @@ -0,0 +1,18 @@ +# https://www.appveyor.com/docs/appveyor-yml + +environment: + matrix: + - nodejs_version: 4.0 + +version: "{build}" +build: off +deploy: off + +install: + - ps: Install-Product node $env:nodejs_version + - npm install --ignore-scripts + +test_script: + - node --version + - npm --version + - cmd: "npm test" diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000000..e06d7982bc --- /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/.gitignore b/.gitignore new file mode 100644 index 0000000000..f8952c957f --- /dev/null +++ b/.gitignore @@ -0,0 +1,9 @@ +node_modules +.* +!.appveyor.yml +!.editorconfig +!.gitignore +!.tape.js +!.travis.yml +*.log* +*.result.css diff --git a/.tape.js b/.tape.js new file mode 100644 index 0000000000..f1e2881271 --- /dev/null +++ b/.tape.js @@ -0,0 +1,7 @@ +module.exports = { + 'postcss-dir-pseudo-class': { + 'basic': { + message: 'supports basic usage' + } + } +}; diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000000..c56466446c --- /dev/null +++ b/.travis.yml @@ -0,0 +1,9 @@ +# https://docs.travis-ci.com/user/travis-lint + +language: node_js + +node_js: + - 4 + +install: + - npm install --ignore-scripts diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000000..8031dac314 --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,5 @@ +# Changes to PostCSS :dir() + +### 1.0.0 (May 30, 2017) + +- Initial version diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 0000000000..f58b57fa7d --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,65 @@ +# Contributing to PostCSS :dir() + +You want to help? You rock! Now, take a moment to be sure your contributions +make sense to everyone else. + +## Reporting Issues + +Found a problem? Want a new feature? + +- See if your issue or idea has [already been reported]. +- Provide a [reduced test case] or a [live example]. + +Remember, a bug is a _demonstrable problem_ caused by _our_ code. + +## Submitting Pull Requests + +Pull requests are the greatest contributions, so be sure they are focused in +scope and avoid unrelated commits. + +1. To begin; [fork this project], clone your fork, and add our upstream. + ```bash + # Clone your fork of the repo into the current directory + git clone git@github.com:YOUR_USER/postcss-dir-pseudo-class.git + + # Navigate to the newly cloned directory + cd postcss-dir-pseudo-class + + # Assign the original repo to a remote called "upstream" + git remote add upstream git@github.com:jonathantneal/postcss-dir-pseudo-class.git + + # Install the tools necessary for testing + npm install + ``` + +2. Create a branch for your feature or fix: + ```bash + # Move into a new branch for your feature + git checkout -b feature/thing + ``` + ```bash + # Move into a new branch for your fix + git checkout -b fix/something + ``` + +3. If your code follows our practices, then push your feature branch: + ```bash + # Test current code + npm test + ``` + ```bash + # Push the branch for your new feature + git push origin feature/thing + ``` + ```bash + # Or, push the branch for your update + git push origin update/something + ``` + +That’s it! Now [open a pull request] with a clear title and description. + +[already been reported]: issues +[fork this project]: fork +[live example]: https://codepen.io/pen +[open a pull request]: https://help.github.com/articles/using-pull-requests/ +[reduced test case]: https://css-tricks.com/reduced-test-cases/ diff --git a/LICENSE.md b/LICENSE.md new file mode 100644 index 0000000000..b5bc55c9f6 --- /dev/null +++ b/LICENSE.md @@ -0,0 +1,106 @@ +# CC0 1.0 Universal + +## Statement of Purpose + +The laws of most jurisdictions throughout the world automatically confer +exclusive Copyright and Related Rights (defined below) upon the creator and +subsequent owner(s) (each and all, an “owner”) of an original work of +authorship and/or a database (each, a “Work”). + +Certain owners wish to permanently relinquish those rights to a Work for the +purpose of contributing to a commons of creative, cultural and scientific works +(“Commons”) that the public can reliably and without fear of later claims of +infringement build upon, modify, incorporate in other works, reuse and +redistribute as freely as possible in any form whatsoever and for any purposes, +including without limitation commercial purposes. These owners may contribute +to the Commons to promote the ideal of a free culture and the further +production of creative, cultural and scientific works, or to gain reputation or +greater distribution for their Work in part through the use and efforts of +others. + +For these and/or other purposes and motivations, and without any expectation of +additional consideration or compensation, the person associating CC0 with a +Work (the “Affirmer”), to the extent that he or she is an owner of Copyright +and Related Rights in the Work, voluntarily elects to apply CC0 to the Work and +publicly distribute the Work under its terms, with knowledge of his or her +Copyright and Related Rights in the Work and the meaning and intended legal +effect of CC0 on those rights. + +1. Copyright and Related Rights. A Work made available under CC0 may be + protected by copyright and related or neighboring rights (“Copyright and + Related Rights”). Copyright and Related Rights include, but are not limited + to, the following: + 1. the right to reproduce, adapt, distribute, perform, display, + communicate, and translate a Work; + 2. moral rights retained by the original author(s) and/or performer(s); + 3. publicity and privacy rights pertaining to a person’s image or likeness + depicted in a Work; + 4. rights protecting against unfair competition in regards to a Work, + subject to the limitations in paragraph 4(i), below; + 5. rights protecting the extraction, dissemination, use and reuse of data + in a Work; + 6. database rights (such as those arising under Directive 96/9/EC of the + European Parliament and of the Council of 11 March 1996 on the legal + protection of databases, and under any national implementation thereof, + including any amended or successor version of such directive); and + 7. other similar, equivalent or corresponding rights throughout the world + based on applicable law or treaty, and any national implementations + thereof. + +2. Waiver. To the greatest extent permitted by, but not in contravention of, +applicable law, Affirmer hereby overtly, fully, permanently, irrevocably and +unconditionally waives, abandons, and surrenders all of Affirmer’s Copyright +and Related Rights and associated claims and causes of action, whether now +known or unknown (including existing as well as future claims and causes of +action), in the Work (i) in all territories worldwide, (ii) for the maximum +duration provided by applicable law or treaty (including future time +extensions), (iii) in any current or future medium and for any number of +copies, and (iv) for any purpose whatsoever, including without limitation +commercial, advertising or promotional purposes (the “Waiver”). Affirmer makes +the Waiver for the benefit of each member of the public at large and to the +detriment of Affirmer’s heirs and successors, fully intending that such Waiver +shall not be subject to revocation, rescission, cancellation, termination, or +any other legal or equitable action to disrupt the quiet enjoyment of the Work +by the public as contemplated by Affirmer’s express Statement of Purpose. + +3. Public License Fallback. Should any part of the Waiver for any reason be +judged legally invalid or ineffective under applicable law, then the Waiver +shall be preserved to the maximum extent permitted taking into account +Affirmer’s express Statement of Purpose. In addition, to the extent the Waiver +is so judged Affirmer hereby grants to each affected person a royalty-free, non +transferable, non sublicensable, non exclusive, irrevocable and unconditional +license to exercise Affirmer’s Copyright and Related Rights in the Work (i) in +all territories worldwide, (ii) for the maximum duration provided by applicable +law or treaty (including future time extensions), (iii) in any current or +future medium and for any number of copies, and (iv) for any purpose +whatsoever, including without limitation commercial, advertising or promotional +purposes (the “License”). The License shall be deemed effective as of the date +CC0 was applied by Affirmer to the Work. Should any part of the License for any +reason be judged legally invalid or ineffective under applicable law, such +partial invalidity or ineffectiveness shall not invalidate the remainder of the +License, and in such case Affirmer hereby affirms that he or she will not (i) +exercise any of his or her remaining Copyright and Related Rights in the Work +or (ii) assert any associated claims and causes of action with respect to the +Work, in either case contrary to Affirmer’s express Statement of Purpose. + +4. Limitations and Disclaimers. + 1. No trademark or patent rights held by Affirmer are waived, abandoned, + surrendered, licensed or otherwise affected by this document. + 2. Affirmer offers the Work as-is and makes no representations or + warranties of any kind concerning the Work, express, implied, statutory + or otherwise, including without limitation warranties of title, + merchantability, fitness for a particular purpose, non infringement, or + the absence of latent or other defects, accuracy, or the present or + absence of errors, whether or not discoverable, all to the greatest + extent permissible under applicable law. + 3. Affirmer disclaims responsibility for clearing rights of other persons + that may apply to the Work or any use thereof, including without + limitation any person’s Copyright and Related Rights in the Work. + Further, Affirmer disclaims responsibility for obtaining any necessary + consents, permissions or other rights required for any use of the Work. + 4. Affirmer understands and acknowledges that Creative Commons is not a + party to this document and has no duty or obligation with respect to + this CC0 or use of the Work. + +For more information, please see +https://creativecommons.org/publicdomain/zero/1.0/. diff --git a/README.md b/README.md new file mode 100644 index 0000000000..87a6efcfe2 --- /dev/null +++ b/README.md @@ -0,0 +1,120 @@ +# PostCSS :dir() [PostCSS Logo][postcss] + +[![NPM Version][npm-img]][npm-url] +[![Linux Build Status][cli-img]][cli-url] +[![Windows Build Status][win-img]][win-url] +[![Gitter Chat][git-img]][git-url] + +[PostCSS :dir()] lets you use the `:dir` pseudo-class in CSS. + +```css +.example:dir(ltr) { + margin-left: 10px; +} + +/* becomes */ + +[dir="ltr"] .example { + margin-left: 10px; +} +``` + +Selector weight remains the same, but this requires you to specify a direction +(`dir`) attribute in your HTML. + +## Usage + +Add [PostCSS :dir()] to your build tool: + +```bash +npm install postcss-dir-pseudo-class --save-dev +``` + +#### Node + +Use [PostCSS :dir()] to process your CSS: + +```js +require('postcss-dir-pseudo-class').process(YOUR_CSS); +``` + +#### PostCSS + +Add [PostCSS] to your build tool: + +```bash +npm install postcss --save-dev +``` + +Use [PostCSS :dir()] as a plugin: + +```js +postcss([ + require('postcss-dir-pseudo-class')() +]).process(YOUR_CSS); +``` + +#### Gulp + +Add [Gulp PostCSS] to your build tool: + +```bash +npm install gulp-postcss --save-dev +``` + +Use [PostCSS :dir()] in your Gulpfile: + +```js +var postcss = require('gulp-postcss'); + +gulp.task('css', function () { + return gulp.src('./src/*.css').pipe( + postcss([ + require('postcss-dir-pseudo-class')() + ]) + ).pipe( + gulp.dest('.') + ); +}); +``` + +#### Grunt + +Add [Grunt PostCSS] to your build tool: + +```bash +npm install grunt-postcss --save-dev +``` + +Use [PostCSS :dir()] in your Gruntfile: + +```js +grunt.loadNpmTasks('grunt-postcss'); + +grunt.initConfig({ + postcss: { + options: { + use: [ + require('postcss-dir-pseudo-class')() + ] + }, + dist: { + src: '*.css' + } + } +}); +``` + +[npm-url]: https://www.npmjs.com/package/postcss-dir-pseudo-class +[npm-img]: https://img.shields.io/npm/v/postcss-dir-pseudo-class.svg +[cli-url]: https://travis-ci.org/jonathantneal/postcss-dir-pseudo-class +[cli-img]: https://img.shields.io/travis/jonathantneal/postcss-dir-pseudo-class.svg +[win-url]: https://ci.appveyor.com/project/jonathantneal/postcss-dir-pseudo-class +[win-img]: https://img.shields.io/appveyor/ci/jonathantneal/postcss-dir-pseudo-class.svg +[git-url]: https://gitter.im/postcss/postcss +[git-img]: https://img.shields.io/badge/chat-gitter-blue.svg + +[PostCSS :dir()]: https://github.com/jonathantneal/postcss-dir-pseudo-class +[PostCSS]: https://github.com/postcss/postcss +[Gulp PostCSS]: https://github.com/postcss/gulp-postcss +[Grunt PostCSS]: https://github.com/nDmitry/grunt-postcss diff --git a/index.js b/index.js new file mode 100644 index 0000000000..9de45abb85 --- /dev/null +++ b/index.js @@ -0,0 +1,52 @@ +// tooling +const postcss = require('postcss'); +const selectorParser = require('postcss-selector-parser'); + +// plugin +module.exports = postcss.plugin('postcss-dir-pseudo-class', () => (root) => { + root.walkRules(/:dir\([^\)]*\)/, (rule) => { + rule.selector = selectorParser((selectors) => { + selectors.nodes.forEach( + (selector) => { + selector.walk((node) => { + // ... + if ('pseudo' === node.type && ':dir' === node.value) { + const prev = node.prev(); + const prevIsSpaceCombinator = prev && prev.type && 'combinator' === prev.type && ' ' === prev.value; + + const next = node.next(); + const nextIsSpaceCombinator = next && next.type && 'combinator' === next.type && ' ' === next.value; + + if (prevIsSpaceCombinator && (nextIsSpaceCombinator || !next)) { + node.replaceWith( + selectorParser.universal() + ); + } else { + node.remove(); + } + + const first = selector.nodes[0]; + const firstIsSpaceCombinator = first && 'combinator' === first.type && ' ' === first.value; + + if (first && !firstIsSpaceCombinator) { + selector.prepend( + selectorParser.combinator({ + value: ' ' + }) + ); + } + + selector.prepend( + selectorParser.attribute({ + attribute: 'dir', + operator: '=', + value: `"${ node.nodes.toString() }"` + }) + ); + } + }); + } + ); + }).process(rule.selector).result; + }); +}); diff --git a/package.json b/package.json new file mode 100644 index 0000000000..99348f4fc9 --- /dev/null +++ b/package.json @@ -0,0 +1,47 @@ +{ + "name": "postcss-dir-pseudo-class", + "version": "1.0.0", + "description": "Use the :dir pseudo-class in CSS", + "author": "Jonathan Neal ", + "license": "CC0-1.0", + "repository": "jonathantneal/postcss-dir-pseudo-class", + "homepage": "https://github.com/jonathantneal/postcss-dir-pseudo-class#readme", + "bugs": "https://github.com/jonathantneal/postcss-dir-pseudo-class/issues", + "main": "index.js", + "files": [ + "index.js" + ], + "scripts": { + "clean": "git clean -X -d -f", + "prepublish": "npm test", + "test": "echo 'Running tests...'; npm run test:js && npm run test:tape", + "test:js": "eslint *.js --cache --ignore-pattern .gitignore", + "test:tape": "postcss-tape" + }, + "engines": { + "node": ">=4.0.0" + }, + "dependencies": { + "postcss": "^6.0.1", + "postcss-selector-parser": "^2.2.3" + }, + "devDependencies": { + "eslint": "^3.19.0", + "eslint-config-dev": "2.0.0", + "postcss-tape": "2.0.1", + "pre-commit": "^1.2.2" + }, + "eslintConfig": { + "extends": "dev" + }, + "keywords": [ + "postcss", + "css", + "postcss-plugin", + "directionality", + "directions", + "selector", + "attribute", + "polyfill" + ] +} diff --git a/test/basic.css b/test/basic.css new file mode 100644 index 0000000000..b9410af66e --- /dev/null +++ b/test/basic.css @@ -0,0 +1,27 @@ +:dir(ltr) { + order: 0; +} + +:dir(ltr) test { + order: 1; +} + +test :dir(ltr) { + order: 2; +} + +test :dir(ltr) test { + order: 3; +} + +test:dir(ltr) { + order: 4; +} + +test:dir(ltr) test { + order: 5; +} + +test test:dir(ltr) { + order: 6; +} diff --git a/test/basic.expect.css b/test/basic.expect.css new file mode 100644 index 0000000000..ef80f2d0df --- /dev/null +++ b/test/basic.expect.css @@ -0,0 +1,27 @@ +[dir="ltr"] { + order: 0; +} + +[dir="ltr"] test { + order: 1; +} + +[dir="ltr"] test * { + order: 2; +} + +[dir="ltr"] test * test { + order: 3; +} + +[dir="ltr"] test { + order: 4; +} + +[dir="ltr"] test test { + order: 5; +} + +[dir="ltr"] test test { + order: 6; +} From 81367451777303ac464a5b82eab549241df74992 Mon Sep 17 00:00:00 2001 From: Dmitry Semigradsky Date: Fri, 2 Jun 2017 11:36:57 +0300 Subject: [PATCH 459/795] Change link to specification --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index bcf5a79940..254b9b21df 100755 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # postcss-custom-media [![Build Status](https://travis-ci.org/postcss/postcss-custom-media.png)](https://travis-ci.org/postcss/postcss-custom-media) -> [PostCSS](https://github.com/postcss/postcss) plugin to transform [W3C CSS Custom Media Queries](https://www.w3.org/TR/2016/WD-mediaqueries-4-20160126/#custom-mq) syntax to more compatible CSS. +> [PostCSS](https://github.com/postcss/postcss) plugin to transform [W3C CSS Custom Media Queries](https://drafts.csswg.org/mediaqueries-5/#custom-mq) syntax to more compatible CSS. ## Installation From a76e3f87f9156ee0dddd7acc1946a4edc36fa79a Mon Sep 17 00:00:00 2001 From: Jonathan Neal Date: Fri, 2 Jun 2017 12:46:41 -0400 Subject: [PATCH 460/795] Update Plugin: Organize and document source --- index.js | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/index.js b/index.js index 9de45abb85..d745d511fe 100644 --- a/index.js +++ b/index.js @@ -1,22 +1,27 @@ // tooling -const postcss = require('postcss'); +const postcss = require('postcss'); const selectorParser = require('postcss-selector-parser'); // plugin -module.exports = postcss.plugin('postcss-dir-pseudo-class', () => (root) => { +module.exports = postcss.plugin('postcss-dir-pseudo-class', (opts) => (root) => { + // walk rules using the :dir pseudo-class root.walkRules(/:dir\([^\)]*\)/, (rule) => { + // update the rule selector rule.selector = selectorParser((selectors) => { + // for each (comma separated) selector selectors.nodes.forEach( (selector) => { + // walk all selector nodes that are :dir pseudo-classes selector.walk((node) => { - // ... if ('pseudo' === node.type && ':dir' === node.value) { + // previous and next selector nodes const prev = node.prev(); - const prevIsSpaceCombinator = prev && prev.type && 'combinator' === prev.type && ' ' === prev.value; - const next = node.next(); + + const prevIsSpaceCombinator = prev && prev.type && 'combinator' === prev.type && ' ' === prev.value; const nextIsSpaceCombinator = next && next.type && 'combinator' === next.type && ' ' === next.value; + // preserve the selector tree if (prevIsSpaceCombinator && (nextIsSpaceCombinator || !next)) { node.replaceWith( selectorParser.universal() @@ -25,6 +30,7 @@ module.exports = postcss.plugin('postcss-dir-pseudo-class', () => (root) => { node.remove(); } + // conditionally prepend a combinator before inserting the [dir] attribute const first = selector.nodes[0]; const firstIsSpaceCombinator = first && 'combinator' === first.type && ' ' === first.value; @@ -36,11 +42,15 @@ module.exports = postcss.plugin('postcss-dir-pseudo-class', () => (root) => { ); } + // value of the :dir pseudo-class + const value = node.nodes.toString(); + + // prepend the dir attribute selector.prepend( selectorParser.attribute({ attribute: 'dir', operator: '=', - value: `"${ node.nodes.toString() }"` + value: `"${ value }"` }) ); } From d4b09d4cd238031f77cbf6a79925536ac80bf604 Mon Sep 17 00:00:00 2001 From: Jonathan Neal Date: Fri, 2 Jun 2017 12:47:14 -0400 Subject: [PATCH 461/795] Update Plugin: Support presumed "dir" option --- index.js | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/index.js b/index.js index d745d511fe..984d435be6 100644 --- a/index.js +++ b/index.js @@ -33,8 +33,9 @@ module.exports = postcss.plugin('postcss-dir-pseudo-class', (opts) => (root) => // conditionally prepend a combinator before inserting the [dir] attribute const first = selector.nodes[0]; const firstIsSpaceCombinator = first && 'combinator' === first.type && ' ' === first.value; + const firstIsRoot = first && 'pseudo' === first.type && ':root' === first.value; - if (first && !firstIsSpaceCombinator) { + if (first && !firstIsRoot && !firstIsSpaceCombinator) { selector.prepend( selectorParser.combinator({ value: ' ' @@ -45,9 +46,16 @@ module.exports = postcss.plugin('postcss-dir-pseudo-class', (opts) => (root) => // value of the :dir pseudo-class const value = node.nodes.toString(); - // prepend the dir attribute + // whether that value matches the presumed direction + const isdir = opts && Object(opts).dir === value; + selector.prepend( - selectorParser.attribute({ + // prepend :root if the direction is presumed + isdir ? selectorParser.pseudo({ + value: ':root' + }) + // otherwise, prepend the dir attribute + : selectorParser.attribute({ attribute: 'dir', operator: '=', value: `"${ value }"` From e76b7ef835ff07b6928d1496a95c7a95a25e02d8 Mon Sep 17 00:00:00 2001 From: Jonathan Neal Date: Fri, 2 Jun 2017 12:47:41 -0400 Subject: [PATCH 462/795] Update Plugin: Support a browserslist --- index.js | 17 +++++++++++++++++ package.json | 1 + 2 files changed, 18 insertions(+) diff --git a/index.js b/index.js index 984d435be6..ae333571a4 100644 --- a/index.js +++ b/index.js @@ -1,9 +1,26 @@ // tooling +const browserslist = require('browserslist'); const postcss = require('postcss'); const selectorParser = require('postcss-selector-parser'); // plugin module.exports = postcss.plugin('postcss-dir-pseudo-class', (opts) => (root) => { + // client browser list + const clientBrowserList = browserslist(opts && opts.browsers, { + path: root.source && root.source.input && root.source.input.file + }); + + // whether this library is needed + const requiresPolyfill = clientBrowserList.some( + (clientBrowser) => browserslist('chrome > 0, edge > 0, firefox <= 48, ie > 0, safari > 0').some( + (polyfillBrowser) => polyfillBrowser === clientBrowser + ) + ); + + if (!requiresPolyfill) { + return; + } + // walk rules using the :dir pseudo-class root.walkRules(/:dir\([^\)]*\)/, (rule) => { // update the rule selector diff --git a/package.json b/package.json index 99348f4fc9..81ed7c72de 100644 --- a/package.json +++ b/package.json @@ -22,6 +22,7 @@ "node": ">=4.0.0" }, "dependencies": { + "browserslist": "^2.1.4", "postcss": "^6.0.1", "postcss-selector-parser": "^2.2.3" }, From 6958cade16e3b022a953aa5ae2e230561e5a4734 Mon Sep 17 00:00:00 2001 From: Jonathan Neal Date: Fri, 2 Jun 2017 12:48:10 -0400 Subject: [PATCH 463/795] Update Tests MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Test for “dir” and “browsers” options --- .tape.js | 23 +++++++++++++++++++++++ test/basic.css | 4 ++++ test/basic.dir.expect.css | 31 +++++++++++++++++++++++++++++++ test/basic.expect.css | 4 ++++ test/basic.supported.expect.css | 31 +++++++++++++++++++++++++++++++ 5 files changed, 93 insertions(+) create mode 100644 test/basic.dir.expect.css create mode 100644 test/basic.supported.expect.css diff --git a/.tape.js b/.tape.js index f1e2881271..6570b96b63 100644 --- a/.tape.js +++ b/.tape.js @@ -2,6 +2,29 @@ module.exports = { 'postcss-dir-pseudo-class': { 'basic': { message: 'supports basic usage' + }, + 'basic:dir': { + message: 'supports { dir: "ltr" } usage', + source: 'basic.css', + options: { + dir: 'ltr' + } + }, + 'basic:browsers': { + message: 'supports { browsers: "last 2 versions" } usage', + source: 'basic.css', + expect: 'basic.expect.css', + result: 'basic.result.css', + options: { + browsers: 'last 2 versions' + } + }, + 'basic:supported': { + message: 'ignores supported { ff >= 49 } usage', + source: 'basic.css', + options: { + browsers: 'ff >= 49' + } } } }; diff --git a/test/basic.css b/test/basic.css index b9410af66e..be2282f8fd 100644 --- a/test/basic.css +++ b/test/basic.css @@ -25,3 +25,7 @@ test:dir(ltr) test { test test:dir(ltr) { order: 6; } + +:root :dir(ltr) { + order: 7 +} diff --git a/test/basic.dir.expect.css b/test/basic.dir.expect.css new file mode 100644 index 0000000000..4a11562b4c --- /dev/null +++ b/test/basic.dir.expect.css @@ -0,0 +1,31 @@ +:root { + order: 0; +} + +:root test { + order: 1; +} + +:root test * { + order: 2; +} + +:root test * test { + order: 3; +} + +:root test { + order: 4; +} + +:root test test { + order: 5; +} + +:root test test { + order: 6; +} + +:root:root * { + order: 7 +} diff --git a/test/basic.expect.css b/test/basic.expect.css index ef80f2d0df..7dae80c413 100644 --- a/test/basic.expect.css +++ b/test/basic.expect.css @@ -25,3 +25,7 @@ [dir="ltr"] test test { order: 6; } + +[dir="ltr"]:root * { + order: 7 +} diff --git a/test/basic.supported.expect.css b/test/basic.supported.expect.css new file mode 100644 index 0000000000..be2282f8fd --- /dev/null +++ b/test/basic.supported.expect.css @@ -0,0 +1,31 @@ +:dir(ltr) { + order: 0; +} + +:dir(ltr) test { + order: 1; +} + +test :dir(ltr) { + order: 2; +} + +test :dir(ltr) test { + order: 3; +} + +test:dir(ltr) { + order: 4; +} + +test:dir(ltr) test { + order: 5; +} + +test test:dir(ltr) { + order: 6; +} + +:root :dir(ltr) { + order: 7 +} From 7b3b7cc071f09f96fb7333a8cc41fd51409f3dd6 Mon Sep 17 00:00:00 2001 From: Jonathan Neal Date: Fri, 2 Jun 2017 13:41:12 -0400 Subject: [PATCH 464/795] Update documentation --- README.md | 96 +++++++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 90 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 87a6efcfe2..b4da5e9f8e 100644 --- a/README.md +++ b/README.md @@ -8,19 +8,24 @@ [PostCSS :dir()] lets you use the `:dir` pseudo-class in CSS. ```css -.example:dir(ltr) { - margin-left: 10px; +.example:dir(rtl) { + margin-right: 10px; } /* becomes */ -[dir="ltr"] .example { - margin-left: 10px; +[dir="rtl"] .example { + margin-right: 10px; } ``` -Selector weight remains the same, but this requires you to specify a direction -(`dir`) attribute in your HTML. +If your [browserslist] already supports the `:dir` pseudo-class, this plugin +will not change your CSS. You can learn more this by reading about the +[`browsers` option](#browsers-option). + +By default, this plugin requires you to specify a direction `[dir]` attribute +in your HTML, preferably on the `html` element. If you prefer not to, you +can presume a direction in your CSS using the [`dir` option](#dir-option). ## Usage @@ -105,6 +110,84 @@ grunt.initConfig({ }); ``` +--- + +## browsers option + +If your [browserslist] already supports the `:dir` pseudo-class, this plugin +will not change your CSS. While only Firefox currently supports `:dir`, this +will surely improve over time. + +Here’s an example of a `package.json` using a browserslist that would fully +support the `:dir` pseudo-class: + +```json +{ + "browserslist": "firefox >= 49" +} +``` + +And here’s an example of using the `browsers` option to accomplish the same +thing: + +```js +require('postcss-dir-pseudo-class')({ + browsers: 'firefox >= 49' +}); +``` + +In both of these examples, the CSS would remain unchanged. + +```css +.example:dir(rtl) { + margin-right: 10px; +} + +/* becomes */ + +.example:dir(rtl) { + margin-right: 10px; +} +``` + +## dir option + +By default, this plugin requires you to specify a direction `[dir]` attribute +in your HTML, preferably on the `html` element. If you prefer not to, you +can presume a direction in your CSS using the `dir` option. + +Here’s an example of using the `dir` option to presume a left-to-right +direction: + +```js +require('postcss-dir-pseudo-class')({ + dir: 'ltr' +}); +``` + +```css +.example:dir(ltr) { + margin-left: 10px; +} + +.example:dir(rtl) { + margin-right: 10px; +} + +/* becomes */ + +:root .example { + margin-left: 10px; +} + +[dir="rtl"] .example { + margin-right: 10px; +} +``` + +*Note: The `:root` pseudo-class is added here to preserve the weight of the +original selector.* + [npm-url]: https://www.npmjs.com/package/postcss-dir-pseudo-class [npm-img]: https://img.shields.io/npm/v/postcss-dir-pseudo-class.svg [cli-url]: https://travis-ci.org/jonathantneal/postcss-dir-pseudo-class @@ -118,3 +201,4 @@ grunt.initConfig({ [PostCSS]: https://github.com/postcss/postcss [Gulp PostCSS]: https://github.com/postcss/gulp-postcss [Grunt PostCSS]: https://github.com/nDmitry/grunt-postcss +[browserslist]: https://github.com/ai/browserslist From 39756e624b7253a5ad581ad17bba8166c797d654 Mon Sep 17 00:00:00 2001 From: Jonathan Neal Date: Fri, 2 Jun 2017 13:42:29 -0400 Subject: [PATCH 465/795] 1.1.0 --- CHANGELOG.md | 5 +++++ package.json | 10 ++++++++-- 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8031dac314..5b2f0290e7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,10 @@ # Changes to PostCSS :dir() +### 1.1.0 (June 2, 2017) + +- Added: Support for browserslist and a 'browsers' option +- Added: Support for a presumed direction via the 'browsers' option + ### 1.0.0 (May 30, 2017) - Initial version diff --git a/package.json b/package.json index 81ed7c72de..33c4b0385e 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "postcss-dir-pseudo-class", - "version": "1.0.0", + "version": "1.1.0", "description": "Use the :dir pseudo-class in CSS", "author": "Jonathan Neal ", "license": "CC0-1.0", @@ -43,6 +43,12 @@ "directions", "selector", "attribute", - "polyfill" + "polyfill", + "left", + "left-to-right", + "ltr", + "right", + "right-to-left", + "rtl" ] } From 98f4184a609403e5287d390641bba473e9dd4fb1 Mon Sep 17 00:00:00 2001 From: Jonathan Neal Date: Wed, 21 Jun 2017 08:54:29 -0400 Subject: [PATCH 466/795] Update dependencies --- package.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/package.json b/package.json index 444996f7a2..9386aa79de 100644 --- a/package.json +++ b/package.json @@ -25,11 +25,11 @@ "node": ">=4.0.0" }, "dependencies": { - "browserslist": "^2.1.2", - "postcss": "^6.0.1" + "browserslist": "^2.1.5", + "postcss": "^6.0.2" }, "devDependencies": { - "eslint": "^3.19.0", + "eslint": "^4.0.0", "eslint-config-dev": "2.0.0", "fse": "^3.0.0", "postcss-tape": "2.0.1", From 0c0d7b5a0326c0bff3c1b5bbfc348b7b1243fd28 Mon Sep 17 00:00:00 2001 From: Jonathan Neal Date: Wed, 21 Jun 2017 08:54:41 -0400 Subject: [PATCH 467/795] Add package-lock.json --- package-lock.json | 772 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 772 insertions(+) create mode 100644 package-lock.json diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 0000000000..c4bb0542a7 --- /dev/null +++ b/package-lock.json @@ -0,0 +1,772 @@ +{ + "name": "postcss-normalize", + "version": "3.0.0", + "lockfileVersion": 1, + "dependencies": { + "acorn": { + "version": "https://registry.npmjs.org/acorn/-/acorn-5.0.3.tgz", + "integrity": "sha1-xGDfCEkUY/AozLguqzcwvwEIez0=", + "dev": true + }, + "acorn-jsx": { + "version": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-3.0.1.tgz", + "integrity": "sha1-r9+UiPsezvyDSPb7IvRk4ypYs2s=", + "dev": true, + "dependencies": { + "acorn": { + "version": "https://registry.npmjs.org/acorn/-/acorn-3.3.0.tgz", + "integrity": "sha1-ReN/s56No/JbruP/U2niu18iAXo=", + "dev": true + } + } + }, + "ajv": { + "version": "https://registry.npmjs.org/ajv/-/ajv-4.11.8.tgz", + "integrity": "sha1-gv+wKynmYq5TvcIK8VlHcGc5xTY=", + "dev": true + }, + "ajv-keywords": { + "version": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-1.5.1.tgz", + "integrity": "sha1-MU3QpLM2j609/NxU7eYXG4htrzw=", + "dev": true + }, + "ansi-regex": { + "version": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=" + }, + "ansi-styles": { + "version": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=" + }, + "argparse": { + "version": "https://registry.npmjs.org/argparse/-/argparse-1.0.9.tgz", + "integrity": "sha1-c9g7wmP4bpf4zE9rrhsOkKfSLIY=", + "dev": true + }, + "array-union": { + "version": "https://registry.npmjs.org/array-union/-/array-union-1.0.2.tgz", + "integrity": "sha1-mjRBDk9OPaI96jdb5b5w8kd47Dk=", + "dev": true + }, + "array-uniq": { + "version": "https://registry.npmjs.org/array-uniq/-/array-uniq-1.0.3.tgz", + "integrity": "sha1-r2rId6Jcx/dOBYiUdThY39sk/bY=", + "dev": true + }, + "arrify": { + "version": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", + "integrity": "sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=", + "dev": true + }, + "babel-code-frame": { + "version": "https://registry.npmjs.org/babel-code-frame/-/babel-code-frame-6.22.0.tgz", + "integrity": "sha1-AnYgvuVnqIwyVhV05/0IAdMxGOQ=", + "dev": true + }, + "balanced-match": { + "version": "https://registry.npmjs.org/balanced-match/-/balanced-match-0.4.2.tgz", + "integrity": "sha1-yz8+PHMtwPAe5wtAPzAuYddwmDg=", + "dev": true + }, + "brace-expansion": { + "version": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.7.tgz", + "integrity": "sha1-Pv/DxQ4ABTH7cg6v+A8K6O8jz1k=", + "dev": true + }, + "browserslist": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-2.1.5.tgz", + "integrity": "sha1-6IJVDfPRzW1IHBo+ADjyuvE6RxE=", + "dependencies": { + "caniuse-lite": { + "version": "1.0.30000692", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30000692.tgz", + "integrity": "sha1-NGAP1xUjUthaR/RmKjtRsC2LZG8=" + }, + "electron-to-chromium": { + "version": "1.3.14", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.14.tgz", + "integrity": "sha1-ZK8Pnv08PGrNV9cfg7Scp+6cS0M=" + } + } + }, + "buffer-shims": { + "version": "https://registry.npmjs.org/buffer-shims/-/buffer-shims-1.0.0.tgz", + "integrity": "sha1-mXjOMXOIxkmth5MCjDR37wRKi1E=", + "dev": true + }, + "caller-path": { + "version": "https://registry.npmjs.org/caller-path/-/caller-path-0.1.0.tgz", + "integrity": "sha1-lAhe9jWB7NPaqSREqP6U6CV3dR8=", + "dev": true + }, + "callsites": { + "version": "https://registry.npmjs.org/callsites/-/callsites-0.2.0.tgz", + "integrity": "sha1-r6uWJikQp/M8GaV3WCXGnzTjUMo=", + "dev": true + }, + "chalk": { + "version": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", + "dependencies": { + "supports-color": { + "version": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", + "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=" + } + } + }, + "circular-json": { + "version": "https://registry.npmjs.org/circular-json/-/circular-json-0.3.1.tgz", + "integrity": "sha1-vos2rvzN6LPKeqLWr8B6NyQsDS0=", + "dev": true + }, + "cli-width": { + "version": "https://registry.npmjs.org/cli-width/-/cli-width-2.1.0.tgz", + "integrity": "sha1-sjTKIJsp72b8UY2bmNWEewDt8Ao=", + "dev": true + }, + "co": { + "version": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", + "integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ=", + "dev": true + }, + "concat-map": { + "version": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", + "dev": true + }, + "concat-stream": { + "version": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.0.tgz", + "integrity": "sha1-CqxmL9Ur54lk1VMvaUeE5wEQrPc=", + "dev": true + }, + "core-util-is": { + "version": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", + "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=", + "dev": true + }, + "cross-spawn": { + "version": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-5.1.0.tgz", + "integrity": "sha1-6L0O/uWPz/b4+UUQoKVUu/ojVEk=", + "dev": true + }, + "debug": { + "version": "https://registry.npmjs.org/debug/-/debug-2.6.8.tgz", + "integrity": "sha1-5zFTHKLt4n0YgiJCfaF4IdaP9Pw=", + "dev": true + }, + "deep-is": { + "version": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz", + "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=", + "dev": true + }, + "del": { + "version": "https://registry.npmjs.org/del/-/del-2.2.2.tgz", + "integrity": "sha1-wSyYHQZ4RshLyvhiz/kw2Qf/0ag=", + "dev": true + }, + "doctrine": { + "version": "https://registry.npmjs.org/doctrine/-/doctrine-2.0.0.tgz", + "integrity": "sha1-xz2NKQnSIpHhoAejlYBNqLZl/mM=", + "dev": true + }, + "escape-string-regexp": { + "version": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=" + }, + "eslint": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-4.0.0.tgz", + "integrity": "sha1-cnfAFDf99B3M0WjVqg5Jt1yh8mA=", + "dev": true, + "dependencies": { + "ansi-escapes": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-2.0.0.tgz", + "integrity": "sha1-W65SvkJIeN2Xg+iRDj/Cki6DyBs=", + "dev": true + }, + "cli-cursor": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-2.1.0.tgz", + "integrity": "sha1-s12sN2R5+sw+lHR9QdDQ9SOP/LU=", + "dev": true + }, + "figures": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/figures/-/figures-2.0.0.tgz", + "integrity": "sha1-OrGi0qYsi/tDGgyUy3l6L84nyWI=", + "dev": true + }, + "inquirer": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-3.1.1.tgz", + "integrity": "sha512-H50sHQwgvvaTBd3HpKMVtL/u6LoHDvYym51gd7bGQe/+9HkCE+J0/3N5FJLfd6O6oz44hHewC2Pc2LodzWVafQ==", + "dev": true + }, + "is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", + "dev": true + }, + "mute-stream": { + "version": "0.0.7", + "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.7.tgz", + "integrity": "sha1-MHXOk7whuPq0PhvE2n6BFe0ee6s=", + "dev": true + }, + "onetime": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-2.0.1.tgz", + "integrity": "sha1-BnQoIw/WdEOyeUsiu6UotoZ5YtQ=", + "dev": true + }, + "pluralize": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/pluralize/-/pluralize-4.0.0.tgz", + "integrity": "sha1-WbcIwcAZCi9pLxx2GMRGsFL9F2I=", + "dev": true + }, + "progress": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.0.tgz", + "integrity": "sha1-ihvjZr+Pwj2yvSPxDG/pILQ4nR8=", + "dev": true + }, + "restore-cursor": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-2.0.0.tgz", + "integrity": "sha1-n37ih/gv0ybU/RYpI9YhKe7g368=", + "dev": true + }, + "run-async": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.3.0.tgz", + "integrity": "sha1-A3GrSuC91yDUFm19/aZP96RFpsA=", + "dev": true + }, + "rx-lite": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/rx-lite/-/rx-lite-4.0.8.tgz", + "integrity": "sha1-Cx4Rr4vESDbwSmQH6S2kJGe3lEQ=", + "dev": true + }, + "string-width": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.0.0.tgz", + "integrity": "sha1-Y1xUNsxypuDDh87KJ41OLuxSaH4=", + "dev": true + }, + "table": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/table/-/table-4.0.1.tgz", + "integrity": "sha1-qBFsEz+sLGH0pCCrbN9cTWHw5DU=", + "dev": true + } + } + }, + "eslint-config-dev": { + "version": "https://registry.npmjs.org/eslint-config-dev/-/eslint-config-dev-2.0.0.tgz", + "integrity": "sha1-guXKMTRJr3sSu/1OlzPrKG8PQ7c=", + "dev": true + }, + "eslint-scope": { + "version": "3.7.1", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-3.7.1.tgz", + "integrity": "sha1-PWPD7f2gLgbgGkUq2IyqzHzctug=", + "dev": true + }, + "espree": { + "version": "https://registry.npmjs.org/espree/-/espree-3.4.3.tgz", + "integrity": "sha1-KRC1zNSc6JPC//+qtP2LOjG4I3Q=", + "dev": true + }, + "esprima": { + "version": "https://registry.npmjs.org/esprima/-/esprima-3.1.3.tgz", + "integrity": "sha1-/cpRzuYTOJXjyI1TXOSdv/YqRjM=", + "dev": true + }, + "esquery": { + "version": "https://registry.npmjs.org/esquery/-/esquery-1.0.0.tgz", + "integrity": "sha1-z7qLV9f7qT8XKYqKAGoEzaE9gPo=", + "dev": true + }, + "esrecurse": { + "version": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.1.0.tgz", + "integrity": "sha1-RxO2U2rffyrE8yfVWed1a/9kgiA=", + "dev": true, + "dependencies": { + "estraverse": { + "version": "https://registry.npmjs.org/estraverse/-/estraverse-4.1.1.tgz", + "integrity": "sha1-9srKcokzqFDvkGYdDheYK6RxEaI=", + "dev": true + } + } + }, + "estraverse": { + "version": "https://registry.npmjs.org/estraverse/-/estraverse-4.2.0.tgz", + "integrity": "sha1-De4/7TH81GlhjOc0IJn8GvoL2xM=", + "dev": true + }, + "esutils": { + "version": "https://registry.npmjs.org/esutils/-/esutils-2.0.2.tgz", + "integrity": "sha1-Cr9PHKpbyx96nYrMbepPqqBLrJs=", + "dev": true + }, + "external-editor": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-2.0.4.tgz", + "integrity": "sha1-HtkZnanL/i7y96MbL96LDRI2iXI=", + "dev": true + }, + "fast-levenshtein": { + "version": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", + "dev": true + }, + "file-entry-cache": { + "version": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-2.0.0.tgz", + "integrity": "sha1-w5KZDD5oR4PYOLjISkXYoEhFg2E=", + "dev": true + }, + "flat-cache": { + "version": "https://registry.npmjs.org/flat-cache/-/flat-cache-1.2.2.tgz", + "integrity": "sha1-+oZxTnLCHbiGAXYezy9VXRq8a5Y=", + "dev": true + }, + "fs.realpath": { + "version": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", + "dev": true + }, + "fse": { + "version": "https://registry.npmjs.org/fse/-/fse-3.0.0.tgz", + "integrity": "sha1-f65r9PWDb1gVcID4BjaO5it1hX8=", + "dev": true + }, + "generate-function": { + "version": "https://registry.npmjs.org/generate-function/-/generate-function-2.0.0.tgz", + "integrity": "sha1-aFj+fAlpt9TpCTM3ZHrHn2DfvnQ=", + "dev": true + }, + "generate-object-property": { + "version": "https://registry.npmjs.org/generate-object-property/-/generate-object-property-1.2.0.tgz", + "integrity": "sha1-nA4cQDCM6AT0eDYYuTf6iPmdUNA=", + "dev": true + }, + "glob": { + "version": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz", + "integrity": "sha1-wZyd+aAocC1nhhI4SmVSQExjbRU=", + "dev": true + }, + "globals": { + "version": "https://registry.npmjs.org/globals/-/globals-9.17.0.tgz", + "integrity": "sha1-DAymltm5u2lNLlRwvTd3fKrVAoY=", + "dev": true + }, + "globby": { + "version": "https://registry.npmjs.org/globby/-/globby-5.0.0.tgz", + "integrity": "sha1-69hGZ8oNuzMLmbz8aOrCvFQ3Dg0=", + "dev": true + }, + "graceful-fs": { + "version": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.11.tgz", + "integrity": "sha1-Dovf5NHduIVNZOBOp8AOKgJuVlg=", + "dev": true + }, + "has-ansi": { + "version": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", + "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=" + }, + "has-flag": { + "version": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz", + "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo=" + }, + "iconv-lite": { + "version": "0.4.18", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.18.tgz", + "integrity": "sha512-sr1ZQph3UwHTR0XftSbK85OvBbxe/abLGzEnPENCQwmHf7sck8Oyu4ob3LgBxWWxRoM+QszeUyl7jbqapu2TqA==", + "dev": true + }, + "ignore": { + "version": "https://registry.npmjs.org/ignore/-/ignore-3.3.3.tgz", + "integrity": "sha1-QyNS5XrM2HqzEQ6C0/6g5HgSFW0=", + "dev": true + }, + "imurmurhash": { + "version": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", + "dev": true + }, + "inflight": { + "version": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "dev": true + }, + "inherits": { + "version": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", + "dev": true + }, + "is-my-json-valid": { + "version": "https://registry.npmjs.org/is-my-json-valid/-/is-my-json-valid-2.16.0.tgz", + "integrity": "sha1-8Hndm/2uZe4gOKrorLyGqxCeNpM=", + "dev": true + }, + "is-path-cwd": { + "version": "https://registry.npmjs.org/is-path-cwd/-/is-path-cwd-1.0.0.tgz", + "integrity": "sha1-0iXsIxMuie3Tj9p2dHLmLmXxEG0=", + "dev": true + }, + "is-path-in-cwd": { + "version": "https://registry.npmjs.org/is-path-in-cwd/-/is-path-in-cwd-1.0.0.tgz", + "integrity": "sha1-ZHdYK4IU1gI0YJRWcAO+ip6sBNw=", + "dev": true + }, + "is-path-inside": { + "version": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-1.0.0.tgz", + "integrity": "sha1-/AbloWg/vaE95mev9xe7wQpI838=", + "dev": true + }, + "is-promise": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-2.1.0.tgz", + "integrity": "sha1-eaKp7OfwlugPNtKy87wWwf9L8/o=", + "dev": true + }, + "is-property": { + "version": "https://registry.npmjs.org/is-property/-/is-property-1.0.2.tgz", + "integrity": "sha1-V/4cTkhHTt1lsJkR8msc1Ald2oQ=", + "dev": true + }, + "is-resolvable": { + "version": "https://registry.npmjs.org/is-resolvable/-/is-resolvable-1.0.0.tgz", + "integrity": "sha1-jfV8YeouPFAUCNEA+wE8+NbgzGI=", + "dev": true + }, + "isarray": { + "version": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", + "dev": true + }, + "isexe": { + "version": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", + "dev": true + }, + "js-tokens": { + "version": "https://registry.npmjs.org/js-tokens/-/js-tokens-3.0.1.tgz", + "integrity": "sha1-COnxMkhKLEWjCQfp3E1VZ7fxFNc=", + "dev": true + }, + "js-yaml": { + "version": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.8.4.tgz", + "integrity": "sha1-UgtFZPhlc7qWZir4Woyvp7S1pvY=", + "dev": true + }, + "jschardet": { + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/jschardet/-/jschardet-1.4.2.tgz", + "integrity": "sha1-KqEH8UKvQSHRRWWdRPUIMJYeaZo=", + "dev": true + }, + "json-stable-stringify": { + "version": "https://registry.npmjs.org/json-stable-stringify/-/json-stable-stringify-1.0.1.tgz", + "integrity": "sha1-mnWdOcXy/1A/1TAGRu1EX4jE+a8=", + "dev": true + }, + "jsonify": { + "version": "https://registry.npmjs.org/jsonify/-/jsonify-0.0.0.tgz", + "integrity": "sha1-LHS27kHZPKUbe1qu6PUDYx0lKnM=", + "dev": true + }, + "jsonpointer": { + "version": "https://registry.npmjs.org/jsonpointer/-/jsonpointer-4.0.1.tgz", + "integrity": "sha1-T9kss04OnbPInIYi7PUfm5eMbLk=", + "dev": true + }, + "levn": { + "version": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", + "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=", + "dev": true + }, + "lodash": { + "version": "https://registry.npmjs.org/lodash/-/lodash-4.17.4.tgz", + "integrity": "sha1-eCA6TRwyiuHYbcpkYONptX9AVa4=", + "dev": true + }, + "lru-cache": { + "version": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.0.2.tgz", + "integrity": "sha1-HRdnnAac2l0ECZGgnbwsDbN35V4=", + "dev": true + }, + "mimic-fn": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-1.1.0.tgz", + "integrity": "sha1-5md4PZLonb00KBi1IwudYqZyrRg=", + "dev": true + }, + "minimatch": { + "version": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", + "integrity": "sha1-UWbihkV/AzBgZL5Ul+jbsMPTIIM=", + "dev": true + }, + "minimist": { + "version": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", + "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=", + "dev": true + }, + "mkdirp": { + "version": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", + "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", + "dev": true + }, + "ms": { + "version": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + }, + "natural-compare": { + "version": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=", + "dev": true + }, + "object-assign": { + "version": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", + "dev": true + }, + "once": { + "version": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "dev": true + }, + "optionator": { + "version": "https://registry.npmjs.org/optionator/-/optionator-0.8.2.tgz", + "integrity": "sha1-NkxeQJ0/TWMB1sC0wFu6UBgK62Q=", + "dev": true + }, + "os-shim": { + "version": "https://registry.npmjs.org/os-shim/-/os-shim-0.1.3.tgz", + "integrity": "sha1-a2LDeRz3kJ6jXtRuF2WLtBfLORc=", + "dev": true + }, + "os-tmpdir": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", + "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=", + "dev": true + }, + "path-is-absolute": { + "version": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", + "dev": true + }, + "path-is-inside": { + "version": "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz", + "integrity": "sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM=", + "dev": true + }, + "pify": { + "version": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", + "dev": true + }, + "pinkie": { + "version": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz", + "integrity": "sha1-clVrgM+g1IqXToDnckjoDtT3+HA=", + "dev": true + }, + "pinkie-promise": { + "version": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz", + "integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=", + "dev": true + }, + "postcss": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.2.tgz", + "integrity": "sha1-XE/qWJ8Kw7AMqnWxy8OihBlbfl0=" + }, + "postcss-tape": { + "version": "https://registry.npmjs.org/postcss-tape/-/postcss-tape-2.0.1.tgz", + "integrity": "sha1-PP4pUg4ZJ4E3zCvTXOeyvXq42jY=", + "dev": true + }, + "pre-commit": { + "version": "https://registry.npmjs.org/pre-commit/-/pre-commit-1.2.2.tgz", + "integrity": "sha1-287g7p3nI15X95xW186UZBpp7sY=", + "dev": true + }, + "prelude-ls": { + "version": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", + "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=", + "dev": true + }, + "process-nextick-args": { + "version": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-1.0.7.tgz", + "integrity": "sha1-FQ4gt1ZZCtP5EJPyWk8q2L/zC6M=", + "dev": true + }, + "pseudomap": { + "version": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", + "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=", + "dev": true + }, + "readable-stream": { + "version": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.2.9.tgz", + "integrity": "sha1-z3jsb0ptHrQ9JkiMrJfwQudLf8g=", + "dev": true + }, + "require-uncached": { + "version": "https://registry.npmjs.org/require-uncached/-/require-uncached-1.0.3.tgz", + "integrity": "sha1-Tg1W1slmL9MeQwEcS5WqSZVUIdM=", + "dev": true + }, + "resolve-from": { + "version": "https://registry.npmjs.org/resolve-from/-/resolve-from-1.0.1.tgz", + "integrity": "sha1-Jsv+k10a7uq7Kbw/5a6wHpPUQiY=", + "dev": true + }, + "rimraf": { + "version": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.1.tgz", + "integrity": "sha1-wjOOxkPfeht/5cVPqG9XQopV8z0=", + "dev": true + }, + "rx-lite": { + "version": "https://registry.npmjs.org/rx-lite/-/rx-lite-3.1.2.tgz", + "integrity": "sha1-Gc5QLKVyZl87ZHsQk5+X/RYV8QI=", + "dev": true + }, + "rx-lite-aggregates": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/rx-lite-aggregates/-/rx-lite-aggregates-4.0.8.tgz", + "integrity": "sha1-dTuHqJoRyVRnxKwWJsTvxOBcZ74=", + "dev": true + }, + "safe-buffer": { + "version": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.0.1.tgz", + "integrity": "sha1-0mPKVGls2KMGtcplUekt5XkY++c=", + "dev": true + }, + "shebang-command": { + "version": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", + "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=", + "dev": true + }, + "shebang-regex": { + "version": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", + "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=", + "dev": true + }, + "signal-exit": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz", + "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=", + "dev": true + }, + "slice-ansi": { + "version": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-0.0.4.tgz", + "integrity": "sha1-7b+JA/ZvfOL46v1s7tZeJkyDGzU=", + "dev": true + }, + "source-map": { + "version": "https://registry.npmjs.org/source-map/-/source-map-0.5.6.tgz", + "integrity": "sha1-dc449SvwczxafwwRjYEzSiu19BI=" + }, + "spawn-sync": { + "version": "https://registry.npmjs.org/spawn-sync/-/spawn-sync-1.0.15.tgz", + "integrity": "sha1-sAeZVX63+wyDdsKdROih6mfldHY=", + "dev": true + }, + "sprintf-js": { + "version": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", + "dev": true + }, + "string_decoder": { + "version": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.1.tgz", + "integrity": "sha1-YuIA8DmVWmgQ2N8KM//A8BNmLZg=", + "dev": true + }, + "strip-ansi": { + "version": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=" + }, + "strip-json-comments": { + "version": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", + "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=", + "dev": true + }, + "supports-color": { + "version": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz", + "integrity": "sha1-ZawFBLOVQXHYpklGsq48u4pfVPY=" + }, + "text-table": { + "version": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", + "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=", + "dev": true + }, + "through": { + "version": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", + "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=", + "dev": true + }, + "tmp": { + "version": "0.0.31", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.31.tgz", + "integrity": "sha1-jzirlDjhcxXl29izZX6L+yd65Kc=", + "dev": true + }, + "tryit": { + "version": "https://registry.npmjs.org/tryit/-/tryit-1.0.3.tgz", + "integrity": "sha1-OTvnMKlEb9Hq1tpZoBQwjzbCics=", + "dev": true + }, + "type-check": { + "version": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", + "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=", + "dev": true + }, + "typedarray": { + "version": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", + "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=", + "dev": true + }, + "util-deprecate": { + "version": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=", + "dev": true + }, + "which": { + "version": "https://registry.npmjs.org/which/-/which-1.2.14.tgz", + "integrity": "sha1-mofEN48D6CfOyvGs31bHNsAcFOU=", + "dev": true + }, + "wordwrap": { + "version": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", + "integrity": "sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus=", + "dev": true + }, + "wrappy": { + "version": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", + "dev": true + }, + "write": { + "version": "https://registry.npmjs.org/write/-/write-0.2.1.tgz", + "integrity": "sha1-X8A4KOJkzqP+kUVUdvejxWbLB1c=", + "dev": true + }, + "xtend": { + "version": "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz", + "integrity": "sha1-pcbVMr5lbiPbgg77lDofBJmNY68=", + "dev": true + }, + "yallist": { + "version": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", + "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=", + "dev": true + } + } +} From 3b750eba74b920a2149f6a009125f2cccd2d51f3 Mon Sep 17 00:00:00 2001 From: Jonathan Neal Date: Wed, 21 Jun 2017 08:55:21 -0400 Subject: [PATCH 468/795] Add options to allow duplicates or force imports --- .tape.js | 9 ++++-- index.js | 11 +++++-- test/basic.css | 2 ++ test/basic.expect.css | 32 +++++++++++++++++++ test/basic.last-1.expect.css | 29 +++++++++++++++++ test/basic.last-2.expect.css | 32 +++++++++++++++++++ ...{insertion.css => option-force-import.css} | 2 -- ...ect.css => option-force-import.expect.css} | 32 ------------------- 8 files changed, 110 insertions(+), 39 deletions(-) rename test/{insertion.css => option-force-import.css} (63%) rename test/{insertion.expect.css => option-force-import.expect.css} (98%) diff --git a/.tape.js b/.tape.js index 1e7612c0ec..c36417bed3 100644 --- a/.tape.js +++ b/.tape.js @@ -15,14 +15,17 @@ module.exports = { browsers: 'last 1 versions' } }, - 'insertion': { - message: 'supports an insertion point' - }, 'insertion-after': { message: 'support an insertion point (at the end of the file)' }, 'insertion-duplicate': { message: 'removes duplicate insertion points' + }, + 'option-force-import': { + message: 'forces an import at the beginning of the file', + options: { + forceImport: true + } } } }; diff --git a/index.js b/index.js index 02e2cc182f..9329ca7813 100644 --- a/index.js +++ b/index.js @@ -37,7 +37,14 @@ module.exports = postcss.plugin('postcss-normalize', (opts) => { root.walkAtRules( 'import-normalize', (atrule) => { - if (appliedRules[0].parent) { + if (opts && opts.allowDuplicates) { + // use any insertion point + atrule.replaceWith( + appliedRules.map( + (rule) => rule.clone() + ) + ); + } else if (appliedRules[0].parent) { // remove duplicate insertions atrule.remove(); } else { @@ -47,7 +54,7 @@ module.exports = postcss.plugin('postcss-normalize', (opts) => { } ); - if (!appliedRules[0].parent) { + if (opts && opts.forceImport && !appliedRules[0].parent) { // prepend required normalize rules root.prepend(appliedRules); } diff --git a/test/basic.css b/test/basic.css index a326381313..28b15407a5 100644 --- a/test/basic.css +++ b/test/basic.css @@ -1,3 +1,5 @@ +@import-normalize; + body { font-family: sans-serif; } diff --git a/test/basic.expect.css b/test/basic.expect.css index 4d3f333648..6ef7a7ce2b 100644 --- a/test/basic.expect.css +++ b/test/basic.expect.css @@ -3,49 +3,61 @@ html { -ms-text-size-adjust: 100%; -webkit-text-size-adjust: 100%; } + h1 { font-size: 2em; margin: 0.67em 0; } + hr { box-sizing: content-box; height: 0; overflow: visible; } + main { display: block; } + pre { font-family: monospace, monospace; font-size: 1em; } + a { background-color: transparent; -webkit-text-decoration-skip: objects; } + abbr[title] { text-decoration: underline; text-decoration: underline dotted; } + b, strong { font-weight: bolder; } + code, kbd, samp { font-family: monospace, monospace; font-size: 1em; } + small { font-size: 80%; } + img { border-style: none; } + svg:not(:root) { overflow: hidden; } + button, input, optgroup, @@ -53,16 +65,19 @@ select, textarea { margin: 0; } + button { overflow: visible; text-transform: none; } + button, [type="button"], [type="reset"], [type="submit"] { -webkit-appearance: button; } + button::-moz-focus-inner, [type="button"]::-moz-focus-inner, [type="reset"]::-moz-focus-inner, @@ -70,18 +85,22 @@ button::-moz-focus-inner, border-style: none; padding: 0; } + button:-moz-focusring, [type="button"]:-moz-focusring, [type="reset"]:-moz-focusring, [type="submit"]:-moz-focusring { outline: 1px dotted ButtonText; } + fieldset { padding: 0.35em 0.75em 0.625em; } + input { overflow: visible; } + legend { box-sizing: border-box; color: inherit; @@ -90,49 +109,62 @@ legend { padding: 0; white-space: normal; } + progress { display: inline-block; vertical-align: baseline; } + select { text-transform: none; } + textarea { overflow: auto; } + [type="checkbox"], [type="radio"] { box-sizing: border-box; padding: 0; } + [type="number"]::-webkit-inner-spin-button, [type="number"]::-webkit-outer-spin-button { height: auto; } + [type="search"] { -webkit-appearance: textfield; outline-offset: -2px; } + [type="search"]::-webkit-search-cancel-button, [type="search"]::-webkit-search-decoration { -webkit-appearance: none; } + ::-webkit-file-upload-button { -webkit-appearance: button; font: inherit; } + details { display: block; } + summary { display: list-item; } + template { display: none; } + [hidden] { display: none; } + body { font-family: sans-serif; } diff --git a/test/basic.last-1.expect.css b/test/basic.last-1.expect.css index 03c7093e75..7b123847fc 100644 --- a/test/basic.last-1.expect.css +++ b/test/basic.last-1.expect.css @@ -3,45 +3,56 @@ html { -ms-text-size-adjust: 100%; -webkit-text-size-adjust: 100%; } + h1 { font-size: 2em; margin: 0.67em 0; } + hr { box-sizing: content-box; height: 0; overflow: visible; } + main { display: block; } + pre { font-family: monospace, monospace; font-size: 1em; } + a { -webkit-text-decoration-skip: objects; } + abbr[title] { text-decoration: underline; text-decoration: underline dotted; } + b, strong { font-weight: bolder; } + code, kbd, samp { font-family: monospace, monospace; font-size: 1em; } + small { font-size: 80%; } + svg:not(:root) { overflow: hidden; } + button, input, optgroup, @@ -49,16 +60,19 @@ select, textarea { margin: 0; } + button { overflow: visible; text-transform: none; } + button, [type="button"], [type="reset"], [type="submit"] { -webkit-appearance: button; } + button::-moz-focus-inner, [type="button"]::-moz-focus-inner, [type="reset"]::-moz-focus-inner, @@ -66,18 +80,22 @@ button::-moz-focus-inner, border-style: none; padding: 0; } + button:-moz-focusring, [type="button"]:-moz-focusring, [type="reset"]:-moz-focusring, [type="submit"]:-moz-focusring { outline: 1px dotted ButtonText; } + fieldset { padding: 0.35em 0.75em 0.625em; } + input { overflow: visible; } + legend { box-sizing: border-box; color: inherit; @@ -86,41 +104,52 @@ legend { padding: 0; white-space: normal; } + progress { display: inline-block; vertical-align: baseline; } + select { text-transform: none; } + textarea { overflow: auto; } + [type="number"]::-webkit-inner-spin-button, [type="number"]::-webkit-outer-spin-button { height: auto; } + [type="search"] { -webkit-appearance: textfield; outline-offset: -2px; } + [type="search"]::-webkit-search-cancel-button, [type="search"]::-webkit-search-decoration { -webkit-appearance: none; } + ::-webkit-file-upload-button { -webkit-appearance: button; font: inherit; } + details { display: block; } + summary { display: list-item; } + template { display: none; } + body { font-family: sans-serif; } diff --git a/test/basic.last-2.expect.css b/test/basic.last-2.expect.css index 4d3f333648..6ef7a7ce2b 100644 --- a/test/basic.last-2.expect.css +++ b/test/basic.last-2.expect.css @@ -3,49 +3,61 @@ html { -ms-text-size-adjust: 100%; -webkit-text-size-adjust: 100%; } + h1 { font-size: 2em; margin: 0.67em 0; } + hr { box-sizing: content-box; height: 0; overflow: visible; } + main { display: block; } + pre { font-family: monospace, monospace; font-size: 1em; } + a { background-color: transparent; -webkit-text-decoration-skip: objects; } + abbr[title] { text-decoration: underline; text-decoration: underline dotted; } + b, strong { font-weight: bolder; } + code, kbd, samp { font-family: monospace, monospace; font-size: 1em; } + small { font-size: 80%; } + img { border-style: none; } + svg:not(:root) { overflow: hidden; } + button, input, optgroup, @@ -53,16 +65,19 @@ select, textarea { margin: 0; } + button { overflow: visible; text-transform: none; } + button, [type="button"], [type="reset"], [type="submit"] { -webkit-appearance: button; } + button::-moz-focus-inner, [type="button"]::-moz-focus-inner, [type="reset"]::-moz-focus-inner, @@ -70,18 +85,22 @@ button::-moz-focus-inner, border-style: none; padding: 0; } + button:-moz-focusring, [type="button"]:-moz-focusring, [type="reset"]:-moz-focusring, [type="submit"]:-moz-focusring { outline: 1px dotted ButtonText; } + fieldset { padding: 0.35em 0.75em 0.625em; } + input { overflow: visible; } + legend { box-sizing: border-box; color: inherit; @@ -90,49 +109,62 @@ legend { padding: 0; white-space: normal; } + progress { display: inline-block; vertical-align: baseline; } + select { text-transform: none; } + textarea { overflow: auto; } + [type="checkbox"], [type="radio"] { box-sizing: border-box; padding: 0; } + [type="number"]::-webkit-inner-spin-button, [type="number"]::-webkit-outer-spin-button { height: auto; } + [type="search"] { -webkit-appearance: textfield; outline-offset: -2px; } + [type="search"]::-webkit-search-cancel-button, [type="search"]::-webkit-search-decoration { -webkit-appearance: none; } + ::-webkit-file-upload-button { -webkit-appearance: button; font: inherit; } + details { display: block; } + summary { display: list-item; } + template { display: none; } + [hidden] { display: none; } + body { font-family: sans-serif; } diff --git a/test/insertion.css b/test/option-force-import.css similarity index 63% rename from test/insertion.css rename to test/option-force-import.css index 28b15407a5..a326381313 100644 --- a/test/insertion.css +++ b/test/option-force-import.css @@ -1,5 +1,3 @@ -@import-normalize; - body { font-family: sans-serif; } diff --git a/test/insertion.expect.css b/test/option-force-import.expect.css similarity index 98% rename from test/insertion.expect.css rename to test/option-force-import.expect.css index 6ef7a7ce2b..4d3f333648 100644 --- a/test/insertion.expect.css +++ b/test/option-force-import.expect.css @@ -3,61 +3,49 @@ html { -ms-text-size-adjust: 100%; -webkit-text-size-adjust: 100%; } - h1 { font-size: 2em; margin: 0.67em 0; } - hr { box-sizing: content-box; height: 0; overflow: visible; } - main { display: block; } - pre { font-family: monospace, monospace; font-size: 1em; } - a { background-color: transparent; -webkit-text-decoration-skip: objects; } - abbr[title] { text-decoration: underline; text-decoration: underline dotted; } - b, strong { font-weight: bolder; } - code, kbd, samp { font-family: monospace, monospace; font-size: 1em; } - small { font-size: 80%; } - img { border-style: none; } - svg:not(:root) { overflow: hidden; } - button, input, optgroup, @@ -65,19 +53,16 @@ select, textarea { margin: 0; } - button { overflow: visible; text-transform: none; } - button, [type="button"], [type="reset"], [type="submit"] { -webkit-appearance: button; } - button::-moz-focus-inner, [type="button"]::-moz-focus-inner, [type="reset"]::-moz-focus-inner, @@ -85,22 +70,18 @@ button::-moz-focus-inner, border-style: none; padding: 0; } - button:-moz-focusring, [type="button"]:-moz-focusring, [type="reset"]:-moz-focusring, [type="submit"]:-moz-focusring { outline: 1px dotted ButtonText; } - fieldset { padding: 0.35em 0.75em 0.625em; } - input { overflow: visible; } - legend { box-sizing: border-box; color: inherit; @@ -109,62 +90,49 @@ legend { padding: 0; white-space: normal; } - progress { display: inline-block; vertical-align: baseline; } - select { text-transform: none; } - textarea { overflow: auto; } - [type="checkbox"], [type="radio"] { box-sizing: border-box; padding: 0; } - [type="number"]::-webkit-inner-spin-button, [type="number"]::-webkit-outer-spin-button { height: auto; } - [type="search"] { -webkit-appearance: textfield; outline-offset: -2px; } - [type="search"]::-webkit-search-cancel-button, [type="search"]::-webkit-search-decoration { -webkit-appearance: none; } - ::-webkit-file-upload-button { -webkit-appearance: button; font: inherit; } - details { display: block; } - summary { display: list-item; } - template { display: none; } - [hidden] { display: none; } - body { font-family: sans-serif; } From 63e73269174eb173145ad286a2a513e95b1ec93b Mon Sep 17 00:00:00 2001 From: Jonathan Neal Date: Wed, 21 Jun 2017 08:55:36 -0400 Subject: [PATCH 469/795] Update README.md for options --- README.md | 55 ++++++++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 44 insertions(+), 11 deletions(-) diff --git a/README.md b/README.md index c99fb3b77d..374b8dc125 100644 --- a/README.md +++ b/README.md @@ -8,7 +8,14 @@ [PostCSS Normalize] lets you use the parts of [normalize.css] you need, based on your project’s [browserlist]. -Example: +Use `@import-normalize` to determine where [normalize.css] rules will be +included. Duplicate `@import-normalize` rules will be removed. See all the [Options] for more information. + +```css +@import-normalize; +``` + +Results: ```css /* { "browserlist": ["last 3 versions"] } */ @@ -43,16 +50,6 @@ img { } ``` -[PostCSS Normalize] will put itself at the beginning of your CSS file, unless -you dictate where it should be included: - -```css -@import-normalize; -``` - -Duplicate `@import-normalize` rules will be removed for your convenience. Only -the first instance will be replaced. - --- [PostCSS Normalize] uses the non-opinionated version of [normalize.css]. @@ -150,6 +147,41 @@ grunt.initConfig({ }); ``` +## Options + +### allowDuplicates + +Allows you to insert multiple, duplicate insertions of [normalize.css] rules. +The default is `false`. + +```js +require('postcss-normalize')({ + allowDuplicates: true +}); +``` + +### browsers + +Allows you to override of the project’s [browserlist] for [PostCSS Normalize]. +The default is `false`. + +```js +require('postcss-normalize')({ + browsers: 'last 2 versions' +}); +``` + +### forceImport + +Allows you to force an insertion of [normalize.css] rules at the beginning of +the CSS file if no insertion point is specified. The default is `false`. + +```js +require('postcss-normalize')({ + forceImport: true +}); +``` + [npm-url]: https://www.npmjs.com/package/postcss-normalize [npm-img]: https://img.shields.io/npm/v/postcss-normalize.svg [cli-url]: https://travis-ci.org/jonathantneal/postcss-normalize @@ -166,3 +198,4 @@ grunt.initConfig({ [browserlist]: http://browserl.ist/ [normalize.css]: https://github.com/jonathantneal/normalize.css +[Options]: #Options From c56d952a2504cc25aae82e2c218f613738bfd967 Mon Sep 17 00:00:00 2001 From: Jonathan Neal Date: Wed, 21 Jun 2017 08:56:08 -0400 Subject: [PATCH 470/795] 4.0.0 --- CHANGELOG.md | 5 +++++ package-lock.json | 2 +- package.json | 2 +- 3 files changed, 7 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1f49295bdc..0f0acbdbed 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,10 @@ # Changes to PostCSS Normalize +### 4.0.0 (June 21, 2017) + +- Require insertion point. Make old behavior an option. +- Allow multiple insertion points. + ### 3.0.0 (May 26, 2017) - Use jonathantneal/normalize.css v7 diff --git a/package-lock.json b/package-lock.json index c4bb0542a7..a4de6885d3 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "postcss-normalize", - "version": "3.0.0", + "version": "4.0.0", "lockfileVersion": 1, "dependencies": { "acorn": { diff --git a/package.json b/package.json index 9386aa79de..820a605af6 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "postcss-normalize", - "version": "3.0.0", + "version": "4.0.0", "description": "Use the parts of normalize.css you need from your browserlist", "author": "Jonathan Neal ", "license": "CC0-1.0", From c371abefcb81008b581d0c453fca7354d60a6c86 Mon Sep 17 00:00:00 2001 From: Bundyo Date: Tue, 4 Apr 2017 17:27:52 +0300 Subject: [PATCH 471/795] Let "warnings" option silence all warnings. --- index.js | 25 ++++++++++++++++++------- 1 file changed, 18 insertions(+), 7 deletions(-) diff --git a/index.js b/index.js index 5e98545765..e7911048c8 100755 --- a/index.js +++ b/index.js @@ -6,6 +6,12 @@ const VAR_FUNC_IDENTIFIER = "var" // matches `name[, fallback]`, captures "name" and "fallback" const RE_VAR = /([\w-]+)(?:\s*,\s*)?\s*(.*)?/ +/** + * Module variables + */ + +let globalWarnings + /** * Resolve CSS variables. * @@ -41,10 +47,12 @@ function resolveValue(value, variables, result, decl) { let post // undefined and without fallback, just keep original value if (!variable && !fallback) { - result.warn( - "variable '" + name + "' is undefined and used without a fallback", - {node: decl} - ) + if (globalWarnings) { + result.warn( + "variable '" + name + "' is undefined and used without a fallback", + {node: decl} + ) + } post = matches.post ? resolveValue(matches.post, variables, result, decl) : [""] @@ -82,7 +90,9 @@ function resolveValue(value, variables, result, decl) { // circular reference encountered if (variable.deps.indexOf(name) !== -1) { if (!fallback) { - result.warn("Circular variable reference: " + name, {node: decl}) + if (globalWarnings) { + result.warn("Circular variable reference: " + name, {node: decl}) + } variable.value = [variable.value] variable.circular = true } @@ -142,7 +152,6 @@ export default postcss.plugin("postcss-custom-properties", (options = {}) => { } function plugin(style, result) { - const warnings = options.warnings === undefined ? true : options.warnings const variables = prefixVariables(options.variables) const strict = options.strict === undefined ? true : options.strict const appendVariables = options.appendVariables @@ -150,6 +159,8 @@ export default postcss.plugin("postcss-custom-properties", (options = {}) => { const map = {} const importantMap = {} + globalWarnings = options.warnings === undefined ? true : options.warnings + // define variables style.walkRules((rule) => { const toRemove = [] @@ -163,7 +174,7 @@ export default postcss.plugin("postcss-custom-properties", (options = {}) => { rule.each((decl) => { const prop = decl.prop if ( - warnings && + globalWarnings && prop && prop.indexOf(VAR_PROP_IDENTIFIER) === 0 ) { From bd38c2fc25945d034d64b5cbc5c77f02388de80c Mon Sep 17 00:00:00 2001 From: Jonathan Neal Date: Tue, 27 Jun 2017 14:30:24 -0400 Subject: [PATCH 472/795] Update dependencies --- package.json | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/package.json b/package.json index f3be783a98..3479c7b752 100644 --- a/package.json +++ b/package.json @@ -18,17 +18,17 @@ "dist" ], "dependencies": { - "balanced-match": "^0.4.2", - "postcss": "^6.0.1" + "balanced-match": "^1.0.0", + "postcss": "^6.0.3" }, "devDependencies": { "babel-cli": "^6.24.1", "babel-plugin-add-module-exports": "^0.2.1", - "babel-preset-env": "^1.4.0", + "babel-preset-env": "^1.5.2", "babel-register": "^6.24.1", - "eslint": "^3.19.0", + "eslint": "^4.1.1", "npmpub": "^3.1.0", - "tape": "^4.6.3" + "tape": "^4.7.0" }, "scripts": { "lint": "eslint *.js index.js ./test/", From bbf92943e9aa8578429e29adc369179665275616 Mon Sep 17 00:00:00 2001 From: Jonathan Neal Date: Tue, 27 Jun 2017 14:33:27 -0400 Subject: [PATCH 473/795] 6.1.0 --- CHANGELOG.md | 6 ++++++ package.json | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c987daaf27..dcc5820615 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,9 @@ +# 6.1.0 - 2017-06-28 + +- Added: Let "warnings" option silence all warnings +([#67](https://github.com/postcss/postcss-custom-properties/pull/67)) +- Dependencies update (postcss, balanced-match) + # 6.0.1 - 2017-05-15 - Fixed: incorrect export ([#69](https://github.com/postcss/postcss-custom-properties/issues/69)) diff --git a/package.json b/package.json index 3479c7b752..d38f38b61d 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "postcss-custom-properties", - "version": "6.0.1", + "version": "6.1.0", "description": "PostCSS plugin to polyfill W3C CSS Custom Properties for cascading variables", "keywords": [ "css", From 04ccea0af8bac355cd50734f4be32d59b77d51a6 Mon Sep 17 00:00:00 2001 From: Jonathan Neal Date: Fri, 30 Jun 2017 09:14:55 -0400 Subject: [PATCH 474/795] Node 4+ compatibility --- index.js | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/index.js b/index.js index 21a0e34f06..364fb36545 100644 --- a/index.js +++ b/index.js @@ -3,11 +3,9 @@ const postcss = require('postcss'); const parser = require('postcss-value-parser'); // plugin -module.exports = postcss.plugin('postcss-place', ({ - prefix = '' -} = {}) => { +module.exports = postcss.plugin('postcss-place', (opts) => { // dashed prefix - const dashedPrefix = prefix ? `-${ prefix }-` : ''; + const dashedPrefix = opts && opts.prefix ? `-${ opts.prefix }-` : ''; // property matcher const propertyMatch = new RegExp(`^${ dashedPrefix }place-(content|items|self)`); From 131b31461d7f14ab69d7a726d0c0de448fd8e90a Mon Sep 17 00:00:00 2001 From: Jonathan Neal Date: Fri, 30 Jun 2017 09:15:14 -0400 Subject: [PATCH 475/795] PostCSS 6+ compatibility --- package.json | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/package.json b/package.json index 38c510ec6a..ec288b47a0 100644 --- a/package.json +++ b/package.json @@ -21,17 +21,17 @@ "node": ">=6.9.1" }, "dependencies": { - "postcss": "^5.2.6", + "postcss": "^6.0.4", "postcss-value-parser": "^3.3.0" }, "devDependencies": { - "echint": "^2.1.0", + "echint": "^4.0.1", "echint-config-dev": "1.0.0", - "eslint": "^3.12.1", - "eslint-config-dev": "1.0.0", + "eslint": "^4.1.1", + "eslint-config-dev": "2.0.0", "jscs": "^3.0.7", "jscs-config-dev": "1.0.1", - "postcss-tape": "1.3.0" + "postcss-tape": "2.0.1" }, "echint": { "extends": "dev" From a405af1ffecd6846e36c7ea93895a3f2179e305b Mon Sep 17 00:00:00 2001 From: Jonathan Neal Date: Fri, 30 Jun 2017 09:15:56 -0400 Subject: [PATCH 476/795] 2.0.0 --- CHANGELOG.md | 5 +++++ package.json | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3274032868..3ab2300370 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,10 @@ # Changes to Place +### 2.0.0 (June 30, 2017) + +- Added: Node 4+ compatibility +- Added: PostCSS 6+ compatibility + ### 1.0.2 (December 8, 2016) - Updated: Use destructing assignment on plugin options diff --git a/package.json b/package.json index ec288b47a0..8b12e48375 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "postcss-place", - "version": "1.0.2", + "version": "2.0.0", "description": "`place-[alignment] shorthand for align-[alignment] and justify-[alignment]", "author": "Jonathan Neal (http://jonathantneal.com)", "license": "CC0-1.0", From 218ad29b415355df051806311b846e8ee033f861 Mon Sep 17 00:00:00 2001 From: Jonathan Neal Date: Fri, 30 Jun 2017 09:16:49 -0400 Subject: [PATCH 477/795] .travis.yml - Node 4 compatibility --- .travis.yml | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 833d09d149..c56466446c 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,3 +1,9 @@ +# https://docs.travis-ci.com/user/travis-lint + language: node_js + node_js: - - stable + - 4 + +install: + - npm install --ignore-scripts From f1621c4c07265f3e80397e1f2dc8c338404793de Mon Sep 17 00:00:00 2001 From: Oleg Lykasov Date: Wed, 19 Jul 2017 00:29:30 +0300 Subject: [PATCH 478/795] Added: noValueNotifications option (#71) --- README.md | 9 +++++++++ index.js | 26 +++++++++++++++++--------- test/index.js | 18 ++++++++++++++++++ 3 files changed, 44 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index 154ebeb7e8..2648f134de 100755 --- a/README.md +++ b/README.md @@ -129,6 +129,15 @@ Allows you to enable/disable warnings. If true, will enable all warnings. For now, it only allow to disable messages about custom properties definition not scoped in a `:root` selector. + +### `noValueNotifications` + +Default: `'warning'` +Values: `'warning'|'error'` + +If it is set to `'error'`, using of undefined variable will throw an error. + + --- ## Contributing diff --git a/index.js b/index.js index e7911048c8..89183c62e6 100755 --- a/index.js +++ b/index.js @@ -10,7 +10,7 @@ const RE_VAR = /([\w-]+)(?:\s*,\s*)?\s*(.*)?/ * Module variables */ -let globalWarnings +let globalOpts /** * Resolve CSS variables. @@ -47,11 +47,16 @@ function resolveValue(value, variables, result, decl) { let post // undefined and without fallback, just keep original value if (!variable && !fallback) { - if (globalWarnings) { - result.warn( - "variable '" + name + "' is undefined and used without a fallback", - {node: decl} - ) + if (globalOpts.warnings) { + const errorStr = + `variable '${name}' is undefined and used without a fallback` + + if (globalOpts.noValueNotifications === "error") { + throw decl.error(errorStr, {word: name}) + } + else { + result.warn(errorStr, {node: decl}) + } } post = matches.post ? resolveValue(matches.post, variables, result, decl) @@ -90,7 +95,7 @@ function resolveValue(value, variables, result, decl) { // circular reference encountered if (variable.deps.indexOf(name) !== -1) { if (!fallback) { - if (globalWarnings) { + if (globalOpts.warnings) { result.warn("Circular variable reference: " + name, {node: decl}) } variable.value = [variable.value] @@ -159,7 +164,10 @@ export default postcss.plugin("postcss-custom-properties", (options = {}) => { const map = {} const importantMap = {} - globalWarnings = options.warnings === undefined ? true : options.warnings + globalOpts = { + warnings: options.warnings === undefined ? true : options.warnings, + noValueNotifications: options.noValueNotifications || "warning", + } // define variables style.walkRules((rule) => { @@ -174,7 +182,7 @@ export default postcss.plugin("postcss-custom-properties", (options = {}) => { rule.each((decl) => { const prop = decl.prop if ( - globalWarnings && + globalOpts.warnings && prop && prop.indexOf(VAR_PROP_IDENTIFIER) === 0 ) { diff --git a/test/index.js b/test/index.js index 1978b84f3e..fc2441c1f3 100755 --- a/test/index.js +++ b/test/index.js @@ -71,6 +71,24 @@ test( } ) +test( + "generate error for undefined var when flag is set", + function(t) { + t.throws( + function() { + return postcss(customProperties({ + noValueNotifications: "error", + })) + .process(fixture("substitution-undefined")) + .css + }, + "variable '--test' is undefined and used without a fallback", + "should add a warning for undefined variable" + ) + t.end() + } +) + test("substitutes defined variables in `:root` only", function(t) { const result = compareFixtures(t, "substitution-defined") t.ok( From bb84580f6116c3beb4995dddb53256769f5206ba Mon Sep 17 00:00:00 2001 From: Jonathan Neal Date: Mon, 24 Jul 2017 21:45:56 -0400 Subject: [PATCH 479/795] Remove indent on selector walker --- index.js | 94 +++++++++++++++++++++++++++----------------------------- 1 file changed, 46 insertions(+), 48 deletions(-) diff --git a/index.js b/index.js index ae333571a4..054ed8f244 100644 --- a/index.js +++ b/index.js @@ -26,62 +26,60 @@ module.exports = postcss.plugin('postcss-dir-pseudo-class', (opts) => (root) => // update the rule selector rule.selector = selectorParser((selectors) => { // for each (comma separated) selector - selectors.nodes.forEach( - (selector) => { - // walk all selector nodes that are :dir pseudo-classes - selector.walk((node) => { - if ('pseudo' === node.type && ':dir' === node.value) { - // previous and next selector nodes - const prev = node.prev(); - const next = node.next(); + selectors.nodes.forEach((selector) => { + // walk all selector nodes that are :dir pseudo-classes + selector.walk((node) => { + if ('pseudo' === node.type && ':dir' === node.value) { + // previous and next selector nodes + const prev = node.prev(); + const next = node.next(); - const prevIsSpaceCombinator = prev && prev.type && 'combinator' === prev.type && ' ' === prev.value; - const nextIsSpaceCombinator = next && next.type && 'combinator' === next.type && ' ' === next.value; + const prevIsSpaceCombinator = prev && prev.type && 'combinator' === prev.type && ' ' === prev.value; + const nextIsSpaceCombinator = next && next.type && 'combinator' === next.type && ' ' === next.value; - // preserve the selector tree - if (prevIsSpaceCombinator && (nextIsSpaceCombinator || !next)) { - node.replaceWith( - selectorParser.universal() - ); - } else { - node.remove(); - } - - // conditionally prepend a combinator before inserting the [dir] attribute - const first = selector.nodes[0]; - const firstIsSpaceCombinator = first && 'combinator' === first.type && ' ' === first.value; - const firstIsRoot = first && 'pseudo' === first.type && ':root' === first.value; - - if (first && !firstIsRoot && !firstIsSpaceCombinator) { - selector.prepend( - selectorParser.combinator({ - value: ' ' - }) - ); - } - - // value of the :dir pseudo-class - const value = node.nodes.toString(); + // preserve the selector tree + if (prevIsSpaceCombinator && (nextIsSpaceCombinator || !next)) { + node.replaceWith( + selectorParser.universal() + ); + } else { + node.remove(); + } - // whether that value matches the presumed direction - const isdir = opts && Object(opts).dir === value; + // conditionally prepend a combinator before inserting the [dir] attribute + const first = selector.nodes[0]; + const firstIsSpaceCombinator = first && 'combinator' === first.type && ' ' === first.value; + const firstIsRoot = first && 'pseudo' === first.type && ':root' === first.value; + if (first && !firstIsRoot && !firstIsSpaceCombinator) { selector.prepend( - // prepend :root if the direction is presumed - isdir ? selectorParser.pseudo({ - value: ':root' - }) - // otherwise, prepend the dir attribute - : selectorParser.attribute({ - attribute: 'dir', - operator: '=', - value: `"${ value }"` + selectorParser.combinator({ + value: ' ' }) ); } - }); - } - ); + + // value of the :dir pseudo-class + const value = node.nodes.toString(); + + // whether that value matches the presumed direction + const isdir = opts && Object(opts).dir === value; + + selector.prepend( + // prepend :root if the direction is presumed + isdir ? selectorParser.pseudo({ + value: ':root' + }) + // otherwise, prepend the dir attribute + : selectorParser.attribute({ + attribute: 'dir', + operator: '=', + value: `"${ value }"` + }) + ); + } + }); + }); }).process(rule.selector).result; }); }); From 43b41083944aa33b0892314f9d4e14d4a46a59c7 Mon Sep 17 00:00:00 2001 From: Jonathan Neal Date: Mon, 24 Jul 2017 21:50:39 -0400 Subject: [PATCH 480/795] Change presumed LTR from root to not rtl MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit `:root` to `html:not([dir="rtl”]` --- index.js | 45 +++++++++++++++++++++++++++++++++++---------- 1 file changed, 35 insertions(+), 10 deletions(-) diff --git a/index.js b/index.js index 054ed8f244..79dc578ad9 100644 --- a/index.js +++ b/index.js @@ -49,9 +49,10 @@ module.exports = postcss.plugin('postcss-dir-pseudo-class', (opts) => (root) => // conditionally prepend a combinator before inserting the [dir] attribute const first = selector.nodes[0]; const firstIsSpaceCombinator = first && 'combinator' === first.type && ' ' === first.value; + const firstIsHtml = first && 'tag' === first.type && 'html' === first.value; const firstIsRoot = first && 'pseudo' === first.type && ':root' === first.value; - if (first && !firstIsRoot && !firstIsSpaceCombinator) { + if (first && !firstIsHtml && !firstIsRoot && !firstIsSpaceCombinator) { selector.prepend( selectorParser.combinator({ value: ' ' @@ -65,18 +66,42 @@ module.exports = postcss.plugin('postcss-dir-pseudo-class', (opts) => (root) => // whether that value matches the presumed direction const isdir = opts && Object(opts).dir === value; - selector.prepend( - // prepend :root if the direction is presumed - isdir ? selectorParser.pseudo({ - value: ':root' - }) - // otherwise, prepend the dir attribute - : selectorParser.attribute({ + // [dir] attribute + const dirAttr = selectorParser.attribute({ + attribute: 'dir', + operator: '=', + value: `"${ value }"` + }); + + // not[dir] attribute + const notDirAttr = selectorParser.pseudo({ + value: ':not' + }); + + notDirAttr.append( + selectorParser.attribute({ attribute: 'dir', - operator: '=', - value: `"${ value }"` + operator: '=', + value: `"${ 'ltr' === value ? 'rtl' : 'ltr' }"` }) ); + + if (isdir) { + // if the direction is presumed + if (firstIsHtml) { + // insert :root after html tag + selector.insertAfter(first, notDirAttr); + } else { + // prepend :root + selector.prepend(notDirAttr); + } + } else if (firstIsHtml) { + // otherwise, insert dir attribute after html tag + selector.insertAfter(first, dirAttr); + } else { + // otherwise, prepend the dir attribute + selector.prepend(dirAttr); + } } }); }); From 315993c9aa25ece3c8ffacfa8e5c14857a53d6c7 Mon Sep 17 00:00:00 2001 From: Jonathan Neal Date: Mon, 24 Jul 2017 21:57:13 -0400 Subject: [PATCH 481/795] Update tests --- test/basic.css | 42 +++++++++++++++++++++++- test/basic.dir.expect.css | 58 ++++++++++++++++++++++++++++----- test/basic.expect.css | 42 +++++++++++++++++++++++- test/basic.supported.expect.css | 42 +++++++++++++++++++++++- 4 files changed, 172 insertions(+), 12 deletions(-) diff --git a/test/basic.css b/test/basic.css index be2282f8fd..0037e7ddf5 100644 --- a/test/basic.css +++ b/test/basic.css @@ -27,5 +27,45 @@ test test:dir(ltr) { } :root :dir(ltr) { - order: 7 + order: 7; +} + +html :dir(ltr) { + order: 8; +} + +:dir(rtl) { + order: 9; +} + +:dir(rtl) test { + order: 10; +} + +test :dir(rtl) { + order: 11; +} + +test :dir(rtl) test { + order: 12; +} + +test:dir(rtl) { + order: 13; +} + +test:dir(rtl) test { + order: 14; +} + +test test:dir(rtl) { + order: 15; +} + +:root :dir(rtl) { + order: 16; +} + +html :dir(rtl) { + order: 17; } diff --git a/test/basic.dir.expect.css b/test/basic.dir.expect.css index 4a11562b4c..b1a24dd696 100644 --- a/test/basic.dir.expect.css +++ b/test/basic.dir.expect.css @@ -1,31 +1,71 @@ -:root { +:not([dir="rtl"]) { order: 0; } -:root test { +:not([dir="rtl"]) test { order: 1; } -:root test * { +:not([dir="rtl"]) test * { order: 2; } -:root test * test { +:not([dir="rtl"]) test * test { order: 3; } -:root test { +:not([dir="rtl"]) test { order: 4; } -:root test test { +:not([dir="rtl"]) test test { order: 5; } -:root test test { +:not([dir="rtl"]) test test { order: 6; } -:root:root * { - order: 7 +:not([dir="rtl"]):root * { + order: 7; +} + +html:not([dir="rtl"]) * { + order: 8; +} + +[dir="rtl"] { + order: 9; +} + +[dir="rtl"] test { + order: 10; +} + +[dir="rtl"] test * { + order: 11; +} + +[dir="rtl"] test * test { + order: 12; +} + +[dir="rtl"] test { + order: 13; +} + +[dir="rtl"] test test { + order: 14; +} + +[dir="rtl"] test test { + order: 15; +} + +[dir="rtl"]:root * { + order: 16; +} + +html[dir="rtl"] * { + order: 17; } diff --git a/test/basic.expect.css b/test/basic.expect.css index 7dae80c413..f1983a2fbf 100644 --- a/test/basic.expect.css +++ b/test/basic.expect.css @@ -27,5 +27,45 @@ } [dir="ltr"]:root * { - order: 7 + order: 7; +} + +html[dir="ltr"] * { + order: 8; +} + +[dir="rtl"] { + order: 9; +} + +[dir="rtl"] test { + order: 10; +} + +[dir="rtl"] test * { + order: 11; +} + +[dir="rtl"] test * test { + order: 12; +} + +[dir="rtl"] test { + order: 13; +} + +[dir="rtl"] test test { + order: 14; +} + +[dir="rtl"] test test { + order: 15; +} + +[dir="rtl"]:root * { + order: 16; +} + +html[dir="rtl"] * { + order: 17; } diff --git a/test/basic.supported.expect.css b/test/basic.supported.expect.css index be2282f8fd..0037e7ddf5 100644 --- a/test/basic.supported.expect.css +++ b/test/basic.supported.expect.css @@ -27,5 +27,45 @@ test test:dir(ltr) { } :root :dir(ltr) { - order: 7 + order: 7; +} + +html :dir(ltr) { + order: 8; +} + +:dir(rtl) { + order: 9; +} + +:dir(rtl) test { + order: 10; +} + +test :dir(rtl) { + order: 11; +} + +test :dir(rtl) test { + order: 12; +} + +test:dir(rtl) { + order: 13; +} + +test:dir(rtl) test { + order: 14; +} + +test test:dir(rtl) { + order: 15; +} + +:root :dir(rtl) { + order: 16; +} + +html :dir(rtl) { + order: 17; } From ef36b0c4cd222464332f8b9292513eb60d18fa49 Mon Sep 17 00:00:00 2001 From: Jonathan Neal Date: Mon, 24 Jul 2017 21:57:25 -0400 Subject: [PATCH 482/795] Update documentation --- README.md | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index b4da5e9f8e..5f8706bfd3 100644 --- a/README.md +++ b/README.md @@ -12,11 +12,19 @@ margin-right: 10px; } +.example:dir(ltr) { + margin-left: 10px; +} + /* becomes */ [dir="rtl"] .example { margin-right: 10px; } + +[dir="ltr"] .example { + margin-left: 10px; +} ``` If your [browserslist] already supports the `:dir` pseudo-class, this plugin @@ -176,7 +184,7 @@ require('postcss-dir-pseudo-class')({ /* becomes */ -:root .example { +:not([dir="rtl"]) .example { margin-left: 10px; } From 8b30b25cb2c2797f7e9e3750d4dccbd73de24a2e Mon Sep 17 00:00:00 2001 From: Jonathan Neal Date: Mon, 24 Jul 2017 21:57:51 -0400 Subject: [PATCH 483/795] Update dependencies --- package.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/package.json b/package.json index 33c4b0385e..48c235d633 100644 --- a/package.json +++ b/package.json @@ -22,12 +22,12 @@ "node": ">=4.0.0" }, "dependencies": { - "browserslist": "^2.1.4", - "postcss": "^6.0.1", + "browserslist": "^2.2.2", + "postcss": "^6.0.8", "postcss-selector-parser": "^2.2.3" }, "devDependencies": { - "eslint": "^3.19.0", + "eslint": "^4.3.0", "eslint-config-dev": "2.0.0", "postcss-tape": "2.0.1", "pre-commit": "^1.2.2" From b725726f0bf31fe543a86c848b165d9c2c0ab600 Mon Sep 17 00:00:00 2001 From: Jonathan Neal Date: Tue, 25 Jul 2017 12:40:29 -0400 Subject: [PATCH 484/795] 2.0.0 --- CHANGELOG.md | 4 ++++ README.md | 16 +++++++++++++--- package.json | 2 +- 3 files changed, 18 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5b2f0290e7..024a47b46e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # Changes to PostCSS :dir() +### 2.0.0 (July 24, 2017) + +- Changed: Method of presumed direction from `:root` to `html:not([dir])` + ### 1.1.0 (June 2, 2017) - Added: Support for browserslist and a 'browsers' option diff --git a/README.md b/README.md index 5f8706bfd3..58df6c9064 100644 --- a/README.md +++ b/README.md @@ -31,9 +31,19 @@ If your [browserslist] already supports the `:dir` pseudo-class, this plugin will not change your CSS. You can learn more this by reading about the [`browsers` option](#browsers-option). -By default, this plugin requires you to specify a direction `[dir]` attribute -in your HTML, preferably on the `html` element. If you prefer not to, you -can presume a direction in your CSS using the [`dir` option](#dir-option). +[PostCSS :dir()] does not change selector weight, but does require at least one +`[dir]` attribute in your HTML. If you don’t have _any_ `[dir]` attributes, +consider using the following JavaScript: + +```js +// force at least one dir attribute (this can run at any time) +document.documentElement.dir=document.documentElement.dir||'ltr'; +``` + +If you absolutely cannot add a `[dir]` attribute in your HTML or force one via +JavaScript, you can still get around this by presuming a direction in your CSS +using the [`dir` option](#dir-option), but know that this will increase +selector weight by one element (`html`). ## Usage diff --git a/package.json b/package.json index 48c235d633..ad76e1e371 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "postcss-dir-pseudo-class", - "version": "1.1.0", + "version": "2.0.0", "description": "Use the :dir pseudo-class in CSS", "author": "Jonathan Neal ", "license": "CC0-1.0", From eb7ee123ce562a24b239c8ae3fee20958ae8f3d5 Mon Sep 17 00:00:00 2001 From: Jonathan Neal Date: Wed, 9 Aug 2017 13:00:41 -0400 Subject: [PATCH 485/795] 1.0.0 --- .appveyor.yml | 18 ++ .editorconfig | 15 ++ .gitignore | 9 + .tape.js | 28 +++ .travis.yml | 9 + CHANGELOG.md | 5 + CONTRIBUTING.md | 65 +++++++ LICENSE.md | 106 +++++++++++ README.md | 193 +++++++++++++++++++ dependent-js/clone-decl.js | 7 + dependent-js/clone-rule.js | 23 +++ dependent-js/match-inset-prefix.js | 1 + dependent-js/match-side.js | 1 + dependent-js/match-size.js | 1 + dependent-js/match-supported-properties.js | 1 + dependent-js/transform-border.js | 210 +++++++++++++++++++++ dependent-js/transform-float.js | 21 +++ dependent-js/transform-inset.js | 29 +++ dependent-js/transform-resize.js | 5 + dependent-js/transform-side.js | 82 ++++++++ dependent-js/transform-size.js | 8 + dependent-js/transform-spacing.js | 30 +++ dependent-js/transform-text-align.js | 21 +++ index.js | 57 ++++++ package.json | 55 ++++++ test/border.css | 52 +++++ test/border.expect.css | 177 +++++++++++++++++ test/float.css | 6 + test/float.expect.css | 16 ++ test/inset.css | 26 +++ test/inset.expect.css | 121 ++++++++++++ test/margin.css | 32 ++++ test/margin.expect.css | 86 +++++++++ test/padding.css | 32 ++++ test/padding.expect.css | 86 +++++++++ test/resize.css | 4 + test/resize.expect.css | 4 + test/size.css | 4 + test/size.expect.css | 4 + test/text-align.css | 6 + test/text-align.expect.css | 16 ++ 41 files changed, 1672 insertions(+) create mode 100644 .appveyor.yml create mode 100644 .editorconfig create mode 100644 .gitignore create mode 100644 .tape.js create mode 100644 .travis.yml create mode 100644 CHANGELOG.md create mode 100644 CONTRIBUTING.md create mode 100644 LICENSE.md create mode 100644 README.md create mode 100644 dependent-js/clone-decl.js create mode 100644 dependent-js/clone-rule.js create mode 100644 dependent-js/match-inset-prefix.js create mode 100644 dependent-js/match-side.js create mode 100644 dependent-js/match-size.js create mode 100644 dependent-js/match-supported-properties.js create mode 100644 dependent-js/transform-border.js create mode 100644 dependent-js/transform-float.js create mode 100644 dependent-js/transform-inset.js create mode 100644 dependent-js/transform-resize.js create mode 100644 dependent-js/transform-side.js create mode 100644 dependent-js/transform-size.js create mode 100644 dependent-js/transform-spacing.js create mode 100644 dependent-js/transform-text-align.js create mode 100644 index.js create mode 100644 package.json create mode 100644 test/border.css create mode 100644 test/border.expect.css create mode 100644 test/float.css create mode 100644 test/float.expect.css create mode 100644 test/inset.css create mode 100644 test/inset.expect.css create mode 100644 test/margin.css create mode 100644 test/margin.expect.css create mode 100644 test/padding.css create mode 100644 test/padding.expect.css create mode 100644 test/resize.css create mode 100644 test/resize.expect.css create mode 100644 test/size.css create mode 100644 test/size.expect.css create mode 100644 test/text-align.css create mode 100644 test/text-align.expect.css diff --git a/.appveyor.yml b/.appveyor.yml new file mode 100644 index 0000000000..d6b511f500 --- /dev/null +++ b/.appveyor.yml @@ -0,0 +1,18 @@ +# https://www.appveyor.com/docs/appveyor-yml + +environment: + matrix: + - nodejs_version: 4.0 + +version: "{build}" +build: off +deploy: off + +install: + - ps: Install-Product node $env:nodejs_version + - npm install --ignore-scripts + +test_script: + - node --version + - npm --version + - cmd: "npm test" diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000000..e06d7982bc --- /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/.gitignore b/.gitignore new file mode 100644 index 0000000000..f8952c957f --- /dev/null +++ b/.gitignore @@ -0,0 +1,9 @@ +node_modules +.* +!.appveyor.yml +!.editorconfig +!.gitignore +!.tape.js +!.travis.yml +*.log* +*.result.css diff --git a/.tape.js b/.tape.js new file mode 100644 index 0000000000..aaaff59d4d --- /dev/null +++ b/.tape.js @@ -0,0 +1,28 @@ +module.exports = { + 'postcss-logical-properties': { + 'border': { + message: 'supports logical "border" property values' + }, + 'float': { + message: 'supports logical "float" property values' + }, + 'inset': { + message: 'supports logical "inset" properties' + }, + 'margin': { + message: 'supports logical "margin" properties' + }, + 'padding': { + message: 'supports logical "padding" properties' + }, + 'resize': { + message: 'supports logical "resize" properties' + }, + 'size': { + message: 'supports logical "size" properties' + }, + 'text-align': { + message: 'supports logical "text-align" properties' + } + } +}; diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000000..c56466446c --- /dev/null +++ b/.travis.yml @@ -0,0 +1,9 @@ +# https://docs.travis-ci.com/user/travis-lint + +language: node_js + +node_js: + - 4 + +install: + - npm install --ignore-scripts diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000000..5bdbfd83a8 --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,5 @@ +# Changes to PostCSS Logical Properties + +### 1.0.0 (Aug 8, 2017) + +- Initial version diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 0000000000..ccd6aea54c --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,65 @@ +# Contributing to PostCSS Logical Properties + +You want to help? You rock! Now, take a moment to be sure your contributions +make sense to everyone else. + +## Reporting Issues + +Found a problem? Want a new feature? + +- See if your issue or idea has [already been reported]. +- Provide a [reduced test case] or a [live example]. + +Remember, a bug is a _demonstrable problem_ caused by _our_ code. + +## Submitting Pull Requests + +Pull requests are the greatest contributions, so be sure they are focused in +scope and avoid unrelated commits. + +1. To begin; [fork this project], clone your fork, and add our upstream. + ```bash + # Clone your fork of the repo into the current directory + git clone git@github.com:YOUR_USER/postcss-logical-properties.git + + # Navigate to the newly cloned directory + cd postcss-logical-properties + + # Assign the original repo to a remote called "upstream" + git remote add upstream git@github.com:jonathantneal/postcss-logical-properties.git + + # Install the tools necessary for testing + npm install + ``` + +2. Create a branch for your feature or fix: + ```bash + # Move into a new branch for your feature + git checkout -b feature/thing + ``` + ```bash + # Move into a new branch for your fix + git checkout -b fix/something + ``` + +3. If your code follows our practices, then push your feature branch: + ```bash + # Test current code + npm test + ``` + ```bash + # Push the branch for your new feature + git push origin feature/thing + ``` + ```bash + # Or, push the branch for your update + git push origin update/something + ``` + +That’s it! Now [open a pull request] with a clear title and description. + +[already been reported]: issues +[fork this project]: fork +[live example]: https://codepen.io/pen +[open a pull request]: https://help.github.com/articles/using-pull-requests/ +[reduced test case]: https://css-tricks.com/reduced-test-cases/ diff --git a/LICENSE.md b/LICENSE.md new file mode 100644 index 0000000000..b5bc55c9f6 --- /dev/null +++ b/LICENSE.md @@ -0,0 +1,106 @@ +# CC0 1.0 Universal + +## Statement of Purpose + +The laws of most jurisdictions throughout the world automatically confer +exclusive Copyright and Related Rights (defined below) upon the creator and +subsequent owner(s) (each and all, an “owner”) of an original work of +authorship and/or a database (each, a “Work”). + +Certain owners wish to permanently relinquish those rights to a Work for the +purpose of contributing to a commons of creative, cultural and scientific works +(“Commons”) that the public can reliably and without fear of later claims of +infringement build upon, modify, incorporate in other works, reuse and +redistribute as freely as possible in any form whatsoever and for any purposes, +including without limitation commercial purposes. These owners may contribute +to the Commons to promote the ideal of a free culture and the further +production of creative, cultural and scientific works, or to gain reputation or +greater distribution for their Work in part through the use and efforts of +others. + +For these and/or other purposes and motivations, and without any expectation of +additional consideration or compensation, the person associating CC0 with a +Work (the “Affirmer”), to the extent that he or she is an owner of Copyright +and Related Rights in the Work, voluntarily elects to apply CC0 to the Work and +publicly distribute the Work under its terms, with knowledge of his or her +Copyright and Related Rights in the Work and the meaning and intended legal +effect of CC0 on those rights. + +1. Copyright and Related Rights. A Work made available under CC0 may be + protected by copyright and related or neighboring rights (“Copyright and + Related Rights”). Copyright and Related Rights include, but are not limited + to, the following: + 1. the right to reproduce, adapt, distribute, perform, display, + communicate, and translate a Work; + 2. moral rights retained by the original author(s) and/or performer(s); + 3. publicity and privacy rights pertaining to a person’s image or likeness + depicted in a Work; + 4. rights protecting against unfair competition in regards to a Work, + subject to the limitations in paragraph 4(i), below; + 5. rights protecting the extraction, dissemination, use and reuse of data + in a Work; + 6. database rights (such as those arising under Directive 96/9/EC of the + European Parliament and of the Council of 11 March 1996 on the legal + protection of databases, and under any national implementation thereof, + including any amended or successor version of such directive); and + 7. other similar, equivalent or corresponding rights throughout the world + based on applicable law or treaty, and any national implementations + thereof. + +2. Waiver. To the greatest extent permitted by, but not in contravention of, +applicable law, Affirmer hereby overtly, fully, permanently, irrevocably and +unconditionally waives, abandons, and surrenders all of Affirmer’s Copyright +and Related Rights and associated claims and causes of action, whether now +known or unknown (including existing as well as future claims and causes of +action), in the Work (i) in all territories worldwide, (ii) for the maximum +duration provided by applicable law or treaty (including future time +extensions), (iii) in any current or future medium and for any number of +copies, and (iv) for any purpose whatsoever, including without limitation +commercial, advertising or promotional purposes (the “Waiver”). Affirmer makes +the Waiver for the benefit of each member of the public at large and to the +detriment of Affirmer’s heirs and successors, fully intending that such Waiver +shall not be subject to revocation, rescission, cancellation, termination, or +any other legal or equitable action to disrupt the quiet enjoyment of the Work +by the public as contemplated by Affirmer’s express Statement of Purpose. + +3. Public License Fallback. Should any part of the Waiver for any reason be +judged legally invalid or ineffective under applicable law, then the Waiver +shall be preserved to the maximum extent permitted taking into account +Affirmer’s express Statement of Purpose. In addition, to the extent the Waiver +is so judged Affirmer hereby grants to each affected person a royalty-free, non +transferable, non sublicensable, non exclusive, irrevocable and unconditional +license to exercise Affirmer’s Copyright and Related Rights in the Work (i) in +all territories worldwide, (ii) for the maximum duration provided by applicable +law or treaty (including future time extensions), (iii) in any current or +future medium and for any number of copies, and (iv) for any purpose +whatsoever, including without limitation commercial, advertising or promotional +purposes (the “License”). The License shall be deemed effective as of the date +CC0 was applied by Affirmer to the Work. Should any part of the License for any +reason be judged legally invalid or ineffective under applicable law, such +partial invalidity or ineffectiveness shall not invalidate the remainder of the +License, and in such case Affirmer hereby affirms that he or she will not (i) +exercise any of his or her remaining Copyright and Related Rights in the Work +or (ii) assert any associated claims and causes of action with respect to the +Work, in either case contrary to Affirmer’s express Statement of Purpose. + +4. Limitations and Disclaimers. + 1. No trademark or patent rights held by Affirmer are waived, abandoned, + surrendered, licensed or otherwise affected by this document. + 2. Affirmer offers the Work as-is and makes no representations or + warranties of any kind concerning the Work, express, implied, statutory + or otherwise, including without limitation warranties of title, + merchantability, fitness for a particular purpose, non infringement, or + the absence of latent or other defects, accuracy, or the present or + absence of errors, whether or not discoverable, all to the greatest + extent permissible under applicable law. + 3. Affirmer disclaims responsibility for clearing rights of other persons + that may apply to the Work or any use thereof, including without + limitation any person’s Copyright and Related Rights in the Work. + Further, Affirmer disclaims responsibility for obtaining any necessary + consents, permissions or other rights required for any use of the Work. + 4. Affirmer understands and acknowledges that Creative Commons is not a + party to this document and has no duty or obligation with respect to + this CC0 or use of the Work. + +For more information, please see +https://creativecommons.org/publicdomain/zero/1.0/. diff --git a/README.md b/README.md new file mode 100644 index 0000000000..448fdadc0e --- /dev/null +++ b/README.md @@ -0,0 +1,193 @@ +# PostCSS Logical Properties [PostCSS Logo][postcss] + +[![NPM Version][npm-img]][npm-url] +[![Linux Build Status][cli-img]][cli-url] +[![Windows Build Status][win-img]][win-url] +[![Gitter Chat][git-img]][git-url] + +[PostCSS Logical Properties] lets you use nearly 60 new [logical properties] +and a half dozen flow-relative values in CSS. + +```css +.banner { + color: #222222; + inset: logical 0 5px 10px; + padding-inline: 20px 40px; + resize: block; +} + +/* used alongside postcss-nesting, postcss-dir-pseudo-class */ + +.banner { + color: #222222; + top: 0; left: 5px; bottom: 10px; right: 5px; +} + +[dir="ltr"] .banner { + padding-left: 20px; padding-right: 40px; +} + +[dir="rtl"] .banner { + padding-right: 20px; padding-left: 40px; +} + +.banner { + resize: vertical; +} +``` + +These shorthand properties set values for physical properties by default. +Specifying the `logical` keyboard at the beginning of the property value will +transform the flow-relative values afterward into both physical LTR and RTL +properties: + +#### Logical Borders + +- `border`, `border-block`, `border-block-start`, `border-block-end`, + `border-inline`, `border-inline-start`, `border-inline-end`, `border-start`, + `border-end`, `border-color`, `border-block-color`, + `border-block-start-color`, `border-block-end-color`, `border-inline-color`, + `border-inline-start-color`, `border-inline-end-color`, `border-start-color`, + `border-end-color`, `border-style`, `border-block-style`, + `border-block-start-style`, `border-block-end-style`, `border-inline-style`, + `border-inline-start-style`, `border-inline-end-style`, `border-start-style`, + `border-end-style`, `border-width`, `border-block-width`, + `border-block-start-width`, `border-block-end-width`, `border-inline-width`, + `border-inline-start-width`, `border-inline-end-width`, `border-start-width`, + `border-end-width` + +#### Logical Offsets + +- `inset`, `inset-block`, `inset-block-start`, `inset-block-end`, + `inset-inline`, `inset-inline-start`, `inset-inline-end`, `inset-start`, + `inset-end` + +#### Logical Margins + +- `margin`, `margin-block`, `margin-block-start`, `margin-block-end`, + `margin-inline`, `margin-inline-start`, `margin-inline-end`, `margin-start`, + `margin-end` + +#### Logical Paddings + +- `padding`, `padding-block`, `padding-block-start`, `padding-block-end`, + `padding-inline`, `padding-inline-start`, `padding-inline-end`, + `padding-start`, `padding-end` + +#### Logical Sizes + +- `block-size`, `inline-size` + +#### Flow-Relative Values + +- `float: inline-start`, `float: inline-end`, `text-align: start`, + `text-align: end` + +--- + +[PostCSS Logical Properties] changes the selector weight of flow-relative +declarations and requires at least one [dir] attribute in your HTML. If you +don’t have any [dir] attributes, consider using the following JavaScript: + +```js +// force at least one dir attribute (this can run at any time) +document.documentElement.dir=document.documentElement.dir||'ltr'; +``` + +## Usage + +Add [PostCSS Logical Properties] to your build tool: + +```bash +npm install postcss-logical --save-dev +``` + +#### Node + +Use [PostCSS Logical Properties] to process your CSS: + +```js +require('postcss-logical').process(YOUR_CSS); +``` + +#### PostCSS + +Add [PostCSS] to your build tool: + +```bash +npm install postcss --save-dev +``` + +Use [PostCSS Logical Properties] as a plugin: + +```js +postcss([ + require('postcss-logical')() +]).process(YOUR_CSS); +``` + +#### Gulp + +Add [Gulp PostCSS] to your build tool: + +```bash +npm install gulp-postcss --save-dev +``` + +Use [PostCSS Logical Properties] in your Gulpfile: + +```js +var postcss = require('gulp-postcss'); + +gulp.task('css', function () { + return gulp.src('./src/*.css').pipe( + postcss([ + require('postcss-logical')() + ]) + ).pipe( + gulp.dest('.') + ); +}); +``` + +#### Grunt + +Add [Grunt PostCSS] to your build tool: + +```bash +npm install grunt-postcss --save-dev +``` + +Use [PostCSS Logical Properties] in your Gruntfile: + +```js +grunt.loadNpmTasks('grunt-postcss'); + +grunt.initConfig({ + postcss: { + options: { + use: [ + require('postcss-logical')() + ] + }, + dist: { + src: '*.css' + } + } +}); +``` + +[npm-url]: https://www.npmjs.com/package/postcss-logical +[npm-img]: https://img.shields.io/npm/v/postcss-logical.svg +[cli-url]: https://travis-ci.org/jonathantneal/postcss-logical-properties +[cli-img]: https://img.shields.io/travis/jonathantneal/postcss-logical-properties.svg +[win-url]: https://ci.appveyor.com/project/jonathantneal/postcss-logical-properties +[win-img]: https://img.shields.io/appveyor/ci/jonathantneal/postcss-logical-properties.svg +[git-url]: https://gitter.im/postcss/postcss +[git-img]: https://img.shields.io/badge/chat-gitter-blue.svg + +[PostCSS Logical Properties]: https://github.com/jonathantneal/postcss-logical-properties +[logical properties]: https://drafts.csswg.org/css-logical/ +[PostCSS]: https://github.com/postcss/postcss +[Gulp PostCSS]: https://github.com/postcss/gulp-postcss +[Grunt PostCSS]: https://github.com/nDmitry/grunt-postcss diff --git a/dependent-js/clone-decl.js b/dependent-js/clone-decl.js new file mode 100644 index 0000000000..06e2a12faa --- /dev/null +++ b/dependent-js/clone-decl.js @@ -0,0 +1,7 @@ +const matchSide = require('./match-side'); +const matchInsetPrefix = require('./match-inset-prefix'); + +module.exports = (decl, suffix, value) => decl.clone({ + prop: `${decl.prop.replace(matchSide, '$1')}${suffix}`.replace(matchInsetPrefix, ''), + value +}); diff --git a/dependent-js/clone-rule.js b/dependent-js/clone-rule.js new file mode 100644 index 0000000000..032213bfb3 --- /dev/null +++ b/dependent-js/clone-rule.js @@ -0,0 +1,23 @@ +'use strict'; + +const postcss = require('postcss'); + +module.exports = (decl, dir) => { + let node = decl.parent; + + while (node && 'rule' !== node.type) { + node = node.parent; + } + + if (node) { + node = node.clone({ + raws: {} + }).removeAll() + } else { + node = postcss.rule(); + } + + node.selector = `&:dir(${dir})`; + + return node; +}; diff --git a/dependent-js/match-inset-prefix.js b/dependent-js/match-inset-prefix.js new file mode 100644 index 0000000000..0a6c302778 --- /dev/null +++ b/dependent-js/match-inset-prefix.js @@ -0,0 +1 @@ +module.exports = /^inset-/i; diff --git a/dependent-js/match-side.js b/dependent-js/match-side.js new file mode 100644 index 0000000000..285a554053 --- /dev/null +++ b/dependent-js/match-side.js @@ -0,0 +1 @@ +module.exports = /^(inset|margin|padding)(?:-(block|block-start|block-end|inline|inline-start|inline-end|start|end))$/i; diff --git a/dependent-js/match-size.js b/dependent-js/match-size.js new file mode 100644 index 0000000000..1514b4cd61 --- /dev/null +++ b/dependent-js/match-size.js @@ -0,0 +1 @@ +module.exports = /^(min-|max-)?(block|inline)-(size)$/i; diff --git a/dependent-js/match-supported-properties.js b/dependent-js/match-supported-properties.js new file mode 100644 index 0000000000..8c9eeb8c31 --- /dev/null +++ b/dependent-js/match-supported-properties.js @@ -0,0 +1 @@ +module.exports = /^(?:(inset|margin|padding)(?:-(block|block-start|block-end|inline|inline-start|inline-end|start|end))|(min-|max-)?(block|inline)-(size))$/i; diff --git a/dependent-js/transform-border.js b/dependent-js/transform-border.js new file mode 100644 index 0000000000..b2d7530562 --- /dev/null +++ b/dependent-js/transform-border.js @@ -0,0 +1,210 @@ +const cloneRule = require('./clone-rule'); + +const matchLogical = /^\s*logical\s+/i; +const matchLogicalBorder = /^border(-width|-style|-color)?$/i; +const matchLogicalBorderSide = /^border-(?:(width|style|color)-)?(block|block-start|block-end|inline|inline-start|inline-end|start|end)/i; + +// border +module.exports['border'] = (decl, values) => { + const isLogical = matchLogical.test(values[0]); + + if (isLogical) { + values[0] = values[0].replace(matchLogical, ''); + } + + return isLogical ? 1 === values.length + ? decl.clone({ + value: decl.value.replace(matchLogical, '') + }) + : !values[3] || values[3] === values[1] + ? [ + decl.clone({ + prop: `border-top${decl.prop.replace(matchLogicalBorder, '$1')}`, + value: values[0] + }), + decl.clone({ + prop: `border-right${decl.prop.replace(matchLogicalBorder, '$1')}`, + value: values[3] || values[1] || values[0] + }), + decl.clone({ + prop: `border-bottom${decl.prop.replace(matchLogicalBorder, '$1')}`, + value: values[2] || values[0] + }), + decl.clone({ + prop: `border-left${decl.prop.replace(matchLogicalBorder, '$1')}`, + value: values[1] || values[0] + }) + ] + : [ + cloneRule(decl, 'ltr').append([ + decl.clone({ + prop: `border-top${decl.prop.replace(matchLogicalBorder, '$1')}`, + value: values[0] + }), + decl.clone({ + prop: `border-left${decl.prop.replace(matchLogicalBorder, '$1')}`, + value: values[1] || values[0] + }), + decl.clone({ + prop: `border-bottom${decl.prop.replace(matchLogicalBorder, '$1')}`, + value: values[2] || values[0] + }), + decl.clone({ + prop: `border-right${decl.prop.replace(matchLogicalBorder, '$1')}`, + value: values[3] || values[1] || values[0] + }) + ]), + cloneRule(decl, 'rtl').append([ + decl.clone({ + prop: `border-top${decl.prop.replace(matchLogicalBorder, '$1')}`, + value: values[0] + }), + decl.clone({ + prop: `border-right${decl.prop.replace(matchLogicalBorder, '$1')}`, + value: values[1] || values[0] + }), + decl.clone({ + prop: `border-bottom${decl.prop.replace(matchLogicalBorder, '$1')}`, + value: values[2] || values[0] + }), + decl.clone({ + prop: `border-left${decl.prop.replace(matchLogicalBorder, '$1')}`, + value: values[3] || values[1] || values[0] + }) + ]) + ] + : null; +}; + + +// border-block +module.exports['border-block'] = (decl, values) => [ + decl.clone({ + prop: `border-top${decl.prop.replace(matchLogicalBorderSide, '$1')}`, + value: values[0] + }), + decl.clone({ + prop: `border-bottom${decl.prop.replace(matchLogicalBorderSide, '$1')}`, + value: values[0] + }) +]; + +// border-block-start +module.exports['border-block-start'] = (decl) => { + decl.prop = 'border-top'; +}; + +// border-block-end +module.exports['border-block-end'] = (decl) => { + decl.prop = 'border-bottom'; +}; + +// border-inline +module.exports['border-inline'] = (decl, values) => 1 === values.length || 2 === values.length && values[0] === values[1] +? [ + decl.clone({ + prop: `border-left${decl.prop.replace(matchLogicalBorderSide, '$1')}`, + value: values[0] + }), + decl.clone({ + prop: `border-right${decl.prop.replace(matchLogicalBorderSide, '$1')}`, + value: values[1] || values[0] + }) +] +: [ + cloneRule(decl, 'ltr').append([ + decl.clone({ + prop: `border-left${decl.prop.replace(matchLogicalBorderSide, '$1')}`, + value: values[0] + }), + decl.clone({ + prop: `border-right${decl.prop.replace(matchLogicalBorderSide, '$1')}`, + value: values[1] || values[0] + }) + ]), + cloneRule(decl, 'rtl').append([ + decl.clone({ + prop: `border-right${decl.prop.replace(matchLogicalBorderSide, '$1')}`, + value: values[0] + }), + decl.clone({ + prop: `border-left${decl.prop.replace(matchLogicalBorderSide, '$1')}`, + value: values[1] || values[0] + }) + ]) +]; + +// border-inline-start +module.exports['border-inline-start'] = (decl) => [ + cloneRule(decl, 'ltr').append( + decl.clone({ + prop: `border-left${decl.prop.replace(matchLogicalBorderSide, '$1')}` + }) + ), + cloneRule(decl, 'rtl').append( + decl.clone({ + prop: `border-right${decl.prop.replace(matchLogicalBorderSide, '$1')}` + }) + ) +]; + +// border-inline-end +module.exports['border-inline-end'] = (decl) => [ + cloneRule(decl, 'ltr').append( + decl.clone({ + prop: `border-right${decl.prop.replace(matchLogicalBorderSide, '$1')}` + }) + ), + cloneRule(decl, 'rtl').append( + decl.clone({ + prop: `border-left${decl.prop.replace(matchLogicalBorderSide, '$1')}` + }) + ) +]; + +// border-start +module.exports['border-start'] = (decl, values) => [ + cloneRule(decl, 'ltr').append([ + decl.clone({ + prop: `border-top${decl.prop.replace(matchLogicalBorderSide, '$1')}`, + value: values[0] + }), + decl.clone({ + prop: `border-left${decl.prop.replace(matchLogicalBorderSide, '$1')}`, + value: values[1] || values[0] + }) + ]), + cloneRule(decl, 'rtl').append([ + decl.clone({ + prop: `border-top${decl.prop.replace(matchLogicalBorderSide, '$1')}`, + value: values[0] + }), + decl.clone({ + prop: `border-right${decl.prop.replace(matchLogicalBorderSide, '$1')}`, + value: values[1] || values[0] + }) + ]) +]; + +// border-end +module.exports['border-end'] = (decl, values) => [ + cloneRule(decl, 'ltr').append([decl.clone({ + prop: `border-bottom${decl.prop.replace(matchLogicalBorderSide, '$1')}`, + value: values[0] + }), + decl.clone({ + prop: `border-right${decl.prop.replace(matchLogicalBorderSide, '$1')}`, + value: values[1] || values[0] + }) + ]), + cloneRule(decl, 'rtl').append([ + decl.clone({ + prop: `border-bottom${decl.prop.replace(matchLogicalBorderSide, '$1')}`, + value: values[0] + }), + decl.clone({ + prop: `border-left${decl.prop.replace(matchLogicalBorderSide, '$1')}`, + value: values[1] || values[0] + }) + ]) +]; diff --git a/dependent-js/transform-float.js b/dependent-js/transform-float.js new file mode 100644 index 0000000000..8b1be7e611 --- /dev/null +++ b/dependent-js/transform-float.js @@ -0,0 +1,21 @@ +const cloneRule = require('./clone-rule'); + +module.exports = (decl) => /^inline-start$/i.test(decl.value) + ? [ + cloneRule(decl, 'ltr').append([ + decl.clone({ value: 'left' }) + ]), + cloneRule(decl, 'rtl').append([ + decl.clone({ value: 'right' }) + ]) + ] + : /^inline-end$/i.test(decl.value) + ? [ + cloneRule(decl, 'ltr').append([ + decl.clone({ value: 'right' }) + ]), + cloneRule(decl, 'rtl').append([ + decl.clone({ value: 'left' }) + ]) + ] + : null; diff --git a/dependent-js/transform-inset.js b/dependent-js/transform-inset.js new file mode 100644 index 0000000000..e4ce88d7ea --- /dev/null +++ b/dependent-js/transform-inset.js @@ -0,0 +1,29 @@ +const cloneRule = require('./clone-rule'); + +module.exports = (decl, values) => 'logical' === values[0] + ? !values[4] || values[2] === values[4] + ? [ + decl.clone({ prop: 'top', value: values[1] }), + decl.clone({ prop: 'left', value: values[2] || values[1] }), + decl.clone({ prop: 'bottom', value: values[3] || values[1] }), + decl.clone({ prop: 'right', value: values[4] || values[2] || values[1] }) + ] : [ + cloneRule(decl, 'ltr').append([ + decl.clone({ prop: 'top', value: values[1] }), + decl.clone({ prop: 'left', value: values[2] || values[1] }), + decl.clone({ prop: 'bottom', value: values[3] || values[1] }), + decl.clone({ prop: 'right', value: values[4] || values[2] || values[1] }) + ]), + cloneRule(decl, 'rtl').append([ + decl.clone({ prop: 'top', value: values[1] }), + decl.clone({ prop: 'right', value: values[2] || values[1] }), + decl.clone({ prop: 'bottom', value: values[3] || values[1] }), + decl.clone({ prop: 'left', value: values[4] || values[2] || values[1] }) + ]) + ] + : [ + decl.clone({ prop: 'top', value: values[0] }), + decl.clone({ prop: 'right', value: values[1] || values[0] }), + decl.clone({ prop: 'bottom', value: values[2] || values[0] }), + decl.clone({ prop: 'left', value: values[3] || values[1] || values[0] }) + ]; diff --git a/dependent-js/transform-resize.js b/dependent-js/transform-resize.js new file mode 100644 index 0000000000..d48aa04350 --- /dev/null +++ b/dependent-js/transform-resize.js @@ -0,0 +1,5 @@ +module.exports = (decl) => /^block$/i.test(decl.value) + ? decl.clone({ value: 'vertical' }) + : /^inline$/i.test(decl.value) + ? decl.clone({ value: 'horizontal' }) + : null; diff --git a/dependent-js/transform-side.js b/dependent-js/transform-side.js new file mode 100644 index 0000000000..c4a8b0b03e --- /dev/null +++ b/dependent-js/transform-side.js @@ -0,0 +1,82 @@ +const cloneDecl = require('./clone-decl'); +const cloneRule = require('./clone-rule'); +const matchSide = require('./match-side'); + +const matchInsetPrefix = require('./match-inset-prefix'); + +// inset-block, margin-block, padding-block +module.exports['block'] = (decl, values) => [ + cloneDecl(decl, '-top', values[0]), + cloneDecl(decl, '-bottom', values[1] || values[0]) +]; + +// inset-block-start, margin-block-start, padding-block-start +module.exports['block-start'] = (decl) => { + decl.prop = decl.prop.replace(matchSide, '$1-top').replace(matchInsetPrefix, ''); +}; + +// inset-block-end, margin-block-end, padding-block-end +module.exports['block-end'] = (decl) => { + decl.prop = decl.prop.replace(matchSide, '$1-bottom').replace(matchInsetPrefix, ''); +}; + +// inset-inline, margin-inline, padding-inline +module.exports['inline'] = (decl, values) => 1 === values.length || 2 === values.length && values[0] === values[1] +? [ + cloneDecl(decl, '-left', values[0]), + cloneDecl(decl, '-right', values[1] || values[0]) +] +: [ + cloneRule(decl, 'ltr').append([ + cloneDecl(decl, '-left', values[0]), + cloneDecl(decl, '-right', values[1] || values[0]) + ]), + cloneRule(decl, 'rtl').append([ + cloneDecl(decl, '-right', values[0]), + cloneDecl(decl, '-left', values[1] || values[0]) + ]), +]; + +// inset-inline-start, margin-inline-start, padding-inline-start +module.exports['inline-start'] = (decl) => [ + cloneRule(decl, 'ltr').append( + cloneDecl(decl, '-left', decl.value) + ), + cloneRule(decl, 'rtl').append( + cloneDecl(decl, '-right', decl.value) + ) +]; + +// inset-inline-end, margin-inline-end, padding-inline-end +module.exports['inline-end'] = (decl) => [ + cloneRule(decl, 'ltr').append( + cloneDecl(decl, '-right', decl.value) + ), + cloneRule(decl, 'rtl').append( + cloneDecl(decl, '-left', decl.value) + ) +]; + +// inset-start, margin-start, padding-start +module.exports['start'] = (decl, values) => [ + cloneRule(decl, 'ltr').append([ + cloneDecl(decl, '-top', values[0]), + cloneDecl(decl, '-left', values[1] || values[0]) + ]), + cloneRule(decl, 'rtl').append([ + cloneDecl(decl, '-top', values[0]), + cloneDecl(decl, '-right', values[1] || values[0]) + ]) +]; + +// inset-end, margin-end, padding-end +module.exports['end'] = (decl, values) => [ + cloneRule(decl, 'ltr').append([ + cloneDecl(decl, '-bottom', values[0]), + cloneDecl(decl, '-right', values[1] || values[0]) + ]), + cloneRule(decl, 'rtl').append([ + cloneDecl(decl, '-bottom', values[0]), + cloneDecl(decl, '-left', values[1] || values[0]) + ]) +]; diff --git a/dependent-js/transform-size.js b/dependent-js/transform-size.js new file mode 100644 index 0000000000..17c89b39b1 --- /dev/null +++ b/dependent-js/transform-size.js @@ -0,0 +1,8 @@ +const matchSize = require('./match-size'); + +module.exports = (decl) => { + decl.prop = decl.prop.replace( + matchSize, + ($0, minmax, flow) => `${minmax||''}${'block' === flow ? 'height' : 'width'}` + ); +}; diff --git a/dependent-js/transform-spacing.js b/dependent-js/transform-spacing.js new file mode 100644 index 0000000000..cbe4d4d830 --- /dev/null +++ b/dependent-js/transform-spacing.js @@ -0,0 +1,30 @@ +const cloneRule = require('./clone-rule'); + +module.exports = (decl, values) => 'logical' === values[0] + ? !values[4] || values[4] === values[2] + ? decl.clone({ + value: decl.value.replace(/^\s*logical\s+/i, '') + }) + : [ + cloneRule(decl, 'ltr').append( + decl.clone({ + value: [ + values[1], + values[4] || values[2] || values[1], + values[3] || values[1], + values[2] || values[1] + ].join(' ') + }) + ), + cloneRule(decl, 'rtl').append( + decl.clone({ + value: [ + values[1], + values[2] || values[1], + values[3] || values[1], + values[4] || values[2] || values[1] + ].join(' ') + }) + ) + ] + : null; diff --git a/dependent-js/transform-text-align.js b/dependent-js/transform-text-align.js new file mode 100644 index 0000000000..7dc40d3020 --- /dev/null +++ b/dependent-js/transform-text-align.js @@ -0,0 +1,21 @@ +const cloneRule = require('./clone-rule'); + +module.exports = (decl) => /^start$/i.test(decl.value) + ? [ + cloneRule(decl, 'ltr').append([ + decl.clone({ value: 'left' }) + ]), + cloneRule(decl, 'rtl').append([ + decl.clone({ value: 'right' }) + ]) + ] + : /^end$/i.test(decl.value) + ? [ + cloneRule(decl, 'ltr').append([ + decl.clone({ value: 'right' }) + ]), + cloneRule(decl, 'rtl').append([ + decl.clone({ value: 'left' }) + ]) + ] + : null; diff --git a/index.js b/index.js new file mode 100644 index 0000000000..de65b864cc --- /dev/null +++ b/index.js @@ -0,0 +1,57 @@ +// tooling +const postcss = require('postcss'); + +// internal tooling +const transformBorder = require('./dependent-js/transform-border'); +const transformFloat = require('./dependent-js/transform-float'); +const transformInset = require('./dependent-js/transform-inset'); +const transformResize = require('./dependent-js/transform-resize'); +const transformSide = require('./dependent-js/transform-side'); +const transformSize = require('./dependent-js/transform-size'); +const transformSpacing = require('./dependent-js/transform-spacing'); +const transformTextAlign = require('./dependent-js/transform-text-align'); +const matchSupportedProperties = require('./dependent-js/match-supported-properties'); + +// supported transforms +const transforms = { + 'border': transformBorder['border'], 'border-width': transformBorder['border'], 'border-style': transformBorder['border'], 'border-color': transformBorder['border'], + 'border-block': transformBorder['border-block'], 'border-block-width': transformBorder['border-block'], 'border-block-style': transformBorder['border-block'], 'border-block-color': transformBorder['border-block'], + 'border-block-start': transformBorder['border-block-start'], 'border-block-start-width': transformBorder['border-block-start'], 'border-block-start-style': transformBorder['border-block-start'], 'border-block-start-color': transformBorder['border-block-start'], + 'border-block-end': transformBorder['border-block-end'], 'border-block-end-width': transformBorder['border-block-end'], 'border-block-end-style': transformBorder['border-block-end'], 'border-block-end-color': transformBorder['border-block-end'], + 'border-inline': transformBorder['border-inline'], 'border-inline-width': transformBorder['border-inline'], 'border-inline-style': transformBorder['border-inline'], 'border-inline-color': transformBorder['border-inline'], + 'border-inline-start': transformBorder['border-inline-start'], 'border-inline-start-width': transformBorder['border-inline-start'], 'border-inline-start-style': transformBorder['border-inline-start'], 'border-inline-start-color': transformBorder['border-inline-start'], + 'border-inline-end': transformBorder['border-inline-end'], 'border-inline-end-width': transformBorder['border-inline-end'], 'border-inline-end-style': transformBorder['border-inline-end'], 'border-inline-end-color': transformBorder['border-inline-end'], + 'border-start': transformBorder['border-start'], 'border-start-width': transformBorder['border-start'], 'border-start-style': transformBorder['border-start'], 'border-start-color': transformBorder['border-start'], + 'border-end': transformBorder['border-end'], 'border-end-width': transformBorder['border-end'], 'border-end-style': transformBorder['border-end'], 'border-end-color': transformBorder['border-end'], + 'inset': transformInset, + 'margin': transformSpacing, + 'padding': transformSpacing, + 'block': transformSide['block'], + 'block-start': transformSide['block-start'], + 'block-end': transformSide['block-end'], + 'inline': transformSide['inline'], + 'inline-start': transformSide['inline-start'], + 'inline-end': transformSide['inline-end'], + 'start': transformSide['start'], + 'end': transformSide['end'], + 'float': transformFloat, + 'resize': transformResize, + 'size': transformSize, + 'text-align': transformTextAlign +}; + +// plugin +module.exports = postcss.plugin('postcss-logical-properties', () => (root) => { + root.walkDecls((decl) => { + const values = postcss.list.split(decl.value, /^border/i.test(decl.prop) ? '/' : ' '); + const prop = decl.prop.replace(matchSupportedProperties, '$2$5').toLowerCase(); + + if (prop in transforms) { + const replacer = transforms[prop](decl, values); + + if (replacer) { + decl.replaceWith(replacer); + } + } + }); +}); diff --git a/package.json b/package.json new file mode 100644 index 0000000000..c78ef9ae86 --- /dev/null +++ b/package.json @@ -0,0 +1,55 @@ +{ + "name": "postcss-logical", + "version": "1.0.0", + "description": "Use logical properties and flow-relative values in CSS", + "author": "Jonathan Neal ", + "license": "CC0-1.0", + "repository": "jonathantneal/postcss-logical-properties", + "homepage": "https://github.com/jonathantneal/postcss-logical-properties#readme", + "bugs": "https://github.com/jonathantneal/postcss-logical-properties/issues", + "main": "index.js", + "files": [ + "index.js", + "dependent-js" + ], + "scripts": { + "clean": "git clean -X -d -f", + "prepublish": "npm test", + "test": "echo 'Running tests...'; npm run test:js && npm run test:tape", + "test:js": "eslint *.js --cache --ignore-pattern .gitignore", + "test:tape": "postcss-tape" + }, + "engines": { + "node": ">=4.0.0" + }, + "dependencies": { + "postcss": "^6.0.8" + }, + "devDependencies": { + "eslint": "^4.3.0", + "eslint-config-dev": "2.0.0", + "postcss-tape": "2.0.1", + "pre-commit": "^1.2.2" + }, + "eslintConfig": { + "extends": "dev" + }, + "keywords": [ + "postcss", + "css", + "postcss-plugin", + "logical", + "flow", + "relative", + "ltr", + "rtl", + "properties", + "values", + "directions", + "dirs", + "inline", + "block", + "start", + "end" + ] +} diff --git a/test/border.css b/test/border.css new file mode 100644 index 0000000000..08341b05be --- /dev/null +++ b/test/border.css @@ -0,0 +1,52 @@ +test-border { + border: logical 1px solid black; + border: logical 2px solid black / 3px solid black; + border: logical 4px solid black / 5px solid black / 6px solid black; + border: logical 7px solid black / 8px solid black / 9px solid black / 8px solid black; + border-inline: 10px solid black; + border-inline: 11px solid black / 11px solid black; + border-block: 12px solid black; + border-block: 13px solid black / 14px solid black; + border-block-start: 15px solid black; + border-block-end: 16px solid black; +} + +test-flowing-border { + border: inherit; + border: logical 1px solid black / 2px solid black / 3px solid black / 4px solid black; + border: inherit; + border-inline: 5px solid black / 6px solid black; + border: inherit; + border-inline-start: 7px solid black; + border: inherit; + border-inline-end: 8px solid black; + border: inherit; + border-start: 9px solid black; + border: inherit; + border-start: 10px solid black / 11px solid black; + border: inherit; + border-end: 12px solid black; + border: inherit; + border-end: 13px solid black / 14px solid black; + border: inherit; +} + +test-flowing-border-color { + border-color: inherit; + border-color: logical 1px solid black / 2px solid black / 3px solid black / 4px solid black; + border-color: inherit; + border-inline-color: 5px solid black / 6px solid black; + border-color: inherit; + border-inline-start-color: 7px solid black; + border-color: inherit; + border-inline-end-color: 8px solid black; + border-color: inherit; + border-start-color: 9px solid black; + border-color: inherit; + border-start-color: 10px solid black / 11px solid black; + border-color: inherit; + border-end-color: 12px solid black; + border-color: inherit; + border-end-color: 13px solid black / 14px solid black; + border-color: inherit; +} diff --git a/test/border.expect.css b/test/border.expect.css new file mode 100644 index 0000000000..0d9d5c0c1b --- /dev/null +++ b/test/border.expect.css @@ -0,0 +1,177 @@ +test-border { + border: 1px solid black; + border-top: 2px solid black; + border-right: 3px solid black; + border-bottom: 2px solid black; + border-left: 3px solid black; + border-top: 4px solid black; + border-right: 5px solid black; + border-bottom: 6px solid black; + border-left: 5px solid black; + border-top: 7px solid black; + border-right: 8px solid black; + border-bottom: 9px solid black; + border-left: 8px solid black; + border-left: 10px solid black; + border-right: 10px solid black; + border-left: 11px solid black; + border-right: 11px solid black; + border-top: 12px solid black; + border-bottom: 12px solid black; + border-top: 13px solid black; + border-bottom: 13px solid black; + border-top: 15px solid black; + border-bottom: 16px solid black; +} + +test-flowing-border { + border: inherit; + &:dir(ltr) { + border-top: 1px solid black; + border-left: 2px solid black; + border-bottom: 3px solid black; + border-right: 4px solid black; + } + &:dir(rtl) { + border-top: 1px solid black; + border-right: 2px solid black; + border-bottom: 3px solid black; + border-left: 4px solid black; + } + border: inherit; + &:dir(ltr) { + border-left: 5px solid black; + border-right: 6px solid black; + } + &:dir(rtl) { + border-right: 5px solid black; + border-left: 6px solid black; + } + border: inherit; + &:dir(ltr) { + border-left-start: 7px solid black; + } + &:dir(rtl) { + border-right-start: 7px solid black; + } + border: inherit; + &:dir(ltr) { + border-right-end: 8px solid black; + } + &:dir(rtl) { + border-left-end: 8px solid black; + } + border: inherit; + &:dir(ltr) { + border-top: 9px solid black; + border-left: 9px solid black; + } + &:dir(rtl) { + border-top: 9px solid black; + border-right: 9px solid black; + } + border: inherit; + &:dir(ltr) { + border-top: 10px solid black; + border-left: 11px solid black; + } + &:dir(rtl) { + border-top: 10px solid black; + border-right: 11px solid black; + } + border: inherit; + &:dir(ltr) { + border-bottom: 12px solid black; + border-right: 12px solid black; + } + &:dir(rtl) { + border-bottom: 12px solid black; + border-left: 12px solid black; + } + border: inherit; + &:dir(ltr) { + border-bottom: 13px solid black; + border-right: 14px solid black; + } + &:dir(rtl) { + border-bottom: 13px solid black; + border-left: 14px solid black; + } + border: inherit; +} + +test-flowing-border-color { + border-color: inherit; + &:dir(ltr) { + border-top-color: 1px solid black; + border-left-color: 2px solid black; + border-bottom-color: 3px solid black; + border-right-color: 4px solid black; + } + &:dir(rtl) { + border-top-color: 1px solid black; + border-right-color: 2px solid black; + border-bottom-color: 3px solid black; + border-left-color: 4px solid black; + } + border-color: inherit; + &:dir(ltr) { + border-left-color: 5px solid black; + border-right-color: 6px solid black; + } + &:dir(rtl) { + border-right-color: 5px solid black; + border-left-color: 6px solid black; + } + border-color: inherit; + &:dir(ltr) { + border-left-start-color: 7px solid black; + } + &:dir(rtl) { + border-right-start-color: 7px solid black; + } + border-color: inherit; + &:dir(ltr) { + border-right-end-color: 8px solid black; + } + &:dir(rtl) { + border-left-end-color: 8px solid black; + } + border-color: inherit; + &:dir(ltr) { + border-top-color: 9px solid black; + border-left-color: 9px solid black; + } + &:dir(rtl) { + border-top-color: 9px solid black; + border-right-color: 9px solid black; + } + border-color: inherit; + &:dir(ltr) { + border-top-color: 10px solid black; + border-left-color: 11px solid black; + } + &:dir(rtl) { + border-top-color: 10px solid black; + border-right-color: 11px solid black; + } + border-color: inherit; + &:dir(ltr) { + border-bottom-color: 12px solid black; + border-right-color: 12px solid black; + } + &:dir(rtl) { + border-bottom-color: 12px solid black; + border-left-color: 12px solid black; + } + border-color: inherit; + &:dir(ltr) { + border-bottom-color: 13px solid black; + border-right-color: 14px solid black; + } + &:dir(rtl) { + border-bottom-color: 13px solid black; + border-left-color: 14px solid black; + } + border-color: inherit; +} diff --git a/test/float.css b/test/float.css new file mode 100644 index 0000000000..c6bc1a5ae2 --- /dev/null +++ b/test/float.css @@ -0,0 +1,6 @@ +test-float { + float: left; + float: inline-start; + float: inline-end; + float: right; +} diff --git a/test/float.expect.css b/test/float.expect.css new file mode 100644 index 0000000000..d2c5c40ce4 --- /dev/null +++ b/test/float.expect.css @@ -0,0 +1,16 @@ +test-float { + float: left; + &:dir(ltr) { + float: left; + } + &:dir(rtl) { + float: right; + } + &:dir(ltr) { + float: right; + } + &:dir(rtl) { + float: left; + } + float: right; +} diff --git a/test/inset.css b/test/inset.css new file mode 100644 index 0000000000..5e0c8ab38c --- /dev/null +++ b/test/inset.css @@ -0,0 +1,26 @@ +test-inset { + inset: logical 1px; + inset: logical 2px 3px; + inset: logical 4px 5px 6px; + inset: logical 7px 8px 9px 8px; +} + +test-flowing-inset { + inset: auto; + inset: logical 1px 2px 3px 4px; + inset: auto; + inset-inline: 5px 6px; + inset: auto; + inset-inline-start: 7px; + inset: auto; + inset-inline-end: 8px; + inset: auto; + inset-start: 9px; + inset: auto; + inset-start: 10px 11px; + inset: auto; + inset-end: 12px; + inset: auto; + inset-end: 13px 14px; + inset: auto; +} diff --git a/test/inset.expect.css b/test/inset.expect.css new file mode 100644 index 0000000000..9be548e81b --- /dev/null +++ b/test/inset.expect.css @@ -0,0 +1,121 @@ +test-inset { + top: 1px; + left: 1px; + bottom: 1px; + right: 1px; + top: 2px; + left: 3px; + bottom: 2px; + right: 3px; + top: 4px; + left: 5px; + bottom: 6px; + right: 5px; + top: 7px; + left: 8px; + bottom: 9px; + right: 8px; +} + +test-flowing-inset { + top: auto; + right: auto; + bottom: auto; + left: auto; + &:dir(ltr) { + top: 1px; + left: 2px; + bottom: 3px; + right: 4px; + } + &:dir(rtl) { + top: 1px; + right: 2px; + bottom: 3px; + left: 4px; + } + top: auto; + right: auto; + bottom: auto; + left: auto; + &:dir(ltr) { + left: 5px; + right: 6px; + } + &:dir(rtl) { + right: 5px; + left: 6px; + } + top: auto; + right: auto; + bottom: auto; + left: auto; + &:dir(ltr) { + left: 7px; + } + &:dir(rtl) { + right: 7px; + } + top: auto; + right: auto; + bottom: auto; + left: auto; + &:dir(ltr) { + right: 8px; + } + &:dir(rtl) { + left: 8px; + } + top: auto; + right: auto; + bottom: auto; + left: auto; + &:dir(ltr) { + top: 9px; + left: 9px; + } + &:dir(rtl) { + top: 9px; + right: 9px; + } + top: auto; + right: auto; + bottom: auto; + left: auto; + &:dir(ltr) { + top: 10px; + left: 11px; + } + &:dir(rtl) { + top: 10px; + right: 11px; + } + top: auto; + right: auto; + bottom: auto; + left: auto; + &:dir(ltr) { + bottom: 12px; + right: 12px; + } + &:dir(rtl) { + bottom: 12px; + left: 12px; + } + top: auto; + right: auto; + bottom: auto; + left: auto; + &:dir(ltr) { + bottom: 13px; + right: 14px; + } + &:dir(rtl) { + bottom: 13px; + left: 14px; + } + top: auto; + right: auto; + bottom: auto; + left: auto; +} diff --git a/test/margin.css b/test/margin.css new file mode 100644 index 0000000000..15c17392b3 --- /dev/null +++ b/test/margin.css @@ -0,0 +1,32 @@ +test-margin { + margin: logical 1px; + margin: logical 2px 3px; + margin: logical 4px 5px 6px; + margin: logical 7px 8px 9px 8px; + margin-inline: 10px; + margin-inline: 11px 11px; + margin-block: 12px; + margin-block: 13px 14px; + margin-block-start: 15px; + margin-block-end: 16px; +} + +test-flowing-margin { + margin: auto; + margin: logical 1px 2px 3px 4px; + margin: auto; + margin-inline: 5px 6px; + margin: auto; + margin-inline-start: 7px; + margin: auto; + margin-inline-end: 8px; + margin: auto; + margin-start: 9px; + margin: auto; + margin-start: 10px 11px; + margin: auto; + margin-end: 12px; + margin: auto; + margin-end: 13px 14px; + margin: auto; +} diff --git a/test/margin.expect.css b/test/margin.expect.css new file mode 100644 index 0000000000..fb8b4a81d8 --- /dev/null +++ b/test/margin.expect.css @@ -0,0 +1,86 @@ +test-margin { + margin: 1px; + margin: 2px 3px; + margin: 4px 5px 6px; + margin: 7px 8px 9px 8px; + margin-left: 10px; + margin-right: 10px; + margin-left: 11px; + margin-right: 11px; + margin-top: 12px; + margin-bottom: 12px; + margin-top: 13px; + margin-bottom: 14px; + margin-top: 15px; + margin-bottom: 16px; +} + +test-flowing-margin { + margin: auto; + &:dir(ltr) { + margin: 1px 4px 3px 2px; + } + &:dir(rtl) { + margin: 1px 2px 3px 4px; + } + margin: auto; + &:dir(ltr) { + margin-left: 5px; + margin-right: 6px; + } + &:dir(rtl) { + margin-right: 5px; + margin-left: 6px; + } + margin: auto; + &:dir(ltr) { + margin-left: 7px; + } + &:dir(rtl) { + margin-right: 7px; + } + margin: auto; + &:dir(ltr) { + margin-right: 8px; + } + &:dir(rtl) { + margin-left: 8px; + } + margin: auto; + &:dir(ltr) { + margin-top: 9px; + margin-left: 9px; + } + &:dir(rtl) { + margin-top: 9px; + margin-right: 9px; + } + margin: auto; + &:dir(ltr) { + margin-top: 10px; + margin-left: 11px; + } + &:dir(rtl) { + margin-top: 10px; + margin-right: 11px; + } + margin: auto; + &:dir(ltr) { + margin-bottom: 12px; + margin-right: 12px; + } + &:dir(rtl) { + margin-bottom: 12px; + margin-left: 12px; + } + margin: auto; + &:dir(ltr) { + margin-bottom: 13px; + margin-right: 14px; + } + &:dir(rtl) { + margin-bottom: 13px; + margin-left: 14px; + } + margin: auto; +} diff --git a/test/padding.css b/test/padding.css new file mode 100644 index 0000000000..9f040e0e6b --- /dev/null +++ b/test/padding.css @@ -0,0 +1,32 @@ +test-padding { + padding: logical 1px; + padding: logical 2px 3px; + padding: logical 4px 5px 6px; + padding: logical 7px 8px 9px 8px; + padding-inline: 10px; + padding-inline: 11px 11px; + padding-block: 12px; + padding-block: 13px 14px; + padding-block-start: 15px; + padding-block-end: 16px; +} + +test-flowing-padding { + padding: auto; + padding: logical 1px 2px 3px 4px; + padding: auto; + padding-inline: 5px 6px; + padding: auto; + padding-inline-start: 7px; + padding: auto; + padding-inline-end: 8px; + padding: auto; + padding-start: 9px; + padding: auto; + padding-start: 10px 11px; + padding: auto; + padding-end: 12px; + padding: auto; + padding-end: 13px 14px; + padding: auto; +} diff --git a/test/padding.expect.css b/test/padding.expect.css new file mode 100644 index 0000000000..0819c1eb55 --- /dev/null +++ b/test/padding.expect.css @@ -0,0 +1,86 @@ +test-padding { + padding: 1px; + padding: 2px 3px; + padding: 4px 5px 6px; + padding: 7px 8px 9px 8px; + padding-left: 10px; + padding-right: 10px; + padding-left: 11px; + padding-right: 11px; + padding-top: 12px; + padding-bottom: 12px; + padding-top: 13px; + padding-bottom: 14px; + padding-top: 15px; + padding-bottom: 16px; +} + +test-flowing-padding { + padding: auto; + &:dir(ltr) { + padding: 1px 4px 3px 2px; + } + &:dir(rtl) { + padding: 1px 2px 3px 4px; + } + padding: auto; + &:dir(ltr) { + padding-left: 5px; + padding-right: 6px; + } + &:dir(rtl) { + padding-right: 5px; + padding-left: 6px; + } + padding: auto; + &:dir(ltr) { + padding-left: 7px; + } + &:dir(rtl) { + padding-right: 7px; + } + padding: auto; + &:dir(ltr) { + padding-right: 8px; + } + &:dir(rtl) { + padding-left: 8px; + } + padding: auto; + &:dir(ltr) { + padding-top: 9px; + padding-left: 9px; + } + &:dir(rtl) { + padding-top: 9px; + padding-right: 9px; + } + padding: auto; + &:dir(ltr) { + padding-top: 10px; + padding-left: 11px; + } + &:dir(rtl) { + padding-top: 10px; + padding-right: 11px; + } + padding: auto; + &:dir(ltr) { + padding-bottom: 12px; + padding-right: 12px; + } + &:dir(rtl) { + padding-bottom: 12px; + padding-left: 12px; + } + padding: auto; + &:dir(ltr) { + padding-bottom: 13px; + padding-right: 14px; + } + &:dir(rtl) { + padding-bottom: 13px; + padding-left: 14px; + } + padding: auto; +} diff --git a/test/resize.css b/test/resize.css new file mode 100644 index 0000000000..1503859afd --- /dev/null +++ b/test/resize.css @@ -0,0 +1,4 @@ +test-resize { + resize: block; + resize: inline; +} diff --git a/test/resize.expect.css b/test/resize.expect.css new file mode 100644 index 0000000000..d9cf49b724 --- /dev/null +++ b/test/resize.expect.css @@ -0,0 +1,4 @@ +test-resize { + resize: vertical; + resize: horizontal; +} diff --git a/test/size.css b/test/size.css new file mode 100644 index 0000000000..f30df39d5f --- /dev/null +++ b/test/size.css @@ -0,0 +1,4 @@ +test-size { + block-size: auto; + inline-size: auto; +} diff --git a/test/size.expect.css b/test/size.expect.css new file mode 100644 index 0000000000..ed734025e9 --- /dev/null +++ b/test/size.expect.css @@ -0,0 +1,4 @@ +test-size { + height: auto; + width: auto; +} diff --git a/test/text-align.css b/test/text-align.css new file mode 100644 index 0000000000..950d748ab4 --- /dev/null +++ b/test/text-align.css @@ -0,0 +1,6 @@ +test-text-align { + text-align: left; + text-align: start; + text-align: end; + text-align: right; +} diff --git a/test/text-align.expect.css b/test/text-align.expect.css new file mode 100644 index 0000000000..605981cefa --- /dev/null +++ b/test/text-align.expect.css @@ -0,0 +1,16 @@ +test-text-align { + text-align: left; + &:dir(ltr) { + text-align: left; + } + &:dir(rtl) { + text-align: right; + } + &:dir(ltr) { + text-align: right; + } + &:dir(rtl) { + text-align: left; + } + text-align: right; +} From a58332990506d6016154498f7016043f8bd64662 Mon Sep 17 00:00:00 2001 From: Jonathan Neal Date: Sun, 13 Aug 2017 15:03:29 -0400 Subject: [PATCH 486/795] Improve flow-relative border support --- dependent-js/transform-border.js | 45 ++++++++++++++++---------------- index.js | 2 +- test/border.expect.css | 16 ++++++------ 3 files changed, 32 insertions(+), 31 deletions(-) diff --git a/dependent-js/transform-border.js b/dependent-js/transform-border.js index b2d7530562..74ec630ffd 100644 --- a/dependent-js/transform-border.js +++ b/dependent-js/transform-border.js @@ -2,7 +2,7 @@ const cloneRule = require('./clone-rule'); const matchLogical = /^\s*logical\s+/i; const matchLogicalBorder = /^border(-width|-style|-color)?$/i; -const matchLogicalBorderSide = /^border-(?:(width|style|color)-)?(block|block-start|block-end|inline|inline-start|inline-end|start|end)/i; +const matchLogicalBorderSide = /^border-(block|block-start|block-end|inline|inline-start|inline-end|start|end)(-(width|style|color))?$/i; // border module.exports['border'] = (decl, values) => { @@ -80,11 +80,11 @@ module.exports['border'] = (decl, values) => { // border-block module.exports['border-block'] = (decl, values) => [ decl.clone({ - prop: `border-top${decl.prop.replace(matchLogicalBorderSide, '$1')}`, + prop: `border-top${decl.prop.replace(matchLogicalBorderSide, '$2')}`, value: values[0] }), decl.clone({ - prop: `border-bottom${decl.prop.replace(matchLogicalBorderSide, '$1')}`, + prop: `border-bottom${decl.prop.replace(matchLogicalBorderSide, '$2')}`, value: values[0] }) ]; @@ -103,32 +103,32 @@ module.exports['border-block-end'] = (decl) => { module.exports['border-inline'] = (decl, values) => 1 === values.length || 2 === values.length && values[0] === values[1] ? [ decl.clone({ - prop: `border-left${decl.prop.replace(matchLogicalBorderSide, '$1')}`, + prop: `border-left${decl.prop.replace(matchLogicalBorderSide, '$2')}`, value: values[0] }), decl.clone({ - prop: `border-right${decl.prop.replace(matchLogicalBorderSide, '$1')}`, + prop: `border-right${decl.prop.replace(matchLogicalBorderSide, '$2')}`, value: values[1] || values[0] }) ] : [ cloneRule(decl, 'ltr').append([ decl.clone({ - prop: `border-left${decl.prop.replace(matchLogicalBorderSide, '$1')}`, + prop: `border-left${decl.prop.replace(matchLogicalBorderSide, '$2')}`, value: values[0] }), decl.clone({ - prop: `border-right${decl.prop.replace(matchLogicalBorderSide, '$1')}`, + prop: `border-right${decl.prop.replace(matchLogicalBorderSide, '$2')}`, value: values[1] || values[0] }) ]), cloneRule(decl, 'rtl').append([ decl.clone({ - prop: `border-right${decl.prop.replace(matchLogicalBorderSide, '$1')}`, + prop: `border-right${decl.prop.replace(matchLogicalBorderSide, '$2')}`, value: values[0] }), decl.clone({ - prop: `border-left${decl.prop.replace(matchLogicalBorderSide, '$1')}`, + prop: `border-left${decl.prop.replace(matchLogicalBorderSide, '$2')}`, value: values[1] || values[0] }) ]) @@ -138,12 +138,12 @@ module.exports['border-inline'] = (decl, values) => 1 === values.length || 2 === module.exports['border-inline-start'] = (decl) => [ cloneRule(decl, 'ltr').append( decl.clone({ - prop: `border-left${decl.prop.replace(matchLogicalBorderSide, '$1')}` + prop: `border-left${decl.prop.replace(matchLogicalBorderSide, '$2')}` }) ), cloneRule(decl, 'rtl').append( decl.clone({ - prop: `border-right${decl.prop.replace(matchLogicalBorderSide, '$1')}` + prop: `border-right${decl.prop.replace(matchLogicalBorderSide, '$2')}` }) ) ]; @@ -152,12 +152,12 @@ module.exports['border-inline-start'] = (decl) => [ module.exports['border-inline-end'] = (decl) => [ cloneRule(decl, 'ltr').append( decl.clone({ - prop: `border-right${decl.prop.replace(matchLogicalBorderSide, '$1')}` + prop: `border-right${decl.prop.replace(matchLogicalBorderSide, '$2')}` }) ), cloneRule(decl, 'rtl').append( decl.clone({ - prop: `border-left${decl.prop.replace(matchLogicalBorderSide, '$1')}` + prop: `border-left${decl.prop.replace(matchLogicalBorderSide, '$2')}` }) ) ]; @@ -166,21 +166,21 @@ module.exports['border-inline-end'] = (decl) => [ module.exports['border-start'] = (decl, values) => [ cloneRule(decl, 'ltr').append([ decl.clone({ - prop: `border-top${decl.prop.replace(matchLogicalBorderSide, '$1')}`, + prop: `border-top${decl.prop.replace(matchLogicalBorderSide, '$2')}`, value: values[0] }), decl.clone({ - prop: `border-left${decl.prop.replace(matchLogicalBorderSide, '$1')}`, + prop: `border-left${decl.prop.replace(matchLogicalBorderSide, '$2')}`, value: values[1] || values[0] }) ]), cloneRule(decl, 'rtl').append([ decl.clone({ - prop: `border-top${decl.prop.replace(matchLogicalBorderSide, '$1')}`, + prop: `border-top${decl.prop.replace(matchLogicalBorderSide, '$2')}`, value: values[0] }), decl.clone({ - prop: `border-right${decl.prop.replace(matchLogicalBorderSide, '$1')}`, + prop: `border-right${decl.prop.replace(matchLogicalBorderSide, '$2')}`, value: values[1] || values[0] }) ]) @@ -188,22 +188,23 @@ module.exports['border-start'] = (decl, values) => [ // border-end module.exports['border-end'] = (decl, values) => [ - cloneRule(decl, 'ltr').append([decl.clone({ - prop: `border-bottom${decl.prop.replace(matchLogicalBorderSide, '$1')}`, + cloneRule(decl, 'ltr').append([ + decl.clone({ + prop: `border-bottom${decl.prop.replace(matchLogicalBorderSide, '$2')}`, value: values[0] }), decl.clone({ - prop: `border-right${decl.prop.replace(matchLogicalBorderSide, '$1')}`, + prop: `border-right${decl.prop.replace(matchLogicalBorderSide, '$2')}`, value: values[1] || values[0] }) ]), cloneRule(decl, 'rtl').append([ decl.clone({ - prop: `border-bottom${decl.prop.replace(matchLogicalBorderSide, '$1')}`, + prop: `border-bottom${decl.prop.replace(matchLogicalBorderSide, '$2')}`, value: values[0] }), decl.clone({ - prop: `border-left${decl.prop.replace(matchLogicalBorderSide, '$1')}`, + prop: `border-left${decl.prop.replace(matchLogicalBorderSide, '$2')}`, value: values[1] || values[0] }) ]) diff --git a/index.js b/index.js index de65b864cc..1cbe746a99 100644 --- a/index.js +++ b/index.js @@ -43,7 +43,7 @@ const transforms = { // plugin module.exports = postcss.plugin('postcss-logical-properties', () => (root) => { root.walkDecls((decl) => { - const values = postcss.list.split(decl.value, /^border/i.test(decl.prop) ? '/' : ' '); + const values = postcss.list.split(decl.value, /^border(-block|-inline|-start|-end)?(-width|-style|-color)?$/i.test(decl.prop) ? '/' : ' '); const prop = decl.prop.replace(matchSupportedProperties, '$2$5').toLowerCase(); if (prop in transforms) { diff --git a/test/border.expect.css b/test/border.expect.css index 0d9d5c0c1b..6d670f7d55 100644 --- a/test/border.expect.css +++ b/test/border.expect.css @@ -49,17 +49,17 @@ test-flowing-border { } border: inherit; &:dir(ltr) { - border-left-start: 7px solid black; + border-left: 7px solid black; } &:dir(rtl) { - border-right-start: 7px solid black; + border-right: 7px solid black; } border: inherit; &:dir(ltr) { - border-right-end: 8px solid black; + border-right: 8px solid black; } &:dir(rtl) { - border-left-end: 8px solid black; + border-left: 8px solid black; } border: inherit; &:dir(ltr) { @@ -125,17 +125,17 @@ test-flowing-border-color { } border-color: inherit; &:dir(ltr) { - border-left-start-color: 7px solid black; + border-left-color: 7px solid black; } &:dir(rtl) { - border-right-start-color: 7px solid black; + border-right-color: 7px solid black; } border-color: inherit; &:dir(ltr) { - border-right-end-color: 8px solid black; + border-right-color: 8px solid black; } &:dir(rtl) { - border-left-end-color: 8px solid black; + border-left-color: 8px solid black; } border-color: inherit; &:dir(ltr) { From 26adc1843b3d80aa551f8bfa20efd51de5430b2d Mon Sep 17 00:00:00 2001 From: Jonathan Neal Date: Sun, 13 Aug 2017 15:04:56 -0400 Subject: [PATCH 487/795] 1.0.1 --- CHANGELOG.md | 5 +++++ package.json | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5bdbfd83a8..56503e7208 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,10 @@ # Changes to PostCSS Logical Properties +### 1.0.1 (Aug 13, 2017) + +- Improve flow-relative border support +- Update dependencies + ### 1.0.0 (Aug 8, 2017) - Initial version diff --git a/package.json b/package.json index c78ef9ae86..4542075f45 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "postcss-logical", - "version": "1.0.0", + "version": "1.0.1", "description": "Use logical properties and flow-relative values in CSS", "author": "Jonathan Neal ", "license": "CC0-1.0", From 74323d2fa57ee3dc052881102a4fef3d434dd754 Mon Sep 17 00:00:00 2001 From: Jonathan Neal Date: Tue, 15 Aug 2017 14:26:38 -0400 Subject: [PATCH 488/795] Improve flow-relative clear support --- .tape.js | 3 +++ index.js | 1 + test/clear.css | 7 +++++++ test/clear.expect.css | 17 +++++++++++++++++ 4 files changed, 28 insertions(+) create mode 100644 test/clear.css create mode 100644 test/clear.expect.css diff --git a/.tape.js b/.tape.js index aaaff59d4d..05cce545a3 100644 --- a/.tape.js +++ b/.tape.js @@ -3,6 +3,9 @@ module.exports = { 'border': { message: 'supports logical "border" property values' }, + 'clear': { + message: 'supports logical "clear" property values' + }, 'float': { message: 'supports logical "float" property values' }, diff --git a/index.js b/index.js index 1cbe746a99..e445026201 100644 --- a/index.js +++ b/index.js @@ -23,6 +23,7 @@ const transforms = { 'border-inline-end': transformBorder['border-inline-end'], 'border-inline-end-width': transformBorder['border-inline-end'], 'border-inline-end-style': transformBorder['border-inline-end'], 'border-inline-end-color': transformBorder['border-inline-end'], 'border-start': transformBorder['border-start'], 'border-start-width': transformBorder['border-start'], 'border-start-style': transformBorder['border-start'], 'border-start-color': transformBorder['border-start'], 'border-end': transformBorder['border-end'], 'border-end-width': transformBorder['border-end'], 'border-end-style': transformBorder['border-end'], 'border-end-color': transformBorder['border-end'], + 'clear': transformFloat, 'inset': transformInset, 'margin': transformSpacing, 'padding': transformSpacing, diff --git a/test/clear.css b/test/clear.css new file mode 100644 index 0000000000..69f0de1a80 --- /dev/null +++ b/test/clear.css @@ -0,0 +1,7 @@ +test-clear { + clear: both; + clear: left; + clear: inline-start; + clear: inline-end; + clear: right; +} diff --git a/test/clear.expect.css b/test/clear.expect.css new file mode 100644 index 0000000000..75cc0cc378 --- /dev/null +++ b/test/clear.expect.css @@ -0,0 +1,17 @@ +test-clear { + clear: both; + clear: left; + &:dir(ltr) { + clear: left; + } + &:dir(rtl) { + clear: right; + } + &:dir(ltr) { + clear: right; + } + &:dir(rtl) { + clear: left; + } + clear: right; +} From edac99d457e8ef3ad087e52774505d0f72e9858a Mon Sep 17 00:00:00 2001 From: Jonathan Neal Date: Tue, 15 Aug 2017 14:26:48 -0400 Subject: [PATCH 489/795] Update dependencies --- package.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index 4542075f45..c0ca8dfa0f 100644 --- a/package.json +++ b/package.json @@ -23,10 +23,10 @@ "node": ">=4.0.0" }, "dependencies": { - "postcss": "^6.0.8" + "postcss": "^6.0.9" }, "devDependencies": { - "eslint": "^4.3.0", + "eslint": "^4.4.1", "eslint-config-dev": "2.0.0", "postcss-tape": "2.0.1", "pre-commit": "^1.2.2" From aa5665ba20ad6b49f0a61ca71361c3b5653d223d Mon Sep 17 00:00:00 2001 From: Jonathan Neal Date: Tue, 15 Aug 2017 14:27:36 -0400 Subject: [PATCH 490/795] 1.0.2 --- CHANGELOG.md | 5 +++++ package.json | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 56503e7208..4552293858 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,10 @@ # Changes to PostCSS Logical Properties +### 1.0.2 (Aug 15, 2017) + +- Improve flow-relative clear support +- Update dependencies + ### 1.0.1 (Aug 13, 2017) - Improve flow-relative border support diff --git a/package.json b/package.json index c0ca8dfa0f..78da97228b 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "postcss-logical", - "version": "1.0.1", + "version": "1.0.2", "description": "Use logical properties and flow-relative values in CSS", "author": "Jonathan Neal ", "license": "CC0-1.0", From aac271c3c3ab3409ae743428a10d956444e579ad Mon Sep 17 00:00:00 2001 From: Jonathan Neal Date: Tue, 15 Aug 2017 14:29:51 -0400 Subject: [PATCH 491/795] Update documentation --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 448fdadc0e..774c48ece5 100644 --- a/README.md +++ b/README.md @@ -80,8 +80,8 @@ properties: #### Flow-Relative Values -- `float: inline-start`, `float: inline-end`, `text-align: start`, - `text-align: end` +- `clear: inline-start`, `clear: inline-end`, `float: inline-start`, + `float: inline-end`, `text-align: start`, `text-align: end` --- From 6a093745e8cc7cb9e57eb498bdaba7f84ad4b46a Mon Sep 17 00:00:00 2001 From: Junliang Huang Date: Sun, 20 Aug 2017 00:53:18 +0800 Subject: [PATCH 492/795] fix: a case in which test rule will compose another valid CSS qualified name (#44) To be nest-containing, any nesting selector must composed with other selectors into a valid complex selectors. However, the current implementation will turn ``` a { &|b { } } ``` into ``` a|b { } ``` which is a valid CSS rule. We should reject the vertical bar on selector validity test. --- lib/transform-nesting-atrule.js | 2 +- lib/transform-nesting-rule.js | 2 +- test/ignore.css | 3 +++ test/ignore.expect.css | 3 +++ 4 files changed, 8 insertions(+), 2 deletions(-) diff --git a/lib/transform-nesting-atrule.js b/lib/transform-nesting-atrule.js index 08ece98db1..878de25981 100644 --- a/lib/transform-nesting-atrule.js +++ b/lib/transform-nesting-atrule.js @@ -39,5 +39,5 @@ module.exports = (node) => { // whether the node is a nesting atrule (e.g. @nest .something &) module.exports.test = (node) => node.type === 'atrule' && node.name === 'nest' && node.parent && node.parent.type === 'rule' && comma(node.params).every( - (selector) => selector.split('&').length === 2 && /&([^\w-]|$)/.test(selector) + (selector) => selector.split('&').length === 2 && /&([^\w-|]|$)/.test(selector) ); diff --git a/lib/transform-nesting-rule.js b/lib/transform-nesting-rule.js index 4ace658692..689528132f 100644 --- a/lib/transform-nesting-rule.js +++ b/lib/transform-nesting-rule.js @@ -25,5 +25,5 @@ module.exports = (node) => { // whether the node is a nesting rule (e.g. &.something) module.exports.test = (node) => node.type === 'rule' && node.parent && node.parent.type === 'rule' && node.selectors.every( - (selector) => selector.trim().lastIndexOf('&') === 0 && /^&([^\w-]|$)/.test(selector) + (selector) => selector.trim().lastIndexOf('&') === 0 && /^&([^\w-|]|$)/.test(selector) ); diff --git a/test/ignore.css b/test/ignore.css index 3829c74064..5a5ef98290 100644 --- a/test/ignore.css +++ b/test/ignore.css @@ -31,4 +31,7 @@ f { @nest &h { order: 5; } + @nest &|i { + order: 6; + } } diff --git a/test/ignore.expect.css b/test/ignore.expect.css index 3829c74064..5a5ef98290 100644 --- a/test/ignore.expect.css +++ b/test/ignore.expect.css @@ -31,4 +31,7 @@ f { @nest &h { order: 5; } + @nest &|i { + order: 6; + } } From 7eacf48b27dd0ccaec9591bc5a9026705c3e7a0c Mon Sep 17 00:00:00 2001 From: Junliang Huang Date: Sun, 20 Aug 2017 00:53:33 +0800 Subject: [PATCH 493/795] Use mutation-safe walk method (#45) * test: add at-rule test case * refactor: use root.walk method root.walk is safe for mutation arrays, thus we use root.walk instead of handwritten conditional walk * fix: clone atrule semicolon raws to generated rule --- .tape.js | 3 +++ index.js | 14 ++------------ lib/transform-nesting-atrule.js | 3 +++ test/at-rule.css | 30 ++++++++++++++++++++++++++++++ test/at-rule.expect.css | 30 ++++++++++++++++++++++++++++++ 5 files changed, 68 insertions(+), 12 deletions(-) create mode 100644 test/at-rule.css create mode 100644 test/at-rule.expect.css diff --git a/.tape.js b/.tape.js index 442ed52ff1..695808faa4 100644 --- a/.tape.js +++ b/.tape.js @@ -3,6 +3,9 @@ module.exports = { 'basic': { message: 'supports basic usage' }, + 'at-rule': { + message: 'supports at-rule usage' + }, 'direct': { message: 'supports direct usage' }, diff --git a/index.js b/index.js index a4627d325b..7504e3b9a1 100644 --- a/index.js +++ b/index.js @@ -8,10 +8,10 @@ const transformNestingRule = require('./lib/transform-nesting-rule'); // plugin module.exports = postcss.plugin('postcss-nesting', () => { - return walk; + return (root) => root.walk(transform); }); -function walk(node) { +function transform(node) { // console.log('walk', [node.type], [node.name || node.selector || node.prop || 'root'], node.nodes ? `length: ${node.nodes.length}` : `value: "${node.value}"`); if (transformBubblingAtrule.test(node)) { @@ -25,14 +25,4 @@ function walk(node) { transformNestingRule(node); } - if (node.nodes) { - // conditionally walk the children of the node - let childNode = node.nodes[0]; - - while (childNode) { - walk(childNode); - - childNode = childNode.parent && childNode.parent.nodes[childNode.parent.nodes.indexOf(childNode) + 1]; - } - } } diff --git a/lib/transform-nesting-atrule.js b/lib/transform-nesting-atrule.js index 878de25981..dca39cf0a0 100644 --- a/lib/transform-nesting-atrule.js +++ b/lib/transform-nesting-atrule.js @@ -20,6 +20,9 @@ module.exports = (node) => { source: node.source }); + // clone atrule semicolon raws + rule.raws = node.raws.semicolon ? { semicolon: true } : {}; + // move the clone after the parent const parent = node.parent.after(rule); diff --git a/test/at-rule.css b/test/at-rule.css new file mode 100644 index 0000000000..a9406c42c9 --- /dev/null +++ b/test/at-rule.css @@ -0,0 +1,30 @@ +a { + order: 1; + @nest b & { + order: 2; + } + @nest c & { + order: 3; + } + @nest d & { + order: 4; + } + @nest e & { + order: 5; + } +} +a { + order: 1; + @nest & b { + order: 2; + } + @nest & c { + order: 3; + } + @nest & d { + order: 4; + } + @nest & e { + order: 5; + } +} diff --git a/test/at-rule.expect.css b/test/at-rule.expect.css new file mode 100644 index 0000000000..df7cfadae8 --- /dev/null +++ b/test/at-rule.expect.css @@ -0,0 +1,30 @@ +a { + order: 1 +} +b a { + order: 2; +} +c a { + order: 3; +} +d a { + order: 4; +} +e a { + order: 5; +} +a { + order: 1 +} +a b { + order: 2; +} +a c { + order: 3; +} +a d { + order: 4; +} +a e { + order: 5; +} From 9dab9a6a1c9eea890f331cb971687fe6fb216e3b Mon Sep 17 00:00:00 2001 From: Jonathan Neal Date: Sat, 19 Aug 2017 13:01:29 -0400 Subject: [PATCH 494/795] Use spaces in Markdown files Use spaces within Markdown files --- .editorconfig | 2 +- CONTRIBUTING.md | 63 ++++++++++++++++++++++--------------------- LICENSE.md | 72 ++++++++++++++++++++++++------------------------- 3 files changed, 70 insertions(+), 67 deletions(-) diff --git a/.editorconfig b/.editorconfig index 5a40119853..e06d7982bc 100644 --- a/.editorconfig +++ b/.editorconfig @@ -10,6 +10,6 @@ trim_trailing_whitespace = true [*.md] trim_trailing_whitespace = false -[*.{json,yml}] +[*.{json,md,yml}] indent_size = 2 indent_style = space diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 104bbe13ee..e1b6dcac30 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -18,42 +18,45 @@ Pull requests are the greatest contributions, so be sure they are focused in scope, and do avoid unrelated commits. 1. To begin, [fork this project], clone your fork, and add our upstream. - ```bash - # Clone your fork of the repo into the current directory - git clone https://github.com//postcss-nesting - # Navigate to the newly cloned directory - cd postcss-nesting - # Assign the original repo to a remote called "upstream" - git remote add upstream https://github.com/jonathantneal/postcss-nesting - # Install the tools necessary for development - npm install - ``` + ```bash + # Clone your fork of the repo into the current directory + git clone https://github.com//postcss-nesting + + # Navigate to the newly cloned directory + cd postcss-nesting + + # Assign the original repo to a remote called "upstream" + git remote add upstream https://github.com/jonathantneal/postcss-nesting + + # Install the tools necessary for development + npm install + ``` 2. Create a branch for your feature or fix: - ```bash - # Move into a new branch for a feature - git checkout -b feature/thing - ``` - ```bash - # Move into a new branch for a fix - git checkout -b fix/something - ``` + ```bash + # Move into a new branch for a feature + git checkout -b feature/thing + ``` + ```bash + # Move into a new branch for a fix + git checkout -b fix/something + ``` 3. Be sure your code follows our practices. - ```bash - # Test current code - npm run test - ``` + ```bash + # Test current code + npm run test + ``` 4. Push your branch up to your fork: - ```bash - # Push a feature branch - git push origin feature/thing - ``` - ```bash - # Push a fix branch - git push origin fix/something - ``` + ```bash + # Push a feature branch + git push origin feature/thing + ``` + ```bash + # Push a fix branch + git push origin fix/something + ``` 5. Now [open a pull request] with a clear title and description. diff --git a/LICENSE.md b/LICENSE.md index 34f902f6c4..ba9e7860ce 100644 --- a/LICENSE.md +++ b/LICENSE.md @@ -27,25 +27,25 @@ Copyright and Related Rights in the Work and the meaning and intended legal effect of CC0 on those rights. 1. Copyright and Related Rights. A Work made available under CC0 may be - protected by copyright and related or neighboring rights (“Copyright and - Related Rights”). Copyright and Related Rights include, but are not limited - to, the following: - 1. the right to reproduce, adapt, distribute, perform, display, - communicate, and translate a Work; - 2. moral rights retained by the original author(s) and/or performer(s); - 3. publicity and privacy rights pertaining to a person’s image or likeness - depicted in a Work; - 4. rights protecting against unfair competition in regards to a Work, - subject to the limitations in paragraph 4(i), below; - 5. rights protecting the extraction, dissemination, use and reuse of data - in a Work; - 6. database rights (such as those arising under Directive 96/9/EC of the - European Parliament and of the Council of 11 March 1996 on the legal - protection of databases, and under any national implementation thereof, - including any amended or successor version of such directive); and - 7. other similar, equivalent or corresponding rights throughout the world - based on applicable law or treaty, and any national implementations - thereof. + protected by copyright and related or neighboring rights (“Copyright and + Related Rights”). Copyright and Related Rights include, but are not limited + to, the following: + 1. the right to reproduce, adapt, distribute, perform, display, + communicate, and translate a Work; + 2. moral rights retained by the original author(s) and/or performer(s); + 3. publicity and privacy rights pertaining to a person’s image or likeness + depicted in a Work; + 4. rights protecting against unfair competition in regards to a Work, + subject to the limitations in paragraph 4(i), below; + 5. rights protecting the extraction, dissemination, use and reuse of data + in a Work; + 6. database rights (such as those arising under Directive 96/9/EC of the + European Parliament and of the Council of 11 March 1996 on the legal + protection of databases, and under any national implementation thereof, + including any amended or successor version of such directive); and + 7. other similar, equivalent or corresponding rights throughout the world + based on applicable law or treaty, and any national implementations + thereof. 2. Waiver. To the greatest extent permitted by, but not in contravention of, applicable law, Affirmer hereby overtly, fully, permanently, irrevocably and @@ -84,23 +84,23 @@ or (ii) assert any associated claims and causes of action with respect to the Work, in either case contrary to Affirmer’s express Statement of Purpose. 4. Limitations and Disclaimers. - 1. No trademark or patent rights held by Affirmer are waived, abandoned, - surrendered, licensed or otherwise affected by this document. - 2. Affirmer offers the Work as-is and makes no representations or - warranties of any kind concerning the Work, express, implied, statutory - or otherwise, including without limitation warranties of title, - merchantability, fitness for a particular purpose, non infringement, or - the absence of latent or other defects, accuracy, or the present or - absence of errors, whether or not discoverable, all to the greatest - extent permissible under applicable law. - 3. Affirmer disclaims responsibility for clearing rights of other persons - that may apply to the Work or any use thereof, including without - limitation any person’s Copyright and Related Rights in the Work. - Further, Affirmer disclaims responsibility for obtaining any necessary - consents, permissions or other rights required for any use of the Work. - 4. Affirmer understands and acknowledges that Creative Commons is not a - party to this document and has no duty or obligation with respect to - this CC0 or use of the Work. + 1. No trademark or patent rights held by Affirmer are waived, abandoned, + surrendered, licensed or otherwise affected by this document. + 2. Affirmer offers the Work as-is and makes no representations or + warranties of any kind concerning the Work, express, implied, statutory + or otherwise, including without limitation warranties of title, + merchantability, fitness for a particular purpose, non infringement, or + the absence of latent or other defects, accuracy, or the present or + absence of errors, whether or not discoverable, all to the greatest + extent permissible under applicable law. + 3. Affirmer disclaims responsibility for clearing rights of other persons + that may apply to the Work or any use thereof, including without + limitation any person’s Copyright and Related Rights in the Work. + Further, Affirmer disclaims responsibility for obtaining any necessary + consents, permissions or other rights required for any use of the Work. + 4. Affirmer understands and acknowledges that Creative Commons is not a + party to this document and has no duty or obligation with respect to + this CC0 or use of the Work. For more information, please see http://creativecommons.org/publicdomain/zero/1.0/. From 4d16c8425dc4b2189de3481deedc29652b01214f Mon Sep 17 00:00:00 2001 From: Jonathan Neal Date: Sat, 19 Aug 2017 13:03:54 -0400 Subject: [PATCH 495/795] 4.1.0 --- CHANGELOG.md | 6 ++++++ package.json | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 86d12c75a6..fea01a805e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,11 @@ # Changes to PostCSS Nesting +### 4.1.0 (August 19, 2017) + +- Improve complex selector validity testing +- Use mutation-safe walk method +- A special thanks to @JLHwung for these improvements + ### 4.0.1 (May 22, 2017) - Improve selector validity testing diff --git a/package.json b/package.json index a70d46165b..fed703bc5c 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "postcss-nesting", - "version": "4.0.1", + "version": "4.1.0", "description": "Nest style and media rules inside each another, following the CSS Nesting Module Level 3 specification", "author": "Jonathan Neal ", "license": "CC0-1.0", From 654e5db8e0fa8a0454914ab3759b1901a8f6e5c2 Mon Sep 17 00:00:00 2001 From: Jonathan Neal Date: Sat, 19 Aug 2017 20:52:21 -0400 Subject: [PATCH 496/795] Update devDependencies --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 78da97228b..f9e7cdb6d1 100644 --- a/package.json +++ b/package.json @@ -26,7 +26,7 @@ "postcss": "^6.0.9" }, "devDependencies": { - "eslint": "^4.4.1", + "eslint": "^4.5.0", "eslint-config-dev": "2.0.0", "postcss-tape": "2.0.1", "pre-commit": "^1.2.2" From e85161efe6099234e576c7c689e96a3eb9de3b64 Mon Sep 17 00:00:00 2001 From: Jonathan Neal Date: Sat, 19 Aug 2017 20:52:40 -0400 Subject: [PATCH 497/795] Support "dir" option --- dependent-js/transform-border.js | 199 +++++++++++++++------------ dependent-js/transform-float.js | 31 ++--- dependent-js/transform-inset.js | 56 ++++---- dependent-js/transform-side.js | 95 +++++++------ dependent-js/transform-spacing.js | 60 ++++---- dependent-js/transform-text-align.js | 31 ++--- index.js | 6 +- 7 files changed, 254 insertions(+), 224 deletions(-) diff --git a/dependent-js/transform-border.js b/dependent-js/transform-border.js index 74ec630ffd..274b3290b1 100644 --- a/dependent-js/transform-border.js +++ b/dependent-js/transform-border.js @@ -5,13 +5,51 @@ const matchLogicalBorder = /^border(-width|-style|-color)?$/i; const matchLogicalBorderSide = /^border-(block|block-start|block-end|inline|inline-start|inline-end|start|end)(-(width|style|color))?$/i; // border -module.exports['border'] = (decl, values) => { +module.exports['border'] = (decl, values, dir) => { const isLogical = matchLogical.test(values[0]); if (isLogical) { values[0] = values[0].replace(matchLogical, ''); } + const ltrDecls = [ + decl.clone({ + prop: `border-top${decl.prop.replace(matchLogicalBorder, '$1')}`, + value: values[0] + }), + decl.clone({ + prop: `border-left${decl.prop.replace(matchLogicalBorder, '$1')}`, + value: values[1] || values[0] + }), + decl.clone({ + prop: `border-bottom${decl.prop.replace(matchLogicalBorder, '$1')}`, + value: values[2] || values[0] + }), + decl.clone({ + prop: `border-right${decl.prop.replace(matchLogicalBorder, '$1')}`, + value: values[3] || values[1] || values[0] + }) + ]; + + const rtlDecls = [ + decl.clone({ + prop: `border-top${decl.prop.replace(matchLogicalBorder, '$1')}`, + value: values[0] + }), + decl.clone({ + prop: `border-right${decl.prop.replace(matchLogicalBorder, '$1')}`, + value: values[1] || values[0] + }), + decl.clone({ + prop: `border-bottom${decl.prop.replace(matchLogicalBorder, '$1')}`, + value: values[2] || values[0] + }), + decl.clone({ + prop: `border-left${decl.prop.replace(matchLogicalBorder, '$1')}`, + value: values[3] || values[1] || values[0] + }) + ]; + return isLogical ? 1 === values.length ? decl.clone({ value: decl.value.replace(matchLogical, '') @@ -35,43 +73,9 @@ module.exports['border'] = (decl, values) => { value: values[1] || values[0] }) ] - : [ - cloneRule(decl, 'ltr').append([ - decl.clone({ - prop: `border-top${decl.prop.replace(matchLogicalBorder, '$1')}`, - value: values[0] - }), - decl.clone({ - prop: `border-left${decl.prop.replace(matchLogicalBorder, '$1')}`, - value: values[1] || values[0] - }), - decl.clone({ - prop: `border-bottom${decl.prop.replace(matchLogicalBorder, '$1')}`, - value: values[2] || values[0] - }), - decl.clone({ - prop: `border-right${decl.prop.replace(matchLogicalBorder, '$1')}`, - value: values[3] || values[1] || values[0] - }) - ]), - cloneRule(decl, 'rtl').append([ - decl.clone({ - prop: `border-top${decl.prop.replace(matchLogicalBorder, '$1')}`, - value: values[0] - }), - decl.clone({ - prop: `border-right${decl.prop.replace(matchLogicalBorder, '$1')}`, - value: values[1] || values[0] - }), - decl.clone({ - prop: `border-bottom${decl.prop.replace(matchLogicalBorder, '$1')}`, - value: values[2] || values[0] - }), - decl.clone({ - prop: `border-left${decl.prop.replace(matchLogicalBorder, '$1')}`, - value: values[3] || values[1] || values[0] - }) - ]) + : 'ltr' === dir ? ltrDecls : 'rtl' === dir ? rtlDecls : [ + cloneRule(decl, 'ltr').append(ltrDecls), + cloneRule(decl, 'rtl').append(rtlDecls) ] : null; }; @@ -100,19 +104,8 @@ module.exports['border-block-end'] = (decl) => { }; // border-inline -module.exports['border-inline'] = (decl, values) => 1 === values.length || 2 === values.length && values[0] === values[1] -? [ - decl.clone({ - prop: `border-left${decl.prop.replace(matchLogicalBorderSide, '$2')}`, - value: values[0] - }), - decl.clone({ - prop: `border-right${decl.prop.replace(matchLogicalBorderSide, '$2')}`, - value: values[1] || values[0] - }) -] -: [ - cloneRule(decl, 'ltr').append([ +module.exports['border-inline'] = (decl, values, dir) => { + const ltrDecls = [ decl.clone({ prop: `border-left${decl.prop.replace(matchLogicalBorderSide, '$2')}`, value: values[0] @@ -121,8 +114,9 @@ module.exports['border-inline'] = (decl, values) => 1 === values.length || 2 === prop: `border-right${decl.prop.replace(matchLogicalBorderSide, '$2')}`, value: values[1] || values[0] }) - ]), - cloneRule(decl, 'rtl').append([ + ]; + + const rtlDecls = [ decl.clone({ prop: `border-right${decl.prop.replace(matchLogicalBorderSide, '$2')}`, value: values[0] @@ -131,40 +125,51 @@ module.exports['border-inline'] = (decl, values) => 1 === values.length || 2 === prop: `border-left${decl.prop.replace(matchLogicalBorderSide, '$2')}`, value: values[1] || values[0] }) - ]) -]; + ]; + + const isLTR = 1 === values.length || 2 === values.length && values[0] === values[1]; + + return isLTR ? ltrDecls : 'ltr' === dir ? ltrDecls : 'rtl' === dir ? rtlDecls : [ + cloneRule(decl, 'ltr').append(ltrDecls), + cloneRule(decl, 'rtl').append(rtlDecls) + ]; +}; // border-inline-start -module.exports['border-inline-start'] = (decl) => [ - cloneRule(decl, 'ltr').append( - decl.clone({ - prop: `border-left${decl.prop.replace(matchLogicalBorderSide, '$2')}` - }) - ), - cloneRule(decl, 'rtl').append( - decl.clone({ - prop: `border-right${decl.prop.replace(matchLogicalBorderSide, '$2')}` - }) - ) -]; +module.exports['border-inline-start'] = (decl, values, dir) => { + const ltrDecl = decl.clone({ + prop: `border-left${decl.prop.replace(matchLogicalBorderSide, '$2')}` + }); + + const rtlDecl = decl.clone({ + prop: `border-right${decl.prop.replace(matchLogicalBorderSide, '$2')}` + }); + + return 'ltr' === dir ? ltrDecl : 'rtl' === dir ? rtlDecl : [ + cloneRule(decl, 'ltr').append(ltrDecl), + cloneRule(decl, 'rtl').append(rtlDecl) + ]; +}; // border-inline-end -module.exports['border-inline-end'] = (decl) => [ - cloneRule(decl, 'ltr').append( - decl.clone({ - prop: `border-right${decl.prop.replace(matchLogicalBorderSide, '$2')}` - }) - ), - cloneRule(decl, 'rtl').append( - decl.clone({ - prop: `border-left${decl.prop.replace(matchLogicalBorderSide, '$2')}` - }) - ) -]; +module.exports['border-inline-end'] = (decl, values, dir) => { + const ltrDecl = decl.clone({ + prop: `border-right${decl.prop.replace(matchLogicalBorderSide, '$2')}` + }); + + const rtlDecl = decl.clone({ + prop: `border-left${decl.prop.replace(matchLogicalBorderSide, '$2')}` + }); + + return 'ltr' === dir ? ltrDecl : 'rtl' === dir ? rtlDecl : [ + cloneRule(decl, 'ltr').append(ltrDecl), + cloneRule(decl, 'rtl').append(rtlDecl) + ]; +}; // border-start -module.exports['border-start'] = (decl, values) => [ - cloneRule(decl, 'ltr').append([ +module.exports['border-start'] = (decl, values, dir) => { + const ltrDecls = [ decl.clone({ prop: `border-top${decl.prop.replace(matchLogicalBorderSide, '$2')}`, value: values[0] @@ -173,8 +178,9 @@ module.exports['border-start'] = (decl, values) => [ prop: `border-left${decl.prop.replace(matchLogicalBorderSide, '$2')}`, value: values[1] || values[0] }) - ]), - cloneRule(decl, 'rtl').append([ + ]; + + const rtlDecls = [ decl.clone({ prop: `border-top${decl.prop.replace(matchLogicalBorderSide, '$2')}`, value: values[0] @@ -183,12 +189,17 @@ module.exports['border-start'] = (decl, values) => [ prop: `border-right${decl.prop.replace(matchLogicalBorderSide, '$2')}`, value: values[1] || values[0] }) - ]) -]; + ]; + + return 'ltr' === dir ? ltrDecls : 'rtl' === dir ? rtlDecls : [ + cloneRule(decl, 'ltr').append(ltrDecls), + cloneRule(decl, 'rtl').append(rtlDecls) + ]; +}; // border-end -module.exports['border-end'] = (decl, values) => [ - cloneRule(decl, 'ltr').append([ +module.exports['border-end'] = (decl, values, dir) => { + const ltrDecls = [ decl.clone({ prop: `border-bottom${decl.prop.replace(matchLogicalBorderSide, '$2')}`, value: values[0] @@ -197,8 +208,9 @@ module.exports['border-end'] = (decl, values) => [ prop: `border-right${decl.prop.replace(matchLogicalBorderSide, '$2')}`, value: values[1] || values[0] }) - ]), - cloneRule(decl, 'rtl').append([ + ]; + + const rtlDecls = [ decl.clone({ prop: `border-bottom${decl.prop.replace(matchLogicalBorderSide, '$2')}`, value: values[0] @@ -207,5 +219,10 @@ module.exports['border-end'] = (decl, values) => [ prop: `border-left${decl.prop.replace(matchLogicalBorderSide, '$2')}`, value: values[1] || values[0] }) - ]) -]; + ]; + + return 'ltr' === dir ? ltrDecls : 'rtl' === dir ? rtlDecls : [ + cloneRule(decl, 'ltr').append(ltrDecls), + cloneRule(decl, 'rtl').append(rtlDecls) + ]; +}; diff --git a/dependent-js/transform-float.js b/dependent-js/transform-float.js index 8b1be7e611..eedab0aca1 100644 --- a/dependent-js/transform-float.js +++ b/dependent-js/transform-float.js @@ -1,21 +1,14 @@ const cloneRule = require('./clone-rule'); -module.exports = (decl) => /^inline-start$/i.test(decl.value) - ? [ - cloneRule(decl, 'ltr').append([ - decl.clone({ value: 'left' }) - ]), - cloneRule(decl, 'rtl').append([ - decl.clone({ value: 'right' }) - ]) - ] - : /^inline-end$/i.test(decl.value) - ? [ - cloneRule(decl, 'ltr').append([ - decl.clone({ value: 'right' }) - ]), - cloneRule(decl, 'rtl').append([ - decl.clone({ value: 'left' }) - ]) - ] - : null; +module.exports = (decl, values, dir) => { + const lDecl = decl.clone({ value: 'left' }); + const rDecl = decl.clone({ value: 'right' }); + + return /^inline-start$/i.test(decl.value) ? 'ltr' === dir ? lDecl : 'rtl' === dir ? rDecl : [ + cloneRule(decl, 'ltr').append(lDecl), + cloneRule(decl, 'rtl').append(rDecl) + ] : /^inline-end$/i.test(decl.value) ? 'ltr' === dir ? rDecl : 'rtl' === dir ? lDecl : [ + cloneRule(decl, 'ltr').append(rDecl), + cloneRule(decl, 'rtl').append(lDecl) + ] : null; +}; diff --git a/dependent-js/transform-inset.js b/dependent-js/transform-inset.js index e4ce88d7ea..b072ec44ab 100644 --- a/dependent-js/transform-inset.js +++ b/dependent-js/transform-inset.js @@ -1,29 +1,33 @@ const cloneRule = require('./clone-rule'); -module.exports = (decl, values) => 'logical' === values[0] - ? !values[4] || values[2] === values[4] - ? [ - decl.clone({ prop: 'top', value: values[1] }), - decl.clone({ prop: 'left', value: values[2] || values[1] }), - decl.clone({ prop: 'bottom', value: values[3] || values[1] }), - decl.clone({ prop: 'right', value: values[4] || values[2] || values[1] }) - ] : [ - cloneRule(decl, 'ltr').append([ - decl.clone({ prop: 'top', value: values[1] }), - decl.clone({ prop: 'left', value: values[2] || values[1] }), - decl.clone({ prop: 'bottom', value: values[3] || values[1] }), - decl.clone({ prop: 'right', value: values[4] || values[2] || values[1] }) - ]), - cloneRule(decl, 'rtl').append([ - decl.clone({ prop: 'top', value: values[1] }), - decl.clone({ prop: 'right', value: values[2] || values[1] }), - decl.clone({ prop: 'bottom', value: values[3] || values[1] }), - decl.clone({ prop: 'left', value: values[4] || values[2] || values[1] }) - ]) - ] - : [ - decl.clone({ prop: 'top', value: values[0] }), - decl.clone({ prop: 'right', value: values[1] || values[0] }), - decl.clone({ prop: 'bottom', value: values[2] || values[0] }), - decl.clone({ prop: 'left', value: values[3] || values[1] || values[0] }) +module.exports = (decl, values, dir) => { + if ('logical' !== values[0]) { + return [ + decl.clone({ prop: 'top', value: values[0] }), + decl.clone({ prop: 'right', value: values[1] || values[0] }), + decl.clone({ prop: 'bottom', value: values[2] || values[0] }), + decl.clone({ prop: 'left', value: values[3] || values[1] || values[0] }) + ]; + } + + const isLTR = !values[4] || values[4] === values[2]; + + const ltrDecls = [ + decl.clone({ prop: 'top', value: values[1] }), + decl.clone({ prop: 'left', value: values[2] || values[1] }), + decl.clone({ prop: 'bottom', value: values[3] || values[1] }), + decl.clone({ prop: 'right', value: values[4] || values[2] || values[1] }) + ]; + + const rtlDecls = [ + decl.clone({ prop: 'top', value: values[1] }), + decl.clone({ prop: 'right', value: values[2] || values[1] }), + decl.clone({ prop: 'bottom', value: values[3] || values[1] }), + decl.clone({ prop: 'left', value: values[4] || values[2] || values[1] }) + ]; + + return isLTR || 'ltr' === dir ? ltrDecls : 'rtl' === dir ? rtlDecls : [ + cloneRule(decl, 'ltr').append(ltrDecls), + cloneRule(decl, 'rtl').append(rtlDecls) ]; +} diff --git a/dependent-js/transform-side.js b/dependent-js/transform-side.js index c4a8b0b03e..8bde3fa53f 100644 --- a/dependent-js/transform-side.js +++ b/dependent-js/transform-side.js @@ -21,62 +21,79 @@ module.exports['block-end'] = (decl) => { }; // inset-inline, margin-inline, padding-inline -module.exports['inline'] = (decl, values) => 1 === values.length || 2 === values.length && values[0] === values[1] -? [ - cloneDecl(decl, '-left', values[0]), - cloneDecl(decl, '-right', values[1] || values[0]) -] -: [ - cloneRule(decl, 'ltr').append([ +module.exports['inline'] = (decl, values, dir) => { + const ltrDecls = [ cloneDecl(decl, '-left', values[0]), cloneDecl(decl, '-right', values[1] || values[0]) - ]), - cloneRule(decl, 'rtl').append([ + ]; + + const rtlDecls = [ cloneDecl(decl, '-right', values[0]), cloneDecl(decl, '-left', values[1] || values[0]) - ]), -]; + ]; + + const isLTR = 1 === values.length || 2 === values.length && values[0] === values[1]; + + return isLTR ? ltrDecls : 'ltr' === dir ? ltrDecls : 'rtl' === dir ? rtlDecls : [ + cloneRule(decl, 'ltr').append(ltrDecls), + cloneRule(decl, 'rtl').append(rtlDecls), + ]; +} // inset-inline-start, margin-inline-start, padding-inline-start -module.exports['inline-start'] = (decl) => [ - cloneRule(decl, 'ltr').append( - cloneDecl(decl, '-left', decl.value) - ), - cloneRule(decl, 'rtl').append( - cloneDecl(decl, '-right', decl.value) - ) -]; +module.exports['inline-start'] = (decl, values, dir) => { + const ltrDecl = cloneDecl(decl, '-left', decl.value); + const rtlDecl = cloneDecl(decl, '-right', decl.value); + + return 'ltr' === dir ? ltrDecl : 'rtl' === dir ? rtlDecl : [ + cloneRule(decl, 'ltr').append(ltrDecl), + cloneRule(decl, 'rtl').append(rtlDecl) + ]; +}; // inset-inline-end, margin-inline-end, padding-inline-end -module.exports['inline-end'] = (decl) => [ - cloneRule(decl, 'ltr').append( - cloneDecl(decl, '-right', decl.value) - ), - cloneRule(decl, 'rtl').append( - cloneDecl(decl, '-left', decl.value) - ) -]; +module.exports['inline-end'] = (decl, values, dir) => { + const ltrDecl = cloneDecl(decl, '-right', decl.value); + const rtlDecl = cloneDecl(decl, '-left', decl.value); + + return 'ltr' === dir ? ltrDecl : 'rtl' === dir ? rtlDecl : [ + cloneRule(decl, 'ltr').append(ltrDecl), + cloneRule(decl, 'rtl').append(rtlDecl) + ]; +}; // inset-start, margin-start, padding-start -module.exports['start'] = (decl, values) => [ - cloneRule(decl, 'ltr').append([ +module.exports['start'] = (decl, values, dir) => { + const ltrDecls = [ cloneDecl(decl, '-top', values[0]), cloneDecl(decl, '-left', values[1] || values[0]) - ]), - cloneRule(decl, 'rtl').append([ + ]; + + const rtlDecls = [ cloneDecl(decl, '-top', values[0]), cloneDecl(decl, '-right', values[1] || values[0]) - ]) -]; + ]; + + return 'ltr' === dir ? ltrDecls : 'rtl' === dir ? rtlDecls : [ + cloneRule(decl, 'ltr').append(ltrDecls), + cloneRule(decl, 'rtl').append(rtlDecls) + ]; +}; // inset-end, margin-end, padding-end -module.exports['end'] = (decl, values) => [ - cloneRule(decl, 'ltr').append([ +module.exports['end'] = (decl, values, dir) => { + const ltrDecls = [ cloneDecl(decl, '-bottom', values[0]), cloneDecl(decl, '-right', values[1] || values[0]) - ]), - cloneRule(decl, 'rtl').append([ + ]; + + const rtlDecls = [ cloneDecl(decl, '-bottom', values[0]), cloneDecl(decl, '-left', values[1] || values[0]) - ]) -]; + ]; + + return 'ltr' === dir ? ltrDecls : 'rtl' === dir ? rtlDecls : [ + cloneRule(decl, 'ltr').append(ltrDecls), + cloneRule(decl, 'rtl').append(rtlDecls) + ]; +}; diff --git a/dependent-js/transform-spacing.js b/dependent-js/transform-spacing.js index cbe4d4d830..537afc7e90 100644 --- a/dependent-js/transform-spacing.js +++ b/dependent-js/transform-spacing.js @@ -1,30 +1,34 @@ const cloneRule = require('./clone-rule'); -module.exports = (decl, values) => 'logical' === values[0] - ? !values[4] || values[4] === values[2] - ? decl.clone({ - value: decl.value.replace(/^\s*logical\s+/i, '') - }) - : [ - cloneRule(decl, 'ltr').append( - decl.clone({ - value: [ - values[1], - values[4] || values[2] || values[1], - values[3] || values[1], - values[2] || values[1] - ].join(' ') - }) - ), - cloneRule(decl, 'rtl').append( - decl.clone({ - value: [ - values[1], - values[2] || values[1], - values[3] || values[1], - values[4] || values[2] || values[1] - ].join(' ') - }) - ) - ] - : null; +module.exports = (decl, values, dir) => { + if ('logical' !== values[0]) { + return null; + } + + const isLTR = !values[4] || values[4] === values[2]; + + const ltrDecl = decl.clone({ + value: [ + values[1], + values[4] || values[2] || values[1], + values[3] || values[1], + values[2] || values[1] + ].join(' ') + }); + + const rtlDecl = decl.clone({ + value: [ + values[1], + values[2] || values[1], + values[3] || values[1], + values[4] || values[2] || values[1] + ].join(' ') + }); + + return isLTR ? decl.clone({ + value: decl.value.replace(/^\s*logical\s+/i, '') + }) : 'ltr' === dir ? ltrDecl : 'rtl' === dir ? rtlDecl : [ + cloneRule(decl, 'ltr').append(ltrDecl), + cloneRule(decl, 'rtl').append(rtlDecl) + ]; +}; diff --git a/dependent-js/transform-text-align.js b/dependent-js/transform-text-align.js index 7dc40d3020..9b74e03b21 100644 --- a/dependent-js/transform-text-align.js +++ b/dependent-js/transform-text-align.js @@ -1,21 +1,14 @@ const cloneRule = require('./clone-rule'); -module.exports = (decl) => /^start$/i.test(decl.value) - ? [ - cloneRule(decl, 'ltr').append([ - decl.clone({ value: 'left' }) - ]), - cloneRule(decl, 'rtl').append([ - decl.clone({ value: 'right' }) - ]) - ] - : /^end$/i.test(decl.value) - ? [ - cloneRule(decl, 'ltr').append([ - decl.clone({ value: 'right' }) - ]), - cloneRule(decl, 'rtl').append([ - decl.clone({ value: 'left' }) - ]) - ] - : null; +module.exports = (decl, values, dir) => { + const lDecl = decl.clone({ value: 'left' }); + const rDecl = decl.clone({ value: 'right' }); + + return /^start$/i.test(decl.value) ? 'ltr' === dir ? lDecl : 'rtl' === dir ? rDecl : [ + cloneRule(decl, 'ltr').append(lDecl), + cloneRule(decl, 'rtl').append(rDecl) + ] : /^end$/i.test(decl.value) ? 'ltr' === dir ? rDecl : 'rtl' === dir ? lDecl : [ + cloneRule(decl, 'ltr').append(rDecl), + cloneRule(decl, 'rtl').append(lDecl) + ] : null; +}; diff --git a/index.js b/index.js index e445026201..63dc709d20 100644 --- a/index.js +++ b/index.js @@ -42,13 +42,15 @@ const transforms = { }; // plugin -module.exports = postcss.plugin('postcss-logical-properties', () => (root) => { +module.exports = postcss.plugin('postcss-logical-properties', (opts) => (root) => { + const dir = Object(opts) === opts ? /^rtl$/i.test(opts.dir) ? 'rtl' : 'ltr' : false; + root.walkDecls((decl) => { const values = postcss.list.split(decl.value, /^border(-block|-inline|-start|-end)?(-width|-style|-color)?$/i.test(decl.prop) ? '/' : ' '); const prop = decl.prop.replace(matchSupportedProperties, '$2$5').toLowerCase(); if (prop in transforms) { - const replacer = transforms[prop](decl, values); + const replacer = transforms[prop](decl, values, dir); if (replacer) { decl.replaceWith(replacer); From ec00e0f3609c78ef9c57156a24aa0ea84920941f Mon Sep 17 00:00:00 2001 From: Jonathan Neal Date: Sat, 19 Aug 2017 20:52:52 -0400 Subject: [PATCH 498/795] Add "dir" tests --- .tape.js | 42 ++++++++++++++++++ test/border.ltr.expect.css | 81 ++++++++++++++++++++++++++++++++++ test/clear.ltr.expect.css | 7 +++ test/float.ltr.expect.css | 6 +++ test/inset.ltr.expect.css | 73 ++++++++++++++++++++++++++++++ test/margin.ltr.expect.css | 41 +++++++++++++++++ test/padding.ltr.expect.css | 41 +++++++++++++++++ test/text-align.ltr.expect.css | 6 +++ 8 files changed, 297 insertions(+) create mode 100644 test/border.ltr.expect.css create mode 100644 test/clear.ltr.expect.css create mode 100644 test/float.ltr.expect.css create mode 100644 test/inset.ltr.expect.css create mode 100644 test/margin.ltr.expect.css create mode 100644 test/padding.ltr.expect.css create mode 100644 test/text-align.ltr.expect.css diff --git a/.tape.js b/.tape.js index 05cce545a3..35915214be 100644 --- a/.tape.js +++ b/.tape.js @@ -3,21 +3,57 @@ module.exports = { 'border': { message: 'supports logical "border" property values' }, + 'border:ltr': { + message: 'supports logical "border" property values with { dir: "ltr" }', + options: { + dir: 'ltr' + } + }, 'clear': { message: 'supports logical "clear" property values' }, + 'clear:ltr': { + message: 'supports logical "clear" property values with { dir: "ltr" }', + options: { + dir: 'ltr' + } + }, 'float': { message: 'supports logical "float" property values' }, + 'float:ltr': { + message: 'supports logical "float" property values with { dir: "ltr" }', + options: { + dir: 'ltr' + } + }, 'inset': { message: 'supports logical "inset" properties' }, + 'inset:ltr': { + message: 'supports logical "inset" properties with { dir: "ltr" }', + options: { + dir: 'ltr' + } + }, 'margin': { message: 'supports logical "margin" properties' }, + 'margin:ltr': { + message: 'supports logical "margin" properties with { dir: "ltr" }', + options: { + dir: 'ltr' + } + }, 'padding': { message: 'supports logical "padding" properties' }, + 'padding:ltr': { + message: 'supports logical "padding" properties with { dir: "ltr" }', + options: { + dir: 'ltr' + } + }, 'resize': { message: 'supports logical "resize" properties' }, @@ -26,6 +62,12 @@ module.exports = { }, 'text-align': { message: 'supports logical "text-align" properties' + }, + 'text-align:ltr': { + message: 'supports logical "text-align" properties with { dir: "ltr" }', + options: { + dir: 'ltr' + } } } }; diff --git a/test/border.ltr.expect.css b/test/border.ltr.expect.css new file mode 100644 index 0000000000..330fe8b377 --- /dev/null +++ b/test/border.ltr.expect.css @@ -0,0 +1,81 @@ +test-border { + border: 1px solid black; + border-top: 2px solid black; + border-right: 3px solid black; + border-bottom: 2px solid black; + border-left: 3px solid black; + border-top: 4px solid black; + border-right: 5px solid black; + border-bottom: 6px solid black; + border-left: 5px solid black; + border-top: 7px solid black; + border-right: 8px solid black; + border-bottom: 9px solid black; + border-left: 8px solid black; + border-left: 10px solid black; + border-right: 10px solid black; + border-left: 11px solid black; + border-right: 11px solid black; + border-top: 12px solid black; + border-bottom: 12px solid black; + border-top: 13px solid black; + border-bottom: 13px solid black; + border-top: 15px solid black; + border-bottom: 16px solid black; +} + +test-flowing-border { + border: inherit; + border-top: 1px solid black; + border-left: 2px solid black; + border-bottom: 3px solid black; + border-right: 4px solid black; + border: inherit; + border-left: 5px solid black; + border-right: 6px solid black; + border: inherit; + border-left: 7px solid black; + border: inherit; + border-right: 8px solid black; + border: inherit; + border-top: 9px solid black; + border-left: 9px solid black; + border: inherit; + border-top: 10px solid black; + border-left: 11px solid black; + border: inherit; + border-bottom: 12px solid black; + border-right: 12px solid black; + border: inherit; + border-bottom: 13px solid black; + border-right: 14px solid black; + border: inherit; +} + +test-flowing-border-color { + border-color: inherit; + border-top-color: 1px solid black; + border-left-color: 2px solid black; + border-bottom-color: 3px solid black; + border-right-color: 4px solid black; + border-color: inherit; + border-left-color: 5px solid black; + border-right-color: 6px solid black; + border-color: inherit; + border-left-color: 7px solid black; + border-color: inherit; + border-right-color: 8px solid black; + border-color: inherit; + border-top-color: 9px solid black; + border-left-color: 9px solid black; + border-color: inherit; + border-top-color: 10px solid black; + border-left-color: 11px solid black; + border-color: inherit; + border-bottom-color: 12px solid black; + border-right-color: 12px solid black; + border-color: inherit; + border-bottom-color: 13px solid black; + border-right-color: 14px solid black; + border-color: inherit; +} diff --git a/test/clear.ltr.expect.css b/test/clear.ltr.expect.css new file mode 100644 index 0000000000..d05d2411bf --- /dev/null +++ b/test/clear.ltr.expect.css @@ -0,0 +1,7 @@ +test-clear { + clear: both; + clear: left; + clear: left; + clear: right; + clear: right; +} diff --git a/test/float.ltr.expect.css b/test/float.ltr.expect.css new file mode 100644 index 0000000000..590760ecaf --- /dev/null +++ b/test/float.ltr.expect.css @@ -0,0 +1,6 @@ +test-float { + float: left; + float: left; + float: right; + float: right; +} diff --git a/test/inset.ltr.expect.css b/test/inset.ltr.expect.css new file mode 100644 index 0000000000..352f602ccf --- /dev/null +++ b/test/inset.ltr.expect.css @@ -0,0 +1,73 @@ +test-inset { + top: 1px; + left: 1px; + bottom: 1px; + right: 1px; + top: 2px; + left: 3px; + bottom: 2px; + right: 3px; + top: 4px; + left: 5px; + bottom: 6px; + right: 5px; + top: 7px; + left: 8px; + bottom: 9px; + right: 8px; +} + +test-flowing-inset { + top: auto; + right: auto; + bottom: auto; + left: auto; + top: 1px; + left: 2px; + bottom: 3px; + right: 4px; + top: auto; + right: auto; + bottom: auto; + left: auto; + left: 5px; + right: 6px; + top: auto; + right: auto; + bottom: auto; + left: auto; + left: 7px; + top: auto; + right: auto; + bottom: auto; + left: auto; + right: 8px; + top: auto; + right: auto; + bottom: auto; + left: auto; + top: 9px; + left: 9px; + top: auto; + right: auto; + bottom: auto; + left: auto; + top: 10px; + left: 11px; + top: auto; + right: auto; + bottom: auto; + left: auto; + bottom: 12px; + right: 12px; + top: auto; + right: auto; + bottom: auto; + left: auto; + bottom: 13px; + right: 14px; + top: auto; + right: auto; + bottom: auto; + left: auto; +} diff --git a/test/margin.ltr.expect.css b/test/margin.ltr.expect.css new file mode 100644 index 0000000000..9d7d5b1e97 --- /dev/null +++ b/test/margin.ltr.expect.css @@ -0,0 +1,41 @@ +test-margin { + margin: 1px; + margin: 2px 3px; + margin: 4px 5px 6px; + margin: 7px 8px 9px 8px; + margin-left: 10px; + margin-right: 10px; + margin-left: 11px; + margin-right: 11px; + margin-top: 12px; + margin-bottom: 12px; + margin-top: 13px; + margin-bottom: 14px; + margin-top: 15px; + margin-bottom: 16px; +} + +test-flowing-margin { + margin: auto; + margin: 1px 4px 3px 2px; + margin: auto; + margin-left: 5px; + margin-right: 6px; + margin: auto; + margin-left: 7px; + margin: auto; + margin-right: 8px; + margin: auto; + margin-top: 9px; + margin-left: 9px; + margin: auto; + margin-top: 10px; + margin-left: 11px; + margin: auto; + margin-bottom: 12px; + margin-right: 12px; + margin: auto; + margin-bottom: 13px; + margin-right: 14px; + margin: auto; +} diff --git a/test/padding.ltr.expect.css b/test/padding.ltr.expect.css new file mode 100644 index 0000000000..1ccece6550 --- /dev/null +++ b/test/padding.ltr.expect.css @@ -0,0 +1,41 @@ +test-padding { + padding: 1px; + padding: 2px 3px; + padding: 4px 5px 6px; + padding: 7px 8px 9px 8px; + padding-left: 10px; + padding-right: 10px; + padding-left: 11px; + padding-right: 11px; + padding-top: 12px; + padding-bottom: 12px; + padding-top: 13px; + padding-bottom: 14px; + padding-top: 15px; + padding-bottom: 16px; +} + +test-flowing-padding { + padding: auto; + padding: 1px 4px 3px 2px; + padding: auto; + padding-left: 5px; + padding-right: 6px; + padding: auto; + padding-left: 7px; + padding: auto; + padding-right: 8px; + padding: auto; + padding-top: 9px; + padding-left: 9px; + padding: auto; + padding-top: 10px; + padding-left: 11px; + padding: auto; + padding-bottom: 12px; + padding-right: 12px; + padding: auto; + padding-bottom: 13px; + padding-right: 14px; + padding: auto; +} diff --git a/test/text-align.ltr.expect.css b/test/text-align.ltr.expect.css new file mode 100644 index 0000000000..7318c05c7e --- /dev/null +++ b/test/text-align.ltr.expect.css @@ -0,0 +1,6 @@ +test-text-align { + text-align: left; + text-align: left; + text-align: right; + text-align: right; +} From 00ef6310566fdaee596bbbf50e33468aed49026f Mon Sep 17 00:00:00 2001 From: Jonathan Neal Date: Sun, 20 Aug 2017 00:09:24 -0400 Subject: [PATCH 499/795] Update documentation --- README.md | 37 ++++++++++++++++++++++++++++--------- package.json | 20 +++++++++++++++----- 2 files changed, 43 insertions(+), 14 deletions(-) diff --git a/README.md b/README.md index 774c48ece5..05855fb252 100644 --- a/README.md +++ b/README.md @@ -5,8 +5,8 @@ [![Windows Build Status][win-img]][win-url] [![Gitter Chat][git-img]][git-url] -[PostCSS Logical Properties] lets you use nearly 60 new [logical properties] -and a half dozen flow-relative values in CSS. +[PostCSS Logical Properties] lets you use Logical Properties and Values in +CSS, following the [CSS Logical Properties and Values Level 1] specification. ```css .banner { @@ -34,6 +34,15 @@ and a half dozen flow-relative values in CSS. .banner { resize: vertical; } + +/* used with { dir: 'ltr' } option */ + +.banner { + color: #222222; + top: 0; left: 5px; bottom: 10px; right: 5px; + padding-left: 20px; padding-right: 40px; + resize: vertical; +} ``` These shorthand properties set values for physical properties by default. @@ -85,15 +94,25 @@ properties: --- -[PostCSS Logical Properties] changes the selector weight of flow-relative -declarations and requires at least one [dir] attribute in your HTML. If you -don’t have any [dir] attributes, consider using the following JavaScript: +By default, [PostCSS Logical Properties] changes the selector weight of +flow-relative declarations and requires at least one [dir] attribute in your +HTML. If you don’t have any [dir] attributes, consider using the following +JavaScript: ```js // force at least one dir attribute (this can run at any time) document.documentElement.dir=document.documentElement.dir||'ltr'; ``` +Otherwise, consider using the `dir` option to transform all logical properties +and values to a specific direction. + +```js +require('postcss-logical')({ + dir: 'ltr' +}); +``` + ## Usage Add [PostCSS Logical Properties] to your build tool: @@ -122,7 +141,7 @@ Use [PostCSS Logical Properties] as a plugin: ```js postcss([ - require('postcss-logical')() + require('postcss-logical')(/* options */) ]).process(YOUR_CSS); ``` @@ -142,7 +161,7 @@ var postcss = require('gulp-postcss'); gulp.task('css', function () { return gulp.src('./src/*.css').pipe( postcss([ - require('postcss-logical')() + require('postcss-logical')(/* options */) ]) ).pipe( gulp.dest('.') @@ -167,7 +186,7 @@ grunt.initConfig({ postcss: { options: { use: [ - require('postcss-logical')() + require('postcss-logical')(/* options */) ] }, dist: { @@ -187,7 +206,7 @@ grunt.initConfig({ [git-img]: https://img.shields.io/badge/chat-gitter-blue.svg [PostCSS Logical Properties]: https://github.com/jonathantneal/postcss-logical-properties -[logical properties]: https://drafts.csswg.org/css-logical/ +[CSS Logical Properties and Values Level 1]: https://drafts.csswg.org/css-logical/ [PostCSS]: https://github.com/postcss/postcss [Gulp PostCSS]: https://github.com/postcss/gulp-postcss [Grunt PostCSS]: https://github.com/nDmitry/grunt-postcss diff --git a/package.json b/package.json index f9e7cdb6d1..b06b47c5c7 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "postcss-logical", "version": "1.0.2", - "description": "Use logical properties and flow-relative values in CSS", + "description": "Use logical properties and values in CSS", "author": "Jonathan Neal ", "license": "CC0-1.0", "repository": "jonathantneal/postcss-logical-properties", @@ -41,15 +41,25 @@ "logical", "flow", "relative", - "ltr", - "rtl", + "property", "properties", "values", + "ltr", + "rtl", + "dir", "directions", - "dirs", + "directional", "inline", "block", "start", - "end" + "end", + "align", + "border", + "clear", + "float", + "margin", + "padding", + "size", + "text" ] } From 83e29ab2339d12e1e333fe37102d3a9470441f2a Mon Sep 17 00:00:00 2001 From: Jonathan Neal Date: Sat, 9 Sep 2017 21:02:52 -0400 Subject: [PATCH 500/795] Update dependencies --- package.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index b06b47c5c7..3becbfa0f9 100644 --- a/package.json +++ b/package.json @@ -23,10 +23,10 @@ "node": ">=4.0.0" }, "dependencies": { - "postcss": "^6.0.9" + "postcss": "^6.0.11" }, "devDependencies": { - "eslint": "^4.5.0", + "eslint": "^4.6.1", "eslint-config-dev": "2.0.0", "postcss-tape": "2.0.1", "pre-commit": "^1.2.2" From f04a9af72d183907b4f65608f5ac8819f012657e Mon Sep 17 00:00:00 2001 From: Jonathan Neal Date: Sat, 9 Sep 2017 21:03:02 -0400 Subject: [PATCH 501/795] Ignore package-lock.json --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index f8952c957f..995098afd2 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,5 @@ node_modules +package-lock.json .* !.appveyor.yml !.editorconfig From b6758b7ddfaee4dd9d7a1c49bbf7af5dd4ead267 Mon Sep 17 00:00:00 2001 From: Jonathan Neal Date: Sat, 9 Sep 2017 21:05:01 -0400 Subject: [PATCH 502/795] Add CSS Standard Status --- README.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/README.md b/README.md index 05855fb252..60e4fa511e 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,7 @@ # PostCSS Logical Properties [PostCSS Logo][postcss] [![NPM Version][npm-img]][npm-url] +[![CSS Standard Status][css-img]][css-url] [![Linux Build Status][cli-img]][cli-url] [![Windows Build Status][win-img]][win-url] [![Gitter Chat][git-img]][git-url] @@ -200,6 +201,8 @@ grunt.initConfig({ [npm-img]: https://img.shields.io/npm/v/postcss-logical.svg [cli-url]: https://travis-ci.org/jonathantneal/postcss-logical-properties [cli-img]: https://img.shields.io/travis/jonathantneal/postcss-logical-properties.svg +[css-img]: https://jonathantneal.github.io/css-db/badge/css-logical.svg +[css-url]: https://jonathantneal.github.io/css-db/#css-logical [win-url]: https://ci.appveyor.com/project/jonathantneal/postcss-logical-properties [win-img]: https://img.shields.io/appveyor/ci/jonathantneal/postcss-logical-properties.svg [git-url]: https://gitter.im/postcss/postcss From 7afb45a0f75c8c6385086f6ae352b4f0e2bdd4a5 Mon Sep 17 00:00:00 2001 From: Jonathan Neal Date: Sat, 9 Sep 2017 21:15:53 -0400 Subject: [PATCH 503/795] Update dependencies --- package.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index fed703bc5c..18e48a1ee4 100644 --- a/package.json +++ b/package.json @@ -23,10 +23,10 @@ "node": ">=4.0.0" }, "dependencies": { - "postcss": "^6.0.1" + "postcss": "^6.0.11" }, "devDependencies": { - "eslint": "^3.19.0", + "eslint": "^4.6.1", "eslint-config-dev": "^2.0.0", "postcss-tape": "^2.0.1", "pre-commit": "^1.2.2" From 27c3311462e518cc372cd85c2e86314af22f68a3 Mon Sep 17 00:00:00 2001 From: Jonathan Neal Date: Sat, 9 Sep 2017 21:16:43 -0400 Subject: [PATCH 504/795] Update gitignore --- .gitignore | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index b8fc2cda3a..995098afd2 100644 --- a/.gitignore +++ b/.gitignore @@ -1,8 +1,10 @@ node_modules +package-lock.json .* +!.appveyor.yml +!.editorconfig !.gitignore !.tape.js !.travis.yml *.log* *.result.css -package-lock.json From d868e492bebb3130463f76c4db8a9b2a6e8cb4ed Mon Sep 17 00:00:00 2001 From: Jonathan Neal Date: Sat, 9 Sep 2017 21:17:37 -0400 Subject: [PATCH 505/795] Add CSS Standard Status --- README.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/README.md b/README.md index a4f34f9150..186f63b809 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,7 @@ # PostCSS Nesting [PostCSS Logo][postcss] [![NPM Version][npm-img]][npm-url] +[![CSS Standard Status][css-img]][css-url] [![Build Status][cli-img]][cli-url] [![Licensing][lic-img]][lic-url] [![Changelog][log-img]][log-url] @@ -116,6 +117,8 @@ grunt.initConfig({ [npm-img]: https://img.shields.io/npm/v/postcss-nesting.svg [cli-url]: https://travis-ci.org/jonathantneal/postcss-nesting [cli-img]: https://img.shields.io/travis/jonathantneal/postcss-nesting.svg +[css-img]: https://jonathantneal.github.io/css-db/badge/css-nesting.svg +[css-url]: https://jonathantneal.github.io/css-db/#css-nesting [lic-url]: LICENSE.md [lic-img]: https://img.shields.io/npm/l/postcss-nesting.svg [log-url]: CHANGELOG.md From 44f347a4a1581e40a5bc2023c8ca39e8e3ad69ca Mon Sep 17 00:00:00 2001 From: Jonathan Neal Date: Sat, 9 Sep 2017 21:31:15 -0400 Subject: [PATCH 506/795] Update dependencies --- package.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/package.json b/package.json index ad76e1e371..258b47aa2e 100644 --- a/package.json +++ b/package.json @@ -22,12 +22,12 @@ "node": ">=4.0.0" }, "dependencies": { - "browserslist": "^2.2.2", - "postcss": "^6.0.8", + "browserslist": "^2.4.0", + "postcss": "^6.0.11", "postcss-selector-parser": "^2.2.3" }, "devDependencies": { - "eslint": "^4.3.0", + "eslint": "^4.6.1", "eslint-config-dev": "2.0.0", "postcss-tape": "2.0.1", "pre-commit": "^1.2.2" From 677d0112d6fd2121070659d752d3b653e58a15dd Mon Sep 17 00:00:00 2001 From: Jonathan Neal Date: Sat, 9 Sep 2017 21:31:25 -0400 Subject: [PATCH 507/795] Update gitignore --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index f8952c957f..995098afd2 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,5 @@ node_modules +package-lock.json .* !.appveyor.yml !.editorconfig From bc926c538285b71c161870ef0d4c695855fd9ff6 Mon Sep 17 00:00:00 2001 From: Jonathan Neal Date: Sat, 9 Sep 2017 21:50:42 -0400 Subject: [PATCH 508/795] Add CSS Standard Status --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 4f09621c25..83a88b17d9 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,6 @@ # PostCSS Custom Selectors +[![CSS Standard Status](https://jonathantneal.github.io/css-db/badge/css-extensions-custom-selectors.svg)](https://jonathantneal.github.io/css-db/#css-extensions-custom-selectors) [![Build Status](https://travis-ci.org/postcss/postcss-custom-selectors.svg?branch=master)](https://travis-ci.org/postcss/postcss-custom-selectors) [![NPM Downloads](https://img.shields.io/npm/dm/postcss-custom-selectors.svg?style=flat)](https://www.npmjs.com/package/postcss-custom-selectors) [![NPM Version](http://img.shields.io/npm/v/postcss-custom-selectors.svg?style=flat)](https://www.npmjs.com/package/postcss-custom-selectors) From 8f03744c682995bd9f481dbb3f8db9eaf2a8e926 Mon Sep 17 00:00:00 2001 From: Jonathan Neal Date: Sat, 9 Sep 2017 21:55:28 -0400 Subject: [PATCH 509/795] Add CSS Standard Status --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 254b9b21df..c5824cb66e 100755 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# postcss-custom-media [![Build Status](https://travis-ci.org/postcss/postcss-custom-media.png)](https://travis-ci.org/postcss/postcss-custom-media) +# postcss-custom-media [![CSS Standard Status](https://jonathantneal.github.io/css-db/badge/mediaqueries-5-custom-mq.svg)](https://jonathantneal.github.io/css-db/#mediaqueries-5-custom-mq) [![Build Status](https://travis-ci.org/postcss/postcss-custom-media.png)](https://travis-ci.org/postcss/postcss-custom-media) > [PostCSS](https://github.com/postcss/postcss) plugin to transform [W3C CSS Custom Media Queries](https://drafts.csswg.org/mediaqueries-5/#custom-mq) syntax to more compatible CSS. From d45e8c9206b8cffac37b839df14fc5d749aff262 Mon Sep 17 00:00:00 2001 From: Jonathan Neal Date: Sat, 9 Sep 2017 22:01:26 -0400 Subject: [PATCH 510/795] Add CSS Standard Status --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 9c097ca131..098cb6e703 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# postcss-selector-not [![Build Status](https://travis-ci.org/postcss/postcss-selector-not.svg?branch=master)](https://travis-ci.org/postcss/postcss-selector-not) +# postcss-selector-not [![CSS Standard Status](https://jonathantneal.github.io/css-db/badge/selectors-negation.svg)](https://jonathantneal.github.io/css-db/#selectors-negation) [![Build Status](https://travis-ci.org/postcss/postcss-selector-not.svg?branch=master)](https://travis-ci.org/postcss/postcss-selector-not) > PostCSS plugin to transform `:not()` W3C CSS leve 4 pseudo class to :not() CSS level 3 selectors From e299d4d040084e464dffe4a57b3b094159c58392 Mon Sep 17 00:00:00 2001 From: Jonathan Neal Date: Sat, 9 Sep 2017 22:04:10 -0400 Subject: [PATCH 511/795] Add CSS Standard Status --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 4bf62d7ada..d77a85564f 100755 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# postcss-color-hex-alpha [![Build Status](https://travis-ci.org/postcss/postcss-color-hex-alpha.png)](https://travis-ci.org/postcss/postcss-color-hex-alpha) +# postcss-color-hex-alpha [![CSS Standard Status](https://jonathantneal.github.io/css-db/badge/css-color-hex-notation.svg)](https://jonathantneal.github.io/css-db/#css-color-hex-notation) [![Build Status](https://travis-ci.org/postcss/postcss-color-hex-alpha.png)](https://travis-ci.org/postcss/postcss-color-hex-alpha) > [PostCSS](https://github.com/postcss/postcss) plugin to transform [W3C RGBA hexadecimal notations (#RRGGBBAA or #RGBA)](http://dev.w3.org/csswg/css-color/#hex-notation) to more compatible CSS (rgba()). From 42ad9ecd8f9ff26b8b988756efb36a251ecb8dbd Mon Sep 17 00:00:00 2001 From: Jonathan Neal Date: Sat, 9 Sep 2017 22:06:00 -0400 Subject: [PATCH 512/795] Add CSS Standard Status --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 49c109cbfb..a8ed0e89ab 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,6 @@ # PostCSS Media Minmax +[![CSS Standard Status](https://jonathantneal.github.io/css-db/badge/mediaqueries-mq-ranges.svg)](https://jonathantneal.github.io/css-db/#mediaqueries-mq-ranges) [![Build Status](https://travis-ci.org/postcss/postcss-media-minmax.svg?branch=master)](https://travis-ci.org/postcss/postcss-media-minmax) [![NPM Downloads](https://img.shields.io/npm/dm/postcss-media-minmax.svg?style=flat)](https://www.npmjs.com/package/postcss-media-minmax) [![NPM Version](http://img.shields.io/npm/v/postcss-media-minmax.svg?style=flat)](https://www.npmjs.com/package/postcss-media-minmax) From 016dc99d3733e4519c5573130c521c08d5f555e9 Mon Sep 17 00:00:00 2001 From: Jonathan Neal Date: Sat, 9 Sep 2017 22:07:25 -0400 Subject: [PATCH 513/795] Add CSS Standard Status --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index fe7577d136..e31b60e591 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# postcss-selector-matches [![Build Status](https://travis-ci.org/postcss/postcss-selector-matches.svg?branch=master)](https://travis-ci.org/postcss/postcss-selector-matches) +# postcss-selector-matches [![CSS Standard Status](https://jonathantneal.github.io/css-db/badge/selectors-matches.svg)](https://jonathantneal.github.io/css-db/#selectors-matches) [![Build Status](https://travis-ci.org/postcss/postcss-selector-matches.svg?branch=master)](https://travis-ci.org/postcss/postcss-selector-matches) > PostCSS plugin to transform `:matches()` W3C CSS pseudo class to more compatible CSS selectors From 4519205cbb576e254d7bcab315d6f625a944c09d Mon Sep 17 00:00:00 2001 From: Jonathan Neal Date: Sat, 9 Sep 2017 22:29:14 -0400 Subject: [PATCH 514/795] Organize README.md - Remove Windows Build Status badge - Add Licensing badge - Update specification title - Organize badges --- README.md | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/README.md b/README.md index 60e4fa511e..0636163572 100644 --- a/README.md +++ b/README.md @@ -1,13 +1,13 @@ # PostCSS Logical Properties [PostCSS Logo][postcss] -[![NPM Version][npm-img]][npm-url] [![CSS Standard Status][css-img]][css-url] -[![Linux Build Status][cli-img]][cli-url] -[![Windows Build Status][win-img]][win-url] +[![NPM Version][npm-img]][npm-url] +[![Build Status][cli-img]][cli-url] +[![Licensing][lic-img]][lic-url] [![Gitter Chat][git-img]][git-url] [PostCSS Logical Properties] lets you use Logical Properties and Values in -CSS, following the [CSS Logical Properties and Values Level 1] specification. +CSS, following the [CSS Logical Properties and Values] specification. ```css .banner { @@ -197,19 +197,19 @@ grunt.initConfig({ }); ``` -[npm-url]: https://www.npmjs.com/package/postcss-logical -[npm-img]: https://img.shields.io/npm/v/postcss-logical.svg [cli-url]: https://travis-ci.org/jonathantneal/postcss-logical-properties [cli-img]: https://img.shields.io/travis/jonathantneal/postcss-logical-properties.svg [css-img]: https://jonathantneal.github.io/css-db/badge/css-logical.svg [css-url]: https://jonathantneal.github.io/css-db/#css-logical -[win-url]: https://ci.appveyor.com/project/jonathantneal/postcss-logical-properties -[win-img]: https://img.shields.io/appveyor/ci/jonathantneal/postcss-logical-properties.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-logical.svg +[npm-url]: https://www.npmjs.com/package/postcss-logical +[npm-img]: https://img.shields.io/npm/v/postcss-logical.svg -[PostCSS Logical Properties]: https://github.com/jonathantneal/postcss-logical-properties -[CSS Logical Properties and Values Level 1]: https://drafts.csswg.org/css-logical/ -[PostCSS]: https://github.com/postcss/postcss +[CSS Logical Properties and Values]: https://drafts.csswg.org/css-logical/ [Gulp PostCSS]: https://github.com/postcss/gulp-postcss [Grunt PostCSS]: https://github.com/nDmitry/grunt-postcss +[PostCSS]: https://github.com/postcss/postcss +[PostCSS Logical Properties]: https://github.com/jonathantneal/postcss-logical-properties From bfb37c33092bea70a00a93a7d04c26cb7d95edad Mon Sep 17 00:00:00 2001 From: Jonathan Neal Date: Sat, 9 Sep 2017 22:30:04 -0400 Subject: [PATCH 515/795] Update README - Organize badges - Update CSS Nesting specification title --- README.md | 22 +++++++++------------- 1 file changed, 9 insertions(+), 13 deletions(-) diff --git a/README.md b/README.md index 186f63b809..fd81abcea1 100644 --- a/README.md +++ b/README.md @@ -1,14 +1,13 @@ # PostCSS Nesting [PostCSS Logo][postcss] -[![NPM Version][npm-img]][npm-url] [![CSS Standard Status][css-img]][css-url] +[![NPM Version][npm-img]][npm-url] [![Build Status][cli-img]][cli-url] [![Licensing][lic-img]][lic-url] -[![Changelog][log-img]][log-url] [![Gitter Chat][git-img]][git-url] [PostCSS Nesting] lets you nest style rules inside each other, following the -[CSS Nesting Module Level 3] specification. +[CSS Nesting] specification. ```css a, b { @@ -113,22 +112,19 @@ grunt.initConfig({ }); ``` -[npm-url]: https://www.npmjs.com/package/postcss-nesting -[npm-img]: https://img.shields.io/npm/v/postcss-nesting.svg [cli-url]: https://travis-ci.org/jonathantneal/postcss-nesting [cli-img]: https://img.shields.io/travis/jonathantneal/postcss-nesting.svg [css-img]: https://jonathantneal.github.io/css-db/badge/css-nesting.svg [css-url]: https://jonathantneal.github.io/css-db/#css-nesting -[lic-url]: LICENSE.md -[lic-img]: https://img.shields.io/npm/l/postcss-nesting.svg -[log-url]: CHANGELOG.md -[log-img]: https://img.shields.io/badge/changelog-md-blue.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-nesting.svg +[npm-url]: https://www.npmjs.com/package/postcss-nesting +[npm-img]: https://img.shields.io/npm/v/postcss-nesting.svg -[PostCSS Nesting]: https://github.com/jonathantneal/postcss-nesting -[PostCSS]: https://github.com/postcss/postcss +[CSS Nesting]: http://tabatkins.github.io/specs/css-nesting/ [Gulp PostCSS]: https://github.com/postcss/gulp-postcss [Grunt PostCSS]: https://github.com/nDmitry/grunt-postcss - -[CSS Nesting Module Level 3]: http://tabatkins.github.io/specs/css-nesting/ +[PostCSS]: https://github.com/postcss/postcss +[PostCSS Nesting]: https://github.com/jonathantneal/postcss-nesting From c264ac75604e48200e426ada1ed7be48b5bed986 Mon Sep 17 00:00:00 2001 From: Jonathan Neal Date: Sat, 9 Sep 2017 22:31:45 -0400 Subject: [PATCH 516/795] Update README - Add CSS Standard Status - Add Licensing badge - Remove Windows Build Status badge --- README.md | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index 58df6c9064..c693b7c257 100644 --- a/README.md +++ b/README.md @@ -1,8 +1,9 @@ # PostCSS :dir() [PostCSS Logo][postcss] +[![CSS Standard Status][css-img]][css-url] [![NPM Version][npm-img]][npm-url] -[![Linux Build Status][cli-img]][cli-url] -[![Windows Build Status][win-img]][win-url] +[![Build Status][cli-img]][cli-url] +[![Licensing][lic-img]][lic-url] [![Gitter Chat][git-img]][git-url] [PostCSS :dir()] lets you use the `:dir` pseudo-class in CSS. @@ -206,17 +207,19 @@ require('postcss-dir-pseudo-class')({ *Note: The `:root` pseudo-class is added here to preserve the weight of the original selector.* -[npm-url]: https://www.npmjs.com/package/postcss-dir-pseudo-class -[npm-img]: https://img.shields.io/npm/v/postcss-dir-pseudo-class.svg [cli-url]: https://travis-ci.org/jonathantneal/postcss-dir-pseudo-class [cli-img]: https://img.shields.io/travis/jonathantneal/postcss-dir-pseudo-class.svg -[win-url]: https://ci.appveyor.com/project/jonathantneal/postcss-dir-pseudo-class -[win-img]: https://img.shields.io/appveyor/ci/jonathantneal/postcss-dir-pseudo-class.svg +[css-img]: https://jonathantneal.github.io/css-db/badge/selectors-the-dir-pseudo.svg +[css-url]: https://jonathantneal.github.io/css-db/#selectors-the-dir-pseudo [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-dir-pseudo-class.svg +[npm-url]: https://www.npmjs.com/package/postcss-dir-pseudo-class +[npm-img]: https://img.shields.io/npm/v/postcss-dir-pseudo-class.svg -[PostCSS :dir()]: https://github.com/jonathantneal/postcss-dir-pseudo-class -[PostCSS]: https://github.com/postcss/postcss +[browserslist]: https://github.com/ai/browserslist [Gulp PostCSS]: https://github.com/postcss/gulp-postcss [Grunt PostCSS]: https://github.com/nDmitry/grunt-postcss -[browserslist]: https://github.com/ai/browserslist +[PostCSS]: https://github.com/postcss/postcss +[PostCSS :dir()]: https://github.com/jonathantneal/postcss-dir-pseudo-class From a70212a8427ee134f605aee346970becca9f0d29 Mon Sep 17 00:00:00 2001 From: Jonathan Neal Date: Sat, 9 Sep 2017 23:09:09 -0400 Subject: [PATCH 517/795] Update dependencies --- package.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index 9a1778c13e..c1fdcc287b 100644 --- a/package.json +++ b/package.json @@ -22,11 +22,11 @@ "node": ">=4.0.0" }, "dependencies": { - "postcss": "^6.0.1", + "postcss": "^6.0.11", "postcss-selector-parser": "^2.2.3" }, "devDependencies": { - "eslint": "^3.19.0", + "eslint": "^4.6.1", "eslint-config-dev": "2.0.0", "postcss-tape": "2.0.1", "pre-commit": "^1.2.2" From 806ae5b28169d933a0bf9340fbb746c35ee3f89f Mon Sep 17 00:00:00 2001 From: Jonathan Neal Date: Sat, 9 Sep 2017 23:10:03 -0400 Subject: [PATCH 518/795] Add .editorconfig --- .editorconfig | 15 +++++++++++++++ 1 file changed, 15 insertions(+) create mode 100644 .editorconfig diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000000..e06d7982bc --- /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 From 4d07b5951afd316b1b9dcdeeee2e6cfec6ad89d6 Mon Sep 17 00:00:00 2001 From: Jonathan Neal Date: Sat, 9 Sep 2017 23:10:16 -0400 Subject: [PATCH 519/795] Update .gitignore --- .gitignore | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.gitignore b/.gitignore index 0de7b9c259..995098afd2 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,8 @@ node_modules +package-lock.json .* +!.appveyor.yml +!.editorconfig !.gitignore !.tape.js !.travis.yml From 1cdccca7c6fdf255da5b654e9b4866c45a0b78b0 Mon Sep 17 00:00:00 2001 From: Jonathan Neal Date: Sat, 9 Sep 2017 23:11:04 -0400 Subject: [PATCH 520/795] Add CSS Standard Status --- README.md | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index aaea603d38..0a358b5542 100644 --- a/README.md +++ b/README.md @@ -1,9 +1,9 @@ # :any-link [PostCSS Logo][postcss] +[![CSS Standard Status][css-img]][css-url] [![NPM Version][npm-img]][npm-url] [![Build Status][cli-img]][cli-url] [![Licensing][lic-img]][lic-url] -[![Changelog][log-img]][log-url] [![Gitter Chat][git-img]][git-url] [:any-link] lets you to use the proposed [`:any-link`] pseudo-class in CSS. @@ -129,22 +129,22 @@ Here are a few other ways to simulate the effect of [PostCSS Pseudo-Class Any-Li :link, :visited { /* ... */ } ``` -[npm-url]: https://www.npmjs.com/package/postcss-pseudo-class-any-link -[npm-img]: https://img.shields.io/npm/v/postcss-pseudo-class-any-link.svg [cli-url]: https://travis-ci.org/jonathantneal/postcss-pseudo-class-any-link [cli-img]: https://img.shields.io/travis/jonathantneal/postcss-pseudo-class-any-link.svg -[lic-url]: LICENSE.md -[lic-img]: https://img.shields.io/npm/l/postcss-pseudo-class-any-link.svg -[log-url]: CHANGELOG.md -[log-img]: https://img.shields.io/badge/changelog-md-blue.svg +[css-url]: https://jonathantneal.github.io/css-db/#selectors-any-link-pseudo +[css-img]: https://jonathantneal.github.io/css-db/badge/selectors-any-link-pseudo.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-pseudo-class-any-link.svg +[npm-url]: https://www.npmjs.com/package/postcss-pseudo-class-any-link +[npm-img]: https://img.shields.io/npm/v/postcss-pseudo-class-any-link.svg -[:any-link]: https://github.com/jonathantneal/postcss-pseudo-class-any-link [`:any-link`]: http://dev.w3.org/csswg/selectors/#any-link-pseudo [`:link`]: http://dev.w3.org/csswg/selectors/#link-pseudo [`:visited`]: http://dev.w3.org/csswg/selectors/#visited-pseudo -[proposal]: http://dev.w3.org/csswg/selectors/ -[PostCSS]: https://github.com/postcss/postcss +[:any-link]: https://github.com/jonathantneal/postcss-pseudo-class-any-link [Gulp PostCSS]: https://github.com/postcss/gulp-postcss [Grunt PostCSS]: https://github.com/nDmitry/grunt-postcss +[PostCSS]: https://github.com/postcss/postcss +[proposal]: http://dev.w3.org/csswg/selectors/ From 129f75068200da5d39df155387f9993d4ce57ebd Mon Sep 17 00:00:00 2001 From: Brett Jankord Date: Fri, 15 Sep 2017 11:58:19 -0500 Subject: [PATCH 521/795] README: Document compiling fallback values. (#75) I wasn't sure if this was possible with the plugin so I coded it up and it worked. It would be cool to note this in the README so others can save some time by looking at the README. --- README.md | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/README.md b/README.md index 2648f134de..3ecb2026f6 100755 --- a/README.md +++ b/README.md @@ -59,6 +59,24 @@ div { } ``` +You can also compile CSS custom properties with their fallback value. + +Using this `input.css`: + +```css +div { + color: var(--color, #f00); +} +``` + +you will get: + +```css +div { + color: #f00; +} +``` + Note that plugin returns itself in order to expose a `setVariables` function that allow you to programmatically change the variables. From 7acd5599a04ce95f8ed5a97aa12c9b9062a263ff Mon Sep 17 00:00:00 2001 From: Jonathan Neal Date: Fri, 15 Sep 2017 12:58:58 -0400 Subject: [PATCH 522/795] README: Add CSS Standard Status (#78) --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 3ecb2026f6..33e5e1c114 100755 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# postcss-custom-properties [![Build Status](https://travis-ci.org/postcss/postcss-custom-properties.svg)](https://travis-ci.org/postcss/postcss-custom-properties) +# postcss-custom-properties [![CSS Standard Status](https://jonathantneal.github.io/css-db/badge/css-variables.svg)](https://jonathantneal.github.io/css-db/#css-variables) [![Build Status](https://travis-ci.org/postcss/postcss-custom-properties.svg)](https://travis-ci.org/postcss/postcss-custom-properties) > [PostCSS](https://github.com/postcss/postcss) plugin to transform [W3C CSS Custom Properties for ~~cascading~~ variables](http://www.w3.org/TR/css-variables/) syntax to more compatible CSS. From 5e2fc78841acecad555b42eeec52ff4d0074ed24 Mon Sep 17 00:00:00 2001 From: Jonathan Neal Date: Mon, 18 Sep 2017 13:09:45 -0400 Subject: [PATCH 523/795] Update devDependencies --- package.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index 18e48a1ee4..38be6fe7ed 100644 --- a/package.json +++ b/package.json @@ -26,9 +26,9 @@ "postcss": "^6.0.11" }, "devDependencies": { - "eslint": "^4.6.1", + "eslint": "^4.7.0", "eslint-config-dev": "^2.0.0", - "postcss-tape": "^2.0.1", + "postcss-tape": "^2.1.0", "pre-commit": "^1.2.2" }, "eslintConfig": { From 8de8fc8e9a3d7d106c971084a7590dd9e20d7d3a Mon Sep 17 00:00:00 2001 From: Jonathan Neal Date: Mon, 18 Sep 2017 13:12:56 -0400 Subject: [PATCH 524/795] Reduce the splitting of rules --- lib/get-closest-rule.js | 12 ++++++++++++ lib/transform-after-nodes.js | 8 +++++--- lib/transform-nesting-atrule.js | 24 ++++++++++++++++++++++-- 3 files changed, 39 insertions(+), 5 deletions(-) create mode 100644 lib/get-closest-rule.js diff --git a/lib/get-closest-rule.js b/lib/get-closest-rule.js new file mode 100644 index 0000000000..62b9bff5c2 --- /dev/null +++ b/lib/get-closest-rule.js @@ -0,0 +1,12 @@ +'use strict'; + +// return the closest rule +module.exports = (node) => { + let selectorParent = node.parent; + + while (selectorParent && selectorParent.type !== 'rule') { + selectorParent = selectorParent.parent; + } + + return selectorParent; +}; diff --git a/lib/transform-after-nodes.js b/lib/transform-after-nodes.js index ba2acd68bc..7d6f0999ed 100644 --- a/lib/transform-after-nodes.js +++ b/lib/transform-after-nodes.js @@ -8,11 +8,13 @@ module.exports = (node) => { if (affectedNodes.length) { // insert an empty parent clone after the parent - const emptyParentClone = cleanNode(node.parent.clone()).removeAll(); + const afterParent = cleanNode(node.parent.clone()).removeAll(); - node.parent.after(emptyParentClone); + node.parent.after(afterParent); // append the affected nodes to the empty parent clone - emptyParentClone.append(affectedNodes); + afterParent.append(affectedNodes); + + return afterParent; } }; diff --git a/lib/transform-nesting-atrule.js b/lib/transform-nesting-atrule.js index dca39cf0a0..739b4150b6 100644 --- a/lib/transform-nesting-atrule.js +++ b/lib/transform-nesting-atrule.js @@ -1,6 +1,7 @@ // tooling const cleanNode = require('./clean-node'); const comma = require('postcss').list.comma; +const getClosestRule = require('./get-closest-rule'); const mergeSelectors = require('./merge-selectors'); const postcss = require('postcss'); const transformAfterNodes = require('./transform-after-nodes'); @@ -11,12 +12,15 @@ module.exports = (node) => { cleanNode(node).nodes.forEach(cleanNode); // affected nodes after the current node moved into a cloned parent node - transformAfterNodes(node); + const afterParent = transformAfterNodes(node); + + // get the closest rule + const selectorParent = getClosestRule(node); // clone of the atrule as a rule const rule = postcss.rule({ // merge selectors - selectors: mergeSelectors(node.parent.selectors, node.params), + selectors: mergeSelectors(selectorParent && selectorParent.selectors || '', node.params), source: node.source }); @@ -37,6 +41,22 @@ module.exports = (node) => { parent.remove(); } + // if the next sibling shares the same selector + if (afterParent && afterParent.selector === rule.selector) { + rule.append(afterParent.nodes); + + afterParent.remove(); + } + + // if the previous sibling shares the same selector + if (parent.parent && parent.next() === rule && parent.selector === rule.selector) { + parent.append(rule.nodes); + + rule.remove(); + + return parent; + } + return rule; }; From 8c13c72dc60cd8894d8d14e8339a911730c72759 Mon Sep 17 00:00:00 2001 From: Jonathan Neal Date: Mon, 18 Sep 2017 13:20:07 -0400 Subject: [PATCH 525/795] Normalize CHANGELOG --- CHANGELOG.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index fea01a805e..48d974d550 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,18 +2,18 @@ ### 4.1.0 (August 19, 2017) -- Improve complex selector validity testing -- Use mutation-safe walk method -- A special thanks to @JLHwung for these improvements +- Added: Mutation-safe walk method +- Improved: Complex selector validity testing +- Thanks: A special thanks to @JLHwung for these improvements ### 4.0.1 (May 22, 2017) -- Improve selector validity testing +- Improved: Selector validity testing ### 4.0.0 (May 20, 2017) -- Transform only compliant nesting -- Preserve more raws formatting +- Changed: Transform only compliant nesting +- Added: Preserve more raws formatting ### 3.0.0 (May 8, 2017) From 620d5ffbb3893f427d43d709d4eabadb30fbec38 Mon Sep 17 00:00:00 2001 From: Jonathan Neal Date: Mon, 18 Sep 2017 18:48:28 -0400 Subject: [PATCH 526/795] Update devDependencies --- package.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index 258b47aa2e..e0749a3dc5 100644 --- a/package.json +++ b/package.json @@ -27,9 +27,9 @@ "postcss-selector-parser": "^2.2.3" }, "devDependencies": { - "eslint": "^4.6.1", + "eslint": "^4.7.1", "eslint-config-dev": "2.0.0", - "postcss-tape": "2.0.1", + "postcss-tape": "2.1.0", "pre-commit": "^1.2.2" }, "eslintConfig": { From 06c910d58fa6f3a1d0fd44e14a48f0488f39fb8a Mon Sep 17 00:00:00 2001 From: Jonathan Neal Date: Mon, 18 Sep 2017 18:48:39 -0400 Subject: [PATCH 527/795] Remove .appveyor.yml --- .appveyor.yml | 18 ------------------ 1 file changed, 18 deletions(-) delete mode 100644 .appveyor.yml diff --git a/.appveyor.yml b/.appveyor.yml deleted file mode 100644 index d6b511f500..0000000000 --- a/.appveyor.yml +++ /dev/null @@ -1,18 +0,0 @@ -# https://www.appveyor.com/docs/appveyor-yml - -environment: - matrix: - - nodejs_version: 4.0 - -version: "{build}" -build: off -deploy: off - -install: - - ps: Install-Product node $env:nodejs_version - - npm install --ignore-scripts - -test_script: - - node --version - - npm --version - - cmd: "npm test" From 7a2d1a28ea3f20cd3a4e1966ad5e2d4a9efb8713 Mon Sep 17 00:00:00 2001 From: Jonathan Neal Date: Mon, 18 Sep 2017 18:48:57 -0400 Subject: [PATCH 528/795] Add specification to README --- README.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index c693b7c257..105835bf5f 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,8 @@ [![Licensing][lic-img]][lic-url] [![Gitter Chat][git-img]][git-url] -[PostCSS :dir()] lets you use the `:dir` pseudo-class in CSS. +[PostCSS :dir()] lets you use the `:dir` pseudo-class in CSS, following the +[Selectors] specification. ```css .example:dir(rtl) { @@ -223,3 +224,4 @@ original selector.* [Grunt PostCSS]: https://github.com/nDmitry/grunt-postcss [PostCSS]: https://github.com/postcss/postcss [PostCSS :dir()]: https://github.com/jonathantneal/postcss-dir-pseudo-class +[Selectors]: https://drafts.csswg.org/selectors-4/#the-dir-pseudo From 524d34e297c6805566fd76b57097e42abd78324c Mon Sep 17 00:00:00 2001 From: Jonathan Neal Date: Tue, 19 Sep 2017 08:37:56 -0400 Subject: [PATCH 529/795] 4.2.0 --- CHANGELOG.md | 4 ++++ package.json | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 48d974d550..15fd5351ac 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # Changes to PostCSS Nesting +### 4.2.0 (September 18, 2017) + +- Added: Reduced splitting of rules + ### 4.1.0 (August 19, 2017) - Added: Mutation-safe walk method diff --git a/package.json b/package.json index 38be6fe7ed..a0dbc598f0 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "postcss-nesting", - "version": "4.1.0", + "version": "4.2.0", "description": "Nest style and media rules inside each another, following the CSS Nesting Module Level 3 specification", "author": "Jonathan Neal ", "license": "CC0-1.0", From 8f7122e88088dc880af2b10f99430465c0ddaad9 Mon Sep 17 00:00:00 2001 From: Jonathan Neal Date: Tue, 19 Sep 2017 09:59:21 -0400 Subject: [PATCH 530/795] Update dev dependencies --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index a0dbc598f0..913f92e0e7 100644 --- a/package.json +++ b/package.json @@ -26,7 +26,7 @@ "postcss": "^6.0.11" }, "devDependencies": { - "eslint": "^4.7.0", + "eslint": "^4.7.1", "eslint-config-dev": "^2.0.0", "postcss-tape": "^2.1.0", "pre-commit": "^1.2.2" From c857ccf4f7cf8205222574cd9e9267e4c0023b71 Mon Sep 17 00:00:00 2001 From: Jonathan Neal Date: Tue, 19 Sep 2017 09:59:58 -0400 Subject: [PATCH 531/795] Move transform into its own function --- index.js | 22 ++-------------------- lib/transform.js | 18 ++++++++++++++++++ 2 files changed, 20 insertions(+), 20 deletions(-) create mode 100644 lib/transform.js diff --git a/index.js b/index.js index 7504e3b9a1..710cada262 100644 --- a/index.js +++ b/index.js @@ -1,28 +1,10 @@ 'use strict'; // tooling -const postcss = require('postcss'); -const transformBubblingAtrule = require('./lib/transform-bubbling-atrule'); -const transformNestingAtRule = require('./lib/transform-nesting-atrule'); -const transformNestingRule = require('./lib/transform-nesting-rule'); +const postcss = require('postcss'); +const transform = require('./lib/transform'); // plugin module.exports = postcss.plugin('postcss-nesting', () => { return (root) => root.walk(transform); }); - -function transform(node) { - // console.log('walk', [node.type], [node.name || node.selector || node.prop || 'root'], node.nodes ? `length: ${node.nodes.length}` : `value: "${node.value}"`); - - if (transformBubblingAtrule.test(node)) { - // conditionally transform a bubbling atrule - transformBubblingAtrule(node); - } else if (transformNestingAtRule.test(node)) { - // conditionally transform a nesting atrule - node = transformNestingAtRule(node); // eslint-disable-line no-param-reassign - } else if (transformNestingRule.test(node)) { - // conditionally transform a nesting rule - transformNestingRule(node); - } - -} diff --git a/lib/transform.js b/lib/transform.js new file mode 100644 index 0000000000..df9bd4fe43 --- /dev/null +++ b/lib/transform.js @@ -0,0 +1,18 @@ +// tooling +const transformBubblingAtrule = require('./transform-bubbling-atrule'); +const transformNestingAtRule = require('./transform-nesting-atrule'); +const transformNestingRule = require('./transform-nesting-rule'); + +// conditionally transform a nesting rule +module.exports = (node) => { + if (transformBubblingAtrule.test(node)) { + // conditionally transform a bubbling atrule + transformBubblingAtrule(node); + } else if (transformNestingAtRule.test(node)) { + // conditionally transform a nesting atrule + transformNestingAtRule(node); + } else if (transformNestingRule.test(node)) { + // conditionally transform a nesting rule + transformNestingRule(node); + } +}; From f51dda6c867a9bb8b63e28e24d22510ac237ab29 Mon Sep 17 00:00:00 2001 From: Jonathan Neal Date: Tue, 19 Sep 2017 10:59:00 -0400 Subject: [PATCH 532/795] 4.2.1 --- CHANGELOG.md | 4 ++++ package.json | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 15fd5351ac..8c36b5756c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # Changes to PostCSS Nesting +### 4.2.1 (September 19, 2017) + +- Updated: Exposing the transform function as its own for postcss-extend + ### 4.2.0 (September 18, 2017) - Added: Reduced splitting of rules diff --git a/package.json b/package.json index 913f92e0e7..86995000b8 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "postcss-nesting", - "version": "4.2.0", + "version": "4.2.1", "description": "Nest style and media rules inside each another, following the CSS Nesting Module Level 3 specification", "author": "Jonathan Neal ", "license": "CC0-1.0", From ace8303a57b282897768e3e445b59f57e15b1908 Mon Sep 17 00:00:00 2001 From: Jonathan Neal Date: Tue, 19 Sep 2017 15:50:26 -0400 Subject: [PATCH 533/795] Improve how options are utilized --- index.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/index.js b/index.js index 79dc578ad9..c0a506df35 100644 --- a/index.js +++ b/index.js @@ -6,7 +6,7 @@ const selectorParser = require('postcss-selector-parser'); // plugin module.exports = postcss.plugin('postcss-dir-pseudo-class', (opts) => (root) => { // client browser list - const clientBrowserList = browserslist(opts && opts.browsers, { + const clientBrowserList = browserslist(Object(opts).browsers, { path: root.source && root.source.input && root.source.input.file }); @@ -63,8 +63,8 @@ module.exports = postcss.plugin('postcss-dir-pseudo-class', (opts) => (root) => // value of the :dir pseudo-class const value = node.nodes.toString(); - // whether that value matches the presumed direction - const isdir = opts && Object(opts).dir === value; + // whether :dir matches the presumed direction + const isdir = Object(opts).dir === value; // [dir] attribute const dirAttr = selectorParser.attribute({ From 0fcde20c0aa42bd8fdba4e2a50f8e229cf1c71c5 Mon Sep 17 00:00:00 2001 From: Jonathan Neal Date: Tue, 19 Sep 2017 15:53:39 -0400 Subject: [PATCH 534/795] More safely manage presumed directions --- index.js | 2 +- test/basic.dir.expect.css | 14 +++++++------- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/index.js b/index.js index c0a506df35..337dae3a14 100644 --- a/index.js +++ b/index.js @@ -75,7 +75,7 @@ module.exports = postcss.plugin('postcss-dir-pseudo-class', (opts) => (root) => // not[dir] attribute const notDirAttr = selectorParser.pseudo({ - value: ':not' + value: `${firstIsHtml || firstIsRoot ? '' : 'html'}:not` }); notDirAttr.append( diff --git a/test/basic.dir.expect.css b/test/basic.dir.expect.css index b1a24dd696..d74acaa7e7 100644 --- a/test/basic.dir.expect.css +++ b/test/basic.dir.expect.css @@ -1,28 +1,28 @@ -:not([dir="rtl"]) { +html:not([dir="rtl"]) { order: 0; } -:not([dir="rtl"]) test { +html:not([dir="rtl"]) test { order: 1; } -:not([dir="rtl"]) test * { +html:not([dir="rtl"]) test * { order: 2; } -:not([dir="rtl"]) test * test { +html:not([dir="rtl"]) test * test { order: 3; } -:not([dir="rtl"]) test { +html:not([dir="rtl"]) test { order: 4; } -:not([dir="rtl"]) test test { +html:not([dir="rtl"]) test test { order: 5; } -:not([dir="rtl"]) test test { +html:not([dir="rtl"]) test test { order: 6; } From 3d926c5aa45ed621257b96d192569ddaa0d9b928 Mon Sep 17 00:00:00 2001 From: Jonathan Neal Date: Tue, 19 Sep 2017 16:03:29 -0400 Subject: [PATCH 535/795] Update documentation --- README.md | 69 ++++++++++++++++++++++++++++--------------------------- 1 file changed, 35 insertions(+), 34 deletions(-) diff --git a/README.md b/README.md index 105835bf5f..c94b1b6865 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# PostCSS :dir() [PostCSS Logo][postcss] +# PostCSS :dir() Pseudo [PostCSS Logo][postcss] [![CSS Standard Status][css-img]][css-url] [![NPM Version][npm-img]][npm-url] @@ -6,50 +6,54 @@ [![Licensing][lic-img]][lic-url] [![Gitter Chat][git-img]][git-url] -[PostCSS :dir()] lets you use the `:dir` pseudo-class in CSS, following the -[Selectors] specification. +[PostCSS :dir() Pseudo] lets you use the `:dir()` pseudo-class to style by +directionality in CSS, following the [Selectors] specification. ```css -.example:dir(rtl) { +article h3:dir(rtl) { margin-right: 10px; } -.example:dir(ltr) { +article h3:dir(ltr) { margin-left: 10px; } /* becomes */ -[dir="rtl"] .example { +[dir="rtl"] article h3 { margin-right: 10px; } -[dir="ltr"] .example { +[dir="ltr"] article h3 { margin-left: 10px; } ``` -If your [browserslist] already supports the `:dir` pseudo-class, this plugin -will not change your CSS. You can learn more this by reading about the -[`browsers` option](#browsers-option). +### Future-proof your CSS -[PostCSS :dir()] does not change selector weight, but does require at least one -`[dir]` attribute in your HTML. If you don’t have _any_ `[dir]` attributes, -consider using the following JavaScript: +If your [browserslist] already supports the `:dir()` pseudo-class, this plugin +will not change your CSS. Learn more about this feature in the +[`browsers`](#browsers-option) section. + +### Maintain Specificity + +Using [PostCSS :dir() Pseudo] will not impact selector weight, but it will +require having at least one `[dir]` attribute in your HTML. If you don’t have +_any_ `[dir]` attributes, consider using the following JavaScript: ```js // force at least one dir attribute (this can run at any time) document.documentElement.dir=document.documentElement.dir||'ltr'; ``` -If you absolutely cannot add a `[dir]` attribute in your HTML or force one via -JavaScript, you can still get around this by presuming a direction in your CSS -using the [`dir` option](#dir-option), but know that this will increase -selector weight by one element (`html`). +If you absolutely cannot add a `[dir]` attribute in your HTML or even force one +via JavaScript, you can still work around this by presuming a direction in your +CSS using the [`dir` option](#dir-option), but understand that this will +sometimes increase selector weight by one element (`html`). ## Usage -Add [PostCSS :dir()] to your build tool: +Add [PostCSS :dir() Pseudo] to your build tool: ```bash npm install postcss-dir-pseudo-class --save-dev @@ -57,10 +61,10 @@ npm install postcss-dir-pseudo-class --save-dev #### Node -Use [PostCSS :dir()] to process your CSS: +Use [PostCSS :dir() Pseudo] to process your CSS: ```js -require('postcss-dir-pseudo-class').process(YOUR_CSS); +require('postcss-dir-pseudo-class').process(YOUR_CSS /*, processConfig, options */); ``` #### PostCSS @@ -71,11 +75,11 @@ Add [PostCSS] to your build tool: npm install postcss --save-dev ``` -Use [PostCSS :dir()] as a plugin: +Use [PostCSS :dir() Pseudo] as a plugin: ```js postcss([ - require('postcss-dir-pseudo-class')() + require('postcss-dir-pseudo-class')(/* Options */) ]).process(YOUR_CSS); ``` @@ -87,7 +91,7 @@ Add [Gulp PostCSS] to your build tool: npm install gulp-postcss --save-dev ``` -Use [PostCSS :dir()] in your Gulpfile: +Use [PostCSS :dir() Pseudo] in your Gulpfile: ```js var postcss = require('gulp-postcss'); @@ -95,7 +99,7 @@ var postcss = require('gulp-postcss'); gulp.task('css', function () { return gulp.src('./src/*.css').pipe( postcss([ - require('postcss-dir-pseudo-class')() + require('postcss-dir-pseudo-class')(/* Options */) ]) ).pipe( gulp.dest('.') @@ -111,7 +115,7 @@ Add [Grunt PostCSS] to your build tool: npm install grunt-postcss --save-dev ``` -Use [PostCSS :dir()] in your Gruntfile: +Use [PostCSS :dir() Pseudo] in your Gruntfile: ```js grunt.loadNpmTasks('grunt-postcss'); @@ -120,7 +124,7 @@ grunt.initConfig({ postcss: { options: { use: [ - require('postcss-dir-pseudo-class')() + require('postcss-dir-pseudo-class')(/* Options */) ] }, dist: { @@ -132,7 +136,7 @@ grunt.initConfig({ --- -## browsers option +## Browsers Option If your [browserslist] already supports the `:dir` pseudo-class, this plugin will not change your CSS. While only Firefox currently supports `:dir`, this @@ -170,9 +174,9 @@ In both of these examples, the CSS would remain unchanged. } ``` -## dir option +## Dir Option -By default, this plugin requires you to specify a direction `[dir]` attribute +By default, this plugin requires you to include a direction `[dir]` attribute in your HTML, preferably on the `html` element. If you prefer not to, you can presume a direction in your CSS using the `dir` option. @@ -196,7 +200,7 @@ require('postcss-dir-pseudo-class')({ /* becomes */ -:not([dir="rtl"]) .example { +html:not([dir="rtl"]) .example { margin-left: 10px; } @@ -205,9 +209,6 @@ require('postcss-dir-pseudo-class')({ } ``` -*Note: The `:root` pseudo-class is added here to preserve the weight of the -original selector.* - [cli-url]: https://travis-ci.org/jonathantneal/postcss-dir-pseudo-class [cli-img]: https://img.shields.io/travis/jonathantneal/postcss-dir-pseudo-class.svg [css-img]: https://jonathantneal.github.io/css-db/badge/selectors-the-dir-pseudo.svg @@ -223,5 +224,5 @@ original selector.* [Gulp PostCSS]: https://github.com/postcss/gulp-postcss [Grunt PostCSS]: https://github.com/nDmitry/grunt-postcss [PostCSS]: https://github.com/postcss/postcss -[PostCSS :dir()]: https://github.com/jonathantneal/postcss-dir-pseudo-class +[PostCSS :dir() Pseudo]: https://github.com/jonathantneal/postcss-dir-pseudo-class [Selectors]: https://drafts.csswg.org/selectors-4/#the-dir-pseudo From ce68791f405ba561e74b39b71866cf1fe4166383 Mon Sep 17 00:00:00 2001 From: Jonathan Neal Date: Tue, 19 Sep 2017 16:08:47 -0400 Subject: [PATCH 536/795] 2.1.0 --- CHANGELOG.md | 6 ++++++ package.json | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 024a47b46e..173fb62be4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,11 @@ # Changes to PostCSS :dir() +### 2.1.0 (September 19, 2017) + +- Fixed: Enforcement of presumed direction, e.g. `html:dir([dir="rtl"])` +- Updated: Browserslist and PostCSS +- Improved: How options are safely called, i.e. `Object(opts)` + ### 2.0.0 (July 24, 2017) - Changed: Method of presumed direction from `:root` to `html:not([dir])` diff --git a/package.json b/package.json index e0749a3dc5..63ea33d448 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "postcss-dir-pseudo-class", - "version": "2.0.0", + "version": "2.1.0", "description": "Use the :dir pseudo-class in CSS", "author": "Jonathan Neal ", "license": "CC0-1.0", From 9f4ce733fe04343f15cec22b5f3c2a7cf555c142 Mon Sep 17 00:00:00 2001 From: Jonathan Neal Date: Wed, 20 Sep 2017 13:34:21 -0400 Subject: [PATCH 537/795] Add CSS Standard Status (#8) --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 4e3bd33d61..3d10288182 100755 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# postcss-color-hwb [![Build Status](https://travis-ci.org/postcss/postcss-color-hwb.png)](https://travis-ci.org/postcss/postcss-color-hwb) +# postcss-color-hwb [![CSS Standard Status](https://jonathantneal.github.io/css-db/badge/css-color-the-hwb-notation.svg)](https://jonathantneal.github.io/css-db/#css-color-the-hwb-notation) [![Build Status](https://travis-ci.org/postcss/postcss-color-hwb.png)](https://travis-ci.org/postcss/postcss-color-hwb) > [PostCSS](https://github.com/postcss/postcss) plugin to transform [W3C CSS hwb() color](http://dev.w3.org/csswg/css-color/#the-hwb-notation) to more compatible CSS (rgb() (or rgba())). From 3c8a7b84ad8c52ac16ca7b2796044a95ab519e20 Mon Sep 17 00:00:00 2001 From: Jonathan Neal Date: Wed, 20 Sep 2017 13:35:26 -0400 Subject: [PATCH 538/795] Add CSS Standard Status (#9) --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 65adcf0d13..c32945e17e 100755 --- a/README.md +++ b/README.md @@ -1,5 +1,6 @@ # postcss-color-gray +[![CSS Standard Status](https://jonathantneal.github.io/css-db/badge/css-color-grays.svg)](https://jonathantneal.github.io/css-db/#css-color-grays) [![Build Status](https://travis-ci.org/postcss/postcss-color-gray.svg?branch=master)](https://travis-ci.org/postcss/postcss-color-gray) [![Build status](https://ci.appveyor.com/api/projects/status/190t5i4f23r49345?svg=true)](https://ci.appveyor.com/project/ShinnosukeWatanabe/postcss-color-gray) [![Coverage Status](https://img.shields.io/coveralls/postcss/postcss-color-gray.svg)](https://coveralls.io/r/postcss/postcss-color-gray) From 9bfcb517fddac3ad39f40208f1d4dd460a5c9fe0 Mon Sep 17 00:00:00 2001 From: Hiroki Osame Date: Fri, 6 Oct 2017 10:26:50 -0700 Subject: [PATCH 539/795] Typo in variable name (#77) --- index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/index.js b/index.js index 89183c62e6..1ae92c9a6b 100755 --- a/index.js +++ b/index.js @@ -133,7 +133,7 @@ function prefixVariables(variables) { const prefixedVariables = {} if (!variables) { - return prefixVariables + return prefixedVariables } Object.keys(variables).forEach((name) => { From c572e60bbd91d1dbb43bdca93b89f275378ac5d4 Mon Sep 17 00:00:00 2001 From: Jonathan Neal Date: Fri, 6 Oct 2017 10:34:50 -0700 Subject: [PATCH 540/795] Bump deps --- package.json | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/package.json b/package.json index d38f38b61d..0b7d0e12cb 100644 --- a/package.json +++ b/package.json @@ -19,16 +19,16 @@ ], "dependencies": { "balanced-match": "^1.0.0", - "postcss": "^6.0.3" + "postcss": "^6.0.13" }, "devDependencies": { - "babel-cli": "^6.24.1", + "babel-cli": "^6.26.0", "babel-plugin-add-module-exports": "^0.2.1", - "babel-preset-env": "^1.5.2", - "babel-register": "^6.24.1", - "eslint": "^4.1.1", + "babel-preset-env": "^1.6.0", + "babel-register": "^6.26.0", + "eslint": "^4.8.0", "npmpub": "^3.1.0", - "tape": "^4.7.0" + "tape": "^4.8.0" }, "scripts": { "lint": "eslint *.js index.js ./test/", From 025db4d90f39ba6ea4ae37aa618d899cb74651c1 Mon Sep 17 00:00:00 2001 From: Jonathan Neal Date: Fri, 6 Oct 2017 10:37:55 -0700 Subject: [PATCH 541/795] 6.2.0 --- CHANGELOG.md | 5 +++++ package.json | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index dcc5820615..dd77abc559 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,8 @@ +# 6.2.0 - 2017-10-06 + +- Added: `noValueNotifications` option (#71) +- Fixed: Typo in `prefixedVariables` variable name (#77) + # 6.1.0 - 2017-06-28 - Added: Let "warnings" option silence all warnings diff --git a/package.json b/package.json index 0b7d0e12cb..059d9b2111 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "postcss-custom-properties", - "version": "6.1.0", + "version": "6.2.0", "description": "PostCSS plugin to polyfill W3C CSS Custom Properties for cascading variables", "keywords": [ "css", From d4721131336434f87325d4ad184460384c7a7165 Mon Sep 17 00:00:00 2001 From: Dmitry Semigradsky Date: Tue, 10 Oct 2017 19:36:30 +0300 Subject: [PATCH 542/795] Fix badge --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index c5824cb66e..d5ae05744e 100755 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# postcss-custom-media [![CSS Standard Status](https://jonathantneal.github.io/css-db/badge/mediaqueries-5-custom-mq.svg)](https://jonathantneal.github.io/css-db/#mediaqueries-5-custom-mq) [![Build Status](https://travis-ci.org/postcss/postcss-custom-media.png)](https://travis-ci.org/postcss/postcss-custom-media) +# postcss-custom-media [![CSS Standard Status](https://jonathantneal.github.io/css-db/badge/mediaqueries-custom-mq.svg)](https://jonathantneal.github.io/css-db/#mediaqueries-custom-mq) [![Build Status](https://travis-ci.org/postcss/postcss-custom-media.png)](https://travis-ci.org/postcss/postcss-custom-media) > [PostCSS](https://github.com/postcss/postcss) plugin to transform [W3C CSS Custom Media Queries](https://drafts.csswg.org/mediaqueries-5/#custom-mq) syntax to more compatible CSS. From 57c416c8fb2e8ced95a548a0e92789b4e43e0cb0 Mon Sep 17 00:00:00 2001 From: Frank Mecklenburg Date: Thu, 16 Nov 2017 13:37:55 +0100 Subject: [PATCH 543/795] Fix typo in README.md (#23) --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 374b8dc125..5c7103af38 100644 --- a/README.md +++ b/README.md @@ -18,7 +18,7 @@ included. Duplicate `@import-normalize` rules will be removed. See all the [Opti Results: ```css -/* { "browserlist": ["last 3 versions"] } */ +/* { "browserslist": ["last 3 versions"] } */ /** * Add the correct display in IE 9-. From 3dbf13a10f6e31303602e790db161749e47fc376 Mon Sep 17 00:00:00 2001 From: Shinnosuke Watanabe Date: Wed, 13 Dec 2017 19:40:05 +0900 Subject: [PATCH 544/795] update dependnecies Highlights: * update color from v1 to v2 https://github.com/Qix-/color * update ESLint from v3 to v4 https://eslint.org/blog/2017/06/eslint-v4.0.0-released * introduce @shinnn/eslint-config and follow its coding rules https://github.com/shinnn/eslint-config * remove no longer maintained JSCS https://eslint.org/blog/2016/04/welcoming-jscs-to-eslint * switch from istanbul to nyc https://github.com/istanbuljs/nyc --- .editorconfig | 7 +- .eslintrc.yml | 35 - .gitignore | 1 + .travis.yml | 10 +- appveyor.yml | 18 +- index.js | 88 +- package-lock.json | 3531 +++++++++++++++++++++++++++++++++++++++++++++ package.json | 93 +- test.js | 118 +- 9 files changed, 3675 insertions(+), 226 deletions(-) mode change 100755 => 100644 .editorconfig delete mode 100644 .eslintrc.yml mode change 100755 => 100644 .gitignore mode change 100755 => 100644 .travis.yml mode change 100755 => 100644 appveyor.yml mode change 100755 => 100644 index.js create mode 100644 package-lock.json mode change 100755 => 100644 test.js diff --git a/.editorconfig b/.editorconfig old mode 100755 new mode 100644 index 8c52ff9378..e7bbe21364 --- a/.editorconfig +++ b/.editorconfig @@ -3,10 +3,13 @@ root = true [*] charset = utf-8 end_of_line = lf -indent_style = space -indent_size = 2 +indent_style = tab +tab_width = 2 insert_final_newline = true trim_trailing_whitespace = true +[*.{md,yml}] +indent_style = space + [*.md] trim_trailing_whitespace = false diff --git a/.eslintrc.yml b/.eslintrc.yml deleted file mode 100644 index 003b54272b..0000000000 --- a/.eslintrc.yml +++ /dev/null @@ -1,35 +0,0 @@ -root: true -extends: eslint:recommended - -parserOptions: - ecmaVersion: 5 - -env: - commonjs: true - -rules: - indent: [2, 2] # 2 spaces indentation - max-len: [2, 80, 4, { "ignoreStrings": true }] - quotes: [2, "single"] - semi: [2, "always"] - no-multiple-empty-lines: [2, {"max": 1}] - - brace-style: [2, "1tbs"] - 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"] diff --git a/.gitignore b/.gitignore old mode 100755 new mode 100644 index 62562b74a3..76b1021d09 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ +.nyc_output coverage node_modules diff --git a/.travis.yml b/.travis.yml old mode 100755 new mode 100644 index 0204bbebe8..6dcb13b81c --- a/.travis.yml +++ b/.travis.yml @@ -1,11 +1,7 @@ -sudo: false -git: - depth: 2 +branches: + except: /^v\d/ language: node_js node_js: - '4' - '6' -notifications: - email: false -after_script: - - npm run-script coveralls +after_script: node_modules/.bin/nyc report --reporter=text-lcov | npx coveralls diff --git a/appveyor.yml b/appveyor.yml old mode 100755 new mode 100644 index 4c66cc7c36..551069ccd4 --- a/appveyor.yml +++ b/appveyor.yml @@ -1,23 +1,9 @@ -init: - - git config --global core.autocrlf input - -version: '{build}' - environment: matrix: - nodejs_version: '4' - nodejs_version: '6' - install: - ps: Install-Product node $env:nodejs_version - - npm install --production - - npm install postcss tape - + - npm install build: off - -test_script: - - ps: 'node test.js #PowerShell' - - cmd: node test.js - -cache: - - node_modules +test_script: node test.js diff --git a/index.js b/index.js old mode 100755 new mode 100644 index 386760d9d6..2982ea15a7 --- a/index.js +++ b/index.js @@ -1,62 +1,48 @@ -/*! - * postcss-color-gray | MIT (c) Shinnosuke Watanabe - * https://github.com/postcss/postcss-color-gray -*/ - 'use strict'; -var color = require('color'); -var postcss = require('postcss'); -var helpers = require('postcss-message-helpers'); -var reduceFunctionCall = require('reduce-function-call'); +const color = require('color'); +const postcss = require('postcss'); +const helpers = require('postcss-message-helpers'); +const reduceFunctionCall = require('reduce-function-call'); -var pluginName = 'postcss-color-gray'; -var errorContext = {plugin: pluginName}; +const pluginName = 'postcss-color-gray'; +const errorContext = {plugin: pluginName}; function parseAlpha(alpha) { - if (alpha) { - var match = alpha.match(/^\d(\d|\.)+?%$/); - if (match && match[0] === alpha) { - return parseFloat(alpha) * 0.01; - } - } - return alpha; + if (alpha) { + const match = alpha.match(/^\d(\d|\.)+?%$/); + + if (match && match[0] === alpha) { + return parseFloat(alpha) * 0.01; + } + } + + return alpha; } function parseGray(decl) { - return reduceFunctionCall(decl.value, 'gray', function(body) { - if (/^,/.test(body) || /,$/.test(body)) { - throw decl.error( - 'Unable to parse color from string "gray(' + body + ')"', - errorContext - ); - } - var fn = 'rgb'; - var args = postcss.list.comma(body); - var lightness = args[0]; - var rgb = [lightness, lightness, lightness]; - var alpha = parseAlpha(args[1]); - if (alpha) { - fn += 'a'; - rgb.push(alpha); - } - try { - return color(fn + '(' + rgb + ')').rgb().string(); - } catch (err) { - throw decl.error( - 'Unable to parse color from string "gray(' + args + ')"', - errorContext - ); - } - }); + return reduceFunctionCall(decl.value, 'gray', body => { + if (body.startsWith(',') || body.endsWith(',')) { + throw decl.error(`Unable to parse color from string "gray(${body})"`, errorContext); + } + + const args = postcss.list.comma(body); + const lightness = args[0]; + const alpha = parseAlpha(args[1]); + const rgb = `${lightness},${lightness},${lightness}`; + + try { + return color(alpha ? `rgba(${rgb},${alpha})` : `rgb(${rgb})`).rgb().string(); + } catch (err) { + throw decl.error(`Unable to parse color from string "gray(${args})"`, errorContext); + } + }); } -module.exports = postcss.plugin(pluginName, function() { - return function(root) { - root.walkDecls(function(decl) { - if (decl.value && decl.value.indexOf('gray(') !== -1) { - decl.value = helpers.try(parseGray.bind(this, decl), decl.source); - } - }); - }; +module.exports = postcss.plugin(pluginName, () => function(root) { + root.walkDecls(function(decl) { + if (decl.value && decl.value.includes('gray(')) { + decl.value = helpers.try(parseGray.bind(this, decl), decl.source); + } + }); }); diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 0000000000..e1f3dad17a --- /dev/null +++ b/package-lock.json @@ -0,0 +1,3531 @@ +{ + "name": "postcss-color-gray", + "version": "4.0.0", + "lockfileVersion": 1, + "requires": true, + "dependencies": { + "@shinnn/eslint-config": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/@shinnn/eslint-config/-/eslint-config-5.0.0.tgz", + "integrity": "sha512-PTwC+LB5FK+RBmJzCvHlDbp1yVT6pW0P4KcXFxEizJv3YNj21l8TezmbEM5E22AQrrtpPkXuFtJ8Dphit5SC6A==", + "dev": true, + "requires": { + "eslint-plugin-no-use-extend-native": "0.3.12", + "eslint-plugin-node": "5.2.1" + } + }, + "@shinnn/eslint-config-node": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/@shinnn/eslint-config-node/-/eslint-config-node-5.0.0.tgz", + "integrity": "sha512-76g40UhvDpgBfmWI1gGkFFRsZXE5pzOcS1aWC6NcPkxuOPGtqEv26b9DscApPA7by5XS8htPfJeDN6l9Eudf0g==", + "dev": true, + "requires": { + "@shinnn/eslint-config": "5.0.0" + } + }, + "@sindresorhus/df": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@sindresorhus/df/-/df-2.1.0.tgz", + "integrity": "sha1-0gjPJ+BvC7R20U197M19cm6ao4k=", + "dev": true, + "requires": { + "execa": "0.2.2" + } + }, + "acorn": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-5.2.1.tgz", + "integrity": "sha512-jG0u7c4Ly+3QkkW18V+NRDN+4bWHdln30NL1ZL2AvFZZmQe/BfopYCtghCKKVBUSetZ4QKcyA0pY6/4Gw8Pv8w==", + "dev": true + }, + "acorn-jsx": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-3.0.1.tgz", + "integrity": "sha1-r9+UiPsezvyDSPb7IvRk4ypYs2s=", + "dev": true, + "requires": { + "acorn": "3.3.0" + }, + "dependencies": { + "acorn": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-3.3.0.tgz", + "integrity": "sha1-ReN/s56No/JbruP/U2niu18iAXo=", + "dev": true + } + } + }, + "agent-base": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-2.1.1.tgz", + "integrity": "sha1-1t4Q1a9hMtW9aSQn1G/FOFOQlMc=", + "dev": true, + "requires": { + "extend": "3.0.1", + "semver": "5.0.3" + }, + "dependencies": { + "semver": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.0.3.tgz", + "integrity": "sha1-d0Zt5YnNXTyV8TiqeLxWmjy10no=", + "dev": true + } + } + }, + "ajv": { + "version": "5.5.1", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-5.5.1.tgz", + "integrity": "sha1-s4u4h22ehr7plJVqBOch6IskjrI=", + "dev": true, + "requires": { + "co": "4.6.0", + "fast-deep-equal": "1.0.0", + "fast-json-stable-stringify": "2.0.0", + "json-schema-traverse": "0.3.1" + } + }, + "ajv-keywords": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-2.1.1.tgz", + "integrity": "sha1-YXmX/F9gV2iUxDX5QNgZ4TW4B2I=", + "dev": true + }, + "ansi-escapes": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-3.0.0.tgz", + "integrity": "sha512-O/klc27mWNUigtv0F8NJWbLF00OcegQalkqKURWdosW08YZKi4m6CnSUSvIZG1otNJbTWhN01Hhz389DW7mvDQ==", + "dev": true + }, + "ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", + "dev": true + }, + "ansi-styles": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.0.tgz", + "integrity": "sha512-NnSOmMEYtVR2JVMIGTzynRkkaxtiq1xnFBcdQD/DnNCYPoEPsVJhM98BDyaoNOQIi7p4okdi3E27eN7GQbsUug==", + "requires": { + "color-convert": "1.9.1" + } + }, + "argparse": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.9.tgz", + "integrity": "sha1-c9g7wmP4bpf4zE9rrhsOkKfSLIY=", + "dev": true, + "requires": { + "sprintf-js": "1.0.3" + } + }, + "array-union": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-1.0.2.tgz", + "integrity": "sha1-mjRBDk9OPaI96jdb5b5w8kd47Dk=", + "dev": true, + "requires": { + "array-uniq": "1.0.3" + } + }, + "array-uniq": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/array-uniq/-/array-uniq-1.0.3.tgz", + "integrity": "sha1-r2rId6Jcx/dOBYiUdThY39sk/bY=", + "dev": true + }, + "arrify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", + "integrity": "sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=", + "dev": true + }, + "babel-code-frame": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-code-frame/-/babel-code-frame-6.26.0.tgz", + "integrity": "sha1-Y/1D99weO7fONZR9uP42mj9Yx0s=", + "dev": true, + "requires": { + "chalk": "1.1.3", + "esutils": "2.0.2", + "js-tokens": "3.0.2" + }, + "dependencies": { + "ansi-styles": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", + "dev": true + }, + "chalk": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", + "dev": true, + "requires": { + "ansi-styles": "2.2.1", + "escape-string-regexp": "1.0.5", + "has-ansi": "2.0.0", + "strip-ansi": "3.0.1", + "supports-color": "2.0.0" + } + }, + "strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "dev": true, + "requires": { + "ansi-regex": "2.1.1" + } + }, + "supports-color": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", + "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", + "dev": true + } + } + }, + "balanced-match": { + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-0.4.2.tgz", + "integrity": "sha1-yz8+PHMtwPAe5wtAPzAuYddwmDg=" + }, + "brace-expansion": { + "version": "1.1.8", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.8.tgz", + "integrity": "sha1-wHshHHyVLsH479Uad+8NHTmQopI=", + "dev": true, + "requires": { + "balanced-match": "1.0.0", + "concat-map": "0.0.1" + }, + "dependencies": { + "balanced-match": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", + "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", + "dev": true + } + } + }, + "caller-path": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/caller-path/-/caller-path-0.1.0.tgz", + "integrity": "sha1-lAhe9jWB7NPaqSREqP6U6CV3dR8=", + "dev": true, + "requires": { + "callsites": "0.2.0" + } + }, + "callsites": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-0.2.0.tgz", + "integrity": "sha1-r6uWJikQp/M8GaV3WCXGnzTjUMo=", + "dev": true + }, + "chalk": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.3.0.tgz", + "integrity": "sha512-Az5zJR2CBujap2rqXGaJKaPHyJ0IrUimvYNX+ncCy8PJP4ltOGTrHUIo097ZaL2zMeKYpiCdqDvS6zdrTFok3Q==", + "requires": { + "ansi-styles": "3.2.0", + "escape-string-regexp": "1.0.5", + "supports-color": "4.5.0" + } + }, + "chardet": { + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.4.2.tgz", + "integrity": "sha1-tUc7M9yXxCTl2Y3IfVXU2KKci/I=", + "dev": true + }, + "checkup": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/checkup/-/checkup-1.3.0.tgz", + "integrity": "sha1-04ACdv6l0PJH/8lRvnjIsC+ODXY=", + "dev": true + }, + "circular-json": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/circular-json/-/circular-json-0.3.3.tgz", + "integrity": "sha512-UZK3NBx2Mca+b5LsG7bY183pHWt5Y1xts4P3Pz7ENTwGVnJOUWbRb3ocjvX7hx9tq/yTAdclXm9sZ38gNuem4A==", + "dev": true + }, + "cli-cursor": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-2.1.0.tgz", + "integrity": "sha1-s12sN2R5+sw+lHR9QdDQ9SOP/LU=", + "dev": true, + "requires": { + "restore-cursor": "2.0.0" + } + }, + "cli-width": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-2.2.0.tgz", + "integrity": "sha1-/xnt6Kml5XkyQUewwR8PvLq+1jk=", + "dev": true + }, + "co": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", + "integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ=", + "dev": true + }, + "color": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color/-/color-2.0.1.tgz", + "integrity": "sha512-ubUCVVKfT7r2w2D3qtHakj8mbmKms+tThR8gI8zEYCbUBl8/voqFGt3kgBqGwXAopgXybnkuOq+qMYCRrp4cXw==", + "requires": { + "color-convert": "1.9.1", + "color-string": "1.5.2" + } + }, + "color-convert": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.1.tgz", + "integrity": "sha512-mjGanIiwQJskCC18rPR6OmrZ6fm2Lc7PeGFYwCmy5J34wC6F1PzdGL6xeMfmgicfYcNLGuVFA3WzXtIDCQSZxQ==", + "requires": { + "color-name": "1.1.3" + } + }, + "color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=" + }, + "color-string": { + "version": "1.5.2", + "resolved": "https://registry.npmjs.org/color-string/-/color-string-1.5.2.tgz", + "integrity": "sha1-JuRYFLw8mny9Z1FkikFDRRSnc6k=", + "requires": { + "color-name": "1.1.3", + "simple-swizzle": "0.2.2" + } + }, + "concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", + "dev": true + }, + "concat-stream": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.0.tgz", + "integrity": "sha1-CqxmL9Ur54lk1VMvaUeE5wEQrPc=", + "dev": true, + "requires": { + "inherits": "2.0.3", + "readable-stream": "2.3.3", + "typedarray": "0.0.6" + } + }, + "core-util-is": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", + "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=", + "dev": true + }, + "cross-spawn": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-5.1.0.tgz", + "integrity": "sha1-6L0O/uWPz/b4+UUQoKVUu/ojVEk=", + "dev": true, + "requires": { + "lru-cache": "4.1.1", + "shebang-command": "1.2.0", + "which": "1.3.0" + } + }, + "cross-spawn-async": { + "version": "2.2.5", + "resolved": "https://registry.npmjs.org/cross-spawn-async/-/cross-spawn-async-2.2.5.tgz", + "integrity": "sha1-hF/wwINKPe2dFg2sptOQkGuyiMw=", + "dev": true, + "requires": { + "lru-cache": "4.1.1", + "which": "1.3.0" + } + }, + "debug": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", + "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "deep-equal": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/deep-equal/-/deep-equal-1.0.1.tgz", + "integrity": "sha1-9dJgKStmDghO/0zbyfCK0yR0SLU=", + "dev": true + }, + "deep-is": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz", + "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=", + "dev": true + }, + "define-properties": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.2.tgz", + "integrity": "sha1-g6c/L+pWmJj7c3GTyPhzyvbUXJQ=", + "dev": true, + "requires": { + "foreach": "2.0.5", + "object-keys": "1.0.11" + } + }, + "defined": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/defined/-/defined-1.0.0.tgz", + "integrity": "sha1-yY2bzvdWdBiOEQlpFRGZ45sfppM=", + "dev": true + }, + "del": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/del/-/del-2.2.2.tgz", + "integrity": "sha1-wSyYHQZ4RshLyvhiz/kw2Qf/0ag=", + "dev": true, + "requires": { + "globby": "5.0.0", + "is-path-cwd": "1.0.0", + "is-path-in-cwd": "1.0.0", + "object-assign": "4.1.1", + "pify": "2.3.0", + "pinkie-promise": "2.0.1", + "rimraf": "2.6.2" + } + }, + "doctrine": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.0.2.tgz", + "integrity": "sha512-y0tm5Pq6ywp3qSTZ1vPgVdAnbDEoeoc5wlOHXoY1c4Wug/a7JvqHIl7BTvwodaHmejWkK/9dSb3sCYfyo/om8A==", + "dev": true, + "requires": { + "esutils": "2.0.2" + } + }, + "es-abstract": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.10.0.tgz", + "integrity": "sha512-/uh/DhdqIOSkAWifU+8nG78vlQxdLckUdI/sPgy0VhuXi2qJ7T8czBmqIYtLQVpCIFYafChnsRsB5pyb1JdmCQ==", + "dev": true, + "requires": { + "es-to-primitive": "1.1.1", + "function-bind": "1.1.1", + "has": "1.0.1", + "is-callable": "1.1.3", + "is-regex": "1.0.4" + } + }, + "es-to-primitive": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.1.1.tgz", + "integrity": "sha1-RTVSSKiJeQNLZ5Lhm7gfK3l13Q0=", + "dev": true, + "requires": { + "is-callable": "1.1.3", + "is-date-object": "1.0.1", + "is-symbol": "1.0.1" + } + }, + "escape-string-applescript": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/escape-string-applescript/-/escape-string-applescript-1.0.0.tgz", + "integrity": "sha1-bxwilCRdgsY7wDM43BmpSqhCiJI=", + "dev": true + }, + "escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=" + }, + "eslint": { + "version": "4.13.1", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-4.13.1.tgz", + "integrity": "sha512-UCJVV50RtLHYzBp1DZ8CMPtRSg4iVZvjgO9IJHIKyWU/AnJVjtdRikoUPLB29n5pzMB7TnsLQWf0V6VUJfoPfw==", + "dev": true, + "requires": { + "ajv": "5.5.1", + "babel-code-frame": "6.26.0", + "chalk": "2.3.0", + "concat-stream": "1.6.0", + "cross-spawn": "5.1.0", + "debug": "3.1.0", + "doctrine": "2.0.2", + "eslint-scope": "3.7.1", + "espree": "3.5.2", + "esquery": "1.0.0", + "estraverse": "4.2.0", + "esutils": "2.0.2", + "file-entry-cache": "2.0.0", + "functional-red-black-tree": "1.0.1", + "glob": "7.1.2", + "globals": "11.1.0", + "ignore": "3.3.7", + "imurmurhash": "0.1.4", + "inquirer": "3.3.0", + "is-resolvable": "1.0.1", + "js-yaml": "3.10.0", + "json-stable-stringify-without-jsonify": "1.0.1", + "levn": "0.3.0", + "lodash": "4.17.4", + "minimatch": "3.0.4", + "mkdirp": "0.5.1", + "natural-compare": "1.4.0", + "optionator": "0.8.2", + "path-is-inside": "1.0.2", + "pluralize": "7.0.0", + "progress": "2.0.0", + "require-uncached": "1.0.3", + "semver": "5.3.0", + "strip-ansi": "4.0.0", + "strip-json-comments": "2.0.1", + "table": "4.0.2", + "text-table": "0.2.0" + } + }, + "eslint-plugin-no-use-extend-native": { + "version": "0.3.12", + "resolved": "https://registry.npmjs.org/eslint-plugin-no-use-extend-native/-/eslint-plugin-no-use-extend-native-0.3.12.tgz", + "integrity": "sha1-OtmgDC3yO11/f2vpFVCYWkq3Aeo=", + "dev": true, + "requires": { + "is-get-set-prop": "1.0.0", + "is-js-type": "2.0.0", + "is-obj-prop": "1.0.0", + "is-proto-prop": "1.0.0" + } + }, + "eslint-plugin-node": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-node/-/eslint-plugin-node-5.2.1.tgz", + "integrity": "sha512-xhPXrh0Vl/b7870uEbaumb2Q+LxaEcOQ3kS1jtIXanBAwpMre1l5q/l2l/hESYJGEFKuI78bp6Uw50hlpr7B+g==", + "dev": true, + "requires": { + "ignore": "3.3.7", + "minimatch": "3.0.4", + "resolve": "1.5.0", + "semver": "5.3.0" + } + }, + "eslint-scope": { + "version": "3.7.1", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-3.7.1.tgz", + "integrity": "sha1-PWPD7f2gLgbgGkUq2IyqzHzctug=", + "dev": true, + "requires": { + "esrecurse": "4.2.0", + "estraverse": "4.2.0" + } + }, + "espree": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/espree/-/espree-3.5.2.tgz", + "integrity": "sha512-sadKeYwaR/aJ3stC2CdvgXu1T16TdYN+qwCpcWbMnGJ8s0zNWemzrvb2GbD4OhmJ/fwpJjudThAlLobGbWZbCQ==", + "dev": true, + "requires": { + "acorn": "5.2.1", + "acorn-jsx": "3.0.1" + } + }, + "esprima": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.0.tgz", + "integrity": "sha512-oftTcaMu/EGrEIu904mWteKIv8vMuOgGYo7EhVJJN00R/EED9DCua/xxHRdYnKtcECzVg7xOWhflvJMnqcFZjw==", + "dev": true + }, + "esquery": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.0.0.tgz", + "integrity": "sha1-z7qLV9f7qT8XKYqKAGoEzaE9gPo=", + "dev": true, + "requires": { + "estraverse": "4.2.0" + } + }, + "esrecurse": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.2.0.tgz", + "integrity": "sha1-+pVo2Y04I/mkHZHpAtyrnqblsWM=", + "dev": true, + "requires": { + "estraverse": "4.2.0", + "object-assign": "4.1.1" + } + }, + "estraverse": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.2.0.tgz", + "integrity": "sha1-De4/7TH81GlhjOc0IJn8GvoL2xM=", + "dev": true + }, + "esutils": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.2.tgz", + "integrity": "sha1-Cr9PHKpbyx96nYrMbepPqqBLrJs=", + "dev": true + }, + "execa": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/execa/-/execa-0.2.2.tgz", + "integrity": "sha1-4urUcsLDGq1vc/GslW7vReEjIMs=", + "dev": true, + "requires": { + "cross-spawn-async": "2.2.5", + "npm-run-path": "1.0.0", + "object-assign": "4.1.1", + "path-key": "1.0.0", + "strip-eof": "1.0.0" + } + }, + "execon": { + "version": "1.2.9", + "resolved": "https://registry.npmjs.org/execon/-/execon-1.2.9.tgz", + "integrity": "sha1-bbETM9zIJPHxPnMX/tDZSi8mSR8=", + "dev": true + }, + "extend": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.1.tgz", + "integrity": "sha1-p1Xqe8Gt/MWjHOfnYtuq3F5jZEQ=", + "dev": true + }, + "external-editor": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-2.1.0.tgz", + "integrity": "sha512-E44iT5QVOUJBKij4IIV3uvxuNlbKS38Tw1HiupxEIHPv9qtC2PrDYohbXV5U+1jnfIXttny8gUhj+oZvflFlzA==", + "dev": true, + "requires": { + "chardet": "0.4.2", + "iconv-lite": "0.4.19", + "tmp": "0.0.33" + } + }, + "fast-deep-equal": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-1.0.0.tgz", + "integrity": "sha1-liVqO8l1WV6zbYLpkp0GDYk0Of8=", + "dev": true + }, + "fast-json-stable-stringify": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz", + "integrity": "sha1-1RQsDK7msRifh9OnYREGT4bIu/I=", + "dev": true + }, + "fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", + "dev": true + }, + "figures": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/figures/-/figures-2.0.0.tgz", + "integrity": "sha1-OrGi0qYsi/tDGgyUy3l6L84nyWI=", + "dev": true, + "requires": { + "escape-string-regexp": "1.0.5" + } + }, + "file-entry-cache": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-2.0.0.tgz", + "integrity": "sha1-w5KZDD5oR4PYOLjISkXYoEhFg2E=", + "dev": true, + "requires": { + "flat-cache": "1.3.0", + "object-assign": "4.1.1" + } + }, + "flat-cache": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-1.3.0.tgz", + "integrity": "sha1-0wMLMrOBVPTjt+nHCfSQ9++XxIE=", + "dev": true, + "requires": { + "circular-json": "0.3.3", + "del": "2.2.2", + "graceful-fs": "4.1.11", + "write": "0.2.1" + } + }, + "follow-redirects": { + "version": "0.0.7", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-0.0.7.tgz", + "integrity": "sha1-NLkLqyqRGqNHVx2pDyK9NuzYqRk=", + "dev": true, + "requires": { + "debug": "2.6.9", + "stream-consume": "0.1.0" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + } + } + }, + "for-each": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.2.tgz", + "integrity": "sha1-LEBFC5NI6X8oEyJZO6lnBLmr1NQ=", + "dev": true, + "requires": { + "is-function": "1.0.1" + } + }, + "foreach": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/foreach/-/foreach-2.0.5.tgz", + "integrity": "sha1-C+4AUBiusmDQo6865ljdATbsG5k=", + "dev": true + }, + "fs-extra": { + "version": "0.26.7", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-0.26.7.tgz", + "integrity": "sha1-muH92UiXeY7at20JGM9C0MMYT6k=", + "dev": true, + "requires": { + "graceful-fs": "4.1.11", + "jsonfile": "2.4.0", + "klaw": "1.3.1", + "path-is-absolute": "1.0.1", + "rimraf": "2.6.2" + } + }, + "fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", + "dev": true + }, + "function-bind": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", + "dev": true + }, + "functional-red-black-tree": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", + "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=", + "dev": true + }, + "get-set-props": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/get-set-props/-/get-set-props-0.1.0.tgz", + "integrity": "sha1-mYR1wXhEVobQsyJG2l3428++jqM=", + "dev": true + }, + "github": { + "version": "11.0.0", + "resolved": "https://registry.npmjs.org/github/-/github-11.0.0.tgz", + "integrity": "sha1-7bMt9e+zPK0ATr8L3SpLMLtjqFQ=", + "dev": true, + "requires": { + "follow-redirects": "0.0.7", + "https-proxy-agent": "1.0.0", + "mime": "1.6.0", + "netrc": "0.1.4" + } + }, + "github-release-from-changelog": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/github-release-from-changelog/-/github-release-from-changelog-1.3.0.tgz", + "integrity": "sha512-WXIdtpdVCSC2Pz8U7pA1047lMxxneDy7lTuRBqGqopBtLXTzpwaBeZJcnC2AXykuq2Fory07Q+yUtDyqOaip3g==", + "dev": true, + "requires": { + "grizzly": "2.1.5", + "minimist": "1.2.0" + }, + "dependencies": { + "minimist": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", + "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", + "dev": true + } + } + }, + "glob": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz", + "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==", + "dev": true, + "requires": { + "fs.realpath": "1.0.0", + "inflight": "1.0.6", + "inherits": "2.0.3", + "minimatch": "3.0.4", + "once": "1.4.0", + "path-is-absolute": "1.0.1" + } + }, + "globals": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-11.1.0.tgz", + "integrity": "sha512-uEuWt9mqTlPDwSqi+sHjD4nWU/1N+q0fiWI9T1mZpD2UENqX20CFD5T/ziLZvztPaBKl7ZylUi1q6Qfm7E2CiQ==", + "dev": true + }, + "globby": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-5.0.0.tgz", + "integrity": "sha1-69hGZ8oNuzMLmbz8aOrCvFQ3Dg0=", + "dev": true, + "requires": { + "array-union": "1.0.2", + "arrify": "1.0.1", + "glob": "7.1.2", + "object-assign": "4.1.1", + "pify": "2.3.0", + "pinkie-promise": "2.0.1" + } + }, + "graceful-fs": { + "version": "4.1.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.11.tgz", + "integrity": "sha1-Dovf5NHduIVNZOBOp8AOKgJuVlg=", + "dev": true + }, + "grizzly": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/grizzly/-/grizzly-2.1.5.tgz", + "integrity": "sha512-GnfH/XDglF6ltXfllWrxXxzC+XcZHFaVBzEsXxorPSPuCxFfAW/eDGsu4b/ItWfH3oVZp4U/TVaZU8UlqsoZqg==", + "dev": true, + "requires": { + "checkup": "1.3.0", + "debug": "3.1.0", + "execon": "1.2.9", + "github": "11.0.0", + "minimist": "1.2.0", + "os-homedir": "1.0.2", + "readjson": "1.1.3" + }, + "dependencies": { + "minimist": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", + "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", + "dev": true + } + } + }, + "has": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/has/-/has-1.0.1.tgz", + "integrity": "sha1-hGFzP1OLCDfJNh45qauelwTcLyg=", + "dev": true, + "requires": { + "function-bind": "1.1.1" + } + }, + "has-ansi": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", + "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=", + "dev": true, + "requires": { + "ansi-regex": "2.1.1" + } + }, + "has-flag": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz", + "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=" + }, + "https-proxy-agent": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-1.0.0.tgz", + "integrity": "sha1-NffabEjOTdv6JkiRrFk+5f+GceY=", + "dev": true, + "requires": { + "agent-base": "2.1.1", + "debug": "2.6.9", + "extend": "3.0.1" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + } + } + }, + "iconv-lite": { + "version": "0.4.19", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.19.tgz", + "integrity": "sha512-oTZqweIP51xaGPI4uPa56/Pri/480R+mo7SeU+YETByQNhDG55ycFyNLIgta9vXhILrxXDmF7ZGhqZIcuN0gJQ==", + "dev": true + }, + "ignore": { + "version": "3.3.7", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-3.3.7.tgz", + "integrity": "sha512-YGG3ejvBNHRqu0559EOxxNFihD0AjpvHlC/pdGKd3X3ofe+CoJkYazwNJYTNebqpPKN+VVQbh4ZFn1DivMNuHA==", + "dev": true + }, + "imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", + "dev": true + }, + "inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "dev": true, + "requires": { + "once": "1.4.0", + "wrappy": "1.0.2" + } + }, + "inherits": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", + "dev": true + }, + "inquirer": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-3.3.0.tgz", + "integrity": "sha512-h+xtnyk4EwKvFWHrUYsWErEVR+igKtLdchu+o0Z1RL7VU/jVMFbYir2bp6bAj8efFNxWqHX0dIss6fJQ+/+qeQ==", + "dev": true, + "requires": { + "ansi-escapes": "3.0.0", + "chalk": "2.3.0", + "cli-cursor": "2.1.0", + "cli-width": "2.2.0", + "external-editor": "2.1.0", + "figures": "2.0.0", + "lodash": "4.17.4", + "mute-stream": "0.0.7", + "run-async": "2.3.0", + "rx-lite": "4.0.8", + "rx-lite-aggregates": "4.0.8", + "string-width": "2.1.1", + "strip-ansi": "4.0.0", + "through": "2.3.8" + } + }, + "is-arrayish": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.3.1.tgz", + "integrity": "sha1-wt/DhquqDD4zxI2z/ocFnmkGXv0=" + }, + "is-callable": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.1.3.tgz", + "integrity": "sha1-hut1OSgF3cM69xySoO7fdO52BLI=", + "dev": true + }, + "is-date-object": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.1.tgz", + "integrity": "sha1-mqIOtq7rv/d/vTPnTKAbM1gdOhY=", + "dev": true + }, + "is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", + "dev": true + }, + "is-function": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-function/-/is-function-1.0.1.tgz", + "integrity": "sha1-Es+5i2W1fdPRk6MSH19uL0N2ArU=", + "dev": true + }, + "is-get-set-prop": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-get-set-prop/-/is-get-set-prop-1.0.0.tgz", + "integrity": "sha1-JzGHfk14pqae3M5rudaLB3nnYxI=", + "dev": true, + "requires": { + "get-set-props": "0.1.0", + "lowercase-keys": "1.0.0" + } + }, + "is-js-type": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-js-type/-/is-js-type-2.0.0.tgz", + "integrity": "sha1-c2FwBtZZtOtHKbunR9KHgt8PfiI=", + "dev": true, + "requires": { + "js-types": "1.0.0" + } + }, + "is-obj-prop": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-obj-prop/-/is-obj-prop-1.0.0.tgz", + "integrity": "sha1-s03nnEULjXxzqyzfZ9yHWtuF+A4=", + "dev": true, + "requires": { + "lowercase-keys": "1.0.0", + "obj-props": "1.1.0" + } + }, + "is-path-cwd": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-path-cwd/-/is-path-cwd-1.0.0.tgz", + "integrity": "sha1-0iXsIxMuie3Tj9p2dHLmLmXxEG0=", + "dev": true + }, + "is-path-in-cwd": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-path-in-cwd/-/is-path-in-cwd-1.0.0.tgz", + "integrity": "sha1-ZHdYK4IU1gI0YJRWcAO+ip6sBNw=", + "dev": true, + "requires": { + "is-path-inside": "1.0.1" + } + }, + "is-path-inside": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-1.0.1.tgz", + "integrity": "sha1-jvW33lBDej/cprToZe96pVy0gDY=", + "dev": true, + "requires": { + "path-is-inside": "1.0.2" + } + }, + "is-promise": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-2.1.0.tgz", + "integrity": "sha1-eaKp7OfwlugPNtKy87wWwf9L8/o=", + "dev": true + }, + "is-proto-prop": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-proto-prop/-/is-proto-prop-1.0.0.tgz", + "integrity": "sha1-s5UflcCJkk+11PzaZUKrPoPisiA=", + "dev": true, + "requires": { + "lowercase-keys": "1.0.0", + "proto-props": "0.2.1" + } + }, + "is-regex": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.0.4.tgz", + "integrity": "sha1-VRdIm1RwkbCTDglWVM7SXul+lJE=", + "dev": true, + "requires": { + "has": "1.0.1" + } + }, + "is-resolvable": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-resolvable/-/is-resolvable-1.0.1.tgz", + "integrity": "sha512-y5CXYbzvB3jTnWAZH1Nl7ykUWb6T3BcTs56HUruwBf8MhF56n1HWqhDWnVFo8GHrUPDgvUUNVhrc2U8W7iqz5g==", + "dev": true + }, + "is-symbol": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.1.tgz", + "integrity": "sha1-PMWfAAJRlLarLjjbrmaJJWtmBXI=", + "dev": true + }, + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", + "dev": true + }, + "isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", + "dev": true + }, + "js-tokens": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-3.0.2.tgz", + "integrity": "sha1-mGbfOVECEw449/mWvOtlRDIJwls=", + "dev": true + }, + "js-types": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/js-types/-/js-types-1.0.0.tgz", + "integrity": "sha1-0kLmSU7Vcq08koCfyL7X92h8vwM=", + "dev": true + }, + "js-yaml": { + "version": "3.10.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.10.0.tgz", + "integrity": "sha512-O2v52ffjLa9VeM43J4XocZE//WT9N0IiwDa3KSHH7Tu8CtH+1qM8SIZvnsTh6v+4yFy5KUY3BHUVwjpfAWsjIA==", + "dev": true, + "requires": { + "argparse": "1.0.9", + "esprima": "4.0.0" + } + }, + "json-schema-traverse": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.3.1.tgz", + "integrity": "sha1-NJptRMU6Ud6JtAgFxdXlm0F9M0A=", + "dev": true + }, + "json-stable-stringify-without-jsonify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", + "integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=", + "dev": true + }, + "jsonfile": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-2.4.0.tgz", + "integrity": "sha1-NzaitCi4e72gzIO1P6PWM6NcKug=", + "dev": true, + "requires": { + "graceful-fs": "4.1.11" + } + }, + "klaw": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/klaw/-/klaw-1.3.1.tgz", + "integrity": "sha1-QIhDO0azsbolnXh4XY6W9zugJDk=", + "dev": true, + "requires": { + "graceful-fs": "4.1.11" + } + }, + "levn": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", + "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=", + "dev": true, + "requires": { + "prelude-ls": "1.1.2", + "type-check": "0.3.2" + } + }, + "lodash": { + "version": "4.17.4", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.4.tgz", + "integrity": "sha1-eCA6TRwyiuHYbcpkYONptX9AVa4=", + "dev": true + }, + "lowercase-keys": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-1.0.0.tgz", + "integrity": "sha1-TjNms55/VFfjXxMkvfb4jQv8cwY=", + "dev": true + }, + "lru-cache": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.1.tgz", + "integrity": "sha512-q4spe4KTfsAS1SUHLO0wz8Qiyf1+vMIAgpRYioFYDMNqKfHQbg+AVDH3i4fvpl71/P1L0dBl+fQi+P37UYf0ew==", + "dev": true, + "requires": { + "pseudomap": "1.0.2", + "yallist": "2.1.2" + } + }, + "mime": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", + "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", + "dev": true + }, + "mimic-fn": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-1.1.0.tgz", + "integrity": "sha1-5md4PZLonb00KBi1IwudYqZyrRg=", + "dev": true + }, + "minimatch": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", + "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "dev": true, + "requires": { + "brace-expansion": "1.1.8" + } + }, + "minimist": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", + "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=", + "dev": true + }, + "mkdirp": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", + "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", + "dev": true, + "requires": { + "minimist": "0.0.8" + } + }, + "mount-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/mount-point/-/mount-point-3.0.0.tgz", + "integrity": "sha1-Zly57evoDREOZY21bDHQrvUaj5c=", + "dev": true, + "requires": { + "@sindresorhus/df": "1.0.1", + "pify": "2.3.0", + "pinkie-promise": "2.0.1" + }, + "dependencies": { + "@sindresorhus/df": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@sindresorhus/df/-/df-1.0.1.tgz", + "integrity": "sha1-xptm9S9vzdKHyAffIQMF2694UA0=", + "dev": true + } + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + }, + "mute-stream": { + "version": "0.0.7", + "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.7.tgz", + "integrity": "sha1-MHXOk7whuPq0PhvE2n6BFe0ee6s=", + "dev": true + }, + "natural-compare": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=", + "dev": true + }, + "netrc": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/netrc/-/netrc-0.1.4.tgz", + "integrity": "sha1-a+lPysqNd63gqWcNxGCRTJRHJEQ=", + "dev": true + }, + "npm-run-path": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-1.0.0.tgz", + "integrity": "sha1-9cMr9ZX+ga6Sfa7FLoL4sACsPI8=", + "dev": true, + "requires": { + "path-key": "1.0.0" + } + }, + "npmpub": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/npmpub/-/npmpub-3.1.0.tgz", + "integrity": "sha1-c0OoAf+xi/0s7CM1hLkUWa5O4Uk=", + "dev": true, + "requires": { + "chalk": "1.1.3", + "github-release-from-changelog": "1.3.0", + "minimist": "1.2.0", + "shelljs": "0.5.3", + "trash": "3.4.2" + }, + "dependencies": { + "ansi-styles": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", + "dev": true + }, + "chalk": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", + "dev": true, + "requires": { + "ansi-styles": "2.2.1", + "escape-string-regexp": "1.0.5", + "has-ansi": "2.0.0", + "strip-ansi": "3.0.1", + "supports-color": "2.0.0" + } + }, + "minimist": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", + "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", + "dev": true + }, + "strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "dev": true, + "requires": { + "ansi-regex": "2.1.1" + } + }, + "supports-color": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", + "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", + "dev": true + } + } + }, + "nyc": { + "version": "11.4.0", + "resolved": "https://registry.npmjs.org/nyc/-/nyc-11.4.0.tgz", + "integrity": "sha512-4Due4ssNvAog/Sz3LpPpaFTV5pdHWRU+z5UcENwthSn079tY6UcQnF4h2q/TaTH3WuNmhiXsaRWbNeFSmH2JhA==", + "dev": true, + "requires": { + "archy": "1.0.0", + "arrify": "1.0.1", + "caching-transform": "1.0.1", + "convert-source-map": "1.5.1", + "debug-log": "1.0.1", + "default-require-extensions": "1.0.0", + "find-cache-dir": "0.1.1", + "find-up": "2.1.0", + "foreground-child": "1.5.6", + "glob": "7.1.2", + "istanbul-lib-coverage": "1.1.1", + "istanbul-lib-hook": "1.1.0", + "istanbul-lib-instrument": "1.9.1", + "istanbul-lib-report": "1.1.2", + "istanbul-lib-source-maps": "1.2.2", + "istanbul-reports": "1.1.3", + "md5-hex": "1.3.0", + "merge-source-map": "1.0.4", + "micromatch": "2.3.11", + "mkdirp": "0.5.1", + "resolve-from": "2.0.0", + "rimraf": "2.6.2", + "signal-exit": "3.0.2", + "spawn-wrap": "1.4.1", + "test-exclude": "4.1.1", + "yargs": "10.0.3", + "yargs-parser": "8.0.0" + }, + "dependencies": { + "align-text": { + "version": "0.1.4", + "bundled": true, + "dev": true, + "requires": { + "kind-of": "3.2.2", + "longest": "1.0.1", + "repeat-string": "1.6.1" + } + }, + "amdefine": { + "version": "1.0.1", + "bundled": true, + "dev": true + }, + "ansi-regex": { + "version": "2.1.1", + "bundled": true, + "dev": true + }, + "ansi-styles": { + "version": "2.2.1", + "bundled": true, + "dev": true + }, + "append-transform": { + "version": "0.4.0", + "bundled": true, + "dev": true, + "requires": { + "default-require-extensions": "1.0.0" + } + }, + "archy": { + "version": "1.0.0", + "bundled": true, + "dev": true + }, + "arr-diff": { + "version": "2.0.0", + "bundled": true, + "dev": true, + "requires": { + "arr-flatten": "1.1.0" + } + }, + "arr-flatten": { + "version": "1.1.0", + "bundled": true, + "dev": true + }, + "array-unique": { + "version": "0.2.1", + "bundled": true, + "dev": true + }, + "arrify": { + "version": "1.0.1", + "bundled": true, + "dev": true + }, + "async": { + "version": "1.5.2", + "bundled": true, + "dev": true + }, + "babel-code-frame": { + "version": "6.26.0", + "bundled": true, + "dev": true, + "requires": { + "chalk": "1.1.3", + "esutils": "2.0.2", + "js-tokens": "3.0.2" + } + }, + "babel-generator": { + "version": "6.26.0", + "bundled": true, + "dev": true, + "requires": { + "babel-messages": "6.23.0", + "babel-runtime": "6.26.0", + "babel-types": "6.26.0", + "detect-indent": "4.0.0", + "jsesc": "1.3.0", + "lodash": "4.17.4", + "source-map": "0.5.7", + "trim-right": "1.0.1" + } + }, + "babel-messages": { + "version": "6.23.0", + "bundled": true, + "dev": true, + "requires": { + "babel-runtime": "6.26.0" + } + }, + "babel-runtime": { + "version": "6.26.0", + "bundled": true, + "dev": true, + "requires": { + "core-js": "2.5.1", + "regenerator-runtime": "0.11.0" + } + }, + "babel-template": { + "version": "6.26.0", + "bundled": true, + "dev": true, + "requires": { + "babel-runtime": "6.26.0", + "babel-traverse": "6.26.0", + "babel-types": "6.26.0", + "babylon": "6.18.0", + "lodash": "4.17.4" + } + }, + "babel-traverse": { + "version": "6.26.0", + "bundled": true, + "dev": true, + "requires": { + "babel-code-frame": "6.26.0", + "babel-messages": "6.23.0", + "babel-runtime": "6.26.0", + "babel-types": "6.26.0", + "babylon": "6.18.0", + "debug": "2.6.9", + "globals": "9.18.0", + "invariant": "2.2.2", + "lodash": "4.17.4" + } + }, + "babel-types": { + "version": "6.26.0", + "bundled": true, + "dev": true, + "requires": { + "babel-runtime": "6.26.0", + "esutils": "2.0.2", + "lodash": "4.17.4", + "to-fast-properties": "1.0.3" + } + }, + "babylon": { + "version": "6.18.0", + "bundled": true, + "dev": true + }, + "balanced-match": { + "version": "1.0.0", + "bundled": true, + "dev": true + }, + "brace-expansion": { + "version": "1.1.8", + "bundled": true, + "dev": true, + "requires": { + "balanced-match": "1.0.0", + "concat-map": "0.0.1" + } + }, + "braces": { + "version": "1.8.5", + "bundled": true, + "dev": true, + "requires": { + "expand-range": "1.8.2", + "preserve": "0.2.0", + "repeat-element": "1.1.2" + } + }, + "builtin-modules": { + "version": "1.1.1", + "bundled": true, + "dev": true + }, + "caching-transform": { + "version": "1.0.1", + "bundled": true, + "dev": true, + "requires": { + "md5-hex": "1.3.0", + "mkdirp": "0.5.1", + "write-file-atomic": "1.3.4" + } + }, + "camelcase": { + "version": "1.2.1", + "bundled": true, + "dev": true, + "optional": true + }, + "center-align": { + "version": "0.1.3", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "align-text": "0.1.4", + "lazy-cache": "1.0.4" + } + }, + "chalk": { + "version": "1.1.3", + "bundled": true, + "dev": true, + "requires": { + "ansi-styles": "2.2.1", + "escape-string-regexp": "1.0.5", + "has-ansi": "2.0.0", + "strip-ansi": "3.0.1", + "supports-color": "2.0.0" + } + }, + "cliui": { + "version": "2.1.0", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "center-align": "0.1.3", + "right-align": "0.1.3", + "wordwrap": "0.0.2" + }, + "dependencies": { + "wordwrap": { + "version": "0.0.2", + "bundled": true, + "dev": true, + "optional": true + } + } + }, + "code-point-at": { + "version": "1.1.0", + "bundled": true, + "dev": true + }, + "commondir": { + "version": "1.0.1", + "bundled": true, + "dev": true + }, + "concat-map": { + "version": "0.0.1", + "bundled": true, + "dev": true + }, + "convert-source-map": { + "version": "1.5.1", + "bundled": true, + "dev": true + }, + "core-js": { + "version": "2.5.1", + "bundled": true, + "dev": true + }, + "cross-spawn": { + "version": "4.0.2", + "bundled": true, + "dev": true, + "requires": { + "lru-cache": "4.1.1", + "which": "1.3.0" + } + }, + "debug": { + "version": "2.6.9", + "bundled": true, + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "debug-log": { + "version": "1.0.1", + "bundled": true, + "dev": true + }, + "decamelize": { + "version": "1.2.0", + "bundled": true, + "dev": true + }, + "default-require-extensions": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "requires": { + "strip-bom": "2.0.0" + } + }, + "detect-indent": { + "version": "4.0.0", + "bundled": true, + "dev": true, + "requires": { + "repeating": "2.0.1" + } + }, + "error-ex": { + "version": "1.3.1", + "bundled": true, + "dev": true, + "requires": { + "is-arrayish": "0.2.1" + } + }, + "escape-string-regexp": { + "version": "1.0.5", + "bundled": true, + "dev": true + }, + "esutils": { + "version": "2.0.2", + "bundled": true, + "dev": true + }, + "execa": { + "version": "0.7.0", + "bundled": true, + "dev": true, + "requires": { + "cross-spawn": "5.1.0", + "get-stream": "3.0.0", + "is-stream": "1.1.0", + "npm-run-path": "2.0.2", + "p-finally": "1.0.0", + "signal-exit": "3.0.2", + "strip-eof": "1.0.0" + }, + "dependencies": { + "cross-spawn": { + "version": "5.1.0", + "bundled": true, + "dev": true, + "requires": { + "lru-cache": "4.1.1", + "shebang-command": "1.2.0", + "which": "1.3.0" + } + } + } + }, + "expand-brackets": { + "version": "0.1.5", + "bundled": true, + "dev": true, + "requires": { + "is-posix-bracket": "0.1.1" + } + }, + "expand-range": { + "version": "1.8.2", + "bundled": true, + "dev": true, + "requires": { + "fill-range": "2.2.3" + } + }, + "extglob": { + "version": "0.3.2", + "bundled": true, + "dev": true, + "requires": { + "is-extglob": "1.0.0" + } + }, + "filename-regex": { + "version": "2.0.1", + "bundled": true, + "dev": true + }, + "fill-range": { + "version": "2.2.3", + "bundled": true, + "dev": true, + "requires": { + "is-number": "2.1.0", + "isobject": "2.1.0", + "randomatic": "1.1.7", + "repeat-element": "1.1.2", + "repeat-string": "1.6.1" + } + }, + "find-cache-dir": { + "version": "0.1.1", + "bundled": true, + "dev": true, + "requires": { + "commondir": "1.0.1", + "mkdirp": "0.5.1", + "pkg-dir": "1.0.0" + } + }, + "find-up": { + "version": "2.1.0", + "bundled": true, + "dev": true, + "requires": { + "locate-path": "2.0.0" + } + }, + "for-in": { + "version": "1.0.2", + "bundled": true, + "dev": true + }, + "for-own": { + "version": "0.1.5", + "bundled": true, + "dev": true, + "requires": { + "for-in": "1.0.2" + } + }, + "foreground-child": { + "version": "1.5.6", + "bundled": true, + "dev": true, + "requires": { + "cross-spawn": "4.0.2", + "signal-exit": "3.0.2" + } + }, + "fs.realpath": { + "version": "1.0.0", + "bundled": true, + "dev": true + }, + "get-caller-file": { + "version": "1.0.2", + "bundled": true, + "dev": true + }, + "get-stream": { + "version": "3.0.0", + "bundled": true, + "dev": true + }, + "glob": { + "version": "7.1.2", + "bundled": true, + "dev": true, + "requires": { + "fs.realpath": "1.0.0", + "inflight": "1.0.6", + "inherits": "2.0.3", + "minimatch": "3.0.4", + "once": "1.4.0", + "path-is-absolute": "1.0.1" + } + }, + "glob-base": { + "version": "0.3.0", + "bundled": true, + "dev": true, + "requires": { + "glob-parent": "2.0.0", + "is-glob": "2.0.1" + } + }, + "glob-parent": { + "version": "2.0.0", + "bundled": true, + "dev": true, + "requires": { + "is-glob": "2.0.1" + } + }, + "globals": { + "version": "9.18.0", + "bundled": true, + "dev": true + }, + "graceful-fs": { + "version": "4.1.11", + "bundled": true, + "dev": true + }, + "handlebars": { + "version": "4.0.11", + "bundled": true, + "dev": true, + "requires": { + "async": "1.5.2", + "optimist": "0.6.1", + "source-map": "0.4.4", + "uglify-js": "2.8.29" + }, + "dependencies": { + "source-map": { + "version": "0.4.4", + "bundled": true, + "dev": true, + "requires": { + "amdefine": "1.0.1" + } + } + } + }, + "has-ansi": { + "version": "2.0.0", + "bundled": true, + "dev": true, + "requires": { + "ansi-regex": "2.1.1" + } + }, + "has-flag": { + "version": "1.0.0", + "bundled": true, + "dev": true + }, + "hosted-git-info": { + "version": "2.5.0", + "bundled": true, + "dev": true + }, + "imurmurhash": { + "version": "0.1.4", + "bundled": true, + "dev": true + }, + "inflight": { + "version": "1.0.6", + "bundled": true, + "dev": true, + "requires": { + "once": "1.4.0", + "wrappy": "1.0.2" + } + }, + "inherits": { + "version": "2.0.3", + "bundled": true, + "dev": true + }, + "invariant": { + "version": "2.2.2", + "bundled": true, + "dev": true, + "requires": { + "loose-envify": "1.3.1" + } + }, + "invert-kv": { + "version": "1.0.0", + "bundled": true, + "dev": true + }, + "is-arrayish": { + "version": "0.2.1", + "bundled": true, + "dev": true + }, + "is-buffer": { + "version": "1.1.6", + "bundled": true, + "dev": true + }, + "is-builtin-module": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "requires": { + "builtin-modules": "1.1.1" + } + }, + "is-dotfile": { + "version": "1.0.3", + "bundled": true, + "dev": true + }, + "is-equal-shallow": { + "version": "0.1.3", + "bundled": true, + "dev": true, + "requires": { + "is-primitive": "2.0.0" + } + }, + "is-extendable": { + "version": "0.1.1", + "bundled": true, + "dev": true + }, + "is-extglob": { + "version": "1.0.0", + "bundled": true, + "dev": true + }, + "is-finite": { + "version": "1.0.2", + "bundled": true, + "dev": true, + "requires": { + "number-is-nan": "1.0.1" + } + }, + "is-fullwidth-code-point": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "requires": { + "number-is-nan": "1.0.1" + } + }, + "is-glob": { + "version": "2.0.1", + "bundled": true, + "dev": true, + "requires": { + "is-extglob": "1.0.0" + } + }, + "is-number": { + "version": "2.1.0", + "bundled": true, + "dev": true, + "requires": { + "kind-of": "3.2.2" + } + }, + "is-posix-bracket": { + "version": "0.1.1", + "bundled": true, + "dev": true + }, + "is-primitive": { + "version": "2.0.0", + "bundled": true, + "dev": true + }, + "is-stream": { + "version": "1.1.0", + "bundled": true, + "dev": true + }, + "is-utf8": { + "version": "0.2.1", + "bundled": true, + "dev": true + }, + "isarray": { + "version": "1.0.0", + "bundled": true, + "dev": true + }, + "isexe": { + "version": "2.0.0", + "bundled": true, + "dev": true + }, + "isobject": { + "version": "2.1.0", + "bundled": true, + "dev": true, + "requires": { + "isarray": "1.0.0" + } + }, + "istanbul-lib-coverage": { + "version": "1.1.1", + "bundled": true, + "dev": true + }, + "istanbul-lib-hook": { + "version": "1.1.0", + "bundled": true, + "dev": true, + "requires": { + "append-transform": "0.4.0" + } + }, + "istanbul-lib-instrument": { + "version": "1.9.1", + "bundled": true, + "dev": true, + "requires": { + "babel-generator": "6.26.0", + "babel-template": "6.26.0", + "babel-traverse": "6.26.0", + "babel-types": "6.26.0", + "babylon": "6.18.0", + "istanbul-lib-coverage": "1.1.1", + "semver": "5.4.1" + } + }, + "istanbul-lib-report": { + "version": "1.1.2", + "bundled": true, + "dev": true, + "requires": { + "istanbul-lib-coverage": "1.1.1", + "mkdirp": "0.5.1", + "path-parse": "1.0.5", + "supports-color": "3.2.3" + }, + "dependencies": { + "supports-color": { + "version": "3.2.3", + "bundled": true, + "dev": true, + "requires": { + "has-flag": "1.0.0" + } + } + } + }, + "istanbul-lib-source-maps": { + "version": "1.2.2", + "bundled": true, + "dev": true, + "requires": { + "debug": "3.1.0", + "istanbul-lib-coverage": "1.1.1", + "mkdirp": "0.5.1", + "rimraf": "2.6.2", + "source-map": "0.5.7" + }, + "dependencies": { + "debug": { + "version": "3.1.0", + "bundled": true, + "dev": true, + "requires": { + "ms": "2.0.0" + } + } + } + }, + "istanbul-reports": { + "version": "1.1.3", + "bundled": true, + "dev": true, + "requires": { + "handlebars": "4.0.11" + } + }, + "js-tokens": { + "version": "3.0.2", + "bundled": true, + "dev": true + }, + "jsesc": { + "version": "1.3.0", + "bundled": true, + "dev": true + }, + "kind-of": { + "version": "3.2.2", + "bundled": true, + "dev": true, + "requires": { + "is-buffer": "1.1.6" + } + }, + "lazy-cache": { + "version": "1.0.4", + "bundled": true, + "dev": true, + "optional": true + }, + "lcid": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "requires": { + "invert-kv": "1.0.0" + } + }, + "load-json-file": { + "version": "1.1.0", + "bundled": true, + "dev": true, + "requires": { + "graceful-fs": "4.1.11", + "parse-json": "2.2.0", + "pify": "2.3.0", + "pinkie-promise": "2.0.1", + "strip-bom": "2.0.0" + } + }, + "locate-path": { + "version": "2.0.0", + "bundled": true, + "dev": true, + "requires": { + "p-locate": "2.0.0", + "path-exists": "3.0.0" + }, + "dependencies": { + "path-exists": { + "version": "3.0.0", + "bundled": true, + "dev": true + } + } + }, + "lodash": { + "version": "4.17.4", + "bundled": true, + "dev": true + }, + "longest": { + "version": "1.0.1", + "bundled": true, + "dev": true + }, + "loose-envify": { + "version": "1.3.1", + "bundled": true, + "dev": true, + "requires": { + "js-tokens": "3.0.2" + } + }, + "lru-cache": { + "version": "4.1.1", + "bundled": true, + "dev": true, + "requires": { + "pseudomap": "1.0.2", + "yallist": "2.1.2" + } + }, + "md5-hex": { + "version": "1.3.0", + "bundled": true, + "dev": true, + "requires": { + "md5-o-matic": "0.1.1" + } + }, + "md5-o-matic": { + "version": "0.1.1", + "bundled": true, + "dev": true + }, + "mem": { + "version": "1.1.0", + "bundled": true, + "dev": true, + "requires": { + "mimic-fn": "1.1.0" + } + }, + "merge-source-map": { + "version": "1.0.4", + "bundled": true, + "dev": true, + "requires": { + "source-map": "0.5.7" + } + }, + "micromatch": { + "version": "2.3.11", + "bundled": true, + "dev": true, + "requires": { + "arr-diff": "2.0.0", + "array-unique": "0.2.1", + "braces": "1.8.5", + "expand-brackets": "0.1.5", + "extglob": "0.3.2", + "filename-regex": "2.0.1", + "is-extglob": "1.0.0", + "is-glob": "2.0.1", + "kind-of": "3.2.2", + "normalize-path": "2.1.1", + "object.omit": "2.0.1", + "parse-glob": "3.0.4", + "regex-cache": "0.4.4" + } + }, + "mimic-fn": { + "version": "1.1.0", + "bundled": true, + "dev": true + }, + "minimatch": { + "version": "3.0.4", + "bundled": true, + "dev": true, + "requires": { + "brace-expansion": "1.1.8" + } + }, + "minimist": { + "version": "0.0.8", + "bundled": true, + "dev": true + }, + "mkdirp": { + "version": "0.5.1", + "bundled": true, + "dev": true, + "requires": { + "minimist": "0.0.8" + } + }, + "ms": { + "version": "2.0.0", + "bundled": true, + "dev": true + }, + "normalize-package-data": { + "version": "2.4.0", + "bundled": true, + "dev": true, + "requires": { + "hosted-git-info": "2.5.0", + "is-builtin-module": "1.0.0", + "semver": "5.4.1", + "validate-npm-package-license": "3.0.1" + } + }, + "normalize-path": { + "version": "2.1.1", + "bundled": true, + "dev": true, + "requires": { + "remove-trailing-separator": "1.1.0" + } + }, + "npm-run-path": { + "version": "2.0.2", + "bundled": true, + "dev": true, + "requires": { + "path-key": "2.0.1" + } + }, + "number-is-nan": { + "version": "1.0.1", + "bundled": true, + "dev": true + }, + "object-assign": { + "version": "4.1.1", + "bundled": true, + "dev": true + }, + "object.omit": { + "version": "2.0.1", + "bundled": true, + "dev": true, + "requires": { + "for-own": "0.1.5", + "is-extendable": "0.1.1" + } + }, + "once": { + "version": "1.4.0", + "bundled": true, + "dev": true, + "requires": { + "wrappy": "1.0.2" + } + }, + "optimist": { + "version": "0.6.1", + "bundled": true, + "dev": true, + "requires": { + "minimist": "0.0.8", + "wordwrap": "0.0.3" + } + }, + "os-homedir": { + "version": "1.0.2", + "bundled": true, + "dev": true + }, + "os-locale": { + "version": "2.1.0", + "bundled": true, + "dev": true, + "requires": { + "execa": "0.7.0", + "lcid": "1.0.0", + "mem": "1.1.0" + } + }, + "p-finally": { + "version": "1.0.0", + "bundled": true, + "dev": true + }, + "p-limit": { + "version": "1.1.0", + "bundled": true, + "dev": true + }, + "p-locate": { + "version": "2.0.0", + "bundled": true, + "dev": true, + "requires": { + "p-limit": "1.1.0" + } + }, + "parse-glob": { + "version": "3.0.4", + "bundled": true, + "dev": true, + "requires": { + "glob-base": "0.3.0", + "is-dotfile": "1.0.3", + "is-extglob": "1.0.0", + "is-glob": "2.0.1" + } + }, + "parse-json": { + "version": "2.2.0", + "bundled": true, + "dev": true, + "requires": { + "error-ex": "1.3.1" + } + }, + "path-exists": { + "version": "2.1.0", + "bundled": true, + "dev": true, + "requires": { + "pinkie-promise": "2.0.1" + } + }, + "path-is-absolute": { + "version": "1.0.1", + "bundled": true, + "dev": true + }, + "path-key": { + "version": "2.0.1", + "bundled": true, + "dev": true + }, + "path-parse": { + "version": "1.0.5", + "bundled": true, + "dev": true + }, + "path-type": { + "version": "1.1.0", + "bundled": true, + "dev": true, + "requires": { + "graceful-fs": "4.1.11", + "pify": "2.3.0", + "pinkie-promise": "2.0.1" + } + }, + "pify": { + "version": "2.3.0", + "bundled": true, + "dev": true + }, + "pinkie": { + "version": "2.0.4", + "bundled": true, + "dev": true + }, + "pinkie-promise": { + "version": "2.0.1", + "bundled": true, + "dev": true, + "requires": { + "pinkie": "2.0.4" + } + }, + "pkg-dir": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "requires": { + "find-up": "1.1.2" + }, + "dependencies": { + "find-up": { + "version": "1.1.2", + "bundled": true, + "dev": true, + "requires": { + "path-exists": "2.1.0", + "pinkie-promise": "2.0.1" + } + } + } + }, + "preserve": { + "version": "0.2.0", + "bundled": true, + "dev": true + }, + "pseudomap": { + "version": "1.0.2", + "bundled": true, + "dev": true + }, + "randomatic": { + "version": "1.1.7", + "bundled": true, + "dev": true, + "requires": { + "is-number": "3.0.0", + "kind-of": "4.0.0" + }, + "dependencies": { + "is-number": { + "version": "3.0.0", + "bundled": true, + "dev": true, + "requires": { + "kind-of": "3.2.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "bundled": true, + "dev": true, + "requires": { + "is-buffer": "1.1.6" + } + } + } + }, + "kind-of": { + "version": "4.0.0", + "bundled": true, + "dev": true, + "requires": { + "is-buffer": "1.1.6" + } + } + } + }, + "read-pkg": { + "version": "1.1.0", + "bundled": true, + "dev": true, + "requires": { + "load-json-file": "1.1.0", + "normalize-package-data": "2.4.0", + "path-type": "1.1.0" + } + }, + "read-pkg-up": { + "version": "1.0.1", + "bundled": true, + "dev": true, + "requires": { + "find-up": "1.1.2", + "read-pkg": "1.1.0" + }, + "dependencies": { + "find-up": { + "version": "1.1.2", + "bundled": true, + "dev": true, + "requires": { + "path-exists": "2.1.0", + "pinkie-promise": "2.0.1" + } + } + } + }, + "regenerator-runtime": { + "version": "0.11.0", + "bundled": true, + "dev": true + }, + "regex-cache": { + "version": "0.4.4", + "bundled": true, + "dev": true, + "requires": { + "is-equal-shallow": "0.1.3" + } + }, + "remove-trailing-separator": { + "version": "1.1.0", + "bundled": true, + "dev": true + }, + "repeat-element": { + "version": "1.1.2", + "bundled": true, + "dev": true + }, + "repeat-string": { + "version": "1.6.1", + "bundled": true, + "dev": true + }, + "repeating": { + "version": "2.0.1", + "bundled": true, + "dev": true, + "requires": { + "is-finite": "1.0.2" + } + }, + "require-directory": { + "version": "2.1.1", + "bundled": true, + "dev": true + }, + "require-main-filename": { + "version": "1.0.1", + "bundled": true, + "dev": true + }, + "resolve-from": { + "version": "2.0.0", + "bundled": true, + "dev": true + }, + "right-align": { + "version": "0.1.3", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "align-text": "0.1.4" + } + }, + "rimraf": { + "version": "2.6.2", + "bundled": true, + "dev": true, + "requires": { + "glob": "7.1.2" + } + }, + "semver": { + "version": "5.4.1", + "bundled": true, + "dev": true + }, + "set-blocking": { + "version": "2.0.0", + "bundled": true, + "dev": true + }, + "shebang-command": { + "version": "1.2.0", + "bundled": true, + "dev": true, + "requires": { + "shebang-regex": "1.0.0" + } + }, + "shebang-regex": { + "version": "1.0.0", + "bundled": true, + "dev": true + }, + "signal-exit": { + "version": "3.0.2", + "bundled": true, + "dev": true + }, + "slide": { + "version": "1.1.6", + "bundled": true, + "dev": true + }, + "source-map": { + "version": "0.5.7", + "bundled": true, + "dev": true + }, + "spawn-wrap": { + "version": "1.4.1", + "bundled": true, + "dev": true, + "requires": { + "foreground-child": "1.5.6", + "mkdirp": "0.5.1", + "os-homedir": "1.0.2", + "rimraf": "2.6.2", + "signal-exit": "3.0.2", + "which": "1.3.0" + } + }, + "spdx-correct": { + "version": "1.0.2", + "bundled": true, + "dev": true, + "requires": { + "spdx-license-ids": "1.2.2" + } + }, + "spdx-expression-parse": { + "version": "1.0.4", + "bundled": true, + "dev": true + }, + "spdx-license-ids": { + "version": "1.2.2", + "bundled": true, + "dev": true + }, + "string-width": { + "version": "2.1.1", + "bundled": true, + "dev": true, + "requires": { + "is-fullwidth-code-point": "2.0.0", + "strip-ansi": "4.0.0" + }, + "dependencies": { + "ansi-regex": { + "version": "3.0.0", + "bundled": true, + "dev": true + }, + "is-fullwidth-code-point": { + "version": "2.0.0", + "bundled": true, + "dev": true + }, + "strip-ansi": { + "version": "4.0.0", + "bundled": true, + "dev": true, + "requires": { + "ansi-regex": "3.0.0" + } + } + } + }, + "strip-ansi": { + "version": "3.0.1", + "bundled": true, + "dev": true, + "requires": { + "ansi-regex": "2.1.1" + } + }, + "strip-bom": { + "version": "2.0.0", + "bundled": true, + "dev": true, + "requires": { + "is-utf8": "0.2.1" + } + }, + "strip-eof": { + "version": "1.0.0", + "bundled": true, + "dev": true + }, + "supports-color": { + "version": "2.0.0", + "bundled": true, + "dev": true + }, + "test-exclude": { + "version": "4.1.1", + "bundled": true, + "dev": true, + "requires": { + "arrify": "1.0.1", + "micromatch": "2.3.11", + "object-assign": "4.1.1", + "read-pkg-up": "1.0.1", + "require-main-filename": "1.0.1" + } + }, + "to-fast-properties": { + "version": "1.0.3", + "bundled": true, + "dev": true + }, + "trim-right": { + "version": "1.0.1", + "bundled": true, + "dev": true + }, + "uglify-js": { + "version": "2.8.29", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "source-map": "0.5.7", + "uglify-to-browserify": "1.0.2", + "yargs": "3.10.0" + }, + "dependencies": { + "yargs": { + "version": "3.10.0", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "camelcase": "1.2.1", + "cliui": "2.1.0", + "decamelize": "1.2.0", + "window-size": "0.1.0" + } + } + } + }, + "uglify-to-browserify": { + "version": "1.0.2", + "bundled": true, + "dev": true, + "optional": true + }, + "validate-npm-package-license": { + "version": "3.0.1", + "bundled": true, + "dev": true, + "requires": { + "spdx-correct": "1.0.2", + "spdx-expression-parse": "1.0.4" + } + }, + "which": { + "version": "1.3.0", + "bundled": true, + "dev": true, + "requires": { + "isexe": "2.0.0" + } + }, + "which-module": { + "version": "2.0.0", + "bundled": true, + "dev": true + }, + "window-size": { + "version": "0.1.0", + "bundled": true, + "dev": true, + "optional": true + }, + "wordwrap": { + "version": "0.0.3", + "bundled": true, + "dev": true + }, + "wrap-ansi": { + "version": "2.1.0", + "bundled": true, + "dev": true, + "requires": { + "string-width": "1.0.2", + "strip-ansi": "3.0.1" + }, + "dependencies": { + "string-width": { + "version": "1.0.2", + "bundled": true, + "dev": true, + "requires": { + "code-point-at": "1.1.0", + "is-fullwidth-code-point": "1.0.0", + "strip-ansi": "3.0.1" + } + } + } + }, + "wrappy": { + "version": "1.0.2", + "bundled": true, + "dev": true + }, + "write-file-atomic": { + "version": "1.3.4", + "bundled": true, + "dev": true, + "requires": { + "graceful-fs": "4.1.11", + "imurmurhash": "0.1.4", + "slide": "1.1.6" + } + }, + "y18n": { + "version": "3.2.1", + "bundled": true, + "dev": true + }, + "yallist": { + "version": "2.1.2", + "bundled": true, + "dev": true + }, + "yargs": { + "version": "10.0.3", + "bundled": true, + "dev": true, + "requires": { + "cliui": "3.2.0", + "decamelize": "1.2.0", + "find-up": "2.1.0", + "get-caller-file": "1.0.2", + "os-locale": "2.1.0", + "require-directory": "2.1.1", + "require-main-filename": "1.0.1", + "set-blocking": "2.0.0", + "string-width": "2.1.1", + "which-module": "2.0.0", + "y18n": "3.2.1", + "yargs-parser": "8.0.0" + }, + "dependencies": { + "cliui": { + "version": "3.2.0", + "bundled": true, + "dev": true, + "requires": { + "string-width": "1.0.2", + "strip-ansi": "3.0.1", + "wrap-ansi": "2.1.0" + }, + "dependencies": { + "string-width": { + "version": "1.0.2", + "bundled": true, + "dev": true, + "requires": { + "code-point-at": "1.1.0", + "is-fullwidth-code-point": "1.0.0", + "strip-ansi": "3.0.1" + } + } + } + } + } + }, + "yargs-parser": { + "version": "8.0.0", + "bundled": true, + "dev": true, + "requires": { + "camelcase": "4.1.0" + }, + "dependencies": { + "camelcase": { + "version": "4.1.0", + "bundled": true, + "dev": true + } + } + } + } + }, + "obj-props": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/obj-props/-/obj-props-1.1.0.tgz", + "integrity": "sha1-YmMT+qRCvv1KROmgLDy2vek3tRE=", + "dev": true + }, + "object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", + "dev": true + }, + "object-inspect": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.3.0.tgz", + "integrity": "sha512-OHHnLgLNXpM++GnJRyyhbr2bwl3pPVm4YvaraHrRvDt/N3r+s/gDVHciA7EJBTkijKXj61ssgSAikq1fb0IBRg==", + "dev": true + }, + "object-keys": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.0.11.tgz", + "integrity": "sha1-xUYBd4rVYPEULODgG8yotW0TQm0=", + "dev": true + }, + "once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "dev": true, + "requires": { + "wrappy": "1.0.2" + } + }, + "onetime": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-2.0.1.tgz", + "integrity": "sha1-BnQoIw/WdEOyeUsiu6UotoZ5YtQ=", + "dev": true, + "requires": { + "mimic-fn": "1.1.0" + } + }, + "optionator": { + "version": "0.8.2", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.2.tgz", + "integrity": "sha1-NkxeQJ0/TWMB1sC0wFu6UBgK62Q=", + "dev": true, + "requires": { + "deep-is": "0.1.3", + "fast-levenshtein": "2.0.6", + "levn": "0.3.0", + "prelude-ls": "1.1.2", + "type-check": "0.3.2", + "wordwrap": "1.0.0" + } + }, + "os-homedir": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz", + "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=", + "dev": true + }, + "os-tmpdir": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", + "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=", + "dev": true + }, + "path-exists": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-2.1.0.tgz", + "integrity": "sha1-D+tsZPD8UY2adU3V77YscCJ2H0s=", + "dev": true, + "requires": { + "pinkie-promise": "2.0.1" + } + }, + "path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", + "dev": true + }, + "path-is-inside": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz", + "integrity": "sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM=", + "dev": true + }, + "path-key": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-1.0.0.tgz", + "integrity": "sha1-XVPVeAGWRsDWiADbThRua9wqx68=", + "dev": true + }, + "path-parse": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.5.tgz", + "integrity": "sha1-PBrfhx6pzWyUMbbqK9dKD/BVxME=", + "dev": true + }, + "pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", + "dev": true + }, + "pinkie": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz", + "integrity": "sha1-clVrgM+g1IqXToDnckjoDtT3+HA=", + "dev": true + }, + "pinkie-promise": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz", + "integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=", + "dev": true, + "requires": { + "pinkie": "2.0.4" + } + }, + "pluralize": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/pluralize/-/pluralize-7.0.0.tgz", + "integrity": "sha512-ARhBOdzS3e41FbkW/XWrTEtukqqLoK5+Z/4UeDaLuSW+39JPeFgs4gCGqsrJHVZX0fUrx//4OF0K1CUGwlIFow==", + "dev": true + }, + "postcss": { + "version": "6.0.14", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.14.tgz", + "integrity": "sha512-NJ1z0f+1offCgadPhz+DvGm5Mkci+mmV5BqD13S992o0Xk9eElxUfPPF+t2ksH5R/17gz4xVK8KWocUQ5o3Rog==", + "requires": { + "chalk": "2.3.0", + "source-map": "0.6.1", + "supports-color": "4.5.0" + } + }, + "postcss-message-helpers": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/postcss-message-helpers/-/postcss-message-helpers-2.0.0.tgz", + "integrity": "sha1-pPL0+rbk/gAvCu0ABHjN9S+bpg4=" + }, + "prelude-ls": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", + "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=", + "dev": true + }, + "process-nextick-args": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-1.0.7.tgz", + "integrity": "sha1-FQ4gt1ZZCtP5EJPyWk8q2L/zC6M=", + "dev": true + }, + "progress": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.0.tgz", + "integrity": "sha1-ihvjZr+Pwj2yvSPxDG/pILQ4nR8=", + "dev": true + }, + "proto-props": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/proto-props/-/proto-props-0.2.1.tgz", + "integrity": "sha1-XgHcJnWg3pq/p255nfozTW9IP0s=", + "dev": true + }, + "pseudomap": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", + "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=", + "dev": true + }, + "readable-stream": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.3.tgz", + "integrity": "sha512-m+qzzcn7KUxEmd1gMbchF+Y2eIUbieUaxkWtptyHywrX0rE8QEYqPC07Vuy4Wm32/xE16NcdBctb8S0Xe/5IeQ==", + "dev": true, + "requires": { + "core-util-is": "1.0.2", + "inherits": "2.0.3", + "isarray": "1.0.0", + "process-nextick-args": "1.0.7", + "safe-buffer": "5.1.1", + "string_decoder": "1.0.3", + "util-deprecate": "1.0.2" + } + }, + "readjson": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/readjson/-/readjson-1.1.3.tgz", + "integrity": "sha1-y0xpFVHG5P7mZ/UcKczi9c6kWTw=", + "dev": true, + "requires": { + "try-catch": "1.0.0" + } + }, + "reduce-function-call": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/reduce-function-call/-/reduce-function-call-1.0.2.tgz", + "integrity": "sha1-WiAL+S4ON3UXUv5FsKszD9S2vpk=", + "requires": { + "balanced-match": "0.4.2" + } + }, + "require-uncached": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/require-uncached/-/require-uncached-1.0.3.tgz", + "integrity": "sha1-Tg1W1slmL9MeQwEcS5WqSZVUIdM=", + "dev": true, + "requires": { + "caller-path": "0.1.0", + "resolve-from": "1.0.1" + } + }, + "resolve": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.5.0.tgz", + "integrity": "sha512-hgoSGrc3pjzAPHNBg+KnFcK2HwlHTs/YrAGUr6qgTVUZmXv1UEXXl0bZNBKMA9fud6lRYFdPGz0xXxycPzmmiw==", + "dev": true, + "requires": { + "path-parse": "1.0.5" + } + }, + "resolve-from": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-1.0.1.tgz", + "integrity": "sha1-Jsv+k10a7uq7Kbw/5a6wHpPUQiY=", + "dev": true + }, + "restore-cursor": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-2.0.0.tgz", + "integrity": "sha1-n37ih/gv0ybU/RYpI9YhKe7g368=", + "dev": true, + "requires": { + "onetime": "2.0.1", + "signal-exit": "3.0.2" + } + }, + "resumer": { + "version": "0.0.0", + "resolved": "https://registry.npmjs.org/resumer/-/resumer-0.0.0.tgz", + "integrity": "sha1-8ej0YeQGS6Oegq883CqMiT0HZ1k=", + "dev": true, + "requires": { + "through": "2.3.8" + } + }, + "rimraf": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.2.tgz", + "integrity": "sha512-lreewLK/BlghmxtfH36YYVg1i8IAce4TI7oao75I1g245+6BctqTVQiBP3YUJ9C6DQOXJmkYR9X9fCLtCOJc5w==", + "dev": true, + "requires": { + "glob": "7.1.2" + } + }, + "run-applescript": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/run-applescript/-/run-applescript-2.1.0.tgz", + "integrity": "sha1-O/8sz5W2zqy0lyPlUPADcdYYUQ0=", + "dev": true, + "requires": { + "pify": "2.3.0", + "pinkie-promise": "2.0.1" + } + }, + "run-async": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.3.0.tgz", + "integrity": "sha1-A3GrSuC91yDUFm19/aZP96RFpsA=", + "dev": true, + "requires": { + "is-promise": "2.1.0" + } + }, + "rx-lite": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/rx-lite/-/rx-lite-4.0.8.tgz", + "integrity": "sha1-Cx4Rr4vESDbwSmQH6S2kJGe3lEQ=", + "dev": true + }, + "rx-lite-aggregates": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/rx-lite-aggregates/-/rx-lite-aggregates-4.0.8.tgz", + "integrity": "sha1-dTuHqJoRyVRnxKwWJsTvxOBcZ74=", + "dev": true, + "requires": { + "rx-lite": "4.0.8" + } + }, + "safe-buffer": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.1.tgz", + "integrity": "sha512-kKvNJn6Mm93gAczWVJg7wH+wGYWNrDHdWvpUmHyEsgCtIwwo3bqPtV4tR5tuPaUhTOo/kvhVwd8XwwOllGYkbg==", + "dev": true + }, + "semver": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.3.0.tgz", + "integrity": "sha1-myzl094C0XxgEq0yaqa00M9U+U8=", + "dev": true + }, + "shebang-command": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", + "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=", + "dev": true, + "requires": { + "shebang-regex": "1.0.0" + } + }, + "shebang-regex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", + "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=", + "dev": true + }, + "shelljs": { + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/shelljs/-/shelljs-0.5.3.tgz", + "integrity": "sha1-xUmCuZbHbvDB5rWfvcWCX1txMRM=", + "dev": true + }, + "signal-exit": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz", + "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=", + "dev": true + }, + "simple-swizzle": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/simple-swizzle/-/simple-swizzle-0.2.2.tgz", + "integrity": "sha1-pNprY1/8zMoz9w0Xy5JZLeleVXo=", + "requires": { + "is-arrayish": "0.3.1" + } + }, + "slice-ansi": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-1.0.0.tgz", + "integrity": "sha512-POqxBK6Lb3q6s047D/XsDVNPnF9Dl8JSaqe9h9lURl0OdNqy/ujDrOiIHtsqXMGbWWTIomRzAMaTyawAU//Reg==", + "dev": true, + "requires": { + "is-fullwidth-code-point": "2.0.0" + } + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" + }, + "sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", + "dev": true + }, + "stream-consume": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/stream-consume/-/stream-consume-0.1.0.tgz", + "integrity": "sha1-pB6tGm1ggc63n2WwYZAbbY89HQ8=", + "dev": true + }, + "string-width": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", + "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", + "dev": true, + "requires": { + "is-fullwidth-code-point": "2.0.0", + "strip-ansi": "4.0.0" + } + }, + "string.prototype.trim": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.1.2.tgz", + "integrity": "sha1-0E3iyJ4Tf019IG8Ia17S+ua+jOo=", + "dev": true, + "requires": { + "define-properties": "1.1.2", + "es-abstract": "1.10.0", + "function-bind": "1.1.1" + } + }, + "string_decoder": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz", + "integrity": "sha512-4AH6Z5fzNNBcH+6XDMfA/BTt87skxqJlO0lAh3Dker5zThcAxG6mKz+iGu308UKoPPQ8Dcqx/4JhujzltRa+hQ==", + "dev": true, + "requires": { + "safe-buffer": "5.1.1" + } + }, + "strip-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", + "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", + "dev": true, + "requires": { + "ansi-regex": "3.0.0" + }, + "dependencies": { + "ansi-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", + "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", + "dev": true + } + } + }, + "strip-eof": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz", + "integrity": "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8=", + "dev": true + }, + "strip-json-comments": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", + "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=", + "dev": true + }, + "supports-color": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.5.0.tgz", + "integrity": "sha1-vnoN5ITexcXN34s9WRJQRJEvY1s=", + "requires": { + "has-flag": "2.0.0" + } + }, + "table": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/table/-/table-4.0.2.tgz", + "integrity": "sha512-UUkEAPdSGxtRpiV9ozJ5cMTtYiqz7Ni1OGqLXRCynrvzdtR1p+cfOWe2RJLwvUG8hNanaSRjecIqwOjqeatDsA==", + "dev": true, + "requires": { + "ajv": "5.5.1", + "ajv-keywords": "2.1.1", + "chalk": "2.3.0", + "lodash": "4.17.4", + "slice-ansi": "1.0.0", + "string-width": "2.1.1" + } + }, + "tape": { + "version": "4.8.0", + "resolved": "https://registry.npmjs.org/tape/-/tape-4.8.0.tgz", + "integrity": "sha512-TWILfEnvO7I8mFe35d98F6T5fbLaEtbFTG/lxWvid8qDfFTxt19EBijWmB4j3+Hoh5TfHE2faWs73ua+EphuBA==", + "dev": true, + "requires": { + "deep-equal": "1.0.1", + "defined": "1.0.0", + "for-each": "0.3.2", + "function-bind": "1.1.1", + "glob": "7.1.2", + "has": "1.0.1", + "inherits": "2.0.3", + "minimist": "1.2.0", + "object-inspect": "1.3.0", + "resolve": "1.4.0", + "resumer": "0.0.0", + "string.prototype.trim": "1.1.2", + "through": "2.3.8" + }, + "dependencies": { + "minimist": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", + "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", + "dev": true + }, + "resolve": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.4.0.tgz", + "integrity": "sha512-aW7sVKPufyHqOmyyLzg/J+8606v5nevBgaliIlV7nUpVMsDnoBGV/cbSLNjZAg9q0Cfd/+easKVKQ8vOu8fn1Q==", + "dev": true, + "requires": { + "path-parse": "1.0.5" + } + } + } + }, + "text-table": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", + "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=", + "dev": true + }, + "through": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", + "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=", + "dev": true + }, + "tmp": { + "version": "0.0.33", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", + "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", + "dev": true, + "requires": { + "os-tmpdir": "1.0.2" + } + }, + "trash": { + "version": "3.4.2", + "resolved": "https://registry.npmjs.org/trash/-/trash-3.4.2.tgz", + "integrity": "sha1-+wQiUvwmoCInaVCiuw7Om5QF6xk=", + "dev": true, + "requires": { + "escape-string-applescript": "1.0.0", + "fs-extra": "0.26.7", + "globby": "4.1.0", + "path-exists": "2.1.0", + "pify": "2.3.0", + "pinkie-promise": "2.0.1", + "run-applescript": "2.1.0", + "uuid": "2.0.3", + "xdg-trashdir": "2.1.1" + }, + "dependencies": { + "glob": { + "version": "6.0.4", + "resolved": "https://registry.npmjs.org/glob/-/glob-6.0.4.tgz", + "integrity": "sha1-DwiGD2oVUSey+t1PnOJLGqtuTSI=", + "dev": true, + "requires": { + "inflight": "1.0.6", + "inherits": "2.0.3", + "minimatch": "3.0.4", + "once": "1.4.0", + "path-is-absolute": "1.0.1" + } + }, + "globby": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-4.1.0.tgz", + "integrity": "sha1-CA9UVJ7BuCpsYOYx/ILhIR2+lfg=", + "dev": true, + "requires": { + "array-union": "1.0.2", + "arrify": "1.0.1", + "glob": "6.0.4", + "object-assign": "4.1.1", + "pify": "2.3.0", + "pinkie-promise": "2.0.1" + } + } + } + }, + "try-catch": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/try-catch/-/try-catch-1.0.0.tgz", + "integrity": "sha1-N5fas5omZ3X00Npcv0Kso/A2COY=", + "dev": true + }, + "type-check": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", + "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=", + "dev": true, + "requires": { + "prelude-ls": "1.1.2" + } + }, + "typedarray": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", + "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=", + "dev": true + }, + "user-home": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/user-home/-/user-home-2.0.0.tgz", + "integrity": "sha1-nHC/2Babwdy/SGBODwS4tJzenp8=", + "dev": true, + "requires": { + "os-homedir": "1.0.2" + } + }, + "util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=", + "dev": true + }, + "uuid": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-2.0.3.tgz", + "integrity": "sha1-Z+LoY3lyFVMN/zGOW/nc6/1Hsho=", + "dev": true + }, + "which": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.0.tgz", + "integrity": "sha512-xcJpopdamTuY5duC/KnTTNBraPK54YwpenP4lzxU8H91GudWpFv38u0CKjclE1Wi2EH2EDz5LRcHcKbCIzqGyg==", + "dev": true, + "requires": { + "isexe": "2.0.0" + } + }, + "wordwrap": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", + "integrity": "sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus=", + "dev": true + }, + "wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", + "dev": true + }, + "write": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/write/-/write-0.2.1.tgz", + "integrity": "sha1-X8A4KOJkzqP+kUVUdvejxWbLB1c=", + "dev": true, + "requires": { + "mkdirp": "0.5.1" + } + }, + "xdg-basedir": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/xdg-basedir/-/xdg-basedir-2.0.0.tgz", + "integrity": "sha1-7byQPMOF/ARSPZZqM1UEtVBNG9I=", + "dev": true, + "requires": { + "os-homedir": "1.0.2" + } + }, + "xdg-trashdir": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/xdg-trashdir/-/xdg-trashdir-2.1.1.tgz", + "integrity": "sha512-KcVhPaOu2ZurYNHSRTf1+ZHORkTZGCQ+u0JHN17QixRISJq4pXOnjt/lQcehvtHL5QAKhSzKgyjrcNnPdkPBHA==", + "dev": true, + "requires": { + "@sindresorhus/df": "2.1.0", + "mount-point": "3.0.0", + "pify": "2.3.0", + "user-home": "2.0.0", + "xdg-basedir": "2.0.0" + } + }, + "yallist": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", + "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=", + "dev": true + } + } +} diff --git a/package.json b/package.json index ae2e205397..049df2338e 100644 --- a/package.json +++ b/package.json @@ -1,53 +1,44 @@ { - "name": "postcss-color-gray", - "version": "4.0.0", - "description": "PostCSS plugin to transform gray() function to today's CSS", - "repository": "https://github.com/postcss/postcss-color-gray.git", - "author": { - "name": "Shinnosuke Watanabe", - "url": "https://github.com/shinnn" - }, - "scripts": { - "pretest": "npm run eslint", - "eslint": "eslint index.js test.js", - "jscs": "jscs index.js test.js", - "test": "node test.js | tap-spec", - "coverage": "istanbul cover test.js", - "coveralls": "${npm_package_scripts_coverage} && istanbul-coveralls", - "release": "npmpub" - }, - "licenses": [ - { - "type": "MIT", - "url": "https://github.com/postcss/postcss-color-gray/blob/master/LICENSE" - } - ], - "files": [ - "index.js" - ], - "keywords": [ - "css", - "css4", - "style", - "stylesheet", - "postcss", - "postcss-plugin", - "color", - "gray", - "function" - ], - "dependencies": { - "color": "^1.0.3", - "postcss": "^6.0.1", - "postcss-message-helpers": "^2.0.0", - "reduce-function-call": "^1.0.2" - }, - "devDependencies": { - "eslint": "^3.19.0", - "istanbul": "^0.4.5", - "istanbul-coveralls": "^1.0.3", - "npmpub": "^3.1.0", - "tap-spec": "^4.1.1", - "tape": "^4.6.3" - } + "name": "postcss-color-gray", + "version": "4.0.0", + "description": "PostCSS plugin to transform gray() function to today's CSS", + "repository": "postcss/postcss-color-gray", + "author": "Shinnosuke Watanabe (https://github.com/shinnn)", + "scripts": { + "pretest": "eslint --fix --format=codeframe index.js test.js", + "test": "nyc --reporter=text --reporter=html node test.js", + "release": "npmpub" + }, + "license": "MIT", + "files": [ + "index.js" + ], + "keywords": [ + "css", + "css4", + "style", + "stylesheet", + "postcss", + "postcss-plugin", + "color", + "convert", + "gray", + "function" + ], + "dependencies": { + "color": "^2.0.1", + "postcss": "^6.0.14", + "postcss-message-helpers": "^2.0.0", + "reduce-function-call": "^1.0.2" + }, + "devDependencies": { + "@shinnn/eslint-config-node": "^5.0.0", + "eslint": "^4.13.1", + "npmpub": "^3.1.0", + "nyc": "^11.4.0", + "tape": "^4.8.0" + }, + "eslintConfig": { + "extends": "@shinnn/node" + } } diff --git a/test.js b/test.js old mode 100755 new mode 100644 index 9dc53483a8..c92dfd853b --- a/test.js +++ b/test.js @@ -1,71 +1,61 @@ 'use strict'; -var postcss = require('postcss'); -var colorGray = require('./'); -var test = require('tape'); +const postcss = require('postcss'); +const colorGray = require('.'); +const test = require('tape'); function useGray() { - return postcss().use(colorGray()); + return postcss().use(colorGray()); } -test('filterDeclarations()', function(t) { - t.plan(8); - - t.equal( - useGray().process('a {color: gray(200); background: gray(00000034%)}').css, - 'a {color: rgb(200, 200, 200); background: rgb(87, 87, 87)}', - 'should convert gray(A) to rgb(A,A,A).' - ); - - t.equal( - useGray().process('a {color: gray( 1, 4.5%)}; b {color: gray(030%,0.75 \t)}').css, - 'a {color: rgba(1, 1, 1, 0.045)}; b {color: rgba(77, 77, 77, 0.75)}', - 'should convert gray(A,B) to rgba(A,A,A,B).' - ); - - t.equal( - useGray().process('a {border-color: gray;}').css, - 'a {border-color: gray;}', - 'should not modify original CSS when gray() is not used.' - ); - - t.throws( - function() { - return useGray().process('a {color: gray()}').css; - }, - /Unable to parse color from string "gray\(\)"/, - 'should throw an error when gray() doesn\'t take any arguments.' - ); - - t.throws( - function() { - return useGray().process('a {color: gray(,foo)}').css; - }, - /:1:4: Unable to parse color from string "gray\(,foo\)"/, - 'should throw an error when gray() args start with a comma.' - ); - - t.throws( - function() { - return useGray().process('a {color: gray(foo,)}').css; - }, - /:1:4: Unable to parse color from string "gray\(foo,\)"/, - 'should throw an error when gray() args end with a comma.' - ); - - t.throws( - function() { - return useGray().process('a {color: gray(red)}', {from: 'fixture.css'}).css; - }, - /fixture\.css:1:4: Unable to parse color from string "gray\(red\)"/, - 'should throw a detailed error when a source file is specified.' - ); - - t.throws( - function() { - return useGray().process('a {color: gray(,)}', {map: true}).css; - }, - /:1:4: Unable to parse color from string "gray\(,\)"/, - 'should throw a detailed error when source map is enabled but file isn\'t specified.' - ); +test('postCssColorGray()', t => { + t.equal( + useGray().process('a {color: gray(200); background: gray(00000034%)}').css, + 'a {color: rgb(200, 200, 200); background: rgb(87, 87, 87)}', + 'should convert gray(A) to rgb(A,A,A).' + ); + + t.equal( + useGray().process('a {color: gray( 1, 4.5%)}; b {color: gray(030%,0.75 \t)}').css, + 'a {color: rgba(1, 1, 1, 0.045)}; b {color: rgba(77, 77, 77, 0.75)}', + 'should convert gray(A,B) to rgba(A,A,A,B).' + ); + + t.equal( + useGray().process('a {border-color: gray;}').css, + 'a {border-color: gray;}', + 'should not modify original CSS when gray() is not used.' + ); + + t.throws( + () => useGray().process('a {color: gray()}').css, + /Unable to parse color from string "gray\(\)"/, + 'should throw an error when gray() doesn\'t take any arguments.' + ); + + t.throws( + () => useGray().process('a {color: gray(,foo)}').css, + /:1:4: Unable to parse color from string "gray\(,foo\)"/, + 'should throw an error when gray() args start with a comma.' + ); + + t.throws( + () => useGray().process('a {color: gray(foo,)}').css, + /:1:4: Unable to parse color from string "gray\(foo,\)"/, + 'should throw an error when gray() args end with a comma.' + ); + + t.throws( + () => useGray().process('a {color: gray(red)}', {from: 'fixture.css'}).css, + /fixture\.css:1:4: Unable to parse color from string "gray\(red\)"/, + 'should throw a detailed error when a source file is specified.' + ); + + t.throws( + () => useGray().process('a {color: gray(,)}', {map: true}).css, + /:1:4: Unable to parse color from string "gray\(,\)"/, + 'should throw a detailed error when source map is enabled but file isn\'t specified.' + ); + + t.end(); }); From b263554af1fe90472d9f6ebbe29238b8ee86070d Mon Sep 17 00:00:00 2001 From: Shinnosuke Watanabe Date: Wed, 13 Dec 2017 19:53:00 +0900 Subject: [PATCH 545/795] stop testing on AppVeyor MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Because this plugin doesn’t contain any platform-specific code --- README.md | 3 --- appveyor.yml | 9 --------- 2 files changed, 12 deletions(-) delete mode 100644 appveyor.yml diff --git a/README.md b/README.md index c32945e17e..2234f8745e 100755 --- a/README.md +++ b/README.md @@ -2,10 +2,7 @@ [![CSS Standard Status](https://jonathantneal.github.io/css-db/badge/css-color-grays.svg)](https://jonathantneal.github.io/css-db/#css-color-grays) [![Build Status](https://travis-ci.org/postcss/postcss-color-gray.svg?branch=master)](https://travis-ci.org/postcss/postcss-color-gray) -[![Build status](https://ci.appveyor.com/api/projects/status/190t5i4f23r49345?svg=true)](https://ci.appveyor.com/project/ShinnosukeWatanabe/postcss-color-gray) [![Coverage Status](https://img.shields.io/coveralls/postcss/postcss-color-gray.svg)](https://coveralls.io/r/postcss/postcss-color-gray) -[![Dependency Status](https://david-dm.org/postcss/postcss-color-gray.svg)](https://david-dm.org/postcss/postcss-color-gray) -[![devDependency Status](https://david-dm.org/postcss/postcss-color-gray/dev-status.svg)](https://david-dm.org/postcss/postcss-color-gray#info=devDependencies) [PostCSS](https://github.com/postcss/postcss) plugin to transform [gray()](http://dev.w3.org/csswg/css-color/#grays) function to today's CSS diff --git a/appveyor.yml b/appveyor.yml deleted file mode 100644 index 551069ccd4..0000000000 --- a/appveyor.yml +++ /dev/null @@ -1,9 +0,0 @@ -environment: - matrix: - - nodejs_version: '4' - - nodejs_version: '6' -install: - - ps: Install-Product node $env:nodejs_version - - npm install -build: off -test_script: node test.js From 065e6c8bebd250be89b369c4fffffe931ec8a495 Mon Sep 17 00:00:00 2001 From: Shinnosuke Watanabe Date: Wed, 13 Dec 2017 19:59:00 +0900 Subject: [PATCH 546/795] test on the latest Node.js --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 6dcb13b81c..414a7e6600 100644 --- a/.travis.yml +++ b/.travis.yml @@ -3,5 +3,5 @@ branches: language: node_js node_js: - '4' - - '6' after_script: node_modules/.bin/nyc report --reporter=text-lcov | npx coveralls + - node From 363313d5abf3bae48ff56eeccfdd11e7d11e7c1a Mon Sep 17 00:00:00 2001 From: Shinnosuke Watanabe Date: Wed, 13 Dec 2017 19:59:54 +0900 Subject: [PATCH 547/795] run code linter and coverage reporter only with the latest Node.js --- .travis.yml | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 414a7e6600..d0134fae41 100644 --- a/.travis.yml +++ b/.travis.yml @@ -3,5 +3,11 @@ branches: language: node_js node_js: - '4' -after_script: node_modules/.bin/nyc report --reporter=text-lcov | npx coveralls - node +script: if [[ `node --version` != v4.* ]]; + then npm test; + else node test.js; + fi; +after_script: if [[ `node --version` != v4.* ]]; + then node_modules/.bin/nyc report --reporter=text-lcov | npx coveralls; + fi; From 1f7a63d6863e06275ee46e752a897b150bebe5d5 Mon Sep 17 00:00:00 2001 From: Shinnosuke Watanabe Date: Wed, 13 Dec 2017 20:25:50 +0900 Subject: [PATCH 548/795] switch from MIT license to ISC license https://opensource.org/licenses/ISC --- LICENSE | 22 ++++------------------ README.md | 4 +--- package.json | 2 +- 3 files changed, 6 insertions(+), 22 deletions(-) mode change 100755 => 100644 LICENSE mode change 100755 => 100644 README.md diff --git a/LICENSE b/LICENSE old mode 100755 new mode 100644 index 0b0cb16d89..cd1b1332d2 --- a/LICENSE +++ b/LICENSE @@ -1,20 +1,6 @@ -The MIT License (MIT) +ISC License (ISC) +Copyright 2017 Shinnosuke Watanabe -Copyright (c) 2017 Shinnosuke Watanabe +Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted, provided that the above copyright notice and this permission notice appear in all copies. -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. +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. diff --git a/README.md b/README.md old mode 100755 new mode 100644 index 2234f8745e..c0919f93f5 --- a/README.md +++ b/README.md @@ -73,6 +73,4 @@ postcss() ## License -Copyright (c) 2017 [Shinnosuke Watanabe](https://github.com/shinnn) - -Licensed under [the MIT License](./LICENSE). +[ISC License](./LICENSE) © 2017 Shinnosuke Watanabe diff --git a/package.json b/package.json index 049df2338e..bedb083708 100644 --- a/package.json +++ b/package.json @@ -9,7 +9,7 @@ "test": "nyc --reporter=text --reporter=html node test.js", "release": "npmpub" }, - "license": "MIT", + "license": "ISC", "files": [ "index.js" ], From f143771be342b252b612a793b543d0063a648aaf Mon Sep 17 00:00:00 2001 From: Shinnosuke Watanabe Date: Tue, 19 Dec 2017 14:17:46 +0900 Subject: [PATCH 549/795] 4.1.0 --- CHANGELOG.md | 9 +++++++-- package-lock.json | 30 +++++++++++++++--------------- package.json | 4 ++-- 3 files changed, 24 insertions(+), 19 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 34de8f031b..3c06b6a5b0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,8 @@ +# 4.1.0 - 2017-12-19 + +- Changed: relicense ([MIT](https://opensource.org/licenses/MIT) → [ISC](https://opensource.org/licenses/ISC)) +- Updated dependencies + # 4.0.0 - 2017-05-15 - Added: compatibility with postcss v6.x @@ -11,12 +16,12 @@ # 3.0.0 - 2015-09-08 - Added: compatibility with postcss v5.x -- Removed: compatiblity with postcss v4.x +- Removed: compatibility with postcss v4.x # 2.0.0 - 2015-01-26 - Added: compatibility with postcss v4.x -- Removed: compatiblity with postcss v3.x +- Removed: compatibility with postcss v3.x # 1.1.0 - 2014-11-25 diff --git a/package-lock.json b/package-lock.json index e1f3dad17a..0cdf775e6d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "postcss-color-gray", - "version": "4.0.0", + "version": "4.1.0", "lockfileVersion": 1, "requires": true, "dependencies": { @@ -74,9 +74,9 @@ } }, "ajv": { - "version": "5.5.1", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-5.5.1.tgz", - "integrity": "sha1-s4u4h22ehr7plJVqBOch6IskjrI=", + "version": "5.5.2", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-5.5.2.tgz", + "integrity": "sha1-c7Xuyj+rZT49P5Qis0GtQiBdyWU=", "dev": true, "requires": { "co": "4.6.0", @@ -452,7 +452,7 @@ "integrity": "sha512-UCJVV50RtLHYzBp1DZ8CMPtRSg4iVZvjgO9IJHIKyWU/AnJVjtdRikoUPLB29n5pzMB7TnsLQWf0V6VUJfoPfw==", "dev": true, "requires": { - "ajv": "5.5.1", + "ajv": "5.5.2", "babel-code-frame": "6.26.0", "chalk": "2.3.0", "concat-stream": "1.6.0", @@ -1283,9 +1283,9 @@ } }, "nyc": { - "version": "11.4.0", - "resolved": "https://registry.npmjs.org/nyc/-/nyc-11.4.0.tgz", - "integrity": "sha512-4Due4ssNvAog/Sz3LpPpaFTV5pdHWRU+z5UcENwthSn079tY6UcQnF4h2q/TaTH3WuNmhiXsaRWbNeFSmH2JhA==", + "version": "11.4.1", + "resolved": "https://registry.npmjs.org/nyc/-/nyc-11.4.1.tgz", + "integrity": "sha512-5eCZpvaksFVjP2rt1r60cfXmt3MUtsQDw8bAzNqNEr4WLvUMLgiVENMf/B9bE9YAX0mGVvaGA3v9IS9ekNqB1Q==", "dev": true, "requires": { "archy": "1.0.0", @@ -1311,7 +1311,7 @@ "resolve-from": "2.0.0", "rimraf": "2.6.2", "signal-exit": "3.0.2", - "spawn-wrap": "1.4.1", + "spawn-wrap": "1.4.2", "test-exclude": "4.1.1", "yargs": "10.0.3", "yargs-parser": "8.0.0" @@ -1421,8 +1421,8 @@ "bundled": true, "dev": true, "requires": { - "core-js": "2.5.1", - "regenerator-runtime": "0.11.0" + "core-js": "2.5.3", + "regenerator-runtime": "0.11.1" } }, "babel-template": { @@ -1576,7 +1576,7 @@ "dev": true }, "core-js": { - "version": "2.5.1", + "version": "2.5.3", "bundled": true, "dev": true }, @@ -2493,7 +2493,7 @@ } }, "regenerator-runtime": { - "version": "0.11.0", + "version": "0.11.1", "bundled": true, "dev": true }, @@ -2599,7 +2599,7 @@ "dev": true }, "spawn-wrap": { - "version": "1.4.1", + "version": "1.4.2", "bundled": true, "dev": true, "requires": { @@ -3314,7 +3314,7 @@ "integrity": "sha512-UUkEAPdSGxtRpiV9ozJ5cMTtYiqz7Ni1OGqLXRCynrvzdtR1p+cfOWe2RJLwvUG8hNanaSRjecIqwOjqeatDsA==", "dev": true, "requires": { - "ajv": "5.5.1", + "ajv": "5.5.2", "ajv-keywords": "2.1.1", "chalk": "2.3.0", "lodash": "4.17.4", diff --git a/package.json b/package.json index bedb083708..1fbebaf519 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "postcss-color-gray", - "version": "4.0.0", + "version": "4.1.0", "description": "PostCSS plugin to transform gray() function to today's CSS", "repository": "postcss/postcss-color-gray", "author": "Shinnosuke Watanabe (https://github.com/shinnn)", @@ -35,7 +35,7 @@ "@shinnn/eslint-config-node": "^5.0.0", "eslint": "^4.13.1", "npmpub": "^3.1.0", - "nyc": "^11.4.0", + "nyc": "^11.4.1", "tape": "^4.8.0" }, "eslintConfig": { From 604e99ae76f2df8d24428cbcde0885c386eaf7c5 Mon Sep 17 00:00:00 2001 From: Jonathan Neal Date: Tue, 16 Jan 2018 15:19:39 -0500 Subject: [PATCH 550/795] 1.0.0 --- .appveyor.yml | 18 + .editorconfig | 15 + .gitignore | 12 + .rollup.js | 13 + .tape.js | 21 ++ .travis.yml | 9 + CHANGELOG.md | 5 + CONTRIBUTING.md | 65 ++++ LICENSE.md | 108 ++++++ README.md | 199 +++++++++++ index.js | 30 ++ lib/color.js | 553 +++++++++++++++++++++++++++++ lib/manage-unresolved.js | 7 + lib/transform.js | 663 +++++++++++++++++++++++++++++++++++ package.json | 78 +++++ test/basic.colors.expect.css | 96 +++++ test/basic.css | 96 +++++ test/basic.expect.css | 96 +++++ test/warn.css | 48 +++ 19 files changed, 2132 insertions(+) create mode 100644 .appveyor.yml create mode 100644 .editorconfig create mode 100644 .gitignore create mode 100644 .rollup.js create mode 100644 .tape.js create mode 100644 .travis.yml create mode 100644 CHANGELOG.md create mode 100644 CONTRIBUTING.md create mode 100644 LICENSE.md create mode 100644 README.md create mode 100644 index.js create mode 100644 lib/color.js create mode 100644 lib/manage-unresolved.js create mode 100644 lib/transform.js create mode 100644 package.json create mode 100644 test/basic.colors.expect.css create mode 100644 test/basic.css create mode 100644 test/basic.expect.css create mode 100644 test/warn.css diff --git a/.appveyor.yml b/.appveyor.yml new file mode 100644 index 0000000000..d6b511f500 --- /dev/null +++ b/.appveyor.yml @@ -0,0 +1,18 @@ +# https://www.appveyor.com/docs/appveyor-yml + +environment: + matrix: + - nodejs_version: 4.0 + +version: "{build}" +build: off +deploy: off + +install: + - ps: Install-Product node $env:nodejs_version + - npm install --ignore-scripts + +test_script: + - node --version + - npm --version + - cmd: "npm test" diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000000..e06d7982bc --- /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/.gitignore b/.gitignore new file mode 100644 index 0000000000..6832ce87db --- /dev/null +++ b/.gitignore @@ -0,0 +1,12 @@ +node_modules +index.bundle.js +package-lock.json +*.log* +*.result.css +.* +!.appveyor.yml +!.editorconfig +!.gitignore +!.rollup.js +!.tape.js +!.travis.yml diff --git a/.rollup.js b/.rollup.js new file mode 100644 index 0000000000..7f4e231750 --- /dev/null +++ b/.rollup.js @@ -0,0 +1,13 @@ +import babel from 'rollup-plugin-babel'; + +export default { + input: 'index.js', + output: { file: 'index.bundle.js', format: 'cjs' }, + plugins: [ + babel({ + presets: [ + ['env', { modules: false, targets: { node: 4 } }] + ] + }) + ] +}; diff --git a/.tape.js b/.tape.js new file mode 100644 index 0000000000..2b03327db7 --- /dev/null +++ b/.tape.js @@ -0,0 +1,21 @@ +module.exports = { + 'postcss-color-mod-function': { + 'basic': { + message: 'supports basic usage' + }, + 'basic:colors': { + message: 'supports { stringifier } usage', + options: { + stringifier: color => color.toString() + } + }, + 'warn': { + message: 'supports { unresolved } usage', + options: { + unresolved: 'warn' + }, + warning: 43, + expect: 'warn.css' + } + } +}; diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000000..c56466446c --- /dev/null +++ b/.travis.yml @@ -0,0 +1,9 @@ +# https://docs.travis-ci.com/user/travis-lint + +language: node_js + +node_js: + - 4 + +install: + - npm install --ignore-scripts diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000000..c609a5682a --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,5 @@ +# Changes to PostCSS color-mod() Function + +### 1.0.0 (January 16, 2018) + +- Initial version diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 0000000000..1a88ff75f5 --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,65 @@ +# Contributing to PostCSS color-mod() Function + +You want to help? You rock! Now, take a moment to be sure your contributions +make sense to everyone else. + +## Reporting Issues + +Found a problem? Want a new feature? + +- See if your issue or idea has [already been reported]. +- Provide a [reduced test case] or a [live example]. + +Remember, a bug is a _demonstrable problem_ caused by _our_ code. + +## Submitting Pull Requests + +Pull requests are the greatest contributions, so be sure they are focused in +scope and avoid unrelated commits. + +1. To begin; [fork this project], clone your fork, and add our upstream. + ```bash + # Clone your fork of the repo into the current directory + git clone git@github.com:YOUR_USER/postcss-color-mod-function.git + + # Navigate to the newly cloned directory + cd postcss-color-mod-function + + # Assign the original repo to a remote called "upstream" + git remote add upstream git@github.com:jonathantneal/postcss-color-mod-function.git + + # Install the tools necessary for testing + npm install + ``` + +2. Create a branch for your feature or fix: + ```bash + # Move into a new branch for your feature + git checkout -b feature/thing + ``` + ```bash + # Move into a new branch for your fix + git checkout -b fix/something + ``` + +3. If your code follows our practices, then push your feature branch: + ```bash + # Test current code + npm test + ``` + ```bash + # Push the branch for your new feature + git push origin feature/thing + ``` + ```bash + # Or, push the branch for your update + git push origin update/something + ``` + +That’s it! Now [open a pull request] with a clear title and description. + +[already been reported]: issues +[fork this project]: fork +[live example]: https://codepen.io/pen +[open a pull request]: https://help.github.com/articles/using-pull-requests/ +[reduced test case]: https://css-tricks.com/reduced-test-cases/ diff --git a/LICENSE.md b/LICENSE.md new file mode 100644 index 0000000000..0bc1fa7060 --- /dev/null +++ b/LICENSE.md @@ -0,0 +1,108 @@ +# CC0 1.0 Universal + +## Statement of Purpose + +The laws of most jurisdictions throughout the world automatically confer +exclusive Copyright and Related Rights (defined below) upon the creator and +subsequent owner(s) (each and all, an “owner”) of an original work of +authorship and/or a database (each, a “Work”). + +Certain owners wish to permanently relinquish those rights to a Work for the +purpose of contributing to a commons of creative, cultural and scientific works +(“Commons”) that the public can reliably and without fear of later claims of +infringement build upon, modify, incorporate in other works, reuse and +redistribute as freely as possible in any form whatsoever and for any purposes, +including without limitation commercial purposes. These owners may contribute +to the Commons to promote the ideal of a free culture and the further +production of creative, cultural and scientific works, or to gain reputation or +greater distribution for their Work in part through the use and efforts of +others. + +For these and/or other purposes and motivations, and without any expectation of +additional consideration or compensation, the person associating CC0 with a +Work (the “Affirmer”), to the extent that he or she is an owner of Copyright +and Related Rights in the Work, voluntarily elects to apply CC0 to the Work and +publicly distribute the Work under its terms, with knowledge of his or her +Copyright and Related Rights in the Work and the meaning and intended legal +effect of CC0 on those rights. + +1. Copyright and Related Rights. A Work made available under CC0 may be + protected by copyright and related or neighboring rights (“Copyright and + Related Rights”). Copyright and Related Rights include, but are not limited + to, the following: + 1. the right to reproduce, adapt, distribute, perform, display, communicate, + and translate a Work; + 2. moral rights retained by the original author(s) and/or performer(s); + 3. publicity and privacy rights pertaining to a person’s image or likeness + depicted in a Work; + 4. rights protecting against unfair competition in regards to a Work, + subject to the limitations in paragraph 4(i), below; + 5. rights protecting the extraction, dissemination, use and reuse of data in + a Work; + 6. database rights (such as those arising under Directive 96/9/EC of the + European Parliament and of the Council of 11 March 1996 on the legal + protection of databases, and under any national implementation thereof, + including any amended or successor version of such directive); and + 7. other similar, equivalent or corresponding rights throughout the world + based on applicable law or treaty, and any national implementations + thereof. + +2. Waiver. To the greatest extent permitted by, but not in contravention of, + applicable law, Affirmer hereby overtly, fully, permanently, irrevocably and + unconditionally waives, abandons, and surrenders all of Affirmer’s Copyright + and Related Rights and associated claims and causes of action, whether now + known or unknown (including existing as well as future claims and causes of + action), in the Work (i) in all territories worldwide, (ii) for the maximum + duration provided by applicable law or treaty (including future time + extensions), (iii) in any current or future medium and for any number of + copies, and (iv) for any purpose whatsoever, including without limitation + commercial, advertising or promotional purposes (the “Waiver”). Affirmer + makes the Waiver for the benefit of each member of the public at large and + to the detriment of Affirmer’s heirs and successors, fully intending that + such Waiver shall not be subject to revocation, rescission, cancellation, + termination, or any other legal or equitable action to disrupt the quiet + enjoyment of the Work by the public as contemplated by Affirmer’s express + Statement of Purpose. + +3. Public License Fallback. Should any part of the Waiver for any reason be + judged legally invalid or ineffective under applicable law, then the Waiver + shall be preserved to the maximum extent permitted taking into account + Affirmer’s express Statement of Purpose. In addition, to the extent the + Waiver is so judged Affirmer hereby grants to each affected person a + royalty-free, non transferable, non sublicensable, non exclusive, + irrevocable and unconditional license to exercise Affirmer’s Copyright and + Related Rights in the Work (i) in all territories worldwide, (ii) for the + maximum duration provided by applicable law or treaty (including future time + extensions), (iii) in any current or future medium and for any number of + copies, and (iv) for any purpose whatsoever, including without limitation + commercial, advertising or promotional purposes (the “License”). The License + shall be deemed effective as of the date CC0 was applied by Affirmer to the + Work. Should any part of the License for any reason be judged legally + invalid or ineffective under applicable law, such partial invalidity or + ineffectiveness shall not invalidate the remainder of the License, and in + such case Affirmer hereby affirms that he or she will not (i) exercise any + of his or her remaining Copyright and Related Rights in the Work or (ii) + assert any associated claims and causes of action with respect to the Work, + in either case contrary to Affirmer’s express Statement of Purpose. + +4. Limitations and Disclaimers. + 1. No trademark or patent rights held by Affirmer are waived, abandoned, + surrendered, licensed or otherwise affected by this document. + 2. Affirmer offers the Work as-is and makes no representations or warranties + of any kind concerning the Work, express, implied, statutory or + otherwise, including without limitation warranties of title, + merchantability, fitness for a particular purpose, non infringement, or + the absence of latent or other defects, accuracy, or the present or + absence of errors, whether or not discoverable, all to the greatest + extent permissible under applicable law. + 3. Affirmer disclaims responsibility for clearing rights of other persons + that may apply to the Work or any use thereof, including without + limitation any person’s Copyright and Related Rights in the Work. + Further, Affirmer disclaims responsibility for obtaining any necessary + consents, permissions or other rights required for any use of the Work. + 4. Affirmer understands and acknowledges that Creative Commons is not a + party to this document and has no duty or obligation with respect to this + CC0 or use of the Work. + +For more information, please see +http://creativecommons.org/publicdomain/zero/1.0/. diff --git a/README.md b/README.md new file mode 100644 index 0000000000..43f58bb9b8 --- /dev/null +++ b/README.md @@ -0,0 +1,199 @@ +# PostCSS color-mod() Function [PostCSS Logo][postcss] + +[![NPM Version][npm-img]][npm-url] +[![Linux Build Status][cli-img]][cli-url] +[![Windows Build Status][win-img]][win-url] +[![Gitter Chat][git-img]][git-url] + +[PostCSS color-mod() Function] lets you modify colors using the `color-mod()` +function in CSS, following the [CSS Color Module Level 4] specification. + +```css +:root { + --brand-red: color-mod(yellow blend(red 50%)); + --brand-red-hsl: color-mod(yellow blend(red 50% hsl)); + --brand-red-hwb: color-mod(yellow blend(red 50% hwb)); + --brand-red-dark: color-mod(red blackness(20%)); +} + +/* becomes */ + +:root { + --brand-red: rgb(255, 127.5, 0); + --brand-red-hsl: rgb(255, 127.5, 255); + --brand-red-hwb: rgb(255, 127.5, 0); + --brand-red-dark: rgb(204, 0, 0); +} + +/* or, using stringifier(color) { return color.toString() } */ + +:root { + --brand-red: rgb(100% 50% 0% / 100%); + --brand-red-hsl: hsl(30 100% 50% / 100%); + --brand-red-hwb: hwb(30 0% 0% / 100%); + --brand-red-dark: hwb(0 0% 20% / 100%); +} +``` + +## Supported Colors + +The `color-mod()` function accepts `rgb()`, legacy `rgb()`, `rgba()`, `hsl()`, +legacy `hsl()`, `hsla()`, `hwb()`, and `color-mod()` colors, as well as 3, 4, +6, and 8 digit hex colors, and named colors without the need for additional +plugins. + +Implemention details are available in +[the specification](https://drafts.csswg.org/css-color/#funcdef-color-mod). + +*Because CSS variables (`var()`) cannot not be inferred at compilation, they +will need to be compiled beforehand.* + +## Supported Color Adjusters + +The `color-mod()` function accepts `red()`, `green()`, `blue()`, `a()` / +`alpha()`, `rgb()`, `h()` / `hue()`, `s()` / `saturation()`, `l()` / +`lightness()`, `w()` / `whiteness()`, `b()` / `blackness()`, `tint()`, +`shade()`, `blend()`, `blenda()`, and `contrast()` color adjusters. + +Implemention details are available in +[the specification](https://drafts.csswg.org/css-color/#typedef-color-adjuster). + +--- + +## Usage + +Add [PostCSS color-mod() Function] to your build tool: + +```bash +npm install postcss-color-mod-function --save-dev +``` + +#### Node + +Use [PostCSS color-mod() Function] to process your CSS: + +```js +import postcssColorMod from 'postcss-color-mod-function'; + +postcssColorMod.process(YOUR_CSS); +``` + +#### PostCSS + +Add [PostCSS] to your build tool: + +```bash +npm install postcss --save-dev +``` + +Use [PostCSS color-mod() Function] as a plugin: + +```js +import postcss from 'postcss'; +import postcssColorMod from 'postcss-color-mod-function'; + +postcss([ + postcssColorMod(/* options */) +]).process(YOUR_CSS); +``` + +#### Gulp + +Add [Gulp PostCSS] to your build tool: + +```bash +npm install gulp-postcss --save-dev +``` + +Use [PostCSS color-mod() Function] in your Gulpfile: + +```js +import postcss from 'gulp-postcss'; +import postcssColorMod from 'postcss-color-mod-function'; + +gulp.task('css', + () => gulp.src('./src/*.css') + .pipe( postcss([ postcssColorMod(/* options */) ]) ) + .pipe( gulp.dest('.') ); +``` + +#### Grunt + +Add [Grunt PostCSS] to your build tool: + +```bash +npm install grunt-postcss --save-dev +``` + +Use [PostCSS color-mod() Function] in your Gruntfile: + +```js +import postcssColorMod from 'postcss-color-mod-function'; + +grunt.loadNpmTasks('grunt-postcss'); + +grunt.initConfig({ + postcss: { + options: { + use: [ postcssColorMod(/* options */) ] + }, + dist: { + src: '*.css' + } + } +}); +``` + +--- + +## Options + +### stringifier + +The `stringifier` option defines how transformed colors will be produced in CSS. +By default, legacy `rbg()` and `rgba()` colors are produced, but this can be +easily updated to support [CSS Color Module Level 4 colors] colors. + +```js +import postcssColorMod from 'postcss-color-mod-function'; + +postcssColorMod({ + stringifier(color) { + return color.toString(); // use CSS Color Module Level 4 colors (rgb, hsl, hwb) + } +}); +``` + +Future major releases of [PostCSS color-mod() Function] may reverse this +functionality so that CSS Color Module Level 4 colors are produced by default. + +### unresolved + +The `unresolved` option defines how unresolved functions and arguments should +be handled. The available options are `throw`, `warn`, and `ignore`. The +default option is to `throw`. + +If `ignore` is used, the `color-mod()` function will remain unchanged. + +```js +import postcssColorMod from 'postcss-color-mod-function'; + +postcssColorMod({ + unresolved: 'ignore' // ignore unresolved color-mod() functions +}); +``` + +[npm-url]: https://www.npmjs.com/package/postcss-color-mod-function +[npm-img]: https://img.shields.io/npm/v/postcss-color-mod-function.svg +[cli-url]: https://travis-ci.org/jonathantneal/postcss-color-mod-function +[cli-img]: https://img.shields.io/travis/jonathantneal/postcss-color-mod-function.svg +[win-url]: https://ci.appveyor.com/project/jonathantneal/postcss-color-mod-function +[win-img]: https://img.shields.io/appveyor/ci/jonathantneal/postcss-color-mod-function.svg +[git-url]: https://gitter.im/postcss/postcss +[git-img]: https://img.shields.io/badge/chat-gitter-blue.svg + +[CSS Color Module Level 4]: https://drafts.csswg.org/css-color/#modifying-colors +[Gulp PostCSS]: https://github.com/postcss/gulp-postcss +[Grunt PostCSS]: https://github.com/nDmitry/grunt-postcss +[PostCSS]: https://github.com/postcss/postcss +[PostCSS color-mod() Function]: https://github.com/jonathantneal/postcss-color-mod-function diff --git a/index.js b/index.js new file mode 100644 index 0000000000..de40f34144 --- /dev/null +++ b/index.js @@ -0,0 +1,30 @@ +// tooling +import parser from 'postcss-values-parser'; +import postcss from 'postcss'; +import transformAST from './lib/transform'; + +// plugin +export default postcss.plugin('postcss-color-mod-function', opts => { + const unresolvedOpt = String(Object(opts).unresolved || 'throw').toLowerCase(); + const stringifierOpt = Object(opts).stringifier || (color => color.toRGBLegacy()); + + return (root, result) => { + root.walkDecls(decl => { + const originalValue = decl.value; + + if (colorModFunctionMatch.test(originalValue)) { + const ast = parser(originalValue, { loose: true }).parse(); + + transformAST(ast, { unresolved: unresolvedOpt, stringifier: stringifierOpt, decl, result }); + + const modifiedValue = ast.toString(); + + if (originalValue !== modifiedValue) { + decl.value = modifiedValue; + } + } + }); + }; +}); + +const colorModFunctionMatch = /(^|\s)color-mod\(/i; diff --git a/lib/color.js b/lib/color.js new file mode 100644 index 0000000000..2860f80ed1 --- /dev/null +++ b/lib/color.js @@ -0,0 +1,553 @@ +export default class Color { + constructor(color) { + this.color = Object(Object(color).color || color); + + if (color.colorspace === 'rgb') { + this.color.hue = rgb2hue(color.red, color.green, color.blue, color.hue || 0); + } + } + + alpha(alpha) { + const color = this.color; + + return alpha === undefined + ? color.alpha + : new Color(assign(color, { alpha })); + } + + blackness(blackness) { + const hwb = color2hwb(this.color); + + return blackness === undefined + ? hwb.blackness + : new Color(assign(hwb, { blackness })); + } + + blend(color, percentage, colorspace = 'rgb') { + const base = this.color; + + return new Color(blend(base, color, percentage, colorspace)); + } + + blenda(color, percentage, colorspace = 'rgb') { + const base = this.color; + + return new Color(blend(base, color, percentage, colorspace, true)); + } + + blue(blue) { + const rgb = color2rgb(this.color); + + return blue === undefined + ? rgb.blue + : new Color(assign(rgb, { blue })); + } + + contrast(percentage) { + const base = this.color; + + return new Color(contrast(base, percentage)); + } + + green(green) { + const rgb = color2rgb(this.color); + + return green === undefined + ? rgb.green + : new Color(assign(rgb, { green })); + } + + hue(hue) { + const hsl = color2hsl(this.color); + + return hue === undefined + ? hsl.hue + : new Color(assign(hsl, { hue })); + } + + lightness(lightness) { + const hsl = color2hsl(this.color); + + return lightness === undefined + ? hsl.lightness + : new Color(assign(hsl, { lightness })) + } + + red(red) { + const rgb = color2rgb(this.color); + + return red === undefined + ? rgb.red + : new Color(assign(rgb, { red })); + } + + rgb(red, green, blue) { + const rgb = color2rgb(this.color); + + return new Color(assign(rgb, { red, green, blue })); + } + + saturation(saturation) { + const hsl = color2hsl(this.color); + + return saturation === undefined + ? hsl.saturation + : new Color(assign(hsl, { saturation })); + } + + shade(percentage) { + const hwb = color2hwb(this.color); + const shade = { hue: 0, whiteness: 1, blackness: 0, colorspace: 'hwb' }; + const colorspace = 'hwb'; + + return percentage === undefined + ? hwb.blackness + : new Color(blend(hwb, shade, percentage, colorspace)); + } + + tint(percentage) { + const hwb = color2hwb(this.color); + const tint = { hue: 0, whiteness: 0, blackness: 1, colorspace: 'hwb' }; + const colorspace = 'hwb'; + + return percentage === undefined + ? hwb.blackness + : new Color(blend(hwb, tint, percentage, colorspace)); + } + + whiteness(whiteness) { + const hwb = color2hwb(this.color); + + return whiteness === undefined + ? hwb.whiteness + : new Color(assign(hwb, { whiteness })); + } + + toHSL() { + const color = color2hsl(this.color); + const isOpaque = color.alpha === 1; + const hue = color.hue; + const saturation = color.saturation * 100; + const lightness = color.lightness * 100; + const alpha = color.alpha * 100; + + return `hsl(${hue} ${saturation}% ${lightness}%${isOpaque + ? '' + : ` / ${alpha}%`})`; + } + + toHWB() { + const color = color2hwb(this.color); + const isOpaque = color.alpha === 1; + const hue = color.hue; + const whiteness = color.whiteness * 100; + const blackness = color.blackness * 100; + const alpha = color.alpha * 100; + + return `hwb(${hue} ${whiteness}% ${blackness}%${isOpaque + ? '' + : ` / ${alpha}%`})`; + } + + toRGB() { + const color = color2rgb(this.color); + const isOpaque = color.alpha === 1; + const red = color.red * 100; + const green = color.green * 100; + const blue = color.blue * 100; + const alpha = color.alpha * 100; + + return `rgb(${red}% ${green}% ${blue}%${isOpaque + ? '' + : ` / ${alpha}%`})`; + } + + toRGBLegacy() { + const color = color2rgb(this.color); + const isOpaque = color.alpha === 1; + const name = isOpaque ? 'rgb' : 'rgba'; + const red = color.red * 255; + const green = color.green * 255; + const blue = color.blue * 255; + const alpha = color.alpha; + + return `${name}(${red}, ${green}, ${blue}${isOpaque + ? '' + : `, ${alpha}`})`; + } + + toString(rawcolorspace) { + const colorspace = rawcolorspace || this.color.colorspace; + + const color = colorspace === 'hsl' + ? this.toHSL() + : colorspace === 'hwb' + ? this.toHWB() + : this.toRGB(); + + return color; + } +} + +/* Blending +/* ========================================================================== */ + +function blend(base, color, percentage, colorspace, isBlendingAlpha) { // eslint-disable-line max-params + const subtraction = 1 - percentage; + + if (colorspace === 'hsl') { + const { hue: h1, saturation: s1, lightness: l1, alpha: a1 } = color2hsl(base); + const { hue: h2, saturation: s2, lightness: l2, alpha: a2 } = color2hsl(color); + + const [hue, saturation, lightness, alpha] = [ + h1 * percentage + h2 * subtraction, + s1 * percentage + s2 * subtraction, + l1 * percentage + l2 * subtraction, + isBlendingAlpha ? a1 * percentage + a2 * subtraction : a1 + ]; + + return { hue, saturation, lightness, alpha, colorspace: 'hsl' }; + } else if (colorspace === 'hwb') { + const { hue: h1, whiteness: w1, blackness: b1, alpha: a1 } = color2hwb(base); + const { hue: h2, whiteness: w2, blackness: b2, alpha: a2 } = color2hwb(color); + + const [hue, whiteness, blackness, alpha] = [ + h1 * percentage + h2 * subtraction, + w1 * percentage + w2 * subtraction, + b1 * percentage + b2 * subtraction, + isBlendingAlpha ? a1 * percentage + a2 * subtraction : a1 + ]; + + return { hue, whiteness, blackness, alpha, colorspace: 'hwb' }; + } else { + const { red: r1, green: g1, blue: b1, alpha: a1 } = color2rgb(base); + const { red: r2, green: g2, blue: b2, alpha: a2 } = color2rgb(color); + + const [red, green, blue, alpha] = [ + r1 * percentage + r2 * subtraction, + g1 * percentage + g2 * subtraction, + b1 * percentage + b2 * subtraction, + isBlendingAlpha ? a1 * percentage + a2 * subtraction : a1 + ]; + + return { red, green, blue, alpha, colorspace: 'rgb' }; + } +} + +/* Assign channels to a new instance of a base color +/* ========================================================================== */ + +function assign(base, channels) { + const color = Object.assign({}, base); + + Object.keys(channels).forEach( + channel => { + // detect channel + const isHue = channel === 'hue'; + const isRGB = !isHue && blueGreenRedMatch.test(channel); + + // value of the channel + const adjustment = channels[channel]; + + // value limitations + const min = 0; + const max = isHue ? 360 : 1; + + // updated value + const value = Math.min(Math.max(parseFloat(adjustment), min), max); + + // assign channel to new object + if (isHue) { + color.hue = value; + } else { + color[channel] = value; + + color.hue = isRGB + ? rgb2hue(color.red, color.green, color.blue, base.hue || 0) + : base.hue; + } + } + ); + + return color; +} + +/* Convert colors +/* ========================================================================== */ + +function color2hsl(color) { + return color.colorspace === 'rgb' + ? rgb2hsl(color, color.hue) + : color.colorspace === 'hwb' + ? rgb2hsl(hwb2rgb(color), color.hue) + : color; +} + +function color2hwb(color) { + return color.colorspace === 'rgb' + ? rgb2hwb(color, color.hue) + : color.colorspace === 'hsl' + ? rgb2hwb(hsl2rgb(color), color.hue) + : color; +} + +function color2rgb(color) { + return color.colorspace === 'hsl' + ? hsl2rgb(color) + : color.colorspace === 'hwb' + ? hwb2rgb(color) + : color; +} + +/* Convert HSL to RGB +/* ========================================================================== */ + +function hsl2rgb({ hue, saturation, lightness, alpha = 1 }) { + const t2 = lightness <= 0.5 + ? lightness * (saturation + 1) + : lightness + saturation - lightness * saturation; + + const t1 = lightness * 2 - t2; + + const red = hue2rgb(t1, t2, hue / 60 + 2); + const green = hue2rgb(t1, t2, hue / 60); + const blue = hue2rgb(t1, t2, hue / 60 - 2); + + return { hue, red, green, blue, alpha, colorspace: 'rgb' }; +} + +/* Convert HWB to RGB +/* ========================================================================== */ + +function hwb2rgb({ hue, whiteness, blackness, alpha = 1 }) { + const ratio = whiteness + blackness; + const rwhiteness = ratio > 1 ? whiteness / ratio : whiteness; + const rblackness = ratio > 1 ? blackness / ratio : blackness; + + const value = 1 - rblackness; + const hexagon = 6 * hue / 360; + const hexagonFloor = Math.floor(hexagon); + const hexagonF = hexagonFloor % 6 ? 1 - (hexagon - hexagonFloor) : hexagon - hexagonFloor; + const interpolation = rwhiteness + hexagonF * (value - rwhiteness); + + const [red, green, blue] = hexagonFloor % 6 === 5 + ? [value, rwhiteness, interpolation] + : hexagonFloor % 6 === 4 + ? [interpolation, rwhiteness, value] + : hexagonFloor % 6 === 3 + ? [rwhiteness, interpolation, value] + : hexagonFloor % 6 === 2 + ? [rwhiteness, value, interpolation] + : hexagonFloor % 6 === 1 + ? [interpolation, value, rwhiteness] + : [value, interpolation, rwhiteness]; + + return { hue, red, green, blue, alpha, colorspace: 'rgb' }; +} + +/* Convert RGB to HSL +/* ========================================================================== */ + +function rgb2hsl({ red, green, blue, alpha = 1 }, fallback = 0) { // eslint-disable-line max-params + const hue = rgb2hue(red, green, blue, fallback); + const whiteness = rgb2whiteness(red, green, blue); + const value = rgb2value(red, green, blue); + const lightness = wv2lightness(whiteness, value); + const saturation = lvw2saturation(lightness, value, whiteness); + + return { hue, saturation, lightness, alpha, colorspace: 'hsl' }; +} + +/* Convert RGB to HWB +/* ========================================================================== */ + +function rgb2hwb({ red, green, blue, alpha = 1 }, fallback = 0) { // eslint-disable-line max-params + const hue = rgb2hue(red, green, blue, fallback); + const whiteness = rgb2whiteness(red, green, blue); + const value = rgb2value(red, green, blue); + const blackness = 1 - value; + + return { hue, whiteness, blackness, alpha, colorspace: 'hwb' }; +} + +/* Convert Hue to RGB +/* ========================================================================== */ + +function hue2rgb(t1, t2, hue) { + const huerange = hue < 0 ? hue + 6 : hue >= 6 ? hue - 6 : hue; + + const rgb = huerange < 1 + ? (t2 - t1) * hue + t1 + : hue < 3 + ? t2 + : hue < 4 + ? (t2 - t1) * (4 - hue) + t1 + : t1; + + return rgb; +} + +/* Convert RGB to Hue +/* ========================================================================== */ + +function rgb2hue(red, green, blue, fallback) { // eslint-disable-line max-params + const whiteness = rgb2whiteness(red, green, blue); + const value = rgb2value(red, green, blue); + const chroma = vw2chroma(value, whiteness); + + if (chroma === 0) { + return fallback; + } else { + const segment = value === red + ? (green - blue) / chroma + : value === green + ? (blue - red) / chroma + : (red - green) / chroma; + + const shift = value === red + ? segment < 0 + ? 360 / 60 + : 0 / 60 + : value === green + ? 120 / 60 + : 240 / 60; + + const hue = (segment + shift) * 60; + + return hue; + } +} + +/* Contrast functions +/* ========================================================================== */ + +function contrast(color, percentage) { + // https://drafts.csswg.org/css-color/#contrast-adjuster + const hwb = color2hwb(color); + + // compute the luminance of the color. + const luminance = rgb2luminance(color.red, color.green, color.blue); + + // the maximum-contrast color, if it is less than .5 + const maxContrastColor = luminance < 0.5 + // hwb(X, 100%, 0%), where X is the hue angle of the color + ? { hue: hwb.hue, whiteness: 100, blackness: 0, alpha: hwb.alpha, colorspace: 'hwb' } + // otherwise, hwb(X, 0%, 100%), where X is the hue angle of the color + : { hue: hwb.hue, whiteness: 0, blackness: 1, alpha: hwb.alpha, colorspace: 'hwb' }; + + // contrast ratio + const contrastRatio = colors2contrast(color, maxContrastColor); + + const minContrastColor = contrastRatio > 4.5 + // the color with the smallest contrast ratio with the base color that is greater than 4.5 + ? colors2contrastRatioColor(hwb, maxContrastColor) + // otherwise, the maximum-contrast color + : maxContrastColor; + + // color(maximum-contrast blend(minimum-contrast hwb)) + return blend(maxContrastColor, minContrastColor, percentage, 'hwb', false); +} + +function colors2contrast(color1, color2) { + // https://drafts.csswg.org/css-color/#contrast-ratio + const rgb1 = color2rgb(color1); + const rgb2 = color2rgb(color2); + var l1 = rgb2luminance(rgb1.red, rgb1.green, rgb1.blue); + var l2 = rgb2luminance(rgb2.red, rgb2.green, rgb2.blue); + + return l1 > l2 + // if l1 is the relative luminance of the lighter of the colors + ? (l1 + 0.05) / (l2 + 0.05) + // otherwise, if l2 is the relative luminance of the lighter of the colors + : (l2 + 0.05) / (l2 + 0.05); +} + +function rgb2luminance(red, green, blue) { + const [ redLuminance, greenLuminance, blueLuminance ] = [ + channel2luminance(red), + channel2luminance(green), + channel2luminance(blue) + ]; + + // https://drafts.csswg.org/css-color/#luminance + return 0.2126 * redLuminance + 0.7152 * greenLuminance + 0.0722 * blueLuminance; +} + +function channel2luminance(value) { + // https://drafts.csswg.org/css-color/#luminance + return value <= 0.03928 ? value / 12.92 : Math.pow((value + 0.055) / 1.055, 2.4); +} + +// return the smallest contrast ratio from a color and a maximum contrast (credit: @thetalecrafter) +function colors2contrastRatioColor(hwb, maxHWB) { + const modifiedHWB = Object.assign({}, hwb); + + // values to be used for linear interpolations in HWB space + let minW = hwb.whiteness; + let minB = hwb.blackness; + let maxW = maxHWB.whiteness; + let maxB = maxHWB.blackness; + + // find the color with the smallest contrast ratio with the base color that is greater than 4.5 + while (Math.abs(minW - maxW) > 1 || Math.abs(minB - maxB) > 1) { + const midW = Math.round((maxW + minW) / 2); + const midB = Math.round((maxB + minB) / 2); + + modifiedHWB.whiteness = midW; + modifiedHWB.blackness = midB; + + if (colors2contrast(modifiedHWB, hwb) > 4.5) { + maxW = midW; + maxB = midB; + } else { + minW = midW; + minB = midB; + } + } + + return modifiedHWB; +} + +/* Convert RGB to Whiteness +/* ========================================================================== */ + +function rgb2whiteness(red, green, blue) { + return Math.min(red, green, blue); +} + +/* Convert RGB to Value +/* ========================================================================== */ + +function rgb2value(red, green, blue) { + return Math.max(red, green, blue) +} + +/* Convert Whiteness and Value to Lightness +/* ========================================================================== */ + +function wv2lightness(whiteness, value) { + return (whiteness + value) / 2; +} + +/* Convert Value and Whiteness to Chroma +/* ========================================================================== */ + +function vw2chroma(value, whiteness) { + return value - whiteness; +} + +/* Convert Lightness, Value, and Whiteness to Saturation +/* ========================================================================== */ + +function lvw2saturation(lightness, value, whiteness) { + return whiteness === value + ? 0 + : lightness < 0.5 + ? (value - whiteness) / (value + whiteness) + : (value - whiteness) / (2 - value - whiteness); +} + +/* Match +/* ========================================================================== */ + +const blueGreenRedMatch = /^(blue|green|red)$/i; diff --git a/lib/manage-unresolved.js b/lib/manage-unresolved.js new file mode 100644 index 0000000000..3a8ef68dd8 --- /dev/null +++ b/lib/manage-unresolved.js @@ -0,0 +1,7 @@ +export default function manageUnresolved(node, opts, word, message) { // eslint-disable-line max-params + if ('warn' === opts.unresolved) { + opts.decl.warn(opts.result, message, { word }); + } else if ('ignore' !== opts.unresolved) { + throw opts.decl.error(message, { word }); + } +} diff --git a/lib/transform.js b/lib/transform.js new file mode 100644 index 0000000000..00782a8d6c --- /dev/null +++ b/lib/transform.js @@ -0,0 +1,663 @@ +// tooling +import Color from './color'; +import manageUnresolved from './manage-unresolved'; +import names from 'color-name'; +import parser from 'postcss-values-parser'; + +/* Transform AST +/* ========================================================================== */ + +export default function transformAST(node, opts) { + node.nodes.slice(0).forEach(child => { + if (isColorModFunction(child)) { + // transform any color-mod() functions + const color = transformColorModFunction(child, opts); + + if (color) { + // update the color-mod() function with the transformed value + child.replaceWith( + parser.word({ + value: opts.stringifier(color) + }) + ); + } + } else if (child.nodes && Object(child.nodes).length) { + transformAST(child, opts); + } + }); +} + +/* Transform functions +/* ========================================================================== */ + +function transformColor(node, opts) { + if (isRGBFunction(node)) { + return transformRGBFunction(node, opts); + } else if (isHSLFunction(node)) { + return transformHSLFunction(node, opts); + } else if (isHWBFunction(node)) { + return transformHWBFunction(node, opts); + } else if (isColorModFunction(node)) { + return transformColorModFunction(node, opts); + } else if (isHexColor(node)) { + return transformHexColor(node, opts); + } else if (isNamedColor(node)) { + return transformNamedColor(node, opts); + } else { + return manageUnresolved(node, opts, node.value, `Expected a color`); + } +} + +// return a transformed rgb/rgba color function +function transformRGBFunction(node, opts) { + const [red, green, blue, alpha = 1] = transformArgsByParams(node, [ + // [ {3} | {3} ] [ / ]? + [transformRGBValue, transformRGBValue, transformRGBValue, isSlash, transformAlpha], + // #{3} [ , ]? ] + [transformRGBValue, isComma, transformRGBValue, isComma, transformRGBValue, isComma, transformAlpha] + ]); + + if (red !== undefined) { + const color = new Color({ red, green, blue, alpha, colorspace: 'rgb' }); + + return color; + } else { + return manageUnresolved(node, opts, node.value, `Expected a valid rgb() function`); + } +} + +// return a transformed hsl/hsla color function +function transformHSLFunction(node, opts) { + const [hue, saturation, lightness, alpha = 1] = transformArgsByParams(node, [ + // {2} [ / ]? + [transformHue, transformPercentage, transformPercentage, isSlash, transformAlpha], + // hue, #{2} [ , ]? ] + [transformHue, isComma, transformPercentage, isComma, transformPercentage, isComma, transformAlpha] + ]); + + if (lightness !== undefined) { + const color = new Color({ hue, saturation, lightness, alpha, colorspace: 'hsl' }); + + return color; + } else { + return manageUnresolved(node, opts, node.value, `Expected a valid hsl() function`); + } +} + +// return a transformed hwb color function +function transformHWBFunction(node, opts) { + const [hue, whiteness, blackness, alpha = 1] = transformArgsByParams(node, [ + // [ / ]? + [transformHue, transformPercentage, transformPercentage, isSlash, transformAlpha] + ]); + + if (blackness !== undefined) { + const color = new Color({ hue, whiteness, blackness, alpha, colorspace: 'hwb' }); + + return color; + } else { + return manageUnresolved(node, opts, node.value, `Expected a valid hwb() function`); + } +} + +// return a transformed color-mod color function +function transformColorModFunction(node, opts) { + // [ | ] * + const [colorOrHueNode, ...adjusterNodes] = (node.nodes || []).slice(1, -1) || []; + + if (colorOrHueNode !== undefined) { + const color = isHue(colorOrHueNode) + ? new Color({ hue: transformHue(colorOrHueNode, opts), saturation: 1, lightness: 0.5, alpha: 1, colorspace: 'hsl' }) + : transformColor(colorOrHueNode, opts); + + if (color) { + const adjustedColor = transformColorByAdjusters(color, adjusterNodes, opts); + + return adjustedColor; + } else { + return manageUnresolved(node, opts, node.value, `Expected a valid color`); + } + } else { + return manageUnresolved(node, opts, node.value, `Expected a valid color-mod() function`); + } +} + +// return a transformed hex color +function transformHexColor(node, opts) { + if (hexColorMatch.test(node.value)) { + // #{3,4,6,8} + const [r, g, b, a, rr, gg, bb, aa] = (node.value.match(hexColorMatch) || []).slice(1); + + const color = new Color({ + red: rr !== undefined ? parseInt(rr, 16) / 255 : r !== undefined ? parseInt(r + r, 16) / 255 : 0, + green: gg !== undefined ? parseInt(gg, 16) / 255 : g !== undefined ? parseInt(g + g, 16) / 255 : 0, + blue: bb !== undefined ? parseInt(bb, 16) / 255 : b !== undefined ? parseInt(b + b, 16) / 255 : 0, + alpha: aa !== undefined ? parseInt(aa, 16) / 255 : a !== undefined ? parseInt(a + a, 16) / 255 : 1 + }); + + return color; + } else { + return manageUnresolved(node, opts, node.value, `Expected a valid hex color`); + } +} + +// return a transformed named-color +function transformNamedColor(node, opts) { + if (isNamedColor(node)) { + // + const [red, green, blue] = names[node.value]; + + const color = new Color({ red: red / 255, green: green / 255, blue: blue / 255, alpha: 1, colorspace: 'rgb' }); + + return color; + } else { + return manageUnresolved(node, opts, node.value, `Expected a valid named-color`); + } +} + +/* Transform functions +/* ========================================================================== */ + +// return a transformed color using adjustments +function transformColorByAdjusters(color, adjusterNodes, opts) { + const adjustedColor = adjusterNodes.reduce((base, node) => { + if (isAlphaBlueGreenRedAdjuster(node)) { + return transformAlphaBlueGreenRedAdjuster(base, node, opts); + } else if (isRGBAdjuster(node)) { + return transformRGBAdjuster(base, node, opts); + } else if (isHueAdjuster(node)) { + return transformHueAdjuster(base, node, opts); + } else if (isBlacknessLightnessSaturationWhitenessAdjuster(node)) { + return transformBlacknessLightnessSaturationWhitenessAdjuster(base, node, opts); + } else if (isShadeTintAdjuster(node)) { + return transformShadeTintAdjuster(base, node, opts); + } else if (isBlendAdjuster(node)) { + return transformBlendAdjuster(base, node, node.value === 'blenda', opts); + } else if (isContrastAdjuster(node)) { + return transformContrastAdjuster(base, node, opts); + } else { + manageUnresolved(node, opts, node.value, `Expected a valid color adjuster`); + + return base; + } + }, color); + + return adjustedColor; +} + +// return a transformed color using a/alpha/blue/green/red adjustments +function transformAlphaBlueGreenRedAdjuster(base, node, opts) { + const [operatorOrValue, adjustment] = transformArgsByParams(node, alphaMatch.test(node.value) + ? [ + // [ + | - ] + [transformMinusPlusOperator, transformAlpha], + // * + [transformTimesOperator, transformPercentage], + // + [transformAlpha] + ] + : [ + // [ + | - ] + [transformMinusPlusOperator, transformRGBValue], + // * + [transformTimesOperator, transformPercentage], + // + [transformRGBValue] + ] + ); + + if (operatorOrValue !== undefined) { + // normalized channel name + const channel = node.value.toLowerCase().replace(alphaMatch, 'alpha'); + + const existingValue = base[channel](); + + const modifiedValue = adjustment + ? operatorOrValue === '+' + ? existingValue + adjustment + : operatorOrValue === '-' + ? existingValue - adjustment + : operatorOrValue === '*' + ? existingValue * adjustment + : adjustment + : operatorOrValue; + + const modifiedColor = base[channel](modifiedValue); + + return modifiedColor; + } else { + return manageUnresolved(node, opts, node.value, `Expected a valid modifier()`); + } +} + +// return a transformed color using an rgb adjustment +function transformRGBAdjuster(base, node, opts) { + const [arg1, arg2, arg3, arg4] = transformArgsByParams(node, [ + // [ + | - ] + [transformMinusPlusOperator, transformRGBNumber, transformRGBNumber, transformRGBNumber], + // [ + | - ] + [transformMinusPlusOperator, transformPercentage, transformPercentage, transformPercentage], + // [ + | - ] + [transformMinusPlusOperator, transformHexColor], + // [ * ] + [transformTimesOperator, transformPercentage] + ] + ); + + if (arg2 !== undefined && arg2.color) { + const modifiedColor = base.rgb( + arg1 === '+' + ? base.red() + arg2.red() + : base.red() - arg2.red(), + arg1 === '+' + ? base.green() + arg2.green() + : base.green() - arg2.green(), + arg1 === '+' + ? base.blue() + arg2.blue() + : base.blue() - arg2.blue() + ); + + return modifiedColor; + } else if (arg1 !== undefined && minusPlusMatch.test(arg1)) { + const modifiedColor = base.rgb( + arg1 === '+' + ? base.red() + arg2 + : base.red() - arg2, + arg1 === '+' + ? base.green() + arg3 + : base.green() - arg3, + arg1 === '+' + ? base.blue() + arg4 + : base.blue() - arg4 + ); + + return modifiedColor; + } else if (arg1 !== undefined && arg2 !== undefined) { + const modifiedColor = base.rgb( + base.red() * arg2, + base.green() * arg2, + base.blue() * arg2 + ); + + return modifiedColor; + } else { + return manageUnresolved(node, opts, node.value, `Expected a valid rgb() adjuster)`); + } +} + +// return a transformed color using a blend/blenda adjustment +function transformBlendAdjuster(base, node, isAlphaBlend, opts) { // eslint-disable-line max-params + const [color, percentage, colorspace = 'rgb'] = transformArgsByParams(node, [ + [transformColor, transformPercentage, transformColorSpace] + ]); + + if (percentage !== undefined) { + const modifiedColor = isAlphaBlend + ? base.blenda(color.color, percentage, colorspace) + : base.blend(color.color, percentage, colorspace); + + return modifiedColor; + } else { + return manageUnresolved(node, opts, node.value, `Expected a valid blend() adjuster)`); + } +} + +// return a transformed color using a contrast adjustment +function transformContrastAdjuster(base, node, opts) { + const [percentage] = transformArgsByParams(node, [ + // + [transformPercentage] + ]); + + if (percentage !== undefined) { + const modifiedColor = base.contrast(percentage); + + return modifiedColor; + } else { + return manageUnresolved(node, opts, node.value, `Expected a valid contrast() adjuster)`); + } +} + +// return a transformed color using a hue adjustment +function transformHueAdjuster(base, node, opts) { + const [operatorOrHue, rawAdjustment] = transformArgsByParams(node, [ + // [ + | - | * ] + [transformMinusPlusTimesOperator, transformHue], + // + [transformHue] + ]); + + if (operatorOrHue !== undefined) { + const existingHue = base.hue(); + const adjustment = parseFloat(rawAdjustment); + + const rawModifiedValue = adjustment + ? operatorOrHue === '+' + ? existingHue + adjustment + : operatorOrHue === '-' + ? existingHue - adjustment + : operatorOrHue === '*' + ? existingHue * adjustment + : adjustment + : parseFloat(operatorOrHue); + + const modifiedValue = rawModifiedValue < 0 + ? 360 + rawModifiedValue % 360 + : rawModifiedValue % 360; + + return base.hue(modifiedValue); + } else { + return manageUnresolved(node, opts, node.value, `Expected a valid hue() function)`); + } +} + +// [ b | blackness | l | lightness | s | saturation | w | whiteness ]( [ + | - | * ]? ) +function transformBlacknessLightnessSaturationWhitenessAdjuster(base, node, opts) { + const channel = node.value.toLowerCase().replace(/^b$/, 'blackness').replace(/^l$/, 'lightness').replace(/^s$/, 'saturation').replace(/^w$/, 'whiteness'); + const [operatorOrValue, rawAdjustment] = transformArgsByParams(node, [ + [transformMinusPlusTimesOperator, transformPercentage], + [transformPercentage] + ]); + + if (operatorOrValue !== undefined) { + const existingValue = base[channel](); + const adjustment = parseFloat(rawAdjustment); + + const modifiedValue = adjustment + ? operatorOrValue === '+' + ? existingValue + adjustment + : operatorOrValue === '-' + ? existingValue - adjustment + : operatorOrValue === '*' + ? existingValue * adjustment + : adjustment + : parseFloat(operatorOrValue); + + return base[channel](modifiedValue); + } else { + return manageUnresolved(node, opts, node.value, `Expected a valid ${channel}() function)`); + } +} + +// return a transformed color using shade/tint adjustments +function transformShadeTintAdjuster(base, node, opts) { + const channel = node.value.toLowerCase(); + const [percentage] = transformArgsByParams(node, [ + // [ shade | tint ]( ) + [transformPercentage] + ]); + + if (percentage !== undefined) { + const modifiedValue = parseFloat(percentage); + + return base[channel](modifiedValue); + } else { + return manageUnresolved(node, opts, node.value, `Expected valid ${channel}() arguments`); + } +} + +/* Argument Transforms +/* ========================================================================== */ + +// return a transformed color space +function transformColorSpace(node, opts) { + if (isColorSpace(node)) { + // [ hsl | hwb | rgb ] + return node.value; + } else { + return manageUnresolved(node, opts, node.value, `Expected a valid color space)`); + } +} + +// return a transformed alpha value +function transformAlpha(node, opts) { + if (isNumber(node)) { + // + return parseFloat(node.value); + } else if (isPercentage(node)) { + // + return transformPercentage(node, opts); + } else { + return manageUnresolved(node, opts, node.value, `Expected a valid alpha value)`); + } +} + +// return a transformed rgb value +function transformRGBValue(node, opts) { + if (isNumber(node)) { + // + return transformRGBNumber(node, opts); + } else if (isPercentage(node)) { + // + return transformPercentage(node, opts); + } else { + return manageUnresolved(node, opts, node.value, `Expected a valid RGB value)`); + } +} + +// return a transformed rgb number +function transformRGBNumber(node, opts) { + if (isNumber(node)) { + // + return parseFloat(node.value) / 255; + } else { + return manageUnresolved(node, opts, node.value, `Expected a valid RGB value)`); + } +} + +// return a transformed hue +function transformHue(node, opts) { + if (isHue(node)) { + // + return parseFloat(node.value); + } else { + return manageUnresolved(node, opts, node.value, `Expected a valid hue`); + } +} + +// return a transformed percentage +function transformPercentage(node, opts) { + if (isPercentage(node)) { + // + return parseFloat(node.value) / 100; + } else { + return manageUnresolved(node, opts, node.value, `Expected a valid hue`); + } +} + +// return a transformed minus-plus operator +function transformMinusPlusOperator(node, opts) { + if (isMinusPlusOperator(node)) { + // [ - | + ] + return node.value; + } else { + return manageUnresolved(node, opts, node.value, `Expected a plus or minus operator`); + } +} + +// return a transformed times operator +function transformTimesOperator(node, opts) { + if (isTimesOperator(node)) { + // [ * ] + return node.value; + } else { + return manageUnresolved(node, opts, node.value, `Expected a times operator`); + } +} + +// return a transformed minus-plus-times operator +function transformMinusPlusTimesOperator(node, opts) { + if (isMinusPlusTimesOperator(node)) { + // [ - | + | * ] + return node.value; + } else { + return manageUnresolved(node, opts, node.value, `Expected a plus, minus, or times operator`); + } +} + +/* Transform helper +/* ========================================================================== */ + +// return the first set of transformed arguments allowable by the parameters +function transformArgsByParams(node, params) { + const nodes = (node.nodes || []).slice(1, -1); + const opts = { unresolved: 'ignore' }; + + return params.map(param => nodes.map( + (childNode, index) => typeof param[index] === 'function' ? param[index](childNode, opts) : undefined + ).filter(child => typeof child !== 'boolean')).filter(param => param.every( + result => result !== undefined + ))[0] || []; +} + +/* Adjustment validators +/* ========================================================================== */ + +// return whether the node is an a/alpha/blue/green/red adjuster +function isAlphaBlueGreenRedAdjuster(node) { + // [ a(), alpha(), blue(), green(), red() ] + return Object(node).type === 'func' && alphaBlueGreenRedMatch.test(node.value); +} + +// return whether the node is an rgb adjuster +function isRGBAdjuster(node) { + return Object(node).type === 'func' && rgbMatch.test(node.value); +} + +// return whether the node is a hue adjuster +function isHueAdjuster(node) { + // [ h() | hue() ] + return Object(node).type === 'func' && hueMatch.test(node.value); +} + +// return whether the node is a blackness/lightness/saturation/whiteness adjuster +function isBlacknessLightnessSaturationWhitenessAdjuster(node) { + // [ b() | blackness() | l() | lightness() | s() | saturation() | w() | whiteness() ] + return Object(node).type === 'func' && blacknessLightnessSaturationWhitenessMatch.test(node.value); +} + +// return whether the node is a shade/tint adjuster +function isShadeTintAdjuster(node) { + // [ shade() | tint() ] + return Object(node).type === 'func' && shadeTintMatch.test(node.value); +} + +// return whether the node is a blend adjuster +function isBlendAdjuster(node) { + // [ blend(), blenda() ] + return Object(node).type === 'func' && blendMatch.test(node.value); +} + +// return whether the node is a contrast adjuster +function isContrastAdjuster(node) { + // [ contrast() ] + return Object(node).type === 'func' && contrastMatch.test(node.value); +} + +/* Color validators +/* ========================================================================== */ + +// return whether the node is an rgb/rgba color function +function isRGBFunction(node) { + // [ rgb(), rgba() ] + return Object(node).type === 'func' && rgbaMatch.test(node.value); +} + +// return whether the node is an hsl color function +function isHSLFunction(node) { + // [ hsl(), hsla() ] + return Object(node).type === 'func' && hslaMatch.test(node.value); +} + +// return whether the node is an hwb color function +function isHWBFunction(node) { + // hwb() + return Object(node).type === 'func' && hwbMatch.test(node.value); +} + +// return whether the node is a color-mod function +function isColorModFunction(node) { + // color-mod() + return Object(node).type === 'func' && colorModMatch.test(node.value); +} + +// return whether the node is a valid named-color +function isNamedColor(node) { + return Object(node).type === 'word' && node.value in names; +} + +// return whether the node is a valid hex color +function isHexColor(node) { + // #{3,4,6,8} + return Object(node).type === 'word' && hexColorMatch.test(node.value); +} + +// return whether the node is a valid color space +function isColorSpace(node) { + // [ hsl | hwb | rgb ] + return Object(node).type === 'word' && colorSpaceMatch.test(node.value); +} + +/* Additional validators +/* ========================================================================== */ + +// return whether the hue value is valid +function isHue(node) { + return Object(node).type === 'number' && /^(deg)?$/.test(node.unit); +} + +// return whether the comma is valid +function isComma(node) { + return Object(node).type === 'comma'; +} + +// return whether the slash operator is valid +function isSlash(node) { + return Object(node).type === 'operator' && node.value === '/'; +} + +// return whether the number is valid +function isNumber(node) { + return Object(node).type === 'number' && node.unit === ''; +} + +// return whether the mind-plus operator is valid +function isMinusPlusOperator(node) { + return Object(node).type === 'operator' && minusPlusMatch.test(node.value); +} + +// return whether the minus-plus-times operator is valid +function isMinusPlusTimesOperator(node) { + return Object(node).type === 'operator' && minusPlusTimesMatch.test(node.value); +} + +// return whether the times operator is valid +function isTimesOperator(node) { + return Object(node).type === 'operator' && timesMatch.test(node.value); +} + +// return whether the percentage is valid +function isPercentage(node) { + return Object(node).type === 'number' && node.unit === '%'; +} + +/* Matchers +/* ========================================================================== */ + +const alphaMatch = /^a(lpha)?$/i; +const alphaBlueGreenRedMatch = /^(a(lpha)?|blue|green|red)$/i; +const blacknessLightnessSaturationWhitenessMatch = /^(b(lackness)?|l(ightness)?|s(aturation)?|w(hiteness)?)$/i; +const blendMatch = /^blenda?$/i; +const colorModMatch = /^color-mod$/i; +const colorSpaceMatch = /^(hsl|hwb|rgb)$/i; +const contrastMatch = /^contrast$/i; +const hexColorMatch = /^#(?:([a-f0-9])([a-f0-9])([a-f0-9])([a-f0-9])?|([a-f0-9]{2})([a-f0-9]{2})([a-f0-9]{2})([a-f0-9]{2})?)$/i; +const hslaMatch = /^hsla?$/i; +const hueMatch = /^h(ue)?$/i; +const hwbMatch = /^hwb$/i; +const minusPlusMatch = /^[+-]$/; +const minusPlusTimesMatch = /^[*+-]$/; +const rgbMatch = /^rgb$/i; +const rgbaMatch = /^rgba?$/i; +const shadeTintMatch = /^(shade|tint)$/i; +const timesMatch = /^[*]$/; diff --git a/package.json b/package.json new file mode 100644 index 0000000000..0ad395d5e6 --- /dev/null +++ b/package.json @@ -0,0 +1,78 @@ +{ + "name": "postcss-color-mod-function", + "version": "1.0.0", + "description": "Modify colors using the color-mod() function in CSS", + "author": "Jonathan Neal ", + "license": "CC0-1.0", + "repository": "jonathantneal/postcss-color-mod-function", + "homepage": "https://github.com/jonathantneal/postcss-color-mod-function#readme", + "bugs": "https://github.com/jonathantneal/postcss-color-mod-function/issues", + "main": "index.bundle.js", + "module": "index.js", + "files": [ + "index.js", + "index.bundle.js", + "lib" + ], + "scripts": { + "prepublishOnly": "npm test", + "pretest": "rollup -c .rollup.js --silent", + "test": "echo 'Running tests...'; npm run test:ec && npm run test:js && npm run test:tape", + "test:ec": "echint --ignore index.bundle.js test", + "test:js": "eslint *.js lib/*.js --cache --ignore-path .gitignore --quiet", + "test:tape": "postcss-tape" + }, + "engines": { + "node": ">=4.0.0" + }, + "dependencies": { + "color-name": "^1.1.3", + "postcss": "^6.0", + "postcss-values-parser": "^1.3.1" + }, + "devDependencies": { + "babel-core": "^6.26", + "babel-eslint": "^8.2", + "babel-preset-env": "^1.6", + "echint": "^4.0", + "eslint": "^4.15", + "eslint-config-dev": "2.0", + "postcss-tape": "2.2", + "pre-commit": "^1.2", + "rollup": "^0.54", + "rollup-plugin-babel": "^3.0" + }, + "eslintConfig": { + "extends": "dev", + "parser": "babel-eslint" + }, + "keywords": [ + "postcss", + "css", + "postcss-plugin", + "colors", + "colours", + "modifications", + "mods", + "adjusters", + "adjustments", + "csswg", + "rgba", + "hsla", + "white", + "black", + "red", + "green", + "blue", + "alpha", + "hue", + "saturation", + "lightness", + "whiteness", + "blackness", + "tint", + "shade", + "blenda", + "contrast" + ] +} diff --git a/test/basic.colors.expect.css b/test/basic.colors.expect.css new file mode 100644 index 0000000000..ebe329f0bc --- /dev/null +++ b/test/basic.colors.expect.css @@ -0,0 +1,96 @@ +test-color-mod { + color: rgb(100% 0% 0%); + color: rgb(100% 0% 0%); + color: rgb(100% 0% 0%); + color: rgb(100% 0% 0%); + color: rgb(100% 0% 0%); + color: rgb(100% 0% 0%); + color: rgb(100% 0% 0%); + color: rgb(100% 0% 0%); + color: rgb(100% 0% 0%); + color: rgb(100% 0% 0%); + color: rgb(100% 0% 0%); + color: rgb(100% 0% 0%); + color: hsl(0 100% 50%); + color: hsl(0 100% 50%); + color: hsl(0 100% 50%); + color: hsl(0 100% 50%); + color: hsl(0 100% 50%); + color: hwb(0 0% 0%); + color: hwb(0 0% 0%); + color: hsl(0 100% 50%); + color: hsl(0 100% 50%); +} + +test-red-green-blue-alpha-adjuster { + color: rgb(100% 0% 7.8431372549019605%); + color: rgb(100% 0% 20%); + color: rgb(100% 7.8431372549019605% 0%); + color: rgb(100% 20% 0%); + color: rgb(92.15686274509804% 0% 0%); + color: rgb(80% 0% 0%); + color: rgb(100% 0% 0% / 20%); +} + +test-rgb-adjuster { + color: rgb(100% 100% 0%); + color: rgb(100% 100% 0%); + color: rgb(0% 0% 0%); + color: rgb(0% 0% 0%); + color: rgb(50% 0% 0%); +} + +test-hue-adjuster { + color: hsl(20 100% 50%); + color: hsl(20 100% 50%); + color: hsl(20 100% 50%); + color: hsl(20 100% 50%); + color: hsl(340 100% 50%); + color: hsl(340 100% 50%); + color: hsl(0 100% 50%); + color: hsl(0 100% 50%); +} + +test-lightness-saturation-adjuster { + color: hsl(0 100% 20%); + color: hsl(0 100% 70%); + color: hsl(0 100% 30%); + color: hsl(0 100% 10%); + color: hsl(0 20% 50%); + color: hsl(0 100% 50%); + color: hsl(0 80% 50%); + color: hsl(0 20% 50%); +} + +test-blackness-whiteness-adjuster { + color: hwb(0 0% 20%); + color: hwb(0 0% 20%); + color: hwb(0 0% 0%); + color: hwb(0 0% 0%); + color: hwb(0 20% 0%); + color: hwb(0 20% 0%); + color: hwb(0 0% 0%); + color: hwb(0 0% 0%); +} + +test-tint-shade-adjuster { + color: hwb(0 0% 80%); + color: hwb(0 80% 0%); +} + +test-blend-adjuster { + color: rgb(100% 50% 0%); + color: rgb(100% 50% 0%); + color: hsl(30 100% 50%); + color: hwb(30 0% 0%); +} + +test-contrast-adjuster { + color: hwb(60 0% 25%); + color: hwb(60 0% 50%); + color: hwb(60 0% 75%); +} + +test-combination-adjuster { + color: rgb(34.56764855961519% 17.846405228758172% 44.56764855961519%); +} diff --git a/test/basic.css b/test/basic.css new file mode 100644 index 0000000000..eb6005179f --- /dev/null +++ b/test/basic.css @@ -0,0 +1,96 @@ +test-color-mod { + color: color-mod(red); + color: color-mod(color-mod(red)); + color: color-mod(color-mod(color-mod(red))); + color: color-mod(#f00); + color: color-mod(#f00f); + color: color-mod(#ff0000); + color: color-mod(#ff0000ff); + color: color-mod(rgb(100% 0% 0%)); + color: color-mod(rgb(100% 0% 0% / 100%)); + color: color-mod(rgb(255, 0, 0)); + color: color-mod(rgb(255, 0, 0, 1)); + color: color-mod(rgba(255, 0, 0, 1)); + color: color-mod(hsl(0 100% 50%)); + color: color-mod(hsl(0 100% 50% / 100%)); + color: color-mod(hsl(0, 100%, 50%)); + color: color-mod(hsl(0, 100%, 50%, 1)); + color: color-mod(hsla(0, 100%, 50%, 1)); + color: color-mod(hwb(0 0% 0%)); + color: color-mod(hwb(0 0% 0% / 100%)); + color: color-mod(0); + color: color-mod(0deg); +} + +test-red-green-blue-alpha-adjuster { + color: color-mod(red blue(20)); + color: color-mod(red blue(20%)); + color: color-mod(red green(+ 20)); + color: color-mod(red green(+ 20%)); + color: color-mod(red red(- 20)); + color: color-mod(red red(- 20%)); + color: color-mod(red alpha(* 20%)); +} + +test-rgb-adjuster { + color: color-mod(red rgb(+ 0 255 0)); + color: color-mod(red rgb(+ #0f0)); + color: color-mod(red rgb(- 255 0 0)); + color: color-mod(red rgb(- #f00)); + color: color-mod(red rgb(* 50%)); +} + +test-hue-adjuster { + color: color-mod(red hue(20)); + color: color-mod(red hue(20deg)); + color: color-mod(red hue(+ 20)); + color: color-mod(red hue(+ 20deg)); + color: color-mod(red hue(- 20)); + color: color-mod(red hue(- 20deg)); + color: color-mod(red hue(* 20)); + color: color-mod(red hue(* 20deg)); +} + +test-lightness-saturation-adjuster { + color: color-mod(red lightness(20%)); + color: color-mod(red lightness(+ 20%)); + color: color-mod(red lightness(- 20%)); + color: color-mod(red lightness(* 20%)); + color: color-mod(red saturation(20%)); + color: color-mod(red saturation(+ 20%)); + color: color-mod(red saturation(- 20%)); + color: color-mod(red saturation(* 20%)); +} + +test-blackness-whiteness-adjuster { + color: color-mod(red blackness(20%)); + color: color-mod(red blackness(+ 20%)); + color: color-mod(red blackness(- 20%)); + color: color-mod(red blackness(* 20%)); + color: color-mod(red whiteness(20%)); + color: color-mod(red whiteness(+ 20%)); + color: color-mod(red whiteness(- 20%)); + color: color-mod(red whiteness(* 20%)); +} + +test-tint-shade-adjuster { + color: color-mod(red tint(20%)); + color: color-mod(red shade(20%)); +} + +test-blend-adjuster { + color: color-mod(yellow blend(red 50%)); + color: color-mod(yellow blend(red 50% rgb)); + color: color-mod(yellow blend(red 50% hsl)); + color: color-mod(yellow blend(red 50% hwb)); +} + +test-contrast-adjuster { + color: color-mod(yellow contrast(25%)); + color: color-mod(yellow contrast(50%)); + color: color-mod(yellow contrast(75%)); +} + +test-combination-adjuster { + color: color-mod(color-mod(0deg blue(10%)) rgb(+ 0 10 0) hue(+ 10deg) tint(10%) lightness(+ 10%) saturation(+ 10%) blend(rebeccapurple 50%)); +} diff --git a/test/basic.expect.css b/test/basic.expect.css new file mode 100644 index 0000000000..d9bcee77ed --- /dev/null +++ b/test/basic.expect.css @@ -0,0 +1,96 @@ +test-color-mod { + color: rgb(255, 0, 0); + color: rgb(255, 0, 0); + color: rgb(255, 0, 0); + color: rgb(255, 0, 0); + color: rgb(255, 0, 0); + color: rgb(255, 0, 0); + color: rgb(255, 0, 0); + color: rgb(255, 0, 0); + color: rgb(255, 0, 0); + color: rgb(255, 0, 0); + color: rgb(255, 0, 0); + color: rgb(255, 0, 0); + color: rgb(255, 0, 255); + color: rgb(255, 0, 255); + color: rgb(255, 0, 255); + color: rgb(255, 0, 255); + color: rgb(255, 0, 255); + color: rgb(255, 0, 0); + color: rgb(255, 0, 0); + color: rgb(255, 0, 255); + color: rgb(255, 0, 255); +} + +test-red-green-blue-alpha-adjuster { + color: rgb(255, 0, 20); + color: rgb(255, 0, 51); + color: rgb(255, 20, 0); + color: rgb(255, 51, 0); + color: rgb(235.00000000000003, 0, 0); + color: rgb(204, 0, 0); + color: rgba(255, 0, 0, 0.2); +} + +test-rgb-adjuster { + color: rgb(255, 255, 0); + color: rgb(255, 255, 0); + color: rgb(0, 0, 0); + color: rgb(0, 0, 0); + color: rgb(127.5, 0, 0); +} + +test-hue-adjuster { + color: rgb(255, 85, 255); + color: rgb(255, 85, 255); + color: rgb(255, 85, 255); + color: rgb(255, 85, 255); + color: rgb(0, 0, 84.99999999999993); + color: rgb(0, 0, 84.99999999999993); + color: rgb(255, 0, 255); + color: rgb(255, 0, 255); +} + +test-lightness-saturation-adjuster { + color: rgb(102, 0, 102); + color: rgb(255, 101.99999999999997, 255); + color: rgb(153, 0, 153); + color: rgb(51, 0, 51); + color: rgb(153, 102, 153); + color: rgb(255, 0, 255); + color: rgb(229.5, 25.499999999999993, 229.5); + color: rgb(153, 102, 153); +} + +test-blackness-whiteness-adjuster { + color: rgb(204, 0, 0); + color: rgb(204, 0, 0); + color: rgb(255, 0, 0); + color: rgb(255, 0, 0); + color: rgb(255, 51, 51); + color: rgb(255, 51, 51); + color: rgb(255, 0, 0); + color: rgb(255, 0, 0); +} + +test-tint-shade-adjuster { + color: rgb(50.999999999999986, 0, 0); + color: rgb(255, 204, 204); +} + +test-blend-adjuster { + color: rgb(255, 127.5, 0); + color: rgb(255, 127.5, 0); + color: rgb(255, 127.5, 255); + color: rgb(255, 127.5, 0); +} + +test-contrast-adjuster { + color: rgb(191.25, 191.25, 0); + color: rgb(127.5, 127.5, 0); + color: rgb(63.75, 63.75, 0); +} + +test-combination-adjuster { + color: rgb(88.14750382701874, 45.50833333333334, 113.64750382701874); +} diff --git a/test/warn.css b/test/warn.css new file mode 100644 index 0000000000..702b819497 --- /dev/null +++ b/test/warn.css @@ -0,0 +1,48 @@ +test-color-mod { + color: color-mod(); +} + +test-color-adjusters { + color: color-mod(red red(20deg)); + color: color-mod(red blue(* 20)); + color: color-mod(red green(* blue)); + color: color-mod(red alpha(* 1)); + color: color-mod(red alpha(0 1)); + color: color-mod(red rgb(+ 0 255 0 0)); + color: color-mod(red rgb(* 0 255 0)); + color: color-mod(red rgb(100%)); + color: color-mod(red hue(blue)); + color: color-mod(red hue(20%)); + color: color-mod(red hue(+ 20em)); + color: color-mod(red hue(- 20em)); + color: color-mod(red hue(* 20%)); + color: color-mod(red lightness(20)); + color: color-mod(red lightness(+ 20)); + color: color-mod(red lightness(- 20)); + color: color-mod(red lightness(* 20)); + color: color-mod(red lightness(* 20 20)); + color: color-mod(red saturation(20)); + color: color-mod(red saturation(+ 20)); + color: color-mod(red saturation(- 20)); + color: color-mod(red saturation(* 20)); + color: color-mod(red saturation(* 20 20)); + color: color-mod(red blackness(20)); + color: color-mod(red blackness(+ 20)); + color: color-mod(red blackness(- 20)); + color: color-mod(red blackness(* 20)); + color: color-mod(red blackness(* 20 20)); + color: color-mod(red whiteness(20)); + color: color-mod(red whiteness(+ 20)); + color: color-mod(red whiteness(- 20)); + color: color-mod(red whiteness(* 20)); + color: color-mod(red whiteness(* 20 20)); + color: color-mod(red tint(20)); + color: color-mod(red tint(+ 20%)); + color: color-mod(red shade(20)); + color: color-mod(red shade(+ 20%)); + color: color-mod(yellow blend(20% 50%)); + color: color-mod(yellow blend(red 50)); + color: color-mod(yellow blend(red 50% blue)); + color: color-mod(yellow contrast(50)); + color: color-mod(yellow contrast(+ 50%)); +} From e55972761317a5acbddae23e1811663d77fd3acd Mon Sep 17 00:00:00 2001 From: Jonathan Neal Date: Wed, 17 Jan 2018 01:18:38 -0500 Subject: [PATCH 551/795] Round stringified color values - Round by 4 decimals for all percentages and alpha values - Round by 0 decimals for all legacy rgb values --- lib/color.js | 35 +++++++++++++++++++++-------------- test/basic.colors.expect.css | 8 ++++---- test/basic.expect.css | 30 +++++++++++++++--------------- 3 files changed, 40 insertions(+), 33 deletions(-) diff --git a/lib/color.js b/lib/color.js index 2860f80ed1..587ab0daea 100644 --- a/lib/color.js +++ b/lib/color.js @@ -127,9 +127,9 @@ export default class Color { const color = color2hsl(this.color); const isOpaque = color.alpha === 1; const hue = color.hue; - const saturation = color.saturation * 100; - const lightness = color.lightness * 100; - const alpha = color.alpha * 100; + const saturation = round(color.saturation * 100, 4); + const lightness = round(color.lightness * 100, 4); + const alpha = round(color.alpha * 100, 4); return `hsl(${hue} ${saturation}% ${lightness}%${isOpaque ? '' @@ -140,9 +140,9 @@ export default class Color { const color = color2hwb(this.color); const isOpaque = color.alpha === 1; const hue = color.hue; - const whiteness = color.whiteness * 100; - const blackness = color.blackness * 100; - const alpha = color.alpha * 100; + const whiteness = round(color.whiteness * 100, 4); + const blackness = round(color.blackness * 100, 4); + const alpha = round(color.alpha * 100, 4); return `hwb(${hue} ${whiteness}% ${blackness}%${isOpaque ? '' @@ -152,10 +152,10 @@ export default class Color { toRGB() { const color = color2rgb(this.color); const isOpaque = color.alpha === 1; - const red = color.red * 100; - const green = color.green * 100; - const blue = color.blue * 100; - const alpha = color.alpha * 100; + const red = round(color.red * 100, 4); + const green = round(color.green * 100, 4); + const blue = round(color.blue * 100, 4); + const alpha = round(color.alpha * 100, 4); return `rgb(${red}% ${green}% ${blue}%${isOpaque ? '' @@ -166,10 +166,10 @@ export default class Color { const color = color2rgb(this.color); const isOpaque = color.alpha === 1; const name = isOpaque ? 'rgb' : 'rgba'; - const red = color.red * 255; - const green = color.green * 255; - const blue = color.blue * 255; - const alpha = color.alpha; + const red = round(color.red * 255, 0); + const green = round(color.green * 255, 0); + const blue = round(color.blue * 255, 0); + const alpha = round(color.alpha, 4); return `${name}(${red}, ${green}, ${blue}${isOpaque ? '' @@ -547,6 +547,13 @@ function lvw2saturation(lightness, value, whiteness) { : (value - whiteness) / (2 - value - whiteness); } +/* Round to decimal place +/* ========================================================================== */ + +function round(value, decimals) { + return Number(`${Math.round(`${value}e${decimals}`)}e-${decimals}`); +} + /* Match /* ========================================================================== */ diff --git a/test/basic.colors.expect.css b/test/basic.colors.expect.css index ebe329f0bc..7b05a174df 100644 --- a/test/basic.colors.expect.css +++ b/test/basic.colors.expect.css @@ -23,11 +23,11 @@ test-color-mod { } test-red-green-blue-alpha-adjuster { - color: rgb(100% 0% 7.8431372549019605%); + color: rgb(100% 0% 7.8431%); color: rgb(100% 0% 20%); - color: rgb(100% 7.8431372549019605% 0%); + color: rgb(100% 7.8431% 0%); color: rgb(100% 20% 0%); - color: rgb(92.15686274509804% 0% 0%); + color: rgb(92.1569% 0% 0%); color: rgb(80% 0% 0%); color: rgb(100% 0% 0% / 20%); } @@ -92,5 +92,5 @@ test-contrast-adjuster { } test-combination-adjuster { - color: rgb(34.56764855961519% 17.846405228758172% 44.56764855961519%); + color: rgb(34.5676% 17.8464% 44.5676%); } diff --git a/test/basic.expect.css b/test/basic.expect.css index d9bcee77ed..84fe4373d9 100644 --- a/test/basic.expect.css +++ b/test/basic.expect.css @@ -27,7 +27,7 @@ test-red-green-blue-alpha-adjuster { color: rgb(255, 0, 51); color: rgb(255, 20, 0); color: rgb(255, 51, 0); - color: rgb(235.00000000000003, 0, 0); + color: rgb(235, 0, 0); color: rgb(204, 0, 0); color: rgba(255, 0, 0, 0.2); } @@ -37,7 +37,7 @@ test-rgb-adjuster { color: rgb(255, 255, 0); color: rgb(0, 0, 0); color: rgb(0, 0, 0); - color: rgb(127.5, 0, 0); + color: rgb(128, 0, 0); } test-hue-adjuster { @@ -45,20 +45,20 @@ test-hue-adjuster { color: rgb(255, 85, 255); color: rgb(255, 85, 255); color: rgb(255, 85, 255); - color: rgb(0, 0, 84.99999999999993); - color: rgb(0, 0, 84.99999999999993); + color: rgb(0, 0, 85); + color: rgb(0, 0, 85); color: rgb(255, 0, 255); color: rgb(255, 0, 255); } test-lightness-saturation-adjuster { color: rgb(102, 0, 102); - color: rgb(255, 101.99999999999997, 255); + color: rgb(255, 102, 255); color: rgb(153, 0, 153); color: rgb(51, 0, 51); color: rgb(153, 102, 153); color: rgb(255, 0, 255); - color: rgb(229.5, 25.499999999999993, 229.5); + color: rgb(230, 25, 230); color: rgb(153, 102, 153); } @@ -74,23 +74,23 @@ test-blackness-whiteness-adjuster { } test-tint-shade-adjuster { - color: rgb(50.999999999999986, 0, 0); + color: rgb(51, 0, 0); color: rgb(255, 204, 204); } test-blend-adjuster { - color: rgb(255, 127.5, 0); - color: rgb(255, 127.5, 0); - color: rgb(255, 127.5, 255); - color: rgb(255, 127.5, 0); + color: rgb(255, 128, 0); + color: rgb(255, 128, 0); + color: rgb(255, 128, 255); + color: rgb(255, 128, 0); } test-contrast-adjuster { - color: rgb(191.25, 191.25, 0); - color: rgb(127.5, 127.5, 0); - color: rgb(63.75, 63.75, 0); + color: rgb(191, 191, 0); + color: rgb(128, 128, 0); + color: rgb(64, 64, 0); } test-combination-adjuster { - color: rgb(88.14750382701874, 45.50833333333334, 113.64750382701874); + color: rgb(88, 46, 114); } From 16bd403e37cdbb8696dbdb7d6937cd93e248b005 Mon Sep 17 00:00:00 2001 From: Jonathan Neal Date: Wed, 17 Jan 2018 01:19:10 -0500 Subject: [PATCH 552/795] 1.1.0 --- CHANGELOG.md | 4 ++++ package.json | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c609a5682a..aedd457c01 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # Changes to PostCSS color-mod() Function +### 1.1.0 (January 17, 2018) + +- Round stringified color values + ### 1.0.0 (January 16, 2018) - Initial version diff --git a/package.json b/package.json index 0ad395d5e6..13b59021a9 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "postcss-color-mod-function", - "version": "1.0.0", + "version": "1.1.0", "description": "Modify colors using the color-mod() function in CSS", "author": "Jonathan Neal ", "license": "CC0-1.0", From 4e4de6e9904d61d6ae85372164f27a46325b3674 Mon Sep 17 00:00:00 2001 From: Jonathan Neal Date: Wed, 17 Jan 2018 18:48:43 -0500 Subject: [PATCH 553/795] Add various improvements - Use 0 - 100 for color and alpha channels instead of 0 to 1 - Restrict colors to 0 - 100 for color channels - Restrict hue by a 360 modulus - Reverse blend/blenda percentage calculations (the spec has this reversed) - Stringify to 10 digits of precision for percentages and alpha values (like Sass 3.5.0) - Use big.js for more precise calculatons --- lib/color.js | 330 ++++++++++++++++++++--------------- lib/transform.js | 120 +++++++------ package.json | 1 + test/basic.colors.expect.css | 76 +++++--- test/basic.css | 56 ++++-- test/basic.expect.css | 70 +++++--- 6 files changed, 391 insertions(+), 262 deletions(-) diff --git a/lib/color.js b/lib/color.js index 587ab0daea..d77de6e72f 100644 --- a/lib/color.js +++ b/lib/color.js @@ -1,3 +1,5 @@ +import number from 'big.js'; + export default class Color { constructor(color) { this.color = Object(Object(color).color || color); @@ -97,8 +99,8 @@ export default class Color { shade(percentage) { const hwb = color2hwb(this.color); - const shade = { hue: 0, whiteness: 1, blackness: 0, colorspace: 'hwb' }; - const colorspace = 'hwb'; + const shade = { hue: 0, whiteness: 0, blackness: 100, colorspace: 'hwb' }; + const colorspace = 'rgb'; return percentage === undefined ? hwb.blackness @@ -107,8 +109,8 @@ export default class Color { tint(percentage) { const hwb = color2hwb(this.color); - const tint = { hue: 0, whiteness: 0, blackness: 1, colorspace: 'hwb' }; - const colorspace = 'hwb'; + const tint = { hue: 0, whiteness: 100, blackness: 0, colorspace: 'hwb' }; + const colorspace = 'rgb'; return percentage === undefined ? hwb.blackness @@ -124,68 +126,23 @@ export default class Color { } toHSL() { - const color = color2hsl(this.color); - const isOpaque = color.alpha === 1; - const hue = color.hue; - const saturation = round(color.saturation * 100, 4); - const lightness = round(color.lightness * 100, 4); - const alpha = round(color.alpha * 100, 4); - - return `hsl(${hue} ${saturation}% ${lightness}%${isOpaque - ? '' - : ` / ${alpha}%`})`; + return color2hslString(this.color); } toHWB() { - const color = color2hwb(this.color); - const isOpaque = color.alpha === 1; - const hue = color.hue; - const whiteness = round(color.whiteness * 100, 4); - const blackness = round(color.blackness * 100, 4); - const alpha = round(color.alpha * 100, 4); - - return `hwb(${hue} ${whiteness}% ${blackness}%${isOpaque - ? '' - : ` / ${alpha}%`})`; + return color2hwbString(this.color); } toRGB() { - const color = color2rgb(this.color); - const isOpaque = color.alpha === 1; - const red = round(color.red * 100, 4); - const green = round(color.green * 100, 4); - const blue = round(color.blue * 100, 4); - const alpha = round(color.alpha * 100, 4); - - return `rgb(${red}% ${green}% ${blue}%${isOpaque - ? '' - : ` / ${alpha}%`})`; + return color2rgbString(this.color); } toRGBLegacy() { - const color = color2rgb(this.color); - const isOpaque = color.alpha === 1; - const name = isOpaque ? 'rgb' : 'rgba'; - const red = round(color.red * 255, 0); - const green = round(color.green * 255, 0); - const blue = round(color.blue * 255, 0); - const alpha = round(color.alpha, 4); - - return `${name}(${red}, ${green}, ${blue}${isOpaque - ? '' - : `, ${alpha}`})`; + return color2rgbLegacyString(this.color); } - toString(rawcolorspace) { - const colorspace = rawcolorspace || this.color.colorspace; - - const color = colorspace === 'hsl' - ? this.toHSL() - : colorspace === 'hwb' - ? this.toHWB() - : this.toRGB(); - - return color; + toString() { + return color2string(this.color); } } @@ -193,17 +150,20 @@ export default class Color { /* ========================================================================== */ function blend(base, color, percentage, colorspace, isBlendingAlpha) { // eslint-disable-line max-params - const subtraction = 1 - percentage; + const addition = number(percentage).div(100); + const subtraction = number(1).minus(addition); if (colorspace === 'hsl') { const { hue: h1, saturation: s1, lightness: l1, alpha: a1 } = color2hsl(base); const { hue: h2, saturation: s2, lightness: l2, alpha: a2 } = color2hsl(color); const [hue, saturation, lightness, alpha] = [ - h1 * percentage + h2 * subtraction, - s1 * percentage + s2 * subtraction, - l1 * percentage + l2 * subtraction, - isBlendingAlpha ? a1 * percentage + a2 * subtraction : a1 + Number(number(h1).times(subtraction).plus(number(h2).times(addition))), + Number(number(s1).times(subtraction).plus(number(s2).times(addition))), + Number(number(l1).times(subtraction).plus(number(l2).times(addition))), + isBlendingAlpha + ? Number(number(a1).times(subtraction).plus(number(a2).times(addition))) + : a1 ]; return { hue, saturation, lightness, alpha, colorspace: 'hsl' }; @@ -212,10 +172,10 @@ function blend(base, color, percentage, colorspace, isBlendingAlpha) { // eslint const { hue: h2, whiteness: w2, blackness: b2, alpha: a2 } = color2hwb(color); const [hue, whiteness, blackness, alpha] = [ - h1 * percentage + h2 * subtraction, - w1 * percentage + w2 * subtraction, - b1 * percentage + b2 * subtraction, - isBlendingAlpha ? a1 * percentage + a2 * subtraction : a1 + Number(number(h1).times(subtraction).plus(number(h2).times(addition))), + Number(number(w1).times(subtraction).plus(number(w2).times(addition))), + Number(number(b1).times(subtraction).plus(number(b2).times(addition))), + isBlendingAlpha ? Number(number(a1).times(subtraction).plus(number(a2).times(addition))) : a1 ]; return { hue, whiteness, blackness, alpha, colorspace: 'hwb' }; @@ -224,10 +184,10 @@ function blend(base, color, percentage, colorspace, isBlendingAlpha) { // eslint const { red: r2, green: g2, blue: b2, alpha: a2 } = color2rgb(color); const [red, green, blue, alpha] = [ - r1 * percentage + r2 * subtraction, - g1 * percentage + g2 * subtraction, - b1 * percentage + b2 * subtraction, - isBlendingAlpha ? a1 * percentage + a2 * subtraction : a1 + Number(number(r1).times(subtraction).plus(number(r2).times(addition))), + Number(number(g1).times(subtraction).plus(number(g2).times(addition))), + Number(number(b1).times(subtraction).plus(number(b2).times(addition))), + isBlendingAlpha ? Number(number(a1).times(subtraction).plus(number(a2).times(addition))) : a1 ]; return { red, green, blue, alpha, colorspace: 'rgb' }; @@ -246,25 +206,15 @@ function assign(base, channels) { const isHue = channel === 'hue'; const isRGB = !isHue && blueGreenRedMatch.test(channel); - // value of the channel - const adjustment = channels[channel]; - - // value limitations - const min = 0; - const max = isHue ? 360 : 1; - - // updated value - const value = Math.min(Math.max(parseFloat(adjustment), min), max); + // normalized value of the channel + const value = normalize(channels[channel], channel); // assign channel to new object - if (isHue) { - color.hue = value; - } else { - color[channel] = value; - - color.hue = isRGB - ? rgb2hue(color.red, color.green, color.blue, base.hue || 0) - : base.hue; + color[channel] = value; + + if (isRGB) { + // conditionally preserve the hue + color.hue = rgb2hue(color.red, color.green, color.blue, base.hue || 0); } } ); @@ -272,6 +222,21 @@ function assign(base, channels) { return color; } +function normalize(value, channel) { + // detect channel + const isHue = channel === 'hue'; + + // value limitations + const min = 0; + const max = isHue ? 360 : 100; + + const modifiedValue = Math.min(Math.max(isHue + ? number(value).mod(360) + : value, min), max); + + return modifiedValue +} + /* Convert colors /* ========================================================================== */ @@ -302,16 +267,28 @@ function color2rgb(color) { /* Convert HSL to RGB /* ========================================================================== */ -function hsl2rgb({ hue, saturation, lightness, alpha = 1 }) { - const t2 = lightness <= 0.5 - ? lightness * (saturation + 1) - : lightness + saturation - lightness * saturation; +function hsl2rgb({ hue, saturation, lightness, alpha = 100 }) { + const t2 = lightness <= 50 + ? Number( + number(lightness).div(100).times( + number(saturation).div(100).plus(1) + ) + ) + : Number( + number(lightness).div(100).plus( + number(saturation).div(100) + ).minus( + number(lightness).div(100).times( + number(saturation).div(100) + ) + ) + ); - const t1 = lightness * 2 - t2; + const t1 = Number(number(lightness).div(100).times(2).minus(t2)); - const red = hue2rgb(t1, t2, hue / 60 + 2); - const green = hue2rgb(t1, t2, hue / 60); - const blue = hue2rgb(t1, t2, hue / 60 - 2); + const red = hue2channel(t1, t2, Number(number(hue).div(60).plus(2))); + const green = hue2channel(t1, t2, Number(number(hue).div(60))); + const blue = hue2channel(t1, t2, Number(number(hue).div(60).minus(2))); return { hue, red, green, blue, alpha, colorspace: 'rgb' }; } @@ -319,16 +296,26 @@ function hsl2rgb({ hue, saturation, lightness, alpha = 1 }) { /* Convert HWB to RGB /* ========================================================================== */ -function hwb2rgb({ hue, whiteness, blackness, alpha = 1 }) { - const ratio = whiteness + blackness; - const rwhiteness = ratio > 1 ? whiteness / ratio : whiteness; - const rblackness = ratio > 1 ? blackness / ratio : blackness; +function hwb2rgb({ hue, whiteness, blackness, alpha = 100 }) { + const ratio = Number(number(whiteness).plus(blackness)); + const rwhiteness = ratio > 100 ? Number(number(whiteness).div(ratio)) : whiteness; + const rblackness = ratio > 100 ? Number(number(blackness).div(ratio)) : blackness; + const value = Number(number(100).minus(rblackness)); + const hexagon = number(6).times(hue).div(360); - const value = 1 - rblackness; - const hexagon = 6 * hue / 360; const hexagonFloor = Math.floor(hexagon); - const hexagonF = hexagonFloor % 6 ? 1 - (hexagon - hexagonFloor) : hexagon - hexagonFloor; - const interpolation = rwhiteness + hexagonF * (value - rwhiteness); + + const hexagonF = hexagonFloor % 6 + ? number(1).minus( + hexagon.minus(hexagonFloor) + ) + : hexagon.minus(hexagonFloor); + + const interpolation = Number(number(rwhiteness).plus( + hexagonF.times( + number(value).minus(rwhiteness) + ) + )); const [red, green, blue] = hexagonFloor % 6 === 5 ? [value, rwhiteness, interpolation] @@ -348,11 +335,11 @@ function hwb2rgb({ hue, whiteness, blackness, alpha = 1 }) { /* Convert RGB to HSL /* ========================================================================== */ -function rgb2hsl({ red, green, blue, alpha = 1 }, fallback = 0) { // eslint-disable-line max-params +function rgb2hsl({ red, green, blue, alpha = 100 }, fallback = 0) { // eslint-disable-line max-params const hue = rgb2hue(red, green, blue, fallback); const whiteness = rgb2whiteness(red, green, blue); const value = rgb2value(red, green, blue); - const lightness = wv2lightness(whiteness, value); + const lightness = wv2lightness(whiteness, value); const saturation = lvw2saturation(lightness, value, whiteness); return { hue, saturation, lightness, alpha, colorspace: 'hsl' }; @@ -361,11 +348,11 @@ function rgb2hsl({ red, green, blue, alpha = 1 }, fallback = 0) { // eslint-disa /* Convert RGB to HWB /* ========================================================================== */ -function rgb2hwb({ red, green, blue, alpha = 1 }, fallback = 0) { // eslint-disable-line max-params +function rgb2hwb({ red, green, blue, alpha = 100 }, fallback = 0) { // eslint-disable-line max-params const hue = rgb2hue(red, green, blue, fallback); const whiteness = rgb2whiteness(red, green, blue); const value = rgb2value(red, green, blue); - const blackness = 1 - value; + const blackness = Number(number(100).minus(value)); return { hue, whiteness, blackness, alpha, colorspace: 'hwb' }; } @@ -373,18 +360,22 @@ function rgb2hwb({ red, green, blue, alpha = 1 }, fallback = 0) { // eslint-disa /* Convert Hue to RGB /* ========================================================================== */ -function hue2rgb(t1, t2, hue) { - const huerange = hue < 0 ? hue + 6 : hue >= 6 ? hue - 6 : hue; +function hue2channel(t1, t2, hue) { + const huerange = hue < 0 + ? number(hue).plus(6) + : hue >= 6 + ? number(hue).minus(6) + : number(hue); const rgb = huerange < 1 - ? (t2 - t1) * hue + t1 + ? Number(number(number(t2).minus(t1)).times(hue).plus(t1)) : hue < 3 ? t2 : hue < 4 - ? (t2 - t1) * (4 - hue) + t1 + ? Number(number(number(t2).minus(t1)).times(number(4).minus(hue)).plus(t1)) : t1; - return rgb; + return Number(number(rgb).times(100)); } /* Convert RGB to Hue @@ -399,10 +390,10 @@ function rgb2hue(red, green, blue, fallback) { // eslint-disable-line max-params return fallback; } else { const segment = value === red - ? (green - blue) / chroma + ? number(green).minus(blue).div(chroma) : value === green - ? (blue - red) / chroma - : (red - green) / chroma; + ? number(blue).minus(red).div(chroma) + : number(red).minus(green).div(chroma); const shift = value === red ? segment < 0 @@ -412,7 +403,7 @@ function rgb2hue(red, green, blue, fallback) { // eslint-disable-line max-params ? 120 / 60 : 240 / 60; - const hue = (segment + shift) * 60; + const hue = Number(number(segment).plus(shift).times(60)); return hue; } @@ -433,7 +424,7 @@ function contrast(color, percentage) { // hwb(X, 100%, 0%), where X is the hue angle of the color ? { hue: hwb.hue, whiteness: 100, blackness: 0, alpha: hwb.alpha, colorspace: 'hwb' } // otherwise, hwb(X, 0%, 100%), where X is the hue angle of the color - : { hue: hwb.hue, whiteness: 0, blackness: 1, alpha: hwb.alpha, colorspace: 'hwb' }; + : { hue: hwb.hue, whiteness: 0, blackness: 100, alpha: hwb.alpha, colorspace: 'hwb' }; // contrast ratio const contrastRatio = colors2contrast(color, maxContrastColor); @@ -457,9 +448,9 @@ function colors2contrast(color1, color2) { return l1 > l2 // if l1 is the relative luminance of the lighter of the colors - ? (l1 + 0.05) / (l2 + 0.05) + ? Number(number(l1).plus(0.05).div(number(l2).plus(0.05))) // otherwise, if l2 is the relative luminance of the lighter of the colors - : (l2 + 0.05) / (l2 + 0.05); + : Number(number(l2).plus(0.05).div(number(l2).plus(0.05))); } function rgb2luminance(red, green, blue) { @@ -470,12 +461,16 @@ function rgb2luminance(red, green, blue) { ]; // https://drafts.csswg.org/css-color/#luminance - return 0.2126 * redLuminance + 0.7152 * greenLuminance + 0.0722 * blueLuminance; + const luminance = Number(number(0.2126).times(redLuminance).plus(number(0.7152).times(greenLuminance)).plus(number(0.0722).times(blueLuminance))); + + return luminance; } function channel2luminance(value) { // https://drafts.csswg.org/css-color/#luminance - return value <= 0.03928 ? value / 12.92 : Math.pow((value + 0.055) / 1.055, 2.4); + const luminance = value <= 0.03928 ? Number(number(value).div(12.92)) : Math.pow(number(value).plus(0.055).div(1.055), 2.4); + + return luminance; } // return the smallest contrast ratio from a color and a maximum contrast (credit: @thetalecrafter) @@ -483,18 +478,18 @@ function colors2contrastRatioColor(hwb, maxHWB) { const modifiedHWB = Object.assign({}, hwb); // values to be used for linear interpolations in HWB space - let minW = hwb.whiteness; - let minB = hwb.blackness; - let maxW = maxHWB.whiteness; - let maxB = maxHWB.blackness; + let minW = number(hwb.whiteness); + let minB = number(hwb.blackness); + let maxW = number(maxHWB.whiteness); + let maxB = number(maxHWB.blackness); // find the color with the smallest contrast ratio with the base color that is greater than 4.5 - while (Math.abs(minW - maxW) > 1 || Math.abs(minB - maxB) > 1) { - const midW = Math.round((maxW + minW) / 2); - const midB = Math.round((maxB + minB) / 2); + while (Number(minW.minus(maxW).abs()) > 100 || Number(minB.minus(maxB).abs()) > 100) { + const midW = maxW.plus(minW).div(2).round(); + const midB = maxB.plus(minB).div(2).round(); - modifiedHWB.whiteness = midW; - modifiedHWB.blackness = midB; + modifiedHWB.whiteness = Number(midW); + modifiedHWB.blackness = Number(midB); if (colors2contrast(modifiedHWB, hwb) > 4.5) { maxW = midW; @@ -526,14 +521,14 @@ function rgb2value(red, green, blue) { /* ========================================================================== */ function wv2lightness(whiteness, value) { - return (whiteness + value) / 2; + return Number(number(whiteness).plus(value).div(2)); } /* Convert Value and Whiteness to Chroma /* ========================================================================== */ function vw2chroma(value, whiteness) { - return value - whiteness; + return Number(number(value).minus(whiteness)); } /* Convert Lightness, Value, and Whiteness to Saturation @@ -542,19 +537,76 @@ function vw2chroma(value, whiteness) { function lvw2saturation(lightness, value, whiteness) { return whiteness === value ? 0 - : lightness < 0.5 - ? (value - whiteness) / (value + whiteness) - : (value - whiteness) / (2 - value - whiteness); + : lightness < 50 + ? Number(number(value).minus(whiteness).div(number(value).plus(whiteness)).times(100)) + : Number(number(value).minus(whiteness).div(number(200).minus(value).minus(whiteness)).times(100)); } -/* Round to decimal place +/* Match /* ========================================================================== */ -function round(value, decimals) { - return Number(`${Math.round(`${value}e${decimals}`)}e-${decimals}`); -} +const blueGreenRedMatch = /^(blue|green|red)$/i; -/* Match +/* Stringifiers /* ========================================================================== */ -const blueGreenRedMatch = /^(blue|green|red)$/i; +function color2string(color) { + return color.colorspace === 'hsl' + ? color2hslString(color) + : color.colorspace === 'hwb' + ? color2hwbString(color) + : color2rgbString(color); +} + +function color2hslString(color) { + const hsl = color2hsl(color); + const isOpaque = hsl.alpha === 100; + const hue = hsl.hue; + const saturation = number(hsl.saturation).round(10); + const lightness = number(hsl.lightness).round(10); + const alpha = number(hsl.alpha).round(10); + + return `hsl(${hue} ${saturation}% ${lightness}%${isOpaque + ? '' + : ` / ${alpha}%`})`; +} + +function color2hwbString(color) { + const hwb = color2hwb(color); + const isOpaque = hwb.alpha === 100; + const hue = hwb.hue; + const whiteness = number(hwb.whiteness).round(10); + const blackness = number(hwb.blackness).round(10); + const alpha = number(hwb.alpha).round(10); + + return `hwb(${hue} ${whiteness}% ${blackness}%${isOpaque + ? '' + : ` / ${alpha}%`})`; +} + +function color2rgbString(color) { + const rgb = color2rgb(color); + const isOpaque = rgb.alpha === 100; + const red = number(rgb.red).round(10); + const green = number(rgb.green).round(10); + const blue = number(rgb.blue).round(10); + const alpha = number(rgb.alpha).round(10); + + return `rgb(${red}% ${green}% ${blue}%${isOpaque + ? '' + : ` / ${alpha}%`})`; +} + +function color2rgbLegacyString(color) { + const rgb = color2rgb(color); + const isOpaque = rgb.alpha === 100; + const name = isOpaque ? 'rgb' : 'rgba'; + const red = number(rgb.red).times(2.55).round(0); + const green = number(rgb.green).times(2.55).round(0); + const blue = number(rgb.blue).times(2.55).round(0); + const alpha = number(rgb.alpha).div(100).round(10); + + return `${name}(${red}, ${green}, ${blue}${isOpaque + ? '' + : `, ${alpha}`})`; +} diff --git a/lib/transform.js b/lib/transform.js index 00782a8d6c..64c2e79662 100644 --- a/lib/transform.js +++ b/lib/transform.js @@ -2,6 +2,7 @@ import Color from './color'; import manageUnresolved from './manage-unresolved'; import names from 'color-name'; +import number from 'big.js'; import parser from 'postcss-values-parser'; /* Transform AST @@ -50,7 +51,7 @@ function transformColor(node, opts) { // return a transformed rgb/rgba color function function transformRGBFunction(node, opts) { - const [red, green, blue, alpha = 1] = transformArgsByParams(node, [ + const [red, green, blue, alpha = 100] = transformArgsByParams(node, [ // [ {3} | {3} ] [ / ]? [transformRGBValue, transformRGBValue, transformRGBValue, isSlash, transformAlpha], // #{3} [ , ]? ] @@ -68,7 +69,7 @@ function transformRGBFunction(node, opts) { // return a transformed hsl/hsla color function function transformHSLFunction(node, opts) { - const [hue, saturation, lightness, alpha = 1] = transformArgsByParams(node, [ + const [hue, saturation, lightness, alpha = 100] = transformArgsByParams(node, [ // {2} [ / ]? [transformHue, transformPercentage, transformPercentage, isSlash, transformAlpha], // hue, #{2} [ , ]? ] @@ -86,7 +87,7 @@ function transformHSLFunction(node, opts) { // return a transformed hwb color function function transformHWBFunction(node, opts) { - const [hue, whiteness, blackness, alpha = 1] = transformArgsByParams(node, [ + const [hue, whiteness, blackness, alpha = 100] = transformArgsByParams(node, [ // [ / ]? [transformHue, transformPercentage, transformPercentage, isSlash, transformAlpha] ]); @@ -107,7 +108,13 @@ function transformColorModFunction(node, opts) { if (colorOrHueNode !== undefined) { const color = isHue(colorOrHueNode) - ? new Color({ hue: transformHue(colorOrHueNode, opts), saturation: 1, lightness: 0.5, alpha: 1, colorspace: 'hsl' }) + ? new Color({ + hue: transformHue(colorOrHueNode, opts), + saturation: 100, + lightness: 50, + alpha: 100, + colorspace: 'hsl' + }) : transformColor(colorOrHueNode, opts); if (color) { @@ -129,10 +136,10 @@ function transformHexColor(node, opts) { const [r, g, b, a, rr, gg, bb, aa] = (node.value.match(hexColorMatch) || []).slice(1); const color = new Color({ - red: rr !== undefined ? parseInt(rr, 16) / 255 : r !== undefined ? parseInt(r + r, 16) / 255 : 0, - green: gg !== undefined ? parseInt(gg, 16) / 255 : g !== undefined ? parseInt(g + g, 16) / 255 : 0, - blue: bb !== undefined ? parseInt(bb, 16) / 255 : b !== undefined ? parseInt(b + b, 16) / 255 : 0, - alpha: aa !== undefined ? parseInt(aa, 16) / 255 : a !== undefined ? parseInt(a + a, 16) / 255 : 1 + red: rr !== undefined ? Number(number(parseInt(rr, 16)).div(2.55)) : r !== undefined ? Number(number(parseInt(r + r, 16)).div(2.55)) : 0, + green: gg !== undefined ? Number(number(parseInt(gg, 16)).div(2.55)) : g !== undefined ? Number(number(parseInt(g + g, 16)).div(2.55)) : 0, + blue: bb !== undefined ? Number(number(parseInt(bb, 16)).div(2.55)) : b !== undefined ? Number(number(parseInt(b + b, 16)).div(2.55)) : 0, + alpha: aa !== undefined ? Number(number(parseInt(aa, 16)).div(2.55)) : a !== undefined ? Number(number(parseInt(a + a, 16)).div(2.55)) : 100 }); return color; @@ -147,7 +154,13 @@ function transformNamedColor(node, opts) { // const [red, green, blue] = names[node.value]; - const color = new Color({ red: red / 255, green: green / 255, blue: blue / 255, alpha: 1, colorspace: 'rgb' }); + const color = new Color({ + red: Number(number(red).div(2.55)), + green: Number(number(green).div(2.55)), + blue: Number(number(blue).div(2.55)), + alpha: 100, + colorspace: 'rgb' + }); return color; } else { @@ -210,19 +223,19 @@ function transformAlphaBlueGreenRedAdjuster(base, node, opts) { // normalized channel name const channel = node.value.toLowerCase().replace(alphaMatch, 'alpha'); - const existingValue = base[channel](); + const existingValue = number(base[channel]()); - const modifiedValue = adjustment + const modifiedValue = adjustment !== undefined ? operatorOrValue === '+' - ? existingValue + adjustment + ? existingValue.plus(adjustment) : operatorOrValue === '-' - ? existingValue - adjustment + ? existingValue.minus(adjustment) : operatorOrValue === '*' - ? existingValue * adjustment + ? existingValue.times(adjustment) : adjustment : operatorOrValue; - const modifiedColor = base[channel](modifiedValue); + const modifiedColor = base[channel](Number(modifiedValue)); return modifiedColor; } else { @@ -247,41 +260,41 @@ function transformRGBAdjuster(base, node, opts) { if (arg2 !== undefined && arg2.color) { const modifiedColor = base.rgb( arg1 === '+' - ? base.red() + arg2.red() - : base.red() - arg2.red(), + ? Number(number(base.red()).plus(arg2.red())) + : Number(number(base.red()).minus(arg2.red())), arg1 === '+' - ? base.green() + arg2.green() - : base.green() - arg2.green(), + ? Number(number(base.green()).plus(arg2.green())) + : Number(number(base.green()).minus(arg2.green())), arg1 === '+' - ? base.blue() + arg2.blue() - : base.blue() - arg2.blue() + ? Number(number(base.blue()).plus(arg2.blue())) + : Number(number(base.blue()).minus(arg2.blue())) ); return modifiedColor; } else if (arg1 !== undefined && minusPlusMatch.test(arg1)) { const modifiedColor = base.rgb( arg1 === '+' - ? base.red() + arg2 - : base.red() - arg2, + ? Number(number(base.red()).plus(arg2)) + : Number(number(base.red()).minus(arg2)), arg1 === '+' - ? base.green() + arg3 - : base.green() - arg3, + ? Number(number(base.green()).plus(arg3)) + : Number(number(base.green()).minus(arg3)), arg1 === '+' - ? base.blue() + arg4 - : base.blue() - arg4 + ? Number(number(base.blue()).plus(arg4)) + : Number(number(base.blue()).minus(arg4)) ); return modifiedColor; } else if (arg1 !== undefined && arg2 !== undefined) { const modifiedColor = base.rgb( - base.red() * arg2, - base.green() * arg2, - base.blue() * arg2 + Number(number(base.red()).times(arg2)), + Number(number(base.green()).times(arg2)), + Number(number(base.blue()).times(arg2)) ); return modifiedColor; } else { - return manageUnresolved(node, opts, node.value, `Expected a valid rgb() adjuster)`); + return manageUnresolved(node, opts, node.value, `Expected a valid rgb() adjuster`); } } @@ -320,7 +333,7 @@ function transformContrastAdjuster(base, node, opts) { // return a transformed color using a hue adjustment function transformHueAdjuster(base, node, opts) { - const [operatorOrHue, rawAdjustment] = transformArgsByParams(node, [ + const [operatorOrHue, adjustment] = transformArgsByParams(node, [ // [ + | - | * ] [transformMinusPlusTimesOperator, transformHue], // @@ -329,23 +342,18 @@ function transformHueAdjuster(base, node, opts) { if (operatorOrHue !== undefined) { const existingHue = base.hue(); - const adjustment = parseFloat(rawAdjustment); - const rawModifiedValue = adjustment + const modifiedValue = adjustment !== undefined ? operatorOrHue === '+' - ? existingHue + adjustment + ? number(existingHue).plus(adjustment) : operatorOrHue === '-' - ? existingHue - adjustment + ? number(existingHue).minus(adjustment) : operatorOrHue === '*' - ? existingHue * adjustment - : adjustment - : parseFloat(operatorOrHue); + ? number(existingHue).times(adjustment) + : number(adjustment) + : number(operatorOrHue); - const modifiedValue = rawModifiedValue < 0 - ? 360 + rawModifiedValue % 360 - : rawModifiedValue % 360; - - return base.hue(modifiedValue); + return base.hue(Number(modifiedValue)); } else { return manageUnresolved(node, opts, node.value, `Expected a valid hue() function)`); } @@ -360,18 +368,20 @@ function transformBlacknessLightnessSaturationWhitenessAdjuster(base, node, opts ]); if (operatorOrValue !== undefined) { - const existingValue = base[channel](); + const existingValue = number(base[channel]()); const adjustment = parseFloat(rawAdjustment); - const modifiedValue = adjustment + const rawModifiedValue = !isNaN(adjustment) ? operatorOrValue === '+' - ? existingValue + adjustment + ? existingValue.plus(adjustment) : operatorOrValue === '-' - ? existingValue - adjustment + ? existingValue.minus(adjustment) : operatorOrValue === '*' - ? existingValue * adjustment - : adjustment - : parseFloat(operatorOrValue); + ? existingValue.times(adjustment) + : number(adjustment) + : number(operatorOrValue); + + const modifiedValue = Number(rawModifiedValue); return base[channel](modifiedValue); } else { @@ -413,7 +423,7 @@ function transformColorSpace(node, opts) { function transformAlpha(node, opts) { if (isNumber(node)) { // - return parseFloat(node.value); + return Number(number(node.value).times(100)); } else if (isPercentage(node)) { // return transformPercentage(node, opts); @@ -439,7 +449,7 @@ function transformRGBValue(node, opts) { function transformRGBNumber(node, opts) { if (isNumber(node)) { // - return parseFloat(node.value) / 255; + return Number(number(node.value).div(2.55)); } else { return manageUnresolved(node, opts, node.value, `Expected a valid RGB value)`); } @@ -459,7 +469,7 @@ function transformHue(node, opts) { function transformPercentage(node, opts) { if (isPercentage(node)) { // - return parseFloat(node.value) / 100; + return Number(number(node.value)); } else { return manageUnresolved(node, opts, node.value, `Expected a valid hue`); } @@ -638,7 +648,7 @@ function isTimesOperator(node) { // return whether the percentage is valid function isPercentage(node) { - return Object(node).type === 'number' && node.unit === '%'; + return Object(node).type === 'number' && (node.unit === '%' || node.value === '0'); } /* Matchers diff --git a/package.json b/package.json index 13b59021a9..57a31487de 100644 --- a/package.json +++ b/package.json @@ -26,6 +26,7 @@ "node": ">=4.0.0" }, "dependencies": { + "big.js": "^5.0.3", "color-name": "^1.1.3", "postcss": "^6.0", "postcss-values-parser": "^1.3.1" diff --git a/test/basic.colors.expect.css b/test/basic.colors.expect.css index 7b05a174df..c6698e8ff2 100644 --- a/test/basic.colors.expect.css +++ b/test/basic.colors.expect.css @@ -18,26 +18,29 @@ test-color-mod { color: hsl(0 100% 50%); color: hwb(0 0% 0%); color: hwb(0 0% 0%); + color: hwb(0 0% 0%); color: hsl(0 100% 50%); color: hsl(0 100% 50%); } test-red-green-blue-alpha-adjuster { - color: rgb(100% 0% 7.8431%); + color: rgb(100% 0% 7.8431372549%); color: rgb(100% 0% 20%); - color: rgb(100% 7.8431% 0%); + color: rgb(100% 7.8431372549% 0%); color: rgb(100% 20% 0%); - color: rgb(92.1569% 0% 0%); + color: rgb(92.1568627451% 0% 0%); color: rgb(80% 0% 0%); - color: rgb(100% 0% 0% / 20%); + color: rgb(49.8039215686% 0% 0%); + color: rgb(100% 0% 0% / 50%); + color: rgb(100% 0% 0% / 25%); } test-rgb-adjuster { color: rgb(100% 100% 0%); color: rgb(100% 100% 0%); - color: rgb(0% 0% 0%); - color: rgb(0% 0% 0%); - color: rgb(50% 0% 0%); + color: rgb(40% 0% 0%); + color: rgb(40% 0% 0%); + color: rgb(40% 20% 60%); } test-hue-adjuster { @@ -45,37 +48,43 @@ test-hue-adjuster { color: hsl(20 100% 50%); color: hsl(20 100% 50%); color: hsl(20 100% 50%); - color: hsl(340 100% 50%); - color: hsl(340 100% 50%); + color: hsl(0 100% 50%); + color: hsl(0 100% 50%); color: hsl(0 100% 50%); color: hsl(0 100% 50%); } test-lightness-saturation-adjuster { + color: hsl(0 100% 50%); color: hsl(0 100% 20%); color: hsl(0 100% 70%); color: hsl(0 100% 30%); - color: hsl(0 100% 10%); - color: hsl(0 20% 50%); - color: hsl(0 100% 50%); - color: hsl(0 80% 50%); - color: hsl(0 20% 50%); + color: hsl(0 100% 75%); + color: hsl(60 20% 91.1764705882%); + color: hsl(60 75.5555555556% 91.1764705882%); + color: hsl(60 35.5555555556% 91.1764705882%); + color: hsl(60 83.3333333333% 91.1764705882%); } test-blackness-whiteness-adjuster { - color: hwb(0 0% 20%); - color: hwb(0 0% 20%); - color: hwb(0 0% 0%); - color: hwb(0 0% 0%); - color: hwb(0 20% 0%); - color: hwb(0 20% 0%); - color: hwb(0 0% 0%); - color: hwb(0 0% 0%); + color: hwb(60 86.2745098039% 20%); + color: hwb(60 86.2745098039% 23.9215686275%); + color: hwb(60 86.2745098039% 2.9215686275%); + color: hwb(60 86.2745098039% 78.431372549%); + color: hwb(60 20% 3.9215686275%); + color: hwb(60 87.2745098039% 3.9215686275%); + color: hwb(60 66.2745098039% 3.9215686275%); + color: hwb(60 43.137254902% 3.9215686275%); } test-tint-shade-adjuster { - color: hwb(0 0% 80%); - color: hwb(0 80% 0%); + color: rgb(100% 0% 0%); + color: rgb(100% 0% 0%); + color: rgb(100% 0% 0%); + color: rgb(100% 100% 100%); + color: rgb(0% 0% 0%); + color: rgb(100% 20% 20%); + color: rgb(80% 0% 0%); } test-blend-adjuster { @@ -86,11 +95,24 @@ test-blend-adjuster { } test-contrast-adjuster { - color: hwb(60 0% 25%); - color: hwb(60 0% 50%); + color: hwb(60 0% 100%); color: hwb(60 0% 75%); + color: hwb(60 0% 50%); + color: hwb(60 0% 25%); + color: hwb(60 0% 0%); } test-combination-adjuster { - color: rgb(34.5676% 17.8464% 44.5676%); + color: rgb(41.2352941176% 31.2352941176% 80%); +} + +test-sameness { + color: rgb(96.0784313725% 96.0784313725% 86.2745098039%); + color: hsl(60 55.5555555556% 91.1764705882%); + color: hsl(60 55.5555555556% 91.1764705882%); + color: hsl(60 55.5555555556% 91.1764705882%); + color: rgb(96.0784313725% 96.0784313725% 86.2745098039%); + color: rgb(96.0784313725% 96.0784313725% 86.2745098039%); + color: rgb(96.0784313725% 96.0784313725% 86.2745098039%); + color: hsl(60 55.5555555556% 91.1764705882%); } diff --git a/test/basic.css b/test/basic.css index eb6005179f..d6ebe6e91a 100644 --- a/test/basic.css +++ b/test/basic.css @@ -16,6 +16,7 @@ test-color-mod { color: color-mod(hsl(0, 100%, 50%)); color: color-mod(hsl(0, 100%, 50%, 1)); color: color-mod(hsla(0, 100%, 50%, 1)); + color: color-mod(hwb(0 0 0)); color: color-mod(hwb(0 0% 0%)); color: color-mod(hwb(0 0% 0% / 100%)); color: color-mod(0); @@ -29,15 +30,17 @@ test-red-green-blue-alpha-adjuster { color: color-mod(red green(+ 20%)); color: color-mod(red red(- 20)); color: color-mod(red red(- 20%)); - color: color-mod(red alpha(* 20%)); + color: color-mod(red red(- 128)); + color: color-mod(red alpha(- 50%)); + color: color-mod(red alpha(- .75)); } test-rgb-adjuster { color: color-mod(red rgb(+ 0 255 0)); color: color-mod(red rgb(+ #0f0)); - color: color-mod(red rgb(- 255 0 0)); - color: color-mod(red rgb(- #f00)); - color: color-mod(red rgb(* 50%)); + color: color-mod(red rgb(- 60% 0 0)); + color: color-mod(red rgb(- #900)); + color: color-mod(rebeccapurple rgb(* 1%)); } test-hue-adjuster { @@ -52,28 +55,34 @@ test-hue-adjuster { } test-lightness-saturation-adjuster { + color: color-mod(red lightness(50%)); color: color-mod(red lightness(20%)); color: color-mod(red lightness(+ 20%)); color: color-mod(red lightness(- 20%)); - color: color-mod(red lightness(* 20%)); - color: color-mod(red saturation(20%)); - color: color-mod(red saturation(+ 20%)); - color: color-mod(red saturation(- 20%)); - color: color-mod(red saturation(* 20%)); + color: color-mod(red lightness(* 1.5%)); + color: color-mod(beige saturation(20%)); + color: color-mod(beige saturation(+ 20%)); + color: color-mod(beige saturation(- 20%)); + color: color-mod(beige saturation(* 1.5%)); } test-blackness-whiteness-adjuster { - color: color-mod(red blackness(20%)); - color: color-mod(red blackness(+ 20%)); - color: color-mod(red blackness(- 20%)); - color: color-mod(red blackness(* 20%)); - color: color-mod(red whiteness(20%)); - color: color-mod(red whiteness(+ 20%)); - color: color-mod(red whiteness(- 20%)); - color: color-mod(red whiteness(* 20%)); + color: color-mod(beige blackness(20%)); + color: color-mod(beige blackness(+ 20%)); + color: color-mod(beige blackness(- 1%)); + color: color-mod(beige blackness(* 20%)); + color: color-mod(beige whiteness(20%)); + color: color-mod(beige whiteness(+ 1%)); + color: color-mod(beige whiteness(- 20%)); + color: color-mod(beige whiteness(* .5%)); } test-tint-shade-adjuster { + color: color-mod(red); + color: color-mod(red tint(0%)); + color: color-mod(red shade(0%)); + color: color-mod(red tint(100%)); + color: color-mod(red shade(100%)); color: color-mod(red tint(20%)); color: color-mod(red shade(20%)); } @@ -86,11 +95,24 @@ test-blend-adjuster { } test-contrast-adjuster { + color: color-mod(yellow contrast(0%)); color: color-mod(yellow contrast(25%)); color: color-mod(yellow contrast(50%)); color: color-mod(yellow contrast(75%)); + color: color-mod(yellow contrast(100%)); } test-combination-adjuster { color: color-mod(color-mod(0deg blue(10%)) rgb(+ 0 10 0) hue(+ 10deg) tint(10%) lightness(+ 10%) saturation(+ 10%) blend(rebeccapurple 50%)); } + +test-sameness { + color: color-mod(beige); + color: color-mod(beige hue(+ 0deg)); + color: color-mod(beige saturation(+ 0%)); + color: color-mod(beige lightness(+ 0%)); + color: color-mod(beige alpha(1)); + color: color-mod(beige alpha(+ 0)); + color: color-mod(beige alpha(+ 0%)); + color: color-mod(beige blend(beige 0% hsl)); +} diff --git a/test/basic.expect.css b/test/basic.expect.css index 84fe4373d9..9049a4ba0b 100644 --- a/test/basic.expect.css +++ b/test/basic.expect.css @@ -18,6 +18,7 @@ test-color-mod { color: rgb(255, 0, 255); color: rgb(255, 0, 0); color: rgb(255, 0, 0); + color: rgb(255, 0, 0); color: rgb(255, 0, 255); color: rgb(255, 0, 255); } @@ -29,15 +30,17 @@ test-red-green-blue-alpha-adjuster { color: rgb(255, 51, 0); color: rgb(235, 0, 0); color: rgb(204, 0, 0); - color: rgba(255, 0, 0, 0.2); + color: rgb(127, 0, 0); + color: rgba(255, 0, 0, 0.5); + color: rgba(255, 0, 0, 0.25); } test-rgb-adjuster { color: rgb(255, 255, 0); color: rgb(255, 255, 0); - color: rgb(0, 0, 0); - color: rgb(0, 0, 0); - color: rgb(128, 0, 0); + color: rgb(102, 0, 0); + color: rgb(102, 0, 0); + color: rgb(102, 51, 153); } test-hue-adjuster { @@ -45,37 +48,43 @@ test-hue-adjuster { color: rgb(255, 85, 255); color: rgb(255, 85, 255); color: rgb(255, 85, 255); - color: rgb(0, 0, 85); - color: rgb(0, 0, 85); + color: rgb(255, 0, 255); + color: rgb(255, 0, 255); color: rgb(255, 0, 255); color: rgb(255, 0, 255); } test-lightness-saturation-adjuster { + color: rgb(255, 0, 255); color: rgb(102, 0, 102); color: rgb(255, 102, 255); color: rgb(153, 0, 153); - color: rgb(51, 0, 51); - color: rgb(153, 102, 153); - color: rgb(255, 0, 255); - color: rgb(230, 25, 230); - color: rgb(153, 102, 153); + color: rgb(255, 128, 255); + color: rgb(237, 237, 237); + color: rgb(249, 249, 249); + color: rgb(241, 241, 241); + color: rgb(251, 251, 251); } test-blackness-whiteness-adjuster { - color: rgb(204, 0, 0); - color: rgb(204, 0, 0); - color: rgb(255, 0, 0); - color: rgb(255, 0, 0); - color: rgb(255, 51, 51); - color: rgb(255, 51, 51); - color: rgb(255, 0, 0); - color: rgb(255, 0, 0); + color: rgb(255, 255, 2); + color: rgb(254, 254, 2); + color: rgb(248, 248, 220); + color: rgb(254, 254, 1); + color: rgb(245, 245, 51); + color: rgb(245, 245, 223); + color: rgb(245, 245, 169); + color: rgb(245, 245, 110); } test-tint-shade-adjuster { - color: rgb(51, 0, 0); - color: rgb(255, 204, 204); + color: rgb(255, 0, 0); + color: rgb(255, 0, 0); + color: rgb(255, 0, 0); + color: rgb(255, 255, 255); + color: rgb(0, 0, 0); + color: rgb(255, 51, 51); + color: rgb(204, 0, 0); } test-blend-adjuster { @@ -86,11 +95,24 @@ test-blend-adjuster { } test-contrast-adjuster { - color: rgb(191, 191, 0); - color: rgb(128, 128, 0); + color: rgb(0, 0, 0); color: rgb(64, 64, 0); + color: rgb(128, 128, 0); + color: rgb(191, 191, 0); + color: rgb(255, 255, 0); } test-combination-adjuster { - color: rgb(88, 46, 114); + color: rgb(105, 80, 204); +} + +test-sameness { + color: rgb(245, 245, 220); + color: rgb(245, 245, 245); + color: rgb(245, 245, 245); + color: rgb(245, 245, 245); + color: rgb(245, 245, 220); + color: rgb(245, 245, 220); + color: rgb(245, 245, 220); + color: rgb(245, 245, 245); } From 444db022f9d73b150873a6b1093924957bad17c7 Mon Sep 17 00:00:00 2001 From: Jonathan Neal Date: Wed, 17 Jan 2018 18:49:36 -0500 Subject: [PATCH 554/795] 2.0.0 --- CHANGELOG.md | 5 +++++ package.json | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index aedd457c01..8d164d7d46 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,10 @@ # Changes to PostCSS color-mod() Function +### 2.0.0 (January 17, 2018) + +- Reverse blend/blenda percentage calculations (breaking change) +- Other improvements (see 4e4de6e) + ### 1.1.0 (January 17, 2018) - Round stringified color values diff --git a/package.json b/package.json index 57a31487de..adb148c4bc 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "postcss-color-mod-function", - "version": "1.1.0", + "version": "2.0.0", "description": "Modify colors using the color-mod() function in CSS", "author": "Jonathan Neal ", "license": "CC0-1.0", From 17eb49b2105f06a1868be6cf2577b83b1f4c5a22 Mon Sep 17 00:00:00 2001 From: Jonathan Neal Date: Sat, 20 Jan 2018 21:58:48 -0500 Subject: [PATCH 555/795] 2.1.0 --- .appveyor.yml | 2 +- CHANGELOG.md | 9 + index.js | 2 +- lib/color.js | 345 +++++++++---------------------- lib/conversions.js | 380 +++++++++++++++++++++++++++++++++++ lib/manage-unresolved.js | 2 +- lib/transform.js | 178 ++++++++-------- package.json | 14 +- test/basic.colors.expect.css | 5 +- test/basic.css | 3 + test/basic.expect.css | 69 ++++--- 11 files changed, 635 insertions(+), 374 deletions(-) create mode 100644 lib/conversions.js diff --git a/.appveyor.yml b/.appveyor.yml index d6b511f500..acbf8a5eeb 100644 --- a/.appveyor.yml +++ b/.appveyor.yml @@ -2,7 +2,7 @@ environment: matrix: - - nodejs_version: 4.0 + - nodejs_version: 4 version: "{build}" build: off diff --git a/CHANGELOG.md b/CHANGELOG.md index 8d164d7d46..064d6bc921 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,14 @@ # Changes to PostCSS color-mod() Function +### 2.1.0 (January 20, 2018) + +- Added support for legacy (comma-separated) `hsl()` colors +- Added support for all `` units +- Added use of legacy (comma-separated) `hsl()` colors when appropriate +- Improved color conversions +- Improved support for all `rgb()` colors +- Removed external math and color dependencies + ### 2.0.0 (January 17, 2018) - Reverse blend/blenda percentage calculations (breaking change) diff --git a/index.js b/index.js index de40f34144..15f03052d5 100644 --- a/index.js +++ b/index.js @@ -6,7 +6,7 @@ import transformAST from './lib/transform'; // plugin export default postcss.plugin('postcss-color-mod-function', opts => { const unresolvedOpt = String(Object(opts).unresolved || 'throw').toLowerCase(); - const stringifierOpt = Object(opts).stringifier || (color => color.toRGBLegacy()); + const stringifierOpt = Object(opts).stringifier || (color => color.toLegacy()); return (root, result) => { root.walkDecls(decl => { diff --git a/lib/color.js b/lib/color.js index d77de6e72f..8d4c547afd 100644 --- a/lib/color.js +++ b/lib/color.js @@ -1,11 +1,11 @@ -import number from 'big.js'; +import { convertRGBtoHSL, convertRGBtoHWB, convertHSLtoRGB, convertHSLtoHWB, convertHWBtoRGB, convertHWBtoHSL, convertRGBtoH } from './conversions'; export default class Color { constructor(color) { this.color = Object(Object(color).color || color); if (color.colorspace === 'rgb') { - this.color.hue = rgb2hue(color.red, color.green, color.blue, color.hue || 0); + this.color.hue = convertRGBtoH(color.red, color.green, color.blue, color.hue || 0); } } @@ -133,6 +133,10 @@ export default class Color { return color2hwbString(this.color); } + toLegacy() { + return color2legacyString(this.color); + } + toRGB() { return color2rgbString(this.color); } @@ -149,20 +153,20 @@ export default class Color { /* Blending /* ========================================================================== */ -function blend(base, color, percentage, colorspace, isBlendingAlpha) { // eslint-disable-line max-params - const addition = number(percentage).div(100); - const subtraction = number(1).minus(addition); +function blend(base, color, percentage, colorspace, isBlendingAlpha) { + const addition = percentage / 100; + const subtraction = 1 - addition; if (colorspace === 'hsl') { const { hue: h1, saturation: s1, lightness: l1, alpha: a1 } = color2hsl(base); const { hue: h2, saturation: s2, lightness: l2, alpha: a2 } = color2hsl(color); const [hue, saturation, lightness, alpha] = [ - Number(number(h1).times(subtraction).plus(number(h2).times(addition))), - Number(number(s1).times(subtraction).plus(number(s2).times(addition))), - Number(number(l1).times(subtraction).plus(number(l2).times(addition))), + h1 * subtraction + h2 * addition, + s1 * subtraction + s2 * addition, + l1 * subtraction + l2 * addition, isBlendingAlpha - ? Number(number(a1).times(subtraction).plus(number(a2).times(addition))) + ? a1 * subtraction + a2 * addition : a1 ]; @@ -172,10 +176,12 @@ function blend(base, color, percentage, colorspace, isBlendingAlpha) { // eslint const { hue: h2, whiteness: w2, blackness: b2, alpha: a2 } = color2hwb(color); const [hue, whiteness, blackness, alpha] = [ - Number(number(h1).times(subtraction).plus(number(h2).times(addition))), - Number(number(w1).times(subtraction).plus(number(w2).times(addition))), - Number(number(b1).times(subtraction).plus(number(b2).times(addition))), - isBlendingAlpha ? Number(number(a1).times(subtraction).plus(number(a2).times(addition))) : a1 + h1 * subtraction + h2 * addition, + w1 * subtraction + w2 * addition, + b1 * subtraction + b2 * addition, + isBlendingAlpha + ? a1 * subtraction + a2 * addition + : a1 ]; return { hue, whiteness, blackness, alpha, colorspace: 'hwb' }; @@ -184,10 +190,12 @@ function blend(base, color, percentage, colorspace, isBlendingAlpha) { // eslint const { red: r2, green: g2, blue: b2, alpha: a2 } = color2rgb(color); const [red, green, blue, alpha] = [ - Number(number(r1).times(subtraction).plus(number(r2).times(addition))), - Number(number(g1).times(subtraction).plus(number(g2).times(addition))), - Number(number(b1).times(subtraction).plus(number(b2).times(addition))), - isBlendingAlpha ? Number(number(a1).times(subtraction).plus(number(a2).times(addition))) : a1 + r1 * subtraction + r2 * addition, + g1 * subtraction + g2 * addition, + b1 * subtraction + b2 * addition, + isBlendingAlpha + ? a1 * subtraction + a2 * addition + : a1 ]; return { red, green, blue, alpha, colorspace: 'rgb' }; @@ -214,7 +222,7 @@ function assign(base, channels) { if (isRGB) { // conditionally preserve the hue - color.hue = rgb2hue(color.red, color.green, color.blue, base.hue || 0); + color.hue = convertRGBtoH(color.red, color.green, color.blue, base.hue || 0); } } ); @@ -230,183 +238,44 @@ function normalize(value, channel) { const min = 0; const max = isHue ? 360 : 100; - const modifiedValue = Math.min(Math.max(isHue - ? number(value).mod(360) + const normalizedValue = Math.min(Math.max(isHue + ? value % 360 : value, min), max); - return modifiedValue + return normalizedValue; } /* Convert colors /* ========================================================================== */ -function color2hsl(color) { - return color.colorspace === 'rgb' - ? rgb2hsl(color, color.hue) - : color.colorspace === 'hwb' - ? rgb2hsl(hwb2rgb(color), color.hue) - : color; -} - -function color2hwb(color) { - return color.colorspace === 'rgb' - ? rgb2hwb(color, color.hue) - : color.colorspace === 'hsl' - ? rgb2hwb(hsl2rgb(color), color.hue) - : color; -} - function color2rgb(color) { - return color.colorspace === 'hsl' - ? hsl2rgb(color) + const [ red, green, blue ] = color.colorspace === 'hsl' + ? convertHSLtoRGB(color.hue, color.saturation, color.lightness) : color.colorspace === 'hwb' - ? hwb2rgb(color) - : color; -} - -/* Convert HSL to RGB -/* ========================================================================== */ - -function hsl2rgb({ hue, saturation, lightness, alpha = 100 }) { - const t2 = lightness <= 50 - ? Number( - number(lightness).div(100).times( - number(saturation).div(100).plus(1) - ) - ) - : Number( - number(lightness).div(100).plus( - number(saturation).div(100) - ).minus( - number(lightness).div(100).times( - number(saturation).div(100) - ) - ) - ); - - const t1 = Number(number(lightness).div(100).times(2).minus(t2)); - - const red = hue2channel(t1, t2, Number(number(hue).div(60).plus(2))); - const green = hue2channel(t1, t2, Number(number(hue).div(60))); - const blue = hue2channel(t1, t2, Number(number(hue).div(60).minus(2))); - - return { hue, red, green, blue, alpha, colorspace: 'rgb' }; -} + ? convertHWBtoRGB(color.hue, color.whiteness, color.blackness) + : [ color.red, color.green, color.blue ]; -/* Convert HWB to RGB -/* ========================================================================== */ - -function hwb2rgb({ hue, whiteness, blackness, alpha = 100 }) { - const ratio = Number(number(whiteness).plus(blackness)); - const rwhiteness = ratio > 100 ? Number(number(whiteness).div(ratio)) : whiteness; - const rblackness = ratio > 100 ? Number(number(blackness).div(ratio)) : blackness; - const value = Number(number(100).minus(rblackness)); - const hexagon = number(6).times(hue).div(360); - - const hexagonFloor = Math.floor(hexagon); - - const hexagonF = hexagonFloor % 6 - ? number(1).minus( - hexagon.minus(hexagonFloor) - ) - : hexagon.minus(hexagonFloor); - - const interpolation = Number(number(rwhiteness).plus( - hexagonF.times( - number(value).minus(rwhiteness) - ) - )); - - const [red, green, blue] = hexagonFloor % 6 === 5 - ? [value, rwhiteness, interpolation] - : hexagonFloor % 6 === 4 - ? [interpolation, rwhiteness, value] - : hexagonFloor % 6 === 3 - ? [rwhiteness, interpolation, value] - : hexagonFloor % 6 === 2 - ? [rwhiteness, value, interpolation] - : hexagonFloor % 6 === 1 - ? [interpolation, value, rwhiteness] - : [value, interpolation, rwhiteness]; - - return { hue, red, green, blue, alpha, colorspace: 'rgb' }; + return { red, green, blue, hue: color.hue, alpha: color.alpha, colorspace: 'rgb' }; } -/* Convert RGB to HSL -/* ========================================================================== */ - -function rgb2hsl({ red, green, blue, alpha = 100 }, fallback = 0) { // eslint-disable-line max-params - const hue = rgb2hue(red, green, blue, fallback); - const whiteness = rgb2whiteness(red, green, blue); - const value = rgb2value(red, green, blue); - const lightness = wv2lightness(whiteness, value); - const saturation = lvw2saturation(lightness, value, whiteness); - - return { hue, saturation, lightness, alpha, colorspace: 'hsl' }; -} - -/* Convert RGB to HWB -/* ========================================================================== */ - -function rgb2hwb({ red, green, blue, alpha = 100 }, fallback = 0) { // eslint-disable-line max-params - const hue = rgb2hue(red, green, blue, fallback); - const whiteness = rgb2whiteness(red, green, blue); - const value = rgb2value(red, green, blue); - const blackness = Number(number(100).minus(value)); - - return { hue, whiteness, blackness, alpha, colorspace: 'hwb' }; -} - -/* Convert Hue to RGB -/* ========================================================================== */ +function color2hsl(color) { + const [ hue, saturation, lightness ] = color.colorspace === 'rgb' + ? convertRGBtoHSL(color.red, color.green, color.blue, color.hue) + : color.colorspace === 'hwb' + ? convertHWBtoHSL(color.hue, color.whiteness, color.blackness) + : [ color.hue, color.saturation, color.lightness ]; -function hue2channel(t1, t2, hue) { - const huerange = hue < 0 - ? number(hue).plus(6) - : hue >= 6 - ? number(hue).minus(6) - : number(hue); - - const rgb = huerange < 1 - ? Number(number(number(t2).minus(t1)).times(hue).plus(t1)) - : hue < 3 - ? t2 - : hue < 4 - ? Number(number(number(t2).minus(t1)).times(number(4).minus(hue)).plus(t1)) - : t1; - - return Number(number(rgb).times(100)); + return { hue, saturation, lightness, alpha: color.alpha, colorspace: 'hsl' }; } -/* Convert RGB to Hue -/* ========================================================================== */ - -function rgb2hue(red, green, blue, fallback) { // eslint-disable-line max-params - const whiteness = rgb2whiteness(red, green, blue); - const value = rgb2value(red, green, blue); - const chroma = vw2chroma(value, whiteness); +function color2hwb(color) { + const [ hue, whiteness, blackness ] = color.colorspace === 'rgb' + ? convertRGBtoHWB(color.red, color.green, color.blue, color.hue) + : color.colorspace === 'hsl' + ? convertHSLtoHWB(color.hue, color.saturation, color.lightness) + : [ color.hue, color.whiteness, color.blackness ]; - if (chroma === 0) { - return fallback; - } else { - const segment = value === red - ? number(green).minus(blue).div(chroma) - : value === green - ? number(blue).minus(red).div(chroma) - : number(red).minus(green).div(chroma); - - const shift = value === red - ? segment < 0 - ? 360 / 60 - : 0 / 60 - : value === green - ? 120 / 60 - : 240 / 60; - - const hue = Number(number(segment).plus(shift).times(60)); - - return hue; - } + return { hue, whiteness, blackness, alpha: color.alpha, colorspace: 'hwb' }; } /* Contrast functions @@ -415,9 +284,10 @@ function rgb2hue(red, green, blue, fallback) { // eslint-disable-line max-params function contrast(color, percentage) { // https://drafts.csswg.org/css-color/#contrast-adjuster const hwb = color2hwb(color); + const rgb = color2rgb(color); // compute the luminance of the color. - const luminance = rgb2luminance(color.red, color.green, color.blue); + const luminance = rgb2luminance(rgb.red, rgb.green, rgb.blue); // the maximum-contrast color, if it is less than .5 const maxContrastColor = luminance < 0.5 @@ -435,7 +305,7 @@ function contrast(color, percentage) { // otherwise, the maximum-contrast color : maxContrastColor; - // color(maximum-contrast blend(minimum-contrast hwb)) + // color(maximum-contrast blend(minimum-contrast hwb))); return blend(maxContrastColor, minContrastColor, percentage, 'hwb', false); } @@ -448,9 +318,9 @@ function colors2contrast(color1, color2) { return l1 > l2 // if l1 is the relative luminance of the lighter of the colors - ? Number(number(l1).plus(0.05).div(number(l2).plus(0.05))) + ? (l1 + 0.05) / (l2 + 0.05) // otherwise, if l2 is the relative luminance of the lighter of the colors - : Number(number(l2).plus(0.05).div(number(l2).plus(0.05))); + : (l2 + 0.05) / (l1 + 0.05); } function rgb2luminance(red, green, blue) { @@ -461,14 +331,14 @@ function rgb2luminance(red, green, blue) { ]; // https://drafts.csswg.org/css-color/#luminance - const luminance = Number(number(0.2126).times(redLuminance).plus(number(0.7152).times(greenLuminance)).plus(number(0.0722).times(blueLuminance))); + const luminance = 0.2126 * redLuminance + 0.7152 * greenLuminance + 0.0722 * blueLuminance; return luminance; } function channel2luminance(value) { // https://drafts.csswg.org/css-color/#luminance - const luminance = value <= 0.03928 ? Number(number(value).div(12.92)) : Math.pow(number(value).plus(0.055).div(1.055), 2.4); + const luminance = value <= 0.03928 ? value / 12.92 : Math.pow((value + 0.055) /1.055, 2.4); return luminance; } @@ -478,18 +348,18 @@ function colors2contrastRatioColor(hwb, maxHWB) { const modifiedHWB = Object.assign({}, hwb); // values to be used for linear interpolations in HWB space - let minW = number(hwb.whiteness); - let minB = number(hwb.blackness); - let maxW = number(maxHWB.whiteness); - let maxB = number(maxHWB.blackness); + let minW = hwb.whiteness; + let minB = hwb.blackness; + let maxW = maxHWB.whiteness; + let maxB = maxHWB.blackness; // find the color with the smallest contrast ratio with the base color that is greater than 4.5 - while (Number(minW.minus(maxW).abs()) > 100 || Number(minB.minus(maxB).abs()) > 100) { - const midW = maxW.plus(minW).div(2).round(); - const midB = maxB.plus(minB).div(2).round(); + while (Math.abs(minW - maxW) > 100 || Math.abs(minB - maxB) > 100) { + const midW = Math.round((maxW + minW) / 2); + const midB = Math.round((maxB + minB) / 2); - modifiedHWB.whiteness = Number(midW); - modifiedHWB.blackness = Number(midB); + modifiedHWB.whiteness = midW; + modifiedHWB.blackness = midB; if (colors2contrast(modifiedHWB, hwb) > 4.5) { maxW = midW; @@ -503,45 +373,6 @@ function colors2contrastRatioColor(hwb, maxHWB) { return modifiedHWB; } -/* Convert RGB to Whiteness -/* ========================================================================== */ - -function rgb2whiteness(red, green, blue) { - return Math.min(red, green, blue); -} - -/* Convert RGB to Value -/* ========================================================================== */ - -function rgb2value(red, green, blue) { - return Math.max(red, green, blue) -} - -/* Convert Whiteness and Value to Lightness -/* ========================================================================== */ - -function wv2lightness(whiteness, value) { - return Number(number(whiteness).plus(value).div(2)); -} - -/* Convert Value and Whiteness to Chroma -/* ========================================================================== */ - -function vw2chroma(value, whiteness) { - return Number(number(value).minus(whiteness)); -} - -/* Convert Lightness, Value, and Whiteness to Saturation -/* ========================================================================== */ - -function lvw2saturation(lightness, value, whiteness) { - return whiteness === value - ? 0 - : lightness < 50 - ? Number(number(value).minus(whiteness).div(number(value).plus(whiteness)).times(100)) - : Number(number(value).minus(whiteness).div(number(200).minus(value).minus(whiteness)).times(100)); -} - /* Match /* ========================================================================== */ @@ -562,9 +393,9 @@ function color2hslString(color) { const hsl = color2hsl(color); const isOpaque = hsl.alpha === 100; const hue = hsl.hue; - const saturation = number(hsl.saturation).round(10); - const lightness = number(hsl.lightness).round(10); - const alpha = number(hsl.alpha).round(10); + const saturation = Math.round(hsl.saturation * 10000000000) / 10000000000; + const lightness = Math.round(hsl.lightness * 10000000000) / 10000000000; + const alpha = Math.round(hsl.alpha * 10000000000) / 10000000000; return `hsl(${hue} ${saturation}% ${lightness}%${isOpaque ? '' @@ -575,9 +406,9 @@ function color2hwbString(color) { const hwb = color2hwb(color); const isOpaque = hwb.alpha === 100; const hue = hwb.hue; - const whiteness = number(hwb.whiteness).round(10); - const blackness = number(hwb.blackness).round(10); - const alpha = number(hwb.alpha).round(10); + const whiteness = Math.round(hwb.whiteness * 10000000000) / 10000000000; + const blackness = Math.round(hwb.blackness * 10000000000) / 10000000000; + const alpha = Math.round(hwb.alpha * 10000000000) / 10000000000; return `hwb(${hue} ${whiteness}% ${blackness}%${isOpaque ? '' @@ -587,26 +418,46 @@ function color2hwbString(color) { function color2rgbString(color) { const rgb = color2rgb(color); const isOpaque = rgb.alpha === 100; - const red = number(rgb.red).round(10); - const green = number(rgb.green).round(10); - const blue = number(rgb.blue).round(10); - const alpha = number(rgb.alpha).round(10); + const red = Math.round(rgb.red * 10000000000) / 10000000000; + const green = Math.round(rgb.green * 10000000000) / 10000000000; + const blue = Math.round(rgb.blue * 10000000000) / 10000000000; + const alpha = Math.round(rgb.alpha * 10000000000) / 10000000000; return `rgb(${red}% ${green}% ${blue}%${isOpaque ? '' : ` / ${alpha}%`})`; } +function color2legacyString(color) { + return color.colorspace === 'hsl' + ? color2hslLegacyString(color) + : color2rgbLegacyString(color); +} + function color2rgbLegacyString(color) { const rgb = color2rgb(color); const isOpaque = rgb.alpha === 100; const name = isOpaque ? 'rgb' : 'rgba'; - const red = number(rgb.red).times(2.55).round(0); - const green = number(rgb.green).times(2.55).round(0); - const blue = number(rgb.blue).times(2.55).round(0); - const alpha = number(rgb.alpha).div(100).round(10); + const red = Math.round(rgb.red * 255 / 100); + const green = Math.round(rgb.green * 255 / 100); + const blue = Math.round(rgb.blue * 255 / 100); + const alpha = Math.round(rgb.alpha / 100 * 10000000000) / 10000000000; return `${name}(${red}, ${green}, ${blue}${isOpaque ? '' : `, ${alpha}`})`; } + +function color2hslLegacyString(color) { + const hsl = color2hsl(color); + const isOpaque = hsl.alpha === 100; + const name = isOpaque ? 'hsl' : 'hsla'; + const hue = hsl.hue; + const saturation = Math.round(hsl.saturation * 10000000000) / 10000000000; + const lightness = Math.round(hsl.lightness * 10000000000) / 10000000000; + const alpha = Math.round(hsl.alpha / 100 * 10000000000) / 10000000000; + + return `${name}(${hue}, ${saturation}%, ${lightness}%${isOpaque + ? '' + : `, ${alpha}`})`; +} diff --git a/lib/conversions.js b/lib/conversions.js new file mode 100644 index 0000000000..22003ca13a --- /dev/null +++ b/lib/conversions.js @@ -0,0 +1,380 @@ +/* Convert Degree to Hue Degree +/* ========================================================================== */ + +export function convertDtoD(deg) { + return deg % 360; +} + +/* Convert Gradian to Hue Degree +/* ========================================================================== */ + +export function convertGtoD(grad) { + return grad * 0.9 % 360; +} + +/* Convert Radian to Hue Degree +/* ========================================================================== */ + +export function convertRtoD(rad) { + return rad * 180 / Math.PI % 360; +} + +/* Convert Turn to Hue Degree +/* ========================================================================== */ + +export function convertTtoD(turn) { + return turn * 360 % 360; +} + +/* Convert Red/Green/Blue to Red/Green/Blue (0 - 255) +/* ========================================================================== */ + +export function convertRGBtoRGB255(red, green, blue) { + const red255 = convertChannelToChannel255(red); + const green255 = convertChannelToChannel255(green); + const blue255 = convertChannelToChannel255(blue); + + return [red255, green255, blue255]; +} + +/* Convert Red/Green/Blue to Hue/Saturation/Lightness +/* ========================================================================== */ + +export function convertRGBtoHSL(red, green, blue, fallbackHue = 0) { + const hue = convertRGBtoH(red, green, blue, fallbackHue); + const whiteness = convertRGBtoW(red, green, blue); + const value = convertRGBtoV(red, green, blue); + const lightness = convertWVtoL(whiteness, value); + const saturation = convertLVWtoS(lightness, value, whiteness); + + return [ hue, saturation, lightness ]; +} + +/* Convert Red/Green/Blue to Hue/Whiteness/Blackness +/* ========================================================================== */ + +export function convertRGBtoHWB(red, green, blue, fallbackHue = 0) { + const hue = convertRGBtoH(red, green, blue, fallbackHue); + const whiteness = convertRGBtoW(red, green, blue); + const value = convertRGBtoV(red, green, blue); + const blackness = convertVtoB(value); + + return [ hue, whiteness, blackness ]; +} + +/* Convert Hue/Saturation/Lightness to Red/Green/Blue (and fallback Hue) +/* ========================================================================== */ + +export function convertHSLtoRGB(hue, saturation, lightness) { + const hexagon = hue / 60; + + const t2 = lightness <= 50 + ? lightness * (saturation + 100) / 10000 + : (lightness + saturation) / 100 - lightness * saturation / 10000; + + const t1 = lightness * 0.02 - t2; + + const red = convertTTHtoChannel(t1, t2, hexagon + 2) * 100; + const green = convertTTHtoChannel(t1, t2, hexagon) * 100; + const blue = convertTTHtoChannel(t1, t2, hexagon - 2) * 100; + + return [red, green, blue]; +} + +/* Convert Hue/Saturation/Lightness to Hue/Whiteness/Blackness +/* ========================================================================== */ + +export function convertHSLtoHWB(hue, saturation, lightness) { + const [ red, green, blue ] = convertHSLtoRGB(hue, saturation, lightness); + const [ , whiteness, blackness ] = convertRGBtoHWB(red, green, blue, hue); + + return [ hue, whiteness, blackness ]; +} + +/* Convert Hue/Whiteness/Blackness to Hue/Saturation/Lightness +/* ========================================================================== */ + +export function convertHWBtoHSL(hue, whiteness, blackness) { + const [ red, green, blue ] = convertHWBtoRGB(hue, whiteness, blackness); + const [ , saturation, lightness ] = convertRGBtoHSL(red, green, blue, hue); + + return [ hue, saturation, lightness ]; +} + +/* Convert Hue/Whiteness/Blackness to Red/Green/Blue (and fallback Hue) +/* ========================================================================== */ + +export function convertHWBtoRGB(hue, whiteness, blackness) { + const [ hslRed, hslGreen, hslBlue ] = convertHSLtoRGB(hue, 100, 50); + + const tot = whiteness + blackness; + const w = tot > 100 ? whiteness / tot * 100 : whiteness; + const b = tot > 100 ? blackness / tot * 100 : blackness; + + const red = hslRed * (100 - w - b) / 100 + w; + const green = hslGreen * (100 - w - b) / 100 + w; + const blue = hslBlue * (100 - w - b) / 100 + w; + + return [red, green, blue]; +} + +/* Convert Channel to Channel (0 - 255) +/* ========================================================================== */ + +export function convertChannelToChannel255(channel) { + return Math.round(channel * 2.55); +} + +/* Convert Red/Green/Blue to Hue +/* ========================================================================== */ + +export function convertRGBtoH(red, green, blue, fallbackHue = 0) { + const whiteness = convertRGBtoW(red, green, blue); + const value = convertRGBtoV(red, green, blue); + const chroma = convertVWtoC(value, whiteness); + + if (chroma === 0) { + return fallbackHue; + } else { + const segment = value === red + ? (green - blue) / chroma + : value === green + ? (blue - red) / chroma + : (red - green) / chroma; + + const shift = value === red + ? segment < 0 + ? 360 / 60 + : 0 / 60 + : value === green + ? 120 / 60 + : 240 / 60; + + const hue = (segment + shift) * 60; + + return hue; + } +} + +/* Convert Red/Green/Blue to Whiteness +/* ========================================================================== */ + +export function convertRGBtoW(red, green, blue) { + return Math.min(red, green, blue); +} + +/* Convert Red/Green/Blue to Value +/* ========================================================================== */ + +export function convertRGBtoV(red, green, blue) { + return Math.max(red, green, blue); +} + +/* Convert Value/Whiteness to Chroma +/* ========================================================================== */ + +export function convertVWtoC(value, whiteness) { + return value - whiteness; +} + +/* Convert Whiteness/Value to Lightness +/* ========================================================================== */ + +export function convertWVtoL(whiteness, value) { + return (whiteness + value) / 2; +} + +/* Convert Lightness/Value/Whiteness to Saturation +/* ========================================================================== */ + +export function convertLVWtoS(lightness, value, whiteness) { + return whiteness === value + ? 0 + : lightness < 50 + ? (value - whiteness) / (value + whiteness) * 100 + : (value - whiteness) / (200 - value - whiteness) * 100; +} + +/* Convert Value to Blackness +/* ========================================================================== */ + +export function convertVtoB(value) { + return 100 - value; +} + +/* Convert Hue parts to Channel +/* ========================================================================== */ + +export function convertTTHtoChannel(t1, t2, hexagon) { + const althexagon = hexagon < 0 + ? hexagon + 6 + : hexagon >= 6 + ? hexagon - 6 + : hexagon; + + return althexagon < 1 + ? (t2 - t1) * althexagon + t1 + : althexagon < 3 + ? t2 + : althexagon < 4 + ? (t2 - t1) * (4 - althexagon) + t1 + : t1; +} + +/* Convert a Name to Red/Green/Blue +/* ========================================================================== */ + +export function convertNtoRGB(name) { + const names = { + aliceblue: [240, 248, 255], + antiquewhite: [250, 235, 215], + aqua: [0, 255, 255], + aquamarine: [127, 255, 212], + azure: [240, 255, 255], + beige: [245, 245, 220], + bisque: [255, 228, 196], + black: [0, 0, 0], + blanchedalmond: [255, 235, 205], + blue: [0, 0, 255], + blueviolet: [138, 43, 226], + brown: [165, 42, 42], + burlywood: [222, 184, 135], + cadetblue: [95, 158, 160], + chartreuse: [127, 255, 0], + chocolate: [210, 105, 30], + coral: [255, 127, 80], + cornflowerblue: [100, 149, 237], + cornsilk: [255, 248, 220], + crimson: [220, 20, 60], + cyan: [0, 255, 255], + darkblue: [0, 0, 139], + darkcyan: [0, 139, 139], + darkgoldenrod: [184, 134, 11], + darkgray: [169, 169, 169], + darkgreen: [0, 100, 0], + darkgrey: [169, 169, 169], + darkkhaki: [189, 183, 107], + darkmagenta: [139, 0, 139], + darkolivegreen: [85, 107, 47], + darkorange: [255, 140, 0], + darkorchid: [153, 50, 204], + darkred: [139, 0, 0], + darksalmon: [233, 150, 122], + darkseagreen: [143, 188, 143], + darkslateblue: [72, 61, 139], + darkslategray: [47, 79, 79], + darkslategrey: [47, 79, 79], + darkturquoise: [0, 206, 209], + darkviolet: [148, 0, 211], + deeppink: [255, 20, 147], + deepskyblue: [0, 191, 255], + dimgray: [105, 105, 105], + dimgrey: [105, 105, 105], + dodgerblue: [30, 144, 255], + firebrick: [178, 34, 34], + floralwhite: [255, 250, 240], + forestgreen: [34, 139, 34], + fuchsia: [255, 0, 255], + gainsboro: [220, 220, 220], + ghostwhite: [248, 248, 255], + gold: [255, 215, 0], + goldenrod: [218, 165, 32], + gray: [128, 128, 128], + green: [0, 128, 0], + greenyellow: [173, 255, 47], + grey: [128, 128, 128], + honeydew: [240, 255, 240], + hotpink: [255, 105, 180], + indianred: [205, 92, 92], + indigo: [75, 0, 130], + ivory: [255, 255, 240], + khaki: [240, 230, 140], + lavender: [230, 230, 250], + lavenderblush: [255, 240, 245], + lawngreen: [124, 252, 0], + lemonchiffon: [255, 250, 205], + lightblue: [173, 216, 230], + lightcoral: [240, 128, 128], + lightcyan: [224, 255, 255], + lightgoldenrodyellow: [250, 250, 210], + lightgray: [211, 211, 211], + lightgreen: [144, 238, 144], + lightgrey: [211, 211, 211], + lightpink: [255, 182, 193], + lightsalmon: [255, 160, 122], + lightseagreen: [32, 178, 170], + lightskyblue: [135, 206, 250], + lightslategray: [119, 136, 153], + lightslategrey: [119, 136, 153], + lightsteelblue: [176, 196, 222], + lightyellow: [255, 255, 224], + lime: [0, 255, 0], + limegreen: [50, 205, 50], + linen: [250, 240, 230], + magenta: [255, 0, 255], + maroon: [128, 0, 0], + mediumaquamarine: [102, 205, 170], + mediumblue: [0, 0, 205], + mediumorchid: [186, 85, 211], + mediumpurple: [147, 112, 219], + mediumseagreen: [60, 179, 113], + mediumslateblue: [123, 104, 238], + mediumspringgreen: [0, 250, 154], + mediumturquoise: [72, 209, 204], + mediumvioletred: [199, 21, 133], + midnightblue: [25, 25, 112], + mintcream: [245, 255, 250], + mistyrose: [255, 228, 225], + moccasin: [255, 228, 181], + navajowhite: [255, 222, 173], + navy: [0, 0, 128], + oldlace: [253, 245, 230], + olive: [128, 128, 0], + olivedrab: [107, 142, 35], + orange: [255, 165, 0], + orangered: [255, 69, 0], + orchid: [218, 112, 214], + palegoldenrod: [238, 232, 170], + palegreen: [152, 251, 152], + paleturquoise: [175, 238, 238], + palevioletred: [219, 112, 147], + papayawhip: [255, 239, 213], + peachpuff: [255, 218, 185], + peru: [205, 133, 63], + pink: [255, 192, 203], + plum: [221, 160, 221], + powderblue: [176, 224, 230], + purple: [128, 0, 128], + rebeccapurple: [102, 51, 153], + red: [255, 0, 0], + rosybrown: [188, 143, 143], + royalblue: [65, 105, 225], + saddlebrown: [139, 69, 19], + salmon: [250, 128, 114], + sandybrown: [244, 164, 96], + seagreen: [46, 139, 87], + seashell: [255, 245, 238], + sienna: [160, 82, 45], + silver: [192, 192, 192], + skyblue: [135, 206, 235], + slateblue: [106, 90, 205], + slategray: [112, 128, 144], + slategrey: [112, 128, 144], + snow: [255, 250, 250], + springgreen: [0, 255, 127], + steelblue: [70, 130, 180], + tan: [210, 180, 140], + teal: [0, 128, 128], + thistle: [216, 191, 216], + tomato: [255, 99, 71], + turquoise: [64, 224, 208], + violet: [238, 130, 238], + wheat: [245, 222, 179], + white: [255, 255, 255], + whitesmoke: [245, 245, 245], + yellow: [255, 255, 0], + yellowgreen: [154, 205, 50] + }; + + return names[name]; +} diff --git a/lib/manage-unresolved.js b/lib/manage-unresolved.js index 3a8ef68dd8..028a8db0a9 100644 --- a/lib/manage-unresolved.js +++ b/lib/manage-unresolved.js @@ -1,4 +1,4 @@ -export default function manageUnresolved(node, opts, word, message) { // eslint-disable-line max-params +export default function manageUnresolved(node, opts, word, message) { if ('warn' === opts.unresolved) { opts.decl.warn(opts.result, message, { word }); } else if ('ignore' !== opts.unresolved) { diff --git a/lib/transform.js b/lib/transform.js index 64c2e79662..13e4ffa13b 100644 --- a/lib/transform.js +++ b/lib/transform.js @@ -1,8 +1,7 @@ // tooling +import { convertDtoD, convertGtoD, convertRtoD, convertTtoD, convertNtoRGB } from './conversions'; import Color from './color'; import manageUnresolved from './manage-unresolved'; -import names from 'color-name'; -import number from 'big.js'; import parser from 'postcss-values-parser'; /* Transform AST @@ -52,10 +51,14 @@ function transformColor(node, opts) { // return a transformed rgb/rgba color function function transformRGBFunction(node, opts) { const [red, green, blue, alpha = 100] = transformArgsByParams(node, [ - // [ {3} | {3} ] [ / ]? - [transformRGBValue, transformRGBValue, transformRGBValue, isSlash, transformAlpha], - // #{3} [ , ]? ] - [transformRGBValue, isComma, transformRGBValue, isComma, transformRGBValue, isComma, transformAlpha] + // [ , ]? + [transformPercentage, transformPercentage, transformPercentage, isSlash, transformAlpha], + // [ , ]? + [transformRGBNumber, transformRGBNumber, transformRGBNumber, isSlash, transformAlpha], + // , , [ , ]? + [transformPercentage, isComma, transformPercentage, isComma, transformPercentage, isComma, transformAlpha], + // , , [ , ]? + [transformRGBNumber, isComma, transformRGBNumber, isComma, transformRGBNumber, isComma, transformAlpha] ]); if (red !== undefined) { @@ -70,9 +73,9 @@ function transformRGBFunction(node, opts) { // return a transformed hsl/hsla color function function transformHSLFunction(node, opts) { const [hue, saturation, lightness, alpha = 100] = transformArgsByParams(node, [ - // {2} [ / ]? + // [ / ]? [transformHue, transformPercentage, transformPercentage, isSlash, transformAlpha], - // hue, #{2} [ , ]? ] + // , , [ , ]? [transformHue, isComma, transformPercentage, isComma, transformPercentage, isComma, transformAlpha] ]); @@ -136,10 +139,10 @@ function transformHexColor(node, opts) { const [r, g, b, a, rr, gg, bb, aa] = (node.value.match(hexColorMatch) || []).slice(1); const color = new Color({ - red: rr !== undefined ? Number(number(parseInt(rr, 16)).div(2.55)) : r !== undefined ? Number(number(parseInt(r + r, 16)).div(2.55)) : 0, - green: gg !== undefined ? Number(number(parseInt(gg, 16)).div(2.55)) : g !== undefined ? Number(number(parseInt(g + g, 16)).div(2.55)) : 0, - blue: bb !== undefined ? Number(number(parseInt(bb, 16)).div(2.55)) : b !== undefined ? Number(number(parseInt(b + b, 16)).div(2.55)) : 0, - alpha: aa !== undefined ? Number(number(parseInt(aa, 16)).div(2.55)) : a !== undefined ? Number(number(parseInt(a + a, 16)).div(2.55)) : 100 + red: rr !== undefined ? parseInt(rr, 16) / 2.55 : r !== undefined ? parseInt(r + r, 16) / 2.55 : 0, + green: gg !== undefined ? parseInt(gg, 16) / 2.55 : g !== undefined ? parseInt(g + g, 16) / 2.55 : 0, + blue: bb !== undefined ? parseInt(bb, 16) / 2.55 : b !== undefined ? parseInt(b + b, 16) / 2.55 : 0, + alpha: aa !== undefined ? parseInt(aa, 16) / 2.55 : a !== undefined ? parseInt(a + a, 16) / 2.55 : 100 }); return color; @@ -152,12 +155,12 @@ function transformHexColor(node, opts) { function transformNamedColor(node, opts) { if (isNamedColor(node)) { // - const [red, green, blue] = names[node.value]; + const [red, green, blue] = convertNtoRGB(node.value); const color = new Color({ - red: Number(number(red).div(2.55)), - green: Number(number(green).div(2.55)), - blue: Number(number(blue).div(2.55)), + red: red / 2.55, + green: green / 2.55, + blue: blue / 2.55, alpha: 100, colorspace: 'rgb' }); @@ -201,21 +204,27 @@ function transformColorByAdjusters(color, adjusterNodes, opts) { // return a transformed color using a/alpha/blue/green/red adjustments function transformAlphaBlueGreenRedAdjuster(base, node, opts) { const [operatorOrValue, adjustment] = transformArgsByParams(node, alphaMatch.test(node.value) + // a/alpha adjustments ? [ // [ + | - ] [transformMinusPlusOperator, transformAlpha], - // * + // * [transformTimesOperator, transformPercentage], // [transformAlpha] ] + // blue/green/red adjustments : [ - // [ + | - ] - [transformMinusPlusOperator, transformRGBValue], + // [ + | - ] + [transformMinusPlusOperator, transformPercentage], + // [ + | - ] + [transformMinusPlusOperator, transformRGBNumber], // * [transformTimesOperator, transformPercentage], - // - [transformRGBValue] + // + [transformPercentage], + // + [transformRGBNumber] ] ); @@ -223,19 +232,19 @@ function transformAlphaBlueGreenRedAdjuster(base, node, opts) { // normalized channel name const channel = node.value.toLowerCase().replace(alphaMatch, 'alpha'); - const existingValue = number(base[channel]()); + const existingValue = base[channel](); const modifiedValue = adjustment !== undefined ? operatorOrValue === '+' - ? existingValue.plus(adjustment) + ? existingValue + Number(adjustment) : operatorOrValue === '-' - ? existingValue.minus(adjustment) + ? existingValue - Number(adjustment) : operatorOrValue === '*' - ? existingValue.times(adjustment) - : adjustment - : operatorOrValue; + ? existingValue * Number(adjustment) + : Number(adjustment) + : Number(operatorOrValue); - const modifiedColor = base[channel](Number(modifiedValue)); + const modifiedColor = base[channel](modifiedValue); return modifiedColor; } else { @@ -246,10 +255,10 @@ function transformAlphaBlueGreenRedAdjuster(base, node, opts) { // return a transformed color using an rgb adjustment function transformRGBAdjuster(base, node, opts) { const [arg1, arg2, arg3, arg4] = transformArgsByParams(node, [ - // [ + | - ] - [transformMinusPlusOperator, transformRGBNumber, transformRGBNumber, transformRGBNumber], // [ + | - ] [transformMinusPlusOperator, transformPercentage, transformPercentage, transformPercentage], + // [ + | - ] + [transformMinusPlusOperator, transformRGBNumber, transformRGBNumber, transformRGBNumber], // [ + | - ] [transformMinusPlusOperator, transformHexColor], // [ * ] @@ -260,36 +269,36 @@ function transformRGBAdjuster(base, node, opts) { if (arg2 !== undefined && arg2.color) { const modifiedColor = base.rgb( arg1 === '+' - ? Number(number(base.red()).plus(arg2.red())) - : Number(number(base.red()).minus(arg2.red())), + ? base.red() + arg2.red() + : base.red() - arg2.red(), arg1 === '+' - ? Number(number(base.green()).plus(arg2.green())) - : Number(number(base.green()).minus(arg2.green())), + ? base.green() + arg2.green() + : base.green() - arg2.green(), arg1 === '+' - ? Number(number(base.blue()).plus(arg2.blue())) - : Number(number(base.blue()).minus(arg2.blue())) + ? base.blue() + arg2.blue() + : base.blue() - arg2.blue() ); return modifiedColor; } else if (arg1 !== undefined && minusPlusMatch.test(arg1)) { const modifiedColor = base.rgb( arg1 === '+' - ? Number(number(base.red()).plus(arg2)) - : Number(number(base.red()).minus(arg2)), + ? base.red() + arg2 + : base.red() - arg2, arg1 === '+' - ? Number(number(base.green()).plus(arg3)) - : Number(number(base.green()).minus(arg3)), + ? base.green() + arg3 + : base.green() - arg3, arg1 === '+' - ? Number(number(base.blue()).plus(arg4)) - : Number(number(base.blue()).minus(arg4)) + ? base.blue() + arg4 + : base.blue() - arg4 ); return modifiedColor; } else if (arg1 !== undefined && arg2 !== undefined) { const modifiedColor = base.rgb( - Number(number(base.red()).times(arg2)), - Number(number(base.green()).times(arg2)), - Number(number(base.blue()).times(arg2)) + base.red() * arg2, + base.green() * arg2, + base.blue() * arg2 ); return modifiedColor; @@ -299,7 +308,7 @@ function transformRGBAdjuster(base, node, opts) { } // return a transformed color using a blend/blenda adjustment -function transformBlendAdjuster(base, node, isAlphaBlend, opts) { // eslint-disable-line max-params +function transformBlendAdjuster(base, node, isAlphaBlend, opts) { const [color, percentage, colorspace = 'rgb'] = transformArgsByParams(node, [ [transformColor, transformPercentage, transformColorSpace] ]); @@ -345,15 +354,15 @@ function transformHueAdjuster(base, node, opts) { const modifiedValue = adjustment !== undefined ? operatorOrHue === '+' - ? number(existingHue).plus(adjustment) + ? existingHue + Number(adjustment) : operatorOrHue === '-' - ? number(existingHue).minus(adjustment) + ? existingHue - Number(adjustment) : operatorOrHue === '*' - ? number(existingHue).times(adjustment) - : number(adjustment) - : number(operatorOrHue); + ? existingHue * Number(adjustment) + : Number(adjustment) + : Number(operatorOrHue); - return base.hue(Number(modifiedValue)); + return base.hue(modifiedValue); } else { return manageUnresolved(node, opts, node.value, `Expected a valid hue() function)`); } @@ -362,26 +371,23 @@ function transformHueAdjuster(base, node, opts) { // [ b | blackness | l | lightness | s | saturation | w | whiteness ]( [ + | - | * ]? ) function transformBlacknessLightnessSaturationWhitenessAdjuster(base, node, opts) { const channel = node.value.toLowerCase().replace(/^b$/, 'blackness').replace(/^l$/, 'lightness').replace(/^s$/, 'saturation').replace(/^w$/, 'whiteness'); - const [operatorOrValue, rawAdjustment] = transformArgsByParams(node, [ + const [operatorOrValue, adjustment] = transformArgsByParams(node, [ [transformMinusPlusTimesOperator, transformPercentage], [transformPercentage] ]); if (operatorOrValue !== undefined) { - const existingValue = number(base[channel]()); - const adjustment = parseFloat(rawAdjustment); + const existingValue = base[channel](); - const rawModifiedValue = !isNaN(adjustment) + const modifiedValue = adjustment !== undefined ? operatorOrValue === '+' - ? existingValue.plus(adjustment) + ? existingValue + Number(adjustment) : operatorOrValue === '-' - ? existingValue.minus(adjustment) + ? existingValue - Number(adjustment) : operatorOrValue === '*' - ? existingValue.times(adjustment) - : number(adjustment) - : number(operatorOrValue); - - const modifiedValue = Number(rawModifiedValue); + ? existingValue * Number(adjustment) + : Number(adjustment) + : Number(operatorOrValue); return base[channel](modifiedValue); } else { @@ -398,7 +404,7 @@ function transformShadeTintAdjuster(base, node, opts) { ]); if (percentage !== undefined) { - const modifiedValue = parseFloat(percentage); + const modifiedValue = Number(percentage); return base[channel](modifiedValue); } else { @@ -423,7 +429,7 @@ function transformColorSpace(node, opts) { function transformAlpha(node, opts) { if (isNumber(node)) { // - return Number(number(node.value).times(100)); + return node.value * 100; } else if (isPercentage(node)) { // return transformPercentage(node, opts); @@ -432,24 +438,11 @@ function transformAlpha(node, opts) { } } -// return a transformed rgb value -function transformRGBValue(node, opts) { - if (isNumber(node)) { - // - return transformRGBNumber(node, opts); - } else if (isPercentage(node)) { - // - return transformPercentage(node, opts); - } else { - return manageUnresolved(node, opts, node.value, `Expected a valid RGB value)`); - } -} - // return a transformed rgb number function transformRGBNumber(node, opts) { if (isNumber(node)) { - // - return Number(number(node.value).div(2.55)); + // + return node.value / 2.55; } else { return manageUnresolved(node, opts, node.value, `Expected a valid RGB value)`); } @@ -458,8 +451,22 @@ function transformRGBNumber(node, opts) { // return a transformed hue function transformHue(node, opts) { if (isHue(node)) { - // - return parseFloat(node.value); + // = | + const unit = node.unit.toLowerCase(); + + if (unit === 'grad') { + // if = (400 per circle) + return convertGtoD(node.value); + } else if (unit === 'rad') { + // if = (2π per circle) + return convertRtoD(node.value); + } else if (unit === 'turn') { + // if = (1 per circle) + return convertTtoD(node.value); + } else { + // if = [ | ] (360 per circle) + return convertDtoD(node.value); + } } else { return manageUnresolved(node, opts, node.value, `Expected a valid hue`); } @@ -469,7 +476,7 @@ function transformHue(node, opts) { function transformPercentage(node, opts) { if (isPercentage(node)) { // - return Number(number(node.value)); + return Number(node.value); } else { return manageUnresolved(node, opts, node.value, `Expected a valid hue`); } @@ -593,7 +600,7 @@ function isColorModFunction(node) { // return whether the node is a valid named-color function isNamedColor(node) { - return Object(node).type === 'word' && node.value in names; + return Object(node).type === 'word' && Boolean(convertNtoRGB(node.value)); } // return whether the node is a valid hex color @@ -613,7 +620,7 @@ function isColorSpace(node) { // return whether the hue value is valid function isHue(node) { - return Object(node).type === 'number' && /^(deg)?$/.test(node.unit); + return Object(node).type === 'number' && hueUnitMatch.test(node.unit); } // return whether the comma is valid @@ -663,6 +670,7 @@ const colorSpaceMatch = /^(hsl|hwb|rgb)$/i; const contrastMatch = /^contrast$/i; const hexColorMatch = /^#(?:([a-f0-9])([a-f0-9])([a-f0-9])([a-f0-9])?|([a-f0-9]{2})([a-f0-9]{2})([a-f0-9]{2})([a-f0-9]{2})?)$/i; const hslaMatch = /^hsla?$/i; +const hueUnitMatch = /^(deg|grad|rad|turn)?$/i; const hueMatch = /^h(ue)?$/i; const hwbMatch = /^hwb$/i; const minusPlusMatch = /^[+-]$/; diff --git a/package.json b/package.json index adb148c4bc..edcbf1a40e 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "postcss-color-mod-function", - "version": "2.0.0", + "version": "2.1.0", "description": "Modify colors using the color-mod() function in CSS", "author": "Jonathan Neal ", "license": "CC0-1.0", @@ -26,8 +26,6 @@ "node": ">=4.0.0" }, "dependencies": { - "big.js": "^5.0.3", - "color-name": "^1.1.3", "postcss": "^6.0", "postcss-values-parser": "^1.3.1" }, @@ -36,7 +34,7 @@ "babel-eslint": "^8.2", "babel-preset-env": "^1.6", "echint": "^4.0", - "eslint": "^4.15", + "eslint": "^4.16", "eslint-config-dev": "2.0", "postcss-tape": "2.2", "pre-commit": "^1.2", @@ -45,7 +43,13 @@ }, "eslintConfig": { "extends": "dev", - "parser": "babel-eslint" + "parser": "babel-eslint", + "rules": { + "max-params": [ + 2, + 5 + ] + } }, "keywords": [ "postcss", diff --git a/test/basic.colors.expect.css b/test/basic.colors.expect.css index c6698e8ff2..e06f831934 100644 --- a/test/basic.colors.expect.css +++ b/test/basic.colors.expect.css @@ -21,6 +21,9 @@ test-color-mod { color: hwb(0 0% 0%); color: hsl(0 100% 50%); color: hsl(0 100% 50%); + color: hsl(0 100% 50%); + color: hsl(0 100% 50%); + color: hsl(0 100% 50%); } test-red-green-blue-alpha-adjuster { @@ -103,7 +106,7 @@ test-contrast-adjuster { } test-combination-adjuster { - color: rgb(41.2352941176% 31.2352941176% 80%); + color: rgb(70% 30.2012805122% 46.7647058824%); } test-sameness { diff --git a/test/basic.css b/test/basic.css index d6ebe6e91a..55c49217cd 100644 --- a/test/basic.css +++ b/test/basic.css @@ -21,6 +21,9 @@ test-color-mod { color: color-mod(hwb(0 0% 0% / 100%)); color: color-mod(0); color: color-mod(0deg); + color: color-mod(0grad); + color: color-mod(0rad); + color: color-mod(0turn); } test-red-green-blue-alpha-adjuster { diff --git a/test/basic.expect.css b/test/basic.expect.css index 9049a4ba0b..050adf9ca5 100644 --- a/test/basic.expect.css +++ b/test/basic.expect.css @@ -11,16 +11,19 @@ test-color-mod { color: rgb(255, 0, 0); color: rgb(255, 0, 0); color: rgb(255, 0, 0); - color: rgb(255, 0, 255); - color: rgb(255, 0, 255); - color: rgb(255, 0, 255); - color: rgb(255, 0, 255); - color: rgb(255, 0, 255); + color: hsl(0, 100%, 50%); + color: hsl(0, 100%, 50%); + color: hsl(0, 100%, 50%); + color: hsl(0, 100%, 50%); + color: hsl(0, 100%, 50%); color: rgb(255, 0, 0); color: rgb(255, 0, 0); color: rgb(255, 0, 0); - color: rgb(255, 0, 255); - color: rgb(255, 0, 255); + color: hsl(0, 100%, 50%); + color: hsl(0, 100%, 50%); + color: hsl(0, 100%, 50%); + color: hsl(0, 100%, 50%); + color: hsl(0, 100%, 50%); } test-red-green-blue-alpha-adjuster { @@ -44,33 +47,33 @@ test-rgb-adjuster { } test-hue-adjuster { - color: rgb(255, 85, 255); - color: rgb(255, 85, 255); - color: rgb(255, 85, 255); - color: rgb(255, 85, 255); - color: rgb(255, 0, 255); - color: rgb(255, 0, 255); - color: rgb(255, 0, 255); - color: rgb(255, 0, 255); + color: hsl(20, 100%, 50%); + color: hsl(20, 100%, 50%); + color: hsl(20, 100%, 50%); + color: hsl(20, 100%, 50%); + color: hsl(0, 100%, 50%); + color: hsl(0, 100%, 50%); + color: hsl(0, 100%, 50%); + color: hsl(0, 100%, 50%); } test-lightness-saturation-adjuster { - color: rgb(255, 0, 255); - color: rgb(102, 0, 102); - color: rgb(255, 102, 255); - color: rgb(153, 0, 153); - color: rgb(255, 128, 255); - color: rgb(237, 237, 237); - color: rgb(249, 249, 249); - color: rgb(241, 241, 241); - color: rgb(251, 251, 251); + color: hsl(0, 100%, 50%); + color: hsl(0, 100%, 20%); + color: hsl(0, 100%, 70%); + color: hsl(0, 100%, 30%); + color: hsl(0, 100%, 75%); + color: hsl(60, 20%, 91.1764705882%); + color: hsl(60, 75.5555555556%, 91.1764705882%); + color: hsl(60, 35.5555555556%, 91.1764705882%); + color: hsl(60, 83.3333333333%, 91.1764705882%); } test-blackness-whiteness-adjuster { - color: rgb(255, 255, 2); - color: rgb(254, 254, 2); + color: rgb(207, 207, 207); + color: rgb(200, 200, 200); color: rgb(248, 248, 220); - color: rgb(254, 254, 1); + color: rgb(134, 134, 134); color: rgb(245, 245, 51); color: rgb(245, 245, 223); color: rgb(245, 245, 169); @@ -90,7 +93,7 @@ test-tint-shade-adjuster { test-blend-adjuster { color: rgb(255, 128, 0); color: rgb(255, 128, 0); - color: rgb(255, 128, 255); + color: hsl(30, 100%, 50%); color: rgb(255, 128, 0); } @@ -103,16 +106,16 @@ test-contrast-adjuster { } test-combination-adjuster { - color: rgb(105, 80, 204); + color: rgb(178, 77, 119); } test-sameness { color: rgb(245, 245, 220); - color: rgb(245, 245, 245); - color: rgb(245, 245, 245); - color: rgb(245, 245, 245); + color: hsl(60, 55.5555555556%, 91.1764705882%); + color: hsl(60, 55.5555555556%, 91.1764705882%); + color: hsl(60, 55.5555555556%, 91.1764705882%); color: rgb(245, 245, 220); color: rgb(245, 245, 220); color: rgb(245, 245, 220); - color: rgb(245, 245, 245); + color: hsl(60, 55.5555555556%, 91.1764705882%); } From 52efbb6282aedcb7921166e6b2d58f0380b8345e Mon Sep 17 00:00:00 2001 From: Jonathan Neal Date: Mon, 22 Jan 2018 11:45:08 -0500 Subject: [PATCH 556/795] Follow package.json dependency versioning consistently --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index edcbf1a40e..2afa95185e 100644 --- a/package.json +++ b/package.json @@ -27,7 +27,7 @@ }, "dependencies": { "postcss": "^6.0", - "postcss-values-parser": "^1.3.1" + "postcss-values-parser": "^1.3" }, "devDependencies": { "babel-core": "^6.26", From 7ef0467fb6c525457dfd2ead4a7d01ceaf09e310 Mon Sep 17 00:00:00 2001 From: Jonathan Neal Date: Mon, 22 Jan 2018 11:45:35 -0500 Subject: [PATCH 557/795] Update color conversions --- lib/color.js | 18 ++-- lib/conversions.js | 219 +++++------------------------------------- lib/transform.js | 19 +--- package.json | 1 + test/basic.expect.css | 6 +- 5 files changed, 40 insertions(+), 223 deletions(-) diff --git a/lib/color.js b/lib/color.js index 8d4c547afd..1f488c8c0a 100644 --- a/lib/color.js +++ b/lib/color.js @@ -1,11 +1,11 @@ -import { convertRGBtoHSL, convertRGBtoHWB, convertHSLtoRGB, convertHSLtoHWB, convertHWBtoRGB, convertHWBtoHSL, convertRGBtoH } from './conversions'; +import { rgb2hsl, rgb2hwb, hsl2rgb, hsl2hwb, hwb2rgb, hwb2hsl, rgb2hue } from '@csstools/convert-colors'; export default class Color { constructor(color) { this.color = Object(Object(color).color || color); if (color.colorspace === 'rgb') { - this.color.hue = convertRGBtoH(color.red, color.green, color.blue, color.hue || 0); + this.color.hue = rgb2hue(color.red, color.green, color.blue, color.hue || 0); } } @@ -222,7 +222,7 @@ function assign(base, channels) { if (isRGB) { // conditionally preserve the hue - color.hue = convertRGBtoH(color.red, color.green, color.blue, base.hue || 0); + color.hue = rgb2hue(color.red, color.green, color.blue, base.hue || 0); } } ); @@ -250,9 +250,9 @@ function normalize(value, channel) { function color2rgb(color) { const [ red, green, blue ] = color.colorspace === 'hsl' - ? convertHSLtoRGB(color.hue, color.saturation, color.lightness) + ? hsl2rgb(color.hue, color.saturation, color.lightness) : color.colorspace === 'hwb' - ? convertHWBtoRGB(color.hue, color.whiteness, color.blackness) + ? hwb2rgb(color.hue, color.whiteness, color.blackness) : [ color.red, color.green, color.blue ]; return { red, green, blue, hue: color.hue, alpha: color.alpha, colorspace: 'rgb' }; @@ -260,9 +260,9 @@ function color2rgb(color) { function color2hsl(color) { const [ hue, saturation, lightness ] = color.colorspace === 'rgb' - ? convertRGBtoHSL(color.red, color.green, color.blue, color.hue) + ? rgb2hsl(color.red, color.green, color.blue, color.hue) : color.colorspace === 'hwb' - ? convertHWBtoHSL(color.hue, color.whiteness, color.blackness) + ? hwb2hsl(color.hue, color.whiteness, color.blackness) : [ color.hue, color.saturation, color.lightness ]; return { hue, saturation, lightness, alpha: color.alpha, colorspace: 'hsl' }; @@ -270,9 +270,9 @@ function color2hsl(color) { function color2hwb(color) { const [ hue, whiteness, blackness ] = color.colorspace === 'rgb' - ? convertRGBtoHWB(color.red, color.green, color.blue, color.hue) + ? rgb2hwb(color.red, color.green, color.blue, color.hue) : color.colorspace === 'hsl' - ? convertHSLtoHWB(color.hue, color.saturation, color.lightness) + ? hsl2hwb(color.hue, color.saturation, color.lightness) : [ color.hue, color.whiteness, color.blackness ]; return { hue, whiteness, blackness, alpha: color.alpha, colorspace: 'hwb' }; diff --git a/lib/conversions.js b/lib/conversions.js index 22003ca13a..416cf44500 100644 --- a/lib/conversions.js +++ b/lib/conversions.js @@ -26,201 +26,6 @@ export function convertTtoD(turn) { return turn * 360 % 360; } -/* Convert Red/Green/Blue to Red/Green/Blue (0 - 255) -/* ========================================================================== */ - -export function convertRGBtoRGB255(red, green, blue) { - const red255 = convertChannelToChannel255(red); - const green255 = convertChannelToChannel255(green); - const blue255 = convertChannelToChannel255(blue); - - return [red255, green255, blue255]; -} - -/* Convert Red/Green/Blue to Hue/Saturation/Lightness -/* ========================================================================== */ - -export function convertRGBtoHSL(red, green, blue, fallbackHue = 0) { - const hue = convertRGBtoH(red, green, blue, fallbackHue); - const whiteness = convertRGBtoW(red, green, blue); - const value = convertRGBtoV(red, green, blue); - const lightness = convertWVtoL(whiteness, value); - const saturation = convertLVWtoS(lightness, value, whiteness); - - return [ hue, saturation, lightness ]; -} - -/* Convert Red/Green/Blue to Hue/Whiteness/Blackness -/* ========================================================================== */ - -export function convertRGBtoHWB(red, green, blue, fallbackHue = 0) { - const hue = convertRGBtoH(red, green, blue, fallbackHue); - const whiteness = convertRGBtoW(red, green, blue); - const value = convertRGBtoV(red, green, blue); - const blackness = convertVtoB(value); - - return [ hue, whiteness, blackness ]; -} - -/* Convert Hue/Saturation/Lightness to Red/Green/Blue (and fallback Hue) -/* ========================================================================== */ - -export function convertHSLtoRGB(hue, saturation, lightness) { - const hexagon = hue / 60; - - const t2 = lightness <= 50 - ? lightness * (saturation + 100) / 10000 - : (lightness + saturation) / 100 - lightness * saturation / 10000; - - const t1 = lightness * 0.02 - t2; - - const red = convertTTHtoChannel(t1, t2, hexagon + 2) * 100; - const green = convertTTHtoChannel(t1, t2, hexagon) * 100; - const blue = convertTTHtoChannel(t1, t2, hexagon - 2) * 100; - - return [red, green, blue]; -} - -/* Convert Hue/Saturation/Lightness to Hue/Whiteness/Blackness -/* ========================================================================== */ - -export function convertHSLtoHWB(hue, saturation, lightness) { - const [ red, green, blue ] = convertHSLtoRGB(hue, saturation, lightness); - const [ , whiteness, blackness ] = convertRGBtoHWB(red, green, blue, hue); - - return [ hue, whiteness, blackness ]; -} - -/* Convert Hue/Whiteness/Blackness to Hue/Saturation/Lightness -/* ========================================================================== */ - -export function convertHWBtoHSL(hue, whiteness, blackness) { - const [ red, green, blue ] = convertHWBtoRGB(hue, whiteness, blackness); - const [ , saturation, lightness ] = convertRGBtoHSL(red, green, blue, hue); - - return [ hue, saturation, lightness ]; -} - -/* Convert Hue/Whiteness/Blackness to Red/Green/Blue (and fallback Hue) -/* ========================================================================== */ - -export function convertHWBtoRGB(hue, whiteness, blackness) { - const [ hslRed, hslGreen, hslBlue ] = convertHSLtoRGB(hue, 100, 50); - - const tot = whiteness + blackness; - const w = tot > 100 ? whiteness / tot * 100 : whiteness; - const b = tot > 100 ? blackness / tot * 100 : blackness; - - const red = hslRed * (100 - w - b) / 100 + w; - const green = hslGreen * (100 - w - b) / 100 + w; - const blue = hslBlue * (100 - w - b) / 100 + w; - - return [red, green, blue]; -} - -/* Convert Channel to Channel (0 - 255) -/* ========================================================================== */ - -export function convertChannelToChannel255(channel) { - return Math.round(channel * 2.55); -} - -/* Convert Red/Green/Blue to Hue -/* ========================================================================== */ - -export function convertRGBtoH(red, green, blue, fallbackHue = 0) { - const whiteness = convertRGBtoW(red, green, blue); - const value = convertRGBtoV(red, green, blue); - const chroma = convertVWtoC(value, whiteness); - - if (chroma === 0) { - return fallbackHue; - } else { - const segment = value === red - ? (green - blue) / chroma - : value === green - ? (blue - red) / chroma - : (red - green) / chroma; - - const shift = value === red - ? segment < 0 - ? 360 / 60 - : 0 / 60 - : value === green - ? 120 / 60 - : 240 / 60; - - const hue = (segment + shift) * 60; - - return hue; - } -} - -/* Convert Red/Green/Blue to Whiteness -/* ========================================================================== */ - -export function convertRGBtoW(red, green, blue) { - return Math.min(red, green, blue); -} - -/* Convert Red/Green/Blue to Value -/* ========================================================================== */ - -export function convertRGBtoV(red, green, blue) { - return Math.max(red, green, blue); -} - -/* Convert Value/Whiteness to Chroma -/* ========================================================================== */ - -export function convertVWtoC(value, whiteness) { - return value - whiteness; -} - -/* Convert Whiteness/Value to Lightness -/* ========================================================================== */ - -export function convertWVtoL(whiteness, value) { - return (whiteness + value) / 2; -} - -/* Convert Lightness/Value/Whiteness to Saturation -/* ========================================================================== */ - -export function convertLVWtoS(lightness, value, whiteness) { - return whiteness === value - ? 0 - : lightness < 50 - ? (value - whiteness) / (value + whiteness) * 100 - : (value - whiteness) / (200 - value - whiteness) * 100; -} - -/* Convert Value to Blackness -/* ========================================================================== */ - -export function convertVtoB(value) { - return 100 - value; -} - -/* Convert Hue parts to Channel -/* ========================================================================== */ - -export function convertTTHtoChannel(t1, t2, hexagon) { - const althexagon = hexagon < 0 - ? hexagon + 6 - : hexagon >= 6 - ? hexagon - 6 - : hexagon; - - return althexagon < 1 - ? (t2 - t1) * althexagon + t1 - : althexagon < 3 - ? t2 - : althexagon < 4 - ? (t2 - t1) * (4 - althexagon) + t1 - : t1; -} - /* Convert a Name to Red/Green/Blue /* ========================================================================== */ @@ -376,5 +181,27 @@ export function convertNtoRGB(name) { yellowgreen: [154, 205, 50] }; - return names[name]; + return names[name] && names[name].map(c => c / 2.55); } + + +/* Convert a Hex to Red/Green/Blue +/* ========================================================================== */ + +export function convertHtoRGB(hex) { + // #{3,4,6,8} + const [r, g, b, a, rr, gg, bb, aa] = (hex.match(hexColorMatch) || []).slice(1); + + if (rr !== undefined || r !== undefined) { + const red = rr !== undefined ? parseInt(rr, 16) : r !== undefined ? parseInt(r + r, 16) : 0; + const green = gg !== undefined ? parseInt(gg, 16) : g !== undefined ? parseInt(g + g, 16) : 0; + const blue = bb !== undefined ? parseInt(bb, 16) : b !== undefined ? parseInt(b + b, 16) : 0; + const alpha = aa !== undefined ? parseInt(aa, 16) : a !== undefined ? parseInt(a + a, 16) : 255; + + return [red, green, blue, alpha].map(c => c / 2.55); + } + + return undefined; +} + +const hexColorMatch = /^#(?:([a-f0-9])([a-f0-9])([a-f0-9])([a-f0-9])?|([a-f0-9]{2})([a-f0-9]{2})([a-f0-9]{2})([a-f0-9]{2})?)$/i; diff --git a/lib/transform.js b/lib/transform.js index 13e4ffa13b..638e4d3c55 100644 --- a/lib/transform.js +++ b/lib/transform.js @@ -1,5 +1,5 @@ // tooling -import { convertDtoD, convertGtoD, convertRtoD, convertTtoD, convertNtoRGB } from './conversions'; +import { convertDtoD, convertGtoD, convertRtoD, convertTtoD, convertNtoRGB, convertHtoRGB } from './conversions'; import Color from './color'; import manageUnresolved from './manage-unresolved'; import parser from 'postcss-values-parser'; @@ -136,14 +136,9 @@ function transformColorModFunction(node, opts) { function transformHexColor(node, opts) { if (hexColorMatch.test(node.value)) { // #{3,4,6,8} - const [r, g, b, a, rr, gg, bb, aa] = (node.value.match(hexColorMatch) || []).slice(1); + const [red, green, blue, alpha] = convertHtoRGB(node.value); - const color = new Color({ - red: rr !== undefined ? parseInt(rr, 16) / 2.55 : r !== undefined ? parseInt(r + r, 16) / 2.55 : 0, - green: gg !== undefined ? parseInt(gg, 16) / 2.55 : g !== undefined ? parseInt(g + g, 16) / 2.55 : 0, - blue: bb !== undefined ? parseInt(bb, 16) / 2.55 : b !== undefined ? parseInt(b + b, 16) / 2.55 : 0, - alpha: aa !== undefined ? parseInt(aa, 16) / 2.55 : a !== undefined ? parseInt(a + a, 16) / 2.55 : 100 - }); + const color = new Color({ red, green, blue, alpha }); return color; } else { @@ -157,13 +152,7 @@ function transformNamedColor(node, opts) { // const [red, green, blue] = convertNtoRGB(node.value); - const color = new Color({ - red: red / 2.55, - green: green / 2.55, - blue: blue / 2.55, - alpha: 100, - colorspace: 'rgb' - }); + const color = new Color({ red, green, blue, alpha: 100, colorspace: 'rgb' }); return color; } else { diff --git a/package.json b/package.json index 2afa95185e..edbc1aedc3 100644 --- a/package.json +++ b/package.json @@ -26,6 +26,7 @@ "node": ">=4.0.0" }, "dependencies": { + "@csstools/convert-colors": "^1.1", "postcss": "^6.0", "postcss-values-parser": "^1.3" }, diff --git a/test/basic.expect.css b/test/basic.expect.css index 050adf9ca5..71a93f9296 100644 --- a/test/basic.expect.css +++ b/test/basic.expect.css @@ -70,10 +70,10 @@ test-lightness-saturation-adjuster { } test-blackness-whiteness-adjuster { - color: rgb(207, 207, 207); - color: rgb(200, 200, 200); + color: rgb(204, 204, 204); + color: rgb(194, 194, 194); color: rgb(248, 248, 220); - color: rgb(134, 134, 134); + color: rgb(55, 55, 55); color: rgb(245, 245, 51); color: rgb(245, 245, 223); color: rgb(245, 245, 169); From 7133e87af06fbf79a3aab76dbafd607b52d74679 Mon Sep 17 00:00:00 2001 From: Jonathan Neal Date: Mon, 22 Jan 2018 11:47:29 -0500 Subject: [PATCH 558/795] 2.2.0 --- CHANGELOG.md | 4 ++++ package.json | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 064d6bc921..70ddca338e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # Changes to PostCSS color-mod() Function +### 2.2.0 (January 22, 2018) + +- Added `@csstools/convert-colors` to convert between color spaces + ### 2.1.0 (January 20, 2018) - Added support for legacy (comma-separated) `hsl()` colors diff --git a/package.json b/package.json index edbc1aedc3..1beeaf903d 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "postcss-color-mod-function", - "version": "2.1.0", + "version": "2.2.0", "description": "Modify colors using the color-mod() function in CSS", "author": "Jonathan Neal ", "license": "CC0-1.0", From 65077c08650f110bab797e88f25d15908b567ce1 Mon Sep 17 00:00:00 2001 From: Jonathan Neal Date: Thu, 25 Jan 2018 22:22:58 -0500 Subject: [PATCH 559/795] 2.3.0 --- CHANGELOG.md | 5 +++++ package.json | 6 +++--- test/basic.expect.css | 8 ++++---- 3 files changed, 12 insertions(+), 7 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 70ddca338e..858f3c7904 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,10 @@ # Changes to PostCSS color-mod() Function +### 2.3.0 (January 25, 2018) + +- Updated `@csstools/convert-colors` to 1.3 (minor update) +- Updated tests to reflect more accurate color conversions + ### 2.2.0 (January 22, 2018) - Added `@csstools/convert-colors` to convert between color spaces diff --git a/package.json b/package.json index 1beeaf903d..7592564d5e 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "postcss-color-mod-function", - "version": "2.2.0", + "version": "2.3.0", "description": "Modify colors using the color-mod() function in CSS", "author": "Jonathan Neal ", "license": "CC0-1.0", @@ -26,7 +26,7 @@ "node": ">=4.0.0" }, "dependencies": { - "@csstools/convert-colors": "^1.1", + "@csstools/convert-colors": "^1.3", "postcss": "^6.0", "postcss-values-parser": "^1.3" }, @@ -39,7 +39,7 @@ "eslint-config-dev": "2.0", "postcss-tape": "2.2", "pre-commit": "^1.2", - "rollup": "^0.54", + "rollup": "^0.55", "rollup-plugin-babel": "^3.0" }, "eslintConfig": { diff --git a/test/basic.expect.css b/test/basic.expect.css index 71a93f9296..c7610e0230 100644 --- a/test/basic.expect.css +++ b/test/basic.expect.css @@ -70,10 +70,10 @@ test-lightness-saturation-adjuster { } test-blackness-whiteness-adjuster { - color: rgb(204, 204, 204); - color: rgb(194, 194, 194); + color: rgb(204, 204, 220); + color: rgb(194, 194, 220); color: rgb(248, 248, 220); - color: rgb(55, 55, 55); + color: rgb(55, 55, 220); color: rgb(245, 245, 51); color: rgb(245, 245, 223); color: rgb(245, 245, 169); @@ -106,7 +106,7 @@ test-contrast-adjuster { } test-combination-adjuster { - color: rgb(178, 77, 119); + color: rgb(179, 77, 119); } test-sameness { From c082ec3b221ca3a4e3768cd2a19787df008c0390 Mon Sep 17 00:00:00 2001 From: Yvain Liechti Date: Thu, 28 Dec 2017 10:27:32 +0100 Subject: [PATCH 560/795] rename :focus-ring and .focus-ring as :focus-visible and .focus-visible --- .tape.js | 2 +- README.md | 30 +- index.js | 14 +- package-lock.json | 1433 +++++++++++++++++++++++++++++++++++++++++ package.json | 2 +- test/basic.css | 30 +- test/basic.expect.css | 30 +- 7 files changed, 1487 insertions(+), 54 deletions(-) create mode 100644 package-lock.json diff --git a/.tape.js b/.tape.js index e5f4fb1ba5..99c45b7962 100644 --- a/.tape.js +++ b/.tape.js @@ -11,7 +11,7 @@ module.exports = { assignTo: cache }, after: () => { - const expectJSON = '[".focus-ring",".focus-ring test","test .focus-ring","test test.focus-ring","test .focus-ring test","test test.focus-ring test","test .focus-ring .focus-ring test","test :matches(.focus-ring) test","test :matches(.focus-ring test) test","test :matches(test .focus-ring) test","test :matches(test test.focus-ring) test","test :matches(test .focus-ring test) test","test :matches(test test.focus-ring test) test","test :matches(test .focus-ring .focus-ring test) test"]'; + const expectJSON = '[".focus-visible",".focus-visible test","test .focus-visible","test test.focus-visible","test .focus-visible test","test test.focus-visible test","test .focus-visible .focus-visible test","test :matches(.focus-visible) test","test :matches(.focus-visible test) test","test :matches(test .focus-visible) test","test :matches(test test.focus-visible) test","test :matches(test .focus-visible test) test","test :matches(test test.focus-visible test) test","test :matches(test .focus-visible .focus-visible test) test"]'; const resultJSON = JSON.stringify(cache); if (expectJSON !== resultJSON) { diff --git a/README.md b/README.md index 9b2d76ecd4..859a3ff267 100644 --- a/README.md +++ b/README.md @@ -5,20 +5,20 @@ [![Windows Build Status][win-img]][win-url] [![Gitter Chat][git-img]][git-url] -[PostCSS Focus Ring] lets you use the `:focus-ring` pseudo-selector in CSS, +[PostCSS Focus Ring] lets you use the `:focus-visible` pseudo-selector in CSS, following the [Selectors Level 4] specification. ```css -:focus:not(:focus-ring) { +:focus:not(:focus-visible) { outline: none; } ``` -Use PostCSS Focus Ring alongside the [focus-ring polyfill] to swap the +Use PostCSS Focus Ring alongside the [focus-visible polyfill] to swap the pseudo-selector for a class, which maintains the same selector weight. ```css -:focus:not(.focus-ring) { +:focus:not(.focus-visible) { outline: none; } ``` @@ -35,9 +35,9 @@ require('postcss-focus-ring')({ ```json [ - ".focus-ring", - ".x-component-outside .focus-ring", - ".focus-ring .x-component-inside", + ".focus-visible", + ".x-component-outside .focus-visible", + ".focus-visible .x-component-inside", ] ``` @@ -51,14 +51,14 @@ require('postcss-focus-ring')({ ```js export default [ - ".focus-ring", - ".x-component-outside .focus-ring", - ".focus-ring .x-component-inside", + ".focus-visible", + ".x-component-outside .focus-visible", + ".focus-visible .x-component-inside", ]; ``` With these variables synchronized to JavaScript, they can be used alongside the -[focus-ring polyfill]. +[focus-visible polyfill]. ## Usage @@ -154,7 +154,7 @@ require('postcss-focus-ring')({ /* options */ }); #### exportAs `exportAs` is used to export transformed selectors originally containing the -`:focus-ring` pseudo-selector. +`:focus-visible` pseudo-selector. - If a `js` string is passed, the selectors will be exported as JavaScript. - If a `json` string is passed, the selectors will be exported as JSON. @@ -162,7 +162,7 @@ require('postcss-focus-ring')({ /* options */ }); #### exportTo `exportTo` is the path to where your JSON or JavaScript will be saved. By -default, it is the CSS source file with an additional `focus-ring-selectors` +default, it is the CSS source file with an additional `focus-visible-selectors` and `.js` or `.json` extension. #### assignTo @@ -183,5 +183,5 @@ be useful if running the plugin on the client side. [PostCSS]: https://github.com/postcss/postcss [Gulp PostCSS]: https://github.com/postcss/gulp-postcss [Grunt PostCSS]: https://github.com/nDmitry/grunt-postcss -[Selectors Level 4]: https://drafts.csswg.org/selectors-4/#the-focusring-pseudo -[focus-ring polyfill]: https://github.com/WICG/focus-ring +[Selectors Level 4]: https://drafts.csswg.org/selectors-4/#the-focus-visible-pseudo +[focus-visible polyfill]: https://github.com/WICG/focus-ring diff --git a/index.js b/index.js index 85715a3992..b77aaf307c 100644 --- a/index.js +++ b/index.js @@ -4,12 +4,12 @@ const postcss = require('postcss'); const parser = require('postcss-selector-parser'); // plugin -module.exports = postcss.plugin('postcss-focus-ring', (opts) => (root) => { // eslint-disable-line consistent-return +module.exports = postcss.plugin('postcss-focus-visible', (opts) => (root) => { // eslint-disable-line consistent-return // transformed cache const transformed = []; // walk each matching rule - root.walkRules(/:focus-ring\b/, (rule) => { + root.walkRules(/:focus-visible\b/, (rule) => { // original selector const originalSelector = rule.selector; @@ -17,10 +17,10 @@ module.exports = postcss.plugin('postcss-focus-ring', (opts) => (root) => { // e const transformedSelector = parser((selectors) => { // for each selector part selectors.walk((selector) => { - // if the selector part is a :focus-ring pseudo - if (selector.type === 'pseudo' && selector.value === ':focus-ring') { - // change it to a .focus-ring class - selector.value = '.focus-ring'; + // if the selector part is a :focus-visible pseudo + if (selector.type === 'pseudo' && selector.value === ':focus-visible') { + // change it to a .focus-visible class + selector.value = '.focus-visible'; selector.type = 'class'; } }); @@ -50,7 +50,7 @@ module.exports = postcss.plugin('postcss-focus-ring', (opts) => (root) => { // e // destination path const destination = `${ opts.destination || `${ root.source && root.source.input && root.source.input.file && root.source.input.file || 'css' - }.focus-ring-selectors.${ opts.exportAs === 'js' ? 'js' : 'json' }` }`; + }.focus-visible-selectors.${ opts.exportAs === 'js' ? 'js' : 'json' }` }`; // stringified contents const json = JSON.stringify(transformedClean, null, ' '); diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 0000000000..e1760dae46 --- /dev/null +++ b/package-lock.json @@ -0,0 +1,1433 @@ +{ + "name": "postcss-focus-ring", + "version": "1.0.0", + "lockfileVersion": 1, + "requires": true, + "dependencies": { + "acorn": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-5.2.1.tgz", + "integrity": "sha512-jG0u7c4Ly+3QkkW18V+NRDN+4bWHdln30NL1ZL2AvFZZmQe/BfopYCtghCKKVBUSetZ4QKcyA0pY6/4Gw8Pv8w==", + "dev": true + }, + "acorn-jsx": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-3.0.1.tgz", + "integrity": "sha1-r9+UiPsezvyDSPb7IvRk4ypYs2s=", + "dev": true, + "requires": { + "acorn": "3.3.0" + }, + "dependencies": { + "acorn": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-3.3.0.tgz", + "integrity": "sha1-ReN/s56No/JbruP/U2niu18iAXo=", + "dev": true + } + } + }, + "ajv": { + "version": "4.11.8", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-4.11.8.tgz", + "integrity": "sha1-gv+wKynmYq5TvcIK8VlHcGc5xTY=", + "dev": true, + "requires": { + "co": "4.6.0", + "json-stable-stringify": "1.0.1" + } + }, + "ajv-keywords": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-1.5.1.tgz", + "integrity": "sha1-MU3QpLM2j609/NxU7eYXG4htrzw=", + "dev": true + }, + "ansi-escapes": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-1.4.0.tgz", + "integrity": "sha1-06ioOzGapneTZisT52HHkRQiMG4=", + "dev": true + }, + "ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", + "dev": true + }, + "ansi-styles": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.0.tgz", + "integrity": "sha512-NnSOmMEYtVR2JVMIGTzynRkkaxtiq1xnFBcdQD/DnNCYPoEPsVJhM98BDyaoNOQIi7p4okdi3E27eN7GQbsUug==", + "requires": { + "color-convert": "1.9.1" + } + }, + "argparse": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.9.tgz", + "integrity": "sha1-c9g7wmP4bpf4zE9rrhsOkKfSLIY=", + "dev": true, + "requires": { + "sprintf-js": "1.0.3" + } + }, + "array-union": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-1.0.2.tgz", + "integrity": "sha1-mjRBDk9OPaI96jdb5b5w8kd47Dk=", + "dev": true, + "requires": { + "array-uniq": "1.0.3" + } + }, + "array-uniq": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/array-uniq/-/array-uniq-1.0.3.tgz", + "integrity": "sha1-r2rId6Jcx/dOBYiUdThY39sk/bY=", + "dev": true + }, + "arrify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", + "integrity": "sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=", + "dev": true + }, + "babel-code-frame": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-code-frame/-/babel-code-frame-6.26.0.tgz", + "integrity": "sha1-Y/1D99weO7fONZR9uP42mj9Yx0s=", + "dev": true, + "requires": { + "chalk": "1.1.3", + "esutils": "2.0.2", + "js-tokens": "3.0.2" + }, + "dependencies": { + "ansi-styles": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", + "dev": true + }, + "chalk": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", + "dev": true, + "requires": { + "ansi-styles": "2.2.1", + "escape-string-regexp": "1.0.5", + "has-ansi": "2.0.0", + "strip-ansi": "3.0.1", + "supports-color": "2.0.0" + } + }, + "supports-color": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", + "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", + "dev": true + } + } + }, + "balanced-match": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", + "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", + "dev": true + }, + "brace-expansion": { + "version": "1.1.8", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.8.tgz", + "integrity": "sha1-wHshHHyVLsH479Uad+8NHTmQopI=", + "dev": true, + "requires": { + "balanced-match": "1.0.0", + "concat-map": "0.0.1" + } + }, + "caller-path": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/caller-path/-/caller-path-0.1.0.tgz", + "integrity": "sha1-lAhe9jWB7NPaqSREqP6U6CV3dR8=", + "dev": true, + "requires": { + "callsites": "0.2.0" + } + }, + "callsites": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-0.2.0.tgz", + "integrity": "sha1-r6uWJikQp/M8GaV3WCXGnzTjUMo=", + "dev": true + }, + "chalk": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.3.0.tgz", + "integrity": "sha512-Az5zJR2CBujap2rqXGaJKaPHyJ0IrUimvYNX+ncCy8PJP4ltOGTrHUIo097ZaL2zMeKYpiCdqDvS6zdrTFok3Q==", + "requires": { + "ansi-styles": "3.2.0", + "escape-string-regexp": "1.0.5", + "supports-color": "4.5.0" + } + }, + "circular-json": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/circular-json/-/circular-json-0.3.3.tgz", + "integrity": "sha512-UZK3NBx2Mca+b5LsG7bY183pHWt5Y1xts4P3Pz7ENTwGVnJOUWbRb3ocjvX7hx9tq/yTAdclXm9sZ38gNuem4A==", + "dev": true + }, + "cli-cursor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-1.0.2.tgz", + "integrity": "sha1-ZNo/fValRBLll5S9Ytw1KV6PKYc=", + "dev": true, + "requires": { + "restore-cursor": "1.0.1" + } + }, + "cli-width": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-2.2.0.tgz", + "integrity": "sha1-/xnt6Kml5XkyQUewwR8PvLq+1jk=", + "dev": true + }, + "co": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", + "integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ=", + "dev": true + }, + "code-point-at": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", + "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=", + "dev": true + }, + "color-convert": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.1.tgz", + "integrity": "sha512-mjGanIiwQJskCC18rPR6OmrZ6fm2Lc7PeGFYwCmy5J34wC6F1PzdGL6xeMfmgicfYcNLGuVFA3WzXtIDCQSZxQ==", + "requires": { + "color-name": "1.1.3" + } + }, + "color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=" + }, + "concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", + "dev": true + }, + "concat-stream": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.0.tgz", + "integrity": "sha1-CqxmL9Ur54lk1VMvaUeE5wEQrPc=", + "dev": true, + "requires": { + "inherits": "2.0.3", + "readable-stream": "2.3.3", + "typedarray": "0.0.6" + } + }, + "core-util-is": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", + "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=", + "dev": true + }, + "cross-spawn": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-5.1.0.tgz", + "integrity": "sha1-6L0O/uWPz/b4+UUQoKVUu/ojVEk=", + "dev": true, + "requires": { + "lru-cache": "4.1.1", + "shebang-command": "1.2.0", + "which": "1.2.14" + } + }, + "d": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/d/-/d-1.0.0.tgz", + "integrity": "sha1-dUu1v+VUUdpppYuU1F9MWwRi1Y8=", + "dev": true, + "requires": { + "es5-ext": "0.10.37" + } + }, + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "deep-is": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz", + "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=", + "dev": true + }, + "del": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/del/-/del-2.2.2.tgz", + "integrity": "sha1-wSyYHQZ4RshLyvhiz/kw2Qf/0ag=", + "dev": true, + "requires": { + "globby": "5.0.0", + "is-path-cwd": "1.0.0", + "is-path-in-cwd": "1.0.0", + "object-assign": "4.1.1", + "pify": "2.3.0", + "pinkie-promise": "2.0.1", + "rimraf": "2.6.2" + } + }, + "doctrine": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.0.2.tgz", + "integrity": "sha512-y0tm5Pq6ywp3qSTZ1vPgVdAnbDEoeoc5wlOHXoY1c4Wug/a7JvqHIl7BTvwodaHmejWkK/9dSb3sCYfyo/om8A==", + "dev": true, + "requires": { + "esutils": "2.0.2" + } + }, + "es5-ext": { + "version": "0.10.37", + "resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.37.tgz", + "integrity": "sha1-DudB0Ui4AGm6J9AgOTdWryV978M=", + "dev": true, + "requires": { + "es6-iterator": "2.0.3", + "es6-symbol": "3.1.1" + } + }, + "es6-iterator": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/es6-iterator/-/es6-iterator-2.0.3.tgz", + "integrity": "sha1-p96IkUGgWpSwhUQDstCg+/qY87c=", + "dev": true, + "requires": { + "d": "1.0.0", + "es5-ext": "0.10.37", + "es6-symbol": "3.1.1" + } + }, + "es6-map": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/es6-map/-/es6-map-0.1.5.tgz", + "integrity": "sha1-kTbgUD3MBqMBaQ8LsU/042TpSfA=", + "dev": true, + "requires": { + "d": "1.0.0", + "es5-ext": "0.10.37", + "es6-iterator": "2.0.3", + "es6-set": "0.1.5", + "es6-symbol": "3.1.1", + "event-emitter": "0.3.5" + } + }, + "es6-set": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/es6-set/-/es6-set-0.1.5.tgz", + "integrity": "sha1-0rPsXU2ADO2BjbU40ol02wpzzLE=", + "dev": true, + "requires": { + "d": "1.0.0", + "es5-ext": "0.10.37", + "es6-iterator": "2.0.3", + "es6-symbol": "3.1.1", + "event-emitter": "0.3.5" + } + }, + "es6-symbol": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/es6-symbol/-/es6-symbol-3.1.1.tgz", + "integrity": "sha1-vwDvT9q2uhtG7Le2KbTH7VcVzHc=", + "dev": true, + "requires": { + "d": "1.0.0", + "es5-ext": "0.10.37" + } + }, + "es6-weak-map": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/es6-weak-map/-/es6-weak-map-2.0.2.tgz", + "integrity": "sha1-XjqzIlH/0VOKH45f+hNXdy+S2W8=", + "dev": true, + "requires": { + "d": "1.0.0", + "es5-ext": "0.10.37", + "es6-iterator": "2.0.3", + "es6-symbol": "3.1.1" + } + }, + "escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=" + }, + "escope": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/escope/-/escope-3.6.0.tgz", + "integrity": "sha1-4Bl16BJ4GhY6ba392AOY3GTIicM=", + "dev": true, + "requires": { + "es6-map": "0.1.5", + "es6-weak-map": "2.0.2", + "esrecurse": "4.2.0", + "estraverse": "4.2.0" + } + }, + "eslint": { + "version": "3.19.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-3.19.0.tgz", + "integrity": "sha1-yPxiAcf0DdCJQbh8CFdnOGpnmsw=", + "dev": true, + "requires": { + "babel-code-frame": "6.26.0", + "chalk": "1.1.3", + "concat-stream": "1.6.0", + "debug": "2.6.9", + "doctrine": "2.0.2", + "escope": "3.6.0", + "espree": "3.5.2", + "esquery": "1.0.0", + "estraverse": "4.2.0", + "esutils": "2.0.2", + "file-entry-cache": "2.0.0", + "glob": "7.1.2", + "globals": "9.18.0", + "ignore": "3.3.7", + "imurmurhash": "0.1.4", + "inquirer": "0.12.0", + "is-my-json-valid": "2.17.1", + "is-resolvable": "1.0.1", + "js-yaml": "3.10.0", + "json-stable-stringify": "1.0.1", + "levn": "0.3.0", + "lodash": "4.17.4", + "mkdirp": "0.5.1", + "natural-compare": "1.4.0", + "optionator": "0.8.2", + "path-is-inside": "1.0.2", + "pluralize": "1.2.1", + "progress": "1.1.8", + "require-uncached": "1.0.3", + "shelljs": "0.7.8", + "strip-bom": "3.0.0", + "strip-json-comments": "2.0.1", + "table": "3.8.3", + "text-table": "0.2.0", + "user-home": "2.0.0" + }, + "dependencies": { + "ansi-styles": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", + "dev": true + }, + "chalk": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", + "dev": true, + "requires": { + "ansi-styles": "2.2.1", + "escape-string-regexp": "1.0.5", + "has-ansi": "2.0.0", + "strip-ansi": "3.0.1", + "supports-color": "2.0.0" + } + }, + "supports-color": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", + "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", + "dev": true + } + } + }, + "eslint-config-dev": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/eslint-config-dev/-/eslint-config-dev-2.0.0.tgz", + "integrity": "sha1-guXKMTRJr3sSu/1OlzPrKG8PQ7c=", + "dev": true + }, + "espree": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/espree/-/espree-3.5.2.tgz", + "integrity": "sha512-sadKeYwaR/aJ3stC2CdvgXu1T16TdYN+qwCpcWbMnGJ8s0zNWemzrvb2GbD4OhmJ/fwpJjudThAlLobGbWZbCQ==", + "dev": true, + "requires": { + "acorn": "5.2.1", + "acorn-jsx": "3.0.1" + } + }, + "esprima": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.0.tgz", + "integrity": "sha512-oftTcaMu/EGrEIu904mWteKIv8vMuOgGYo7EhVJJN00R/EED9DCua/xxHRdYnKtcECzVg7xOWhflvJMnqcFZjw==", + "dev": true + }, + "esquery": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.0.0.tgz", + "integrity": "sha1-z7qLV9f7qT8XKYqKAGoEzaE9gPo=", + "dev": true, + "requires": { + "estraverse": "4.2.0" + } + }, + "esrecurse": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.2.0.tgz", + "integrity": "sha1-+pVo2Y04I/mkHZHpAtyrnqblsWM=", + "dev": true, + "requires": { + "estraverse": "4.2.0", + "object-assign": "4.1.1" + } + }, + "estraverse": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.2.0.tgz", + "integrity": "sha1-De4/7TH81GlhjOc0IJn8GvoL2xM=", + "dev": true + }, + "esutils": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.2.tgz", + "integrity": "sha1-Cr9PHKpbyx96nYrMbepPqqBLrJs=", + "dev": true + }, + "event-emitter": { + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/event-emitter/-/event-emitter-0.3.5.tgz", + "integrity": "sha1-34xp7vFkeSPHFXuc6DhAYQsCzDk=", + "dev": true, + "requires": { + "d": "1.0.0", + "es5-ext": "0.10.37" + } + }, + "exit-hook": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/exit-hook/-/exit-hook-1.1.1.tgz", + "integrity": "sha1-8FyiM7SMBdVP/wd2XfhQfpXAL/g=", + "dev": true + }, + "fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", + "dev": true + }, + "figures": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/figures/-/figures-1.7.0.tgz", + "integrity": "sha1-y+Hjr/zxzUS4DK3+0o3Hk6lwHS4=", + "dev": true, + "requires": { + "escape-string-regexp": "1.0.5", + "object-assign": "4.1.1" + } + }, + "file-entry-cache": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-2.0.0.tgz", + "integrity": "sha1-w5KZDD5oR4PYOLjISkXYoEhFg2E=", + "dev": true, + "requires": { + "flat-cache": "1.3.0", + "object-assign": "4.1.1" + } + }, + "flat-cache": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-1.3.0.tgz", + "integrity": "sha1-0wMLMrOBVPTjt+nHCfSQ9++XxIE=", + "dev": true, + "requires": { + "circular-json": "0.3.3", + "del": "2.2.2", + "graceful-fs": "4.1.11", + "write": "0.2.1" + } + }, + "flatten": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/flatten/-/flatten-1.0.2.tgz", + "integrity": "sha1-2uRqnXj74lKSJYzB54CkHZXAN4I=" + }, + "fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", + "dev": true + }, + "generate-function": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/generate-function/-/generate-function-2.0.0.tgz", + "integrity": "sha1-aFj+fAlpt9TpCTM3ZHrHn2DfvnQ=", + "dev": true + }, + "generate-object-property": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/generate-object-property/-/generate-object-property-1.2.0.tgz", + "integrity": "sha1-nA4cQDCM6AT0eDYYuTf6iPmdUNA=", + "dev": true, + "requires": { + "is-property": "1.0.2" + } + }, + "glob": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz", + "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==", + "dev": true, + "requires": { + "fs.realpath": "1.0.0", + "inflight": "1.0.6", + "inherits": "2.0.3", + "minimatch": "3.0.4", + "once": "1.4.0", + "path-is-absolute": "1.0.1" + } + }, + "globals": { + "version": "9.18.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-9.18.0.tgz", + "integrity": "sha512-S0nG3CLEQiY/ILxqtztTWH/3iRRdyBLw6KMDxnKMchrtbj2OFmehVh0WUCfW3DUrIgx/qFrJPICrq4Z4sTR9UQ==", + "dev": true + }, + "globby": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-5.0.0.tgz", + "integrity": "sha1-69hGZ8oNuzMLmbz8aOrCvFQ3Dg0=", + "dev": true, + "requires": { + "array-union": "1.0.2", + "arrify": "1.0.1", + "glob": "7.1.2", + "object-assign": "4.1.1", + "pify": "2.3.0", + "pinkie-promise": "2.0.1" + } + }, + "graceful-fs": { + "version": "4.1.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.11.tgz", + "integrity": "sha1-Dovf5NHduIVNZOBOp8AOKgJuVlg=", + "dev": true + }, + "has-ansi": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", + "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=", + "dev": true, + "requires": { + "ansi-regex": "2.1.1" + } + }, + "has-flag": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz", + "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=" + }, + "ignore": { + "version": "3.3.7", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-3.3.7.tgz", + "integrity": "sha512-YGG3ejvBNHRqu0559EOxxNFihD0AjpvHlC/pdGKd3X3ofe+CoJkYazwNJYTNebqpPKN+VVQbh4ZFn1DivMNuHA==", + "dev": true + }, + "imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", + "dev": true + }, + "indexes-of": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/indexes-of/-/indexes-of-1.0.1.tgz", + "integrity": "sha1-8w9xbI4r00bHtn0985FVZqfAVgc=" + }, + "inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "dev": true, + "requires": { + "once": "1.4.0", + "wrappy": "1.0.2" + } + }, + "inherits": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", + "dev": true + }, + "inquirer": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-0.12.0.tgz", + "integrity": "sha1-HvK/1jUE3wvHV4X/+MLEHfEvB34=", + "dev": true, + "requires": { + "ansi-escapes": "1.4.0", + "ansi-regex": "2.1.1", + "chalk": "1.1.3", + "cli-cursor": "1.0.2", + "cli-width": "2.2.0", + "figures": "1.7.0", + "lodash": "4.17.4", + "readline2": "1.0.1", + "run-async": "0.1.0", + "rx-lite": "3.1.2", + "string-width": "1.0.2", + "strip-ansi": "3.0.1", + "through": "2.3.8" + }, + "dependencies": { + "ansi-styles": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", + "dev": true + }, + "chalk": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", + "dev": true, + "requires": { + "ansi-styles": "2.2.1", + "escape-string-regexp": "1.0.5", + "has-ansi": "2.0.0", + "strip-ansi": "3.0.1", + "supports-color": "2.0.0" + } + }, + "supports-color": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", + "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", + "dev": true + } + } + }, + "interpret": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.1.0.tgz", + "integrity": "sha1-ftGxQQxqDg94z5XTuEQMY/eLhhQ=", + "dev": true + }, + "is-fullwidth-code-point": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", + "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", + "dev": true, + "requires": { + "number-is-nan": "1.0.1" + } + }, + "is-my-json-valid": { + "version": "2.17.1", + "resolved": "https://registry.npmjs.org/is-my-json-valid/-/is-my-json-valid-2.17.1.tgz", + "integrity": "sha512-Q2khNw+oBlWuaYvEEHtKSw/pCxD2L5Rc1C+UQme9X6JdRDh7m5D7HkozA0qa3DUkQ6VzCnEm8mVIQPyIRkI5sQ==", + "dev": true, + "requires": { + "generate-function": "2.0.0", + "generate-object-property": "1.2.0", + "jsonpointer": "4.0.1", + "xtend": "4.0.1" + } + }, + "is-path-cwd": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-path-cwd/-/is-path-cwd-1.0.0.tgz", + "integrity": "sha1-0iXsIxMuie3Tj9p2dHLmLmXxEG0=", + "dev": true + }, + "is-path-in-cwd": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-path-in-cwd/-/is-path-in-cwd-1.0.0.tgz", + "integrity": "sha1-ZHdYK4IU1gI0YJRWcAO+ip6sBNw=", + "dev": true, + "requires": { + "is-path-inside": "1.0.1" + } + }, + "is-path-inside": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-1.0.1.tgz", + "integrity": "sha1-jvW33lBDej/cprToZe96pVy0gDY=", + "dev": true, + "requires": { + "path-is-inside": "1.0.2" + } + }, + "is-property": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-property/-/is-property-1.0.2.tgz", + "integrity": "sha1-V/4cTkhHTt1lsJkR8msc1Ald2oQ=", + "dev": true + }, + "is-resolvable": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-resolvable/-/is-resolvable-1.0.1.tgz", + "integrity": "sha512-y5CXYbzvB3jTnWAZH1Nl7ykUWb6T3BcTs56HUruwBf8MhF56n1HWqhDWnVFo8GHrUPDgvUUNVhrc2U8W7iqz5g==", + "dev": true + }, + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", + "dev": true + }, + "isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", + "dev": true + }, + "js-tokens": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-3.0.2.tgz", + "integrity": "sha1-mGbfOVECEw449/mWvOtlRDIJwls=", + "dev": true + }, + "js-yaml": { + "version": "3.10.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.10.0.tgz", + "integrity": "sha512-O2v52ffjLa9VeM43J4XocZE//WT9N0IiwDa3KSHH7Tu8CtH+1qM8SIZvnsTh6v+4yFy5KUY3BHUVwjpfAWsjIA==", + "dev": true, + "requires": { + "argparse": "1.0.9", + "esprima": "4.0.0" + } + }, + "json-stable-stringify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify/-/json-stable-stringify-1.0.1.tgz", + "integrity": "sha1-mnWdOcXy/1A/1TAGRu1EX4jE+a8=", + "dev": true, + "requires": { + "jsonify": "0.0.0" + } + }, + "jsonify": { + "version": "0.0.0", + "resolved": "https://registry.npmjs.org/jsonify/-/jsonify-0.0.0.tgz", + "integrity": "sha1-LHS27kHZPKUbe1qu6PUDYx0lKnM=", + "dev": true + }, + "jsonpointer": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/jsonpointer/-/jsonpointer-4.0.1.tgz", + "integrity": "sha1-T9kss04OnbPInIYi7PUfm5eMbLk=", + "dev": true + }, + "levn": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", + "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=", + "dev": true, + "requires": { + "prelude-ls": "1.1.2", + "type-check": "0.3.2" + } + }, + "lodash": { + "version": "4.17.4", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.4.tgz", + "integrity": "sha1-eCA6TRwyiuHYbcpkYONptX9AVa4=", + "dev": true + }, + "lru-cache": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.1.tgz", + "integrity": "sha512-q4spe4KTfsAS1SUHLO0wz8Qiyf1+vMIAgpRYioFYDMNqKfHQbg+AVDH3i4fvpl71/P1L0dBl+fQi+P37UYf0ew==", + "dev": true, + "requires": { + "pseudomap": "1.0.2", + "yallist": "2.1.2" + } + }, + "minimatch": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", + "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "dev": true, + "requires": { + "brace-expansion": "1.1.8" + } + }, + "minimist": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", + "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=", + "dev": true + }, + "mkdirp": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", + "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", + "dev": true, + "requires": { + "minimist": "0.0.8" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + }, + "mute-stream": { + "version": "0.0.5", + "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.5.tgz", + "integrity": "sha1-j7+rsKmKJT0xhDMfno3rc3L6xsA=", + "dev": true + }, + "natural-compare": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=", + "dev": true + }, + "number-is-nan": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", + "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=", + "dev": true + }, + "object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", + "dev": true + }, + "once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "dev": true, + "requires": { + "wrappy": "1.0.2" + } + }, + "onetime": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-1.1.0.tgz", + "integrity": "sha1-ofeDj4MUxRbwXs78vEzP4EtO14k=", + "dev": true + }, + "optionator": { + "version": "0.8.2", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.2.tgz", + "integrity": "sha1-NkxeQJ0/TWMB1sC0wFu6UBgK62Q=", + "dev": true, + "requires": { + "deep-is": "0.1.3", + "fast-levenshtein": "2.0.6", + "levn": "0.3.0", + "prelude-ls": "1.1.2", + "type-check": "0.3.2", + "wordwrap": "1.0.0" + } + }, + "os-homedir": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz", + "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=", + "dev": true + }, + "os-shim": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/os-shim/-/os-shim-0.1.3.tgz", + "integrity": "sha1-a2LDeRz3kJ6jXtRuF2WLtBfLORc=", + "dev": true + }, + "path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", + "dev": true + }, + "path-is-inside": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz", + "integrity": "sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM=", + "dev": true + }, + "path-parse": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.5.tgz", + "integrity": "sha1-PBrfhx6pzWyUMbbqK9dKD/BVxME=", + "dev": true + }, + "pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", + "dev": true + }, + "pinkie": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz", + "integrity": "sha1-clVrgM+g1IqXToDnckjoDtT3+HA=", + "dev": true + }, + "pinkie-promise": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz", + "integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=", + "dev": true, + "requires": { + "pinkie": "2.0.4" + } + }, + "pluralize": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/pluralize/-/pluralize-1.2.1.tgz", + "integrity": "sha1-0aIUg/0iu0HlihL6NCGCMUCJfEU=", + "dev": true + }, + "postcss": { + "version": "6.0.14", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.14.tgz", + "integrity": "sha512-NJ1z0f+1offCgadPhz+DvGm5Mkci+mmV5BqD13S992o0Xk9eElxUfPPF+t2ksH5R/17gz4xVK8KWocUQ5o3Rog==", + "requires": { + "chalk": "2.3.0", + "source-map": "0.6.1", + "supports-color": "4.5.0" + } + }, + "postcss-selector-parser": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-2.2.3.tgz", + "integrity": "sha1-+UN3iGBsPJrO4W/+jYsWKX8nu5A=", + "requires": { + "flatten": "1.0.2", + "indexes-of": "1.0.1", + "uniq": "1.0.1" + } + }, + "postcss-tape": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/postcss-tape/-/postcss-tape-2.0.1.tgz", + "integrity": "sha1-PP4pUg4ZJ4E3zCvTXOeyvXq42jY=", + "dev": true + }, + "pre-commit": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/pre-commit/-/pre-commit-1.2.2.tgz", + "integrity": "sha1-287g7p3nI15X95xW186UZBpp7sY=", + "dev": true, + "requires": { + "cross-spawn": "5.1.0", + "spawn-sync": "1.0.15", + "which": "1.2.14" + } + }, + "prelude-ls": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", + "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=", + "dev": true + }, + "process-nextick-args": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-1.0.7.tgz", + "integrity": "sha1-FQ4gt1ZZCtP5EJPyWk8q2L/zC6M=", + "dev": true + }, + "progress": { + "version": "1.1.8", + "resolved": "https://registry.npmjs.org/progress/-/progress-1.1.8.tgz", + "integrity": "sha1-4mDHj2Fhzdmw5WzD4Khd4Xx6V74=", + "dev": true + }, + "pseudomap": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", + "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=", + "dev": true + }, + "readable-stream": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.3.tgz", + "integrity": "sha512-m+qzzcn7KUxEmd1gMbchF+Y2eIUbieUaxkWtptyHywrX0rE8QEYqPC07Vuy4Wm32/xE16NcdBctb8S0Xe/5IeQ==", + "dev": true, + "requires": { + "core-util-is": "1.0.2", + "inherits": "2.0.3", + "isarray": "1.0.0", + "process-nextick-args": "1.0.7", + "safe-buffer": "5.1.1", + "string_decoder": "1.0.3", + "util-deprecate": "1.0.2" + } + }, + "readline2": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/readline2/-/readline2-1.0.1.tgz", + "integrity": "sha1-QQWWCP/BVHV7cV2ZidGZ/783LjU=", + "dev": true, + "requires": { + "code-point-at": "1.1.0", + "is-fullwidth-code-point": "1.0.0", + "mute-stream": "0.0.5" + } + }, + "rechoir": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.6.2.tgz", + "integrity": "sha1-hSBLVNuoLVdC4oyWdW70OvUOM4Q=", + "dev": true, + "requires": { + "resolve": "1.5.0" + } + }, + "require-uncached": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/require-uncached/-/require-uncached-1.0.3.tgz", + "integrity": "sha1-Tg1W1slmL9MeQwEcS5WqSZVUIdM=", + "dev": true, + "requires": { + "caller-path": "0.1.0", + "resolve-from": "1.0.1" + } + }, + "resolve": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.5.0.tgz", + "integrity": "sha512-hgoSGrc3pjzAPHNBg+KnFcK2HwlHTs/YrAGUr6qgTVUZmXv1UEXXl0bZNBKMA9fud6lRYFdPGz0xXxycPzmmiw==", + "dev": true, + "requires": { + "path-parse": "1.0.5" + } + }, + "resolve-from": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-1.0.1.tgz", + "integrity": "sha1-Jsv+k10a7uq7Kbw/5a6wHpPUQiY=", + "dev": true + }, + "restore-cursor": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-1.0.1.tgz", + "integrity": "sha1-NGYfRohjJ/7SmRR5FSJS35LapUE=", + "dev": true, + "requires": { + "exit-hook": "1.1.1", + "onetime": "1.1.0" + } + }, + "rimraf": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.2.tgz", + "integrity": "sha512-lreewLK/BlghmxtfH36YYVg1i8IAce4TI7oao75I1g245+6BctqTVQiBP3YUJ9C6DQOXJmkYR9X9fCLtCOJc5w==", + "dev": true, + "requires": { + "glob": "7.1.2" + } + }, + "run-async": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/run-async/-/run-async-0.1.0.tgz", + "integrity": "sha1-yK1KXhEGYeQCp9IbUw4AnyX444k=", + "dev": true, + "requires": { + "once": "1.4.0" + } + }, + "rx-lite": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/rx-lite/-/rx-lite-3.1.2.tgz", + "integrity": "sha1-Gc5QLKVyZl87ZHsQk5+X/RYV8QI=", + "dev": true + }, + "safe-buffer": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.1.tgz", + "integrity": "sha512-kKvNJn6Mm93gAczWVJg7wH+wGYWNrDHdWvpUmHyEsgCtIwwo3bqPtV4tR5tuPaUhTOo/kvhVwd8XwwOllGYkbg==", + "dev": true + }, + "shebang-command": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", + "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=", + "dev": true, + "requires": { + "shebang-regex": "1.0.0" + } + }, + "shebang-regex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", + "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=", + "dev": true + }, + "shelljs": { + "version": "0.7.8", + "resolved": "https://registry.npmjs.org/shelljs/-/shelljs-0.7.8.tgz", + "integrity": "sha1-3svPh0sNHl+3LhSxZKloMEjprLM=", + "dev": true, + "requires": { + "glob": "7.1.2", + "interpret": "1.1.0", + "rechoir": "0.6.2" + } + }, + "slice-ansi": { + "version": "0.0.4", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-0.0.4.tgz", + "integrity": "sha1-7b+JA/ZvfOL46v1s7tZeJkyDGzU=", + "dev": true + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" + }, + "spawn-sync": { + "version": "1.0.15", + "resolved": "https://registry.npmjs.org/spawn-sync/-/spawn-sync-1.0.15.tgz", + "integrity": "sha1-sAeZVX63+wyDdsKdROih6mfldHY=", + "dev": true, + "requires": { + "concat-stream": "1.6.0", + "os-shim": "0.1.3" + } + }, + "sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", + "dev": true + }, + "string-width": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", + "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", + "dev": true, + "requires": { + "code-point-at": "1.1.0", + "is-fullwidth-code-point": "1.0.0", + "strip-ansi": "3.0.1" + } + }, + "string_decoder": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz", + "integrity": "sha512-4AH6Z5fzNNBcH+6XDMfA/BTt87skxqJlO0lAh3Dker5zThcAxG6mKz+iGu308UKoPPQ8Dcqx/4JhujzltRa+hQ==", + "dev": true, + "requires": { + "safe-buffer": "5.1.1" + } + }, + "strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "dev": true, + "requires": { + "ansi-regex": "2.1.1" + } + }, + "strip-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", + "dev": true + }, + "strip-json-comments": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", + "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=", + "dev": true + }, + "supports-color": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.5.0.tgz", + "integrity": "sha1-vnoN5ITexcXN34s9WRJQRJEvY1s=", + "requires": { + "has-flag": "2.0.0" + } + }, + "table": { + "version": "3.8.3", + "resolved": "https://registry.npmjs.org/table/-/table-3.8.3.tgz", + "integrity": "sha1-K7xULw/amGGnVdOUf+/Ys/UThV8=", + "dev": true, + "requires": { + "ajv": "4.11.8", + "ajv-keywords": "1.5.1", + "chalk": "1.1.3", + "lodash": "4.17.4", + "slice-ansi": "0.0.4", + "string-width": "2.1.1" + }, + "dependencies": { + "ansi-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", + "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", + "dev": true + }, + "ansi-styles": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", + "dev": true + }, + "chalk": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", + "dev": true, + "requires": { + "ansi-styles": "2.2.1", + "escape-string-regexp": "1.0.5", + "has-ansi": "2.0.0", + "strip-ansi": "3.0.1", + "supports-color": "2.0.0" + } + }, + "is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", + "dev": true + }, + "string-width": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", + "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", + "dev": true, + "requires": { + "is-fullwidth-code-point": "2.0.0", + "strip-ansi": "4.0.0" + }, + "dependencies": { + "strip-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", + "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", + "dev": true, + "requires": { + "ansi-regex": "3.0.0" + } + } + } + }, + "supports-color": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", + "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", + "dev": true + } + } + }, + "text-table": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", + "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=", + "dev": true + }, + "through": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", + "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=", + "dev": true + }, + "type-check": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", + "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=", + "dev": true, + "requires": { + "prelude-ls": "1.1.2" + } + }, + "typedarray": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", + "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=", + "dev": true + }, + "uniq": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/uniq/-/uniq-1.0.1.tgz", + "integrity": "sha1-sxxa6CVIRKOoKBVBzisEuGWnNP8=" + }, + "user-home": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/user-home/-/user-home-2.0.0.tgz", + "integrity": "sha1-nHC/2Babwdy/SGBODwS4tJzenp8=", + "dev": true, + "requires": { + "os-homedir": "1.0.2" + } + }, + "util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=", + "dev": true + }, + "which": { + "version": "1.2.14", + "resolved": "https://registry.npmjs.org/which/-/which-1.2.14.tgz", + "integrity": "sha1-mofEN48D6CfOyvGs31bHNsAcFOU=", + "dev": true, + "requires": { + "isexe": "2.0.0" + } + }, + "wordwrap": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", + "integrity": "sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus=", + "dev": true + }, + "wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", + "dev": true + }, + "write": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/write/-/write-0.2.1.tgz", + "integrity": "sha1-X8A4KOJkzqP+kUVUdvejxWbLB1c=", + "dev": true, + "requires": { + "mkdirp": "0.5.1" + } + }, + "xtend": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz", + "integrity": "sha1-pcbVMr5lbiPbgg77lDofBJmNY68=", + "dev": true + }, + "yallist": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", + "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=", + "dev": true + } + } +} diff --git a/package.json b/package.json index 26655147eb..66b9550d2f 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "postcss-focus-ring", "version": "1.0.0", - "description": "Use the :focus-ring pseudo-selector in CSS", + "description": "Use the :focus-visible pseudo-selector in CSS", "author": "Jonathan Neal ", "license": "CC0-1.0", "repository": "jonathantneal/postcss-focus-ring", diff --git a/test/basic.css b/test/basic.css index 06df6bf939..eb304180a1 100644 --- a/test/basic.css +++ b/test/basic.css @@ -1,20 +1,20 @@ -:focus-ring { +:focus-visible { order: 1; } -:focus-ring, -:focus-ring test, -test :focus-ring, -test test:focus-ring, -test :focus-ring test, -test test:focus-ring test, -test :focus-ring :focus-ring test, -test :matches(:focus-ring) test, -test :matches(:focus-ring test) test, -test :matches(test :focus-ring) test, -test :matches(test test:focus-ring) test, -test :matches(test :focus-ring test) test, -test :matches(test test:focus-ring test) test, -test :matches(test :focus-ring :focus-ring test) test { +:focus-visible, +:focus-visible test, +test :focus-visible, +test test:focus-visible, +test :focus-visible test, +test test:focus-visible test, +test :focus-visible :focus-visible test, +test :matches(:focus-visible) test, +test :matches(:focus-visible test) test, +test :matches(test :focus-visible) test, +test :matches(test test:focus-visible) test, +test :matches(test :focus-visible test) test, +test :matches(test test:focus-visible test) test, +test :matches(test :focus-visible :focus-visible test) test { order: 2; } diff --git a/test/basic.expect.css b/test/basic.expect.css index 5f92e4fad5..e31bfbc490 100644 --- a/test/basic.expect.css +++ b/test/basic.expect.css @@ -1,20 +1,20 @@ -.focus-ring { +.focus-visible { order: 1; } -.focus-ring, -.focus-ring test, -test .focus-ring, -test test.focus-ring, -test .focus-ring test, -test test.focus-ring test, -test .focus-ring .focus-ring test, -test :matches(.focus-ring) test, -test :matches(.focus-ring test) test, -test :matches(test .focus-ring) test, -test :matches(test test.focus-ring) test, -test :matches(test .focus-ring test) test, -test :matches(test test.focus-ring test) test, -test :matches(test .focus-ring .focus-ring test) test { +.focus-visible, +.focus-visible test, +test .focus-visible, +test test.focus-visible, +test .focus-visible test, +test test.focus-visible test, +test .focus-visible .focus-visible test, +test :matches(.focus-visible) test, +test :matches(.focus-visible test) test, +test :matches(test .focus-visible) test, +test :matches(test test.focus-visible) test, +test :matches(test .focus-visible test) test, +test :matches(test test.focus-visible test) test, +test :matches(test .focus-visible .focus-visible test) test { order: 2; } From 59ba7a6ceefb8c6d4eab461f7b1e03e3123cc767 Mon Sep 17 00:00:00 2001 From: Jonathan Neal Date: Sat, 10 Feb 2018 15:09:31 -0500 Subject: [PATCH 561/795] Preserve declaration comments - Includes test --- index.js | 2 +- test/fixtures/substitution-defined.css | 3 +++ test/fixtures/substitution-defined.expected.css | 3 +++ 3 files changed, 7 insertions(+), 1 deletion(-) diff --git a/index.js b/index.js index 1ae92c9a6b..c2d1e90226 100755 --- a/index.js +++ b/index.js @@ -248,7 +248,7 @@ export default postcss.plugin("postcss-custom-properties", (options = {}) => { // resolve variables style.walkDecls((decl) => { - const value = decl.value + const value = decl.raws.value ? decl.raws.value.raw : decl.value // skip values that don’t contain variable functions if (!value || value.indexOf(VAR_FUNC_IDENTIFIER + "(") === -1) { diff --git a/test/fixtures/substitution-defined.css b/test/fixtures/substitution-defined.css index af44bfa459..c1f7a40232 100755 --- a/test/fixtures/substitution-defined.css +++ b/test/fixtures/substitution-defined.css @@ -21,6 +21,9 @@ div { /* single variable */ color: var(--test-one); + /* single variable with comments */ + color: /*comment before*/var(--test-one)/*comment after*/; + /* single variable with tail */ color: var(--test-one) !important; diff --git a/test/fixtures/substitution-defined.expected.css b/test/fixtures/substitution-defined.expected.css index d330bfe007..5d38f7ac23 100755 --- a/test/fixtures/substitution-defined.expected.css +++ b/test/fixtures/substitution-defined.expected.css @@ -13,6 +13,9 @@ div { /* single variable */ color: green; + /* single variable with comments */ + color: /*comment before*/green/*comment after*/; + /* single variable with tail */ color: green !important; From 86637d12722a42b9440a6788e2c79e9ac98e8209 Mon Sep 17 00:00:00 2001 From: Jonathan Neal Date: Sat, 10 Feb 2018 17:02:19 -0500 Subject: [PATCH 562/795] Only transform var() functions --- index.js | 9 +++++++-- test/fixtures/substitution-defined.css | 3 +++ test/fixtures/substitution-defined.expected.css | 3 +++ 3 files changed, 13 insertions(+), 2 deletions(-) diff --git a/index.js b/index.js index c2d1e90226..d95ad76d6a 100755 --- a/index.js +++ b/index.js @@ -3,6 +3,7 @@ import balanced from "balanced-match" const VAR_PROP_IDENTIFIER = "--" const VAR_FUNC_IDENTIFIER = "var" +const VAR_FUNC_REGEX = /(^|[^\w-])var\(/ // matches `name[, fallback]`, captures "name" and "fallback" const RE_VAR = /([\w-]+)(?:\s*,\s*)?\s*(.*)?/ @@ -27,11 +28,15 @@ let globalOpts function resolveValue(value, variables, result, decl) { const results = [] - const start = value.indexOf(VAR_FUNC_IDENTIFIER + "(") - if (start === -1) { + const hasVarFunction = VAR_FUNC_REGEX.test(value) + + if (!hasVarFunction) { return [value] } + const match = value.match(VAR_FUNC_REGEX) + const start = match.index + match[1].length + const matches = balanced("(", ")", value.substring(start)) if (!matches) { diff --git a/test/fixtures/substitution-defined.css b/test/fixtures/substitution-defined.css index c1f7a40232..f6dc84ba77 100755 --- a/test/fixtures/substitution-defined.css +++ b/test/fixtures/substitution-defined.css @@ -35,4 +35,7 @@ div { /* multiple variables within a function */ background: linear-gradient(to top, var(--test-one), var(--test-two)); + + /* untouched custom function */ + color: myvar(--test-one); } diff --git a/test/fixtures/substitution-defined.expected.css b/test/fixtures/substitution-defined.expected.css index 5d38f7ac23..531b6eee8f 100755 --- a/test/fixtures/substitution-defined.expected.css +++ b/test/fixtures/substitution-defined.expected.css @@ -28,4 +28,7 @@ div { /* multiple variables within a function */ background: linear-gradient(to top, green, blue); + + /* untouched custom function */ + color: myvar(--test-one); } From 3f4e7fa930c0de37c930ec50904d88edffbcba1d Mon Sep 17 00:00:00 2001 From: Jonathan Neal Date: Sat, 10 Feb 2018 17:11:05 -0500 Subject: [PATCH 563/795] Fix documentation for warning option --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 33e5e1c114..0b64e6c5ea 100755 --- a/README.md +++ b/README.md @@ -141,7 +141,7 @@ variables at the end of your CSS. #### `warnings` Default: `true` -Type: `Boolean|Object` +Type: `Boolean` Allows you to enable/disable warnings. If true, will enable all warnings. For now, it only allow to disable messages about custom properties definition From a64158a6128f9c7ba2b6c4a2f321d87ec8576646 Mon Sep 17 00:00:00 2001 From: Jonathan Neal Date: Thu, 15 Feb 2018 14:11:00 -0500 Subject: [PATCH 564/795] Update dependencies --- package.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/package.json b/package.json index 059d9b2111..5c6a160414 100644 --- a/package.json +++ b/package.json @@ -19,14 +19,14 @@ ], "dependencies": { "balanced-match": "^1.0.0", - "postcss": "^6.0.13" + "postcss": "^6.0.18" }, "devDependencies": { "babel-cli": "^6.26.0", "babel-plugin-add-module-exports": "^0.2.1", - "babel-preset-env": "^1.6.0", + "babel-preset-env": "^1.6.1", "babel-register": "^6.26.0", - "eslint": "^4.8.0", + "eslint": "^4.17.0", "npmpub": "^3.1.0", "tape": "^4.8.0" }, From 7cbf23941a5ca3294f291a068507e37e490fc92e Mon Sep 17 00:00:00 2001 From: Jonathan Neal Date: Thu, 15 Feb 2018 18:02:44 -0500 Subject: [PATCH 565/795] Support spec-valid whitespace https://www.w3.org/TR/css-syntax-3/#whitespace-diagram --- index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/index.js b/index.js index d95ad76d6a..acb982dc0c 100755 --- a/index.js +++ b/index.js @@ -5,7 +5,7 @@ const VAR_PROP_IDENTIFIER = "--" const VAR_FUNC_IDENTIFIER = "var" const VAR_FUNC_REGEX = /(^|[^\w-])var\(/ // matches `name[, fallback]`, captures "name" and "fallback" -const RE_VAR = /([\w-]+)(?:\s*,\s*)?\s*(.*)?/ +const RE_VAR = /[\f\n\r\t ]*([\w-]+)(?:[\f\n\r\t ]*,[\f\n\r\t ]*([\W\w]+))?/ /** * Module variables From c51737874d9b0dd4351eeb9f34ff25c93bad8519 Mon Sep 17 00:00:00 2001 From: Jonathan Neal Date: Thu, 15 Feb 2018 18:08:25 -0500 Subject: [PATCH 566/795] Make options more explicit expectations --- index.js | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/index.js b/index.js index acb982dc0c..cb3c85d9d2 100755 --- a/index.js +++ b/index.js @@ -163,15 +163,17 @@ export default postcss.plugin("postcss-custom-properties", (options = {}) => { function plugin(style, result) { const variables = prefixVariables(options.variables) - const strict = options.strict === undefined ? true : options.strict - const appendVariables = options.appendVariables - const preserve = options.preserve + const strict = "strict" in options ? Boolean(options.strict) : true + const appendVariables = "appendVariables" in options + ? Boolean(options.appendVariables) : false + const preserve = "preserve" in options ? options.preserve : null const map = {} const importantMap = {} globalOpts = { - warnings: options.warnings === undefined ? true : options.warnings, - noValueNotifications: options.noValueNotifications || "warning", + warnings: "warnings" in options ? Boolean(options.warnings) : true, + noValueNotifications: "noValueNotifications" in options + ? String(options.noValueNotifications) : "warning", } // define variables From 5d4620c658c480f5a99a1cc65f684cc2dee5088c Mon Sep 17 00:00:00 2001 From: Jonathan Neal Date: Thu, 15 Feb 2018 18:16:07 -0500 Subject: [PATCH 567/795] Preserve by default --- index.js | 2 +- .../automatic-variable-prefix.expected.css | 2 ++ test/fixtures/case-sensitive.expected.css | 7 +++++++ test/fixtures/circular-reference.expected.css | 9 ++++++++- test/fixtures/important.expected.css | 14 ++++++++++++++ test/fixtures/js-defined.expected.css | 11 +++++++++++ test/fixtures/js-override.expected.css | 11 +++++++++++ test/fixtures/remove-properties.expected.css | 10 ++++++++++ .../self-reference-double-fallback.expected.css | 8 ++++++++ .../self-reference-fallback.expected.css | 5 +++++ test/fixtures/self-reference.expected.css | 5 +++++ test/fixtures/substitution-defined.expected.css | 16 ++++++++++++++++ test/fixtures/substitution-fallback.expected.css | 14 ++++++++++++++ .../fixtures/substitution-overwrite.expected.css | 10 ++++++++++ test/fixtures/substitution-strict.expected.css | 9 +++++++++ .../substitution-trailing-space.expected.css | 7 ++++++- .../fixtures/substitution-undefined.expected.css | 10 ++++++++++ test/index.js | 2 +- 18 files changed, 148 insertions(+), 4 deletions(-) diff --git a/index.js b/index.js index cb3c85d9d2..36f1fd1996 100755 --- a/index.js +++ b/index.js @@ -166,7 +166,7 @@ export default postcss.plugin("postcss-custom-properties", (options = {}) => { const strict = "strict" in options ? Boolean(options.strict) : true const appendVariables = "appendVariables" in options ? Boolean(options.appendVariables) : false - const preserve = "preserve" in options ? options.preserve : null + const preserve = "preserve" in options ? options.preserve : true const map = {} const importantMap = {} diff --git a/test/fixtures/automatic-variable-prefix.expected.css b/test/fixtures/automatic-variable-prefix.expected.css index b9f2fdb43f..bf547b19a1 100644 --- a/test/fixtures/automatic-variable-prefix.expected.css +++ b/test/fixtures/automatic-variable-prefix.expected.css @@ -1,4 +1,6 @@ div { color: blue; + color: var(--unprefixed); background: white; + background: var(--prefixed); } diff --git a/test/fixtures/case-sensitive.expected.css b/test/fixtures/case-sensitive.expected.css index 365540a2ba..8543ba9256 100755 --- a/test/fixtures/case-sensitive.expected.css +++ b/test/fixtures/case-sensitive.expected.css @@ -1,4 +1,11 @@ +:root { + --TEST-color: red; + --tESt-COLOR: green; +} + div { color: red; + color: var(--TEST-color); color: green; + color: var(--tESt-COLOR); } diff --git a/test/fixtures/circular-reference.expected.css b/test/fixtures/circular-reference.expected.css index c04ff5b60b..cc73e70873 100644 --- a/test/fixtures/circular-reference.expected.css +++ b/test/fixtures/circular-reference.expected.css @@ -1,3 +1,10 @@ +:root { + --color: var(--color); + --color: var(--bg-color); + --bg-color: var(--color); + --bg-color: var(--color); +} body { - color: var(--bg-color); + color: var(--color); + color: var(--color); } diff --git a/test/fixtures/important.expected.css b/test/fixtures/important.expected.css index 0439cf8b3d..ec9f08768a 100644 --- a/test/fixtures/important.expected.css +++ b/test/fixtures/important.expected.css @@ -1,5 +1,19 @@ +:root { + --one: not important; + --one: important !important; + + --two: important !important; + --two: not important; + + --three: important !important; + --three: more important !important; +} + selector { one: important; + one: var(--one); two: important; + two: var(--two); three: more important; + three: var(--three); } diff --git a/test/fixtures/js-defined.expected.css b/test/fixtures/js-defined.expected.css index d043e0bf13..d7ce1b2c48 100755 --- a/test/fixtures/js-defined.expected.css +++ b/test/fixtures/js-defined.expected.css @@ -1,8 +1,19 @@ +:root { + --test-one: local; + --test-two: local; +} + div { p: js-one; + p: var(--test-one); p: js-two; + p: var(--test-two); p: js-three; + p: var(--test-three); p: js-one; + p: var(--test-varception); p: js-one; + p: var(--test-jsception); p: 1; + p: var(--test-num); } diff --git a/test/fixtures/js-override.expected.css b/test/fixtures/js-override.expected.css index d043e0bf13..d7ce1b2c48 100755 --- a/test/fixtures/js-override.expected.css +++ b/test/fixtures/js-override.expected.css @@ -1,8 +1,19 @@ +:root { + --test-one: local; + --test-two: local; +} + div { p: js-one; + p: var(--test-one); p: js-two; + p: var(--test-two); p: js-three; + p: var(--test-three); p: js-one; + p: var(--test-varception); p: js-one; + p: var(--test-jsception); p: 1; + p: var(--test-num); } diff --git a/test/fixtures/remove-properties.expected.css b/test/fixtures/remove-properties.expected.css index 538fa56f4a..649e9631d8 100755 --- a/test/fixtures/remove-properties.expected.css +++ b/test/fixtures/remove-properties.expected.css @@ -1,3 +1,13 @@ +:root { + --test-one: test; + --test-two: test; +} + div { color: red; } + +:root { + --test-three: test; + --test-four: test; +} diff --git a/test/fixtures/self-reference-double-fallback.expected.css b/test/fixtures/self-reference-double-fallback.expected.css index 67a9b3beb4..9ff57e4db8 100644 --- a/test/fixtures/self-reference-double-fallback.expected.css +++ b/test/fixtures/self-reference-double-fallback.expected.css @@ -1,4 +1,12 @@ +:root { + --color: #aaa; + --color: #aaa; + --color: #aaa; + --color: var(--color, #aaa); +} body { color: #bbb; color: #aaa; + color: #aaa; + color: var(--color, #bbb); } diff --git a/test/fixtures/self-reference-fallback.expected.css b/test/fixtures/self-reference-fallback.expected.css index 8c9a1c831d..47a67efa86 100644 --- a/test/fixtures/self-reference-fallback.expected.css +++ b/test/fixtures/self-reference-fallback.expected.css @@ -1,3 +1,8 @@ +:root { + --color: var(--color); + --color: var(--color); +} body { color: #aaa; + color: var(--color, #aaa); } diff --git a/test/fixtures/self-reference.expected.css b/test/fixtures/self-reference.expected.css index 6f6d04fee9..d5045a67c7 100644 --- a/test/fixtures/self-reference.expected.css +++ b/test/fixtures/self-reference.expected.css @@ -1,3 +1,8 @@ +:root { + --color: var(--color); + --color: var(--color); +} body { color: var(--color); + color: var(--color); } diff --git a/test/fixtures/substitution-defined.expected.css b/test/fixtures/substitution-defined.expected.css index 531b6eee8f..5f6bc4021d 100755 --- a/test/fixtures/substitution-defined.expected.css +++ b/test/fixtures/substitution-defined.expected.css @@ -2,6 +2,15 @@ * Test comment */ +:root { + --test: green; + --test-one: green; + --test-one: var(--test); + + --test-two: blue; + --test-three: yellow; +} + :root, span { --untouched: red; @@ -12,23 +21,30 @@ div { /* single variable */ color: green; + color: var(--test-one); /* single variable with comments */ color: /*comment before*/green/*comment after*/; + color: /*comment before*/var(--test-one)/*comment after*/; /* single variable with tail */ color: green !important; + color: var(--test-one) !important; /* multiple variables */ color: green, blue; + color: var(--test-one), var(--test-two); /* variable with function in fallback */ border: 1px solid rgba(0, 0, 0, 0.1); border: green; + border: var(--test-one, 1px solid rgba(0, 0, 0, 0.1)); /* multiple variables within a function */ background: linear-gradient(to top, green, blue); + background: linear-gradient(to top, var(--test-one), var(--test-two)); /* untouched custom function */ color: myvar(--test-one); + color: myvar(--test-one); } diff --git a/test/fixtures/substitution-fallback.expected.css b/test/fixtures/substitution-fallback.expected.css index 8f79a3a8f5..8ae69dc82b 100755 --- a/test/fixtures/substitution-fallback.expected.css +++ b/test/fixtures/substitution-fallback.expected.css @@ -1,33 +1,47 @@ +:root { + --nested: green; +} + div { /* simple fallback */ color: green; + color: var(--missing, green); /* comma-separated fallback */ color: green, blue; + color: var(--missing, green, blue); /* fallback is a function */ background: linear-gradient(to top, #000, #111); + background: var(--missing, linear-gradient(to top, #000, #111)); /* fallback contains a function */ background: 1px solid rgba(0, 0, 0, 0.1); + background: var(--missing, 1px solid rgba(0, 0, 0, 0.1)); /* fallback is a function containing a function */ background: linear-gradient(to top, #000, rgba(0, 0, 0, 0.5)); + background: var(--missing, linear-gradient(to top, #000, rgba(0, 0, 0, 0.5))); /* fallback contains a defined variable */ background: green; + background: var(--missing, var(--nested)); /* fallback contains a defined variable within a function */ background: linear-gradient(to top, #000, green); + background: var(--missing, linear-gradient(to top, #000, var(--nested))); /* fallback contains an undefined variable with a fallack */ background: green; + background: var(--missing, var(--also-missing, green)); /* fallback for invalid variables http://www.w3.org/TR/css-variables/#invalid-variables */ font-size: 1rem; font-size: green; + font-size: var(--nested, 1rem); /* fallback contains an defined variable with a fallack */ font-size: 1rem; font-size: green; + font-size: var(--missing, var(--nested, 1rem)); } diff --git a/test/fixtures/substitution-overwrite.expected.css b/test/fixtures/substitution-overwrite.expected.css index 8585a8cae5..5fdc7f3a4b 100755 --- a/test/fixtures/substitution-overwrite.expected.css +++ b/test/fixtures/substitution-overwrite.expected.css @@ -1,4 +1,14 @@ +:root { + --test-override: red; +} + div { background: green; + background: var(--test-override); color: green; + color: var(--test-override); +} + +:root { + --test-override: green; } diff --git a/test/fixtures/substitution-strict.expected.css b/test/fixtures/substitution-strict.expected.css index ed8e05e70b..be554a66c9 100755 --- a/test/fixtures/substitution-strict.expected.css +++ b/test/fixtures/substitution-strict.expected.css @@ -1,5 +1,14 @@ +:root { + --a: "a"; + --b: bFallback; + --b: var(--bUndef, bFallback); +} + div { aProp: "a"; + aProp: var(--a, aPropFallback); bProp: bFallback; + bProp: var(--b, bPropFallback); bProp: cPropFallback; + bProp: var(--cUndef, cPropFallback); } diff --git a/test/fixtures/substitution-trailing-space.expected.css b/test/fixtures/substitution-trailing-space.expected.css index c4f8827f1f..d5c3289c17 100755 --- a/test/fixtures/substitution-trailing-space.expected.css +++ b/test/fixtures/substitution-trailing-space.expected.css @@ -1,3 +1,8 @@ +:root { + --test-trailing-space: red; +} + div { color: red; -} \ No newline at end of file + color: var( --test-trailing-space ); +} diff --git a/test/fixtures/substitution-undefined.expected.css b/test/fixtures/substitution-undefined.expected.css index a7f4a9b252..029404a391 100644 --- a/test/fixtures/substitution-undefined.expected.css +++ b/test/fixtures/substitution-undefined.expected.css @@ -1,8 +1,18 @@ +:root { + --defined: true +} + div { + color: var(--test); color: var(--test); color: fallback; + color: var(--test, fallback); + background: linear-gradient(var(--a), var(--b)); background: linear-gradient(var(--a), var(--b)); background: linear-gradient(var(--a), var(--b), true); + background: linear-gradient(var(--a), var(--b), var(--defined)); background: linear-gradient(var(--a), true , var(--b)); + background: linear-gradient(var(--a), var(--defined) , var(--b)); background: linear-gradient(var(--a), true , var(--b), true); + background: linear-gradient(var(--a), var(--defined) , var(--b), var(--defined)); } diff --git a/test/index.js b/test/index.js index fc2441c1f3..18cb2a7de4 100755 --- a/test/index.js +++ b/test/index.js @@ -215,7 +215,7 @@ test("circular variable references", function(t) { const result = compareFixtures(t, "circular-reference") t.equal( result.messages[0].text, - "Circular variable reference: --color", + "Circular variable reference: --bg-color", "should add a warning for circular reference" ) t.end() From c6f914053368f0810d0538604d3f5f400405aa0c Mon Sep 17 00:00:00 2001 From: Jonathan Neal Date: Thu, 15 Feb 2018 18:19:41 -0500 Subject: [PATCH 568/795] No warnings by default --- index.js | 2 +- test/index.js | 13 ++++++++++--- 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/index.js b/index.js index 36f1fd1996..645f981bbb 100755 --- a/index.js +++ b/index.js @@ -171,7 +171,7 @@ export default postcss.plugin("postcss-custom-properties", (options = {}) => { const importantMap = {} globalOpts = { - warnings: "warnings" in options ? Boolean(options.warnings) : true, + warnings: "warnings" in options ? Boolean(options.warnings) : false, noValueNotifications: "noValueNotifications" in options ? String(options.noValueNotifications) : "warning", } diff --git a/test/index.js b/test/index.js index 18cb2a7de4..68c26a1376 100755 --- a/test/index.js +++ b/test/index.js @@ -61,7 +61,9 @@ test("throw errors", function(t) { test( "substitutes nothing when a variable function references an undefined var", function(t) { - const result = compareFixtures(t, "substitution-undefined") + const result = compareFixtures(t, "substitution-undefined", { + warnings: true, + }) t.equal( result.messages[0].text, "variable '--test' is undefined and used without a fallback", @@ -78,6 +80,7 @@ test( function() { return postcss(customProperties({ noValueNotifications: "error", + warnings: true, })) .process(fixture("substitution-undefined")) .css @@ -90,7 +93,9 @@ test( ) test("substitutes defined variables in `:root` only", function(t) { - const result = compareFixtures(t, "substitution-defined") + const result = compareFixtures(t, "substitution-defined", { + warnings: true, + }) t.ok( result.messages[0].text.match(/^Custom property ignored/), "should add a warning for non root custom properties" @@ -212,7 +217,9 @@ test("preserves computed value when `preserve` is `\"computed\"`", function(t) { test("circular variable references", function(t) { compareFixtures(t, "self-reference") - const result = compareFixtures(t, "circular-reference") + const result = compareFixtures(t, "circular-reference", { + warnings: true, + }) t.equal( result.messages[0].text, "Circular variable reference: --bg-color", From cdb1fb0b415fd14f1f78361274f7667d4d7640f7 Mon Sep 17 00:00:00 2001 From: Jonathan Neal Date: Thu, 15 Feb 2018 19:06:00 -0500 Subject: [PATCH 569/795] Update documentation --- README.md | 378 +++++++++++++++++++++++++++++++++++++++++------------- 1 file changed, 291 insertions(+), 87 deletions(-) diff --git a/README.md b/README.md index 0b64e6c5ea..17369ada65 100755 --- a/README.md +++ b/README.md @@ -1,45 +1,130 @@ -# postcss-custom-properties [![CSS Standard Status](https://jonathantneal.github.io/css-db/badge/css-variables.svg)](https://jonathantneal.github.io/css-db/#css-variables) [![Build Status](https://travis-ci.org/postcss/postcss-custom-properties.svg)](https://travis-ci.org/postcss/postcss-custom-properties) +# PostCSS Custom Properties [PostCSS Logo][postcss] -> [PostCSS](https://github.com/postcss/postcss) plugin to transform [W3C CSS Custom Properties for ~~cascading~~ variables](http://www.w3.org/TR/css-variables/) syntax to more compatible CSS. +[![NPM Version][npm-img]][npm-url] +[![CSS Standard Status][css-img]][css-url] +[![Build Status][cli-img]][cli-url] +[![Gitter Chat][git-img]][git-url] -_Per w3c specifications, the usage of `var()` is limited to property values. Do not expect the plugin to transform `var()` in media queries or in selectors._ +[PostCSS Custom Properties] lets you use CSS Custom Properties in CSS, following +the [CSS Custom Properties for Cascading Variables] specification. -**N.B.** The transformation _is not complete_ and **cannot be** (dynamic *cascading* variables based on custom properties relies on the DOM tree). -It currently just aims to provide a future-proof way of using a **limited subset (to `:root` selector)** of the features provided by native CSS custom properties. -_Since we do not know the DOM in the context of this plugin, we cannot produce safe output_. -Read [#1](https://github.com/postcss/postcss-custom-properties/issues/1) & [#9](https://github.com/postcss/postcss-custom-properties/issues/9) to know why this limitation exists. - -_If you are looking for a full support of CSS custom properties, please follow [the opened issue for runtime support](https://github.com/postcss/postcss-custom-properties/issues/32)._ +```css +:root { + --color: red; +} -**N.B.²** If you are wondering why there is a different plugin ([`postcss-css-variables`](https://github.com/MadLittleMods/postcss-css-variables)) that claims to do more than this plugin, be sure to understand the explanation above about limitation. This plugins have a behavior that is not [reflecting the specifications](https://github.com/MadLittleMods/postcss-css-variables/issues/4). +h1 { + color: var(--color); +} -_This plugin works great with [postcss-calc](https://github.com/postcss/postcss-calc)._ +/* becomes */ -## Installation +:root { + --color: red; +} -```console -$ npm install postcss-custom-properties +div { + color: red; + color: var(--color); +} ``` ## Usage +Add [PostCSS Custom Properties] to your build tool: + +```bash +npm install postcss-custom-properties --save-dev +``` + +#### Node + +Use [PostCSS Custom Properties] to process your CSS: + ```js -// dependencies -var fs = require("fs") -var postcss = require("postcss") -var customProperties = require("postcss-custom-properties") +import postCSSCustomProperties from 'postcss-custom-properties'; + +postCSSCustomProperties.process(YOUR_CSS); +``` + +#### PostCSS -// css to be processed -var css = fs.readFileSync("input.css", "utf8") +Add [PostCSS] to your build tool: -// process css using postcss-custom-properties -var output = postcss() - .use(customProperties()) - .process(css) - .css +```bash +npm install postcss --save-dev ``` -Using this `input.css`: +Use [PostCSS Custom Properties] as a plugin: + +```js +import postcss from 'gulp-postcss'; +import postCSSCustomProperties from 'postcss-custom-properties'; + +postcss([ + postCSSCustomProperties() +]).process(YOUR_CSS); +``` + +#### Gulp + +Add [Gulp PostCSS] to your build tool: + +```bash +npm install gulp-postcss --save-dev +``` + +Use [PostCSS Custom Properties] in your Gulpfile: + +```js +import postcss from 'gulp-postcss'; +import postCSSCustomProperties from 'postcss-custom-properties'; + +gulp.task('css', () => gulp.src('./src/*.css').pipe( + postcss([ + postCSSCustomProperties() + ]) +).pipe( + gulp.dest('.') +)); +``` + +#### Grunt + +Add [Grunt PostCSS] to your build tool: + +```bash +npm install grunt-postcss --save-dev +``` + +Use [PostCSS Custom Properties] in your Gruntfile: + +```js +import postCSSCustomProperties from 'postcss-custom-properties'; + +grunt.loadNpmTasks('grunt-postcss'); + +grunt.initConfig({ + postcss: { + options: { + use: [ + postCSSCustomProperties() + ] + }, + dist: { + src: '*.css' + } + } +}); +``` + +## Options + +### strict + +The `strict` option determines whether a `var()` function should transform into +its specified fallback value. By default, the option is `true` because this +plugin can not verify if the computed `:root` value is valid or not. ```css :root { @@ -47,128 +132,247 @@ Using this `input.css`: } div { - color: var(--color); + color: var(--color, blue); } -``` -you will get: +/* becomes */ + +:root { + --color: red; +} -```css div { - color: red; + color: blue; + color: var(--color, blue); } ``` -You can also compile CSS custom properties with their fallback value. +### preserve -Using this `input.css`: +The `preserve` option determines how Custom Properties should be preserved. By +default, this option is truthy and preserves declarations containing `var()`. ```css -div { - color: var(--color, #f00); +:root { + --color: red; +} + +h1 { + color: var(--color); } -``` -you will get: +/* becomes */ -```css -div { - color: #f00; +:root { + --color: red; +} + +h1 { + color: red; + color: var(--color); } ``` -Note that plugin returns itself in order to expose a `setVariables` function -that allow you to programmatically change the variables. +The option may also be set to `false`, where Custom Properties and declarations +containing `var()` will be removed: ```js -var variables = { - "--a": "b", +postCSSCustomProperties({ + variables: { + preserve: false + } +}) +``` + +```css +:root { + --color: red; +} + +h1 { + color: var(--color); +} + +/* becomes */ + +h1 { + color: red; } -var plugin = customProperties() -plugin.setVariables(variables) -var result = postcss() - .use(plugin) - .process(input) ``` -This might help for dynamic live/hot reloading. +The option may also be set to `"preserve-computed"`, where Custom Properties +will remain, but declarations containing `var()` will be removed: -Checkout [tests](test) for more. +```js +postCSSCustomProperties({ + variables: { + preserve: 'preserve-computed' + } +}) +``` -### Options +```css +:root { + --color: red; +} -#### `strict` +h1 { + color: var(--color); +} -Default: `true` +/* becomes */ -Per specifications, all fallbacks should be added since we can't verify if a -computed value is valid or not. -This option allows you to avoid adding too many fallback values in your CSS. +:root { + --color: red; +} -#### `preserve` +h1 { + color: red; +} +``` -Default: `false` +### variables -Allows you to preserve custom properties & var() usage in output. +The `variables` option allows you to pass an object of variables into CSS, as if +they had been specified on `:root`. ```js -var out = postcss() - .use(customProperties({preserve: true})) - .process(css) - .css +postCSSCustomProperties({ + variables: { + color: 'red' + } +}) ``` -You can also set `preserve: "computed"` to get computed resolved custom -properties in the final output. -Handy to make them available to your JavaScript. +```css +h1 { + color: var(--color); +} -#### `variables` +/* becomes */ -Default: `{}` +h1 { + color: red; + color: var(--color); +} +``` -Allows you to pass an object of variables for `:root`. These definitions will -override any that exist in the CSS. -The keys are automatically prefixed with the CSS `--` to make it easier to share +Note that these definitions will override any that exist in the CSS, and that +the keys will be automatically prefixed (`--`) to make it easier to share variables in your codebase. -#### `appendVariables` +### appendVariables -Default: `false` +The `appendVariables` option determines whether Custom Properties will be +appended to your CSS file. By default, this option is `false`. -If `preserve` is set to `true` (or `"computed"`), allows you to append your -variables at the end of your CSS. +If enabled when `preserve` is set to `true` or `"computed"`, this option allows +you to append your variables at the end of your CSS: -#### `warnings` +```js +postCSSCustomProperties({ + appendVariables: true, + variables: { + color: 'red' + } +}) +``` -Default: `true` -Type: `Boolean` +```css +h1 { + color: var(--color); +} -Allows you to enable/disable warnings. If true, will enable all warnings. -For now, it only allow to disable messages about custom properties definition -not scoped in a `:root` selector. +/* becomes */ +h1 { + color: red; + color: var(--color); +} -### `noValueNotifications` +:root { + --color: red; +} +``` -Default: `'warning'` -Values: `'warning'|'error'` +### warnings -If it is set to `'error'`, using of undefined variable will throw an error. +The `warnings` option determines whether Custom Property related warnings should +be logged by the plugin or not. By default, warnings are set to `false` and are +not logged. +If enabled, the plugin will enable all warnings: + +```js +postCSSCustomProperties({ + warnings: true +}) +``` + +```css +h1 { + color: var(--color); +} +``` + +``` +variable '--color' is undefined and used without a fallback +``` + +### noValueNotifications + +When warnings are enabled, the `noValueNotifications` option determines whether +undefined variables will throw a warning or an error. By default, it is set to +`warning`. --- +## Notes + +As written in the specification, usage of `var()` is limited to property values. +Do not expect the plugin to transform `var()` in media queries or in selectors. + +The transformation of Custom Properties done by this plugin _is not complete_ +and **cannot be** because dynamic *cascading* variables based on custom +properties relies on the DOM tree. Since we do not know the DOM in the context +of this plugin, we cannot produce safe output. This plugin currently aims to +provide a future-proof way of using a **limited subset** of the features +provided by native CSS custom properties. + +There is a separate plugin, [PostCSS CSS Variables], that attempts to guess the +context of Custom Properties without access to the DOM tree. This does not +[reflecting the specifications](https://github.com/MadLittleMods/postcss-css-variables/issues/4), +so be sure you understand the risks before you decide to use it. + ## Contributing Fork, work on a branch, install dependencies & run tests before submitting a PR. -```console +```bash $ git clone https://github.com/YOU/postcss-custom-properties.git $ git checkout -b patch-1 $ npm install $ npm test ``` +--- + ## [Changelog](CHANGELOG.md) ## [License](LICENSE) + +[npm-url]: https://www.npmjs.com/package/postcss-custom-properties +[npm-img]: https://img.shields.io/npm/v/postcss-custom-properties.svg +[css-url]: https://jonathantneal.github.io/css-db/#css-variables +[css-img]: https://jonathantneal.github.io/css-db/badge/css-variables.svg +[cli-url]: https://travis-ci.org/postcss/postcss-custom-properties +[cli-img]: https://img.shields.io/travis/postcss/postcss-custom-properties.svg +[git-url]: https://gitter.im/postcss/postcss +[git-img]: https://img.shields.io/badge/chat-gitter-blue.svg + +[CSS Custom Properties for Cascading Variables]: https://www.w3.org/TR/css-variables-1/ +[PostCSS CSS Variables]: https://github.com/MadLittleMods/postcss-css-variables +[PostCSS Custom Properties]: https://github.com/postcss/postcss-custom-properties +[PostCSS]: https://github.com/postcss/postcss +[Gulp PostCSS]: https://github.com/postcss/gulp-postcss +[Grunt PostCSS]: https://github.com/nDmitry/grunt-postcss From 52526c3836fc98ed92b76f818bcca554f9982422 Mon Sep 17 00:00:00 2001 From: Jonathan Neal Date: Thu, 15 Feb 2018 19:06:29 -0500 Subject: [PATCH 570/795] 6.3.0 --- CHANGELOG.md | 9 +++++++++ package.json | 2 +- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index dd77abc559..ed245c1d0e 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,12 @@ +# 6.3.0 - 2018-02-15 + +- Fixed: `var()` captures strictly `var()` functions and not `xvar()`, etc +- Fixed: `var()` better captures whitespace within the function +- Fixed: comments within declarations using `var()` are now preserved +- Changed: `preserve` option defaults as `true` to reflect the browser climate +- Changed: `warnings` option defaults to `false` to reflect the browser climate +- Updated documentation + # 6.2.0 - 2017-10-06 - Added: `noValueNotifications` option (#71) diff --git a/package.json b/package.json index 5c6a160414..e9bed16daa 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "postcss-custom-properties", - "version": "6.2.0", + "version": "6.3.0", "description": "PostCSS plugin to polyfill W3C CSS Custom Properties for cascading variables", "keywords": [ "css", From 9ce4b29add4497dcd4fd606ce266aa2fea1693b6 Mon Sep 17 00:00:00 2001 From: Jonathan Neal Date: Fri, 16 Feb 2018 08:13:17 -0500 Subject: [PATCH 571/795] 2.3.0 --- .tape.js | 9 ++++ CHANGELOG.md | 6 +++ README.md | 27 ++++++++---- index.js | 9 +++- lib/transform.js | 80 ++++++++++++++++++++++++++++++++++++ package.json | 8 ++-- test/basic.colors.expect.css | 8 ++++ test/basic.css | 8 ++++ test/basic.expect.css | 8 ++++ 9 files changed, 151 insertions(+), 12 deletions(-) diff --git a/.tape.js b/.tape.js index 2b03327db7..2f17776867 100644 --- a/.tape.js +++ b/.tape.js @@ -9,6 +9,15 @@ module.exports = { stringifier: color => color.toString() } }, + 'basic:transformvars': { + message: 'supports { transformVars: false } usage', + options: { + transformVars: false + }, + error: { + reason: 'Expected a color' + } + }, 'warn': { message: 'supports { unresolved } usage', options: { diff --git a/CHANGELOG.md b/CHANGELOG.md index 858f3c7904..6632ebc7dc 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,11 @@ # Changes to PostCSS color-mod() Function +### 2.3.0 (February 16, 2018) + +- Added build-time support for Custom Properties and Variables +- Updated `@csstools/convert-colors` to 1.4 (minor update) +- Updated tests to reflect variable support + ### 2.3.0 (January 25, 2018) - Updated `@csstools/convert-colors` to 1.3 (minor update) diff --git a/README.md b/README.md index 43f58bb9b8..91b7698792 100644 --- a/README.md +++ b/README.md @@ -37,17 +37,14 @@ function in CSS, following the [CSS Color Module Level 4] specification. ## Supported Colors -The `color-mod()` function accepts `rgb()`, legacy `rgb()`, `rgba()`, `hsl()`, -legacy `hsl()`, `hsla()`, `hwb()`, and `color-mod()` colors, as well as 3, 4, -6, and 8 digit hex colors, and named colors without the need for additional -plugins. +The `color-mod()` function accepts `rgb()`, legacy comma-separated `rgb()`, +`rgba()`, `hsl()`, legacy comma-separated `hsl()`, `hsla()`, `hwb()`, and +`color-mod()` colors, as well as 3, 4, 6, and 8 digit hex colors, and named +colors without the need for additional plugins. Implemention details are available in [the specification](https://drafts.csswg.org/css-color/#funcdef-color-mod). -*Because CSS variables (`var()`) cannot not be inferred at compilation, they -will need to be compiled beforehand.* - ## Supported Color Adjusters The `color-mod()` function accepts `red()`, `green()`, `blue()`, `a()` / @@ -58,6 +55,11 @@ The `color-mod()` function accepts `red()`, `green()`, `blue()`, `a()` / Implemention details are available in [the specification](https://drafts.csswg.org/css-color/#typedef-color-adjuster). +## Supported Variables + +By default, `var()` variables will be used if their corresponding Custom +Properties are found in a `:root` rule, or if a fallback value is specified. + --- ## Usage @@ -183,6 +185,17 @@ postcssColorMod({ }); ``` +### transformVars + +The `transformVars` option defines whether `var()` variables used within +`color-mod()` should be transformed into their corresponding Custom Properties +available in `:root`, or their fallback value if it is specified. By default, +`var()` variables will be transformed. + +However, because these transformations occur at build time, they cannot be +considered accurate. Accurately resolving cascading variables relies on +knowledge of the living DOM tree. + [npm-url]: https://www.npmjs.com/package/postcss-color-mod-function [npm-img]: https://img.shields.io/npm/v/postcss-color-mod-function.svg [cli-url]: https://travis-ci.org/jonathantneal/postcss-color-mod-function diff --git a/index.js b/index.js index 15f03052d5..a4867e31c1 100644 --- a/index.js +++ b/index.js @@ -7,6 +7,7 @@ import transformAST from './lib/transform'; export default postcss.plugin('postcss-color-mod-function', opts => { const unresolvedOpt = String(Object(opts).unresolved || 'throw').toLowerCase(); const stringifierOpt = Object(opts).stringifier || (color => color.toLegacy()); + const transformVarsOpt = 'transformVars' in Object(opts) ? opts.transformVars : true; return (root, result) => { root.walkDecls(decl => { @@ -15,7 +16,13 @@ export default postcss.plugin('postcss-color-mod-function', opts => { if (colorModFunctionMatch.test(originalValue)) { const ast = parser(originalValue, { loose: true }).parse(); - transformAST(ast, { unresolved: unresolvedOpt, stringifier: stringifierOpt, decl, result }); + transformAST(ast, { + unresolved: unresolvedOpt, + stringifier: stringifierOpt, + transformVars: transformVarsOpt, + decl, + result + }); const modifiedValue = ast.toString(); diff --git a/lib/transform.js b/lib/transform.js index 638e4d3c55..a50382c6dc 100644 --- a/lib/transform.js +++ b/lib/transform.js @@ -10,6 +10,11 @@ import parser from 'postcss-values-parser'; export default function transformAST(node, opts) { node.nodes.slice(0).forEach(child => { if (isColorModFunction(child)) { + // transform any variables within the color-mod() function + if (opts.transformVars) { + transformVariables(child, opts); + } + // transform any color-mod() functions const color = transformColorModFunction(child, opts); @@ -27,6 +32,50 @@ export default function transformAST(node, opts) { }); } +/* Transform functions +/* ========================================================================== */ + +function transformVariables(node, opts) { + node.walk( + child => { + if (isVariable(child)) { + const [variableName, fallbackNode] = transformArgsByParams(child, [ + // , [ ]? + [transformWord, isComma, transformNode] + ]); + + if (variableName) { + let variableNode; + + opts.result.root.walkRules(':root', rule => { + rule.nodes.filter( + rootChild => rootChild.prop === variableName + ).slice(-1).forEach( + rootChild => { + const rootChildValue = rootChild.value; + + const rootChildAST = parser(rootChildValue, { loose: true }).parse(); + + transformVariables(rootChildAST, opts); + + variableNode = rootChildAST.nodes[0]; + } + ); + }); + + if (variableNode) { + child.replaceWith(...variableNode.nodes); + } + } else if (fallbackNode) { + transformVariables(fallbackNode, opts); + + child.replaceWith(...fallbackNode.nodes[0].nodes); + } + } + } + ); +} + /* Transform functions /* ========================================================================== */ @@ -501,6 +550,21 @@ function transformMinusPlusTimesOperator(node, opts) { } } +/* Additional transforms +/* ========================================================================== */ + +function transformWord(node, opts) { + if (isWord(node)) { + return node.value; + } else { + return manageUnresolved(node, opts, node.value, `Expected a valid word`); + } +} + +function transformNode(node) { + return Object(node); +} + /* Transform helper /* ========================================================================== */ @@ -516,6 +580,15 @@ function transformArgsByParams(node, params) { ))[0] || []; } +/* Variable validators +/* ========================================================================== */ + +// return whether the node is a var function +function isVariable(node) { + // var() + return Object(node).type === 'func' && varMatch.test(node.value); +} + /* Adjustment validators /* ========================================================================== */ @@ -647,6 +720,12 @@ function isPercentage(node) { return Object(node).type === 'number' && (node.unit === '%' || node.value === '0'); } +// return whether the node is a word +function isWord(node) { + // + return Object(node).type === 'word'; +} + /* Matchers /* ========================================================================== */ @@ -667,4 +746,5 @@ const minusPlusTimesMatch = /^[*+-]$/; const rgbMatch = /^rgb$/i; const rgbaMatch = /^rgba?$/i; const shadeTintMatch = /^(shade|tint)$/i; +const varMatch = /^var$/i; const timesMatch = /^[*]$/; diff --git a/package.json b/package.json index 7592564d5e..e2a8407e76 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "postcss-color-mod-function", - "version": "2.3.0", + "version": "2.4.0", "description": "Modify colors using the color-mod() function in CSS", "author": "Jonathan Neal ", "license": "CC0-1.0", @@ -26,7 +26,7 @@ "node": ">=4.0.0" }, "dependencies": { - "@csstools/convert-colors": "^1.3", + "@csstools/convert-colors": "^1.4", "postcss": "^6.0", "postcss-values-parser": "^1.3" }, @@ -35,11 +35,11 @@ "babel-eslint": "^8.2", "babel-preset-env": "^1.6", "echint": "^4.0", - "eslint": "^4.16", + "eslint": "^4.17", "eslint-config-dev": "2.0", "postcss-tape": "2.2", "pre-commit": "^1.2", - "rollup": "^0.55", + "rollup": "^0.56", "rollup-plugin-babel": "^3.0" }, "eslintConfig": { diff --git a/test/basic.colors.expect.css b/test/basic.colors.expect.css index e06f831934..91744a07a4 100644 --- a/test/basic.colors.expect.css +++ b/test/basic.colors.expect.css @@ -119,3 +119,11 @@ test-sameness { color: rgb(96.0784313725% 96.0784313725% 86.2745098039%); color: hsl(60 55.5555555556% 91.1764705882%); } + +:root { + --color: blue; +} + +test-var { + color: rgb(0% 0% 100%); +} diff --git a/test/basic.css b/test/basic.css index 55c49217cd..2ae92a4feb 100644 --- a/test/basic.css +++ b/test/basic.css @@ -119,3 +119,11 @@ test-sameness { color: color-mod(beige alpha(+ 0%)); color: color-mod(beige blend(beige 0% hsl)); } + +:root { + --color: blue; +} + +test-var { + color: color-mod(var(--color)); +} diff --git a/test/basic.expect.css b/test/basic.expect.css index c7610e0230..95579227c5 100644 --- a/test/basic.expect.css +++ b/test/basic.expect.css @@ -119,3 +119,11 @@ test-sameness { color: rgb(245, 245, 220); color: hsl(60, 55.5555555556%, 91.1764705882%); } + +:root { + --color: blue; +} + +test-var { + color: rgb(0, 0, 255); +} From bb69518c935f48308354f3c6e505dd3544a119e1 Mon Sep 17 00:00:00 2001 From: Jonathan Neal Date: Fri, 16 Feb 2018 08:57:28 -0500 Subject: [PATCH 572/795] 6.3.1 Reverts option changes in 6.3.0 --- CHANGELOG.md | 4 ++++ index.js | 4 ++-- package.json | 2 +- 3 files changed, 7 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ed245c1d0e..0857e0d5cc 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,7 @@ +# 6.3.1 - 2018-02-16 + +- Reverted: `preserve` and `warnings` option to be added in major release + # 6.3.0 - 2018-02-15 - Fixed: `var()` captures strictly `var()` functions and not `xvar()`, etc diff --git a/index.js b/index.js index 645f981bbb..7c0a3042b1 100755 --- a/index.js +++ b/index.js @@ -166,12 +166,12 @@ export default postcss.plugin("postcss-custom-properties", (options = {}) => { const strict = "strict" in options ? Boolean(options.strict) : true const appendVariables = "appendVariables" in options ? Boolean(options.appendVariables) : false - const preserve = "preserve" in options ? options.preserve : true + const preserve = "preserve" in options ? options.preserve : false const map = {} const importantMap = {} globalOpts = { - warnings: "warnings" in options ? Boolean(options.warnings) : false, + warnings: "warnings" in options ? Boolean(options.warnings) : true, noValueNotifications: "noValueNotifications" in options ? String(options.noValueNotifications) : "warning", } diff --git a/package.json b/package.json index e9bed16daa..85b530ca5e 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "postcss-custom-properties", - "version": "6.3.0", + "version": "6.3.1", "description": "PostCSS plugin to polyfill W3C CSS Custom Properties for cascading variables", "keywords": [ "css", From f17bf96e1836526bcd9fc83040c7768c2336e46e Mon Sep 17 00:00:00 2001 From: Jonathan Neal Date: Fri, 16 Feb 2018 08:59:55 -0500 Subject: [PATCH 573/795] 7.0.0 --- CHANGELOG.md | 5 +++++ index.js | 4 ++-- package.json | 2 +- 3 files changed, 8 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0857e0d5cc..fe4fcd4aee 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,8 @@ +# 7.0.0 - 2018-02-16 + +- Changed: `preserve` option defaults as `true` to reflect the browser climate +- Changed: `warnings` option defaults to `false` to reflect the browser climate + # 6.3.1 - 2018-02-16 - Reverted: `preserve` and `warnings` option to be added in major release diff --git a/index.js b/index.js index 7c0a3042b1..645f981bbb 100755 --- a/index.js +++ b/index.js @@ -166,12 +166,12 @@ export default postcss.plugin("postcss-custom-properties", (options = {}) => { const strict = "strict" in options ? Boolean(options.strict) : true const appendVariables = "appendVariables" in options ? Boolean(options.appendVariables) : false - const preserve = "preserve" in options ? options.preserve : false + const preserve = "preserve" in options ? options.preserve : true const map = {} const importantMap = {} globalOpts = { - warnings: "warnings" in options ? Boolean(options.warnings) : true, + warnings: "warnings" in options ? Boolean(options.warnings) : false, noValueNotifications: "noValueNotifications" in options ? String(options.noValueNotifications) : "warning", } diff --git a/package.json b/package.json index 85b530ca5e..aa97e9503b 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "postcss-custom-properties", - "version": "6.3.1", + "version": "7.0.0", "description": "PostCSS plugin to polyfill W3C CSS Custom Properties for cascading variables", "keywords": [ "css", From f1089506c5b260ac9210b3497dd87d58a49e0caf Mon Sep 17 00:00:00 2001 From: everdimension Date: Sat, 17 Feb 2018 15:13:27 +0300 Subject: [PATCH 574/795] Update README.md Fix tag name in output example --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 17369ada65..cfa3a8495d 100755 --- a/README.md +++ b/README.md @@ -23,7 +23,7 @@ h1 { --color: red; } -div { +h1 { color: red; color: var(--color); } From 68cbe6253db248ab5ee4556e883d9b2f7d58da3b Mon Sep 17 00:00:00 2001 From: Jonathan Neal Date: Sat, 17 Feb 2018 17:16:05 -0500 Subject: [PATCH 575/795] 2.0.0 --- .appveyor.yml | 2 +- .editorconfig | 15 + .gitignore | 9 +- .rollup.js | 13 + .tape.js | 38 +- CHANGELOG.md | 7 +- CONTRIBUTING.md | 8 +- LICENSE.md | 140 +-- README.md | 184 ++-- index.js | 66 +- package-lock.json | 1433 ----------------------------- package.json | 65 +- test/basic.css | 7 + test/basic.expect.css | 7 + test/basic.replacewith.expect.css | 27 + test/basic.replacewith.result.css | 27 + test/basic.result.css | 27 + 17 files changed, 358 insertions(+), 1717 deletions(-) create mode 100644 .editorconfig create mode 100644 .rollup.js delete mode 100644 package-lock.json create mode 100644 test/basic.replacewith.expect.css create mode 100644 test/basic.replacewith.result.css create mode 100644 test/basic.result.css diff --git a/.appveyor.yml b/.appveyor.yml index d6b511f500..acbf8a5eeb 100644 --- a/.appveyor.yml +++ b/.appveyor.yml @@ -2,7 +2,7 @@ environment: matrix: - - nodejs_version: 4.0 + - nodejs_version: 4 version: "{build}" build: off diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000000..e06d7982bc --- /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/.gitignore b/.gitignore index 540f9a9674..6832ce87db 100644 --- a/.gitignore +++ b/.gitignore @@ -1,9 +1,12 @@ node_modules +index.bundle.js +package-lock.json +*.log* +*.result.css .* !.appveyor.yml +!.editorconfig !.gitignore +!.rollup.js !.tape.js !.travis.yml -*.log* -*.result.css -basic.css.* diff --git a/.rollup.js b/.rollup.js new file mode 100644 index 0000000000..7f4e231750 --- /dev/null +++ b/.rollup.js @@ -0,0 +1,13 @@ +import babel from 'rollup-plugin-babel'; + +export default { + input: 'index.js', + output: { file: 'index.bundle.js', format: 'cjs' }, + plugins: [ + babel({ + presets: [ + ['env', { modules: false, targets: { node: 4 } }] + ] + }) + ] +}; diff --git a/.tape.js b/.tape.js index 99c45b7962..b94e24d292 100644 --- a/.tape.js +++ b/.tape.js @@ -1,41 +1,13 @@ -const cache = []; - module.exports = { - 'postcss-focus-ring': { + 'postcss-focus-visible': { 'basic': { message: 'supports basic usage' }, - 'basic:cache': { - message: 'supports { assignTo: [] } usage', + 'basic:replacewith': { + message: 'supports { replaceWith: "[data-focus-visible-added]" } usage', options: { - assignTo: cache - }, - after: () => { - const expectJSON = '[".focus-visible",".focus-visible test","test .focus-visible","test test.focus-visible","test .focus-visible test","test test.focus-visible test","test .focus-visible .focus-visible test","test :matches(.focus-visible) test","test :matches(.focus-visible test) test","test :matches(test .focus-visible) test","test :matches(test test.focus-visible) test","test :matches(test .focus-visible test) test","test :matches(test test.focus-visible test) test","test :matches(test .focus-visible .focus-visible test) test"]'; - const resultJSON = JSON.stringify(cache); - - if (expectJSON !== resultJSON) { - throw new Error('JSON does not match'); - } - }, - expect: 'basic.expect.css', - result: 'basic.result.css' - }, - 'basic:exportas-js': { - message: 'supports { exportAs: "js" } usage', - options: { - exportAs: 'js' - }, - expect: 'basic.expect.css', - result: 'basic.result.css' - }, - 'basic:exportas-json': { - message: 'supports { exportAs: "json" } usage', - options: { - exportAs: 'json' - }, - expect: 'basic.expect.css', - result: 'basic.result.css' + replaceWith: '[data-focus-visible-added]' + } } } }; diff --git a/CHANGELOG.md b/CHANGELOG.md index 062b0a96aa..0aab1e9d47 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,9 @@ -# Changes to PostCSS Focus Ring +# Changes to PostCSS Focus Visible + +### 2.0.0 (February 17, 2018) + +- Changed `:focus-ring` to `:focus-visible` per the specification +- Removed `assignTo` export option ### 1.0.0 (May 22, 2017) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 41693d5f9d..56e94d0708 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,4 +1,4 @@ -# Contributing to PostCSS Focus Ring +# Contributing to PostCSS Focus Visible You want to help? You rock! Now, take a moment to be sure your contributions make sense to everyone else. @@ -20,13 +20,13 @@ scope and avoid unrelated commits. 1. To begin; [fork this project], clone your fork, and add our upstream. ```bash # Clone your fork of the repo into the current directory - git clone git@github.com:YOUR_USER/postcss-focus-ring.git + git clone git@github.com:YOUR_USER/postcss-focus-visible.git # Navigate to the newly cloned directory - cd postcss-focus-ring + cd postcss-focus-visible # Assign the original repo to a remote called "upstream" - git remote add upstream git@github.com:jonathantneal/postcss-focus-ring.git + git remote add upstream git@github.com:jonathantneal/postcss-focus-visible.git # Install the tools necessary for testing npm install diff --git a/LICENSE.md b/LICENSE.md index b5bc55c9f6..0bc1fa7060 100644 --- a/LICENSE.md +++ b/LICENSE.md @@ -27,80 +27,82 @@ Copyright and Related Rights in the Work and the meaning and intended legal effect of CC0 on those rights. 1. Copyright and Related Rights. A Work made available under CC0 may be - protected by copyright and related or neighboring rights (“Copyright and - Related Rights”). Copyright and Related Rights include, but are not limited - to, the following: - 1. the right to reproduce, adapt, distribute, perform, display, - communicate, and translate a Work; - 2. moral rights retained by the original author(s) and/or performer(s); - 3. publicity and privacy rights pertaining to a person’s image or likeness - depicted in a Work; - 4. rights protecting against unfair competition in regards to a Work, - subject to the limitations in paragraph 4(i), below; - 5. rights protecting the extraction, dissemination, use and reuse of data - in a Work; - 6. database rights (such as those arising under Directive 96/9/EC of the - European Parliament and of the Council of 11 March 1996 on the legal - protection of databases, and under any national implementation thereof, - including any amended or successor version of such directive); and - 7. other similar, equivalent or corresponding rights throughout the world - based on applicable law or treaty, and any national implementations - thereof. + protected by copyright and related or neighboring rights (“Copyright and + Related Rights”). Copyright and Related Rights include, but are not limited + to, the following: + 1. the right to reproduce, adapt, distribute, perform, display, communicate, + and translate a Work; + 2. moral rights retained by the original author(s) and/or performer(s); + 3. publicity and privacy rights pertaining to a person’s image or likeness + depicted in a Work; + 4. rights protecting against unfair competition in regards to a Work, + subject to the limitations in paragraph 4(i), below; + 5. rights protecting the extraction, dissemination, use and reuse of data in + a Work; + 6. database rights (such as those arising under Directive 96/9/EC of the + European Parliament and of the Council of 11 March 1996 on the legal + protection of databases, and under any national implementation thereof, + including any amended or successor version of such directive); and + 7. other similar, equivalent or corresponding rights throughout the world + based on applicable law or treaty, and any national implementations + thereof. 2. Waiver. To the greatest extent permitted by, but not in contravention of, -applicable law, Affirmer hereby overtly, fully, permanently, irrevocably and -unconditionally waives, abandons, and surrenders all of Affirmer’s Copyright -and Related Rights and associated claims and causes of action, whether now -known or unknown (including existing as well as future claims and causes of -action), in the Work (i) in all territories worldwide, (ii) for the maximum -duration provided by applicable law or treaty (including future time -extensions), (iii) in any current or future medium and for any number of -copies, and (iv) for any purpose whatsoever, including without limitation -commercial, advertising or promotional purposes (the “Waiver”). Affirmer makes -the Waiver for the benefit of each member of the public at large and to the -detriment of Affirmer’s heirs and successors, fully intending that such Waiver -shall not be subject to revocation, rescission, cancellation, termination, or -any other legal or equitable action to disrupt the quiet enjoyment of the Work -by the public as contemplated by Affirmer’s express Statement of Purpose. + applicable law, Affirmer hereby overtly, fully, permanently, irrevocably and + unconditionally waives, abandons, and surrenders all of Affirmer’s Copyright + and Related Rights and associated claims and causes of action, whether now + known or unknown (including existing as well as future claims and causes of + action), in the Work (i) in all territories worldwide, (ii) for the maximum + duration provided by applicable law or treaty (including future time + extensions), (iii) in any current or future medium and for any number of + copies, and (iv) for any purpose whatsoever, including without limitation + commercial, advertising or promotional purposes (the “Waiver”). Affirmer + makes the Waiver for the benefit of each member of the public at large and + to the detriment of Affirmer’s heirs and successors, fully intending that + such Waiver shall not be subject to revocation, rescission, cancellation, + termination, or any other legal or equitable action to disrupt the quiet + enjoyment of the Work by the public as contemplated by Affirmer’s express + Statement of Purpose. 3. Public License Fallback. Should any part of the Waiver for any reason be -judged legally invalid or ineffective under applicable law, then the Waiver -shall be preserved to the maximum extent permitted taking into account -Affirmer’s express Statement of Purpose. In addition, to the extent the Waiver -is so judged Affirmer hereby grants to each affected person a royalty-free, non -transferable, non sublicensable, non exclusive, irrevocable and unconditional -license to exercise Affirmer’s Copyright and Related Rights in the Work (i) in -all territories worldwide, (ii) for the maximum duration provided by applicable -law or treaty (including future time extensions), (iii) in any current or -future medium and for any number of copies, and (iv) for any purpose -whatsoever, including without limitation commercial, advertising or promotional -purposes (the “License”). The License shall be deemed effective as of the date -CC0 was applied by Affirmer to the Work. Should any part of the License for any -reason be judged legally invalid or ineffective under applicable law, such -partial invalidity or ineffectiveness shall not invalidate the remainder of the -License, and in such case Affirmer hereby affirms that he or she will not (i) -exercise any of his or her remaining Copyright and Related Rights in the Work -or (ii) assert any associated claims and causes of action with respect to the -Work, in either case contrary to Affirmer’s express Statement of Purpose. + judged legally invalid or ineffective under applicable law, then the Waiver + shall be preserved to the maximum extent permitted taking into account + Affirmer’s express Statement of Purpose. In addition, to the extent the + Waiver is so judged Affirmer hereby grants to each affected person a + royalty-free, non transferable, non sublicensable, non exclusive, + irrevocable and unconditional license to exercise Affirmer’s Copyright and + Related Rights in the Work (i) in all territories worldwide, (ii) for the + maximum duration provided by applicable law or treaty (including future time + extensions), (iii) in any current or future medium and for any number of + copies, and (iv) for any purpose whatsoever, including without limitation + commercial, advertising or promotional purposes (the “License”). The License + shall be deemed effective as of the date CC0 was applied by Affirmer to the + Work. Should any part of the License for any reason be judged legally + invalid or ineffective under applicable law, such partial invalidity or + ineffectiveness shall not invalidate the remainder of the License, and in + such case Affirmer hereby affirms that he or she will not (i) exercise any + of his or her remaining Copyright and Related Rights in the Work or (ii) + assert any associated claims and causes of action with respect to the Work, + in either case contrary to Affirmer’s express Statement of Purpose. 4. Limitations and Disclaimers. - 1. No trademark or patent rights held by Affirmer are waived, abandoned, - surrendered, licensed or otherwise affected by this document. - 2. Affirmer offers the Work as-is and makes no representations or - warranties of any kind concerning the Work, express, implied, statutory - or otherwise, including without limitation warranties of title, - merchantability, fitness for a particular purpose, non infringement, or - the absence of latent or other defects, accuracy, or the present or - absence of errors, whether or not discoverable, all to the greatest - extent permissible under applicable law. - 3. Affirmer disclaims responsibility for clearing rights of other persons - that may apply to the Work or any use thereof, including without - limitation any person’s Copyright and Related Rights in the Work. - Further, Affirmer disclaims responsibility for obtaining any necessary - consents, permissions or other rights required for any use of the Work. - 4. Affirmer understands and acknowledges that Creative Commons is not a - party to this document and has no duty or obligation with respect to - this CC0 or use of the Work. + 1. No trademark or patent rights held by Affirmer are waived, abandoned, + surrendered, licensed or otherwise affected by this document. + 2. Affirmer offers the Work as-is and makes no representations or warranties + of any kind concerning the Work, express, implied, statutory or + otherwise, including without limitation warranties of title, + merchantability, fitness for a particular purpose, non infringement, or + the absence of latent or other defects, accuracy, or the present or + absence of errors, whether or not discoverable, all to the greatest + extent permissible under applicable law. + 3. Affirmer disclaims responsibility for clearing rights of other persons + that may apply to the Work or any use thereof, including without + limitation any person’s Copyright and Related Rights in the Work. + Further, Affirmer disclaims responsibility for obtaining any necessary + consents, permissions or other rights required for any use of the Work. + 4. Affirmer understands and acknowledges that Creative Commons is not a + party to this document and has no duty or obligation with respect to this + CC0 or use of the Work. For more information, please see -https://creativecommons.org/publicdomain/zero/1.0/. +http://creativecommons.org/publicdomain/zero/1.0/. diff --git a/README.md b/README.md index 859a3ff267..81cc2f6f17 100644 --- a/README.md +++ b/README.md @@ -1,95 +1,97 @@ -# PostCSS Focus Ring [PostCSS Logo][postcss] +# PostCSS Focus Visible [PostCSS Logo][postcss] [![NPM Version][npm-img]][npm-url] -[![Linux Build Status][cli-img]][cli-url] +[![Build Status][cli-img]][cli-url] [![Windows Build Status][win-img]][win-url] [![Gitter Chat][git-img]][git-url] -[PostCSS Focus Ring] lets you use the `:focus-visible` pseudo-selector in CSS, -following the [Selectors Level 4] specification. +[PostCSS Focus Visible] lets you use the `:focus-visible` pseudo-selector in +CSS, following the [Selectors Level 4 specification]. ```css :focus:not(:focus-visible) { outline: none; } -``` -Use PostCSS Focus Ring alongside the [focus-visible polyfill] to swap the -pseudo-selector for a class, which maintains the same selector weight. +/* becomes */ -```css :focus:not(.focus-visible) { outline: none; } ``` ---- +[PostCSS Focus Visible] replaces the `:focus-visible` pseudo-selector with a +`.focus-visible` class selector, the same selector used by the +[focus-visible polyfill]. The replacement selector can be changed using the +`replaceWith` option. -Additionally, transformed selectors can be exported to a JSON file. +## Usage -```js -require('postcss-focus-ring')({ - exportAs: 'json' -}); -``` +Add [PostCSS Focus Visible] to your build tool: -```json -[ - ".focus-visible", - ".x-component-outside .focus-visible", - ".focus-visible .x-component-inside", -] +```bash +npm install postcss-focus-visible --save-dev ``` -Or as a JavaScript export: +#### Node -```js -require('postcss-focus-ring')({ - exportAs: 'js' -}); -``` +Use [PostCSS Focus Visible] to process your CSS: ```js -export default [ - ".focus-visible", - ".x-component-outside .focus-visible", - ".focus-visible .x-component-inside", -]; -``` +import focusVisible from 'postcss-focus-visible'; -With these variables synchronized to JavaScript, they can be used alongside the -[focus-visible polyfill]. +focusVisible.process(YOUR_CSS); +``` -## Usage +#### PostCSS -Add [PostCSS Focus Ring] to your build tool: +Add [PostCSS] to your build tool: ```bash -npm install postcss-focus-ring --save-dev +npm install postcss --save-dev ``` -#### Node - -Use [PostCSS Focus Ring] to process your CSS: +Use [PostCSS Focus Visible] as a plugin: ```js -require('postcss-focus-ring').process(YOUR_CSS); +import postcss from 'gulp-postcss'; +import focusVisible from 'postcss-focus-visible'; + +postcss([ + focusVisible() +]).process(YOUR_CSS); ``` -#### PostCSS +#### Webpack -Add [PostCSS] to your build tool: +Add [PostCSS Loader] to your build tool: ```bash -npm install postcss --save-dev +npm install postcss-loader --save-dev ``` -Use [PostCSS Focus Ring] as a plugin: +Use [PostCSS Focus Visible] in your Gulpfile: ```js -postcss([ - require('postcss-focus-ring')() -]).process(YOUR_CSS); +import focusVisible from 'postcss-focus-visible'; + +module.exports = { + module: { + rules: [ + { + test: /\.css$/, + use: [ + 'style-loader', + { loader: 'css-loader', options: { importLoaders: 1 } }, + { loader: 'postcss-loader', options: { + ident: 'postcss', + plugins: () => [ focusVisible() ] + } } + ] + } + ] + } +} ``` #### Gulp @@ -100,20 +102,19 @@ Add [Gulp PostCSS] to your build tool: npm install gulp-postcss --save-dev ``` -Use [PostCSS Focus Ring] in your Gulpfile: +Use [PostCSS Focus Visible] in your Gulpfile: ```js -var postcss = require('gulp-postcss'); - -gulp.task('css', function () { - return gulp.src('./src/*.css').pipe( - postcss([ - require('postcss-focus-ring')() - ]) - ).pipe( - gulp.dest('.') - ); -}); +import postcss from 'gulp-postcss'; +import focusVisible from 'postcss-focus-visible'; + +gulp.task('css', () => gulp.src('./src/*.css').pipe( + postcss([ + focusVisible() + ]) +).pipe( + gulp.dest('.') +)); ``` #### Grunt @@ -124,16 +125,18 @@ Add [Grunt PostCSS] to your build tool: npm install grunt-postcss --save-dev ``` -Use [PostCSS Focus Ring] in your Gruntfile: +Use [PostCSS Focus Visible] in your Gruntfile: ```js +import focusVisible from 'postcss-focus-visible'; + grunt.loadNpmTasks('grunt-postcss'); grunt.initConfig({ postcss: { options: { use: [ - require('postcss-focus-ring')() + focusVisible() ] }, dist: { @@ -143,45 +146,42 @@ grunt.initConfig({ }); ``` -## Advanced Options +## Options + +### replaceWith -These options may be passed directly into the plugin. +The `replaceWith` option defines the selector to replace `:focus-visible`. By +default, the replacement selector is `.focus-visible`. ```js -require('postcss-focus-ring')({ /* options */ }); +focusVisible({ replaceWith: '[data-focus-visible-added]' }); ``` -#### exportAs - -`exportAs` is used to export transformed selectors originally containing the -`:focus-visible` pseudo-selector. - -- If a `js` string is passed, the selectors will be exported as JavaScript. -- If a `json` string is passed, the selectors will be exported as JSON. - -#### exportTo - -`exportTo` is the path to where your JSON or JavaScript will be saved. By -default, it is the CSS source file with an additional `focus-visible-selectors` -and `.js` or `.json` extension. +```css +:focus:not(:focus-visible) { + outline: none; +} -#### assignTo +/* becomes */ -`assignTo` is an Array you may push your transformed selectors to. This can -be useful if running the plugin on the client side. +:focus:not([data-focus-visible-added]) { + outline: none; +} +``` -[npm-url]: https://www.npmjs.com/package/postcss-focus-ring -[npm-img]: https://img.shields.io/npm/v/postcss-focus-ring.svg -[cli-url]: https://travis-ci.org/jonathantneal/postcss-focus-ring -[cli-img]: https://img.shields.io/travis/jonathantneal/postcss-focus-ring.svg -[win-url]: https://ci.appveyor.com/project/jonathantneal/postcss-focus-ring -[win-img]: https://img.shields.io/appveyor/ci/jonathantneal/postcss-focus-ring.svg +[npm-url]: https://www.npmjs.com/package/postcss-focus-visible +[npm-img]: https://img.shields.io/npm/v/postcss-focus-visible.svg +[cli-url]: https://travis-ci.org/jonathantneal/postcss-focus-visible +[cli-img]: https://img.shields.io/travis/jonathantneal/postcss-focus-visible.svg +[win-url]: https://ci.appveyor.com/project/jonathantneal/postcss-focus-visible +[win-img]: https://img.shields.io/appveyor/ci/jonathantneal/postcss-focus-visible.svg [git-url]: https://gitter.im/postcss/postcss [git-img]: https://img.shields.io/badge/chat-gitter-blue.svg -[PostCSS Focus Ring]: https://github.com/jonathantneal/postcss-focus-ring -[PostCSS]: https://github.com/postcss/postcss +[focus-visible polyfill]: https://github.com/WICG/focus-visible [Gulp PostCSS]: https://github.com/postcss/gulp-postcss [Grunt PostCSS]: https://github.com/nDmitry/grunt-postcss -[Selectors Level 4]: https://drafts.csswg.org/selectors-4/#the-focus-visible-pseudo -[focus-visible polyfill]: https://github.com/WICG/focus-ring +[PostCSS]: https://github.com/postcss/postcss +[PostCSS Focus Visible]: https://github.com/jonathantneal/postcss-focus-visible +[PostCSS Loader]: https://github.com/postcss/postcss-loader +[Selectors Level 4 specification]: https://www.w3.org/TR/selectors-4/#the-focus-visible-pseudo diff --git a/index.js b/index.js index b77aaf307c..03358abe52 100644 --- a/index.js +++ b/index.js @@ -1,63 +1,15 @@ -// tooling -const fs = require('fs'); -const postcss = require('postcss'); -const parser = require('postcss-selector-parser'); +import postcss from 'postcss'; -// plugin -module.exports = postcss.plugin('postcss-focus-visible', (opts) => (root) => { // eslint-disable-line consistent-return - // transformed cache - const transformed = []; +const focusVisibleSelectorRegExp = /:focus-visible([^\w-]|$)/gi; - // walk each matching rule - root.walkRules(/:focus-visible\b/, (rule) => { - // original selector - const originalSelector = rule.selector; +export default postcss.plugin('postcss-focus-visible', opts => { + const replaceWith = String(Object(opts).replaceWith || '.focus-visible'); - // transformed selector - const transformedSelector = parser((selectors) => { - // for each selector part - selectors.walk((selector) => { - // if the selector part is a :focus-visible pseudo - if (selector.type === 'pseudo' && selector.value === ':focus-visible') { - // change it to a .focus-visible class - selector.value = '.focus-visible'; - selector.type = 'class'; - } + return root => { + root.walkRules(focusVisibleSelectorRegExp, rule => { + rule.selector = rule.selector.replace(focusVisibleSelectorRegExp, ($0, $1) => { + return `${replaceWith}${$1}`; }); - }).process(originalSelector).result; - - // if the selector has changed - if (originalSelector !== transformedSelector) { - // update the rule’s selector - rule.selector = transformedSelector; - - // push the transformed selector into the transformed cache - transformed.push.apply(transformed, rule.selectors); - } - }); - - // filter the transformed cache of repeats - const transformedClean = transformed.filter((selector, index) => transformed.indexOf(selector) === index); - - // if the assignTo option is enabled - if (opts && opts.assignTo) { - // push the transformed cache into the assignTo option - opts.assignTo.push.apply(opts.assignTo, transformedClean); - } - - // if the exportAs option is enabled - if (opts && opts.exportAs) { - // destination path - const destination = `${ opts.destination || `${ - root.source && root.source.input && root.source.input.file && root.source.input.file || 'css' - }.focus-visible-selectors.${ opts.exportAs === 'js' ? 'js' : 'json' }` }`; - - // stringified contents - const json = JSON.stringify(transformedClean, null, ' '); - const contents = opts.exportAs === 'js' ? `export default ${ json };` : json; - - return new Promise((resolve, reject) => { - fs.writeFile(destination, contents, (error) => error ? reject(error) : resolve()); }); - } + }; }); diff --git a/package-lock.json b/package-lock.json deleted file mode 100644 index e1760dae46..0000000000 --- a/package-lock.json +++ /dev/null @@ -1,1433 +0,0 @@ -{ - "name": "postcss-focus-ring", - "version": "1.0.0", - "lockfileVersion": 1, - "requires": true, - "dependencies": { - "acorn": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-5.2.1.tgz", - "integrity": "sha512-jG0u7c4Ly+3QkkW18V+NRDN+4bWHdln30NL1ZL2AvFZZmQe/BfopYCtghCKKVBUSetZ4QKcyA0pY6/4Gw8Pv8w==", - "dev": true - }, - "acorn-jsx": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-3.0.1.tgz", - "integrity": "sha1-r9+UiPsezvyDSPb7IvRk4ypYs2s=", - "dev": true, - "requires": { - "acorn": "3.3.0" - }, - "dependencies": { - "acorn": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-3.3.0.tgz", - "integrity": "sha1-ReN/s56No/JbruP/U2niu18iAXo=", - "dev": true - } - } - }, - "ajv": { - "version": "4.11.8", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-4.11.8.tgz", - "integrity": "sha1-gv+wKynmYq5TvcIK8VlHcGc5xTY=", - "dev": true, - "requires": { - "co": "4.6.0", - "json-stable-stringify": "1.0.1" - } - }, - "ajv-keywords": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-1.5.1.tgz", - "integrity": "sha1-MU3QpLM2j609/NxU7eYXG4htrzw=", - "dev": true - }, - "ansi-escapes": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-1.4.0.tgz", - "integrity": "sha1-06ioOzGapneTZisT52HHkRQiMG4=", - "dev": true - }, - "ansi-regex": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", - "dev": true - }, - "ansi-styles": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.0.tgz", - "integrity": "sha512-NnSOmMEYtVR2JVMIGTzynRkkaxtiq1xnFBcdQD/DnNCYPoEPsVJhM98BDyaoNOQIi7p4okdi3E27eN7GQbsUug==", - "requires": { - "color-convert": "1.9.1" - } - }, - "argparse": { - "version": "1.0.9", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.9.tgz", - "integrity": "sha1-c9g7wmP4bpf4zE9rrhsOkKfSLIY=", - "dev": true, - "requires": { - "sprintf-js": "1.0.3" - } - }, - "array-union": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/array-union/-/array-union-1.0.2.tgz", - "integrity": "sha1-mjRBDk9OPaI96jdb5b5w8kd47Dk=", - "dev": true, - "requires": { - "array-uniq": "1.0.3" - } - }, - "array-uniq": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/array-uniq/-/array-uniq-1.0.3.tgz", - "integrity": "sha1-r2rId6Jcx/dOBYiUdThY39sk/bY=", - "dev": true - }, - "arrify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", - "integrity": "sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=", - "dev": true - }, - "babel-code-frame": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-code-frame/-/babel-code-frame-6.26.0.tgz", - "integrity": "sha1-Y/1D99weO7fONZR9uP42mj9Yx0s=", - "dev": true, - "requires": { - "chalk": "1.1.3", - "esutils": "2.0.2", - "js-tokens": "3.0.2" - }, - "dependencies": { - "ansi-styles": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", - "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", - "dev": true - }, - "chalk": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", - "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", - "dev": true, - "requires": { - "ansi-styles": "2.2.1", - "escape-string-regexp": "1.0.5", - "has-ansi": "2.0.0", - "strip-ansi": "3.0.1", - "supports-color": "2.0.0" - } - }, - "supports-color": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", - "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", - "dev": true - } - } - }, - "balanced-match": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", - "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", - "dev": true - }, - "brace-expansion": { - "version": "1.1.8", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.8.tgz", - "integrity": "sha1-wHshHHyVLsH479Uad+8NHTmQopI=", - "dev": true, - "requires": { - "balanced-match": "1.0.0", - "concat-map": "0.0.1" - } - }, - "caller-path": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/caller-path/-/caller-path-0.1.0.tgz", - "integrity": "sha1-lAhe9jWB7NPaqSREqP6U6CV3dR8=", - "dev": true, - "requires": { - "callsites": "0.2.0" - } - }, - "callsites": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/callsites/-/callsites-0.2.0.tgz", - "integrity": "sha1-r6uWJikQp/M8GaV3WCXGnzTjUMo=", - "dev": true - }, - "chalk": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.3.0.tgz", - "integrity": "sha512-Az5zJR2CBujap2rqXGaJKaPHyJ0IrUimvYNX+ncCy8PJP4ltOGTrHUIo097ZaL2zMeKYpiCdqDvS6zdrTFok3Q==", - "requires": { - "ansi-styles": "3.2.0", - "escape-string-regexp": "1.0.5", - "supports-color": "4.5.0" - } - }, - "circular-json": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/circular-json/-/circular-json-0.3.3.tgz", - "integrity": "sha512-UZK3NBx2Mca+b5LsG7bY183pHWt5Y1xts4P3Pz7ENTwGVnJOUWbRb3ocjvX7hx9tq/yTAdclXm9sZ38gNuem4A==", - "dev": true - }, - "cli-cursor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-1.0.2.tgz", - "integrity": "sha1-ZNo/fValRBLll5S9Ytw1KV6PKYc=", - "dev": true, - "requires": { - "restore-cursor": "1.0.1" - } - }, - "cli-width": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-2.2.0.tgz", - "integrity": "sha1-/xnt6Kml5XkyQUewwR8PvLq+1jk=", - "dev": true - }, - "co": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", - "integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ=", - "dev": true - }, - "code-point-at": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", - "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=", - "dev": true - }, - "color-convert": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.1.tgz", - "integrity": "sha512-mjGanIiwQJskCC18rPR6OmrZ6fm2Lc7PeGFYwCmy5J34wC6F1PzdGL6xeMfmgicfYcNLGuVFA3WzXtIDCQSZxQ==", - "requires": { - "color-name": "1.1.3" - } - }, - "color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=" - }, - "concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", - "dev": true - }, - "concat-stream": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.0.tgz", - "integrity": "sha1-CqxmL9Ur54lk1VMvaUeE5wEQrPc=", - "dev": true, - "requires": { - "inherits": "2.0.3", - "readable-stream": "2.3.3", - "typedarray": "0.0.6" - } - }, - "core-util-is": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", - "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=", - "dev": true - }, - "cross-spawn": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-5.1.0.tgz", - "integrity": "sha1-6L0O/uWPz/b4+UUQoKVUu/ojVEk=", - "dev": true, - "requires": { - "lru-cache": "4.1.1", - "shebang-command": "1.2.0", - "which": "1.2.14" - } - }, - "d": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/d/-/d-1.0.0.tgz", - "integrity": "sha1-dUu1v+VUUdpppYuU1F9MWwRi1Y8=", - "dev": true, - "requires": { - "es5-ext": "0.10.37" - } - }, - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "deep-is": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz", - "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=", - "dev": true - }, - "del": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/del/-/del-2.2.2.tgz", - "integrity": "sha1-wSyYHQZ4RshLyvhiz/kw2Qf/0ag=", - "dev": true, - "requires": { - "globby": "5.0.0", - "is-path-cwd": "1.0.0", - "is-path-in-cwd": "1.0.0", - "object-assign": "4.1.1", - "pify": "2.3.0", - "pinkie-promise": "2.0.1", - "rimraf": "2.6.2" - } - }, - "doctrine": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.0.2.tgz", - "integrity": "sha512-y0tm5Pq6ywp3qSTZ1vPgVdAnbDEoeoc5wlOHXoY1c4Wug/a7JvqHIl7BTvwodaHmejWkK/9dSb3sCYfyo/om8A==", - "dev": true, - "requires": { - "esutils": "2.0.2" - } - }, - "es5-ext": { - "version": "0.10.37", - "resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.37.tgz", - "integrity": "sha1-DudB0Ui4AGm6J9AgOTdWryV978M=", - "dev": true, - "requires": { - "es6-iterator": "2.0.3", - "es6-symbol": "3.1.1" - } - }, - "es6-iterator": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/es6-iterator/-/es6-iterator-2.0.3.tgz", - "integrity": "sha1-p96IkUGgWpSwhUQDstCg+/qY87c=", - "dev": true, - "requires": { - "d": "1.0.0", - "es5-ext": "0.10.37", - "es6-symbol": "3.1.1" - } - }, - "es6-map": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/es6-map/-/es6-map-0.1.5.tgz", - "integrity": "sha1-kTbgUD3MBqMBaQ8LsU/042TpSfA=", - "dev": true, - "requires": { - "d": "1.0.0", - "es5-ext": "0.10.37", - "es6-iterator": "2.0.3", - "es6-set": "0.1.5", - "es6-symbol": "3.1.1", - "event-emitter": "0.3.5" - } - }, - "es6-set": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/es6-set/-/es6-set-0.1.5.tgz", - "integrity": "sha1-0rPsXU2ADO2BjbU40ol02wpzzLE=", - "dev": true, - "requires": { - "d": "1.0.0", - "es5-ext": "0.10.37", - "es6-iterator": "2.0.3", - "es6-symbol": "3.1.1", - "event-emitter": "0.3.5" - } - }, - "es6-symbol": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/es6-symbol/-/es6-symbol-3.1.1.tgz", - "integrity": "sha1-vwDvT9q2uhtG7Le2KbTH7VcVzHc=", - "dev": true, - "requires": { - "d": "1.0.0", - "es5-ext": "0.10.37" - } - }, - "es6-weak-map": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/es6-weak-map/-/es6-weak-map-2.0.2.tgz", - "integrity": "sha1-XjqzIlH/0VOKH45f+hNXdy+S2W8=", - "dev": true, - "requires": { - "d": "1.0.0", - "es5-ext": "0.10.37", - "es6-iterator": "2.0.3", - "es6-symbol": "3.1.1" - } - }, - "escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=" - }, - "escope": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/escope/-/escope-3.6.0.tgz", - "integrity": "sha1-4Bl16BJ4GhY6ba392AOY3GTIicM=", - "dev": true, - "requires": { - "es6-map": "0.1.5", - "es6-weak-map": "2.0.2", - "esrecurse": "4.2.0", - "estraverse": "4.2.0" - } - }, - "eslint": { - "version": "3.19.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-3.19.0.tgz", - "integrity": "sha1-yPxiAcf0DdCJQbh8CFdnOGpnmsw=", - "dev": true, - "requires": { - "babel-code-frame": "6.26.0", - "chalk": "1.1.3", - "concat-stream": "1.6.0", - "debug": "2.6.9", - "doctrine": "2.0.2", - "escope": "3.6.0", - "espree": "3.5.2", - "esquery": "1.0.0", - "estraverse": "4.2.0", - "esutils": "2.0.2", - "file-entry-cache": "2.0.0", - "glob": "7.1.2", - "globals": "9.18.0", - "ignore": "3.3.7", - "imurmurhash": "0.1.4", - "inquirer": "0.12.0", - "is-my-json-valid": "2.17.1", - "is-resolvable": "1.0.1", - "js-yaml": "3.10.0", - "json-stable-stringify": "1.0.1", - "levn": "0.3.0", - "lodash": "4.17.4", - "mkdirp": "0.5.1", - "natural-compare": "1.4.0", - "optionator": "0.8.2", - "path-is-inside": "1.0.2", - "pluralize": "1.2.1", - "progress": "1.1.8", - "require-uncached": "1.0.3", - "shelljs": "0.7.8", - "strip-bom": "3.0.0", - "strip-json-comments": "2.0.1", - "table": "3.8.3", - "text-table": "0.2.0", - "user-home": "2.0.0" - }, - "dependencies": { - "ansi-styles": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", - "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", - "dev": true - }, - "chalk": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", - "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", - "dev": true, - "requires": { - "ansi-styles": "2.2.1", - "escape-string-regexp": "1.0.5", - "has-ansi": "2.0.0", - "strip-ansi": "3.0.1", - "supports-color": "2.0.0" - } - }, - "supports-color": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", - "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", - "dev": true - } - } - }, - "eslint-config-dev": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/eslint-config-dev/-/eslint-config-dev-2.0.0.tgz", - "integrity": "sha1-guXKMTRJr3sSu/1OlzPrKG8PQ7c=", - "dev": true - }, - "espree": { - "version": "3.5.2", - "resolved": "https://registry.npmjs.org/espree/-/espree-3.5.2.tgz", - "integrity": "sha512-sadKeYwaR/aJ3stC2CdvgXu1T16TdYN+qwCpcWbMnGJ8s0zNWemzrvb2GbD4OhmJ/fwpJjudThAlLobGbWZbCQ==", - "dev": true, - "requires": { - "acorn": "5.2.1", - "acorn-jsx": "3.0.1" - } - }, - "esprima": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.0.tgz", - "integrity": "sha512-oftTcaMu/EGrEIu904mWteKIv8vMuOgGYo7EhVJJN00R/EED9DCua/xxHRdYnKtcECzVg7xOWhflvJMnqcFZjw==", - "dev": true - }, - "esquery": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.0.0.tgz", - "integrity": "sha1-z7qLV9f7qT8XKYqKAGoEzaE9gPo=", - "dev": true, - "requires": { - "estraverse": "4.2.0" - } - }, - "esrecurse": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.2.0.tgz", - "integrity": "sha1-+pVo2Y04I/mkHZHpAtyrnqblsWM=", - "dev": true, - "requires": { - "estraverse": "4.2.0", - "object-assign": "4.1.1" - } - }, - "estraverse": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.2.0.tgz", - "integrity": "sha1-De4/7TH81GlhjOc0IJn8GvoL2xM=", - "dev": true - }, - "esutils": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.2.tgz", - "integrity": "sha1-Cr9PHKpbyx96nYrMbepPqqBLrJs=", - "dev": true - }, - "event-emitter": { - "version": "0.3.5", - "resolved": "https://registry.npmjs.org/event-emitter/-/event-emitter-0.3.5.tgz", - "integrity": "sha1-34xp7vFkeSPHFXuc6DhAYQsCzDk=", - "dev": true, - "requires": { - "d": "1.0.0", - "es5-ext": "0.10.37" - } - }, - "exit-hook": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/exit-hook/-/exit-hook-1.1.1.tgz", - "integrity": "sha1-8FyiM7SMBdVP/wd2XfhQfpXAL/g=", - "dev": true - }, - "fast-levenshtein": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", - "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", - "dev": true - }, - "figures": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/figures/-/figures-1.7.0.tgz", - "integrity": "sha1-y+Hjr/zxzUS4DK3+0o3Hk6lwHS4=", - "dev": true, - "requires": { - "escape-string-regexp": "1.0.5", - "object-assign": "4.1.1" - } - }, - "file-entry-cache": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-2.0.0.tgz", - "integrity": "sha1-w5KZDD5oR4PYOLjISkXYoEhFg2E=", - "dev": true, - "requires": { - "flat-cache": "1.3.0", - "object-assign": "4.1.1" - } - }, - "flat-cache": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-1.3.0.tgz", - "integrity": "sha1-0wMLMrOBVPTjt+nHCfSQ9++XxIE=", - "dev": true, - "requires": { - "circular-json": "0.3.3", - "del": "2.2.2", - "graceful-fs": "4.1.11", - "write": "0.2.1" - } - }, - "flatten": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/flatten/-/flatten-1.0.2.tgz", - "integrity": "sha1-2uRqnXj74lKSJYzB54CkHZXAN4I=" - }, - "fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", - "dev": true - }, - "generate-function": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/generate-function/-/generate-function-2.0.0.tgz", - "integrity": "sha1-aFj+fAlpt9TpCTM3ZHrHn2DfvnQ=", - "dev": true - }, - "generate-object-property": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/generate-object-property/-/generate-object-property-1.2.0.tgz", - "integrity": "sha1-nA4cQDCM6AT0eDYYuTf6iPmdUNA=", - "dev": true, - "requires": { - "is-property": "1.0.2" - } - }, - "glob": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz", - "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==", - "dev": true, - "requires": { - "fs.realpath": "1.0.0", - "inflight": "1.0.6", - "inherits": "2.0.3", - "minimatch": "3.0.4", - "once": "1.4.0", - "path-is-absolute": "1.0.1" - } - }, - "globals": { - "version": "9.18.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-9.18.0.tgz", - "integrity": "sha512-S0nG3CLEQiY/ILxqtztTWH/3iRRdyBLw6KMDxnKMchrtbj2OFmehVh0WUCfW3DUrIgx/qFrJPICrq4Z4sTR9UQ==", - "dev": true - }, - "globby": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/globby/-/globby-5.0.0.tgz", - "integrity": "sha1-69hGZ8oNuzMLmbz8aOrCvFQ3Dg0=", - "dev": true, - "requires": { - "array-union": "1.0.2", - "arrify": "1.0.1", - "glob": "7.1.2", - "object-assign": "4.1.1", - "pify": "2.3.0", - "pinkie-promise": "2.0.1" - } - }, - "graceful-fs": { - "version": "4.1.11", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.11.tgz", - "integrity": "sha1-Dovf5NHduIVNZOBOp8AOKgJuVlg=", - "dev": true - }, - "has-ansi": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", - "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=", - "dev": true, - "requires": { - "ansi-regex": "2.1.1" - } - }, - "has-flag": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz", - "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=" - }, - "ignore": { - "version": "3.3.7", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-3.3.7.tgz", - "integrity": "sha512-YGG3ejvBNHRqu0559EOxxNFihD0AjpvHlC/pdGKd3X3ofe+CoJkYazwNJYTNebqpPKN+VVQbh4ZFn1DivMNuHA==", - "dev": true - }, - "imurmurhash": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", - "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", - "dev": true - }, - "indexes-of": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/indexes-of/-/indexes-of-1.0.1.tgz", - "integrity": "sha1-8w9xbI4r00bHtn0985FVZqfAVgc=" - }, - "inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", - "dev": true, - "requires": { - "once": "1.4.0", - "wrappy": "1.0.2" - } - }, - "inherits": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", - "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", - "dev": true - }, - "inquirer": { - "version": "0.12.0", - "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-0.12.0.tgz", - "integrity": "sha1-HvK/1jUE3wvHV4X/+MLEHfEvB34=", - "dev": true, - "requires": { - "ansi-escapes": "1.4.0", - "ansi-regex": "2.1.1", - "chalk": "1.1.3", - "cli-cursor": "1.0.2", - "cli-width": "2.2.0", - "figures": "1.7.0", - "lodash": "4.17.4", - "readline2": "1.0.1", - "run-async": "0.1.0", - "rx-lite": "3.1.2", - "string-width": "1.0.2", - "strip-ansi": "3.0.1", - "through": "2.3.8" - }, - "dependencies": { - "ansi-styles": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", - "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", - "dev": true - }, - "chalk": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", - "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", - "dev": true, - "requires": { - "ansi-styles": "2.2.1", - "escape-string-regexp": "1.0.5", - "has-ansi": "2.0.0", - "strip-ansi": "3.0.1", - "supports-color": "2.0.0" - } - }, - "supports-color": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", - "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", - "dev": true - } - } - }, - "interpret": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.1.0.tgz", - "integrity": "sha1-ftGxQQxqDg94z5XTuEQMY/eLhhQ=", - "dev": true - }, - "is-fullwidth-code-point": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", - "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", - "dev": true, - "requires": { - "number-is-nan": "1.0.1" - } - }, - "is-my-json-valid": { - "version": "2.17.1", - "resolved": "https://registry.npmjs.org/is-my-json-valid/-/is-my-json-valid-2.17.1.tgz", - "integrity": "sha512-Q2khNw+oBlWuaYvEEHtKSw/pCxD2L5Rc1C+UQme9X6JdRDh7m5D7HkozA0qa3DUkQ6VzCnEm8mVIQPyIRkI5sQ==", - "dev": true, - "requires": { - "generate-function": "2.0.0", - "generate-object-property": "1.2.0", - "jsonpointer": "4.0.1", - "xtend": "4.0.1" - } - }, - "is-path-cwd": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-path-cwd/-/is-path-cwd-1.0.0.tgz", - "integrity": "sha1-0iXsIxMuie3Tj9p2dHLmLmXxEG0=", - "dev": true - }, - "is-path-in-cwd": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-path-in-cwd/-/is-path-in-cwd-1.0.0.tgz", - "integrity": "sha1-ZHdYK4IU1gI0YJRWcAO+ip6sBNw=", - "dev": true, - "requires": { - "is-path-inside": "1.0.1" - } - }, - "is-path-inside": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-1.0.1.tgz", - "integrity": "sha1-jvW33lBDej/cprToZe96pVy0gDY=", - "dev": true, - "requires": { - "path-is-inside": "1.0.2" - } - }, - "is-property": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-property/-/is-property-1.0.2.tgz", - "integrity": "sha1-V/4cTkhHTt1lsJkR8msc1Ald2oQ=", - "dev": true - }, - "is-resolvable": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-resolvable/-/is-resolvable-1.0.1.tgz", - "integrity": "sha512-y5CXYbzvB3jTnWAZH1Nl7ykUWb6T3BcTs56HUruwBf8MhF56n1HWqhDWnVFo8GHrUPDgvUUNVhrc2U8W7iqz5g==", - "dev": true - }, - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", - "dev": true - }, - "isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", - "dev": true - }, - "js-tokens": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-3.0.2.tgz", - "integrity": "sha1-mGbfOVECEw449/mWvOtlRDIJwls=", - "dev": true - }, - "js-yaml": { - "version": "3.10.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.10.0.tgz", - "integrity": "sha512-O2v52ffjLa9VeM43J4XocZE//WT9N0IiwDa3KSHH7Tu8CtH+1qM8SIZvnsTh6v+4yFy5KUY3BHUVwjpfAWsjIA==", - "dev": true, - "requires": { - "argparse": "1.0.9", - "esprima": "4.0.0" - } - }, - "json-stable-stringify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json-stable-stringify/-/json-stable-stringify-1.0.1.tgz", - "integrity": "sha1-mnWdOcXy/1A/1TAGRu1EX4jE+a8=", - "dev": true, - "requires": { - "jsonify": "0.0.0" - } - }, - "jsonify": { - "version": "0.0.0", - "resolved": "https://registry.npmjs.org/jsonify/-/jsonify-0.0.0.tgz", - "integrity": "sha1-LHS27kHZPKUbe1qu6PUDYx0lKnM=", - "dev": true - }, - "jsonpointer": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/jsonpointer/-/jsonpointer-4.0.1.tgz", - "integrity": "sha1-T9kss04OnbPInIYi7PUfm5eMbLk=", - "dev": true - }, - "levn": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", - "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=", - "dev": true, - "requires": { - "prelude-ls": "1.1.2", - "type-check": "0.3.2" - } - }, - "lodash": { - "version": "4.17.4", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.4.tgz", - "integrity": "sha1-eCA6TRwyiuHYbcpkYONptX9AVa4=", - "dev": true - }, - "lru-cache": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.1.tgz", - "integrity": "sha512-q4spe4KTfsAS1SUHLO0wz8Qiyf1+vMIAgpRYioFYDMNqKfHQbg+AVDH3i4fvpl71/P1L0dBl+fQi+P37UYf0ew==", - "dev": true, - "requires": { - "pseudomap": "1.0.2", - "yallist": "2.1.2" - } - }, - "minimatch": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", - "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", - "dev": true, - "requires": { - "brace-expansion": "1.1.8" - } - }, - "minimist": { - "version": "0.0.8", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", - "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=", - "dev": true - }, - "mkdirp": { - "version": "0.5.1", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", - "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", - "dev": true, - "requires": { - "minimist": "0.0.8" - } - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", - "dev": true - }, - "mute-stream": { - "version": "0.0.5", - "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.5.tgz", - "integrity": "sha1-j7+rsKmKJT0xhDMfno3rc3L6xsA=", - "dev": true - }, - "natural-compare": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", - "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=", - "dev": true - }, - "number-is-nan": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", - "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=", - "dev": true - }, - "object-assign": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", - "dev": true - }, - "once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", - "dev": true, - "requires": { - "wrappy": "1.0.2" - } - }, - "onetime": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-1.1.0.tgz", - "integrity": "sha1-ofeDj4MUxRbwXs78vEzP4EtO14k=", - "dev": true - }, - "optionator": { - "version": "0.8.2", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.2.tgz", - "integrity": "sha1-NkxeQJ0/TWMB1sC0wFu6UBgK62Q=", - "dev": true, - "requires": { - "deep-is": "0.1.3", - "fast-levenshtein": "2.0.6", - "levn": "0.3.0", - "prelude-ls": "1.1.2", - "type-check": "0.3.2", - "wordwrap": "1.0.0" - } - }, - "os-homedir": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz", - "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=", - "dev": true - }, - "os-shim": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/os-shim/-/os-shim-0.1.3.tgz", - "integrity": "sha1-a2LDeRz3kJ6jXtRuF2WLtBfLORc=", - "dev": true - }, - "path-is-absolute": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", - "dev": true - }, - "path-is-inside": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz", - "integrity": "sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM=", - "dev": true - }, - "path-parse": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.5.tgz", - "integrity": "sha1-PBrfhx6pzWyUMbbqK9dKD/BVxME=", - "dev": true - }, - "pify": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", - "dev": true - }, - "pinkie": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz", - "integrity": "sha1-clVrgM+g1IqXToDnckjoDtT3+HA=", - "dev": true - }, - "pinkie-promise": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz", - "integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=", - "dev": true, - "requires": { - "pinkie": "2.0.4" - } - }, - "pluralize": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/pluralize/-/pluralize-1.2.1.tgz", - "integrity": "sha1-0aIUg/0iu0HlihL6NCGCMUCJfEU=", - "dev": true - }, - "postcss": { - "version": "6.0.14", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.14.tgz", - "integrity": "sha512-NJ1z0f+1offCgadPhz+DvGm5Mkci+mmV5BqD13S992o0Xk9eElxUfPPF+t2ksH5R/17gz4xVK8KWocUQ5o3Rog==", - "requires": { - "chalk": "2.3.0", - "source-map": "0.6.1", - "supports-color": "4.5.0" - } - }, - "postcss-selector-parser": { - "version": "2.2.3", - "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-2.2.3.tgz", - "integrity": "sha1-+UN3iGBsPJrO4W/+jYsWKX8nu5A=", - "requires": { - "flatten": "1.0.2", - "indexes-of": "1.0.1", - "uniq": "1.0.1" - } - }, - "postcss-tape": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/postcss-tape/-/postcss-tape-2.0.1.tgz", - "integrity": "sha1-PP4pUg4ZJ4E3zCvTXOeyvXq42jY=", - "dev": true - }, - "pre-commit": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/pre-commit/-/pre-commit-1.2.2.tgz", - "integrity": "sha1-287g7p3nI15X95xW186UZBpp7sY=", - "dev": true, - "requires": { - "cross-spawn": "5.1.0", - "spawn-sync": "1.0.15", - "which": "1.2.14" - } - }, - "prelude-ls": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", - "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=", - "dev": true - }, - "process-nextick-args": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-1.0.7.tgz", - "integrity": "sha1-FQ4gt1ZZCtP5EJPyWk8q2L/zC6M=", - "dev": true - }, - "progress": { - "version": "1.1.8", - "resolved": "https://registry.npmjs.org/progress/-/progress-1.1.8.tgz", - "integrity": "sha1-4mDHj2Fhzdmw5WzD4Khd4Xx6V74=", - "dev": true - }, - "pseudomap": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", - "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=", - "dev": true - }, - "readable-stream": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.3.tgz", - "integrity": "sha512-m+qzzcn7KUxEmd1gMbchF+Y2eIUbieUaxkWtptyHywrX0rE8QEYqPC07Vuy4Wm32/xE16NcdBctb8S0Xe/5IeQ==", - "dev": true, - "requires": { - "core-util-is": "1.0.2", - "inherits": "2.0.3", - "isarray": "1.0.0", - "process-nextick-args": "1.0.7", - "safe-buffer": "5.1.1", - "string_decoder": "1.0.3", - "util-deprecate": "1.0.2" - } - }, - "readline2": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/readline2/-/readline2-1.0.1.tgz", - "integrity": "sha1-QQWWCP/BVHV7cV2ZidGZ/783LjU=", - "dev": true, - "requires": { - "code-point-at": "1.1.0", - "is-fullwidth-code-point": "1.0.0", - "mute-stream": "0.0.5" - } - }, - "rechoir": { - "version": "0.6.2", - "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.6.2.tgz", - "integrity": "sha1-hSBLVNuoLVdC4oyWdW70OvUOM4Q=", - "dev": true, - "requires": { - "resolve": "1.5.0" - } - }, - "require-uncached": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/require-uncached/-/require-uncached-1.0.3.tgz", - "integrity": "sha1-Tg1W1slmL9MeQwEcS5WqSZVUIdM=", - "dev": true, - "requires": { - "caller-path": "0.1.0", - "resolve-from": "1.0.1" - } - }, - "resolve": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.5.0.tgz", - "integrity": "sha512-hgoSGrc3pjzAPHNBg+KnFcK2HwlHTs/YrAGUr6qgTVUZmXv1UEXXl0bZNBKMA9fud6lRYFdPGz0xXxycPzmmiw==", - "dev": true, - "requires": { - "path-parse": "1.0.5" - } - }, - "resolve-from": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-1.0.1.tgz", - "integrity": "sha1-Jsv+k10a7uq7Kbw/5a6wHpPUQiY=", - "dev": true - }, - "restore-cursor": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-1.0.1.tgz", - "integrity": "sha1-NGYfRohjJ/7SmRR5FSJS35LapUE=", - "dev": true, - "requires": { - "exit-hook": "1.1.1", - "onetime": "1.1.0" - } - }, - "rimraf": { - "version": "2.6.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.2.tgz", - "integrity": "sha512-lreewLK/BlghmxtfH36YYVg1i8IAce4TI7oao75I1g245+6BctqTVQiBP3YUJ9C6DQOXJmkYR9X9fCLtCOJc5w==", - "dev": true, - "requires": { - "glob": "7.1.2" - } - }, - "run-async": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/run-async/-/run-async-0.1.0.tgz", - "integrity": "sha1-yK1KXhEGYeQCp9IbUw4AnyX444k=", - "dev": true, - "requires": { - "once": "1.4.0" - } - }, - "rx-lite": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/rx-lite/-/rx-lite-3.1.2.tgz", - "integrity": "sha1-Gc5QLKVyZl87ZHsQk5+X/RYV8QI=", - "dev": true - }, - "safe-buffer": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.1.tgz", - "integrity": "sha512-kKvNJn6Mm93gAczWVJg7wH+wGYWNrDHdWvpUmHyEsgCtIwwo3bqPtV4tR5tuPaUhTOo/kvhVwd8XwwOllGYkbg==", - "dev": true - }, - "shebang-command": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", - "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=", - "dev": true, - "requires": { - "shebang-regex": "1.0.0" - } - }, - "shebang-regex": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", - "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=", - "dev": true - }, - "shelljs": { - "version": "0.7.8", - "resolved": "https://registry.npmjs.org/shelljs/-/shelljs-0.7.8.tgz", - "integrity": "sha1-3svPh0sNHl+3LhSxZKloMEjprLM=", - "dev": true, - "requires": { - "glob": "7.1.2", - "interpret": "1.1.0", - "rechoir": "0.6.2" - } - }, - "slice-ansi": { - "version": "0.0.4", - "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-0.0.4.tgz", - "integrity": "sha1-7b+JA/ZvfOL46v1s7tZeJkyDGzU=", - "dev": true - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" - }, - "spawn-sync": { - "version": "1.0.15", - "resolved": "https://registry.npmjs.org/spawn-sync/-/spawn-sync-1.0.15.tgz", - "integrity": "sha1-sAeZVX63+wyDdsKdROih6mfldHY=", - "dev": true, - "requires": { - "concat-stream": "1.6.0", - "os-shim": "0.1.3" - } - }, - "sprintf-js": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", - "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", - "dev": true - }, - "string-width": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", - "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", - "dev": true, - "requires": { - "code-point-at": "1.1.0", - "is-fullwidth-code-point": "1.0.0", - "strip-ansi": "3.0.1" - } - }, - "string_decoder": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz", - "integrity": "sha512-4AH6Z5fzNNBcH+6XDMfA/BTt87skxqJlO0lAh3Dker5zThcAxG6mKz+iGu308UKoPPQ8Dcqx/4JhujzltRa+hQ==", - "dev": true, - "requires": { - "safe-buffer": "5.1.1" - } - }, - "strip-ansi": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", - "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", - "dev": true, - "requires": { - "ansi-regex": "2.1.1" - } - }, - "strip-bom": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", - "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", - "dev": true - }, - "strip-json-comments": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", - "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=", - "dev": true - }, - "supports-color": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.5.0.tgz", - "integrity": "sha1-vnoN5ITexcXN34s9WRJQRJEvY1s=", - "requires": { - "has-flag": "2.0.0" - } - }, - "table": { - "version": "3.8.3", - "resolved": "https://registry.npmjs.org/table/-/table-3.8.3.tgz", - "integrity": "sha1-K7xULw/amGGnVdOUf+/Ys/UThV8=", - "dev": true, - "requires": { - "ajv": "4.11.8", - "ajv-keywords": "1.5.1", - "chalk": "1.1.3", - "lodash": "4.17.4", - "slice-ansi": "0.0.4", - "string-width": "2.1.1" - }, - "dependencies": { - "ansi-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", - "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", - "dev": true - }, - "ansi-styles": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", - "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", - "dev": true - }, - "chalk": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", - "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", - "dev": true, - "requires": { - "ansi-styles": "2.2.1", - "escape-string-regexp": "1.0.5", - "has-ansi": "2.0.0", - "strip-ansi": "3.0.1", - "supports-color": "2.0.0" - } - }, - "is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", - "dev": true - }, - "string-width": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", - "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", - "dev": true, - "requires": { - "is-fullwidth-code-point": "2.0.0", - "strip-ansi": "4.0.0" - }, - "dependencies": { - "strip-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", - "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", - "dev": true, - "requires": { - "ansi-regex": "3.0.0" - } - } - } - }, - "supports-color": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", - "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", - "dev": true - } - } - }, - "text-table": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", - "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=", - "dev": true - }, - "through": { - "version": "2.3.8", - "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", - "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=", - "dev": true - }, - "type-check": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", - "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=", - "dev": true, - "requires": { - "prelude-ls": "1.1.2" - } - }, - "typedarray": { - "version": "0.0.6", - "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", - "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=", - "dev": true - }, - "uniq": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/uniq/-/uniq-1.0.1.tgz", - "integrity": "sha1-sxxa6CVIRKOoKBVBzisEuGWnNP8=" - }, - "user-home": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/user-home/-/user-home-2.0.0.tgz", - "integrity": "sha1-nHC/2Babwdy/SGBODwS4tJzenp8=", - "dev": true, - "requires": { - "os-homedir": "1.0.2" - } - }, - "util-deprecate": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=", - "dev": true - }, - "which": { - "version": "1.2.14", - "resolved": "https://registry.npmjs.org/which/-/which-1.2.14.tgz", - "integrity": "sha1-mofEN48D6CfOyvGs31bHNsAcFOU=", - "dev": true, - "requires": { - "isexe": "2.0.0" - } - }, - "wordwrap": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", - "integrity": "sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus=", - "dev": true - }, - "wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", - "dev": true - }, - "write": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/write/-/write-0.2.1.tgz", - "integrity": "sha1-X8A4KOJkzqP+kUVUdvejxWbLB1c=", - "dev": true, - "requires": { - "mkdirp": "0.5.1" - } - }, - "xtend": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz", - "integrity": "sha1-pcbVMr5lbiPbgg77lDofBJmNY68=", - "dev": true - }, - "yallist": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", - "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=", - "dev": true - } - } -} diff --git a/package.json b/package.json index 66b9550d2f..e155e8b102 100644 --- a/package.json +++ b/package.json @@ -1,38 +1,47 @@ { - "name": "postcss-focus-ring", - "version": "1.0.0", + "name": "postcss-focus-visible", + "version": "2.0.0", "description": "Use the :focus-visible pseudo-selector in CSS", "author": "Jonathan Neal ", "license": "CC0-1.0", - "repository": "jonathantneal/postcss-focus-ring", - "homepage": "https://github.com/jonathantneal/postcss-focus-ring#readme", - "bugs": "https://github.com/jonathantneal/postcss-focus-ring/issues", - "main": "index.js", + "repository": "jonathantneal/postcss-focus-visible", + "homepage": "https://github.com/jonathantneal/postcss-focus-visible#readme", + "bugs": "https://github.com/jonathantneal/postcss-focus-visible/issues", + "main": "index.bundle.js", + "module": "index.js", "files": [ - "index.js" + "index.js", + "index.bundle.js" ], "scripts": { - "clean": "git clean -X -d -f", - "prepublish": "npm test", - "test": "echo 'Running tests...'; npm run test:js && npm run test:tape", - "test:js": "eslint *.js --cache --ignore-pattern .gitignore", + "prepublishOnly": "npm test", + "pretest": "rollup -c .rollup.js --silent", + "test": "echo 'Running tests...'; npm run test:ec && npm run test:js && npm run test:tape", + "test:ec": "echint --ignore index.bundle.js test", + "test:js": "eslint *.js --cache --ignore-path .gitignore --quiet", "test:tape": "postcss-tape" }, "engines": { "node": ">=4.0.0" }, "dependencies": { - "postcss": "^6.0.1", - "postcss-selector-parser": "^2.2.3" + "postcss": "^6.0" }, "devDependencies": { - "eslint": "^3.19.0", - "eslint-config-dev": "2.0.0", - "postcss-tape": "2.0.1", - "pre-commit": "^1.2.2" + "babel-core": "^6.26", + "babel-eslint": "^8.2", + "babel-preset-env": "^1.6", + "echint": "^4.0", + "eslint": "^4.18", + "eslint-config-dev": "2.0", + "postcss-tape": "2.2", + "pre-commit": "^1.2", + "rollup": "^0.56", + "rollup-plugin-babel": "^3.0" }, "eslintConfig": { - "extends": "dev" + "extends": "dev", + "parser": "babel-eslint" }, "keywords": [ "postcss", @@ -40,17 +49,25 @@ "postcss-plugin", "focus", "ring", - "css4", + "css", + "pseudos", "selectors", "accessibility", "a11y", - "input", - "keyboard", - "mouse", - "pen", + "keyboards", "pointer", "cursor", + "mice", + "mouse", + "pen", + "touch", "trackpad", - "javascript" + "button", + "input", + "select", + "textarea", + "contenteditable", + "javascript", + "js" ] } diff --git a/test/basic.css b/test/basic.css index eb304180a1..f6628e44c0 100644 --- a/test/basic.css +++ b/test/basic.css @@ -18,3 +18,10 @@ test :matches(test test:focus-visible test) test, test :matches(test :focus-visible :focus-visible test) test { order: 2; } + +:ignore-focus-visible, +:focus-visible-ignore, +:ignorefocus-visible, +:focus-visibleignore { + order: 3; +} diff --git a/test/basic.expect.css b/test/basic.expect.css index e31bfbc490..6a85671726 100644 --- a/test/basic.expect.css +++ b/test/basic.expect.css @@ -18,3 +18,10 @@ test :matches(test test.focus-visible test) test, test :matches(test .focus-visible .focus-visible test) test { order: 2; } + +:ignore-focus-visible, +:focus-visible-ignore, +:ignorefocus-visible, +:focus-visibleignore { + order: 3; +} diff --git a/test/basic.replacewith.expect.css b/test/basic.replacewith.expect.css new file mode 100644 index 0000000000..a37c668807 --- /dev/null +++ b/test/basic.replacewith.expect.css @@ -0,0 +1,27 @@ +[data-focus-visible-added] { + order: 1; +} + +[data-focus-visible-added], +[data-focus-visible-added] test, +test [data-focus-visible-added], +test test[data-focus-visible-added], +test [data-focus-visible-added] test, +test test[data-focus-visible-added] test, +test [data-focus-visible-added] [data-focus-visible-added] test, +test :matches([data-focus-visible-added]) test, +test :matches([data-focus-visible-added] test) test, +test :matches(test [data-focus-visible-added]) test, +test :matches(test test[data-focus-visible-added]) test, +test :matches(test [data-focus-visible-added] test) test, +test :matches(test test[data-focus-visible-added] test) test, +test :matches(test [data-focus-visible-added] [data-focus-visible-added] test) test { + order: 2; +} + +:ignore-focus-visible, +:focus-visible-ignore, +:ignorefocus-visible, +:focus-visibleignore { + order: 3; +} diff --git a/test/basic.replacewith.result.css b/test/basic.replacewith.result.css new file mode 100644 index 0000000000..a37c668807 --- /dev/null +++ b/test/basic.replacewith.result.css @@ -0,0 +1,27 @@ +[data-focus-visible-added] { + order: 1; +} + +[data-focus-visible-added], +[data-focus-visible-added] test, +test [data-focus-visible-added], +test test[data-focus-visible-added], +test [data-focus-visible-added] test, +test test[data-focus-visible-added] test, +test [data-focus-visible-added] [data-focus-visible-added] test, +test :matches([data-focus-visible-added]) test, +test :matches([data-focus-visible-added] test) test, +test :matches(test [data-focus-visible-added]) test, +test :matches(test test[data-focus-visible-added]) test, +test :matches(test [data-focus-visible-added] test) test, +test :matches(test test[data-focus-visible-added] test) test, +test :matches(test [data-focus-visible-added] [data-focus-visible-added] test) test { + order: 2; +} + +:ignore-focus-visible, +:focus-visible-ignore, +:ignorefocus-visible, +:focus-visibleignore { + order: 3; +} diff --git a/test/basic.result.css b/test/basic.result.css new file mode 100644 index 0000000000..6a85671726 --- /dev/null +++ b/test/basic.result.css @@ -0,0 +1,27 @@ +.focus-visible { + order: 1; +} + +.focus-visible, +.focus-visible test, +test .focus-visible, +test test.focus-visible, +test .focus-visible test, +test test.focus-visible test, +test .focus-visible .focus-visible test, +test :matches(.focus-visible) test, +test :matches(.focus-visible test) test, +test :matches(test .focus-visible) test, +test :matches(test test.focus-visible) test, +test :matches(test .focus-visible test) test, +test :matches(test test.focus-visible test) test, +test :matches(test .focus-visible .focus-visible test) test { + order: 2; +} + +:ignore-focus-visible, +:focus-visible-ignore, +:ignorefocus-visible, +:focus-visibleignore { + order: 3; +} From 8c364eaba066b08e788d6ad1c652090185bf0ece Mon Sep 17 00:00:00 2001 From: Jonathan Neal Date: Sat, 17 Feb 2018 18:30:14 -0500 Subject: [PATCH 576/795] 1.0.0 --- .appveyor.yml | 18 +++ .editorconfig | 15 +++ .gitignore | 12 ++ .rollup.js | 13 +++ .tape.js | 13 +++ .travis.yml | 9 ++ CHANGELOG.md | 5 + CONTRIBUTING.md | 65 +++++++++++ LICENSE.md | 108 +++++++++++++++++ README.md | 187 ++++++++++++++++++++++++++++++ index.js | 15 +++ package.json | 60 ++++++++++ test/basic.css | 27 +++++ test/basic.expect.css | 27 +++++ test/basic.replacewith.expect.css | 27 +++++ 15 files changed, 601 insertions(+) create mode 100644 .appveyor.yml create mode 100644 .editorconfig create mode 100644 .gitignore create mode 100644 .rollup.js create mode 100644 .tape.js create mode 100644 .travis.yml create mode 100644 CHANGELOG.md create mode 100644 CONTRIBUTING.md create mode 100644 LICENSE.md create mode 100644 README.md create mode 100644 index.js create mode 100644 package.json create mode 100644 test/basic.css create mode 100644 test/basic.expect.css create mode 100644 test/basic.replacewith.expect.css diff --git a/.appveyor.yml b/.appveyor.yml new file mode 100644 index 0000000000..acbf8a5eeb --- /dev/null +++ b/.appveyor.yml @@ -0,0 +1,18 @@ +# https://www.appveyor.com/docs/appveyor-yml + +environment: + matrix: + - nodejs_version: 4 + +version: "{build}" +build: off +deploy: off + +install: + - ps: Install-Product node $env:nodejs_version + - npm install --ignore-scripts + +test_script: + - node --version + - npm --version + - cmd: "npm test" diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000000..e06d7982bc --- /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/.gitignore b/.gitignore new file mode 100644 index 0000000000..6832ce87db --- /dev/null +++ b/.gitignore @@ -0,0 +1,12 @@ +node_modules +index.bundle.js +package-lock.json +*.log* +*.result.css +.* +!.appveyor.yml +!.editorconfig +!.gitignore +!.rollup.js +!.tape.js +!.travis.yml diff --git a/.rollup.js b/.rollup.js new file mode 100644 index 0000000000..7f4e231750 --- /dev/null +++ b/.rollup.js @@ -0,0 +1,13 @@ +import babel from 'rollup-plugin-babel'; + +export default { + input: 'index.js', + output: { file: 'index.bundle.js', format: 'cjs' }, + plugins: [ + babel({ + presets: [ + ['env', { modules: false, targets: { node: 4 } }] + ] + }) + ] +}; diff --git a/.tape.js b/.tape.js new file mode 100644 index 0000000000..826394f626 --- /dev/null +++ b/.tape.js @@ -0,0 +1,13 @@ +module.exports = { + 'postcss-focus-within': { + 'basic': { + message: 'supports basic usage' + }, + 'basic:replacewith': { + message: 'supports { replaceWith: ".focus-within" } usage', + options: { + replaceWith: '.focus-within' + } + } + } +}; diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000000..c56466446c --- /dev/null +++ b/.travis.yml @@ -0,0 +1,9 @@ +# https://docs.travis-ci.com/user/travis-lint + +language: node_js + +node_js: + - 4 + +install: + - npm install --ignore-scripts diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000000..7b2f126da6 --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,5 @@ +# Changes to PostCSS Focus Within + +### 1.0.0 (February 17, 2018) + +- Initial version diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 0000000000..e1295e92a7 --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,65 @@ +# Contributing to PostCSS Focus Within + +You want to help? You rock! Now, take a moment to be sure your contributions +make sense to everyone else. + +## Reporting Issues + +Found a problem? Want a new feature? + +- See if your issue or idea has [already been reported]. +- Provide a [reduced test case] or a [live example]. + +Remember, a bug is a _demonstrable problem_ caused by _our_ code. + +## Submitting Pull Requests + +Pull requests are the greatest contributions, so be sure they are focused in +scope and avoid unrelated commits. + +1. To begin; [fork this project], clone your fork, and add our upstream. + ```bash + # Clone your fork of the repo into the current directory + git clone git@github.com:YOUR_USER/postcss-focus-within.git + + # Navigate to the newly cloned directory + cd postcss-focus-within + + # Assign the original repo to a remote called "upstream" + git remote add upstream git@github.com:jonathantneal/postcss-focus-within.git + + # Install the tools necessary for testing + npm install + ``` + +2. Create a branch for your feature or fix: + ```bash + # Move into a new branch for your feature + git checkout -b feature/thing + ``` + ```bash + # Move into a new branch for your fix + git checkout -b fix/something + ``` + +3. If your code follows our practices, then push your feature branch: + ```bash + # Test current code + npm test + ``` + ```bash + # Push the branch for your new feature + git push origin feature/thing + ``` + ```bash + # Or, push the branch for your update + git push origin update/something + ``` + +That’s it! Now [open a pull request] with a clear title and description. + +[already been reported]: issues +[fork this project]: fork +[live example]: https://codepen.io/pen +[open a pull request]: https://help.github.com/articles/using-pull-requests/ +[reduced test case]: https://css-tricks.com/reduced-test-cases/ diff --git a/LICENSE.md b/LICENSE.md new file mode 100644 index 0000000000..0bc1fa7060 --- /dev/null +++ b/LICENSE.md @@ -0,0 +1,108 @@ +# CC0 1.0 Universal + +## Statement of Purpose + +The laws of most jurisdictions throughout the world automatically confer +exclusive Copyright and Related Rights (defined below) upon the creator and +subsequent owner(s) (each and all, an “owner”) of an original work of +authorship and/or a database (each, a “Work”). + +Certain owners wish to permanently relinquish those rights to a Work for the +purpose of contributing to a commons of creative, cultural and scientific works +(“Commons”) that the public can reliably and without fear of later claims of +infringement build upon, modify, incorporate in other works, reuse and +redistribute as freely as possible in any form whatsoever and for any purposes, +including without limitation commercial purposes. These owners may contribute +to the Commons to promote the ideal of a free culture and the further +production of creative, cultural and scientific works, or to gain reputation or +greater distribution for their Work in part through the use and efforts of +others. + +For these and/or other purposes and motivations, and without any expectation of +additional consideration or compensation, the person associating CC0 with a +Work (the “Affirmer”), to the extent that he or she is an owner of Copyright +and Related Rights in the Work, voluntarily elects to apply CC0 to the Work and +publicly distribute the Work under its terms, with knowledge of his or her +Copyright and Related Rights in the Work and the meaning and intended legal +effect of CC0 on those rights. + +1. Copyright and Related Rights. A Work made available under CC0 may be + protected by copyright and related or neighboring rights (“Copyright and + Related Rights”). Copyright and Related Rights include, but are not limited + to, the following: + 1. the right to reproduce, adapt, distribute, perform, display, communicate, + and translate a Work; + 2. moral rights retained by the original author(s) and/or performer(s); + 3. publicity and privacy rights pertaining to a person’s image or likeness + depicted in a Work; + 4. rights protecting against unfair competition in regards to a Work, + subject to the limitations in paragraph 4(i), below; + 5. rights protecting the extraction, dissemination, use and reuse of data in + a Work; + 6. database rights (such as those arising under Directive 96/9/EC of the + European Parliament and of the Council of 11 March 1996 on the legal + protection of databases, and under any national implementation thereof, + including any amended or successor version of such directive); and + 7. other similar, equivalent or corresponding rights throughout the world + based on applicable law or treaty, and any national implementations + thereof. + +2. Waiver. To the greatest extent permitted by, but not in contravention of, + applicable law, Affirmer hereby overtly, fully, permanently, irrevocably and + unconditionally waives, abandons, and surrenders all of Affirmer’s Copyright + and Related Rights and associated claims and causes of action, whether now + known or unknown (including existing as well as future claims and causes of + action), in the Work (i) in all territories worldwide, (ii) for the maximum + duration provided by applicable law or treaty (including future time + extensions), (iii) in any current or future medium and for any number of + copies, and (iv) for any purpose whatsoever, including without limitation + commercial, advertising or promotional purposes (the “Waiver”). Affirmer + makes the Waiver for the benefit of each member of the public at large and + to the detriment of Affirmer’s heirs and successors, fully intending that + such Waiver shall not be subject to revocation, rescission, cancellation, + termination, or any other legal or equitable action to disrupt the quiet + enjoyment of the Work by the public as contemplated by Affirmer’s express + Statement of Purpose. + +3. Public License Fallback. Should any part of the Waiver for any reason be + judged legally invalid or ineffective under applicable law, then the Waiver + shall be preserved to the maximum extent permitted taking into account + Affirmer’s express Statement of Purpose. In addition, to the extent the + Waiver is so judged Affirmer hereby grants to each affected person a + royalty-free, non transferable, non sublicensable, non exclusive, + irrevocable and unconditional license to exercise Affirmer’s Copyright and + Related Rights in the Work (i) in all territories worldwide, (ii) for the + maximum duration provided by applicable law or treaty (including future time + extensions), (iii) in any current or future medium and for any number of + copies, and (iv) for any purpose whatsoever, including without limitation + commercial, advertising or promotional purposes (the “License”). The License + shall be deemed effective as of the date CC0 was applied by Affirmer to the + Work. Should any part of the License for any reason be judged legally + invalid or ineffective under applicable law, such partial invalidity or + ineffectiveness shall not invalidate the remainder of the License, and in + such case Affirmer hereby affirms that he or she will not (i) exercise any + of his or her remaining Copyright and Related Rights in the Work or (ii) + assert any associated claims and causes of action with respect to the Work, + in either case contrary to Affirmer’s express Statement of Purpose. + +4. Limitations and Disclaimers. + 1. No trademark or patent rights held by Affirmer are waived, abandoned, + surrendered, licensed or otherwise affected by this document. + 2. Affirmer offers the Work as-is and makes no representations or warranties + of any kind concerning the Work, express, implied, statutory or + otherwise, including without limitation warranties of title, + merchantability, fitness for a particular purpose, non infringement, or + the absence of latent or other defects, accuracy, or the present or + absence of errors, whether or not discoverable, all to the greatest + extent permissible under applicable law. + 3. Affirmer disclaims responsibility for clearing rights of other persons + that may apply to the Work or any use thereof, including without + limitation any person’s Copyright and Related Rights in the Work. + Further, Affirmer disclaims responsibility for obtaining any necessary + consents, permissions or other rights required for any use of the Work. + 4. Affirmer understands and acknowledges that Creative Commons is not a + party to this document and has no duty or obligation with respect to this + CC0 or use of the Work. + +For more information, please see +http://creativecommons.org/publicdomain/zero/1.0/. diff --git a/README.md b/README.md new file mode 100644 index 0000000000..991ee7fcd0 --- /dev/null +++ b/README.md @@ -0,0 +1,187 @@ +# PostCSS Focus Within [PostCSS Logo][postcss] + +[![NPM Version][npm-img]][npm-url] +[![Build Status][cli-img]][cli-url] +[![Windows Build Status][win-img]][win-url] +[![Gitter Chat][git-img]][git-url] + +[PostCSS Focus Within] lets you use the `:focus-within` pseudo-selector in +CSS, following the [Selectors Level 4 specification]. + +```css +.my-form-field:focus-within label { + background-color: yellow; +} + +/* becomes */ + +.my-form-field[focus-within] label { + background-color: yellow; +} +``` + +[PostCSS Focus Within] replaces the `:focus-within` pseudo-selector with a +`.focus-within` class selector, the same selector used by the +[focus-within polyfill]. The replacement selector can be changed using the +`replaceWith` option. + +## Usage + +Add [PostCSS Focus Within] to your build tool: + +```bash +npm install postcss-focus-within --save-dev +``` + +#### Node + +Use [PostCSS Focus Within] to process your CSS: + +```js +import focusWithin from 'postcss-focus-within'; + +focusWithin.process(YOUR_CSS); +``` + +#### PostCSS + +Add [PostCSS] to your build tool: + +```bash +npm install postcss --save-dev +``` + +Use [PostCSS Focus Within] as a plugin: + +```js +import postcss from 'gulp-postcss'; +import focusWithin from 'postcss-focus-within'; + +postcss([ + focusWithin() +]).process(YOUR_CSS); +``` + +#### Webpack + +Add [PostCSS Loader] to your build tool: + +```bash +npm install postcss-loader --save-dev +``` + +Use [PostCSS Focus Within] in your Gulpfile: + +```js +import focusWithin from 'postcss-focus-within'; + +module.exports = { + module: { + rules: [ + { + test: /\.css$/, + use: [ + 'style-loader', + { loader: 'css-loader', options: { importLoaders: 1 } }, + { loader: 'postcss-loader', options: { + ident: 'postcss', + plugins: () => [ focusWithin() ] + } } + ] + } + ] + } +} +``` + +#### Gulp + +Add [Gulp PostCSS] to your build tool: + +```bash +npm install gulp-postcss --save-dev +``` + +Use [PostCSS Focus Within] in your Gulpfile: + +```js +import postcss from 'gulp-postcss'; +import focusWithin from 'postcss-focus-within'; + +gulp.task('css', () => gulp.src('./src/*.css').pipe( + postcss([ + focusWithin() + ]) +).pipe( + gulp.dest('.') +)); +``` + +#### Grunt + +Add [Grunt PostCSS] to your build tool: + +```bash +npm install grunt-postcss --save-dev +``` + +Use [PostCSS Focus Within] in your Gruntfile: + +```js +import focusWithin from 'postcss-focus-within'; + +grunt.loadNpmTasks('grunt-postcss'); + +grunt.initConfig({ + postcss: { + options: { + use: [ + focusWithin() + ] + }, + dist: { + src: '*.css' + } + } +}); +``` + +## Options + +### replaceWith + +The `replaceWith` option defines the selector to replace `:focus-within`. By +default, the replacement selector is `[focus-within]`. + +```js +focusWithin({ replaceWith: '.focus-within' }); +``` + +```css +.my-form-field:focus-within label { + background-color: yellow; +} + +/* becomes */ + +.my-form-field.focus-within label { + background-color: yellow; +} +``` + +[npm-url]: https://www.npmjs.com/package/postcss-focus-within +[npm-img]: https://img.shields.io/npm/v/postcss-focus-within.svg +[cli-url]: https://travis-ci.org/jonathantneal/postcss-focus-within +[cli-img]: https://img.shields.io/travis/jonathantneal/postcss-focus-within.svg +[win-url]: https://ci.appveyor.com/project/jonathantneal/postcss-focus-within +[win-img]: https://img.shields.io/appveyor/ci/jonathantneal/postcss-focus-within.svg +[git-url]: https://gitter.im/postcss/postcss +[git-img]: https://img.shields.io/badge/chat-gitter-blue.svg + +[focus-within polyfill]: https://github.com/jonathantneal/focus-within +[Gulp PostCSS]: https://github.com/postcss/gulp-postcss +[Grunt PostCSS]: https://github.com/nDmitry/grunt-postcss +[PostCSS]: https://github.com/postcss/postcss +[PostCSS Focus Within]: https://github.com/jonathantneal/postcss-focus-within +[PostCSS Loader]: https://github.com/postcss/postcss-loader +[Selectors Level 4 specification]: https://www.w3.org/TR/selectors-4/#the-focus-within-pseudo diff --git a/index.js b/index.js new file mode 100644 index 0000000000..dbaff97513 --- /dev/null +++ b/index.js @@ -0,0 +1,15 @@ +import postcss from 'postcss'; + +const selectorRegExp = /:focus-within([^\w-]|$)/gi; + +export default postcss.plugin('postcss-focus-within', opts => { + const replaceWith = String(Object(opts).replaceWith || '[focus-within]'); + + return root => { + root.walkRules(selectorRegExp, rule => { + rule.selector = rule.selector.replace(selectorRegExp, ($0, $1) => { + return `${replaceWith}${$1}`; + }); + }); + }; +}); diff --git a/package.json b/package.json new file mode 100644 index 0000000000..72568f77ca --- /dev/null +++ b/package.json @@ -0,0 +1,60 @@ +{ + "name": "postcss-focus-within", + "version": "1.0.0", + "description": "", + "author": "Jonathan Neal ", + "license": "CC0-1.0", + "repository": "jonathantneal/postcss-focus-within", + "homepage": "https://github.com/jonathantneal/postcss-focus-within#readme", + "bugs": "https://github.com/jonathantneal/postcss-focus-within/issues", + "main": "index.bundle.js", + "module": "index.js", + "files": [ + "index.js", + "index.bundle.js" + ], + "scripts": { + "prepublishOnly": "npm test", + "pretest": "rollup -c .rollup.js --silent", + "test": "echo 'Running tests...'; npm run test:ec && npm run test:js && npm run test:tape", + "test:ec": "echint --ignore index.bundle.js test", + "test:js": "eslint *.js --cache --ignore-path .gitignore --quiet", + "test:tape": "postcss-tape" + }, + "engines": { + "node": ">=4.0.0" + }, + "dependencies": { + "postcss": "^6.0" + }, + "devDependencies": { + "babel-core": "^6.26", + "babel-eslint": "^8.2", + "babel-preset-env": "^1.6", + "echint": "^4.0", + "eslint": "^4.18", + "eslint-config-dev": "2.0", + "postcss-tape": "2.2", + "pre-commit": "^1.2", + "rollup": "^0.56", + "rollup-plugin-babel": "^3.0" + }, + "eslintConfig": { + "extends": "dev", + "parser": "babel-eslint" + }, + "keywords": [ + "postcss", + "css", + "postcss-plugin", + "focus", + "within", + "polyfill", + "pseudos", + "selectors", + "accessibility", + "a11y", + "descendants", + "ancestors" + ] +} diff --git a/test/basic.css b/test/basic.css new file mode 100644 index 0000000000..3dc906893b --- /dev/null +++ b/test/basic.css @@ -0,0 +1,27 @@ +:focus-within { + order: 1; +} + +:focus-within, +:focus-within test, +test :focus-within, +test test:focus-within, +test :focus-within test, +test test:focus-within test, +test :focus-within :focus-within test, +test :matches(:focus-within) test, +test :matches(:focus-within test) test, +test :matches(test :focus-within) test, +test :matches(test test:focus-within) test, +test :matches(test :focus-within test) test, +test :matches(test test:focus-within test) test, +test :matches(test :focus-within :focus-within test) test { + order: 2; +} + +:ignore-focus-within, +:focus-within-ignore, +:ignorefocus-within, +:focus-withinignore { + order: 3; +} diff --git a/test/basic.expect.css b/test/basic.expect.css new file mode 100644 index 0000000000..7691c5efa1 --- /dev/null +++ b/test/basic.expect.css @@ -0,0 +1,27 @@ +[focus-within] { + order: 1; +} + +[focus-within], +[focus-within] test, +test [focus-within], +test test[focus-within], +test [focus-within] test, +test test[focus-within] test, +test [focus-within] [focus-within] test, +test :matches([focus-within]) test, +test :matches([focus-within] test) test, +test :matches(test [focus-within]) test, +test :matches(test test[focus-within]) test, +test :matches(test [focus-within] test) test, +test :matches(test test[focus-within] test) test, +test :matches(test [focus-within] [focus-within] test) test { + order: 2; +} + +:ignore-focus-within, +:focus-within-ignore, +:ignorefocus-within, +:focus-withinignore { + order: 3; +} diff --git a/test/basic.replacewith.expect.css b/test/basic.replacewith.expect.css new file mode 100644 index 0000000000..407dc2610c --- /dev/null +++ b/test/basic.replacewith.expect.css @@ -0,0 +1,27 @@ +.focus-within { + order: 1; +} + +.focus-within, +.focus-within test, +test .focus-within, +test test.focus-within, +test .focus-within test, +test test.focus-within test, +test .focus-within .focus-within test, +test :matches(.focus-within) test, +test :matches(.focus-within test) test, +test :matches(test .focus-within) test, +test :matches(test test.focus-within) test, +test :matches(test .focus-within test) test, +test :matches(test test.focus-within test) test, +test :matches(test .focus-within .focus-within test) test { + order: 2; +} + +:ignore-focus-within, +:focus-within-ignore, +:ignorefocus-within, +:focus-withinignore { + order: 3; +} From 1b495ce1c5acb50f58c1bd4cc1f594b8468e37b8 Mon Sep 17 00:00:00 2001 From: Jonathan Neal Date: Mon, 19 Feb 2018 01:48:58 -0500 Subject: [PATCH 577/795] Fix documentation code examples for preserve option --- README.md | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index cfa3a8495d..5b79d91db7 100755 --- a/README.md +++ b/README.md @@ -178,9 +178,7 @@ containing `var()` will be removed: ```js postCSSCustomProperties({ - variables: { - preserve: false - } + preserve: false }) ``` @@ -205,9 +203,7 @@ will remain, but declarations containing `var()` will be removed: ```js postCSSCustomProperties({ - variables: { - preserve: 'preserve-computed' - } + preserve: 'preserve-computed' }) ``` From 792c86b5708dd2d98629d5ccc8bbb7b68a0d9d31 Mon Sep 17 00:00:00 2001 From: Lee Symes <2038057+leesdolphin@users.noreply.github.com> Date: Thu, 22 Feb 2018 04:21:31 +1300 Subject: [PATCH 578/795] Retain spacing around color-mod function --- lib/transform.js | 1 + test/basic.colors.expect.css | 4 ++++ test/basic.css | 4 ++++ test/basic.expect.css | 4 ++++ 4 files changed, 13 insertions(+) diff --git a/lib/transform.js b/lib/transform.js index a50382c6dc..866940a15d 100644 --- a/lib/transform.js +++ b/lib/transform.js @@ -22,6 +22,7 @@ export default function transformAST(node, opts) { // update the color-mod() function with the transformed value child.replaceWith( parser.word({ + raws: child.raws, value: opts.stringifier(color) }) ); diff --git a/test/basic.colors.expect.css b/test/basic.colors.expect.css index 91744a07a4..d758803c0e 100644 --- a/test/basic.colors.expect.css +++ b/test/basic.colors.expect.css @@ -127,3 +127,7 @@ test-sameness { test-var { color: rgb(0% 0% 100%); } + +test-multiple-value-items { + border: 1px solid rgb(100% 0% 0%); +} diff --git a/test/basic.css b/test/basic.css index 2ae92a4feb..58f6efca9b 100644 --- a/test/basic.css +++ b/test/basic.css @@ -127,3 +127,7 @@ test-sameness { test-var { color: color-mod(var(--color)); } + +test-multiple-value-items { + border: 1px solid color-mod(red); +} diff --git a/test/basic.expect.css b/test/basic.expect.css index 95579227c5..ec89f8b4f8 100644 --- a/test/basic.expect.css +++ b/test/basic.expect.css @@ -127,3 +127,7 @@ test-sameness { test-var { color: rgb(0, 0, 255); } + +test-multiple-value-items { + border: 1px solid rgb(255, 0, 0); +} From 7297ddb0e2e4bdbed14a91702ed58ac52979d9dd Mon Sep 17 00:00:00 2001 From: Jonathan Neal Date: Wed, 21 Feb 2018 10:25:53 -0500 Subject: [PATCH 579/795] 2.4.1 --- CHANGELOG.md | 8 +++++++- package.json | 4 ++-- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6632ebc7dc..8dd94183d5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,10 @@ # Changes to PostCSS color-mod() Function -### 2.3.0 (February 16, 2018) +### 2.4.1 (February 21, 2018) + +- Fixed issue with spacing around `color-mod` (credit: [@leesdolphin]) + +### 2.4.0 (February 16, 2018) - Added build-time support for Custom Properties and Variables - Updated `@csstools/convert-colors` to 1.4 (minor update) @@ -36,3 +40,5 @@ ### 1.0.0 (January 16, 2018) - Initial version + +[@leesdolphin]: https://github.com/leesdolphin diff --git a/package.json b/package.json index e2a8407e76..093bb620dc 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "postcss-color-mod-function", - "version": "2.4.0", + "version": "2.4.1", "description": "Modify colors using the color-mod() function in CSS", "author": "Jonathan Neal ", "license": "CC0-1.0", @@ -35,7 +35,7 @@ "babel-eslint": "^8.2", "babel-preset-env": "^1.6", "echint": "^4.0", - "eslint": "^4.17", + "eslint": "^4.18", "eslint-config-dev": "2.0", "postcss-tape": "2.2", "pre-commit": "^1.2", From 6460130771211ec01254b9be0c6c3fab4d77bb00 Mon Sep 17 00:00:00 2001 From: Evgeny Petukhov Date: Mon, 26 Feb 2018 01:38:10 +0300 Subject: [PATCH 580/795] Fixed link to CSS Color Module Level 4 --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 91b7698792..b2829b4245 100644 --- a/README.md +++ b/README.md @@ -205,7 +205,7 @@ knowledge of the living DOM tree. [git-url]: https://gitter.im/postcss/postcss [git-img]: https://img.shields.io/badge/chat-gitter-blue.svg -[CSS Color Module Level 4]: https://drafts.csswg.org/css-color/#modifying-colors +[CSS Color Module Level 4]: https://www.w3.org/TR/css-color-4/#funcdef-color-mod [Gulp PostCSS]: https://github.com/postcss/gulp-postcss [Grunt PostCSS]: https://github.com/nDmitry/grunt-postcss [PostCSS]: https://github.com/postcss/postcss From 4ab54f63231e06bf934d5b97a626785c1344d7f9 Mon Sep 17 00:00:00 2001 From: Jonathan Neal Date: Tue, 27 Feb 2018 00:56:28 -0500 Subject: [PATCH 581/795] Detect colorspace --- lib/color.js | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/lib/color.js b/lib/color.js index 1f488c8c0a..66e232a093 100644 --- a/lib/color.js +++ b/lib/color.js @@ -4,6 +4,16 @@ export default class Color { constructor(color) { this.color = Object(Object(color).color || color); + this.color.colorspace = this.color.colorspace + ? this.color.colorspace + : 'red' in color && 'green' in color && 'blue' in color + ? 'rgb' + : 'hue' in color && 'saturation' in color && 'lightness' in color + ? 'hsl' + : 'hue' in color && 'whiteness' in color && 'blackness' in color + ? 'hwb' + : 'unknown'; + if (color.colorspace === 'rgb') { this.color.hue = rgb2hue(color.red, color.green, color.blue, color.hue || 0); } From 162a6b15b2aab2a4cbe4ba9c647f0f13ff525985 Mon Sep 17 00:00:00 2001 From: Jonathan Neal Date: Tue, 27 Feb 2018 00:56:41 -0500 Subject: [PATCH 582/795] Test hex colors --- .tape.js | 5 ++++- test/hex.css | 23 +++++++++++++++++++++++ test/hex.expect.css | 23 +++++++++++++++++++++++ 3 files changed, 50 insertions(+), 1 deletion(-) create mode 100644 test/hex.css create mode 100644 test/hex.expect.css diff --git a/.tape.js b/.tape.js index 2f17776867..daa07d1e55 100644 --- a/.tape.js +++ b/.tape.js @@ -25,6 +25,9 @@ module.exports = { }, warning: 43, expect: 'warn.css' - } + }, + 'hex': { + message: 'supports hex usage' + }, } }; diff --git a/test/hex.css b/test/hex.css new file mode 100644 index 0000000000..c644daf790 --- /dev/null +++ b/test/hex.css @@ -0,0 +1,23 @@ +test { + color: color-mod(#000000 b(50%)); + color: color-mod(#000000 red(50%)); + color: color-mod(#000000 green(50%)); + color: color-mod(#000000 blue(50%)); + color: color-mod(#000000 a(50%)); + color: color-mod(#000000 alpha(50%)); + color: color-mod(#000000 h(50deg)); + color: color-mod(#000000 hue(50deg)); + color: color-mod(#000000 s(50%)); + color: color-mod(#000000 saturation(50%)); + color: color-mod(#000000 l(50%)); + color: color-mod(#000000 lightness(50%)); + color: color-mod(#000000 w(50%)); + color: color-mod(#000000 whiteness(50%)); + color: color-mod(#000000 b(50%)); + color: color-mod(#000000 blackness(50%)); + color: color-mod(#000000 tint(50%)); + color: color-mod(#000000 shade(50%)); + color: color-mod(#000000 blend(#ffffff 50%)); + color: color-mod(#000000 blenda(#ffffff 50%)); + color: color-mod(#000000 contrast(50%)); +} diff --git a/test/hex.expect.css b/test/hex.expect.css new file mode 100644 index 0000000000..04233880fb --- /dev/null +++ b/test/hex.expect.css @@ -0,0 +1,23 @@ +test { + color: rgb(128, 0, 0); + color: rgb(128, 0, 0); + color: rgb(0, 128, 0); + color: rgb(0, 0, 128); + color: rgba(0, 0, 0, 0.5); + color: rgba(0, 0, 0, 0.5); + color: hsl(50, 0%, 0%); + color: hsl(50, 0%, 0%); + color: hsl(0, 50%, 0%); + color: hsl(0, 50%, 0%); + color: hsl(0, 0%, 50%); + color: hsl(0, 0%, 50%); + color: rgb(0, 128, 128); + color: rgb(0, 128, 128); + color: rgb(128, 0, 0); + color: rgb(128, 0, 0); + color: rgb(128, 128, 128); + color: rgb(0, 0, 0); + color: rgb(128, 128, 128); + color: rgb(128, 128, 128); + color: rgb(128, 128, 128); +} From cc44ed5922aef9bfd15954b908bccc25e3acc514 Mon Sep 17 00:00:00 2001 From: Jonathan Neal Date: Tue, 27 Feb 2018 00:56:54 -0500 Subject: [PATCH 583/795] Update packages --- package.json | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/package.json b/package.json index 093bb620dc..28f11d28f9 100644 --- a/package.json +++ b/package.json @@ -26,21 +26,21 @@ "node": ">=4.0.0" }, "dependencies": { - "@csstools/convert-colors": "^1.4", - "postcss": "^6.0", - "postcss-values-parser": "^1.3" + "@csstools/convert-colors": "^1.4.0", + "postcss": "^6.0.19", + "postcss-values-parser": "^1.3.2" }, "devDependencies": { - "babel-core": "^6.26", - "babel-eslint": "^8.2", - "babel-preset-env": "^1.6", - "echint": "^4.0", - "eslint": "^4.18", - "eslint-config-dev": "2.0", - "postcss-tape": "2.2", - "pre-commit": "^1.2", - "rollup": "^0.56", - "rollup-plugin-babel": "^3.0" + "babel-core": "^6.26.0", + "babel-eslint": "^8.2.2", + "babel-preset-env": "^1.6.1", + "echint": "^4.0.1", + "eslint": "^4.18.1", + "eslint-config-dev": "^2.0.0", + "postcss-tape": "^2.2.0", + "pre-commit": "^1.2.2", + "rollup": "^0.56.3", + "rollup-plugin-babel": "^3.0.3" }, "eslintConfig": { "extends": "dev", From 39f669e5be337dd72defb31bf461e808c07f1c91 Mon Sep 17 00:00:00 2001 From: Jonathan Neal Date: Tue, 27 Feb 2018 00:57:36 -0500 Subject: [PATCH 584/795] 2.4.2 --- CHANGELOG.md | 4 ++++ package.json | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8dd94183d5..5373f2af06 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # Changes to PostCSS color-mod() Function +### 2.4.2 (February 27, 2018) + +- Fixed issue with converting colorspaces + ### 2.4.1 (February 21, 2018) - Fixed issue with spacing around `color-mod` (credit: [@leesdolphin]) diff --git a/package.json b/package.json index 28f11d28f9..da1a0f5d49 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "postcss-color-mod-function", - "version": "2.4.1", + "version": "2.4.2", "description": "Modify colors using the color-mod() function in CSS", "author": "Jonathan Neal ", "license": "CC0-1.0", From a50f2f7384b9f025de27c77bfd9cb95192a4d044 Mon Sep 17 00:00:00 2001 From: Jonathan Neal Date: Tue, 20 Mar 2018 23:02:00 -0400 Subject: [PATCH 585/795] Update project configuration --- .appveyor.yml | 2 +- .gitignore | 6 +- .rollup.js | 16 + dependent-js/clone-decl.js | 6 +- dependent-js/clone-rule.js | 4 +- dependent-js/match-inset-prefix.js | 2 +- dependent-js/match-side.js | 2 +- dependent-js/match-size.js | 2 +- dependent-js/match-supported-properties.js | 2 +- dependent-js/transform-border.js | 429 +++++++++++---------- dependent-js/transform-float.js | 4 +- dependent-js/transform-inset.js | 4 +- dependent-js/transform-resize.js | 2 +- dependent-js/transform-side.js | 194 +++++----- dependent-js/transform-size.js | 4 +- dependent-js/transform-spacing.js | 4 +- dependent-js/transform-text-align.js | 4 +- index.js | 44 ++- package.json | 35 +- 19 files changed, 399 insertions(+), 367 deletions(-) create mode 100644 .rollup.js diff --git a/.appveyor.yml b/.appveyor.yml index d6b511f500..acbf8a5eeb 100644 --- a/.appveyor.yml +++ b/.appveyor.yml @@ -2,7 +2,7 @@ environment: matrix: - - nodejs_version: 4.0 + - nodejs_version: 4 version: "{build}" build: off diff --git a/.gitignore b/.gitignore index 995098afd2..de73e5a338 100644 --- a/.gitignore +++ b/.gitignore @@ -1,10 +1,12 @@ node_modules +index.*.js package-lock.json +*.log* +*.result.css .* !.appveyor.yml !.editorconfig !.gitignore +!.rollup.js !.tape.js !.travis.yml -*.log* -*.result.css diff --git a/.rollup.js b/.rollup.js new file mode 100644 index 0000000000..0436758216 --- /dev/null +++ b/.rollup.js @@ -0,0 +1,16 @@ +import babel from 'rollup-plugin-babel'; + +export default { + input: 'index.js', + output: [ + { file: 'index.cjs.js', format: 'cjs' }, + { file: 'index.es.js', format: 'es' } + ], + plugins: [ + babel({ + presets: [ + ['env', { modules: false, targets: { node: 4 } }] + ] + }) + ] +}; diff --git a/dependent-js/clone-decl.js b/dependent-js/clone-decl.js index 06e2a12faa..69c124b2da 100644 --- a/dependent-js/clone-decl.js +++ b/dependent-js/clone-decl.js @@ -1,7 +1,7 @@ -const matchSide = require('./match-side'); -const matchInsetPrefix = require('./match-inset-prefix'); +import matchSide from './match-side'; +import matchInsetPrefix from './match-inset-prefix'; -module.exports = (decl, suffix, value) => decl.clone({ +export default (decl, suffix, value) => decl.clone({ prop: `${decl.prop.replace(matchSide, '$1')}${suffix}`.replace(matchInsetPrefix, ''), value }); diff --git a/dependent-js/clone-rule.js b/dependent-js/clone-rule.js index 032213bfb3..91039ef85c 100644 --- a/dependent-js/clone-rule.js +++ b/dependent-js/clone-rule.js @@ -1,8 +1,8 @@ 'use strict'; -const postcss = require('postcss'); +import postcss from 'postcss'; -module.exports = (decl, dir) => { +export default (decl, dir) => { let node = decl.parent; while (node && 'rule' !== node.type) { diff --git a/dependent-js/match-inset-prefix.js b/dependent-js/match-inset-prefix.js index 0a6c302778..f0449be6d3 100644 --- a/dependent-js/match-inset-prefix.js +++ b/dependent-js/match-inset-prefix.js @@ -1 +1 @@ -module.exports = /^inset-/i; +export default /^inset-/i; diff --git a/dependent-js/match-side.js b/dependent-js/match-side.js index 285a554053..19b557e5af 100644 --- a/dependent-js/match-side.js +++ b/dependent-js/match-side.js @@ -1 +1 @@ -module.exports = /^(inset|margin|padding)(?:-(block|block-start|block-end|inline|inline-start|inline-end|start|end))$/i; +export default /^(inset|margin|padding)(?:-(block|block-start|block-end|inline|inline-start|inline-end|start|end))$/i; diff --git a/dependent-js/match-size.js b/dependent-js/match-size.js index 1514b4cd61..f53000b47a 100644 --- a/dependent-js/match-size.js +++ b/dependent-js/match-size.js @@ -1 +1 @@ -module.exports = /^(min-|max-)?(block|inline)-(size)$/i; +export default /^(min-|max-)?(block|inline)-(size)$/i; diff --git a/dependent-js/match-supported-properties.js b/dependent-js/match-supported-properties.js index 8c9eeb8c31..8697638448 100644 --- a/dependent-js/match-supported-properties.js +++ b/dependent-js/match-supported-properties.js @@ -1 +1 @@ -module.exports = /^(?:(inset|margin|padding)(?:-(block|block-start|block-end|inline|inline-start|inline-end|start|end))|(min-|max-)?(block|inline)-(size))$/i; +export default /^(?:(inset|margin|padding)(?:-(block|block-start|block-end|inline|inline-start|inline-end|start|end))|(min-|max-)?(block|inline)-(size))$/i; diff --git a/dependent-js/transform-border.js b/dependent-js/transform-border.js index 274b3290b1..25d6a6f46b 100644 --- a/dependent-js/transform-border.js +++ b/dependent-js/transform-border.js @@ -1,228 +1,229 @@ -const cloneRule = require('./clone-rule'); +import cloneRule from './clone-rule'; const matchLogical = /^\s*logical\s+/i; const matchLogicalBorder = /^border(-width|-style|-color)?$/i; const matchLogicalBorderSide = /^border-(block|block-start|block-end|inline|inline-start|inline-end|start|end)(-(width|style|color))?$/i; -// border -module.exports['border'] = (decl, values, dir) => { - const isLogical = matchLogical.test(values[0]); - - if (isLogical) { - values[0] = values[0].replace(matchLogical, ''); - } - - const ltrDecls = [ - decl.clone({ - prop: `border-top${decl.prop.replace(matchLogicalBorder, '$1')}`, - value: values[0] - }), - decl.clone({ - prop: `border-left${decl.prop.replace(matchLogicalBorder, '$1')}`, - value: values[1] || values[0] - }), - decl.clone({ - prop: `border-bottom${decl.prop.replace(matchLogicalBorder, '$1')}`, - value: values[2] || values[0] - }), - decl.clone({ - prop: `border-right${decl.prop.replace(matchLogicalBorder, '$1')}`, - value: values[3] || values[1] || values[0] - }) - ]; - - const rtlDecls = [ - decl.clone({ - prop: `border-top${decl.prop.replace(matchLogicalBorder, '$1')}`, - value: values[0] - }), - decl.clone({ - prop: `border-right${decl.prop.replace(matchLogicalBorder, '$1')}`, - value: values[1] || values[0] - }), - decl.clone({ - prop: `border-bottom${decl.prop.replace(matchLogicalBorder, '$1')}`, - value: values[2] || values[0] - }), - decl.clone({ - prop: `border-left${decl.prop.replace(matchLogicalBorder, '$1')}`, - value: values[3] || values[1] || values[0] - }) - ]; - - return isLogical ? 1 === values.length - ? decl.clone({ - value: decl.value.replace(matchLogical, '') - }) - : !values[3] || values[3] === values[1] - ? [ - decl.clone({ - prop: `border-top${decl.prop.replace(matchLogicalBorder, '$1')}`, - value: values[0] - }), - decl.clone({ - prop: `border-right${decl.prop.replace(matchLogicalBorder, '$1')}`, - value: values[3] || values[1] || values[0] - }), - decl.clone({ - prop: `border-bottom${decl.prop.replace(matchLogicalBorder, '$1')}`, - value: values[2] || values[0] - }), - decl.clone({ - prop: `border-left${decl.prop.replace(matchLogicalBorder, '$1')}`, - value: values[1] || values[0] - }) - ] - : 'ltr' === dir ? ltrDecls : 'rtl' === dir ? rtlDecls : [ - cloneRule(decl, 'ltr').append(ltrDecls), - cloneRule(decl, 'rtl').append(rtlDecls) - ] - : null; -}; - - -// border-block -module.exports['border-block'] = (decl, values) => [ - decl.clone({ - prop: `border-top${decl.prop.replace(matchLogicalBorderSide, '$2')}`, - value: values[0] - }), - decl.clone({ - prop: `border-bottom${decl.prop.replace(matchLogicalBorderSide, '$2')}`, - value: values[0] - }) -]; - -// border-block-start -module.exports['border-block-start'] = (decl) => { - decl.prop = 'border-top'; -}; - -// border-block-end -module.exports['border-block-end'] = (decl) => { - decl.prop = 'border-bottom'; -}; - -// border-inline -module.exports['border-inline'] = (decl, values, dir) => { - const ltrDecls = [ - decl.clone({ - prop: `border-left${decl.prop.replace(matchLogicalBorderSide, '$2')}`, - value: values[0] - }), - decl.clone({ - prop: `border-right${decl.prop.replace(matchLogicalBorderSide, '$2')}`, - value: values[1] || values[0] - }) - ]; - - const rtlDecls = [ - decl.clone({ - prop: `border-right${decl.prop.replace(matchLogicalBorderSide, '$2')}`, - value: values[0] - }), - decl.clone({ - prop: `border-left${decl.prop.replace(matchLogicalBorderSide, '$2')}`, - value: values[1] || values[0] - }) - ]; - - const isLTR = 1 === values.length || 2 === values.length && values[0] === values[1]; - - return isLTR ? ltrDecls : 'ltr' === dir ? ltrDecls : 'rtl' === dir ? rtlDecls : [ - cloneRule(decl, 'ltr').append(ltrDecls), - cloneRule(decl, 'rtl').append(rtlDecls) - ]; -}; - -// border-inline-start -module.exports['border-inline-start'] = (decl, values, dir) => { - const ltrDecl = decl.clone({ - prop: `border-left${decl.prop.replace(matchLogicalBorderSide, '$2')}` - }); - - const rtlDecl = decl.clone({ - prop: `border-right${decl.prop.replace(matchLogicalBorderSide, '$2')}` - }); - - return 'ltr' === dir ? ltrDecl : 'rtl' === dir ? rtlDecl : [ - cloneRule(decl, 'ltr').append(ltrDecl), - cloneRule(decl, 'rtl').append(rtlDecl) - ]; -}; - -// border-inline-end -module.exports['border-inline-end'] = (decl, values, dir) => { - const ltrDecl = decl.clone({ - prop: `border-right${decl.prop.replace(matchLogicalBorderSide, '$2')}` - }); - - const rtlDecl = decl.clone({ - prop: `border-left${decl.prop.replace(matchLogicalBorderSide, '$2')}` - }); - - return 'ltr' === dir ? ltrDecl : 'rtl' === dir ? rtlDecl : [ - cloneRule(decl, 'ltr').append(ltrDecl), - cloneRule(decl, 'rtl').append(rtlDecl) - ]; -}; - -// border-start -module.exports['border-start'] = (decl, values, dir) => { - const ltrDecls = [ - decl.clone({ - prop: `border-top${decl.prop.replace(matchLogicalBorderSide, '$2')}`, - value: values[0] - }), - decl.clone({ - prop: `border-left${decl.prop.replace(matchLogicalBorderSide, '$2')}`, - value: values[1] || values[0] - }) - ]; - - const rtlDecls = [ +export default { + // border + 'border': (decl, values, dir) => { + const isLogical = matchLogical.test(values[0]); + + if (isLogical) { + values[0] = values[0].replace(matchLogical, ''); + } + + const ltrDecls = [ + decl.clone({ + prop: `border-top${decl.prop.replace(matchLogicalBorder, '$1')}`, + value: values[0] + }), + decl.clone({ + prop: `border-left${decl.prop.replace(matchLogicalBorder, '$1')}`, + value: values[1] || values[0] + }), + decl.clone({ + prop: `border-bottom${decl.prop.replace(matchLogicalBorder, '$1')}`, + value: values[2] || values[0] + }), + decl.clone({ + prop: `border-right${decl.prop.replace(matchLogicalBorder, '$1')}`, + value: values[3] || values[1] || values[0] + }) + ]; + + const rtlDecls = [ + decl.clone({ + prop: `border-top${decl.prop.replace(matchLogicalBorder, '$1')}`, + value: values[0] + }), + decl.clone({ + prop: `border-right${decl.prop.replace(matchLogicalBorder, '$1')}`, + value: values[1] || values[0] + }), + decl.clone({ + prop: `border-bottom${decl.prop.replace(matchLogicalBorder, '$1')}`, + value: values[2] || values[0] + }), + decl.clone({ + prop: `border-left${decl.prop.replace(matchLogicalBorder, '$1')}`, + value: values[3] || values[1] || values[0] + }) + ]; + + return isLogical ? 1 === values.length + ? decl.clone({ + value: decl.value.replace(matchLogical, '') + }) + : !values[3] || values[3] === values[1] + ? [ + decl.clone({ + prop: `border-top${decl.prop.replace(matchLogicalBorder, '$1')}`, + value: values[0] + }), + decl.clone({ + prop: `border-right${decl.prop.replace(matchLogicalBorder, '$1')}`, + value: values[3] || values[1] || values[0] + }), + decl.clone({ + prop: `border-bottom${decl.prop.replace(matchLogicalBorder, '$1')}`, + value: values[2] || values[0] + }), + decl.clone({ + prop: `border-left${decl.prop.replace(matchLogicalBorder, '$1')}`, + value: values[1] || values[0] + }) + ] + : 'ltr' === dir ? ltrDecls : 'rtl' === dir ? rtlDecls : [ + cloneRule(decl, 'ltr').append(ltrDecls), + cloneRule(decl, 'rtl').append(rtlDecls) + ] + : null; + }, + + // border-block + 'border-block': (decl, values) => [ decl.clone({ prop: `border-top${decl.prop.replace(matchLogicalBorderSide, '$2')}`, value: values[0] }), - decl.clone({ - prop: `border-right${decl.prop.replace(matchLogicalBorderSide, '$2')}`, - value: values[1] || values[0] - }) - ]; - - return 'ltr' === dir ? ltrDecls : 'rtl' === dir ? rtlDecls : [ - cloneRule(decl, 'ltr').append(ltrDecls), - cloneRule(decl, 'rtl').append(rtlDecls) - ]; -}; - -// border-end -module.exports['border-end'] = (decl, values, dir) => { - const ltrDecls = [ decl.clone({ prop: `border-bottom${decl.prop.replace(matchLogicalBorderSide, '$2')}`, value: values[0] - }), - decl.clone({ - prop: `border-right${decl.prop.replace(matchLogicalBorderSide, '$2')}`, - value: values[1] || values[0] }) - ]; - - const rtlDecls = [ - decl.clone({ - prop: `border-bottom${decl.prop.replace(matchLogicalBorderSide, '$2')}`, - value: values[0] - }), - decl.clone({ - prop: `border-left${decl.prop.replace(matchLogicalBorderSide, '$2')}`, - value: values[1] || values[0] - }) - ]; - - return 'ltr' === dir ? ltrDecls : 'rtl' === dir ? rtlDecls : [ - cloneRule(decl, 'ltr').append(ltrDecls), - cloneRule(decl, 'rtl').append(rtlDecls) - ]; + ], + + // border-block-start + 'border-block-start': decl => { + decl.prop = 'border-top'; + }, + + // border-block-end + 'border-block-end': decl => { + decl.prop = 'border-bottom'; + }, + + // border-inline + 'border-inline': (decl, values, dir) => { + const ltrDecls = [ + decl.clone({ + prop: `border-left${decl.prop.replace(matchLogicalBorderSide, '$2')}`, + value: values[0] + }), + decl.clone({ + prop: `border-right${decl.prop.replace(matchLogicalBorderSide, '$2')}`, + value: values[1] || values[0] + }) + ]; + + const rtlDecls = [ + decl.clone({ + prop: `border-right${decl.prop.replace(matchLogicalBorderSide, '$2')}`, + value: values[0] + }), + decl.clone({ + prop: `border-left${decl.prop.replace(matchLogicalBorderSide, '$2')}`, + value: values[1] || values[0] + }) + ]; + + const isLTR = 1 === values.length || 2 === values.length && values[0] === values[1]; + + return isLTR ? ltrDecls : 'ltr' === dir ? ltrDecls : 'rtl' === dir ? rtlDecls : [ + cloneRule(decl, 'ltr').append(ltrDecls), + cloneRule(decl, 'rtl').append(rtlDecls) + ]; + }, + + // border-inline-start + 'border-inline-start': (decl, values, dir) => { + const ltrDecl = decl.clone({ + prop: `border-left${decl.prop.replace(matchLogicalBorderSide, '$2')}` + }); + + const rtlDecl = decl.clone({ + prop: `border-right${decl.prop.replace(matchLogicalBorderSide, '$2')}` + }); + + return 'ltr' === dir ? ltrDecl : 'rtl' === dir ? rtlDecl : [ + cloneRule(decl, 'ltr').append(ltrDecl), + cloneRule(decl, 'rtl').append(rtlDecl) + ]; + }, + + // border-inline-end + 'border-inline-end': (decl, values, dir) => { + const ltrDecl = decl.clone({ + prop: `border-right${decl.prop.replace(matchLogicalBorderSide, '$2')}` + }); + + const rtlDecl = decl.clone({ + prop: `border-left${decl.prop.replace(matchLogicalBorderSide, '$2')}` + }); + + return 'ltr' === dir ? ltrDecl : 'rtl' === dir ? rtlDecl : [ + cloneRule(decl, 'ltr').append(ltrDecl), + cloneRule(decl, 'rtl').append(rtlDecl) + ]; + }, + + // border-start + 'border-start': (decl, values, dir) => { + const ltrDecls = [ + decl.clone({ + prop: `border-top${decl.prop.replace(matchLogicalBorderSide, '$2')}`, + value: values[0] + }), + decl.clone({ + prop: `border-left${decl.prop.replace(matchLogicalBorderSide, '$2')}`, + value: values[1] || values[0] + }) + ]; + + const rtlDecls = [ + decl.clone({ + prop: `border-top${decl.prop.replace(matchLogicalBorderSide, '$2')}`, + value: values[0] + }), + decl.clone({ + prop: `border-right${decl.prop.replace(matchLogicalBorderSide, '$2')}`, + value: values[1] || values[0] + }) + ]; + + return 'ltr' === dir ? ltrDecls : 'rtl' === dir ? rtlDecls : [ + cloneRule(decl, 'ltr').append(ltrDecls), + cloneRule(decl, 'rtl').append(rtlDecls) + ]; + }, + + // border-end + 'border-end': (decl, values, dir) => { + const ltrDecls = [ + decl.clone({ + prop: `border-bottom${decl.prop.replace(matchLogicalBorderSide, '$2')}`, + value: values[0] + }), + decl.clone({ + prop: `border-right${decl.prop.replace(matchLogicalBorderSide, '$2')}`, + value: values[1] || values[0] + }) + ]; + + const rtlDecls = [ + decl.clone({ + prop: `border-bottom${decl.prop.replace(matchLogicalBorderSide, '$2')}`, + value: values[0] + }), + decl.clone({ + prop: `border-left${decl.prop.replace(matchLogicalBorderSide, '$2')}`, + value: values[1] || values[0] + }) + ]; + + return 'ltr' === dir ? ltrDecls : 'rtl' === dir ? rtlDecls : [ + cloneRule(decl, 'ltr').append(ltrDecls), + cloneRule(decl, 'rtl').append(rtlDecls) + ]; + } }; diff --git a/dependent-js/transform-float.js b/dependent-js/transform-float.js index eedab0aca1..c8e734a6bd 100644 --- a/dependent-js/transform-float.js +++ b/dependent-js/transform-float.js @@ -1,6 +1,6 @@ -const cloneRule = require('./clone-rule'); +import cloneRule from './clone-rule'; -module.exports = (decl, values, dir) => { +export default (decl, values, dir) => { const lDecl = decl.clone({ value: 'left' }); const rDecl = decl.clone({ value: 'right' }); diff --git a/dependent-js/transform-inset.js b/dependent-js/transform-inset.js index b072ec44ab..5f7251de31 100644 --- a/dependent-js/transform-inset.js +++ b/dependent-js/transform-inset.js @@ -1,6 +1,6 @@ -const cloneRule = require('./clone-rule'); +import cloneRule from './clone-rule'; -module.exports = (decl, values, dir) => { +export default (decl, values, dir) => { if ('logical' !== values[0]) { return [ decl.clone({ prop: 'top', value: values[0] }), diff --git a/dependent-js/transform-resize.js b/dependent-js/transform-resize.js index d48aa04350..6b71037fd2 100644 --- a/dependent-js/transform-resize.js +++ b/dependent-js/transform-resize.js @@ -1,4 +1,4 @@ -module.exports = (decl) => /^block$/i.test(decl.value) +export default decl => /^block$/i.test(decl.value) ? decl.clone({ value: 'vertical' }) : /^inline$/i.test(decl.value) ? decl.clone({ value: 'horizontal' }) diff --git a/dependent-js/transform-side.js b/dependent-js/transform-side.js index 8bde3fa53f..a826e6a00d 100644 --- a/dependent-js/transform-side.js +++ b/dependent-js/transform-side.js @@ -1,99 +1,101 @@ -const cloneDecl = require('./clone-decl'); -const cloneRule = require('./clone-rule'); -const matchSide = require('./match-side'); - -const matchInsetPrefix = require('./match-inset-prefix'); - -// inset-block, margin-block, padding-block -module.exports['block'] = (decl, values) => [ - cloneDecl(decl, '-top', values[0]), - cloneDecl(decl, '-bottom', values[1] || values[0]) -]; - -// inset-block-start, margin-block-start, padding-block-start -module.exports['block-start'] = (decl) => { - decl.prop = decl.prop.replace(matchSide, '$1-top').replace(matchInsetPrefix, ''); -}; - -// inset-block-end, margin-block-end, padding-block-end -module.exports['block-end'] = (decl) => { - decl.prop = decl.prop.replace(matchSide, '$1-bottom').replace(matchInsetPrefix, ''); -}; - -// inset-inline, margin-inline, padding-inline -module.exports['inline'] = (decl, values, dir) => { - const ltrDecls = [ - cloneDecl(decl, '-left', values[0]), - cloneDecl(decl, '-right', values[1] || values[0]) - ]; - - const rtlDecls = [ - cloneDecl(decl, '-right', values[0]), - cloneDecl(decl, '-left', values[1] || values[0]) - ]; - - const isLTR = 1 === values.length || 2 === values.length && values[0] === values[1]; - - return isLTR ? ltrDecls : 'ltr' === dir ? ltrDecls : 'rtl' === dir ? rtlDecls : [ - cloneRule(decl, 'ltr').append(ltrDecls), - cloneRule(decl, 'rtl').append(rtlDecls), - ]; -} +import cloneDecl from './clone-decl'; +import cloneRule from './clone-rule'; +import matchSide from './match-side'; -// inset-inline-start, margin-inline-start, padding-inline-start -module.exports['inline-start'] = (decl, values, dir) => { - const ltrDecl = cloneDecl(decl, '-left', decl.value); - const rtlDecl = cloneDecl(decl, '-right', decl.value); - - return 'ltr' === dir ? ltrDecl : 'rtl' === dir ? rtlDecl : [ - cloneRule(decl, 'ltr').append(ltrDecl), - cloneRule(decl, 'rtl').append(rtlDecl) - ]; -}; - -// inset-inline-end, margin-inline-end, padding-inline-end -module.exports['inline-end'] = (decl, values, dir) => { - const ltrDecl = cloneDecl(decl, '-right', decl.value); - const rtlDecl = cloneDecl(decl, '-left', decl.value); - - return 'ltr' === dir ? ltrDecl : 'rtl' === dir ? rtlDecl : [ - cloneRule(decl, 'ltr').append(ltrDecl), - cloneRule(decl, 'rtl').append(rtlDecl) - ]; -}; - -// inset-start, margin-start, padding-start -module.exports['start'] = (decl, values, dir) => { - const ltrDecls = [ - cloneDecl(decl, '-top', values[0]), - cloneDecl(decl, '-left', values[1] || values[0]) - ]; +import matchInsetPrefix from './match-inset-prefix'; - const rtlDecls = [ +export default { + // inset-block, margin-block, padding-block + 'block': (decl, values) => [ cloneDecl(decl, '-top', values[0]), - cloneDecl(decl, '-right', values[1] || values[0]) - ]; - - return 'ltr' === dir ? ltrDecls : 'rtl' === dir ? rtlDecls : [ - cloneRule(decl, 'ltr').append(ltrDecls), - cloneRule(decl, 'rtl').append(rtlDecls) - ]; -}; - -// inset-end, margin-end, padding-end -module.exports['end'] = (decl, values, dir) => { - const ltrDecls = [ - cloneDecl(decl, '-bottom', values[0]), - cloneDecl(decl, '-right', values[1] || values[0]) - ]; - - const rtlDecls = [ - cloneDecl(decl, '-bottom', values[0]), - cloneDecl(decl, '-left', values[1] || values[0]) - ]; - - return 'ltr' === dir ? ltrDecls : 'rtl' === dir ? rtlDecls : [ - cloneRule(decl, 'ltr').append(ltrDecls), - cloneRule(decl, 'rtl').append(rtlDecls) - ]; -}; + cloneDecl(decl, '-bottom', values[1] || values[0]) + ], + + // inset-block-start, margin-block-start, padding-block-start + 'block-start': decl => { + decl.prop = decl.prop.replace(matchSide, '$1-top').replace(matchInsetPrefix, ''); + }, + + // inset-block-end, margin-block-end, padding-block-end + 'block-end': decl => { + decl.prop = decl.prop.replace(matchSide, '$1-bottom').replace(matchInsetPrefix, ''); + }, + + // inset-inline, margin-inline, padding-inline + 'inline': (decl, values, dir) => { + const ltrDecls = [ + cloneDecl(decl, '-left', values[0]), + cloneDecl(decl, '-right', values[1] || values[0]) + ]; + + const rtlDecls = [ + cloneDecl(decl, '-right', values[0]), + cloneDecl(decl, '-left', values[1] || values[0]) + ]; + + const isLTR = 1 === values.length || 2 === values.length && values[0] === values[1]; + + return isLTR ? ltrDecls : 'ltr' === dir ? ltrDecls : 'rtl' === dir ? rtlDecls : [ + cloneRule(decl, 'ltr').append(ltrDecls), + cloneRule(decl, 'rtl').append(rtlDecls), + ]; + }, + + // inset-inline-start, margin-inline-start, padding-inline-start + 'inline-start': (decl, values, dir) => { + const ltrDecl = cloneDecl(decl, '-left', decl.value); + const rtlDecl = cloneDecl(decl, '-right', decl.value); + + return 'ltr' === dir ? ltrDecl : 'rtl' === dir ? rtlDecl : [ + cloneRule(decl, 'ltr').append(ltrDecl), + cloneRule(decl, 'rtl').append(rtlDecl) + ]; + }, + + // inset-inline-end, margin-inline-end, padding-inline-end + 'inline-end': (decl, values, dir) => { + const ltrDecl = cloneDecl(decl, '-right', decl.value); + const rtlDecl = cloneDecl(decl, '-left', decl.value); + + return 'ltr' === dir ? ltrDecl : 'rtl' === dir ? rtlDecl : [ + cloneRule(decl, 'ltr').append(ltrDecl), + cloneRule(decl, 'rtl').append(rtlDecl) + ]; + }, + + // inset-start, margin-start, padding-start + 'start': (decl, values, dir) => { + const ltrDecls = [ + cloneDecl(decl, '-top', values[0]), + cloneDecl(decl, '-left', values[1] || values[0]) + ]; + + const rtlDecls = [ + cloneDecl(decl, '-top', values[0]), + cloneDecl(decl, '-right', values[1] || values[0]) + ]; + + return 'ltr' === dir ? ltrDecls : 'rtl' === dir ? rtlDecls : [ + cloneRule(decl, 'ltr').append(ltrDecls), + cloneRule(decl, 'rtl').append(rtlDecls) + ]; + }, + + // inset-end, margin-end, padding-end + 'end': (decl, values, dir) => { + const ltrDecls = [ + cloneDecl(decl, '-bottom', values[0]), + cloneDecl(decl, '-right', values[1] || values[0]) + ]; + + const rtlDecls = [ + cloneDecl(decl, '-bottom', values[0]), + cloneDecl(decl, '-left', values[1] || values[0]) + ]; + + return 'ltr' === dir ? ltrDecls : 'rtl' === dir ? rtlDecls : [ + cloneRule(decl, 'ltr').append(ltrDecls), + cloneRule(decl, 'rtl').append(rtlDecls) + ]; + } +} diff --git a/dependent-js/transform-size.js b/dependent-js/transform-size.js index 17c89b39b1..c8f2c42099 100644 --- a/dependent-js/transform-size.js +++ b/dependent-js/transform-size.js @@ -1,6 +1,6 @@ -const matchSize = require('./match-size'); +import matchSize from './match-size'; -module.exports = (decl) => { +export default decl => { decl.prop = decl.prop.replace( matchSize, ($0, minmax, flow) => `${minmax||''}${'block' === flow ? 'height' : 'width'}` diff --git a/dependent-js/transform-spacing.js b/dependent-js/transform-spacing.js index 537afc7e90..8ab2a1e0b1 100644 --- a/dependent-js/transform-spacing.js +++ b/dependent-js/transform-spacing.js @@ -1,6 +1,6 @@ -const cloneRule = require('./clone-rule'); +import cloneRule from './clone-rule'; -module.exports = (decl, values, dir) => { +export default (decl, values, dir) => { if ('logical' !== values[0]) { return null; } diff --git a/dependent-js/transform-text-align.js b/dependent-js/transform-text-align.js index 9b74e03b21..ed09f55c27 100644 --- a/dependent-js/transform-text-align.js +++ b/dependent-js/transform-text-align.js @@ -1,6 +1,6 @@ -const cloneRule = require('./clone-rule'); +import cloneRule from './clone-rule'; -module.exports = (decl, values, dir) => { +export default (decl, values, dir) => { const lDecl = decl.clone({ value: 'left' }); const rDecl = decl.clone({ value: 'right' }); diff --git a/index.js b/index.js index 63dc709d20..f95ccdc904 100644 --- a/index.js +++ b/index.js @@ -1,16 +1,16 @@ // tooling -const postcss = require('postcss'); +import postcss from 'postcss'; // internal tooling -const transformBorder = require('./dependent-js/transform-border'); -const transformFloat = require('./dependent-js/transform-float'); -const transformInset = require('./dependent-js/transform-inset'); -const transformResize = require('./dependent-js/transform-resize'); -const transformSide = require('./dependent-js/transform-side'); -const transformSize = require('./dependent-js/transform-size'); -const transformSpacing = require('./dependent-js/transform-spacing'); -const transformTextAlign = require('./dependent-js/transform-text-align'); -const matchSupportedProperties = require('./dependent-js/match-supported-properties'); +import transformBorder from './dependent-js/transform-border'; +import transformFloat from './dependent-js/transform-float'; +import transformInset from './dependent-js/transform-inset'; +import transformResize from './dependent-js/transform-resize'; +import transformSide from './dependent-js/transform-side'; +import transformSize from './dependent-js/transform-size'; +import transformSpacing from './dependent-js/transform-spacing'; +import transformTextAlign from './dependent-js/transform-text-align'; +import matchSupportedProperties from './dependent-js/match-supported-properties'; // supported transforms const transforms = { @@ -42,19 +42,21 @@ const transforms = { }; // plugin -module.exports = postcss.plugin('postcss-logical-properties', (opts) => (root) => { - const dir = Object(opts) === opts ? /^rtl$/i.test(opts.dir) ? 'rtl' : 'ltr' : false; +export default postcss.plugin('postcss-logical-properties', opts => { + const dir = 'dir' in Object(opts) ? /^rtl$/i.test(Object(opts).dir) ? 'rtl' : 'ltr' : false; - root.walkDecls((decl) => { - const values = postcss.list.split(decl.value, /^border(-block|-inline|-start|-end)?(-width|-style|-color)?$/i.test(decl.prop) ? '/' : ' '); - const prop = decl.prop.replace(matchSupportedProperties, '$2$5').toLowerCase(); + return root => { + root.walkDecls(decl => { + const values = postcss.list.split(decl.value, /^border(-block|-inline|-start|-end)?(-width|-style|-color)?$/i.test(decl.prop) ? '/' : ' '); + const prop = decl.prop.replace(matchSupportedProperties, '$2$5').toLowerCase(); - if (prop in transforms) { - const replacer = transforms[prop](decl, values, dir); + if (prop in transforms) { + const replacer = transforms[prop](decl, values, dir); - if (replacer) { - decl.replaceWith(replacer); + if (replacer) { + decl.replaceWith(replacer); + } } - } - }); + }); + }; }); diff --git a/package.json b/package.json index 3becbfa0f9..3e855031b1 100644 --- a/package.json +++ b/package.json @@ -7,32 +7,41 @@ "repository": "jonathantneal/postcss-logical-properties", "homepage": "https://github.com/jonathantneal/postcss-logical-properties#readme", "bugs": "https://github.com/jonathantneal/postcss-logical-properties/issues", - "main": "index.js", + "main": "index.cjs.js", + "module": "index.es.js", "files": [ - "index.js", - "dependent-js" + "index.cjs.js", + "index.es.js" ], "scripts": { - "clean": "git clean -X -d -f", - "prepublish": "npm test", - "test": "echo 'Running tests...'; npm run test:js && npm run test:tape", - "test:js": "eslint *.js --cache --ignore-pattern .gitignore", + "prepublishOnly": "npm test", + "pretest": "rollup -c .rollup.js --silent", + "test": "echo 'Running tests...'; npm run test:ec && npm run test:js && npm run test:tape", + "test:ec": "echint --ignore index.*.js test", + "test:js": "eslint *.js --cache --ignore-path .gitignore --quiet", "test:tape": "postcss-tape" }, "engines": { "node": ">=4.0.0" }, "dependencies": { - "postcss": "^6.0.11" + "postcss": "^6.0.20" }, "devDependencies": { - "eslint": "^4.6.1", - "eslint-config-dev": "2.0.0", - "postcss-tape": "2.0.1", - "pre-commit": "^1.2.2" + "babel-core": "^6.26.0", + "babel-eslint": "^8.2.2", + "babel-preset-env": "^1.6.1", + "echint": "^4.0.1", + "eslint": "^4.19.0", + "eslint-config-dev": "^2.0.0", + "postcss-tape": "^2.2.0", + "pre-commit": "^1.2.2", + "rollup": "^0.57.1", + "rollup-plugin-babel": "^3.0.3" }, "eslintConfig": { - "extends": "dev" + "extends": "dev", + "parser": "babel-eslint" }, "keywords": [ "postcss", From 0d087f00c9e728a94f5ae46e187b28aea07e714a Mon Sep 17 00:00:00 2001 From: Jonathan Neal Date: Tue, 20 Mar 2018 23:04:43 -0400 Subject: [PATCH 586/795] Update project configuration --- index.js | 20 +++++++++---------- {dependent-js => lib}/clone-decl.js | 0 {dependent-js => lib}/clone-rule.js | 0 {dependent-js => lib}/match-inset-prefix.js | 0 {dependent-js => lib}/match-side.js | 0 {dependent-js => lib}/match-size.js | 0 .../match-supported-properties.js | 0 {dependent-js => lib}/transform-border.js | 0 {dependent-js => lib}/transform-float.js | 0 {dependent-js => lib}/transform-inset.js | 0 {dependent-js => lib}/transform-resize.js | 0 {dependent-js => lib}/transform-side.js | 0 {dependent-js => lib}/transform-size.js | 0 {dependent-js => lib}/transform-spacing.js | 0 {dependent-js => lib}/transform-text-align.js | 0 15 files changed, 10 insertions(+), 10 deletions(-) rename {dependent-js => lib}/clone-decl.js (100%) rename {dependent-js => lib}/clone-rule.js (100%) rename {dependent-js => lib}/match-inset-prefix.js (100%) rename {dependent-js => lib}/match-side.js (100%) rename {dependent-js => lib}/match-size.js (100%) rename {dependent-js => lib}/match-supported-properties.js (100%) rename {dependent-js => lib}/transform-border.js (100%) rename {dependent-js => lib}/transform-float.js (100%) rename {dependent-js => lib}/transform-inset.js (100%) rename {dependent-js => lib}/transform-resize.js (100%) rename {dependent-js => lib}/transform-side.js (100%) rename {dependent-js => lib}/transform-size.js (100%) rename {dependent-js => lib}/transform-spacing.js (100%) rename {dependent-js => lib}/transform-text-align.js (100%) diff --git a/index.js b/index.js index f95ccdc904..67152fa472 100644 --- a/index.js +++ b/index.js @@ -2,15 +2,15 @@ import postcss from 'postcss'; // internal tooling -import transformBorder from './dependent-js/transform-border'; -import transformFloat from './dependent-js/transform-float'; -import transformInset from './dependent-js/transform-inset'; -import transformResize from './dependent-js/transform-resize'; -import transformSide from './dependent-js/transform-side'; -import transformSize from './dependent-js/transform-size'; -import transformSpacing from './dependent-js/transform-spacing'; -import transformTextAlign from './dependent-js/transform-text-align'; -import matchSupportedProperties from './dependent-js/match-supported-properties'; +import transformBorder from './lib/transform-border'; +import transformFloat from './lib/transform-float'; +import transformInset from './lib/transform-inset'; +import transformResize from './lib/transform-resize'; +import transformSide from './lib/transform-side'; +import transformSize from './lib/transform-size'; +import transformSpacing from './lib/transform-spacing'; +import transformTextAlign from './lib/transform-text-align'; +import matchSupportedProperties from './lib/match-supported-properties'; // supported transforms const transforms = { @@ -43,7 +43,7 @@ const transforms = { // plugin export default postcss.plugin('postcss-logical-properties', opts => { - const dir = 'dir' in Object(opts) ? /^rtl$/i.test(Object(opts).dir) ? 'rtl' : 'ltr' : false; + const dir = Object(opts) === opts ? /^rtl$/i.test(opts.dir) ? 'rtl' : 'ltr' : false; return root => { root.walkDecls(decl => { diff --git a/dependent-js/clone-decl.js b/lib/clone-decl.js similarity index 100% rename from dependent-js/clone-decl.js rename to lib/clone-decl.js diff --git a/dependent-js/clone-rule.js b/lib/clone-rule.js similarity index 100% rename from dependent-js/clone-rule.js rename to lib/clone-rule.js diff --git a/dependent-js/match-inset-prefix.js b/lib/match-inset-prefix.js similarity index 100% rename from dependent-js/match-inset-prefix.js rename to lib/match-inset-prefix.js diff --git a/dependent-js/match-side.js b/lib/match-side.js similarity index 100% rename from dependent-js/match-side.js rename to lib/match-side.js diff --git a/dependent-js/match-size.js b/lib/match-size.js similarity index 100% rename from dependent-js/match-size.js rename to lib/match-size.js diff --git a/dependent-js/match-supported-properties.js b/lib/match-supported-properties.js similarity index 100% rename from dependent-js/match-supported-properties.js rename to lib/match-supported-properties.js diff --git a/dependent-js/transform-border.js b/lib/transform-border.js similarity index 100% rename from dependent-js/transform-border.js rename to lib/transform-border.js diff --git a/dependent-js/transform-float.js b/lib/transform-float.js similarity index 100% rename from dependent-js/transform-float.js rename to lib/transform-float.js diff --git a/dependent-js/transform-inset.js b/lib/transform-inset.js similarity index 100% rename from dependent-js/transform-inset.js rename to lib/transform-inset.js diff --git a/dependent-js/transform-resize.js b/lib/transform-resize.js similarity index 100% rename from dependent-js/transform-resize.js rename to lib/transform-resize.js diff --git a/dependent-js/transform-side.js b/lib/transform-side.js similarity index 100% rename from dependent-js/transform-side.js rename to lib/transform-side.js diff --git a/dependent-js/transform-size.js b/lib/transform-size.js similarity index 100% rename from dependent-js/transform-size.js rename to lib/transform-size.js diff --git a/dependent-js/transform-spacing.js b/lib/transform-spacing.js similarity index 100% rename from dependent-js/transform-spacing.js rename to lib/transform-spacing.js diff --git a/dependent-js/transform-text-align.js b/lib/transform-text-align.js similarity index 100% rename from dependent-js/transform-text-align.js rename to lib/transform-text-align.js From 109119a679b0706914b22a7dcc9a4e2339253e52 Mon Sep 17 00:00:00 2001 From: Jonathan Neal Date: Tue, 20 Mar 2018 23:04:52 -0400 Subject: [PATCH 587/795] Update LICENSE spacing --- LICENSE.md | 140 +++++++++++++++++++++++++++-------------------------- 1 file changed, 71 insertions(+), 69 deletions(-) diff --git a/LICENSE.md b/LICENSE.md index b5bc55c9f6..0bc1fa7060 100644 --- a/LICENSE.md +++ b/LICENSE.md @@ -27,80 +27,82 @@ Copyright and Related Rights in the Work and the meaning and intended legal effect of CC0 on those rights. 1. Copyright and Related Rights. A Work made available under CC0 may be - protected by copyright and related or neighboring rights (“Copyright and - Related Rights”). Copyright and Related Rights include, but are not limited - to, the following: - 1. the right to reproduce, adapt, distribute, perform, display, - communicate, and translate a Work; - 2. moral rights retained by the original author(s) and/or performer(s); - 3. publicity and privacy rights pertaining to a person’s image or likeness - depicted in a Work; - 4. rights protecting against unfair competition in regards to a Work, - subject to the limitations in paragraph 4(i), below; - 5. rights protecting the extraction, dissemination, use and reuse of data - in a Work; - 6. database rights (such as those arising under Directive 96/9/EC of the - European Parliament and of the Council of 11 March 1996 on the legal - protection of databases, and under any national implementation thereof, - including any amended or successor version of such directive); and - 7. other similar, equivalent or corresponding rights throughout the world - based on applicable law or treaty, and any national implementations - thereof. + protected by copyright and related or neighboring rights (“Copyright and + Related Rights”). Copyright and Related Rights include, but are not limited + to, the following: + 1. the right to reproduce, adapt, distribute, perform, display, communicate, + and translate a Work; + 2. moral rights retained by the original author(s) and/or performer(s); + 3. publicity and privacy rights pertaining to a person’s image or likeness + depicted in a Work; + 4. rights protecting against unfair competition in regards to a Work, + subject to the limitations in paragraph 4(i), below; + 5. rights protecting the extraction, dissemination, use and reuse of data in + a Work; + 6. database rights (such as those arising under Directive 96/9/EC of the + European Parliament and of the Council of 11 March 1996 on the legal + protection of databases, and under any national implementation thereof, + including any amended or successor version of such directive); and + 7. other similar, equivalent or corresponding rights throughout the world + based on applicable law or treaty, and any national implementations + thereof. 2. Waiver. To the greatest extent permitted by, but not in contravention of, -applicable law, Affirmer hereby overtly, fully, permanently, irrevocably and -unconditionally waives, abandons, and surrenders all of Affirmer’s Copyright -and Related Rights and associated claims and causes of action, whether now -known or unknown (including existing as well as future claims and causes of -action), in the Work (i) in all territories worldwide, (ii) for the maximum -duration provided by applicable law or treaty (including future time -extensions), (iii) in any current or future medium and for any number of -copies, and (iv) for any purpose whatsoever, including without limitation -commercial, advertising or promotional purposes (the “Waiver”). Affirmer makes -the Waiver for the benefit of each member of the public at large and to the -detriment of Affirmer’s heirs and successors, fully intending that such Waiver -shall not be subject to revocation, rescission, cancellation, termination, or -any other legal or equitable action to disrupt the quiet enjoyment of the Work -by the public as contemplated by Affirmer’s express Statement of Purpose. + applicable law, Affirmer hereby overtly, fully, permanently, irrevocably and + unconditionally waives, abandons, and surrenders all of Affirmer’s Copyright + and Related Rights and associated claims and causes of action, whether now + known or unknown (including existing as well as future claims and causes of + action), in the Work (i) in all territories worldwide, (ii) for the maximum + duration provided by applicable law or treaty (including future time + extensions), (iii) in any current or future medium and for any number of + copies, and (iv) for any purpose whatsoever, including without limitation + commercial, advertising or promotional purposes (the “Waiver”). Affirmer + makes the Waiver for the benefit of each member of the public at large and + to the detriment of Affirmer’s heirs and successors, fully intending that + such Waiver shall not be subject to revocation, rescission, cancellation, + termination, or any other legal or equitable action to disrupt the quiet + enjoyment of the Work by the public as contemplated by Affirmer’s express + Statement of Purpose. 3. Public License Fallback. Should any part of the Waiver for any reason be -judged legally invalid or ineffective under applicable law, then the Waiver -shall be preserved to the maximum extent permitted taking into account -Affirmer’s express Statement of Purpose. In addition, to the extent the Waiver -is so judged Affirmer hereby grants to each affected person a royalty-free, non -transferable, non sublicensable, non exclusive, irrevocable and unconditional -license to exercise Affirmer’s Copyright and Related Rights in the Work (i) in -all territories worldwide, (ii) for the maximum duration provided by applicable -law or treaty (including future time extensions), (iii) in any current or -future medium and for any number of copies, and (iv) for any purpose -whatsoever, including without limitation commercial, advertising or promotional -purposes (the “License”). The License shall be deemed effective as of the date -CC0 was applied by Affirmer to the Work. Should any part of the License for any -reason be judged legally invalid or ineffective under applicable law, such -partial invalidity or ineffectiveness shall not invalidate the remainder of the -License, and in such case Affirmer hereby affirms that he or she will not (i) -exercise any of his or her remaining Copyright and Related Rights in the Work -or (ii) assert any associated claims and causes of action with respect to the -Work, in either case contrary to Affirmer’s express Statement of Purpose. + judged legally invalid or ineffective under applicable law, then the Waiver + shall be preserved to the maximum extent permitted taking into account + Affirmer’s express Statement of Purpose. In addition, to the extent the + Waiver is so judged Affirmer hereby grants to each affected person a + royalty-free, non transferable, non sublicensable, non exclusive, + irrevocable and unconditional license to exercise Affirmer’s Copyright and + Related Rights in the Work (i) in all territories worldwide, (ii) for the + maximum duration provided by applicable law or treaty (including future time + extensions), (iii) in any current or future medium and for any number of + copies, and (iv) for any purpose whatsoever, including without limitation + commercial, advertising or promotional purposes (the “License”). The License + shall be deemed effective as of the date CC0 was applied by Affirmer to the + Work. Should any part of the License for any reason be judged legally + invalid or ineffective under applicable law, such partial invalidity or + ineffectiveness shall not invalidate the remainder of the License, and in + such case Affirmer hereby affirms that he or she will not (i) exercise any + of his or her remaining Copyright and Related Rights in the Work or (ii) + assert any associated claims and causes of action with respect to the Work, + in either case contrary to Affirmer’s express Statement of Purpose. 4. Limitations and Disclaimers. - 1. No trademark or patent rights held by Affirmer are waived, abandoned, - surrendered, licensed or otherwise affected by this document. - 2. Affirmer offers the Work as-is and makes no representations or - warranties of any kind concerning the Work, express, implied, statutory - or otherwise, including without limitation warranties of title, - merchantability, fitness for a particular purpose, non infringement, or - the absence of latent or other defects, accuracy, or the present or - absence of errors, whether or not discoverable, all to the greatest - extent permissible under applicable law. - 3. Affirmer disclaims responsibility for clearing rights of other persons - that may apply to the Work or any use thereof, including without - limitation any person’s Copyright and Related Rights in the Work. - Further, Affirmer disclaims responsibility for obtaining any necessary - consents, permissions or other rights required for any use of the Work. - 4. Affirmer understands and acknowledges that Creative Commons is not a - party to this document and has no duty or obligation with respect to - this CC0 or use of the Work. + 1. No trademark or patent rights held by Affirmer are waived, abandoned, + surrendered, licensed or otherwise affected by this document. + 2. Affirmer offers the Work as-is and makes no representations or warranties + of any kind concerning the Work, express, implied, statutory or + otherwise, including without limitation warranties of title, + merchantability, fitness for a particular purpose, non infringement, or + the absence of latent or other defects, accuracy, or the present or + absence of errors, whether or not discoverable, all to the greatest + extent permissible under applicable law. + 3. Affirmer disclaims responsibility for clearing rights of other persons + that may apply to the Work or any use thereof, including without + limitation any person’s Copyright and Related Rights in the Work. + Further, Affirmer disclaims responsibility for obtaining any necessary + consents, permissions or other rights required for any use of the Work. + 4. Affirmer understands and acknowledges that Creative Commons is not a + party to this document and has no duty or obligation with respect to this + CC0 or use of the Work. For more information, please see -https://creativecommons.org/publicdomain/zero/1.0/. +http://creativecommons.org/publicdomain/zero/1.0/. From 68522071d28b7f3b2bf050fdc53e22bb700047ff Mon Sep 17 00:00:00 2001 From: Jonathan Neal Date: Tue, 20 Mar 2018 23:43:51 -0400 Subject: [PATCH 588/795] Add preserve option --- index.js | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/index.js b/index.js index 67152fa472..6185c96260 100644 --- a/index.js +++ b/index.js @@ -43,7 +43,12 @@ const transforms = { // plugin export default postcss.plugin('postcss-logical-properties', opts => { - const dir = Object(opts) === opts ? /^rtl$/i.test(opts.dir) ? 'rtl' : 'ltr' : false; + const preserve = Boolean(Object(opts).preserve); + const dir = !preserve && 'dir' in Object(opts) + ? /^rtl$/i.test(Object(opts).dir) + ? 'rtl' + : 'ltr' + : false; return root => { root.walkDecls(decl => { @@ -54,7 +59,11 @@ export default postcss.plugin('postcss-logical-properties', opts => { const replacer = transforms[prop](decl, values, dir); if (replacer) { - decl.replaceWith(replacer); + if (preserve) { + decl.before(replacer); + } else { + decl.replaceWith(replacer); + } } } }); From 41366b2d1414c32d3a226dd77d9d4c96e9531571 Mon Sep 17 00:00:00 2001 From: Jonathan Neal Date: Tue, 20 Mar 2018 23:44:03 -0400 Subject: [PATCH 589/795] Update tests --- .tape.js | 6 + test/border.preserve.expect.css | 201 ++++++++++++++++++++++++++++++++ 2 files changed, 207 insertions(+) create mode 100644 test/border.preserve.expect.css diff --git a/.tape.js b/.tape.js index 35915214be..05757bcb53 100644 --- a/.tape.js +++ b/.tape.js @@ -9,6 +9,12 @@ module.exports = { dir: 'ltr' } }, + 'border:preserve': { + message: 'supports logical "border" property values with { preserve: true }', + options: { + preserve: true + } + }, 'clear': { message: 'supports logical "clear" property values' }, diff --git a/test/border.preserve.expect.css b/test/border.preserve.expect.css new file mode 100644 index 0000000000..dffc85d7de --- /dev/null +++ b/test/border.preserve.expect.css @@ -0,0 +1,201 @@ +test-border { + border: 1px solid black; + border: logical 1px solid black; + border-top: 2px solid black; + border-right: 3px solid black; + border-bottom: 2px solid black; + border-left: 3px solid black; + border: logical 2px solid black / 3px solid black; + border-top: 4px solid black; + border-right: 5px solid black; + border-bottom: 6px solid black; + border-left: 5px solid black; + border: logical 4px solid black / 5px solid black / 6px solid black; + border-top: 7px solid black; + border-right: 8px solid black; + border-bottom: 9px solid black; + border-left: 8px solid black; + border: logical 7px solid black / 8px solid black / 9px solid black / 8px solid black; + border-left: 10px solid black; + border-right: 10px solid black; + border-inline: 10px solid black; + border-left: 11px solid black; + border-right: 11px solid black; + border-inline: 11px solid black / 11px solid black; + border-top: 12px solid black; + border-bottom: 12px solid black; + border-block: 12px solid black; + border-top: 13px solid black; + border-bottom: 13px solid black; + border-block: 13px solid black / 14px solid black; + border-top: 15px solid black; + border-bottom: 16px solid black; +} + +test-flowing-border { + border: inherit; + &:dir(ltr) { + border-top: 1px solid black; + border-left: 2px solid black; + border-bottom: 3px solid black; + border-right: 4px solid black; + } + &:dir(rtl) { + border-top: 1px solid black; + border-right: 2px solid black; + border-bottom: 3px solid black; + border-left: 4px solid black; + } + border: logical 1px solid black / 2px solid black / 3px solid black / 4px solid black; + border: inherit; + &:dir(ltr) { + border-left: 5px solid black; + border-right: 6px solid black; + } + &:dir(rtl) { + border-right: 5px solid black; + border-left: 6px solid black; + } + border-inline: 5px solid black / 6px solid black; + border: inherit; + &:dir(ltr) { + border-left: 7px solid black; + } + &:dir(rtl) { + border-right: 7px solid black; + } + border-inline-start: 7px solid black; + border: inherit; + &:dir(ltr) { + border-right: 8px solid black; + } + &:dir(rtl) { + border-left: 8px solid black; + } + border-inline-end: 8px solid black; + border: inherit; + &:dir(ltr) { + border-top: 9px solid black; + border-left: 9px solid black; + } + &:dir(rtl) { + border-top: 9px solid black; + border-right: 9px solid black; + } + border-start: 9px solid black; + border: inherit; + &:dir(ltr) { + border-top: 10px solid black; + border-left: 11px solid black; + } + &:dir(rtl) { + border-top: 10px solid black; + border-right: 11px solid black; + } + border-start: 10px solid black / 11px solid black; + border: inherit; + &:dir(ltr) { + border-bottom: 12px solid black; + border-right: 12px solid black; + } + &:dir(rtl) { + border-bottom: 12px solid black; + border-left: 12px solid black; + } + border-end: 12px solid black; + border: inherit; + &:dir(ltr) { + border-bottom: 13px solid black; + border-right: 14px solid black; + } + &:dir(rtl) { + border-bottom: 13px solid black; + border-left: 14px solid black; + } + border-end: 13px solid black / 14px solid black; + border: inherit; +} + +test-flowing-border-color { + border-color: inherit; + &:dir(ltr) { + border-top-color: 1px solid black; + border-left-color: 2px solid black; + border-bottom-color: 3px solid black; + border-right-color: 4px solid black; + } + &:dir(rtl) { + border-top-color: 1px solid black; + border-right-color: 2px solid black; + border-bottom-color: 3px solid black; + border-left-color: 4px solid black; + } + border-color: logical 1px solid black / 2px solid black / 3px solid black / 4px solid black; + border-color: inherit; + &:dir(ltr) { + border-left-color: 5px solid black; + border-right-color: 6px solid black; + } + &:dir(rtl) { + border-right-color: 5px solid black; + border-left-color: 6px solid black; + } + border-inline-color: 5px solid black / 6px solid black; + border-color: inherit; + &:dir(ltr) { + border-left-color: 7px solid black; + } + &:dir(rtl) { + border-right-color: 7px solid black; + } + border-inline-start-color: 7px solid black; + border-color: inherit; + &:dir(ltr) { + border-right-color: 8px solid black; + } + &:dir(rtl) { + border-left-color: 8px solid black; + } + border-inline-end-color: 8px solid black; + border-color: inherit; + &:dir(ltr) { + border-top-color: 9px solid black; + border-left-color: 9px solid black; + } + &:dir(rtl) { + border-top-color: 9px solid black; + border-right-color: 9px solid black; + } + border-start-color: 9px solid black; + border-color: inherit; + &:dir(ltr) { + border-top-color: 10px solid black; + border-left-color: 11px solid black; + } + &:dir(rtl) { + border-top-color: 10px solid black; + border-right-color: 11px solid black; + } + border-start-color: 10px solid black / 11px solid black; + border-color: inherit; + &:dir(ltr) { + border-bottom-color: 12px solid black; + border-right-color: 12px solid black; + } + &:dir(rtl) { + border-bottom-color: 12px solid black; + border-left-color: 12px solid black; + } + border-end-color: 12px solid black; + border-color: inherit; + &:dir(ltr) { + border-bottom-color: 13px solid black; + border-right-color: 14px solid black; + } + &:dir(rtl) { + border-bottom-color: 13px solid black; + border-left-color: 14px solid black; + } + border-end-color: 13px solid black / 14px solid black; + border-color: inherit; +} From 498b63ab1ecd5e433911b7f4d69935d4ae582e1f Mon Sep 17 00:00:00 2001 From: Jonathan Neal Date: Tue, 20 Mar 2018 23:44:10 -0400 Subject: [PATCH 590/795] Update documentation --- README.md | 92 +++++++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 82 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index 0636163572..11ead509bd 100644 --- a/README.md +++ b/README.md @@ -9,40 +9,62 @@ [PostCSS Logical Properties] lets you use Logical Properties and Values in CSS, following the [CSS Logical Properties and Values] specification. -```css +```pcss .banner { color: #222222; inset: logical 0 5px 10px; padding-inline: 20px 40px; resize: block; + transition: color 200ms; } -/* used alongside postcss-nesting, postcss-dir-pseudo-class */ +/* becomes */ .banner { color: #222222; top: 0; left: 5px; bottom: 10px; right: 5px; -} -[dir="ltr"] .banner { - padding-left: 20px; padding-right: 40px; -} + &:dir(ltr) { + padding-left: 20px; padding-right: 40px; + } + + &:dir(rtl) { + padding-right: 20px; padding-left: 40px; + } -[dir="rtl"] .banner { - padding-right: 20px; padding-left: 40px; + resize: vertical; + transition: color 200ms; } +/* or, when used with { dir: 'ltr' } */ + .banner { + color: #222222; + top: 0; left: 5px; bottom: 10px; right: 5px; + padding-left: 20px; padding-right: 40px; resize: vertical; + transition: color 200ms; } -/* used with { dir: 'ltr' } option */ +/* or, when used with { preserve: true } */ .banner { color: #222222; top: 0; left: 5px; bottom: 10px; right: 5px; - padding-left: 20px; padding-right: 40px; + + &:dir(ltr) { + padding-left: 20px; padding-right: 40px; + } + + &:dir(rtl) { + padding-right: 20px; padding-left: 40px; + } + + inset: logical 0 5px 10px; + padding-inline: 20px 40px; + resize: block; resize: vertical; + transition: color 200ms; } ``` @@ -146,6 +168,38 @@ postcss([ ]).process(YOUR_CSS); ``` +#### Webpack + +Add [PostCSS Loader] to your build tool: + +```bash +npm install postcss-loader --save-dev +``` + +Use [PostCSS Logical Properties] in your Webpack.config.js: + +```js +import ${idCamelCase} from '${id}'; + +module.exports = { + module: { + rules: [ + { + test: /\.css$/, + use: [ + 'style-loader', + { loader: 'css-loader', options: { importLoaders: 1 } }, + { loader: 'postcss-loader', options: { + ident: 'postcss', + plugins: () => [ ${idCamelCase}() ] + } } + ] + } + ] + } +} +``` + #### Gulp Add [Gulp PostCSS] to your build tool: @@ -197,6 +251,23 @@ grunt.initConfig({ }); ``` +## Options + +### dir + +The `dir` option determines how directional fallbacks should be added to CSS. +By default, fallbacks replace the logical declaration with nested `:dir` +pseudo-classes. If `dir` is defined as `ltr` or `rtl` then only the left or +right directional fallbacks will replace the logical declarations. If +`preserve` is defined as `true`, then the `dir` option will be ignored. + +### preserve + +The `preserve` option determines whether directional fallbacks should be added +before logical declarations without replacing them. By default, directional +fallbacks replace logical declaration. If `preserve` is defined as `true`, then +the `dir` option will be ignored. + [cli-url]: https://travis-ci.org/jonathantneal/postcss-logical-properties [cli-img]: https://img.shields.io/travis/jonathantneal/postcss-logical-properties.svg [css-img]: https://jonathantneal.github.io/css-db/badge/css-logical.svg @@ -212,4 +283,5 @@ grunt.initConfig({ [Gulp PostCSS]: https://github.com/postcss/gulp-postcss [Grunt PostCSS]: https://github.com/nDmitry/grunt-postcss [PostCSS]: https://github.com/postcss/postcss +[PostCSS Loader]: https://github.com/postcss/postcss-loader [PostCSS Logical Properties]: https://github.com/jonathantneal/postcss-logical-properties From 82d8bc9d158f94947b4ea469f873659f6175ae25 Mon Sep 17 00:00:00 2001 From: Jonathan Neal Date: Tue, 20 Mar 2018 23:44:41 -0400 Subject: [PATCH 591/795] 1.1.0 --- CHANGELOG.md | 6 ++++-- package.json | 2 +- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4552293858..3865802432 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,14 +1,16 @@ # Changes to PostCSS Logical Properties +### 1.1.0 (March 20, 2017) + +- Add `preserve` option to preserve logical properties and values + ### 1.0.2 (Aug 15, 2017) - Improve flow-relative clear support -- Update dependencies ### 1.0.1 (Aug 13, 2017) - Improve flow-relative border support -- Update dependencies ### 1.0.0 (Aug 8, 2017) diff --git a/package.json b/package.json index 3e855031b1..40aa9a8a1d 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "postcss-logical", - "version": "1.0.2", + "version": "1.1.0", "description": "Use logical properties and values in CSS", "author": "Jonathan Neal ", "license": "CC0-1.0", From 366ac2060565522a0ec3664865055b99992865cd Mon Sep 17 00:00:00 2001 From: Jonathan Neal Date: Wed, 21 Mar 2018 00:38:05 -0400 Subject: [PATCH 592/795] Update README.md --- README.md | 76 ++++++++++++++++++++++++++++++------------------------- 1 file changed, 42 insertions(+), 34 deletions(-) diff --git a/README.md b/README.md index 11ead509bd..faac0db42d 100644 --- a/README.md +++ b/README.md @@ -1,13 +1,14 @@ -# PostCSS Logical Properties [PostCSS Logo][postcss] +# PostCSS Logical Properties and Values [PostCSS Logo][postcss] [![CSS Standard Status][css-img]][css-url] [![NPM Version][npm-img]][npm-url] [![Build Status][cli-img]][cli-url] -[![Licensing][lic-img]][lic-url] +[![Windows Build Status][win-img]][win-url] [![Gitter Chat][git-img]][git-url] -[PostCSS Logical Properties] lets you use Logical Properties and Values in -CSS, following the [CSS Logical Properties and Values] specification. +[PostCSS Logical Properties and Values] lets you use logical, rather than +physical, direction and dimension mappings in CSS, following the +[CSS Logical Properties and Values] specification. ```pcss .banner { @@ -117,10 +118,9 @@ properties: --- -By default, [PostCSS Logical Properties] changes the selector weight of -flow-relative declarations and requires at least one [dir] attribute in your -HTML. If you don’t have any [dir] attributes, consider using the following -JavaScript: +By default, [PostCSS Logical Properties and Values] creates fallback selectors +which require at least one `[dir]` attribute in your HTML. If you don’t have +any `[dir]` attributes, consider using the following JavaScript: ```js // force at least one dir attribute (this can run at any time) @@ -138,7 +138,7 @@ require('postcss-logical')({ ## Usage -Add [PostCSS Logical Properties] to your build tool: +Add [PostCSS Logical Properties and Values] to your build tool: ```bash npm install postcss-logical --save-dev @@ -146,10 +146,12 @@ npm install postcss-logical --save-dev #### Node -Use [PostCSS Logical Properties] to process your CSS: +Use [PostCSS Logical Properties and Values] to process your CSS: ```js -require('postcss-logical').process(YOUR_CSS); +import postcssLogical from 'postcss-logical'; + +postcssLogical.process(YOUR_CSS); ``` #### PostCSS @@ -160,11 +162,14 @@ Add [PostCSS] to your build tool: npm install postcss --save-dev ``` -Use [PostCSS Logical Properties] as a plugin: +Use [PostCSS Logical Properties and Values] as a plugin: ```js +import postcss from 'gulp-postcss'; +import postcssLogical from 'postcss-logical'; + postcss([ - require('postcss-logical')(/* options */) + postcssLogical(/* options */) ]).process(YOUR_CSS); ``` @@ -176,12 +181,12 @@ Add [PostCSS Loader] to your build tool: npm install postcss-loader --save-dev ``` -Use [PostCSS Logical Properties] in your Webpack.config.js: +Use [PostCSS Logical Properties and Values] in your Webpack configuration: ```js -import ${idCamelCase} from '${id}'; +import postcssLogical from 'postcss-logical'; -module.exports = { +export default { module: { rules: [ { @@ -191,7 +196,9 @@ module.exports = { { loader: 'css-loader', options: { importLoaders: 1 } }, { loader: 'postcss-loader', options: { ident: 'postcss', - plugins: () => [ ${idCamelCase}() ] + plugins: () => [ + postcssLogical(/* options */) + ] } } ] } @@ -208,20 +215,19 @@ Add [Gulp PostCSS] to your build tool: npm install gulp-postcss --save-dev ``` -Use [PostCSS Logical Properties] in your Gulpfile: +Use [PostCSS Logical Properties and Values] in your Gulpfile: ```js -var postcss = require('gulp-postcss'); - -gulp.task('css', function () { - return gulp.src('./src/*.css').pipe( - postcss([ - require('postcss-logical')(/* options */) - ]) - ).pipe( - gulp.dest('.') - ); -}); +import postcss from 'gulp-postcss'; +import postcssLogical from 'postcss-logical'; + +gulp.task('css', () => gulp.src('./src/*.css').pipe( + postcss([ + postcssLogical(/* options */) + ]) +).pipe( + gulp.dest('.') +)); ``` #### Grunt @@ -232,16 +238,18 @@ Add [Grunt PostCSS] to your build tool: npm install grunt-postcss --save-dev ``` -Use [PostCSS Logical Properties] in your Gruntfile: +Use [PostCSS Logical Properties and Values] in your Gruntfile: ```js +import postcssLogical from 'postcss-logical'; + grunt.loadNpmTasks('grunt-postcss'); grunt.initConfig({ postcss: { options: { use: [ - require('postcss-logical')(/* options */) + postcssLogical(/* options */) ] }, dist: { @@ -274,14 +282,14 @@ the `dir` option will be ignored. [css-url]: https://jonathantneal.github.io/css-db/#css-logical [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-logical.svg [npm-url]: https://www.npmjs.com/package/postcss-logical [npm-img]: https://img.shields.io/npm/v/postcss-logical.svg +[win-url]: https://ci.appveyor.com/project/jonathantneal/postcss-logical-properties +[win-img]: https://img.shields.io/appveyor/ci/jonathantneal/postcss-logical-properties.svg [CSS Logical Properties and Values]: https://drafts.csswg.org/css-logical/ [Gulp PostCSS]: https://github.com/postcss/gulp-postcss [Grunt PostCSS]: https://github.com/nDmitry/grunt-postcss [PostCSS]: https://github.com/postcss/postcss [PostCSS Loader]: https://github.com/postcss/postcss-loader -[PostCSS Logical Properties]: https://github.com/jonathantneal/postcss-logical-properties +[PostCSS Logical Properties and Values]: https://github.com/jonathantneal/postcss-logical-properties From 5b49b7cc618c0b6e0724c626a25125e3c7c39a96 Mon Sep 17 00:00:00 2001 From: Jonathan Neal Date: Wed, 21 Mar 2018 00:42:54 -0400 Subject: [PATCH 593/795] Use consistent postcss-logical URL --- README.md | 10 +++++----- package.json | 6 +++--- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index faac0db42d..58fc9c6795 100644 --- a/README.md +++ b/README.md @@ -276,20 +276,20 @@ before logical declarations without replacing them. By default, directional fallbacks replace logical declaration. If `preserve` is defined as `true`, then the `dir` option will be ignored. -[cli-url]: https://travis-ci.org/jonathantneal/postcss-logical-properties -[cli-img]: https://img.shields.io/travis/jonathantneal/postcss-logical-properties.svg +[cli-url]: https://travis-ci.org/jonathantneal/postcss-logical +[cli-img]: https://img.shields.io/travis/jonathantneal/postcss-logical.svg [css-img]: https://jonathantneal.github.io/css-db/badge/css-logical.svg [css-url]: https://jonathantneal.github.io/css-db/#css-logical [git-url]: https://gitter.im/postcss/postcss [git-img]: https://img.shields.io/badge/chat-gitter-blue.svg [npm-url]: https://www.npmjs.com/package/postcss-logical [npm-img]: https://img.shields.io/npm/v/postcss-logical.svg -[win-url]: https://ci.appveyor.com/project/jonathantneal/postcss-logical-properties -[win-img]: https://img.shields.io/appveyor/ci/jonathantneal/postcss-logical-properties.svg +[win-url]: https://ci.appveyor.com/project/jonathantneal/postcss-logical +[win-img]: https://img.shields.io/appveyor/ci/jonathantneal/postcss-logical.svg [CSS Logical Properties and Values]: https://drafts.csswg.org/css-logical/ [Gulp PostCSS]: https://github.com/postcss/gulp-postcss [Grunt PostCSS]: https://github.com/nDmitry/grunt-postcss [PostCSS]: https://github.com/postcss/postcss [PostCSS Loader]: https://github.com/postcss/postcss-loader -[PostCSS Logical Properties and Values]: https://github.com/jonathantneal/postcss-logical-properties +[PostCSS Logical Properties and Values]: https://github.com/jonathantneal/postcss-logical diff --git a/package.json b/package.json index 40aa9a8a1d..1b0978f649 100644 --- a/package.json +++ b/package.json @@ -4,9 +4,9 @@ "description": "Use logical properties and values in CSS", "author": "Jonathan Neal ", "license": "CC0-1.0", - "repository": "jonathantneal/postcss-logical-properties", - "homepage": "https://github.com/jonathantneal/postcss-logical-properties#readme", - "bugs": "https://github.com/jonathantneal/postcss-logical-properties/issues", + "repository": "jonathantneal/postcss-logical", + "homepage": "https://github.com/jonathantneal/postcss-logical#readme", + "bugs": "https://github.com/jonathantneal/postcss-logical/issues", "main": "index.cjs.js", "module": "index.es.js", "files": [ From 6c37dc9e51e1355678ad657e05ba143d5b500eaf Mon Sep 17 00:00:00 2001 From: Jonathan Neal Date: Wed, 21 Mar 2018 01:35:31 -0400 Subject: [PATCH 594/795] Fix dir option --- index.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/index.js b/index.js index 6185c96260..8362d3b61f 100644 --- a/index.js +++ b/index.js @@ -44,8 +44,8 @@ const transforms = { // plugin export default postcss.plugin('postcss-logical-properties', opts => { const preserve = Boolean(Object(opts).preserve); - const dir = !preserve && 'dir' in Object(opts) - ? /^rtl$/i.test(Object(opts).dir) + const dir = !preserve && typeof Object(opts).dir === 'string' + ? /^rtl$/i.test(opts.dir) ? 'rtl' : 'ltr' : false; From ba0dd1ca31d4066265770d0fd279f5e55ec37744 Mon Sep 17 00:00:00 2001 From: Jonathan Neal Date: Wed, 21 Mar 2018 01:35:36 -0400 Subject: [PATCH 595/795] 1.1.1 --- CHANGELOG.md | 4 ++++ package.json | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3865802432..c8e30c2520 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # Changes to PostCSS Logical Properties +### 1.1.1 (March 21, 2017) + +- Fix `dir` option to allow falsey value + ### 1.1.0 (March 20, 2017) - Add `preserve` option to preserve logical properties and values diff --git a/package.json b/package.json index 1b0978f649..a8225c88e6 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "postcss-logical", - "version": "1.1.0", + "version": "1.1.1", "description": "Use logical properties and values in CSS", "author": "Jonathan Neal ", "license": "CC0-1.0", From ba81d33008f6601bf199d682754080efcbf9fb39 Mon Sep 17 00:00:00 2001 From: Jonathan Neal Date: Wed, 21 Mar 2018 02:31:07 -0400 Subject: [PATCH 596/795] 3.0.0 --- .appveyor.yml | 18 ++++ .gitignore | 6 +- .rollup.js | 16 +++ .tape.js | 15 +-- CHANGELOG.md | 9 +- CONTRIBUTING.md | 2 +- LICENSE.md | 140 ++++++++++++------------- README.md | 165 +++++++++++++++--------------- index.js | 175 +++++++++++++++----------------- package.json | 47 ++++++--- test/basic.preserve.expect.css | 143 ++++++++++++++++++++++++++ test/basic.supported.expect.css | 71 ------------- 12 files changed, 463 insertions(+), 344 deletions(-) create mode 100644 .appveyor.yml create mode 100644 .rollup.js create mode 100644 test/basic.preserve.expect.css delete mode 100644 test/basic.supported.expect.css diff --git a/.appveyor.yml b/.appveyor.yml new file mode 100644 index 0000000000..acbf8a5eeb --- /dev/null +++ b/.appveyor.yml @@ -0,0 +1,18 @@ +# https://www.appveyor.com/docs/appveyor-yml + +environment: + matrix: + - nodejs_version: 4 + +version: "{build}" +build: off +deploy: off + +install: + - ps: Install-Product node $env:nodejs_version + - npm install --ignore-scripts + +test_script: + - node --version + - npm --version + - cmd: "npm test" diff --git a/.gitignore b/.gitignore index 995098afd2..de73e5a338 100644 --- a/.gitignore +++ b/.gitignore @@ -1,10 +1,12 @@ node_modules +index.*.js package-lock.json +*.log* +*.result.css .* !.appveyor.yml !.editorconfig !.gitignore +!.rollup.js !.tape.js !.travis.yml -*.log* -*.result.css diff --git a/.rollup.js b/.rollup.js new file mode 100644 index 0000000000..0436758216 --- /dev/null +++ b/.rollup.js @@ -0,0 +1,16 @@ +import babel from 'rollup-plugin-babel'; + +export default { + input: 'index.js', + output: [ + { file: 'index.cjs.js', format: 'cjs' }, + { file: 'index.es.js', format: 'es' } + ], + plugins: [ + babel({ + presets: [ + ['env', { modules: false, targets: { node: 4 } }] + ] + }) + ] +}; diff --git a/.tape.js b/.tape.js index 6570b96b63..a86a6be091 100644 --- a/.tape.js +++ b/.tape.js @@ -10,20 +10,11 @@ module.exports = { dir: 'ltr' } }, - 'basic:browsers': { - message: 'supports { browsers: "last 2 versions" } usage', + 'basic:preserve': { + message: 'supports { preserve: true } usage', source: 'basic.css', - expect: 'basic.expect.css', - result: 'basic.result.css', options: { - browsers: 'last 2 versions' - } - }, - 'basic:supported': { - message: 'ignores supported { ff >= 49 } usage', - source: 'basic.css', - options: { - browsers: 'ff >= 49' + preserve: true } } } diff --git a/CHANGELOG.md b/CHANGELOG.md index 173fb62be4..3190505b73 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,11 @@ -# Changes to PostCSS :dir() +# Changes to PostCSS Dir Pseudo Class + +### 3.0.0 (March 21, 2018) + +- Added: `preserve` option to preserve the original `:dir()` rule +- Updated: `postcss-selector-parser` to v3 (major) +- Removed: `browsers` option which is better covered by + [PostCSS Preset Env](https://github.com/jonathantneal/postcss-preset-env/) ### 2.1.0 (September 19, 2017) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index f58b57fa7d..76d75aa12b 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,4 +1,4 @@ -# Contributing to PostCSS :dir() +# Contributing to PostCSS Dir Pseudo Class You want to help? You rock! Now, take a moment to be sure your contributions make sense to everyone else. diff --git a/LICENSE.md b/LICENSE.md index b5bc55c9f6..0bc1fa7060 100644 --- a/LICENSE.md +++ b/LICENSE.md @@ -27,80 +27,82 @@ Copyright and Related Rights in the Work and the meaning and intended legal effect of CC0 on those rights. 1. Copyright and Related Rights. A Work made available under CC0 may be - protected by copyright and related or neighboring rights (“Copyright and - Related Rights”). Copyright and Related Rights include, but are not limited - to, the following: - 1. the right to reproduce, adapt, distribute, perform, display, - communicate, and translate a Work; - 2. moral rights retained by the original author(s) and/or performer(s); - 3. publicity and privacy rights pertaining to a person’s image or likeness - depicted in a Work; - 4. rights protecting against unfair competition in regards to a Work, - subject to the limitations in paragraph 4(i), below; - 5. rights protecting the extraction, dissemination, use and reuse of data - in a Work; - 6. database rights (such as those arising under Directive 96/9/EC of the - European Parliament and of the Council of 11 March 1996 on the legal - protection of databases, and under any national implementation thereof, - including any amended or successor version of such directive); and - 7. other similar, equivalent or corresponding rights throughout the world - based on applicable law or treaty, and any national implementations - thereof. + protected by copyright and related or neighboring rights (“Copyright and + Related Rights”). Copyright and Related Rights include, but are not limited + to, the following: + 1. the right to reproduce, adapt, distribute, perform, display, communicate, + and translate a Work; + 2. moral rights retained by the original author(s) and/or performer(s); + 3. publicity and privacy rights pertaining to a person’s image or likeness + depicted in a Work; + 4. rights protecting against unfair competition in regards to a Work, + subject to the limitations in paragraph 4(i), below; + 5. rights protecting the extraction, dissemination, use and reuse of data in + a Work; + 6. database rights (such as those arising under Directive 96/9/EC of the + European Parliament and of the Council of 11 March 1996 on the legal + protection of databases, and under any national implementation thereof, + including any amended or successor version of such directive); and + 7. other similar, equivalent or corresponding rights throughout the world + based on applicable law or treaty, and any national implementations + thereof. 2. Waiver. To the greatest extent permitted by, but not in contravention of, -applicable law, Affirmer hereby overtly, fully, permanently, irrevocably and -unconditionally waives, abandons, and surrenders all of Affirmer’s Copyright -and Related Rights and associated claims and causes of action, whether now -known or unknown (including existing as well as future claims and causes of -action), in the Work (i) in all territories worldwide, (ii) for the maximum -duration provided by applicable law or treaty (including future time -extensions), (iii) in any current or future medium and for any number of -copies, and (iv) for any purpose whatsoever, including without limitation -commercial, advertising or promotional purposes (the “Waiver”). Affirmer makes -the Waiver for the benefit of each member of the public at large and to the -detriment of Affirmer’s heirs and successors, fully intending that such Waiver -shall not be subject to revocation, rescission, cancellation, termination, or -any other legal or equitable action to disrupt the quiet enjoyment of the Work -by the public as contemplated by Affirmer’s express Statement of Purpose. + applicable law, Affirmer hereby overtly, fully, permanently, irrevocably and + unconditionally waives, abandons, and surrenders all of Affirmer’s Copyright + and Related Rights and associated claims and causes of action, whether now + known or unknown (including existing as well as future claims and causes of + action), in the Work (i) in all territories worldwide, (ii) for the maximum + duration provided by applicable law or treaty (including future time + extensions), (iii) in any current or future medium and for any number of + copies, and (iv) for any purpose whatsoever, including without limitation + commercial, advertising or promotional purposes (the “Waiver”). Affirmer + makes the Waiver for the benefit of each member of the public at large and + to the detriment of Affirmer’s heirs and successors, fully intending that + such Waiver shall not be subject to revocation, rescission, cancellation, + termination, or any other legal or equitable action to disrupt the quiet + enjoyment of the Work by the public as contemplated by Affirmer’s express + Statement of Purpose. 3. Public License Fallback. Should any part of the Waiver for any reason be -judged legally invalid or ineffective under applicable law, then the Waiver -shall be preserved to the maximum extent permitted taking into account -Affirmer’s express Statement of Purpose. In addition, to the extent the Waiver -is so judged Affirmer hereby grants to each affected person a royalty-free, non -transferable, non sublicensable, non exclusive, irrevocable and unconditional -license to exercise Affirmer’s Copyright and Related Rights in the Work (i) in -all territories worldwide, (ii) for the maximum duration provided by applicable -law or treaty (including future time extensions), (iii) in any current or -future medium and for any number of copies, and (iv) for any purpose -whatsoever, including without limitation commercial, advertising or promotional -purposes (the “License”). The License shall be deemed effective as of the date -CC0 was applied by Affirmer to the Work. Should any part of the License for any -reason be judged legally invalid or ineffective under applicable law, such -partial invalidity or ineffectiveness shall not invalidate the remainder of the -License, and in such case Affirmer hereby affirms that he or she will not (i) -exercise any of his or her remaining Copyright and Related Rights in the Work -or (ii) assert any associated claims and causes of action with respect to the -Work, in either case contrary to Affirmer’s express Statement of Purpose. + judged legally invalid or ineffective under applicable law, then the Waiver + shall be preserved to the maximum extent permitted taking into account + Affirmer’s express Statement of Purpose. In addition, to the extent the + Waiver is so judged Affirmer hereby grants to each affected person a + royalty-free, non transferable, non sublicensable, non exclusive, + irrevocable and unconditional license to exercise Affirmer’s Copyright and + Related Rights in the Work (i) in all territories worldwide, (ii) for the + maximum duration provided by applicable law or treaty (including future time + extensions), (iii) in any current or future medium and for any number of + copies, and (iv) for any purpose whatsoever, including without limitation + commercial, advertising or promotional purposes (the “License”). The License + shall be deemed effective as of the date CC0 was applied by Affirmer to the + Work. Should any part of the License for any reason be judged legally + invalid or ineffective under applicable law, such partial invalidity or + ineffectiveness shall not invalidate the remainder of the License, and in + such case Affirmer hereby affirms that he or she will not (i) exercise any + of his or her remaining Copyright and Related Rights in the Work or (ii) + assert any associated claims and causes of action with respect to the Work, + in either case contrary to Affirmer’s express Statement of Purpose. 4. Limitations and Disclaimers. - 1. No trademark or patent rights held by Affirmer are waived, abandoned, - surrendered, licensed or otherwise affected by this document. - 2. Affirmer offers the Work as-is and makes no representations or - warranties of any kind concerning the Work, express, implied, statutory - or otherwise, including without limitation warranties of title, - merchantability, fitness for a particular purpose, non infringement, or - the absence of latent or other defects, accuracy, or the present or - absence of errors, whether or not discoverable, all to the greatest - extent permissible under applicable law. - 3. Affirmer disclaims responsibility for clearing rights of other persons - that may apply to the Work or any use thereof, including without - limitation any person’s Copyright and Related Rights in the Work. - Further, Affirmer disclaims responsibility for obtaining any necessary - consents, permissions or other rights required for any use of the Work. - 4. Affirmer understands and acknowledges that Creative Commons is not a - party to this document and has no duty or obligation with respect to - this CC0 or use of the Work. + 1. No trademark or patent rights held by Affirmer are waived, abandoned, + surrendered, licensed or otherwise affected by this document. + 2. Affirmer offers the Work as-is and makes no representations or warranties + of any kind concerning the Work, express, implied, statutory or + otherwise, including without limitation warranties of title, + merchantability, fitness for a particular purpose, non infringement, or + the absence of latent or other defects, accuracy, or the present or + absence of errors, whether or not discoverable, all to the greatest + extent permissible under applicable law. + 3. Affirmer disclaims responsibility for clearing rights of other persons + that may apply to the Work or any use thereof, including without + limitation any person’s Copyright and Related Rights in the Work. + Further, Affirmer disclaims responsibility for obtaining any necessary + consents, permissions or other rights required for any use of the Work. + 4. Affirmer understands and acknowledges that Creative Commons is not a + party to this document and has no duty or obligation with respect to this + CC0 or use of the Work. For more information, please see -https://creativecommons.org/publicdomain/zero/1.0/. +http://creativecommons.org/publicdomain/zero/1.0/. diff --git a/README.md b/README.md index c94b1b6865..a76d11d17c 100644 --- a/README.md +++ b/README.md @@ -1,13 +1,13 @@ -# PostCSS :dir() Pseudo [PostCSS Logo][postcss] +# PostCSS Dir Pseudo Class [PostCSS Logo][postcss] [![CSS Standard Status][css-img]][css-url] [![NPM Version][npm-img]][npm-url] [![Build Status][cli-img]][cli-url] -[![Licensing][lic-img]][lic-url] +[![Windows Build Status][win-img]][win-url] [![Gitter Chat][git-img]][git-url] -[PostCSS :dir() Pseudo] lets you use the `:dir()` pseudo-class to style by -directionality in CSS, following the [Selectors] specification. +[PostCSS Dir Pseudo Class] lets you use the `:dir()` pseudo-class to style by +directionality in CSS, following the [Selectors Level 4] specification. ```css article h3:dir(rtl) { @@ -29,15 +29,9 @@ article h3:dir(ltr) { } ``` -### Future-proof your CSS - -If your [browserslist] already supports the `:dir()` pseudo-class, this plugin -will not change your CSS. Learn more about this feature in the -[`browsers`](#browsers-option) section. - ### Maintain Specificity -Using [PostCSS :dir() Pseudo] will not impact selector weight, but it will +Using [PostCSS Dir Pseudo Class] will not impact selector weight, but it will require having at least one `[dir]` attribute in your HTML. If you don’t have _any_ `[dir]` attributes, consider using the following JavaScript: @@ -53,7 +47,7 @@ sometimes increase selector weight by one element (`html`). ## Usage -Add [PostCSS :dir() Pseudo] to your build tool: +Add [PostCSS Dir Pseudo Class] to your build tool: ```bash npm install postcss-dir-pseudo-class --save-dev @@ -61,10 +55,12 @@ npm install postcss-dir-pseudo-class --save-dev #### Node -Use [PostCSS :dir() Pseudo] to process your CSS: +Use [PostCSS Dir Pseudo Class] to process your CSS: ```js -require('postcss-dir-pseudo-class').process(YOUR_CSS /*, processConfig, options */); +import postcssDirPseudoClass from 'postcss-dir-pseudo-class'; + +postcssDirPseudoClass.process(YOUR_CSS); ``` #### PostCSS @@ -75,14 +71,51 @@ Add [PostCSS] to your build tool: npm install postcss --save-dev ``` -Use [PostCSS :dir() Pseudo] as a plugin: +Use [PostCSS Dir Pseudo Class] as a plugin: ```js +import postcss from 'gulp-postcss'; +import postcssDirPseudoClass from 'postcss-dir-pseudo-class'; + postcss([ - require('postcss-dir-pseudo-class')(/* Options */) + postcssDirPseudoClass() ]).process(YOUR_CSS); ``` +#### Webpack + +Add [PostCSS Loader] to your build tool: + +```bash +npm install postcss-loader --save-dev +``` + +Use [PostCSS Dir Pseudo Class] in your Webpack configuration: + +```js +import postcssDirPseudoClass from 'postcss-dir-pseudo-class'; + +module.exports = { + module: { + rules: [ + { + test: /\.css$/, + use: [ + 'style-loader', + { loader: 'css-loader', options: { importLoaders: 1 } }, + { loader: 'postcss-loader', options: { + ident: 'postcss', + plugins: () => [ + postcssDirPseudoClass(/* options */) + ] + } } + ] + } + ] + } +} +``` + #### Gulp Add [Gulp PostCSS] to your build tool: @@ -91,20 +124,19 @@ Add [Gulp PostCSS] to your build tool: npm install gulp-postcss --save-dev ``` -Use [PostCSS :dir() Pseudo] in your Gulpfile: +Use [PostCSS Dir Pseudo Class] in your Gulpfile: ```js -var postcss = require('gulp-postcss'); - -gulp.task('css', function () { - return gulp.src('./src/*.css').pipe( - postcss([ - require('postcss-dir-pseudo-class')(/* Options */) - ]) - ).pipe( - gulp.dest('.') - ); -}); +import postcss from 'gulp-postcss'; +import postcssDirPseudoClass from 'postcss-dir-pseudo-class'; + +gulp.task('css', () => gulp.src('./src/*.css').pipe( + postcss([ + postcssDirPseudoClass(/* options */) + ]) +).pipe( + gulp.dest('.') +)); ``` #### Grunt @@ -115,16 +147,18 @@ Add [Grunt PostCSS] to your build tool: npm install grunt-postcss --save-dev ``` -Use [PostCSS :dir() Pseudo] in your Gruntfile: +Use [PostCSS Dir Pseudo Class] in your Gruntfile: ```js +import postcssDirPseudoClass from 'postcss-dir-pseudo-class'; + grunt.loadNpmTasks('grunt-postcss'); grunt.initConfig({ postcss: { options: { use: [ - require('postcss-dir-pseudo-class')(/* Options */) + postcssDirPseudoClass(/* options */) ] }, dist: { @@ -134,51 +168,13 @@ grunt.initConfig({ }); ``` ---- - -## Browsers Option - -If your [browserslist] already supports the `:dir` pseudo-class, this plugin -will not change your CSS. While only Firefox currently supports `:dir`, this -will surely improve over time. - -Here’s an example of a `package.json` using a browserslist that would fully -support the `:dir` pseudo-class: - -```json -{ - "browserslist": "firefox >= 49" -} -``` - -And here’s an example of using the `browsers` option to accomplish the same -thing: - -```js -require('postcss-dir-pseudo-class')({ - browsers: 'firefox >= 49' -}); -``` - -In both of these examples, the CSS would remain unchanged. - -```css -.example:dir(rtl) { - margin-right: 10px; -} - -/* becomes */ - -.example:dir(rtl) { - margin-right: 10px; -} -``` +## Options -## Dir Option +### dir -By default, this plugin requires you to include a direction `[dir]` attribute -in your HTML, preferably on the `html` element. If you prefer not to, you -can presume a direction in your CSS using the `dir` option. +The `dir` option allows you presume a direction in your CSS. By default, this +is not specified and you are required to include a direction `[dir]` attribute +somewhere in your HTML, preferably on the `html` element. Here’s an example of using the `dir` option to presume a left-to-right direction: @@ -209,20 +205,25 @@ html:not([dir="rtl"]) .example { } ``` +### preserve + +The `preserve` option determines whether the original `:dir()` rule should +remain in the CSS. By default, the rule is replaced by the fallback. + +[css-img]: https://jonathantneal.github.io/css-db/badge/selectors-dir-pseudo.svg +[css-url]: https://jonathantneal.github.io/css-db/#selectors-dir-pseudo +[npm-url]: https://www.npmjs.com/package/postcss-dir-pseudo-class +[npm-img]: https://img.shields.io/npm/v/postcss-dir-pseudo-class.svg [cli-url]: https://travis-ci.org/jonathantneal/postcss-dir-pseudo-class [cli-img]: https://img.shields.io/travis/jonathantneal/postcss-dir-pseudo-class.svg -[css-img]: https://jonathantneal.github.io/css-db/badge/selectors-the-dir-pseudo.svg -[css-url]: https://jonathantneal.github.io/css-db/#selectors-the-dir-pseudo +[win-url]: https://ci.appveyor.com/project/jonathantneal/postcss-dir-pseudo-class +[win-img]: https://img.shields.io/appveyor/ci/jonathantneal/postcss-dir-pseudo-class.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-dir-pseudo-class.svg -[npm-url]: https://www.npmjs.com/package/postcss-dir-pseudo-class -[npm-img]: https://img.shields.io/npm/v/postcss-dir-pseudo-class.svg -[browserslist]: https://github.com/ai/browserslist [Gulp PostCSS]: https://github.com/postcss/gulp-postcss [Grunt PostCSS]: https://github.com/nDmitry/grunt-postcss [PostCSS]: https://github.com/postcss/postcss -[PostCSS :dir() Pseudo]: https://github.com/jonathantneal/postcss-dir-pseudo-class -[Selectors]: https://drafts.csswg.org/selectors-4/#the-dir-pseudo +[PostCSS Dir Pseudo Class]: https://github.com/jonathantneal/postcss-dir-pseudo-class +[PostCSS Loader]: https://github.com/postcss/postcss-loader +[Selectors Level 4]: https://www.w3.org/TR/selectors-4/ diff --git a/index.js b/index.js index 337dae3a14..347992f5cc 100644 --- a/index.js +++ b/index.js @@ -1,110 +1,103 @@ -// tooling -const browserslist = require('browserslist'); -const postcss = require('postcss'); -const selectorParser = require('postcss-selector-parser'); +import postcss from 'postcss'; +import selectorParser from 'postcss-selector-parser'; -// plugin -module.exports = postcss.plugin('postcss-dir-pseudo-class', (opts) => (root) => { - // client browser list - const clientBrowserList = browserslist(Object(opts).browsers, { - path: root.source && root.source.input && root.source.input.file - }); +export default postcss.plugin('postcss-dir-pseudo-class', opts => { + const dir = Object(opts).dir; + const preserve = Boolean(Object(opts).preserve); - // whether this library is needed - const requiresPolyfill = clientBrowserList.some( - (clientBrowser) => browserslist('chrome > 0, edge > 0, firefox <= 48, ie > 0, safari > 0').some( - (polyfillBrowser) => polyfillBrowser === clientBrowser - ) - ); + return root => { + // walk rules using the :dir pseudo-class + root.walkRules(/:dir\([^\)]*\)/, rule => { + let currentRule = rule - if (!requiresPolyfill) { - return; - } + // conditionally preserve the original rule + if (preserve) { + currentRule = rule.cloneBefore(); + } - // walk rules using the :dir pseudo-class - root.walkRules(/:dir\([^\)]*\)/, (rule) => { - // update the rule selector - rule.selector = selectorParser((selectors) => { - // for each (comma separated) selector - selectors.nodes.forEach((selector) => { - // walk all selector nodes that are :dir pseudo-classes - selector.walk((node) => { - if ('pseudo' === node.type && ':dir' === node.value) { - // previous and next selector nodes - const prev = node.prev(); - const next = node.next(); + // update the rule selector + currentRule.selector = selectorParser(selectors => { + // for each (comma separated) selector + selectors.nodes.forEach(selector => { + // walk all selector nodes that are :dir pseudo-classes + selector.walk(node => { + if ('pseudo' === node.type && ':dir' === node.value) { + // previous and next selector nodes + const prev = node.prev(); + const next = node.next(); - const prevIsSpaceCombinator = prev && prev.type && 'combinator' === prev.type && ' ' === prev.value; - const nextIsSpaceCombinator = next && next.type && 'combinator' === next.type && ' ' === next.value; + const prevIsSpaceCombinator = prev && prev.type && 'combinator' === prev.type && ' ' === prev.value; + const nextIsSpaceCombinator = next && next.type && 'combinator' === next.type && ' ' === next.value; - // preserve the selector tree - if (prevIsSpaceCombinator && (nextIsSpaceCombinator || !next)) { - node.replaceWith( - selectorParser.universal() - ); - } else { - node.remove(); - } - - // conditionally prepend a combinator before inserting the [dir] attribute - const first = selector.nodes[0]; - const firstIsSpaceCombinator = first && 'combinator' === first.type && ' ' === first.value; - const firstIsHtml = first && 'tag' === first.type && 'html' === first.value; - const firstIsRoot = first && 'pseudo' === first.type && ':root' === first.value; - - if (first && !firstIsHtml && !firstIsRoot && !firstIsSpaceCombinator) { - selector.prepend( - selectorParser.combinator({ - value: ' ' - }) - ); - } + // preserve the selector tree + if (prevIsSpaceCombinator && (nextIsSpaceCombinator || !next)) { + node.replaceWith( + selectorParser.universal() + ); + } else { + node.remove(); + } - // value of the :dir pseudo-class - const value = node.nodes.toString(); + // conditionally prepend a combinator before inserting the [dir] attribute + const first = selector.nodes[0]; + const firstIsSpaceCombinator = first && 'combinator' === first.type && ' ' === first.value; + const firstIsHtml = first && 'tag' === first.type && 'html' === first.value; + const firstIsRoot = first && 'pseudo' === first.type && ':root' === first.value; - // whether :dir matches the presumed direction - const isdir = Object(opts).dir === value; + if (first && !firstIsHtml && !firstIsRoot && !firstIsSpaceCombinator) { + selector.prepend( + selectorParser.combinator({ + value: ' ' + }) + ); + } - // [dir] attribute - const dirAttr = selectorParser.attribute({ - attribute: 'dir', - operator: '=', - value: `"${ value }"` - }); + // value of the :dir pseudo-class + const value = node.nodes.toString(); - // not[dir] attribute - const notDirAttr = selectorParser.pseudo({ - value: `${firstIsHtml || firstIsRoot ? '' : 'html'}:not` - }); + // whether :dir matches the presumed direction + const isdir = dir === value; - notDirAttr.append( - selectorParser.attribute({ + // [dir] attribute + const dirAttr = selectorParser.attribute({ attribute: 'dir', operator: '=', - value: `"${ 'ltr' === value ? 'rtl' : 'ltr' }"` - }) - ); + value: `"${ value }"` + }); + + // not[dir] attribute + const notDirAttr = selectorParser.pseudo({ + value: `${firstIsHtml || firstIsRoot ? '' : 'html'}:not` + }); + + notDirAttr.append( + selectorParser.attribute({ + attribute: 'dir', + operator: '=', + value: `"${ 'ltr' === value ? 'rtl' : 'ltr' }"` + }) + ); - if (isdir) { - // if the direction is presumed - if (firstIsHtml) { - // insert :root after html tag - selector.insertAfter(first, notDirAttr); + if (isdir) { + // if the direction is presumed + if (firstIsHtml) { + // insert :root after html tag + selector.insertAfter(first, notDirAttr); + } else { + // prepend :root + selector.prepend(notDirAttr); + } + } else if (firstIsHtml) { + // otherwise, insert dir attribute after html tag + selector.insertAfter(first, dirAttr); } else { - // prepend :root - selector.prepend(notDirAttr); + // otherwise, prepend the dir attribute + selector.prepend(dirAttr); } - } else if (firstIsHtml) { - // otherwise, insert dir attribute after html tag - selector.insertAfter(first, dirAttr); - } else { - // otherwise, prepend the dir attribute - selector.prepend(dirAttr); } - } + }); }); - }); - }).process(rule.selector).result; - }); + }).processSync(currentRule.selector); + }); + }; }); diff --git a/package.json b/package.json index 63ea33d448..13b26a34ba 100644 --- a/package.json +++ b/package.json @@ -1,39 +1,56 @@ { "name": "postcss-dir-pseudo-class", - "version": "2.1.0", + "version": "3.0.0", "description": "Use the :dir pseudo-class in CSS", "author": "Jonathan Neal ", "license": "CC0-1.0", "repository": "jonathantneal/postcss-dir-pseudo-class", "homepage": "https://github.com/jonathantneal/postcss-dir-pseudo-class#readme", "bugs": "https://github.com/jonathantneal/postcss-dir-pseudo-class/issues", - "main": "index.js", + "main": "index.cjs.js", + "module": "index.es.js", "files": [ - "index.js" + "index.cjs.js", + "index.es.js" ], "scripts": { - "clean": "git clean -X -d -f", - "prepublish": "npm test", - "test": "echo 'Running tests...'; npm run test:js && npm run test:tape", - "test:js": "eslint *.js --cache --ignore-pattern .gitignore", + "prepublishOnly": "npm test", + "pretest": "rollup -c .rollup.js --silent", + "test": "echo 'Running tests...'; npm run test:ec && npm run test:js && npm run test:tape", + "test:ec": "echint --ignore index.*.js test", + "test:js": "eslint *.js --cache --ignore-path .gitignore --quiet", "test:tape": "postcss-tape" }, "engines": { "node": ">=4.0.0" }, "dependencies": { - "browserslist": "^2.4.0", - "postcss": "^6.0.11", - "postcss-selector-parser": "^2.2.3" + "postcss": "^6.0.20", + "postcss-selector-parser": "^3.1.1" }, "devDependencies": { - "eslint": "^4.7.1", - "eslint-config-dev": "2.0.0", - "postcss-tape": "2.1.0", - "pre-commit": "^1.2.2" + "babel-core": "^6.26.0", + "babel-eslint": "^8.2.2", + "babel-preset-env": "^1.6.1", + "echint": "^4.0.1", + "eslint": "^4.19.0", + "eslint-config-dev": "^2.0.0", + "postcss-tape": "^2.2.0", + "pre-commit": "^1.2.2", + "rollup": "^0.57.1", + "rollup-plugin-babel": "^3.0.3" }, "eslintConfig": { - "extends": "dev" + "extends": "dev", + "parser": "babel-eslint", + "rules": { + "complexity": [ + "error", + { + "max": 30 + } + ] + } }, "keywords": [ "postcss", diff --git a/test/basic.preserve.expect.css b/test/basic.preserve.expect.css new file mode 100644 index 0000000000..95fcf5b5fb --- /dev/null +++ b/test/basic.preserve.expect.css @@ -0,0 +1,143 @@ +[dir="ltr"] { + order: 0; +} + +:dir(ltr) { + order: 0; +} + +[dir="ltr"] test { + order: 1; +} + +:dir(ltr) test { + order: 1; +} + +[dir="ltr"] test * { + order: 2; +} + +test :dir(ltr) { + order: 2; +} + +[dir="ltr"] test * test { + order: 3; +} + +test :dir(ltr) test { + order: 3; +} + +[dir="ltr"] test { + order: 4; +} + +test:dir(ltr) { + order: 4; +} + +[dir="ltr"] test test { + order: 5; +} + +test:dir(ltr) test { + order: 5; +} + +[dir="ltr"] test test { + order: 6; +} + +test test:dir(ltr) { + order: 6; +} + +[dir="ltr"]:root * { + order: 7; +} + +:root :dir(ltr) { + order: 7; +} + +html[dir="ltr"] * { + order: 8; +} + +html :dir(ltr) { + order: 8; +} + +[dir="rtl"] { + order: 9; +} + +:dir(rtl) { + order: 9; +} + +[dir="rtl"] test { + order: 10; +} + +:dir(rtl) test { + order: 10; +} + +[dir="rtl"] test * { + order: 11; +} + +test :dir(rtl) { + order: 11; +} + +[dir="rtl"] test * test { + order: 12; +} + +test :dir(rtl) test { + order: 12; +} + +[dir="rtl"] test { + order: 13; +} + +test:dir(rtl) { + order: 13; +} + +[dir="rtl"] test test { + order: 14; +} + +test:dir(rtl) test { + order: 14; +} + +[dir="rtl"] test test { + order: 15; +} + +test test:dir(rtl) { + order: 15; +} + +[dir="rtl"]:root * { + order: 16; +} + +:root :dir(rtl) { + order: 16; +} + +html[dir="rtl"] * { + order: 17; +} + +html :dir(rtl) { + order: 17; +} diff --git a/test/basic.supported.expect.css b/test/basic.supported.expect.css deleted file mode 100644 index 0037e7ddf5..0000000000 --- a/test/basic.supported.expect.css +++ /dev/null @@ -1,71 +0,0 @@ -:dir(ltr) { - order: 0; -} - -:dir(ltr) test { - order: 1; -} - -test :dir(ltr) { - order: 2; -} - -test :dir(ltr) test { - order: 3; -} - -test:dir(ltr) { - order: 4; -} - -test:dir(ltr) test { - order: 5; -} - -test test:dir(ltr) { - order: 6; -} - -:root :dir(ltr) { - order: 7; -} - -html :dir(ltr) { - order: 8; -} - -:dir(rtl) { - order: 9; -} - -:dir(rtl) test { - order: 10; -} - -test :dir(rtl) { - order: 11; -} - -test :dir(rtl) test { - order: 12; -} - -test:dir(rtl) { - order: 13; -} - -test:dir(rtl) test { - order: 14; -} - -test test:dir(rtl) { - order: 15; -} - -:root :dir(rtl) { - order: 16; -} - -html :dir(rtl) { - order: 17; -} From 1596182fbd0d23a936bcd6389b360f4e0afd5cef Mon Sep 17 00:00:00 2001 From: Jonathan Neal Date: Sat, 7 Apr 2018 21:52:33 -0400 Subject: [PATCH 597/795] 2.0.0 --- .gitignore | 2 +- .rollup.js | 5 +++- .tape.js | 6 ++++ CHANGELOG.md | 5 ++++ README.md | 46 ++++++++++++++++++++++++++----- index.js | 11 +++++++- package.json | 36 ++++++++++++------------ test/basic.expect.css | 21 ++++++++++++++ test/basic.preserve.expect.css | 27 ++++++++++++++++++ test/basic.replacewith.expect.css | 21 ++++++++++++++ 10 files changed, 151 insertions(+), 29 deletions(-) create mode 100644 test/basic.preserve.expect.css diff --git a/.gitignore b/.gitignore index 6832ce87db..de73e5a338 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,5 @@ node_modules -index.bundle.js +index.*.js package-lock.json *.log* *.result.css diff --git a/.rollup.js b/.rollup.js index 7f4e231750..0436758216 100644 --- a/.rollup.js +++ b/.rollup.js @@ -2,7 +2,10 @@ import babel from 'rollup-plugin-babel'; export default { input: 'index.js', - output: { file: 'index.bundle.js', format: 'cjs' }, + output: [ + { file: 'index.cjs.js', format: 'cjs' }, + { file: 'index.es.js', format: 'es' } + ], plugins: [ babel({ presets: [ diff --git a/.tape.js b/.tape.js index 826394f626..85f8fe9f1f 100644 --- a/.tape.js +++ b/.tape.js @@ -8,6 +8,12 @@ module.exports = { options: { replaceWith: '.focus-within' } + }, + 'basic:preserve': { + message: 'supports { preserve: false } usage', + options: { + preserve: false + } } } }; diff --git a/CHANGELOG.md b/CHANGELOG.md index 7b2f126da6..b018586815 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,10 @@ # Changes to PostCSS Focus Within +### 2.0.0 (April 7, 2018) + +- Changed: default functionality to preserve the original rule +- Added: `preserve` option to preserve the original rule using `:focus-within` + ### 1.0.0 (February 17, 2018) - Initial version diff --git a/README.md b/README.md index 991ee7fcd0..d0965b8672 100644 --- a/README.md +++ b/README.md @@ -5,8 +5,10 @@ [![Windows Build Status][win-img]][win-url] [![Gitter Chat][git-img]][git-url] -[PostCSS Focus Within] lets you use the `:focus-within` pseudo-selector in -CSS, following the [Selectors Level 4 specification]. +[PostCSS Focus Within] lets you use the `:focus-within` pseudo-class in CSS, +following the [Selectors Level 4 specification]. + +It is the companion to the [focus-within polyfill]. ```css .my-form-field:focus-within label { @@ -18,12 +20,17 @@ CSS, following the [Selectors Level 4 specification]. .my-form-field[focus-within] label { background-color: yellow; } + +.my-form-field:focus-within label { + background-color: yellow; +} ``` -[PostCSS Focus Within] replaces the `:focus-within` pseudo-selector with a -`.focus-within` class selector, the same selector used by the -[focus-within polyfill]. The replacement selector can be changed using the -`replaceWith` option. +[PostCSS Focus Within] duplicates rules using the `:focus-within` pseudo-class +with a `[focus-within]` attribute selector, the same selector used by the +[focus-within polyfill]. This replacement selector can be changed using the +`replaceWith` option. Also, the preservation of the original `:focus-within` +rule can be disabled using the `preserve` option. ## Usage @@ -148,6 +155,27 @@ grunt.initConfig({ ## Options +### preserve + +The `preserve` option defines whether the original selector should remain. By +default, the original selector is preserved. + +```js +focusWithin({ preserve: false }); +``` + +```css +.my-form-field:focus-within label { + background-color: yellow; +} + +/* becomes */ + +.my-form-field[focus-within] label { + background-color: yellow; +} +``` + ### replaceWith The `replaceWith` option defines the selector to replace `:focus-within`. By @@ -167,6 +195,10 @@ focusWithin({ replaceWith: '.focus-within' }); .my-form-field.focus-within label { background-color: yellow; } + +.my-form-field:focus-within label { + background-color: yellow; +} ``` [npm-url]: https://www.npmjs.com/package/postcss-focus-within @@ -176,7 +208,7 @@ focusWithin({ replaceWith: '.focus-within' }); [win-url]: https://ci.appveyor.com/project/jonathantneal/postcss-focus-within [win-img]: https://img.shields.io/appveyor/ci/jonathantneal/postcss-focus-within.svg [git-url]: https://gitter.im/postcss/postcss -[git-img]: https://img.shields.io/badge/chat-gitter-blue.svg +[git-img]: https://img.shields.io/badge/support-chat-blue.svg [focus-within polyfill]: https://github.com/jonathantneal/focus-within [Gulp PostCSS]: https://github.com/postcss/gulp-postcss diff --git a/index.js b/index.js index dbaff97513..d82d2e0894 100644 --- a/index.js +++ b/index.js @@ -4,12 +4,21 @@ const selectorRegExp = /:focus-within([^\w-]|$)/gi; export default postcss.plugin('postcss-focus-within', opts => { const replaceWith = String(Object(opts).replaceWith || '[focus-within]'); + const preserve = Boolean('preserve' in Object(opts) ? opts.preserve : true); return root => { root.walkRules(selectorRegExp, rule => { - rule.selector = rule.selector.replace(selectorRegExp, ($0, $1) => { + const selector = rule.selector.replace(selectorRegExp, ($0, $1) => { return `${replaceWith}${$1}`; }); + + const clone = rule.clone({ selector }); + + if (preserve) { + rule.before(clone); + } else { + rule.replaceWith(clone); + } }); }; }); diff --git a/package.json b/package.json index 72568f77ca..afd7ec1031 100644 --- a/package.json +++ b/package.json @@ -1,23 +1,22 @@ { "name": "postcss-focus-within", - "version": "1.0.0", - "description": "", + "version": "2.0.0", + "description": "Ise the :focus-within pseudo-selector in CSS", "author": "Jonathan Neal ", "license": "CC0-1.0", "repository": "jonathantneal/postcss-focus-within", "homepage": "https://github.com/jonathantneal/postcss-focus-within#readme", "bugs": "https://github.com/jonathantneal/postcss-focus-within/issues", - "main": "index.bundle.js", - "module": "index.js", + "main": "index.cjs.js", + "module": "index.es.js", "files": [ - "index.js", - "index.bundle.js" + "index.cjs.js", + "index.es.js" ], "scripts": { "prepublishOnly": "npm test", "pretest": "rollup -c .rollup.js --silent", - "test": "echo 'Running tests...'; npm run test:ec && npm run test:js && npm run test:tape", - "test:ec": "echint --ignore index.bundle.js test", + "test": "echo 'Running tests...'; npm run test:js && npm run test:tape", "test:js": "eslint *.js --cache --ignore-path .gitignore --quiet", "test:tape": "postcss-tape" }, @@ -25,19 +24,18 @@ "node": ">=4.0.0" }, "dependencies": { - "postcss": "^6.0" + "postcss": "^6.0.21" }, "devDependencies": { - "babel-core": "^6.26", - "babel-eslint": "^8.2", - "babel-preset-env": "^1.6", - "echint": "^4.0", - "eslint": "^4.18", - "eslint-config-dev": "2.0", - "postcss-tape": "2.2", - "pre-commit": "^1.2", - "rollup": "^0.56", - "rollup-plugin-babel": "^3.0" + "babel-core": "^6.26.0", + "babel-eslint": "^8.2.2", + "babel-preset-env": "^1.6.1", + "eslint": "^4.19.1", + "eslint-config-dev": "2.0.0", + "postcss-tape": "2.2.0", + "pre-commit": "^1.2.2", + "rollup": "^0.57.1", + "rollup-plugin-babel": "^3.0.3" }, "eslintConfig": { "extends": "dev", diff --git a/test/basic.expect.css b/test/basic.expect.css index 7691c5efa1..b83063ad53 100644 --- a/test/basic.expect.css +++ b/test/basic.expect.css @@ -2,6 +2,10 @@ order: 1; } +:focus-within { + order: 1; +} + [focus-within], [focus-within] test, test [focus-within], @@ -19,6 +23,23 @@ test :matches(test [focus-within] [focus-within] test) test { order: 2; } +:focus-within, +:focus-within test, +test :focus-within, +test test:focus-within, +test :focus-within test, +test test:focus-within test, +test :focus-within :focus-within test, +test :matches(:focus-within) test, +test :matches(:focus-within test) test, +test :matches(test :focus-within) test, +test :matches(test test:focus-within) test, +test :matches(test :focus-within test) test, +test :matches(test test:focus-within test) test, +test :matches(test :focus-within :focus-within test) test { + order: 2; +} + :ignore-focus-within, :focus-within-ignore, :ignorefocus-within, diff --git a/test/basic.preserve.expect.css b/test/basic.preserve.expect.css new file mode 100644 index 0000000000..7691c5efa1 --- /dev/null +++ b/test/basic.preserve.expect.css @@ -0,0 +1,27 @@ +[focus-within] { + order: 1; +} + +[focus-within], +[focus-within] test, +test [focus-within], +test test[focus-within], +test [focus-within] test, +test test[focus-within] test, +test [focus-within] [focus-within] test, +test :matches([focus-within]) test, +test :matches([focus-within] test) test, +test :matches(test [focus-within]) test, +test :matches(test test[focus-within]) test, +test :matches(test [focus-within] test) test, +test :matches(test test[focus-within] test) test, +test :matches(test [focus-within] [focus-within] test) test { + order: 2; +} + +:ignore-focus-within, +:focus-within-ignore, +:ignorefocus-within, +:focus-withinignore { + order: 3; +} diff --git a/test/basic.replacewith.expect.css b/test/basic.replacewith.expect.css index 407dc2610c..b8fe63268d 100644 --- a/test/basic.replacewith.expect.css +++ b/test/basic.replacewith.expect.css @@ -2,6 +2,10 @@ order: 1; } +:focus-within { + order: 1; +} + .focus-within, .focus-within test, test .focus-within, @@ -19,6 +23,23 @@ test :matches(test .focus-within .focus-within test) test { order: 2; } +:focus-within, +:focus-within test, +test :focus-within, +test test:focus-within, +test :focus-within test, +test test:focus-within test, +test :focus-within :focus-within test, +test :matches(:focus-within) test, +test :matches(:focus-within test) test, +test :matches(test :focus-within) test, +test :matches(test test:focus-within) test, +test :matches(test :focus-within test) test, +test :matches(test test:focus-within test) test, +test :matches(test :focus-within :focus-within test) test { + order: 2; +} + :ignore-focus-within, :focus-within-ignore, :ignorefocus-within, From fc74d538f6b67a78ce144c0668252b5e3104184a Mon Sep 17 00:00:00 2001 From: Jonathan Neal Date: Sat, 7 Apr 2018 22:34:27 -0400 Subject: [PATCH 598/795] 3.0.0 --- .gitignore | 2 +- .rollup.js | 5 ++- .tape.js | 10 ++++-- CHANGELOG.md | 5 +++ README.md | 48 ++++++++++++++++++++++++----- index.js | 15 +++++++-- package.json | 18 +++++------ test/basic.expect.css | 21 +++++++++++++ test/basic.preserve.expect.css | 27 ++++++++++++++++ test/basic.replacewith.expect.css | 51 ++++++++++++++++++++++--------- test/basic.replacewith.result.css | 51 ++++++++++++++++++++++--------- test/basic.result.css | 21 +++++++++++++ 12 files changed, 219 insertions(+), 55 deletions(-) create mode 100644 test/basic.preserve.expect.css diff --git a/.gitignore b/.gitignore index 6832ce87db..de73e5a338 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,5 @@ node_modules -index.bundle.js +index.*.js package-lock.json *.log* *.result.css diff --git a/.rollup.js b/.rollup.js index 7f4e231750..0436758216 100644 --- a/.rollup.js +++ b/.rollup.js @@ -2,7 +2,10 @@ import babel from 'rollup-plugin-babel'; export default { input: 'index.js', - output: { file: 'index.bundle.js', format: 'cjs' }, + output: [ + { file: 'index.cjs.js', format: 'cjs' }, + { file: 'index.es.js', format: 'es' } + ], plugins: [ babel({ presets: [ diff --git a/.tape.js b/.tape.js index b94e24d292..7dc366f171 100644 --- a/.tape.js +++ b/.tape.js @@ -4,9 +4,15 @@ module.exports = { message: 'supports basic usage' }, 'basic:replacewith': { - message: 'supports { replaceWith: "[data-focus-visible-added]" } usage', + message: 'supports { replaceWith: "[focus-visible]" } usage', options: { - replaceWith: '[data-focus-visible-added]' + replaceWith: '[focus-visible]' + } + }, + 'basic:preserve': { + message: 'supports { preserve: false } usage', + options: { + preserve: false } } } diff --git a/CHANGELOG.md b/CHANGELOG.md index 0aab1e9d47..aca919c854 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,10 @@ # Changes to PostCSS Focus Visible +### 3.0.0 (April 7, 2018) + +- Changed: default functionality to preserve the original rule +- Added: `preserve` option to preserve the original rule using `:focus-visible` + ### 2.0.0 (February 17, 2018) - Changed `:focus-ring` to `:focus-visible` per the specification diff --git a/README.md b/README.md index 81cc2f6f17..d27dc5ff22 100644 --- a/README.md +++ b/README.md @@ -5,9 +5,11 @@ [![Windows Build Status][win-img]][win-url] [![Gitter Chat][git-img]][git-url] -[PostCSS Focus Visible] lets you use the `:focus-visible` pseudo-selector in +[PostCSS Focus Visible] lets you use the `:focus-visible` pseudo-class in CSS, following the [Selectors Level 4 specification]. +It is the companion to the [focus-visible polyfill]. + ```css :focus:not(:focus-visible) { outline: none; @@ -18,12 +20,17 @@ CSS, following the [Selectors Level 4 specification]. :focus:not(.focus-visible) { outline: none; } + +:focus:not(:focus-visible) { + outline: none; +} ``` -[PostCSS Focus Visible] replaces the `:focus-visible` pseudo-selector with a -`.focus-visible` class selector, the same selector used by the -[focus-visible polyfill]. The replacement selector can be changed using the -`replaceWith` option. +[PostCSS Focus Visible] duplicates rules using the `:focus-visible` pseudo-class +with a `.focus-visible` class selector, the same selector used by the +[focus-visible polyfill]. This replacement selector can be changed using the +`replaceWith` option. Also, the preservation of the original `:focus-visible` +rule can be disabled using the `preserve` option. ## Usage @@ -148,13 +155,34 @@ grunt.initConfig({ ## Options +### preserve + +The `preserve` option defines whether the original selector should remain. By +default, the original selector is preserved. + +```js +focusVisible({ preserve: false }); +``` + +```css +:focus:not(:focus-visible) { + outline: none; +} + +/* becomes */ + +:focus:not(.focus-visible) { + outline: none; +} +``` + ### replaceWith The `replaceWith` option defines the selector to replace `:focus-visible`. By default, the replacement selector is `.focus-visible`. ```js -focusVisible({ replaceWith: '[data-focus-visible-added]' }); +focusVisible({ replaceWith: '[focus-visible]' }); ``` ```css @@ -164,7 +192,11 @@ focusVisible({ replaceWith: '[data-focus-visible-added]' }); /* becomes */ -:focus:not([data-focus-visible-added]) { +:focus:not([focus-visible]) { + outline: none; +} + +:focus:not(:focus-visible) { outline: none; } ``` @@ -176,7 +208,7 @@ focusVisible({ replaceWith: '[data-focus-visible-added]' }); [win-url]: https://ci.appveyor.com/project/jonathantneal/postcss-focus-visible [win-img]: https://img.shields.io/appveyor/ci/jonathantneal/postcss-focus-visible.svg [git-url]: https://gitter.im/postcss/postcss -[git-img]: https://img.shields.io/badge/chat-gitter-blue.svg +[git-img]: https://img.shields.io/badge/support-chat-blue.svg [focus-visible polyfill]: https://github.com/WICG/focus-visible [Gulp PostCSS]: https://github.com/postcss/gulp-postcss diff --git a/index.js b/index.js index 03358abe52..64486ad39e 100644 --- a/index.js +++ b/index.js @@ -1,15 +1,24 @@ import postcss from 'postcss'; -const focusVisibleSelectorRegExp = /:focus-visible([^\w-]|$)/gi; +const selectorRegExp = /:focus-visible([^\w-]|$)/gi; export default postcss.plugin('postcss-focus-visible', opts => { const replaceWith = String(Object(opts).replaceWith || '.focus-visible'); + const preserve = Boolean('preserve' in Object(opts) ? opts.preserve : true); return root => { - root.walkRules(focusVisibleSelectorRegExp, rule => { - rule.selector = rule.selector.replace(focusVisibleSelectorRegExp, ($0, $1) => { + root.walkRules(selectorRegExp, rule => { + const selector = rule.selector.replace(selectorRegExp, ($0, $1) => { return `${replaceWith}${$1}`; }); + + const clone = rule.clone({ selector }); + + if (preserve) { + rule.before(clone); + } else { + rule.replaceWith(clone); + } }); }; }); diff --git a/package.json b/package.json index e155e8b102..f39687e249 100644 --- a/package.json +++ b/package.json @@ -1,23 +1,22 @@ { "name": "postcss-focus-visible", - "version": "2.0.0", + "version": "3.0.0", "description": "Use the :focus-visible pseudo-selector in CSS", "author": "Jonathan Neal ", "license": "CC0-1.0", "repository": "jonathantneal/postcss-focus-visible", "homepage": "https://github.com/jonathantneal/postcss-focus-visible#readme", "bugs": "https://github.com/jonathantneal/postcss-focus-visible/issues", - "main": "index.bundle.js", - "module": "index.js", + "main": "index.cjs.js", + "module": "index.es.js", "files": [ - "index.js", - "index.bundle.js" + "index.cjs.js", + "index.es.js" ], "scripts": { "prepublishOnly": "npm test", "pretest": "rollup -c .rollup.js --silent", - "test": "echo 'Running tests...'; npm run test:ec && npm run test:js && npm run test:tape", - "test:ec": "echint --ignore index.bundle.js test", + "test": "echo 'Running tests...'; npm run test:js && npm run test:tape", "test:js": "eslint *.js --cache --ignore-path .gitignore --quiet", "test:tape": "postcss-tape" }, @@ -31,12 +30,11 @@ "babel-core": "^6.26", "babel-eslint": "^8.2", "babel-preset-env": "^1.6", - "echint": "^4.0", - "eslint": "^4.18", + "eslint": "^4.19", "eslint-config-dev": "2.0", "postcss-tape": "2.2", "pre-commit": "^1.2", - "rollup": "^0.56", + "rollup": "^0.57", "rollup-plugin-babel": "^3.0" }, "eslintConfig": { diff --git a/test/basic.expect.css b/test/basic.expect.css index 6a85671726..0dfd32b804 100644 --- a/test/basic.expect.css +++ b/test/basic.expect.css @@ -2,6 +2,10 @@ order: 1; } +:focus-visible { + order: 1; +} + .focus-visible, .focus-visible test, test .focus-visible, @@ -19,6 +23,23 @@ test :matches(test .focus-visible .focus-visible test) test { order: 2; } +:focus-visible, +:focus-visible test, +test :focus-visible, +test test:focus-visible, +test :focus-visible test, +test test:focus-visible test, +test :focus-visible :focus-visible test, +test :matches(:focus-visible) test, +test :matches(:focus-visible test) test, +test :matches(test :focus-visible) test, +test :matches(test test:focus-visible) test, +test :matches(test :focus-visible test) test, +test :matches(test test:focus-visible test) test, +test :matches(test :focus-visible :focus-visible test) test { + order: 2; +} + :ignore-focus-visible, :focus-visible-ignore, :ignorefocus-visible, diff --git a/test/basic.preserve.expect.css b/test/basic.preserve.expect.css new file mode 100644 index 0000000000..6a85671726 --- /dev/null +++ b/test/basic.preserve.expect.css @@ -0,0 +1,27 @@ +.focus-visible { + order: 1; +} + +.focus-visible, +.focus-visible test, +test .focus-visible, +test test.focus-visible, +test .focus-visible test, +test test.focus-visible test, +test .focus-visible .focus-visible test, +test :matches(.focus-visible) test, +test :matches(.focus-visible test) test, +test :matches(test .focus-visible) test, +test :matches(test test.focus-visible) test, +test :matches(test .focus-visible test) test, +test :matches(test test.focus-visible test) test, +test :matches(test .focus-visible .focus-visible test) test { + order: 2; +} + +:ignore-focus-visible, +:focus-visible-ignore, +:ignorefocus-visible, +:focus-visibleignore { + order: 3; +} diff --git a/test/basic.replacewith.expect.css b/test/basic.replacewith.expect.css index a37c668807..10a0675006 100644 --- a/test/basic.replacewith.expect.css +++ b/test/basic.replacewith.expect.css @@ -1,21 +1,42 @@ -[data-focus-visible-added] { +[focus-visible] { order: 1; } -[data-focus-visible-added], -[data-focus-visible-added] test, -test [data-focus-visible-added], -test test[data-focus-visible-added], -test [data-focus-visible-added] test, -test test[data-focus-visible-added] test, -test [data-focus-visible-added] [data-focus-visible-added] test, -test :matches([data-focus-visible-added]) test, -test :matches([data-focus-visible-added] test) test, -test :matches(test [data-focus-visible-added]) test, -test :matches(test test[data-focus-visible-added]) test, -test :matches(test [data-focus-visible-added] test) test, -test :matches(test test[data-focus-visible-added] test) test, -test :matches(test [data-focus-visible-added] [data-focus-visible-added] test) test { +:focus-visible { + order: 1; +} + +[focus-visible], +[focus-visible] test, +test [focus-visible], +test test[focus-visible], +test [focus-visible] test, +test test[focus-visible] test, +test [focus-visible] [focus-visible] test, +test :matches([focus-visible]) test, +test :matches([focus-visible] test) test, +test :matches(test [focus-visible]) test, +test :matches(test test[focus-visible]) test, +test :matches(test [focus-visible] test) test, +test :matches(test test[focus-visible] test) test, +test :matches(test [focus-visible] [focus-visible] test) test { + order: 2; +} + +:focus-visible, +:focus-visible test, +test :focus-visible, +test test:focus-visible, +test :focus-visible test, +test test:focus-visible test, +test :focus-visible :focus-visible test, +test :matches(:focus-visible) test, +test :matches(:focus-visible test) test, +test :matches(test :focus-visible) test, +test :matches(test test:focus-visible) test, +test :matches(test :focus-visible test) test, +test :matches(test test:focus-visible test) test, +test :matches(test :focus-visible :focus-visible test) test { order: 2; } diff --git a/test/basic.replacewith.result.css b/test/basic.replacewith.result.css index a37c668807..10a0675006 100644 --- a/test/basic.replacewith.result.css +++ b/test/basic.replacewith.result.css @@ -1,21 +1,42 @@ -[data-focus-visible-added] { +[focus-visible] { order: 1; } -[data-focus-visible-added], -[data-focus-visible-added] test, -test [data-focus-visible-added], -test test[data-focus-visible-added], -test [data-focus-visible-added] test, -test test[data-focus-visible-added] test, -test [data-focus-visible-added] [data-focus-visible-added] test, -test :matches([data-focus-visible-added]) test, -test :matches([data-focus-visible-added] test) test, -test :matches(test [data-focus-visible-added]) test, -test :matches(test test[data-focus-visible-added]) test, -test :matches(test [data-focus-visible-added] test) test, -test :matches(test test[data-focus-visible-added] test) test, -test :matches(test [data-focus-visible-added] [data-focus-visible-added] test) test { +:focus-visible { + order: 1; +} + +[focus-visible], +[focus-visible] test, +test [focus-visible], +test test[focus-visible], +test [focus-visible] test, +test test[focus-visible] test, +test [focus-visible] [focus-visible] test, +test :matches([focus-visible]) test, +test :matches([focus-visible] test) test, +test :matches(test [focus-visible]) test, +test :matches(test test[focus-visible]) test, +test :matches(test [focus-visible] test) test, +test :matches(test test[focus-visible] test) test, +test :matches(test [focus-visible] [focus-visible] test) test { + order: 2; +} + +:focus-visible, +:focus-visible test, +test :focus-visible, +test test:focus-visible, +test :focus-visible test, +test test:focus-visible test, +test :focus-visible :focus-visible test, +test :matches(:focus-visible) test, +test :matches(:focus-visible test) test, +test :matches(test :focus-visible) test, +test :matches(test test:focus-visible) test, +test :matches(test :focus-visible test) test, +test :matches(test test:focus-visible test) test, +test :matches(test :focus-visible :focus-visible test) test { order: 2; } diff --git a/test/basic.result.css b/test/basic.result.css index 6a85671726..0dfd32b804 100644 --- a/test/basic.result.css +++ b/test/basic.result.css @@ -2,6 +2,10 @@ order: 1; } +:focus-visible { + order: 1; +} + .focus-visible, .focus-visible test, test .focus-visible, @@ -19,6 +23,23 @@ test :matches(test .focus-visible .focus-visible test) test { order: 2; } +:focus-visible, +:focus-visible test, +test :focus-visible, +test test:focus-visible, +test :focus-visible test, +test test:focus-visible test, +test :focus-visible :focus-visible test, +test :matches(:focus-visible) test, +test :matches(:focus-visible test) test, +test :matches(test :focus-visible) test, +test :matches(test test:focus-visible) test, +test :matches(test :focus-visible test) test, +test :matches(test test:focus-visible test) test, +test :matches(test :focus-visible :focus-visible test) test { + order: 2; +} + :ignore-focus-visible, :focus-visible-ignore, :ignorefocus-visible, From 0bf934da640e3150c20056fc8242af8c64bac547 Mon Sep 17 00:00:00 2001 From: Aditya Agarwal Date: Sat, 14 Apr 2018 00:54:25 +0530 Subject: [PATCH 599/795] change "preserve-computed" to "computed" In my case "preserve-computed" didn't work although "computed" works. Please check if this is actually correct or not. --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 5b79d91db7..65397d8c07 100755 --- a/README.md +++ b/README.md @@ -198,12 +198,12 @@ h1 { } ``` -The option may also be set to `"preserve-computed"`, where Custom Properties +The option may also be set to `"computed"`, where Custom Properties will remain, but declarations containing `var()` will be removed: ```js postCSSCustomProperties({ - preserve: 'preserve-computed' + preserve: 'computed' }) ``` From 4f7ad3539491b6cd30f78f5e952b08763f62ffd5 Mon Sep 17 00:00:00 2001 From: Jonathan Neal Date: Mon, 23 Apr 2018 14:44:08 -0400 Subject: [PATCH 600/795] Update README.md cssdb badge --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 65397d8c07..87c354da8e 100755 --- a/README.md +++ b/README.md @@ -360,7 +360,7 @@ $ npm test [npm-url]: https://www.npmjs.com/package/postcss-custom-properties [npm-img]: https://img.shields.io/npm/v/postcss-custom-properties.svg [css-url]: https://jonathantneal.github.io/css-db/#css-variables -[css-img]: https://jonathantneal.github.io/css-db/badge/css-variables.svg +[css-img]: https://jonathantneal.github.io/cssdb/badge/custom-properties.svg [cli-url]: https://travis-ci.org/postcss/postcss-custom-properties [cli-img]: https://img.shields.io/travis/postcss/postcss-custom-properties.svg [git-url]: https://gitter.im/postcss/postcss From e94669854775e0669484ca2c5086f29b1564195c Mon Sep 17 00:00:00 2001 From: Jonathan Neal Date: Mon, 23 Apr 2018 14:46:10 -0400 Subject: [PATCH 601/795] Update README.md cssdb badge --- README.md | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index d27dc5ff22..fcf1d0f9d5 100644 --- a/README.md +++ b/README.md @@ -1,9 +1,10 @@ # PostCSS Focus Visible [PostCSS Logo][postcss] [![NPM Version][npm-img]][npm-url] +[![CSS Standard Status][css-img]][css-url] [![Build Status][cli-img]][cli-url] [![Windows Build Status][win-img]][win-url] -[![Gitter Chat][git-img]][git-url] +[![Support Chat][git-img]][git-url] [PostCSS Focus Visible] lets you use the `:focus-visible` pseudo-class in CSS, following the [Selectors Level 4 specification]. @@ -201,14 +202,16 @@ focusVisible({ replaceWith: '[focus-visible]' }); } ``` -[npm-url]: https://www.npmjs.com/package/postcss-focus-visible -[npm-img]: https://img.shields.io/npm/v/postcss-focus-visible.svg -[cli-url]: https://travis-ci.org/jonathantneal/postcss-focus-visible [cli-img]: https://img.shields.io/travis/jonathantneal/postcss-focus-visible.svg -[win-url]: https://ci.appveyor.com/project/jonathantneal/postcss-focus-visible -[win-img]: https://img.shields.io/appveyor/ci/jonathantneal/postcss-focus-visible.svg -[git-url]: https://gitter.im/postcss/postcss +[cli-url]: https://travis-ci.org/jonathantneal/postcss-focus-visible +[css-img]: https://jonathantneal.github.io/cssdb/badge/focus-within-pseudo-class.svg +[css-url]: https://jonathantneal.github.io/css-db/#css-variables [git-img]: https://img.shields.io/badge/support-chat-blue.svg +[git-url]: https://gitter.im/postcss/postcss +[npm-img]: https://img.shields.io/npm/v/postcss-focus-visible.svg +[npm-url]: https://www.npmjs.com/package/postcss-focus-visible +[win-img]: https://img.shields.io/appveyor/ci/jonathantneal/postcss-focus-visible.svg +[win-url]: https://ci.appveyor.com/project/jonathantneal/postcss-focus-visible [focus-visible polyfill]: https://github.com/WICG/focus-visible [Gulp PostCSS]: https://github.com/postcss/gulp-postcss From 2881ac97246ef14fcaebb6d94bac56830d0671d9 Mon Sep 17 00:00:00 2001 From: Jonathan Neal Date: Mon, 23 Apr 2018 14:48:37 -0400 Subject: [PATCH 602/795] Update README.md badges --- README.md | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index b2829b4245..4081d03e9e 100644 --- a/README.md +++ b/README.md @@ -1,9 +1,10 @@ # PostCSS color-mod() Function [PostCSS Logo][postcss] [![NPM Version][npm-img]][npm-url] -[![Linux Build Status][cli-img]][cli-url] +[![CSS Standard Status][css-img]][css-url] +[![Build Status][cli-img]][cli-url] [![Windows Build Status][win-img]][win-url] -[![Gitter Chat][git-img]][git-url] +[![Support Chat][git-img]][git-url] [PostCSS color-mod() Function] lets you modify colors using the `color-mod()` function in CSS, following the [CSS Color Module Level 4] specification. @@ -196,14 +197,16 @@ However, because these transformations occur at build time, they cannot be considered accurate. Accurately resolving cascading variables relies on knowledge of the living DOM tree. -[npm-url]: https://www.npmjs.com/package/postcss-color-mod-function -[npm-img]: https://img.shields.io/npm/v/postcss-color-mod-function.svg -[cli-url]: https://travis-ci.org/jonathantneal/postcss-color-mod-function [cli-img]: https://img.shields.io/travis/jonathantneal/postcss-color-mod-function.svg -[win-url]: https://ci.appveyor.com/project/jonathantneal/postcss-color-mod-function -[win-img]: https://img.shields.io/appveyor/ci/jonathantneal/postcss-color-mod-function.svg +[cli-url]: https://travis-ci.org/jonathantneal/postcss-color-mod-function +[css-img]: https://jonathantneal.github.io/cssdb/badge/color-mod-function.svg +[css-url]: https://jonathantneal.github.io/css-db/#css-variables +[git-img]: https://img.shields.io/badge/support-chat-blue.svg [git-url]: https://gitter.im/postcss/postcss -[git-img]: https://img.shields.io/badge/chat-gitter-blue.svg +[npm-img]: https://img.shields.io/npm/v/postcss-color-mod-function.svg +[npm-url]: https://www.npmjs.com/package/postcss-color-mod-function +[win-img]: https://img.shields.io/appveyor/ci/jonathantneal/postcss-color-mod-function.svg +[win-url]: https://ci.appveyor.com/project/jonathantneal/postcss-color-mod-function [CSS Color Module Level 4]: https://www.w3.org/TR/css-color-4/#funcdef-color-mod [Gulp PostCSS]: https://github.com/postcss/gulp-postcss From bdf0d110ec66c06814b4d15c63af3b21e0f9baa9 Mon Sep 17 00:00:00 2001 From: Jonathan Neal Date: Mon, 23 Apr 2018 14:52:00 -0400 Subject: [PATCH 603/795] Update README.md badges --- README.md | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index 0a358b5542..091b46a3cc 100644 --- a/README.md +++ b/README.md @@ -1,10 +1,9 @@ # :any-link [PostCSS Logo][postcss] -[![CSS Standard Status][css-img]][css-url] [![NPM Version][npm-img]][npm-url] +[![CSS Standard Status][css-img]][css-url] [![Build Status][cli-img]][cli-url] -[![Licensing][lic-img]][lic-url] -[![Gitter Chat][git-img]][git-url] +[![Support Chat][git-img]][git-url] [:any-link] lets you to use the proposed [`:any-link`] pseudo-class in CSS. @@ -129,16 +128,14 @@ Here are a few other ways to simulate the effect of [PostCSS Pseudo-Class Any-Li :link, :visited { /* ... */ } ``` -[cli-url]: https://travis-ci.org/jonathantneal/postcss-pseudo-class-any-link [cli-img]: https://img.shields.io/travis/jonathantneal/postcss-pseudo-class-any-link.svg -[css-url]: https://jonathantneal.github.io/css-db/#selectors-any-link-pseudo -[css-img]: https://jonathantneal.github.io/css-db/badge/selectors-any-link-pseudo.svg -[git-url]: https://gitter.im/postcss/postcss +[cli-url]: https://travis-ci.org/jonathantneal/postcss-pseudo-class-any-link +[css-img]: https://jonathantneal.github.io/cssdb/badge/any-link-pseudo-class.svg +[css-url]: https://jonathantneal.github.io/cssdb/#any-link-pseudo-class [git-img]: https://img.shields.io/badge/chat-gitter-blue.svg -[lic-url]: LICENSE.md -[lic-img]: https://img.shields.io/npm/l/postcss-pseudo-class-any-link.svg -[npm-url]: https://www.npmjs.com/package/postcss-pseudo-class-any-link +[git-url]: https://gitter.im/postcss/postcss [npm-img]: https://img.shields.io/npm/v/postcss-pseudo-class-any-link.svg +[npm-url]: https://www.npmjs.com/package/postcss-pseudo-class-any-link [`:any-link`]: http://dev.w3.org/csswg/selectors/#any-link-pseudo [`:link`]: http://dev.w3.org/csswg/selectors/#link-pseudo From 3cf40a4e891b3aa1849733e295a4507af33d93f4 Mon Sep 17 00:00:00 2001 From: Jonathan Neal Date: Mon, 23 Apr 2018 14:53:26 -0400 Subject: [PATCH 604/795] Update README.md badges --- README.md | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index a76d11d17c..2bf8aedfe7 100644 --- a/README.md +++ b/README.md @@ -1,10 +1,10 @@ # PostCSS Dir Pseudo Class [PostCSS Logo][postcss] -[![CSS Standard Status][css-img]][css-url] [![NPM Version][npm-img]][npm-url] +[![CSS Standard Status][css-img]][css-url] [![Build Status][cli-img]][cli-url] [![Windows Build Status][win-img]][win-url] -[![Gitter Chat][git-img]][git-url] +[![Support Chat][git-img]][git-url] [PostCSS Dir Pseudo Class] lets you use the `:dir()` pseudo-class to style by directionality in CSS, following the [Selectors Level 4] specification. @@ -210,16 +210,16 @@ html:not([dir="rtl"]) .example { The `preserve` option determines whether the original `:dir()` rule should remain in the CSS. By default, the rule is replaced by the fallback. -[css-img]: https://jonathantneal.github.io/css-db/badge/selectors-dir-pseudo.svg -[css-url]: https://jonathantneal.github.io/css-db/#selectors-dir-pseudo -[npm-url]: https://www.npmjs.com/package/postcss-dir-pseudo-class -[npm-img]: https://img.shields.io/npm/v/postcss-dir-pseudo-class.svg [cli-url]: https://travis-ci.org/jonathantneal/postcss-dir-pseudo-class [cli-img]: https://img.shields.io/travis/jonathantneal/postcss-dir-pseudo-class.svg +[css-img]: https://jonathantneal.github.io/cssdb/badge/dir-pseudo-class.svg +[css-url]: https://jonathantneal.github.io/cssdb/#dir-pseudo-class +[git-url]: https://gitter.im/postcss/postcss +[git-img]: https://img.shields.io/badge/support-chat-blue.svg +[npm-url]: https://www.npmjs.com/package/postcss-dir-pseudo-class +[npm-img]: https://img.shields.io/npm/v/postcss-dir-pseudo-class.svg [win-url]: https://ci.appveyor.com/project/jonathantneal/postcss-dir-pseudo-class [win-img]: https://img.shields.io/appveyor/ci/jonathantneal/postcss-dir-pseudo-class.svg -[git-url]: https://gitter.im/postcss/postcss -[git-img]: https://img.shields.io/badge/chat-gitter-blue.svg [Gulp PostCSS]: https://github.com/postcss/gulp-postcss [Grunt PostCSS]: https://github.com/nDmitry/grunt-postcss From 97a15c1673464804fd6c3c1d2dc8a86fde621f81 Mon Sep 17 00:00:00 2001 From: Jonathan Neal Date: Mon, 23 Apr 2018 14:55:11 -0400 Subject: [PATCH 605/795] Update README.md badges --- README.md | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index d0965b8672..50dd3f9ab6 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,7 @@ # PostCSS Focus Within [PostCSS Logo][postcss] [![NPM Version][npm-img]][npm-url] +[![CSS Standard Status][css-img]][css-url] [![Build Status][cli-img]][cli-url] [![Windows Build Status][win-img]][win-url] [![Gitter Chat][git-img]][git-url] @@ -201,14 +202,16 @@ focusWithin({ replaceWith: '.focus-within' }); } ``` -[npm-url]: https://www.npmjs.com/package/postcss-focus-within -[npm-img]: https://img.shields.io/npm/v/postcss-focus-within.svg -[cli-url]: https://travis-ci.org/jonathantneal/postcss-focus-within +[css-img]: https://jonathantneal.github.io/cssdb/badge/focus-within-pseudo-class.svg +[css-url]: https://jonathantneal.github.io/cssdb/#focus-within-pseudo-class [cli-img]: https://img.shields.io/travis/jonathantneal/postcss-focus-within.svg -[win-url]: https://ci.appveyor.com/project/jonathantneal/postcss-focus-within -[win-img]: https://img.shields.io/appveyor/ci/jonathantneal/postcss-focus-within.svg -[git-url]: https://gitter.im/postcss/postcss +[cli-url]: https://travis-ci.org/jonathantneal/postcss-focus-within [git-img]: https://img.shields.io/badge/support-chat-blue.svg +[git-url]: https://gitter.im/postcss/postcss +[npm-img]: https://img.shields.io/npm/v/postcss-focus-within.svg +[npm-url]: https://www.npmjs.com/package/postcss-focus-within +[win-img]: https://img.shields.io/appveyor/ci/jonathantneal/postcss-focus-within.svg +[win-url]: https://ci.appveyor.com/project/jonathantneal/postcss-focus-within [focus-within polyfill]: https://github.com/jonathantneal/focus-within [Gulp PostCSS]: https://github.com/postcss/gulp-postcss From c3c5e3d351e660b3afc67cf05509b4eebeb24ba2 Mon Sep 17 00:00:00 2001 From: Jonathan Neal Date: Mon, 23 Apr 2018 15:07:51 -0400 Subject: [PATCH 606/795] Update README.md badges --- README.md | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index 58fc9c6795..cfa6f4be8d 100644 --- a/README.md +++ b/README.md @@ -1,10 +1,10 @@ # PostCSS Logical Properties and Values [PostCSS Logo][postcss] -[![CSS Standard Status][css-img]][css-url] [![NPM Version][npm-img]][npm-url] +[![CSS Standard Status][css-img]][css-url] [![Build Status][cli-img]][cli-url] [![Windows Build Status][win-img]][win-url] -[![Gitter Chat][git-img]][git-url] +[![Support Chat][git-img]][git-url] [PostCSS Logical Properties and Values] lets you use logical, rather than physical, direction and dimension mappings in CSS, following the @@ -276,16 +276,16 @@ before logical declarations without replacing them. By default, directional fallbacks replace logical declaration. If `preserve` is defined as `true`, then the `dir` option will be ignored. -[cli-url]: https://travis-ci.org/jonathantneal/postcss-logical +[css-img]: https://jonathantneal.github.io/cssdb/badge/logical-properties-and-values.svg +[css-url]: https://jonathantneal.github.io/cssdb/#logical-properties-and-values [cli-img]: https://img.shields.io/travis/jonathantneal/postcss-logical.svg -[css-img]: https://jonathantneal.github.io/css-db/badge/css-logical.svg -[css-url]: https://jonathantneal.github.io/css-db/#css-logical +[cli-url]: https://travis-ci.org/jonathantneal/postcss-logical +[git-img]: https://img.shields.io/badge/support-chat-blue.svg [git-url]: https://gitter.im/postcss/postcss -[git-img]: https://img.shields.io/badge/chat-gitter-blue.svg -[npm-url]: https://www.npmjs.com/package/postcss-logical [npm-img]: https://img.shields.io/npm/v/postcss-logical.svg -[win-url]: https://ci.appveyor.com/project/jonathantneal/postcss-logical +[npm-url]: https://www.npmjs.com/package/postcss-logical [win-img]: https://img.shields.io/appveyor/ci/jonathantneal/postcss-logical.svg +[win-url]: https://ci.appveyor.com/project/jonathantneal/postcss-logical [CSS Logical Properties and Values]: https://drafts.csswg.org/css-logical/ [Gulp PostCSS]: https://github.com/postcss/gulp-postcss From 78f9cd13806177e41128c182a447a705b7befef3 Mon Sep 17 00:00:00 2001 From: Jonathan Neal Date: Mon, 23 Apr 2018 15:25:10 -0400 Subject: [PATCH 607/795] 5.0.0 --- .appveyor.yml | 18 +++++ .gitignore | 6 +- .rollup.js | 16 ++++ .travis.yml | 2 + CHANGELOG.md | 4 + LICENSE.md | 132 ++++++++++++++++--------------- README.md | 89 +++++++++++++++------ index.js | 12 +-- lib/clean-node.js | 2 +- lib/get-closest-rule.js | 4 +- lib/merge-params.js | 11 +-- lib/merge-selectors.js | 7 +- lib/transform-after-nodes.js | 7 +- lib/transform-before-nodes.js | 22 ++++++ lib/transform-bubbling-atrule.js | 11 ++- lib/transform-nesting-atrule.js | 20 ++--- lib/transform-nesting-rule.js | 13 ++- lib/transform.js | 15 ++-- package.json | 33 +++++--- 19 files changed, 265 insertions(+), 159 deletions(-) create mode 100644 .appveyor.yml create mode 100644 .rollup.js create mode 100644 lib/transform-before-nodes.js diff --git a/.appveyor.yml b/.appveyor.yml new file mode 100644 index 0000000000..acbf8a5eeb --- /dev/null +++ b/.appveyor.yml @@ -0,0 +1,18 @@ +# https://www.appveyor.com/docs/appveyor-yml + +environment: + matrix: + - nodejs_version: 4 + +version: "{build}" +build: off +deploy: off + +install: + - ps: Install-Product node $env:nodejs_version + - npm install --ignore-scripts + +test_script: + - node --version + - npm --version + - cmd: "npm test" diff --git a/.gitignore b/.gitignore index 995098afd2..de73e5a338 100644 --- a/.gitignore +++ b/.gitignore @@ -1,10 +1,12 @@ node_modules +index.*.js package-lock.json +*.log* +*.result.css .* !.appveyor.yml !.editorconfig !.gitignore +!.rollup.js !.tape.js !.travis.yml -*.log* -*.result.css diff --git a/.rollup.js b/.rollup.js new file mode 100644 index 0000000000..0436758216 --- /dev/null +++ b/.rollup.js @@ -0,0 +1,16 @@ +import babel from 'rollup-plugin-babel'; + +export default { + input: 'index.js', + output: [ + { file: 'index.cjs.js', format: 'cjs' }, + { file: 'index.es.js', format: 'es' } + ], + plugins: [ + babel({ + presets: [ + ['env', { modules: false, targets: { node: 4 } }] + ] + }) + ] +}; diff --git a/.travis.yml b/.travis.yml index d75992d613..c56466446c 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,7 +1,9 @@ # https://docs.travis-ci.com/user/travis-lint language: node_js + node_js: - 4 + install: - npm install --ignore-scripts diff --git a/CHANGELOG.md b/CHANGELOG.md index 8c36b5756c..15d3dd954e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # Changes to PostCSS Nesting +### 5.0.0 (March 24, 2018) + +- Refactored code to use Imports babel-transformed for Node v4 compatibility + ### 4.2.1 (September 19, 2017) - Updated: Exposing the transform function as its own for postcss-extend diff --git a/LICENSE.md b/LICENSE.md index ba9e7860ce..0bc1fa7060 100644 --- a/LICENSE.md +++ b/LICENSE.md @@ -30,77 +30,79 @@ effect of CC0 on those rights. protected by copyright and related or neighboring rights (“Copyright and Related Rights”). Copyright and Related Rights include, but are not limited to, the following: - 1. the right to reproduce, adapt, distribute, perform, display, - communicate, and translate a Work; - 2. moral rights retained by the original author(s) and/or performer(s); - 3. publicity and privacy rights pertaining to a person’s image or likeness - depicted in a Work; - 4. rights protecting against unfair competition in regards to a Work, - subject to the limitations in paragraph 4(i), below; - 5. rights protecting the extraction, dissemination, use and reuse of data - in a Work; - 6. database rights (such as those arising under Directive 96/9/EC of the - European Parliament and of the Council of 11 March 1996 on the legal - protection of databases, and under any national implementation thereof, - including any amended or successor version of such directive); and - 7. other similar, equivalent or corresponding rights throughout the world - based on applicable law or treaty, and any national implementations - thereof. + 1. the right to reproduce, adapt, distribute, perform, display, communicate, + and translate a Work; + 2. moral rights retained by the original author(s) and/or performer(s); + 3. publicity and privacy rights pertaining to a person’s image or likeness + depicted in a Work; + 4. rights protecting against unfair competition in regards to a Work, + subject to the limitations in paragraph 4(i), below; + 5. rights protecting the extraction, dissemination, use and reuse of data in + a Work; + 6. database rights (such as those arising under Directive 96/9/EC of the + European Parliament and of the Council of 11 March 1996 on the legal + protection of databases, and under any national implementation thereof, + including any amended or successor version of such directive); and + 7. other similar, equivalent or corresponding rights throughout the world + based on applicable law or treaty, and any national implementations + thereof. 2. Waiver. To the greatest extent permitted by, but not in contravention of, -applicable law, Affirmer hereby overtly, fully, permanently, irrevocably and -unconditionally waives, abandons, and surrenders all of Affirmer’s Copyright -and Related Rights and associated claims and causes of action, whether now -known or unknown (including existing as well as future claims and causes of -action), in the Work (i) in all territories worldwide, (ii) for the maximum -duration provided by applicable law or treaty (including future time -extensions), (iii) in any current or future medium and for any number of -copies, and (iv) for any purpose whatsoever, including without limitation -commercial, advertising or promotional purposes (the “Waiver”). Affirmer makes -the Waiver for the benefit of each member of the public at large and to the -detriment of Affirmer’s heirs and successors, fully intending that such Waiver -shall not be subject to revocation, rescission, cancellation, termination, or -any other legal or equitable action to disrupt the quiet enjoyment of the Work -by the public as contemplated by Affirmer’s express Statement of Purpose. + applicable law, Affirmer hereby overtly, fully, permanently, irrevocably and + unconditionally waives, abandons, and surrenders all of Affirmer’s Copyright + and Related Rights and associated claims and causes of action, whether now + known or unknown (including existing as well as future claims and causes of + action), in the Work (i) in all territories worldwide, (ii) for the maximum + duration provided by applicable law or treaty (including future time + extensions), (iii) in any current or future medium and for any number of + copies, and (iv) for any purpose whatsoever, including without limitation + commercial, advertising or promotional purposes (the “Waiver”). Affirmer + makes the Waiver for the benefit of each member of the public at large and + to the detriment of Affirmer’s heirs and successors, fully intending that + such Waiver shall not be subject to revocation, rescission, cancellation, + termination, or any other legal or equitable action to disrupt the quiet + enjoyment of the Work by the public as contemplated by Affirmer’s express + Statement of Purpose. 3. Public License Fallback. Should any part of the Waiver for any reason be -judged legally invalid or ineffective under applicable law, then the Waiver -shall be preserved to the maximum extent permitted taking into account -Affirmer’s express Statement of Purpose. In addition, to the extent the Waiver -is so judged Affirmer hereby grants to each affected person a royalty-free, non -transferable, non sublicensable, non exclusive, irrevocable and unconditional -license to exercise Affirmer’s Copyright and Related Rights in the Work (i) in -all territories worldwide, (ii) for the maximum duration provided by applicable -law or treaty (including future time extensions), (iii) in any current or -future medium and for any number of copies, and (iv) for any purpose -whatsoever, including without limitation commercial, advertising or promotional -purposes (the “License”). The License shall be deemed effective as of the date -CC0 was applied by Affirmer to the Work. Should any part of the License for any -reason be judged legally invalid or ineffective under applicable law, such -partial invalidity or ineffectiveness shall not invalidate the remainder of the -License, and in such case Affirmer hereby affirms that he or she will not (i) -exercise any of his or her remaining Copyright and Related Rights in the Work -or (ii) assert any associated claims and causes of action with respect to the -Work, in either case contrary to Affirmer’s express Statement of Purpose. + judged legally invalid or ineffective under applicable law, then the Waiver + shall be preserved to the maximum extent permitted taking into account + Affirmer’s express Statement of Purpose. In addition, to the extent the + Waiver is so judged Affirmer hereby grants to each affected person a + royalty-free, non transferable, non sublicensable, non exclusive, + irrevocable and unconditional license to exercise Affirmer’s Copyright and + Related Rights in the Work (i) in all territories worldwide, (ii) for the + maximum duration provided by applicable law or treaty (including future time + extensions), (iii) in any current or future medium and for any number of + copies, and (iv) for any purpose whatsoever, including without limitation + commercial, advertising or promotional purposes (the “License”). The License + shall be deemed effective as of the date CC0 was applied by Affirmer to the + Work. Should any part of the License for any reason be judged legally + invalid or ineffective under applicable law, such partial invalidity or + ineffectiveness shall not invalidate the remainder of the License, and in + such case Affirmer hereby affirms that he or she will not (i) exercise any + of his or her remaining Copyright and Related Rights in the Work or (ii) + assert any associated claims and causes of action with respect to the Work, + in either case contrary to Affirmer’s express Statement of Purpose. 4. Limitations and Disclaimers. - 1. No trademark or patent rights held by Affirmer are waived, abandoned, - surrendered, licensed or otherwise affected by this document. - 2. Affirmer offers the Work as-is and makes no representations or - warranties of any kind concerning the Work, express, implied, statutory - or otherwise, including without limitation warranties of title, - merchantability, fitness for a particular purpose, non infringement, or - the absence of latent or other defects, accuracy, or the present or - absence of errors, whether or not discoverable, all to the greatest - extent permissible under applicable law. - 3. Affirmer disclaims responsibility for clearing rights of other persons - that may apply to the Work or any use thereof, including without - limitation any person’s Copyright and Related Rights in the Work. - Further, Affirmer disclaims responsibility for obtaining any necessary - consents, permissions or other rights required for any use of the Work. - 4. Affirmer understands and acknowledges that Creative Commons is not a - party to this document and has no duty or obligation with respect to - this CC0 or use of the Work. + 1. No trademark or patent rights held by Affirmer are waived, abandoned, + surrendered, licensed or otherwise affected by this document. + 2. Affirmer offers the Work as-is and makes no representations or warranties + of any kind concerning the Work, express, implied, statutory or + otherwise, including without limitation warranties of title, + merchantability, fitness for a particular purpose, non infringement, or + the absence of latent or other defects, accuracy, or the present or + absence of errors, whether or not discoverable, all to the greatest + extent permissible under applicable law. + 3. Affirmer disclaims responsibility for clearing rights of other persons + that may apply to the Work or any use thereof, including without + limitation any person’s Copyright and Related Rights in the Work. + Further, Affirmer disclaims responsibility for obtaining any necessary + consents, permissions or other rights required for any use of the Work. + 4. Affirmer understands and acknowledges that Creative Commons is not a + party to this document and has no duty or obligation with respect to this + CC0 or use of the Work. For more information, please see http://creativecommons.org/publicdomain/zero/1.0/. diff --git a/README.md b/README.md index fd81abcea1..a82c8b4e2f 100644 --- a/README.md +++ b/README.md @@ -1,15 +1,15 @@ # PostCSS Nesting [PostCSS Logo][postcss] -[![CSS Standard Status][css-img]][css-url] [![NPM Version][npm-img]][npm-url] +[![CSS Standard Status][css-img]][css-url] [![Build Status][cli-img]][cli-url] -[![Licensing][lic-img]][lic-url] -[![Gitter Chat][git-img]][git-url] +[![Windows Build Status][win-img]][win-url] +[![Support Chat][git-img]][git-url] [PostCSS Nesting] lets you nest style rules inside each other, following the [CSS Nesting] specification. -```css +```pcss a, b { color: red; @@ -18,7 +18,7 @@ a, b { } } -/* after postcss-nesting */ +/* becomes */ a, b { color: red; @@ -42,7 +42,9 @@ npm install postcss-nesting --save-dev Use [PostCSS Nesting] to process your CSS: ```js -require('postcss-nesting').process(YOUR_CSS, { /* options */ }); +import postcssNesting from 'postcss-nesting'; + +postcssNesting.process(YOUR_CSS); ``` #### PostCSS @@ -56,9 +58,46 @@ npm install postcss --save-dev Use [PostCSS Nesting] as a plugin: ```js +import postcss from 'gulp-postcss'; +import postcssNesting from 'postcss-nesting'; + postcss([ - require('postcss-nesting')({ /* options */ }) -]).process(YOUR_CSS, /* options */); + postcssNesting(/* options */) +]).process(YOUR_CSS); +``` + +#### Webpack + +Add [PostCSS Loader] to your build tool: + +```bash +npm install postcss-loader --save-dev +``` + +Use [PostCSS Nesting] in your Webpack configuration: + +```js +import postcssNesting from 'postcss-nesting'; + +export default { + module: { + rules: [ + { + test: /\.css$/, + use: [ + 'style-loader', + { loader: 'css-loader', options: { importLoaders: 1 } }, + { loader: 'postcss-loader', options: { + ident: 'postcss', + plugins: () => [ + postcssNesting(/* options */) + ] + } } + ] + } + ] + } +} ``` #### Gulp @@ -72,17 +111,16 @@ npm install gulp-postcss --save-dev Use [PostCSS Nesting] in your Gulpfile: ```js -var postcss = require('gulp-postcss'); - -gulp.task('css', function () { - return gulp.src('./src/*.css').pipe( - postcss([ - require('postcss-nesting')({ /* options */ }) - ]) - ).pipe( - gulp.dest('.') - ); -}); +import postcss from 'gulp-postcss'; +import postcssNesting from 'postcss-nesting'; + +gulp.task('css', () => gulp.src('./src/*.css').pipe( + postcss([ + postcssNesting(/* options */) + ]) +).pipe( + gulp.dest('.') +)); ``` #### Grunt @@ -96,13 +134,15 @@ npm install grunt-postcss --save-dev Use [PostCSS Nesting] in your Gruntfile: ```js +import postcssNesting from 'postcss-nesting'; + grunt.loadNpmTasks('grunt-postcss'); grunt.initConfig({ postcss: { options: { use: [ - require('postcss-nesting')({ /* options */ }) + postcssNesting(/* options */) ] }, dist: { @@ -114,17 +154,18 @@ grunt.initConfig({ [cli-url]: https://travis-ci.org/jonathantneal/postcss-nesting [cli-img]: https://img.shields.io/travis/jonathantneal/postcss-nesting.svg -[css-img]: https://jonathantneal.github.io/css-db/badge/css-nesting.svg -[css-url]: https://jonathantneal.github.io/css-db/#css-nesting +[css-img]: https://jonathantneal.github.io/cssdb/badge/nesting-rules.svg +[css-url]: https://jonathantneal.github.io/cssdb/#nesting-rules [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-nesting.svg [npm-url]: https://www.npmjs.com/package/postcss-nesting [npm-img]: https://img.shields.io/npm/v/postcss-nesting.svg +[win-img]: https://img.shields.io/appveyor/ci/jonathantneal/postcss-nesting.svg +[win-url]: https://ci.appveyor.com/project/jonathantneal/postcss-nesting [CSS Nesting]: http://tabatkins.github.io/specs/css-nesting/ [Gulp PostCSS]: https://github.com/postcss/gulp-postcss [Grunt PostCSS]: https://github.com/nDmitry/grunt-postcss [PostCSS]: https://github.com/postcss/postcss +[PostCSS Loader]: https://github.com/postcss/postcss-loader [PostCSS Nesting]: https://github.com/jonathantneal/postcss-nesting diff --git a/index.js b/index.js index 710cada262..ae0d905f4b 100644 --- a/index.js +++ b/index.js @@ -1,10 +1,4 @@ -'use strict'; +import postcss from 'postcss'; +import transform from './lib/transform'; -// tooling -const postcss = require('postcss'); -const transform = require('./lib/transform'); - -// plugin -module.exports = postcss.plugin('postcss-nesting', () => { - return (root) => root.walk(transform); -}); +export default postcss.plugin('postcss-nesting', () => root => root.walk(transform)); diff --git a/lib/clean-node.js b/lib/clean-node.js index 9d430e9b59..369749a401 100644 --- a/lib/clean-node.js +++ b/lib/clean-node.js @@ -1,5 +1,5 @@ // clean the raws of the node -module.exports = (node) => { +export default node => { node.raws = Object.assign( node.raws.between ? { between: node.raws.between } : {}, node.raws.semicolon ? { semicolon: true } : {}, diff --git a/lib/get-closest-rule.js b/lib/get-closest-rule.js index 62b9bff5c2..780734b0af 100644 --- a/lib/get-closest-rule.js +++ b/lib/get-closest-rule.js @@ -1,7 +1,5 @@ -'use strict'; - // return the closest rule -module.exports = (node) => { +export default node => { let selectorParent = node.parent; while (selectorParent && selectorParent.type !== 'rule') { diff --git a/lib/merge-params.js b/lib/merge-params.js index b270a957ed..6b92943e5a 100644 --- a/lib/merge-params.js +++ b/lib/merge-params.js @@ -1,9 +1,10 @@ -// tooling -const comma = require('postcss').list.comma; +import { list } from 'postcss'; + +const { comma } = list; // merge params -module.exports = (fromParams, toParams) => comma(fromParams).map( - (params1) => comma(toParams).map( - (params2) => params1 + ' and ' + params2 +export default (fromParams, toParams) => comma(fromParams).map( + params1 => comma(toParams).map( + params2 => params1 + ' and ' + params2 ).join(', ') ).join(', '); diff --git a/lib/merge-selectors.js b/lib/merge-selectors.js index 376a5ce645..6840ac1544 100644 --- a/lib/merge-selectors.js +++ b/lib/merge-selectors.js @@ -1,11 +1,12 @@ // tooling -const comma = require('postcss').list.comma; +import { list } from 'postcss'; +const { comma } = list; // merge selectors -module.exports = (fromSelectors, toSelectors) => (typeof fromSelectors === 'string' ? comma(fromSelectors) : fromSelectors).reduce( +export default (fromSelectors, toSelectors) => (typeof fromSelectors === 'string' ? comma(fromSelectors) : fromSelectors).reduce( (selectors, fromSelector) => selectors.concat( (typeof toSelectors === 'string' ? comma(toSelectors) : toSelectors).map( - (toSelector) => toSelector.replace(/&/g, fromSelector) + toSelector => toSelector.replace(/&/g, fromSelector) ) ), [] diff --git a/lib/transform-after-nodes.js b/lib/transform-after-nodes.js index 7d6f0999ed..a1d7843518 100644 --- a/lib/transform-after-nodes.js +++ b/lib/transform-after-nodes.js @@ -1,8 +1,7 @@ -// tooling -const cleanNode = require('./clean-node'); +import cleanNode from './clean-node'; // move nodes after the current node into a cloned parent node -module.exports = (node) => { +export default node => { // affected nodes after the current node const affectedNodes = node.parent.nodes.slice(node.parent.nodes.indexOf(node) + 1).map(cleanNode); @@ -17,4 +16,6 @@ module.exports = (node) => { return afterParent; } + + return undefined; }; diff --git a/lib/transform-before-nodes.js b/lib/transform-before-nodes.js new file mode 100644 index 0000000000..b14ac2588d --- /dev/null +++ b/lib/transform-before-nodes.js @@ -0,0 +1,22 @@ +import cleanNode from './clean-node'; + +// move nodes after the current node into a cloned parent node +export default node => { + // affected nodes after the current node + const affectedNodes = node.parent.nodes.slice(0, node.parent.nodes.indexOf(node)).map(cleanNode); + + if (affectedNodes.length) { + // clone the current parent + const beforeParent = cleanNode(node.parent.clone()).removeAll(); + + // append the affected nodes to the parent clone + beforeParent.append(affectedNodes); + + // insert a parent clone before the current parent + node.parent.before(beforeParent); + + return beforeParent; + } + + return undefined; +}; diff --git a/lib/transform-bubbling-atrule.js b/lib/transform-bubbling-atrule.js index bf8e358892..6e119e990c 100644 --- a/lib/transform-bubbling-atrule.js +++ b/lib/transform-bubbling-atrule.js @@ -1,10 +1,9 @@ -// tooling -const cleanNode = require('./clean-node'); -const mergeParams = require('./merge-params'); -const transformAfterNodes = require('./transform-after-nodes'); +import cleanNode from './clean-node'; +import mergeParams from './merge-params'; +import transformAfterNodes from './transform-after-nodes'; // transform a bubbling atrule (e.g. @document, @media, @supports) -module.exports = (node) => { +export default node => { // clean node cleanNode(node); @@ -55,4 +54,4 @@ module.exports = (node) => { }; // whether the node is a bubbling atrule (e.g. @document, @media, @supports) -module.exports.test = (node, bubbles) => node.type === 'atrule' && ['document', 'media', 'supports'].indexOf(node.name) !== -1 && node.parent && node.parent.type === 'rule'; +export const test = node => node.type === 'atrule' && ['document', 'media', 'supports'].indexOf(node.name) !== -1 && node.parent && node.parent.type === 'rule'; diff --git a/lib/transform-nesting-atrule.js b/lib/transform-nesting-atrule.js index 739b4150b6..c655e484fb 100644 --- a/lib/transform-nesting-atrule.js +++ b/lib/transform-nesting-atrule.js @@ -1,13 +1,13 @@ -// tooling -const cleanNode = require('./clean-node'); -const comma = require('postcss').list.comma; -const getClosestRule = require('./get-closest-rule'); -const mergeSelectors = require('./merge-selectors'); -const postcss = require('postcss'); -const transformAfterNodes = require('./transform-after-nodes'); +import postcss, { list } from 'postcss'; +import cleanNode from './clean-node'; +import getClosestRule from './get-closest-rule'; +import mergeSelectors from './merge-selectors'; +import transformAfterNodes from './transform-after-nodes'; + +const { comma } = list; // transform a nesting atrule (e.g. @nest .something &) -module.exports = (node) => { +export default node => { // clean node and child nodes cleanNode(node).nodes.forEach(cleanNode); @@ -61,6 +61,6 @@ module.exports = (node) => { }; // whether the node is a nesting atrule (e.g. @nest .something &) -module.exports.test = (node) => node.type === 'atrule' && node.name === 'nest' && node.parent && node.parent.type === 'rule' && comma(node.params).every( - (selector) => selector.split('&').length === 2 && /&([^\w-|]|$)/.test(selector) +export const test = node => node.type === 'atrule' && node.name === 'nest' && node.parent && node.parent.type === 'rule' && comma(node.params).every( + selector => selector.split('&').length === 2 && /&([^\w-|]|$)/.test(selector) ); diff --git a/lib/transform-nesting-rule.js b/lib/transform-nesting-rule.js index 689528132f..8546d2f382 100644 --- a/lib/transform-nesting-rule.js +++ b/lib/transform-nesting-rule.js @@ -1,10 +1,9 @@ -// tooling -const cleanNode = require('./clean-node'); -const mergeSelectors = require('./merge-selectors'); -const transformAfterNodes = require('./transform-after-nodes'); +import cleanNode from './clean-node'; +import mergeSelectors from './merge-selectors'; +import transformAfterNodes from './transform-after-nodes'; // transform a nesting rule (e.g. &.something) -module.exports = (node) => { +export default node => { // clean node and child nodes cleanNode(node).nodes.forEach(cleanNode); @@ -24,6 +23,6 @@ module.exports = (node) => { }; // whether the node is a nesting rule (e.g. &.something) -module.exports.test = (node) => node.type === 'rule' && node.parent && node.parent.type === 'rule' && node.selectors.every( - (selector) => selector.trim().lastIndexOf('&') === 0 && /^&([^\w-|]|$)/.test(selector) +export const test = node => node.type === 'rule' && node.parent && node.parent.type === 'rule' && node.selectors.every( + selector => selector.trim().lastIndexOf('&') === 0 && /^&([^\w-|]|$)/.test(selector) ); diff --git a/lib/transform.js b/lib/transform.js index df9bd4fe43..ff5685b000 100644 --- a/lib/transform.js +++ b/lib/transform.js @@ -1,17 +1,16 @@ -// tooling -const transformBubblingAtrule = require('./transform-bubbling-atrule'); -const transformNestingAtRule = require('./transform-nesting-atrule'); -const transformNestingRule = require('./transform-nesting-rule'); +import transformBubblingAtrule, { test as transformBubblingAtruleTest } from './transform-bubbling-atrule'; +import transformNestingAtRule, { test as transformNestingAtRuleTest } from './transform-nesting-atrule'; +import transformNestingRule, { test as transformNestingRuleTest } from './transform-nesting-rule'; // conditionally transform a nesting rule -module.exports = (node) => { - if (transformBubblingAtrule.test(node)) { +export default node => { + if (transformBubblingAtruleTest(node)) { // conditionally transform a bubbling atrule transformBubblingAtrule(node); - } else if (transformNestingAtRule.test(node)) { + } else if (transformNestingAtRuleTest(node)) { // conditionally transform a nesting atrule transformNestingAtRule(node); - } else if (transformNestingRule.test(node)) { + } else if (transformNestingRuleTest(node)) { // conditionally transform a nesting rule transformNestingRule(node); } diff --git a/package.json b/package.json index 86995000b8..8f3653b391 100644 --- a/package.json +++ b/package.json @@ -1,38 +1,45 @@ { "name": "postcss-nesting", - "version": "4.2.1", - "description": "Nest style and media rules inside each another, following the CSS Nesting Module Level 3 specification", + "version": "5.0.0", + "description": "Nest style rules inside each other", "author": "Jonathan Neal ", "license": "CC0-1.0", "repository": "jonathantneal/postcss-nesting", "homepage": "https://github.com/jonathantneal/postcss-nesting#readme", "bugs": "https://github.com/jonathantneal/postcss-nesting/issues", - "main": "index.js", + "main": "index.cjs.js", + "module": "index.es.js", "files": [ - "index.js", - "lib" + "index.cjs.js", + "index.es.js" ], "scripts": { - "clean": "git clean -X -d -f", - "prepublish": "npm test", + "prepublishOnly": "npm test", + "pretest": "rollup -c .rollup.js --silent", "test": "echo 'Running tests...'; npm run test:js && npm run test:tape", - "test:js": "eslint *.js --cache --ignore-pattern .gitignore", + "test:js": "eslint *.js lib/*.js --cache --ignore-path .gitignore --quiet", "test:tape": "postcss-tape" }, "engines": { "node": ">=4.0.0" }, "dependencies": { - "postcss": "^6.0.11" + "postcss": "^6.0.21" }, "devDependencies": { - "eslint": "^4.7.1", + "babel-core": "^6.26.0", + "babel-eslint": "^8.2.3", + "babel-preset-env": "^1.6.1", + "eslint": "^4.19.1", "eslint-config-dev": "^2.0.0", - "postcss-tape": "^2.1.0", - "pre-commit": "^1.2.2" + "postcss-tape": "^2.2.0", + "pre-commit": "^1.2.2", + "rollup": "^0.58.2", + "rollup-plugin-babel": "^3.0.4" }, "eslintConfig": { - "extends": "dev" + "extends": "dev", + "parser": "babel-eslint" }, "keywords": [ "postcss", From c7f2f6c3fa4dc1feac82e5c4bc75aec33ee88e9d Mon Sep 17 00:00:00 2001 From: Jonathan Neal Date: Sat, 28 Apr 2018 15:02:04 -0400 Subject: [PATCH 608/795] 1.0.0 --- .appveyor.yml | 18 ++++ .editorconfig | 15 ++++ .gitignore | 12 +++ .rollup.js | 16 ++++ .tape.js | 13 +++ .travis.yml | 9 ++ CHANGELOG.md | 5 ++ CONTRIBUTING.md | 65 ++++++++++++++ LICENSE.md | 108 ++++++++++++++++++++++++ README.md | 169 +++++++++++++++++++++++++++++++++++++ index.js | 20 +++++ lib/get-fn-value.js | 8 ++ lib/get-replaced-value.js | 18 ++++ lib/get-supported-value.js | 5 ++ lib/is-atrule.js | 2 + lib/is-decl.js | 2 + lib/is-env-func.js | 2 + lib/replace-with-word.js | 8 ++ lib/set-supported-value.js | 13 +++ lib/update-env-value.js | 12 +++ lib/walk-env-funcs.js | 14 +++ package.json | 56 ++++++++++++ test/basic.css | 10 +++ test/basic.expect.css | 10 +++ 24 files changed, 610 insertions(+) create mode 100644 .appveyor.yml create mode 100644 .editorconfig create mode 100644 .gitignore create mode 100644 .rollup.js create mode 100644 .tape.js create mode 100644 .travis.yml create mode 100644 CHANGELOG.md create mode 100644 CONTRIBUTING.md create mode 100644 LICENSE.md create mode 100644 README.md create mode 100644 index.js create mode 100644 lib/get-fn-value.js create mode 100644 lib/get-replaced-value.js create mode 100644 lib/get-supported-value.js create mode 100644 lib/is-atrule.js create mode 100644 lib/is-decl.js create mode 100644 lib/is-env-func.js create mode 100644 lib/replace-with-word.js create mode 100644 lib/set-supported-value.js create mode 100644 lib/update-env-value.js create mode 100644 lib/walk-env-funcs.js create mode 100644 package.json create mode 100644 test/basic.css create mode 100644 test/basic.expect.css diff --git a/.appveyor.yml b/.appveyor.yml new file mode 100644 index 0000000000..acbf8a5eeb --- /dev/null +++ b/.appveyor.yml @@ -0,0 +1,18 @@ +# https://www.appveyor.com/docs/appveyor-yml + +environment: + matrix: + - nodejs_version: 4 + +version: "{build}" +build: off +deploy: off + +install: + - ps: Install-Product node $env:nodejs_version + - npm install --ignore-scripts + +test_script: + - node --version + - npm --version + - cmd: "npm test" diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000000..e06d7982bc --- /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/.gitignore b/.gitignore new file mode 100644 index 0000000000..de73e5a338 --- /dev/null +++ b/.gitignore @@ -0,0 +1,12 @@ +node_modules +index.*.js +package-lock.json +*.log* +*.result.css +.* +!.appveyor.yml +!.editorconfig +!.gitignore +!.rollup.js +!.tape.js +!.travis.yml diff --git a/.rollup.js b/.rollup.js new file mode 100644 index 0000000000..0436758216 --- /dev/null +++ b/.rollup.js @@ -0,0 +1,16 @@ +import babel from 'rollup-plugin-babel'; + +export default { + input: 'index.js', + output: [ + { file: 'index.cjs.js', format: 'cjs' }, + { file: 'index.es.js', format: 'es' } + ], + plugins: [ + babel({ + presets: [ + ['env', { modules: false, targets: { node: 4 } }] + ] + }) + ] +}; diff --git a/.tape.js b/.tape.js new file mode 100644 index 0000000000..f6b23c84a8 --- /dev/null +++ b/.tape.js @@ -0,0 +1,13 @@ +module.exports = { + 'postcss-env-function': { + 'basic': { + message: 'supports basic usage', + options: { + variables: { + '--some-custom-padding': '20px', + '--another-custom-width': '600px' + } + } + } + } +}; diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000000..c56466446c --- /dev/null +++ b/.travis.yml @@ -0,0 +1,9 @@ +# https://docs.travis-ci.com/user/travis-lint + +language: node_js + +node_js: + - 4 + +install: + - npm install --ignore-scripts diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000000..8bcc451ecb --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,5 @@ +# Changes to PostCSS Environment Variables + +### 1.0.0 (April 28, 2018) + +- Initial version diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 0000000000..69d4440fc8 --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,65 @@ +# Contributing to PostCSS Environment Variables + +You want to help? You rock! Now, take a moment to be sure your contributions +make sense to everyone else. + +## Reporting Issues + +Found a problem? Want a new feature? + +- See if your issue or idea has [already been reported]. +- Provide a [reduced test case] or a [live example]. + +Remember, a bug is a _demonstrable problem_ caused by _our_ code. + +## Submitting Pull Requests + +Pull requests are the greatest contributions, so be sure they are focused in +scope and avoid unrelated commits. + +1. To begin; [fork this project], clone your fork, and add our upstream. + ```bash + # Clone your fork of the repo into the current directory + git clone git@github.com:YOUR_USER/postcss-env-function.git + + # Navigate to the newly cloned directory + cd postcss-env-function + + # Assign the original repo to a remote called "upstream" + git remote add upstream git@github.com:jonathantneal/postcss-env-function.git + + # Install the tools necessary for testing + npm install + ``` + +2. Create a branch for your feature or fix: + ```bash + # Move into a new branch for your feature + git checkout -b feature/thing + ``` + ```bash + # Move into a new branch for your fix + git checkout -b fix/something + ``` + +3. If your code follows our practices, then push your feature branch: + ```bash + # Test current code + npm test + ``` + ```bash + # Push the branch for your new feature + git push origin feature/thing + ``` + ```bash + # Or, push the branch for your update + git push origin update/something + ``` + +That’s it! Now [open a pull request] with a clear title and description. + +[already been reported]: issues +[fork this project]: fork +[live example]: https://codepen.io/pen +[open a pull request]: https://help.github.com/articles/using-pull-requests/ +[reduced test case]: https://css-tricks.com/reduced-test-cases/ diff --git a/LICENSE.md b/LICENSE.md new file mode 100644 index 0000000000..0bc1fa7060 --- /dev/null +++ b/LICENSE.md @@ -0,0 +1,108 @@ +# CC0 1.0 Universal + +## Statement of Purpose + +The laws of most jurisdictions throughout the world automatically confer +exclusive Copyright and Related Rights (defined below) upon the creator and +subsequent owner(s) (each and all, an “owner”) of an original work of +authorship and/or a database (each, a “Work”). + +Certain owners wish to permanently relinquish those rights to a Work for the +purpose of contributing to a commons of creative, cultural and scientific works +(“Commons”) that the public can reliably and without fear of later claims of +infringement build upon, modify, incorporate in other works, reuse and +redistribute as freely as possible in any form whatsoever and for any purposes, +including without limitation commercial purposes. These owners may contribute +to the Commons to promote the ideal of a free culture and the further +production of creative, cultural and scientific works, or to gain reputation or +greater distribution for their Work in part through the use and efforts of +others. + +For these and/or other purposes and motivations, and without any expectation of +additional consideration or compensation, the person associating CC0 with a +Work (the “Affirmer”), to the extent that he or she is an owner of Copyright +and Related Rights in the Work, voluntarily elects to apply CC0 to the Work and +publicly distribute the Work under its terms, with knowledge of his or her +Copyright and Related Rights in the Work and the meaning and intended legal +effect of CC0 on those rights. + +1. Copyright and Related Rights. A Work made available under CC0 may be + protected by copyright and related or neighboring rights (“Copyright and + Related Rights”). Copyright and Related Rights include, but are not limited + to, the following: + 1. the right to reproduce, adapt, distribute, perform, display, communicate, + and translate a Work; + 2. moral rights retained by the original author(s) and/or performer(s); + 3. publicity and privacy rights pertaining to a person’s image or likeness + depicted in a Work; + 4. rights protecting against unfair competition in regards to a Work, + subject to the limitations in paragraph 4(i), below; + 5. rights protecting the extraction, dissemination, use and reuse of data in + a Work; + 6. database rights (such as those arising under Directive 96/9/EC of the + European Parliament and of the Council of 11 March 1996 on the legal + protection of databases, and under any national implementation thereof, + including any amended or successor version of such directive); and + 7. other similar, equivalent or corresponding rights throughout the world + based on applicable law or treaty, and any national implementations + thereof. + +2. Waiver. To the greatest extent permitted by, but not in contravention of, + applicable law, Affirmer hereby overtly, fully, permanently, irrevocably and + unconditionally waives, abandons, and surrenders all of Affirmer’s Copyright + and Related Rights and associated claims and causes of action, whether now + known or unknown (including existing as well as future claims and causes of + action), in the Work (i) in all territories worldwide, (ii) for the maximum + duration provided by applicable law or treaty (including future time + extensions), (iii) in any current or future medium and for any number of + copies, and (iv) for any purpose whatsoever, including without limitation + commercial, advertising or promotional purposes (the “Waiver”). Affirmer + makes the Waiver for the benefit of each member of the public at large and + to the detriment of Affirmer’s heirs and successors, fully intending that + such Waiver shall not be subject to revocation, rescission, cancellation, + termination, or any other legal or equitable action to disrupt the quiet + enjoyment of the Work by the public as contemplated by Affirmer’s express + Statement of Purpose. + +3. Public License Fallback. Should any part of the Waiver for any reason be + judged legally invalid or ineffective under applicable law, then the Waiver + shall be preserved to the maximum extent permitted taking into account + Affirmer’s express Statement of Purpose. In addition, to the extent the + Waiver is so judged Affirmer hereby grants to each affected person a + royalty-free, non transferable, non sublicensable, non exclusive, + irrevocable and unconditional license to exercise Affirmer’s Copyright and + Related Rights in the Work (i) in all territories worldwide, (ii) for the + maximum duration provided by applicable law or treaty (including future time + extensions), (iii) in any current or future medium and for any number of + copies, and (iv) for any purpose whatsoever, including without limitation + commercial, advertising or promotional purposes (the “License”). The License + shall be deemed effective as of the date CC0 was applied by Affirmer to the + Work. Should any part of the License for any reason be judged legally + invalid or ineffective under applicable law, such partial invalidity or + ineffectiveness shall not invalidate the remainder of the License, and in + such case Affirmer hereby affirms that he or she will not (i) exercise any + of his or her remaining Copyright and Related Rights in the Work or (ii) + assert any associated claims and causes of action with respect to the Work, + in either case contrary to Affirmer’s express Statement of Purpose. + +4. Limitations and Disclaimers. + 1. No trademark or patent rights held by Affirmer are waived, abandoned, + surrendered, licensed or otherwise affected by this document. + 2. Affirmer offers the Work as-is and makes no representations or warranties + of any kind concerning the Work, express, implied, statutory or + otherwise, including without limitation warranties of title, + merchantability, fitness for a particular purpose, non infringement, or + the absence of latent or other defects, accuracy, or the present or + absence of errors, whether or not discoverable, all to the greatest + extent permissible under applicable law. + 3. Affirmer disclaims responsibility for clearing rights of other persons + that may apply to the Work or any use thereof, including without + limitation any person’s Copyright and Related Rights in the Work. + Further, Affirmer disclaims responsibility for obtaining any necessary + consents, permissions or other rights required for any use of the Work. + 4. Affirmer understands and acknowledges that Creative Commons is not a + party to this document and has no duty or obligation with respect to this + CC0 or use of the Work. + +For more information, please see +http://creativecommons.org/publicdomain/zero/1.0/. diff --git a/README.md b/README.md new file mode 100644 index 0000000000..a0c72b5549 --- /dev/null +++ b/README.md @@ -0,0 +1,169 @@ +# PostCSS Environment Variables [PostCSS Logo][postcss] + +[![NPM Version][npm-img]][npm-url] +[![Build Status][cli-img]][cli-url] +[![Windows Build Status][win-img]][win-url] +[![Support Chat][git-img]][git-url] + +[PostCSS Environment Variables] lets you use `env()` variables in CSS, +following the [CSS Environment Variables] specification. + +```pcss +@media (max-width: env(--branding-small)) { + body { + padding: env(--branding-padding); + } +} + +/* becomes */ + +@media (min-width: 600px) { + body { + padding: 20px; + } +} + +/* when the `variables` option is: { + "--branding-small": "600px", + "--branding-padding": "20px" +} */ +``` + +## Usage + +Add [PostCSS Environment Variables] to your build tool: + +```bash +npm install postcss-env-function --save-dev +``` + +#### Node + +Use [PostCSS Environment Variables] to process your CSS: + +```js +import postcssEnvFunction from 'postcss-env-function'; + +postcssEnvFunction.process(YOUR_CSS, /* processOptions */, /* pluginOptions */); +``` + +#### PostCSS + +Add [PostCSS] to your build tool: + +```bash +npm install postcss --save-dev +``` + +Use [PostCSS Environment Variables] as a plugin: + +```js +import postcss from 'gulp-postcss'; +import postcssEnvFunction from 'postcss-env-function'; + +postcss([ + postcssEnvFunction(/* pluginOptions */) +]).process(YOUR_CSS); +``` + +#### Webpack + +Add [PostCSS Loader] to your build tool: + +```bash +npm install postcss-loader --save-dev +``` + +Use [PostCSS Environment Variables] in your Webpack configuration: + +```js +import postcssEnvFunction from 'postcss-env-function'; + +module.exports = { + module: { + rules: [ + { + test: /\.css$/, + use: [ + 'style-loader', + { loader: 'css-loader', options: { importLoaders: 1 } }, + { loader: 'postcss-loader', options: { + ident: 'postcss', + plugins: () => [ + postcssEnvFunction(/* pluginOptions */) + ] + } } + ] + } + ] + } +} +``` + +#### Gulp + +Add [Gulp PostCSS] to your build tool: + +```bash +npm install gulp-postcss --save-dev +``` + +Use [PostCSS Environment Variables] in your Gulpfile: + +```js +import postcss from 'gulp-postcss'; +import postcssEnvFunction from 'postcss-env-function'; + +gulp.task('css', () => gulp.src('./src/*.css').pipe( + postcss([ + postcssEnvFunction(/* pluginOptions */) + ]) +).pipe( + gulp.dest('.') +)); +``` + +#### Grunt + +Add [Grunt PostCSS] to your build tool: + +```bash +npm install grunt-postcss --save-dev +``` + +Use [PostCSS Environment Variables] in your Gruntfile: + +```js +import postcssEnvFunction from 'postcss-env-function'; + +grunt.loadNpmTasks('grunt-postcss'); + +grunt.initConfig({ + postcss: { + options: { + use: [ + postcssEnvFunction(/* pluginOptions */) + ] + }, + dist: { + src: '*.css' + } + } +}); +``` + +[cli-img]: https://img.shields.io/travis/jonathantneal/postcss-env-function.svg +[cli-url]: https://travis-ci.org/jonathantneal/postcss-env-function +[git-img]: https://img.shields.io/badge/support-chat-blue.svg +[git-url]: https://gitter.im/postcss/postcss +[npm-img]: https://img.shields.io/npm/v/postcss-env-function.svg +[npm-url]: https://www.npmjs.com/package/postcss-env-function +[win-img]: https://img.shields.io/appveyor/ci/jonathantneal/postcss-env-function.svg +[win-url]: https://ci.appveyor.com/project/jonathantneal/postcss-env-function + +[CSS Environment Variables]: https://drafts.csswg.org/css-env-1/ +[Gulp PostCSS]: https://github.com/postcss/gulp-postcss +[Grunt PostCSS]: https://github.com/nDmitry/grunt-postcss +[PostCSS]: https://github.com/postcss/postcss +[PostCSS Environment Variables]: https://github.com/jonathantneal/postcss-env-function +[PostCSS Loader]: https://github.com/postcss/postcss-loader diff --git a/index.js b/index.js new file mode 100644 index 0000000000..f458df64a3 --- /dev/null +++ b/index.js @@ -0,0 +1,20 @@ +import postcss from 'postcss'; +import getReplacedValue from './lib/get-replaced-value'; +import getSupportedValue from './lib/get-supported-value'; +import setSupportedValue from './lib/set-supported-value'; + +export default postcss.plugin('postcss-env-fn', opts => root => { + const variables = Object(Object(opts).variables); + + root.walk(node => { + const supportedValue = getSupportedValue(node); + + if (supportedValue) { + const replacedValue = getReplacedValue(supportedValue, variables); + + if (replacedValue !== supportedValue) { + setSupportedValue(node, replacedValue); + } + } + }); +}); diff --git a/lib/get-fn-value.js b/lib/get-fn-value.js new file mode 100644 index 0000000000..1f61a05404 --- /dev/null +++ b/lib/get-fn-value.js @@ -0,0 +1,8 @@ +const dashedMatch = /^--/; + +// returns the value of a css function as a string +export default (node) => { + const value = String(node.nodes.slice(1, -1)); + + return dashedMatch.test(value) ? value : undefined; +}; diff --git a/lib/get-replaced-value.js b/lib/get-replaced-value.js new file mode 100644 index 0000000000..32b166c0f6 --- /dev/null +++ b/lib/get-replaced-value.js @@ -0,0 +1,18 @@ +import parser from 'postcss-values-parser'; +import updateEnvValue from './update-env-value'; +import walkEnvFuncs from './walk-env-funcs'; + +// returns a value replaced with environment variables +export default (originalValue, variables) => { + // get the ast of the original value + const ast = parser(originalValue).parse(); + + // walk all of the css env() functions + walkEnvFuncs(ast, node => { + // update the environment value for the css env() function + updateEnvValue(node, variables); + }); + + // return the stringified ast + return String(ast); +}; diff --git a/lib/get-supported-value.js b/lib/get-supported-value.js new file mode 100644 index 0000000000..1bbc83ffe3 --- /dev/null +++ b/lib/get-supported-value.js @@ -0,0 +1,5 @@ +import isAtrule from './is-atrule'; +import isDecl from './is-decl'; + +// returns a value from an at-rule or declaration +export default (node) => isAtrule(node) && node.params || isDecl(node) && node.value; diff --git a/lib/is-atrule.js b/lib/is-atrule.js new file mode 100644 index 0000000000..233a7a1497 --- /dev/null +++ b/lib/is-atrule.js @@ -0,0 +1,2 @@ +// returns whether a node is an at-rule +export default (node) => node && node.type === 'atrule'; diff --git a/lib/is-decl.js b/lib/is-decl.js new file mode 100644 index 0000000000..1b362848fb --- /dev/null +++ b/lib/is-decl.js @@ -0,0 +1,2 @@ +// returns whether a node is a declaration +export default (node) => node && node.type === 'decl'; diff --git a/lib/is-env-func.js b/lib/is-env-func.js new file mode 100644 index 0000000000..ac3da5ab42 --- /dev/null +++ b/lib/is-env-func.js @@ -0,0 +1,2 @@ +// returns whether a node is a css env() function +export default (node) => node && node.type === 'func' && node.value === 'env'; diff --git a/lib/replace-with-word.js b/lib/replace-with-word.js new file mode 100644 index 0000000000..59800c1a94 --- /dev/null +++ b/lib/replace-with-word.js @@ -0,0 +1,8 @@ +import parser from 'postcss-values-parser'; + +// replaces a node with a word node +export default function (node, value) { + const raws = node.raws; + + node.replaceWith(parser.word({ value, raws })); +} diff --git a/lib/set-supported-value.js b/lib/set-supported-value.js new file mode 100644 index 0000000000..c7fb8ae273 --- /dev/null +++ b/lib/set-supported-value.js @@ -0,0 +1,13 @@ +import isAtrule from './is-atrule'; +import isDecl from './is-decl'; + +// assigns a value to an at-rule or declaration +export default function (node, value) { + if (isAtrule(node)) { + node.params = value; + } + + if (isDecl(node)) { + node.value = value; + } +} diff --git a/lib/update-env-value.js b/lib/update-env-value.js new file mode 100644 index 0000000000..89523f07ee --- /dev/null +++ b/lib/update-env-value.js @@ -0,0 +1,12 @@ +import getFnValue from './get-fn-value'; +import replaceWithWord from './replace-with-word'; + +// update a node with an environment value +export default function (node, variables) { + // get the value of a css function as a string + const value = getFnValue(node); + + if (typeof value === 'string') { + replaceWithWord(node, variables[value]) + } +} diff --git a/lib/walk-env-funcs.js b/lib/walk-env-funcs.js new file mode 100644 index 0000000000..a70952750e --- /dev/null +++ b/lib/walk-env-funcs.js @@ -0,0 +1,14 @@ +import isEnvFunc from './is-env-func'; + +// walks a node recursively and runs a function using its children +export default function walk(node, fn) { + node.nodes.slice(0).forEach(childNode => { + if (childNode.nodes) { + walk(childNode, fn); + } + + if (isEnvFunc(childNode)) { + fn(childNode); + } + }); +} diff --git a/package.json b/package.json new file mode 100644 index 0000000000..87c6e92f19 --- /dev/null +++ b/package.json @@ -0,0 +1,56 @@ +{ + "name": "postcss-env-function", + "version": "1.0.0", + "description": "", + "author": "Jonathan Neal ", + "license": "CC0-1.0", + "repository": "jonathantneal/postcss-env-function", + "homepage": "https://github.com/jonathantneal/postcss-env-function#readme", + "bugs": "https://github.com/jonathantneal/postcss-env-function/issues", + "main": "index.cjs.js", + "module": "index.es.js", + "files": [ + "index.cjs.js", + "index.es.js" + ], + "scripts": { + "prepublishOnly": "npm test", + "pretest": "rollup -c .rollup.js --silent", + "test": "echo 'Running tests...'; npm run test:js && npm run test:tape", + "test:ec": "echint --ignore index.*.js test", + "test:js": "eslint *.js --cache --ignore-path .gitignore --quiet", + "test:tape": "postcss-tape" + }, + "engines": { + "node": ">=4.0.0" + }, + "dependencies": { + "postcss": "^6.0.22", + "postcss-values-parser": "^1.5.0" + }, + "devDependencies": { + "babel-core": "^6.26.3", + "babel-eslint": "^8.2.3", + "babel-preset-env": "^1.6.1", + "eslint": "^4.19.1", + "eslint-config-dev": "^2.0.0", + "postcss-tape": "^2.2.0", + "pre-commit": "^1.2.2", + "rollup": "^0.58.2", + "rollup-plugin-babel": "^3.0.4" + }, + "eslintConfig": { + "extends": "dev", + "parser": "babel-eslint" + }, + "keywords": [ + "postcss", + "css", + "postcss-plugin", + "environments", + "variables", + "envs", + "constants", + "functions" + ] +} diff --git a/test/basic.css b/test/basic.css new file mode 100644 index 0000000000..5199c9faee --- /dev/null +++ b/test/basic.css @@ -0,0 +1,10 @@ +body { + order: 1; + padding: env(--some-custom-padding); +} + +@media (min-width: env(--another-custom-width)) { + body { + order: 2; + } +} diff --git a/test/basic.expect.css b/test/basic.expect.css new file mode 100644 index 0000000000..762c0d04a7 --- /dev/null +++ b/test/basic.expect.css @@ -0,0 +1,10 @@ +body { + order: 1; + padding: 20px; +} + +@media (min-width: 600px) { + body { + order: 2; + } +} From caa500944bf6fa35158267b1e126cc111fc2bdca Mon Sep 17 00:00:00 2001 From: Jonathan Neal Date: Mon, 30 Apr 2018 22:35:06 -0400 Subject: [PATCH 609/795] 1.0.0 --- .appveyor.yml | 18 +++ .editorconfig | 15 +++ .gitignore | 12 ++ .rollup.js | 16 +++ .tape.js | 13 ++ .travis.yml | 9 ++ CHANGELOG.md | 5 + CONTRIBUTING.md | 65 ++++++++++ LICENSE.md | 108 ++++++++++++++++ README.md | 179 +++++++++++++++++++++++++++ index.js | 23 ++++ package.json | 57 +++++++++ test/basic.css | 9 ++ test/basic.expect.css | 12 ++ test/basic.preserve-false.expect.css | 9 ++ 15 files changed, 550 insertions(+) create mode 100644 .appveyor.yml create mode 100644 .editorconfig create mode 100644 .gitignore create mode 100644 .rollup.js create mode 100644 .tape.js create mode 100644 .travis.yml create mode 100644 CHANGELOG.md create mode 100644 CONTRIBUTING.md create mode 100644 LICENSE.md create mode 100644 README.md create mode 100644 index.js create mode 100644 package.json create mode 100644 test/basic.css create mode 100644 test/basic.expect.css create mode 100644 test/basic.preserve-false.expect.css diff --git a/.appveyor.yml b/.appveyor.yml new file mode 100644 index 0000000000..acbf8a5eeb --- /dev/null +++ b/.appveyor.yml @@ -0,0 +1,18 @@ +# https://www.appveyor.com/docs/appveyor-yml + +environment: + matrix: + - nodejs_version: 4 + +version: "{build}" +build: off +deploy: off + +install: + - ps: Install-Product node $env:nodejs_version + - npm install --ignore-scripts + +test_script: + - node --version + - npm --version + - cmd: "npm test" diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000000..e06d7982bc --- /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/.gitignore b/.gitignore new file mode 100644 index 0000000000..de73e5a338 --- /dev/null +++ b/.gitignore @@ -0,0 +1,12 @@ +node_modules +index.*.js +package-lock.json +*.log* +*.result.css +.* +!.appveyor.yml +!.editorconfig +!.gitignore +!.rollup.js +!.tape.js +!.travis.yml diff --git a/.rollup.js b/.rollup.js new file mode 100644 index 0000000000..0436758216 --- /dev/null +++ b/.rollup.js @@ -0,0 +1,16 @@ +import babel from 'rollup-plugin-babel'; + +export default { + input: 'index.js', + output: [ + { file: 'index.cjs.js', format: 'cjs' }, + { file: 'index.es.js', format: 'es' } + ], + plugins: [ + babel({ + presets: [ + ['env', { modules: false, targets: { node: 4 } }] + ] + }) + ] +}; diff --git a/.tape.js b/.tape.js new file mode 100644 index 0000000000..96c94d1f25 --- /dev/null +++ b/.tape.js @@ -0,0 +1,13 @@ +module.exports = { + 'postcss-gap-properties': { + 'basic': { + message: 'supports basic usage' + }, + 'basic:preserve-false': { + message: 'supports { preserve: false } usage', + options: { + preserve: false + } + } + } +}; diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000000..c56466446c --- /dev/null +++ b/.travis.yml @@ -0,0 +1,9 @@ +# https://docs.travis-ci.com/user/travis-lint + +language: node_js + +node_js: + - 4 + +install: + - npm install --ignore-scripts diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000000..81c24bbdb6 --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,5 @@ +# Changes to PostCSS Gap Properties + +### 1.0.0 (April 30, 2018) + +- Initial version diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 0000000000..1dee17f1b8 --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,65 @@ +# Contributing to PostCSS Gap Properties + +You want to help? You rock! Now, take a moment to be sure your contributions +make sense to everyone else. + +## Reporting Issues + +Found a problem? Want a new feature? + +- See if your issue or idea has [already been reported]. +- Provide a [reduced test case] or a [live example]. + +Remember, a bug is a _demonstrable problem_ caused by _our_ code. + +## Submitting Pull Requests + +Pull requests are the greatest contributions, so be sure they are focused in +scope and avoid unrelated commits. + +1. To begin; [fork this project], clone your fork, and add our upstream. + ```bash + # Clone your fork of the repo into the current directory + git clone git@github.com:YOUR_USER/postcss-gap-properties.git + + # Navigate to the newly cloned directory + cd postcss-gap-properties + + # Assign the original repo to a remote called "upstream" + git remote add upstream git@github.com:jonathantneal/postcss-gap-properties.git + + # Install the tools necessary for testing + npm install + ``` + +2. Create a branch for your feature or fix: + ```bash + # Move into a new branch for your feature + git checkout -b feature/thing + ``` + ```bash + # Move into a new branch for your fix + git checkout -b fix/something + ``` + +3. If your code follows our practices, then push your feature branch: + ```bash + # Test current code + npm test + ``` + ```bash + # Push the branch for your new feature + git push origin feature/thing + ``` + ```bash + # Or, push the branch for your update + git push origin update/something + ``` + +That’s it! Now [open a pull request] with a clear title and description. + +[already been reported]: issues +[fork this project]: fork +[live example]: https://codepen.io/pen +[open a pull request]: https://help.github.com/articles/using-pull-requests/ +[reduced test case]: https://css-tricks.com/reduced-test-cases/ diff --git a/LICENSE.md b/LICENSE.md new file mode 100644 index 0000000000..0bc1fa7060 --- /dev/null +++ b/LICENSE.md @@ -0,0 +1,108 @@ +# CC0 1.0 Universal + +## Statement of Purpose + +The laws of most jurisdictions throughout the world automatically confer +exclusive Copyright and Related Rights (defined below) upon the creator and +subsequent owner(s) (each and all, an “owner”) of an original work of +authorship and/or a database (each, a “Work”). + +Certain owners wish to permanently relinquish those rights to a Work for the +purpose of contributing to a commons of creative, cultural and scientific works +(“Commons”) that the public can reliably and without fear of later claims of +infringement build upon, modify, incorporate in other works, reuse and +redistribute as freely as possible in any form whatsoever and for any purposes, +including without limitation commercial purposes. These owners may contribute +to the Commons to promote the ideal of a free culture and the further +production of creative, cultural and scientific works, or to gain reputation or +greater distribution for their Work in part through the use and efforts of +others. + +For these and/or other purposes and motivations, and without any expectation of +additional consideration or compensation, the person associating CC0 with a +Work (the “Affirmer”), to the extent that he or she is an owner of Copyright +and Related Rights in the Work, voluntarily elects to apply CC0 to the Work and +publicly distribute the Work under its terms, with knowledge of his or her +Copyright and Related Rights in the Work and the meaning and intended legal +effect of CC0 on those rights. + +1. Copyright and Related Rights. A Work made available under CC0 may be + protected by copyright and related or neighboring rights (“Copyright and + Related Rights”). Copyright and Related Rights include, but are not limited + to, the following: + 1. the right to reproduce, adapt, distribute, perform, display, communicate, + and translate a Work; + 2. moral rights retained by the original author(s) and/or performer(s); + 3. publicity and privacy rights pertaining to a person’s image or likeness + depicted in a Work; + 4. rights protecting against unfair competition in regards to a Work, + subject to the limitations in paragraph 4(i), below; + 5. rights protecting the extraction, dissemination, use and reuse of data in + a Work; + 6. database rights (such as those arising under Directive 96/9/EC of the + European Parliament and of the Council of 11 March 1996 on the legal + protection of databases, and under any national implementation thereof, + including any amended or successor version of such directive); and + 7. other similar, equivalent or corresponding rights throughout the world + based on applicable law or treaty, and any national implementations + thereof. + +2. Waiver. To the greatest extent permitted by, but not in contravention of, + applicable law, Affirmer hereby overtly, fully, permanently, irrevocably and + unconditionally waives, abandons, and surrenders all of Affirmer’s Copyright + and Related Rights and associated claims and causes of action, whether now + known or unknown (including existing as well as future claims and causes of + action), in the Work (i) in all territories worldwide, (ii) for the maximum + duration provided by applicable law or treaty (including future time + extensions), (iii) in any current or future medium and for any number of + copies, and (iv) for any purpose whatsoever, including without limitation + commercial, advertising or promotional purposes (the “Waiver”). Affirmer + makes the Waiver for the benefit of each member of the public at large and + to the detriment of Affirmer’s heirs and successors, fully intending that + such Waiver shall not be subject to revocation, rescission, cancellation, + termination, or any other legal or equitable action to disrupt the quiet + enjoyment of the Work by the public as contemplated by Affirmer’s express + Statement of Purpose. + +3. Public License Fallback. Should any part of the Waiver for any reason be + judged legally invalid or ineffective under applicable law, then the Waiver + shall be preserved to the maximum extent permitted taking into account + Affirmer’s express Statement of Purpose. In addition, to the extent the + Waiver is so judged Affirmer hereby grants to each affected person a + royalty-free, non transferable, non sublicensable, non exclusive, + irrevocable and unconditional license to exercise Affirmer’s Copyright and + Related Rights in the Work (i) in all territories worldwide, (ii) for the + maximum duration provided by applicable law or treaty (including future time + extensions), (iii) in any current or future medium and for any number of + copies, and (iv) for any purpose whatsoever, including without limitation + commercial, advertising or promotional purposes (the “License”). The License + shall be deemed effective as of the date CC0 was applied by Affirmer to the + Work. Should any part of the License for any reason be judged legally + invalid or ineffective under applicable law, such partial invalidity or + ineffectiveness shall not invalidate the remainder of the License, and in + such case Affirmer hereby affirms that he or she will not (i) exercise any + of his or her remaining Copyright and Related Rights in the Work or (ii) + assert any associated claims and causes of action with respect to the Work, + in either case contrary to Affirmer’s express Statement of Purpose. + +4. Limitations and Disclaimers. + 1. No trademark or patent rights held by Affirmer are waived, abandoned, + surrendered, licensed or otherwise affected by this document. + 2. Affirmer offers the Work as-is and makes no representations or warranties + of any kind concerning the Work, express, implied, statutory or + otherwise, including without limitation warranties of title, + merchantability, fitness for a particular purpose, non infringement, or + the absence of latent or other defects, accuracy, or the present or + absence of errors, whether or not discoverable, all to the greatest + extent permissible under applicable law. + 3. Affirmer disclaims responsibility for clearing rights of other persons + that may apply to the Work or any use thereof, including without + limitation any person’s Copyright and Related Rights in the Work. + Further, Affirmer disclaims responsibility for obtaining any necessary + consents, permissions or other rights required for any use of the Work. + 4. Affirmer understands and acknowledges that Creative Commons is not a + party to this document and has no duty or obligation with respect to this + CC0 or use of the Work. + +For more information, please see +http://creativecommons.org/publicdomain/zero/1.0/. diff --git a/README.md b/README.md new file mode 100644 index 0000000000..d19298c166 --- /dev/null +++ b/README.md @@ -0,0 +1,179 @@ +# PostCSS Gap Properties [PostCSS Logo][postcss] + +[![NPM Version][npm-img]][npm-url] +[![Build Status][cli-img]][cli-url] +[![Windows Build Status][win-img]][win-url] +[![Support Chat][git-img]][git-url] + +[PostCSS Gap Properties] lets you use the `gap`, `column-gap`, and `row-gap` +shorthand properties in CSS. + +```pcss +.standard-grid { + gap: 20px; +} + +.spaced-grid { + column-gap: 40px; + row-gap: 20px; +} + +/* becomes */ + +.standard-grid { + grid-gap: 20px; + gap: 20px; +} + +.spaced-grid { + grid-column-gap: 40px; + column-gap: 40px; + grid-row-gap: 20px; + row-gap: 20px; +} +``` + +## Usage + +Add [PostCSS Gap Properties] to your build tool: + +```bash +npm install postcss-gap-properties --save-dev +``` + +#### Node + +Use [PostCSS Gap Properties] to process your CSS: + +```js +import postcssGapProperties from 'postcss-gap-properties'; + +postcssGapProperties.process(YOUR_CSS, /* processOptions */, /* pluginOptions */); +``` + +#### PostCSS + +Add [PostCSS] to your build tool: + +```bash +npm install postcss --save-dev +``` + +Use [PostCSS Gap Properties] as a plugin: + +```js +import postcss from 'gulp-postcss'; +import postcssGapProperties from 'postcss-gap-properties'; + +postcss([ + postcssGapProperties(/* pluginOptions */) +]).process(YOUR_CSS); +``` + +#### Webpack + +Add [PostCSS Loader] to your build tool: + +```bash +npm install postcss-loader --save-dev +``` + +Use [PostCSS Gap Properties] in your Webpack configuration: + +```js +import postcssGapProperties from 'postcss-gap-properties'; + +module.exports = { + module: { + rules: [ + { + test: /\.css$/, + use: [ + 'style-loader', + { loader: 'css-loader', options: { importLoaders: 1 } }, + { loader: 'postcss-loader', options: { + ident: 'postcss', + plugins: () => [ + postcssGapProperties(/* pluginOptions */) + ] + } } + ] + } + ] + } +} +``` + +#### Gulp + +Add [Gulp PostCSS] to your build tool: + +```bash +npm install gulp-postcss --save-dev +``` + +Use [PostCSS Gap Properties] in your Gulpfile: + +```js +import postcss from 'gulp-postcss'; +import postcssGapProperties from 'postcss-gap-properties'; + +gulp.task('css', () => gulp.src('./src/*.css').pipe( + postcss([ + postcssGapProperties(/* pluginOptions */) + ]) +).pipe( + gulp.dest('.') +)); +``` + +#### Grunt + +Add [Grunt PostCSS] to your build tool: + +```bash +npm install grunt-postcss --save-dev +``` + +Use [PostCSS Gap Properties] in your Gruntfile: + +```js +import postcssGapProperties from 'postcss-gap-properties'; + +grunt.loadNpmTasks('grunt-postcss'); + +grunt.initConfig({ + postcss: { + options: { + use: [ + postcssGapProperties(/* pluginOptions */) + ] + }, + dist: { + src: '*.css' + } + } +}); +``` + +## Options + +### preserve + +The `preserve` option determines whether the original `gap` declaration should +remain in the CSS. By default, the original declaration is preserved. + +[cli-img]: https://img.shields.io/travis/jonathantneal/postcss-gap-properties.svg +[cli-url]: https://travis-ci.org/jonathantneal/postcss-gap-properties +[git-img]: https://img.shields.io/badge/support-chat-blue.svg +[git-url]: https://gitter.im/postcss/postcss +[npm-img]: https://img.shields.io/npm/v/postcss-gap-properties.svg +[npm-url]: https://www.npmjs.com/package/postcss-gap-properties +[win-img]: https://img.shields.io/appveyor/ci/jonathantneal/postcss-gap-properties.svg +[win-url]: https://ci.appveyor.com/project/jonathantneal/postcss-gap-properties + +[Gulp PostCSS]: https://github.com/postcss/gulp-postcss +[Grunt PostCSS]: https://github.com/nDmitry/grunt-postcss +[PostCSS]: https://github.com/postcss/postcss +[PostCSS Loader]: https://github.com/postcss/postcss-loader +[PostCSS Gap Properties]: https://github.com/jonathantneal/postcss-gap-properties diff --git a/index.js b/index.js new file mode 100644 index 0000000000..b8ce0925fd --- /dev/null +++ b/index.js @@ -0,0 +1,23 @@ +import postcss from 'postcss'; + +// gap shorthand property matcher +const gapPropertyRegExp = /^(column-gap|gap|row-gap)$/i; + +export default postcss.plugin('postcss-gap-properties', opts => { + const preserve = 'preserve' in Object(opts) ? Boolean(opts.preserve) : true; + + return root => { + // for each shorthand gap, column-gap, or row-gap declaration + root.walkDecls(gapPropertyRegExp, decl => { + // insert a grid-* fallback declaration + decl.cloneBefore({ + prop: `grid-${decl.prop}` + }); + + // conditionally remove the original declaration + if (!preserve) { + decl.remove(); + } + }) + }; +}); diff --git a/package.json b/package.json new file mode 100644 index 0000000000..f2ba45d1a0 --- /dev/null +++ b/package.json @@ -0,0 +1,57 @@ +{ + "name": "postcss-gap-properties", + "version": "1.0.0", + "description": "Use the gap, column-gap, and row-gap shorthand properties in CSS", + "author": "Jonathan Neal ", + "license": "CC0-1.0", + "repository": "jonathantneal/postcss-gap-properties", + "homepage": "https://github.com/jonathantneal/postcss-gap-properties#readme", + "bugs": "https://github.com/jonathantneal/postcss-gap-properties/issues", + "main": "index.cjs.js", + "module": "index.es.js", + "files": [ + "index.cjs.js", + "index.es.js" + ], + "scripts": { + "prepublishOnly": "npm test", + "pretest": "rollup -c .rollup.js --silent", + "test": "echo 'Running tests...'; npm run test:js && npm run test:tape", + "test:ec": "echint --ignore index.*.js test", + "test:js": "eslint *.js --cache --ignore-path .gitignore --quiet", + "test:tape": "postcss-tape" + }, + "engines": { + "node": ">=4.0.0" + }, + "dependencies": { + "postcss": "^6.0.22" + }, + "devDependencies": { + "babel-core": "^6.26.3", + "babel-eslint": "^8.2.3", + "babel-preset-env": "^1.6.1", + "eslint": "^4.19.1", + "eslint-config-dev": "^2.0.0", + "postcss-tape": "^2.2.0", + "pre-commit": "^1.2.2", + "rollup": "^0.58.2", + "rollup-plugin-babel": "^3.0.4" + }, + "eslintConfig": { + "extends": "dev", + "parser": "babel-eslint" + }, + "keywords": [ + "postcss", + "css", + "postcss-plugin", + "grids", + "layouts", + "columns", + "rows", + "gaps", + "shorthands", + "prefixes" + ] +} diff --git a/test/basic.css b/test/basic.css new file mode 100644 index 0000000000..933c87719f --- /dev/null +++ b/test/basic.css @@ -0,0 +1,9 @@ +test { + order: 1; + gap: 20px; + order: 2; + column-gap: 20px; + order: 3; + row-gap: 20px; + order: 4; +} diff --git a/test/basic.expect.css b/test/basic.expect.css new file mode 100644 index 0000000000..af061fbe6d --- /dev/null +++ b/test/basic.expect.css @@ -0,0 +1,12 @@ +test { + order: 1; + grid-gap: 20px; + gap: 20px; + order: 2; + grid-column-gap: 20px; + column-gap: 20px; + order: 3; + grid-row-gap: 20px; + row-gap: 20px; + order: 4; +} diff --git a/test/basic.preserve-false.expect.css b/test/basic.preserve-false.expect.css new file mode 100644 index 0000000000..8c0fb78ea3 --- /dev/null +++ b/test/basic.preserve-false.expect.css @@ -0,0 +1,9 @@ +test { + order: 1; + grid-gap: 20px; + order: 2; + grid-column-gap: 20px; + order: 3; + grid-row-gap: 20px; + order: 4; +} From e391f4a9c94bb2cead4b18486894ff965489bc42 Mon Sep 17 00:00:00 2001 From: Jonathan Neal Date: Mon, 30 Apr 2018 23:12:20 -0400 Subject: [PATCH 610/795] 1.0.0 --- .appveyor.yml | 18 +++ .editorconfig | 15 +++ .gitignore | 12 ++ .rollup.js | 16 +++ .tape.js | 13 +++ .travis.yml | 9 ++ CHANGELOG.md | 5 + CONTRIBUTING.md | 65 +++++++++++ LICENSE.md | 108 ++++++++++++++++++ README.md | 162 +++++++++++++++++++++++++++ index.js | 38 +++++++ package.json | 54 +++++++++ test/basic.css | 3 + test/basic.expect.css | 5 + test/basic.preserve-false.expect.css | 4 + 15 files changed, 527 insertions(+) create mode 100644 .appveyor.yml create mode 100644 .editorconfig create mode 100644 .gitignore create mode 100644 .rollup.js create mode 100644 .tape.js create mode 100644 .travis.yml create mode 100644 CHANGELOG.md create mode 100644 CONTRIBUTING.md create mode 100644 LICENSE.md create mode 100644 README.md create mode 100644 index.js create mode 100644 package.json create mode 100644 test/basic.css create mode 100644 test/basic.expect.css create mode 100644 test/basic.preserve-false.expect.css diff --git a/.appveyor.yml b/.appveyor.yml new file mode 100644 index 0000000000..acbf8a5eeb --- /dev/null +++ b/.appveyor.yml @@ -0,0 +1,18 @@ +# https://www.appveyor.com/docs/appveyor-yml + +environment: + matrix: + - nodejs_version: 4 + +version: "{build}" +build: off +deploy: off + +install: + - ps: Install-Product node $env:nodejs_version + - npm install --ignore-scripts + +test_script: + - node --version + - npm --version + - cmd: "npm test" diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000000..e06d7982bc --- /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/.gitignore b/.gitignore new file mode 100644 index 0000000000..de73e5a338 --- /dev/null +++ b/.gitignore @@ -0,0 +1,12 @@ +node_modules +index.*.js +package-lock.json +*.log* +*.result.css +.* +!.appveyor.yml +!.editorconfig +!.gitignore +!.rollup.js +!.tape.js +!.travis.yml diff --git a/.rollup.js b/.rollup.js new file mode 100644 index 0000000000..0436758216 --- /dev/null +++ b/.rollup.js @@ -0,0 +1,16 @@ +import babel from 'rollup-plugin-babel'; + +export default { + input: 'index.js', + output: [ + { file: 'index.cjs.js', format: 'cjs' }, + { file: 'index.es.js', format: 'es' } + ], + plugins: [ + babel({ + presets: [ + ['env', { modules: false, targets: { node: 4 } }] + ] + }) + ] +}; diff --git a/.tape.js b/.tape.js new file mode 100644 index 0000000000..52923cf863 --- /dev/null +++ b/.tape.js @@ -0,0 +1,13 @@ +module.exports = { + 'postcss-overflow-shorthand': { + 'basic': { + message: 'supports basic usage' + }, + 'basic:preserve-false': { + message: 'supports { preserve: false } usage', + options: { + preserve: false + } + } + } +}; diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000000..c56466446c --- /dev/null +++ b/.travis.yml @@ -0,0 +1,9 @@ +# https://docs.travis-ci.com/user/travis-lint + +language: node_js + +node_js: + - 4 + +install: + - npm install --ignore-scripts diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000000..f04b927af1 --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,5 @@ +# Changes to PostCSS Overflow Shorthand + +### 1.0.0 (April 30, 2018) + +- Initial version diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 0000000000..fee8ef5b09 --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,65 @@ +# Contributing to PostCSS Overflow Shorthand + +You want to help? You rock! Now, take a moment to be sure your contributions +make sense to everyone else. + +## Reporting Issues + +Found a problem? Want a new feature? + +- See if your issue or idea has [already been reported]. +- Provide a [reduced test case] or a [live example]. + +Remember, a bug is a _demonstrable problem_ caused by _our_ code. + +## Submitting Pull Requests + +Pull requests are the greatest contributions, so be sure they are focused in +scope and avoid unrelated commits. + +1. To begin; [fork this project], clone your fork, and add our upstream. + ```bash + # Clone your fork of the repo into the current directory + git clone git@github.com:YOUR_USER/postcss-overflow-shorthand.git + + # Navigate to the newly cloned directory + cd postcss-overflow-shorthand + + # Assign the original repo to a remote called "upstream" + git remote add upstream git@github.com:jonathantneal/postcss-overflow-shorthand.git + + # Install the tools necessary for testing + npm install + ``` + +2. Create a branch for your feature or fix: + ```bash + # Move into a new branch for your feature + git checkout -b feature/thing + ``` + ```bash + # Move into a new branch for your fix + git checkout -b fix/something + ``` + +3. If your code follows our practices, then push your feature branch: + ```bash + # Test current code + npm test + ``` + ```bash + # Push the branch for your new feature + git push origin feature/thing + ``` + ```bash + # Or, push the branch for your update + git push origin update/something + ``` + +That’s it! Now [open a pull request] with a clear title and description. + +[already been reported]: issues +[fork this project]: fork +[live example]: https://codepen.io/pen +[open a pull request]: https://help.github.com/articles/using-pull-requests/ +[reduced test case]: https://css-tricks.com/reduced-test-cases/ diff --git a/LICENSE.md b/LICENSE.md new file mode 100644 index 0000000000..0bc1fa7060 --- /dev/null +++ b/LICENSE.md @@ -0,0 +1,108 @@ +# CC0 1.0 Universal + +## Statement of Purpose + +The laws of most jurisdictions throughout the world automatically confer +exclusive Copyright and Related Rights (defined below) upon the creator and +subsequent owner(s) (each and all, an “owner”) of an original work of +authorship and/or a database (each, a “Work”). + +Certain owners wish to permanently relinquish those rights to a Work for the +purpose of contributing to a commons of creative, cultural and scientific works +(“Commons”) that the public can reliably and without fear of later claims of +infringement build upon, modify, incorporate in other works, reuse and +redistribute as freely as possible in any form whatsoever and for any purposes, +including without limitation commercial purposes. These owners may contribute +to the Commons to promote the ideal of a free culture and the further +production of creative, cultural and scientific works, or to gain reputation or +greater distribution for their Work in part through the use and efforts of +others. + +For these and/or other purposes and motivations, and without any expectation of +additional consideration or compensation, the person associating CC0 with a +Work (the “Affirmer”), to the extent that he or she is an owner of Copyright +and Related Rights in the Work, voluntarily elects to apply CC0 to the Work and +publicly distribute the Work under its terms, with knowledge of his or her +Copyright and Related Rights in the Work and the meaning and intended legal +effect of CC0 on those rights. + +1. Copyright and Related Rights. A Work made available under CC0 may be + protected by copyright and related or neighboring rights (“Copyright and + Related Rights”). Copyright and Related Rights include, but are not limited + to, the following: + 1. the right to reproduce, adapt, distribute, perform, display, communicate, + and translate a Work; + 2. moral rights retained by the original author(s) and/or performer(s); + 3. publicity and privacy rights pertaining to a person’s image or likeness + depicted in a Work; + 4. rights protecting against unfair competition in regards to a Work, + subject to the limitations in paragraph 4(i), below; + 5. rights protecting the extraction, dissemination, use and reuse of data in + a Work; + 6. database rights (such as those arising under Directive 96/9/EC of the + European Parliament and of the Council of 11 March 1996 on the legal + protection of databases, and under any national implementation thereof, + including any amended or successor version of such directive); and + 7. other similar, equivalent or corresponding rights throughout the world + based on applicable law or treaty, and any national implementations + thereof. + +2. Waiver. To the greatest extent permitted by, but not in contravention of, + applicable law, Affirmer hereby overtly, fully, permanently, irrevocably and + unconditionally waives, abandons, and surrenders all of Affirmer’s Copyright + and Related Rights and associated claims and causes of action, whether now + known or unknown (including existing as well as future claims and causes of + action), in the Work (i) in all territories worldwide, (ii) for the maximum + duration provided by applicable law or treaty (including future time + extensions), (iii) in any current or future medium and for any number of + copies, and (iv) for any purpose whatsoever, including without limitation + commercial, advertising or promotional purposes (the “Waiver”). Affirmer + makes the Waiver for the benefit of each member of the public at large and + to the detriment of Affirmer’s heirs and successors, fully intending that + such Waiver shall not be subject to revocation, rescission, cancellation, + termination, or any other legal or equitable action to disrupt the quiet + enjoyment of the Work by the public as contemplated by Affirmer’s express + Statement of Purpose. + +3. Public License Fallback. Should any part of the Waiver for any reason be + judged legally invalid or ineffective under applicable law, then the Waiver + shall be preserved to the maximum extent permitted taking into account + Affirmer’s express Statement of Purpose. In addition, to the extent the + Waiver is so judged Affirmer hereby grants to each affected person a + royalty-free, non transferable, non sublicensable, non exclusive, + irrevocable and unconditional license to exercise Affirmer’s Copyright and + Related Rights in the Work (i) in all territories worldwide, (ii) for the + maximum duration provided by applicable law or treaty (including future time + extensions), (iii) in any current or future medium and for any number of + copies, and (iv) for any purpose whatsoever, including without limitation + commercial, advertising or promotional purposes (the “License”). The License + shall be deemed effective as of the date CC0 was applied by Affirmer to the + Work. Should any part of the License for any reason be judged legally + invalid or ineffective under applicable law, such partial invalidity or + ineffectiveness shall not invalidate the remainder of the License, and in + such case Affirmer hereby affirms that he or she will not (i) exercise any + of his or her remaining Copyright and Related Rights in the Work or (ii) + assert any associated claims and causes of action with respect to the Work, + in either case contrary to Affirmer’s express Statement of Purpose. + +4. Limitations and Disclaimers. + 1. No trademark or patent rights held by Affirmer are waived, abandoned, + surrendered, licensed or otherwise affected by this document. + 2. Affirmer offers the Work as-is and makes no representations or warranties + of any kind concerning the Work, express, implied, statutory or + otherwise, including without limitation warranties of title, + merchantability, fitness for a particular purpose, non infringement, or + the absence of latent or other defects, accuracy, or the present or + absence of errors, whether or not discoverable, all to the greatest + extent permissible under applicable law. + 3. Affirmer disclaims responsibility for clearing rights of other persons + that may apply to the Work or any use thereof, including without + limitation any person’s Copyright and Related Rights in the Work. + Further, Affirmer disclaims responsibility for obtaining any necessary + consents, permissions or other rights required for any use of the Work. + 4. Affirmer understands and acknowledges that Creative Commons is not a + party to this document and has no duty or obligation with respect to this + CC0 or use of the Work. + +For more information, please see +http://creativecommons.org/publicdomain/zero/1.0/. diff --git a/README.md b/README.md new file mode 100644 index 0000000000..4f9f766a37 --- /dev/null +++ b/README.md @@ -0,0 +1,162 @@ +# PostCSS Overflow Shorthand [PostCSS Logo][postcss] + +[![NPM Version][npm-img]][npm-url] +[![Build Status][cli-img]][cli-url] +[![Windows Build Status][win-img]][win-url] +[![Support Chat][git-img]][git-url] + +[PostCSS Overflow Shorthand] lets you use the `overflow` shorthand in CSS, +following the [CSS Overflow] specification. + +```pcss +html { + overflow: hidden auto; +} + +/* becomes */ + +html { + overflow-x: hidden; + overflow-y: auto; + overflow: hidden auto; +} +``` + +## Usage + +Add [PostCSS Overflow Shorthand] to your build tool: + +```bash +npm install postcss-overflow-shorthand --save-dev +``` + +#### Node + +Use [PostCSS Overflow Shorthand] to process your CSS: + +```js +import postcssOverflowShorthand from 'postcss-overflow-shorthand'; + +postcssOverflowShorthand.process(YOUR_CSS, /* processOptions */, /* pluginOptions */); +``` + +#### PostCSS + +Add [PostCSS] to your build tool: + +```bash +npm install postcss --save-dev +``` + +Use [PostCSS Overflow Shorthand] as a plugin: + +```js +import postcss from 'gulp-postcss'; +import postcssOverflowShorthand from 'postcss-overflow-shorthand'; + +postcss([ + postcssOverflowShorthand(/* pluginOptions */) +]).process(YOUR_CSS); +``` + +#### Webpack + +Add [PostCSS Loader] to your build tool: + +```bash +npm install postcss-loader --save-dev +``` + +Use [PostCSS Overflow Shorthand] in your Webpack configuration: + +```js +import postcssOverflowShorthand from 'postcss-overflow-shorthand'; + +module.exports = { + module: { + rules: [ + { + test: /\.css$/, + use: [ + 'style-loader', + { loader: 'css-loader', options: { importLoaders: 1 } }, + { loader: 'postcss-loader', options: { + ident: 'postcss', + plugins: () => [ + postcssOverflowShorthand(/* pluginOptions */) + ] + } } + ] + } + ] + } +} +``` + +#### Gulp + +Add [Gulp PostCSS] to your build tool: + +```bash +npm install gulp-postcss --save-dev +``` + +Use [PostCSS Overflow Shorthand] in your Gulpfile: + +```js +import postcss from 'gulp-postcss'; +import postcssOverflowShorthand from 'postcss-overflow-shorthand'; + +gulp.task('css', () => gulp.src('./src/*.css').pipe( + postcss([ + postcssOverflowShorthand(/* pluginOptions */) + ]) +).pipe( + gulp.dest('.') +)); +``` + +#### Grunt + +Add [Grunt PostCSS] to your build tool: + +```bash +npm install grunt-postcss --save-dev +``` + +Use [PostCSS Overflow Shorthand] in your Gruntfile: + +```js +import postcssOverflowShorthand from 'postcss-overflow-shorthand'; + +grunt.loadNpmTasks('grunt-postcss'); + +grunt.initConfig({ + postcss: { + options: { + use: [ + postcssOverflowShorthand(/* pluginOptions */) + ] + }, + dist: { + src: '*.css' + } + } +}); +``` + +[cli-img]: https://img.shields.io/travis/jonathantneal/postcss-overflow-shorthand.svg +[cli-url]: https://travis-ci.org/jonathantneal/postcss-overflow-shorthand +[git-img]: https://img.shields.io/badge/support-chat-blue.svg +[git-url]: https://gitter.im/postcss/postcss +[npm-img]: https://img.shields.io/npm/v/postcss-overflow-shorthand.svg +[npm-url]: https://www.npmjs.com/package/postcss-overflow-shorthand +[win-img]: https://img.shields.io/appveyor/ci/jonathantneal/postcss-overflow-shorthand.svg +[win-url]: https://ci.appveyor.com/project/jonathantneal/postcss-overflow-shorthand + +[CSS Overflow]: https://drafts.csswg.org/css-overflow/#propdef-overflow +[Gulp PostCSS]: https://github.com/postcss/gulp-postcss +[Grunt PostCSS]: https://github.com/nDmitry/grunt-postcss +[PostCSS]: https://github.com/postcss/postcss +[PostCSS Loader]: https://github.com/postcss/postcss-loader +[PostCSS Overflow Shorthand]: https://github.com/jonathantneal/postcss-overflow-shorthand diff --git a/index.js b/index.js new file mode 100644 index 0000000000..c8ea698ea6 --- /dev/null +++ b/index.js @@ -0,0 +1,38 @@ +import postcss from 'postcss'; + +// space-separated values splitter +const { list: { space } } = postcss + +// overflow shorthand property matcher +const overflowPropertyRegExp = /^overflow$/i; + +export default postcss.plugin('postcss-overflow-shorthand', opts => { + const preserve = 'preserve' in Object(opts) ? Boolean(opts.preserve) : true; + + return root => { + // for each overflow declaration + root.walkDecls(overflowPropertyRegExp, decl => { + // split the declaration values + const [overflowX, overflowY, ...invalidatingValues] = space(decl.value); + + // if there are no invalidating values + if (!invalidatingValues.length) { + // insert the overflow-* longhand declarations + decl.cloneBefore({ + prop: `${decl.prop}-x`, + value: overflowX + }); + + decl.cloneBefore({ + prop: `${decl.prop}-y`, + value: overflowY + }); + + // conditionally remove the original declaration + if (!preserve) { + decl.remove(); + } + } + }) + }; +}); diff --git a/package.json b/package.json new file mode 100644 index 0000000000..ab1cf7ec91 --- /dev/null +++ b/package.json @@ -0,0 +1,54 @@ +{ + "name": "postcss-overflow-shorthand", + "version": "1.0.0", + "description": "Use the overflow shorthand in CSS", + "author": "Jonathan Neal ", + "license": "CC0-1.0", + "repository": "jonathantneal/postcss-overflow-shorthand", + "homepage": "https://github.com/jonathantneal/postcss-overflow-shorthand#readme", + "bugs": "https://github.com/jonathantneal/postcss-overflow-shorthand/issues", + "main": "index.cjs.js", + "module": "index.es.js", + "files": [ + "index.cjs.js", + "index.es.js" + ], + "scripts": { + "prepublishOnly": "npm test", + "pretest": "rollup -c .rollup.js --silent", + "test": "echo 'Running tests...'; npm run test:js && npm run test:tape", + "test:ec": "echint --ignore index.*.js test", + "test:js": "eslint *.js --cache --ignore-path .gitignore --quiet", + "test:tape": "postcss-tape" + }, + "engines": { + "node": ">=4.0.0" + }, + "dependencies": { + "postcss": "^6.0.22" + }, + "devDependencies": { + "babel-core": "^6.26.3", + "babel-eslint": "^8.2.3", + "babel-preset-env": "^1.6.1", + "eslint": "^4.19.1", + "eslint-config-dev": "^2.0.0", + "postcss-tape": "^2.2.0", + "pre-commit": "^1.2.2", + "rollup": "^0.58.2", + "rollup-plugin-babel": "^3.0.4" + }, + "eslintConfig": { + "extends": "dev", + "parser": "babel-eslint" + }, + "keywords": [ + "postcss", + "css", + "postcss-plugin", + "overflow", + "properties", + "shorthands", + "values" + ] +} diff --git a/test/basic.css b/test/basic.css new file mode 100644 index 0000000000..4e1e544baf --- /dev/null +++ b/test/basic.css @@ -0,0 +1,3 @@ +test { + overflow: hidden auto; +} diff --git a/test/basic.expect.css b/test/basic.expect.css new file mode 100644 index 0000000000..8a6e0a27e9 --- /dev/null +++ b/test/basic.expect.css @@ -0,0 +1,5 @@ +test { + overflow-x: hidden; + overflow-y: auto; + overflow: hidden auto; +} diff --git a/test/basic.preserve-false.expect.css b/test/basic.preserve-false.expect.css new file mode 100644 index 0000000000..b23480b3eb --- /dev/null +++ b/test/basic.preserve-false.expect.css @@ -0,0 +1,4 @@ +test { + overflow-x: hidden; + overflow-y: auto; +} From 05c0ea7c34d16559df77d767365e4dc971e643a8 Mon Sep 17 00:00:00 2001 From: Jonathan Neal Date: Mon, 30 Apr 2018 23:15:09 -0400 Subject: [PATCH 611/795] Update README.md - include link to specification --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index d19298c166..947175aa34 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,7 @@ [![Support Chat][git-img]][git-url] [PostCSS Gap Properties] lets you use the `gap`, `column-gap`, and `row-gap` -shorthand properties in CSS. +shorthand properties in CSS, following the [CSS Grid Layout] specification. ```pcss .standard-grid { @@ -172,6 +172,7 @@ remain in the CSS. By default, the original declaration is preserved. [win-img]: https://img.shields.io/appveyor/ci/jonathantneal/postcss-gap-properties.svg [win-url]: https://ci.appveyor.com/project/jonathantneal/postcss-gap-properties +[CSS Grid Layout]: https://www.w3.org/TR/css-grid-1/#gutters [Gulp PostCSS]: https://github.com/postcss/gulp-postcss [Grunt PostCSS]: https://github.com/nDmitry/grunt-postcss [PostCSS]: https://github.com/postcss/postcss From b4acbc9ba31a5122840a671a133185359522ff17 Mon Sep 17 00:00:00 2001 From: Jonathan Neal Date: Wed, 2 May 2018 01:15:02 -0400 Subject: [PATCH 612/795] 3.1.0 --- CHANGELOG.md | 8 +++++++- index.js | 13 +++++++++---- package.json | 10 +++++----- test/index.js | 3 +-- 4 files changed, 22 insertions(+), 12 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9b508ddf3d..397ef488b0 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,10 @@ -# 3.0.0 - 2016-05-10 +# 3.1.0 - 2018-05-01 + +- Improve `rebeccapurple` pre-parse word detection +- Switched from `postcss-value-parser` to `postcss-values-parser` +- Bump `postcss` from `^6.0.1` to `^6.0.22` + +# 3.0.0 - 2017-05-10 - Added: compatibility with postcss v6.x diff --git a/index.js b/index.js index 11cde582aa..18ffab7962 100755 --- a/index.js +++ b/index.js @@ -2,8 +2,9 @@ * Module dependencies. */ const postcss = require("postcss") -const valueParser = require("postcss-value-parser") +const valueParser = require("postcss-values-parser") const color = "#639" +const regexp = /(^|[^\w-])rebeccapurple([^\w-]|$)/ /** * PostCSS plugin to convert colors @@ -12,12 +13,16 @@ module.exports = postcss.plugin("postcss-color-rebeccapurple", () => (style) => style.walkDecls((decl) => { const value = decl.value; - if (value && value.indexOf("rebeccapurple") !== -1) { - decl.value = valueParser(value).walk((node) => { + if (value && regexp.test(value)) { + const ast = valueParser(value).parse() + + ast.walk(node => { if (node.type === "word" && node.value === "rebeccapurple") { node.value = color } - }).toString() + }) + + decl.value = ast.toString() } }) }) diff --git a/package.json b/package.json index 683d4c2c47..42fff4d123 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "postcss-color-rebeccapurple", - "version": "3.0.0", + "version": "3.1.0", "description": "PostCSS plugin to transform W3C CSS rebeccapurple color to more compatible CSS (rgb())", "keywords": [ "css", @@ -21,14 +21,14 @@ "index.js" ], "dependencies": { - "postcss": "^6.0.1", - "postcss-value-parser": "^3.3.0" + "postcss": "^6.0.22", + "postcss-values-parser": "^1.5.0" }, "devDependencies": { "jscs": "^3.0.7", - "jshint": "^2.9.4", + "jshint": "^2.9.5", "npmpub": "^3.1.0", - "tape": "^4.6.3" + "tape": "^4.9.0" }, "scripts": { "lint": "npm run jscs && npm run jshint", diff --git a/test/index.js b/test/index.js index 650439b713..ff7c5bdd40 100755 --- a/test/index.js +++ b/test/index.js @@ -14,11 +14,10 @@ function compareFixtures(t, name, msg, opts, postcssOpts) { opts = opts || {} var actual = postcss().use(plugin(opts)).process(read(postcssOpts.from), postcssOpts).css var expected = read(filename("fixtures/" + name + ".expected")) - fs.writeFile(filename("fixtures/" + name + ".actual"), actual) + fs.writeFile(filename("fixtures/" + name + ".actual"), actual, t.end) t.equal(actual, expected, msg) } test("rebeccapurple", function(t) { compareFixtures(t, "rebeccapurple", "should transform rebeccapurple") - t.end() }) From f9436809c6859b035bc619e4862c6255b89524d0 Mon Sep 17 00:00:00 2001 From: Jonathan Neal Date: Mon, 7 May 2018 04:52:21 -0400 Subject: [PATCH 613/795] 1.0.0 --- .appveyor.yml | 18 ++ .editorconfig | 19 ++ .gitignore | 12 + .rollup.js | 16 ++ .tape.js | 38 +++ .travis.yml | 9 + CHANGELOG.md | 5 + CONTRIBUTING.md | 65 ++++++ LICENSE.md | 108 +++++++++ README.md | 247 ++++++++++++++++++++ index.js | 35 +++ lib/get-comma.js | 2 + lib/get-image.js | 13 ++ lib/get-media.js | 25 ++ lib/handle-invalidation.js | 7 + lib/process-image-set.js | 65 ++++++ package.json | 58 +++++ test/basic.css | 105 +++++++++ test/basic.expect.css | 369 ++++++++++++++++++++++++++++++ test/basic.no-preserve.expect.css | 308 +++++++++++++++++++++++++ test/invalid.css | 52 +++++ 21 files changed, 1576 insertions(+) create mode 100644 .appveyor.yml create mode 100644 .editorconfig create mode 100644 .gitignore create mode 100644 .rollup.js create mode 100644 .tape.js create mode 100644 .travis.yml create mode 100644 CHANGELOG.md create mode 100644 CONTRIBUTING.md create mode 100644 LICENSE.md create mode 100644 README.md create mode 100644 index.js create mode 100644 lib/get-comma.js create mode 100644 lib/get-image.js create mode 100644 lib/get-media.js create mode 100644 lib/handle-invalidation.js create mode 100644 lib/process-image-set.js create mode 100644 package.json create mode 100644 test/basic.css create mode 100644 test/basic.expect.css create mode 100644 test/basic.no-preserve.expect.css create mode 100644 test/invalid.css diff --git a/.appveyor.yml b/.appveyor.yml new file mode 100644 index 0000000000..acbf8a5eeb --- /dev/null +++ b/.appveyor.yml @@ -0,0 +1,18 @@ +# https://www.appveyor.com/docs/appveyor-yml + +environment: + matrix: + - nodejs_version: 4 + +version: "{build}" +build: off +deploy: off + +install: + - ps: Install-Product node $env:nodejs_version + - npm install --ignore-scripts + +test_script: + - node --version + - npm --version + - cmd: "npm test" diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000000..7227e5a5f7 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,19 @@ +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 + +[test/*.expect.css] +insert_final_newline = false +trim_trailing_whitespace = false diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000000..de73e5a338 --- /dev/null +++ b/.gitignore @@ -0,0 +1,12 @@ +node_modules +index.*.js +package-lock.json +*.log* +*.result.css +.* +!.appveyor.yml +!.editorconfig +!.gitignore +!.rollup.js +!.tape.js +!.travis.yml diff --git a/.rollup.js b/.rollup.js new file mode 100644 index 0000000000..0436758216 --- /dev/null +++ b/.rollup.js @@ -0,0 +1,16 @@ +import babel from 'rollup-plugin-babel'; + +export default { + input: 'index.js', + output: [ + { file: 'index.cjs.js', format: 'cjs' }, + { file: 'index.es.js', format: 'es' } + ], + plugins: [ + babel({ + presets: [ + ['env', { modules: false, targets: { node: 4 } }] + ] + }) + ] +}; diff --git a/.tape.js b/.tape.js new file mode 100644 index 0000000000..cf56d4bd92 --- /dev/null +++ b/.tape.js @@ -0,0 +1,38 @@ +module.exports = { + 'postcss-image-set-function': { + 'basic': { + message: 'supports basic usage' + }, + 'basic:no-preserve': { + message: 'supports { preserve: false } usage', + options: { + preserve: false + } + }, + 'invalid': { + message: 'ignores invalid usage', + expect: 'invalid.css', + result: 'invalid.css' + }, + 'invalid:warn': { + message: 'warns invalid usage when { onvalid: "warn" }', + options: { + oninvalid: 'warn' + }, + expect: 'invalid.css', + result: 'invalid.css', + warning: 10 + }, + 'invalid:throw': { + message: 'throws invalid usage when { onvalid: "throw" }', + options: { + oninvalid: 'throw' + }, + expect: 'invalid.css', + result: 'invalid.css', + error: { + message: /unexpected image/ + } + } + } +}; diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000000..c56466446c --- /dev/null +++ b/.travis.yml @@ -0,0 +1,9 @@ +# https://docs.travis-ci.com/user/travis-lint + +language: node_js + +node_js: + - 4 + +install: + - npm install --ignore-scripts diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000000..8526ab9f2d --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,5 @@ +# Changes to PostCSS image-set() Function + +### 1.0.0 (May 2, 2018) + +- Initial version diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 0000000000..c2c61d30c1 --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,65 @@ +# Contributing to PostCSS image-set() Function + +You want to help? You rock! Now, take a moment to be sure your contributions +make sense to everyone else. + +## Reporting Issues + +Found a problem? Want a new feature? + +- See if your issue or idea has [already been reported]. +- Provide a [reduced test case] or a [live example]. + +Remember, a bug is a _demonstrable problem_ caused by _our_ code. + +## Submitting Pull Requests + +Pull requests are the greatest contributions, so be sure they are focused in +scope and avoid unrelated commits. + +1. To begin; [fork this project], clone your fork, and add our upstream. + ```bash + # Clone your fork of the repo into the current directory + git clone git@github.com:YOUR_USER/postcss-image-set-function.git + + # Navigate to the newly cloned directory + cd postcss-image-set-function + + # Assign the original repo to a remote called "upstream" + git remote add upstream git@github.com:jonathantneal/postcss-image-set-function.git + + # Install the tools necessary for testing + npm install + ``` + +2. Create a branch for your feature or fix: + ```bash + # Move into a new branch for your feature + git checkout -b feature/thing + ``` + ```bash + # Move into a new branch for your fix + git checkout -b fix/something + ``` + +3. If your code follows our practices, then push your feature branch: + ```bash + # Test current code + npm test + ``` + ```bash + # Push the branch for your new feature + git push origin feature/thing + ``` + ```bash + # Or, push the branch for your update + git push origin update/something + ``` + +That’s it! Now [open a pull request] with a clear title and description. + +[already been reported]: issues +[fork this project]: fork +[live example]: https://codepen.io/pen +[open a pull request]: https://help.github.com/articles/using-pull-requests/ +[reduced test case]: https://css-tricks.com/reduced-test-cases/ diff --git a/LICENSE.md b/LICENSE.md new file mode 100644 index 0000000000..0bc1fa7060 --- /dev/null +++ b/LICENSE.md @@ -0,0 +1,108 @@ +# CC0 1.0 Universal + +## Statement of Purpose + +The laws of most jurisdictions throughout the world automatically confer +exclusive Copyright and Related Rights (defined below) upon the creator and +subsequent owner(s) (each and all, an “owner”) of an original work of +authorship and/or a database (each, a “Work”). + +Certain owners wish to permanently relinquish those rights to a Work for the +purpose of contributing to a commons of creative, cultural and scientific works +(“Commons”) that the public can reliably and without fear of later claims of +infringement build upon, modify, incorporate in other works, reuse and +redistribute as freely as possible in any form whatsoever and for any purposes, +including without limitation commercial purposes. These owners may contribute +to the Commons to promote the ideal of a free culture and the further +production of creative, cultural and scientific works, or to gain reputation or +greater distribution for their Work in part through the use and efforts of +others. + +For these and/or other purposes and motivations, and without any expectation of +additional consideration or compensation, the person associating CC0 with a +Work (the “Affirmer”), to the extent that he or she is an owner of Copyright +and Related Rights in the Work, voluntarily elects to apply CC0 to the Work and +publicly distribute the Work under its terms, with knowledge of his or her +Copyright and Related Rights in the Work and the meaning and intended legal +effect of CC0 on those rights. + +1. Copyright and Related Rights. A Work made available under CC0 may be + protected by copyright and related or neighboring rights (“Copyright and + Related Rights”). Copyright and Related Rights include, but are not limited + to, the following: + 1. the right to reproduce, adapt, distribute, perform, display, communicate, + and translate a Work; + 2. moral rights retained by the original author(s) and/or performer(s); + 3. publicity and privacy rights pertaining to a person’s image or likeness + depicted in a Work; + 4. rights protecting against unfair competition in regards to a Work, + subject to the limitations in paragraph 4(i), below; + 5. rights protecting the extraction, dissemination, use and reuse of data in + a Work; + 6. database rights (such as those arising under Directive 96/9/EC of the + European Parliament and of the Council of 11 March 1996 on the legal + protection of databases, and under any national implementation thereof, + including any amended or successor version of such directive); and + 7. other similar, equivalent or corresponding rights throughout the world + based on applicable law or treaty, and any national implementations + thereof. + +2. Waiver. To the greatest extent permitted by, but not in contravention of, + applicable law, Affirmer hereby overtly, fully, permanently, irrevocably and + unconditionally waives, abandons, and surrenders all of Affirmer’s Copyright + and Related Rights and associated claims and causes of action, whether now + known or unknown (including existing as well as future claims and causes of + action), in the Work (i) in all territories worldwide, (ii) for the maximum + duration provided by applicable law or treaty (including future time + extensions), (iii) in any current or future medium and for any number of + copies, and (iv) for any purpose whatsoever, including without limitation + commercial, advertising or promotional purposes (the “Waiver”). Affirmer + makes the Waiver for the benefit of each member of the public at large and + to the detriment of Affirmer’s heirs and successors, fully intending that + such Waiver shall not be subject to revocation, rescission, cancellation, + termination, or any other legal or equitable action to disrupt the quiet + enjoyment of the Work by the public as contemplated by Affirmer’s express + Statement of Purpose. + +3. Public License Fallback. Should any part of the Waiver for any reason be + judged legally invalid or ineffective under applicable law, then the Waiver + shall be preserved to the maximum extent permitted taking into account + Affirmer’s express Statement of Purpose. In addition, to the extent the + Waiver is so judged Affirmer hereby grants to each affected person a + royalty-free, non transferable, non sublicensable, non exclusive, + irrevocable and unconditional license to exercise Affirmer’s Copyright and + Related Rights in the Work (i) in all territories worldwide, (ii) for the + maximum duration provided by applicable law or treaty (including future time + extensions), (iii) in any current or future medium and for any number of + copies, and (iv) for any purpose whatsoever, including without limitation + commercial, advertising or promotional purposes (the “License”). The License + shall be deemed effective as of the date CC0 was applied by Affirmer to the + Work. Should any part of the License for any reason be judged legally + invalid or ineffective under applicable law, such partial invalidity or + ineffectiveness shall not invalidate the remainder of the License, and in + such case Affirmer hereby affirms that he or she will not (i) exercise any + of his or her remaining Copyright and Related Rights in the Work or (ii) + assert any associated claims and causes of action with respect to the Work, + in either case contrary to Affirmer’s express Statement of Purpose. + +4. Limitations and Disclaimers. + 1. No trademark or patent rights held by Affirmer are waived, abandoned, + surrendered, licensed or otherwise affected by this document. + 2. Affirmer offers the Work as-is and makes no representations or warranties + of any kind concerning the Work, express, implied, statutory or + otherwise, including without limitation warranties of title, + merchantability, fitness for a particular purpose, non infringement, or + the absence of latent or other defects, accuracy, or the present or + absence of errors, whether or not discoverable, all to the greatest + extent permissible under applicable law. + 3. Affirmer disclaims responsibility for clearing rights of other persons + that may apply to the Work or any use thereof, including without + limitation any person’s Copyright and Related Rights in the Work. + Further, Affirmer disclaims responsibility for obtaining any necessary + consents, permissions or other rights required for any use of the Work. + 4. Affirmer understands and acknowledges that Creative Commons is not a + party to this document and has no duty or obligation with respect to this + CC0 or use of the Work. + +For more information, please see +http://creativecommons.org/publicdomain/zero/1.0/. diff --git a/README.md b/README.md new file mode 100644 index 0000000000..49c88f0d08 --- /dev/null +++ b/README.md @@ -0,0 +1,247 @@ +# PostCSS image-set() Function [PostCSS Logo][postcss] + +[![NPM Version][npm-img]][npm-url] +[![CSS Standard Status][css-img]][css-url] +[![Build Status][cli-img]][cli-url] +[![Windows Build Status][win-img]][win-url] +[![Support Chat][git-img]][git-url] + +[PostCSS image-set() Function] lets you display resolution-dependent images +using the `image-set()` function in CSS, following the [CSS Images] +specification. + +```pcss +.example { + background-image: image-set( + url(img.png) 1x, + url(img@2x.png) 2x, + url(img@print.png) 600dpi + ); +} + +/* becomes */ + +@media (-webkit-min-device-pixel-ratio: 1), (min-resolution: 96dpi) { + .example { + background-image: url(img.png); + } +} + +@media (-webkit-min-device-pixel-ratio: 2), (min-resolution: 192dpi) { + .example { + background-image: url(img@2x.png); + } +} + + +@media (-webkit-min-device-pixel-ratio: 6.25), (min-resolution: 600dpi) { + .example { + background-image: url(my@print.png); + } +} + +.example { + background-image: image-set( + url(img.png) 1x, + url(img@2x.png) 2x, + url(img@print.png) 600dpi + ); +} +``` + +## Usage + +Add [PostCSS image-set() Function] to your build tool: + +```bash +npm install postcss-image-set-function --save-dev +``` + +#### Node + +Use [PostCSS image-set() Function] to process your CSS: + +```js +import postcssImageSetFunction from 'postcss-image-set-function'; + +postcssImageSetFunction.process(YOUR_CSS, /* processOptions */, /* pluginOptions */); +``` + +#### PostCSS + +Add [PostCSS] to your build tool: + +```bash +npm install postcss --save-dev +``` + +Use [PostCSS image-set() Function] as a plugin: + +```js +import postcss from 'gulp-postcss'; +import postcssImageSetFunction from 'postcss-image-set-function'; + +postcss([ + postcssImageSetFunction(/* pluginOptions */) +]).process(YOUR_CSS); +``` + +#### Webpack + +Add [PostCSS Loader] to your build tool: + +```bash +npm install postcss-loader --save-dev +``` + +Use [PostCSS image-set() Function] in your Webpack configuration: + +```js +import postcssImageSetFunction from 'postcss-image-set-function'; + +module.exports = { + module: { + rules: [ + { + test: /\.css$/, + use: [ + 'style-loader', + { loader: 'css-loader', options: { importLoaders: 1 } }, + { loader: 'postcss-loader', options: { + ident: 'postcss', + plugins: () => [ + postcssImageSetFunction(/* pluginOptions */) + ] + } } + ] + } + ] + } +} +``` + +#### Gulp + +Add [Gulp PostCSS] to your build tool: + +```bash +npm install gulp-postcss --save-dev +``` + +Use [PostCSS image-set() Function] in your Gulpfile: + +```js +import postcss from 'gulp-postcss'; +import postcssImageSetFunction from 'postcss-image-set-function'; + +gulp.task('css', () => gulp.src('./src/*.css').pipe( + postcss([ + postcssImageSetFunction(/* pluginOptions */) + ]) +).pipe( + gulp.dest('.') +)); +``` + +#### Grunt + +Add [Grunt PostCSS] to your build tool: + +```bash +npm install grunt-postcss --save-dev +``` + +Use [PostCSS image-set() Function] in your Gruntfile: + +```js +import postcssImageSetFunction from 'postcss-image-set-function'; + +grunt.loadNpmTasks('grunt-postcss'); + +grunt.initConfig({ + postcss: { + options: { + use: [ + postcssImageSetFunction(/* pluginOptions */) + ] + }, + dist: { + src: '*.css' + } + } +}); +``` + +## Options + +### preserve + +The `preserve` option determines whether the original declaration using +`image-set()` is preserved. By default, it is preserved. + +```js +postcssImageSetFunction({ preserve: false }) +``` + +```pcss +.example { + background-image: image-set( + url(img.png) 1x, + url(img@2x.png) 2x, + url(img@print.png) 600dpi + ); +} + +/* becomes */ + +@media (-webkit-min-device-pixel-ratio: 1), (min-resolution: 96dpi) { + .example { + background-image: url(img.png); + } +} + +@media (-webkit-min-device-pixel-ratio: 2), (min-resolution: 192dpi) { + .example { + background-image: url(img@2x.png); + } +} + + +@media (-webkit-min-device-pixel-ratio: 6.25), (min-resolution: 600dpi) { + .example { + background-image: url(my@print.png); + } +} +``` + +### onvalid + +The `oninvalid` option determines how invalid usage of `image-set()` should be +handled. By default, invalid usages of `image-set()` are ignored. They can be +configured to display a `warning` or `throw` an error. + +```js +postcssImageSetFunction({ oninvalid: 'warning' }) // warn on invalid usages +``` + +```js +postcssImageSetFunction({ oninvalid: 'throw' }) // throw on invalid usages +``` + +[cli-img]: https://img.shields.io/travis/jonathantneal/postcss-image-set-function.svg +[cli-url]: https://travis-ci.org/jonathantneal/postcss-image-set-function +[css-img]: https://cssdb.org/badge/image-set-function.svg +[css-url]: https://cssdb.org/#image-set-function +[git-img]: https://img.shields.io/badge/support-chat-blue.svg +[git-url]: https://gitter.im/postcss/postcss +[npm-img]: https://img.shields.io/npm/v/postcss-image-set-function.svg +[npm-url]: https://www.npmjs.com/package/postcss-image-set-function +[win-img]: https://img.shields.io/appveyor/ci/jonathantneal/postcss-image-set-function.svg +[win-url]: https://ci.appveyor.com/project/jonathantneal/postcss-image-set-function + +[CSS Images]: https://drafts.csswg.org/css-images-4/#image-set-notation +[Gulp PostCSS]: https://github.com/postcss/gulp-postcss +[Grunt PostCSS]: https://github.com/nDmitry/grunt-postcss +[PostCSS]: https://github.com/postcss/postcss +[PostCSS Loader]: https://github.com/postcss/postcss-loader +[PostCSS image-set() Function]: https://github.com/jonathantneal/postcss-image-set-function diff --git a/index.js b/index.js new file mode 100644 index 0000000000..002d2ed68b --- /dev/null +++ b/index.js @@ -0,0 +1,35 @@ +import postcss from 'postcss'; +import parser from 'postcss-values-parser'; +import processImageSet from './lib/process-image-set'; + +const imageSetValueMatchRegExp = /(^|[^\w-])(-webkit-)?image-set\(/ +const imageSetFunctionMatchRegExp = /^(-webkit-)?image-set$/i + +export default postcss.plugin('postcss-image-set-function', opts => { + // prepare options + const preserve = 'preserve' in Object(opts) ? Boolean(opts.preserve) : true; + const oninvalid = 'oninvalid' in Object(opts) ? opts.oninvalid : 'ignore'; + + return (root, result) => { + // for every declaration + root.walkDecls(decl => { + const { value } = decl; + + // if a declaration likely uses an image-set() function + if (imageSetValueMatchRegExp.test(value)) { + const ast = parser(value).parse(); + + // process every image-set() function + ast.walkType('func', node => { + if (imageSetFunctionMatchRegExp.test(node.value)) { + processImageSet( + node.nodes.slice(1, -1), + decl, + { decl, oninvalid, preserve, result } + ); + } + }) + } + }) + } +}); diff --git a/lib/get-comma.js b/lib/get-comma.js new file mode 100644 index 0000000000..6b2f8bea4e --- /dev/null +++ b/lib/get-comma.js @@ -0,0 +1,2 @@ +// return whether a node is a valid comma +export default node => Object(node).type === 'comma'; diff --git a/lib/get-image.js b/lib/get-image.js new file mode 100644 index 0000000000..84061ba71a --- /dev/null +++ b/lib/get-image.js @@ -0,0 +1,13 @@ +const imageSetFunctionMatchRegExp = /^(-webkit-)?image-set$/i + +// return a valid image +export default node => + // | | | + // the image-set() function can not be nested inside of itself + Object(node).type === 'func' && /^(cross-fade|image|(repeating-)?(conic|linear|radial)-gradient|url)$/i.test(node.value) && !( + node.parent.parent && node.parent.parent.type === 'func' && imageSetFunctionMatchRegExp.test(node.parent.parent.value) + ) + ? String(node) +: Object(node).type === 'string' + ? node.value +: false; diff --git a/lib/get-media.js b/lib/get-media.js new file mode 100644 index 0000000000..84c2edbbf4 --- /dev/null +++ b/lib/get-media.js @@ -0,0 +1,25 @@ +import postcss from 'postcss'; + +const dpiRatios = { dpcm: 2.54, dpi: 1, dppx: 96, x: 96 }; + +// return a valid @media rule +export default (node, mediasByDpi) => { + if (Object(node).type === 'number' && node.unit in dpiRatios) { + // calculate min-device-pixel-ratio and min-resolution + const dpi = Number(node.value) * dpiRatios[node.unit.toLowerCase()]; + const pxRatio = Math.floor(dpi / dpiRatios.x * 100) / 100; + + if (dpi in mediasByDpi) { + return false; + } else { + const media = mediasByDpi[dpi] = postcss.atRule({ + name: 'media', + params: `(-webkit-min-device-pixel-ratio: ${pxRatio}), (min-resolution: ${dpi}dpi)` + }); + + return media; + } + } else { + return false; + } +}; diff --git a/lib/handle-invalidation.js b/lib/handle-invalidation.js new file mode 100644 index 0000000000..67b4991fb4 --- /dev/null +++ b/lib/handle-invalidation.js @@ -0,0 +1,7 @@ +export default (opts, message, word) => { + if (opts.oninvalid === 'warn') { + opts.decl.warn(opts.result, message, { word: String(word) }); + } else if (opts.oninvalid === 'throw') { + throw opts.decl.error(message, { word: String(word) }); + } +}; diff --git a/lib/process-image-set.js b/lib/process-image-set.js new file mode 100644 index 0000000000..7d15da6272 --- /dev/null +++ b/lib/process-image-set.js @@ -0,0 +1,65 @@ +import getComma from './get-comma'; +import getImage from './get-image'; +import getMedia from './get-media'; +import handleInvalidation from './handle-invalidation'; + +export default (imageSetOptionNodes, decl, opts) => { + const parent = decl.parent; + const mediasByDpi = {}; + + let length = imageSetOptionNodes.length; + let index = -1; + + while (index < length) { + const [comma, value, media] = [ + index < 0 ? true : getComma(imageSetOptionNodes[index]), + getImage(imageSetOptionNodes[index + 1]), + getMedia(imageSetOptionNodes[index + 2], mediasByDpi) + ]; + + // handle invalidations + if (!comma) { + return handleInvalidation(opts, 'unexpected comma', imageSetOptionNodes[index]); + } else if (!value) { + return handleInvalidation(opts, 'unexpected image', imageSetOptionNodes[index + 1]); + } else if (!media) { + return handleInvalidation(opts, 'unexpected resolution', imageSetOptionNodes[index + 2]); + } + + // prepare @media { decl: } + const parentClone = parent.clone().removeAll(); + const declClone = decl.clone({ value }); + + parentClone.append(declClone); + media.append(parentClone); + + index += 3 + } + + const medias = Object.keys(mediasByDpi).map(params => mediasByDpi[params]); + + // conditionally prepend previous siblings + if (medias.length) { + const siblings = parent.nodes; + const previousSiblings = siblings.slice(0, siblings.indexOf(decl)); + + if (previousSiblings.length) { + const parentClone = parent.cloneBefore().removeAll(); + + parentClone.append(previousSiblings); + } + + // prepend any @media { decl: } rules + parent.before(medias); + + // conditionally remove the current rule + if (!opts.preserve) { + decl.remove(); + + // and then conditionally remove its parent + if (!parent.nodes.length) { + parent.remove(); + } + } + } +} diff --git a/package.json b/package.json new file mode 100644 index 0000000000..aa64676dbb --- /dev/null +++ b/package.json @@ -0,0 +1,58 @@ +{ + "name": "postcss-image-set-function", + "version": "1.0.0", + "description": "Display resolution-dependent images using the image-set() function in CSS", + "author": "Jonathan Neal ", + "license": "CC0-1.0", + "repository": "jonathantneal/postcss-image-set-function", + "homepage": "https://github.com/jonathantneal/postcss-image-set-function#readme", + "bugs": "https://github.com/jonathantneal/postcss-image-set-function/issues", + "main": "index.cjs.js", + "module": "index.es.js", + "files": [ + "index.cjs.js", + "index.es.js" + ], + "scripts": { + "prepublishOnly": "npm test", + "pretest": "rollup -c .rollup.js --silent", + "test": "echo 'Running tests...'; npm run test:js && npm run test:tape", + "test:ec": "echint --ignore index.*.js test", + "test:js": "eslint *.js --cache --ignore-path .gitignore --quiet", + "test:tape": "postcss-tape" + }, + "engines": { + "node": ">=4.0.0" + }, + "dependencies": { + "postcss": "^6.0.22", + "postcss-values-parser": "^1.5.0" + }, + "devDependencies": { + "babel-core": "^6.26.3", + "babel-eslint": "^8.2.3", + "babel-preset-env": "^1.6.1", + "eslint": "^4.19.1", + "eslint-config-dev": "^2.0.0", + "postcss-tape": "^2.2.0", + "pre-commit": "^1.2.2", + "rollup": "^0.58.2", + "rollup-plugin-babel": "^3.0.4" + }, + "eslintConfig": { + "extends": "dev", + "parser": "babel-eslint" + }, + "keywords": [ + "postcss", + "css", + "postcss-plugin", + "image-set", + "background", + "image", + "responsive", + "resolution", + "negotiation", + "optimization" + ] +} diff --git a/test/basic.css b/test/basic.css new file mode 100644 index 0000000000..0daf0e97fb --- /dev/null +++ b/test/basic.css @@ -0,0 +1,105 @@ +.test-unchanged-properties { + order: 1; + background-image: url("img/test.png"); + order: 2; + background: url(my-img-print.png) top left no-repeat red; + order: 3; +} + +.test-changed-properties { + order: 1; + background-image: image-set( + url(img/test.png) 1x + ); + order: 2; + background-image: image-set( + url(img/test.png) 2x + ); + order: 3; + background-image: image-set( + url(img/test.png) 1x, + url(img/test-2x.png) 2x + ); + order: 4; + background-image: image-set( + url(img/test.png) 1x, + url(img/test-2x.png) 2x, + url(my-img-print.png) 600dpi + ); + order: 5; +} + +.test-mixed-units { + order: 1; + background-image: image-set( + url(img/test.png) 1x, + url(img/test-2x.png) 2dppx + ); + order: 2; + background-image: image-set( + url(img/test.png) 1x, + url(img/test-2x.png) 20dpcm + ); + order: 3; +} + +.test-mixed-order { + order: 1; + background: image-set( + url(../images/bck@3x.png) 3x, + url(../images/bck.png) 1x, + url(../images/bck@2x.png) 2x + ); + order: 2; + background: image-set( + url(../images/bck@2x.png) 2x, + url(../images/bck@3x.png) 3x, + url(../images/bck.png) 1x + ); + order: 3; +} + +.test-no-url { + order: 1; + background-image: image-set( + "img/test.png" 1x, + "img/test-2x.png" 2x + ); + order: 2; + background-image: image-set( + "img/test.png" 1x, + "img/test-2x.png" 2x, + "my-img-print.png" 600dpi + ); + order: 3; +} + +.test-webkit-prefix { + order: 1; + background-image: -webkit-image-set( + url(img/test.png) 1x, + url(img/test-2x.png) 2x, + url(my-img-print.png) 600dpi + ); + order: 2; +} + +@media (min-width: 1000px) { + .test-within-mq-1 { + background-image: image-set( + url(img/test.png) 1x, + url(img/test-2x.png) 2x, + url(my-img-print.png) 600dpi + ); + } +} + +@media (min-width: 768px) and (max-width: 1024px) { + .test-within-mq-2 { + background-image: image-set( + url(img/test.png) 1x, + url(img/test-2x.png) 2x, + url(my-img-print.png) 600dpi + ); + } +} diff --git a/test/basic.expect.css b/test/basic.expect.css new file mode 100644 index 0000000000..5c9fe830e1 --- /dev/null +++ b/test/basic.expect.css @@ -0,0 +1,369 @@ +.test-unchanged-properties { + order: 1; + background-image: url("img/test.png"); + order: 2; + background: url(my-img-print.png) top left no-repeat red; + order: 3; +} + +.test-changed-properties { + order: 1; +} + +@media (-webkit-min-device-pixel-ratio: 1), (min-resolution: 96dpi) { + +.test-changed-properties { + background-image: + url(img/test.png); +} +} + +.test-changed-properties { + background-image: image-set( + url(img/test.png) 1x + ); + order: 2; +} + +@media (-webkit-min-device-pixel-ratio: 2), (min-resolution: 192dpi) { + +.test-changed-properties { + background-image: + url(img/test.png); +} +} + +.test-changed-properties { + background-image: image-set( + url(img/test.png) 2x + ); + order: 3; +} + +@media (-webkit-min-device-pixel-ratio: 1), (min-resolution: 96dpi) { + +.test-changed-properties { + background-image: + url(img/test.png); +} +} + +@media (-webkit-min-device-pixel-ratio: 2), (min-resolution: 192dpi) { + +.test-changed-properties { + background-image: + url(img/test-2x.png); +} +} + +.test-changed-properties { + background-image: image-set( + url(img/test.png) 1x, + url(img/test-2x.png) 2x + ); + order: 4; +} + +@media (-webkit-min-device-pixel-ratio: 1), (min-resolution: 96dpi) { + +.test-changed-properties { + background-image: + url(img/test.png); +} +} + +@media (-webkit-min-device-pixel-ratio: 2), (min-resolution: 192dpi) { + +.test-changed-properties { + background-image: + url(img/test-2x.png); +} +} + +@media (-webkit-min-device-pixel-ratio: 6.25), (min-resolution: 600dpi) { + +.test-changed-properties { + background-image: + url(my-img-print.png); +} +} + +.test-changed-properties { + background-image: image-set( + url(img/test.png) 1x, + url(img/test-2x.png) 2x, + url(my-img-print.png) 600dpi + ); + order: 5; +} + +.test-mixed-units { + order: 1; +} + +@media (-webkit-min-device-pixel-ratio: 1), (min-resolution: 96dpi) { + +.test-mixed-units { + background-image: + url(img/test.png); +} +} + +@media (-webkit-min-device-pixel-ratio: 2), (min-resolution: 192dpi) { + +.test-mixed-units { + background-image: + url(img/test-2x.png); +} +} + +.test-mixed-units { + background-image: image-set( + url(img/test.png) 1x, + url(img/test-2x.png) 2dppx + ); + order: 2; +} + +@media (-webkit-min-device-pixel-ratio: 1), (min-resolution: 96dpi) { + +.test-mixed-units { + background-image: + url(img/test.png); +} +} + +@media (-webkit-min-device-pixel-ratio: 0.52), (min-resolution: 50.8dpi) { + +.test-mixed-units { + background-image: + url(img/test-2x.png); +} +} + +.test-mixed-units { + background-image: image-set( + url(img/test.png) 1x, + url(img/test-2x.png) 20dpcm + ); + order: 3; +} + +.test-mixed-order { + order: 1; +} + +@media (-webkit-min-device-pixel-ratio: 1), (min-resolution: 96dpi) { + +.test-mixed-order { + background: + url(../images/bck.png); +} +} + +@media (-webkit-min-device-pixel-ratio: 2), (min-resolution: 192dpi) { + +.test-mixed-order { + background: + url(../images/bck@2x.png); +} +} + +@media (-webkit-min-device-pixel-ratio: 3), (min-resolution: 288dpi) { + +.test-mixed-order { + background: + url(../images/bck@3x.png); +} +} + +.test-mixed-order { + background: image-set( + url(../images/bck@3x.png) 3x, + url(../images/bck.png) 1x, + url(../images/bck@2x.png) 2x + ); + order: 2; +} + +@media (-webkit-min-device-pixel-ratio: 1), (min-resolution: 96dpi) { + +.test-mixed-order { + background: + url(../images/bck.png); +} +} + +@media (-webkit-min-device-pixel-ratio: 2), (min-resolution: 192dpi) { + +.test-mixed-order { + background: + url(../images/bck@2x.png); +} +} + +@media (-webkit-min-device-pixel-ratio: 3), (min-resolution: 288dpi) { + +.test-mixed-order { + background: + url(../images/bck@3x.png); +} +} + +.test-mixed-order { + background: image-set( + url(../images/bck@2x.png) 2x, + url(../images/bck@3x.png) 3x, + url(../images/bck.png) 1x + ); + order: 3; +} + +.test-no-url { + order: 1; +} + +@media (-webkit-min-device-pixel-ratio: 1), (min-resolution: 96dpi) { + +.test-no-url { + background-image: img/test.png; +} +} + +@media (-webkit-min-device-pixel-ratio: 2), (min-resolution: 192dpi) { + +.test-no-url { + background-image: img/test-2x.png; +} +} + +.test-no-url { + background-image: image-set( + "img/test.png" 1x, + "img/test-2x.png" 2x + ); + order: 2; +} + +@media (-webkit-min-device-pixel-ratio: 1), (min-resolution: 96dpi) { + +.test-no-url { + background-image: img/test.png; +} +} + +@media (-webkit-min-device-pixel-ratio: 2), (min-resolution: 192dpi) { + +.test-no-url { + background-image: img/test-2x.png; +} +} + +@media (-webkit-min-device-pixel-ratio: 6.25), (min-resolution: 600dpi) { + +.test-no-url { + background-image: my-img-print.png; +} +} + +.test-no-url { + background-image: image-set( + "img/test.png" 1x, + "img/test-2x.png" 2x, + "my-img-print.png" 600dpi + ); + order: 3; +} + +.test-webkit-prefix { + order: 1; +} + +@media (-webkit-min-device-pixel-ratio: 1), (min-resolution: 96dpi) { + +.test-webkit-prefix { + background-image: + url(img/test.png); +} +} + +@media (-webkit-min-device-pixel-ratio: 2), (min-resolution: 192dpi) { + +.test-webkit-prefix { + background-image: + url(img/test-2x.png); +} +} + +@media (-webkit-min-device-pixel-ratio: 6.25), (min-resolution: 600dpi) { + +.test-webkit-prefix { + background-image: + url(my-img-print.png); +} +} + +.test-webkit-prefix { + background-image: -webkit-image-set( + url(img/test.png) 1x, + url(img/test-2x.png) 2x, + url(my-img-print.png) 600dpi + ); + order: 2; +} + +@media (min-width: 1000px) { + @media (-webkit-min-device-pixel-ratio: 1), (min-resolution: 96dpi) { + .test-within-mq-1 { + background-image: + url(img/test.png); + } + } + @media (-webkit-min-device-pixel-ratio: 2), (min-resolution: 192dpi) { + .test-within-mq-1 { + background-image: + url(img/test-2x.png); + } + } + @media (-webkit-min-device-pixel-ratio: 6.25), (min-resolution: 600dpi) { + .test-within-mq-1 { + background-image: + url(my-img-print.png); + } + } + .test-within-mq-1 { + background-image: image-set( + url(img/test.png) 1x, + url(img/test-2x.png) 2x, + url(my-img-print.png) 600dpi + ); + } +} + +@media (min-width: 768px) and (max-width: 1024px) { + @media (-webkit-min-device-pixel-ratio: 1), (min-resolution: 96dpi) { + .test-within-mq-2 { + background-image: + url(img/test.png); + } + } + @media (-webkit-min-device-pixel-ratio: 2), (min-resolution: 192dpi) { + .test-within-mq-2 { + background-image: + url(img/test-2x.png); + } + } + @media (-webkit-min-device-pixel-ratio: 6.25), (min-resolution: 600dpi) { + .test-within-mq-2 { + background-image: + url(my-img-print.png); + } + } + .test-within-mq-2 { + background-image: image-set( + url(img/test.png) 1x, + url(img/test-2x.png) 2x, + url(my-img-print.png) 600dpi + ); + } +} diff --git a/test/basic.no-preserve.expect.css b/test/basic.no-preserve.expect.css new file mode 100644 index 0000000000..d28790c0fa --- /dev/null +++ b/test/basic.no-preserve.expect.css @@ -0,0 +1,308 @@ +.test-unchanged-properties { + order: 1; + background-image: url("img/test.png"); + order: 2; + background: url(my-img-print.png) top left no-repeat red; + order: 3; +} + +.test-changed-properties { + order: 1; +} + +@media (-webkit-min-device-pixel-ratio: 1), (min-resolution: 96dpi) { + +.test-changed-properties { + background-image: + url(img/test.png); +} +} + +.test-changed-properties { + order: 2; +} + +@media (-webkit-min-device-pixel-ratio: 2), (min-resolution: 192dpi) { + +.test-changed-properties { + background-image: + url(img/test.png); +} +} + +.test-changed-properties { + order: 3; +} + +@media (-webkit-min-device-pixel-ratio: 1), (min-resolution: 96dpi) { + +.test-changed-properties { + background-image: + url(img/test.png); +} +} + +@media (-webkit-min-device-pixel-ratio: 2), (min-resolution: 192dpi) { + +.test-changed-properties { + background-image: + url(img/test-2x.png); +} +} + +.test-changed-properties { + order: 4; +} + +@media (-webkit-min-device-pixel-ratio: 1), (min-resolution: 96dpi) { + +.test-changed-properties { + background-image: + url(img/test.png); +} +} + +@media (-webkit-min-device-pixel-ratio: 2), (min-resolution: 192dpi) { + +.test-changed-properties { + background-image: + url(img/test-2x.png); +} +} + +@media (-webkit-min-device-pixel-ratio: 6.25), (min-resolution: 600dpi) { + +.test-changed-properties { + background-image: + url(my-img-print.png); +} +} + +.test-changed-properties { + order: 5; +} + +.test-mixed-units { + order: 1; +} + +@media (-webkit-min-device-pixel-ratio: 1), (min-resolution: 96dpi) { + +.test-mixed-units { + background-image: + url(img/test.png); +} +} + +@media (-webkit-min-device-pixel-ratio: 2), (min-resolution: 192dpi) { + +.test-mixed-units { + background-image: + url(img/test-2x.png); +} +} + +.test-mixed-units { + order: 2; +} + +@media (-webkit-min-device-pixel-ratio: 1), (min-resolution: 96dpi) { + +.test-mixed-units { + background-image: + url(img/test.png); +} +} + +@media (-webkit-min-device-pixel-ratio: 0.52), (min-resolution: 50.8dpi) { + +.test-mixed-units { + background-image: + url(img/test-2x.png); +} +} + +.test-mixed-units { + order: 3; +} + +.test-mixed-order { + order: 1; +} + +@media (-webkit-min-device-pixel-ratio: 1), (min-resolution: 96dpi) { + +.test-mixed-order { + background: + url(../images/bck.png); +} +} + +@media (-webkit-min-device-pixel-ratio: 2), (min-resolution: 192dpi) { + +.test-mixed-order { + background: + url(../images/bck@2x.png); +} +} + +@media (-webkit-min-device-pixel-ratio: 3), (min-resolution: 288dpi) { + +.test-mixed-order { + background: + url(../images/bck@3x.png); +} +} + +.test-mixed-order { + order: 2; +} + +@media (-webkit-min-device-pixel-ratio: 1), (min-resolution: 96dpi) { + +.test-mixed-order { + background: + url(../images/bck.png); +} +} + +@media (-webkit-min-device-pixel-ratio: 2), (min-resolution: 192dpi) { + +.test-mixed-order { + background: + url(../images/bck@2x.png); +} +} + +@media (-webkit-min-device-pixel-ratio: 3), (min-resolution: 288dpi) { + +.test-mixed-order { + background: + url(../images/bck@3x.png); +} +} + +.test-mixed-order { + order: 3; +} + +.test-no-url { + order: 1; +} + +@media (-webkit-min-device-pixel-ratio: 1), (min-resolution: 96dpi) { + +.test-no-url { + background-image: img/test.png; +} +} + +@media (-webkit-min-device-pixel-ratio: 2), (min-resolution: 192dpi) { + +.test-no-url { + background-image: img/test-2x.png; +} +} + +.test-no-url { + order: 2; +} + +@media (-webkit-min-device-pixel-ratio: 1), (min-resolution: 96dpi) { + +.test-no-url { + background-image: img/test.png; +} +} + +@media (-webkit-min-device-pixel-ratio: 2), (min-resolution: 192dpi) { + +.test-no-url { + background-image: img/test-2x.png; +} +} + +@media (-webkit-min-device-pixel-ratio: 6.25), (min-resolution: 600dpi) { + +.test-no-url { + background-image: my-img-print.png; +} +} + +.test-no-url { + order: 3; +} + +.test-webkit-prefix { + order: 1; +} + +@media (-webkit-min-device-pixel-ratio: 1), (min-resolution: 96dpi) { + +.test-webkit-prefix { + background-image: + url(img/test.png); +} +} + +@media (-webkit-min-device-pixel-ratio: 2), (min-resolution: 192dpi) { + +.test-webkit-prefix { + background-image: + url(img/test-2x.png); +} +} + +@media (-webkit-min-device-pixel-ratio: 6.25), (min-resolution: 600dpi) { + +.test-webkit-prefix { + background-image: + url(my-img-print.png); +} +} + +.test-webkit-prefix { + order: 2; +} + +@media (min-width: 1000px) { + @media (-webkit-min-device-pixel-ratio: 1), (min-resolution: 96dpi) { + .test-within-mq-1 { + background-image: + url(img/test.png); + } + } + @media (-webkit-min-device-pixel-ratio: 2), (min-resolution: 192dpi) { + .test-within-mq-1 { + background-image: + url(img/test-2x.png); + } + } + @media (-webkit-min-device-pixel-ratio: 6.25), (min-resolution: 600dpi) { + .test-within-mq-1 { + background-image: + url(my-img-print.png); + } + } +} + +@media (min-width: 768px) and (max-width: 1024px) { + @media (-webkit-min-device-pixel-ratio: 1), (min-resolution: 96dpi) { + .test-within-mq-2 { + background-image: + url(img/test.png); + } + } + @media (-webkit-min-device-pixel-ratio: 2), (min-resolution: 192dpi) { + .test-within-mq-2 { + background-image: + url(img/test-2x.png); + } + } + @media (-webkit-min-device-pixel-ratio: 6.25), (min-resolution: 600dpi) { + .test-within-mq-2 { + background-image: + url(my-img-print.png); + } + } +} diff --git a/test/invalid.css b/test/invalid.css new file mode 100644 index 0000000000..1691f24d8d --- /dev/null +++ b/test/invalid.css @@ -0,0 +1,52 @@ +.test-invalid-params { + order: 1; + background-image: image-set(); + order: 2; + background-image: image-set( + url(img/test.png) + ); + order: 3; + background-image: image-set( + 1x + ); + order: 4; +} + +.test-invalid-commas { + order: 1; + background-image: image-set( + url(img/test.png) 1x, + ); + order: 2; + background-image: image-set( + url(img/test.png) 1x, + url(img/test-2x.png) 2x, + ); + order: 3; +} + +.test-invalid-images { + order: 1; + background: image-set( + image-set( + url(img/test.png) 1x + ) 1x + ); + order: 2; + background: image-set( + calc(1rem + 1px) 1x + ); + order: 3; +} + +.test-invalid-resolutions { + order: 1; + background-image: image-set( + url(img/test.png) 1 + ); + order: 2; + background-image: image-set( + url(img/test.png) 1omg + ); + order: 3; +} From 1060925936d0f0776792f1674a9ff99653965a86 Mon Sep 17 00:00:00 2001 From: Jonathan Neal Date: Mon, 7 May 2018 20:30:07 -0400 Subject: [PATCH 614/795] Sort images by DPR and use the lowest as the default --- README.md | 23 +++++++-- lib/get-media.js | 10 ++-- lib/process-image-set.js | 40 ++++++++------ test/basic.expect.css | 86 +------------------------------ test/basic.no-preserve.expect.css | 80 +--------------------------- 5 files changed, 51 insertions(+), 188 deletions(-) diff --git a/README.md b/README.md index 49c88f0d08..a870bb4b21 100644 --- a/README.md +++ b/README.md @@ -21,10 +21,8 @@ specification. /* becomes */ -@media (-webkit-min-device-pixel-ratio: 1), (min-resolution: 96dpi) { - .example { - background-image: url(img.png); - } +.example { + background-image: url(img.png); } @media (-webkit-min-device-pixel-ratio: 2), (min-resolution: 192dpi) { @@ -228,6 +226,23 @@ postcssImageSetFunction({ oninvalid: 'warning' }) // warn on invalid usages postcssImageSetFunction({ oninvalid: 'throw' }) // throw on invalid usages ``` +## Image Resolution + +The `image-set()` function allows an author to provide multiple resolutions of +an image and let the browser decide which is most appropriate in a given +situation. The `image-set()` also never fails to choose an image; the +`` just helps determine which of the images is chosen. + +Since this plugin is not a browser, the image options are sorted by device +pixel ratio and the lowest ratio is used as the default, while the remaining +images are pushed behind media queries. + +Therefore, this plugin can only approximate native browser behavior. While +images should typically match the resolution as the device they’re being viewed +in, other factors can affect the chosen image. For example, if the user is on a +slow mobile connection, the browser may prefer to select a lower-res image +rather than wait for a larger, resolution-matching image to load. + [cli-img]: https://img.shields.io/travis/jonathantneal/postcss-image-set-function.svg [cli-url]: https://travis-ci.org/jonathantneal/postcss-image-set-function [css-img]: https://cssdb.org/badge/image-set-function.svg diff --git a/lib/get-media.js b/lib/get-media.js index 84c2edbbf4..5482dea4c0 100644 --- a/lib/get-media.js +++ b/lib/get-media.js @@ -3,18 +3,18 @@ import postcss from 'postcss'; const dpiRatios = { dpcm: 2.54, dpi: 1, dppx: 96, x: 96 }; // return a valid @media rule -export default (node, mediasByDpi) => { +export default (node, mediasByDpr) => { if (Object(node).type === 'number' && node.unit in dpiRatios) { // calculate min-device-pixel-ratio and min-resolution const dpi = Number(node.value) * dpiRatios[node.unit.toLowerCase()]; - const pxRatio = Math.floor(dpi / dpiRatios.x * 100) / 100; + const dpr = Math.floor(dpi / dpiRatios.x * 100) / 100; - if (dpi in mediasByDpi) { + if (dpi in mediasByDpr) { return false; } else { - const media = mediasByDpi[dpi] = postcss.atRule({ + const media = mediasByDpr[dpi] = postcss.atRule({ name: 'media', - params: `(-webkit-min-device-pixel-ratio: ${pxRatio}), (min-resolution: ${dpi}dpi)` + params: `(-webkit-min-device-pixel-ratio: ${dpr}), (min-resolution: ${dpi}dpi)` }); return media; diff --git a/lib/process-image-set.js b/lib/process-image-set.js index 7d15da6272..2a3293528d 100644 --- a/lib/process-image-set.js +++ b/lib/process-image-set.js @@ -5,7 +5,7 @@ import handleInvalidation from './handle-invalidation'; export default (imageSetOptionNodes, decl, opts) => { const parent = decl.parent; - const mediasByDpi = {}; + const mediasByDpr = {}; let length = imageSetOptionNodes.length; let index = -1; @@ -14,7 +14,7 @@ export default (imageSetOptionNodes, decl, opts) => { const [comma, value, media] = [ index < 0 ? true : getComma(imageSetOptionNodes[index]), getImage(imageSetOptionNodes[index + 1]), - getMedia(imageSetOptionNodes[index + 2], mediasByDpi) + getMedia(imageSetOptionNodes[index + 2], mediasByDpr) ]; // handle invalidations @@ -36,29 +36,35 @@ export default (imageSetOptionNodes, decl, opts) => { index += 3 } - const medias = Object.keys(mediasByDpi).map(params => mediasByDpi[params]); + const medias = Object.keys(mediasByDpr).sort((a, b) => a - b).map(params => mediasByDpr[params]); // conditionally prepend previous siblings if (medias.length) { - const siblings = parent.nodes; - const previousSiblings = siblings.slice(0, siblings.indexOf(decl)); + const firstDecl = medias[0].nodes[0].nodes[0]; - if (previousSiblings.length) { - const parentClone = parent.cloneBefore().removeAll(); + if (medias.length === 1) { + decl.value = firstDecl.value + } else { + const siblings = parent.nodes; + const previousSiblings = siblings.slice(0, siblings.indexOf(decl)).concat(firstDecl); - parentClone.append(previousSiblings); - } + if (previousSiblings.length) { + const parentClone = parent.cloneBefore().removeAll(); + + parentClone.append(previousSiblings); + } - // prepend any @media { decl: } rules - parent.before(medias); + // prepend any @media { decl: } rules + parent.before(medias.slice(1)); - // conditionally remove the current rule - if (!opts.preserve) { - decl.remove(); + // conditionally remove the current rule + if (!opts.preserve) { + decl.remove(); - // and then conditionally remove its parent - if (!parent.nodes.length) { - parent.remove(); + // and then conditionally remove its parent + if (!parent.nodes.length) { + parent.remove(); + } } } } diff --git a/test/basic.expect.css b/test/basic.expect.css index 5c9fe830e1..fd6c2435a1 100644 --- a/test/basic.expect.css +++ b/test/basic.expect.css @@ -8,45 +8,15 @@ .test-changed-properties { order: 1; -} - -@media (-webkit-min-device-pixel-ratio: 1), (min-resolution: 96dpi) { - -.test-changed-properties { background-image: url(img/test.png); -} -} - -.test-changed-properties { - background-image: image-set( - url(img/test.png) 1x - ); order: 2; -} - -@media (-webkit-min-device-pixel-ratio: 2), (min-resolution: 192dpi) { - -.test-changed-properties { background-image: url(img/test.png); -} -} - -.test-changed-properties { - background-image: image-set( - url(img/test.png) 2x - ); order: 3; -} - -@media (-webkit-min-device-pixel-ratio: 1), (min-resolution: 96dpi) { - -.test-changed-properties { background-image: url(img/test.png); } -} @media (-webkit-min-device-pixel-ratio: 2), (min-resolution: 192dpi) { @@ -62,15 +32,9 @@ url(img/test-2x.png) 2x ); order: 4; -} - -@media (-webkit-min-device-pixel-ratio: 1), (min-resolution: 96dpi) { - -.test-changed-properties { background-image: url(img/test.png); } -} @media (-webkit-min-device-pixel-ratio: 2), (min-resolution: 192dpi) { @@ -99,15 +63,9 @@ .test-mixed-units { order: 1; -} - -@media (-webkit-min-device-pixel-ratio: 1), (min-resolution: 96dpi) { - -.test-mixed-units { background-image: url(img/test.png); } -} @media (-webkit-min-device-pixel-ratio: 2), (min-resolution: 192dpi) { @@ -123,6 +81,8 @@ url(img/test-2x.png) 2dppx ); order: 2; + background-image: + url(img/test-2x.png); } @media (-webkit-min-device-pixel-ratio: 1), (min-resolution: 96dpi) { @@ -133,14 +93,6 @@ } } -@media (-webkit-min-device-pixel-ratio: 0.52), (min-resolution: 50.8dpi) { - -.test-mixed-units { - background-image: - url(img/test-2x.png); -} -} - .test-mixed-units { background-image: image-set( url(img/test.png) 1x, @@ -151,15 +103,9 @@ .test-mixed-order { order: 1; -} - -@media (-webkit-min-device-pixel-ratio: 1), (min-resolution: 96dpi) { - -.test-mixed-order { background: url(../images/bck.png); } -} @media (-webkit-min-device-pixel-ratio: 2), (min-resolution: 192dpi) { @@ -184,15 +130,9 @@ url(../images/bck@2x.png) 2x ); order: 2; -} - -@media (-webkit-min-device-pixel-ratio: 1), (min-resolution: 96dpi) { - -.test-mixed-order { background: url(../images/bck.png); } -} @media (-webkit-min-device-pixel-ratio: 2), (min-resolution: 192dpi) { @@ -221,14 +161,8 @@ .test-no-url { order: 1; -} - -@media (-webkit-min-device-pixel-ratio: 1), (min-resolution: 96dpi) { - -.test-no-url { background-image: img/test.png; } -} @media (-webkit-min-device-pixel-ratio: 2), (min-resolution: 192dpi) { @@ -243,14 +177,8 @@ "img/test-2x.png" 2x ); order: 2; -} - -@media (-webkit-min-device-pixel-ratio: 1), (min-resolution: 96dpi) { - -.test-no-url { background-image: img/test.png; } -} @media (-webkit-min-device-pixel-ratio: 2), (min-resolution: 192dpi) { @@ -277,15 +205,9 @@ .test-webkit-prefix { order: 1; -} - -@media (-webkit-min-device-pixel-ratio: 1), (min-resolution: 96dpi) { - -.test-webkit-prefix { background-image: url(img/test.png); } -} @media (-webkit-min-device-pixel-ratio: 2), (min-resolution: 192dpi) { @@ -313,12 +235,10 @@ } @media (min-width: 1000px) { - @media (-webkit-min-device-pixel-ratio: 1), (min-resolution: 96dpi) { .test-within-mq-1 { background-image: url(img/test.png); } - } @media (-webkit-min-device-pixel-ratio: 2), (min-resolution: 192dpi) { .test-within-mq-1 { background-image: @@ -341,12 +261,10 @@ } @media (min-width: 768px) and (max-width: 1024px) { - @media (-webkit-min-device-pixel-ratio: 1), (min-resolution: 96dpi) { .test-within-mq-2 { background-image: url(img/test.png); } - } @media (-webkit-min-device-pixel-ratio: 2), (min-resolution: 192dpi) { .test-within-mq-2 { background-image: diff --git a/test/basic.no-preserve.expect.css b/test/basic.no-preserve.expect.css index d28790c0fa..4f594a9237 100644 --- a/test/basic.no-preserve.expect.css +++ b/test/basic.no-preserve.expect.css @@ -8,39 +8,15 @@ .test-changed-properties { order: 1; -} - -@media (-webkit-min-device-pixel-ratio: 1), (min-resolution: 96dpi) { - -.test-changed-properties { background-image: url(img/test.png); -} -} - -.test-changed-properties { order: 2; -} - -@media (-webkit-min-device-pixel-ratio: 2), (min-resolution: 192dpi) { - -.test-changed-properties { background-image: url(img/test.png); -} -} - -.test-changed-properties { order: 3; -} - -@media (-webkit-min-device-pixel-ratio: 1), (min-resolution: 96dpi) { - -.test-changed-properties { background-image: url(img/test.png); } -} @media (-webkit-min-device-pixel-ratio: 2), (min-resolution: 192dpi) { @@ -52,15 +28,9 @@ .test-changed-properties { order: 4; -} - -@media (-webkit-min-device-pixel-ratio: 1), (min-resolution: 96dpi) { - -.test-changed-properties { background-image: url(img/test.png); } -} @media (-webkit-min-device-pixel-ratio: 2), (min-resolution: 192dpi) { @@ -84,15 +54,9 @@ .test-mixed-units { order: 1; -} - -@media (-webkit-min-device-pixel-ratio: 1), (min-resolution: 96dpi) { - -.test-mixed-units { background-image: url(img/test.png); } -} @media (-webkit-min-device-pixel-ratio: 2), (min-resolution: 192dpi) { @@ -104,6 +68,8 @@ .test-mixed-units { order: 2; + background-image: + url(img/test-2x.png); } @media (-webkit-min-device-pixel-ratio: 1), (min-resolution: 96dpi) { @@ -114,29 +80,15 @@ } } -@media (-webkit-min-device-pixel-ratio: 0.52), (min-resolution: 50.8dpi) { - -.test-mixed-units { - background-image: - url(img/test-2x.png); -} -} - .test-mixed-units { order: 3; } .test-mixed-order { order: 1; -} - -@media (-webkit-min-device-pixel-ratio: 1), (min-resolution: 96dpi) { - -.test-mixed-order { background: url(../images/bck.png); } -} @media (-webkit-min-device-pixel-ratio: 2), (min-resolution: 192dpi) { @@ -156,15 +108,9 @@ .test-mixed-order { order: 2; -} - -@media (-webkit-min-device-pixel-ratio: 1), (min-resolution: 96dpi) { - -.test-mixed-order { background: url(../images/bck.png); } -} @media (-webkit-min-device-pixel-ratio: 2), (min-resolution: 192dpi) { @@ -188,14 +134,8 @@ .test-no-url { order: 1; -} - -@media (-webkit-min-device-pixel-ratio: 1), (min-resolution: 96dpi) { - -.test-no-url { background-image: img/test.png; } -} @media (-webkit-min-device-pixel-ratio: 2), (min-resolution: 192dpi) { @@ -206,14 +146,8 @@ .test-no-url { order: 2; -} - -@media (-webkit-min-device-pixel-ratio: 1), (min-resolution: 96dpi) { - -.test-no-url { background-image: img/test.png; } -} @media (-webkit-min-device-pixel-ratio: 2), (min-resolution: 192dpi) { @@ -235,15 +169,9 @@ .test-webkit-prefix { order: 1; -} - -@media (-webkit-min-device-pixel-ratio: 1), (min-resolution: 96dpi) { - -.test-webkit-prefix { background-image: url(img/test.png); } -} @media (-webkit-min-device-pixel-ratio: 2), (min-resolution: 192dpi) { @@ -266,12 +194,10 @@ } @media (min-width: 1000px) { - @media (-webkit-min-device-pixel-ratio: 1), (min-resolution: 96dpi) { .test-within-mq-1 { background-image: url(img/test.png); } - } @media (-webkit-min-device-pixel-ratio: 2), (min-resolution: 192dpi) { .test-within-mq-1 { background-image: @@ -287,12 +213,10 @@ } @media (min-width: 768px) and (max-width: 1024px) { - @media (-webkit-min-device-pixel-ratio: 1), (min-resolution: 96dpi) { .test-within-mq-2 { background-image: url(img/test.png); } - } @media (-webkit-min-device-pixel-ratio: 2), (min-resolution: 192dpi) { .test-within-mq-2 { background-image: From 1aaca7dddfe889ce34e805dd4e5175b4d76e6e34 Mon Sep 17 00:00:00 2001 From: Jonathan Neal Date: Mon, 7 May 2018 20:30:25 -0400 Subject: [PATCH 615/795] 2.0.0 --- CHANGELOG.md | 4 ++++ package.json | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8526ab9f2d..9119c00317 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # Changes to PostCSS image-set() Function +### 2.0.0 (May 7, 2018) + +- Sort images by DPR and use the lowest as the default + ### 1.0.0 (May 2, 2018) - Initial version diff --git a/package.json b/package.json index aa64676dbb..e47c16fb8d 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "postcss-image-set-function", - "version": "1.0.0", + "version": "2.0.0", "description": "Display resolution-dependent images using the image-set() function in CSS", "author": "Jonathan Neal ", "license": "CC0-1.0", From 0da9daa789c2aa99ae3577656d45ec1dddc77020 Mon Sep 17 00:00:00 2001 From: Jonathan Neal Date: Mon, 7 May 2018 22:19:20 -0400 Subject: [PATCH 616/795] 1.0.0 --- .appveyor.yml | 18 +++ .editorconfig | 15 +++ .gitignore | 12 ++ .rollup.js | 16 +++ .tape.js | 13 ++ .travis.yml | 9 ++ CHANGELOG.md | 5 + CONTRIBUTING.md | 65 +++++++++ LICENSE.md | 108 +++++++++++++++ README.md | 202 ++++++++++++++++++++++++++++ index.js | 98 ++++++++++++++ package.json | 64 +++++++++ test/basic.css | 46 +++++++ test/basic.expect.css | 46 +++++++ test/basic.preserve-true.expect.css | 69 ++++++++++ 15 files changed, 786 insertions(+) create mode 100644 .appveyor.yml create mode 100644 .editorconfig create mode 100644 .gitignore create mode 100644 .rollup.js create mode 100644 .tape.js create mode 100644 .travis.yml create mode 100644 CHANGELOG.md create mode 100644 CONTRIBUTING.md create mode 100644 LICENSE.md create mode 100644 README.md create mode 100644 index.js create mode 100644 package.json create mode 100644 test/basic.css create mode 100644 test/basic.expect.css create mode 100644 test/basic.preserve-true.expect.css diff --git a/.appveyor.yml b/.appveyor.yml new file mode 100644 index 0000000000..acbf8a5eeb --- /dev/null +++ b/.appveyor.yml @@ -0,0 +1,18 @@ +# https://www.appveyor.com/docs/appveyor-yml + +environment: + matrix: + - nodejs_version: 4 + +version: "{build}" +build: off +deploy: off + +install: + - ps: Install-Product node $env:nodejs_version + - npm install --ignore-scripts + +test_script: + - node --version + - npm --version + - cmd: "npm test" diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000000..e06d7982bc --- /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/.gitignore b/.gitignore new file mode 100644 index 0000000000..de73e5a338 --- /dev/null +++ b/.gitignore @@ -0,0 +1,12 @@ +node_modules +index.*.js +package-lock.json +*.log* +*.result.css +.* +!.appveyor.yml +!.editorconfig +!.gitignore +!.rollup.js +!.tape.js +!.travis.yml diff --git a/.rollup.js b/.rollup.js new file mode 100644 index 0000000000..0436758216 --- /dev/null +++ b/.rollup.js @@ -0,0 +1,16 @@ +import babel from 'rollup-plugin-babel'; + +export default { + input: 'index.js', + output: [ + { file: 'index.cjs.js', format: 'cjs' }, + { file: 'index.es.js', format: 'es' } + ], + plugins: [ + babel({ + presets: [ + ['env', { modules: false, targets: { node: 4 } }] + ] + }) + ] +}; diff --git a/.tape.js b/.tape.js new file mode 100644 index 0000000000..4c8f446b52 --- /dev/null +++ b/.tape.js @@ -0,0 +1,13 @@ +module.exports = { + 'postcss-color-functional-notation': { + 'basic': { + message: 'supports basic usage' + }, + 'basic:preserve-true': { + message: 'supports { preserve: true } usage', + options: { + preserve: true + } + } + } +}; diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000000..c56466446c --- /dev/null +++ b/.travis.yml @@ -0,0 +1,9 @@ +# https://docs.travis-ci.com/user/travis-lint + +language: node_js + +node_js: + - 4 + +install: + - npm install --ignore-scripts diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000000..c229c7f419 --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,5 @@ +# Changes to PostCSS Color Functional Notation + +### 1.0.0 (May 7, 2018) + +- Initial version diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 0000000000..b336ebf048 --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,65 @@ +# Contributing to PostCSS Color Functional Notation + +You want to help? You rock! Now, take a moment to be sure your contributions +make sense to everyone else. + +## Reporting Issues + +Found a problem? Want a new feature? + +- See if your issue or idea has [already been reported]. +- Provide a [reduced test case] or a [live example]. + +Remember, a bug is a _demonstrable problem_ caused by _our_ code. + +## Submitting Pull Requests + +Pull requests are the greatest contributions, so be sure they are focused in +scope and avoid unrelated commits. + +1. To begin; [fork this project], clone your fork, and add our upstream. + ```bash + # Clone your fork of the repo into the current directory + git clone git@github.com:YOUR_USER/postcss-color-functional-notation.git + + # Navigate to the newly cloned directory + cd postcss-color-functional-notation + + # Assign the original repo to a remote called "upstream" + git remote add upstream git@github.com:jonathantneal/postcss-color-functional-notation.git + + # Install the tools necessary for testing + npm install + ``` + +2. Create a branch for your feature or fix: + ```bash + # Move into a new branch for your feature + git checkout -b feature/thing + ``` + ```bash + # Move into a new branch for your fix + git checkout -b fix/something + ``` + +3. If your code follows our practices, then push your feature branch: + ```bash + # Test current code + npm test + ``` + ```bash + # Push the branch for your new feature + git push origin feature/thing + ``` + ```bash + # Or, push the branch for your update + git push origin update/something + ``` + +That’s it! Now [open a pull request] with a clear title and description. + +[already been reported]: issues +[fork this project]: fork +[live example]: https://codepen.io/pen +[open a pull request]: https://help.github.com/articles/using-pull-requests/ +[reduced test case]: https://css-tricks.com/reduced-test-cases/ diff --git a/LICENSE.md b/LICENSE.md new file mode 100644 index 0000000000..0bc1fa7060 --- /dev/null +++ b/LICENSE.md @@ -0,0 +1,108 @@ +# CC0 1.0 Universal + +## Statement of Purpose + +The laws of most jurisdictions throughout the world automatically confer +exclusive Copyright and Related Rights (defined below) upon the creator and +subsequent owner(s) (each and all, an “owner”) of an original work of +authorship and/or a database (each, a “Work”). + +Certain owners wish to permanently relinquish those rights to a Work for the +purpose of contributing to a commons of creative, cultural and scientific works +(“Commons”) that the public can reliably and without fear of later claims of +infringement build upon, modify, incorporate in other works, reuse and +redistribute as freely as possible in any form whatsoever and for any purposes, +including without limitation commercial purposes. These owners may contribute +to the Commons to promote the ideal of a free culture and the further +production of creative, cultural and scientific works, or to gain reputation or +greater distribution for their Work in part through the use and efforts of +others. + +For these and/or other purposes and motivations, and without any expectation of +additional consideration or compensation, the person associating CC0 with a +Work (the “Affirmer”), to the extent that he or she is an owner of Copyright +and Related Rights in the Work, voluntarily elects to apply CC0 to the Work and +publicly distribute the Work under its terms, with knowledge of his or her +Copyright and Related Rights in the Work and the meaning and intended legal +effect of CC0 on those rights. + +1. Copyright and Related Rights. A Work made available under CC0 may be + protected by copyright and related or neighboring rights (“Copyright and + Related Rights”). Copyright and Related Rights include, but are not limited + to, the following: + 1. the right to reproduce, adapt, distribute, perform, display, communicate, + and translate a Work; + 2. moral rights retained by the original author(s) and/or performer(s); + 3. publicity and privacy rights pertaining to a person’s image or likeness + depicted in a Work; + 4. rights protecting against unfair competition in regards to a Work, + subject to the limitations in paragraph 4(i), below; + 5. rights protecting the extraction, dissemination, use and reuse of data in + a Work; + 6. database rights (such as those arising under Directive 96/9/EC of the + European Parliament and of the Council of 11 March 1996 on the legal + protection of databases, and under any national implementation thereof, + including any amended or successor version of such directive); and + 7. other similar, equivalent or corresponding rights throughout the world + based on applicable law or treaty, and any national implementations + thereof. + +2. Waiver. To the greatest extent permitted by, but not in contravention of, + applicable law, Affirmer hereby overtly, fully, permanently, irrevocably and + unconditionally waives, abandons, and surrenders all of Affirmer’s Copyright + and Related Rights and associated claims and causes of action, whether now + known or unknown (including existing as well as future claims and causes of + action), in the Work (i) in all territories worldwide, (ii) for the maximum + duration provided by applicable law or treaty (including future time + extensions), (iii) in any current or future medium and for any number of + copies, and (iv) for any purpose whatsoever, including without limitation + commercial, advertising or promotional purposes (the “Waiver”). Affirmer + makes the Waiver for the benefit of each member of the public at large and + to the detriment of Affirmer’s heirs and successors, fully intending that + such Waiver shall not be subject to revocation, rescission, cancellation, + termination, or any other legal or equitable action to disrupt the quiet + enjoyment of the Work by the public as contemplated by Affirmer’s express + Statement of Purpose. + +3. Public License Fallback. Should any part of the Waiver for any reason be + judged legally invalid or ineffective under applicable law, then the Waiver + shall be preserved to the maximum extent permitted taking into account + Affirmer’s express Statement of Purpose. In addition, to the extent the + Waiver is so judged Affirmer hereby grants to each affected person a + royalty-free, non transferable, non sublicensable, non exclusive, + irrevocable and unconditional license to exercise Affirmer’s Copyright and + Related Rights in the Work (i) in all territories worldwide, (ii) for the + maximum duration provided by applicable law or treaty (including future time + extensions), (iii) in any current or future medium and for any number of + copies, and (iv) for any purpose whatsoever, including without limitation + commercial, advertising or promotional purposes (the “License”). The License + shall be deemed effective as of the date CC0 was applied by Affirmer to the + Work. Should any part of the License for any reason be judged legally + invalid or ineffective under applicable law, such partial invalidity or + ineffectiveness shall not invalidate the remainder of the License, and in + such case Affirmer hereby affirms that he or she will not (i) exercise any + of his or her remaining Copyright and Related Rights in the Work or (ii) + assert any associated claims and causes of action with respect to the Work, + in either case contrary to Affirmer’s express Statement of Purpose. + +4. Limitations and Disclaimers. + 1. No trademark or patent rights held by Affirmer are waived, abandoned, + surrendered, licensed or otherwise affected by this document. + 2. Affirmer offers the Work as-is and makes no representations or warranties + of any kind concerning the Work, express, implied, statutory or + otherwise, including without limitation warranties of title, + merchantability, fitness for a particular purpose, non infringement, or + the absence of latent or other defects, accuracy, or the present or + absence of errors, whether or not discoverable, all to the greatest + extent permissible under applicable law. + 3. Affirmer disclaims responsibility for clearing rights of other persons + that may apply to the Work or any use thereof, including without + limitation any person’s Copyright and Related Rights in the Work. + Further, Affirmer disclaims responsibility for obtaining any necessary + consents, permissions or other rights required for any use of the Work. + 4. Affirmer understands and acknowledges that Creative Commons is not a + party to this document and has no duty or obligation with respect to this + CC0 or use of the Work. + +For more information, please see +http://creativecommons.org/publicdomain/zero/1.0/. diff --git a/README.md b/README.md new file mode 100644 index 0000000000..7f450274af --- /dev/null +++ b/README.md @@ -0,0 +1,202 @@ +# PostCSS Color Functional Notation [PostCSS Logo][postcss] + +[![NPM Version][npm-img]][npm-url] +[![CSS Standard Status][css-img]][css-url] +[![Build Status][cli-img]][cli-url] +[![Windows Build Status][win-img]][win-url] +[![Support Chat][git-img]][git-url] + +[PostCSS Color Functional Notation] lets you use space and slash separated +color notation in CSS, following the [CSS Color] specification. + +```pcss +:root { + --firebrick: rgb(178 34 34); + --firebrick-a50: color: rgb(70% 13.5% 13.5% / 50%); + --firebrick-hsl: color: hsla(0 68% 42%); + --firebrick-hsl-a50: color: hsl(0 68% 42% / 50%); +} + +/* becomes */ + +:root { + --firebrick: rgb(178, 34, 34); + --firebrick-a50: color: rgba(178, 34, 34, .5); + --firebrick-hsl: color: hsl(0, 68%, 42%); + --firebrick-hsl-a50: color: hsla(0, 68%, 42%, .5); +} +``` + +## Usage + +Add [PostCSS Color Functional Notation] to your build tool: + +```bash +npm install postcss-color-functional-notation --save-dev +``` + +#### Node + +Use [PostCSS Color Functional Notation] to process your CSS: + +```js +import postcssColorFunctionalNotation from 'postcss-color-functional-notation'; + +postcssColorFunctionalNotation.process(YOUR_CSS, /* processOptions */, /* pluginOptions */); +``` + +#### PostCSS + +Add [PostCSS] to your build tool: + +```bash +npm install postcss --save-dev +``` + +Use [PostCSS Color Functional Notation] as a plugin: + +```js +import postcss from 'gulp-postcss'; +import postcssColorFunctionalNotation from 'postcss-color-functional-notation'; + +postcss([ + postcssColorFunctionalNotation(/* pluginOptions */) +]).process(YOUR_CSS); +``` + +#### Webpack + +Add [PostCSS Loader] to your build tool: + +```bash +npm install postcss-loader --save-dev +``` + +Use [PostCSS Color Functional Notation] in your Webpack configuration: + +```js +import postcssColorFunctionalNotation from 'postcss-color-functional-notation'; + +module.exports = { + module: { + rules: [ + { + test: /\.css$/, + use: [ + 'style-loader', + { loader: 'css-loader', options: { importLoaders: 1 } }, + { loader: 'postcss-loader', options: { + ident: 'postcss', + plugins: () => [ + postcssColorFunctionalNotation(/* pluginOptions */) + ] + } } + ] + } + ] + } +} +``` + +#### Gulp + +Add [Gulp PostCSS] to your build tool: + +```bash +npm install gulp-postcss --save-dev +``` + +Use [PostCSS Color Functional Notation] in your Gulpfile: + +```js +import postcss from 'gulp-postcss'; +import postcssColorFunctionalNotation from 'postcss-color-functional-notation'; + +gulp.task('css', () => gulp.src('./src/*.css').pipe( + postcss([ + postcssColorFunctionalNotation(/* pluginOptions */) + ]) +).pipe( + gulp.dest('.') +)); +``` + +#### Grunt + +Add [Grunt PostCSS] to your build tool: + +```bash +npm install grunt-postcss --save-dev +``` + +Use [PostCSS Color Functional Notation] in your Gruntfile: + +```js +import postcssColorFunctionalNotation from 'postcss-color-functional-notation'; + +grunt.loadNpmTasks('grunt-postcss'); + +grunt.initConfig({ + postcss: { + options: { + use: [ + postcssColorFunctionalNotation(/* pluginOptions */) + ] + }, + dist: { + src: '*.css' + } + } +}); +``` + +## Options + +### preserve + +The `preserve` option determines whether the original functional color notation +is preserved. By default, it is not preserved. + +```js +postcssImageSetFunction({ preserve: true }) +``` + +```pcss +:root { + --firebrick: rgb(178 34 34); + --firebrick-a50: color: rgb(70% 13.5% 13.5% / 50%); + --firebrick-hsl: color: hsla(0 68% 42%); + --firebrick-hsl-a50: color: hsl(0 68% 42% / 50%); +} + +/* becomes */ + +:root { + --firebrick: rgb(178, 34, 34); + --firebrick: rgb(178 34 34); + --firebrick-a50: color: rgba(178, 34, 34, .5); + --firebrick-a50: color: rgb(70% 13.5% 13.5% / 50%); + --firebrick-hsl: color: hsl(0, 68%, 42%); + --firebrick-hsl: color: hsla(0 68% 42%); + --firebrick-hsl-a50: color: hsla(0, 68%, 42%, .5); + --firebrick-hsl-a50: color: hsl(0 68% 42% / 50%); +} +``` + +[cli-img]: https://img.shields.io/travis/jonathantneal/postcss-color-functional-notation.svg +[cli-url]: https://travis-ci.org/jonathantneal/postcss-color-functional-notation +[css-img]: https://cssdb.org/badge/color-functional-notation.svg +[css-url]: https://cssdb.org/#color-functional-notation +[git-img]: https://img.shields.io/badge/support-chat-blue.svg +[git-url]: https://gitter.im/postcss/postcss +[npm-img]: https://img.shields.io/npm/v/postcss-color-functional-notation.svg +[npm-url]: https://www.npmjs.com/package/postcss-color-functional-notation +[win-img]: https://img.shields.io/appveyor/ci/jonathantneal/postcss-color-functional-notation.svg +[win-url]: https://ci.appveyor.com/project/jonathantneal/postcss-color-functional-notation + +[CSS Color]: https://drafts.csswg.org/css-color/#ref-for-funcdef-rgb%E2%91%A1%E2%91%A0 +[Gulp PostCSS]: https://github.com/postcss/gulp-postcss +[Grunt PostCSS]: https://github.com/nDmitry/grunt-postcss +[PostCSS]: https://github.com/postcss/postcss +[PostCSS Loader]: https://github.com/postcss/postcss-loader +[PostCSS Color Functional Notation]: https://github.com/jonathantneal/postcss-color-functional-notation diff --git a/index.js b/index.js new file mode 100644 index 0000000000..4e00f5f56f --- /dev/null +++ b/index.js @@ -0,0 +1,98 @@ +import postcss from 'postcss'; +import parser from 'postcss-values-parser'; + +const colorAnyRegExp = /(^|[^\w-])(hsla?|rgba?)\(/i; +const colorRegExp = /^(hsla?|rgba?)$/i; + +export default postcss.plugin('postcss-color-functional-notation', opts => { + const preserve = 'preserve' in Object(opts) ? Boolean(opts.preserve) : false; + + return root => { + root.walkDecls(decl => { + const { value } = decl; + + if (colorAnyRegExp.test(value)) { + const ast = parser(value).parse(); + + ast.walkType('func', node => { + if (colorRegExp.test(node.value)) { + const children = node.nodes.slice(1, -1); + const isFunctionalHSL = matchFunctionalHSL(children); + const isFunctionalRGB1 = matchFunctionalRGB1(children); + const isFunctionalRGB2 = matchFunctionalRGB2(children); + + if (isFunctionalHSL || isFunctionalRGB1 || isFunctionalRGB2) { + const slashNode = children[3]; + const alphaNode = children[4]; + + if (alphaNode) { + if (isPercentage(alphaNode) && !isCalc(alphaNode)) { + alphaNode.unit = ''; + alphaNode.value = String(alphaNode.value / 100); + } + + if (isHslRgb(node)) { + node.value += 'a'; + } + } else if (isHslaRgba(node)) { + node.value = node.value.slice(0, -1); + } + + if (isSlash(slashNode)) { + slashNode.replaceWith( newComma() ); + } + + if (isFunctionalRGB2) { + children[0].unit = children[1].unit = children[2].unit = ''; + + children[0].value = String(Math.floor(children[0].value * 255 / 100)); + children[1].value = String(Math.floor(children[1].value * 255 / 100)); + children[2].value = String(Math.floor(children[2].value * 255 / 100)); + } + + node.nodes.splice(3, 0, [ newComma() ]); + node.nodes.splice(2, 0, [ newComma() ]); + } + } + }); + + const newValue = String(ast); + + if (preserve) { + decl.cloneBefore({ value: newValue }); + } else { + decl.value = newValue; + } + } + }); + }; +}); + +const alphaUnitMatch = /^%?$/i; +const calcFuncMatch = /^calc$/i; +const hueUnitMatch = /^(deg|grad|rad|turn)?$/i; +const hslRgbFuncMatch = /^(hsl|rgb)$/i; +const hslaRgbaFuncMatch = /^(hsla|rgba)$/i; +const isAlphaValue = node => isCalc(node) || Object(node).type === 'number' && alphaUnitMatch.test(node.unit); +const isCalc = node => Object(node).type === 'func' && calcFuncMatch.test(node.value); +const isHue = node => isCalc(node) || Object(node).type === 'number' && hueUnitMatch.test(node.unit); +const isNumber = node => isCalc(node) || Object(node).type === 'number' && node.unit === ''; +const isPercentage = node => isCalc(node) || Object(node).type === 'number' && node.unit === '%'; +const isHslRgb = node => Object(node).type === 'func' && hslRgbFuncMatch.test(node.value); +const isHslaRgba = node => Object(node).type === 'func' && hslaRgbaFuncMatch.test(node.value); +const isSlash = node => Object(node).type === 'operator' && node.value === '/'; +const functionalHSLMatch = [isHue, isPercentage, isPercentage, isSlash, isAlphaValue]; +const functionalRGB1Match = [isNumber, isNumber, isNumber, isSlash, isAlphaValue]; +const functionalRGB2Match = [isPercentage, isPercentage, isPercentage, isSlash, isAlphaValue]; + +const matchFunctionalHSL = children => children.every( + (child, index) => typeof functionalHSLMatch[index] === 'function' && functionalHSLMatch[index](child) +); +const matchFunctionalRGB1 = children => children.every( + (child, index) => typeof functionalRGB1Match[index] === 'function' && functionalRGB1Match[index](child) +); +const matchFunctionalRGB2 = children => children.every( + (child, index) => typeof functionalRGB2Match[index] === 'function' && functionalRGB2Match[index](child) +); + +const newComma = () => parser.comma({ value: ',' }) diff --git a/package.json b/package.json new file mode 100644 index 0000000000..1a1e867d4c --- /dev/null +++ b/package.json @@ -0,0 +1,64 @@ +{ + "name": "postcss-color-functional-notation", + "version": "1.0.0", + "description": "Use space and slash separated color notation in CSS", + "author": "Jonathan Neal ", + "license": "CC0-1.0", + "repository": "jonathantneal/postcss-color-functional-notation", + "homepage": "https://github.com/jonathantneal/postcss-color-functional-notation#readme", + "bugs": "https://github.com/jonathantneal/postcss-color-functional-notation/issues", + "main": "index.cjs.js", + "module": "index.es.js", + "files": [ + "index.cjs.js", + "index.es.js" + ], + "scripts": { + "prepublishOnly": "npm test", + "pretest": "rollup -c .rollup.js --silent", + "test": "echo 'Running tests...'; npm run test:js && npm run test:tape", + "test:ec": "echint --ignore index.*.js test", + "test:js": "eslint *.js --cache --ignore-path .gitignore --quiet", + "test:tape": "postcss-tape" + }, + "engines": { + "node": ">=4.0.0" + }, + "dependencies": { + "postcss": "^6.0.22", + "postcss-values-parser": "^1.5.0" + }, + "devDependencies": { + "babel-core": "^6.26.3", + "babel-eslint": "^8.2.3", + "babel-preset-env": "^1.6.1", + "eslint": "^4.19.1", + "eslint-config-dev": "^2.0.0", + "postcss-tape": "^2.2.0", + "pre-commit": "^1.2.2", + "rollup": "^0.58.2", + "rollup-plugin-babel": "^3.0.4" + }, + "eslintConfig": { + "extends": "dev", + "parser": "babel-eslint" + }, + "keywords": [ + "postcss", + "css", + "postcss-plugin", + "color", + "colors", + "rgb", + "rgba", + "hsl", + "hsla", + "hwb", + "functional", + "notation", + "design", + "syntax", + "space", + "comma" + ] +} diff --git a/test/basic.css b/test/basic.css new file mode 100644 index 0000000000..4dcca4653e --- /dev/null +++ b/test/basic.css @@ -0,0 +1,46 @@ +.test-rgb { + color: rgb(178 34 34); + color: rgb(178 34 34 / 1); + color: rgb(178 34 34 / .5); + color: rgb(178 34 34 / 100%); + color: rgb(178 34 34 / 50%); +} + +.test-rgba { + color: rgba(178 34 34); + color: rgba(178 34 34 / 1); + color: rgba(178 34 34 / .5); +} + +.test-rgb-percentages { + color: rgba(70% 13.5% 13.5%); + color: rgba(70% 13.5% 13.5% / 100%); + color: rgba(70% 13.5% 13.5% / 50%); +} + +.test-hsl { + color: hsl(120deg 100% 50%); + color: hsl(120 100% 50%); + color: hsl(120 100% 50% / 1); + color: hsl(120 100% 50% / .5); + color: hsl(120 100% 50% / 100%); + color: hsl(120 100% 50% / 50%); + color: hsla(120deg 100% 50%); +} + +.test-hsla { + color: hsla(120 100% 50%); + color: hsla(120 100% 50% / 1); + color: hsla(120 100% 50% / .5); + color: hsla(120 100% 50% / 100%); + color: hsla(120 100% 50% / 50%); +} + +.test-hwb { + color: hwb(0deg 0% 0%); + color: hwb(0 0% 0%); + color: hwb(0 0% 0% / 1); + color: hwb(0 0% 0% / .5); + color: hwb(0 0% 0% / 100%); + color: hwb(0 0% 0% / 50%); +} diff --git a/test/basic.expect.css b/test/basic.expect.css new file mode 100644 index 0000000000..9c0d84b4af --- /dev/null +++ b/test/basic.expect.css @@ -0,0 +1,46 @@ +.test-rgb { + color: rgb(178, 34, 34); + color: rgba(178, 34, 34, 1); + color: rgba(178, 34, 34, .5); + color: rgba(178, 34, 34, 1); + color: rgba(178, 34, 34, 0.5); +} + +.test-rgba { + color: rgb(178, 34, 34); + color: rgba(178, 34, 34, 1); + color: rgba(178, 34, 34, .5); +} + +.test-rgb-percentages { + color: rgb(178, 34, 34); + color: rgba(178, 34, 34, 1); + color: rgba(178, 34, 34, 0.5); +} + +.test-hsl { + color: hsl(120deg, 100%, 50%); + color: hsl(120, 100%, 50%); + color: hsla(120, 100%, 50%, 1); + color: hsla(120, 100%, 50%, .5); + color: hsla(120, 100%, 50%, 1); + color: hsla(120, 100%, 50%, 0.5); + color: hsl(120deg, 100%, 50%); +} + +.test-hsla { + color: hsl(120, 100%, 50%); + color: hsla(120, 100%, 50%, 1); + color: hsla(120, 100%, 50%, .5); + color: hsla(120, 100%, 50%, 1); + color: hsla(120, 100%, 50%, 0.5); +} + +.test-hwb { + color: hwb(0deg 0% 0%); + color: hwb(0 0% 0%); + color: hwb(0 0% 0% / 1); + color: hwb(0 0% 0% / .5); + color: hwb(0 0% 0% / 100%); + color: hwb(0 0% 0% / 50%); +} diff --git a/test/basic.preserve-true.expect.css b/test/basic.preserve-true.expect.css new file mode 100644 index 0000000000..bb946f2515 --- /dev/null +++ b/test/basic.preserve-true.expect.css @@ -0,0 +1,69 @@ +.test-rgb { + color: rgb(178, 34, 34); + color: rgb(178 34 34); + color: rgba(178, 34, 34, 1); + color: rgb(178 34 34 / 1); + color: rgba(178, 34, 34, .5); + color: rgb(178 34 34 / .5); + color: rgba(178, 34, 34, 1); + color: rgb(178 34 34 / 100%); + color: rgba(178, 34, 34, 0.5); + color: rgb(178 34 34 / 50%); +} + +.test-rgba { + color: rgb(178, 34, 34); + color: rgba(178 34 34); + color: rgba(178, 34, 34, 1); + color: rgba(178 34 34 / 1); + color: rgba(178, 34, 34, .5); + color: rgba(178 34 34 / .5); +} + +.test-rgb-percentages { + color: rgb(178, 34, 34); + color: rgba(70% 13.5% 13.5%); + color: rgba(178, 34, 34, 1); + color: rgba(70% 13.5% 13.5% / 100%); + color: rgba(178, 34, 34, 0.5); + color: rgba(70% 13.5% 13.5% / 50%); +} + +.test-hsl { + color: hsl(120deg, 100%, 50%); + color: hsl(120deg 100% 50%); + color: hsl(120, 100%, 50%); + color: hsl(120 100% 50%); + color: hsla(120, 100%, 50%, 1); + color: hsl(120 100% 50% / 1); + color: hsla(120, 100%, 50%, .5); + color: hsl(120 100% 50% / .5); + color: hsla(120, 100%, 50%, 1); + color: hsl(120 100% 50% / 100%); + color: hsla(120, 100%, 50%, 0.5); + color: hsl(120 100% 50% / 50%); + color: hsl(120deg, 100%, 50%); + color: hsla(120deg 100% 50%); +} + +.test-hsla { + color: hsl(120, 100%, 50%); + color: hsla(120 100% 50%); + color: hsla(120, 100%, 50%, 1); + color: hsla(120 100% 50% / 1); + color: hsla(120, 100%, 50%, .5); + color: hsla(120 100% 50% / .5); + color: hsla(120, 100%, 50%, 1); + color: hsla(120 100% 50% / 100%); + color: hsla(120, 100%, 50%, 0.5); + color: hsla(120 100% 50% / 50%); +} + +.test-hwb { + color: hwb(0deg 0% 0%); + color: hwb(0 0% 0%); + color: hwb(0 0% 0% / 1); + color: hwb(0 0% 0% / .5); + color: hwb(0 0% 0% / 100%); + color: hwb(0 0% 0% / 50%); +} From 3c97d97d5d173728ba242a4e1495fcf943553aca Mon Sep 17 00:00:00 2001 From: Jonathan Neal Date: Mon, 7 May 2018 23:58:17 -0400 Subject: [PATCH 617/795] 5.0.0 --- .appveyor.yml | 18 +++ .gitignore | 6 +- .rollup.js | 16 +++ .tape.js | 6 + .travis.yml | 6 + CHANGELOG.md | 8 +- CONTRIBUTING.md | 79 ++++++------- LICENSE.md | 138 ++++++++++++----------- README.md | 163 +++++++++++++++++---------- index.js | 114 ++++++++++--------- package.json | 38 ++++--- test/basic.expect.css | 13 +++ test/basic.preserve-false.expect.css | 13 +++ 13 files changed, 384 insertions(+), 234 deletions(-) create mode 100644 .appveyor.yml create mode 100644 .rollup.js create mode 100644 test/basic.preserve-false.expect.css diff --git a/.appveyor.yml b/.appveyor.yml new file mode 100644 index 0000000000..acbf8a5eeb --- /dev/null +++ b/.appveyor.yml @@ -0,0 +1,18 @@ +# https://www.appveyor.com/docs/appveyor-yml + +environment: + matrix: + - nodejs_version: 4 + +version: "{build}" +build: off +deploy: off + +install: + - ps: Install-Product node $env:nodejs_version + - npm install --ignore-scripts + +test_script: + - node --version + - npm --version + - cmd: "npm test" diff --git a/.gitignore b/.gitignore index 995098afd2..de73e5a338 100644 --- a/.gitignore +++ b/.gitignore @@ -1,10 +1,12 @@ node_modules +index.*.js package-lock.json +*.log* +*.result.css .* !.appveyor.yml !.editorconfig !.gitignore +!.rollup.js !.tape.js !.travis.yml -*.log* -*.result.css diff --git a/.rollup.js b/.rollup.js new file mode 100644 index 0000000000..0436758216 --- /dev/null +++ b/.rollup.js @@ -0,0 +1,16 @@ +import babel from 'rollup-plugin-babel'; + +export default { + input: 'index.js', + output: [ + { file: 'index.cjs.js', format: 'cjs' }, + { file: 'index.es.js', format: 'es' } + ], + plugins: [ + babel({ + presets: [ + ['env', { modules: false, targets: { node: 4 } }] + ] + }) + ] +}; diff --git a/.tape.js b/.tape.js index 15007b941a..6d365d8fd0 100644 --- a/.tape.js +++ b/.tape.js @@ -2,6 +2,12 @@ module.exports = { 'postcss-pseudo-class-any-link': { 'basic': { message: 'supports basic usage' + }, + 'basic:preserve-false': { + message: 'supports { preserve: false } usage', + options: { + preserve: false + } } } }; diff --git a/.travis.yml b/.travis.yml index 85242354aa..c56466446c 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,3 +1,9 @@ +# https://docs.travis-ci.com/user/travis-lint + language: node_js + node_js: - 4 + +install: + - npm install --ignore-scripts diff --git a/CHANGELOG.md b/CHANGELOG.md index 24f5a6d61a..2f24843fbd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,10 @@ -# Changes to :any-link +# Changes to PostCSS Pseudo Class Any Link + +### 5.0.0 (May 7, 2018) + +- Updated: `postcss-selector-parser` to v4.0.0 (major) +- Updated: `postcss` to v6.0.22 (patch) +- Changed: Preserves `:any-link` by default ### 4.0.0 (May 10, 2017) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index d245cc3d1b..fb2eebb998 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,4 +1,4 @@ -# Contributing to :any-link +# Contributing to PostCSS Pseudo Class Any Link You want to help? You rock! Now, take a moment to be sure your contributions make sense to everyone else. @@ -14,51 +14,52 @@ Remember, a bug is a _demonstrable problem_ caused by _our_ code. ## Submitting Pull Requests -Pull requests are the greatest contributions, so be sure they are focused in -scope, and do avoid unrelated commits. +Pull requests are the greatest contributions, so be sure they are focused in +scope and avoid unrelated commits. -1. To begin, [fork this project], clone your fork, and add our upstream. - ```bash - # Clone your fork of the repo into the current directory - git clone https://github.com//postcss-pseudo-class-any-link - # Navigate to the newly cloned directory - cd postcss-pseudo-class-any-link - # Assign the original repo to a remote called "upstream" - git remote add upstream https://github.com/jonathantneal/postcss-pseudo-class-any-link - # Install the tools necessary for development - npm install - ``` +1. To begin; [fork this project], clone your fork, and add our upstream. + ```bash + # Clone your fork of the repo into the current directory + git clone git@github.com:YOUR_USER/postcss-pseudo-class-any-link.git -2. Create a branch for your feature or fix: - ```bash - # Move into a new branch for a feature - git checkout -b feature/thing - ``` - ```bash - # Move into a new branch for a fix - git checkout -b fix/something - ``` + # Navigate to the newly cloned directory + cd postcss-pseudo-class-any-link + + # Assign the original repo to a remote called "upstream" + git remote add upstream git@github.com:jonathantneal/postcss-pseudo-class-any-link.git -3. Be sure your code follows our practices. - ```bash - # Test current code - npm run test - ``` + # Install the tools necessary for testing + npm install + ``` + +2. Create a branch for your feature or fix: + ```bash + # Move into a new branch for your feature + git checkout -b feature/thing + ``` + ```bash + # Move into a new branch for your fix + git checkout -b fix/something + ``` -4. Push your branch up to your fork: - ```bash - # Push a feature branch - git push origin feature/thing - ``` - ```bash - # Push a fix branch - git push origin fix/something - ``` +3. If your code follows our practices, then push your feature branch: + ```bash + # Test current code + npm test + ``` + ```bash + # Push the branch for your new feature + git push origin feature/thing + ``` + ```bash + # Or, push the branch for your update + git push origin update/something + ``` -5. Now [open a pull request] with a clear title and description. +That’s it! Now [open a pull request] with a clear title and description. [already been reported]: issues [fork this project]: fork -[live example]: http://codepen.io/pen +[live example]: https://codepen.io/pen [open a pull request]: https://help.github.com/articles/using-pull-requests/ [reduced test case]: https://css-tricks.com/reduced-test-cases/ diff --git a/LICENSE.md b/LICENSE.md index 34f902f6c4..0bc1fa7060 100644 --- a/LICENSE.md +++ b/LICENSE.md @@ -27,80 +27,82 @@ Copyright and Related Rights in the Work and the meaning and intended legal effect of CC0 on those rights. 1. Copyright and Related Rights. A Work made available under CC0 may be - protected by copyright and related or neighboring rights (“Copyright and - Related Rights”). Copyright and Related Rights include, but are not limited - to, the following: - 1. the right to reproduce, adapt, distribute, perform, display, - communicate, and translate a Work; - 2. moral rights retained by the original author(s) and/or performer(s); - 3. publicity and privacy rights pertaining to a person’s image or likeness - depicted in a Work; - 4. rights protecting against unfair competition in regards to a Work, - subject to the limitations in paragraph 4(i), below; - 5. rights protecting the extraction, dissemination, use and reuse of data - in a Work; - 6. database rights (such as those arising under Directive 96/9/EC of the - European Parliament and of the Council of 11 March 1996 on the legal - protection of databases, and under any national implementation thereof, - including any amended or successor version of such directive); and - 7. other similar, equivalent or corresponding rights throughout the world - based on applicable law or treaty, and any national implementations - thereof. + protected by copyright and related or neighboring rights (“Copyright and + Related Rights”). Copyright and Related Rights include, but are not limited + to, the following: + 1. the right to reproduce, adapt, distribute, perform, display, communicate, + and translate a Work; + 2. moral rights retained by the original author(s) and/or performer(s); + 3. publicity and privacy rights pertaining to a person’s image or likeness + depicted in a Work; + 4. rights protecting against unfair competition in regards to a Work, + subject to the limitations in paragraph 4(i), below; + 5. rights protecting the extraction, dissemination, use and reuse of data in + a Work; + 6. database rights (such as those arising under Directive 96/9/EC of the + European Parliament and of the Council of 11 March 1996 on the legal + protection of databases, and under any national implementation thereof, + including any amended or successor version of such directive); and + 7. other similar, equivalent or corresponding rights throughout the world + based on applicable law or treaty, and any national implementations + thereof. 2. Waiver. To the greatest extent permitted by, but not in contravention of, -applicable law, Affirmer hereby overtly, fully, permanently, irrevocably and -unconditionally waives, abandons, and surrenders all of Affirmer’s Copyright -and Related Rights and associated claims and causes of action, whether now -known or unknown (including existing as well as future claims and causes of -action), in the Work (i) in all territories worldwide, (ii) for the maximum -duration provided by applicable law or treaty (including future time -extensions), (iii) in any current or future medium and for any number of -copies, and (iv) for any purpose whatsoever, including without limitation -commercial, advertising or promotional purposes (the “Waiver”). Affirmer makes -the Waiver for the benefit of each member of the public at large and to the -detriment of Affirmer’s heirs and successors, fully intending that such Waiver -shall not be subject to revocation, rescission, cancellation, termination, or -any other legal or equitable action to disrupt the quiet enjoyment of the Work -by the public as contemplated by Affirmer’s express Statement of Purpose. + applicable law, Affirmer hereby overtly, fully, permanently, irrevocably and + unconditionally waives, abandons, and surrenders all of Affirmer’s Copyright + and Related Rights and associated claims and causes of action, whether now + known or unknown (including existing as well as future claims and causes of + action), in the Work (i) in all territories worldwide, (ii) for the maximum + duration provided by applicable law or treaty (including future time + extensions), (iii) in any current or future medium and for any number of + copies, and (iv) for any purpose whatsoever, including without limitation + commercial, advertising or promotional purposes (the “Waiver”). Affirmer + makes the Waiver for the benefit of each member of the public at large and + to the detriment of Affirmer’s heirs and successors, fully intending that + such Waiver shall not be subject to revocation, rescission, cancellation, + termination, or any other legal or equitable action to disrupt the quiet + enjoyment of the Work by the public as contemplated by Affirmer’s express + Statement of Purpose. 3. Public License Fallback. Should any part of the Waiver for any reason be -judged legally invalid or ineffective under applicable law, then the Waiver -shall be preserved to the maximum extent permitted taking into account -Affirmer’s express Statement of Purpose. In addition, to the extent the Waiver -is so judged Affirmer hereby grants to each affected person a royalty-free, non -transferable, non sublicensable, non exclusive, irrevocable and unconditional -license to exercise Affirmer’s Copyright and Related Rights in the Work (i) in -all territories worldwide, (ii) for the maximum duration provided by applicable -law or treaty (including future time extensions), (iii) in any current or -future medium and for any number of copies, and (iv) for any purpose -whatsoever, including without limitation commercial, advertising or promotional -purposes (the “License”). The License shall be deemed effective as of the date -CC0 was applied by Affirmer to the Work. Should any part of the License for any -reason be judged legally invalid or ineffective under applicable law, such -partial invalidity or ineffectiveness shall not invalidate the remainder of the -License, and in such case Affirmer hereby affirms that he or she will not (i) -exercise any of his or her remaining Copyright and Related Rights in the Work -or (ii) assert any associated claims and causes of action with respect to the -Work, in either case contrary to Affirmer’s express Statement of Purpose. + judged legally invalid or ineffective under applicable law, then the Waiver + shall be preserved to the maximum extent permitted taking into account + Affirmer’s express Statement of Purpose. In addition, to the extent the + Waiver is so judged Affirmer hereby grants to each affected person a + royalty-free, non transferable, non sublicensable, non exclusive, + irrevocable and unconditional license to exercise Affirmer’s Copyright and + Related Rights in the Work (i) in all territories worldwide, (ii) for the + maximum duration provided by applicable law or treaty (including future time + extensions), (iii) in any current or future medium and for any number of + copies, and (iv) for any purpose whatsoever, including without limitation + commercial, advertising or promotional purposes (the “License”). The License + shall be deemed effective as of the date CC0 was applied by Affirmer to the + Work. Should any part of the License for any reason be judged legally + invalid or ineffective under applicable law, such partial invalidity or + ineffectiveness shall not invalidate the remainder of the License, and in + such case Affirmer hereby affirms that he or she will not (i) exercise any + of his or her remaining Copyright and Related Rights in the Work or (ii) + assert any associated claims and causes of action with respect to the Work, + in either case contrary to Affirmer’s express Statement of Purpose. 4. Limitations and Disclaimers. - 1. No trademark or patent rights held by Affirmer are waived, abandoned, - surrendered, licensed or otherwise affected by this document. - 2. Affirmer offers the Work as-is and makes no representations or - warranties of any kind concerning the Work, express, implied, statutory - or otherwise, including without limitation warranties of title, - merchantability, fitness for a particular purpose, non infringement, or - the absence of latent or other defects, accuracy, or the present or - absence of errors, whether or not discoverable, all to the greatest - extent permissible under applicable law. - 3. Affirmer disclaims responsibility for clearing rights of other persons - that may apply to the Work or any use thereof, including without - limitation any person’s Copyright and Related Rights in the Work. - Further, Affirmer disclaims responsibility for obtaining any necessary - consents, permissions or other rights required for any use of the Work. - 4. Affirmer understands and acknowledges that Creative Commons is not a - party to this document and has no duty or obligation with respect to - this CC0 or use of the Work. + 1. No trademark or patent rights held by Affirmer are waived, abandoned, + surrendered, licensed or otherwise affected by this document. + 2. Affirmer offers the Work as-is and makes no representations or warranties + of any kind concerning the Work, express, implied, statutory or + otherwise, including without limitation warranties of title, + merchantability, fitness for a particular purpose, non infringement, or + the absence of latent or other defects, accuracy, or the present or + absence of errors, whether or not discoverable, all to the greatest + extent permissible under applicable law. + 3. Affirmer disclaims responsibility for clearing rights of other persons + that may apply to the Work or any use thereof, including without + limitation any person’s Copyright and Related Rights in the Work. + Further, Affirmer disclaims responsibility for obtaining any necessary + consents, permissions or other rights required for any use of the Work. + 4. Affirmer understands and acknowledges that Creative Commons is not a + party to this document and has no duty or obligation with respect to this + CC0 or use of the Work. For more information, please see http://creativecommons.org/publicdomain/zero/1.0/. diff --git a/README.md b/README.md index 091b46a3cc..96b8a5cf7e 100644 --- a/README.md +++ b/README.md @@ -1,33 +1,39 @@ -# :any-link [PostCSS Logo][postcss] +# PostCSS Pseudo Class Any Link [PostCSS Logo][postcss] [![NPM Version][npm-img]][npm-url] [![CSS Standard Status][css-img]][css-url] [![Build Status][cli-img]][cli-url] +[![Windows Build Status][win-img]][win-url] [![Support Chat][git-img]][git-url] -[:any-link] lets you to use the proposed [`:any-link`] pseudo-class in CSS. +[PostCSS Pseudo Class Any Link] lets you `:any-link` pseudo-class in CSS, +following the [Selectors] specification. -`:any-link` simplifies selectors targeting links, as the naming of `:link` is misleading; it specifically means unvisited links only, rather than all links. - -```css +```pcss nav :any-link > span { - background-color: yellow; + background-color: yellow; } /* becomes */ nav :link > span, nav :visited > span { - background-color: yellow; + background-color: yellow; +} + +nav :any-link > span { + background-color: yellow; } ``` -From the [proposal]: +From the [proposal][Selectors]: -> The [`:any-link`] pseudo-class represents an element that acts as the source anchor of a hyperlink. It matches an element if the element would match [`:link`] or [`:visited`]. +> The `:any-link` pseudo-class represents an element that acts as the source + anchor of a hyperlink. It matches an element if the element would match + `:link` or `:visited`. ## Usage -Add [:any-link] to your build tool: +Add [PostCSS Pseudo Class Any Link] to your build tool: ```bash npm install postcss-pseudo-class-any-link --save-dev @@ -35,10 +41,12 @@ npm install postcss-pseudo-class-any-link --save-dev #### Node -Use [:any-link] to process your CSS: +Use [PostCSS Pseudo Class Any Link] to process your CSS: ```js -require('postcss-pseudo-class-any-link').process(YOUR_CSS); +import postcssPseudoClassAnyLink from 'postcss-pseudo-class-any-link'; + +postcssPseudoClassAnyLink.process(YOUR_CSS, /* processOptions */, /* pluginOptions */); ``` #### PostCSS @@ -49,14 +57,51 @@ Add [PostCSS] to your build tool: npm install postcss --save-dev ``` -Use [:any-link] as a plugin: +Use [PostCSS Pseudo Class Any Link] as a plugin: ```js +import postcss from 'gulp-postcss'; +import postcssPseudoClassAnyLink from 'postcss-pseudo-class-any-link'; + postcss([ - require('postcss-pseudo-class-any-link')() + postcssPseudoClassAnyLink(/* pluginOptions */) ]).process(YOUR_CSS); ``` +#### Webpack + +Add [PostCSS Loader] to your build tool: + +```bash +npm install postcss-loader --save-dev +``` + +Use [PostCSS Pseudo Class Any Link] in your Webpack configuration: + +```js +import postcssPseudoClassAnyLink from 'postcss-pseudo-class-any-link'; + +module.exports = { + module: { + rules: [ + { + test: /\.css$/, + use: [ + 'style-loader', + { loader: 'css-loader', options: { importLoaders: 1 } }, + { loader: 'postcss-loader', options: { + ident: 'postcss', + plugins: () => [ + postcssPseudoClassAnyLink(/* pluginOptions */) + ] + } } + ] + } + ] + } +} +``` + #### Gulp Add [Gulp PostCSS] to your build tool: @@ -65,20 +110,19 @@ Add [Gulp PostCSS] to your build tool: npm install gulp-postcss --save-dev ``` -Use [:any-link] in your Gulpfile: +Use [PostCSS Pseudo Class Any Link] in your Gulpfile: ```js -var postcss = require('gulp-postcss'); - -gulp.task('css', function () { - return gulp.src('./src/*.css').pipe( - postcss([ - require('postcss-pseudo-class-any-link')() - ]) - ).pipe( - gulp.dest('.') - ); -}); +import postcss from 'gulp-postcss'; +import postcssPseudoClassAnyLink from 'postcss-pseudo-class-any-link'; + +gulp.task('css', () => gulp.src('./src/*.css').pipe( + postcss([ + postcssPseudoClassAnyLink(/* pluginOptions */) + ]) +).pipe( + gulp.dest('.') +)); ``` #### Grunt @@ -89,59 +133,64 @@ Add [Grunt PostCSS] to your build tool: npm install grunt-postcss --save-dev ``` -Use [:any-link] in your Gruntfile: +Use [PostCSS Pseudo Class Any Link] in your Gruntfile: ```js +import postcssPseudoClassAnyLink from 'postcss-pseudo-class-any-link'; + grunt.loadNpmTasks('grunt-postcss'); grunt.initConfig({ - postcss: { - options: { - use: [ - require('postcss-pseudo-class-any-link')() - ] - }, - dist: { - src: '*.css' - } - } + postcss: { + options: { + use: [ + postcssPseudoClassAnyLink(/* pluginOptions */) + ] + }, + dist: { + src: '*.css' + } + } }); ``` -### Alternatives +## Options -Here are a few other ways to simulate the effect of [PostCSS Pseudo-Class Any-Link]. +### preserve -```css -/* Use @custom-selector; supported nowhere yet */ +The `preserve` option determines whether the original `:any-link` rule is +preserved. By default, it is preserved. -@custom-selector :--any-link :link, :visited; - -:--any-link { /* ... */ } - -/* Use :matches; supported in Firefox 4+, Chrome 12+, Opera 15+, Safari 5.1+ */ +```js +postcssPseudoClassAnyLink({ preserve: false }) +``` -:matches(:link, :visited) { /* ... */ } +```pcss +nav :any-link > span { + background-color: yellow; +} -/* Use :link and :visited; supported everywhere */ +/* becomes */ -:link, :visited { /* ... */ } +nav :link > span, nav :visited > span { + background-color: yellow; +} ``` [cli-img]: https://img.shields.io/travis/jonathantneal/postcss-pseudo-class-any-link.svg [cli-url]: https://travis-ci.org/jonathantneal/postcss-pseudo-class-any-link -[css-img]: https://jonathantneal.github.io/cssdb/badge/any-link-pseudo-class.svg -[css-url]: https://jonathantneal.github.io/cssdb/#any-link-pseudo-class -[git-img]: https://img.shields.io/badge/chat-gitter-blue.svg +[css-img]: https://cssdb.org/badge/any-link-pseudo-class.svg +[css-url]: https://cssdb.org/#any-link-pseudo-class +[git-img]: https://img.shields.io/badge/support-chat-blue.svg [git-url]: https://gitter.im/postcss/postcss [npm-img]: https://img.shields.io/npm/v/postcss-pseudo-class-any-link.svg [npm-url]: https://www.npmjs.com/package/postcss-pseudo-class-any-link +[win-img]: https://img.shields.io/appveyor/ci/jonathantneal/postcss-pseudo-class-any-link.svg +[win-url]: https://ci.appveyor.com/project/jonathantneal/postcss-pseudo-class-any-link -[`:any-link`]: http://dev.w3.org/csswg/selectors/#any-link-pseudo -[`:link`]: http://dev.w3.org/csswg/selectors/#link-pseudo -[`:visited`]: http://dev.w3.org/csswg/selectors/#visited-pseudo -[:any-link]: https://github.com/jonathantneal/postcss-pseudo-class-any-link [Gulp PostCSS]: https://github.com/postcss/gulp-postcss [Grunt PostCSS]: https://github.com/nDmitry/grunt-postcss [PostCSS]: https://github.com/postcss/postcss -[proposal]: http://dev.w3.org/csswg/selectors/ +[PostCSS Loader]: https://github.com/postcss/postcss-loader +[PostCSS Pseudo Class Any Link]: https://github.com/jonathantneal/postcss-pseudo-class-any-link +[Selectors]: https://www.w3.org/TR/selectors-4/#the-any-link-pseudo diff --git a/index.js b/index.js index 94d3f59d5b..374beaffd1 100644 --- a/index.js +++ b/index.js @@ -1,55 +1,67 @@ -'use strict'; - -// tooling -const postcss = require('postcss'); -const parser = require('postcss-selector-parser'); - -// plugin -module.exports = postcss.plugin('postcss-pseudo-class-any-link', () => (css) => { - // walk each matching rule - css.walkRules(/:any-link/, (rule) => { - const rawSelector = rule.raws.selector && rule.raws.selector.raw || rule.selector; - - // workaround for https://github.com/postcss/postcss-selector-parser/issues/28#issuecomment-171910556 - if (rawSelector[rawSelector.length - 1] !== ':') { - // update the selector - rule.selector = parser((selectors) => { - // cache variables - let node; - let nodeIndex; - let selector; - let selectorLink; - let selectorVisited; - - // cache the selector index - let selectorIndex = -1; - - // for each selector - while (selector = selectors.nodes[++selectorIndex]) { - // reset the node index - nodeIndex = -1; - - // for each node - while (node = selector.nodes[++nodeIndex]) { - // if the node value matches the any-link value - if (node.value === ':any-link') { - // clone the selector - selectorLink = selector.clone(); - selectorVisited = selector.clone(); - - // update the matching clone values - selectorLink.nodes[nodeIndex].value = ':link'; - selectorVisited.nodes[nodeIndex].value = ':visited'; - - // replace the selector with the clones and roll back the selector index - selectors.nodes.splice(selectorIndex--, 1, selectorLink, selectorVisited); - - // stop updating the selector - break; +import postcss from 'postcss'; +import parser from 'postcss-selector-parser'; + +const anyAnyLinkMatch = /:any-link/; + +export default postcss.plugin('postcss-pseudo-class-any-link', opts => { + const preserve = 'preserve' in Object(opts) ? Boolean(opts.preserve) : true; + + return root => { + // walk each matching rule + root.walkRules(anyAnyLinkMatch, rule => { + const rawSelector = rule.raws.selector && rule.raws.selector.raw || rule.selector; + + // workaround for https://github.com/postcss/postcss-selector-parser/issues/28#issuecomment-171910556 + if (rawSelector[rawSelector.length - 1] !== ':') { + // update the selector + const updatedSelector = parser(selectors => { + // cache variables + let node; + let nodeIndex; + let selector; + let selectorLink; + let selectorVisited; + + // cache the selector index + let selectorIndex = -1; + + // for each selector + while (selector = selectors.nodes[++selectorIndex]) { + // reset the node index + nodeIndex = -1; + + // for each node + while (node = selector.nodes[++nodeIndex]) { + // if the node value matches the any-link value + if (node.value === ':any-link') { + // clone the selector + selectorLink = selector.clone(); + selectorVisited = selector.clone(); + + // update the matching clone values + selectorLink.nodes[nodeIndex].value = ':link'; + selectorVisited.nodes[nodeIndex].value = ':visited'; + + // replace the selector with the clones and roll back the selector index + selectors.nodes.splice(selectorIndex--, 1, selectorLink, selectorVisited); + + // stop updating the selector + break; + } } } + }).processSync(rawSelector); + + if (updatedSelector !== rawSelector) { + if (preserve) { + rule.cloneBefore({ + selector: updatedSelector + }); + } else { + rule.selector = updatedSelector; + } } - }).process(rawSelector).result; - } - }); + } + }) + }; }); diff --git a/package.json b/package.json index c1fdcc287b..bac67503fd 100644 --- a/package.json +++ b/package.json @@ -1,41 +1,47 @@ { "name": "postcss-pseudo-class-any-link", - "version": "4.0.0", - "description": "Use the proposed :any-link pseudo-class in CSS", + "version": "5.0.0", + "description": "Use the :any-link pseudo-class in CSS", "author": "Jonathan Neal ", "license": "CC0-1.0", "repository": "jonathantneal/postcss-pseudo-class-any-link", "homepage": "https://github.com/jonathantneal/postcss-pseudo-class-any-link#readme", "bugs": "https://github.com/jonathantneal/postcss-pseudo-class-any-link/issues", - "main": "index.js", + "main": "index.cjs.js", + "module": "index.es.js", "files": [ - "index.js" + "index.cjs.js", + "index.es.js" ], "scripts": { - "clean": "git clean -X -d -f", - "prepublish": "npm test", + "prepublishOnly": "npm test", + "pretest": "rollup -c .rollup.js --silent", "test": "echo 'Running tests...'; npm run test:js && npm run test:tape", - "test:js": "eslint *.js --cache --ignore-pattern .gitignore", + "test:ec": "echint --ignore index.*.js test", + "test:js": "eslint *.js --cache --ignore-path .gitignore --quiet", "test:tape": "postcss-tape" }, "engines": { "node": ">=4.0.0" }, "dependencies": { - "postcss": "^6.0.11", - "postcss-selector-parser": "^2.2.3" + "postcss": "^6.0.22", + "postcss-selector-parser": "^4.0.0" }, "devDependencies": { - "eslint": "^4.6.1", - "eslint-config-dev": "2.0.0", - "postcss-tape": "2.0.1", - "pre-commit": "^1.2.2" + "babel-core": "^6.26.3", + "babel-eslint": "^8.2.3", + "babel-preset-env": "^1.6.1", + "eslint": "^4.19.1", + "eslint-config-dev": "^2.0.0", + "postcss-tape": "^2.2.0", + "pre-commit": "^1.2.2", + "rollup": "^0.58.2", + "rollup-plugin-babel": "^3.0.4" }, "eslintConfig": { "extends": "dev", - "parserOptions": { - "sourceType": "module" - } + "parser": "babel-eslint" }, "keywords": [ "postcss", diff --git a/test/basic.expect.css b/test/basic.expect.css index 806a50e056..904d425139 100644 --- a/test/basic.expect.css +++ b/test/basic.expect.css @@ -2,12 +2,25 @@ background: blue; } +:any-link { + background: blue; +} + :link,:visited, ul a:link > span, ul a:visited > span { background: blue; } +:any-link, +ul a:any-link > span { + background: blue; +} + :link :link,:link :visited,:visited :link,:visited :visited { background: blue; } + +:any-link :any-link { + background: blue; +} diff --git a/test/basic.preserve-false.expect.css b/test/basic.preserve-false.expect.css new file mode 100644 index 0000000000..806a50e056 --- /dev/null +++ b/test/basic.preserve-false.expect.css @@ -0,0 +1,13 @@ +:link,:visited { + background: blue; +} + +:link,:visited, +ul a:link > span, +ul a:visited > span { + background: blue; +} + +:link :link,:link :visited,:visited :link,:visited :visited { + background: blue; +} From 62c1907d173b78bf521e3887b53f994eb1801b8e Mon Sep 17 00:00:00 2001 From: Jonathan Neal Date: Tue, 8 May 2018 00:24:42 -0400 Subject: [PATCH 618/795] 4.0.0 --- CHANGELOG.md | 5 ++++ README.md | 70 +++++++++++++++++++++++++++++++++++++--------------- index.js | 2 ++ package.json | 19 +++++++------- 4 files changed, 66 insertions(+), 30 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3190505b73..deaa14c1ff 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,10 @@ # Changes to PostCSS Dir Pseudo Class +### 4.0.0 (May 8, 2018) + +- Updated: `postcss-selector-parser` to v4.0.0 (major) +- Updated: `postcss` to v6.0.22 (patch) + ### 3.0.0 (March 21, 2018) - Added: `preserve` option to preserve the original `:dir()` rule diff --git a/README.md b/README.md index 2bf8aedfe7..4109695ceb 100644 --- a/README.md +++ b/README.md @@ -6,10 +6,10 @@ [![Windows Build Status][win-img]][win-url] [![Support Chat][git-img]][git-url] -[PostCSS Dir Pseudo Class] lets you use the `:dir()` pseudo-class to style by -directionality in CSS, following the [Selectors Level 4] specification. +[PostCSS Dir Pseudo Class] lets you style by directionality using the `:dir()` +pseudo-class in CSS, following the [Selectors] specification. -```css +```pcss article h3:dir(rtl) { margin-right: 10px; } @@ -29,7 +29,7 @@ article h3:dir(ltr) { } ``` -### Maintain Specificity +### Maintaining Specificity Using [PostCSS Dir Pseudo Class] will not impact selector weight, but it will require having at least one `[dir]` attribute in your HTML. If you don’t have @@ -60,7 +60,7 @@ Use [PostCSS Dir Pseudo Class] to process your CSS: ```js import postcssDirPseudoClass from 'postcss-dir-pseudo-class'; -postcssDirPseudoClass.process(YOUR_CSS); +postcssDirPseudoClass.process(YOUR_CSS, /* processOptions */, /* pluginOptions */); ``` #### PostCSS @@ -78,7 +78,7 @@ import postcss from 'gulp-postcss'; import postcssDirPseudoClass from 'postcss-dir-pseudo-class'; postcss([ - postcssDirPseudoClass() + postcssDirPseudoClass(/* pluginOptions */) ]).process(YOUR_CSS); ``` @@ -106,7 +106,7 @@ module.exports = { { loader: 'postcss-loader', options: { ident: 'postcss', plugins: () => [ - postcssDirPseudoClass(/* options */) + postcssDirPseudoClass(/* pluginOptions */) ] } } ] @@ -132,7 +132,7 @@ import postcssDirPseudoClass from 'postcss-dir-pseudo-class'; gulp.task('css', () => gulp.src('./src/*.css').pipe( postcss([ - postcssDirPseudoClass(/* options */) + postcssDirPseudoClass(/* pluginOptions */) ]) ).pipe( gulp.dest('.') @@ -158,7 +158,7 @@ grunt.initConfig({ postcss: { options: { use: [ - postcssDirPseudoClass(/* options */) + postcssDirPseudoClass(/* pluginOptions */) ] }, dist: { @@ -180,12 +180,10 @@ Here’s an example of using the `dir` option to presume a left-to-right direction: ```js -require('postcss-dir-pseudo-class')({ - dir: 'ltr' -}); +postcssDirPseudoClass({ dir: 'ltr' }); ``` -```css +```pcss .example:dir(ltr) { margin-left: 10px; } @@ -208,22 +206,54 @@ html:not([dir="rtl"]) .example { ### preserve The `preserve` option determines whether the original `:dir()` rule should -remain in the CSS. By default, the rule is replaced by the fallback. +remain in the CSS. By default, the original rule is not preserved. + +```js +postcssDirPseudoClass({ preserve: true }); +``` + +```pcss +article h3:dir(rtl) { + margin-right: 10px; +} + +article h3:dir(ltr) { + margin-left: 10px; +} + +/* becomes */ + +[dir="rtl"] article h3 { + margin-right: 10px; +} + +article h3:dir(rtl) { + margin-right: 10px; +} + +[dir="ltr"] article h3 { + margin-left: 10px; +} + +article h3:dir(ltr) { + margin-left: 10px; +} +``` -[cli-url]: https://travis-ci.org/jonathantneal/postcss-dir-pseudo-class [cli-img]: https://img.shields.io/travis/jonathantneal/postcss-dir-pseudo-class.svg +[cli-url]: https://travis-ci.org/jonathantneal/postcss-dir-pseudo-class [css-img]: https://jonathantneal.github.io/cssdb/badge/dir-pseudo-class.svg [css-url]: https://jonathantneal.github.io/cssdb/#dir-pseudo-class -[git-url]: https://gitter.im/postcss/postcss [git-img]: https://img.shields.io/badge/support-chat-blue.svg -[npm-url]: https://www.npmjs.com/package/postcss-dir-pseudo-class +[git-url]: https://gitter.im/postcss/postcss [npm-img]: https://img.shields.io/npm/v/postcss-dir-pseudo-class.svg -[win-url]: https://ci.appveyor.com/project/jonathantneal/postcss-dir-pseudo-class +[npm-url]: https://www.npmjs.com/package/postcss-dir-pseudo-class [win-img]: https://img.shields.io/appveyor/ci/jonathantneal/postcss-dir-pseudo-class.svg +[win-url]: https://ci.appveyor.com/project/jonathantneal/postcss-dir-pseudo-class [Gulp PostCSS]: https://github.com/postcss/gulp-postcss [Grunt PostCSS]: https://github.com/nDmitry/grunt-postcss [PostCSS]: https://github.com/postcss/postcss -[PostCSS Dir Pseudo Class]: https://github.com/jonathantneal/postcss-dir-pseudo-class [PostCSS Loader]: https://github.com/postcss/postcss-loader -[Selectors Level 4]: https://www.w3.org/TR/selectors-4/ +[PostCSS Dir Pseudo Class]: https://github.com/jonathantneal/postcss-dir-pseudo-class +[Selectors]: https://www.w3.org/TR/selectors-4/#the-dir-pseudo diff --git a/index.js b/index.js index 347992f5cc..8e1e132cb2 100644 --- a/index.js +++ b/index.js @@ -62,6 +62,7 @@ export default postcss.plugin('postcss-dir-pseudo-class', opts => { const dirAttr = selectorParser.attribute({ attribute: 'dir', operator: '=', + quoteMark: '"', value: `"${ value }"` }); @@ -74,6 +75,7 @@ export default postcss.plugin('postcss-dir-pseudo-class', opts => { selectorParser.attribute({ attribute: 'dir', operator: '=', + quoteMark: '"', value: `"${ 'ltr' === value ? 'rtl' : 'ltr' }"` }) ); diff --git a/package.json b/package.json index 13b26a34ba..bf0a6cf754 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "postcss-dir-pseudo-class", - "version": "3.0.0", + "version": "4.0.0", "description": "Use the :dir pseudo-class in CSS", "author": "Jonathan Neal ", "license": "CC0-1.0", @@ -16,7 +16,7 @@ "scripts": { "prepublishOnly": "npm test", "pretest": "rollup -c .rollup.js --silent", - "test": "echo 'Running tests...'; npm run test:ec && npm run test:js && npm run test:tape", + "test": "echo 'Running tests...'; npm run test:js && npm run test:tape", "test:ec": "echint --ignore index.*.js test", "test:js": "eslint *.js --cache --ignore-path .gitignore --quiet", "test:tape": "postcss-tape" @@ -25,20 +25,19 @@ "node": ">=4.0.0" }, "dependencies": { - "postcss": "^6.0.20", - "postcss-selector-parser": "^3.1.1" + "postcss": "^6.0.22", + "postcss-selector-parser": "^4.0.0" }, "devDependencies": { - "babel-core": "^6.26.0", - "babel-eslint": "^8.2.2", + "babel-core": "^6.26.3", + "babel-eslint": "^8.2.3", "babel-preset-env": "^1.6.1", - "echint": "^4.0.1", - "eslint": "^4.19.0", + "eslint": "^4.19.1", "eslint-config-dev": "^2.0.0", "postcss-tape": "^2.2.0", "pre-commit": "^1.2.2", - "rollup": "^0.57.1", - "rollup-plugin-babel": "^3.0.3" + "rollup": "^0.58.2", + "rollup-plugin-babel": "^3.0.4" }, "eslintConfig": { "extends": "dev", From 5815b683017fbaa0b60502274a2089a79cd1d07b Mon Sep 17 00:00:00 2001 From: Jonathan Neal Date: Tue, 8 May 2018 01:17:37 -0400 Subject: [PATCH 619/795] 1.0.1 --- CHANGELOG.md | 4 ++++ README.md | 27 +++++++++++++++++++++++++++ index.js | 4 ++-- package.json | 2 +- test/basic.css | 6 +++++- test/basic.expect.css | 6 +++++- test/basic.preserve-false.expect.css | 6 +++++- 7 files changed, 49 insertions(+), 6 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f04b927af1..dc2cc1ab08 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # Changes to PostCSS Overflow Shorthand +### 1.0.1 (May 8, 2018) + +- Fixed: Single `overflow` values previously being parsed + ### 1.0.0 (April 30, 2018) - Initial version diff --git a/README.md b/README.md index 4f9f766a37..e9e9ce2ef5 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,7 @@ # PostCSS Overflow Shorthand [PostCSS Logo][postcss] [![NPM Version][npm-img]][npm-url] +[![CSS Standard Status][css-img]][css-url] [![Build Status][cli-img]][cli-url] [![Windows Build Status][win-img]][win-url] [![Support Chat][git-img]][git-url] @@ -145,8 +146,34 @@ grunt.initConfig({ }); ``` +## Options + +### preserve + +The `preserve` option determines whether the original `overflow` declaration is +preserved. By default, it is preserved. + +```js +postcssOverflowShorthand({ preserve: false }) +``` + +```pcss +html { + overflow: hidden auto; +} + +/* becomes */ + +html { + overflow-x: hidden; + overflow-y: auto; +} +``` + [cli-img]: https://img.shields.io/travis/jonathantneal/postcss-overflow-shorthand.svg [cli-url]: https://travis-ci.org/jonathantneal/postcss-overflow-shorthand +[css-img]: https://cssdb.org/badge/overflow-property.svg +[css-url]: https://cssdb.org/#overflow-property [git-img]: https://img.shields.io/badge/support-chat-blue.svg [git-url]: https://gitter.im/postcss/postcss [npm-img]: https://img.shields.io/npm/v/postcss-overflow-shorthand.svg diff --git a/index.js b/index.js index c8ea698ea6..de384ac629 100644 --- a/index.js +++ b/index.js @@ -15,8 +15,8 @@ export default postcss.plugin('postcss-overflow-shorthand', opts => { // split the declaration values const [overflowX, overflowY, ...invalidatingValues] = space(decl.value); - // if there are no invalidating values - if (!invalidatingValues.length) { + // if there are two values, but no invalidating values + if (overflowY && !invalidatingValues.length) { // insert the overflow-* longhand declarations decl.cloneBefore({ prop: `${decl.prop}-x`, diff --git a/package.json b/package.json index ab1cf7ec91..eca2476197 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "postcss-overflow-shorthand", - "version": "1.0.0", + "version": "1.0.1", "description": "Use the overflow shorthand in CSS", "author": "Jonathan Neal ", "license": "CC0-1.0", diff --git a/test/basic.css b/test/basic.css index 4e1e544baf..63f9b0f1a3 100644 --- a/test/basic.css +++ b/test/basic.css @@ -1,3 +1,7 @@ -test { +html.single-overflow { + overflow: hidden; +} + +html.double-overflow { overflow: hidden auto; } diff --git a/test/basic.expect.css b/test/basic.expect.css index 8a6e0a27e9..6f1325db5f 100644 --- a/test/basic.expect.css +++ b/test/basic.expect.css @@ -1,4 +1,8 @@ -test { +html.single-overflow { + overflow: hidden; +} + +html.double-overflow { overflow-x: hidden; overflow-y: auto; overflow: hidden auto; diff --git a/test/basic.preserve-false.expect.css b/test/basic.preserve-false.expect.css index b23480b3eb..7455817112 100644 --- a/test/basic.preserve-false.expect.css +++ b/test/basic.preserve-false.expect.css @@ -1,4 +1,8 @@ -test { +html.single-overflow { + overflow: hidden; +} + +html.double-overflow { overflow-x: hidden; overflow-y: auto; } From 55bcbd92fef8dd19bfb9ed129d10e0e70101f54f Mon Sep 17 00:00:00 2001 From: Jonathan Neal Date: Tue, 8 May 2018 01:36:11 -0400 Subject: [PATCH 620/795] 3.0.0 --- .appveyor.yml | 18 +++ .editorconfig | 15 +++ .gitignore | 13 +- .rollup.js | 16 +++ .tape.js | 6 + CHANGELOG.md | 7 +- CONTRIBUTING.md | 79 +++++------ LICENSE.md | 138 +++++++++---------- README.md | 190 ++++++++++++++++++--------- index.js | 40 +++--- package.json | 52 ++++---- test/basic.expect.css | 12 ++ test/basic.preserve-false.expect.css | 35 +++++ 13 files changed, 396 insertions(+), 225 deletions(-) create mode 100644 .appveyor.yml create mode 100644 .editorconfig create mode 100644 .rollup.js create mode 100644 test/basic.preserve-false.expect.css diff --git a/.appveyor.yml b/.appveyor.yml new file mode 100644 index 0000000000..acbf8a5eeb --- /dev/null +++ b/.appveyor.yml @@ -0,0 +1,18 @@ +# https://www.appveyor.com/docs/appveyor-yml + +environment: + matrix: + - nodejs_version: 4 + +version: "{build}" +build: off +deploy: off + +install: + - ps: Install-Product node $env:nodejs_version + - npm install --ignore-scripts + +test_script: + - node --version + - npm --version + - cmd: "npm test" diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000000..e06d7982bc --- /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/.gitignore b/.gitignore index 091413ef02..de73e5a338 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,12 @@ node_modules -npm-debug.log -test/*.result.css +index.*.js +package-lock.json +*.log* +*.result.css +.* +!.appveyor.yml +!.editorconfig +!.gitignore +!.rollup.js +!.tape.js +!.travis.yml diff --git a/.rollup.js b/.rollup.js new file mode 100644 index 0000000000..0436758216 --- /dev/null +++ b/.rollup.js @@ -0,0 +1,16 @@ +import babel from 'rollup-plugin-babel'; + +export default { + input: 'index.js', + output: [ + { file: 'index.cjs.js', format: 'cjs' }, + { file: 'index.es.js', format: 'es' } + ], + plugins: [ + babel({ + presets: [ + ['env', { modules: false, targets: { node: 4 } }] + ] + }) + ] +}; diff --git a/.tape.js b/.tape.js index 44e3eb54e0..a8cc739bf0 100644 --- a/.tape.js +++ b/.tape.js @@ -2,6 +2,12 @@ module.exports = { 'postcss-place': { 'basic': { message: 'supports basic usage' + }, + 'basic:preserve-false': { + message: 'supports { preserve: false } usage', + options: { + preserve: false + } } } }; diff --git a/CHANGELOG.md b/CHANGELOG.md index 3ab2300370..9b11bd59a4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,9 @@ -# Changes to Place +# Changes to PostCSS Place Properties + +### 3.0.0 (May 8, 2018) + +- Updated: `postcss-selector-parser` to v4.0.0 (major) +- Updated: `postcss` to v6.0.22 (patch) ### 2.0.0 (June 30, 2017) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 5e65704b72..3b65d9b80f 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,4 +1,4 @@ -# Contributing to Place +# Contributing to PostCSS Place Properties You want to help? You rock! Now, take a moment to be sure your contributions make sense to everyone else. @@ -14,51 +14,52 @@ Remember, a bug is a _demonstrable problem_ caused by _our_ code. ## Submitting Pull Requests -Pull requests are the greatest contributions, so be sure they are focused in -scope, and do avoid unrelated commits. +Pull requests are the greatest contributions, so be sure they are focused in +scope and avoid unrelated commits. -1. To begin, [fork this project], clone your fork, and add our upstream. - ```bash - # Clone your fork of the repo into the current directory - git clone https://github.com//postcss-place - # Navigate to the newly cloned directory - cd postcss-place - # Assign the original repo to a remote called "upstream" - git remote add upstream https://github.com/jonathantneal/postcss-place - # Install the tools necessary for development - npm install - ``` +1. To begin; [fork this project], clone your fork, and add our upstream. + ```bash + # Clone your fork of the repo into the current directory + git clone git@github.com:YOUR_USER/postcss-place.git -2. Create a branch for your feature or fix: - ```bash - # Move into a new branch for a feature - git checkout -b feature/thing - ``` - ```bash - # Move into a new branch for a fix - git checkout -b fix/something - ``` + # Navigate to the newly cloned directory + cd postcss-place + + # Assign the original repo to a remote called "upstream" + git remote add upstream git@github.com:jonathantneal/postcss-place.git -3. Be sure your code follows our practices. - ```bash - # Test current code - npm run test - ``` + # Install the tools necessary for testing + npm install + ``` + +2. Create a branch for your feature or fix: + ```bash + # Move into a new branch for your feature + git checkout -b feature/thing + ``` + ```bash + # Move into a new branch for your fix + git checkout -b fix/something + ``` -4. Push your branch up to your fork: - ```bash - # Push a feature branch - git push origin feature/thing - ``` - ```bash - # Push a fix branch - git push origin fix/something - ``` +3. If your code follows our practices, then push your feature branch: + ```bash + # Test current code + npm test + ``` + ```bash + # Push the branch for your new feature + git push origin feature/thing + ``` + ```bash + # Or, push the branch for your update + git push origin update/something + ``` -5. Now [open a pull request] with a clear title and description. +That’s it! Now [open a pull request] with a clear title and description. [already been reported]: issues [fork this project]: fork -[live example]: http://codepen.io/pen +[live example]: https://codepen.io/pen [open a pull request]: https://help.github.com/articles/using-pull-requests/ [reduced test case]: https://css-tricks.com/reduced-test-cases/ diff --git a/LICENSE.md b/LICENSE.md index 34f902f6c4..0bc1fa7060 100644 --- a/LICENSE.md +++ b/LICENSE.md @@ -27,80 +27,82 @@ Copyright and Related Rights in the Work and the meaning and intended legal effect of CC0 on those rights. 1. Copyright and Related Rights. A Work made available under CC0 may be - protected by copyright and related or neighboring rights (“Copyright and - Related Rights”). Copyright and Related Rights include, but are not limited - to, the following: - 1. the right to reproduce, adapt, distribute, perform, display, - communicate, and translate a Work; - 2. moral rights retained by the original author(s) and/or performer(s); - 3. publicity and privacy rights pertaining to a person’s image or likeness - depicted in a Work; - 4. rights protecting against unfair competition in regards to a Work, - subject to the limitations in paragraph 4(i), below; - 5. rights protecting the extraction, dissemination, use and reuse of data - in a Work; - 6. database rights (such as those arising under Directive 96/9/EC of the - European Parliament and of the Council of 11 March 1996 on the legal - protection of databases, and under any national implementation thereof, - including any amended or successor version of such directive); and - 7. other similar, equivalent or corresponding rights throughout the world - based on applicable law or treaty, and any national implementations - thereof. + protected by copyright and related or neighboring rights (“Copyright and + Related Rights”). Copyright and Related Rights include, but are not limited + to, the following: + 1. the right to reproduce, adapt, distribute, perform, display, communicate, + and translate a Work; + 2. moral rights retained by the original author(s) and/or performer(s); + 3. publicity and privacy rights pertaining to a person’s image or likeness + depicted in a Work; + 4. rights protecting against unfair competition in regards to a Work, + subject to the limitations in paragraph 4(i), below; + 5. rights protecting the extraction, dissemination, use and reuse of data in + a Work; + 6. database rights (such as those arising under Directive 96/9/EC of the + European Parliament and of the Council of 11 March 1996 on the legal + protection of databases, and under any national implementation thereof, + including any amended or successor version of such directive); and + 7. other similar, equivalent or corresponding rights throughout the world + based on applicable law or treaty, and any national implementations + thereof. 2. Waiver. To the greatest extent permitted by, but not in contravention of, -applicable law, Affirmer hereby overtly, fully, permanently, irrevocably and -unconditionally waives, abandons, and surrenders all of Affirmer’s Copyright -and Related Rights and associated claims and causes of action, whether now -known or unknown (including existing as well as future claims and causes of -action), in the Work (i) in all territories worldwide, (ii) for the maximum -duration provided by applicable law or treaty (including future time -extensions), (iii) in any current or future medium and for any number of -copies, and (iv) for any purpose whatsoever, including without limitation -commercial, advertising or promotional purposes (the “Waiver”). Affirmer makes -the Waiver for the benefit of each member of the public at large and to the -detriment of Affirmer’s heirs and successors, fully intending that such Waiver -shall not be subject to revocation, rescission, cancellation, termination, or -any other legal or equitable action to disrupt the quiet enjoyment of the Work -by the public as contemplated by Affirmer’s express Statement of Purpose. + applicable law, Affirmer hereby overtly, fully, permanently, irrevocably and + unconditionally waives, abandons, and surrenders all of Affirmer’s Copyright + and Related Rights and associated claims and causes of action, whether now + known or unknown (including existing as well as future claims and causes of + action), in the Work (i) in all territories worldwide, (ii) for the maximum + duration provided by applicable law or treaty (including future time + extensions), (iii) in any current or future medium and for any number of + copies, and (iv) for any purpose whatsoever, including without limitation + commercial, advertising or promotional purposes (the “Waiver”). Affirmer + makes the Waiver for the benefit of each member of the public at large and + to the detriment of Affirmer’s heirs and successors, fully intending that + such Waiver shall not be subject to revocation, rescission, cancellation, + termination, or any other legal or equitable action to disrupt the quiet + enjoyment of the Work by the public as contemplated by Affirmer’s express + Statement of Purpose. 3. Public License Fallback. Should any part of the Waiver for any reason be -judged legally invalid or ineffective under applicable law, then the Waiver -shall be preserved to the maximum extent permitted taking into account -Affirmer’s express Statement of Purpose. In addition, to the extent the Waiver -is so judged Affirmer hereby grants to each affected person a royalty-free, non -transferable, non sublicensable, non exclusive, irrevocable and unconditional -license to exercise Affirmer’s Copyright and Related Rights in the Work (i) in -all territories worldwide, (ii) for the maximum duration provided by applicable -law or treaty (including future time extensions), (iii) in any current or -future medium and for any number of copies, and (iv) for any purpose -whatsoever, including without limitation commercial, advertising or promotional -purposes (the “License”). The License shall be deemed effective as of the date -CC0 was applied by Affirmer to the Work. Should any part of the License for any -reason be judged legally invalid or ineffective under applicable law, such -partial invalidity or ineffectiveness shall not invalidate the remainder of the -License, and in such case Affirmer hereby affirms that he or she will not (i) -exercise any of his or her remaining Copyright and Related Rights in the Work -or (ii) assert any associated claims and causes of action with respect to the -Work, in either case contrary to Affirmer’s express Statement of Purpose. + judged legally invalid or ineffective under applicable law, then the Waiver + shall be preserved to the maximum extent permitted taking into account + Affirmer’s express Statement of Purpose. In addition, to the extent the + Waiver is so judged Affirmer hereby grants to each affected person a + royalty-free, non transferable, non sublicensable, non exclusive, + irrevocable and unconditional license to exercise Affirmer’s Copyright and + Related Rights in the Work (i) in all territories worldwide, (ii) for the + maximum duration provided by applicable law or treaty (including future time + extensions), (iii) in any current or future medium and for any number of + copies, and (iv) for any purpose whatsoever, including without limitation + commercial, advertising or promotional purposes (the “License”). The License + shall be deemed effective as of the date CC0 was applied by Affirmer to the + Work. Should any part of the License for any reason be judged legally + invalid or ineffective under applicable law, such partial invalidity or + ineffectiveness shall not invalidate the remainder of the License, and in + such case Affirmer hereby affirms that he or she will not (i) exercise any + of his or her remaining Copyright and Related Rights in the Work or (ii) + assert any associated claims and causes of action with respect to the Work, + in either case contrary to Affirmer’s express Statement of Purpose. 4. Limitations and Disclaimers. - 1. No trademark or patent rights held by Affirmer are waived, abandoned, - surrendered, licensed or otherwise affected by this document. - 2. Affirmer offers the Work as-is and makes no representations or - warranties of any kind concerning the Work, express, implied, statutory - or otherwise, including without limitation warranties of title, - merchantability, fitness for a particular purpose, non infringement, or - the absence of latent or other defects, accuracy, or the present or - absence of errors, whether or not discoverable, all to the greatest - extent permissible under applicable law. - 3. Affirmer disclaims responsibility for clearing rights of other persons - that may apply to the Work or any use thereof, including without - limitation any person’s Copyright and Related Rights in the Work. - Further, Affirmer disclaims responsibility for obtaining any necessary - consents, permissions or other rights required for any use of the Work. - 4. Affirmer understands and acknowledges that Creative Commons is not a - party to this document and has no duty or obligation with respect to - this CC0 or use of the Work. + 1. No trademark or patent rights held by Affirmer are waived, abandoned, + surrendered, licensed or otherwise affected by this document. + 2. Affirmer offers the Work as-is and makes no representations or warranties + of any kind concerning the Work, express, implied, statutory or + otherwise, including without limitation warranties of title, + merchantability, fitness for a particular purpose, non infringement, or + the absence of latent or other defects, accuracy, or the present or + absence of errors, whether or not discoverable, all to the greatest + extent permissible under applicable law. + 3. Affirmer disclaims responsibility for clearing rights of other persons + that may apply to the Work or any use thereof, including without + limitation any person’s Copyright and Related Rights in the Work. + Further, Affirmer disclaims responsibility for obtaining any necessary + consents, permissions or other rights required for any use of the Work. + 4. Affirmer understands and acknowledges that Creative Commons is not a + party to this document and has no duty or obligation with respect to this + CC0 or use of the Work. For more information, please see http://creativecommons.org/publicdomain/zero/1.0/. diff --git a/README.md b/README.md index 191d189872..18052c2f23 100644 --- a/README.md +++ b/README.md @@ -1,52 +1,48 @@ -# Place PostCSS Logo +# PostCSS Place Properties [PostCSS Logo][postcss] [![NPM Version][npm-img]][npm-url] +[![CSS Standard Status][css-img]][css-url] [![Build Status][cli-img]][cli-url] -[![Licensing][lic-image]][lic-url] -[![Changelog][log-image]][log-url] -[![Gitter Chat][git-image]][git-url] +[![Windows Build Status][win-img]][win-url] +[![Support Chat][git-img]][git-url] -[Place] lets you use `place-*` properties as shorthands for `align-*` and `justify-*` per the [CSS Box Alignment Module Level 3]. - -```css -/* before */ +[PostCSS Place Properties] lets you use `place-*` properties as shorthands for `align-*` +and `justify-*`, following the [CSS Box Alignment] specification. +```pcss .example { - place-self: center; - place-content: space-between center; + place-self: center; + place-content: space-between center; } -/* after */ +/* becomes */ .example { - align-self: center; - justify-self: center; - align-content: space-between; - justify-content: center; + align-self: center; + justify-self: center; + place-self: center; + align-content: space-between; + justify-content: center; + place-content: space-between center; } ``` -## Options - -#### `prefix` - -Type: `String` -Default: `null` - -Specifies a prefix to be surrounded by dashes before the declaration (e.g. `prefix: 'x'` changes the detected property to `-x-place-content`). - ## Usage -Add [Place] to your build tool: +Add [PostCSS Place Properties] to your build tool: ```bash -npm install jonathantneal/postcss-place --save-dev +npm install postcss-place --save-dev ``` #### Node +Use [PostCSS Place Properties] to process your CSS: + ```js -require('postcss-place').process(YOUR_CSS, { /* options */ }); +import postcssPlace from 'postcss-place'; + +postcssPlace.process(YOUR_CSS, /* processOptions */, /* pluginOptions */); ``` #### PostCSS @@ -57,12 +53,49 @@ Add [PostCSS] to your build tool: npm install postcss --save-dev ``` -Load [Place] as a PostCSS plugin: +Use [PostCSS Place Properties] as a plugin: ```js +import postcss from 'gulp-postcss'; +import postcssPlace from 'postcss-place'; + postcss([ - require('postcss-place')({ /* options */ }) -]).process(YOUR_CSS, /* options */); + postcssPlace(/* pluginOptions */) +]).process(YOUR_CSS); +``` + +#### Webpack + +Add [PostCSS Loader] to your build tool: + +```bash +npm install postcss-loader --save-dev +``` + +Use [PostCSS Place Properties] in your Webpack configuration: + +```js +import postcssPlace from 'postcss-place'; + +module.exports = { + module: { + rules: [ + { + test: /\.css$/, + use: [ + 'style-loader', + { loader: 'css-loader', options: { importLoaders: 1 } }, + { loader: 'postcss-loader', options: { + ident: 'postcss', + plugins: () => [ + postcssPlace(/* pluginOptions */) + ] + } } + ] + } + ] + } +} ``` #### Gulp @@ -73,20 +106,19 @@ Add [Gulp PostCSS] to your build tool: npm install gulp-postcss --save-dev ``` -Enable [Place] within your Gulpfile: +Use [PostCSS Place Properties] in your Gulpfile: ```js -var postcss = require('gulp-postcss'); - -gulp.task('css', function () { - return gulp.src('./src/*.css').pipe( - postcss([ - require('postcss-place')({ /* options */ }) - ]) - ).pipe( - gulp.dest('.') - ); -}); +import postcss from 'gulp-postcss'; +import postcssPlace from 'postcss-place'; + +gulp.task('css', () => gulp.src('./src/*.css').pipe( + postcss([ + postcssPlace(/* pluginOptions */) + ]) +).pipe( + gulp.dest('.') +)); ``` #### Grunt @@ -97,38 +129,68 @@ Add [Grunt PostCSS] to your build tool: npm install grunt-postcss --save-dev ``` -Enable [Place] within your Gruntfile: +Use [PostCSS Place Properties] in your Gruntfile: ```js +import postcssPlace from 'postcss-place'; + grunt.loadNpmTasks('grunt-postcss'); grunt.initConfig({ - postcss: { - options: { - use: [ - require('postcss-place')({ /* options */ }) - ] - }, - dist: { - src: '*.css' - } - } + postcss: { + options: { + use: [ + postcssPlace(/* pluginOptions */) + ] + }, + dist: { + src: '*.css' + } + } }); ``` -[npm-url]: https://www.npmjs.com/package/postcss-place -[npm-img]: https://img.shields.io/npm/v/postcss-place.svg -[cli-url]: https://travis-ci.org/jonathantneal/postcss-place +## Options + +### preserve + +The `preserve` option determines whether the original place declaration is +preserved. By default, it is preserved. + +```js +postcssPlace({ preserve: false }) +``` + +```pcss +.example { + place-self: center; + place-content: space-between center; +} + +/* becomes */ + +.example { + align-self: center; + justify-self: center; + align-content: space-between; + justify-content: center; +} +``` + [cli-img]: https://img.shields.io/travis/jonathantneal/postcss-place.svg -[lic-url]: LICENSE.md -[lic-image]: https://img.shields.io/npm/l/postcss-place.svg -[log-url]: CHANGELOG.md -[log-image]: https://img.shields.io/badge/changelog-md-blue.svg +[cli-url]: https://travis-ci.org/jonathantneal/postcss-place +[css-img]: https://cssdb.org/badge/place-properties.svg +[css-url]: https://cssdb.org/#place-properties +[git-img]: https://img.shields.io/badge/support-chat-blue.svg [git-url]: https://gitter.im/postcss/postcss -[git-image]: https://img.shields.io/badge/chat-gitter-blue.svg +[npm-img]: https://img.shields.io/npm/v/postcss-place.svg +[npm-url]: https://www.npmjs.com/package/postcss-place +[win-img]: https://img.shields.io/appveyor/ci/jonathantneal/postcss-place.svg +[win-url]: https://ci.appveyor.com/project/jonathantneal/postcss-place -[Place]: https://github.com/jonathantneal/postcss-place -[CSS Box Alignment Module Level 3]: https://drafts.csswg.org/css-align/#propdef-place-content -[PostCSS]: https://github.com/postcss/postcss +[CSS Box Alignment]: https://www.w3.org/TR/css-align-3/#place-content [Gulp PostCSS]: https://github.com/postcss/gulp-postcss [Grunt PostCSS]: https://github.com/nDmitry/grunt-postcss +[PostCSS]: https://github.com/postcss/postcss +[PostCSS Loader]: https://github.com/postcss/postcss-loader +[PostCSS Place Properties]: https://github.com/jonathantneal/postcss-place diff --git a/index.js b/index.js index 364fb36545..6f9be9e07b 100644 --- a/index.js +++ b/index.js @@ -1,20 +1,17 @@ -// tooling -const postcss = require('postcss'); -const parser = require('postcss-value-parser'); +import postcss from 'postcss'; +import parser from 'postcss-value-parser'; -// plugin -module.exports = postcss.plugin('postcss-place', (opts) => { - // dashed prefix - const dashedPrefix = opts && opts.prefix ? `-${ opts.prefix }-` : ''; +const placeMatch = /^place-(content|items|self)/; - // property matcher - const propertyMatch = new RegExp(`^${ dashedPrefix }place-(content|items|self)`); +export default postcss.plugin('postcss-place', opts => { + // prepare options + const preserve = 'preserve' in Object(opts) ? Boolean(opts.prefix) : true; - return (root) => { + return root => { // walk each matching declaration - root.walkDecls(propertyMatch, (decl) => { + root.walkDecls(placeMatch, decl => { // alignment - const alignment = decl.prop.match(propertyMatch)[1]; + const alignment = decl.prop.match(placeMatch)[1]; // value const value = parser(decl.value); @@ -25,28 +22,23 @@ module.exports = postcss.plugin('postcss-place', (opts) => { ).indexOf('space'); // new justify-[alignment] and align-[alignment] declarations - const alignValue = index === -1 ? decl.value : parser.stringify(value.nodes.slice(0, index)); + const alignValue = index === -1 ? decl.value : parser.stringify(value.nodes.slice(0, index)); const justifyValue = index === -1 ? decl.value : parser.stringify(value.nodes.slice(index + 1)); decl.cloneBefore({ - prop: `align-${ alignment }`, + prop: `align-${alignment}`, value: alignValue }); decl.cloneBefore({ - prop: `justify-${ alignment }`, + prop: `justify-${alignment}`, value: justifyValue }); - // remove place-[alignment] - decl.remove(); + // conditionally remove place-[alignment] + if (!preserve) { + decl.remove(); + } }); }; }); - -// override plugin#process -module.exports.process = function (cssString, pluginOptions, processOptions) { - return postcss([ - 0 in arguments ? module.exports(pluginOptions) : module.exports() - ]).process(cssString, processOptions); -}; diff --git a/package.json b/package.json index 8b12e48375..e1480e394b 100644 --- a/package.json +++ b/package.json @@ -1,49 +1,47 @@ { "name": "postcss-place", - "version": "2.0.0", - "description": "`place-[alignment] shorthand for align-[alignment] and justify-[alignment]", - "author": "Jonathan Neal (http://jonathantneal.com)", + "version": "3.0.0", + "description": "Use a place-* shorthand for align-* and justify-* in CSS", + "author": "Jonathan Neal ", "license": "CC0-1.0", "repository": "jonathantneal/postcss-place", "homepage": "https://github.com/jonathantneal/postcss-place#readme", "bugs": "https://github.com/jonathantneal/postcss-place/issues", - "main": "index.js", + "main": "index.cjs.js", + "module": "index.es.js", "files": [ - "index.js" + "index.cjs.js", + "index.es.js" ], "scripts": { - "lint": "echint && eslint index.js && jscs index.js", - "prepublish": "npm test", - "tape": "postcss-tape", - "test": "npm run lint && postcss-tape" + "prepublishOnly": "npm test", + "pretest": "rollup -c .rollup.js --silent", + "test": "echo 'Running tests...'; npm run test:js && npm run test:tape", + "test:ec": "echint --ignore index.*.js test", + "test:js": "eslint *.js --cache --ignore-path .gitignore --quiet", + "test:tape": "postcss-tape" }, "engines": { - "node": ">=6.9.1" + "node": ">=4.0.0" }, "dependencies": { - "postcss": "^6.0.4", + "postcss": "^6.0.22", "postcss-value-parser": "^3.3.0" }, "devDependencies": { - "echint": "^4.0.1", - "echint-config-dev": "1.0.0", - "eslint": "^4.1.1", - "eslint-config-dev": "2.0.0", - "jscs": "^3.0.7", - "jscs-config-dev": "1.0.1", - "postcss-tape": "2.0.1" - }, - "echint": { - "extends": "dev" + "babel-core": "^6.26.3", + "babel-eslint": "^8.2.3", + "babel-preset-env": "^1.6.1", + "eslint": "^4.19.1", + "eslint-config-dev": "^2.0.0", + "postcss-tape": "^2.2.0", + "pre-commit": "^1.2.2", + "rollup": "^0.58.2", + "rollup-plugin-babel": "^3.0.4" }, "eslintConfig": { "extends": "dev", - "parserOptions": { - "sourceType": "module" - } - }, - "jscsConfig": { - "preset": "dev" + "parser": "babel-eslint" }, "keywords": [ "postcss", diff --git a/test/basic.expect.css b/test/basic.expect.css index 92214f4558..f94f52a313 100644 --- a/test/basic.expect.css +++ b/test/basic.expect.css @@ -1,35 +1,47 @@ a { align-content: first; justify-content: second; + place-content: first second; align-items: first; justify-items: second; + place-items: first second; align-self: first; justify-self: second; + place-self: first second; } b { align-content: first; justify-content: first; + place-content: first; align-items: first; justify-items: first; + place-items: first; align-self: first; justify-self: first; + place-self: first; } c { align-content: var(--first); justify-content: second; + place-content: var(--first) second; align-items: var(--first); justify-items: second; + place-items: var(--first) second; align-self: var(--first); justify-self: second; + place-self: var(--first) second; } d { align-content: first; justify-content: var(--second); + place-content: first var(--second); align-items: first; justify-items: var(--second); + place-items: first var(--second); align-self: first; justify-self: var(--second); + place-self: first var(--second); } diff --git a/test/basic.preserve-false.expect.css b/test/basic.preserve-false.expect.css new file mode 100644 index 0000000000..92214f4558 --- /dev/null +++ b/test/basic.preserve-false.expect.css @@ -0,0 +1,35 @@ +a { + align-content: first; + justify-content: second; + align-items: first; + justify-items: second; + align-self: first; + justify-self: second; +} + +b { + align-content: first; + justify-content: first; + align-items: first; + justify-items: first; + align-self: first; + justify-self: first; +} + +c { + align-content: var(--first); + justify-content: second; + align-items: var(--first); + justify-items: second; + align-self: var(--first); + justify-self: second; +} + +d { + align-content: first; + justify-content: var(--second); + align-items: first; + justify-items: var(--second); + align-self: first; + justify-self: var(--second); +} From b628680cc930f6c1af62c8babb8c0946132f1030 Mon Sep 17 00:00:00 2001 From: Jonathan Neal Date: Tue, 8 May 2018 01:57:08 -0400 Subject: [PATCH 621/795] 3.0.1 --- CHANGELOG.md | 4 ++-- index.js | 16 ++++++---------- package.json | 4 ++-- 3 files changed, 10 insertions(+), 14 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9b11bd59a4..35b9a5fd70 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,8 +1,8 @@ # Changes to PostCSS Place Properties -### 3.0.0 (May 8, 2018) +### 3.0.1 (May 8, 2018) -- Updated: `postcss-selector-parser` to v4.0.0 (major) +- Updated: `postcss-values-parser` to v1.5.0 (major) - Updated: `postcss` to v6.0.22 (patch) ### 2.0.0 (June 30, 2017) diff --git a/index.js b/index.js index 6f9be9e07b..0bb31ccc80 100644 --- a/index.js +++ b/index.js @@ -1,5 +1,5 @@ import postcss from 'postcss'; -import parser from 'postcss-value-parser'; +import parser from 'postcss-values-parser'; const placeMatch = /^place-(content|items|self)/; @@ -13,17 +13,13 @@ export default postcss.plugin('postcss-place', opts => { // alignment const alignment = decl.prop.match(placeMatch)[1]; - // value - const value = parser(decl.value); - - // divider position - const index = value.nodes.map( - (node) => node.type - ).indexOf('space'); + // value ast and child nodes + const value = parser(decl.value).parse(); + const children = value.nodes[0].nodes; // new justify-[alignment] and align-[alignment] declarations - const alignValue = index === -1 ? decl.value : parser.stringify(value.nodes.slice(0, index)); - const justifyValue = index === -1 ? decl.value : parser.stringify(value.nodes.slice(index + 1)); + const alignValue = children.length === 1 ? decl.value : String(children.slice(0, 1)).trim(); + const justifyValue = children.length === 1 ? decl.value : String(children.slice(1)).trim(); decl.cloneBefore({ prop: `align-${alignment}`, diff --git a/package.json b/package.json index e1480e394b..e461e48598 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "postcss-place", - "version": "3.0.0", + "version": "3.0.1", "description": "Use a place-* shorthand for align-* and justify-* in CSS", "author": "Jonathan Neal ", "license": "CC0-1.0", @@ -26,7 +26,7 @@ }, "dependencies": { "postcss": "^6.0.22", - "postcss-value-parser": "^3.3.0" + "postcss-values-parser": "^1.5.0" }, "devDependencies": { "babel-core": "^6.26.3", From a2b9cd2d621cee32063f4d43c282b7f9b0fd5aa1 Mon Sep 17 00:00:00 2001 From: Jonathan Neal Date: Fri, 11 May 2018 10:19:13 -0400 Subject: [PATCH 622/795] 1.0.0 --- .appveyor.yml | 18 +++ .editorconfig | 15 +++ .gitignore | 12 ++ .rollup.js | 16 +++ .tape.js | 13 ++ .travis.yml | 9 ++ CHANGELOG.md | 5 + CONTRIBUTING.md | 65 ++++++++++ LICENSE.md | 108 ++++++++++++++++ README.md | 192 ++++++++++++++++++++++++++++ index.js | 104 +++++++++++++++ package.json | 65 ++++++++++ test/basic.css | 15 +++ test/basic.expect.css | 15 +++ test/basic.preserve-true.expect.css | 25 ++++ 15 files changed, 677 insertions(+) create mode 100644 .appveyor.yml create mode 100644 .editorconfig create mode 100644 .gitignore create mode 100644 .rollup.js create mode 100644 .tape.js create mode 100644 .travis.yml create mode 100644 CHANGELOG.md create mode 100644 CONTRIBUTING.md create mode 100644 LICENSE.md create mode 100644 README.md create mode 100644 index.js create mode 100644 package.json create mode 100644 test/basic.css create mode 100644 test/basic.expect.css create mode 100644 test/basic.preserve-true.expect.css diff --git a/.appveyor.yml b/.appveyor.yml new file mode 100644 index 0000000000..acbf8a5eeb --- /dev/null +++ b/.appveyor.yml @@ -0,0 +1,18 @@ +# https://www.appveyor.com/docs/appveyor-yml + +environment: + matrix: + - nodejs_version: 4 + +version: "{build}" +build: off +deploy: off + +install: + - ps: Install-Product node $env:nodejs_version + - npm install --ignore-scripts + +test_script: + - node --version + - npm --version + - cmd: "npm test" diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000000..e06d7982bc --- /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/.gitignore b/.gitignore new file mode 100644 index 0000000000..de73e5a338 --- /dev/null +++ b/.gitignore @@ -0,0 +1,12 @@ +node_modules +index.*.js +package-lock.json +*.log* +*.result.css +.* +!.appveyor.yml +!.editorconfig +!.gitignore +!.rollup.js +!.tape.js +!.travis.yml diff --git a/.rollup.js b/.rollup.js new file mode 100644 index 0000000000..0436758216 --- /dev/null +++ b/.rollup.js @@ -0,0 +1,16 @@ +import babel from 'rollup-plugin-babel'; + +export default { + input: 'index.js', + output: [ + { file: 'index.cjs.js', format: 'cjs' }, + { file: 'index.es.js', format: 'es' } + ], + plugins: [ + babel({ + presets: [ + ['env', { modules: false, targets: { node: 4 } }] + ] + }) + ] +}; diff --git a/.tape.js b/.tape.js new file mode 100644 index 0000000000..4f2b738523 --- /dev/null +++ b/.tape.js @@ -0,0 +1,13 @@ +module.exports = { + 'postcss-lab-function': { + 'basic': { + message: 'supports basic usage' + }, + 'basic:preserve-true': { + message: 'supports { preserve: true } usage', + options: { + preserve: true + } + } + } +}; diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000000..c56466446c --- /dev/null +++ b/.travis.yml @@ -0,0 +1,9 @@ +# https://docs.travis-ci.com/user/travis-lint + +language: node_js + +node_js: + - 4 + +install: + - npm install --ignore-scripts diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000000..6b10693aa5 --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,5 @@ +# Changes to PostCSS Lab Function + +### 1.0.0 (May 11, 2018) + +- Initial version diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 0000000000..bb9debdfdd --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,65 @@ +# Contributing to PostCSS Lab Function + +You want to help? You rock! Now, take a moment to be sure your contributions +make sense to everyone else. + +## Reporting Issues + +Found a problem? Want a new feature? + +- See if your issue or idea has [already been reported]. +- Provide a [reduced test case] or a [live example]. + +Remember, a bug is a _demonstrable problem_ caused by _our_ code. + +## Submitting Pull Requests + +Pull requests are the greatest contributions, so be sure they are focused in +scope and avoid unrelated commits. + +1. To begin; [fork this project], clone your fork, and add our upstream. + ```bash + # Clone your fork of the repo into the current directory + git clone git@github.com:YOUR_USER/postcss-lab-function.git + + # Navigate to the newly cloned directory + cd postcss-lab-function + + # Assign the original repo to a remote called "upstream" + git remote add upstream git@github.com:jonathantneal/postcss-lab-function.git + + # Install the tools necessary for testing + npm install + ``` + +2. Create a branch for your feature or fix: + ```bash + # Move into a new branch for your feature + git checkout -b feature/thing + ``` + ```bash + # Move into a new branch for your fix + git checkout -b fix/something + ``` + +3. If your code follows our practices, then push your feature branch: + ```bash + # Test current code + npm test + ``` + ```bash + # Push the branch for your new feature + git push origin feature/thing + ``` + ```bash + # Or, push the branch for your update + git push origin update/something + ``` + +That’s it! Now [open a pull request] with a clear title and description. + +[already been reported]: issues +[fork this project]: fork +[live example]: https://codepen.io/pen +[open a pull request]: https://help.github.com/articles/using-pull-requests/ +[reduced test case]: https://css-tricks.com/reduced-test-cases/ diff --git a/LICENSE.md b/LICENSE.md new file mode 100644 index 0000000000..0bc1fa7060 --- /dev/null +++ b/LICENSE.md @@ -0,0 +1,108 @@ +# CC0 1.0 Universal + +## Statement of Purpose + +The laws of most jurisdictions throughout the world automatically confer +exclusive Copyright and Related Rights (defined below) upon the creator and +subsequent owner(s) (each and all, an “owner”) of an original work of +authorship and/or a database (each, a “Work”). + +Certain owners wish to permanently relinquish those rights to a Work for the +purpose of contributing to a commons of creative, cultural and scientific works +(“Commons”) that the public can reliably and without fear of later claims of +infringement build upon, modify, incorporate in other works, reuse and +redistribute as freely as possible in any form whatsoever and for any purposes, +including without limitation commercial purposes. These owners may contribute +to the Commons to promote the ideal of a free culture and the further +production of creative, cultural and scientific works, or to gain reputation or +greater distribution for their Work in part through the use and efforts of +others. + +For these and/or other purposes and motivations, and without any expectation of +additional consideration or compensation, the person associating CC0 with a +Work (the “Affirmer”), to the extent that he or she is an owner of Copyright +and Related Rights in the Work, voluntarily elects to apply CC0 to the Work and +publicly distribute the Work under its terms, with knowledge of his or her +Copyright and Related Rights in the Work and the meaning and intended legal +effect of CC0 on those rights. + +1. Copyright and Related Rights. A Work made available under CC0 may be + protected by copyright and related or neighboring rights (“Copyright and + Related Rights”). Copyright and Related Rights include, but are not limited + to, the following: + 1. the right to reproduce, adapt, distribute, perform, display, communicate, + and translate a Work; + 2. moral rights retained by the original author(s) and/or performer(s); + 3. publicity and privacy rights pertaining to a person’s image or likeness + depicted in a Work; + 4. rights protecting against unfair competition in regards to a Work, + subject to the limitations in paragraph 4(i), below; + 5. rights protecting the extraction, dissemination, use and reuse of data in + a Work; + 6. database rights (such as those arising under Directive 96/9/EC of the + European Parliament and of the Council of 11 March 1996 on the legal + protection of databases, and under any national implementation thereof, + including any amended or successor version of such directive); and + 7. other similar, equivalent or corresponding rights throughout the world + based on applicable law or treaty, and any national implementations + thereof. + +2. Waiver. To the greatest extent permitted by, but not in contravention of, + applicable law, Affirmer hereby overtly, fully, permanently, irrevocably and + unconditionally waives, abandons, and surrenders all of Affirmer’s Copyright + and Related Rights and associated claims and causes of action, whether now + known or unknown (including existing as well as future claims and causes of + action), in the Work (i) in all territories worldwide, (ii) for the maximum + duration provided by applicable law or treaty (including future time + extensions), (iii) in any current or future medium and for any number of + copies, and (iv) for any purpose whatsoever, including without limitation + commercial, advertising or promotional purposes (the “Waiver”). Affirmer + makes the Waiver for the benefit of each member of the public at large and + to the detriment of Affirmer’s heirs and successors, fully intending that + such Waiver shall not be subject to revocation, rescission, cancellation, + termination, or any other legal or equitable action to disrupt the quiet + enjoyment of the Work by the public as contemplated by Affirmer’s express + Statement of Purpose. + +3. Public License Fallback. Should any part of the Waiver for any reason be + judged legally invalid or ineffective under applicable law, then the Waiver + shall be preserved to the maximum extent permitted taking into account + Affirmer’s express Statement of Purpose. In addition, to the extent the + Waiver is so judged Affirmer hereby grants to each affected person a + royalty-free, non transferable, non sublicensable, non exclusive, + irrevocable and unconditional license to exercise Affirmer’s Copyright and + Related Rights in the Work (i) in all territories worldwide, (ii) for the + maximum duration provided by applicable law or treaty (including future time + extensions), (iii) in any current or future medium and for any number of + copies, and (iv) for any purpose whatsoever, including without limitation + commercial, advertising or promotional purposes (the “License”). The License + shall be deemed effective as of the date CC0 was applied by Affirmer to the + Work. Should any part of the License for any reason be judged legally + invalid or ineffective under applicable law, such partial invalidity or + ineffectiveness shall not invalidate the remainder of the License, and in + such case Affirmer hereby affirms that he or she will not (i) exercise any + of his or her remaining Copyright and Related Rights in the Work or (ii) + assert any associated claims and causes of action with respect to the Work, + in either case contrary to Affirmer’s express Statement of Purpose. + +4. Limitations and Disclaimers. + 1. No trademark or patent rights held by Affirmer are waived, abandoned, + surrendered, licensed or otherwise affected by this document. + 2. Affirmer offers the Work as-is and makes no representations or warranties + of any kind concerning the Work, express, implied, statutory or + otherwise, including without limitation warranties of title, + merchantability, fitness for a particular purpose, non infringement, or + the absence of latent or other defects, accuracy, or the present or + absence of errors, whether or not discoverable, all to the greatest + extent permissible under applicable law. + 3. Affirmer disclaims responsibility for clearing rights of other persons + that may apply to the Work or any use thereof, including without + limitation any person’s Copyright and Related Rights in the Work. + Further, Affirmer disclaims responsibility for obtaining any necessary + consents, permissions or other rights required for any use of the Work. + 4. Affirmer understands and acknowledges that Creative Commons is not a + party to this document and has no duty or obligation with respect to this + CC0 or use of the Work. + +For more information, please see +http://creativecommons.org/publicdomain/zero/1.0/. diff --git a/README.md b/README.md new file mode 100644 index 0000000000..99dc229b6c --- /dev/null +++ b/README.md @@ -0,0 +1,192 @@ +# PostCSS Lab Function [PostCSS Logo][postcss] + +[![NPM Version][npm-img]][npm-url] +[![CSS Standard Status][css-img]][css-url] +[![Build Status][cli-img]][cli-url] +[![Windows Build Status][win-img]][win-url] +[![Support Chat][git-img]][git-url] + +[PostCSS Lab Function] lets you use `lab` and `lch` color functions in CSS, +following the [CSS Color] specification. + +```pcss +:root { + --firebrick: lab(40 56.6 39); + --firebrick-a50: lch(40 68.8 34.5 / 50%); +} + +/* becomes */ + +:root { + --firebrick: rgb(178, 34, 34); + --firebrick-a50: rgba(178, 34, 34, .5); +} +``` + +## Usage + +Add [PostCSS Lab Function] to your build tool: + +```bash +npm install postcss-lab-function --save-dev +``` + +#### Node + +Use [PostCSS Lab Function] to process your CSS: + +```js +import postcssLabFunction from 'postcss-lab-function'; + +postcssLabFunction.process(YOUR_CSS, /* processOptions */, /* pluginOptions */); +``` + +#### PostCSS + +Add [PostCSS] to your build tool: + +```bash +npm install postcss --save-dev +``` + +Use [PostCSS Lab Function] as a plugin: + +```js +import postcss from 'gulp-postcss'; +import postcssLabFunction from 'postcss-lab-function'; + +postcss([ + postcssLabFunction(/* pluginOptions */) +]).process(YOUR_CSS); +``` + +#### Webpack + +Add [PostCSS Loader] to your build tool: + +```bash +npm install postcss-loader --save-dev +``` + +Use [PostCSS Lab Function] in your Webpack configuration: + +```js +import postcssLabFunction from 'postcss-lab-function'; + +module.exports = { + module: { + rules: [ + { + test: /\.css$/, + use: [ + 'style-loader', + { loader: 'css-loader', options: { importLoaders: 1 } }, + { loader: 'postcss-loader', options: { + ident: 'postcss', + plugins: () => [ + postcssLabFunction(/* pluginOptions */) + ] + } } + ] + } + ] + } +} +``` + +#### Gulp + +Add [Gulp PostCSS] to your build tool: + +```bash +npm install gulp-postcss --save-dev +``` + +Use [PostCSS Lab Function] in your Gulpfile: + +```js +import postcss from 'gulp-postcss'; +import postcssLabFunction from 'postcss-lab-function'; + +gulp.task('css', () => gulp.src('./src/*.css').pipe( + postcss([ + postcssLabFunction(/* pluginOptions */) + ]) +).pipe( + gulp.dest('.') +)); +``` + +#### Grunt + +Add [Grunt PostCSS] to your build tool: + +```bash +npm install grunt-postcss --save-dev +``` + +Use [PostCSS Lab Function] in your Gruntfile: + +```js +import postcssLabFunction from 'postcss-lab-function'; + +grunt.loadNpmTasks('grunt-postcss'); + +grunt.initConfig({ + postcss: { + options: { + use: [ + postcssLabFunction(/* pluginOptions */) + ] + }, + dist: { + src: '*.css' + } + } +}); +``` + +## Options + +### preserve + +The `preserve` option determines whether the original functional color notation +is preserved. By default, it is not preserved. + +```js +postcssImageSetFunction({ preserve: true }) +``` + +```pcss +:root { + --firebrick: lab(40 56.6 39); + --firebrick-a50: lch(40 68.8 34.5 / 50%); +} + +/* becomes */ + +:root { + --firebrick: rgb(178, 34, 34); + --firebrick: lab(40 56.6 39); + --firebrick-a50: rgba(178, 34, 34, .5); + --firebrick-a50: lch(40 68.8 34.5 / 50%); +} +``` + +[cli-img]: https://img.shields.io/travis/jonathantneal/postcss-lab-function.svg +[cli-url]: https://travis-ci.org/jonathantneal/postcss-lab-function +[css-img]: https://cssdb.org/badge/lab-function.svg +[css-url]: https://cssdb.org/#lab-function +[git-img]: https://img.shields.io/badge/support-chat-blue.svg +[git-url]: https://gitter.im/postcss/postcss +[npm-img]: https://img.shields.io/npm/v/postcss-lab-function.svg +[npm-url]: https://www.npmjs.com/package/postcss-lab-function +[win-img]: https://img.shields.io/appveyor/ci/jonathantneal/postcss-lab-function.svg +[win-url]: https://ci.appveyor.com/project/jonathantneal/postcss-lab-function + +[CSS Color]: https://drafts.csswg.org/css-color/#specifying-lab-lch +[Gulp PostCSS]: https://github.com/postcss/gulp-postcss +[Grunt PostCSS]: https://github.com/nDmitry/grunt-postcss +[PostCSS]: https://github.com/postcss/postcss +[PostCSS Loader]: https://github.com/postcss/postcss-loader +[PostCSS Lab Function]: https://github.com/jonathantneal/postcss-lab-function diff --git a/index.js b/index.js new file mode 100644 index 0000000000..9a23ff2169 --- /dev/null +++ b/index.js @@ -0,0 +1,104 @@ +import { lab2rgb, lch2rgb } from '@csstools/convert-colors'; +import postcss from 'postcss'; +import parser from 'postcss-values-parser'; + +export default postcss.plugin('postcss-lab-function', opts => { + const preserve = 'preserve' in Object(opts) ? Boolean(opts.preserve) : false; + + return root => { + root.walkDecls(decl => { + const { value } = decl; + + if (colorAnyRegExp.test(value)) { + const ast = parser(value).parse(); + + ast.walkType('func', node => { + if (colorRegExp.test(node.value)) { + const children = node.nodes.slice(1, -1); + const isLab = labRegExp.test(node.value); + const isFunctionalLAB = matchFunctionalLAB(children); + const isFunctionalLCH = matchFunctionalLCH(children); + + if (isFunctionalLAB || isFunctionalLCH) { + node.value = 'rgb' + + const slashNode = children[3]; + const alphaNode = children[4]; + + if (alphaNode) { + if (isPercentage(alphaNode) && !isCalc(alphaNode)) { + alphaNode.unit = ''; + alphaNode.value = String(alphaNode.value / 100); + } + + if (alphaNode.value === '1') { + slashNode.remove(); + alphaNode.remove(); + } else { + node.value += 'a'; + } + } + + if (isSlash(slashNode)) { + slashNode.replaceWith( newComma() ); + } + + const converter = isLab ? lab2rgb : lch2rgb; + + const rgbValues = converter( + ...[ + children[0].value, + children[1].value, + children[2].value + ].map( + number => parseFloat(number) + ) + ).map( + sourceValue => parseInt(sourceValue * 2.55) + ) + + children[0].value = String(rgbValues[0]); + children[1].value = String(rgbValues[1]); + children[2].value = String(rgbValues[2]); + + node.nodes.splice(3, 0, [ newComma() ]); + node.nodes.splice(2, 0, [ newComma() ]); + } + } + }); + + const newValue = String(ast); + + if (preserve) { + decl.cloneBefore({ value: newValue }); + } else { + decl.value = newValue; + } + } + }); + }; +}); + +const colorAnyRegExp = /(^|[^\w-])(lab?|lch?)\(/i; +const colorRegExp = /^(lab?|lch?)$/i; +const labRegExp = /^lab$/i; +const alphaUnitMatch = /^%?$/i; +const calcFuncMatch = /^calc$/i; +const hueUnitMatch = /^(deg|grad|rad|turn)?$/i; + +const isAlphaValue = node => isCalc(node) || Object(node).type === 'number' && alphaUnitMatch.test(node.unit); +const isCalc = node => Object(node).type === 'func' && calcFuncMatch.test(node.value); +const isHue = node => isCalc(node) || Object(node).type === 'number' && hueUnitMatch.test(node.unit); +const isNumber = node => isCalc(node) || Object(node).type === 'number' && node.unit === ''; +const isPercentage = node => isCalc(node) || Object(node).type === 'number' && node.unit === '%'; +const isSlash = node => Object(node).type === 'operator' && node.value === '/'; +const functionalLABMatch = [isNumber, isNumber, isNumber, isSlash, isAlphaValue]; +const functionalLCHMatch = [isNumber, isNumber, isHue, isSlash, isAlphaValue]; +const matchFunctionalLAB = children => children.every( + (child, index) => typeof functionalLABMatch[index] === 'function' && functionalLABMatch[index](child) +); +const matchFunctionalLCH = children => children.every( + (child, index) => typeof functionalLCHMatch[index] === 'function' && functionalLCHMatch[index](child) +); + +const newComma = () => parser.comma({ value: ',' }) diff --git a/package.json b/package.json new file mode 100644 index 0000000000..85489c8e1b --- /dev/null +++ b/package.json @@ -0,0 +1,65 @@ +{ + "name": "postcss-lab-function", + "version": "1.0.0", + "description": "Use lab() and lch() color functions in CSS", + "author": "Jonathan Neal ", + "license": "CC0-1.0", + "repository": "jonathantneal/postcss-lab-function", + "homepage": "https://github.com/jonathantneal/postcss-lab-function#readme", + "bugs": "https://github.com/jonathantneal/postcss-lab-function/issues", + "main": "index.cjs.js", + "module": "index.es.js", + "files": [ + "index.cjs.js", + "index.es.js" + ], + "scripts": { + "prepublishOnly": "npm test", + "pretest": "rollup -c .rollup.js --silent", + "test": "echo 'Running tests...'; npm run test:js && npm run test:tape", + "test:ec": "echint --ignore index.*.js test", + "test:js": "eslint *.js --cache --ignore-path .gitignore --quiet", + "test:tape": "postcss-tape" + }, + "engines": { + "node": ">=4.0.0" + }, + "dependencies": { + "@csstools/convert-colors": "^1.4.0", + "postcss": "^6.0.22", + "postcss-values-parser": "^1.5.0" + }, + "devDependencies": { + "babel-core": "^6.26.3", + "babel-eslint": "^8.2.3", + "babel-preset-env": "^1.7.0", + "eslint": "^4.19.1", + "eslint-config-dev": "^2.0.0", + "postcss-tape": "^2.2.0", + "pre-commit": "^1.2.2", + "rollup": "^0.58.2", + "rollup-plugin-babel": "^3.0.4" + }, + "eslintConfig": { + "extends": "dev", + "parser": "babel-eslint" + }, + "keywords": [ + "postcss", + "css", + "postcss-plugin", + "color", + "colors", + "rgb", + "rgba", + "hsl", + "hsla", + "hwb", + "functional", + "notation", + "design", + "syntax", + "space", + "comma" + ] +} diff --git a/test/basic.css b/test/basic.css new file mode 100644 index 0000000000..65e029e573 --- /dev/null +++ b/test/basic.css @@ -0,0 +1,15 @@ +.test-lab { + color: lab(40 56.6 39); + color: lab(40 56.6 39 / 1); + color: lab(40 56.6 39 / .5); + color: lab(40 56.6 39 / 100%); + color: lab(40 56.6 39 / 50%); +} + +.test-lch { + color: lch(40 68.8 34.5); + color: lch(40 68.8 34.5 / 1); + color: lch(40 68.8 34.5 / .5); + color: lch(40 68.8 34.5 / 100%); + color: lch(40 68.8 34.5 / 50%); +} diff --git a/test/basic.expect.css b/test/basic.expect.css new file mode 100644 index 0000000000..306d9a75da --- /dev/null +++ b/test/basic.expect.css @@ -0,0 +1,15 @@ +.test-lab { + color: rgb(178, 34, 34); + color: rgb(178, 34, 34); + color: rgba(178, 34, 34, .5); + color: rgb(178, 34, 34); + color: rgba(178, 34, 34, 0.5); +} + +.test-lch { + color: rgb(178, 34, 34); + color: rgb(178, 34, 34); + color: rgba(178, 34, 34, .5); + color: rgb(178, 34, 34); + color: rgba(178, 34, 34, 0.5); +} diff --git a/test/basic.preserve-true.expect.css b/test/basic.preserve-true.expect.css new file mode 100644 index 0000000000..f030287308 --- /dev/null +++ b/test/basic.preserve-true.expect.css @@ -0,0 +1,25 @@ +.test-lab { + color: rgb(178, 34, 34); + color: lab(40 56.6 39); + color: rgb(178, 34, 34); + color: lab(40 56.6 39 / 1); + color: rgba(178, 34, 34, .5); + color: lab(40 56.6 39 / .5); + color: rgb(178, 34, 34); + color: lab(40 56.6 39 / 100%); + color: rgba(178, 34, 34, 0.5); + color: lab(40 56.6 39 / 50%); +} + +.test-lch { + color: rgb(178, 34, 34); + color: lch(40 68.8 34.5); + color: rgb(178, 34, 34); + color: lch(40 68.8 34.5 / 1); + color: rgba(178, 34, 34, .5); + color: lch(40 68.8 34.5 / .5); + color: rgb(178, 34, 34); + color: lch(40 68.8 34.5 / 100%); + color: rgba(178, 34, 34, 0.5); + color: lch(40 68.8 34.5 / 50%); +} From 1f3ce3b6590dfe442aec931bc1cd3a3908dfe124 Mon Sep 17 00:00:00 2001 From: Jonathan Neal Date: Fri, 11 May 2018 12:30:27 -0400 Subject: [PATCH 623/795] 1.0.1 --- CHANGELOG.md | 4 ++++ index.js | 2 +- package.json | 2 +- test/basic.css | 2 ++ test/basic.expect.css | 2 ++ test/basic.preserve-true.expect.css | 4 ++++ 6 files changed, 14 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6b10693aa5..a106b4086c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # Changes to PostCSS Lab Function +### 1.0.1 (May 11, 2018) + +- Fixed: Values beyond the acceptable 0-255 RGB range + ### 1.0.0 (May 11, 2018) - Initial version diff --git a/index.js b/index.js index 9a23ff2169..ff5eeb181f 100644 --- a/index.js +++ b/index.js @@ -54,7 +54,7 @@ export default postcss.plugin('postcss-lab-function', opts => { number => parseFloat(number) ) ).map( - sourceValue => parseInt(sourceValue * 2.55) + sourceValue => Math.max(Math.min(parseInt(sourceValue * 2.55), 255), 0) ) children[0].value = String(rgbValues[0]); diff --git a/package.json b/package.json index 85489c8e1b..0256cee60f 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "postcss-lab-function", - "version": "1.0.0", + "version": "1.0.1", "description": "Use lab() and lch() color functions in CSS", "author": "Jonathan Neal ", "license": "CC0-1.0", diff --git a/test/basic.css b/test/basic.css index 65e029e573..a06b69e0b9 100644 --- a/test/basic.css +++ b/test/basic.css @@ -4,6 +4,7 @@ color: lab(40 56.6 39 / .5); color: lab(40 56.6 39 / 100%); color: lab(40 56.6 39 / 50%); + color: lab(100 50 0); } .test-lch { @@ -12,4 +13,5 @@ color: lch(40 68.8 34.5 / .5); color: lch(40 68.8 34.5 / 100%); color: lch(40 68.8 34.5 / 50%); + color: lch(100 50 0); } diff --git a/test/basic.expect.css b/test/basic.expect.css index 306d9a75da..4068e14752 100644 --- a/test/basic.expect.css +++ b/test/basic.expect.css @@ -4,6 +4,7 @@ color: rgba(178, 34, 34, .5); color: rgb(178, 34, 34); color: rgba(178, 34, 34, 0.5); + color: rgb(255, 216, 255); } .test-lch { @@ -12,4 +13,5 @@ color: rgba(178, 34, 34, .5); color: rgb(178, 34, 34); color: rgba(178, 34, 34, 0.5); + color: rgb(255, 216, 255); } diff --git a/test/basic.preserve-true.expect.css b/test/basic.preserve-true.expect.css index f030287308..fdf49ebb0e 100644 --- a/test/basic.preserve-true.expect.css +++ b/test/basic.preserve-true.expect.css @@ -9,6 +9,8 @@ color: lab(40 56.6 39 / 100%); color: rgba(178, 34, 34, 0.5); color: lab(40 56.6 39 / 50%); + color: rgb(255, 216, 255); + color: lab(100 50 0); } .test-lch { @@ -22,4 +24,6 @@ color: lch(40 68.8 34.5 / 100%); color: rgba(178, 34, 34, 0.5); color: lch(40 68.8 34.5 / 50%); + color: rgb(255, 216, 255); + color: lch(100 50 0); } From 6d2040ac0007e7465450f84519073a3f661abd9c Mon Sep 17 00:00:00 2001 From: Jonathan Neal Date: Fri, 11 May 2018 17:28:08 -0400 Subject: [PATCH 624/795] 1.0.1 --- CHANGELOG.md | 4 ++++ index.js | 9 ++++----- package.json | 4 ++-- 3 files changed, 10 insertions(+), 7 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c229c7f419..5641f6930a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # Changes to PostCSS Color Functional Notation +### 1.0.1 (May 11, 2018) + +- Fixed: A non-percentage 0 works alongside other percentages + ### 1.0.0 (May 7, 2018) - Initial version diff --git a/index.js b/index.js index 4e00f5f56f..18e90cc717 100644 --- a/index.js +++ b/index.js @@ -1,9 +1,6 @@ import postcss from 'postcss'; import parser from 'postcss-values-parser'; -const colorAnyRegExp = /(^|[^\w-])(hsla?|rgba?)\(/i; -const colorRegExp = /^(hsla?|rgba?)$/i; - export default postcss.plugin('postcss-color-functional-notation', opts => { const preserve = 'preserve' in Object(opts) ? Boolean(opts.preserve) : false; @@ -70,14 +67,16 @@ export default postcss.plugin('postcss-color-functional-notation', opts => { const alphaUnitMatch = /^%?$/i; const calcFuncMatch = /^calc$/i; -const hueUnitMatch = /^(deg|grad|rad|turn)?$/i; +const colorAnyRegExp = /(^|[^\w-])(hsla?|rgba?)\(/i; +const colorRegExp = /^(hsla?|rgba?)$/i; const hslRgbFuncMatch = /^(hsl|rgb)$/i; const hslaRgbaFuncMatch = /^(hsla|rgba)$/i; +const hueUnitMatch = /^(deg|grad|rad|turn)?$/i; const isAlphaValue = node => isCalc(node) || Object(node).type === 'number' && alphaUnitMatch.test(node.unit); const isCalc = node => Object(node).type === 'func' && calcFuncMatch.test(node.value); const isHue = node => isCalc(node) || Object(node).type === 'number' && hueUnitMatch.test(node.unit); const isNumber = node => isCalc(node) || Object(node).type === 'number' && node.unit === ''; -const isPercentage = node => isCalc(node) || Object(node).type === 'number' && node.unit === '%'; +const isPercentage = node => isCalc(node) || Object(node).type === 'number' && (node.unit === '%' || node.unit === '' && node.value === '0'); const isHslRgb = node => Object(node).type === 'func' && hslRgbFuncMatch.test(node.value); const isHslaRgba = node => Object(node).type === 'func' && hslaRgbaFuncMatch.test(node.value); const isSlash = node => Object(node).type === 'operator' && node.value === '/'; diff --git a/package.json b/package.json index 1a1e867d4c..db870cc54f 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "postcss-color-functional-notation", - "version": "1.0.0", + "version": "1.0.1", "description": "Use space and slash separated color notation in CSS", "author": "Jonathan Neal ", "license": "CC0-1.0", @@ -31,7 +31,7 @@ "devDependencies": { "babel-core": "^6.26.3", "babel-eslint": "^8.2.3", - "babel-preset-env": "^1.6.1", + "babel-preset-env": "^1.7.0", "eslint": "^4.19.1", "eslint-config-dev": "^2.0.0", "postcss-tape": "^2.2.0", From 04b917547d848f88e26cd39c003797a9f18175cb Mon Sep 17 00:00:00 2001 From: Jonathan Neal Date: Fri, 11 May 2018 17:29:40 -0400 Subject: [PATCH 625/795] Update README.md --- README.md | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/README.md b/README.md index 7f450274af..881e0ca8d6 100644 --- a/README.md +++ b/README.md @@ -12,18 +12,18 @@ color notation in CSS, following the [CSS Color] specification. ```pcss :root { --firebrick: rgb(178 34 34); - --firebrick-a50: color: rgb(70% 13.5% 13.5% / 50%); - --firebrick-hsl: color: hsla(0 68% 42%); - --firebrick-hsl-a50: color: hsl(0 68% 42% / 50%); + --firebrick-a50: rgb(70% 13.5% 13.5% / 50%); + --firebrick-hsl: hsla(0 68% 42%); + --firebrick-hsl-a50: hsl(0 68% 42% / 50%); } /* becomes */ :root { --firebrick: rgb(178, 34, 34); - --firebrick-a50: color: rgba(178, 34, 34, .5); - --firebrick-hsl: color: hsl(0, 68%, 42%); - --firebrick-hsl-a50: color: hsla(0, 68%, 42%, .5); + --firebrick-a50: rgba(178, 34, 34, .5); + --firebrick-hsl: hsl(0, 68%, 42%); + --firebrick-hsl-a50: hsla(0, 68%, 42%, .5); } ``` @@ -164,9 +164,9 @@ postcssImageSetFunction({ preserve: true }) ```pcss :root { --firebrick: rgb(178 34 34); - --firebrick-a50: color: rgb(70% 13.5% 13.5% / 50%); - --firebrick-hsl: color: hsla(0 68% 42%); - --firebrick-hsl-a50: color: hsl(0 68% 42% / 50%); + --firebrick-a50: rgb(70% 13.5% 13.5% / 50%); + --firebrick-hsl: hsla(0 68% 42%); + --firebrick-hsl-a50: hsl(0 68% 42% / 50%); } /* becomes */ @@ -174,12 +174,12 @@ postcssImageSetFunction({ preserve: true }) :root { --firebrick: rgb(178, 34, 34); --firebrick: rgb(178 34 34); - --firebrick-a50: color: rgba(178, 34, 34, .5); - --firebrick-a50: color: rgb(70% 13.5% 13.5% / 50%); - --firebrick-hsl: color: hsl(0, 68%, 42%); - --firebrick-hsl: color: hsla(0 68% 42%); - --firebrick-hsl-a50: color: hsla(0, 68%, 42%, .5); - --firebrick-hsl-a50: color: hsl(0 68% 42% / 50%); + --firebrick-a50: rgba(178, 34, 34, .5); + --firebrick-a50: rgb(70% 13.5% 13.5% / 50%); + --firebrick-hsl: hsl(0, 68%, 42%); + --firebrick-hsl: hsla(0 68% 42%); + --firebrick-hsl-a50: hsla(0, 68%, 42%, .5); + --firebrick-hsl-a50: hsl(0 68% 42% / 50%); } ``` From 52d91194510bb6871b48708ad71087d44af44623 Mon Sep 17 00:00:00 2001 From: Marco Pfeiffer Date: Sat, 12 May 2018 21:53:51 +0200 Subject: [PATCH 626/795] fixed #4 The implementation is correct, the documentation is not. --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 098cb6e703..0279afaa1f 100644 --- a/README.md +++ b/README.md @@ -32,7 +32,7 @@ p:not(:first-child, .special) { you will get: ```css -p:not(:first-child), p:not(.special) { +p:not(:first-child):not(.special) { color: red; } ``` From 77c5e7f363c319cce436d3b51a196950892c1056 Mon Sep 17 00:00:00 2001 From: Jonathan Neal Date: Mon, 14 May 2018 16:55:40 -0400 Subject: [PATCH 627/795] Update README.md - cssdb stage --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 0279afaa1f..810c9f5d5f 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# postcss-selector-not [![CSS Standard Status](https://jonathantneal.github.io/css-db/badge/selectors-negation.svg)](https://jonathantneal.github.io/css-db/#selectors-negation) [![Build Status](https://travis-ci.org/postcss/postcss-selector-not.svg?branch=master)](https://travis-ci.org/postcss/postcss-selector-not) +# postcss-selector-not [![CSS Standard Status](https://cssdb.org/badge/not-pseudo-class.svg)](https://cssdb.org/#not-pseudo-class) [![Build Status](https://travis-ci.org/postcss/postcss-selector-not.svg?branch=master)](https://travis-ci.org/postcss/postcss-selector-not) > PostCSS plugin to transform `:not()` W3C CSS leve 4 pseudo class to :not() CSS level 3 selectors From 136962105e906c838f9d01871ae9fe1313ddcad0 Mon Sep 17 00:00:00 2001 From: Jonathan Neal Date: Tue, 15 May 2018 10:16:45 -0400 Subject: [PATCH 628/795] Update README.md cssdb link --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index fcf1d0f9d5..4ef4aa6d2b 100644 --- a/README.md +++ b/README.md @@ -204,8 +204,8 @@ focusVisible({ replaceWith: '[focus-visible]' }); [cli-img]: https://img.shields.io/travis/jonathantneal/postcss-focus-visible.svg [cli-url]: https://travis-ci.org/jonathantneal/postcss-focus-visible -[css-img]: https://jonathantneal.github.io/cssdb/badge/focus-within-pseudo-class.svg -[css-url]: https://jonathantneal.github.io/css-db/#css-variables +[css-img]: https://cssdb.org/badge/focus-within-pseudo-class.svg +[css-url]: https://cssdb.org/#focus-visible-pseudo-class [git-img]: https://img.shields.io/badge/support-chat-blue.svg [git-url]: https://gitter.im/postcss/postcss [npm-img]: https://img.shields.io/npm/v/postcss-focus-visible.svg From 8336b818f3a28b7e35dc59ec66a365196185365e Mon Sep 17 00:00:00 2001 From: Jonathan Neal Date: Tue, 15 May 2018 10:25:16 -0400 Subject: [PATCH 629/795] Update README.md heading --- README.md | 55 +++++++++++++++++++++++++++++++++++-------------------- 1 file changed, 35 insertions(+), 20 deletions(-) diff --git a/README.md b/README.md index d5ae05744e..0ec621dc2a 100755 --- a/README.md +++ b/README.md @@ -1,6 +1,27 @@ -# postcss-custom-media [![CSS Standard Status](https://jonathantneal.github.io/css-db/badge/mediaqueries-custom-mq.svg)](https://jonathantneal.github.io/css-db/#mediaqueries-custom-mq) [![Build Status](https://travis-ci.org/postcss/postcss-custom-media.png)](https://travis-ci.org/postcss/postcss-custom-media) +# PostCSS Custom Media [PostCSS Logo][postcss] -> [PostCSS](https://github.com/postcss/postcss) plugin to transform [W3C CSS Custom Media Queries](https://drafts.csswg.org/mediaqueries-5/#custom-mq) syntax to more compatible CSS. +[![NPM Version][npm-img]][npm-url] +[![CSS Standard Status][css-img]][css-url] +[![Build Status][cli-img]][cli-url] +[![Support Chat][git-img]][git-url] + +> [PostCSS Custom Media] lets you use Custom Media Queries in CSS, following +the [CSS Media Queries](https://drafts.csswg.org/mediaqueries-5/#custom-mq) +specification. + +```pcss +@custom-media --small-viewport (max-width: 30em); + +@media (--small-viewport) { + /* styles for small viewport */ +} + +/* becomes */ + +@media (max-width: 30em) { + /* styles for small viewport */ +} +``` ## Installation @@ -25,24 +46,6 @@ var out = postcss() .css ``` -Using this `input.css`: - -```css -@custom-media --small-viewport (max-width: 30em); - -@media (--small-viewport) { - /* styles for small viewport */ -} -``` - -you will get: - -```css -@media (max-width: 30em) { - /* styles for small viewport */ -} -``` - Checkout [tests](test) for more examples. ### Options @@ -81,3 +84,15 @@ Allows you to append your extensions at end of your CSS. ## [Changelog](CHANGELOG.md) ## [License](LICENSE) + +[cli-img]: https://img.shields.io/travis/postcss/postcss-custom-media.svg +[cli-url]: https://travis-ci.org/postcss/postcss-custom-media +[css-img]: https://cssdb.org/badge/custom-media-queries.svg +[css-url]: https://cssdb.org/#custom-media-queries +[git-img]: https://img.shields.io/badge/support-chat-blue.svg +[git-url]: https://gitter.im/postcss/postcss +[npm-img]: https://img.shields.io/npm/v/postcss-custom-media.svg +[npm-url]: https://www.npmjs.com/package/postcss-custom-media + +[PostCSS]: https://github.com/postcss/postcss +[PostCSS Custom Media]: https://github.com/postcss/postcss-custom-media From ccc045dff596c22f364264852fa4a2f6fd15653d Mon Sep 17 00:00:00 2001 From: Jonathan Neal Date: Tue, 15 May 2018 10:26:53 -0400 Subject: [PATCH 630/795] Update README.md badges --- README.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 87c354da8e..b24e8a80c0 100755 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ [![NPM Version][npm-img]][npm-url] [![CSS Standard Status][css-img]][css-url] [![Build Status][cli-img]][cli-url] -[![Gitter Chat][git-img]][git-url] +[![Support Chat][git-img]][git-url] [PostCSS Custom Properties] lets you use CSS Custom Properties in CSS, following the [CSS Custom Properties for Cascading Variables] specification. @@ -359,12 +359,12 @@ $ npm test [npm-url]: https://www.npmjs.com/package/postcss-custom-properties [npm-img]: https://img.shields.io/npm/v/postcss-custom-properties.svg -[css-url]: https://jonathantneal.github.io/css-db/#css-variables -[css-img]: https://jonathantneal.github.io/cssdb/badge/custom-properties.svg +[css-url]: https://cssdb.org/#css-variables +[css-img]: https://cssdb.org/badge/custom-properties.svg [cli-url]: https://travis-ci.org/postcss/postcss-custom-properties [cli-img]: https://img.shields.io/travis/postcss/postcss-custom-properties.svg [git-url]: https://gitter.im/postcss/postcss -[git-img]: https://img.shields.io/badge/chat-gitter-blue.svg +[git-img]: https://img.shields.io/badge/support-chat-blue.svg [CSS Custom Properties for Cascading Variables]: https://www.w3.org/TR/css-variables-1/ [PostCSS CSS Variables]: https://github.com/MadLittleMods/postcss-css-variables From ed433b3f696939b14afbfe336af1b1e7e9d4b044 Mon Sep 17 00:00:00 2001 From: Jonathan Neal Date: Tue, 15 May 2018 10:28:29 -0400 Subject: [PATCH 631/795] Update README.md badges --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 50dd3f9ab6..32a562b8d4 100644 --- a/README.md +++ b/README.md @@ -202,8 +202,8 @@ focusWithin({ replaceWith: '.focus-within' }); } ``` -[css-img]: https://jonathantneal.github.io/cssdb/badge/focus-within-pseudo-class.svg -[css-url]: https://jonathantneal.github.io/cssdb/#focus-within-pseudo-class +[css-img]: https://cssdb.org/badge/focus-within-pseudo-class.svg +[css-url]: https://cssdb.org/#focus-within-pseudo-class [cli-img]: https://img.shields.io/travis/jonathantneal/postcss-focus-within.svg [cli-url]: https://travis-ci.org/jonathantneal/postcss-focus-within [git-img]: https://img.shields.io/badge/support-chat-blue.svg From ad8ea10e9be3be827544f388af20e7d0041afd96 Mon Sep 17 00:00:00 2001 From: Jonathan Neal Date: Tue, 15 May 2018 10:30:31 -0400 Subject: [PATCH 632/795] Update README.md badges --- README.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/README.md b/README.md index 947175aa34..fc4451547f 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,7 @@ # PostCSS Gap Properties [PostCSS Logo][postcss] [![NPM Version][npm-img]][npm-url] +[![CSS Standard Status][css-img]][css-url] [![Build Status][cli-img]][cli-url] [![Windows Build Status][win-img]][win-url] [![Support Chat][git-img]][git-url] @@ -163,6 +164,8 @@ grunt.initConfig({ The `preserve` option determines whether the original `gap` declaration should remain in the CSS. By default, the original declaration is preserved. +[css-img]: https://cssdb.org/badge/gap-properties.svg +[css-url]: https://cssdb.org/#gap-properties [cli-img]: https://img.shields.io/travis/jonathantneal/postcss-gap-properties.svg [cli-url]: https://travis-ci.org/jonathantneal/postcss-gap-properties [git-img]: https://img.shields.io/badge/support-chat-blue.svg From c2666f19280726a149af37f42314fb91fbab5416 Mon Sep 17 00:00:00 2001 From: Jonathan Neal Date: Tue, 15 May 2018 10:39:27 -0400 Subject: [PATCH 633/795] Update README.md heading --- README.md | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 4017d695bf..c3769d3f43 100755 --- a/README.md +++ b/README.md @@ -1,6 +1,10 @@ -# postcss-font-variant [![Build Status](https://travis-ci.org/postcss/postcss-font-variant.png)](https://travis-ci.org/postcss/postcss-font-variant) +# PostCSS Font-Variant [PostCSS Logo](https://github.com/postcss/postcss/) -> [PostCSS](https://github.com/postcss/postcss) plugin to transform [W3C CSS font variant](http://dev.w3.org/csswg/css-fonts/#propdef-font-variant) properties to more compatible CSS (font-feature-settings). +[![CSS Status](https://cssdb.org/badge/font-variant-property.svg)](https://cssdb.org/#font-variant-property) +[![Build Status](https://travis-ci.org/postcss/postcss-font-variant.svg)](https://travis-ci.org/postcss/postcss-font-variant) + +PostCSS Font-Variant lets you use `font-variant` in CSS, following the +[CSS Fonts](https://www.w3.org/TR/css-fonts-3/#font-variant-prop) specification. ## Installation From 4adb75ccf3fb05a1f1d0560ce6715400808cf09e Mon Sep 17 00:00:00 2001 From: Joe Schmitt Date: Tue, 15 May 2018 22:05:46 -0400 Subject: [PATCH 634/795] Fix appendVariables appending duplicate vars --- index.js | 26 +++++++++++--------- test/fixtures/append.duplicates.css | 8 ++++++ test/fixtures/append.duplicates.expected.css | 14 +++++++++++ test/index.js | 16 +++++++++++- 4 files changed, 51 insertions(+), 13 deletions(-) create mode 100644 test/fixtures/append.duplicates.css create mode 100644 test/fixtures/append.duplicates.expected.css diff --git a/index.js b/index.js index 645f981bbb..0faac2e48d 100755 --- a/index.js +++ b/index.js @@ -276,25 +276,27 @@ export default postcss.plugin("postcss-custom-properties", (options = {}) => { } }) - if (preserve && appendVariables) { + if (preserve && variables && appendVariables) { const names = Object.keys(map) if (names.length) { const container = postcss.rule({ selector: ":root", raws: {semicolon: true}, }) - names.forEach((name) => { - const variable = map[name] - let val = variable.value - if (variable.resolved) { - val = val[val.length - 1] - } - const decl = postcss.decl({ - prop: name, - value: val, + names + .filter((name) => variables.hasOwnProperty(name)) + .forEach((name) => { + const variable = map[name] + let val = variable.value + if (variable.resolved) { + val = val[val.length - 1] + } + const decl = postcss.decl({ + prop: name, + value: val, + }) + container.append(decl) }) - container.append(decl) - }) style.append(container) } } diff --git a/test/fixtures/append.duplicates.css b/test/fixtures/append.duplicates.css new file mode 100644 index 0000000000..7dab61fdee --- /dev/null +++ b/test/fixtures/append.duplicates.css @@ -0,0 +1,8 @@ +:root { + --test-one: css-one; +} + +div { + p: var(--test-one); + a: var(--test-two); +} diff --git a/test/fixtures/append.duplicates.expected.css b/test/fixtures/append.duplicates.expected.css new file mode 100644 index 0000000000..f9b7947f57 --- /dev/null +++ b/test/fixtures/append.duplicates.expected.css @@ -0,0 +1,14 @@ +:root { + --test-one: css-one; +} + +div { + p: css-one; + a: js-one; +} + +:root { + --test-two: js-one; + --test-three: js-two; + --test-four: css-one js-one js-two; +} \ No newline at end of file diff --git a/test/index.js b/test/index.js index 68c26a1376..52c3ccf258 100755 --- a/test/index.js +++ b/test/index.js @@ -23,7 +23,7 @@ function compareFixtures(t, name, options) { const actual = postcssResult.css.trim() // handy thing: checkout actual in the *.actual.css file - fs.writeFile(fixturePath(name + ".actual"), actual) + fs.writeFile(fixturePath(name + ".actual"), actual, () => {}) const expected = fixture(name + ".expected") t.equal( @@ -247,6 +247,20 @@ test("append variables", function(t) { t.end() }) +test("append variables without duplicates", function(t) { + compareFixtures(t, "append.duplicates", { + variables: { + "--test-two": "js-one", + "test-three": "js-two", + "test-four": "var(--test-one, one) var(--test-two, two) " + + "var(--test-three, three)", + }, + preserve: "computed", + appendVariables: true, + }) + t.end() +}) + test("strict option", function(t) { compareFixtures(t, "substitution-strict", { strict: false, From 76c1ff6dc2702f4d13a0fe659426cc810a4b8e35 Mon Sep 17 00:00:00 2001 From: Jonathan Neal Date: Tue, 22 May 2018 09:57:37 -0400 Subject: [PATCH 635/795] Update README.md cssdb links --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 4109695ceb..a044cce91d 100644 --- a/README.md +++ b/README.md @@ -242,8 +242,8 @@ article h3:dir(ltr) { [cli-img]: https://img.shields.io/travis/jonathantneal/postcss-dir-pseudo-class.svg [cli-url]: https://travis-ci.org/jonathantneal/postcss-dir-pseudo-class -[css-img]: https://jonathantneal.github.io/cssdb/badge/dir-pseudo-class.svg -[css-url]: https://jonathantneal.github.io/cssdb/#dir-pseudo-class +[css-img]: https://cssdb.org/badge/dir-pseudo-class.svg +[css-url]: https://cssdb.org/#dir-pseudo-class [git-img]: https://img.shields.io/badge/support-chat-blue.svg [git-url]: https://gitter.im/postcss/postcss [npm-img]: https://img.shields.io/npm/v/postcss-dir-pseudo-class.svg From 34a3aae7733594515493917bff7347052c8217a1 Mon Sep 17 00:00:00 2001 From: Philip Bordallo Date: Sat, 26 May 2018 10:29:31 -0700 Subject: [PATCH 636/795] Fix cssdb badge and link --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index a82c8b4e2f..893c695a4f 100644 --- a/README.md +++ b/README.md @@ -154,8 +154,8 @@ grunt.initConfig({ [cli-url]: https://travis-ci.org/jonathantneal/postcss-nesting [cli-img]: https://img.shields.io/travis/jonathantneal/postcss-nesting.svg -[css-img]: https://jonathantneal.github.io/cssdb/badge/nesting-rules.svg -[css-url]: https://jonathantneal.github.io/cssdb/#nesting-rules +[css-img]: https://cssdb.org/badge/nesting-rules.svg +[css-url]: https://cssdb.org/#nesting-rules [git-url]: https://gitter.im/postcss/postcss [git-img]: https://img.shields.io/badge/chat-gitter-blue.svg [npm-url]: https://www.npmjs.com/package/postcss-nesting From a68c2d5fd94ed34b895ba866821ceb0718f93a96 Mon Sep 17 00:00:00 2001 From: Jonathan Neal Date: Thu, 7 Jun 2018 00:43:49 -0400 Subject: [PATCH 637/795] 5.0.0 --- .gitignore | 10 +- .rollup.js | 16 + .travis.yml | 2 +- CHANGELOG.md | 6 + CONTRIBUTING.md | 77 +-- INSTALL.md | 149 ++++++ LICENSE.md | 138 ++--- README.md | 126 ++--- lib/normalize.json | 1 + package-lock.json | 772 ---------------------------- package.json | 49 +- test/basic.expect.css | 15 - test/insertion-after.expect.css | 15 - test/insertion-duplicate.expect.css | 15 - test/option-force-import.expect.css | 12 - 15 files changed, 346 insertions(+), 1057 deletions(-) create mode 100644 .rollup.js create mode 100644 INSTALL.md create mode 100644 lib/normalize.json delete mode 100644 package-lock.json diff --git a/.gitignore b/.gitignore index 04d3d72273..94065768da 100644 --- a/.gitignore +++ b/.gitignore @@ -1,11 +1,11 @@ node_modules +index.*.js +package-lock.json +*.log* +*.result.css .* -!.appveyor.yml !.editorconfig !.gitignore +!.rollup.js !.tape.js !.travis.yml -*.log* -*.result.css -/index.css -/lib/normalize.json diff --git a/.rollup.js b/.rollup.js new file mode 100644 index 0000000000..48e2d2e760 --- /dev/null +++ b/.rollup.js @@ -0,0 +1,16 @@ +import babel from 'rollup-plugin-babel'; + +export default { + input: 'index.js', + output: [ + { file: 'index.cjs.js', format: 'cjs' }, + { file: 'index.es.js', format: 'es' } + ], + plugins: [ + babel({ + presets: [ + ['env', { modules: false, targets: { node: 6 } }] + ] + }) + ] +}; diff --git a/.travis.yml b/.travis.yml index c56466446c..e1f11a52e6 100644 --- a/.travis.yml +++ b/.travis.yml @@ -3,7 +3,7 @@ language: node_js node_js: - - 4 + - 6 install: - npm install --ignore-scripts diff --git a/CHANGELOG.md b/CHANGELOG.md index 0f0acbdbed..0fe139a072 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,11 @@ # Changes to PostCSS Normalize +### 5.0.0 (June 7, 2018) + +- Update `browserslist` to v3.2.8 (major) +- Update: `postcss` to v6.0.22 (patch) +- Update: Node support from v4 to v6 (major) + ### 4.0.0 (June 21, 2017) - Require insertion point. Make old behavior an option. diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index d280ee89d4..b1765ba538 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -14,51 +14,52 @@ Remember, a bug is a _demonstrable problem_ caused by _our_ code. ## Submitting Pull Requests -Pull requests are the greatest contributions, so be sure they are focused in -scope, and do avoid unrelated commits. +Pull requests are the greatest contributions, so be sure they are focused in +scope and avoid unrelated commits. -1. To begin, [fork this project], clone your fork, and add our upstream. - ```bash - # Clone your fork of the repo into the current directory - git clone https://github.com//postcss-normalize - # Navigate to the newly cloned directory - cd postcss-normalize - # Assign the original repo to a remote called "upstream" - git remote add upstream https://github.com/jonathantneal/postcss-normalize - # Install the tools necessary for development - npm install - ``` +1. To begin; [fork this project], clone your fork, and add our upstream. + ```bash + # Clone your fork of the repo into the current directory + git clone git@github.com:YOUR_USER/postcss-normalize.git -2. Create a branch for your feature or fix: - ```bash - # Move into a new branch for a feature - git checkout -b feature/thing - ``` - ```bash - # Move into a new branch for a fix - git checkout -b fix/something - ``` + # Navigate to the newly cloned directory + cd postcss-normalize + + # Assign the original repo to a remote called "upstream" + git remote add upstream git@github.com:jonathantneal/postcss-normalize.git -3. Be sure your code follows our practices. - ```bash - # Test current code - npm run test - ``` + # Install the tools necessary for testing + npm install + ``` + +2. Create a branch for your feature or fix: + ```bash + # Move into a new branch for your feature + git checkout -b feature/thing + ``` + ```bash + # Move into a new branch for your fix + git checkout -b fix/something + ``` -4. Push your branch up to your fork: - ```bash - # Push a feature branch - git push origin feature/thing - ``` - ```bash - # Push a fix branch - git push origin fix/something - ``` +3. If your code follows our practices, then push your feature branch: + ```bash + # Test current code + npm test + ``` + ```bash + # Push the branch for your new feature + git push origin feature/thing + ``` + ```bash + # Or, push the branch for your update + git push origin update/something + ``` -5. Now [open a pull request] with a clear title and description. +That’s it! Now [open a pull request] with a clear title and description. [already been reported]: issues [fork this project]: fork -[live example]: http://codepen.io/pen +[live example]: https://codepen.io/pen [open a pull request]: https://help.github.com/articles/using-pull-requests/ [reduced test case]: https://css-tricks.com/reduced-test-cases/ diff --git a/INSTALL.md b/INSTALL.md new file mode 100644 index 0000000000..e3430ee9d6 --- /dev/null +++ b/INSTALL.md @@ -0,0 +1,149 @@ +# Installing PostCSS Normalize + +$[PostCSS Normalize] runs in all Node environments, with special instructions for: + +| [Node](#node) | [Webpack](#webpack) | [Create React App](#create-react-app) | [Gulp](#gulp) | [Grunt](#grunt) | +| --- | --- | --- | --- | --- | + +## Node + +Add [PostCSS Normalize] to your project: + +```bash +npm install postcss-normalize --save-dev +``` + +Use [PostCSS Normalize] to process your CSS: + +```js +import postcssNormalize from 'postcss-normalize'; + +postcssNormalize.process(YOUR_CSS /*, processOptions, pluginOptions */); +``` + +Or use it as a [PostCSS] plugin: + +```js +import postcss from 'postcss'; +import postcssNormalize from 'postcss-normalize'; + +postcss([ + postcssNormalize(/* pluginOptions */) +]).process(YOUR_CSS /*, processOptions */); +``` + +## Webpack + +Add [PostCSS Loader] to your project: + +```bash +npm install postcss-loader --save-dev +``` + +Use [PostCSS Normalize] in your Webpack configuration: + +```js +import postcssNormalize from 'postcss-normalize'; + +module.exports = { + module: { + rules: [ + { + test: /\.css$/, + use: [ + 'style-loader', + { loader: 'css-loader', options: { importLoaders: 1 } }, + { loader: 'postcss-loader', options: { + ident: 'postcss', + plugins: () => [ + postcssNormalize(/* pluginOptions */) + ] + } } + ] + } + ] + } +} +``` + +## Create React App + +Add [React App Rewired] and [React App Rewire PostCSS] to your project: + +```bash +npm install react-app-rewired react-app-rewire-postcss --save-dev +``` + +Use [React App Rewire PostCSS] and [PostCSS Normalize] in your +`config-overrides.js` file: + +```js +import reactAppRewirePostcss from 'react-app-rewire-postcss'; +import postcssNormalize from 'postcss-normalize'; + +export default config => reactAppRewirePostcss(config, { + plugins: () => [ + postcssNormalize(/* pluginOptions */) + ] +}); +``` + +## Gulp + +Add [Gulp PostCSS] to your project: + +```bash +npm install gulp-postcss --save-dev +``` + +Use [PostCSS Normalize] in your Gulpfile: + +```js +import postcss from 'gulp-postcss'; +import postcssNormalize from 'postcss-normalize'; + +gulp.task('css', () => gulp.src('./src/*.css').pipe( + postcss([ + postcssNormalize(/* pluginOptions */) + ]) +).pipe( + gulp.dest('.') +)); +``` + +## Grunt + +Add [Grunt PostCSS] to your project: + +```bash +npm install grunt-postcss --save-dev +``` + +Use [PostCSS Normalize] in your Gruntfile: + +```js +import postcssNormalize from 'postcss-normalize'; + +grunt.loadNpmTasks('grunt-postcss'); + +grunt.initConfig({ + postcss: { + options: { + use: [ + postcssNormalize(/* pluginOptions */) + ] + }, + dist: { + src: '*.css' + } + } +}); +``` + +[Gulp PostCSS]: https://github.com/postcss/gulp-postcss +[Grunt PostCSS]: https://github.com/nDmitry/grunt-postcss +[PostCSS]: https://github.com/postcss/postcss +[PostCSS Loader]: https://github.com/postcss/postcss-loader +[PostCSS Normalize]: https://github.com/jonathantneal/postcss-normalize +[React App Rewire PostCSS]: https://github.com/csstools/react-app-rewire-postcss +[React App Rewired]: https://github.com/timarney/react-app-rewired diff --git a/LICENSE.md b/LICENSE.md index 34f902f6c4..0bc1fa7060 100644 --- a/LICENSE.md +++ b/LICENSE.md @@ -27,80 +27,82 @@ Copyright and Related Rights in the Work and the meaning and intended legal effect of CC0 on those rights. 1. Copyright and Related Rights. A Work made available under CC0 may be - protected by copyright and related or neighboring rights (“Copyright and - Related Rights”). Copyright and Related Rights include, but are not limited - to, the following: - 1. the right to reproduce, adapt, distribute, perform, display, - communicate, and translate a Work; - 2. moral rights retained by the original author(s) and/or performer(s); - 3. publicity and privacy rights pertaining to a person’s image or likeness - depicted in a Work; - 4. rights protecting against unfair competition in regards to a Work, - subject to the limitations in paragraph 4(i), below; - 5. rights protecting the extraction, dissemination, use and reuse of data - in a Work; - 6. database rights (such as those arising under Directive 96/9/EC of the - European Parliament and of the Council of 11 March 1996 on the legal - protection of databases, and under any national implementation thereof, - including any amended or successor version of such directive); and - 7. other similar, equivalent or corresponding rights throughout the world - based on applicable law or treaty, and any national implementations - thereof. + protected by copyright and related or neighboring rights (“Copyright and + Related Rights”). Copyright and Related Rights include, but are not limited + to, the following: + 1. the right to reproduce, adapt, distribute, perform, display, communicate, + and translate a Work; + 2. moral rights retained by the original author(s) and/or performer(s); + 3. publicity and privacy rights pertaining to a person’s image or likeness + depicted in a Work; + 4. rights protecting against unfair competition in regards to a Work, + subject to the limitations in paragraph 4(i), below; + 5. rights protecting the extraction, dissemination, use and reuse of data in + a Work; + 6. database rights (such as those arising under Directive 96/9/EC of the + European Parliament and of the Council of 11 March 1996 on the legal + protection of databases, and under any national implementation thereof, + including any amended or successor version of such directive); and + 7. other similar, equivalent or corresponding rights throughout the world + based on applicable law or treaty, and any national implementations + thereof. 2. Waiver. To the greatest extent permitted by, but not in contravention of, -applicable law, Affirmer hereby overtly, fully, permanently, irrevocably and -unconditionally waives, abandons, and surrenders all of Affirmer’s Copyright -and Related Rights and associated claims and causes of action, whether now -known or unknown (including existing as well as future claims and causes of -action), in the Work (i) in all territories worldwide, (ii) for the maximum -duration provided by applicable law or treaty (including future time -extensions), (iii) in any current or future medium and for any number of -copies, and (iv) for any purpose whatsoever, including without limitation -commercial, advertising or promotional purposes (the “Waiver”). Affirmer makes -the Waiver for the benefit of each member of the public at large and to the -detriment of Affirmer’s heirs and successors, fully intending that such Waiver -shall not be subject to revocation, rescission, cancellation, termination, or -any other legal or equitable action to disrupt the quiet enjoyment of the Work -by the public as contemplated by Affirmer’s express Statement of Purpose. + applicable law, Affirmer hereby overtly, fully, permanently, irrevocably and + unconditionally waives, abandons, and surrenders all of Affirmer’s Copyright + and Related Rights and associated claims and causes of action, whether now + known or unknown (including existing as well as future claims and causes of + action), in the Work (i) in all territories worldwide, (ii) for the maximum + duration provided by applicable law or treaty (including future time + extensions), (iii) in any current or future medium and for any number of + copies, and (iv) for any purpose whatsoever, including without limitation + commercial, advertising or promotional purposes (the “Waiver”). Affirmer + makes the Waiver for the benefit of each member of the public at large and + to the detriment of Affirmer’s heirs and successors, fully intending that + such Waiver shall not be subject to revocation, rescission, cancellation, + termination, or any other legal or equitable action to disrupt the quiet + enjoyment of the Work by the public as contemplated by Affirmer’s express + Statement of Purpose. 3. Public License Fallback. Should any part of the Waiver for any reason be -judged legally invalid or ineffective under applicable law, then the Waiver -shall be preserved to the maximum extent permitted taking into account -Affirmer’s express Statement of Purpose. In addition, to the extent the Waiver -is so judged Affirmer hereby grants to each affected person a royalty-free, non -transferable, non sublicensable, non exclusive, irrevocable and unconditional -license to exercise Affirmer’s Copyright and Related Rights in the Work (i) in -all territories worldwide, (ii) for the maximum duration provided by applicable -law or treaty (including future time extensions), (iii) in any current or -future medium and for any number of copies, and (iv) for any purpose -whatsoever, including without limitation commercial, advertising or promotional -purposes (the “License”). The License shall be deemed effective as of the date -CC0 was applied by Affirmer to the Work. Should any part of the License for any -reason be judged legally invalid or ineffective under applicable law, such -partial invalidity or ineffectiveness shall not invalidate the remainder of the -License, and in such case Affirmer hereby affirms that he or she will not (i) -exercise any of his or her remaining Copyright and Related Rights in the Work -or (ii) assert any associated claims and causes of action with respect to the -Work, in either case contrary to Affirmer’s express Statement of Purpose. + judged legally invalid or ineffective under applicable law, then the Waiver + shall be preserved to the maximum extent permitted taking into account + Affirmer’s express Statement of Purpose. In addition, to the extent the + Waiver is so judged Affirmer hereby grants to each affected person a + royalty-free, non transferable, non sublicensable, non exclusive, + irrevocable and unconditional license to exercise Affirmer’s Copyright and + Related Rights in the Work (i) in all territories worldwide, (ii) for the + maximum duration provided by applicable law or treaty (including future time + extensions), (iii) in any current or future medium and for any number of + copies, and (iv) for any purpose whatsoever, including without limitation + commercial, advertising or promotional purposes (the “License”). The License + shall be deemed effective as of the date CC0 was applied by Affirmer to the + Work. Should any part of the License for any reason be judged legally + invalid or ineffective under applicable law, such partial invalidity or + ineffectiveness shall not invalidate the remainder of the License, and in + such case Affirmer hereby affirms that he or she will not (i) exercise any + of his or her remaining Copyright and Related Rights in the Work or (ii) + assert any associated claims and causes of action with respect to the Work, + in either case contrary to Affirmer’s express Statement of Purpose. 4. Limitations and Disclaimers. - 1. No trademark or patent rights held by Affirmer are waived, abandoned, - surrendered, licensed or otherwise affected by this document. - 2. Affirmer offers the Work as-is and makes no representations or - warranties of any kind concerning the Work, express, implied, statutory - or otherwise, including without limitation warranties of title, - merchantability, fitness for a particular purpose, non infringement, or - the absence of latent or other defects, accuracy, or the present or - absence of errors, whether or not discoverable, all to the greatest - extent permissible under applicable law. - 3. Affirmer disclaims responsibility for clearing rights of other persons - that may apply to the Work or any use thereof, including without - limitation any person’s Copyright and Related Rights in the Work. - Further, Affirmer disclaims responsibility for obtaining any necessary - consents, permissions or other rights required for any use of the Work. - 4. Affirmer understands and acknowledges that Creative Commons is not a - party to this document and has no duty or obligation with respect to - this CC0 or use of the Work. + 1. No trademark or patent rights held by Affirmer are waived, abandoned, + surrendered, licensed or otherwise affected by this document. + 2. Affirmer offers the Work as-is and makes no representations or warranties + of any kind concerning the Work, express, implied, statutory or + otherwise, including without limitation warranties of title, + merchantability, fitness for a particular purpose, non infringement, or + the absence of latent or other defects, accuracy, or the present or + absence of errors, whether or not discoverable, all to the greatest + extent permissible under applicable law. + 3. Affirmer disclaims responsibility for clearing rights of other persons + that may apply to the Work or any use thereof, including without + limitation any person’s Copyright and Related Rights in the Work. + Further, Affirmer disclaims responsibility for obtaining any necessary + consents, permissions or other rights required for any use of the Work. + 4. Affirmer understands and acknowledges that Creative Commons is not a + party to this document and has no duty or obligation with respect to this + CC0 or use of the Work. For more information, please see http://creativecommons.org/publicdomain/zero/1.0/. diff --git a/README.md b/README.md index 5c7103af38..f2c25f86aa 100644 --- a/README.md +++ b/README.md @@ -1,25 +1,23 @@ -# PostCSS Normalize [PostCSS Logo][postcss] +# PostCSS Normalize [PostCSS][postcss] [![NPM Version][npm-img]][npm-url] [![Build Status][cli-img]][cli-url] -[![Windows Build Status][win-img]][win-url] -[![Gitter Chat][git-img]][git-url] +[![Support Chat][git-img]][git-url] -[PostCSS Normalize] lets you use the parts of [normalize.css] you need, based -on your project’s [browserlist]. +[PostCSS Normalize] lets you use the parts of [normalize.css] you need from +your [browserslist]. -Use `@import-normalize` to determine where [normalize.css] rules will be -included. Duplicate `@import-normalize` rules will be removed. See all the [Options] for more information. +Use `@import-normalize` to determine where [normalize.css] rules should be +included. Duplicate `@import-normalize` rules will be removed. See all the +[Options] for more information. ```css @import-normalize; ``` -Results: +Results when [browserslist] is `last 3 versions`: ```css -/* { "browserslist": ["last 3 versions"] } */ - /** * Add the correct display in IE 9-. */ @@ -38,9 +36,9 @@ img { } ``` -```css -/* { "browserlist": ["last 2 versions"] } */ +Results when [browserslist] is `last 2 versions`: +```css /** * Remove the border on images inside links in IE 10-. */ @@ -58,13 +56,13 @@ img { ## Usage -Add [PostCSS Normalize] to your build tool: +Add [PostCSS Normalize] to your project: ```bash npm install postcss-normalize --save-dev ``` -Add a [browserlist] entry in your package.json: +Add a [browserslist] entry in `package.json`: ```json { @@ -72,80 +70,29 @@ Add a [browserlist] entry in your package.json: } ``` -#### Node - Use [PostCSS Normalize] to process your CSS: ```js -require('postcss-normalize').process(YOUR_CSS, { /* options */ }); -``` +import postcssNormalize from 'postcss-normalize'; -#### PostCSS - -Add [PostCSS] to your build tool: - -```bash -npm install postcss --save-dev +postcssNormalize.process(YOUR_CSS /*, processOptions, pluginOptions */); ``` -Use [PostCSS Normalize] as a plugin: +Or use it as a [PostCSS] plugin: ```js -postcss([ - require('postcss-normalize')({ /* options */ }) -]).process(YOUR_CSS, /* options */); -``` - -#### Gulp - -Add [Gulp PostCSS] to your build tool: - -```bash -npm install gulp-postcss --save-dev -``` - -Use [PostCSS Normalize] in your Gulpfile: - -```js -var postcss = require('gulp-postcss'); - -gulp.task('css', function () { - return gulp.src('./src/*.css').pipe( - postcss([ - require('postcss-normalize')({ /* options */ }) - ]) - ).pipe( - gulp.dest('.') - ); -}); -``` - -#### Grunt - -Add [Grunt PostCSS] to your build tool: +import postcss from 'postcss'; +import postcssNormalize from 'postcss-normalize'; -```bash -npm install grunt-postcss --save-dev +postcss([ + postcssNormalize(/* pluginOptions */) +]).process(YOUR_CSS /*, processOptions */); ``` -Use [PostCSS Normalize] in your Gruntfile: +[PostCSS Normalize] runs in all Node environments, with special instructions for: -```js -grunt.loadNpmTasks('grunt-postcss'); - -grunt.initConfig({ - postcss: { - options: { - use: [ - require('postcss-normalize')({ /* options */ }) - ] - }, - dist: { - src: '*.css' - } - } -}); -``` +| [Node](INSTALL.md#node) | [Webpack](INSTALL.md#webpack) | [Create React App](INSTALL.md#create-react-app) | [Gulp](INSTALL.md#gulp) | [Grunt](INSTALL.md#grunt) | +| --- | --- | --- | --- | --- | ## Options @@ -155,18 +102,18 @@ Allows you to insert multiple, duplicate insertions of [normalize.css] rules. The default is `false`. ```js -require('postcss-normalize')({ +postcssNormalize({ allowDuplicates: true }); ``` ### browsers -Allows you to override of the project’s [browserlist] for [PostCSS Normalize]. +Allows you to override of the project’s [browserslist] for [PostCSS Normalize]. The default is `false`. ```js -require('postcss-normalize')({ +postcssNormalize({ browsers: 'last 2 versions' }); ``` @@ -177,25 +124,20 @@ Allows you to force an insertion of [normalize.css] rules at the beginning of the CSS file if no insertion point is specified. The default is `false`. ```js -require('postcss-normalize')({ +postcssNormalize({ forceImport: true }); ``` -[npm-url]: https://www.npmjs.com/package/postcss-normalize -[npm-img]: https://img.shields.io/npm/v/postcss-normalize.svg -[cli-url]: https://travis-ci.org/jonathantneal/postcss-normalize [cli-img]: https://img.shields.io/travis/jonathantneal/postcss-normalize.svg -[win-url]: https://ci.appveyor.com/project/jonathantneal/postcss-normalize -[win-img]: https://img.shields.io/appveyor/ci/jonathantneal/postcss-normalize.svg +[cli-url]: https://travis-ci.org/jonathantneal/postcss-normalize +[git-img]: https://img.shields.io/badge/support-chat-blue.svg [git-url]: https://gitter.im/postcss/postcss -[git-img]: https://img.shields.io/badge/chat-gitter-blue.svg - -[PostCSS Normalize]: https://github.com/jonathantneal/postcss-normalize -[PostCSS]: https://github.com/postcss/postcss -[Gulp PostCSS]: https://github.com/postcss/gulp-postcss -[Grunt PostCSS]: https://github.com/nDmitry/grunt-postcss +[npm-img]: https://img.shields.io/npm/v/postcss-normalize.svg +[npm-url]: https://www.npmjs.com/package/postcss-normalize -[browserlist]: http://browserl.ist/ +[browserslist]: http://browserl.ist/ [normalize.css]: https://github.com/jonathantneal/normalize.css [Options]: #Options +[PostCSS]: https://github.com/postcss/postcss +[PostCSS Normalize]: https://github.com/jonathantneal/postcss-normalize diff --git a/lib/normalize.json b/lib/normalize.json new file mode 100644 index 0000000000..3f9ab9f555 --- /dev/null +++ b/lib/normalize.json @@ -0,0 +1 @@ +{"browserList":[["> 0%"],["ie > 0"],["ios > 0"],["ie <= 8"],["chrome > 0","ff > 0","safari > 0"],["chrome > 0","ff > 0","safari > 0"],["ie <= 8"],["ie <= 8"],["ff > 0"],["ff > 0"],["edge > 0","ie > 0"],["ie > 0"],["> 0%"],["> 0%"],["ie <= 10"],["ios > 0","safari > 0"],["ff <= 39"],["chrome <= 58","edge > 0","ie > 0","opera > 0","safari > 0"],["chrome <= 58","edge > 0","ie > 0","opera > 0","safari > 0"],["safari <= 6"],["chrome > 0","edge > 0","safari > 0"],["> 0%"],["> 0%"],["android <= 4.3"],["ie <= 8"],["ie <= 8"],["> 0%"],["ie <= 9"],["ios <= 7"],["ios <= 7"],["ie <= 10"],["ie > 0"],["ff > 0","safari > 0"],["ie > 0"],["edge > 0","ff > 0","ie > 0"],["ios > 0","safari > 0"],["android <= 4"],["ff > 0"],["ff > 0"],["ff > 0"],["ff > 0"],["edge > 0","ie > 0"],["edge > 0","ie > 0"],["ie > 0"],["edge > 0","ie > 0"],["edge > 0","ie > 0"],["> 0%"],["edge > 0","ie > 0"],["edge > 0","ie > 0"],["chrome > 0","ff > 0","opera > 0"],["firefox > 0"],["ie > 0"],["ie <= 10"],["ie <= 10"],["chrome > 0"],["chrome > 0","safari > 0"],["safari > 0"],["chrome > 0","safari > 0"],["ios > 0","safari > 0"],["safari > 0"],["edge > 0","ff <= 48","ie > 0"],["> 0%"],["ie <= 9"],["ie > 0"],["ie <= 10"]],"css":"/*! normalize.css v7.0.0 | MIT License | github.com/jonathantneal/normalize.css */\n\n/* Document\n ========================================================================== */\n\n/**\n * 1. Correct the line height in all browsers.\n * 2. Prevent adjustments of font size after orientation changes in\n * IE on Windows Phone and in iOS.\n */\n\nhtml {\n line-height: 1.15; /* 1 */\n -ms-text-size-adjust: 100%; /* 2 */\n -webkit-text-size-adjust: 100%; /* 2 */\n}\n\n/* Sections\n ========================================================================== */\n\n/**\n * Add the correct display in IE 8-.\n */\n\narticle,\naside,\nfooter,\nheader,\nnav,\nsection {\n display: block;\n}\n\n/**\n * Correct the font size and margin on `h1` elements within `section` and\n * `article` contexts in Chrome, Firefox, and Safari.\n */\n\nh1 {\n font-size: 2em;\n margin: 0.67em 0;\n}\n\n/* Grouping content\n ========================================================================== */\n\n/**\n * Add the correct display in IE 8-.\n */\n\nfigcaption,\nfigure {\n display: block;\n}\n\n/**\n * Add the correct margin in IE 8-.\n */\n\nfigure {\n margin: 1em 40px;\n}\n\n/**\n * 1. Add the correct box sizing in Firefox.\n * 2. Show the overflow in Edge and IE.\n */\n\nhr {\n box-sizing: content-box; /* 1 */\n height: 0; /* 1 */\n overflow: visible; /* 2 */\n}\n\n/**\n * Add the correct display in IE.\n */\n\nmain {\n display: block;\n}\n\n/**\n * 1. Correct the inheritance and scaling of font size in all browsers.\n * 2. Correct the odd `em` font sizing in all browsers.\n */\n\npre {\n font-family: monospace, monospace; /* 1 */\n font-size: 1em; /* 2 */\n}\n\n/* Text-level semantics\n ========================================================================== */\n\n/**\n * 1. Remove the gray background on active links in IE 10.\n * 2. Remove gaps in links underline in iOS 8+ and Safari 8+.\n */\n\na {\n background-color: transparent; /* 1 */\n -webkit-text-decoration-skip: objects; /* 2 */\n}\n\n/**\n * 1. Remove the bottom border in Firefox 39-.\n * 2. Add the correct text decoration in Chrome 57-, Edge, IE, Opera,\n and Safari.\n */\n\nabbr[title] {\n border-bottom: none; /* 1 */\n text-decoration: underline; /* 2 */\n text-decoration: underline dotted; /* 2 */\n}\n\n/**\n * Prevent the duplicate application of `bolder` by the next rule in Safari 6.\n */\n\nb,\nstrong {\n font-weight: inherit;\n}\n\n/**\n * Add the correct font weight in Chrome, Edge, and Safari.\n */\n\nb,\nstrong {\n font-weight: bolder;\n}\n\n/**\n * 1. Correct the inheritance and scaling of font size in all browsers.\n * 2. Correct the odd `em` font sizing in all browsers.\n */\n\ncode,\nkbd,\nsamp {\n font-family: monospace, monospace; /* 1 */\n font-size: 1em; /* 2 */\n}\n\n/**\n * Add the correct font style in Android 4.3-.\n */\n\ndfn {\n font-style: italic;\n}\n\n/**\n * Add the correct background and color in IE 8-.\n */\n\nmark {\n background-color: #ff0;\n color: #000;\n}\n\n/**\n * Add the correct font size in all browsers.\n */\n\nsmall {\n font-size: 80%;\n}\n\n/* Embedded content\n ========================================================================== */\n\n/**\n * Add the correct display in IE 9-.\n */\n\naudio,\nvideo {\n display: inline-block;\n}\n\n/**\n * Add the correct display in iOS 4-7.\n */\n\naudio:not([controls]) {\n display: none;\n height: 0;\n}\n\n/**\n * Remove the border on images inside links in IE 10-.\n */\n\nimg {\n border-style: none;\n}\n\n/**\n * Hide the overflow in IE.\n */\n\nsvg:not(:root) {\n overflow: hidden;\n}\n\n/* Forms\n ========================================================================== */\n\n/**\n * Remove the margin in Firefox and Safari.\n */\n\nbutton,\ninput,\noptgroup,\nselect,\ntextarea {\n margin: 0;\n}\n\n/**\n * 1. Show the overflow in IE.\n * 2. Remove the inheritance of text transform in Edge, Firefox, and IE.\n */\n\nbutton {\n overflow: visible; /* 1 */\n text-transform: none; /* 2 */\n}\n\n/**\n * Correct the inability to style clickable types in iOS and Safari.\n */\n\nbutton,\n[type=\"button\"],\n[type=\"reset\"],\n[type=\"submit\"] {\n -webkit-appearance: button;\n}\n\n/**\n * Prevent a WebKit bug where (2) destroys native `audio` and `video` controls\n * in Android 4.\n */\n\nhtml [type=\"button\"] {\n -webkit-appearance: button;\n}\n\n/**\n * Remove the inner border and padding in Firefox.\n */\n\nbutton::-moz-focus-inner,\n[type=\"button\"]::-moz-focus-inner,\n[type=\"reset\"]::-moz-focus-inner,\n[type=\"submit\"]::-moz-focus-inner {\n border-style: none;\n padding: 0;\n}\n\n/**\n * Restore the focus styles unset by the previous rule.\n */\n\nbutton:-moz-focusring,\n[type=\"button\"]:-moz-focusring,\n[type=\"reset\"]:-moz-focusring,\n[type=\"submit\"]:-moz-focusring {\n outline: 1px dotted ButtonText;\n}\n\n/**\n * Correct the padding in Firefox.\n */\n\nfieldset {\n padding: 0.35em 0.75em 0.625em;\n}\n\n/**\n * Show the overflow in Edge and IE.\n */\n\ninput {\n overflow: visible;\n}\n\n/**\n * 1. Correct the text wrapping in Edge and IE.\n * 2. Correct the color inheritance from `fieldset` elements in IE.\n * 3. Remove the padding so developers are not caught out when they zero out\n * `fieldset` elements in all browsers.\n */\n\nlegend {\n box-sizing: border-box; /* 1 */\n color: inherit; /* 2 */\n display: table; /* 1 */\n max-width: 100%; /* 1 */\n padding: 0; /* 3 */\n white-space: normal; /* 1 */\n}\n\n/**\n * 1. Add the correct display in Edge and IE.\n * 2. Add the correct vertical alignment in Chrome, Firefox, and Opera.\n */\n\nprogress {\n display: inline-block; /* 1 */\n vertical-align: baseline; /* 2 */\n}\n\n/**\n * Remove the inheritance of text transform in Firefox.\n */\n\nselect {\n text-transform: none;\n}\n\n/**\n * Remove the default vertical scrollbar in IE.\n */\n\ntextarea {\n overflow: auto;\n}\n\n/**\n * 1. Add the correct box sizing in IE 10-.\n * 2. Remove the padding in IE 10-.\n */\n\n[type=\"checkbox\"],\n[type=\"radio\"] {\n box-sizing: border-box; /* 1 */\n padding: 0; /* 2 */\n}\n\n/**\n * Correct the cursor style of increment and decrement buttons in Chrome.\n */\n\n[type=\"number\"]::-webkit-inner-spin-button,\n[type=\"number\"]::-webkit-outer-spin-button {\n height: auto;\n}\n\n/**\n * 1. Correct the odd appearance in Chrome and Safari.\n * 2. Correct the outline style in Safari.\n */\n\n[type=\"search\"] {\n -webkit-appearance: textfield; /* 1 */\n outline-offset: -2px; /* 2 */\n}\n\n/**\n * Remove the inner padding and cancel buttons in Chrome and Safari on macOS.\n */\n\n[type=\"search\"]::-webkit-search-cancel-button,\n[type=\"search\"]::-webkit-search-decoration {\n -webkit-appearance: none;\n}\n\n/**\n * 1. Correct the inability to style clickable types in iOS and Safari.\n * 2. Change font properties to `inherit` in Safari.\n */\n\n::-webkit-file-upload-button {\n -webkit-appearance: button; /* 1 */\n font: inherit; /* 2 */\n}\n\n/* Interactive\n ========================================================================== */\n\n/*\n * Add the correct display in Edge, Firefox 48-, and IE.\n */\n\ndetails {\n display: block;\n}\n\n/*\n * Add the correct display in all browsers.\n */\n\nsummary {\n display: list-item;\n}\n\n/* Scripting\n ========================================================================== */\n\n/**\n * Add the correct display in IE 9-.\n */\n\ncanvas {\n display: inline-block;\n}\n\n/**\n * Add the correct display in IE.\n */\n\ntemplate {\n display: none;\n}\n\n/* Hidden\n ========================================================================== */\n\n/**\n * Add the correct display in IE 10-.\n */\n\n[hidden] {\n display: none;\n}\n"} \ No newline at end of file diff --git a/package-lock.json b/package-lock.json deleted file mode 100644 index a4de6885d3..0000000000 --- a/package-lock.json +++ /dev/null @@ -1,772 +0,0 @@ -{ - "name": "postcss-normalize", - "version": "4.0.0", - "lockfileVersion": 1, - "dependencies": { - "acorn": { - "version": "https://registry.npmjs.org/acorn/-/acorn-5.0.3.tgz", - "integrity": "sha1-xGDfCEkUY/AozLguqzcwvwEIez0=", - "dev": true - }, - "acorn-jsx": { - "version": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-3.0.1.tgz", - "integrity": "sha1-r9+UiPsezvyDSPb7IvRk4ypYs2s=", - "dev": true, - "dependencies": { - "acorn": { - "version": "https://registry.npmjs.org/acorn/-/acorn-3.3.0.tgz", - "integrity": "sha1-ReN/s56No/JbruP/U2niu18iAXo=", - "dev": true - } - } - }, - "ajv": { - "version": "https://registry.npmjs.org/ajv/-/ajv-4.11.8.tgz", - "integrity": "sha1-gv+wKynmYq5TvcIK8VlHcGc5xTY=", - "dev": true - }, - "ajv-keywords": { - "version": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-1.5.1.tgz", - "integrity": "sha1-MU3QpLM2j609/NxU7eYXG4htrzw=", - "dev": true - }, - "ansi-regex": { - "version": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=" - }, - "ansi-styles": { - "version": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", - "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=" - }, - "argparse": { - "version": "https://registry.npmjs.org/argparse/-/argparse-1.0.9.tgz", - "integrity": "sha1-c9g7wmP4bpf4zE9rrhsOkKfSLIY=", - "dev": true - }, - "array-union": { - "version": "https://registry.npmjs.org/array-union/-/array-union-1.0.2.tgz", - "integrity": "sha1-mjRBDk9OPaI96jdb5b5w8kd47Dk=", - "dev": true - }, - "array-uniq": { - "version": "https://registry.npmjs.org/array-uniq/-/array-uniq-1.0.3.tgz", - "integrity": "sha1-r2rId6Jcx/dOBYiUdThY39sk/bY=", - "dev": true - }, - "arrify": { - "version": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", - "integrity": "sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=", - "dev": true - }, - "babel-code-frame": { - "version": "https://registry.npmjs.org/babel-code-frame/-/babel-code-frame-6.22.0.tgz", - "integrity": "sha1-AnYgvuVnqIwyVhV05/0IAdMxGOQ=", - "dev": true - }, - "balanced-match": { - "version": "https://registry.npmjs.org/balanced-match/-/balanced-match-0.4.2.tgz", - "integrity": "sha1-yz8+PHMtwPAe5wtAPzAuYddwmDg=", - "dev": true - }, - "brace-expansion": { - "version": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.7.tgz", - "integrity": "sha1-Pv/DxQ4ABTH7cg6v+A8K6O8jz1k=", - "dev": true - }, - "browserslist": { - "version": "2.1.5", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-2.1.5.tgz", - "integrity": "sha1-6IJVDfPRzW1IHBo+ADjyuvE6RxE=", - "dependencies": { - "caniuse-lite": { - "version": "1.0.30000692", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30000692.tgz", - "integrity": "sha1-NGAP1xUjUthaR/RmKjtRsC2LZG8=" - }, - "electron-to-chromium": { - "version": "1.3.14", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.14.tgz", - "integrity": "sha1-ZK8Pnv08PGrNV9cfg7Scp+6cS0M=" - } - } - }, - "buffer-shims": { - "version": "https://registry.npmjs.org/buffer-shims/-/buffer-shims-1.0.0.tgz", - "integrity": "sha1-mXjOMXOIxkmth5MCjDR37wRKi1E=", - "dev": true - }, - "caller-path": { - "version": "https://registry.npmjs.org/caller-path/-/caller-path-0.1.0.tgz", - "integrity": "sha1-lAhe9jWB7NPaqSREqP6U6CV3dR8=", - "dev": true - }, - "callsites": { - "version": "https://registry.npmjs.org/callsites/-/callsites-0.2.0.tgz", - "integrity": "sha1-r6uWJikQp/M8GaV3WCXGnzTjUMo=", - "dev": true - }, - "chalk": { - "version": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", - "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", - "dependencies": { - "supports-color": { - "version": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", - "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=" - } - } - }, - "circular-json": { - "version": "https://registry.npmjs.org/circular-json/-/circular-json-0.3.1.tgz", - "integrity": "sha1-vos2rvzN6LPKeqLWr8B6NyQsDS0=", - "dev": true - }, - "cli-width": { - "version": "https://registry.npmjs.org/cli-width/-/cli-width-2.1.0.tgz", - "integrity": "sha1-sjTKIJsp72b8UY2bmNWEewDt8Ao=", - "dev": true - }, - "co": { - "version": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", - "integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ=", - "dev": true - }, - "concat-map": { - "version": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", - "dev": true - }, - "concat-stream": { - "version": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.0.tgz", - "integrity": "sha1-CqxmL9Ur54lk1VMvaUeE5wEQrPc=", - "dev": true - }, - "core-util-is": { - "version": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", - "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=", - "dev": true - }, - "cross-spawn": { - "version": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-5.1.0.tgz", - "integrity": "sha1-6L0O/uWPz/b4+UUQoKVUu/ojVEk=", - "dev": true - }, - "debug": { - "version": "https://registry.npmjs.org/debug/-/debug-2.6.8.tgz", - "integrity": "sha1-5zFTHKLt4n0YgiJCfaF4IdaP9Pw=", - "dev": true - }, - "deep-is": { - "version": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz", - "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=", - "dev": true - }, - "del": { - "version": "https://registry.npmjs.org/del/-/del-2.2.2.tgz", - "integrity": "sha1-wSyYHQZ4RshLyvhiz/kw2Qf/0ag=", - "dev": true - }, - "doctrine": { - "version": "https://registry.npmjs.org/doctrine/-/doctrine-2.0.0.tgz", - "integrity": "sha1-xz2NKQnSIpHhoAejlYBNqLZl/mM=", - "dev": true - }, - "escape-string-regexp": { - "version": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=" - }, - "eslint": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-4.0.0.tgz", - "integrity": "sha1-cnfAFDf99B3M0WjVqg5Jt1yh8mA=", - "dev": true, - "dependencies": { - "ansi-escapes": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-2.0.0.tgz", - "integrity": "sha1-W65SvkJIeN2Xg+iRDj/Cki6DyBs=", - "dev": true - }, - "cli-cursor": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-2.1.0.tgz", - "integrity": "sha1-s12sN2R5+sw+lHR9QdDQ9SOP/LU=", - "dev": true - }, - "figures": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/figures/-/figures-2.0.0.tgz", - "integrity": "sha1-OrGi0qYsi/tDGgyUy3l6L84nyWI=", - "dev": true - }, - "inquirer": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-3.1.1.tgz", - "integrity": "sha512-H50sHQwgvvaTBd3HpKMVtL/u6LoHDvYym51gd7bGQe/+9HkCE+J0/3N5FJLfd6O6oz44hHewC2Pc2LodzWVafQ==", - "dev": true - }, - "is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", - "dev": true - }, - "mute-stream": { - "version": "0.0.7", - "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.7.tgz", - "integrity": "sha1-MHXOk7whuPq0PhvE2n6BFe0ee6s=", - "dev": true - }, - "onetime": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-2.0.1.tgz", - "integrity": "sha1-BnQoIw/WdEOyeUsiu6UotoZ5YtQ=", - "dev": true - }, - "pluralize": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/pluralize/-/pluralize-4.0.0.tgz", - "integrity": "sha1-WbcIwcAZCi9pLxx2GMRGsFL9F2I=", - "dev": true - }, - "progress": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.0.tgz", - "integrity": "sha1-ihvjZr+Pwj2yvSPxDG/pILQ4nR8=", - "dev": true - }, - "restore-cursor": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-2.0.0.tgz", - "integrity": "sha1-n37ih/gv0ybU/RYpI9YhKe7g368=", - "dev": true - }, - "run-async": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.3.0.tgz", - "integrity": "sha1-A3GrSuC91yDUFm19/aZP96RFpsA=", - "dev": true - }, - "rx-lite": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/rx-lite/-/rx-lite-4.0.8.tgz", - "integrity": "sha1-Cx4Rr4vESDbwSmQH6S2kJGe3lEQ=", - "dev": true - }, - "string-width": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.0.0.tgz", - "integrity": "sha1-Y1xUNsxypuDDh87KJ41OLuxSaH4=", - "dev": true - }, - "table": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/table/-/table-4.0.1.tgz", - "integrity": "sha1-qBFsEz+sLGH0pCCrbN9cTWHw5DU=", - "dev": true - } - } - }, - "eslint-config-dev": { - "version": "https://registry.npmjs.org/eslint-config-dev/-/eslint-config-dev-2.0.0.tgz", - "integrity": "sha1-guXKMTRJr3sSu/1OlzPrKG8PQ7c=", - "dev": true - }, - "eslint-scope": { - "version": "3.7.1", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-3.7.1.tgz", - "integrity": "sha1-PWPD7f2gLgbgGkUq2IyqzHzctug=", - "dev": true - }, - "espree": { - "version": "https://registry.npmjs.org/espree/-/espree-3.4.3.tgz", - "integrity": "sha1-KRC1zNSc6JPC//+qtP2LOjG4I3Q=", - "dev": true - }, - "esprima": { - "version": "https://registry.npmjs.org/esprima/-/esprima-3.1.3.tgz", - "integrity": "sha1-/cpRzuYTOJXjyI1TXOSdv/YqRjM=", - "dev": true - }, - "esquery": { - "version": "https://registry.npmjs.org/esquery/-/esquery-1.0.0.tgz", - "integrity": "sha1-z7qLV9f7qT8XKYqKAGoEzaE9gPo=", - "dev": true - }, - "esrecurse": { - "version": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.1.0.tgz", - "integrity": "sha1-RxO2U2rffyrE8yfVWed1a/9kgiA=", - "dev": true, - "dependencies": { - "estraverse": { - "version": "https://registry.npmjs.org/estraverse/-/estraverse-4.1.1.tgz", - "integrity": "sha1-9srKcokzqFDvkGYdDheYK6RxEaI=", - "dev": true - } - } - }, - "estraverse": { - "version": "https://registry.npmjs.org/estraverse/-/estraverse-4.2.0.tgz", - "integrity": "sha1-De4/7TH81GlhjOc0IJn8GvoL2xM=", - "dev": true - }, - "esutils": { - "version": "https://registry.npmjs.org/esutils/-/esutils-2.0.2.tgz", - "integrity": "sha1-Cr9PHKpbyx96nYrMbepPqqBLrJs=", - "dev": true - }, - "external-editor": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-2.0.4.tgz", - "integrity": "sha1-HtkZnanL/i7y96MbL96LDRI2iXI=", - "dev": true - }, - "fast-levenshtein": { - "version": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", - "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", - "dev": true - }, - "file-entry-cache": { - "version": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-2.0.0.tgz", - "integrity": "sha1-w5KZDD5oR4PYOLjISkXYoEhFg2E=", - "dev": true - }, - "flat-cache": { - "version": "https://registry.npmjs.org/flat-cache/-/flat-cache-1.2.2.tgz", - "integrity": "sha1-+oZxTnLCHbiGAXYezy9VXRq8a5Y=", - "dev": true - }, - "fs.realpath": { - "version": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", - "dev": true - }, - "fse": { - "version": "https://registry.npmjs.org/fse/-/fse-3.0.0.tgz", - "integrity": "sha1-f65r9PWDb1gVcID4BjaO5it1hX8=", - "dev": true - }, - "generate-function": { - "version": "https://registry.npmjs.org/generate-function/-/generate-function-2.0.0.tgz", - "integrity": "sha1-aFj+fAlpt9TpCTM3ZHrHn2DfvnQ=", - "dev": true - }, - "generate-object-property": { - "version": "https://registry.npmjs.org/generate-object-property/-/generate-object-property-1.2.0.tgz", - "integrity": "sha1-nA4cQDCM6AT0eDYYuTf6iPmdUNA=", - "dev": true - }, - "glob": { - "version": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz", - "integrity": "sha1-wZyd+aAocC1nhhI4SmVSQExjbRU=", - "dev": true - }, - "globals": { - "version": "https://registry.npmjs.org/globals/-/globals-9.17.0.tgz", - "integrity": "sha1-DAymltm5u2lNLlRwvTd3fKrVAoY=", - "dev": true - }, - "globby": { - "version": "https://registry.npmjs.org/globby/-/globby-5.0.0.tgz", - "integrity": "sha1-69hGZ8oNuzMLmbz8aOrCvFQ3Dg0=", - "dev": true - }, - "graceful-fs": { - "version": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.11.tgz", - "integrity": "sha1-Dovf5NHduIVNZOBOp8AOKgJuVlg=", - "dev": true - }, - "has-ansi": { - "version": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", - "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=" - }, - "has-flag": { - "version": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz", - "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo=" - }, - "iconv-lite": { - "version": "0.4.18", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.18.tgz", - "integrity": "sha512-sr1ZQph3UwHTR0XftSbK85OvBbxe/abLGzEnPENCQwmHf7sck8Oyu4ob3LgBxWWxRoM+QszeUyl7jbqapu2TqA==", - "dev": true - }, - "ignore": { - "version": "https://registry.npmjs.org/ignore/-/ignore-3.3.3.tgz", - "integrity": "sha1-QyNS5XrM2HqzEQ6C0/6g5HgSFW0=", - "dev": true - }, - "imurmurhash": { - "version": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", - "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", - "dev": true - }, - "inflight": { - "version": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", - "dev": true - }, - "inherits": { - "version": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", - "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", - "dev": true - }, - "is-my-json-valid": { - "version": "https://registry.npmjs.org/is-my-json-valid/-/is-my-json-valid-2.16.0.tgz", - "integrity": "sha1-8Hndm/2uZe4gOKrorLyGqxCeNpM=", - "dev": true - }, - "is-path-cwd": { - "version": "https://registry.npmjs.org/is-path-cwd/-/is-path-cwd-1.0.0.tgz", - "integrity": "sha1-0iXsIxMuie3Tj9p2dHLmLmXxEG0=", - "dev": true - }, - "is-path-in-cwd": { - "version": "https://registry.npmjs.org/is-path-in-cwd/-/is-path-in-cwd-1.0.0.tgz", - "integrity": "sha1-ZHdYK4IU1gI0YJRWcAO+ip6sBNw=", - "dev": true - }, - "is-path-inside": { - "version": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-1.0.0.tgz", - "integrity": "sha1-/AbloWg/vaE95mev9xe7wQpI838=", - "dev": true - }, - "is-promise": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-2.1.0.tgz", - "integrity": "sha1-eaKp7OfwlugPNtKy87wWwf9L8/o=", - "dev": true - }, - "is-property": { - "version": "https://registry.npmjs.org/is-property/-/is-property-1.0.2.tgz", - "integrity": "sha1-V/4cTkhHTt1lsJkR8msc1Ald2oQ=", - "dev": true - }, - "is-resolvable": { - "version": "https://registry.npmjs.org/is-resolvable/-/is-resolvable-1.0.0.tgz", - "integrity": "sha1-jfV8YeouPFAUCNEA+wE8+NbgzGI=", - "dev": true - }, - "isarray": { - "version": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", - "dev": true - }, - "isexe": { - "version": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", - "dev": true - }, - "js-tokens": { - "version": "https://registry.npmjs.org/js-tokens/-/js-tokens-3.0.1.tgz", - "integrity": "sha1-COnxMkhKLEWjCQfp3E1VZ7fxFNc=", - "dev": true - }, - "js-yaml": { - "version": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.8.4.tgz", - "integrity": "sha1-UgtFZPhlc7qWZir4Woyvp7S1pvY=", - "dev": true - }, - "jschardet": { - "version": "1.4.2", - "resolved": "https://registry.npmjs.org/jschardet/-/jschardet-1.4.2.tgz", - "integrity": "sha1-KqEH8UKvQSHRRWWdRPUIMJYeaZo=", - "dev": true - }, - "json-stable-stringify": { - "version": "https://registry.npmjs.org/json-stable-stringify/-/json-stable-stringify-1.0.1.tgz", - "integrity": "sha1-mnWdOcXy/1A/1TAGRu1EX4jE+a8=", - "dev": true - }, - "jsonify": { - "version": "https://registry.npmjs.org/jsonify/-/jsonify-0.0.0.tgz", - "integrity": "sha1-LHS27kHZPKUbe1qu6PUDYx0lKnM=", - "dev": true - }, - "jsonpointer": { - "version": "https://registry.npmjs.org/jsonpointer/-/jsonpointer-4.0.1.tgz", - "integrity": "sha1-T9kss04OnbPInIYi7PUfm5eMbLk=", - "dev": true - }, - "levn": { - "version": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", - "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=", - "dev": true - }, - "lodash": { - "version": "https://registry.npmjs.org/lodash/-/lodash-4.17.4.tgz", - "integrity": "sha1-eCA6TRwyiuHYbcpkYONptX9AVa4=", - "dev": true - }, - "lru-cache": { - "version": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.0.2.tgz", - "integrity": "sha1-HRdnnAac2l0ECZGgnbwsDbN35V4=", - "dev": true - }, - "mimic-fn": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-1.1.0.tgz", - "integrity": "sha1-5md4PZLonb00KBi1IwudYqZyrRg=", - "dev": true - }, - "minimatch": { - "version": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", - "integrity": "sha1-UWbihkV/AzBgZL5Ul+jbsMPTIIM=", - "dev": true - }, - "minimist": { - "version": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", - "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=", - "dev": true - }, - "mkdirp": { - "version": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", - "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", - "dev": true - }, - "ms": { - "version": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", - "dev": true - }, - "natural-compare": { - "version": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", - "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=", - "dev": true - }, - "object-assign": { - "version": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", - "dev": true - }, - "once": { - "version": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", - "dev": true - }, - "optionator": { - "version": "https://registry.npmjs.org/optionator/-/optionator-0.8.2.tgz", - "integrity": "sha1-NkxeQJ0/TWMB1sC0wFu6UBgK62Q=", - "dev": true - }, - "os-shim": { - "version": "https://registry.npmjs.org/os-shim/-/os-shim-0.1.3.tgz", - "integrity": "sha1-a2LDeRz3kJ6jXtRuF2WLtBfLORc=", - "dev": true - }, - "os-tmpdir": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", - "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=", - "dev": true - }, - "path-is-absolute": { - "version": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", - "dev": true - }, - "path-is-inside": { - "version": "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz", - "integrity": "sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM=", - "dev": true - }, - "pify": { - "version": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", - "dev": true - }, - "pinkie": { - "version": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz", - "integrity": "sha1-clVrgM+g1IqXToDnckjoDtT3+HA=", - "dev": true - }, - "pinkie-promise": { - "version": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz", - "integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=", - "dev": true - }, - "postcss": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.2.tgz", - "integrity": "sha1-XE/qWJ8Kw7AMqnWxy8OihBlbfl0=" - }, - "postcss-tape": { - "version": "https://registry.npmjs.org/postcss-tape/-/postcss-tape-2.0.1.tgz", - "integrity": "sha1-PP4pUg4ZJ4E3zCvTXOeyvXq42jY=", - "dev": true - }, - "pre-commit": { - "version": "https://registry.npmjs.org/pre-commit/-/pre-commit-1.2.2.tgz", - "integrity": "sha1-287g7p3nI15X95xW186UZBpp7sY=", - "dev": true - }, - "prelude-ls": { - "version": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", - "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=", - "dev": true - }, - "process-nextick-args": { - "version": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-1.0.7.tgz", - "integrity": "sha1-FQ4gt1ZZCtP5EJPyWk8q2L/zC6M=", - "dev": true - }, - "pseudomap": { - "version": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", - "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=", - "dev": true - }, - "readable-stream": { - "version": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.2.9.tgz", - "integrity": "sha1-z3jsb0ptHrQ9JkiMrJfwQudLf8g=", - "dev": true - }, - "require-uncached": { - "version": "https://registry.npmjs.org/require-uncached/-/require-uncached-1.0.3.tgz", - "integrity": "sha1-Tg1W1slmL9MeQwEcS5WqSZVUIdM=", - "dev": true - }, - "resolve-from": { - "version": "https://registry.npmjs.org/resolve-from/-/resolve-from-1.0.1.tgz", - "integrity": "sha1-Jsv+k10a7uq7Kbw/5a6wHpPUQiY=", - "dev": true - }, - "rimraf": { - "version": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.1.tgz", - "integrity": "sha1-wjOOxkPfeht/5cVPqG9XQopV8z0=", - "dev": true - }, - "rx-lite": { - "version": "https://registry.npmjs.org/rx-lite/-/rx-lite-3.1.2.tgz", - "integrity": "sha1-Gc5QLKVyZl87ZHsQk5+X/RYV8QI=", - "dev": true - }, - "rx-lite-aggregates": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/rx-lite-aggregates/-/rx-lite-aggregates-4.0.8.tgz", - "integrity": "sha1-dTuHqJoRyVRnxKwWJsTvxOBcZ74=", - "dev": true - }, - "safe-buffer": { - "version": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.0.1.tgz", - "integrity": "sha1-0mPKVGls2KMGtcplUekt5XkY++c=", - "dev": true - }, - "shebang-command": { - "version": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", - "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=", - "dev": true - }, - "shebang-regex": { - "version": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", - "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=", - "dev": true - }, - "signal-exit": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz", - "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=", - "dev": true - }, - "slice-ansi": { - "version": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-0.0.4.tgz", - "integrity": "sha1-7b+JA/ZvfOL46v1s7tZeJkyDGzU=", - "dev": true - }, - "source-map": { - "version": "https://registry.npmjs.org/source-map/-/source-map-0.5.6.tgz", - "integrity": "sha1-dc449SvwczxafwwRjYEzSiu19BI=" - }, - "spawn-sync": { - "version": "https://registry.npmjs.org/spawn-sync/-/spawn-sync-1.0.15.tgz", - "integrity": "sha1-sAeZVX63+wyDdsKdROih6mfldHY=", - "dev": true - }, - "sprintf-js": { - "version": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", - "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", - "dev": true - }, - "string_decoder": { - "version": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.1.tgz", - "integrity": "sha1-YuIA8DmVWmgQ2N8KM//A8BNmLZg=", - "dev": true - }, - "strip-ansi": { - "version": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", - "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=" - }, - "strip-json-comments": { - "version": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", - "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=", - "dev": true - }, - "supports-color": { - "version": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz", - "integrity": "sha1-ZawFBLOVQXHYpklGsq48u4pfVPY=" - }, - "text-table": { - "version": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", - "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=", - "dev": true - }, - "through": { - "version": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", - "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=", - "dev": true - }, - "tmp": { - "version": "0.0.31", - "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.31.tgz", - "integrity": "sha1-jzirlDjhcxXl29izZX6L+yd65Kc=", - "dev": true - }, - "tryit": { - "version": "https://registry.npmjs.org/tryit/-/tryit-1.0.3.tgz", - "integrity": "sha1-OTvnMKlEb9Hq1tpZoBQwjzbCics=", - "dev": true - }, - "type-check": { - "version": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", - "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=", - "dev": true - }, - "typedarray": { - "version": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", - "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=", - "dev": true - }, - "util-deprecate": { - "version": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=", - "dev": true - }, - "which": { - "version": "https://registry.npmjs.org/which/-/which-1.2.14.tgz", - "integrity": "sha1-mofEN48D6CfOyvGs31bHNsAcFOU=", - "dev": true - }, - "wordwrap": { - "version": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", - "integrity": "sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus=", - "dev": true - }, - "wrappy": { - "version": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", - "dev": true - }, - "write": { - "version": "https://registry.npmjs.org/write/-/write-0.2.1.tgz", - "integrity": "sha1-X8A4KOJkzqP+kUVUdvejxWbLB1c=", - "dev": true - }, - "xtend": { - "version": "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz", - "integrity": "sha1-pcbVMr5lbiPbgg77lDofBJmNY68=", - "dev": true - }, - "yallist": { - "version": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", - "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=", - "dev": true - } - } -} diff --git a/package.json b/package.json index 820a605af6..75687ca812 100644 --- a/package.json +++ b/package.json @@ -1,54 +1,55 @@ { "name": "postcss-normalize", - "version": "4.0.0", - "description": "Use the parts of normalize.css you need from your browserlist", + "version": "5.0.0", + "description": "Use the parts of normalize.css you need from your browserslist", "author": "Jonathan Neal ", "license": "CC0-1.0", "repository": "jonathantneal/postcss-normalize", "homepage": "https://github.com/jonathantneal/postcss-normalize#readme", "bugs": "https://github.com/jonathantneal/postcss-normalize/issues", - "main": "index.js", + "main": "index.cjs.js", + "module": "index.es.js", "files": [ - "index.js", + "index.cjs.js", + "index.es.js", "lib/normalize.js", "lib/normalize.json" ], "scripts": { - "clean": "git clean -X -d -f", - "prepublish": "npm test", + "prepublishOnly": "npm test", + "pretest": "rollup -c .rollup.js --silent", "test": "npm run test:init && npm run test:js && npm run test:tape", "test:init": "node lib/normalize-init", - "test:js": "eslint *.js --cache --ignore-pattern .gitignore", + "test:js": "eslint *.js --cache --ignore-path .gitignore --quiet", "test:tape": "postcss-tape" }, "engines": { - "node": ">=4.0.0" + "node": ">=6.0.0" }, "dependencies": { - "browserslist": "^2.1.5", - "postcss": "^6.0.2" + "browserslist": "^3.2.8", + "postcss": "^6.0.22" }, "devDependencies": { - "eslint": "^4.0.0", - "eslint-config-dev": "2.0.0", - "fse": "^3.0.0", - "postcss-tape": "2.0.1", - "pre-commit": "^1.2.2" + "babel-core": "^6.26.3", + "babel-eslint": "^8.2.3", + "babel-preset-env": "^1.7.0", + "eslint": "^4.19.1", + "eslint-config-dev": "^2.0.0", + "fse": "^4.0.1", + "postcss-tape": "^2.2.0", + "pre-commit": "^1.2.2", + "rollup": "^0.60.0", + "rollup-plugin-babel": "^3.0.4" }, "eslintConfig": { - "extends": "dev" + "extends": "dev", + "parser": "babel-eslint" }, "keywords": [ "postcss", "css", "postcss-plugin", - "normalize.css", - "normalize", - "browsers", - "bugs", - "fixes", - "usability", - "browserslist", - "browserlist" + "normalize" ] } diff --git a/test/basic.expect.css b/test/basic.expect.css index 6ef7a7ce2b..7b123847fc 100644 --- a/test/basic.expect.css +++ b/test/basic.expect.css @@ -25,7 +25,6 @@ pre { } a { - background-color: transparent; -webkit-text-decoration-skip: objects; } @@ -50,10 +49,6 @@ small { font-size: 80%; } -img { - border-style: none; -} - svg:not(:root) { overflow: hidden; } @@ -123,12 +118,6 @@ textarea { overflow: auto; } -[type="checkbox"], -[type="radio"] { - box-sizing: border-box; - padding: 0; -} - [type="number"]::-webkit-inner-spin-button, [type="number"]::-webkit-outer-spin-button { height: auto; @@ -161,10 +150,6 @@ template { display: none; } -[hidden] { - display: none; -} - body { font-family: sans-serif; } diff --git a/test/insertion-after.expect.css b/test/insertion-after.expect.css index 8e1a6f289d..2a102e5ef0 100644 --- a/test/insertion-after.expect.css +++ b/test/insertion-after.expect.css @@ -29,7 +29,6 @@ pre { } a { - background-color: transparent; -webkit-text-decoration-skip: objects; } @@ -54,10 +53,6 @@ small { font-size: 80%; } -img { - border-style: none; -} - svg:not(:root) { overflow: hidden; } @@ -127,12 +122,6 @@ textarea { overflow: auto; } -[type="checkbox"], -[type="radio"] { - box-sizing: border-box; - padding: 0; -} - [type="number"]::-webkit-inner-spin-button, [type="number"]::-webkit-outer-spin-button { height: auto; @@ -164,7 +153,3 @@ summary { template { display: none; } - -[hidden] { - display: none; -} diff --git a/test/insertion-duplicate.expect.css b/test/insertion-duplicate.expect.css index 6ef7a7ce2b..7b123847fc 100644 --- a/test/insertion-duplicate.expect.css +++ b/test/insertion-duplicate.expect.css @@ -25,7 +25,6 @@ pre { } a { - background-color: transparent; -webkit-text-decoration-skip: objects; } @@ -50,10 +49,6 @@ small { font-size: 80%; } -img { - border-style: none; -} - svg:not(:root) { overflow: hidden; } @@ -123,12 +118,6 @@ textarea { overflow: auto; } -[type="checkbox"], -[type="radio"] { - box-sizing: border-box; - padding: 0; -} - [type="number"]::-webkit-inner-spin-button, [type="number"]::-webkit-outer-spin-button { height: auto; @@ -161,10 +150,6 @@ template { display: none; } -[hidden] { - display: none; -} - body { font-family: sans-serif; } diff --git a/test/option-force-import.expect.css b/test/option-force-import.expect.css index 4d3f333648..03c7093e75 100644 --- a/test/option-force-import.expect.css +++ b/test/option-force-import.expect.css @@ -20,7 +20,6 @@ pre { font-size: 1em; } a { - background-color: transparent; -webkit-text-decoration-skip: objects; } abbr[title] { @@ -40,9 +39,6 @@ samp { small { font-size: 80%; } -img { - border-style: none; -} svg:not(:root) { overflow: hidden; } @@ -100,11 +96,6 @@ select { textarea { overflow: auto; } -[type="checkbox"], -[type="radio"] { - box-sizing: border-box; - padding: 0; -} [type="number"]::-webkit-inner-spin-button, [type="number"]::-webkit-outer-spin-button { height: auto; @@ -130,9 +121,6 @@ summary { template { display: none; } -[hidden] { - display: none; -} body { font-family: sans-serif; } From 731eed040911b110152780dcdb2461cadfcb28f8 Mon Sep 17 00:00:00 2001 From: Jonathan Neal Date: Sat, 9 Jun 2018 17:12:38 -0400 Subject: [PATCH 638/795] Update dependencies --- package.json | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/package.json b/package.json index afd7ec1031..818b7c2fda 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "postcss-focus-within", "version": "2.0.0", - "description": "Ise the :focus-within pseudo-selector in CSS", + "description": "Use the :focus-within pseudo-selector in CSS", "author": "Jonathan Neal ", "license": "CC0-1.0", "repository": "jonathantneal/postcss-focus-within", @@ -24,18 +24,18 @@ "node": ">=4.0.0" }, "dependencies": { - "postcss": "^6.0.21" + "postcss": "^6.0.22" }, "devDependencies": { - "babel-core": "^6.26.0", - "babel-eslint": "^8.2.2", - "babel-preset-env": "^1.6.1", + "babel-core": "^6.26.3", + "babel-eslint": "^8.2.3", + "babel-preset-env": "^1.7.0", "eslint": "^4.19.1", "eslint-config-dev": "2.0.0", "postcss-tape": "2.2.0", "pre-commit": "^1.2.2", - "rollup": "^0.57.1", - "rollup-plugin-babel": "^3.0.3" + "rollup": "^0.60.1", + "rollup-plugin-babel": "^3.0.4" }, "eslintConfig": { "extends": "dev", From d4691ebcd74172f158f5d066c139aba5448d4d41 Mon Sep 17 00:00:00 2001 From: Jonathan Neal Date: Sat, 9 Jun 2018 19:01:33 -0400 Subject: [PATCH 639/795] 6.0.0 --- .appveyor.yml | 2 +- .rollup.js | 5 +- .travis.yml | 2 +- CHANGELOG.md | 5 ++ CONTRIBUTING.md | 32 ++++--- INSTALL.md | 149 +++++++++++++++++++++++++++++++ README.md | 128 ++++---------------------- index.js | 6 +- lib/atrule-within-atrule.js | 23 +++++ lib/atrule-within-rule.js | 28 ++++++ lib/clean-node.js | 10 --- lib/cleanup-parent.js | 5 ++ lib/get-closest-rule.js | 10 --- lib/merge-params.js | 13 +-- lib/merge-selectors.js | 23 +++-- lib/nest-rule-within-rule.js | 32 +++++++ lib/rule-within-rule.js | 19 ++++ lib/shift-nodes-before-parent.js | 16 ++++ lib/transform-after-nodes.js | 21 ----- lib/transform-before-nodes.js | 22 ----- lib/transform-bubbling-atrule.js | 57 ------------ lib/transform-nesting-atrule.js | 66 -------------- lib/transform-nesting-rule.js | 28 ------ lib/transform.js | 17 ---- lib/valid-atrules.js | 1 + lib/valid-selector.js | 4 + lib/walk.js | 24 +++++ package.json | 13 +-- test/at-rule.expect.css | 16 ++-- test/basic.css | 53 ++++++++--- test/basic.expect.css | 73 ++++++++++----- test/direct.expect.css | 18 ++-- test/empty.expect.css | 21 ++--- test/media.expect.css | 66 +++++++------- 34 files changed, 525 insertions(+), 483 deletions(-) create mode 100644 INSTALL.md create mode 100644 lib/atrule-within-atrule.js create mode 100644 lib/atrule-within-rule.js delete mode 100644 lib/clean-node.js create mode 100644 lib/cleanup-parent.js delete mode 100644 lib/get-closest-rule.js create mode 100644 lib/nest-rule-within-rule.js create mode 100644 lib/rule-within-rule.js create mode 100644 lib/shift-nodes-before-parent.js delete mode 100644 lib/transform-after-nodes.js delete mode 100644 lib/transform-before-nodes.js delete mode 100644 lib/transform-bubbling-atrule.js delete mode 100644 lib/transform-nesting-atrule.js delete mode 100644 lib/transform-nesting-rule.js delete mode 100644 lib/transform.js create mode 100644 lib/valid-atrules.js create mode 100644 lib/valid-selector.js create mode 100644 lib/walk.js diff --git a/.appveyor.yml b/.appveyor.yml index acbf8a5eeb..73f0d8fa3f 100644 --- a/.appveyor.yml +++ b/.appveyor.yml @@ -2,7 +2,7 @@ environment: matrix: - - nodejs_version: 4 + - nodejs_version: 6 version: "{build}" build: off diff --git a/.rollup.js b/.rollup.js index 0436758216..1d581cace5 100644 --- a/.rollup.js +++ b/.rollup.js @@ -8,8 +8,11 @@ export default { ], plugins: [ babel({ + plugins: [ + 'array-includes' + ], presets: [ - ['env', { modules: false, targets: { node: 4 } }] + ['env', { modules: false, targets: { node: 6 } }] ] }) ] diff --git a/.travis.yml b/.travis.yml index c56466446c..e1f11a52e6 100644 --- a/.travis.yml +++ b/.travis.yml @@ -3,7 +3,7 @@ language: node_js node_js: - - 4 + - 6 install: - npm install --ignore-scripts diff --git a/CHANGELOG.md b/CHANGELOG.md index 15d3dd954e..5a125aa8a5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,10 @@ # Changes to PostCSS Nesting +### 6.0.0 (June 9, 2018) + +- Deprecated: Nested at-rules like `@media` will no longer work in 7.0.0 +- Refactored code to improve efficiency + ### 5.0.0 (March 24, 2018) - Refactored code to use Imports babel-transformed for Node v4 compatibility diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index e1b6dcac30..3d23f375b1 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -14,54 +14,52 @@ Remember, a bug is a _demonstrable problem_ caused by _our_ code. ## Submitting Pull Requests -Pull requests are the greatest contributions, so be sure they are focused in -scope, and do avoid unrelated commits. +Pull requests are the greatest contributions, so be sure they are focused in +scope and avoid unrelated commits. -1. To begin, [fork this project], clone your fork, and add our upstream. +1. To begin; [fork this project], clone your fork, and add our upstream. ```bash # Clone your fork of the repo into the current directory - git clone https://github.com//postcss-nesting + git clone git@github.com:YOUR_USER/postcss-nesting.git # Navigate to the newly cloned directory cd postcss-nesting # Assign the original repo to a remote called "upstream" - git remote add upstream https://github.com/jonathantneal/postcss-nesting + git remote add upstream git@github.com:jonathantneal/postcss-nesting.git - # Install the tools necessary for development + # Install the tools necessary for testing npm install ``` 2. Create a branch for your feature or fix: ```bash - # Move into a new branch for a feature + # Move into a new branch for your feature git checkout -b feature/thing ``` ```bash - # Move into a new branch for a fix + # Move into a new branch for your fix git checkout -b fix/something ``` -3. Be sure your code follows our practices. +3. If your code follows our practices, then push your feature branch: ```bash # Test current code - npm run test + npm test ``` - -4. Push your branch up to your fork: ```bash - # Push a feature branch + # Push the branch for your new feature git push origin feature/thing ``` ```bash - # Push a fix branch - git push origin fix/something + # Or, push the branch for your update + git push origin update/something ``` -5. Now [open a pull request] with a clear title and description. +That’s it! Now [open a pull request] with a clear title and description. [already been reported]: issues [fork this project]: fork -[live example]: http://codepen.io/pen +[live example]: https://codepen.io/pen [open a pull request]: https://help.github.com/articles/using-pull-requests/ [reduced test case]: https://css-tricks.com/reduced-test-cases/ diff --git a/INSTALL.md b/INSTALL.md new file mode 100644 index 0000000000..45ae189c2c --- /dev/null +++ b/INSTALL.md @@ -0,0 +1,149 @@ +# Installing PostCSS Nesting + +[PostCSS Nesting] runs in all Node environments, with special instructions for: + +| [Node](#node) | [Webpack](#webpack) | [Create React App](#create-react-app) | [Gulp](#gulp) | [Grunt](#grunt) | +| --- | --- | --- | --- | --- | + +## Node + +Add [PostCSS Nesting] to your project: + +```bash +npm install postcss-nesting --save-dev +``` + +Use [PostCSS Nesting] to process your CSS: + +```js +import postcssNesting from 'postcss-nesting'; + +postcssNesting.process(YOUR_CSS /*, processOptions, pluginOptions */); +``` + +Or use it as a [PostCSS] plugin: + +```js +import postcss from 'postcss'; +import postcssNesting from 'postcss-nesting'; + +postcss([ + postcssNesting(/* pluginOptions */) +]).process(YOUR_CSS /*, processOptions */); +``` + +## Webpack + +Add [PostCSS Loader] to your project: + +```bash +npm install postcss-loader --save-dev +``` + +Use [PostCSS Nesting] in your Webpack configuration: + +```js +import postcssNesting from 'postcss-nesting'; + +module.exports = { + module: { + rules: [ + { + test: /\.css$/, + use: [ + 'style-loader', + { loader: 'css-loader', options: { importLoaders: 1 } }, + { loader: 'postcss-loader', options: { + ident: 'postcss', + plugins: () => [ + postcssNesting(/* pluginOptions */) + ] + } } + ] + } + ] + } +} +``` + +## Create React App + +Add [React App Rewired] and [React App Rewire PostCSS] to your project: + +```bash +npm install react-app-rewired react-app-rewire-postcss --save-dev +``` + +Use [React App Rewire PostCSS] and [PostCSS Nesting] in your +`config-overrides.js` file: + +```js +import reactAppRewirePostcss from 'react-app-rewire-postcss'; +import postcssNesting from 'postcss-nesting'; + +export default config => reactAppRewirePostcss(config, { + plugins: () => [ + postcssNesting(/* pluginOptions */) + ] +}); +``` + +## Gulp + +Add [Gulp PostCSS] to your project: + +```bash +npm install gulp-postcss --save-dev +``` + +Use [PostCSS Nesting] in your Gulpfile: + +```js +import postcss from 'gulp-postcss'; +import postcssNesting from 'postcss-nesting'; + +gulp.task('css', () => gulp.src('./src/*.css').pipe( + postcss([ + postcssNesting(/* pluginOptions */) + ]) +).pipe( + gulp.dest('.') +)); +``` + +## Grunt + +Add [Grunt PostCSS] to your project: + +```bash +npm install grunt-postcss --save-dev +``` + +Use [PostCSS Nesting] in your Gruntfile: + +```js +import postcssNesting from 'postcss-nesting'; + +grunt.loadNpmTasks('grunt-postcss'); + +grunt.initConfig({ + postcss: { + options: { + use: [ + postcssNesting(/* pluginOptions */) + ] + }, + dist: { + src: '*.css' + } + } +}); +``` + +[Gulp PostCSS]: https://github.com/postcss/gulp-postcss +[Grunt PostCSS]: https://github.com/nDmitry/grunt-postcss +[PostCSS]: https://github.com/postcss/postcss +[PostCSS Loader]: https://github.com/postcss/postcss-loader +[PostCSS Nesting]: https://github.com/jonathantneal/postcss-nesting +[React App Rewire PostCSS]: https://github.com/csstools/react-app-rewire-postcss +[React App Rewired]: https://github.com/timarney/react-app-rewired diff --git a/README.md b/README.md index 893c695a4f..c138919389 100644 --- a/README.md +++ b/README.md @@ -1,9 +1,8 @@ -# PostCSS Nesting [PostCSS Logo][postcss] +# PostCSS Nesting [PostCSS][postcss] -[![NPM Version][npm-img]][npm-url] [![CSS Standard Status][css-img]][css-url] +[![NPM Version][npm-img]][npm-url] [![Build Status][cli-img]][cli-url] -[![Windows Build Status][win-img]][win-url] [![Support Chat][git-img]][git-url] [PostCSS Nesting] lets you nest style rules inside each other, following the @@ -29,143 +28,50 @@ a c, a d, b c, b d { } ``` +**NOTICE**: In v7.0.0 nesting at-rules like `@media` will no longer work, as +they are not part of the nesting proposal. + ## Usage -Add [PostCSS Nesting] to your build tool: +Add [PostCSS Nesting] to your project: ```bash npm install postcss-nesting --save-dev ``` -#### Node - Use [PostCSS Nesting] to process your CSS: ```js import postcssNesting from 'postcss-nesting'; -postcssNesting.process(YOUR_CSS); -``` - -#### PostCSS - -Add [PostCSS] to your build tool: - -```bash -npm install postcss --save-dev +postcssNesting.process(YOUR_CSS /*, processOptions, pluginOptions */); ``` -Use [PostCSS Nesting] as a plugin: +Or use it as a [PostCSS] plugin: ```js -import postcss from 'gulp-postcss'; +import postcss from 'postcss'; import postcssNesting from 'postcss-nesting'; postcss([ - postcssNesting(/* options */) -]).process(YOUR_CSS); -``` - -#### Webpack - -Add [PostCSS Loader] to your build tool: - -```bash -npm install postcss-loader --save-dev -``` - -Use [PostCSS Nesting] in your Webpack configuration: - -```js -import postcssNesting from 'postcss-nesting'; - -export default { - module: { - rules: [ - { - test: /\.css$/, - use: [ - 'style-loader', - { loader: 'css-loader', options: { importLoaders: 1 } }, - { loader: 'postcss-loader', options: { - ident: 'postcss', - plugins: () => [ - postcssNesting(/* options */) - ] - } } - ] - } - ] - } -} + postcssNesting(/* pluginOptions */) +]).process(YOUR_CSS /*, processOptions */); ``` -#### Gulp +[PostCSS Nesting] runs in all Node environments, with special instructions for: -Add [Gulp PostCSS] to your build tool: +| [Node](INSTALL.md#node) | [Webpack](INSTALL.md#webpack) | [Create React App](INSTALL.md#create-react-app) | [Gulp](INSTALL.md#gulp) | [Grunt](INSTALL.md#grunt) | +| --- | --- | --- | --- | --- | -```bash -npm install gulp-postcss --save-dev -``` - -Use [PostCSS Nesting] in your Gulpfile: - -```js -import postcss from 'gulp-postcss'; -import postcssNesting from 'postcss-nesting'; - -gulp.task('css', () => gulp.src('./src/*.css').pipe( - postcss([ - postcssNesting(/* options */) - ]) -).pipe( - gulp.dest('.') -)); -``` - -#### Grunt - -Add [Grunt PostCSS] to your build tool: - -```bash -npm install grunt-postcss --save-dev -``` - -Use [PostCSS Nesting] in your Gruntfile: - -```js -import postcssNesting from 'postcss-nesting'; - -grunt.loadNpmTasks('grunt-postcss'); - -grunt.initConfig({ - postcss: { - options: { - use: [ - postcssNesting(/* options */) - ] - }, - dist: { - src: '*.css' - } - } -}); -``` - -[cli-url]: https://travis-ci.org/jonathantneal/postcss-nesting [cli-img]: https://img.shields.io/travis/jonathantneal/postcss-nesting.svg +[cli-url]: https://travis-ci.org/jonathantneal/postcss-nesting [css-img]: https://cssdb.org/badge/nesting-rules.svg [css-url]: https://cssdb.org/#nesting-rules +[git-img]: https://img.shields.io/badge/support-chat-blue.svg [git-url]: https://gitter.im/postcss/postcss -[git-img]: https://img.shields.io/badge/chat-gitter-blue.svg -[npm-url]: https://www.npmjs.com/package/postcss-nesting [npm-img]: https://img.shields.io/npm/v/postcss-nesting.svg -[win-img]: https://img.shields.io/appveyor/ci/jonathantneal/postcss-nesting.svg -[win-url]: https://ci.appveyor.com/project/jonathantneal/postcss-nesting +[npm-url]: https://www.npmjs.com/package/postcss-nesting [CSS Nesting]: http://tabatkins.github.io/specs/css-nesting/ -[Gulp PostCSS]: https://github.com/postcss/gulp-postcss -[Grunt PostCSS]: https://github.com/nDmitry/grunt-postcss [PostCSS]: https://github.com/postcss/postcss -[PostCSS Loader]: https://github.com/postcss/postcss-loader [PostCSS Nesting]: https://github.com/jonathantneal/postcss-nesting diff --git a/index.js b/index.js index ae0d905f4b..d41b55ba35 100644 --- a/index.js +++ b/index.js @@ -1,4 +1,4 @@ -import postcss from 'postcss'; -import transform from './lib/transform'; +import postcss from 'postcss'; +import walk from './lib/walk'; -export default postcss.plugin('postcss-nesting', () => root => root.walk(transform)); +export default postcss.plugin('postcss-nesting', () => walk); diff --git a/lib/atrule-within-atrule.js b/lib/atrule-within-atrule.js new file mode 100644 index 0000000000..baab671da1 --- /dev/null +++ b/lib/atrule-within-atrule.js @@ -0,0 +1,23 @@ +import shiftNodesBeforeParent from './shift-nodes-before-parent'; +import mergeParams from './merge-params'; +import cleanupParent from './cleanup-parent'; + +/* + * DEPRECATED: In v7.0.0 these features will be removed as they are not part of + * the nesting proposal. + */ + +export default function transformAtruleWithinAtrule(node) { + // move previous siblings and the node to before the parent + const parent = shiftNodesBeforeParent(node); + + // update the params of the node to be merged with the parent + node.params = mergeParams(parent.params, node.params); + + // conditionally cleanup an empty parent rule + cleanupParent(parent); +} + +import validAtrules from './valid-atrules'; + +export const isAtruleWithinAtrule = node => node.type === 'atrule' && validAtrules.includes(node.name) && Object(node.parent).type === 'atrule' && node.name === node.parent.name; diff --git a/lib/atrule-within-rule.js b/lib/atrule-within-rule.js new file mode 100644 index 0000000000..1b610c2708 --- /dev/null +++ b/lib/atrule-within-rule.js @@ -0,0 +1,28 @@ +import shiftNodesBeforeParent from './shift-nodes-before-parent'; +import cleanupParent from './cleanup-parent'; +import validAtrules from './valid-atrules'; +import walk from './walk'; + +/* + * DEPRECATED: In v7.0.0 these features will be removed as they are not part of + * the nesting proposal. + */ + +export default function atruleWithinRule(node) { + // move previous siblings and the node to before the parent + const parent = shiftNodesBeforeParent(node); + + // clone the parent as a new rule with children appended to it + const rule = parent.clone().removeAll().append(node.nodes); + + // append the new rule to the node + node.append(rule); + + // conditionally cleanup an empty parent rule + cleanupParent(parent); + + // walk the children of the new rule + walk(rule); +} + +export const isAtruleWithinRule = node => node.type === 'atrule' && validAtrules.includes(node.name) && Object(node.parent).type === 'rule'; diff --git a/lib/clean-node.js b/lib/clean-node.js deleted file mode 100644 index 369749a401..0000000000 --- a/lib/clean-node.js +++ /dev/null @@ -1,10 +0,0 @@ -// clean the raws of the node -export default node => { - node.raws = Object.assign( - node.raws.between ? { between: node.raws.between } : {}, - node.raws.semicolon ? { semicolon: true } : {}, - node.raws.important ? { important: node.raws.important } : {} - ); - - return node; -}; diff --git a/lib/cleanup-parent.js b/lib/cleanup-parent.js new file mode 100644 index 0000000000..57dbf0c978 --- /dev/null +++ b/lib/cleanup-parent.js @@ -0,0 +1,5 @@ +export default function cleanupParent(parent) { + if (!parent.nodes.length) { + parent.remove(); + } +} diff --git a/lib/get-closest-rule.js b/lib/get-closest-rule.js deleted file mode 100644 index 780734b0af..0000000000 --- a/lib/get-closest-rule.js +++ /dev/null @@ -1,10 +0,0 @@ -// return the closest rule -export default node => { - let selectorParent = node.parent; - - while (selectorParent && selectorParent.type !== 'rule') { - selectorParent = selectorParent.parent; - } - - return selectorParent; -}; diff --git a/lib/merge-params.js b/lib/merge-params.js index 6b92943e5a..f7d5339e89 100644 --- a/lib/merge-params.js +++ b/lib/merge-params.js @@ -2,9 +2,10 @@ import { list } from 'postcss'; const { comma } = list; -// merge params -export default (fromParams, toParams) => comma(fromParams).map( - params1 => comma(toParams).map( - params2 => params1 + ' and ' + params2 - ).join(', ') -).join(', '); +export default function mergeParams(fromParams, toParams) { + return comma(fromParams).map( + params1 => comma(toParams).map( + params2 => `${params1} and ${params2}` + ).join(', ') + ).join(', '); +} diff --git a/lib/merge-selectors.js b/lib/merge-selectors.js index 6840ac1544..6a504eb526 100644 --- a/lib/merge-selectors.js +++ b/lib/merge-selectors.js @@ -1,13 +1,12 @@ -// tooling -import { list } from 'postcss'; -const { comma } = list; +import { replaceable } from './valid-selector'; -// merge selectors -export default (fromSelectors, toSelectors) => (typeof fromSelectors === 'string' ? comma(fromSelectors) : fromSelectors).reduce( - (selectors, fromSelector) => selectors.concat( - (typeof toSelectors === 'string' ? comma(toSelectors) : toSelectors).map( - toSelector => toSelector.replace(/&/g, fromSelector) - ) - ), - [] -); +export default function mergeSelectors(fromSelectors, toSelectors) { + return fromSelectors.reduce( + (selectors, fromSelector) => selectors.concat( + toSelectors.map( + toSelector => toSelector.replace(replaceable, fromSelector) + ) + ), + [] + ); +} diff --git a/lib/nest-rule-within-rule.js b/lib/nest-rule-within-rule.js new file mode 100644 index 0000000000..f4bc8159bb --- /dev/null +++ b/lib/nest-rule-within-rule.js @@ -0,0 +1,32 @@ +import { list } from 'postcss'; +import shiftNodesBeforeParent from './shift-nodes-before-parent'; +import cleanupParent from './cleanup-parent'; +import mergeSelectors from './merge-selectors'; +import validSelector from './valid-selector'; +import walk from './walk'; + +const { comma } = list; + +export default function transformNestRuleWithinRule(node) { + // move previous siblings and the node to before the parent + const parent = shiftNodesBeforeParent(node); + + // clone the parent as a new rule with children appended to it + const rule = parent.clone().removeAll().append(node.nodes); + + // replace the node with the new rule + node.replaceWith(rule); + + // update the selectors of the node to be merged with the parent + rule.selectors = mergeSelectors(parent.selectors, comma(node.params)); + + // conditionally cleanup an empty parent rule + cleanupParent(parent); + + // walk the children of the new rule + walk(rule); +} + +export const isNestRuleWithinRule = node => node.type === 'atrule' && node.name === 'nest' && Object(node.parent).type === 'rule' && comma(node.params).every( + selector => selector.split('&').length === 2 && validSelector.test(selector) +); diff --git a/lib/rule-within-rule.js b/lib/rule-within-rule.js new file mode 100644 index 0000000000..e90a6e6a2d --- /dev/null +++ b/lib/rule-within-rule.js @@ -0,0 +1,19 @@ +import shiftNodesBeforeParent from './shift-nodes-before-parent'; +import cleanupParent from './cleanup-parent'; +import mergeSelectors from './merge-selectors'; +import validSelector from './valid-selector'; + +export default function transformRuleWithinRule(node) { + // move previous siblings and the node to before the parent + const parent = shiftNodesBeforeParent(node); + + // update the selectors of the node to be merged with the parent + node.selectors = mergeSelectors(parent.selectors, node.selectors); + + // conditionally cleanup an empty parent rule + cleanupParent(parent); +} + +export const isRuleWithinRule = node => node.type === 'rule' && Object(node.parent).type === 'rule' && node.selectors.every( + selector => selector.trim().lastIndexOf('&') === 0 && validSelector.test(selector) +); diff --git a/lib/shift-nodes-before-parent.js b/lib/shift-nodes-before-parent.js new file mode 100644 index 0000000000..512bd5a861 --- /dev/null +++ b/lib/shift-nodes-before-parent.js @@ -0,0 +1,16 @@ +export default function shiftNodesBeforeParent(node) { + const parent = node.parent; + const index = parent.index(node); + + // conditionally move previous siblings into a clone of the parent + if (index) { + parent.cloneBefore().removeAll().append( + parent.nodes.slice(0, index) + ) + } + + // move the current node before the parent (and after the conditional clone) + parent.before(node); + + return parent; +} diff --git a/lib/transform-after-nodes.js b/lib/transform-after-nodes.js deleted file mode 100644 index a1d7843518..0000000000 --- a/lib/transform-after-nodes.js +++ /dev/null @@ -1,21 +0,0 @@ -import cleanNode from './clean-node'; - -// move nodes after the current node into a cloned parent node -export default node => { - // affected nodes after the current node - const affectedNodes = node.parent.nodes.slice(node.parent.nodes.indexOf(node) + 1).map(cleanNode); - - if (affectedNodes.length) { - // insert an empty parent clone after the parent - const afterParent = cleanNode(node.parent.clone()).removeAll(); - - node.parent.after(afterParent); - - // append the affected nodes to the empty parent clone - afterParent.append(affectedNodes); - - return afterParent; - } - - return undefined; -}; diff --git a/lib/transform-before-nodes.js b/lib/transform-before-nodes.js deleted file mode 100644 index b14ac2588d..0000000000 --- a/lib/transform-before-nodes.js +++ /dev/null @@ -1,22 +0,0 @@ -import cleanNode from './clean-node'; - -// move nodes after the current node into a cloned parent node -export default node => { - // affected nodes after the current node - const affectedNodes = node.parent.nodes.slice(0, node.parent.nodes.indexOf(node)).map(cleanNode); - - if (affectedNodes.length) { - // clone the current parent - const beforeParent = cleanNode(node.parent.clone()).removeAll(); - - // append the affected nodes to the parent clone - beforeParent.append(affectedNodes); - - // insert a parent clone before the current parent - node.parent.before(beforeParent); - - return beforeParent; - } - - return undefined; -}; diff --git a/lib/transform-bubbling-atrule.js b/lib/transform-bubbling-atrule.js deleted file mode 100644 index 6e119e990c..0000000000 --- a/lib/transform-bubbling-atrule.js +++ /dev/null @@ -1,57 +0,0 @@ -import cleanNode from './clean-node'; -import mergeParams from './merge-params'; -import transformAfterNodes from './transform-after-nodes'; - -// transform a bubbling atrule (e.g. @document, @media, @supports) -export default node => { - // clean node - cleanNode(node); - - // affected nodes after the current node moved into a cloned parent node - transformAfterNodes(node); - - // inner nodes within the current node - const innerNodes = node.nodes.slice(0).map(cleanNode); - - // prepend an empty parent clone to the node - const parentCloneForNodesWithinAtrule = cleanNode(node.parent.clone()).removeAll(); - - node.prepend(parentCloneForNodesWithinAtrule); - - // append the inner nodes to the empty parent clone - parentCloneForNodesWithinAtrule.append(innerNodes); - - // swap semicolon raws - const semicolon = node.raws.semicolon; - - node.raws.semicolon = node.parent.raws.semicolon; - node.parent.raws.semicolon = semicolon; - - // move the node after the parent - const parent = node.parent.after(node); - - if (!parent.nodes.length) { - // conditionally remove the original empty parent - parent.remove(); - } - - // if the node and the parent are both media atrules - if (node.parent.type === 'atrule' && node.name === node.parent.name) { - // affected nodes after the current node moved into a cloned parent node - transformAfterNodes(node); - - // merge media params - node.params = mergeParams(node.parent.params, node.params); - - // move the node after the parent - const subparent = node.parent.after(node); - - if (!subparent.nodes.length) { - // conditionally remove the original empty parent - subparent.remove(); - } - } -}; - -// whether the node is a bubbling atrule (e.g. @document, @media, @supports) -export const test = node => node.type === 'atrule' && ['document', 'media', 'supports'].indexOf(node.name) !== -1 && node.parent && node.parent.type === 'rule'; diff --git a/lib/transform-nesting-atrule.js b/lib/transform-nesting-atrule.js deleted file mode 100644 index c655e484fb..0000000000 --- a/lib/transform-nesting-atrule.js +++ /dev/null @@ -1,66 +0,0 @@ -import postcss, { list } from 'postcss'; -import cleanNode from './clean-node'; -import getClosestRule from './get-closest-rule'; -import mergeSelectors from './merge-selectors'; -import transformAfterNodes from './transform-after-nodes'; - -const { comma } = list; - -// transform a nesting atrule (e.g. @nest .something &) -export default node => { - // clean node and child nodes - cleanNode(node).nodes.forEach(cleanNode); - - // affected nodes after the current node moved into a cloned parent node - const afterParent = transformAfterNodes(node); - - // get the closest rule - const selectorParent = getClosestRule(node); - - // clone of the atrule as a rule - const rule = postcss.rule({ - // merge selectors - selectors: mergeSelectors(selectorParent && selectorParent.selectors || '', node.params), - source: node.source - }); - - // clone atrule semicolon raws - rule.raws = node.raws.semicolon ? { semicolon: true } : {}; - - // move the clone after the parent - const parent = node.parent.after(rule); - - // remove the original node - node.remove(); - - // move child nodes into the clone - rule.append(node.nodes); - - if (!parent.nodes.length) { - // conditionally remove the original empty parent - parent.remove(); - } - - // if the next sibling shares the same selector - if (afterParent && afterParent.selector === rule.selector) { - rule.append(afterParent.nodes); - - afterParent.remove(); - } - - // if the previous sibling shares the same selector - if (parent.parent && parent.next() === rule && parent.selector === rule.selector) { - parent.append(rule.nodes); - - rule.remove(); - - return parent; - } - - return rule; -}; - -// whether the node is a nesting atrule (e.g. @nest .something &) -export const test = node => node.type === 'atrule' && node.name === 'nest' && node.parent && node.parent.type === 'rule' && comma(node.params).every( - selector => selector.split('&').length === 2 && /&([^\w-|]|$)/.test(selector) -); diff --git a/lib/transform-nesting-rule.js b/lib/transform-nesting-rule.js deleted file mode 100644 index 8546d2f382..0000000000 --- a/lib/transform-nesting-rule.js +++ /dev/null @@ -1,28 +0,0 @@ -import cleanNode from './clean-node'; -import mergeSelectors from './merge-selectors'; -import transformAfterNodes from './transform-after-nodes'; - -// transform a nesting rule (e.g. &.something) -export default node => { - // clean node and child nodes - cleanNode(node).nodes.forEach(cleanNode); - - // move nodes after the current node into a cloned parent node - transformAfterNodes(node); - - // merge selectors - node.selectors = mergeSelectors(node.parent.selectors, node.selectors); - - // move the node after the parent - const parent = node.parent.after(node); - - if (!parent.nodes.length) { - // conditionally remove the original empty parent - parent.remove(); - } -}; - -// whether the node is a nesting rule (e.g. &.something) -export const test = node => node.type === 'rule' && node.parent && node.parent.type === 'rule' && node.selectors.every( - selector => selector.trim().lastIndexOf('&') === 0 && /^&([^\w-|]|$)/.test(selector) -); diff --git a/lib/transform.js b/lib/transform.js deleted file mode 100644 index ff5685b000..0000000000 --- a/lib/transform.js +++ /dev/null @@ -1,17 +0,0 @@ -import transformBubblingAtrule, { test as transformBubblingAtruleTest } from './transform-bubbling-atrule'; -import transformNestingAtRule, { test as transformNestingAtRuleTest } from './transform-nesting-atrule'; -import transformNestingRule, { test as transformNestingRuleTest } from './transform-nesting-rule'; - -// conditionally transform a nesting rule -export default node => { - if (transformBubblingAtruleTest(node)) { - // conditionally transform a bubbling atrule - transformBubblingAtrule(node); - } else if (transformNestingAtRuleTest(node)) { - // conditionally transform a nesting atrule - transformNestingAtRule(node); - } else if (transformNestingRuleTest(node)) { - // conditionally transform a nesting rule - transformNestingRule(node); - } -}; diff --git a/lib/valid-atrules.js b/lib/valid-atrules.js new file mode 100644 index 0000000000..3438450fc1 --- /dev/null +++ b/lib/valid-atrules.js @@ -0,0 +1 @@ +export default ['document', 'media', 'supports']; diff --git a/lib/valid-selector.js b/lib/valid-selector.js new file mode 100644 index 0000000000..b9d943acf3 --- /dev/null +++ b/lib/valid-selector.js @@ -0,0 +1,4 @@ +// a valid selector is an ampersand followed by a non-word character or nothing +export default /&(?:[^\w-|]|$)/; + +export const replaceable = /&/g; diff --git a/lib/walk.js b/lib/walk.js new file mode 100644 index 0000000000..e62d437c40 --- /dev/null +++ b/lib/walk.js @@ -0,0 +1,24 @@ +import transformRuleWithinRule, { isRuleWithinRule} from './rule-within-rule'; +import transformNestRuleWithinRule, { isNestRuleWithinRule } from './nest-rule-within-rule'; +import transformAtruleWithinRule, { isAtruleWithinRule } from './atrule-within-rule'; +import transformAtruleWithinAtrule, { isAtruleWithinAtrule } from './atrule-within-atrule'; + +export default function walk(node) { + node.nodes.slice(0).forEach(child => { + if (child.parent === node) { + if (isRuleWithinRule(child)) { + transformRuleWithinRule(child); + } else if (isNestRuleWithinRule(child)) { + transformNestRuleWithinRule(child); + } else if (isAtruleWithinRule(child)) { + transformAtruleWithinRule(child); + } else if (isAtruleWithinAtrule(child)) { + transformAtruleWithinAtrule(child); + } + + if (Object(child.nodes).length) { + walk(child); + } + } + }); +} diff --git a/package.json b/package.json index 8f3653b391..c3f81d099c 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "postcss-nesting", - "version": "5.0.0", + "version": "6.0.0", "description": "Nest style rules inside each other", "author": "Jonathan Neal ", "license": "CC0-1.0", @@ -21,20 +21,21 @@ "test:tape": "postcss-tape" }, "engines": { - "node": ">=4.0.0" + "node": ">=6.0.0" }, "dependencies": { - "postcss": "^6.0.21" + "postcss": "^6.0.22" }, "devDependencies": { - "babel-core": "^6.26.0", + "babel-core": "^6.26.3", "babel-eslint": "^8.2.3", - "babel-preset-env": "^1.6.1", + "babel-plugin-array-includes": "^2.0.3", + "babel-preset-env": "^1.7.0", "eslint": "^4.19.1", "eslint-config-dev": "^2.0.0", "postcss-tape": "^2.2.0", "pre-commit": "^1.2.2", - "rollup": "^0.58.2", + "rollup": "^0.60.1", "rollup-plugin-babel": "^3.0.4" }, "eslintConfig": { diff --git a/test/at-rule.expect.css b/test/at-rule.expect.css index df7cfadae8..e14978cc3a 100644 --- a/test/at-rule.expect.css +++ b/test/at-rule.expect.css @@ -2,29 +2,29 @@ a { order: 1 } b a { - order: 2; + order: 2 } c a { - order: 3; + order: 3 } d a { - order: 4; + order: 4 } e a { - order: 5; + order: 5 } a { order: 1 } a b { - order: 2; + order: 2 } a c { - order: 3; + order: 3 } a d { - order: 4; + order: 4 } a e { - order: 5; + order: 5 } diff --git a/test/basic.css b/test/basic.css index df6cafdff6..dbd84ef451 100644 --- a/test/basic.css +++ b/test/basic.css @@ -1,19 +1,48 @@ -.rule-1 { +a { order: 1; + @media screen, print { order: 2; - &.rule-2 { + + @media (min-width: 480px) { order: 3; - @media (max-width: 30em) { - order: 4; - @nest .rule-prefix & { - order: 5; - } - order: 6; - } - order: 7; } - order: 8; + + order: 4; + } + + order: 5; + order: 6; + + & b { + order: 7; + + & c { + order: 8; + } + + order: 9; + } + + order: 10; + + @nest body & { + order: 11; + + @nest html & { + order: 12; + } + + order: 13; + } + + order: 14; + + @media screen { + order: 15; + + @media (min-width: 480px) { + order: 16; + } } - order: 9; } diff --git a/test/basic.expect.css b/test/basic.expect.css index aefc97b7f0..759fdf0424 100644 --- a/test/basic.expect.css +++ b/test/basic.expect.css @@ -1,33 +1,62 @@ -.rule-1 { - order: 1; +a { + order: 1 } @media screen, print { - .rule-1 { - order: 2; - } - .rule-1.rule-2 { - order: 3; - } + a { + order: 2 } -@media screen and (max-width: 30em), print and (max-width: 30em) { - .rule-1.rule-2 { - order: 4; - } - .rule-prefix .rule-1.rule-2 { - order: 5; - } - .rule-1.rule-2 { - order: 6; } +@media screen and (min-width: 480px), print and (min-width: 480px) { + a { + order: 3 } + } @media screen, print { - .rule-1.rule-2 { + a { + + order: 4 +} + } +a { + + order: 5; + order: 6 +} +a b { order: 7; } - .rule-1 { - order: 8; +a b c { + order: 8; + } +a b { + + order: 9; } +a { + + order: 10 } -.rule-1 { - order: 9; +body a { + order: 11 +} +html body a { + order: 12 +} +body a { + + order: 13 +} +a { + + order: 14 +} +@media screen { + a { + order: 15 +} + } +@media screen and (min-width: 480px) { + a { + order: 16 } + } diff --git a/test/direct.expect.css b/test/direct.expect.css index 07c4bdfa09..fad601f5ea 100644 --- a/test/direct.expect.css +++ b/test/direct.expect.css @@ -2,14 +2,14 @@ a, b { order: 1; } a c, a d, b c, b d { - order: 2; -} + order: 2; + } a c e, a c f, a d e, a d f, b c e, b c f, b d e, b d f { - order: 3; -} + order: 3; + } a c, a d, b c, b d { - order: 4; -} + order: 4; + } a, b { order: 5; } @@ -17,13 +17,13 @@ a, b { order: 1; } a c, a d, b c, b d { - order: 2; + order: 2; } a c e, a c f, a d e, a d f, b c e, b c f, b d e, b d f { - order: 3; + order: 3; } a c, a d, b c, b d { - order: 4; + order: 4; } a, b { order: 5; diff --git a/test/empty.expect.css b/test/empty.expect.css index a2423bc723..a23b4e20d1 100644 --- a/test/empty.expect.css +++ b/test/empty.expect.css @@ -1,29 +1,30 @@ -a b c { - order: 1; -} + + a b c { + order: 1; + } d { order: 2 } d e { - order: 3; -} + order: 3; + } f g { - order: 4; -} + order: 4; + } f { order: 5; } a b c { - order: 1; + order: 1 } d { order: 2 } d e { - order: 3; + order: 3 } f g { - order: 4; + order: 4; } f { order: 5; diff --git a/test/media.expect.css b/test/media.expect.css index b3e80c929d..2d3e4cccce 100644 --- a/test/media.expect.css +++ b/test/media.expect.css @@ -1,52 +1,52 @@ a { - order: 1; + order: 1 } @media (min-width: 100px) { - a { - order: 2; - } +a { + order: 2 } -@media (min-width: 100px) and (max-width: 200px) { - a { - order: 3; } -} @media (min-width: 100px) and (max-width: 200px) { - a b { - order: 4; - } +a { + order: 3 } + } +@media (min-width: 100px) and (max-width: 200px) { + a b { + order: 4 + } + } @media screen and (max-width: 300px), screen and (min-aspect-ratio: 16/9), print and speech and (max-width: 300px), print and speech and (min-aspect-ratio: 16/9) { - a { - order: 5; - } - a c { - order: 6; - } +a { + order: 5 } + a c { + order: 6; + } + } a { - order: 1; + order: 1 } @media (min-width: 100px) { - a { - order: 2; - } +a { + order: 2 } -@media (min-width: 100px) and (max-width: 200px) { - a { - order: 3; } +@media (min-width: 100px) and (max-width: 200px) { +a { + order: 3 } + } @media (min-width: 100px) and (max-width: 200px) { - a b { - order: 4; - } +a b { + order: 4 } + } @media screen and (max-width: 300px), screen and (min-aspect-ratio: 16/9), print and speech and (max-width: 300px), print and speech and (min-aspect-ratio: 16/9) { - a { - order: 5; - } - a c { - order: 6; - } +a { + order: 5 +} +a c { + order: 6 } + } From 5c5b70ad62fd016ec543ac1bec93e8b8f1026b7c Mon Sep 17 00:00:00 2001 From: Jonathan Neal Date: Sat, 16 Jun 2018 02:24:55 -0400 Subject: [PATCH 640/795] 6.0.0 --- CHANGELOG.md | 6 + CONTRIBUTING.md | 2 +- INSTALL.md | 4 +- README.md | 12 +- index.js | 80 +++--- lib/normalize-browser-list.json | 67 ----- lib/normalize-init.js | 23 -- lib/normalize.css | 432 ---------------------------- lib/normalize.js | 36 --- lib/normalize.json | 1 - package.json | 26 +- test/basic.expect.css | 286 ++++++++++++++---- test/basic.last-1.expect.css | 286 ++++++++++++++---- test/basic.last-2.expect.css | 312 ++++++++++++++++---- test/insertion-after.expect.css | 286 ++++++++++++++---- test/insertion-duplicate.expect.css | 286 ++++++++++++++---- test/option-force-import.expect.css | 315 ++++++++++++++++---- 17 files changed, 1492 insertions(+), 968 deletions(-) delete mode 100644 lib/normalize-browser-list.json delete mode 100644 lib/normalize-init.js delete mode 100644 lib/normalize.css delete mode 100644 lib/normalize.js delete mode 100644 lib/normalize.json diff --git a/CHANGELOG.md b/CHANGELOG.md index 0fe139a072..59046ee885 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,11 @@ # Changes to PostCSS Normalize +### 6.0.0 (June 16, 2018) + +- Use normalize.css v8 (major) +- Include normalize.css comments +- Include normalize.css sourcemap + ### 5.0.0 (June 7, 2018) - Update `browserslist` to v3.2.8 (major) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index b1765ba538..5b860e6c83 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -26,7 +26,7 @@ scope and avoid unrelated commits. cd postcss-normalize # Assign the original repo to a remote called "upstream" - git remote add upstream git@github.com:jonathantneal/postcss-normalize.git + git remote add upstream git@github.com:csstools/postcss-normalize.git # Install the tools necessary for testing npm install diff --git a/INSTALL.md b/INSTALL.md index e3430ee9d6..bb335f6dee 100644 --- a/INSTALL.md +++ b/INSTALL.md @@ -1,6 +1,6 @@ # Installing PostCSS Normalize -$[PostCSS Normalize] runs in all Node environments, with special instructions for: +[PostCSS Normalize] runs in all Node environments, with special instructions for: | [Node](#node) | [Webpack](#webpack) | [Create React App](#create-react-app) | [Gulp](#gulp) | [Grunt](#grunt) | | --- | --- | --- | --- | --- | @@ -144,6 +144,6 @@ grunt.initConfig({ [Grunt PostCSS]: https://github.com/nDmitry/grunt-postcss [PostCSS]: https://github.com/postcss/postcss [PostCSS Loader]: https://github.com/postcss/postcss-loader -[PostCSS Normalize]: https://github.com/jonathantneal/postcss-normalize +[PostCSS Normalize]: https://github.com/csstools/postcss-normalize [React App Rewire PostCSS]: https://github.com/csstools/react-app-rewire-postcss [React App Rewired]: https://github.com/timarney/react-app-rewired diff --git a/README.md b/README.md index f2c25f86aa..ae01eb8d17 100644 --- a/README.md +++ b/README.md @@ -11,7 +11,7 @@ Use `@import-normalize` to determine where [normalize.css] rules should be included. Duplicate `@import-normalize` rules will be removed. See all the [Options] for more information. -```css +```pcss @import-normalize; ``` @@ -129,15 +129,15 @@ postcssNormalize({ }); ``` -[cli-img]: https://img.shields.io/travis/jonathantneal/postcss-normalize.svg -[cli-url]: https://travis-ci.org/jonathantneal/postcss-normalize +[cli-img]: https://img.shields.io/travis/csstools/postcss-normalize.svg +[cli-url]: https://travis-ci.org/csstools/postcss-normalize [git-img]: https://img.shields.io/badge/support-chat-blue.svg [git-url]: https://gitter.im/postcss/postcss [npm-img]: https://img.shields.io/npm/v/postcss-normalize.svg [npm-url]: https://www.npmjs.com/package/postcss-normalize [browserslist]: http://browserl.ist/ -[normalize.css]: https://github.com/jonathantneal/normalize.css -[Options]: #Options +[normalize.css]: https://github.com/csstools/normalize.css +[Options]: #options [PostCSS]: https://github.com/postcss/postcss -[PostCSS Normalize]: https://github.com/jonathantneal/postcss-normalize +[PostCSS Normalize]: https://github.com/csstools/postcss-normalize diff --git a/index.js b/index.js index 9329ca7813..8ac0a8162e 100644 --- a/index.js +++ b/index.js @@ -1,62 +1,58 @@ -// tooling -const browserslist = require('browserslist'); -const normalizeRules = require('./lib/normalize.js'); -const postcss = require('postcss'); +import postcss from 'postcss'; +import postcssBrowserComments from 'postcss-browser-comments'; +import fs from 'fs'; -// plugin -module.exports = postcss.plugin('postcss-normalize', (opts) => { - return (root) => { - // client browser list - const clientBrowserList = browserslist(opts && opts.browsers, { - path: root.source && root.source.input && root.source.input.file - }); +export default postcss.plugin('postcss-normalize', opts => { + const parsedNormalize = parseNormalize(opts); - // applied rules from normalize - const appliedRules = normalizeRules.map( - (rule) => { - const clone = rule.clone(); - - clone.nodes = clone.nodes.filter( - (decl, index) => { - // whether the declaration browser list matches the client browser list - return clientBrowserList.some( - (clientBrowser) => browserslist(rule.nodes[index].browserList).some( - (declBrowser) => declBrowser === clientBrowser - ) - ); - } - ); - - return clone; - } - ).filter( - (rule) => rule.nodes.length - ); + return async root => { + const normalizeRoot = await parsedNormalize; // use @import postcss-normalize insertion point root.walkAtRules( 'import-normalize', - (atrule) => { + atrule => { if (opts && opts.allowDuplicates) { // use any insertion point - atrule.replaceWith( - appliedRules.map( - (rule) => rule.clone() - ) - ); - } else if (appliedRules[0].parent) { + atrule.replaceWith(normalizeRoot); + } else if (normalizeRoot.parent) { // remove duplicate insertions atrule.remove(); } else { // use the first insertion point - atrule.replaceWith(appliedRules); + atrule.replaceWith(normalizeRoot); } } ); - if (opts && opts.forceImport && !appliedRules[0].parent) { + if (opts && opts.forceImport && !normalizeRoot.parent) { // prepend required normalize rules - root.prepend(appliedRules); + root.prepend(normalizeRoot); } }; }); + +function parseNormalize(opts) { + const from = require.resolve('@csstools/normalize.css'); + const postcssBrowserCommentsParser = postcssBrowserComments(opts); + + return new Promise( + (resolve, reject) => fs.readFile(from, 'utf8', + (err, res) => { + if (err) { + reject(err); + } else { + resolve(res); + } + } + ) + ).then( + css => postcss.parse(css, { from }) + ).then( + root => { + postcssBrowserCommentsParser(root); + + return root; + } + ); +} diff --git a/lib/normalize-browser-list.json b/lib/normalize-browser-list.json deleted file mode 100644 index eab4a148fd..0000000000 --- a/lib/normalize-browser-list.json +++ /dev/null @@ -1,67 +0,0 @@ -[ - ["> 0%"], - ["ie > 0"], - ["ios > 0"], - ["ie <= 8"], - ["chrome > 0", "ff > 0", "safari > 0"], - ["chrome > 0", "ff > 0", "safari > 0"], - ["ie <= 8"], - ["ie <= 8"], - ["ff > 0"], - ["ff > 0"], - ["edge > 0", "ie > 0"], - ["ie > 0"], - ["> 0%"], - ["> 0%"], - ["ie <= 10"], - ["ios > 0", "safari > 0"], - ["ff <= 39"], - ["chrome <= 58", "edge > 0", "ie > 0", "opera > 0", "safari > 0"], - ["chrome <= 58", "edge > 0", "ie > 0", "opera > 0", "safari > 0"], - ["safari <= 6"], - ["chrome > 0", "edge > 0", "safari > 0"], - ["> 0%"], - ["> 0%"], - ["android <= 4.3"], - ["ie <= 8"], - ["ie <= 8"], - ["> 0%"], - ["ie <= 9"], - ["ios <= 7"], - ["ios <= 7"], - ["ie <= 10"], - ["ie > 0"], - ["ff > 0", "safari > 0"], - ["ie > 0"], - ["edge > 0", "ff > 0", "ie > 0"], - ["ios > 0", "safari > 0"], - ["android <= 4"], - ["ff > 0"], - ["ff > 0"], - ["ff > 0"], - ["ff > 0"], - ["edge > 0", "ie > 0"], - ["edge > 0", "ie > 0"], - ["ie > 0"], - ["edge > 0", "ie > 0"], - ["edge > 0", "ie > 0"], - ["> 0%"], - ["edge > 0", "ie > 0"], - ["edge > 0", "ie > 0"], - ["chrome > 0", "ff > 0", "opera > 0"], - ["firefox > 0"], - ["ie > 0"], - ["ie <= 10"], - ["ie <= 10"], - ["chrome > 0"], - ["chrome > 0", "safari > 0"], - ["safari > 0"], - ["chrome > 0", "safari > 0"], - ["ios > 0", "safari > 0"], - ["safari > 0"], - ["edge > 0", "ff <= 48", "ie > 0"], - ["> 0%"], - ["ie <= 9"], - ["ie > 0"], - ["ie <= 10"] -] diff --git a/lib/normalize-init.js b/lib/normalize-init.js deleted file mode 100644 index f6454d2a3e..0000000000 --- a/lib/normalize-init.js +++ /dev/null @@ -1,23 +0,0 @@ -// tooling -const fs = require('fse'); -const path = require('path'); -const normalizeBrowserList = require('./normalize-browser-list.json'); - -// paths to normalize.css and normalize.json -const pathToNormalizeCSS = path.resolve(__dirname, 'normalize.css'); -const pathToNormalizeJSON = path.resolve(__dirname, 'normalize.json'); -const pathToNormalizeImport = path.resolve(path.dirname(__dirname), 'index.css'); - -Promise.resolve().then( - // parse normalize.css - () => fs.readFile(pathToNormalizeCSS, 'utf8').then( - (normalizeCSS) => fs.writeFile( - pathToNormalizeJSON, - JSON.stringify({ - browserList: normalizeBrowserList, - css: normalizeCSS.replace(/\r?\n|\r/g, '\n') - }), - 'utf8' - ) - ) -); diff --git a/lib/normalize.css b/lib/normalize.css deleted file mode 100644 index 33efd60ade..0000000000 --- a/lib/normalize.css +++ /dev/null @@ -1,432 +0,0 @@ -/*! normalize.css v7.0.0 | MIT License | github.com/jonathantneal/normalize.css */ - -/* Document - ========================================================================== */ - -/** - * 1. Correct the line height in all browsers. - * 2. Prevent adjustments of font size after orientation changes in - * IE on Windows Phone and in iOS. - */ - -html { - line-height: 1.15; /* 1 */ - -ms-text-size-adjust: 100%; /* 2 */ - -webkit-text-size-adjust: 100%; /* 2 */ -} - -/* Sections - ========================================================================== */ - -/** - * Add the correct display in IE 8-. - */ - -article, -aside, -footer, -header, -nav, -section { - display: block; -} - -/** - * Correct the font size and margin on `h1` elements within `section` and - * `article` contexts in Chrome, Firefox, and Safari. - */ - -h1 { - font-size: 2em; - margin: 0.67em 0; -} - -/* Grouping content - ========================================================================== */ - -/** - * Add the correct display in IE 8-. - */ - -figcaption, -figure { - display: block; -} - -/** - * Add the correct margin in IE 8-. - */ - -figure { - margin: 1em 40px; -} - -/** - * 1. Add the correct box sizing in Firefox. - * 2. Show the overflow in Edge and IE. - */ - -hr { - box-sizing: content-box; /* 1 */ - height: 0; /* 1 */ - overflow: visible; /* 2 */ -} - -/** - * Add the correct display in IE. - */ - -main { - display: block; -} - -/** - * 1. Correct the inheritance and scaling of font size in all browsers. - * 2. Correct the odd `em` font sizing in all browsers. - */ - -pre { - font-family: monospace, monospace; /* 1 */ - font-size: 1em; /* 2 */ -} - -/* Text-level semantics - ========================================================================== */ - -/** - * 1. Remove the gray background on active links in IE 10. - * 2. Remove gaps in links underline in iOS 8+ and Safari 8+. - */ - -a { - background-color: transparent; /* 1 */ - -webkit-text-decoration-skip: objects; /* 2 */ -} - -/** - * 1. Remove the bottom border in Firefox 39-. - * 2. Add the correct text decoration in Chrome 57-, Edge, IE, Opera, - and Safari. - */ - -abbr[title] { - border-bottom: none; /* 1 */ - text-decoration: underline; /* 2 */ - text-decoration: underline dotted; /* 2 */ -} - -/** - * Prevent the duplicate application of `bolder` by the next rule in Safari 6. - */ - -b, -strong { - font-weight: inherit; -} - -/** - * Add the correct font weight in Chrome, Edge, and Safari. - */ - -b, -strong { - font-weight: bolder; -} - -/** - * 1. Correct the inheritance and scaling of font size in all browsers. - * 2. Correct the odd `em` font sizing in all browsers. - */ - -code, -kbd, -samp { - font-family: monospace, monospace; /* 1 */ - font-size: 1em; /* 2 */ -} - -/** - * Add the correct font style in Android 4.3-. - */ - -dfn { - font-style: italic; -} - -/** - * Add the correct background and color in IE 8-. - */ - -mark { - background-color: #ff0; - color: #000; -} - -/** - * Add the correct font size in all browsers. - */ - -small { - font-size: 80%; -} - -/* Embedded content - ========================================================================== */ - -/** - * Add the correct display in IE 9-. - */ - -audio, -video { - display: inline-block; -} - -/** - * Add the correct display in iOS 4-7. - */ - -audio:not([controls]) { - display: none; - height: 0; -} - -/** - * Remove the border on images inside links in IE 10-. - */ - -img { - border-style: none; -} - -/** - * Hide the overflow in IE. - */ - -svg:not(:root) { - overflow: hidden; -} - -/* Forms - ========================================================================== */ - -/** - * Remove the margin in Firefox and Safari. - */ - -button, -input, -optgroup, -select, -textarea { - margin: 0; -} - -/** - * 1. Show the overflow in IE. - * 2. Remove the inheritance of text transform in Edge, Firefox, and IE. - */ - -button { - overflow: visible; /* 1 */ - text-transform: none; /* 2 */ -} - -/** - * Correct the inability to style clickable types in iOS and Safari. - */ - -button, -[type="button"], -[type="reset"], -[type="submit"] { - -webkit-appearance: button; -} - -/** - * Prevent a WebKit bug where (2) destroys native `audio` and `video` controls - * in Android 4. - */ - -html [type="button"] { - -webkit-appearance: button; -} - -/** - * Remove the inner border and padding in Firefox. - */ - -button::-moz-focus-inner, -[type="button"]::-moz-focus-inner, -[type="reset"]::-moz-focus-inner, -[type="submit"]::-moz-focus-inner { - border-style: none; - padding: 0; -} - -/** - * Restore the focus styles unset by the previous rule. - */ - -button:-moz-focusring, -[type="button"]:-moz-focusring, -[type="reset"]:-moz-focusring, -[type="submit"]:-moz-focusring { - outline: 1px dotted ButtonText; -} - -/** - * Correct the padding in Firefox. - */ - -fieldset { - padding: 0.35em 0.75em 0.625em; -} - -/** - * Show the overflow in Edge and IE. - */ - -input { - overflow: visible; -} - -/** - * 1. Correct the text wrapping in Edge and IE. - * 2. Correct the color inheritance from `fieldset` elements in IE. - * 3. Remove the padding so developers are not caught out when they zero out - * `fieldset` elements in all browsers. - */ - -legend { - box-sizing: border-box; /* 1 */ - color: inherit; /* 2 */ - display: table; /* 1 */ - max-width: 100%; /* 1 */ - padding: 0; /* 3 */ - white-space: normal; /* 1 */ -} - -/** - * 1. Add the correct display in Edge and IE. - * 2. Add the correct vertical alignment in Chrome, Firefox, and Opera. - */ - -progress { - display: inline-block; /* 1 */ - vertical-align: baseline; /* 2 */ -} - -/** - * Remove the inheritance of text transform in Firefox. - */ - -select { - text-transform: none; -} - -/** - * Remove the default vertical scrollbar in IE. - */ - -textarea { - overflow: auto; -} - -/** - * 1. Add the correct box sizing in IE 10-. - * 2. Remove the padding in IE 10-. - */ - -[type="checkbox"], -[type="radio"] { - box-sizing: border-box; /* 1 */ - padding: 0; /* 2 */ -} - -/** - * Correct the cursor style of increment and decrement buttons in Chrome. - */ - -[type="number"]::-webkit-inner-spin-button, -[type="number"]::-webkit-outer-spin-button { - height: auto; -} - -/** - * 1. Correct the odd appearance in Chrome and Safari. - * 2. Correct the outline style in Safari. - */ - -[type="search"] { - -webkit-appearance: textfield; /* 1 */ - outline-offset: -2px; /* 2 */ -} - -/** - * Remove the inner padding and cancel buttons in Chrome and Safari on macOS. - */ - -[type="search"]::-webkit-search-cancel-button, -[type="search"]::-webkit-search-decoration { - -webkit-appearance: none; -} - -/** - * 1. Correct the inability to style clickable types in iOS and Safari. - * 2. Change font properties to `inherit` in Safari. - */ - -::-webkit-file-upload-button { - -webkit-appearance: button; /* 1 */ - font: inherit; /* 2 */ -} - -/* Interactive - ========================================================================== */ - -/* - * Add the correct display in Edge, Firefox 48-, and IE. - */ - -details { - display: block; -} - -/* - * Add the correct display in all browsers. - */ - -summary { - display: list-item; -} - -/* Scripting - ========================================================================== */ - -/** - * Add the correct display in IE 9-. - */ - -canvas { - display: inline-block; -} - -/** - * Add the correct display in IE. - */ - -template { - display: none; -} - -/* Hidden - ========================================================================== */ - -/** - * Add the correct display in IE 10-. - */ - -[hidden] { - display: none; -} diff --git a/lib/normalize.js b/lib/normalize.js deleted file mode 100644 index 05dd46be50..0000000000 --- a/lib/normalize.js +++ /dev/null @@ -1,36 +0,0 @@ -'use strict'; - -// tooling -const postcss = require('postcss'); -const normalize = require('./normalize.json'); - -let browserListIndex = -1; - -// return normalize.css with browserlist -module.exports = postcss.parse(normalize.css).nodes.filter( - (rule) => { - // filter nodes to keep only rules - if (rule.type === 'rule') { - // filter nodes to keep only declarations - rule.nodes = rule.nodes.filter( - (decl) => { - // if the node is a declaration - if (decl.type === 'decl') { - // copy browserList - decl.browserList = normalize.browserList[++browserListIndex]; - - // delete raws - delete decl.raws; - - return decl; - } - } - ); - - // delete raws - delete rule.raws; - - return rule; - } - } -); diff --git a/lib/normalize.json b/lib/normalize.json deleted file mode 100644 index 3f9ab9f555..0000000000 --- a/lib/normalize.json +++ /dev/null @@ -1 +0,0 @@ -{"browserList":[["> 0%"],["ie > 0"],["ios > 0"],["ie <= 8"],["chrome > 0","ff > 0","safari > 0"],["chrome > 0","ff > 0","safari > 0"],["ie <= 8"],["ie <= 8"],["ff > 0"],["ff > 0"],["edge > 0","ie > 0"],["ie > 0"],["> 0%"],["> 0%"],["ie <= 10"],["ios > 0","safari > 0"],["ff <= 39"],["chrome <= 58","edge > 0","ie > 0","opera > 0","safari > 0"],["chrome <= 58","edge > 0","ie > 0","opera > 0","safari > 0"],["safari <= 6"],["chrome > 0","edge > 0","safari > 0"],["> 0%"],["> 0%"],["android <= 4.3"],["ie <= 8"],["ie <= 8"],["> 0%"],["ie <= 9"],["ios <= 7"],["ios <= 7"],["ie <= 10"],["ie > 0"],["ff > 0","safari > 0"],["ie > 0"],["edge > 0","ff > 0","ie > 0"],["ios > 0","safari > 0"],["android <= 4"],["ff > 0"],["ff > 0"],["ff > 0"],["ff > 0"],["edge > 0","ie > 0"],["edge > 0","ie > 0"],["ie > 0"],["edge > 0","ie > 0"],["edge > 0","ie > 0"],["> 0%"],["edge > 0","ie > 0"],["edge > 0","ie > 0"],["chrome > 0","ff > 0","opera > 0"],["firefox > 0"],["ie > 0"],["ie <= 10"],["ie <= 10"],["chrome > 0"],["chrome > 0","safari > 0"],["safari > 0"],["chrome > 0","safari > 0"],["ios > 0","safari > 0"],["safari > 0"],["edge > 0","ff <= 48","ie > 0"],["> 0%"],["ie <= 9"],["ie > 0"],["ie <= 10"]],"css":"/*! normalize.css v7.0.0 | MIT License | github.com/jonathantneal/normalize.css */\n\n/* Document\n ========================================================================== */\n\n/**\n * 1. Correct the line height in all browsers.\n * 2. Prevent adjustments of font size after orientation changes in\n * IE on Windows Phone and in iOS.\n */\n\nhtml {\n line-height: 1.15; /* 1 */\n -ms-text-size-adjust: 100%; /* 2 */\n -webkit-text-size-adjust: 100%; /* 2 */\n}\n\n/* Sections\n ========================================================================== */\n\n/**\n * Add the correct display in IE 8-.\n */\n\narticle,\naside,\nfooter,\nheader,\nnav,\nsection {\n display: block;\n}\n\n/**\n * Correct the font size and margin on `h1` elements within `section` and\n * `article` contexts in Chrome, Firefox, and Safari.\n */\n\nh1 {\n font-size: 2em;\n margin: 0.67em 0;\n}\n\n/* Grouping content\n ========================================================================== */\n\n/**\n * Add the correct display in IE 8-.\n */\n\nfigcaption,\nfigure {\n display: block;\n}\n\n/**\n * Add the correct margin in IE 8-.\n */\n\nfigure {\n margin: 1em 40px;\n}\n\n/**\n * 1. Add the correct box sizing in Firefox.\n * 2. Show the overflow in Edge and IE.\n */\n\nhr {\n box-sizing: content-box; /* 1 */\n height: 0; /* 1 */\n overflow: visible; /* 2 */\n}\n\n/**\n * Add the correct display in IE.\n */\n\nmain {\n display: block;\n}\n\n/**\n * 1. Correct the inheritance and scaling of font size in all browsers.\n * 2. Correct the odd `em` font sizing in all browsers.\n */\n\npre {\n font-family: monospace, monospace; /* 1 */\n font-size: 1em; /* 2 */\n}\n\n/* Text-level semantics\n ========================================================================== */\n\n/**\n * 1. Remove the gray background on active links in IE 10.\n * 2. Remove gaps in links underline in iOS 8+ and Safari 8+.\n */\n\na {\n background-color: transparent; /* 1 */\n -webkit-text-decoration-skip: objects; /* 2 */\n}\n\n/**\n * 1. Remove the bottom border in Firefox 39-.\n * 2. Add the correct text decoration in Chrome 57-, Edge, IE, Opera,\n and Safari.\n */\n\nabbr[title] {\n border-bottom: none; /* 1 */\n text-decoration: underline; /* 2 */\n text-decoration: underline dotted; /* 2 */\n}\n\n/**\n * Prevent the duplicate application of `bolder` by the next rule in Safari 6.\n */\n\nb,\nstrong {\n font-weight: inherit;\n}\n\n/**\n * Add the correct font weight in Chrome, Edge, and Safari.\n */\n\nb,\nstrong {\n font-weight: bolder;\n}\n\n/**\n * 1. Correct the inheritance and scaling of font size in all browsers.\n * 2. Correct the odd `em` font sizing in all browsers.\n */\n\ncode,\nkbd,\nsamp {\n font-family: monospace, monospace; /* 1 */\n font-size: 1em; /* 2 */\n}\n\n/**\n * Add the correct font style in Android 4.3-.\n */\n\ndfn {\n font-style: italic;\n}\n\n/**\n * Add the correct background and color in IE 8-.\n */\n\nmark {\n background-color: #ff0;\n color: #000;\n}\n\n/**\n * Add the correct font size in all browsers.\n */\n\nsmall {\n font-size: 80%;\n}\n\n/* Embedded content\n ========================================================================== */\n\n/**\n * Add the correct display in IE 9-.\n */\n\naudio,\nvideo {\n display: inline-block;\n}\n\n/**\n * Add the correct display in iOS 4-7.\n */\n\naudio:not([controls]) {\n display: none;\n height: 0;\n}\n\n/**\n * Remove the border on images inside links in IE 10-.\n */\n\nimg {\n border-style: none;\n}\n\n/**\n * Hide the overflow in IE.\n */\n\nsvg:not(:root) {\n overflow: hidden;\n}\n\n/* Forms\n ========================================================================== */\n\n/**\n * Remove the margin in Firefox and Safari.\n */\n\nbutton,\ninput,\noptgroup,\nselect,\ntextarea {\n margin: 0;\n}\n\n/**\n * 1. Show the overflow in IE.\n * 2. Remove the inheritance of text transform in Edge, Firefox, and IE.\n */\n\nbutton {\n overflow: visible; /* 1 */\n text-transform: none; /* 2 */\n}\n\n/**\n * Correct the inability to style clickable types in iOS and Safari.\n */\n\nbutton,\n[type=\"button\"],\n[type=\"reset\"],\n[type=\"submit\"] {\n -webkit-appearance: button;\n}\n\n/**\n * Prevent a WebKit bug where (2) destroys native `audio` and `video` controls\n * in Android 4.\n */\n\nhtml [type=\"button\"] {\n -webkit-appearance: button;\n}\n\n/**\n * Remove the inner border and padding in Firefox.\n */\n\nbutton::-moz-focus-inner,\n[type=\"button\"]::-moz-focus-inner,\n[type=\"reset\"]::-moz-focus-inner,\n[type=\"submit\"]::-moz-focus-inner {\n border-style: none;\n padding: 0;\n}\n\n/**\n * Restore the focus styles unset by the previous rule.\n */\n\nbutton:-moz-focusring,\n[type=\"button\"]:-moz-focusring,\n[type=\"reset\"]:-moz-focusring,\n[type=\"submit\"]:-moz-focusring {\n outline: 1px dotted ButtonText;\n}\n\n/**\n * Correct the padding in Firefox.\n */\n\nfieldset {\n padding: 0.35em 0.75em 0.625em;\n}\n\n/**\n * Show the overflow in Edge and IE.\n */\n\ninput {\n overflow: visible;\n}\n\n/**\n * 1. Correct the text wrapping in Edge and IE.\n * 2. Correct the color inheritance from `fieldset` elements in IE.\n * 3. Remove the padding so developers are not caught out when they zero out\n * `fieldset` elements in all browsers.\n */\n\nlegend {\n box-sizing: border-box; /* 1 */\n color: inherit; /* 2 */\n display: table; /* 1 */\n max-width: 100%; /* 1 */\n padding: 0; /* 3 */\n white-space: normal; /* 1 */\n}\n\n/**\n * 1. Add the correct display in Edge and IE.\n * 2. Add the correct vertical alignment in Chrome, Firefox, and Opera.\n */\n\nprogress {\n display: inline-block; /* 1 */\n vertical-align: baseline; /* 2 */\n}\n\n/**\n * Remove the inheritance of text transform in Firefox.\n */\n\nselect {\n text-transform: none;\n}\n\n/**\n * Remove the default vertical scrollbar in IE.\n */\n\ntextarea {\n overflow: auto;\n}\n\n/**\n * 1. Add the correct box sizing in IE 10-.\n * 2. Remove the padding in IE 10-.\n */\n\n[type=\"checkbox\"],\n[type=\"radio\"] {\n box-sizing: border-box; /* 1 */\n padding: 0; /* 2 */\n}\n\n/**\n * Correct the cursor style of increment and decrement buttons in Chrome.\n */\n\n[type=\"number\"]::-webkit-inner-spin-button,\n[type=\"number\"]::-webkit-outer-spin-button {\n height: auto;\n}\n\n/**\n * 1. Correct the odd appearance in Chrome and Safari.\n * 2. Correct the outline style in Safari.\n */\n\n[type=\"search\"] {\n -webkit-appearance: textfield; /* 1 */\n outline-offset: -2px; /* 2 */\n}\n\n/**\n * Remove the inner padding and cancel buttons in Chrome and Safari on macOS.\n */\n\n[type=\"search\"]::-webkit-search-cancel-button,\n[type=\"search\"]::-webkit-search-decoration {\n -webkit-appearance: none;\n}\n\n/**\n * 1. Correct the inability to style clickable types in iOS and Safari.\n * 2. Change font properties to `inherit` in Safari.\n */\n\n::-webkit-file-upload-button {\n -webkit-appearance: button; /* 1 */\n font: inherit; /* 2 */\n}\n\n/* Interactive\n ========================================================================== */\n\n/*\n * Add the correct display in Edge, Firefox 48-, and IE.\n */\n\ndetails {\n display: block;\n}\n\n/*\n * Add the correct display in all browsers.\n */\n\nsummary {\n display: list-item;\n}\n\n/* Scripting\n ========================================================================== */\n\n/**\n * Add the correct display in IE 9-.\n */\n\ncanvas {\n display: inline-block;\n}\n\n/**\n * Add the correct display in IE.\n */\n\ntemplate {\n display: none;\n}\n\n/* Hidden\n ========================================================================== */\n\n/**\n * Add the correct display in IE 10-.\n */\n\n[hidden] {\n display: none;\n}\n"} \ No newline at end of file diff --git a/package.json b/package.json index 75687ca812..189dcbc7a0 100644 --- a/package.json +++ b/package.json @@ -1,25 +1,22 @@ { "name": "postcss-normalize", - "version": "5.0.0", + "version": "6.0.0", "description": "Use the parts of normalize.css you need from your browserslist", "author": "Jonathan Neal ", "license": "CC0-1.0", - "repository": "jonathantneal/postcss-normalize", - "homepage": "https://github.com/jonathantneal/postcss-normalize#readme", - "bugs": "https://github.com/jonathantneal/postcss-normalize/issues", + "repository": "csstools/postcss-normalize", + "homepage": "https://github.com/csstools/postcss-normalize#readme", + "bugs": "https://github.com/csstools/postcss-normalize/issues", "main": "index.cjs.js", "module": "index.es.js", "files": [ "index.cjs.js", - "index.es.js", - "lib/normalize.js", - "lib/normalize.json" + "index.es.js" ], "scripts": { "prepublishOnly": "npm test", "pretest": "rollup -c .rollup.js --silent", - "test": "npm run test:init && npm run test:js && npm run test:tape", - "test:init": "node lib/normalize-init", + "test": "echo 'Running tests...'; npm run test:js && npm run test:tape", "test:js": "eslint *.js --cache --ignore-path .gitignore --quiet", "test:tape": "postcss-tape" }, @@ -27,8 +24,10 @@ "node": ">=6.0.0" }, "dependencies": { + "@csstools/normalize.css": "^8.0.0", "browserslist": "^3.2.8", - "postcss": "^6.0.22" + "postcss": "^6.0.22", + "postcss-browser-comments": "^1.0.0" }, "devDependencies": { "babel-core": "^6.26.3", @@ -36,10 +35,9 @@ "babel-preset-env": "^1.7.0", "eslint": "^4.19.1", "eslint-config-dev": "^2.0.0", - "fse": "^4.0.1", "postcss-tape": "^2.2.0", "pre-commit": "^1.2.2", - "rollup": "^0.60.0", + "rollup": "^0.60.7", "rollup-plugin-babel": "^3.0.4" }, "eslintConfig": { @@ -50,6 +48,8 @@ "postcss", "css", "postcss-plugin", - "normalize" + "normalizes", + "browsers", + "fixes" ] } diff --git a/test/basic.expect.css b/test/basic.expect.css index 7b123847fc..20e294d860 100644 --- a/test/basic.expect.css +++ b/test/basic.expect.css @@ -1,155 +1,327 @@ +/*! normalize.css v8.0.0 | MIT License | github.com/csstools/normalize.css */ + +/* Document + * ========================================================================== */ + +/** + * 1. Correct the line height in all browsers. + * 2. Prevent adjustments of font size after orientation changes in + * IE on Windows Phone and in iOS. + */ + html { - line-height: 1.15; - -ms-text-size-adjust: 100%; - -webkit-text-size-adjust: 100%; + line-height: 1.15; /* 1 */ + -ms-text-size-adjust: 100%; /* 2 */ + -webkit-text-size-adjust: 100%; /* 2 */ } +/* Sections + * ========================================================================== */ + +/** + * Correct the font size and margin on `h1` elements within `section` and + * `article` contexts in Chrome, Firefox, and Safari. + */ + h1 { - font-size: 2em; - margin: 0.67em 0; + font-size: 2em; + margin: 0.67em 0; } +/* Grouping content + * ========================================================================== */ + +/** + * 1. Add the correct box sizing in Firefox. + * 2. Show the overflow in Edge and IE. + */ + hr { - box-sizing: content-box; - height: 0; - overflow: visible; + box-sizing: content-box; /* 1 */ + height: 0; /* 1 */ + overflow: visible; /* 2 */ } +/** + * Add the correct display in IE. + */ + main { - display: block; + display: block; } +/** + * 1. Correct the inheritance and scaling of font size in all browsers. + * 2. Correct the odd `em` font sizing in all browsers. + */ + pre { - font-family: monospace, monospace; - font-size: 1em; + font-family: monospace, monospace; /* 1 */ + font-size: 1em; /* 2 */ } -a { - -webkit-text-decoration-skip: objects; -} +/* Text-level semantics + * ========================================================================== */ + +/** + * Add the correct text decoration in Edge, IE, Opera, and Safari. + */ abbr[title] { - text-decoration: underline; - text-decoration: underline dotted; + text-decoration: underline; + text-decoration: underline dotted; } +/** + * Add the correct font weight in Chrome, Edge, and Safari. + */ + b, strong { - font-weight: bolder; + font-weight: bolder; } +/** + * 1. Correct the inheritance and scaling of font size in all browsers. + * 2. Correct the odd `em` font sizing in all browsers. + */ + code, kbd, samp { - font-family: monospace, monospace; - font-size: 1em; + font-family: monospace, monospace; /* 1 */ + font-size: 1em; /* 2 */ } +/** + * Add the correct font size in all browsers. + */ + small { - font-size: 80%; + font-size: 80%; } +/* Embedded content + * ========================================================================== */ + +/** + * Hide the overflow in IE. + */ + svg:not(:root) { - overflow: hidden; + overflow: hidden; } +/* Forms + * ========================================================================== */ + +/** + * Remove the margin in Firefox and Safari. + */ + button, input, optgroup, select, textarea { - margin: 0; + margin: 0; } +/** + * 1. Show the overflow in IE. + * 2. Remove the inheritance of text transform in Edge, Firefox, and IE. + */ + button { - overflow: visible; - text-transform: none; + overflow: visible; /* 1 */ + text-transform: none; /* 2 */ } +/** + * Correct the inability to style clickable types in iOS and Safari. + */ + button, [type="button"], [type="reset"], [type="submit"] { - -webkit-appearance: button; + -webkit-appearance: button; } -button::-moz-focus-inner, -[type="button"]::-moz-focus-inner, -[type="reset"]::-moz-focus-inner, -[type="submit"]::-moz-focus-inner { - border-style: none; - padding: 0; +/** + * Remove the inner border and padding in Firefox. + */ + +::-moz-focus-inner { + border-style: none; + padding: 0; } +/** + * Restore the focus styles unset by the previous rule in Firefox. + */ + button:-moz-focusring, [type="button"]:-moz-focusring, [type="reset"]:-moz-focusring, [type="submit"]:-moz-focusring { - outline: 1px dotted ButtonText; + outline: 1px dotted ButtonText; } +/** + * Correct the padding in Firefox. + */ + fieldset { - padding: 0.35em 0.75em 0.625em; + padding: 0.35em 0.75em 0.625em; } +/** + * Show the overflow in Edge and IE. + */ + input { - overflow: visible; + overflow: visible; } +/** + * 1. Correct the text wrapping in Edge and IE. + * 2. Correct the color inheritance from `fieldset` elements in IE. + * 3. Remove the padding so developers are not caught out when they zero out + * `fieldset` elements in all browsers. + */ + legend { - box-sizing: border-box; - color: inherit; - display: table; - max-width: 100%; - padding: 0; - white-space: normal; + box-sizing: border-box; /* 1 */ + color: inherit; /* 2 */ + display: table; /* 1 */ + max-width: 100%; /* 1 */ + padding: 0; /* 3 */ + white-space: normal; /* 1 */ } +/** + * 1. Add the correct display in Edge and IE. + * 2. Add the correct vertical alignment in Chrome, Firefox, and Opera. + */ + progress { - display: inline-block; - vertical-align: baseline; + display: inline-block; /* 1 */ + vertical-align: baseline; /* 2 */ } +/** + * Remove the inheritance of text transform in Firefox. + */ + select { - text-transform: none; + text-transform: none; } +/** + * Remove the default vertical scrollbar in IE. + */ + textarea { - overflow: auto; + overflow: auto; } -[type="number"]::-webkit-inner-spin-button, -[type="number"]::-webkit-outer-spin-button { - height: auto; +/** + * Correct the cursor style of increment and decrement buttons in Chrome. + */ + +::-webkit-inner-spin-button, +::-webkit-outer-spin-button { + height: auto; } +/** + * 1. Correct the odd appearance in Chrome and Safari. + * 2. Correct the outline style in Safari. + */ + [type="search"] { - -webkit-appearance: textfield; - outline-offset: -2px; + -webkit-appearance: textfield; /* 1 */ + outline-offset: -2px; /* 2 */ } -[type="search"]::-webkit-search-cancel-button, -[type="search"]::-webkit-search-decoration { - -webkit-appearance: none; +/** + * Remove the inner padding in Chrome and Safari on macOS. + */ + +::-webkit-search-decoration { + -webkit-appearance: none; } +/** + * 1. Correct the inability to style clickable types in iOS and Safari. + * 2. Change font properties to `inherit` in Safari. + */ + ::-webkit-file-upload-button { - -webkit-appearance: button; - font: inherit; + -webkit-appearance: button; /* 1 */ + font: inherit; /* 2 */ } +/* Interactive + * ========================================================================== */ + +/* + * Add the correct display in Edge and IE. + */ + details { - display: block; + display: block; +} + +/* + * Add the correct styles in Edge, IE, and Safari. + */ + +dialog { + background-color: white; + border: solid; + color: black; + display: block; + height: -moz-fit-content; + height: -webkit-fit-content; + height: fit-content; + left: 0; + margin: auto; + padding: 1em; + position: absolute; + right: 0; + width: -moz-fit-content; + width: -webkit-fit-content; + width: fit-content; +} + +dialog:not([open]) { + display: none; } +/* + * Add the correct display in all browsers. + */ + summary { - display: list-item; + display: list-item; } +/* Scripting + * ========================================================================== */ + +/** + * Add the correct display in IE. + */ + template { - display: none; + display: none; } +/* User interaction + * ========================================================================== */ + body { font-family: sans-serif; } diff --git a/test/basic.last-1.expect.css b/test/basic.last-1.expect.css index 7b123847fc..20e294d860 100644 --- a/test/basic.last-1.expect.css +++ b/test/basic.last-1.expect.css @@ -1,155 +1,327 @@ +/*! normalize.css v8.0.0 | MIT License | github.com/csstools/normalize.css */ + +/* Document + * ========================================================================== */ + +/** + * 1. Correct the line height in all browsers. + * 2. Prevent adjustments of font size after orientation changes in + * IE on Windows Phone and in iOS. + */ + html { - line-height: 1.15; - -ms-text-size-adjust: 100%; - -webkit-text-size-adjust: 100%; + line-height: 1.15; /* 1 */ + -ms-text-size-adjust: 100%; /* 2 */ + -webkit-text-size-adjust: 100%; /* 2 */ } +/* Sections + * ========================================================================== */ + +/** + * Correct the font size and margin on `h1` elements within `section` and + * `article` contexts in Chrome, Firefox, and Safari. + */ + h1 { - font-size: 2em; - margin: 0.67em 0; + font-size: 2em; + margin: 0.67em 0; } +/* Grouping content + * ========================================================================== */ + +/** + * 1. Add the correct box sizing in Firefox. + * 2. Show the overflow in Edge and IE. + */ + hr { - box-sizing: content-box; - height: 0; - overflow: visible; + box-sizing: content-box; /* 1 */ + height: 0; /* 1 */ + overflow: visible; /* 2 */ } +/** + * Add the correct display in IE. + */ + main { - display: block; + display: block; } +/** + * 1. Correct the inheritance and scaling of font size in all browsers. + * 2. Correct the odd `em` font sizing in all browsers. + */ + pre { - font-family: monospace, monospace; - font-size: 1em; + font-family: monospace, monospace; /* 1 */ + font-size: 1em; /* 2 */ } -a { - -webkit-text-decoration-skip: objects; -} +/* Text-level semantics + * ========================================================================== */ + +/** + * Add the correct text decoration in Edge, IE, Opera, and Safari. + */ abbr[title] { - text-decoration: underline; - text-decoration: underline dotted; + text-decoration: underline; + text-decoration: underline dotted; } +/** + * Add the correct font weight in Chrome, Edge, and Safari. + */ + b, strong { - font-weight: bolder; + font-weight: bolder; } +/** + * 1. Correct the inheritance and scaling of font size in all browsers. + * 2. Correct the odd `em` font sizing in all browsers. + */ + code, kbd, samp { - font-family: monospace, monospace; - font-size: 1em; + font-family: monospace, monospace; /* 1 */ + font-size: 1em; /* 2 */ } +/** + * Add the correct font size in all browsers. + */ + small { - font-size: 80%; + font-size: 80%; } +/* Embedded content + * ========================================================================== */ + +/** + * Hide the overflow in IE. + */ + svg:not(:root) { - overflow: hidden; + overflow: hidden; } +/* Forms + * ========================================================================== */ + +/** + * Remove the margin in Firefox and Safari. + */ + button, input, optgroup, select, textarea { - margin: 0; + margin: 0; } +/** + * 1. Show the overflow in IE. + * 2. Remove the inheritance of text transform in Edge, Firefox, and IE. + */ + button { - overflow: visible; - text-transform: none; + overflow: visible; /* 1 */ + text-transform: none; /* 2 */ } +/** + * Correct the inability to style clickable types in iOS and Safari. + */ + button, [type="button"], [type="reset"], [type="submit"] { - -webkit-appearance: button; + -webkit-appearance: button; } -button::-moz-focus-inner, -[type="button"]::-moz-focus-inner, -[type="reset"]::-moz-focus-inner, -[type="submit"]::-moz-focus-inner { - border-style: none; - padding: 0; +/** + * Remove the inner border and padding in Firefox. + */ + +::-moz-focus-inner { + border-style: none; + padding: 0; } +/** + * Restore the focus styles unset by the previous rule in Firefox. + */ + button:-moz-focusring, [type="button"]:-moz-focusring, [type="reset"]:-moz-focusring, [type="submit"]:-moz-focusring { - outline: 1px dotted ButtonText; + outline: 1px dotted ButtonText; } +/** + * Correct the padding in Firefox. + */ + fieldset { - padding: 0.35em 0.75em 0.625em; + padding: 0.35em 0.75em 0.625em; } +/** + * Show the overflow in Edge and IE. + */ + input { - overflow: visible; + overflow: visible; } +/** + * 1. Correct the text wrapping in Edge and IE. + * 2. Correct the color inheritance from `fieldset` elements in IE. + * 3. Remove the padding so developers are not caught out when they zero out + * `fieldset` elements in all browsers. + */ + legend { - box-sizing: border-box; - color: inherit; - display: table; - max-width: 100%; - padding: 0; - white-space: normal; + box-sizing: border-box; /* 1 */ + color: inherit; /* 2 */ + display: table; /* 1 */ + max-width: 100%; /* 1 */ + padding: 0; /* 3 */ + white-space: normal; /* 1 */ } +/** + * 1. Add the correct display in Edge and IE. + * 2. Add the correct vertical alignment in Chrome, Firefox, and Opera. + */ + progress { - display: inline-block; - vertical-align: baseline; + display: inline-block; /* 1 */ + vertical-align: baseline; /* 2 */ } +/** + * Remove the inheritance of text transform in Firefox. + */ + select { - text-transform: none; + text-transform: none; } +/** + * Remove the default vertical scrollbar in IE. + */ + textarea { - overflow: auto; + overflow: auto; } -[type="number"]::-webkit-inner-spin-button, -[type="number"]::-webkit-outer-spin-button { - height: auto; +/** + * Correct the cursor style of increment and decrement buttons in Chrome. + */ + +::-webkit-inner-spin-button, +::-webkit-outer-spin-button { + height: auto; } +/** + * 1. Correct the odd appearance in Chrome and Safari. + * 2. Correct the outline style in Safari. + */ + [type="search"] { - -webkit-appearance: textfield; - outline-offset: -2px; + -webkit-appearance: textfield; /* 1 */ + outline-offset: -2px; /* 2 */ } -[type="search"]::-webkit-search-cancel-button, -[type="search"]::-webkit-search-decoration { - -webkit-appearance: none; +/** + * Remove the inner padding in Chrome and Safari on macOS. + */ + +::-webkit-search-decoration { + -webkit-appearance: none; } +/** + * 1. Correct the inability to style clickable types in iOS and Safari. + * 2. Change font properties to `inherit` in Safari. + */ + ::-webkit-file-upload-button { - -webkit-appearance: button; - font: inherit; + -webkit-appearance: button; /* 1 */ + font: inherit; /* 2 */ } +/* Interactive + * ========================================================================== */ + +/* + * Add the correct display in Edge and IE. + */ + details { - display: block; + display: block; +} + +/* + * Add the correct styles in Edge, IE, and Safari. + */ + +dialog { + background-color: white; + border: solid; + color: black; + display: block; + height: -moz-fit-content; + height: -webkit-fit-content; + height: fit-content; + left: 0; + margin: auto; + padding: 1em; + position: absolute; + right: 0; + width: -moz-fit-content; + width: -webkit-fit-content; + width: fit-content; +} + +dialog:not([open]) { + display: none; } +/* + * Add the correct display in all browsers. + */ + summary { - display: list-item; + display: list-item; } +/* Scripting + * ========================================================================== */ + +/** + * Add the correct display in IE. + */ + template { - display: none; + display: none; } +/* User interaction + * ========================================================================== */ + body { font-family: sans-serif; } diff --git a/test/basic.last-2.expect.css b/test/basic.last-2.expect.css index 6ef7a7ce2b..1d08211fdb 100644 --- a/test/basic.last-2.expect.css +++ b/test/basic.last-2.expect.css @@ -1,168 +1,360 @@ +/*! normalize.css v8.0.0 | MIT License | github.com/csstools/normalize.css */ + +/* Document + * ========================================================================== */ + +/** + * 1. Correct the line height in all browsers. + * 2. Prevent adjustments of font size after orientation changes in + * IE on Windows Phone and in iOS. + */ + html { - line-height: 1.15; - -ms-text-size-adjust: 100%; - -webkit-text-size-adjust: 100%; + line-height: 1.15; /* 1 */ + -ms-text-size-adjust: 100%; /* 2 */ + -webkit-text-size-adjust: 100%; /* 2 */ } +/* Sections + * ========================================================================== */ + +/** + * Correct the font size and margin on `h1` elements within `section` and + * `article` contexts in Chrome, Firefox, and Safari. + */ + h1 { - font-size: 2em; - margin: 0.67em 0; + font-size: 2em; + margin: 0.67em 0; } +/* Grouping content + * ========================================================================== */ + +/** + * 1. Add the correct box sizing in Firefox. + * 2. Show the overflow in Edge and IE. + */ + hr { - box-sizing: content-box; - height: 0; - overflow: visible; + box-sizing: content-box; /* 1 */ + height: 0; /* 1 */ + overflow: visible; /* 2 */ } +/** + * Add the correct display in IE. + */ + main { - display: block; + display: block; } +/** + * 1. Correct the inheritance and scaling of font size in all browsers. + * 2. Correct the odd `em` font sizing in all browsers. + */ + pre { - font-family: monospace, monospace; - font-size: 1em; + font-family: monospace, monospace; /* 1 */ + font-size: 1em; /* 2 */ } +/* Text-level semantics + * ========================================================================== */ + +/** + * Remove the gray background on active links in IE 10. + */ + a { - background-color: transparent; - -webkit-text-decoration-skip: objects; + background-color: transparent; /* 1 */ } +/** + * Add the correct text decoration in Edge, IE, Opera, and Safari. + */ + abbr[title] { - text-decoration: underline; - text-decoration: underline dotted; + text-decoration: underline; + text-decoration: underline dotted; } +/** + * Add the correct font weight in Chrome, Edge, and Safari. + */ + b, strong { - font-weight: bolder; + font-weight: bolder; } +/** + * 1. Correct the inheritance and scaling of font size in all browsers. + * 2. Correct the odd `em` font sizing in all browsers. + */ + code, kbd, samp { - font-family: monospace, monospace; - font-size: 1em; + font-family: monospace, monospace; /* 1 */ + font-size: 1em; /* 2 */ } +/** + * Add the correct font size in all browsers. + */ + small { - font-size: 80%; + font-size: 80%; } +/* Embedded content + * ========================================================================== */ + +/** + * Remove the border on images inside links in IE 10-. + */ + img { - border-style: none; + border-style: none; } +/** + * Hide the overflow in IE. + */ + svg:not(:root) { - overflow: hidden; + overflow: hidden; } +/* Forms + * ========================================================================== */ + +/** + * Remove the margin in Firefox and Safari. + */ + button, input, optgroup, select, textarea { - margin: 0; + margin: 0; } +/** + * 1. Show the overflow in IE. + * 2. Remove the inheritance of text transform in Edge, Firefox, and IE. + */ + button { - overflow: visible; - text-transform: none; + overflow: visible; /* 1 */ + text-transform: none; /* 2 */ } +/** + * Correct the inability to style clickable types in iOS and Safari. + */ + button, [type="button"], [type="reset"], [type="submit"] { - -webkit-appearance: button; + -webkit-appearance: button; } -button::-moz-focus-inner, -[type="button"]::-moz-focus-inner, -[type="reset"]::-moz-focus-inner, -[type="submit"]::-moz-focus-inner { - border-style: none; - padding: 0; +/** + * Remove the inner border and padding in Firefox. + */ + +::-moz-focus-inner { + border-style: none; + padding: 0; } +/** + * Restore the focus styles unset by the previous rule in Firefox. + */ + button:-moz-focusring, [type="button"]:-moz-focusring, [type="reset"]:-moz-focusring, [type="submit"]:-moz-focusring { - outline: 1px dotted ButtonText; + outline: 1px dotted ButtonText; } +/** + * Correct the padding in Firefox. + */ + fieldset { - padding: 0.35em 0.75em 0.625em; + padding: 0.35em 0.75em 0.625em; } +/** + * Show the overflow in Edge and IE. + */ + input { - overflow: visible; + overflow: visible; } +/** + * 1. Correct the text wrapping in Edge and IE. + * 2. Correct the color inheritance from `fieldset` elements in IE. + * 3. Remove the padding so developers are not caught out when they zero out + * `fieldset` elements in all browsers. + */ + legend { - box-sizing: border-box; - color: inherit; - display: table; - max-width: 100%; - padding: 0; - white-space: normal; + box-sizing: border-box; /* 1 */ + color: inherit; /* 2 */ + display: table; /* 1 */ + max-width: 100%; /* 1 */ + padding: 0; /* 3 */ + white-space: normal; /* 1 */ } +/** + * 1. Add the correct display in Edge and IE. + * 2. Add the correct vertical alignment in Chrome, Firefox, and Opera. + */ + progress { - display: inline-block; - vertical-align: baseline; + display: inline-block; /* 1 */ + vertical-align: baseline; /* 2 */ } +/** + * Remove the inheritance of text transform in Firefox. + */ + select { - text-transform: none; + text-transform: none; } +/** + * Remove the default vertical scrollbar in IE. + */ + textarea { - overflow: auto; + overflow: auto; } +/** + * 1. Add the correct box sizing in IE 10-. + * 2. Remove the padding in IE 10-. + */ + [type="checkbox"], [type="radio"] { - box-sizing: border-box; - padding: 0; + box-sizing: border-box; /* 1 */ + padding: 0; /* 2 */ } -[type="number"]::-webkit-inner-spin-button, -[type="number"]::-webkit-outer-spin-button { - height: auto; +/** + * Correct the cursor style of increment and decrement buttons in Chrome. + */ + +::-webkit-inner-spin-button, +::-webkit-outer-spin-button { + height: auto; } +/** + * 1. Correct the odd appearance in Chrome and Safari. + * 2. Correct the outline style in Safari. + */ + [type="search"] { - -webkit-appearance: textfield; - outline-offset: -2px; + -webkit-appearance: textfield; /* 1 */ + outline-offset: -2px; /* 2 */ } -[type="search"]::-webkit-search-cancel-button, -[type="search"]::-webkit-search-decoration { - -webkit-appearance: none; +/** + * Remove the inner padding in Chrome and Safari on macOS. + */ + +::-webkit-search-decoration { + -webkit-appearance: none; } +/** + * 1. Correct the inability to style clickable types in iOS and Safari. + * 2. Change font properties to `inherit` in Safari. + */ + ::-webkit-file-upload-button { - -webkit-appearance: button; - font: inherit; + -webkit-appearance: button; /* 1 */ + font: inherit; /* 2 */ } +/* Interactive + * ========================================================================== */ + +/* + * Add the correct display in Edge and IE. + */ + details { - display: block; + display: block; +} + +/* + * Add the correct styles in Edge, IE, and Safari. + */ + +dialog { + background-color: white; + border: solid; + color: black; + display: block; + height: -moz-fit-content; + height: -webkit-fit-content; + height: fit-content; + left: 0; + margin: auto; + padding: 1em; + position: absolute; + right: 0; + width: -moz-fit-content; + width: -webkit-fit-content; + width: fit-content; +} + +dialog:not([open]) { + display: none; } +/* + * Add the correct display in all browsers. + */ + summary { - display: list-item; + display: list-item; } +/* Scripting + * ========================================================================== */ + +/** + * Add the correct display in IE. + */ + template { - display: none; + display: none; } +/* User interaction + * ========================================================================== */ + +/** + * Add the correct display in IE 10-. + */ + [hidden] { - display: none; + display: none; } body { diff --git a/test/insertion-after.expect.css b/test/insertion-after.expect.css index 2a102e5ef0..ef9b4f6a9b 100644 --- a/test/insertion-after.expect.css +++ b/test/insertion-after.expect.css @@ -2,154 +2,326 @@ body { font-family: sans-serif; } +/*! normalize.css v8.0.0 | MIT License | github.com/csstools/normalize.css */ + +/* Document + * ========================================================================== */ + +/** + * 1. Correct the line height in all browsers. + * 2. Prevent adjustments of font size after orientation changes in + * IE on Windows Phone and in iOS. + */ + html { - line-height: 1.15; - -ms-text-size-adjust: 100%; - -webkit-text-size-adjust: 100%; + line-height: 1.15; /* 1 */ + -ms-text-size-adjust: 100%; /* 2 */ + -webkit-text-size-adjust: 100%; /* 2 */ } +/* Sections + * ========================================================================== */ + +/** + * Correct the font size and margin on `h1` elements within `section` and + * `article` contexts in Chrome, Firefox, and Safari. + */ + h1 { - font-size: 2em; - margin: 0.67em 0; + font-size: 2em; + margin: 0.67em 0; } +/* Grouping content + * ========================================================================== */ + +/** + * 1. Add the correct box sizing in Firefox. + * 2. Show the overflow in Edge and IE. + */ + hr { - box-sizing: content-box; - height: 0; - overflow: visible; + box-sizing: content-box; /* 1 */ + height: 0; /* 1 */ + overflow: visible; /* 2 */ } +/** + * Add the correct display in IE. + */ + main { - display: block; + display: block; } +/** + * 1. Correct the inheritance and scaling of font size in all browsers. + * 2. Correct the odd `em` font sizing in all browsers. + */ + pre { - font-family: monospace, monospace; - font-size: 1em; + font-family: monospace, monospace; /* 1 */ + font-size: 1em; /* 2 */ } -a { - -webkit-text-decoration-skip: objects; -} +/* Text-level semantics + * ========================================================================== */ + +/** + * Add the correct text decoration in Edge, IE, Opera, and Safari. + */ abbr[title] { - text-decoration: underline; - text-decoration: underline dotted; + text-decoration: underline; + text-decoration: underline dotted; } +/** + * Add the correct font weight in Chrome, Edge, and Safari. + */ + b, strong { - font-weight: bolder; + font-weight: bolder; } +/** + * 1. Correct the inheritance and scaling of font size in all browsers. + * 2. Correct the odd `em` font sizing in all browsers. + */ + code, kbd, samp { - font-family: monospace, monospace; - font-size: 1em; + font-family: monospace, monospace; /* 1 */ + font-size: 1em; /* 2 */ } +/** + * Add the correct font size in all browsers. + */ + small { - font-size: 80%; + font-size: 80%; } +/* Embedded content + * ========================================================================== */ + +/** + * Hide the overflow in IE. + */ + svg:not(:root) { - overflow: hidden; + overflow: hidden; } +/* Forms + * ========================================================================== */ + +/** + * Remove the margin in Firefox and Safari. + */ + button, input, optgroup, select, textarea { - margin: 0; + margin: 0; } +/** + * 1. Show the overflow in IE. + * 2. Remove the inheritance of text transform in Edge, Firefox, and IE. + */ + button { - overflow: visible; - text-transform: none; + overflow: visible; /* 1 */ + text-transform: none; /* 2 */ } +/** + * Correct the inability to style clickable types in iOS and Safari. + */ + button, [type="button"], [type="reset"], [type="submit"] { - -webkit-appearance: button; + -webkit-appearance: button; } -button::-moz-focus-inner, -[type="button"]::-moz-focus-inner, -[type="reset"]::-moz-focus-inner, -[type="submit"]::-moz-focus-inner { - border-style: none; - padding: 0; +/** + * Remove the inner border and padding in Firefox. + */ + +::-moz-focus-inner { + border-style: none; + padding: 0; } +/** + * Restore the focus styles unset by the previous rule in Firefox. + */ + button:-moz-focusring, [type="button"]:-moz-focusring, [type="reset"]:-moz-focusring, [type="submit"]:-moz-focusring { - outline: 1px dotted ButtonText; + outline: 1px dotted ButtonText; } +/** + * Correct the padding in Firefox. + */ + fieldset { - padding: 0.35em 0.75em 0.625em; + padding: 0.35em 0.75em 0.625em; } +/** + * Show the overflow in Edge and IE. + */ + input { - overflow: visible; + overflow: visible; } +/** + * 1. Correct the text wrapping in Edge and IE. + * 2. Correct the color inheritance from `fieldset` elements in IE. + * 3. Remove the padding so developers are not caught out when they zero out + * `fieldset` elements in all browsers. + */ + legend { - box-sizing: border-box; - color: inherit; - display: table; - max-width: 100%; - padding: 0; - white-space: normal; + box-sizing: border-box; /* 1 */ + color: inherit; /* 2 */ + display: table; /* 1 */ + max-width: 100%; /* 1 */ + padding: 0; /* 3 */ + white-space: normal; /* 1 */ } +/** + * 1. Add the correct display in Edge and IE. + * 2. Add the correct vertical alignment in Chrome, Firefox, and Opera. + */ + progress { - display: inline-block; - vertical-align: baseline; + display: inline-block; /* 1 */ + vertical-align: baseline; /* 2 */ } +/** + * Remove the inheritance of text transform in Firefox. + */ + select { - text-transform: none; + text-transform: none; } +/** + * Remove the default vertical scrollbar in IE. + */ + textarea { - overflow: auto; + overflow: auto; } -[type="number"]::-webkit-inner-spin-button, -[type="number"]::-webkit-outer-spin-button { - height: auto; +/** + * Correct the cursor style of increment and decrement buttons in Chrome. + */ + +::-webkit-inner-spin-button, +::-webkit-outer-spin-button { + height: auto; } +/** + * 1. Correct the odd appearance in Chrome and Safari. + * 2. Correct the outline style in Safari. + */ + [type="search"] { - -webkit-appearance: textfield; - outline-offset: -2px; + -webkit-appearance: textfield; /* 1 */ + outline-offset: -2px; /* 2 */ } -[type="search"]::-webkit-search-cancel-button, -[type="search"]::-webkit-search-decoration { - -webkit-appearance: none; +/** + * Remove the inner padding in Chrome and Safari on macOS. + */ + +::-webkit-search-decoration { + -webkit-appearance: none; } +/** + * 1. Correct the inability to style clickable types in iOS and Safari. + * 2. Change font properties to `inherit` in Safari. + */ + ::-webkit-file-upload-button { - -webkit-appearance: button; - font: inherit; + -webkit-appearance: button; /* 1 */ + font: inherit; /* 2 */ } +/* Interactive + * ========================================================================== */ + +/* + * Add the correct display in Edge and IE. + */ + details { - display: block; + display: block; +} + +/* + * Add the correct styles in Edge, IE, and Safari. + */ + +dialog { + background-color: white; + border: solid; + color: black; + display: block; + height: -moz-fit-content; + height: -webkit-fit-content; + height: fit-content; + left: 0; + margin: auto; + padding: 1em; + position: absolute; + right: 0; + width: -moz-fit-content; + width: -webkit-fit-content; + width: fit-content; +} + +dialog:not([open]) { + display: none; } +/* + * Add the correct display in all browsers. + */ + summary { - display: list-item; + display: list-item; } +/* Scripting + * ========================================================================== */ + +/** + * Add the correct display in IE. + */ + template { - display: none; + display: none; } + +/* User interaction + * ========================================================================== */ diff --git a/test/insertion-duplicate.expect.css b/test/insertion-duplicate.expect.css index 7b123847fc..20e294d860 100644 --- a/test/insertion-duplicate.expect.css +++ b/test/insertion-duplicate.expect.css @@ -1,155 +1,327 @@ +/*! normalize.css v8.0.0 | MIT License | github.com/csstools/normalize.css */ + +/* Document + * ========================================================================== */ + +/** + * 1. Correct the line height in all browsers. + * 2. Prevent adjustments of font size after orientation changes in + * IE on Windows Phone and in iOS. + */ + html { - line-height: 1.15; - -ms-text-size-adjust: 100%; - -webkit-text-size-adjust: 100%; + line-height: 1.15; /* 1 */ + -ms-text-size-adjust: 100%; /* 2 */ + -webkit-text-size-adjust: 100%; /* 2 */ } +/* Sections + * ========================================================================== */ + +/** + * Correct the font size and margin on `h1` elements within `section` and + * `article` contexts in Chrome, Firefox, and Safari. + */ + h1 { - font-size: 2em; - margin: 0.67em 0; + font-size: 2em; + margin: 0.67em 0; } +/* Grouping content + * ========================================================================== */ + +/** + * 1. Add the correct box sizing in Firefox. + * 2. Show the overflow in Edge and IE. + */ + hr { - box-sizing: content-box; - height: 0; - overflow: visible; + box-sizing: content-box; /* 1 */ + height: 0; /* 1 */ + overflow: visible; /* 2 */ } +/** + * Add the correct display in IE. + */ + main { - display: block; + display: block; } +/** + * 1. Correct the inheritance and scaling of font size in all browsers. + * 2. Correct the odd `em` font sizing in all browsers. + */ + pre { - font-family: monospace, monospace; - font-size: 1em; + font-family: monospace, monospace; /* 1 */ + font-size: 1em; /* 2 */ } -a { - -webkit-text-decoration-skip: objects; -} +/* Text-level semantics + * ========================================================================== */ + +/** + * Add the correct text decoration in Edge, IE, Opera, and Safari. + */ abbr[title] { - text-decoration: underline; - text-decoration: underline dotted; + text-decoration: underline; + text-decoration: underline dotted; } +/** + * Add the correct font weight in Chrome, Edge, and Safari. + */ + b, strong { - font-weight: bolder; + font-weight: bolder; } +/** + * 1. Correct the inheritance and scaling of font size in all browsers. + * 2. Correct the odd `em` font sizing in all browsers. + */ + code, kbd, samp { - font-family: monospace, monospace; - font-size: 1em; + font-family: monospace, monospace; /* 1 */ + font-size: 1em; /* 2 */ } +/** + * Add the correct font size in all browsers. + */ + small { - font-size: 80%; + font-size: 80%; } +/* Embedded content + * ========================================================================== */ + +/** + * Hide the overflow in IE. + */ + svg:not(:root) { - overflow: hidden; + overflow: hidden; } +/* Forms + * ========================================================================== */ + +/** + * Remove the margin in Firefox and Safari. + */ + button, input, optgroup, select, textarea { - margin: 0; + margin: 0; } +/** + * 1. Show the overflow in IE. + * 2. Remove the inheritance of text transform in Edge, Firefox, and IE. + */ + button { - overflow: visible; - text-transform: none; + overflow: visible; /* 1 */ + text-transform: none; /* 2 */ } +/** + * Correct the inability to style clickable types in iOS and Safari. + */ + button, [type="button"], [type="reset"], [type="submit"] { - -webkit-appearance: button; + -webkit-appearance: button; } -button::-moz-focus-inner, -[type="button"]::-moz-focus-inner, -[type="reset"]::-moz-focus-inner, -[type="submit"]::-moz-focus-inner { - border-style: none; - padding: 0; +/** + * Remove the inner border and padding in Firefox. + */ + +::-moz-focus-inner { + border-style: none; + padding: 0; } +/** + * Restore the focus styles unset by the previous rule in Firefox. + */ + button:-moz-focusring, [type="button"]:-moz-focusring, [type="reset"]:-moz-focusring, [type="submit"]:-moz-focusring { - outline: 1px dotted ButtonText; + outline: 1px dotted ButtonText; } +/** + * Correct the padding in Firefox. + */ + fieldset { - padding: 0.35em 0.75em 0.625em; + padding: 0.35em 0.75em 0.625em; } +/** + * Show the overflow in Edge and IE. + */ + input { - overflow: visible; + overflow: visible; } +/** + * 1. Correct the text wrapping in Edge and IE. + * 2. Correct the color inheritance from `fieldset` elements in IE. + * 3. Remove the padding so developers are not caught out when they zero out + * `fieldset` elements in all browsers. + */ + legend { - box-sizing: border-box; - color: inherit; - display: table; - max-width: 100%; - padding: 0; - white-space: normal; + box-sizing: border-box; /* 1 */ + color: inherit; /* 2 */ + display: table; /* 1 */ + max-width: 100%; /* 1 */ + padding: 0; /* 3 */ + white-space: normal; /* 1 */ } +/** + * 1. Add the correct display in Edge and IE. + * 2. Add the correct vertical alignment in Chrome, Firefox, and Opera. + */ + progress { - display: inline-block; - vertical-align: baseline; + display: inline-block; /* 1 */ + vertical-align: baseline; /* 2 */ } +/** + * Remove the inheritance of text transform in Firefox. + */ + select { - text-transform: none; + text-transform: none; } +/** + * Remove the default vertical scrollbar in IE. + */ + textarea { - overflow: auto; + overflow: auto; } -[type="number"]::-webkit-inner-spin-button, -[type="number"]::-webkit-outer-spin-button { - height: auto; +/** + * Correct the cursor style of increment and decrement buttons in Chrome. + */ + +::-webkit-inner-spin-button, +::-webkit-outer-spin-button { + height: auto; } +/** + * 1. Correct the odd appearance in Chrome and Safari. + * 2. Correct the outline style in Safari. + */ + [type="search"] { - -webkit-appearance: textfield; - outline-offset: -2px; + -webkit-appearance: textfield; /* 1 */ + outline-offset: -2px; /* 2 */ } -[type="search"]::-webkit-search-cancel-button, -[type="search"]::-webkit-search-decoration { - -webkit-appearance: none; +/** + * Remove the inner padding in Chrome and Safari on macOS. + */ + +::-webkit-search-decoration { + -webkit-appearance: none; } +/** + * 1. Correct the inability to style clickable types in iOS and Safari. + * 2. Change font properties to `inherit` in Safari. + */ + ::-webkit-file-upload-button { - -webkit-appearance: button; - font: inherit; + -webkit-appearance: button; /* 1 */ + font: inherit; /* 2 */ } +/* Interactive + * ========================================================================== */ + +/* + * Add the correct display in Edge and IE. + */ + details { - display: block; + display: block; +} + +/* + * Add the correct styles in Edge, IE, and Safari. + */ + +dialog { + background-color: white; + border: solid; + color: black; + display: block; + height: -moz-fit-content; + height: -webkit-fit-content; + height: fit-content; + left: 0; + margin: auto; + padding: 1em; + position: absolute; + right: 0; + width: -moz-fit-content; + width: -webkit-fit-content; + width: fit-content; +} + +dialog:not([open]) { + display: none; } +/* + * Add the correct display in all browsers. + */ + summary { - display: list-item; + display: list-item; } +/* Scripting + * ========================================================================== */ + +/** + * Add the correct display in IE. + */ + template { - display: none; + display: none; } +/* User interaction + * ========================================================================== */ + body { font-family: sans-serif; } diff --git a/test/option-force-import.expect.css b/test/option-force-import.expect.css index 03c7093e75..20e294d860 100644 --- a/test/option-force-import.expect.css +++ b/test/option-force-import.expect.css @@ -1,126 +1,327 @@ +/*! normalize.css v8.0.0 | MIT License | github.com/csstools/normalize.css */ + +/* Document + * ========================================================================== */ + +/** + * 1. Correct the line height in all browsers. + * 2. Prevent adjustments of font size after orientation changes in + * IE on Windows Phone and in iOS. + */ + html { - line-height: 1.15; - -ms-text-size-adjust: 100%; - -webkit-text-size-adjust: 100%; + line-height: 1.15; /* 1 */ + -ms-text-size-adjust: 100%; /* 2 */ + -webkit-text-size-adjust: 100%; /* 2 */ } + +/* Sections + * ========================================================================== */ + +/** + * Correct the font size and margin on `h1` elements within `section` and + * `article` contexts in Chrome, Firefox, and Safari. + */ + h1 { - font-size: 2em; - margin: 0.67em 0; + font-size: 2em; + margin: 0.67em 0; } + +/* Grouping content + * ========================================================================== */ + +/** + * 1. Add the correct box sizing in Firefox. + * 2. Show the overflow in Edge and IE. + */ + hr { - box-sizing: content-box; - height: 0; - overflow: visible; + box-sizing: content-box; /* 1 */ + height: 0; /* 1 */ + overflow: visible; /* 2 */ } + +/** + * Add the correct display in IE. + */ + main { - display: block; + display: block; } + +/** + * 1. Correct the inheritance and scaling of font size in all browsers. + * 2. Correct the odd `em` font sizing in all browsers. + */ + pre { - font-family: monospace, monospace; - font-size: 1em; -} -a { - -webkit-text-decoration-skip: objects; + font-family: monospace, monospace; /* 1 */ + font-size: 1em; /* 2 */ } + +/* Text-level semantics + * ========================================================================== */ + +/** + * Add the correct text decoration in Edge, IE, Opera, and Safari. + */ + abbr[title] { - text-decoration: underline; - text-decoration: underline dotted; + text-decoration: underline; + text-decoration: underline dotted; } + +/** + * Add the correct font weight in Chrome, Edge, and Safari. + */ + b, strong { - font-weight: bolder; + font-weight: bolder; } + +/** + * 1. Correct the inheritance and scaling of font size in all browsers. + * 2. Correct the odd `em` font sizing in all browsers. + */ + code, kbd, samp { - font-family: monospace, monospace; - font-size: 1em; + font-family: monospace, monospace; /* 1 */ + font-size: 1em; /* 2 */ } + +/** + * Add the correct font size in all browsers. + */ + small { - font-size: 80%; + font-size: 80%; } + +/* Embedded content + * ========================================================================== */ + +/** + * Hide the overflow in IE. + */ + svg:not(:root) { - overflow: hidden; + overflow: hidden; } + +/* Forms + * ========================================================================== */ + +/** + * Remove the margin in Firefox and Safari. + */ + button, input, optgroup, select, textarea { - margin: 0; + margin: 0; } + +/** + * 1. Show the overflow in IE. + * 2. Remove the inheritance of text transform in Edge, Firefox, and IE. + */ + button { - overflow: visible; - text-transform: none; + overflow: visible; /* 1 */ + text-transform: none; /* 2 */ } + +/** + * Correct the inability to style clickable types in iOS and Safari. + */ + button, [type="button"], [type="reset"], [type="submit"] { - -webkit-appearance: button; + -webkit-appearance: button; } -button::-moz-focus-inner, -[type="button"]::-moz-focus-inner, -[type="reset"]::-moz-focus-inner, -[type="submit"]::-moz-focus-inner { - border-style: none; - padding: 0; + +/** + * Remove the inner border and padding in Firefox. + */ + +::-moz-focus-inner { + border-style: none; + padding: 0; } + +/** + * Restore the focus styles unset by the previous rule in Firefox. + */ + button:-moz-focusring, [type="button"]:-moz-focusring, [type="reset"]:-moz-focusring, [type="submit"]:-moz-focusring { - outline: 1px dotted ButtonText; + outline: 1px dotted ButtonText; } + +/** + * Correct the padding in Firefox. + */ + fieldset { - padding: 0.35em 0.75em 0.625em; + padding: 0.35em 0.75em 0.625em; } + +/** + * Show the overflow in Edge and IE. + */ + input { - overflow: visible; + overflow: visible; } + +/** + * 1. Correct the text wrapping in Edge and IE. + * 2. Correct the color inheritance from `fieldset` elements in IE. + * 3. Remove the padding so developers are not caught out when they zero out + * `fieldset` elements in all browsers. + */ + legend { - box-sizing: border-box; - color: inherit; - display: table; - max-width: 100%; - padding: 0; - white-space: normal; + box-sizing: border-box; /* 1 */ + color: inherit; /* 2 */ + display: table; /* 1 */ + max-width: 100%; /* 1 */ + padding: 0; /* 3 */ + white-space: normal; /* 1 */ } + +/** + * 1. Add the correct display in Edge and IE. + * 2. Add the correct vertical alignment in Chrome, Firefox, and Opera. + */ + progress { - display: inline-block; - vertical-align: baseline; + display: inline-block; /* 1 */ + vertical-align: baseline; /* 2 */ } + +/** + * Remove the inheritance of text transform in Firefox. + */ + select { - text-transform: none; + text-transform: none; } + +/** + * Remove the default vertical scrollbar in IE. + */ + textarea { - overflow: auto; + overflow: auto; } -[type="number"]::-webkit-inner-spin-button, -[type="number"]::-webkit-outer-spin-button { - height: auto; + +/** + * Correct the cursor style of increment and decrement buttons in Chrome. + */ + +::-webkit-inner-spin-button, +::-webkit-outer-spin-button { + height: auto; } + +/** + * 1. Correct the odd appearance in Chrome and Safari. + * 2. Correct the outline style in Safari. + */ + [type="search"] { - -webkit-appearance: textfield; - outline-offset: -2px; + -webkit-appearance: textfield; /* 1 */ + outline-offset: -2px; /* 2 */ } -[type="search"]::-webkit-search-cancel-button, -[type="search"]::-webkit-search-decoration { - -webkit-appearance: none; + +/** + * Remove the inner padding in Chrome and Safari on macOS. + */ + +::-webkit-search-decoration { + -webkit-appearance: none; } + +/** + * 1. Correct the inability to style clickable types in iOS and Safari. + * 2. Change font properties to `inherit` in Safari. + */ + ::-webkit-file-upload-button { - -webkit-appearance: button; - font: inherit; + -webkit-appearance: button; /* 1 */ + font: inherit; /* 2 */ } + +/* Interactive + * ========================================================================== */ + +/* + * Add the correct display in Edge and IE. + */ + details { - display: block; + display: block; +} + +/* + * Add the correct styles in Edge, IE, and Safari. + */ + +dialog { + background-color: white; + border: solid; + color: black; + display: block; + height: -moz-fit-content; + height: -webkit-fit-content; + height: fit-content; + left: 0; + margin: auto; + padding: 1em; + position: absolute; + right: 0; + width: -moz-fit-content; + width: -webkit-fit-content; + width: fit-content; +} + +dialog:not([open]) { + display: none; } + +/* + * Add the correct display in all browsers. + */ + summary { - display: list-item; + display: list-item; } + +/* Scripting + * ========================================================================== */ + +/** + * Add the correct display in IE. + */ + template { - display: none; + display: none; } + +/* User interaction + * ========================================================================== */ + body { font-family: sans-serif; } From 450896402908596ceb21532e8d65388bb9d8e112 Mon Sep 17 00:00:00 2001 From: nagits Date: Fri, 23 Mar 2018 05:11:22 +0500 Subject: [PATCH 641/795] Allow `warnings` option to be an object to configure each warning --- index.js | 91 ++++++++++++++++++++++++++++++++++-------------- test/index.js | 95 ++++++++++++++++++++++++++++++++++++++++++++++++--- 2 files changed, 156 insertions(+), 30 deletions(-) diff --git a/index.js b/index.js index 0faac2e48d..48824c96d0 100755 --- a/index.js +++ b/index.js @@ -52,17 +52,12 @@ function resolveValue(value, variables, result, decl) { let post // undefined and without fallback, just keep original value if (!variable && !fallback) { - if (globalOpts.warnings) { - const errorStr = - `variable '${name}' is undefined and used without a fallback` + assert( + "no-value-notifications", false, + `variable '${name}' is undefined and used without a fallback`, + {decl, result, word: name} + ) - if (globalOpts.noValueNotifications === "error") { - throw decl.error(errorStr, {word: name}) - } - else { - result.warn(errorStr, {node: decl}) - } - } post = matches.post ? resolveValue(matches.post, variables, result, decl) : [""] @@ -100,9 +95,12 @@ function resolveValue(value, variables, result, decl) { // circular reference encountered if (variable.deps.indexOf(name) !== -1) { if (!fallback) { - if (globalOpts.warnings) { - result.warn("Circular variable reference: " + name, {node: decl}) - } + assert( + "circular-reference", false, + `Circular variable reference: ${name}`, + {decl, result, word: name} + ) + variable.value = [variable.value] variable.circular = true } @@ -152,6 +150,32 @@ function prefixVariables(variables) { return prefixedVariables } +/** + * Define an assertion that will print a warning or throw an exception + * if the condition is not met. + * + * @param {String} ruleName Name of the rule in `options.warnings`. + * @param {Boolean} condition Must be truthy for the assertion to pass. + * @param {String} message Text of the warning or error if the assertion fails. + * @param {Object} context PostCSS context objects: decl, result and + * warning (error) options. + */ +function assert(ruleName, condition, message, { + decl, result, word, index, plugin, +}) { + if (condition || !globalOpts.warnings) { + return + } + + if (globalOpts.warnings === true || globalOpts.warnings[ruleName] === true) { + result.warn(message, {node: decl, word, index, plugin}) + } + else if (globalOpts.warnings[ruleName] === "error") { + decl = decl || result.root.first + throw decl.error(message, {word, index, plugin}) + } +} + /** * Module export. */ @@ -171,9 +195,28 @@ export default postcss.plugin("postcss-custom-properties", (options = {}) => { const importantMap = {} globalOpts = { - warnings: "warnings" in options ? Boolean(options.warnings) : false, - noValueNotifications: "noValueNotifications" in options - ? String(options.noValueNotifications) : "warning", + warnings: options.warnings, + } + + if ("noValueNotifications" in options) { + result.warn( + "'noValueNotifications' is deprecated. Use " + + "\"options.warnings['no-value-notifications']: true|false|'error'\"" + + "instead." + ) + + if (typeof globalOpts.warnings === "object") { + globalOpts.warnings["no-value-notifications"] = + options.noValueNotifications === "error" ? "error" : true + } + else if (globalOpts.warnings === true + && options.noValueNotifications === "error") { + globalOpts.warnings = { + "no-value-notifications": "error", + "not-scoped-to-root": true, + "circular-reference": true, + } + } } // define variables @@ -188,18 +231,14 @@ export default postcss.plugin("postcss-custom-properties", (options = {}) => { ) { rule.each((decl) => { const prop = decl.prop - if ( - globalOpts.warnings && - prop && - prop.indexOf(VAR_PROP_IDENTIFIER) === 0 - ) { - result.warn( - "Custom property ignored: not scoped to the top-level :root " + + assert( + "not-scoped-to-root", + !prop || prop.indexOf(VAR_PROP_IDENTIFIER) !== 0, + "Custom property ignored: not scoped to the top-level :root " + `element (${rule.selectors} { ... ${prop}: ... })` + (rule.parent.type !== "root" ? ", in " + rule.parent.type : ""), - {node: decl} - ) - } + {decl, result} + ) }) return } diff --git a/test/index.js b/test/index.js index 52c3ccf258..11cfd34db3 100755 --- a/test/index.js +++ b/test/index.js @@ -61,7 +61,7 @@ test("throw errors", function(t) { test( "substitutes nothing when a variable function references an undefined var", function(t) { - const result = compareFixtures(t, "substitution-undefined", { + let result = compareFixtures(t, "substitution-undefined", { warnings: true, }) t.equal( @@ -69,6 +69,30 @@ test( "variable '--test' is undefined and used without a fallback", "should add a warning for undefined variable" ) + + result = compareFixtures(t, "substitution-undefined", { + warnings: { + "no-value-notifications": true, + }, + }) + t.equal( + result.messages[0].text, + "variable '--test' is undefined and used without a fallback", + "should add a warning for undefined variable" + ) + + t.throws( + function() { + compareFixtures(t, "substitution-undefined", { + warnings: { + "no-value-notifications": "error", + }, + }) + }, + /variable '--test' is undefined and used without a fallback/, + "should throw an error for undefined variable" + ) + t.end() } ) @@ -93,18 +117,41 @@ test( ) test("substitutes defined variables in `:root` only", function(t) { - const result = compareFixtures(t, "substitution-defined", { + let result = compareFixtures(t, "substitution-defined", { warnings: true, }) t.ok( result.messages[0].text.match(/^Custom property ignored/), "should add a warning for non root custom properties" ) + + result = compareFixtures(t, "substitution-defined", { + warnings: { + "not-scoped-to-root": true, + }, + }) + t.ok( + result.messages[0].text.match(/^Custom property ignored/), + "should add a warning for non root custom properties" + ) + + t.throws( + function() { + compareFixtures(t, "substitution-defined", { + warnings: { + "not-scoped-to-root": "error", + }, + }) + }, + /Custom property ignored/, + "should throw an error for non root custom properties" + ) + t.end() }) test("allow to hide warnings", function(t) { - const result = compareFixtures( + let result = compareFixtures( t, "substitution-defined", {warnings: false} @@ -114,6 +161,22 @@ test("allow to hide warnings", function(t) { 0, "should not add warnings if option set to false" ) + + result = compareFixtures( + t, + "substitution-defined", + { + warnings: { + "not-scoped-to-root": false, + }, + } + ) + t.equal( + result.messages.length, + 0, + "should not add warnings if option set to false" + ) + t.end() }) @@ -217,7 +280,7 @@ test("preserves computed value when `preserve` is `\"computed\"`", function(t) { test("circular variable references", function(t) { compareFixtures(t, "self-reference") - const result = compareFixtures(t, "circular-reference", { + let result = compareFixtures(t, "circular-reference", { warnings: true, }) t.equal( @@ -225,6 +288,30 @@ test("circular variable references", function(t) { "Circular variable reference: --bg-color", "should add a warning for circular reference" ) + + result = compareFixtures(t, "circular-reference", { + warnings: { + "circular-reference": true, + }, + }) + t.equal( + result.messages[0].text, + "Circular variable reference: --bg-color", + "should add a warning for circular reference" + ) + + t.throws( + function() { + compareFixtures(t, "circular-reference", { + warnings: { + "circular-reference": "error", + }, + }) + }, + /Circular variable reference: --bg-color/, + "should throw an error for circular reference" + ) + t.end() }) From a115c35e39acd888e1980bd84bef48f86cc45e30 Mon Sep 17 00:00:00 2001 From: Jonathan Neal Date: Wed, 27 Jun 2018 21:54:07 -0400 Subject: [PATCH 642/795] Update dependencies --- package.json | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/package.json b/package.json index aa97e9503b..f92e6716fc 100644 --- a/package.json +++ b/package.json @@ -19,16 +19,16 @@ ], "dependencies": { "balanced-match": "^1.0.0", - "postcss": "^6.0.18" + "postcss": "^6.0.23" }, "devDependencies": { "babel-cli": "^6.26.0", "babel-plugin-add-module-exports": "^0.2.1", - "babel-preset-env": "^1.6.1", + "babel-preset-env": "^1.7.0", "babel-register": "^6.26.0", - "eslint": "^4.17.0", - "npmpub": "^3.1.0", - "tape": "^4.8.0" + "eslint": "^5.0.1", + "npmpub": "^4.0.1", + "tape": "^4.9.1" }, "scripts": { "lint": "eslint *.js index.js ./test/", From 17acc21f7d6c1486808cf960d81d42782e84eb47 Mon Sep 17 00:00:00 2001 From: Jonathan Neal Date: Fri, 13 Jul 2018 15:05:03 -0400 Subject: [PATCH 643/795] Update dependencies / testing --- .appveyor.yml | 2 +- .travis.yml | 2 +- package.json | 10 +++++----- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/.appveyor.yml b/.appveyor.yml index acbf8a5eeb..73f0d8fa3f 100644 --- a/.appveyor.yml +++ b/.appveyor.yml @@ -2,7 +2,7 @@ environment: matrix: - - nodejs_version: 4 + - nodejs_version: 6 version: "{build}" build: off diff --git a/.travis.yml b/.travis.yml index c56466446c..e1f11a52e6 100644 --- a/.travis.yml +++ b/.travis.yml @@ -3,7 +3,7 @@ language: node_js node_js: - - 4 + - 6 install: - npm install --ignore-scripts diff --git a/package.json b/package.json index db870cc54f..622e328ab0 100644 --- a/package.json +++ b/package.json @@ -25,19 +25,19 @@ "node": ">=4.0.0" }, "dependencies": { - "postcss": "^6.0.22", + "postcss": "^6.0.23", "postcss-values-parser": "^1.5.0" }, "devDependencies": { "babel-core": "^6.26.3", - "babel-eslint": "^8.2.3", + "babel-eslint": "^8.2.6", "babel-preset-env": "^1.7.0", - "eslint": "^4.19.1", + "eslint": "^5.1.0", "eslint-config-dev": "^2.0.0", "postcss-tape": "^2.2.0", "pre-commit": "^1.2.2", - "rollup": "^0.58.2", - "rollup-plugin-babel": "^3.0.4" + "rollup": "^0.62.0", + "rollup-plugin-babel": "^3.0.7" }, "eslintConfig": { "extends": "dev", From 0ca961931b5e5ac2b54ce0dc7a06c7f1db201ce0 Mon Sep 17 00:00:00 2001 From: Jonathan Neal Date: Fri, 13 Jul 2018 15:05:39 -0400 Subject: [PATCH 644/795] Fix issue with badly determined hsl and rgb --- index.js | 16 ++++++++++------ test/basic.css | 1 + test/basic.expect.css | 1 + test/basic.preserve-true.expect.css | 2 ++ 4 files changed, 14 insertions(+), 6 deletions(-) diff --git a/index.js b/index.js index 18e90cc717..3769674c47 100644 --- a/index.js +++ b/index.js @@ -14,9 +14,9 @@ export default postcss.plugin('postcss-color-functional-notation', opts => { ast.walkType('func', node => { if (colorRegExp.test(node.value)) { const children = node.nodes.slice(1, -1); - const isFunctionalHSL = matchFunctionalHSL(children); - const isFunctionalRGB1 = matchFunctionalRGB1(children); - const isFunctionalRGB2 = matchFunctionalRGB2(children); + const isFunctionalHSL = matchFunctionalHSL(node, children); + const isFunctionalRGB1 = matchFunctionalRGB1(node, children); + const isFunctionalRGB2 = matchFunctionalRGB2(node, children); if (isFunctionalHSL || isFunctionalRGB1 || isFunctionalRGB2) { const slashNode = children[3]; @@ -69,28 +69,32 @@ const alphaUnitMatch = /^%?$/i; const calcFuncMatch = /^calc$/i; const colorAnyRegExp = /(^|[^\w-])(hsla?|rgba?)\(/i; const colorRegExp = /^(hsla?|rgba?)$/i; +const hslishRegExp = /^hsla?$/i; const hslRgbFuncMatch = /^(hsl|rgb)$/i; const hslaRgbaFuncMatch = /^(hsla|rgba)$/i; const hueUnitMatch = /^(deg|grad|rad|turn)?$/i; +const rgbishRegExp = /^rgba?$/i; const isAlphaValue = node => isCalc(node) || Object(node).type === 'number' && alphaUnitMatch.test(node.unit); const isCalc = node => Object(node).type === 'func' && calcFuncMatch.test(node.value); const isHue = node => isCalc(node) || Object(node).type === 'number' && hueUnitMatch.test(node.unit); const isNumber = node => isCalc(node) || Object(node).type === 'number' && node.unit === ''; const isPercentage = node => isCalc(node) || Object(node).type === 'number' && (node.unit === '%' || node.unit === '' && node.value === '0'); +const isHslish = node => Object(node).type === 'func' && hslishRegExp.test(node.value); const isHslRgb = node => Object(node).type === 'func' && hslRgbFuncMatch.test(node.value); const isHslaRgba = node => Object(node).type === 'func' && hslaRgbaFuncMatch.test(node.value); +const isRgbish = node => Object(node).type === 'func' && rgbishRegExp.test(node.value); const isSlash = node => Object(node).type === 'operator' && node.value === '/'; const functionalHSLMatch = [isHue, isPercentage, isPercentage, isSlash, isAlphaValue]; const functionalRGB1Match = [isNumber, isNumber, isNumber, isSlash, isAlphaValue]; const functionalRGB2Match = [isPercentage, isPercentage, isPercentage, isSlash, isAlphaValue]; -const matchFunctionalHSL = children => children.every( +const matchFunctionalHSL = (node, children) => isHslish(node) && children.every( (child, index) => typeof functionalHSLMatch[index] === 'function' && functionalHSLMatch[index](child) ); -const matchFunctionalRGB1 = children => children.every( +const matchFunctionalRGB1 = (node, children) => isRgbish(node) && children.every( (child, index) => typeof functionalRGB1Match[index] === 'function' && functionalRGB1Match[index](child) ); -const matchFunctionalRGB2 = children => children.every( +const matchFunctionalRGB2 = (node, children) => isRgbish(node) && children.every( (child, index) => typeof functionalRGB2Match[index] === 'function' && functionalRGB2Match[index](child) ); diff --git a/test/basic.css b/test/basic.css index 4dcca4653e..b334ca9970 100644 --- a/test/basic.css +++ b/test/basic.css @@ -19,6 +19,7 @@ } .test-hsl { + color: hsl(0 0% 100%); color: hsl(120deg 100% 50%); color: hsl(120 100% 50%); color: hsl(120 100% 50% / 1); diff --git a/test/basic.expect.css b/test/basic.expect.css index 9c0d84b4af..1da2148f5a 100644 --- a/test/basic.expect.css +++ b/test/basic.expect.css @@ -19,6 +19,7 @@ } .test-hsl { + color: hsl(0, 0%, 100%); color: hsl(120deg, 100%, 50%); color: hsl(120, 100%, 50%); color: hsla(120, 100%, 50%, 1); diff --git a/test/basic.preserve-true.expect.css b/test/basic.preserve-true.expect.css index bb946f2515..90a63f447a 100644 --- a/test/basic.preserve-true.expect.css +++ b/test/basic.preserve-true.expect.css @@ -30,6 +30,8 @@ } .test-hsl { + color: hsl(0, 0%, 100%); + color: hsl(0 0% 100%); color: hsl(120deg, 100%, 50%); color: hsl(120deg 100% 50%); color: hsl(120, 100%, 50%); From 58a16404280a41191527f88b235ee4b8af8cbd64 Mon Sep 17 00:00:00 2001 From: Jonathan Neal Date: Fri, 13 Jul 2018 15:09:27 -0400 Subject: [PATCH 645/795] 1.0.2 --- CHANGELOG.md | 4 ++++ package.json | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5641f6930a..a86db3dcdd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # Changes to PostCSS Color Functional Notation +### 1.0.2 (July 13, 2018) + +- Fixed: Poorly detected hsl() and rgb() now resolve correctly + ### 1.0.1 (May 11, 2018) - Fixed: A non-percentage 0 works alongside other percentages diff --git a/package.json b/package.json index 622e328ab0..46ba4e9f8a 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "postcss-color-functional-notation", - "version": "1.0.1", + "version": "1.0.2", "description": "Use space and slash separated color notation in CSS", "author": "Jonathan Neal ", "license": "CC0-1.0", From 6ce644fa93fe7a3c8938ff2c1d54906e0e608f8e Mon Sep 17 00:00:00 2001 From: Jonathan Neal Date: Sat, 21 Jul 2018 07:41:50 -0400 Subject: [PATCH 646/795] 2.4.3 --- .appveyor.yml | 2 +- .gitignore | 2 +- .rollup.js | 5 ++++- .travis.yml | 2 +- CHANGELOG.md | 4 ++++ README.md | 4 ++-- index.js | 2 +- package.json | 26 +++++++++++++------------- test/basic.colors.expect.css | 4 ++++ test/basic.css | 4 ++++ test/basic.expect.css | 4 ++++ 11 files changed, 39 insertions(+), 20 deletions(-) diff --git a/.appveyor.yml b/.appveyor.yml index acbf8a5eeb..73f0d8fa3f 100644 --- a/.appveyor.yml +++ b/.appveyor.yml @@ -2,7 +2,7 @@ environment: matrix: - - nodejs_version: 4 + - nodejs_version: 6 version: "{build}" build: off diff --git a/.gitignore b/.gitignore index 6832ce87db..de73e5a338 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,5 @@ node_modules -index.bundle.js +index.*.js package-lock.json *.log* *.result.css diff --git a/.rollup.js b/.rollup.js index 7f4e231750..0436758216 100644 --- a/.rollup.js +++ b/.rollup.js @@ -2,7 +2,10 @@ import babel from 'rollup-plugin-babel'; export default { input: 'index.js', - output: { file: 'index.bundle.js', format: 'cjs' }, + output: [ + { file: 'index.cjs.js', format: 'cjs' }, + { file: 'index.es.js', format: 'es' } + ], plugins: [ babel({ presets: [ diff --git a/.travis.yml b/.travis.yml index c56466446c..e1f11a52e6 100644 --- a/.travis.yml +++ b/.travis.yml @@ -3,7 +3,7 @@ language: node_js node_js: - - 4 + - 6 install: - npm install --ignore-scripts diff --git a/CHANGELOG.md b/CHANGELOG.md index 5373f2af06..1cc2fbd46d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # Changes to PostCSS color-mod() Function +### 2.4.3 (July 21, 2018) + +- Fixed issue with color-mod not being converted within function + ### 2.4.2 (February 27, 2018) - Fixed issue with converting colorspaces diff --git a/README.md b/README.md index 4081d03e9e..976c1aa028 100644 --- a/README.md +++ b/README.md @@ -199,8 +199,8 @@ knowledge of the living DOM tree. [cli-img]: https://img.shields.io/travis/jonathantneal/postcss-color-mod-function.svg [cli-url]: https://travis-ci.org/jonathantneal/postcss-color-mod-function -[css-img]: https://jonathantneal.github.io/cssdb/badge/color-mod-function.svg -[css-url]: https://jonathantneal.github.io/css-db/#css-variables +[css-img]: https://cssdb.org/badge/color-mod-function.svg +[css-url]: https://preset-env.cssdb.org/features#color-mod-function [git-img]: https://img.shields.io/badge/support-chat-blue.svg [git-url]: https://gitter.im/postcss/postcss [npm-img]: https://img.shields.io/npm/v/postcss-color-mod-function.svg diff --git a/index.js b/index.js index a4867e31c1..5d10d76b31 100644 --- a/index.js +++ b/index.js @@ -34,4 +34,4 @@ export default postcss.plugin('postcss-color-mod-function', opts => { }; }); -const colorModFunctionMatch = /(^|\s)color-mod\(/i; +const colorModFunctionMatch = /(^|[^\w-])color-mod\(/i; diff --git a/package.json b/package.json index da1a0f5d49..1d3600994b 100644 --- a/package.json +++ b/package.json @@ -1,17 +1,17 @@ { "name": "postcss-color-mod-function", - "version": "2.4.2", + "version": "2.4.3", "description": "Modify colors using the color-mod() function in CSS", "author": "Jonathan Neal ", "license": "CC0-1.0", "repository": "jonathantneal/postcss-color-mod-function", "homepage": "https://github.com/jonathantneal/postcss-color-mod-function#readme", "bugs": "https://github.com/jonathantneal/postcss-color-mod-function/issues", - "main": "index.bundle.js", - "module": "index.js", + "main": "index.cjs.js", + "module": "index.es.js", "files": [ - "index.js", - "index.bundle.js", + "index.cjs.js", + "index.es.js", "lib" ], "scripts": { @@ -27,20 +27,20 @@ }, "dependencies": { "@csstools/convert-colors": "^1.4.0", - "postcss": "^6.0.19", - "postcss-values-parser": "^1.3.2" + "postcss": "^6.0.23", + "postcss-values-parser": "^1.5.0" }, "devDependencies": { - "babel-core": "^6.26.0", - "babel-eslint": "^8.2.2", - "babel-preset-env": "^1.6.1", + "babel-core": "^6.26.3", + "babel-eslint": "^8.2.6", + "babel-preset-env": "^1.7.0", "echint": "^4.0.1", - "eslint": "^4.18.1", + "eslint": "^5.2.0", "eslint-config-dev": "^2.0.0", "postcss-tape": "^2.2.0", "pre-commit": "^1.2.2", - "rollup": "^0.56.3", - "rollup-plugin-babel": "^3.0.3" + "rollup": "^0.63.4", + "rollup-plugin-babel": "^3.0.7" }, "eslintConfig": { "extends": "dev", diff --git a/test/basic.colors.expect.css b/test/basic.colors.expect.css index d758803c0e..bc19fc583b 100644 --- a/test/basic.colors.expect.css +++ b/test/basic.colors.expect.css @@ -131,3 +131,7 @@ test-var { test-multiple-value-items { border: 1px solid rgb(100% 0% 0%); } + +test-linear-gradient { + background-image: linear-gradient(rgb(100% 0% 0%), rgb(100% 0% 0% / 0%)); +} diff --git a/test/basic.css b/test/basic.css index 58f6efca9b..1bcd540af4 100644 --- a/test/basic.css +++ b/test/basic.css @@ -131,3 +131,7 @@ test-var { test-multiple-value-items { border: 1px solid color-mod(red); } + +test-linear-gradient { + background-image: linear-gradient(color-mod(red alpha(100%)), color-mod(red alpha(0%))); +} diff --git a/test/basic.expect.css b/test/basic.expect.css index ec89f8b4f8..b1f62ab38f 100644 --- a/test/basic.expect.css +++ b/test/basic.expect.css @@ -131,3 +131,7 @@ test-var { test-multiple-value-items { border: 1px solid rgb(255, 0, 0); } + +test-linear-gradient { + background-image: linear-gradient(rgb(255, 0, 0), rgba(255, 0, 0, 0)); +} From bde8f0e939f7ebaba91a4f580639d2564755b3d3 Mon Sep 17 00:00:00 2001 From: Jonathan Neal Date: Tue, 24 Jul 2018 20:49:32 -0400 Subject: [PATCH 647/795] Update dependencies --- package.json | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/package.json b/package.json index 0256cee60f..a2f9ba7842 100644 --- a/package.json +++ b/package.json @@ -26,19 +26,19 @@ }, "dependencies": { "@csstools/convert-colors": "^1.4.0", - "postcss": "^6.0.22", + "postcss": "^6.0.23", "postcss-values-parser": "^1.5.0" }, "devDependencies": { "babel-core": "^6.26.3", - "babel-eslint": "^8.2.3", + "babel-eslint": "^8.2.6", "babel-preset-env": "^1.7.0", - "eslint": "^4.19.1", + "eslint": "^5.2.0", "eslint-config-dev": "^2.0.0", "postcss-tape": "^2.2.0", "pre-commit": "^1.2.2", - "rollup": "^0.58.2", - "rollup-plugin-babel": "^3.0.4" + "rollup": "^0.63.4", + "rollup-plugin-babel": "^3.0.7" }, "eslintConfig": { "extends": "dev", From 2ee1743724927c669653a47816b2c252e79e7522 Mon Sep 17 00:00:00 2001 From: Jonathan Neal Date: Tue, 24 Jul 2018 20:53:07 -0400 Subject: [PATCH 648/795] Add support for gray(a / b) as lab(a 0 0 / b) --- index.js | 61 ++++++++++++++++++++++++++--- test/basic.css | 8 ++++ test/basic.expect.css | 8 ++++ test/basic.preserve-true.expect.css | 13 ++++++ 4 files changed, 84 insertions(+), 6 deletions(-) diff --git a/index.js b/index.js index ff5eeb181f..ff94a81a78 100644 --- a/index.js +++ b/index.js @@ -16,11 +16,13 @@ export default postcss.plugin('postcss-lab-function', opts => { if (colorRegExp.test(node.value)) { const children = node.nodes.slice(1, -1); const isLab = labRegExp.test(node.value); - const isFunctionalLAB = matchFunctionalLAB(children); - const isFunctionalLCH = matchFunctionalLCH(children); + const isGray = grayRegExp.test(node.value); + const isFunctionalLAB = !isGray && matchFunctionalLAB(children); + const isFunctionalLCH = !isGray && matchFunctionalLCH(children); + const isFunctionalGray = isGray && matchFunctionalGray(children); if (isFunctionalLAB || isFunctionalLCH) { - node.value = 'rgb' + node.value = 'rgb'; const slashNode = children[3]; const alphaNode = children[4]; @@ -63,6 +65,46 @@ export default postcss.plugin('postcss-lab-function', opts => { node.nodes.splice(3, 0, [ newComma() ]); node.nodes.splice(2, 0, [ newComma() ]); + } else if (isFunctionalGray) { + node.value = 'rgb'; + + const alphaNode = children[2]; + + const rgbValues = lab2rgb( + ...[ + children[0].value, + 0, + 0 + ].map( + number => parseFloat(number) + ) + ).map( + sourceValue => Math.max(Math.min(parseInt(sourceValue * 2.55), 255), 0) + ); + + node.removeAll() + .append(newParen('(')) + .append(newNumber(rgbValues[0])) + .append(newComma()) + .append(newNumber(rgbValues[1])) + .append(newComma()) + .append(newNumber(rgbValues[2])) + .append(newParen(')')); + + if (alphaNode) { + if (isPercentage(alphaNode) && !isCalc(alphaNode)) { + alphaNode.unit = ''; + alphaNode.value = String(alphaNode.value / 100); + } + + if (alphaNode.value !== '1') { + node.value += 'a'; + + node + .insertBefore(node.last, newComma()) + .insertBefore(node.last, alphaNode) + } + } } } }); @@ -79,9 +121,10 @@ export default postcss.plugin('postcss-lab-function', opts => { }; }); -const colorAnyRegExp = /(^|[^\w-])(lab?|lch?)\(/i; -const colorRegExp = /^(lab?|lch?)$/i; +const colorAnyRegExp = /(^|[^\w-])(lab|lch|gray)\(/i; +const colorRegExp = /^(lab|lch|gray)$/i; const labRegExp = /^lab$/i; +const grayRegExp = /^gray$/i; const alphaUnitMatch = /^%?$/i; const calcFuncMatch = /^calc$/i; const hueUnitMatch = /^(deg|grad|rad|turn)?$/i; @@ -94,11 +137,17 @@ const isPercentage = node => isCalc(node) || Object(node).type === 'number' && n const isSlash = node => Object(node).type === 'operator' && node.value === '/'; const functionalLABMatch = [isNumber, isNumber, isNumber, isSlash, isAlphaValue]; const functionalLCHMatch = [isNumber, isNumber, isHue, isSlash, isAlphaValue]; +const functionalGrayMatch = [isNumber, isSlash, isAlphaValue]; const matchFunctionalLAB = children => children.every( (child, index) => typeof functionalLABMatch[index] === 'function' && functionalLABMatch[index](child) ); const matchFunctionalLCH = children => children.every( (child, index) => typeof functionalLCHMatch[index] === 'function' && functionalLCHMatch[index](child) ); +const matchFunctionalGray = children => children.every( + (child, index) => typeof functionalGrayMatch[index] === 'function' && functionalGrayMatch[index](child) +); -const newComma = () => parser.comma({ value: ',' }) +const newComma = () => parser.comma({ value: ',' }); +const newNumber = value => parser.number({ value }); +const newParen = value => parser.paren({ value }); diff --git a/test/basic.css b/test/basic.css index a06b69e0b9..aa52e7f7e7 100644 --- a/test/basic.css +++ b/test/basic.css @@ -15,3 +15,11 @@ color: lch(40 68.8 34.5 / 50%); color: lch(100 50 0); } + +.test-gray { + color: gray(40); + color: gray(40 / 1); + color: gray(40 / .5); + color: gray(40 / 100%); + color: gray(40 / 50%); +} diff --git a/test/basic.expect.css b/test/basic.expect.css index 4068e14752..76dccaef9c 100644 --- a/test/basic.expect.css +++ b/test/basic.expect.css @@ -15,3 +15,11 @@ color: rgba(178, 34, 34, 0.5); color: rgb(255, 216, 255); } + +.test-gray { + color: rgb(94,94,94); + color: rgb(94,94,94); + color: rgba(94,94,94, .5); + color: rgb(94,94,94); + color: rgba(94,94,94, 0.5); +} diff --git a/test/basic.preserve-true.expect.css b/test/basic.preserve-true.expect.css index fdf49ebb0e..88b381dfcc 100644 --- a/test/basic.preserve-true.expect.css +++ b/test/basic.preserve-true.expect.css @@ -27,3 +27,16 @@ color: rgb(255, 216, 255); color: lch(100 50 0); } + +.test-gray { + color: rgb(94,94,94); + color: gray(40); + color: rgb(94,94,94); + color: gray(40 / 1); + color: rgba(94,94,94, .5); + color: gray(40 / .5); + color: rgb(94,94,94); + color: gray(40 / 100%); + color: rgba(94,94,94, 0.5); + color: gray(40 / 50%); +} From ca2da97de3ecb390b719ee3c1aa93c7c8de932de Mon Sep 17 00:00:00 2001 From: Jonathan Neal Date: Tue, 24 Jul 2018 20:56:07 -0400 Subject: [PATCH 649/795] 1.1.0 --- CHANGELOG.md | 4 ++++ README.md | 8 ++++++-- package.json | 2 +- 3 files changed, 11 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a106b4086c..1b5f64c464 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # Changes to PostCSS Lab Function +### 1.1.0 (July 24, 2018) + +- Added: Support for `gray(a / b)` as `lab(a 0 0 / b)` + ### 1.0.1 (May 11, 2018) - Fixed: Values beyond the acceptable 0-255 RGB range diff --git a/README.md b/README.md index 99dc229b6c..eb7cce72dd 100644 --- a/README.md +++ b/README.md @@ -6,13 +6,15 @@ [![Windows Build Status][win-img]][win-url] [![Support Chat][git-img]][git-url] -[PostCSS Lab Function] lets you use `lab` and `lch` color functions in CSS, -following the [CSS Color] specification. +[PostCSS Lab Function] lets you use `lab`, `lch`, and `gray` color functions in +CSS, following the [CSS Color] specification. ```pcss :root { --firebrick: lab(40 56.6 39); --firebrick-a50: lch(40 68.8 34.5 / 50%); + --gray-40: gray(40); + --gray-40a50: gray(40 / .5); } /* becomes */ @@ -20,6 +22,8 @@ following the [CSS Color] specification. :root { --firebrick: rgb(178, 34, 34); --firebrick-a50: rgba(178, 34, 34, .5); + --gray-40: rgb(94,94,94); + --gray-40a50: rgba(94,94,94, .5); } ``` diff --git a/package.json b/package.json index a2f9ba7842..9a18df2d95 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "postcss-lab-function", - "version": "1.0.1", + "version": "1.1.0", "description": "Use lab() and lch() color functions in CSS", "author": "Jonathan Neal ", "license": "CC0-1.0", From c0c9622daca64d36b5f696e610f6802a6fc09f9d Mon Sep 17 00:00:00 2001 From: Jonathan Neal Date: Tue, 24 Jul 2018 20:59:04 -0400 Subject: [PATCH 650/795] Update testing to Node v6 --- .appveyor.yml | 2 +- .travis.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.appveyor.yml b/.appveyor.yml index acbf8a5eeb..73f0d8fa3f 100644 --- a/.appveyor.yml +++ b/.appveyor.yml @@ -2,7 +2,7 @@ environment: matrix: - - nodejs_version: 4 + - nodejs_version: 6 version: "{build}" build: off diff --git a/.travis.yml b/.travis.yml index c56466446c..e1f11a52e6 100644 --- a/.travis.yml +++ b/.travis.yml @@ -3,7 +3,7 @@ language: node_js node_js: - - 4 + - 6 install: - npm install --ignore-scripts From 104eb5320f7ac070114aa4cc81d5339e25960e6d Mon Sep 17 00:00:00 2001 From: Eduard Kyvenko Date: Fri, 10 Aug 2018 09:46:39 +0200 Subject: [PATCH 651/795] Upgrade postcss version to v7 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index bac67503fd..3f05cbdd95 100644 --- a/package.json +++ b/package.json @@ -25,7 +25,7 @@ "node": ">=4.0.0" }, "dependencies": { - "postcss": "^6.0.22", + "postcss": "^7.0.2", "postcss-selector-parser": "^4.0.0" }, "devDependencies": { From 0508237c9adfadf1557de04f857f67e2eee2920a Mon Sep 17 00:00:00 2001 From: Eduard Kyvenko Date: Thu, 9 Aug 2018 22:20:39 +0200 Subject: [PATCH 652/795] Upgrade postcss version --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 7197895d58..6f361b00ac 100644 --- a/package.json +++ b/package.json @@ -21,7 +21,7 @@ ], "dependencies": { "balanced-match": "^0.4.2", - "postcss": "^6.0.1" + "postcss": "^7.0.2" }, "devDependencies": { "babel-cli": "^6.24.1", From 76589c15f123ac0a82adcdba53643348ccf8197c Mon Sep 17 00:00:00 2001 From: Eduard Kyvenko Date: Thu, 9 Aug 2018 22:34:21 +0200 Subject: [PATCH 653/795] Upgrade postcss to v7 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index e8639a9a1e..adfe3db2fd 100644 --- a/package.json +++ b/package.json @@ -18,7 +18,7 @@ ], "dependencies": { "balanced-match": "^0.4.2", - "postcss": "^6.0.1" + "postcss": "^7.0.2" }, "devDependencies": { "babel-cli": "^6.24.1", From fd622b8b8782054495f1e1c2a2f86e0218d8e83c Mon Sep 17 00:00:00 2001 From: Pascal Duez Date: Mon, 13 Aug 2018 14:34:52 +0200 Subject: [PATCH 654/795] Use PostCSS 7 * Upgrade PostCSS to version 7 * Add package-lock file * Fix broken unit tests --- .travis.yml | 3 +- package-lock.json | 1535 +++++++++++++++++++++++++++++++++++++++++++++ package.json | 5 +- test/index.js | 2 +- 4 files changed, 1542 insertions(+), 3 deletions(-) create mode 100644 package-lock.json diff --git a/.travis.yml b/.travis.yml index 10e9429ed5..ca92cebc21 100644 --- a/.travis.yml +++ b/.travis.yml @@ -2,4 +2,5 @@ sudo: false language: node_js node_js: - "6" - - "4" + - "8" + - "stable" diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 0000000000..eab4b36507 --- /dev/null +++ b/package-lock.json @@ -0,0 +1,1535 @@ +{ + "name": "postcss-color-hex-alpha", + "version": "3.0.0", + "lockfileVersion": 1, + "requires": true, + "dependencies": { + "acorn": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-5.7.1.tgz", + "integrity": "sha512-d+nbxBUGKg7Arpsvbnlq61mc12ek3EY8EQldM3GPAhWJ1UVxC6TDGbIvUMNU6obBX3i1+ptCIzV4vq0gFPEGVQ==", + "dev": true + }, + "acorn-jsx": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-3.0.1.tgz", + "integrity": "sha1-r9+UiPsezvyDSPb7IvRk4ypYs2s=", + "dev": true, + "requires": { + "acorn": "^3.0.4" + }, + "dependencies": { + "acorn": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-3.3.0.tgz", + "integrity": "sha1-ReN/s56No/JbruP/U2niu18iAXo=", + "dev": true + } + } + }, + "ajv": { + "version": "4.11.8", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-4.11.8.tgz", + "integrity": "sha1-gv+wKynmYq5TvcIK8VlHcGc5xTY=", + "dev": true, + "requires": { + "co": "^4.6.0", + "json-stable-stringify": "^1.0.1" + } + }, + "ajv-keywords": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-1.5.1.tgz", + "integrity": "sha1-MU3QpLM2j609/NxU7eYXG4htrzw=", + "dev": true + }, + "ansi-escapes": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-1.4.0.tgz", + "integrity": "sha1-06ioOzGapneTZisT52HHkRQiMG4=", + "dev": true + }, + "ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", + "dev": true + }, + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "requires": { + "color-convert": "^1.9.0" + } + }, + "argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "dev": true, + "requires": { + "sprintf-js": "~1.0.2" + } + }, + "array-union": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-1.0.2.tgz", + "integrity": "sha1-mjRBDk9OPaI96jdb5b5w8kd47Dk=", + "dev": true, + "requires": { + "array-uniq": "^1.0.1" + } + }, + "array-uniq": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/array-uniq/-/array-uniq-1.0.3.tgz", + "integrity": "sha1-r2rId6Jcx/dOBYiUdThY39sk/bY=", + "dev": true + }, + "arrify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", + "integrity": "sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=", + "dev": true + }, + "babel-code-frame": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-code-frame/-/babel-code-frame-6.26.0.tgz", + "integrity": "sha1-Y/1D99weO7fONZR9uP42mj9Yx0s=", + "dev": true, + "requires": { + "chalk": "^1.1.3", + "esutils": "^2.0.2", + "js-tokens": "^3.0.2" + }, + "dependencies": { + "ansi-styles": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", + "dev": true + }, + "chalk": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", + "dev": true, + "requires": { + "ansi-styles": "^2.2.1", + "escape-string-regexp": "^1.0.2", + "has-ansi": "^2.0.0", + "strip-ansi": "^3.0.0", + "supports-color": "^2.0.0" + } + }, + "supports-color": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", + "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", + "dev": true + } + } + }, + "balanced-match": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", + "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", + "dev": true + }, + "brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "buffer-from": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", + "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==", + "dev": true + }, + "caller-path": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/caller-path/-/caller-path-0.1.0.tgz", + "integrity": "sha1-lAhe9jWB7NPaqSREqP6U6CV3dR8=", + "dev": true, + "requires": { + "callsites": "^0.2.0" + } + }, + "callsites": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-0.2.0.tgz", + "integrity": "sha1-r6uWJikQp/M8GaV3WCXGnzTjUMo=", + "dev": true + }, + "chalk": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.1.tgz", + "integrity": "sha512-ObN6h1v2fTJSmUXoS3nMQ92LbDK9be4TV+6G+omQlGJFdcUX5heKi1LZ1YnRMIgwTLEj3E24bT6tYni50rlCfQ==", + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, + "circular-json": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/circular-json/-/circular-json-0.3.3.tgz", + "integrity": "sha512-UZK3NBx2Mca+b5LsG7bY183pHWt5Y1xts4P3Pz7ENTwGVnJOUWbRb3ocjvX7hx9tq/yTAdclXm9sZ38gNuem4A==", + "dev": true + }, + "cli-cursor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-1.0.2.tgz", + "integrity": "sha1-ZNo/fValRBLll5S9Ytw1KV6PKYc=", + "dev": true, + "requires": { + "restore-cursor": "^1.0.1" + } + }, + "cli-width": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-2.2.0.tgz", + "integrity": "sha1-/xnt6Kml5XkyQUewwR8PvLq+1jk=", + "dev": true + }, + "co": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", + "integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ=", + "dev": true + }, + "code-point-at": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", + "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=", + "dev": true + }, + "color": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/color/-/color-1.0.3.tgz", + "integrity": "sha1-5I6DLYXxTvaU+0aIEcLVz+cptV0=", + "requires": { + "color-convert": "^1.8.2", + "color-string": "^1.4.0" + } + }, + "color-convert": { + "version": "1.9.2", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.2.tgz", + "integrity": "sha512-3NUJZdhMhcdPn8vJ9v2UQJoH0qqoGUkYTgFEPZaPjEtwmmKUfNV46zZmgB2M5M4DCEQHMaCfWHCxiBflLm04Tg==", + "requires": { + "color-name": "1.1.1" + } + }, + "color-name": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.1.tgz", + "integrity": "sha1-SxQVMEz1ACjqgWQ2Q72C6gWANok=" + }, + "color-string": { + "version": "1.5.3", + "resolved": "https://registry.npmjs.org/color-string/-/color-string-1.5.3.tgz", + "integrity": "sha512-dC2C5qeWoYkxki5UAXapdjqO672AM4vZuPGRQfO8b5HKuKGBbKWpITyDYN7TOFKvRW7kOgAn3746clDBMDJyQw==", + "requires": { + "color-name": "^1.0.0", + "simple-swizzle": "^0.2.2" + } + }, + "concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", + "dev": true + }, + "concat-stream": { + "version": "1.6.2", + "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz", + "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==", + "dev": true, + "requires": { + "buffer-from": "^1.0.0", + "inherits": "^2.0.3", + "readable-stream": "^2.2.2", + "typedarray": "^0.0.6" + } + }, + "core-util-is": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", + "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=", + "dev": true + }, + "d": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/d/-/d-1.0.0.tgz", + "integrity": "sha1-dUu1v+VUUdpppYuU1F9MWwRi1Y8=", + "dev": true, + "requires": { + "es5-ext": "^0.10.9" + } + }, + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "deep-equal": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/deep-equal/-/deep-equal-1.0.1.tgz", + "integrity": "sha1-9dJgKStmDghO/0zbyfCK0yR0SLU=", + "dev": true + }, + "deep-is": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz", + "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=", + "dev": true + }, + "define-properties": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.2.tgz", + "integrity": "sha1-g6c/L+pWmJj7c3GTyPhzyvbUXJQ=", + "dev": true, + "requires": { + "foreach": "^2.0.5", + "object-keys": "^1.0.8" + } + }, + "defined": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/defined/-/defined-1.0.0.tgz", + "integrity": "sha1-yY2bzvdWdBiOEQlpFRGZ45sfppM=", + "dev": true + }, + "del": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/del/-/del-2.2.2.tgz", + "integrity": "sha1-wSyYHQZ4RshLyvhiz/kw2Qf/0ag=", + "dev": true, + "requires": { + "globby": "^5.0.0", + "is-path-cwd": "^1.0.0", + "is-path-in-cwd": "^1.0.0", + "object-assign": "^4.0.1", + "pify": "^2.0.0", + "pinkie-promise": "^2.0.0", + "rimraf": "^2.2.8" + } + }, + "doctrine": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", + "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", + "dev": true, + "requires": { + "esutils": "^2.0.2" + } + }, + "es-abstract": { + "version": "1.12.0", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.12.0.tgz", + "integrity": "sha512-C8Fx/0jFmV5IPoMOFPA9P9G5NtqW+4cOPit3MIuvR2t7Ag2K15EJTpxnHAYTzL+aYQJIESYeXZmDBfOBE1HcpA==", + "dev": true, + "requires": { + "es-to-primitive": "^1.1.1", + "function-bind": "^1.1.1", + "has": "^1.0.1", + "is-callable": "^1.1.3", + "is-regex": "^1.0.4" + } + }, + "es-to-primitive": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.1.1.tgz", + "integrity": "sha1-RTVSSKiJeQNLZ5Lhm7gfK3l13Q0=", + "dev": true, + "requires": { + "is-callable": "^1.1.1", + "is-date-object": "^1.0.1", + "is-symbol": "^1.0.1" + } + }, + "es5-ext": { + "version": "0.10.45", + "resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.45.tgz", + "integrity": "sha512-FkfM6Vxxfmztilbxxz5UKSD4ICMf5tSpRFtDNtkAhOxZ0EKtX6qwmXNyH/sFyIbX2P/nU5AMiA9jilWsUGJzCQ==", + "dev": true, + "requires": { + "es6-iterator": "~2.0.3", + "es6-symbol": "~3.1.1", + "next-tick": "1" + } + }, + "es6-iterator": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/es6-iterator/-/es6-iterator-2.0.3.tgz", + "integrity": "sha1-p96IkUGgWpSwhUQDstCg+/qY87c=", + "dev": true, + "requires": { + "d": "1", + "es5-ext": "^0.10.35", + "es6-symbol": "^3.1.1" + } + }, + "es6-map": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/es6-map/-/es6-map-0.1.5.tgz", + "integrity": "sha1-kTbgUD3MBqMBaQ8LsU/042TpSfA=", + "dev": true, + "requires": { + "d": "1", + "es5-ext": "~0.10.14", + "es6-iterator": "~2.0.1", + "es6-set": "~0.1.5", + "es6-symbol": "~3.1.1", + "event-emitter": "~0.3.5" + } + }, + "es6-set": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/es6-set/-/es6-set-0.1.5.tgz", + "integrity": "sha1-0rPsXU2ADO2BjbU40ol02wpzzLE=", + "dev": true, + "requires": { + "d": "1", + "es5-ext": "~0.10.14", + "es6-iterator": "~2.0.1", + "es6-symbol": "3.1.1", + "event-emitter": "~0.3.5" + } + }, + "es6-symbol": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/es6-symbol/-/es6-symbol-3.1.1.tgz", + "integrity": "sha1-vwDvT9q2uhtG7Le2KbTH7VcVzHc=", + "dev": true, + "requires": { + "d": "1", + "es5-ext": "~0.10.14" + } + }, + "es6-weak-map": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/es6-weak-map/-/es6-weak-map-2.0.2.tgz", + "integrity": "sha1-XjqzIlH/0VOKH45f+hNXdy+S2W8=", + "dev": true, + "requires": { + "d": "1", + "es5-ext": "^0.10.14", + "es6-iterator": "^2.0.1", + "es6-symbol": "^3.1.1" + } + }, + "escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=" + }, + "escope": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/escope/-/escope-3.6.0.tgz", + "integrity": "sha1-4Bl16BJ4GhY6ba392AOY3GTIicM=", + "dev": true, + "requires": { + "es6-map": "^0.1.3", + "es6-weak-map": "^2.0.1", + "esrecurse": "^4.1.0", + "estraverse": "^4.1.1" + } + }, + "eslint": { + "version": "3.19.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-3.19.0.tgz", + "integrity": "sha1-yPxiAcf0DdCJQbh8CFdnOGpnmsw=", + "dev": true, + "requires": { + "babel-code-frame": "^6.16.0", + "chalk": "^1.1.3", + "concat-stream": "^1.5.2", + "debug": "^2.1.1", + "doctrine": "^2.0.0", + "escope": "^3.6.0", + "espree": "^3.4.0", + "esquery": "^1.0.0", + "estraverse": "^4.2.0", + "esutils": "^2.0.2", + "file-entry-cache": "^2.0.0", + "glob": "^7.0.3", + "globals": "^9.14.0", + "ignore": "^3.2.0", + "imurmurhash": "^0.1.4", + "inquirer": "^0.12.0", + "is-my-json-valid": "^2.10.0", + "is-resolvable": "^1.0.0", + "js-yaml": "^3.5.1", + "json-stable-stringify": "^1.0.0", + "levn": "^0.3.0", + "lodash": "^4.0.0", + "mkdirp": "^0.5.0", + "natural-compare": "^1.4.0", + "optionator": "^0.8.2", + "path-is-inside": "^1.0.1", + "pluralize": "^1.2.1", + "progress": "^1.1.8", + "require-uncached": "^1.0.2", + "shelljs": "^0.7.5", + "strip-bom": "^3.0.0", + "strip-json-comments": "~2.0.1", + "table": "^3.7.8", + "text-table": "~0.2.0", + "user-home": "^2.0.0" + }, + "dependencies": { + "ansi-styles": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", + "dev": true + }, + "chalk": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", + "dev": true, + "requires": { + "ansi-styles": "^2.2.1", + "escape-string-regexp": "^1.0.2", + "has-ansi": "^2.0.0", + "strip-ansi": "^3.0.0", + "supports-color": "^2.0.0" + } + }, + "supports-color": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", + "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", + "dev": true + } + } + }, + "espree": { + "version": "3.5.4", + "resolved": "https://registry.npmjs.org/espree/-/espree-3.5.4.tgz", + "integrity": "sha512-yAcIQxtmMiB/jL32dzEp2enBeidsB7xWPLNiw3IIkpVds1P+h7qF9YwJq1yUNzp2OKXgAprs4F61ih66UsoD1A==", + "dev": true, + "requires": { + "acorn": "^5.5.0", + "acorn-jsx": "^3.0.0" + } + }, + "esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "dev": true + }, + "esquery": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.0.1.tgz", + "integrity": "sha512-SmiyZ5zIWH9VM+SRUReLS5Q8a7GxtRdxEBVZpm98rJM7Sb+A9DVCndXfkeFUd3byderg+EbDkfnevfCwynWaNA==", + "dev": true, + "requires": { + "estraverse": "^4.0.0" + } + }, + "esrecurse": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.2.1.tgz", + "integrity": "sha512-64RBB++fIOAXPw3P9cy89qfMlvZEXZkqqJkjqqXIvzP5ezRZjW+lPWjw35UX/3EhUPFYbg5ER4JYgDw4007/DQ==", + "dev": true, + "requires": { + "estraverse": "^4.1.0" + } + }, + "estraverse": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.2.0.tgz", + "integrity": "sha1-De4/7TH81GlhjOc0IJn8GvoL2xM=", + "dev": true + }, + "esutils": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.2.tgz", + "integrity": "sha1-Cr9PHKpbyx96nYrMbepPqqBLrJs=", + "dev": true + }, + "event-emitter": { + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/event-emitter/-/event-emitter-0.3.5.tgz", + "integrity": "sha1-34xp7vFkeSPHFXuc6DhAYQsCzDk=", + "dev": true, + "requires": { + "d": "1", + "es5-ext": "~0.10.14" + } + }, + "exit-hook": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/exit-hook/-/exit-hook-1.1.1.tgz", + "integrity": "sha1-8FyiM7SMBdVP/wd2XfhQfpXAL/g=", + "dev": true + }, + "fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", + "dev": true + }, + "figures": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/figures/-/figures-1.7.0.tgz", + "integrity": "sha1-y+Hjr/zxzUS4DK3+0o3Hk6lwHS4=", + "dev": true, + "requires": { + "escape-string-regexp": "^1.0.5", + "object-assign": "^4.1.0" + } + }, + "file-entry-cache": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-2.0.0.tgz", + "integrity": "sha1-w5KZDD5oR4PYOLjISkXYoEhFg2E=", + "dev": true, + "requires": { + "flat-cache": "^1.2.1", + "object-assign": "^4.0.1" + } + }, + "flat-cache": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-1.3.0.tgz", + "integrity": "sha1-0wMLMrOBVPTjt+nHCfSQ9++XxIE=", + "dev": true, + "requires": { + "circular-json": "^0.3.1", + "del": "^2.0.2", + "graceful-fs": "^4.1.2", + "write": "^0.2.1" + } + }, + "for-each": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz", + "integrity": "sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==", + "dev": true, + "requires": { + "is-callable": "^1.1.3" + } + }, + "foreach": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/foreach/-/foreach-2.0.5.tgz", + "integrity": "sha1-C+4AUBiusmDQo6865ljdATbsG5k=", + "dev": true + }, + "fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", + "dev": true + }, + "function-bind": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", + "dev": true + }, + "generate-function": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/generate-function/-/generate-function-2.0.0.tgz", + "integrity": "sha1-aFj+fAlpt9TpCTM3ZHrHn2DfvnQ=", + "dev": true + }, + "generate-object-property": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/generate-object-property/-/generate-object-property-1.2.0.tgz", + "integrity": "sha1-nA4cQDCM6AT0eDYYuTf6iPmdUNA=", + "dev": true, + "requires": { + "is-property": "^1.0.0" + } + }, + "glob": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz", + "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==", + "dev": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "globals": { + "version": "9.18.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-9.18.0.tgz", + "integrity": "sha512-S0nG3CLEQiY/ILxqtztTWH/3iRRdyBLw6KMDxnKMchrtbj2OFmehVh0WUCfW3DUrIgx/qFrJPICrq4Z4sTR9UQ==", + "dev": true + }, + "globby": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-5.0.0.tgz", + "integrity": "sha1-69hGZ8oNuzMLmbz8aOrCvFQ3Dg0=", + "dev": true, + "requires": { + "array-union": "^1.0.1", + "arrify": "^1.0.0", + "glob": "^7.0.3", + "object-assign": "^4.0.1", + "pify": "^2.0.0", + "pinkie-promise": "^2.0.0" + } + }, + "graceful-fs": { + "version": "4.1.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.11.tgz", + "integrity": "sha1-Dovf5NHduIVNZOBOp8AOKgJuVlg=", + "dev": true + }, + "has": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", + "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "dev": true, + "requires": { + "function-bind": "^1.1.1" + } + }, + "has-ansi": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", + "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=", + "dev": true, + "requires": { + "ansi-regex": "^2.0.0" + } + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=" + }, + "ignore": { + "version": "3.3.10", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-3.3.10.tgz", + "integrity": "sha512-Pgs951kaMm5GXP7MOvxERINe3gsaVjUWFm+UZPSq9xYriQAksyhg0csnS0KXSNRD5NmNdapXEpjxG49+AKh/ug==", + "dev": true + }, + "imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", + "dev": true + }, + "inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "dev": true, + "requires": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "inherits": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", + "dev": true + }, + "inquirer": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-0.12.0.tgz", + "integrity": "sha1-HvK/1jUE3wvHV4X/+MLEHfEvB34=", + "dev": true, + "requires": { + "ansi-escapes": "^1.1.0", + "ansi-regex": "^2.0.0", + "chalk": "^1.0.0", + "cli-cursor": "^1.0.1", + "cli-width": "^2.0.0", + "figures": "^1.3.5", + "lodash": "^4.3.0", + "readline2": "^1.0.1", + "run-async": "^0.1.0", + "rx-lite": "^3.1.2", + "string-width": "^1.0.1", + "strip-ansi": "^3.0.0", + "through": "^2.3.6" + }, + "dependencies": { + "ansi-styles": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", + "dev": true + }, + "chalk": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", + "dev": true, + "requires": { + "ansi-styles": "^2.2.1", + "escape-string-regexp": "^1.0.2", + "has-ansi": "^2.0.0", + "strip-ansi": "^3.0.0", + "supports-color": "^2.0.0" + } + }, + "supports-color": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", + "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", + "dev": true + } + } + }, + "interpret": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.1.0.tgz", + "integrity": "sha1-ftGxQQxqDg94z5XTuEQMY/eLhhQ=", + "dev": true + }, + "is-arrayish": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.3.2.tgz", + "integrity": "sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==" + }, + "is-callable": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.1.4.tgz", + "integrity": "sha512-r5p9sxJjYnArLjObpjA4xu5EKI3CuKHkJXMhT7kwbpUyIFD1n5PMAsoPvWnvtZiNz7LjkYDRZhd7FlI0eMijEA==", + "dev": true + }, + "is-date-object": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.1.tgz", + "integrity": "sha1-mqIOtq7rv/d/vTPnTKAbM1gdOhY=", + "dev": true + }, + "is-fullwidth-code-point": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", + "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", + "dev": true, + "requires": { + "number-is-nan": "^1.0.0" + } + }, + "is-my-ip-valid": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-my-ip-valid/-/is-my-ip-valid-1.0.0.tgz", + "integrity": "sha512-gmh/eWXROncUzRnIa1Ubrt5b8ep/MGSnfAUI3aRp+sqTCs1tv1Isl8d8F6JmkN3dXKc3ehZMrtiPN9eL03NuaQ==", + "dev": true + }, + "is-my-json-valid": { + "version": "2.18.0", + "resolved": "https://registry.npmjs.org/is-my-json-valid/-/is-my-json-valid-2.18.0.tgz", + "integrity": "sha512-DWT87JHCSdCPCxbqBpS6Z2ajAt+MvrJq8I4xrpQljCvzODO5/fiquBp20a3sN6yCJvFbCRyYvJOHjpzkPTKJyA==", + "dev": true, + "requires": { + "generate-function": "^2.0.0", + "generate-object-property": "^1.1.0", + "is-my-ip-valid": "^1.0.0", + "jsonpointer": "^4.0.0", + "xtend": "^4.0.0" + } + }, + "is-path-cwd": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-path-cwd/-/is-path-cwd-1.0.0.tgz", + "integrity": "sha1-0iXsIxMuie3Tj9p2dHLmLmXxEG0=", + "dev": true + }, + "is-path-in-cwd": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-path-in-cwd/-/is-path-in-cwd-1.0.1.tgz", + "integrity": "sha512-FjV1RTW48E7CWM7eE/J2NJvAEEVektecDBVBE5Hh3nM1Jd0kvhHtX68Pr3xsDf857xt3Y4AkwVULK1Vku62aaQ==", + "dev": true, + "requires": { + "is-path-inside": "^1.0.0" + } + }, + "is-path-inside": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-1.0.1.tgz", + "integrity": "sha1-jvW33lBDej/cprToZe96pVy0gDY=", + "dev": true, + "requires": { + "path-is-inside": "^1.0.1" + } + }, + "is-property": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-property/-/is-property-1.0.2.tgz", + "integrity": "sha1-V/4cTkhHTt1lsJkR8msc1Ald2oQ=", + "dev": true + }, + "is-regex": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.0.4.tgz", + "integrity": "sha1-VRdIm1RwkbCTDglWVM7SXul+lJE=", + "dev": true, + "requires": { + "has": "^1.0.1" + } + }, + "is-resolvable": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-resolvable/-/is-resolvable-1.1.0.tgz", + "integrity": "sha512-qgDYXFSR5WvEfuS5dMj6oTMEbrrSaM0CrFk2Yiq/gXnBvD9pMa2jGXxyhGLfvhZpuMZe18CJpFxAt3CRs42NMg==", + "dev": true + }, + "is-symbol": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.1.tgz", + "integrity": "sha1-PMWfAAJRlLarLjjbrmaJJWtmBXI=", + "dev": true + }, + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", + "dev": true + }, + "js-tokens": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-3.0.2.tgz", + "integrity": "sha1-mGbfOVECEw449/mWvOtlRDIJwls=", + "dev": true + }, + "js-yaml": { + "version": "3.12.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.12.0.tgz", + "integrity": "sha512-PIt2cnwmPfL4hKNwqeiuz4bKfnzHTBv6HyVgjahA6mPLwPDzjDWrplJBMjHUFxku/N3FlmrbyPclad+I+4mJ3A==", + "dev": true, + "requires": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + } + }, + "json-stable-stringify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify/-/json-stable-stringify-1.0.1.tgz", + "integrity": "sha1-mnWdOcXy/1A/1TAGRu1EX4jE+a8=", + "dev": true, + "requires": { + "jsonify": "~0.0.0" + } + }, + "jsonify": { + "version": "0.0.0", + "resolved": "https://registry.npmjs.org/jsonify/-/jsonify-0.0.0.tgz", + "integrity": "sha1-LHS27kHZPKUbe1qu6PUDYx0lKnM=", + "dev": true + }, + "jsonpointer": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/jsonpointer/-/jsonpointer-4.0.1.tgz", + "integrity": "sha1-T9kss04OnbPInIYi7PUfm5eMbLk=", + "dev": true + }, + "levn": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", + "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=", + "dev": true, + "requires": { + "prelude-ls": "~1.1.2", + "type-check": "~0.3.2" + } + }, + "lodash": { + "version": "4.17.10", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.10.tgz", + "integrity": "sha512-UejweD1pDoXu+AD825lWwp4ZGtSwgnpZxb3JDViD7StjQz+Nb/6l093lx4OQ0foGWNRoc19mWy7BzL+UAK2iVg==", + "dev": true + }, + "minimatch": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", + "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "dev": true, + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "minimist": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", + "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=", + "dev": true + }, + "mkdirp": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", + "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", + "dev": true, + "requires": { + "minimist": "0.0.8" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + }, + "mute-stream": { + "version": "0.0.5", + "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.5.tgz", + "integrity": "sha1-j7+rsKmKJT0xhDMfno3rc3L6xsA=", + "dev": true + }, + "natural-compare": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=", + "dev": true + }, + "next-tick": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/next-tick/-/next-tick-1.0.0.tgz", + "integrity": "sha1-yobR/ogoFpsBICCOPchCS524NCw=", + "dev": true + }, + "number-is-nan": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", + "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=", + "dev": true + }, + "object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", + "dev": true + }, + "object-inspect": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.6.0.tgz", + "integrity": "sha512-GJzfBZ6DgDAmnuaM3104jR4s1Myxr3Y3zfIyN4z3UdqN69oSRacNK8UhnobDdC+7J2AHCjGwxQubNJfE70SXXQ==", + "dev": true + }, + "object-keys": { + "version": "1.0.12", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.0.12.tgz", + "integrity": "sha512-FTMyFUm2wBcGHnH2eXmz7tC6IwlqQZ6mVZ+6dm6vZ4IQIHjs6FdNsQBuKGPuUUUY6NfJw2PshC08Tn6LzLDOag==", + "dev": true + }, + "once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "dev": true, + "requires": { + "wrappy": "1" + } + }, + "onetime": { + "version": "1.1.0", + "resolved": "http://registry.npmjs.org/onetime/-/onetime-1.1.0.tgz", + "integrity": "sha1-ofeDj4MUxRbwXs78vEzP4EtO14k=", + "dev": true + }, + "optionator": { + "version": "0.8.2", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.2.tgz", + "integrity": "sha1-NkxeQJ0/TWMB1sC0wFu6UBgK62Q=", + "dev": true, + "requires": { + "deep-is": "~0.1.3", + "fast-levenshtein": "~2.0.4", + "levn": "~0.3.0", + "prelude-ls": "~1.1.2", + "type-check": "~0.3.2", + "wordwrap": "~1.0.0" + } + }, + "os-homedir": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz", + "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=", + "dev": true + }, + "path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", + "dev": true + }, + "path-is-inside": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz", + "integrity": "sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM=", + "dev": true + }, + "path-parse": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz", + "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==", + "dev": true + }, + "pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", + "dev": true + }, + "pinkie": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz", + "integrity": "sha1-clVrgM+g1IqXToDnckjoDtT3+HA=", + "dev": true + }, + "pinkie-promise": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz", + "integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=", + "dev": true, + "requires": { + "pinkie": "^2.0.0" + } + }, + "pluralize": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/pluralize/-/pluralize-1.2.1.tgz", + "integrity": "sha1-0aIUg/0iu0HlihL6NCGCMUCJfEU=", + "dev": true + }, + "postcss": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.2.tgz", + "integrity": "sha512-fmaUY5370keLUTx+CnwRxtGiuFTcNBLQBqr1oE3WZ/euIYmGAo0OAgOhVJ3ByDnVmOR3PK+0V9VebzfjRIUcqw==", + "requires": { + "chalk": "^2.4.1", + "source-map": "^0.6.1", + "supports-color": "^5.4.0" + } + }, + "postcss-message-helpers": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/postcss-message-helpers/-/postcss-message-helpers-2.0.0.tgz", + "integrity": "sha1-pPL0+rbk/gAvCu0ABHjN9S+bpg4=" + }, + "prelude-ls": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", + "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=", + "dev": true + }, + "process-nextick-args": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.0.tgz", + "integrity": "sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw==", + "dev": true + }, + "progress": { + "version": "1.1.8", + "resolved": "https://registry.npmjs.org/progress/-/progress-1.1.8.tgz", + "integrity": "sha1-4mDHj2Fhzdmw5WzD4Khd4Xx6V74=", + "dev": true + }, + "readable-stream": { + "version": "2.3.6", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", + "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", + "dev": true, + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "readline2": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/readline2/-/readline2-1.0.1.tgz", + "integrity": "sha1-QQWWCP/BVHV7cV2ZidGZ/783LjU=", + "dev": true, + "requires": { + "code-point-at": "^1.0.0", + "is-fullwidth-code-point": "^1.0.0", + "mute-stream": "0.0.5" + } + }, + "rechoir": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.6.2.tgz", + "integrity": "sha1-hSBLVNuoLVdC4oyWdW70OvUOM4Q=", + "dev": true, + "requires": { + "resolve": "^1.1.6" + } + }, + "require-uncached": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/require-uncached/-/require-uncached-1.0.3.tgz", + "integrity": "sha1-Tg1W1slmL9MeQwEcS5WqSZVUIdM=", + "dev": true, + "requires": { + "caller-path": "^0.1.0", + "resolve-from": "^1.0.0" + } + }, + "resolve": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.8.1.tgz", + "integrity": "sha512-AicPrAC7Qu1JxPCZ9ZgCZlY35QgFnNqc+0LtbRNxnVw4TXvjQ72wnuL9JQcEBgXkI9JM8MsT9kaQoHcpCRJOYA==", + "dev": true, + "requires": { + "path-parse": "^1.0.5" + } + }, + "resolve-from": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-1.0.1.tgz", + "integrity": "sha1-Jsv+k10a7uq7Kbw/5a6wHpPUQiY=", + "dev": true + }, + "restore-cursor": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-1.0.1.tgz", + "integrity": "sha1-NGYfRohjJ/7SmRR5FSJS35LapUE=", + "dev": true, + "requires": { + "exit-hook": "^1.0.0", + "onetime": "^1.0.0" + } + }, + "resumer": { + "version": "0.0.0", + "resolved": "https://registry.npmjs.org/resumer/-/resumer-0.0.0.tgz", + "integrity": "sha1-8ej0YeQGS6Oegq883CqMiT0HZ1k=", + "dev": true, + "requires": { + "through": "~2.3.4" + } + }, + "rimraf": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.2.tgz", + "integrity": "sha512-lreewLK/BlghmxtfH36YYVg1i8IAce4TI7oao75I1g245+6BctqTVQiBP3YUJ9C6DQOXJmkYR9X9fCLtCOJc5w==", + "dev": true, + "requires": { + "glob": "^7.0.5" + } + }, + "run-async": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/run-async/-/run-async-0.1.0.tgz", + "integrity": "sha1-yK1KXhEGYeQCp9IbUw4AnyX444k=", + "dev": true, + "requires": { + "once": "^1.3.0" + } + }, + "rx-lite": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/rx-lite/-/rx-lite-3.1.2.tgz", + "integrity": "sha1-Gc5QLKVyZl87ZHsQk5+X/RYV8QI=", + "dev": true + }, + "safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true + }, + "shelljs": { + "version": "0.7.8", + "resolved": "https://registry.npmjs.org/shelljs/-/shelljs-0.7.8.tgz", + "integrity": "sha1-3svPh0sNHl+3LhSxZKloMEjprLM=", + "dev": true, + "requires": { + "glob": "^7.0.0", + "interpret": "^1.0.0", + "rechoir": "^0.6.2" + } + }, + "simple-swizzle": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/simple-swizzle/-/simple-swizzle-0.2.2.tgz", + "integrity": "sha1-pNprY1/8zMoz9w0Xy5JZLeleVXo=", + "requires": { + "is-arrayish": "^0.3.1" + } + }, + "slice-ansi": { + "version": "0.0.4", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-0.0.4.tgz", + "integrity": "sha1-7b+JA/ZvfOL46v1s7tZeJkyDGzU=", + "dev": true + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" + }, + "sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", + "dev": true + }, + "string-width": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", + "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", + "dev": true, + "requires": { + "code-point-at": "^1.0.0", + "is-fullwidth-code-point": "^1.0.0", + "strip-ansi": "^3.0.0" + } + }, + "string.prototype.trim": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.1.2.tgz", + "integrity": "sha1-0E3iyJ4Tf019IG8Ia17S+ua+jOo=", + "dev": true, + "requires": { + "define-properties": "^1.1.2", + "es-abstract": "^1.5.0", + "function-bind": "^1.0.2" + } + }, + "string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dev": true, + "requires": { + "safe-buffer": "~5.1.0" + } + }, + "strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "dev": true, + "requires": { + "ansi-regex": "^2.0.0" + } + }, + "strip-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", + "dev": true + }, + "strip-json-comments": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", + "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=", + "dev": true + }, + "supports-color": { + "version": "5.4.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.4.0.tgz", + "integrity": "sha512-zjaXglF5nnWpsq470jSv6P9DwPvgLkuapYmfDm3JWOm0vkNTVF2tI4UrN2r6jH1qM/uc/WtxYY1hYoA2dOKj5w==", + "requires": { + "has-flag": "^3.0.0" + } + }, + "table": { + "version": "3.8.3", + "resolved": "https://registry.npmjs.org/table/-/table-3.8.3.tgz", + "integrity": "sha1-K7xULw/amGGnVdOUf+/Ys/UThV8=", + "dev": true, + "requires": { + "ajv": "^4.7.0", + "ajv-keywords": "^1.0.0", + "chalk": "^1.1.1", + "lodash": "^4.0.0", + "slice-ansi": "0.0.4", + "string-width": "^2.0.0" + }, + "dependencies": { + "ansi-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", + "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", + "dev": true + }, + "ansi-styles": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", + "dev": true + }, + "chalk": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", + "dev": true, + "requires": { + "ansi-styles": "^2.2.1", + "escape-string-regexp": "^1.0.2", + "has-ansi": "^2.0.0", + "strip-ansi": "^3.0.0", + "supports-color": "^2.0.0" + } + }, + "is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", + "dev": true + }, + "string-width": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", + "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", + "dev": true, + "requires": { + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^4.0.0" + }, + "dependencies": { + "strip-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", + "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", + "dev": true, + "requires": { + "ansi-regex": "^3.0.0" + } + } + } + }, + "supports-color": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", + "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", + "dev": true + } + } + }, + "tape": { + "version": "4.9.1", + "resolved": "https://registry.npmjs.org/tape/-/tape-4.9.1.tgz", + "integrity": "sha512-6fKIXknLpoe/Jp4rzHKFPpJUHDHDqn8jus99IfPnHIjyz78HYlefTGD3b5EkbQzuLfaEvmfPK3IolLgq2xT3kw==", + "dev": true, + "requires": { + "deep-equal": "~1.0.1", + "defined": "~1.0.0", + "for-each": "~0.3.3", + "function-bind": "~1.1.1", + "glob": "~7.1.2", + "has": "~1.0.3", + "inherits": "~2.0.3", + "minimist": "~1.2.0", + "object-inspect": "~1.6.0", + "resolve": "~1.7.1", + "resumer": "~0.0.0", + "string.prototype.trim": "~1.1.2", + "through": "~2.3.8" + }, + "dependencies": { + "minimist": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", + "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", + "dev": true + }, + "resolve": { + "version": "1.7.1", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.7.1.tgz", + "integrity": "sha512-c7rwLofp8g1U+h1KNyHL/jicrKg1Ek4q+Lr33AL65uZTinUZHe30D5HlyN5V9NW0JX1D5dXQ4jqW5l7Sy/kGfw==", + "dev": true, + "requires": { + "path-parse": "^1.0.5" + } + } + } + }, + "text-table": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", + "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=", + "dev": true + }, + "through": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", + "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=", + "dev": true + }, + "type-check": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", + "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=", + "dev": true, + "requires": { + "prelude-ls": "~1.1.2" + } + }, + "typedarray": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", + "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=", + "dev": true + }, + "user-home": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/user-home/-/user-home-2.0.0.tgz", + "integrity": "sha1-nHC/2Babwdy/SGBODwS4tJzenp8=", + "dev": true, + "requires": { + "os-homedir": "^1.0.0" + } + }, + "util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=", + "dev": true + }, + "wordwrap": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", + "integrity": "sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus=", + "dev": true + }, + "wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", + "dev": true + }, + "write": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/write/-/write-0.2.1.tgz", + "integrity": "sha1-X8A4KOJkzqP+kUVUdvejxWbLB1c=", + "dev": true, + "requires": { + "mkdirp": "^0.5.1" + } + }, + "xtend": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz", + "integrity": "sha1-pcbVMr5lbiPbgg77lDofBJmNY68=", + "dev": true + } + } +} diff --git a/package.json b/package.json index 48336b2bd8..3dbdf7e784 100644 --- a/package.json +++ b/package.json @@ -20,9 +20,12 @@ "files": [ "index.js" ], + "engines": { + "node": ">=6.0.0" + }, "dependencies": { "color": "^1.0.3", - "postcss": "^6.0.1", + "postcss": "^7.0.2", "postcss-message-helpers": "^2.0.0" }, "devDependencies": { diff --git a/test/index.js b/test/index.js index b16a67d7a8..de49833831 100755 --- a/test/index.js +++ b/test/index.js @@ -23,7 +23,7 @@ function compareFixtures(t, name, msg, opts, postcssOpts) { opts = opts || {} var actual = transform(read(postcssOpts.from), postcssOpts) var expected = read(filename("fixtures/" + name + ".expected")) - fs.writeFile(filename("fixtures/" + name + ".actual"), actual) + fs.writeFileSync(filename("fixtures/" + name + ".actual"), actual) t.equal(actual, expected, msg) } From 77754167fac853609be3673e06c669108279b96c Mon Sep 17 00:00:00 2001 From: Pascal Duez Date: Mon, 13 Aug 2018 14:35:47 +0200 Subject: [PATCH 655/795] Use PostCSS 7 Also added a `package-lock` file. --- .travis.yml | 2 +- package-lock.json | 3692 +++++++++++++++++++++++++++++++++++++++++++++ package.json | 5 +- 3 files changed, 3697 insertions(+), 2 deletions(-) create mode 100644 package-lock.json diff --git a/.travis.yml b/.travis.yml index 6e538237ad..ebea37eb05 100644 --- a/.travis.yml +++ b/.travis.yml @@ -2,5 +2,5 @@ sudo: false language: node_js node_js: - "stable" + - "8" - "6" - - "4" diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 0000000000..c04923956b --- /dev/null +++ b/package-lock.json @@ -0,0 +1,3692 @@ +{ + "name": "postcss-custom-properties", + "version": "7.0.0", + "lockfileVersion": 1, + "requires": true, + "dependencies": { + "@octokit/rest": { + "version": "14.0.9", + "resolved": "https://registry.npmjs.org/@octokit/rest/-/rest-14.0.9.tgz", + "integrity": "sha512-irP9phKfTXEZIcW2R+VNCtGHZJrXMWmSYp6RRfFn4BtAqtDRXF5z9JxCEQlAhNBf6X1koNi5k49tIAAAEJNlVQ==", + "dev": true, + "requires": { + "before-after-hook": "^1.1.0", + "debug": "^3.1.0", + "is-array-buffer": "^1.0.0", + "is-stream": "^1.1.0", + "lodash": "^4.17.4", + "url-template": "^2.0.8" + }, + "dependencies": { + "debug": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", + "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + } + } + }, + "@sindresorhus/df": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@sindresorhus/df/-/df-2.1.0.tgz", + "integrity": "sha1-0gjPJ+BvC7R20U197M19cm6ao4k=", + "dev": true, + "requires": { + "execa": "^0.2.2" + } + }, + "acorn": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-5.7.1.tgz", + "integrity": "sha512-d+nbxBUGKg7Arpsvbnlq61mc12ek3EY8EQldM3GPAhWJ1UVxC6TDGbIvUMNU6obBX3i1+ptCIzV4vq0gFPEGVQ==", + "dev": true + }, + "acorn-jsx": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-4.1.1.tgz", + "integrity": "sha512-JY+iV6r+cO21KtntVvFkD+iqjtdpRUpGqKWgfkCdZq1R+kbreEl8EcdcJR4SmiIgsIQT33s6QzheQ9a275Q8xw==", + "dev": true, + "requires": { + "acorn": "^5.0.3" + } + }, + "ajv": { + "version": "6.5.2", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.5.2.tgz", + "integrity": "sha512-hOs7GfvI6tUI1LfZddH82ky6mOMyTuY0mk7kE2pWpmhhUSkumzaTO5vbVwij39MdwPQWCV4Zv57Eo06NtL/GVA==", + "dev": true, + "requires": { + "fast-deep-equal": "^2.0.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.1" + } + }, + "ajv-keywords": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.2.0.tgz", + "integrity": "sha1-6GuBnGAs+IIa1jdBNpjx3sAhhHo=", + "dev": true + }, + "ansi-escapes": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-3.1.0.tgz", + "integrity": "sha512-UgAb8H9D41AQnu/PbWlCofQVcnV4Gs2bBJi9eZPxfU/hgglFh3SMDMENRIqdr7H6XFnXdoknctFByVsCOotTVw==", + "dev": true + }, + "ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", + "dev": true + }, + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "requires": { + "color-convert": "^1.9.0" + } + }, + "anymatch": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-1.3.2.tgz", + "integrity": "sha512-0XNayC8lTHQ2OI8aljNCN3sSx6hsr/1+rlcDAotXJR7C1oZZHCNsfpbKwMjRA3Uqb5tF1Rae2oloTr4xpq+WjA==", + "dev": true, + "optional": true, + "requires": { + "micromatch": "^2.1.5", + "normalize-path": "^2.0.0" + } + }, + "argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "dev": true, + "requires": { + "sprintf-js": "~1.0.2" + } + }, + "arr-diff": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-2.0.0.tgz", + "integrity": "sha1-jzuCf5Vai9ZpaX5KQlasPOrjVs8=", + "dev": true, + "optional": true, + "requires": { + "arr-flatten": "^1.0.1" + } + }, + "arr-flatten": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/arr-flatten/-/arr-flatten-1.1.0.tgz", + "integrity": "sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==", + "dev": true, + "optional": true + }, + "array-union": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-1.0.2.tgz", + "integrity": "sha1-mjRBDk9OPaI96jdb5b5w8kd47Dk=", + "dev": true, + "requires": { + "array-uniq": "^1.0.1" + } + }, + "array-uniq": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/array-uniq/-/array-uniq-1.0.3.tgz", + "integrity": "sha1-r2rId6Jcx/dOBYiUdThY39sk/bY=", + "dev": true + }, + "array-unique": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.2.1.tgz", + "integrity": "sha1-odl8yvy8JiXMcPrc6zalDFiwGlM=", + "dev": true, + "optional": true + }, + "arrify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", + "integrity": "sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=", + "dev": true + }, + "async-each": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/async-each/-/async-each-1.0.1.tgz", + "integrity": "sha1-GdOGodntxufByF04iu28xW0zYC0=", + "dev": true, + "optional": true + }, + "babel-cli": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-cli/-/babel-cli-6.26.0.tgz", + "integrity": "sha1-UCq1SHTX24itALiHoGODzgPQAvE=", + "dev": true, + "requires": { + "babel-core": "^6.26.0", + "babel-polyfill": "^6.26.0", + "babel-register": "^6.26.0", + "babel-runtime": "^6.26.0", + "chokidar": "^1.6.1", + "commander": "^2.11.0", + "convert-source-map": "^1.5.0", + "fs-readdir-recursive": "^1.0.0", + "glob": "^7.1.2", + "lodash": "^4.17.4", + "output-file-sync": "^1.1.2", + "path-is-absolute": "^1.0.1", + "slash": "^1.0.0", + "source-map": "^0.5.6", + "v8flags": "^2.1.1" + }, + "dependencies": { + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "dev": true + } + } + }, + "babel-code-frame": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-code-frame/-/babel-code-frame-6.26.0.tgz", + "integrity": "sha1-Y/1D99weO7fONZR9uP42mj9Yx0s=", + "dev": true, + "requires": { + "chalk": "^1.1.3", + "esutils": "^2.0.2", + "js-tokens": "^3.0.2" + }, + "dependencies": { + "ansi-styles": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", + "dev": true + }, + "chalk": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", + "dev": true, + "requires": { + "ansi-styles": "^2.2.1", + "escape-string-regexp": "^1.0.2", + "has-ansi": "^2.0.0", + "strip-ansi": "^3.0.0", + "supports-color": "^2.0.0" + } + }, + "supports-color": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", + "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", + "dev": true + } + } + }, + "babel-core": { + "version": "6.26.3", + "resolved": "https://registry.npmjs.org/babel-core/-/babel-core-6.26.3.tgz", + "integrity": "sha512-6jyFLuDmeidKmUEb3NM+/yawG0M2bDZ9Z1qbZP59cyHLz8kYGKYwpJP0UwUKKUiTRNvxfLesJnTedqczP7cTDA==", + "dev": true, + "requires": { + "babel-code-frame": "^6.26.0", + "babel-generator": "^6.26.0", + "babel-helpers": "^6.24.1", + "babel-messages": "^6.23.0", + "babel-register": "^6.26.0", + "babel-runtime": "^6.26.0", + "babel-template": "^6.26.0", + "babel-traverse": "^6.26.0", + "babel-types": "^6.26.0", + "babylon": "^6.18.0", + "convert-source-map": "^1.5.1", + "debug": "^2.6.9", + "json5": "^0.5.1", + "lodash": "^4.17.4", + "minimatch": "^3.0.4", + "path-is-absolute": "^1.0.1", + "private": "^0.1.8", + "slash": "^1.0.0", + "source-map": "^0.5.7" + }, + "dependencies": { + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "dev": true + } + } + }, + "babel-generator": { + "version": "6.26.1", + "resolved": "https://registry.npmjs.org/babel-generator/-/babel-generator-6.26.1.tgz", + "integrity": "sha512-HyfwY6ApZj7BYTcJURpM5tznulaBvyio7/0d4zFOeMPUmfxkCjHocCuoLa2SAGzBI8AREcH3eP3758F672DppA==", + "dev": true, + "requires": { + "babel-messages": "^6.23.0", + "babel-runtime": "^6.26.0", + "babel-types": "^6.26.0", + "detect-indent": "^4.0.0", + "jsesc": "^1.3.0", + "lodash": "^4.17.4", + "source-map": "^0.5.7", + "trim-right": "^1.0.1" + }, + "dependencies": { + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "dev": true + } + } + }, + "babel-helper-builder-binary-assignment-operator-visitor": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-helper-builder-binary-assignment-operator-visitor/-/babel-helper-builder-binary-assignment-operator-visitor-6.24.1.tgz", + "integrity": "sha1-zORReto1b0IgvK6KAsKzRvmlZmQ=", + "dev": true, + "requires": { + "babel-helper-explode-assignable-expression": "^6.24.1", + "babel-runtime": "^6.22.0", + "babel-types": "^6.24.1" + } + }, + "babel-helper-call-delegate": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-helper-call-delegate/-/babel-helper-call-delegate-6.24.1.tgz", + "integrity": "sha1-7Oaqzdx25Bw0YfiL/Fdb0Nqi340=", + "dev": true, + "requires": { + "babel-helper-hoist-variables": "^6.24.1", + "babel-runtime": "^6.22.0", + "babel-traverse": "^6.24.1", + "babel-types": "^6.24.1" + } + }, + "babel-helper-define-map": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-helper-define-map/-/babel-helper-define-map-6.26.0.tgz", + "integrity": "sha1-pfVtq0GiX5fstJjH66ypgZ+Vvl8=", + "dev": true, + "requires": { + "babel-helper-function-name": "^6.24.1", + "babel-runtime": "^6.26.0", + "babel-types": "^6.26.0", + "lodash": "^4.17.4" + } + }, + "babel-helper-explode-assignable-expression": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-helper-explode-assignable-expression/-/babel-helper-explode-assignable-expression-6.24.1.tgz", + "integrity": "sha1-8luCz33BBDPFX3BZLVdGQArCLKo=", + "dev": true, + "requires": { + "babel-runtime": "^6.22.0", + "babel-traverse": "^6.24.1", + "babel-types": "^6.24.1" + } + }, + "babel-helper-function-name": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-helper-function-name/-/babel-helper-function-name-6.24.1.tgz", + "integrity": "sha1-00dbjAPtmCQqJbSDUasYOZ01gKk=", + "dev": true, + "requires": { + "babel-helper-get-function-arity": "^6.24.1", + "babel-runtime": "^6.22.0", + "babel-template": "^6.24.1", + "babel-traverse": "^6.24.1", + "babel-types": "^6.24.1" + } + }, + "babel-helper-get-function-arity": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-helper-get-function-arity/-/babel-helper-get-function-arity-6.24.1.tgz", + "integrity": "sha1-j3eCqpNAfEHTqlCQj4mwMbG2hT0=", + "dev": true, + "requires": { + "babel-runtime": "^6.22.0", + "babel-types": "^6.24.1" + } + }, + "babel-helper-hoist-variables": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-helper-hoist-variables/-/babel-helper-hoist-variables-6.24.1.tgz", + "integrity": "sha1-HssnaJydJVE+rbyZFKc/VAi+enY=", + "dev": true, + "requires": { + "babel-runtime": "^6.22.0", + "babel-types": "^6.24.1" + } + }, + "babel-helper-optimise-call-expression": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-helper-optimise-call-expression/-/babel-helper-optimise-call-expression-6.24.1.tgz", + "integrity": "sha1-96E0J7qfc/j0+pk8VKl4gtEkQlc=", + "dev": true, + "requires": { + "babel-runtime": "^6.22.0", + "babel-types": "^6.24.1" + } + }, + "babel-helper-regex": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-helper-regex/-/babel-helper-regex-6.26.0.tgz", + "integrity": "sha1-MlxZ+QL4LyS3T6zu0DY5VPZJXnI=", + "dev": true, + "requires": { + "babel-runtime": "^6.26.0", + "babel-types": "^6.26.0", + "lodash": "^4.17.4" + } + }, + "babel-helper-remap-async-to-generator": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-helper-remap-async-to-generator/-/babel-helper-remap-async-to-generator-6.24.1.tgz", + "integrity": "sha1-XsWBgnrXI/7N04HxySg5BnbkVRs=", + "dev": true, + "requires": { + "babel-helper-function-name": "^6.24.1", + "babel-runtime": "^6.22.0", + "babel-template": "^6.24.1", + "babel-traverse": "^6.24.1", + "babel-types": "^6.24.1" + } + }, + "babel-helper-replace-supers": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-helper-replace-supers/-/babel-helper-replace-supers-6.24.1.tgz", + "integrity": "sha1-v22/5Dk40XNpohPKiov3S2qQqxo=", + "dev": true, + "requires": { + "babel-helper-optimise-call-expression": "^6.24.1", + "babel-messages": "^6.23.0", + "babel-runtime": "^6.22.0", + "babel-template": "^6.24.1", + "babel-traverse": "^6.24.1", + "babel-types": "^6.24.1" + } + }, + "babel-helpers": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-helpers/-/babel-helpers-6.24.1.tgz", + "integrity": "sha1-NHHenK7DiOXIUOWX5Yom3fN2ArI=", + "dev": true, + "requires": { + "babel-runtime": "^6.22.0", + "babel-template": "^6.24.1" + } + }, + "babel-messages": { + "version": "6.23.0", + "resolved": "https://registry.npmjs.org/babel-messages/-/babel-messages-6.23.0.tgz", + "integrity": "sha1-8830cDhYA1sqKVHG7F7fbGLyYw4=", + "dev": true, + "requires": { + "babel-runtime": "^6.22.0" + } + }, + "babel-plugin-add-module-exports": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/babel-plugin-add-module-exports/-/babel-plugin-add-module-exports-0.2.1.tgz", + "integrity": "sha1-mumh9KjcZ/DN7E9K7aHkOl/2XiU=", + "dev": true + }, + "babel-plugin-check-es2015-constants": { + "version": "6.22.0", + "resolved": "https://registry.npmjs.org/babel-plugin-check-es2015-constants/-/babel-plugin-check-es2015-constants-6.22.0.tgz", + "integrity": "sha1-NRV7EBQm/S/9PaP3XH0ekYNbv4o=", + "dev": true, + "requires": { + "babel-runtime": "^6.22.0" + } + }, + "babel-plugin-syntax-async-functions": { + "version": "6.13.0", + "resolved": "https://registry.npmjs.org/babel-plugin-syntax-async-functions/-/babel-plugin-syntax-async-functions-6.13.0.tgz", + "integrity": "sha1-ytnK0RkbWtY0vzCuCHI5HgZHvpU=", + "dev": true + }, + "babel-plugin-syntax-exponentiation-operator": { + "version": "6.13.0", + "resolved": "https://registry.npmjs.org/babel-plugin-syntax-exponentiation-operator/-/babel-plugin-syntax-exponentiation-operator-6.13.0.tgz", + "integrity": "sha1-nufoM3KQ2pUoggGmpX9BcDF4MN4=", + "dev": true + }, + "babel-plugin-syntax-trailing-function-commas": { + "version": "6.22.0", + "resolved": "https://registry.npmjs.org/babel-plugin-syntax-trailing-function-commas/-/babel-plugin-syntax-trailing-function-commas-6.22.0.tgz", + "integrity": "sha1-ugNgk3+NBuQBgKQ/4NVhb/9TLPM=", + "dev": true + }, + "babel-plugin-transform-async-to-generator": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-async-to-generator/-/babel-plugin-transform-async-to-generator-6.24.1.tgz", + "integrity": "sha1-ZTbjeK/2yx1VF6wOQOs+n8jQh2E=", + "dev": true, + "requires": { + "babel-helper-remap-async-to-generator": "^6.24.1", + "babel-plugin-syntax-async-functions": "^6.8.0", + "babel-runtime": "^6.22.0" + } + }, + "babel-plugin-transform-es2015-arrow-functions": { + "version": "6.22.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-arrow-functions/-/babel-plugin-transform-es2015-arrow-functions-6.22.0.tgz", + "integrity": "sha1-RSaSy3EdX3ncf4XkQM5BufJE0iE=", + "dev": true, + "requires": { + "babel-runtime": "^6.22.0" + } + }, + "babel-plugin-transform-es2015-block-scoped-functions": { + "version": "6.22.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-block-scoped-functions/-/babel-plugin-transform-es2015-block-scoped-functions-6.22.0.tgz", + "integrity": "sha1-u8UbSflk1wy42OC5ToICRs46YUE=", + "dev": true, + "requires": { + "babel-runtime": "^6.22.0" + } + }, + "babel-plugin-transform-es2015-block-scoping": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-block-scoping/-/babel-plugin-transform-es2015-block-scoping-6.26.0.tgz", + "integrity": "sha1-1w9SmcEwjQXBL0Y4E7CgnnOxiV8=", + "dev": true, + "requires": { + "babel-runtime": "^6.26.0", + "babel-template": "^6.26.0", + "babel-traverse": "^6.26.0", + "babel-types": "^6.26.0", + "lodash": "^4.17.4" + } + }, + "babel-plugin-transform-es2015-classes": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-classes/-/babel-plugin-transform-es2015-classes-6.24.1.tgz", + "integrity": "sha1-WkxYpQyclGHlZLSyo7+ryXolhNs=", + "dev": true, + "requires": { + "babel-helper-define-map": "^6.24.1", + "babel-helper-function-name": "^6.24.1", + "babel-helper-optimise-call-expression": "^6.24.1", + "babel-helper-replace-supers": "^6.24.1", + "babel-messages": "^6.23.0", + "babel-runtime": "^6.22.0", + "babel-template": "^6.24.1", + "babel-traverse": "^6.24.1", + "babel-types": "^6.24.1" + } + }, + "babel-plugin-transform-es2015-computed-properties": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-computed-properties/-/babel-plugin-transform-es2015-computed-properties-6.24.1.tgz", + "integrity": "sha1-b+Ko0WiV1WNPTNmZttNICjCBWbM=", + "dev": true, + "requires": { + "babel-runtime": "^6.22.0", + "babel-template": "^6.24.1" + } + }, + "babel-plugin-transform-es2015-destructuring": { + "version": "6.23.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-destructuring/-/babel-plugin-transform-es2015-destructuring-6.23.0.tgz", + "integrity": "sha1-mXux8auWf2gtKwh2/jWNYOdlxW0=", + "dev": true, + "requires": { + "babel-runtime": "^6.22.0" + } + }, + "babel-plugin-transform-es2015-duplicate-keys": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-duplicate-keys/-/babel-plugin-transform-es2015-duplicate-keys-6.24.1.tgz", + "integrity": "sha1-c+s9MQypaePvnskcU3QabxV2Qj4=", + "dev": true, + "requires": { + "babel-runtime": "^6.22.0", + "babel-types": "^6.24.1" + } + }, + "babel-plugin-transform-es2015-for-of": { + "version": "6.23.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-for-of/-/babel-plugin-transform-es2015-for-of-6.23.0.tgz", + "integrity": "sha1-9HyVsrYT3x0+zC/bdXNiPHUkhpE=", + "dev": true, + "requires": { + "babel-runtime": "^6.22.0" + } + }, + "babel-plugin-transform-es2015-function-name": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-function-name/-/babel-plugin-transform-es2015-function-name-6.24.1.tgz", + "integrity": "sha1-g0yJhTvDaxrw86TF26qU/Y6sqos=", + "dev": true, + "requires": { + "babel-helper-function-name": "^6.24.1", + "babel-runtime": "^6.22.0", + "babel-types": "^6.24.1" + } + }, + "babel-plugin-transform-es2015-literals": { + "version": "6.22.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-literals/-/babel-plugin-transform-es2015-literals-6.22.0.tgz", + "integrity": "sha1-T1SgLWzWbPkVKAAZox0xklN3yi4=", + "dev": true, + "requires": { + "babel-runtime": "^6.22.0" + } + }, + "babel-plugin-transform-es2015-modules-amd": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-modules-amd/-/babel-plugin-transform-es2015-modules-amd-6.24.1.tgz", + "integrity": "sha1-Oz5UAXI5hC1tGcMBHEvS8AoA0VQ=", + "dev": true, + "requires": { + "babel-plugin-transform-es2015-modules-commonjs": "^6.24.1", + "babel-runtime": "^6.22.0", + "babel-template": "^6.24.1" + } + }, + "babel-plugin-transform-es2015-modules-commonjs": { + "version": "6.26.2", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-modules-commonjs/-/babel-plugin-transform-es2015-modules-commonjs-6.26.2.tgz", + "integrity": "sha512-CV9ROOHEdrjcwhIaJNBGMBCodN+1cfkwtM1SbUHmvyy35KGT7fohbpOxkE2uLz1o6odKK2Ck/tz47z+VqQfi9Q==", + "dev": true, + "requires": { + "babel-plugin-transform-strict-mode": "^6.24.1", + "babel-runtime": "^6.26.0", + "babel-template": "^6.26.0", + "babel-types": "^6.26.0" + } + }, + "babel-plugin-transform-es2015-modules-systemjs": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-modules-systemjs/-/babel-plugin-transform-es2015-modules-systemjs-6.24.1.tgz", + "integrity": "sha1-/4mhQrkRmpBhlfXxBuzzBdlAfSM=", + "dev": true, + "requires": { + "babel-helper-hoist-variables": "^6.24.1", + "babel-runtime": "^6.22.0", + "babel-template": "^6.24.1" + } + }, + "babel-plugin-transform-es2015-modules-umd": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-modules-umd/-/babel-plugin-transform-es2015-modules-umd-6.24.1.tgz", + "integrity": "sha1-rJl+YoXNGO1hdq22B9YCNErThGg=", + "dev": true, + "requires": { + "babel-plugin-transform-es2015-modules-amd": "^6.24.1", + "babel-runtime": "^6.22.0", + "babel-template": "^6.24.1" + } + }, + "babel-plugin-transform-es2015-object-super": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-object-super/-/babel-plugin-transform-es2015-object-super-6.24.1.tgz", + "integrity": "sha1-JM72muIcuDp/hgPa0CH1cusnj40=", + "dev": true, + "requires": { + "babel-helper-replace-supers": "^6.24.1", + "babel-runtime": "^6.22.0" + } + }, + "babel-plugin-transform-es2015-parameters": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-parameters/-/babel-plugin-transform-es2015-parameters-6.24.1.tgz", + "integrity": "sha1-V6w1GrScrxSpfNE7CfZv3wpiXys=", + "dev": true, + "requires": { + "babel-helper-call-delegate": "^6.24.1", + "babel-helper-get-function-arity": "^6.24.1", + "babel-runtime": "^6.22.0", + "babel-template": "^6.24.1", + "babel-traverse": "^6.24.1", + "babel-types": "^6.24.1" + } + }, + "babel-plugin-transform-es2015-shorthand-properties": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-shorthand-properties/-/babel-plugin-transform-es2015-shorthand-properties-6.24.1.tgz", + "integrity": "sha1-JPh11nIch2YbvZmkYi5R8U3jiqA=", + "dev": true, + "requires": { + "babel-runtime": "^6.22.0", + "babel-types": "^6.24.1" + } + }, + "babel-plugin-transform-es2015-spread": { + "version": "6.22.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-spread/-/babel-plugin-transform-es2015-spread-6.22.0.tgz", + "integrity": "sha1-1taKmfia7cRTbIGlQujdnxdG+NE=", + "dev": true, + "requires": { + "babel-runtime": "^6.22.0" + } + }, + "babel-plugin-transform-es2015-sticky-regex": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-sticky-regex/-/babel-plugin-transform-es2015-sticky-regex-6.24.1.tgz", + "integrity": "sha1-AMHNsaynERLN8M9hJsLta0V8zbw=", + "dev": true, + "requires": { + "babel-helper-regex": "^6.24.1", + "babel-runtime": "^6.22.0", + "babel-types": "^6.24.1" + } + }, + "babel-plugin-transform-es2015-template-literals": { + "version": "6.22.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-template-literals/-/babel-plugin-transform-es2015-template-literals-6.22.0.tgz", + "integrity": "sha1-qEs0UPfp+PH2g51taH2oS7EjbY0=", + "dev": true, + "requires": { + "babel-runtime": "^6.22.0" + } + }, + "babel-plugin-transform-es2015-typeof-symbol": { + "version": "6.23.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-typeof-symbol/-/babel-plugin-transform-es2015-typeof-symbol-6.23.0.tgz", + "integrity": "sha1-3sCfHN3/lLUqxz1QXITfWdzOs3I=", + "dev": true, + "requires": { + "babel-runtime": "^6.22.0" + } + }, + "babel-plugin-transform-es2015-unicode-regex": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-unicode-regex/-/babel-plugin-transform-es2015-unicode-regex-6.24.1.tgz", + "integrity": "sha1-04sS9C6nMj9yk4fxinxa4frrNek=", + "dev": true, + "requires": { + "babel-helper-regex": "^6.24.1", + "babel-runtime": "^6.22.0", + "regexpu-core": "^2.0.0" + } + }, + "babel-plugin-transform-exponentiation-operator": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-exponentiation-operator/-/babel-plugin-transform-exponentiation-operator-6.24.1.tgz", + "integrity": "sha1-KrDJx/MJj6SJB3cruBP+QejeOg4=", + "dev": true, + "requires": { + "babel-helper-builder-binary-assignment-operator-visitor": "^6.24.1", + "babel-plugin-syntax-exponentiation-operator": "^6.8.0", + "babel-runtime": "^6.22.0" + } + }, + "babel-plugin-transform-regenerator": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-regenerator/-/babel-plugin-transform-regenerator-6.26.0.tgz", + "integrity": "sha1-4HA2lvveJ/Cj78rPi03KL3s6jy8=", + "dev": true, + "requires": { + "regenerator-transform": "^0.10.0" + } + }, + "babel-plugin-transform-strict-mode": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-strict-mode/-/babel-plugin-transform-strict-mode-6.24.1.tgz", + "integrity": "sha1-1fr3qleKZbvlkc9e2uBKDGcCB1g=", + "dev": true, + "requires": { + "babel-runtime": "^6.22.0", + "babel-types": "^6.24.1" + } + }, + "babel-polyfill": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-polyfill/-/babel-polyfill-6.26.0.tgz", + "integrity": "sha1-N5k3q8Z9eJWXCtxiHyhM2WbPIVM=", + "dev": true, + "requires": { + "babel-runtime": "^6.26.0", + "core-js": "^2.5.0", + "regenerator-runtime": "^0.10.5" + }, + "dependencies": { + "regenerator-runtime": { + "version": "0.10.5", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.10.5.tgz", + "integrity": "sha1-M2w+/BIgrc7dosn6tntaeVWjNlg=", + "dev": true + } + } + }, + "babel-preset-env": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/babel-preset-env/-/babel-preset-env-1.7.0.tgz", + "integrity": "sha512-9OR2afuKDneX2/q2EurSftUYM0xGu4O2D9adAhVfADDhrYDaxXV0rBbevVYoY9n6nyX1PmQW/0jtpJvUNr9CHg==", + "dev": true, + "requires": { + "babel-plugin-check-es2015-constants": "^6.22.0", + "babel-plugin-syntax-trailing-function-commas": "^6.22.0", + "babel-plugin-transform-async-to-generator": "^6.22.0", + "babel-plugin-transform-es2015-arrow-functions": "^6.22.0", + "babel-plugin-transform-es2015-block-scoped-functions": "^6.22.0", + "babel-plugin-transform-es2015-block-scoping": "^6.23.0", + "babel-plugin-transform-es2015-classes": "^6.23.0", + "babel-plugin-transform-es2015-computed-properties": "^6.22.0", + "babel-plugin-transform-es2015-destructuring": "^6.23.0", + "babel-plugin-transform-es2015-duplicate-keys": "^6.22.0", + "babel-plugin-transform-es2015-for-of": "^6.23.0", + "babel-plugin-transform-es2015-function-name": "^6.22.0", + "babel-plugin-transform-es2015-literals": "^6.22.0", + "babel-plugin-transform-es2015-modules-amd": "^6.22.0", + "babel-plugin-transform-es2015-modules-commonjs": "^6.23.0", + "babel-plugin-transform-es2015-modules-systemjs": "^6.23.0", + "babel-plugin-transform-es2015-modules-umd": "^6.23.0", + "babel-plugin-transform-es2015-object-super": "^6.22.0", + "babel-plugin-transform-es2015-parameters": "^6.23.0", + "babel-plugin-transform-es2015-shorthand-properties": "^6.22.0", + "babel-plugin-transform-es2015-spread": "^6.22.0", + "babel-plugin-transform-es2015-sticky-regex": "^6.22.0", + "babel-plugin-transform-es2015-template-literals": "^6.22.0", + "babel-plugin-transform-es2015-typeof-symbol": "^6.23.0", + "babel-plugin-transform-es2015-unicode-regex": "^6.22.0", + "babel-plugin-transform-exponentiation-operator": "^6.22.0", + "babel-plugin-transform-regenerator": "^6.22.0", + "browserslist": "^3.2.6", + "invariant": "^2.2.2", + "semver": "^5.3.0" + } + }, + "babel-register": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-register/-/babel-register-6.26.0.tgz", + "integrity": "sha1-btAhFz4vy0htestFxgCahW9kcHE=", + "dev": true, + "requires": { + "babel-core": "^6.26.0", + "babel-runtime": "^6.26.0", + "core-js": "^2.5.0", + "home-or-tmp": "^2.0.0", + "lodash": "^4.17.4", + "mkdirp": "^0.5.1", + "source-map-support": "^0.4.15" + } + }, + "babel-runtime": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-runtime/-/babel-runtime-6.26.0.tgz", + "integrity": "sha1-llxwWGaOgrVde/4E/yM3vItWR/4=", + "dev": true, + "requires": { + "core-js": "^2.4.0", + "regenerator-runtime": "^0.11.0" + } + }, + "babel-template": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-template/-/babel-template-6.26.0.tgz", + "integrity": "sha1-3gPi0WOWsGn0bdn/+FIfsaDjXgI=", + "dev": true, + "requires": { + "babel-runtime": "^6.26.0", + "babel-traverse": "^6.26.0", + "babel-types": "^6.26.0", + "babylon": "^6.18.0", + "lodash": "^4.17.4" + } + }, + "babel-traverse": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-traverse/-/babel-traverse-6.26.0.tgz", + "integrity": "sha1-RqnL1+3MYsjlwGTi0tjQ9ANXZu4=", + "dev": true, + "requires": { + "babel-code-frame": "^6.26.0", + "babel-messages": "^6.23.0", + "babel-runtime": "^6.26.0", + "babel-types": "^6.26.0", + "babylon": "^6.18.0", + "debug": "^2.6.8", + "globals": "^9.18.0", + "invariant": "^2.2.2", + "lodash": "^4.17.4" + } + }, + "babel-types": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-types/-/babel-types-6.26.0.tgz", + "integrity": "sha1-o7Bz+Uq0nrb6Vc1lInozQ4BjJJc=", + "dev": true, + "requires": { + "babel-runtime": "^6.26.0", + "esutils": "^2.0.2", + "lodash": "^4.17.4", + "to-fast-properties": "^1.0.3" + } + }, + "babylon": { + "version": "6.18.0", + "resolved": "https://registry.npmjs.org/babylon/-/babylon-6.18.0.tgz", + "integrity": "sha512-q/UEjfGJ2Cm3oKV71DJz9d25TPnq5rhBVL2Q4fA5wcC3jcrdn7+SssEybFIxwAvvP+YCsCYNKughoF33GxgycQ==", + "dev": true + }, + "balanced-match": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", + "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=" + }, + "before-after-hook": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/before-after-hook/-/before-after-hook-1.1.0.tgz", + "integrity": "sha512-VOMDtYPwLbIncTxNoSzRyvaMxtXmLWLUqr8k5AfC1BzLk34HvBXaQX8snOwQZ4c0aX8aSERqtJSiI9/m2u5kuA==", + "dev": true + }, + "binary-extensions": { + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.11.0.tgz", + "integrity": "sha1-RqoXUftqL5PuXmibsQh9SxTGwgU=", + "dev": true, + "optional": true + }, + "brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "braces": { + "version": "1.8.5", + "resolved": "https://registry.npmjs.org/braces/-/braces-1.8.5.tgz", + "integrity": "sha1-uneWLhLf+WnWt2cR6RS3N4V79qc=", + "dev": true, + "optional": true, + "requires": { + "expand-range": "^1.8.1", + "preserve": "^0.2.0", + "repeat-element": "^1.1.2" + } + }, + "browserslist": { + "version": "3.2.8", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-3.2.8.tgz", + "integrity": "sha512-WHVocJYavUwVgVViC0ORikPHQquXwVh939TaelZ4WDqpWgTX/FsGhl/+P4qBUAGcRvtOgDgC+xftNWWp2RUTAQ==", + "dev": true, + "requires": { + "caniuse-lite": "^1.0.30000844", + "electron-to-chromium": "^1.3.47" + } + }, + "caller-path": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/caller-path/-/caller-path-0.1.0.tgz", + "integrity": "sha1-lAhe9jWB7NPaqSREqP6U6CV3dR8=", + "dev": true, + "requires": { + "callsites": "^0.2.0" + } + }, + "callsites": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-0.2.0.tgz", + "integrity": "sha1-r6uWJikQp/M8GaV3WCXGnzTjUMo=", + "dev": true + }, + "caniuse-lite": { + "version": "1.0.30000874", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30000874.tgz", + "integrity": "sha512-29nr1EPiHwrJTAHHsEmTt2h+55L8j2GNFdAcYPlRy2NX6iFz7ZZiepVI7kP/QqlnHLq3KvfWpbmGa0d063U09w==", + "dev": true + }, + "chalk": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.1.tgz", + "integrity": "sha512-ObN6h1v2fTJSmUXoS3nMQ92LbDK9be4TV+6G+omQlGJFdcUX5heKi1LZ1YnRMIgwTLEj3E24bT6tYni50rlCfQ==", + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, + "chardet": { + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.4.2.tgz", + "integrity": "sha1-tUc7M9yXxCTl2Y3IfVXU2KKci/I=", + "dev": true + }, + "checkup": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/checkup/-/checkup-1.3.0.tgz", + "integrity": "sha1-04ACdv6l0PJH/8lRvnjIsC+ODXY=", + "dev": true + }, + "chokidar": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-1.7.0.tgz", + "integrity": "sha1-eY5ol3gVHIB2tLNg5e3SjNortGg=", + "dev": true, + "optional": true, + "requires": { + "anymatch": "^1.3.0", + "async-each": "^1.0.0", + "fsevents": "^1.0.0", + "glob-parent": "^2.0.0", + "inherits": "^2.0.1", + "is-binary-path": "^1.0.0", + "is-glob": "^2.0.0", + "path-is-absolute": "^1.0.0", + "readdirp": "^2.0.0" + } + }, + "circular-json": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/circular-json/-/circular-json-0.3.3.tgz", + "integrity": "sha512-UZK3NBx2Mca+b5LsG7bY183pHWt5Y1xts4P3Pz7ENTwGVnJOUWbRb3ocjvX7hx9tq/yTAdclXm9sZ38gNuem4A==", + "dev": true + }, + "cli-cursor": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-2.1.0.tgz", + "integrity": "sha1-s12sN2R5+sw+lHR9QdDQ9SOP/LU=", + "dev": true, + "requires": { + "restore-cursor": "^2.0.0" + } + }, + "cli-width": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-2.2.0.tgz", + "integrity": "sha1-/xnt6Kml5XkyQUewwR8PvLq+1jk=", + "dev": true + }, + "color-convert": { + "version": "1.9.2", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.2.tgz", + "integrity": "sha512-3NUJZdhMhcdPn8vJ9v2UQJoH0qqoGUkYTgFEPZaPjEtwmmKUfNV46zZmgB2M5M4DCEQHMaCfWHCxiBflLm04Tg==", + "requires": { + "color-name": "1.1.1" + } + }, + "color-name": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.1.tgz", + "integrity": "sha1-SxQVMEz1ACjqgWQ2Q72C6gWANok=" + }, + "commander": { + "version": "2.17.1", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.17.1.tgz", + "integrity": "sha512-wPMUt6FnH2yzG95SA6mzjQOEKUU3aLaDEmzs1ti+1E9h+CsrZghRlqEM/EJ4KscsQVG8uNN4uVreUeT8+drlgg==", + "dev": true + }, + "concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", + "dev": true + }, + "convert-source-map": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.5.1.tgz", + "integrity": "sha1-uCeAl7m8IpNl3lxiz1/K7YtVmeU=", + "dev": true + }, + "core-js": { + "version": "2.5.7", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.5.7.tgz", + "integrity": "sha512-RszJCAxg/PP6uzXVXL6BsxSXx/B05oJAQ2vkJRjyjrEcNVycaqOmNb5OTxZPE3xa5gwZduqza6L9JOCenh/Ecw==", + "dev": true + }, + "core-util-is": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", + "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=", + "dev": true, + "optional": true + }, + "cross-spawn": { + "version": "6.0.5", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", + "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", + "dev": true, + "requires": { + "nice-try": "^1.0.4", + "path-key": "^2.0.1", + "semver": "^5.5.0", + "shebang-command": "^1.2.0", + "which": "^1.2.9" + } + }, + "cross-spawn-async": { + "version": "2.2.5", + "resolved": "https://registry.npmjs.org/cross-spawn-async/-/cross-spawn-async-2.2.5.tgz", + "integrity": "sha1-hF/wwINKPe2dFg2sptOQkGuyiMw=", + "dev": true, + "requires": { + "lru-cache": "^4.0.0", + "which": "^1.2.8" + } + }, + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "deep-equal": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/deep-equal/-/deep-equal-1.0.1.tgz", + "integrity": "sha1-9dJgKStmDghO/0zbyfCK0yR0SLU=", + "dev": true + }, + "deep-is": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz", + "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=", + "dev": true + }, + "define-properties": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.2.tgz", + "integrity": "sha1-g6c/L+pWmJj7c3GTyPhzyvbUXJQ=", + "dev": true, + "requires": { + "foreach": "^2.0.5", + "object-keys": "^1.0.8" + } + }, + "defined": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/defined/-/defined-1.0.0.tgz", + "integrity": "sha1-yY2bzvdWdBiOEQlpFRGZ45sfppM=", + "dev": true + }, + "del": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/del/-/del-2.2.2.tgz", + "integrity": "sha1-wSyYHQZ4RshLyvhiz/kw2Qf/0ag=", + "dev": true, + "requires": { + "globby": "^5.0.0", + "is-path-cwd": "^1.0.0", + "is-path-in-cwd": "^1.0.0", + "object-assign": "^4.0.1", + "pify": "^2.0.0", + "pinkie-promise": "^2.0.0", + "rimraf": "^2.2.8" + } + }, + "detect-indent": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/detect-indent/-/detect-indent-4.0.0.tgz", + "integrity": "sha1-920GQ1LN9Docts5hnE7jqUdd4gg=", + "dev": true, + "requires": { + "repeating": "^2.0.0" + } + }, + "doctrine": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", + "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", + "dev": true, + "requires": { + "esutils": "^2.0.2" + } + }, + "electron-to-chromium": { + "version": "1.3.57", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.57.tgz", + "integrity": "sha512-YYpZlr6mzR8cK5VRmTZydEt5Mp+WMg1/syrO40PoQzl76vJ+oQchL2d3FmEcWzw3FYqJVYJP/kYYSzTa7FLXwg==", + "dev": true + }, + "es-abstract": { + "version": "1.12.0", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.12.0.tgz", + "integrity": "sha512-C8Fx/0jFmV5IPoMOFPA9P9G5NtqW+4cOPit3MIuvR2t7Ag2K15EJTpxnHAYTzL+aYQJIESYeXZmDBfOBE1HcpA==", + "dev": true, + "requires": { + "es-to-primitive": "^1.1.1", + "function-bind": "^1.1.1", + "has": "^1.0.1", + "is-callable": "^1.1.3", + "is-regex": "^1.0.4" + } + }, + "es-to-primitive": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.1.1.tgz", + "integrity": "sha1-RTVSSKiJeQNLZ5Lhm7gfK3l13Q0=", + "dev": true, + "requires": { + "is-callable": "^1.1.1", + "is-date-object": "^1.0.1", + "is-symbol": "^1.0.1" + } + }, + "escape-string-applescript": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/escape-string-applescript/-/escape-string-applescript-1.0.0.tgz", + "integrity": "sha1-bxwilCRdgsY7wDM43BmpSqhCiJI=", + "dev": true + }, + "escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=" + }, + "eslint": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-5.3.0.tgz", + "integrity": "sha512-N/tCqlMKkyNvAvLu+zI9AqDasnSLt00K+Hu8kdsERliC9jYEc8ck12XtjvOXrBKu8fK6RrBcN9bat6Xk++9jAg==", + "dev": true, + "requires": { + "ajv": "^6.5.0", + "babel-code-frame": "^6.26.0", + "chalk": "^2.1.0", + "cross-spawn": "^6.0.5", + "debug": "^3.1.0", + "doctrine": "^2.1.0", + "eslint-scope": "^4.0.0", + "eslint-utils": "^1.3.1", + "eslint-visitor-keys": "^1.0.0", + "espree": "^4.0.0", + "esquery": "^1.0.1", + "esutils": "^2.0.2", + "file-entry-cache": "^2.0.0", + "functional-red-black-tree": "^1.0.1", + "glob": "^7.1.2", + "globals": "^11.7.0", + "ignore": "^4.0.2", + "imurmurhash": "^0.1.4", + "inquirer": "^5.2.0", + "is-resolvable": "^1.1.0", + "js-yaml": "^3.11.0", + "json-stable-stringify-without-jsonify": "^1.0.1", + "levn": "^0.3.0", + "lodash": "^4.17.5", + "minimatch": "^3.0.4", + "mkdirp": "^0.5.1", + "natural-compare": "^1.4.0", + "optionator": "^0.8.2", + "path-is-inside": "^1.0.2", + "pluralize": "^7.0.0", + "progress": "^2.0.0", + "regexpp": "^2.0.0", + "require-uncached": "^1.0.3", + "semver": "^5.5.0", + "string.prototype.matchall": "^2.0.0", + "strip-ansi": "^4.0.0", + "strip-json-comments": "^2.0.1", + "table": "^4.0.3", + "text-table": "^0.2.0" + }, + "dependencies": { + "ansi-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", + "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", + "dev": true + }, + "debug": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", + "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "globals": { + "version": "11.7.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-11.7.0.tgz", + "integrity": "sha512-K8BNSPySfeShBQXsahYB/AbbWruVOTyVpgoIDnl8odPpeSfP2J5QO2oLFFdl2j7GfDCtZj2bMKar2T49itTPCg==", + "dev": true + }, + "strip-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", + "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", + "dev": true, + "requires": { + "ansi-regex": "^3.0.0" + } + } + } + }, + "eslint-scope": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-4.0.0.tgz", + "integrity": "sha512-1G6UTDi7Jc1ELFwnR58HV4fK9OQK4S6N985f166xqXxpjU6plxFISJa2Ba9KCQuFa8RCnj/lSFJbHo7UFDBnUA==", + "dev": true, + "requires": { + "esrecurse": "^4.1.0", + "estraverse": "^4.1.1" + } + }, + "eslint-utils": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-1.3.1.tgz", + "integrity": "sha512-Z7YjnIldX+2XMcjr7ZkgEsOj/bREONV60qYeB/bjMAqqqZ4zxKyWX+BOUkdmRmA9riiIPVvo5x86m5elviOk0Q==", + "dev": true + }, + "eslint-visitor-keys": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.0.0.tgz", + "integrity": "sha512-qzm/XxIbxm/FHyH341ZrbnMUpe+5Bocte9xkmFMzPMjRaZMcXww+MpBptFvtU+79L362nqiLhekCxCxDPaUMBQ==", + "dev": true + }, + "espree": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/espree/-/espree-4.0.0.tgz", + "integrity": "sha512-kapdTCt1bjmspxStVKX6huolXVV5ZfyZguY1lcfhVVZstce3bqxH9mcLzNn3/mlgW6wQ732+0fuG9v7h0ZQoKg==", + "dev": true, + "requires": { + "acorn": "^5.6.0", + "acorn-jsx": "^4.1.1" + } + }, + "esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "dev": true + }, + "esquery": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.0.1.tgz", + "integrity": "sha512-SmiyZ5zIWH9VM+SRUReLS5Q8a7GxtRdxEBVZpm98rJM7Sb+A9DVCndXfkeFUd3byderg+EbDkfnevfCwynWaNA==", + "dev": true, + "requires": { + "estraverse": "^4.0.0" + } + }, + "esrecurse": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.2.1.tgz", + "integrity": "sha512-64RBB++fIOAXPw3P9cy89qfMlvZEXZkqqJkjqqXIvzP5ezRZjW+lPWjw35UX/3EhUPFYbg5ER4JYgDw4007/DQ==", + "dev": true, + "requires": { + "estraverse": "^4.1.0" + } + }, + "estraverse": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.2.0.tgz", + "integrity": "sha1-De4/7TH81GlhjOc0IJn8GvoL2xM=", + "dev": true + }, + "esutils": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.2.tgz", + "integrity": "sha1-Cr9PHKpbyx96nYrMbepPqqBLrJs=", + "dev": true + }, + "execa": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/execa/-/execa-0.2.2.tgz", + "integrity": "sha1-4urUcsLDGq1vc/GslW7vReEjIMs=", + "dev": true, + "requires": { + "cross-spawn-async": "^2.1.1", + "npm-run-path": "^1.0.0", + "object-assign": "^4.0.1", + "path-key": "^1.0.0", + "strip-eof": "^1.0.0" + }, + "dependencies": { + "path-key": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-1.0.0.tgz", + "integrity": "sha1-XVPVeAGWRsDWiADbThRua9wqx68=", + "dev": true + } + } + }, + "execon": { + "version": "1.2.9", + "resolved": "https://registry.npmjs.org/execon/-/execon-1.2.9.tgz", + "integrity": "sha1-bbETM9zIJPHxPnMX/tDZSi8mSR8=", + "dev": true + }, + "expand-brackets": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-0.1.5.tgz", + "integrity": "sha1-3wcoTjQqgHzXM6xa9yQR5YHRF3s=", + "dev": true, + "optional": true, + "requires": { + "is-posix-bracket": "^0.1.0" + } + }, + "expand-range": { + "version": "1.8.2", + "resolved": "https://registry.npmjs.org/expand-range/-/expand-range-1.8.2.tgz", + "integrity": "sha1-opnv/TNf4nIeuujiV+x5ZE/IUzc=", + "dev": true, + "optional": true, + "requires": { + "fill-range": "^2.1.0" + } + }, + "external-editor": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-2.2.0.tgz", + "integrity": "sha512-bSn6gvGxKt+b7+6TKEv1ZycHleA7aHhRHyAqJyp5pbUFuYYNIzpZnQDk7AsYckyWdEnTeAnay0aCy2aV6iTk9A==", + "dev": true, + "requires": { + "chardet": "^0.4.0", + "iconv-lite": "^0.4.17", + "tmp": "^0.0.33" + } + }, + "extglob": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/extglob/-/extglob-0.3.2.tgz", + "integrity": "sha1-Lhj/PS9JqydlzskCPwEdqo2DSaE=", + "dev": true, + "optional": true, + "requires": { + "is-extglob": "^1.0.0" + } + }, + "fast-deep-equal": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz", + "integrity": "sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk=", + "dev": true + }, + "fast-json-stable-stringify": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz", + "integrity": "sha1-1RQsDK7msRifh9OnYREGT4bIu/I=", + "dev": true + }, + "fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", + "dev": true + }, + "figures": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/figures/-/figures-2.0.0.tgz", + "integrity": "sha1-OrGi0qYsi/tDGgyUy3l6L84nyWI=", + "dev": true, + "requires": { + "escape-string-regexp": "^1.0.5" + } + }, + "file-entry-cache": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-2.0.0.tgz", + "integrity": "sha1-w5KZDD5oR4PYOLjISkXYoEhFg2E=", + "dev": true, + "requires": { + "flat-cache": "^1.2.1", + "object-assign": "^4.0.1" + } + }, + "filename-regex": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/filename-regex/-/filename-regex-2.0.1.tgz", + "integrity": "sha1-wcS5vuPglyXdsQa3XB4wH+LxiyY=", + "dev": true, + "optional": true + }, + "fill-range": { + "version": "2.2.4", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-2.2.4.tgz", + "integrity": "sha512-cnrcCbj01+j2gTG921VZPnHbjmdAf8oQV/iGeV2kZxGSyfYjjTyY79ErsK1WJWMpw6DaApEX72binqJE+/d+5Q==", + "dev": true, + "optional": true, + "requires": { + "is-number": "^2.1.0", + "isobject": "^2.0.0", + "randomatic": "^3.0.0", + "repeat-element": "^1.1.2", + "repeat-string": "^1.5.2" + } + }, + "flat-cache": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-1.3.0.tgz", + "integrity": "sha1-0wMLMrOBVPTjt+nHCfSQ9++XxIE=", + "dev": true, + "requires": { + "circular-json": "^0.3.1", + "del": "^2.0.2", + "graceful-fs": "^4.1.2", + "write": "^0.2.1" + } + }, + "for-each": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz", + "integrity": "sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==", + "dev": true, + "requires": { + "is-callable": "^1.1.3" + } + }, + "for-in": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz", + "integrity": "sha1-gQaNKVqBQuwKxybG4iAMMPttXoA=", + "dev": true, + "optional": true + }, + "for-own": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/for-own/-/for-own-0.1.5.tgz", + "integrity": "sha1-UmXGgaTylNq78XyVCbZ2OqhFEM4=", + "dev": true, + "optional": true, + "requires": { + "for-in": "^1.0.1" + } + }, + "foreach": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/foreach/-/foreach-2.0.5.tgz", + "integrity": "sha1-C+4AUBiusmDQo6865ljdATbsG5k=", + "dev": true + }, + "fs-extra": { + "version": "0.26.7", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-0.26.7.tgz", + "integrity": "sha1-muH92UiXeY7at20JGM9C0MMYT6k=", + "dev": true, + "requires": { + "graceful-fs": "^4.1.2", + "jsonfile": "^2.1.0", + "klaw": "^1.0.0", + "path-is-absolute": "^1.0.0", + "rimraf": "^2.2.8" + } + }, + "fs-readdir-recursive": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/fs-readdir-recursive/-/fs-readdir-recursive-1.1.0.tgz", + "integrity": "sha512-GNanXlVr2pf02+sPN40XN8HG+ePaNcvM0q5mZBd668Obwb0yD5GiUbZOFgwn8kGMY6I3mdyDJzieUy3PTYyTRA==", + "dev": true + }, + "fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", + "dev": true + }, + "fsevents": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.4.tgz", + "integrity": "sha512-z8H8/diyk76B7q5wg+Ud0+CqzcAF3mBBI/bA5ne5zrRUUIvNkJY//D3BqyH571KuAC4Nr7Rw7CjWX4r0y9DvNg==", + "dev": true, + "optional": true, + "requires": { + "nan": "^2.9.2", + "node-pre-gyp": "^0.10.0" + }, + "dependencies": { + "abbrev": { + "version": "1.1.1", + "bundled": true, + "dev": true, + "optional": true + }, + "ansi-regex": { + "version": "2.1.1", + "bundled": true, + "dev": true + }, + "aproba": { + "version": "1.2.0", + "bundled": true, + "dev": true, + "optional": true + }, + "are-we-there-yet": { + "version": "1.1.4", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "delegates": "^1.0.0", + "readable-stream": "^2.0.6" + } + }, + "balanced-match": { + "version": "1.0.0", + "bundled": true, + "dev": true + }, + "brace-expansion": { + "version": "1.1.11", + "bundled": true, + "dev": true, + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "chownr": { + "version": "1.0.1", + "bundled": true, + "dev": true, + "optional": true + }, + "code-point-at": { + "version": "1.1.0", + "bundled": true, + "dev": true + }, + "concat-map": { + "version": "0.0.1", + "bundled": true, + "dev": true + }, + "console-control-strings": { + "version": "1.1.0", + "bundled": true, + "dev": true + }, + "core-util-is": { + "version": "1.0.2", + "bundled": true, + "dev": true, + "optional": true + }, + "debug": { + "version": "2.6.9", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "ms": "2.0.0" + } + }, + "deep-extend": { + "version": "0.5.1", + "bundled": true, + "dev": true, + "optional": true + }, + "delegates": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "optional": true + }, + "detect-libc": { + "version": "1.0.3", + "bundled": true, + "dev": true, + "optional": true + }, + "fs-minipass": { + "version": "1.2.5", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "minipass": "^2.2.1" + } + }, + "fs.realpath": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "optional": true + }, + "gauge": { + "version": "2.7.4", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "aproba": "^1.0.3", + "console-control-strings": "^1.0.0", + "has-unicode": "^2.0.0", + "object-assign": "^4.1.0", + "signal-exit": "^3.0.0", + "string-width": "^1.0.1", + "strip-ansi": "^3.0.1", + "wide-align": "^1.1.0" + } + }, + "glob": { + "version": "7.1.2", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "has-unicode": { + "version": "2.0.1", + "bundled": true, + "dev": true, + "optional": true + }, + "iconv-lite": { + "version": "0.4.21", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "safer-buffer": "^2.1.0" + } + }, + "ignore-walk": { + "version": "3.0.1", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "minimatch": "^3.0.4" + } + }, + "inflight": { + "version": "1.0.6", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "inherits": { + "version": "2.0.3", + "bundled": true, + "dev": true + }, + "ini": { + "version": "1.3.5", + "bundled": true, + "dev": true, + "optional": true + }, + "is-fullwidth-code-point": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "requires": { + "number-is-nan": "^1.0.0" + } + }, + "isarray": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "optional": true + }, + "minimatch": { + "version": "3.0.4", + "bundled": true, + "dev": true, + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "minimist": { + "version": "0.0.8", + "bundled": true, + "dev": true + }, + "minipass": { + "version": "2.2.4", + "bundled": true, + "dev": true, + "requires": { + "safe-buffer": "^5.1.1", + "yallist": "^3.0.0" + } + }, + "minizlib": { + "version": "1.1.0", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "minipass": "^2.2.1" + } + }, + "mkdirp": { + "version": "0.5.1", + "bundled": true, + "dev": true, + "requires": { + "minimist": "0.0.8" + } + }, + "ms": { + "version": "2.0.0", + "bundled": true, + "dev": true, + "optional": true + }, + "needle": { + "version": "2.2.0", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "debug": "^2.1.2", + "iconv-lite": "^0.4.4", + "sax": "^1.2.4" + } + }, + "node-pre-gyp": { + "version": "0.10.0", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "detect-libc": "^1.0.2", + "mkdirp": "^0.5.1", + "needle": "^2.2.0", + "nopt": "^4.0.1", + "npm-packlist": "^1.1.6", + "npmlog": "^4.0.2", + "rc": "^1.1.7", + "rimraf": "^2.6.1", + "semver": "^5.3.0", + "tar": "^4" + } + }, + "nopt": { + "version": "4.0.1", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "abbrev": "1", + "osenv": "^0.1.4" + } + }, + "npm-bundled": { + "version": "1.0.3", + "bundled": true, + "dev": true, + "optional": true + }, + "npm-packlist": { + "version": "1.1.10", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "ignore-walk": "^3.0.1", + "npm-bundled": "^1.0.1" + } + }, + "npmlog": { + "version": "4.1.2", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "are-we-there-yet": "~1.1.2", + "console-control-strings": "~1.1.0", + "gauge": "~2.7.3", + "set-blocking": "~2.0.0" + } + }, + "number-is-nan": { + "version": "1.0.1", + "bundled": true, + "dev": true + }, + "object-assign": { + "version": "4.1.1", + "bundled": true, + "dev": true, + "optional": true + }, + "once": { + "version": "1.4.0", + "bundled": true, + "dev": true, + "requires": { + "wrappy": "1" + } + }, + "os-homedir": { + "version": "1.0.2", + "bundled": true, + "dev": true, + "optional": true + }, + "os-tmpdir": { + "version": "1.0.2", + "bundled": true, + "dev": true, + "optional": true + }, + "osenv": { + "version": "0.1.5", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "os-homedir": "^1.0.0", + "os-tmpdir": "^1.0.0" + } + }, + "path-is-absolute": { + "version": "1.0.1", + "bundled": true, + "dev": true, + "optional": true + }, + "process-nextick-args": { + "version": "2.0.0", + "bundled": true, + "dev": true, + "optional": true + }, + "rc": { + "version": "1.2.7", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "deep-extend": "^0.5.1", + "ini": "~1.3.0", + "minimist": "^1.2.0", + "strip-json-comments": "~2.0.1" + }, + "dependencies": { + "minimist": { + "version": "1.2.0", + "bundled": true, + "dev": true, + "optional": true + } + } + }, + "readable-stream": { + "version": "2.3.6", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "rimraf": { + "version": "2.6.2", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "glob": "^7.0.5" + } + }, + "safe-buffer": { + "version": "5.1.1", + "bundled": true, + "dev": true + }, + "safer-buffer": { + "version": "2.1.2", + "bundled": true, + "dev": true, + "optional": true + }, + "sax": { + "version": "1.2.4", + "bundled": true, + "dev": true, + "optional": true + }, + "semver": { + "version": "5.5.0", + "bundled": true, + "dev": true, + "optional": true + }, + "set-blocking": { + "version": "2.0.0", + "bundled": true, + "dev": true, + "optional": true + }, + "signal-exit": { + "version": "3.0.2", + "bundled": true, + "dev": true, + "optional": true + }, + "string-width": { + "version": "1.0.2", + "bundled": true, + "dev": true, + "requires": { + "code-point-at": "^1.0.0", + "is-fullwidth-code-point": "^1.0.0", + "strip-ansi": "^3.0.0" + } + }, + "string_decoder": { + "version": "1.1.1", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "safe-buffer": "~5.1.0" + } + }, + "strip-ansi": { + "version": "3.0.1", + "bundled": true, + "dev": true, + "requires": { + "ansi-regex": "^2.0.0" + } + }, + "strip-json-comments": { + "version": "2.0.1", + "bundled": true, + "dev": true, + "optional": true + }, + "tar": { + "version": "4.4.1", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "chownr": "^1.0.1", + "fs-minipass": "^1.2.5", + "minipass": "^2.2.4", + "minizlib": "^1.1.0", + "mkdirp": "^0.5.0", + "safe-buffer": "^5.1.1", + "yallist": "^3.0.2" + } + }, + "util-deprecate": { + "version": "1.0.2", + "bundled": true, + "dev": true, + "optional": true + }, + "wide-align": { + "version": "1.1.2", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "string-width": "^1.0.2" + } + }, + "wrappy": { + "version": "1.0.2", + "bundled": true, + "dev": true + }, + "yallist": { + "version": "3.0.2", + "bundled": true, + "dev": true + } + } + }, + "function-bind": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", + "dev": true + }, + "functional-red-black-tree": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", + "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=", + "dev": true + }, + "github-release-from-changelog": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/github-release-from-changelog/-/github-release-from-changelog-1.3.2.tgz", + "integrity": "sha512-3Cj5zazWfk9heJzBSXxBsh9xQSYt8ZOseresfNeHewFVC2g0Au9181xob9eXTv4hRysi9k3gRVCXOUmBH+J2bA==", + "dev": true, + "requires": { + "grizzly": "^3.0.3", + "minimist": "^1.2.0" + }, + "dependencies": { + "minimist": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", + "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", + "dev": true + } + } + }, + "glob": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz", + "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==", + "dev": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "glob-base": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/glob-base/-/glob-base-0.3.0.tgz", + "integrity": "sha1-27Fk9iIbHAscz4Kuoyi0l98Oo8Q=", + "dev": true, + "optional": true, + "requires": { + "glob-parent": "^2.0.0", + "is-glob": "^2.0.0" + } + }, + "glob-parent": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-2.0.0.tgz", + "integrity": "sha1-gTg9ctsFT8zPUzbaqQLxgvbtuyg=", + "dev": true, + "requires": { + "is-glob": "^2.0.0" + } + }, + "globals": { + "version": "9.18.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-9.18.0.tgz", + "integrity": "sha512-S0nG3CLEQiY/ILxqtztTWH/3iRRdyBLw6KMDxnKMchrtbj2OFmehVh0WUCfW3DUrIgx/qFrJPICrq4Z4sTR9UQ==", + "dev": true + }, + "globby": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-5.0.0.tgz", + "integrity": "sha1-69hGZ8oNuzMLmbz8aOrCvFQ3Dg0=", + "dev": true, + "requires": { + "array-union": "^1.0.1", + "arrify": "^1.0.0", + "glob": "^7.0.3", + "object-assign": "^4.0.1", + "pify": "^2.0.0", + "pinkie-promise": "^2.0.0" + } + }, + "graceful-fs": { + "version": "4.1.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.11.tgz", + "integrity": "sha1-Dovf5NHduIVNZOBOp8AOKgJuVlg=", + "dev": true + }, + "grizzly": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/grizzly/-/grizzly-3.0.3.tgz", + "integrity": "sha512-IGcSYOg8W75e1/92oHy1RgO4fiWxWYi94C5nwjJwTe5usRx241LkqiO4923LVLwkon7ro69ZKcCbI4ox25pDOw==", + "dev": true, + "requires": { + "@octokit/rest": "^14.0.7", + "checkup": "^1.3.0", + "debug": "^3.0.0", + "execon": "^1.2.0", + "minimist": "^1.2.0", + "readjson": "^1.1.0" + }, + "dependencies": { + "debug": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", + "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "minimist": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", + "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", + "dev": true + } + } + }, + "has": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", + "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "dev": true, + "requires": { + "function-bind": "^1.1.1" + } + }, + "has-ansi": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", + "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=", + "dev": true, + "requires": { + "ansi-regex": "^2.0.0" + } + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=" + }, + "has-symbols": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.0.tgz", + "integrity": "sha1-uhqPGvKg/DllD1yFA2dwQSIGO0Q=", + "dev": true + }, + "home-or-tmp": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/home-or-tmp/-/home-or-tmp-2.0.0.tgz", + "integrity": "sha1-42w/LSyufXRqhX440Y1fMqeILbg=", + "dev": true, + "requires": { + "os-homedir": "^1.0.0", + "os-tmpdir": "^1.0.1" + } + }, + "iconv-lite": { + "version": "0.4.23", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.23.tgz", + "integrity": "sha512-neyTUVFtahjf0mB3dZT77u+8O0QB89jFdnBkd5P1JgYPbPaia3gXXOVL2fq8VyU2gMMD7SaN7QukTB/pmXYvDA==", + "dev": true, + "requires": { + "safer-buffer": ">= 2.1.2 < 3" + } + }, + "ignore": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.5.tgz", + "integrity": "sha512-Q2daVnMtQJPacGrcCRyOEiI+syPCt+mR4YotoC0KEYeinV/6HztT5mUuVEj7UYyoNZ1jGYiu2XEem7I8oM44bg==", + "dev": true + }, + "imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", + "dev": true + }, + "inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "dev": true, + "requires": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "inherits": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", + "dev": true + }, + "inquirer": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-5.2.0.tgz", + "integrity": "sha512-E9BmnJbAKLPGonz0HeWHtbKf+EeSP93paWO3ZYoUpq/aowXvYGjjCSuashhXPpzbArIjBbji39THkxTz9ZeEUQ==", + "dev": true, + "requires": { + "ansi-escapes": "^3.0.0", + "chalk": "^2.0.0", + "cli-cursor": "^2.1.0", + "cli-width": "^2.0.0", + "external-editor": "^2.1.0", + "figures": "^2.0.0", + "lodash": "^4.3.0", + "mute-stream": "0.0.7", + "run-async": "^2.2.0", + "rxjs": "^5.5.2", + "string-width": "^2.1.0", + "strip-ansi": "^4.0.0", + "through": "^2.3.6" + }, + "dependencies": { + "ansi-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", + "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", + "dev": true + }, + "strip-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", + "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", + "dev": true, + "requires": { + "ansi-regex": "^3.0.0" + } + } + } + }, + "invariant": { + "version": "2.2.4", + "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz", + "integrity": "sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==", + "dev": true, + "requires": { + "loose-envify": "^1.0.0" + } + }, + "is-array-buffer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-1.0.1.tgz", + "integrity": "sha512-lj035IqdAwsodoRGs9/8+Kn3HPoz9CTuZbcw63afugWonxigvUVeHY5d6Ve1O+s1N3RCk7txo2TIWQLbU0SuNA==", + "dev": true + }, + "is-binary-path": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-1.0.1.tgz", + "integrity": "sha1-dfFmQrSA8YenEcgUFh/TpKdlWJg=", + "dev": true, + "optional": true, + "requires": { + "binary-extensions": "^1.0.0" + } + }, + "is-buffer": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", + "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==", + "dev": true + }, + "is-callable": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.1.4.tgz", + "integrity": "sha512-r5p9sxJjYnArLjObpjA4xu5EKI3CuKHkJXMhT7kwbpUyIFD1n5PMAsoPvWnvtZiNz7LjkYDRZhd7FlI0eMijEA==", + "dev": true + }, + "is-date-object": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.1.tgz", + "integrity": "sha1-mqIOtq7rv/d/vTPnTKAbM1gdOhY=", + "dev": true + }, + "is-dotfile": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/is-dotfile/-/is-dotfile-1.0.3.tgz", + "integrity": "sha1-pqLzL/0t+wT1yiXs0Pa4PPeYoeE=", + "dev": true, + "optional": true + }, + "is-equal-shallow": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/is-equal-shallow/-/is-equal-shallow-0.1.3.tgz", + "integrity": "sha1-IjgJj8Ih3gvPpdnqxMRdY4qhxTQ=", + "dev": true, + "optional": true, + "requires": { + "is-primitive": "^2.0.0" + } + }, + "is-extendable": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", + "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=", + "dev": true, + "optional": true + }, + "is-extglob": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-1.0.0.tgz", + "integrity": "sha1-rEaBd8SUNAWgkvyPKXYMb/xiBsA=", + "dev": true + }, + "is-finite": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-finite/-/is-finite-1.0.2.tgz", + "integrity": "sha1-zGZ3aVYCvlUO8R6LSqYwU0K20Ko=", + "dev": true, + "requires": { + "number-is-nan": "^1.0.0" + } + }, + "is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", + "dev": true + }, + "is-glob": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-2.0.1.tgz", + "integrity": "sha1-0Jb5JqPe1WAPP9/ZEZjLCIjC2GM=", + "dev": true, + "requires": { + "is-extglob": "^1.0.0" + } + }, + "is-number": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-2.1.0.tgz", + "integrity": "sha1-Afy7s5NGOlSPL0ZszhbezknbkI8=", + "dev": true, + "optional": true, + "requires": { + "kind-of": "^3.0.2" + } + }, + "is-path-cwd": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-path-cwd/-/is-path-cwd-1.0.0.tgz", + "integrity": "sha1-0iXsIxMuie3Tj9p2dHLmLmXxEG0=", + "dev": true + }, + "is-path-in-cwd": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-path-in-cwd/-/is-path-in-cwd-1.0.1.tgz", + "integrity": "sha512-FjV1RTW48E7CWM7eE/J2NJvAEEVektecDBVBE5Hh3nM1Jd0kvhHtX68Pr3xsDf857xt3Y4AkwVULK1Vku62aaQ==", + "dev": true, + "requires": { + "is-path-inside": "^1.0.0" + } + }, + "is-path-inside": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-1.0.1.tgz", + "integrity": "sha1-jvW33lBDej/cprToZe96pVy0gDY=", + "dev": true, + "requires": { + "path-is-inside": "^1.0.1" + } + }, + "is-posix-bracket": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/is-posix-bracket/-/is-posix-bracket-0.1.1.tgz", + "integrity": "sha1-MzTceXdDaOkvAW5vvAqI9c1ua8Q=", + "dev": true, + "optional": true + }, + "is-primitive": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-primitive/-/is-primitive-2.0.0.tgz", + "integrity": "sha1-IHurkWOEmcB7Kt8kCkGochADRXU=", + "dev": true, + "optional": true + }, + "is-promise": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-2.1.0.tgz", + "integrity": "sha1-eaKp7OfwlugPNtKy87wWwf9L8/o=", + "dev": true + }, + "is-regex": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.0.4.tgz", + "integrity": "sha1-VRdIm1RwkbCTDglWVM7SXul+lJE=", + "dev": true, + "requires": { + "has": "^1.0.1" + } + }, + "is-resolvable": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-resolvable/-/is-resolvable-1.1.0.tgz", + "integrity": "sha512-qgDYXFSR5WvEfuS5dMj6oTMEbrrSaM0CrFk2Yiq/gXnBvD9pMa2jGXxyhGLfvhZpuMZe18CJpFxAt3CRs42NMg==", + "dev": true + }, + "is-stream": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", + "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=", + "dev": true + }, + "is-symbol": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.1.tgz", + "integrity": "sha1-PMWfAAJRlLarLjjbrmaJJWtmBXI=", + "dev": true + }, + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", + "dev": true + }, + "isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", + "dev": true + }, + "isobject": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", + "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=", + "dev": true, + "optional": true, + "requires": { + "isarray": "1.0.0" + } + }, + "js-tokens": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-3.0.2.tgz", + "integrity": "sha1-mGbfOVECEw449/mWvOtlRDIJwls=", + "dev": true + }, + "js-yaml": { + "version": "3.12.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.12.0.tgz", + "integrity": "sha512-PIt2cnwmPfL4hKNwqeiuz4bKfnzHTBv6HyVgjahA6mPLwPDzjDWrplJBMjHUFxku/N3FlmrbyPclad+I+4mJ3A==", + "dev": true, + "requires": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + } + }, + "jsesc": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-1.3.0.tgz", + "integrity": "sha1-RsP+yMGJKxKwgz25vHYiF226s0s=", + "dev": true + }, + "json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true + }, + "json-stable-stringify-without-jsonify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", + "integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=", + "dev": true + }, + "json5": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/json5/-/json5-0.5.1.tgz", + "integrity": "sha1-Hq3nrMASA0rYTiOWdn6tn6VJWCE=", + "dev": true + }, + "jsonfile": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-2.4.0.tgz", + "integrity": "sha1-NzaitCi4e72gzIO1P6PWM6NcKug=", + "dev": true, + "requires": { + "graceful-fs": "^4.1.6" + } + }, + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + }, + "klaw": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/klaw/-/klaw-1.3.1.tgz", + "integrity": "sha1-QIhDO0azsbolnXh4XY6W9zugJDk=", + "dev": true, + "requires": { + "graceful-fs": "^4.1.9" + } + }, + "levn": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", + "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=", + "dev": true, + "requires": { + "prelude-ls": "~1.1.2", + "type-check": "~0.3.2" + } + }, + "lodash": { + "version": "4.17.10", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.10.tgz", + "integrity": "sha512-UejweD1pDoXu+AD825lWwp4ZGtSwgnpZxb3JDViD7StjQz+Nb/6l093lx4OQ0foGWNRoc19mWy7BzL+UAK2iVg==", + "dev": true + }, + "loose-envify": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", + "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", + "dev": true, + "requires": { + "js-tokens": "^3.0.0 || ^4.0.0" + } + }, + "lru-cache": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.3.tgz", + "integrity": "sha512-fFEhvcgzuIoJVUF8fYr5KR0YqxD238zgObTps31YdADwPPAp82a4M8TrckkWyx7ekNlf9aBcVn81cFwwXngrJA==", + "dev": true, + "requires": { + "pseudomap": "^1.0.2", + "yallist": "^2.1.2" + } + }, + "math-random": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/math-random/-/math-random-1.0.1.tgz", + "integrity": "sha1-izqsWIuKZuSXXjzepn97sylgH6w=", + "dev": true, + "optional": true + }, + "micromatch": { + "version": "2.3.11", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-2.3.11.tgz", + "integrity": "sha1-hmd8l9FyCzY0MdBNDRUpO9OMFWU=", + "dev": true, + "optional": true, + "requires": { + "arr-diff": "^2.0.0", + "array-unique": "^0.2.1", + "braces": "^1.8.2", + "expand-brackets": "^0.1.4", + "extglob": "^0.3.1", + "filename-regex": "^2.0.0", + "is-extglob": "^1.0.0", + "is-glob": "^2.0.1", + "kind-of": "^3.0.2", + "normalize-path": "^2.0.1", + "object.omit": "^2.0.0", + "parse-glob": "^3.0.4", + "regex-cache": "^0.4.2" + } + }, + "mimic-fn": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-1.2.0.tgz", + "integrity": "sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ==", + "dev": true + }, + "minimatch": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", + "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "dev": true, + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "minimist": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", + "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=", + "dev": true + }, + "mkdirp": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", + "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", + "dev": true, + "requires": { + "minimist": "0.0.8" + } + }, + "mount-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/mount-point/-/mount-point-3.0.0.tgz", + "integrity": "sha1-Zly57evoDREOZY21bDHQrvUaj5c=", + "dev": true, + "requires": { + "@sindresorhus/df": "^1.0.1", + "pify": "^2.3.0", + "pinkie-promise": "^2.0.1" + }, + "dependencies": { + "@sindresorhus/df": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@sindresorhus/df/-/df-1.0.1.tgz", + "integrity": "sha1-xptm9S9vzdKHyAffIQMF2694UA0=", + "dev": true + } + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + }, + "mute-stream": { + "version": "0.0.7", + "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.7.tgz", + "integrity": "sha1-MHXOk7whuPq0PhvE2n6BFe0ee6s=", + "dev": true + }, + "nan": { + "version": "2.10.0", + "resolved": "https://registry.npmjs.org/nan/-/nan-2.10.0.tgz", + "integrity": "sha512-bAdJv7fBLhWC+/Bls0Oza+mvTaNQtP+1RyhhhvD95pgUJz6XM5IzgmxOkItJ9tkoCiplvAnXI1tNmmUD/eScyA==", + "dev": true, + "optional": true + }, + "natural-compare": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=", + "dev": true + }, + "nice-try": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.4.tgz", + "integrity": "sha512-2NpiFHqC87y/zFke0fC0spBXL3bBsoh/p5H1EFhshxjCR5+0g2d6BiXbUFz9v1sAcxsk2htp2eQnNIci2dIYcA==", + "dev": true + }, + "normalize-path": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", + "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", + "dev": true, + "requires": { + "remove-trailing-separator": "^1.0.1" + } + }, + "npm-run-path": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-1.0.0.tgz", + "integrity": "sha1-9cMr9ZX+ga6Sfa7FLoL4sACsPI8=", + "dev": true, + "requires": { + "path-key": "^1.0.0" + }, + "dependencies": { + "path-key": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-1.0.0.tgz", + "integrity": "sha1-XVPVeAGWRsDWiADbThRua9wqx68=", + "dev": true + } + } + }, + "npmpub": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/npmpub/-/npmpub-4.1.0.tgz", + "integrity": "sha512-aFaX5gp09tl5NxpqxkHg1QCZrTx6QHBLfQkfonXR0ohwvWeNJItFVSN2R+6IVKtLis085A6zbOUi8r6lMtPO9A==", + "dev": true, + "requires": { + "chalk": "^1.1.1", + "github-release-from-changelog": "^1.3.2", + "minimist": "^1.2.0", + "shelljs": "^0.5.3", + "trash": "^3.4.1" + }, + "dependencies": { + "ansi-styles": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", + "dev": true + }, + "chalk": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", + "dev": true, + "requires": { + "ansi-styles": "^2.2.1", + "escape-string-regexp": "^1.0.2", + "has-ansi": "^2.0.0", + "strip-ansi": "^3.0.0", + "supports-color": "^2.0.0" + } + }, + "minimist": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", + "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", + "dev": true + }, + "supports-color": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", + "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", + "dev": true + } + } + }, + "number-is-nan": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", + "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=", + "dev": true + }, + "object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", + "dev": true + }, + "object-inspect": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.6.0.tgz", + "integrity": "sha512-GJzfBZ6DgDAmnuaM3104jR4s1Myxr3Y3zfIyN4z3UdqN69oSRacNK8UhnobDdC+7J2AHCjGwxQubNJfE70SXXQ==", + "dev": true + }, + "object-keys": { + "version": "1.0.12", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.0.12.tgz", + "integrity": "sha512-FTMyFUm2wBcGHnH2eXmz7tC6IwlqQZ6mVZ+6dm6vZ4IQIHjs6FdNsQBuKGPuUUUY6NfJw2PshC08Tn6LzLDOag==", + "dev": true + }, + "object.omit": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/object.omit/-/object.omit-2.0.1.tgz", + "integrity": "sha1-Gpx0SCnznbuFjHbKNXmuKlTr0fo=", + "dev": true, + "optional": true, + "requires": { + "for-own": "^0.1.4", + "is-extendable": "^0.1.1" + } + }, + "once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "dev": true, + "requires": { + "wrappy": "1" + } + }, + "onetime": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-2.0.1.tgz", + "integrity": "sha1-BnQoIw/WdEOyeUsiu6UotoZ5YtQ=", + "dev": true, + "requires": { + "mimic-fn": "^1.0.0" + } + }, + "optionator": { + "version": "0.8.2", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.2.tgz", + "integrity": "sha1-NkxeQJ0/TWMB1sC0wFu6UBgK62Q=", + "dev": true, + "requires": { + "deep-is": "~0.1.3", + "fast-levenshtein": "~2.0.4", + "levn": "~0.3.0", + "prelude-ls": "~1.1.2", + "type-check": "~0.3.2", + "wordwrap": "~1.0.0" + } + }, + "os-homedir": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz", + "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=", + "dev": true + }, + "os-tmpdir": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", + "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=", + "dev": true + }, + "output-file-sync": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/output-file-sync/-/output-file-sync-1.1.2.tgz", + "integrity": "sha1-0KM+7+YaIF+suQCS6CZZjVJFznY=", + "dev": true, + "requires": { + "graceful-fs": "^4.1.4", + "mkdirp": "^0.5.1", + "object-assign": "^4.1.0" + } + }, + "parse-glob": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/parse-glob/-/parse-glob-3.0.4.tgz", + "integrity": "sha1-ssN2z7EfNVE7rdFz7wu246OIORw=", + "dev": true, + "optional": true, + "requires": { + "glob-base": "^0.3.0", + "is-dotfile": "^1.0.0", + "is-extglob": "^1.0.0", + "is-glob": "^2.0.0" + } + }, + "path-exists": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-2.1.0.tgz", + "integrity": "sha1-D+tsZPD8UY2adU3V77YscCJ2H0s=", + "dev": true, + "requires": { + "pinkie-promise": "^2.0.0" + } + }, + "path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", + "dev": true + }, + "path-is-inside": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz", + "integrity": "sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM=", + "dev": true + }, + "path-key": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", + "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=", + "dev": true + }, + "path-parse": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz", + "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==", + "dev": true + }, + "pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", + "dev": true + }, + "pinkie": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz", + "integrity": "sha1-clVrgM+g1IqXToDnckjoDtT3+HA=", + "dev": true + }, + "pinkie-promise": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz", + "integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=", + "dev": true, + "requires": { + "pinkie": "^2.0.0" + } + }, + "pluralize": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/pluralize/-/pluralize-7.0.0.tgz", + "integrity": "sha512-ARhBOdzS3e41FbkW/XWrTEtukqqLoK5+Z/4UeDaLuSW+39JPeFgs4gCGqsrJHVZX0fUrx//4OF0K1CUGwlIFow==", + "dev": true + }, + "postcss": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.2.tgz", + "integrity": "sha512-fmaUY5370keLUTx+CnwRxtGiuFTcNBLQBqr1oE3WZ/euIYmGAo0OAgOhVJ3ByDnVmOR3PK+0V9VebzfjRIUcqw==", + "requires": { + "chalk": "^2.4.1", + "source-map": "^0.6.1", + "supports-color": "^5.4.0" + } + }, + "prelude-ls": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", + "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=", + "dev": true + }, + "preserve": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/preserve/-/preserve-0.2.0.tgz", + "integrity": "sha1-gV7R9uvGWSb4ZbMQwHE7yzMVzks=", + "dev": true, + "optional": true + }, + "private": { + "version": "0.1.8", + "resolved": "https://registry.npmjs.org/private/-/private-0.1.8.tgz", + "integrity": "sha512-VvivMrbvd2nKkiG38qjULzlc+4Vx4wm/whI9pQD35YrARNnhxeiRktSOhSukRLFNlzg6Br/cJPet5J/u19r/mg==", + "dev": true + }, + "process-nextick-args": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.0.tgz", + "integrity": "sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw==", + "dev": true, + "optional": true + }, + "progress": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.0.tgz", + "integrity": "sha1-ihvjZr+Pwj2yvSPxDG/pILQ4nR8=", + "dev": true + }, + "pseudomap": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", + "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=", + "dev": true + }, + "punycode": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", + "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", + "dev": true + }, + "randomatic": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/randomatic/-/randomatic-3.1.0.tgz", + "integrity": "sha512-KnGPVE0lo2WoXxIZ7cPR8YBpiol4gsSuOwDSg410oHh80ZMp5EiypNqL2K4Z77vJn6lB5rap7IkAmcUlalcnBQ==", + "dev": true, + "optional": true, + "requires": { + "is-number": "^4.0.0", + "kind-of": "^6.0.0", + "math-random": "^1.0.1" + }, + "dependencies": { + "is-number": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-4.0.0.tgz", + "integrity": "sha512-rSklcAIlf1OmFdyAqbnWTLVelsQ58uvZ66S/ZyawjWqIviTWCjg2PzVGw8WUA+nNuPTqb4wgA+NszrJ+08LlgQ==", + "dev": true, + "optional": true + }, + "kind-of": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", + "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==", + "dev": true, + "optional": true + } + } + }, + "readable-stream": { + "version": "2.3.6", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", + "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", + "dev": true, + "optional": true, + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "readdirp": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-2.1.0.tgz", + "integrity": "sha1-TtCtBg3zBzMAxIRANz9y0cxkLXg=", + "dev": true, + "optional": true, + "requires": { + "graceful-fs": "^4.1.2", + "minimatch": "^3.0.2", + "readable-stream": "^2.0.2", + "set-immediate-shim": "^1.0.1" + } + }, + "readjson": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/readjson/-/readjson-1.1.4.tgz", + "integrity": "sha512-H4dRk2S67w3HtE1apnw5wlHpN9qkJ0pen0AcEvyAfnrPfskZIyUOYLXpfN6olDQZI+eUlxg0Yo4lJ2bymujOUA==", + "dev": true, + "requires": { + "try-catch": "^2.0.0" + } + }, + "regenerate": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.0.tgz", + "integrity": "sha512-1G6jJVDWrt0rK99kBjvEtziZNCICAuvIPkSiUFIQxVP06RCVpq3dmDo2oi6ABpYaDYaTRr67BEhL8r1wgEZZKg==", + "dev": true + }, + "regenerator-runtime": { + "version": "0.11.1", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz", + "integrity": "sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg==", + "dev": true + }, + "regenerator-transform": { + "version": "0.10.1", + "resolved": "https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.10.1.tgz", + "integrity": "sha512-PJepbvDbuK1xgIgnau7Y90cwaAmO/LCLMI2mPvaXq2heGMR3aWW5/BQvYrhJ8jgmQjXewXvBjzfqKcVOmhjZ6Q==", + "dev": true, + "requires": { + "babel-runtime": "^6.18.0", + "babel-types": "^6.19.0", + "private": "^0.1.6" + } + }, + "regex-cache": { + "version": "0.4.4", + "resolved": "https://registry.npmjs.org/regex-cache/-/regex-cache-0.4.4.tgz", + "integrity": "sha512-nVIZwtCjkC9YgvWkpM55B5rBhBYRZhAaJbgcFYXXsHnbZ9UZI9nnVWYZpBlCqv9ho2eZryPnWrZGsOdPwVWXWQ==", + "dev": true, + "optional": true, + "requires": { + "is-equal-shallow": "^0.1.3" + } + }, + "regexp.prototype.flags": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.2.0.tgz", + "integrity": "sha512-ztaw4M1VqgMwl9HlPpOuiYgItcHlunW0He2fE6eNfT6E/CF2FtYi9ofOYe4mKntstYk0Fyh/rDRBdS3AnxjlrA==", + "dev": true, + "requires": { + "define-properties": "^1.1.2" + } + }, + "regexpp": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-2.0.0.tgz", + "integrity": "sha512-g2FAVtR8Uh8GO1Nv5wpxW7VFVwHcCEr4wyA8/MHiRkO8uHoR5ntAA8Uq3P1vvMTX/BeQiRVSpDGLd+Wn5HNOTA==", + "dev": true + }, + "regexpu-core": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-2.0.0.tgz", + "integrity": "sha1-SdA4g3uNz4v6W5pCE5k45uoq4kA=", + "dev": true, + "requires": { + "regenerate": "^1.2.1", + "regjsgen": "^0.2.0", + "regjsparser": "^0.1.4" + } + }, + "regjsgen": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/regjsgen/-/regjsgen-0.2.0.tgz", + "integrity": "sha1-bAFq3qxVT3WCP+N6wFuS1aTtsfc=", + "dev": true + }, + "regjsparser": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.1.5.tgz", + "integrity": "sha1-fuj4Tcb6eS0/0K4ijSS9lJ6tIFw=", + "dev": true, + "requires": { + "jsesc": "~0.5.0" + }, + "dependencies": { + "jsesc": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-0.5.0.tgz", + "integrity": "sha1-597mbjXW/Bb3EP6R1c9p9w8IkR0=", + "dev": true + } + } + }, + "remove-trailing-separator": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz", + "integrity": "sha1-wkvOKig62tW8P1jg1IJJuSN52O8=", + "dev": true + }, + "repeat-element": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.2.tgz", + "integrity": "sha1-7wiaF40Ug7quTZPrmLT55OEdmQo=", + "dev": true + }, + "repeat-string": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", + "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=", + "dev": true, + "optional": true + }, + "repeating": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/repeating/-/repeating-2.0.1.tgz", + "integrity": "sha1-UhTFOpJtNVJwdSf7q0FdvAjQbdo=", + "dev": true, + "requires": { + "is-finite": "^1.0.0" + } + }, + "require-uncached": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/require-uncached/-/require-uncached-1.0.3.tgz", + "integrity": "sha1-Tg1W1slmL9MeQwEcS5WqSZVUIdM=", + "dev": true, + "requires": { + "caller-path": "^0.1.0", + "resolve-from": "^1.0.0" + } + }, + "resolve": { + "version": "1.7.1", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.7.1.tgz", + "integrity": "sha512-c7rwLofp8g1U+h1KNyHL/jicrKg1Ek4q+Lr33AL65uZTinUZHe30D5HlyN5V9NW0JX1D5dXQ4jqW5l7Sy/kGfw==", + "dev": true, + "requires": { + "path-parse": "^1.0.5" + } + }, + "resolve-from": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-1.0.1.tgz", + "integrity": "sha1-Jsv+k10a7uq7Kbw/5a6wHpPUQiY=", + "dev": true + }, + "restore-cursor": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-2.0.0.tgz", + "integrity": "sha1-n37ih/gv0ybU/RYpI9YhKe7g368=", + "dev": true, + "requires": { + "onetime": "^2.0.0", + "signal-exit": "^3.0.2" + } + }, + "resumer": { + "version": "0.0.0", + "resolved": "https://registry.npmjs.org/resumer/-/resumer-0.0.0.tgz", + "integrity": "sha1-8ej0YeQGS6Oegq883CqMiT0HZ1k=", + "dev": true, + "requires": { + "through": "~2.3.4" + } + }, + "rimraf": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.2.tgz", + "integrity": "sha512-lreewLK/BlghmxtfH36YYVg1i8IAce4TI7oao75I1g245+6BctqTVQiBP3YUJ9C6DQOXJmkYR9X9fCLtCOJc5w==", + "dev": true, + "requires": { + "glob": "^7.0.5" + } + }, + "run-applescript": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/run-applescript/-/run-applescript-2.1.0.tgz", + "integrity": "sha1-O/8sz5W2zqy0lyPlUPADcdYYUQ0=", + "dev": true, + "requires": { + "pify": "^2.2.0", + "pinkie-promise": "^2.0.0" + } + }, + "run-async": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.3.0.tgz", + "integrity": "sha1-A3GrSuC91yDUFm19/aZP96RFpsA=", + "dev": true, + "requires": { + "is-promise": "^2.1.0" + } + }, + "rxjs": { + "version": "5.5.11", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-5.5.11.tgz", + "integrity": "sha512-3bjO7UwWfA2CV7lmwYMBzj4fQ6Cq+ftHc2MvUe+WMS7wcdJ1LosDWmdjPQanYp2dBRj572p7PeU81JUxHKOcBA==", + "dev": true, + "requires": { + "symbol-observable": "1.0.1" + } + }, + "safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true + }, + "safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", + "dev": true + }, + "semver": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.5.0.tgz", + "integrity": "sha512-4SJ3dm0WAwWy/NVeioZh5AntkdJoWKxHxcmyP622fOkgHa4z3R0TdBJICINyaSDE6uNwVc8gZr+ZinwZAH4xIA==", + "dev": true + }, + "set-immediate-shim": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/set-immediate-shim/-/set-immediate-shim-1.0.1.tgz", + "integrity": "sha1-SysbJ+uAip+NzEgaWOXlb1mfP2E=", + "dev": true, + "optional": true + }, + "shebang-command": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", + "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=", + "dev": true, + "requires": { + "shebang-regex": "^1.0.0" + } + }, + "shebang-regex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", + "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=", + "dev": true + }, + "shelljs": { + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/shelljs/-/shelljs-0.5.3.tgz", + "integrity": "sha1-xUmCuZbHbvDB5rWfvcWCX1txMRM=", + "dev": true + }, + "signal-exit": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz", + "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=", + "dev": true + }, + "slash": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-1.0.0.tgz", + "integrity": "sha1-xB8vbDn8FtHNF61LXYlhFK5HDVU=", + "dev": true + }, + "slice-ansi": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-1.0.0.tgz", + "integrity": "sha512-POqxBK6Lb3q6s047D/XsDVNPnF9Dl8JSaqe9h9lURl0OdNqy/ujDrOiIHtsqXMGbWWTIomRzAMaTyawAU//Reg==", + "dev": true, + "requires": { + "is-fullwidth-code-point": "^2.0.0" + } + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" + }, + "source-map-support": { + "version": "0.4.18", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.4.18.tgz", + "integrity": "sha512-try0/JqxPLF9nOjvSta7tVondkP5dwgyLDjVoyMDlmjugT2lRZ1OfsrYTkCd2hkDnJTKRbO/Rl3orm8vlsUzbA==", + "dev": true, + "requires": { + "source-map": "^0.5.6" + }, + "dependencies": { + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "dev": true + } + } + }, + "sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", + "dev": true + }, + "string-width": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", + "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", + "dev": true, + "requires": { + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^4.0.0" + }, + "dependencies": { + "ansi-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", + "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", + "dev": true + }, + "strip-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", + "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", + "dev": true, + "requires": { + "ansi-regex": "^3.0.0" + } + } + } + }, + "string.prototype.matchall": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/string.prototype.matchall/-/string.prototype.matchall-2.0.0.tgz", + "integrity": "sha512-WoZ+B2ypng1dp4iFLF2kmZlwwlE19gmjgKuhL1FJfDgCREWb3ye3SDVHSzLH6bxfnvYmkCxbzkmWcQZHA4P//Q==", + "dev": true, + "requires": { + "define-properties": "^1.1.2", + "es-abstract": "^1.10.0", + "function-bind": "^1.1.1", + "has-symbols": "^1.0.0", + "regexp.prototype.flags": "^1.2.0" + } + }, + "string.prototype.trim": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.1.2.tgz", + "integrity": "sha1-0E3iyJ4Tf019IG8Ia17S+ua+jOo=", + "dev": true, + "requires": { + "define-properties": "^1.1.2", + "es-abstract": "^1.5.0", + "function-bind": "^1.0.2" + } + }, + "string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dev": true, + "optional": true, + "requires": { + "safe-buffer": "~5.1.0" + } + }, + "strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "dev": true, + "requires": { + "ansi-regex": "^2.0.0" + } + }, + "strip-eof": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz", + "integrity": "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8=", + "dev": true + }, + "strip-json-comments": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", + "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=", + "dev": true + }, + "supports-color": { + "version": "5.4.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.4.0.tgz", + "integrity": "sha512-zjaXglF5nnWpsq470jSv6P9DwPvgLkuapYmfDm3JWOm0vkNTVF2tI4UrN2r6jH1qM/uc/WtxYY1hYoA2dOKj5w==", + "requires": { + "has-flag": "^3.0.0" + } + }, + "symbol-observable": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/symbol-observable/-/symbol-observable-1.0.1.tgz", + "integrity": "sha1-g0D8RwLDEi310iKI+IKD9RPT/dQ=", + "dev": true + }, + "table": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/table/-/table-4.0.3.tgz", + "integrity": "sha512-S7rnFITmBH1EnyKcvxBh1LjYeQMmnZtCXSEbHcH6S0NoKit24ZuFO/T1vDcLdYsLQkM188PVVhQmzKIuThNkKg==", + "dev": true, + "requires": { + "ajv": "^6.0.1", + "ajv-keywords": "^3.0.0", + "chalk": "^2.1.0", + "lodash": "^4.17.4", + "slice-ansi": "1.0.0", + "string-width": "^2.1.1" + } + }, + "tape": { + "version": "4.9.1", + "resolved": "https://registry.npmjs.org/tape/-/tape-4.9.1.tgz", + "integrity": "sha512-6fKIXknLpoe/Jp4rzHKFPpJUHDHDqn8jus99IfPnHIjyz78HYlefTGD3b5EkbQzuLfaEvmfPK3IolLgq2xT3kw==", + "dev": true, + "requires": { + "deep-equal": "~1.0.1", + "defined": "~1.0.0", + "for-each": "~0.3.3", + "function-bind": "~1.1.1", + "glob": "~7.1.2", + "has": "~1.0.3", + "inherits": "~2.0.3", + "minimist": "~1.2.0", + "object-inspect": "~1.6.0", + "resolve": "~1.7.1", + "resumer": "~0.0.0", + "string.prototype.trim": "~1.1.2", + "through": "~2.3.8" + }, + "dependencies": { + "minimist": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", + "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", + "dev": true + } + } + }, + "text-table": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", + "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=", + "dev": true + }, + "through": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", + "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=", + "dev": true + }, + "tmp": { + "version": "0.0.33", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", + "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", + "dev": true, + "requires": { + "os-tmpdir": "~1.0.2" + } + }, + "to-fast-properties": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-1.0.3.tgz", + "integrity": "sha1-uDVx+k2MJbguIxsG46MFXeTKGkc=", + "dev": true + }, + "trash": { + "version": "3.4.2", + "resolved": "https://registry.npmjs.org/trash/-/trash-3.4.2.tgz", + "integrity": "sha1-+wQiUvwmoCInaVCiuw7Om5QF6xk=", + "dev": true, + "requires": { + "escape-string-applescript": "^1.0.0", + "fs-extra": "^0.26.2", + "globby": "^4.0.0", + "path-exists": "^2.0.0", + "pify": "^2.3.0", + "pinkie-promise": "^2.0.0", + "run-applescript": "^2.0.0", + "uuid": "^2.0.1", + "xdg-trashdir": "^2.0.0" + }, + "dependencies": { + "glob": { + "version": "6.0.4", + "resolved": "https://registry.npmjs.org/glob/-/glob-6.0.4.tgz", + "integrity": "sha1-DwiGD2oVUSey+t1PnOJLGqtuTSI=", + "dev": true, + "requires": { + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "2 || 3", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "globby": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-4.1.0.tgz", + "integrity": "sha1-CA9UVJ7BuCpsYOYx/ILhIR2+lfg=", + "dev": true, + "requires": { + "array-union": "^1.0.1", + "arrify": "^1.0.0", + "glob": "^6.0.1", + "object-assign": "^4.0.1", + "pify": "^2.0.0", + "pinkie-promise": "^2.0.0" + } + } + } + }, + "trim-right": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/trim-right/-/trim-right-1.0.1.tgz", + "integrity": "sha1-yy4SAwZ+DI3h9hQJS5/kVwTqYAM=", + "dev": true + }, + "try-catch": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/try-catch/-/try-catch-2.0.0.tgz", + "integrity": "sha512-RPXpVjsbtWgymwGq5F/OWDFsjEzdvzwHFaMjWWW6f/p6+uk/N7YSKJHQfIfGqITfj8qH4cBqCLMnhKZBaKk7Kg==", + "dev": true + }, + "type-check": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", + "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=", + "dev": true, + "requires": { + "prelude-ls": "~1.1.2" + } + }, + "uri-js": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.2.2.tgz", + "integrity": "sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ==", + "dev": true, + "requires": { + "punycode": "^2.1.0" + } + }, + "url-template": { + "version": "2.0.8", + "resolved": "https://registry.npmjs.org/url-template/-/url-template-2.0.8.tgz", + "integrity": "sha1-/FZaPMy/93MMd19WQflVV5FDnyE=", + "dev": true + }, + "user-home": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/user-home/-/user-home-1.1.1.tgz", + "integrity": "sha1-K1viOjK2Onyd640PKNSFcko98ZA=", + "dev": true + }, + "util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=", + "dev": true, + "optional": true + }, + "uuid": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-2.0.3.tgz", + "integrity": "sha1-Z+LoY3lyFVMN/zGOW/nc6/1Hsho=", + "dev": true + }, + "v8flags": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/v8flags/-/v8flags-2.1.1.tgz", + "integrity": "sha1-qrGh+jDUX4jdMhFIh1rALAtV5bQ=", + "dev": true, + "requires": { + "user-home": "^1.1.1" + } + }, + "which": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", + "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "dev": true, + "requires": { + "isexe": "^2.0.0" + } + }, + "wordwrap": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", + "integrity": "sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus=", + "dev": true + }, + "wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", + "dev": true + }, + "write": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/write/-/write-0.2.1.tgz", + "integrity": "sha1-X8A4KOJkzqP+kUVUdvejxWbLB1c=", + "dev": true, + "requires": { + "mkdirp": "^0.5.1" + } + }, + "xdg-basedir": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/xdg-basedir/-/xdg-basedir-2.0.0.tgz", + "integrity": "sha1-7byQPMOF/ARSPZZqM1UEtVBNG9I=", + "dev": true, + "requires": { + "os-homedir": "^1.0.0" + } + }, + "xdg-trashdir": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/xdg-trashdir/-/xdg-trashdir-2.1.1.tgz", + "integrity": "sha512-KcVhPaOu2ZurYNHSRTf1+ZHORkTZGCQ+u0JHN17QixRISJq4pXOnjt/lQcehvtHL5QAKhSzKgyjrcNnPdkPBHA==", + "dev": true, + "requires": { + "@sindresorhus/df": "^2.1.0", + "mount-point": "^3.0.0", + "pify": "^2.2.0", + "user-home": "^2.0.0", + "xdg-basedir": "^2.0.0" + }, + "dependencies": { + "user-home": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/user-home/-/user-home-2.0.0.tgz", + "integrity": "sha1-nHC/2Babwdy/SGBODwS4tJzenp8=", + "dev": true, + "requires": { + "os-homedir": "^1.0.0" + } + } + } + }, + "yallist": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", + "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=", + "dev": true + } + } +} diff --git a/package.json b/package.json index f92e6716fc..4b1b5a5dd5 100644 --- a/package.json +++ b/package.json @@ -17,9 +17,12 @@ "files": [ "dist" ], + "engines": { + "node": ">=6.0.0" + }, "dependencies": { "balanced-match": "^1.0.0", - "postcss": "^6.0.23" + "postcss": "^7.0.2" }, "devDependencies": { "babel-cli": "^6.26.0", From 77742ddd1f03ea78e777e3cf428795baf2eafab7 Mon Sep 17 00:00:00 2001 From: Pascal Duez Date: Mon, 13 Aug 2018 14:36:30 +0200 Subject: [PATCH 656/795] Use PostCSS 7 Refs csstools/postcss-preset-env#58 Also added a `package-lock` file. --- .travis.yml | 2 +- package-lock.json | 4144 +++++++++++++++++++++++++++++++++++++++++++++ package.json | 5 +- 3 files changed, 4149 insertions(+), 2 deletions(-) create mode 100644 package-lock.json diff --git a/.travis.yml b/.travis.yml index 39024ba818..527110b309 100644 --- a/.travis.yml +++ b/.travis.yml @@ -2,5 +2,5 @@ sudo: false language: node_js node_js: - stable + - "8" - "6" - - "4" diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 0000000000..b89deadf46 --- /dev/null +++ b/package-lock.json @@ -0,0 +1,4144 @@ +{ + "name": "postcss-custom-selectors", + "version": "4.0.1", + "lockfileVersion": 1, + "requires": true, + "dependencies": { + "acorn": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-5.7.1.tgz", + "integrity": "sha512-d+nbxBUGKg7Arpsvbnlq61mc12ek3EY8EQldM3GPAhWJ1UVxC6TDGbIvUMNU6obBX3i1+ptCIzV4vq0gFPEGVQ==", + "dev": true + }, + "acorn-jsx": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-3.0.1.tgz", + "integrity": "sha1-r9+UiPsezvyDSPb7IvRk4ypYs2s=", + "dev": true, + "requires": { + "acorn": "^3.0.4" + }, + "dependencies": { + "acorn": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-3.3.0.tgz", + "integrity": "sha1-ReN/s56No/JbruP/U2niu18iAXo=", + "dev": true + } + } + }, + "ajv": { + "version": "4.11.8", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-4.11.8.tgz", + "integrity": "sha1-gv+wKynmYq5TvcIK8VlHcGc5xTY=", + "dev": true, + "requires": { + "co": "^4.6.0", + "json-stable-stringify": "^1.0.1" + } + }, + "ajv-keywords": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-1.5.1.tgz", + "integrity": "sha1-MU3QpLM2j609/NxU7eYXG4htrzw=", + "dev": true + }, + "align-text": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/align-text/-/align-text-0.1.4.tgz", + "integrity": "sha1-DNkKVhCT810KmSVsIrcGlDP60Rc=", + "dev": true, + "requires": { + "kind-of": "^3.0.2", + "longest": "^1.0.1", + "repeat-string": "^1.5.2" + } + }, + "alter": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/alter/-/alter-0.2.0.tgz", + "integrity": "sha1-x1iICGF1cgNKrmJICvJrHU0cs80=", + "dev": true, + "requires": { + "stable": "~0.1.3" + } + }, + "amdefine": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/amdefine/-/amdefine-1.0.1.tgz", + "integrity": "sha1-SlKCrBZHKek2Gbz9OtFR+BfOkfU=", + "dev": true + }, + "ansi-escapes": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-1.4.0.tgz", + "integrity": "sha1-06ioOzGapneTZisT52HHkRQiMG4=", + "dev": true + }, + "ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", + "dev": true + }, + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "requires": { + "color-convert": "^1.9.0" + } + }, + "anymatch": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-1.3.2.tgz", + "integrity": "sha512-0XNayC8lTHQ2OI8aljNCN3sSx6hsr/1+rlcDAotXJR7C1oZZHCNsfpbKwMjRA3Uqb5tF1Rae2oloTr4xpq+WjA==", + "dev": true, + "optional": true, + "requires": { + "micromatch": "^2.1.5", + "normalize-path": "^2.0.0" + } + }, + "argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "dev": true, + "requires": { + "sprintf-js": "~1.0.2" + } + }, + "arr-diff": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-2.0.0.tgz", + "integrity": "sha1-jzuCf5Vai9ZpaX5KQlasPOrjVs8=", + "dev": true, + "optional": true, + "requires": { + "arr-flatten": "^1.0.1" + } + }, + "arr-flatten": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/arr-flatten/-/arr-flatten-1.1.0.tgz", + "integrity": "sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==", + "dev": true, + "optional": true + }, + "array-union": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-1.0.2.tgz", + "integrity": "sha1-mjRBDk9OPaI96jdb5b5w8kd47Dk=", + "dev": true, + "requires": { + "array-uniq": "^1.0.1" + } + }, + "array-uniq": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/array-uniq/-/array-uniq-1.0.3.tgz", + "integrity": "sha1-r2rId6Jcx/dOBYiUdThY39sk/bY=", + "dev": true + }, + "array-unique": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.2.1.tgz", + "integrity": "sha1-odl8yvy8JiXMcPrc6zalDFiwGlM=", + "dev": true, + "optional": true + }, + "arrify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", + "integrity": "sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=", + "dev": true + }, + "ast-traverse": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/ast-traverse/-/ast-traverse-0.1.1.tgz", + "integrity": "sha1-ac8rg4bxnc2hux4F1o/jWdiJfeY=", + "dev": true + }, + "ast-types": { + "version": "0.9.6", + "resolved": "https://registry.npmjs.org/ast-types/-/ast-types-0.9.6.tgz", + "integrity": "sha1-ECyenpAF0+fjgpvwxPok7oYu6bk=", + "dev": true + }, + "async-each": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/async-each/-/async-each-1.0.1.tgz", + "integrity": "sha1-GdOGodntxufByF04iu28xW0zYC0=", + "dev": true, + "optional": true + }, + "babel-cli": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-cli/-/babel-cli-6.26.0.tgz", + "integrity": "sha1-UCq1SHTX24itALiHoGODzgPQAvE=", + "dev": true, + "requires": { + "babel-core": "^6.26.0", + "babel-polyfill": "^6.26.0", + "babel-register": "^6.26.0", + "babel-runtime": "^6.26.0", + "chokidar": "^1.6.1", + "commander": "^2.11.0", + "convert-source-map": "^1.5.0", + "fs-readdir-recursive": "^1.0.0", + "glob": "^7.1.2", + "lodash": "^4.17.4", + "output-file-sync": "^1.1.2", + "path-is-absolute": "^1.0.1", + "slash": "^1.0.0", + "source-map": "^0.5.6", + "v8flags": "^2.1.1" + }, + "dependencies": { + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "dev": true + } + } + }, + "babel-code-frame": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-code-frame/-/babel-code-frame-6.26.0.tgz", + "integrity": "sha1-Y/1D99weO7fONZR9uP42mj9Yx0s=", + "dev": true, + "requires": { + "chalk": "^1.1.3", + "esutils": "^2.0.2", + "js-tokens": "^3.0.2" + }, + "dependencies": { + "ansi-styles": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", + "dev": true + }, + "chalk": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", + "dev": true, + "requires": { + "ansi-styles": "^2.2.1", + "escape-string-regexp": "^1.0.2", + "has-ansi": "^2.0.0", + "strip-ansi": "^3.0.0", + "supports-color": "^2.0.0" + } + }, + "supports-color": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", + "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", + "dev": true + } + } + }, + "babel-core": { + "version": "6.26.3", + "resolved": "https://registry.npmjs.org/babel-core/-/babel-core-6.26.3.tgz", + "integrity": "sha512-6jyFLuDmeidKmUEb3NM+/yawG0M2bDZ9Z1qbZP59cyHLz8kYGKYwpJP0UwUKKUiTRNvxfLesJnTedqczP7cTDA==", + "dev": true, + "requires": { + "babel-code-frame": "^6.26.0", + "babel-generator": "^6.26.0", + "babel-helpers": "^6.24.1", + "babel-messages": "^6.23.0", + "babel-register": "^6.26.0", + "babel-runtime": "^6.26.0", + "babel-template": "^6.26.0", + "babel-traverse": "^6.26.0", + "babel-types": "^6.26.0", + "babylon": "^6.18.0", + "convert-source-map": "^1.5.1", + "debug": "^2.6.9", + "json5": "^0.5.1", + "lodash": "^4.17.4", + "minimatch": "^3.0.4", + "path-is-absolute": "^1.0.1", + "private": "^0.1.8", + "slash": "^1.0.0", + "source-map": "^0.5.7" + }, + "dependencies": { + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "dev": true + } + } + }, + "babel-generator": { + "version": "6.26.1", + "resolved": "https://registry.npmjs.org/babel-generator/-/babel-generator-6.26.1.tgz", + "integrity": "sha512-HyfwY6ApZj7BYTcJURpM5tznulaBvyio7/0d4zFOeMPUmfxkCjHocCuoLa2SAGzBI8AREcH3eP3758F672DppA==", + "dev": true, + "requires": { + "babel-messages": "^6.23.0", + "babel-runtime": "^6.26.0", + "babel-types": "^6.26.0", + "detect-indent": "^4.0.0", + "jsesc": "^1.3.0", + "lodash": "^4.17.4", + "source-map": "^0.5.7", + "trim-right": "^1.0.1" + }, + "dependencies": { + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "dev": true + } + } + }, + "babel-helper-builder-binary-assignment-operator-visitor": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-helper-builder-binary-assignment-operator-visitor/-/babel-helper-builder-binary-assignment-operator-visitor-6.24.1.tgz", + "integrity": "sha1-zORReto1b0IgvK6KAsKzRvmlZmQ=", + "dev": true, + "requires": { + "babel-helper-explode-assignable-expression": "^6.24.1", + "babel-runtime": "^6.22.0", + "babel-types": "^6.24.1" + } + }, + "babel-helper-call-delegate": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-helper-call-delegate/-/babel-helper-call-delegate-6.24.1.tgz", + "integrity": "sha1-7Oaqzdx25Bw0YfiL/Fdb0Nqi340=", + "dev": true, + "requires": { + "babel-helper-hoist-variables": "^6.24.1", + "babel-runtime": "^6.22.0", + "babel-traverse": "^6.24.1", + "babel-types": "^6.24.1" + } + }, + "babel-helper-define-map": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-helper-define-map/-/babel-helper-define-map-6.26.0.tgz", + "integrity": "sha1-pfVtq0GiX5fstJjH66ypgZ+Vvl8=", + "dev": true, + "requires": { + "babel-helper-function-name": "^6.24.1", + "babel-runtime": "^6.26.0", + "babel-types": "^6.26.0", + "lodash": "^4.17.4" + } + }, + "babel-helper-explode-assignable-expression": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-helper-explode-assignable-expression/-/babel-helper-explode-assignable-expression-6.24.1.tgz", + "integrity": "sha1-8luCz33BBDPFX3BZLVdGQArCLKo=", + "dev": true, + "requires": { + "babel-runtime": "^6.22.0", + "babel-traverse": "^6.24.1", + "babel-types": "^6.24.1" + } + }, + "babel-helper-function-name": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-helper-function-name/-/babel-helper-function-name-6.24.1.tgz", + "integrity": "sha1-00dbjAPtmCQqJbSDUasYOZ01gKk=", + "dev": true, + "requires": { + "babel-helper-get-function-arity": "^6.24.1", + "babel-runtime": "^6.22.0", + "babel-template": "^6.24.1", + "babel-traverse": "^6.24.1", + "babel-types": "^6.24.1" + } + }, + "babel-helper-get-function-arity": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-helper-get-function-arity/-/babel-helper-get-function-arity-6.24.1.tgz", + "integrity": "sha1-j3eCqpNAfEHTqlCQj4mwMbG2hT0=", + "dev": true, + "requires": { + "babel-runtime": "^6.22.0", + "babel-types": "^6.24.1" + } + }, + "babel-helper-hoist-variables": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-helper-hoist-variables/-/babel-helper-hoist-variables-6.24.1.tgz", + "integrity": "sha1-HssnaJydJVE+rbyZFKc/VAi+enY=", + "dev": true, + "requires": { + "babel-runtime": "^6.22.0", + "babel-types": "^6.24.1" + } + }, + "babel-helper-optimise-call-expression": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-helper-optimise-call-expression/-/babel-helper-optimise-call-expression-6.24.1.tgz", + "integrity": "sha1-96E0J7qfc/j0+pk8VKl4gtEkQlc=", + "dev": true, + "requires": { + "babel-runtime": "^6.22.0", + "babel-types": "^6.24.1" + } + }, + "babel-helper-regex": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-helper-regex/-/babel-helper-regex-6.26.0.tgz", + "integrity": "sha1-MlxZ+QL4LyS3T6zu0DY5VPZJXnI=", + "dev": true, + "requires": { + "babel-runtime": "^6.26.0", + "babel-types": "^6.26.0", + "lodash": "^4.17.4" + } + }, + "babel-helper-remap-async-to-generator": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-helper-remap-async-to-generator/-/babel-helper-remap-async-to-generator-6.24.1.tgz", + "integrity": "sha1-XsWBgnrXI/7N04HxySg5BnbkVRs=", + "dev": true, + "requires": { + "babel-helper-function-name": "^6.24.1", + "babel-runtime": "^6.22.0", + "babel-template": "^6.24.1", + "babel-traverse": "^6.24.1", + "babel-types": "^6.24.1" + } + }, + "babel-helper-replace-supers": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-helper-replace-supers/-/babel-helper-replace-supers-6.24.1.tgz", + "integrity": "sha1-v22/5Dk40XNpohPKiov3S2qQqxo=", + "dev": true, + "requires": { + "babel-helper-optimise-call-expression": "^6.24.1", + "babel-messages": "^6.23.0", + "babel-runtime": "^6.22.0", + "babel-template": "^6.24.1", + "babel-traverse": "^6.24.1", + "babel-types": "^6.24.1" + } + }, + "babel-helpers": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-helpers/-/babel-helpers-6.24.1.tgz", + "integrity": "sha1-NHHenK7DiOXIUOWX5Yom3fN2ArI=", + "dev": true, + "requires": { + "babel-runtime": "^6.22.0", + "babel-template": "^6.24.1" + } + }, + "babel-messages": { + "version": "6.23.0", + "resolved": "https://registry.npmjs.org/babel-messages/-/babel-messages-6.23.0.tgz", + "integrity": "sha1-8830cDhYA1sqKVHG7F7fbGLyYw4=", + "dev": true, + "requires": { + "babel-runtime": "^6.22.0" + } + }, + "babel-plugin-add-module-exports": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/babel-plugin-add-module-exports/-/babel-plugin-add-module-exports-0.2.1.tgz", + "integrity": "sha1-mumh9KjcZ/DN7E9K7aHkOl/2XiU=", + "dev": true + }, + "babel-plugin-check-es2015-constants": { + "version": "6.22.0", + "resolved": "https://registry.npmjs.org/babel-plugin-check-es2015-constants/-/babel-plugin-check-es2015-constants-6.22.0.tgz", + "integrity": "sha1-NRV7EBQm/S/9PaP3XH0ekYNbv4o=", + "dev": true, + "requires": { + "babel-runtime": "^6.22.0" + } + }, + "babel-plugin-constant-folding": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/babel-plugin-constant-folding/-/babel-plugin-constant-folding-1.0.1.tgz", + "integrity": "sha1-g2HTZMmORJw2kr26Ue/whEKQqo4=", + "dev": true + }, + "babel-plugin-dead-code-elimination": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/babel-plugin-dead-code-elimination/-/babel-plugin-dead-code-elimination-1.0.2.tgz", + "integrity": "sha1-X3xFEnTc18zNv7s+C4XdKBIfD2U=", + "dev": true + }, + "babel-plugin-eval": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/babel-plugin-eval/-/babel-plugin-eval-1.0.1.tgz", + "integrity": "sha1-ovrtJc5r5preS/7CY/cBaRlZUNo=", + "dev": true + }, + "babel-plugin-inline-environment-variables": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/babel-plugin-inline-environment-variables/-/babel-plugin-inline-environment-variables-1.0.1.tgz", + "integrity": "sha1-H1jOkSB61qgmqL9kX6/mj/X+P/4=", + "dev": true + }, + "babel-plugin-jscript": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/babel-plugin-jscript/-/babel-plugin-jscript-1.0.4.tgz", + "integrity": "sha1-jzQsOCduh6R9X6CovT1etsytj8w=", + "dev": true + }, + "babel-plugin-member-expression-literals": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/babel-plugin-member-expression-literals/-/babel-plugin-member-expression-literals-1.0.1.tgz", + "integrity": "sha1-zF7bD6qNyScXDnTW0cAkQAIWJNM=", + "dev": true + }, + "babel-plugin-property-literals": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/babel-plugin-property-literals/-/babel-plugin-property-literals-1.0.1.tgz", + "integrity": "sha1-AlIwGQAZKYCxwRjv6kjOk6q4MzY=", + "dev": true + }, + "babel-plugin-proto-to-assign": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/babel-plugin-proto-to-assign/-/babel-plugin-proto-to-assign-1.0.4.tgz", + "integrity": "sha1-xJ56/QL1d7xNoF6i3wAiUM980SM=", + "dev": true, + "requires": { + "lodash": "^3.9.3" + }, + "dependencies": { + "lodash": { + "version": "3.10.1", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-3.10.1.tgz", + "integrity": "sha1-W/Rejkm6QYnhfUgnid/RW9FAt7Y=", + "dev": true + } + } + }, + "babel-plugin-react-constant-elements": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/babel-plugin-react-constant-elements/-/babel-plugin-react-constant-elements-1.0.3.tgz", + "integrity": "sha1-lGc26DeEKcvDSdz/YvUcFDs041o=", + "dev": true + }, + "babel-plugin-react-display-name": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/babel-plugin-react-display-name/-/babel-plugin-react-display-name-1.0.3.tgz", + "integrity": "sha1-dU/jiSboQkpOexWrbqYTne4FFPw=", + "dev": true + }, + "babel-plugin-remove-console": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/babel-plugin-remove-console/-/babel-plugin-remove-console-1.0.1.tgz", + "integrity": "sha1-2PJFVsOgUAXUKqqv0neH9T/wE6c=", + "dev": true + }, + "babel-plugin-remove-debugger": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/babel-plugin-remove-debugger/-/babel-plugin-remove-debugger-1.0.1.tgz", + "integrity": "sha1-/S6jzWGkKK0fO5yJiC/0KT6MFMc=", + "dev": true + }, + "babel-plugin-runtime": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/babel-plugin-runtime/-/babel-plugin-runtime-1.0.7.tgz", + "integrity": "sha1-v3x9lm3Vbs1cF/ocslPJrLflSq8=", + "dev": true + }, + "babel-plugin-syntax-async-functions": { + "version": "6.13.0", + "resolved": "https://registry.npmjs.org/babel-plugin-syntax-async-functions/-/babel-plugin-syntax-async-functions-6.13.0.tgz", + "integrity": "sha1-ytnK0RkbWtY0vzCuCHI5HgZHvpU=", + "dev": true + }, + "babel-plugin-syntax-exponentiation-operator": { + "version": "6.13.0", + "resolved": "https://registry.npmjs.org/babel-plugin-syntax-exponentiation-operator/-/babel-plugin-syntax-exponentiation-operator-6.13.0.tgz", + "integrity": "sha1-nufoM3KQ2pUoggGmpX9BcDF4MN4=", + "dev": true + }, + "babel-plugin-syntax-object-rest-spread": { + "version": "6.13.0", + "resolved": "https://registry.npmjs.org/babel-plugin-syntax-object-rest-spread/-/babel-plugin-syntax-object-rest-spread-6.13.0.tgz", + "integrity": "sha1-/WU28rzhODb/o6VFjEkDpZe7O/U=", + "dev": true + }, + "babel-plugin-syntax-trailing-function-commas": { + "version": "6.22.0", + "resolved": "https://registry.npmjs.org/babel-plugin-syntax-trailing-function-commas/-/babel-plugin-syntax-trailing-function-commas-6.22.0.tgz", + "integrity": "sha1-ugNgk3+NBuQBgKQ/4NVhb/9TLPM=", + "dev": true + }, + "babel-plugin-transform-async-to-generator": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-async-to-generator/-/babel-plugin-transform-async-to-generator-6.24.1.tgz", + "integrity": "sha1-ZTbjeK/2yx1VF6wOQOs+n8jQh2E=", + "dev": true, + "requires": { + "babel-helper-remap-async-to-generator": "^6.24.1", + "babel-plugin-syntax-async-functions": "^6.8.0", + "babel-runtime": "^6.22.0" + } + }, + "babel-plugin-transform-es2015-arrow-functions": { + "version": "6.22.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-arrow-functions/-/babel-plugin-transform-es2015-arrow-functions-6.22.0.tgz", + "integrity": "sha1-RSaSy3EdX3ncf4XkQM5BufJE0iE=", + "dev": true, + "requires": { + "babel-runtime": "^6.22.0" + } + }, + "babel-plugin-transform-es2015-block-scoped-functions": { + "version": "6.22.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-block-scoped-functions/-/babel-plugin-transform-es2015-block-scoped-functions-6.22.0.tgz", + "integrity": "sha1-u8UbSflk1wy42OC5ToICRs46YUE=", + "dev": true, + "requires": { + "babel-runtime": "^6.22.0" + } + }, + "babel-plugin-transform-es2015-block-scoping": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-block-scoping/-/babel-plugin-transform-es2015-block-scoping-6.26.0.tgz", + "integrity": "sha1-1w9SmcEwjQXBL0Y4E7CgnnOxiV8=", + "dev": true, + "requires": { + "babel-runtime": "^6.26.0", + "babel-template": "^6.26.0", + "babel-traverse": "^6.26.0", + "babel-types": "^6.26.0", + "lodash": "^4.17.4" + } + }, + "babel-plugin-transform-es2015-classes": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-classes/-/babel-plugin-transform-es2015-classes-6.24.1.tgz", + "integrity": "sha1-WkxYpQyclGHlZLSyo7+ryXolhNs=", + "dev": true, + "requires": { + "babel-helper-define-map": "^6.24.1", + "babel-helper-function-name": "^6.24.1", + "babel-helper-optimise-call-expression": "^6.24.1", + "babel-helper-replace-supers": "^6.24.1", + "babel-messages": "^6.23.0", + "babel-runtime": "^6.22.0", + "babel-template": "^6.24.1", + "babel-traverse": "^6.24.1", + "babel-types": "^6.24.1" + } + }, + "babel-plugin-transform-es2015-computed-properties": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-computed-properties/-/babel-plugin-transform-es2015-computed-properties-6.24.1.tgz", + "integrity": "sha1-b+Ko0WiV1WNPTNmZttNICjCBWbM=", + "dev": true, + "requires": { + "babel-runtime": "^6.22.0", + "babel-template": "^6.24.1" + } + }, + "babel-plugin-transform-es2015-destructuring": { + "version": "6.23.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-destructuring/-/babel-plugin-transform-es2015-destructuring-6.23.0.tgz", + "integrity": "sha1-mXux8auWf2gtKwh2/jWNYOdlxW0=", + "dev": true, + "requires": { + "babel-runtime": "^6.22.0" + } + }, + "babel-plugin-transform-es2015-duplicate-keys": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-duplicate-keys/-/babel-plugin-transform-es2015-duplicate-keys-6.24.1.tgz", + "integrity": "sha1-c+s9MQypaePvnskcU3QabxV2Qj4=", + "dev": true, + "requires": { + "babel-runtime": "^6.22.0", + "babel-types": "^6.24.1" + } + }, + "babel-plugin-transform-es2015-for-of": { + "version": "6.23.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-for-of/-/babel-plugin-transform-es2015-for-of-6.23.0.tgz", + "integrity": "sha1-9HyVsrYT3x0+zC/bdXNiPHUkhpE=", + "dev": true, + "requires": { + "babel-runtime": "^6.22.0" + } + }, + "babel-plugin-transform-es2015-function-name": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-function-name/-/babel-plugin-transform-es2015-function-name-6.24.1.tgz", + "integrity": "sha1-g0yJhTvDaxrw86TF26qU/Y6sqos=", + "dev": true, + "requires": { + "babel-helper-function-name": "^6.24.1", + "babel-runtime": "^6.22.0", + "babel-types": "^6.24.1" + } + }, + "babel-plugin-transform-es2015-literals": { + "version": "6.22.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-literals/-/babel-plugin-transform-es2015-literals-6.22.0.tgz", + "integrity": "sha1-T1SgLWzWbPkVKAAZox0xklN3yi4=", + "dev": true, + "requires": { + "babel-runtime": "^6.22.0" + } + }, + "babel-plugin-transform-es2015-modules-amd": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-modules-amd/-/babel-plugin-transform-es2015-modules-amd-6.24.1.tgz", + "integrity": "sha1-Oz5UAXI5hC1tGcMBHEvS8AoA0VQ=", + "dev": true, + "requires": { + "babel-plugin-transform-es2015-modules-commonjs": "^6.24.1", + "babel-runtime": "^6.22.0", + "babel-template": "^6.24.1" + } + }, + "babel-plugin-transform-es2015-modules-commonjs": { + "version": "6.26.2", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-modules-commonjs/-/babel-plugin-transform-es2015-modules-commonjs-6.26.2.tgz", + "integrity": "sha512-CV9ROOHEdrjcwhIaJNBGMBCodN+1cfkwtM1SbUHmvyy35KGT7fohbpOxkE2uLz1o6odKK2Ck/tz47z+VqQfi9Q==", + "dev": true, + "requires": { + "babel-plugin-transform-strict-mode": "^6.24.1", + "babel-runtime": "^6.26.0", + "babel-template": "^6.26.0", + "babel-types": "^6.26.0" + } + }, + "babel-plugin-transform-es2015-modules-systemjs": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-modules-systemjs/-/babel-plugin-transform-es2015-modules-systemjs-6.24.1.tgz", + "integrity": "sha1-/4mhQrkRmpBhlfXxBuzzBdlAfSM=", + "dev": true, + "requires": { + "babel-helper-hoist-variables": "^6.24.1", + "babel-runtime": "^6.22.0", + "babel-template": "^6.24.1" + } + }, + "babel-plugin-transform-es2015-modules-umd": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-modules-umd/-/babel-plugin-transform-es2015-modules-umd-6.24.1.tgz", + "integrity": "sha1-rJl+YoXNGO1hdq22B9YCNErThGg=", + "dev": true, + "requires": { + "babel-plugin-transform-es2015-modules-amd": "^6.24.1", + "babel-runtime": "^6.22.0", + "babel-template": "^6.24.1" + } + }, + "babel-plugin-transform-es2015-object-super": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-object-super/-/babel-plugin-transform-es2015-object-super-6.24.1.tgz", + "integrity": "sha1-JM72muIcuDp/hgPa0CH1cusnj40=", + "dev": true, + "requires": { + "babel-helper-replace-supers": "^6.24.1", + "babel-runtime": "^6.22.0" + } + }, + "babel-plugin-transform-es2015-parameters": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-parameters/-/babel-plugin-transform-es2015-parameters-6.24.1.tgz", + "integrity": "sha1-V6w1GrScrxSpfNE7CfZv3wpiXys=", + "dev": true, + "requires": { + "babel-helper-call-delegate": "^6.24.1", + "babel-helper-get-function-arity": "^6.24.1", + "babel-runtime": "^6.22.0", + "babel-template": "^6.24.1", + "babel-traverse": "^6.24.1", + "babel-types": "^6.24.1" + } + }, + "babel-plugin-transform-es2015-shorthand-properties": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-shorthand-properties/-/babel-plugin-transform-es2015-shorthand-properties-6.24.1.tgz", + "integrity": "sha1-JPh11nIch2YbvZmkYi5R8U3jiqA=", + "dev": true, + "requires": { + "babel-runtime": "^6.22.0", + "babel-types": "^6.24.1" + } + }, + "babel-plugin-transform-es2015-spread": { + "version": "6.22.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-spread/-/babel-plugin-transform-es2015-spread-6.22.0.tgz", + "integrity": "sha1-1taKmfia7cRTbIGlQujdnxdG+NE=", + "dev": true, + "requires": { + "babel-runtime": "^6.22.0" + } + }, + "babel-plugin-transform-es2015-sticky-regex": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-sticky-regex/-/babel-plugin-transform-es2015-sticky-regex-6.24.1.tgz", + "integrity": "sha1-AMHNsaynERLN8M9hJsLta0V8zbw=", + "dev": true, + "requires": { + "babel-helper-regex": "^6.24.1", + "babel-runtime": "^6.22.0", + "babel-types": "^6.24.1" + } + }, + "babel-plugin-transform-es2015-template-literals": { + "version": "6.22.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-template-literals/-/babel-plugin-transform-es2015-template-literals-6.22.0.tgz", + "integrity": "sha1-qEs0UPfp+PH2g51taH2oS7EjbY0=", + "dev": true, + "requires": { + "babel-runtime": "^6.22.0" + } + }, + "babel-plugin-transform-es2015-typeof-symbol": { + "version": "6.23.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-typeof-symbol/-/babel-plugin-transform-es2015-typeof-symbol-6.23.0.tgz", + "integrity": "sha1-3sCfHN3/lLUqxz1QXITfWdzOs3I=", + "dev": true, + "requires": { + "babel-runtime": "^6.22.0" + } + }, + "babel-plugin-transform-es2015-unicode-regex": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-unicode-regex/-/babel-plugin-transform-es2015-unicode-regex-6.24.1.tgz", + "integrity": "sha1-04sS9C6nMj9yk4fxinxa4frrNek=", + "dev": true, + "requires": { + "babel-helper-regex": "^6.24.1", + "babel-runtime": "^6.22.0", + "regexpu-core": "^2.0.0" + } + }, + "babel-plugin-transform-exponentiation-operator": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-exponentiation-operator/-/babel-plugin-transform-exponentiation-operator-6.24.1.tgz", + "integrity": "sha1-KrDJx/MJj6SJB3cruBP+QejeOg4=", + "dev": true, + "requires": { + "babel-helper-builder-binary-assignment-operator-visitor": "^6.24.1", + "babel-plugin-syntax-exponentiation-operator": "^6.8.0", + "babel-runtime": "^6.22.0" + } + }, + "babel-plugin-transform-object-rest-spread": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-object-rest-spread/-/babel-plugin-transform-object-rest-spread-6.26.0.tgz", + "integrity": "sha1-DzZpLVD+9rfi1LOsFHgTepY7ewY=", + "dev": true, + "requires": { + "babel-plugin-syntax-object-rest-spread": "^6.8.0", + "babel-runtime": "^6.26.0" + } + }, + "babel-plugin-transform-regenerator": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-regenerator/-/babel-plugin-transform-regenerator-6.26.0.tgz", + "integrity": "sha1-4HA2lvveJ/Cj78rPi03KL3s6jy8=", + "dev": true, + "requires": { + "regenerator-transform": "^0.10.0" + } + }, + "babel-plugin-transform-strict-mode": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-strict-mode/-/babel-plugin-transform-strict-mode-6.24.1.tgz", + "integrity": "sha1-1fr3qleKZbvlkc9e2uBKDGcCB1g=", + "dev": true, + "requires": { + "babel-runtime": "^6.22.0", + "babel-types": "^6.24.1" + } + }, + "babel-plugin-undeclared-variables-check": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/babel-plugin-undeclared-variables-check/-/babel-plugin-undeclared-variables-check-1.0.2.tgz", + "integrity": "sha1-XPGqU52BP/ZOmWQSkK9iCWX2Xe4=", + "dev": true, + "requires": { + "leven": "^1.0.2" + } + }, + "babel-plugin-undefined-to-void": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/babel-plugin-undefined-to-void/-/babel-plugin-undefined-to-void-1.1.6.tgz", + "integrity": "sha1-f1eO+LeN+uYAM4XYQXph7aBuL4E=", + "dev": true + }, + "babel-polyfill": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-polyfill/-/babel-polyfill-6.26.0.tgz", + "integrity": "sha1-N5k3q8Z9eJWXCtxiHyhM2WbPIVM=", + "dev": true, + "requires": { + "babel-runtime": "^6.26.0", + "core-js": "^2.5.0", + "regenerator-runtime": "^0.10.5" + }, + "dependencies": { + "regenerator-runtime": { + "version": "0.10.5", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.10.5.tgz", + "integrity": "sha1-M2w+/BIgrc7dosn6tntaeVWjNlg=", + "dev": true + } + } + }, + "babel-preset-env": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/babel-preset-env/-/babel-preset-env-1.7.0.tgz", + "integrity": "sha512-9OR2afuKDneX2/q2EurSftUYM0xGu4O2D9adAhVfADDhrYDaxXV0rBbevVYoY9n6nyX1PmQW/0jtpJvUNr9CHg==", + "dev": true, + "requires": { + "babel-plugin-check-es2015-constants": "^6.22.0", + "babel-plugin-syntax-trailing-function-commas": "^6.22.0", + "babel-plugin-transform-async-to-generator": "^6.22.0", + "babel-plugin-transform-es2015-arrow-functions": "^6.22.0", + "babel-plugin-transform-es2015-block-scoped-functions": "^6.22.0", + "babel-plugin-transform-es2015-block-scoping": "^6.23.0", + "babel-plugin-transform-es2015-classes": "^6.23.0", + "babel-plugin-transform-es2015-computed-properties": "^6.22.0", + "babel-plugin-transform-es2015-destructuring": "^6.23.0", + "babel-plugin-transform-es2015-duplicate-keys": "^6.22.0", + "babel-plugin-transform-es2015-for-of": "^6.23.0", + "babel-plugin-transform-es2015-function-name": "^6.22.0", + "babel-plugin-transform-es2015-literals": "^6.22.0", + "babel-plugin-transform-es2015-modules-amd": "^6.22.0", + "babel-plugin-transform-es2015-modules-commonjs": "^6.23.0", + "babel-plugin-transform-es2015-modules-systemjs": "^6.23.0", + "babel-plugin-transform-es2015-modules-umd": "^6.23.0", + "babel-plugin-transform-es2015-object-super": "^6.22.0", + "babel-plugin-transform-es2015-parameters": "^6.23.0", + "babel-plugin-transform-es2015-shorthand-properties": "^6.22.0", + "babel-plugin-transform-es2015-spread": "^6.22.0", + "babel-plugin-transform-es2015-sticky-regex": "^6.22.0", + "babel-plugin-transform-es2015-template-literals": "^6.22.0", + "babel-plugin-transform-es2015-typeof-symbol": "^6.23.0", + "babel-plugin-transform-es2015-unicode-regex": "^6.22.0", + "babel-plugin-transform-exponentiation-operator": "^6.22.0", + "babel-plugin-transform-regenerator": "^6.22.0", + "browserslist": "^3.2.6", + "invariant": "^2.2.2", + "semver": "^5.3.0" + } + }, + "babel-register": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-register/-/babel-register-6.26.0.tgz", + "integrity": "sha1-btAhFz4vy0htestFxgCahW9kcHE=", + "dev": true, + "requires": { + "babel-core": "^6.26.0", + "babel-runtime": "^6.26.0", + "core-js": "^2.5.0", + "home-or-tmp": "^2.0.0", + "lodash": "^4.17.4", + "mkdirp": "^0.5.1", + "source-map-support": "^0.4.15" + } + }, + "babel-runtime": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-runtime/-/babel-runtime-6.26.0.tgz", + "integrity": "sha1-llxwWGaOgrVde/4E/yM3vItWR/4=", + "dev": true, + "requires": { + "core-js": "^2.4.0", + "regenerator-runtime": "^0.11.0" + } + }, + "babel-tape-runner": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/babel-tape-runner/-/babel-tape-runner-1.3.1.tgz", + "integrity": "sha1-aabKl/TxHOSGFSuijtIl4TM1yfg=", + "dev": true, + "requires": { + "babel-core": "^5.8.20", + "glob": "^5.0.14" + }, + "dependencies": { + "ansi-styles": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", + "dev": true + }, + "babel-core": { + "version": "5.8.38", + "resolved": "https://registry.npmjs.org/babel-core/-/babel-core-5.8.38.tgz", + "integrity": "sha1-H8ruedfmG3ULALjlT238nQr4ZVg=", + "dev": true, + "requires": { + "babel-plugin-constant-folding": "^1.0.1", + "babel-plugin-dead-code-elimination": "^1.0.2", + "babel-plugin-eval": "^1.0.1", + "babel-plugin-inline-environment-variables": "^1.0.1", + "babel-plugin-jscript": "^1.0.4", + "babel-plugin-member-expression-literals": "^1.0.1", + "babel-plugin-property-literals": "^1.0.1", + "babel-plugin-proto-to-assign": "^1.0.3", + "babel-plugin-react-constant-elements": "^1.0.3", + "babel-plugin-react-display-name": "^1.0.3", + "babel-plugin-remove-console": "^1.0.1", + "babel-plugin-remove-debugger": "^1.0.1", + "babel-plugin-runtime": "^1.0.7", + "babel-plugin-undeclared-variables-check": "^1.0.2", + "babel-plugin-undefined-to-void": "^1.1.6", + "babylon": "^5.8.38", + "bluebird": "^2.9.33", + "chalk": "^1.0.0", + "convert-source-map": "^1.1.0", + "core-js": "^1.0.0", + "debug": "^2.1.1", + "detect-indent": "^3.0.0", + "esutils": "^2.0.0", + "fs-readdir-recursive": "^0.1.0", + "globals": "^6.4.0", + "home-or-tmp": "^1.0.0", + "is-integer": "^1.0.4", + "js-tokens": "1.0.1", + "json5": "^0.4.0", + "lodash": "^3.10.0", + "minimatch": "^2.0.3", + "output-file-sync": "^1.1.0", + "path-exists": "^1.0.0", + "path-is-absolute": "^1.0.0", + "private": "^0.1.6", + "regenerator": "0.8.40", + "regexpu": "^1.3.0", + "repeating": "^1.1.2", + "resolve": "^1.1.6", + "shebang-regex": "^1.0.0", + "slash": "^1.0.0", + "source-map": "^0.5.0", + "source-map-support": "^0.2.10", + "to-fast-properties": "^1.0.0", + "trim-right": "^1.0.0", + "try-resolve": "^1.0.0" + } + }, + "babylon": { + "version": "5.8.38", + "resolved": "https://registry.npmjs.org/babylon/-/babylon-5.8.38.tgz", + "integrity": "sha1-7JsSCxG/bM1Bc6GL8hfmC3mFn/0=", + "dev": true + }, + "chalk": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", + "dev": true, + "requires": { + "ansi-styles": "^2.2.1", + "escape-string-regexp": "^1.0.2", + "has-ansi": "^2.0.0", + "strip-ansi": "^3.0.0", + "supports-color": "^2.0.0" + } + }, + "core-js": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-1.2.7.tgz", + "integrity": "sha1-ZSKUwUZR2yj6k70tX/KYOk8IxjY=", + "dev": true + }, + "detect-indent": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/detect-indent/-/detect-indent-3.0.1.tgz", + "integrity": "sha1-ncXl3bzu+DJXZLlFGwK8bVQIT3U=", + "dev": true, + "requires": { + "get-stdin": "^4.0.1", + "minimist": "^1.1.0", + "repeating": "^1.1.0" + } + }, + "fs-readdir-recursive": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/fs-readdir-recursive/-/fs-readdir-recursive-0.1.2.tgz", + "integrity": "sha1-MVtPuMHKW4xH3v7zGdBz2tNWgFk=", + "dev": true + }, + "glob": { + "version": "5.0.15", + "resolved": "https://registry.npmjs.org/glob/-/glob-5.0.15.tgz", + "integrity": "sha1-G8k2ueAvSmA/zCIuz3Yz0wuLk7E=", + "dev": true, + "requires": { + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "2 || 3", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "globals": { + "version": "6.4.1", + "resolved": "https://registry.npmjs.org/globals/-/globals-6.4.1.tgz", + "integrity": "sha1-hJgDKzttHMge68X3lpDY/in6v08=", + "dev": true + }, + "home-or-tmp": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/home-or-tmp/-/home-or-tmp-1.0.0.tgz", + "integrity": "sha1-S58eQIAMPlDGwn94FnavzOcfOYU=", + "dev": true, + "requires": { + "os-tmpdir": "^1.0.1", + "user-home": "^1.1.1" + } + }, + "js-tokens": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-1.0.1.tgz", + "integrity": "sha1-zENaXIuUrRWst5gxQPyAGCyJrq4=", + "dev": true + }, + "json5": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/json5/-/json5-0.4.0.tgz", + "integrity": "sha1-BUNS5MTIDIbAkjh31EneF2pzLI0=", + "dev": true + }, + "lodash": { + "version": "3.10.1", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-3.10.1.tgz", + "integrity": "sha1-W/Rejkm6QYnhfUgnid/RW9FAt7Y=", + "dev": true + }, + "minimatch": { + "version": "2.0.10", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-2.0.10.tgz", + "integrity": "sha1-jQh8OcazjAAbl/ynzm0OHoCvusc=", + "dev": true, + "requires": { + "brace-expansion": "^1.0.0" + } + }, + "minimist": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", + "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", + "dev": true + }, + "repeating": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/repeating/-/repeating-1.1.3.tgz", + "integrity": "sha1-PUEUIYh3U3SU+X93+Xhfq4EPpKw=", + "dev": true, + "requires": { + "is-finite": "^1.0.0" + } + }, + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "dev": true + }, + "source-map-support": { + "version": "0.2.10", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.2.10.tgz", + "integrity": "sha1-6lo5AKHByyUJagrozFwrSxDe09w=", + "dev": true, + "requires": { + "source-map": "0.1.32" + }, + "dependencies": { + "source-map": { + "version": "0.1.32", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.1.32.tgz", + "integrity": "sha1-yLbBZ3l7pHQKjqMyUhYv8IWRsmY=", + "dev": true, + "requires": { + "amdefine": ">=0.0.4" + } + } + } + }, + "supports-color": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", + "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", + "dev": true + } + } + }, + "babel-template": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-template/-/babel-template-6.26.0.tgz", + "integrity": "sha1-3gPi0WOWsGn0bdn/+FIfsaDjXgI=", + "dev": true, + "requires": { + "babel-runtime": "^6.26.0", + "babel-traverse": "^6.26.0", + "babel-types": "^6.26.0", + "babylon": "^6.18.0", + "lodash": "^4.17.4" + } + }, + "babel-traverse": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-traverse/-/babel-traverse-6.26.0.tgz", + "integrity": "sha1-RqnL1+3MYsjlwGTi0tjQ9ANXZu4=", + "dev": true, + "requires": { + "babel-code-frame": "^6.26.0", + "babel-messages": "^6.23.0", + "babel-runtime": "^6.26.0", + "babel-types": "^6.26.0", + "babylon": "^6.18.0", + "debug": "^2.6.8", + "globals": "^9.18.0", + "invariant": "^2.2.2", + "lodash": "^4.17.4" + } + }, + "babel-types": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-types/-/babel-types-6.26.0.tgz", + "integrity": "sha1-o7Bz+Uq0nrb6Vc1lInozQ4BjJJc=", + "dev": true, + "requires": { + "babel-runtime": "^6.26.0", + "esutils": "^2.0.2", + "lodash": "^4.17.4", + "to-fast-properties": "^1.0.3" + } + }, + "babylon": { + "version": "6.18.0", + "resolved": "https://registry.npmjs.org/babylon/-/babylon-6.18.0.tgz", + "integrity": "sha512-q/UEjfGJ2Cm3oKV71DJz9d25TPnq5rhBVL2Q4fA5wcC3jcrdn7+SssEybFIxwAvvP+YCsCYNKughoF33GxgycQ==", + "dev": true + }, + "balanced-match": { + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-0.4.2.tgz", + "integrity": "sha1-yz8+PHMtwPAe5wtAPzAuYddwmDg=" + }, + "binary-extensions": { + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.11.0.tgz", + "integrity": "sha1-RqoXUftqL5PuXmibsQh9SxTGwgU=", + "dev": true, + "optional": true + }, + "bluebird": { + "version": "2.11.0", + "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-2.11.0.tgz", + "integrity": "sha1-U0uQM8AiyVecVro7Plpcqvu2UOE=", + "dev": true + }, + "brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + }, + "dependencies": { + "balanced-match": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", + "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", + "dev": true + } + } + }, + "braces": { + "version": "1.8.5", + "resolved": "https://registry.npmjs.org/braces/-/braces-1.8.5.tgz", + "integrity": "sha1-uneWLhLf+WnWt2cR6RS3N4V79qc=", + "dev": true, + "optional": true, + "requires": { + "expand-range": "^1.8.1", + "preserve": "^0.2.0", + "repeat-element": "^1.1.2" + } + }, + "breakable": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/breakable/-/breakable-1.0.0.tgz", + "integrity": "sha1-eEp5eRWjjq0nutRWtVcstLuqeME=", + "dev": true + }, + "browserslist": { + "version": "3.2.8", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-3.2.8.tgz", + "integrity": "sha512-WHVocJYavUwVgVViC0ORikPHQquXwVh939TaelZ4WDqpWgTX/FsGhl/+P4qBUAGcRvtOgDgC+xftNWWp2RUTAQ==", + "dev": true, + "requires": { + "caniuse-lite": "^1.0.30000844", + "electron-to-chromium": "^1.3.47" + } + }, + "buffer-from": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", + "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==", + "dev": true + }, + "caller-path": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/caller-path/-/caller-path-0.1.0.tgz", + "integrity": "sha1-lAhe9jWB7NPaqSREqP6U6CV3dR8=", + "dev": true, + "requires": { + "callsites": "^0.2.0" + } + }, + "callsites": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-0.2.0.tgz", + "integrity": "sha1-r6uWJikQp/M8GaV3WCXGnzTjUMo=", + "dev": true + }, + "camelcase": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-1.2.1.tgz", + "integrity": "sha1-m7UwTS4LVmmLLHWLCKPqqdqlijk=", + "dev": true + }, + "caniuse-lite": { + "version": "1.0.30000874", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30000874.tgz", + "integrity": "sha512-29nr1EPiHwrJTAHHsEmTt2h+55L8j2GNFdAcYPlRy2NX6iFz7ZZiepVI7kP/QqlnHLq3KvfWpbmGa0d063U09w==", + "dev": true + }, + "center-align": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/center-align/-/center-align-0.1.3.tgz", + "integrity": "sha1-qg0yYptu6XIgBBHL1EYckHvCt60=", + "dev": true, + "requires": { + "align-text": "^0.1.3", + "lazy-cache": "^1.0.3" + } + }, + "chalk": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.1.tgz", + "integrity": "sha512-ObN6h1v2fTJSmUXoS3nMQ92LbDK9be4TV+6G+omQlGJFdcUX5heKi1LZ1YnRMIgwTLEj3E24bT6tYni50rlCfQ==", + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, + "chokidar": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-1.7.0.tgz", + "integrity": "sha1-eY5ol3gVHIB2tLNg5e3SjNortGg=", + "dev": true, + "optional": true, + "requires": { + "anymatch": "^1.3.0", + "async-each": "^1.0.0", + "fsevents": "^1.0.0", + "glob-parent": "^2.0.0", + "inherits": "^2.0.1", + "is-binary-path": "^1.0.0", + "is-glob": "^2.0.0", + "path-is-absolute": "^1.0.0", + "readdirp": "^2.0.0" + } + }, + "circular-json": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/circular-json/-/circular-json-0.3.3.tgz", + "integrity": "sha512-UZK3NBx2Mca+b5LsG7bY183pHWt5Y1xts4P3Pz7ENTwGVnJOUWbRb3ocjvX7hx9tq/yTAdclXm9sZ38gNuem4A==", + "dev": true + }, + "cli-cursor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-1.0.2.tgz", + "integrity": "sha1-ZNo/fValRBLll5S9Ytw1KV6PKYc=", + "dev": true, + "requires": { + "restore-cursor": "^1.0.1" + } + }, + "cli-width": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-2.2.0.tgz", + "integrity": "sha1-/xnt6Kml5XkyQUewwR8PvLq+1jk=", + "dev": true + }, + "cliui": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-2.1.0.tgz", + "integrity": "sha1-S0dXYP+AJkx2LDoXGQMukcf+oNE=", + "dev": true, + "requires": { + "center-align": "^0.1.1", + "right-align": "^0.1.1", + "wordwrap": "0.0.2" + } + }, + "co": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", + "integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ=", + "dev": true + }, + "code-point-at": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", + "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=", + "dev": true + }, + "color-convert": { + "version": "1.9.2", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.2.tgz", + "integrity": "sha512-3NUJZdhMhcdPn8vJ9v2UQJoH0qqoGUkYTgFEPZaPjEtwmmKUfNV46zZmgB2M5M4DCEQHMaCfWHCxiBflLm04Tg==", + "requires": { + "color-name": "1.1.1" + } + }, + "color-name": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.1.tgz", + "integrity": "sha1-SxQVMEz1ACjqgWQ2Q72C6gWANok=" + }, + "commander": { + "version": "2.17.1", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.17.1.tgz", + "integrity": "sha512-wPMUt6FnH2yzG95SA6mzjQOEKUU3aLaDEmzs1ti+1E9h+CsrZghRlqEM/EJ4KscsQVG8uNN4uVreUeT8+drlgg==", + "dev": true + }, + "commoner": { + "version": "0.10.8", + "resolved": "https://registry.npmjs.org/commoner/-/commoner-0.10.8.tgz", + "integrity": "sha1-NPw2cs0kOT6LtH5wyqApOBH08sU=", + "dev": true, + "requires": { + "commander": "^2.5.0", + "detective": "^4.3.1", + "glob": "^5.0.15", + "graceful-fs": "^4.1.2", + "iconv-lite": "^0.4.5", + "mkdirp": "^0.5.0", + "private": "^0.1.6", + "q": "^1.1.2", + "recast": "^0.11.17" + }, + "dependencies": { + "esprima": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-3.1.3.tgz", + "integrity": "sha1-/cpRzuYTOJXjyI1TXOSdv/YqRjM=", + "dev": true + }, + "glob": { + "version": "5.0.15", + "resolved": "https://registry.npmjs.org/glob/-/glob-5.0.15.tgz", + "integrity": "sha1-G8k2ueAvSmA/zCIuz3Yz0wuLk7E=", + "dev": true, + "requires": { + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "2 || 3", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "recast": { + "version": "0.11.23", + "resolved": "https://registry.npmjs.org/recast/-/recast-0.11.23.tgz", + "integrity": "sha1-RR/TAEqx5N+bTktmN2sqIZEkYtM=", + "dev": true, + "requires": { + "ast-types": "0.9.6", + "esprima": "~3.1.0", + "private": "~0.1.5", + "source-map": "~0.5.0" + } + }, + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "dev": true + } + } + }, + "concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", + "dev": true + }, + "concat-stream": { + "version": "1.6.2", + "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz", + "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==", + "dev": true, + "requires": { + "buffer-from": "^1.0.0", + "inherits": "^2.0.3", + "readable-stream": "^2.2.2", + "typedarray": "^0.0.6" + } + }, + "convert-source-map": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.5.1.tgz", + "integrity": "sha1-uCeAl7m8IpNl3lxiz1/K7YtVmeU=", + "dev": true + }, + "core-js": { + "version": "2.5.7", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.5.7.tgz", + "integrity": "sha512-RszJCAxg/PP6uzXVXL6BsxSXx/B05oJAQ2vkJRjyjrEcNVycaqOmNb5OTxZPE3xa5gwZduqza6L9JOCenh/Ecw==", + "dev": true + }, + "core-util-is": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", + "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=", + "dev": true + }, + "d": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/d/-/d-1.0.0.tgz", + "integrity": "sha1-dUu1v+VUUdpppYuU1F9MWwRi1Y8=", + "dev": true, + "requires": { + "es5-ext": "^0.10.9" + } + }, + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "decamelize": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", + "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=", + "dev": true + }, + "deep-equal": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/deep-equal/-/deep-equal-1.0.1.tgz", + "integrity": "sha1-9dJgKStmDghO/0zbyfCK0yR0SLU=", + "dev": true + }, + "deep-is": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz", + "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=", + "dev": true + }, + "define-properties": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.2.tgz", + "integrity": "sha1-g6c/L+pWmJj7c3GTyPhzyvbUXJQ=", + "dev": true, + "requires": { + "foreach": "^2.0.5", + "object-keys": "^1.0.8" + } + }, + "defined": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/defined/-/defined-1.0.0.tgz", + "integrity": "sha1-yY2bzvdWdBiOEQlpFRGZ45sfppM=", + "dev": true + }, + "defs": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/defs/-/defs-1.1.1.tgz", + "integrity": "sha1-siYJ8sehG6ej2xFoBcE5scr/qdI=", + "dev": true, + "requires": { + "alter": "~0.2.0", + "ast-traverse": "~0.1.1", + "breakable": "~1.0.0", + "esprima-fb": "~15001.1001.0-dev-harmony-fb", + "simple-fmt": "~0.1.0", + "simple-is": "~0.2.0", + "stringmap": "~0.2.2", + "stringset": "~0.2.1", + "tryor": "~0.1.2", + "yargs": "~3.27.0" + } + }, + "del": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/del/-/del-2.2.2.tgz", + "integrity": "sha1-wSyYHQZ4RshLyvhiz/kw2Qf/0ag=", + "dev": true, + "requires": { + "globby": "^5.0.0", + "is-path-cwd": "^1.0.0", + "is-path-in-cwd": "^1.0.0", + "object-assign": "^4.0.1", + "pify": "^2.0.0", + "pinkie-promise": "^2.0.0", + "rimraf": "^2.2.8" + } + }, + "detect-indent": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/detect-indent/-/detect-indent-4.0.0.tgz", + "integrity": "sha1-920GQ1LN9Docts5hnE7jqUdd4gg=", + "dev": true, + "requires": { + "repeating": "^2.0.0" + } + }, + "detective": { + "version": "4.7.1", + "resolved": "https://registry.npmjs.org/detective/-/detective-4.7.1.tgz", + "integrity": "sha512-H6PmeeUcZloWtdt4DAkFyzFL94arpHr3NOwwmVILFiy+9Qd4JTxxXrzfyGk/lmct2qVGBwTSwSXagqu2BxmWig==", + "dev": true, + "requires": { + "acorn": "^5.2.1", + "defined": "^1.0.0" + } + }, + "doctrine": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", + "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", + "dev": true, + "requires": { + "esutils": "^2.0.2" + } + }, + "electron-to-chromium": { + "version": "1.3.57", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.57.tgz", + "integrity": "sha512-YYpZlr6mzR8cK5VRmTZydEt5Mp+WMg1/syrO40PoQzl76vJ+oQchL2d3FmEcWzw3FYqJVYJP/kYYSzTa7FLXwg==", + "dev": true + }, + "es-abstract": { + "version": "1.12.0", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.12.0.tgz", + "integrity": "sha512-C8Fx/0jFmV5IPoMOFPA9P9G5NtqW+4cOPit3MIuvR2t7Ag2K15EJTpxnHAYTzL+aYQJIESYeXZmDBfOBE1HcpA==", + "dev": true, + "requires": { + "es-to-primitive": "^1.1.1", + "function-bind": "^1.1.1", + "has": "^1.0.1", + "is-callable": "^1.1.3", + "is-regex": "^1.0.4" + } + }, + "es-to-primitive": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.1.1.tgz", + "integrity": "sha1-RTVSSKiJeQNLZ5Lhm7gfK3l13Q0=", + "dev": true, + "requires": { + "is-callable": "^1.1.1", + "is-date-object": "^1.0.1", + "is-symbol": "^1.0.1" + } + }, + "es5-ext": { + "version": "0.10.45", + "resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.45.tgz", + "integrity": "sha512-FkfM6Vxxfmztilbxxz5UKSD4ICMf5tSpRFtDNtkAhOxZ0EKtX6qwmXNyH/sFyIbX2P/nU5AMiA9jilWsUGJzCQ==", + "dev": true, + "requires": { + "es6-iterator": "~2.0.3", + "es6-symbol": "~3.1.1", + "next-tick": "1" + } + }, + "es6-iterator": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/es6-iterator/-/es6-iterator-2.0.3.tgz", + "integrity": "sha1-p96IkUGgWpSwhUQDstCg+/qY87c=", + "dev": true, + "requires": { + "d": "1", + "es5-ext": "^0.10.35", + "es6-symbol": "^3.1.1" + } + }, + "es6-map": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/es6-map/-/es6-map-0.1.5.tgz", + "integrity": "sha1-kTbgUD3MBqMBaQ8LsU/042TpSfA=", + "dev": true, + "requires": { + "d": "1", + "es5-ext": "~0.10.14", + "es6-iterator": "~2.0.1", + "es6-set": "~0.1.5", + "es6-symbol": "~3.1.1", + "event-emitter": "~0.3.5" + } + }, + "es6-set": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/es6-set/-/es6-set-0.1.5.tgz", + "integrity": "sha1-0rPsXU2ADO2BjbU40ol02wpzzLE=", + "dev": true, + "requires": { + "d": "1", + "es5-ext": "~0.10.14", + "es6-iterator": "~2.0.1", + "es6-symbol": "3.1.1", + "event-emitter": "~0.3.5" + } + }, + "es6-symbol": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/es6-symbol/-/es6-symbol-3.1.1.tgz", + "integrity": "sha1-vwDvT9q2uhtG7Le2KbTH7VcVzHc=", + "dev": true, + "requires": { + "d": "1", + "es5-ext": "~0.10.14" + } + }, + "es6-weak-map": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/es6-weak-map/-/es6-weak-map-2.0.2.tgz", + "integrity": "sha1-XjqzIlH/0VOKH45f+hNXdy+S2W8=", + "dev": true, + "requires": { + "d": "1", + "es5-ext": "^0.10.14", + "es6-iterator": "^2.0.1", + "es6-symbol": "^3.1.1" + } + }, + "escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=" + }, + "escope": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/escope/-/escope-3.6.0.tgz", + "integrity": "sha1-4Bl16BJ4GhY6ba392AOY3GTIicM=", + "dev": true, + "requires": { + "es6-map": "^0.1.3", + "es6-weak-map": "^2.0.1", + "esrecurse": "^4.1.0", + "estraverse": "^4.1.1" + } + }, + "eslint": { + "version": "3.19.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-3.19.0.tgz", + "integrity": "sha1-yPxiAcf0DdCJQbh8CFdnOGpnmsw=", + "dev": true, + "requires": { + "babel-code-frame": "^6.16.0", + "chalk": "^1.1.3", + "concat-stream": "^1.5.2", + "debug": "^2.1.1", + "doctrine": "^2.0.0", + "escope": "^3.6.0", + "espree": "^3.4.0", + "esquery": "^1.0.0", + "estraverse": "^4.2.0", + "esutils": "^2.0.2", + "file-entry-cache": "^2.0.0", + "glob": "^7.0.3", + "globals": "^9.14.0", + "ignore": "^3.2.0", + "imurmurhash": "^0.1.4", + "inquirer": "^0.12.0", + "is-my-json-valid": "^2.10.0", + "is-resolvable": "^1.0.0", + "js-yaml": "^3.5.1", + "json-stable-stringify": "^1.0.0", + "levn": "^0.3.0", + "lodash": "^4.0.0", + "mkdirp": "^0.5.0", + "natural-compare": "^1.4.0", + "optionator": "^0.8.2", + "path-is-inside": "^1.0.1", + "pluralize": "^1.2.1", + "progress": "^1.1.8", + "require-uncached": "^1.0.2", + "shelljs": "^0.7.5", + "strip-bom": "^3.0.0", + "strip-json-comments": "~2.0.1", + "table": "^3.7.8", + "text-table": "~0.2.0", + "user-home": "^2.0.0" + }, + "dependencies": { + "ansi-styles": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", + "dev": true + }, + "chalk": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", + "dev": true, + "requires": { + "ansi-styles": "^2.2.1", + "escape-string-regexp": "^1.0.2", + "has-ansi": "^2.0.0", + "strip-ansi": "^3.0.0", + "supports-color": "^2.0.0" + } + }, + "supports-color": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", + "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", + "dev": true + }, + "user-home": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/user-home/-/user-home-2.0.0.tgz", + "integrity": "sha1-nHC/2Babwdy/SGBODwS4tJzenp8=", + "dev": true, + "requires": { + "os-homedir": "^1.0.0" + } + } + } + }, + "espree": { + "version": "3.5.4", + "resolved": "https://registry.npmjs.org/espree/-/espree-3.5.4.tgz", + "integrity": "sha512-yAcIQxtmMiB/jL32dzEp2enBeidsB7xWPLNiw3IIkpVds1P+h7qF9YwJq1yUNzp2OKXgAprs4F61ih66UsoD1A==", + "dev": true, + "requires": { + "acorn": "^5.5.0", + "acorn-jsx": "^3.0.0" + } + }, + "esprima-fb": { + "version": "15001.1001.0-dev-harmony-fb", + "resolved": "https://registry.npmjs.org/esprima-fb/-/esprima-fb-15001.1001.0-dev-harmony-fb.tgz", + "integrity": "sha1-Q761fsJujPI3092LM+QlM1d/Jlk=", + "dev": true + }, + "esquery": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.0.1.tgz", + "integrity": "sha512-SmiyZ5zIWH9VM+SRUReLS5Q8a7GxtRdxEBVZpm98rJM7Sb+A9DVCndXfkeFUd3byderg+EbDkfnevfCwynWaNA==", + "dev": true, + "requires": { + "estraverse": "^4.0.0" + } + }, + "esrecurse": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.2.1.tgz", + "integrity": "sha512-64RBB++fIOAXPw3P9cy89qfMlvZEXZkqqJkjqqXIvzP5ezRZjW+lPWjw35UX/3EhUPFYbg5ER4JYgDw4007/DQ==", + "dev": true, + "requires": { + "estraverse": "^4.1.0" + } + }, + "estraverse": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.2.0.tgz", + "integrity": "sha1-De4/7TH81GlhjOc0IJn8GvoL2xM=", + "dev": true + }, + "esutils": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.2.tgz", + "integrity": "sha1-Cr9PHKpbyx96nYrMbepPqqBLrJs=", + "dev": true + }, + "event-emitter": { + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/event-emitter/-/event-emitter-0.3.5.tgz", + "integrity": "sha1-34xp7vFkeSPHFXuc6DhAYQsCzDk=", + "dev": true, + "requires": { + "d": "1", + "es5-ext": "~0.10.14" + } + }, + "exit-hook": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/exit-hook/-/exit-hook-1.1.1.tgz", + "integrity": "sha1-8FyiM7SMBdVP/wd2XfhQfpXAL/g=", + "dev": true + }, + "expand-brackets": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-0.1.5.tgz", + "integrity": "sha1-3wcoTjQqgHzXM6xa9yQR5YHRF3s=", + "dev": true, + "optional": true, + "requires": { + "is-posix-bracket": "^0.1.0" + } + }, + "expand-range": { + "version": "1.8.2", + "resolved": "https://registry.npmjs.org/expand-range/-/expand-range-1.8.2.tgz", + "integrity": "sha1-opnv/TNf4nIeuujiV+x5ZE/IUzc=", + "dev": true, + "optional": true, + "requires": { + "fill-range": "^2.1.0" + } + }, + "extglob": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/extglob/-/extglob-0.3.2.tgz", + "integrity": "sha1-Lhj/PS9JqydlzskCPwEdqo2DSaE=", + "dev": true, + "optional": true, + "requires": { + "is-extglob": "^1.0.0" + } + }, + "fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", + "dev": true + }, + "figures": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/figures/-/figures-1.7.0.tgz", + "integrity": "sha1-y+Hjr/zxzUS4DK3+0o3Hk6lwHS4=", + "dev": true, + "requires": { + "escape-string-regexp": "^1.0.5", + "object-assign": "^4.1.0" + } + }, + "file-entry-cache": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-2.0.0.tgz", + "integrity": "sha1-w5KZDD5oR4PYOLjISkXYoEhFg2E=", + "dev": true, + "requires": { + "flat-cache": "^1.2.1", + "object-assign": "^4.0.1" + } + }, + "filename-regex": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/filename-regex/-/filename-regex-2.0.1.tgz", + "integrity": "sha1-wcS5vuPglyXdsQa3XB4wH+LxiyY=", + "dev": true, + "optional": true + }, + "fill-range": { + "version": "2.2.4", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-2.2.4.tgz", + "integrity": "sha512-cnrcCbj01+j2gTG921VZPnHbjmdAf8oQV/iGeV2kZxGSyfYjjTyY79ErsK1WJWMpw6DaApEX72binqJE+/d+5Q==", + "dev": true, + "optional": true, + "requires": { + "is-number": "^2.1.0", + "isobject": "^2.0.0", + "randomatic": "^3.0.0", + "repeat-element": "^1.1.2", + "repeat-string": "^1.5.2" + } + }, + "flat-cache": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-1.3.0.tgz", + "integrity": "sha1-0wMLMrOBVPTjt+nHCfSQ9++XxIE=", + "dev": true, + "requires": { + "circular-json": "^0.3.1", + "del": "^2.0.2", + "graceful-fs": "^4.1.2", + "write": "^0.2.1" + } + }, + "for-each": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz", + "integrity": "sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==", + "dev": true, + "requires": { + "is-callable": "^1.1.3" + } + }, + "for-in": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz", + "integrity": "sha1-gQaNKVqBQuwKxybG4iAMMPttXoA=", + "dev": true, + "optional": true + }, + "for-own": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/for-own/-/for-own-0.1.5.tgz", + "integrity": "sha1-UmXGgaTylNq78XyVCbZ2OqhFEM4=", + "dev": true, + "optional": true, + "requires": { + "for-in": "^1.0.1" + } + }, + "foreach": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/foreach/-/foreach-2.0.5.tgz", + "integrity": "sha1-C+4AUBiusmDQo6865ljdATbsG5k=", + "dev": true + }, + "fs-readdir-recursive": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/fs-readdir-recursive/-/fs-readdir-recursive-1.1.0.tgz", + "integrity": "sha512-GNanXlVr2pf02+sPN40XN8HG+ePaNcvM0q5mZBd668Obwb0yD5GiUbZOFgwn8kGMY6I3mdyDJzieUy3PTYyTRA==", + "dev": true + }, + "fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", + "dev": true + }, + "fsevents": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.4.tgz", + "integrity": "sha512-z8H8/diyk76B7q5wg+Ud0+CqzcAF3mBBI/bA5ne5zrRUUIvNkJY//D3BqyH571KuAC4Nr7Rw7CjWX4r0y9DvNg==", + "dev": true, + "optional": true, + "requires": { + "nan": "^2.9.2", + "node-pre-gyp": "^0.10.0" + }, + "dependencies": { + "abbrev": { + "version": "1.1.1", + "bundled": true, + "dev": true, + "optional": true + }, + "ansi-regex": { + "version": "2.1.1", + "bundled": true, + "dev": true + }, + "aproba": { + "version": "1.2.0", + "bundled": true, + "dev": true, + "optional": true + }, + "are-we-there-yet": { + "version": "1.1.4", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "delegates": "^1.0.0", + "readable-stream": "^2.0.6" + } + }, + "balanced-match": { + "version": "1.0.0", + "bundled": true, + "dev": true + }, + "brace-expansion": { + "version": "1.1.11", + "bundled": true, + "dev": true, + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "chownr": { + "version": "1.0.1", + "bundled": true, + "dev": true, + "optional": true + }, + "code-point-at": { + "version": "1.1.0", + "bundled": true, + "dev": true + }, + "concat-map": { + "version": "0.0.1", + "bundled": true, + "dev": true + }, + "console-control-strings": { + "version": "1.1.0", + "bundled": true, + "dev": true + }, + "core-util-is": { + "version": "1.0.2", + "bundled": true, + "dev": true, + "optional": true + }, + "debug": { + "version": "2.6.9", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "ms": "2.0.0" + } + }, + "deep-extend": { + "version": "0.5.1", + "bundled": true, + "dev": true, + "optional": true + }, + "delegates": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "optional": true + }, + "detect-libc": { + "version": "1.0.3", + "bundled": true, + "dev": true, + "optional": true + }, + "fs-minipass": { + "version": "1.2.5", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "minipass": "^2.2.1" + } + }, + "fs.realpath": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "optional": true + }, + "gauge": { + "version": "2.7.4", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "aproba": "^1.0.3", + "console-control-strings": "^1.0.0", + "has-unicode": "^2.0.0", + "object-assign": "^4.1.0", + "signal-exit": "^3.0.0", + "string-width": "^1.0.1", + "strip-ansi": "^3.0.1", + "wide-align": "^1.1.0" + } + }, + "glob": { + "version": "7.1.2", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "has-unicode": { + "version": "2.0.1", + "bundled": true, + "dev": true, + "optional": true + }, + "iconv-lite": { + "version": "0.4.21", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "safer-buffer": "^2.1.0" + } + }, + "ignore-walk": { + "version": "3.0.1", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "minimatch": "^3.0.4" + } + }, + "inflight": { + "version": "1.0.6", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "inherits": { + "version": "2.0.3", + "bundled": true, + "dev": true + }, + "ini": { + "version": "1.3.5", + "bundled": true, + "dev": true, + "optional": true + }, + "is-fullwidth-code-point": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "requires": { + "number-is-nan": "^1.0.0" + } + }, + "isarray": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "optional": true + }, + "minimatch": { + "version": "3.0.4", + "bundled": true, + "dev": true, + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "minimist": { + "version": "0.0.8", + "bundled": true, + "dev": true + }, + "minipass": { + "version": "2.2.4", + "bundled": true, + "dev": true, + "requires": { + "safe-buffer": "^5.1.1", + "yallist": "^3.0.0" + } + }, + "minizlib": { + "version": "1.1.0", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "minipass": "^2.2.1" + } + }, + "mkdirp": { + "version": "0.5.1", + "bundled": true, + "dev": true, + "requires": { + "minimist": "0.0.8" + } + }, + "ms": { + "version": "2.0.0", + "bundled": true, + "dev": true, + "optional": true + }, + "needle": { + "version": "2.2.0", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "debug": "^2.1.2", + "iconv-lite": "^0.4.4", + "sax": "^1.2.4" + } + }, + "node-pre-gyp": { + "version": "0.10.0", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "detect-libc": "^1.0.2", + "mkdirp": "^0.5.1", + "needle": "^2.2.0", + "nopt": "^4.0.1", + "npm-packlist": "^1.1.6", + "npmlog": "^4.0.2", + "rc": "^1.1.7", + "rimraf": "^2.6.1", + "semver": "^5.3.0", + "tar": "^4" + } + }, + "nopt": { + "version": "4.0.1", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "abbrev": "1", + "osenv": "^0.1.4" + } + }, + "npm-bundled": { + "version": "1.0.3", + "bundled": true, + "dev": true, + "optional": true + }, + "npm-packlist": { + "version": "1.1.10", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "ignore-walk": "^3.0.1", + "npm-bundled": "^1.0.1" + } + }, + "npmlog": { + "version": "4.1.2", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "are-we-there-yet": "~1.1.2", + "console-control-strings": "~1.1.0", + "gauge": "~2.7.3", + "set-blocking": "~2.0.0" + } + }, + "number-is-nan": { + "version": "1.0.1", + "bundled": true, + "dev": true + }, + "object-assign": { + "version": "4.1.1", + "bundled": true, + "dev": true, + "optional": true + }, + "once": { + "version": "1.4.0", + "bundled": true, + "dev": true, + "requires": { + "wrappy": "1" + } + }, + "os-homedir": { + "version": "1.0.2", + "bundled": true, + "dev": true, + "optional": true + }, + "os-tmpdir": { + "version": "1.0.2", + "bundled": true, + "dev": true, + "optional": true + }, + "osenv": { + "version": "0.1.5", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "os-homedir": "^1.0.0", + "os-tmpdir": "^1.0.0" + } + }, + "path-is-absolute": { + "version": "1.0.1", + "bundled": true, + "dev": true, + "optional": true + }, + "process-nextick-args": { + "version": "2.0.0", + "bundled": true, + "dev": true, + "optional": true + }, + "rc": { + "version": "1.2.7", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "deep-extend": "^0.5.1", + "ini": "~1.3.0", + "minimist": "^1.2.0", + "strip-json-comments": "~2.0.1" + }, + "dependencies": { + "minimist": { + "version": "1.2.0", + "bundled": true, + "dev": true, + "optional": true + } + } + }, + "readable-stream": { + "version": "2.3.6", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "rimraf": { + "version": "2.6.2", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "glob": "^7.0.5" + } + }, + "safe-buffer": { + "version": "5.1.1", + "bundled": true, + "dev": true + }, + "safer-buffer": { + "version": "2.1.2", + "bundled": true, + "dev": true, + "optional": true + }, + "sax": { + "version": "1.2.4", + "bundled": true, + "dev": true, + "optional": true + }, + "semver": { + "version": "5.5.0", + "bundled": true, + "dev": true, + "optional": true + }, + "set-blocking": { + "version": "2.0.0", + "bundled": true, + "dev": true, + "optional": true + }, + "signal-exit": { + "version": "3.0.2", + "bundled": true, + "dev": true, + "optional": true + }, + "string-width": { + "version": "1.0.2", + "bundled": true, + "dev": true, + "requires": { + "code-point-at": "^1.0.0", + "is-fullwidth-code-point": "^1.0.0", + "strip-ansi": "^3.0.0" + } + }, + "string_decoder": { + "version": "1.1.1", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "safe-buffer": "~5.1.0" + } + }, + "strip-ansi": { + "version": "3.0.1", + "bundled": true, + "dev": true, + "requires": { + "ansi-regex": "^2.0.0" + } + }, + "strip-json-comments": { + "version": "2.0.1", + "bundled": true, + "dev": true, + "optional": true + }, + "tar": { + "version": "4.4.1", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "chownr": "^1.0.1", + "fs-minipass": "^1.2.5", + "minipass": "^2.2.4", + "minizlib": "^1.1.0", + "mkdirp": "^0.5.0", + "safe-buffer": "^5.1.1", + "yallist": "^3.0.2" + } + }, + "util-deprecate": { + "version": "1.0.2", + "bundled": true, + "dev": true, + "optional": true + }, + "wide-align": { + "version": "1.1.2", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "string-width": "^1.0.2" + } + }, + "wrappy": { + "version": "1.0.2", + "bundled": true, + "dev": true + }, + "yallist": { + "version": "3.0.2", + "bundled": true, + "dev": true + } + } + }, + "function-bind": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", + "dev": true + }, + "generate-function": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/generate-function/-/generate-function-2.0.0.tgz", + "integrity": "sha1-aFj+fAlpt9TpCTM3ZHrHn2DfvnQ=", + "dev": true + }, + "generate-object-property": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/generate-object-property/-/generate-object-property-1.2.0.tgz", + "integrity": "sha1-nA4cQDCM6AT0eDYYuTf6iPmdUNA=", + "dev": true, + "requires": { + "is-property": "^1.0.0" + } + }, + "get-stdin": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-4.0.1.tgz", + "integrity": "sha1-uWjGsKBDhDJJAui/Gl3zJXmkUP4=", + "dev": true + }, + "glob": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz", + "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==", + "dev": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "glob-base": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/glob-base/-/glob-base-0.3.0.tgz", + "integrity": "sha1-27Fk9iIbHAscz4Kuoyi0l98Oo8Q=", + "dev": true, + "optional": true, + "requires": { + "glob-parent": "^2.0.0", + "is-glob": "^2.0.0" + } + }, + "glob-parent": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-2.0.0.tgz", + "integrity": "sha1-gTg9ctsFT8zPUzbaqQLxgvbtuyg=", + "dev": true, + "requires": { + "is-glob": "^2.0.0" + } + }, + "globals": { + "version": "9.18.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-9.18.0.tgz", + "integrity": "sha512-S0nG3CLEQiY/ILxqtztTWH/3iRRdyBLw6KMDxnKMchrtbj2OFmehVh0WUCfW3DUrIgx/qFrJPICrq4Z4sTR9UQ==", + "dev": true + }, + "globby": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-5.0.0.tgz", + "integrity": "sha1-69hGZ8oNuzMLmbz8aOrCvFQ3Dg0=", + "dev": true, + "requires": { + "array-union": "^1.0.1", + "arrify": "^1.0.0", + "glob": "^7.0.3", + "object-assign": "^4.0.1", + "pify": "^2.0.0", + "pinkie-promise": "^2.0.0" + } + }, + "graceful-fs": { + "version": "4.1.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.11.tgz", + "integrity": "sha1-Dovf5NHduIVNZOBOp8AOKgJuVlg=", + "dev": true + }, + "has": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", + "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "dev": true, + "requires": { + "function-bind": "^1.1.1" + } + }, + "has-ansi": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", + "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=", + "dev": true, + "requires": { + "ansi-regex": "^2.0.0" + } + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=" + }, + "home-or-tmp": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/home-or-tmp/-/home-or-tmp-2.0.0.tgz", + "integrity": "sha1-42w/LSyufXRqhX440Y1fMqeILbg=", + "dev": true, + "requires": { + "os-homedir": "^1.0.0", + "os-tmpdir": "^1.0.1" + } + }, + "iconv-lite": { + "version": "0.4.23", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.23.tgz", + "integrity": "sha512-neyTUVFtahjf0mB3dZT77u+8O0QB89jFdnBkd5P1JgYPbPaia3gXXOVL2fq8VyU2gMMD7SaN7QukTB/pmXYvDA==", + "dev": true, + "requires": { + "safer-buffer": ">= 2.1.2 < 3" + } + }, + "ignore": { + "version": "3.3.10", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-3.3.10.tgz", + "integrity": "sha512-Pgs951kaMm5GXP7MOvxERINe3gsaVjUWFm+UZPSq9xYriQAksyhg0csnS0KXSNRD5NmNdapXEpjxG49+AKh/ug==", + "dev": true + }, + "imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", + "dev": true + }, + "inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "dev": true, + "requires": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "inherits": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", + "dev": true + }, + "inquirer": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-0.12.0.tgz", + "integrity": "sha1-HvK/1jUE3wvHV4X/+MLEHfEvB34=", + "dev": true, + "requires": { + "ansi-escapes": "^1.1.0", + "ansi-regex": "^2.0.0", + "chalk": "^1.0.0", + "cli-cursor": "^1.0.1", + "cli-width": "^2.0.0", + "figures": "^1.3.5", + "lodash": "^4.3.0", + "readline2": "^1.0.1", + "run-async": "^0.1.0", + "rx-lite": "^3.1.2", + "string-width": "^1.0.1", + "strip-ansi": "^3.0.0", + "through": "^2.3.6" + }, + "dependencies": { + "ansi-styles": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", + "dev": true + }, + "chalk": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", + "dev": true, + "requires": { + "ansi-styles": "^2.2.1", + "escape-string-regexp": "^1.0.2", + "has-ansi": "^2.0.0", + "strip-ansi": "^3.0.0", + "supports-color": "^2.0.0" + } + }, + "supports-color": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", + "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", + "dev": true + } + } + }, + "interpret": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.1.0.tgz", + "integrity": "sha1-ftGxQQxqDg94z5XTuEQMY/eLhhQ=", + "dev": true + }, + "invariant": { + "version": "2.2.4", + "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz", + "integrity": "sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==", + "dev": true, + "requires": { + "loose-envify": "^1.0.0" + } + }, + "invert-kv": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/invert-kv/-/invert-kv-1.0.0.tgz", + "integrity": "sha1-EEqOSqym09jNFXqO+L+rLXo//bY=", + "dev": true + }, + "is-binary-path": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-1.0.1.tgz", + "integrity": "sha1-dfFmQrSA8YenEcgUFh/TpKdlWJg=", + "dev": true, + "optional": true, + "requires": { + "binary-extensions": "^1.0.0" + } + }, + "is-buffer": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", + "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==", + "dev": true + }, + "is-callable": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.1.4.tgz", + "integrity": "sha512-r5p9sxJjYnArLjObpjA4xu5EKI3CuKHkJXMhT7kwbpUyIFD1n5PMAsoPvWnvtZiNz7LjkYDRZhd7FlI0eMijEA==", + "dev": true + }, + "is-date-object": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.1.tgz", + "integrity": "sha1-mqIOtq7rv/d/vTPnTKAbM1gdOhY=", + "dev": true + }, + "is-dotfile": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/is-dotfile/-/is-dotfile-1.0.3.tgz", + "integrity": "sha1-pqLzL/0t+wT1yiXs0Pa4PPeYoeE=", + "dev": true, + "optional": true + }, + "is-equal-shallow": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/is-equal-shallow/-/is-equal-shallow-0.1.3.tgz", + "integrity": "sha1-IjgJj8Ih3gvPpdnqxMRdY4qhxTQ=", + "dev": true, + "optional": true, + "requires": { + "is-primitive": "^2.0.0" + } + }, + "is-extendable": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", + "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=", + "dev": true, + "optional": true + }, + "is-extglob": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-1.0.0.tgz", + "integrity": "sha1-rEaBd8SUNAWgkvyPKXYMb/xiBsA=", + "dev": true + }, + "is-finite": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-finite/-/is-finite-1.0.2.tgz", + "integrity": "sha1-zGZ3aVYCvlUO8R6LSqYwU0K20Ko=", + "dev": true, + "requires": { + "number-is-nan": "^1.0.0" + } + }, + "is-fullwidth-code-point": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", + "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", + "dev": true, + "requires": { + "number-is-nan": "^1.0.0" + } + }, + "is-glob": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-2.0.1.tgz", + "integrity": "sha1-0Jb5JqPe1WAPP9/ZEZjLCIjC2GM=", + "dev": true, + "requires": { + "is-extglob": "^1.0.0" + } + }, + "is-integer": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/is-integer/-/is-integer-1.0.7.tgz", + "integrity": "sha1-a96Bqs3feLZZtmKdYpytxRqIbVw=", + "dev": true, + "requires": { + "is-finite": "^1.0.0" + } + }, + "is-my-ip-valid": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-my-ip-valid/-/is-my-ip-valid-1.0.0.tgz", + "integrity": "sha512-gmh/eWXROncUzRnIa1Ubrt5b8ep/MGSnfAUI3aRp+sqTCs1tv1Isl8d8F6JmkN3dXKc3ehZMrtiPN9eL03NuaQ==", + "dev": true + }, + "is-my-json-valid": { + "version": "2.18.0", + "resolved": "https://registry.npmjs.org/is-my-json-valid/-/is-my-json-valid-2.18.0.tgz", + "integrity": "sha512-DWT87JHCSdCPCxbqBpS6Z2ajAt+MvrJq8I4xrpQljCvzODO5/fiquBp20a3sN6yCJvFbCRyYvJOHjpzkPTKJyA==", + "dev": true, + "requires": { + "generate-function": "^2.0.0", + "generate-object-property": "^1.1.0", + "is-my-ip-valid": "^1.0.0", + "jsonpointer": "^4.0.0", + "xtend": "^4.0.0" + } + }, + "is-number": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-2.1.0.tgz", + "integrity": "sha1-Afy7s5NGOlSPL0ZszhbezknbkI8=", + "dev": true, + "optional": true, + "requires": { + "kind-of": "^3.0.2" + } + }, + "is-path-cwd": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-path-cwd/-/is-path-cwd-1.0.0.tgz", + "integrity": "sha1-0iXsIxMuie3Tj9p2dHLmLmXxEG0=", + "dev": true + }, + "is-path-in-cwd": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-path-in-cwd/-/is-path-in-cwd-1.0.1.tgz", + "integrity": "sha512-FjV1RTW48E7CWM7eE/J2NJvAEEVektecDBVBE5Hh3nM1Jd0kvhHtX68Pr3xsDf857xt3Y4AkwVULK1Vku62aaQ==", + "dev": true, + "requires": { + "is-path-inside": "^1.0.0" + } + }, + "is-path-inside": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-1.0.1.tgz", + "integrity": "sha1-jvW33lBDej/cprToZe96pVy0gDY=", + "dev": true, + "requires": { + "path-is-inside": "^1.0.1" + } + }, + "is-posix-bracket": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/is-posix-bracket/-/is-posix-bracket-0.1.1.tgz", + "integrity": "sha1-MzTceXdDaOkvAW5vvAqI9c1ua8Q=", + "dev": true, + "optional": true + }, + "is-primitive": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-primitive/-/is-primitive-2.0.0.tgz", + "integrity": "sha1-IHurkWOEmcB7Kt8kCkGochADRXU=", + "dev": true, + "optional": true + }, + "is-property": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-property/-/is-property-1.0.2.tgz", + "integrity": "sha1-V/4cTkhHTt1lsJkR8msc1Ald2oQ=", + "dev": true + }, + "is-regex": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.0.4.tgz", + "integrity": "sha1-VRdIm1RwkbCTDglWVM7SXul+lJE=", + "dev": true, + "requires": { + "has": "^1.0.1" + } + }, + "is-resolvable": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-resolvable/-/is-resolvable-1.1.0.tgz", + "integrity": "sha512-qgDYXFSR5WvEfuS5dMj6oTMEbrrSaM0CrFk2Yiq/gXnBvD9pMa2jGXxyhGLfvhZpuMZe18CJpFxAt3CRs42NMg==", + "dev": true + }, + "is-symbol": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.1.tgz", + "integrity": "sha1-PMWfAAJRlLarLjjbrmaJJWtmBXI=", + "dev": true + }, + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", + "dev": true + }, + "isobject": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", + "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=", + "dev": true, + "optional": true, + "requires": { + "isarray": "1.0.0" + } + }, + "js-tokens": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-3.0.2.tgz", + "integrity": "sha1-mGbfOVECEw449/mWvOtlRDIJwls=", + "dev": true + }, + "js-yaml": { + "version": "3.12.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.12.0.tgz", + "integrity": "sha512-PIt2cnwmPfL4hKNwqeiuz4bKfnzHTBv6HyVgjahA6mPLwPDzjDWrplJBMjHUFxku/N3FlmrbyPclad+I+4mJ3A==", + "dev": true, + "requires": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + }, + "dependencies": { + "esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "dev": true + } + } + }, + "jsesc": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-1.3.0.tgz", + "integrity": "sha1-RsP+yMGJKxKwgz25vHYiF226s0s=", + "dev": true + }, + "json-stable-stringify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify/-/json-stable-stringify-1.0.1.tgz", + "integrity": "sha1-mnWdOcXy/1A/1TAGRu1EX4jE+a8=", + "dev": true, + "requires": { + "jsonify": "~0.0.0" + } + }, + "json5": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/json5/-/json5-0.5.1.tgz", + "integrity": "sha1-Hq3nrMASA0rYTiOWdn6tn6VJWCE=", + "dev": true + }, + "jsonify": { + "version": "0.0.0", + "resolved": "https://registry.npmjs.org/jsonify/-/jsonify-0.0.0.tgz", + "integrity": "sha1-LHS27kHZPKUbe1qu6PUDYx0lKnM=", + "dev": true + }, + "jsonpointer": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/jsonpointer/-/jsonpointer-4.0.1.tgz", + "integrity": "sha1-T9kss04OnbPInIYi7PUfm5eMbLk=", + "dev": true + }, + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + }, + "lazy-cache": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/lazy-cache/-/lazy-cache-1.0.4.tgz", + "integrity": "sha1-odePw6UEdMuAhF07O24dpJpEbo4=", + "dev": true + }, + "lcid": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/lcid/-/lcid-1.0.0.tgz", + "integrity": "sha1-MIrMr6C8SDo4Z7S28rlQYlHRuDU=", + "dev": true, + "requires": { + "invert-kv": "^1.0.0" + } + }, + "leven": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/leven/-/leven-1.0.2.tgz", + "integrity": "sha1-kUS27ryl8dBoAWnxpncNzqYLdcM=", + "dev": true + }, + "levn": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", + "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=", + "dev": true, + "requires": { + "prelude-ls": "~1.1.2", + "type-check": "~0.3.2" + } + }, + "lodash": { + "version": "4.17.10", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.10.tgz", + "integrity": "sha512-UejweD1pDoXu+AD825lWwp4ZGtSwgnpZxb3JDViD7StjQz+Nb/6l093lx4OQ0foGWNRoc19mWy7BzL+UAK2iVg==", + "dev": true + }, + "longest": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/longest/-/longest-1.0.1.tgz", + "integrity": "sha1-MKCy2jj3N3DoKUoNIuZiXtd9AJc=", + "dev": true + }, + "loose-envify": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", + "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", + "dev": true, + "requires": { + "js-tokens": "^3.0.0 || ^4.0.0" + } + }, + "math-random": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/math-random/-/math-random-1.0.1.tgz", + "integrity": "sha1-izqsWIuKZuSXXjzepn97sylgH6w=", + "dev": true, + "optional": true + }, + "micromatch": { + "version": "2.3.11", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-2.3.11.tgz", + "integrity": "sha1-hmd8l9FyCzY0MdBNDRUpO9OMFWU=", + "dev": true, + "optional": true, + "requires": { + "arr-diff": "^2.0.0", + "array-unique": "^0.2.1", + "braces": "^1.8.2", + "expand-brackets": "^0.1.4", + "extglob": "^0.3.1", + "filename-regex": "^2.0.0", + "is-extglob": "^1.0.0", + "is-glob": "^2.0.1", + "kind-of": "^3.0.2", + "normalize-path": "^2.0.1", + "object.omit": "^2.0.0", + "parse-glob": "^3.0.4", + "regex-cache": "^0.4.2" + } + }, + "minimatch": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", + "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "dev": true, + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "minimist": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", + "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=", + "dev": true + }, + "mkdirp": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", + "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", + "dev": true, + "requires": { + "minimist": "0.0.8" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + }, + "mute-stream": { + "version": "0.0.5", + "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.5.tgz", + "integrity": "sha1-j7+rsKmKJT0xhDMfno3rc3L6xsA=", + "dev": true + }, + "nan": { + "version": "2.10.0", + "resolved": "https://registry.npmjs.org/nan/-/nan-2.10.0.tgz", + "integrity": "sha512-bAdJv7fBLhWC+/Bls0Oza+mvTaNQtP+1RyhhhvD95pgUJz6XM5IzgmxOkItJ9tkoCiplvAnXI1tNmmUD/eScyA==", + "dev": true, + "optional": true + }, + "natural-compare": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=", + "dev": true + }, + "next-tick": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/next-tick/-/next-tick-1.0.0.tgz", + "integrity": "sha1-yobR/ogoFpsBICCOPchCS524NCw=", + "dev": true + }, + "normalize-path": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", + "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", + "dev": true, + "requires": { + "remove-trailing-separator": "^1.0.1" + } + }, + "number-is-nan": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", + "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=", + "dev": true + }, + "object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", + "dev": true + }, + "object-inspect": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.6.0.tgz", + "integrity": "sha512-GJzfBZ6DgDAmnuaM3104jR4s1Myxr3Y3zfIyN4z3UdqN69oSRacNK8UhnobDdC+7J2AHCjGwxQubNJfE70SXXQ==", + "dev": true + }, + "object-keys": { + "version": "1.0.12", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.0.12.tgz", + "integrity": "sha512-FTMyFUm2wBcGHnH2eXmz7tC6IwlqQZ6mVZ+6dm6vZ4IQIHjs6FdNsQBuKGPuUUUY6NfJw2PshC08Tn6LzLDOag==", + "dev": true + }, + "object.omit": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/object.omit/-/object.omit-2.0.1.tgz", + "integrity": "sha1-Gpx0SCnznbuFjHbKNXmuKlTr0fo=", + "dev": true, + "optional": true, + "requires": { + "for-own": "^0.1.4", + "is-extendable": "^0.1.1" + } + }, + "once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "dev": true, + "requires": { + "wrappy": "1" + } + }, + "onetime": { + "version": "1.1.0", + "resolved": "http://registry.npmjs.org/onetime/-/onetime-1.1.0.tgz", + "integrity": "sha1-ofeDj4MUxRbwXs78vEzP4EtO14k=", + "dev": true + }, + "optionator": { + "version": "0.8.2", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.2.tgz", + "integrity": "sha1-NkxeQJ0/TWMB1sC0wFu6UBgK62Q=", + "dev": true, + "requires": { + "deep-is": "~0.1.3", + "fast-levenshtein": "~2.0.4", + "levn": "~0.3.0", + "prelude-ls": "~1.1.2", + "type-check": "~0.3.2", + "wordwrap": "~1.0.0" + }, + "dependencies": { + "wordwrap": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", + "integrity": "sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus=", + "dev": true + } + } + }, + "os-homedir": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz", + "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=", + "dev": true + }, + "os-locale": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-1.4.0.tgz", + "integrity": "sha1-IPnxeuKe00XoveWDsT0gCYA8FNk=", + "dev": true, + "requires": { + "lcid": "^1.0.0" + } + }, + "os-tmpdir": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", + "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=", + "dev": true + }, + "output-file-sync": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/output-file-sync/-/output-file-sync-1.1.2.tgz", + "integrity": "sha1-0KM+7+YaIF+suQCS6CZZjVJFznY=", + "dev": true, + "requires": { + "graceful-fs": "^4.1.4", + "mkdirp": "^0.5.1", + "object-assign": "^4.1.0" + } + }, + "parse-glob": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/parse-glob/-/parse-glob-3.0.4.tgz", + "integrity": "sha1-ssN2z7EfNVE7rdFz7wu246OIORw=", + "dev": true, + "optional": true, + "requires": { + "glob-base": "^0.3.0", + "is-dotfile": "^1.0.0", + "is-extglob": "^1.0.0", + "is-glob": "^2.0.0" + } + }, + "path-exists": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-1.0.0.tgz", + "integrity": "sha1-1aiZjrce83p0w06w2eum6HjuoIE=", + "dev": true + }, + "path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", + "dev": true + }, + "path-is-inside": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz", + "integrity": "sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM=", + "dev": true + }, + "path-parse": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz", + "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==", + "dev": true + }, + "pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", + "dev": true + }, + "pinkie": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz", + "integrity": "sha1-clVrgM+g1IqXToDnckjoDtT3+HA=", + "dev": true + }, + "pinkie-promise": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz", + "integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=", + "dev": true, + "requires": { + "pinkie": "^2.0.0" + } + }, + "pluralize": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/pluralize/-/pluralize-1.2.1.tgz", + "integrity": "sha1-0aIUg/0iu0HlihL6NCGCMUCJfEU=", + "dev": true + }, + "postcss": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.2.tgz", + "integrity": "sha512-fmaUY5370keLUTx+CnwRxtGiuFTcNBLQBqr1oE3WZ/euIYmGAo0OAgOhVJ3ByDnVmOR3PK+0V9VebzfjRIUcqw==", + "requires": { + "chalk": "^2.4.1", + "source-map": "^0.6.1", + "supports-color": "^5.4.0" + } + }, + "postcss-selector-matches": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/postcss-selector-matches/-/postcss-selector-matches-3.0.1.tgz", + "integrity": "sha1-5WNAEeE5UIgYYbvdWMLQER/8lqs=", + "requires": { + "balanced-match": "^0.4.2", + "postcss": "^6.0.1" + }, + "dependencies": { + "postcss": { + "version": "6.0.23", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.23.tgz", + "integrity": "sha512-soOk1h6J3VMTZtVeVpv15/Hpdl2cBLX3CAw4TAbkpTJiNPk9YP/zWcD1ND+xEtvyuuvKzbxliTOIyvkSeSJ6ag==", + "requires": { + "chalk": "^2.4.1", + "source-map": "^0.6.1", + "supports-color": "^5.4.0" + } + } + } + }, + "prelude-ls": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", + "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=", + "dev": true + }, + "preserve": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/preserve/-/preserve-0.2.0.tgz", + "integrity": "sha1-gV7R9uvGWSb4ZbMQwHE7yzMVzks=", + "dev": true, + "optional": true + }, + "private": { + "version": "0.1.8", + "resolved": "https://registry.npmjs.org/private/-/private-0.1.8.tgz", + "integrity": "sha512-VvivMrbvd2nKkiG38qjULzlc+4Vx4wm/whI9pQD35YrARNnhxeiRktSOhSukRLFNlzg6Br/cJPet5J/u19r/mg==", + "dev": true + }, + "process-nextick-args": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.0.tgz", + "integrity": "sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw==", + "dev": true + }, + "progress": { + "version": "1.1.8", + "resolved": "https://registry.npmjs.org/progress/-/progress-1.1.8.tgz", + "integrity": "sha1-4mDHj2Fhzdmw5WzD4Khd4Xx6V74=", + "dev": true + }, + "q": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/q/-/q-1.5.1.tgz", + "integrity": "sha1-fjL3W0E4EpHQRhHxvxQQmsAGUdc=", + "dev": true + }, + "randomatic": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/randomatic/-/randomatic-3.1.0.tgz", + "integrity": "sha512-KnGPVE0lo2WoXxIZ7cPR8YBpiol4gsSuOwDSg410oHh80ZMp5EiypNqL2K4Z77vJn6lB5rap7IkAmcUlalcnBQ==", + "dev": true, + "optional": true, + "requires": { + "is-number": "^4.0.0", + "kind-of": "^6.0.0", + "math-random": "^1.0.1" + }, + "dependencies": { + "is-number": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-4.0.0.tgz", + "integrity": "sha512-rSklcAIlf1OmFdyAqbnWTLVelsQ58uvZ66S/ZyawjWqIviTWCjg2PzVGw8WUA+nNuPTqb4wgA+NszrJ+08LlgQ==", + "dev": true, + "optional": true + }, + "kind-of": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", + "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==", + "dev": true, + "optional": true + } + } + }, + "readable-stream": { + "version": "2.3.6", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", + "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", + "dev": true, + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "readdirp": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-2.1.0.tgz", + "integrity": "sha1-TtCtBg3zBzMAxIRANz9y0cxkLXg=", + "dev": true, + "optional": true, + "requires": { + "graceful-fs": "^4.1.2", + "minimatch": "^3.0.2", + "readable-stream": "^2.0.2", + "set-immediate-shim": "^1.0.1" + } + }, + "readline2": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/readline2/-/readline2-1.0.1.tgz", + "integrity": "sha1-QQWWCP/BVHV7cV2ZidGZ/783LjU=", + "dev": true, + "requires": { + "code-point-at": "^1.0.0", + "is-fullwidth-code-point": "^1.0.0", + "mute-stream": "0.0.5" + } + }, + "recast": { + "version": "0.10.33", + "resolved": "https://registry.npmjs.org/recast/-/recast-0.10.33.tgz", + "integrity": "sha1-lCgI96oBbx+nFCxGHX5XBKqo1pc=", + "dev": true, + "requires": { + "ast-types": "0.8.12", + "esprima-fb": "~15001.1001.0-dev-harmony-fb", + "private": "~0.1.5", + "source-map": "~0.5.0" + }, + "dependencies": { + "ast-types": { + "version": "0.8.12", + "resolved": "https://registry.npmjs.org/ast-types/-/ast-types-0.8.12.tgz", + "integrity": "sha1-oNkOQ1G7iHcWyD/WN+v4GK9K38w=", + "dev": true + }, + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "dev": true + } + } + }, + "rechoir": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.6.2.tgz", + "integrity": "sha1-hSBLVNuoLVdC4oyWdW70OvUOM4Q=", + "dev": true, + "requires": { + "resolve": "^1.1.6" + } + }, + "regenerate": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.0.tgz", + "integrity": "sha512-1G6jJVDWrt0rK99kBjvEtziZNCICAuvIPkSiUFIQxVP06RCVpq3dmDo2oi6ABpYaDYaTRr67BEhL8r1wgEZZKg==", + "dev": true + }, + "regenerator": { + "version": "0.8.40", + "resolved": "https://registry.npmjs.org/regenerator/-/regenerator-0.8.40.tgz", + "integrity": "sha1-oORXxY69uuV1yfjNdRJ+k3VkNdg=", + "dev": true, + "requires": { + "commoner": "~0.10.3", + "defs": "~1.1.0", + "esprima-fb": "~15001.1001.0-dev-harmony-fb", + "private": "~0.1.5", + "recast": "0.10.33", + "through": "~2.3.8" + } + }, + "regenerator-runtime": { + "version": "0.11.1", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz", + "integrity": "sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg==", + "dev": true + }, + "regenerator-transform": { + "version": "0.10.1", + "resolved": "https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.10.1.tgz", + "integrity": "sha512-PJepbvDbuK1xgIgnau7Y90cwaAmO/LCLMI2mPvaXq2heGMR3aWW5/BQvYrhJ8jgmQjXewXvBjzfqKcVOmhjZ6Q==", + "dev": true, + "requires": { + "babel-runtime": "^6.18.0", + "babel-types": "^6.19.0", + "private": "^0.1.6" + } + }, + "regex-cache": { + "version": "0.4.4", + "resolved": "https://registry.npmjs.org/regex-cache/-/regex-cache-0.4.4.tgz", + "integrity": "sha512-nVIZwtCjkC9YgvWkpM55B5rBhBYRZhAaJbgcFYXXsHnbZ9UZI9nnVWYZpBlCqv9ho2eZryPnWrZGsOdPwVWXWQ==", + "dev": true, + "optional": true, + "requires": { + "is-equal-shallow": "^0.1.3" + } + }, + "regexpu": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/regexpu/-/regexpu-1.3.0.tgz", + "integrity": "sha1-5TTcmRqeWEYFDJjebX3UpVyeoW0=", + "dev": true, + "requires": { + "esprima": "^2.6.0", + "recast": "^0.10.10", + "regenerate": "^1.2.1", + "regjsgen": "^0.2.0", + "regjsparser": "^0.1.4" + }, + "dependencies": { + "esprima": { + "version": "2.7.3", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-2.7.3.tgz", + "integrity": "sha1-luO3DVd59q1JzQMmc9HDEnZ7pYE=", + "dev": true + } + } + }, + "regexpu-core": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-2.0.0.tgz", + "integrity": "sha1-SdA4g3uNz4v6W5pCE5k45uoq4kA=", + "dev": true, + "requires": { + "regenerate": "^1.2.1", + "regjsgen": "^0.2.0", + "regjsparser": "^0.1.4" + } + }, + "regjsgen": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/regjsgen/-/regjsgen-0.2.0.tgz", + "integrity": "sha1-bAFq3qxVT3WCP+N6wFuS1aTtsfc=", + "dev": true + }, + "regjsparser": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.1.5.tgz", + "integrity": "sha1-fuj4Tcb6eS0/0K4ijSS9lJ6tIFw=", + "dev": true, + "requires": { + "jsesc": "~0.5.0" + }, + "dependencies": { + "jsesc": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-0.5.0.tgz", + "integrity": "sha1-597mbjXW/Bb3EP6R1c9p9w8IkR0=", + "dev": true + } + } + }, + "remove-trailing-separator": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz", + "integrity": "sha1-wkvOKig62tW8P1jg1IJJuSN52O8=", + "dev": true + }, + "repeat-element": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.2.tgz", + "integrity": "sha1-7wiaF40Ug7quTZPrmLT55OEdmQo=", + "dev": true + }, + "repeat-string": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", + "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=", + "dev": true + }, + "repeating": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/repeating/-/repeating-2.0.1.tgz", + "integrity": "sha1-UhTFOpJtNVJwdSf7q0FdvAjQbdo=", + "dev": true, + "requires": { + "is-finite": "^1.0.0" + } + }, + "require-uncached": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/require-uncached/-/require-uncached-1.0.3.tgz", + "integrity": "sha1-Tg1W1slmL9MeQwEcS5WqSZVUIdM=", + "dev": true, + "requires": { + "caller-path": "^0.1.0", + "resolve-from": "^1.0.0" + } + }, + "resolve": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.8.1.tgz", + "integrity": "sha512-AicPrAC7Qu1JxPCZ9ZgCZlY35QgFnNqc+0LtbRNxnVw4TXvjQ72wnuL9JQcEBgXkI9JM8MsT9kaQoHcpCRJOYA==", + "dev": true, + "requires": { + "path-parse": "^1.0.5" + } + }, + "resolve-from": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-1.0.1.tgz", + "integrity": "sha1-Jsv+k10a7uq7Kbw/5a6wHpPUQiY=", + "dev": true + }, + "restore-cursor": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-1.0.1.tgz", + "integrity": "sha1-NGYfRohjJ/7SmRR5FSJS35LapUE=", + "dev": true, + "requires": { + "exit-hook": "^1.0.0", + "onetime": "^1.0.0" + } + }, + "resumer": { + "version": "0.0.0", + "resolved": "https://registry.npmjs.org/resumer/-/resumer-0.0.0.tgz", + "integrity": "sha1-8ej0YeQGS6Oegq883CqMiT0HZ1k=", + "dev": true, + "requires": { + "through": "~2.3.4" + } + }, + "right-align": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/right-align/-/right-align-0.1.3.tgz", + "integrity": "sha1-YTObci/mo1FWiSENJOFMlhSGE+8=", + "dev": true, + "requires": { + "align-text": "^0.1.1" + } + }, + "rimraf": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.2.tgz", + "integrity": "sha512-lreewLK/BlghmxtfH36YYVg1i8IAce4TI7oao75I1g245+6BctqTVQiBP3YUJ9C6DQOXJmkYR9X9fCLtCOJc5w==", + "dev": true, + "requires": { + "glob": "^7.0.5" + } + }, + "run-async": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/run-async/-/run-async-0.1.0.tgz", + "integrity": "sha1-yK1KXhEGYeQCp9IbUw4AnyX444k=", + "dev": true, + "requires": { + "once": "^1.3.0" + } + }, + "rx-lite": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/rx-lite/-/rx-lite-3.1.2.tgz", + "integrity": "sha1-Gc5QLKVyZl87ZHsQk5+X/RYV8QI=", + "dev": true + }, + "safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true + }, + "safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", + "dev": true + }, + "semver": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.5.0.tgz", + "integrity": "sha512-4SJ3dm0WAwWy/NVeioZh5AntkdJoWKxHxcmyP622fOkgHa4z3R0TdBJICINyaSDE6uNwVc8gZr+ZinwZAH4xIA==", + "dev": true + }, + "set-immediate-shim": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/set-immediate-shim/-/set-immediate-shim-1.0.1.tgz", + "integrity": "sha1-SysbJ+uAip+NzEgaWOXlb1mfP2E=", + "dev": true, + "optional": true + }, + "shebang-regex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", + "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=", + "dev": true + }, + "shelljs": { + "version": "0.7.8", + "resolved": "https://registry.npmjs.org/shelljs/-/shelljs-0.7.8.tgz", + "integrity": "sha1-3svPh0sNHl+3LhSxZKloMEjprLM=", + "dev": true, + "requires": { + "glob": "^7.0.0", + "interpret": "^1.0.0", + "rechoir": "^0.6.2" + } + }, + "simple-fmt": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/simple-fmt/-/simple-fmt-0.1.0.tgz", + "integrity": "sha1-GRv1ZqWeZTBILLJatTtKjchcOms=", + "dev": true + }, + "simple-is": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/simple-is/-/simple-is-0.2.0.tgz", + "integrity": "sha1-Krt1qt453rXMgVzhDmGRFkhQuvA=", + "dev": true + }, + "slash": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-1.0.0.tgz", + "integrity": "sha1-xB8vbDn8FtHNF61LXYlhFK5HDVU=", + "dev": true + }, + "slice-ansi": { + "version": "0.0.4", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-0.0.4.tgz", + "integrity": "sha1-7b+JA/ZvfOL46v1s7tZeJkyDGzU=", + "dev": true + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" + }, + "source-map-support": { + "version": "0.4.18", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.4.18.tgz", + "integrity": "sha512-try0/JqxPLF9nOjvSta7tVondkP5dwgyLDjVoyMDlmjugT2lRZ1OfsrYTkCd2hkDnJTKRbO/Rl3orm8vlsUzbA==", + "dev": true, + "requires": { + "source-map": "^0.5.6" + }, + "dependencies": { + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "dev": true + } + } + }, + "sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", + "dev": true + }, + "stable": { + "version": "0.1.8", + "resolved": "https://registry.npmjs.org/stable/-/stable-0.1.8.tgz", + "integrity": "sha512-ji9qxRnOVfcuLDySj9qzhGSEFVobyt1kIOSkj1qZzYLzq7Tos/oUUWvotUPQLlrsidqsK6tBH89Bc9kL5zHA6w==", + "dev": true + }, + "string-width": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", + "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", + "dev": true, + "requires": { + "code-point-at": "^1.0.0", + "is-fullwidth-code-point": "^1.0.0", + "strip-ansi": "^3.0.0" + } + }, + "string.prototype.trim": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.1.2.tgz", + "integrity": "sha1-0E3iyJ4Tf019IG8Ia17S+ua+jOo=", + "dev": true, + "requires": { + "define-properties": "^1.1.2", + "es-abstract": "^1.5.0", + "function-bind": "^1.0.2" + } + }, + "string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dev": true, + "requires": { + "safe-buffer": "~5.1.0" + } + }, + "stringmap": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/stringmap/-/stringmap-0.2.2.tgz", + "integrity": "sha1-VWwTeyWPlCuHdvWy71gqoGnX0bE=", + "dev": true + }, + "stringset": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/stringset/-/stringset-0.2.1.tgz", + "integrity": "sha1-7yWcTjSTRDd/zRyRPdLoSMnAQrU=", + "dev": true + }, + "strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "dev": true, + "requires": { + "ansi-regex": "^2.0.0" + } + }, + "strip-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", + "dev": true + }, + "strip-json-comments": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", + "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=", + "dev": true + }, + "supports-color": { + "version": "5.4.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.4.0.tgz", + "integrity": "sha512-zjaXglF5nnWpsq470jSv6P9DwPvgLkuapYmfDm3JWOm0vkNTVF2tI4UrN2r6jH1qM/uc/WtxYY1hYoA2dOKj5w==", + "requires": { + "has-flag": "^3.0.0" + } + }, + "table": { + "version": "3.8.3", + "resolved": "https://registry.npmjs.org/table/-/table-3.8.3.tgz", + "integrity": "sha1-K7xULw/amGGnVdOUf+/Ys/UThV8=", + "dev": true, + "requires": { + "ajv": "^4.7.0", + "ajv-keywords": "^1.0.0", + "chalk": "^1.1.1", + "lodash": "^4.0.0", + "slice-ansi": "0.0.4", + "string-width": "^2.0.0" + }, + "dependencies": { + "ansi-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", + "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", + "dev": true + }, + "ansi-styles": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", + "dev": true + }, + "chalk": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", + "dev": true, + "requires": { + "ansi-styles": "^2.2.1", + "escape-string-regexp": "^1.0.2", + "has-ansi": "^2.0.0", + "strip-ansi": "^3.0.0", + "supports-color": "^2.0.0" + } + }, + "is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", + "dev": true + }, + "string-width": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", + "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", + "dev": true, + "requires": { + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^4.0.0" + }, + "dependencies": { + "strip-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", + "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", + "dev": true, + "requires": { + "ansi-regex": "^3.0.0" + } + } + } + }, + "supports-color": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", + "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", + "dev": true + } + } + }, + "tape": { + "version": "4.9.1", + "resolved": "https://registry.npmjs.org/tape/-/tape-4.9.1.tgz", + "integrity": "sha512-6fKIXknLpoe/Jp4rzHKFPpJUHDHDqn8jus99IfPnHIjyz78HYlefTGD3b5EkbQzuLfaEvmfPK3IolLgq2xT3kw==", + "dev": true, + "requires": { + "deep-equal": "~1.0.1", + "defined": "~1.0.0", + "for-each": "~0.3.3", + "function-bind": "~1.1.1", + "glob": "~7.1.2", + "has": "~1.0.3", + "inherits": "~2.0.3", + "minimist": "~1.2.0", + "object-inspect": "~1.6.0", + "resolve": "~1.7.1", + "resumer": "~0.0.0", + "string.prototype.trim": "~1.1.2", + "through": "~2.3.8" + }, + "dependencies": { + "minimist": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", + "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", + "dev": true + }, + "resolve": { + "version": "1.7.1", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.7.1.tgz", + "integrity": "sha512-c7rwLofp8g1U+h1KNyHL/jicrKg1Ek4q+Lr33AL65uZTinUZHe30D5HlyN5V9NW0JX1D5dXQ4jqW5l7Sy/kGfw==", + "dev": true, + "requires": { + "path-parse": "^1.0.5" + } + } + } + }, + "text-table": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", + "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=", + "dev": true + }, + "through": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", + "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=", + "dev": true + }, + "to-fast-properties": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-1.0.3.tgz", + "integrity": "sha1-uDVx+k2MJbguIxsG46MFXeTKGkc=", + "dev": true + }, + "trim-right": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/trim-right/-/trim-right-1.0.1.tgz", + "integrity": "sha1-yy4SAwZ+DI3h9hQJS5/kVwTqYAM=", + "dev": true + }, + "try-resolve": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/try-resolve/-/try-resolve-1.0.1.tgz", + "integrity": "sha1-z95vq9ctY+V5fPqrhzq76OcA6RI=", + "dev": true + }, + "tryor": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/tryor/-/tryor-0.1.2.tgz", + "integrity": "sha1-gUXkynyv9ArN48z5Rui4u3W0Fys=", + "dev": true + }, + "type-check": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", + "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=", + "dev": true, + "requires": { + "prelude-ls": "~1.1.2" + } + }, + "typedarray": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", + "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=", + "dev": true + }, + "user-home": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/user-home/-/user-home-1.1.1.tgz", + "integrity": "sha1-K1viOjK2Onyd640PKNSFcko98ZA=", + "dev": true + }, + "util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=", + "dev": true + }, + "v8flags": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/v8flags/-/v8flags-2.1.1.tgz", + "integrity": "sha1-qrGh+jDUX4jdMhFIh1rALAtV5bQ=", + "dev": true, + "requires": { + "user-home": "^1.1.1" + } + }, + "window-size": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/window-size/-/window-size-0.1.4.tgz", + "integrity": "sha1-+OGqHuWlPsW/FR/6CXQqatdpeHY=", + "dev": true + }, + "wordwrap": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.2.tgz", + "integrity": "sha1-t5Zpu0LstAn4PVg8rVLKF+qhZD8=", + "dev": true + }, + "wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", + "dev": true + }, + "write": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/write/-/write-0.2.1.tgz", + "integrity": "sha1-X8A4KOJkzqP+kUVUdvejxWbLB1c=", + "dev": true, + "requires": { + "mkdirp": "^0.5.1" + } + }, + "xtend": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz", + "integrity": "sha1-pcbVMr5lbiPbgg77lDofBJmNY68=", + "dev": true + }, + "y18n": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-3.2.1.tgz", + "integrity": "sha1-bRX7qITAhnnA136I53WegR4H+kE=", + "dev": true + }, + "yargs": { + "version": "3.27.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-3.27.0.tgz", + "integrity": "sha1-ISBUaTFuk5Ex1Z8toMbX+YIh6kA=", + "dev": true, + "requires": { + "camelcase": "^1.2.1", + "cliui": "^2.1.0", + "decamelize": "^1.0.0", + "os-locale": "^1.4.0", + "window-size": "^0.1.2", + "y18n": "^3.2.0" + } + } + } +} diff --git a/package.json b/package.json index d34a197542..174ebf0aba 100644 --- a/package.json +++ b/package.json @@ -23,8 +23,11 @@ "dist", "README-zh.md" ], + "engines": { + "node": ">=6.0.0" + }, "dependencies": { - "postcss": "^6.0.1", + "postcss": "^7.0.2", "postcss-selector-matches": "^3.0.0" }, "devDependencies": { From 926f1ef629b3e82118148b1153deafe45f6e5a39 Mon Sep 17 00:00:00 2001 From: Pascal Duez Date: Mon, 13 Aug 2018 14:36:50 +0200 Subject: [PATCH 657/795] Use PostCSS 7 Refs csstools/postcss-preset-env#58 - Fixed borken unit tests runner. - Added a `package-lock` file. --- .travis.yml | 2 +- package-lock.json | 2035 +++++++++++++++++++++++++++++++++++++++++++++ package.json | 5 +- test/index.js | 2 +- 4 files changed, 2041 insertions(+), 3 deletions(-) create mode 100644 package-lock.json diff --git a/.travis.yml b/.travis.yml index 6e538237ad..ebea37eb05 100644 --- a/.travis.yml +++ b/.travis.yml @@ -2,5 +2,5 @@ sudo: false language: node_js node_js: - "stable" + - "8" - "6" - - "4" diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 0000000000..8330f0a5bd --- /dev/null +++ b/package-lock.json @@ -0,0 +1,2035 @@ +{ + "name": "postcss-custom-media", + "version": "6.0.0", + "lockfileVersion": 1, + "requires": true, + "dependencies": { + "@octokit/rest": { + "version": "14.0.9", + "resolved": "https://registry.npmjs.org/@octokit/rest/-/rest-14.0.9.tgz", + "integrity": "sha512-irP9phKfTXEZIcW2R+VNCtGHZJrXMWmSYp6RRfFn4BtAqtDRXF5z9JxCEQlAhNBf6X1koNi5k49tIAAAEJNlVQ==", + "dev": true, + "requires": { + "before-after-hook": "^1.1.0", + "debug": "^3.1.0", + "is-array-buffer": "^1.0.0", + "is-stream": "^1.1.0", + "lodash": "^4.17.4", + "url-template": "^2.0.8" + }, + "dependencies": { + "debug": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", + "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + } + } + }, + "@sindresorhus/df": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@sindresorhus/df/-/df-2.1.0.tgz", + "integrity": "sha1-0gjPJ+BvC7R20U197M19cm6ao4k=", + "dev": true, + "requires": { + "execa": "^0.2.2" + } + }, + "acorn": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-5.7.1.tgz", + "integrity": "sha512-d+nbxBUGKg7Arpsvbnlq61mc12ek3EY8EQldM3GPAhWJ1UVxC6TDGbIvUMNU6obBX3i1+ptCIzV4vq0gFPEGVQ==", + "dev": true + }, + "acorn-jsx": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-3.0.1.tgz", + "integrity": "sha1-r9+UiPsezvyDSPb7IvRk4ypYs2s=", + "dev": true, + "requires": { + "acorn": "^3.0.4" + }, + "dependencies": { + "acorn": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-3.3.0.tgz", + "integrity": "sha1-ReN/s56No/JbruP/U2niu18iAXo=", + "dev": true + } + } + }, + "ajv": { + "version": "4.11.8", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-4.11.8.tgz", + "integrity": "sha1-gv+wKynmYq5TvcIK8VlHcGc5xTY=", + "dev": true, + "requires": { + "co": "^4.6.0", + "json-stable-stringify": "^1.0.1" + } + }, + "ajv-keywords": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-1.5.1.tgz", + "integrity": "sha1-MU3QpLM2j609/NxU7eYXG4htrzw=", + "dev": true + }, + "ansi-escapes": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-1.4.0.tgz", + "integrity": "sha1-06ioOzGapneTZisT52HHkRQiMG4=", + "dev": true + }, + "ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", + "dev": true + }, + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "requires": { + "color-convert": "^1.9.0" + } + }, + "argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "dev": true, + "requires": { + "sprintf-js": "~1.0.2" + } + }, + "array-union": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-1.0.2.tgz", + "integrity": "sha1-mjRBDk9OPaI96jdb5b5w8kd47Dk=", + "dev": true, + "requires": { + "array-uniq": "^1.0.1" + } + }, + "array-uniq": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/array-uniq/-/array-uniq-1.0.3.tgz", + "integrity": "sha1-r2rId6Jcx/dOBYiUdThY39sk/bY=", + "dev": true + }, + "arrify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", + "integrity": "sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=", + "dev": true + }, + "babel-code-frame": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-code-frame/-/babel-code-frame-6.26.0.tgz", + "integrity": "sha1-Y/1D99weO7fONZR9uP42mj9Yx0s=", + "dev": true, + "requires": { + "chalk": "^1.1.3", + "esutils": "^2.0.2", + "js-tokens": "^3.0.2" + }, + "dependencies": { + "ansi-styles": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", + "dev": true + }, + "chalk": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", + "dev": true, + "requires": { + "ansi-styles": "^2.2.1", + "escape-string-regexp": "^1.0.2", + "has-ansi": "^2.0.0", + "strip-ansi": "^3.0.0", + "supports-color": "^2.0.0" + } + }, + "supports-color": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", + "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", + "dev": true + } + } + }, + "balanced-match": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", + "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", + "dev": true + }, + "before-after-hook": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/before-after-hook/-/before-after-hook-1.1.0.tgz", + "integrity": "sha512-VOMDtYPwLbIncTxNoSzRyvaMxtXmLWLUqr8k5AfC1BzLk34HvBXaQX8snOwQZ4c0aX8aSERqtJSiI9/m2u5kuA==", + "dev": true + }, + "brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "buffer-from": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", + "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==", + "dev": true + }, + "builtin-modules": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-1.1.1.tgz", + "integrity": "sha1-Jw8HbFpywC9bZaR9+Uxf46J4iS8=", + "dev": true + }, + "caller-path": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/caller-path/-/caller-path-0.1.0.tgz", + "integrity": "sha1-lAhe9jWB7NPaqSREqP6U6CV3dR8=", + "dev": true, + "requires": { + "callsites": "^0.2.0" + } + }, + "callsites": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-0.2.0.tgz", + "integrity": "sha1-r6uWJikQp/M8GaV3WCXGnzTjUMo=", + "dev": true + }, + "chalk": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.1.tgz", + "integrity": "sha512-ObN6h1v2fTJSmUXoS3nMQ92LbDK9be4TV+6G+omQlGJFdcUX5heKi1LZ1YnRMIgwTLEj3E24bT6tYni50rlCfQ==", + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, + "checkup": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/checkup/-/checkup-1.3.0.tgz", + "integrity": "sha1-04ACdv6l0PJH/8lRvnjIsC+ODXY=", + "dev": true + }, + "circular-json": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/circular-json/-/circular-json-0.3.3.tgz", + "integrity": "sha512-UZK3NBx2Mca+b5LsG7bY183pHWt5Y1xts4P3Pz7ENTwGVnJOUWbRb3ocjvX7hx9tq/yTAdclXm9sZ38gNuem4A==", + "dev": true + }, + "cli-cursor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-1.0.2.tgz", + "integrity": "sha1-ZNo/fValRBLll5S9Ytw1KV6PKYc=", + "dev": true, + "requires": { + "restore-cursor": "^1.0.1" + } + }, + "cli-width": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-2.2.0.tgz", + "integrity": "sha1-/xnt6Kml5XkyQUewwR8PvLq+1jk=", + "dev": true + }, + "co": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", + "integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ=", + "dev": true + }, + "code-point-at": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", + "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=", + "dev": true + }, + "color-convert": { + "version": "1.9.2", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.2.tgz", + "integrity": "sha512-3NUJZdhMhcdPn8vJ9v2UQJoH0qqoGUkYTgFEPZaPjEtwmmKUfNV46zZmgB2M5M4DCEQHMaCfWHCxiBflLm04Tg==", + "requires": { + "color-name": "1.1.1" + } + }, + "color-name": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.1.tgz", + "integrity": "sha1-SxQVMEz1ACjqgWQ2Q72C6gWANok=" + }, + "concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", + "dev": true + }, + "concat-stream": { + "version": "1.6.2", + "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz", + "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==", + "dev": true, + "requires": { + "buffer-from": "^1.0.0", + "inherits": "^2.0.3", + "readable-stream": "^2.2.2", + "typedarray": "^0.0.6" + } + }, + "contains-path": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/contains-path/-/contains-path-0.1.0.tgz", + "integrity": "sha1-/ozxhP9mcLa67wGp1IYaXL7EEgo=", + "dev": true + }, + "core-util-is": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", + "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=", + "dev": true + }, + "cross-spawn-async": { + "version": "2.2.5", + "resolved": "https://registry.npmjs.org/cross-spawn-async/-/cross-spawn-async-2.2.5.tgz", + "integrity": "sha1-hF/wwINKPe2dFg2sptOQkGuyiMw=", + "dev": true, + "requires": { + "lru-cache": "^4.0.0", + "which": "^1.2.8" + } + }, + "d": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/d/-/d-1.0.0.tgz", + "integrity": "sha1-dUu1v+VUUdpppYuU1F9MWwRi1Y8=", + "dev": true, + "requires": { + "es5-ext": "^0.10.9" + } + }, + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "deep-equal": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/deep-equal/-/deep-equal-1.0.1.tgz", + "integrity": "sha1-9dJgKStmDghO/0zbyfCK0yR0SLU=", + "dev": true + }, + "deep-is": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz", + "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=", + "dev": true + }, + "define-properties": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.2.tgz", + "integrity": "sha1-g6c/L+pWmJj7c3GTyPhzyvbUXJQ=", + "dev": true, + "requires": { + "foreach": "^2.0.5", + "object-keys": "^1.0.8" + } + }, + "defined": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/defined/-/defined-1.0.0.tgz", + "integrity": "sha1-yY2bzvdWdBiOEQlpFRGZ45sfppM=", + "dev": true + }, + "del": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/del/-/del-2.2.2.tgz", + "integrity": "sha1-wSyYHQZ4RshLyvhiz/kw2Qf/0ag=", + "dev": true, + "requires": { + "globby": "^5.0.0", + "is-path-cwd": "^1.0.0", + "is-path-in-cwd": "^1.0.0", + "object-assign": "^4.0.1", + "pify": "^2.0.0", + "pinkie-promise": "^2.0.0", + "rimraf": "^2.2.8" + } + }, + "doctrine": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", + "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", + "dev": true, + "requires": { + "esutils": "^2.0.2" + } + }, + "es-abstract": { + "version": "1.12.0", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.12.0.tgz", + "integrity": "sha512-C8Fx/0jFmV5IPoMOFPA9P9G5NtqW+4cOPit3MIuvR2t7Ag2K15EJTpxnHAYTzL+aYQJIESYeXZmDBfOBE1HcpA==", + "dev": true, + "requires": { + "es-to-primitive": "^1.1.1", + "function-bind": "^1.1.1", + "has": "^1.0.1", + "is-callable": "^1.1.3", + "is-regex": "^1.0.4" + } + }, + "es-to-primitive": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.1.1.tgz", + "integrity": "sha1-RTVSSKiJeQNLZ5Lhm7gfK3l13Q0=", + "dev": true, + "requires": { + "is-callable": "^1.1.1", + "is-date-object": "^1.0.1", + "is-symbol": "^1.0.1" + } + }, + "es5-ext": { + "version": "0.10.45", + "resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.45.tgz", + "integrity": "sha512-FkfM6Vxxfmztilbxxz5UKSD4ICMf5tSpRFtDNtkAhOxZ0EKtX6qwmXNyH/sFyIbX2P/nU5AMiA9jilWsUGJzCQ==", + "dev": true, + "requires": { + "es6-iterator": "~2.0.3", + "es6-symbol": "~3.1.1", + "next-tick": "1" + } + }, + "es6-iterator": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/es6-iterator/-/es6-iterator-2.0.3.tgz", + "integrity": "sha1-p96IkUGgWpSwhUQDstCg+/qY87c=", + "dev": true, + "requires": { + "d": "1", + "es5-ext": "^0.10.35", + "es6-symbol": "^3.1.1" + } + }, + "es6-map": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/es6-map/-/es6-map-0.1.5.tgz", + "integrity": "sha1-kTbgUD3MBqMBaQ8LsU/042TpSfA=", + "dev": true, + "requires": { + "d": "1", + "es5-ext": "~0.10.14", + "es6-iterator": "~2.0.1", + "es6-set": "~0.1.5", + "es6-symbol": "~3.1.1", + "event-emitter": "~0.3.5" + } + }, + "es6-set": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/es6-set/-/es6-set-0.1.5.tgz", + "integrity": "sha1-0rPsXU2ADO2BjbU40ol02wpzzLE=", + "dev": true, + "requires": { + "d": "1", + "es5-ext": "~0.10.14", + "es6-iterator": "~2.0.1", + "es6-symbol": "3.1.1", + "event-emitter": "~0.3.5" + } + }, + "es6-symbol": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/es6-symbol/-/es6-symbol-3.1.1.tgz", + "integrity": "sha1-vwDvT9q2uhtG7Le2KbTH7VcVzHc=", + "dev": true, + "requires": { + "d": "1", + "es5-ext": "~0.10.14" + } + }, + "es6-weak-map": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/es6-weak-map/-/es6-weak-map-2.0.2.tgz", + "integrity": "sha1-XjqzIlH/0VOKH45f+hNXdy+S2W8=", + "dev": true, + "requires": { + "d": "1", + "es5-ext": "^0.10.14", + "es6-iterator": "^2.0.1", + "es6-symbol": "^3.1.1" + } + }, + "escape-string-applescript": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/escape-string-applescript/-/escape-string-applescript-1.0.0.tgz", + "integrity": "sha1-bxwilCRdgsY7wDM43BmpSqhCiJI=", + "dev": true + }, + "escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=" + }, + "escope": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/escope/-/escope-3.6.0.tgz", + "integrity": "sha1-4Bl16BJ4GhY6ba392AOY3GTIicM=", + "dev": true, + "requires": { + "es6-map": "^0.1.3", + "es6-weak-map": "^2.0.1", + "esrecurse": "^4.1.0", + "estraverse": "^4.1.1" + } + }, + "eslint": { + "version": "3.19.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-3.19.0.tgz", + "integrity": "sha1-yPxiAcf0DdCJQbh8CFdnOGpnmsw=", + "dev": true, + "requires": { + "babel-code-frame": "^6.16.0", + "chalk": "^1.1.3", + "concat-stream": "^1.5.2", + "debug": "^2.1.1", + "doctrine": "^2.0.0", + "escope": "^3.6.0", + "espree": "^3.4.0", + "esquery": "^1.0.0", + "estraverse": "^4.2.0", + "esutils": "^2.0.2", + "file-entry-cache": "^2.0.0", + "glob": "^7.0.3", + "globals": "^9.14.0", + "ignore": "^3.2.0", + "imurmurhash": "^0.1.4", + "inquirer": "^0.12.0", + "is-my-json-valid": "^2.10.0", + "is-resolvable": "^1.0.0", + "js-yaml": "^3.5.1", + "json-stable-stringify": "^1.0.0", + "levn": "^0.3.0", + "lodash": "^4.0.0", + "mkdirp": "^0.5.0", + "natural-compare": "^1.4.0", + "optionator": "^0.8.2", + "path-is-inside": "^1.0.1", + "pluralize": "^1.2.1", + "progress": "^1.1.8", + "require-uncached": "^1.0.2", + "shelljs": "^0.7.5", + "strip-bom": "^3.0.0", + "strip-json-comments": "~2.0.1", + "table": "^3.7.8", + "text-table": "~0.2.0", + "user-home": "^2.0.0" + }, + "dependencies": { + "ansi-styles": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", + "dev": true + }, + "chalk": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", + "dev": true, + "requires": { + "ansi-styles": "^2.2.1", + "escape-string-regexp": "^1.0.2", + "has-ansi": "^2.0.0", + "strip-ansi": "^3.0.0", + "supports-color": "^2.0.0" + } + }, + "supports-color": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", + "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", + "dev": true + } + } + }, + "eslint-config-i-am-meticulous": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/eslint-config-i-am-meticulous/-/eslint-config-i-am-meticulous-6.0.1.tgz", + "integrity": "sha1-M3/z/T/delhHp0fxejjY9spxfDk=", + "dev": true, + "requires": { + "eslint-plugin-import": "^1.7.0" + } + }, + "eslint-import-resolver-node": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.2.3.tgz", + "integrity": "sha1-Wt2BBujJKNssuiMrzZ76hG49oWw=", + "dev": true, + "requires": { + "debug": "^2.2.0", + "object-assign": "^4.0.1", + "resolve": "^1.1.6" + } + }, + "eslint-plugin-import": { + "version": "1.16.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-1.16.0.tgz", + "integrity": "sha1-svoH68xTUE0PKkR3WC7Iv/GHG58=", + "dev": true, + "requires": { + "builtin-modules": "^1.1.1", + "contains-path": "^0.1.0", + "debug": "^2.2.0", + "doctrine": "1.3.x", + "es6-map": "^0.1.3", + "es6-set": "^0.1.4", + "eslint-import-resolver-node": "^0.2.0", + "has": "^1.0.1", + "lodash.cond": "^4.3.0", + "lodash.endswith": "^4.0.1", + "lodash.find": "^4.3.0", + "lodash.findindex": "^4.3.0", + "minimatch": "^3.0.3", + "object-assign": "^4.0.1", + "pkg-dir": "^1.0.0", + "pkg-up": "^1.0.0" + }, + "dependencies": { + "doctrine": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-1.3.0.tgz", + "integrity": "sha1-E+dWgrVVGEJCdvfBc3g0Vu+RPSY=", + "dev": true, + "requires": { + "esutils": "^2.0.2", + "isarray": "^1.0.0" + } + } + } + }, + "espree": { + "version": "3.5.4", + "resolved": "https://registry.npmjs.org/espree/-/espree-3.5.4.tgz", + "integrity": "sha512-yAcIQxtmMiB/jL32dzEp2enBeidsB7xWPLNiw3IIkpVds1P+h7qF9YwJq1yUNzp2OKXgAprs4F61ih66UsoD1A==", + "dev": true, + "requires": { + "acorn": "^5.5.0", + "acorn-jsx": "^3.0.0" + } + }, + "esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "dev": true + }, + "esquery": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.0.1.tgz", + "integrity": "sha512-SmiyZ5zIWH9VM+SRUReLS5Q8a7GxtRdxEBVZpm98rJM7Sb+A9DVCndXfkeFUd3byderg+EbDkfnevfCwynWaNA==", + "dev": true, + "requires": { + "estraverse": "^4.0.0" + } + }, + "esrecurse": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.2.1.tgz", + "integrity": "sha512-64RBB++fIOAXPw3P9cy89qfMlvZEXZkqqJkjqqXIvzP5ezRZjW+lPWjw35UX/3EhUPFYbg5ER4JYgDw4007/DQ==", + "dev": true, + "requires": { + "estraverse": "^4.1.0" + } + }, + "estraverse": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.2.0.tgz", + "integrity": "sha1-De4/7TH81GlhjOc0IJn8GvoL2xM=", + "dev": true + }, + "esutils": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.2.tgz", + "integrity": "sha1-Cr9PHKpbyx96nYrMbepPqqBLrJs=", + "dev": true + }, + "event-emitter": { + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/event-emitter/-/event-emitter-0.3.5.tgz", + "integrity": "sha1-34xp7vFkeSPHFXuc6DhAYQsCzDk=", + "dev": true, + "requires": { + "d": "1", + "es5-ext": "~0.10.14" + } + }, + "execa": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/execa/-/execa-0.2.2.tgz", + "integrity": "sha1-4urUcsLDGq1vc/GslW7vReEjIMs=", + "dev": true, + "requires": { + "cross-spawn-async": "^2.1.1", + "npm-run-path": "^1.0.0", + "object-assign": "^4.0.1", + "path-key": "^1.0.0", + "strip-eof": "^1.0.0" + } + }, + "execon": { + "version": "1.2.9", + "resolved": "https://registry.npmjs.org/execon/-/execon-1.2.9.tgz", + "integrity": "sha1-bbETM9zIJPHxPnMX/tDZSi8mSR8=", + "dev": true + }, + "exit-hook": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/exit-hook/-/exit-hook-1.1.1.tgz", + "integrity": "sha1-8FyiM7SMBdVP/wd2XfhQfpXAL/g=", + "dev": true + }, + "fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", + "dev": true + }, + "figures": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/figures/-/figures-1.7.0.tgz", + "integrity": "sha1-y+Hjr/zxzUS4DK3+0o3Hk6lwHS4=", + "dev": true, + "requires": { + "escape-string-regexp": "^1.0.5", + "object-assign": "^4.1.0" + } + }, + "file-entry-cache": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-2.0.0.tgz", + "integrity": "sha1-w5KZDD5oR4PYOLjISkXYoEhFg2E=", + "dev": true, + "requires": { + "flat-cache": "^1.2.1", + "object-assign": "^4.0.1" + } + }, + "find-up": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-1.1.2.tgz", + "integrity": "sha1-ay6YIrGizgpgq2TWEOzK1TyyTQ8=", + "dev": true, + "requires": { + "path-exists": "^2.0.0", + "pinkie-promise": "^2.0.0" + } + }, + "flat-cache": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-1.3.0.tgz", + "integrity": "sha1-0wMLMrOBVPTjt+nHCfSQ9++XxIE=", + "dev": true, + "requires": { + "circular-json": "^0.3.1", + "del": "^2.0.2", + "graceful-fs": "^4.1.2", + "write": "^0.2.1" + } + }, + "for-each": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz", + "integrity": "sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==", + "dev": true, + "requires": { + "is-callable": "^1.1.3" + } + }, + "foreach": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/foreach/-/foreach-2.0.5.tgz", + "integrity": "sha1-C+4AUBiusmDQo6865ljdATbsG5k=", + "dev": true + }, + "fs-extra": { + "version": "0.26.7", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-0.26.7.tgz", + "integrity": "sha1-muH92UiXeY7at20JGM9C0MMYT6k=", + "dev": true, + "requires": { + "graceful-fs": "^4.1.2", + "jsonfile": "^2.1.0", + "klaw": "^1.0.0", + "path-is-absolute": "^1.0.0", + "rimraf": "^2.2.8" + } + }, + "fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", + "dev": true + }, + "function-bind": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", + "dev": true + }, + "generate-function": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/generate-function/-/generate-function-2.0.0.tgz", + "integrity": "sha1-aFj+fAlpt9TpCTM3ZHrHn2DfvnQ=", + "dev": true + }, + "generate-object-property": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/generate-object-property/-/generate-object-property-1.2.0.tgz", + "integrity": "sha1-nA4cQDCM6AT0eDYYuTf6iPmdUNA=", + "dev": true, + "requires": { + "is-property": "^1.0.0" + } + }, + "github-release-from-changelog": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/github-release-from-changelog/-/github-release-from-changelog-1.3.2.tgz", + "integrity": "sha512-3Cj5zazWfk9heJzBSXxBsh9xQSYt8ZOseresfNeHewFVC2g0Au9181xob9eXTv4hRysi9k3gRVCXOUmBH+J2bA==", + "dev": true, + "requires": { + "grizzly": "^3.0.3", + "minimist": "^1.2.0" + }, + "dependencies": { + "minimist": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", + "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", + "dev": true + } + } + }, + "glob": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz", + "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==", + "dev": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "globals": { + "version": "9.18.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-9.18.0.tgz", + "integrity": "sha512-S0nG3CLEQiY/ILxqtztTWH/3iRRdyBLw6KMDxnKMchrtbj2OFmehVh0WUCfW3DUrIgx/qFrJPICrq4Z4sTR9UQ==", + "dev": true + }, + "globby": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-5.0.0.tgz", + "integrity": "sha1-69hGZ8oNuzMLmbz8aOrCvFQ3Dg0=", + "dev": true, + "requires": { + "array-union": "^1.0.1", + "arrify": "^1.0.0", + "glob": "^7.0.3", + "object-assign": "^4.0.1", + "pify": "^2.0.0", + "pinkie-promise": "^2.0.0" + } + }, + "graceful-fs": { + "version": "4.1.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.11.tgz", + "integrity": "sha1-Dovf5NHduIVNZOBOp8AOKgJuVlg=", + "dev": true + }, + "grizzly": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/grizzly/-/grizzly-3.0.3.tgz", + "integrity": "sha512-IGcSYOg8W75e1/92oHy1RgO4fiWxWYi94C5nwjJwTe5usRx241LkqiO4923LVLwkon7ro69ZKcCbI4ox25pDOw==", + "dev": true, + "requires": { + "@octokit/rest": "^14.0.7", + "checkup": "^1.3.0", + "debug": "^3.0.0", + "execon": "^1.2.0", + "minimist": "^1.2.0", + "readjson": "^1.1.0" + }, + "dependencies": { + "debug": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", + "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "minimist": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", + "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", + "dev": true + } + } + }, + "has": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", + "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "dev": true, + "requires": { + "function-bind": "^1.1.1" + } + }, + "has-ansi": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", + "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=", + "dev": true, + "requires": { + "ansi-regex": "^2.0.0" + } + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=" + }, + "ignore": { + "version": "3.3.10", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-3.3.10.tgz", + "integrity": "sha512-Pgs951kaMm5GXP7MOvxERINe3gsaVjUWFm+UZPSq9xYriQAksyhg0csnS0KXSNRD5NmNdapXEpjxG49+AKh/ug==", + "dev": true + }, + "imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", + "dev": true + }, + "inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "dev": true, + "requires": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "inherits": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", + "dev": true + }, + "inquirer": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-0.12.0.tgz", + "integrity": "sha1-HvK/1jUE3wvHV4X/+MLEHfEvB34=", + "dev": true, + "requires": { + "ansi-escapes": "^1.1.0", + "ansi-regex": "^2.0.0", + "chalk": "^1.0.0", + "cli-cursor": "^1.0.1", + "cli-width": "^2.0.0", + "figures": "^1.3.5", + "lodash": "^4.3.0", + "readline2": "^1.0.1", + "run-async": "^0.1.0", + "rx-lite": "^3.1.2", + "string-width": "^1.0.1", + "strip-ansi": "^3.0.0", + "through": "^2.3.6" + }, + "dependencies": { + "ansi-styles": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", + "dev": true + }, + "chalk": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", + "dev": true, + "requires": { + "ansi-styles": "^2.2.1", + "escape-string-regexp": "^1.0.2", + "has-ansi": "^2.0.0", + "strip-ansi": "^3.0.0", + "supports-color": "^2.0.0" + } + }, + "supports-color": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", + "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", + "dev": true + } + } + }, + "interpret": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.1.0.tgz", + "integrity": "sha1-ftGxQQxqDg94z5XTuEQMY/eLhhQ=", + "dev": true + }, + "is-array-buffer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-1.0.1.tgz", + "integrity": "sha512-lj035IqdAwsodoRGs9/8+Kn3HPoz9CTuZbcw63afugWonxigvUVeHY5d6Ve1O+s1N3RCk7txo2TIWQLbU0SuNA==", + "dev": true + }, + "is-callable": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.1.4.tgz", + "integrity": "sha512-r5p9sxJjYnArLjObpjA4xu5EKI3CuKHkJXMhT7kwbpUyIFD1n5PMAsoPvWnvtZiNz7LjkYDRZhd7FlI0eMijEA==", + "dev": true + }, + "is-date-object": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.1.tgz", + "integrity": "sha1-mqIOtq7rv/d/vTPnTKAbM1gdOhY=", + "dev": true + }, + "is-fullwidth-code-point": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", + "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", + "dev": true, + "requires": { + "number-is-nan": "^1.0.0" + } + }, + "is-my-ip-valid": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-my-ip-valid/-/is-my-ip-valid-1.0.0.tgz", + "integrity": "sha512-gmh/eWXROncUzRnIa1Ubrt5b8ep/MGSnfAUI3aRp+sqTCs1tv1Isl8d8F6JmkN3dXKc3ehZMrtiPN9eL03NuaQ==", + "dev": true + }, + "is-my-json-valid": { + "version": "2.18.0", + "resolved": "https://registry.npmjs.org/is-my-json-valid/-/is-my-json-valid-2.18.0.tgz", + "integrity": "sha512-DWT87JHCSdCPCxbqBpS6Z2ajAt+MvrJq8I4xrpQljCvzODO5/fiquBp20a3sN6yCJvFbCRyYvJOHjpzkPTKJyA==", + "dev": true, + "requires": { + "generate-function": "^2.0.0", + "generate-object-property": "^1.1.0", + "is-my-ip-valid": "^1.0.0", + "jsonpointer": "^4.0.0", + "xtend": "^4.0.0" + } + }, + "is-path-cwd": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-path-cwd/-/is-path-cwd-1.0.0.tgz", + "integrity": "sha1-0iXsIxMuie3Tj9p2dHLmLmXxEG0=", + "dev": true + }, + "is-path-in-cwd": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-path-in-cwd/-/is-path-in-cwd-1.0.1.tgz", + "integrity": "sha512-FjV1RTW48E7CWM7eE/J2NJvAEEVektecDBVBE5Hh3nM1Jd0kvhHtX68Pr3xsDf857xt3Y4AkwVULK1Vku62aaQ==", + "dev": true, + "requires": { + "is-path-inside": "^1.0.0" + } + }, + "is-path-inside": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-1.0.1.tgz", + "integrity": "sha1-jvW33lBDej/cprToZe96pVy0gDY=", + "dev": true, + "requires": { + "path-is-inside": "^1.0.1" + } + }, + "is-property": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-property/-/is-property-1.0.2.tgz", + "integrity": "sha1-V/4cTkhHTt1lsJkR8msc1Ald2oQ=", + "dev": true + }, + "is-regex": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.0.4.tgz", + "integrity": "sha1-VRdIm1RwkbCTDglWVM7SXul+lJE=", + "dev": true, + "requires": { + "has": "^1.0.1" + } + }, + "is-resolvable": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-resolvable/-/is-resolvable-1.1.0.tgz", + "integrity": "sha512-qgDYXFSR5WvEfuS5dMj6oTMEbrrSaM0CrFk2Yiq/gXnBvD9pMa2jGXxyhGLfvhZpuMZe18CJpFxAt3CRs42NMg==", + "dev": true + }, + "is-stream": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", + "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=", + "dev": true + }, + "is-symbol": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.1.tgz", + "integrity": "sha1-PMWfAAJRlLarLjjbrmaJJWtmBXI=", + "dev": true + }, + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", + "dev": true + }, + "isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", + "dev": true + }, + "js-tokens": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-3.0.2.tgz", + "integrity": "sha1-mGbfOVECEw449/mWvOtlRDIJwls=", + "dev": true + }, + "js-yaml": { + "version": "3.12.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.12.0.tgz", + "integrity": "sha512-PIt2cnwmPfL4hKNwqeiuz4bKfnzHTBv6HyVgjahA6mPLwPDzjDWrplJBMjHUFxku/N3FlmrbyPclad+I+4mJ3A==", + "dev": true, + "requires": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + } + }, + "json-stable-stringify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify/-/json-stable-stringify-1.0.1.tgz", + "integrity": "sha1-mnWdOcXy/1A/1TAGRu1EX4jE+a8=", + "dev": true, + "requires": { + "jsonify": "~0.0.0" + } + }, + "jsonfile": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-2.4.0.tgz", + "integrity": "sha1-NzaitCi4e72gzIO1P6PWM6NcKug=", + "dev": true, + "requires": { + "graceful-fs": "^4.1.6" + } + }, + "jsonify": { + "version": "0.0.0", + "resolved": "https://registry.npmjs.org/jsonify/-/jsonify-0.0.0.tgz", + "integrity": "sha1-LHS27kHZPKUbe1qu6PUDYx0lKnM=", + "dev": true + }, + "jsonpointer": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/jsonpointer/-/jsonpointer-4.0.1.tgz", + "integrity": "sha1-T9kss04OnbPInIYi7PUfm5eMbLk=", + "dev": true + }, + "klaw": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/klaw/-/klaw-1.3.1.tgz", + "integrity": "sha1-QIhDO0azsbolnXh4XY6W9zugJDk=", + "dev": true, + "requires": { + "graceful-fs": "^4.1.9" + } + }, + "levn": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", + "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=", + "dev": true, + "requires": { + "prelude-ls": "~1.1.2", + "type-check": "~0.3.2" + } + }, + "lodash": { + "version": "4.17.10", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.10.tgz", + "integrity": "sha512-UejweD1pDoXu+AD825lWwp4ZGtSwgnpZxb3JDViD7StjQz+Nb/6l093lx4OQ0foGWNRoc19mWy7BzL+UAK2iVg==", + "dev": true + }, + "lodash.cond": { + "version": "4.5.2", + "resolved": "https://registry.npmjs.org/lodash.cond/-/lodash.cond-4.5.2.tgz", + "integrity": "sha1-9HGh2khr5g9quVXRcRVSPdHSVdU=", + "dev": true + }, + "lodash.endswith": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/lodash.endswith/-/lodash.endswith-4.2.1.tgz", + "integrity": "sha1-/tWawXOO0+I27dcGTsRWRIs3vAk=", + "dev": true + }, + "lodash.find": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/lodash.find/-/lodash.find-4.6.0.tgz", + "integrity": "sha1-ywcE1Hq3F4n/oN6Ll92Sb7iLE7E=", + "dev": true + }, + "lodash.findindex": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/lodash.findindex/-/lodash.findindex-4.6.0.tgz", + "integrity": "sha1-oyRd7mH7m24GJLU1ElYku2nBEQY=", + "dev": true + }, + "lru-cache": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.3.tgz", + "integrity": "sha512-fFEhvcgzuIoJVUF8fYr5KR0YqxD238zgObTps31YdADwPPAp82a4M8TrckkWyx7ekNlf9aBcVn81cFwwXngrJA==", + "dev": true, + "requires": { + "pseudomap": "^1.0.2", + "yallist": "^2.1.2" + } + }, + "minimatch": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", + "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "dev": true, + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "minimist": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", + "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=", + "dev": true + }, + "mkdirp": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", + "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", + "dev": true, + "requires": { + "minimist": "0.0.8" + } + }, + "mount-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/mount-point/-/mount-point-3.0.0.tgz", + "integrity": "sha1-Zly57evoDREOZY21bDHQrvUaj5c=", + "dev": true, + "requires": { + "@sindresorhus/df": "^1.0.1", + "pify": "^2.3.0", + "pinkie-promise": "^2.0.1" + }, + "dependencies": { + "@sindresorhus/df": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@sindresorhus/df/-/df-1.0.1.tgz", + "integrity": "sha1-xptm9S9vzdKHyAffIQMF2694UA0=", + "dev": true + } + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + }, + "mute-stream": { + "version": "0.0.5", + "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.5.tgz", + "integrity": "sha1-j7+rsKmKJT0xhDMfno3rc3L6xsA=", + "dev": true + }, + "natural-compare": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=", + "dev": true + }, + "next-tick": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/next-tick/-/next-tick-1.0.0.tgz", + "integrity": "sha1-yobR/ogoFpsBICCOPchCS524NCw=", + "dev": true + }, + "npm-run-path": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-1.0.0.tgz", + "integrity": "sha1-9cMr9ZX+ga6Sfa7FLoL4sACsPI8=", + "dev": true, + "requires": { + "path-key": "^1.0.0" + } + }, + "npmpub": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/npmpub/-/npmpub-3.1.0.tgz", + "integrity": "sha1-c0OoAf+xi/0s7CM1hLkUWa5O4Uk=", + "dev": true, + "requires": { + "chalk": "^1.1.1", + "github-release-from-changelog": "^1.1.1", + "minimist": "^1.2.0", + "shelljs": "^0.5.3", + "trash": "^3.4.1" + }, + "dependencies": { + "ansi-styles": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", + "dev": true + }, + "chalk": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", + "dev": true, + "requires": { + "ansi-styles": "^2.2.1", + "escape-string-regexp": "^1.0.2", + "has-ansi": "^2.0.0", + "strip-ansi": "^3.0.0", + "supports-color": "^2.0.0" + } + }, + "minimist": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", + "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", + "dev": true + }, + "shelljs": { + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/shelljs/-/shelljs-0.5.3.tgz", + "integrity": "sha1-xUmCuZbHbvDB5rWfvcWCX1txMRM=", + "dev": true + }, + "supports-color": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", + "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", + "dev": true + } + } + }, + "number-is-nan": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", + "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=", + "dev": true + }, + "object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", + "dev": true + }, + "object-inspect": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.6.0.tgz", + "integrity": "sha512-GJzfBZ6DgDAmnuaM3104jR4s1Myxr3Y3zfIyN4z3UdqN69oSRacNK8UhnobDdC+7J2AHCjGwxQubNJfE70SXXQ==", + "dev": true + }, + "object-keys": { + "version": "1.0.12", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.0.12.tgz", + "integrity": "sha512-FTMyFUm2wBcGHnH2eXmz7tC6IwlqQZ6mVZ+6dm6vZ4IQIHjs6FdNsQBuKGPuUUUY6NfJw2PshC08Tn6LzLDOag==", + "dev": true + }, + "once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "dev": true, + "requires": { + "wrappy": "1" + } + }, + "onetime": { + "version": "1.1.0", + "resolved": "http://registry.npmjs.org/onetime/-/onetime-1.1.0.tgz", + "integrity": "sha1-ofeDj4MUxRbwXs78vEzP4EtO14k=", + "dev": true + }, + "optionator": { + "version": "0.8.2", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.2.tgz", + "integrity": "sha1-NkxeQJ0/TWMB1sC0wFu6UBgK62Q=", + "dev": true, + "requires": { + "deep-is": "~0.1.3", + "fast-levenshtein": "~2.0.4", + "levn": "~0.3.0", + "prelude-ls": "~1.1.2", + "type-check": "~0.3.2", + "wordwrap": "~1.0.0" + } + }, + "os-homedir": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz", + "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=", + "dev": true + }, + "path-exists": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-2.1.0.tgz", + "integrity": "sha1-D+tsZPD8UY2adU3V77YscCJ2H0s=", + "dev": true, + "requires": { + "pinkie-promise": "^2.0.0" + } + }, + "path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", + "dev": true + }, + "path-is-inside": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz", + "integrity": "sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM=", + "dev": true + }, + "path-key": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-1.0.0.tgz", + "integrity": "sha1-XVPVeAGWRsDWiADbThRua9wqx68=", + "dev": true + }, + "path-parse": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz", + "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==", + "dev": true + }, + "pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", + "dev": true + }, + "pinkie": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz", + "integrity": "sha1-clVrgM+g1IqXToDnckjoDtT3+HA=", + "dev": true + }, + "pinkie-promise": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz", + "integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=", + "dev": true, + "requires": { + "pinkie": "^2.0.0" + } + }, + "pkg-dir": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-1.0.0.tgz", + "integrity": "sha1-ektQio1bstYp1EcFb/TpyTFM89Q=", + "dev": true, + "requires": { + "find-up": "^1.0.0" + } + }, + "pkg-up": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/pkg-up/-/pkg-up-1.0.0.tgz", + "integrity": "sha1-Pgj7RhUlxEIWJKM7n35tCvWwWiY=", + "dev": true, + "requires": { + "find-up": "^1.0.0" + } + }, + "pluralize": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/pluralize/-/pluralize-1.2.1.tgz", + "integrity": "sha1-0aIUg/0iu0HlihL6NCGCMUCJfEU=", + "dev": true + }, + "postcss": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.2.tgz", + "integrity": "sha512-fmaUY5370keLUTx+CnwRxtGiuFTcNBLQBqr1oE3WZ/euIYmGAo0OAgOhVJ3ByDnVmOR3PK+0V9VebzfjRIUcqw==", + "requires": { + "chalk": "^2.4.1", + "source-map": "^0.6.1", + "supports-color": "^5.4.0" + } + }, + "prelude-ls": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", + "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=", + "dev": true + }, + "process-nextick-args": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.0.tgz", + "integrity": "sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw==", + "dev": true + }, + "progress": { + "version": "1.1.8", + "resolved": "https://registry.npmjs.org/progress/-/progress-1.1.8.tgz", + "integrity": "sha1-4mDHj2Fhzdmw5WzD4Khd4Xx6V74=", + "dev": true + }, + "pseudomap": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", + "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=", + "dev": true + }, + "readable-stream": { + "version": "2.3.6", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", + "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", + "dev": true, + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "readjson": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/readjson/-/readjson-1.1.4.tgz", + "integrity": "sha512-H4dRk2S67w3HtE1apnw5wlHpN9qkJ0pen0AcEvyAfnrPfskZIyUOYLXpfN6olDQZI+eUlxg0Yo4lJ2bymujOUA==", + "dev": true, + "requires": { + "try-catch": "^2.0.0" + } + }, + "readline2": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/readline2/-/readline2-1.0.1.tgz", + "integrity": "sha1-QQWWCP/BVHV7cV2ZidGZ/783LjU=", + "dev": true, + "requires": { + "code-point-at": "^1.0.0", + "is-fullwidth-code-point": "^1.0.0", + "mute-stream": "0.0.5" + } + }, + "rechoir": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.6.2.tgz", + "integrity": "sha1-hSBLVNuoLVdC4oyWdW70OvUOM4Q=", + "dev": true, + "requires": { + "resolve": "^1.1.6" + } + }, + "require-uncached": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/require-uncached/-/require-uncached-1.0.3.tgz", + "integrity": "sha1-Tg1W1slmL9MeQwEcS5WqSZVUIdM=", + "dev": true, + "requires": { + "caller-path": "^0.1.0", + "resolve-from": "^1.0.0" + } + }, + "resolve": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.8.1.tgz", + "integrity": "sha512-AicPrAC7Qu1JxPCZ9ZgCZlY35QgFnNqc+0LtbRNxnVw4TXvjQ72wnuL9JQcEBgXkI9JM8MsT9kaQoHcpCRJOYA==", + "dev": true, + "requires": { + "path-parse": "^1.0.5" + } + }, + "resolve-from": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-1.0.1.tgz", + "integrity": "sha1-Jsv+k10a7uq7Kbw/5a6wHpPUQiY=", + "dev": true + }, + "restore-cursor": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-1.0.1.tgz", + "integrity": "sha1-NGYfRohjJ/7SmRR5FSJS35LapUE=", + "dev": true, + "requires": { + "exit-hook": "^1.0.0", + "onetime": "^1.0.0" + } + }, + "resumer": { + "version": "0.0.0", + "resolved": "https://registry.npmjs.org/resumer/-/resumer-0.0.0.tgz", + "integrity": "sha1-8ej0YeQGS6Oegq883CqMiT0HZ1k=", + "dev": true, + "requires": { + "through": "~2.3.4" + } + }, + "rimraf": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.2.tgz", + "integrity": "sha512-lreewLK/BlghmxtfH36YYVg1i8IAce4TI7oao75I1g245+6BctqTVQiBP3YUJ9C6DQOXJmkYR9X9fCLtCOJc5w==", + "dev": true, + "requires": { + "glob": "^7.0.5" + } + }, + "run-applescript": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/run-applescript/-/run-applescript-2.1.0.tgz", + "integrity": "sha1-O/8sz5W2zqy0lyPlUPADcdYYUQ0=", + "dev": true, + "requires": { + "pify": "^2.2.0", + "pinkie-promise": "^2.0.0" + } + }, + "run-async": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/run-async/-/run-async-0.1.0.tgz", + "integrity": "sha1-yK1KXhEGYeQCp9IbUw4AnyX444k=", + "dev": true, + "requires": { + "once": "^1.3.0" + } + }, + "rx-lite": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/rx-lite/-/rx-lite-3.1.2.tgz", + "integrity": "sha1-Gc5QLKVyZl87ZHsQk5+X/RYV8QI=", + "dev": true + }, + "safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true + }, + "shelljs": { + "version": "0.7.8", + "resolved": "https://registry.npmjs.org/shelljs/-/shelljs-0.7.8.tgz", + "integrity": "sha1-3svPh0sNHl+3LhSxZKloMEjprLM=", + "dev": true, + "requires": { + "glob": "^7.0.0", + "interpret": "^1.0.0", + "rechoir": "^0.6.2" + } + }, + "slice-ansi": { + "version": "0.0.4", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-0.0.4.tgz", + "integrity": "sha1-7b+JA/ZvfOL46v1s7tZeJkyDGzU=", + "dev": true + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" + }, + "sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", + "dev": true + }, + "string-width": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", + "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", + "dev": true, + "requires": { + "code-point-at": "^1.0.0", + "is-fullwidth-code-point": "^1.0.0", + "strip-ansi": "^3.0.0" + } + }, + "string.prototype.trim": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.1.2.tgz", + "integrity": "sha1-0E3iyJ4Tf019IG8Ia17S+ua+jOo=", + "dev": true, + "requires": { + "define-properties": "^1.1.2", + "es-abstract": "^1.5.0", + "function-bind": "^1.0.2" + } + }, + "string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dev": true, + "requires": { + "safe-buffer": "~5.1.0" + } + }, + "strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "dev": true, + "requires": { + "ansi-regex": "^2.0.0" + } + }, + "strip-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", + "dev": true + }, + "strip-eof": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz", + "integrity": "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8=", + "dev": true + }, + "strip-json-comments": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", + "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=", + "dev": true + }, + "supports-color": { + "version": "5.4.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.4.0.tgz", + "integrity": "sha512-zjaXglF5nnWpsq470jSv6P9DwPvgLkuapYmfDm3JWOm0vkNTVF2tI4UrN2r6jH1qM/uc/WtxYY1hYoA2dOKj5w==", + "requires": { + "has-flag": "^3.0.0" + } + }, + "table": { + "version": "3.8.3", + "resolved": "https://registry.npmjs.org/table/-/table-3.8.3.tgz", + "integrity": "sha1-K7xULw/amGGnVdOUf+/Ys/UThV8=", + "dev": true, + "requires": { + "ajv": "^4.7.0", + "ajv-keywords": "^1.0.0", + "chalk": "^1.1.1", + "lodash": "^4.0.0", + "slice-ansi": "0.0.4", + "string-width": "^2.0.0" + }, + "dependencies": { + "ansi-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", + "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", + "dev": true + }, + "ansi-styles": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", + "dev": true + }, + "chalk": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", + "dev": true, + "requires": { + "ansi-styles": "^2.2.1", + "escape-string-regexp": "^1.0.2", + "has-ansi": "^2.0.0", + "strip-ansi": "^3.0.0", + "supports-color": "^2.0.0" + } + }, + "is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", + "dev": true + }, + "string-width": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", + "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", + "dev": true, + "requires": { + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^4.0.0" + }, + "dependencies": { + "strip-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", + "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", + "dev": true, + "requires": { + "ansi-regex": "^3.0.0" + } + } + } + }, + "supports-color": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", + "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", + "dev": true + } + } + }, + "tape": { + "version": "4.9.1", + "resolved": "https://registry.npmjs.org/tape/-/tape-4.9.1.tgz", + "integrity": "sha512-6fKIXknLpoe/Jp4rzHKFPpJUHDHDqn8jus99IfPnHIjyz78HYlefTGD3b5EkbQzuLfaEvmfPK3IolLgq2xT3kw==", + "dev": true, + "requires": { + "deep-equal": "~1.0.1", + "defined": "~1.0.0", + "for-each": "~0.3.3", + "function-bind": "~1.1.1", + "glob": "~7.1.2", + "has": "~1.0.3", + "inherits": "~2.0.3", + "minimist": "~1.2.0", + "object-inspect": "~1.6.0", + "resolve": "~1.7.1", + "resumer": "~0.0.0", + "string.prototype.trim": "~1.1.2", + "through": "~2.3.8" + }, + "dependencies": { + "minimist": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", + "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", + "dev": true + }, + "resolve": { + "version": "1.7.1", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.7.1.tgz", + "integrity": "sha512-c7rwLofp8g1U+h1KNyHL/jicrKg1Ek4q+Lr33AL65uZTinUZHe30D5HlyN5V9NW0JX1D5dXQ4jqW5l7Sy/kGfw==", + "dev": true, + "requires": { + "path-parse": "^1.0.5" + } + } + } + }, + "text-table": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", + "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=", + "dev": true + }, + "through": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", + "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=", + "dev": true + }, + "trash": { + "version": "3.4.2", + "resolved": "https://registry.npmjs.org/trash/-/trash-3.4.2.tgz", + "integrity": "sha1-+wQiUvwmoCInaVCiuw7Om5QF6xk=", + "dev": true, + "requires": { + "escape-string-applescript": "^1.0.0", + "fs-extra": "^0.26.2", + "globby": "^4.0.0", + "path-exists": "^2.0.0", + "pify": "^2.3.0", + "pinkie-promise": "^2.0.0", + "run-applescript": "^2.0.0", + "uuid": "^2.0.1", + "xdg-trashdir": "^2.0.0" + }, + "dependencies": { + "glob": { + "version": "6.0.4", + "resolved": "https://registry.npmjs.org/glob/-/glob-6.0.4.tgz", + "integrity": "sha1-DwiGD2oVUSey+t1PnOJLGqtuTSI=", + "dev": true, + "requires": { + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "2 || 3", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "globby": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-4.1.0.tgz", + "integrity": "sha1-CA9UVJ7BuCpsYOYx/ILhIR2+lfg=", + "dev": true, + "requires": { + "array-union": "^1.0.1", + "arrify": "^1.0.0", + "glob": "^6.0.1", + "object-assign": "^4.0.1", + "pify": "^2.0.0", + "pinkie-promise": "^2.0.0" + } + } + } + }, + "try-catch": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/try-catch/-/try-catch-2.0.0.tgz", + "integrity": "sha512-RPXpVjsbtWgymwGq5F/OWDFsjEzdvzwHFaMjWWW6f/p6+uk/N7YSKJHQfIfGqITfj8qH4cBqCLMnhKZBaKk7Kg==", + "dev": true + }, + "type-check": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", + "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=", + "dev": true, + "requires": { + "prelude-ls": "~1.1.2" + } + }, + "typedarray": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", + "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=", + "dev": true + }, + "url-template": { + "version": "2.0.8", + "resolved": "https://registry.npmjs.org/url-template/-/url-template-2.0.8.tgz", + "integrity": "sha1-/FZaPMy/93MMd19WQflVV5FDnyE=", + "dev": true + }, + "user-home": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/user-home/-/user-home-2.0.0.tgz", + "integrity": "sha1-nHC/2Babwdy/SGBODwS4tJzenp8=", + "dev": true, + "requires": { + "os-homedir": "^1.0.0" + } + }, + "util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=", + "dev": true + }, + "uuid": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-2.0.3.tgz", + "integrity": "sha1-Z+LoY3lyFVMN/zGOW/nc6/1Hsho=", + "dev": true + }, + "which": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", + "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "dev": true, + "requires": { + "isexe": "^2.0.0" + } + }, + "wordwrap": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", + "integrity": "sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus=", + "dev": true + }, + "wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", + "dev": true + }, + "write": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/write/-/write-0.2.1.tgz", + "integrity": "sha1-X8A4KOJkzqP+kUVUdvejxWbLB1c=", + "dev": true, + "requires": { + "mkdirp": "^0.5.1" + } + }, + "xdg-basedir": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/xdg-basedir/-/xdg-basedir-2.0.0.tgz", + "integrity": "sha1-7byQPMOF/ARSPZZqM1UEtVBNG9I=", + "dev": true, + "requires": { + "os-homedir": "^1.0.0" + } + }, + "xdg-trashdir": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/xdg-trashdir/-/xdg-trashdir-2.1.1.tgz", + "integrity": "sha512-KcVhPaOu2ZurYNHSRTf1+ZHORkTZGCQ+u0JHN17QixRISJq4pXOnjt/lQcehvtHL5QAKhSzKgyjrcNnPdkPBHA==", + "dev": true, + "requires": { + "@sindresorhus/df": "^2.1.0", + "mount-point": "^3.0.0", + "pify": "^2.2.0", + "user-home": "^2.0.0", + "xdg-basedir": "^2.0.0" + } + }, + "xtend": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz", + "integrity": "sha1-pcbVMr5lbiPbgg77lDofBJmNY68=", + "dev": true + }, + "yallist": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", + "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=", + "dev": true + } + } +} diff --git a/package.json b/package.json index 9bf0f8279d..a1c2654c24 100644 --- a/package.json +++ b/package.json @@ -18,8 +18,11 @@ "files": [ "index.js" ], + "engines": { + "node": ">=6.0.0" + }, "dependencies": { - "postcss": "^6.0.1" + "postcss": "^7.0.2" }, "devDependencies": { "eslint": "^3.19.0", diff --git a/test/index.js b/test/index.js index 043a83d8ce..21132fd102 100755 --- a/test/index.js +++ b/test/index.js @@ -21,7 +21,7 @@ function compareFixtures(t, name, msg, opts, postcssOpts) { .process(read(postcssOpts.from), postcssOpts) var actual = result.css var expected = read(filename("fixtures/" + name + ".expected")) - fs.writeFile(filename("fixtures/" + name + ".actual"), actual) + fs.writeFileSync(filename("fixtures/" + name + ".actual"), actual) t.equal(actual.trim(), expected.trim(), msg) return result From 4f905cbb073c04d30597d954f5e29b7c7ae6c1a9 Mon Sep 17 00:00:00 2001 From: Pascal Duez Date: Mon, 13 Aug 2018 14:38:07 +0200 Subject: [PATCH 658/795] Use PostCSS 7 * Add package-lock file * Upgrade PostCSS to version 7 --- .travis.yml | 4 +- package-lock.json | 2344 +++++++++++++++++++++++++++++++++++++++++++++ package.json | 5 +- 3 files changed, 2351 insertions(+), 2 deletions(-) create mode 100644 package-lock.json diff --git a/.travis.yml b/.travis.yml index 85242354aa..71c4fb1436 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,3 +1,5 @@ language: node_js node_js: - - 4 + - "6" + - "8" + - "stable" diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 0000000000..22ddfe2cf2 --- /dev/null +++ b/package-lock.json @@ -0,0 +1,2344 @@ +{ + "name": "postcss-color-rebeccapurple", + "version": "3.1.0", + "lockfileVersion": 1, + "requires": true, + "dependencies": { + "@octokit/rest": { + "version": "14.0.9", + "resolved": "https://registry.npmjs.org/@octokit/rest/-/rest-14.0.9.tgz", + "integrity": "sha512-irP9phKfTXEZIcW2R+VNCtGHZJrXMWmSYp6RRfFn4BtAqtDRXF5z9JxCEQlAhNBf6X1koNi5k49tIAAAEJNlVQ==", + "dev": true, + "requires": { + "before-after-hook": "^1.1.0", + "debug": "^3.1.0", + "is-array-buffer": "^1.0.0", + "is-stream": "^1.1.0", + "lodash": "^4.17.4", + "url-template": "^2.0.8" + }, + "dependencies": { + "debug": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", + "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "lodash": { + "version": "4.17.10", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.10.tgz", + "integrity": "sha512-UejweD1pDoXu+AD825lWwp4ZGtSwgnpZxb3JDViD7StjQz+Nb/6l093lx4OQ0foGWNRoc19mWy7BzL+UAK2iVg==", + "dev": true + } + } + }, + "@sindresorhus/df": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@sindresorhus/df/-/df-2.1.0.tgz", + "integrity": "sha1-0gjPJ+BvC7R20U197M19cm6ao4k=", + "dev": true, + "requires": { + "execa": "^0.2.2" + } + }, + "JSV": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/JSV/-/JSV-4.0.2.tgz", + "integrity": "sha1-0Hf2glVx+CEy+d/67Vh7QCn+/1c=", + "dev": true + }, + "ajv": { + "version": "5.5.2", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-5.5.2.tgz", + "integrity": "sha1-c7Xuyj+rZT49P5Qis0GtQiBdyWU=", + "dev": true, + "optional": true, + "requires": { + "co": "^4.6.0", + "fast-deep-equal": "^1.0.0", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.3.0" + } + }, + "ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", + "dev": true + }, + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "requires": { + "color-convert": "^1.9.0" + } + }, + "argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "dev": true, + "requires": { + "sprintf-js": "~1.0.2" + } + }, + "array-union": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-1.0.2.tgz", + "integrity": "sha1-mjRBDk9OPaI96jdb5b5w8kd47Dk=", + "dev": true, + "requires": { + "array-uniq": "^1.0.1" + } + }, + "array-uniq": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/array-uniq/-/array-uniq-1.0.3.tgz", + "integrity": "sha1-r2rId6Jcx/dOBYiUdThY39sk/bY=", + "dev": true + }, + "arrify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", + "integrity": "sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=", + "dev": true + }, + "asn1": { + "version": "0.2.4", + "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz", + "integrity": "sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==", + "dev": true, + "optional": true, + "requires": { + "safer-buffer": "~2.1.0" + } + }, + "assert-plus": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", + "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=", + "dev": true + }, + "async": { + "version": "0.2.10", + "resolved": "https://registry.npmjs.org/async/-/async-0.2.10.tgz", + "integrity": "sha1-trvgsGdLnXGXCMo43owjfLUmw9E=", + "dev": true + }, + "asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=", + "dev": true, + "optional": true + }, + "aws-sign2": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", + "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=", + "dev": true, + "optional": true + }, + "aws4": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.8.0.tgz", + "integrity": "sha512-ReZxvNHIOv88FlT7rxcXIIC0fPt4KZqZbOlivyWtXLt8ESx84zd3kMC6iK5jVeS2qt+g7ftS7ye4fi06X5rtRQ==", + "dev": true, + "optional": true + }, + "babel-runtime": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-runtime/-/babel-runtime-6.26.0.tgz", + "integrity": "sha1-llxwWGaOgrVde/4E/yM3vItWR/4=", + "dev": true, + "requires": { + "core-js": "^2.4.0", + "regenerator-runtime": "^0.11.0" + } + }, + "babylon": { + "version": "6.18.0", + "resolved": "https://registry.npmjs.org/babylon/-/babylon-6.18.0.tgz", + "integrity": "sha512-q/UEjfGJ2Cm3oKV71DJz9d25TPnq5rhBVL2Q4fA5wcC3jcrdn7+SssEybFIxwAvvP+YCsCYNKughoF33GxgycQ==", + "dev": true + }, + "balanced-match": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", + "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", + "dev": true + }, + "bcrypt-pbkdf": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", + "integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=", + "dev": true, + "optional": true, + "requires": { + "tweetnacl": "^0.14.3" + } + }, + "before-after-hook": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/before-after-hook/-/before-after-hook-1.1.0.tgz", + "integrity": "sha512-VOMDtYPwLbIncTxNoSzRyvaMxtXmLWLUqr8k5AfC1BzLk34HvBXaQX8snOwQZ4c0aX8aSERqtJSiI9/m2u5kuA==", + "dev": true + }, + "brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "buffer-from": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", + "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==", + "dev": true, + "optional": true + }, + "caseless": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", + "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=", + "dev": true, + "optional": true + }, + "chalk": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.1.tgz", + "integrity": "sha512-ObN6h1v2fTJSmUXoS3nMQ92LbDK9be4TV+6G+omQlGJFdcUX5heKi1LZ1YnRMIgwTLEj3E24bT6tYni50rlCfQ==", + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, + "checkup": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/checkup/-/checkup-1.3.0.tgz", + "integrity": "sha1-04ACdv6l0PJH/8lRvnjIsC+ODXY=", + "dev": true + }, + "cli": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/cli/-/cli-1.0.1.tgz", + "integrity": "sha1-IoF1NPJL+klQw01TLUjsvGIbjBQ=", + "dev": true, + "requires": { + "exit": "0.1.2", + "glob": "^7.1.1" + }, + "dependencies": { + "glob": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz", + "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==", + "dev": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + } + } + }, + "cli-table": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/cli-table/-/cli-table-0.3.1.tgz", + "integrity": "sha1-9TsFJmqLGguTSz0IIebi3FkUriM=", + "dev": true, + "requires": { + "colors": "1.0.3" + } + }, + "co": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", + "integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ=", + "dev": true, + "optional": true + }, + "color-convert": { + "version": "1.9.2", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.2.tgz", + "integrity": "sha512-3NUJZdhMhcdPn8vJ9v2UQJoH0qqoGUkYTgFEPZaPjEtwmmKUfNV46zZmgB2M5M4DCEQHMaCfWHCxiBflLm04Tg==", + "requires": { + "color-name": "1.1.1" + } + }, + "color-name": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.1.tgz", + "integrity": "sha1-SxQVMEz1ACjqgWQ2Q72C6gWANok=" + }, + "colors": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/colors/-/colors-1.0.3.tgz", + "integrity": "sha1-BDP0TYCWgP3rYO0mDxsMJi6CpAs=", + "dev": true + }, + "combined-stream": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.6.tgz", + "integrity": "sha1-cj599ugBrFYTETp+RFqbactjKBg=", + "dev": true, + "requires": { + "delayed-stream": "~1.0.0" + } + }, + "commander": { + "version": "2.9.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.9.0.tgz", + "integrity": "sha1-nJkJQXbhIkDLItbFFGCYQA/g99Q=", + "dev": true, + "requires": { + "graceful-readlink": ">= 1.0.0" + } + }, + "comment-parser": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/comment-parser/-/comment-parser-0.3.2.tgz", + "integrity": "sha1-PAPwd2uGo239mgosl8YwfzMggv4=", + "dev": true, + "requires": { + "readable-stream": "^2.0.4" + }, + "dependencies": { + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", + "dev": true + }, + "readable-stream": { + "version": "2.3.6", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", + "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", + "dev": true, + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dev": true, + "requires": { + "safe-buffer": "~5.1.0" + } + } + } + }, + "concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", + "dev": true + }, + "concat-stream": { + "version": "1.6.2", + "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz", + "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==", + "dev": true, + "optional": true, + "requires": { + "buffer-from": "^1.0.0", + "inherits": "^2.0.3", + "readable-stream": "^2.2.2", + "typedarray": "^0.0.6" + }, + "dependencies": { + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", + "dev": true, + "optional": true + }, + "readable-stream": { + "version": "2.3.6", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", + "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", + "dev": true, + "optional": true, + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dev": true, + "optional": true, + "requires": { + "safe-buffer": "~5.1.0" + } + } + } + }, + "console-browserify": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/console-browserify/-/console-browserify-1.1.0.tgz", + "integrity": "sha1-8CQcRXMKn8YyOyBtvzjtx0HQuxA=", + "dev": true, + "requires": { + "date-now": "^0.1.4" + } + }, + "core-js": { + "version": "2.5.7", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.5.7.tgz", + "integrity": "sha512-RszJCAxg/PP6uzXVXL6BsxSXx/B05oJAQ2vkJRjyjrEcNVycaqOmNb5OTxZPE3xa5gwZduqza6L9JOCenh/Ecw==", + "dev": true + }, + "core-util-is": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", + "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=", + "dev": true + }, + "cross-spawn-async": { + "version": "2.2.5", + "resolved": "https://registry.npmjs.org/cross-spawn-async/-/cross-spawn-async-2.2.5.tgz", + "integrity": "sha1-hF/wwINKPe2dFg2sptOQkGuyiMw=", + "dev": true, + "requires": { + "lru-cache": "^4.0.0", + "which": "^1.2.8" + } + }, + "cst": { + "version": "0.4.10", + "resolved": "https://registry.npmjs.org/cst/-/cst-0.4.10.tgz", + "integrity": "sha512-U5ETe1IOjq2h56ZcBE3oe9rT7XryCH6IKgPMv0L7sSk6w29yR3p5egCK0T3BDNHHV95OoUBgXsqiVG+3a900Ag==", + "dev": true, + "requires": { + "babel-runtime": "^6.9.2", + "babylon": "^6.8.1", + "source-map-support": "^0.4.0" + } + }, + "cycle": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/cycle/-/cycle-1.0.3.tgz", + "integrity": "sha1-IegLK+hYD5i0aPN5QwZisEbDStI=", + "dev": true + }, + "dashdash": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", + "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=", + "dev": true, + "optional": true, + "requires": { + "assert-plus": "^1.0.0" + } + }, + "date-now": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/date-now/-/date-now-0.1.4.tgz", + "integrity": "sha1-6vQ5/U1ISK105cx9vvIAZyueNFs=", + "dev": true + }, + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "optional": true, + "requires": { + "ms": "2.0.0" + } + }, + "deep-equal": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/deep-equal/-/deep-equal-1.0.1.tgz", + "integrity": "sha1-9dJgKStmDghO/0zbyfCK0yR0SLU=", + "dev": true + }, + "define-properties": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.2.tgz", + "integrity": "sha1-g6c/L+pWmJj7c3GTyPhzyvbUXJQ=", + "dev": true, + "requires": { + "foreach": "^2.0.5", + "object-keys": "^1.0.8" + } + }, + "defined": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/defined/-/defined-1.0.0.tgz", + "integrity": "sha1-yY2bzvdWdBiOEQlpFRGZ45sfppM=", + "dev": true + }, + "delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=", + "dev": true + }, + "dom-serializer": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-0.1.0.tgz", + "integrity": "sha1-BzxpdUbOB4DOI75KKOKT5AvDDII=", + "dev": true, + "requires": { + "domelementtype": "~1.1.1", + "entities": "~1.1.1" + }, + "dependencies": { + "domelementtype": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-1.1.3.tgz", + "integrity": "sha1-vSh3PiZCiBrsUVRJJCmcXNgiGFs=", + "dev": true + }, + "entities": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/entities/-/entities-1.1.1.tgz", + "integrity": "sha1-blwtClYhtdra7O+AuQ7ftc13cvA=", + "dev": true + } + } + }, + "domelementtype": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-1.3.0.tgz", + "integrity": "sha1-sXrtguirWeUt2cGbF1bg/BhyBMI=", + "dev": true + }, + "domhandler": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-2.3.0.tgz", + "integrity": "sha1-LeWaCCLVAn+r/28DLCsloqir5zg=", + "dev": true, + "requires": { + "domelementtype": "1" + } + }, + "domutils": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/domutils/-/domutils-1.5.1.tgz", + "integrity": "sha1-3NhIiib1Y9YQeeSMn3t+Mjc2gs8=", + "dev": true, + "requires": { + "dom-serializer": "0", + "domelementtype": "1" + } + }, + "ecc-jsbn": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", + "integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=", + "dev": true, + "optional": true, + "requires": { + "jsbn": "~0.1.0", + "safer-buffer": "^2.1.0" + } + }, + "entities": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-1.0.0.tgz", + "integrity": "sha1-sph6o4ITR/zeZCsk/fyeT7cSvyY=", + "dev": true + }, + "es-abstract": { + "version": "1.12.0", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.12.0.tgz", + "integrity": "sha512-C8Fx/0jFmV5IPoMOFPA9P9G5NtqW+4cOPit3MIuvR2t7Ag2K15EJTpxnHAYTzL+aYQJIESYeXZmDBfOBE1HcpA==", + "dev": true, + "requires": { + "es-to-primitive": "^1.1.1", + "function-bind": "^1.1.1", + "has": "^1.0.1", + "is-callable": "^1.1.3", + "is-regex": "^1.0.4" + } + }, + "es-to-primitive": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.1.1.tgz", + "integrity": "sha1-RTVSSKiJeQNLZ5Lhm7gfK3l13Q0=", + "dev": true, + "requires": { + "is-callable": "^1.1.1", + "is-date-object": "^1.0.1", + "is-symbol": "^1.0.1" + } + }, + "es6-promise": { + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.4.tgz", + "integrity": "sha512-/NdNZVJg+uZgtm9eS3O6lrOLYmQag2DjdEXuPaHlZ6RuVqgqaVZfgYCepEIKsLqwdQArOPtC3XzRLqGGfT8KQQ==", + "dev": true, + "optional": true + }, + "escape-string-applescript": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/escape-string-applescript/-/escape-string-applescript-1.0.0.tgz", + "integrity": "sha1-bxwilCRdgsY7wDM43BmpSqhCiJI=", + "dev": true + }, + "escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=" + }, + "esprima": { + "version": "2.7.3", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-2.7.3.tgz", + "integrity": "sha1-luO3DVd59q1JzQMmc9HDEnZ7pYE=", + "dev": true + }, + "estraverse": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.2.0.tgz", + "integrity": "sha1-De4/7TH81GlhjOc0IJn8GvoL2xM=", + "dev": true + }, + "execa": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/execa/-/execa-0.2.2.tgz", + "integrity": "sha1-4urUcsLDGq1vc/GslW7vReEjIMs=", + "dev": true, + "requires": { + "cross-spawn-async": "^2.1.1", + "npm-run-path": "^1.0.0", + "object-assign": "^4.0.1", + "path-key": "^1.0.0", + "strip-eof": "^1.0.0" + } + }, + "execon": { + "version": "1.2.9", + "resolved": "https://registry.npmjs.org/execon/-/execon-1.2.9.tgz", + "integrity": "sha1-bbETM9zIJPHxPnMX/tDZSi8mSR8=", + "dev": true + }, + "exit": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz", + "integrity": "sha1-BjJjj42HfMghB9MKD/8aF8uhzQw=", + "dev": true + }, + "extend": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", + "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", + "dev": true, + "optional": true + }, + "extract-zip": { + "version": "1.6.7", + "resolved": "https://registry.npmjs.org/extract-zip/-/extract-zip-1.6.7.tgz", + "integrity": "sha1-qEC0uK9kAyZMjbV/Txp0Mz74H+k=", + "dev": true, + "optional": true, + "requires": { + "concat-stream": "1.6.2", + "debug": "2.6.9", + "mkdirp": "0.5.1", + "yauzl": "2.4.1" + } + }, + "extsprintf": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", + "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=", + "dev": true + }, + "eyes": { + "version": "0.1.8", + "resolved": "https://registry.npmjs.org/eyes/-/eyes-0.1.8.tgz", + "integrity": "sha1-Ys8SAjTGg3hdkCNIqADvPgzCC8A=", + "dev": true + }, + "fast-deep-equal": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-1.1.0.tgz", + "integrity": "sha1-wFNHeBfIa1HaqFPIHgWbcz0CNhQ=", + "dev": true, + "optional": true + }, + "fast-json-stable-stringify": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz", + "integrity": "sha1-1RQsDK7msRifh9OnYREGT4bIu/I=", + "dev": true, + "optional": true + }, + "fd-slicer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.0.1.tgz", + "integrity": "sha1-i1vL2ewyfFBBv5qwI/1nUPEXfmU=", + "dev": true, + "optional": true, + "requires": { + "pend": "~1.2.0" + } + }, + "flatten": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/flatten/-/flatten-1.0.2.tgz", + "integrity": "sha1-2uRqnXj74lKSJYzB54CkHZXAN4I=" + }, + "for-each": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz", + "integrity": "sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==", + "dev": true, + "requires": { + "is-callable": "^1.1.3" + } + }, + "foreach": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/foreach/-/foreach-2.0.5.tgz", + "integrity": "sha1-C+4AUBiusmDQo6865ljdATbsG5k=", + "dev": true + }, + "forever-agent": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", + "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=", + "dev": true, + "optional": true + }, + "form-data": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.2.tgz", + "integrity": "sha1-SXBJi+YEwgwAXU9cI67NIda0kJk=", + "dev": true, + "optional": true, + "requires": { + "asynckit": "^0.4.0", + "combined-stream": "1.0.6", + "mime-types": "^2.1.12" + } + }, + "fs-extra": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-1.0.0.tgz", + "integrity": "sha1-zTzl9+fLYUWIP8rjGR6Yd/hYeVA=", + "dev": true, + "optional": true, + "requires": { + "graceful-fs": "^4.1.2", + "jsonfile": "^2.1.0", + "klaw": "^1.0.0" + } + }, + "fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", + "dev": true + }, + "function-bind": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", + "dev": true + }, + "getpass": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", + "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=", + "dev": true, + "optional": true, + "requires": { + "assert-plus": "^1.0.0" + } + }, + "github-release-from-changelog": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/github-release-from-changelog/-/github-release-from-changelog-1.3.2.tgz", + "integrity": "sha512-3Cj5zazWfk9heJzBSXxBsh9xQSYt8ZOseresfNeHewFVC2g0Au9181xob9eXTv4hRysi9k3gRVCXOUmBH+J2bA==", + "dev": true, + "requires": { + "grizzly": "^3.0.3", + "minimist": "^1.2.0" + }, + "dependencies": { + "minimist": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", + "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", + "dev": true + } + } + }, + "glob": { + "version": "5.0.15", + "resolved": "https://registry.npmjs.org/glob/-/glob-5.0.15.tgz", + "integrity": "sha1-G8k2ueAvSmA/zCIuz3Yz0wuLk7E=", + "dev": true, + "requires": { + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "2 || 3", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "globby": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-4.1.0.tgz", + "integrity": "sha1-CA9UVJ7BuCpsYOYx/ILhIR2+lfg=", + "dev": true, + "requires": { + "array-union": "^1.0.1", + "arrify": "^1.0.0", + "glob": "^6.0.1", + "object-assign": "^4.0.1", + "pify": "^2.0.0", + "pinkie-promise": "^2.0.0" + }, + "dependencies": { + "glob": { + "version": "6.0.4", + "resolved": "https://registry.npmjs.org/glob/-/glob-6.0.4.tgz", + "integrity": "sha1-DwiGD2oVUSey+t1PnOJLGqtuTSI=", + "dev": true, + "requires": { + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "2 || 3", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + } + } + }, + "graceful-fs": { + "version": "4.1.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.11.tgz", + "integrity": "sha1-Dovf5NHduIVNZOBOp8AOKgJuVlg=", + "dev": true + }, + "graceful-readlink": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/graceful-readlink/-/graceful-readlink-1.0.1.tgz", + "integrity": "sha1-TK+tdrxi8C+gObL5Tpo906ORpyU=", + "dev": true + }, + "grizzly": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/grizzly/-/grizzly-3.0.3.tgz", + "integrity": "sha512-IGcSYOg8W75e1/92oHy1RgO4fiWxWYi94C5nwjJwTe5usRx241LkqiO4923LVLwkon7ro69ZKcCbI4ox25pDOw==", + "dev": true, + "requires": { + "@octokit/rest": "^14.0.7", + "checkup": "^1.3.0", + "debug": "^3.0.0", + "execon": "^1.2.0", + "minimist": "^1.2.0", + "readjson": "^1.1.0" + }, + "dependencies": { + "debug": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", + "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "minimist": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", + "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", + "dev": true + } + } + }, + "har-schema": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", + "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=", + "dev": true, + "optional": true + }, + "har-validator": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.0.tgz", + "integrity": "sha512-+qnmNjI4OfH2ipQ9VQOw23bBd/ibtfbVdK2fYbY4acTDqKTW/YDp9McimZdDbG8iV9fZizUqQMD5xvriB146TA==", + "dev": true, + "optional": true, + "requires": { + "ajv": "^5.3.0", + "har-schema": "^2.0.0" + } + }, + "has": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", + "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "dev": true, + "requires": { + "function-bind": "^1.1.1" + } + }, + "has-ansi": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", + "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=", + "dev": true, + "requires": { + "ansi-regex": "^2.0.0" + } + }, + "has-color": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/has-color/-/has-color-0.1.7.tgz", + "integrity": "sha1-ZxRKUmDDT8PMpnfQQdr1L+e3iy8=", + "dev": true + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=" + }, + "hasha": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/hasha/-/hasha-2.2.0.tgz", + "integrity": "sha1-eNfL/B5tZjA/55g3NlmEUXsvbuE=", + "dev": true, + "optional": true, + "requires": { + "is-stream": "^1.0.1", + "pinkie-promise": "^2.0.0" + } + }, + "htmlparser2": { + "version": "3.8.3", + "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-3.8.3.tgz", + "integrity": "sha1-mWwosZFRaovoZQGn15dX5ccMEGg=", + "dev": true, + "requires": { + "domelementtype": "1", + "domhandler": "2.3", + "domutils": "1.5", + "entities": "1.0", + "readable-stream": "1.1" + } + }, + "http-signature": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", + "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=", + "dev": true, + "optional": true, + "requires": { + "assert-plus": "^1.0.0", + "jsprim": "^1.2.2", + "sshpk": "^1.7.0" + } + }, + "i": { + "version": "0.3.6", + "resolved": "https://registry.npmjs.org/i/-/i-0.3.6.tgz", + "integrity": "sha1-2WyScyB28HJxG2sQ/X1PZa2O4j0=", + "dev": true + }, + "indexes-of": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/indexes-of/-/indexes-of-1.0.1.tgz", + "integrity": "sha1-8w9xbI4r00bHtn0985FVZqfAVgc=" + }, + "inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "dev": true, + "requires": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "inherit": { + "version": "2.2.6", + "resolved": "https://registry.npmjs.org/inherit/-/inherit-2.2.6.tgz", + "integrity": "sha1-8WFLBshUToEo5CKchjR9tzrZeI0=", + "dev": true + }, + "inherits": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", + "dev": true + }, + "is-array-buffer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-1.0.1.tgz", + "integrity": "sha512-lj035IqdAwsodoRGs9/8+Kn3HPoz9CTuZbcw63afugWonxigvUVeHY5d6Ve1O+s1N3RCk7txo2TIWQLbU0SuNA==", + "dev": true + }, + "is-callable": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.1.4.tgz", + "integrity": "sha512-r5p9sxJjYnArLjObpjA4xu5EKI3CuKHkJXMhT7kwbpUyIFD1n5PMAsoPvWnvtZiNz7LjkYDRZhd7FlI0eMijEA==", + "dev": true + }, + "is-date-object": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.1.tgz", + "integrity": "sha1-mqIOtq7rv/d/vTPnTKAbM1gdOhY=", + "dev": true + }, + "is-regex": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.0.4.tgz", + "integrity": "sha1-VRdIm1RwkbCTDglWVM7SXul+lJE=", + "dev": true, + "requires": { + "has": "^1.0.1" + } + }, + "is-stream": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", + "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=", + "dev": true + }, + "is-symbol": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.1.tgz", + "integrity": "sha1-PMWfAAJRlLarLjjbrmaJJWtmBXI=", + "dev": true + }, + "is-typedarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", + "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=", + "dev": true, + "optional": true + }, + "is-utf8": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-utf8/-/is-utf8-0.2.1.tgz", + "integrity": "sha1-Sw2hRCEE0bM2NA6AeX6GXPOffXI=", + "dev": true + }, + "isarray": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=", + "dev": true + }, + "isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", + "dev": true + }, + "isstream": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", + "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=", + "dev": true + }, + "js-yaml": { + "version": "3.4.6", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.4.6.tgz", + "integrity": "sha1-a+GyP2JJ9T0pM3D9TRqqY84bTrA=", + "dev": true, + "requires": { + "argparse": "^1.0.2", + "esprima": "^2.6.0", + "inherit": "^2.2.2" + } + }, + "jsbn": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", + "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=", + "dev": true, + "optional": true + }, + "jscs": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/jscs/-/jscs-3.0.7.tgz", + "integrity": "sha1-cUG03/W4bjLQ6Z12S4NnZ8MNIBo=", + "dev": true, + "requires": { + "chalk": "~1.1.0", + "cli-table": "~0.3.1", + "commander": "~2.9.0", + "cst": "^0.4.3", + "estraverse": "^4.1.0", + "exit": "~0.1.2", + "glob": "^5.0.1", + "htmlparser2": "3.8.3", + "js-yaml": "~3.4.0", + "jscs-jsdoc": "^2.0.0", + "jscs-preset-wikimedia": "~1.0.0", + "jsonlint": "~1.6.2", + "lodash": "~3.10.0", + "minimatch": "~3.0.0", + "natural-compare": "~1.2.2", + "pathval": "~0.1.1", + "prompt": "~0.2.14", + "reserved-words": "^0.1.1", + "resolve": "^1.1.6", + "strip-bom": "^2.0.0", + "strip-json-comments": "~1.0.2", + "to-double-quotes": "^2.0.0", + "to-single-quotes": "^2.0.0", + "vow": "~0.4.8", + "vow-fs": "~0.3.4", + "xmlbuilder": "^3.1.0" + }, + "dependencies": { + "ansi-styles": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", + "dev": true + }, + "chalk": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", + "dev": true, + "requires": { + "ansi-styles": "^2.2.1", + "escape-string-regexp": "^1.0.2", + "has-ansi": "^2.0.0", + "strip-ansi": "^3.0.0", + "supports-color": "^2.0.0" + } + }, + "supports-color": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", + "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", + "dev": true + } + } + }, + "jscs-jsdoc": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/jscs-jsdoc/-/jscs-jsdoc-2.0.0.tgz", + "integrity": "sha1-9T684CmqMSW9iCkLpQ1k1FEKSHE=", + "dev": true, + "requires": { + "comment-parser": "^0.3.1", + "jsdoctypeparser": "~1.2.0" + } + }, + "jscs-preset-wikimedia": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/jscs-preset-wikimedia/-/jscs-preset-wikimedia-1.0.1.tgz", + "integrity": "sha512-RWqu6IYSUlnYuCRCF0obCOHjJV0vhpLcvKbauwxmLQoZ0PiXDTWBYlfpsEfdhg7pmREAEwrARfDRz5qWD6qknA==", + "dev": true + }, + "jsdoctypeparser": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/jsdoctypeparser/-/jsdoctypeparser-1.2.0.tgz", + "integrity": "sha1-597cFToRhJ/8UUEUSuhqfvDCU5I=", + "dev": true, + "requires": { + "lodash": "^3.7.0" + } + }, + "jshint": { + "version": "2.9.6", + "resolved": "https://registry.npmjs.org/jshint/-/jshint-2.9.6.tgz", + "integrity": "sha512-KO9SIAKTlJQOM4lE64GQUtGBRpTOuvbrRrSZw3AhUxMNG266nX9hK2cKA4SBhXOj0irJGyNyGSLT62HGOVDEOA==", + "dev": true, + "requires": { + "cli": "~1.0.0", + "console-browserify": "1.1.x", + "exit": "0.1.x", + "htmlparser2": "3.8.x", + "lodash": "~4.17.10", + "minimatch": "~3.0.2", + "phantom": "~4.0.1", + "phantomjs-prebuilt": "~2.1.7", + "shelljs": "0.3.x", + "strip-json-comments": "1.0.x", + "unicode-5.2.0": "^0.7.5" + }, + "dependencies": { + "lodash": { + "version": "4.17.10", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.10.tgz", + "integrity": "sha512-UejweD1pDoXu+AD825lWwp4ZGtSwgnpZxb3JDViD7StjQz+Nb/6l093lx4OQ0foGWNRoc19mWy7BzL+UAK2iVg==", + "dev": true + } + } + }, + "json-schema": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz", + "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=", + "dev": true, + "optional": true + }, + "json-schema-traverse": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.3.1.tgz", + "integrity": "sha1-NJptRMU6Ud6JtAgFxdXlm0F9M0A=", + "dev": true, + "optional": true + }, + "json-stringify-safe": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", + "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=", + "dev": true, + "optional": true + }, + "jsonfile": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-2.4.0.tgz", + "integrity": "sha1-NzaitCi4e72gzIO1P6PWM6NcKug=", + "dev": true, + "requires": { + "graceful-fs": "^4.1.6" + } + }, + "jsonlint": { + "version": "1.6.3", + "resolved": "https://registry.npmjs.org/jsonlint/-/jsonlint-1.6.3.tgz", + "integrity": "sha512-jMVTMzP+7gU/IyC6hvKyWpUU8tmTkK5b3BPNuMI9U8Sit+YAWLlZwB6Y6YrdCxfg2kNz05p3XY3Bmm4m26Nv3A==", + "dev": true, + "requires": { + "JSV": "^4.0.x", + "nomnom": "^1.5.x" + } + }, + "jsprim": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz", + "integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=", + "dev": true, + "optional": true, + "requires": { + "assert-plus": "1.0.0", + "extsprintf": "1.3.0", + "json-schema": "0.2.3", + "verror": "1.10.0" + } + }, + "kew": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/kew/-/kew-0.7.0.tgz", + "integrity": "sha1-edk9LTM2PW/dKXCzNdkUGtWR15s=", + "dev": true, + "optional": true + }, + "klaw": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/klaw/-/klaw-1.3.1.tgz", + "integrity": "sha1-QIhDO0azsbolnXh4XY6W9zugJDk=", + "dev": true, + "requires": { + "graceful-fs": "^4.1.9" + } + }, + "lodash": { + "version": "3.10.1", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-3.10.1.tgz", + "integrity": "sha1-W/Rejkm6QYnhfUgnid/RW9FAt7Y=", + "dev": true + }, + "lru-cache": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.3.tgz", + "integrity": "sha512-fFEhvcgzuIoJVUF8fYr5KR0YqxD238zgObTps31YdADwPPAp82a4M8TrckkWyx7ekNlf9aBcVn81cFwwXngrJA==", + "dev": true, + "requires": { + "pseudomap": "^1.0.2", + "yallist": "^2.1.2" + } + }, + "mime-db": { + "version": "1.35.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.35.0.tgz", + "integrity": "sha512-JWT/IcCTsB0Io3AhWUMjRqucrHSPsSf2xKLaRldJVULioggvkJvggZ3VXNNSRkCddE6D+BUI4HEIZIA2OjwIvg==", + "dev": true + }, + "mime-types": { + "version": "2.1.19", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.19.tgz", + "integrity": "sha512-P1tKYHVSZ6uFo26mtnve4HQFE3koh1UWVkp8YUC+ESBHe945xWSoXuHHiGarDqcEZ+whpCDnlNw5LON0kLo+sw==", + "dev": true, + "requires": { + "mime-db": "~1.35.0" + } + }, + "minimatch": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", + "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "dev": true, + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "minimist": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", + "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=", + "dev": true + }, + "mkdirp": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", + "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", + "dev": true, + "requires": { + "minimist": "0.0.8" + } + }, + "mount-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/mount-point/-/mount-point-3.0.0.tgz", + "integrity": "sha1-Zly57evoDREOZY21bDHQrvUaj5c=", + "dev": true, + "requires": { + "@sindresorhus/df": "^1.0.1", + "pify": "^2.3.0", + "pinkie-promise": "^2.0.1" + }, + "dependencies": { + "@sindresorhus/df": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@sindresorhus/df/-/df-1.0.1.tgz", + "integrity": "sha1-xptm9S9vzdKHyAffIQMF2694UA0=", + "dev": true + } + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + }, + "mute-stream": { + "version": "0.0.7", + "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.7.tgz", + "integrity": "sha1-MHXOk7whuPq0PhvE2n6BFe0ee6s=", + "dev": true + }, + "natural-compare": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.2.2.tgz", + "integrity": "sha1-H5bWDjFBysG20FZTzg2urHY69qo=", + "dev": true + }, + "ncp": { + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/ncp/-/ncp-0.4.2.tgz", + "integrity": "sha1-q8xsvT7C7Spyn/bnwfqPAXhKhXQ=", + "dev": true + }, + "nomnom": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/nomnom/-/nomnom-1.8.1.tgz", + "integrity": "sha1-IVH3Ikcrp55Qp2/BJbuMjy5Nwqc=", + "dev": true, + "requires": { + "chalk": "~0.4.0", + "underscore": "~1.6.0" + }, + "dependencies": { + "ansi-styles": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-1.0.0.tgz", + "integrity": "sha1-yxAt8cVvUSPquLZ817mAJ6AnkXg=", + "dev": true + }, + "chalk": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-0.4.0.tgz", + "integrity": "sha1-UZmj3c0MHv4jvAjBsCewYXbgxk8=", + "dev": true, + "requires": { + "ansi-styles": "~1.0.0", + "has-color": "~0.1.0", + "strip-ansi": "~0.1.0" + } + }, + "strip-ansi": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-0.1.1.tgz", + "integrity": "sha1-OeipjQRNFQZgq+SmgIrPcLt7yZE=", + "dev": true + } + } + }, + "npm-run-path": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-1.0.0.tgz", + "integrity": "sha1-9cMr9ZX+ga6Sfa7FLoL4sACsPI8=", + "dev": true, + "requires": { + "path-key": "^1.0.0" + } + }, + "npmpub": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/npmpub/-/npmpub-3.1.0.tgz", + "integrity": "sha1-c0OoAf+xi/0s7CM1hLkUWa5O4Uk=", + "dev": true, + "requires": { + "chalk": "^1.1.1", + "github-release-from-changelog": "^1.1.1", + "minimist": "^1.2.0", + "shelljs": "^0.5.3", + "trash": "^3.4.1" + }, + "dependencies": { + "ansi-styles": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", + "dev": true + }, + "chalk": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", + "dev": true, + "requires": { + "ansi-styles": "^2.2.1", + "escape-string-regexp": "^1.0.2", + "has-ansi": "^2.0.0", + "strip-ansi": "^3.0.0", + "supports-color": "^2.0.0" + } + }, + "minimist": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", + "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", + "dev": true + }, + "shelljs": { + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/shelljs/-/shelljs-0.5.3.tgz", + "integrity": "sha1-xUmCuZbHbvDB5rWfvcWCX1txMRM=", + "dev": true + }, + "supports-color": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", + "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", + "dev": true + } + } + }, + "oauth-sign": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", + "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==", + "dev": true, + "optional": true + }, + "object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", + "dev": true + }, + "object-inspect": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.6.0.tgz", + "integrity": "sha512-GJzfBZ6DgDAmnuaM3104jR4s1Myxr3Y3zfIyN4z3UdqN69oSRacNK8UhnobDdC+7J2AHCjGwxQubNJfE70SXXQ==", + "dev": true + }, + "object-keys": { + "version": "1.0.12", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.0.12.tgz", + "integrity": "sha512-FTMyFUm2wBcGHnH2eXmz7tC6IwlqQZ6mVZ+6dm6vZ4IQIHjs6FdNsQBuKGPuUUUY6NfJw2PshC08Tn6LzLDOag==", + "dev": true + }, + "once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "dev": true, + "requires": { + "wrappy": "1" + } + }, + "os-homedir": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz", + "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=", + "dev": true + }, + "path-exists": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-2.1.0.tgz", + "integrity": "sha1-D+tsZPD8UY2adU3V77YscCJ2H0s=", + "dev": true, + "requires": { + "pinkie-promise": "^2.0.0" + } + }, + "path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", + "dev": true + }, + "path-key": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-1.0.0.tgz", + "integrity": "sha1-XVPVeAGWRsDWiADbThRua9wqx68=", + "dev": true + }, + "path-parse": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz", + "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==", + "dev": true + }, + "pathval": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/pathval/-/pathval-0.1.1.tgz", + "integrity": "sha1-CPkRzcqczllCiA2ngXvAtyO2bYI=", + "dev": true + }, + "pend": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz", + "integrity": "sha1-elfrVQpng/kRUzH89GY9XI4AelA=", + "dev": true, + "optional": true + }, + "performance-now": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", + "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=", + "dev": true, + "optional": true + }, + "phantom": { + "version": "4.0.12", + "resolved": "https://registry.npmjs.org/phantom/-/phantom-4.0.12.tgz", + "integrity": "sha512-Tz82XhtPmwCk1FFPmecy7yRGZG2btpzY2KI9fcoPT7zT9det0CcMyfBFPp1S8DqzsnQnm8ZYEfdy528mwVtksA==", + "dev": true, + "optional": true, + "requires": { + "phantomjs-prebuilt": "^2.1.16", + "split": "^1.0.1", + "winston": "^2.4.0" + }, + "dependencies": { + "async": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/async/-/async-1.0.0.tgz", + "integrity": "sha1-+PwEyjoTeErenhZBr5hXjPvWR6k=", + "dev": true, + "optional": true + }, + "winston": { + "version": "2.4.3", + "resolved": "https://registry.npmjs.org/winston/-/winston-2.4.3.tgz", + "integrity": "sha512-GYKuysPz2pxYAVJD2NPsDLP5Z79SDEzPm9/j4tCjkF/n89iBNGBMJcR+dMUqxgPNgoSs6fVygPi+Vl2oxIpBuw==", + "dev": true, + "optional": true, + "requires": { + "async": "~1.0.0", + "colors": "1.0.x", + "cycle": "1.0.x", + "eyes": "0.1.x", + "isstream": "0.1.x", + "stack-trace": "0.0.x" + } + } + } + }, + "phantomjs-prebuilt": { + "version": "2.1.16", + "resolved": "https://registry.npmjs.org/phantomjs-prebuilt/-/phantomjs-prebuilt-2.1.16.tgz", + "integrity": "sha1-79ISpKOWbTZHaE6ouniFSb4q7+8=", + "dev": true, + "optional": true, + "requires": { + "es6-promise": "^4.0.3", + "extract-zip": "^1.6.5", + "fs-extra": "^1.0.0", + "hasha": "^2.2.0", + "kew": "^0.7.0", + "progress": "^1.1.8", + "request": "^2.81.0", + "request-progress": "^2.0.1", + "which": "^1.2.10" + } + }, + "pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", + "dev": true + }, + "pinkie": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz", + "integrity": "sha1-clVrgM+g1IqXToDnckjoDtT3+HA=", + "dev": true + }, + "pinkie-promise": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz", + "integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=", + "dev": true, + "requires": { + "pinkie": "^2.0.0" + } + }, + "pkginfo": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/pkginfo/-/pkginfo-0.4.1.tgz", + "integrity": "sha1-tUGO8EOd5UJfxJlQQtztFPsqhP8=", + "dev": true + }, + "postcss": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.2.tgz", + "integrity": "sha512-fmaUY5370keLUTx+CnwRxtGiuFTcNBLQBqr1oE3WZ/euIYmGAo0OAgOhVJ3ByDnVmOR3PK+0V9VebzfjRIUcqw==", + "requires": { + "chalk": "^2.4.1", + "source-map": "^0.6.1", + "supports-color": "^5.4.0" + } + }, + "postcss-values-parser": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/postcss-values-parser/-/postcss-values-parser-1.5.0.tgz", + "integrity": "sha512-3M3p+2gMp0AH3da530TlX8kiO1nxdTnc3C6vr8dMxRLIlh8UYkz0/wcwptSXjhtx2Fr0TySI7a+BHDQ8NL7LaQ==", + "requires": { + "flatten": "^1.0.2", + "indexes-of": "^1.0.1", + "uniq": "^1.0.1" + } + }, + "process-nextick-args": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.0.tgz", + "integrity": "sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw==", + "dev": true + }, + "progress": { + "version": "1.1.8", + "resolved": "https://registry.npmjs.org/progress/-/progress-1.1.8.tgz", + "integrity": "sha1-4mDHj2Fhzdmw5WzD4Khd4Xx6V74=", + "dev": true, + "optional": true + }, + "prompt": { + "version": "0.2.14", + "resolved": "https://registry.npmjs.org/prompt/-/prompt-0.2.14.tgz", + "integrity": "sha1-V3VPZPVD/XsIRXB8gY7OYY8F/9w=", + "dev": true, + "requires": { + "pkginfo": "0.x.x", + "read": "1.0.x", + "revalidator": "0.1.x", + "utile": "0.2.x", + "winston": "0.8.x" + } + }, + "pseudomap": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", + "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=", + "dev": true + }, + "psl": { + "version": "1.1.29", + "resolved": "https://registry.npmjs.org/psl/-/psl-1.1.29.tgz", + "integrity": "sha512-AeUmQ0oLN02flVHXWh9sSJF7mcdFq0ppid/JkErufc3hGIV/AMa8Fo9VgDo/cT2jFdOWoFvHp90qqBH54W+gjQ==", + "dev": true, + "optional": true + }, + "punycode": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", + "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=", + "dev": true, + "optional": true + }, + "qs": { + "version": "6.5.2", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz", + "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==", + "dev": true, + "optional": true + }, + "read": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/read/-/read-1.0.7.tgz", + "integrity": "sha1-s9oZvQUkMal2cdRKQmNK33ELQMQ=", + "dev": true, + "requires": { + "mute-stream": "~0.0.4" + } + }, + "readable-stream": { + "version": "1.1.14", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz", + "integrity": "sha1-fPTFTvZI44EwhMY23SB54WbAgdk=", + "dev": true, + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.1", + "isarray": "0.0.1", + "string_decoder": "~0.10.x" + } + }, + "readjson": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/readjson/-/readjson-1.1.4.tgz", + "integrity": "sha512-H4dRk2S67w3HtE1apnw5wlHpN9qkJ0pen0AcEvyAfnrPfskZIyUOYLXpfN6olDQZI+eUlxg0Yo4lJ2bymujOUA==", + "dev": true, + "requires": { + "try-catch": "^2.0.0" + } + }, + "regenerator-runtime": { + "version": "0.11.1", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz", + "integrity": "sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg==", + "dev": true + }, + "request": { + "version": "2.88.0", + "resolved": "https://registry.npmjs.org/request/-/request-2.88.0.tgz", + "integrity": "sha512-NAqBSrijGLZdM0WZNsInLJpkJokL72XYjUpnB0iwsRgxh7dB6COrHnTBNwN0E+lHDAJzu7kLAkDeY08z2/A0hg==", + "dev": true, + "optional": true, + "requires": { + "aws-sign2": "~0.7.0", + "aws4": "^1.8.0", + "caseless": "~0.12.0", + "combined-stream": "~1.0.6", + "extend": "~3.0.2", + "forever-agent": "~0.6.1", + "form-data": "~2.3.2", + "har-validator": "~5.1.0", + "http-signature": "~1.2.0", + "is-typedarray": "~1.0.0", + "isstream": "~0.1.2", + "json-stringify-safe": "~5.0.1", + "mime-types": "~2.1.19", + "oauth-sign": "~0.9.0", + "performance-now": "^2.1.0", + "qs": "~6.5.2", + "safe-buffer": "^5.1.2", + "tough-cookie": "~2.4.3", + "tunnel-agent": "^0.6.0", + "uuid": "^3.3.2" + }, + "dependencies": { + "uuid": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.2.tgz", + "integrity": "sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA==", + "dev": true, + "optional": true + } + } + }, + "request-progress": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/request-progress/-/request-progress-2.0.1.tgz", + "integrity": "sha1-XTa7V5YcZzqlt4jbyBQf3yO0Tgg=", + "dev": true, + "optional": true, + "requires": { + "throttleit": "^1.0.0" + } + }, + "reserved-words": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/reserved-words/-/reserved-words-0.1.2.tgz", + "integrity": "sha1-AKCUD5jNUBrqqsMWQR2a3FKzGrE=", + "dev": true + }, + "resolve": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.8.1.tgz", + "integrity": "sha512-AicPrAC7Qu1JxPCZ9ZgCZlY35QgFnNqc+0LtbRNxnVw4TXvjQ72wnuL9JQcEBgXkI9JM8MsT9kaQoHcpCRJOYA==", + "dev": true, + "requires": { + "path-parse": "^1.0.5" + } + }, + "resumer": { + "version": "0.0.0", + "resolved": "https://registry.npmjs.org/resumer/-/resumer-0.0.0.tgz", + "integrity": "sha1-8ej0YeQGS6Oegq883CqMiT0HZ1k=", + "dev": true, + "requires": { + "through": "~2.3.4" + } + }, + "revalidator": { + "version": "0.1.8", + "resolved": "https://registry.npmjs.org/revalidator/-/revalidator-0.1.8.tgz", + "integrity": "sha1-/s5hv6DBtSoga9axgZgYS91SOjs=", + "dev": true + }, + "rimraf": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.2.tgz", + "integrity": "sha512-lreewLK/BlghmxtfH36YYVg1i8IAce4TI7oao75I1g245+6BctqTVQiBP3YUJ9C6DQOXJmkYR9X9fCLtCOJc5w==", + "dev": true, + "requires": { + "glob": "^7.0.5" + }, + "dependencies": { + "glob": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz", + "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==", + "dev": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + } + } + }, + "run-applescript": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/run-applescript/-/run-applescript-2.1.0.tgz", + "integrity": "sha1-O/8sz5W2zqy0lyPlUPADcdYYUQ0=", + "dev": true, + "requires": { + "pify": "^2.2.0", + "pinkie-promise": "^2.0.0" + } + }, + "safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true + }, + "safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", + "dev": true + }, + "shelljs": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/shelljs/-/shelljs-0.3.0.tgz", + "integrity": "sha1-NZbmMHp4FUT1kfN9phg2DzHbV7E=", + "dev": true + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" + }, + "source-map-support": { + "version": "0.4.18", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.4.18.tgz", + "integrity": "sha512-try0/JqxPLF9nOjvSta7tVondkP5dwgyLDjVoyMDlmjugT2lRZ1OfsrYTkCd2hkDnJTKRbO/Rl3orm8vlsUzbA==", + "dev": true, + "requires": { + "source-map": "^0.5.6" + }, + "dependencies": { + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "dev": true + } + } + }, + "split": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/split/-/split-1.0.1.tgz", + "integrity": "sha512-mTyOoPbrivtXnwnIxZRFYRrPNtEFKlpB2fvjSnCQUiAA6qAZzqwna5envK4uk6OIeP17CsdF3rSBGYVBsU0Tkg==", + "dev": true, + "optional": true, + "requires": { + "through": "2" + } + }, + "sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", + "dev": true + }, + "sshpk": { + "version": "1.14.2", + "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.14.2.tgz", + "integrity": "sha1-xvxhZIo9nE52T9P8306hBeSSupg=", + "dev": true, + "optional": true, + "requires": { + "asn1": "~0.2.3", + "assert-plus": "^1.0.0", + "bcrypt-pbkdf": "^1.0.0", + "dashdash": "^1.12.0", + "ecc-jsbn": "~0.1.1", + "getpass": "^0.1.1", + "jsbn": "~0.1.0", + "safer-buffer": "^2.0.2", + "tweetnacl": "~0.14.0" + } + }, + "stack-trace": { + "version": "0.0.10", + "resolved": "https://registry.npmjs.org/stack-trace/-/stack-trace-0.0.10.tgz", + "integrity": "sha1-VHxws0fo0ytOEI6hoqFZ5f3eGcA=", + "dev": true + }, + "string.prototype.trim": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.1.2.tgz", + "integrity": "sha1-0E3iyJ4Tf019IG8Ia17S+ua+jOo=", + "dev": true, + "requires": { + "define-properties": "^1.1.2", + "es-abstract": "^1.5.0", + "function-bind": "^1.0.2" + } + }, + "string_decoder": { + "version": "0.10.31", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", + "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=", + "dev": true + }, + "strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "dev": true, + "requires": { + "ansi-regex": "^2.0.0" + } + }, + "strip-bom": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-2.0.0.tgz", + "integrity": "sha1-YhmoVhZSBJHzV4i9vxRHqZx+aw4=", + "dev": true, + "requires": { + "is-utf8": "^0.2.0" + } + }, + "strip-eof": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz", + "integrity": "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8=", + "dev": true + }, + "strip-json-comments": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-1.0.4.tgz", + "integrity": "sha1-HhX7ysl9Pumb8tc7TGVrCCu6+5E=", + "dev": true + }, + "supports-color": { + "version": "5.4.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.4.0.tgz", + "integrity": "sha512-zjaXglF5nnWpsq470jSv6P9DwPvgLkuapYmfDm3JWOm0vkNTVF2tI4UrN2r6jH1qM/uc/WtxYY1hYoA2dOKj5w==", + "requires": { + "has-flag": "^3.0.0" + } + }, + "tape": { + "version": "4.9.1", + "resolved": "https://registry.npmjs.org/tape/-/tape-4.9.1.tgz", + "integrity": "sha512-6fKIXknLpoe/Jp4rzHKFPpJUHDHDqn8jus99IfPnHIjyz78HYlefTGD3b5EkbQzuLfaEvmfPK3IolLgq2xT3kw==", + "dev": true, + "requires": { + "deep-equal": "~1.0.1", + "defined": "~1.0.0", + "for-each": "~0.3.3", + "function-bind": "~1.1.1", + "glob": "~7.1.2", + "has": "~1.0.3", + "inherits": "~2.0.3", + "minimist": "~1.2.0", + "object-inspect": "~1.6.0", + "resolve": "~1.7.1", + "resumer": "~0.0.0", + "string.prototype.trim": "~1.1.2", + "through": "~2.3.8" + }, + "dependencies": { + "glob": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz", + "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==", + "dev": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "minimist": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", + "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", + "dev": true + }, + "resolve": { + "version": "1.7.1", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.7.1.tgz", + "integrity": "sha512-c7rwLofp8g1U+h1KNyHL/jicrKg1Ek4q+Lr33AL65uZTinUZHe30D5HlyN5V9NW0JX1D5dXQ4jqW5l7Sy/kGfw==", + "dev": true, + "requires": { + "path-parse": "^1.0.5" + } + } + } + }, + "throttleit": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/throttleit/-/throttleit-1.0.0.tgz", + "integrity": "sha1-nnhYNtr0Z0MUWlmEtiaNgoUorGw=", + "dev": true, + "optional": true + }, + "through": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", + "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=", + "dev": true + }, + "to-double-quotes": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/to-double-quotes/-/to-double-quotes-2.0.0.tgz", + "integrity": "sha1-qvIx1vqUiUn4GTAburRITYWI5Kc=", + "dev": true + }, + "to-single-quotes": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/to-single-quotes/-/to-single-quotes-2.0.1.tgz", + "integrity": "sha1-fMKRUfD18sQZRvEZ9ZMv5VQXASU=", + "dev": true + }, + "tough-cookie": { + "version": "2.4.3", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.4.3.tgz", + "integrity": "sha512-Q5srk/4vDM54WJsJio3XNn6K2sCG+CQ8G5Wz6bZhRZoAe/+TxjWB/GlFAnYEbkYVlON9FMk/fE3h2RLpPXo4lQ==", + "dev": true, + "optional": true, + "requires": { + "psl": "^1.1.24", + "punycode": "^1.4.1" + } + }, + "trash": { + "version": "3.4.2", + "resolved": "https://registry.npmjs.org/trash/-/trash-3.4.2.tgz", + "integrity": "sha1-+wQiUvwmoCInaVCiuw7Om5QF6xk=", + "dev": true, + "requires": { + "escape-string-applescript": "^1.0.0", + "fs-extra": "^0.26.2", + "globby": "^4.0.0", + "path-exists": "^2.0.0", + "pify": "^2.3.0", + "pinkie-promise": "^2.0.0", + "run-applescript": "^2.0.0", + "uuid": "^2.0.1", + "xdg-trashdir": "^2.0.0" + }, + "dependencies": { + "fs-extra": { + "version": "0.26.7", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-0.26.7.tgz", + "integrity": "sha1-muH92UiXeY7at20JGM9C0MMYT6k=", + "dev": true, + "requires": { + "graceful-fs": "^4.1.2", + "jsonfile": "^2.1.0", + "klaw": "^1.0.0", + "path-is-absolute": "^1.0.0", + "rimraf": "^2.2.8" + } + } + } + }, + "try-catch": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/try-catch/-/try-catch-2.0.0.tgz", + "integrity": "sha512-RPXpVjsbtWgymwGq5F/OWDFsjEzdvzwHFaMjWWW6f/p6+uk/N7YSKJHQfIfGqITfj8qH4cBqCLMnhKZBaKk7Kg==", + "dev": true + }, + "tunnel-agent": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", + "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=", + "dev": true, + "optional": true, + "requires": { + "safe-buffer": "^5.0.1" + } + }, + "tweetnacl": { + "version": "0.14.5", + "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", + "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=", + "dev": true, + "optional": true + }, + "typedarray": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", + "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=", + "dev": true, + "optional": true + }, + "underscore": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.6.0.tgz", + "integrity": "sha1-izixDKze9jM3uLJOT/htRa6lKag=", + "dev": true + }, + "unicode-5.2.0": { + "version": "0.7.5", + "resolved": "https://registry.npmjs.org/unicode-5.2.0/-/unicode-5.2.0-0.7.5.tgz", + "integrity": "sha512-KVGLW1Bri30x00yv4HNM8kBxoqFXr0Sbo55735nvrlsx4PYBZol3UtoWgO492fSwmsetzPEZzy73rbU8OGXJcA==", + "dev": true + }, + "uniq": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/uniq/-/uniq-1.0.1.tgz", + "integrity": "sha1-sxxa6CVIRKOoKBVBzisEuGWnNP8=" + }, + "url-template": { + "version": "2.0.8", + "resolved": "https://registry.npmjs.org/url-template/-/url-template-2.0.8.tgz", + "integrity": "sha1-/FZaPMy/93MMd19WQflVV5FDnyE=", + "dev": true + }, + "user-home": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/user-home/-/user-home-2.0.0.tgz", + "integrity": "sha1-nHC/2Babwdy/SGBODwS4tJzenp8=", + "dev": true, + "requires": { + "os-homedir": "^1.0.0" + } + }, + "util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=", + "dev": true + }, + "utile": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/utile/-/utile-0.2.1.tgz", + "integrity": "sha1-kwyI6ZCY1iIINMNWy9mncFItkNc=", + "dev": true, + "requires": { + "async": "~0.2.9", + "deep-equal": "*", + "i": "0.3.x", + "mkdirp": "0.x.x", + "ncp": "0.4.x", + "rimraf": "2.x.x" + } + }, + "uuid": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-2.0.3.tgz", + "integrity": "sha1-Z+LoY3lyFVMN/zGOW/nc6/1Hsho=", + "dev": true + }, + "verror": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", + "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=", + "dev": true, + "optional": true, + "requires": { + "assert-plus": "^1.0.0", + "core-util-is": "1.0.2", + "extsprintf": "^1.2.0" + } + }, + "vow": { + "version": "0.4.17", + "resolved": "https://registry.npmjs.org/vow/-/vow-0.4.17.tgz", + "integrity": "sha512-A3/9bWFqf6gT0jLR4/+bT+IPTe1mQf+tdsW6+WI5geP9smAp8Kbbu4R6QQCDKZN/8TSCqTlXVQm12QliB4rHfg==", + "dev": true + }, + "vow-fs": { + "version": "0.3.6", + "resolved": "https://registry.npmjs.org/vow-fs/-/vow-fs-0.3.6.tgz", + "integrity": "sha1-LUxZviLivyYY3fWXq0uqkjvnIA0=", + "dev": true, + "requires": { + "glob": "^7.0.5", + "uuid": "^2.0.2", + "vow": "^0.4.7", + "vow-queue": "^0.4.1" + }, + "dependencies": { + "glob": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz", + "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==", + "dev": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + } + } + }, + "vow-queue": { + "version": "0.4.3", + "resolved": "https://registry.npmjs.org/vow-queue/-/vow-queue-0.4.3.tgz", + "integrity": "sha512-/poAKDTFL3zYbeQg7cl4BGcfP4sGgXKrHnRFSKj97dteUFu8oyXMwIcdwu8NSx/RmPGIuYx1Bik/y5vU4H/VKw==", + "dev": true, + "requires": { + "vow": "^0.4.17" + } + }, + "which": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", + "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "dev": true, + "requires": { + "isexe": "^2.0.0" + } + }, + "winston": { + "version": "0.8.3", + "resolved": "https://registry.npmjs.org/winston/-/winston-0.8.3.tgz", + "integrity": "sha1-ZLar9M0Brcrv1QCTk7HY6L7BnbA=", + "dev": true, + "requires": { + "async": "0.2.x", + "colors": "0.6.x", + "cycle": "1.0.x", + "eyes": "0.1.x", + "isstream": "0.1.x", + "pkginfo": "0.3.x", + "stack-trace": "0.0.x" + }, + "dependencies": { + "colors": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/colors/-/colors-0.6.2.tgz", + "integrity": "sha1-JCP+ZnisDF2uiFLl0OW+CMmXq8w=", + "dev": true + }, + "pkginfo": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/pkginfo/-/pkginfo-0.3.1.tgz", + "integrity": "sha1-Wyn2qB9wcXFC4J52W76rl7T4HiE=", + "dev": true + } + } + }, + "wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", + "dev": true + }, + "xdg-basedir": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/xdg-basedir/-/xdg-basedir-2.0.0.tgz", + "integrity": "sha1-7byQPMOF/ARSPZZqM1UEtVBNG9I=", + "dev": true, + "requires": { + "os-homedir": "^1.0.0" + } + }, + "xdg-trashdir": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/xdg-trashdir/-/xdg-trashdir-2.1.1.tgz", + "integrity": "sha512-KcVhPaOu2ZurYNHSRTf1+ZHORkTZGCQ+u0JHN17QixRISJq4pXOnjt/lQcehvtHL5QAKhSzKgyjrcNnPdkPBHA==", + "dev": true, + "requires": { + "@sindresorhus/df": "^2.1.0", + "mount-point": "^3.0.0", + "pify": "^2.2.0", + "user-home": "^2.0.0", + "xdg-basedir": "^2.0.0" + } + }, + "xmlbuilder": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-3.1.0.tgz", + "integrity": "sha1-LIaIjy1OrehQ+jjKf3Ij9yCVFuE=", + "dev": true, + "requires": { + "lodash": "^3.5.0" + } + }, + "yallist": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", + "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=", + "dev": true + }, + "yauzl": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.4.1.tgz", + "integrity": "sha1-lSj0QtqxsihOWLQ3m7GU4i4MQAU=", + "dev": true, + "optional": true, + "requires": { + "fd-slicer": "~1.0.1" + } + } + } +} diff --git a/package.json b/package.json index 42fff4d123..52bc063cec 100644 --- a/package.json +++ b/package.json @@ -20,8 +20,11 @@ "files": [ "index.js" ], + "engines": { + "node": ">=6.0.0" + }, "dependencies": { - "postcss": "^6.0.22", + "postcss": "^7.0.2", "postcss-values-parser": "^1.5.0" }, "devDependencies": { From cd964ceb53c491f1f6197b6fe568680ab00c2e71 Mon Sep 17 00:00:00 2001 From: Douglas Duteil Date: Mon, 13 Aug 2018 14:49:19 +0200 Subject: [PATCH 659/795] Drop node@4 support From e0f68f90953f865f310bf95cf25915c22c871bc9 Mon Sep 17 00:00:00 2001 From: Douglas Duteil Date: Mon, 13 Aug 2018 14:54:47 +0200 Subject: [PATCH 660/795] Use postcss 7 From 57bfc092647a433f6226e3fde560aa9c99435ff9 Mon Sep 17 00:00:00 2001 From: Aaron Ballard Date: Wed, 15 Aug 2018 16:44:37 -0500 Subject: [PATCH 661/795] Upgrade PostCSS to 7.0.2 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 87c6e92f19..896a668109 100644 --- a/package.json +++ b/package.json @@ -25,7 +25,7 @@ "node": ">=4.0.0" }, "dependencies": { - "postcss": "^6.0.22", + "postcss": "^7.0.2", "postcss-values-parser": "^1.5.0" }, "devDependencies": { From e10ab0cabb5e2812ec9442ec95c7d8fb07527fde Mon Sep 17 00:00:00 2001 From: Aaron Ballard Date: Wed, 15 Aug 2018 16:42:27 -0500 Subject: [PATCH 662/795] Upgrade PostCSS to 7.0.2 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index bf0a6cf754..4ba83c9785 100644 --- a/package.json +++ b/package.json @@ -25,7 +25,7 @@ "node": ">=4.0.0" }, "dependencies": { - "postcss": "^6.0.22", + "postcss": "^7.0.2", "postcss-selector-parser": "^4.0.0" }, "devDependencies": { From 59b11bda2564198b098e870be340dd00141d3fe9 Mon Sep 17 00:00:00 2001 From: Aaron Ballard Date: Wed, 15 Aug 2018 16:47:31 -0500 Subject: [PATCH 663/795] Upgrade PostCSS to 7.0.2 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index f39687e249..b287ced548 100644 --- a/package.json +++ b/package.json @@ -24,7 +24,7 @@ "node": ">=4.0.0" }, "dependencies": { - "postcss": "^6.0" + "postcss": "^7.0.2" }, "devDependencies": { "babel-core": "^6.26", From f795800292c0b1a0ae9cfa2133528afd0a4bbdd0 Mon Sep 17 00:00:00 2001 From: Aaron Ballard Date: Wed, 15 Aug 2018 16:49:27 -0500 Subject: [PATCH 664/795] Upgrade PostCSS to 7.0.2 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 818b7c2fda..d71ba66ed7 100644 --- a/package.json +++ b/package.json @@ -24,7 +24,7 @@ "node": ">=4.0.0" }, "dependencies": { - "postcss": "^6.0.22" + "postcss": "^7.0.2" }, "devDependencies": { "babel-core": "^6.26.3", From 2058170d5aa5ec2b51e45440ec1f3df09c2f4c11 Mon Sep 17 00:00:00 2001 From: Aaron Ballard Date: Wed, 15 Aug 2018 16:54:37 -0500 Subject: [PATCH 665/795] Upgrade PostCSS to 7.0.2 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index f2ba45d1a0..c3f8beafc4 100644 --- a/package.json +++ b/package.json @@ -25,7 +25,7 @@ "node": ">=4.0.0" }, "dependencies": { - "postcss": "^6.0.22" + "postcss": "^7.0.2" }, "devDependencies": { "babel-core": "^6.26.3", From 0d732c06a0598c08e1e270549dddec900dce9da9 Mon Sep 17 00:00:00 2001 From: Aaron Ballard Date: Wed, 15 Aug 2018 16:56:44 -0500 Subject: [PATCH 666/795] Upgrade PostCSS to 7.0.2 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index e47c16fb8d..1902c6a4aa 100644 --- a/package.json +++ b/package.json @@ -25,7 +25,7 @@ "node": ">=4.0.0" }, "dependencies": { - "postcss": "^6.0.22", + "postcss": "^7.0.2", "postcss-values-parser": "^1.5.0" }, "devDependencies": { From b2a385a23cd3a9ea3f63eb5f740f44493d4c6842 Mon Sep 17 00:00:00 2001 From: Aaron Ballard Date: Wed, 15 Aug 2018 17:00:28 -0500 Subject: [PATCH 667/795] Upgrade PostCSS to 7.0.2 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 9a18df2d95..5bbd02c5d6 100644 --- a/package.json +++ b/package.json @@ -26,7 +26,7 @@ }, "dependencies": { "@csstools/convert-colors": "^1.4.0", - "postcss": "^6.0.23", + "postcss": "^7.0.2", "postcss-values-parser": "^1.5.0" }, "devDependencies": { From add059833bf5b5223d1870e5118cb984924ee1bd Mon Sep 17 00:00:00 2001 From: Aaron Ballard Date: Wed, 15 Aug 2018 17:01:55 -0500 Subject: [PATCH 668/795] Upgrade PostCSS to 7.0.2 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index a8225c88e6..73778adea8 100644 --- a/package.json +++ b/package.json @@ -25,7 +25,7 @@ "node": ">=4.0.0" }, "dependencies": { - "postcss": "^6.0.20" + "postcss": "^7.0.2" }, "devDependencies": { "babel-core": "^6.26.0", From 24cd0d595cd17d7489a8ab642266d05e1ad4c478 Mon Sep 17 00:00:00 2001 From: Aaron Ballard Date: Wed, 15 Aug 2018 19:02:58 -0500 Subject: [PATCH 669/795] Upgrade PostCSS to 7.0.2 --- .appveyor.yml | 2 +- .travis.yml | 2 +- package.json | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.appveyor.yml b/.appveyor.yml index acbf8a5eeb..73f0d8fa3f 100644 --- a/.appveyor.yml +++ b/.appveyor.yml @@ -2,7 +2,7 @@ environment: matrix: - - nodejs_version: 4 + - nodejs_version: 6 version: "{build}" build: off diff --git a/.travis.yml b/.travis.yml index c56466446c..e1f11a52e6 100644 --- a/.travis.yml +++ b/.travis.yml @@ -3,7 +3,7 @@ language: node_js node_js: - - 4 + - 6 install: - npm install --ignore-scripts diff --git a/package.json b/package.json index eca2476197..9414434b91 100644 --- a/package.json +++ b/package.json @@ -25,7 +25,7 @@ "node": ">=4.0.0" }, "dependencies": { - "postcss": "^6.0.22" + "postcss": "^7.0.2" }, "devDependencies": { "babel-core": "^6.26.3", From ae337a2ea0360f868b5a233d6ac772f49331d445 Mon Sep 17 00:00:00 2001 From: Aaron Ballard Date: Wed, 15 Aug 2018 16:51:34 -0500 Subject: [PATCH 670/795] Upgrade PostCSS to 7.0.2 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 46ce82d6a9..d4f3166bba 100644 --- a/package.json +++ b/package.json @@ -17,7 +17,7 @@ "index.js" ], "dependencies": { - "postcss": "^6.0.1" + "postcss": "^7.0.2" }, "devDependencies": { "jscs": "^3.0.7", From 84fe5072ad418ccd07589288c61637b6f6b488b8 Mon Sep 17 00:00:00 2001 From: Aaron Ballard Date: Wed, 15 Aug 2018 11:45:38 -0500 Subject: [PATCH 671/795] Upgrade PostCSS to 7.0.2 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index c3f81d099c..15bea0b0a7 100644 --- a/package.json +++ b/package.json @@ -24,7 +24,7 @@ "node": ">=6.0.0" }, "dependencies": { - "postcss": "^6.0.22" + "postcss": "^7.0.2" }, "devDependencies": { "babel-core": "^6.26.3", From 3fdc61bdde08dbe11853cc3307748a15c1d9d2e2 Mon Sep 17 00:00:00 2001 From: Jonathan Neal Date: Tue, 4 Sep 2018 09:06:47 -0400 Subject: [PATCH 672/795] 7.0.0 --- .appveyor.yml | 2 +- .rollup.js | 2 +- CHANGELOG.md | 4 ++ INSTALL.md | 41 +++++++++++---- README.md | 2 +- package.json | 20 ++++---- test/basic.expect.css | 75 ++++++++++++++-------------- test/basic.last-1.expect.css | 75 ++++++++++++++-------------- test/basic.last-2.expect.css | 77 +++++++++++++++-------------- test/insertion-after.expect.css | 75 ++++++++++++++-------------- test/insertion-duplicate.expect.css | 75 ++++++++++++++-------------- test/option-force-import.expect.css | 75 ++++++++++++++-------------- 12 files changed, 283 insertions(+), 240 deletions(-) diff --git a/.appveyor.yml b/.appveyor.yml index d6b511f500..8e87d1d4d5 100644 --- a/.appveyor.yml +++ b/.appveyor.yml @@ -2,7 +2,7 @@ environment: matrix: - - nodejs_version: 4.0 + - nodejs_version: 6.0 version: "{build}" build: off diff --git a/.rollup.js b/.rollup.js index 48e2d2e760..ecc7800364 100644 --- a/.rollup.js +++ b/.rollup.js @@ -9,7 +9,7 @@ export default { plugins: [ babel({ presets: [ - ['env', { modules: false, targets: { node: 6 } }] + ['@babel/env', { modules: false, targets: { node: 6 } }] ] }) ] diff --git a/CHANGELOG.md b/CHANGELOG.md index 59046ee885..158975cf66 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # Changes to PostCSS Normalize +### 7.0.0 (August 24, 2018) + +- Use normalize.css v9.0.1 (major) + ### 6.0.0 (June 16, 2018) - Use normalize.css v8 (major) diff --git a/INSTALL.md b/INSTALL.md index bb335f6dee..efd6884f4d 100644 --- a/INSTALL.md +++ b/INSTALL.md @@ -2,7 +2,7 @@ [PostCSS Normalize] runs in all Node environments, with special instructions for: -| [Node](#node) | [Webpack](#webpack) | [Create React App](#create-react-app) | [Gulp](#gulp) | [Grunt](#grunt) | +| [Node](#node) | [PostCSS CLI](#postcss-cli) | [Webpack](#webpack) | [Create React App](#create-react-app) | [Gulp](#gulp) | [Grunt](#grunt) | | --- | --- | --- | --- | --- | ## Node @@ -16,7 +16,7 @@ npm install postcss-normalize --save-dev Use [PostCSS Normalize] to process your CSS: ```js -import postcssNormalize from 'postcss-normalize'; +const postcssNormalize = require('postcss-normalize'); postcssNormalize.process(YOUR_CSS /*, processOptions, pluginOptions */); ``` @@ -24,14 +24,35 @@ postcssNormalize.process(YOUR_CSS /*, processOptions, pluginOptions */); Or use it as a [PostCSS] plugin: ```js -import postcss from 'postcss'; -import postcssNormalize from 'postcss-normalize'; +const postcss = require('postcss'); +const postcssNormalize = require('postcss-normalize'); postcss([ postcssNormalize(/* pluginOptions */) ]).process(YOUR_CSS /*, processOptions */); ``` +## PostCSS CLI + +Add [PostCSS CLI] to your project: + +```bash +npm install postcss-cli --save-dev +``` + +Use [PostCSS Logical Properties and Values] in your `postcss.config.js` +configuration file: + +```js +const postcssNormalize = require('postcss-logical'); + +module.exports = { + plugins: [ + postcssNormalize(/* pluginOptions */) + ] +} +``` + ## Webpack Add [PostCSS Loader] to your project: @@ -43,7 +64,7 @@ npm install postcss-loader --save-dev Use [PostCSS Normalize] in your Webpack configuration: ```js -import postcssNormalize from 'postcss-normalize'; +const postcssNormalize = require('postcss-normalize'); module.exports = { module: { @@ -78,8 +99,8 @@ Use [React App Rewire PostCSS] and [PostCSS Normalize] in your `config-overrides.js` file: ```js -import reactAppRewirePostcss from 'react-app-rewire-postcss'; -import postcssNormalize from 'postcss-normalize'; +const reactAppRewirePostcss = require('react-app-rewire-postcss'); +const postcssNormalize = require('postcss-normalize'); export default config => reactAppRewirePostcss(config, { plugins: () => [ @@ -99,8 +120,8 @@ npm install gulp-postcss --save-dev Use [PostCSS Normalize] in your Gulpfile: ```js -import postcss from 'gulp-postcss'; -import postcssNormalize from 'postcss-normalize'; +const postcss = require('gulp-postcss'); +const postcssNormalize = require('postcss-normalize'); gulp.task('css', () => gulp.src('./src/*.css').pipe( postcss([ @@ -122,7 +143,7 @@ npm install grunt-postcss --save-dev Use [PostCSS Normalize] in your Gruntfile: ```js -import postcssNormalize from 'postcss-normalize'; +const postcssNormalize = require('postcss-normalize'); grunt.loadNpmTasks('grunt-postcss'); diff --git a/README.md b/README.md index ae01eb8d17..ed700d3ae7 100644 --- a/README.md +++ b/README.md @@ -91,7 +91,7 @@ postcss([ [PostCSS Normalize] runs in all Node environments, with special instructions for: -| [Node](INSTALL.md#node) | [Webpack](INSTALL.md#webpack) | [Create React App](INSTALL.md#create-react-app) | [Gulp](INSTALL.md#gulp) | [Grunt](INSTALL.md#grunt) | +| [Node](INSTALL.md#node) | [PostCSS CLI](INSTALL.md#postcss-cli) | [Webpack](INSTALL.md#webpack) | [Create React App](INSTALL.md#create-react-app) | [Gulp](INSTALL.md#gulp) | [Grunt](INSTALL.md#grunt) | | --- | --- | --- | --- | --- | ## Options diff --git a/package.json b/package.json index 189dcbc7a0..ed63b440f9 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "postcss-normalize", - "version": "6.0.0", + "version": "7.0.0", "description": "Use the parts of normalize.css you need from your browserslist", "author": "Jonathan Neal ", "license": "CC0-1.0", @@ -24,21 +24,21 @@ "node": ">=6.0.0" }, "dependencies": { - "@csstools/normalize.css": "^8.0.0", - "browserslist": "^3.2.8", - "postcss": "^6.0.22", + "@csstools/normalize.css": "^9.0.1", + "browserslist": "^4.1.0", + "postcss": "^7.0.2", "postcss-browser-comments": "^1.0.0" }, "devDependencies": { - "babel-core": "^6.26.3", - "babel-eslint": "^8.2.3", - "babel-preset-env": "^1.7.0", - "eslint": "^4.19.1", + "@babel/core": "^7.0.0", + "@babel/preset-env": "^7.0.0", + "babel-eslint": "^9.0.0", + "eslint": "^5.5.0", "eslint-config-dev": "^2.0.0", "postcss-tape": "^2.2.0", "pre-commit": "^1.2.2", - "rollup": "^0.60.7", - "rollup-plugin-babel": "^3.0.4" + "rollup": "^0.65.0", + "rollup-plugin-babel": "^4.0.1" }, "eslintConfig": { "extends": "dev", diff --git a/test/basic.expect.css b/test/basic.expect.css index 20e294d860..f85bc306a7 100644 --- a/test/basic.expect.css +++ b/test/basic.expect.css @@ -1,4 +1,4 @@ -/*! normalize.css v8.0.0 | MIT License | github.com/csstools/normalize.css */ +/*! normalize.css v9.0.1 | MIT License | github.com/csstools/normalize.css */ /* Document * ========================================================================== */ @@ -116,14 +116,12 @@ svg:not(:root) { * ========================================================================== */ /** - * Remove the margin in Firefox and Safari. + * Remove the margin in Safari. */ button, input, -optgroup, -select, -textarea { +select { margin: 0; } @@ -148,26 +146,6 @@ button, -webkit-appearance: button; } -/** - * Remove the inner border and padding in Firefox. - */ - -::-moz-focus-inner { - border-style: none; - padding: 0; -} - -/** - * Restore the focus styles unset by the previous rule in Firefox. - */ - -button:-moz-focusring, -[type="button"]:-moz-focusring, -[type="reset"]:-moz-focusring, -[type="submit"]:-moz-focusring { - outline: 1px dotted ButtonText; -} - /** * Correct the padding in Firefox. */ @@ -187,8 +165,6 @@ input { /** * 1. Correct the text wrapping in Edge and IE. * 2. Correct the color inheritance from `fieldset` elements in IE. - * 3. Remove the padding so developers are not caught out when they zero out - * `fieldset` elements in all browsers. */ legend { @@ -196,7 +172,6 @@ legend { color: inherit; /* 2 */ display: table; /* 1 */ max-width: 100%; /* 1 */ - padding: 0; /* 3 */ white-space: normal; /* 1 */ } @@ -219,15 +194,27 @@ select { } /** - * Remove the default vertical scrollbar in IE. + * 1. Remove the margin in Firefox and Safari. + * 2. Remove the default vertical scrollbar in IE. */ textarea { - overflow: auto; + margin: 0; /* 1 */ + overflow: auto; /* 2 */ } /** - * Correct the cursor style of increment and decrement buttons in Chrome. + * 1. Correct the odd appearance in Chrome and Safari. + * 2. Correct the outline style in Safari. + */ + +[type="search"] { + -webkit-appearance: textfield; /* 1 */ + outline-offset: -2px; /* 2 */ +} + +/** + * Correct the cursor style of increment and decrement buttons in Safari. */ ::-webkit-inner-spin-button, @@ -236,13 +223,12 @@ textarea { } /** - * 1. Correct the odd appearance in Chrome and Safari. - * 2. Correct the outline style in Safari. + * Correct the text style of placeholders in Chrome, Edge, and Safari. */ -[type="search"] { - -webkit-appearance: textfield; /* 1 */ - outline-offset: -2px; /* 2 */ +::-webkit-input-placeholder { + color: inherit; + opacity: 0.54; } /** @@ -263,6 +249,23 @@ textarea { font: inherit; /* 2 */ } +/** + * Remove the inner border and padding of focus outlines in Firefox. + */ + +::-moz-focus-inner { + border-style: none; + padding: 0; +} + +/** + * Restore the focus outline styles unset by the previous rule in Firefox. + */ + +:-moz-focusring { + outline: 1px dotted ButtonText; +} + /* Interactive * ========================================================================== */ diff --git a/test/basic.last-1.expect.css b/test/basic.last-1.expect.css index 20e294d860..f85bc306a7 100644 --- a/test/basic.last-1.expect.css +++ b/test/basic.last-1.expect.css @@ -1,4 +1,4 @@ -/*! normalize.css v8.0.0 | MIT License | github.com/csstools/normalize.css */ +/*! normalize.css v9.0.1 | MIT License | github.com/csstools/normalize.css */ /* Document * ========================================================================== */ @@ -116,14 +116,12 @@ svg:not(:root) { * ========================================================================== */ /** - * Remove the margin in Firefox and Safari. + * Remove the margin in Safari. */ button, input, -optgroup, -select, -textarea { +select { margin: 0; } @@ -148,26 +146,6 @@ button, -webkit-appearance: button; } -/** - * Remove the inner border and padding in Firefox. - */ - -::-moz-focus-inner { - border-style: none; - padding: 0; -} - -/** - * Restore the focus styles unset by the previous rule in Firefox. - */ - -button:-moz-focusring, -[type="button"]:-moz-focusring, -[type="reset"]:-moz-focusring, -[type="submit"]:-moz-focusring { - outline: 1px dotted ButtonText; -} - /** * Correct the padding in Firefox. */ @@ -187,8 +165,6 @@ input { /** * 1. Correct the text wrapping in Edge and IE. * 2. Correct the color inheritance from `fieldset` elements in IE. - * 3. Remove the padding so developers are not caught out when they zero out - * `fieldset` elements in all browsers. */ legend { @@ -196,7 +172,6 @@ legend { color: inherit; /* 2 */ display: table; /* 1 */ max-width: 100%; /* 1 */ - padding: 0; /* 3 */ white-space: normal; /* 1 */ } @@ -219,15 +194,27 @@ select { } /** - * Remove the default vertical scrollbar in IE. + * 1. Remove the margin in Firefox and Safari. + * 2. Remove the default vertical scrollbar in IE. */ textarea { - overflow: auto; + margin: 0; /* 1 */ + overflow: auto; /* 2 */ } /** - * Correct the cursor style of increment and decrement buttons in Chrome. + * 1. Correct the odd appearance in Chrome and Safari. + * 2. Correct the outline style in Safari. + */ + +[type="search"] { + -webkit-appearance: textfield; /* 1 */ + outline-offset: -2px; /* 2 */ +} + +/** + * Correct the cursor style of increment and decrement buttons in Safari. */ ::-webkit-inner-spin-button, @@ -236,13 +223,12 @@ textarea { } /** - * 1. Correct the odd appearance in Chrome and Safari. - * 2. Correct the outline style in Safari. + * Correct the text style of placeholders in Chrome, Edge, and Safari. */ -[type="search"] { - -webkit-appearance: textfield; /* 1 */ - outline-offset: -2px; /* 2 */ +::-webkit-input-placeholder { + color: inherit; + opacity: 0.54; } /** @@ -263,6 +249,23 @@ textarea { font: inherit; /* 2 */ } +/** + * Remove the inner border and padding of focus outlines in Firefox. + */ + +::-moz-focus-inner { + border-style: none; + padding: 0; +} + +/** + * Restore the focus outline styles unset by the previous rule in Firefox. + */ + +:-moz-focusring { + outline: 1px dotted ButtonText; +} + /* Interactive * ========================================================================== */ diff --git a/test/basic.last-2.expect.css b/test/basic.last-2.expect.css index 1d08211fdb..92c7c8d7bf 100644 --- a/test/basic.last-2.expect.css +++ b/test/basic.last-2.expect.css @@ -1,4 +1,4 @@ -/*! normalize.css v8.0.0 | MIT License | github.com/csstools/normalize.css */ +/*! normalize.css v9.0.1 | MIT License | github.com/csstools/normalize.css */ /* Document * ========================================================================== */ @@ -68,7 +68,7 @@ pre { */ a { - background-color: transparent; /* 1 */ + background-color: transparent; } /** @@ -132,14 +132,12 @@ svg:not(:root) { * ========================================================================== */ /** - * Remove the margin in Firefox and Safari. + * Remove the margin in Safari. */ button, input, -optgroup, -select, -textarea { +select { margin: 0; } @@ -164,26 +162,6 @@ button, -webkit-appearance: button; } -/** - * Remove the inner border and padding in Firefox. - */ - -::-moz-focus-inner { - border-style: none; - padding: 0; -} - -/** - * Restore the focus styles unset by the previous rule in Firefox. - */ - -button:-moz-focusring, -[type="button"]:-moz-focusring, -[type="reset"]:-moz-focusring, -[type="submit"]:-moz-focusring { - outline: 1px dotted ButtonText; -} - /** * Correct the padding in Firefox. */ @@ -203,8 +181,6 @@ input { /** * 1. Correct the text wrapping in Edge and IE. * 2. Correct the color inheritance from `fieldset` elements in IE. - * 3. Remove the padding so developers are not caught out when they zero out - * `fieldset` elements in all browsers. */ legend { @@ -212,7 +188,6 @@ legend { color: inherit; /* 2 */ display: table; /* 1 */ max-width: 100%; /* 1 */ - padding: 0; /* 3 */ white-space: normal; /* 1 */ } @@ -235,11 +210,13 @@ select { } /** - * Remove the default vertical scrollbar in IE. + * 1. Remove the margin in Firefox and Safari. + * 2. Remove the default vertical scrollbar in IE. */ textarea { - overflow: auto; + margin: 0; /* 1 */ + overflow: auto; /* 2 */ } /** @@ -254,7 +231,17 @@ textarea { } /** - * Correct the cursor style of increment and decrement buttons in Chrome. + * 1. Correct the odd appearance in Chrome and Safari. + * 2. Correct the outline style in Safari. + */ + +[type="search"] { + -webkit-appearance: textfield; /* 1 */ + outline-offset: -2px; /* 2 */ +} + +/** + * Correct the cursor style of increment and decrement buttons in Safari. */ ::-webkit-inner-spin-button, @@ -263,13 +250,12 @@ textarea { } /** - * 1. Correct the odd appearance in Chrome and Safari. - * 2. Correct the outline style in Safari. + * Correct the text style of placeholders in Chrome, Edge, and Safari. */ -[type="search"] { - -webkit-appearance: textfield; /* 1 */ - outline-offset: -2px; /* 2 */ +::-webkit-input-placeholder { + color: inherit; + opacity: 0.54; } /** @@ -290,6 +276,23 @@ textarea { font: inherit; /* 2 */ } +/** + * Remove the inner border and padding of focus outlines in Firefox. + */ + +::-moz-focus-inner { + border-style: none; + padding: 0; +} + +/** + * Restore the focus outline styles unset by the previous rule in Firefox. + */ + +:-moz-focusring { + outline: 1px dotted ButtonText; +} + /* Interactive * ========================================================================== */ diff --git a/test/insertion-after.expect.css b/test/insertion-after.expect.css index ef9b4f6a9b..f7f7a12d9a 100644 --- a/test/insertion-after.expect.css +++ b/test/insertion-after.expect.css @@ -2,7 +2,7 @@ body { font-family: sans-serif; } -/*! normalize.css v8.0.0 | MIT License | github.com/csstools/normalize.css */ +/*! normalize.css v9.0.1 | MIT License | github.com/csstools/normalize.css */ /* Document * ========================================================================== */ @@ -120,14 +120,12 @@ svg:not(:root) { * ========================================================================== */ /** - * Remove the margin in Firefox and Safari. + * Remove the margin in Safari. */ button, input, -optgroup, -select, -textarea { +select { margin: 0; } @@ -152,26 +150,6 @@ button, -webkit-appearance: button; } -/** - * Remove the inner border and padding in Firefox. - */ - -::-moz-focus-inner { - border-style: none; - padding: 0; -} - -/** - * Restore the focus styles unset by the previous rule in Firefox. - */ - -button:-moz-focusring, -[type="button"]:-moz-focusring, -[type="reset"]:-moz-focusring, -[type="submit"]:-moz-focusring { - outline: 1px dotted ButtonText; -} - /** * Correct the padding in Firefox. */ @@ -191,8 +169,6 @@ input { /** * 1. Correct the text wrapping in Edge and IE. * 2. Correct the color inheritance from `fieldset` elements in IE. - * 3. Remove the padding so developers are not caught out when they zero out - * `fieldset` elements in all browsers. */ legend { @@ -200,7 +176,6 @@ legend { color: inherit; /* 2 */ display: table; /* 1 */ max-width: 100%; /* 1 */ - padding: 0; /* 3 */ white-space: normal; /* 1 */ } @@ -223,15 +198,27 @@ select { } /** - * Remove the default vertical scrollbar in IE. + * 1. Remove the margin in Firefox and Safari. + * 2. Remove the default vertical scrollbar in IE. */ textarea { - overflow: auto; + margin: 0; /* 1 */ + overflow: auto; /* 2 */ } /** - * Correct the cursor style of increment and decrement buttons in Chrome. + * 1. Correct the odd appearance in Chrome and Safari. + * 2. Correct the outline style in Safari. + */ + +[type="search"] { + -webkit-appearance: textfield; /* 1 */ + outline-offset: -2px; /* 2 */ +} + +/** + * Correct the cursor style of increment and decrement buttons in Safari. */ ::-webkit-inner-spin-button, @@ -240,13 +227,12 @@ textarea { } /** - * 1. Correct the odd appearance in Chrome and Safari. - * 2. Correct the outline style in Safari. + * Correct the text style of placeholders in Chrome, Edge, and Safari. */ -[type="search"] { - -webkit-appearance: textfield; /* 1 */ - outline-offset: -2px; /* 2 */ +::-webkit-input-placeholder { + color: inherit; + opacity: 0.54; } /** @@ -267,6 +253,23 @@ textarea { font: inherit; /* 2 */ } +/** + * Remove the inner border and padding of focus outlines in Firefox. + */ + +::-moz-focus-inner { + border-style: none; + padding: 0; +} + +/** + * Restore the focus outline styles unset by the previous rule in Firefox. + */ + +:-moz-focusring { + outline: 1px dotted ButtonText; +} + /* Interactive * ========================================================================== */ diff --git a/test/insertion-duplicate.expect.css b/test/insertion-duplicate.expect.css index 20e294d860..f85bc306a7 100644 --- a/test/insertion-duplicate.expect.css +++ b/test/insertion-duplicate.expect.css @@ -1,4 +1,4 @@ -/*! normalize.css v8.0.0 | MIT License | github.com/csstools/normalize.css */ +/*! normalize.css v9.0.1 | MIT License | github.com/csstools/normalize.css */ /* Document * ========================================================================== */ @@ -116,14 +116,12 @@ svg:not(:root) { * ========================================================================== */ /** - * Remove the margin in Firefox and Safari. + * Remove the margin in Safari. */ button, input, -optgroup, -select, -textarea { +select { margin: 0; } @@ -148,26 +146,6 @@ button, -webkit-appearance: button; } -/** - * Remove the inner border and padding in Firefox. - */ - -::-moz-focus-inner { - border-style: none; - padding: 0; -} - -/** - * Restore the focus styles unset by the previous rule in Firefox. - */ - -button:-moz-focusring, -[type="button"]:-moz-focusring, -[type="reset"]:-moz-focusring, -[type="submit"]:-moz-focusring { - outline: 1px dotted ButtonText; -} - /** * Correct the padding in Firefox. */ @@ -187,8 +165,6 @@ input { /** * 1. Correct the text wrapping in Edge and IE. * 2. Correct the color inheritance from `fieldset` elements in IE. - * 3. Remove the padding so developers are not caught out when they zero out - * `fieldset` elements in all browsers. */ legend { @@ -196,7 +172,6 @@ legend { color: inherit; /* 2 */ display: table; /* 1 */ max-width: 100%; /* 1 */ - padding: 0; /* 3 */ white-space: normal; /* 1 */ } @@ -219,15 +194,27 @@ select { } /** - * Remove the default vertical scrollbar in IE. + * 1. Remove the margin in Firefox and Safari. + * 2. Remove the default vertical scrollbar in IE. */ textarea { - overflow: auto; + margin: 0; /* 1 */ + overflow: auto; /* 2 */ } /** - * Correct the cursor style of increment and decrement buttons in Chrome. + * 1. Correct the odd appearance in Chrome and Safari. + * 2. Correct the outline style in Safari. + */ + +[type="search"] { + -webkit-appearance: textfield; /* 1 */ + outline-offset: -2px; /* 2 */ +} + +/** + * Correct the cursor style of increment and decrement buttons in Safari. */ ::-webkit-inner-spin-button, @@ -236,13 +223,12 @@ textarea { } /** - * 1. Correct the odd appearance in Chrome and Safari. - * 2. Correct the outline style in Safari. + * Correct the text style of placeholders in Chrome, Edge, and Safari. */ -[type="search"] { - -webkit-appearance: textfield; /* 1 */ - outline-offset: -2px; /* 2 */ +::-webkit-input-placeholder { + color: inherit; + opacity: 0.54; } /** @@ -263,6 +249,23 @@ textarea { font: inherit; /* 2 */ } +/** + * Remove the inner border and padding of focus outlines in Firefox. + */ + +::-moz-focus-inner { + border-style: none; + padding: 0; +} + +/** + * Restore the focus outline styles unset by the previous rule in Firefox. + */ + +:-moz-focusring { + outline: 1px dotted ButtonText; +} + /* Interactive * ========================================================================== */ diff --git a/test/option-force-import.expect.css b/test/option-force-import.expect.css index 20e294d860..f85bc306a7 100644 --- a/test/option-force-import.expect.css +++ b/test/option-force-import.expect.css @@ -1,4 +1,4 @@ -/*! normalize.css v8.0.0 | MIT License | github.com/csstools/normalize.css */ +/*! normalize.css v9.0.1 | MIT License | github.com/csstools/normalize.css */ /* Document * ========================================================================== */ @@ -116,14 +116,12 @@ svg:not(:root) { * ========================================================================== */ /** - * Remove the margin in Firefox and Safari. + * Remove the margin in Safari. */ button, input, -optgroup, -select, -textarea { +select { margin: 0; } @@ -148,26 +146,6 @@ button, -webkit-appearance: button; } -/** - * Remove the inner border and padding in Firefox. - */ - -::-moz-focus-inner { - border-style: none; - padding: 0; -} - -/** - * Restore the focus styles unset by the previous rule in Firefox. - */ - -button:-moz-focusring, -[type="button"]:-moz-focusring, -[type="reset"]:-moz-focusring, -[type="submit"]:-moz-focusring { - outline: 1px dotted ButtonText; -} - /** * Correct the padding in Firefox. */ @@ -187,8 +165,6 @@ input { /** * 1. Correct the text wrapping in Edge and IE. * 2. Correct the color inheritance from `fieldset` elements in IE. - * 3. Remove the padding so developers are not caught out when they zero out - * `fieldset` elements in all browsers. */ legend { @@ -196,7 +172,6 @@ legend { color: inherit; /* 2 */ display: table; /* 1 */ max-width: 100%; /* 1 */ - padding: 0; /* 3 */ white-space: normal; /* 1 */ } @@ -219,15 +194,27 @@ select { } /** - * Remove the default vertical scrollbar in IE. + * 1. Remove the margin in Firefox and Safari. + * 2. Remove the default vertical scrollbar in IE. */ textarea { - overflow: auto; + margin: 0; /* 1 */ + overflow: auto; /* 2 */ } /** - * Correct the cursor style of increment and decrement buttons in Chrome. + * 1. Correct the odd appearance in Chrome and Safari. + * 2. Correct the outline style in Safari. + */ + +[type="search"] { + -webkit-appearance: textfield; /* 1 */ + outline-offset: -2px; /* 2 */ +} + +/** + * Correct the cursor style of increment and decrement buttons in Safari. */ ::-webkit-inner-spin-button, @@ -236,13 +223,12 @@ textarea { } /** - * 1. Correct the odd appearance in Chrome and Safari. - * 2. Correct the outline style in Safari. + * Correct the text style of placeholders in Chrome, Edge, and Safari. */ -[type="search"] { - -webkit-appearance: textfield; /* 1 */ - outline-offset: -2px; /* 2 */ +::-webkit-input-placeholder { + color: inherit; + opacity: 0.54; } /** @@ -263,6 +249,23 @@ textarea { font: inherit; /* 2 */ } +/** + * Remove the inner border and padding of focus outlines in Firefox. + */ + +::-moz-focus-inner { + border-style: none; + padding: 0; +} + +/** + * Restore the focus outline styles unset by the previous rule in Firefox. + */ + +:-moz-focusring { + outline: 1px dotted ButtonText; +} + /* Interactive * ========================================================================== */ From e5e3797e1ad02065e2e6544f6c4288569d7167be Mon Sep 17 00:00:00 2001 From: Jonathan Neal Date: Thu, 6 Sep 2018 08:26:04 -0400 Subject: [PATCH 673/795] 7.0.1 --- CHANGELOG.md | 7 +++++++ INSTALL.md | 11 ++++++----- README.md | 2 +- package.json | 10 +++++----- 4 files changed, 19 insertions(+), 11 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 158975cf66..3be8990b9f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,12 @@ # Changes to PostCSS Normalize +### 7.0.1 (August 24, 2018) + +- Use postcss-browser-comments v2.0.0 (major, but a patch for this project) + +PostCSS Browser Comments was using an older version of PostCSS, requiring 2 +versions of PostCSS to use PostCSS Normalize. This update resolves that. + ### 7.0.0 (August 24, 2018) - Use normalize.css v9.0.1 (major) diff --git a/INSTALL.md b/INSTALL.md index efd6884f4d..d93d586e49 100644 --- a/INSTALL.md +++ b/INSTALL.md @@ -1,9 +1,10 @@ # Installing PostCSS Normalize -[PostCSS Normalize] runs in all Node environments, with special instructions for: +[PostCSS Normalize] runs in all Node environments, with special instructions +for: | [Node](#node) | [PostCSS CLI](#postcss-cli) | [Webpack](#webpack) | [Create React App](#create-react-app) | [Gulp](#gulp) | [Grunt](#grunt) | -| --- | --- | --- | --- | --- | +| --- | --- | --- | --- | --- | --- | ## Node @@ -40,11 +41,10 @@ Add [PostCSS CLI] to your project: npm install postcss-cli --save-dev ``` -Use [PostCSS Logical Properties and Values] in your `postcss.config.js` -configuration file: +Use [PostCSS Normalize] in your `postcss.config.js` configuration file: ```js -const postcssNormalize = require('postcss-logical'); +const postcssNormalize = require('postcss-normalize'); module.exports = { plugins: [ @@ -164,6 +164,7 @@ grunt.initConfig({ [Gulp PostCSS]: https://github.com/postcss/gulp-postcss [Grunt PostCSS]: https://github.com/nDmitry/grunt-postcss [PostCSS]: https://github.com/postcss/postcss +[PostCSS CLI]: https://github.com/postcss/postcss-cli [PostCSS Loader]: https://github.com/postcss/postcss-loader [PostCSS Normalize]: https://github.com/csstools/postcss-normalize [React App Rewire PostCSS]: https://github.com/csstools/react-app-rewire-postcss diff --git a/README.md b/README.md index ed700d3ae7..9a2983ed06 100644 --- a/README.md +++ b/README.md @@ -92,7 +92,7 @@ postcss([ [PostCSS Normalize] runs in all Node environments, with special instructions for: | [Node](INSTALL.md#node) | [PostCSS CLI](INSTALL.md#postcss-cli) | [Webpack](INSTALL.md#webpack) | [Create React App](INSTALL.md#create-react-app) | [Gulp](INSTALL.md#gulp) | [Grunt](INSTALL.md#grunt) | -| --- | --- | --- | --- | --- | +| --- | --- | --- | --- | --- | --- | ## Options diff --git a/package.json b/package.json index ed63b440f9..2bcb22952c 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "postcss-normalize", - "version": "7.0.0", + "version": "7.0.1", "description": "Use the parts of normalize.css you need from your browserslist", "author": "Jonathan Neal ", "license": "CC0-1.0", @@ -25,9 +25,9 @@ }, "dependencies": { "@csstools/normalize.css": "^9.0.1", - "browserslist": "^4.1.0", + "browserslist": "^4.1.1", "postcss": "^7.0.2", - "postcss-browser-comments": "^1.0.0" + "postcss-browser-comments": "^2.0.0" }, "devDependencies": { "@babel/core": "^7.0.0", @@ -37,8 +37,8 @@ "eslint-config-dev": "^2.0.0", "postcss-tape": "^2.2.0", "pre-commit": "^1.2.2", - "rollup": "^0.65.0", - "rollup-plugin-babel": "^4.0.1" + "rollup": "^0.65.2", + "rollup-plugin-babel": "^4.0.3" }, "eslintConfig": { "extends": "dev", From aadf18cc6d098b0c6e8be6743b990e457f949d8b Mon Sep 17 00:00:00 2001 From: Jonathan Neal Date: Sat, 8 Sep 2018 14:33:25 -0400 Subject: [PATCH 674/795] 5.0.0 --- .babelrc | 13 - .editorconfig | 10 +- .eslintignore | 1 - .eslintrc.yml | 36 - .gitignore | 15 +- .rollup.js | 19 + .tape.js | 47 + .travis.yml | 11 +- CHANGELOG.md | 33 +- CONTRIBUTING.md | 65 + INSTALL.md | 170 + LICENSE => LICENSE.md | 17 +- README.md | 332 +- index.js | 24 + lib/custom-selectors-from-root.js | 34 + lib/import-from.js | 119 + lib/selectors-ast-from-selectors-string.js | 14 + lib/transform-rules.js | 19 + ...transform-selectors-by-custom-selectors.js | 52 + package-lock.json | 4144 ----------------- package.json | 84 +- src/index.js | 78 - test/basic.css | 94 + test/basic.expect.css | 57 + test/basic.import.expect.css | 57 + test/basic.preserve.expect.css | 148 + test/import-selectors.css | 1 + test/import-selectors.js | 5 + test/import-selectors.json | 5 + 29 files changed, 1108 insertions(+), 4596 deletions(-) delete mode 100644 .babelrc delete mode 100644 .eslintignore delete mode 100644 .eslintrc.yml create mode 100644 .rollup.js create mode 100644 .tape.js create mode 100644 CONTRIBUTING.md create mode 100644 INSTALL.md rename LICENSE => LICENSE.md (61%) create mode 100644 index.js create mode 100644 lib/custom-selectors-from-root.js create mode 100644 lib/import-from.js create mode 100644 lib/selectors-ast-from-selectors-string.js create mode 100644 lib/transform-rules.js create mode 100644 lib/transform-selectors-by-custom-selectors.js delete mode 100644 package-lock.json delete mode 100644 src/index.js create mode 100644 test/basic.css create mode 100644 test/basic.expect.css create mode 100644 test/basic.import.expect.css create mode 100644 test/basic.preserve.expect.css create mode 100644 test/import-selectors.css create mode 100644 test/import-selectors.js create mode 100644 test/import-selectors.json diff --git a/.babelrc b/.babelrc deleted file mode 100644 index dd69366430..0000000000 --- a/.babelrc +++ /dev/null @@ -1,13 +0,0 @@ -{ - "presets": [ - ["env", { - "targets": { - "node": 4 - } - }] - ], - "plugins": [ - "transform-object-rest-spread", - "add-module-exports" - ] -} diff --git a/.editorconfig b/.editorconfig index dffb18adfb..e06d7982bc 100644 --- a/.editorconfig +++ b/.editorconfig @@ -1,13 +1,15 @@ -# editorconfig.org root = true [*] charset = utf-8 -indent_style = space -indent_size = 2 end_of_line = lf -trim_trailing_whitespace = true +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/.eslintignore b/.eslintignore deleted file mode 100644 index 1521c8b765..0000000000 --- a/.eslintignore +++ /dev/null @@ -1 +0,0 @@ -dist diff --git a/.eslintrc.yml b/.eslintrc.yml deleted file mode 100644 index 39a8cb81ad..0000000000 --- a/.eslintrc.yml +++ /dev/null @@ -1,36 +0,0 @@ -root: true -extends: eslint:recommended - -parserOptions: - ecmaVersion: 6 - sourceType: "module" - ecmaFeatures: - experimentalObjectRestSpread: true - -rules: - indent: [2, 2] # 2 spaces indentation - max-len: [2, 80, 4] - 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"] diff --git a/.gitignore b/.gitignore index 9d0bd2bf07..d920b78fec 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,11 @@ -.DS_Store -*.sublime-workspace - node_modules -test/fixtures/*/actual.css -dist +index.*.* +package-lock.json +*.log* +*.result.css +.* +!.editorconfig +!.gitignore +!.rollup.js +!.tape.js +!.travis.yml diff --git a/.rollup.js b/.rollup.js new file mode 100644 index 0000000000..eab5c0d513 --- /dev/null +++ b/.rollup.js @@ -0,0 +1,19 @@ +import babel from 'rollup-plugin-babel'; + +export default { + input: 'index.js', + output: [ + { file: 'index.cjs.js', format: 'cjs' }, + { file: 'index.es.mjs', format: 'es' } + ], + plugins: [ + babel({ + plugins: [ + '@babel/plugin-syntax-dynamic-import' + ], + presets: [ + ['@babel/env', { modules: false, targets: { node: 6 } }] + ] + }) + ] +}; diff --git a/.tape.js b/.tape.js new file mode 100644 index 0000000000..c4485d4bf8 --- /dev/null +++ b/.tape.js @@ -0,0 +1,47 @@ +module.exports = { + 'postcss-custom-selectors': { + 'basic': { + message: 'supports basic usage' + }, + 'basic:preserve': { + message: 'supports { preserve: true } usage', + options: { + preserve: true + } + }, + 'basic:import': { + message: 'supports { importFrom: { customSelectors: { ... } } } usage', + options: { + importFrom: { + customSelectors: { + ':--heading': 'h1, h2, h3' + } + } + } + }, + 'basic:import-json': { + message: 'supports { importFrom: "test/import-selectors.json" } usage', + options: { + importFrom: 'test/import-selectors.json' + }, + expect: 'basic.import.expect.css', + result: 'basic.import.result.css' + }, + 'basic:import-js': { + message: 'supports { importFrom: "test/import-selectors.js" } usage', + options: { + importFrom: 'test/import-selectors.js' + }, + expect: 'basic.import.expect.css', + result: 'basic.import.result.css' + }, + 'basic:import-css': { + message: 'supports { importFrom: "test/import-selectors.css" } usage', + options: { + importFrom: 'test/import-selectors.css' + }, + expect: 'basic.import.expect.css', + result: 'basic.import.result.css' + } + } +}; diff --git a/.travis.yml b/.travis.yml index 527110b309..e1f11a52e6 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,6 +1,9 @@ -sudo: false +# https://docs.travis-ci.com/user/travis-lint + language: node_js + node_js: - - stable - - "8" - - "6" + - 6 + +install: + - npm install --ignore-scripts diff --git a/CHANGELOG.md b/CHANGELOG.md index 0debc9eed9..cebfe28aa1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,47 +1,56 @@ -# 4.0.1 - 2017-05-15 +# Changes to PostCSS Custom Selectors + +### 5.0.0 (September 7, 2018) + +- Added: New `preserve` option to preserve custom selectors and rules using them +- Added: New `importFrom` option to specify where to import custom selectors +- Added: Support for PostCSS v7 +- Added: Support for Node v6+ + +### 4.0.1 (May 15, 2017) - Fixed: incorrect export -# 4.0.0 - 2017-05-12 +### 4.0.0 (May 12, 2017) - Added: compatibility with postcss v6.x -# 3.0.0 - 2015-08-25 +### 3.0.0 (August 25, 2015) - Removed: compatibility with postcss v4.x - Added: compatibility with postcss v5.x -# 2.3.0 - 2015-07-14 +### 2.3.0 (July 14, 2015) * Fixed: Nested/mixed selectors now works correctly ([#19](https://github.com/postcss/postcss-custom-selectors/issues/19)) * Added: `transformMatches` option to limit transformation to :matches() replacements. -# 2.2.0 - 2015-06-30 +### 2.2.0 (June 30, 2015) * Fixed: No more useless warnings for undefined non custom selectors ([#22](https://github.com/postcss/postcss-custom-selectors/issues/22)) * Changed: warnings now use PostCSS message API -# 2.1.1 - 2015-06-30 +### 2.1.1 (June 30, 2015) * Fixed: the lineBreak option keeping the selectors indent ([#18](https://github.com/postcss/postcss-custom-selectors/issues/18)) * Fixed: the tip of an undefined selector ([#20](https://github.com/postcss/postcss-custom-selectors/issues/20)) -# 2.1.0 - 2015-06-04 +### 2.1.0 (June 4, 2015) * Changed: use PostCSS 4.1 plugin API ([#13](https://github.com/postcss/postcss-custom-selectors/issues/13)) -# 2.0.1 - 2015-06-03 +### 2.0.1 (June 3, 2015) * Fixed: `(foo, bar)` conversion error exists in the selector (See also [:matches() test](test/fixtures/matches/input.css)) -# 2.0.0 - 2015-05-29 +### 2.0.0 (May 29, 2015) * Removed: no longer support `::` or `--` to defined a custom selectors, you must use the syntax `:--` to define it. @@ -50,14 +59,14 @@ you must use the syntax `:--` to define it. ([#14](https://github.com/postcss/postcss-custom-selectors/issues/14)) -# 1.1.1 - 2015-04-06 +### 1.1.1 (April 6, 2015) * Fixed: add support for multilines definition -# 1.1.0 - 2014-12-06 +### 1.1.0 (December 6, 2014) * Added: "lineBreak" option -# 1.0.0 - 2014-12-06 +### 1.0.0 (December 6, 2014) * First release diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 0000000000..c345221e55 --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,65 @@ +# Contributing to PostCSS Custom Selectors + +You want to help? You rock! Now, take a moment to be sure your contributions +make sense to everyone else. + +## Reporting Issues + +Found a problem? Want a new feature? + +- See if your issue or idea has [already been reported]. +- Provide a [reduced test case] or a [live example]. + +Remember, a bug is a _demonstrable problem_ caused by _our_ code. + +## Submitting Pull Requests + +Pull requests are the greatest contributions, so be sure they are focused in +scope and avoid unrelated commits. + +1. To begin; [fork this project], clone your fork, and add our upstream. + ```bash + # Clone your fork of the repo into the current directory + git clone git@github.com:YOUR_USER/postcss-custom-selectors.git + + # Navigate to the newly cloned directory + cd postcss-custom-selectors + + # Assign the original repo to a remote called "upstream" + git remote add upstream git@github.com:jonathantneal/postcss-custom-selectors.git + + # Install the tools necessary for testing + npm install + ``` + +2. Create a branch for your feature or fix: + ```bash + # Move into a new branch for your feature + git checkout -b feature/thing + ``` + ```bash + # Move into a new branch for your fix + git checkout -b fix/something + ``` + +3. If your code follows our practices, then push your feature branch: + ```bash + # Test current code + npm test + ``` + ```bash + # Push the branch for your new feature + git push origin feature/thing + ``` + ```bash + # Or, push the branch for your update + git push origin update/something + ``` + +That’s it! Now [open a pull request] with a clear title and description. + +[already been reported]: issues +[fork this project]: fork +[live example]: https://codepen.io/pen +[open a pull request]: https://help.github.com/articles/using-pull-requests/ +[reduced test case]: https://css-tricks.com/reduced-test-cases/ diff --git a/INSTALL.md b/INSTALL.md new file mode 100644 index 0000000000..ae9a9ce163 --- /dev/null +++ b/INSTALL.md @@ -0,0 +1,170 @@ +# Installing PostCSS Custom Selectors + +[PostCSS Custom Selectors] runs in all Node environments, with special instructions for: + +| [Node](#node) | [PostCSS CLI](#postcss-cli) | [Webpack](#webpack) | [Create React App](#create-react-app) | [Gulp](#gulp) | [Grunt](#grunt) | +| --- | --- | --- | --- | --- | --- | + +## Node + +Add [PostCSS Custom Selectors] to your project: + +```bash +npm install postcss-custom-selectors --save-dev +``` + +Use [PostCSS Custom Selectors] to process your CSS: + +```js +const postcssCustomSelectors = require('postcss-custom-selectors'); + +postcssCustomSelectors.process(YOUR_CSS /*, processOptions, pluginOptions */); +``` + +Or use it as a [PostCSS] plugin: + +```js +const postcss = require('postcss'); +const postcssCustomSelectors = require('postcss-custom-selectors'); + +postcss([ + postcssCustomSelectors(/* pluginOptions */) +]).process(YOUR_CSS /*, processOptions */); +``` + +## PostCSS CLI + +Add [PostCSS CLI] to your project: + +```bash +npm install postcss-cli --save-dev +``` + +Use [PostCSS Custom Selectors] in your `postcss.config.js` configuration file: + +```js +const postcssCustomSelectors = require('postcss-custom-selectors'); + +module.exports = { + plugins: [ + postcssCustomSelectors(/* pluginOptions */) + ] +} +``` + +## Webpack + +Add [PostCSS Loader] to your project: + +```bash +npm install postcss-loader --save-dev +``` + +Use [PostCSS Custom Selectors] in your Webpack configuration: + +```js +const postcssCustomSelectors = require('postcss-custom-selectors'); + +module.exports = { + module: { + rules: [ + { + test: /\.css$/, + use: [ + 'style-loader', + { loader: 'css-loader', options: { importLoaders: 1 } }, + { loader: 'postcss-loader', options: { + ident: 'postcss', + plugins: () => [ + postcssCustomSelectors(/* pluginOptions */) + ] + } } + ] + } + ] + } +} +``` + +## Create React App + +Add [React App Rewired] and [React App Rewire PostCSS] to your project: + +```bash +npm install react-app-rewired react-app-rewire-postcss --save-dev +``` + +Use [React App Rewire PostCSS] and [PostCSS Custom Selectors] in your +`config-overrides.js` file: + +```js +const reactAppRewirePostcss = require('react-app-rewire-postcss'); +const postcssCustomSelectors = require('postcss-custom-selectors'); + +module.exports config => reactAppRewirePostcss(config, { + plugins: () => [ + postcssCustomSelectors(/* pluginOptions */) + ] +}); +``` + +## Gulp + +Add [Gulp PostCSS] to your project: + +```bash +npm install gulp-postcss --save-dev +``` + +Use [PostCSS Custom Selectors] in your Gulpfile: + +```js +const postcss = require('gulp-postcss'); +const postcssCustomSelectors = require('postcss-custom-selectors'); + +gulp.task('css', () => gulp.src('./src/*.css').pipe( + postcss([ + postcssCustomSelectors(/* pluginOptions */) + ]) +).pipe( + gulp.dest('.') +)); +``` + +## Grunt + +Add [Grunt PostCSS] to your project: + +```bash +npm install grunt-postcss --save-dev +``` + +Use [PostCSS Custom Selectors] in your Gruntfile: + +```js +const postcssCustomSelectors = require('postcss-custom-selectors'); + +grunt.loadNpmTasks('grunt-postcss'); + +grunt.initConfig({ + postcss: { + options: { + use: [ + postcssCustomSelectors(/* pluginOptions */) + ] + }, + dist: { + src: '*.css' + } + } +}); +``` + +[Gulp PostCSS]: https://github.com/postcss/gulp-postcss +[Grunt PostCSS]: https://github.com/nDmitry/grunt-postcss +[PostCSS]: https://github.com/postcss/postcss +[PostCSS CLI]: https://github.com/postcss/postcss-cli +[PostCSS Custom Selectors]: https://github.com/jonathantneal/postcss-custom-selectors +[PostCSS Loader]: https://github.com/postcss/postcss-loader +[React App Rewire PostCSS]: https://github.com/csstools/react-app-rewire-postcss +[React App Rewired]: https://github.com/timarney/react-app-rewired diff --git a/LICENSE b/LICENSE.md similarity index 61% rename from LICENSE rename to LICENSE.md index 3c9a87231c..6d70470888 100644 --- a/LICENSE +++ b/LICENSE.md @@ -1,13 +1,13 @@ -The MIT License (MIT) +# The MIT License (MIT) -Copyright (c) 2017 PostCSS +Copyright © PostCSS -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: +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. @@ -19,4 +19,3 @@ 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. - diff --git a/README.md b/README.md index 83a88b17d9..5000430621 100644 --- a/README.md +++ b/README.md @@ -1,309 +1,129 @@ -# PostCSS Custom Selectors +# PostCSS Custom Selectors [PostCSS][postcss] -[![CSS Standard Status](https://jonathantneal.github.io/css-db/badge/css-extensions-custom-selectors.svg)](https://jonathantneal.github.io/css-db/#css-extensions-custom-selectors) -[![Build Status](https://travis-ci.org/postcss/postcss-custom-selectors.svg?branch=master)](https://travis-ci.org/postcss/postcss-custom-selectors) -[![NPM Downloads](https://img.shields.io/npm/dm/postcss-custom-selectors.svg?style=flat)](https://www.npmjs.com/package/postcss-custom-selectors) -[![NPM Version](http://img.shields.io/npm/v/postcss-custom-selectors.svg?style=flat)](https://www.npmjs.com/package/postcss-custom-selectors) -[![License](https://img.shields.io/npm/l/postcss-custom-selectors.svg?style=flat)](http://opensource.org/licenses/MIT) +[![NPM Version][npm-img]][npm-url] +[![CSS Standard Status][css-img]][css-url] +[![Build Status][cli-img]][cli-url] +[![Support Chat][git-img]][git-url] -> [PostCSS](https://github.com/postcss/postcss) plugin to transform [W3C CSS Extensions(Custom Selectors)](http://dev.w3.org/csswg/css-extensions/#custom-selectors) to more compatible CSS. +[PostCSS Custom Selectors] lets you use Custom Selectors in CSS, following the +[CSS Extensions] specification. -[简体中文](README-zh.md) - -![GIF Demo](http://gtms01.alicdn.com/tps/i1/TB1ZCe3GVXXXXbzXFXXRi48IXXX-780-610.gif) - -## Installation - -```console -$ npm install postcss-custom-selectors -``` - -## Quick Start - -```js -// dependencies -var fs = require('fs') -var postcss = require('postcss') -var selector = require('postcss-custom-selectors') - -// css to be processed -var css = fs.readFileSync('input.css', 'utf8') - -// process css using postcss-custom-selectors -var output = postcss() - .use(selector()) - .process(css) - .css - -console.log('\n====>Output CSS:\n', output) -``` - -Or just: - -```js -var output = postcss(selector()) - .process(css) - .css -``` - -input: - -```css -@custom-selector :--heading h1, h2, h3, h4, h5, h6; +```pcss +@custom-selector :--heading h1, h2, h3; article :--heading + p { margin-top: 0; } -``` -You will get: +/* becomes */ -```css -article h1 + p, -article h2 + p, -article h3 + p, -article h4 + p, -article h5 + p, -article h6 + p { - margin-top: 0; -} +article h1 + p, article h2 + p, article h3 + p {} ``` -## CSS syntax - -```css -@custom-selector = @custom-selector : ; -``` - -## How to use - -The custom selector is a pseudo-class, so you must use `:--` to define it. - -For example to simulate [:any-link](http://dev.w3.org/csswg/selectors/#the-any-link-pseudo) selector: - -```css -@custom-selector :--any-link :link, :visited; - -a:--any-link { - color: blue; -} -``` +## Usage -output: +Add [PostCSS Custom Selectors] to your project: -```css -a:link, -a:visited { - color: blue; -} +```bash +npm install postcss-custom-selectors --save-dev ``` -You can even make some smart use like this: +Use [PostCSS Custom Selectors] to process your CSS: -```css -@custom-selector :--button button, .button; -@custom-selector :--enter :hover, :focus; - -:--button:--enter { +```js +const postcssCustomSelectors = require('postcss-custom-selectors'); -} +postcssCustomSelectors.process(YOUR_CSS /*, processOptions, pluginOptions */); ``` -output +Or use it as a [PostCSS] plugin: -```css -button:hover, -.button:hover, -button:focus, -.button:focus { +```js +const postcss = require('postcss'); +const postcssCustomSelectors = require('postcss-custom-selectors'); -} +postcss([ + postcssCustomSelectors(/* pluginOptions */) +]).process(YOUR_CSS /*, processOptions */); ``` -## Options - -### `lineBreak` - -_(default: `true`)_ +[PostCSS Custom Selectors] runs in all Node environments, with special instructions for: -Set whether multiple selector wrap.The default is turning on to be a newline. +| [Node](INSTALL.md#node) | [PostCSS CLI](INSTALL.md#postcss-cli) | [Webpack](INSTALL.md#webpack) | [Create React App](INSTALL.md#create-react-app) | [Gulp](INSTALL.md#gulp) | [Grunt](INSTALL.md#grunt) | +| --- | --- | --- | --- | --- | --- | -Close the line breaks. +## Options -```js -var options = { - lineBreak: false -} +### preserve -var output = postcss(selector(options)) - .process(css) - .css -``` +The `preserve` option determines whether custom selectors and rules using +custom selectors should be preserved in their original form. -With the first example, the output will be: +```pcss +@custom-selector :--heading h1, h2, h3; -```css -article h1 + p, article h2 + p, article h3 + p, article h4 + p, article h5 + p, article h6 + p { +article :--heading + p { margin-top: 0; } -``` - -### `extensions` -_(default: `{}`)_ +/* becomes */ -This option allows you to customize an object to set the `` (selector alias) and ``, these definitions will cover the same alias of `@custom-selector` in CSS. +article h1 + p, article h2 + p, article h3 + p {} -```js -var options = { - extensions: { - ':--any' : 'section, article, aside, nav' - } -} - -var output = postcss(selector(options)) - .process(css) - .css; +article :--heading + p {} ``` -input.css - -```css -@custom-selector :--any .foo, .bar; /* No effect */ -:--any h1 { - margin-top: 16px; -} -``` +### importFrom -output: +The `importFrom` option specifies sources where custom selectors can be +imported from, which might be CSS, JS, and JSON files, and directly passed +objects. -```css -/* No effect */ -section h1, -article h1, -aside h1, -nav h1 { - margin-top: 16px; -} -``` - -### `transformMatches` - -_(default: `true`)_ - -Allows you to limit transformation to `:matches()` usage -If set to false: - -input - -```css -@custom-selector :--foo .bar, .baz; -.foo:--foo { - margin-top: 16px; -} +```js +postcssCustomSelectors({ + importFrom: 'path/to/file.css' // => @custom-selector h1, h2, h3 +}); ``` -output - -```css -.foo:matches(.bar, .baz) { - margin-top: 16px; +```pcss +article :--heading + p { + margin-top: 0; } -``` - -## Usage - -### Node Watch - -Dependence [chokidar](https://github.com/paulmillr/chokidar) module. +/* becomes */ -```js -var fs = require('fs') -var chokidar = require('chokidar') -var postcss = require('postcss') -var selector = require('postcss-custom-selectors') - -var src = 'input.css' - -console.info('Watching…\nModify the input.css and save.') - -chokidar.watch(src, { - ignored: /[\/\\]\./, - persistent: true -}).on('all', - function(event, path, stats) { - var css = fs.readFileSync(src, 'utf8') - var output = postcss(selector()) - .process(css) - .css - fs.writeFileSync('output.css', output) - }) +article h1 + p, article h2 + p, article h3 + p {} ``` -### Grunt +Multiple files can be passed into this option, and they will be parsed in the +order they are received. JavaScript files, JSON files, and objects will need +to namespace custom selectors using the `customProperties` or +`custom-properties` key. ```js -module.exports = function(grunt) { - grunt.initConfig({ - pkg: grunt.file.readJSON('package.json'), - postcss: { - options: { - processors: [ - require('autoprefixer-core')({ browsers: ['> 0%'] }).postcss, //Other plugin - require('postcss-custom-selectors')(), - ] - }, - dist: { - src: ['src/*.css'], - dest: 'build/grunt.css' +postcssCustomSelectors({ + importFrom: [ + 'path/to/file.css', + 'and/then/this.js', + 'and/then/that.json', + { + customSelectors: { + ':--heading': 'h1, h2, h3' } } - }); - - grunt.loadNpmTasks('grunt-contrib-uglify'); - grunt.loadNpmTasks('grunt-postcss'); - - grunt.registerTask('default', ['postcss']); -} -``` - -### Gulp - -```js -var gulp = require('gulp'); -var rename = require('gulp-rename'); -var postcss = require('gulp-postcss'); -var selector = require('postcss-custom-selectors') -var autoprefixer = require('autoprefixer-core') - -gulp.task('default', function () { - var processors = [ - autoprefixer({ browsers: ['> 0%'] }), //Other plugin - selector() - ]; - gulp.src('src/*.css') - .pipe(postcss(processors)) - .pipe(rename('gulp.css')) - .pipe(gulp.dest('build')) + ] }); -gulp.watch('src/*.css', ['default']); -``` - -## Contributing - -* Install the relevant dependent module. -* Respect coding style(Install [EditorConfig](http://editorconfig.org/)). -* Add test cases in the [test](test) directory. -* Run test. - -```console -$ git clone https://github.com/postcss/postcss-custom-selectors.git -$ git checkout -b patch -$ npm install -$ npm test ``` -## [Changelog](CHANGELOG.md) +[cli-img]: https://img.shields.io/travis/postcss/postcss-custom-selectors.svg +[cli-url]: https://travis-ci.org/postcss/postcss-custom-selectors +[css-img]: https://cssdb.org/badge/custom-selectors.svg +[css-url]: https://cssdb.org/#custom-selectors +[git-img]: https://img.shields.io/badge/support-chat-blue.svg +[git-url]: https://gitter.im/postcss/postcss +[npm-img]: https://img.shields.io/npm/v/postcss-custom-selectors.svg +[npm-url]: https://www.npmjs.com/package/postcss-custom-selectors -## [License](LICENSE) +[CSS Extensions]: https://drafts.csswg.org/css-extensions/#custom-selectors +[PostCSS]: https://github.com/postcss/postcss +[PostCSS Custom Selectors]: https://github.com/postcss/postcss-custom-selectors diff --git a/index.js b/index.js new file mode 100644 index 0000000000..e12e5b32bc --- /dev/null +++ b/index.js @@ -0,0 +1,24 @@ +import postcss from 'postcss'; +import getCustomSelectors from './lib/custom-selectors-from-root'; +import transformRules from './lib/transform-rules'; +import importCustomSelectorsFromSources from './lib/import-from'; + +export default postcss.plugin('postcss-custom-selectors', opts => { + // whether to preserve custom selectors and rules using them + const preserve = Boolean(Object(opts).preserve); + + // sources from where to import custom selectors + const importFrom = [].concat(Object(opts).importFrom || []); + + // promise any custom selectors are imported + const customSelectorsPromise = importCustomSelectorsFromSources(importFrom); + + return async root => { + const customProperties = Object.assign( + await customSelectorsPromise, + getCustomSelectors(root, { preserve }) + ); + + transformRules(root, customProperties, { preserve }); + }; +}); diff --git a/lib/custom-selectors-from-root.js b/lib/custom-selectors-from-root.js new file mode 100644 index 0000000000..7a4bf42c7d --- /dev/null +++ b/lib/custom-selectors-from-root.js @@ -0,0 +1,34 @@ +import getASTFromSelectors from './selectors-ast-from-selectors-string'; + +// return custom selectors from the css root, conditionally removing them +export default (root, opts) => { + // initialize custom selectors + const customSelectors = {}; + + // for each custom selector atrule that is a child of the css root + root.nodes.slice().forEach(node => { + if (isCustomSelector(node)) { + // extract the name and selectors from the params of the custom selector + const [, name, selectors] = node.params.match(customSelectorParamsRegExp); + + // write the parsed selectors to the custom selector + customSelectors[name] = getASTFromSelectors(selectors); + + // conditionally remove the custom selector atrule + if (!Object(opts).preserve) { + node.remove(); + } + } + }); + + return customSelectors; +}; + +// match the custom selector name +const customSelectorNameRegExp = /^custom-selector$/i; + +// match the custom selector params +const customSelectorParamsRegExp = /^(:--[A-z][\w-]*)\s+([\W\w]+)\s*$/; + +// whether the atrule is a custom selector +const isCustomSelector = node => node.type === 'atrule' && customSelectorNameRegExp.test(node.name) && customSelectorParamsRegExp.test(node.params); diff --git a/lib/import-from.js b/lib/import-from.js new file mode 100644 index 0000000000..f89e6ddb63 --- /dev/null +++ b/lib/import-from.js @@ -0,0 +1,119 @@ +import fs from 'fs'; +import path from 'path'; +import postcss from 'postcss'; +import getSelectorsAstFromSelectorsString from './selectors-ast-from-selectors-string'; +import getCustomSelectors from './custom-selectors-from-root'; + +/* Import Custom Selectors from CSS AST +/* ========================================================================== */ + +function importCustomSelectorsFromCSSAST(root) { + return getCustomSelectors(root); +} + +/* Import Custom Selectors from CSS File +/* ========================================================================== */ + +async function importCustomSelectorsFromCSSFile(from) { + const css = await readFile(path.resolve(from)); + const root = postcss.parse(css, { from: path.resolve(from) }); + + return importCustomSelectorsFromCSSAST(root); +} + +/* Import Custom Selectors from Object +/* ========================================================================== */ + +function importCustomSelectorsFromObject(object) { + const customSelectors = Object.assign( + {}, + Object(object).customSelectors || Object(object)['custom-selectors'] + ); + + for (const key in customSelectors) { + customSelectors[key] = getSelectorsAstFromSelectorsString(customSelectors[key]); + } + + return customSelectors; +} + +/* Import Custom Selectors from JSON file +/* ========================================================================== */ + +async function importCustomSelectorsFromJSONFile(from) { + const object = await readJSON(path.resolve(from)); + + return importCustomSelectorsFromObject(object); +} + +/* Import Custom Selectors from JS file +/* ========================================================================== */ + +async function importCustomSelectorsFromJSFile(from) { + const object = await import(path.resolve(from)); + + return importCustomSelectorsFromObject(object); +} + +/* Import Custom Selectors from Sources +/* ========================================================================== */ + +export default function importCustomSelectorsFromSources(sources) { + return sources.map(source => { + if (typeof source === 'string') { + if (isCSSPath(source)) { + return [ 'css', source ] + } else if (isJSPath(source)) { + return [ 'js', source ] + } else if (isJSONPath(source)) { + return [ 'json', source ] + } + } + + return Object(source); + }).reduce(async (customSelectors, source) => { + const type = source[0]; + const from = source[1]; + + if (type === 'ast') { + return Object.assign(customSelectors, importCustomSelectorsFromCSSAST(from)); + } + + if (type === 'css') { + return Object.assign(customSelectors, await importCustomSelectorsFromCSSFile(from)); + } + + if (type === 'js') { + return Object.assign(customSelectors, await importCustomSelectorsFromJSFile(from)); + } + + if (type === 'json') { + return Object.assign(customSelectors, await importCustomSelectorsFromJSONFile(from)); + } + + return Object.assign(customSelectors, importCustomSelectorsFromObject(source)); + }, {}); +} + +/* Helper utilities +/* ========================================================================== */ + +const matchCSSPath = /\.\w*css/i; +const matchJSPath = /\.\w*js/i; +const matchJSONPath = /\.\w*json/i; + +const isCSSPath = from => matchCSSPath.test(from); +const isJSPath = from => matchJSPath.test(from); +const isJSONPath = from => matchJSONPath.test(from); + +const readFile = from => new Promise((resolve, reject) => { + fs.readFile(from, 'utf8', (error, result) => { + if (error) { + reject(error); + } else { + resolve(result); + } + }); +}); + +const readJSON = async from => JSON.parse(await readFile(from)); diff --git a/lib/selectors-ast-from-selectors-string.js b/lib/selectors-ast-from-selectors-string.js new file mode 100644 index 0000000000..e3fdfd0d94 --- /dev/null +++ b/lib/selectors-ast-from-selectors-string.js @@ -0,0 +1,14 @@ +import parser from 'postcss-selector-parser'; + +/* Return a Selectors AST from a Selectors String +/* ========================================================================== */ + +export default selectorString => { + let selectorAST; + + parser(selectors => { + selectorAST = selectors + }).processSync(selectorString); + + return selectorAST; +}; diff --git a/lib/transform-rules.js b/lib/transform-rules.js new file mode 100644 index 0000000000..a13d285ab4 --- /dev/null +++ b/lib/transform-rules.js @@ -0,0 +1,19 @@ +import parser from 'postcss-selector-parser'; +import transformSelectorsByCustomSelectors from './transform-selectors-by-custom-selectors'; + +// transform custom pseudo selectors with custom selectors +export default (root, customSelectors, opts) => { + root.walkRules(customPseudoRegExp, rule => { + const selector = parser(selectors => { + transformSelectorsByCustomSelectors(selectors, customSelectors, opts) + }).processSync(rule.selector); + + if (opts.preserve) { + rule.cloneBefore({ selector }); + } else { + rule.selector = selector; + } + }); +}; + +const customPseudoRegExp = /:--[A-z][\w-]*/; diff --git a/lib/transform-selectors-by-custom-selectors.js b/lib/transform-selectors-by-custom-selectors.js new file mode 100644 index 0000000000..8ca113804c --- /dev/null +++ b/lib/transform-selectors-by-custom-selectors.js @@ -0,0 +1,52 @@ +// return transformed selectors, replacing custom pseudo selectors with custom selectors +export default function transformSelectorList(selectorList, customSelectors) { + let index = selectorList.nodes.length - 1; + + while (index >= 0) { + const transformedSelectors = transformSelector(selectorList.nodes[index], customSelectors); + + if (transformedSelectors.length) { + selectorList.nodes.splice(index, 1, ...transformedSelectors); + } + + --index; + } + + return selectorList; +} + +// return custom pseudo selectors replaced with custom selectors +function transformSelector(selector, customSelectors) { + const transpiledSelectors = []; + + for (const index in selector.nodes) { + const { value, nodes } = selector.nodes[index]; + + if (value in customSelectors) { + for (const replacementSelector of customSelectors[value].nodes) { + const selectorClone = selector.clone(); + + selectorClone.nodes.splice(index, 1, ...replacementSelector.clone().nodes.map(node => { + // use spacing from the current usage + node.spaces = { ...selector.nodes[index].spaces }; + + return node; + })); + + const retranspiledSelectors = transformSelector(selectorClone, customSelectors); + + if (retranspiledSelectors.length) { + transpiledSelectors.push(...retranspiledSelectors); + } else { + transpiledSelectors.push(selectorClone); + } + } + + return transpiledSelectors; + } else if (nodes && nodes.length) { + transformSelectorList(selector.nodes[index], customSelectors); + } + } + + return transpiledSelectors; +} diff --git a/package-lock.json b/package-lock.json deleted file mode 100644 index b89deadf46..0000000000 --- a/package-lock.json +++ /dev/null @@ -1,4144 +0,0 @@ -{ - "name": "postcss-custom-selectors", - "version": "4.0.1", - "lockfileVersion": 1, - "requires": true, - "dependencies": { - "acorn": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-5.7.1.tgz", - "integrity": "sha512-d+nbxBUGKg7Arpsvbnlq61mc12ek3EY8EQldM3GPAhWJ1UVxC6TDGbIvUMNU6obBX3i1+ptCIzV4vq0gFPEGVQ==", - "dev": true - }, - "acorn-jsx": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-3.0.1.tgz", - "integrity": "sha1-r9+UiPsezvyDSPb7IvRk4ypYs2s=", - "dev": true, - "requires": { - "acorn": "^3.0.4" - }, - "dependencies": { - "acorn": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-3.3.0.tgz", - "integrity": "sha1-ReN/s56No/JbruP/U2niu18iAXo=", - "dev": true - } - } - }, - "ajv": { - "version": "4.11.8", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-4.11.8.tgz", - "integrity": "sha1-gv+wKynmYq5TvcIK8VlHcGc5xTY=", - "dev": true, - "requires": { - "co": "^4.6.0", - "json-stable-stringify": "^1.0.1" - } - }, - "ajv-keywords": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-1.5.1.tgz", - "integrity": "sha1-MU3QpLM2j609/NxU7eYXG4htrzw=", - "dev": true - }, - "align-text": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/align-text/-/align-text-0.1.4.tgz", - "integrity": "sha1-DNkKVhCT810KmSVsIrcGlDP60Rc=", - "dev": true, - "requires": { - "kind-of": "^3.0.2", - "longest": "^1.0.1", - "repeat-string": "^1.5.2" - } - }, - "alter": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/alter/-/alter-0.2.0.tgz", - "integrity": "sha1-x1iICGF1cgNKrmJICvJrHU0cs80=", - "dev": true, - "requires": { - "stable": "~0.1.3" - } - }, - "amdefine": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/amdefine/-/amdefine-1.0.1.tgz", - "integrity": "sha1-SlKCrBZHKek2Gbz9OtFR+BfOkfU=", - "dev": true - }, - "ansi-escapes": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-1.4.0.tgz", - "integrity": "sha1-06ioOzGapneTZisT52HHkRQiMG4=", - "dev": true - }, - "ansi-regex": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", - "dev": true - }, - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "requires": { - "color-convert": "^1.9.0" - } - }, - "anymatch": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-1.3.2.tgz", - "integrity": "sha512-0XNayC8lTHQ2OI8aljNCN3sSx6hsr/1+rlcDAotXJR7C1oZZHCNsfpbKwMjRA3Uqb5tF1Rae2oloTr4xpq+WjA==", - "dev": true, - "optional": true, - "requires": { - "micromatch": "^2.1.5", - "normalize-path": "^2.0.0" - } - }, - "argparse": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", - "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", - "dev": true, - "requires": { - "sprintf-js": "~1.0.2" - } - }, - "arr-diff": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-2.0.0.tgz", - "integrity": "sha1-jzuCf5Vai9ZpaX5KQlasPOrjVs8=", - "dev": true, - "optional": true, - "requires": { - "arr-flatten": "^1.0.1" - } - }, - "arr-flatten": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/arr-flatten/-/arr-flatten-1.1.0.tgz", - "integrity": "sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==", - "dev": true, - "optional": true - }, - "array-union": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/array-union/-/array-union-1.0.2.tgz", - "integrity": "sha1-mjRBDk9OPaI96jdb5b5w8kd47Dk=", - "dev": true, - "requires": { - "array-uniq": "^1.0.1" - } - }, - "array-uniq": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/array-uniq/-/array-uniq-1.0.3.tgz", - "integrity": "sha1-r2rId6Jcx/dOBYiUdThY39sk/bY=", - "dev": true - }, - "array-unique": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.2.1.tgz", - "integrity": "sha1-odl8yvy8JiXMcPrc6zalDFiwGlM=", - "dev": true, - "optional": true - }, - "arrify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", - "integrity": "sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=", - "dev": true - }, - "ast-traverse": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/ast-traverse/-/ast-traverse-0.1.1.tgz", - "integrity": "sha1-ac8rg4bxnc2hux4F1o/jWdiJfeY=", - "dev": true - }, - "ast-types": { - "version": "0.9.6", - "resolved": "https://registry.npmjs.org/ast-types/-/ast-types-0.9.6.tgz", - "integrity": "sha1-ECyenpAF0+fjgpvwxPok7oYu6bk=", - "dev": true - }, - "async-each": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/async-each/-/async-each-1.0.1.tgz", - "integrity": "sha1-GdOGodntxufByF04iu28xW0zYC0=", - "dev": true, - "optional": true - }, - "babel-cli": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-cli/-/babel-cli-6.26.0.tgz", - "integrity": "sha1-UCq1SHTX24itALiHoGODzgPQAvE=", - "dev": true, - "requires": { - "babel-core": "^6.26.0", - "babel-polyfill": "^6.26.0", - "babel-register": "^6.26.0", - "babel-runtime": "^6.26.0", - "chokidar": "^1.6.1", - "commander": "^2.11.0", - "convert-source-map": "^1.5.0", - "fs-readdir-recursive": "^1.0.0", - "glob": "^7.1.2", - "lodash": "^4.17.4", - "output-file-sync": "^1.1.2", - "path-is-absolute": "^1.0.1", - "slash": "^1.0.0", - "source-map": "^0.5.6", - "v8flags": "^2.1.1" - }, - "dependencies": { - "source-map": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", - "dev": true - } - } - }, - "babel-code-frame": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-code-frame/-/babel-code-frame-6.26.0.tgz", - "integrity": "sha1-Y/1D99weO7fONZR9uP42mj9Yx0s=", - "dev": true, - "requires": { - "chalk": "^1.1.3", - "esutils": "^2.0.2", - "js-tokens": "^3.0.2" - }, - "dependencies": { - "ansi-styles": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", - "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", - "dev": true - }, - "chalk": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", - "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", - "dev": true, - "requires": { - "ansi-styles": "^2.2.1", - "escape-string-regexp": "^1.0.2", - "has-ansi": "^2.0.0", - "strip-ansi": "^3.0.0", - "supports-color": "^2.0.0" - } - }, - "supports-color": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", - "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", - "dev": true - } - } - }, - "babel-core": { - "version": "6.26.3", - "resolved": "https://registry.npmjs.org/babel-core/-/babel-core-6.26.3.tgz", - "integrity": "sha512-6jyFLuDmeidKmUEb3NM+/yawG0M2bDZ9Z1qbZP59cyHLz8kYGKYwpJP0UwUKKUiTRNvxfLesJnTedqczP7cTDA==", - "dev": true, - "requires": { - "babel-code-frame": "^6.26.0", - "babel-generator": "^6.26.0", - "babel-helpers": "^6.24.1", - "babel-messages": "^6.23.0", - "babel-register": "^6.26.0", - "babel-runtime": "^6.26.0", - "babel-template": "^6.26.0", - "babel-traverse": "^6.26.0", - "babel-types": "^6.26.0", - "babylon": "^6.18.0", - "convert-source-map": "^1.5.1", - "debug": "^2.6.9", - "json5": "^0.5.1", - "lodash": "^4.17.4", - "minimatch": "^3.0.4", - "path-is-absolute": "^1.0.1", - "private": "^0.1.8", - "slash": "^1.0.0", - "source-map": "^0.5.7" - }, - "dependencies": { - "source-map": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", - "dev": true - } - } - }, - "babel-generator": { - "version": "6.26.1", - "resolved": "https://registry.npmjs.org/babel-generator/-/babel-generator-6.26.1.tgz", - "integrity": "sha512-HyfwY6ApZj7BYTcJURpM5tznulaBvyio7/0d4zFOeMPUmfxkCjHocCuoLa2SAGzBI8AREcH3eP3758F672DppA==", - "dev": true, - "requires": { - "babel-messages": "^6.23.0", - "babel-runtime": "^6.26.0", - "babel-types": "^6.26.0", - "detect-indent": "^4.0.0", - "jsesc": "^1.3.0", - "lodash": "^4.17.4", - "source-map": "^0.5.7", - "trim-right": "^1.0.1" - }, - "dependencies": { - "source-map": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", - "dev": true - } - } - }, - "babel-helper-builder-binary-assignment-operator-visitor": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-helper-builder-binary-assignment-operator-visitor/-/babel-helper-builder-binary-assignment-operator-visitor-6.24.1.tgz", - "integrity": "sha1-zORReto1b0IgvK6KAsKzRvmlZmQ=", - "dev": true, - "requires": { - "babel-helper-explode-assignable-expression": "^6.24.1", - "babel-runtime": "^6.22.0", - "babel-types": "^6.24.1" - } - }, - "babel-helper-call-delegate": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-helper-call-delegate/-/babel-helper-call-delegate-6.24.1.tgz", - "integrity": "sha1-7Oaqzdx25Bw0YfiL/Fdb0Nqi340=", - "dev": true, - "requires": { - "babel-helper-hoist-variables": "^6.24.1", - "babel-runtime": "^6.22.0", - "babel-traverse": "^6.24.1", - "babel-types": "^6.24.1" - } - }, - "babel-helper-define-map": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-helper-define-map/-/babel-helper-define-map-6.26.0.tgz", - "integrity": "sha1-pfVtq0GiX5fstJjH66ypgZ+Vvl8=", - "dev": true, - "requires": { - "babel-helper-function-name": "^6.24.1", - "babel-runtime": "^6.26.0", - "babel-types": "^6.26.0", - "lodash": "^4.17.4" - } - }, - "babel-helper-explode-assignable-expression": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-helper-explode-assignable-expression/-/babel-helper-explode-assignable-expression-6.24.1.tgz", - "integrity": "sha1-8luCz33BBDPFX3BZLVdGQArCLKo=", - "dev": true, - "requires": { - "babel-runtime": "^6.22.0", - "babel-traverse": "^6.24.1", - "babel-types": "^6.24.1" - } - }, - "babel-helper-function-name": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-helper-function-name/-/babel-helper-function-name-6.24.1.tgz", - "integrity": "sha1-00dbjAPtmCQqJbSDUasYOZ01gKk=", - "dev": true, - "requires": { - "babel-helper-get-function-arity": "^6.24.1", - "babel-runtime": "^6.22.0", - "babel-template": "^6.24.1", - "babel-traverse": "^6.24.1", - "babel-types": "^6.24.1" - } - }, - "babel-helper-get-function-arity": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-helper-get-function-arity/-/babel-helper-get-function-arity-6.24.1.tgz", - "integrity": "sha1-j3eCqpNAfEHTqlCQj4mwMbG2hT0=", - "dev": true, - "requires": { - "babel-runtime": "^6.22.0", - "babel-types": "^6.24.1" - } - }, - "babel-helper-hoist-variables": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-helper-hoist-variables/-/babel-helper-hoist-variables-6.24.1.tgz", - "integrity": "sha1-HssnaJydJVE+rbyZFKc/VAi+enY=", - "dev": true, - "requires": { - "babel-runtime": "^6.22.0", - "babel-types": "^6.24.1" - } - }, - "babel-helper-optimise-call-expression": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-helper-optimise-call-expression/-/babel-helper-optimise-call-expression-6.24.1.tgz", - "integrity": "sha1-96E0J7qfc/j0+pk8VKl4gtEkQlc=", - "dev": true, - "requires": { - "babel-runtime": "^6.22.0", - "babel-types": "^6.24.1" - } - }, - "babel-helper-regex": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-helper-regex/-/babel-helper-regex-6.26.0.tgz", - "integrity": "sha1-MlxZ+QL4LyS3T6zu0DY5VPZJXnI=", - "dev": true, - "requires": { - "babel-runtime": "^6.26.0", - "babel-types": "^6.26.0", - "lodash": "^4.17.4" - } - }, - "babel-helper-remap-async-to-generator": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-helper-remap-async-to-generator/-/babel-helper-remap-async-to-generator-6.24.1.tgz", - "integrity": "sha1-XsWBgnrXI/7N04HxySg5BnbkVRs=", - "dev": true, - "requires": { - "babel-helper-function-name": "^6.24.1", - "babel-runtime": "^6.22.0", - "babel-template": "^6.24.1", - "babel-traverse": "^6.24.1", - "babel-types": "^6.24.1" - } - }, - "babel-helper-replace-supers": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-helper-replace-supers/-/babel-helper-replace-supers-6.24.1.tgz", - "integrity": "sha1-v22/5Dk40XNpohPKiov3S2qQqxo=", - "dev": true, - "requires": { - "babel-helper-optimise-call-expression": "^6.24.1", - "babel-messages": "^6.23.0", - "babel-runtime": "^6.22.0", - "babel-template": "^6.24.1", - "babel-traverse": "^6.24.1", - "babel-types": "^6.24.1" - } - }, - "babel-helpers": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-helpers/-/babel-helpers-6.24.1.tgz", - "integrity": "sha1-NHHenK7DiOXIUOWX5Yom3fN2ArI=", - "dev": true, - "requires": { - "babel-runtime": "^6.22.0", - "babel-template": "^6.24.1" - } - }, - "babel-messages": { - "version": "6.23.0", - "resolved": "https://registry.npmjs.org/babel-messages/-/babel-messages-6.23.0.tgz", - "integrity": "sha1-8830cDhYA1sqKVHG7F7fbGLyYw4=", - "dev": true, - "requires": { - "babel-runtime": "^6.22.0" - } - }, - "babel-plugin-add-module-exports": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/babel-plugin-add-module-exports/-/babel-plugin-add-module-exports-0.2.1.tgz", - "integrity": "sha1-mumh9KjcZ/DN7E9K7aHkOl/2XiU=", - "dev": true - }, - "babel-plugin-check-es2015-constants": { - "version": "6.22.0", - "resolved": "https://registry.npmjs.org/babel-plugin-check-es2015-constants/-/babel-plugin-check-es2015-constants-6.22.0.tgz", - "integrity": "sha1-NRV7EBQm/S/9PaP3XH0ekYNbv4o=", - "dev": true, - "requires": { - "babel-runtime": "^6.22.0" - } - }, - "babel-plugin-constant-folding": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/babel-plugin-constant-folding/-/babel-plugin-constant-folding-1.0.1.tgz", - "integrity": "sha1-g2HTZMmORJw2kr26Ue/whEKQqo4=", - "dev": true - }, - "babel-plugin-dead-code-elimination": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/babel-plugin-dead-code-elimination/-/babel-plugin-dead-code-elimination-1.0.2.tgz", - "integrity": "sha1-X3xFEnTc18zNv7s+C4XdKBIfD2U=", - "dev": true - }, - "babel-plugin-eval": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/babel-plugin-eval/-/babel-plugin-eval-1.0.1.tgz", - "integrity": "sha1-ovrtJc5r5preS/7CY/cBaRlZUNo=", - "dev": true - }, - "babel-plugin-inline-environment-variables": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/babel-plugin-inline-environment-variables/-/babel-plugin-inline-environment-variables-1.0.1.tgz", - "integrity": "sha1-H1jOkSB61qgmqL9kX6/mj/X+P/4=", - "dev": true - }, - "babel-plugin-jscript": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/babel-plugin-jscript/-/babel-plugin-jscript-1.0.4.tgz", - "integrity": "sha1-jzQsOCduh6R9X6CovT1etsytj8w=", - "dev": true - }, - "babel-plugin-member-expression-literals": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/babel-plugin-member-expression-literals/-/babel-plugin-member-expression-literals-1.0.1.tgz", - "integrity": "sha1-zF7bD6qNyScXDnTW0cAkQAIWJNM=", - "dev": true - }, - "babel-plugin-property-literals": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/babel-plugin-property-literals/-/babel-plugin-property-literals-1.0.1.tgz", - "integrity": "sha1-AlIwGQAZKYCxwRjv6kjOk6q4MzY=", - "dev": true - }, - "babel-plugin-proto-to-assign": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/babel-plugin-proto-to-assign/-/babel-plugin-proto-to-assign-1.0.4.tgz", - "integrity": "sha1-xJ56/QL1d7xNoF6i3wAiUM980SM=", - "dev": true, - "requires": { - "lodash": "^3.9.3" - }, - "dependencies": { - "lodash": { - "version": "3.10.1", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-3.10.1.tgz", - "integrity": "sha1-W/Rejkm6QYnhfUgnid/RW9FAt7Y=", - "dev": true - } - } - }, - "babel-plugin-react-constant-elements": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/babel-plugin-react-constant-elements/-/babel-plugin-react-constant-elements-1.0.3.tgz", - "integrity": "sha1-lGc26DeEKcvDSdz/YvUcFDs041o=", - "dev": true - }, - "babel-plugin-react-display-name": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/babel-plugin-react-display-name/-/babel-plugin-react-display-name-1.0.3.tgz", - "integrity": "sha1-dU/jiSboQkpOexWrbqYTne4FFPw=", - "dev": true - }, - "babel-plugin-remove-console": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/babel-plugin-remove-console/-/babel-plugin-remove-console-1.0.1.tgz", - "integrity": "sha1-2PJFVsOgUAXUKqqv0neH9T/wE6c=", - "dev": true - }, - "babel-plugin-remove-debugger": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/babel-plugin-remove-debugger/-/babel-plugin-remove-debugger-1.0.1.tgz", - "integrity": "sha1-/S6jzWGkKK0fO5yJiC/0KT6MFMc=", - "dev": true - }, - "babel-plugin-runtime": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/babel-plugin-runtime/-/babel-plugin-runtime-1.0.7.tgz", - "integrity": "sha1-v3x9lm3Vbs1cF/ocslPJrLflSq8=", - "dev": true - }, - "babel-plugin-syntax-async-functions": { - "version": "6.13.0", - "resolved": "https://registry.npmjs.org/babel-plugin-syntax-async-functions/-/babel-plugin-syntax-async-functions-6.13.0.tgz", - "integrity": "sha1-ytnK0RkbWtY0vzCuCHI5HgZHvpU=", - "dev": true - }, - "babel-plugin-syntax-exponentiation-operator": { - "version": "6.13.0", - "resolved": "https://registry.npmjs.org/babel-plugin-syntax-exponentiation-operator/-/babel-plugin-syntax-exponentiation-operator-6.13.0.tgz", - "integrity": "sha1-nufoM3KQ2pUoggGmpX9BcDF4MN4=", - "dev": true - }, - "babel-plugin-syntax-object-rest-spread": { - "version": "6.13.0", - "resolved": "https://registry.npmjs.org/babel-plugin-syntax-object-rest-spread/-/babel-plugin-syntax-object-rest-spread-6.13.0.tgz", - "integrity": "sha1-/WU28rzhODb/o6VFjEkDpZe7O/U=", - "dev": true - }, - "babel-plugin-syntax-trailing-function-commas": { - "version": "6.22.0", - "resolved": "https://registry.npmjs.org/babel-plugin-syntax-trailing-function-commas/-/babel-plugin-syntax-trailing-function-commas-6.22.0.tgz", - "integrity": "sha1-ugNgk3+NBuQBgKQ/4NVhb/9TLPM=", - "dev": true - }, - "babel-plugin-transform-async-to-generator": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-async-to-generator/-/babel-plugin-transform-async-to-generator-6.24.1.tgz", - "integrity": "sha1-ZTbjeK/2yx1VF6wOQOs+n8jQh2E=", - "dev": true, - "requires": { - "babel-helper-remap-async-to-generator": "^6.24.1", - "babel-plugin-syntax-async-functions": "^6.8.0", - "babel-runtime": "^6.22.0" - } - }, - "babel-plugin-transform-es2015-arrow-functions": { - "version": "6.22.0", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-arrow-functions/-/babel-plugin-transform-es2015-arrow-functions-6.22.0.tgz", - "integrity": "sha1-RSaSy3EdX3ncf4XkQM5BufJE0iE=", - "dev": true, - "requires": { - "babel-runtime": "^6.22.0" - } - }, - "babel-plugin-transform-es2015-block-scoped-functions": { - "version": "6.22.0", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-block-scoped-functions/-/babel-plugin-transform-es2015-block-scoped-functions-6.22.0.tgz", - "integrity": "sha1-u8UbSflk1wy42OC5ToICRs46YUE=", - "dev": true, - "requires": { - "babel-runtime": "^6.22.0" - } - }, - "babel-plugin-transform-es2015-block-scoping": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-block-scoping/-/babel-plugin-transform-es2015-block-scoping-6.26.0.tgz", - "integrity": "sha1-1w9SmcEwjQXBL0Y4E7CgnnOxiV8=", - "dev": true, - "requires": { - "babel-runtime": "^6.26.0", - "babel-template": "^6.26.0", - "babel-traverse": "^6.26.0", - "babel-types": "^6.26.0", - "lodash": "^4.17.4" - } - }, - "babel-plugin-transform-es2015-classes": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-classes/-/babel-plugin-transform-es2015-classes-6.24.1.tgz", - "integrity": "sha1-WkxYpQyclGHlZLSyo7+ryXolhNs=", - "dev": true, - "requires": { - "babel-helper-define-map": "^6.24.1", - "babel-helper-function-name": "^6.24.1", - "babel-helper-optimise-call-expression": "^6.24.1", - "babel-helper-replace-supers": "^6.24.1", - "babel-messages": "^6.23.0", - "babel-runtime": "^6.22.0", - "babel-template": "^6.24.1", - "babel-traverse": "^6.24.1", - "babel-types": "^6.24.1" - } - }, - "babel-plugin-transform-es2015-computed-properties": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-computed-properties/-/babel-plugin-transform-es2015-computed-properties-6.24.1.tgz", - "integrity": "sha1-b+Ko0WiV1WNPTNmZttNICjCBWbM=", - "dev": true, - "requires": { - "babel-runtime": "^6.22.0", - "babel-template": "^6.24.1" - } - }, - "babel-plugin-transform-es2015-destructuring": { - "version": "6.23.0", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-destructuring/-/babel-plugin-transform-es2015-destructuring-6.23.0.tgz", - "integrity": "sha1-mXux8auWf2gtKwh2/jWNYOdlxW0=", - "dev": true, - "requires": { - "babel-runtime": "^6.22.0" - } - }, - "babel-plugin-transform-es2015-duplicate-keys": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-duplicate-keys/-/babel-plugin-transform-es2015-duplicate-keys-6.24.1.tgz", - "integrity": "sha1-c+s9MQypaePvnskcU3QabxV2Qj4=", - "dev": true, - "requires": { - "babel-runtime": "^6.22.0", - "babel-types": "^6.24.1" - } - }, - "babel-plugin-transform-es2015-for-of": { - "version": "6.23.0", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-for-of/-/babel-plugin-transform-es2015-for-of-6.23.0.tgz", - "integrity": "sha1-9HyVsrYT3x0+zC/bdXNiPHUkhpE=", - "dev": true, - "requires": { - "babel-runtime": "^6.22.0" - } - }, - "babel-plugin-transform-es2015-function-name": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-function-name/-/babel-plugin-transform-es2015-function-name-6.24.1.tgz", - "integrity": "sha1-g0yJhTvDaxrw86TF26qU/Y6sqos=", - "dev": true, - "requires": { - "babel-helper-function-name": "^6.24.1", - "babel-runtime": "^6.22.0", - "babel-types": "^6.24.1" - } - }, - "babel-plugin-transform-es2015-literals": { - "version": "6.22.0", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-literals/-/babel-plugin-transform-es2015-literals-6.22.0.tgz", - "integrity": "sha1-T1SgLWzWbPkVKAAZox0xklN3yi4=", - "dev": true, - "requires": { - "babel-runtime": "^6.22.0" - } - }, - "babel-plugin-transform-es2015-modules-amd": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-modules-amd/-/babel-plugin-transform-es2015-modules-amd-6.24.1.tgz", - "integrity": "sha1-Oz5UAXI5hC1tGcMBHEvS8AoA0VQ=", - "dev": true, - "requires": { - "babel-plugin-transform-es2015-modules-commonjs": "^6.24.1", - "babel-runtime": "^6.22.0", - "babel-template": "^6.24.1" - } - }, - "babel-plugin-transform-es2015-modules-commonjs": { - "version": "6.26.2", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-modules-commonjs/-/babel-plugin-transform-es2015-modules-commonjs-6.26.2.tgz", - "integrity": "sha512-CV9ROOHEdrjcwhIaJNBGMBCodN+1cfkwtM1SbUHmvyy35KGT7fohbpOxkE2uLz1o6odKK2Ck/tz47z+VqQfi9Q==", - "dev": true, - "requires": { - "babel-plugin-transform-strict-mode": "^6.24.1", - "babel-runtime": "^6.26.0", - "babel-template": "^6.26.0", - "babel-types": "^6.26.0" - } - }, - "babel-plugin-transform-es2015-modules-systemjs": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-modules-systemjs/-/babel-plugin-transform-es2015-modules-systemjs-6.24.1.tgz", - "integrity": "sha1-/4mhQrkRmpBhlfXxBuzzBdlAfSM=", - "dev": true, - "requires": { - "babel-helper-hoist-variables": "^6.24.1", - "babel-runtime": "^6.22.0", - "babel-template": "^6.24.1" - } - }, - "babel-plugin-transform-es2015-modules-umd": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-modules-umd/-/babel-plugin-transform-es2015-modules-umd-6.24.1.tgz", - "integrity": "sha1-rJl+YoXNGO1hdq22B9YCNErThGg=", - "dev": true, - "requires": { - "babel-plugin-transform-es2015-modules-amd": "^6.24.1", - "babel-runtime": "^6.22.0", - "babel-template": "^6.24.1" - } - }, - "babel-plugin-transform-es2015-object-super": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-object-super/-/babel-plugin-transform-es2015-object-super-6.24.1.tgz", - "integrity": "sha1-JM72muIcuDp/hgPa0CH1cusnj40=", - "dev": true, - "requires": { - "babel-helper-replace-supers": "^6.24.1", - "babel-runtime": "^6.22.0" - } - }, - "babel-plugin-transform-es2015-parameters": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-parameters/-/babel-plugin-transform-es2015-parameters-6.24.1.tgz", - "integrity": "sha1-V6w1GrScrxSpfNE7CfZv3wpiXys=", - "dev": true, - "requires": { - "babel-helper-call-delegate": "^6.24.1", - "babel-helper-get-function-arity": "^6.24.1", - "babel-runtime": "^6.22.0", - "babel-template": "^6.24.1", - "babel-traverse": "^6.24.1", - "babel-types": "^6.24.1" - } - }, - "babel-plugin-transform-es2015-shorthand-properties": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-shorthand-properties/-/babel-plugin-transform-es2015-shorthand-properties-6.24.1.tgz", - "integrity": "sha1-JPh11nIch2YbvZmkYi5R8U3jiqA=", - "dev": true, - "requires": { - "babel-runtime": "^6.22.0", - "babel-types": "^6.24.1" - } - }, - "babel-plugin-transform-es2015-spread": { - "version": "6.22.0", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-spread/-/babel-plugin-transform-es2015-spread-6.22.0.tgz", - "integrity": "sha1-1taKmfia7cRTbIGlQujdnxdG+NE=", - "dev": true, - "requires": { - "babel-runtime": "^6.22.0" - } - }, - "babel-plugin-transform-es2015-sticky-regex": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-sticky-regex/-/babel-plugin-transform-es2015-sticky-regex-6.24.1.tgz", - "integrity": "sha1-AMHNsaynERLN8M9hJsLta0V8zbw=", - "dev": true, - "requires": { - "babel-helper-regex": "^6.24.1", - "babel-runtime": "^6.22.0", - "babel-types": "^6.24.1" - } - }, - "babel-plugin-transform-es2015-template-literals": { - "version": "6.22.0", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-template-literals/-/babel-plugin-transform-es2015-template-literals-6.22.0.tgz", - "integrity": "sha1-qEs0UPfp+PH2g51taH2oS7EjbY0=", - "dev": true, - "requires": { - "babel-runtime": "^6.22.0" - } - }, - "babel-plugin-transform-es2015-typeof-symbol": { - "version": "6.23.0", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-typeof-symbol/-/babel-plugin-transform-es2015-typeof-symbol-6.23.0.tgz", - "integrity": "sha1-3sCfHN3/lLUqxz1QXITfWdzOs3I=", - "dev": true, - "requires": { - "babel-runtime": "^6.22.0" - } - }, - "babel-plugin-transform-es2015-unicode-regex": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-unicode-regex/-/babel-plugin-transform-es2015-unicode-regex-6.24.1.tgz", - "integrity": "sha1-04sS9C6nMj9yk4fxinxa4frrNek=", - "dev": true, - "requires": { - "babel-helper-regex": "^6.24.1", - "babel-runtime": "^6.22.0", - "regexpu-core": "^2.0.0" - } - }, - "babel-plugin-transform-exponentiation-operator": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-exponentiation-operator/-/babel-plugin-transform-exponentiation-operator-6.24.1.tgz", - "integrity": "sha1-KrDJx/MJj6SJB3cruBP+QejeOg4=", - "dev": true, - "requires": { - "babel-helper-builder-binary-assignment-operator-visitor": "^6.24.1", - "babel-plugin-syntax-exponentiation-operator": "^6.8.0", - "babel-runtime": "^6.22.0" - } - }, - "babel-plugin-transform-object-rest-spread": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-object-rest-spread/-/babel-plugin-transform-object-rest-spread-6.26.0.tgz", - "integrity": "sha1-DzZpLVD+9rfi1LOsFHgTepY7ewY=", - "dev": true, - "requires": { - "babel-plugin-syntax-object-rest-spread": "^6.8.0", - "babel-runtime": "^6.26.0" - } - }, - "babel-plugin-transform-regenerator": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-regenerator/-/babel-plugin-transform-regenerator-6.26.0.tgz", - "integrity": "sha1-4HA2lvveJ/Cj78rPi03KL3s6jy8=", - "dev": true, - "requires": { - "regenerator-transform": "^0.10.0" - } - }, - "babel-plugin-transform-strict-mode": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-strict-mode/-/babel-plugin-transform-strict-mode-6.24.1.tgz", - "integrity": "sha1-1fr3qleKZbvlkc9e2uBKDGcCB1g=", - "dev": true, - "requires": { - "babel-runtime": "^6.22.0", - "babel-types": "^6.24.1" - } - }, - "babel-plugin-undeclared-variables-check": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/babel-plugin-undeclared-variables-check/-/babel-plugin-undeclared-variables-check-1.0.2.tgz", - "integrity": "sha1-XPGqU52BP/ZOmWQSkK9iCWX2Xe4=", - "dev": true, - "requires": { - "leven": "^1.0.2" - } - }, - "babel-plugin-undefined-to-void": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/babel-plugin-undefined-to-void/-/babel-plugin-undefined-to-void-1.1.6.tgz", - "integrity": "sha1-f1eO+LeN+uYAM4XYQXph7aBuL4E=", - "dev": true - }, - "babel-polyfill": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-polyfill/-/babel-polyfill-6.26.0.tgz", - "integrity": "sha1-N5k3q8Z9eJWXCtxiHyhM2WbPIVM=", - "dev": true, - "requires": { - "babel-runtime": "^6.26.0", - "core-js": "^2.5.0", - "regenerator-runtime": "^0.10.5" - }, - "dependencies": { - "regenerator-runtime": { - "version": "0.10.5", - "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.10.5.tgz", - "integrity": "sha1-M2w+/BIgrc7dosn6tntaeVWjNlg=", - "dev": true - } - } - }, - "babel-preset-env": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/babel-preset-env/-/babel-preset-env-1.7.0.tgz", - "integrity": "sha512-9OR2afuKDneX2/q2EurSftUYM0xGu4O2D9adAhVfADDhrYDaxXV0rBbevVYoY9n6nyX1PmQW/0jtpJvUNr9CHg==", - "dev": true, - "requires": { - "babel-plugin-check-es2015-constants": "^6.22.0", - "babel-plugin-syntax-trailing-function-commas": "^6.22.0", - "babel-plugin-transform-async-to-generator": "^6.22.0", - "babel-plugin-transform-es2015-arrow-functions": "^6.22.0", - "babel-plugin-transform-es2015-block-scoped-functions": "^6.22.0", - "babel-plugin-transform-es2015-block-scoping": "^6.23.0", - "babel-plugin-transform-es2015-classes": "^6.23.0", - "babel-plugin-transform-es2015-computed-properties": "^6.22.0", - "babel-plugin-transform-es2015-destructuring": "^6.23.0", - "babel-plugin-transform-es2015-duplicate-keys": "^6.22.0", - "babel-plugin-transform-es2015-for-of": "^6.23.0", - "babel-plugin-transform-es2015-function-name": "^6.22.0", - "babel-plugin-transform-es2015-literals": "^6.22.0", - "babel-plugin-transform-es2015-modules-amd": "^6.22.0", - "babel-plugin-transform-es2015-modules-commonjs": "^6.23.0", - "babel-plugin-transform-es2015-modules-systemjs": "^6.23.0", - "babel-plugin-transform-es2015-modules-umd": "^6.23.0", - "babel-plugin-transform-es2015-object-super": "^6.22.0", - "babel-plugin-transform-es2015-parameters": "^6.23.0", - "babel-plugin-transform-es2015-shorthand-properties": "^6.22.0", - "babel-plugin-transform-es2015-spread": "^6.22.0", - "babel-plugin-transform-es2015-sticky-regex": "^6.22.0", - "babel-plugin-transform-es2015-template-literals": "^6.22.0", - "babel-plugin-transform-es2015-typeof-symbol": "^6.23.0", - "babel-plugin-transform-es2015-unicode-regex": "^6.22.0", - "babel-plugin-transform-exponentiation-operator": "^6.22.0", - "babel-plugin-transform-regenerator": "^6.22.0", - "browserslist": "^3.2.6", - "invariant": "^2.2.2", - "semver": "^5.3.0" - } - }, - "babel-register": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-register/-/babel-register-6.26.0.tgz", - "integrity": "sha1-btAhFz4vy0htestFxgCahW9kcHE=", - "dev": true, - "requires": { - "babel-core": "^6.26.0", - "babel-runtime": "^6.26.0", - "core-js": "^2.5.0", - "home-or-tmp": "^2.0.0", - "lodash": "^4.17.4", - "mkdirp": "^0.5.1", - "source-map-support": "^0.4.15" - } - }, - "babel-runtime": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-runtime/-/babel-runtime-6.26.0.tgz", - "integrity": "sha1-llxwWGaOgrVde/4E/yM3vItWR/4=", - "dev": true, - "requires": { - "core-js": "^2.4.0", - "regenerator-runtime": "^0.11.0" - } - }, - "babel-tape-runner": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/babel-tape-runner/-/babel-tape-runner-1.3.1.tgz", - "integrity": "sha1-aabKl/TxHOSGFSuijtIl4TM1yfg=", - "dev": true, - "requires": { - "babel-core": "^5.8.20", - "glob": "^5.0.14" - }, - "dependencies": { - "ansi-styles": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", - "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", - "dev": true - }, - "babel-core": { - "version": "5.8.38", - "resolved": "https://registry.npmjs.org/babel-core/-/babel-core-5.8.38.tgz", - "integrity": "sha1-H8ruedfmG3ULALjlT238nQr4ZVg=", - "dev": true, - "requires": { - "babel-plugin-constant-folding": "^1.0.1", - "babel-plugin-dead-code-elimination": "^1.0.2", - "babel-plugin-eval": "^1.0.1", - "babel-plugin-inline-environment-variables": "^1.0.1", - "babel-plugin-jscript": "^1.0.4", - "babel-plugin-member-expression-literals": "^1.0.1", - "babel-plugin-property-literals": "^1.0.1", - "babel-plugin-proto-to-assign": "^1.0.3", - "babel-plugin-react-constant-elements": "^1.0.3", - "babel-plugin-react-display-name": "^1.0.3", - "babel-plugin-remove-console": "^1.0.1", - "babel-plugin-remove-debugger": "^1.0.1", - "babel-plugin-runtime": "^1.0.7", - "babel-plugin-undeclared-variables-check": "^1.0.2", - "babel-plugin-undefined-to-void": "^1.1.6", - "babylon": "^5.8.38", - "bluebird": "^2.9.33", - "chalk": "^1.0.0", - "convert-source-map": "^1.1.0", - "core-js": "^1.0.0", - "debug": "^2.1.1", - "detect-indent": "^3.0.0", - "esutils": "^2.0.0", - "fs-readdir-recursive": "^0.1.0", - "globals": "^6.4.0", - "home-or-tmp": "^1.0.0", - "is-integer": "^1.0.4", - "js-tokens": "1.0.1", - "json5": "^0.4.0", - "lodash": "^3.10.0", - "minimatch": "^2.0.3", - "output-file-sync": "^1.1.0", - "path-exists": "^1.0.0", - "path-is-absolute": "^1.0.0", - "private": "^0.1.6", - "regenerator": "0.8.40", - "regexpu": "^1.3.0", - "repeating": "^1.1.2", - "resolve": "^1.1.6", - "shebang-regex": "^1.0.0", - "slash": "^1.0.0", - "source-map": "^0.5.0", - "source-map-support": "^0.2.10", - "to-fast-properties": "^1.0.0", - "trim-right": "^1.0.0", - "try-resolve": "^1.0.0" - } - }, - "babylon": { - "version": "5.8.38", - "resolved": "https://registry.npmjs.org/babylon/-/babylon-5.8.38.tgz", - "integrity": "sha1-7JsSCxG/bM1Bc6GL8hfmC3mFn/0=", - "dev": true - }, - "chalk": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", - "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", - "dev": true, - "requires": { - "ansi-styles": "^2.2.1", - "escape-string-regexp": "^1.0.2", - "has-ansi": "^2.0.0", - "strip-ansi": "^3.0.0", - "supports-color": "^2.0.0" - } - }, - "core-js": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/core-js/-/core-js-1.2.7.tgz", - "integrity": "sha1-ZSKUwUZR2yj6k70tX/KYOk8IxjY=", - "dev": true - }, - "detect-indent": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/detect-indent/-/detect-indent-3.0.1.tgz", - "integrity": "sha1-ncXl3bzu+DJXZLlFGwK8bVQIT3U=", - "dev": true, - "requires": { - "get-stdin": "^4.0.1", - "minimist": "^1.1.0", - "repeating": "^1.1.0" - } - }, - "fs-readdir-recursive": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/fs-readdir-recursive/-/fs-readdir-recursive-0.1.2.tgz", - "integrity": "sha1-MVtPuMHKW4xH3v7zGdBz2tNWgFk=", - "dev": true - }, - "glob": { - "version": "5.0.15", - "resolved": "https://registry.npmjs.org/glob/-/glob-5.0.15.tgz", - "integrity": "sha1-G8k2ueAvSmA/zCIuz3Yz0wuLk7E=", - "dev": true, - "requires": { - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "2 || 3", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "globals": { - "version": "6.4.1", - "resolved": "https://registry.npmjs.org/globals/-/globals-6.4.1.tgz", - "integrity": "sha1-hJgDKzttHMge68X3lpDY/in6v08=", - "dev": true - }, - "home-or-tmp": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/home-or-tmp/-/home-or-tmp-1.0.0.tgz", - "integrity": "sha1-S58eQIAMPlDGwn94FnavzOcfOYU=", - "dev": true, - "requires": { - "os-tmpdir": "^1.0.1", - "user-home": "^1.1.1" - } - }, - "js-tokens": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-1.0.1.tgz", - "integrity": "sha1-zENaXIuUrRWst5gxQPyAGCyJrq4=", - "dev": true - }, - "json5": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/json5/-/json5-0.4.0.tgz", - "integrity": "sha1-BUNS5MTIDIbAkjh31EneF2pzLI0=", - "dev": true - }, - "lodash": { - "version": "3.10.1", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-3.10.1.tgz", - "integrity": "sha1-W/Rejkm6QYnhfUgnid/RW9FAt7Y=", - "dev": true - }, - "minimatch": { - "version": "2.0.10", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-2.0.10.tgz", - "integrity": "sha1-jQh8OcazjAAbl/ynzm0OHoCvusc=", - "dev": true, - "requires": { - "brace-expansion": "^1.0.0" - } - }, - "minimist": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", - "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", - "dev": true - }, - "repeating": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/repeating/-/repeating-1.1.3.tgz", - "integrity": "sha1-PUEUIYh3U3SU+X93+Xhfq4EPpKw=", - "dev": true, - "requires": { - "is-finite": "^1.0.0" - } - }, - "source-map": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", - "dev": true - }, - "source-map-support": { - "version": "0.2.10", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.2.10.tgz", - "integrity": "sha1-6lo5AKHByyUJagrozFwrSxDe09w=", - "dev": true, - "requires": { - "source-map": "0.1.32" - }, - "dependencies": { - "source-map": { - "version": "0.1.32", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.1.32.tgz", - "integrity": "sha1-yLbBZ3l7pHQKjqMyUhYv8IWRsmY=", - "dev": true, - "requires": { - "amdefine": ">=0.0.4" - } - } - } - }, - "supports-color": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", - "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", - "dev": true - } - } - }, - "babel-template": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-template/-/babel-template-6.26.0.tgz", - "integrity": "sha1-3gPi0WOWsGn0bdn/+FIfsaDjXgI=", - "dev": true, - "requires": { - "babel-runtime": "^6.26.0", - "babel-traverse": "^6.26.0", - "babel-types": "^6.26.0", - "babylon": "^6.18.0", - "lodash": "^4.17.4" - } - }, - "babel-traverse": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-traverse/-/babel-traverse-6.26.0.tgz", - "integrity": "sha1-RqnL1+3MYsjlwGTi0tjQ9ANXZu4=", - "dev": true, - "requires": { - "babel-code-frame": "^6.26.0", - "babel-messages": "^6.23.0", - "babel-runtime": "^6.26.0", - "babel-types": "^6.26.0", - "babylon": "^6.18.0", - "debug": "^2.6.8", - "globals": "^9.18.0", - "invariant": "^2.2.2", - "lodash": "^4.17.4" - } - }, - "babel-types": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-types/-/babel-types-6.26.0.tgz", - "integrity": "sha1-o7Bz+Uq0nrb6Vc1lInozQ4BjJJc=", - "dev": true, - "requires": { - "babel-runtime": "^6.26.0", - "esutils": "^2.0.2", - "lodash": "^4.17.4", - "to-fast-properties": "^1.0.3" - } - }, - "babylon": { - "version": "6.18.0", - "resolved": "https://registry.npmjs.org/babylon/-/babylon-6.18.0.tgz", - "integrity": "sha512-q/UEjfGJ2Cm3oKV71DJz9d25TPnq5rhBVL2Q4fA5wcC3jcrdn7+SssEybFIxwAvvP+YCsCYNKughoF33GxgycQ==", - "dev": true - }, - "balanced-match": { - "version": "0.4.2", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-0.4.2.tgz", - "integrity": "sha1-yz8+PHMtwPAe5wtAPzAuYddwmDg=" - }, - "binary-extensions": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.11.0.tgz", - "integrity": "sha1-RqoXUftqL5PuXmibsQh9SxTGwgU=", - "dev": true, - "optional": true - }, - "bluebird": { - "version": "2.11.0", - "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-2.11.0.tgz", - "integrity": "sha1-U0uQM8AiyVecVro7Plpcqvu2UOE=", - "dev": true - }, - "brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, - "requires": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - }, - "dependencies": { - "balanced-match": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", - "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", - "dev": true - } - } - }, - "braces": { - "version": "1.8.5", - "resolved": "https://registry.npmjs.org/braces/-/braces-1.8.5.tgz", - "integrity": "sha1-uneWLhLf+WnWt2cR6RS3N4V79qc=", - "dev": true, - "optional": true, - "requires": { - "expand-range": "^1.8.1", - "preserve": "^0.2.0", - "repeat-element": "^1.1.2" - } - }, - "breakable": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/breakable/-/breakable-1.0.0.tgz", - "integrity": "sha1-eEp5eRWjjq0nutRWtVcstLuqeME=", - "dev": true - }, - "browserslist": { - "version": "3.2.8", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-3.2.8.tgz", - "integrity": "sha512-WHVocJYavUwVgVViC0ORikPHQquXwVh939TaelZ4WDqpWgTX/FsGhl/+P4qBUAGcRvtOgDgC+xftNWWp2RUTAQ==", - "dev": true, - "requires": { - "caniuse-lite": "^1.0.30000844", - "electron-to-chromium": "^1.3.47" - } - }, - "buffer-from": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", - "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==", - "dev": true - }, - "caller-path": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/caller-path/-/caller-path-0.1.0.tgz", - "integrity": "sha1-lAhe9jWB7NPaqSREqP6U6CV3dR8=", - "dev": true, - "requires": { - "callsites": "^0.2.0" - } - }, - "callsites": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/callsites/-/callsites-0.2.0.tgz", - "integrity": "sha1-r6uWJikQp/M8GaV3WCXGnzTjUMo=", - "dev": true - }, - "camelcase": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-1.2.1.tgz", - "integrity": "sha1-m7UwTS4LVmmLLHWLCKPqqdqlijk=", - "dev": true - }, - "caniuse-lite": { - "version": "1.0.30000874", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30000874.tgz", - "integrity": "sha512-29nr1EPiHwrJTAHHsEmTt2h+55L8j2GNFdAcYPlRy2NX6iFz7ZZiepVI7kP/QqlnHLq3KvfWpbmGa0d063U09w==", - "dev": true - }, - "center-align": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/center-align/-/center-align-0.1.3.tgz", - "integrity": "sha1-qg0yYptu6XIgBBHL1EYckHvCt60=", - "dev": true, - "requires": { - "align-text": "^0.1.3", - "lazy-cache": "^1.0.3" - } - }, - "chalk": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.1.tgz", - "integrity": "sha512-ObN6h1v2fTJSmUXoS3nMQ92LbDK9be4TV+6G+omQlGJFdcUX5heKi1LZ1YnRMIgwTLEj3E24bT6tYni50rlCfQ==", - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - } - }, - "chokidar": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-1.7.0.tgz", - "integrity": "sha1-eY5ol3gVHIB2tLNg5e3SjNortGg=", - "dev": true, - "optional": true, - "requires": { - "anymatch": "^1.3.0", - "async-each": "^1.0.0", - "fsevents": "^1.0.0", - "glob-parent": "^2.0.0", - "inherits": "^2.0.1", - "is-binary-path": "^1.0.0", - "is-glob": "^2.0.0", - "path-is-absolute": "^1.0.0", - "readdirp": "^2.0.0" - } - }, - "circular-json": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/circular-json/-/circular-json-0.3.3.tgz", - "integrity": "sha512-UZK3NBx2Mca+b5LsG7bY183pHWt5Y1xts4P3Pz7ENTwGVnJOUWbRb3ocjvX7hx9tq/yTAdclXm9sZ38gNuem4A==", - "dev": true - }, - "cli-cursor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-1.0.2.tgz", - "integrity": "sha1-ZNo/fValRBLll5S9Ytw1KV6PKYc=", - "dev": true, - "requires": { - "restore-cursor": "^1.0.1" - } - }, - "cli-width": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-2.2.0.tgz", - "integrity": "sha1-/xnt6Kml5XkyQUewwR8PvLq+1jk=", - "dev": true - }, - "cliui": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-2.1.0.tgz", - "integrity": "sha1-S0dXYP+AJkx2LDoXGQMukcf+oNE=", - "dev": true, - "requires": { - "center-align": "^0.1.1", - "right-align": "^0.1.1", - "wordwrap": "0.0.2" - } - }, - "co": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", - "integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ=", - "dev": true - }, - "code-point-at": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", - "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=", - "dev": true - }, - "color-convert": { - "version": "1.9.2", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.2.tgz", - "integrity": "sha512-3NUJZdhMhcdPn8vJ9v2UQJoH0qqoGUkYTgFEPZaPjEtwmmKUfNV46zZmgB2M5M4DCEQHMaCfWHCxiBflLm04Tg==", - "requires": { - "color-name": "1.1.1" - } - }, - "color-name": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.1.tgz", - "integrity": "sha1-SxQVMEz1ACjqgWQ2Q72C6gWANok=" - }, - "commander": { - "version": "2.17.1", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.17.1.tgz", - "integrity": "sha512-wPMUt6FnH2yzG95SA6mzjQOEKUU3aLaDEmzs1ti+1E9h+CsrZghRlqEM/EJ4KscsQVG8uNN4uVreUeT8+drlgg==", - "dev": true - }, - "commoner": { - "version": "0.10.8", - "resolved": "https://registry.npmjs.org/commoner/-/commoner-0.10.8.tgz", - "integrity": "sha1-NPw2cs0kOT6LtH5wyqApOBH08sU=", - "dev": true, - "requires": { - "commander": "^2.5.0", - "detective": "^4.3.1", - "glob": "^5.0.15", - "graceful-fs": "^4.1.2", - "iconv-lite": "^0.4.5", - "mkdirp": "^0.5.0", - "private": "^0.1.6", - "q": "^1.1.2", - "recast": "^0.11.17" - }, - "dependencies": { - "esprima": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-3.1.3.tgz", - "integrity": "sha1-/cpRzuYTOJXjyI1TXOSdv/YqRjM=", - "dev": true - }, - "glob": { - "version": "5.0.15", - "resolved": "https://registry.npmjs.org/glob/-/glob-5.0.15.tgz", - "integrity": "sha1-G8k2ueAvSmA/zCIuz3Yz0wuLk7E=", - "dev": true, - "requires": { - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "2 || 3", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "recast": { - "version": "0.11.23", - "resolved": "https://registry.npmjs.org/recast/-/recast-0.11.23.tgz", - "integrity": "sha1-RR/TAEqx5N+bTktmN2sqIZEkYtM=", - "dev": true, - "requires": { - "ast-types": "0.9.6", - "esprima": "~3.1.0", - "private": "~0.1.5", - "source-map": "~0.5.0" - } - }, - "source-map": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", - "dev": true - } - } - }, - "concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", - "dev": true - }, - "concat-stream": { - "version": "1.6.2", - "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz", - "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==", - "dev": true, - "requires": { - "buffer-from": "^1.0.0", - "inherits": "^2.0.3", - "readable-stream": "^2.2.2", - "typedarray": "^0.0.6" - } - }, - "convert-source-map": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.5.1.tgz", - "integrity": "sha1-uCeAl7m8IpNl3lxiz1/K7YtVmeU=", - "dev": true - }, - "core-js": { - "version": "2.5.7", - "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.5.7.tgz", - "integrity": "sha512-RszJCAxg/PP6uzXVXL6BsxSXx/B05oJAQ2vkJRjyjrEcNVycaqOmNb5OTxZPE3xa5gwZduqza6L9JOCenh/Ecw==", - "dev": true - }, - "core-util-is": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", - "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=", - "dev": true - }, - "d": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/d/-/d-1.0.0.tgz", - "integrity": "sha1-dUu1v+VUUdpppYuU1F9MWwRi1Y8=", - "dev": true, - "requires": { - "es5-ext": "^0.10.9" - } - }, - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "decamelize": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", - "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=", - "dev": true - }, - "deep-equal": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/deep-equal/-/deep-equal-1.0.1.tgz", - "integrity": "sha1-9dJgKStmDghO/0zbyfCK0yR0SLU=", - "dev": true - }, - "deep-is": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz", - "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=", - "dev": true - }, - "define-properties": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.2.tgz", - "integrity": "sha1-g6c/L+pWmJj7c3GTyPhzyvbUXJQ=", - "dev": true, - "requires": { - "foreach": "^2.0.5", - "object-keys": "^1.0.8" - } - }, - "defined": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/defined/-/defined-1.0.0.tgz", - "integrity": "sha1-yY2bzvdWdBiOEQlpFRGZ45sfppM=", - "dev": true - }, - "defs": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/defs/-/defs-1.1.1.tgz", - "integrity": "sha1-siYJ8sehG6ej2xFoBcE5scr/qdI=", - "dev": true, - "requires": { - "alter": "~0.2.0", - "ast-traverse": "~0.1.1", - "breakable": "~1.0.0", - "esprima-fb": "~15001.1001.0-dev-harmony-fb", - "simple-fmt": "~0.1.0", - "simple-is": "~0.2.0", - "stringmap": "~0.2.2", - "stringset": "~0.2.1", - "tryor": "~0.1.2", - "yargs": "~3.27.0" - } - }, - "del": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/del/-/del-2.2.2.tgz", - "integrity": "sha1-wSyYHQZ4RshLyvhiz/kw2Qf/0ag=", - "dev": true, - "requires": { - "globby": "^5.0.0", - "is-path-cwd": "^1.0.0", - "is-path-in-cwd": "^1.0.0", - "object-assign": "^4.0.1", - "pify": "^2.0.0", - "pinkie-promise": "^2.0.0", - "rimraf": "^2.2.8" - } - }, - "detect-indent": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/detect-indent/-/detect-indent-4.0.0.tgz", - "integrity": "sha1-920GQ1LN9Docts5hnE7jqUdd4gg=", - "dev": true, - "requires": { - "repeating": "^2.0.0" - } - }, - "detective": { - "version": "4.7.1", - "resolved": "https://registry.npmjs.org/detective/-/detective-4.7.1.tgz", - "integrity": "sha512-H6PmeeUcZloWtdt4DAkFyzFL94arpHr3NOwwmVILFiy+9Qd4JTxxXrzfyGk/lmct2qVGBwTSwSXagqu2BxmWig==", - "dev": true, - "requires": { - "acorn": "^5.2.1", - "defined": "^1.0.0" - } - }, - "doctrine": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", - "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", - "dev": true, - "requires": { - "esutils": "^2.0.2" - } - }, - "electron-to-chromium": { - "version": "1.3.57", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.57.tgz", - "integrity": "sha512-YYpZlr6mzR8cK5VRmTZydEt5Mp+WMg1/syrO40PoQzl76vJ+oQchL2d3FmEcWzw3FYqJVYJP/kYYSzTa7FLXwg==", - "dev": true - }, - "es-abstract": { - "version": "1.12.0", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.12.0.tgz", - "integrity": "sha512-C8Fx/0jFmV5IPoMOFPA9P9G5NtqW+4cOPit3MIuvR2t7Ag2K15EJTpxnHAYTzL+aYQJIESYeXZmDBfOBE1HcpA==", - "dev": true, - "requires": { - "es-to-primitive": "^1.1.1", - "function-bind": "^1.1.1", - "has": "^1.0.1", - "is-callable": "^1.1.3", - "is-regex": "^1.0.4" - } - }, - "es-to-primitive": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.1.1.tgz", - "integrity": "sha1-RTVSSKiJeQNLZ5Lhm7gfK3l13Q0=", - "dev": true, - "requires": { - "is-callable": "^1.1.1", - "is-date-object": "^1.0.1", - "is-symbol": "^1.0.1" - } - }, - "es5-ext": { - "version": "0.10.45", - "resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.45.tgz", - "integrity": "sha512-FkfM6Vxxfmztilbxxz5UKSD4ICMf5tSpRFtDNtkAhOxZ0EKtX6qwmXNyH/sFyIbX2P/nU5AMiA9jilWsUGJzCQ==", - "dev": true, - "requires": { - "es6-iterator": "~2.0.3", - "es6-symbol": "~3.1.1", - "next-tick": "1" - } - }, - "es6-iterator": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/es6-iterator/-/es6-iterator-2.0.3.tgz", - "integrity": "sha1-p96IkUGgWpSwhUQDstCg+/qY87c=", - "dev": true, - "requires": { - "d": "1", - "es5-ext": "^0.10.35", - "es6-symbol": "^3.1.1" - } - }, - "es6-map": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/es6-map/-/es6-map-0.1.5.tgz", - "integrity": "sha1-kTbgUD3MBqMBaQ8LsU/042TpSfA=", - "dev": true, - "requires": { - "d": "1", - "es5-ext": "~0.10.14", - "es6-iterator": "~2.0.1", - "es6-set": "~0.1.5", - "es6-symbol": "~3.1.1", - "event-emitter": "~0.3.5" - } - }, - "es6-set": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/es6-set/-/es6-set-0.1.5.tgz", - "integrity": "sha1-0rPsXU2ADO2BjbU40ol02wpzzLE=", - "dev": true, - "requires": { - "d": "1", - "es5-ext": "~0.10.14", - "es6-iterator": "~2.0.1", - "es6-symbol": "3.1.1", - "event-emitter": "~0.3.5" - } - }, - "es6-symbol": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/es6-symbol/-/es6-symbol-3.1.1.tgz", - "integrity": "sha1-vwDvT9q2uhtG7Le2KbTH7VcVzHc=", - "dev": true, - "requires": { - "d": "1", - "es5-ext": "~0.10.14" - } - }, - "es6-weak-map": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/es6-weak-map/-/es6-weak-map-2.0.2.tgz", - "integrity": "sha1-XjqzIlH/0VOKH45f+hNXdy+S2W8=", - "dev": true, - "requires": { - "d": "1", - "es5-ext": "^0.10.14", - "es6-iterator": "^2.0.1", - "es6-symbol": "^3.1.1" - } - }, - "escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=" - }, - "escope": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/escope/-/escope-3.6.0.tgz", - "integrity": "sha1-4Bl16BJ4GhY6ba392AOY3GTIicM=", - "dev": true, - "requires": { - "es6-map": "^0.1.3", - "es6-weak-map": "^2.0.1", - "esrecurse": "^4.1.0", - "estraverse": "^4.1.1" - } - }, - "eslint": { - "version": "3.19.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-3.19.0.tgz", - "integrity": "sha1-yPxiAcf0DdCJQbh8CFdnOGpnmsw=", - "dev": true, - "requires": { - "babel-code-frame": "^6.16.0", - "chalk": "^1.1.3", - "concat-stream": "^1.5.2", - "debug": "^2.1.1", - "doctrine": "^2.0.0", - "escope": "^3.6.0", - "espree": "^3.4.0", - "esquery": "^1.0.0", - "estraverse": "^4.2.0", - "esutils": "^2.0.2", - "file-entry-cache": "^2.0.0", - "glob": "^7.0.3", - "globals": "^9.14.0", - "ignore": "^3.2.0", - "imurmurhash": "^0.1.4", - "inquirer": "^0.12.0", - "is-my-json-valid": "^2.10.0", - "is-resolvable": "^1.0.0", - "js-yaml": "^3.5.1", - "json-stable-stringify": "^1.0.0", - "levn": "^0.3.0", - "lodash": "^4.0.0", - "mkdirp": "^0.5.0", - "natural-compare": "^1.4.0", - "optionator": "^0.8.2", - "path-is-inside": "^1.0.1", - "pluralize": "^1.2.1", - "progress": "^1.1.8", - "require-uncached": "^1.0.2", - "shelljs": "^0.7.5", - "strip-bom": "^3.0.0", - "strip-json-comments": "~2.0.1", - "table": "^3.7.8", - "text-table": "~0.2.0", - "user-home": "^2.0.0" - }, - "dependencies": { - "ansi-styles": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", - "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", - "dev": true - }, - "chalk": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", - "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", - "dev": true, - "requires": { - "ansi-styles": "^2.2.1", - "escape-string-regexp": "^1.0.2", - "has-ansi": "^2.0.0", - "strip-ansi": "^3.0.0", - "supports-color": "^2.0.0" - } - }, - "supports-color": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", - "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", - "dev": true - }, - "user-home": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/user-home/-/user-home-2.0.0.tgz", - "integrity": "sha1-nHC/2Babwdy/SGBODwS4tJzenp8=", - "dev": true, - "requires": { - "os-homedir": "^1.0.0" - } - } - } - }, - "espree": { - "version": "3.5.4", - "resolved": "https://registry.npmjs.org/espree/-/espree-3.5.4.tgz", - "integrity": "sha512-yAcIQxtmMiB/jL32dzEp2enBeidsB7xWPLNiw3IIkpVds1P+h7qF9YwJq1yUNzp2OKXgAprs4F61ih66UsoD1A==", - "dev": true, - "requires": { - "acorn": "^5.5.0", - "acorn-jsx": "^3.0.0" - } - }, - "esprima-fb": { - "version": "15001.1001.0-dev-harmony-fb", - "resolved": "https://registry.npmjs.org/esprima-fb/-/esprima-fb-15001.1001.0-dev-harmony-fb.tgz", - "integrity": "sha1-Q761fsJujPI3092LM+QlM1d/Jlk=", - "dev": true - }, - "esquery": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.0.1.tgz", - "integrity": "sha512-SmiyZ5zIWH9VM+SRUReLS5Q8a7GxtRdxEBVZpm98rJM7Sb+A9DVCndXfkeFUd3byderg+EbDkfnevfCwynWaNA==", - "dev": true, - "requires": { - "estraverse": "^4.0.0" - } - }, - "esrecurse": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.2.1.tgz", - "integrity": "sha512-64RBB++fIOAXPw3P9cy89qfMlvZEXZkqqJkjqqXIvzP5ezRZjW+lPWjw35UX/3EhUPFYbg5ER4JYgDw4007/DQ==", - "dev": true, - "requires": { - "estraverse": "^4.1.0" - } - }, - "estraverse": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.2.0.tgz", - "integrity": "sha1-De4/7TH81GlhjOc0IJn8GvoL2xM=", - "dev": true - }, - "esutils": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.2.tgz", - "integrity": "sha1-Cr9PHKpbyx96nYrMbepPqqBLrJs=", - "dev": true - }, - "event-emitter": { - "version": "0.3.5", - "resolved": "https://registry.npmjs.org/event-emitter/-/event-emitter-0.3.5.tgz", - "integrity": "sha1-34xp7vFkeSPHFXuc6DhAYQsCzDk=", - "dev": true, - "requires": { - "d": "1", - "es5-ext": "~0.10.14" - } - }, - "exit-hook": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/exit-hook/-/exit-hook-1.1.1.tgz", - "integrity": "sha1-8FyiM7SMBdVP/wd2XfhQfpXAL/g=", - "dev": true - }, - "expand-brackets": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-0.1.5.tgz", - "integrity": "sha1-3wcoTjQqgHzXM6xa9yQR5YHRF3s=", - "dev": true, - "optional": true, - "requires": { - "is-posix-bracket": "^0.1.0" - } - }, - "expand-range": { - "version": "1.8.2", - "resolved": "https://registry.npmjs.org/expand-range/-/expand-range-1.8.2.tgz", - "integrity": "sha1-opnv/TNf4nIeuujiV+x5ZE/IUzc=", - "dev": true, - "optional": true, - "requires": { - "fill-range": "^2.1.0" - } - }, - "extglob": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/extglob/-/extglob-0.3.2.tgz", - "integrity": "sha1-Lhj/PS9JqydlzskCPwEdqo2DSaE=", - "dev": true, - "optional": true, - "requires": { - "is-extglob": "^1.0.0" - } - }, - "fast-levenshtein": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", - "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", - "dev": true - }, - "figures": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/figures/-/figures-1.7.0.tgz", - "integrity": "sha1-y+Hjr/zxzUS4DK3+0o3Hk6lwHS4=", - "dev": true, - "requires": { - "escape-string-regexp": "^1.0.5", - "object-assign": "^4.1.0" - } - }, - "file-entry-cache": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-2.0.0.tgz", - "integrity": "sha1-w5KZDD5oR4PYOLjISkXYoEhFg2E=", - "dev": true, - "requires": { - "flat-cache": "^1.2.1", - "object-assign": "^4.0.1" - } - }, - "filename-regex": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/filename-regex/-/filename-regex-2.0.1.tgz", - "integrity": "sha1-wcS5vuPglyXdsQa3XB4wH+LxiyY=", - "dev": true, - "optional": true - }, - "fill-range": { - "version": "2.2.4", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-2.2.4.tgz", - "integrity": "sha512-cnrcCbj01+j2gTG921VZPnHbjmdAf8oQV/iGeV2kZxGSyfYjjTyY79ErsK1WJWMpw6DaApEX72binqJE+/d+5Q==", - "dev": true, - "optional": true, - "requires": { - "is-number": "^2.1.0", - "isobject": "^2.0.0", - "randomatic": "^3.0.0", - "repeat-element": "^1.1.2", - "repeat-string": "^1.5.2" - } - }, - "flat-cache": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-1.3.0.tgz", - "integrity": "sha1-0wMLMrOBVPTjt+nHCfSQ9++XxIE=", - "dev": true, - "requires": { - "circular-json": "^0.3.1", - "del": "^2.0.2", - "graceful-fs": "^4.1.2", - "write": "^0.2.1" - } - }, - "for-each": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz", - "integrity": "sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==", - "dev": true, - "requires": { - "is-callable": "^1.1.3" - } - }, - "for-in": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz", - "integrity": "sha1-gQaNKVqBQuwKxybG4iAMMPttXoA=", - "dev": true, - "optional": true - }, - "for-own": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/for-own/-/for-own-0.1.5.tgz", - "integrity": "sha1-UmXGgaTylNq78XyVCbZ2OqhFEM4=", - "dev": true, - "optional": true, - "requires": { - "for-in": "^1.0.1" - } - }, - "foreach": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/foreach/-/foreach-2.0.5.tgz", - "integrity": "sha1-C+4AUBiusmDQo6865ljdATbsG5k=", - "dev": true - }, - "fs-readdir-recursive": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/fs-readdir-recursive/-/fs-readdir-recursive-1.1.0.tgz", - "integrity": "sha512-GNanXlVr2pf02+sPN40XN8HG+ePaNcvM0q5mZBd668Obwb0yD5GiUbZOFgwn8kGMY6I3mdyDJzieUy3PTYyTRA==", - "dev": true - }, - "fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", - "dev": true - }, - "fsevents": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.4.tgz", - "integrity": "sha512-z8H8/diyk76B7q5wg+Ud0+CqzcAF3mBBI/bA5ne5zrRUUIvNkJY//D3BqyH571KuAC4Nr7Rw7CjWX4r0y9DvNg==", - "dev": true, - "optional": true, - "requires": { - "nan": "^2.9.2", - "node-pre-gyp": "^0.10.0" - }, - "dependencies": { - "abbrev": { - "version": "1.1.1", - "bundled": true, - "dev": true, - "optional": true - }, - "ansi-regex": { - "version": "2.1.1", - "bundled": true, - "dev": true - }, - "aproba": { - "version": "1.2.0", - "bundled": true, - "dev": true, - "optional": true - }, - "are-we-there-yet": { - "version": "1.1.4", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "delegates": "^1.0.0", - "readable-stream": "^2.0.6" - } - }, - "balanced-match": { - "version": "1.0.0", - "bundled": true, - "dev": true - }, - "brace-expansion": { - "version": "1.1.11", - "bundled": true, - "dev": true, - "requires": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "chownr": { - "version": "1.0.1", - "bundled": true, - "dev": true, - "optional": true - }, - "code-point-at": { - "version": "1.1.0", - "bundled": true, - "dev": true - }, - "concat-map": { - "version": "0.0.1", - "bundled": true, - "dev": true - }, - "console-control-strings": { - "version": "1.1.0", - "bundled": true, - "dev": true - }, - "core-util-is": { - "version": "1.0.2", - "bundled": true, - "dev": true, - "optional": true - }, - "debug": { - "version": "2.6.9", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "ms": "2.0.0" - } - }, - "deep-extend": { - "version": "0.5.1", - "bundled": true, - "dev": true, - "optional": true - }, - "delegates": { - "version": "1.0.0", - "bundled": true, - "dev": true, - "optional": true - }, - "detect-libc": { - "version": "1.0.3", - "bundled": true, - "dev": true, - "optional": true - }, - "fs-minipass": { - "version": "1.2.5", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "minipass": "^2.2.1" - } - }, - "fs.realpath": { - "version": "1.0.0", - "bundled": true, - "dev": true, - "optional": true - }, - "gauge": { - "version": "2.7.4", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "aproba": "^1.0.3", - "console-control-strings": "^1.0.0", - "has-unicode": "^2.0.0", - "object-assign": "^4.1.0", - "signal-exit": "^3.0.0", - "string-width": "^1.0.1", - "strip-ansi": "^3.0.1", - "wide-align": "^1.1.0" - } - }, - "glob": { - "version": "7.1.2", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "has-unicode": { - "version": "2.0.1", - "bundled": true, - "dev": true, - "optional": true - }, - "iconv-lite": { - "version": "0.4.21", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "safer-buffer": "^2.1.0" - } - }, - "ignore-walk": { - "version": "3.0.1", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "minimatch": "^3.0.4" - } - }, - "inflight": { - "version": "1.0.6", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "inherits": { - "version": "2.0.3", - "bundled": true, - "dev": true - }, - "ini": { - "version": "1.3.5", - "bundled": true, - "dev": true, - "optional": true - }, - "is-fullwidth-code-point": { - "version": "1.0.0", - "bundled": true, - "dev": true, - "requires": { - "number-is-nan": "^1.0.0" - } - }, - "isarray": { - "version": "1.0.0", - "bundled": true, - "dev": true, - "optional": true - }, - "minimatch": { - "version": "3.0.4", - "bundled": true, - "dev": true, - "requires": { - "brace-expansion": "^1.1.7" - } - }, - "minimist": { - "version": "0.0.8", - "bundled": true, - "dev": true - }, - "minipass": { - "version": "2.2.4", - "bundled": true, - "dev": true, - "requires": { - "safe-buffer": "^5.1.1", - "yallist": "^3.0.0" - } - }, - "minizlib": { - "version": "1.1.0", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "minipass": "^2.2.1" - } - }, - "mkdirp": { - "version": "0.5.1", - "bundled": true, - "dev": true, - "requires": { - "minimist": "0.0.8" - } - }, - "ms": { - "version": "2.0.0", - "bundled": true, - "dev": true, - "optional": true - }, - "needle": { - "version": "2.2.0", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "debug": "^2.1.2", - "iconv-lite": "^0.4.4", - "sax": "^1.2.4" - } - }, - "node-pre-gyp": { - "version": "0.10.0", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "detect-libc": "^1.0.2", - "mkdirp": "^0.5.1", - "needle": "^2.2.0", - "nopt": "^4.0.1", - "npm-packlist": "^1.1.6", - "npmlog": "^4.0.2", - "rc": "^1.1.7", - "rimraf": "^2.6.1", - "semver": "^5.3.0", - "tar": "^4" - } - }, - "nopt": { - "version": "4.0.1", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "abbrev": "1", - "osenv": "^0.1.4" - } - }, - "npm-bundled": { - "version": "1.0.3", - "bundled": true, - "dev": true, - "optional": true - }, - "npm-packlist": { - "version": "1.1.10", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "ignore-walk": "^3.0.1", - "npm-bundled": "^1.0.1" - } - }, - "npmlog": { - "version": "4.1.2", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "are-we-there-yet": "~1.1.2", - "console-control-strings": "~1.1.0", - "gauge": "~2.7.3", - "set-blocking": "~2.0.0" - } - }, - "number-is-nan": { - "version": "1.0.1", - "bundled": true, - "dev": true - }, - "object-assign": { - "version": "4.1.1", - "bundled": true, - "dev": true, - "optional": true - }, - "once": { - "version": "1.4.0", - "bundled": true, - "dev": true, - "requires": { - "wrappy": "1" - } - }, - "os-homedir": { - "version": "1.0.2", - "bundled": true, - "dev": true, - "optional": true - }, - "os-tmpdir": { - "version": "1.0.2", - "bundled": true, - "dev": true, - "optional": true - }, - "osenv": { - "version": "0.1.5", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "os-homedir": "^1.0.0", - "os-tmpdir": "^1.0.0" - } - }, - "path-is-absolute": { - "version": "1.0.1", - "bundled": true, - "dev": true, - "optional": true - }, - "process-nextick-args": { - "version": "2.0.0", - "bundled": true, - "dev": true, - "optional": true - }, - "rc": { - "version": "1.2.7", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "deep-extend": "^0.5.1", - "ini": "~1.3.0", - "minimist": "^1.2.0", - "strip-json-comments": "~2.0.1" - }, - "dependencies": { - "minimist": { - "version": "1.2.0", - "bundled": true, - "dev": true, - "optional": true - } - } - }, - "readable-stream": { - "version": "2.3.6", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "rimraf": { - "version": "2.6.2", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "glob": "^7.0.5" - } - }, - "safe-buffer": { - "version": "5.1.1", - "bundled": true, - "dev": true - }, - "safer-buffer": { - "version": "2.1.2", - "bundled": true, - "dev": true, - "optional": true - }, - "sax": { - "version": "1.2.4", - "bundled": true, - "dev": true, - "optional": true - }, - "semver": { - "version": "5.5.0", - "bundled": true, - "dev": true, - "optional": true - }, - "set-blocking": { - "version": "2.0.0", - "bundled": true, - "dev": true, - "optional": true - }, - "signal-exit": { - "version": "3.0.2", - "bundled": true, - "dev": true, - "optional": true - }, - "string-width": { - "version": "1.0.2", - "bundled": true, - "dev": true, - "requires": { - "code-point-at": "^1.0.0", - "is-fullwidth-code-point": "^1.0.0", - "strip-ansi": "^3.0.0" - } - }, - "string_decoder": { - "version": "1.1.1", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "safe-buffer": "~5.1.0" - } - }, - "strip-ansi": { - "version": "3.0.1", - "bundled": true, - "dev": true, - "requires": { - "ansi-regex": "^2.0.0" - } - }, - "strip-json-comments": { - "version": "2.0.1", - "bundled": true, - "dev": true, - "optional": true - }, - "tar": { - "version": "4.4.1", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "chownr": "^1.0.1", - "fs-minipass": "^1.2.5", - "minipass": "^2.2.4", - "minizlib": "^1.1.0", - "mkdirp": "^0.5.0", - "safe-buffer": "^5.1.1", - "yallist": "^3.0.2" - } - }, - "util-deprecate": { - "version": "1.0.2", - "bundled": true, - "dev": true, - "optional": true - }, - "wide-align": { - "version": "1.1.2", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "string-width": "^1.0.2" - } - }, - "wrappy": { - "version": "1.0.2", - "bundled": true, - "dev": true - }, - "yallist": { - "version": "3.0.2", - "bundled": true, - "dev": true - } - } - }, - "function-bind": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", - "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", - "dev": true - }, - "generate-function": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/generate-function/-/generate-function-2.0.0.tgz", - "integrity": "sha1-aFj+fAlpt9TpCTM3ZHrHn2DfvnQ=", - "dev": true - }, - "generate-object-property": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/generate-object-property/-/generate-object-property-1.2.0.tgz", - "integrity": "sha1-nA4cQDCM6AT0eDYYuTf6iPmdUNA=", - "dev": true, - "requires": { - "is-property": "^1.0.0" - } - }, - "get-stdin": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-4.0.1.tgz", - "integrity": "sha1-uWjGsKBDhDJJAui/Gl3zJXmkUP4=", - "dev": true - }, - "glob": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz", - "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "glob-base": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/glob-base/-/glob-base-0.3.0.tgz", - "integrity": "sha1-27Fk9iIbHAscz4Kuoyi0l98Oo8Q=", - "dev": true, - "optional": true, - "requires": { - "glob-parent": "^2.0.0", - "is-glob": "^2.0.0" - } - }, - "glob-parent": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-2.0.0.tgz", - "integrity": "sha1-gTg9ctsFT8zPUzbaqQLxgvbtuyg=", - "dev": true, - "requires": { - "is-glob": "^2.0.0" - } - }, - "globals": { - "version": "9.18.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-9.18.0.tgz", - "integrity": "sha512-S0nG3CLEQiY/ILxqtztTWH/3iRRdyBLw6KMDxnKMchrtbj2OFmehVh0WUCfW3DUrIgx/qFrJPICrq4Z4sTR9UQ==", - "dev": true - }, - "globby": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/globby/-/globby-5.0.0.tgz", - "integrity": "sha1-69hGZ8oNuzMLmbz8aOrCvFQ3Dg0=", - "dev": true, - "requires": { - "array-union": "^1.0.1", - "arrify": "^1.0.0", - "glob": "^7.0.3", - "object-assign": "^4.0.1", - "pify": "^2.0.0", - "pinkie-promise": "^2.0.0" - } - }, - "graceful-fs": { - "version": "4.1.11", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.11.tgz", - "integrity": "sha1-Dovf5NHduIVNZOBOp8AOKgJuVlg=", - "dev": true - }, - "has": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", - "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", - "dev": true, - "requires": { - "function-bind": "^1.1.1" - } - }, - "has-ansi": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", - "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=", - "dev": true, - "requires": { - "ansi-regex": "^2.0.0" - } - }, - "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=" - }, - "home-or-tmp": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/home-or-tmp/-/home-or-tmp-2.0.0.tgz", - "integrity": "sha1-42w/LSyufXRqhX440Y1fMqeILbg=", - "dev": true, - "requires": { - "os-homedir": "^1.0.0", - "os-tmpdir": "^1.0.1" - } - }, - "iconv-lite": { - "version": "0.4.23", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.23.tgz", - "integrity": "sha512-neyTUVFtahjf0mB3dZT77u+8O0QB89jFdnBkd5P1JgYPbPaia3gXXOVL2fq8VyU2gMMD7SaN7QukTB/pmXYvDA==", - "dev": true, - "requires": { - "safer-buffer": ">= 2.1.2 < 3" - } - }, - "ignore": { - "version": "3.3.10", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-3.3.10.tgz", - "integrity": "sha512-Pgs951kaMm5GXP7MOvxERINe3gsaVjUWFm+UZPSq9xYriQAksyhg0csnS0KXSNRD5NmNdapXEpjxG49+AKh/ug==", - "dev": true - }, - "imurmurhash": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", - "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", - "dev": true - }, - "inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", - "dev": true, - "requires": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "inherits": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", - "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", - "dev": true - }, - "inquirer": { - "version": "0.12.0", - "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-0.12.0.tgz", - "integrity": "sha1-HvK/1jUE3wvHV4X/+MLEHfEvB34=", - "dev": true, - "requires": { - "ansi-escapes": "^1.1.0", - "ansi-regex": "^2.0.0", - "chalk": "^1.0.0", - "cli-cursor": "^1.0.1", - "cli-width": "^2.0.0", - "figures": "^1.3.5", - "lodash": "^4.3.0", - "readline2": "^1.0.1", - "run-async": "^0.1.0", - "rx-lite": "^3.1.2", - "string-width": "^1.0.1", - "strip-ansi": "^3.0.0", - "through": "^2.3.6" - }, - "dependencies": { - "ansi-styles": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", - "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", - "dev": true - }, - "chalk": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", - "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", - "dev": true, - "requires": { - "ansi-styles": "^2.2.1", - "escape-string-regexp": "^1.0.2", - "has-ansi": "^2.0.0", - "strip-ansi": "^3.0.0", - "supports-color": "^2.0.0" - } - }, - "supports-color": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", - "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", - "dev": true - } - } - }, - "interpret": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.1.0.tgz", - "integrity": "sha1-ftGxQQxqDg94z5XTuEQMY/eLhhQ=", - "dev": true - }, - "invariant": { - "version": "2.2.4", - "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz", - "integrity": "sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==", - "dev": true, - "requires": { - "loose-envify": "^1.0.0" - } - }, - "invert-kv": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/invert-kv/-/invert-kv-1.0.0.tgz", - "integrity": "sha1-EEqOSqym09jNFXqO+L+rLXo//bY=", - "dev": true - }, - "is-binary-path": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-1.0.1.tgz", - "integrity": "sha1-dfFmQrSA8YenEcgUFh/TpKdlWJg=", - "dev": true, - "optional": true, - "requires": { - "binary-extensions": "^1.0.0" - } - }, - "is-buffer": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", - "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==", - "dev": true - }, - "is-callable": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.1.4.tgz", - "integrity": "sha512-r5p9sxJjYnArLjObpjA4xu5EKI3CuKHkJXMhT7kwbpUyIFD1n5PMAsoPvWnvtZiNz7LjkYDRZhd7FlI0eMijEA==", - "dev": true - }, - "is-date-object": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.1.tgz", - "integrity": "sha1-mqIOtq7rv/d/vTPnTKAbM1gdOhY=", - "dev": true - }, - "is-dotfile": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/is-dotfile/-/is-dotfile-1.0.3.tgz", - "integrity": "sha1-pqLzL/0t+wT1yiXs0Pa4PPeYoeE=", - "dev": true, - "optional": true - }, - "is-equal-shallow": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/is-equal-shallow/-/is-equal-shallow-0.1.3.tgz", - "integrity": "sha1-IjgJj8Ih3gvPpdnqxMRdY4qhxTQ=", - "dev": true, - "optional": true, - "requires": { - "is-primitive": "^2.0.0" - } - }, - "is-extendable": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", - "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=", - "dev": true, - "optional": true - }, - "is-extglob": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-1.0.0.tgz", - "integrity": "sha1-rEaBd8SUNAWgkvyPKXYMb/xiBsA=", - "dev": true - }, - "is-finite": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-finite/-/is-finite-1.0.2.tgz", - "integrity": "sha1-zGZ3aVYCvlUO8R6LSqYwU0K20Ko=", - "dev": true, - "requires": { - "number-is-nan": "^1.0.0" - } - }, - "is-fullwidth-code-point": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", - "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", - "dev": true, - "requires": { - "number-is-nan": "^1.0.0" - } - }, - "is-glob": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-2.0.1.tgz", - "integrity": "sha1-0Jb5JqPe1WAPP9/ZEZjLCIjC2GM=", - "dev": true, - "requires": { - "is-extglob": "^1.0.0" - } - }, - "is-integer": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/is-integer/-/is-integer-1.0.7.tgz", - "integrity": "sha1-a96Bqs3feLZZtmKdYpytxRqIbVw=", - "dev": true, - "requires": { - "is-finite": "^1.0.0" - } - }, - "is-my-ip-valid": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-my-ip-valid/-/is-my-ip-valid-1.0.0.tgz", - "integrity": "sha512-gmh/eWXROncUzRnIa1Ubrt5b8ep/MGSnfAUI3aRp+sqTCs1tv1Isl8d8F6JmkN3dXKc3ehZMrtiPN9eL03NuaQ==", - "dev": true - }, - "is-my-json-valid": { - "version": "2.18.0", - "resolved": "https://registry.npmjs.org/is-my-json-valid/-/is-my-json-valid-2.18.0.tgz", - "integrity": "sha512-DWT87JHCSdCPCxbqBpS6Z2ajAt+MvrJq8I4xrpQljCvzODO5/fiquBp20a3sN6yCJvFbCRyYvJOHjpzkPTKJyA==", - "dev": true, - "requires": { - "generate-function": "^2.0.0", - "generate-object-property": "^1.1.0", - "is-my-ip-valid": "^1.0.0", - "jsonpointer": "^4.0.0", - "xtend": "^4.0.0" - } - }, - "is-number": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-2.1.0.tgz", - "integrity": "sha1-Afy7s5NGOlSPL0ZszhbezknbkI8=", - "dev": true, - "optional": true, - "requires": { - "kind-of": "^3.0.2" - } - }, - "is-path-cwd": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-path-cwd/-/is-path-cwd-1.0.0.tgz", - "integrity": "sha1-0iXsIxMuie3Tj9p2dHLmLmXxEG0=", - "dev": true - }, - "is-path-in-cwd": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-path-in-cwd/-/is-path-in-cwd-1.0.1.tgz", - "integrity": "sha512-FjV1RTW48E7CWM7eE/J2NJvAEEVektecDBVBE5Hh3nM1Jd0kvhHtX68Pr3xsDf857xt3Y4AkwVULK1Vku62aaQ==", - "dev": true, - "requires": { - "is-path-inside": "^1.0.0" - } - }, - "is-path-inside": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-1.0.1.tgz", - "integrity": "sha1-jvW33lBDej/cprToZe96pVy0gDY=", - "dev": true, - "requires": { - "path-is-inside": "^1.0.1" - } - }, - "is-posix-bracket": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/is-posix-bracket/-/is-posix-bracket-0.1.1.tgz", - "integrity": "sha1-MzTceXdDaOkvAW5vvAqI9c1ua8Q=", - "dev": true, - "optional": true - }, - "is-primitive": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-primitive/-/is-primitive-2.0.0.tgz", - "integrity": "sha1-IHurkWOEmcB7Kt8kCkGochADRXU=", - "dev": true, - "optional": true - }, - "is-property": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-property/-/is-property-1.0.2.tgz", - "integrity": "sha1-V/4cTkhHTt1lsJkR8msc1Ald2oQ=", - "dev": true - }, - "is-regex": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.0.4.tgz", - "integrity": "sha1-VRdIm1RwkbCTDglWVM7SXul+lJE=", - "dev": true, - "requires": { - "has": "^1.0.1" - } - }, - "is-resolvable": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-resolvable/-/is-resolvable-1.1.0.tgz", - "integrity": "sha512-qgDYXFSR5WvEfuS5dMj6oTMEbrrSaM0CrFk2Yiq/gXnBvD9pMa2jGXxyhGLfvhZpuMZe18CJpFxAt3CRs42NMg==", - "dev": true - }, - "is-symbol": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.1.tgz", - "integrity": "sha1-PMWfAAJRlLarLjjbrmaJJWtmBXI=", - "dev": true - }, - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", - "dev": true - }, - "isobject": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", - "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=", - "dev": true, - "optional": true, - "requires": { - "isarray": "1.0.0" - } - }, - "js-tokens": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-3.0.2.tgz", - "integrity": "sha1-mGbfOVECEw449/mWvOtlRDIJwls=", - "dev": true - }, - "js-yaml": { - "version": "3.12.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.12.0.tgz", - "integrity": "sha512-PIt2cnwmPfL4hKNwqeiuz4bKfnzHTBv6HyVgjahA6mPLwPDzjDWrplJBMjHUFxku/N3FlmrbyPclad+I+4mJ3A==", - "dev": true, - "requires": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" - }, - "dependencies": { - "esprima": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", - "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", - "dev": true - } - } - }, - "jsesc": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-1.3.0.tgz", - "integrity": "sha1-RsP+yMGJKxKwgz25vHYiF226s0s=", - "dev": true - }, - "json-stable-stringify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json-stable-stringify/-/json-stable-stringify-1.0.1.tgz", - "integrity": "sha1-mnWdOcXy/1A/1TAGRu1EX4jE+a8=", - "dev": true, - "requires": { - "jsonify": "~0.0.0" - } - }, - "json5": { - "version": "0.5.1", - "resolved": "https://registry.npmjs.org/json5/-/json5-0.5.1.tgz", - "integrity": "sha1-Hq3nrMASA0rYTiOWdn6tn6VJWCE=", - "dev": true - }, - "jsonify": { - "version": "0.0.0", - "resolved": "https://registry.npmjs.org/jsonify/-/jsonify-0.0.0.tgz", - "integrity": "sha1-LHS27kHZPKUbe1qu6PUDYx0lKnM=", - "dev": true - }, - "jsonpointer": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/jsonpointer/-/jsonpointer-4.0.1.tgz", - "integrity": "sha1-T9kss04OnbPInIYi7PUfm5eMbLk=", - "dev": true - }, - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - }, - "lazy-cache": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/lazy-cache/-/lazy-cache-1.0.4.tgz", - "integrity": "sha1-odePw6UEdMuAhF07O24dpJpEbo4=", - "dev": true - }, - "lcid": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/lcid/-/lcid-1.0.0.tgz", - "integrity": "sha1-MIrMr6C8SDo4Z7S28rlQYlHRuDU=", - "dev": true, - "requires": { - "invert-kv": "^1.0.0" - } - }, - "leven": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/leven/-/leven-1.0.2.tgz", - "integrity": "sha1-kUS27ryl8dBoAWnxpncNzqYLdcM=", - "dev": true - }, - "levn": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", - "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=", - "dev": true, - "requires": { - "prelude-ls": "~1.1.2", - "type-check": "~0.3.2" - } - }, - "lodash": { - "version": "4.17.10", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.10.tgz", - "integrity": "sha512-UejweD1pDoXu+AD825lWwp4ZGtSwgnpZxb3JDViD7StjQz+Nb/6l093lx4OQ0foGWNRoc19mWy7BzL+UAK2iVg==", - "dev": true - }, - "longest": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/longest/-/longest-1.0.1.tgz", - "integrity": "sha1-MKCy2jj3N3DoKUoNIuZiXtd9AJc=", - "dev": true - }, - "loose-envify": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", - "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", - "dev": true, - "requires": { - "js-tokens": "^3.0.0 || ^4.0.0" - } - }, - "math-random": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/math-random/-/math-random-1.0.1.tgz", - "integrity": "sha1-izqsWIuKZuSXXjzepn97sylgH6w=", - "dev": true, - "optional": true - }, - "micromatch": { - "version": "2.3.11", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-2.3.11.tgz", - "integrity": "sha1-hmd8l9FyCzY0MdBNDRUpO9OMFWU=", - "dev": true, - "optional": true, - "requires": { - "arr-diff": "^2.0.0", - "array-unique": "^0.2.1", - "braces": "^1.8.2", - "expand-brackets": "^0.1.4", - "extglob": "^0.3.1", - "filename-regex": "^2.0.0", - "is-extglob": "^1.0.0", - "is-glob": "^2.0.1", - "kind-of": "^3.0.2", - "normalize-path": "^2.0.1", - "object.omit": "^2.0.0", - "parse-glob": "^3.0.4", - "regex-cache": "^0.4.2" - } - }, - "minimatch": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", - "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", - "dev": true, - "requires": { - "brace-expansion": "^1.1.7" - } - }, - "minimist": { - "version": "0.0.8", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", - "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=", - "dev": true - }, - "mkdirp": { - "version": "0.5.1", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", - "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", - "dev": true, - "requires": { - "minimist": "0.0.8" - } - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", - "dev": true - }, - "mute-stream": { - "version": "0.0.5", - "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.5.tgz", - "integrity": "sha1-j7+rsKmKJT0xhDMfno3rc3L6xsA=", - "dev": true - }, - "nan": { - "version": "2.10.0", - "resolved": "https://registry.npmjs.org/nan/-/nan-2.10.0.tgz", - "integrity": "sha512-bAdJv7fBLhWC+/Bls0Oza+mvTaNQtP+1RyhhhvD95pgUJz6XM5IzgmxOkItJ9tkoCiplvAnXI1tNmmUD/eScyA==", - "dev": true, - "optional": true - }, - "natural-compare": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", - "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=", - "dev": true - }, - "next-tick": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/next-tick/-/next-tick-1.0.0.tgz", - "integrity": "sha1-yobR/ogoFpsBICCOPchCS524NCw=", - "dev": true - }, - "normalize-path": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", - "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", - "dev": true, - "requires": { - "remove-trailing-separator": "^1.0.1" - } - }, - "number-is-nan": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", - "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=", - "dev": true - }, - "object-assign": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", - "dev": true - }, - "object-inspect": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.6.0.tgz", - "integrity": "sha512-GJzfBZ6DgDAmnuaM3104jR4s1Myxr3Y3zfIyN4z3UdqN69oSRacNK8UhnobDdC+7J2AHCjGwxQubNJfE70SXXQ==", - "dev": true - }, - "object-keys": { - "version": "1.0.12", - "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.0.12.tgz", - "integrity": "sha512-FTMyFUm2wBcGHnH2eXmz7tC6IwlqQZ6mVZ+6dm6vZ4IQIHjs6FdNsQBuKGPuUUUY6NfJw2PshC08Tn6LzLDOag==", - "dev": true - }, - "object.omit": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/object.omit/-/object.omit-2.0.1.tgz", - "integrity": "sha1-Gpx0SCnznbuFjHbKNXmuKlTr0fo=", - "dev": true, - "optional": true, - "requires": { - "for-own": "^0.1.4", - "is-extendable": "^0.1.1" - } - }, - "once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", - "dev": true, - "requires": { - "wrappy": "1" - } - }, - "onetime": { - "version": "1.1.0", - "resolved": "http://registry.npmjs.org/onetime/-/onetime-1.1.0.tgz", - "integrity": "sha1-ofeDj4MUxRbwXs78vEzP4EtO14k=", - "dev": true - }, - "optionator": { - "version": "0.8.2", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.2.tgz", - "integrity": "sha1-NkxeQJ0/TWMB1sC0wFu6UBgK62Q=", - "dev": true, - "requires": { - "deep-is": "~0.1.3", - "fast-levenshtein": "~2.0.4", - "levn": "~0.3.0", - "prelude-ls": "~1.1.2", - "type-check": "~0.3.2", - "wordwrap": "~1.0.0" - }, - "dependencies": { - "wordwrap": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", - "integrity": "sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus=", - "dev": true - } - } - }, - "os-homedir": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz", - "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=", - "dev": true - }, - "os-locale": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-1.4.0.tgz", - "integrity": "sha1-IPnxeuKe00XoveWDsT0gCYA8FNk=", - "dev": true, - "requires": { - "lcid": "^1.0.0" - } - }, - "os-tmpdir": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", - "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=", - "dev": true - }, - "output-file-sync": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/output-file-sync/-/output-file-sync-1.1.2.tgz", - "integrity": "sha1-0KM+7+YaIF+suQCS6CZZjVJFznY=", - "dev": true, - "requires": { - "graceful-fs": "^4.1.4", - "mkdirp": "^0.5.1", - "object-assign": "^4.1.0" - } - }, - "parse-glob": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/parse-glob/-/parse-glob-3.0.4.tgz", - "integrity": "sha1-ssN2z7EfNVE7rdFz7wu246OIORw=", - "dev": true, - "optional": true, - "requires": { - "glob-base": "^0.3.0", - "is-dotfile": "^1.0.0", - "is-extglob": "^1.0.0", - "is-glob": "^2.0.0" - } - }, - "path-exists": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-1.0.0.tgz", - "integrity": "sha1-1aiZjrce83p0w06w2eum6HjuoIE=", - "dev": true - }, - "path-is-absolute": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", - "dev": true - }, - "path-is-inside": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz", - "integrity": "sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM=", - "dev": true - }, - "path-parse": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz", - "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==", - "dev": true - }, - "pify": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", - "dev": true - }, - "pinkie": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz", - "integrity": "sha1-clVrgM+g1IqXToDnckjoDtT3+HA=", - "dev": true - }, - "pinkie-promise": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz", - "integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=", - "dev": true, - "requires": { - "pinkie": "^2.0.0" - } - }, - "pluralize": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/pluralize/-/pluralize-1.2.1.tgz", - "integrity": "sha1-0aIUg/0iu0HlihL6NCGCMUCJfEU=", - "dev": true - }, - "postcss": { - "version": "7.0.2", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.2.tgz", - "integrity": "sha512-fmaUY5370keLUTx+CnwRxtGiuFTcNBLQBqr1oE3WZ/euIYmGAo0OAgOhVJ3ByDnVmOR3PK+0V9VebzfjRIUcqw==", - "requires": { - "chalk": "^2.4.1", - "source-map": "^0.6.1", - "supports-color": "^5.4.0" - } - }, - "postcss-selector-matches": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/postcss-selector-matches/-/postcss-selector-matches-3.0.1.tgz", - "integrity": "sha1-5WNAEeE5UIgYYbvdWMLQER/8lqs=", - "requires": { - "balanced-match": "^0.4.2", - "postcss": "^6.0.1" - }, - "dependencies": { - "postcss": { - "version": "6.0.23", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.23.tgz", - "integrity": "sha512-soOk1h6J3VMTZtVeVpv15/Hpdl2cBLX3CAw4TAbkpTJiNPk9YP/zWcD1ND+xEtvyuuvKzbxliTOIyvkSeSJ6ag==", - "requires": { - "chalk": "^2.4.1", - "source-map": "^0.6.1", - "supports-color": "^5.4.0" - } - } - } - }, - "prelude-ls": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", - "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=", - "dev": true - }, - "preserve": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/preserve/-/preserve-0.2.0.tgz", - "integrity": "sha1-gV7R9uvGWSb4ZbMQwHE7yzMVzks=", - "dev": true, - "optional": true - }, - "private": { - "version": "0.1.8", - "resolved": "https://registry.npmjs.org/private/-/private-0.1.8.tgz", - "integrity": "sha512-VvivMrbvd2nKkiG38qjULzlc+4Vx4wm/whI9pQD35YrARNnhxeiRktSOhSukRLFNlzg6Br/cJPet5J/u19r/mg==", - "dev": true - }, - "process-nextick-args": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.0.tgz", - "integrity": "sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw==", - "dev": true - }, - "progress": { - "version": "1.1.8", - "resolved": "https://registry.npmjs.org/progress/-/progress-1.1.8.tgz", - "integrity": "sha1-4mDHj2Fhzdmw5WzD4Khd4Xx6V74=", - "dev": true - }, - "q": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/q/-/q-1.5.1.tgz", - "integrity": "sha1-fjL3W0E4EpHQRhHxvxQQmsAGUdc=", - "dev": true - }, - "randomatic": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/randomatic/-/randomatic-3.1.0.tgz", - "integrity": "sha512-KnGPVE0lo2WoXxIZ7cPR8YBpiol4gsSuOwDSg410oHh80ZMp5EiypNqL2K4Z77vJn6lB5rap7IkAmcUlalcnBQ==", - "dev": true, - "optional": true, - "requires": { - "is-number": "^4.0.0", - "kind-of": "^6.0.0", - "math-random": "^1.0.1" - }, - "dependencies": { - "is-number": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-4.0.0.tgz", - "integrity": "sha512-rSklcAIlf1OmFdyAqbnWTLVelsQ58uvZ66S/ZyawjWqIviTWCjg2PzVGw8WUA+nNuPTqb4wgA+NszrJ+08LlgQ==", - "dev": true, - "optional": true - }, - "kind-of": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", - "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==", - "dev": true, - "optional": true - } - } - }, - "readable-stream": { - "version": "2.3.6", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", - "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "readdirp": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-2.1.0.tgz", - "integrity": "sha1-TtCtBg3zBzMAxIRANz9y0cxkLXg=", - "dev": true, - "optional": true, - "requires": { - "graceful-fs": "^4.1.2", - "minimatch": "^3.0.2", - "readable-stream": "^2.0.2", - "set-immediate-shim": "^1.0.1" - } - }, - "readline2": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/readline2/-/readline2-1.0.1.tgz", - "integrity": "sha1-QQWWCP/BVHV7cV2ZidGZ/783LjU=", - "dev": true, - "requires": { - "code-point-at": "^1.0.0", - "is-fullwidth-code-point": "^1.0.0", - "mute-stream": "0.0.5" - } - }, - "recast": { - "version": "0.10.33", - "resolved": "https://registry.npmjs.org/recast/-/recast-0.10.33.tgz", - "integrity": "sha1-lCgI96oBbx+nFCxGHX5XBKqo1pc=", - "dev": true, - "requires": { - "ast-types": "0.8.12", - "esprima-fb": "~15001.1001.0-dev-harmony-fb", - "private": "~0.1.5", - "source-map": "~0.5.0" - }, - "dependencies": { - "ast-types": { - "version": "0.8.12", - "resolved": "https://registry.npmjs.org/ast-types/-/ast-types-0.8.12.tgz", - "integrity": "sha1-oNkOQ1G7iHcWyD/WN+v4GK9K38w=", - "dev": true - }, - "source-map": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", - "dev": true - } - } - }, - "rechoir": { - "version": "0.6.2", - "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.6.2.tgz", - "integrity": "sha1-hSBLVNuoLVdC4oyWdW70OvUOM4Q=", - "dev": true, - "requires": { - "resolve": "^1.1.6" - } - }, - "regenerate": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.0.tgz", - "integrity": "sha512-1G6jJVDWrt0rK99kBjvEtziZNCICAuvIPkSiUFIQxVP06RCVpq3dmDo2oi6ABpYaDYaTRr67BEhL8r1wgEZZKg==", - "dev": true - }, - "regenerator": { - "version": "0.8.40", - "resolved": "https://registry.npmjs.org/regenerator/-/regenerator-0.8.40.tgz", - "integrity": "sha1-oORXxY69uuV1yfjNdRJ+k3VkNdg=", - "dev": true, - "requires": { - "commoner": "~0.10.3", - "defs": "~1.1.0", - "esprima-fb": "~15001.1001.0-dev-harmony-fb", - "private": "~0.1.5", - "recast": "0.10.33", - "through": "~2.3.8" - } - }, - "regenerator-runtime": { - "version": "0.11.1", - "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz", - "integrity": "sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg==", - "dev": true - }, - "regenerator-transform": { - "version": "0.10.1", - "resolved": "https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.10.1.tgz", - "integrity": "sha512-PJepbvDbuK1xgIgnau7Y90cwaAmO/LCLMI2mPvaXq2heGMR3aWW5/BQvYrhJ8jgmQjXewXvBjzfqKcVOmhjZ6Q==", - "dev": true, - "requires": { - "babel-runtime": "^6.18.0", - "babel-types": "^6.19.0", - "private": "^0.1.6" - } - }, - "regex-cache": { - "version": "0.4.4", - "resolved": "https://registry.npmjs.org/regex-cache/-/regex-cache-0.4.4.tgz", - "integrity": "sha512-nVIZwtCjkC9YgvWkpM55B5rBhBYRZhAaJbgcFYXXsHnbZ9UZI9nnVWYZpBlCqv9ho2eZryPnWrZGsOdPwVWXWQ==", - "dev": true, - "optional": true, - "requires": { - "is-equal-shallow": "^0.1.3" - } - }, - "regexpu": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/regexpu/-/regexpu-1.3.0.tgz", - "integrity": "sha1-5TTcmRqeWEYFDJjebX3UpVyeoW0=", - "dev": true, - "requires": { - "esprima": "^2.6.0", - "recast": "^0.10.10", - "regenerate": "^1.2.1", - "regjsgen": "^0.2.0", - "regjsparser": "^0.1.4" - }, - "dependencies": { - "esprima": { - "version": "2.7.3", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-2.7.3.tgz", - "integrity": "sha1-luO3DVd59q1JzQMmc9HDEnZ7pYE=", - "dev": true - } - } - }, - "regexpu-core": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-2.0.0.tgz", - "integrity": "sha1-SdA4g3uNz4v6W5pCE5k45uoq4kA=", - "dev": true, - "requires": { - "regenerate": "^1.2.1", - "regjsgen": "^0.2.0", - "regjsparser": "^0.1.4" - } - }, - "regjsgen": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/regjsgen/-/regjsgen-0.2.0.tgz", - "integrity": "sha1-bAFq3qxVT3WCP+N6wFuS1aTtsfc=", - "dev": true - }, - "regjsparser": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.1.5.tgz", - "integrity": "sha1-fuj4Tcb6eS0/0K4ijSS9lJ6tIFw=", - "dev": true, - "requires": { - "jsesc": "~0.5.0" - }, - "dependencies": { - "jsesc": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-0.5.0.tgz", - "integrity": "sha1-597mbjXW/Bb3EP6R1c9p9w8IkR0=", - "dev": true - } - } - }, - "remove-trailing-separator": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz", - "integrity": "sha1-wkvOKig62tW8P1jg1IJJuSN52O8=", - "dev": true - }, - "repeat-element": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.2.tgz", - "integrity": "sha1-7wiaF40Ug7quTZPrmLT55OEdmQo=", - "dev": true - }, - "repeat-string": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", - "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=", - "dev": true - }, - "repeating": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/repeating/-/repeating-2.0.1.tgz", - "integrity": "sha1-UhTFOpJtNVJwdSf7q0FdvAjQbdo=", - "dev": true, - "requires": { - "is-finite": "^1.0.0" - } - }, - "require-uncached": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/require-uncached/-/require-uncached-1.0.3.tgz", - "integrity": "sha1-Tg1W1slmL9MeQwEcS5WqSZVUIdM=", - "dev": true, - "requires": { - "caller-path": "^0.1.0", - "resolve-from": "^1.0.0" - } - }, - "resolve": { - "version": "1.8.1", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.8.1.tgz", - "integrity": "sha512-AicPrAC7Qu1JxPCZ9ZgCZlY35QgFnNqc+0LtbRNxnVw4TXvjQ72wnuL9JQcEBgXkI9JM8MsT9kaQoHcpCRJOYA==", - "dev": true, - "requires": { - "path-parse": "^1.0.5" - } - }, - "resolve-from": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-1.0.1.tgz", - "integrity": "sha1-Jsv+k10a7uq7Kbw/5a6wHpPUQiY=", - "dev": true - }, - "restore-cursor": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-1.0.1.tgz", - "integrity": "sha1-NGYfRohjJ/7SmRR5FSJS35LapUE=", - "dev": true, - "requires": { - "exit-hook": "^1.0.0", - "onetime": "^1.0.0" - } - }, - "resumer": { - "version": "0.0.0", - "resolved": "https://registry.npmjs.org/resumer/-/resumer-0.0.0.tgz", - "integrity": "sha1-8ej0YeQGS6Oegq883CqMiT0HZ1k=", - "dev": true, - "requires": { - "through": "~2.3.4" - } - }, - "right-align": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/right-align/-/right-align-0.1.3.tgz", - "integrity": "sha1-YTObci/mo1FWiSENJOFMlhSGE+8=", - "dev": true, - "requires": { - "align-text": "^0.1.1" - } - }, - "rimraf": { - "version": "2.6.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.2.tgz", - "integrity": "sha512-lreewLK/BlghmxtfH36YYVg1i8IAce4TI7oao75I1g245+6BctqTVQiBP3YUJ9C6DQOXJmkYR9X9fCLtCOJc5w==", - "dev": true, - "requires": { - "glob": "^7.0.5" - } - }, - "run-async": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/run-async/-/run-async-0.1.0.tgz", - "integrity": "sha1-yK1KXhEGYeQCp9IbUw4AnyX444k=", - "dev": true, - "requires": { - "once": "^1.3.0" - } - }, - "rx-lite": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/rx-lite/-/rx-lite-3.1.2.tgz", - "integrity": "sha1-Gc5QLKVyZl87ZHsQk5+X/RYV8QI=", - "dev": true - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "safer-buffer": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", - "dev": true - }, - "semver": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.5.0.tgz", - "integrity": "sha512-4SJ3dm0WAwWy/NVeioZh5AntkdJoWKxHxcmyP622fOkgHa4z3R0TdBJICINyaSDE6uNwVc8gZr+ZinwZAH4xIA==", - "dev": true - }, - "set-immediate-shim": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/set-immediate-shim/-/set-immediate-shim-1.0.1.tgz", - "integrity": "sha1-SysbJ+uAip+NzEgaWOXlb1mfP2E=", - "dev": true, - "optional": true - }, - "shebang-regex": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", - "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=", - "dev": true - }, - "shelljs": { - "version": "0.7.8", - "resolved": "https://registry.npmjs.org/shelljs/-/shelljs-0.7.8.tgz", - "integrity": "sha1-3svPh0sNHl+3LhSxZKloMEjprLM=", - "dev": true, - "requires": { - "glob": "^7.0.0", - "interpret": "^1.0.0", - "rechoir": "^0.6.2" - } - }, - "simple-fmt": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/simple-fmt/-/simple-fmt-0.1.0.tgz", - "integrity": "sha1-GRv1ZqWeZTBILLJatTtKjchcOms=", - "dev": true - }, - "simple-is": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/simple-is/-/simple-is-0.2.0.tgz", - "integrity": "sha1-Krt1qt453rXMgVzhDmGRFkhQuvA=", - "dev": true - }, - "slash": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-1.0.0.tgz", - "integrity": "sha1-xB8vbDn8FtHNF61LXYlhFK5HDVU=", - "dev": true - }, - "slice-ansi": { - "version": "0.0.4", - "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-0.0.4.tgz", - "integrity": "sha1-7b+JA/ZvfOL46v1s7tZeJkyDGzU=", - "dev": true - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" - }, - "source-map-support": { - "version": "0.4.18", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.4.18.tgz", - "integrity": "sha512-try0/JqxPLF9nOjvSta7tVondkP5dwgyLDjVoyMDlmjugT2lRZ1OfsrYTkCd2hkDnJTKRbO/Rl3orm8vlsUzbA==", - "dev": true, - "requires": { - "source-map": "^0.5.6" - }, - "dependencies": { - "source-map": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", - "dev": true - } - } - }, - "sprintf-js": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", - "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", - "dev": true - }, - "stable": { - "version": "0.1.8", - "resolved": "https://registry.npmjs.org/stable/-/stable-0.1.8.tgz", - "integrity": "sha512-ji9qxRnOVfcuLDySj9qzhGSEFVobyt1kIOSkj1qZzYLzq7Tos/oUUWvotUPQLlrsidqsK6tBH89Bc9kL5zHA6w==", - "dev": true - }, - "string-width": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", - "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", - "dev": true, - "requires": { - "code-point-at": "^1.0.0", - "is-fullwidth-code-point": "^1.0.0", - "strip-ansi": "^3.0.0" - } - }, - "string.prototype.trim": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.1.2.tgz", - "integrity": "sha1-0E3iyJ4Tf019IG8Ia17S+ua+jOo=", - "dev": true, - "requires": { - "define-properties": "^1.1.2", - "es-abstract": "^1.5.0", - "function-bind": "^1.0.2" - } - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - }, - "stringmap": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/stringmap/-/stringmap-0.2.2.tgz", - "integrity": "sha1-VWwTeyWPlCuHdvWy71gqoGnX0bE=", - "dev": true - }, - "stringset": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/stringset/-/stringset-0.2.1.tgz", - "integrity": "sha1-7yWcTjSTRDd/zRyRPdLoSMnAQrU=", - "dev": true - }, - "strip-ansi": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", - "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", - "dev": true, - "requires": { - "ansi-regex": "^2.0.0" - } - }, - "strip-bom": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", - "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", - "dev": true - }, - "strip-json-comments": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", - "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=", - "dev": true - }, - "supports-color": { - "version": "5.4.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.4.0.tgz", - "integrity": "sha512-zjaXglF5nnWpsq470jSv6P9DwPvgLkuapYmfDm3JWOm0vkNTVF2tI4UrN2r6jH1qM/uc/WtxYY1hYoA2dOKj5w==", - "requires": { - "has-flag": "^3.0.0" - } - }, - "table": { - "version": "3.8.3", - "resolved": "https://registry.npmjs.org/table/-/table-3.8.3.tgz", - "integrity": "sha1-K7xULw/amGGnVdOUf+/Ys/UThV8=", - "dev": true, - "requires": { - "ajv": "^4.7.0", - "ajv-keywords": "^1.0.0", - "chalk": "^1.1.1", - "lodash": "^4.0.0", - "slice-ansi": "0.0.4", - "string-width": "^2.0.0" - }, - "dependencies": { - "ansi-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", - "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", - "dev": true - }, - "ansi-styles": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", - "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", - "dev": true - }, - "chalk": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", - "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", - "dev": true, - "requires": { - "ansi-styles": "^2.2.1", - "escape-string-regexp": "^1.0.2", - "has-ansi": "^2.0.0", - "strip-ansi": "^3.0.0", - "supports-color": "^2.0.0" - } - }, - "is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", - "dev": true - }, - "string-width": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", - "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", - "dev": true, - "requires": { - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^4.0.0" - }, - "dependencies": { - "strip-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", - "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", - "dev": true, - "requires": { - "ansi-regex": "^3.0.0" - } - } - } - }, - "supports-color": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", - "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", - "dev": true - } - } - }, - "tape": { - "version": "4.9.1", - "resolved": "https://registry.npmjs.org/tape/-/tape-4.9.1.tgz", - "integrity": "sha512-6fKIXknLpoe/Jp4rzHKFPpJUHDHDqn8jus99IfPnHIjyz78HYlefTGD3b5EkbQzuLfaEvmfPK3IolLgq2xT3kw==", - "dev": true, - "requires": { - "deep-equal": "~1.0.1", - "defined": "~1.0.0", - "for-each": "~0.3.3", - "function-bind": "~1.1.1", - "glob": "~7.1.2", - "has": "~1.0.3", - "inherits": "~2.0.3", - "minimist": "~1.2.0", - "object-inspect": "~1.6.0", - "resolve": "~1.7.1", - "resumer": "~0.0.0", - "string.prototype.trim": "~1.1.2", - "through": "~2.3.8" - }, - "dependencies": { - "minimist": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", - "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", - "dev": true - }, - "resolve": { - "version": "1.7.1", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.7.1.tgz", - "integrity": "sha512-c7rwLofp8g1U+h1KNyHL/jicrKg1Ek4q+Lr33AL65uZTinUZHe30D5HlyN5V9NW0JX1D5dXQ4jqW5l7Sy/kGfw==", - "dev": true, - "requires": { - "path-parse": "^1.0.5" - } - } - } - }, - "text-table": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", - "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=", - "dev": true - }, - "through": { - "version": "2.3.8", - "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", - "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=", - "dev": true - }, - "to-fast-properties": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-1.0.3.tgz", - "integrity": "sha1-uDVx+k2MJbguIxsG46MFXeTKGkc=", - "dev": true - }, - "trim-right": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/trim-right/-/trim-right-1.0.1.tgz", - "integrity": "sha1-yy4SAwZ+DI3h9hQJS5/kVwTqYAM=", - "dev": true - }, - "try-resolve": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/try-resolve/-/try-resolve-1.0.1.tgz", - "integrity": "sha1-z95vq9ctY+V5fPqrhzq76OcA6RI=", - "dev": true - }, - "tryor": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/tryor/-/tryor-0.1.2.tgz", - "integrity": "sha1-gUXkynyv9ArN48z5Rui4u3W0Fys=", - "dev": true - }, - "type-check": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", - "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=", - "dev": true, - "requires": { - "prelude-ls": "~1.1.2" - } - }, - "typedarray": { - "version": "0.0.6", - "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", - "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=", - "dev": true - }, - "user-home": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/user-home/-/user-home-1.1.1.tgz", - "integrity": "sha1-K1viOjK2Onyd640PKNSFcko98ZA=", - "dev": true - }, - "util-deprecate": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=", - "dev": true - }, - "v8flags": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/v8flags/-/v8flags-2.1.1.tgz", - "integrity": "sha1-qrGh+jDUX4jdMhFIh1rALAtV5bQ=", - "dev": true, - "requires": { - "user-home": "^1.1.1" - } - }, - "window-size": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/window-size/-/window-size-0.1.4.tgz", - "integrity": "sha1-+OGqHuWlPsW/FR/6CXQqatdpeHY=", - "dev": true - }, - "wordwrap": { - "version": "0.0.2", - "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.2.tgz", - "integrity": "sha1-t5Zpu0LstAn4PVg8rVLKF+qhZD8=", - "dev": true - }, - "wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", - "dev": true - }, - "write": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/write/-/write-0.2.1.tgz", - "integrity": "sha1-X8A4KOJkzqP+kUVUdvejxWbLB1c=", - "dev": true, - "requires": { - "mkdirp": "^0.5.1" - } - }, - "xtend": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz", - "integrity": "sha1-pcbVMr5lbiPbgg77lDofBJmNY68=", - "dev": true - }, - "y18n": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-3.2.1.tgz", - "integrity": "sha1-bRX7qITAhnnA136I53WegR4H+kE=", - "dev": true - }, - "yargs": { - "version": "3.27.0", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-3.27.0.tgz", - "integrity": "sha1-ISBUaTFuk5Ex1Z8toMbX+YIh6kA=", - "dev": true, - "requires": { - "camelcase": "^1.2.1", - "cliui": "^2.1.0", - "decamelize": "^1.0.0", - "os-locale": "^1.4.0", - "window-size": "^0.1.2", - "y18n": "^3.2.0" - } - } - } -} diff --git a/package.json b/package.json index 174ebf0aba..6711a8a0d2 100644 --- a/package.json +++ b/package.json @@ -1,50 +1,66 @@ { "name": "postcss-custom-selectors", - "version": "4.0.1", - "description": "PostCSS plugin to transform W3C CSS Extensions(Custom Selectors) to more compatible CSS", - "keywords": [ - "postcss", - "postcss-plugin", - "css", - "selector", - "custom-selector" - ], - "authors": [ + "version": "5.0.0", + "description": "Use Custom Selectors in CSS", + "author": "Jonathan Neal ", + "contributors": [ "yisi", "Maxime Thirouin" ], - "license": "MIT", - "repository": { - "type": "git", - "url": "https://github.com/postcss/postcss-custom-selectors.git" - }, - "main": "dist/index.js", + "license": "CC0-1.0", + "repository": "jonathantneal/postcss-custom-selectors", + "homepage": "https://github.com/jonathantneal/postcss-custom-selectors#readme", + "bugs": "https://github.com/jonathantneal/postcss-custom-selectors/issues", + "main": "index.cjs.js", + "module": "index.es.mjs", "files": [ - "dist", - "README-zh.md" + "index.cjs.js", + "index.es.mjs" ], + "scripts": { + "prepublishOnly": "npm test", + "pretest": "rollup -c .rollup.js --silent", + "test": "echo 'Running tests...'; npm run test:js && npm run test:tape", + "test:ec": "echint --ignore index.*.js test", + "test:js": "eslint *.js lib/*.js --cache --ignore-path .gitignore --quiet", + "test:tape": "postcss-tape" + }, "engines": { "node": ">=6.0.0" }, "dependencies": { "postcss": "^7.0.2", - "postcss-selector-matches": "^3.0.0" + "postcss-selector-parser": "^5.0.0-rc.3" }, "devDependencies": { - "babel-cli": "^6.24.1", - "babel-plugin-add-module-exports": "^0.2.1", - "babel-plugin-transform-object-rest-spread": "^6.23.0", - "babel-preset-env": "^1.4.0", - "babel-register": "^6.24.1", - "babel-tape-runner": "^1.1.0", - "eslint": "^3.19.0", - "tape": "^4.6.3" + "@babel/core": "^7.0.0", + "@babel/plugin-syntax-dynamic-import": "^7.0.0", + "@babel/preset-env": "^7.0.0", + "babel-eslint": "^9.0.0", + "eslint": "^5.5.0", + "eslint-config-dev": "^2.0.0", + "postcss-tape": "^2.2.0", + "pre-commit": "^1.2.2", + "rollup": "^0.65.2", + "rollup-plugin-babel": "^4.0.1" }, - "scripts": { - "babelify": "babel src --out-dir dist", - "prepublish": "npm run babelify", - "lint": "eslint *.js ./src/ ./test/", - "tape": "tape -r babel-register test/*.js", - "test": "npm run lint && npm run babelify && npm run tape" - } + "eslintConfig": { + "extends": "dev", + "parser": "babel-eslint" + }, + "keywords": [ + "postcss", + "css", + "postcss-plugin", + "custom", + "selectors", + "w3c", + "csswg", + "extensions", + "declarative", + "rule", + "atrule", + "at-rule", + "specification" + ] } diff --git a/src/index.js b/src/index.js deleted file mode 100644 index bed17313c7..0000000000 --- a/src/index.js +++ /dev/null @@ -1,78 +0,0 @@ -import postcss from "postcss" -import replaceRuleSelector - from "postcss-selector-matches/dist/replaceRuleSelector" - -const CUSTOM_SELECTOR_RE = /:--[\w-]+/g - -export default postcss.plugin("postcss-custom-selectors", function(options) { - const { - extensions, - lineBreak, - transformMatches, - } = { - extensions: {}, - lineBreak: true, - transformMatches: true, - ...options || {}, - } - - const transformMatchesOnRule = transformMatches - ? (rule) => replaceRuleSelector(rule, { - lineBreak, - }) - : (rule) => rule.selector - - return function(css, result) { - const toRemove = [] - const customSelectors = {} - - // first, read custom selectors - css.walkAtRules(function(rule) { - if (rule.name !== "custom-selector") { - return - } - - // @custom-selector = @custom-selector - const params = rule.params.split(/\s/) - const customName = params.shift() - const customList = rule.params.replace(customName, "").trim() - customSelectors[customName] = customList - - toRemove.push(rule) - }) - - // Add JS defined selectors - Object.keys(extensions).forEach(function(extension) { - customSelectors[extension] = extensions[extension] - }) - - // Convert those selectors to :matches() - css.walkRules(function(rule) { - if (rule.selector.indexOf(":--") > -1) { - rule.selector = rule.selector.replace( - CUSTOM_SELECTOR_RE, - function(extensionName, matches, selector) { - - if (!customSelectors[extensionName]) { - result.warn( - "The selector '" + rule.selector + "' is undefined", - {node: rule} - ) - - return selector - } - - return ":matches(" + customSelectors[extensionName] + ")" - } - ) - - rule.selector = transformMatchesOnRule(rule) - } - }) - - toRemove.forEach(function(rule) { - rule.remove() - }) - - } -}) diff --git a/test/basic.css b/test/basic.css new file mode 100644 index 0000000000..bc702aa942 --- /dev/null +++ b/test/basic.css @@ -0,0 +1,94 @@ +@custom-selector :--foo .bar, .baz; + +.foo:--foo { + margin-top: 16px; +} + +@custom-selector :--any-heading h1, h2, h3, h4, h5, h6; + +:--any-heading + p {} + +@custom-selector :--foobar .foo, .bar; +@custom-selector :--baz .baz; +@custom-selector :--fizzbuzz .fizz, .buzz; +@custom-selector :--button-types + .btn-primary, + .btn-success, + .btn-info, + .btn-warning, + .btn-danger; + +:--foobar > :--baz {} +:--fizzbuzz > :--foobar {} +:--button-types, :--button-types:active {} + +@custom-selector :--commented-foo + /* comment */ + .foo, + .bar > .baz; + +:--commented-foo + p { + display: block; +} + +@custom-selector :--pseudo ::before, ::after; + +.foo > a:--pseudo img { + display: block; +} + +@custom-selector :--foo .foo; + +:--foo, :--foo.bar { + color: white; +} + +:--foo :--foo:hover { + color: white; +} + +@custom-selector :--fo-----o h1, h2, h3; +@custom-selector :--ba-----r h4, h5, h6; + +.fo--oo > :--fo-----o { + margin: auto; +} + +:--ba-----r:hover .ba--z { + display: block; +} + +/* comment */ + +article :--heading + p { + margin-top: 0; +} + +@custom-selector :--multiline + .foo, + .bar > .baz; + +:--multiline { + display: block; +} + +/* should works with collapsed custom selectors */ + +@custom-selector :--button button, .button; +@custom-selector :--enter :hover, :focus; + +:--button:--enter {} + +@custom-selector :--any-foobar .foo, .bar; + +:--any-foobar h1 { + margin-top: 16px; +} + +main :--foo + p { + margin-top: 16px; +} + +@custom-selector :--foobar .foo; + +:--foobar {} diff --git a/test/basic.expect.css b/test/basic.expect.css new file mode 100644 index 0000000000..c473452988 --- /dev/null +++ b/test/basic.expect.css @@ -0,0 +1,57 @@ +.foo.foo { + margin-top: 16px; +} + +h1 + p,h2 + p,h3 + p,h4 + p,h5 + p,h6 + p {} + +.foo > .baz {} +.fizz > .foo,.buzz > .foo {} +.btn-primary,.btn-success,.btn-info,.btn-warning,.btn-danger, .btn-primary:active, .btn-success:active, .btn-info:active, .btn-warning:active, .btn-danger:active {} + +.foo + p,.bar>.baz + p { + display: block; +} + +.foo > a::before img,.foo > a::after img { + display: block; +} + +.foo, .foo.bar { + color: white; +} + +.foo .foo:hover { + color: white; +} + +.fo--oo > h1,.fo--oo > h2,.fo--oo > h3 { + margin: auto; +} + +h4:hover .ba--z,h5:hover .ba--z,h6:hover .ba--z { + display: block; +} + +/* comment */ + +article :--heading + p { + margin-top: 0; +} + +.foo,.bar>.baz { + display: block; +} + +/* should works with collapsed custom selectors */ + +button:hover,button:focus,.button:hover,.button:focus {} + +.foo h1,.bar h1 { + margin-top: 16px; +} + +main .foo + p { + margin-top: 16px; +} + +.foo {} diff --git a/test/basic.import.expect.css b/test/basic.import.expect.css new file mode 100644 index 0000000000..46a68c70ea --- /dev/null +++ b/test/basic.import.expect.css @@ -0,0 +1,57 @@ +.foo.foo { + margin-top: 16px; +} + +h1 + p,h2 + p,h3 + p,h4 + p,h5 + p,h6 + p {} + +.foo > .baz {} +.fizz > .foo,.buzz > .foo {} +.btn-primary,.btn-success,.btn-info,.btn-warning,.btn-danger, .btn-primary:active, .btn-success:active, .btn-info:active, .btn-warning:active, .btn-danger:active {} + +.foo + p,.bar>.baz + p { + display: block; +} + +.foo > a::before img,.foo > a::after img { + display: block; +} + +.foo, .foo.bar { + color: white; +} + +.foo .foo:hover { + color: white; +} + +.fo--oo > h1,.fo--oo > h2,.fo--oo > h3 { + margin: auto; +} + +h4:hover .ba--z,h5:hover .ba--z,h6:hover .ba--z { + display: block; +} + +/* comment */ + +article h1 + p,article h2 + p,article h3 + p { + margin-top: 0; +} + +.foo,.bar>.baz { + display: block; +} + +/* should works with collapsed custom selectors */ + +button:hover,button:focus,.button:hover,.button:focus {} + +.foo h1,.bar h1 { + margin-top: 16px; +} + +main .foo + p { + margin-top: 16px; +} + +.foo {} diff --git a/test/basic.preserve.expect.css b/test/basic.preserve.expect.css new file mode 100644 index 0000000000..6727460be1 --- /dev/null +++ b/test/basic.preserve.expect.css @@ -0,0 +1,148 @@ +@custom-selector :--foo .bar, .baz; + +.foo.foo { + margin-top: 16px; +} + +.foo:--foo { + margin-top: 16px; +} + +@custom-selector :--any-heading h1, h2, h3, h4, h5, h6; + +h1 + p,h2 + p,h3 + p,h4 + p,h5 + p,h6 + p {} + +:--any-heading + p {} + +@custom-selector :--foobar .foo, .bar; +@custom-selector :--baz .baz; +@custom-selector :--fizzbuzz .fizz, .buzz; +@custom-selector :--button-types + .btn-primary, + .btn-success, + .btn-info, + .btn-warning, + .btn-danger; + +.foo > .baz {} + +:--foobar > :--baz {} +.fizz > .foo,.buzz > .foo {} +:--fizzbuzz > :--foobar {} +.btn-primary,.btn-success,.btn-info,.btn-warning,.btn-danger, .btn-primary:active, .btn-success:active, .btn-info:active, .btn-warning:active, .btn-danger:active {} +:--button-types, :--button-types:active {} + +@custom-selector :--commented-foo + /* comment */ + .foo, + .bar > .baz; + +.foo + p,.bar>.baz + p { + display: block; +} + +:--commented-foo + p { + display: block; +} + +@custom-selector :--pseudo ::before, ::after; + +.foo > a::before img,.foo > a::after img { + display: block; +} + +.foo > a:--pseudo img { + display: block; +} + +@custom-selector :--foo .foo; + +.foo, .foo.bar { + color: white; +} + +:--foo, :--foo.bar { + color: white; +} + +.foo .foo:hover { + color: white; +} + +:--foo :--foo:hover { + color: white; +} + +@custom-selector :--fo-----o h1, h2, h3; +@custom-selector :--ba-----r h4, h5, h6; + +.fo--oo > h1,.fo--oo > h2,.fo--oo > h3 { + margin: auto; +} + +.fo--oo > :--fo-----o { + margin: auto; +} + +h4:hover .ba--z,h5:hover .ba--z,h6:hover .ba--z { + display: block; +} + +:--ba-----r:hover .ba--z { + display: block; +} + +/* comment */ + +article :--heading + p { + margin-top: 0; +} + +article :--heading + p { + margin-top: 0; +} + +@custom-selector :--multiline + .foo, + .bar > .baz; + +.foo,.bar>.baz { + display: block; +} + +:--multiline { + display: block; +} + +/* should works with collapsed custom selectors */ + +@custom-selector :--button button, .button; +@custom-selector :--enter :hover, :focus; + +button:hover,button:focus,.button:hover,.button:focus {} + +:--button:--enter {} + +@custom-selector :--any-foobar .foo, .bar; + +.foo h1,.bar h1 { + margin-top: 16px; +} + +:--any-foobar h1 { + margin-top: 16px; +} + +main .foo + p { + margin-top: 16px; +} + +main :--foo + p { + margin-top: 16px; +} + +@custom-selector :--foobar .foo; + +.foo {} + +:--foobar {} diff --git a/test/import-selectors.css b/test/import-selectors.css new file mode 100644 index 0000000000..6926002c1b --- /dev/null +++ b/test/import-selectors.css @@ -0,0 +1 @@ +@custom-selector :--heading h1, h2, h3; diff --git a/test/import-selectors.js b/test/import-selectors.js new file mode 100644 index 0000000000..71d4556011 --- /dev/null +++ b/test/import-selectors.js @@ -0,0 +1,5 @@ +module.exports = { + customSelectors: { + ':--heading': 'h1, h2, h3' + } +} diff --git a/test/import-selectors.json b/test/import-selectors.json new file mode 100644 index 0000000000..1c3b8bc4f8 --- /dev/null +++ b/test/import-selectors.json @@ -0,0 +1,5 @@ +{ + "custom-selectors": { + ":--heading": "h1, h2, h3" + } +} From b7806565adab9093eb3f9ea67ad85d659ab88373 Mon Sep 17 00:00:00 2001 From: Jonathan Neal Date: Thu, 13 Sep 2018 21:35:17 -0400 Subject: [PATCH 675/795] 7.0.0 --- .editorconfig | 13 +- .gitignore | 11 +- .rollup.js | 19 + .tape.js | 7 + .travis.yml | 11 +- CHANGELOG.md | 34 +- CONTRIBUTING.md | 65 + INSTALL.md | 170 ++ LICENSE => LICENSE.md | 21 +- README.md | 160 +- index.js | 163 +- lib/custom-media-from-root.js | 34 + lib/export-to.js | 129 ++ lib/import-from.js | 120 + lib/media-ast-from-string.js | 134 ++ lib/transform-atrules.js | 21 + lib/transform-params-by-custom-params.js | 62 + package-lock.json | 2035 ----------------- package.json | 73 +- test/basic.css | 33 + test/basic.expect.css | 27 + test/fixtures/append.css | 3 - test/fixtures/append.expected.css | 4 - test/fixtures/js-defined.css | 15 - test/fixtures/js-defined.expected.css | 15 - test/fixtures/preserve.css | 4 - test/fixtures/preserve.expected.css | 4 - test/fixtures/transform-all.css | 8 - test/fixtures/transform-all.expected.css | 7 - .../fixtures/transform-circular-reference.css | 16 - .../transform-circular-reference.expected.css | 1 - test/fixtures/transform-reference.css | 8 - .../fixtures/transform-reference.expected.css | 7 - test/fixtures/transform-self-reference.css | 9 - .../transform-self-reference.expected.css | 1 - test/fixtures/transform.css | 16 - test/fixtures/transform.expected.css | 15 - test/fixtures/undefined.css | 5 - test/fixtures/undefined.expected.css | 1 - test/index.js | 117 - 40 files changed, 1064 insertions(+), 2534 deletions(-) create mode 100644 .rollup.js create mode 100644 .tape.js create mode 100644 CONTRIBUTING.md create mode 100644 INSTALL.md rename LICENSE => LICENSE.md (51%) mode change 100755 => 100644 create mode 100644 lib/custom-media-from-root.js create mode 100644 lib/export-to.js create mode 100644 lib/import-from.js create mode 100644 lib/media-ast-from-string.js create mode 100644 lib/transform-atrules.js create mode 100644 lib/transform-params-by-custom-params.js delete mode 100644 package-lock.json create mode 100644 test/basic.css create mode 100644 test/basic.expect.css delete mode 100644 test/fixtures/append.css delete mode 100644 test/fixtures/append.expected.css delete mode 100755 test/fixtures/js-defined.css delete mode 100755 test/fixtures/js-defined.expected.css delete mode 100644 test/fixtures/preserve.css delete mode 100644 test/fixtures/preserve.expected.css delete mode 100644 test/fixtures/transform-all.css delete mode 100644 test/fixtures/transform-all.expected.css delete mode 100644 test/fixtures/transform-circular-reference.css delete mode 100644 test/fixtures/transform-circular-reference.expected.css delete mode 100644 test/fixtures/transform-reference.css delete mode 100644 test/fixtures/transform-reference.expected.css delete mode 100644 test/fixtures/transform-self-reference.css delete mode 100644 test/fixtures/transform-self-reference.expected.css delete mode 100755 test/fixtures/transform.css delete mode 100755 test/fixtures/transform.expected.css delete mode 100755 test/fixtures/undefined.css delete mode 100755 test/fixtures/undefined.expected.css delete mode 100755 test/index.js diff --git a/.editorconfig b/.editorconfig index 8978b448a6..e06d7982bc 100644 --- a/.editorconfig +++ b/.editorconfig @@ -1,16 +1,15 @@ -# editorconfig.org root = true [*] -end_of_line = lf charset = utf-8 -trim_trailing_whitespace = true +end_of_line = lf +indent_style = tab insert_final_newline = true -indent_style = space -indent_size = 2 +trim_trailing_whitespace = true [*.md] trim_trailing_whitespace = false -[Makefile] -indent_style = tab +[*.{json,md,yml}] +indent_size = 2 +indent_style = space diff --git a/.gitignore b/.gitignore index 7ab649f420..d920b78fec 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,11 @@ node_modules -test/fixtures/*.actual.css +index.*.* +package-lock.json +*.log* +*.result.css +.* +!.editorconfig +!.gitignore +!.rollup.js +!.tape.js +!.travis.yml diff --git a/.rollup.js b/.rollup.js new file mode 100644 index 0000000000..eab5c0d513 --- /dev/null +++ b/.rollup.js @@ -0,0 +1,19 @@ +import babel from 'rollup-plugin-babel'; + +export default { + input: 'index.js', + output: [ + { file: 'index.cjs.js', format: 'cjs' }, + { file: 'index.es.mjs', format: 'es' } + ], + plugins: [ + babel({ + plugins: [ + '@babel/plugin-syntax-dynamic-import' + ], + presets: [ + ['@babel/env', { modules: false, targets: { node: 6 } }] + ] + }) + ] +}; diff --git a/.tape.js b/.tape.js new file mode 100644 index 0000000000..ee6d7a3ac2 --- /dev/null +++ b/.tape.js @@ -0,0 +1,7 @@ +module.exports = { + 'postcss-custom-media': { + 'basic': { + message: 'supports basic usage' + } + } +}; diff --git a/.travis.yml b/.travis.yml index ebea37eb05..e1f11a52e6 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,6 +1,9 @@ -sudo: false +# https://docs.travis-ci.com/user/travis-lint + language: node_js + node_js: - - "stable" - - "8" - - "6" + - 6 + +install: + - npm install --ignore-scripts diff --git a/CHANGELOG.md b/CHANGELOG.md index 70d4c04ab8..666301d609 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,23 +1,33 @@ -# 6.0.0 - 2017-05-12 +# Changes to PostCSS Custom Media + +### 7.0.0 (September 12, 2018) + +- Added: New `preserve` option to preserve custom media and atrules using them +- Added: New `exportTo` function to specify where to export custom media +- Added: New `importFrom` option to specify where to import custom media +- Added: Support for PostCSS v7 +- Added: Support for Node v6+ + +# 6.0.0 (May 12, 2017) - Added: compatibility with postcss v6.x -# 5.0.1 - 2016-02-03 +# 5.0.1 (February 3, 2016) - Fixed: circular dependencies are properly detected ([#17](https://github.com/postcss/postcss-custom-media/pull/17)) -# 5.0.0 - 2015-08-25 +# 5.0.0 (August 25, 2015) - Removed: compatibility with postcss v4.x - Added: compatibility with postcss v5.x -# 4.1.0 - 2015-06-30 +# 4.1.0 (06 30, 2015) - Added: Allow custom media to reference each other ([#10](https://github.com/postcss/postcss-custom-media/pull/10)) -# 4.0.0 - 2015-05-17 +# 4.0.0 (May 17, 2015) - Changed: warning messages are now sent via postcss messages api (^4.1.0) - Added: automatic custom media `--` prefixing @@ -25,7 +35,7 @@ - Added: `preserve` allows you to preserve custom media query defintions - Added: `appendExtensions` allows you (when `preserve` is truthy) to append your extensions as media queries -# 3.0.0 - 2015-01-29 +# 3.0.0 (January 29, 2015) - Added: compatibility with postcss v4.x - Removed: compatibility with postcss v3.x @@ -34,26 +44,26 @@ _You never saw this version (this is a bad release that points to 1.0.0)._ -# 1.3.0 - 2014-11-25 +# 1.3.0 (November 25, 2014) - Changed: better gnu message -# 1.2.1 - 2014-10-09 +# 1.2.1 (October 9, 2014) - Fixed: npm description -# 1.2.0 - 2014-10-01 +# 1.2.0 (October 1, 2014) - Added: support for multiples media in query list (ref [#rework-custom-media/5](https://github.com/reworkcss/rework-custom-media/pull/5)) -# 1.1.0 - 2014-09-30 +# 1.1.0 (September 30, 2014) - Added: support for js-defined media queries (fix [#3](https://github.com/postcss/postcss-custom-media/issues/3)) -# 1.0.1 - 2014-09-16 +# 1.0.1 (September 16, 2014) - Added: Allow whitespace around custom media name (fix [#2](https://github.com/postcss/postcss-custom-media/issues/2)) -# 1.0.0 - 2014-08-12 +# 1.0.0 (August 12, 2014) ✨ First release based on [rework-custom-media](https://github.com/reworkcss/rework-custom-media) v0.1.1 diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 0000000000..bce2ffa0a6 --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,65 @@ +# Contributing to PostCSS Custom Media + +You want to help? You rock! Now, take a moment to be sure your contributions +make sense to everyone else. + +## Reporting Issues + +Found a problem? Want a new feature? + +- See if your issue or idea has [already been reported]. +- Provide a [reduced test case] or a [live example]. + +Remember, a bug is a _demonstrable problem_ caused by _our_ code. + +## Submitting Pull Requests + +Pull requests are the greatest contributions, so be sure they are focused in +scope and avoid unrelated commits. + +1. To begin; [fork this project], clone your fork, and add our upstream. + ```bash + # Clone your fork of the repo into the current directory + git clone git@github.com:YOUR_USER/postcss-custom-media.git + + # Navigate to the newly cloned directory + cd postcss-custom-media + + # Assign the original repo to a remote called "upstream" + git remote add upstream git@github.com:postcss/postcss-custom-media.git + + # Install the tools necessary for testing + npm install + ``` + +2. Create a branch for your feature or fix: + ```bash + # Move into a new branch for your feature + git checkout -b feature/thing + ``` + ```bash + # Move into a new branch for your fix + git checkout -b fix/something + ``` + +3. If your code follows our practices, then push your feature branch: + ```bash + # Test current code + npm test + ``` + ```bash + # Push the branch for your new feature + git push origin feature/thing + ``` + ```bash + # Or, push the branch for your update + git push origin update/something + ``` + +That’s it! Now [open a pull request] with a clear title and description. + +[already been reported]: issues +[fork this project]: fork +[live example]: https://codepen.io/pen +[open a pull request]: https://help.github.com/articles/using-pull-requests/ +[reduced test case]: https://css-tricks.com/reduced-test-cases/ diff --git a/INSTALL.md b/INSTALL.md new file mode 100644 index 0000000000..a5b16bd0e8 --- /dev/null +++ b/INSTALL.md @@ -0,0 +1,170 @@ +# Installing PostCSS Custom Media + +[PostCSS Custom Media] runs in all Node environments, with special instructions for: + +| [Node](#node) | [PostCSS CLI](#postcss-cli) | [Webpack](#webpack) | [Create React App](#create-react-app) | [Gulp](#gulp) | [Grunt](#grunt) | +| --- | --- | --- | --- | --- | --- | + +## Node + +Add [PostCSS Custom Media] to your project: + +```bash +npm install postcss-custom-media --save-dev +``` + +Use [PostCSS Custom Media] to process your CSS: + +```js +const postcssCustomMedia = require('postcss-custom-media'); + +postcssCustomMedia.process(YOUR_CSS /*, processOptions, pluginOptions */); +``` + +Or use it as a [PostCSS] plugin: + +```js +const postcss = require('postcss'); +const postcssCustomMedia = require('postcss-custom-media'); + +postcss([ + postcssCustomMedia(/* pluginOptions */) +]).process(YOUR_CSS /*, processOptions */); +``` + +## PostCSS CLI + +Add [PostCSS CLI] to your project: + +```bash +npm install postcss-cli --save-dev +``` + +Use [PostCSS Custom Media] in your `postcss.config.js` configuration file: + +```js +const postcssCustomMedia = require('postcss-custom-media'); + +module.exports = { + plugins: [ + postcssCustomMedia(/* pluginOptions */) + ] +} +``` + +## Webpack + +Add [PostCSS Loader] to your project: + +```bash +npm install postcss-loader --save-dev +``` + +Use [PostCSS Custom Media] in your Webpack configuration: + +```js +const postcssCustomMedia = require('postcss-custom-media'); + +module.exports = { + module: { + rules: [ + { + test: /\.css$/, + use: [ + 'style-loader', + { loader: 'css-loader', options: { importLoaders: 1 } }, + { loader: 'postcss-loader', options: { + ident: 'postcss', + plugins: () => [ + postcssCustomMedia(/* pluginOptions */) + ] + } } + ] + } + ] + } +} +``` + +## Create React App + +Add [React App Rewired] and [React App Rewire PostCSS] to your project: + +```bash +npm install react-app-rewired react-app-rewire-postcss --save-dev +``` + +Use [React App Rewire PostCSS] and [PostCSS Custom Media] in your +`config-overrides.js` file: + +```js +const reactAppRewirePostcss = require('react-app-rewire-postcss'); +const postcssCustomMedia = require('postcss-custom-media'); + +module.exports = config => reactAppRewirePostcss(config, { + plugins: () => [ + postcssCustomMedia(/* pluginOptions */) + ] +}); +``` + +## Gulp + +Add [Gulp PostCSS] to your project: + +```bash +npm install gulp-postcss --save-dev +``` + +Use [PostCSS Custom Media] in your Gulpfile: + +```js +const postcss = require('gulp-postcss'); +const postcssCustomMedia = require('postcss-custom-media'); + +gulp.task('css', () => gulp.src('./src/*.css').pipe( + postcss([ + postcssCustomMedia(/* pluginOptions */) + ]) +).pipe( + gulp.dest('.') +)); +``` + +## Grunt + +Add [Grunt PostCSS] to your project: + +```bash +npm install grunt-postcss --save-dev +``` + +Use [PostCSS Custom Media] in your Gruntfile: + +```js +const postcssCustomMedia = require('postcss-custom-media'); + +grunt.loadNpmTasks('grunt-postcss'); + +grunt.initConfig({ + postcss: { + options: { + use: [ + postcssCustomMedia(/* pluginOptions */) + ] + }, + dist: { + src: '*.css' + } + } +}); +``` + +[Gulp PostCSS]: https://github.com/postcss/gulp-postcss +[Grunt PostCSS]: https://github.com/nDmitry/grunt-postcss +[PostCSS]: https://github.com/postcss/postcss +[PostCSS CLI]: https://github.com/postcss/postcss-cli +[PostCSS Loader]: https://github.com/postcss/postcss-loader +[PostCSS Custom Media]: https://github.com/postcss/postcss-custom-media +[React App Rewire PostCSS]: https://github.com/csstools/react-app-rewire-postcss +[React App Rewired]: https://github.com/timarney/react-app-rewired diff --git a/LICENSE b/LICENSE.md old mode 100755 new mode 100644 similarity index 51% rename from LICENSE rename to LICENSE.md index f559d05e10..6d70470888 --- a/LICENSE +++ b/LICENSE.md @@ -1,20 +1,21 @@ -The MIT License (MIT) +# The MIT License (MIT) -Copyright (c) 2017 Maxime Thirouin & Nicolas Gallagher +Copyright © PostCSS 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: +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. +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. diff --git a/README.md b/README.md index 0ec621dc2a..eb9551c103 100755 --- a/README.md +++ b/README.md @@ -1,13 +1,12 @@ -# PostCSS Custom Media [PostCSS Logo][postcss] +# PostCSS Custom Media [PostCSS][postcss] [![NPM Version][npm-img]][npm-url] [![CSS Standard Status][css-img]][css-url] [![Build Status][cli-img]][cli-url] [![Support Chat][git-img]][git-url] -> [PostCSS Custom Media] lets you use Custom Media Queries in CSS, following -the [CSS Media Queries](https://drafts.csswg.org/mediaqueries-5/#custom-mq) -specification. +[PostCSS Custom Media] lets you use Custom Media Queries in CSS, following the +[CSS Media Queries] specification. ```pcss @custom-media --small-viewport (max-width: 30em); @@ -23,67 +22,143 @@ specification. } ``` -## Installation +## Usage + +Add [PostCSS Custom Media] to your project: -```console -$ npm install postcss-custom-media +```bash +npm install postcss-custom-media --save-dev ``` -## Usage +Use [PostCSS Custom Media] to process your CSS: + +```js +const postcssCustomMedia = require('postcss-custom-media'); + +postcssCustomMedia.process(YOUR_CSS /*, processOptions, pluginOptions */); +``` + +Or use it as a [PostCSS] plugin: ```js -// dependencies -var postcss = require("postcss") -var customMedia = require("postcss-custom-media") - -// css to be processed -var css = fs.readFileSync("input.css", "utf8") - -// process css using postcss-custom-media -var out = postcss() - .use(customMedia()) - .process(css) - .css +const postcss = require('postcss'); +const postcssCustomMedia = require('postcss-custom-media'); + +postcss([ + postcssCustomMedia(/* pluginOptions */) +]).process(YOUR_CSS /*, processOptions */); ``` -Checkout [tests](test) for more examples. +[PostCSS Custom Media] runs in all Node environments, with special instructions for: -### Options +| [Node](INSTALL.md#node) | [PostCSS CLI](INSTALL.md#postcss-cli) | [Webpack](INSTALL.md#webpack) | [Create React App](INSTALL.md#create-react-app) | [Gulp](INSTALL.md#gulp) | [Grunt](INSTALL.md#grunt) | +| --- | --- | --- | --- | --- | --- | -#### `extensions` +## Options -(default: `{}`) +### preserve -Allows you to pass an object to define the `` for each -``. These definitions will override any that exist in the CSS. +The `preserve` option determines whether custom media and atrules using custom +media should be preserved in their original form. + +```pcss +@custom-media --small-viewport (max-width: 30em); -```javascript -{ - '--phone': '(min-width: 544px)', - '--tablet': '(min-width: 768px)', - '--desktop': '(min-width: 992px)', - '--large-desktop': '(min-width: 1200px)', +@media (--small-viewport) { + /* styles for small viewport */ +} + +/* becomes */ + +@custom-media --small-viewport (max-width: 30em); + +@media (max-width: 30em) { + /* styles for small viewport */ +} + +@media (--small-viewport) { + /* styles for small viewport */ } ``` -#### `preserve` +### importFrom + +The `importFrom` option specifies sources where custom media can be imported +from, which might be CSS, JS, and JSON files, functions, and directly passed +objects. + +```js +postcssCustomMedia({ + importFrom: 'path/to/file.css' // => @custom-selector --small-viewport (max-width: 30em); +}); +``` + +```pcss +@media (max-width: 30em) { + /* styles for small viewport */ +} -(default: `false`) +@media (--small-viewport) { + /* styles for small viewport */ +} +``` -Allows you to preserve custom media query definitions in output. +Multiple sources can be passed into this option, and they will be parsed in the +order they are received. JavaScript files, JSON files, functions, and objects +will need to namespace custom media using the `customProperties` or +`custom-properties` key. -#### `appendExtensions` +```js +postcssCustomMedia({ + importFrom: [ + 'path/to/file.css', + 'and/then/this.js', + 'and/then/that.json', + { + customMedia: { '--small-viewport': '(max-width: 30em)' } + }, + () => { + const customProperties = { '--small-viewport': '(max-width: 30em)' }; + + return { customProperties }; + } + ] +}); +``` -(default: `false`) +### exportTo -**This option only works if `preserve` is truthy**. -Allows you to append your extensions at end of your CSS. +The `exportTo` option specifies destinations where custom media can be exported +to, which might be CSS, JS, and JSON files, functions, and directly passed +objects. ---- +```js +postcssCustomMedia({ + exportTo: 'path/to/file.css' // @custom-media --small-viewport (max-width: 30em); +}); +``` -## [Changelog](CHANGELOG.md) +Multiple destinations can be passed into this option, and they will be parsed +in the order they are received. JavaScript files, JSON files, and objects will +need to namespace custom media using the `customProperties` or +`custom-properties` key. -## [License](LICENSE) +```js +const cachedObject = { customMedia: {} }; + +postcssCustomMedia({ + exportTo: [ + 'path/to/file.css', // @custom-media --small-viewport (max-width: 30em); + 'and/then/this.js', // module.exports = { customMedia: { '--small-viewport': '(max-width: 30em)' } } + 'and/then/this.mjs', // export const customMedia = { '--small-viewport': '(max-width: 30em)' } } + 'and/then/that.json', // { "custom-media": { "--small-viewport": "(max-width: 30em)" } } + cachedObject, + customProperties => { + customProperties // { '--small-viewport': '(max-width: 30em)' } + } + ] +}); +``` [cli-img]: https://img.shields.io/travis/postcss/postcss-custom-media.svg [cli-url]: https://travis-ci.org/postcss/postcss-custom-media @@ -94,5 +169,6 @@ Allows you to append your extensions at end of your CSS. [npm-img]: https://img.shields.io/npm/v/postcss-custom-media.svg [npm-url]: https://www.npmjs.com/package/postcss-custom-media +[CSS Media Queries]: https://drafts.csswg.org/mediaqueries-5/#custom-mq [PostCSS]: https://github.com/postcss/postcss [PostCSS Custom Media]: https://github.com/postcss/postcss-custom-media diff --git a/index.js b/index.js index 5531f7589a..7547790c60 100755 --- a/index.js +++ b/index.js @@ -1,147 +1,30 @@ -var postcss = require("postcss") +import postcss from 'postcss'; +import getCustomMedia from './lib/custom-media-from-root'; +import transformAtrules from './lib/transform-atrules'; +import importCustomMediaFromSources from './lib/import-from'; +import exportCustomMediaToDestinations from './lib/export-to'; -var EXTENSION_RE = /\(\s*(--[\w-]+)\s*\)/g +export default postcss.plugin('postcss-custom-media', opts => { + // whether to preserve custom selectors and rules using them + const preserve = Boolean(Object(opts).preserve); -/* - * Resolve custom media values. - */ -function resolveValue(query, depChain, map, result) { - if (!EXTENSION_RE.test(query.value)) { - return query.value - } - var val = query.value.replace(EXTENSION_RE, function(orig, name) { - if (!map[name]) { - return orig - } + // sources to import custom selectors from + const importFrom = [].concat(Object(opts).importFrom || []); - var mq = map[name] - if (mq.resolved) { - return mq.value - } + // destinations to export custom selectors to + const exportTo = [].concat(Object(opts).exportTo || []); - if (depChain.indexOf(name) !== -1) { - mq.circular = true - return orig - } - depChain.push(name) - mq.value = resolveValue(mq, depChain, map, result) - return mq.value - }) - if (val === query.value) { - query.circular = true - } - return val -} + // promise any custom selectors are imported + const customMediaPromise = importCustomMediaFromSources(importFrom); -/* - * read & replace custom media queries by standard media queries - */ -function customMedia(options) { - return function(styles, result) { - options = options || {} - var extensions = {} - if (options.extensions) { - Object.keys(options.extensions).forEach(function(name) { - var val = options.extensions[name] - if (name.slice(0, 2) !== "--") { - name = "--" + name - } - extensions[name] = val - }) - } - var appendExtensions = options.appendExtensions - var preserve = options.preserve - var map = {} - var toRemove = [] + return async root => { + const customMedia = Object.assign( + await customMediaPromise, + getCustomMedia(root, { preserve }) + ); - // read custom media queries - styles.walkAtRules(function(rule) { - if (rule.name !== "custom-media") { - return - } + await exportCustomMediaToDestinations(customMedia, exportTo); - var params = rule.params.split(" ") - // @custom-media ; - // map[] = - map[params.shift()] = { - value: params.join(" "), - circular: false, - resolved: false, - } - - if (!preserve) { - toRemove.push(rule) - } - }) - - // apply js-defined media queries - Object.keys(extensions).forEach(function(name) { - map[name] = { - value: extensions[name], - circular: false, - resolved: false, - } - }) - - Object.keys(map).forEach(function(name) { - map[name].value = resolveValue(map[name], [ name ], map, result) - map[name].resolved = true - }) - - // transform custom media query aliases - styles.walkAtRules(function(rule) { - if (rule.name !== "media") { - return - } - - rule.params = rule.params.replace(EXTENSION_RE, function(_, name) { - if (map[name]) { - if (map[name].circular) { - result.warn( - "Circular @custom-media definition for '" + name + - "'. The entire rule has been removed from the output.", - { node: rule } - ) - toRemove.push(rule) - } - return map[name].value - } - - result.warn( - "Missing @custom-media definition for '" + name + - "'. The entire rule has been removed from the output.", - { node: rule } - ) - toRemove.push(rule) - }) - }) - - if (appendExtensions) { - var names = Object.keys(map) - if (names.length) { - names.forEach(function(name) { - if (map[name].circular) { - return - } - var atRule = postcss.atRule({ - name: "custom-media", - params: name + " " + map[name].value, - raws: { - afterName: " ", - }, - }) - styles.append(atRule) - }) - styles.raws.semicolon = true - styles.raws.after = "\n" - } - } - - // remove @custom-media - toRemove.forEach(function(rule) { - rule.remove() - }) - } -} - -module.exports = postcss.plugin("postcss-custom-media", customMedia) + transformAtrules(root, customMedia, { preserve }); + }; +}); diff --git a/lib/custom-media-from-root.js b/lib/custom-media-from-root.js new file mode 100644 index 0000000000..ff4fb4d1bd --- /dev/null +++ b/lib/custom-media-from-root.js @@ -0,0 +1,34 @@ +import mediaASTFromString from './media-ast-from-string'; + +// return custom selectors from the css root, conditionally removing them +export default (root, opts) => { + // initialize custom selectors + const customMedias = {}; + + // for each custom selector atrule that is a child of the css root + root.nodes.slice().forEach(node => { + if (isCustomMedia(node)) { + // extract the name and selectors from the params of the custom selector + const [, name, selectors] = node.params.match(customMediaParamsRegExp); + + // write the parsed selectors to the custom selector + customMedias[name] = mediaASTFromString(selectors); + + // conditionally remove the custom selector atrule + if (!Object(opts).preserve) { + node.remove(); + } + } + }); + + return customMedias; +}; + +// match the custom selector name +const customMediaNameRegExp = /^custom-media$/i; + +// match the custom selector params +const customMediaParamsRegExp = /^(--[A-z][\w-]*)\s+([\W\w]+)\s*$/; + +// whether the atrule is a custom selector +const isCustomMedia = node => node.type === 'atrule' && customMediaNameRegExp.test(node.name) && customMediaParamsRegExp.test(node.params); diff --git a/lib/export-to.js b/lib/export-to.js new file mode 100644 index 0000000000..0059757db3 --- /dev/null +++ b/lib/export-to.js @@ -0,0 +1,129 @@ +import fs from 'fs'; +import path from 'path'; + +/* Import Custom Media from CSS File +/* ========================================================================== */ + +async function exportCustomMediaToCssFile(to, customMedia) { + const cssContent = Object.keys(customMedia).reduce((cssLines, name) => { + cssLines.push(`@custom-media ${name} ${customMedia[name]};`); + + return cssLines; + }, []).join('\n'); + const css = `${cssContent}\n`; + + await writeFile(to, css); +} + +/* Import Custom Media from JSON file +/* ========================================================================== */ + +async function exportCustomMediaToJsonFile(to, customMedia) { + const jsonContent = JSON.stringify({ + 'custom-media': customMedia + }, null, ' '); + const json = `${jsonContent}\n`; + + await writeFile(to, json); +} + +/* Import Custom Media from Common JS file +/* ========================================================================== */ + +async function exportCustomMediaToCjsFile(to, customMedia) { + const jsContents = Object.keys(customMedia).reduce((jsLines, name) => { + jsLines.push(`\t\t'${escapeForJS(name)}': '${escapeForJS(customMedia[name])}'`); + + return jsLines; + }, []).join(',\n'); + const js = `module.exports = {\n\tcustomMedia: {\n${jsContents}\n\t}\n};\n`; + + await writeFile(to, js); +} + +/* Import Custom Media from Module JS file +/* ========================================================================== */ + +async function exportCustomMediaToMjsFile(to, customMedia) { + const mjsContents = Object.keys(customMedia).reduce((mjsLines, name) => { + mjsLines.push(`\t'${escapeForJS(name)}': '${escapeForJS(customMedia[name])}'`); + + return mjsLines; + }, []).join(',\n'); + const mjs = `export const customMedia = {\n${mjsContents}\n};\n`; + + await writeFile(to, mjs); +} + +/* Export Custom Media to Destinations +/* ========================================================================== */ + +export default function exportCustomMediaToDestinations(customMedia, destinations) { + return Promise.all(destinations.map(async destination => { + if (destination instanceof Function) { + await destination(defaultCustomMediaToJSON(customMedia)); + } else { + // read the destination as an object + const opts = destination === Object(destination) ? destination : { to: String(destination) }; + + // transformer for custom media into a JSON-compatible object + const toJSON = opts.toJSON || defaultCustomMediaToJSON; + + if ('customMedia' in opts) { + // write directly to an object as customMedia + opts.customMedia = toJSON(customMedia); + } else if ('custom-media' in opts) { + // write directly to an object as custom-media + opts['custom-media'] = toJSON(customMedia); + } else { + // destination pathname + const to = String(opts.to || ''); + + // type of file being written to + const type = (opts.type || path.extname(opts.to).slice(1)).toLowerCase(); + + // transformed custom media + const customMediaJSON = toJSON(customMedia); + + if (type === 'css') { + await exportCustomMediaToCssFile(to, customMediaJSON); + } + + if (type === 'js') { + await exportCustomMediaToCjsFile(to, customMediaJSON); + } + + if (type === 'json') { + await exportCustomMediaToJsonFile(to, customMediaJSON); + } + + if (type === 'mjs') { + await exportCustomMediaToMjsFile(to, customMediaJSON); + } + } + } + })); +} + +/* Helper utilities +/* ========================================================================== */ + +const defaultCustomMediaToJSON = customMedia => { + return Object.keys(customMedia).reduce((customMediaJSON, key) => { + customMediaJSON[key] = String(customMedia[key]); + + return customMediaJSON; + }, {}); +}; + +const writeFile = (to, text) => new Promise((resolve, reject) => { + fs.writeFile(to, text, error => { + if (error) { + reject(error); + } else { + resolve(); + } + }); +}); + +const escapeForJS = string => string.replace(/\\([\s\S])|(')/g, '\\$1$2').replace(/\n/g, '\\n').replace(/\r/g, '\\r'); diff --git a/lib/import-from.js b/lib/import-from.js new file mode 100644 index 0000000000..41030d4f6a --- /dev/null +++ b/lib/import-from.js @@ -0,0 +1,120 @@ +import fs from 'fs'; +import path from 'path'; +import postcss from 'postcss'; +import getMediaAstFromMediaString from './media-ast-from-string'; +import getCustomMedia from './custom-media-from-root'; + +/* Import Custom Media from CSS AST +/* ========================================================================== */ + +function importCustomMediaFromCSSAST(root) { + return getCustomMedia(root); +} + +/* Import Custom Media from CSS File +/* ========================================================================== */ + +async function importCustomMediaFromCSSFile(from) { + const css = await readFile(path.resolve(from)); + const root = postcss.parse(css, { from: path.resolve(from) }); + + return importCustomMediaFromCSSAST(root); +} + +/* Import Custom Media from Object +/* ========================================================================== */ + +function importCustomMediaFromObject(object) { + const customMedia = Object.assign( + {}, + Object(object).customMedia || Object(object)['custom-media'] + ); + + for (const key in customMedia) { + customMedia[key] = getMediaAstFromMediaString(customMedia[key]); + } + + return customMedia; +} + +/* Import Custom Media from JSON file +/* ========================================================================== */ + +async function importCustomMediaFromJSONFile(from) { + const object = await readJSON(path.resolve(from)); + + return importCustomMediaFromObject(object); +} + +/* Import Custom Media from JS file +/* ========================================================================== */ + +async function importCustomMediaFromJSFile(from) { + const object = await import(path.resolve(from)); + + return importCustomMediaFromObject(object); +} + +/* Import Custom Media from Sources +/* ========================================================================== */ + +export default function importCustomMediaFromSources(sources) { + return sources.map(source => { + if (source instanceof Promise) { + return source; + } else if (source instanceof Function) { + return source(); + } + + // read the source as an object + const opts = source === Object(source) ? source : { from: String(source) }; + + // skip objects with custom media + if (Object(opts).customMedia || Object(opts)['custom-media']) { + return opts + } + + // source pathname + const from = String(opts.from || ''); + + // type of file being read from + const type = (opts.type || path.extname(opts.from).slice(1)).toLowerCase(); + + return { type, from }; + }).reduce(async (customMedia, source) => { + const { type, from } = await source; + + if (type === 'ast') { + return Object.assign(customMedia, importCustomMediaFromCSSAST(from)); + } + + if (type === 'css') { + return Object.assign(customMedia, await importCustomMediaFromCSSFile(from)); + } + + if (type === 'js') { + return Object.assign(customMedia, await importCustomMediaFromJSFile(from)); + } + + if (type === 'json') { + return Object.assign(customMedia, await importCustomMediaFromJSONFile(from)); + } + + return Object.assign(customMedia, importCustomMediaFromObject(await source)); + }, {}); +} + +/* Helper utilities +/* ========================================================================== */ + +const readFile = from => new Promise((resolve, reject) => { + fs.readFile(from, 'utf8', (error, result) => { + if (error) { + reject(error); + } else { + resolve(result); + } + }); +}); + +const readJSON = async from => JSON.parse(await readFile(from)); diff --git a/lib/media-ast-from-string.js b/lib/media-ast-from-string.js new file mode 100644 index 0000000000..38e3b6384d --- /dev/null +++ b/lib/media-ast-from-string.js @@ -0,0 +1,134 @@ +function parse(string, splitByAnd) { + const array = []; + let buffer = ''; + let split = false; + let func = 0; + let i = -1; + + while (++i < string.length) { + const char = string[i]; + + if (char === '(') { + func += 1; + } else if (char === ')') { + if (func > 0) { + func -= 1; + } + } else if (func === 0) { + if (splitByAnd && andRegExp.test(buffer + char)) { + split = true; + } else if (!splitByAnd && char === ',') { + split = true; + } + } + + if (split) { + array.push(splitByAnd ? new MediaExpression(buffer + char) : new MediaQuery(buffer)); + + buffer = ''; + split = false; + } else { + buffer += char + } + } + + if (buffer !== '') { + array.push(splitByAnd ? new MediaExpression(buffer) : new MediaQuery(buffer)); + } + + return array; +} + +class MediaQueryList { + constructor(string) { + this.nodes = parse(string); + } + + invert() { + this.nodes.forEach(node => { + node.invert(); + }) + + return this; + } + + clone() { + return new MediaQueryList(String(this)); + } + + toString() { + return this.nodes.join(','); + } +} + +class MediaQuery { + constructor(string) { + const [, before, media, after ] = string.match(spaceWrapRegExp); + const [, modifier = '', afterModifier = ' ', type = '', beforeAnd = '', and = '', beforeExpression = '', expression1 = '', expression2 = ''] = media.match(mediaRegExp) || []; + const raws = { before, after, afterModifier, originalModifier: modifier || 'not', beforeAnd, and, beforeExpression }; + const nodes = parse(expression1 || expression2, true); + + Object.assign(this, { + modifier, + type, + raws, + nodes + }); + } + + clone(overrides) { + const instance = new MediaQuery(String(this)); + + Object.assign(instance, overrides); + + return instance; + } + + invert() { + this.modifier = this.modifier ? '' : this.raws.originalModifier; + + return this; + } + + toString() { + const { raws } = this; + + return `${raws.before}${this.modifier}${this.modifier ? `${raws.afterModifier}` : ''}${this.type}${raws.beforeAnd}${raws.and}${raws.beforeExpression}${this.nodes.join('')}${this.raws.after}`; + } +} + +class MediaExpression { + constructor(string) { + const [, value, after = '', and = '', afterAnd = '' ] = string.match(andRegExp) || [null, string]; + const raws = { after, and, afterAnd }; + + Object.assign(this, { value, raws }); + } + + clone(overrides) { + const instance = new MediaExpression(String(this)); + + Object.assign(instance, overrides); + + return instance; + } + + toString() { + const { raws } = this; + + return `${this.value}${raws.after}${raws.and}${raws.afterAnd}`; + } +} + +const modifierRE = '(not|only)'; +const typeRE = '(all|print|screen|speech)'; +const noExpressionRE = '([\\W\\w]*)'; +const expressionRE = '([\\W\\w]+)'; +const noSpaceRE = '(\\s*)'; +const spaceRE = '(\\s+)'; +const andRE = '(?:(\\s+)(and))'; +const andRegExp = new RegExp(`^${expressionRE}(?:${andRE}${spaceRE})$`, 'i'); +const spaceWrapRegExp = new RegExp(`^${noSpaceRE}${noExpressionRE}${noSpaceRE}$`); +const mediaRegExp = new RegExp(`^(?:${modifierRE}${spaceRE})?(?:${typeRE}(?:${andRE}${spaceRE}${expressionRE})?|${expressionRE})$`, 'i'); + +export default string => new MediaQueryList(string); diff --git a/lib/transform-atrules.js b/lib/transform-atrules.js new file mode 100644 index 0000000000..74f54315a3 --- /dev/null +++ b/lib/transform-atrules.js @@ -0,0 +1,21 @@ +import transformParamsByCustomParams from './transform-params-by-custom-params'; +import mediaASTFromString from './media-ast-from-string'; + +// transform custom pseudo selectors with custom selectors +export default (root, customMedia, opts) => { + root.walkAtRules(mediaAtRuleRegExp, atrule => { + if (customPseudoRegExp.test(atrule.params)) { + const mediaAST = mediaASTFromString(atrule.params); + const params = transformParamsByCustomParams(mediaAST, customMedia, opts); + + if (opts.preserve) { + atrule.cloneBefore({ params }); + } else { + atrule.params = params; + } + } + }); +}; + +const mediaAtRuleRegExp = /^media$/i; +const customPseudoRegExp = /\(--[A-z][\w-]*\)/; diff --git a/lib/transform-params-by-custom-params.js b/lib/transform-params-by-custom-params.js new file mode 100644 index 0000000000..b9a6cf53dd --- /dev/null +++ b/lib/transform-params-by-custom-params.js @@ -0,0 +1,62 @@ +// return transformed medias, replacing custom pseudo medias with custom medias +export default function transformMediaList(mediaList, customMedias) { + let index = mediaList.nodes.length - 1; + + while (index >= 0) { + const transformedMedias = transformMedia(mediaList.nodes[index], customMedias); + + if (transformedMedias.length) { + mediaList.nodes.splice(index, 1, ...transformedMedias); + } + + --index; + } + + return mediaList; +} + +// return custom pseudo medias replaced with custom medias +function transformMedia(media, customMedias) { + const transpiledMedias = []; + + for (const index in media.nodes) { + const { value, nodes } = media.nodes[index]; + const key = value.replace(customPseudoRegExp, '$1'); + + if (key in customMedias) { + for (const replacementMedia of customMedias[key].nodes) { + const mediaClone = media.clone({ + modifier: replacementMedia.modifier === media.modifier && modifierRegExp.test(media.modifier) + ? '' + : replacementMedia.modifier + }); + + mediaClone.nodes.splice(index, 1, ...replacementMedia.clone().nodes.map(node => { + // use spacing from the current usage + node.spaces = { ...media.nodes[index].spaces }; + + return node; + })); + + const retranspiledMedias = String(mediaClone) === String(customMedias[key]) + ? [] + : transformMedia(mediaClone, customMedias); + + if (retranspiledMedias.length) { + transpiledMedias.push(...retranspiledMedias); + } else { + transpiledMedias.push(mediaClone); + } + } + + return transpiledMedias; + } else if (nodes && nodes.length) { + transformMediaList(media.nodes[index], customMedias); + } + } + + return transpiledMedias; +} + +const modifierRegExp = /^not$/i; +const customPseudoRegExp = /\((--[A-z][\w-]*)\)/; diff --git a/package-lock.json b/package-lock.json deleted file mode 100644 index 8330f0a5bd..0000000000 --- a/package-lock.json +++ /dev/null @@ -1,2035 +0,0 @@ -{ - "name": "postcss-custom-media", - "version": "6.0.0", - "lockfileVersion": 1, - "requires": true, - "dependencies": { - "@octokit/rest": { - "version": "14.0.9", - "resolved": "https://registry.npmjs.org/@octokit/rest/-/rest-14.0.9.tgz", - "integrity": "sha512-irP9phKfTXEZIcW2R+VNCtGHZJrXMWmSYp6RRfFn4BtAqtDRXF5z9JxCEQlAhNBf6X1koNi5k49tIAAAEJNlVQ==", - "dev": true, - "requires": { - "before-after-hook": "^1.1.0", - "debug": "^3.1.0", - "is-array-buffer": "^1.0.0", - "is-stream": "^1.1.0", - "lodash": "^4.17.4", - "url-template": "^2.0.8" - }, - "dependencies": { - "debug": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", - "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - } - } - }, - "@sindresorhus/df": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/@sindresorhus/df/-/df-2.1.0.tgz", - "integrity": "sha1-0gjPJ+BvC7R20U197M19cm6ao4k=", - "dev": true, - "requires": { - "execa": "^0.2.2" - } - }, - "acorn": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-5.7.1.tgz", - "integrity": "sha512-d+nbxBUGKg7Arpsvbnlq61mc12ek3EY8EQldM3GPAhWJ1UVxC6TDGbIvUMNU6obBX3i1+ptCIzV4vq0gFPEGVQ==", - "dev": true - }, - "acorn-jsx": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-3.0.1.tgz", - "integrity": "sha1-r9+UiPsezvyDSPb7IvRk4ypYs2s=", - "dev": true, - "requires": { - "acorn": "^3.0.4" - }, - "dependencies": { - "acorn": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-3.3.0.tgz", - "integrity": "sha1-ReN/s56No/JbruP/U2niu18iAXo=", - "dev": true - } - } - }, - "ajv": { - "version": "4.11.8", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-4.11.8.tgz", - "integrity": "sha1-gv+wKynmYq5TvcIK8VlHcGc5xTY=", - "dev": true, - "requires": { - "co": "^4.6.0", - "json-stable-stringify": "^1.0.1" - } - }, - "ajv-keywords": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-1.5.1.tgz", - "integrity": "sha1-MU3QpLM2j609/NxU7eYXG4htrzw=", - "dev": true - }, - "ansi-escapes": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-1.4.0.tgz", - "integrity": "sha1-06ioOzGapneTZisT52HHkRQiMG4=", - "dev": true - }, - "ansi-regex": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", - "dev": true - }, - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "requires": { - "color-convert": "^1.9.0" - } - }, - "argparse": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", - "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", - "dev": true, - "requires": { - "sprintf-js": "~1.0.2" - } - }, - "array-union": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/array-union/-/array-union-1.0.2.tgz", - "integrity": "sha1-mjRBDk9OPaI96jdb5b5w8kd47Dk=", - "dev": true, - "requires": { - "array-uniq": "^1.0.1" - } - }, - "array-uniq": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/array-uniq/-/array-uniq-1.0.3.tgz", - "integrity": "sha1-r2rId6Jcx/dOBYiUdThY39sk/bY=", - "dev": true - }, - "arrify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", - "integrity": "sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=", - "dev": true - }, - "babel-code-frame": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-code-frame/-/babel-code-frame-6.26.0.tgz", - "integrity": "sha1-Y/1D99weO7fONZR9uP42mj9Yx0s=", - "dev": true, - "requires": { - "chalk": "^1.1.3", - "esutils": "^2.0.2", - "js-tokens": "^3.0.2" - }, - "dependencies": { - "ansi-styles": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", - "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", - "dev": true - }, - "chalk": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", - "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", - "dev": true, - "requires": { - "ansi-styles": "^2.2.1", - "escape-string-regexp": "^1.0.2", - "has-ansi": "^2.0.0", - "strip-ansi": "^3.0.0", - "supports-color": "^2.0.0" - } - }, - "supports-color": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", - "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", - "dev": true - } - } - }, - "balanced-match": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", - "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", - "dev": true - }, - "before-after-hook": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/before-after-hook/-/before-after-hook-1.1.0.tgz", - "integrity": "sha512-VOMDtYPwLbIncTxNoSzRyvaMxtXmLWLUqr8k5AfC1BzLk34HvBXaQX8snOwQZ4c0aX8aSERqtJSiI9/m2u5kuA==", - "dev": true - }, - "brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, - "requires": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "buffer-from": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", - "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==", - "dev": true - }, - "builtin-modules": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-1.1.1.tgz", - "integrity": "sha1-Jw8HbFpywC9bZaR9+Uxf46J4iS8=", - "dev": true - }, - "caller-path": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/caller-path/-/caller-path-0.1.0.tgz", - "integrity": "sha1-lAhe9jWB7NPaqSREqP6U6CV3dR8=", - "dev": true, - "requires": { - "callsites": "^0.2.0" - } - }, - "callsites": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/callsites/-/callsites-0.2.0.tgz", - "integrity": "sha1-r6uWJikQp/M8GaV3WCXGnzTjUMo=", - "dev": true - }, - "chalk": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.1.tgz", - "integrity": "sha512-ObN6h1v2fTJSmUXoS3nMQ92LbDK9be4TV+6G+omQlGJFdcUX5heKi1LZ1YnRMIgwTLEj3E24bT6tYni50rlCfQ==", - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - } - }, - "checkup": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/checkup/-/checkup-1.3.0.tgz", - "integrity": "sha1-04ACdv6l0PJH/8lRvnjIsC+ODXY=", - "dev": true - }, - "circular-json": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/circular-json/-/circular-json-0.3.3.tgz", - "integrity": "sha512-UZK3NBx2Mca+b5LsG7bY183pHWt5Y1xts4P3Pz7ENTwGVnJOUWbRb3ocjvX7hx9tq/yTAdclXm9sZ38gNuem4A==", - "dev": true - }, - "cli-cursor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-1.0.2.tgz", - "integrity": "sha1-ZNo/fValRBLll5S9Ytw1KV6PKYc=", - "dev": true, - "requires": { - "restore-cursor": "^1.0.1" - } - }, - "cli-width": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-2.2.0.tgz", - "integrity": "sha1-/xnt6Kml5XkyQUewwR8PvLq+1jk=", - "dev": true - }, - "co": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", - "integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ=", - "dev": true - }, - "code-point-at": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", - "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=", - "dev": true - }, - "color-convert": { - "version": "1.9.2", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.2.tgz", - "integrity": "sha512-3NUJZdhMhcdPn8vJ9v2UQJoH0qqoGUkYTgFEPZaPjEtwmmKUfNV46zZmgB2M5M4DCEQHMaCfWHCxiBflLm04Tg==", - "requires": { - "color-name": "1.1.1" - } - }, - "color-name": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.1.tgz", - "integrity": "sha1-SxQVMEz1ACjqgWQ2Q72C6gWANok=" - }, - "concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", - "dev": true - }, - "concat-stream": { - "version": "1.6.2", - "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz", - "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==", - "dev": true, - "requires": { - "buffer-from": "^1.0.0", - "inherits": "^2.0.3", - "readable-stream": "^2.2.2", - "typedarray": "^0.0.6" - } - }, - "contains-path": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/contains-path/-/contains-path-0.1.0.tgz", - "integrity": "sha1-/ozxhP9mcLa67wGp1IYaXL7EEgo=", - "dev": true - }, - "core-util-is": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", - "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=", - "dev": true - }, - "cross-spawn-async": { - "version": "2.2.5", - "resolved": "https://registry.npmjs.org/cross-spawn-async/-/cross-spawn-async-2.2.5.tgz", - "integrity": "sha1-hF/wwINKPe2dFg2sptOQkGuyiMw=", - "dev": true, - "requires": { - "lru-cache": "^4.0.0", - "which": "^1.2.8" - } - }, - "d": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/d/-/d-1.0.0.tgz", - "integrity": "sha1-dUu1v+VUUdpppYuU1F9MWwRi1Y8=", - "dev": true, - "requires": { - "es5-ext": "^0.10.9" - } - }, - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "deep-equal": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/deep-equal/-/deep-equal-1.0.1.tgz", - "integrity": "sha1-9dJgKStmDghO/0zbyfCK0yR0SLU=", - "dev": true - }, - "deep-is": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz", - "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=", - "dev": true - }, - "define-properties": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.2.tgz", - "integrity": "sha1-g6c/L+pWmJj7c3GTyPhzyvbUXJQ=", - "dev": true, - "requires": { - "foreach": "^2.0.5", - "object-keys": "^1.0.8" - } - }, - "defined": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/defined/-/defined-1.0.0.tgz", - "integrity": "sha1-yY2bzvdWdBiOEQlpFRGZ45sfppM=", - "dev": true - }, - "del": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/del/-/del-2.2.2.tgz", - "integrity": "sha1-wSyYHQZ4RshLyvhiz/kw2Qf/0ag=", - "dev": true, - "requires": { - "globby": "^5.0.0", - "is-path-cwd": "^1.0.0", - "is-path-in-cwd": "^1.0.0", - "object-assign": "^4.0.1", - "pify": "^2.0.0", - "pinkie-promise": "^2.0.0", - "rimraf": "^2.2.8" - } - }, - "doctrine": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", - "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", - "dev": true, - "requires": { - "esutils": "^2.0.2" - } - }, - "es-abstract": { - "version": "1.12.0", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.12.0.tgz", - "integrity": "sha512-C8Fx/0jFmV5IPoMOFPA9P9G5NtqW+4cOPit3MIuvR2t7Ag2K15EJTpxnHAYTzL+aYQJIESYeXZmDBfOBE1HcpA==", - "dev": true, - "requires": { - "es-to-primitive": "^1.1.1", - "function-bind": "^1.1.1", - "has": "^1.0.1", - "is-callable": "^1.1.3", - "is-regex": "^1.0.4" - } - }, - "es-to-primitive": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.1.1.tgz", - "integrity": "sha1-RTVSSKiJeQNLZ5Lhm7gfK3l13Q0=", - "dev": true, - "requires": { - "is-callable": "^1.1.1", - "is-date-object": "^1.0.1", - "is-symbol": "^1.0.1" - } - }, - "es5-ext": { - "version": "0.10.45", - "resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.45.tgz", - "integrity": "sha512-FkfM6Vxxfmztilbxxz5UKSD4ICMf5tSpRFtDNtkAhOxZ0EKtX6qwmXNyH/sFyIbX2P/nU5AMiA9jilWsUGJzCQ==", - "dev": true, - "requires": { - "es6-iterator": "~2.0.3", - "es6-symbol": "~3.1.1", - "next-tick": "1" - } - }, - "es6-iterator": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/es6-iterator/-/es6-iterator-2.0.3.tgz", - "integrity": "sha1-p96IkUGgWpSwhUQDstCg+/qY87c=", - "dev": true, - "requires": { - "d": "1", - "es5-ext": "^0.10.35", - "es6-symbol": "^3.1.1" - } - }, - "es6-map": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/es6-map/-/es6-map-0.1.5.tgz", - "integrity": "sha1-kTbgUD3MBqMBaQ8LsU/042TpSfA=", - "dev": true, - "requires": { - "d": "1", - "es5-ext": "~0.10.14", - "es6-iterator": "~2.0.1", - "es6-set": "~0.1.5", - "es6-symbol": "~3.1.1", - "event-emitter": "~0.3.5" - } - }, - "es6-set": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/es6-set/-/es6-set-0.1.5.tgz", - "integrity": "sha1-0rPsXU2ADO2BjbU40ol02wpzzLE=", - "dev": true, - "requires": { - "d": "1", - "es5-ext": "~0.10.14", - "es6-iterator": "~2.0.1", - "es6-symbol": "3.1.1", - "event-emitter": "~0.3.5" - } - }, - "es6-symbol": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/es6-symbol/-/es6-symbol-3.1.1.tgz", - "integrity": "sha1-vwDvT9q2uhtG7Le2KbTH7VcVzHc=", - "dev": true, - "requires": { - "d": "1", - "es5-ext": "~0.10.14" - } - }, - "es6-weak-map": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/es6-weak-map/-/es6-weak-map-2.0.2.tgz", - "integrity": "sha1-XjqzIlH/0VOKH45f+hNXdy+S2W8=", - "dev": true, - "requires": { - "d": "1", - "es5-ext": "^0.10.14", - "es6-iterator": "^2.0.1", - "es6-symbol": "^3.1.1" - } - }, - "escape-string-applescript": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/escape-string-applescript/-/escape-string-applescript-1.0.0.tgz", - "integrity": "sha1-bxwilCRdgsY7wDM43BmpSqhCiJI=", - "dev": true - }, - "escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=" - }, - "escope": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/escope/-/escope-3.6.0.tgz", - "integrity": "sha1-4Bl16BJ4GhY6ba392AOY3GTIicM=", - "dev": true, - "requires": { - "es6-map": "^0.1.3", - "es6-weak-map": "^2.0.1", - "esrecurse": "^4.1.0", - "estraverse": "^4.1.1" - } - }, - "eslint": { - "version": "3.19.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-3.19.0.tgz", - "integrity": "sha1-yPxiAcf0DdCJQbh8CFdnOGpnmsw=", - "dev": true, - "requires": { - "babel-code-frame": "^6.16.0", - "chalk": "^1.1.3", - "concat-stream": "^1.5.2", - "debug": "^2.1.1", - "doctrine": "^2.0.0", - "escope": "^3.6.0", - "espree": "^3.4.0", - "esquery": "^1.0.0", - "estraverse": "^4.2.0", - "esutils": "^2.0.2", - "file-entry-cache": "^2.0.0", - "glob": "^7.0.3", - "globals": "^9.14.0", - "ignore": "^3.2.0", - "imurmurhash": "^0.1.4", - "inquirer": "^0.12.0", - "is-my-json-valid": "^2.10.0", - "is-resolvable": "^1.0.0", - "js-yaml": "^3.5.1", - "json-stable-stringify": "^1.0.0", - "levn": "^0.3.0", - "lodash": "^4.0.0", - "mkdirp": "^0.5.0", - "natural-compare": "^1.4.0", - "optionator": "^0.8.2", - "path-is-inside": "^1.0.1", - "pluralize": "^1.2.1", - "progress": "^1.1.8", - "require-uncached": "^1.0.2", - "shelljs": "^0.7.5", - "strip-bom": "^3.0.0", - "strip-json-comments": "~2.0.1", - "table": "^3.7.8", - "text-table": "~0.2.0", - "user-home": "^2.0.0" - }, - "dependencies": { - "ansi-styles": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", - "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", - "dev": true - }, - "chalk": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", - "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", - "dev": true, - "requires": { - "ansi-styles": "^2.2.1", - "escape-string-regexp": "^1.0.2", - "has-ansi": "^2.0.0", - "strip-ansi": "^3.0.0", - "supports-color": "^2.0.0" - } - }, - "supports-color": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", - "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", - "dev": true - } - } - }, - "eslint-config-i-am-meticulous": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/eslint-config-i-am-meticulous/-/eslint-config-i-am-meticulous-6.0.1.tgz", - "integrity": "sha1-M3/z/T/delhHp0fxejjY9spxfDk=", - "dev": true, - "requires": { - "eslint-plugin-import": "^1.7.0" - } - }, - "eslint-import-resolver-node": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.2.3.tgz", - "integrity": "sha1-Wt2BBujJKNssuiMrzZ76hG49oWw=", - "dev": true, - "requires": { - "debug": "^2.2.0", - "object-assign": "^4.0.1", - "resolve": "^1.1.6" - } - }, - "eslint-plugin-import": { - "version": "1.16.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-1.16.0.tgz", - "integrity": "sha1-svoH68xTUE0PKkR3WC7Iv/GHG58=", - "dev": true, - "requires": { - "builtin-modules": "^1.1.1", - "contains-path": "^0.1.0", - "debug": "^2.2.0", - "doctrine": "1.3.x", - "es6-map": "^0.1.3", - "es6-set": "^0.1.4", - "eslint-import-resolver-node": "^0.2.0", - "has": "^1.0.1", - "lodash.cond": "^4.3.0", - "lodash.endswith": "^4.0.1", - "lodash.find": "^4.3.0", - "lodash.findindex": "^4.3.0", - "minimatch": "^3.0.3", - "object-assign": "^4.0.1", - "pkg-dir": "^1.0.0", - "pkg-up": "^1.0.0" - }, - "dependencies": { - "doctrine": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-1.3.0.tgz", - "integrity": "sha1-E+dWgrVVGEJCdvfBc3g0Vu+RPSY=", - "dev": true, - "requires": { - "esutils": "^2.0.2", - "isarray": "^1.0.0" - } - } - } - }, - "espree": { - "version": "3.5.4", - "resolved": "https://registry.npmjs.org/espree/-/espree-3.5.4.tgz", - "integrity": "sha512-yAcIQxtmMiB/jL32dzEp2enBeidsB7xWPLNiw3IIkpVds1P+h7qF9YwJq1yUNzp2OKXgAprs4F61ih66UsoD1A==", - "dev": true, - "requires": { - "acorn": "^5.5.0", - "acorn-jsx": "^3.0.0" - } - }, - "esprima": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", - "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", - "dev": true - }, - "esquery": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.0.1.tgz", - "integrity": "sha512-SmiyZ5zIWH9VM+SRUReLS5Q8a7GxtRdxEBVZpm98rJM7Sb+A9DVCndXfkeFUd3byderg+EbDkfnevfCwynWaNA==", - "dev": true, - "requires": { - "estraverse": "^4.0.0" - } - }, - "esrecurse": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.2.1.tgz", - "integrity": "sha512-64RBB++fIOAXPw3P9cy89qfMlvZEXZkqqJkjqqXIvzP5ezRZjW+lPWjw35UX/3EhUPFYbg5ER4JYgDw4007/DQ==", - "dev": true, - "requires": { - "estraverse": "^4.1.0" - } - }, - "estraverse": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.2.0.tgz", - "integrity": "sha1-De4/7TH81GlhjOc0IJn8GvoL2xM=", - "dev": true - }, - "esutils": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.2.tgz", - "integrity": "sha1-Cr9PHKpbyx96nYrMbepPqqBLrJs=", - "dev": true - }, - "event-emitter": { - "version": "0.3.5", - "resolved": "https://registry.npmjs.org/event-emitter/-/event-emitter-0.3.5.tgz", - "integrity": "sha1-34xp7vFkeSPHFXuc6DhAYQsCzDk=", - "dev": true, - "requires": { - "d": "1", - "es5-ext": "~0.10.14" - } - }, - "execa": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/execa/-/execa-0.2.2.tgz", - "integrity": "sha1-4urUcsLDGq1vc/GslW7vReEjIMs=", - "dev": true, - "requires": { - "cross-spawn-async": "^2.1.1", - "npm-run-path": "^1.0.0", - "object-assign": "^4.0.1", - "path-key": "^1.0.0", - "strip-eof": "^1.0.0" - } - }, - "execon": { - "version": "1.2.9", - "resolved": "https://registry.npmjs.org/execon/-/execon-1.2.9.tgz", - "integrity": "sha1-bbETM9zIJPHxPnMX/tDZSi8mSR8=", - "dev": true - }, - "exit-hook": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/exit-hook/-/exit-hook-1.1.1.tgz", - "integrity": "sha1-8FyiM7SMBdVP/wd2XfhQfpXAL/g=", - "dev": true - }, - "fast-levenshtein": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", - "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", - "dev": true - }, - "figures": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/figures/-/figures-1.7.0.tgz", - "integrity": "sha1-y+Hjr/zxzUS4DK3+0o3Hk6lwHS4=", - "dev": true, - "requires": { - "escape-string-regexp": "^1.0.5", - "object-assign": "^4.1.0" - } - }, - "file-entry-cache": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-2.0.0.tgz", - "integrity": "sha1-w5KZDD5oR4PYOLjISkXYoEhFg2E=", - "dev": true, - "requires": { - "flat-cache": "^1.2.1", - "object-assign": "^4.0.1" - } - }, - "find-up": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-1.1.2.tgz", - "integrity": "sha1-ay6YIrGizgpgq2TWEOzK1TyyTQ8=", - "dev": true, - "requires": { - "path-exists": "^2.0.0", - "pinkie-promise": "^2.0.0" - } - }, - "flat-cache": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-1.3.0.tgz", - "integrity": "sha1-0wMLMrOBVPTjt+nHCfSQ9++XxIE=", - "dev": true, - "requires": { - "circular-json": "^0.3.1", - "del": "^2.0.2", - "graceful-fs": "^4.1.2", - "write": "^0.2.1" - } - }, - "for-each": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz", - "integrity": "sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==", - "dev": true, - "requires": { - "is-callable": "^1.1.3" - } - }, - "foreach": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/foreach/-/foreach-2.0.5.tgz", - "integrity": "sha1-C+4AUBiusmDQo6865ljdATbsG5k=", - "dev": true - }, - "fs-extra": { - "version": "0.26.7", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-0.26.7.tgz", - "integrity": "sha1-muH92UiXeY7at20JGM9C0MMYT6k=", - "dev": true, - "requires": { - "graceful-fs": "^4.1.2", - "jsonfile": "^2.1.0", - "klaw": "^1.0.0", - "path-is-absolute": "^1.0.0", - "rimraf": "^2.2.8" - } - }, - "fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", - "dev": true - }, - "function-bind": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", - "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", - "dev": true - }, - "generate-function": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/generate-function/-/generate-function-2.0.0.tgz", - "integrity": "sha1-aFj+fAlpt9TpCTM3ZHrHn2DfvnQ=", - "dev": true - }, - "generate-object-property": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/generate-object-property/-/generate-object-property-1.2.0.tgz", - "integrity": "sha1-nA4cQDCM6AT0eDYYuTf6iPmdUNA=", - "dev": true, - "requires": { - "is-property": "^1.0.0" - } - }, - "github-release-from-changelog": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/github-release-from-changelog/-/github-release-from-changelog-1.3.2.tgz", - "integrity": "sha512-3Cj5zazWfk9heJzBSXxBsh9xQSYt8ZOseresfNeHewFVC2g0Au9181xob9eXTv4hRysi9k3gRVCXOUmBH+J2bA==", - "dev": true, - "requires": { - "grizzly": "^3.0.3", - "minimist": "^1.2.0" - }, - "dependencies": { - "minimist": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", - "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", - "dev": true - } - } - }, - "glob": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz", - "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "globals": { - "version": "9.18.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-9.18.0.tgz", - "integrity": "sha512-S0nG3CLEQiY/ILxqtztTWH/3iRRdyBLw6KMDxnKMchrtbj2OFmehVh0WUCfW3DUrIgx/qFrJPICrq4Z4sTR9UQ==", - "dev": true - }, - "globby": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/globby/-/globby-5.0.0.tgz", - "integrity": "sha1-69hGZ8oNuzMLmbz8aOrCvFQ3Dg0=", - "dev": true, - "requires": { - "array-union": "^1.0.1", - "arrify": "^1.0.0", - "glob": "^7.0.3", - "object-assign": "^4.0.1", - "pify": "^2.0.0", - "pinkie-promise": "^2.0.0" - } - }, - "graceful-fs": { - "version": "4.1.11", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.11.tgz", - "integrity": "sha1-Dovf5NHduIVNZOBOp8AOKgJuVlg=", - "dev": true - }, - "grizzly": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/grizzly/-/grizzly-3.0.3.tgz", - "integrity": "sha512-IGcSYOg8W75e1/92oHy1RgO4fiWxWYi94C5nwjJwTe5usRx241LkqiO4923LVLwkon7ro69ZKcCbI4ox25pDOw==", - "dev": true, - "requires": { - "@octokit/rest": "^14.0.7", - "checkup": "^1.3.0", - "debug": "^3.0.0", - "execon": "^1.2.0", - "minimist": "^1.2.0", - "readjson": "^1.1.0" - }, - "dependencies": { - "debug": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", - "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "minimist": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", - "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", - "dev": true - } - } - }, - "has": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", - "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", - "dev": true, - "requires": { - "function-bind": "^1.1.1" - } - }, - "has-ansi": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", - "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=", - "dev": true, - "requires": { - "ansi-regex": "^2.0.0" - } - }, - "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=" - }, - "ignore": { - "version": "3.3.10", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-3.3.10.tgz", - "integrity": "sha512-Pgs951kaMm5GXP7MOvxERINe3gsaVjUWFm+UZPSq9xYriQAksyhg0csnS0KXSNRD5NmNdapXEpjxG49+AKh/ug==", - "dev": true - }, - "imurmurhash": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", - "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", - "dev": true - }, - "inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", - "dev": true, - "requires": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "inherits": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", - "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", - "dev": true - }, - "inquirer": { - "version": "0.12.0", - "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-0.12.0.tgz", - "integrity": "sha1-HvK/1jUE3wvHV4X/+MLEHfEvB34=", - "dev": true, - "requires": { - "ansi-escapes": "^1.1.0", - "ansi-regex": "^2.0.0", - "chalk": "^1.0.0", - "cli-cursor": "^1.0.1", - "cli-width": "^2.0.0", - "figures": "^1.3.5", - "lodash": "^4.3.0", - "readline2": "^1.0.1", - "run-async": "^0.1.0", - "rx-lite": "^3.1.2", - "string-width": "^1.0.1", - "strip-ansi": "^3.0.0", - "through": "^2.3.6" - }, - "dependencies": { - "ansi-styles": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", - "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", - "dev": true - }, - "chalk": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", - "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", - "dev": true, - "requires": { - "ansi-styles": "^2.2.1", - "escape-string-regexp": "^1.0.2", - "has-ansi": "^2.0.0", - "strip-ansi": "^3.0.0", - "supports-color": "^2.0.0" - } - }, - "supports-color": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", - "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", - "dev": true - } - } - }, - "interpret": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.1.0.tgz", - "integrity": "sha1-ftGxQQxqDg94z5XTuEQMY/eLhhQ=", - "dev": true - }, - "is-array-buffer": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-1.0.1.tgz", - "integrity": "sha512-lj035IqdAwsodoRGs9/8+Kn3HPoz9CTuZbcw63afugWonxigvUVeHY5d6Ve1O+s1N3RCk7txo2TIWQLbU0SuNA==", - "dev": true - }, - "is-callable": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.1.4.tgz", - "integrity": "sha512-r5p9sxJjYnArLjObpjA4xu5EKI3CuKHkJXMhT7kwbpUyIFD1n5PMAsoPvWnvtZiNz7LjkYDRZhd7FlI0eMijEA==", - "dev": true - }, - "is-date-object": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.1.tgz", - "integrity": "sha1-mqIOtq7rv/d/vTPnTKAbM1gdOhY=", - "dev": true - }, - "is-fullwidth-code-point": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", - "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", - "dev": true, - "requires": { - "number-is-nan": "^1.0.0" - } - }, - "is-my-ip-valid": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-my-ip-valid/-/is-my-ip-valid-1.0.0.tgz", - "integrity": "sha512-gmh/eWXROncUzRnIa1Ubrt5b8ep/MGSnfAUI3aRp+sqTCs1tv1Isl8d8F6JmkN3dXKc3ehZMrtiPN9eL03NuaQ==", - "dev": true - }, - "is-my-json-valid": { - "version": "2.18.0", - "resolved": "https://registry.npmjs.org/is-my-json-valid/-/is-my-json-valid-2.18.0.tgz", - "integrity": "sha512-DWT87JHCSdCPCxbqBpS6Z2ajAt+MvrJq8I4xrpQljCvzODO5/fiquBp20a3sN6yCJvFbCRyYvJOHjpzkPTKJyA==", - "dev": true, - "requires": { - "generate-function": "^2.0.0", - "generate-object-property": "^1.1.0", - "is-my-ip-valid": "^1.0.0", - "jsonpointer": "^4.0.0", - "xtend": "^4.0.0" - } - }, - "is-path-cwd": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-path-cwd/-/is-path-cwd-1.0.0.tgz", - "integrity": "sha1-0iXsIxMuie3Tj9p2dHLmLmXxEG0=", - "dev": true - }, - "is-path-in-cwd": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-path-in-cwd/-/is-path-in-cwd-1.0.1.tgz", - "integrity": "sha512-FjV1RTW48E7CWM7eE/J2NJvAEEVektecDBVBE5Hh3nM1Jd0kvhHtX68Pr3xsDf857xt3Y4AkwVULK1Vku62aaQ==", - "dev": true, - "requires": { - "is-path-inside": "^1.0.0" - } - }, - "is-path-inside": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-1.0.1.tgz", - "integrity": "sha1-jvW33lBDej/cprToZe96pVy0gDY=", - "dev": true, - "requires": { - "path-is-inside": "^1.0.1" - } - }, - "is-property": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-property/-/is-property-1.0.2.tgz", - "integrity": "sha1-V/4cTkhHTt1lsJkR8msc1Ald2oQ=", - "dev": true - }, - "is-regex": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.0.4.tgz", - "integrity": "sha1-VRdIm1RwkbCTDglWVM7SXul+lJE=", - "dev": true, - "requires": { - "has": "^1.0.1" - } - }, - "is-resolvable": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-resolvable/-/is-resolvable-1.1.0.tgz", - "integrity": "sha512-qgDYXFSR5WvEfuS5dMj6oTMEbrrSaM0CrFk2Yiq/gXnBvD9pMa2jGXxyhGLfvhZpuMZe18CJpFxAt3CRs42NMg==", - "dev": true - }, - "is-stream": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", - "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=", - "dev": true - }, - "is-symbol": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.1.tgz", - "integrity": "sha1-PMWfAAJRlLarLjjbrmaJJWtmBXI=", - "dev": true - }, - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", - "dev": true - }, - "isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", - "dev": true - }, - "js-tokens": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-3.0.2.tgz", - "integrity": "sha1-mGbfOVECEw449/mWvOtlRDIJwls=", - "dev": true - }, - "js-yaml": { - "version": "3.12.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.12.0.tgz", - "integrity": "sha512-PIt2cnwmPfL4hKNwqeiuz4bKfnzHTBv6HyVgjahA6mPLwPDzjDWrplJBMjHUFxku/N3FlmrbyPclad+I+4mJ3A==", - "dev": true, - "requires": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" - } - }, - "json-stable-stringify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json-stable-stringify/-/json-stable-stringify-1.0.1.tgz", - "integrity": "sha1-mnWdOcXy/1A/1TAGRu1EX4jE+a8=", - "dev": true, - "requires": { - "jsonify": "~0.0.0" - } - }, - "jsonfile": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-2.4.0.tgz", - "integrity": "sha1-NzaitCi4e72gzIO1P6PWM6NcKug=", - "dev": true, - "requires": { - "graceful-fs": "^4.1.6" - } - }, - "jsonify": { - "version": "0.0.0", - "resolved": "https://registry.npmjs.org/jsonify/-/jsonify-0.0.0.tgz", - "integrity": "sha1-LHS27kHZPKUbe1qu6PUDYx0lKnM=", - "dev": true - }, - "jsonpointer": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/jsonpointer/-/jsonpointer-4.0.1.tgz", - "integrity": "sha1-T9kss04OnbPInIYi7PUfm5eMbLk=", - "dev": true - }, - "klaw": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/klaw/-/klaw-1.3.1.tgz", - "integrity": "sha1-QIhDO0azsbolnXh4XY6W9zugJDk=", - "dev": true, - "requires": { - "graceful-fs": "^4.1.9" - } - }, - "levn": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", - "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=", - "dev": true, - "requires": { - "prelude-ls": "~1.1.2", - "type-check": "~0.3.2" - } - }, - "lodash": { - "version": "4.17.10", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.10.tgz", - "integrity": "sha512-UejweD1pDoXu+AD825lWwp4ZGtSwgnpZxb3JDViD7StjQz+Nb/6l093lx4OQ0foGWNRoc19mWy7BzL+UAK2iVg==", - "dev": true - }, - "lodash.cond": { - "version": "4.5.2", - "resolved": "https://registry.npmjs.org/lodash.cond/-/lodash.cond-4.5.2.tgz", - "integrity": "sha1-9HGh2khr5g9quVXRcRVSPdHSVdU=", - "dev": true - }, - "lodash.endswith": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/lodash.endswith/-/lodash.endswith-4.2.1.tgz", - "integrity": "sha1-/tWawXOO0+I27dcGTsRWRIs3vAk=", - "dev": true - }, - "lodash.find": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/lodash.find/-/lodash.find-4.6.0.tgz", - "integrity": "sha1-ywcE1Hq3F4n/oN6Ll92Sb7iLE7E=", - "dev": true - }, - "lodash.findindex": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/lodash.findindex/-/lodash.findindex-4.6.0.tgz", - "integrity": "sha1-oyRd7mH7m24GJLU1ElYku2nBEQY=", - "dev": true - }, - "lru-cache": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.3.tgz", - "integrity": "sha512-fFEhvcgzuIoJVUF8fYr5KR0YqxD238zgObTps31YdADwPPAp82a4M8TrckkWyx7ekNlf9aBcVn81cFwwXngrJA==", - "dev": true, - "requires": { - "pseudomap": "^1.0.2", - "yallist": "^2.1.2" - } - }, - "minimatch": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", - "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", - "dev": true, - "requires": { - "brace-expansion": "^1.1.7" - } - }, - "minimist": { - "version": "0.0.8", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", - "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=", - "dev": true - }, - "mkdirp": { - "version": "0.5.1", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", - "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", - "dev": true, - "requires": { - "minimist": "0.0.8" - } - }, - "mount-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/mount-point/-/mount-point-3.0.0.tgz", - "integrity": "sha1-Zly57evoDREOZY21bDHQrvUaj5c=", - "dev": true, - "requires": { - "@sindresorhus/df": "^1.0.1", - "pify": "^2.3.0", - "pinkie-promise": "^2.0.1" - }, - "dependencies": { - "@sindresorhus/df": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@sindresorhus/df/-/df-1.0.1.tgz", - "integrity": "sha1-xptm9S9vzdKHyAffIQMF2694UA0=", - "dev": true - } - } - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", - "dev": true - }, - "mute-stream": { - "version": "0.0.5", - "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.5.tgz", - "integrity": "sha1-j7+rsKmKJT0xhDMfno3rc3L6xsA=", - "dev": true - }, - "natural-compare": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", - "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=", - "dev": true - }, - "next-tick": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/next-tick/-/next-tick-1.0.0.tgz", - "integrity": "sha1-yobR/ogoFpsBICCOPchCS524NCw=", - "dev": true - }, - "npm-run-path": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-1.0.0.tgz", - "integrity": "sha1-9cMr9ZX+ga6Sfa7FLoL4sACsPI8=", - "dev": true, - "requires": { - "path-key": "^1.0.0" - } - }, - "npmpub": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/npmpub/-/npmpub-3.1.0.tgz", - "integrity": "sha1-c0OoAf+xi/0s7CM1hLkUWa5O4Uk=", - "dev": true, - "requires": { - "chalk": "^1.1.1", - "github-release-from-changelog": "^1.1.1", - "minimist": "^1.2.0", - "shelljs": "^0.5.3", - "trash": "^3.4.1" - }, - "dependencies": { - "ansi-styles": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", - "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", - "dev": true - }, - "chalk": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", - "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", - "dev": true, - "requires": { - "ansi-styles": "^2.2.1", - "escape-string-regexp": "^1.0.2", - "has-ansi": "^2.0.0", - "strip-ansi": "^3.0.0", - "supports-color": "^2.0.0" - } - }, - "minimist": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", - "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", - "dev": true - }, - "shelljs": { - "version": "0.5.3", - "resolved": "https://registry.npmjs.org/shelljs/-/shelljs-0.5.3.tgz", - "integrity": "sha1-xUmCuZbHbvDB5rWfvcWCX1txMRM=", - "dev": true - }, - "supports-color": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", - "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", - "dev": true - } - } - }, - "number-is-nan": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", - "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=", - "dev": true - }, - "object-assign": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", - "dev": true - }, - "object-inspect": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.6.0.tgz", - "integrity": "sha512-GJzfBZ6DgDAmnuaM3104jR4s1Myxr3Y3zfIyN4z3UdqN69oSRacNK8UhnobDdC+7J2AHCjGwxQubNJfE70SXXQ==", - "dev": true - }, - "object-keys": { - "version": "1.0.12", - "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.0.12.tgz", - "integrity": "sha512-FTMyFUm2wBcGHnH2eXmz7tC6IwlqQZ6mVZ+6dm6vZ4IQIHjs6FdNsQBuKGPuUUUY6NfJw2PshC08Tn6LzLDOag==", - "dev": true - }, - "once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", - "dev": true, - "requires": { - "wrappy": "1" - } - }, - "onetime": { - "version": "1.1.0", - "resolved": "http://registry.npmjs.org/onetime/-/onetime-1.1.0.tgz", - "integrity": "sha1-ofeDj4MUxRbwXs78vEzP4EtO14k=", - "dev": true - }, - "optionator": { - "version": "0.8.2", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.2.tgz", - "integrity": "sha1-NkxeQJ0/TWMB1sC0wFu6UBgK62Q=", - "dev": true, - "requires": { - "deep-is": "~0.1.3", - "fast-levenshtein": "~2.0.4", - "levn": "~0.3.0", - "prelude-ls": "~1.1.2", - "type-check": "~0.3.2", - "wordwrap": "~1.0.0" - } - }, - "os-homedir": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz", - "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=", - "dev": true - }, - "path-exists": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-2.1.0.tgz", - "integrity": "sha1-D+tsZPD8UY2adU3V77YscCJ2H0s=", - "dev": true, - "requires": { - "pinkie-promise": "^2.0.0" - } - }, - "path-is-absolute": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", - "dev": true - }, - "path-is-inside": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz", - "integrity": "sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM=", - "dev": true - }, - "path-key": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-1.0.0.tgz", - "integrity": "sha1-XVPVeAGWRsDWiADbThRua9wqx68=", - "dev": true - }, - "path-parse": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz", - "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==", - "dev": true - }, - "pify": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", - "dev": true - }, - "pinkie": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz", - "integrity": "sha1-clVrgM+g1IqXToDnckjoDtT3+HA=", - "dev": true - }, - "pinkie-promise": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz", - "integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=", - "dev": true, - "requires": { - "pinkie": "^2.0.0" - } - }, - "pkg-dir": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-1.0.0.tgz", - "integrity": "sha1-ektQio1bstYp1EcFb/TpyTFM89Q=", - "dev": true, - "requires": { - "find-up": "^1.0.0" - } - }, - "pkg-up": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/pkg-up/-/pkg-up-1.0.0.tgz", - "integrity": "sha1-Pgj7RhUlxEIWJKM7n35tCvWwWiY=", - "dev": true, - "requires": { - "find-up": "^1.0.0" - } - }, - "pluralize": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/pluralize/-/pluralize-1.2.1.tgz", - "integrity": "sha1-0aIUg/0iu0HlihL6NCGCMUCJfEU=", - "dev": true - }, - "postcss": { - "version": "7.0.2", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.2.tgz", - "integrity": "sha512-fmaUY5370keLUTx+CnwRxtGiuFTcNBLQBqr1oE3WZ/euIYmGAo0OAgOhVJ3ByDnVmOR3PK+0V9VebzfjRIUcqw==", - "requires": { - "chalk": "^2.4.1", - "source-map": "^0.6.1", - "supports-color": "^5.4.0" - } - }, - "prelude-ls": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", - "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=", - "dev": true - }, - "process-nextick-args": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.0.tgz", - "integrity": "sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw==", - "dev": true - }, - "progress": { - "version": "1.1.8", - "resolved": "https://registry.npmjs.org/progress/-/progress-1.1.8.tgz", - "integrity": "sha1-4mDHj2Fhzdmw5WzD4Khd4Xx6V74=", - "dev": true - }, - "pseudomap": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", - "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=", - "dev": true - }, - "readable-stream": { - "version": "2.3.6", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", - "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "readjson": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/readjson/-/readjson-1.1.4.tgz", - "integrity": "sha512-H4dRk2S67w3HtE1apnw5wlHpN9qkJ0pen0AcEvyAfnrPfskZIyUOYLXpfN6olDQZI+eUlxg0Yo4lJ2bymujOUA==", - "dev": true, - "requires": { - "try-catch": "^2.0.0" - } - }, - "readline2": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/readline2/-/readline2-1.0.1.tgz", - "integrity": "sha1-QQWWCP/BVHV7cV2ZidGZ/783LjU=", - "dev": true, - "requires": { - "code-point-at": "^1.0.0", - "is-fullwidth-code-point": "^1.0.0", - "mute-stream": "0.0.5" - } - }, - "rechoir": { - "version": "0.6.2", - "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.6.2.tgz", - "integrity": "sha1-hSBLVNuoLVdC4oyWdW70OvUOM4Q=", - "dev": true, - "requires": { - "resolve": "^1.1.6" - } - }, - "require-uncached": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/require-uncached/-/require-uncached-1.0.3.tgz", - "integrity": "sha1-Tg1W1slmL9MeQwEcS5WqSZVUIdM=", - "dev": true, - "requires": { - "caller-path": "^0.1.0", - "resolve-from": "^1.0.0" - } - }, - "resolve": { - "version": "1.8.1", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.8.1.tgz", - "integrity": "sha512-AicPrAC7Qu1JxPCZ9ZgCZlY35QgFnNqc+0LtbRNxnVw4TXvjQ72wnuL9JQcEBgXkI9JM8MsT9kaQoHcpCRJOYA==", - "dev": true, - "requires": { - "path-parse": "^1.0.5" - } - }, - "resolve-from": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-1.0.1.tgz", - "integrity": "sha1-Jsv+k10a7uq7Kbw/5a6wHpPUQiY=", - "dev": true - }, - "restore-cursor": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-1.0.1.tgz", - "integrity": "sha1-NGYfRohjJ/7SmRR5FSJS35LapUE=", - "dev": true, - "requires": { - "exit-hook": "^1.0.0", - "onetime": "^1.0.0" - } - }, - "resumer": { - "version": "0.0.0", - "resolved": "https://registry.npmjs.org/resumer/-/resumer-0.0.0.tgz", - "integrity": "sha1-8ej0YeQGS6Oegq883CqMiT0HZ1k=", - "dev": true, - "requires": { - "through": "~2.3.4" - } - }, - "rimraf": { - "version": "2.6.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.2.tgz", - "integrity": "sha512-lreewLK/BlghmxtfH36YYVg1i8IAce4TI7oao75I1g245+6BctqTVQiBP3YUJ9C6DQOXJmkYR9X9fCLtCOJc5w==", - "dev": true, - "requires": { - "glob": "^7.0.5" - } - }, - "run-applescript": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/run-applescript/-/run-applescript-2.1.0.tgz", - "integrity": "sha1-O/8sz5W2zqy0lyPlUPADcdYYUQ0=", - "dev": true, - "requires": { - "pify": "^2.2.0", - "pinkie-promise": "^2.0.0" - } - }, - "run-async": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/run-async/-/run-async-0.1.0.tgz", - "integrity": "sha1-yK1KXhEGYeQCp9IbUw4AnyX444k=", - "dev": true, - "requires": { - "once": "^1.3.0" - } - }, - "rx-lite": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/rx-lite/-/rx-lite-3.1.2.tgz", - "integrity": "sha1-Gc5QLKVyZl87ZHsQk5+X/RYV8QI=", - "dev": true - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "shelljs": { - "version": "0.7.8", - "resolved": "https://registry.npmjs.org/shelljs/-/shelljs-0.7.8.tgz", - "integrity": "sha1-3svPh0sNHl+3LhSxZKloMEjprLM=", - "dev": true, - "requires": { - "glob": "^7.0.0", - "interpret": "^1.0.0", - "rechoir": "^0.6.2" - } - }, - "slice-ansi": { - "version": "0.0.4", - "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-0.0.4.tgz", - "integrity": "sha1-7b+JA/ZvfOL46v1s7tZeJkyDGzU=", - "dev": true - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" - }, - "sprintf-js": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", - "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", - "dev": true - }, - "string-width": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", - "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", - "dev": true, - "requires": { - "code-point-at": "^1.0.0", - "is-fullwidth-code-point": "^1.0.0", - "strip-ansi": "^3.0.0" - } - }, - "string.prototype.trim": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.1.2.tgz", - "integrity": "sha1-0E3iyJ4Tf019IG8Ia17S+ua+jOo=", - "dev": true, - "requires": { - "define-properties": "^1.1.2", - "es-abstract": "^1.5.0", - "function-bind": "^1.0.2" - } - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - }, - "strip-ansi": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", - "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", - "dev": true, - "requires": { - "ansi-regex": "^2.0.0" - } - }, - "strip-bom": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", - "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", - "dev": true - }, - "strip-eof": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz", - "integrity": "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8=", - "dev": true - }, - "strip-json-comments": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", - "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=", - "dev": true - }, - "supports-color": { - "version": "5.4.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.4.0.tgz", - "integrity": "sha512-zjaXglF5nnWpsq470jSv6P9DwPvgLkuapYmfDm3JWOm0vkNTVF2tI4UrN2r6jH1qM/uc/WtxYY1hYoA2dOKj5w==", - "requires": { - "has-flag": "^3.0.0" - } - }, - "table": { - "version": "3.8.3", - "resolved": "https://registry.npmjs.org/table/-/table-3.8.3.tgz", - "integrity": "sha1-K7xULw/amGGnVdOUf+/Ys/UThV8=", - "dev": true, - "requires": { - "ajv": "^4.7.0", - "ajv-keywords": "^1.0.0", - "chalk": "^1.1.1", - "lodash": "^4.0.0", - "slice-ansi": "0.0.4", - "string-width": "^2.0.0" - }, - "dependencies": { - "ansi-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", - "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", - "dev": true - }, - "ansi-styles": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", - "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", - "dev": true - }, - "chalk": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", - "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", - "dev": true, - "requires": { - "ansi-styles": "^2.2.1", - "escape-string-regexp": "^1.0.2", - "has-ansi": "^2.0.0", - "strip-ansi": "^3.0.0", - "supports-color": "^2.0.0" - } - }, - "is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", - "dev": true - }, - "string-width": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", - "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", - "dev": true, - "requires": { - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^4.0.0" - }, - "dependencies": { - "strip-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", - "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", - "dev": true, - "requires": { - "ansi-regex": "^3.0.0" - } - } - } - }, - "supports-color": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", - "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", - "dev": true - } - } - }, - "tape": { - "version": "4.9.1", - "resolved": "https://registry.npmjs.org/tape/-/tape-4.9.1.tgz", - "integrity": "sha512-6fKIXknLpoe/Jp4rzHKFPpJUHDHDqn8jus99IfPnHIjyz78HYlefTGD3b5EkbQzuLfaEvmfPK3IolLgq2xT3kw==", - "dev": true, - "requires": { - "deep-equal": "~1.0.1", - "defined": "~1.0.0", - "for-each": "~0.3.3", - "function-bind": "~1.1.1", - "glob": "~7.1.2", - "has": "~1.0.3", - "inherits": "~2.0.3", - "minimist": "~1.2.0", - "object-inspect": "~1.6.0", - "resolve": "~1.7.1", - "resumer": "~0.0.0", - "string.prototype.trim": "~1.1.2", - "through": "~2.3.8" - }, - "dependencies": { - "minimist": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", - "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", - "dev": true - }, - "resolve": { - "version": "1.7.1", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.7.1.tgz", - "integrity": "sha512-c7rwLofp8g1U+h1KNyHL/jicrKg1Ek4q+Lr33AL65uZTinUZHe30D5HlyN5V9NW0JX1D5dXQ4jqW5l7Sy/kGfw==", - "dev": true, - "requires": { - "path-parse": "^1.0.5" - } - } - } - }, - "text-table": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", - "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=", - "dev": true - }, - "through": { - "version": "2.3.8", - "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", - "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=", - "dev": true - }, - "trash": { - "version": "3.4.2", - "resolved": "https://registry.npmjs.org/trash/-/trash-3.4.2.tgz", - "integrity": "sha1-+wQiUvwmoCInaVCiuw7Om5QF6xk=", - "dev": true, - "requires": { - "escape-string-applescript": "^1.0.0", - "fs-extra": "^0.26.2", - "globby": "^4.0.0", - "path-exists": "^2.0.0", - "pify": "^2.3.0", - "pinkie-promise": "^2.0.0", - "run-applescript": "^2.0.0", - "uuid": "^2.0.1", - "xdg-trashdir": "^2.0.0" - }, - "dependencies": { - "glob": { - "version": "6.0.4", - "resolved": "https://registry.npmjs.org/glob/-/glob-6.0.4.tgz", - "integrity": "sha1-DwiGD2oVUSey+t1PnOJLGqtuTSI=", - "dev": true, - "requires": { - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "2 || 3", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "globby": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/globby/-/globby-4.1.0.tgz", - "integrity": "sha1-CA9UVJ7BuCpsYOYx/ILhIR2+lfg=", - "dev": true, - "requires": { - "array-union": "^1.0.1", - "arrify": "^1.0.0", - "glob": "^6.0.1", - "object-assign": "^4.0.1", - "pify": "^2.0.0", - "pinkie-promise": "^2.0.0" - } - } - } - }, - "try-catch": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/try-catch/-/try-catch-2.0.0.tgz", - "integrity": "sha512-RPXpVjsbtWgymwGq5F/OWDFsjEzdvzwHFaMjWWW6f/p6+uk/N7YSKJHQfIfGqITfj8qH4cBqCLMnhKZBaKk7Kg==", - "dev": true - }, - "type-check": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", - "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=", - "dev": true, - "requires": { - "prelude-ls": "~1.1.2" - } - }, - "typedarray": { - "version": "0.0.6", - "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", - "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=", - "dev": true - }, - "url-template": { - "version": "2.0.8", - "resolved": "https://registry.npmjs.org/url-template/-/url-template-2.0.8.tgz", - "integrity": "sha1-/FZaPMy/93MMd19WQflVV5FDnyE=", - "dev": true - }, - "user-home": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/user-home/-/user-home-2.0.0.tgz", - "integrity": "sha1-nHC/2Babwdy/SGBODwS4tJzenp8=", - "dev": true, - "requires": { - "os-homedir": "^1.0.0" - } - }, - "util-deprecate": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=", - "dev": true - }, - "uuid": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-2.0.3.tgz", - "integrity": "sha1-Z+LoY3lyFVMN/zGOW/nc6/1Hsho=", - "dev": true - }, - "which": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", - "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", - "dev": true, - "requires": { - "isexe": "^2.0.0" - } - }, - "wordwrap": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", - "integrity": "sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus=", - "dev": true - }, - "wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", - "dev": true - }, - "write": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/write/-/write-0.2.1.tgz", - "integrity": "sha1-X8A4KOJkzqP+kUVUdvejxWbLB1c=", - "dev": true, - "requires": { - "mkdirp": "^0.5.1" - } - }, - "xdg-basedir": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/xdg-basedir/-/xdg-basedir-2.0.0.tgz", - "integrity": "sha1-7byQPMOF/ARSPZZqM1UEtVBNG9I=", - "dev": true, - "requires": { - "os-homedir": "^1.0.0" - } - }, - "xdg-trashdir": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/xdg-trashdir/-/xdg-trashdir-2.1.1.tgz", - "integrity": "sha512-KcVhPaOu2ZurYNHSRTf1+ZHORkTZGCQ+u0JHN17QixRISJq4pXOnjt/lQcehvtHL5QAKhSzKgyjrcNnPdkPBHA==", - "dev": true, - "requires": { - "@sindresorhus/df": "^2.1.0", - "mount-point": "^3.0.0", - "pify": "^2.2.0", - "user-home": "^2.0.0", - "xdg-basedir": "^2.0.0" - } - }, - "xtend": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz", - "integrity": "sha1-pcbVMr5lbiPbgg77lDofBJmNY68=", - "dev": true - }, - "yallist": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", - "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=", - "dev": true - } - } -} diff --git a/package.json b/package.json index a1c2654c24..82f3e833d3 100644 --- a/package.json +++ b/package.json @@ -1,23 +1,28 @@ { "name": "postcss-custom-media", - "version": "6.0.0", - "description": "PostCSS plugin to transform W3C CSS Custom Media Queries to more compatible CSS", - "keywords": [ - "css", - "postcss", - "postcss-plugin", - "media queries", - "custom-media" + "version": "7.0.0", + "description": "Use Custom Media Queries in CSS", + "author": "Jonathan Neal ", + "contributors": [ + "Maxime Thirouin" ], - "author": "Maxime Thirouin", "license": "MIT", - "repository": { - "type": "git", - "url": "https://github.com/postcss/postcss-custom-media.git" - }, + "repository": "postcss/postcss-custom-media", + "homepage": "https://github.com/postcss/postcss-custom-media#readme", + "bugs": "https://github.com/postcss/postcss-custom-media/issues", + "main": "index.cjs.js", + "module": "index.es.mjs", "files": [ - "index.js" + "index.cjs.js", + "index.es.mjs" ], + "scripts": { + "prepublishOnly": "npm test", + "pretest": "rollup -c .rollup.js --silent", + "test": "echo 'Running tests...'; npm run test:js && npm run test:tape", + "test:js": "eslint *.js lib/*.js --cache --ignore-path .gitignore --quiet", + "test:tape": "postcss-tape" + }, "engines": { "node": ">=6.0.0" }, @@ -25,19 +30,33 @@ "postcss": "^7.0.2" }, "devDependencies": { - "eslint": "^3.19.0", - "eslint-config-i-am-meticulous": "^6.0.1", - "eslint-plugin-import": "^1.7.0", - "npmpub": "^3.1.0", - "tape": "^4.6.3" - }, - "scripts": { - "lint": "eslint --fix .", - "tests": "tape test", - "test": "npm run lint && npm run tests", - "release": "npmpub" + "@babel/core": "^7.0.0", + "@babel/plugin-syntax-dynamic-import": "^7.0.0", + "@babel/preset-env": "^7.0.0", + "babel-eslint": "^9.0.0", + "eslint": "^5.5.0", + "eslint-config-dev": "^2.0.0", + "postcss-tape": "^2.2.0", + "pre-commit": "^1.2.2", + "rollup": "^0.65.2", + "rollup-plugin-babel": "^4.0.3" }, "eslintConfig": { - "extends": "eslint-config-i-am-meticulous/es5" - } + "extends": "dev", + "parser": "babel-eslint" + }, + "keywords": [ + "postcss", + "css", + "postcss-plugin", + "custom", + "media", + "query", + "queries", + "w3c", + "csswg", + "atrule", + "at-rule", + "specification" + ] } diff --git a/test/basic.css b/test/basic.css new file mode 100644 index 0000000000..287c730151 --- /dev/null +++ b/test/basic.css @@ -0,0 +1,33 @@ +@custom-media --mq-a (max-width: 30em), (max-height: 30em); +@custom-media --not-mq-a not all and (--mq-a); + +@media not (--mq-a) { + body { + order: 1; + } +} + +@media not (--not-mq-a) { + body { + order: 2; + } +} + +@custom-media --circular-mq-a (--circular-mq-b); +@custom-media --circular-mq-b (--circular-mq-a); + +@media (--circular-mq-a) { + body { + order: 3; + } +} + +@media (--circular-mq-b) { + body { + order: 4; + } +} + +@media (--unresolved-mq) { + body order: 5; +} diff --git a/test/basic.expect.css b/test/basic.expect.css new file mode 100644 index 0000000000..6aafdb5a15 --- /dev/null +++ b/test/basic.expect.css @@ -0,0 +1,27 @@ +@media (max-width: 30em),(max-height: 30em) { + body { + order: 1; + } +} + +@media (max-width: 30em),(max-height: 30em) { + body { + order: 2; + } +} + +@media (--circular-mq-b) { + body { + order: 3; + } +} + +@media (--circular-mq-a) { + body { + order: 4; + } +} + +@media (--unresolved-mq) { + body order: 5; +} diff --git a/test/fixtures/append.css b/test/fixtures/append.css deleted file mode 100644 index 945cc118d0..0000000000 --- a/test/fixtures/append.css +++ /dev/null @@ -1,3 +0,0 @@ -@media (--viewport-max-s) { - body { font-size: 1rem; } -} diff --git a/test/fixtures/append.expected.css b/test/fixtures/append.expected.css deleted file mode 100644 index 6c44041f98..0000000000 --- a/test/fixtures/append.expected.css +++ /dev/null @@ -1,4 +0,0 @@ -@media (max-width: 30em) { - body { font-size: 1rem; } -} -@custom-media --viewport-max-s (max-width: 30em); diff --git a/test/fixtures/js-defined.css b/test/fixtures/js-defined.css deleted file mode 100755 index 46334f5173..0000000000 --- a/test/fixtures/js-defined.css +++ /dev/null @@ -1,15 +0,0 @@ -@custom-media --viewport-max-s (max-width: 50em); - -body { color: #000 } - -@media (--viewport-max-s) { - body { font-size: 1rem; } -} - -@media (--viewport-min-s) { - body { font-size: 1.2rem; } -} - -@media (--viewport-min-s ) { - -} diff --git a/test/fixtures/js-defined.expected.css b/test/fixtures/js-defined.expected.css deleted file mode 100755 index b53bb468d8..0000000000 --- a/test/fixtures/js-defined.expected.css +++ /dev/null @@ -1,15 +0,0 @@ - - -body { color: #000 } - -@media (max-width: 30em) { - body { font-size: 1rem; } -} - -@media (min-width: 30.01em) { - body { font-size: 1.2rem; } -} - -@media (min-width: 30.01em) { - -} diff --git a/test/fixtures/preserve.css b/test/fixtures/preserve.css deleted file mode 100644 index 46a14f7b16..0000000000 --- a/test/fixtures/preserve.css +++ /dev/null @@ -1,4 +0,0 @@ -@custom-media --viewport-max-s (max-width: 30em); -@media (--viewport-max-s) { - body { font-size: 1rem; } -} diff --git a/test/fixtures/preserve.expected.css b/test/fixtures/preserve.expected.css deleted file mode 100644 index 5bfb3c8eb5..0000000000 --- a/test/fixtures/preserve.expected.css +++ /dev/null @@ -1,4 +0,0 @@ -@custom-media --viewport-max-s (max-width: 30em); -@media (max-width: 30em) { - body { font-size: 1rem; } -} diff --git a/test/fixtures/transform-all.css b/test/fixtures/transform-all.css deleted file mode 100644 index 72f8501c55..0000000000 --- a/test/fixtures/transform-all.css +++ /dev/null @@ -1,8 +0,0 @@ -@custom-media --a (foo: bar); -@custom-media --b (bar: baz); - -@media (--a), (--b) { - selector { - property: value; - } -} diff --git a/test/fixtures/transform-all.expected.css b/test/fixtures/transform-all.expected.css deleted file mode 100644 index e08678c028..0000000000 --- a/test/fixtures/transform-all.expected.css +++ /dev/null @@ -1,7 +0,0 @@ - - -@media (foo: bar), (bar: baz) { - selector { - property: value; - } -} diff --git a/test/fixtures/transform-circular-reference.css b/test/fixtures/transform-circular-reference.css deleted file mode 100644 index 48b1f3cfc1..0000000000 --- a/test/fixtures/transform-circular-reference.css +++ /dev/null @@ -1,16 +0,0 @@ -body { color: #000 } - -@custom-media --a (--b); -@custom-media --b (--a); - -@media (--a) { - selector { - property: value; - } -} - -@media (--b) { - selector { - property: value; - } -} diff --git a/test/fixtures/transform-circular-reference.expected.css b/test/fixtures/transform-circular-reference.expected.css deleted file mode 100644 index 4746c8775a..0000000000 --- a/test/fixtures/transform-circular-reference.expected.css +++ /dev/null @@ -1 +0,0 @@ -body { color: #000 } diff --git a/test/fixtures/transform-reference.css b/test/fixtures/transform-reference.css deleted file mode 100644 index e5e8a5b3e5..0000000000 --- a/test/fixtures/transform-reference.css +++ /dev/null @@ -1,8 +0,0 @@ -@custom-media --a (foo: bar); -@custom-media --b (--a); - -@media (--b) { - selector { - property: value; - } -} diff --git a/test/fixtures/transform-reference.expected.css b/test/fixtures/transform-reference.expected.css deleted file mode 100644 index c949741814..0000000000 --- a/test/fixtures/transform-reference.expected.css +++ /dev/null @@ -1,7 +0,0 @@ - - -@media (foo: bar) { - selector { - property: value; - } -} diff --git a/test/fixtures/transform-self-reference.css b/test/fixtures/transform-self-reference.css deleted file mode 100644 index 7907752313..0000000000 --- a/test/fixtures/transform-self-reference.css +++ /dev/null @@ -1,9 +0,0 @@ -body { color: #000 } - -@custom-media --a (--a); - -@media (--a) { - selector { - property: value; - } -} diff --git a/test/fixtures/transform-self-reference.expected.css b/test/fixtures/transform-self-reference.expected.css deleted file mode 100644 index 4746c8775a..0000000000 --- a/test/fixtures/transform-self-reference.expected.css +++ /dev/null @@ -1 +0,0 @@ -body { color: #000 } diff --git a/test/fixtures/transform.css b/test/fixtures/transform.css deleted file mode 100755 index 8114b7491f..0000000000 --- a/test/fixtures/transform.css +++ /dev/null @@ -1,16 +0,0 @@ -@custom-media --viewport-max-s (max-width: 30em); -@custom-media --viewport-min-s (min-width: 30.01em); - -body { color: #000 } - -@media (--viewport-max-s) { - body { font-size: 1rem; } -} - -@media (--viewport-min-s) { - body { font-size: 1.2rem; } -} - -@media (--viewport-min-s ) { - -} diff --git a/test/fixtures/transform.expected.css b/test/fixtures/transform.expected.css deleted file mode 100755 index b53bb468d8..0000000000 --- a/test/fixtures/transform.expected.css +++ /dev/null @@ -1,15 +0,0 @@ - - -body { color: #000 } - -@media (max-width: 30em) { - body { font-size: 1rem; } -} - -@media (min-width: 30.01em) { - body { font-size: 1.2rem; } -} - -@media (min-width: 30.01em) { - -} diff --git a/test/fixtures/undefined.css b/test/fixtures/undefined.css deleted file mode 100755 index 4c36cd113d..0000000000 --- a/test/fixtures/undefined.css +++ /dev/null @@ -1,5 +0,0 @@ -body { color: #000 } - -@media (--undefined-custom-media) { - body { font-size: 1rem; } -} diff --git a/test/fixtures/undefined.expected.css b/test/fixtures/undefined.expected.css deleted file mode 100755 index 4746c8775a..0000000000 --- a/test/fixtures/undefined.expected.css +++ /dev/null @@ -1 +0,0 @@ -body { color: #000 } diff --git a/test/index.js b/test/index.js deleted file mode 100755 index 21132fd102..0000000000 --- a/test/index.js +++ /dev/null @@ -1,117 +0,0 @@ -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 result = postcss() - .use(plugin(opts)) - .process(read(postcssOpts.from), postcssOpts) - var actual = result.css - var expected = read(filename("fixtures/" + name + ".expected")) - fs.writeFileSync(filename("fixtures/" + name + ".actual"), actual) - t.equal(actual.trim(), expected.trim(), msg) - - return result -} - -test("@custom-media", function(t) { - compareFixtures( - t, - "transform", - "should transform custom media" - ) - - compareFixtures( - t, - "transform-all", - "should replaces all extension names" - ) - - compareFixtures( - t, - "transform-reference", - "should transform custom media referencing another custom media" - ) - - compareFixtures( - t, - "transform-self-reference", - "should transform custom media with self reference" - ) - - compareFixtures( - t, - "transform-circular-reference", - "should transform custom media with circular reference" - ) - - var undefinedRes = compareFixtures( - t, - "undefined", - "should remove undefined @media" - ) - - t.ok( - undefinedRes.warnings()[0].text.match(/Missing @custom-media/), - "should send warning to postcss" - ) - - compareFixtures( - t, - "js-defined", - "should transform custom media and override local extensions", - { - extensions: { - "--viewport-max-s": "(max-width: 30em)", - "--viewport-min-s": "(min-width: 30.01em)", - }, - } - ) - - compareFixtures( - t, - "js-defined", - "should transform custom media and override local unprefixed extensions", - { - extensions: { - "viewport-max-s": "(max-width: 30em)", - "viewport-min-s": "(min-width: 30.01em)", - }, - } - ) - - compareFixtures( - t, - "preserve", - "should preserve custom media", - { preserve: true } - ) - - compareFixtures( - t, - "append", - "should append custom media", - { - extensions: { - "--viewport-max-s": "(max-width: 30em)", - "--a": "(--a)", - }, - appendExtensions: true, - } - ) - - t.end() -}) From 6380b0095095740f6aeade7da6a31739ecb51f5a Mon Sep 17 00:00:00 2001 From: Jonathan Neal Date: Thu, 13 Sep 2018 21:43:39 -0400 Subject: [PATCH 676/795] 5.1.0 --- .tape.js | 185 +++++++++++++++++++++++++++++++++++++ CHANGELOG.md | 5 + CONTRIBUTING.md | 2 +- INSTALL.md | 2 +- README.md | 55 +++++++++-- index.js | 8 +- lib/export-to.js | 129 ++++++++++++++++++++++++++ lib/import-from.js | 41 ++++---- package.json | 15 ++- test/export-selectors.css | 20 ++++ test/export-selectors.js | 18 ++++ test/export-selectors.json | 18 ++++ test/export-selectors.mjs | 16 ++++ 13 files changed, 474 insertions(+), 40 deletions(-) create mode 100644 lib/export-to.js create mode 100644 test/export-selectors.css create mode 100644 test/export-selectors.js create mode 100644 test/export-selectors.json create mode 100644 test/export-selectors.mjs diff --git a/.tape.js b/.tape.js index c4485d4bf8..846b95efcc 100644 --- a/.tape.js +++ b/.tape.js @@ -19,6 +19,36 @@ module.exports = { } } }, + 'basic:import-fn': { + message: 'supports { importFrom() } usage', + options: { + importFrom() { + return { + customSelectors: { + ':--heading': 'h1, h2, h3' + } + }; + } + }, + expect: 'basic.import.expect.css', + result: 'basic.import.result.css' + }, + 'basic:import-fn-promise': { + message: 'supports { async importFrom() } usage', + options: { + importFrom() { + return new Promise(resolve => { + resolve({ + customSelectors: { + ':--heading': 'h1, h2, h3' + } + }) + }); + } + }, + expect: 'basic.import.expect.css', + result: 'basic.import.result.css' + }, 'basic:import-json': { message: 'supports { importFrom: "test/import-selectors.json" } usage', options: { @@ -42,6 +72,161 @@ module.exports = { }, expect: 'basic.import.expect.css', result: 'basic.import.result.css' + }, + 'basic:import-css-from': { + message: 'supports { importFrom: { from: "test/import-selectors.css" } } usage', + options: { + importFrom: { from: 'test/import-selectors.css' } + }, + expect: 'basic.import.expect.css', + result: 'basic.import.result.css' + }, + 'basic:import-css-from-type': { + message: 'supports { importFrom: [ { from: "test/import-selectors.css", type: "css" } ] } usage', + options: { + importFrom: [ { from: 'test/import-selectors.css', type: 'css' } ] + }, + expect: 'basic.import.expect.css', + result: 'basic.import.result.css' + }, + 'basic:export': { + message: 'supports { exportTo: { customSelectors: { ... } } } usage', + options: { + exportTo: (global.__exportSelectorObject = global.__exportSelectorObject || { + customSelectors: null + }) + }, + expect: 'basic.expect.css', + result: 'basic.result.css', + after() { + if (__exportSelectorObject.customSelectors[':--foo'] !== '.foo') { + throw new Error('The exportTo function failed'); + } + } + }, + 'basic:export-fn': { + message: 'supports { exportTo() } usage', + options: { + exportTo(customProperties) { + if (customProperties[':--foo'] !== '.foo') { + throw new Error('The exportTo function failed'); + } + } + }, + expect: 'basic.expect.css', + result: 'basic.result.css' + }, + 'basic:export-fn-promise': { + message: 'supports { async exportTo() } usage', + options: { + exportTo(customProperties) { + return new Promise((resolve, reject) => { + if (customProperties[':--foo'] !== '.foo') { + reject('The exportTo function failed'); + } else { + resolve(); + } + }); + } + }, + expect: 'basic.expect.css', + result: 'basic.result.css' + }, + 'basic:export-json': { + message: 'supports { exportTo: "test/export-selectors.json" } usage', + options: { + exportTo: 'test/export-selectors.json' + }, + expect: 'basic.expect.css', + result: 'basic.result.css', + before() { + global.__exportSelectorsString = require('fs').readFileSync('test/export-selectors.json', 'utf8'); + }, + after() { + if (global.__exportSelectorsString !== require('fs').readFileSync('test/export-selectors.json', 'utf8')) { + throw new Error('The original file did not match the freshly exported copy'); + } + } + }, + 'basic:export-js': { + message: 'supports { exportTo: "test/export-selectors.js" } usage', + options: { + exportTo: 'test/export-selectors.js' + }, + expect: 'basic.expect.css', + result: 'basic.result.css', + before() { + global.__exportSelectorsString = require('fs').readFileSync('test/export-selectors.js', 'utf8'); + }, + after() { + if (global.__exportSelectorsString !== require('fs').readFileSync('test/export-selectors.js', 'utf8')) { + throw new Error('The original file did not match the freshly exported copy'); + } + } + }, + 'basic:export-mjs': { + message: 'supports { exportTo: "test/export-selectors.mjs" } usage', + options: { + exportTo: 'test/export-selectors.mjs' + }, + expect: 'basic.expect.css', + result: 'basic.result.css', + before() { + global.__exportSelectorsString = require('fs').readFileSync('test/export-selectors.mjs', 'utf8'); + }, + after() { + if (global.__exportSelectorsString !== require('fs').readFileSync('test/export-selectors.mjs', 'utf8')) { + throw new Error('The original file did not match the freshly exported copy'); + } + } + }, + 'basic:export-css': { + message: 'supports { exportTo: "test/export-selectors.css" } usage', + options: { + exportTo: 'test/export-selectors.css' + }, + expect: 'basic.expect.css', + result: 'basic.result.css', + before() { + global.__exportSelectorsString = require('fs').readFileSync('test/export-selectors.css', 'utf8'); + }, + after() { + if (global.__exportSelectorsString !== require('fs').readFileSync('test/export-selectors.css', 'utf8')) { + throw new Error('The original file did not match the freshly exported copy'); + } + } + }, + 'basic:export-css-to': { + message: 'supports { exportTo: { to: "test/export-selectors.css" } } usage', + options: { + exportTo: { to: 'test/export-selectors.css' } + }, + expect: 'basic.expect.css', + result: 'basic.result.css', + before() { + global.__exportSelectorsString = require('fs').readFileSync('test/export-selectors.css', 'utf8'); + }, + after() { + if (global.__exportSelectorsString !== require('fs').readFileSync('test/export-selectors.css', 'utf8')) { + throw new Error('The original file did not match the freshly exported copy'); + } + } + }, + 'basic:export-css-to-type': { + message: 'supports { exportTo: { to: "test/export-selectors.css", type: "css" } } usage', + options: { + exportTo: { to: 'test/export-selectors.css', type: 'css' } + }, + expect: 'basic.expect.css', + result: 'basic.result.css', + before() { + global.__exportSelectorsString = require('fs').readFileSync('test/export-selectors.css', 'utf8'); + }, + after() { + if (global.__exportSelectorsString !== require('fs').readFileSync('test/export-selectors.css', 'utf8')) { + throw new Error('The original file did not match the freshly exported copy'); + } + } } } }; diff --git a/CHANGELOG.md b/CHANGELOG.md index cebfe28aa1..7d2a8849ee 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,10 @@ # Changes to PostCSS Custom Selectors +### 5.1.0 (September 12, 2018) + +- Added: New `exportTo` function to specify where to export custom selectors +- Updated: `importFrom` option to support passing it a function + ### 5.0.0 (September 7, 2018) - Added: New `preserve` option to preserve custom selectors and rules using them diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index c345221e55..02d06083dc 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -26,7 +26,7 @@ scope and avoid unrelated commits. cd postcss-custom-selectors # Assign the original repo to a remote called "upstream" - git remote add upstream git@github.com:jonathantneal/postcss-custom-selectors.git + git remote add upstream git@github.com:postcss/postcss-custom-selectors.git # Install the tools necessary for testing npm install diff --git a/INSTALL.md b/INSTALL.md index ae9a9ce163..6cd5dbfdf4 100644 --- a/INSTALL.md +++ b/INSTALL.md @@ -164,7 +164,7 @@ grunt.initConfig({ [Grunt PostCSS]: https://github.com/nDmitry/grunt-postcss [PostCSS]: https://github.com/postcss/postcss [PostCSS CLI]: https://github.com/postcss/postcss-cli -[PostCSS Custom Selectors]: https://github.com/jonathantneal/postcss-custom-selectors +[PostCSS Custom Selectors]: https://github.com/postcss/postcss-custom-selectors [PostCSS Loader]: https://github.com/postcss/postcss-loader [React App Rewire PostCSS]: https://github.com/csstools/react-app-rewire-postcss [React App Rewired]: https://github.com/timarney/react-app-rewired diff --git a/README.md b/README.md index 5000430621..163f5f5e6c 100644 --- a/README.md +++ b/README.md @@ -76,12 +76,12 @@ article :--heading + p {} ### importFrom The `importFrom` option specifies sources where custom selectors can be -imported from, which might be CSS, JS, and JSON files, and directly passed -objects. +imported from, which might be CSS, JS, and JSON files, functions, and directly +passed objects. ```js postcssCustomSelectors({ - importFrom: 'path/to/file.css' // => @custom-selector h1, h2, h3 + importFrom: 'path/to/file.css' // => @custom-selector :--heading h1, h2, h3; }); ``` @@ -95,9 +95,9 @@ article :--heading + p { article h1 + p, article h2 + p, article h3 + p {} ``` -Multiple files can be passed into this option, and they will be parsed in the -order they are received. JavaScript files, JSON files, and objects will need -to namespace custom selectors using the `customProperties` or +Multiple sources can be passed into this option, and they will be parsed in the +order they are received. JavaScript files, JSON files, functions, and objects +will need to namespace custom selectors using the `customProperties` or `custom-properties` key. ```js @@ -107,9 +107,46 @@ postcssCustomSelectors({ 'and/then/this.js', 'and/then/that.json', { - customSelectors: { - ':--heading': 'h1, h2, h3' - } + customSelectors: { ':--heading': 'h1, h2, h3' } + }, + () => { + const customProperties = { ':--heading': 'h1, h2, h3' }; + + return { customProperties }; + } + ] +}); +``` + +### exportTo + +The `exportTo` option specifies destinations where custom selectors can be +exported to, which might be CSS, JS, and JSON files, functions, and directly +passed objects. + +```js +postcssCustomSelectors({ + exportTo: 'path/to/file.css' // @custom-selector :--heading h1, h2, h3; +}); +``` + +Multiple destinations can be passed into this option, and they will be parsed +in the order they are received. JavaScript files, JSON files, and objects will +need to namespace custom selectors using the `customProperties` or +`custom-properties` key. + +```js +const cachedObject = { customSelectors: {} }; + +postcssCustomSelectors({ + exportTo: [ + 'path/to/file.css', // @custom-selector :--heading h1, h2, h3; + 'and/then/this.js', // module.exports = { customSelectors: { ':--heading': 'h1, h2, h3' } } + 'and/then/this.mjs', // export const customSelectors = { ':--heading': 'h1, h2, h3' } } + 'and/then/that.json', // { "custom-selectors": { ":--heading": "h1, h2, h3" } } + cachedObject, + customProperties => { + customProperties // { ':--heading': 'h1, h2, h3' } } ] }); diff --git a/index.js b/index.js index e12e5b32bc..9dad15e553 100644 --- a/index.js +++ b/index.js @@ -2,14 +2,18 @@ import postcss from 'postcss'; import getCustomSelectors from './lib/custom-selectors-from-root'; import transformRules from './lib/transform-rules'; import importCustomSelectorsFromSources from './lib/import-from'; +import exportCustomSelectorsToDestinations from './lib/export-to'; export default postcss.plugin('postcss-custom-selectors', opts => { // whether to preserve custom selectors and rules using them const preserve = Boolean(Object(opts).preserve); - // sources from where to import custom selectors + // sources to import custom selectors from const importFrom = [].concat(Object(opts).importFrom || []); + // destinations to export custom selectors to + const exportTo = [].concat(Object(opts).exportTo || []); + // promise any custom selectors are imported const customSelectorsPromise = importCustomSelectorsFromSources(importFrom); @@ -19,6 +23,8 @@ export default postcss.plugin('postcss-custom-selectors', opts => { getCustomSelectors(root, { preserve }) ); + await exportCustomSelectorsToDestinations(customProperties, exportTo); + transformRules(root, customProperties, { preserve }); }; }); diff --git a/lib/export-to.js b/lib/export-to.js new file mode 100644 index 0000000000..f589f5d2d1 --- /dev/null +++ b/lib/export-to.js @@ -0,0 +1,129 @@ +import fs from 'fs'; +import path from 'path'; + +/* Import Custom Selectors from CSS File +/* ========================================================================== */ + +async function exportCustomSelectorsToCssFile(to, customSelectors) { + const cssContent = Object.keys(customSelectors).reduce((cssLines, name) => { + cssLines.push(`@custom-selector ${name} ${customSelectors[name]};`); + + return cssLines; + }, []).join('\n'); + const css = `${cssContent}\n`; + + await writeFile(to, css); +} + +/* Import Custom Selectors from JSON file +/* ========================================================================== */ + +async function exportCustomSelectorsToJsonFile(to, customSelectors) { + const jsonContent = JSON.stringify({ + 'custom-selectors': customSelectors + }, null, ' '); + const json = `${jsonContent}\n`; + + await writeFile(to, json); +} + +/* Import Custom Selectors from Common JS file +/* ========================================================================== */ + +async function exportCustomSelectorsToCjsFile(to, customSelectors) { + const jsContents = Object.keys(customSelectors).reduce((jsLines, name) => { + jsLines.push(`\t\t'${escapeForJS(name)}': '${escapeForJS(customSelectors[name])}'`); + + return jsLines; + }, []).join(',\n'); + const js = `module.exports = {\n\tcustomSelectors: {\n${jsContents}\n\t}\n};\n`; + + await writeFile(to, js); +} + +/* Import Custom Selectors from Module JS file +/* ========================================================================== */ + +async function exportCustomSelectorsToMjsFile(to, customSelectors) { + const mjsContents = Object.keys(customSelectors).reduce((mjsLines, name) => { + mjsLines.push(`\t'${escapeForJS(name)}': '${escapeForJS(customSelectors[name])}'`); + + return mjsLines; + }, []).join(',\n'); + const mjs = `export const customSelectors = {\n${mjsContents}\n};\n`; + + await writeFile(to, mjs); +} + +/* Export Custom Selectors to Destinations +/* ========================================================================== */ + +export default function exportCustomSelectorsToDestinations(customSelectors, destinations) { + return Promise.all(destinations.map(async destination => { + if (destination instanceof Function) { + await destination(defaultCustomSelectorsToJSON(customSelectors)); + } else { + // read the destination as an object + const opts = destination === Object(destination) ? destination : { to: String(destination) }; + + // transformer for custom selectors into a JSON-compatible object + const toJSON = opts.toJSON || defaultCustomSelectorsToJSON; + + if ('customSelectors' in opts) { + // write directly to an object as customSelectors + opts.customSelectors = toJSON(customSelectors); + } else if ('custom-selectors' in opts) { + // write directly to an object as custom-selectors + opts['custom-selectors'] = toJSON(customSelectors); + } else { + // destination pathname + const to = String(opts.to || ''); + + // type of file being written to + const type = (opts.type || path.extname(opts.to).slice(1)).toLowerCase(); + + // transformed custom selectors + const customSelectorsJSON = toJSON(customSelectors); + + if (type === 'css') { + await exportCustomSelectorsToCssFile(to, customSelectorsJSON); + } + + if (type === 'js') { + await exportCustomSelectorsToCjsFile(to, customSelectorsJSON); + } + + if (type === 'json') { + await exportCustomSelectorsToJsonFile(to, customSelectorsJSON); + } + + if (type === 'mjs') { + await exportCustomSelectorsToMjsFile(to, customSelectorsJSON); + } + } + } + })); +} + +/* Helper utilities +/* ========================================================================== */ + +const defaultCustomSelectorsToJSON = customSelectors => { + return Object.keys(customSelectors).reduce((customSelectorsJSON, key) => { + customSelectorsJSON[key] = String(customSelectors[key]); + + return customSelectorsJSON; + }, {}); +}; + +const writeFile = (to, text) => new Promise((resolve, reject) => { + fs.writeFile(to, text, error => { + if (error) { + reject(error); + } else { + resolve(); + } + }); +}); + +const escapeForJS = string => string.replace(/\\([\s\S])|(')/g, '\\$1$2').replace(/\n/g, '\\n').replace(/\r/g, '\\r'); diff --git a/lib/import-from.js b/lib/import-from.js index f89e6ddb63..5201d639b4 100644 --- a/lib/import-from.js +++ b/lib/import-from.js @@ -60,20 +60,29 @@ async function importCustomSelectorsFromJSFile(from) { export default function importCustomSelectorsFromSources(sources) { return sources.map(source => { - if (typeof source === 'string') { - if (isCSSPath(source)) { - return [ 'css', source ] - } else if (isJSPath(source)) { - return [ 'js', source ] - } else if (isJSONPath(source)) { - return [ 'json', source ] - } + if (source instanceof Promise) { + return source; + } else if (source instanceof Function) { + return source(); } - return Object(source); + // read the source as an object + const opts = source === Object(source) ? source : { from: String(source) }; + + // skip objects with custom selectors + if (Object(opts).customSelectors || Object(opts)['custom-selectors']) { + return opts + } + + // source pathname + const from = String(opts.from || ''); + + // type of file being read from + const type = (opts.type || path.extname(opts.from).slice(1)).toLowerCase(); + + return { type, from }; }).reduce(async (customSelectors, source) => { - const type = source[0]; - const from = source[1]; + const { type, from } = await source; if (type === 'ast') { return Object.assign(customSelectors, importCustomSelectorsFromCSSAST(from)); @@ -91,21 +100,13 @@ export default function importCustomSelectorsFromSources(sources) { return Object.assign(customSelectors, await importCustomSelectorsFromJSONFile(from)); } - return Object.assign(customSelectors, importCustomSelectorsFromObject(source)); + return Object.assign(customSelectors, importCustomSelectorsFromObject(await source)); }, {}); } /* Helper utilities /* ========================================================================== */ -const matchCSSPath = /\.\w*css/i; -const matchJSPath = /\.\w*js/i; -const matchJSONPath = /\.\w*json/i; - -const isCSSPath = from => matchCSSPath.test(from); -const isJSPath = from => matchJSPath.test(from); -const isJSONPath = from => matchJSONPath.test(from); - const readFile = from => new Promise((resolve, reject) => { fs.readFile(from, 'utf8', (error, result) => { if (error) { diff --git a/package.json b/package.json index 6711a8a0d2..5314c276d2 100644 --- a/package.json +++ b/package.json @@ -1,16 +1,16 @@ { "name": "postcss-custom-selectors", - "version": "5.0.0", + "version": "5.1.0", "description": "Use Custom Selectors in CSS", "author": "Jonathan Neal ", "contributors": [ "yisi", "Maxime Thirouin" ], - "license": "CC0-1.0", - "repository": "jonathantneal/postcss-custom-selectors", - "homepage": "https://github.com/jonathantneal/postcss-custom-selectors#readme", - "bugs": "https://github.com/jonathantneal/postcss-custom-selectors/issues", + "license": "MIT", + "repository": "postcss/postcss-custom-selectors", + "homepage": "https://github.com/postcss/postcss-custom-selectors#readme", + "bugs": "https://github.com/postcss/postcss-custom-selectors/issues", "main": "index.cjs.js", "module": "index.es.mjs", "files": [ @@ -21,7 +21,6 @@ "prepublishOnly": "npm test", "pretest": "rollup -c .rollup.js --silent", "test": "echo 'Running tests...'; npm run test:js && npm run test:tape", - "test:ec": "echint --ignore index.*.js test", "test:js": "eslint *.js lib/*.js --cache --ignore-path .gitignore --quiet", "test:tape": "postcss-tape" }, @@ -33,7 +32,7 @@ "postcss-selector-parser": "^5.0.0-rc.3" }, "devDependencies": { - "@babel/core": "^7.0.0", + "@babel/core": "^7.0.1", "@babel/plugin-syntax-dynamic-import": "^7.0.0", "@babel/preset-env": "^7.0.0", "babel-eslint": "^9.0.0", @@ -42,7 +41,7 @@ "postcss-tape": "^2.2.0", "pre-commit": "^1.2.2", "rollup": "^0.65.2", - "rollup-plugin-babel": "^4.0.1" + "rollup-plugin-babel": "^4.0.3" }, "eslintConfig": { "extends": "dev", diff --git a/test/export-selectors.css b/test/export-selectors.css new file mode 100644 index 0000000000..7973b78f25 --- /dev/null +++ b/test/export-selectors.css @@ -0,0 +1,20 @@ +@custom-selector :--foo .foo; +@custom-selector :--any-heading h1, h2, h3, h4, h5, h6; +@custom-selector :--foobar .foo; +@custom-selector :--baz .baz; +@custom-selector :--fizzbuzz .fizz, .buzz; +@custom-selector :--button-types .btn-primary, + .btn-success, + .btn-info, + .btn-warning, + .btn-danger; +@custom-selector :--commented-foo .foo, + .bar > .baz; +@custom-selector :--pseudo ::before, ::after; +@custom-selector :--fo-----o h1, h2, h3; +@custom-selector :--ba-----r h4, h5, h6; +@custom-selector :--multiline .foo, + .bar > .baz; +@custom-selector :--button button, .button; +@custom-selector :--enter :hover, :focus; +@custom-selector :--any-foobar .foo, .bar; diff --git a/test/export-selectors.js b/test/export-selectors.js new file mode 100644 index 0000000000..e6ed9f04ea --- /dev/null +++ b/test/export-selectors.js @@ -0,0 +1,18 @@ +module.exports = { + customSelectors: { + ':--foo': '.foo', + ':--any-heading': 'h1, h2, h3, h4, h5, h6', + ':--foobar': '.foo', + ':--baz': '.baz', + ':--fizzbuzz': '.fizz, .buzz', + ':--button-types': '.btn-primary,\n .btn-success,\n .btn-info,\n .btn-warning,\n .btn-danger', + ':--commented-foo': '.foo,\n .bar > .baz', + ':--pseudo': '::before, ::after', + ':--fo-----o': 'h1, h2, h3', + ':--ba-----r': 'h4, h5, h6', + ':--multiline': '.foo,\n .bar > .baz', + ':--button': 'button, .button', + ':--enter': ':hover, :focus', + ':--any-foobar': '.foo, .bar' + } +}; diff --git a/test/export-selectors.json b/test/export-selectors.json new file mode 100644 index 0000000000..089840cd78 --- /dev/null +++ b/test/export-selectors.json @@ -0,0 +1,18 @@ +{ + "custom-selectors": { + ":--foo": ".foo", + ":--any-heading": "h1, h2, h3, h4, h5, h6", + ":--foobar": ".foo", + ":--baz": ".baz", + ":--fizzbuzz": ".fizz, .buzz", + ":--button-types": ".btn-primary,\n\t.btn-success,\n\t.btn-info,\n\t.btn-warning,\n\t.btn-danger", + ":--commented-foo": ".foo,\n\t.bar > .baz", + ":--pseudo": "::before, ::after", + ":--fo-----o": "h1, h2, h3", + ":--ba-----r": "h4, h5, h6", + ":--multiline": ".foo,\n\t.bar > .baz", + ":--button": "button, .button", + ":--enter": ":hover, :focus", + ":--any-foobar": ".foo, .bar" + } +} diff --git a/test/export-selectors.mjs b/test/export-selectors.mjs new file mode 100644 index 0000000000..f445eb2319 --- /dev/null +++ b/test/export-selectors.mjs @@ -0,0 +1,16 @@ +export const customSelectors = { + ':--foo': '.foo', + ':--any-heading': 'h1, h2, h3, h4, h5, h6', + ':--foobar': '.foo', + ':--baz': '.baz', + ':--fizzbuzz': '.fizz, .buzz', + ':--button-types': '.btn-primary,\n .btn-success,\n .btn-info,\n .btn-warning,\n .btn-danger', + ':--commented-foo': '.foo,\n .bar > .baz', + ':--pseudo': '::before, ::after', + ':--fo-----o': 'h1, h2, h3', + ':--ba-----r': 'h4, h5, h6', + ':--multiline': '.foo,\n .bar > .baz', + ':--button': 'button, .button', + ':--enter': ':hover, :focus', + ':--any-foobar': '.foo, .bar' +}; From b59e59a14e2996714ea1223699bd46a824f0549a Mon Sep 17 00:00:00 2001 From: Jonathan Neal Date: Fri, 14 Sep 2018 00:54:00 -0400 Subject: [PATCH 677/795] 7.0.1 --- .tape.js | 228 +++++++++++++++++++++++ CHANGELOG.md | 6 +- lib/import-from.js | 2 +- lib/transform-params-by-custom-params.js | 28 ++- package.json | 4 +- test/basic.css | 22 ++- test/basic.expect.css | 24 ++- test/basic.import.expect.css | 0 test/basic.preserve.expect.css | 97 ++++++++++ test/export-media.css | 4 + test/export-media.js | 8 + test/export-media.json | 8 + test/export-media.mjs | 6 + test/import-css.css | 0 test/import-media.css | 2 + test/import-media.js | 6 + test/import-media.json | 6 + test/import.css | 29 +++ test/import.expect.css | 29 +++ 19 files changed, 493 insertions(+), 16 deletions(-) create mode 100644 test/basic.import.expect.css create mode 100644 test/basic.preserve.expect.css create mode 100644 test/export-media.css create mode 100644 test/export-media.js create mode 100644 test/export-media.json create mode 100644 test/export-media.mjs create mode 100644 test/import-css.css create mode 100644 test/import-media.css create mode 100644 test/import-media.js create mode 100644 test/import-media.json create mode 100644 test/import.css create mode 100644 test/import.expect.css diff --git a/.tape.js b/.tape.js index ee6d7a3ac2..72204e3812 100644 --- a/.tape.js +++ b/.tape.js @@ -2,6 +2,234 @@ module.exports = { 'postcss-custom-media': { 'basic': { message: 'supports basic usage' + }, + 'basic:preserve': { + message: 'supports { preserve: true } usage', + options: { + preserve: true + } + }, + 'import': { + message: 'supports { importFrom: { customMedia: { ... } } } usage', + options: { + importFrom: { + customMedia: { + '--mq-a': '(max-width: 30em), (max-height: 30em)', + '--not-mq-a': 'not all and (--mq-a)' + } + } + } + }, + 'import:import-fn': { + message: 'supports { importFrom() } usage', + options: { + importFrom() { + return { + customMedia: { + '--mq-a': '(max-width: 30em), (max-height: 30em)', + '--not-mq-a': 'not all and (--mq-a)' + } + }; + } + }, + expect: 'import.expect.css', + result: 'import.result.css' + }, + 'import:import-fn-promise': { + message: 'supports { async importFrom() } usage', + options: { + importFrom() { + return new Promise(resolve => { + resolve({ + customMedia: { + '--mq-a': '(max-width: 30em), (max-height: 30em)', + '--not-mq-a': 'not all and (--mq-a)' + } + }) + }); + } + }, + expect: 'import.expect.css', + result: 'import.result.css' + }, + 'import:json': { + message: 'supports { importFrom: "test/import-media.json" } usage', + options: { + importFrom: 'test/import-media.json' + }, + expect: 'import.expect.css', + result: 'import.result.css' + }, + 'import:js': { + message: 'supports { importFrom: "test/import-media.js" } usage', + options: { + importFrom: 'test/import-media.js' + }, + expect: 'import.expect.css', + result: 'import.result.css' + }, + 'import:css': { + message: 'supports { importFrom: "test/import-media.css" } usage', + options: { + importFrom: 'test/import-media.css' + }, + expect: 'import.expect.css', + result: 'import.result.css' + }, + 'import:css-from': { + message: 'supports { importFrom: { from: "test/import-media.css" } } usage', + options: { + importFrom: { from: 'test/import-media.css' } + }, + expect: 'import.expect.css', + result: 'import.result.css' + }, + 'import:css-from-type': { + message: 'supports { importFrom: [ { from: "test/import-media.css", type: "css" } ] } usage', + options: { + importFrom: [ { from: 'test/import-media.css', type: 'css' } ] + }, + expect: 'import.expect.css', + result: 'import.result.css' + }, + 'basic:export': { + message: 'supports { exportTo: { customMedia: { ... } } } usage', + options: { + exportTo: (global.__exportMediaObject = global.__exportMediaObject || { + customMedia: null + }) + }, + expect: 'basic.expect.css', + result: 'basic.result.css', + after() { + if (__exportMediaObject.customMedia['--mq-a'] !== '(max-width: 30em), (max-height: 30em)') { + throw new Error('The exportTo function failed'); + } + } + }, + 'basic:export-fn': { + message: 'supports { exportTo() } usage', + options: { + exportTo(customMedia) { + if (customMedia['--mq-a'] !== '(max-width: 30em), (max-height: 30em)') { + throw new Error('The exportTo function failed'); + } + } + }, + expect: 'basic.expect.css', + result: 'basic.result.css' + }, + 'basic:export-fn-promise': { + message: 'supports { async exportTo() } usage', + options: { + exportTo(customMedia) { + return new Promise((resolve, reject) => { + if (customMedia['--mq-a'] !== '(max-width: 30em), (max-height: 30em)') { + reject('The exportTo function failed'); + } else { + resolve(); + } + }); + } + }, + expect: 'basic.expect.css', + result: 'basic.result.css' + }, + 'basic:export-json': { + message: 'supports { exportTo: "test/export-media.json" } usage', + options: { + exportTo: 'test/export-media.json' + }, + expect: 'basic.expect.css', + result: 'basic.result.css', + before() { + global.__exportMediaString = require('fs').readFileSync('test/export-media.json', 'utf8'); + }, + after() { + if (global.__exportMediaString !== require('fs').readFileSync('test/export-media.json', 'utf8')) { + throw new Error('The original file did not match the freshly exported copy'); + } + } + }, + 'basic:export-js': { + message: 'supports { exportTo: "test/export-media.js" } usage', + options: { + exportTo: 'test/export-media.js' + }, + expect: 'basic.expect.css', + result: 'basic.result.css', + before() { + global.__exportMediaString = require('fs').readFileSync('test/export-media.js', 'utf8'); + }, + after() { + if (global.__exportMediaString !== require('fs').readFileSync('test/export-media.js', 'utf8')) { + throw new Error('The original file did not match the freshly exported copy'); + } + } + }, + 'basic:export-mjs': { + message: 'supports { exportTo: "test/export-media.mjs" } usage', + options: { + exportTo: 'test/export-media.mjs' + }, + expect: 'basic.expect.css', + result: 'basic.result.css', + before() { + global.__exportMediaString = require('fs').readFileSync('test/export-media.mjs', 'utf8'); + }, + after() { + if (global.__exportMediaString !== require('fs').readFileSync('test/export-media.mjs', 'utf8')) { + throw new Error('The original file did not match the freshly exported copy'); + } + } + }, + 'basic:export-css': { + message: 'supports { exportTo: "test/export-media.css" } usage', + options: { + exportTo: 'test/export-media.css' + }, + expect: 'basic.expect.css', + result: 'basic.result.css', + before() { + global.__exportMediaString = require('fs').readFileSync('test/export-media.css', 'utf8'); + }, + after() { + if (global.__exportMediaString !== require('fs').readFileSync('test/export-media.css', 'utf8')) { + throw new Error('The original file did not match the freshly exported copy'); + } + } + }, + 'basic:export-css-to': { + message: 'supports { exportTo: { to: "test/export-media.css" } } usage', + options: { + exportTo: { to: 'test/export-media.css' } + }, + expect: 'basic.expect.css', + result: 'basic.result.css', + before() { + global.__exportMediaString = require('fs').readFileSync('test/export-media.css', 'utf8'); + }, + after() { + if (global.__exportMediaString !== require('fs').readFileSync('test/export-media.css', 'utf8')) { + throw new Error('The original file did not match the freshly exported copy'); + } + } + }, + 'basic:export-css-to-type': { + message: 'supports { exportTo: { to: "test/export-media.css", type: "css" } } usage', + options: { + exportTo: { to: 'test/export-media.css', type: 'css' } + }, + expect: 'basic.expect.css', + result: 'basic.result.css', + before() { + global.__exportMediaString = require('fs').readFileSync('test/export-media.css', 'utf8'); + }, + after() { + if (global.__exportMediaString !== require('fs').readFileSync('test/export-media.css', 'utf8')) { + throw new Error('The original file did not match the freshly exported copy'); + } + } } } }; diff --git a/CHANGELOG.md b/CHANGELOG.md index 666301d609..f7372c25c5 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,10 @@ # Changes to PostCSS Custom Media -### 7.0.0 (September 12, 2018) +### 7.0.1 (September 14, 2018) + +- Fixed: An issue with how opposing queries are resolved. + +### 7.0.0 (September 14, 2018) - Added: New `preserve` option to preserve custom media and atrules using them - Added: New `exportTo` function to specify where to export custom media diff --git a/lib/import-from.js b/lib/import-from.js index 41030d4f6a..79f3bf4be1 100644 --- a/lib/import-from.js +++ b/lib/import-from.js @@ -8,7 +8,7 @@ import getCustomMedia from './custom-media-from-root'; /* ========================================================================== */ function importCustomMediaFromCSSAST(root) { - return getCustomMedia(root); + return getCustomMedia(root, { preserve: true }); } /* Import Custom Media from CSS File diff --git a/lib/transform-params-by-custom-params.js b/lib/transform-params-by-custom-params.js index b9a6cf53dd..5a3d59841d 100644 --- a/lib/transform-params-by-custom-params.js +++ b/lib/transform-params-by-custom-params.js @@ -25,10 +25,17 @@ function transformMedia(media, customMedias) { if (key in customMedias) { for (const replacementMedia of customMedias[key].nodes) { + // use the first available modifier unless they cancel each other out + const modifier = media.modifier !== replacementMedia.modifier + ? media.modifier || replacementMedia.modifier + : ''; const mediaClone = media.clone({ - modifier: replacementMedia.modifier === media.modifier && modifierRegExp.test(media.modifier) - ? '' - : replacementMedia.modifier + modifier, + // conditionally use the raws from the first available modifier + raws: !modifier || media.modifier + ? { ...media.raws } + : { ...replacementMedia.raws }, + type: media.type || replacementMedia.type }); mediaClone.nodes.splice(index, 1, ...replacementMedia.clone().nodes.map(node => { @@ -38,9 +45,9 @@ function transformMedia(media, customMedias) { return node; })); - const retranspiledMedias = String(mediaClone) === String(customMedias[key]) - ? [] - : transformMedia(mediaClone, customMedias); + // remove the currently transformed key to prevent recursion + const nextCustomMedia = getCustomMediasWithoutKey(customMedias, key); + const retranspiledMedias = transformMedia(mediaClone, nextCustomMedia); if (retranspiledMedias.length) { transpiledMedias.push(...retranspiledMedias); @@ -58,5 +65,12 @@ function transformMedia(media, customMedias) { return transpiledMedias; } -const modifierRegExp = /^not$/i; const customPseudoRegExp = /\((--[A-z][\w-]*)\)/; + +const getCustomMediasWithoutKey = (customMedias, key) => { + const nextCustomMedias = Object.assign({}, customMedias); + + delete nextCustomMedias[key]; + + return nextCustomMedias; +}; diff --git a/package.json b/package.json index 82f3e833d3..987ebbac63 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "postcss-custom-media", - "version": "7.0.0", + "version": "7.0.1", "description": "Use Custom Media Queries in CSS", "author": "Jonathan Neal ", "contributors": [ @@ -30,7 +30,7 @@ "postcss": "^7.0.2" }, "devDependencies": { - "@babel/core": "^7.0.0", + "@babel/core": "^7.0.1", "@babel/plugin-syntax-dynamic-import": "^7.0.0", "@babel/preset-env": "^7.0.0", "babel-eslint": "^9.0.0", diff --git a/test/basic.css b/test/basic.css index 287c730151..360bb9e46d 100644 --- a/test/basic.css +++ b/test/basic.css @@ -1,13 +1,31 @@ @custom-media --mq-a (max-width: 30em), (max-height: 30em); @custom-media --not-mq-a not all and (--mq-a); -@media not (--mq-a) { +@media (--mq-a) { body { order: 1; } } -@media not (--not-mq-a) { +@media (--mq-a), (--mq-a) { + body { + order: 1; + } +} + +@media not all and (--mq-a) { + body { + order: 2; + } +} + +@media (--not-mq-a) { + body { + order: 1; + } +} + +@media not all and (--not-mq-a) { body { order: 2; } diff --git a/test/basic.expect.css b/test/basic.expect.css index 6aafdb5a15..6d15f5e84c 100644 --- a/test/basic.expect.css +++ b/test/basic.expect.css @@ -4,19 +4,37 @@ } } -@media (max-width: 30em),(max-height: 30em) { +@media (max-width: 30em),(max-height: 30em), (max-width: 30em), (max-height: 30em) { + body { + order: 1; + } +} + +@media not all and (max-width: 30em),not all and (max-height: 30em) { body { order: 2; } } -@media (--circular-mq-b) { +@media not all and (max-width: 30em),not all and (max-height: 30em) { body { - order: 3; + order: 1; + } +} + +@media all and (max-width: 30em),all and (max-height: 30em) { + body { + order: 2; } } @media (--circular-mq-a) { + body { + order: 3; + } +} + +@media (--circular-mq-b) { body { order: 4; } diff --git a/test/basic.import.expect.css b/test/basic.import.expect.css new file mode 100644 index 0000000000..e69de29bb2 diff --git a/test/basic.preserve.expect.css b/test/basic.preserve.expect.css new file mode 100644 index 0000000000..3fa5361d2b --- /dev/null +++ b/test/basic.preserve.expect.css @@ -0,0 +1,97 @@ +@custom-media --mq-a (max-width: 30em), (max-height: 30em); +@custom-media --not-mq-a not all and (--mq-a); + +@media (max-width: 30em),(max-height: 30em) { + body { + order: 1; + } +} + +@media (--mq-a) { + body { + order: 1; + } +} + +@media (max-width: 30em),(max-height: 30em), (max-width: 30em), (max-height: 30em) { + body { + order: 1; + } +} + +@media (--mq-a), (--mq-a) { + body { + order: 1; + } +} + +@media not all and (max-width: 30em),not all and (max-height: 30em) { + body { + order: 2; + } +} + +@media not all and (--mq-a) { + body { + order: 2; + } +} + +@media not all and (max-width: 30em),not all and (max-height: 30em) { + body { + order: 1; + } +} + +@media (--not-mq-a) { + body { + order: 1; + } +} + +@media all and (max-width: 30em),all and (max-height: 30em) { + body { + order: 2; + } +} + +@media not all and (--not-mq-a) { + body { + order: 2; + } +} + +@custom-media --circular-mq-a (--circular-mq-b); +@custom-media --circular-mq-b (--circular-mq-a); + +@media (--circular-mq-a) { + body { + order: 3; + } +} + +@media (--circular-mq-a) { + body { + order: 3; + } +} + +@media (--circular-mq-b) { + body { + order: 4; + } +} + +@media (--circular-mq-b) { + body { + order: 4; + } +} + +@media (--unresolved-mq) { + body order: 5; +} + +@media (--unresolved-mq) { + body order: 5; +} diff --git a/test/export-media.css b/test/export-media.css new file mode 100644 index 0000000000..fc776fcec3 --- /dev/null +++ b/test/export-media.css @@ -0,0 +1,4 @@ +@custom-media --mq-a (max-width: 30em), (max-height: 30em); +@custom-media --not-mq-a not all and (--mq-a); +@custom-media --circular-mq-a (--circular-mq-b); +@custom-media --circular-mq-b (--circular-mq-a); diff --git a/test/export-media.js b/test/export-media.js new file mode 100644 index 0000000000..579c929893 --- /dev/null +++ b/test/export-media.js @@ -0,0 +1,8 @@ +module.exports = { + customMedia: { + '--mq-a': '(max-width: 30em), (max-height: 30em)', + '--not-mq-a': 'not all and (--mq-a)', + '--circular-mq-a': '(--circular-mq-b)', + '--circular-mq-b': '(--circular-mq-a)' + } +}; diff --git a/test/export-media.json b/test/export-media.json new file mode 100644 index 0000000000..b0a258771f --- /dev/null +++ b/test/export-media.json @@ -0,0 +1,8 @@ +{ + "custom-media": { + "--mq-a": "(max-width: 30em), (max-height: 30em)", + "--not-mq-a": "not all and (--mq-a)", + "--circular-mq-a": "(--circular-mq-b)", + "--circular-mq-b": "(--circular-mq-a)" + } +} diff --git a/test/export-media.mjs b/test/export-media.mjs new file mode 100644 index 0000000000..c1a4a72904 --- /dev/null +++ b/test/export-media.mjs @@ -0,0 +1,6 @@ +export const customMedia = { + '--mq-a': '(max-width: 30em), (max-height: 30em)', + '--not-mq-a': 'not all and (--mq-a)', + '--circular-mq-a': '(--circular-mq-b)', + '--circular-mq-b': '(--circular-mq-a)' +}; diff --git a/test/import-css.css b/test/import-css.css new file mode 100644 index 0000000000..e69de29bb2 diff --git a/test/import-media.css b/test/import-media.css new file mode 100644 index 0000000000..e788f32ae5 --- /dev/null +++ b/test/import-media.css @@ -0,0 +1,2 @@ +@custom-media --mq-a (max-width: 30em), (max-height: 30em); +@custom-media --not-mq-a not all and (--mq-a); diff --git a/test/import-media.js b/test/import-media.js new file mode 100644 index 0000000000..3f2e0401ab --- /dev/null +++ b/test/import-media.js @@ -0,0 +1,6 @@ +module.exports = { + customMedia: { + '--mq-a': '(max-width: 30em), (max-height: 30em)', + '--not-mq-a': 'not all and (--mq-a)' + } +} diff --git a/test/import-media.json b/test/import-media.json new file mode 100644 index 0000000000..807d8dfdd5 --- /dev/null +++ b/test/import-media.json @@ -0,0 +1,6 @@ +{ + "customMedia": { + "--mq-a": "(max-width: 30em), (max-height: 30em)", + "--not-mq-a": "not all and (--mq-a)" + } +} diff --git a/test/import.css b/test/import.css new file mode 100644 index 0000000000..f37220e74e --- /dev/null +++ b/test/import.css @@ -0,0 +1,29 @@ +@media (--mq-a) { + body { + order: 1; + } +} + +@media (--mq-a), (--mq-a) { + body { + order: 1; + } +} + +@media not all and (--mq-a) { + body { + order: 2; + } +} + +@media (--not-mq-a) { + body { + order: 1; + } +} + +@media not all and (--not-mq-a) { + body { + order: 2; + } +} diff --git a/test/import.expect.css b/test/import.expect.css new file mode 100644 index 0000000000..0bc2bbf3bf --- /dev/null +++ b/test/import.expect.css @@ -0,0 +1,29 @@ +@media (max-width: 30em),(max-height: 30em) { + body { + order: 1; + } +} + +@media (max-width: 30em),(max-height: 30em), (max-width: 30em), (max-height: 30em) { + body { + order: 1; + } +} + +@media not all and (max-width: 30em),not all and (max-height: 30em) { + body { + order: 2; + } +} + +@media not all and (max-width: 30em),not all and (max-height: 30em) { + body { + order: 1; + } +} + +@media all and (max-width: 30em),all and (max-height: 30em) { + body { + order: 2; + } +} From 407c33cd8821a869db9dc6fac3d99681ee74a1ef Mon Sep 17 00:00:00 2001 From: Jonathan Neal Date: Sat, 15 Sep 2018 15:35:35 -0400 Subject: [PATCH 678/795] 7.0.2 --- CHANGELOG.md | 4 ++++ lib/transform-atrules.js | 4 ++-- ...orm-params-by-custom-params.js => transform-media-list.js} | 0 package.json | 4 ++-- 4 files changed, 8 insertions(+), 4 deletions(-) rename lib/{transform-params-by-custom-params.js => transform-media-list.js} (100%) diff --git a/CHANGELOG.md b/CHANGELOG.md index f7372c25c5..4284f45fad 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # Changes to PostCSS Custom Media +### 7.0.2 (September 15, 2018) + +- Fixed: An issue with re-assigning params as a non-string + ### 7.0.1 (September 14, 2018) - Fixed: An issue with how opposing queries are resolved. diff --git a/lib/transform-atrules.js b/lib/transform-atrules.js index 74f54315a3..b85758855f 100644 --- a/lib/transform-atrules.js +++ b/lib/transform-atrules.js @@ -1,4 +1,4 @@ -import transformParamsByCustomParams from './transform-params-by-custom-params'; +import transformMediaList from './transform-media-list'; import mediaASTFromString from './media-ast-from-string'; // transform custom pseudo selectors with custom selectors @@ -6,7 +6,7 @@ export default (root, customMedia, opts) => { root.walkAtRules(mediaAtRuleRegExp, atrule => { if (customPseudoRegExp.test(atrule.params)) { const mediaAST = mediaASTFromString(atrule.params); - const params = transformParamsByCustomParams(mediaAST, customMedia, opts); + const params = String(transformMediaList(mediaAST, customMedia)); if (opts.preserve) { atrule.cloneBefore({ params }); diff --git a/lib/transform-params-by-custom-params.js b/lib/transform-media-list.js similarity index 100% rename from lib/transform-params-by-custom-params.js rename to lib/transform-media-list.js diff --git a/package.json b/package.json index 987ebbac63..4955b81aab 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "postcss-custom-media", - "version": "7.0.1", + "version": "7.0.2", "description": "Use Custom Media Queries in CSS", "author": "Jonathan Neal ", "contributors": [ @@ -34,7 +34,7 @@ "@babel/plugin-syntax-dynamic-import": "^7.0.0", "@babel/preset-env": "^7.0.0", "babel-eslint": "^9.0.0", - "eslint": "^5.5.0", + "eslint": "^5.6.0", "eslint-config-dev": "^2.0.0", "postcss-tape": "^2.2.0", "pre-commit": "^1.2.2", From 6ef218d07cbe30c357a0d00e8979f07a950383f1 Mon Sep 17 00:00:00 2001 From: Jonathan Neal Date: Sun, 16 Sep 2018 17:30:46 -0400 Subject: [PATCH 679/795] 8.0.0 --- .babelrc | 12 - .editorconfig | 13 +- .eslintignore | 1 - .eslintrc.yml | 34 - .gitignore | 12 +- .rollup.js | 19 + .tape.js | 238 ++ .travis.yml | 11 +- CHANGELOG.md | 75 +- CONTRIBUTING.md | 65 + INSTALL.md | 170 + LICENSE => LICENSE.md | 21 +- README.md | 350 +- index.js | 363 +- lib/export-to.js | 129 + lib/get-custom-properties.js | 57 + lib/import-from.js | 120 + lib/transform-properties.js | 35 + lib/transform-value-ast.js | 50 + package-lock.json | 3692 ----------------- package.json | 78 +- test/basic.css | 27 + test/basic.expect.css | 30 + test/basic.import.expect.css | 30 + test/basic.preserve.expect.css | 16 + test/export-properties.css | 6 + test/export-properties.js | 8 + test/export-properties.json | 8 + test/export-properties.mjs | 6 + test/fixtures/append.css | 3 - test/fixtures/append.duplicates.css | 8 - test/fixtures/append.duplicates.expected.css | 14 - test/fixtures/append.expected.css | 8 - test/fixtures/automatic-variable-prefix.css | 4 - .../automatic-variable-prefix.expected.css | 6 - test/fixtures/case-sensitive.css | 9 - test/fixtures/case-sensitive.expected.css | 11 - test/fixtures/circular-reference.css | 7 - test/fixtures/circular-reference.expected.css | 10 - test/fixtures/important.css | 16 - test/fixtures/important.expected.css | 19 - test/fixtures/js-defined.css | 13 - test/fixtures/js-defined.expected.css | 19 - test/fixtures/js-override.css | 13 - test/fixtures/js-override.expected.css | 19 - test/fixtures/media-query.css | 5 - test/fixtures/media-query.expected.css | 5 - test/fixtures/preserve-computed.css | 21 - test/fixtures/preserve-computed.expected.css | 21 - test/fixtures/preserve-variables.css | 20 - test/fixtures/preserve-variables.expected.css | 23 - test/fixtures/remove-properties.css | 13 - test/fixtures/remove-properties.expected.css | 13 - .../self-reference-double-fallback.css | 6 - ...elf-reference-double-fallback.expected.css | 12 - test/fixtures/self-reference-fallback.css | 6 - .../self-reference-fallback.expected.css | 8 - test/fixtures/self-reference.css | 6 - test/fixtures/self-reference.expected.css | 8 - test/fixtures/substitution-defined.css | 41 - .../substitution-defined.expected.css | 50 - test/fixtures/substitution-empty.css | 3 - test/fixtures/substitution-fallback.css | 35 - .../substitution-fallback.expected.css | 47 - test/fixtures/substitution-malformed.css | 4 - test/fixtures/substitution-overwrite.css | 12 - .../substitution-overwrite.expected.css | 14 - test/fixtures/substitution-strict.css | 10 - .../fixtures/substitution-strict.expected.css | 14 - test/fixtures/substitution-trailing-space.css | 7 - .../substitution-trailing-space.expected.css | 8 - test/fixtures/substitution-undefined.css | 12 - .../substitution-undefined.expected.css | 18 - test/import-properties.css | 5 + test/import-properties.js | 7 + test/import-properties.json | 7 + test/index.js | 362 -- 77 files changed, 1265 insertions(+), 5413 deletions(-) delete mode 100644 .babelrc delete mode 100644 .eslintignore delete mode 100644 .eslintrc.yml create mode 100644 .rollup.js create mode 100644 .tape.js create mode 100644 CONTRIBUTING.md create mode 100644 INSTALL.md rename LICENSE => LICENSE.md (50%) create mode 100644 lib/export-to.js create mode 100644 lib/get-custom-properties.js create mode 100644 lib/import-from.js create mode 100644 lib/transform-properties.js create mode 100644 lib/transform-value-ast.js delete mode 100644 package-lock.json create mode 100644 test/basic.css create mode 100644 test/basic.expect.css create mode 100644 test/basic.import.expect.css create mode 100644 test/basic.preserve.expect.css create mode 100644 test/export-properties.css create mode 100644 test/export-properties.js create mode 100644 test/export-properties.json create mode 100644 test/export-properties.mjs delete mode 100644 test/fixtures/append.css delete mode 100644 test/fixtures/append.duplicates.css delete mode 100644 test/fixtures/append.duplicates.expected.css delete mode 100644 test/fixtures/append.expected.css delete mode 100644 test/fixtures/automatic-variable-prefix.css delete mode 100644 test/fixtures/automatic-variable-prefix.expected.css delete mode 100755 test/fixtures/case-sensitive.css delete mode 100755 test/fixtures/case-sensitive.expected.css delete mode 100644 test/fixtures/circular-reference.css delete mode 100644 test/fixtures/circular-reference.expected.css delete mode 100644 test/fixtures/important.css delete mode 100644 test/fixtures/important.expected.css delete mode 100755 test/fixtures/js-defined.css delete mode 100755 test/fixtures/js-defined.expected.css delete mode 100755 test/fixtures/js-override.css delete mode 100755 test/fixtures/js-override.expected.css delete mode 100755 test/fixtures/media-query.css delete mode 100755 test/fixtures/media-query.expected.css delete mode 100755 test/fixtures/preserve-computed.css delete mode 100755 test/fixtures/preserve-computed.expected.css delete mode 100755 test/fixtures/preserve-variables.css delete mode 100755 test/fixtures/preserve-variables.expected.css delete mode 100755 test/fixtures/remove-properties.css delete mode 100755 test/fixtures/remove-properties.expected.css delete mode 100644 test/fixtures/self-reference-double-fallback.css delete mode 100644 test/fixtures/self-reference-double-fallback.expected.css delete mode 100644 test/fixtures/self-reference-fallback.css delete mode 100644 test/fixtures/self-reference-fallback.expected.css delete mode 100644 test/fixtures/self-reference.css delete mode 100644 test/fixtures/self-reference.expected.css delete mode 100755 test/fixtures/substitution-defined.css delete mode 100755 test/fixtures/substitution-defined.expected.css delete mode 100755 test/fixtures/substitution-empty.css delete mode 100755 test/fixtures/substitution-fallback.css delete mode 100755 test/fixtures/substitution-fallback.expected.css delete mode 100755 test/fixtures/substitution-malformed.css delete mode 100755 test/fixtures/substitution-overwrite.css delete mode 100755 test/fixtures/substitution-overwrite.expected.css delete mode 100755 test/fixtures/substitution-strict.css delete mode 100755 test/fixtures/substitution-strict.expected.css delete mode 100755 test/fixtures/substitution-trailing-space.css delete mode 100755 test/fixtures/substitution-trailing-space.expected.css delete mode 100755 test/fixtures/substitution-undefined.css delete mode 100644 test/fixtures/substitution-undefined.expected.css create mode 100644 test/import-properties.css create mode 100644 test/import-properties.js create mode 100644 test/import-properties.json delete mode 100755 test/index.js diff --git a/.babelrc b/.babelrc deleted file mode 100644 index f36920318c..0000000000 --- a/.babelrc +++ /dev/null @@ -1,12 +0,0 @@ -{ - "presets": [ - ["env", { - "targets": { - "node": 4 - } - }] - ], - "plugins": [ - "add-module-exports" - ] -} diff --git a/.editorconfig b/.editorconfig index 8978b448a6..e06d7982bc 100644 --- a/.editorconfig +++ b/.editorconfig @@ -1,16 +1,15 @@ -# editorconfig.org root = true [*] -end_of_line = lf charset = utf-8 -trim_trailing_whitespace = true +end_of_line = lf +indent_style = tab insert_final_newline = true -indent_style = space -indent_size = 2 +trim_trailing_whitespace = true [*.md] trim_trailing_whitespace = false -[Makefile] -indent_style = tab +[*.{json,md,yml}] +indent_size = 2 +indent_style = space diff --git a/.eslintignore b/.eslintignore deleted file mode 100644 index 1521c8b765..0000000000 --- a/.eslintignore +++ /dev/null @@ -1 +0,0 @@ -dist diff --git a/.eslintrc.yml b/.eslintrc.yml deleted file mode 100644 index ec22acd0a3..0000000000 --- a/.eslintrc.yml +++ /dev/null @@ -1,34 +0,0 @@ -root: true -extends: eslint:recommended - -parserOptions: - ecmaVersion: 6 - sourceType: "module" - -rules: - indent: [2, 2] # 2 spaces indentation - max-len: [2, 80, 4] - 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"] diff --git a/.gitignore b/.gitignore index 319d993c5f..d920b78fec 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,11 @@ -dist node_modules -test/fixtures/*.actual.css +index.*.* +package-lock.json +*.log* +*.result.css +.* +!.editorconfig +!.gitignore +!.rollup.js +!.tape.js +!.travis.yml diff --git a/.rollup.js b/.rollup.js new file mode 100644 index 0000000000..eab5c0d513 --- /dev/null +++ b/.rollup.js @@ -0,0 +1,19 @@ +import babel from 'rollup-plugin-babel'; + +export default { + input: 'index.js', + output: [ + { file: 'index.cjs.js', format: 'cjs' }, + { file: 'index.es.mjs', format: 'es' } + ], + plugins: [ + babel({ + plugins: [ + '@babel/plugin-syntax-dynamic-import' + ], + presets: [ + ['@babel/env', { modules: false, targets: { node: 6 } }] + ] + }) + ] +}; diff --git a/.tape.js b/.tape.js new file mode 100644 index 0000000000..5fc09cc2b1 --- /dev/null +++ b/.tape.js @@ -0,0 +1,238 @@ +module.exports = { + 'postcss-custom-properties': { + 'basic': { + message: 'supports basic usage' + }, + 'basic:preserve': { + message: 'supports { preserve: false } usage', + options: { + preserve: false + } + }, + 'basic:import': { + message: 'supports { importFrom: { customProperties: { ... } } } usage', + options: { + importFrom: { + customProperties: { + '--color': 'red', + '--color-2': 'yellow', + '--ref-color': 'var(--color)' + } + } + } + }, + 'basic:import-fn': { + message: 'supports { importFrom() } usage', + options: { + importFrom() { + return { + customProperties: { + '--color': 'red', + '--color-2': 'yellow', + '--ref-color': 'var(--color)' + } + }; + } + }, + expect: 'basic.import.expect.css', + result: 'basic.import.result.css' + }, + 'basic:import-fn-promise': { + message: 'supports { async importFrom() } usage', + options: { + importFrom() { + return new Promise(resolve => { + resolve({ + customProperties: { + '--color': 'red', + '--color-2': 'yellow', + '--ref-color': 'var(--color)' + } + }) + }); + } + }, + expect: 'basic.import.expect.css', + result: 'basic.import.result.css' + }, + 'basic:import-json': { + message: 'supports { importFrom: "test/import-properties.json" } usage', + options: { + importFrom: 'test/import-properties.json' + }, + expect: 'basic.import.expect.css', + result: 'basic.import.result.css' + }, + 'basic:import-js': { + message: 'supports { importFrom: "test/import-properties.js" } usage', + options: { + importFrom: 'test/import-properties.js' + }, + expect: 'basic.import.expect.css', + result: 'basic.import.result.css' + }, + 'basic:import-css': { + message: 'supports { importFrom: "test/import-properties.css" } usage', + options: { + importFrom: 'test/import-properties.css' + }, + expect: 'basic.import.expect.css', + result: 'basic.import.result.css' + }, + 'basic:import-css-from': { + message: 'supports { importFrom: { from: "test/import-properties.css" } } usage', + options: { + importFrom: { from: 'test/import-properties.css' } + }, + expect: 'basic.import.expect.css', + result: 'basic.import.result.css' + }, + 'basic:import-css-from-type': { + message: 'supports { importFrom: [ { from: "test/import-properties.css", type: "css" } ] } usage', + options: { + importFrom: [ { from: 'test/import-properties.css', type: 'css' } ] + }, + expect: 'basic.import.expect.css', + result: 'basic.import.result.css' + }, + 'basic:export': { + message: 'supports { exportTo: { customProperties: { ... } } } usage', + options: { + exportTo: (global.__exportPropertiesObject = global.__exportPropertiesObject || { + customProperties: null + }) + }, + expect: 'basic.expect.css', + result: 'basic.result.css', + after() { + if (__exportPropertiesObject.customProperties['--color'] !== 'red') { + throw new Error('The exportTo function failed'); + } + } + }, + 'basic:export-fn': { + message: 'supports { exportTo() } usage', + options: { + exportTo(customProperties) { + if (customProperties['--color'] !== 'red') { + throw new Error('The exportTo function failed'); + } + } + }, + expect: 'basic.expect.css', + result: 'basic.result.css' + }, + 'basic:export-fn-promise': { + message: 'supports { async exportTo() } usage', + options: { + exportTo(customProperties) { + return new Promise((resolve, reject) => { + if (customProperties['--color'] !== 'red') { + reject('The exportTo function failed'); + } else { + resolve(); + } + }); + } + }, + expect: 'basic.expect.css', + result: 'basic.result.css' + }, + 'basic:export-json': { + message: 'supports { exportTo: "test/export-properties.json" } usage', + options: { + exportTo: 'test/export-properties.json' + }, + expect: 'basic.expect.css', + result: 'basic.result.css', + before() { + global.__exportPropertiesString = require('fs').readFileSync('test/export-properties.json', 'utf8'); + }, + after() { + if (global.__exportPropertiesString !== require('fs').readFileSync('test/export-properties.json', 'utf8')) { + throw new Error('The original file did not match the freshly exported copy'); + } + } + }, + 'basic:export-js': { + message: 'supports { exportTo: "test/export-properties.js" } usage', + options: { + exportTo: 'test/export-properties.js' + }, + expect: 'basic.expect.css', + result: 'basic.result.css', + before() { + global.__exportPropertiesString = require('fs').readFileSync('test/export-properties.js', 'utf8'); + }, + after() { + if (global.__exportPropertiesString !== require('fs').readFileSync('test/export-properties.js', 'utf8')) { + throw new Error('The original file did not match the freshly exported copy'); + } + } + }, + 'basic:export-mjs': { + message: 'supports { exportTo: "test/export-properties.mjs" } usage', + options: { + exportTo: 'test/export-properties.mjs' + }, + expect: 'basic.expect.css', + result: 'basic.result.css', + before() { + global.__exportPropertiesString = require('fs').readFileSync('test/export-properties.mjs', 'utf8'); + }, + after() { + if (global.__exportPropertiesString !== require('fs').readFileSync('test/export-properties.mjs', 'utf8')) { + throw new Error('The original file did not match the freshly exported copy'); + } + } + }, + 'basic:export-css': { + message: 'supports { exportTo: "test/export-properties.css" } usage', + options: { + exportTo: 'test/export-properties.css' + }, + expect: 'basic.expect.css', + result: 'basic.result.css', + before() { + global.__exportPropertiesString = require('fs').readFileSync('test/export-properties.css', 'utf8'); + }, + after() { + if (global.__exportPropertiesString !== require('fs').readFileSync('test/export-properties.css', 'utf8')) { + throw new Error('The original file did not match the freshly exported copy'); + } + } + }, + 'basic:export-css-to': { + message: 'supports { exportTo: { to: "test/export-properties.css" } } usage', + options: { + exportTo: { to: 'test/export-properties.css' } + }, + expect: 'basic.expect.css', + result: 'basic.result.css', + before() { + global.__exportPropertiesString = require('fs').readFileSync('test/export-properties.css', 'utf8'); + }, + after() { + if (global.__exportPropertiesString !== require('fs').readFileSync('test/export-properties.css', 'utf8')) { + throw new Error('The original file did not match the freshly exported copy'); + } + } + }, + 'basic:export-css-to-type': { + message: 'supports { exportTo: { to: "test/export-properties.css", type: "css" } } usage', + options: { + exportTo: { to: 'test/export-properties.css', type: 'css' } + }, + expect: 'basic.expect.css', + result: 'basic.result.css', + before() { + global.__exportPropertiesString = require('fs').readFileSync('test/export-properties.css', 'utf8'); + }, + after() { + if (global.__exportPropertiesString !== require('fs').readFileSync('test/export-properties.css', 'utf8')) { + throw new Error('The original file did not match the freshly exported copy'); + } + } + } + } +}; diff --git a/.travis.yml b/.travis.yml index ebea37eb05..e1f11a52e6 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,6 +1,9 @@ -sudo: false +# https://docs.travis-ci.com/user/travis-lint + language: node_js + node_js: - - "stable" - - "8" - - "6" + - 6 + +install: + - npm install --ignore-scripts diff --git a/CHANGELOG.md b/CHANGELOG.md index fe4fcd4aee..b5d079d1a6 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,13 +1,30 @@ -# 7.0.0 - 2018-02-16 +# Changes to PostCSS Custom Properties + +### 8.0.0 (September 16, 2018) + +- Added: New `exportTo` function to specify where to export custom properties to. +- Added: New `importFrom` option to specify where to import custom properties from. +- Added: Support for variables written within `html` +- Added: Support for PostCSS v7. +- Added: Support for Node v6+. +- Removed: `strict` option, as using the fallback value isn’t necessarily more valid. +- Removed: `preserve: "computed"` option, as there seems to be little use in preserving custom property declarations while removing all usages of them. +- Removed: `warnings` and `noValueNotifications` options, as this should be the job of a linter tool. +- Removed: `variables` option, which is now replaced by `importFrom` +- Removed: `appendVariables` option, which is now replaced by `exportTo` +- Fixed: Custom Properties in `:root` are not also transformed. +- Fixed: Declarations that do not change are not duplicated during preserve. + +### 7.0.0 (February 16, 2018) - Changed: `preserve` option defaults as `true` to reflect the browser climate - Changed: `warnings` option defaults to `false` to reflect the browser climate -# 6.3.1 - 2018-02-16 +### 6.3.1 (February 16, 2018) - Reverted: `preserve` and `warnings` option to be added in major release -# 6.3.0 - 2018-02-15 +### 6.3.0 (February 15, 2018) - Fixed: `var()` captures strictly `var()` functions and not `xvar()`, etc - Fixed: `var()` better captures whitespace within the function @@ -16,124 +33,124 @@ - Changed: `warnings` option defaults to `false` to reflect the browser climate - Updated documentation -# 6.2.0 - 2017-10-06 +### 6.2.0 (October 6, 2017) - Added: `noValueNotifications` option (#71) - Fixed: Typo in `prefixedVariables` variable name (#77) -# 6.1.0 - 2017-06-28 +### 6.1.0 (June 28, 2017) - Added: Let "warnings" option silence all warnings ([#67](https://github.com/postcss/postcss-custom-properties/pull/67)) - Dependencies update (postcss, balanced-match) -# 6.0.1 - 2017-05-15 +### 6.0.1 (May 15, 2017) - Fixed: incorrect export ([#69](https://github.com/postcss/postcss-custom-properties/issues/69)) -# 6.0.0 - 2017-05-12 +### 6.0.0 (May 12, 2017) - Added: compatibility with postcss v6.x -# 5.0.2 - 2017-02-01 +### 5.0.2 (February 1, 2017) - Minor dependency update ([#57](https://github.com/postcss/postcss-custom-properties/pull/57)) -# 5.0.1 - 2016-04-22 +### 5.0.1 (April 22, 2016) - Fixed: trailing space after custom property name causes duplicate empty property ([#43](https://github.com/postcss/postcss-custom-properties/pull/43)) -# 5.0.0 - 2015-08-25 +### 5.0.0 (August 25, 2015) - Removed: compatibility with postcss v4.x - Added: compatibility with postcss v5.x -# 4.2.0 - 2015-07-21 +### 4.2.0 (July 21, 2015) - Added: `warnings` option allows you to disable warnings. ([cssnext#186](https://github.com/cssnext/cssnext/issues/186)) -# 4.1.0 - 2015-07-14 +### 4.1.0 (July 14, 2015) - Added: plugin now returns itself in order to expose a `setVariables` function that allow you to programmatically change the variables. ([#35](https://github.com/postcss/postcss-custom-properties/pull/35)) -# 4.0.0 - 2015-06-17 +### 4.0.0 (June 17, 2015) - Changed: messages and exceptions are now sent using postcss message API. -# 3.3.0 - 2015-04-08 +### 3.3.0 (April 8, 2015) - Added: `preserve` now support `"computed"` so only preserve resolved custom properties (see new option below) - Added: `appendVariables` allows you (when `preserve` is truthy) to append your variables as custom properties - Added: `strict: false` allows your to avoid too many fallbacks added in your CSS. -# 3.2.0 - 2015-03-31 +### 3.2.0 (03 31, 2015) - Added: JS defined variables are now resolved too ([#22](https://github.com/postcss/postcss-custom-properties/issues/22)) -# 3.1.0 - 2015-03-16 +### 3.1.0 (03 16, 2015) - Added: variables defined in JS are now automatically prefixed with `--` ([0691784](https://github.com/postcss/postcss-custom-properties/commit/0691784ed2218d7e6b16da8c4df03e2ca0c4798c)) -# 3.0.1 - 2015-02-06 +### 3.0.1 (February 6, 2015) - Fixed: logs now have filename back ([#19](https://github.com/postcss/postcss-custom-properties/issues/19)) -# 3.0.0 - 2015-01-20 +### 3.0.0 (January 20, 2015) - Changed: upgrade to postcss 4 ([#18](https://github.com/postcss/postcss-custom-properties/pull/18)) - Removed: some code that seems to be useless ([16ff3c2](https://github.com/postcss/postcss-custom-properties/commit/16ff3c22fe0563a1283411d7866791966fff4c58)) -# 2.1.1 - 2014-12-02 +### 2.1.1 (December 2, 2014) - Fixed: issue when multiples undefined custom properties are referenced ([#16](https://github.com/postcss/postcss-custom-properties/issues/16)) -# 2.1.0 - 2014-11-25 +### 2.1.0 (November 25, 2014) - Added: enhanced exceptions & messages -# 2.0.0 - 2014-11-12 +### 2.0.0 (November 12, 2014) - Changed: upgrade to postcss 3 -# 1.0.2 - 2014-11-04 +### 1.0.2 (November 4, 2014) - Fixed: more clear message for warning about custom prop used in non top-level :root -# 1.0.1 - 2014-11-03 +### 1.0.1 (November 3, 2014) - Fixed: warning about custom prop used in non :root -# 1.0.0 - 2014-11-02 +### 1.0.0 (November 2, 2014) - Added: warning when a custom prop is used in another place than :root - Added: handle !important -# 0.4.0 - 2014-09-30 +### 0.4.0 (September 30, 2014) - Added: JS-defined properties override CSS-defined -# 0.3.1 - 2014-08-27 +### 0.3.1 (August 27, 2014) - Added: nested custom properties usages are now correctly resolved - Changed: undefined var doesn't throw error anymore (just a console warning) & are kept as is in the output -# 0.3.0 - 2014-08-26 +### 0.3.0 (August 26, 2014) - Changed: fallback now are always added by default ([see why](http://www.w3.org/TR/css-variables/#invalid-variables)) - Changed: `map` option renamed to `variables` -# 0.2.0 - 2014-08-22 +### 0.2.0 (August 22, 2014) - Added: `map` option - Changed: GNU style error message -# 0.1.0 - 2014-08-01 +### 0.1.0 (August 1, 2014) ✨ First release based on [rework-vars](https://github.com/reworkcss/rework-vars) v3.1.1 diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 0000000000..f2e8fb76f1 --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,65 @@ +# Contributing to PostCSS Custom Properties + +You want to help? You rock! Now, take a moment to be sure your contributions +make sense to everyone else. + +## Reporting Issues + +Found a problem? Want a new feature? + +- See if your issue or idea has [already been reported]. +- Provide a [reduced test case] or a [live example]. + +Remember, a bug is a _demonstrable problem_ caused by _our_ code. + +## Submitting Pull Requests + +Pull requests are the greatest contributions, so be sure they are focused in +scope and avoid unrelated commits. + +1. To begin; [fork this project], clone your fork, and add our upstream. + ```bash + # Clone your fork of the repo into the current directory + git clone git@github.com:YOUR_USER/postcss-custom-properties.git + + # Navigate to the newly cloned directory + cd postcss-custom-properties + + # Assign the original repo to a remote called "upstream" + git remote add upstream git@github.com:postcss/postcss-custom-properties.git + + # Install the tools necessary for testing + npm install + ``` + +2. Create a branch for your feature or fix: + ```bash + # Move into a new branch for your feature + git checkout -b feature/thing + ``` + ```bash + # Move into a new branch for your fix + git checkout -b fix/something + ``` + +3. If your code follows our practices, then push your feature branch: + ```bash + # Test current code + npm test + ``` + ```bash + # Push the branch for your new feature + git push origin feature/thing + ``` + ```bash + # Or, push the branch for your update + git push origin update/something + ``` + +That’s it! Now [open a pull request] with a clear title and description. + +[already been reported]: issues +[fork this project]: fork +[live example]: https://codepen.io/pen +[open a pull request]: https://help.github.com/articles/using-pull-requests/ +[reduced test case]: https://css-tricks.com/reduced-test-cases/ diff --git a/INSTALL.md b/INSTALL.md new file mode 100644 index 0000000000..0e0a7e1d3c --- /dev/null +++ b/INSTALL.md @@ -0,0 +1,170 @@ +# Installing PostCSS Custom Properties + +[PostCSS Custom Properties] runs in all Node environments, with special instructions for: + +| [Node](#node) | [PostCSS CLI](#postcss-cli) | [Webpack](#webpack) | [Create React App](#create-react-app) | [Gulp](#gulp) | [Grunt](#grunt) | +| --- | --- | --- | --- | --- | --- | + +## Node + +Add [PostCSS Custom Properties] to your project: + +```bash +npm install postcss-custom-properties --save-dev +``` + +Use [PostCSS Custom Properties] to process your CSS: + +```js +const postcssCustomProperties = require('postcss-custom-properties'); + +postcssCustomProperties.process(YOUR_CSS /*, processOptions, pluginOptions */); +``` + +Or use it as a [PostCSS] plugin: + +```js +const postcss = require('postcss'); +const postcssCustomProperties = require('postcss-custom-properties'); + +postcss([ + postcssCustomProperties(/* pluginOptions */) +]).process(YOUR_CSS /*, processOptions */); +``` + +## PostCSS CLI + +Add [PostCSS CLI] to your project: + +```bash +npm install postcss-cli --save-dev +``` + +Use [PostCSS Custom Properties] in your `postcss.config.js` configuration file: + +```js +const postcssCustomProperties = require('postcss-custom-properties'); + +module.exports = { + plugins: [ + postcssCustomProperties(/* pluginOptions */) + ] +} +``` + +## Webpack + +Add [PostCSS Loader] to your project: + +```bash +npm install postcss-loader --save-dev +``` + +Use [PostCSS Custom Properties] in your Webpack configuration: + +```js +const postcssCustomProperties = require('postcss-custom-properties'); + +module.exports = { + module: { + rules: [ + { + test: /\.css$/, + use: [ + 'style-loader', + { loader: 'css-loader', options: { importLoaders: 1 } }, + { loader: 'postcss-loader', options: { + ident: 'postcss', + plugins: () => [ + postcssCustomProperties(/* pluginOptions */) + ] + } } + ] + } + ] + } +} +``` + +## Create React App + +Add [React App Rewired] and [React App Rewire PostCSS] to your project: + +```bash +npm install react-app-rewired react-app-rewire-postcss --save-dev +``` + +Use [React App Rewire PostCSS] and [PostCSS Custom Properties] in your +`config-overrides.js` file: + +```js +const reactAppRewirePostcss = require('react-app-rewire-postcss'); +const postcssCustomProperties = require('postcss-custom-properties'); + +module.exports = config => reactAppRewirePostcss(config, { + plugins: () => [ + postcssCustomProperties(/* pluginOptions */) + ] +}); +``` + +## Gulp + +Add [Gulp PostCSS] to your project: + +```bash +npm install gulp-postcss --save-dev +``` + +Use [PostCSS Custom Properties] in your Gulpfile: + +```js +const postcss = require('gulp-postcss'); +const postcssCustomProperties = require('postcss-custom-properties'); + +gulp.task('css', () => gulp.src('./src/*.css').pipe( + postcss([ + postcssCustomProperties(/* pluginOptions */) + ]) +).pipe( + gulp.dest('.') +)); +``` + +## Grunt + +Add [Grunt PostCSS] to your project: + +```bash +npm install grunt-postcss --save-dev +``` + +Use [PostCSS Custom Properties] in your Gruntfile: + +```js +const postcssCustomProperties = require('postcss-custom-properties'); + +grunt.loadNpmTasks('grunt-postcss'); + +grunt.initConfig({ + postcss: { + options: { + use: [ + postcssCustomProperties(/* pluginOptions */) + ] + }, + dist: { + src: '*.css' + } + } +}); +``` + +[Gulp PostCSS]: https://github.com/postcss/gulp-postcss +[Grunt PostCSS]: https://github.com/nDmitry/grunt-postcss +[PostCSS]: https://github.com/postcss/postcss +[PostCSS CLI]: https://github.com/postcss/postcss-cli +[PostCSS Loader]: https://github.com/postcss/postcss-loader +[PostCSS Custom Properties]: https://github.com/postcss/postcss-custom-properties +[React App Rewire PostCSS]: https://github.com/csstools/react-app-rewire-postcss +[React App Rewired]: https://github.com/timarney/react-app-rewired diff --git a/LICENSE b/LICENSE.md similarity index 50% rename from LICENSE rename to LICENSE.md index 84a7d54928..6d70470888 100644 --- a/LICENSE +++ b/LICENSE.md @@ -1,20 +1,21 @@ -The MIT License (MIT) +# The MIT License (MIT) -Copyright (c) 2017 Maxime Thirouin, Nicolas Gallagher & TJ Holowaychuk +Copyright © PostCSS 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: +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. +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. diff --git a/README.md b/README.md index b24e8a80c0..33c9038136 100755 --- a/README.md +++ b/README.md @@ -1,14 +1,14 @@ -# PostCSS Custom Properties [PostCSS Logo][postcss] +# PostCSS Custom Properties [PostCSS][postcss] [![NPM Version][npm-img]][npm-url] [![CSS Standard Status][css-img]][css-url] [![Build Status][cli-img]][cli-url] [![Support Chat][git-img]][git-url] -[PostCSS Custom Properties] lets you use CSS Custom Properties in CSS, following -the [CSS Custom Properties for Cascading Variables] specification. +[PostCSS Custom Properties] lets you use Custom Properties in CSS, following +the [CSS Custom Properties] specification. -```css +```pcss :root { --color: red; } @@ -31,183 +31,51 @@ h1 { ## Usage -Add [PostCSS Custom Properties] to your build tool: +Add [PostCSS Custom Properties] to your project: ```bash npm install postcss-custom-properties --save-dev ``` -#### Node - Use [PostCSS Custom Properties] to process your CSS: ```js -import postCSSCustomProperties from 'postcss-custom-properties'; - -postCSSCustomProperties.process(YOUR_CSS); -``` - -#### PostCSS - -Add [PostCSS] to your build tool: +const postcssCustomProperties = require('postcss-custom-properties'); -```bash -npm install postcss --save-dev +postcssCustomProperties.process(YOUR_CSS /*, processOptions, pluginOptions */); ``` -Use [PostCSS Custom Properties] as a plugin: +Or use it as a [PostCSS] plugin: ```js -import postcss from 'gulp-postcss'; -import postCSSCustomProperties from 'postcss-custom-properties'; +const postcss = require('postcss'); +const postcssCustomProperties = require('postcss-custom-properties'); postcss([ - postCSSCustomProperties() -]).process(YOUR_CSS); -``` - -#### Gulp - -Add [Gulp PostCSS] to your build tool: - -```bash -npm install gulp-postcss --save-dev -``` - -Use [PostCSS Custom Properties] in your Gulpfile: - -```js -import postcss from 'gulp-postcss'; -import postCSSCustomProperties from 'postcss-custom-properties'; - -gulp.task('css', () => gulp.src('./src/*.css').pipe( - postcss([ - postCSSCustomProperties() - ]) -).pipe( - gulp.dest('.') -)); -``` - -#### Grunt - -Add [Grunt PostCSS] to your build tool: - -```bash -npm install grunt-postcss --save-dev + postcssCustomProperties(/* pluginOptions */) +]).process(YOUR_CSS /*, processOptions */); ``` -Use [PostCSS Custom Properties] in your Gruntfile: - -```js -import postCSSCustomProperties from 'postcss-custom-properties'; +[PostCSS Custom Properties] runs in all Node environments, with special instructions for: -grunt.loadNpmTasks('grunt-postcss'); - -grunt.initConfig({ - postcss: { - options: { - use: [ - postCSSCustomProperties() - ] - }, - dist: { - src: '*.css' - } - } -}); -``` +| [Node](INSTALL.md#node) | [PostCSS CLI](INSTALL.md#postcss-cli) | [Webpack](INSTALL.md#webpack) | [Create React App](INSTALL.md#create-react-app) | [Gulp](INSTALL.md#gulp) | [Grunt](INSTALL.md#grunt) | +| --- | --- | --- | --- | --- | --- | ## Options -### strict - -The `strict` option determines whether a `var()` function should transform into -its specified fallback value. By default, the option is `true` because this -plugin can not verify if the computed `:root` value is valid or not. - -```css -:root { - --color: red; -} - -div { - color: var(--color, blue); -} - -/* becomes */ - -:root { - --color: red; -} - -div { - color: blue; - color: var(--color, blue); -} -``` - ### preserve -The `preserve` option determines how Custom Properties should be preserved. By -default, this option is truthy and preserves declarations containing `var()`. - -```css -:root { - --color: red; -} - -h1 { - color: var(--color); -} - -/* becomes */ - -:root { - --color: red; -} - -h1 { - color: red; - color: var(--color); -} -``` - -The option may also be set to `false`, where Custom Properties and declarations -containing `var()` will be removed: +The `preserve` option determines whether Custom Properties and properties using +custom properties should be preserved in their original form. By default, both +of these are preserved. ```js -postCSSCustomProperties({ +postcssCustomProperties({ preserve: false -}) -``` - -```css -:root { - --color: red; -} - -h1 { - color: var(--color); -} - -/* becomes */ - -h1 { - color: red; -} -``` - -The option may also be set to `"computed"`, where Custom Properties -will remain, but declarations containing `var()` will be removed: - -```js -postCSSCustomProperties({ - preserve: 'computed' -}) +}); ``` -```css +```pcss :root { --color: red; } @@ -218,29 +86,24 @@ h1 { /* becomes */ -:root { - --color: red; -} - h1 { color: red; } ``` -### variables +### importFrom -The `variables` option allows you to pass an object of variables into CSS, as if -they had been specified on `:root`. +The `importFrom` option specifies sources where Custom Properties can be imported +from, which might be CSS, JS, and JSON files, functions, and directly passed +objects. ```js -postCSSCustomProperties({ - variables: { - color: 'red' - } -}) +postcssCustomProperties({ + importFrom: 'path/to/file.css' // => :root { --color: red } +}); ``` -```css +```pcss h1 { color: var(--color); } @@ -249,126 +112,75 @@ h1 { h1 { color: red; - color: var(--color); } ``` -Note that these definitions will override any that exist in the CSS, and that -the keys will be automatically prefixed (`--`) to make it easier to share -variables in your codebase. - -### appendVariables - -The `appendVariables` option determines whether Custom Properties will be -appended to your CSS file. By default, this option is `false`. - -If enabled when `preserve` is set to `true` or `"computed"`, this option allows -you to append your variables at the end of your CSS: +Multiple sources can be passed into this option, and they will be parsed in the +order they are received. JavaScript files, JSON files, functions, and objects +will need to namespace Custom Properties using the `customProperties` or +`custom-properties` key. ```js -postCSSCustomProperties({ - appendVariables: true, - variables: { - color: 'red' - } -}) -``` - -```css -h1 { - color: var(--color); -} - -/* becomes */ - -h1 { - color: red; - color: var(--color); -} +postcssCustomProperties({ + importFrom: [ + 'path/to/file.css', + 'and/then/this.js', + 'and/then/that.json', + { + customProperties: { '--color': 'red' } + }, + () => { + const customProperties = { '--color': 'red' }; -:root { - --color: red; -} + return { customProperties }; + } + ] +}); ``` -### warnings +### exportTo -The `warnings` option determines whether Custom Property related warnings should -be logged by the plugin or not. By default, warnings are set to `false` and are -not logged. - -If enabled, the plugin will enable all warnings: +The `exportTo` option specifies destinations where Custom Properties can be exported +to, which might be CSS, JS, and JSON files, functions, and directly passed +objects. ```js -postCSSCustomProperties({ - warnings: true -}) -``` - -```css -h1 { - color: var(--color); -} -``` - -``` -variable '--color' is undefined and used without a fallback +postcssCustomProperties({ + exportTo: 'path/to/file.css' // :root { --color: red; } +}); ``` -### noValueNotifications +Multiple destinations can be passed into this option, and they will be parsed +in the order they are received. JavaScript files, JSON files, and objects will +need to namespace Custom Properties using the `customProperties` or +`custom-properties` key. -When warnings are enabled, the `noValueNotifications` option determines whether -undefined variables will throw a warning or an error. By default, it is set to -`warning`. - ---- - -## Notes - -As written in the specification, usage of `var()` is limited to property values. -Do not expect the plugin to transform `var()` in media queries or in selectors. - -The transformation of Custom Properties done by this plugin _is not complete_ -and **cannot be** because dynamic *cascading* variables based on custom -properties relies on the DOM tree. Since we do not know the DOM in the context -of this plugin, we cannot produce safe output. This plugin currently aims to -provide a future-proof way of using a **limited subset** of the features -provided by native CSS custom properties. - -There is a separate plugin, [PostCSS CSS Variables], that attempts to guess the -context of Custom Properties without access to the DOM tree. This does not -[reflecting the specifications](https://github.com/MadLittleMods/postcss-css-variables/issues/4), -so be sure you understand the risks before you decide to use it. - -## Contributing - -Fork, work on a branch, install dependencies & run tests before submitting a PR. - -```bash -$ git clone https://github.com/YOU/postcss-custom-properties.git -$ git checkout -b patch-1 -$ npm install -$ npm test +```js +const cachedObject = { customProperties: {} }; + +postcssCustomProperties({ + exportTo: [ + 'path/to/file.css', // :root { --color: red; } + 'and/then/this.js', // module.exports = { customProperties: { '--color': 'red' } } + 'and/then/this.mjs', // export const customProperties = { '--color': 'red' } } + 'and/then/that.json', // { "custom-properties": { "--color": "red" } } + cachedObject, + customProperties => { + customProperties // { '--color': 'red' } + } + ] +}); ``` ---- - -## [Changelog](CHANGELOG.md) - -## [License](LICENSE) - -[npm-url]: https://www.npmjs.com/package/postcss-custom-properties -[npm-img]: https://img.shields.io/npm/v/postcss-custom-properties.svg -[css-url]: https://cssdb.org/#css-variables -[css-img]: https://cssdb.org/badge/custom-properties.svg -[cli-url]: https://travis-ci.org/postcss/postcss-custom-properties [cli-img]: https://img.shields.io/travis/postcss/postcss-custom-properties.svg -[git-url]: https://gitter.im/postcss/postcss +[cli-url]: https://travis-ci.org/postcss/postcss-custom-properties +[css-img]: https://cssdb.org/badge/custom-properties.svg +[css-url]: https://cssdb.org/#custom-properties [git-img]: https://img.shields.io/badge/support-chat-blue.svg +[git-url]: https://gitter.im/postcss/postcss +[npm-img]: https://img.shields.io/npm/v/postcss-custom-properties.svg +[npm-url]: https://www.npmjs.com/package/postcss-custom-properties -[CSS Custom Properties for Cascading Variables]: https://www.w3.org/TR/css-variables-1/ -[PostCSS CSS Variables]: https://github.com/MadLittleMods/postcss-css-variables -[PostCSS Custom Properties]: https://github.com/postcss/postcss-custom-properties +[CSS Custom Properties]: https://www.w3.org/TR/css-variables-1/ [PostCSS]: https://github.com/postcss/postcss -[Gulp PostCSS]: https://github.com/postcss/gulp-postcss -[Grunt PostCSS]: https://github.com/nDmitry/grunt-postcss +[PostCSS Custom Properties]: https://github.com/postcss/postcss-custom-properties diff --git a/index.js b/index.js index 48824c96d0..35a4a5459d 100755 --- a/index.js +++ b/index.js @@ -1,347 +1,30 @@ -import postcss from "postcss" -import balanced from "balanced-match" +import postcss from 'postcss'; +import getCustomProperties from './lib/get-custom-properties'; +import transformProperties from './lib/transform-properties'; +import importCustomPropertiesFromSources from './lib/import-from'; +import exportCustomPropertiesToDestinations from './lib/export-to'; -const VAR_PROP_IDENTIFIER = "--" -const VAR_FUNC_IDENTIFIER = "var" -const VAR_FUNC_REGEX = /(^|[^\w-])var\(/ -// matches `name[, fallback]`, captures "name" and "fallback" -const RE_VAR = /[\f\n\r\t ]*([\w-]+)(?:[\f\n\r\t ]*,[\f\n\r\t ]*([\W\w]+))?/ +export default postcss.plugin('postcss-custom-properties', opts => { + // whether to preserve custom selectors and rules using them + const preserve = 'preserve' in Object(opts) ? Boolean(opts.preserve) : true; -/** - * Module variables - */ + // sources to import custom selectors from + const importFrom = [].concat(Object(opts).importFrom || []); -let globalOpts + // destinations to export custom selectors to + const exportTo = [].concat(Object(opts).exportTo || []); -/** - * Resolve CSS variables. - * - * The second argument to the CSS variable function, var(name[, fallback]), - * is used in the event that first argument cannot be resolved. - * - * @param {String} value May contain the CSS variable function - * @param {Object} variables A map of variable names and values - * @param {Object} result The PostCSS result object - * @param {Object} decl The declaration containing the rule - * @return {String} A property value with all CSS variables substituted. - */ -function resolveValue(value, variables, result, decl) { - const results = [] + // promise any custom selectors are imported + const customPropertiesPromise = importCustomPropertiesFromSources(importFrom); - const hasVarFunction = VAR_FUNC_REGEX.test(value) + return async root => { + const customProperties = Object.assign( + await customPropertiesPromise, + getCustomProperties(root, { preserve }) + ); - if (!hasVarFunction) { - return [value] - } + await exportCustomPropertiesToDestinations(customProperties, exportTo); - const match = value.match(VAR_FUNC_REGEX) - const start = match.index + match[1].length - - const matches = balanced("(", ")", value.substring(start)) - - if (!matches) { - throw decl.error(`missing closing ')' in the value '${value}'`) - } - - if (matches.body === "") { - throw decl.error("var() must contain a non-whitespace string") - } - - matches.body.replace(RE_VAR, function(_, name, fallback) { - const variable = variables[name] - let post - // undefined and without fallback, just keep original value - if (!variable && !fallback) { - assert( - "no-value-notifications", false, - `variable '${name}' is undefined and used without a fallback`, - {decl, result, word: name} - ) - - post = matches.post - ? resolveValue(matches.post, variables, result, decl) - : [""] - // resolve the end of the expression - post.forEach(function(afterValue) { - results.push( - value.slice(0, start) + - VAR_FUNC_IDENTIFIER + "(" + name + ")" + afterValue - ) - }) - return - } - - // prepend with fallbacks - if (fallback) { - // resolve fallback values - fallback = resolveValue(fallback, variables, result, decl) - // resolve the end of the expression before the rest - post = matches.post - ? resolveValue(matches.post, variables, result, decl) - : [""] - fallback.forEach((fbValue) => { - post.forEach((afterValue) => { - results.push(value.slice(0, start) + fbValue + afterValue) - }) - }) - } - - if (!variable) { - return - } - - // replace with computed custom properties - if (!variable.resolved) { - // circular reference encountered - if (variable.deps.indexOf(name) !== -1) { - if (!fallback) { - assert( - "circular-reference", false, - `Circular variable reference: ${name}`, - {decl, result, word: name} - ) - - variable.value = [variable.value] - variable.circular = true - } - else { - variable.value = fallback - return - } - } - else { - variable.deps.push(name) - variable.value = resolveValue(variable.value, variables, result, decl) - } - variable.resolved = true - } - if (variable.circular && fallback) { - return - } - // resolve the end of the expression - post = matches.post - ? resolveValue(matches.post, variables, result, decl) - : [""] - variable.value.forEach((replacementValue) => { - post.forEach((afterValue) => { - results.push(value.slice(0, start) + replacementValue + afterValue) - }) - }) - }) - - return results -} - -function prefixVariables(variables) { - const prefixedVariables = {} - - if (!variables) { - return prefixedVariables - } - - Object.keys(variables).forEach((name) => { - const val = variables[name] - if (name.slice(0, 2) !== "--") { - name = "--" + name - } - prefixedVariables[name] = String(val) - }) - - return prefixedVariables -} - -/** - * Define an assertion that will print a warning or throw an exception - * if the condition is not met. - * - * @param {String} ruleName Name of the rule in `options.warnings`. - * @param {Boolean} condition Must be truthy for the assertion to pass. - * @param {String} message Text of the warning or error if the assertion fails. - * @param {Object} context PostCSS context objects: decl, result and - * warning (error) options. - */ -function assert(ruleName, condition, message, { - decl, result, word, index, plugin, -}) { - if (condition || !globalOpts.warnings) { - return - } - - if (globalOpts.warnings === true || globalOpts.warnings[ruleName] === true) { - result.warn(message, {node: decl, word, index, plugin}) - } - else if (globalOpts.warnings[ruleName] === "error") { - decl = decl || result.root.first - throw decl.error(message, {word, index, plugin}) - } -} - -/** - * Module export. - */ -export default postcss.plugin("postcss-custom-properties", (options = {}) => { - - function setVariables(variables) { - options.variables = prefixVariables(variables) - } - - function plugin(style, result) { - const variables = prefixVariables(options.variables) - const strict = "strict" in options ? Boolean(options.strict) : true - const appendVariables = "appendVariables" in options - ? Boolean(options.appendVariables) : false - const preserve = "preserve" in options ? options.preserve : true - const map = {} - const importantMap = {} - - globalOpts = { - warnings: options.warnings, - } - - if ("noValueNotifications" in options) { - result.warn( - "'noValueNotifications' is deprecated. Use " - + "\"options.warnings['no-value-notifications']: true|false|'error'\"" - + "instead." - ) - - if (typeof globalOpts.warnings === "object") { - globalOpts.warnings["no-value-notifications"] = - options.noValueNotifications === "error" ? "error" : true - } - else if (globalOpts.warnings === true - && options.noValueNotifications === "error") { - globalOpts.warnings = { - "no-value-notifications": "error", - "not-scoped-to-root": true, - "circular-reference": true, - } - } - } - - // define variables - style.walkRules((rule) => { - const toRemove = [] - - // only variables declared for `:root` are supported for now - if ( - rule.selectors.length !== 1 || - rule.selectors[0] !== ":root" || - rule.parent.type !== "root" - ) { - rule.each((decl) => { - const prop = decl.prop - assert( - "not-scoped-to-root", - !prop || prop.indexOf(VAR_PROP_IDENTIFIER) !== 0, - "Custom property ignored: not scoped to the top-level :root " + - `element (${rule.selectors} { ... ${prop}: ... })` + - (rule.parent.type !== "root" ? ", in " + rule.parent.type : ""), - {decl, result} - ) - }) - return - } - - rule.each((decl, index) => { - const prop = decl.prop - if (prop && prop.indexOf(VAR_PROP_IDENTIFIER) === 0) { - if (!map[prop] || !importantMap[prop] || decl.important) { - map[prop] = { - value: decl.value, - deps: [], - circular: false, - resolved: false, - } - importantMap[prop] = decl.important - } - toRemove.push(index) - } - }) - - // optionally remove `--*` properties from the rule - if (!preserve) { - for (let i = toRemove.length - 1; i >= 0; i--) { - rule.nodes.splice(toRemove[i], 1) - } - - // remove empty :root {} - if (rule.nodes.length === 0) { - rule.remove() - } - } - }) - - // apply js-defined custom properties - Object.keys(variables).forEach((variable) => { - map[variable] = { - value: variables[variable], - deps: [], - circular: false, - resolved: false, - } - }) - - if (preserve) { - Object.keys(map).forEach((name) => { - const variable = map[name] - if (!variable.resolved) { - variable.value = resolveValue(variable.value, map, result) - variable.resolved = true - } - }) - } - - // resolve variables - style.walkDecls((decl) => { - const value = decl.raws.value ? decl.raws.value.raw : decl.value - - // skip values that don’t contain variable functions - if (!value || value.indexOf(VAR_FUNC_IDENTIFIER + "(") === -1) { - return - } - - let resolved = resolveValue(value, map, result, decl) - if (!strict) { - resolved = [resolved.pop()] - } - resolved.forEach((resolvedValue) => { - const clone = decl.cloneBefore() - clone.value = resolvedValue - }) - - if (!preserve || preserve === "computed") { - decl.remove() - } - }) - - if (preserve && variables && appendVariables) { - const names = Object.keys(map) - if (names.length) { - const container = postcss.rule({ - selector: ":root", - raws: {semicolon: true}, - }) - names - .filter((name) => variables.hasOwnProperty(name)) - .forEach((name) => { - const variable = map[name] - let val = variable.value - if (variable.resolved) { - val = val[val.length - 1] - } - const decl = postcss.decl({ - prop: name, - value: val, - }) - container.append(decl) - }) - style.append(container) - } - } - } - - plugin.setVariables = setVariables - - return plugin -}) + transformProperties(root, customProperties, { preserve }); + }; +}); diff --git a/lib/export-to.js b/lib/export-to.js new file mode 100644 index 0000000000..ac9d7f138c --- /dev/null +++ b/lib/export-to.js @@ -0,0 +1,129 @@ +import fs from 'fs'; +import path from 'path'; + +/* Export Custom Properties to CSS File +/* ========================================================================== */ + +async function exportCustomPropertiesToCssFile(to, customProperties) { + const cssContent = Object.keys(customProperties).reduce((cssLines, name) => { + cssLines.push(`\t${name}: ${customProperties[name]};`); + + return cssLines; + }, []).join('\n'); + const css = `:root {\n${cssContent}\n}\n`; + + await writeFile(to, css); +} + +/* Export Custom Properties to JSON file +/* ========================================================================== */ + +async function exportCustomPropertiesToJsonFile(to, customProperties) { + const jsonContent = JSON.stringify({ + 'custom-properties': customProperties + }, null, ' '); + const json = `${jsonContent}\n`; + + await writeFile(to, json); +} + +/* Export Custom Properties to Common JS file +/* ========================================================================== */ + +async function exportCustomPropertiesToCjsFile(to, customProperties) { + const jsContents = Object.keys(customProperties).reduce((jsLines, name) => { + jsLines.push(`\t\t'${escapeForJS(name)}': '${escapeForJS(customProperties[name])}'`); + + return jsLines; + }, []).join(',\n'); + const js = `module.exports = {\n\tcustomProperties: {\n${jsContents}\n\t}\n};\n`; + + await writeFile(to, js); +} + +/* Export Custom Properties to Module JS file +/* ========================================================================== */ + +async function exportCustomPropertiesToMjsFile(to, customProperties) { + const mjsContents = Object.keys(customProperties).reduce((mjsLines, name) => { + mjsLines.push(`\t'${escapeForJS(name)}': '${escapeForJS(customProperties[name])}'`); + + return mjsLines; + }, []).join(',\n'); + const mjs = `export const customProperties = {\n${mjsContents}\n};\n`; + + await writeFile(to, mjs); +} + +/* Export Custom Properties to Destinations +/* ========================================================================== */ + +export default function exportCustomPropertiesToDestinations(customProperties, destinations) { + return Promise.all(destinations.map(async destination => { + if (destination instanceof Function) { + await destination(defaultCustomPropertiesToJSON(customProperties)); + } else { + // read the destination as an object + const opts = destination === Object(destination) ? destination : { to: String(destination) }; + + // transformer for Custom Properties into a JSON-compatible object + const toJSON = opts.toJSON || defaultCustomPropertiesToJSON; + + if ('customProperties' in opts) { + // write directly to an object as customProperties + opts.customProperties = toJSON(customProperties); + } else if ('custom-properties' in opts) { + // write directly to an object as custom-properties + opts['custom-properties'] = toJSON(customProperties); + } else { + // destination pathname + const to = String(opts.to || ''); + + // type of file being written to + const type = (opts.type || path.extname(opts.to).slice(1)).toLowerCase(); + + // transformed Custom Properties + const customPropertiesJSON = toJSON(customProperties); + + if (type === 'css') { + await exportCustomPropertiesToCssFile(to, customPropertiesJSON); + } + + if (type === 'js') { + await exportCustomPropertiesToCjsFile(to, customPropertiesJSON); + } + + if (type === 'json') { + await exportCustomPropertiesToJsonFile(to, customPropertiesJSON); + } + + if (type === 'mjs') { + await exportCustomPropertiesToMjsFile(to, customPropertiesJSON); + } + } + } + })); +} + +/* Helper utilities +/* ========================================================================== */ + +const defaultCustomPropertiesToJSON = customProperties => { + return Object.keys(customProperties).reduce((customPropertiesJSON, key) => { + customPropertiesJSON[key] = String(customProperties[key]); + + return customPropertiesJSON; + }, {}); +}; + +const writeFile = (to, text) => new Promise((resolve, reject) => { + fs.writeFile(to, text, error => { + if (error) { + reject(error); + } else { + resolve(); + } + }); +}); + +const escapeForJS = string => string.replace(/\\([\s\S])|(')/g, '\\$1$2').replace(/\n/g, '\\n').replace(/\r/g, '\\r'); diff --git a/lib/get-custom-properties.js b/lib/get-custom-properties.js new file mode 100644 index 0000000000..c60fbd56eb --- /dev/null +++ b/lib/get-custom-properties.js @@ -0,0 +1,57 @@ +import valueParser from 'postcss-values-parser'; + +// return custom selectors from the css root, conditionally removing them +export default function getCustomProperties(root, opts) { + // initialize custom selectors + const customPropertiesFromHtmlElement = {}; + const customPropertiesFromRootPsuedo = {}; + + // for each html or :root rule + root.nodes.slice().forEach(rule => { + const customPropertiesObject = isHtmlRule(rule) + ? customPropertiesFromHtmlElement + : isRootRule(rule) + ? customPropertiesFromRootPsuedo + : null; + + // for each custom property + if (customPropertiesObject) { + rule.nodes.slice().forEach(decl => { + if (isCustomDecl(decl)) { + const { prop } = decl; + + // write the parsed value to the custom property + customPropertiesObject[prop] = valueParser(decl.value).parse().nodes; + + // conditionally remove the custom property declaration + if (!opts.preserve) { + decl.remove(); + } + } + }); + + // conditionally remove the empty html or :root rule + if (!opts.preserve && isEmptyParent(rule)) { + rule.remove(); + } + } + }); + + // return all custom properties, preferring :root properties over html properties + return { ...customPropertiesFromHtmlElement, ...customPropertiesFromRootPsuedo }; +} + +// match html and :root rules +const htmlSelectorRegExp = /^html$/i; +const rootSelectorRegExp = /^:root$/i; +const customPropertyRegExp = /^--[A-z][\w-]*$/; + +// whether the node is an html or :root rule +const isHtmlRule = node => node.type === 'rule' && htmlSelectorRegExp.test(node.selector) && Object(node.nodes).length; +const isRootRule = node => node.type === 'rule' && rootSelectorRegExp.test(node.selector) && Object(node.nodes).length; + +// whether the node is an custom property +const isCustomDecl = node => node.type === 'decl' && customPropertyRegExp.test(node.prop); + +// whether the node is a parent without children +const isEmptyParent = node => Object(node.nodes).length === 0; diff --git a/lib/import-from.js b/lib/import-from.js new file mode 100644 index 0000000000..a5c918a38b --- /dev/null +++ b/lib/import-from.js @@ -0,0 +1,120 @@ +import fs from 'fs'; +import path from 'path'; +import postcss from 'postcss'; +import valueParser from 'postcss-values-parser'; +import getCustomProperties from './get-custom-properties'; + +/* Import Custom Properties from CSS AST +/* ========================================================================== */ + +function importCustomPropertiesFromCSSAST(root) { + return getCustomProperties(root, { preserve: true }); +} + +/* Import Custom Properties from CSS File +/* ========================================================================== */ + +async function importCustomPropertiesFromCSSFile(from) { + const css = await readFile(path.resolve(from)); + const root = postcss.parse(css, { from: path.resolve(from) }); + + return importCustomPropertiesFromCSSAST(root); +} + +/* Import Custom Properties from Object +/* ========================================================================== */ + +function importCustomPropertiesFromObject(object) { + const customProperties = Object.assign( + {}, + Object(object).customProperties || Object(object)['custom-properties'] + ); + + for (const key in customProperties) { + customProperties[key] = valueParser(customProperties[key]).parse().nodes; + } + + return customProperties; +} + +/* Import Custom Properties from JSON file +/* ========================================================================== */ + +async function importCustomPropertiesFromJSONFile(from) { + const object = await readJSON(path.resolve(from)); + + return importCustomPropertiesFromObject(object); +} + +/* Import Custom Properties from JS file +/* ========================================================================== */ + +async function importCustomPropertiesFromJSFile(from) { + const object = await import(path.resolve(from)); + + return importCustomPropertiesFromObject(object); +} + +/* Import Custom Properties from Sources +/* ========================================================================== */ + +export default function importCustomPropertiesFromSources(sources) { + return sources.map(source => { + if (source instanceof Promise) { + return source; + } else if (source instanceof Function) { + return source(); + } + + // read the source as an object + const opts = source === Object(source) ? source : { from: String(source) }; + + // skip objects with Custom Properties + if (opts.customProperties || opts['custom-properties']) { + return opts + } + + // source pathname + const from = String(opts.from || ''); + + // type of file being read from + const type = (opts.type || path.extname(opts.from).slice(1)).toLowerCase(); + + return { type, from }; + }).reduce(async (customProperties, source) => { + const { type, from } = await source; + + if (type === 'ast') { + return Object.assign(customProperties, importCustomPropertiesFromCSSAST(from)); + } + + if (type === 'css') { + return Object.assign(customProperties, await importCustomPropertiesFromCSSFile(from)); + } + + if (type === 'js') { + return Object.assign(customProperties, await importCustomPropertiesFromJSFile(from)); + } + + if (type === 'json') { + return Object.assign(customProperties, await importCustomPropertiesFromJSONFile(from)); + } + + return Object.assign(customProperties, importCustomPropertiesFromObject(await source)); + }, {}); +} + +/* Helper utilities +/* ========================================================================== */ + +const readFile = from => new Promise((resolve, reject) => { + fs.readFile(from, 'utf8', (error, result) => { + if (error) { + reject(error); + } else { + resolve(result); + } + }); +}); + +const readJSON = async from => JSON.parse(await readFile(from)); diff --git a/lib/transform-properties.js b/lib/transform-properties.js new file mode 100644 index 0000000000..283fd100c9 --- /dev/null +++ b/lib/transform-properties.js @@ -0,0 +1,35 @@ +import valueParser from 'postcss-values-parser'; +import transformValueAST from './transform-value-ast'; + +// transform custom pseudo selectors with custom selectors +export default (root, customProperties, opts) => { + // walk decls that can be transformed + root.walkDecls(decl => { + if (isTransformableDecl(decl)) { + const originalValue = decl.value; + const valueAST = valueParser(originalValue).parse(); + const value = String(transformValueAST(valueAST, customProperties)); + + // conditionally transform values that have changed + if (value !== originalValue) { + if (opts.preserve) { + decl.cloneBefore({ value }); + } else { + decl.value = value; + } + } + } + }); +}; + +// match html and :root rules +const htmlOrRootSelectorRegExp = /^(html|:root)$/i; + +// match custom property inclusions +const customPropertiesRegExp = /(^|[^\w-])var\([\W\w]+\)/; + +// whether the declaration has a parent rule that is either html or :root +const isDeclChildOfHtmlOrRootRule = decl => Object(decl.parent).type === 'rule' && htmlOrRootSelectorRegExp.test(decl.parent.selector); + +// whether the declaration should be potentially transformed +const isTransformableDecl = decl => customPropertiesRegExp.test(decl.value) && !isDeclChildOfHtmlOrRootRule(decl); diff --git a/lib/transform-value-ast.js b/lib/transform-value-ast.js new file mode 100644 index 0000000000..f4897ef3b4 --- /dev/null +++ b/lib/transform-value-ast.js @@ -0,0 +1,50 @@ +export default function transformValueAST(root, customProperties) { + if (root.nodes && root.nodes.length) { + root.nodes.slice().forEach(child => { + if (isVarFunction(child)) { + // eslint-disable-next-line no-unused-vars + const [propertyNode, comma, ...fallbacks] = child.nodes.slice(1, -1); + const { value: name } = propertyNode; + + if (name in customProperties) { + // conditionally replace a known custom property + child.replaceWith( + ...asClonedArray(customProperties[name]) + ); + + const nextCustomProperties = Object.assign({}, customProperties); + + delete nextCustomProperties[name]; + + transformValueAST(root, nextCustomProperties); + } else if (fallbacks.length) { + // conditionally replace a custom property with a fallback + const clonedFallbacks = asClonedArray(fallbacks); + + Object.assign(clonedFallbacks[0].raws, { before: '' }); + + child.replaceWith(...clonedFallbacks); + + const nextCustomProperties = Object.assign({}, customProperties); + + delete nextCustomProperties[name]; + + transformValueAST(root, nextCustomProperties); + } + } else { + transformValueAST(child, customProperties); + } + }) + } + + return root; +} + +// match var() functions +const varRegExp = /^var$/i; + +// whether the node is a var() function +const isVarFunction = node => node.type === 'func' && varRegExp.test(node.value) && Object(node.nodes).length > 0; + +// return an array with its nodes cloned +const asClonedArray = array => array.map(node => node.clone()); diff --git a/package-lock.json b/package-lock.json deleted file mode 100644 index c04923956b..0000000000 --- a/package-lock.json +++ /dev/null @@ -1,3692 +0,0 @@ -{ - "name": "postcss-custom-properties", - "version": "7.0.0", - "lockfileVersion": 1, - "requires": true, - "dependencies": { - "@octokit/rest": { - "version": "14.0.9", - "resolved": "https://registry.npmjs.org/@octokit/rest/-/rest-14.0.9.tgz", - "integrity": "sha512-irP9phKfTXEZIcW2R+VNCtGHZJrXMWmSYp6RRfFn4BtAqtDRXF5z9JxCEQlAhNBf6X1koNi5k49tIAAAEJNlVQ==", - "dev": true, - "requires": { - "before-after-hook": "^1.1.0", - "debug": "^3.1.0", - "is-array-buffer": "^1.0.0", - "is-stream": "^1.1.0", - "lodash": "^4.17.4", - "url-template": "^2.0.8" - }, - "dependencies": { - "debug": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", - "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - } - } - }, - "@sindresorhus/df": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/@sindresorhus/df/-/df-2.1.0.tgz", - "integrity": "sha1-0gjPJ+BvC7R20U197M19cm6ao4k=", - "dev": true, - "requires": { - "execa": "^0.2.2" - } - }, - "acorn": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-5.7.1.tgz", - "integrity": "sha512-d+nbxBUGKg7Arpsvbnlq61mc12ek3EY8EQldM3GPAhWJ1UVxC6TDGbIvUMNU6obBX3i1+ptCIzV4vq0gFPEGVQ==", - "dev": true - }, - "acorn-jsx": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-4.1.1.tgz", - "integrity": "sha512-JY+iV6r+cO21KtntVvFkD+iqjtdpRUpGqKWgfkCdZq1R+kbreEl8EcdcJR4SmiIgsIQT33s6QzheQ9a275Q8xw==", - "dev": true, - "requires": { - "acorn": "^5.0.3" - } - }, - "ajv": { - "version": "6.5.2", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.5.2.tgz", - "integrity": "sha512-hOs7GfvI6tUI1LfZddH82ky6mOMyTuY0mk7kE2pWpmhhUSkumzaTO5vbVwij39MdwPQWCV4Zv57Eo06NtL/GVA==", - "dev": true, - "requires": { - "fast-deep-equal": "^2.0.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.1" - } - }, - "ajv-keywords": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.2.0.tgz", - "integrity": "sha1-6GuBnGAs+IIa1jdBNpjx3sAhhHo=", - "dev": true - }, - "ansi-escapes": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-3.1.0.tgz", - "integrity": "sha512-UgAb8H9D41AQnu/PbWlCofQVcnV4Gs2bBJi9eZPxfU/hgglFh3SMDMENRIqdr7H6XFnXdoknctFByVsCOotTVw==", - "dev": true - }, - "ansi-regex": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", - "dev": true - }, - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "requires": { - "color-convert": "^1.9.0" - } - }, - "anymatch": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-1.3.2.tgz", - "integrity": "sha512-0XNayC8lTHQ2OI8aljNCN3sSx6hsr/1+rlcDAotXJR7C1oZZHCNsfpbKwMjRA3Uqb5tF1Rae2oloTr4xpq+WjA==", - "dev": true, - "optional": true, - "requires": { - "micromatch": "^2.1.5", - "normalize-path": "^2.0.0" - } - }, - "argparse": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", - "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", - "dev": true, - "requires": { - "sprintf-js": "~1.0.2" - } - }, - "arr-diff": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-2.0.0.tgz", - "integrity": "sha1-jzuCf5Vai9ZpaX5KQlasPOrjVs8=", - "dev": true, - "optional": true, - "requires": { - "arr-flatten": "^1.0.1" - } - }, - "arr-flatten": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/arr-flatten/-/arr-flatten-1.1.0.tgz", - "integrity": "sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==", - "dev": true, - "optional": true - }, - "array-union": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/array-union/-/array-union-1.0.2.tgz", - "integrity": "sha1-mjRBDk9OPaI96jdb5b5w8kd47Dk=", - "dev": true, - "requires": { - "array-uniq": "^1.0.1" - } - }, - "array-uniq": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/array-uniq/-/array-uniq-1.0.3.tgz", - "integrity": "sha1-r2rId6Jcx/dOBYiUdThY39sk/bY=", - "dev": true - }, - "array-unique": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.2.1.tgz", - "integrity": "sha1-odl8yvy8JiXMcPrc6zalDFiwGlM=", - "dev": true, - "optional": true - }, - "arrify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", - "integrity": "sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=", - "dev": true - }, - "async-each": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/async-each/-/async-each-1.0.1.tgz", - "integrity": "sha1-GdOGodntxufByF04iu28xW0zYC0=", - "dev": true, - "optional": true - }, - "babel-cli": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-cli/-/babel-cli-6.26.0.tgz", - "integrity": "sha1-UCq1SHTX24itALiHoGODzgPQAvE=", - "dev": true, - "requires": { - "babel-core": "^6.26.0", - "babel-polyfill": "^6.26.0", - "babel-register": "^6.26.0", - "babel-runtime": "^6.26.0", - "chokidar": "^1.6.1", - "commander": "^2.11.0", - "convert-source-map": "^1.5.0", - "fs-readdir-recursive": "^1.0.0", - "glob": "^7.1.2", - "lodash": "^4.17.4", - "output-file-sync": "^1.1.2", - "path-is-absolute": "^1.0.1", - "slash": "^1.0.0", - "source-map": "^0.5.6", - "v8flags": "^2.1.1" - }, - "dependencies": { - "source-map": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", - "dev": true - } - } - }, - "babel-code-frame": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-code-frame/-/babel-code-frame-6.26.0.tgz", - "integrity": "sha1-Y/1D99weO7fONZR9uP42mj9Yx0s=", - "dev": true, - "requires": { - "chalk": "^1.1.3", - "esutils": "^2.0.2", - "js-tokens": "^3.0.2" - }, - "dependencies": { - "ansi-styles": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", - "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", - "dev": true - }, - "chalk": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", - "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", - "dev": true, - "requires": { - "ansi-styles": "^2.2.1", - "escape-string-regexp": "^1.0.2", - "has-ansi": "^2.0.0", - "strip-ansi": "^3.0.0", - "supports-color": "^2.0.0" - } - }, - "supports-color": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", - "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", - "dev": true - } - } - }, - "babel-core": { - "version": "6.26.3", - "resolved": "https://registry.npmjs.org/babel-core/-/babel-core-6.26.3.tgz", - "integrity": "sha512-6jyFLuDmeidKmUEb3NM+/yawG0M2bDZ9Z1qbZP59cyHLz8kYGKYwpJP0UwUKKUiTRNvxfLesJnTedqczP7cTDA==", - "dev": true, - "requires": { - "babel-code-frame": "^6.26.0", - "babel-generator": "^6.26.0", - "babel-helpers": "^6.24.1", - "babel-messages": "^6.23.0", - "babel-register": "^6.26.0", - "babel-runtime": "^6.26.0", - "babel-template": "^6.26.0", - "babel-traverse": "^6.26.0", - "babel-types": "^6.26.0", - "babylon": "^6.18.0", - "convert-source-map": "^1.5.1", - "debug": "^2.6.9", - "json5": "^0.5.1", - "lodash": "^4.17.4", - "minimatch": "^3.0.4", - "path-is-absolute": "^1.0.1", - "private": "^0.1.8", - "slash": "^1.0.0", - "source-map": "^0.5.7" - }, - "dependencies": { - "source-map": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", - "dev": true - } - } - }, - "babel-generator": { - "version": "6.26.1", - "resolved": "https://registry.npmjs.org/babel-generator/-/babel-generator-6.26.1.tgz", - "integrity": "sha512-HyfwY6ApZj7BYTcJURpM5tznulaBvyio7/0d4zFOeMPUmfxkCjHocCuoLa2SAGzBI8AREcH3eP3758F672DppA==", - "dev": true, - "requires": { - "babel-messages": "^6.23.0", - "babel-runtime": "^6.26.0", - "babel-types": "^6.26.0", - "detect-indent": "^4.0.0", - "jsesc": "^1.3.0", - "lodash": "^4.17.4", - "source-map": "^0.5.7", - "trim-right": "^1.0.1" - }, - "dependencies": { - "source-map": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", - "dev": true - } - } - }, - "babel-helper-builder-binary-assignment-operator-visitor": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-helper-builder-binary-assignment-operator-visitor/-/babel-helper-builder-binary-assignment-operator-visitor-6.24.1.tgz", - "integrity": "sha1-zORReto1b0IgvK6KAsKzRvmlZmQ=", - "dev": true, - "requires": { - "babel-helper-explode-assignable-expression": "^6.24.1", - "babel-runtime": "^6.22.0", - "babel-types": "^6.24.1" - } - }, - "babel-helper-call-delegate": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-helper-call-delegate/-/babel-helper-call-delegate-6.24.1.tgz", - "integrity": "sha1-7Oaqzdx25Bw0YfiL/Fdb0Nqi340=", - "dev": true, - "requires": { - "babel-helper-hoist-variables": "^6.24.1", - "babel-runtime": "^6.22.0", - "babel-traverse": "^6.24.1", - "babel-types": "^6.24.1" - } - }, - "babel-helper-define-map": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-helper-define-map/-/babel-helper-define-map-6.26.0.tgz", - "integrity": "sha1-pfVtq0GiX5fstJjH66ypgZ+Vvl8=", - "dev": true, - "requires": { - "babel-helper-function-name": "^6.24.1", - "babel-runtime": "^6.26.0", - "babel-types": "^6.26.0", - "lodash": "^4.17.4" - } - }, - "babel-helper-explode-assignable-expression": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-helper-explode-assignable-expression/-/babel-helper-explode-assignable-expression-6.24.1.tgz", - "integrity": "sha1-8luCz33BBDPFX3BZLVdGQArCLKo=", - "dev": true, - "requires": { - "babel-runtime": "^6.22.0", - "babel-traverse": "^6.24.1", - "babel-types": "^6.24.1" - } - }, - "babel-helper-function-name": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-helper-function-name/-/babel-helper-function-name-6.24.1.tgz", - "integrity": "sha1-00dbjAPtmCQqJbSDUasYOZ01gKk=", - "dev": true, - "requires": { - "babel-helper-get-function-arity": "^6.24.1", - "babel-runtime": "^6.22.0", - "babel-template": "^6.24.1", - "babel-traverse": "^6.24.1", - "babel-types": "^6.24.1" - } - }, - "babel-helper-get-function-arity": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-helper-get-function-arity/-/babel-helper-get-function-arity-6.24.1.tgz", - "integrity": "sha1-j3eCqpNAfEHTqlCQj4mwMbG2hT0=", - "dev": true, - "requires": { - "babel-runtime": "^6.22.0", - "babel-types": "^6.24.1" - } - }, - "babel-helper-hoist-variables": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-helper-hoist-variables/-/babel-helper-hoist-variables-6.24.1.tgz", - "integrity": "sha1-HssnaJydJVE+rbyZFKc/VAi+enY=", - "dev": true, - "requires": { - "babel-runtime": "^6.22.0", - "babel-types": "^6.24.1" - } - }, - "babel-helper-optimise-call-expression": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-helper-optimise-call-expression/-/babel-helper-optimise-call-expression-6.24.1.tgz", - "integrity": "sha1-96E0J7qfc/j0+pk8VKl4gtEkQlc=", - "dev": true, - "requires": { - "babel-runtime": "^6.22.0", - "babel-types": "^6.24.1" - } - }, - "babel-helper-regex": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-helper-regex/-/babel-helper-regex-6.26.0.tgz", - "integrity": "sha1-MlxZ+QL4LyS3T6zu0DY5VPZJXnI=", - "dev": true, - "requires": { - "babel-runtime": "^6.26.0", - "babel-types": "^6.26.0", - "lodash": "^4.17.4" - } - }, - "babel-helper-remap-async-to-generator": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-helper-remap-async-to-generator/-/babel-helper-remap-async-to-generator-6.24.1.tgz", - "integrity": "sha1-XsWBgnrXI/7N04HxySg5BnbkVRs=", - "dev": true, - "requires": { - "babel-helper-function-name": "^6.24.1", - "babel-runtime": "^6.22.0", - "babel-template": "^6.24.1", - "babel-traverse": "^6.24.1", - "babel-types": "^6.24.1" - } - }, - "babel-helper-replace-supers": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-helper-replace-supers/-/babel-helper-replace-supers-6.24.1.tgz", - "integrity": "sha1-v22/5Dk40XNpohPKiov3S2qQqxo=", - "dev": true, - "requires": { - "babel-helper-optimise-call-expression": "^6.24.1", - "babel-messages": "^6.23.0", - "babel-runtime": "^6.22.0", - "babel-template": "^6.24.1", - "babel-traverse": "^6.24.1", - "babel-types": "^6.24.1" - } - }, - "babel-helpers": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-helpers/-/babel-helpers-6.24.1.tgz", - "integrity": "sha1-NHHenK7DiOXIUOWX5Yom3fN2ArI=", - "dev": true, - "requires": { - "babel-runtime": "^6.22.0", - "babel-template": "^6.24.1" - } - }, - "babel-messages": { - "version": "6.23.0", - "resolved": "https://registry.npmjs.org/babel-messages/-/babel-messages-6.23.0.tgz", - "integrity": "sha1-8830cDhYA1sqKVHG7F7fbGLyYw4=", - "dev": true, - "requires": { - "babel-runtime": "^6.22.0" - } - }, - "babel-plugin-add-module-exports": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/babel-plugin-add-module-exports/-/babel-plugin-add-module-exports-0.2.1.tgz", - "integrity": "sha1-mumh9KjcZ/DN7E9K7aHkOl/2XiU=", - "dev": true - }, - "babel-plugin-check-es2015-constants": { - "version": "6.22.0", - "resolved": "https://registry.npmjs.org/babel-plugin-check-es2015-constants/-/babel-plugin-check-es2015-constants-6.22.0.tgz", - "integrity": "sha1-NRV7EBQm/S/9PaP3XH0ekYNbv4o=", - "dev": true, - "requires": { - "babel-runtime": "^6.22.0" - } - }, - "babel-plugin-syntax-async-functions": { - "version": "6.13.0", - "resolved": "https://registry.npmjs.org/babel-plugin-syntax-async-functions/-/babel-plugin-syntax-async-functions-6.13.0.tgz", - "integrity": "sha1-ytnK0RkbWtY0vzCuCHI5HgZHvpU=", - "dev": true - }, - "babel-plugin-syntax-exponentiation-operator": { - "version": "6.13.0", - "resolved": "https://registry.npmjs.org/babel-plugin-syntax-exponentiation-operator/-/babel-plugin-syntax-exponentiation-operator-6.13.0.tgz", - "integrity": "sha1-nufoM3KQ2pUoggGmpX9BcDF4MN4=", - "dev": true - }, - "babel-plugin-syntax-trailing-function-commas": { - "version": "6.22.0", - "resolved": "https://registry.npmjs.org/babel-plugin-syntax-trailing-function-commas/-/babel-plugin-syntax-trailing-function-commas-6.22.0.tgz", - "integrity": "sha1-ugNgk3+NBuQBgKQ/4NVhb/9TLPM=", - "dev": true - }, - "babel-plugin-transform-async-to-generator": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-async-to-generator/-/babel-plugin-transform-async-to-generator-6.24.1.tgz", - "integrity": "sha1-ZTbjeK/2yx1VF6wOQOs+n8jQh2E=", - "dev": true, - "requires": { - "babel-helper-remap-async-to-generator": "^6.24.1", - "babel-plugin-syntax-async-functions": "^6.8.0", - "babel-runtime": "^6.22.0" - } - }, - "babel-plugin-transform-es2015-arrow-functions": { - "version": "6.22.0", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-arrow-functions/-/babel-plugin-transform-es2015-arrow-functions-6.22.0.tgz", - "integrity": "sha1-RSaSy3EdX3ncf4XkQM5BufJE0iE=", - "dev": true, - "requires": { - "babel-runtime": "^6.22.0" - } - }, - "babel-plugin-transform-es2015-block-scoped-functions": { - "version": "6.22.0", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-block-scoped-functions/-/babel-plugin-transform-es2015-block-scoped-functions-6.22.0.tgz", - "integrity": "sha1-u8UbSflk1wy42OC5ToICRs46YUE=", - "dev": true, - "requires": { - "babel-runtime": "^6.22.0" - } - }, - "babel-plugin-transform-es2015-block-scoping": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-block-scoping/-/babel-plugin-transform-es2015-block-scoping-6.26.0.tgz", - "integrity": "sha1-1w9SmcEwjQXBL0Y4E7CgnnOxiV8=", - "dev": true, - "requires": { - "babel-runtime": "^6.26.0", - "babel-template": "^6.26.0", - "babel-traverse": "^6.26.0", - "babel-types": "^6.26.0", - "lodash": "^4.17.4" - } - }, - "babel-plugin-transform-es2015-classes": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-classes/-/babel-plugin-transform-es2015-classes-6.24.1.tgz", - "integrity": "sha1-WkxYpQyclGHlZLSyo7+ryXolhNs=", - "dev": true, - "requires": { - "babel-helper-define-map": "^6.24.1", - "babel-helper-function-name": "^6.24.1", - "babel-helper-optimise-call-expression": "^6.24.1", - "babel-helper-replace-supers": "^6.24.1", - "babel-messages": "^6.23.0", - "babel-runtime": "^6.22.0", - "babel-template": "^6.24.1", - "babel-traverse": "^6.24.1", - "babel-types": "^6.24.1" - } - }, - "babel-plugin-transform-es2015-computed-properties": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-computed-properties/-/babel-plugin-transform-es2015-computed-properties-6.24.1.tgz", - "integrity": "sha1-b+Ko0WiV1WNPTNmZttNICjCBWbM=", - "dev": true, - "requires": { - "babel-runtime": "^6.22.0", - "babel-template": "^6.24.1" - } - }, - "babel-plugin-transform-es2015-destructuring": { - "version": "6.23.0", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-destructuring/-/babel-plugin-transform-es2015-destructuring-6.23.0.tgz", - "integrity": "sha1-mXux8auWf2gtKwh2/jWNYOdlxW0=", - "dev": true, - "requires": { - "babel-runtime": "^6.22.0" - } - }, - "babel-plugin-transform-es2015-duplicate-keys": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-duplicate-keys/-/babel-plugin-transform-es2015-duplicate-keys-6.24.1.tgz", - "integrity": "sha1-c+s9MQypaePvnskcU3QabxV2Qj4=", - "dev": true, - "requires": { - "babel-runtime": "^6.22.0", - "babel-types": "^6.24.1" - } - }, - "babel-plugin-transform-es2015-for-of": { - "version": "6.23.0", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-for-of/-/babel-plugin-transform-es2015-for-of-6.23.0.tgz", - "integrity": "sha1-9HyVsrYT3x0+zC/bdXNiPHUkhpE=", - "dev": true, - "requires": { - "babel-runtime": "^6.22.0" - } - }, - "babel-plugin-transform-es2015-function-name": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-function-name/-/babel-plugin-transform-es2015-function-name-6.24.1.tgz", - "integrity": "sha1-g0yJhTvDaxrw86TF26qU/Y6sqos=", - "dev": true, - "requires": { - "babel-helper-function-name": "^6.24.1", - "babel-runtime": "^6.22.0", - "babel-types": "^6.24.1" - } - }, - "babel-plugin-transform-es2015-literals": { - "version": "6.22.0", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-literals/-/babel-plugin-transform-es2015-literals-6.22.0.tgz", - "integrity": "sha1-T1SgLWzWbPkVKAAZox0xklN3yi4=", - "dev": true, - "requires": { - "babel-runtime": "^6.22.0" - } - }, - "babel-plugin-transform-es2015-modules-amd": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-modules-amd/-/babel-plugin-transform-es2015-modules-amd-6.24.1.tgz", - "integrity": "sha1-Oz5UAXI5hC1tGcMBHEvS8AoA0VQ=", - "dev": true, - "requires": { - "babel-plugin-transform-es2015-modules-commonjs": "^6.24.1", - "babel-runtime": "^6.22.0", - "babel-template": "^6.24.1" - } - }, - "babel-plugin-transform-es2015-modules-commonjs": { - "version": "6.26.2", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-modules-commonjs/-/babel-plugin-transform-es2015-modules-commonjs-6.26.2.tgz", - "integrity": "sha512-CV9ROOHEdrjcwhIaJNBGMBCodN+1cfkwtM1SbUHmvyy35KGT7fohbpOxkE2uLz1o6odKK2Ck/tz47z+VqQfi9Q==", - "dev": true, - "requires": { - "babel-plugin-transform-strict-mode": "^6.24.1", - "babel-runtime": "^6.26.0", - "babel-template": "^6.26.0", - "babel-types": "^6.26.0" - } - }, - "babel-plugin-transform-es2015-modules-systemjs": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-modules-systemjs/-/babel-plugin-transform-es2015-modules-systemjs-6.24.1.tgz", - "integrity": "sha1-/4mhQrkRmpBhlfXxBuzzBdlAfSM=", - "dev": true, - "requires": { - "babel-helper-hoist-variables": "^6.24.1", - "babel-runtime": "^6.22.0", - "babel-template": "^6.24.1" - } - }, - "babel-plugin-transform-es2015-modules-umd": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-modules-umd/-/babel-plugin-transform-es2015-modules-umd-6.24.1.tgz", - "integrity": "sha1-rJl+YoXNGO1hdq22B9YCNErThGg=", - "dev": true, - "requires": { - "babel-plugin-transform-es2015-modules-amd": "^6.24.1", - "babel-runtime": "^6.22.0", - "babel-template": "^6.24.1" - } - }, - "babel-plugin-transform-es2015-object-super": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-object-super/-/babel-plugin-transform-es2015-object-super-6.24.1.tgz", - "integrity": "sha1-JM72muIcuDp/hgPa0CH1cusnj40=", - "dev": true, - "requires": { - "babel-helper-replace-supers": "^6.24.1", - "babel-runtime": "^6.22.0" - } - }, - "babel-plugin-transform-es2015-parameters": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-parameters/-/babel-plugin-transform-es2015-parameters-6.24.1.tgz", - "integrity": "sha1-V6w1GrScrxSpfNE7CfZv3wpiXys=", - "dev": true, - "requires": { - "babel-helper-call-delegate": "^6.24.1", - "babel-helper-get-function-arity": "^6.24.1", - "babel-runtime": "^6.22.0", - "babel-template": "^6.24.1", - "babel-traverse": "^6.24.1", - "babel-types": "^6.24.1" - } - }, - "babel-plugin-transform-es2015-shorthand-properties": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-shorthand-properties/-/babel-plugin-transform-es2015-shorthand-properties-6.24.1.tgz", - "integrity": "sha1-JPh11nIch2YbvZmkYi5R8U3jiqA=", - "dev": true, - "requires": { - "babel-runtime": "^6.22.0", - "babel-types": "^6.24.1" - } - }, - "babel-plugin-transform-es2015-spread": { - "version": "6.22.0", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-spread/-/babel-plugin-transform-es2015-spread-6.22.0.tgz", - "integrity": "sha1-1taKmfia7cRTbIGlQujdnxdG+NE=", - "dev": true, - "requires": { - "babel-runtime": "^6.22.0" - } - }, - "babel-plugin-transform-es2015-sticky-regex": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-sticky-regex/-/babel-plugin-transform-es2015-sticky-regex-6.24.1.tgz", - "integrity": "sha1-AMHNsaynERLN8M9hJsLta0V8zbw=", - "dev": true, - "requires": { - "babel-helper-regex": "^6.24.1", - "babel-runtime": "^6.22.0", - "babel-types": "^6.24.1" - } - }, - "babel-plugin-transform-es2015-template-literals": { - "version": "6.22.0", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-template-literals/-/babel-plugin-transform-es2015-template-literals-6.22.0.tgz", - "integrity": "sha1-qEs0UPfp+PH2g51taH2oS7EjbY0=", - "dev": true, - "requires": { - "babel-runtime": "^6.22.0" - } - }, - "babel-plugin-transform-es2015-typeof-symbol": { - "version": "6.23.0", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-typeof-symbol/-/babel-plugin-transform-es2015-typeof-symbol-6.23.0.tgz", - "integrity": "sha1-3sCfHN3/lLUqxz1QXITfWdzOs3I=", - "dev": true, - "requires": { - "babel-runtime": "^6.22.0" - } - }, - "babel-plugin-transform-es2015-unicode-regex": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-unicode-regex/-/babel-plugin-transform-es2015-unicode-regex-6.24.1.tgz", - "integrity": "sha1-04sS9C6nMj9yk4fxinxa4frrNek=", - "dev": true, - "requires": { - "babel-helper-regex": "^6.24.1", - "babel-runtime": "^6.22.0", - "regexpu-core": "^2.0.0" - } - }, - "babel-plugin-transform-exponentiation-operator": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-exponentiation-operator/-/babel-plugin-transform-exponentiation-operator-6.24.1.tgz", - "integrity": "sha1-KrDJx/MJj6SJB3cruBP+QejeOg4=", - "dev": true, - "requires": { - "babel-helper-builder-binary-assignment-operator-visitor": "^6.24.1", - "babel-plugin-syntax-exponentiation-operator": "^6.8.0", - "babel-runtime": "^6.22.0" - } - }, - "babel-plugin-transform-regenerator": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-regenerator/-/babel-plugin-transform-regenerator-6.26.0.tgz", - "integrity": "sha1-4HA2lvveJ/Cj78rPi03KL3s6jy8=", - "dev": true, - "requires": { - "regenerator-transform": "^0.10.0" - } - }, - "babel-plugin-transform-strict-mode": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-strict-mode/-/babel-plugin-transform-strict-mode-6.24.1.tgz", - "integrity": "sha1-1fr3qleKZbvlkc9e2uBKDGcCB1g=", - "dev": true, - "requires": { - "babel-runtime": "^6.22.0", - "babel-types": "^6.24.1" - } - }, - "babel-polyfill": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-polyfill/-/babel-polyfill-6.26.0.tgz", - "integrity": "sha1-N5k3q8Z9eJWXCtxiHyhM2WbPIVM=", - "dev": true, - "requires": { - "babel-runtime": "^6.26.0", - "core-js": "^2.5.0", - "regenerator-runtime": "^0.10.5" - }, - "dependencies": { - "regenerator-runtime": { - "version": "0.10.5", - "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.10.5.tgz", - "integrity": "sha1-M2w+/BIgrc7dosn6tntaeVWjNlg=", - "dev": true - } - } - }, - "babel-preset-env": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/babel-preset-env/-/babel-preset-env-1.7.0.tgz", - "integrity": "sha512-9OR2afuKDneX2/q2EurSftUYM0xGu4O2D9adAhVfADDhrYDaxXV0rBbevVYoY9n6nyX1PmQW/0jtpJvUNr9CHg==", - "dev": true, - "requires": { - "babel-plugin-check-es2015-constants": "^6.22.0", - "babel-plugin-syntax-trailing-function-commas": "^6.22.0", - "babel-plugin-transform-async-to-generator": "^6.22.0", - "babel-plugin-transform-es2015-arrow-functions": "^6.22.0", - "babel-plugin-transform-es2015-block-scoped-functions": "^6.22.0", - "babel-plugin-transform-es2015-block-scoping": "^6.23.0", - "babel-plugin-transform-es2015-classes": "^6.23.0", - "babel-plugin-transform-es2015-computed-properties": "^6.22.0", - "babel-plugin-transform-es2015-destructuring": "^6.23.0", - "babel-plugin-transform-es2015-duplicate-keys": "^6.22.0", - "babel-plugin-transform-es2015-for-of": "^6.23.0", - "babel-plugin-transform-es2015-function-name": "^6.22.0", - "babel-plugin-transform-es2015-literals": "^6.22.0", - "babel-plugin-transform-es2015-modules-amd": "^6.22.0", - "babel-plugin-transform-es2015-modules-commonjs": "^6.23.0", - "babel-plugin-transform-es2015-modules-systemjs": "^6.23.0", - "babel-plugin-transform-es2015-modules-umd": "^6.23.0", - "babel-plugin-transform-es2015-object-super": "^6.22.0", - "babel-plugin-transform-es2015-parameters": "^6.23.0", - "babel-plugin-transform-es2015-shorthand-properties": "^6.22.0", - "babel-plugin-transform-es2015-spread": "^6.22.0", - "babel-plugin-transform-es2015-sticky-regex": "^6.22.0", - "babel-plugin-transform-es2015-template-literals": "^6.22.0", - "babel-plugin-transform-es2015-typeof-symbol": "^6.23.0", - "babel-plugin-transform-es2015-unicode-regex": "^6.22.0", - "babel-plugin-transform-exponentiation-operator": "^6.22.0", - "babel-plugin-transform-regenerator": "^6.22.0", - "browserslist": "^3.2.6", - "invariant": "^2.2.2", - "semver": "^5.3.0" - } - }, - "babel-register": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-register/-/babel-register-6.26.0.tgz", - "integrity": "sha1-btAhFz4vy0htestFxgCahW9kcHE=", - "dev": true, - "requires": { - "babel-core": "^6.26.0", - "babel-runtime": "^6.26.0", - "core-js": "^2.5.0", - "home-or-tmp": "^2.0.0", - "lodash": "^4.17.4", - "mkdirp": "^0.5.1", - "source-map-support": "^0.4.15" - } - }, - "babel-runtime": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-runtime/-/babel-runtime-6.26.0.tgz", - "integrity": "sha1-llxwWGaOgrVde/4E/yM3vItWR/4=", - "dev": true, - "requires": { - "core-js": "^2.4.0", - "regenerator-runtime": "^0.11.0" - } - }, - "babel-template": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-template/-/babel-template-6.26.0.tgz", - "integrity": "sha1-3gPi0WOWsGn0bdn/+FIfsaDjXgI=", - "dev": true, - "requires": { - "babel-runtime": "^6.26.0", - "babel-traverse": "^6.26.0", - "babel-types": "^6.26.0", - "babylon": "^6.18.0", - "lodash": "^4.17.4" - } - }, - "babel-traverse": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-traverse/-/babel-traverse-6.26.0.tgz", - "integrity": "sha1-RqnL1+3MYsjlwGTi0tjQ9ANXZu4=", - "dev": true, - "requires": { - "babel-code-frame": "^6.26.0", - "babel-messages": "^6.23.0", - "babel-runtime": "^6.26.0", - "babel-types": "^6.26.0", - "babylon": "^6.18.0", - "debug": "^2.6.8", - "globals": "^9.18.0", - "invariant": "^2.2.2", - "lodash": "^4.17.4" - } - }, - "babel-types": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-types/-/babel-types-6.26.0.tgz", - "integrity": "sha1-o7Bz+Uq0nrb6Vc1lInozQ4BjJJc=", - "dev": true, - "requires": { - "babel-runtime": "^6.26.0", - "esutils": "^2.0.2", - "lodash": "^4.17.4", - "to-fast-properties": "^1.0.3" - } - }, - "babylon": { - "version": "6.18.0", - "resolved": "https://registry.npmjs.org/babylon/-/babylon-6.18.0.tgz", - "integrity": "sha512-q/UEjfGJ2Cm3oKV71DJz9d25TPnq5rhBVL2Q4fA5wcC3jcrdn7+SssEybFIxwAvvP+YCsCYNKughoF33GxgycQ==", - "dev": true - }, - "balanced-match": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", - "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=" - }, - "before-after-hook": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/before-after-hook/-/before-after-hook-1.1.0.tgz", - "integrity": "sha512-VOMDtYPwLbIncTxNoSzRyvaMxtXmLWLUqr8k5AfC1BzLk34HvBXaQX8snOwQZ4c0aX8aSERqtJSiI9/m2u5kuA==", - "dev": true - }, - "binary-extensions": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.11.0.tgz", - "integrity": "sha1-RqoXUftqL5PuXmibsQh9SxTGwgU=", - "dev": true, - "optional": true - }, - "brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, - "requires": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "braces": { - "version": "1.8.5", - "resolved": "https://registry.npmjs.org/braces/-/braces-1.8.5.tgz", - "integrity": "sha1-uneWLhLf+WnWt2cR6RS3N4V79qc=", - "dev": true, - "optional": true, - "requires": { - "expand-range": "^1.8.1", - "preserve": "^0.2.0", - "repeat-element": "^1.1.2" - } - }, - "browserslist": { - "version": "3.2.8", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-3.2.8.tgz", - "integrity": "sha512-WHVocJYavUwVgVViC0ORikPHQquXwVh939TaelZ4WDqpWgTX/FsGhl/+P4qBUAGcRvtOgDgC+xftNWWp2RUTAQ==", - "dev": true, - "requires": { - "caniuse-lite": "^1.0.30000844", - "electron-to-chromium": "^1.3.47" - } - }, - "caller-path": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/caller-path/-/caller-path-0.1.0.tgz", - "integrity": "sha1-lAhe9jWB7NPaqSREqP6U6CV3dR8=", - "dev": true, - "requires": { - "callsites": "^0.2.0" - } - }, - "callsites": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/callsites/-/callsites-0.2.0.tgz", - "integrity": "sha1-r6uWJikQp/M8GaV3WCXGnzTjUMo=", - "dev": true - }, - "caniuse-lite": { - "version": "1.0.30000874", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30000874.tgz", - "integrity": "sha512-29nr1EPiHwrJTAHHsEmTt2h+55L8j2GNFdAcYPlRy2NX6iFz7ZZiepVI7kP/QqlnHLq3KvfWpbmGa0d063U09w==", - "dev": true - }, - "chalk": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.1.tgz", - "integrity": "sha512-ObN6h1v2fTJSmUXoS3nMQ92LbDK9be4TV+6G+omQlGJFdcUX5heKi1LZ1YnRMIgwTLEj3E24bT6tYni50rlCfQ==", - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - } - }, - "chardet": { - "version": "0.4.2", - "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.4.2.tgz", - "integrity": "sha1-tUc7M9yXxCTl2Y3IfVXU2KKci/I=", - "dev": true - }, - "checkup": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/checkup/-/checkup-1.3.0.tgz", - "integrity": "sha1-04ACdv6l0PJH/8lRvnjIsC+ODXY=", - "dev": true - }, - "chokidar": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-1.7.0.tgz", - "integrity": "sha1-eY5ol3gVHIB2tLNg5e3SjNortGg=", - "dev": true, - "optional": true, - "requires": { - "anymatch": "^1.3.0", - "async-each": "^1.0.0", - "fsevents": "^1.0.0", - "glob-parent": "^2.0.0", - "inherits": "^2.0.1", - "is-binary-path": "^1.0.0", - "is-glob": "^2.0.0", - "path-is-absolute": "^1.0.0", - "readdirp": "^2.0.0" - } - }, - "circular-json": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/circular-json/-/circular-json-0.3.3.tgz", - "integrity": "sha512-UZK3NBx2Mca+b5LsG7bY183pHWt5Y1xts4P3Pz7ENTwGVnJOUWbRb3ocjvX7hx9tq/yTAdclXm9sZ38gNuem4A==", - "dev": true - }, - "cli-cursor": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-2.1.0.tgz", - "integrity": "sha1-s12sN2R5+sw+lHR9QdDQ9SOP/LU=", - "dev": true, - "requires": { - "restore-cursor": "^2.0.0" - } - }, - "cli-width": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-2.2.0.tgz", - "integrity": "sha1-/xnt6Kml5XkyQUewwR8PvLq+1jk=", - "dev": true - }, - "color-convert": { - "version": "1.9.2", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.2.tgz", - "integrity": "sha512-3NUJZdhMhcdPn8vJ9v2UQJoH0qqoGUkYTgFEPZaPjEtwmmKUfNV46zZmgB2M5M4DCEQHMaCfWHCxiBflLm04Tg==", - "requires": { - "color-name": "1.1.1" - } - }, - "color-name": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.1.tgz", - "integrity": "sha1-SxQVMEz1ACjqgWQ2Q72C6gWANok=" - }, - "commander": { - "version": "2.17.1", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.17.1.tgz", - "integrity": "sha512-wPMUt6FnH2yzG95SA6mzjQOEKUU3aLaDEmzs1ti+1E9h+CsrZghRlqEM/EJ4KscsQVG8uNN4uVreUeT8+drlgg==", - "dev": true - }, - "concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", - "dev": true - }, - "convert-source-map": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.5.1.tgz", - "integrity": "sha1-uCeAl7m8IpNl3lxiz1/K7YtVmeU=", - "dev": true - }, - "core-js": { - "version": "2.5.7", - "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.5.7.tgz", - "integrity": "sha512-RszJCAxg/PP6uzXVXL6BsxSXx/B05oJAQ2vkJRjyjrEcNVycaqOmNb5OTxZPE3xa5gwZduqza6L9JOCenh/Ecw==", - "dev": true - }, - "core-util-is": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", - "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=", - "dev": true, - "optional": true - }, - "cross-spawn": { - "version": "6.0.5", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", - "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", - "dev": true, - "requires": { - "nice-try": "^1.0.4", - "path-key": "^2.0.1", - "semver": "^5.5.0", - "shebang-command": "^1.2.0", - "which": "^1.2.9" - } - }, - "cross-spawn-async": { - "version": "2.2.5", - "resolved": "https://registry.npmjs.org/cross-spawn-async/-/cross-spawn-async-2.2.5.tgz", - "integrity": "sha1-hF/wwINKPe2dFg2sptOQkGuyiMw=", - "dev": true, - "requires": { - "lru-cache": "^4.0.0", - "which": "^1.2.8" - } - }, - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "deep-equal": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/deep-equal/-/deep-equal-1.0.1.tgz", - "integrity": "sha1-9dJgKStmDghO/0zbyfCK0yR0SLU=", - "dev": true - }, - "deep-is": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz", - "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=", - "dev": true - }, - "define-properties": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.2.tgz", - "integrity": "sha1-g6c/L+pWmJj7c3GTyPhzyvbUXJQ=", - "dev": true, - "requires": { - "foreach": "^2.0.5", - "object-keys": "^1.0.8" - } - }, - "defined": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/defined/-/defined-1.0.0.tgz", - "integrity": "sha1-yY2bzvdWdBiOEQlpFRGZ45sfppM=", - "dev": true - }, - "del": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/del/-/del-2.2.2.tgz", - "integrity": "sha1-wSyYHQZ4RshLyvhiz/kw2Qf/0ag=", - "dev": true, - "requires": { - "globby": "^5.0.0", - "is-path-cwd": "^1.0.0", - "is-path-in-cwd": "^1.0.0", - "object-assign": "^4.0.1", - "pify": "^2.0.0", - "pinkie-promise": "^2.0.0", - "rimraf": "^2.2.8" - } - }, - "detect-indent": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/detect-indent/-/detect-indent-4.0.0.tgz", - "integrity": "sha1-920GQ1LN9Docts5hnE7jqUdd4gg=", - "dev": true, - "requires": { - "repeating": "^2.0.0" - } - }, - "doctrine": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", - "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", - "dev": true, - "requires": { - "esutils": "^2.0.2" - } - }, - "electron-to-chromium": { - "version": "1.3.57", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.57.tgz", - "integrity": "sha512-YYpZlr6mzR8cK5VRmTZydEt5Mp+WMg1/syrO40PoQzl76vJ+oQchL2d3FmEcWzw3FYqJVYJP/kYYSzTa7FLXwg==", - "dev": true - }, - "es-abstract": { - "version": "1.12.0", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.12.0.tgz", - "integrity": "sha512-C8Fx/0jFmV5IPoMOFPA9P9G5NtqW+4cOPit3MIuvR2t7Ag2K15EJTpxnHAYTzL+aYQJIESYeXZmDBfOBE1HcpA==", - "dev": true, - "requires": { - "es-to-primitive": "^1.1.1", - "function-bind": "^1.1.1", - "has": "^1.0.1", - "is-callable": "^1.1.3", - "is-regex": "^1.0.4" - } - }, - "es-to-primitive": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.1.1.tgz", - "integrity": "sha1-RTVSSKiJeQNLZ5Lhm7gfK3l13Q0=", - "dev": true, - "requires": { - "is-callable": "^1.1.1", - "is-date-object": "^1.0.1", - "is-symbol": "^1.0.1" - } - }, - "escape-string-applescript": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/escape-string-applescript/-/escape-string-applescript-1.0.0.tgz", - "integrity": "sha1-bxwilCRdgsY7wDM43BmpSqhCiJI=", - "dev": true - }, - "escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=" - }, - "eslint": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-5.3.0.tgz", - "integrity": "sha512-N/tCqlMKkyNvAvLu+zI9AqDasnSLt00K+Hu8kdsERliC9jYEc8ck12XtjvOXrBKu8fK6RrBcN9bat6Xk++9jAg==", - "dev": true, - "requires": { - "ajv": "^6.5.0", - "babel-code-frame": "^6.26.0", - "chalk": "^2.1.0", - "cross-spawn": "^6.0.5", - "debug": "^3.1.0", - "doctrine": "^2.1.0", - "eslint-scope": "^4.0.0", - "eslint-utils": "^1.3.1", - "eslint-visitor-keys": "^1.0.0", - "espree": "^4.0.0", - "esquery": "^1.0.1", - "esutils": "^2.0.2", - "file-entry-cache": "^2.0.0", - "functional-red-black-tree": "^1.0.1", - "glob": "^7.1.2", - "globals": "^11.7.0", - "ignore": "^4.0.2", - "imurmurhash": "^0.1.4", - "inquirer": "^5.2.0", - "is-resolvable": "^1.1.0", - "js-yaml": "^3.11.0", - "json-stable-stringify-without-jsonify": "^1.0.1", - "levn": "^0.3.0", - "lodash": "^4.17.5", - "minimatch": "^3.0.4", - "mkdirp": "^0.5.1", - "natural-compare": "^1.4.0", - "optionator": "^0.8.2", - "path-is-inside": "^1.0.2", - "pluralize": "^7.0.0", - "progress": "^2.0.0", - "regexpp": "^2.0.0", - "require-uncached": "^1.0.3", - "semver": "^5.5.0", - "string.prototype.matchall": "^2.0.0", - "strip-ansi": "^4.0.0", - "strip-json-comments": "^2.0.1", - "table": "^4.0.3", - "text-table": "^0.2.0" - }, - "dependencies": { - "ansi-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", - "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", - "dev": true - }, - "debug": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", - "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "globals": { - "version": "11.7.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-11.7.0.tgz", - "integrity": "sha512-K8BNSPySfeShBQXsahYB/AbbWruVOTyVpgoIDnl8odPpeSfP2J5QO2oLFFdl2j7GfDCtZj2bMKar2T49itTPCg==", - "dev": true - }, - "strip-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", - "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", - "dev": true, - "requires": { - "ansi-regex": "^3.0.0" - } - } - } - }, - "eslint-scope": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-4.0.0.tgz", - "integrity": "sha512-1G6UTDi7Jc1ELFwnR58HV4fK9OQK4S6N985f166xqXxpjU6plxFISJa2Ba9KCQuFa8RCnj/lSFJbHo7UFDBnUA==", - "dev": true, - "requires": { - "esrecurse": "^4.1.0", - "estraverse": "^4.1.1" - } - }, - "eslint-utils": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-1.3.1.tgz", - "integrity": "sha512-Z7YjnIldX+2XMcjr7ZkgEsOj/bREONV60qYeB/bjMAqqqZ4zxKyWX+BOUkdmRmA9riiIPVvo5x86m5elviOk0Q==", - "dev": true - }, - "eslint-visitor-keys": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.0.0.tgz", - "integrity": "sha512-qzm/XxIbxm/FHyH341ZrbnMUpe+5Bocte9xkmFMzPMjRaZMcXww+MpBptFvtU+79L362nqiLhekCxCxDPaUMBQ==", - "dev": true - }, - "espree": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/espree/-/espree-4.0.0.tgz", - "integrity": "sha512-kapdTCt1bjmspxStVKX6huolXVV5ZfyZguY1lcfhVVZstce3bqxH9mcLzNn3/mlgW6wQ732+0fuG9v7h0ZQoKg==", - "dev": true, - "requires": { - "acorn": "^5.6.0", - "acorn-jsx": "^4.1.1" - } - }, - "esprima": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", - "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", - "dev": true - }, - "esquery": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.0.1.tgz", - "integrity": "sha512-SmiyZ5zIWH9VM+SRUReLS5Q8a7GxtRdxEBVZpm98rJM7Sb+A9DVCndXfkeFUd3byderg+EbDkfnevfCwynWaNA==", - "dev": true, - "requires": { - "estraverse": "^4.0.0" - } - }, - "esrecurse": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.2.1.tgz", - "integrity": "sha512-64RBB++fIOAXPw3P9cy89qfMlvZEXZkqqJkjqqXIvzP5ezRZjW+lPWjw35UX/3EhUPFYbg5ER4JYgDw4007/DQ==", - "dev": true, - "requires": { - "estraverse": "^4.1.0" - } - }, - "estraverse": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.2.0.tgz", - "integrity": "sha1-De4/7TH81GlhjOc0IJn8GvoL2xM=", - "dev": true - }, - "esutils": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.2.tgz", - "integrity": "sha1-Cr9PHKpbyx96nYrMbepPqqBLrJs=", - "dev": true - }, - "execa": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/execa/-/execa-0.2.2.tgz", - "integrity": "sha1-4urUcsLDGq1vc/GslW7vReEjIMs=", - "dev": true, - "requires": { - "cross-spawn-async": "^2.1.1", - "npm-run-path": "^1.0.0", - "object-assign": "^4.0.1", - "path-key": "^1.0.0", - "strip-eof": "^1.0.0" - }, - "dependencies": { - "path-key": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-1.0.0.tgz", - "integrity": "sha1-XVPVeAGWRsDWiADbThRua9wqx68=", - "dev": true - } - } - }, - "execon": { - "version": "1.2.9", - "resolved": "https://registry.npmjs.org/execon/-/execon-1.2.9.tgz", - "integrity": "sha1-bbETM9zIJPHxPnMX/tDZSi8mSR8=", - "dev": true - }, - "expand-brackets": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-0.1.5.tgz", - "integrity": "sha1-3wcoTjQqgHzXM6xa9yQR5YHRF3s=", - "dev": true, - "optional": true, - "requires": { - "is-posix-bracket": "^0.1.0" - } - }, - "expand-range": { - "version": "1.8.2", - "resolved": "https://registry.npmjs.org/expand-range/-/expand-range-1.8.2.tgz", - "integrity": "sha1-opnv/TNf4nIeuujiV+x5ZE/IUzc=", - "dev": true, - "optional": true, - "requires": { - "fill-range": "^2.1.0" - } - }, - "external-editor": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-2.2.0.tgz", - "integrity": "sha512-bSn6gvGxKt+b7+6TKEv1ZycHleA7aHhRHyAqJyp5pbUFuYYNIzpZnQDk7AsYckyWdEnTeAnay0aCy2aV6iTk9A==", - "dev": true, - "requires": { - "chardet": "^0.4.0", - "iconv-lite": "^0.4.17", - "tmp": "^0.0.33" - } - }, - "extglob": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/extglob/-/extglob-0.3.2.tgz", - "integrity": "sha1-Lhj/PS9JqydlzskCPwEdqo2DSaE=", - "dev": true, - "optional": true, - "requires": { - "is-extglob": "^1.0.0" - } - }, - "fast-deep-equal": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz", - "integrity": "sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk=", - "dev": true - }, - "fast-json-stable-stringify": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz", - "integrity": "sha1-1RQsDK7msRifh9OnYREGT4bIu/I=", - "dev": true - }, - "fast-levenshtein": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", - "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", - "dev": true - }, - "figures": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/figures/-/figures-2.0.0.tgz", - "integrity": "sha1-OrGi0qYsi/tDGgyUy3l6L84nyWI=", - "dev": true, - "requires": { - "escape-string-regexp": "^1.0.5" - } - }, - "file-entry-cache": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-2.0.0.tgz", - "integrity": "sha1-w5KZDD5oR4PYOLjISkXYoEhFg2E=", - "dev": true, - "requires": { - "flat-cache": "^1.2.1", - "object-assign": "^4.0.1" - } - }, - "filename-regex": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/filename-regex/-/filename-regex-2.0.1.tgz", - "integrity": "sha1-wcS5vuPglyXdsQa3XB4wH+LxiyY=", - "dev": true, - "optional": true - }, - "fill-range": { - "version": "2.2.4", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-2.2.4.tgz", - "integrity": "sha512-cnrcCbj01+j2gTG921VZPnHbjmdAf8oQV/iGeV2kZxGSyfYjjTyY79ErsK1WJWMpw6DaApEX72binqJE+/d+5Q==", - "dev": true, - "optional": true, - "requires": { - "is-number": "^2.1.0", - "isobject": "^2.0.0", - "randomatic": "^3.0.0", - "repeat-element": "^1.1.2", - "repeat-string": "^1.5.2" - } - }, - "flat-cache": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-1.3.0.tgz", - "integrity": "sha1-0wMLMrOBVPTjt+nHCfSQ9++XxIE=", - "dev": true, - "requires": { - "circular-json": "^0.3.1", - "del": "^2.0.2", - "graceful-fs": "^4.1.2", - "write": "^0.2.1" - } - }, - "for-each": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz", - "integrity": "sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==", - "dev": true, - "requires": { - "is-callable": "^1.1.3" - } - }, - "for-in": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz", - "integrity": "sha1-gQaNKVqBQuwKxybG4iAMMPttXoA=", - "dev": true, - "optional": true - }, - "for-own": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/for-own/-/for-own-0.1.5.tgz", - "integrity": "sha1-UmXGgaTylNq78XyVCbZ2OqhFEM4=", - "dev": true, - "optional": true, - "requires": { - "for-in": "^1.0.1" - } - }, - "foreach": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/foreach/-/foreach-2.0.5.tgz", - "integrity": "sha1-C+4AUBiusmDQo6865ljdATbsG5k=", - "dev": true - }, - "fs-extra": { - "version": "0.26.7", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-0.26.7.tgz", - "integrity": "sha1-muH92UiXeY7at20JGM9C0MMYT6k=", - "dev": true, - "requires": { - "graceful-fs": "^4.1.2", - "jsonfile": "^2.1.0", - "klaw": "^1.0.0", - "path-is-absolute": "^1.0.0", - "rimraf": "^2.2.8" - } - }, - "fs-readdir-recursive": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/fs-readdir-recursive/-/fs-readdir-recursive-1.1.0.tgz", - "integrity": "sha512-GNanXlVr2pf02+sPN40XN8HG+ePaNcvM0q5mZBd668Obwb0yD5GiUbZOFgwn8kGMY6I3mdyDJzieUy3PTYyTRA==", - "dev": true - }, - "fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", - "dev": true - }, - "fsevents": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.4.tgz", - "integrity": "sha512-z8H8/diyk76B7q5wg+Ud0+CqzcAF3mBBI/bA5ne5zrRUUIvNkJY//D3BqyH571KuAC4Nr7Rw7CjWX4r0y9DvNg==", - "dev": true, - "optional": true, - "requires": { - "nan": "^2.9.2", - "node-pre-gyp": "^0.10.0" - }, - "dependencies": { - "abbrev": { - "version": "1.1.1", - "bundled": true, - "dev": true, - "optional": true - }, - "ansi-regex": { - "version": "2.1.1", - "bundled": true, - "dev": true - }, - "aproba": { - "version": "1.2.0", - "bundled": true, - "dev": true, - "optional": true - }, - "are-we-there-yet": { - "version": "1.1.4", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "delegates": "^1.0.0", - "readable-stream": "^2.0.6" - } - }, - "balanced-match": { - "version": "1.0.0", - "bundled": true, - "dev": true - }, - "brace-expansion": { - "version": "1.1.11", - "bundled": true, - "dev": true, - "requires": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "chownr": { - "version": "1.0.1", - "bundled": true, - "dev": true, - "optional": true - }, - "code-point-at": { - "version": "1.1.0", - "bundled": true, - "dev": true - }, - "concat-map": { - "version": "0.0.1", - "bundled": true, - "dev": true - }, - "console-control-strings": { - "version": "1.1.0", - "bundled": true, - "dev": true - }, - "core-util-is": { - "version": "1.0.2", - "bundled": true, - "dev": true, - "optional": true - }, - "debug": { - "version": "2.6.9", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "ms": "2.0.0" - } - }, - "deep-extend": { - "version": "0.5.1", - "bundled": true, - "dev": true, - "optional": true - }, - "delegates": { - "version": "1.0.0", - "bundled": true, - "dev": true, - "optional": true - }, - "detect-libc": { - "version": "1.0.3", - "bundled": true, - "dev": true, - "optional": true - }, - "fs-minipass": { - "version": "1.2.5", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "minipass": "^2.2.1" - } - }, - "fs.realpath": { - "version": "1.0.0", - "bundled": true, - "dev": true, - "optional": true - }, - "gauge": { - "version": "2.7.4", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "aproba": "^1.0.3", - "console-control-strings": "^1.0.0", - "has-unicode": "^2.0.0", - "object-assign": "^4.1.0", - "signal-exit": "^3.0.0", - "string-width": "^1.0.1", - "strip-ansi": "^3.0.1", - "wide-align": "^1.1.0" - } - }, - "glob": { - "version": "7.1.2", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "has-unicode": { - "version": "2.0.1", - "bundled": true, - "dev": true, - "optional": true - }, - "iconv-lite": { - "version": "0.4.21", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "safer-buffer": "^2.1.0" - } - }, - "ignore-walk": { - "version": "3.0.1", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "minimatch": "^3.0.4" - } - }, - "inflight": { - "version": "1.0.6", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "inherits": { - "version": "2.0.3", - "bundled": true, - "dev": true - }, - "ini": { - "version": "1.3.5", - "bundled": true, - "dev": true, - "optional": true - }, - "is-fullwidth-code-point": { - "version": "1.0.0", - "bundled": true, - "dev": true, - "requires": { - "number-is-nan": "^1.0.0" - } - }, - "isarray": { - "version": "1.0.0", - "bundled": true, - "dev": true, - "optional": true - }, - "minimatch": { - "version": "3.0.4", - "bundled": true, - "dev": true, - "requires": { - "brace-expansion": "^1.1.7" - } - }, - "minimist": { - "version": "0.0.8", - "bundled": true, - "dev": true - }, - "minipass": { - "version": "2.2.4", - "bundled": true, - "dev": true, - "requires": { - "safe-buffer": "^5.1.1", - "yallist": "^3.0.0" - } - }, - "minizlib": { - "version": "1.1.0", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "minipass": "^2.2.1" - } - }, - "mkdirp": { - "version": "0.5.1", - "bundled": true, - "dev": true, - "requires": { - "minimist": "0.0.8" - } - }, - "ms": { - "version": "2.0.0", - "bundled": true, - "dev": true, - "optional": true - }, - "needle": { - "version": "2.2.0", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "debug": "^2.1.2", - "iconv-lite": "^0.4.4", - "sax": "^1.2.4" - } - }, - "node-pre-gyp": { - "version": "0.10.0", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "detect-libc": "^1.0.2", - "mkdirp": "^0.5.1", - "needle": "^2.2.0", - "nopt": "^4.0.1", - "npm-packlist": "^1.1.6", - "npmlog": "^4.0.2", - "rc": "^1.1.7", - "rimraf": "^2.6.1", - "semver": "^5.3.0", - "tar": "^4" - } - }, - "nopt": { - "version": "4.0.1", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "abbrev": "1", - "osenv": "^0.1.4" - } - }, - "npm-bundled": { - "version": "1.0.3", - "bundled": true, - "dev": true, - "optional": true - }, - "npm-packlist": { - "version": "1.1.10", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "ignore-walk": "^3.0.1", - "npm-bundled": "^1.0.1" - } - }, - "npmlog": { - "version": "4.1.2", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "are-we-there-yet": "~1.1.2", - "console-control-strings": "~1.1.0", - "gauge": "~2.7.3", - "set-blocking": "~2.0.0" - } - }, - "number-is-nan": { - "version": "1.0.1", - "bundled": true, - "dev": true - }, - "object-assign": { - "version": "4.1.1", - "bundled": true, - "dev": true, - "optional": true - }, - "once": { - "version": "1.4.0", - "bundled": true, - "dev": true, - "requires": { - "wrappy": "1" - } - }, - "os-homedir": { - "version": "1.0.2", - "bundled": true, - "dev": true, - "optional": true - }, - "os-tmpdir": { - "version": "1.0.2", - "bundled": true, - "dev": true, - "optional": true - }, - "osenv": { - "version": "0.1.5", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "os-homedir": "^1.0.0", - "os-tmpdir": "^1.0.0" - } - }, - "path-is-absolute": { - "version": "1.0.1", - "bundled": true, - "dev": true, - "optional": true - }, - "process-nextick-args": { - "version": "2.0.0", - "bundled": true, - "dev": true, - "optional": true - }, - "rc": { - "version": "1.2.7", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "deep-extend": "^0.5.1", - "ini": "~1.3.0", - "minimist": "^1.2.0", - "strip-json-comments": "~2.0.1" - }, - "dependencies": { - "minimist": { - "version": "1.2.0", - "bundled": true, - "dev": true, - "optional": true - } - } - }, - "readable-stream": { - "version": "2.3.6", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "rimraf": { - "version": "2.6.2", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "glob": "^7.0.5" - } - }, - "safe-buffer": { - "version": "5.1.1", - "bundled": true, - "dev": true - }, - "safer-buffer": { - "version": "2.1.2", - "bundled": true, - "dev": true, - "optional": true - }, - "sax": { - "version": "1.2.4", - "bundled": true, - "dev": true, - "optional": true - }, - "semver": { - "version": "5.5.0", - "bundled": true, - "dev": true, - "optional": true - }, - "set-blocking": { - "version": "2.0.0", - "bundled": true, - "dev": true, - "optional": true - }, - "signal-exit": { - "version": "3.0.2", - "bundled": true, - "dev": true, - "optional": true - }, - "string-width": { - "version": "1.0.2", - "bundled": true, - "dev": true, - "requires": { - "code-point-at": "^1.0.0", - "is-fullwidth-code-point": "^1.0.0", - "strip-ansi": "^3.0.0" - } - }, - "string_decoder": { - "version": "1.1.1", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "safe-buffer": "~5.1.0" - } - }, - "strip-ansi": { - "version": "3.0.1", - "bundled": true, - "dev": true, - "requires": { - "ansi-regex": "^2.0.0" - } - }, - "strip-json-comments": { - "version": "2.0.1", - "bundled": true, - "dev": true, - "optional": true - }, - "tar": { - "version": "4.4.1", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "chownr": "^1.0.1", - "fs-minipass": "^1.2.5", - "minipass": "^2.2.4", - "minizlib": "^1.1.0", - "mkdirp": "^0.5.0", - "safe-buffer": "^5.1.1", - "yallist": "^3.0.2" - } - }, - "util-deprecate": { - "version": "1.0.2", - "bundled": true, - "dev": true, - "optional": true - }, - "wide-align": { - "version": "1.1.2", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "string-width": "^1.0.2" - } - }, - "wrappy": { - "version": "1.0.2", - "bundled": true, - "dev": true - }, - "yallist": { - "version": "3.0.2", - "bundled": true, - "dev": true - } - } - }, - "function-bind": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", - "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", - "dev": true - }, - "functional-red-black-tree": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", - "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=", - "dev": true - }, - "github-release-from-changelog": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/github-release-from-changelog/-/github-release-from-changelog-1.3.2.tgz", - "integrity": "sha512-3Cj5zazWfk9heJzBSXxBsh9xQSYt8ZOseresfNeHewFVC2g0Au9181xob9eXTv4hRysi9k3gRVCXOUmBH+J2bA==", - "dev": true, - "requires": { - "grizzly": "^3.0.3", - "minimist": "^1.2.0" - }, - "dependencies": { - "minimist": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", - "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", - "dev": true - } - } - }, - "glob": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz", - "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "glob-base": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/glob-base/-/glob-base-0.3.0.tgz", - "integrity": "sha1-27Fk9iIbHAscz4Kuoyi0l98Oo8Q=", - "dev": true, - "optional": true, - "requires": { - "glob-parent": "^2.0.0", - "is-glob": "^2.0.0" - } - }, - "glob-parent": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-2.0.0.tgz", - "integrity": "sha1-gTg9ctsFT8zPUzbaqQLxgvbtuyg=", - "dev": true, - "requires": { - "is-glob": "^2.0.0" - } - }, - "globals": { - "version": "9.18.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-9.18.0.tgz", - "integrity": "sha512-S0nG3CLEQiY/ILxqtztTWH/3iRRdyBLw6KMDxnKMchrtbj2OFmehVh0WUCfW3DUrIgx/qFrJPICrq4Z4sTR9UQ==", - "dev": true - }, - "globby": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/globby/-/globby-5.0.0.tgz", - "integrity": "sha1-69hGZ8oNuzMLmbz8aOrCvFQ3Dg0=", - "dev": true, - "requires": { - "array-union": "^1.0.1", - "arrify": "^1.0.0", - "glob": "^7.0.3", - "object-assign": "^4.0.1", - "pify": "^2.0.0", - "pinkie-promise": "^2.0.0" - } - }, - "graceful-fs": { - "version": "4.1.11", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.11.tgz", - "integrity": "sha1-Dovf5NHduIVNZOBOp8AOKgJuVlg=", - "dev": true - }, - "grizzly": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/grizzly/-/grizzly-3.0.3.tgz", - "integrity": "sha512-IGcSYOg8W75e1/92oHy1RgO4fiWxWYi94C5nwjJwTe5usRx241LkqiO4923LVLwkon7ro69ZKcCbI4ox25pDOw==", - "dev": true, - "requires": { - "@octokit/rest": "^14.0.7", - "checkup": "^1.3.0", - "debug": "^3.0.0", - "execon": "^1.2.0", - "minimist": "^1.2.0", - "readjson": "^1.1.0" - }, - "dependencies": { - "debug": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", - "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "minimist": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", - "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", - "dev": true - } - } - }, - "has": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", - "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", - "dev": true, - "requires": { - "function-bind": "^1.1.1" - } - }, - "has-ansi": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", - "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=", - "dev": true, - "requires": { - "ansi-regex": "^2.0.0" - } - }, - "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=" - }, - "has-symbols": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.0.tgz", - "integrity": "sha1-uhqPGvKg/DllD1yFA2dwQSIGO0Q=", - "dev": true - }, - "home-or-tmp": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/home-or-tmp/-/home-or-tmp-2.0.0.tgz", - "integrity": "sha1-42w/LSyufXRqhX440Y1fMqeILbg=", - "dev": true, - "requires": { - "os-homedir": "^1.0.0", - "os-tmpdir": "^1.0.1" - } - }, - "iconv-lite": { - "version": "0.4.23", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.23.tgz", - "integrity": "sha512-neyTUVFtahjf0mB3dZT77u+8O0QB89jFdnBkd5P1JgYPbPaia3gXXOVL2fq8VyU2gMMD7SaN7QukTB/pmXYvDA==", - "dev": true, - "requires": { - "safer-buffer": ">= 2.1.2 < 3" - } - }, - "ignore": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.5.tgz", - "integrity": "sha512-Q2daVnMtQJPacGrcCRyOEiI+syPCt+mR4YotoC0KEYeinV/6HztT5mUuVEj7UYyoNZ1jGYiu2XEem7I8oM44bg==", - "dev": true - }, - "imurmurhash": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", - "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", - "dev": true - }, - "inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", - "dev": true, - "requires": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "inherits": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", - "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", - "dev": true - }, - "inquirer": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-5.2.0.tgz", - "integrity": "sha512-E9BmnJbAKLPGonz0HeWHtbKf+EeSP93paWO3ZYoUpq/aowXvYGjjCSuashhXPpzbArIjBbji39THkxTz9ZeEUQ==", - "dev": true, - "requires": { - "ansi-escapes": "^3.0.0", - "chalk": "^2.0.0", - "cli-cursor": "^2.1.0", - "cli-width": "^2.0.0", - "external-editor": "^2.1.0", - "figures": "^2.0.0", - "lodash": "^4.3.0", - "mute-stream": "0.0.7", - "run-async": "^2.2.0", - "rxjs": "^5.5.2", - "string-width": "^2.1.0", - "strip-ansi": "^4.0.0", - "through": "^2.3.6" - }, - "dependencies": { - "ansi-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", - "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", - "dev": true - }, - "strip-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", - "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", - "dev": true, - "requires": { - "ansi-regex": "^3.0.0" - } - } - } - }, - "invariant": { - "version": "2.2.4", - "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz", - "integrity": "sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==", - "dev": true, - "requires": { - "loose-envify": "^1.0.0" - } - }, - "is-array-buffer": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-1.0.1.tgz", - "integrity": "sha512-lj035IqdAwsodoRGs9/8+Kn3HPoz9CTuZbcw63afugWonxigvUVeHY5d6Ve1O+s1N3RCk7txo2TIWQLbU0SuNA==", - "dev": true - }, - "is-binary-path": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-1.0.1.tgz", - "integrity": "sha1-dfFmQrSA8YenEcgUFh/TpKdlWJg=", - "dev": true, - "optional": true, - "requires": { - "binary-extensions": "^1.0.0" - } - }, - "is-buffer": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", - "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==", - "dev": true - }, - "is-callable": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.1.4.tgz", - "integrity": "sha512-r5p9sxJjYnArLjObpjA4xu5EKI3CuKHkJXMhT7kwbpUyIFD1n5PMAsoPvWnvtZiNz7LjkYDRZhd7FlI0eMijEA==", - "dev": true - }, - "is-date-object": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.1.tgz", - "integrity": "sha1-mqIOtq7rv/d/vTPnTKAbM1gdOhY=", - "dev": true - }, - "is-dotfile": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/is-dotfile/-/is-dotfile-1.0.3.tgz", - "integrity": "sha1-pqLzL/0t+wT1yiXs0Pa4PPeYoeE=", - "dev": true, - "optional": true - }, - "is-equal-shallow": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/is-equal-shallow/-/is-equal-shallow-0.1.3.tgz", - "integrity": "sha1-IjgJj8Ih3gvPpdnqxMRdY4qhxTQ=", - "dev": true, - "optional": true, - "requires": { - "is-primitive": "^2.0.0" - } - }, - "is-extendable": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", - "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=", - "dev": true, - "optional": true - }, - "is-extglob": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-1.0.0.tgz", - "integrity": "sha1-rEaBd8SUNAWgkvyPKXYMb/xiBsA=", - "dev": true - }, - "is-finite": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-finite/-/is-finite-1.0.2.tgz", - "integrity": "sha1-zGZ3aVYCvlUO8R6LSqYwU0K20Ko=", - "dev": true, - "requires": { - "number-is-nan": "^1.0.0" - } - }, - "is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", - "dev": true - }, - "is-glob": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-2.0.1.tgz", - "integrity": "sha1-0Jb5JqPe1WAPP9/ZEZjLCIjC2GM=", - "dev": true, - "requires": { - "is-extglob": "^1.0.0" - } - }, - "is-number": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-2.1.0.tgz", - "integrity": "sha1-Afy7s5NGOlSPL0ZszhbezknbkI8=", - "dev": true, - "optional": true, - "requires": { - "kind-of": "^3.0.2" - } - }, - "is-path-cwd": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-path-cwd/-/is-path-cwd-1.0.0.tgz", - "integrity": "sha1-0iXsIxMuie3Tj9p2dHLmLmXxEG0=", - "dev": true - }, - "is-path-in-cwd": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-path-in-cwd/-/is-path-in-cwd-1.0.1.tgz", - "integrity": "sha512-FjV1RTW48E7CWM7eE/J2NJvAEEVektecDBVBE5Hh3nM1Jd0kvhHtX68Pr3xsDf857xt3Y4AkwVULK1Vku62aaQ==", - "dev": true, - "requires": { - "is-path-inside": "^1.0.0" - } - }, - "is-path-inside": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-1.0.1.tgz", - "integrity": "sha1-jvW33lBDej/cprToZe96pVy0gDY=", - "dev": true, - "requires": { - "path-is-inside": "^1.0.1" - } - }, - "is-posix-bracket": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/is-posix-bracket/-/is-posix-bracket-0.1.1.tgz", - "integrity": "sha1-MzTceXdDaOkvAW5vvAqI9c1ua8Q=", - "dev": true, - "optional": true - }, - "is-primitive": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-primitive/-/is-primitive-2.0.0.tgz", - "integrity": "sha1-IHurkWOEmcB7Kt8kCkGochADRXU=", - "dev": true, - "optional": true - }, - "is-promise": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-2.1.0.tgz", - "integrity": "sha1-eaKp7OfwlugPNtKy87wWwf9L8/o=", - "dev": true - }, - "is-regex": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.0.4.tgz", - "integrity": "sha1-VRdIm1RwkbCTDglWVM7SXul+lJE=", - "dev": true, - "requires": { - "has": "^1.0.1" - } - }, - "is-resolvable": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-resolvable/-/is-resolvable-1.1.0.tgz", - "integrity": "sha512-qgDYXFSR5WvEfuS5dMj6oTMEbrrSaM0CrFk2Yiq/gXnBvD9pMa2jGXxyhGLfvhZpuMZe18CJpFxAt3CRs42NMg==", - "dev": true - }, - "is-stream": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", - "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=", - "dev": true - }, - "is-symbol": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.1.tgz", - "integrity": "sha1-PMWfAAJRlLarLjjbrmaJJWtmBXI=", - "dev": true - }, - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", - "dev": true - }, - "isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", - "dev": true - }, - "isobject": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", - "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=", - "dev": true, - "optional": true, - "requires": { - "isarray": "1.0.0" - } - }, - "js-tokens": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-3.0.2.tgz", - "integrity": "sha1-mGbfOVECEw449/mWvOtlRDIJwls=", - "dev": true - }, - "js-yaml": { - "version": "3.12.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.12.0.tgz", - "integrity": "sha512-PIt2cnwmPfL4hKNwqeiuz4bKfnzHTBv6HyVgjahA6mPLwPDzjDWrplJBMjHUFxku/N3FlmrbyPclad+I+4mJ3A==", - "dev": true, - "requires": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" - } - }, - "jsesc": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-1.3.0.tgz", - "integrity": "sha1-RsP+yMGJKxKwgz25vHYiF226s0s=", - "dev": true - }, - "json-schema-traverse": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", - "dev": true - }, - "json-stable-stringify-without-jsonify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", - "integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=", - "dev": true - }, - "json5": { - "version": "0.5.1", - "resolved": "https://registry.npmjs.org/json5/-/json5-0.5.1.tgz", - "integrity": "sha1-Hq3nrMASA0rYTiOWdn6tn6VJWCE=", - "dev": true - }, - "jsonfile": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-2.4.0.tgz", - "integrity": "sha1-NzaitCi4e72gzIO1P6PWM6NcKug=", - "dev": true, - "requires": { - "graceful-fs": "^4.1.6" - } - }, - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - }, - "klaw": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/klaw/-/klaw-1.3.1.tgz", - "integrity": "sha1-QIhDO0azsbolnXh4XY6W9zugJDk=", - "dev": true, - "requires": { - "graceful-fs": "^4.1.9" - } - }, - "levn": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", - "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=", - "dev": true, - "requires": { - "prelude-ls": "~1.1.2", - "type-check": "~0.3.2" - } - }, - "lodash": { - "version": "4.17.10", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.10.tgz", - "integrity": "sha512-UejweD1pDoXu+AD825lWwp4ZGtSwgnpZxb3JDViD7StjQz+Nb/6l093lx4OQ0foGWNRoc19mWy7BzL+UAK2iVg==", - "dev": true - }, - "loose-envify": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", - "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", - "dev": true, - "requires": { - "js-tokens": "^3.0.0 || ^4.0.0" - } - }, - "lru-cache": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.3.tgz", - "integrity": "sha512-fFEhvcgzuIoJVUF8fYr5KR0YqxD238zgObTps31YdADwPPAp82a4M8TrckkWyx7ekNlf9aBcVn81cFwwXngrJA==", - "dev": true, - "requires": { - "pseudomap": "^1.0.2", - "yallist": "^2.1.2" - } - }, - "math-random": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/math-random/-/math-random-1.0.1.tgz", - "integrity": "sha1-izqsWIuKZuSXXjzepn97sylgH6w=", - "dev": true, - "optional": true - }, - "micromatch": { - "version": "2.3.11", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-2.3.11.tgz", - "integrity": "sha1-hmd8l9FyCzY0MdBNDRUpO9OMFWU=", - "dev": true, - "optional": true, - "requires": { - "arr-diff": "^2.0.0", - "array-unique": "^0.2.1", - "braces": "^1.8.2", - "expand-brackets": "^0.1.4", - "extglob": "^0.3.1", - "filename-regex": "^2.0.0", - "is-extglob": "^1.0.0", - "is-glob": "^2.0.1", - "kind-of": "^3.0.2", - "normalize-path": "^2.0.1", - "object.omit": "^2.0.0", - "parse-glob": "^3.0.4", - "regex-cache": "^0.4.2" - } - }, - "mimic-fn": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-1.2.0.tgz", - "integrity": "sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ==", - "dev": true - }, - "minimatch": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", - "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", - "dev": true, - "requires": { - "brace-expansion": "^1.1.7" - } - }, - "minimist": { - "version": "0.0.8", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", - "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=", - "dev": true - }, - "mkdirp": { - "version": "0.5.1", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", - "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", - "dev": true, - "requires": { - "minimist": "0.0.8" - } - }, - "mount-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/mount-point/-/mount-point-3.0.0.tgz", - "integrity": "sha1-Zly57evoDREOZY21bDHQrvUaj5c=", - "dev": true, - "requires": { - "@sindresorhus/df": "^1.0.1", - "pify": "^2.3.0", - "pinkie-promise": "^2.0.1" - }, - "dependencies": { - "@sindresorhus/df": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@sindresorhus/df/-/df-1.0.1.tgz", - "integrity": "sha1-xptm9S9vzdKHyAffIQMF2694UA0=", - "dev": true - } - } - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", - "dev": true - }, - "mute-stream": { - "version": "0.0.7", - "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.7.tgz", - "integrity": "sha1-MHXOk7whuPq0PhvE2n6BFe0ee6s=", - "dev": true - }, - "nan": { - "version": "2.10.0", - "resolved": "https://registry.npmjs.org/nan/-/nan-2.10.0.tgz", - "integrity": "sha512-bAdJv7fBLhWC+/Bls0Oza+mvTaNQtP+1RyhhhvD95pgUJz6XM5IzgmxOkItJ9tkoCiplvAnXI1tNmmUD/eScyA==", - "dev": true, - "optional": true - }, - "natural-compare": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", - "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=", - "dev": true - }, - "nice-try": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.4.tgz", - "integrity": "sha512-2NpiFHqC87y/zFke0fC0spBXL3bBsoh/p5H1EFhshxjCR5+0g2d6BiXbUFz9v1sAcxsk2htp2eQnNIci2dIYcA==", - "dev": true - }, - "normalize-path": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", - "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", - "dev": true, - "requires": { - "remove-trailing-separator": "^1.0.1" - } - }, - "npm-run-path": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-1.0.0.tgz", - "integrity": "sha1-9cMr9ZX+ga6Sfa7FLoL4sACsPI8=", - "dev": true, - "requires": { - "path-key": "^1.0.0" - }, - "dependencies": { - "path-key": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-1.0.0.tgz", - "integrity": "sha1-XVPVeAGWRsDWiADbThRua9wqx68=", - "dev": true - } - } - }, - "npmpub": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/npmpub/-/npmpub-4.1.0.tgz", - "integrity": "sha512-aFaX5gp09tl5NxpqxkHg1QCZrTx6QHBLfQkfonXR0ohwvWeNJItFVSN2R+6IVKtLis085A6zbOUi8r6lMtPO9A==", - "dev": true, - "requires": { - "chalk": "^1.1.1", - "github-release-from-changelog": "^1.3.2", - "minimist": "^1.2.0", - "shelljs": "^0.5.3", - "trash": "^3.4.1" - }, - "dependencies": { - "ansi-styles": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", - "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", - "dev": true - }, - "chalk": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", - "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", - "dev": true, - "requires": { - "ansi-styles": "^2.2.1", - "escape-string-regexp": "^1.0.2", - "has-ansi": "^2.0.0", - "strip-ansi": "^3.0.0", - "supports-color": "^2.0.0" - } - }, - "minimist": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", - "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", - "dev": true - }, - "supports-color": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", - "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", - "dev": true - } - } - }, - "number-is-nan": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", - "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=", - "dev": true - }, - "object-assign": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", - "dev": true - }, - "object-inspect": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.6.0.tgz", - "integrity": "sha512-GJzfBZ6DgDAmnuaM3104jR4s1Myxr3Y3zfIyN4z3UdqN69oSRacNK8UhnobDdC+7J2AHCjGwxQubNJfE70SXXQ==", - "dev": true - }, - "object-keys": { - "version": "1.0.12", - "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.0.12.tgz", - "integrity": "sha512-FTMyFUm2wBcGHnH2eXmz7tC6IwlqQZ6mVZ+6dm6vZ4IQIHjs6FdNsQBuKGPuUUUY6NfJw2PshC08Tn6LzLDOag==", - "dev": true - }, - "object.omit": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/object.omit/-/object.omit-2.0.1.tgz", - "integrity": "sha1-Gpx0SCnznbuFjHbKNXmuKlTr0fo=", - "dev": true, - "optional": true, - "requires": { - "for-own": "^0.1.4", - "is-extendable": "^0.1.1" - } - }, - "once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", - "dev": true, - "requires": { - "wrappy": "1" - } - }, - "onetime": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-2.0.1.tgz", - "integrity": "sha1-BnQoIw/WdEOyeUsiu6UotoZ5YtQ=", - "dev": true, - "requires": { - "mimic-fn": "^1.0.0" - } - }, - "optionator": { - "version": "0.8.2", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.2.tgz", - "integrity": "sha1-NkxeQJ0/TWMB1sC0wFu6UBgK62Q=", - "dev": true, - "requires": { - "deep-is": "~0.1.3", - "fast-levenshtein": "~2.0.4", - "levn": "~0.3.0", - "prelude-ls": "~1.1.2", - "type-check": "~0.3.2", - "wordwrap": "~1.0.0" - } - }, - "os-homedir": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz", - "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=", - "dev": true - }, - "os-tmpdir": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", - "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=", - "dev": true - }, - "output-file-sync": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/output-file-sync/-/output-file-sync-1.1.2.tgz", - "integrity": "sha1-0KM+7+YaIF+suQCS6CZZjVJFznY=", - "dev": true, - "requires": { - "graceful-fs": "^4.1.4", - "mkdirp": "^0.5.1", - "object-assign": "^4.1.0" - } - }, - "parse-glob": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/parse-glob/-/parse-glob-3.0.4.tgz", - "integrity": "sha1-ssN2z7EfNVE7rdFz7wu246OIORw=", - "dev": true, - "optional": true, - "requires": { - "glob-base": "^0.3.0", - "is-dotfile": "^1.0.0", - "is-extglob": "^1.0.0", - "is-glob": "^2.0.0" - } - }, - "path-exists": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-2.1.0.tgz", - "integrity": "sha1-D+tsZPD8UY2adU3V77YscCJ2H0s=", - "dev": true, - "requires": { - "pinkie-promise": "^2.0.0" - } - }, - "path-is-absolute": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", - "dev": true - }, - "path-is-inside": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz", - "integrity": "sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM=", - "dev": true - }, - "path-key": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", - "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=", - "dev": true - }, - "path-parse": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz", - "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==", - "dev": true - }, - "pify": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", - "dev": true - }, - "pinkie": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz", - "integrity": "sha1-clVrgM+g1IqXToDnckjoDtT3+HA=", - "dev": true - }, - "pinkie-promise": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz", - "integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=", - "dev": true, - "requires": { - "pinkie": "^2.0.0" - } - }, - "pluralize": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/pluralize/-/pluralize-7.0.0.tgz", - "integrity": "sha512-ARhBOdzS3e41FbkW/XWrTEtukqqLoK5+Z/4UeDaLuSW+39JPeFgs4gCGqsrJHVZX0fUrx//4OF0K1CUGwlIFow==", - "dev": true - }, - "postcss": { - "version": "7.0.2", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.2.tgz", - "integrity": "sha512-fmaUY5370keLUTx+CnwRxtGiuFTcNBLQBqr1oE3WZ/euIYmGAo0OAgOhVJ3ByDnVmOR3PK+0V9VebzfjRIUcqw==", - "requires": { - "chalk": "^2.4.1", - "source-map": "^0.6.1", - "supports-color": "^5.4.0" - } - }, - "prelude-ls": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", - "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=", - "dev": true - }, - "preserve": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/preserve/-/preserve-0.2.0.tgz", - "integrity": "sha1-gV7R9uvGWSb4ZbMQwHE7yzMVzks=", - "dev": true, - "optional": true - }, - "private": { - "version": "0.1.8", - "resolved": "https://registry.npmjs.org/private/-/private-0.1.8.tgz", - "integrity": "sha512-VvivMrbvd2nKkiG38qjULzlc+4Vx4wm/whI9pQD35YrARNnhxeiRktSOhSukRLFNlzg6Br/cJPet5J/u19r/mg==", - "dev": true - }, - "process-nextick-args": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.0.tgz", - "integrity": "sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw==", - "dev": true, - "optional": true - }, - "progress": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.0.tgz", - "integrity": "sha1-ihvjZr+Pwj2yvSPxDG/pILQ4nR8=", - "dev": true - }, - "pseudomap": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", - "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=", - "dev": true - }, - "punycode": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", - "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", - "dev": true - }, - "randomatic": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/randomatic/-/randomatic-3.1.0.tgz", - "integrity": "sha512-KnGPVE0lo2WoXxIZ7cPR8YBpiol4gsSuOwDSg410oHh80ZMp5EiypNqL2K4Z77vJn6lB5rap7IkAmcUlalcnBQ==", - "dev": true, - "optional": true, - "requires": { - "is-number": "^4.0.0", - "kind-of": "^6.0.0", - "math-random": "^1.0.1" - }, - "dependencies": { - "is-number": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-4.0.0.tgz", - "integrity": "sha512-rSklcAIlf1OmFdyAqbnWTLVelsQ58uvZ66S/ZyawjWqIviTWCjg2PzVGw8WUA+nNuPTqb4wgA+NszrJ+08LlgQ==", - "dev": true, - "optional": true - }, - "kind-of": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", - "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==", - "dev": true, - "optional": true - } - } - }, - "readable-stream": { - "version": "2.3.6", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", - "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", - "dev": true, - "optional": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "readdirp": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-2.1.0.tgz", - "integrity": "sha1-TtCtBg3zBzMAxIRANz9y0cxkLXg=", - "dev": true, - "optional": true, - "requires": { - "graceful-fs": "^4.1.2", - "minimatch": "^3.0.2", - "readable-stream": "^2.0.2", - "set-immediate-shim": "^1.0.1" - } - }, - "readjson": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/readjson/-/readjson-1.1.4.tgz", - "integrity": "sha512-H4dRk2S67w3HtE1apnw5wlHpN9qkJ0pen0AcEvyAfnrPfskZIyUOYLXpfN6olDQZI+eUlxg0Yo4lJ2bymujOUA==", - "dev": true, - "requires": { - "try-catch": "^2.0.0" - } - }, - "regenerate": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.0.tgz", - "integrity": "sha512-1G6jJVDWrt0rK99kBjvEtziZNCICAuvIPkSiUFIQxVP06RCVpq3dmDo2oi6ABpYaDYaTRr67BEhL8r1wgEZZKg==", - "dev": true - }, - "regenerator-runtime": { - "version": "0.11.1", - "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz", - "integrity": "sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg==", - "dev": true - }, - "regenerator-transform": { - "version": "0.10.1", - "resolved": "https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.10.1.tgz", - "integrity": "sha512-PJepbvDbuK1xgIgnau7Y90cwaAmO/LCLMI2mPvaXq2heGMR3aWW5/BQvYrhJ8jgmQjXewXvBjzfqKcVOmhjZ6Q==", - "dev": true, - "requires": { - "babel-runtime": "^6.18.0", - "babel-types": "^6.19.0", - "private": "^0.1.6" - } - }, - "regex-cache": { - "version": "0.4.4", - "resolved": "https://registry.npmjs.org/regex-cache/-/regex-cache-0.4.4.tgz", - "integrity": "sha512-nVIZwtCjkC9YgvWkpM55B5rBhBYRZhAaJbgcFYXXsHnbZ9UZI9nnVWYZpBlCqv9ho2eZryPnWrZGsOdPwVWXWQ==", - "dev": true, - "optional": true, - "requires": { - "is-equal-shallow": "^0.1.3" - } - }, - "regexp.prototype.flags": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.2.0.tgz", - "integrity": "sha512-ztaw4M1VqgMwl9HlPpOuiYgItcHlunW0He2fE6eNfT6E/CF2FtYi9ofOYe4mKntstYk0Fyh/rDRBdS3AnxjlrA==", - "dev": true, - "requires": { - "define-properties": "^1.1.2" - } - }, - "regexpp": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-2.0.0.tgz", - "integrity": "sha512-g2FAVtR8Uh8GO1Nv5wpxW7VFVwHcCEr4wyA8/MHiRkO8uHoR5ntAA8Uq3P1vvMTX/BeQiRVSpDGLd+Wn5HNOTA==", - "dev": true - }, - "regexpu-core": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-2.0.0.tgz", - "integrity": "sha1-SdA4g3uNz4v6W5pCE5k45uoq4kA=", - "dev": true, - "requires": { - "regenerate": "^1.2.1", - "regjsgen": "^0.2.0", - "regjsparser": "^0.1.4" - } - }, - "regjsgen": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/regjsgen/-/regjsgen-0.2.0.tgz", - "integrity": "sha1-bAFq3qxVT3WCP+N6wFuS1aTtsfc=", - "dev": true - }, - "regjsparser": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.1.5.tgz", - "integrity": "sha1-fuj4Tcb6eS0/0K4ijSS9lJ6tIFw=", - "dev": true, - "requires": { - "jsesc": "~0.5.0" - }, - "dependencies": { - "jsesc": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-0.5.0.tgz", - "integrity": "sha1-597mbjXW/Bb3EP6R1c9p9w8IkR0=", - "dev": true - } - } - }, - "remove-trailing-separator": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz", - "integrity": "sha1-wkvOKig62tW8P1jg1IJJuSN52O8=", - "dev": true - }, - "repeat-element": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.2.tgz", - "integrity": "sha1-7wiaF40Ug7quTZPrmLT55OEdmQo=", - "dev": true - }, - "repeat-string": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", - "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=", - "dev": true, - "optional": true - }, - "repeating": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/repeating/-/repeating-2.0.1.tgz", - "integrity": "sha1-UhTFOpJtNVJwdSf7q0FdvAjQbdo=", - "dev": true, - "requires": { - "is-finite": "^1.0.0" - } - }, - "require-uncached": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/require-uncached/-/require-uncached-1.0.3.tgz", - "integrity": "sha1-Tg1W1slmL9MeQwEcS5WqSZVUIdM=", - "dev": true, - "requires": { - "caller-path": "^0.1.0", - "resolve-from": "^1.0.0" - } - }, - "resolve": { - "version": "1.7.1", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.7.1.tgz", - "integrity": "sha512-c7rwLofp8g1U+h1KNyHL/jicrKg1Ek4q+Lr33AL65uZTinUZHe30D5HlyN5V9NW0JX1D5dXQ4jqW5l7Sy/kGfw==", - "dev": true, - "requires": { - "path-parse": "^1.0.5" - } - }, - "resolve-from": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-1.0.1.tgz", - "integrity": "sha1-Jsv+k10a7uq7Kbw/5a6wHpPUQiY=", - "dev": true - }, - "restore-cursor": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-2.0.0.tgz", - "integrity": "sha1-n37ih/gv0ybU/RYpI9YhKe7g368=", - "dev": true, - "requires": { - "onetime": "^2.0.0", - "signal-exit": "^3.0.2" - } - }, - "resumer": { - "version": "0.0.0", - "resolved": "https://registry.npmjs.org/resumer/-/resumer-0.0.0.tgz", - "integrity": "sha1-8ej0YeQGS6Oegq883CqMiT0HZ1k=", - "dev": true, - "requires": { - "through": "~2.3.4" - } - }, - "rimraf": { - "version": "2.6.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.2.tgz", - "integrity": "sha512-lreewLK/BlghmxtfH36YYVg1i8IAce4TI7oao75I1g245+6BctqTVQiBP3YUJ9C6DQOXJmkYR9X9fCLtCOJc5w==", - "dev": true, - "requires": { - "glob": "^7.0.5" - } - }, - "run-applescript": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/run-applescript/-/run-applescript-2.1.0.tgz", - "integrity": "sha1-O/8sz5W2zqy0lyPlUPADcdYYUQ0=", - "dev": true, - "requires": { - "pify": "^2.2.0", - "pinkie-promise": "^2.0.0" - } - }, - "run-async": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.3.0.tgz", - "integrity": "sha1-A3GrSuC91yDUFm19/aZP96RFpsA=", - "dev": true, - "requires": { - "is-promise": "^2.1.0" - } - }, - "rxjs": { - "version": "5.5.11", - "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-5.5.11.tgz", - "integrity": "sha512-3bjO7UwWfA2CV7lmwYMBzj4fQ6Cq+ftHc2MvUe+WMS7wcdJ1LosDWmdjPQanYp2dBRj572p7PeU81JUxHKOcBA==", - "dev": true, - "requires": { - "symbol-observable": "1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "safer-buffer": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", - "dev": true - }, - "semver": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.5.0.tgz", - "integrity": "sha512-4SJ3dm0WAwWy/NVeioZh5AntkdJoWKxHxcmyP622fOkgHa4z3R0TdBJICINyaSDE6uNwVc8gZr+ZinwZAH4xIA==", - "dev": true - }, - "set-immediate-shim": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/set-immediate-shim/-/set-immediate-shim-1.0.1.tgz", - "integrity": "sha1-SysbJ+uAip+NzEgaWOXlb1mfP2E=", - "dev": true, - "optional": true - }, - "shebang-command": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", - "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=", - "dev": true, - "requires": { - "shebang-regex": "^1.0.0" - } - }, - "shebang-regex": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", - "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=", - "dev": true - }, - "shelljs": { - "version": "0.5.3", - "resolved": "https://registry.npmjs.org/shelljs/-/shelljs-0.5.3.tgz", - "integrity": "sha1-xUmCuZbHbvDB5rWfvcWCX1txMRM=", - "dev": true - }, - "signal-exit": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz", - "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=", - "dev": true - }, - "slash": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-1.0.0.tgz", - "integrity": "sha1-xB8vbDn8FtHNF61LXYlhFK5HDVU=", - "dev": true - }, - "slice-ansi": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-1.0.0.tgz", - "integrity": "sha512-POqxBK6Lb3q6s047D/XsDVNPnF9Dl8JSaqe9h9lURl0OdNqy/ujDrOiIHtsqXMGbWWTIomRzAMaTyawAU//Reg==", - "dev": true, - "requires": { - "is-fullwidth-code-point": "^2.0.0" - } - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" - }, - "source-map-support": { - "version": "0.4.18", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.4.18.tgz", - "integrity": "sha512-try0/JqxPLF9nOjvSta7tVondkP5dwgyLDjVoyMDlmjugT2lRZ1OfsrYTkCd2hkDnJTKRbO/Rl3orm8vlsUzbA==", - "dev": true, - "requires": { - "source-map": "^0.5.6" - }, - "dependencies": { - "source-map": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", - "dev": true - } - } - }, - "sprintf-js": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", - "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", - "dev": true - }, - "string-width": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", - "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", - "dev": true, - "requires": { - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^4.0.0" - }, - "dependencies": { - "ansi-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", - "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", - "dev": true - }, - "strip-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", - "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", - "dev": true, - "requires": { - "ansi-regex": "^3.0.0" - } - } - } - }, - "string.prototype.matchall": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/string.prototype.matchall/-/string.prototype.matchall-2.0.0.tgz", - "integrity": "sha512-WoZ+B2ypng1dp4iFLF2kmZlwwlE19gmjgKuhL1FJfDgCREWb3ye3SDVHSzLH6bxfnvYmkCxbzkmWcQZHA4P//Q==", - "dev": true, - "requires": { - "define-properties": "^1.1.2", - "es-abstract": "^1.10.0", - "function-bind": "^1.1.1", - "has-symbols": "^1.0.0", - "regexp.prototype.flags": "^1.2.0" - } - }, - "string.prototype.trim": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.1.2.tgz", - "integrity": "sha1-0E3iyJ4Tf019IG8Ia17S+ua+jOo=", - "dev": true, - "requires": { - "define-properties": "^1.1.2", - "es-abstract": "^1.5.0", - "function-bind": "^1.0.2" - } - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "optional": true, - "requires": { - "safe-buffer": "~5.1.0" - } - }, - "strip-ansi": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", - "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", - "dev": true, - "requires": { - "ansi-regex": "^2.0.0" - } - }, - "strip-eof": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz", - "integrity": "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8=", - "dev": true - }, - "strip-json-comments": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", - "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=", - "dev": true - }, - "supports-color": { - "version": "5.4.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.4.0.tgz", - "integrity": "sha512-zjaXglF5nnWpsq470jSv6P9DwPvgLkuapYmfDm3JWOm0vkNTVF2tI4UrN2r6jH1qM/uc/WtxYY1hYoA2dOKj5w==", - "requires": { - "has-flag": "^3.0.0" - } - }, - "symbol-observable": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/symbol-observable/-/symbol-observable-1.0.1.tgz", - "integrity": "sha1-g0D8RwLDEi310iKI+IKD9RPT/dQ=", - "dev": true - }, - "table": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/table/-/table-4.0.3.tgz", - "integrity": "sha512-S7rnFITmBH1EnyKcvxBh1LjYeQMmnZtCXSEbHcH6S0NoKit24ZuFO/T1vDcLdYsLQkM188PVVhQmzKIuThNkKg==", - "dev": true, - "requires": { - "ajv": "^6.0.1", - "ajv-keywords": "^3.0.0", - "chalk": "^2.1.0", - "lodash": "^4.17.4", - "slice-ansi": "1.0.0", - "string-width": "^2.1.1" - } - }, - "tape": { - "version": "4.9.1", - "resolved": "https://registry.npmjs.org/tape/-/tape-4.9.1.tgz", - "integrity": "sha512-6fKIXknLpoe/Jp4rzHKFPpJUHDHDqn8jus99IfPnHIjyz78HYlefTGD3b5EkbQzuLfaEvmfPK3IolLgq2xT3kw==", - "dev": true, - "requires": { - "deep-equal": "~1.0.1", - "defined": "~1.0.0", - "for-each": "~0.3.3", - "function-bind": "~1.1.1", - "glob": "~7.1.2", - "has": "~1.0.3", - "inherits": "~2.0.3", - "minimist": "~1.2.0", - "object-inspect": "~1.6.0", - "resolve": "~1.7.1", - "resumer": "~0.0.0", - "string.prototype.trim": "~1.1.2", - "through": "~2.3.8" - }, - "dependencies": { - "minimist": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", - "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", - "dev": true - } - } - }, - "text-table": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", - "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=", - "dev": true - }, - "through": { - "version": "2.3.8", - "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", - "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=", - "dev": true - }, - "tmp": { - "version": "0.0.33", - "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", - "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", - "dev": true, - "requires": { - "os-tmpdir": "~1.0.2" - } - }, - "to-fast-properties": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-1.0.3.tgz", - "integrity": "sha1-uDVx+k2MJbguIxsG46MFXeTKGkc=", - "dev": true - }, - "trash": { - "version": "3.4.2", - "resolved": "https://registry.npmjs.org/trash/-/trash-3.4.2.tgz", - "integrity": "sha1-+wQiUvwmoCInaVCiuw7Om5QF6xk=", - "dev": true, - "requires": { - "escape-string-applescript": "^1.0.0", - "fs-extra": "^0.26.2", - "globby": "^4.0.0", - "path-exists": "^2.0.0", - "pify": "^2.3.0", - "pinkie-promise": "^2.0.0", - "run-applescript": "^2.0.0", - "uuid": "^2.0.1", - "xdg-trashdir": "^2.0.0" - }, - "dependencies": { - "glob": { - "version": "6.0.4", - "resolved": "https://registry.npmjs.org/glob/-/glob-6.0.4.tgz", - "integrity": "sha1-DwiGD2oVUSey+t1PnOJLGqtuTSI=", - "dev": true, - "requires": { - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "2 || 3", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "globby": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/globby/-/globby-4.1.0.tgz", - "integrity": "sha1-CA9UVJ7BuCpsYOYx/ILhIR2+lfg=", - "dev": true, - "requires": { - "array-union": "^1.0.1", - "arrify": "^1.0.0", - "glob": "^6.0.1", - "object-assign": "^4.0.1", - "pify": "^2.0.0", - "pinkie-promise": "^2.0.0" - } - } - } - }, - "trim-right": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/trim-right/-/trim-right-1.0.1.tgz", - "integrity": "sha1-yy4SAwZ+DI3h9hQJS5/kVwTqYAM=", - "dev": true - }, - "try-catch": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/try-catch/-/try-catch-2.0.0.tgz", - "integrity": "sha512-RPXpVjsbtWgymwGq5F/OWDFsjEzdvzwHFaMjWWW6f/p6+uk/N7YSKJHQfIfGqITfj8qH4cBqCLMnhKZBaKk7Kg==", - "dev": true - }, - "type-check": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", - "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=", - "dev": true, - "requires": { - "prelude-ls": "~1.1.2" - } - }, - "uri-js": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.2.2.tgz", - "integrity": "sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ==", - "dev": true, - "requires": { - "punycode": "^2.1.0" - } - }, - "url-template": { - "version": "2.0.8", - "resolved": "https://registry.npmjs.org/url-template/-/url-template-2.0.8.tgz", - "integrity": "sha1-/FZaPMy/93MMd19WQflVV5FDnyE=", - "dev": true - }, - "user-home": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/user-home/-/user-home-1.1.1.tgz", - "integrity": "sha1-K1viOjK2Onyd640PKNSFcko98ZA=", - "dev": true - }, - "util-deprecate": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=", - "dev": true, - "optional": true - }, - "uuid": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-2.0.3.tgz", - "integrity": "sha1-Z+LoY3lyFVMN/zGOW/nc6/1Hsho=", - "dev": true - }, - "v8flags": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/v8flags/-/v8flags-2.1.1.tgz", - "integrity": "sha1-qrGh+jDUX4jdMhFIh1rALAtV5bQ=", - "dev": true, - "requires": { - "user-home": "^1.1.1" - } - }, - "which": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", - "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", - "dev": true, - "requires": { - "isexe": "^2.0.0" - } - }, - "wordwrap": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", - "integrity": "sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus=", - "dev": true - }, - "wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", - "dev": true - }, - "write": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/write/-/write-0.2.1.tgz", - "integrity": "sha1-X8A4KOJkzqP+kUVUdvejxWbLB1c=", - "dev": true, - "requires": { - "mkdirp": "^0.5.1" - } - }, - "xdg-basedir": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/xdg-basedir/-/xdg-basedir-2.0.0.tgz", - "integrity": "sha1-7byQPMOF/ARSPZZqM1UEtVBNG9I=", - "dev": true, - "requires": { - "os-homedir": "^1.0.0" - } - }, - "xdg-trashdir": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/xdg-trashdir/-/xdg-trashdir-2.1.1.tgz", - "integrity": "sha512-KcVhPaOu2ZurYNHSRTf1+ZHORkTZGCQ+u0JHN17QixRISJq4pXOnjt/lQcehvtHL5QAKhSzKgyjrcNnPdkPBHA==", - "dev": true, - "requires": { - "@sindresorhus/df": "^2.1.0", - "mount-point": "^3.0.0", - "pify": "^2.2.0", - "user-home": "^2.0.0", - "xdg-basedir": "^2.0.0" - }, - "dependencies": { - "user-home": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/user-home/-/user-home-2.0.0.tgz", - "integrity": "sha1-nHC/2Babwdy/SGBODwS4tJzenp8=", - "dev": true, - "requires": { - "os-homedir": "^1.0.0" - } - } - } - }, - "yallist": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", - "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=", - "dev": true - } - } -} diff --git a/package.json b/package.json index 4b1b5a5dd5..d3718732cd 100644 --- a/package.json +++ b/package.json @@ -1,44 +1,62 @@ { "name": "postcss-custom-properties", - "version": "7.0.0", - "description": "PostCSS plugin to polyfill W3C CSS Custom Properties for cascading variables", - "keywords": [ - "css", - "postcss", - "postcss-plugin", - "custom-properties", - "variables", - "vars" + "version": "8.0.0", + "description": "Use Custom Properties Queries in CSS", + "author": "Jonathan Neal ", + "contributors": [ + "Maxime Thirouin" ], - "author": "Maxime Thirouin", "license": "MIT", - "repository": "https://github.com/postcss/postcss-custom-properties.git", - "main": "dist/index.js", + "repository": "postcss/postcss-custom-properties", + "homepage": "https://github.com/postcss/postcss-custom-properties#readme", + "bugs": "https://github.com/postcss/postcss-custom-properties/issues", + "main": "index.cjs.js", + "module": "index.es.mjs", "files": [ - "dist" + "index.cjs.js", + "index.es.mjs" ], + "scripts": { + "prepublishOnly": "npm test", + "pretest": "rollup -c .rollup.js --silent", + "test": "echo 'Running tests...'; npm run test:js && npm run test:tape", + "test:js": "eslint *.js lib/*.js --cache --ignore-path .gitignore --quiet", + "test:tape": "postcss-tape" + }, "engines": { "node": ">=6.0.0" }, "dependencies": { - "balanced-match": "^1.0.0", - "postcss": "^7.0.2" + "postcss": "^7.0.2", + "postcss-values-parser": "^1.5.0" }, "devDependencies": { - "babel-cli": "^6.26.0", - "babel-plugin-add-module-exports": "^0.2.1", - "babel-preset-env": "^1.7.0", - "babel-register": "^6.26.0", - "eslint": "^5.0.1", - "npmpub": "^4.0.1", - "tape": "^4.9.1" + "@babel/core": "^7.0.1", + "@babel/plugin-syntax-dynamic-import": "^7.0.0", + "@babel/preset-env": "^7.0.0", + "babel-eslint": "^9.0.0", + "eslint": "^5.6.0", + "eslint-config-dev": "^2.0.0", + "postcss-tape": "^2.2.0", + "pre-commit": "^1.2.2", + "rollup": "^0.66.0", + "rollup-plugin-babel": "^4.0.3" }, - "scripts": { - "lint": "eslint *.js index.js ./test/", - "tape": "tape -r babel-register test/*.js", - "test": "npm run lint && npm run babelify && npm run tape", - "babelify": "babel index.js --out-dir dist", - "prepublish": "npm run babelify", - "release": "npmpub" - } + "eslintConfig": { + "extends": "dev", + "parser": "babel-eslint" + }, + "keywords": [ + "postcss", + "css", + "postcss-plugin", + "custom", + "properties", + "declarations", + "variables", + "vars", + "w3c", + "csswg", + "specification" + ] } diff --git a/test/basic.css b/test/basic.css new file mode 100644 index 0000000000..c6a4644603 --- /dev/null +++ b/test/basic.css @@ -0,0 +1,27 @@ +html { + --ref-color: skip; +} + +:root { + --color: red; + --ref-color: var(--color); + --circular: var(--circular-2); + --circular-2: var(--circular); +} + +.test { + --skip: gray; + color: var(--color); +} + +.test--fallback { + color: var(--color-2, blue); +} + +.test--color_w_var { + color: var(--ref-color); +} + +.test--circular_var { + color: var(--circular); +} diff --git a/test/basic.expect.css b/test/basic.expect.css new file mode 100644 index 0000000000..ed3889760a --- /dev/null +++ b/test/basic.expect.css @@ -0,0 +1,30 @@ +html { + --ref-color: skip; +} + +:root { + --color: red; + --ref-color: var(--color); + --circular: var(--circular-2); + --circular-2: var(--circular); +} + +.test { + --skip: gray; + color: red; + color: var(--color); +} + +.test--fallback { + color: blue; + color: var(--color-2, blue); +} + +.test--color_w_var { + color: red; + color: var(--ref-color); +} + +.test--circular_var { + color: var(--circular); +} diff --git a/test/basic.import.expect.css b/test/basic.import.expect.css new file mode 100644 index 0000000000..4edc29dc4d --- /dev/null +++ b/test/basic.import.expect.css @@ -0,0 +1,30 @@ +html { + --ref-color: skip; +} + +:root { + --color: red; + --ref-color: var(--color); + --circular: var(--circular-2); + --circular-2: var(--circular); +} + +.test { + --skip: gray; + color: red; + color: var(--color); +} + +.test--fallback { + color: yellow; + color: var(--color-2, blue); +} + +.test--color_w_var { + color: red; + color: var(--ref-color); +} + +.test--circular_var { + color: var(--circular); +} diff --git a/test/basic.preserve.expect.css b/test/basic.preserve.expect.css new file mode 100644 index 0000000000..16f3e38e35 --- /dev/null +++ b/test/basic.preserve.expect.css @@ -0,0 +1,16 @@ +.test { + --skip: gray; + color: red; +} + +.test--fallback { + color: blue; +} + +.test--color_w_var { + color: red; +} + +.test--circular_var { + color: var(--circular); +} diff --git a/test/export-properties.css b/test/export-properties.css new file mode 100644 index 0000000000..77bf4d8a46 --- /dev/null +++ b/test/export-properties.css @@ -0,0 +1,6 @@ +:root { + --ref-color: var(--color); + --color: red; + --circular: var(--circular-2); + --circular-2: var(--circular); +} diff --git a/test/export-properties.js b/test/export-properties.js new file mode 100644 index 0000000000..8191eaaffe --- /dev/null +++ b/test/export-properties.js @@ -0,0 +1,8 @@ +module.exports = { + customProperties: { + '--ref-color': 'var(--color)', + '--color': 'red', + '--circular': 'var(--circular-2)', + '--circular-2': 'var(--circular)' + } +}; diff --git a/test/export-properties.json b/test/export-properties.json new file mode 100644 index 0000000000..bc2721dd8f --- /dev/null +++ b/test/export-properties.json @@ -0,0 +1,8 @@ +{ + "custom-properties": { + "--ref-color": "var(--color)", + "--color": "red", + "--circular": "var(--circular-2)", + "--circular-2": "var(--circular)" + } +} diff --git a/test/export-properties.mjs b/test/export-properties.mjs new file mode 100644 index 0000000000..0b5373989b --- /dev/null +++ b/test/export-properties.mjs @@ -0,0 +1,6 @@ +export const customProperties = { + '--ref-color': 'var(--color)', + '--color': 'red', + '--circular': 'var(--circular-2)', + '--circular-2': 'var(--circular)' +}; diff --git a/test/fixtures/append.css b/test/fixtures/append.css deleted file mode 100644 index 6da553d015..0000000000 --- a/test/fixtures/append.css +++ /dev/null @@ -1,3 +0,0 @@ -div { - p: var(--test-one); -} diff --git a/test/fixtures/append.duplicates.css b/test/fixtures/append.duplicates.css deleted file mode 100644 index 7dab61fdee..0000000000 --- a/test/fixtures/append.duplicates.css +++ /dev/null @@ -1,8 +0,0 @@ -:root { - --test-one: css-one; -} - -div { - p: var(--test-one); - a: var(--test-two); -} diff --git a/test/fixtures/append.duplicates.expected.css b/test/fixtures/append.duplicates.expected.css deleted file mode 100644 index f9b7947f57..0000000000 --- a/test/fixtures/append.duplicates.expected.css +++ /dev/null @@ -1,14 +0,0 @@ -:root { - --test-one: css-one; -} - -div { - p: css-one; - a: js-one; -} - -:root { - --test-two: js-one; - --test-three: js-two; - --test-four: css-one js-one js-two; -} \ No newline at end of file diff --git a/test/fixtures/append.expected.css b/test/fixtures/append.expected.css deleted file mode 100644 index 8b22df0494..0000000000 --- a/test/fixtures/append.expected.css +++ /dev/null @@ -1,8 +0,0 @@ -div { - p: js-one; -} -:root { - --test-one: js-one; - --test-two: js-two; - --test-three: js-one js-two; -} diff --git a/test/fixtures/automatic-variable-prefix.css b/test/fixtures/automatic-variable-prefix.css deleted file mode 100644 index bf61e60b57..0000000000 --- a/test/fixtures/automatic-variable-prefix.css +++ /dev/null @@ -1,4 +0,0 @@ -div { - color: var(--unprefixed); - background: var(--prefixed); -} diff --git a/test/fixtures/automatic-variable-prefix.expected.css b/test/fixtures/automatic-variable-prefix.expected.css deleted file mode 100644 index bf547b19a1..0000000000 --- a/test/fixtures/automatic-variable-prefix.expected.css +++ /dev/null @@ -1,6 +0,0 @@ -div { - color: blue; - color: var(--unprefixed); - background: white; - background: var(--prefixed); -} diff --git a/test/fixtures/case-sensitive.css b/test/fixtures/case-sensitive.css deleted file mode 100755 index f54b954abc..0000000000 --- a/test/fixtures/case-sensitive.css +++ /dev/null @@ -1,9 +0,0 @@ -:root { - --TEST-color: red; - --tESt-COLOR: green; -} - -div { - color: var(--TEST-color); - color: var(--tESt-COLOR); -} diff --git a/test/fixtures/case-sensitive.expected.css b/test/fixtures/case-sensitive.expected.css deleted file mode 100755 index 8543ba9256..0000000000 --- a/test/fixtures/case-sensitive.expected.css +++ /dev/null @@ -1,11 +0,0 @@ -:root { - --TEST-color: red; - --tESt-COLOR: green; -} - -div { - color: red; - color: var(--TEST-color); - color: green; - color: var(--tESt-COLOR); -} diff --git a/test/fixtures/circular-reference.css b/test/fixtures/circular-reference.css deleted file mode 100644 index d1ae2d5e01..0000000000 --- a/test/fixtures/circular-reference.css +++ /dev/null @@ -1,7 +0,0 @@ -:root { - --color: var(--bg-color); - --bg-color: var(--color); -} -body { - color: var(--color); -} diff --git a/test/fixtures/circular-reference.expected.css b/test/fixtures/circular-reference.expected.css deleted file mode 100644 index cc73e70873..0000000000 --- a/test/fixtures/circular-reference.expected.css +++ /dev/null @@ -1,10 +0,0 @@ -:root { - --color: var(--color); - --color: var(--bg-color); - --bg-color: var(--color); - --bg-color: var(--color); -} -body { - color: var(--color); - color: var(--color); -} diff --git a/test/fixtures/important.css b/test/fixtures/important.css deleted file mode 100644 index f0172f2051..0000000000 --- a/test/fixtures/important.css +++ /dev/null @@ -1,16 +0,0 @@ -:root { - --one: not important; - --one: important !important; - - --two: important !important; - --two: not important; - - --three: important !important; - --three: more important !important; -} - -selector { - one: var(--one); - two: var(--two); - three: var(--three); -} diff --git a/test/fixtures/important.expected.css b/test/fixtures/important.expected.css deleted file mode 100644 index ec9f08768a..0000000000 --- a/test/fixtures/important.expected.css +++ /dev/null @@ -1,19 +0,0 @@ -:root { - --one: not important; - --one: important !important; - - --two: important !important; - --two: not important; - - --three: important !important; - --three: more important !important; -} - -selector { - one: important; - one: var(--one); - two: important; - two: var(--two); - three: more important; - three: var(--three); -} diff --git a/test/fixtures/js-defined.css b/test/fixtures/js-defined.css deleted file mode 100755 index 8c4fedc728..0000000000 --- a/test/fixtures/js-defined.css +++ /dev/null @@ -1,13 +0,0 @@ -:root { - --test-one: local; - --test-two: local; -} - -div { - p: var(--test-one); - p: var(--test-two); - p: var(--test-three); - p: var(--test-varception); - p: var(--test-jsception); - p: var(--test-num); -} diff --git a/test/fixtures/js-defined.expected.css b/test/fixtures/js-defined.expected.css deleted file mode 100755 index d7ce1b2c48..0000000000 --- a/test/fixtures/js-defined.expected.css +++ /dev/null @@ -1,19 +0,0 @@ -:root { - --test-one: local; - --test-two: local; -} - -div { - p: js-one; - p: var(--test-one); - p: js-two; - p: var(--test-two); - p: js-three; - p: var(--test-three); - p: js-one; - p: var(--test-varception); - p: js-one; - p: var(--test-jsception); - p: 1; - p: var(--test-num); -} diff --git a/test/fixtures/js-override.css b/test/fixtures/js-override.css deleted file mode 100755 index 8c4fedc728..0000000000 --- a/test/fixtures/js-override.css +++ /dev/null @@ -1,13 +0,0 @@ -:root { - --test-one: local; - --test-two: local; -} - -div { - p: var(--test-one); - p: var(--test-two); - p: var(--test-three); - p: var(--test-varception); - p: var(--test-jsception); - p: var(--test-num); -} diff --git a/test/fixtures/js-override.expected.css b/test/fixtures/js-override.expected.css deleted file mode 100755 index d7ce1b2c48..0000000000 --- a/test/fixtures/js-override.expected.css +++ /dev/null @@ -1,19 +0,0 @@ -:root { - --test-one: local; - --test-two: local; -} - -div { - p: js-one; - p: var(--test-one); - p: js-two; - p: var(--test-two); - p: js-three; - p: var(--test-three); - p: js-one; - p: var(--test-varception); - p: js-one; - p: var(--test-jsception); - p: 1; - p: var(--test-num); -} diff --git a/test/fixtures/media-query.css b/test/fixtures/media-query.css deleted file mode 100755 index 2ff566f020..0000000000 --- a/test/fixtures/media-query.css +++ /dev/null @@ -1,5 +0,0 @@ -@media screen and (min-width: 320px) { - :root { - --error: red; - } -} diff --git a/test/fixtures/media-query.expected.css b/test/fixtures/media-query.expected.css deleted file mode 100755 index 2ff566f020..0000000000 --- a/test/fixtures/media-query.expected.css +++ /dev/null @@ -1,5 +0,0 @@ -@media screen and (min-width: 320px) { - :root { - --error: red; - } -} diff --git a/test/fixtures/preserve-computed.css b/test/fixtures/preserve-computed.css deleted file mode 100755 index 58a256a46b..0000000000 --- a/test/fixtures/preserve-computed.css +++ /dev/null @@ -1,21 +0,0 @@ -:root { - --color-one: red; - --color-two: blue; - --color-three: var(--color-two); -} - -.atthebeginning { - color: var(--color-one); - prop: after; -} - -.attheend { - prop: before; - color: var(--color-two); -} - -.surrounded { - prop: before; - color: var(--undefined-color, green); - otherprop: after; -} diff --git a/test/fixtures/preserve-computed.expected.css b/test/fixtures/preserve-computed.expected.css deleted file mode 100755 index 7fe1e4f6bb..0000000000 --- a/test/fixtures/preserve-computed.expected.css +++ /dev/null @@ -1,21 +0,0 @@ -:root { - --color-one: red; - --color-two: blue; - --color-three: blue; -} - -.atthebeginning { - color: red; - prop: after; -} - -.attheend { - prop: before; - color: blue; -} - -.surrounded { - prop: before; - color: green; - otherprop: after; -} diff --git a/test/fixtures/preserve-variables.css b/test/fixtures/preserve-variables.css deleted file mode 100755 index 35849be7cc..0000000000 --- a/test/fixtures/preserve-variables.css +++ /dev/null @@ -1,20 +0,0 @@ -:root { - --color-one: red; - --color-two: blue; -} - -.atthebeginning { - color: var(--color-one); - prop: after; -} - -.attheend { - prop: before; - color: var(--color-two); -} - -.surrounded { - prop: before; - color: var(--undefined-color, green); - otherprop: after; -} diff --git a/test/fixtures/preserve-variables.expected.css b/test/fixtures/preserve-variables.expected.css deleted file mode 100755 index 9e7677692d..0000000000 --- a/test/fixtures/preserve-variables.expected.css +++ /dev/null @@ -1,23 +0,0 @@ -:root { - --color-one: red; - --color-two: blue; -} - -.atthebeginning { - color: red; - color: var(--color-one); - prop: after; -} - -.attheend { - prop: before; - color: blue; - color: var(--color-two); -} - -.surrounded { - prop: before; - color: green; - color: var(--undefined-color, green); - otherprop: after; -} diff --git a/test/fixtures/remove-properties.css b/test/fixtures/remove-properties.css deleted file mode 100755 index 649e9631d8..0000000000 --- a/test/fixtures/remove-properties.css +++ /dev/null @@ -1,13 +0,0 @@ -:root { - --test-one: test; - --test-two: test; -} - -div { - color: red; -} - -:root { - --test-three: test; - --test-four: test; -} diff --git a/test/fixtures/remove-properties.expected.css b/test/fixtures/remove-properties.expected.css deleted file mode 100755 index 649e9631d8..0000000000 --- a/test/fixtures/remove-properties.expected.css +++ /dev/null @@ -1,13 +0,0 @@ -:root { - --test-one: test; - --test-two: test; -} - -div { - color: red; -} - -:root { - --test-three: test; - --test-four: test; -} diff --git a/test/fixtures/self-reference-double-fallback.css b/test/fixtures/self-reference-double-fallback.css deleted file mode 100644 index 1476ad8428..0000000000 --- a/test/fixtures/self-reference-double-fallback.css +++ /dev/null @@ -1,6 +0,0 @@ -:root { - --color: var(--color, #aaa); -} -body { - color: var(--color, #bbb); -} diff --git a/test/fixtures/self-reference-double-fallback.expected.css b/test/fixtures/self-reference-double-fallback.expected.css deleted file mode 100644 index 9ff57e4db8..0000000000 --- a/test/fixtures/self-reference-double-fallback.expected.css +++ /dev/null @@ -1,12 +0,0 @@ -:root { - --color: #aaa; - --color: #aaa; - --color: #aaa; - --color: var(--color, #aaa); -} -body { - color: #bbb; - color: #aaa; - color: #aaa; - color: var(--color, #bbb); -} diff --git a/test/fixtures/self-reference-fallback.css b/test/fixtures/self-reference-fallback.css deleted file mode 100644 index b585bb8564..0000000000 --- a/test/fixtures/self-reference-fallback.css +++ /dev/null @@ -1,6 +0,0 @@ -:root { - --color: var(--color); -} -body { - color: var(--color, #aaa); -} diff --git a/test/fixtures/self-reference-fallback.expected.css b/test/fixtures/self-reference-fallback.expected.css deleted file mode 100644 index 47a67efa86..0000000000 --- a/test/fixtures/self-reference-fallback.expected.css +++ /dev/null @@ -1,8 +0,0 @@ -:root { - --color: var(--color); - --color: var(--color); -} -body { - color: #aaa; - color: var(--color, #aaa); -} diff --git a/test/fixtures/self-reference.css b/test/fixtures/self-reference.css deleted file mode 100644 index a5b8489f26..0000000000 --- a/test/fixtures/self-reference.css +++ /dev/null @@ -1,6 +0,0 @@ -:root { - --color: var(--color); -} -body { - color: var(--color); -} diff --git a/test/fixtures/self-reference.expected.css b/test/fixtures/self-reference.expected.css deleted file mode 100644 index d5045a67c7..0000000000 --- a/test/fixtures/self-reference.expected.css +++ /dev/null @@ -1,8 +0,0 @@ -:root { - --color: var(--color); - --color: var(--color); -} -body { - color: var(--color); - color: var(--color); -} diff --git a/test/fixtures/substitution-defined.css b/test/fixtures/substitution-defined.css deleted file mode 100755 index f6dc84ba77..0000000000 --- a/test/fixtures/substitution-defined.css +++ /dev/null @@ -1,41 +0,0 @@ -/** - * Test comment - */ - -:root { - --test: green; - --test-one: var(--test); - - --test-two: blue; - --test-three: yellow; -} - -:root, -span { - --untouched: red; -} - -div { - --untouched: red; - - /* single variable */ - color: var(--test-one); - - /* single variable with comments */ - color: /*comment before*/var(--test-one)/*comment after*/; - - /* single variable with tail */ - color: var(--test-one) !important; - - /* multiple variables */ - color: var(--test-one), var(--test-two); - - /* variable with function in fallback */ - border: var(--test-one, 1px solid rgba(0, 0, 0, 0.1)); - - /* multiple variables within a function */ - background: linear-gradient(to top, var(--test-one), var(--test-two)); - - /* untouched custom function */ - color: myvar(--test-one); -} diff --git a/test/fixtures/substitution-defined.expected.css b/test/fixtures/substitution-defined.expected.css deleted file mode 100755 index 5f6bc4021d..0000000000 --- a/test/fixtures/substitution-defined.expected.css +++ /dev/null @@ -1,50 +0,0 @@ -/** - * Test comment - */ - -:root { - --test: green; - --test-one: green; - --test-one: var(--test); - - --test-two: blue; - --test-three: yellow; -} - -:root, -span { - --untouched: red; -} - -div { - --untouched: red; - - /* single variable */ - color: green; - color: var(--test-one); - - /* single variable with comments */ - color: /*comment before*/green/*comment after*/; - color: /*comment before*/var(--test-one)/*comment after*/; - - /* single variable with tail */ - color: green !important; - color: var(--test-one) !important; - - /* multiple variables */ - color: green, blue; - color: var(--test-one), var(--test-two); - - /* variable with function in fallback */ - border: 1px solid rgba(0, 0, 0, 0.1); - border: green; - border: var(--test-one, 1px solid rgba(0, 0, 0, 0.1)); - - /* multiple variables within a function */ - background: linear-gradient(to top, green, blue); - background: linear-gradient(to top, var(--test-one), var(--test-two)); - - /* untouched custom function */ - color: myvar(--test-one); - color: myvar(--test-one); -} diff --git a/test/fixtures/substitution-empty.css b/test/fixtures/substitution-empty.css deleted file mode 100755 index 12ed84db17..0000000000 --- a/test/fixtures/substitution-empty.css +++ /dev/null @@ -1,3 +0,0 @@ -div { - color: var(); -} diff --git a/test/fixtures/substitution-fallback.css b/test/fixtures/substitution-fallback.css deleted file mode 100755 index 50cea75fe3..0000000000 --- a/test/fixtures/substitution-fallback.css +++ /dev/null @@ -1,35 +0,0 @@ -:root { - --nested: green; -} - -div { - /* simple fallback */ - color: var(--missing, green); - - /* comma-separated fallback */ - color: var(--missing, green, blue); - - /* fallback is a function */ - background: var(--missing, linear-gradient(to top, #000, #111)); - - /* fallback contains a function */ - background: var(--missing, 1px solid rgba(0, 0, 0, 0.1)); - - /* fallback is a function containing a function */ - background: var(--missing, linear-gradient(to top, #000, rgba(0, 0, 0, 0.5))); - - /* fallback contains a defined variable */ - background: var(--missing, var(--nested)); - - /* fallback contains a defined variable within a function */ - background: var(--missing, linear-gradient(to top, #000, var(--nested))); - - /* fallback contains an undefined variable with a fallack */ - background: var(--missing, var(--also-missing, green)); - - /* fallback for invalid variables http://www.w3.org/TR/css-variables/#invalid-variables */ - font-size: var(--nested, 1rem); - - /* fallback contains an defined variable with a fallack */ - font-size: var(--missing, var(--nested, 1rem)); -} diff --git a/test/fixtures/substitution-fallback.expected.css b/test/fixtures/substitution-fallback.expected.css deleted file mode 100755 index 8ae69dc82b..0000000000 --- a/test/fixtures/substitution-fallback.expected.css +++ /dev/null @@ -1,47 +0,0 @@ -:root { - --nested: green; -} - -div { - /* simple fallback */ - color: green; - color: var(--missing, green); - - /* comma-separated fallback */ - color: green, blue; - color: var(--missing, green, blue); - - /* fallback is a function */ - background: linear-gradient(to top, #000, #111); - background: var(--missing, linear-gradient(to top, #000, #111)); - - /* fallback contains a function */ - background: 1px solid rgba(0, 0, 0, 0.1); - background: var(--missing, 1px solid rgba(0, 0, 0, 0.1)); - - /* fallback is a function containing a function */ - background: linear-gradient(to top, #000, rgba(0, 0, 0, 0.5)); - background: var(--missing, linear-gradient(to top, #000, rgba(0, 0, 0, 0.5))); - - /* fallback contains a defined variable */ - background: green; - background: var(--missing, var(--nested)); - - /* fallback contains a defined variable within a function */ - background: linear-gradient(to top, #000, green); - background: var(--missing, linear-gradient(to top, #000, var(--nested))); - - /* fallback contains an undefined variable with a fallack */ - background: green; - background: var(--missing, var(--also-missing, green)); - - /* fallback for invalid variables http://www.w3.org/TR/css-variables/#invalid-variables */ - font-size: 1rem; - font-size: green; - font-size: var(--nested, 1rem); - - /* fallback contains an defined variable with a fallack */ - font-size: 1rem; - font-size: green; - font-size: var(--missing, var(--nested, 1rem)); -} diff --git a/test/fixtures/substitution-malformed.css b/test/fixtures/substitution-malformed.css deleted file mode 100755 index 2c13bed62b..0000000000 --- a/test/fixtures/substitution-malformed.css +++ /dev/null @@ -1,4 +0,0 @@ -div { - /* missing closing ')' */ - color: var(--test, rgba(0,0,0,0.5); -} diff --git a/test/fixtures/substitution-overwrite.css b/test/fixtures/substitution-overwrite.css deleted file mode 100755 index cbb937cd57..0000000000 --- a/test/fixtures/substitution-overwrite.css +++ /dev/null @@ -1,12 +0,0 @@ -:root { - --test-override: red; -} - -div { - background: var(--test-override); - color: var(--test-override); -} - -:root { - --test-override: green; -} diff --git a/test/fixtures/substitution-overwrite.expected.css b/test/fixtures/substitution-overwrite.expected.css deleted file mode 100755 index 5fdc7f3a4b..0000000000 --- a/test/fixtures/substitution-overwrite.expected.css +++ /dev/null @@ -1,14 +0,0 @@ -:root { - --test-override: red; -} - -div { - background: green; - background: var(--test-override); - color: green; - color: var(--test-override); -} - -:root { - --test-override: green; -} diff --git a/test/fixtures/substitution-strict.css b/test/fixtures/substitution-strict.css deleted file mode 100755 index f13b196758..0000000000 --- a/test/fixtures/substitution-strict.css +++ /dev/null @@ -1,10 +0,0 @@ -:root { - --a: "a"; - --b: var(--bUndef, bFallback); -} - -div { - aProp: var(--a, aPropFallback); - bProp: var(--b, bPropFallback); - bProp: var(--cUndef, cPropFallback); -} diff --git a/test/fixtures/substitution-strict.expected.css b/test/fixtures/substitution-strict.expected.css deleted file mode 100755 index be554a66c9..0000000000 --- a/test/fixtures/substitution-strict.expected.css +++ /dev/null @@ -1,14 +0,0 @@ -:root { - --a: "a"; - --b: bFallback; - --b: var(--bUndef, bFallback); -} - -div { - aProp: "a"; - aProp: var(--a, aPropFallback); - bProp: bFallback; - bProp: var(--b, bPropFallback); - bProp: cPropFallback; - bProp: var(--cUndef, cPropFallback); -} diff --git a/test/fixtures/substitution-trailing-space.css b/test/fixtures/substitution-trailing-space.css deleted file mode 100755 index 62a577fdcd..0000000000 --- a/test/fixtures/substitution-trailing-space.css +++ /dev/null @@ -1,7 +0,0 @@ -:root { - --test-trailing-space: red; -} - -div { - color: var( --test-trailing-space ); -} diff --git a/test/fixtures/substitution-trailing-space.expected.css b/test/fixtures/substitution-trailing-space.expected.css deleted file mode 100755 index d5c3289c17..0000000000 --- a/test/fixtures/substitution-trailing-space.expected.css +++ /dev/null @@ -1,8 +0,0 @@ -:root { - --test-trailing-space: red; -} - -div { - color: red; - color: var( --test-trailing-space ); -} diff --git a/test/fixtures/substitution-undefined.css b/test/fixtures/substitution-undefined.css deleted file mode 100755 index 718af2745c..0000000000 --- a/test/fixtures/substitution-undefined.css +++ /dev/null @@ -1,12 +0,0 @@ -:root { - --defined: true -} - -div { - color: var(--test); - color: var(--test, fallback); - background: linear-gradient(var(--a), var(--b)); - background: linear-gradient(var(--a), var(--b), var(--defined)); - background: linear-gradient(var(--a), var(--defined) , var(--b)); - background: linear-gradient(var(--a), var(--defined) , var(--b), var(--defined)); -} diff --git a/test/fixtures/substitution-undefined.expected.css b/test/fixtures/substitution-undefined.expected.css deleted file mode 100644 index 029404a391..0000000000 --- a/test/fixtures/substitution-undefined.expected.css +++ /dev/null @@ -1,18 +0,0 @@ -:root { - --defined: true -} - -div { - color: var(--test); - color: var(--test); - color: fallback; - color: var(--test, fallback); - background: linear-gradient(var(--a), var(--b)); - background: linear-gradient(var(--a), var(--b)); - background: linear-gradient(var(--a), var(--b), true); - background: linear-gradient(var(--a), var(--b), var(--defined)); - background: linear-gradient(var(--a), true , var(--b)); - background: linear-gradient(var(--a), var(--defined) , var(--b)); - background: linear-gradient(var(--a), true , var(--b), true); - background: linear-gradient(var(--a), var(--defined) , var(--b), var(--defined)); -} diff --git a/test/import-properties.css b/test/import-properties.css new file mode 100644 index 0000000000..23b36d9cea --- /dev/null +++ b/test/import-properties.css @@ -0,0 +1,5 @@ +:root { + --color: red; + --color-2: yellow; + --ref-color: var(--color); +} diff --git a/test/import-properties.js b/test/import-properties.js new file mode 100644 index 0000000000..5b2b9bbe7c --- /dev/null +++ b/test/import-properties.js @@ -0,0 +1,7 @@ +module.exports = { + customProperties: { + '--color': 'red', + '--color-2': 'yellow', + '--ref-color': 'var(--color)' + } +}; diff --git a/test/import-properties.json b/test/import-properties.json new file mode 100644 index 0000000000..9527f11cfd --- /dev/null +++ b/test/import-properties.json @@ -0,0 +1,7 @@ +{ + "custom-properties": { + "--color": "red", + "--color-2": "yellow", + "--ref-color": "var(--color)" + } +} diff --git a/test/index.js b/test/index.js deleted file mode 100755 index 11cfd34db3..0000000000 --- a/test/index.js +++ /dev/null @@ -1,362 +0,0 @@ -import fs from "fs" - -import test from "tape" - -import postcss from "postcss" -import customProperties from ".." - -function fixturePath(name) { - return "test/fixtures/" + name + ".css" -} - -function fixture(name) { - return fs.readFileSync(fixturePath(name), "utf8").trim() -} - -function resolveFixture(name, options) { - return postcss(customProperties(options)) - .process(fixture(name), {from: fixturePath(name)}) -} - -function compareFixtures(t, name, options) { - const postcssResult = resolveFixture(name, options) - const actual = postcssResult.css.trim() - - // handy thing: checkout actual in the *.actual.css file - fs.writeFile(fixturePath(name + ".actual"), actual, () => {}) - - const expected = fixture(name + ".expected") - t.equal( - actual, expected, - "processed fixture '" + name + "' should be equal to expected output" - ) - - return postcssResult -} - -test("throw errors", function(t) { - t.throws( - function() { - return postcss(customProperties()) - .process(fixture("substitution-empty")) - .css - }, - /must contain a non-whitespace string/, - "throws an error when a variable function is empty" - ) - - t.throws( - function() { - return postcss(customProperties()) - .process(fixture("substitution-malformed")) - .css - }, - /missing closing/, - "throws an error when a variable function is malformed" - ) - - t.end() -}) - -test( - "substitutes nothing when a variable function references an undefined var", - function(t) { - let result = compareFixtures(t, "substitution-undefined", { - warnings: true, - }) - t.equal( - result.messages[0].text, - "variable '--test' is undefined and used without a fallback", - "should add a warning for undefined variable" - ) - - result = compareFixtures(t, "substitution-undefined", { - warnings: { - "no-value-notifications": true, - }, - }) - t.equal( - result.messages[0].text, - "variable '--test' is undefined and used without a fallback", - "should add a warning for undefined variable" - ) - - t.throws( - function() { - compareFixtures(t, "substitution-undefined", { - warnings: { - "no-value-notifications": "error", - }, - }) - }, - /variable '--test' is undefined and used without a fallback/, - "should throw an error for undefined variable" - ) - - t.end() - } -) - -test( - "generate error for undefined var when flag is set", - function(t) { - t.throws( - function() { - return postcss(customProperties({ - noValueNotifications: "error", - warnings: true, - })) - .process(fixture("substitution-undefined")) - .css - }, - "variable '--test' is undefined and used without a fallback", - "should add a warning for undefined variable" - ) - t.end() - } -) - -test("substitutes defined variables in `:root` only", function(t) { - let result = compareFixtures(t, "substitution-defined", { - warnings: true, - }) - t.ok( - result.messages[0].text.match(/^Custom property ignored/), - "should add a warning for non root custom properties" - ) - - result = compareFixtures(t, "substitution-defined", { - warnings: { - "not-scoped-to-root": true, - }, - }) - t.ok( - result.messages[0].text.match(/^Custom property ignored/), - "should add a warning for non root custom properties" - ) - - t.throws( - function() { - compareFixtures(t, "substitution-defined", { - warnings: { - "not-scoped-to-root": "error", - }, - }) - }, - /Custom property ignored/, - "should throw an error for non root custom properties" - ) - - t.end() -}) - -test("allow to hide warnings", function(t) { - let result = compareFixtures( - t, - "substitution-defined", - {warnings: false} - ) - t.equal( - result.messages.length, - 0, - "should not add warnings if option set to false" - ) - - result = compareFixtures( - t, - "substitution-defined", - { - warnings: { - "not-scoped-to-root": false, - }, - } - ) - t.equal( - result.messages.length, - 0, - "should not add warnings if option set to false" - ) - - t.end() -}) - -test( - "accepts variables defined from JavaScript, and overrides local definitions", - function(t) { - compareFixtures(t, "js-defined", { - variables: { - "--test-one": "js-one", - "--test-two": "js-two", - "--test-three": "js-three", - "--test-varception": "var(--test-one)", - "--test-jsception": "var(--test-varception)", - "--test-num": 1, - }, - }) - t.end() - } -) - -test( - "prefixes js defined variabled with a double dash automatically", - function(t) { - compareFixtures(t, "automatic-variable-prefix", { - variables: { - unprefixed: "blue", - "--prefixed": "white", - }, - }) - t.end() - } -) - -test("allows users to programmatically change the variables", function(t) { - const variables = { - "--test-one": "js-one", - "--test-two": "js-two", - "--test-three": "js-three", - "--test-varception": "var(--test-one)", - "--test-jsception": "var(--test-varception)", - "--test-num": 1, - } - const plugin = customProperties() - const name = "js-override" - const expected = fs.readFileSync( - fixturePath(name + ".expected"), "utf8" - ).trim() - - plugin.setVariables(variables) - - const actual = postcss(plugin) - .process(fixture(name), {from: fixturePath(name)}).css.trim() - - t.equal( - actual, expected, - "processed fixture '" + name + "' should be equal to expected output" - ) - - t.end() -}) - -test("removes variable properties from the output", function(t) { - compareFixtures(t, "remove-properties") - t.end() -}) - -test("ignores variables defined in a media query", function(t) { - compareFixtures(t, "media-query") - t.end() -}) - -test("overwrites variables correctly", function(t) { - compareFixtures(t, "substitution-overwrite") - t.end() -}) - -test("substitutes undefined variables if there is a fallback", function(t) { - compareFixtures(t, "substitution-fallback") - t.end() -}) - -test("supports case-sensitive variables", function(t) { - compareFixtures(t, "case-sensitive") - t.end() -}) - -test("supports !important", function(t) { - compareFixtures(t, "important") - t.end() -}) - -test("preserves variables when `preserve` is `true`", function(t) { - compareFixtures(t, "preserve-variables", {preserve: true}) - t.end() -}) - -test("preserves computed value when `preserve` is `\"computed\"`", function(t) { - compareFixtures(t, "preserve-computed", {preserve: "computed"}) - t.end() -}) - -test("circular variable references", function(t) { - compareFixtures(t, "self-reference") - let result = compareFixtures(t, "circular-reference", { - warnings: true, - }) - t.equal( - result.messages[0].text, - "Circular variable reference: --bg-color", - "should add a warning for circular reference" - ) - - result = compareFixtures(t, "circular-reference", { - warnings: { - "circular-reference": true, - }, - }) - t.equal( - result.messages[0].text, - "Circular variable reference: --bg-color", - "should add a warning for circular reference" - ) - - t.throws( - function() { - compareFixtures(t, "circular-reference", { - warnings: { - "circular-reference": "error", - }, - }) - }, - /Circular variable reference: --bg-color/, - "should throw an error for circular reference" - ) - - t.end() -}) - -test("circular variable references with fallback", function(t) { - compareFixtures(t, "self-reference-fallback") - compareFixtures(t, "self-reference-double-fallback") - t.end() -}) - -test("append variables", function(t) { - compareFixtures(t, "append", { - variables: { - "--test-one": "js-one", - "test-two": "js-two", - "test-three": "var(--test-one, one) var(--test-two, two)", - }, - preserve: "computed", - appendVariables: true, - }) - t.end() -}) - -test("append variables without duplicates", function(t) { - compareFixtures(t, "append.duplicates", { - variables: { - "--test-two": "js-one", - "test-three": "js-two", - "test-four": "var(--test-one, one) var(--test-two, two) " + - "var(--test-three, three)", - }, - preserve: "computed", - appendVariables: true, - }) - t.end() -}) - -test("strict option", function(t) { - compareFixtures(t, "substitution-strict", { - strict: false, - }) - - t.end() -}) - -test("ignores trailing space after variable", function(t) { - compareFixtures(t, "substitution-trailing-space") - t.end() -}) From 7487215e2770944833a93f604223ecc6d5b1dc04 Mon Sep 17 00:00:00 2001 From: Jonathan Neal Date: Mon, 17 Sep 2018 11:50:27 -0400 Subject: [PATCH 680/795] 8.0.1 --- .rollup.js | 4 ++-- .tape.js | 12 ++++++------ CHANGELOG.md | 4 ++++ README.md | 13 ++++++++++--- lib/transform-value-ast.js | 21 +++++++++++++++++++-- package.json | 6 ++++-- test/basic.css | 2 +- test/basic.expect.css | 6 +++--- test/basic.import.expect.css | 6 +++--- test/basic.preserve.expect.css | 4 ++-- test/export-properties.css | 2 +- test/export-properties.js | 2 +- test/export-properties.json | 2 +- test/export-properties.mjs | 2 +- test/import-properties.css | 2 +- test/import-properties.js | 2 +- test/import-properties.json | 2 +- 17 files changed, 61 insertions(+), 31 deletions(-) diff --git a/.rollup.js b/.rollup.js index eab5c0d513..3f28a5511b 100644 --- a/.rollup.js +++ b/.rollup.js @@ -3,8 +3,8 @@ import babel from 'rollup-plugin-babel'; export default { input: 'index.js', output: [ - { file: 'index.cjs.js', format: 'cjs' }, - { file: 'index.es.mjs', format: 'es' } + { file: 'index.cjs.js', format: 'cjs', sourcemap: true }, + { file: 'index.es.mjs', format: 'es', sourcemap: true } ], plugins: [ babel({ diff --git a/.tape.js b/.tape.js index 5fc09cc2b1..7dd62f6af5 100644 --- a/.tape.js +++ b/.tape.js @@ -14,7 +14,7 @@ module.exports = { options: { importFrom: { customProperties: { - '--color': 'red', + '--color': 'rgb(255, 0, 0)', '--color-2': 'yellow', '--ref-color': 'var(--color)' } @@ -27,7 +27,7 @@ module.exports = { importFrom() { return { customProperties: { - '--color': 'red', + '--color': 'rgb(255, 0, 0)', '--color-2': 'yellow', '--ref-color': 'var(--color)' } @@ -44,7 +44,7 @@ module.exports = { return new Promise(resolve => { resolve({ customProperties: { - '--color': 'red', + '--color': 'rgb(255, 0, 0)', '--color-2': 'yellow', '--ref-color': 'var(--color)' } @@ -105,7 +105,7 @@ module.exports = { expect: 'basic.expect.css', result: 'basic.result.css', after() { - if (__exportPropertiesObject.customProperties['--color'] !== 'red') { + if (__exportPropertiesObject.customProperties['--color'] !== 'rgb(255, 0, 0)') { throw new Error('The exportTo function failed'); } } @@ -114,7 +114,7 @@ module.exports = { message: 'supports { exportTo() } usage', options: { exportTo(customProperties) { - if (customProperties['--color'] !== 'red') { + if (customProperties['--color'] !== 'rgb(255, 0, 0)') { throw new Error('The exportTo function failed'); } } @@ -127,7 +127,7 @@ module.exports = { options: { exportTo(customProperties) { return new Promise((resolve, reject) => { - if (customProperties['--color'] !== 'red') { + if (customProperties['--color'] !== 'rgb(255, 0, 0)') { reject('The exportTo function failed'); } else { resolve(); diff --git a/CHANGELOG.md b/CHANGELOG.md index b5d079d1a6..adc6513459 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # Changes to PostCSS Custom Properties +### 8.0.1 (September 17, 2018) + +- Fixed: Workaround issue in `postcss-values-parser` incorrectly cloning nodes. + ### 8.0.0 (September 16, 2018) - Added: New `exportTo` function to specify where to export custom properties to. diff --git a/README.md b/README.md index 33c9038136..1a0f7b223a 100755 --- a/README.md +++ b/README.md @@ -123,9 +123,9 @@ will need to namespace Custom Properties using the `customProperties` or ```js postcssCustomProperties({ importFrom: [ - 'path/to/file.css', - 'and/then/this.js', - 'and/then/that.json', + 'path/to/file.css', // :root { --color: red; } + 'and/then/this.js', // module.exports = { customProperties: { '--color': 'red' } } + 'and/then/that.json', // { "custom-properties": { "--color": "red" } } { customProperties: { '--color': 'red' } }, @@ -138,6 +138,9 @@ postcssCustomProperties({ }); ``` +See example imports written in [CSS](test/import-properties.css), +[JS](test/import-properties.js), and [JSON](test/import-properties.json). + ### exportTo The `exportTo` option specifies destinations where Custom Properties can be exported @@ -172,6 +175,10 @@ postcssCustomProperties({ }); ``` +See example exports written to [CSS](test/export-properties.css), +[JS](test/export-properties.js), [MJS](test/export-properties.mjs), and +[JSON](test/export-properties.json). + [cli-img]: https://img.shields.io/travis/postcss/postcss-custom-properties.svg [cli-url]: https://travis-ci.org/postcss/postcss-custom-properties [css-img]: https://cssdb.org/badge/custom-properties.svg diff --git a/lib/transform-value-ast.js b/lib/transform-value-ast.js index f4897ef3b4..a8db9faf5e 100644 --- a/lib/transform-value-ast.js +++ b/lib/transform-value-ast.js @@ -9,7 +9,7 @@ export default function transformValueAST(root, customProperties) { if (name in customProperties) { // conditionally replace a known custom property child.replaceWith( - ...asClonedArray(customProperties[name]) + ...asClonedArray(customProperties[name], null) ); const nextCustomProperties = Object.assign({}, customProperties); @@ -47,4 +47,21 @@ const varRegExp = /^var$/i; const isVarFunction = node => node.type === 'func' && varRegExp.test(node.value) && Object(node.nodes).length > 0; // return an array with its nodes cloned -const asClonedArray = array => array.map(node => node.clone()); +const asClonedArray = (array, parent) => array.map(node => asClonedNode(node, parent)); + +// return a cloned node +const asClonedNode = (node, parent) => { + const cloneNode = new node.constructor(node); + + for (const key in node) { + if (key === 'parent') { + cloneNode.parent = parent; + } else if (Object(node[key]).constructor === Array) { + cloneNode[key] = asClonedArray(node.nodes, cloneNode); + } else if (Object(node[key]).constructor === Object) { + cloneNode[key] = Object.assign({}, node[key]); + } + } + + return cloneNode; +} diff --git a/package.json b/package.json index d3718732cd..dae5872f7d 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "postcss-custom-properties", - "version": "8.0.0", + "version": "8.0.1", "description": "Use Custom Properties Queries in CSS", "author": "Jonathan Neal ", "contributors": [ @@ -14,7 +14,9 @@ "module": "index.es.mjs", "files": [ "index.cjs.js", - "index.es.mjs" + "index.cjs.js.map", + "index.es.mjs", + "index.es.mjs.map" ], "scripts": { "prepublishOnly": "npm test", diff --git a/test/basic.css b/test/basic.css index c6a4644603..c99e71a642 100644 --- a/test/basic.css +++ b/test/basic.css @@ -3,7 +3,7 @@ html { } :root { - --color: red; + --color: rgb(255, 0, 0); --ref-color: var(--color); --circular: var(--circular-2); --circular-2: var(--circular); diff --git a/test/basic.expect.css b/test/basic.expect.css index ed3889760a..0ffbdb16cd 100644 --- a/test/basic.expect.css +++ b/test/basic.expect.css @@ -3,7 +3,7 @@ html { } :root { - --color: red; + --color: rgb(255, 0, 0); --ref-color: var(--color); --circular: var(--circular-2); --circular-2: var(--circular); @@ -11,7 +11,7 @@ html { .test { --skip: gray; - color: red; + color: rgb(255, 0, 0); color: var(--color); } @@ -21,7 +21,7 @@ html { } .test--color_w_var { - color: red; + color: rgb(255, 0, 0); color: var(--ref-color); } diff --git a/test/basic.import.expect.css b/test/basic.import.expect.css index 4edc29dc4d..d120fcf126 100644 --- a/test/basic.import.expect.css +++ b/test/basic.import.expect.css @@ -3,7 +3,7 @@ html { } :root { - --color: red; + --color: rgb(255, 0, 0); --ref-color: var(--color); --circular: var(--circular-2); --circular-2: var(--circular); @@ -11,7 +11,7 @@ html { .test { --skip: gray; - color: red; + color: rgb(255, 0, 0); color: var(--color); } @@ -21,7 +21,7 @@ html { } .test--color_w_var { - color: red; + color: rgb(255, 0, 0); color: var(--ref-color); } diff --git a/test/basic.preserve.expect.css b/test/basic.preserve.expect.css index 16f3e38e35..e430ce1c3e 100644 --- a/test/basic.preserve.expect.css +++ b/test/basic.preserve.expect.css @@ -1,6 +1,6 @@ .test { --skip: gray; - color: red; + color: rgb(255, 0, 0); } .test--fallback { @@ -8,7 +8,7 @@ } .test--color_w_var { - color: red; + color: rgb(255, 0, 0); } .test--circular_var { diff --git a/test/export-properties.css b/test/export-properties.css index 77bf4d8a46..40a1bf6799 100644 --- a/test/export-properties.css +++ b/test/export-properties.css @@ -1,6 +1,6 @@ :root { --ref-color: var(--color); - --color: red; + --color: rgb(255, 0, 0); --circular: var(--circular-2); --circular-2: var(--circular); } diff --git a/test/export-properties.js b/test/export-properties.js index 8191eaaffe..63b9360b21 100644 --- a/test/export-properties.js +++ b/test/export-properties.js @@ -1,7 +1,7 @@ module.exports = { customProperties: { '--ref-color': 'var(--color)', - '--color': 'red', + '--color': 'rgb(255, 0, 0)', '--circular': 'var(--circular-2)', '--circular-2': 'var(--circular)' } diff --git a/test/export-properties.json b/test/export-properties.json index bc2721dd8f..bf2dcd937f 100644 --- a/test/export-properties.json +++ b/test/export-properties.json @@ -1,7 +1,7 @@ { "custom-properties": { "--ref-color": "var(--color)", - "--color": "red", + "--color": "rgb(255, 0, 0)", "--circular": "var(--circular-2)", "--circular-2": "var(--circular)" } diff --git a/test/export-properties.mjs b/test/export-properties.mjs index 0b5373989b..553762eaeb 100644 --- a/test/export-properties.mjs +++ b/test/export-properties.mjs @@ -1,6 +1,6 @@ export const customProperties = { '--ref-color': 'var(--color)', - '--color': 'red', + '--color': 'rgb(255, 0, 0)', '--circular': 'var(--circular-2)', '--circular-2': 'var(--circular)' }; diff --git a/test/import-properties.css b/test/import-properties.css index 23b36d9cea..7a2b7ec16a 100644 --- a/test/import-properties.css +++ b/test/import-properties.css @@ -1,5 +1,5 @@ :root { - --color: red; + --color: rgb(255, 0, 0); --color-2: yellow; --ref-color: var(--color); } diff --git a/test/import-properties.js b/test/import-properties.js index 5b2b9bbe7c..60e653c5f0 100644 --- a/test/import-properties.js +++ b/test/import-properties.js @@ -1,6 +1,6 @@ module.exports = { customProperties: { - '--color': 'red', + '--color': 'rgb(255, 0, 0)', '--color-2': 'yellow', '--ref-color': 'var(--color)' } diff --git a/test/import-properties.json b/test/import-properties.json index 9527f11cfd..3687057da1 100644 --- a/test/import-properties.json +++ b/test/import-properties.json @@ -1,6 +1,6 @@ { "custom-properties": { - "--color": "red", + "--color": "rgb(255, 0, 0)", "--color-2": "yellow", "--ref-color": "var(--color)" } From 2be8c58b56ae6e7a0a7f497f9465ac5391144d38 Mon Sep 17 00:00:00 2001 From: Aaron Ballard Date: Mon, 17 Sep 2018 12:23:58 -0500 Subject: [PATCH 681/795] Upgrade PostCSS to 7.0.2 - tests pass, just ran `npm i postcss@latest` --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 46ba4e9f8a..7fe7c1cc0d 100644 --- a/package.json +++ b/package.json @@ -25,7 +25,7 @@ "node": ">=4.0.0" }, "dependencies": { - "postcss": "^6.0.23", + "postcss": "^7.0.2", "postcss-values-parser": "^1.5.0" }, "devDependencies": { From 9109000611230d0849eb61f06dd87ccd07e1fa1d Mon Sep 17 00:00:00 2001 From: Pascal Duez Date: Mon, 17 Sep 2018 19:24:26 +0200 Subject: [PATCH 682/795] Upgrade to PostCSS 7 --- .travis.yml | 4 +- package-lock.json | 840 ++++++++++++++++++++++++++++++++++++++++++++++ package.json | 5 +- test/index.js | 2 +- 4 files changed, 848 insertions(+), 3 deletions(-) create mode 100644 package-lock.json diff --git a/.travis.yml b/.travis.yml index 85242354aa..71c4fb1436 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,3 +1,5 @@ language: node_js node_js: - - 4 + - "6" + - "8" + - "stable" diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 0000000000..b00ec64031 --- /dev/null +++ b/package-lock.json @@ -0,0 +1,840 @@ +{ + "name": "postcss-media-minmax", + "version": "3.0.0", + "lockfileVersion": 1, + "requires": true, + "dependencies": { + "@octokit/rest": { + "version": "14.0.9", + "resolved": "https://registry.npmjs.org/@octokit/rest/-/rest-14.0.9.tgz", + "integrity": "sha512-irP9phKfTXEZIcW2R+VNCtGHZJrXMWmSYp6RRfFn4BtAqtDRXF5z9JxCEQlAhNBf6X1koNi5k49tIAAAEJNlVQ==", + "dev": true, + "requires": { + "before-after-hook": "^1.1.0", + "debug": "^3.1.0", + "is-array-buffer": "^1.0.0", + "is-stream": "^1.1.0", + "lodash": "^4.17.4", + "url-template": "^2.0.8" + } + }, + "@sindresorhus/df": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@sindresorhus/df/-/df-2.1.0.tgz", + "integrity": "sha1-0gjPJ+BvC7R20U197M19cm6ao4k=", + "dev": true, + "requires": { + "execa": "^0.2.2" + } + }, + "ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", + "dev": true + }, + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "requires": { + "color-convert": "^1.9.0" + } + }, + "array-union": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-1.0.2.tgz", + "integrity": "sha1-mjRBDk9OPaI96jdb5b5w8kd47Dk=", + "dev": true, + "requires": { + "array-uniq": "^1.0.1" + } + }, + "array-uniq": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/array-uniq/-/array-uniq-1.0.3.tgz", + "integrity": "sha1-r2rId6Jcx/dOBYiUdThY39sk/bY=", + "dev": true + }, + "arrify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", + "integrity": "sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=", + "dev": true + }, + "balanced-match": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", + "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", + "dev": true + }, + "before-after-hook": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/before-after-hook/-/before-after-hook-1.1.0.tgz", + "integrity": "sha512-VOMDtYPwLbIncTxNoSzRyvaMxtXmLWLUqr8k5AfC1BzLk34HvBXaQX8snOwQZ4c0aX8aSERqtJSiI9/m2u5kuA==", + "dev": true + }, + "brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "chalk": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.1.tgz", + "integrity": "sha512-ObN6h1v2fTJSmUXoS3nMQ92LbDK9be4TV+6G+omQlGJFdcUX5heKi1LZ1YnRMIgwTLEj3E24bT6tYni50rlCfQ==", + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, + "checkup": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/checkup/-/checkup-1.3.0.tgz", + "integrity": "sha1-04ACdv6l0PJH/8lRvnjIsC+ODXY=", + "dev": true + }, + "color-convert": { + "version": "1.9.2", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.2.tgz", + "integrity": "sha512-3NUJZdhMhcdPn8vJ9v2UQJoH0qqoGUkYTgFEPZaPjEtwmmKUfNV46zZmgB2M5M4DCEQHMaCfWHCxiBflLm04Tg==", + "requires": { + "color-name": "1.1.1" + } + }, + "color-name": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.1.tgz", + "integrity": "sha1-SxQVMEz1ACjqgWQ2Q72C6gWANok=" + }, + "concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", + "dev": true + }, + "cross-spawn-async": { + "version": "2.2.5", + "resolved": "https://registry.npmjs.org/cross-spawn-async/-/cross-spawn-async-2.2.5.tgz", + "integrity": "sha1-hF/wwINKPe2dFg2sptOQkGuyiMw=", + "dev": true, + "requires": { + "lru-cache": "^4.0.0", + "which": "^1.2.8" + } + }, + "debug": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", + "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "deep-equal": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/deep-equal/-/deep-equal-1.0.1.tgz", + "integrity": "sha1-9dJgKStmDghO/0zbyfCK0yR0SLU=", + "dev": true + }, + "define-properties": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.2.tgz", + "integrity": "sha1-g6c/L+pWmJj7c3GTyPhzyvbUXJQ=", + "dev": true, + "requires": { + "foreach": "^2.0.5", + "object-keys": "^1.0.8" + } + }, + "defined": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/defined/-/defined-1.0.0.tgz", + "integrity": "sha1-yY2bzvdWdBiOEQlpFRGZ45sfppM=", + "dev": true + }, + "es-abstract": { + "version": "1.12.0", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.12.0.tgz", + "integrity": "sha512-C8Fx/0jFmV5IPoMOFPA9P9G5NtqW+4cOPit3MIuvR2t7Ag2K15EJTpxnHAYTzL+aYQJIESYeXZmDBfOBE1HcpA==", + "dev": true, + "requires": { + "es-to-primitive": "^1.1.1", + "function-bind": "^1.1.1", + "has": "^1.0.1", + "is-callable": "^1.1.3", + "is-regex": "^1.0.4" + } + }, + "es-to-primitive": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.1.1.tgz", + "integrity": "sha1-RTVSSKiJeQNLZ5Lhm7gfK3l13Q0=", + "dev": true, + "requires": { + "is-callable": "^1.1.1", + "is-date-object": "^1.0.1", + "is-symbol": "^1.0.1" + } + }, + "escape-string-applescript": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/escape-string-applescript/-/escape-string-applescript-1.0.0.tgz", + "integrity": "sha1-bxwilCRdgsY7wDM43BmpSqhCiJI=", + "dev": true + }, + "escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=" + }, + "execa": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/execa/-/execa-0.2.2.tgz", + "integrity": "sha1-4urUcsLDGq1vc/GslW7vReEjIMs=", + "dev": true, + "requires": { + "cross-spawn-async": "^2.1.1", + "npm-run-path": "^1.0.0", + "object-assign": "^4.0.1", + "path-key": "^1.0.0", + "strip-eof": "^1.0.0" + } + }, + "execon": { + "version": "1.2.9", + "resolved": "https://registry.npmjs.org/execon/-/execon-1.2.9.tgz", + "integrity": "sha1-bbETM9zIJPHxPnMX/tDZSi8mSR8=", + "dev": true + }, + "for-each": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz", + "integrity": "sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==", + "dev": true, + "requires": { + "is-callable": "^1.1.3" + } + }, + "foreach": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/foreach/-/foreach-2.0.5.tgz", + "integrity": "sha1-C+4AUBiusmDQo6865ljdATbsG5k=", + "dev": true + }, + "fs-extra": { + "version": "0.26.7", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-0.26.7.tgz", + "integrity": "sha1-muH92UiXeY7at20JGM9C0MMYT6k=", + "dev": true, + "requires": { + "graceful-fs": "^4.1.2", + "jsonfile": "^2.1.0", + "klaw": "^1.0.0", + "path-is-absolute": "^1.0.0", + "rimraf": "^2.2.8" + } + }, + "fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", + "dev": true + }, + "function-bind": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", + "dev": true + }, + "github-release-from-changelog": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/github-release-from-changelog/-/github-release-from-changelog-1.3.2.tgz", + "integrity": "sha512-3Cj5zazWfk9heJzBSXxBsh9xQSYt8ZOseresfNeHewFVC2g0Au9181xob9eXTv4hRysi9k3gRVCXOUmBH+J2bA==", + "dev": true, + "requires": { + "grizzly": "^3.0.3", + "minimist": "^1.2.0" + } + }, + "glob": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz", + "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==", + "dev": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "globby": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-4.1.0.tgz", + "integrity": "sha1-CA9UVJ7BuCpsYOYx/ILhIR2+lfg=", + "dev": true, + "requires": { + "array-union": "^1.0.1", + "arrify": "^1.0.0", + "glob": "^6.0.1", + "object-assign": "^4.0.1", + "pify": "^2.0.0", + "pinkie-promise": "^2.0.0" + }, + "dependencies": { + "glob": { + "version": "6.0.4", + "resolved": "https://registry.npmjs.org/glob/-/glob-6.0.4.tgz", + "integrity": "sha1-DwiGD2oVUSey+t1PnOJLGqtuTSI=", + "dev": true, + "requires": { + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "2 || 3", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + } + } + }, + "graceful-fs": { + "version": "4.1.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.11.tgz", + "integrity": "sha1-Dovf5NHduIVNZOBOp8AOKgJuVlg=", + "dev": true + }, + "grizzly": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/grizzly/-/grizzly-3.0.3.tgz", + "integrity": "sha512-IGcSYOg8W75e1/92oHy1RgO4fiWxWYi94C5nwjJwTe5usRx241LkqiO4923LVLwkon7ro69ZKcCbI4ox25pDOw==", + "dev": true, + "requires": { + "@octokit/rest": "^14.0.7", + "checkup": "^1.3.0", + "debug": "^3.0.0", + "execon": "^1.2.0", + "minimist": "^1.2.0", + "readjson": "^1.1.0" + } + }, + "has": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", + "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "dev": true, + "requires": { + "function-bind": "^1.1.1" + } + }, + "has-ansi": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", + "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=", + "dev": true, + "requires": { + "ansi-regex": "^2.0.0" + } + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=" + }, + "inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "dev": true, + "requires": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "inherits": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", + "dev": true + }, + "is-array-buffer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-1.0.1.tgz", + "integrity": "sha512-lj035IqdAwsodoRGs9/8+Kn3HPoz9CTuZbcw63afugWonxigvUVeHY5d6Ve1O+s1N3RCk7txo2TIWQLbU0SuNA==", + "dev": true + }, + "is-callable": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.1.4.tgz", + "integrity": "sha512-r5p9sxJjYnArLjObpjA4xu5EKI3CuKHkJXMhT7kwbpUyIFD1n5PMAsoPvWnvtZiNz7LjkYDRZhd7FlI0eMijEA==", + "dev": true + }, + "is-date-object": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.1.tgz", + "integrity": "sha1-mqIOtq7rv/d/vTPnTKAbM1gdOhY=", + "dev": true + }, + "is-regex": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.0.4.tgz", + "integrity": "sha1-VRdIm1RwkbCTDglWVM7SXul+lJE=", + "dev": true, + "requires": { + "has": "^1.0.1" + } + }, + "is-stream": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", + "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=", + "dev": true + }, + "is-symbol": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.1.tgz", + "integrity": "sha1-PMWfAAJRlLarLjjbrmaJJWtmBXI=", + "dev": true + }, + "isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", + "dev": true + }, + "jsonfile": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-2.4.0.tgz", + "integrity": "sha1-NzaitCi4e72gzIO1P6PWM6NcKug=", + "dev": true, + "requires": { + "graceful-fs": "^4.1.6" + } + }, + "klaw": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/klaw/-/klaw-1.3.1.tgz", + "integrity": "sha1-QIhDO0azsbolnXh4XY6W9zugJDk=", + "dev": true, + "requires": { + "graceful-fs": "^4.1.9" + } + }, + "lodash": { + "version": "4.17.10", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.10.tgz", + "integrity": "sha512-UejweD1pDoXu+AD825lWwp4ZGtSwgnpZxb3JDViD7StjQz+Nb/6l093lx4OQ0foGWNRoc19mWy7BzL+UAK2iVg==", + "dev": true + }, + "lru-cache": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.3.tgz", + "integrity": "sha512-fFEhvcgzuIoJVUF8fYr5KR0YqxD238zgObTps31YdADwPPAp82a4M8TrckkWyx7ekNlf9aBcVn81cFwwXngrJA==", + "dev": true, + "requires": { + "pseudomap": "^1.0.2", + "yallist": "^2.1.2" + } + }, + "minimatch": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", + "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "dev": true, + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "minimist": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", + "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", + "dev": true + }, + "mount-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/mount-point/-/mount-point-3.0.0.tgz", + "integrity": "sha1-Zly57evoDREOZY21bDHQrvUaj5c=", + "dev": true, + "requires": { + "@sindresorhus/df": "^1.0.1", + "pify": "^2.3.0", + "pinkie-promise": "^2.0.1" + }, + "dependencies": { + "@sindresorhus/df": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@sindresorhus/df/-/df-1.0.1.tgz", + "integrity": "sha1-xptm9S9vzdKHyAffIQMF2694UA0=", + "dev": true + } + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + }, + "npm-run-path": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-1.0.0.tgz", + "integrity": "sha1-9cMr9ZX+ga6Sfa7FLoL4sACsPI8=", + "dev": true, + "requires": { + "path-key": "^1.0.0" + } + }, + "npmpub": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/npmpub/-/npmpub-3.1.0.tgz", + "integrity": "sha1-c0OoAf+xi/0s7CM1hLkUWa5O4Uk=", + "dev": true, + "requires": { + "chalk": "^1.1.1", + "github-release-from-changelog": "^1.1.1", + "minimist": "^1.2.0", + "shelljs": "^0.5.3", + "trash": "^3.4.1" + }, + "dependencies": { + "ansi-styles": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", + "dev": true + }, + "chalk": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", + "dev": true, + "requires": { + "ansi-styles": "^2.2.1", + "escape-string-regexp": "^1.0.2", + "has-ansi": "^2.0.0", + "strip-ansi": "^3.0.0", + "supports-color": "^2.0.0" + } + }, + "supports-color": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", + "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", + "dev": true + } + } + }, + "object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", + "dev": true + }, + "object-inspect": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.6.0.tgz", + "integrity": "sha512-GJzfBZ6DgDAmnuaM3104jR4s1Myxr3Y3zfIyN4z3UdqN69oSRacNK8UhnobDdC+7J2AHCjGwxQubNJfE70SXXQ==", + "dev": true + }, + "object-keys": { + "version": "1.0.12", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.0.12.tgz", + "integrity": "sha512-FTMyFUm2wBcGHnH2eXmz7tC6IwlqQZ6mVZ+6dm6vZ4IQIHjs6FdNsQBuKGPuUUUY6NfJw2PshC08Tn6LzLDOag==", + "dev": true + }, + "once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "dev": true, + "requires": { + "wrappy": "1" + } + }, + "os-homedir": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz", + "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=", + "dev": true + }, + "path-exists": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-2.1.0.tgz", + "integrity": "sha1-D+tsZPD8UY2adU3V77YscCJ2H0s=", + "dev": true, + "requires": { + "pinkie-promise": "^2.0.0" + } + }, + "path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", + "dev": true + }, + "path-key": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-1.0.0.tgz", + "integrity": "sha1-XVPVeAGWRsDWiADbThRua9wqx68=", + "dev": true + }, + "path-parse": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz", + "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==", + "dev": true + }, + "pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", + "dev": true + }, + "pinkie": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz", + "integrity": "sha1-clVrgM+g1IqXToDnckjoDtT3+HA=", + "dev": true + }, + "pinkie-promise": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz", + "integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=", + "dev": true, + "requires": { + "pinkie": "^2.0.0" + } + }, + "postcss": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.2.tgz", + "integrity": "sha512-fmaUY5370keLUTx+CnwRxtGiuFTcNBLQBqr1oE3WZ/euIYmGAo0OAgOhVJ3ByDnVmOR3PK+0V9VebzfjRIUcqw==", + "requires": { + "chalk": "^2.4.1", + "source-map": "^0.6.1", + "supports-color": "^5.4.0" + } + }, + "pseudomap": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", + "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=", + "dev": true + }, + "readjson": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/readjson/-/readjson-1.1.4.tgz", + "integrity": "sha512-H4dRk2S67w3HtE1apnw5wlHpN9qkJ0pen0AcEvyAfnrPfskZIyUOYLXpfN6olDQZI+eUlxg0Yo4lJ2bymujOUA==", + "dev": true, + "requires": { + "try-catch": "^2.0.0" + } + }, + "resolve": { + "version": "1.7.1", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.7.1.tgz", + "integrity": "sha512-c7rwLofp8g1U+h1KNyHL/jicrKg1Ek4q+Lr33AL65uZTinUZHe30D5HlyN5V9NW0JX1D5dXQ4jqW5l7Sy/kGfw==", + "dev": true, + "requires": { + "path-parse": "^1.0.5" + } + }, + "resumer": { + "version": "0.0.0", + "resolved": "https://registry.npmjs.org/resumer/-/resumer-0.0.0.tgz", + "integrity": "sha1-8ej0YeQGS6Oegq883CqMiT0HZ1k=", + "dev": true, + "requires": { + "through": "~2.3.4" + } + }, + "rimraf": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.2.tgz", + "integrity": "sha512-lreewLK/BlghmxtfH36YYVg1i8IAce4TI7oao75I1g245+6BctqTVQiBP3YUJ9C6DQOXJmkYR9X9fCLtCOJc5w==", + "dev": true, + "requires": { + "glob": "^7.0.5" + } + }, + "run-applescript": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/run-applescript/-/run-applescript-2.1.0.tgz", + "integrity": "sha1-O/8sz5W2zqy0lyPlUPADcdYYUQ0=", + "dev": true, + "requires": { + "pify": "^2.2.0", + "pinkie-promise": "^2.0.0" + } + }, + "shelljs": { + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/shelljs/-/shelljs-0.5.3.tgz", + "integrity": "sha1-xUmCuZbHbvDB5rWfvcWCX1txMRM=", + "dev": true + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" + }, + "string.prototype.trim": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.1.2.tgz", + "integrity": "sha1-0E3iyJ4Tf019IG8Ia17S+ua+jOo=", + "dev": true, + "requires": { + "define-properties": "^1.1.2", + "es-abstract": "^1.5.0", + "function-bind": "^1.0.2" + } + }, + "strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "dev": true, + "requires": { + "ansi-regex": "^2.0.0" + } + }, + "strip-eof": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz", + "integrity": "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8=", + "dev": true + }, + "supports-color": { + "version": "5.4.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.4.0.tgz", + "integrity": "sha512-zjaXglF5nnWpsq470jSv6P9DwPvgLkuapYmfDm3JWOm0vkNTVF2tI4UrN2r6jH1qM/uc/WtxYY1hYoA2dOKj5w==", + "requires": { + "has-flag": "^3.0.0" + } + }, + "tape": { + "version": "4.9.1", + "resolved": "https://registry.npmjs.org/tape/-/tape-4.9.1.tgz", + "integrity": "sha512-6fKIXknLpoe/Jp4rzHKFPpJUHDHDqn8jus99IfPnHIjyz78HYlefTGD3b5EkbQzuLfaEvmfPK3IolLgq2xT3kw==", + "dev": true, + "requires": { + "deep-equal": "~1.0.1", + "defined": "~1.0.0", + "for-each": "~0.3.3", + "function-bind": "~1.1.1", + "glob": "~7.1.2", + "has": "~1.0.3", + "inherits": "~2.0.3", + "minimist": "~1.2.0", + "object-inspect": "~1.6.0", + "resolve": "~1.7.1", + "resumer": "~0.0.0", + "string.prototype.trim": "~1.1.2", + "through": "~2.3.8" + } + }, + "through": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", + "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=", + "dev": true + }, + "trash": { + "version": "3.4.2", + "resolved": "https://registry.npmjs.org/trash/-/trash-3.4.2.tgz", + "integrity": "sha1-+wQiUvwmoCInaVCiuw7Om5QF6xk=", + "dev": true, + "requires": { + "escape-string-applescript": "^1.0.0", + "fs-extra": "^0.26.2", + "globby": "^4.0.0", + "path-exists": "^2.0.0", + "pify": "^2.3.0", + "pinkie-promise": "^2.0.0", + "run-applescript": "^2.0.0", + "uuid": "^2.0.1", + "xdg-trashdir": "^2.0.0" + } + }, + "try-catch": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/try-catch/-/try-catch-2.0.0.tgz", + "integrity": "sha512-RPXpVjsbtWgymwGq5F/OWDFsjEzdvzwHFaMjWWW6f/p6+uk/N7YSKJHQfIfGqITfj8qH4cBqCLMnhKZBaKk7Kg==", + "dev": true + }, + "url-template": { + "version": "2.0.8", + "resolved": "https://registry.npmjs.org/url-template/-/url-template-2.0.8.tgz", + "integrity": "sha1-/FZaPMy/93MMd19WQflVV5FDnyE=", + "dev": true + }, + "user-home": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/user-home/-/user-home-2.0.0.tgz", + "integrity": "sha1-nHC/2Babwdy/SGBODwS4tJzenp8=", + "dev": true, + "requires": { + "os-homedir": "^1.0.0" + } + }, + "uuid": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-2.0.3.tgz", + "integrity": "sha1-Z+LoY3lyFVMN/zGOW/nc6/1Hsho=", + "dev": true + }, + "which": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", + "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "dev": true, + "requires": { + "isexe": "^2.0.0" + } + }, + "wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", + "dev": true + }, + "xdg-basedir": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/xdg-basedir/-/xdg-basedir-2.0.0.tgz", + "integrity": "sha1-7byQPMOF/ARSPZZqM1UEtVBNG9I=", + "dev": true, + "requires": { + "os-homedir": "^1.0.0" + } + }, + "xdg-trashdir": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/xdg-trashdir/-/xdg-trashdir-2.1.1.tgz", + "integrity": "sha512-KcVhPaOu2ZurYNHSRTf1+ZHORkTZGCQ+u0JHN17QixRISJq4pXOnjt/lQcehvtHL5QAKhSzKgyjrcNnPdkPBHA==", + "dev": true, + "requires": { + "@sindresorhus/df": "^2.1.0", + "mount-point": "^3.0.0", + "pify": "^2.2.0", + "user-home": "^2.0.0", + "xdg-basedir": "^2.0.0" + } + }, + "yallist": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", + "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=", + "dev": true + } + } +} diff --git a/package.json b/package.json index 2e22b64729..e0a3662e13 100644 --- a/package.json +++ b/package.json @@ -24,8 +24,11 @@ "LICENSE", "index.js" ], + "engines": { + "node": ">=6.0.0" + }, "dependencies": { - "postcss": "^6.0.1" + "postcss": "^7.0.2" }, "devDependencies": { "npmpub": "^3.1.0", diff --git a/test/index.js b/test/index.js index b0ef75e111..86c402e268 100644 --- a/test/index.js +++ b/test/index.js @@ -14,7 +14,7 @@ function compareFixtures(t, name, msg, opts, postcssOpts) { opts = opts || {} var actual = postcss().use(plugin(opts)).process(read(postcssOpts.from), postcssOpts).css var expected = read(filename("fixtures/" + name + ".output")) - fs.writeFile(filename("fixtures/" + name + ".actual"), actual) + fs.writeFileSync(filename("fixtures/" + name + ".actual"), actual) t.equal(actual.trim(), expected.trim(), msg) } From 8a254c61a35c5ac2bb5963b52c498678edb5460e Mon Sep 17 00:00:00 2001 From: Aleks Hudochenkov Date: Mon, 17 Sep 2018 19:25:04 +0200 Subject: [PATCH 683/795] Update PostCSS From d727fdfcd1e96bdb4677fa1d479cd6ed9f2c1b89 Mon Sep 17 00:00:00 2001 From: Eduard Kyvenko Date: Mon, 17 Sep 2018 20:25:30 +0300 Subject: [PATCH 684/795] Upgrade to PostCSS 7 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index e461e48598..43582c2a00 100644 --- a/package.json +++ b/package.json @@ -25,7 +25,7 @@ "node": ">=4.0.0" }, "dependencies": { - "postcss": "^6.0.22", + "postcss": "^7.0.2", "postcss-values-parser": "^1.5.0" }, "devDependencies": { From 6a1a6fc6846b0cffc4e7d15d7e444c4f2bf01b9f Mon Sep 17 00:00:00 2001 From: Jonathan Neal Date: Mon, 17 Sep 2018 14:47:54 -0400 Subject: [PATCH 685/795] 3.0.0 --- .gitignore | 2 +- .rollup.js | 9 +- .tape.js | 52 +++++++++++ CHANGELOG.md | 7 ++ INSTALL.md | 170 +++++++++++++++++++++++++++++++++++ README.md | 136 ++++++++++++++-------------- index.js | 13 ++- lib/color.js | 4 +- lib/import.js | 131 +++++++++++++++++++++++++++ lib/transform.js | 86 +++++++++--------- package.json | 22 ++--- test/basic.colors.expect.css | 8 +- test/basic.css | 8 +- test/basic.expect.css | 8 +- test/import-root.css | 9 ++ test/import-root.js | 7 ++ test/import-root.json | 7 ++ test/import.css | 95 ++++++++++++++++++++ test/import.expect.css | 95 ++++++++++++++++++++ 19 files changed, 734 insertions(+), 135 deletions(-) create mode 100644 INSTALL.md create mode 100644 lib/import.js create mode 100644 test/import-root.css create mode 100644 test/import-root.js create mode 100644 test/import-root.json create mode 100644 test/import.css create mode 100644 test/import.expect.css diff --git a/.gitignore b/.gitignore index de73e5a338..6b0c809b57 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,5 @@ node_modules -index.*.js +index.*.* package-lock.json *.log* *.result.css diff --git a/.rollup.js b/.rollup.js index 0436758216..3f28a5511b 100644 --- a/.rollup.js +++ b/.rollup.js @@ -3,13 +3,16 @@ import babel from 'rollup-plugin-babel'; export default { input: 'index.js', output: [ - { file: 'index.cjs.js', format: 'cjs' }, - { file: 'index.es.js', format: 'es' } + { file: 'index.cjs.js', format: 'cjs', sourcemap: true }, + { file: 'index.es.mjs', format: 'es', sourcemap: true } ], plugins: [ babel({ + plugins: [ + '@babel/plugin-syntax-dynamic-import' + ], presets: [ - ['env', { modules: false, targets: { node: 4 } }] + ['@babel/env', { modules: false, targets: { node: 6 } }] ] }) ] diff --git a/.tape.js b/.tape.js index daa07d1e55..5c34e31777 100644 --- a/.tape.js +++ b/.tape.js @@ -29,5 +29,57 @@ module.exports = { 'hex': { message: 'supports hex usage' }, + 'import': { + message: 'supports { importFrom: "test/import-root.css" } usage', + options: { + importFrom: 'test/import-root.css' + } + }, + 'import:array': { + message: 'supports { importFrom: ["test/import-root.css"] } usage', + options: { + importFrom: ['test/import-root.css'] + }, + expect: 'import.expect.css', + result: 'import.result.css' + }, + 'import:array-array': { + message: 'supports { importFrom: [["css", "test/import-root.css" ]] } usage', + options: { + importFrom: [['css', 'test/import-root.css' ]] + }, + expect: 'import.expect.css', + result: 'import.result.css' + }, + 'import:js': { + message: 'supports { importFrom: "test/import-root.js" } usage', + options: { + importFrom: 'test/import-root.js' + }, + expect: 'import.expect.css', + result: 'import.result.css' + }, + 'import:json': { + message: 'supports { importFrom: "test/import-root.json" } usage', + options: { + importFrom: 'test/import-root.json' + }, + expect: 'import.expect.css', + result: 'import.result.css' + }, + 'import:object': { + message: 'supports { importFrom: { customProperties: {} } } usage', + options: { + importFrom: { + customProperties: { + '--color-blue': 'blue', + '--color-red': 'red', + '--color': 'var(--color-blue)' + } + } + }, + expect: 'import.expect.css', + result: 'import.result.css' + } } }; diff --git a/CHANGELOG.md b/CHANGELOG.md index 1cc2fbd46d..d41564501b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,12 @@ # Changes to PostCSS color-mod() Function +### 3.0.0 (August 30, 2018) + +- Added `importFrom` option which allows you to import Custom Properties from +CSS, JS, and JSON files, and directly passed objects +- Fixed an issue where multiple variables could not be used in `color-mod()` +- Updated to support Node v6+ + ### 2.4.3 (July 21, 2018) - Fixed issue with color-mod not being converted within function diff --git a/INSTALL.md b/INSTALL.md new file mode 100644 index 0000000000..3db6b033ca --- /dev/null +++ b/INSTALL.md @@ -0,0 +1,170 @@ +# Installing PostCSS color-mod() Function + +[PostCSS color-mod() Function] runs in all Node environments, with special instructions for: + +| [Node](#node) | [PostCSS CLI](#postcss-cli) | [Webpack](#webpack) | [Create React App](#create-react-app) | [Gulp](#gulp) | [Grunt](#grunt) | +| --- | --- | --- | --- | --- | --- | + +## Node + +Add [PostCSS color-mod() Function] to your project: + +```bash +npm install postcss-color-mod-function --save-dev +``` + +Use [PostCSS color-mod() Function] to process your CSS: + +```js +const postcssColorMod = require('postcss-color-mod-function'); + +postcssColorMod.process(YOUR_CSS /*, processOptions, pluginOptions */); +``` + +Or use it as a [PostCSS] plugin: + +```js +const postcss = require('postcss'); +const postcssColorMod = require('postcss-color-mod-function'); + +postcss([ + postcssColorMod(/* pluginOptions */) +]).process(YOUR_CSS /*, processOptions */); +``` + +## PostCSS CLI + +Add [PostCSS CLI] to your project: + +```bash +npm install postcss-cli --save-dev +``` + +Use [PostCSS color-mod() Function] in your `postcss.config.js` configuration file: + +```js +const postcssColorMod = require('postcss-color-mod-function'); + +module.exports = { + plugins: [ + postcssColorMod(/* pluginOptions */) + ] +} +``` + +## Webpack + +Add [PostCSS Loader] to your project: + +```bash +npm install postcss-loader --save-dev +``` + +Use [PostCSS color-mod() Function] in your Webpack configuration: + +```js +const postcssColorMod = require('postcss-color-mod-function'); + +module.exports = { + module: { + rules: [ + { + test: /\.css$/, + use: [ + 'style-loader', + { loader: 'css-loader', options: { importLoaders: 1 } }, + { loader: 'postcss-loader', options: { + ident: 'postcss', + plugins: () => [ + postcssColorMod(/* pluginOptions */) + ] + } } + ] + } + ] + } +} +``` + +## Create React App + +Add [React App Rewired] and [React App Rewire PostCSS] to your project: + +```bash +npm install react-app-rewired react-app-rewire-postcss --save-dev +``` + +Use [React App Rewire PostCSS] and [PostCSS color-mod() Function] in your +`config-overrides.js` file: + +```js +const reactAppRewirePostcss = require('react-app-rewire-postcss'); +const postcssColorMod = require('postcss-color-mod-function'); + +module.exports = config => reactAppRewirePostcss(config, { + plugins: () => [ + postcssColorMod(/* pluginOptions */) + ] +}); +``` + +## Gulp + +Add [Gulp PostCSS] to your project: + +```bash +npm install gulp-postcss --save-dev +``` + +Use [PostCSS color-mod() Function] in your Gulpfile: + +```js +const postcss = require('gulp-postcss'); +const postcssColorMod = require('postcss-color-mod-function'); + +gulp.task('css', () => gulp.src('./src/*.css').pipe( + postcss([ + postcssColorMod(/* pluginOptions */) + ]) +).pipe( + gulp.dest('.') +)); +``` + +## Grunt + +Add [Grunt PostCSS] to your project: + +```bash +npm install grunt-postcss --save-dev +``` + +Use [PostCSS color-mod() Function] in your Gruntfile: + +```js +const postcssColorMod = require('postcss-color-mod-function'); + +grunt.loadNpmTasks('grunt-postcss'); + +grunt.initConfig({ + postcss: { + options: { + use: [ + postcssColorMod(/* pluginOptions */) + ] + }, + dist: { + src: '*.css' + } + } +}); +``` + +[Gulp PostCSS]: https://github.com/postcss/gulp-postcss +[Grunt PostCSS]: https://github.com/nDmitry/grunt-postcss +[PostCSS]: https://github.com/postcss/postcss +[PostCSS CLI]: https://github.com/postcss/postcss-cli +[PostCSS Loader]: https://github.com/postcss/postcss-loader +[PostCSS color-mod() Function]: https://github.com/jonathantneal/postcss-color-mod-function +[React App Rewire PostCSS]: https://github.com/csstools/react-app-rewire-postcss +[React App Rewired]: https://github.com/timarney/react-app-rewired diff --git a/README.md b/README.md index 976c1aa028..7670583920 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,9 @@ [PostCSS color-mod() Function] lets you modify colors using the `color-mod()` function in CSS, following the [CSS Color Module Level 4] specification. -```css +**`color-mod()` has been removed from the Color Module Level 4 specification.** + +```pcss :root { --brand-red: color-mod(yellow blend(red 50%)); --brand-red-hsl: color-mod(yellow blend(red 50% hsl)); @@ -36,7 +38,7 @@ function in CSS, following the [CSS Color Module Level 4] specification. } ``` -## Supported Colors +### Supported Colors The `color-mod()` function accepts `rgb()`, legacy comma-separated `rgb()`, `rgba()`, `hsl()`, legacy comma-separated `hsl()`, `hsla()`, `hwb()`, and @@ -46,7 +48,7 @@ colors without the need for additional plugins. Implemention details are available in [the specification](https://drafts.csswg.org/css-color/#funcdef-color-mod). -## Supported Color Adjusters +### Supported Color Adjusters The `color-mod()` function accepts `red()`, `green()`, `blue()`, `a()` / `alpha()`, `rgb()`, `h()` / `hue()`, `s()` / `saturation()`, `l()` / @@ -56,98 +58,42 @@ The `color-mod()` function accepts `red()`, `green()`, `blue()`, `a()` / Implemention details are available in [the specification](https://drafts.csswg.org/css-color/#typedef-color-adjuster). -## Supported Variables +### Supported Variables By default, `var()` variables will be used if their corresponding Custom Properties are found in a `:root` rule, or if a fallback value is specified. ---- - ## Usage -Add [PostCSS color-mod() Function] to your build tool: +Add [PostCSS color-mod() Function] to your project: ```bash npm install postcss-color-mod-function --save-dev ``` -#### Node - Use [PostCSS color-mod() Function] to process your CSS: ```js -import postcssColorMod from 'postcss-color-mod-function'; +const postcssColorMod = require('postcss-color-mod-function'); -postcssColorMod.process(YOUR_CSS); +postcssColorMod.process(YOUR_CSS /*, processOptions, pluginOptions */); ``` -#### PostCSS - -Add [PostCSS] to your build tool: - -```bash -npm install postcss --save-dev -``` - -Use [PostCSS color-mod() Function] as a plugin: +Or use it as a [PostCSS] plugin: ```js -import postcss from 'postcss'; -import postcssColorMod from 'postcss-color-mod-function'; +const postcss = require('postcss'); +const postcssColorMod = require('postcss-color-mod-function'); postcss([ - postcssColorMod(/* options */) -]).process(YOUR_CSS); -``` - -#### Gulp - -Add [Gulp PostCSS] to your build tool: - -```bash -npm install gulp-postcss --save-dev + postcssColorMod(/* pluginOptions */) +]).process(YOUR_CSS /*, processOptions */); ``` -Use [PostCSS color-mod() Function] in your Gulpfile: - -```js -import postcss from 'gulp-postcss'; -import postcssColorMod from 'postcss-color-mod-function'; - -gulp.task('css', - () => gulp.src('./src/*.css') - .pipe( postcss([ postcssColorMod(/* options */) ]) ) - .pipe( gulp.dest('.') ); -``` - -#### Grunt - -Add [Grunt PostCSS] to your build tool: - -```bash -npm install grunt-postcss --save-dev -``` - -Use [PostCSS color-mod() Function] in your Gruntfile: - -```js -import postcssColorMod from 'postcss-color-mod-function'; +[PostCSS color-mod() Function] runs in all Node environments, with special instructions for: -grunt.loadNpmTasks('grunt-postcss'); - -grunt.initConfig({ - postcss: { - options: { - use: [ postcssColorMod(/* options */) ] - }, - dist: { - src: '*.css' - } - } -}); -``` - ---- +| [Node](INSTALL.md#node) | [PostCSS CLI](INSTALL.md#postcss-cli) | [Webpack](INSTALL.md#webpack) | [Create React App](INSTALL.md#create-react-app) | [Gulp](INSTALL.md#gulp) | [Grunt](INSTALL.md#grunt) | +| --- | --- | --- | --- | --- | --- | ## Options @@ -197,6 +143,54 @@ However, because these transformations occur at build time, they cannot be considered accurate. Accurately resolving cascading variables relies on knowledge of the living DOM tree. +### importFrom + +The `importFrom` option allows you to import variables from other sources, +which might be CSS, JS, and JSON files, and directly passed objects. + +```js +postcssColorMod({ + importFrom: 'path/to/file.css' // :root { --brand-dark: blue; --brand-main: var(--brand-dark); } +}); +``` + +```pcss +.brand-faded { + color: color-mod(var(--brand-main) a(50%)); +} + +/* becomes */ + +.brand-faded { + color: rgba(0, 0, 255, .5); +} +``` + +Multiple files can be passed into this option, and they will be parsed in the +order they were received. JavaScript files, JSON files, and objects will need +to namespace custom properties under a `customProperties` or +`custom-properties` key. + +```js +postcssColorMod({ + importFrom: [ + 'path/to/file.css', // :root { --brand-dark: blue; --brand-main: var(--brand-dark); } + 'and/then/this.js', // module.exports = { customProperties: { '--brand-dark': 'blue', '--brand-main': 'var(--brand-dark)' } } + 'and/then/that.json', // { "custom-properties": { "--brand-dark": "blue", "--brand-main": "var(--brand-dark)" } } + { + customProperties: { + '--brand-dark': 'blue', + '--brand-main': 'var(--brand-dark)' + } + } + ] +}); +``` + +Variables may reference other variables, and this plugin will attempt to +resolve them. If `transformVars` is set to `false` then `importFrom` will not +be used. + [cli-img]: https://img.shields.io/travis/jonathantneal/postcss-color-mod-function.svg [cli-url]: https://travis-ci.org/jonathantneal/postcss-color-mod-function [css-img]: https://cssdb.org/badge/color-mod-function.svg diff --git a/index.js b/index.js index 5d10d76b31..15e80ecadb 100644 --- a/index.js +++ b/index.js @@ -1,15 +1,19 @@ -// tooling +import { importCustomPropertiesFromSources, importCustomPropertiesFromCSSAST } from './lib/import'; import parser from 'postcss-values-parser'; import postcss from 'postcss'; import transformAST from './lib/transform'; -// plugin export default postcss.plugin('postcss-color-mod-function', opts => { const unresolvedOpt = String(Object(opts).unresolved || 'throw').toLowerCase(); const stringifierOpt = Object(opts).stringifier || (color => color.toLegacy()); + const importFrom = [].concat(Object(opts).importFrom || []); const transformVarsOpt = 'transformVars' in Object(opts) ? opts.transformVars : true; - return (root, result) => { + const customPropertiesPromise = importCustomPropertiesFromSources(importFrom); + + return async (root, result) => { + const customProperties = Object.assign(await customPropertiesPromise, await importCustomPropertiesFromCSSAST(root)); + root.walkDecls(decl => { const originalValue = decl.value; @@ -21,7 +25,8 @@ export default postcss.plugin('postcss-color-mod-function', opts => { stringifier: stringifierOpt, transformVars: transformVarsOpt, decl, - result + result, + customProperties }); const modifiedValue = ast.toString(); diff --git a/lib/color.js b/lib/color.js index 66e232a093..f37ae4bbed 100644 --- a/lib/color.js +++ b/lib/color.js @@ -323,8 +323,8 @@ function colors2contrast(color1, color2) { // https://drafts.csswg.org/css-color/#contrast-ratio const rgb1 = color2rgb(color1); const rgb2 = color2rgb(color2); - var l1 = rgb2luminance(rgb1.red, rgb1.green, rgb1.blue); - var l2 = rgb2luminance(rgb2.red, rgb2.green, rgb2.blue); + const l1 = rgb2luminance(rgb1.red, rgb1.green, rgb1.blue); + const l2 = rgb2luminance(rgb2.red, rgb2.green, rgb2.blue); return l1 > l2 // if l1 is the relative luminance of the lighter of the colors diff --git a/lib/import.js b/lib/import.js new file mode 100644 index 0000000000..47100bd71d --- /dev/null +++ b/lib/import.js @@ -0,0 +1,131 @@ +import fs from 'fs'; +import path from 'path'; +import postcss from 'postcss'; + +/* Import Custom Properties from CSS AST +/* ========================================================================== */ + +export function importCustomPropertiesFromCSSAST(root) { + // custom properties can be written on html or :root + const htmlCustomProperties = {}; + const rootCustomProperties = {}; + + // for each html and :root rule + Object(root.nodes).filter(isHtmlOrRootRule).forEach(({ nodes, selector }) => { + // for each custom property + Object(nodes).filter(isCustomPropertyDecl).forEach(({ prop, value }) => { + // write to the custom properties from either html or :root + const customProperties = matchHtml.test(selector) ? htmlCustomProperties : rootCustomProperties; + + customProperties[prop] = value; + }); + }); + + // return all html and :root custom properties, where :root prevails + return Object.assign({}, htmlCustomProperties, rootCustomProperties); +} + +/* Import Custom Properties from CSS File +/* ========================================================================== */ + +async function importCustomPropertiesFromCSSFile(from) { + const css = await readFile(path.resolve(from)); + const root = postcss.parse(css, { from: path.resolve(from) }); + + return importCustomPropertiesFromCSSAST(root); +} + +/* Import Custom Properties from Object +/* ========================================================================== */ + +function importCustomPropertiesFromObject(object) { + const customProperties = Object.assign({}, Object(object).customProperties || Object(object)['custom-properties']); + + return customProperties; +} + +/* Import Custom Properties from JSON file +/* ========================================================================== */ + +async function importCustomPropertiesFromJSONFile(from) { + const object = await readJSON(path.resolve(from)); + + return importCustomPropertiesFromObject(object); +} + +/* Import Custom Properties from JS file +/* ========================================================================== */ + +async function importCustomPropertiesFromJSFile(from) { + const object = await import(path.resolve(from)); + + return importCustomPropertiesFromObject(object); +} + +/* Import Custom Properties from Sources +/* ========================================================================== */ + +export function importCustomPropertiesFromSources(sources) { + return sources.map(source => { + if (typeof source === 'string') { + if (isCSSPath(source)) { + return [ 'css', source ] + } else if (isJSPath(source)) { + return [ 'js', source ] + } else if (isJSONPath(source)) { + return [ 'json', source ] + } + } + + return Object(source); + }).reduce(async (customProperties, source) => { + const type = source[0]; + const from = source[1]; + + if (type === 'ast') { + return Object.assign(customProperties, importCustomPropertiesFromCSSAST(from)); + } + + if (type === 'css') { + return Object.assign(customProperties, await importCustomPropertiesFromCSSFile(from)); + } + + if (type === 'js') { + return Object.assign(customProperties, await importCustomPropertiesFromJSFile(from)); + } + + if (type === 'json') { + return Object.assign(customProperties, await importCustomPropertiesFromJSONFile(from)); + } + + return Object.assign(customProperties, importCustomPropertiesFromObject(source)); + }, {}); +} + +/* Helper utilities +/* ========================================================================== */ + +const matchCustomProperty = /^--\w/; +const matchHtml = /^html$/i; +const matchHtmlOrRoot = /^(html|:root)$/i; +const matchCSSPath = /\.\w*css/i; +const matchJSPath = /\.\w*js/i; +const matchJSONPath = /\.\w*json/i; + +const isCustomPropertyDecl = node => Object(node).type === 'decl' && matchCustomProperty.test(node.prop); +const isHtmlOrRootRule = node => Object(node).type === 'rule' && matchHtmlOrRoot.test(node.selector); +const isCSSPath = from => matchCSSPath.test(from); +const isJSPath = from => matchJSPath.test(from); +const isJSONPath = from => matchJSONPath.test(from); + +const readFile = from => new Promise((resolve, reject) => { + fs.readFile(from, 'utf8', (error, result) => { + if (error) { + reject(error); + } else { + resolve(result); + } + }); +}); + +const readJSON = async from => JSON.parse(await readFile(from)); diff --git a/lib/transform.js b/lib/transform.js index 866940a15d..4baa72c633 100644 --- a/lib/transform.js +++ b/lib/transform.js @@ -20,12 +20,10 @@ export default function transformAST(node, opts) { if (color) { // update the color-mod() function with the transformed value - child.replaceWith( - parser.word({ - raws: child.raws, - value: opts.stringifier(color) - }) - ); + child.replaceWith(parser.word({ + raws: child.raws, + value: opts.stringifier(color) + })); } } else if (child.nodes && Object(child.nodes).length) { transformAST(child, opts); @@ -37,44 +35,35 @@ export default function transformAST(node, opts) { /* ========================================================================== */ function transformVariables(node, opts) { - node.walk( - child => { - if (isVariable(child)) { - const [variableName, fallbackNode] = transformArgsByParams(child, [ - // , [ ]? - [transformWord, isComma, transformNode] - ]); - - if (variableName) { - let variableNode; - - opts.result.root.walkRules(':root', rule => { - rule.nodes.filter( - rootChild => rootChild.prop === variableName - ).slice(-1).forEach( - rootChild => { - const rootChildValue = rootChild.value; - - const rootChildAST = parser(rootChildValue, { loose: true }).parse(); - - transformVariables(rootChildAST, opts); - - variableNode = rootChildAST.nodes[0]; - } - ); - }); - - if (variableNode) { - child.replaceWith(...variableNode.nodes); - } - } else if (fallbackNode) { - transformVariables(fallbackNode, opts); - - child.replaceWith(...fallbackNode.nodes[0].nodes); + walk(node, child => { + if (isVariable(child)) { + const [variableName, fallbackNode] = transformArgsByParams(child, [ + // , [ ]? + [transformWord, isComma, transformNode] + ]); + + if (variableName in opts.customProperties) { + let customPropertyValue = String(opts.customProperties[variableName]); + + if (looseVarMatch.test(customPropertyValue)) { + const rootChildAST = parser(customPropertyValue, { loose: true }).parse(); + + transformVariables(rootChildAST, opts); + + customPropertyValue = opts.customProperties[variableName] = String(rootChildAST); } + + child.replaceWith(parser.word({ + raws: child.raws, + value: customPropertyValue + })); + } else if (fallbackNode) { + transformVariables(fallbackNode, opts); + + child.replaceWith(...fallbackNode.nodes[0].nodes); } } - ); + }); } /* Transform functions @@ -581,6 +570,20 @@ function transformArgsByParams(node, params) { ))[0] || []; } +/* Walk helper (required because the default walker is affected by mutations) +/* ========================================================================== */ + +// run a function over each node and hen walk each child node of that node +function walk(node, fn) { + fn(node); + + if (Object(node.nodes).length) { + node.nodes.slice().forEach(childNode => { + walk(childNode, fn); + }); + } +} + /* Variable validators /* ========================================================================== */ @@ -748,4 +751,5 @@ const rgbMatch = /^rgb$/i; const rgbaMatch = /^rgba?$/i; const shadeTintMatch = /^(shade|tint)$/i; const varMatch = /^var$/i; +const looseVarMatch = /(^|[^\w-])var\(/i; const timesMatch = /^[*]$/; diff --git a/package.json b/package.json index 1d3600994b..d056ed1ab0 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "postcss-color-mod-function", - "version": "2.4.3", + "version": "3.0.0", "description": "Modify colors using the color-mod() function in CSS", "author": "Jonathan Neal ", "license": "CC0-1.0", @@ -11,8 +11,9 @@ "module": "index.es.js", "files": [ "index.cjs.js", - "index.es.js", - "lib" + "index.cjs.js.map", + "index.es.mjs", + "index.es.mjs.map" ], "scripts": { "prepublishOnly": "npm test", @@ -27,20 +28,21 @@ }, "dependencies": { "@csstools/convert-colors": "^1.4.0", - "postcss": "^6.0.23", + "postcss": "^7.0.2", "postcss-values-parser": "^1.5.0" }, "devDependencies": { - "babel-core": "^6.26.3", - "babel-eslint": "^8.2.6", - "babel-preset-env": "^1.7.0", + "@babel/core": "^7.0.1", + "@babel/plugin-syntax-dynamic-import": "^7.0.0", + "@babel/preset-env": "^7.0.0", + "babel-eslint": "^9.0.0", "echint": "^4.0.1", - "eslint": "^5.2.0", + "eslint": "^5.6.0", "eslint-config-dev": "^2.0.0", "postcss-tape": "^2.2.0", "pre-commit": "^1.2.2", - "rollup": "^0.63.4", - "rollup-plugin-babel": "^3.0.7" + "rollup": "^0.66.0", + "rollup-plugin-babel": "^4.0.3" }, "eslintConfig": { "extends": "dev", diff --git a/test/basic.colors.expect.css b/test/basic.colors.expect.css index bc19fc583b..206e68077f 100644 --- a/test/basic.colors.expect.css +++ b/test/basic.colors.expect.css @@ -121,7 +121,9 @@ test-sameness { } :root { - --color: blue; + --color-blue: blue; + --color-red: red; + --color: var(--color-blue); } test-var { @@ -135,3 +137,7 @@ test-multiple-value-items { test-linear-gradient { background-image: linear-gradient(rgb(100% 0% 0%), rgb(100% 0% 0% / 0%)); } + +test-var-blend { + color: rgb(90% 0% 10%); +} diff --git a/test/basic.css b/test/basic.css index 1bcd540af4..1d047a3794 100644 --- a/test/basic.css +++ b/test/basic.css @@ -121,7 +121,9 @@ test-sameness { } :root { - --color: blue; + --color-blue: blue; + --color-red: red; + --color: var(--color-blue); } test-var { @@ -135,3 +137,7 @@ test-multiple-value-items { test-linear-gradient { background-image: linear-gradient(color-mod(red alpha(100%)), color-mod(red alpha(0%))); } + +test-var-blend { + color: color-mod(var(--color-red) blend(var(--color) 10%)); +} diff --git a/test/basic.expect.css b/test/basic.expect.css index b1f62ab38f..6f0e072afc 100644 --- a/test/basic.expect.css +++ b/test/basic.expect.css @@ -121,7 +121,9 @@ test-sameness { } :root { - --color: blue; + --color-blue: blue; + --color-red: red; + --color: var(--color-blue); } test-var { @@ -135,3 +137,7 @@ test-multiple-value-items { test-linear-gradient { background-image: linear-gradient(rgb(255, 0, 0), rgba(255, 0, 0, 0)); } + +test-var-blend { + color: rgb(230, 0, 26); +} diff --git a/test/import-root.css b/test/import-root.css new file mode 100644 index 0000000000..3ac36c1d73 --- /dev/null +++ b/test/import-root.css @@ -0,0 +1,9 @@ +html { + --color-blue: blue; + --color-red: red; + --color: var(--color-red); +} + +:root { + --color: var(--color-blue); +} diff --git a/test/import-root.js b/test/import-root.js new file mode 100644 index 0000000000..910bbb2809 --- /dev/null +++ b/test/import-root.js @@ -0,0 +1,7 @@ +module.exports = { + customProperties: { + '--color-blue': 'blue', + '--color-red': 'red', + '--color': 'var(--color-blue)' + } +}; diff --git a/test/import-root.json b/test/import-root.json new file mode 100644 index 0000000000..821d4051f7 --- /dev/null +++ b/test/import-root.json @@ -0,0 +1,7 @@ +{ + "custom-properties": { + "--color-blue": "blue", + "--color-red": "red", + "--color": "var(--color-blue)" + } +} diff --git a/test/import.css b/test/import.css new file mode 100644 index 0000000000..eb686453c9 --- /dev/null +++ b/test/import.css @@ -0,0 +1,95 @@ +test-color-mod { + color: color-mod(var(--color)); + color: color-mod(color-mod(var(--color))); + color: color-mod(color-mod(color-mod(var(--color)))); +} + +test-red-green-blue-alpha-adjuster { + color: color-mod(var(--color) blue(20)); + color: color-mod(var(--color) blue(20%)); + color: color-mod(var(--color) green(+ 20)); + color: color-mod(var(--color) green(+ 20%)); + color: color-mod(var(--color) red(- 20)); + color: color-mod(var(--color) red(- 20%)); + color: color-mod(var(--color) red(- 128)); + color: color-mod(var(--color) alpha(- 50%)); + color: color-mod(var(--color) alpha(- .75)); +} + +test-rgb-adjuster { + color: color-mod(var(--color) rgb(+ 0 255 0)); + color: color-mod(var(--color) rgb(+ #0f0)); + color: color-mod(var(--color) rgb(- 60% 0 0)); + color: color-mod(var(--color) rgb(- #900)); + color: color-mod(var(--color) rgb(* 1%)); +} + +test-hue-adjuster { + color: color-mod(var(--color) hue(20)); + color: color-mod(var(--color) hue(20deg)); + color: color-mod(var(--color) hue(+ 20)); + color: color-mod(var(--color) hue(+ 20deg)); + color: color-mod(var(--color) hue(- 20)); + color: color-mod(var(--color) hue(- 20deg)); + color: color-mod(var(--color) hue(* 20)); + color: color-mod(var(--color) hue(* 20deg)); +} + +test-lightness-saturation-adjuster { + color: color-mod(var(--color) lightness(50%)); + color: color-mod(var(--color) lightness(20%)); + color: color-mod(var(--color) lightness(+ 20%)); + color: color-mod(var(--color) lightness(- 20%)); + color: color-mod(var(--color) lightness(* 1.5%)); + color: color-mod(var(--color) saturation(20%)); + color: color-mod(var(--color) saturation(+ 20%)); + color: color-mod(var(--color) saturation(- 20%)); + color: color-mod(var(--color) saturation(* 1.5%)); +} + +test-blackness-whiteness-adjuster { + color: color-mod(var(--color) blackness(20%)); + color: color-mod(var(--color) blackness(+ 20%)); + color: color-mod(var(--color) blackness(- 1%)); + color: color-mod(var(--color) blackness(* 20%)); + color: color-mod(var(--color) whiteness(20%)); + color: color-mod(var(--color) whiteness(+ 1%)); + color: color-mod(var(--color) whiteness(- 20%)); + color: color-mod(var(--color) whiteness(* .5%)); +} + +test-tint-shade-adjuster { + color: color-mod(var(--color) tint(0%)); + color: color-mod(var(--color) shade(0%)); + color: color-mod(var(--color) tint(100%)); + color: color-mod(var(--color) shade(100%)); + color: color-mod(var(--color) tint(20%)); + color: color-mod(var(--color) shade(20%)); +} + +test-blend-adjuster { + color: color-mod(var(--color) blend(red 50%)); + color: color-mod(var(--color) blend(red 50% rgb)); + color: color-mod(var(--color) blend(red 50% hsl)); + color: color-mod(var(--color) blend(red 50% hwb)); +} + +test-contrast-adjuster { + color: color-mod(var(--color) contrast(0%)); + color: color-mod(var(--color) contrast(25%)); + color: color-mod(var(--color) contrast(50%)); + color: color-mod(var(--color) contrast(75%)); + color: color-mod(var(--color) contrast(100%)); +} + +test-combination-adjuster { + color: color-mod(color-mod(var(--color) blue(10%)) rgb(+ 0 10 0) hue(+ 10deg) tint(10%) lightness(+ 10%) saturation(+ 10%) blend(rebeccapurple 50%)); +} + +test-multiple-value-items { + border: 1px solid color-mod(var(--color)); +} + +test-linear-gradient { + background-image: linear-gradient(color-mod(var(--color) alpha(100%)), color-mod(var(--color) alpha(0%))); +} diff --git a/test/import.expect.css b/test/import.expect.css new file mode 100644 index 0000000000..f4a005be88 --- /dev/null +++ b/test/import.expect.css @@ -0,0 +1,95 @@ +test-color-mod { + color: rgb(0, 0, 255); + color: rgb(0, 0, 255); + color: rgb(0, 0, 255); +} + +test-red-green-blue-alpha-adjuster { + color: rgb(0, 0, 20); + color: rgb(0, 0, 51); + color: rgb(0, 20, 255); + color: rgb(0, 51, 255); + color: rgb(0, 0, 255); + color: rgb(0, 0, 255); + color: rgb(0, 0, 255); + color: rgba(0, 0, 255, 0.5); + color: rgba(0, 0, 255, 0.25); +} + +test-rgb-adjuster { + color: rgb(0, 255, 255); + color: rgb(0, 255, 255); + color: rgb(0, 0, 255); + color: rgb(0, 0, 255); + color: rgb(0, 0, 255); +} + +test-hue-adjuster { + color: hsl(20, 100%, 50%); + color: hsl(20, 100%, 50%); + color: hsl(260, 100%, 50%); + color: hsl(260, 100%, 50%); + color: hsl(220, 100%, 50%); + color: hsl(220, 100%, 50%); + color: hsl(120, 100%, 50%); + color: hsl(120, 100%, 50%); +} + +test-lightness-saturation-adjuster { + color: hsl(240, 100%, 50%); + color: hsl(240, 100%, 20%); + color: hsl(240, 100%, 70%); + color: hsl(240, 100%, 30%); + color: hsl(240, 100%, 75%); + color: hsl(240, 20%, 50%); + color: hsl(240, 100%, 50%); + color: hsl(240, 80%, 50%); + color: hsl(240, 100%, 50%); +} + +test-blackness-whiteness-adjuster { + color: rgb(0, 0, 204); + color: rgb(0, 0, 204); + color: rgb(0, 0, 255); + color: rgb(0, 0, 255); + color: rgb(51, 51, 255); + color: rgb(3, 3, 255); + color: rgb(0, 0, 255); + color: rgb(0, 0, 255); +} + +test-tint-shade-adjuster { + color: rgb(0, 0, 255); + color: rgb(0, 0, 255); + color: rgb(255, 255, 255); + color: rgb(0, 0, 0); + color: rgb(51, 51, 255); + color: rgb(0, 0, 204); +} + +test-blend-adjuster { + color: rgb(128, 0, 128); + color: rgb(128, 0, 128); + color: hsl(120, 100%, 50%); + color: rgb(0, 255, 0); +} + +test-contrast-adjuster { + color: rgb(0, 0, 0); + color: rgb(0, 0, 64); + color: rgb(0, 0, 128); + color: rgb(0, 0, 191); + color: rgb(0, 0, 255); +} + +test-combination-adjuster { + color: rgb(69, 50, 121); +} + +test-multiple-value-items { + border: 1px solid rgb(0, 0, 255); +} + +test-linear-gradient { + background-image: linear-gradient(rgb(0, 0, 255), rgba(0, 0, 255, 0)); +} From 614a2f942b7caaa071779948723b66b4c7e5b42a Mon Sep 17 00:00:00 2001 From: Jonathan Neal Date: Mon, 17 Sep 2018 17:14:44 -0400 Subject: [PATCH 686/795] 8.0.2 --- CHANGELOG.md | 4 ++++ lib/transform-value-ast.js | 44 +++++++++++++++++++--------------- package.json | 2 +- test/basic.css | 4 ++++ test/basic.expect.css | 5 ++++ test/basic.import.expect.css | 5 ++++ test/basic.preserve.expect.css | 4 ++++ 7 files changed, 48 insertions(+), 20 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index adc6513459..4106ce5234 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # Changes to PostCSS Custom Properties +### 8.0.2 (September 17, 2018) + +- Fixed: Spacing is preserved before replaced variables. + ### 8.0.1 (September 17, 2018) - Fixed: Workaround issue in `postcss-values-parser` incorrectly cloning nodes. diff --git a/lib/transform-value-ast.js b/lib/transform-value-ast.js index a8db9faf5e..2d744a79c3 100644 --- a/lib/transform-value-ast.js +++ b/lib/transform-value-ast.js @@ -8,28 +8,14 @@ export default function transformValueAST(root, customProperties) { if (name in customProperties) { // conditionally replace a known custom property - child.replaceWith( - ...asClonedArray(customProperties[name], null) - ); + child.replaceWith(...asClonedArrayWithBeforeSpacing(customProperties[name], child.raws.before)); - const nextCustomProperties = Object.assign({}, customProperties); - - delete nextCustomProperties[name]; - - transformValueAST(root, nextCustomProperties); + retransformValueAST(root, customProperties, name); } else if (fallbacks.length) { // conditionally replace a custom property with a fallback - const clonedFallbacks = asClonedArray(fallbacks); - - Object.assign(clonedFallbacks[0].raws, { before: '' }); - - child.replaceWith(...clonedFallbacks); + child.replaceWith(...asClonedArrayWithBeforeSpacing(fallbacks, child.raws.before)); - const nextCustomProperties = Object.assign({}, customProperties); - - delete nextCustomProperties[name]; - - transformValueAST(root, nextCustomProperties); + transformValueAST(root, customProperties); } } else { transformValueAST(child, customProperties); @@ -40,12 +26,32 @@ export default function transformValueAST(root, customProperties) { return root; } +// retransform the current ast without a custom property (to prevent recursion) +function retransformValueAST(root, customProperties, withoutProperty) { + const nextCustomProperties = Object.assign({}, customProperties); + + delete nextCustomProperties[withoutProperty]; + + return transformValueAST(root, nextCustomProperties); +} + // match var() functions const varRegExp = /^var$/i; // whether the node is a var() function const isVarFunction = node => node.type === 'func' && varRegExp.test(node.value) && Object(node.nodes).length > 0; +// return an array with its nodes cloned, preserving the raw +const asClonedArrayWithBeforeSpacing = (array, beforeSpacing) => { + const clonedArray = asClonedArray(array, null); + + if (clonedArray[0]) { + clonedArray[0].raws.before = beforeSpacing; + } + + return clonedArray; +}; + // return an array with its nodes cloned const asClonedArray = (array, parent) => array.map(node => asClonedNode(node, parent)); @@ -64,4 +70,4 @@ const asClonedNode = (node, parent) => { } return cloneNode; -} +}; diff --git a/package.json b/package.json index dae5872f7d..ff831f5b27 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "postcss-custom-properties", - "version": "8.0.1", + "version": "8.0.2", "description": "Use Custom Properties Queries in CSS", "author": "Jonathan Neal ", "contributors": [ diff --git a/test/basic.css b/test/basic.css index c99e71a642..f42d93e723 100644 --- a/test/basic.css +++ b/test/basic.css @@ -25,3 +25,7 @@ html { .test--circular_var { color: var(--circular); } + +.test--color_spacing { + box-shadow: inset 0 -3px 0 var(--color); +} diff --git a/test/basic.expect.css b/test/basic.expect.css index 0ffbdb16cd..90691d54b9 100644 --- a/test/basic.expect.css +++ b/test/basic.expect.css @@ -28,3 +28,8 @@ html { .test--circular_var { color: var(--circular); } + +.test--color_spacing { + box-shadow: inset 0 -3px 0 rgb(255, 0, 0); + box-shadow: inset 0 -3px 0 var(--color); +} diff --git a/test/basic.import.expect.css b/test/basic.import.expect.css index d120fcf126..597054f402 100644 --- a/test/basic.import.expect.css +++ b/test/basic.import.expect.css @@ -28,3 +28,8 @@ html { .test--circular_var { color: var(--circular); } + +.test--color_spacing { + box-shadow: inset 0 -3px 0 rgb(255, 0, 0); + box-shadow: inset 0 -3px 0 var(--color); +} diff --git a/test/basic.preserve.expect.css b/test/basic.preserve.expect.css index e430ce1c3e..c6b575b057 100644 --- a/test/basic.preserve.expect.css +++ b/test/basic.preserve.expect.css @@ -14,3 +14,7 @@ .test--circular_var { color: var(--circular); } + +.test--color_spacing { + box-shadow: inset 0 -3px 0 rgb(255, 0, 0); +} From 2cedf27323a977176d1e62581fe1df24e1d5270f Mon Sep 17 00:00:00 2001 From: Jonathan Neal Date: Mon, 17 Sep 2018 22:25:54 -0400 Subject: [PATCH 687/795] 2.0.0 --- .appveyor.yml | 18 ------ .gitignore | 3 +- .rollup.js | 6 +- CHANGELOG.md | 5 ++ INSTALL.md | 170 ++++++++++++++++++++++++++++++++++++++++++++++++++ README.md | 114 +++------------------------------ package.json | 22 ++++--- 7 files changed, 201 insertions(+), 137 deletions(-) delete mode 100644 .appveyor.yml create mode 100644 INSTALL.md diff --git a/.appveyor.yml b/.appveyor.yml deleted file mode 100644 index 73f0d8fa3f..0000000000 --- a/.appveyor.yml +++ /dev/null @@ -1,18 +0,0 @@ -# https://www.appveyor.com/docs/appveyor-yml - -environment: - matrix: - - nodejs_version: 6 - -version: "{build}" -build: off -deploy: off - -install: - - ps: Install-Product node $env:nodejs_version - - npm install --ignore-scripts - -test_script: - - node --version - - npm --version - - cmd: "npm test" diff --git a/.gitignore b/.gitignore index de73e5a338..d920b78fec 100644 --- a/.gitignore +++ b/.gitignore @@ -1,10 +1,9 @@ node_modules -index.*.js +index.*.* package-lock.json *.log* *.result.css .* -!.appveyor.yml !.editorconfig !.gitignore !.rollup.js diff --git a/.rollup.js b/.rollup.js index 0436758216..ebe39f9220 100644 --- a/.rollup.js +++ b/.rollup.js @@ -3,13 +3,13 @@ import babel from 'rollup-plugin-babel'; export default { input: 'index.js', output: [ - { file: 'index.cjs.js', format: 'cjs' }, - { file: 'index.es.js', format: 'es' } + { file: 'index.cjs.js', format: 'cjs', sourcemap: true }, + { file: 'index.es.mjs', format: 'es', sourcemap: true } ], plugins: [ babel({ presets: [ - ['env', { modules: false, targets: { node: 4 } }] + ['@babel/env', { modules: false, targets: { node: 6 } }] ] }) ] diff --git a/CHANGELOG.md b/CHANGELOG.md index a86db3dcdd..e94f937522 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,10 @@ # Changes to PostCSS Color Functional Notation +### 2.0.0 (September 17, 2018) + +- Updated: Support for PostCSS v7+ +- Updated: Support for Node 6+ + ### 1.0.2 (July 13, 2018) - Fixed: Poorly detected hsl() and rgb() now resolve correctly diff --git a/INSTALL.md b/INSTALL.md new file mode 100644 index 0000000000..c7d211eba6 --- /dev/null +++ b/INSTALL.md @@ -0,0 +1,170 @@ +# Installing PostCSS Color Functional Notation + +[PostCSS Color Functional Notation] runs in all Node environments, with special instructions for: + +| [Node](#node) | [PostCSS CLI](#postcss-cli) | [Webpack](#webpack) | [Create React App](#create-react-app) | [Gulp](#gulp) | [Grunt](#grunt) | +| --- | --- | --- | --- | --- | --- | + +## Node + +Add [PostCSS Color Functional Notation] to your project: + +```bash +npm install postcss-color-functional-notation --save-dev +``` + +Use [PostCSS Color Functional Notation] to process your CSS: + +```js +const postcssColorFunctionalNotation = require('postcss-color-functional-notation'); + +postcssColorFunctionalNotation.process(YOUR_CSS /*, processOptions, pluginOptions */); +``` + +Or use it as a [PostCSS] plugin: + +```js +const postcss = require('postcss'); +const postcssColorFunctionalNotation = require('postcss-color-functional-notation'); + +postcss([ + postcssColorFunctionalNotation(/* pluginOptions */) +]).process(YOUR_CSS /*, processOptions */); +``` + +## PostCSS CLI + +Add [PostCSS CLI] to your project: + +```bash +npm install postcss-cli --save-dev +``` + +Use [PostCSS Color Functional Notation] in your `postcss.config.js` configuration file: + +```js +const postcssColorFunctionalNotation = require('postcss-color-functional-notation'); + +module.exports = { + plugins: [ + postcssColorFunctionalNotation(/* pluginOptions */) + ] +} +``` + +## Webpack + +Add [PostCSS Loader] to your project: + +```bash +npm install postcss-loader --save-dev +``` + +Use [PostCSS Color Functional Notation] in your Webpack configuration: + +```js +const postcssColorFunctionalNotation = require('postcss-color-functional-notation'); + +module.exports = { + module: { + rules: [ + { + test: /\.css$/, + use: [ + 'style-loader', + { loader: 'css-loader', options: { importLoaders: 1 } }, + { loader: 'postcss-loader', options: { + ident: 'postcss', + plugins: () => [ + postcssColorFunctionalNotation(/* pluginOptions */) + ] + } } + ] + } + ] + } +} +``` + +## Create React App + +Add [React App Rewired] and [React App Rewire PostCSS] to your project: + +```bash +npm install react-app-rewired react-app-rewire-postcss --save-dev +``` + +Use [React App Rewire PostCSS] and [PostCSS Color Functional Notation] in your +`config-overrides.js` file: + +```js +const reactAppRewirePostcss = require('react-app-rewire-postcss'); +const postcssColorFunctionalNotation = require('postcss-color-functional-notation'); + +module.exports = config => reactAppRewirePostcss(config, { + plugins: () => [ + postcssColorFunctionalNotation(/* pluginOptions */) + ] +}); +``` + +## Gulp + +Add [Gulp PostCSS] to your project: + +```bash +npm install gulp-postcss --save-dev +``` + +Use [PostCSS Color Functional Notation] in your Gulpfile: + +```js +const postcss = require('gulp-postcss'); +const postcssColorFunctionalNotation = require('postcss-color-functional-notation'); + +gulp.task('css', () => gulp.src('./src/*.css').pipe( + postcss([ + postcssColorFunctionalNotation(/* pluginOptions */) + ]) +).pipe( + gulp.dest('.') +)); +``` + +## Grunt + +Add [Grunt PostCSS] to your project: + +```bash +npm install grunt-postcss --save-dev +``` + +Use [PostCSS Color Functional Notation] in your Gruntfile: + +```js +const postcssColorFunctionalNotation = require('postcss-color-functional-notation'); + +grunt.loadNpmTasks('grunt-postcss'); + +grunt.initConfig({ + postcss: { + options: { + use: [ + postcssColorFunctionalNotation(/* pluginOptions */) + ] + }, + dist: { + src: '*.css' + } + } +}); +``` + +[Gulp PostCSS]: https://github.com/postcss/gulp-postcss +[Grunt PostCSS]: https://github.com/nDmitry/grunt-postcss +[PostCSS]: https://github.com/postcss/postcss +[PostCSS CLI]: https://github.com/postcss/postcss-cli +[PostCSS Loader]: https://github.com/postcss/postcss-loader +[PostCSS Color Functional Notation]: https://github.com/jonathantneal/postcss-color-functional-notation +[React App Rewire PostCSS]: https://github.com/csstools/react-app-rewire-postcss +[React App Rewired]: https://github.com/timarney/react-app-rewired diff --git a/README.md b/README.md index 881e0ca8d6..597bf457f0 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,6 @@ [![NPM Version][npm-img]][npm-url] [![CSS Standard Status][css-img]][css-url] [![Build Status][cli-img]][cli-url] -[![Windows Build Status][win-img]][win-url] [![Support Chat][git-img]][git-url] [PostCSS Color Functional Notation] lets you use space and slash separated @@ -29,126 +28,35 @@ color notation in CSS, following the [CSS Color] specification. ## Usage -Add [PostCSS Color Functional Notation] to your build tool: +Add [PostCSS Color Functional Notation] to your project: ```bash npm install postcss-color-functional-notation --save-dev ``` -#### Node - Use [PostCSS Color Functional Notation] to process your CSS: ```js -import postcssColorFunctionalNotation from 'postcss-color-functional-notation'; - -postcssColorFunctionalNotation.process(YOUR_CSS, /* processOptions */, /* pluginOptions */); -``` - -#### PostCSS +const postcssColorFunctionalNotation = require('postcss-color-functional-notation'); -Add [PostCSS] to your build tool: - -```bash -npm install postcss --save-dev +postcssColorFunctionalNotation.process(YOUR_CSS /*, processOptions, pluginOptions */); ``` -Use [PostCSS Color Functional Notation] as a plugin: +Or use it as a [PostCSS] plugin: ```js -import postcss from 'gulp-postcss'; -import postcssColorFunctionalNotation from 'postcss-color-functional-notation'; +const postcss = require('postcss'); +const postcssColorFunctionalNotation = require('postcss-color-functional-notation'); postcss([ postcssColorFunctionalNotation(/* pluginOptions */) -]).process(YOUR_CSS); -``` - -#### Webpack - -Add [PostCSS Loader] to your build tool: - -```bash -npm install postcss-loader --save-dev -``` - -Use [PostCSS Color Functional Notation] in your Webpack configuration: - -```js -import postcssColorFunctionalNotation from 'postcss-color-functional-notation'; - -module.exports = { - module: { - rules: [ - { - test: /\.css$/, - use: [ - 'style-loader', - { loader: 'css-loader', options: { importLoaders: 1 } }, - { loader: 'postcss-loader', options: { - ident: 'postcss', - plugins: () => [ - postcssColorFunctionalNotation(/* pluginOptions */) - ] - } } - ] - } - ] - } -} +]).process(YOUR_CSS /*, processOptions */); ``` -#### Gulp +[PostCSS Color Functional Notation] runs in all Node environments, with special instructions for: -Add [Gulp PostCSS] to your build tool: - -```bash -npm install gulp-postcss --save-dev -``` - -Use [PostCSS Color Functional Notation] in your Gulpfile: - -```js -import postcss from 'gulp-postcss'; -import postcssColorFunctionalNotation from 'postcss-color-functional-notation'; - -gulp.task('css', () => gulp.src('./src/*.css').pipe( - postcss([ - postcssColorFunctionalNotation(/* pluginOptions */) - ]) -).pipe( - gulp.dest('.') -)); -``` - -#### Grunt - -Add [Grunt PostCSS] to your build tool: - -```bash -npm install grunt-postcss --save-dev -``` - -Use [PostCSS Color Functional Notation] in your Gruntfile: - -```js -import postcssColorFunctionalNotation from 'postcss-color-functional-notation'; - -grunt.loadNpmTasks('grunt-postcss'); - -grunt.initConfig({ - postcss: { - options: { - use: [ - postcssColorFunctionalNotation(/* pluginOptions */) - ] - }, - dist: { - src: '*.css' - } - } -}); -``` +| [Node](INSTALL.md#node) | [PostCSS CLI](INSTALL.md#postcss-cli) | [Webpack](INSTALL.md#webpack) | [Create React App](INSTALL.md#create-react-app) | [Gulp](INSTALL.md#gulp) | [Grunt](INSTALL.md#grunt) | +| --- | --- | --- | --- | --- | --- | ## Options @@ -191,8 +99,6 @@ postcssImageSetFunction({ preserve: true }) [git-url]: https://gitter.im/postcss/postcss [npm-img]: https://img.shields.io/npm/v/postcss-color-functional-notation.svg [npm-url]: https://www.npmjs.com/package/postcss-color-functional-notation -[win-img]: https://img.shields.io/appveyor/ci/jonathantneal/postcss-color-functional-notation.svg -[win-url]: https://ci.appveyor.com/project/jonathantneal/postcss-color-functional-notation [CSS Color]: https://drafts.csswg.org/css-color/#ref-for-funcdef-rgb%E2%91%A1%E2%91%A0 [Gulp PostCSS]: https://github.com/postcss/gulp-postcss diff --git a/package.json b/package.json index 7fe7c1cc0d..d2ed563e6b 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "postcss-color-functional-notation", - "version": "1.0.2", + "version": "2.0.0", "description": "Use space and slash separated color notation in CSS", "author": "Jonathan Neal ", "license": "CC0-1.0", @@ -8,10 +8,12 @@ "homepage": "https://github.com/jonathantneal/postcss-color-functional-notation#readme", "bugs": "https://github.com/jonathantneal/postcss-color-functional-notation/issues", "main": "index.cjs.js", - "module": "index.es.js", + "module": "index.es.mjs", "files": [ "index.cjs.js", - "index.es.js" + "index.cjs.js.map", + "index.es.mjs", + "index.es.mjs.map" ], "scripts": { "prepublishOnly": "npm test", @@ -22,22 +24,22 @@ "test:tape": "postcss-tape" }, "engines": { - "node": ">=4.0.0" + "node": ">=6.0.0" }, "dependencies": { "postcss": "^7.0.2", "postcss-values-parser": "^1.5.0" }, "devDependencies": { - "babel-core": "^6.26.3", - "babel-eslint": "^8.2.6", - "babel-preset-env": "^1.7.0", - "eslint": "^5.1.0", + "@babel/core": "^7.0.0", + "@babel/preset-env": "^7.0.0", + "babel-eslint": "^9.0.0", + "eslint": "^5.6.0", "eslint-config-dev": "^2.0.0", "postcss-tape": "^2.2.0", "pre-commit": "^1.2.2", - "rollup": "^0.62.0", - "rollup-plugin-babel": "^3.0.7" + "rollup": "^0.66.0", + "rollup-plugin-babel": "^4.0.1" }, "eslintConfig": { "extends": "dev", From cbe9486f3bac5670bc5948cdb4b27b70b76cdc92 Mon Sep 17 00:00:00 2001 From: Jonathan Neal Date: Mon, 17 Sep 2018 22:38:20 -0400 Subject: [PATCH 688/795] 4.0.0 --- .eslintrc.yml | 2 +- .travis.yml | 11 +- CHANGELOG.md | 8 +- README.md | 4 +- index.js | 31 +- package-lock.json | 1003 ++++++++++++++++----------------------------- package.json | 8 +- 7 files changed, 399 insertions(+), 668 deletions(-) diff --git a/.eslintrc.yml b/.eslintrc.yml index 40483cca86..1f8f8e652b 100644 --- a/.eslintrc.yml +++ b/.eslintrc.yml @@ -2,7 +2,7 @@ root: true extends: eslint:recommended parserOptions: - ecmaVersion: 5 + ecmaVersion: 6 env: commonjs: true diff --git a/.travis.yml b/.travis.yml index ca92cebc21..e1f11a52e6 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,6 +1,9 @@ -sudo: false +# https://docs.travis-ci.com/user/travis-lint + language: node_js + node_js: - - "6" - - "8" - - "stable" + - 6 + +install: + - npm install --ignore-scripts diff --git a/CHANGELOG.md b/CHANGELOG.md index 7fa75320d7..978a1faa97 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,7 +1,13 @@ +# 4.0.0 - 2017-09-17 + +- Updated: Support for PostCSS v7+ +- Updated: Support for Node v6+ +- Updated: color v3+ + # 3.0.0 - 2017-05-15 - Added: compatibility with postcss v6.x -- Uodated dependencies +- Updated dependencies # 2.0.0 - 2015-09-08 diff --git a/README.md b/README.md index d77a85564f..21511b3aef 100755 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ -# postcss-color-hex-alpha [![CSS Standard Status](https://jonathantneal.github.io/css-db/badge/css-color-hex-notation.svg)](https://jonathantneal.github.io/css-db/#css-color-hex-notation) [![Build Status](https://travis-ci.org/postcss/postcss-color-hex-alpha.png)](https://travis-ci.org/postcss/postcss-color-hex-alpha) +# postcss-color-hex-alpha [![CSS Standard Status](https://cssdb.org/badge/hexadecimal-alpha-notation.svg)](https://cssdb.org/#hexadecimal-alpha-notation) [![Build Status](https://api.travis-ci.org/postcss/postcss-color-hex-alpha.svg)](https://travis-ci.org/postcss/postcss-color-hex-alpha) -> [PostCSS](https://github.com/postcss/postcss) plugin to transform [W3C RGBA hexadecimal notations (#RRGGBBAA or #RGBA)](http://dev.w3.org/csswg/css-color/#hex-notation) to more compatible CSS (rgba()). +> [PostCSS](https://github.com/postcss/postcss) plugin to transform [W3C RGBA hexadecimal notations (#RRGGBBAA or #RGBA)](https://www.w3.org/TR/css-color-4/#hex-notation) to more compatible CSS (rgba()). ## Installation diff --git a/index.js b/index.js index dee51a4dac..ad7f25432b 100755 --- a/index.js +++ b/index.js @@ -1,15 +1,15 @@ /** * Module dependencies. */ -var postcss = require("postcss") -var helpers = require("postcss-message-helpers") -var color = require("color") +const postcss = require("postcss") +const helpers = require("postcss-message-helpers") +const color = require("color") /** * Constantes */ -var HEX_ALPHA_RE = /#([0-9a-f]{4}(?:[0-9a-f]{4})?)\b/i -var DECIMAL_PRECISION = 100000 // 5 decimals +const HEX_ALPHA_RE = /#([0-9a-f]{4}(?:[0-9a-f]{4})?)\b/i +const DECIMAL_PRECISION = 100000 // 5 decimals /** * PostCSS plugin to transform hexa alpha colors @@ -35,12 +35,13 @@ module.exports = postcss.plugin("postcss-color-hex-alpha", function() { * @return {String} converted declaration value to rgba() */ function transformHexAlpha(string) { - var m = HEX_ALPHA_RE.exec(string) + const m = HEX_ALPHA_RE.exec(string) + if (!m) { return string } - var hex = m[1] + const hex = m[1] return string.slice(0, m.index) + hexaToRgba(hex) + @@ -60,19 +61,19 @@ function hexaToRgba(hex) { // hex += "f" // } if (hex.length === 4) { - var h0 = hex.charAt(0) - var h1 = hex.charAt(1) - var h2 = hex.charAt(2) - var h3 = hex.charAt(3) + const h0 = hex.charAt(0) + const h1 = hex.charAt(1) + const h2 = hex.charAt(2) + const h3 = hex.charAt(3) hex = h0 + h0 + h1 + h1 + h2 + h2 + h3 + h3 } // if (hex.length === 6) { // hex += "ff" // } - var rgb = [] - for (var i = 0, l = hex.length; i < l; i += 2) { - var isAlpha = i === 6 - var value = parseInt(hex.substr(i, 2), 16) / (isAlpha ? 255 : 1) + const rgb = [] + for (let i = 0, l = hex.length; i < l; i += 2) { + const isAlpha = i === 6 + const value = parseInt(hex.substr(i, 2), 16) / (isAlpha ? 255 : 1) rgb.push(Math.round(value * DECIMAL_PRECISION) / DECIMAL_PRECISION) } diff --git a/package-lock.json b/package-lock.json index eab4b36507..929d23b481 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,58 +1,72 @@ { "name": "postcss-color-hex-alpha", - "version": "3.0.0", + "version": "4.0.0", "lockfileVersion": 1, "requires": true, "dependencies": { + "@babel/code-frame": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.0.0.tgz", + "integrity": "sha512-OfC2uemaknXr87bdLUkWog7nYuliM9Ij5HUcajsVcMCpQrcLmtxRbVFTIqmcSkSeYRBFBRxs2FiUqFJDLdiebA==", + "dev": true, + "requires": { + "@babel/highlight": "^7.0.0" + } + }, + "@babel/highlight": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.0.0.tgz", + "integrity": "sha512-UFMC4ZeFC48Tpvj7C8UgLvtkaUuovQX+5xNWrsIoMG8o2z+XFKjKaN9iVmS84dPwVN00W4wPmqvYoZF3EGAsfw==", + "dev": true, + "requires": { + "chalk": "^2.0.0", + "esutils": "^2.0.2", + "js-tokens": "^4.0.0" + } + }, "acorn": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-5.7.1.tgz", - "integrity": "sha512-d+nbxBUGKg7Arpsvbnlq61mc12ek3EY8EQldM3GPAhWJ1UVxC6TDGbIvUMNU6obBX3i1+ptCIzV4vq0gFPEGVQ==", + "version": "5.7.3", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-5.7.3.tgz", + "integrity": "sha512-T/zvzYRfbVojPWahDsE5evJdHb3oJoQfFbsrKM7w5Zcs++Tr257tia3BmMP8XYVjp1S9RZXQMh7gao96BlqZOw==", "dev": true }, "acorn-jsx": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-3.0.1.tgz", - "integrity": "sha1-r9+UiPsezvyDSPb7IvRk4ypYs2s=", + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-4.1.1.tgz", + "integrity": "sha512-JY+iV6r+cO21KtntVvFkD+iqjtdpRUpGqKWgfkCdZq1R+kbreEl8EcdcJR4SmiIgsIQT33s6QzheQ9a275Q8xw==", "dev": true, "requires": { - "acorn": "^3.0.4" - }, - "dependencies": { - "acorn": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-3.3.0.tgz", - "integrity": "sha1-ReN/s56No/JbruP/U2niu18iAXo=", - "dev": true - } + "acorn": "^5.0.3" } }, "ajv": { - "version": "4.11.8", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-4.11.8.tgz", - "integrity": "sha1-gv+wKynmYq5TvcIK8VlHcGc5xTY=", + "version": "6.5.3", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.5.3.tgz", + "integrity": "sha512-LqZ9wY+fx3UMiiPd741yB2pj3hhil+hQc8taf4o2QGRFpWgZ2V5C8HA165DY9sS3fJwsk7uT7ZlFEyC3Ig3lLg==", "dev": true, "requires": { - "co": "^4.6.0", - "json-stable-stringify": "^1.0.1" + "fast-deep-equal": "^2.0.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" } }, "ajv-keywords": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-1.5.1.tgz", - "integrity": "sha1-MU3QpLM2j609/NxU7eYXG4htrzw=", + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.2.0.tgz", + "integrity": "sha1-6GuBnGAs+IIa1jdBNpjx3sAhhHo=", "dev": true }, "ansi-escapes": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-1.4.0.tgz", - "integrity": "sha1-06ioOzGapneTZisT52HHkRQiMG4=", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-3.1.0.tgz", + "integrity": "sha512-UgAb8H9D41AQnu/PbWlCofQVcnV4Gs2bBJi9eZPxfU/hgglFh3SMDMENRIqdr7H6XFnXdoknctFByVsCOotTVw==", "dev": true }, "ansi-regex": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", + "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", "dev": true }, "ansi-styles": { @@ -93,44 +107,6 @@ "integrity": "sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=", "dev": true }, - "babel-code-frame": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-code-frame/-/babel-code-frame-6.26.0.tgz", - "integrity": "sha1-Y/1D99weO7fONZR9uP42mj9Yx0s=", - "dev": true, - "requires": { - "chalk": "^1.1.3", - "esutils": "^2.0.2", - "js-tokens": "^3.0.2" - }, - "dependencies": { - "ansi-styles": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", - "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", - "dev": true - }, - "chalk": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", - "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", - "dev": true, - "requires": { - "ansi-styles": "^2.2.1", - "escape-string-regexp": "^1.0.2", - "has-ansi": "^2.0.0", - "strip-ansi": "^3.0.0", - "supports-color": "^2.0.0" - } - }, - "supports-color": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", - "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", - "dev": true - } - } - }, "balanced-match": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", @@ -147,12 +123,6 @@ "concat-map": "0.0.1" } }, - "buffer-from": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", - "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==", - "dev": true - }, "caller-path": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/caller-path/-/caller-path-0.1.0.tgz", @@ -178,6 +148,12 @@ "supports-color": "^5.3.0" } }, + "chardet": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.7.0.tgz", + "integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==", + "dev": true + }, "circular-json": { "version": "0.3.3", "resolved": "https://registry.npmjs.org/circular-json/-/circular-json-0.3.3.tgz", @@ -185,12 +161,12 @@ "dev": true }, "cli-cursor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-1.0.2.tgz", - "integrity": "sha1-ZNo/fValRBLll5S9Ytw1KV6PKYc=", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-2.1.0.tgz", + "integrity": "sha1-s12sN2R5+sw+lHR9QdDQ9SOP/LU=", "dev": true, "requires": { - "restore-cursor": "^1.0.1" + "restore-cursor": "^2.0.0" } }, "cli-width": { @@ -199,25 +175,13 @@ "integrity": "sha1-/xnt6Kml5XkyQUewwR8PvLq+1jk=", "dev": true }, - "co": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", - "integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ=", - "dev": true - }, - "code-point-at": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", - "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=", - "dev": true - }, "color": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/color/-/color-1.0.3.tgz", - "integrity": "sha1-5I6DLYXxTvaU+0aIEcLVz+cptV0=", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/color/-/color-3.0.0.tgz", + "integrity": "sha512-jCpd5+s0s0t7p3pHQKpnJ0TpQKKdleP71LWcA0aqiljpiuAkOSUFN/dyH8ZwF0hRmFlrIuRhufds1QyEP9EB+w==", "requires": { - "color-convert": "^1.8.2", - "color-string": "^1.4.0" + "color-convert": "^1.9.1", + "color-string": "^1.5.2" } }, "color-convert": { @@ -248,40 +212,26 @@ "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", "dev": true }, - "concat-stream": { - "version": "1.6.2", - "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz", - "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==", + "cross-spawn": { + "version": "6.0.5", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", + "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", "dev": true, "requires": { - "buffer-from": "^1.0.0", - "inherits": "^2.0.3", - "readable-stream": "^2.2.2", - "typedarray": "^0.0.6" - } - }, - "core-util-is": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", - "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=", - "dev": true - }, - "d": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/d/-/d-1.0.0.tgz", - "integrity": "sha1-dUu1v+VUUdpppYuU1F9MWwRi1Y8=", - "dev": true, - "requires": { - "es5-ext": "^0.10.9" + "nice-try": "^1.0.4", + "path-key": "^2.0.1", + "semver": "^5.5.0", + "shebang-command": "^1.2.0", + "which": "^1.2.9" } }, "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "version": "3.2.5", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.5.tgz", + "integrity": "sha512-D61LaDQPQkxJ5AUM2mbSJRbPkNs/TmdmOeLAi1hgDkpDfIfetSrjmWhccwtuResSwMbACjx/xXQofvM9CE/aeg==", "dev": true, "requires": { - "ms": "2.0.0" + "ms": "^2.1.1" } }, "deep-equal": { @@ -360,172 +310,87 @@ "is-symbol": "^1.0.1" } }, - "es5-ext": { - "version": "0.10.45", - "resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.45.tgz", - "integrity": "sha512-FkfM6Vxxfmztilbxxz5UKSD4ICMf5tSpRFtDNtkAhOxZ0EKtX6qwmXNyH/sFyIbX2P/nU5AMiA9jilWsUGJzCQ==", - "dev": true, - "requires": { - "es6-iterator": "~2.0.3", - "es6-symbol": "~3.1.1", - "next-tick": "1" - } - }, - "es6-iterator": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/es6-iterator/-/es6-iterator-2.0.3.tgz", - "integrity": "sha1-p96IkUGgWpSwhUQDstCg+/qY87c=", - "dev": true, - "requires": { - "d": "1", - "es5-ext": "^0.10.35", - "es6-symbol": "^3.1.1" - } - }, - "es6-map": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/es6-map/-/es6-map-0.1.5.tgz", - "integrity": "sha1-kTbgUD3MBqMBaQ8LsU/042TpSfA=", - "dev": true, - "requires": { - "d": "1", - "es5-ext": "~0.10.14", - "es6-iterator": "~2.0.1", - "es6-set": "~0.1.5", - "es6-symbol": "~3.1.1", - "event-emitter": "~0.3.5" - } - }, - "es6-set": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/es6-set/-/es6-set-0.1.5.tgz", - "integrity": "sha1-0rPsXU2ADO2BjbU40ol02wpzzLE=", - "dev": true, - "requires": { - "d": "1", - "es5-ext": "~0.10.14", - "es6-iterator": "~2.0.1", - "es6-symbol": "3.1.1", - "event-emitter": "~0.3.5" - } - }, - "es6-symbol": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/es6-symbol/-/es6-symbol-3.1.1.tgz", - "integrity": "sha1-vwDvT9q2uhtG7Le2KbTH7VcVzHc=", - "dev": true, - "requires": { - "d": "1", - "es5-ext": "~0.10.14" - } - }, - "es6-weak-map": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/es6-weak-map/-/es6-weak-map-2.0.2.tgz", - "integrity": "sha1-XjqzIlH/0VOKH45f+hNXdy+S2W8=", - "dev": true, - "requires": { - "d": "1", - "es5-ext": "^0.10.14", - "es6-iterator": "^2.0.1", - "es6-symbol": "^3.1.1" - } - }, "escape-string-regexp": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=" }, - "escope": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/escope/-/escope-3.6.0.tgz", - "integrity": "sha1-4Bl16BJ4GhY6ba392AOY3GTIicM=", - "dev": true, - "requires": { - "es6-map": "^0.1.3", - "es6-weak-map": "^2.0.1", - "esrecurse": "^4.1.0", - "estraverse": "^4.1.1" - } - }, "eslint": { - "version": "3.19.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-3.19.0.tgz", - "integrity": "sha1-yPxiAcf0DdCJQbh8CFdnOGpnmsw=", - "dev": true, - "requires": { - "babel-code-frame": "^6.16.0", - "chalk": "^1.1.3", - "concat-stream": "^1.5.2", - "debug": "^2.1.1", - "doctrine": "^2.0.0", - "escope": "^3.6.0", - "espree": "^3.4.0", - "esquery": "^1.0.0", - "estraverse": "^4.2.0", + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-5.6.0.tgz", + "integrity": "sha512-/eVYs9VVVboX286mBK7bbKnO1yamUy2UCRjiY6MryhQL2PaaXCExsCQ2aO83OeYRhU2eCU/FMFP+tVMoOrzNrA==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.0.0", + "ajv": "^6.5.3", + "chalk": "^2.1.0", + "cross-spawn": "^6.0.5", + "debug": "^3.1.0", + "doctrine": "^2.1.0", + "eslint-scope": "^4.0.0", + "eslint-utils": "^1.3.1", + "eslint-visitor-keys": "^1.0.0", + "espree": "^4.0.0", + "esquery": "^1.0.1", "esutils": "^2.0.2", "file-entry-cache": "^2.0.0", - "glob": "^7.0.3", - "globals": "^9.14.0", - "ignore": "^3.2.0", + "functional-red-black-tree": "^1.0.1", + "glob": "^7.1.2", + "globals": "^11.7.0", + "ignore": "^4.0.6", "imurmurhash": "^0.1.4", - "inquirer": "^0.12.0", - "is-my-json-valid": "^2.10.0", - "is-resolvable": "^1.0.0", - "js-yaml": "^3.5.1", - "json-stable-stringify": "^1.0.0", + "inquirer": "^6.1.0", + "is-resolvable": "^1.1.0", + "js-yaml": "^3.12.0", + "json-stable-stringify-without-jsonify": "^1.0.1", "levn": "^0.3.0", - "lodash": "^4.0.0", - "mkdirp": "^0.5.0", + "lodash": "^4.17.5", + "minimatch": "^3.0.4", + "mkdirp": "^0.5.1", "natural-compare": "^1.4.0", "optionator": "^0.8.2", - "path-is-inside": "^1.0.1", - "pluralize": "^1.2.1", - "progress": "^1.1.8", - "require-uncached": "^1.0.2", - "shelljs": "^0.7.5", - "strip-bom": "^3.0.0", - "strip-json-comments": "~2.0.1", - "table": "^3.7.8", - "text-table": "~0.2.0", - "user-home": "^2.0.0" - }, - "dependencies": { - "ansi-styles": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", - "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", - "dev": true - }, - "chalk": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", - "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", - "dev": true, - "requires": { - "ansi-styles": "^2.2.1", - "escape-string-regexp": "^1.0.2", - "has-ansi": "^2.0.0", - "strip-ansi": "^3.0.0", - "supports-color": "^2.0.0" - } - }, - "supports-color": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", - "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", - "dev": true - } + "path-is-inside": "^1.0.2", + "pluralize": "^7.0.0", + "progress": "^2.0.0", + "regexpp": "^2.0.0", + "require-uncached": "^1.0.3", + "semver": "^5.5.1", + "strip-ansi": "^4.0.0", + "strip-json-comments": "^2.0.1", + "table": "^4.0.3", + "text-table": "^0.2.0" } }, + "eslint-scope": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-4.0.0.tgz", + "integrity": "sha512-1G6UTDi7Jc1ELFwnR58HV4fK9OQK4S6N985f166xqXxpjU6plxFISJa2Ba9KCQuFa8RCnj/lSFJbHo7UFDBnUA==", + "dev": true, + "requires": { + "esrecurse": "^4.1.0", + "estraverse": "^4.1.1" + } + }, + "eslint-utils": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-1.3.1.tgz", + "integrity": "sha512-Z7YjnIldX+2XMcjr7ZkgEsOj/bREONV60qYeB/bjMAqqqZ4zxKyWX+BOUkdmRmA9riiIPVvo5x86m5elviOk0Q==", + "dev": true + }, + "eslint-visitor-keys": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.0.0.tgz", + "integrity": "sha512-qzm/XxIbxm/FHyH341ZrbnMUpe+5Bocte9xkmFMzPMjRaZMcXww+MpBptFvtU+79L362nqiLhekCxCxDPaUMBQ==", + "dev": true + }, "espree": { - "version": "3.5.4", - "resolved": "https://registry.npmjs.org/espree/-/espree-3.5.4.tgz", - "integrity": "sha512-yAcIQxtmMiB/jL32dzEp2enBeidsB7xWPLNiw3IIkpVds1P+h7qF9YwJq1yUNzp2OKXgAprs4F61ih66UsoD1A==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/espree/-/espree-4.0.0.tgz", + "integrity": "sha512-kapdTCt1bjmspxStVKX6huolXVV5ZfyZguY1lcfhVVZstce3bqxH9mcLzNn3/mlgW6wQ732+0fuG9v7h0ZQoKg==", "dev": true, "requires": { - "acorn": "^5.5.0", - "acorn-jsx": "^3.0.0" + "acorn": "^5.6.0", + "acorn-jsx": "^4.1.1" } }, "esprima": { @@ -564,20 +429,27 @@ "integrity": "sha1-Cr9PHKpbyx96nYrMbepPqqBLrJs=", "dev": true }, - "event-emitter": { - "version": "0.3.5", - "resolved": "https://registry.npmjs.org/event-emitter/-/event-emitter-0.3.5.tgz", - "integrity": "sha1-34xp7vFkeSPHFXuc6DhAYQsCzDk=", + "external-editor": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-3.0.3.tgz", + "integrity": "sha512-bn71H9+qWoOQKyZDo25mOMVpSmXROAsTJVVVYzrrtol3d4y+AsKjf4Iwl2Q+IuT0kFSQ1qo166UuIwqYq7mGnA==", "dev": true, "requires": { - "d": "1", - "es5-ext": "~0.10.14" + "chardet": "^0.7.0", + "iconv-lite": "^0.4.24", + "tmp": "^0.0.33" } }, - "exit-hook": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/exit-hook/-/exit-hook-1.1.1.tgz", - "integrity": "sha1-8FyiM7SMBdVP/wd2XfhQfpXAL/g=", + "fast-deep-equal": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz", + "integrity": "sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk=", + "dev": true + }, + "fast-json-stable-stringify": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz", + "integrity": "sha1-1RQsDK7msRifh9OnYREGT4bIu/I=", "dev": true }, "fast-levenshtein": { @@ -587,13 +459,12 @@ "dev": true }, "figures": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/figures/-/figures-1.7.0.tgz", - "integrity": "sha1-y+Hjr/zxzUS4DK3+0o3Hk6lwHS4=", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/figures/-/figures-2.0.0.tgz", + "integrity": "sha1-OrGi0qYsi/tDGgyUy3l6L84nyWI=", "dev": true, "requires": { - "escape-string-regexp": "^1.0.5", - "object-assign": "^4.1.0" + "escape-string-regexp": "^1.0.5" } }, "file-entry-cache": { @@ -645,21 +516,12 @@ "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", "dev": true }, - "generate-function": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/generate-function/-/generate-function-2.0.0.tgz", - "integrity": "sha1-aFj+fAlpt9TpCTM3ZHrHn2DfvnQ=", + "functional-red-black-tree": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", + "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=", "dev": true }, - "generate-object-property": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/generate-object-property/-/generate-object-property-1.2.0.tgz", - "integrity": "sha1-nA4cQDCM6AT0eDYYuTf6iPmdUNA=", - "dev": true, - "requires": { - "is-property": "^1.0.0" - } - }, "glob": { "version": "7.1.2", "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz", @@ -675,9 +537,9 @@ } }, "globals": { - "version": "9.18.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-9.18.0.tgz", - "integrity": "sha512-S0nG3CLEQiY/ILxqtztTWH/3iRRdyBLw6KMDxnKMchrtbj2OFmehVh0WUCfW3DUrIgx/qFrJPICrq4Z4sTR9UQ==", + "version": "11.7.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-11.7.0.tgz", + "integrity": "sha512-K8BNSPySfeShBQXsahYB/AbbWruVOTyVpgoIDnl8odPpeSfP2J5QO2oLFFdl2j7GfDCtZj2bMKar2T49itTPCg==", "dev": true }, "globby": { @@ -709,24 +571,24 @@ "function-bind": "^1.1.1" } }, - "has-ansi": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", - "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=", - "dev": true, - "requires": { - "ansi-regex": "^2.0.0" - } - }, "has-flag": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=" }, + "iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "dev": true, + "requires": { + "safer-buffer": ">= 2.1.2 < 3" + } + }, "ignore": { - "version": "3.3.10", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-3.3.10.tgz", - "integrity": "sha512-Pgs951kaMm5GXP7MOvxERINe3gsaVjUWFm+UZPSq9xYriQAksyhg0csnS0KXSNRD5NmNdapXEpjxG49+AKh/ug==", + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", + "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", "dev": true }, "imurmurhash": { @@ -752,59 +614,26 @@ "dev": true }, "inquirer": { - "version": "0.12.0", - "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-0.12.0.tgz", - "integrity": "sha1-HvK/1jUE3wvHV4X/+MLEHfEvB34=", + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-6.2.0.tgz", + "integrity": "sha512-QIEQG4YyQ2UYZGDC4srMZ7BjHOmNk1lR2JQj5UknBapklm6WHA+VVH7N+sUdX3A7NeCfGF8o4X1S3Ao7nAcIeg==", "dev": true, "requires": { - "ansi-escapes": "^1.1.0", - "ansi-regex": "^2.0.0", - "chalk": "^1.0.0", - "cli-cursor": "^1.0.1", + "ansi-escapes": "^3.0.0", + "chalk": "^2.0.0", + "cli-cursor": "^2.1.0", "cli-width": "^2.0.0", - "figures": "^1.3.5", - "lodash": "^4.3.0", - "readline2": "^1.0.1", - "run-async": "^0.1.0", - "rx-lite": "^3.1.2", - "string-width": "^1.0.1", - "strip-ansi": "^3.0.0", + "external-editor": "^3.0.0", + "figures": "^2.0.0", + "lodash": "^4.17.10", + "mute-stream": "0.0.7", + "run-async": "^2.2.0", + "rxjs": "^6.1.0", + "string-width": "^2.1.0", + "strip-ansi": "^4.0.0", "through": "^2.3.6" - }, - "dependencies": { - "ansi-styles": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", - "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", - "dev": true - }, - "chalk": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", - "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", - "dev": true, - "requires": { - "ansi-styles": "^2.2.1", - "escape-string-regexp": "^1.0.2", - "has-ansi": "^2.0.0", - "strip-ansi": "^3.0.0", - "supports-color": "^2.0.0" - } - }, - "supports-color": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", - "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", - "dev": true - } } }, - "interpret": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.1.0.tgz", - "integrity": "sha1-ftGxQQxqDg94z5XTuEQMY/eLhhQ=", - "dev": true - }, "is-arrayish": { "version": "0.3.2", "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.3.2.tgz", @@ -823,33 +652,11 @@ "dev": true }, "is-fullwidth-code-point": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", - "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", - "dev": true, - "requires": { - "number-is-nan": "^1.0.0" - } - }, - "is-my-ip-valid": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-my-ip-valid/-/is-my-ip-valid-1.0.0.tgz", - "integrity": "sha512-gmh/eWXROncUzRnIa1Ubrt5b8ep/MGSnfAUI3aRp+sqTCs1tv1Isl8d8F6JmkN3dXKc3ehZMrtiPN9eL03NuaQ==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", "dev": true }, - "is-my-json-valid": { - "version": "2.18.0", - "resolved": "https://registry.npmjs.org/is-my-json-valid/-/is-my-json-valid-2.18.0.tgz", - "integrity": "sha512-DWT87JHCSdCPCxbqBpS6Z2ajAt+MvrJq8I4xrpQljCvzODO5/fiquBp20a3sN6yCJvFbCRyYvJOHjpzkPTKJyA==", - "dev": true, - "requires": { - "generate-function": "^2.0.0", - "generate-object-property": "^1.1.0", - "is-my-ip-valid": "^1.0.0", - "jsonpointer": "^4.0.0", - "xtend": "^4.0.0" - } - }, "is-path-cwd": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-path-cwd/-/is-path-cwd-1.0.0.tgz", @@ -874,10 +681,10 @@ "path-is-inside": "^1.0.1" } }, - "is-property": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-property/-/is-property-1.0.2.tgz", - "integrity": "sha1-V/4cTkhHTt1lsJkR8msc1Ald2oQ=", + "is-promise": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-2.1.0.tgz", + "integrity": "sha1-eaKp7OfwlugPNtKy87wWwf9L8/o=", "dev": true }, "is-regex": { @@ -901,16 +708,16 @@ "integrity": "sha1-PMWfAAJRlLarLjjbrmaJJWtmBXI=", "dev": true }, - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", + "isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", "dev": true }, "js-tokens": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-3.0.2.tgz", - "integrity": "sha1-mGbfOVECEw449/mWvOtlRDIJwls=", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", "dev": true }, "js-yaml": { @@ -923,25 +730,16 @@ "esprima": "^4.0.0" } }, - "json-stable-stringify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json-stable-stringify/-/json-stable-stringify-1.0.1.tgz", - "integrity": "sha1-mnWdOcXy/1A/1TAGRu1EX4jE+a8=", - "dev": true, - "requires": { - "jsonify": "~0.0.0" - } - }, - "jsonify": { - "version": "0.0.0", - "resolved": "https://registry.npmjs.org/jsonify/-/jsonify-0.0.0.tgz", - "integrity": "sha1-LHS27kHZPKUbe1qu6PUDYx0lKnM=", + "json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", "dev": true }, - "jsonpointer": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/jsonpointer/-/jsonpointer-4.0.1.tgz", - "integrity": "sha1-T9kss04OnbPInIYi7PUfm5eMbLk=", + "json-stable-stringify-without-jsonify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", + "integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=", "dev": true }, "levn": { @@ -955,9 +753,15 @@ } }, "lodash": { - "version": "4.17.10", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.10.tgz", - "integrity": "sha512-UejweD1pDoXu+AD825lWwp4ZGtSwgnpZxb3JDViD7StjQz+Nb/6l093lx4OQ0foGWNRoc19mWy7BzL+UAK2iVg==", + "version": "4.17.11", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.11.tgz", + "integrity": "sha512-cQKh8igo5QUhZ7lg38DYWAxMvjSAKG0A8wGSVimP07SIUEK2UO+arSRKbRZWtelMtN5V0Hkwh5ryOto/SshYIg==", + "dev": true + }, + "mimic-fn": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-1.2.0.tgz", + "integrity": "sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ==", "dev": true }, "minimatch": { @@ -971,13 +775,13 @@ }, "minimist": { "version": "0.0.8", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", + "resolved": "http://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=", "dev": true }, "mkdirp": { "version": "0.5.1", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", + "resolved": "http://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", "dev": true, "requires": { @@ -985,15 +789,15 @@ } }, "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", + "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==", "dev": true }, "mute-stream": { - "version": "0.0.5", - "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.5.tgz", - "integrity": "sha1-j7+rsKmKJT0xhDMfno3rc3L6xsA=", + "version": "0.0.7", + "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.7.tgz", + "integrity": "sha1-MHXOk7whuPq0PhvE2n6BFe0ee6s=", "dev": true }, "natural-compare": { @@ -1002,16 +806,10 @@ "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=", "dev": true }, - "next-tick": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/next-tick/-/next-tick-1.0.0.tgz", - "integrity": "sha1-yobR/ogoFpsBICCOPchCS524NCw=", - "dev": true - }, - "number-is-nan": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", - "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=", + "nice-try": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", + "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==", "dev": true }, "object-assign": { @@ -1042,10 +840,13 @@ } }, "onetime": { - "version": "1.1.0", - "resolved": "http://registry.npmjs.org/onetime/-/onetime-1.1.0.tgz", - "integrity": "sha1-ofeDj4MUxRbwXs78vEzP4EtO14k=", - "dev": true + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-2.0.1.tgz", + "integrity": "sha1-BnQoIw/WdEOyeUsiu6UotoZ5YtQ=", + "dev": true, + "requires": { + "mimic-fn": "^1.0.0" + } }, "optionator": { "version": "0.8.2", @@ -1061,10 +862,10 @@ "wordwrap": "~1.0.0" } }, - "os-homedir": { + "os-tmpdir": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz", - "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=", + "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", + "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=", "dev": true }, "path-is-absolute": { @@ -1079,6 +880,12 @@ "integrity": "sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM=", "dev": true }, + "path-key": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", + "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=", + "dev": true + }, "path-parse": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz", @@ -1107,9 +914,9 @@ } }, "pluralize": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/pluralize/-/pluralize-1.2.1.tgz", - "integrity": "sha1-0aIUg/0iu0HlihL6NCGCMUCJfEU=", + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/pluralize/-/pluralize-7.0.0.tgz", + "integrity": "sha512-ARhBOdzS3e41FbkW/XWrTEtukqqLoK5+Z/4UeDaLuSW+39JPeFgs4gCGqsrJHVZX0fUrx//4OF0K1CUGwlIFow==", "dev": true }, "postcss": { @@ -1133,52 +940,23 @@ "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=", "dev": true }, - "process-nextick-args": { + "progress": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.0.tgz", - "integrity": "sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw==", + "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.0.tgz", + "integrity": "sha1-ihvjZr+Pwj2yvSPxDG/pILQ4nR8=", "dev": true }, - "progress": { - "version": "1.1.8", - "resolved": "https://registry.npmjs.org/progress/-/progress-1.1.8.tgz", - "integrity": "sha1-4mDHj2Fhzdmw5WzD4Khd4Xx6V74=", + "punycode": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", + "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", "dev": true }, - "readable-stream": { - "version": "2.3.6", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", - "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "readline2": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/readline2/-/readline2-1.0.1.tgz", - "integrity": "sha1-QQWWCP/BVHV7cV2ZidGZ/783LjU=", - "dev": true, - "requires": { - "code-point-at": "^1.0.0", - "is-fullwidth-code-point": "^1.0.0", - "mute-stream": "0.0.5" - } - }, - "rechoir": { - "version": "0.6.2", - "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.6.2.tgz", - "integrity": "sha1-hSBLVNuoLVdC4oyWdW70OvUOM4Q=", - "dev": true, - "requires": { - "resolve": "^1.1.6" - } + "regexpp": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-2.0.0.tgz", + "integrity": "sha512-g2FAVtR8Uh8GO1Nv5wpxW7VFVwHcCEr4wyA8/MHiRkO8uHoR5ntAA8Uq3P1vvMTX/BeQiRVSpDGLd+Wn5HNOTA==", + "dev": true }, "require-uncached": { "version": "1.0.3", @@ -1190,15 +968,6 @@ "resolve-from": "^1.0.0" } }, - "resolve": { - "version": "1.8.1", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.8.1.tgz", - "integrity": "sha512-AicPrAC7Qu1JxPCZ9ZgCZlY35QgFnNqc+0LtbRNxnVw4TXvjQ72wnuL9JQcEBgXkI9JM8MsT9kaQoHcpCRJOYA==", - "dev": true, - "requires": { - "path-parse": "^1.0.5" - } - }, "resolve-from": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-1.0.1.tgz", @@ -1206,13 +975,13 @@ "dev": true }, "restore-cursor": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-1.0.1.tgz", - "integrity": "sha1-NGYfRohjJ/7SmRR5FSJS35LapUE=", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-2.0.0.tgz", + "integrity": "sha1-n37ih/gv0ybU/RYpI9YhKe7g368=", "dev": true, "requires": { - "exit-hook": "^1.0.0", - "onetime": "^1.0.0" + "onetime": "^2.0.0", + "signal-exit": "^3.0.2" } }, "resumer": { @@ -1234,37 +1003,56 @@ } }, "run-async": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/run-async/-/run-async-0.1.0.tgz", - "integrity": "sha1-yK1KXhEGYeQCp9IbUw4AnyX444k=", + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.3.0.tgz", + "integrity": "sha1-A3GrSuC91yDUFm19/aZP96RFpsA=", + "dev": true, + "requires": { + "is-promise": "^2.1.0" + } + }, + "rxjs": { + "version": "6.3.2", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.3.2.tgz", + "integrity": "sha512-hV7criqbR0pe7EeL3O66UYVg92IR0XsA97+9y+BWTePK9SKmEI5Qd3Zj6uPnGkNzXsBywBQWTvujPl+1Kn9Zjw==", "dev": true, "requires": { - "once": "^1.3.0" + "tslib": "^1.9.0" } }, - "rx-lite": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/rx-lite/-/rx-lite-3.1.2.tgz", - "integrity": "sha1-Gc5QLKVyZl87ZHsQk5+X/RYV8QI=", + "safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", "dev": true }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "semver": { + "version": "5.5.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.5.1.tgz", + "integrity": "sha512-PqpAxfrEhlSUWge8dwIp4tZnQ25DIOthpiaHNIthsjEFQD6EvqUKUDM7L8O2rShkFccYo1VjJR0coWfNkCubRw==", "dev": true }, - "shelljs": { - "version": "0.7.8", - "resolved": "https://registry.npmjs.org/shelljs/-/shelljs-0.7.8.tgz", - "integrity": "sha1-3svPh0sNHl+3LhSxZKloMEjprLM=", + "shebang-command": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", + "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=", "dev": true, "requires": { - "glob": "^7.0.0", - "interpret": "^1.0.0", - "rechoir": "^0.6.2" + "shebang-regex": "^1.0.0" } }, + "shebang-regex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", + "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=", + "dev": true + }, + "signal-exit": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz", + "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=", + "dev": true + }, "simple-swizzle": { "version": "0.2.2", "resolved": "https://registry.npmjs.org/simple-swizzle/-/simple-swizzle-0.2.2.tgz", @@ -1274,10 +1062,13 @@ } }, "slice-ansi": { - "version": "0.0.4", - "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-0.0.4.tgz", - "integrity": "sha1-7b+JA/ZvfOL46v1s7tZeJkyDGzU=", - "dev": true + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-1.0.0.tgz", + "integrity": "sha512-POqxBK6Lb3q6s047D/XsDVNPnF9Dl8JSaqe9h9lURl0OdNqy/ujDrOiIHtsqXMGbWWTIomRzAMaTyawAU//Reg==", + "dev": true, + "requires": { + "is-fullwidth-code-point": "^2.0.0" + } }, "source-map": { "version": "0.6.1", @@ -1291,14 +1082,13 @@ "dev": true }, "string-width": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", - "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", + "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", "dev": true, "requires": { - "code-point-at": "^1.0.0", - "is-fullwidth-code-point": "^1.0.0", - "strip-ansi": "^3.0.0" + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^4.0.0" } }, "string.prototype.trim": { @@ -1312,30 +1102,15 @@ "function-bind": "^1.0.2" } }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - }, "strip-ansi": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", - "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", + "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", "dev": true, "requires": { - "ansi-regex": "^2.0.0" + "ansi-regex": "^3.0.0" } }, - "strip-bom": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", - "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", - "dev": true - }, "strip-json-comments": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", @@ -1351,77 +1126,17 @@ } }, "table": { - "version": "3.8.3", - "resolved": "https://registry.npmjs.org/table/-/table-3.8.3.tgz", - "integrity": "sha1-K7xULw/amGGnVdOUf+/Ys/UThV8=", + "version": "4.0.3", + "resolved": "http://registry.npmjs.org/table/-/table-4.0.3.tgz", + "integrity": "sha512-S7rnFITmBH1EnyKcvxBh1LjYeQMmnZtCXSEbHcH6S0NoKit24ZuFO/T1vDcLdYsLQkM188PVVhQmzKIuThNkKg==", "dev": true, "requires": { - "ajv": "^4.7.0", - "ajv-keywords": "^1.0.0", - "chalk": "^1.1.1", - "lodash": "^4.0.0", - "slice-ansi": "0.0.4", - "string-width": "^2.0.0" - }, - "dependencies": { - "ansi-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", - "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", - "dev": true - }, - "ansi-styles": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", - "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", - "dev": true - }, - "chalk": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", - "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", - "dev": true, - "requires": { - "ansi-styles": "^2.2.1", - "escape-string-regexp": "^1.0.2", - "has-ansi": "^2.0.0", - "strip-ansi": "^3.0.0", - "supports-color": "^2.0.0" - } - }, - "is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", - "dev": true - }, - "string-width": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", - "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", - "dev": true, - "requires": { - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^4.0.0" - }, - "dependencies": { - "strip-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", - "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", - "dev": true, - "requires": { - "ansi-regex": "^3.0.0" - } - } - } - }, - "supports-color": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", - "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", - "dev": true - } + "ajv": "^6.0.1", + "ajv-keywords": "^3.0.0", + "chalk": "^2.1.0", + "lodash": "^4.17.4", + "slice-ansi": "1.0.0", + "string-width": "^2.1.1" } }, "tape": { @@ -1447,7 +1162,7 @@ "dependencies": { "minimist": { "version": "1.2.0", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", + "resolved": "http://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", "dev": true }, @@ -1470,10 +1185,25 @@ }, "through": { "version": "2.3.8", - "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", + "resolved": "http://registry.npmjs.org/through/-/through-2.3.8.tgz", "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=", "dev": true }, + "tmp": { + "version": "0.0.33", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", + "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", + "dev": true, + "requires": { + "os-tmpdir": "~1.0.2" + } + }, + "tslib": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.9.3.tgz", + "integrity": "sha512-4krF8scpejhaOgqzBEcGM7yDIEfi0/8+8zDRZhNZZ2kjmHJ4hv3zCbQWxoJGz1iw5U0Jl0nma13xzHXcncMavQ==", + "dev": true + }, "type-check": { "version": "0.3.2", "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", @@ -1483,26 +1213,23 @@ "prelude-ls": "~1.1.2" } }, - "typedarray": { - "version": "0.0.6", - "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", - "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=", - "dev": true - }, - "user-home": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/user-home/-/user-home-2.0.0.tgz", - "integrity": "sha1-nHC/2Babwdy/SGBODwS4tJzenp8=", + "uri-js": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.2.2.tgz", + "integrity": "sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ==", "dev": true, "requires": { - "os-homedir": "^1.0.0" + "punycode": "^2.1.0" } }, - "util-deprecate": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=", - "dev": true + "which": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", + "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "dev": true, + "requires": { + "isexe": "^2.0.0" + } }, "wordwrap": { "version": "1.0.0", @@ -1524,12 +1251,6 @@ "requires": { "mkdirp": "^0.5.1" } - }, - "xtend": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz", - "integrity": "sha1-pcbVMr5lbiPbgg77lDofBJmNY68=", - "dev": true } } } diff --git a/package.json b/package.json index 3dbdf7e784..49a7427f60 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "postcss-color-hex-alpha", - "version": "3.0.0", + "version": "4.0.0", "description": "PostCSS plugin to transform W3C RGBA hexadecimal notations (#RRGGBBAA or #RGBA) to more compatible CSS (rgba())", "keywords": [ "css", @@ -24,13 +24,13 @@ "node": ">=6.0.0" }, "dependencies": { - "color": "^1.0.3", + "color": "^3.0.0", "postcss": "^7.0.2", "postcss-message-helpers": "^2.0.0" }, "devDependencies": { - "eslint": "^3.19.0", - "tape": "^4.6.3" + "eslint": "^5.6.0", + "tape": "^4.9.1" }, "scripts": { "lint": "eslint *.js index.js ./test/", From 354e2f64197b23b206cad317d955356152d22668 Mon Sep 17 00:00:00 2001 From: Jonathan Neal Date: Mon, 17 Sep 2018 22:49:53 -0400 Subject: [PATCH 689/795] 4.0.0 --- .travis.yml | 10 +++++++--- CHANGELOG.md | 5 +++++ README.md | 6 +++--- package-lock.json | 49 ++++++++++++++++++++++++++++++----------------- package.json | 8 ++++---- 5 files changed, 50 insertions(+), 28 deletions(-) diff --git a/.travis.yml b/.travis.yml index 71c4fb1436..e1f11a52e6 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,5 +1,9 @@ +# https://docs.travis-ci.com/user/travis-lint + language: node_js + node_js: - - "6" - - "8" - - "stable" + - 6 + +install: + - npm install --ignore-scripts diff --git a/CHANGELOG.md b/CHANGELOG.md index 397ef488b0..4b020de67e 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,8 @@ +# 4.0.0 - 2018-09-17 + +- Updated: Support for PostCSS v7+ +- Updated: Support for Node v6+ + # 3.1.0 - 2018-05-01 - Improve `rebeccapurple` pre-parse word detection diff --git a/README.md b/README.md index f8c56fd2f3..84ebc601aa 100755 --- a/README.md +++ b/README.md @@ -1,11 +1,11 @@ -# postcss-color-rebeccapurple [![Build Status](https://travis-ci.org/postcss/postcss-color-rebeccapurple.png)](https://travis-ci.org/postcss/postcss-color-rebeccapurple) +# postcss-color-rebeccapurple [![CSS Standard Status](https://cssdb.org/badge/rebeccapurple-color.svg)](https://cssdb.org/#rebeccapurple-color) [![Build Status](https://api.travis-ci.org/postcss/postcss-color-rebeccapurple.svg)](https://travis-ci.org/postcss/postcss-color-rebeccapurple) -> [PostCSS](https://github.com/postcss/postcss) plugin to transform [W3C CSS `rebeccapurple` color](http://dev.w3.org/csswg/css-color/#valdef-color-rebeccapurple) to more compatible CSS (rgb()). +> [PostCSS](https://github.com/postcss/postcss) plugin to transform [W3C CSS `rebeccapurple` color](https://www.w3.org/TR/css-color-4/#valdef-color-rebeccapurple) to more compatible CSS (rgb()). ## Why this plugin ? If you did some CSS, I'm sure you know who [Eric Meyer](https://en.wikipedia.org/wiki/Eric_A._Meyer) is, & what he did for this language. -In memory of [Eric Meyer’s daughter](http://meyerweb.com/eric/thoughts/2014/06/09/in-memoriam-2/), [W3C added new color rebeccapurple to CSS 4 Color Module](http://lists.w3.org/Archives/Public/www-style/2014Jun/0312.html). +In memory of [Eric Meyer’s daughter](https://meyerweb.com/eric/thoughts/2014/06/09/in-memoriam-2/), [W3C added new color rebeccapurple to CSS 4 Color Module](https://lists.w3.org/Archives/Public/www-style/2014Jun/0312.html). ## Installation diff --git a/package-lock.json b/package-lock.json index 22ddfe2cf2..eebe1b2d76 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "postcss-color-rebeccapurple", - "version": "3.1.0", + "version": "4.0.0", "lockfileVersion": 1, "requires": true, "dependencies": { "@octokit/rest": { "version": "14.0.9", - "resolved": "https://registry.npmjs.org/@octokit/rest/-/rest-14.0.9.tgz", + "resolved": "http://registry.npmjs.org/@octokit/rest/-/rest-14.0.9.tgz", "integrity": "sha512-irP9phKfTXEZIcW2R+VNCtGHZJrXMWmSYp6RRfFn4BtAqtDRXF5z9JxCEQlAhNBf6X1koNi5k49tIAAAEJNlVQ==", "dev": true, "requires": { @@ -19,18 +19,24 @@ }, "dependencies": { "debug": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", - "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", + "version": "3.2.5", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.5.tgz", + "integrity": "sha512-D61LaDQPQkxJ5AUM2mbSJRbPkNs/TmdmOeLAi1hgDkpDfIfetSrjmWhccwtuResSwMbACjx/xXQofvM9CE/aeg==", "dev": true, "requires": { - "ms": "2.0.0" + "ms": "^2.1.1" } }, "lodash": { - "version": "4.17.10", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.10.tgz", - "integrity": "sha512-UejweD1pDoXu+AD825lWwp4ZGtSwgnpZxb3JDViD7StjQz+Nb/6l093lx4OQ0foGWNRoc19mWy7BzL+UAK2iVg==", + "version": "4.17.11", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.11.tgz", + "integrity": "sha512-cQKh8igo5QUhZ7lg38DYWAxMvjSAKG0A8wGSVimP07SIUEK2UO+arSRKbRZWtelMtN5V0Hkwh5ryOto/SshYIg==", + "dev": true + }, + "ms": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", + "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==", "dev": true } } @@ -865,12 +871,12 @@ }, "dependencies": { "debug": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", - "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", + "version": "3.2.5", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.5.tgz", + "integrity": "sha512-D61LaDQPQkxJ5AUM2mbSJRbPkNs/TmdmOeLAi1hgDkpDfIfetSrjmWhccwtuResSwMbACjx/xXQofvM9CE/aeg==", "dev": true, "requires": { - "ms": "2.0.0" + "ms": "^2.1.1" } }, "minimist": { @@ -878,6 +884,12 @@ "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", "dev": true + }, + "ms": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", + "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==", + "dev": true } } }, @@ -1345,7 +1357,8 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", - "dev": true + "dev": true, + "optional": true }, "mute-stream": { "version": "0.0.7", @@ -1410,13 +1423,13 @@ } }, "npmpub": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/npmpub/-/npmpub-3.1.0.tgz", - "integrity": "sha1-c0OoAf+xi/0s7CM1hLkUWa5O4Uk=", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/npmpub/-/npmpub-4.1.0.tgz", + "integrity": "sha512-aFaX5gp09tl5NxpqxkHg1QCZrTx6QHBLfQkfonXR0ohwvWeNJItFVSN2R+6IVKtLis085A6zbOUi8r6lMtPO9A==", "dev": true, "requires": { "chalk": "^1.1.1", - "github-release-from-changelog": "^1.1.1", + "github-release-from-changelog": "^1.3.2", "minimist": "^1.2.0", "shelljs": "^0.5.3", "trash": "^3.4.1" diff --git a/package.json b/package.json index 52bc063cec..e846116f7f 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "postcss-color-rebeccapurple", - "version": "3.1.0", + "version": "4.0.0", "description": "PostCSS plugin to transform W3C CSS rebeccapurple color to more compatible CSS (rgb())", "keywords": [ "css", @@ -29,9 +29,9 @@ }, "devDependencies": { "jscs": "^3.0.7", - "jshint": "^2.9.5", - "npmpub": "^3.1.0", - "tape": "^4.9.0" + "jshint": "^2.9.6", + "npmpub": "^4.1.0", + "tape": "^4.9.1" }, "scripts": { "lint": "npm run jscs && npm run jshint", From 5d4fc6152f22f2961f8731420873e8dd4247184e Mon Sep 17 00:00:00 2001 From: Jonathan Neal Date: Mon, 17 Sep 2018 22:59:38 -0400 Subject: [PATCH 690/795] 5.0.0 --- .appveyor.yml | 18 ------ .gitignore | 3 +- .rollup.js | 6 +- .travis.yml | 2 +- CHANGELOG.md | 6 ++ INSTALL.md | 170 ++++++++++++++++++++++++++++++++++++++++++++++++++ README.md | 112 +++------------------------------ package.json | 22 ++++--- 8 files changed, 203 insertions(+), 136 deletions(-) delete mode 100644 .appveyor.yml create mode 100644 INSTALL.md diff --git a/.appveyor.yml b/.appveyor.yml deleted file mode 100644 index acbf8a5eeb..0000000000 --- a/.appveyor.yml +++ /dev/null @@ -1,18 +0,0 @@ -# https://www.appveyor.com/docs/appveyor-yml - -environment: - matrix: - - nodejs_version: 4 - -version: "{build}" -build: off -deploy: off - -install: - - ps: Install-Product node $env:nodejs_version - - npm install --ignore-scripts - -test_script: - - node --version - - npm --version - - cmd: "npm test" diff --git a/.gitignore b/.gitignore index de73e5a338..d920b78fec 100644 --- a/.gitignore +++ b/.gitignore @@ -1,10 +1,9 @@ node_modules -index.*.js +index.*.* package-lock.json *.log* *.result.css .* -!.appveyor.yml !.editorconfig !.gitignore !.rollup.js diff --git a/.rollup.js b/.rollup.js index 0436758216..ebe39f9220 100644 --- a/.rollup.js +++ b/.rollup.js @@ -3,13 +3,13 @@ import babel from 'rollup-plugin-babel'; export default { input: 'index.js', output: [ - { file: 'index.cjs.js', format: 'cjs' }, - { file: 'index.es.js', format: 'es' } + { file: 'index.cjs.js', format: 'cjs', sourcemap: true }, + { file: 'index.es.mjs', format: 'es', sourcemap: true } ], plugins: [ babel({ presets: [ - ['env', { modules: false, targets: { node: 4 } }] + ['@babel/env', { modules: false, targets: { node: 6 } }] ] }) ] diff --git a/.travis.yml b/.travis.yml index c56466446c..e1f11a52e6 100644 --- a/.travis.yml +++ b/.travis.yml @@ -3,7 +3,7 @@ language: node_js node_js: - - 4 + - 6 install: - npm install --ignore-scripts diff --git a/CHANGELOG.md b/CHANGELOG.md index deaa14c1ff..d5d1490860 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,11 @@ # Changes to PostCSS Dir Pseudo Class +### 5.0.0 (September 17, 2018) + +- Updated: Support for PostCSS v7+ +- Updated: Support for Node v6+ +- Updated: `postcss-selector-parser` to v5.0.0-rc.3+ (major) + ### 4.0.0 (May 8, 2018) - Updated: `postcss-selector-parser` to v4.0.0 (major) diff --git a/INSTALL.md b/INSTALL.md new file mode 100644 index 0000000000..8777745efc --- /dev/null +++ b/INSTALL.md @@ -0,0 +1,170 @@ +# Installing PostCSS Dir Pseudo Class + +[PostCSS Dir Pseudo Class] runs in all Node environments, with special instructions for: + +| [Node](#node) | [PostCSS CLI](#postcss-cli) | [Webpack](#webpack) | [Create React App](#create-react-app) | [Gulp](#gulp) | [Grunt](#grunt) | +| --- | --- | --- | --- | --- | --- | + +## Node + +Add [PostCSS Dir Pseudo Class] to your project: + +```bash +npm install postcss-dir-pseudo-class --save-dev +``` + +Use [PostCSS Dir Pseudo Class] to process your CSS: + +```js +const postcssDirPseudoClass = require('postcss-dir-pseudo-class'); + +postcssDirPseudoClass.process(YOUR_CSS /*, processOptions, pluginOptions */); +``` + +Or use it as a [PostCSS] plugin: + +```js +const postcss = require('postcss'); +const postcssDirPseudoClass = require('postcss-dir-pseudo-class'); + +postcss([ + postcssDirPseudoClass(/* pluginOptions */) +]).process(YOUR_CSS /*, processOptions */); +``` + +## PostCSS CLI + +Add [PostCSS CLI] to your project: + +```bash +npm install postcss-cli --save-dev +``` + +Use [PostCSS Dir Pseudo Class] in your `postcss.config.js` configuration file: + +```js +const postcssDirPseudoClass = require('postcss-dir-pseudo-class'); + +module.exports = { + plugins: [ + postcssDirPseudoClass(/* pluginOptions */) + ] +} +``` + +## Webpack + +Add [PostCSS Loader] to your project: + +```bash +npm install postcss-loader --save-dev +``` + +Use [PostCSS Dir Pseudo Class] in your Webpack configuration: + +```js +const postcssDirPseudoClass = require('postcss-dir-pseudo-class'); + +module.exports = { + module: { + rules: [ + { + test: /\.css$/, + use: [ + 'style-loader', + { loader: 'css-loader', options: { importLoaders: 1 } }, + { loader: 'postcss-loader', options: { + ident: 'postcss', + plugins: () => [ + postcssDirPseudoClass(/* pluginOptions */) + ] + } } + ] + } + ] + } +} +``` + +## Create React App + +Add [React App Rewired] and [React App Rewire PostCSS] to your project: + +```bash +npm install react-app-rewired react-app-rewire-postcss --save-dev +``` + +Use [React App Rewire PostCSS] and [PostCSS Dir Pseudo Class] in your +`config-overrides.js` file: + +```js +const reactAppRewirePostcss = require('react-app-rewire-postcss'); +const postcssDirPseudoClass = require('postcss-dir-pseudo-class'); + +module.exports = config => reactAppRewirePostcss(config, { + plugins: () => [ + postcssDirPseudoClass(/* pluginOptions */) + ] +}); +``` + +## Gulp + +Add [Gulp PostCSS] to your project: + +```bash +npm install gulp-postcss --save-dev +``` + +Use [PostCSS Dir Pseudo Class] in your Gulpfile: + +```js +const postcss = require('gulp-postcss'); +const postcssDirPseudoClass = require('postcss-dir-pseudo-class'); + +gulp.task('css', () => gulp.src('./src/*.css').pipe( + postcss([ + postcssDirPseudoClass(/* pluginOptions */) + ]) +).pipe( + gulp.dest('.') +)); +``` + +## Grunt + +Add [Grunt PostCSS] to your project: + +```bash +npm install grunt-postcss --save-dev +``` + +Use [PostCSS Dir Pseudo Class] in your Gruntfile: + +```js +const postcssDirPseudoClass = require('postcss-dir-pseudo-class'); + +grunt.loadNpmTasks('grunt-postcss'); + +grunt.initConfig({ + postcss: { + options: { + use: [ + postcssDirPseudoClass(/* pluginOptions */) + ] + }, + dist: { + src: '*.css' + } + } +}); +``` + +[Gulp PostCSS]: https://github.com/postcss/gulp-postcss +[Grunt PostCSS]: https://github.com/nDmitry/grunt-postcss +[PostCSS]: https://github.com/postcss/postcss +[PostCSS CLI]: https://github.com/postcss/postcss-cli +[PostCSS Loader]: https://github.com/postcss/postcss-loader +[PostCSS Dir Pseudo Class]: https://github.com/jonathantneal/postcss-dir-pseudo-class +[React App Rewire PostCSS]: https://github.com/csstools/react-app-rewire-postcss +[React App Rewired]: https://github.com/timarney/react-app-rewired diff --git a/README.md b/README.md index a044cce91d..5f84e1b827 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,6 @@ [![NPM Version][npm-img]][npm-url] [![CSS Standard Status][css-img]][css-url] [![Build Status][cli-img]][cli-url] -[![Windows Build Status][win-img]][win-url] [![Support Chat][git-img]][git-url] [PostCSS Dir Pseudo Class] lets you style by directionality using the `:dir()` @@ -47,126 +46,35 @@ sometimes increase selector weight by one element (`html`). ## Usage -Add [PostCSS Dir Pseudo Class] to your build tool: +Add [PostCSS Dir Pseudo Class] to your project: ```bash npm install postcss-dir-pseudo-class --save-dev ``` -#### Node - Use [PostCSS Dir Pseudo Class] to process your CSS: ```js -import postcssDirPseudoClass from 'postcss-dir-pseudo-class'; - -postcssDirPseudoClass.process(YOUR_CSS, /* processOptions */, /* pluginOptions */); -``` - -#### PostCSS +const postcssDirPseudoClass = require('postcss-dir-pseudo-class'); -Add [PostCSS] to your build tool: - -```bash -npm install postcss --save-dev +postcssDirPseudoClass.process(YOUR_CSS /*, processOptions, pluginOptions */); ``` -Use [PostCSS Dir Pseudo Class] as a plugin: +Or use it as a [PostCSS] plugin: ```js -import postcss from 'gulp-postcss'; -import postcssDirPseudoClass from 'postcss-dir-pseudo-class'; +const postcss = require('postcss'); +const postcssDirPseudoClass = require('postcss-dir-pseudo-class'); postcss([ postcssDirPseudoClass(/* pluginOptions */) -]).process(YOUR_CSS); -``` - -#### Webpack - -Add [PostCSS Loader] to your build tool: - -```bash -npm install postcss-loader --save-dev -``` - -Use [PostCSS Dir Pseudo Class] in your Webpack configuration: - -```js -import postcssDirPseudoClass from 'postcss-dir-pseudo-class'; - -module.exports = { - module: { - rules: [ - { - test: /\.css$/, - use: [ - 'style-loader', - { loader: 'css-loader', options: { importLoaders: 1 } }, - { loader: 'postcss-loader', options: { - ident: 'postcss', - plugins: () => [ - postcssDirPseudoClass(/* pluginOptions */) - ] - } } - ] - } - ] - } -} +]).process(YOUR_CSS /*, processOptions */); ``` -#### Gulp +[PostCSS Dir Pseudo Class] runs in all Node environments, with special instructions for: -Add [Gulp PostCSS] to your build tool: - -```bash -npm install gulp-postcss --save-dev -``` - -Use [PostCSS Dir Pseudo Class] in your Gulpfile: - -```js -import postcss from 'gulp-postcss'; -import postcssDirPseudoClass from 'postcss-dir-pseudo-class'; - -gulp.task('css', () => gulp.src('./src/*.css').pipe( - postcss([ - postcssDirPseudoClass(/* pluginOptions */) - ]) -).pipe( - gulp.dest('.') -)); -``` - -#### Grunt - -Add [Grunt PostCSS] to your build tool: - -```bash -npm install grunt-postcss --save-dev -``` - -Use [PostCSS Dir Pseudo Class] in your Gruntfile: - -```js -import postcssDirPseudoClass from 'postcss-dir-pseudo-class'; - -grunt.loadNpmTasks('grunt-postcss'); - -grunt.initConfig({ - postcss: { - options: { - use: [ - postcssDirPseudoClass(/* pluginOptions */) - ] - }, - dist: { - src: '*.css' - } - } -}); -``` +| [Node](INSTALL.md#node) | [PostCSS CLI](INSTALL.md#postcss-cli) | [Webpack](INSTALL.md#webpack) | [Create React App](INSTALL.md#create-react-app) | [Gulp](INSTALL.md#gulp) | [Grunt](INSTALL.md#grunt) | +| --- | --- | --- | --- | --- | --- | ## Options diff --git a/package.json b/package.json index 4ba83c9785..5a34c45827 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "postcss-dir-pseudo-class", - "version": "4.0.0", + "version": "5.0.0", "description": "Use the :dir pseudo-class in CSS", "author": "Jonathan Neal ", "license": "CC0-1.0", @@ -8,10 +8,12 @@ "homepage": "https://github.com/jonathantneal/postcss-dir-pseudo-class#readme", "bugs": "https://github.com/jonathantneal/postcss-dir-pseudo-class/issues", "main": "index.cjs.js", - "module": "index.es.js", + "module": "index.es.mjs", "files": [ "index.cjs.js", - "index.es.js" + "index.cjs.js.map", + "index.es.mjs", + "index.es.mjs.map" ], "scripts": { "prepublishOnly": "npm test", @@ -26,18 +28,18 @@ }, "dependencies": { "postcss": "^7.0.2", - "postcss-selector-parser": "^4.0.0" + "postcss-selector-parser": "^5.0.0-rc.3" }, "devDependencies": { - "babel-core": "^6.26.3", - "babel-eslint": "^8.2.3", - "babel-preset-env": "^1.6.1", - "eslint": "^4.19.1", + "@babel/core": "^7.0.0", + "@babel/preset-env": "^7.0.0", + "babel-eslint": "^9.0.0", + "eslint": "^5.6.0", "eslint-config-dev": "^2.0.0", "postcss-tape": "^2.2.0", "pre-commit": "^1.2.2", - "rollup": "^0.58.2", - "rollup-plugin-babel": "^3.0.4" + "rollup": "^0.66.0", + "rollup-plugin-babel": "^4.0.1" }, "eslintConfig": { "extends": "dev", From 20f253f30dcfbcec7044daa3d5e05b3bf4349756 Mon Sep 17 00:00:00 2001 From: Jonathan Neal Date: Mon, 17 Sep 2018 23:33:50 -0400 Subject: [PATCH 691/795] 2.0.0 --- .appveyor.yml | 18 ---- .gitignore | 3 +- .rollup.js | 9 +- .tape.js | 77 +++++++++++++++- .travis.yml | 2 +- CHANGELOG.md | 6 ++ INSTALL.md | 170 +++++++++++++++++++++++++++++++++++ README.md | 154 +++++++++++++------------------ index.js | 29 +++--- lib/import-from.js | 93 +++++++++++++++++++ lib/replace-with-word.js | 8 -- lib/update-env-value.js | 42 +++++++-- package.json | 23 ++--- test/basic.expect.css | 4 +- test/basic.import.expect.css | 10 +++ test/import-variables.js | 6 ++ test/import-variables.json | 6 ++ 17 files changed, 504 insertions(+), 156 deletions(-) delete mode 100644 .appveyor.yml create mode 100644 INSTALL.md create mode 100644 lib/import-from.js delete mode 100644 lib/replace-with-word.js create mode 100644 test/basic.import.expect.css create mode 100644 test/import-variables.js create mode 100644 test/import-variables.json diff --git a/.appveyor.yml b/.appveyor.yml deleted file mode 100644 index acbf8a5eeb..0000000000 --- a/.appveyor.yml +++ /dev/null @@ -1,18 +0,0 @@ -# https://www.appveyor.com/docs/appveyor-yml - -environment: - matrix: - - nodejs_version: 4 - -version: "{build}" -build: off -deploy: off - -install: - - ps: Install-Product node $env:nodejs_version - - npm install --ignore-scripts - -test_script: - - node --version - - npm --version - - cmd: "npm test" diff --git a/.gitignore b/.gitignore index de73e5a338..d920b78fec 100644 --- a/.gitignore +++ b/.gitignore @@ -1,10 +1,9 @@ node_modules -index.*.js +index.*.* package-lock.json *.log* *.result.css .* -!.appveyor.yml !.editorconfig !.gitignore !.rollup.js diff --git a/.rollup.js b/.rollup.js index 0436758216..3f28a5511b 100644 --- a/.rollup.js +++ b/.rollup.js @@ -3,13 +3,16 @@ import babel from 'rollup-plugin-babel'; export default { input: 'index.js', output: [ - { file: 'index.cjs.js', format: 'cjs' }, - { file: 'index.es.js', format: 'es' } + { file: 'index.cjs.js', format: 'cjs', sourcemap: true }, + { file: 'index.es.mjs', format: 'es', sourcemap: true } ], plugins: [ babel({ + plugins: [ + '@babel/plugin-syntax-dynamic-import' + ], presets: [ - ['env', { modules: false, targets: { node: 4 } }] + ['@babel/env', { modules: false, targets: { node: 6 } }] ] }) ] diff --git a/.tape.js b/.tape.js index f6b23c84a8..00854c33ed 100644 --- a/.tape.js +++ b/.tape.js @@ -1,13 +1,82 @@ module.exports = { 'postcss-env-function': { 'basic': { - message: 'supports basic usage', + message: 'supports basic usage' + }, + 'basic:import': { + message: 'supports { importFrom: { environmentVariables: { ... } } } usage', options: { - variables: { - '--some-custom-padding': '20px', - '--another-custom-width': '600px' + importFrom: { + environmentVariables: { + '--some-custom-padding': '20px', + '--another-custom-width': '600px' + } } } + }, + 'basic:import-fn': { + message: 'supports { importFrom() } usage', + options: { + importFrom() { + return { + environmentVariables: { + '--some-custom-padding': '20px', + '--another-custom-width': '600px' + } + }; + } + }, + expect: 'basic.import.expect.css', + result: 'basic.import.result.css' + }, + 'basic:import-fn-promise': { + message: 'supports { async importFrom() } usage', + options: { + importFrom() { + return new Promise(resolve => { + resolve({ + environmentVariables: { + '--some-custom-padding': '20px', + '--another-custom-width': '600px' + } + }) + }); + } + }, + expect: 'basic.import.expect.css', + result: 'basic.import.result.css' + }, + 'basic:import-json': { + message: 'supports { importFrom: "test/import-variables.json" } usage', + options: { + importFrom: 'test/import-variables.json' + }, + expect: 'basic.import.expect.css', + result: 'basic.import.result.css' + }, + 'basic:import-js': { + message: 'supports { importFrom: "test/import-variables.js" } usage', + options: { + importFrom: 'test/import-variables.js' + }, + expect: 'basic.import.expect.css', + result: 'basic.import.result.css' + }, + 'basic:import-js-from': { + message: 'supports { importFrom: { from: "test/import-variables.js" } } usage', + options: { + importFrom: { from: 'test/import-variables.js' } + }, + expect: 'basic.import.expect.css', + result: 'basic.import.result.css' + }, + 'basic:import-js-from-type': { + message: 'supports { importFrom: [ { from: "test/import-variables.js", type: "js" } ] } usage', + options: { + importFrom: [ { from: 'test/import-variables.js', type: 'js' } ] + }, + expect: 'basic.import.expect.css', + result: 'basic.import.result.css' } } }; diff --git a/.travis.yml b/.travis.yml index c56466446c..e1f11a52e6 100644 --- a/.travis.yml +++ b/.travis.yml @@ -3,7 +3,7 @@ language: node_js node_js: - - 4 + - 6 install: - npm install --ignore-scripts diff --git a/CHANGELOG.md b/CHANGELOG.md index 8bcc451ecb..633b2ad3ff 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,11 @@ # Changes to PostCSS Environment Variables +### 2.0.0 (September 17, 2018) + +- Updated: Support for PostCSS v7+ +- Updated: Support for Node v6+ +- Updated: Changed `variables` option to `importFrom` option + ### 1.0.0 (April 28, 2018) - Initial version diff --git a/INSTALL.md b/INSTALL.md new file mode 100644 index 0000000000..77a30a1503 --- /dev/null +++ b/INSTALL.md @@ -0,0 +1,170 @@ +# Installing PostCSS Environment Variables + +[PostCSS Environment Variables] runs in all Node environments, with special instructions for: + +| [Node](#node) | [PostCSS CLI](#postcss-cli) | [Webpack](#webpack) | [Create React App](#create-react-app) | [Gulp](#gulp) | [Grunt](#grunt) | +| --- | --- | --- | --- | --- | --- | + +## Node + +Add [PostCSS Environment Variables] to your project: + +```bash +npm install postcss-env-function --save-dev +``` + +Use [PostCSS Environment Variables] to process your CSS: + +```js +const postcssEnvFunction = require('postcss-env-function'); + +postcssEnvFunction.process(YOUR_CSS /*, processOptions, pluginOptions */); +``` + +Or use it as a [PostCSS] plugin: + +```js +const postcss = require('postcss'); +const postcssEnvFunction = require('postcss-env-function'); + +postcss([ + postcssEnvFunction(/* pluginOptions */) +]).process(YOUR_CSS /*, processOptions */); +``` + +## PostCSS CLI + +Add [PostCSS CLI] to your project: + +```bash +npm install postcss-cli --save-dev +``` + +Use [PostCSS Environment Variables] in your `postcss.config.js` configuration file: + +```js +const postcssEnvFunction = require('postcss-env-function'); + +module.exports = { + plugins: [ + postcssEnvFunction(/* pluginOptions */) + ] +} +``` + +## Webpack + +Add [PostCSS Loader] to your project: + +```bash +npm install postcss-loader --save-dev +``` + +Use [PostCSS Environment Variables] in your Webpack configuration: + +```js +const postcssEnvFunction = require('postcss-env-function'); + +module.exports = { + module: { + rules: [ + { + test: /\.css$/, + use: [ + 'style-loader', + { loader: 'css-loader', options: { importLoaders: 1 } }, + { loader: 'postcss-loader', options: { + ident: 'postcss', + plugins: () => [ + postcssEnvFunction(/* pluginOptions */) + ] + } } + ] + } + ] + } +} +``` + +## Create React App + +Add [React App Rewired] and [React App Rewire PostCSS] to your project: + +```bash +npm install react-app-rewired react-app-rewire-postcss --save-dev +``` + +Use [React App Rewire PostCSS] and [PostCSS Environment Variables] in your +`config-overrides.js` file: + +```js +const reactAppRewirePostcss = require('react-app-rewire-postcss'); +const postcssEnvFunction = require('postcss-env-function'); + +module.exports = config => reactAppRewirePostcss(config, { + plugins: () => [ + postcssEnvFunction(/* pluginOptions */) + ] +}); +``` + +## Gulp + +Add [Gulp PostCSS] to your project: + +```bash +npm install gulp-postcss --save-dev +``` + +Use [PostCSS Environment Variables] in your Gulpfile: + +```js +const postcss = require('gulp-postcss'); +const postcssEnvFunction = require('postcss-env-function'); + +gulp.task('css', () => gulp.src('./src/*.css').pipe( + postcss([ + postcssEnvFunction(/* pluginOptions */) + ]) +).pipe( + gulp.dest('.') +)); +``` + +## Grunt + +Add [Grunt PostCSS] to your project: + +```bash +npm install grunt-postcss --save-dev +``` + +Use [PostCSS Environment Variables] in your Gruntfile: + +```js +const postcssEnvFunction = require('postcss-env-function'); + +grunt.loadNpmTasks('grunt-postcss'); + +grunt.initConfig({ + postcss: { + options: { + use: [ + postcssEnvFunction(/* pluginOptions */) + ] + }, + dist: { + src: '*.css' + } + } +}); +``` + +[Gulp PostCSS]: https://github.com/postcss/gulp-postcss +[Grunt PostCSS]: https://github.com/nDmitry/grunt-postcss +[PostCSS]: https://github.com/postcss/postcss +[PostCSS CLI]: https://github.com/postcss/postcss-cli +[PostCSS Loader]: https://github.com/postcss/postcss-loader +[PostCSS Environment Variables]: https://github.com/jonathantneal/postcss-env-function +[React App Rewire PostCSS]: https://github.com/csstools/react-app-rewire-postcss +[React App Rewired]: https://github.com/timarney/react-app-rewired diff --git a/README.md b/README.md index a0c72b5549..ed7e3b6b97 100644 --- a/README.md +++ b/README.md @@ -1,8 +1,8 @@ # PostCSS Environment Variables [PostCSS Logo][postcss] [![NPM Version][npm-img]][npm-url] +[![CSS Standard Status][css-img]][css-url] [![Build Status][cli-img]][cli-url] -[![Windows Build Status][win-img]][win-url] [![Support Chat][git-img]][git-url] [PostCSS Environment Variables] lets you use `env()` variables in CSS, @@ -23,147 +23,115 @@ following the [CSS Environment Variables] specification. } } -/* when the `variables` option is: { - "--branding-small": "600px", - "--branding-padding": "20px" +/* when the `importFrom` option is: { + "environmentVariables": { + "--branding-small": "600px", + "--branding-padding": "20px" + } } */ ``` ## Usage -Add [PostCSS Environment Variables] to your build tool: +Add [PostCSS Environment Variables] to your project: ```bash npm install postcss-env-function --save-dev ``` -#### Node - Use [PostCSS Environment Variables] to process your CSS: ```js -import postcssEnvFunction from 'postcss-env-function'; - -postcssEnvFunction.process(YOUR_CSS, /* processOptions */, /* pluginOptions */); -``` - -#### PostCSS +const postcssEnvFunction = require('postcss-env-function'); -Add [PostCSS] to your build tool: - -```bash -npm install postcss --save-dev +postcssEnvFunction.process(YOUR_CSS /*, processOptions, pluginOptions */); ``` -Use [PostCSS Environment Variables] as a plugin: +Or use it as a [PostCSS] plugin: ```js -import postcss from 'gulp-postcss'; -import postcssEnvFunction from 'postcss-env-function'; +const postcss = require('postcss'); +const postcssEnvFunction = require('postcss-env-function'); postcss([ postcssEnvFunction(/* pluginOptions */) -]).process(YOUR_CSS); -``` - -#### Webpack - -Add [PostCSS Loader] to your build tool: - -```bash -npm install postcss-loader --save-dev +]).process(YOUR_CSS /*, processOptions */); ``` -Use [PostCSS Environment Variables] in your Webpack configuration: - -```js -import postcssEnvFunction from 'postcss-env-function'; - -module.exports = { - module: { - rules: [ - { - test: /\.css$/, - use: [ - 'style-loader', - { loader: 'css-loader', options: { importLoaders: 1 } }, - { loader: 'postcss-loader', options: { - ident: 'postcss', - plugins: () => [ - postcssEnvFunction(/* pluginOptions */) - ] - } } - ] - } - ] - } -} -``` +[PostCSS Environment Variables] runs in all Node environments, with special instructions for: -#### Gulp +| [Node](INSTALL.md#node) | [PostCSS CLI](INSTALL.md#postcss-cli) | [Webpack](INSTALL.md#webpack) | [Create React App](INSTALL.md#create-react-app) | [Gulp](INSTALL.md#gulp) | [Grunt](INSTALL.md#grunt) | +| --- | --- | --- | --- | --- | --- | -Add [Gulp PostCSS] to your build tool: +## Options -```bash -npm install gulp-postcss --save-dev -``` +### importFrom -Use [PostCSS Environment Variables] in your Gulpfile: +The `importFrom` option specifies sources where Environment Variables can be +imported from, which might be JS and JSON files, functions, and directly passed +objects. ```js -import postcss from 'gulp-postcss'; -import postcssEnvFunction from 'postcss-env-function'; - -gulp.task('css', () => gulp.src('./src/*.css').pipe( - postcss([ - postcssEnvFunction(/* pluginOptions */) - ]) -).pipe( - gulp.dest('.') -)); +postcssCustomProperties({ + importFrom: 'path/to/file.js' /* module.exports = { + environmentVariables: { + '--branding-padding': '20px', + '--branding-small': '600px' + } + } */ +}); ``` -#### Grunt +```pcss +@media (max-width: env(--branding-small)) { + body { + padding: env(--branding-padding); + } +} -Add [Grunt PostCSS] to your build tool: +/* becomes */ -```bash -npm install grunt-postcss --save-dev +@media (min-width: 600px) { + body { + padding: 20px; + } +} ``` -Use [PostCSS Environment Variables] in your Gruntfile: +Multiple sources can be passed into this option, and they will be parsed in the +order they are received. JavaScript files, JSON files, functions, and objects +will need to namespace Custom Properties using the `environmentVariables` or +`variables-variables` key. ```js -import postcssEnvFunction from 'postcss-env-function'; - -grunt.loadNpmTasks('grunt-postcss'); - -grunt.initConfig({ - postcss: { - options: { - use: [ - postcssEnvFunction(/* pluginOptions */) - ] +postcssCustomProperties({ + importFrom: [ + 'path/to/file.js', // module.exports = { environmentVariables: { '--branding-padding': '20px' } } + 'and/then/this.json', // { "environment-variables": { "--branding-padding": "20px" } } + { + environmentVariables: { '--branding-padding': '20px' } }, - dist: { - src: '*.css' + () => { + const environmentVariables = { '--branding-padding': '20px' }; + + return { environmentVariables }; } - } + ] }); ``` +See example imports written in [JS](test/import-variables.js) and +[JSON](test/import-variables.json). + [cli-img]: https://img.shields.io/travis/jonathantneal/postcss-env-function.svg [cli-url]: https://travis-ci.org/jonathantneal/postcss-env-function +[css-img]: https://cssdb.org/badge/environment-variables.svg +[css-url]: https://cssdb.org/#environment-variables [git-img]: https://img.shields.io/badge/support-chat-blue.svg [git-url]: https://gitter.im/postcss/postcss [npm-img]: https://img.shields.io/npm/v/postcss-env-function.svg [npm-url]: https://www.npmjs.com/package/postcss-env-function -[win-img]: https://img.shields.io/appveyor/ci/jonathantneal/postcss-env-function.svg -[win-url]: https://ci.appveyor.com/project/jonathantneal/postcss-env-function [CSS Environment Variables]: https://drafts.csswg.org/css-env-1/ -[Gulp PostCSS]: https://github.com/postcss/gulp-postcss -[Grunt PostCSS]: https://github.com/nDmitry/grunt-postcss [PostCSS]: https://github.com/postcss/postcss [PostCSS Environment Variables]: https://github.com/jonathantneal/postcss-env-function -[PostCSS Loader]: https://github.com/postcss/postcss-loader diff --git a/index.js b/index.js index f458df64a3..1a90784203 100644 --- a/index.js +++ b/index.js @@ -2,19 +2,28 @@ import postcss from 'postcss'; import getReplacedValue from './lib/get-replaced-value'; import getSupportedValue from './lib/get-supported-value'; import setSupportedValue from './lib/set-supported-value'; +import importEnvironmentVariablesFromSources from './lib/import-from'; -export default postcss.plugin('postcss-env-fn', opts => root => { - const variables = Object(Object(opts).variables); +export default postcss.plugin('postcss-env-fn', opts => { + // sources to import environment variables from + const importFrom = [].concat(Object(opts).importFrom || []); - root.walk(node => { - const supportedValue = getSupportedValue(node); + // promise any environment variables are imported + const environmentVariablesPromise = importEnvironmentVariablesFromSources(importFrom); - if (supportedValue) { - const replacedValue = getReplacedValue(supportedValue, variables); + return async root => { + const environmentVariables = await environmentVariablesPromise; - if (replacedValue !== supportedValue) { - setSupportedValue(node, replacedValue); + root.walk(node => { + const supportedValue = getSupportedValue(node); + + if (supportedValue) { + const replacedValue = getReplacedValue(supportedValue, environmentVariables); + + if (replacedValue !== supportedValue) { + setSupportedValue(node, replacedValue); + } } - } - }); + }); + }; }); diff --git a/lib/import-from.js b/lib/import-from.js new file mode 100644 index 0000000000..5b99a51d6a --- /dev/null +++ b/lib/import-from.js @@ -0,0 +1,93 @@ +import fs from 'fs'; +import path from 'path'; +import valueParser from 'postcss-values-parser'; + +/* Import Custom Properties from Object +/* ========================================================================== */ + +function importEnvironmentVariablesFromObject(object) { + const environmentVariables = Object.assign( + {}, + Object(object).environmentVariables || Object(object)['environment-variables'] + ); + + for (const key in environmentVariables) { + environmentVariables[key] = valueParser(environmentVariables[key]).parse().nodes; + } + + return environmentVariables; +} + +/* Import Custom Properties from JSON file +/* ========================================================================== */ + +async function importEnvironmentVariablesFromJSONFile(from) { + const object = await readJSON(path.resolve(from)); + + return importEnvironmentVariablesFromObject(object); +} + +/* Import Custom Properties from JS file +/* ========================================================================== */ + +async function importEnvironmentVariablesFromJSFile(from) { + const object = await import(path.resolve(from)); + + return importEnvironmentVariablesFromObject(object); +} + +/* Import Custom Properties from Sources +/* ========================================================================== */ + +export default function importEnvironmentVariablesFromSources(sources) { + return sources.map(source => { + if (source instanceof Promise) { + return source; + } else if (source instanceof Function) { + return source(); + } + + // read the source as an object + const opts = source === Object(source) ? source : { from: String(source) }; + + // skip objects with Custom Properties + if (opts.environmentVariables || opts['environment-variables']) { + return opts + } + + // source pathname + const from = String(opts.from || ''); + + // type of file being read from + const type = (opts.type || path.extname(opts.from).slice(1)).toLowerCase(); + + return { type, from }; + }).reduce(async (environmentVariables, source) => { + const { type, from } = await source; + + if (type === 'js') { + return Object.assign(environmentVariables, await importEnvironmentVariablesFromJSFile(from)); + } + + if (type === 'json') { + return Object.assign(environmentVariables, await importEnvironmentVariablesFromJSONFile(from)); + } + + return Object.assign(environmentVariables, importEnvironmentVariablesFromObject(await source)); + }, {}); +} + +/* Helper utilities +/* ========================================================================== */ + +const readFile = from => new Promise((resolve, reject) => { + fs.readFile(from, 'utf8', (error, result) => { + if (error) { + reject(error); + } else { + resolve(result); + } + }); +}); + +const readJSON = async from => JSON.parse(await readFile(from)); diff --git a/lib/replace-with-word.js b/lib/replace-with-word.js deleted file mode 100644 index 59800c1a94..0000000000 --- a/lib/replace-with-word.js +++ /dev/null @@ -1,8 +0,0 @@ -import parser from 'postcss-values-parser'; - -// replaces a node with a word node -export default function (node, value) { - const raws = node.raws; - - node.replaceWith(parser.word({ value, raws })); -} diff --git a/lib/update-env-value.js b/lib/update-env-value.js index 89523f07ee..1cc2e5d39a 100644 --- a/lib/update-env-value.js +++ b/lib/update-env-value.js @@ -1,12 +1,44 @@ import getFnValue from './get-fn-value'; -import replaceWithWord from './replace-with-word'; // update a node with an environment value -export default function (node, variables) { +export default (node, variables) => { // get the value of a css function as a string const value = getFnValue(node); - if (typeof value === 'string') { - replaceWithWord(node, variables[value]) + if (typeof value === 'string' && value in variables) { + node.replaceWith( + ...asClonedArrayWithBeforeSpacing(variables[value], node.raws.before) + ); } -} +}; + +// return an array with its nodes cloned, preserving the raw +const asClonedArrayWithBeforeSpacing = (array, beforeSpacing) => { + const clonedArray = asClonedArray(array, null); + + if (clonedArray[0]) { + clonedArray[0].raws.before = beforeSpacing; + } + + return clonedArray; +}; + +// return an array with its nodes cloned +const asClonedArray = (array, parent) => array.map(node => asClonedNode(node, parent)); + +// return a cloned node +const asClonedNode = (node, parent) => { + const cloneNode = new node.constructor(node); + + for (const key in node) { + if (key === 'parent') { + cloneNode.parent = parent; + } else if (Object(node[key]).constructor === Array) { + cloneNode[key] = asClonedArray(node.nodes, cloneNode); + } else if (Object(node[key]).constructor === Object) { + cloneNode[key] = Object.assign({}, node[key]); + } + } + + return cloneNode; +}; diff --git a/package.json b/package.json index 896a668109..41cccee926 100644 --- a/package.json +++ b/package.json @@ -1,17 +1,19 @@ { "name": "postcss-env-function", - "version": "1.0.0", - "description": "", + "version": "2.0.0", + "description": "Use env() variables in CSS", "author": "Jonathan Neal ", "license": "CC0-1.0", "repository": "jonathantneal/postcss-env-function", "homepage": "https://github.com/jonathantneal/postcss-env-function#readme", "bugs": "https://github.com/jonathantneal/postcss-env-function/issues", "main": "index.cjs.js", - "module": "index.es.js", + "module": "index.es.mjs", "files": [ "index.cjs.js", - "index.es.js" + "index.cjs.js.map", + "index.es.mjs", + "index.es.mjs.map" ], "scripts": { "prepublishOnly": "npm test", @@ -29,15 +31,16 @@ "postcss-values-parser": "^1.5.0" }, "devDependencies": { - "babel-core": "^6.26.3", - "babel-eslint": "^8.2.3", - "babel-preset-env": "^1.6.1", - "eslint": "^4.19.1", + "@babel/core": "^7.0.0", + "@babel/plugin-syntax-dynamic-import": "^7.0.0", + "@babel/preset-env": "^7.0.0", + "babel-eslint": "^9.0.0", + "eslint": "^5.6.0", "eslint-config-dev": "^2.0.0", "postcss-tape": "^2.2.0", "pre-commit": "^1.2.2", - "rollup": "^0.58.2", - "rollup-plugin-babel": "^3.0.4" + "rollup": "^0.66.0", + "rollup-plugin-babel": "^4.0.1" }, "eslintConfig": { "extends": "dev", diff --git a/test/basic.expect.css b/test/basic.expect.css index 762c0d04a7..5199c9faee 100644 --- a/test/basic.expect.css +++ b/test/basic.expect.css @@ -1,9 +1,9 @@ body { order: 1; - padding: 20px; + padding: env(--some-custom-padding); } -@media (min-width: 600px) { +@media (min-width: env(--another-custom-width)) { body { order: 2; } diff --git a/test/basic.import.expect.css b/test/basic.import.expect.css new file mode 100644 index 0000000000..762c0d04a7 --- /dev/null +++ b/test/basic.import.expect.css @@ -0,0 +1,10 @@ +body { + order: 1; + padding: 20px; +} + +@media (min-width: 600px) { + body { + order: 2; + } +} diff --git a/test/import-variables.js b/test/import-variables.js new file mode 100644 index 0000000000..f08efb764a --- /dev/null +++ b/test/import-variables.js @@ -0,0 +1,6 @@ +module.exports = { + environmentVariables: { + '--some-custom-padding': '20px', + '--another-custom-width': '600px' + } +}; diff --git a/test/import-variables.json b/test/import-variables.json new file mode 100644 index 0000000000..b07ea05005 --- /dev/null +++ b/test/import-variables.json @@ -0,0 +1,6 @@ +{ + "environment-variables": { + "--some-custom-padding": "20px", + "--another-custom-width": "600px" + } +} From 518221410a832af581833bd908d133a34a70d986 Mon Sep 17 00:00:00 2001 From: Jonathan Neal Date: Mon, 17 Sep 2018 23:43:26 -0400 Subject: [PATCH 692/795] 4.0.0 --- .appveyor.yml | 18 ------ .gitignore | 3 +- .rollup.js | 6 +- .travis.yml | 2 +- CHANGELOG.md | 5 ++ INSTALL.md | 170 ++++++++++++++++++++++++++++++++++++++++++++++++++ README.md | 115 ++++------------------------------ package.json | 22 ++++--- 8 files changed, 204 insertions(+), 137 deletions(-) delete mode 100644 .appveyor.yml create mode 100644 INSTALL.md diff --git a/.appveyor.yml b/.appveyor.yml deleted file mode 100644 index acbf8a5eeb..0000000000 --- a/.appveyor.yml +++ /dev/null @@ -1,18 +0,0 @@ -# https://www.appveyor.com/docs/appveyor-yml - -environment: - matrix: - - nodejs_version: 4 - -version: "{build}" -build: off -deploy: off - -install: - - ps: Install-Product node $env:nodejs_version - - npm install --ignore-scripts - -test_script: - - node --version - - npm --version - - cmd: "npm test" diff --git a/.gitignore b/.gitignore index de73e5a338..d920b78fec 100644 --- a/.gitignore +++ b/.gitignore @@ -1,10 +1,9 @@ node_modules -index.*.js +index.*.* package-lock.json *.log* *.result.css .* -!.appveyor.yml !.editorconfig !.gitignore !.rollup.js diff --git a/.rollup.js b/.rollup.js index 0436758216..ebe39f9220 100644 --- a/.rollup.js +++ b/.rollup.js @@ -3,13 +3,13 @@ import babel from 'rollup-plugin-babel'; export default { input: 'index.js', output: [ - { file: 'index.cjs.js', format: 'cjs' }, - { file: 'index.es.js', format: 'es' } + { file: 'index.cjs.js', format: 'cjs', sourcemap: true }, + { file: 'index.es.mjs', format: 'es', sourcemap: true } ], plugins: [ babel({ presets: [ - ['env', { modules: false, targets: { node: 4 } }] + ['@babel/env', { modules: false, targets: { node: 6 } }] ] }) ] diff --git a/.travis.yml b/.travis.yml index c56466446c..e1f11a52e6 100644 --- a/.travis.yml +++ b/.travis.yml @@ -3,7 +3,7 @@ language: node_js node_js: - - 4 + - 6 install: - npm install --ignore-scripts diff --git a/CHANGELOG.md b/CHANGELOG.md index aca919c854..96386b280a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,10 @@ # Changes to PostCSS Focus Visible +### 4.0.0 (September 17, 2018) + +- Updated: Support for PostCSS v7+ +- Updated: Support for Node v6+ + ### 3.0.0 (April 7, 2018) - Changed: default functionality to preserve the original rule diff --git a/INSTALL.md b/INSTALL.md new file mode 100644 index 0000000000..5e1e490fdf --- /dev/null +++ b/INSTALL.md @@ -0,0 +1,170 @@ +# Installing PostCSS Focus Visible + +[PostCSS Focus Visible] runs in all Node environments, with special instructions for: + +| [Node](#node) | [PostCSS CLI](#postcss-cli) | [Webpack](#webpack) | [Create React App](#create-react-app) | [Gulp](#gulp) | [Grunt](#grunt) | +| --- | --- | --- | --- | --- | --- | + +## Node + +Add [PostCSS Focus Visible] to your project: + +```bash +npm install postcss-focus-visible --save-dev +``` + +Use [PostCSS Focus Visible] to process your CSS: + +```js +const postcssFocusVisible = require('postcss-focus-visible'); + +postcssFocusVisible.process(YOUR_CSS /*, processOptions, pluginOptions */); +``` + +Or use it as a [PostCSS] plugin: + +```js +const postcss = require('postcss'); +const postcssFocusVisible = require('postcss-focus-visible'); + +postcss([ + postcssFocusVisible(/* pluginOptions */) +]).process(YOUR_CSS /*, processOptions */); +``` + +## PostCSS CLI + +Add [PostCSS CLI] to your project: + +```bash +npm install postcss-cli --save-dev +``` + +Use [PostCSS Focus Visible] in your `postcss.config.js` configuration file: + +```js +const postcssFocusVisible = require('postcss-focus-visible'); + +module.exports = { + plugins: [ + postcssFocusVisible(/* pluginOptions */) + ] +} +``` + +## Webpack + +Add [PostCSS Loader] to your project: + +```bash +npm install postcss-loader --save-dev +``` + +Use [PostCSS Focus Visible] in your Webpack configuration: + +```js +const postcssFocusVisible = require('postcss-focus-visible'); + +module.exports = { + module: { + rules: [ + { + test: /\.css$/, + use: [ + 'style-loader', + { loader: 'css-loader', options: { importLoaders: 1 } }, + { loader: 'postcss-loader', options: { + ident: 'postcss', + plugins: () => [ + postcssFocusVisible(/* pluginOptions */) + ] + } } + ] + } + ] + } +} +``` + +## Create React App + +Add [React App Rewired] and [React App Rewire PostCSS] to your project: + +```bash +npm install react-app-rewired react-app-rewire-postcss --save-dev +``` + +Use [React App Rewire PostCSS] and [PostCSS Focus Visible] in your +`config-overrides.js` file: + +```js +const reactAppRewirePostcss = require('react-app-rewire-postcss'); +const postcssFocusVisible = require('postcss-focus-visible'); + +module.exports = config => reactAppRewirePostcss(config, { + plugins: () => [ + postcssFocusVisible(/* pluginOptions */) + ] +}); +``` + +## Gulp + +Add [Gulp PostCSS] to your project: + +```bash +npm install gulp-postcss --save-dev +``` + +Use [PostCSS Focus Visible] in your Gulpfile: + +```js +const postcss = require('gulp-postcss'); +const postcssFocusVisible = require('postcss-focus-visible'); + +gulp.task('css', () => gulp.src('./src/*.css').pipe( + postcss([ + postcssFocusVisible(/* pluginOptions */) + ]) +).pipe( + gulp.dest('.') +)); +``` + +## Grunt + +Add [Grunt PostCSS] to your project: + +```bash +npm install grunt-postcss --save-dev +``` + +Use [PostCSS Focus Visible] in your Gruntfile: + +```js +const postcssFocusVisible = require('postcss-focus-visible'); + +grunt.loadNpmTasks('grunt-postcss'); + +grunt.initConfig({ + postcss: { + options: { + use: [ + postcssFocusVisible(/* pluginOptions */) + ] + }, + dist: { + src: '*.css' + } + } +}); +``` + +[Gulp PostCSS]: https://github.com/postcss/gulp-postcss +[Grunt PostCSS]: https://github.com/nDmitry/grunt-postcss +[PostCSS]: https://github.com/postcss/postcss +[PostCSS CLI]: https://github.com/postcss/postcss-cli +[PostCSS Loader]: https://github.com/postcss/postcss-loader +[PostCSS Focus Visible]: https://github.com/jonathantneal/postcss-focus-visible +[React App Rewire PostCSS]: https://github.com/csstools/react-app-rewire-postcss +[React App Rewired]: https://github.com/timarney/react-app-rewired diff --git a/README.md b/README.md index 4ef4aa6d2b..901c7042d9 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,6 @@ [![NPM Version][npm-img]][npm-url] [![CSS Standard Status][css-img]][css-url] [![Build Status][cli-img]][cli-url] -[![Windows Build Status][win-img]][win-url] [![Support Chat][git-img]][git-url] [PostCSS Focus Visible] lets you use the `:focus-visible` pseudo-class in @@ -35,124 +34,36 @@ rule can be disabled using the `preserve` option. ## Usage -Add [PostCSS Focus Visible] to your build tool: +Add [PostCSS Focus Visible] to your project: ```bash npm install postcss-focus-visible --save-dev ``` -#### Node - Use [PostCSS Focus Visible] to process your CSS: ```js -import focusVisible from 'postcss-focus-visible'; - -focusVisible.process(YOUR_CSS); -``` - -#### PostCSS +const postcssFocusVisible = require('postcss-focus-visible'); -Add [PostCSS] to your build tool: - -```bash -npm install postcss --save-dev +postcssFocusVisible.process(YOUR_CSS /*, processOptions, pluginOptions */); ``` -Use [PostCSS Focus Visible] as a plugin: +Or use it as a [PostCSS] plugin: ```js -import postcss from 'gulp-postcss'; -import focusVisible from 'postcss-focus-visible'; +const postcss = require('postcss'); +const postcssFocusVisible = require('postcss-focus-visible'); postcss([ - focusVisible() -]).process(YOUR_CSS); -``` - -#### Webpack - -Add [PostCSS Loader] to your build tool: - -```bash -npm install postcss-loader --save-dev -``` - -Use [PostCSS Focus Visible] in your Gulpfile: - -```js -import focusVisible from 'postcss-focus-visible'; - -module.exports = { - module: { - rules: [ - { - test: /\.css$/, - use: [ - 'style-loader', - { loader: 'css-loader', options: { importLoaders: 1 } }, - { loader: 'postcss-loader', options: { - ident: 'postcss', - plugins: () => [ focusVisible() ] - } } - ] - } - ] - } -} + postcssFocusVisible(/* pluginOptions */) +]).process(YOUR_CSS /*, processOptions */); ``` -#### Gulp +[PostCSS Focus Visible] runs in all Node environments, with special +instructions for: -Add [Gulp PostCSS] to your build tool: - -```bash -npm install gulp-postcss --save-dev -``` - -Use [PostCSS Focus Visible] in your Gulpfile: - -```js -import postcss from 'gulp-postcss'; -import focusVisible from 'postcss-focus-visible'; - -gulp.task('css', () => gulp.src('./src/*.css').pipe( - postcss([ - focusVisible() - ]) -).pipe( - gulp.dest('.') -)); -``` - -#### Grunt - -Add [Grunt PostCSS] to your build tool: - -```bash -npm install grunt-postcss --save-dev -``` - -Use [PostCSS Focus Visible] in your Gruntfile: - -```js -import focusVisible from 'postcss-focus-visible'; - -grunt.loadNpmTasks('grunt-postcss'); - -grunt.initConfig({ - postcss: { - options: { - use: [ - focusVisible() - ] - }, - dist: { - src: '*.css' - } - } -}); -``` +| [Node](INSTALL.md#node) | [PostCSS CLI](INSTALL.md#postcss-cli) | [Webpack](INSTALL.md#webpack) | [Create React App](INSTALL.md#create-react-app) | [Gulp](INSTALL.md#gulp) | [Grunt](INSTALL.md#grunt) | +| --- | --- | --- | --- | --- | --- | ## Options @@ -210,8 +121,6 @@ focusVisible({ replaceWith: '[focus-visible]' }); [git-url]: https://gitter.im/postcss/postcss [npm-img]: https://img.shields.io/npm/v/postcss-focus-visible.svg [npm-url]: https://www.npmjs.com/package/postcss-focus-visible -[win-img]: https://img.shields.io/appveyor/ci/jonathantneal/postcss-focus-visible.svg -[win-url]: https://ci.appveyor.com/project/jonathantneal/postcss-focus-visible [focus-visible polyfill]: https://github.com/WICG/focus-visible [Gulp PostCSS]: https://github.com/postcss/gulp-postcss diff --git a/package.json b/package.json index b287ced548..ea6794ca00 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "postcss-focus-visible", - "version": "3.0.0", + "version": "4.0.0", "description": "Use the :focus-visible pseudo-selector in CSS", "author": "Jonathan Neal ", "license": "CC0-1.0", @@ -8,10 +8,12 @@ "homepage": "https://github.com/jonathantneal/postcss-focus-visible#readme", "bugs": "https://github.com/jonathantneal/postcss-focus-visible/issues", "main": "index.cjs.js", - "module": "index.es.js", + "module": "index.es.mjs", "files": [ "index.cjs.js", - "index.es.js" + "index.cjs.js.map", + "index.es.mjs", + "index.es.mjs.map" ], "scripts": { "prepublishOnly": "npm test", @@ -21,21 +23,21 @@ "test:tape": "postcss-tape" }, "engines": { - "node": ">=4.0.0" + "node": ">=6.0.0" }, "dependencies": { "postcss": "^7.0.2" }, "devDependencies": { - "babel-core": "^6.26", - "babel-eslint": "^8.2", - "babel-preset-env": "^1.6", - "eslint": "^4.19", + "@babel/core": "^7.0.0", + "@babel/preset-env": "^7.0.0", + "babel-eslint": "^9.0", + "eslint": "^5.6", "eslint-config-dev": "2.0", "postcss-tape": "2.2", "pre-commit": "^1.2", - "rollup": "^0.57", - "rollup-plugin-babel": "^3.0" + "rollup": "^0.66", + "rollup-plugin-babel": "^4.0.1" }, "eslintConfig": { "extends": "dev", From 382ed07404b3665e1d31bd795a0c028033bc8276 Mon Sep 17 00:00:00 2001 From: Jonathan Neal Date: Mon, 17 Sep 2018 23:53:50 -0400 Subject: [PATCH 693/795] 3.0.0 --- .appveyor.yml | 18 ------ .gitignore | 3 +- .rollup.js | 6 +- .travis.yml | 2 +- CHANGELOG.md | 5 ++ INSTALL.md | 170 ++++++++++++++++++++++++++++++++++++++++++++++++++ README.md | 117 ++++------------------------------ package.json | 22 ++++--- 8 files changed, 205 insertions(+), 138 deletions(-) delete mode 100644 .appveyor.yml create mode 100644 INSTALL.md diff --git a/.appveyor.yml b/.appveyor.yml deleted file mode 100644 index acbf8a5eeb..0000000000 --- a/.appveyor.yml +++ /dev/null @@ -1,18 +0,0 @@ -# https://www.appveyor.com/docs/appveyor-yml - -environment: - matrix: - - nodejs_version: 4 - -version: "{build}" -build: off -deploy: off - -install: - - ps: Install-Product node $env:nodejs_version - - npm install --ignore-scripts - -test_script: - - node --version - - npm --version - - cmd: "npm test" diff --git a/.gitignore b/.gitignore index de73e5a338..d920b78fec 100644 --- a/.gitignore +++ b/.gitignore @@ -1,10 +1,9 @@ node_modules -index.*.js +index.*.* package-lock.json *.log* *.result.css .* -!.appveyor.yml !.editorconfig !.gitignore !.rollup.js diff --git a/.rollup.js b/.rollup.js index 0436758216..ebe39f9220 100644 --- a/.rollup.js +++ b/.rollup.js @@ -3,13 +3,13 @@ import babel from 'rollup-plugin-babel'; export default { input: 'index.js', output: [ - { file: 'index.cjs.js', format: 'cjs' }, - { file: 'index.es.js', format: 'es' } + { file: 'index.cjs.js', format: 'cjs', sourcemap: true }, + { file: 'index.es.mjs', format: 'es', sourcemap: true } ], plugins: [ babel({ presets: [ - ['env', { modules: false, targets: { node: 4 } }] + ['@babel/env', { modules: false, targets: { node: 6 } }] ] }) ] diff --git a/.travis.yml b/.travis.yml index c56466446c..e1f11a52e6 100644 --- a/.travis.yml +++ b/.travis.yml @@ -3,7 +3,7 @@ language: node_js node_js: - - 4 + - 6 install: - npm install --ignore-scripts diff --git a/CHANGELOG.md b/CHANGELOG.md index b018586815..48bc981043 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,10 @@ # Changes to PostCSS Focus Within +### 3.0.0 (September 17, 2018) + +- Updated: Support for PostCSS v7+ +- Updated: Support for Node v6+ + ### 2.0.0 (April 7, 2018) - Changed: default functionality to preserve the original rule diff --git a/INSTALL.md b/INSTALL.md new file mode 100644 index 0000000000..42589a0424 --- /dev/null +++ b/INSTALL.md @@ -0,0 +1,170 @@ +# Installing PostCSS + +[PostCSS] runs in all Node environments, with special instructions for: + +| [Node](#node) | [PostCSS CLI](#postcss-cli) | [Webpack](#webpack) | [Create React App](#create-react-app) | [Gulp](#gulp) | [Grunt](#grunt) | +| --- | --- | --- | --- | --- | --- | + +## Node + +Add [PostCSS] to your project: + +```bash +npm install postcss-focus-within --save-dev +``` + +Use [PostCSS] to process your CSS: + +```js +const postcssFocusWithin = require('postcss-focus-within'); + +postcssFocusWithin.process(YOUR_CSS /*, processOptions, pluginOptions */); +``` + +Or use it as a [PostCSS] plugin: + +```js +const postcss = require('postcss'); +const postcssFocusWithin = require('postcss-focus-within'); + +postcss([ + postcssFocusWithin(/* pluginOptions */) +]).process(YOUR_CSS /*, processOptions */); +``` + +## PostCSS CLI + +Add [PostCSS CLI] to your project: + +```bash +npm install postcss-cli --save-dev +``` + +Use [PostCSS] in your `postcss.config.js` configuration file: + +```js +const postcssFocusWithin = require('postcss-focus-within'); + +module.exports = { + plugins: [ + postcssFocusWithin(/* pluginOptions */) + ] +} +``` + +## Webpack + +Add [PostCSS Loader] to your project: + +```bash +npm install postcss-loader --save-dev +``` + +Use [PostCSS] in your Webpack configuration: + +```js +const postcssFocusWithin = require('postcss-focus-within'); + +module.exports = { + module: { + rules: [ + { + test: /\.css$/, + use: [ + 'style-loader', + { loader: 'css-loader', options: { importLoaders: 1 } }, + { loader: 'postcss-loader', options: { + ident: 'postcss', + plugins: () => [ + postcssFocusWithin(/* pluginOptions */) + ] + } } + ] + } + ] + } +} +``` + +## Create React App + +Add [React App Rewired] and [React App Rewire PostCSS] to your project: + +```bash +npm install react-app-rewired react-app-rewire-postcss --save-dev +``` + +Use [React App Rewire PostCSS] and [PostCSS] in your +`config-overrides.js` file: + +```js +const reactAppRewirePostcss = require('react-app-rewire-postcss'); +const postcssFocusWithin = require('postcss-focus-within'); + +module.exports = config => reactAppRewirePostcss(config, { + plugins: () => [ + postcssFocusWithin(/* pluginOptions */) + ] +}); +``` + +## Gulp + +Add [Gulp PostCSS] to your project: + +```bash +npm install gulp-postcss --save-dev +``` + +Use [PostCSS] in your Gulpfile: + +```js +const postcss = require('gulp-postcss'); +const postcssFocusWithin = require('postcss-focus-within'); + +gulp.task('css', () => gulp.src('./src/*.css').pipe( + postcss([ + postcssFocusWithin(/* pluginOptions */) + ]) +).pipe( + gulp.dest('.') +)); +``` + +## Grunt + +Add [Grunt PostCSS] to your project: + +```bash +npm install grunt-postcss --save-dev +``` + +Use [PostCSS] in your Gruntfile: + +```js +const postcssFocusWithin = require('postcss-focus-within'); + +grunt.loadNpmTasks('grunt-postcss'); + +grunt.initConfig({ + postcss: { + options: { + use: [ + postcssFocusWithin(/* pluginOptions */) + ] + }, + dist: { + src: '*.css' + } + } +}); +``` + +[Gulp PostCSS]: https://github.com/postcss/gulp-postcss +[Grunt PostCSS]: https://github.com/nDmitry/grunt-postcss +[PostCSS]: https://github.com/postcss/postcss +[PostCSS CLI]: https://github.com/postcss/postcss-cli +[PostCSS Loader]: https://github.com/postcss/postcss-loader +[PostCSS]: https://github.com/jonathantneal/postcss-focus-within +[React App Rewire PostCSS]: https://github.com/csstools/react-app-rewire-postcss +[React App Rewired]: https://github.com/timarney/react-app-rewired diff --git a/README.md b/README.md index 32a562b8d4..bea34d39c2 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,6 @@ [![NPM Version][npm-img]][npm-url] [![CSS Standard Status][css-img]][css-url] [![Build Status][cli-img]][cli-url] -[![Windows Build Status][win-img]][win-url] [![Gitter Chat][git-img]][git-url] [PostCSS Focus Within] lets you use the `:focus-within` pseudo-class in CSS, @@ -31,128 +30,40 @@ It is the companion to the [focus-within polyfill]. with a `[focus-within]` attribute selector, the same selector used by the [focus-within polyfill]. This replacement selector can be changed using the `replaceWith` option. Also, the preservation of the original `:focus-within` -rule can be disabled using the `preserve` option. +rule can be disabled using the `preserve` option. ## Usage -Add [PostCSS Focus Within] to your build tool: +Add [PostCSS Focus Within] to your project: ```bash npm install postcss-focus-within --save-dev ``` -#### Node - Use [PostCSS Focus Within] to process your CSS: ```js -import focusWithin from 'postcss-focus-within'; - -focusWithin.process(YOUR_CSS); -``` - -#### PostCSS +const postcssFocusWithin = require('postcss-focus-within'); -Add [PostCSS] to your build tool: - -```bash -npm install postcss --save-dev +postcssFocusWithin.process(YOUR_CSS /*, processOptions, pluginOptions */); ``` -Use [PostCSS Focus Within] as a plugin: +Or use it as a [PostCSS] plugin: ```js -import postcss from 'gulp-postcss'; -import focusWithin from 'postcss-focus-within'; +const postcss = require('postcss'); +const postcssFocusWithin = require('postcss-focus-within'); postcss([ - focusWithin() -]).process(YOUR_CSS); -``` - -#### Webpack - -Add [PostCSS Loader] to your build tool: - -```bash -npm install postcss-loader --save-dev -``` - -Use [PostCSS Focus Within] in your Gulpfile: - -```js -import focusWithin from 'postcss-focus-within'; - -module.exports = { - module: { - rules: [ - { - test: /\.css$/, - use: [ - 'style-loader', - { loader: 'css-loader', options: { importLoaders: 1 } }, - { loader: 'postcss-loader', options: { - ident: 'postcss', - plugins: () => [ focusWithin() ] - } } - ] - } - ] - } -} + postcssFocusWithin(/* pluginOptions */) +]).process(YOUR_CSS /*, processOptions */); ``` -#### Gulp +[PostCSS Focus Within] runs in all Node environments, with special +instructions for: -Add [Gulp PostCSS] to your build tool: - -```bash -npm install gulp-postcss --save-dev -``` - -Use [PostCSS Focus Within] in your Gulpfile: - -```js -import postcss from 'gulp-postcss'; -import focusWithin from 'postcss-focus-within'; - -gulp.task('css', () => gulp.src('./src/*.css').pipe( - postcss([ - focusWithin() - ]) -).pipe( - gulp.dest('.') -)); -``` - -#### Grunt - -Add [Grunt PostCSS] to your build tool: - -```bash -npm install grunt-postcss --save-dev -``` - -Use [PostCSS Focus Within] in your Gruntfile: - -```js -import focusWithin from 'postcss-focus-within'; - -grunt.loadNpmTasks('grunt-postcss'); - -grunt.initConfig({ - postcss: { - options: { - use: [ - focusWithin() - ] - }, - dist: { - src: '*.css' - } - } -}); -``` +| [Node](INSTALL.md#node) | [PostCSS CLI](INSTALL.md#postcss-cli) | [Webpack](INSTALL.md#webpack) | [Create React App](INSTALL.md#create-react-app) | [Gulp](INSTALL.md#gulp) | [Grunt](INSTALL.md#grunt) | +| --- | --- | --- | --- | --- | --- | ## Options @@ -210,8 +121,6 @@ focusWithin({ replaceWith: '.focus-within' }); [git-url]: https://gitter.im/postcss/postcss [npm-img]: https://img.shields.io/npm/v/postcss-focus-within.svg [npm-url]: https://www.npmjs.com/package/postcss-focus-within -[win-img]: https://img.shields.io/appveyor/ci/jonathantneal/postcss-focus-within.svg -[win-url]: https://ci.appveyor.com/project/jonathantneal/postcss-focus-within [focus-within polyfill]: https://github.com/jonathantneal/focus-within [Gulp PostCSS]: https://github.com/postcss/gulp-postcss diff --git a/package.json b/package.json index d71ba66ed7..37060235f0 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "postcss-focus-within", - "version": "2.0.0", + "version": "3.0.0", "description": "Use the :focus-within pseudo-selector in CSS", "author": "Jonathan Neal ", "license": "CC0-1.0", @@ -8,10 +8,12 @@ "homepage": "https://github.com/jonathantneal/postcss-focus-within#readme", "bugs": "https://github.com/jonathantneal/postcss-focus-within/issues", "main": "index.cjs.js", - "module": "index.es.js", + "module": "index.es.mjs", "files": [ "index.cjs.js", - "index.es.js" + "index.cjs.js.map", + "index.es.mjs", + "index.es.mjs.map" ], "scripts": { "prepublishOnly": "npm test", @@ -21,21 +23,21 @@ "test:tape": "postcss-tape" }, "engines": { - "node": ">=4.0.0" + "node": ">=6.0.0" }, "dependencies": { "postcss": "^7.0.2" }, "devDependencies": { - "babel-core": "^6.26.3", - "babel-eslint": "^8.2.3", - "babel-preset-env": "^1.7.0", - "eslint": "^4.19.1", + "@babel/core": "^7.0.0", + "@babel/preset-env": "^7.0.0", + "babel-eslint": "^9.0.0", + "eslint": "^5.6.0", "eslint-config-dev": "2.0.0", "postcss-tape": "2.2.0", "pre-commit": "^1.2.2", - "rollup": "^0.60.1", - "rollup-plugin-babel": "^3.0.4" + "rollup": "^0.66.0", + "rollup-plugin-babel": "^4.0.1" }, "eslintConfig": { "extends": "dev", From 9ff821af0d9f8af6d60e0e7adb6eaa29488c176f Mon Sep 17 00:00:00 2001 From: Jonathan Neal Date: Tue, 18 Sep 2018 00:10:57 -0400 Subject: [PATCH 694/795] 6.0.0 --- .appveyor.yml | 18 ------ .gitignore | 3 +- .rollup.js | 6 +- .travis.yml | 2 +- CHANGELOG.md | 6 ++ INSTALL.md | 172 ++++++++++++++++++++++++++++++++++++++++++++++++++ README.md | 115 ++++----------------------------- package.json | 24 +++---- 8 files changed, 207 insertions(+), 139 deletions(-) delete mode 100644 .appveyor.yml create mode 100644 INSTALL.md diff --git a/.appveyor.yml b/.appveyor.yml deleted file mode 100644 index acbf8a5eeb..0000000000 --- a/.appveyor.yml +++ /dev/null @@ -1,18 +0,0 @@ -# https://www.appveyor.com/docs/appveyor-yml - -environment: - matrix: - - nodejs_version: 4 - -version: "{build}" -build: off -deploy: off - -install: - - ps: Install-Product node $env:nodejs_version - - npm install --ignore-scripts - -test_script: - - node --version - - npm --version - - cmd: "npm test" diff --git a/.gitignore b/.gitignore index de73e5a338..d920b78fec 100644 --- a/.gitignore +++ b/.gitignore @@ -1,10 +1,9 @@ node_modules -index.*.js +index.*.* package-lock.json *.log* *.result.css .* -!.appveyor.yml !.editorconfig !.gitignore !.rollup.js diff --git a/.rollup.js b/.rollup.js index 0436758216..ebe39f9220 100644 --- a/.rollup.js +++ b/.rollup.js @@ -3,13 +3,13 @@ import babel from 'rollup-plugin-babel'; export default { input: 'index.js', output: [ - { file: 'index.cjs.js', format: 'cjs' }, - { file: 'index.es.js', format: 'es' } + { file: 'index.cjs.js', format: 'cjs', sourcemap: true }, + { file: 'index.es.mjs', format: 'es', sourcemap: true } ], plugins: [ babel({ presets: [ - ['env', { modules: false, targets: { node: 4 } }] + ['@babel/env', { modules: false, targets: { node: 6 } }] ] }) ] diff --git a/.travis.yml b/.travis.yml index c56466446c..e1f11a52e6 100644 --- a/.travis.yml +++ b/.travis.yml @@ -3,7 +3,7 @@ language: node_js node_js: - - 4 + - 6 install: - npm install --ignore-scripts diff --git a/CHANGELOG.md b/CHANGELOG.md index 2f24843fbd..42c7cde769 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,11 @@ # Changes to PostCSS Pseudo Class Any Link +### 6.0.0 (September 17, 2018) + +- Updated: Support for PostCSS v7+ +- Updated: Support for Node v6+ +- Updated: PostCSS Selector Parser 5.0.0-rc.3 (major) + ### 5.0.0 (May 7, 2018) - Updated: `postcss-selector-parser` to v4.0.0 (major) diff --git a/INSTALL.md b/INSTALL.md new file mode 100644 index 0000000000..1222194f11 --- /dev/null +++ b/INSTALL.md @@ -0,0 +1,172 @@ +# Installing PostCSS + +[PostCSS Pseudo Class Any Link] runs in all Node environments, with special +instructions for: + +| [Node](#node) | [PostCSS CLI](#postcss-cli) | [Webpack](#webpack) | [Create React App](#create-react-app) | [Gulp](#gulp) | [Grunt](#grunt) | +| --- | --- | --- | --- | --- | --- | + +## Node + +Add [PostCSS Pseudo Class Any Link] to your project: + +```bash +npm install postcss-pseudo-class-any-link --save-dev +``` + +Use [PostCSS Pseudo Class Any Link] to process your CSS: + +```js +const postcssPseudoClassAnyLink = require('postcss-pseudo-class-any-link'); + +postcssPseudoClassAnyLink.process(YOUR_CSS /*, processOptions, pluginOptions */); +``` + +Or use it as a [PostCSS] plugin: + +```js +const postcss = require('postcss'); +const postcssPseudoClassAnyLink = require('postcss-pseudo-class-any-link'); + +postcss([ + postcssPseudoClassAnyLink(/* pluginOptions */) +]).process(YOUR_CSS /*, processOptions */); +``` + +## PostCSS CLI + +Add [PostCSS CLI] to your project: + +```bash +npm install postcss-cli --save-dev +``` + +Use [PostCSS Pseudo Class Any Link] in your `postcss.config.js` configuration +file: + +```js +const postcssPseudoClassAnyLink = require('postcss-pseudo-class-any-link'); + +module.exports = { + plugins: [ + postcssPseudoClassAnyLink(/* pluginOptions */) + ] +} +``` + +## Webpack + +Add [PostCSS Loader] to your project: + +```bash +npm install postcss-loader --save-dev +``` + +Use [PostCSS Pseudo Class Any Link] in your Webpack configuration: + +```js +const postcssPseudoClassAnyLink = require('postcss-pseudo-class-any-link'); + +module.exports = { + module: { + rules: [ + { + test: /\.css$/, + use: [ + 'style-loader', + { loader: 'css-loader', options: { importLoaders: 1 } }, + { loader: 'postcss-loader', options: { + ident: 'postcss', + plugins: () => [ + postcssPseudoClassAnyLink(/* pluginOptions */) + ] + } } + ] + } + ] + } +} +``` + +## Create React App + +Add [React App Rewired] and [React App Rewire PostCSS] to your project: + +```bash +npm install react-app-rewired react-app-rewire-postcss --save-dev +``` + +Use [React App Rewire PostCSS] and [PostCSS Pseudo Class Any Link] in your +`config-overrides.js` file: + +```js +const reactAppRewirePostcss = require('react-app-rewire-postcss'); +const postcssPseudoClassAnyLink = require('postcss-pseudo-class-any-link'); + +module.exports = config => reactAppRewirePostcss(config, { + plugins: () => [ + postcssPseudoClassAnyLink(/* pluginOptions */) + ] +}); +``` + +## Gulp + +Add [Gulp PostCSS] to your project: + +```bash +npm install gulp-postcss --save-dev +``` + +Use [PostCSS Pseudo Class Any Link] in your Gulpfile: + +```js +const postcss = require('gulp-postcss'); +const postcssPseudoClassAnyLink = require('postcss-pseudo-class-any-link'); + +gulp.task('css', () => gulp.src('./src/*.css').pipe( + postcss([ + postcssPseudoClassAnyLink(/* pluginOptions */) + ]) +).pipe( + gulp.dest('.') +)); +``` + +## Grunt + +Add [Grunt PostCSS] to your project: + +```bash +npm install grunt-postcss --save-dev +``` + +Use [PostCSS Pseudo Class Any Link] in your Gruntfile: + +```js +const postcssPseudoClassAnyLink = require('postcss-pseudo-class-any-link'); + +grunt.loadNpmTasks('grunt-postcss'); + +grunt.initConfig({ + postcss: { + options: { + use: [ + postcssPseudoClassAnyLink(/* pluginOptions */) + ] + }, + dist: { + src: '*.css' + } + } +}); +``` + +[Gulp PostCSS]: https://github.com/postcss/gulp-postcss +[Grunt PostCSS]: https://github.com/nDmitry/grunt-postcss +[PostCSS]: https://github.com/postcss/postcss +[PostCSS CLI]: https://github.com/postcss/postcss-cli +[PostCSS Loader]: https://github.com/postcss/postcss-loader +[PostCSS Pseudo Class Any Link]: https://github.com/jonathantneal/postcss-pseudo-class-any-link +[React App Rewire PostCSS]: https://github.com/csstools/react-app-rewire-postcss +[React App Rewired]: https://github.com/timarney/react-app-rewired diff --git a/README.md b/README.md index 96b8a5cf7e..f8c66d62c1 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,6 @@ [![NPM Version][npm-img]][npm-url] [![CSS Standard Status][css-img]][css-url] [![Build Status][cli-img]][cli-url] -[![Windows Build Status][win-img]][win-url] [![Support Chat][git-img]][git-url] [PostCSS Pseudo Class Any Link] lets you `:any-link` pseudo-class in CSS, @@ -33,126 +32,36 @@ From the [proposal][Selectors]: ## Usage -Add [PostCSS Pseudo Class Any Link] to your build tool: +Add [PostCSS Pseudo Class Any Link] to your project: ```bash npm install postcss-pseudo-class-any-link --save-dev ``` -#### Node - Use [PostCSS Pseudo Class Any Link] to process your CSS: ```js -import postcssPseudoClassAnyLink from 'postcss-pseudo-class-any-link'; - -postcssPseudoClassAnyLink.process(YOUR_CSS, /* processOptions */, /* pluginOptions */); -``` - -#### PostCSS +const postcssPseudoClassAnyLink = require('postcss-pseudo-class-any-link'); -Add [PostCSS] to your build tool: - -```bash -npm install postcss --save-dev +postcssPseudoClassAnyLink.process(YOUR_CSS /*, processOptions, pluginOptions */); ``` -Use [PostCSS Pseudo Class Any Link] as a plugin: +Or use it as a [PostCSS] plugin: ```js -import postcss from 'gulp-postcss'; -import postcssPseudoClassAnyLink from 'postcss-pseudo-class-any-link'; +const postcss = require('postcss'); +const postcssPseudoClassAnyLink = require('postcss-pseudo-class-any-link'); postcss([ postcssPseudoClassAnyLink(/* pluginOptions */) -]).process(YOUR_CSS); -``` - -#### Webpack - -Add [PostCSS Loader] to your build tool: - -```bash -npm install postcss-loader --save-dev -``` - -Use [PostCSS Pseudo Class Any Link] in your Webpack configuration: - -```js -import postcssPseudoClassAnyLink from 'postcss-pseudo-class-any-link'; - -module.exports = { - module: { - rules: [ - { - test: /\.css$/, - use: [ - 'style-loader', - { loader: 'css-loader', options: { importLoaders: 1 } }, - { loader: 'postcss-loader', options: { - ident: 'postcss', - plugins: () => [ - postcssPseudoClassAnyLink(/* pluginOptions */) - ] - } } - ] - } - ] - } -} +]).process(YOUR_CSS /*, processOptions */); ``` -#### Gulp +[PostCSS Pseudo Class Any Link] runs in all Node environments, with special +instructions for: -Add [Gulp PostCSS] to your build tool: - -```bash -npm install gulp-postcss --save-dev -``` - -Use [PostCSS Pseudo Class Any Link] in your Gulpfile: - -```js -import postcss from 'gulp-postcss'; -import postcssPseudoClassAnyLink from 'postcss-pseudo-class-any-link'; - -gulp.task('css', () => gulp.src('./src/*.css').pipe( - postcss([ - postcssPseudoClassAnyLink(/* pluginOptions */) - ]) -).pipe( - gulp.dest('.') -)); -``` - -#### Grunt - -Add [Grunt PostCSS] to your build tool: - -```bash -npm install grunt-postcss --save-dev -``` - -Use [PostCSS Pseudo Class Any Link] in your Gruntfile: - -```js -import postcssPseudoClassAnyLink from 'postcss-pseudo-class-any-link'; - -grunt.loadNpmTasks('grunt-postcss'); - -grunt.initConfig({ - postcss: { - options: { - use: [ - postcssPseudoClassAnyLink(/* pluginOptions */) - ] - }, - dist: { - src: '*.css' - } - } -}); -``` +| [Node](INSTALL.md#node) | [PostCSS CLI](INSTALL.md#postcss-cli) | [Webpack](INSTALL.md#webpack) | [Create React App](INSTALL.md#create-react-app) | [Gulp](INSTALL.md#gulp) | [Grunt](INSTALL.md#grunt) | +| --- | --- | --- | --- | --- | --- | ## Options @@ -185,8 +94,6 @@ nav :link > span, nav :visited > span { [git-url]: https://gitter.im/postcss/postcss [npm-img]: https://img.shields.io/npm/v/postcss-pseudo-class-any-link.svg [npm-url]: https://www.npmjs.com/package/postcss-pseudo-class-any-link -[win-img]: https://img.shields.io/appveyor/ci/jonathantneal/postcss-pseudo-class-any-link.svg -[win-url]: https://ci.appveyor.com/project/jonathantneal/postcss-pseudo-class-any-link [Gulp PostCSS]: https://github.com/postcss/gulp-postcss [Grunt PostCSS]: https://github.com/nDmitry/grunt-postcss diff --git a/package.json b/package.json index 3f05cbdd95..35680b705f 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "postcss-pseudo-class-any-link", - "version": "5.0.0", + "version": "6.0.0", "description": "Use the :any-link pseudo-class in CSS", "author": "Jonathan Neal ", "license": "CC0-1.0", @@ -8,10 +8,12 @@ "homepage": "https://github.com/jonathantneal/postcss-pseudo-class-any-link#readme", "bugs": "https://github.com/jonathantneal/postcss-pseudo-class-any-link/issues", "main": "index.cjs.js", - "module": "index.es.js", + "module": "index.es.mjs", "files": [ "index.cjs.js", - "index.es.js" + "index.cjs.js.map", + "index.es.mjs", + "index.es.mjs.map" ], "scripts": { "prepublishOnly": "npm test", @@ -22,22 +24,22 @@ "test:tape": "postcss-tape" }, "engines": { - "node": ">=4.0.0" + "node": ">=6.0.0" }, "dependencies": { "postcss": "^7.0.2", - "postcss-selector-parser": "^4.0.0" + "postcss-selector-parser": "^5.0.0-rc.3" }, "devDependencies": { - "babel-core": "^6.26.3", - "babel-eslint": "^8.2.3", - "babel-preset-env": "^1.6.1", - "eslint": "^4.19.1", + "@babel/core": "^7.0.0", + "@babel/preset-env": "^7.0.0", + "babel-eslint": "^9.0.0", + "eslint": "^5.6.0", "eslint-config-dev": "^2.0.0", "postcss-tape": "^2.2.0", "pre-commit": "^1.2.2", - "rollup": "^0.58.2", - "rollup-plugin-babel": "^3.0.4" + "rollup": "^0.66.0", + "rollup-plugin-babel": "^4.0.1" }, "eslintConfig": { "extends": "dev", From 581ba23d7c32f472b6785fa37c6a3dd0e467b74f Mon Sep 17 00:00:00 2001 From: Jonathan Neal Date: Tue, 18 Sep 2018 00:19:14 -0400 Subject: [PATCH 695/795] 2.0.0 --- .appveyor.yml | 18 ------ .gitignore | 3 +- .rollup.js | 6 +- .travis.yml | 2 +- CHANGELOG.md | 5 ++ INSTALL.md | 172 ++++++++++++++++++++++++++++++++++++++++++++++++++ README.md | 121 ++++------------------------------- package.json | 22 ++++--- 8 files changed, 208 insertions(+), 141 deletions(-) delete mode 100644 .appveyor.yml create mode 100644 INSTALL.md diff --git a/.appveyor.yml b/.appveyor.yml deleted file mode 100644 index acbf8a5eeb..0000000000 --- a/.appveyor.yml +++ /dev/null @@ -1,18 +0,0 @@ -# https://www.appveyor.com/docs/appveyor-yml - -environment: - matrix: - - nodejs_version: 4 - -version: "{build}" -build: off -deploy: off - -install: - - ps: Install-Product node $env:nodejs_version - - npm install --ignore-scripts - -test_script: - - node --version - - npm --version - - cmd: "npm test" diff --git a/.gitignore b/.gitignore index de73e5a338..d920b78fec 100644 --- a/.gitignore +++ b/.gitignore @@ -1,10 +1,9 @@ node_modules -index.*.js +index.*.* package-lock.json *.log* *.result.css .* -!.appveyor.yml !.editorconfig !.gitignore !.rollup.js diff --git a/.rollup.js b/.rollup.js index 0436758216..ebe39f9220 100644 --- a/.rollup.js +++ b/.rollup.js @@ -3,13 +3,13 @@ import babel from 'rollup-plugin-babel'; export default { input: 'index.js', output: [ - { file: 'index.cjs.js', format: 'cjs' }, - { file: 'index.es.js', format: 'es' } + { file: 'index.cjs.js', format: 'cjs', sourcemap: true }, + { file: 'index.es.mjs', format: 'es', sourcemap: true } ], plugins: [ babel({ presets: [ - ['env', { modules: false, targets: { node: 4 } }] + ['@babel/env', { modules: false, targets: { node: 6 } }] ] }) ] diff --git a/.travis.yml b/.travis.yml index c56466446c..e1f11a52e6 100644 --- a/.travis.yml +++ b/.travis.yml @@ -3,7 +3,7 @@ language: node_js node_js: - - 4 + - 6 install: - npm install --ignore-scripts diff --git a/CHANGELOG.md b/CHANGELOG.md index c8e30c2520..85be9dc803 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,10 @@ # Changes to PostCSS Logical Properties +### 2.0.0 (September 17, 2018) + +- Updated: Support for PostCSS v7+ +- Updated: Support for Node v6+ + ### 1.1.1 (March 21, 2017) - Fix `dir` option to allow falsey value diff --git a/INSTALL.md b/INSTALL.md new file mode 100644 index 0000000000..b5b01efa55 --- /dev/null +++ b/INSTALL.md @@ -0,0 +1,172 @@ +# Installing PostCSS + +[PostCSS Logical Properties and Values] runs in all Node environments, with +special instructions for: + +| [Node](#node) | [PostCSS CLI](#postcss-cli) | [Webpack](#webpack) | [Create React App](#create-react-app) | [Gulp](#gulp) | [Grunt](#grunt) | +| --- | --- | --- | --- | --- | --- | + +## Node + +Add [PostCSS Logical Properties and Values] to your project: + +```bash +npm install postcss-logical --save-dev +``` + +Use [PostCSS Logical Properties and Values] to process your CSS: + +```js +const postcssLogical = require('postcss-logical'); + +postcssLogical.process(YOUR_CSS /*, processOptions, pluginOptions */); +``` + +Or use it as a [PostCSS] plugin: + +```js +const postcss = require('postcss'); +const postcssLogical = require('postcss-logical'); + +postcss([ + postcssLogical(/* pluginOptions */) +]).process(YOUR_CSS /*, processOptions */); +``` + +## PostCSS CLI + +Add [PostCSS CLI] to your project: + +```bash +npm install postcss-cli --save-dev +``` + +Use [PostCSS Logical Properties and Values] in your `postcss.config.js` +configuration file: + +```js +const postcssLogical = require('postcss-logical'); + +module.exports = { + plugins: [ + postcssLogical(/* pluginOptions */) + ] +} +``` + +## Webpack + +Add [PostCSS Loader] to your project: + +```bash +npm install postcss-loader --save-dev +``` + +Use [PostCSS Logical Properties and Values] in your Webpack configuration: + +```js +const postcssLogical = require('postcss-logical'); + +module.exports = { + module: { + rules: [ + { + test: /\.css$/, + use: [ + 'style-loader', + { loader: 'css-loader', options: { importLoaders: 1 } }, + { loader: 'postcss-loader', options: { + ident: 'postcss', + plugins: () => [ + postcssLogical(/* pluginOptions */) + ] + } } + ] + } + ] + } +} +``` + +## Create React App + +Add [React App Rewired] and [React App Rewire PostCSS] to your project: + +```bash +npm install react-app-rewired react-app-rewire-postcss --save-dev +``` + +Use [React App Rewire PostCSS] and [PostCSS Logical Properties and Values] in +your `config-overrides.js` file: + +```js +const reactAppRewirePostcss = require('react-app-rewire-postcss'); +const postcssLogical = require('postcss-logical'); + +module.exports = config => reactAppRewirePostcss(config, { + plugins: () => [ + postcssLogical(/* pluginOptions */) + ] +}); +``` + +## Gulp + +Add [Gulp PostCSS] to your project: + +```bash +npm install gulp-postcss --save-dev +``` + +Use [PostCSS Logical Properties and Values] in your Gulpfile: + +```js +const postcss = require('gulp-postcss'); +const postcssLogical = require('postcss-logical'); + +gulp.task('css', () => gulp.src('./src/*.css').pipe( + postcss([ + postcssLogical(/* pluginOptions */) + ]) +).pipe( + gulp.dest('.') +)); +``` + +## Grunt + +Add [Grunt PostCSS] to your project: + +```bash +npm install grunt-postcss --save-dev +``` + +Use [PostCSS Logical Properties and Values] in your Gruntfile: + +```js +const postcssLogical = require('postcss-logical'); + +grunt.loadNpmTasks('grunt-postcss'); + +grunt.initConfig({ + postcss: { + options: { + use: [ + postcssLogical(/* pluginOptions */) + ] + }, + dist: { + src: '*.css' + } + } +}); +``` + +[Gulp PostCSS]: https://github.com/postcss/gulp-postcss +[Grunt PostCSS]: https://github.com/nDmitry/grunt-postcss +[PostCSS]: https://github.com/postcss/postcss +[PostCSS CLI]: https://github.com/postcss/postcss-cli +[PostCSS Loader]: https://github.com/postcss/postcss-loader +[PostCSS Logical Properties and Values]: https://github.com/jonathantneal/postcss-logical +[React App Rewire PostCSS]: https://github.com/csstools/react-app-rewire-postcss +[React App Rewired]: https://github.com/timarney/react-app-rewired diff --git a/README.md b/README.md index cfa6f4be8d..4de166aa65 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,6 @@ [![NPM Version][npm-img]][npm-url] [![CSS Standard Status][css-img]][css-url] [![Build Status][cli-img]][cli-url] -[![Windows Build Status][win-img]][win-url] [![Support Chat][git-img]][git-url] [PostCSS Logical Properties and Values] lets you use logical, rather than @@ -138,126 +137,36 @@ require('postcss-logical')({ ## Usage -Add [PostCSS Logical Properties and Values] to your build tool: +Add [PostCSS Logical Properties and Values] to your project: ```bash npm install postcss-logical --save-dev ``` -#### Node - Use [PostCSS Logical Properties and Values] to process your CSS: ```js -import postcssLogical from 'postcss-logical'; +const postcssLogical = require('postcss-logical'); -postcssLogical.process(YOUR_CSS); +postcssLogical.process(YOUR_CSS /*, processOptions, pluginOptions */); ``` -#### PostCSS - -Add [PostCSS] to your build tool: - -```bash -npm install postcss --save-dev -``` - -Use [PostCSS Logical Properties and Values] as a plugin: +Or use it as a [PostCSS] plugin: ```js -import postcss from 'gulp-postcss'; -import postcssLogical from 'postcss-logical'; +const postcss = require('postcss'); +const postcssLogical = require('postcss-logical'); postcss([ - postcssLogical(/* options */) -]).process(YOUR_CSS); -``` - -#### Webpack - -Add [PostCSS Loader] to your build tool: - -```bash -npm install postcss-loader --save-dev + postcssLogical(/* pluginOptions */) +]).process(YOUR_CSS /*, processOptions */); ``` -Use [PostCSS Logical Properties and Values] in your Webpack configuration: - -```js -import postcssLogical from 'postcss-logical'; - -export default { - module: { - rules: [ - { - test: /\.css$/, - use: [ - 'style-loader', - { loader: 'css-loader', options: { importLoaders: 1 } }, - { loader: 'postcss-loader', options: { - ident: 'postcss', - plugins: () => [ - postcssLogical(/* options */) - ] - } } - ] - } - ] - } -} -``` - -#### Gulp - -Add [Gulp PostCSS] to your build tool: +[PostCSS Logical Properties and Values] runs in all Node environments, with +special instructions for: -```bash -npm install gulp-postcss --save-dev -``` - -Use [PostCSS Logical Properties and Values] in your Gulpfile: - -```js -import postcss from 'gulp-postcss'; -import postcssLogical from 'postcss-logical'; - -gulp.task('css', () => gulp.src('./src/*.css').pipe( - postcss([ - postcssLogical(/* options */) - ]) -).pipe( - gulp.dest('.') -)); -``` - -#### Grunt - -Add [Grunt PostCSS] to your build tool: - -```bash -npm install grunt-postcss --save-dev -``` - -Use [PostCSS Logical Properties and Values] in your Gruntfile: - -```js -import postcssLogical from 'postcss-logical'; - -grunt.loadNpmTasks('grunt-postcss'); - -grunt.initConfig({ - postcss: { - options: { - use: [ - postcssLogical(/* options */) - ] - }, - dist: { - src: '*.css' - } - } -}); -``` +| [Node](INSTALL.md#node) | [PostCSS CLI](INSTALL.md#postcss-cli) | [Webpack](INSTALL.md#webpack) | [Create React App](INSTALL.md#create-react-app) | [Gulp](INSTALL.md#gulp) | [Grunt](INSTALL.md#grunt) | +| --- | --- | --- | --- | --- | --- | ## Options @@ -276,16 +185,14 @@ before logical declarations without replacing them. By default, directional fallbacks replace logical declaration. If `preserve` is defined as `true`, then the `dir` option will be ignored. -[css-img]: https://jonathantneal.github.io/cssdb/badge/logical-properties-and-values.svg -[css-url]: https://jonathantneal.github.io/cssdb/#logical-properties-and-values +[css-img]: https://cssdb.org/badge/logical-properties-and-values.svg +[css-url]: https://cssdb.org/#logical-properties-and-values [cli-img]: https://img.shields.io/travis/jonathantneal/postcss-logical.svg [cli-url]: https://travis-ci.org/jonathantneal/postcss-logical [git-img]: https://img.shields.io/badge/support-chat-blue.svg [git-url]: https://gitter.im/postcss/postcss [npm-img]: https://img.shields.io/npm/v/postcss-logical.svg [npm-url]: https://www.npmjs.com/package/postcss-logical -[win-img]: https://img.shields.io/appveyor/ci/jonathantneal/postcss-logical.svg -[win-url]: https://ci.appveyor.com/project/jonathantneal/postcss-logical [CSS Logical Properties and Values]: https://drafts.csswg.org/css-logical/ [Gulp PostCSS]: https://github.com/postcss/gulp-postcss diff --git a/package.json b/package.json index 73778adea8..ca0aa17192 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "postcss-logical", - "version": "1.1.1", + "version": "2.0.0", "description": "Use logical properties and values in CSS", "author": "Jonathan Neal ", "license": "CC0-1.0", @@ -8,10 +8,12 @@ "homepage": "https://github.com/jonathantneal/postcss-logical#readme", "bugs": "https://github.com/jonathantneal/postcss-logical/issues", "main": "index.cjs.js", - "module": "index.es.js", + "module": "index.es.mjs", "files": [ "index.cjs.js", - "index.es.js" + "index.cjs.js.map", + "index.es.mjs", + "index.es.mjs.map" ], "scripts": { "prepublishOnly": "npm test", @@ -22,22 +24,22 @@ "test:tape": "postcss-tape" }, "engines": { - "node": ">=4.0.0" + "node": ">=6.0.0" }, "dependencies": { "postcss": "^7.0.2" }, "devDependencies": { - "babel-core": "^6.26.0", - "babel-eslint": "^8.2.2", - "babel-preset-env": "^1.6.1", + "@babel/core": "^7.0.0", + "@babel/preset-env": "^7.0.0", + "babel-eslint": "^9.0.0", "echint": "^4.0.1", - "eslint": "^4.19.0", + "eslint": "^5.6.0", "eslint-config-dev": "^2.0.0", "postcss-tape": "^2.2.0", "pre-commit": "^1.2.2", - "rollup": "^0.57.1", - "rollup-plugin-babel": "^3.0.3" + "rollup": "^0.66.0", + "rollup-plugin-babel": "^4.0.1" }, "eslintConfig": { "extends": "dev", From dc9858d78eef25cda5022d34d5558137486751cd Mon Sep 17 00:00:00 2001 From: Jonathan Neal Date: Tue, 18 Sep 2018 00:25:36 -0400 Subject: [PATCH 696/795] 2.0.0 --- .appveyor.yml | 18 ------ .gitignore | 3 +- .rollup.js | 6 +- CHANGELOG.md | 5 ++ INSTALL.md | 172 ++++++++++++++++++++++++++++++++++++++++++++++++++ README.md | 115 ++++----------------------------- package.json | 22 ++++--- 7 files changed, 204 insertions(+), 137 deletions(-) delete mode 100644 .appveyor.yml create mode 100644 INSTALL.md diff --git a/.appveyor.yml b/.appveyor.yml deleted file mode 100644 index 73f0d8fa3f..0000000000 --- a/.appveyor.yml +++ /dev/null @@ -1,18 +0,0 @@ -# https://www.appveyor.com/docs/appveyor-yml - -environment: - matrix: - - nodejs_version: 6 - -version: "{build}" -build: off -deploy: off - -install: - - ps: Install-Product node $env:nodejs_version - - npm install --ignore-scripts - -test_script: - - node --version - - npm --version - - cmd: "npm test" diff --git a/.gitignore b/.gitignore index de73e5a338..d920b78fec 100644 --- a/.gitignore +++ b/.gitignore @@ -1,10 +1,9 @@ node_modules -index.*.js +index.*.* package-lock.json *.log* *.result.css .* -!.appveyor.yml !.editorconfig !.gitignore !.rollup.js diff --git a/.rollup.js b/.rollup.js index 0436758216..ebe39f9220 100644 --- a/.rollup.js +++ b/.rollup.js @@ -3,13 +3,13 @@ import babel from 'rollup-plugin-babel'; export default { input: 'index.js', output: [ - { file: 'index.cjs.js', format: 'cjs' }, - { file: 'index.es.js', format: 'es' } + { file: 'index.cjs.js', format: 'cjs', sourcemap: true }, + { file: 'index.es.mjs', format: 'es', sourcemap: true } ], plugins: [ babel({ presets: [ - ['env', { modules: false, targets: { node: 4 } }] + ['@babel/env', { modules: false, targets: { node: 6 } }] ] }) ] diff --git a/CHANGELOG.md b/CHANGELOG.md index dc2cc1ab08..1edd8f99eb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,10 @@ # Changes to PostCSS Overflow Shorthand +### 2.0.0 (September 17, 2018) + +- Updated: Support for PostCSS v7+ +- Updated: Support for Node v6+ + ### 1.0.1 (May 8, 2018) - Fixed: Single `overflow` values previously being parsed diff --git a/INSTALL.md b/INSTALL.md new file mode 100644 index 0000000000..47e879b5fe --- /dev/null +++ b/INSTALL.md @@ -0,0 +1,172 @@ +# Installing PostCSS + +[PostCSS Overflow Shorthand] runs in all Node environments, with special +instructions for: + +| [Node](#node) | [PostCSS CLI](#postcss-cli) | [Webpack](#webpack) | [Create React App](#create-react-app) | [Gulp](#gulp) | [Grunt](#grunt) | +| --- | --- | --- | --- | --- | --- | + +## Node + +Add [PostCSS Overflow Shorthand] to your project: + +```bash +npm install postcss-overflow-shorthand --save-dev +``` + +Use [PostCSS Overflow Shorthand] to process your CSS: + +```js +const postcssOverflowShorthand = require('postcss-overflow-shorthand'); + +postcssOverflowShorthand.process(YOUR_CSS /*, processOptions, pluginOptions */); +``` + +Or use it as a [PostCSS] plugin: + +```js +const postcss = require('postcss'); +const postcssOverflowShorthand = require('postcss-overflow-shorthand'); + +postcss([ + postcssOverflowShorthand(/* pluginOptions */) +]).process(YOUR_CSS /*, processOptions */); +``` + +## PostCSS CLI + +Add [PostCSS CLI] to your project: + +```bash +npm install postcss-cli --save-dev +``` + +Use [PostCSS Overflow Shorthand] in your `postcss.config.js` configuration +file: + +```js +const postcssOverflowShorthand = require('postcss-overflow-shorthand'); + +module.exports = { + plugins: [ + postcssOverflowShorthand(/* pluginOptions */) + ] +} +``` + +## Webpack + +Add [PostCSS Loader] to your project: + +```bash +npm install postcss-loader --save-dev +``` + +Use [PostCSS Overflow Shorthand] in your Webpack configuration: + +```js +const postcssOverflowShorthand = require('postcss-overflow-shorthand'); + +module.exports = { + module: { + rules: [ + { + test: /\.css$/, + use: [ + 'style-loader', + { loader: 'css-loader', options: { importLoaders: 1 } }, + { loader: 'postcss-loader', options: { + ident: 'postcss', + plugins: () => [ + postcssOverflowShorthand(/* pluginOptions */) + ] + } } + ] + } + ] + } +} +``` + +## Create React App + +Add [React App Rewired] and [React App Rewire PostCSS] to your project: + +```bash +npm install react-app-rewired react-app-rewire-postcss --save-dev +``` + +Use [React App Rewire PostCSS] and [PostCSS Overflow Shorthand] in your +`config-overrides.js` file: + +```js +const reactAppRewirePostcss = require('react-app-rewire-postcss'); +const postcssOverflowShorthand = require('postcss-overflow-shorthand'); + +module.exports = config => reactAppRewirePostcss(config, { + plugins: () => [ + postcssOverflowShorthand(/* pluginOptions */) + ] +}); +``` + +## Gulp + +Add [Gulp PostCSS] to your project: + +```bash +npm install gulp-postcss --save-dev +``` + +Use [PostCSS Overflow Shorthand] in your Gulpfile: + +```js +const postcss = require('gulp-postcss'); +const postcssOverflowShorthand = require('postcss-overflow-shorthand'); + +gulp.task('css', () => gulp.src('./src/*.css').pipe( + postcss([ + postcssOverflowShorthand(/* pluginOptions */) + ]) +).pipe( + gulp.dest('.') +)); +``` + +## Grunt + +Add [Grunt PostCSS] to your project: + +```bash +npm install grunt-postcss --save-dev +``` + +Use [PostCSS Overflow Shorthand] in your Gruntfile: + +```js +const postcssOverflowShorthand = require('postcss-overflow-shorthand'); + +grunt.loadNpmTasks('grunt-postcss'); + +grunt.initConfig({ + postcss: { + options: { + use: [ + postcssOverflowShorthand(/* pluginOptions */) + ] + }, + dist: { + src: '*.css' + } + } +}); +``` + +[Gulp PostCSS]: https://github.com/postcss/gulp-postcss +[Grunt PostCSS]: https://github.com/nDmitry/grunt-postcss +[PostCSS]: https://github.com/postcss/postcss +[PostCSS CLI]: https://github.com/postcss/postcss-cli +[PostCSS Loader]: https://github.com/postcss/postcss-loader +[PostCSS Overflow Shorthand]: https://github.com/jonathantneal/postcss-overflow-shorthand +[React App Rewire PostCSS]: https://github.com/csstools/react-app-rewire-postcss +[React App Rewired]: https://github.com/timarney/react-app-rewired diff --git a/README.md b/README.md index e9e9ce2ef5..c53cc0d42f 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,6 @@ [![NPM Version][npm-img]][npm-url] [![CSS Standard Status][css-img]][css-url] [![Build Status][cli-img]][cli-url] -[![Windows Build Status][win-img]][win-url] [![Support Chat][git-img]][git-url] [PostCSS Overflow Shorthand] lets you use the `overflow` shorthand in CSS, @@ -25,126 +24,36 @@ html { ## Usage -Add [PostCSS Overflow Shorthand] to your build tool: +Add [PostCSS Overflow Shorthand] to your project: ```bash npm install postcss-overflow-shorthand --save-dev ``` -#### Node - Use [PostCSS Overflow Shorthand] to process your CSS: ```js -import postcssOverflowShorthand from 'postcss-overflow-shorthand'; - -postcssOverflowShorthand.process(YOUR_CSS, /* processOptions */, /* pluginOptions */); -``` - -#### PostCSS +const postcssOverflowShorthand = require('postcss-overflow-shorthand'); -Add [PostCSS] to your build tool: - -```bash -npm install postcss --save-dev +postcssOverflowShorthand.process(YOUR_CSS /*, processOptions, pluginOptions */); ``` -Use [PostCSS Overflow Shorthand] as a plugin: +Or use it as a [PostCSS] plugin: ```js -import postcss from 'gulp-postcss'; -import postcssOverflowShorthand from 'postcss-overflow-shorthand'; +const postcss = require('postcss'); +const postcssOverflowShorthand = require('postcss-overflow-shorthand'); postcss([ postcssOverflowShorthand(/* pluginOptions */) -]).process(YOUR_CSS); -``` - -#### Webpack - -Add [PostCSS Loader] to your build tool: - -```bash -npm install postcss-loader --save-dev -``` - -Use [PostCSS Overflow Shorthand] in your Webpack configuration: - -```js -import postcssOverflowShorthand from 'postcss-overflow-shorthand'; - -module.exports = { - module: { - rules: [ - { - test: /\.css$/, - use: [ - 'style-loader', - { loader: 'css-loader', options: { importLoaders: 1 } }, - { loader: 'postcss-loader', options: { - ident: 'postcss', - plugins: () => [ - postcssOverflowShorthand(/* pluginOptions */) - ] - } } - ] - } - ] - } -} +]).process(YOUR_CSS /*, processOptions */); ``` -#### Gulp +[PostCSS Overflow Shorthand] runs in all Node environments, with special +instructions for: -Add [Gulp PostCSS] to your build tool: - -```bash -npm install gulp-postcss --save-dev -``` - -Use [PostCSS Overflow Shorthand] in your Gulpfile: - -```js -import postcss from 'gulp-postcss'; -import postcssOverflowShorthand from 'postcss-overflow-shorthand'; - -gulp.task('css', () => gulp.src('./src/*.css').pipe( - postcss([ - postcssOverflowShorthand(/* pluginOptions */) - ]) -).pipe( - gulp.dest('.') -)); -``` - -#### Grunt - -Add [Grunt PostCSS] to your build tool: - -```bash -npm install grunt-postcss --save-dev -``` - -Use [PostCSS Overflow Shorthand] in your Gruntfile: - -```js -import postcssOverflowShorthand from 'postcss-overflow-shorthand'; - -grunt.loadNpmTasks('grunt-postcss'); - -grunt.initConfig({ - postcss: { - options: { - use: [ - postcssOverflowShorthand(/* pluginOptions */) - ] - }, - dist: { - src: '*.css' - } - } -}); -``` +| [Node](INSTALL.md#node) | [PostCSS CLI](INSTALL.md#postcss-cli) | [Webpack](INSTALL.md#webpack) | [Create React App](INSTALL.md#create-react-app) | [Gulp](INSTALL.md#gulp) | [Grunt](INSTALL.md#grunt) | +| --- | --- | --- | --- | --- | --- | ## Options @@ -178,8 +87,6 @@ html { [git-url]: https://gitter.im/postcss/postcss [npm-img]: https://img.shields.io/npm/v/postcss-overflow-shorthand.svg [npm-url]: https://www.npmjs.com/package/postcss-overflow-shorthand -[win-img]: https://img.shields.io/appveyor/ci/jonathantneal/postcss-overflow-shorthand.svg -[win-url]: https://ci.appveyor.com/project/jonathantneal/postcss-overflow-shorthand [CSS Overflow]: https://drafts.csswg.org/css-overflow/#propdef-overflow [Gulp PostCSS]: https://github.com/postcss/gulp-postcss diff --git a/package.json b/package.json index 9414434b91..e38d87b584 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "postcss-overflow-shorthand", - "version": "1.0.1", + "version": "2.0.0", "description": "Use the overflow shorthand in CSS", "author": "Jonathan Neal ", "license": "CC0-1.0", @@ -8,10 +8,12 @@ "homepage": "https://github.com/jonathantneal/postcss-overflow-shorthand#readme", "bugs": "https://github.com/jonathantneal/postcss-overflow-shorthand/issues", "main": "index.cjs.js", - "module": "index.es.js", + "module": "index.es.mjs", "files": [ "index.cjs.js", - "index.es.js" + "index.cjs.js.map", + "index.es.mjs", + "index.es.mjs.map" ], "scripts": { "prepublishOnly": "npm test", @@ -22,21 +24,21 @@ "test:tape": "postcss-tape" }, "engines": { - "node": ">=4.0.0" + "node": ">=6.0.0" }, "dependencies": { "postcss": "^7.0.2" }, "devDependencies": { - "babel-core": "^6.26.3", - "babel-eslint": "^8.2.3", - "babel-preset-env": "^1.6.1", - "eslint": "^4.19.1", + "@babel/core": "^7.0.0", + "@babel/preset-env": "^7.0.0", + "babel-eslint": "^9.0.0", + "eslint": "^5.6.0", "eslint-config-dev": "^2.0.0", "postcss-tape": "^2.2.0", "pre-commit": "^1.2.2", - "rollup": "^0.58.2", - "rollup-plugin-babel": "^3.0.4" + "rollup": "^0.66.0", + "rollup-plugin-babel": "^4.0.1" }, "eslintConfig": { "extends": "dev", From 5a6e848a8fe735820efd1299a74d990900ca5ba3 Mon Sep 17 00:00:00 2001 From: Jonathan Neal Date: Tue, 18 Sep 2018 00:31:26 -0400 Subject: [PATCH 697/795] 2.0.0 --- .appveyor.yml | 18 ------ .gitignore | 3 +- .rollup.js | 6 +- CHANGELOG.md | 5 ++ INSTALL.md | 172 ++++++++++++++++++++++++++++++++++++++++++++++++++ README.md | 117 ++++------------------------------ package.json | 22 ++++--- 7 files changed, 205 insertions(+), 138 deletions(-) delete mode 100644 .appveyor.yml create mode 100644 INSTALL.md diff --git a/.appveyor.yml b/.appveyor.yml deleted file mode 100644 index 73f0d8fa3f..0000000000 --- a/.appveyor.yml +++ /dev/null @@ -1,18 +0,0 @@ -# https://www.appveyor.com/docs/appveyor-yml - -environment: - matrix: - - nodejs_version: 6 - -version: "{build}" -build: off -deploy: off - -install: - - ps: Install-Product node $env:nodejs_version - - npm install --ignore-scripts - -test_script: - - node --version - - npm --version - - cmd: "npm test" diff --git a/.gitignore b/.gitignore index de73e5a338..d920b78fec 100644 --- a/.gitignore +++ b/.gitignore @@ -1,10 +1,9 @@ node_modules -index.*.js +index.*.* package-lock.json *.log* *.result.css .* -!.appveyor.yml !.editorconfig !.gitignore !.rollup.js diff --git a/.rollup.js b/.rollup.js index 0436758216..ebe39f9220 100644 --- a/.rollup.js +++ b/.rollup.js @@ -3,13 +3,13 @@ import babel from 'rollup-plugin-babel'; export default { input: 'index.js', output: [ - { file: 'index.cjs.js', format: 'cjs' }, - { file: 'index.es.js', format: 'es' } + { file: 'index.cjs.js', format: 'cjs', sourcemap: true }, + { file: 'index.es.mjs', format: 'es', sourcemap: true } ], plugins: [ babel({ presets: [ - ['env', { modules: false, targets: { node: 4 } }] + ['@babel/env', { modules: false, targets: { node: 6 } }] ] }) ] diff --git a/CHANGELOG.md b/CHANGELOG.md index 1b5f64c464..98fa94373c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,10 @@ # Changes to PostCSS Lab Function +### 2.0.0 (September 17, 2018) + +- Updated: Support for PostCSS v7+ +- Updated: Support for Node v6+ + ### 1.1.0 (July 24, 2018) - Added: Support for `gray(a / b)` as `lab(a 0 0 / b)` diff --git a/INSTALL.md b/INSTALL.md new file mode 100644 index 0000000000..74a3344c8e --- /dev/null +++ b/INSTALL.md @@ -0,0 +1,172 @@ +# Installing PostCSS + +[PostCSS Lab Function] runs in all Node environments, with special +instructions for: + +| [Node](#node) | [PostCSS CLI](#postcss-cli) | [Webpack](#webpack) | [Create React App](#create-react-app) | [Gulp](#gulp) | [Grunt](#grunt) | +| --- | --- | --- | --- | --- | --- | + +## Node + +Add [PostCSS Lab Function] to your project: + +```bash +npm install postcss-lab-function --save-dev +``` + +Use [PostCSS Lab Function] to process your CSS: + +```js +const postcssLabFunction = require('postcss-lab-function'); + +postcssLabFunction.process(YOUR_CSS /*, processOptions, pluginOptions */); +``` + +Or use it as a [PostCSS] plugin: + +```js +const postcss = require('postcss'); +const postcssLabFunction = require('postcss-lab-function'); + +postcss([ + postcssLabFunction(/* pluginOptions */) +]).process(YOUR_CSS /*, processOptions */); +``` + +## PostCSS CLI + +Add [PostCSS CLI] to your project: + +```bash +npm install postcss-cli --save-dev +``` + +Use [PostCSS Lab Function] in your `postcss.config.js` configuration +file: + +```js +const postcssLabFunction = require('postcss-lab-function'); + +module.exports = { + plugins: [ + postcssLabFunction(/* pluginOptions */) + ] +} +``` + +## Webpack + +Add [PostCSS Loader] to your project: + +```bash +npm install postcss-loader --save-dev +``` + +Use [PostCSS Lab Function] in your Webpack configuration: + +```js +const postcssLabFunction = require('postcss-lab-function'); + +module.exports = { + module: { + rules: [ + { + test: /\.css$/, + use: [ + 'style-loader', + { loader: 'css-loader', options: { importLoaders: 1 } }, + { loader: 'postcss-loader', options: { + ident: 'postcss', + plugins: () => [ + postcssLabFunction(/* pluginOptions */) + ] + } } + ] + } + ] + } +} +``` + +## Create React App + +Add [React App Rewired] and [React App Rewire PostCSS] to your project: + +```bash +npm install react-app-rewired react-app-rewire-postcss --save-dev +``` + +Use [React App Rewire PostCSS] and [PostCSS Lab Function] in your +`config-overrides.js` file: + +```js +const reactAppRewirePostcss = require('react-app-rewire-postcss'); +const postcssLabFunction = require('postcss-lab-function'); + +module.exports = config => reactAppRewirePostcss(config, { + plugins: () => [ + postcssLabFunction(/* pluginOptions */) + ] +}); +``` + +## Gulp + +Add [Gulp PostCSS] to your project: + +```bash +npm install gulp-postcss --save-dev +``` + +Use [PostCSS Lab Function] in your Gulpfile: + +```js +const postcss = require('gulp-postcss'); +const postcssLabFunction = require('postcss-lab-function'); + +gulp.task('css', () => gulp.src('./src/*.css').pipe( + postcss([ + postcssLabFunction(/* pluginOptions */) + ]) +).pipe( + gulp.dest('.') +)); +``` + +## Grunt + +Add [Grunt PostCSS] to your project: + +```bash +npm install grunt-postcss --save-dev +``` + +Use [PostCSS Lab Function] in your Gruntfile: + +```js +const postcssLabFunction = require('postcss-lab-function'); + +grunt.loadNpmTasks('grunt-postcss'); + +grunt.initConfig({ + postcss: { + options: { + use: [ + postcssLabFunction(/* pluginOptions */) + ] + }, + dist: { + src: '*.css' + } + } +}); +``` + +[Gulp PostCSS]: https://github.com/postcss/gulp-postcss +[Grunt PostCSS]: https://github.com/nDmitry/grunt-postcss +[PostCSS]: https://github.com/postcss/postcss +[PostCSS CLI]: https://github.com/postcss/postcss-cli +[PostCSS Loader]: https://github.com/postcss/postcss-loader +[PostCSS Lab Function]: https://github.com/jonathantneal/postcss-lab-function +[React App Rewire PostCSS]: https://github.com/csstools/react-app-rewire-postcss +[React App Rewired]: https://github.com/timarney/react-app-rewired diff --git a/README.md b/README.md index eb7cce72dd..79cd5806be 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,6 @@ [![NPM Version][npm-img]][npm-url] [![CSS Standard Status][css-img]][css-url] [![Build Status][cli-img]][cli-url] -[![Windows Build Status][win-img]][win-url] [![Support Chat][git-img]][git-url] [PostCSS Lab Function] lets you use `lab`, `lch`, and `gray` color functions in @@ -29,126 +28,36 @@ CSS, following the [CSS Color] specification. ## Usage -Add [PostCSS Lab Function] to your build tool: +Add [PostCSS Lab Function] to your project: ```bash npm install postcss-lab-function --save-dev ``` -#### Node - Use [PostCSS Lab Function] to process your CSS: ```js -import postcssLabFunction from 'postcss-lab-function'; - -postcssLabFunction.process(YOUR_CSS, /* processOptions */, /* pluginOptions */); -``` - -#### PostCSS +const postcssLabFunction = require('postcss-lab-function'); -Add [PostCSS] to your build tool: - -```bash -npm install postcss --save-dev +postcssLabFunction.process(YOUR_CSS /*, processOptions, pluginOptions */); ``` -Use [PostCSS Lab Function] as a plugin: +Or use it as a [PostCSS] plugin: ```js -import postcss from 'gulp-postcss'; -import postcssLabFunction from 'postcss-lab-function'; +const postcss = require('postcss'); +const postcssLabFunction = require('postcss-lab-function'); postcss([ postcssLabFunction(/* pluginOptions */) -]).process(YOUR_CSS); -``` - -#### Webpack - -Add [PostCSS Loader] to your build tool: - -```bash -npm install postcss-loader --save-dev -``` - -Use [PostCSS Lab Function] in your Webpack configuration: - -```js -import postcssLabFunction from 'postcss-lab-function'; - -module.exports = { - module: { - rules: [ - { - test: /\.css$/, - use: [ - 'style-loader', - { loader: 'css-loader', options: { importLoaders: 1 } }, - { loader: 'postcss-loader', options: { - ident: 'postcss', - plugins: () => [ - postcssLabFunction(/* pluginOptions */) - ] - } } - ] - } - ] - } -} +]).process(YOUR_CSS /*, processOptions */); ``` -#### Gulp +[PostCSS Lab Function] runs in all Node environments, with special +instructions for: -Add [Gulp PostCSS] to your build tool: - -```bash -npm install gulp-postcss --save-dev -``` - -Use [PostCSS Lab Function] in your Gulpfile: - -```js -import postcss from 'gulp-postcss'; -import postcssLabFunction from 'postcss-lab-function'; - -gulp.task('css', () => gulp.src('./src/*.css').pipe( - postcss([ - postcssLabFunction(/* pluginOptions */) - ]) -).pipe( - gulp.dest('.') -)); -``` - -#### Grunt - -Add [Grunt PostCSS] to your build tool: - -```bash -npm install grunt-postcss --save-dev -``` - -Use [PostCSS Lab Function] in your Gruntfile: - -```js -import postcssLabFunction from 'postcss-lab-function'; - -grunt.loadNpmTasks('grunt-postcss'); - -grunt.initConfig({ - postcss: { - options: { - use: [ - postcssLabFunction(/* pluginOptions */) - ] - }, - dist: { - src: '*.css' - } - } -}); -``` +| [Node](INSTALL.md#node) | [PostCSS CLI](INSTALL.md#postcss-cli) | [Webpack](INSTALL.md#webpack) | [Create React App](INSTALL.md#create-react-app) | [Gulp](INSTALL.md#gulp) | [Grunt](INSTALL.md#grunt) | +| --- | --- | --- | --- | --- | --- | ## Options @@ -158,7 +67,7 @@ The `preserve` option determines whether the original functional color notation is preserved. By default, it is not preserved. ```js -postcssImageSetFunction({ preserve: true }) +postcssLabFunction({ preserve: true }) ``` ```pcss @@ -185,8 +94,6 @@ postcssImageSetFunction({ preserve: true }) [git-url]: https://gitter.im/postcss/postcss [npm-img]: https://img.shields.io/npm/v/postcss-lab-function.svg [npm-url]: https://www.npmjs.com/package/postcss-lab-function -[win-img]: https://img.shields.io/appveyor/ci/jonathantneal/postcss-lab-function.svg -[win-url]: https://ci.appveyor.com/project/jonathantneal/postcss-lab-function [CSS Color]: https://drafts.csswg.org/css-color/#specifying-lab-lch [Gulp PostCSS]: https://github.com/postcss/gulp-postcss diff --git a/package.json b/package.json index 5bbd02c5d6..77db8039a1 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "postcss-lab-function", - "version": "1.1.0", + "version": "2.0.0", "description": "Use lab() and lch() color functions in CSS", "author": "Jonathan Neal ", "license": "CC0-1.0", @@ -8,10 +8,12 @@ "homepage": "https://github.com/jonathantneal/postcss-lab-function#readme", "bugs": "https://github.com/jonathantneal/postcss-lab-function/issues", "main": "index.cjs.js", - "module": "index.es.js", + "module": "index.es.mjs", "files": [ "index.cjs.js", - "index.es.js" + "index.cjs.js.map", + "index.es.mjs", + "index.es.mjs.map" ], "scripts": { "prepublishOnly": "npm test", @@ -22,7 +24,7 @@ "test:tape": "postcss-tape" }, "engines": { - "node": ">=4.0.0" + "node": ">=6.0.0" }, "dependencies": { "@csstools/convert-colors": "^1.4.0", @@ -30,15 +32,15 @@ "postcss-values-parser": "^1.5.0" }, "devDependencies": { - "babel-core": "^6.26.3", - "babel-eslint": "^8.2.6", - "babel-preset-env": "^1.7.0", - "eslint": "^5.2.0", + "@babel/core": "^7.0.0", + "@babel/preset-env": "^7.0.0", + "babel-eslint": "^9.0.0", + "eslint": "^5.6.0", "eslint-config-dev": "^2.0.0", "postcss-tape": "^2.2.0", "pre-commit": "^1.2.2", - "rollup": "^0.63.4", - "rollup-plugin-babel": "^3.0.7" + "rollup": "^0.66.0", + "rollup-plugin-babel": "^4.0.1" }, "eslintConfig": { "extends": "dev", From 87c6d347d24798d9aa8e1917986ceac45377a059 Mon Sep 17 00:00:00 2001 From: Jonathan Neal Date: Tue, 18 Sep 2018 00:38:50 -0400 Subject: [PATCH 698/795] 7.0.0 --- .appveyor.yml | 18 ------------------ .gitignore | 3 +-- .rollup.js | 6 +++--- CHANGELOG.md | 9 +++++++++ INSTALL.md | 25 +++++++++++++++++++++++-- README.md | 2 +- package.json | 14 +++++++------- 7 files changed, 44 insertions(+), 33 deletions(-) delete mode 100644 .appveyor.yml diff --git a/.appveyor.yml b/.appveyor.yml deleted file mode 100644 index 73f0d8fa3f..0000000000 --- a/.appveyor.yml +++ /dev/null @@ -1,18 +0,0 @@ -# https://www.appveyor.com/docs/appveyor-yml - -environment: - matrix: - - nodejs_version: 6 - -version: "{build}" -build: off -deploy: off - -install: - - ps: Install-Product node $env:nodejs_version - - npm install --ignore-scripts - -test_script: - - node --version - - npm --version - - cmd: "npm test" diff --git a/.gitignore b/.gitignore index de73e5a338..d920b78fec 100644 --- a/.gitignore +++ b/.gitignore @@ -1,10 +1,9 @@ node_modules -index.*.js +index.*.* package-lock.json *.log* *.result.css .* -!.appveyor.yml !.editorconfig !.gitignore !.rollup.js diff --git a/.rollup.js b/.rollup.js index 1d581cace5..f50894443a 100644 --- a/.rollup.js +++ b/.rollup.js @@ -3,8 +3,8 @@ import babel from 'rollup-plugin-babel'; export default { input: 'index.js', output: [ - { file: 'index.cjs.js', format: 'cjs' }, - { file: 'index.es.js', format: 'es' } + { file: 'index.cjs.js', format: 'cjs', sourcemap: true }, + { file: 'index.es.mjs', format: 'es', sourcemap: true } ], plugins: [ babel({ @@ -12,7 +12,7 @@ export default { 'array-includes' ], presets: [ - ['env', { modules: false, targets: { node: 6 } }] + ['@babel/env', { modules: false, targets: { node: 6 } }] ] }) ] diff --git a/CHANGELOG.md b/CHANGELOG.md index 5a125aa8a5..14def81ef7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,14 @@ # Changes to PostCSS Nesting +### 7.0.0 (September 17, 2018) + +- Updated: Support for PostCSS v7+ +- Updated: Support for Node v6+ + +In a comment, a CSSWG member expressed interest in handling nested `@media` +while handling selector nesting. Since the specification has yet to be added +to the official CSSWG repository, nested at-rule deprecation is further delayed. + ### 6.0.0 (June 9, 2018) - Deprecated: Nested at-rules like `@media` will no longer work in 7.0.0 diff --git a/INSTALL.md b/INSTALL.md index 45ae189c2c..94a59037e3 100644 --- a/INSTALL.md +++ b/INSTALL.md @@ -2,8 +2,8 @@ [PostCSS Nesting] runs in all Node environments, with special instructions for: -| [Node](#node) | [Webpack](#webpack) | [Create React App](#create-react-app) | [Gulp](#gulp) | [Grunt](#grunt) | -| --- | --- | --- | --- | --- | +| [Node](#node) | [PostCSS CLI](#postcss-cli) | [Webpack](#webpack) | [Create React App](#create-react-app) | [Gulp](#gulp) | [Grunt](#grunt) | +| --- | --- | --- | --- | --- | --- | ## Node @@ -32,6 +32,26 @@ postcss([ ]).process(YOUR_CSS /*, processOptions */); ``` +## PostCSS CLI + +Add [PostCSS CLI] to your project: + +```bash +npm install postcss-cli --save-dev +``` + +Use [PostCSS Nesting] in your `postcss.config.js` configuration file: + +```js +const postcssNesting = require('postcss-nesting'); + +module.exports = { + plugins: [ + postcssNesting(/* pluginOptions */) + ] +} +``` + ## Webpack Add [PostCSS Loader] to your project: @@ -143,6 +163,7 @@ grunt.initConfig({ [Gulp PostCSS]: https://github.com/postcss/gulp-postcss [Grunt PostCSS]: https://github.com/nDmitry/grunt-postcss [PostCSS]: https://github.com/postcss/postcss +[PostCSS CLI]: https://github.com/postcss/postcss-cli [PostCSS Loader]: https://github.com/postcss/postcss-loader [PostCSS Nesting]: https://github.com/jonathantneal/postcss-nesting [React App Rewire PostCSS]: https://github.com/csstools/react-app-rewire-postcss diff --git a/README.md b/README.md index c138919389..9f306c92e6 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ # PostCSS Nesting [PostCSS][postcss] -[![CSS Standard Status][css-img]][css-url] [![NPM Version][npm-img]][npm-url] +[![CSS Standard Status][css-img]][css-url] [![Build Status][cli-img]][cli-url] [![Support Chat][git-img]][git-url] diff --git a/package.json b/package.json index 15bea0b0a7..24a4ba8eca 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "postcss-nesting", - "version": "6.0.0", + "version": "7.0.0", "description": "Nest style rules inside each other", "author": "Jonathan Neal ", "license": "CC0-1.0", @@ -27,16 +27,16 @@ "postcss": "^7.0.2" }, "devDependencies": { - "babel-core": "^6.26.3", - "babel-eslint": "^8.2.3", + "@babel/core": "^7.0.0", + "@babel/preset-env": "^7.0.0", + "babel-eslint": "^9.0.0", "babel-plugin-array-includes": "^2.0.3", - "babel-preset-env": "^1.7.0", - "eslint": "^4.19.1", + "eslint": "^5.6.0", "eslint-config-dev": "^2.0.0", "postcss-tape": "^2.2.0", "pre-commit": "^1.2.2", - "rollup": "^0.60.1", - "rollup-plugin-babel": "^3.0.4" + "rollup": "^0.66.0", + "rollup-plugin-babel": "^4.0.1" }, "eslintConfig": { "extends": "dev", From 170ce78c1b78dee3b5138f5b4e0734dd0bd8e901 Mon Sep 17 00:00:00 2001 From: Jonathan Neal Date: Tue, 18 Sep 2018 00:45:35 -0400 Subject: [PATCH 699/795] 2.0.0 --- .appveyor.yml | 18 ------ .gitignore | 3 +- .rollup.js | 6 +- .travis.yml | 2 +- CHANGELOG.md | 5 ++ INSTALL.md | 170 ++++++++++++++++++++++++++++++++++++++++++++++++++ README.md | 110 +++----------------------------- package.json | 22 ++++--- 8 files changed, 200 insertions(+), 136 deletions(-) delete mode 100644 .appveyor.yml create mode 100644 INSTALL.md diff --git a/.appveyor.yml b/.appveyor.yml deleted file mode 100644 index acbf8a5eeb..0000000000 --- a/.appveyor.yml +++ /dev/null @@ -1,18 +0,0 @@ -# https://www.appveyor.com/docs/appveyor-yml - -environment: - matrix: - - nodejs_version: 4 - -version: "{build}" -build: off -deploy: off - -install: - - ps: Install-Product node $env:nodejs_version - - npm install --ignore-scripts - -test_script: - - node --version - - npm --version - - cmd: "npm test" diff --git a/.gitignore b/.gitignore index de73e5a338..d920b78fec 100644 --- a/.gitignore +++ b/.gitignore @@ -1,10 +1,9 @@ node_modules -index.*.js +index.*.* package-lock.json *.log* *.result.css .* -!.appveyor.yml !.editorconfig !.gitignore !.rollup.js diff --git a/.rollup.js b/.rollup.js index 0436758216..ebe39f9220 100644 --- a/.rollup.js +++ b/.rollup.js @@ -3,13 +3,13 @@ import babel from 'rollup-plugin-babel'; export default { input: 'index.js', output: [ - { file: 'index.cjs.js', format: 'cjs' }, - { file: 'index.es.js', format: 'es' } + { file: 'index.cjs.js', format: 'cjs', sourcemap: true }, + { file: 'index.es.mjs', format: 'es', sourcemap: true } ], plugins: [ babel({ presets: [ - ['env', { modules: false, targets: { node: 4 } }] + ['@babel/env', { modules: false, targets: { node: 6 } }] ] }) ] diff --git a/.travis.yml b/.travis.yml index c56466446c..e1f11a52e6 100644 --- a/.travis.yml +++ b/.travis.yml @@ -3,7 +3,7 @@ language: node_js node_js: - - 4 + - 6 install: - npm install --ignore-scripts diff --git a/CHANGELOG.md b/CHANGELOG.md index 81c24bbdb6..496ce59521 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,10 @@ # Changes to PostCSS Gap Properties +### 2.0.0 (September 17, 2018) + +- Updated: Support for PostCSS v7+ +- Updated: Support for Node v6+ + ### 1.0.0 (April 30, 2018) - Initial version diff --git a/INSTALL.md b/INSTALL.md new file mode 100644 index 0000000000..1abbd7c864 --- /dev/null +++ b/INSTALL.md @@ -0,0 +1,170 @@ +# Installing PostCSS Gap Properties + +[PostCSS Gap Properties] runs in all Node environments, with special instructions for: + +| [Node](#node) | [PostCSS CLI](#postcss-cli) | [Webpack](#webpack) | [Create React App](#create-react-app) | [Gulp](#gulp) | [Grunt](#grunt) | +| --- | --- | --- | --- | --- | --- | + +## Node + +Add [PostCSS Gap Properties] to your project: + +```bash +npm install postcss-gap-properties --save-dev +``` + +Use [PostCSS Gap Properties] to process your CSS: + +```js +import postcssGapProperties from 'postcss-gap-properties'; + +postcssGapProperties.process(YOUR_CSS /*, processOptions, pluginOptions */); +``` + +Or use it as a [PostCSS] plugin: + +```js +import postcss from 'postcss'; +import postcssGapProperties from 'postcss-gap-properties'; + +postcss([ + postcssGapProperties(/* pluginOptions */) +]).process(YOUR_CSS /*, processOptions */); +``` + +## PostCSS CLI + +Add [PostCSS CLI] to your project: + +```bash +npm install postcss-cli --save-dev +``` + +Use [PostCSS Gap Properties] in your `postcss.config.js` configuration file: + +```js +const postcssGapProperties = require('postcss-gap-properties'); + +module.exports = { + plugins: [ + postcssGapProperties(/* pluginOptions */) + ] +} +``` + +## Webpack + +Add [PostCSS Loader] to your project: + +```bash +npm install postcss-loader --save-dev +``` + +Use [PostCSS Gap Properties] in your Webpack configuration: + +```js +import postcssGapProperties from 'postcss-gap-properties'; + +module.exports = { + module: { + rules: [ + { + test: /\.css$/, + use: [ + 'style-loader', + { loader: 'css-loader', options: { importLoaders: 1 } }, + { loader: 'postcss-loader', options: { + ident: 'postcss', + plugins: () => [ + postcssGapProperties(/* pluginOptions */) + ] + } } + ] + } + ] + } +} +``` + +## Create React App + +Add [React App Rewired] and [React App Rewire PostCSS] to your project: + +```bash +npm install react-app-rewired react-app-rewire-postcss --save-dev +``` + +Use [React App Rewire PostCSS] and [PostCSS Gap Properties] in your +`config-overrides.js` file: + +```js +import reactAppRewirePostcss from 'react-app-rewire-postcss'; +import postcssGapProperties from 'postcss-gap-properties'; + +export default config => reactAppRewirePostcss(config, { + plugins: () => [ + postcssGapProperties(/* pluginOptions */) + ] +}); +``` + +## Gulp + +Add [Gulp PostCSS] to your project: + +```bash +npm install gulp-postcss --save-dev +``` + +Use [PostCSS Gap Properties] in your Gulpfile: + +```js +import postcss from 'gulp-postcss'; +import postcssGapProperties from 'postcss-gap-properties'; + +gulp.task('css', () => gulp.src('./src/*.css').pipe( + postcss([ + postcssGapProperties(/* pluginOptions */) + ]) +).pipe( + gulp.dest('.') +)); +``` + +## Grunt + +Add [Grunt PostCSS] to your project: + +```bash +npm install grunt-postcss --save-dev +``` + +Use [PostCSS Gap Properties] in your Gruntfile: + +```js +import postcssGapProperties from 'postcss-gap-properties'; + +grunt.loadNpmTasks('grunt-postcss'); + +grunt.initConfig({ + postcss: { + options: { + use: [ + postcssGapProperties(/* pluginOptions */) + ] + }, + dist: { + src: '*.css' + } + } +}); +``` + +[Gulp PostCSS]: https://github.com/postcss/gulp-postcss +[Grunt PostCSS]: https://github.com/nDmitry/grunt-postcss +[PostCSS]: https://github.com/postcss/postcss +[PostCSS CLI]: https://github.com/postcss/postcss-cli +[PostCSS Loader]: https://github.com/postcss/postcss-loader +[PostCSS Gap Properties]: https://github.com/jonathantneal/postcss-gap-properties +[React App Rewire PostCSS]: https://github.com/csstools/react-app-rewire-postcss +[React App Rewired]: https://github.com/timarney/react-app-rewired diff --git a/README.md b/README.md index fc4451547f..6fb911121f 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,6 @@ [![NPM Version][npm-img]][npm-url] [![CSS Standard Status][css-img]][css-url] [![Build Status][cli-img]][cli-url] -[![Windows Build Status][win-img]][win-url] [![Support Chat][git-img]][git-url] [PostCSS Gap Properties] lets you use the `gap`, `column-gap`, and `row-gap` @@ -36,126 +35,35 @@ shorthand properties in CSS, following the [CSS Grid Layout] specification. ## Usage -Add [PostCSS Gap Properties] to your build tool: +Add [PostCSS Gap Properties] to your project: ```bash npm install postcss-gap-properties --save-dev ``` -#### Node - Use [PostCSS Gap Properties] to process your CSS: ```js import postcssGapProperties from 'postcss-gap-properties'; -postcssGapProperties.process(YOUR_CSS, /* processOptions */, /* pluginOptions */); -``` - -#### PostCSS - -Add [PostCSS] to your build tool: - -```bash -npm install postcss --save-dev +postcssGapProperties.process(YOUR_CSS /*, processOptions, pluginOptions */); ``` -Use [PostCSS Gap Properties] as a plugin: +Or use it as a [PostCSS] plugin: ```js -import postcss from 'gulp-postcss'; +import postcss from 'postcss'; import postcssGapProperties from 'postcss-gap-properties'; postcss([ postcssGapProperties(/* pluginOptions */) -]).process(YOUR_CSS); -``` - -#### Webpack - -Add [PostCSS Loader] to your build tool: - -```bash -npm install postcss-loader --save-dev -``` - -Use [PostCSS Gap Properties] in your Webpack configuration: - -```js -import postcssGapProperties from 'postcss-gap-properties'; - -module.exports = { - module: { - rules: [ - { - test: /\.css$/, - use: [ - 'style-loader', - { loader: 'css-loader', options: { importLoaders: 1 } }, - { loader: 'postcss-loader', options: { - ident: 'postcss', - plugins: () => [ - postcssGapProperties(/* pluginOptions */) - ] - } } - ] - } - ] - } -} -``` - -#### Gulp - -Add [Gulp PostCSS] to your build tool: - -```bash -npm install gulp-postcss --save-dev -``` - -Use [PostCSS Gap Properties] in your Gulpfile: - -```js -import postcss from 'gulp-postcss'; -import postcssGapProperties from 'postcss-gap-properties'; - -gulp.task('css', () => gulp.src('./src/*.css').pipe( - postcss([ - postcssGapProperties(/* pluginOptions */) - ]) -).pipe( - gulp.dest('.') -)); +]).process(YOUR_CSS /*, processOptions */); ``` -#### Grunt +[PostCSS Gap Properties] runs in all Node environments, with special instructions for: -Add [Grunt PostCSS] to your build tool: - -```bash -npm install grunt-postcss --save-dev -``` - -Use [PostCSS Gap Properties] in your Gruntfile: - -```js -import postcssGapProperties from 'postcss-gap-properties'; - -grunt.loadNpmTasks('grunt-postcss'); - -grunt.initConfig({ - postcss: { - options: { - use: [ - postcssGapProperties(/* pluginOptions */) - ] - }, - dist: { - src: '*.css' - } - } -}); -``` +| [Node](INSTALL.md#node) | [Webpack](INSTALL.md#webpack) | [Create React App](INSTALL.md#create-react-app) | [Gulp](INSTALL.md#gulp) | [Grunt](INSTALL.md#grunt) | +| --- | --- | --- | --- | --- | ## Options @@ -172,8 +80,6 @@ remain in the CSS. By default, the original declaration is preserved. [git-url]: https://gitter.im/postcss/postcss [npm-img]: https://img.shields.io/npm/v/postcss-gap-properties.svg [npm-url]: https://www.npmjs.com/package/postcss-gap-properties -[win-img]: https://img.shields.io/appveyor/ci/jonathantneal/postcss-gap-properties.svg -[win-url]: https://ci.appveyor.com/project/jonathantneal/postcss-gap-properties [CSS Grid Layout]: https://www.w3.org/TR/css-grid-1/#gutters [Gulp PostCSS]: https://github.com/postcss/gulp-postcss diff --git a/package.json b/package.json index c3f8beafc4..f3fc67892e 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "postcss-gap-properties", - "version": "1.0.0", + "version": "2.0.0", "description": "Use the gap, column-gap, and row-gap shorthand properties in CSS", "author": "Jonathan Neal ", "license": "CC0-1.0", @@ -8,10 +8,12 @@ "homepage": "https://github.com/jonathantneal/postcss-gap-properties#readme", "bugs": "https://github.com/jonathantneal/postcss-gap-properties/issues", "main": "index.cjs.js", - "module": "index.es.js", + "module": "index.es.mjs", "files": [ "index.cjs.js", - "index.es.js" + "index.cjs.js.map", + "index.es.mjs", + "index.es.mjs.map" ], "scripts": { "prepublishOnly": "npm test", @@ -22,21 +24,21 @@ "test:tape": "postcss-tape" }, "engines": { - "node": ">=4.0.0" + "node": ">=6.0.0" }, "dependencies": { "postcss": "^7.0.2" }, "devDependencies": { - "babel-core": "^6.26.3", - "babel-eslint": "^8.2.3", - "babel-preset-env": "^1.6.1", - "eslint": "^4.19.1", + "@babel/core": "^7.0.0", + "@babel/preset-env": "^7.0.0", + "babel-eslint": "^9.0.0", + "eslint": "^5.6.0", "eslint-config-dev": "^2.0.0", "postcss-tape": "^2.2.0", "pre-commit": "^1.2.2", - "rollup": "^0.58.2", - "rollup-plugin-babel": "^3.0.4" + "rollup": "^0.66.0", + "rollup-plugin-babel": "^4.0.1" }, "eslintConfig": { "extends": "dev", From 08fe1ce1c8eb8acab1ffcb9757e809e849539795 Mon Sep 17 00:00:00 2001 From: Jonathan Neal Date: Tue, 18 Sep 2018 00:57:17 -0400 Subject: [PATCH 700/795] 4.0.0 --- .appveyor.yml | 18 ------ .gitignore | 3 +- .rollup.js | 6 +- .travis.yml | 2 +- CHANGELOG.md | 5 ++ INSTALL.md | 170 ++++++++++++++++++++++++++++++++++++++++++++++++++ README.md | 110 +++----------------------------- package.json | 22 ++++--- 8 files changed, 200 insertions(+), 136 deletions(-) delete mode 100644 .appveyor.yml create mode 100644 INSTALL.md diff --git a/.appveyor.yml b/.appveyor.yml deleted file mode 100644 index acbf8a5eeb..0000000000 --- a/.appveyor.yml +++ /dev/null @@ -1,18 +0,0 @@ -# https://www.appveyor.com/docs/appveyor-yml - -environment: - matrix: - - nodejs_version: 4 - -version: "{build}" -build: off -deploy: off - -install: - - ps: Install-Product node $env:nodejs_version - - npm install --ignore-scripts - -test_script: - - node --version - - npm --version - - cmd: "npm test" diff --git a/.gitignore b/.gitignore index de73e5a338..d920b78fec 100644 --- a/.gitignore +++ b/.gitignore @@ -1,10 +1,9 @@ node_modules -index.*.js +index.*.* package-lock.json *.log* *.result.css .* -!.appveyor.yml !.editorconfig !.gitignore !.rollup.js diff --git a/.rollup.js b/.rollup.js index 0436758216..ebe39f9220 100644 --- a/.rollup.js +++ b/.rollup.js @@ -3,13 +3,13 @@ import babel from 'rollup-plugin-babel'; export default { input: 'index.js', output: [ - { file: 'index.cjs.js', format: 'cjs' }, - { file: 'index.es.js', format: 'es' } + { file: 'index.cjs.js', format: 'cjs', sourcemap: true }, + { file: 'index.es.mjs', format: 'es', sourcemap: true } ], plugins: [ babel({ presets: [ - ['env', { modules: false, targets: { node: 4 } }] + ['@babel/env', { modules: false, targets: { node: 6 } }] ] }) ] diff --git a/.travis.yml b/.travis.yml index c56466446c..e1f11a52e6 100644 --- a/.travis.yml +++ b/.travis.yml @@ -3,7 +3,7 @@ language: node_js node_js: - - 4 + - 6 install: - npm install --ignore-scripts diff --git a/CHANGELOG.md b/CHANGELOG.md index 35b9a5fd70..3c66fafe95 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,10 @@ # Changes to PostCSS Place Properties +### 4.0.0 (September 17, 2018) + +- Updated: Support for PostCSS v7+ +- Updated: Support for Node v6+ + ### 3.0.1 (May 8, 2018) - Updated: `postcss-values-parser` to v1.5.0 (major) diff --git a/INSTALL.md b/INSTALL.md new file mode 100644 index 0000000000..bfdf3dd674 --- /dev/null +++ b/INSTALL.md @@ -0,0 +1,170 @@ +# Installing PostCSS Place Properties + +[PostCSS Place Properties] runs in all Node environments, with special instructions for: + +| [Node](#node) | [PostCSS CLI](#postcss-cli) | [Webpack](#webpack) | [Create React App](#create-react-app) | [Gulp](#gulp) | [Grunt](#grunt) | +| --- | --- | --- | --- | --- | --- | + +## Node + +Add [PostCSS Place Properties] to your project: + +```bash +npm install postcss-place --save-dev +``` + +Use [PostCSS Place Properties] to process your CSS: + +```js +import postcssPlace from 'postcss-place'; + +postcssPlace.process(YOUR_CSS /*, processOptions, pluginOptions */); +``` + +Or use it as a [PostCSS] plugin: + +```js +import postcss from 'postcss'; +import postcssPlace from 'postcss-place'; + +postcss([ + postcssPlace(/* pluginOptions */) +]).process(YOUR_CSS /*, processOptions */); +``` + +## PostCSS CLI + +Add [PostCSS CLI] to your project: + +```bash +npm install postcss-cli --save-dev +``` + +Use [PostCSS Place Properties] in your `postcss.config.js` configuration file: + +```js +const postcssPlace = require('postcss-place'); + +module.exports = { + plugins: [ + postcssPlace(/* pluginOptions */) + ] +} +``` + +## Webpack + +Add [PostCSS Loader] to your project: + +```bash +npm install postcss-loader --save-dev +``` + +Use [PostCSS Place Properties] in your Webpack configuration: + +```js +import postcssPlace from 'postcss-place'; + +module.exports = { + module: { + rules: [ + { + test: /\.css$/, + use: [ + 'style-loader', + { loader: 'css-loader', options: { importLoaders: 1 } }, + { loader: 'postcss-loader', options: { + ident: 'postcss', + plugins: () => [ + postcssPlace(/* pluginOptions */) + ] + } } + ] + } + ] + } +} +``` + +## Create React App + +Add [React App Rewired] and [React App Rewire PostCSS] to your project: + +```bash +npm install react-app-rewired react-app-rewire-postcss --save-dev +``` + +Use [React App Rewire PostCSS] and [PostCSS Place Properties] in your +`config-overrides.js` file: + +```js +import reactAppRewirePostcss from 'react-app-rewire-postcss'; +import postcssPlace from 'postcss-place'; + +export default config => reactAppRewirePostcss(config, { + plugins: () => [ + postcssPlace(/* pluginOptions */) + ] +}); +``` + +## Gulp + +Add [Gulp PostCSS] to your project: + +```bash +npm install gulp-postcss --save-dev +``` + +Use [PostCSS Place Properties] in your Gulpfile: + +```js +import postcss from 'gulp-postcss'; +import postcssPlace from 'postcss-place'; + +gulp.task('css', () => gulp.src('./src/*.css').pipe( + postcss([ + postcssPlace(/* pluginOptions */) + ]) +).pipe( + gulp.dest('.') +)); +``` + +## Grunt + +Add [Grunt PostCSS] to your project: + +```bash +npm install grunt-postcss --save-dev +``` + +Use [PostCSS Place Properties] in your Gruntfile: + +```js +import postcssPlace from 'postcss-place'; + +grunt.loadNpmTasks('grunt-postcss'); + +grunt.initConfig({ + postcss: { + options: { + use: [ + postcssPlace(/* pluginOptions */) + ] + }, + dist: { + src: '*.css' + } + } +}); +``` + +[Gulp PostCSS]: https://github.com/postcss/gulp-postcss +[Grunt PostCSS]: https://github.com/nDmitry/grunt-postcss +[PostCSS]: https://github.com/postcss/postcss +[PostCSS CLI]: https://github.com/postcss/postcss-cli +[PostCSS Loader]: https://github.com/postcss/postcss-loader +[PostCSS Place Properties]: https://github.com/jonathantneal/postcss-place +[React App Rewire PostCSS]: https://github.com/csstools/react-app-rewire-postcss +[React App Rewired]: https://github.com/timarney/react-app-rewired diff --git a/README.md b/README.md index 18052c2f23..295f7604be 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,6 @@ [![NPM Version][npm-img]][npm-url] [![CSS Standard Status][css-img]][css-url] [![Build Status][cli-img]][cli-url] -[![Windows Build Status][win-img]][win-url] [![Support Chat][git-img]][git-url] [PostCSS Place Properties] lets you use `place-*` properties as shorthands for `align-*` @@ -29,126 +28,35 @@ and `justify-*`, following the [CSS Box Alignment] specification. ## Usage -Add [PostCSS Place Properties] to your build tool: +Add [PostCSS Place Properties] to your project: ```bash npm install postcss-place --save-dev ``` -#### Node - Use [PostCSS Place Properties] to process your CSS: ```js import postcssPlace from 'postcss-place'; -postcssPlace.process(YOUR_CSS, /* processOptions */, /* pluginOptions */); -``` - -#### PostCSS - -Add [PostCSS] to your build tool: - -```bash -npm install postcss --save-dev +postcssPlace.process(YOUR_CSS /*, processOptions, pluginOptions */); ``` -Use [PostCSS Place Properties] as a plugin: +Or use it as a [PostCSS] plugin: ```js -import postcss from 'gulp-postcss'; +import postcss from 'postcss'; import postcssPlace from 'postcss-place'; postcss([ postcssPlace(/* pluginOptions */) -]).process(YOUR_CSS); -``` - -#### Webpack - -Add [PostCSS Loader] to your build tool: - -```bash -npm install postcss-loader --save-dev -``` - -Use [PostCSS Place Properties] in your Webpack configuration: - -```js -import postcssPlace from 'postcss-place'; - -module.exports = { - module: { - rules: [ - { - test: /\.css$/, - use: [ - 'style-loader', - { loader: 'css-loader', options: { importLoaders: 1 } }, - { loader: 'postcss-loader', options: { - ident: 'postcss', - plugins: () => [ - postcssPlace(/* pluginOptions */) - ] - } } - ] - } - ] - } -} -``` - -#### Gulp - -Add [Gulp PostCSS] to your build tool: - -```bash -npm install gulp-postcss --save-dev -``` - -Use [PostCSS Place Properties] in your Gulpfile: - -```js -import postcss from 'gulp-postcss'; -import postcssPlace from 'postcss-place'; - -gulp.task('css', () => gulp.src('./src/*.css').pipe( - postcss([ - postcssPlace(/* pluginOptions */) - ]) -).pipe( - gulp.dest('.') -)); +]).process(YOUR_CSS /*, processOptions */); ``` -#### Grunt +[PostCSS Place Properties] runs in all Node environments, with special instructions for: -Add [Grunt PostCSS] to your build tool: - -```bash -npm install grunt-postcss --save-dev -``` - -Use [PostCSS Place Properties] in your Gruntfile: - -```js -import postcssPlace from 'postcss-place'; - -grunt.loadNpmTasks('grunt-postcss'); - -grunt.initConfig({ - postcss: { - options: { - use: [ - postcssPlace(/* pluginOptions */) - ] - }, - dist: { - src: '*.css' - } - } -}); -``` +| [Node](INSTALL.md#node) | [Webpack](INSTALL.md#webpack) | [Create React App](INSTALL.md#create-react-app) | [Gulp](INSTALL.md#gulp) | [Grunt](INSTALL.md#grunt) | +| --- | --- | --- | --- | --- | ## Options @@ -185,8 +93,6 @@ postcssPlace({ preserve: false }) [git-url]: https://gitter.im/postcss/postcss [npm-img]: https://img.shields.io/npm/v/postcss-place.svg [npm-url]: https://www.npmjs.com/package/postcss-place -[win-img]: https://img.shields.io/appveyor/ci/jonathantneal/postcss-place.svg -[win-url]: https://ci.appveyor.com/project/jonathantneal/postcss-place [CSS Box Alignment]: https://www.w3.org/TR/css-align-3/#place-content [Gulp PostCSS]: https://github.com/postcss/gulp-postcss diff --git a/package.json b/package.json index 43582c2a00..73b024ded6 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "postcss-place", - "version": "3.0.1", + "version": "4.0.0", "description": "Use a place-* shorthand for align-* and justify-* in CSS", "author": "Jonathan Neal ", "license": "CC0-1.0", @@ -8,10 +8,12 @@ "homepage": "https://github.com/jonathantneal/postcss-place#readme", "bugs": "https://github.com/jonathantneal/postcss-place/issues", "main": "index.cjs.js", - "module": "index.es.js", + "module": "index.es.mjs", "files": [ "index.cjs.js", - "index.es.js" + "index.cjs.js.map", + "index.es.mjs", + "index.es.mjs.map" ], "scripts": { "prepublishOnly": "npm test", @@ -22,22 +24,22 @@ "test:tape": "postcss-tape" }, "engines": { - "node": ">=4.0.0" + "node": ">=6.0.0" }, "dependencies": { "postcss": "^7.0.2", "postcss-values-parser": "^1.5.0" }, "devDependencies": { - "babel-core": "^6.26.3", - "babel-eslint": "^8.2.3", - "babel-preset-env": "^1.6.1", - "eslint": "^4.19.1", + "@babel/core": "^7.0.0", + "@babel/preset-env": "^7.0.0", + "babel-eslint": "^9.0.0", + "eslint": "^5.6.0", "eslint-config-dev": "^2.0.0", "postcss-tape": "^2.2.0", "pre-commit": "^1.2.2", - "rollup": "^0.58.2", - "rollup-plugin-babel": "^3.0.4" + "rollup": "^0.66.0", + "rollup-plugin-babel": "^4.0.1" }, "eslintConfig": { "extends": "dev", From 9084a34e2aea66005f3fa845b2466b6cbdb1b93c Mon Sep 17 00:00:00 2001 From: Jonathan Neal Date: Tue, 18 Sep 2018 01:02:33 -0400 Subject: [PATCH 701/795] 4.0.0 --- .travis.yml | 8 +++++++- CHANGELOG.md | 4 ++++ package.json | 8 ++++---- test/index.js | 2 +- 4 files changed, 16 insertions(+), 6 deletions(-) diff --git a/.travis.yml b/.travis.yml index 85242354aa..e1f11a52e6 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,3 +1,9 @@ +# https://docs.travis-ci.com/user/travis-lint + language: node_js + node_js: - - 4 + - 6 + +install: + - npm install --ignore-scripts diff --git a/CHANGELOG.md b/CHANGELOG.md index f984a47fb2..e238f6dd9c 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,7 @@ +# 4.0.0 - 2018-09-17 + +- Changed: use PostCSS 7 API + # 3.0.0 - 2017-05-11 - Changed: use PostCSS 6 API diff --git a/package.json b/package.json index d4f3166bba..69abc7d299 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "postcss-font-variant", - "version": "3.0.0", + "version": "4.0.0", "description": "PostCSS plugin to transform W3C font-variant properties to more compatible CSS (font-feature-settings)", "keywords": [ "css", @@ -21,9 +21,9 @@ }, "devDependencies": { "jscs": "^3.0.7", - "jshint": "^2.9.4", - "npmpub": "^3.1.0", - "tape": "^4.6.3" + "jshint": "^2.9.6", + "npmpub": "^4.1.0", + "tape": "^4.9.1" }, "scripts": { "lint": "npm run jscs && npm run jshint", diff --git a/test/index.js b/test/index.js index ba3d60a103..65ff36bd66 100755 --- a/test/index.js +++ b/test/index.js @@ -14,7 +14,7 @@ function compareFixtures(t, name, msg, opts, postcssOpts) { opts = opts || {} var actual = postcss().use(plugin(opts)).process(read(postcssOpts.from), postcssOpts).css var expected = read(filename("fixtures/" + name + ".expected")) - fs.writeFile(filename("fixtures/" + name + ".actual"), actual) + fs.writeFileSync(filename("fixtures/" + name + ".actual"), actual) t.equal(actual, expected, msg) } From f25abffafd9efe2e1f445ddaa08db0b8a6ef36d1 Mon Sep 17 00:00:00 2001 From: Jonathan Neal Date: Tue, 18 Sep 2018 01:08:27 -0400 Subject: [PATCH 702/795] 4.0.0 --- .travis.yml | 10 +++++++--- CHANGELOG.md | 5 +++++ README.md | 24 ++++++++++++------------ package-lock.json | 40 ++++++++++++++++++++-------------------- package.json | 6 +++--- 5 files changed, 47 insertions(+), 38 deletions(-) diff --git a/.travis.yml b/.travis.yml index 71c4fb1436..e1f11a52e6 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,5 +1,9 @@ +# https://docs.travis-ci.com/user/travis-lint + language: node_js + node_js: - - "6" - - "8" - - "stable" + - 6 + +install: + - npm install --ignore-scripts diff --git a/CHANGELOG.md b/CHANGELOG.md index 7a70463673..90e5f4492c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,8 @@ +# 4.0.0 2017-09-17 + +- Updated: Support for PostCSS v7+ +- Updated: Support for Node v6+ + # 3.0.0 2017-05-10 Change: Use PostCSS 6 API. diff --git a/README.md b/README.md index a8ed0e89ab..29c9ee7ada 100644 --- a/README.md +++ b/README.md @@ -1,10 +1,10 @@ # PostCSS Media Minmax -[![CSS Standard Status](https://jonathantneal.github.io/css-db/badge/mediaqueries-mq-ranges.svg)](https://jonathantneal.github.io/css-db/#mediaqueries-mq-ranges) +[![CSS Standard Status](https://cssdb.org/badge/media-query-ranges.svg)](https://cssdb.org/#media-query-ranges) [![Build Status](https://travis-ci.org/postcss/postcss-media-minmax.svg?branch=master)](https://travis-ci.org/postcss/postcss-media-minmax) [![NPM Downloads](https://img.shields.io/npm/dm/postcss-media-minmax.svg?style=flat)](https://www.npmjs.com/package/postcss-media-minmax) -[![NPM Version](http://img.shields.io/npm/v/postcss-media-minmax.svg?style=flat)](https://www.npmjs.com/package/postcss-media-minmax) -[![License](https://img.shields.io/npm/l/postcss-media-minmax.svg?style=flat)](http://opensource.org/licenses/MIT) +[![NPM Version](https://img.shields.io/npm/v/postcss-media-minmax.svg?style=flat)](https://www.npmjs.com/package/postcss-media-minmax) +[![License](https://img.shields.io/npm/l/postcss-media-minmax.svg?style=flat)](https://opensource.org/licenses/MIT) > Writing simple and graceful media queries! @@ -19,7 +19,7 @@ This is a polyfill plugin which supports [CSS Media Queries Level 4](https://dra ----- -![Gif Demo](http://gtms02.alicdn.com/tps/i2/TB1UIjyGVXXXXcCaXXXx274FpXX-877-339.gif) +![Gif Demo](https://gtms02.alicdn.com/tps/i2/TB1UIjyGVXXXXcCaXXXx274FpXX-877-339.gif) ## Installation @@ -75,7 +75,7 @@ You will get: ## CSS syntax -### [Syntax](http://dev.w3.org/csswg/mediaqueries/#mq-syntax) +### [Syntax](https://drafts.csswg.org/mediaqueries/#mq-range-context) ``` = [ '<' | '>' ]? '='? @@ -84,15 +84,15 @@ You will get: | '>' '='? '>' '='? ``` -![syntax](http://gtms03.alicdn.com/tps/i3/TB1Rje0HXXXXXXeXpXXccZJ0FXX-640-290.png) +![syntax](https://gtms03.alicdn.com/tps/i3/TB1Rje0HXXXXXXeXpXXccZJ0FXX-640-290.png) PostCSS Media Minmax hasn't implemented syntax such as `200px > = width` or `200px < = width` currently because its readability is not good enough yet. -## [Values](http://dev.w3.org/csswg/mediaqueries/#values) +## [Values](https://drafts.csswg.org/mediaqueries/#values) **The special values:** -* [](http://dev.w3.org/csswg/mediaqueries/#typedef-ratio) +* [](https://drafts.csswg.org/mediaqueries/#typedef-ratio) The value type is a positive (not zero or negative) followed by optional whitespace, followed by a solidus ('/'), followed by optional whitespace, followed by a positive . s can be ordered or compared by transforming them into the number obtained by dividing their first by their second . @@ -107,7 +107,7 @@ PostCSS Media Minmax hasn't implemented syntax such as `200px > = width` or `200 } ``` -* [](http://dev.w3.org/csswg/mediaqueries/#typedef-mq-boolean) +* [](https://drafts.csswg.org/mediaqueries/#typedef-mq-boolean) The value type is an with the value 0 or 1. Any other integer value is invalid. Note that -0 is always equivalent to 0 in CSS, and so is also accepted as a valid value. @@ -285,7 +285,7 @@ gulp.watch('src/*.css', ['default']); ## Contributing * Install all the dependent modules. -* Respect the coding style (Use [EditorConfig](http://editorconfig.org/)). +* Respect the coding style (Use [EditorConfig](https://editorconfig.org/)). * Add test cases in the [test](test) directory. * Run the test cases. @@ -300,9 +300,9 @@ $ npm test * Thank the author of PostCSS [Andrey Sitnik](https://github.com/ai) for giving us such simple and easy CSS syntax analysis tools. -* Thank [Tab Atkins Jr.](http://xanthir.com/contact/) for writing the specs of Media Queries Level 4. +* Thank [Tab Atkins Jr.](https://www.xanthir.com/contact/) for writing the specs of Media Queries Level 4. -* Thank [ziyunfei](http://weibo.com/p/1005051708684567) for suggestions and help of this plugin. +* Thank [ziyunfei](https://weibo.com/p/1005051708684567) for suggestions and help of this plugin. ## [Changelog](CHANGELOG.md) diff --git a/package-lock.json b/package-lock.json index b00ec64031..5249ef9792 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "postcss-media-minmax", - "version": "3.0.0", + "version": "4.0.0", "lockfileVersion": 1, "requires": true, "dependencies": { "@octokit/rest": { "version": "14.0.9", - "resolved": "https://registry.npmjs.org/@octokit/rest/-/rest-14.0.9.tgz", + "resolved": "http://registry.npmjs.org/@octokit/rest/-/rest-14.0.9.tgz", "integrity": "sha512-irP9phKfTXEZIcW2R+VNCtGHZJrXMWmSYp6RRfFn4BtAqtDRXF5z9JxCEQlAhNBf6X1koNi5k49tIAAAEJNlVQ==", "dev": true, "requires": { @@ -130,12 +130,12 @@ } }, "debug": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", - "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", + "version": "3.2.5", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.5.tgz", + "integrity": "sha512-D61LaDQPQkxJ5AUM2mbSJRbPkNs/TmdmOeLAi1hgDkpDfIfetSrjmWhccwtuResSwMbACjx/xXQofvM9CE/aeg==", "dev": true, "requires": { - "ms": "2.0.0" + "ms": "^2.1.1" } }, "deep-equal": { @@ -413,7 +413,7 @@ }, "jsonfile": { "version": "2.4.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-2.4.0.tgz", + "resolved": "http://registry.npmjs.org/jsonfile/-/jsonfile-2.4.0.tgz", "integrity": "sha1-NzaitCi4e72gzIO1P6PWM6NcKug=", "dev": true, "requires": { @@ -430,9 +430,9 @@ } }, "lodash": { - "version": "4.17.10", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.10.tgz", - "integrity": "sha512-UejweD1pDoXu+AD825lWwp4ZGtSwgnpZxb3JDViD7StjQz+Nb/6l093lx4OQ0foGWNRoc19mWy7BzL+UAK2iVg==", + "version": "4.17.11", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.11.tgz", + "integrity": "sha512-cQKh8igo5QUhZ7lg38DYWAxMvjSAKG0A8wGSVimP07SIUEK2UO+arSRKbRZWtelMtN5V0Hkwh5ryOto/SshYIg==", "dev": true }, "lru-cache": { @@ -456,7 +456,7 @@ }, "minimist": { "version": "1.2.0", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", + "resolved": "http://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", "dev": true }, @@ -480,9 +480,9 @@ } }, "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", + "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==", "dev": true }, "npm-run-path": { @@ -495,13 +495,13 @@ } }, "npmpub": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/npmpub/-/npmpub-3.1.0.tgz", - "integrity": "sha1-c0OoAf+xi/0s7CM1hLkUWa5O4Uk=", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/npmpub/-/npmpub-4.1.0.tgz", + "integrity": "sha512-aFaX5gp09tl5NxpqxkHg1QCZrTx6QHBLfQkfonXR0ohwvWeNJItFVSN2R+6IVKtLis085A6zbOUi8r6lMtPO9A==", "dev": true, "requires": { "chalk": "^1.1.1", - "github-release-from-changelog": "^1.1.1", + "github-release-from-changelog": "^1.3.2", "minimist": "^1.2.0", "shelljs": "^0.5.3", "trash": "^3.4.1" @@ -515,7 +515,7 @@ }, "chalk": { "version": "1.1.3", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "resolved": "http://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", "dev": true, "requires": { @@ -745,7 +745,7 @@ }, "through": { "version": "2.3.8", - "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", + "resolved": "http://registry.npmjs.org/through/-/through-2.3.8.tgz", "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=", "dev": true }, diff --git a/package.json b/package.json index e0a3662e13..f52fac7d49 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "postcss-media-minmax", - "version": "3.0.0", + "version": "4.0.0", "description": "Using more intuitive `>=`, `<=`, `>`, `<` instead of media queries min/max prefix.", "scripts": { "test": "tape test", @@ -31,7 +31,7 @@ "postcss": "^7.0.2" }, "devDependencies": { - "npmpub": "^3.1.0", - "tape": "^4.6.3" + "npmpub": "^4.1.0", + "tape": "^4.9.1" } } From a980515a51843d043ae95bbd462f090dd35d77e1 Mon Sep 17 00:00:00 2001 From: Jordan Pittman Date: Tue, 18 Sep 2018 01:13:10 -0400 Subject: [PATCH 703/795] Ensure escaped colons do not break selector transformations * Add failing tests * Use a regex for pseudo selectors searches The regex is set up to ensure that escaped colons are not considered when looking for :not. This slows down selector transformation by about 25% * Cache generated regular expressions This provides a pretty decent speedup. Overall selector matching is now slight slower by about 6% instead of 25%. --- src/index.js | 24 +++++++++++++++++++++++- test/index.js | 12 ++++++++++++ 2 files changed, 35 insertions(+), 1 deletion(-) diff --git a/src/index.js b/src/index.js index b6f1530cff..645dfb413e 100644 --- a/src/index.js +++ b/src/index.js @@ -4,7 +4,7 @@ import list from "postcss/lib/list" import balancedMatch from "balanced-match" function explodeSelector(pseudoClass, selector) { - const position = selector.indexOf(pseudoClass) + const position = locatePseudoClass(selector, pseudoClass) if (selector && position > -1) { const pre = selector.slice(0, position) const matches = balancedMatch("(", ")", selector.slice(position)) @@ -23,6 +23,28 @@ function explodeSelector(pseudoClass, selector) { return selector } +const patternCache = {} + +function locatePseudoClass(selector, pseudoClass) { + patternCache[pseudoClass] = patternCache[pseudoClass] + || new RegExp(`([^\\\\]|^)${pseudoClass}`) + + // The regex is used to ensure that selectors with + // escaped colons in them are treated properly + // Ex: .foo\:not-bar is a valid CSS selector + // But it is not a reference to a pseudo selector + const pattern = patternCache[pseudoClass] + const position = selector.search(pattern) + + if (position === -1) { + return -1 + } + + // The offset returned by the regex may be off by one because + // of it including the negated character match in the position + return position + selector.slice(position).indexOf(pseudoClass) +} + function explodeSelectors(pseudoClass) { return () => { return (css) => { diff --git a/test/index.js b/test/index.js index cd145e6d60..ce0c6059db 100644 --- a/test/index.js +++ b/test/index.js @@ -77,5 +77,17 @@ tape("postcss-selector-not", t => { "should work with something after :not()" ) + t.equal( + transform(".foo\\:not-italic {}"), + ".foo\\:not-italic {}", + "should not replace selectors with escaped colons followed by not" + ) + + t.equal( + transform(".foo\\:not-italic:not(:hover, :focus) {}"), + ".foo\\:not-italic:not(:hover):not(:focus) {}", + "should replace pseudo selectors without touching escaped colons" + ) + t.end() }) From 12ed317213e9014a9fd32bd11f975cb55489a9e2 Mon Sep 17 00:00:00 2001 From: Jonathan Neal Date: Tue, 18 Sep 2018 01:16:47 -0400 Subject: [PATCH 704/795] 4.0.0 --- .travis.yml | 11 +++++++---- CHANGELOG.md | 5 +++++ package.json | 18 +++++++++--------- 3 files changed, 21 insertions(+), 13 deletions(-) diff --git a/.travis.yml b/.travis.yml index 4c4eac6fc3..e1f11a52e6 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,6 +1,9 @@ -sudo: false +# https://docs.travis-ci.com/user/travis-lint + language: node_js + node_js: - - "6" - - "4" - - "stable" + - 6 + +install: + - npm install --ignore-scripts diff --git a/CHANGELOG.md b/CHANGELOG.md index a833d1b87d..c721d230ec 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,8 @@ +# 4.0.0 - 2018-09-17 + +- Added: compatibility with postcss v7.x +- Added: compatibility with node v6.x + # 3.0.1 - 2017-05-15 - Fixed: incorrect export ([#69](https://github.com/postcss/postcss-selector-not/issues/8)) diff --git a/package.json b/package.json index 6f361b00ac..83348525eb 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "postcss-selector-not", - "version": "3.0.1", + "version": "4.0.0", "description": "PostCSS plugin to transform :not() W3C CSS level 4 pseudo class to :not() CSS level 3 selectors", "keywords": [ "postcss", @@ -20,19 +20,19 @@ "dist" ], "dependencies": { - "balanced-match": "^0.4.2", + "balanced-match": "^1.0.0", "postcss": "^7.0.2" }, "devDependencies": { - "babel-cli": "^6.24.1", - "babel-plugin-add-module-exports": "^0.2.1", - "babel-preset-env": "^1.4.0", - "babel-register": "^6.24.1", - "eslint": "^3.19.0", - "tape": "^4.6.3" + "babel-cli": "^6.26.0", + "babel-plugin-add-module-exports": "^1.0.0", + "babel-preset-env": "^1.7.0", + "babel-register": "^6.26.0", + "eslint": "^5.6.0", + "tape": "^4.9.1" }, "scripts": { - "lint": "eslint *.js ./src/ ./test/", + "lint": "eslint ./src/*.js ./test/*.js", "tape": "tape -r babel-register test/*.js", "test": "npm run lint && npm run babelify && npm run tape", "babelify": "babel src --out-dir dist", From adc8f082f980a987769e7bdb4b805055cad0d7c5 Mon Sep 17 00:00:00 2001 From: Jonathan Neal Date: Tue, 18 Sep 2018 01:20:08 -0400 Subject: [PATCH 705/795] 4.0.0 --- .travis.yml | 10 +++++++--- CHANGELOG.md | 5 +++++ README.md | 2 +- package.json | 24 ++++++++++++------------ 4 files changed, 25 insertions(+), 16 deletions(-) diff --git a/.travis.yml b/.travis.yml index 10e9429ed5..e1f11a52e6 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,5 +1,9 @@ -sudo: false +# https://docs.travis-ci.com/user/travis-lint + language: node_js + node_js: - - "6" - - "4" + - 6 + +install: + - npm install --ignore-scripts diff --git a/CHANGELOG.md b/CHANGELOG.md index 6f58527735..f5f0135b57 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,8 @@ +# 4.0.0 - 2018-09-17 + +- Added: compatibility with postcss v7.x +- Added: compatibility with node v6.x + # 3.0.1 - 2017-05-15 - Fixed: incorrect export diff --git a/README.md b/README.md index e31b60e591..e9e49e7be3 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# postcss-selector-matches [![CSS Standard Status](https://jonathantneal.github.io/css-db/badge/selectors-matches.svg)](https://jonathantneal.github.io/css-db/#selectors-matches) [![Build Status](https://travis-ci.org/postcss/postcss-selector-matches.svg?branch=master)](https://travis-ci.org/postcss/postcss-selector-matches) +# postcss-selector-matches [![CSS Standard Status](https://cssdb.org/badge/matches-pseudo-class.svg)](https://cssdb.org/#matches-pseudo-class) [![Build Status](https://travis-ci.org/postcss/postcss-selector-matches.svg?branch=master)](https://travis-ci.org/postcss/postcss-selector-matches) > PostCSS plugin to transform `:matches()` W3C CSS pseudo class to more compatible CSS selectors diff --git a/package.json b/package.json index adfe3db2fd..1ed57d3d40 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "postcss-selector-matches", - "version": "3.0.1", + "version": "4.0.0", "description": "PostCSS plugin to transform :matches() W3C CSS pseudo class to more compatible CSS selectors", "keywords": [ "postcss", @@ -17,22 +17,22 @@ "dist" ], "dependencies": { - "balanced-match": "^0.4.2", + "balanced-match": "^1.0.0", "postcss": "^7.0.2" }, "devDependencies": { - "babel-cli": "^6.24.1", - "babel-plugin-add-module-exports": "^0.2.1", - "babel-preset-env": "^1.4.0", - "babel-preset-es2015": "^6.14.0", - "babel-preset-stage-2": "^6.13.0", - "babel-register": "^6.24.1", - "eslint": "^3.19.0", - "npmpub": "^3.1.0", - "tape": "^4.6.3" + "babel-cli": "^6.26.0", + "babel-plugin-add-module-exports": "^1.0.0", + "babel-preset-env": "^1.7.0", + "babel-preset-es2015": "^6.24.1", + "babel-preset-stage-2": "^6.24.1", + "babel-register": "^6.26.0", + "eslint": "^5.6.0", + "npmpub": "^4.1.0", + "tape": "^4.9.1" }, "scripts": { - "lint": "eslint *.js ./src/ ./test/", + "lint": "eslint ./src/*.js ./test/*.js", "tape": "tape -r babel-register test/*.js", "test": "npm run lint && npm run babelify && npm run tape", "babelify": "babel src --out-dir dist", From 9f7f47083845ea87f489edfb9305ae66b7c97922 Mon Sep 17 00:00:00 2001 From: Jonathan Neal Date: Tue, 18 Sep 2018 03:09:15 -0400 Subject: [PATCH 706/795] 5.0.0 --- .editorconfig | 13 +- .eslintrc.yml | 36 - .gitignore | 11 +- .rollup.js | 16 + .tape.js | 13 + CHANGELOG.md | 22 +- CONTRIBUTING.md | 65 ++ INSTALL.md | 170 ++++ LICENSE => LICENSE.md | 21 +- README.md | 109 ++- index.js | 164 ++-- package-lock.json | 1256 -------------------------- package.json | 75 +- test/basic.css | 10 + test/basic.expect.css | 10 + test/basic.preserve.expect.css | 13 + test/fixtures/hex-alpha.css | 8 - test/fixtures/hex-alpha.expected.css | 8 - test/index.js | 33 - 19 files changed, 540 insertions(+), 1513 deletions(-) delete mode 100644 .eslintrc.yml create mode 100644 .rollup.js create mode 100644 .tape.js create mode 100644 CONTRIBUTING.md create mode 100644 INSTALL.md rename LICENSE => LICENSE.md (52%) mode change 100755 => 100644 delete mode 100644 package-lock.json create mode 100644 test/basic.css create mode 100644 test/basic.expect.css create mode 100644 test/basic.preserve.expect.css delete mode 100644 test/fixtures/hex-alpha.css delete mode 100644 test/fixtures/hex-alpha.expected.css delete mode 100755 test/index.js diff --git a/.editorconfig b/.editorconfig index 8978b448a6..e06d7982bc 100644 --- a/.editorconfig +++ b/.editorconfig @@ -1,16 +1,15 @@ -# editorconfig.org root = true [*] -end_of_line = lf charset = utf-8 -trim_trailing_whitespace = true +end_of_line = lf +indent_style = tab insert_final_newline = true -indent_style = space -indent_size = 2 +trim_trailing_whitespace = true [*.md] trim_trailing_whitespace = false -[Makefile] -indent_style = tab +[*.{json,md,yml}] +indent_size = 2 +indent_style = space diff --git a/.eslintrc.yml b/.eslintrc.yml deleted file mode 100644 index 1f8f8e652b..0000000000 --- a/.eslintrc.yml +++ /dev/null @@ -1,36 +0,0 @@ -root: true -extends: eslint:recommended - -parserOptions: - ecmaVersion: 6 - -env: - commonjs: true - -rules: - indent: [2, 2] # 2 spaces indentation - max-len: [2, 80, 4] - 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"] diff --git a/.gitignore b/.gitignore index 7ab649f420..d920b78fec 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,11 @@ node_modules -test/fixtures/*.actual.css +index.*.* +package-lock.json +*.log* +*.result.css +.* +!.editorconfig +!.gitignore +!.rollup.js +!.tape.js +!.travis.yml diff --git a/.rollup.js b/.rollup.js new file mode 100644 index 0000000000..ebe39f9220 --- /dev/null +++ b/.rollup.js @@ -0,0 +1,16 @@ +import babel from 'rollup-plugin-babel'; + +export default { + input: 'index.js', + output: [ + { file: 'index.cjs.js', format: 'cjs', sourcemap: true }, + { file: 'index.es.mjs', format: 'es', sourcemap: true } + ], + plugins: [ + babel({ + presets: [ + ['@babel/env', { modules: false, targets: { node: 6 } }] + ] + }) + ] +}; diff --git a/.tape.js b/.tape.js new file mode 100644 index 0000000000..7686430981 --- /dev/null +++ b/.tape.js @@ -0,0 +1,13 @@ +module.exports = { + 'postcss-color-hex-alpha': { + 'basic': { + message: 'supports basic usage' + }, + 'basic:preserve': { + message: 'supports { preserve: true } usage', + options: { + preserve: true + } + } + } +}; diff --git a/CHANGELOG.md b/CHANGELOG.md index 978a1faa97..195a3e37b1 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,32 +1,34 @@ -# 4.0.0 - 2017-09-17 +# Changes to PostCSS Color Hex Alpha + +### 5.0.0 (September 18, 2018) + +- Initial version + +### 4.0.0 (September 17, 2018) - Updated: Support for PostCSS v7+ - Updated: Support for Node v6+ - Updated: color v3+ -# 3.0.0 - 2017-05-15 +### 3.0.0 (May 15, 2017) - Added: compatibility with postcss v6.x - Updated dependencies -# 2.0.0 - 2015-09-08 +### 2.0.0 (September 8, 2015) - Added: compatibility with postcss v5.x - Removed: compatiblity with postcss v4.x -# 1.3.0 - 2015-08-13 +### 1.3.0 (August 13, 2015) - Added: compatibility with postcss v4.1.x ([#3](https://github.com/postcss/postcss-color-hex-alpha/pull/3)) -# 1.2.0 - ? - -1.1.0 ? - -# 1.1.0 - 2014-11-25 +### 1.1.0 (November 25, 2014) - Enhanced exceptions -# 1.0.0 - 2014-10-04 +### 1.0.0 - (October 4, 2014) Initial release from [postcss-color](https://github.com/postcss/postcss-color) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 0000000000..e2c7d72400 --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,65 @@ +# Contributing to PostCSS Color Hex Alpha + +You want to help? You rock! Now, take a moment to be sure your contributions +make sense to everyone else. + +## Reporting Issues + +Found a problem? Want a new feature? + +- See if your issue or idea has [already been reported]. +- Provide a [reduced test case] or a [live example]. + +Remember, a bug is a _demonstrable problem_ caused by _our_ code. + +## Submitting Pull Requests + +Pull requests are the greatest contributions, so be sure they are focused in +scope and avoid unrelated commits. + +1. To begin; [fork this project], clone your fork, and add our upstream. + ```bash + # Clone your fork of the repo into the current directory + git clone git@github.com:YOUR_USER/postcss-color-hex-alpha.git + + # Navigate to the newly cloned directory + cd postcss-color-hex-alpha + + # Assign the original repo to a remote called "upstream" + git remote add upstream git@github.com:postcss/postcss-color-hex-alpha.git + + # Install the tools necessary for testing + npm install + ``` + +2. Create a branch for your feature or fix: + ```bash + # Move into a new branch for your feature + git checkout -b feature/thing + ``` + ```bash + # Move into a new branch for your fix + git checkout -b fix/something + ``` + +3. If your code follows our practices, then push your feature branch: + ```bash + # Test current code + npm test + ``` + ```bash + # Push the branch for your new feature + git push origin feature/thing + ``` + ```bash + # Or, push the branch for your update + git push origin update/something + ``` + +That’s it! Now [open a pull request] with a clear title and description. + +[already been reported]: issues +[fork this project]: fork +[live example]: https://codepen.io/pen +[open a pull request]: https://help.github.com/articles/using-pull-requests/ +[reduced test case]: https://css-tricks.com/reduced-test-cases/ diff --git a/INSTALL.md b/INSTALL.md new file mode 100644 index 0000000000..501b278a47 --- /dev/null +++ b/INSTALL.md @@ -0,0 +1,170 @@ +# Installing PostCSS Color Hex Alpha + +[PostCSS Color Hex Alpha] runs in all Node environments, with special instructions for: + +| [Node](#node) | [PostCSS CLI](#postcss-cli) | [Webpack](#webpack) | [Create React App](#create-react-app) | [Gulp](#gulp) | [Grunt](#grunt) | +| --- | --- | --- | --- | --- | --- | + +## Node + +Add [PostCSS Color Hex Alpha] to your project: + +```bash +npm install postcss-color-hex-alpha --save-dev +``` + +Use [PostCSS Color Hex Alpha] to process your CSS: + +```js +const postcssColorHexAlpha = require('postcss-color-hex-alpha'); + +postcssColorHexAlpha.process(YOUR_CSS /*, processOptions, pluginOptions */); +``` + +Or use it as a [PostCSS] plugin: + +```js +const postcss = require('postcss'); +const postcssColorHexAlpha = require('postcss-color-hex-alpha'); + +postcss([ + postcssColorHexAlpha(/* pluginOptions */) +]).process(YOUR_CSS /*, processOptions */); +``` + +## PostCSS CLI + +Add [PostCSS CLI] to your project: + +```bash +npm install postcss-cli --save-dev +``` + +Use [PostCSS Color Hex Alpha] in your `postcss.config.js` configuration file: + +```js +const postcssColorHexAlpha = require('postcss-color-hex-alpha'); + +module.exports = { + plugins: [ + postcssColorHexAlpha(/* pluginOptions */) + ] +} +``` + +## Webpack + +Add [PostCSS Loader] to your project: + +```bash +npm install postcss-loader --save-dev +``` + +Use [PostCSS Color Hex Alpha] in your Webpack configuration: + +```js +const postcssColorHexAlpha = require('postcss-color-hex-alpha'); + +module.exports = { + module: { + rules: [ + { + test: /\.css$/, + use: [ + 'style-loader', + { loader: 'css-loader', options: { importLoaders: 1 } }, + { loader: 'postcss-loader', options: { + ident: 'postcss', + plugins: () => [ + postcssColorHexAlpha(/* pluginOptions */) + ] + } } + ] + } + ] + } +} +``` + +## Create React App + +Add [React App Rewired] and [React App Rewire PostCSS] to your project: + +```bash +npm install react-app-rewired react-app-rewire-postcss --save-dev +``` + +Use [React App Rewire PostCSS] and [PostCSS Color Hex Alpha] in your +`config-overrides.js` file: + +```js +const reactAppRewirePostcss = require('react-app-rewire-postcss'); +const postcssColorHexAlpha = require('postcss-color-hex-alpha'); + +module.exports = config => reactAppRewirePostcss(config, { + plugins: () => [ + postcssColorHexAlpha(/* pluginOptions */) + ] +}); +``` + +## Gulp + +Add [Gulp PostCSS] to your project: + +```bash +npm install gulp-postcss --save-dev +``` + +Use [PostCSS Color Hex Alpha] in your Gulpfile: + +```js +const postcss = require('gulp-postcss'); +const postcssColorHexAlpha = require('postcss-color-hex-alpha'); + +gulp.task('css', () => gulp.src('./src/*.css').pipe( + postcss([ + postcssColorHexAlpha(/* pluginOptions */) + ]) +).pipe( + gulp.dest('.') +)); +``` + +## Grunt + +Add [Grunt PostCSS] to your project: + +```bash +npm install grunt-postcss --save-dev +``` + +Use [PostCSS Color Hex Alpha] in your Gruntfile: + +```js +const postcssColorHexAlpha = require('postcss-color-hex-alpha'); + +grunt.loadNpmTasks('grunt-postcss'); + +grunt.initConfig({ + postcss: { + options: { + use: [ + postcssColorHexAlpha(/* pluginOptions */) + ] + }, + dist: { + src: '*.css' + } + } +}); +``` + +[Gulp PostCSS]: https://github.com/postcss/gulp-postcss +[Grunt PostCSS]: https://github.com/nDmitry/grunt-postcss +[PostCSS]: https://github.com/postcss/postcss +[PostCSS CLI]: https://github.com/postcss/postcss-cli +[PostCSS Loader]: https://github.com/postcss/postcss-loader +[PostCSS Color Hex Alpha]: https://github.com/postcss/postcss-color-hex-alpha +[React App Rewire PostCSS]: https://github.com/csstools/react-app-rewire-postcss +[React App Rewired]: https://github.com/timarney/react-app-rewired diff --git a/LICENSE b/LICENSE.md old mode 100755 new mode 100644 similarity index 52% rename from LICENSE rename to LICENSE.md index 8b39b8f151..6d70470888 --- a/LICENSE +++ b/LICENSE.md @@ -1,20 +1,21 @@ -The MIT License (MIT) +# The MIT License (MIT) -Copyright (c) 2014 Maxime Thirouin +Copyright © PostCSS 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: +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. +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. diff --git a/README.md b/README.md index 21511b3aef..29f7a33c9d 100755 --- a/README.md +++ b/README.md @@ -1,61 +1,92 @@ -# postcss-color-hex-alpha [![CSS Standard Status](https://cssdb.org/badge/hexadecimal-alpha-notation.svg)](https://cssdb.org/#hexadecimal-alpha-notation) [![Build Status](https://api.travis-ci.org/postcss/postcss-color-hex-alpha.svg)](https://travis-ci.org/postcss/postcss-color-hex-alpha) +# PostCSS Color Hex Alpha [PostCSS][postcss] -> [PostCSS](https://github.com/postcss/postcss) plugin to transform [W3C RGBA hexadecimal notations (#RRGGBBAA or #RGBA)](https://www.w3.org/TR/css-color-4/#hex-notation) to more compatible CSS (rgba()). +[![NPM Version][npm-img]][npm-url] +[![CSS Standard Status][css-img]][css-url] +[![Build Status][cli-img]][cli-url] +[![Support Chat][git-img]][git-url] -## Installation +[PostCSS Color Hex Alpha] lets you use 4 & 8 character hex color notation in +CSS, following the [CSS Color Module] specification. -```bash -$ npm install postcss-color-hex-alpha +```pcss +body { + background: #9d9c; +} + +/* becomes */ + +body { + background: rgba(153, 221, 153, 0.8); +} ``` ## Usage -```js -// dependencies -var fs = require("fs") -var postcss = require("postcss") -var colorHexAlpha = require("postcss-color-hex-alpha") - -// css to be processed -var css = fs.readFileSync("input.css", "utf8") - -// process css -var output = postcss() - .use(colorHexAlpha()) - .process(css) - .css +Add [PostCSS Color Hex Alpha] to your project: + +```bash +npm install postcss-color-hex-alpha --save-dev ``` -Using this `input.css`: +Use [PostCSS Color Hex Alpha] to process your CSS: -```css -body { - background: #9d9c -} +```js +const postcssColorHexAlpha = require('postcss-color-hex-alpha'); +postcssColorHexAlpha.process(YOUR_CSS /*, processOptions, pluginOptions */); ``` -you will get: +Or use it as a [PostCSS] plugin: -```css -body { - background: rgba(153, 221, 153, 0.8) -} +```js +const postcss = require('postcss'); +const postcssColorHexAlpha = require('postcss-color-hex-alpha'); + +postcss([ + postcssColorHexAlpha(/* pluginOptions */) +]).process(YOUR_CSS /*, processOptions */); ``` -Checkout [tests](test) for more examples. +[PostCSS Color Hex Alpha] runs in all Node environments, with special instructions for: ---- +| [Node](INSTALL.md#node) | [PostCSS CLI](INSTALL.md#postcss-cli) | [Webpack](INSTALL.md#webpack) | [Create React App](INSTALL.md#create-react-app) | [Gulp](INSTALL.md#gulp) | [Grunt](INSTALL.md#grunt) | +| --- | --- | --- | --- | --- | --- | -## Contributing +## Options -Work on a branch, install dev-dependencies, respect coding style & run tests before submitting a bug fix or a feature. +### preserve - $ git clone https://github.com/postcss/postcss-color-hex-alpha.git - $ git checkout -b patch-1 - $ npm install - $ npm test +The `preserve` option determines whether 4 & 8 character hex color notation +should be preserved in their original form. By default, these are not preserved. -## [Changelog](CHANGELOG.md) +```js +postcssColorHexAlpha({ + preserve: true +}); +``` + +```pcss +body { + background: #9d9c; +} + +/* becomes */ + +body { + background: rgba(153, 221, 153, 0.8); + background: #9d9c; +} +``` -## [License](LICENSE) +[cli-img]: https://img.shields.io/travis/postcss/postcss-color-hex-alpha.svg +[cli-url]: https://travis-ci.org/postcss/postcss-color-hex-alpha +[css-img]: https://cssdb.org/badge/hexadecimal-alpha-notation.svg +[css-url]: https://cssdb.org/#hexadecimal-alpha-notation +[git-img]: https://img.shields.io/badge/support-chat-blue.svg +[git-url]: https://gitter.im/postcss/postcss +[npm-img]: https://img.shields.io/npm/v/postcss-color-hex-alpha.svg +[npm-url]: https://www.npmjs.com/package/postcss-color-hex-alpha + +[PostCSS]: https://github.com/postcss/postcss +[PostCSS Color Hex Alpha]: https://github.com/postcss/postcss-color-hex-alpha +[CSS Color Module]: https://www.w3.org/TR/css-color-4/#hex-notation diff --git a/index.js b/index.js index ad7f25432b..acf4e6b7ba 100755 --- a/index.js +++ b/index.js @@ -1,81 +1,83 @@ -/** - * Module dependencies. - */ -const postcss = require("postcss") -const helpers = require("postcss-message-helpers") -const color = require("color") - -/** - * Constantes - */ -const HEX_ALPHA_RE = /#([0-9a-f]{4}(?:[0-9a-f]{4})?)\b/i -const DECIMAL_PRECISION = 100000 // 5 decimals - -/** - * PostCSS plugin to transform hexa alpha colors - */ -module.exports = postcss.plugin("postcss-color-hex-alpha", function() { - return function(style) { - style.walkDecls(function transformDecl(decl) { - if (!decl.value || decl.value.indexOf("#") === -1) { - return - } - - decl.value = helpers.try(function transformHexAlphaValue() { - return transformHexAlpha(decl.value, decl.source) - }, decl.source) - }) - } -}) - -/** - * transform RGBA hexadecimal notations (#RRGGBBAA or #RGBA) to rgba(). - * - * @param {String} string declaration value - * @return {String} converted declaration value to rgba() - */ -function transformHexAlpha(string) { - const m = HEX_ALPHA_RE.exec(string) - - if (!m) { - return string - } - - const hex = m[1] - - return string.slice(0, m.index) + - hexaToRgba(hex) + - transformHexAlpha( - string.slice(m.index + 1 + hex.length) - ) -} - -/** - * transform RGBA or RRGGBBAA to rgba() - * - * @param {String} hex RGBA or RRGGBBAA - * @return {String} converted value to rgba() - */ -function hexaToRgba(hex) { - // if (hex.length === 3) { - // hex += "f" - // } - if (hex.length === 4) { - const h0 = hex.charAt(0) - const h1 = hex.charAt(1) - const h2 = hex.charAt(2) - const h3 = hex.charAt(3) - hex = h0 + h0 + h1 + h1 + h2 + h2 + h3 + h3 - } - // if (hex.length === 6) { - // hex += "ff" - // } - const rgb = [] - for (let i = 0, l = hex.length; i < l; i += 2) { - const isAlpha = i === 6 - const value = parseInt(hex.substr(i, 2), 16) / (isAlpha ? 255 : 1) - rgb.push(Math.round(value * DECIMAL_PRECISION) / DECIMAL_PRECISION) - } - - return color.rgb(rgb).string() -} +import postcss from 'postcss'; +import valueParser from 'postcss-values-parser'; + +export default postcss.plugin('postcss-color-hex-alpha', opts => { + // whether to preserve the original hexa + const preserve = 'preserve' in Object(opts) ? Boolean(opts.preserve) : false; + + return root => { + // for each declaration with a hexa + root.walkDecls(decl => { + if (hasAlphaHex(decl)) { + // replace instances of hexa with rgba() + const ast = valueParser(decl.value).parse(); + + walk(ast, node => { + if (isAlphaHex(node)) { + node.replaceWith(hexa2rgba(node)); + } + }); + + // conditionally update the declaration + const modifiedValue = String(ast); + + if (decl.value !== modifiedValue) { + if (preserve) { + decl.cloneBefore({ value: modifiedValue }); + } else { + decl.value = modifiedValue; + } + } + } + }); + }; +}); + +// match any hexa +const alphaHexRegExp = /#([0-9A-f]{4}(?:[0-9A-f]{4})?)\b/; + +// whether a node has a hexa +const hasAlphaHex = node => alphaHexRegExp.test(node.value); + +// match an exact hexa +const alphaHexValueRegExp = /^#([0-9A-f]{4}(?:[0-9A-f]{4})?)$/; + +// walk all nodes in a value +const walk = (node, fn) => { + if (Object(node.nodes).length) { + node.nodes.slice().forEach(child => { + fn(child); + + walk(child, fn); + }); + } +}; + +// match a hexa node +const isAlphaHex = node => node.type === 'word' && alphaHexValueRegExp.test(node.value); + +const hexa2rgba = node => { + // hex is the node value + const hex = node.value; + + // conditionally expand a hex + const hex8 = `0x${hex.length === 5 ? hex.slice(1).replace(/[0-9A-f]/g, '$&$&') : hex.slice(1)}`; + + // extract the red, blue, green, and alpha values from the hex + const [r, g, b, a] = [ hex8 >> 32 & 255, hex8 >> 16 & 255, hex8 >> 8 & 255, hex8 & 255 ]; + + // return a new rgba function, preserving the whitespace of the original node + const rgbaFunc = valueParser.func({ value: 'rgba', raws: Object.assign({}, node.raws) }); + + rgbaFunc.append(valueParser.paren({ value: '(' })); + rgbaFunc.append(valueParser.number({ value: r })); + rgbaFunc.append(valueParser.comma({ value: ',' })); + rgbaFunc.append(valueParser.number({ value: g })); + rgbaFunc.append(valueParser.comma({ value: ',' })); + rgbaFunc.append(valueParser.number({ value: b })); + rgbaFunc.append(valueParser.comma({ value: ',' })); + rgbaFunc.append(valueParser.number({ value: a })); + rgbaFunc.append(valueParser.paren({ value: ')' })); + + return rgbaFunc; +}; diff --git a/package-lock.json b/package-lock.json deleted file mode 100644 index 929d23b481..0000000000 --- a/package-lock.json +++ /dev/null @@ -1,1256 +0,0 @@ -{ - "name": "postcss-color-hex-alpha", - "version": "4.0.0", - "lockfileVersion": 1, - "requires": true, - "dependencies": { - "@babel/code-frame": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.0.0.tgz", - "integrity": "sha512-OfC2uemaknXr87bdLUkWog7nYuliM9Ij5HUcajsVcMCpQrcLmtxRbVFTIqmcSkSeYRBFBRxs2FiUqFJDLdiebA==", - "dev": true, - "requires": { - "@babel/highlight": "^7.0.0" - } - }, - "@babel/highlight": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.0.0.tgz", - "integrity": "sha512-UFMC4ZeFC48Tpvj7C8UgLvtkaUuovQX+5xNWrsIoMG8o2z+XFKjKaN9iVmS84dPwVN00W4wPmqvYoZF3EGAsfw==", - "dev": true, - "requires": { - "chalk": "^2.0.0", - "esutils": "^2.0.2", - "js-tokens": "^4.0.0" - } - }, - "acorn": { - "version": "5.7.3", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-5.7.3.tgz", - "integrity": "sha512-T/zvzYRfbVojPWahDsE5evJdHb3oJoQfFbsrKM7w5Zcs++Tr257tia3BmMP8XYVjp1S9RZXQMh7gao96BlqZOw==", - "dev": true - }, - "acorn-jsx": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-4.1.1.tgz", - "integrity": "sha512-JY+iV6r+cO21KtntVvFkD+iqjtdpRUpGqKWgfkCdZq1R+kbreEl8EcdcJR4SmiIgsIQT33s6QzheQ9a275Q8xw==", - "dev": true, - "requires": { - "acorn": "^5.0.3" - } - }, - "ajv": { - "version": "6.5.3", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.5.3.tgz", - "integrity": "sha512-LqZ9wY+fx3UMiiPd741yB2pj3hhil+hQc8taf4o2QGRFpWgZ2V5C8HA165DY9sS3fJwsk7uT7ZlFEyC3Ig3lLg==", - "dev": true, - "requires": { - "fast-deep-equal": "^2.0.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - } - }, - "ajv-keywords": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.2.0.tgz", - "integrity": "sha1-6GuBnGAs+IIa1jdBNpjx3sAhhHo=", - "dev": true - }, - "ansi-escapes": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-3.1.0.tgz", - "integrity": "sha512-UgAb8H9D41AQnu/PbWlCofQVcnV4Gs2bBJi9eZPxfU/hgglFh3SMDMENRIqdr7H6XFnXdoknctFByVsCOotTVw==", - "dev": true - }, - "ansi-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", - "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", - "dev": true - }, - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "requires": { - "color-convert": "^1.9.0" - } - }, - "argparse": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", - "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", - "dev": true, - "requires": { - "sprintf-js": "~1.0.2" - } - }, - "array-union": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/array-union/-/array-union-1.0.2.tgz", - "integrity": "sha1-mjRBDk9OPaI96jdb5b5w8kd47Dk=", - "dev": true, - "requires": { - "array-uniq": "^1.0.1" - } - }, - "array-uniq": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/array-uniq/-/array-uniq-1.0.3.tgz", - "integrity": "sha1-r2rId6Jcx/dOBYiUdThY39sk/bY=", - "dev": true - }, - "arrify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", - "integrity": "sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=", - "dev": true - }, - "balanced-match": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", - "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", - "dev": true - }, - "brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, - "requires": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "caller-path": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/caller-path/-/caller-path-0.1.0.tgz", - "integrity": "sha1-lAhe9jWB7NPaqSREqP6U6CV3dR8=", - "dev": true, - "requires": { - "callsites": "^0.2.0" - } - }, - "callsites": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/callsites/-/callsites-0.2.0.tgz", - "integrity": "sha1-r6uWJikQp/M8GaV3WCXGnzTjUMo=", - "dev": true - }, - "chalk": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.1.tgz", - "integrity": "sha512-ObN6h1v2fTJSmUXoS3nMQ92LbDK9be4TV+6G+omQlGJFdcUX5heKi1LZ1YnRMIgwTLEj3E24bT6tYni50rlCfQ==", - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - } - }, - "chardet": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.7.0.tgz", - "integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==", - "dev": true - }, - "circular-json": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/circular-json/-/circular-json-0.3.3.tgz", - "integrity": "sha512-UZK3NBx2Mca+b5LsG7bY183pHWt5Y1xts4P3Pz7ENTwGVnJOUWbRb3ocjvX7hx9tq/yTAdclXm9sZ38gNuem4A==", - "dev": true - }, - "cli-cursor": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-2.1.0.tgz", - "integrity": "sha1-s12sN2R5+sw+lHR9QdDQ9SOP/LU=", - "dev": true, - "requires": { - "restore-cursor": "^2.0.0" - } - }, - "cli-width": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-2.2.0.tgz", - "integrity": "sha1-/xnt6Kml5XkyQUewwR8PvLq+1jk=", - "dev": true - }, - "color": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/color/-/color-3.0.0.tgz", - "integrity": "sha512-jCpd5+s0s0t7p3pHQKpnJ0TpQKKdleP71LWcA0aqiljpiuAkOSUFN/dyH8ZwF0hRmFlrIuRhufds1QyEP9EB+w==", - "requires": { - "color-convert": "^1.9.1", - "color-string": "^1.5.2" - } - }, - "color-convert": { - "version": "1.9.2", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.2.tgz", - "integrity": "sha512-3NUJZdhMhcdPn8vJ9v2UQJoH0qqoGUkYTgFEPZaPjEtwmmKUfNV46zZmgB2M5M4DCEQHMaCfWHCxiBflLm04Tg==", - "requires": { - "color-name": "1.1.1" - } - }, - "color-name": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.1.tgz", - "integrity": "sha1-SxQVMEz1ACjqgWQ2Q72C6gWANok=" - }, - "color-string": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/color-string/-/color-string-1.5.3.tgz", - "integrity": "sha512-dC2C5qeWoYkxki5UAXapdjqO672AM4vZuPGRQfO8b5HKuKGBbKWpITyDYN7TOFKvRW7kOgAn3746clDBMDJyQw==", - "requires": { - "color-name": "^1.0.0", - "simple-swizzle": "^0.2.2" - } - }, - "concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", - "dev": true - }, - "cross-spawn": { - "version": "6.0.5", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", - "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", - "dev": true, - "requires": { - "nice-try": "^1.0.4", - "path-key": "^2.0.1", - "semver": "^5.5.0", - "shebang-command": "^1.2.0", - "which": "^1.2.9" - } - }, - "debug": { - "version": "3.2.5", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.5.tgz", - "integrity": "sha512-D61LaDQPQkxJ5AUM2mbSJRbPkNs/TmdmOeLAi1hgDkpDfIfetSrjmWhccwtuResSwMbACjx/xXQofvM9CE/aeg==", - "dev": true, - "requires": { - "ms": "^2.1.1" - } - }, - "deep-equal": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/deep-equal/-/deep-equal-1.0.1.tgz", - "integrity": "sha1-9dJgKStmDghO/0zbyfCK0yR0SLU=", - "dev": true - }, - "deep-is": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz", - "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=", - "dev": true - }, - "define-properties": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.2.tgz", - "integrity": "sha1-g6c/L+pWmJj7c3GTyPhzyvbUXJQ=", - "dev": true, - "requires": { - "foreach": "^2.0.5", - "object-keys": "^1.0.8" - } - }, - "defined": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/defined/-/defined-1.0.0.tgz", - "integrity": "sha1-yY2bzvdWdBiOEQlpFRGZ45sfppM=", - "dev": true - }, - "del": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/del/-/del-2.2.2.tgz", - "integrity": "sha1-wSyYHQZ4RshLyvhiz/kw2Qf/0ag=", - "dev": true, - "requires": { - "globby": "^5.0.0", - "is-path-cwd": "^1.0.0", - "is-path-in-cwd": "^1.0.0", - "object-assign": "^4.0.1", - "pify": "^2.0.0", - "pinkie-promise": "^2.0.0", - "rimraf": "^2.2.8" - } - }, - "doctrine": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", - "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", - "dev": true, - "requires": { - "esutils": "^2.0.2" - } - }, - "es-abstract": { - "version": "1.12.0", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.12.0.tgz", - "integrity": "sha512-C8Fx/0jFmV5IPoMOFPA9P9G5NtqW+4cOPit3MIuvR2t7Ag2K15EJTpxnHAYTzL+aYQJIESYeXZmDBfOBE1HcpA==", - "dev": true, - "requires": { - "es-to-primitive": "^1.1.1", - "function-bind": "^1.1.1", - "has": "^1.0.1", - "is-callable": "^1.1.3", - "is-regex": "^1.0.4" - } - }, - "es-to-primitive": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.1.1.tgz", - "integrity": "sha1-RTVSSKiJeQNLZ5Lhm7gfK3l13Q0=", - "dev": true, - "requires": { - "is-callable": "^1.1.1", - "is-date-object": "^1.0.1", - "is-symbol": "^1.0.1" - } - }, - "escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=" - }, - "eslint": { - "version": "5.6.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-5.6.0.tgz", - "integrity": "sha512-/eVYs9VVVboX286mBK7bbKnO1yamUy2UCRjiY6MryhQL2PaaXCExsCQ2aO83OeYRhU2eCU/FMFP+tVMoOrzNrA==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.0.0", - "ajv": "^6.5.3", - "chalk": "^2.1.0", - "cross-spawn": "^6.0.5", - "debug": "^3.1.0", - "doctrine": "^2.1.0", - "eslint-scope": "^4.0.0", - "eslint-utils": "^1.3.1", - "eslint-visitor-keys": "^1.0.0", - "espree": "^4.0.0", - "esquery": "^1.0.1", - "esutils": "^2.0.2", - "file-entry-cache": "^2.0.0", - "functional-red-black-tree": "^1.0.1", - "glob": "^7.1.2", - "globals": "^11.7.0", - "ignore": "^4.0.6", - "imurmurhash": "^0.1.4", - "inquirer": "^6.1.0", - "is-resolvable": "^1.1.0", - "js-yaml": "^3.12.0", - "json-stable-stringify-without-jsonify": "^1.0.1", - "levn": "^0.3.0", - "lodash": "^4.17.5", - "minimatch": "^3.0.4", - "mkdirp": "^0.5.1", - "natural-compare": "^1.4.0", - "optionator": "^0.8.2", - "path-is-inside": "^1.0.2", - "pluralize": "^7.0.0", - "progress": "^2.0.0", - "regexpp": "^2.0.0", - "require-uncached": "^1.0.3", - "semver": "^5.5.1", - "strip-ansi": "^4.0.0", - "strip-json-comments": "^2.0.1", - "table": "^4.0.3", - "text-table": "^0.2.0" - } - }, - "eslint-scope": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-4.0.0.tgz", - "integrity": "sha512-1G6UTDi7Jc1ELFwnR58HV4fK9OQK4S6N985f166xqXxpjU6plxFISJa2Ba9KCQuFa8RCnj/lSFJbHo7UFDBnUA==", - "dev": true, - "requires": { - "esrecurse": "^4.1.0", - "estraverse": "^4.1.1" - } - }, - "eslint-utils": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-1.3.1.tgz", - "integrity": "sha512-Z7YjnIldX+2XMcjr7ZkgEsOj/bREONV60qYeB/bjMAqqqZ4zxKyWX+BOUkdmRmA9riiIPVvo5x86m5elviOk0Q==", - "dev": true - }, - "eslint-visitor-keys": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.0.0.tgz", - "integrity": "sha512-qzm/XxIbxm/FHyH341ZrbnMUpe+5Bocte9xkmFMzPMjRaZMcXww+MpBptFvtU+79L362nqiLhekCxCxDPaUMBQ==", - "dev": true - }, - "espree": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/espree/-/espree-4.0.0.tgz", - "integrity": "sha512-kapdTCt1bjmspxStVKX6huolXVV5ZfyZguY1lcfhVVZstce3bqxH9mcLzNn3/mlgW6wQ732+0fuG9v7h0ZQoKg==", - "dev": true, - "requires": { - "acorn": "^5.6.0", - "acorn-jsx": "^4.1.1" - } - }, - "esprima": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", - "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", - "dev": true - }, - "esquery": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.0.1.tgz", - "integrity": "sha512-SmiyZ5zIWH9VM+SRUReLS5Q8a7GxtRdxEBVZpm98rJM7Sb+A9DVCndXfkeFUd3byderg+EbDkfnevfCwynWaNA==", - "dev": true, - "requires": { - "estraverse": "^4.0.0" - } - }, - "esrecurse": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.2.1.tgz", - "integrity": "sha512-64RBB++fIOAXPw3P9cy89qfMlvZEXZkqqJkjqqXIvzP5ezRZjW+lPWjw35UX/3EhUPFYbg5ER4JYgDw4007/DQ==", - "dev": true, - "requires": { - "estraverse": "^4.1.0" - } - }, - "estraverse": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.2.0.tgz", - "integrity": "sha1-De4/7TH81GlhjOc0IJn8GvoL2xM=", - "dev": true - }, - "esutils": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.2.tgz", - "integrity": "sha1-Cr9PHKpbyx96nYrMbepPqqBLrJs=", - "dev": true - }, - "external-editor": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-3.0.3.tgz", - "integrity": "sha512-bn71H9+qWoOQKyZDo25mOMVpSmXROAsTJVVVYzrrtol3d4y+AsKjf4Iwl2Q+IuT0kFSQ1qo166UuIwqYq7mGnA==", - "dev": true, - "requires": { - "chardet": "^0.7.0", - "iconv-lite": "^0.4.24", - "tmp": "^0.0.33" - } - }, - "fast-deep-equal": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz", - "integrity": "sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk=", - "dev": true - }, - "fast-json-stable-stringify": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz", - "integrity": "sha1-1RQsDK7msRifh9OnYREGT4bIu/I=", - "dev": true - }, - "fast-levenshtein": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", - "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", - "dev": true - }, - "figures": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/figures/-/figures-2.0.0.tgz", - "integrity": "sha1-OrGi0qYsi/tDGgyUy3l6L84nyWI=", - "dev": true, - "requires": { - "escape-string-regexp": "^1.0.5" - } - }, - "file-entry-cache": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-2.0.0.tgz", - "integrity": "sha1-w5KZDD5oR4PYOLjISkXYoEhFg2E=", - "dev": true, - "requires": { - "flat-cache": "^1.2.1", - "object-assign": "^4.0.1" - } - }, - "flat-cache": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-1.3.0.tgz", - "integrity": "sha1-0wMLMrOBVPTjt+nHCfSQ9++XxIE=", - "dev": true, - "requires": { - "circular-json": "^0.3.1", - "del": "^2.0.2", - "graceful-fs": "^4.1.2", - "write": "^0.2.1" - } - }, - "for-each": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz", - "integrity": "sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==", - "dev": true, - "requires": { - "is-callable": "^1.1.3" - } - }, - "foreach": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/foreach/-/foreach-2.0.5.tgz", - "integrity": "sha1-C+4AUBiusmDQo6865ljdATbsG5k=", - "dev": true - }, - "fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", - "dev": true - }, - "function-bind": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", - "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", - "dev": true - }, - "functional-red-black-tree": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", - "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=", - "dev": true - }, - "glob": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz", - "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "globals": { - "version": "11.7.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-11.7.0.tgz", - "integrity": "sha512-K8BNSPySfeShBQXsahYB/AbbWruVOTyVpgoIDnl8odPpeSfP2J5QO2oLFFdl2j7GfDCtZj2bMKar2T49itTPCg==", - "dev": true - }, - "globby": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/globby/-/globby-5.0.0.tgz", - "integrity": "sha1-69hGZ8oNuzMLmbz8aOrCvFQ3Dg0=", - "dev": true, - "requires": { - "array-union": "^1.0.1", - "arrify": "^1.0.0", - "glob": "^7.0.3", - "object-assign": "^4.0.1", - "pify": "^2.0.0", - "pinkie-promise": "^2.0.0" - } - }, - "graceful-fs": { - "version": "4.1.11", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.11.tgz", - "integrity": "sha1-Dovf5NHduIVNZOBOp8AOKgJuVlg=", - "dev": true - }, - "has": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", - "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", - "dev": true, - "requires": { - "function-bind": "^1.1.1" - } - }, - "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=" - }, - "iconv-lite": { - "version": "0.4.24", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", - "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", - "dev": true, - "requires": { - "safer-buffer": ">= 2.1.2 < 3" - } - }, - "ignore": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", - "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", - "dev": true - }, - "imurmurhash": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", - "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", - "dev": true - }, - "inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", - "dev": true, - "requires": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "inherits": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", - "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", - "dev": true - }, - "inquirer": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-6.2.0.tgz", - "integrity": "sha512-QIEQG4YyQ2UYZGDC4srMZ7BjHOmNk1lR2JQj5UknBapklm6WHA+VVH7N+sUdX3A7NeCfGF8o4X1S3Ao7nAcIeg==", - "dev": true, - "requires": { - "ansi-escapes": "^3.0.0", - "chalk": "^2.0.0", - "cli-cursor": "^2.1.0", - "cli-width": "^2.0.0", - "external-editor": "^3.0.0", - "figures": "^2.0.0", - "lodash": "^4.17.10", - "mute-stream": "0.0.7", - "run-async": "^2.2.0", - "rxjs": "^6.1.0", - "string-width": "^2.1.0", - "strip-ansi": "^4.0.0", - "through": "^2.3.6" - } - }, - "is-arrayish": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.3.2.tgz", - "integrity": "sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==" - }, - "is-callable": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.1.4.tgz", - "integrity": "sha512-r5p9sxJjYnArLjObpjA4xu5EKI3CuKHkJXMhT7kwbpUyIFD1n5PMAsoPvWnvtZiNz7LjkYDRZhd7FlI0eMijEA==", - "dev": true - }, - "is-date-object": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.1.tgz", - "integrity": "sha1-mqIOtq7rv/d/vTPnTKAbM1gdOhY=", - "dev": true - }, - "is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", - "dev": true - }, - "is-path-cwd": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-path-cwd/-/is-path-cwd-1.0.0.tgz", - "integrity": "sha1-0iXsIxMuie3Tj9p2dHLmLmXxEG0=", - "dev": true - }, - "is-path-in-cwd": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-path-in-cwd/-/is-path-in-cwd-1.0.1.tgz", - "integrity": "sha512-FjV1RTW48E7CWM7eE/J2NJvAEEVektecDBVBE5Hh3nM1Jd0kvhHtX68Pr3xsDf857xt3Y4AkwVULK1Vku62aaQ==", - "dev": true, - "requires": { - "is-path-inside": "^1.0.0" - } - }, - "is-path-inside": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-1.0.1.tgz", - "integrity": "sha1-jvW33lBDej/cprToZe96pVy0gDY=", - "dev": true, - "requires": { - "path-is-inside": "^1.0.1" - } - }, - "is-promise": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-2.1.0.tgz", - "integrity": "sha1-eaKp7OfwlugPNtKy87wWwf9L8/o=", - "dev": true - }, - "is-regex": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.0.4.tgz", - "integrity": "sha1-VRdIm1RwkbCTDglWVM7SXul+lJE=", - "dev": true, - "requires": { - "has": "^1.0.1" - } - }, - "is-resolvable": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-resolvable/-/is-resolvable-1.1.0.tgz", - "integrity": "sha512-qgDYXFSR5WvEfuS5dMj6oTMEbrrSaM0CrFk2Yiq/gXnBvD9pMa2jGXxyhGLfvhZpuMZe18CJpFxAt3CRs42NMg==", - "dev": true - }, - "is-symbol": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.1.tgz", - "integrity": "sha1-PMWfAAJRlLarLjjbrmaJJWtmBXI=", - "dev": true - }, - "isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", - "dev": true - }, - "js-tokens": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", - "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", - "dev": true - }, - "js-yaml": { - "version": "3.12.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.12.0.tgz", - "integrity": "sha512-PIt2cnwmPfL4hKNwqeiuz4bKfnzHTBv6HyVgjahA6mPLwPDzjDWrplJBMjHUFxku/N3FlmrbyPclad+I+4mJ3A==", - "dev": true, - "requires": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" - } - }, - "json-schema-traverse": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", - "dev": true - }, - "json-stable-stringify-without-jsonify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", - "integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=", - "dev": true - }, - "levn": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", - "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=", - "dev": true, - "requires": { - "prelude-ls": "~1.1.2", - "type-check": "~0.3.2" - } - }, - "lodash": { - "version": "4.17.11", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.11.tgz", - "integrity": "sha512-cQKh8igo5QUhZ7lg38DYWAxMvjSAKG0A8wGSVimP07SIUEK2UO+arSRKbRZWtelMtN5V0Hkwh5ryOto/SshYIg==", - "dev": true - }, - "mimic-fn": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-1.2.0.tgz", - "integrity": "sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ==", - "dev": true - }, - "minimatch": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", - "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", - "dev": true, - "requires": { - "brace-expansion": "^1.1.7" - } - }, - "minimist": { - "version": "0.0.8", - "resolved": "http://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", - "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=", - "dev": true - }, - "mkdirp": { - "version": "0.5.1", - "resolved": "http://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", - "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", - "dev": true, - "requires": { - "minimist": "0.0.8" - } - }, - "ms": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", - "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==", - "dev": true - }, - "mute-stream": { - "version": "0.0.7", - "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.7.tgz", - "integrity": "sha1-MHXOk7whuPq0PhvE2n6BFe0ee6s=", - "dev": true - }, - "natural-compare": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", - "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=", - "dev": true - }, - "nice-try": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", - "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==", - "dev": true - }, - "object-assign": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", - "dev": true - }, - "object-inspect": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.6.0.tgz", - "integrity": "sha512-GJzfBZ6DgDAmnuaM3104jR4s1Myxr3Y3zfIyN4z3UdqN69oSRacNK8UhnobDdC+7J2AHCjGwxQubNJfE70SXXQ==", - "dev": true - }, - "object-keys": { - "version": "1.0.12", - "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.0.12.tgz", - "integrity": "sha512-FTMyFUm2wBcGHnH2eXmz7tC6IwlqQZ6mVZ+6dm6vZ4IQIHjs6FdNsQBuKGPuUUUY6NfJw2PshC08Tn6LzLDOag==", - "dev": true - }, - "once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", - "dev": true, - "requires": { - "wrappy": "1" - } - }, - "onetime": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-2.0.1.tgz", - "integrity": "sha1-BnQoIw/WdEOyeUsiu6UotoZ5YtQ=", - "dev": true, - "requires": { - "mimic-fn": "^1.0.0" - } - }, - "optionator": { - "version": "0.8.2", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.2.tgz", - "integrity": "sha1-NkxeQJ0/TWMB1sC0wFu6UBgK62Q=", - "dev": true, - "requires": { - "deep-is": "~0.1.3", - "fast-levenshtein": "~2.0.4", - "levn": "~0.3.0", - "prelude-ls": "~1.1.2", - "type-check": "~0.3.2", - "wordwrap": "~1.0.0" - } - }, - "os-tmpdir": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", - "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=", - "dev": true - }, - "path-is-absolute": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", - "dev": true - }, - "path-is-inside": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz", - "integrity": "sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM=", - "dev": true - }, - "path-key": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", - "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=", - "dev": true - }, - "path-parse": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz", - "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==", - "dev": true - }, - "pify": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", - "dev": true - }, - "pinkie": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz", - "integrity": "sha1-clVrgM+g1IqXToDnckjoDtT3+HA=", - "dev": true - }, - "pinkie-promise": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz", - "integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=", - "dev": true, - "requires": { - "pinkie": "^2.0.0" - } - }, - "pluralize": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/pluralize/-/pluralize-7.0.0.tgz", - "integrity": "sha512-ARhBOdzS3e41FbkW/XWrTEtukqqLoK5+Z/4UeDaLuSW+39JPeFgs4gCGqsrJHVZX0fUrx//4OF0K1CUGwlIFow==", - "dev": true - }, - "postcss": { - "version": "7.0.2", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.2.tgz", - "integrity": "sha512-fmaUY5370keLUTx+CnwRxtGiuFTcNBLQBqr1oE3WZ/euIYmGAo0OAgOhVJ3ByDnVmOR3PK+0V9VebzfjRIUcqw==", - "requires": { - "chalk": "^2.4.1", - "source-map": "^0.6.1", - "supports-color": "^5.4.0" - } - }, - "postcss-message-helpers": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/postcss-message-helpers/-/postcss-message-helpers-2.0.0.tgz", - "integrity": "sha1-pPL0+rbk/gAvCu0ABHjN9S+bpg4=" - }, - "prelude-ls": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", - "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=", - "dev": true - }, - "progress": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.0.tgz", - "integrity": "sha1-ihvjZr+Pwj2yvSPxDG/pILQ4nR8=", - "dev": true - }, - "punycode": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", - "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", - "dev": true - }, - "regexpp": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-2.0.0.tgz", - "integrity": "sha512-g2FAVtR8Uh8GO1Nv5wpxW7VFVwHcCEr4wyA8/MHiRkO8uHoR5ntAA8Uq3P1vvMTX/BeQiRVSpDGLd+Wn5HNOTA==", - "dev": true - }, - "require-uncached": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/require-uncached/-/require-uncached-1.0.3.tgz", - "integrity": "sha1-Tg1W1slmL9MeQwEcS5WqSZVUIdM=", - "dev": true, - "requires": { - "caller-path": "^0.1.0", - "resolve-from": "^1.0.0" - } - }, - "resolve-from": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-1.0.1.tgz", - "integrity": "sha1-Jsv+k10a7uq7Kbw/5a6wHpPUQiY=", - "dev": true - }, - "restore-cursor": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-2.0.0.tgz", - "integrity": "sha1-n37ih/gv0ybU/RYpI9YhKe7g368=", - "dev": true, - "requires": { - "onetime": "^2.0.0", - "signal-exit": "^3.0.2" - } - }, - "resumer": { - "version": "0.0.0", - "resolved": "https://registry.npmjs.org/resumer/-/resumer-0.0.0.tgz", - "integrity": "sha1-8ej0YeQGS6Oegq883CqMiT0HZ1k=", - "dev": true, - "requires": { - "through": "~2.3.4" - } - }, - "rimraf": { - "version": "2.6.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.2.tgz", - "integrity": "sha512-lreewLK/BlghmxtfH36YYVg1i8IAce4TI7oao75I1g245+6BctqTVQiBP3YUJ9C6DQOXJmkYR9X9fCLtCOJc5w==", - "dev": true, - "requires": { - "glob": "^7.0.5" - } - }, - "run-async": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.3.0.tgz", - "integrity": "sha1-A3GrSuC91yDUFm19/aZP96RFpsA=", - "dev": true, - "requires": { - "is-promise": "^2.1.0" - } - }, - "rxjs": { - "version": "6.3.2", - "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.3.2.tgz", - "integrity": "sha512-hV7criqbR0pe7EeL3O66UYVg92IR0XsA97+9y+BWTePK9SKmEI5Qd3Zj6uPnGkNzXsBywBQWTvujPl+1Kn9Zjw==", - "dev": true, - "requires": { - "tslib": "^1.9.0" - } - }, - "safer-buffer": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", - "dev": true - }, - "semver": { - "version": "5.5.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.5.1.tgz", - "integrity": "sha512-PqpAxfrEhlSUWge8dwIp4tZnQ25DIOthpiaHNIthsjEFQD6EvqUKUDM7L8O2rShkFccYo1VjJR0coWfNkCubRw==", - "dev": true - }, - "shebang-command": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", - "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=", - "dev": true, - "requires": { - "shebang-regex": "^1.0.0" - } - }, - "shebang-regex": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", - "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=", - "dev": true - }, - "signal-exit": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz", - "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=", - "dev": true - }, - "simple-swizzle": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/simple-swizzle/-/simple-swizzle-0.2.2.tgz", - "integrity": "sha1-pNprY1/8zMoz9w0Xy5JZLeleVXo=", - "requires": { - "is-arrayish": "^0.3.1" - } - }, - "slice-ansi": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-1.0.0.tgz", - "integrity": "sha512-POqxBK6Lb3q6s047D/XsDVNPnF9Dl8JSaqe9h9lURl0OdNqy/ujDrOiIHtsqXMGbWWTIomRzAMaTyawAU//Reg==", - "dev": true, - "requires": { - "is-fullwidth-code-point": "^2.0.0" - } - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" - }, - "sprintf-js": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", - "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", - "dev": true - }, - "string-width": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", - "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", - "dev": true, - "requires": { - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^4.0.0" - } - }, - "string.prototype.trim": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.1.2.tgz", - "integrity": "sha1-0E3iyJ4Tf019IG8Ia17S+ua+jOo=", - "dev": true, - "requires": { - "define-properties": "^1.1.2", - "es-abstract": "^1.5.0", - "function-bind": "^1.0.2" - } - }, - "strip-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", - "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", - "dev": true, - "requires": { - "ansi-regex": "^3.0.0" - } - }, - "strip-json-comments": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", - "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=", - "dev": true - }, - "supports-color": { - "version": "5.4.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.4.0.tgz", - "integrity": "sha512-zjaXglF5nnWpsq470jSv6P9DwPvgLkuapYmfDm3JWOm0vkNTVF2tI4UrN2r6jH1qM/uc/WtxYY1hYoA2dOKj5w==", - "requires": { - "has-flag": "^3.0.0" - } - }, - "table": { - "version": "4.0.3", - "resolved": "http://registry.npmjs.org/table/-/table-4.0.3.tgz", - "integrity": "sha512-S7rnFITmBH1EnyKcvxBh1LjYeQMmnZtCXSEbHcH6S0NoKit24ZuFO/T1vDcLdYsLQkM188PVVhQmzKIuThNkKg==", - "dev": true, - "requires": { - "ajv": "^6.0.1", - "ajv-keywords": "^3.0.0", - "chalk": "^2.1.0", - "lodash": "^4.17.4", - "slice-ansi": "1.0.0", - "string-width": "^2.1.1" - } - }, - "tape": { - "version": "4.9.1", - "resolved": "https://registry.npmjs.org/tape/-/tape-4.9.1.tgz", - "integrity": "sha512-6fKIXknLpoe/Jp4rzHKFPpJUHDHDqn8jus99IfPnHIjyz78HYlefTGD3b5EkbQzuLfaEvmfPK3IolLgq2xT3kw==", - "dev": true, - "requires": { - "deep-equal": "~1.0.1", - "defined": "~1.0.0", - "for-each": "~0.3.3", - "function-bind": "~1.1.1", - "glob": "~7.1.2", - "has": "~1.0.3", - "inherits": "~2.0.3", - "minimist": "~1.2.0", - "object-inspect": "~1.6.0", - "resolve": "~1.7.1", - "resumer": "~0.0.0", - "string.prototype.trim": "~1.1.2", - "through": "~2.3.8" - }, - "dependencies": { - "minimist": { - "version": "1.2.0", - "resolved": "http://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", - "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", - "dev": true - }, - "resolve": { - "version": "1.7.1", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.7.1.tgz", - "integrity": "sha512-c7rwLofp8g1U+h1KNyHL/jicrKg1Ek4q+Lr33AL65uZTinUZHe30D5HlyN5V9NW0JX1D5dXQ4jqW5l7Sy/kGfw==", - "dev": true, - "requires": { - "path-parse": "^1.0.5" - } - } - } - }, - "text-table": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", - "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=", - "dev": true - }, - "through": { - "version": "2.3.8", - "resolved": "http://registry.npmjs.org/through/-/through-2.3.8.tgz", - "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=", - "dev": true - }, - "tmp": { - "version": "0.0.33", - "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", - "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", - "dev": true, - "requires": { - "os-tmpdir": "~1.0.2" - } - }, - "tslib": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.9.3.tgz", - "integrity": "sha512-4krF8scpejhaOgqzBEcGM7yDIEfi0/8+8zDRZhNZZ2kjmHJ4hv3zCbQWxoJGz1iw5U0Jl0nma13xzHXcncMavQ==", - "dev": true - }, - "type-check": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", - "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=", - "dev": true, - "requires": { - "prelude-ls": "~1.1.2" - } - }, - "uri-js": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.2.2.tgz", - "integrity": "sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ==", - "dev": true, - "requires": { - "punycode": "^2.1.0" - } - }, - "which": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", - "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", - "dev": true, - "requires": { - "isexe": "^2.0.0" - } - }, - "wordwrap": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", - "integrity": "sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus=", - "dev": true - }, - "wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", - "dev": true - }, - "write": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/write/-/write-0.2.1.tgz", - "integrity": "sha1-X8A4KOJkzqP+kUVUdvejxWbLB1c=", - "dev": true, - "requires": { - "mkdirp": "^0.5.1" - } - } - } -} diff --git a/package.json b/package.json index 49a7427f60..45fce41d62 100644 --- a/package.json +++ b/package.json @@ -1,40 +1,67 @@ { "name": "postcss-color-hex-alpha", - "version": "4.0.0", - "description": "PostCSS plugin to transform W3C RGBA hexadecimal notations (#RRGGBBAA or #RGBA) to more compatible CSS (rgba())", - "keywords": [ - "css", - "postcss", - "postcss-plugin", - "color", - "colour", - "hexa", - "alpha" + "version": "5.0.0", + "description": "Use 4 & 8 character hex color notation in CSS", + "author": "Jonathan Neal ", + "contributors": [ + "Maxime Thirouin" ], - "author": "Maxime Thirouin", "license": "MIT", - "repository": { - "type": "git", - "url": "https://github.com/postcss/postcss-color-hex-alpha.git" - }, + "repository": "postcss/postcss-color-hex-alpha", + "homepage": "https://github.com/postcss/postcss-color-hex-alpha#readme", + "bugs": "https://github.com/postcss/postcss-color-hex-alpha/issues", + "main": "index.cjs.js", + "module": "index.es.mjs", "files": [ - "index.js" + "index.cjs.js", + "index.cjs.js.map", + "index.es.mjs", + "index.es.mjs.map" ], + "scripts": { + "prepublishOnly": "npm test", + "pretest": "rollup -c .rollup.js --silent", + "test": "echo 'Running tests...'; npm run test:js && npm run test:tape", + "test:js": "eslint *.js --cache --ignore-path .gitignore --quiet", + "test:tape": "postcss-tape" + }, "engines": { "node": ">=6.0.0" }, "dependencies": { - "color": "^3.0.0", "postcss": "^7.0.2", - "postcss-message-helpers": "^2.0.0" + "postcss-values-parser": "^1.5.0" }, "devDependencies": { + "@babel/core": "^7.1.0", + "@babel/plugin-syntax-dynamic-import": "^7.0.0", + "@babel/preset-env": "^7.1.0", + "babel-eslint": "^9.0.0", "eslint": "^5.6.0", - "tape": "^4.9.1" + "eslint-config-dev": "^2.0.0", + "postcss-tape": "^2.2.0", + "pre-commit": "^1.2.2", + "rollup": "^0.66.0", + "rollup-plugin-babel": "^4.0.3" }, - "scripts": { - "lint": "eslint *.js index.js ./test/", - "test": "npm run lint && tape test", - "release": "npmpub" - } + "eslintConfig": { + "extends": "dev", + "parser": "babel-eslint" + }, + "keywords": [ + "postcss", + "css", + "postcss-plugin", + "color", + "hex", + "alpha", + "transparent", + "transparency", + "4-digit", + "8-digit", + "w3c", + "csswg", + "specification", + "spec" + ] } diff --git a/test/basic.css b/test/basic.css new file mode 100644 index 0000000000..9d0f9dd129 --- /dev/null +++ b/test/basic.css @@ -0,0 +1,10 @@ +body { + background: #9d9 linear-gradient(#9823f8a9, #9823f834); + color: red; + color: #f00; + color: #f00f; + color: #0000ff; + color: #0000ff00; + content: "#f00"; + content: "#0000ff00"; +} diff --git a/test/basic.expect.css b/test/basic.expect.css new file mode 100644 index 0000000000..c0dd177bd4 --- /dev/null +++ b/test/basic.expect.css @@ -0,0 +1,10 @@ +body { + background: #9d9 linear-gradient(rgba(169,35,248,169), rgba(52,35,248,52)); + color: red; + color: #f00; + color: rgba(255,0,0,255); + color: #0000ff; + color: rgba(0,0,255,0); + content: "#f00"; + content: "#0000ff00"; +} diff --git a/test/basic.preserve.expect.css b/test/basic.preserve.expect.css new file mode 100644 index 0000000000..eb0fc74fc3 --- /dev/null +++ b/test/basic.preserve.expect.css @@ -0,0 +1,13 @@ +body { + background: #9d9 linear-gradient(rgba(169,35,248,169), rgba(52,35,248,52)); + background: #9d9 linear-gradient(#9823f8a9, #9823f834); + color: red; + color: #f00; + color: rgba(255,0,0,255); + color: #f00f; + color: #0000ff; + color: rgba(0,0,255,0); + color: #0000ff00; + content: "#f00"; + content: "#0000ff00"; +} diff --git a/test/fixtures/hex-alpha.css b/test/fixtures/hex-alpha.css deleted file mode 100644 index 9d91b22d70..0000000000 --- a/test/fixtures/hex-alpha.css +++ /dev/null @@ -1,8 +0,0 @@ -body { - color: red; - color: #9d9; - color: #9d9c; - color: #9823f8; - color: #9823f834; - background: #9d9 linear-gradient(#9823f8a9, #9823f834); -} diff --git a/test/fixtures/hex-alpha.expected.css b/test/fixtures/hex-alpha.expected.css deleted file mode 100644 index 068bd971c8..0000000000 --- a/test/fixtures/hex-alpha.expected.css +++ /dev/null @@ -1,8 +0,0 @@ -body { - color: red; - color: #9d9; - color: rgba(153, 221, 153, 0.8); - color: #9823f8; - color: rgba(152, 35, 248, 0.20392); - background: #9d9 linear-gradient(rgba(152, 35, 248, 0.66275), rgba(152, 35, 248, 0.20392)); -} diff --git a/test/index.js b/test/index.js deleted file mode 100755 index de49833831..0000000000 --- a/test/index.js +++ /dev/null @@ -1,33 +0,0 @@ -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 transform(css, options) { - return postcss(plugin(options)).process(css).css -} - -function compareFixtures(t, name, msg, opts, postcssOpts) { - postcssOpts = postcssOpts || {} - postcssOpts.from = filename("fixtures/" + name) - opts = opts || {} - var actual = transform(read(postcssOpts.from), postcssOpts) - var expected = read(filename("fixtures/" + name + ".expected")) - fs.writeFileSync(filename("fixtures/" + name + ".actual"), actual) - t.equal(actual, expected, msg) -} - -test("hex alpha (#RRGGBBAA or #RGBA)", function(t) { - compareFixtures(t, "hex-alpha", "should transform #RRGGBBAA and #RGBA") - t.end() -}) From f980266b4ceecb714fc9a7dbb98b472839eef828 Mon Sep 17 00:00:00 2001 From: Jonathan Neal Date: Tue, 18 Sep 2018 03:30:04 -0400 Subject: [PATCH 707/795] 5.0.1 --- CHANGELOG.md | 4 ++++ index.js | 10 +++++++++- package.json | 2 +- test/basic.css | 5 +++++ test/basic.expect.css | 9 +++++++-- test/basic.preserve.expect.css | 11 +++++++++-- 6 files changed, 35 insertions(+), 6 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 195a3e37b1..c1cb627346 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # Changes to PostCSS Color Hex Alpha +### 5.0.1 (September 18, 2018) + +- Fixed: Issue correclty calculating each channel + ### 5.0.0 (September 18, 2018) - Initial version diff --git a/index.js b/index.js index acf4e6b7ba..5b40aac7da 100755 --- a/index.js +++ b/index.js @@ -53,6 +53,9 @@ const walk = (node, fn) => { } }; +// decimal precision +const alphaDecimalPrecision = 100000; + // match a hexa node const isAlphaHex = node => node.type === 'word' && alphaHexValueRegExp.test(node.value); @@ -64,7 +67,12 @@ const hexa2rgba = node => { const hex8 = `0x${hex.length === 5 ? hex.slice(1).replace(/[0-9A-f]/g, '$&$&') : hex.slice(1)}`; // extract the red, blue, green, and alpha values from the hex - const [r, g, b, a] = [ hex8 >> 32 & 255, hex8 >> 16 & 255, hex8 >> 8 & 255, hex8 & 255 ]; + const [r, g, b, a] = [ + parseInt(hex8.slice(2, 4), 16), + parseInt(hex8.slice(4, 6), 16), + parseInt(hex8.slice(6, 8), 16), + Math.round(parseInt(hex8.slice(8, 10), 16) / 255 * alphaDecimalPrecision) / alphaDecimalPrecision + ]; // return a new rgba function, preserving the whitespace of the original node const rgbaFunc = valueParser.func({ value: 'rgba', raws: Object.assign({}, node.raws) }); diff --git a/package.json b/package.json index 45fce41d62..90ccbfa9c7 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "postcss-color-hex-alpha", - "version": "5.0.0", + "version": "5.0.1", "description": "Use 4 & 8 character hex color notation in CSS", "author": "Jonathan Neal ", "contributors": [ diff --git a/test/basic.css b/test/basic.css index 9d0f9dd129..b94ebabfd2 100644 --- a/test/basic.css +++ b/test/basic.css @@ -8,3 +8,8 @@ body { content: "#f00"; content: "#0000ff00"; } + +body { + background-color: #f3f3f3f3; + color: #0003; +} diff --git a/test/basic.expect.css b/test/basic.expect.css index c0dd177bd4..b55018312f 100644 --- a/test/basic.expect.css +++ b/test/basic.expect.css @@ -1,10 +1,15 @@ body { - background: #9d9 linear-gradient(rgba(169,35,248,169), rgba(52,35,248,52)); + background: #9d9 linear-gradient(rgba(152,35,248,0.66275), rgba(152,35,248,0.20392)); color: red; color: #f00; - color: rgba(255,0,0,255); + color: rgba(255,0,0,1); color: #0000ff; color: rgba(0,0,255,0); content: "#f00"; content: "#0000ff00"; } + +body { + background-color: rgba(243,243,243,0.95294); + color: rgba(0,0,0,0.2); +} diff --git a/test/basic.preserve.expect.css b/test/basic.preserve.expect.css index eb0fc74fc3..057864f8a9 100644 --- a/test/basic.preserve.expect.css +++ b/test/basic.preserve.expect.css @@ -1,9 +1,9 @@ body { - background: #9d9 linear-gradient(rgba(169,35,248,169), rgba(52,35,248,52)); + background: #9d9 linear-gradient(rgba(152,35,248,0.66275), rgba(152,35,248,0.20392)); background: #9d9 linear-gradient(#9823f8a9, #9823f834); color: red; color: #f00; - color: rgba(255,0,0,255); + color: rgba(255,0,0,1); color: #f00f; color: #0000ff; color: rgba(0,0,255,0); @@ -11,3 +11,10 @@ body { content: "#f00"; content: "#0000ff00"; } + +body { + background-color: rgba(243,243,243,0.95294); + background-color: #f3f3f3f3; + color: rgba(0,0,0,0.2); + color: #0003; +} From 849b9606b1461c8b07972d2222020913b1872b0e Mon Sep 17 00:00:00 2001 From: Jonathan Neal Date: Tue, 18 Sep 2018 10:44:43 -0400 Subject: [PATCH 708/795] 2.0.1 --- CHANGELOG.md | 4 ++++ index.js | 46 ++++++++++++++++++++++++---------------------- package.json | 10 +++++----- 3 files changed, 33 insertions(+), 27 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e94f937522..90dfa10dc4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # Changes to PostCSS Color Functional Notation +### 2.0.1 (September 18, 2018) + +- Updated: PostCSS Values Parser 2 (patch for this project) + ### 2.0.0 (September 17, 2018) - Updated: Support for PostCSS v7+ diff --git a/index.js b/index.js index 3769674c47..66f0bc4904 100644 --- a/index.js +++ b/index.js @@ -1,17 +1,17 @@ import postcss from 'postcss'; -import parser from 'postcss-values-parser'; +import valuesParser from 'postcss-values-parser'; export default postcss.plugin('postcss-color-functional-notation', opts => { const preserve = 'preserve' in Object(opts) ? Boolean(opts.preserve) : false; return root => { root.walkDecls(decl => { - const { value } = decl; + const { value: originalValue } = decl; - if (colorAnyRegExp.test(value)) { - const ast = parser(value).parse(); + if (colorAnyRegExp.test(originalValue)) { + const valueAST = valuesParser(originalValue).parse(); - ast.walkType('func', node => { + valueAST.walkType('func', node => { if (colorRegExp.test(node.value)) { const children = node.nodes.slice(1, -1); const isFunctionalHSL = matchFunctionalHSL(node, children); @@ -35,7 +35,7 @@ export default postcss.plugin('postcss-color-functional-notation', opts => { node.value = node.value.slice(0, -1); } - if (isSlash(slashNode)) { + if (slashNode && isSlash(slashNode)) { slashNode.replaceWith( newComma() ); } @@ -53,12 +53,14 @@ export default postcss.plugin('postcss-color-functional-notation', opts => { } }); - const newValue = String(ast); + const modifiedValue = String(valueAST); - if (preserve) { - decl.cloneBefore({ value: newValue }); - } else { - decl.value = newValue; + if (modifiedValue !== originalValue) { + if (preserve) { + decl.cloneBefore({ value: modifiedValue }); + } else { + decl.value = modifiedValue; + } } } }); @@ -74,16 +76,16 @@ const hslRgbFuncMatch = /^(hsl|rgb)$/i; const hslaRgbaFuncMatch = /^(hsla|rgba)$/i; const hueUnitMatch = /^(deg|grad|rad|turn)?$/i; const rgbishRegExp = /^rgba?$/i; -const isAlphaValue = node => isCalc(node) || Object(node).type === 'number' && alphaUnitMatch.test(node.unit); -const isCalc = node => Object(node).type === 'func' && calcFuncMatch.test(node.value); -const isHue = node => isCalc(node) || Object(node).type === 'number' && hueUnitMatch.test(node.unit); -const isNumber = node => isCalc(node) || Object(node).type === 'number' && node.unit === ''; -const isPercentage = node => isCalc(node) || Object(node).type === 'number' && (node.unit === '%' || node.unit === '' && node.value === '0'); -const isHslish = node => Object(node).type === 'func' && hslishRegExp.test(node.value); -const isHslRgb = node => Object(node).type === 'func' && hslRgbFuncMatch.test(node.value); -const isHslaRgba = node => Object(node).type === 'func' && hslaRgbaFuncMatch.test(node.value); -const isRgbish = node => Object(node).type === 'func' && rgbishRegExp.test(node.value); -const isSlash = node => Object(node).type === 'operator' && node.value === '/'; +const isAlphaValue = node => isCalc(node) || node.type === 'number' && alphaUnitMatch.test(node.unit); +const isCalc = node => node.type === 'func' && calcFuncMatch.test(node.value); +const isHue = node => isCalc(node) || node.type === 'number' && hueUnitMatch.test(node.unit); +const isNumber = node => isCalc(node) || node.type === 'number' && node.unit === ''; +const isPercentage = node => isCalc(node) || node.type === 'number' && (node.unit === '%' || node.unit === '' && node.value === '0'); +const isHslish = node => node.type === 'func' && hslishRegExp.test(node.value); +const isHslRgb = node => node.type === 'func' && hslRgbFuncMatch.test(node.value); +const isHslaRgba = node => node.type === 'func' && hslaRgbaFuncMatch.test(node.value); +const isRgbish = node => node.type === 'func' && rgbishRegExp.test(node.value); +const isSlash = node => node.type === 'operator' && node.value === '/'; const functionalHSLMatch = [isHue, isPercentage, isPercentage, isSlash, isAlphaValue]; const functionalRGB1Match = [isNumber, isNumber, isNumber, isSlash, isAlphaValue]; const functionalRGB2Match = [isPercentage, isPercentage, isPercentage, isSlash, isAlphaValue]; @@ -98,4 +100,4 @@ const matchFunctionalRGB2 = (node, children) => isRgbish(node) && children.every (child, index) => typeof functionalRGB2Match[index] === 'function' && functionalRGB2Match[index](child) ); -const newComma = () => parser.comma({ value: ',' }) +const newComma = () => valuesParser.comma({ value: ',' }) diff --git a/package.json b/package.json index d2ed563e6b..96fda45be1 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "postcss-color-functional-notation", - "version": "2.0.0", + "version": "2.0.1", "description": "Use space and slash separated color notation in CSS", "author": "Jonathan Neal ", "license": "CC0-1.0", @@ -28,18 +28,18 @@ }, "dependencies": { "postcss": "^7.0.2", - "postcss-values-parser": "^1.5.0" + "postcss-values-parser": "^2.0.0" }, "devDependencies": { - "@babel/core": "^7.0.0", - "@babel/preset-env": "^7.0.0", + "@babel/core": "^7.1.0", + "@babel/preset-env": "^7.1.0", "babel-eslint": "^9.0.0", "eslint": "^5.6.0", "eslint-config-dev": "^2.0.0", "postcss-tape": "^2.2.0", "pre-commit": "^1.2.2", "rollup": "^0.66.0", - "rollup-plugin-babel": "^4.0.1" + "rollup-plugin-babel": "^4.0.3" }, "eslintConfig": { "extends": "dev", From d3fafd278e0427df8e4ed06f477c0fa26edefb0d Mon Sep 17 00:00:00 2001 From: Jonathan Neal Date: Tue, 18 Sep 2018 11:13:57 -0400 Subject: [PATCH 709/795] 5.0.2 --- CHANGELOG.md | 4 ++++ package.json | 4 ++-- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c1cb627346..42ff03a6dc 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # Changes to PostCSS Color Hex Alpha +### 5.0.2 (September 18, 2018) + +- Updated: PostCSS Values Parser 2 (patch for this project) + ### 5.0.1 (September 18, 2018) - Fixed: Issue correclty calculating each channel diff --git a/package.json b/package.json index 90ccbfa9c7..dbcc466106 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "postcss-color-hex-alpha", - "version": "5.0.1", + "version": "5.0.2", "description": "Use 4 & 8 character hex color notation in CSS", "author": "Jonathan Neal ", "contributors": [ @@ -30,7 +30,7 @@ }, "dependencies": { "postcss": "^7.0.2", - "postcss-values-parser": "^1.5.0" + "postcss-values-parser": "^2.0.0" }, "devDependencies": { "@babel/core": "^7.1.0", From b956f0130fc324ede73e1ff18e22cc45a231561f Mon Sep 17 00:00:00 2001 From: Jonathan Neal Date: Tue, 18 Sep 2018 11:40:32 -0400 Subject: [PATCH 710/795] 4.0.1 --- CHANGELOG.md | 4 ++++ package.json | 10 +++++----- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3c66fafe95..6b6ae0b275 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # Changes to PostCSS Place Properties +### 4.0.1 (September 18, 2018) + +- Updated: PostCSS Values Parser 2 (patch for this project) + ### 4.0.0 (September 17, 2018) - Updated: Support for PostCSS v7+ diff --git a/package.json b/package.json index 73b024ded6..04f3575879 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "postcss-place", - "version": "4.0.0", + "version": "4.0.1", "description": "Use a place-* shorthand for align-* and justify-* in CSS", "author": "Jonathan Neal ", "license": "CC0-1.0", @@ -28,18 +28,18 @@ }, "dependencies": { "postcss": "^7.0.2", - "postcss-values-parser": "^1.5.0" + "postcss-values-parser": "^2.0.0" }, "devDependencies": { - "@babel/core": "^7.0.0", - "@babel/preset-env": "^7.0.0", + "@babel/core": "^7.1.0", + "@babel/preset-env": "^7.1.0", "babel-eslint": "^9.0.0", "eslint": "^5.6.0", "eslint-config-dev": "^2.0.0", "postcss-tape": "^2.2.0", "pre-commit": "^1.2.2", "rollup": "^0.66.0", - "rollup-plugin-babel": "^4.0.1" + "rollup-plugin-babel": "^4.0.3" }, "eslintConfig": { "extends": "dev", From 325c378768d1a353af4effdc7ca1a1f82384fc2e Mon Sep 17 00:00:00 2001 From: Jonathan Neal Date: Tue, 18 Sep 2018 11:45:52 -0400 Subject: [PATCH 711/795] 2.0.1 --- CHANGELOG.md | 8 ++++++-- INSTALL.md | 2 +- index.js | 14 +++++++------- package.json | 10 +++++----- 4 files changed, 19 insertions(+), 15 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 98fa94373c..540f11ffca 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,9 +1,13 @@ # Changes to PostCSS Lab Function +### 2.0.1 (September 18, 2018) + +- Updated: PostCSS Values Parser 2.0.0 + ### 2.0.0 (September 17, 2018) -- Updated: Support for PostCSS v7+ -- Updated: Support for Node v6+ +- Updated: Support for PostCSS 7+ +- Updated: Support for Node 6+ ### 1.1.0 (July 24, 2018) diff --git a/INSTALL.md b/INSTALL.md index 74a3344c8e..a123e2d153 100644 --- a/INSTALL.md +++ b/INSTALL.md @@ -1,4 +1,4 @@ -# Installing PostCSS +# Installing PostCSS Lab Function [PostCSS Lab Function] runs in all Node environments, with special instructions for: diff --git a/index.js b/index.js index ff94a81a78..44e1e1fee8 100644 --- a/index.js +++ b/index.js @@ -41,7 +41,7 @@ export default postcss.plugin('postcss-lab-function', opts => { } } - if (isSlash(slashNode)) { + if (slashNode && isSlash(slashNode)) { slashNode.replaceWith( newComma() ); } @@ -129,12 +129,12 @@ const alphaUnitMatch = /^%?$/i; const calcFuncMatch = /^calc$/i; const hueUnitMatch = /^(deg|grad|rad|turn)?$/i; -const isAlphaValue = node => isCalc(node) || Object(node).type === 'number' && alphaUnitMatch.test(node.unit); -const isCalc = node => Object(node).type === 'func' && calcFuncMatch.test(node.value); -const isHue = node => isCalc(node) || Object(node).type === 'number' && hueUnitMatch.test(node.unit); -const isNumber = node => isCalc(node) || Object(node).type === 'number' && node.unit === ''; -const isPercentage = node => isCalc(node) || Object(node).type === 'number' && node.unit === '%'; -const isSlash = node => Object(node).type === 'operator' && node.value === '/'; +const isAlphaValue = node => isCalc(node) || node.type === 'number' && alphaUnitMatch.test(node.unit); +const isCalc = node => node.type === 'func' && calcFuncMatch.test(node.value); +const isHue = node => isCalc(node) || node.type === 'number' && hueUnitMatch.test(node.unit); +const isNumber = node => isCalc(node) || node.type === 'number' && node.unit === ''; +const isPercentage = node => isCalc(node) || node.type === 'number' && node.unit === '%'; +const isSlash = node => node.type === 'operator' && node.value === '/'; const functionalLABMatch = [isNumber, isNumber, isNumber, isSlash, isAlphaValue]; const functionalLCHMatch = [isNumber, isNumber, isHue, isSlash, isAlphaValue]; const functionalGrayMatch = [isNumber, isSlash, isAlphaValue]; diff --git a/package.json b/package.json index 77db8039a1..47bf792dfd 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "postcss-lab-function", - "version": "2.0.0", + "version": "2.0.1", "description": "Use lab() and lch() color functions in CSS", "author": "Jonathan Neal ", "license": "CC0-1.0", @@ -29,18 +29,18 @@ "dependencies": { "@csstools/convert-colors": "^1.4.0", "postcss": "^7.0.2", - "postcss-values-parser": "^1.5.0" + "postcss-values-parser": "^2.0.0" }, "devDependencies": { - "@babel/core": "^7.0.0", - "@babel/preset-env": "^7.0.0", + "@babel/core": "^7.1.0", + "@babel/preset-env": "^7.1.0", "babel-eslint": "^9.0.0", "eslint": "^5.6.0", "eslint-config-dev": "^2.0.0", "postcss-tape": "^2.2.0", "pre-commit": "^1.2.2", "rollup": "^0.66.0", - "rollup-plugin-babel": "^4.0.1" + "rollup-plugin-babel": "^4.0.3" }, "eslintConfig": { "extends": "dev", From b64c388c4e0d6c347177de60bccd81109a104f80 Mon Sep 17 00:00:00 2001 From: Jonathan Neal Date: Tue, 18 Sep 2018 11:56:38 -0400 Subject: [PATCH 712/795] 3.0.0 --- .appveyor.yml | 18 ------ .gitignore | 3 +- .rollup.js | 6 +- .travis.yml | 2 +- CHANGELOG.md | 5 ++ INSTALL.md | 171 ++++++++++++++++++++++++++++++++++++++++++++++++++ README.md | 115 ++++----------------------------- index.js | 6 +- package.json | 22 ++++--- 9 files changed, 207 insertions(+), 141 deletions(-) delete mode 100644 .appveyor.yml create mode 100644 INSTALL.md diff --git a/.appveyor.yml b/.appveyor.yml deleted file mode 100644 index acbf8a5eeb..0000000000 --- a/.appveyor.yml +++ /dev/null @@ -1,18 +0,0 @@ -# https://www.appveyor.com/docs/appveyor-yml - -environment: - matrix: - - nodejs_version: 4 - -version: "{build}" -build: off -deploy: off - -install: - - ps: Install-Product node $env:nodejs_version - - npm install --ignore-scripts - -test_script: - - node --version - - npm --version - - cmd: "npm test" diff --git a/.gitignore b/.gitignore index de73e5a338..d920b78fec 100644 --- a/.gitignore +++ b/.gitignore @@ -1,10 +1,9 @@ node_modules -index.*.js +index.*.* package-lock.json *.log* *.result.css .* -!.appveyor.yml !.editorconfig !.gitignore !.rollup.js diff --git a/.rollup.js b/.rollup.js index 0436758216..ebe39f9220 100644 --- a/.rollup.js +++ b/.rollup.js @@ -3,13 +3,13 @@ import babel from 'rollup-plugin-babel'; export default { input: 'index.js', output: [ - { file: 'index.cjs.js', format: 'cjs' }, - { file: 'index.es.js', format: 'es' } + { file: 'index.cjs.js', format: 'cjs', sourcemap: true }, + { file: 'index.es.mjs', format: 'es', sourcemap: true } ], plugins: [ babel({ presets: [ - ['env', { modules: false, targets: { node: 4 } }] + ['@babel/env', { modules: false, targets: { node: 6 } }] ] }) ] diff --git a/.travis.yml b/.travis.yml index c56466446c..e1f11a52e6 100644 --- a/.travis.yml +++ b/.travis.yml @@ -3,7 +3,7 @@ language: node_js node_js: - - 4 + - 6 install: - npm install --ignore-scripts diff --git a/CHANGELOG.md b/CHANGELOG.md index 9119c00317..75ef4709dd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,10 @@ # Changes to PostCSS image-set() Function +### 3.0.0 (September 17, 2018) + +- Updated: Support for PostCSS 7+ +- Updated: Support for Node 6+ + ### 2.0.0 (May 7, 2018) - Sort images by DPR and use the lowest as the default diff --git a/INSTALL.md b/INSTALL.md new file mode 100644 index 0000000000..0f66ae653f --- /dev/null +++ b/INSTALL.md @@ -0,0 +1,171 @@ +# Installing PostCSS + +[PostCSS image-set() Function] runs in all Node environments, with special instructions for: + +| [Node](#node) | [PostCSS CLI](#postcss-cli) | [Webpack](#webpack) | [Create React App](#create-react-app) | [Gulp](#gulp) | [Grunt](#grunt) | +| --- | --- | --- | --- | --- | --- | + +## Node + +Add [PostCSS image-set() Function] to your project: + +```bash +npm install postcss-image-set-function --save-dev +``` + +Use [PostCSS image-set() Function] to process your CSS: + +```js +const postcssImageSetFunction = require('postcss-image-set-function'); + +postcssImageSetFunction.process(YOUR_CSS /*, processOptions, pluginOptions */); +``` + +Or use it as a [PostCSS] plugin: + +```js +const postcss = require('postcss'); +const postcssImageSetFunction = require('postcss-image-set-function'); + +postcss([ + postcssImageSetFunction(/* pluginOptions */) +]).process(YOUR_CSS /*, processOptions */); +``` + +## PostCSS CLI + +Add [PostCSS CLI] to your project: + +```bash +npm install postcss-cli --save-dev +``` + +Use [PostCSS image-set() Function] in your `postcss.config.js` configuration +file: + +```js +const postcssImageSetFunction = require('postcss-image-set-function'); + +module.exports = { + plugins: [ + postcssImageSetFunction(/* pluginOptions */) + ] +} +``` + +## Webpack + +Add [PostCSS Loader] to your project: + +```bash +npm install postcss-loader --save-dev +``` + +Use [PostCSS image-set() Function] in your Webpack configuration: + +```js +const postcssImageSetFunction = require('postcss-image-set-function'); + +module.exports = { + module: { + rules: [ + { + test: /\.css$/, + use: [ + 'style-loader', + { loader: 'css-loader', options: { importLoaders: 1 } }, + { loader: 'postcss-loader', options: { + ident: 'postcss', + plugins: () => [ + postcssImageSetFunction(/* pluginOptions */) + ] + } } + ] + } + ] + } +} +``` + +## Create React App + +Add [React App Rewired] and [React App Rewire PostCSS] to your project: + +```bash +npm install react-app-rewired react-app-rewire-postcss --save-dev +``` + +Use [React App Rewire PostCSS] and [PostCSS image-set() Function] in your +`config-overrides.js` file: + +```js +const reactAppRewirePostcss = require('react-app-rewire-postcss'); +const postcssImageSetFunction = require('postcss-image-set-function'); + +module.exports = config => reactAppRewirePostcss(config, { + plugins: () => [ + postcssImageSetFunction(/* pluginOptions */) + ] +}); +``` + +## Gulp + +Add [Gulp PostCSS] to your project: + +```bash +npm install gulp-postcss --save-dev +``` + +Use [PostCSS image-set() Function] in your Gulpfile: + +```js +const postcss = require('gulp-postcss'); +const postcssImageSetFunction = require('postcss-image-set-function'); + +gulp.task('css', () => gulp.src('./src/*.css').pipe( + postcss([ + postcssImageSetFunction(/* pluginOptions */) + ]) +).pipe( + gulp.dest('.') +)); +``` + +## Grunt + +Add [Grunt PostCSS] to your project: + +```bash +npm install grunt-postcss --save-dev +``` + +Use [PostCSS image-set() Function] in your Gruntfile: + +```js +const postcssImageSetFunction = require('postcss-image-set-function'); + +grunt.loadNpmTasks('grunt-postcss'); + +grunt.initConfig({ + postcss: { + options: { + use: [ + postcssImageSetFunction(/* pluginOptions */) + ] + }, + dist: { + src: '*.css' + } + } +}); +``` + +[Gulp PostCSS]: https://github.com/postcss/gulp-postcss +[Grunt PostCSS]: https://github.com/nDmitry/grunt-postcss +[PostCSS]: https://github.com/postcss/postcss +[PostCSS CLI]: https://github.com/postcss/postcss-cli +[PostCSS Loader]: https://github.com/postcss/postcss-loader +[PostCSS image-set() Function]: https://github.com/jonathantneal/postcss-image-set-function +[React App Rewire PostCSS]: https://github.com/csstools/react-app-rewire-postcss +[React App Rewired]: https://github.com/timarney/react-app-rewired diff --git a/README.md b/README.md index 8aced93cbe..92a495e0c6 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,6 @@ [![NPM Version][npm-img]][npm-url] [![CSS Standard Status][css-img]][css-url] [![Build Status][cli-img]][cli-url] -[![Windows Build Status][win-img]][win-url] [![Support Chat][git-img]][git-url] [PostCSS image-set() Function] lets you display resolution-dependent images @@ -49,126 +48,36 @@ specification. ## Usage -Add [PostCSS image-set() Function] to your build tool: +Add [PostCSS image-set() Function] to your project: ```bash npm install postcss-image-set-function --save-dev ``` -#### Node - Use [PostCSS image-set() Function] to process your CSS: ```js -import postcssImageSetFunction from 'postcss-image-set-function'; +const postcssImageSetFunction = require('postcss-image-set-function'); -postcssImageSetFunction.process(YOUR_CSS, /* processOptions */, /* pluginOptions */); +postcssImageSetFunction.process(YOUR_CSS /*, processOptions, pluginOptions */); ``` -#### PostCSS - -Add [PostCSS] to your build tool: - -```bash -npm install postcss --save-dev -``` - -Use [PostCSS image-set() Function] as a plugin: +Or use it as a [PostCSS] plugin: ```js -import postcss from 'gulp-postcss'; -import postcssImageSetFunction from 'postcss-image-set-function'; +const postcss = require('postcss'); +const postcssImageSetFunction = require('postcss-image-set-function'); postcss([ postcssImageSetFunction(/* pluginOptions */) -]).process(YOUR_CSS); -``` - -#### Webpack - -Add [PostCSS Loader] to your build tool: - -```bash -npm install postcss-loader --save-dev -``` - -Use [PostCSS image-set() Function] in your Webpack configuration: - -```js -import postcssImageSetFunction from 'postcss-image-set-function'; - -module.exports = { - module: { - rules: [ - { - test: /\.css$/, - use: [ - 'style-loader', - { loader: 'css-loader', options: { importLoaders: 1 } }, - { loader: 'postcss-loader', options: { - ident: 'postcss', - plugins: () => [ - postcssImageSetFunction(/* pluginOptions */) - ] - } } - ] - } - ] - } -} +]).process(YOUR_CSS /*, processOptions */); ``` -#### Gulp +[PostCSS image-set() Function] runs in all Node environments, with special +instructions for: -Add [Gulp PostCSS] to your build tool: - -```bash -npm install gulp-postcss --save-dev -``` - -Use [PostCSS image-set() Function] in your Gulpfile: - -```js -import postcss from 'gulp-postcss'; -import postcssImageSetFunction from 'postcss-image-set-function'; - -gulp.task('css', () => gulp.src('./src/*.css').pipe( - postcss([ - postcssImageSetFunction(/* pluginOptions */) - ]) -).pipe( - gulp.dest('.') -)); -``` - -#### Grunt - -Add [Grunt PostCSS] to your build tool: - -```bash -npm install grunt-postcss --save-dev -``` - -Use [PostCSS image-set() Function] in your Gruntfile: - -```js -import postcssImageSetFunction from 'postcss-image-set-function'; - -grunt.loadNpmTasks('grunt-postcss'); - -grunt.initConfig({ - postcss: { - options: { - use: [ - postcssImageSetFunction(/* pluginOptions */) - ] - }, - dist: { - src: '*.css' - } - } -}); -``` +| [Node](INSTALL.md#node) | [PostCSS CLI](INSTALL.md#postcss-cli) | [Webpack](INSTALL.md#webpack) | [Create React App](INSTALL.md#create-react-app) | [Gulp](INSTALL.md#gulp) | [Grunt](INSTALL.md#grunt) | +| --- | --- | --- | --- | --- | --- | ## Options @@ -249,8 +158,6 @@ rather than wait for a larger, resolution-matching image to load. [git-url]: https://gitter.im/postcss/postcss [npm-img]: https://img.shields.io/npm/v/postcss-image-set-function.svg [npm-url]: https://www.npmjs.com/package/postcss-image-set-function -[win-img]: https://img.shields.io/appveyor/ci/jonathantneal/postcss-image-set-function.svg -[win-url]: https://ci.appveyor.com/project/jonathantneal/postcss-image-set-function [CSS Images]: https://drafts.csswg.org/css-images-4/#image-set-notation [Gulp PostCSS]: https://github.com/postcss/gulp-postcss diff --git a/index.js b/index.js index 002d2ed68b..3775a02532 100644 --- a/index.js +++ b/index.js @@ -1,5 +1,5 @@ import postcss from 'postcss'; -import parser from 'postcss-values-parser'; +import valueParser from 'postcss-values-parser'; import processImageSet from './lib/process-image-set'; const imageSetValueMatchRegExp = /(^|[^\w-])(-webkit-)?image-set\(/ @@ -17,10 +17,10 @@ export default postcss.plugin('postcss-image-set-function', opts => { // if a declaration likely uses an image-set() function if (imageSetValueMatchRegExp.test(value)) { - const ast = parser(value).parse(); + const valueAST = valueParser(value).parse(); // process every image-set() function - ast.walkType('func', node => { + valueAST.walkType('func', node => { if (imageSetFunctionMatchRegExp.test(node.value)) { processImageSet( node.nodes.slice(1, -1), diff --git a/package.json b/package.json index 1902c6a4aa..3c65e0bf99 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "postcss-image-set-function", - "version": "2.0.0", + "version": "3.0.0", "description": "Display resolution-dependent images using the image-set() function in CSS", "author": "Jonathan Neal ", "license": "CC0-1.0", @@ -8,10 +8,12 @@ "homepage": "https://github.com/jonathantneal/postcss-image-set-function#readme", "bugs": "https://github.com/jonathantneal/postcss-image-set-function/issues", "main": "index.cjs.js", - "module": "index.es.js", + "module": "index.es.mjs", "files": [ "index.cjs.js", - "index.es.js" + "index.cjs.js.map", + "index.es.mjs", + "index.es.mjs.map" ], "scripts": { "prepublishOnly": "npm test", @@ -22,22 +24,22 @@ "test:tape": "postcss-tape" }, "engines": { - "node": ">=4.0.0" + "node": ">=6.0.0" }, "dependencies": { "postcss": "^7.0.2", "postcss-values-parser": "^1.5.0" }, "devDependencies": { - "babel-core": "^6.26.3", - "babel-eslint": "^8.2.3", - "babel-preset-env": "^1.6.1", - "eslint": "^4.19.1", + "@babel/core": "^7.1.0", + "@babel/preset-env": "^7.1.0", + "babel-eslint": "^9.0.0", + "eslint": "^5.6.0", "eslint-config-dev": "^2.0.0", "postcss-tape": "^2.2.0", "pre-commit": "^1.2.2", - "rollup": "^0.58.2", - "rollup-plugin-babel": "^3.0.4" + "rollup": "^0.66.0", + "rollup-plugin-babel": "^4.0.3" }, "eslintConfig": { "extends": "dev", From 2bdb8c42d011a4fe0becd4fc060a25ae4a1195fb Mon Sep 17 00:00:00 2001 From: Jonathan Neal Date: Tue, 18 Sep 2018 11:58:20 -0400 Subject: [PATCH 713/795] 3.0.1 --- CHANGELOG.md | 4 ++++ INSTALL.md | 2 +- package.json | 4 ++-- 3 files changed, 7 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 75ef4709dd..8f662f7d97 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # Changes to PostCSS image-set() Function +### 3.0.1 (September 18, 2018) + +- Updated: PostCSS Values Parser 2 + ### 3.0.0 (September 17, 2018) - Updated: Support for PostCSS 7+ diff --git a/INSTALL.md b/INSTALL.md index 0f66ae653f..5de51e4a02 100644 --- a/INSTALL.md +++ b/INSTALL.md @@ -1,4 +1,4 @@ -# Installing PostCSS +# Installing PostCSS image-set() Function [PostCSS image-set() Function] runs in all Node environments, with special instructions for: diff --git a/package.json b/package.json index 3c65e0bf99..b79b6b31c7 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "postcss-image-set-function", - "version": "3.0.0", + "version": "3.0.1", "description": "Display resolution-dependent images using the image-set() function in CSS", "author": "Jonathan Neal ", "license": "CC0-1.0", @@ -28,7 +28,7 @@ }, "dependencies": { "postcss": "^7.0.2", - "postcss-values-parser": "^1.5.0" + "postcss-values-parser": "^2.0.0" }, "devDependencies": { "@babel/core": "^7.1.0", From 00063ded17b1ccd4c68c676f5fb7a049f69a0aa3 Mon Sep 17 00:00:00 2001 From: Jonathan Neal Date: Tue, 18 Sep 2018 12:02:30 -0400 Subject: [PATCH 714/795] 2.0.1 --- CHANGELOG.md | 8 ++++++-- package.json | 12 ++++++------ 2 files changed, 12 insertions(+), 8 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 633b2ad3ff..007135f27e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,9 +1,13 @@ # Changes to PostCSS Environment Variables +### 2.0.1 (September 18, 2018) + +- Updated: Support for PostCSS Values Parser 2 + ### 2.0.0 (September 17, 2018) -- Updated: Support for PostCSS v7+ -- Updated: Support for Node v6+ +- Updated: Support for PostCSS 7+ +- Updated: Support for Node 6+ - Updated: Changed `variables` option to `importFrom` option ### 1.0.0 (April 28, 2018) diff --git a/package.json b/package.json index 41cccee926..b1e69041ff 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "postcss-env-function", - "version": "2.0.0", + "version": "2.0.1", "description": "Use env() variables in CSS", "author": "Jonathan Neal ", "license": "CC0-1.0", @@ -24,23 +24,23 @@ "test:tape": "postcss-tape" }, "engines": { - "node": ">=4.0.0" + "node": ">=6.0.0" }, "dependencies": { "postcss": "^7.0.2", - "postcss-values-parser": "^1.5.0" + "postcss-values-parser": "^2.0.0" }, "devDependencies": { - "@babel/core": "^7.0.0", + "@babel/core": "^7.1.0", "@babel/plugin-syntax-dynamic-import": "^7.0.0", - "@babel/preset-env": "^7.0.0", + "@babel/preset-env": "^7.1.0", "babel-eslint": "^9.0.0", "eslint": "^5.6.0", "eslint-config-dev": "^2.0.0", "postcss-tape": "^2.2.0", "pre-commit": "^1.2.2", "rollup": "^0.66.0", - "rollup-plugin-babel": "^4.0.1" + "rollup-plugin-babel": "^4.0.3" }, "eslintConfig": { "extends": "dev", From 9eaf9b2fefaae91357c38d225973ee280a429c9c Mon Sep 17 00:00:00 2001 From: Jonathan Neal Date: Tue, 18 Sep 2018 12:12:32 -0400 Subject: [PATCH 715/795] 4.0.1 --- CHANGELOG.md | 4 ++++ index.js | 6 +++--- package-lock.json | 10 +++++----- package.json | 4 ++-- 4 files changed, 14 insertions(+), 10 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4b020de67e..63c2773e81 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,7 @@ +# 4.0.1 - 2018-09-18 + +- Updated: PostCSS Values Parser v2+ + # 4.0.0 - 2018-09-17 - Updated: Support for PostCSS v7+ diff --git a/index.js b/index.js index 18ffab7962..7ba4ceb72d 100755 --- a/index.js +++ b/index.js @@ -14,15 +14,15 @@ module.exports = postcss.plugin("postcss-color-rebeccapurple", () => (style) => const value = decl.value; if (value && regexp.test(value)) { - const ast = valueParser(value).parse() + const valueAST = valueParser(value).parse() - ast.walk(node => { + valueAST.walk(node => { if (node.type === "word" && node.value === "rebeccapurple") { node.value = color } }) - decl.value = ast.toString() + decl.value = valueAST.toString() } }) }) diff --git a/package-lock.json b/package-lock.json index eebe1b2d76..3eab13a842 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "postcss-color-rebeccapurple", - "version": "4.0.0", + "version": "4.0.1", "lockfileVersion": 1, "requires": true, "dependencies": { "@octokit/rest": { "version": "14.0.9", - "resolved": "http://registry.npmjs.org/@octokit/rest/-/rest-14.0.9.tgz", + "resolved": "https://registry.npmjs.org/@octokit/rest/-/rest-14.0.9.tgz", "integrity": "sha512-irP9phKfTXEZIcW2R+VNCtGHZJrXMWmSYp6RRfFn4BtAqtDRXF5z9JxCEQlAhNBf6X1koNi5k49tIAAAEJNlVQ==", "dev": true, "requires": { @@ -1653,9 +1653,9 @@ } }, "postcss-values-parser": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/postcss-values-parser/-/postcss-values-parser-1.5.0.tgz", - "integrity": "sha512-3M3p+2gMp0AH3da530TlX8kiO1nxdTnc3C6vr8dMxRLIlh8UYkz0/wcwptSXjhtx2Fr0TySI7a+BHDQ8NL7LaQ==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/postcss-values-parser/-/postcss-values-parser-2.0.0.tgz", + "integrity": "sha512-cyRdkgbRRefu91ByAlJow4y9w/hnBmmWgLpWmlFQ2bpIy2eKrqowt3VeYcaHQ08otVXmC9V2JtYW1Z/RpvYR8A==", "requires": { "flatten": "^1.0.2", "indexes-of": "^1.0.1", diff --git a/package.json b/package.json index e846116f7f..2af26f3a35 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "postcss-color-rebeccapurple", - "version": "4.0.0", + "version": "4.0.1", "description": "PostCSS plugin to transform W3C CSS rebeccapurple color to more compatible CSS (rgb())", "keywords": [ "css", @@ -25,7 +25,7 @@ }, "dependencies": { "postcss": "^7.0.2", - "postcss-values-parser": "^1.5.0" + "postcss-values-parser": "^2.0.0" }, "devDependencies": { "jscs": "^3.0.7", From ef00b00d4b7a453ce73a0320d52320638878a6bc Mon Sep 17 00:00:00 2001 From: Jonathan Neal Date: Tue, 18 Sep 2018 12:22:02 -0400 Subject: [PATCH 716/795] 3.0.1 --- CHANGELOG.md | 5 +++++ README.md | 3 --- lib/conversions.js | 1 + package.json | 10 +++++----- test/basic.colors.expect.css | 4 ++++ test/basic.css | 4 ++++ test/basic.expect.css | 4 ++++ 7 files changed, 23 insertions(+), 8 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d41564501b..f03bb5e66d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,10 @@ # Changes to PostCSS color-mod() Function +### 3.0.1 (September 18, 2018) + +- Fixed an issue with using the `transparent` color keyword +- Updated to PostCSS Values Parser 2 + ### 3.0.0 (August 30, 2018) - Added `importFrom` option which allows you to import Custom Properties from diff --git a/README.md b/README.md index 7670583920..997b498001 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,6 @@ [![NPM Version][npm-img]][npm-url] [![CSS Standard Status][css-img]][css-url] [![Build Status][cli-img]][cli-url] -[![Windows Build Status][win-img]][win-url] [![Support Chat][git-img]][git-url] [PostCSS color-mod() Function] lets you modify colors using the `color-mod()` @@ -199,8 +198,6 @@ be used. [git-url]: https://gitter.im/postcss/postcss [npm-img]: https://img.shields.io/npm/v/postcss-color-mod-function.svg [npm-url]: https://www.npmjs.com/package/postcss-color-mod-function -[win-img]: https://img.shields.io/appveyor/ci/jonathantneal/postcss-color-mod-function.svg -[win-url]: https://ci.appveyor.com/project/jonathantneal/postcss-color-mod-function [CSS Color Module Level 4]: https://www.w3.org/TR/css-color-4/#funcdef-color-mod [Gulp PostCSS]: https://github.com/postcss/gulp-postcss diff --git a/lib/conversions.js b/lib/conversions.js index 416cf44500..401e150169 100644 --- a/lib/conversions.js +++ b/lib/conversions.js @@ -172,6 +172,7 @@ export function convertNtoRGB(name) { teal: [0, 128, 128], thistle: [216, 191, 216], tomato: [255, 99, 71], + transparent: [0, 0, 0], turquoise: [64, 224, 208], violet: [238, 130, 238], wheat: [245, 222, 179], diff --git a/package.json b/package.json index d056ed1ab0..f63e25ba75 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "postcss-color-mod-function", - "version": "3.0.0", + "version": "3.0.1", "description": "Modify colors using the color-mod() function in CSS", "author": "Jonathan Neal ", "license": "CC0-1.0", @@ -8,7 +8,7 @@ "homepage": "https://github.com/jonathantneal/postcss-color-mod-function#readme", "bugs": "https://github.com/jonathantneal/postcss-color-mod-function/issues", "main": "index.cjs.js", - "module": "index.es.js", + "module": "index.es.mjs", "files": [ "index.cjs.js", "index.cjs.js.map", @@ -29,12 +29,12 @@ "dependencies": { "@csstools/convert-colors": "^1.4.0", "postcss": "^7.0.2", - "postcss-values-parser": "^1.5.0" + "postcss-values-parser": "^2.0.0" }, "devDependencies": { - "@babel/core": "^7.0.1", + "@babel/core": "^7.1.0", "@babel/plugin-syntax-dynamic-import": "^7.0.0", - "@babel/preset-env": "^7.0.0", + "@babel/preset-env": "^7.1.0", "babel-eslint": "^9.0.0", "echint": "^4.0.1", "eslint": "^5.6.0", diff --git a/test/basic.colors.expect.css b/test/basic.colors.expect.css index 206e68077f..bf9b9b5f7b 100644 --- a/test/basic.colors.expect.css +++ b/test/basic.colors.expect.css @@ -141,3 +141,7 @@ test-linear-gradient { test-var-blend { color: rgb(90% 0% 10%); } + +test-transparent { + color: rgb(0% 0% 0%); +} diff --git a/test/basic.css b/test/basic.css index 1d047a3794..d97206386c 100644 --- a/test/basic.css +++ b/test/basic.css @@ -141,3 +141,7 @@ test-linear-gradient { test-var-blend { color: color-mod(var(--color-red) blend(var(--color) 10%)); } + +test-transparent { + color: color-mod(transparent shade(10%)); +} diff --git a/test/basic.expect.css b/test/basic.expect.css index 6f0e072afc..1c029785f5 100644 --- a/test/basic.expect.css +++ b/test/basic.expect.css @@ -141,3 +141,7 @@ test-linear-gradient { test-var-blend { color: rgb(230, 0, 26); } + +test-transparent { + color: rgb(0, 0, 0); +} From 74d738cf300ffb120e4e8df9d267617aae150212 Mon Sep 17 00:00:00 2001 From: Jonathan Neal Date: Tue, 18 Sep 2018 12:30:18 -0400 Subject: [PATCH 717/795] 8.0.3 --- CHANGELOG.md | 4 ++++ package.json | 8 ++++---- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4106ce5234..8c26088365 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # Changes to PostCSS Custom Properties +### 8.0.3 (September 18, 2018) + +- Updated: PostCSS Values Parser 2 + ### 8.0.2 (September 17, 2018) - Fixed: Spacing is preserved before replaced variables. diff --git a/package.json b/package.json index ff831f5b27..7a4720b9b2 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "postcss-custom-properties", - "version": "8.0.2", + "version": "8.0.3", "description": "Use Custom Properties Queries in CSS", "author": "Jonathan Neal ", "contributors": [ @@ -30,12 +30,12 @@ }, "dependencies": { "postcss": "^7.0.2", - "postcss-values-parser": "^1.5.0" + "postcss-values-parser": "^2.0.0" }, "devDependencies": { - "@babel/core": "^7.0.1", + "@babel/core": "^7.1.0", "@babel/plugin-syntax-dynamic-import": "^7.0.0", - "@babel/preset-env": "^7.0.0", + "@babel/preset-env": "^7.1.0", "babel-eslint": "^9.0.0", "eslint": "^5.6.0", "eslint-config-dev": "^2.0.0", From 83292da01b5dab20a7fd5ebd3ab8f18735bfca71 Mon Sep 17 00:00:00 2001 From: Jonathan Neal Date: Tue, 18 Sep 2018 23:36:13 -0400 Subject: [PATCH 718/795] 5.1.1 --- .rollup.js | 4 +- .tape.js | 3 + CHANGELOG.md | 4 + ...transform-selectors-by-custom-selectors.js | 35 ++ package.json | 14 +- test/index.js | 299 ------------------ test/safety.css | 13 + test/safety.expect.css | 11 + 8 files changed, 76 insertions(+), 307 deletions(-) delete mode 100644 test/index.js create mode 100644 test/safety.css create mode 100644 test/safety.expect.css diff --git a/.rollup.js b/.rollup.js index eab5c0d513..3f28a5511b 100644 --- a/.rollup.js +++ b/.rollup.js @@ -3,8 +3,8 @@ import babel from 'rollup-plugin-babel'; export default { input: 'index.js', output: [ - { file: 'index.cjs.js', format: 'cjs' }, - { file: 'index.es.mjs', format: 'es' } + { file: 'index.cjs.js', format: 'cjs', sourcemap: true }, + { file: 'index.es.mjs', format: 'es', sourcemap: true } ], plugins: [ babel({ diff --git a/.tape.js b/.tape.js index 846b95efcc..366f841718 100644 --- a/.tape.js +++ b/.tape.js @@ -9,6 +9,9 @@ module.exports = { preserve: true } }, + 'safety': { + message: 'supports safe tag ordering (.foo:--h1 becomes h1.foo instead of .fooh1)' + }, 'basic:import': { message: 'supports { importFrom: { customSelectors: { ... } } } usage', options: { diff --git a/CHANGELOG.md b/CHANGELOG.md index 7d2a8849ee..3f23dbe3ee 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # Changes to PostCSS Custom Selectors +### 5.1.1 (September 18, 2018) + +- Fixed: Selectors like `.foo:--h1` become `h1.foo` instead of `.fooh1` + ### 5.1.0 (September 12, 2018) - Added: New `exportTo` function to specify where to export custom selectors diff --git a/lib/transform-selectors-by-custom-selectors.js b/lib/transform-selectors-by-custom-selectors.js index 8ca113804c..2a3daf2dae 100644 --- a/lib/transform-selectors-by-custom-selectors.js +++ b/lib/transform-selectors-by-custom-selectors.js @@ -35,6 +35,8 @@ function transformSelector(selector, customSelectors) { const retranspiledSelectors = transformSelector(selectorClone, customSelectors); + adjustNodesBySelectorEnds(selectorClone.nodes, Number(index)); + if (retranspiledSelectors.length) { transpiledSelectors.push(...retranspiledSelectors); } else { @@ -50,3 +52,36 @@ function transformSelector(selector, customSelectors) { return transpiledSelectors; } + +// match selectors by difficult-to-separate ends +const withoutSelectorStartMatch = /^(tag|universal)$/; +const withoutSelectorEndMatch = /^(class|id|pseudo|tag|universal)$/; + +const isWithoutSelectorStart = node => withoutSelectorStartMatch.test(Object(node).type); +const isWithoutSelectorEnd = node => withoutSelectorEndMatch.test(Object(node).type); + +// adjust nodes by selector ends (so that .class:--h1 becomes h1.class rather than .classh1) +const adjustNodesBySelectorEnds = (nodes, index) => { + if (index && isWithoutSelectorStart(nodes[index]) && isWithoutSelectorEnd(nodes[index - 1])) { + let safeIndex = index - 1; + + while (safeIndex && isWithoutSelectorEnd(nodes[safeIndex])) { + --safeIndex; + } + + if (safeIndex < index) { + const node = nodes.splice(index, 1)[0]; + + nodes.splice(safeIndex, 0, node); + + nodes[safeIndex].spaces.before = nodes[safeIndex + 1].spaces.before; + nodes[safeIndex + 1].spaces.before = ''; + + if (nodes[index]) { + nodes[index].spaces.after = nodes[safeIndex].spaces.after; + nodes[safeIndex].spaces.after = ''; + } + } + } +}; + diff --git a/package.json b/package.json index 5314c276d2..58453b369e 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "postcss-custom-selectors", - "version": "5.1.0", + "version": "5.1.1", "description": "Use Custom Selectors in CSS", "author": "Jonathan Neal ", "contributors": [ @@ -15,7 +15,9 @@ "module": "index.es.mjs", "files": [ "index.cjs.js", - "index.es.mjs" + "index.cjs.js.map", + "index.es.mjs", + "index.es.mjs.map" ], "scripts": { "prepublishOnly": "npm test", @@ -32,15 +34,15 @@ "postcss-selector-parser": "^5.0.0-rc.3" }, "devDependencies": { - "@babel/core": "^7.0.1", + "@babel/core": "^7.1.0", "@babel/plugin-syntax-dynamic-import": "^7.0.0", - "@babel/preset-env": "^7.0.0", + "@babel/preset-env": "^7.1.0", "babel-eslint": "^9.0.0", - "eslint": "^5.5.0", + "eslint": "^5.6.0", "eslint-config-dev": "^2.0.0", "postcss-tape": "^2.2.0", "pre-commit": "^1.2.2", - "rollup": "^0.65.2", + "rollup": "^0.66.0", "rollup-plugin-babel": "^4.0.3" }, "eslintConfig": { diff --git a/test/index.js b/test/index.js deleted file mode 100644 index 5fadaec395..0000000000 --- a/test/index.js +++ /dev/null @@ -1,299 +0,0 @@ -import test from "tape" -import postcss from "postcss" -import plugin from "../src" - -function transform(input, opts = {}, postcssOpts = {}) { - return postcss() - .use(plugin(opts)) - .process(input, postcssOpts) -} - -test("@custom-selector", function(t) { - t.equal( - transform( - "" - ).css, - "", - "should works with nothing" - ) - - const undefinedResult = transform(":--undef {}") - t.ok( - undefinedResult.messages && undefinedResult.messages.length === 1, - "should add a message when a custom selectors is undefined" - ) - - t.equal( - transform( - `@custom-selector :--foo .bar, .baz; -.foo:--foo { - margin-top: 16px; -}`, - {transformMatches: false} - ).css, - `.foo:matches(.bar, .baz) { - margin-top: 16px; -}`, - "should works be able to limit transformation to :matches()" - ) - - t.equal( - transform( - `@custom-selector :--heading h1, h2, h3, h4, h5, h6; - -article :--heading + p {}` - ).css, - `article h1 + p, -article h2 + p, -article h3 + p, -article h4 + p, -article h5 + p, -article h6 + p {}`, - "should transform heading" - ) - - t.equal( - transform( - `@custom-selector :--foobar .foo, .bar; -@custom-selector :--baz .baz; -@custom-selector :--fizzbuzz .fizz, .buzz; -@custom-selector :--button-types - .btn-primary, - .btn-success, - .btn-info, - .btn-warning, - .btn-danger; - -:--foobar > :--baz {} - -:--fizzbuzz > :--foobar {} - -:--button-types, :--button-types:active {}` - ).css, - `.foo > .baz, -.bar > .baz {} - -.fizz > .foo, -.buzz > .foo, -.fizz > .bar, -.buzz > .bar {} - -.btn-primary, -.btn-success, -.btn-info, -.btn-warning, -.btn-danger, -.btn-primary:active, -.btn-success:active, -.btn-info:active, -.btn-warning:active, -.btn-danger:active {}`, - "should work with a complicated example" - ) - - t.equal( - transform( - `/* comment */ -@custom-selector :--foo - /* comment */ - .foo, - .bar > .baz; - - -/* comment */ - :--foo + p { - display: block; - }` - ).css, - `/* comment */ - - -/* comment */ - .foo + p, - .bar > .baz + p { - display: block; - }`, - "should works with comments" - ) - - t.equal( - transform( - `@custom-selector :--pseudo ::before, ::after; - -.foo > a:--pseudo img { - display: block; -} -` - ).css, - `.foo > a::before img, -.foo > a::after img { - display: block; -} -`, - "should works with pseudo elements" - ) - - t.equal( - transform( - `@custom-selector :--foo .foo; - -:--foo, :--foo.bar { - color: white; -} -` - ).css, - `.foo, -.foo.bar { - color: white; -} -`, - "should works handle multiples combined selectors" - ) - - t.equal( - transform( - `@custom-selector :--foo .foo; - -:--foo :--foo:hover { - color: white; -} -` - ).css, - `.foo .foo:hover { - color: white; -} -`, - "should works handle multiples combined selectors with pseudo classes" - ) - - t.equal( - transform( - `@custom-selector :--foo h1, h2, h3; -@custom-selector :--ba-----r h4, h5, h6; - -.fo--oo > :--foo { - margin: auto; -} - -:--ba-----r:hover .ba--z { - display: block; -} -` - ).css, - `.fo--oo > h1, -.fo--oo > h2, -.fo--oo > h3 { - margin: auto; -} - -h4:hover .ba--z, -h5:hover .ba--z, -h6:hover .ba--z { - display: block; -} -`, - "should works with weird identifiers" - ) - - t.equal( - transform( - `@custom-selector :--heading h1, h2, h3, h4, h5, h6; -/* comment */ - - article :--heading + p { - margin-top: 0; - } -`, - {lineBreak: false} - ).css, - `/* comment */ - - article h1 + p, article h2 + p, article h3 + p, article h4 + p, ` + - `article h5 + p, article h6 + p { - margin-top: 0; - } -`, - "should works works with no line breaks" - ) - - t.equal( - transform( - `@custom-selector :--multiline - .foo, - .bar > .baz; - -:--multiline { - display: block; -} -` - ).css, - `.foo, -.bar > .baz { - display: block; -} -`, - "should works with multilines definition" - ) - - t.equal( - transform( - `@custom-selector :--button button, .button; -@custom-selector :--enter :hover, :focus; - -:--button:--enter {}` - ).css, - `button:hover, -.button:hover, -button:focus, -.button:focus {}`, - "should works with collapsed custom selectors" - ) - - t.equal( - transform( - `@custom-selector :--any .foo, .bar; -@custom-selector :--foo .baz; - -:--any h1 { - margin-top: 16px; -} - -main :--foo + p { - margin-top: 16px; -} -`, - { - extensions: { - ":--any": "section, article, aside, nav", - ":--foo": "input[type=\"text\"] > section, #nav .bar", - }, - } - ).css, - `section h1, -article h1, -aside h1, -nav h1 { - margin-top: 16px; -} - -main input[type="text"] > section + p, -main #nav .bar + p { - margin-top: 16px; -} -`, - "should transform local extensions" - ) - - const postcssPlugin = postcss().use(plugin()) - t.ok( - postcssPlugin.process("@custom-selector :--foobar .foo;:--foobar{}").css, - "should not create a memory" - ) - t.equal( - postcssPlugin.process(":--foobar{}").css, - ":--foobar{}", - "should have no memory about previous processing" - ) - - t.end() -}) diff --git a/test/safety.css b/test/safety.css new file mode 100644 index 0000000000..7dc80f7e70 --- /dev/null +++ b/test/safety.css @@ -0,0 +1,13 @@ +@custom-selector :--h1 h1; + +.class:--h1, #id:--h1, ::before:--h1, *:--h1 { + order: 1; +} + +.foo.class:--h1 , .foo#id:--h1 , .foo::before:--h1 { + order: 2; +} + +.foo.class:--h1 , .foo#id:--h1 , .foo::before:--h1 { + order: 3; +} diff --git a/test/safety.expect.css b/test/safety.expect.css new file mode 100644 index 0000000000..2184ce4620 --- /dev/null +++ b/test/safety.expect.css @@ -0,0 +1,11 @@ +h1.class, h1#id, h1::before, h1* { + order: 1; +} + +h1.foo.class , h1.foo#id , h1.foo::before { + order: 2; +} + +h1.foo.class , h1.foo#id , h1.foo::before { + order: 3; +} From 606e09248830f49534d61b2c36ed2add09ee52a5 Mon Sep 17 00:00:00 2001 From: Jonathan Neal Date: Thu, 20 Sep 2018 07:12:19 -0400 Subject: [PATCH 719/795] 3.0.0 --- .tape.js | 9 ++ CHANGELOG.md | 7 + README.md | 34 +++-- index.js | 30 ++++- lib/clone-rule.js | 22 +--- lib/split.js | 56 ++++++++ lib/transform-transition.js | 122 +++++++++++++++++ package.json | 10 +- test/border.expect.css | 196 ++++++++++++++++------------ test/border.preserve.expect.css | 224 ++++++++++++++++++-------------- test/clear.expect.css | 22 ++-- test/float.expect.css | 20 +-- test/inset.expect.css | 138 +++++++++++--------- test/margin.expect.css | 98 ++++++++------ test/padding.expect.css | 98 ++++++++------ test/text-align.expect.css | 20 +-- test/transition.css | 45 +++++++ test/transition.expect.css | 103 +++++++++++++++ test/transition.ltr.expect.css | 45 +++++++ 19 files changed, 900 insertions(+), 399 deletions(-) create mode 100644 lib/split.js create mode 100644 lib/transform-transition.js create mode 100644 test/transition.css create mode 100644 test/transition.expect.css create mode 100644 test/transition.ltr.expect.css diff --git a/.tape.js b/.tape.js index 05757bcb53..6823527faf 100644 --- a/.tape.js +++ b/.tape.js @@ -74,6 +74,15 @@ module.exports = { options: { dir: 'ltr' } + }, + 'transition': { + message: 'supports logical "transition" properties' + }, + 'transition:ltr': { + message: 'supports logical "transition" properties with { dir: "ltr" }', + options: { + dir: 'ltr' + } } } }; diff --git a/CHANGELOG.md b/CHANGELOG.md index 85be9dc803..4281a32a1f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,12 @@ # Changes to PostCSS Logical Properties +### 3.0.0 (September 20, 2018) + +- Added: Support for logical properties within `transition` and + `transition-property`. +- Changed: Physical rule fallbacks are written as full selectors rather than + as nesting selectors. + ### 2.0.0 (September 17, 2018) - Updated: Support for PostCSS v7+ diff --git a/README.md b/README.md index 4de166aa65..012b285d0e 100644 --- a/README.md +++ b/README.md @@ -20,18 +20,15 @@ physical, direction and dimension mappings in CSS, following the /* becomes */ -.banner { - color: #222222; - top: 0; left: 5px; bottom: 10px; right: 5px; +.banner:dir(ltr) { + padding-left: 20px; padding-right: 40px; +} - &:dir(ltr) { - padding-left: 20px; padding-right: 40px; - } - - &:dir(rtl) { - padding-right: 20px; padding-left: 40px; - } +.banner:dir(rtl) { + padding-right: 20px; padding-left: 40px; +} +.banner { resize: vertical; transition: color 200ms; } @@ -48,18 +45,17 @@ physical, direction and dimension mappings in CSS, following the /* or, when used with { preserve: true } */ +.banner:dir(ltr) { + padding-left: 20px; padding-right: 40px; +} + +.banner:dir(rtl) { + padding-right: 20px; padding-left: 40px; +} + .banner { color: #222222; top: 0; left: 5px; bottom: 10px; right: 5px; - - &:dir(ltr) { - padding-left: 20px; padding-right: 40px; - } - - &:dir(rtl) { - padding-right: 20px; padding-left: 40px; - } - inset: logical 0 5px 10px; padding-inline: 20px 40px; resize: block; diff --git a/index.js b/index.js index 8362d3b61f..f8ac55805a 100644 --- a/index.js +++ b/index.js @@ -10,7 +10,9 @@ import transformSide from './lib/transform-side'; import transformSize from './lib/transform-size'; import transformSpacing from './lib/transform-spacing'; import transformTextAlign from './lib/transform-text-align'; +import transformTransition from './lib/transform-transition'; import matchSupportedProperties from './lib/match-supported-properties'; +import { splitBySlash, splitBySpace } from './lib/split'; // supported transforms const transforms = { @@ -38,9 +40,14 @@ const transforms = { 'float': transformFloat, 'resize': transformResize, 'size': transformSize, - 'text-align': transformTextAlign + 'text-align': transformTextAlign, + 'transition': transformTransition, + 'transition-property': transformTransition }; +// properties that will be split by slash +const splitBySlashPropRegExp = /^border(-block|-inline|-start|-end)?(-width|-style|-color)?$/i; + // plugin export default postcss.plugin('postcss-logical-properties', opts => { const preserve = Boolean(Object(opts).preserve); @@ -52,17 +59,28 @@ export default postcss.plugin('postcss-logical-properties', opts => { return root => { root.walkDecls(decl => { - const values = postcss.list.split(decl.value, /^border(-block|-inline|-start|-end)?(-width|-style|-color)?$/i.test(decl.prop) ? '/' : ' '); + const parent = decl.parent; + const values = splitBySlashPropRegExp.test(decl.prop) ? splitBySlash(decl.value, true) : splitBySpace(decl.value, true); const prop = decl.prop.replace(matchSupportedProperties, '$2$5').toLowerCase(); if (prop in transforms) { const replacer = transforms[prop](decl, values, dir); if (replacer) { - if (preserve) { - decl.before(replacer); - } else { - decl.replaceWith(replacer); + [].concat(replacer).forEach(replacement => { + if (replacement.type === 'rule') { + parent.before(replacement); + } else { + decl.before(replacement); + } + }); + + if (!preserve) { + decl.remove(); + + if (!parent.nodes.length) { + parent.remove(); + } } } } diff --git a/lib/clone-rule.js b/lib/clone-rule.js index 91039ef85c..cc347210c9 100644 --- a/lib/clone-rule.js +++ b/lib/clone-rule.js @@ -1,23 +1,11 @@ -'use strict'; - import postcss from 'postcss'; export default (decl, dir) => { - let node = decl.parent; - - while (node && 'rule' !== node.type) { - node = node.parent; - } - - if (node) { - node = node.clone({ - raws: {} - }).removeAll() - } else { - node = postcss.rule(); - } + const rule = Object(decl.parent).type === 'rule' ? decl.parent.clone({ + raws: {} + }).removeAll() : postcss.rule({ selector: '&' }); - node.selector = `&:dir(${dir})`; + rule.selectors = rule.selectors.map(selector => `${selector}:dir(${dir})`); - return node; + return rule; }; diff --git a/lib/split.js b/lib/split.js new file mode 100644 index 0000000000..5291f39b37 --- /dev/null +++ b/lib/split.js @@ -0,0 +1,56 @@ +export function splitByComma(string, isTrimmed) { + return splitByRegExp(string, /^,$/, isTrimmed); +} + +export function splitBySpace(string, isTrimmed) { + return splitByRegExp(string, /^\s$/, isTrimmed); +} + +export function splitBySlash(string, isTrimmed) { + return splitByRegExp(string, /^\/$/, isTrimmed); +} + +function splitByRegExp(string, re, isTrimmed) { + const array = []; + let buffer = ''; + let split = false; + let func = 0; + let i = -1; + + while (++i < string.length) { + const char = string[i]; + + if (char === '(') { + func += 1; + } else if (char === ')') { + if (func > 0) { + func -= 1; + } + } else if (func === 0) { + if (re.test(char)) { + split = true; + } + } + + if (split) { + if (!isTrimmed || buffer.trim()) { + array.push(isTrimmed ? buffer.trim() : buffer); + } + + if (!isTrimmed) { + array.push(char); + } + + buffer = ''; + split = false; + } else { + buffer += char + } + } + + if (buffer !== '') { + array.push(isTrimmed ? buffer.trim() : buffer); + } + + return array; +} diff --git a/lib/transform-transition.js b/lib/transform-transition.js new file mode 100644 index 0000000000..ef45d42ea4 --- /dev/null +++ b/lib/transform-transition.js @@ -0,0 +1,122 @@ +import cloneRule from './clone-rule'; +import { splitByComma, splitBySpace } from './split'; + +export default (decl, notValues, dir) => { + const ltrValues = []; + const rtlValues = []; + + splitByComma(decl.value).forEach(value => { + let hasBeenSplit = false; + + splitBySpace(value).forEach((word, index, words) => { + if (word in valueMap) { + hasBeenSplit = true; + + valueMap[word].ltr.forEach(replacement => { + const clone = words.slice(); + + clone.splice(index, 1, replacement); + + if (ltrValues.length && !/^,$/.test(ltrValues[ltrValues.length - 1])) { + ltrValues.push(','); + } + + ltrValues.push(clone.join('')); + }); + + valueMap[word].rtl.forEach(replacement => { + const clone = words.slice(); + + clone.splice(index, 1, replacement); + + if (rtlValues.length && !/^,$/.test(rtlValues[rtlValues.length - 1])) { + rtlValues.push(','); + } + + rtlValues.push(clone.join('')); + }); + } + }); + + if (!hasBeenSplit) { + ltrValues.push(value); + rtlValues.push(value); + } + }); + + const ltrDecl = decl.clone({ value: ltrValues.join('') }); + const rtlDecl = decl.clone({ value: rtlValues.join('') }); + + return ltrValues.length && 'ltr' === dir + ? ltrDecl + : rtlValues.length && 'rtl' === dir + ? rtlDecl + : ltrDecl.value !== rtlDecl.value + ? [ + cloneRule(decl, 'ltr').append(ltrDecl), + cloneRule(decl, 'rtl').append(rtlDecl) + ] + : null; +}; + +const valueMap = { + 'border-block': { ltr: ['border-top', 'border-bottom'], rtl: ['border-top', 'border-bottom'] }, + 'border-block-color': { ltr: ['border-top-color', 'border-bottom-color'], rtl: ['border-top-color', 'border-bottom-color'] }, + 'border-block-end': { ltr: ['border-bottom'], rtl: ['border-bottom'] }, + 'border-block-end-color': { ltr: ['border-bottom-color'], rtl: ['border-bottom-color'] }, + 'border-block-end-style': { ltr: ['border-bottom-style'], rtl: ['border-bottom-style'] }, + 'border-block-end-width': { ltr: ['border-bottom-width'], rtl: ['border-bottom-width'] }, + 'border-block-start': { ltr: ['border-top'], rtl: ['border-top'] }, + 'border-block-start-color': { ltr: ['border-top-color'], rtl: ['border-top-color'] }, + 'border-block-start-style': { ltr: ['border-top-style'], rtl: ['border-top-style'] }, + 'border-block-start-width': { ltr: ['border-top-width'], rtl: ['border-top-width'] }, + 'border-block-style': { ltr: ['border-top-style', 'border-bottom-style'], rtl: ['border-top-style', 'border-bottom-style'] }, + 'border-block-width': { ltr: ['border-top-width', 'border-bottom-width'], rtl: ['border-top-width', 'border-bottom-width'] }, + 'border-end': { ltr: ['border-bottom', 'border-right'], rtl: ['border-bottom', 'border-left'] }, + 'border-end-color': { ltr: ['border-bottom-color', 'border-right-color'], rtl: ['border-bottom-color', 'border-left-color'] }, + 'border-end-style': { ltr: ['border-bottom-style', 'border-right-style'], rtl: ['border-bottom-style', 'border-left-style'] }, + 'border-end-width': { ltr: ['border-bottom-width', 'border-right-width'], rtl: ['border-bottom-width', 'border-left-width'] }, + 'border-inline': { ltr: ['border-left', 'border-right'], rtl: ['border-left', 'border-right'] }, + 'border-inline-color': { ltr: ['border-left-color', 'border-right-color'], rtl: ['border-left-color', 'border-right-color'] }, + 'border-inline-end': { ltr: ['border-right'], rtl: ['border-left'] }, + 'border-inline-end-color': { ltr: ['border-right-color'], rtl: ['border-left-color'] }, + 'border-inline-end-style': { ltr: ['border-right-style'], rtl: ['border-left-style'] }, + 'border-inline-end-width': { ltr: ['border-right-width'], rtl: ['border-left-width'] }, + 'border-inline-start': { ltr: ['border-left'], rtl: ['border-right'] }, + 'border-inline-start-color': { ltr: ['border-left-color'], rtl: ['border-right-color'] }, + 'border-inline-start-style': { ltr: ['border-left-style'], rtl: ['border-right-style'] }, + 'border-inline-start-width': { ltr: ['border-left-width'], rtl: ['border-right-width'] }, + 'border-inline-style': { ltr: ['border-left-style', 'border-right-style'], rtl: ['border-left-style', 'border-right-style'] }, + 'border-inline-width': { ltr: ['border-left-width', 'border-right-width'], rtl: ['border-left-width', 'border-right-width'] }, + 'border-start': { ltr: ['border-top', 'border-left'], rtl: ['border-top', 'border-right'] }, + 'border-start-color': { ltr: ['border-top-color', 'border-left-color'], rtl: ['border-top-color', 'border-right-color'] }, + 'border-start-style': { ltr: ['border-top-style', 'border-left-style'], rtl: ['border-top-style', 'border-right-style'] }, + 'border-start-width': { ltr: ['border-top-width', 'border-left-width'], rtl: ['border-top-width', 'border-right-width'] }, + 'block-size': { ltr: ['height'], rtl: ['height'] }, + 'inline-size': { ltr: ['width'], rtl: ['width'] }, + 'inset': { ltr: ['top', 'right', 'bottom', 'left'], rtl: ['top', 'right', 'bottom', 'left'] }, + 'inset-block': { ltr: ['top', 'bottom'], rtl: ['top', 'bottom'] }, + 'inset-block-start': { ltr: ['top'], rtl: ['top'] }, + 'inset-block-end': { ltr: ['bottom'], rtl: ['bottom'] }, + 'inset-end': { ltr: ['bottom', 'right'], rtl: ['bottom', 'left'] }, + 'inset-inline': { ltr: ['left', 'right'], rtl: ['left', 'right'] }, + 'inset-inline-start': { ltr: ['left'], rtl: ['right'] }, + 'inset-inline-end': { ltr: ['right'], rtl: ['left'] }, + 'inset-start': { ltr: ['top', 'left'], rtl: ['top', 'right'] }, + 'margin-block': { ltr: ['margin-top', 'margin-bottom'], rtl: ['margin-top', 'margin-bottom'] }, + 'margin-block-start': { ltr: ['margin-top'], rtl: ['margin-top'] }, + 'margin-block-end': { ltr: ['margin-bottom'], rtl: ['margin-bottom'] }, + 'margin-end': { ltr: ['margin-bottom', 'margin-right'], rtl: ['margin-bottom', 'margin-left'] }, + 'margin-inline': { ltr: ['margin-left', 'margin-right'], rtl: ['margin-left', 'margin-right'] }, + 'margin-inline-start': { ltr: ['margin-left'], rtl: ['margin-right'] }, + 'margin-inline-end': { ltr: ['margin-right'], rtl: ['margin-left'] }, + 'margin-start': { ltr: ['margin-top', 'margin-left'], rtl: ['margin-top', 'margin-right'] }, + 'padding-block': { ltr: ['padding-top', 'padding-bottom'], rtl: ['padding-top', 'padding-bottom'] }, + 'padding-block-start': { ltr: ['padding-top'], rtl: ['padding-top'] }, + 'padding-block-end': { ltr: ['padding-bottom'], rtl: ['padding-bottom'] }, + 'padding-end': { ltr: ['padding-bottom', 'padding-right'], rtl: ['padding-bottom', 'padding-left'] }, + 'padding-inline': { ltr: ['padding-left', 'padding-right'], rtl: ['padding-left', 'padding-right'] }, + 'padding-inline-start': { ltr: ['padding-left'], rtl: ['padding-right'] }, + 'padding-inline-end': { ltr: ['padding-right'], rtl: ['padding-left'] }, + 'padding-start': { ltr: ['padding-top', 'padding-left'], rtl: ['padding-top', 'padding-right'] }, +}; diff --git a/package.json b/package.json index ca0aa17192..2a331a4741 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "postcss-logical", - "version": "2.0.0", + "version": "3.0.0", "description": "Use logical properties and values in CSS", "author": "Jonathan Neal ", "license": "CC0-1.0", @@ -30,16 +30,16 @@ "postcss": "^7.0.2" }, "devDependencies": { - "@babel/core": "^7.0.0", - "@babel/preset-env": "^7.0.0", + "@babel/core": "^7.1.0", + "@babel/preset-env": "^7.1.0", "babel-eslint": "^9.0.0", "echint": "^4.0.1", "eslint": "^5.6.0", "eslint-config-dev": "^2.0.0", "postcss-tape": "^2.2.0", "pre-commit": "^1.2.2", - "rollup": "^0.66.0", - "rollup-plugin-babel": "^4.0.1" + "rollup": "^0.66.1", + "rollup-plugin-babel": "^4.0.3" }, "eslintConfig": { "extends": "dev", diff --git a/test/border.expect.css b/test/border.expect.css index 6d670f7d55..c625c06879 100644 --- a/test/border.expect.css +++ b/test/border.expect.css @@ -24,154 +24,186 @@ test-border { border-bottom: 16px solid black; } -test-flowing-border { - border: inherit; - &:dir(ltr) { +test-flowing-border:dir(ltr) { border-top: 1px solid black; border-left: 2px solid black; border-bottom: 3px solid black; border-right: 4px solid black; - } - &:dir(rtl) { +} + +test-flowing-border:dir(rtl) { border-top: 1px solid black; border-right: 2px solid black; border-bottom: 3px solid black; border-left: 4px solid black; - } - border: inherit; - &:dir(ltr) { +} + +test-flowing-border:dir(ltr) { border-left: 5px solid black; border-right: 6px solid black; - } - &:dir(rtl) { +} + +test-flowing-border:dir(rtl) { border-right: 5px solid black; border-left: 6px solid black; - } - border: inherit; - &:dir(ltr) { +} + +test-flowing-border:dir(ltr) { border-left: 7px solid black; - } - &:dir(rtl) { +} + +test-flowing-border:dir(rtl) { border-right: 7px solid black; - } - border: inherit; - &:dir(ltr) { +} + +test-flowing-border:dir(ltr) { border-right: 8px solid black; - } - &:dir(rtl) { +} + +test-flowing-border:dir(rtl) { border-left: 8px solid black; - } - border: inherit; - &:dir(ltr) { +} + +test-flowing-border:dir(ltr) { border-top: 9px solid black; border-left: 9px solid black; - } - &:dir(rtl) { +} + +test-flowing-border:dir(rtl) { border-top: 9px solid black; border-right: 9px solid black; - } - border: inherit; - &:dir(ltr) { +} + +test-flowing-border:dir(ltr) { border-top: 10px solid black; border-left: 11px solid black; - } - &:dir(rtl) { +} + +test-flowing-border:dir(rtl) { border-top: 10px solid black; border-right: 11px solid black; - } - border: inherit; - &:dir(ltr) { +} + +test-flowing-border:dir(ltr) { border-bottom: 12px solid black; border-right: 12px solid black; - } - &:dir(rtl) { +} + +test-flowing-border:dir(rtl) { border-bottom: 12px solid black; border-left: 12px solid black; - } - border: inherit; - &:dir(ltr) { +} + +test-flowing-border:dir(ltr) { border-bottom: 13px solid black; border-right: 14px solid black; - } - &:dir(rtl) { +} + +test-flowing-border:dir(rtl) { border-bottom: 13px solid black; border-left: 14px solid black; - } +} + +test-flowing-border { + border: inherit; + border: inherit; + border: inherit; + border: inherit; + border: inherit; + border: inherit; + border: inherit; + border: inherit; border: inherit; } -test-flowing-border-color { - border-color: inherit; - &:dir(ltr) { +test-flowing-border-color:dir(ltr) { border-top-color: 1px solid black; border-left-color: 2px solid black; border-bottom-color: 3px solid black; border-right-color: 4px solid black; - } - &:dir(rtl) { +} + +test-flowing-border-color:dir(rtl) { border-top-color: 1px solid black; border-right-color: 2px solid black; border-bottom-color: 3px solid black; border-left-color: 4px solid black; - } - border-color: inherit; - &:dir(ltr) { +} + +test-flowing-border-color:dir(ltr) { border-left-color: 5px solid black; border-right-color: 6px solid black; - } - &:dir(rtl) { +} + +test-flowing-border-color:dir(rtl) { border-right-color: 5px solid black; border-left-color: 6px solid black; - } - border-color: inherit; - &:dir(ltr) { +} + +test-flowing-border-color:dir(ltr) { border-left-color: 7px solid black; - } - &:dir(rtl) { +} + +test-flowing-border-color:dir(rtl) { border-right-color: 7px solid black; - } - border-color: inherit; - &:dir(ltr) { +} + +test-flowing-border-color:dir(ltr) { border-right-color: 8px solid black; - } - &:dir(rtl) { +} + +test-flowing-border-color:dir(rtl) { border-left-color: 8px solid black; - } - border-color: inherit; - &:dir(ltr) { +} + +test-flowing-border-color:dir(ltr) { border-top-color: 9px solid black; border-left-color: 9px solid black; - } - &:dir(rtl) { +} + +test-flowing-border-color:dir(rtl) { border-top-color: 9px solid black; border-right-color: 9px solid black; - } - border-color: inherit; - &:dir(ltr) { +} + +test-flowing-border-color:dir(ltr) { border-top-color: 10px solid black; border-left-color: 11px solid black; - } - &:dir(rtl) { +} + +test-flowing-border-color:dir(rtl) { border-top-color: 10px solid black; border-right-color: 11px solid black; - } - border-color: inherit; - &:dir(ltr) { +} + +test-flowing-border-color:dir(ltr) { border-bottom-color: 12px solid black; border-right-color: 12px solid black; - } - &:dir(rtl) { +} + +test-flowing-border-color:dir(rtl) { border-bottom-color: 12px solid black; border-left-color: 12px solid black; - } - border-color: inherit; - &:dir(ltr) { +} + +test-flowing-border-color:dir(ltr) { border-bottom-color: 13px solid black; border-right-color: 14px solid black; - } - &:dir(rtl) { +} + +test-flowing-border-color:dir(rtl) { border-bottom-color: 13px solid black; border-left-color: 14px solid black; - } +} + +test-flowing-border-color { + border-color: inherit; + border-color: inherit; + border-color: inherit; + border-color: inherit; + border-color: inherit; + border-color: inherit; + border-color: inherit; + border-color: inherit; border-color: inherit; } diff --git a/test/border.preserve.expect.css b/test/border.preserve.expect.css index dffc85d7de..2031e0a281 100644 --- a/test/border.preserve.expect.css +++ b/test/border.preserve.expect.css @@ -32,170 +32,202 @@ test-border { border-bottom: 16px solid black; } -test-flowing-border { - border: inherit; - &:dir(ltr) { +test-flowing-border:dir(ltr) { border-top: 1px solid black; border-left: 2px solid black; border-bottom: 3px solid black; border-right: 4px solid black; - } - &:dir(rtl) { +} + +test-flowing-border:dir(rtl) { border-top: 1px solid black; border-right: 2px solid black; border-bottom: 3px solid black; border-left: 4px solid black; - } - border: logical 1px solid black / 2px solid black / 3px solid black / 4px solid black; - border: inherit; - &:dir(ltr) { +} + +test-flowing-border:dir(ltr) { border-left: 5px solid black; border-right: 6px solid black; - } - &:dir(rtl) { +} + +test-flowing-border:dir(rtl) { border-right: 5px solid black; border-left: 6px solid black; - } - border-inline: 5px solid black / 6px solid black; - border: inherit; - &:dir(ltr) { +} + +test-flowing-border:dir(ltr) { border-left: 7px solid black; - } - &:dir(rtl) { +} + +test-flowing-border:dir(rtl) { border-right: 7px solid black; - } - border-inline-start: 7px solid black; - border: inherit; - &:dir(ltr) { +} + +test-flowing-border:dir(ltr) { border-right: 8px solid black; - } - &:dir(rtl) { +} + +test-flowing-border:dir(rtl) { border-left: 8px solid black; - } - border-inline-end: 8px solid black; - border: inherit; - &:dir(ltr) { +} + +test-flowing-border:dir(ltr) { border-top: 9px solid black; border-left: 9px solid black; - } - &:dir(rtl) { +} + +test-flowing-border:dir(rtl) { border-top: 9px solid black; border-right: 9px solid black; - } - border-start: 9px solid black; - border: inherit; - &:dir(ltr) { +} + +test-flowing-border:dir(ltr) { border-top: 10px solid black; border-left: 11px solid black; - } - &:dir(rtl) { +} + +test-flowing-border:dir(rtl) { border-top: 10px solid black; border-right: 11px solid black; - } - border-start: 10px solid black / 11px solid black; - border: inherit; - &:dir(ltr) { +} + +test-flowing-border:dir(ltr) { border-bottom: 12px solid black; border-right: 12px solid black; - } - &:dir(rtl) { +} + +test-flowing-border:dir(rtl) { border-bottom: 12px solid black; border-left: 12px solid black; - } - border-end: 12px solid black; - border: inherit; - &:dir(ltr) { +} + +test-flowing-border:dir(ltr) { border-bottom: 13px solid black; border-right: 14px solid black; - } - &:dir(rtl) { +} + +test-flowing-border:dir(rtl) { border-bottom: 13px solid black; border-left: 14px solid black; - } +} + +test-flowing-border { + border: inherit; + border: logical 1px solid black / 2px solid black / 3px solid black / 4px solid black; + border: inherit; + border-inline: 5px solid black / 6px solid black; + border: inherit; + border-inline-start: 7px solid black; + border: inherit; + border-inline-end: 8px solid black; + border: inherit; + border-start: 9px solid black; + border: inherit; + border-start: 10px solid black / 11px solid black; + border: inherit; + border-end: 12px solid black; + border: inherit; border-end: 13px solid black / 14px solid black; border: inherit; } -test-flowing-border-color { - border-color: inherit; - &:dir(ltr) { +test-flowing-border-color:dir(ltr) { border-top-color: 1px solid black; border-left-color: 2px solid black; border-bottom-color: 3px solid black; border-right-color: 4px solid black; - } - &:dir(rtl) { +} + +test-flowing-border-color:dir(rtl) { border-top-color: 1px solid black; border-right-color: 2px solid black; border-bottom-color: 3px solid black; border-left-color: 4px solid black; - } - border-color: logical 1px solid black / 2px solid black / 3px solid black / 4px solid black; - border-color: inherit; - &:dir(ltr) { +} + +test-flowing-border-color:dir(ltr) { border-left-color: 5px solid black; border-right-color: 6px solid black; - } - &:dir(rtl) { +} + +test-flowing-border-color:dir(rtl) { border-right-color: 5px solid black; border-left-color: 6px solid black; - } - border-inline-color: 5px solid black / 6px solid black; - border-color: inherit; - &:dir(ltr) { +} + +test-flowing-border-color:dir(ltr) { border-left-color: 7px solid black; - } - &:dir(rtl) { +} + +test-flowing-border-color:dir(rtl) { border-right-color: 7px solid black; - } - border-inline-start-color: 7px solid black; - border-color: inherit; - &:dir(ltr) { +} + +test-flowing-border-color:dir(ltr) { border-right-color: 8px solid black; - } - &:dir(rtl) { +} + +test-flowing-border-color:dir(rtl) { border-left-color: 8px solid black; - } - border-inline-end-color: 8px solid black; - border-color: inherit; - &:dir(ltr) { +} + +test-flowing-border-color:dir(ltr) { border-top-color: 9px solid black; border-left-color: 9px solid black; - } - &:dir(rtl) { +} + +test-flowing-border-color:dir(rtl) { border-top-color: 9px solid black; border-right-color: 9px solid black; - } - border-start-color: 9px solid black; - border-color: inherit; - &:dir(ltr) { +} + +test-flowing-border-color:dir(ltr) { border-top-color: 10px solid black; border-left-color: 11px solid black; - } - &:dir(rtl) { +} + +test-flowing-border-color:dir(rtl) { border-top-color: 10px solid black; border-right-color: 11px solid black; - } - border-start-color: 10px solid black / 11px solid black; - border-color: inherit; - &:dir(ltr) { +} + +test-flowing-border-color:dir(ltr) { border-bottom-color: 12px solid black; border-right-color: 12px solid black; - } - &:dir(rtl) { +} + +test-flowing-border-color:dir(rtl) { border-bottom-color: 12px solid black; border-left-color: 12px solid black; - } - border-end-color: 12px solid black; - border-color: inherit; - &:dir(ltr) { +} + +test-flowing-border-color:dir(ltr) { border-bottom-color: 13px solid black; border-right-color: 14px solid black; - } - &:dir(rtl) { +} + +test-flowing-border-color:dir(rtl) { border-bottom-color: 13px solid black; border-left-color: 14px solid black; - } +} + +test-flowing-border-color { + border-color: inherit; + border-color: logical 1px solid black / 2px solid black / 3px solid black / 4px solid black; + border-color: inherit; + border-inline-color: 5px solid black / 6px solid black; + border-color: inherit; + border-inline-start-color: 7px solid black; + border-color: inherit; + border-inline-end-color: 8px solid black; + border-color: inherit; + border-start-color: 9px solid black; + border-color: inherit; + border-start-color: 10px solid black / 11px solid black; + border-color: inherit; + border-end-color: 12px solid black; + border-color: inherit; border-end-color: 13px solid black / 14px solid black; border-color: inherit; } diff --git a/test/clear.expect.css b/test/clear.expect.css index 75cc0cc378..43741d2c8a 100644 --- a/test/clear.expect.css +++ b/test/clear.expect.css @@ -1,17 +1,17 @@ -test-clear { - clear: both; - clear: left; - &:dir(ltr) { +test-clear:dir(ltr) { clear: left; - } - &:dir(rtl) { +} +test-clear:dir(rtl) { clear: right; - } - &:dir(ltr) { +} +test-clear:dir(ltr) { clear: right; - } - &:dir(rtl) { +} +test-clear:dir(rtl) { + clear: left; +} +test-clear { + clear: both; clear: left; - } clear: right; } diff --git a/test/float.expect.css b/test/float.expect.css index d2c5c40ce4..37c4e13509 100644 --- a/test/float.expect.css +++ b/test/float.expect.css @@ -1,16 +1,16 @@ -test-float { - float: left; - &:dir(ltr) { +test-float:dir(ltr) { float: left; - } - &:dir(rtl) { +} +test-float:dir(rtl) { float: right; - } - &:dir(ltr) { +} +test-float:dir(ltr) { float: right; - } - &:dir(rtl) { +} +test-float:dir(rtl) { + float: left; +} +test-float { float: left; - } float: right; } diff --git a/test/inset.expect.css b/test/inset.expect.css index 9be548e81b..d824cf8820 100644 --- a/test/inset.expect.css +++ b/test/inset.expect.css @@ -17,103 +17,119 @@ test-inset { right: 8px; } -test-flowing-inset { - top: auto; - right: auto; - bottom: auto; - left: auto; - &:dir(ltr) { +test-flowing-inset:dir(ltr) { top: 1px; left: 2px; bottom: 3px; right: 4px; - } - &:dir(rtl) { +} + +test-flowing-inset:dir(rtl) { top: 1px; right: 2px; bottom: 3px; left: 4px; - } - top: auto; - right: auto; - bottom: auto; - left: auto; - &:dir(ltr) { +} + +test-flowing-inset:dir(ltr) { left: 5px; right: 6px; - } - &:dir(rtl) { +} + +test-flowing-inset:dir(rtl) { right: 5px; left: 6px; - } +} + +test-flowing-inset:dir(ltr) { + left: 7px; +} + +test-flowing-inset:dir(rtl) { + right: 7px; +} + +test-flowing-inset:dir(ltr) { + right: 8px; +} + +test-flowing-inset:dir(rtl) { + left: 8px; +} + +test-flowing-inset:dir(ltr) { + top: 9px; + left: 9px; +} + +test-flowing-inset:dir(rtl) { + top: 9px; + right: 9px; +} + +test-flowing-inset:dir(ltr) { + top: 10px; + left: 11px; +} + +test-flowing-inset:dir(rtl) { + top: 10px; + right: 11px; +} + +test-flowing-inset:dir(ltr) { + bottom: 12px; + right: 12px; +} + +test-flowing-inset:dir(rtl) { + bottom: 12px; + left: 12px; +} + +test-flowing-inset:dir(ltr) { + bottom: 13px; + right: 14px; +} + +test-flowing-inset:dir(rtl) { + bottom: 13px; + left: 14px; +} + +test-flowing-inset { + top: auto; + right: auto; + bottom: auto; + left: auto; + top: auto; + right: auto; + bottom: auto; + left: auto; top: auto; right: auto; bottom: auto; left: auto; - &:dir(ltr) { - left: 7px; - } - &:dir(rtl) { - right: 7px; - } top: auto; right: auto; bottom: auto; left: auto; - &:dir(ltr) { - right: 8px; - } - &:dir(rtl) { - left: 8px; - } top: auto; right: auto; bottom: auto; left: auto; - &:dir(ltr) { - top: 9px; - left: 9px; - } - &:dir(rtl) { - top: 9px; - right: 9px; - } top: auto; right: auto; bottom: auto; left: auto; - &:dir(ltr) { - top: 10px; - left: 11px; - } - &:dir(rtl) { - top: 10px; - right: 11px; - } top: auto; right: auto; bottom: auto; left: auto; - &:dir(ltr) { - bottom: 12px; - right: 12px; - } - &:dir(rtl) { - bottom: 12px; - left: 12px; - } top: auto; right: auto; bottom: auto; left: auto; - &:dir(ltr) { - bottom: 13px; - right: 14px; - } - &:dir(rtl) { - bottom: 13px; - left: 14px; - } top: auto; right: auto; bottom: auto; diff --git a/test/margin.expect.css b/test/margin.expect.css index fb8b4a81d8..c4f57d6809 100644 --- a/test/margin.expect.css +++ b/test/margin.expect.css @@ -15,72 +15,88 @@ test-margin { margin-bottom: 16px; } -test-flowing-margin { - margin: auto; - &:dir(ltr) { +test-flowing-margin:dir(ltr) { margin: 1px 4px 3px 2px; - } - &:dir(rtl) { +} + +test-flowing-margin:dir(rtl) { margin: 1px 2px 3px 4px; - } - margin: auto; - &:dir(ltr) { +} + +test-flowing-margin:dir(ltr) { margin-left: 5px; margin-right: 6px; - } - &:dir(rtl) { +} + +test-flowing-margin:dir(rtl) { margin-right: 5px; margin-left: 6px; - } - margin: auto; - &:dir(ltr) { +} + +test-flowing-margin:dir(ltr) { margin-left: 7px; - } - &:dir(rtl) { +} + +test-flowing-margin:dir(rtl) { margin-right: 7px; - } - margin: auto; - &:dir(ltr) { +} + +test-flowing-margin:dir(ltr) { margin-right: 8px; - } - &:dir(rtl) { +} + +test-flowing-margin:dir(rtl) { margin-left: 8px; - } - margin: auto; - &:dir(ltr) { +} + +test-flowing-margin:dir(ltr) { margin-top: 9px; margin-left: 9px; - } - &:dir(rtl) { +} + +test-flowing-margin:dir(rtl) { margin-top: 9px; margin-right: 9px; - } - margin: auto; - &:dir(ltr) { +} + +test-flowing-margin:dir(ltr) { margin-top: 10px; margin-left: 11px; - } - &:dir(rtl) { +} + +test-flowing-margin:dir(rtl) { margin-top: 10px; margin-right: 11px; - } - margin: auto; - &:dir(ltr) { +} + +test-flowing-margin:dir(ltr) { margin-bottom: 12px; margin-right: 12px; - } - &:dir(rtl) { +} + +test-flowing-margin:dir(rtl) { margin-bottom: 12px; margin-left: 12px; - } - margin: auto; - &:dir(ltr) { +} + +test-flowing-margin:dir(ltr) { margin-bottom: 13px; margin-right: 14px; - } - &:dir(rtl) { +} + +test-flowing-margin:dir(rtl) { margin-bottom: 13px; margin-left: 14px; - } +} + +test-flowing-margin { + margin: auto; + margin: auto; + margin: auto; + margin: auto; + margin: auto; + margin: auto; + margin: auto; + margin: auto; margin: auto; } diff --git a/test/padding.expect.css b/test/padding.expect.css index 0819c1eb55..61d166737b 100644 --- a/test/padding.expect.css +++ b/test/padding.expect.css @@ -15,72 +15,88 @@ test-padding { padding-bottom: 16px; } -test-flowing-padding { - padding: auto; - &:dir(ltr) { +test-flowing-padding:dir(ltr) { padding: 1px 4px 3px 2px; - } - &:dir(rtl) { +} + +test-flowing-padding:dir(rtl) { padding: 1px 2px 3px 4px; - } - padding: auto; - &:dir(ltr) { +} + +test-flowing-padding:dir(ltr) { padding-left: 5px; padding-right: 6px; - } - &:dir(rtl) { +} + +test-flowing-padding:dir(rtl) { padding-right: 5px; padding-left: 6px; - } - padding: auto; - &:dir(ltr) { +} + +test-flowing-padding:dir(ltr) { padding-left: 7px; - } - &:dir(rtl) { +} + +test-flowing-padding:dir(rtl) { padding-right: 7px; - } - padding: auto; - &:dir(ltr) { +} + +test-flowing-padding:dir(ltr) { padding-right: 8px; - } - &:dir(rtl) { +} + +test-flowing-padding:dir(rtl) { padding-left: 8px; - } - padding: auto; - &:dir(ltr) { +} + +test-flowing-padding:dir(ltr) { padding-top: 9px; padding-left: 9px; - } - &:dir(rtl) { +} + +test-flowing-padding:dir(rtl) { padding-top: 9px; padding-right: 9px; - } - padding: auto; - &:dir(ltr) { +} + +test-flowing-padding:dir(ltr) { padding-top: 10px; padding-left: 11px; - } - &:dir(rtl) { +} + +test-flowing-padding:dir(rtl) { padding-top: 10px; padding-right: 11px; - } - padding: auto; - &:dir(ltr) { +} + +test-flowing-padding:dir(ltr) { padding-bottom: 12px; padding-right: 12px; - } - &:dir(rtl) { +} + +test-flowing-padding:dir(rtl) { padding-bottom: 12px; padding-left: 12px; - } - padding: auto; - &:dir(ltr) { +} + +test-flowing-padding:dir(ltr) { padding-bottom: 13px; padding-right: 14px; - } - &:dir(rtl) { +} + +test-flowing-padding:dir(rtl) { padding-bottom: 13px; padding-left: 14px; - } +} + +test-flowing-padding { + padding: auto; + padding: auto; + padding: auto; + padding: auto; + padding: auto; + padding: auto; + padding: auto; + padding: auto; padding: auto; } diff --git a/test/text-align.expect.css b/test/text-align.expect.css index 605981cefa..f33230f7ef 100644 --- a/test/text-align.expect.css +++ b/test/text-align.expect.css @@ -1,16 +1,16 @@ -test-text-align { - text-align: left; - &:dir(ltr) { +test-text-align:dir(ltr) { text-align: left; - } - &:dir(rtl) { +} +test-text-align:dir(rtl) { text-align: right; - } - &:dir(ltr) { +} +test-text-align:dir(ltr) { text-align: right; - } - &:dir(rtl) { +} +test-text-align:dir(rtl) { + text-align: left; +} +test-text-align { text-align: left; - } text-align: right; } diff --git a/test/transition.css b/test/transition.css new file mode 100644 index 0000000000..9a91e6f674 --- /dev/null +++ b/test/transition.css @@ -0,0 +1,45 @@ +.transition { + transition: 1s opacity ease; +} + +.transition-block { + transition: 1s inset-block ease; + transition: 1s margin-block ease; + transition: 1s padding-block ease; + transition-property: border-block, border-block-color, border-block-style, border-block-width; +} + +.transition-inline { + transition: 1s inset-inline ease; + transition: 1s margin-inline ease; + transition: 1s padding-inline ease; + transition-property: border-inline, border-inline-color, border-inline-style, border-inline-width; +} + +.transition-start { + transition: 1s inset-start ease; + transition: 1s margin-start ease; + transition: 1s padding-start ease; +} + +.transition-block-start { + transition: 1s inset-block-start ease; + transition: 1s margin-block-start ease; + transition: 1s padding-block-start ease; +} + +.transition-end { + transition: 1s inset-end ease; + transition: 1s margin-end ease; + transition: 1s padding-end ease; +} + +.transition-inline-end { + transition: 1s inset-inline-end ease; + transition: 1s margin-inline-end ease; + transition: 1s padding-inline-end ease; +} + +.transition-mixed { + transition: 1s opacity ease, 1s inset-inline-start ease; +} diff --git a/test/transition.expect.css b/test/transition.expect.css new file mode 100644 index 0000000000..7bb68a488c --- /dev/null +++ b/test/transition.expect.css @@ -0,0 +1,103 @@ +.transition { + transition: 1s opacity ease; +} + +.transition-block { + transition: 1s inset-block ease; + transition: 1s margin-block ease; + transition: 1s padding-block ease; + transition-property: border-block, border-block-color, border-block-style, border-block-width; +} + +.transition-inline { + transition: 1s inset-inline ease; + transition: 1s margin-inline ease; + transition: 1s padding-inline ease; + transition-property: border-inline, border-inline-color, border-inline-style, border-inline-width; +} + +.transition-start:dir(ltr) { + transition: 1s top ease,1s left ease; +} + +.transition-start:dir(rtl) { + transition: 1s top ease,1s right ease; +} + +.transition-start:dir(ltr) { + transition: 1s margin-top ease,1s margin-left ease; +} + +.transition-start:dir(rtl) { + transition: 1s margin-top ease,1s margin-right ease; +} + +.transition-start:dir(ltr) { + transition: 1s padding-top ease,1s padding-left ease; +} + +.transition-start:dir(rtl) { + transition: 1s padding-top ease,1s padding-right ease; +} + +.transition-block-start { + transition: 1s inset-block-start ease; + transition: 1s margin-block-start ease; + transition: 1s padding-block-start ease; +} + +.transition-end:dir(ltr) { + transition: 1s bottom ease,1s right ease; +} + +.transition-end:dir(rtl) { + transition: 1s bottom ease,1s left ease; +} + +.transition-end:dir(ltr) { + transition: 1s margin-bottom ease,1s margin-right ease; +} + +.transition-end:dir(rtl) { + transition: 1s margin-bottom ease,1s margin-left ease; +} + +.transition-end:dir(ltr) { + transition: 1s padding-bottom ease,1s padding-right ease; +} + +.transition-end:dir(rtl) { + transition: 1s padding-bottom ease,1s padding-left ease; +} + +.transition-inline-end:dir(ltr) { + transition: 1s right ease; +} + +.transition-inline-end:dir(rtl) { + transition: 1s left ease; +} + +.transition-inline-end:dir(ltr) { + transition: 1s margin-right ease; +} + +.transition-inline-end:dir(rtl) { + transition: 1s margin-left ease; +} + +.transition-inline-end:dir(ltr) { + transition: 1s padding-right ease; +} + +.transition-inline-end:dir(rtl) { + transition: 1s padding-left ease; +} + +.transition-mixed:dir(ltr) { + transition: 1s opacity ease, 1s left ease; +} + +.transition-mixed:dir(rtl) { + transition: 1s opacity ease, 1s right ease; +} diff --git a/test/transition.ltr.expect.css b/test/transition.ltr.expect.css new file mode 100644 index 0000000000..469b058006 --- /dev/null +++ b/test/transition.ltr.expect.css @@ -0,0 +1,45 @@ +.transition { + transition: 1s opacity ease; +} + +.transition-block { + transition: 1s top ease,1s bottom ease; + transition: 1s margin-top ease,1s margin-bottom ease; + transition: 1s padding-top ease,1s padding-bottom ease; + transition-property: border-top,border-bottom, border-top-color, border-bottom-color, border-top-style, border-bottom-style, border-top-width, border-bottom-width; +} + +.transition-inline { + transition: 1s left ease,1s right ease; + transition: 1s margin-left ease,1s margin-right ease; + transition: 1s padding-left ease,1s padding-right ease; + transition-property: border-left,border-right, border-left-color, border-right-color, border-left-style, border-right-style, border-left-width, border-right-width; +} + +.transition-start { + transition: 1s top ease,1s left ease; + transition: 1s margin-top ease,1s margin-left ease; + transition: 1s padding-top ease,1s padding-left ease; +} + +.transition-block-start { + transition: 1s top ease; + transition: 1s margin-top ease; + transition: 1s padding-top ease; +} + +.transition-end { + transition: 1s bottom ease,1s right ease; + transition: 1s margin-bottom ease,1s margin-right ease; + transition: 1s padding-bottom ease,1s padding-right ease; +} + +.transition-inline-end { + transition: 1s right ease; + transition: 1s margin-right ease; + transition: 1s padding-right ease; +} + +.transition-mixed { + transition: 1s opacity ease, 1s left ease; +} From ff7a08d9a02390bd26b5233884bb4a7fb2558f20 Mon Sep 17 00:00:00 2001 From: Jonathan Neal Date: Thu, 20 Sep 2018 16:16:44 -0400 Subject: [PATCH 720/795] 2.0.2 --- .tape.js | 6 ++++++ CHANGELOG.md | 4 ++++ lib/import-from.js | 2 +- package.json | 4 ++-- test/basic.import-is-empty.expect.css | 10 ++++++++++ 5 files changed, 23 insertions(+), 3 deletions(-) create mode 100644 test/basic.import-is-empty.expect.css diff --git a/.tape.js b/.tape.js index 00854c33ed..dc9f015b76 100644 --- a/.tape.js +++ b/.tape.js @@ -77,6 +77,12 @@ module.exports = { }, expect: 'basic.import.expect.css', result: 'basic.import.result.css' + }, + 'basic:import-is-empty': { + message: 'supports { importFrom: {} } usage', + options: { + importFrom: {} + } } } }; diff --git a/CHANGELOG.md b/CHANGELOG.md index 007135f27e..3eb621946e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # Changes to PostCSS Environment Variables +### 2.0.2 (September 20, 2018) + +- Updated: Do not break on an empty importFrom object + ### 2.0.1 (September 18, 2018) - Updated: Support for PostCSS Values Parser 2 diff --git a/lib/import-from.js b/lib/import-from.js index 5b99a51d6a..c50ba15b74 100644 --- a/lib/import-from.js +++ b/lib/import-from.js @@ -59,7 +59,7 @@ export default function importEnvironmentVariablesFromSources(sources) { const from = String(opts.from || ''); // type of file being read from - const type = (opts.type || path.extname(opts.from).slice(1)).toLowerCase(); + const type = (opts.type || path.extname(from).slice(1)).toLowerCase(); return { type, from }; }).reduce(async (environmentVariables, source) => { diff --git a/package.json b/package.json index b1e69041ff..16ba077b55 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "postcss-env-function", - "version": "2.0.1", + "version": "2.0.2", "description": "Use env() variables in CSS", "author": "Jonathan Neal ", "license": "CC0-1.0", @@ -39,7 +39,7 @@ "eslint-config-dev": "^2.0.0", "postcss-tape": "^2.2.0", "pre-commit": "^1.2.2", - "rollup": "^0.66.0", + "rollup": "^0.66.1", "rollup-plugin-babel": "^4.0.3" }, "eslintConfig": { diff --git a/test/basic.import-is-empty.expect.css b/test/basic.import-is-empty.expect.css new file mode 100644 index 0000000000..5199c9faee --- /dev/null +++ b/test/basic.import-is-empty.expect.css @@ -0,0 +1,10 @@ +body { + order: 1; + padding: env(--some-custom-padding); +} + +@media (min-width: env(--another-custom-width)) { + body { + order: 2; + } +} From ceb2ac4beb1c54dc17d21f49cbd314ef3b0e5aa1 Mon Sep 17 00:00:00 2001 From: Jonathan Neal Date: Thu, 20 Sep 2018 16:18:15 -0400 Subject: [PATCH 721/795] 8.0.4 --- .tape.js | 6 +++++ CHANGELOG.md | 4 +++ lib/import-from.js | 2 +- package.json | 4 +-- test/basic.import-is-empty.expect.css | 35 +++++++++++++++++++++++++++ 5 files changed, 48 insertions(+), 3 deletions(-) create mode 100644 test/basic.import-is-empty.expect.css diff --git a/.tape.js b/.tape.js index 7dd62f6af5..d97e0101dd 100644 --- a/.tape.js +++ b/.tape.js @@ -233,6 +233,12 @@ module.exports = { throw new Error('The original file did not match the freshly exported copy'); } } + }, + 'basic:import-is-empty': { + message: 'supports { importFrom: {} } usage', + options: { + importFrom: {} + } } } }; diff --git a/CHANGELOG.md b/CHANGELOG.md index 8c26088365..066f19d6ff 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # Changes to PostCSS Custom Properties +### 8.0.4 (September 18, 2018) + +- Fixed: Do not break on an empty `importFrom` object + ### 8.0.3 (September 18, 2018) - Updated: PostCSS Values Parser 2 diff --git a/lib/import-from.js b/lib/import-from.js index a5c918a38b..7e899146ad 100644 --- a/lib/import-from.js +++ b/lib/import-from.js @@ -78,7 +78,7 @@ export default function importCustomPropertiesFromSources(sources) { const from = String(opts.from || ''); // type of file being read from - const type = (opts.type || path.extname(opts.from).slice(1)).toLowerCase(); + const type = (opts.type || path.extname(from).slice(1)).toLowerCase(); return { type, from }; }).reduce(async (customProperties, source) => { diff --git a/package.json b/package.json index 7a4720b9b2..882d3aa626 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "postcss-custom-properties", - "version": "8.0.3", + "version": "8.0.4", "description": "Use Custom Properties Queries in CSS", "author": "Jonathan Neal ", "contributors": [ @@ -41,7 +41,7 @@ "eslint-config-dev": "^2.0.0", "postcss-tape": "^2.2.0", "pre-commit": "^1.2.2", - "rollup": "^0.66.0", + "rollup": "^0.66.1", "rollup-plugin-babel": "^4.0.3" }, "eslintConfig": { diff --git a/test/basic.import-is-empty.expect.css b/test/basic.import-is-empty.expect.css new file mode 100644 index 0000000000..90691d54b9 --- /dev/null +++ b/test/basic.import-is-empty.expect.css @@ -0,0 +1,35 @@ +html { + --ref-color: skip; +} + +:root { + --color: rgb(255, 0, 0); + --ref-color: var(--color); + --circular: var(--circular-2); + --circular-2: var(--circular); +} + +.test { + --skip: gray; + color: rgb(255, 0, 0); + color: var(--color); +} + +.test--fallback { + color: blue; + color: var(--color-2, blue); +} + +.test--color_w_var { + color: rgb(255, 0, 0); + color: var(--ref-color); +} + +.test--circular_var { + color: var(--circular); +} + +.test--color_spacing { + box-shadow: inset 0 -3px 0 rgb(255, 0, 0); + box-shadow: inset 0 -3px 0 var(--color); +} From 39a25e05f39b5cc5f879b8e828ee8ced197750a9 Mon Sep 17 00:00:00 2001 From: Jonathan Neal Date: Thu, 20 Sep 2018 16:23:37 -0400 Subject: [PATCH 722/795] 7.0.3 --- .tape.js | 6 ++++++ CHANGELOG.md | 4 ++++ lib/import-from.js | 2 +- package.json | 8 ++++---- test/import.empty.expect.css | 29 +++++++++++++++++++++++++++++ 5 files changed, 44 insertions(+), 5 deletions(-) create mode 100644 test/import.empty.expect.css diff --git a/.tape.js b/.tape.js index 72204e3812..d5ce77c70f 100644 --- a/.tape.js +++ b/.tape.js @@ -92,6 +92,12 @@ module.exports = { expect: 'import.expect.css', result: 'import.result.css' }, + 'import:empty': { + message: 'supports { importFrom: {} } usage', + options: { + importFrom: {} + } + }, 'basic:export': { message: 'supports { exportTo: { customMedia: { ... } } } usage', options: { diff --git a/CHANGELOG.md b/CHANGELOG.md index 4284f45fad..6a895859ca 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # Changes to PostCSS Custom Media +### 7.0.3 (September 20, 2018) + +- Fixed: Do not break on an empty `importFrom` object + ### 7.0.2 (September 15, 2018) - Fixed: An issue with re-assigning params as a non-string diff --git a/lib/import-from.js b/lib/import-from.js index 79f3bf4be1..47038f6e21 100644 --- a/lib/import-from.js +++ b/lib/import-from.js @@ -78,7 +78,7 @@ export default function importCustomMediaFromSources(sources) { const from = String(opts.from || ''); // type of file being read from - const type = (opts.type || path.extname(opts.from).slice(1)).toLowerCase(); + const type = (opts.type || path.extname(from).slice(1)).toLowerCase(); return { type, from }; }).reduce(async (customMedia, source) => { diff --git a/package.json b/package.json index 4955b81aab..a7479bc0e2 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "postcss-custom-media", - "version": "7.0.2", + "version": "7.0.3", "description": "Use Custom Media Queries in CSS", "author": "Jonathan Neal ", "contributors": [ @@ -30,15 +30,15 @@ "postcss": "^7.0.2" }, "devDependencies": { - "@babel/core": "^7.0.1", + "@babel/core": "^7.1.0", "@babel/plugin-syntax-dynamic-import": "^7.0.0", - "@babel/preset-env": "^7.0.0", + "@babel/preset-env": "^7.1.0", "babel-eslint": "^9.0.0", "eslint": "^5.6.0", "eslint-config-dev": "^2.0.0", "postcss-tape": "^2.2.0", "pre-commit": "^1.2.2", - "rollup": "^0.65.2", + "rollup": "^0.66.1", "rollup-plugin-babel": "^4.0.3" }, "eslintConfig": { diff --git a/test/import.empty.expect.css b/test/import.empty.expect.css new file mode 100644 index 0000000000..f37220e74e --- /dev/null +++ b/test/import.empty.expect.css @@ -0,0 +1,29 @@ +@media (--mq-a) { + body { + order: 1; + } +} + +@media (--mq-a), (--mq-a) { + body { + order: 1; + } +} + +@media not all and (--mq-a) { + body { + order: 2; + } +} + +@media (--not-mq-a) { + body { + order: 1; + } +} + +@media not all and (--not-mq-a) { + body { + order: 2; + } +} From 4a422f0eaba5b47fd53abe36e92f9092ad63858f Mon Sep 17 00:00:00 2001 From: Jonathan Neal Date: Thu, 20 Sep 2018 16:26:45 -0400 Subject: [PATCH 723/795] 5.1.2 --- .tape.js | 6 ++++ CHANGELOG.md | 4 +++ lib/import-from.js | 2 +- package.json | 4 +-- test/basic.import-empty.expect.css | 57 ++++++++++++++++++++++++++++++ 5 files changed, 70 insertions(+), 3 deletions(-) create mode 100644 test/basic.import-empty.expect.css diff --git a/.tape.js b/.tape.js index 366f841718..c960d304e0 100644 --- a/.tape.js +++ b/.tape.js @@ -92,6 +92,12 @@ module.exports = { expect: 'basic.import.expect.css', result: 'basic.import.result.css' }, + 'basic:import-empty': { + message: 'supports { importFrom: {} } usage', + options: { + importFrom: {} + } + }, 'basic:export': { message: 'supports { exportTo: { customSelectors: { ... } } } usage', options: { diff --git a/CHANGELOG.md b/CHANGELOG.md index 3f23dbe3ee..9c8f563e29 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # Changes to PostCSS Custom Selectors +### 5.1.2 (September 20, 2018) + +- Fixed: Do not break on an empty `importFrom` object + ### 5.1.1 (September 18, 2018) - Fixed: Selectors like `.foo:--h1` become `h1.foo` instead of `.fooh1` diff --git a/lib/import-from.js b/lib/import-from.js index 5201d639b4..faf76d3bf4 100644 --- a/lib/import-from.js +++ b/lib/import-from.js @@ -78,7 +78,7 @@ export default function importCustomSelectorsFromSources(sources) { const from = String(opts.from || ''); // type of file being read from - const type = (opts.type || path.extname(opts.from).slice(1)).toLowerCase(); + const type = (opts.type || path.extname(from).slice(1)).toLowerCase(); return { type, from }; }).reduce(async (customSelectors, source) => { diff --git a/package.json b/package.json index 58453b369e..a68c2cf188 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "postcss-custom-selectors", - "version": "5.1.1", + "version": "5.1.2", "description": "Use Custom Selectors in CSS", "author": "Jonathan Neal ", "contributors": [ @@ -42,7 +42,7 @@ "eslint-config-dev": "^2.0.0", "postcss-tape": "^2.2.0", "pre-commit": "^1.2.2", - "rollup": "^0.66.0", + "rollup": "^0.66.1", "rollup-plugin-babel": "^4.0.3" }, "eslintConfig": { diff --git a/test/basic.import-empty.expect.css b/test/basic.import-empty.expect.css new file mode 100644 index 0000000000..c473452988 --- /dev/null +++ b/test/basic.import-empty.expect.css @@ -0,0 +1,57 @@ +.foo.foo { + margin-top: 16px; +} + +h1 + p,h2 + p,h3 + p,h4 + p,h5 + p,h6 + p {} + +.foo > .baz {} +.fizz > .foo,.buzz > .foo {} +.btn-primary,.btn-success,.btn-info,.btn-warning,.btn-danger, .btn-primary:active, .btn-success:active, .btn-info:active, .btn-warning:active, .btn-danger:active {} + +.foo + p,.bar>.baz + p { + display: block; +} + +.foo > a::before img,.foo > a::after img { + display: block; +} + +.foo, .foo.bar { + color: white; +} + +.foo .foo:hover { + color: white; +} + +.fo--oo > h1,.fo--oo > h2,.fo--oo > h3 { + margin: auto; +} + +h4:hover .ba--z,h5:hover .ba--z,h6:hover .ba--z { + display: block; +} + +/* comment */ + +article :--heading + p { + margin-top: 0; +} + +.foo,.bar>.baz { + display: block; +} + +/* should works with collapsed custom selectors */ + +button:hover,button:focus,.button:hover,.button:focus {} + +.foo h1,.bar h1 { + margin-top: 16px; +} + +main .foo + p { + margin-top: 16px; +} + +.foo {} From f6747b04cce22fda413d14213f376641eebb4d42 Mon Sep 17 00:00:00 2001 From: Jonathan Neal Date: Fri, 21 Sep 2018 11:37:46 -0400 Subject: [PATCH 724/795] 8.0.5 --- .tape.js | 35 +++++++++++++++++++++++++++++------ CHANGELOG.md | 4 ++++ lib/import-from.js | 10 +++++----- package.json | 4 ++-- test/import-properties-2.css | 4 ++++ test/import-properties-2.js | 6 ++++++ test/import-properties.css | 2 -- test/import-properties.js | 2 -- 8 files changed, 50 insertions(+), 17 deletions(-) create mode 100644 test/import-properties-2.css create mode 100644 test/import-properties-2.js diff --git a/.tape.js b/.tape.js index d97e0101dd..1e7e7dc0b5 100644 --- a/.tape.js +++ b/.tape.js @@ -64,17 +64,34 @@ module.exports = { result: 'basic.import.result.css' }, 'basic:import-js': { - message: 'supports { importFrom: "test/import-properties.js" } usage', + message: 'supports { importFrom: "test/import-properties{-2}?.js" } usage', options: { - importFrom: 'test/import-properties.js' + importFrom: [ + 'test/import-properties.js', + 'test/import-properties-2.js' + ] }, expect: 'basic.import.expect.css', result: 'basic.import.result.css' }, 'basic:import-css': { - message: 'supports { importFrom: "test/import-properties.css" } usage', + message: 'supports { importFrom: "test/import-properties{-2}?.css" } usage', options: { - importFrom: 'test/import-properties.css' + importFrom: [ + 'test/import-properties.css', + 'test/import-properties-2.css' + ] + }, + expect: 'basic.import.expect.css', + result: 'basic.import.result.css' + }, + 'basic:import-css-js': { + message: 'supports { importFrom: "test/import-properties{-2}?.{css|js}" } usage', + options: { + importFrom: [ + 'test/import-properties.js', + 'test/import-properties-2.css' + ] }, expect: 'basic.import.expect.css', result: 'basic.import.result.css' @@ -82,7 +99,10 @@ module.exports = { 'basic:import-css-from': { message: 'supports { importFrom: { from: "test/import-properties.css" } } usage', options: { - importFrom: { from: 'test/import-properties.css' } + importFrom: [ + { from: 'test/import-properties.css' }, + { from: 'test/import-properties-2.css' } + ] }, expect: 'basic.import.expect.css', result: 'basic.import.result.css' @@ -90,7 +110,10 @@ module.exports = { 'basic:import-css-from-type': { message: 'supports { importFrom: [ { from: "test/import-properties.css", type: "css" } ] } usage', options: { - importFrom: [ { from: 'test/import-properties.css', type: 'css' } ] + importFrom: [ + { from: 'test/import-properties.css', type: 'css' }, + { from: 'test/import-properties-2.css', type: 'css' } + ] }, expect: 'basic.import.expect.css', result: 'basic.import.result.css' diff --git a/CHANGELOG.md b/CHANGELOG.md index 066f19d6ff..65182c0811 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # Changes to PostCSS Custom Properties +### 8.0.5 (September 21, 2018) + +- Fixed: Issue with multiple `importFrom` not getting combined + ### 8.0.4 (September 18, 2018) - Fixed: Do not break on an empty `importFrom` object diff --git a/lib/import-from.js b/lib/import-from.js index 7e899146ad..e6ad80c4c9 100644 --- a/lib/import-from.js +++ b/lib/import-from.js @@ -85,22 +85,22 @@ export default function importCustomPropertiesFromSources(sources) { const { type, from } = await source; if (type === 'ast') { - return Object.assign(customProperties, importCustomPropertiesFromCSSAST(from)); + return Object.assign(await customProperties, importCustomPropertiesFromCSSAST(from)); } if (type === 'css') { - return Object.assign(customProperties, await importCustomPropertiesFromCSSFile(from)); + return Object.assign(await customProperties, await importCustomPropertiesFromCSSFile(from)); } if (type === 'js') { - return Object.assign(customProperties, await importCustomPropertiesFromJSFile(from)); + return Object.assign(await customProperties, await importCustomPropertiesFromJSFile(from)); } if (type === 'json') { - return Object.assign(customProperties, await importCustomPropertiesFromJSONFile(from)); + return Object.assign(await customProperties, await importCustomPropertiesFromJSONFile(from)); } - return Object.assign(customProperties, importCustomPropertiesFromObject(await source)); + return Object.assign(await customProperties, await importCustomPropertiesFromObject(await source)); }, {}); } diff --git a/package.json b/package.json index 882d3aa626..285387936e 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "postcss-custom-properties", - "version": "8.0.4", + "version": "8.0.5", "description": "Use Custom Properties Queries in CSS", "author": "Jonathan Neal ", "contributors": [ @@ -41,7 +41,7 @@ "eslint-config-dev": "^2.0.0", "postcss-tape": "^2.2.0", "pre-commit": "^1.2.2", - "rollup": "^0.66.1", + "rollup": "^0.66.2", "rollup-plugin-babel": "^4.0.3" }, "eslintConfig": { diff --git a/test/import-properties-2.css b/test/import-properties-2.css new file mode 100644 index 0000000000..3f814966ad --- /dev/null +++ b/test/import-properties-2.css @@ -0,0 +1,4 @@ +:root { + --color: rgb(255, 0, 0); + --color-2: yellow; +} diff --git a/test/import-properties-2.js b/test/import-properties-2.js new file mode 100644 index 0000000000..d260227b2c --- /dev/null +++ b/test/import-properties-2.js @@ -0,0 +1,6 @@ +module.exports = { + customProperties: { + '--color': 'rgb(255, 0, 0)', + '--color-2': 'yellow' + } +}; diff --git a/test/import-properties.css b/test/import-properties.css index 7a2b7ec16a..24b0dd98ac 100644 --- a/test/import-properties.css +++ b/test/import-properties.css @@ -1,5 +1,3 @@ :root { - --color: rgb(255, 0, 0); - --color-2: yellow; --ref-color: var(--color); } diff --git a/test/import-properties.js b/test/import-properties.js index 60e653c5f0..a6ea3b20e5 100644 --- a/test/import-properties.js +++ b/test/import-properties.js @@ -1,7 +1,5 @@ module.exports = { customProperties: { - '--color': 'rgb(255, 0, 0)', - '--color-2': 'yellow', '--ref-color': 'var(--color)' } }; From a6499dfdd4422dc3b9b15a0078d7264d1d7430a9 Mon Sep 17 00:00:00 2001 From: Jonathan Neal Date: Sun, 23 Sep 2018 08:36:00 -0400 Subject: [PATCH 725/795] 3.0.2 --- .tape.js | 20 ++++-- CHANGELOG.md | 4 ++ index.js | 16 ++++- lib/get-custom-properties.js | 57 +++++++++++++++ lib/import-from.js | 115 ++++++++++++++++++++++++++++++ lib/import.js | 131 ----------------------------------- lib/transform.js | 12 ++-- package.json | 10 ++- 8 files changed, 215 insertions(+), 150 deletions(-) create mode 100644 lib/get-custom-properties.js create mode 100644 lib/import-from.js delete mode 100644 lib/import.js diff --git a/.tape.js b/.tape.js index 5c34e31777..011fdb4449 100644 --- a/.tape.js +++ b/.tape.js @@ -46,7 +46,7 @@ module.exports = { 'import:array-array': { message: 'supports { importFrom: [["css", "test/import-root.css" ]] } usage', options: { - importFrom: [['css', 'test/import-root.css' ]] + importFrom: { from: 'test/import-root.css', type: 'css' } }, expect: 'import.expect.css', result: 'import.result.css' @@ -70,13 +70,19 @@ module.exports = { 'import:object': { message: 'supports { importFrom: { customProperties: {} } } usage', options: { - importFrom: { - customProperties: { - '--color-blue': 'blue', - '--color-red': 'red', - '--color': 'var(--color-blue)' + importFrom: [ + { + customProperties: { + '--color': 'var(--color-blue)' + } + }, + { + customProperties: { + '--color-blue': 'blue', + '--color-red': 'red' + } } - } + ] }, expect: 'import.expect.css', result: 'import.result.css' diff --git a/CHANGELOG.md b/CHANGELOG.md index f03bb5e66d..1070eac8f6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # Changes to PostCSS color-mod() Function +### 3.0.2 (September 23, 2018) + +- Fixed an incompatibility with other `importFrom` plugins + ### 3.0.1 (September 18, 2018) - Fixed an issue with using the `transparent` color keyword diff --git a/index.js b/index.js index 15e80ecadb..a42d053fc5 100644 --- a/index.js +++ b/index.js @@ -1,18 +1,30 @@ -import { importCustomPropertiesFromSources, importCustomPropertiesFromCSSAST } from './lib/import'; +import getCustomProperties from './lib/get-custom-properties'; +import importCustomPropertiesFromSources from './lib/import-from'; import parser from 'postcss-values-parser'; import postcss from 'postcss'; import transformAST from './lib/transform'; export default postcss.plugin('postcss-color-mod-function', opts => { + // how unresolved functions and arguments should be handled (default: "throw") const unresolvedOpt = String(Object(opts).unresolved || 'throw').toLowerCase(); + + // how transformed colors will be produced in CSS const stringifierOpt = Object(opts).stringifier || (color => color.toLegacy()); + + // sources to import custom selectors from const importFrom = [].concat(Object(opts).importFrom || []); + + // whether var() within color-mod() should use Custom Properties or var() fallback const transformVarsOpt = 'transformVars' in Object(opts) ? opts.transformVars : true; + // promise any custom selectors are imported const customPropertiesPromise = importCustomPropertiesFromSources(importFrom); return async (root, result) => { - const customProperties = Object.assign(await customPropertiesPromise, await importCustomPropertiesFromCSSAST(root)); + const customProperties = Object.assign( + await customPropertiesPromise, + getCustomProperties(root, { preserve: true }) + ); root.walkDecls(decl => { const originalValue = decl.value; diff --git a/lib/get-custom-properties.js b/lib/get-custom-properties.js new file mode 100644 index 0000000000..62b25cc299 --- /dev/null +++ b/lib/get-custom-properties.js @@ -0,0 +1,57 @@ +import valueParser from 'postcss-values-parser'; + +// return custom selectors from the css root, conditionally removing them +export default function getCustomProperties(root, opts) { + // initialize custom selectors + const customPropertiesFromHtmlElement = {}; + const customPropertiesFromRootPsuedo = {}; + + // for each html or :root rule + root.nodes.slice().forEach(rule => { + const customPropertiesObject = isHtmlRule(rule) + ? customPropertiesFromHtmlElement + : isRootRule(rule) + ? customPropertiesFromRootPsuedo + : null; + + // for each custom property + if (customPropertiesObject) { + rule.nodes.slice().forEach(decl => { + if (isCustomDecl(decl)) { + const { prop } = decl; + + // write the parsed value to the custom property + customPropertiesObject[prop] = valueParser(decl.value).parse(); + + // conditionally remove the custom property declaration + if (!opts.preserve) { + decl.remove(); + } + } + }); + + // conditionally remove the empty html or :root rule + if (!opts.preserve && isEmptyParent(rule)) { + rule.remove(); + } + } + }); + + // return all custom properties, preferring :root properties over html properties + return { ...customPropertiesFromHtmlElement, ...customPropertiesFromRootPsuedo }; +} + +// match html and :root rules +const htmlSelectorRegExp = /^html$/i; +const rootSelectorRegExp = /^:root$/i; +const customPropertyRegExp = /^--[A-z][\w-]*$/; + +// whether the node is an html or :root rule +const isHtmlRule = node => node.type === 'rule' && htmlSelectorRegExp.test(node.selector) && Object(node.nodes).length; +const isRootRule = node => node.type === 'rule' && rootSelectorRegExp.test(node.selector) && Object(node.nodes).length; + +// whether the node is an custom property +const isCustomDecl = node => node.type === 'decl' && customPropertyRegExp.test(node.prop); + +// whether the node is a parent without children +const isEmptyParent = node => Object(node.nodes).length === 0; diff --git a/lib/import-from.js b/lib/import-from.js new file mode 100644 index 0000000000..95a7488872 --- /dev/null +++ b/lib/import-from.js @@ -0,0 +1,115 @@ +import fs from 'fs'; +import path from 'path'; +import postcss from 'postcss'; +import getCustomProperties from './get-custom-properties'; + +/* Import Custom Properties from CSS AST +/* ========================================================================== */ + +function importCustomPropertiesFromCSSAST(root) { + return getCustomProperties(root, { preserve: true }); +} + +/* Import Custom Properties from CSS File +/* ========================================================================== */ + +async function importCustomPropertiesFromCSSFile(from) { + const css = await readFile(path.resolve(from)); + const root = postcss.parse(css, { from: path.resolve(from) }); + + return importCustomPropertiesFromCSSAST(root); +} + +/* Import Custom Properties from Object +/* ========================================================================== */ + +function importCustomPropertiesFromObject(object) { + const customProperties = Object.assign( + {}, + Object(object).customProperties || Object(object)['custom-properties'] + ); + + return customProperties; +} + +/* Import Custom Properties from JSON file +/* ========================================================================== */ + +async function importCustomPropertiesFromJSONFile(from) { + const object = await readJSON(path.resolve(from)); + + return importCustomPropertiesFromObject(object); +} + +/* Import Custom Properties from JS file +/* ========================================================================== */ + +async function importCustomPropertiesFromJSFile(from) { + const object = await import(path.resolve(from)); + + return importCustomPropertiesFromObject(object); +} + +/* Import Custom Properties from Sources +/* ========================================================================== */ + +export default function importCustomPropertiesFromSources(sources) { + return sources.map(source => { + if (source instanceof Promise) { + return source; + } else if (source instanceof Function) { + return source(); + } + + // read the source as an object + const opts = source === Object(source) ? source : { from: String(source) }; + + // skip objects with Custom Properties + if (opts.customProperties || opts['custom-properties']) { + return opts + } + + // source pathname + const from = String(opts.from || ''); + + // type of file being read from + const type = (opts.type || path.extname(from).slice(1)).toLowerCase(); + + return { type, from }; + }).reduce(async (customProperties, source) => { + const { type, from } = await source; + + if (type === 'ast') { + return Object.assign(await customProperties, importCustomPropertiesFromCSSAST(from)); + } + + if (type === 'css') { + return Object.assign(await customProperties, await importCustomPropertiesFromCSSFile(from)); + } + + if (type === 'js') { + return Object.assign(await customProperties, await importCustomPropertiesFromJSFile(from)); + } + + if (type === 'json') { + return Object.assign(await customProperties, await importCustomPropertiesFromJSONFile(from)); + } + + return Object.assign(await customProperties, await importCustomPropertiesFromObject(await source)); + }, {}); +} + +/* Helper utilities +/* ========================================================================== */ + +const readFile = from => new Promise((resolve, reject) => { + fs.readFile(from, 'utf8', (error, result) => { + if (error) { + reject(error); + } else { + resolve(result); + } + }); +}); + +const readJSON = async from => JSON.parse(await readFile(from)); diff --git a/lib/import.js b/lib/import.js deleted file mode 100644 index 47100bd71d..0000000000 --- a/lib/import.js +++ /dev/null @@ -1,131 +0,0 @@ -import fs from 'fs'; -import path from 'path'; -import postcss from 'postcss'; - -/* Import Custom Properties from CSS AST -/* ========================================================================== */ - -export function importCustomPropertiesFromCSSAST(root) { - // custom properties can be written on html or :root - const htmlCustomProperties = {}; - const rootCustomProperties = {}; - - // for each html and :root rule - Object(root.nodes).filter(isHtmlOrRootRule).forEach(({ nodes, selector }) => { - // for each custom property - Object(nodes).filter(isCustomPropertyDecl).forEach(({ prop, value }) => { - // write to the custom properties from either html or :root - const customProperties = matchHtml.test(selector) ? htmlCustomProperties : rootCustomProperties; - - customProperties[prop] = value; - }); - }); - - // return all html and :root custom properties, where :root prevails - return Object.assign({}, htmlCustomProperties, rootCustomProperties); -} - -/* Import Custom Properties from CSS File -/* ========================================================================== */ - -async function importCustomPropertiesFromCSSFile(from) { - const css = await readFile(path.resolve(from)); - const root = postcss.parse(css, { from: path.resolve(from) }); - - return importCustomPropertiesFromCSSAST(root); -} - -/* Import Custom Properties from Object -/* ========================================================================== */ - -function importCustomPropertiesFromObject(object) { - const customProperties = Object.assign({}, Object(object).customProperties || Object(object)['custom-properties']); - - return customProperties; -} - -/* Import Custom Properties from JSON file -/* ========================================================================== */ - -async function importCustomPropertiesFromJSONFile(from) { - const object = await readJSON(path.resolve(from)); - - return importCustomPropertiesFromObject(object); -} - -/* Import Custom Properties from JS file -/* ========================================================================== */ - -async function importCustomPropertiesFromJSFile(from) { - const object = await import(path.resolve(from)); - - return importCustomPropertiesFromObject(object); -} - -/* Import Custom Properties from Sources -/* ========================================================================== */ - -export function importCustomPropertiesFromSources(sources) { - return sources.map(source => { - if (typeof source === 'string') { - if (isCSSPath(source)) { - return [ 'css', source ] - } else if (isJSPath(source)) { - return [ 'js', source ] - } else if (isJSONPath(source)) { - return [ 'json', source ] - } - } - - return Object(source); - }).reduce(async (customProperties, source) => { - const type = source[0]; - const from = source[1]; - - if (type === 'ast') { - return Object.assign(customProperties, importCustomPropertiesFromCSSAST(from)); - } - - if (type === 'css') { - return Object.assign(customProperties, await importCustomPropertiesFromCSSFile(from)); - } - - if (type === 'js') { - return Object.assign(customProperties, await importCustomPropertiesFromJSFile(from)); - } - - if (type === 'json') { - return Object.assign(customProperties, await importCustomPropertiesFromJSONFile(from)); - } - - return Object.assign(customProperties, importCustomPropertiesFromObject(source)); - }, {}); -} - -/* Helper utilities -/* ========================================================================== */ - -const matchCustomProperty = /^--\w/; -const matchHtml = /^html$/i; -const matchHtmlOrRoot = /^(html|:root)$/i; -const matchCSSPath = /\.\w*css/i; -const matchJSPath = /\.\w*js/i; -const matchJSONPath = /\.\w*json/i; - -const isCustomPropertyDecl = node => Object(node).type === 'decl' && matchCustomProperty.test(node.prop); -const isHtmlOrRootRule = node => Object(node).type === 'rule' && matchHtmlOrRoot.test(node.selector); -const isCSSPath = from => matchCSSPath.test(from); -const isJSPath = from => matchJSPath.test(from); -const isJSONPath = from => matchJSONPath.test(from); - -const readFile = from => new Promise((resolve, reject) => { - fs.readFile(from, 'utf8', (error, result) => { - if (error) { - reject(error); - } else { - resolve(result); - } - }); -}); - -const readJSON = async from => JSON.parse(await readFile(from)); diff --git a/lib/transform.js b/lib/transform.js index 4baa72c633..8d1c4da66c 100644 --- a/lib/transform.js +++ b/lib/transform.js @@ -43,19 +43,23 @@ function transformVariables(node, opts) { ]); if (variableName in opts.customProperties) { - let customPropertyValue = String(opts.customProperties[variableName]); + let customPropertyValue = opts.customProperties[variableName]; if (looseVarMatch.test(customPropertyValue)) { - const rootChildAST = parser(customPropertyValue, { loose: true }).parse(); + if (typeof customPropertyValue === 'string') { + customPropertyValue = parser(customPropertyValue).parse(); + } + + const rootChildAST = customPropertyValue.clone(); transformVariables(rootChildAST, opts); - customPropertyValue = opts.customProperties[variableName] = String(rootChildAST); + customPropertyValue = opts.customProperties[variableName] = rootChildAST; } child.replaceWith(parser.word({ raws: child.raws, - value: customPropertyValue + value: String(customPropertyValue) })); } else if (fallbackNode) { transformVariables(fallbackNode, opts); diff --git a/package.json b/package.json index f63e25ba75..97aa8dcecb 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "postcss-color-mod-function", - "version": "3.0.1", + "version": "3.0.2", "description": "Modify colors using the color-mod() function in CSS", "author": "Jonathan Neal ", "license": "CC0-1.0", @@ -18,13 +18,12 @@ "scripts": { "prepublishOnly": "npm test", "pretest": "rollup -c .rollup.js --silent", - "test": "echo 'Running tests...'; npm run test:ec && npm run test:js && npm run test:tape", - "test:ec": "echint --ignore index.bundle.js test", + "test": "echo 'Running tests...'; npm run test:js && npm run test:tape", "test:js": "eslint *.js lib/*.js --cache --ignore-path .gitignore --quiet", "test:tape": "postcss-tape" }, "engines": { - "node": ">=4.0.0" + "node": ">=6.0.0" }, "dependencies": { "@csstools/convert-colors": "^1.4.0", @@ -36,12 +35,11 @@ "@babel/plugin-syntax-dynamic-import": "^7.0.0", "@babel/preset-env": "^7.1.0", "babel-eslint": "^9.0.0", - "echint": "^4.0.1", "eslint": "^5.6.0", "eslint-config-dev": "^2.0.0", "postcss-tape": "^2.2.0", "pre-commit": "^1.2.2", - "rollup": "^0.66.0", + "rollup": "^0.66.2", "rollup-plugin-babel": "^4.0.3" }, "eslintConfig": { From 9ff8cac91d105ed370d8fe62e5e8a0c3b4a3003c Mon Sep 17 00:00:00 2001 From: Jonathan Neal Date: Sun, 23 Sep 2018 14:56:15 -0400 Subject: [PATCH 726/795] 3.0.3 --- CHANGELOG.md | 4 ++++ lib/import-from.js | 15 ++++++++++----- lib/transform.js | 32 ++++++++++++++++++-------------- package.json | 2 +- 4 files changed, 33 insertions(+), 20 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1070eac8f6..c08919589d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # Changes to PostCSS color-mod() Function +### 3.0.3 (September 23, 2018) + +- Fixed an issue with certain colors not being tranformed from variables + ### 3.0.2 (September 23, 2018) - Fixed an incompatibility with other `importFrom` plugins diff --git a/lib/import-from.js b/lib/import-from.js index 95a7488872..c80bc489e5 100644 --- a/lib/import-from.js +++ b/lib/import-from.js @@ -2,6 +2,7 @@ import fs from 'fs'; import path from 'path'; import postcss from 'postcss'; import getCustomProperties from './get-custom-properties'; +import valueParser from 'postcss-values-parser'; /* Import Custom Properties from CSS AST /* ========================================================================== */ @@ -14,8 +15,8 @@ function importCustomPropertiesFromCSSAST(root) { /* ========================================================================== */ async function importCustomPropertiesFromCSSFile(from) { - const css = await readFile(path.resolve(from)); - const root = postcss.parse(css, { from: path.resolve(from) }); + const css = await readFile(from); + const root = postcss.parse(css, { from }); return importCustomPropertiesFromCSSAST(root); } @@ -29,6 +30,10 @@ function importCustomPropertiesFromObject(object) { Object(object).customProperties || Object(object)['custom-properties'] ); + for (const prop in customProperties) { + customProperties[prop] = valueParser(customProperties[prop]).parse(); + } + return customProperties; } @@ -36,7 +41,7 @@ function importCustomPropertiesFromObject(object) { /* ========================================================================== */ async function importCustomPropertiesFromJSONFile(from) { - const object = await readJSON(path.resolve(from)); + const object = await readJSON(from); return importCustomPropertiesFromObject(object); } @@ -45,7 +50,7 @@ async function importCustomPropertiesFromJSONFile(from) { /* ========================================================================== */ async function importCustomPropertiesFromJSFile(from) { - const object = await import(path.resolve(from)); + const object = await import(from); return importCustomPropertiesFromObject(object); } @@ -70,7 +75,7 @@ export default function importCustomPropertiesFromSources(sources) { } // source pathname - const from = String(opts.from || ''); + const from = path.resolve(String(opts.from || '')); // type of file being read from const type = (opts.type || path.extname(from).slice(1)).toLowerCase(); diff --git a/lib/transform.js b/lib/transform.js index 8d1c4da66c..d8c3369586 100644 --- a/lib/transform.js +++ b/lib/transform.js @@ -37,34 +37,38 @@ export default function transformAST(node, opts) { function transformVariables(node, opts) { walk(node, child => { if (isVariable(child)) { - const [variableName, fallbackNode] = transformArgsByParams(child, [ + // get the custom property and fallback value from var() + const [prop, fallbackNode] = transformArgsByParams(child, [ // , [ ]? [transformWord, isComma, transformNode] ]); - if (variableName in opts.customProperties) { - let customPropertyValue = opts.customProperties[variableName]; + // if the custom property is known + if (prop in opts.customProperties) { + let customPropertyValue = opts.customProperties[prop]; + // follow custom properties referencing custom properties if (looseVarMatch.test(customPropertyValue)) { - if (typeof customPropertyValue === 'string') { - customPropertyValue = parser(customPropertyValue).parse(); - } - const rootChildAST = customPropertyValue.clone(); transformVariables(rootChildAST, opts); - customPropertyValue = opts.customProperties[variableName] = rootChildAST; + customPropertyValue = rootChildAST; } - child.replaceWith(parser.word({ - raws: child.raws, - value: String(customPropertyValue) - })); - } else if (fallbackNode) { + // replace var() with the custom property value + if (customPropertyValue.nodes.length === 1 && customPropertyValue.nodes[0].nodes.length) { + customPropertyValue.nodes[0].nodes.forEach(customPropertyChild => { + child.parent.insertBefore(child, customPropertyChild); + }); + } + + child.remove(); + } else if (fallbackNode && fallbackNode.nodes.length === 1 && fallbackNode.nodes[0].nodes.length) { + // otherwise, replace var() with the fallback value transformVariables(fallbackNode, opts); - child.replaceWith(...fallbackNode.nodes[0].nodes); + child.replaceWith(...fallbackNode.nodes[0].nodes[0]); } } }); diff --git a/package.json b/package.json index 97aa8dcecb..eceb158cd7 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "postcss-color-mod-function", - "version": "3.0.2", + "version": "3.0.3", "description": "Modify colors using the color-mod() function in CSS", "author": "Jonathan Neal ", "license": "CC0-1.0", From 75c2768ad997711e5020b2b296dea1398c8ce36a Mon Sep 17 00:00:00 2001 From: Jonathan Neal Date: Sun, 23 Sep 2018 23:47:32 -0400 Subject: [PATCH 727/795] 7.0.4 --- CHANGELOG.md | 4 ++++ lib/export-to.js | 2 +- lib/media-ast-from-string.js | 2 +- lib/transform-media-list.js | 11 ++++++++++- package.json | 4 ++-- test/basic.css | 7 +++++++ test/basic.expect.css | 6 ++++++ test/basic.preserve.expect.css | 13 +++++++++++++ test/export-media.css | 1 + test/export-media.js | 1 + test/export-media.json | 1 + test/export-media.mjs | 1 + test/import.plugin.expect.css | 29 +++++++++++++++++++++++++++++ 13 files changed, 77 insertions(+), 5 deletions(-) create mode 100644 test/import.plugin.expect.css diff --git a/CHANGELOG.md b/CHANGELOG.md index 6a895859ca..f3a83ce2a7 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # Changes to PostCSS Custom Media +### 7.0.4 (September 23, 2018) + +- Added: `importFromPlugins` option to process imports + ### 7.0.3 (September 20, 2018) - Fixed: Do not break on an empty `importFrom` object diff --git a/lib/export-to.js b/lib/export-to.js index 0059757db3..e92518df22 100644 --- a/lib/export-to.js +++ b/lib/export-to.js @@ -80,7 +80,7 @@ export default function exportCustomMediaToDestinations(customMedia, destination const to = String(opts.to || ''); // type of file being written to - const type = (opts.type || path.extname(opts.to).slice(1)).toLowerCase(); + const type = (opts.type || path.extname(to).slice(1)).toLowerCase(); // transformed custom media const customMediaJSON = toJSON(customMedia); diff --git a/lib/media-ast-from-string.js b/lib/media-ast-from-string.js index 38e3b6384d..d055849765 100644 --- a/lib/media-ast-from-string.js +++ b/lib/media-ast-from-string.js @@ -65,7 +65,7 @@ class MediaQuery { constructor(string) { const [, before, media, after ] = string.match(spaceWrapRegExp); const [, modifier = '', afterModifier = ' ', type = '', beforeAnd = '', and = '', beforeExpression = '', expression1 = '', expression2 = ''] = media.match(mediaRegExp) || []; - const raws = { before, after, afterModifier, originalModifier: modifier || 'not', beforeAnd, and, beforeExpression }; + const raws = { before, after, afterModifier, originalModifier: modifier || '', beforeAnd, and, beforeExpression }; const nodes = parse(expression1 || expression2, true); Object.assign(this, { diff --git a/lib/transform-media-list.js b/lib/transform-media-list.js index 5a3d59841d..33c0ec78ac 100644 --- a/lib/transform-media-list.js +++ b/lib/transform-media-list.js @@ -35,9 +35,18 @@ function transformMedia(media, customMedias) { raws: !modifier || media.modifier ? { ...media.raws } : { ...replacementMedia.raws }, - type: media.type || replacementMedia.type + type: media.type || replacementMedia.type, }); + // conditionally include more replacement raws when the type is present + if (mediaClone.type === replacementMedia.type) { + Object.assign(mediaClone.raws, { + and: replacementMedia.raws.and, + beforeAnd: replacementMedia.raws.beforeAnd, + beforeExpression: replacementMedia.raws.beforeExpression + }); + } + mediaClone.nodes.splice(index, 1, ...replacementMedia.clone().nodes.map(node => { // use spacing from the current usage node.spaces = { ...media.nodes[index].spaces }; diff --git a/package.json b/package.json index a7479bc0e2..2a36668dff 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "postcss-custom-media", - "version": "7.0.3", + "version": "7.0.4", "description": "Use Custom Media Queries in CSS", "author": "Jonathan Neal ", "contributors": [ @@ -38,7 +38,7 @@ "eslint-config-dev": "^2.0.0", "postcss-tape": "^2.2.0", "pre-commit": "^1.2.2", - "rollup": "^0.66.1", + "rollup": "^0.66.2", "rollup-plugin-babel": "^4.0.3" }, "eslintConfig": { diff --git a/test/basic.css b/test/basic.css index 360bb9e46d..ee34098d63 100644 --- a/test/basic.css +++ b/test/basic.css @@ -1,4 +1,5 @@ @custom-media --mq-a (max-width: 30em), (max-height: 30em); +@custom-media --mq-b screen and (max-width: 30em); @custom-media --not-mq-a not all and (--mq-a); @media (--mq-a) { @@ -7,6 +8,12 @@ } } +@media (--mq-b) { + body { + order: 1; + } +} + @media (--mq-a), (--mq-a) { body { order: 1; diff --git a/test/basic.expect.css b/test/basic.expect.css index 6d15f5e84c..c55e511eb3 100644 --- a/test/basic.expect.css +++ b/test/basic.expect.css @@ -4,6 +4,12 @@ } } +@media screen and (max-width: 30em) { + body { + order: 1; + } +} + @media (max-width: 30em),(max-height: 30em), (max-width: 30em), (max-height: 30em) { body { order: 1; diff --git a/test/basic.preserve.expect.css b/test/basic.preserve.expect.css index 3fa5361d2b..3ec9f68a79 100644 --- a/test/basic.preserve.expect.css +++ b/test/basic.preserve.expect.css @@ -1,4 +1,5 @@ @custom-media --mq-a (max-width: 30em), (max-height: 30em); +@custom-media --mq-b screen and (max-width: 30em); @custom-media --not-mq-a not all and (--mq-a); @media (max-width: 30em),(max-height: 30em) { @@ -13,6 +14,18 @@ } } +@media screen and (max-width: 30em) { + body { + order: 1; + } +} + +@media (--mq-b) { + body { + order: 1; + } +} + @media (max-width: 30em),(max-height: 30em), (max-width: 30em), (max-height: 30em) { body { order: 1; diff --git a/test/export-media.css b/test/export-media.css index fc776fcec3..0f65a294f8 100644 --- a/test/export-media.css +++ b/test/export-media.css @@ -1,4 +1,5 @@ @custom-media --mq-a (max-width: 30em), (max-height: 30em); +@custom-media --mq-b screen and (max-width: 30em); @custom-media --not-mq-a not all and (--mq-a); @custom-media --circular-mq-a (--circular-mq-b); @custom-media --circular-mq-b (--circular-mq-a); diff --git a/test/export-media.js b/test/export-media.js index 579c929893..65bc566768 100644 --- a/test/export-media.js +++ b/test/export-media.js @@ -1,6 +1,7 @@ module.exports = { customMedia: { '--mq-a': '(max-width: 30em), (max-height: 30em)', + '--mq-b': 'screen and (max-width: 30em)', '--not-mq-a': 'not all and (--mq-a)', '--circular-mq-a': '(--circular-mq-b)', '--circular-mq-b': '(--circular-mq-a)' diff --git a/test/export-media.json b/test/export-media.json index b0a258771f..250d9aeb13 100644 --- a/test/export-media.json +++ b/test/export-media.json @@ -1,6 +1,7 @@ { "custom-media": { "--mq-a": "(max-width: 30em), (max-height: 30em)", + "--mq-b": "screen and (max-width: 30em)", "--not-mq-a": "not all and (--mq-a)", "--circular-mq-a": "(--circular-mq-b)", "--circular-mq-b": "(--circular-mq-a)" diff --git a/test/export-media.mjs b/test/export-media.mjs index c1a4a72904..cad637dac7 100644 --- a/test/export-media.mjs +++ b/test/export-media.mjs @@ -1,5 +1,6 @@ export const customMedia = { '--mq-a': '(max-width: 30em), (max-height: 30em)', + '--mq-b': 'screen and (max-width: 30em)', '--not-mq-a': 'not all and (--mq-a)', '--circular-mq-a': '(--circular-mq-b)', '--circular-mq-b': '(--circular-mq-a)' diff --git a/test/import.plugin.expect.css b/test/import.plugin.expect.css new file mode 100644 index 0000000000..0bc2bbf3bf --- /dev/null +++ b/test/import.plugin.expect.css @@ -0,0 +1,29 @@ +@media (max-width: 30em),(max-height: 30em) { + body { + order: 1; + } +} + +@media (max-width: 30em),(max-height: 30em), (max-width: 30em), (max-height: 30em) { + body { + order: 1; + } +} + +@media not all and (max-width: 30em),not all and (max-height: 30em) { + body { + order: 2; + } +} + +@media not all and (max-width: 30em),not all and (max-height: 30em) { + body { + order: 1; + } +} + +@media all and (max-width: 30em),all and (max-height: 30em) { + body { + order: 2; + } +} From fdfbf0788c9c8a0dff238addd607c55207394c2f Mon Sep 17 00:00:00 2001 From: Jonathan Neal Date: Mon, 24 Sep 2018 22:45:08 -0400 Subject: [PATCH 728/795] 1.0.0 --- .editorconfig | 15 +++++ .gitignore | 11 ++++ .rollup.client.js | 16 +++++ .rollup.postcss.js | 16 +++++ .tape.js | 7 ++ .travis.yml | 9 +++ CHANGELOG.md | 5 ++ CONTRIBUTING.md | 65 ++++++++++++++++++ INSTALL.md | 150 ++++++++++++++++++++++++++++++++++++++++++ LICENSE.md | 108 ++++++++++++++++++++++++++++++ README.md | 136 ++++++++++++++++++++++++++++++++++++++ package.json | 66 +++++++++++++++++++ src/client.js | 21 ++++++ src/postcss.js | 17 +++++ test/basic.css | 26 ++++++++ test/basic.expect.css | 26 ++++++++ test/basic.result.css | 26 ++++++++ 17 files changed, 720 insertions(+) create mode 100644 .editorconfig create mode 100644 .gitignore create mode 100644 .rollup.client.js create mode 100644 .rollup.postcss.js create mode 100644 .tape.js create mode 100644 .travis.yml create mode 100644 CHANGELOG.md create mode 100644 CONTRIBUTING.md create mode 100644 INSTALL.md create mode 100644 LICENSE.md create mode 100644 README.md create mode 100644 package.json create mode 100644 src/client.js create mode 100644 src/postcss.js create mode 100644 test/basic.css create mode 100644 test/basic.expect.css create mode 100644 test/basic.result.css diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000000..40e2967e88 --- /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/.gitignore b/.gitignore new file mode 100644 index 0000000000..8435b82030 --- /dev/null +++ b/.gitignore @@ -0,0 +1,11 @@ +node_modules +/client.* +/postcss.* +package-lock.json +*.log* +.* +!.editorconfig +!.gitignore +!.rollup.*.js +!.tape.js +!.travis.yml diff --git a/.rollup.client.js b/.rollup.client.js new file mode 100644 index 0000000000..900f9b6a99 --- /dev/null +++ b/.rollup.client.js @@ -0,0 +1,16 @@ +import babel from 'rollup-plugin-babel'; + +export default { + input: 'src/client.js', + output: [ + { file: 'client.js', format: 'cjs' }, + { file: 'client.mjs', format: 'es' } + ], + plugins: [ + babel({ + presets: [ + ['@babel/env', { modules: false, targets: { node: 6 } }] + ] + }) + ] +}; diff --git a/.rollup.postcss.js b/.rollup.postcss.js new file mode 100644 index 0000000000..1b8d1a3d4b --- /dev/null +++ b/.rollup.postcss.js @@ -0,0 +1,16 @@ +import babel from 'rollup-plugin-babel'; + +export default { + input: 'src/postcss.js', + output: [ + { file: 'postcss.js', format: 'cjs' }, + { file: 'postcss.mjs', format: 'es' } + ], + plugins: [ + babel({ + presets: [ + ['@babel/env', { modules: false, targets: { node: 6 } }] + ] + }) + ] +}; diff --git a/.tape.js b/.tape.js new file mode 100644 index 0000000000..a100e08e83 --- /dev/null +++ b/.tape.js @@ -0,0 +1,7 @@ +module.exports = { + 'postcss-prefers-color-scheme': { + 'basic': { + message: 'supports basic usage' + } + } +}; diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000000..e1f11a52e6 --- /dev/null +++ b/.travis.yml @@ -0,0 +1,9 @@ +# https://docs.travis-ci.com/user/travis-lint + +language: node_js + +node_js: + - 6 + +install: + - npm install --ignore-scripts diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000000..7758189106 --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,5 @@ +# Changes to Prefers Color Scheme + +### 1.0.0 (September 24, 2018) + +- Initial version diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 0000000000..6951d3fd56 --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,65 @@ +# Contributing to Prefers Color Scheme + +You want to help? You rock! Now, take a moment to be sure your contributions +make sense to everyone else. + +## Reporting Issues + +Found a problem? Want a new feature? + +- See if your issue or idea has [already been reported]. +- Provide a [reduced test case] or a [live example]. + +Remember, a bug is a _demonstrable problem_ caused by _our_ code. + +## Submitting Pull Requests + +Pull requests are the greatest contributions, so be sure they are focused in +scope and avoid unrelated commits. + +1. To begin; [fork this project], clone your fork, and add our upstream. + ```bash + # Clone your fork of the repo into the current directory + git clone git@github.com:YOUR_USER/css-prefers-color-scheme.git + + # Navigate to the newly cloned directory + cd css-prefers-color-scheme + + # Assign the original repo to a remote called "upstream" + git remote add upstream git@github.com:csstools/css-prefers-color-scheme.git + + # Install the tools necessary for testing + npm install + ``` + +2. Create a branch for your feature or fix: + ```bash + # Move into a new branch for your feature + git checkout -b feature/thing + ``` + ```bash + # Move into a new branch for your fix + git checkout -b fix/something + ``` + +3. If your code follows our practices, then push your feature branch: + ```bash + # Test current code + npm test + ``` + ```bash + # Push the branch for your new feature + git push origin feature/thing + ``` + ```bash + # Or, push the branch for your update + git push origin update/something + ``` + +That’s it! Now [open a pull request] with a clear title and description. + +[already been reported]: https://github.com/csstools/css-prefers-color-scheme/issues +[fork this project]: https://github.com/csstools/css-prefers-color-scheme/fork +[live example]: https://codepen.io/pen +[open a pull request]: https://help.github.com/articles/using-pull-requests/ +[reduced test case]: https://css-tricks.com/reduced-test-cases/ diff --git a/INSTALL.md b/INSTALL.md new file mode 100644 index 0000000000..9620bbbf4b --- /dev/null +++ b/INSTALL.md @@ -0,0 +1,150 @@ +# Installing Prefers Color Scheme + +[Prefers Color Scheme] runs in all Node environments, with special +instructions for: + +| [Node](#node) | [Webpack](#webpack) | [Create React App](#create-react-app) | [Gulp](#gulp) | [Grunt](#grunt) | +| --- | --- | --- | --- | --- | + +## Node + +Add [Prefers Color Scheme] to your project: + +```bash +npm install css-prefers-color-scheme --save-dev +``` + +Use [Prefers Color Scheme] to process your CSS: + +```js +const postcssPrefers = require('css-prefers-color-scheme/postcss'); + +prefersColorScheme.process(YOUR_CSS /*, processOptions, pluginOptions */); +``` + +Or use it as a [PostCSS] plugin: + +```js +const postcss = require('postcss'); +const postcssPrefers = require('css-prefers-color-scheme/postcss'); + +postcss([ + prefersColorScheme(/* pluginOptions */) +]).process(YOUR_CSS /*, processOptions */); +``` + +## Webpack + +Add [PostCSS Loader] to your project: + +```bash +npm install postcss-loader --save-dev +``` + +Use [Prefers Color Scheme] in your Webpack configuration: + +```js +const postcssPrefers = require('css-prefers-color-scheme/postcss'); + +module.exports = { + module: { + rules: [ + { + test: /\.css$/, + use: [ + 'style-loader', + { loader: 'css-loader', options: { importLoaders: 1 } }, + { loader: 'postcss-loader', options: { + ident: 'postcss', + plugins: () => [ + prefersColorScheme(/* pluginOptions */) + ] + } } + ] + } + ] + } +} +``` + +## Create React App + +Add [React App Rewired] and [React App Rewire PostCSS] to your project: + +```bash +npm install react-app-rewired react-app-rewire-postcss --save-dev +``` + +Use [React App Rewire PostCSS] and [Prefers Color Scheme] in your +`config-overrides.js` file: + +```js +const reactAppRewirePostcss = require('react-app-rewire-postcss'); +const postcssPrefers = require('css-prefers-color-scheme/postcss'); + +export default config => reactAppRewirePostcss(config, { + plugins: () => [ + prefersColorScheme(/* pluginOptions */) + ] +}); +``` + +## Gulp + +Add [Gulp PostCSS] to your project: + +```bash +npm install gulp-postcss --save-dev +``` + +Use [Prefers Color Scheme] in your Gulpfile: + +```js +const postcss = require('gulp-postcss'); +const postcssPrefers = require('css-prefers-color-scheme/postcss'); + +gulp.task('css', () => gulp.src('./src/*.css').pipe( + postcss([ + prefersColorScheme(/* pluginOptions */) + ]) +).pipe( + gulp.dest('.') +)); +``` + +## Grunt + +Add [Grunt PostCSS] to your project: + +```bash +npm install grunt-postcss --save-dev +``` + +Use [Prefers Color Scheme] in your Gruntfile: + +```js +const postcssPrefers = require('css-prefers-color-scheme/postcss'); + +grunt.loadNpmTasks('grunt-postcss'); + +grunt.initConfig({ + postcss: { + options: { + use: [ + prefersColorScheme(/* pluginOptions */) + ] + }, + dist: { + src: '*.css' + } + } +}); +``` + +[Gulp PostCSS]: https://github.com/postcss/gulp-postcss +[Grunt PostCSS]: https://github.com/nDmitry/grunt-postcss +[PostCSS]: https://github.com/postcss/postcss +[PostCSS Loader]: https://github.com/postcss/postcss-loader +[Prefers Color Scheme]: https://github.com/jonathantneal/postcss-prefers-color-scheme +[React App Rewire PostCSS]: https://github.com/csstools/react-app-rewire-postcss +[React App Rewired]: https://github.com/timarney/react-app-rewired diff --git a/LICENSE.md b/LICENSE.md new file mode 100644 index 0000000000..0bc1fa7060 --- /dev/null +++ b/LICENSE.md @@ -0,0 +1,108 @@ +# CC0 1.0 Universal + +## Statement of Purpose + +The laws of most jurisdictions throughout the world automatically confer +exclusive Copyright and Related Rights (defined below) upon the creator and +subsequent owner(s) (each and all, an “owner”) of an original work of +authorship and/or a database (each, a “Work”). + +Certain owners wish to permanently relinquish those rights to a Work for the +purpose of contributing to a commons of creative, cultural and scientific works +(“Commons”) that the public can reliably and without fear of later claims of +infringement build upon, modify, incorporate in other works, reuse and +redistribute as freely as possible in any form whatsoever and for any purposes, +including without limitation commercial purposes. These owners may contribute +to the Commons to promote the ideal of a free culture and the further +production of creative, cultural and scientific works, or to gain reputation or +greater distribution for their Work in part through the use and efforts of +others. + +For these and/or other purposes and motivations, and without any expectation of +additional consideration or compensation, the person associating CC0 with a +Work (the “Affirmer”), to the extent that he or she is an owner of Copyright +and Related Rights in the Work, voluntarily elects to apply CC0 to the Work and +publicly distribute the Work under its terms, with knowledge of his or her +Copyright and Related Rights in the Work and the meaning and intended legal +effect of CC0 on those rights. + +1. Copyright and Related Rights. A Work made available under CC0 may be + protected by copyright and related or neighboring rights (“Copyright and + Related Rights”). Copyright and Related Rights include, but are not limited + to, the following: + 1. the right to reproduce, adapt, distribute, perform, display, communicate, + and translate a Work; + 2. moral rights retained by the original author(s) and/or performer(s); + 3. publicity and privacy rights pertaining to a person’s image or likeness + depicted in a Work; + 4. rights protecting against unfair competition in regards to a Work, + subject to the limitations in paragraph 4(i), below; + 5. rights protecting the extraction, dissemination, use and reuse of data in + a Work; + 6. database rights (such as those arising under Directive 96/9/EC of the + European Parliament and of the Council of 11 March 1996 on the legal + protection of databases, and under any national implementation thereof, + including any amended or successor version of such directive); and + 7. other similar, equivalent or corresponding rights throughout the world + based on applicable law or treaty, and any national implementations + thereof. + +2. Waiver. To the greatest extent permitted by, but not in contravention of, + applicable law, Affirmer hereby overtly, fully, permanently, irrevocably and + unconditionally waives, abandons, and surrenders all of Affirmer’s Copyright + and Related Rights and associated claims and causes of action, whether now + known or unknown (including existing as well as future claims and causes of + action), in the Work (i) in all territories worldwide, (ii) for the maximum + duration provided by applicable law or treaty (including future time + extensions), (iii) in any current or future medium and for any number of + copies, and (iv) for any purpose whatsoever, including without limitation + commercial, advertising or promotional purposes (the “Waiver”). Affirmer + makes the Waiver for the benefit of each member of the public at large and + to the detriment of Affirmer’s heirs and successors, fully intending that + such Waiver shall not be subject to revocation, rescission, cancellation, + termination, or any other legal or equitable action to disrupt the quiet + enjoyment of the Work by the public as contemplated by Affirmer’s express + Statement of Purpose. + +3. Public License Fallback. Should any part of the Waiver for any reason be + judged legally invalid or ineffective under applicable law, then the Waiver + shall be preserved to the maximum extent permitted taking into account + Affirmer’s express Statement of Purpose. In addition, to the extent the + Waiver is so judged Affirmer hereby grants to each affected person a + royalty-free, non transferable, non sublicensable, non exclusive, + irrevocable and unconditional license to exercise Affirmer’s Copyright and + Related Rights in the Work (i) in all territories worldwide, (ii) for the + maximum duration provided by applicable law or treaty (including future time + extensions), (iii) in any current or future medium and for any number of + copies, and (iv) for any purpose whatsoever, including without limitation + commercial, advertising or promotional purposes (the “License”). The License + shall be deemed effective as of the date CC0 was applied by Affirmer to the + Work. Should any part of the License for any reason be judged legally + invalid or ineffective under applicable law, such partial invalidity or + ineffectiveness shall not invalidate the remainder of the License, and in + such case Affirmer hereby affirms that he or she will not (i) exercise any + of his or her remaining Copyright and Related Rights in the Work or (ii) + assert any associated claims and causes of action with respect to the Work, + in either case contrary to Affirmer’s express Statement of Purpose. + +4. Limitations and Disclaimers. + 1. No trademark or patent rights held by Affirmer are waived, abandoned, + surrendered, licensed or otherwise affected by this document. + 2. Affirmer offers the Work as-is and makes no representations or warranties + of any kind concerning the Work, express, implied, statutory or + otherwise, including without limitation warranties of title, + merchantability, fitness for a particular purpose, non infringement, or + the absence of latent or other defects, accuracy, or the present or + absence of errors, whether or not discoverable, all to the greatest + extent permissible under applicable law. + 3. Affirmer disclaims responsibility for clearing rights of other persons + that may apply to the Work or any use thereof, including without + limitation any person’s Copyright and Related Rights in the Work. + Further, Affirmer disclaims responsibility for obtaining any necessary + consents, permissions or other rights required for any use of the Work. + 4. Affirmer understands and acknowledges that Creative Commons is not a + party to this document and has no duty or obligation with respect to this + CC0 or use of the Work. + +For more information, please see +http://creativecommons.org/publicdomain/zero/1.0/. diff --git a/README.md b/README.md new file mode 100644 index 0000000000..c86d0a73f7 --- /dev/null +++ b/README.md @@ -0,0 +1,136 @@ +# Prefers Color Scheme [PostCSS][Prefers Color Scheme] + +[![NPM Version][npm-img]][npm-url] +[![Build Status][cli-img]][cli-url] +[![Support Chat][git-img]][git-url] + +[Prefers Color Scheme] lets you use light or dark color themes in CSS, +following the [Media Queries] specification. + +```bash +npm install css-prefers-color-scheme +``` + +```css +@media (prefers-color-scheme: dark) { + :root { + --site-bgcolor: #1b1b1b; + --site-color: #fff; + } +} + +body { + background-color: var(--site-bgcolor, #f9f9f9); + color: var(--site-color, #111); + font: 100%/1.5 system-ui; +} +``` + +[PostCSS] transforms these into cross-browser compatible `color-index` queries: + +```css +@media (color-index: 48) { + :root { + --site-bgcolor: #1b1b1b; + --site-color: #fff; + } +} + +body { + background-color: var(--site-bgcolor, #f9f9f9); + color: var(--site-color, #111); + font: 100%/1.5 system-ui; +} +``` + +`CSS._prefersColorScheme()` applies these “light mode” and “dark mode” queries +to documents on the fly. The entire frontend script is less than 300 bytes. + +[Prefers Color Scheme] works in all major browsers, including Safari 6+ and +Internet Explorer 9+. +[See it for yourself.](https://app.crossbrowsertesting.com/public/i76b092cd2b52b86/screenshots/z25c0ccdfcc9c9b8956f?size=medium&type=windowed) + +```js +const prefersColorScheme = require('css-prefers-color-scheme'); + +// apply "dark" queries +prefersColorScheme('dark'); + +// apply "light" queries (also disabling "dark" queries) +prefersColorScheme('light'); +``` + +## PostCSS Usage + +Add [Prefers Color Scheme] to your project: + +```bash +npm install css-prefers-color-scheme --save-dev +``` + +Use [Prefers Color Scheme] to process your CSS: + +```js +const postcssPrefersColorScheme = require('css-prefers-color-scheme/postcss'); + +postcssPrefersColorScheme.process(YOUR_CSS /*, processOptions, pluginOptions */); +``` + +Or use it as a [PostCSS] plugin: + +```js +const postcss = require('postcss'); +const postcssPrefersColorScheme = require('css-prefers-color-scheme/postcss'); + +postcss([ + postcssPrefersColorScheme(/* pluginOptions */) +]).process(YOUR_CSS /*, processOptions */); +``` + +[Prefers Color Scheme] runs in all Node environments, with special +instructions for: + +| [Node](INSTALL.md#node) | [Webpack](INSTALL.md#webpack) | [Create React App](INSTALL.md#create-react-app) | [Gulp](INSTALL.md#gulp) | [Grunt](INSTALL.md#grunt) | +| --- | --- | --- | --- | --- | + +--- + +## How does the frontend work? + +The `color-index` media query is understood in all major browsers going back to +Internet Explorer 9, but all implementations only seem to allow a `color-index` +of `0`. + +This script changes `(color-index: 48)` queries into +`not all and (color-index: 48)` to activate “dark mode” specific CSS, and then +it inverts `(color-index: 70)` queries into `not all and (color-index: 48)` +to activate “light mode” specific CSS. + +```css +@media (color-index: 70) { /* "light" query */ + body { + background-color: white; + color: black; + } +} +``` + +These valid queries are accessible to `document.styleSheet`, so no css parsing +is required to use this library, which is how the script is less than 300 bytes. + +## Why does the fallback work this way? + +The value of `48` is chosen for dark mode because it is the keycode for `0`, +the hexidecimal value of black. Likewise, `70` is chosen for light mode because +it is the keycode for `f`, the hexidecimal value of white. + +[cli-img]: https://img.shields.io/travis/csstools/css-prefers-color-scheme.svg +[cli-url]: https://travis-ci.org/csstools/css-prefers-color-scheme +[git-img]: https://img.shields.io/badge/support-chat-blue.svg +[git-url]: https://gitter.im/postcss/postcss +[npm-img]: https://img.shields.io/npm/v/css-prefers-color-scheme.svg +[npm-url]: https://www.npmjs.com/package/css-prefers-color-scheme + +[PostCSS]: https://github.com/postcss/postcss +[Prefers Color Scheme]: https://github.com/csstools/css-prefers-color-scheme +[Media Queries]: https://drafts.csswg.org/mediaqueries-5/#descdef-media-prefers-color-scheme diff --git a/package.json b/package.json new file mode 100644 index 0000000000..8eed73de25 --- /dev/null +++ b/package.json @@ -0,0 +1,66 @@ +{ + "name": "css-prefers-color-scheme", + "version": "1.0.0", + "description": "Use a light or dark color theme in CSS CSS", + "author": "Jonathan Neal ", + "license": "CC0-1.0", + "repository": "csstools/css-prefers-color-scheme", + "homepage": "https://github.com/csstools/css-prefers-color-scheme#readme", + "bugs": "https://github.com/csstools/css-prefers-color-scheme/issues", + "main": "client.js", + "module": "client.mjs", + "files": [ + "client.js", + "client.mjs", + "postcss.js", + "postcss.mjs" + ], + "scripts": { + "build": "npm run build:client && npm run build:postcss", + "build:client": "rollup -c .rollup.client.js --silent", + "build:postcss": "rollup -c .rollup.postcss.js --silent", + "prepublishOnly": "npm test", + "pretest": "npm run build", + "test": "echo 'Running tests...'; npm run test:js && npm run test:tape", + "test:js": "eslint src/*.js --cache --ignore-path .gitignore --quiet", + "test:tape": "postcss-tape --plugin=postcss.js" + }, + "engines": { + "node": ">=6.0.0" + }, + "dependencies": { + "postcss": "^7.0.2" + }, + "devDependencies": { + "@babel/core": "^7.1.0", + "@babel/preset-env": "^7.0.0", + "babel-eslint": "^9.0.0", + "eslint": "^5.6.0", + "eslint-config-dev": "^2.0.0", + "postcss-tape": "^2.2.0", + "pre-commit": "^1.2.2", + "rollup": "^0.66.2", + "rollup-plugin-babel": "^4.0.1", + "uglify-js": "^3.4.9" + }, + "eslintConfig": { + "extends": "dev", + "parser": "babel-eslint" + }, + "keywords": [ + "postcss", + "css", + "postcss-plugin", + "media", + "query", + "prefers", + "color", + "scheme", + "dark", + "light", + "no-preference", + "mode", + "queries", + "interface" + ] +} diff --git a/src/client.js b/src/client.js new file mode 100644 index 0000000000..f867d3d5cc --- /dev/null +++ b/src/client.js @@ -0,0 +1,21 @@ +const colorIndexRegExp = /((?:not )?all and )?(\(color-index:\s*(22|48|70)\))/i; + +export default style => { + [].forEach.call(document.styleSheets, styleSheet => { + [].forEach.call(styleSheet.cssRules, cssRule => { + const mediaMatch = (Object(cssRule.media).mediaText || '').match(colorIndexRegExp); + + if (mediaMatch) { + cssRule.media.mediaText = ( + (/^dark$/i.test(style) + ? mediaMatch[3] === '48' + : /^light$/i.test(style) + ? mediaMatch[3] === '70' + : mediaMatch[3] === '22') + ? 'not all and ' + : '' + ) + cssRule.media.mediaText.replace(colorIndexRegExp, '$2'); + } + }); + }); +}; diff --git a/src/postcss.js b/src/postcss.js new file mode 100644 index 0000000000..2a949c5779 --- /dev/null +++ b/src/postcss.js @@ -0,0 +1,17 @@ +import postcss from 'postcss'; + +const mediaRegExp = /^media$/i; +const prefersInterfaceRegExp = /\(\s*prefers-color-scheme\s*:\s*(dark|light|no-preference)\s*\)/i; +const colorIndexByStyle = { dark: 48, light: 70, 'no-preference': 22 }; +const prefersInterfaceReplacer = ($0, style) => `(color-index: ${colorIndexByStyle[style.toLowerCase()]})`; + +export default postcss.plugin('postcss-prefers-color-scheme', () => root => { + root.walkAtRules(mediaRegExp, atRule => { + const { params } = atRule; + const altParams = params.replace(prefersInterfaceRegExp, prefersInterfaceReplacer); + + if (params !== altParams) { + atRule.params = altParams; + } + }); +}); diff --git a/test/basic.css b/test/basic.css new file mode 100644 index 0000000000..2276649bff --- /dev/null +++ b/test/basic.css @@ -0,0 +1,26 @@ +@media (prefers-color-scheme: no-preference) { + :root { + --site-bgcolor: #f9f9f9; + --site-color: #111; + } +} + +@media (prefers-color-scheme: dark) { + :root { + --site-bgcolor: #1b1b1b; + --site-color: #fff; + } +} + +@media (prefers-color-scheme: light) { + :root { + --site-bgcolor: #fff; + --site-color: #222; + } +} + +body { + background-color: var(--site-bgcolor, #f9f9f9); + color: var(--site-color, #111); + font: 100%/1.5 system-ui; +} diff --git a/test/basic.expect.css b/test/basic.expect.css new file mode 100644 index 0000000000..4915583baf --- /dev/null +++ b/test/basic.expect.css @@ -0,0 +1,26 @@ +@media (color-index: 22) { + :root { + --site-bgcolor: #f9f9f9; + --site-color: #111; + } +} + +@media (color-index: 48) { + :root { + --site-bgcolor: #1b1b1b; + --site-color: #fff; + } +} + +@media (color-index: 70) { + :root { + --site-bgcolor: #fff; + --site-color: #222; + } +} + +body { + background-color: var(--site-bgcolor, #f9f9f9); + color: var(--site-color, #111); + font: 100%/1.5 system-ui; +} diff --git a/test/basic.result.css b/test/basic.result.css new file mode 100644 index 0000000000..4915583baf --- /dev/null +++ b/test/basic.result.css @@ -0,0 +1,26 @@ +@media (color-index: 22) { + :root { + --site-bgcolor: #f9f9f9; + --site-color: #111; + } +} + +@media (color-index: 48) { + :root { + --site-bgcolor: #1b1b1b; + --site-color: #fff; + } +} + +@media (color-index: 70) { + :root { + --site-bgcolor: #fff; + --site-color: #222; + } +} + +body { + background-color: var(--site-bgcolor, #f9f9f9); + color: var(--site-color, #111); + font: 100%/1.5 system-ui; +} From 25d68db4e24c26316e8642e99fb3bddcec33d92c Mon Sep 17 00:00:00 2001 From: Jonathan Neal Date: Wed, 26 Sep 2018 00:22:25 -0400 Subject: [PATCH 729/795] 8.0.6 --- CHANGELOG.md | 5 ++ index.js | 12 ++-- ... => get-custom-properties-from-imports.js} | 60 ++++++++----------- ....js => get-custom-properties-from-root.js} | 2 +- lib/transform-properties.js | 9 +-- ... => write-custom-properties-to-exports.js} | 28 ++++----- package.json | 8 +-- test/basic.css | 1 + test/basic.expect.css | 2 + test/basic.import-is-empty.expect.css | 2 + test/basic.import.expect.css | 2 + test/basic.preserve.expect.css | 4 ++ 12 files changed, 69 insertions(+), 66 deletions(-) rename lib/{import-from.js => get-custom-properties-from-imports.js} (50%) rename lib/{get-custom-properties.js => get-custom-properties-from-root.js} (96%) rename lib/{export-to.js => write-custom-properties-to-exports.js} (79%) diff --git a/CHANGELOG.md b/CHANGELOG.md index 65182c0811..8dc4cff765 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,10 @@ # Changes to PostCSS Custom Properties +### 8.0.6 (September 21, 2018) + +- Fixed: Issue with regular `:root` and `html` properties not getting polyfilled +- Updated: `postcss` to 7.0.3 (patch) + ### 8.0.5 (September 21, 2018) - Fixed: Issue with multiple `importFrom` not getting combined diff --git a/index.js b/index.js index 35a4a5459d..b39e9ae200 100755 --- a/index.js +++ b/index.js @@ -1,8 +1,8 @@ import postcss from 'postcss'; -import getCustomProperties from './lib/get-custom-properties'; +import getCustomPropertiesFromRoot from './lib/get-custom-properties-from-root'; +import getCustomPropertiesFromImports from './lib/get-custom-properties-from-imports'; import transformProperties from './lib/transform-properties'; -import importCustomPropertiesFromSources from './lib/import-from'; -import exportCustomPropertiesToDestinations from './lib/export-to'; +import writeCustomPropertiesToExports from './lib/write-custom-properties-to-exports'; export default postcss.plugin('postcss-custom-properties', opts => { // whether to preserve custom selectors and rules using them @@ -15,15 +15,15 @@ export default postcss.plugin('postcss-custom-properties', opts => { const exportTo = [].concat(Object(opts).exportTo || []); // promise any custom selectors are imported - const customPropertiesPromise = importCustomPropertiesFromSources(importFrom); + const customPropertiesPromise = getCustomPropertiesFromImports(importFrom); return async root => { const customProperties = Object.assign( await customPropertiesPromise, - getCustomProperties(root, { preserve }) + getCustomPropertiesFromRoot(root, { preserve }) ); - await exportCustomPropertiesToDestinations(customProperties, exportTo); + await writeCustomPropertiesToExports(customProperties, exportTo); transformProperties(root, customProperties, { preserve }); }; diff --git a/lib/import-from.js b/lib/get-custom-properties-from-imports.js similarity index 50% rename from lib/import-from.js rename to lib/get-custom-properties-from-imports.js index e6ad80c4c9..d70377882e 100644 --- a/lib/import-from.js +++ b/lib/get-custom-properties-from-imports.js @@ -2,32 +2,26 @@ import fs from 'fs'; import path from 'path'; import postcss from 'postcss'; import valueParser from 'postcss-values-parser'; -import getCustomProperties from './get-custom-properties'; +import getCustomPropertiesFromRoot from './get-custom-properties-from-root'; -/* Import Custom Properties from CSS AST +/* Get Custom Properties from CSS File /* ========================================================================== */ -function importCustomPropertiesFromCSSAST(root) { - return getCustomProperties(root, { preserve: true }); -} - -/* Import Custom Properties from CSS File -/* ========================================================================== */ +async function getCustomPropertiesFromCSSFile(from) { + const css = await readFile(from); + const root = postcss.parse(css, { from }); -async function importCustomPropertiesFromCSSFile(from) { - const css = await readFile(path.resolve(from)); - const root = postcss.parse(css, { from: path.resolve(from) }); - - return importCustomPropertiesFromCSSAST(root); + return getCustomPropertiesFromRoot(root, { preserve: true }); } -/* Import Custom Properties from Object +/* Get Custom Properties from Object /* ========================================================================== */ -function importCustomPropertiesFromObject(object) { +function getCustomPropertiesFromObject(object) { const customProperties = Object.assign( {}, - Object(object).customProperties || Object(object)['custom-properties'] + Object(object).customProperties, + Object(object)['custom-properties'] ); for (const key in customProperties) { @@ -37,28 +31,28 @@ function importCustomPropertiesFromObject(object) { return customProperties; } -/* Import Custom Properties from JSON file +/* Get Custom Properties from JSON file /* ========================================================================== */ -async function importCustomPropertiesFromJSONFile(from) { - const object = await readJSON(path.resolve(from)); +async function getCustomPropertiesFromJSONFile(from) { + const object = await readJSON(from); - return importCustomPropertiesFromObject(object); + return getCustomPropertiesFromObject(object); } -/* Import Custom Properties from JS file +/* Get Custom Properties from JS file /* ========================================================================== */ -async function importCustomPropertiesFromJSFile(from) { - const object = await import(path.resolve(from)); +async function getCustomPropertiesFromJSFile(from) { + const object = await import(from); - return importCustomPropertiesFromObject(object); + return getCustomPropertiesFromObject(object); } -/* Import Custom Properties from Sources +/* Get Custom Properties from Imports /* ========================================================================== */ -export default function importCustomPropertiesFromSources(sources) { +export default function getCustomPropertiesFromImports(sources) { return sources.map(source => { if (source instanceof Promise) { return source; @@ -75,7 +69,7 @@ export default function importCustomPropertiesFromSources(sources) { } // source pathname - const from = String(opts.from || ''); + const from = path.resolve(String(opts.from || '')); // type of file being read from const type = (opts.type || path.extname(from).slice(1)).toLowerCase(); @@ -84,23 +78,19 @@ export default function importCustomPropertiesFromSources(sources) { }).reduce(async (customProperties, source) => { const { type, from } = await source; - if (type === 'ast') { - return Object.assign(await customProperties, importCustomPropertiesFromCSSAST(from)); - } - if (type === 'css') { - return Object.assign(await customProperties, await importCustomPropertiesFromCSSFile(from)); + return Object.assign(await customProperties, await getCustomPropertiesFromCSSFile(from)); } if (type === 'js') { - return Object.assign(await customProperties, await importCustomPropertiesFromJSFile(from)); + return Object.assign(await customProperties, await getCustomPropertiesFromJSFile(from)); } if (type === 'json') { - return Object.assign(await customProperties, await importCustomPropertiesFromJSONFile(from)); + return Object.assign(await customProperties, await getCustomPropertiesFromJSONFile(from)); } - return Object.assign(await customProperties, await importCustomPropertiesFromObject(await source)); + return Object.assign(await customProperties, await getCustomPropertiesFromObject(await source)); }, {}); } diff --git a/lib/get-custom-properties.js b/lib/get-custom-properties-from-root.js similarity index 96% rename from lib/get-custom-properties.js rename to lib/get-custom-properties-from-root.js index c60fbd56eb..3646b2627a 100644 --- a/lib/get-custom-properties.js +++ b/lib/get-custom-properties-from-root.js @@ -1,7 +1,7 @@ import valueParser from 'postcss-values-parser'; // return custom selectors from the css root, conditionally removing them -export default function getCustomProperties(root, opts) { +export default function getCustomPropertiesFromRoot(root, opts) { // initialize custom selectors const customPropertiesFromHtmlElement = {}; const customPropertiesFromRootPsuedo = {}; diff --git a/lib/transform-properties.js b/lib/transform-properties.js index 283fd100c9..9fceaf186e 100644 --- a/lib/transform-properties.js +++ b/lib/transform-properties.js @@ -22,14 +22,11 @@ export default (root, customProperties, opts) => { }); }; -// match html and :root rules -const htmlOrRootSelectorRegExp = /^(html|:root)$/i; +// match custom properties +const customPropertyRegExp = /^--[A-z][\w-]*$/; // match custom property inclusions const customPropertiesRegExp = /(^|[^\w-])var\([\W\w]+\)/; -// whether the declaration has a parent rule that is either html or :root -const isDeclChildOfHtmlOrRootRule = decl => Object(decl.parent).type === 'rule' && htmlOrRootSelectorRegExp.test(decl.parent.selector); - // whether the declaration should be potentially transformed -const isTransformableDecl = decl => customPropertiesRegExp.test(decl.value) && !isDeclChildOfHtmlOrRootRule(decl); +const isTransformableDecl = decl => !customPropertyRegExp.test(decl.prop) && customPropertiesRegExp.test(decl.value); diff --git a/lib/export-to.js b/lib/write-custom-properties-to-exports.js similarity index 79% rename from lib/export-to.js rename to lib/write-custom-properties-to-exports.js index ac9d7f138c..a1e84563c1 100644 --- a/lib/export-to.js +++ b/lib/write-custom-properties-to-exports.js @@ -1,10 +1,10 @@ import fs from 'fs'; import path from 'path'; -/* Export Custom Properties to CSS File +/* Write Custom Properties to CSS File /* ========================================================================== */ -async function exportCustomPropertiesToCssFile(to, customProperties) { +async function writeCustomPropertiesToCssFile(to, customProperties) { const cssContent = Object.keys(customProperties).reduce((cssLines, name) => { cssLines.push(`\t${name}: ${customProperties[name]};`); @@ -15,10 +15,10 @@ async function exportCustomPropertiesToCssFile(to, customProperties) { await writeFile(to, css); } -/* Export Custom Properties to JSON file +/* Write Custom Properties to JSON file /* ========================================================================== */ -async function exportCustomPropertiesToJsonFile(to, customProperties) { +async function writeCustomPropertiesToJsonFile(to, customProperties) { const jsonContent = JSON.stringify({ 'custom-properties': customProperties }, null, ' '); @@ -27,10 +27,10 @@ async function exportCustomPropertiesToJsonFile(to, customProperties) { await writeFile(to, json); } -/* Export Custom Properties to Common JS file +/* Write Custom Properties to Common JS file /* ========================================================================== */ -async function exportCustomPropertiesToCjsFile(to, customProperties) { +async function writeCustomPropertiesToCjsFile(to, customProperties) { const jsContents = Object.keys(customProperties).reduce((jsLines, name) => { jsLines.push(`\t\t'${escapeForJS(name)}': '${escapeForJS(customProperties[name])}'`); @@ -41,10 +41,10 @@ async function exportCustomPropertiesToCjsFile(to, customProperties) { await writeFile(to, js); } -/* Export Custom Properties to Module JS file +/* Write Custom Properties to Module JS file /* ========================================================================== */ -async function exportCustomPropertiesToMjsFile(to, customProperties) { +async function writeCustomPropertiesToMjsFile(to, customProperties) { const mjsContents = Object.keys(customProperties).reduce((mjsLines, name) => { mjsLines.push(`\t'${escapeForJS(name)}': '${escapeForJS(customProperties[name])}'`); @@ -55,10 +55,10 @@ async function exportCustomPropertiesToMjsFile(to, customProperties) { await writeFile(to, mjs); } -/* Export Custom Properties to Destinations +/* Write Custom Properties to Exports /* ========================================================================== */ -export default function exportCustomPropertiesToDestinations(customProperties, destinations) { +export default function writeCustomPropertiesToExports(customProperties, destinations) { return Promise.all(destinations.map(async destination => { if (destination instanceof Function) { await destination(defaultCustomPropertiesToJSON(customProperties)); @@ -86,19 +86,19 @@ export default function exportCustomPropertiesToDestinations(customProperties, d const customPropertiesJSON = toJSON(customProperties); if (type === 'css') { - await exportCustomPropertiesToCssFile(to, customPropertiesJSON); + await writeCustomPropertiesToCssFile(to, customPropertiesJSON); } if (type === 'js') { - await exportCustomPropertiesToCjsFile(to, customPropertiesJSON); + await writeCustomPropertiesToCjsFile(to, customPropertiesJSON); } if (type === 'json') { - await exportCustomPropertiesToJsonFile(to, customPropertiesJSON); + await writeCustomPropertiesToJsonFile(to, customPropertiesJSON); } if (type === 'mjs') { - await exportCustomPropertiesToMjsFile(to, customPropertiesJSON); + await writeCustomPropertiesToMjsFile(to, customPropertiesJSON); } } } diff --git a/package.json b/package.json index 285387936e..6078fd184b 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "postcss-custom-properties", - "version": "8.0.5", + "version": "8.0.6", "description": "Use Custom Properties Queries in CSS", "author": "Jonathan Neal ", "contributors": [ @@ -21,7 +21,7 @@ "scripts": { "prepublishOnly": "npm test", "pretest": "rollup -c .rollup.js --silent", - "test": "echo 'Running tests...'; npm run test:js && npm run test:tape", + "test": "npm run test:js && npm run test:tape", "test:js": "eslint *.js lib/*.js --cache --ignore-path .gitignore --quiet", "test:tape": "postcss-tape" }, @@ -29,14 +29,14 @@ "node": ">=6.0.0" }, "dependencies": { - "postcss": "^7.0.2", + "postcss": "^7.0.3", "postcss-values-parser": "^2.0.0" }, "devDependencies": { "@babel/core": "^7.1.0", "@babel/plugin-syntax-dynamic-import": "^7.0.0", "@babel/preset-env": "^7.1.0", - "babel-eslint": "^9.0.0", + "babel-eslint": "^10.0.0", "eslint": "^5.6.0", "eslint-config-dev": "^2.0.0", "postcss-tape": "^2.2.0", diff --git a/test/basic.css b/test/basic.css index f42d93e723..5f595348ee 100644 --- a/test/basic.css +++ b/test/basic.css @@ -7,6 +7,7 @@ html { --ref-color: var(--color); --circular: var(--circular-2); --circular-2: var(--circular); + color: var(--color); } .test { diff --git a/test/basic.expect.css b/test/basic.expect.css index 90691d54b9..0d36404a63 100644 --- a/test/basic.expect.css +++ b/test/basic.expect.css @@ -7,6 +7,8 @@ html { --ref-color: var(--color); --circular: var(--circular-2); --circular-2: var(--circular); + color: rgb(255, 0, 0); + color: var(--color); } .test { diff --git a/test/basic.import-is-empty.expect.css b/test/basic.import-is-empty.expect.css index 90691d54b9..0d36404a63 100644 --- a/test/basic.import-is-empty.expect.css +++ b/test/basic.import-is-empty.expect.css @@ -7,6 +7,8 @@ html { --ref-color: var(--color); --circular: var(--circular-2); --circular-2: var(--circular); + color: rgb(255, 0, 0); + color: var(--color); } .test { diff --git a/test/basic.import.expect.css b/test/basic.import.expect.css index 597054f402..c2cea45bdb 100644 --- a/test/basic.import.expect.css +++ b/test/basic.import.expect.css @@ -7,6 +7,8 @@ html { --ref-color: var(--color); --circular: var(--circular-2); --circular-2: var(--circular); + color: rgb(255, 0, 0); + color: var(--color); } .test { diff --git a/test/basic.preserve.expect.css b/test/basic.preserve.expect.css index c6b575b057..216f5e8d2a 100644 --- a/test/basic.preserve.expect.css +++ b/test/basic.preserve.expect.css @@ -1,3 +1,7 @@ +:root { + color: rgb(255, 0, 0); +} + .test { --skip: gray; color: rgb(255, 0, 0); From a2e2b49e38f0639676a73676c96a78f3ba4bf2a9 Mon Sep 17 00:00:00 2001 From: Jonathan Neal Date: Tue, 2 Oct 2018 12:12:57 -0400 Subject: [PATCH 730/795] 8.0.7 --- .tape.js | 9 ++++++--- CHANGELOG.md | 5 +++++ lib/get-custom-properties-from-imports.js | 2 +- package.json | 10 +++++----- test/basic.css | 4 ++++ test/basic.expect.css | 4 ++++ test/basic.import-is-empty.expect.css | 4 ++++ test/basic.import.expect.css | 5 +++++ test/basic.preserve.expect.css | 4 ++++ test/import-properties.css | 1 + test/import-properties.js | 3 ++- test/import-properties.json | 3 ++- 12 files changed, 43 insertions(+), 11 deletions(-) diff --git a/.tape.js b/.tape.js index 1e7e7dc0b5..f61ce9be27 100644 --- a/.tape.js +++ b/.tape.js @@ -16,7 +16,8 @@ module.exports = { customProperties: { '--color': 'rgb(255, 0, 0)', '--color-2': 'yellow', - '--ref-color': 'var(--color)' + '--ref-color': 'var(--color)', + '--z-index': 10 } } } @@ -29,7 +30,8 @@ module.exports = { customProperties: { '--color': 'rgb(255, 0, 0)', '--color-2': 'yellow', - '--ref-color': 'var(--color)' + '--ref-color': 'var(--color)', + '--z-index': 10 } }; } @@ -46,7 +48,8 @@ module.exports = { customProperties: { '--color': 'rgb(255, 0, 0)', '--color-2': 'yellow', - '--ref-color': 'var(--color)' + '--ref-color': 'var(--color)', + '--z-index': 10 } }) }); diff --git a/CHANGELOG.md b/CHANGELOG.md index 8dc4cff765..8f9eeb746a 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,10 @@ # Changes to PostCSS Custom Properties +### 8.0.7 (October 2, 2018) + +- Fixed: Issue with parsing custom properties that are not strings +- Updated: `postcss` to 7.0.5 (patch) + ### 8.0.6 (September 21, 2018) - Fixed: Issue with regular `:root` and `html` properties not getting polyfilled diff --git a/lib/get-custom-properties-from-imports.js b/lib/get-custom-properties-from-imports.js index d70377882e..95771292c7 100644 --- a/lib/get-custom-properties-from-imports.js +++ b/lib/get-custom-properties-from-imports.js @@ -25,7 +25,7 @@ function getCustomPropertiesFromObject(object) { ); for (const key in customProperties) { - customProperties[key] = valueParser(customProperties[key]).parse().nodes; + customProperties[key] = valueParser(String(customProperties[key])).parse().nodes; } return customProperties; diff --git a/package.json b/package.json index 6078fd184b..56720ee38b 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "postcss-custom-properties", - "version": "8.0.6", + "version": "8.0.7", "description": "Use Custom Properties Queries in CSS", "author": "Jonathan Neal ", "contributors": [ @@ -29,15 +29,15 @@ "node": ">=6.0.0" }, "dependencies": { - "postcss": "^7.0.3", + "postcss": "^7.0.5", "postcss-values-parser": "^2.0.0" }, "devDependencies": { - "@babel/core": "^7.1.0", + "@babel/core": "^7.1.2", "@babel/plugin-syntax-dynamic-import": "^7.0.0", "@babel/preset-env": "^7.1.0", - "babel-eslint": "^10.0.0", - "eslint": "^5.6.0", + "babel-eslint": "^10.0.1", + "eslint": "^5.6.1", "eslint-config-dev": "^2.0.0", "postcss-tape": "^2.2.0", "pre-commit": "^1.2.2", diff --git a/test/basic.css b/test/basic.css index 5f595348ee..a974108734 100644 --- a/test/basic.css +++ b/test/basic.css @@ -30,3 +30,7 @@ html { .test--color_spacing { box-shadow: inset 0 -3px 0 var(--color); } + +.test--z-index { + z-index: var(--z-index); +} diff --git a/test/basic.expect.css b/test/basic.expect.css index 0d36404a63..b61105b232 100644 --- a/test/basic.expect.css +++ b/test/basic.expect.css @@ -35,3 +35,7 @@ html { box-shadow: inset 0 -3px 0 rgb(255, 0, 0); box-shadow: inset 0 -3px 0 var(--color); } + +.test--z-index { + z-index: var(--z-index); +} diff --git a/test/basic.import-is-empty.expect.css b/test/basic.import-is-empty.expect.css index 0d36404a63..b61105b232 100644 --- a/test/basic.import-is-empty.expect.css +++ b/test/basic.import-is-empty.expect.css @@ -35,3 +35,7 @@ html { box-shadow: inset 0 -3px 0 rgb(255, 0, 0); box-shadow: inset 0 -3px 0 var(--color); } + +.test--z-index { + z-index: var(--z-index); +} diff --git a/test/basic.import.expect.css b/test/basic.import.expect.css index c2cea45bdb..bfdd483b36 100644 --- a/test/basic.import.expect.css +++ b/test/basic.import.expect.css @@ -35,3 +35,8 @@ html { box-shadow: inset 0 -3px 0 rgb(255, 0, 0); box-shadow: inset 0 -3px 0 var(--color); } + +.test--z-index { + z-index: 10; + z-index: var(--z-index); +} diff --git a/test/basic.preserve.expect.css b/test/basic.preserve.expect.css index 216f5e8d2a..642ab08e6a 100644 --- a/test/basic.preserve.expect.css +++ b/test/basic.preserve.expect.css @@ -22,3 +22,7 @@ .test--color_spacing { box-shadow: inset 0 -3px 0 rgb(255, 0, 0); } + +.test--z-index { + z-index: var(--z-index); +} diff --git a/test/import-properties.css b/test/import-properties.css index 24b0dd98ac..a01ea3e89b 100644 --- a/test/import-properties.css +++ b/test/import-properties.css @@ -1,3 +1,4 @@ :root { --ref-color: var(--color); + --z-index: 10; } diff --git a/test/import-properties.js b/test/import-properties.js index a6ea3b20e5..85417faf0e 100644 --- a/test/import-properties.js +++ b/test/import-properties.js @@ -1,5 +1,6 @@ module.exports = { customProperties: { - '--ref-color': 'var(--color)' + '--ref-color': 'var(--color)', + '--z-index': 10 } }; diff --git a/test/import-properties.json b/test/import-properties.json index 3687057da1..6312bf9522 100644 --- a/test/import-properties.json +++ b/test/import-properties.json @@ -2,6 +2,7 @@ "custom-properties": { "--color": "rgb(255, 0, 0)", "--color-2": "yellow", - "--ref-color": "var(--color)" + "--ref-color": "var(--color)", + "--z-index": 10 } } From db2e2a03e13c2e3aa9ee81ad986fc76977b73d50 Mon Sep 17 00:00:00 2001 From: Jonathan Neal Date: Tue, 2 Oct 2018 14:13:59 -0400 Subject: [PATCH 731/795] 8.0.8 --- CHANGELOG.md | 4 ++++ lib/transform-value-ast.js | 4 +++- package.json | 2 +- test/basic.css | 4 ++++ test/basic.expect.css | 5 +++++ test/basic.import-is-empty.expect.css | 5 +++++ test/basic.import.expect.css | 5 +++++ test/basic.preserve.expect.css | 4 ++++ 8 files changed, 31 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8f9eeb746a..930be92ac4 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # Changes to PostCSS Custom Properties +### 8.0.8 (October 2, 2018) + +- Fixed: Issue with nested fallbacks + ### 8.0.7 (October 2, 2018) - Fixed: Issue with parsing custom properties that are not strings diff --git a/lib/transform-value-ast.js b/lib/transform-value-ast.js index 2d744a79c3..a38995bfae 100644 --- a/lib/transform-value-ast.js +++ b/lib/transform-value-ast.js @@ -13,7 +13,9 @@ export default function transformValueAST(root, customProperties) { retransformValueAST(root, customProperties, name); } else if (fallbacks.length) { // conditionally replace a custom property with a fallback - child.replaceWith(...asClonedArrayWithBeforeSpacing(fallbacks, child.raws.before)); + const index = root.nodes.indexOf(child); + + root.nodes.splice(index, 1, ...asClonedArrayWithBeforeSpacing(fallbacks, child.raws.before)); transformValueAST(root, customProperties); } diff --git a/package.json b/package.json index 56720ee38b..96a7a27a3f 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "postcss-custom-properties", - "version": "8.0.7", + "version": "8.0.8", "description": "Use Custom Properties Queries in CSS", "author": "Jonathan Neal ", "contributors": [ diff --git a/test/basic.css b/test/basic.css index a974108734..2ef95add0c 100644 --- a/test/basic.css +++ b/test/basic.css @@ -34,3 +34,7 @@ html { .test--z-index { z-index: var(--z-index); } + +.test--nested-fallback { + z-index: var(--xxx, var(--yyy, 1)); +} diff --git a/test/basic.expect.css b/test/basic.expect.css index b61105b232..2cb77134bf 100644 --- a/test/basic.expect.css +++ b/test/basic.expect.css @@ -39,3 +39,8 @@ html { .test--z-index { z-index: var(--z-index); } + +.test--nested-fallback { + z-index: 1; + z-index: var(--xxx, var(--yyy, 1)); +} diff --git a/test/basic.import-is-empty.expect.css b/test/basic.import-is-empty.expect.css index b61105b232..2cb77134bf 100644 --- a/test/basic.import-is-empty.expect.css +++ b/test/basic.import-is-empty.expect.css @@ -39,3 +39,8 @@ html { .test--z-index { z-index: var(--z-index); } + +.test--nested-fallback { + z-index: 1; + z-index: var(--xxx, var(--yyy, 1)); +} diff --git a/test/basic.import.expect.css b/test/basic.import.expect.css index bfdd483b36..97d87b1261 100644 --- a/test/basic.import.expect.css +++ b/test/basic.import.expect.css @@ -40,3 +40,8 @@ html { z-index: 10; z-index: var(--z-index); } + +.test--nested-fallback { + z-index: 1; + z-index: var(--xxx, var(--yyy, 1)); +} diff --git a/test/basic.preserve.expect.css b/test/basic.preserve.expect.css index 642ab08e6a..44e5df553b 100644 --- a/test/basic.preserve.expect.css +++ b/test/basic.preserve.expect.css @@ -26,3 +26,7 @@ .test--z-index { z-index: var(--z-index); } + +.test--nested-fallback { + z-index: 1; +} From 381c6069aa4fd48e5b8c75c9896578bef02458f0 Mon Sep 17 00:00:00 2001 From: Caleb Eby Date: Thu, 4 Oct 2018 10:20:03 -0700 Subject: [PATCH 732/795] Fix typo in README --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 997b498001..28e45fb00c 100644 --- a/README.md +++ b/README.md @@ -99,7 +99,7 @@ postcss([ ### stringifier The `stringifier` option defines how transformed colors will be produced in CSS. -By default, legacy `rbg()` and `rgba()` colors are produced, but this can be +By default, legacy `rgb()` and `rgba()` colors are produced, but this can be easily updated to support [CSS Color Module Level 4 colors] colors. ```js From e0081bfb5880d7fed812c2c7e2620c75ed7bff8d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carl=20T=C3=B6rnqvist?= Date: Fri, 5 Oct 2018 15:31:34 +0200 Subject: [PATCH 733/795] Fix calc multiple custom props with fallbacks --- lib/transform-value-ast.js | 4 +++- test/basic.css | 4 ++++ test/basic.expect.css | 5 +++++ test/basic.import-is-empty.expect.css | 5 +++++ test/basic.import.expect.css | 5 +++++ test/basic.preserve.expect.css | 4 ++++ 6 files changed, 26 insertions(+), 1 deletion(-) diff --git a/lib/transform-value-ast.js b/lib/transform-value-ast.js index a38995bfae..3d9d299434 100644 --- a/lib/transform-value-ast.js +++ b/lib/transform-value-ast.js @@ -15,7 +15,9 @@ export default function transformValueAST(root, customProperties) { // conditionally replace a custom property with a fallback const index = root.nodes.indexOf(child); - root.nodes.splice(index, 1, ...asClonedArrayWithBeforeSpacing(fallbacks, child.raws.before)); + if (index !== -1) { + root.nodes.splice(index, 1, ...asClonedArrayWithBeforeSpacing(fallbacks, child.raws.before)); + } transformValueAST(root, customProperties); } diff --git a/test/basic.css b/test/basic.css index 2ef95add0c..e095be9cfc 100644 --- a/test/basic.css +++ b/test/basic.css @@ -38,3 +38,7 @@ html { .test--nested-fallback { z-index: var(--xxx, var(--yyy, 1)); } + +.text--calc { + width: calc((100% - var(--xxx, 1px)) + var(--yyy, 10px)); +} diff --git a/test/basic.expect.css b/test/basic.expect.css index 2cb77134bf..9bb775a618 100644 --- a/test/basic.expect.css +++ b/test/basic.expect.css @@ -44,3 +44,8 @@ html { z-index: 1; z-index: var(--xxx, var(--yyy, 1)); } + +.text--calc { + width: calc((100% - 1px) + 10px); + width: calc((100% - var(--xxx, 1px)) + var(--yyy, 10px)); +} diff --git a/test/basic.import-is-empty.expect.css b/test/basic.import-is-empty.expect.css index 2cb77134bf..9bb775a618 100644 --- a/test/basic.import-is-empty.expect.css +++ b/test/basic.import-is-empty.expect.css @@ -44,3 +44,8 @@ html { z-index: 1; z-index: var(--xxx, var(--yyy, 1)); } + +.text--calc { + width: calc((100% - 1px) + 10px); + width: calc((100% - var(--xxx, 1px)) + var(--yyy, 10px)); +} diff --git a/test/basic.import.expect.css b/test/basic.import.expect.css index 97d87b1261..685f245a3f 100644 --- a/test/basic.import.expect.css +++ b/test/basic.import.expect.css @@ -45,3 +45,8 @@ html { z-index: 1; z-index: var(--xxx, var(--yyy, 1)); } + +.text--calc { + width: calc((100% - 1px) + 10px); + width: calc((100% - var(--xxx, 1px)) + var(--yyy, 10px)); +} diff --git a/test/basic.preserve.expect.css b/test/basic.preserve.expect.css index 44e5df553b..9340268416 100644 --- a/test/basic.preserve.expect.css +++ b/test/basic.preserve.expect.css @@ -30,3 +30,7 @@ .test--nested-fallback { z-index: 1; } + +.text--calc { + width: calc((100% - 1px) + 10px); +} From 1d9d913623c5fe8586de763c02463f0cf56d8318 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Lesiecki?= Date: Fri, 5 Oct 2018 09:22:39 +0200 Subject: [PATCH 734/795] Polish readme s/properties/media/ --- README.md | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index eb9551c103..d4ffeba59b 100755 --- a/README.md +++ b/README.md @@ -105,8 +105,8 @@ postcssCustomMedia({ Multiple sources can be passed into this option, and they will be parsed in the order they are received. JavaScript files, JSON files, functions, and objects -will need to namespace custom media using the `customProperties` or -`custom-properties` key. +will need to namespace custom media using the `customMedia` or +`custom-media` key. ```js postcssCustomMedia({ @@ -118,9 +118,9 @@ postcssCustomMedia({ customMedia: { '--small-viewport': '(max-width: 30em)' } }, () => { - const customProperties = { '--small-viewport': '(max-width: 30em)' }; + const customMedia = { '--small-viewport': '(max-width: 30em)' }; - return { customProperties }; + return { customMedia }; } ] }); @@ -140,8 +140,8 @@ postcssCustomMedia({ Multiple destinations can be passed into this option, and they will be parsed in the order they are received. JavaScript files, JSON files, and objects will -need to namespace custom media using the `customProperties` or -`custom-properties` key. +need to namespace custom media using the `customMedia` or +`custom-media` key. ```js const cachedObject = { customMedia: {} }; @@ -153,8 +153,8 @@ postcssCustomMedia({ 'and/then/this.mjs', // export const customMedia = { '--small-viewport': '(max-width: 30em)' } } 'and/then/that.json', // { "custom-media": { "--small-viewport": "(max-width: 30em)" } } cachedObject, - customProperties => { - customProperties // { '--small-viewport': '(max-width: 30em)' } + customMedia => { + customMedia // { '--small-viewport': '(max-width: 30em)' } } ] }); From 0929148f04fff7d400e30d3cb1c6a0be961182e5 Mon Sep 17 00:00:00 2001 From: Jonathan Neal Date: Fri, 5 Oct 2018 17:24:06 -0400 Subject: [PATCH 735/795] 7.0.5 --- .rollup.js | 4 +- CHANGELOG.md | 6 ++ README.md | 4 ++ index.js | 22 +++---- ...om.js => get-custom-media-from-imports.js} | 58 ++++++++----------- ...to.js => write-custom-media-to-exports.js} | 28 ++++----- package.json | 12 ++-- 7 files changed, 67 insertions(+), 67 deletions(-) rename lib/{import-from.js => get-custom-media-from-imports.js} (56%) rename lib/{export-to.js => write-custom-media-to-exports.js} (80%) diff --git a/.rollup.js b/.rollup.js index eab5c0d513..3f28a5511b 100644 --- a/.rollup.js +++ b/.rollup.js @@ -3,8 +3,8 @@ import babel from 'rollup-plugin-babel'; export default { input: 'index.js', output: [ - { file: 'index.cjs.js', format: 'cjs' }, - { file: 'index.es.mjs', format: 'es' } + { file: 'index.cjs.js', format: 'cjs', sourcemap: true }, + { file: 'index.es.mjs', format: 'es', sourcemap: true } ], plugins: [ babel({ diff --git a/CHANGELOG.md b/CHANGELOG.md index f3a83ce2a7..51c74f1c5a 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,11 @@ # Changes to PostCSS Custom Media +### 7.0.5 (October 5, 2018) + +- Fixed: Possible issues resolving paths to imports and exports +- Added: Imports from `customMedia` and `custom-media` simultaneously +- Updated: `postcss` to 7.0.5 + ### 7.0.4 (September 23, 2018) - Added: `importFromPlugins` option to process imports diff --git a/README.md b/README.md index d4ffeba59b..89276eed64 100755 --- a/README.md +++ b/README.md @@ -160,6 +160,10 @@ postcssCustomMedia({ }); ``` +See example exports written to [CSS](test/export-media.css), +[JS](test/export-media.js), [MJS](test/export-media.mjs), and +[JSON](test/export-media.json). + [cli-img]: https://img.shields.io/travis/postcss/postcss-custom-media.svg [cli-url]: https://travis-ci.org/postcss/postcss-custom-media [css-img]: https://cssdb.org/badge/custom-media-queries.svg diff --git a/index.js b/index.js index 7547790c60..18ab7fc810 100755 --- a/index.js +++ b/index.js @@ -1,29 +1,29 @@ import postcss from 'postcss'; -import getCustomMedia from './lib/custom-media-from-root'; +import getCustomMediaFromRoot from './lib/custom-media-from-root'; +import getCustomMediaFromImports from './lib/get-custom-media-from-imports'; import transformAtrules from './lib/transform-atrules'; -import importCustomMediaFromSources from './lib/import-from'; -import exportCustomMediaToDestinations from './lib/export-to'; +import writeCustomMediaToExports from './lib/write-custom-media-to-exports'; export default postcss.plugin('postcss-custom-media', opts => { - // whether to preserve custom selectors and rules using them - const preserve = Boolean(Object(opts).preserve); + // whether to preserve custom media and at-rules using them + const preserve = 'preserve' in Object(opts) ? Boolean(opts.preserve) : false; - // sources to import custom selectors from + // sources to import custom media from const importFrom = [].concat(Object(opts).importFrom || []); - // destinations to export custom selectors to + // destinations to export custom media to const exportTo = [].concat(Object(opts).exportTo || []); - // promise any custom selectors are imported - const customMediaPromise = importCustomMediaFromSources(importFrom); + // promise any custom media are imported + const customMediaPromise = getCustomMediaFromImports(importFrom); return async root => { const customMedia = Object.assign( await customMediaPromise, - getCustomMedia(root, { preserve }) + getCustomMediaFromRoot(root, { preserve }) ); - await exportCustomMediaToDestinations(customMedia, exportTo); + await writeCustomMediaToExports(customMedia, exportTo); transformAtrules(root, customMedia, { preserve }); }; diff --git a/lib/import-from.js b/lib/get-custom-media-from-imports.js similarity index 56% rename from lib/import-from.js rename to lib/get-custom-media-from-imports.js index 47038f6e21..562b3f016b 100644 --- a/lib/import-from.js +++ b/lib/get-custom-media-from-imports.js @@ -4,30 +4,24 @@ import postcss from 'postcss'; import getMediaAstFromMediaString from './media-ast-from-string'; import getCustomMedia from './custom-media-from-root'; -/* Import Custom Media from CSS AST +/* Get Custom Media from CSS File /* ========================================================================== */ -function importCustomMediaFromCSSAST(root) { - return getCustomMedia(root, { preserve: true }); -} - -/* Import Custom Media from CSS File -/* ========================================================================== */ +async function getCustomMediaFromCSSFile(from) { + const css = await readFile(from); + const root = postcss.parse(css, { from }); -async function importCustomMediaFromCSSFile(from) { - const css = await readFile(path.resolve(from)); - const root = postcss.parse(css, { from: path.resolve(from) }); - - return importCustomMediaFromCSSAST(root); + return getCustomMedia(root, { preserve: true }); } -/* Import Custom Media from Object +/* Get Custom Media from Object /* ========================================================================== */ -function importCustomMediaFromObject(object) { +function getCustomMediaFromObject(object) { const customMedia = Object.assign( {}, - Object(object).customMedia || Object(object)['custom-media'] + Object(object).customMedia, + Object(object)['custom-media'] ); for (const key in customMedia) { @@ -37,28 +31,28 @@ function importCustomMediaFromObject(object) { return customMedia; } -/* Import Custom Media from JSON file +/* Get Custom Media from JSON file /* ========================================================================== */ -async function importCustomMediaFromJSONFile(from) { - const object = await readJSON(path.resolve(from)); +async function getCustomMediaFromJSONFile(from) { + const object = await readJSON(from); - return importCustomMediaFromObject(object); + return getCustomMediaFromObject(object); } -/* Import Custom Media from JS file +/* Get Custom Media from JS file /* ========================================================================== */ -async function importCustomMediaFromJSFile(from) { - const object = await import(path.resolve(from)); +async function getCustomMediaFromJSFile(from) { + const object = await import(from); - return importCustomMediaFromObject(object); + return getCustomMediaFromObject(object); } -/* Import Custom Media from Sources +/* Get Custom Media from Sources /* ========================================================================== */ -export default function importCustomMediaFromSources(sources) { +export default function getCustomMediaFromSources(sources) { return sources.map(source => { if (source instanceof Promise) { return source; @@ -75,7 +69,7 @@ export default function importCustomMediaFromSources(sources) { } // source pathname - const from = String(opts.from || ''); + const from = path.resolve(String(opts.from || '')); // type of file being read from const type = (opts.type || path.extname(from).slice(1)).toLowerCase(); @@ -84,23 +78,19 @@ export default function importCustomMediaFromSources(sources) { }).reduce(async (customMedia, source) => { const { type, from } = await source; - if (type === 'ast') { - return Object.assign(customMedia, importCustomMediaFromCSSAST(from)); - } - if (type === 'css') { - return Object.assign(customMedia, await importCustomMediaFromCSSFile(from)); + return Object.assign(await customMedia, await getCustomMediaFromCSSFile(from)); } if (type === 'js') { - return Object.assign(customMedia, await importCustomMediaFromJSFile(from)); + return Object.assign(await customMedia, await getCustomMediaFromJSFile(from)); } if (type === 'json') { - return Object.assign(customMedia, await importCustomMediaFromJSONFile(from)); + return Object.assign(await customMedia, await getCustomMediaFromJSONFile(from)); } - return Object.assign(customMedia, importCustomMediaFromObject(await source)); + return Object.assign(await customMedia, getCustomMediaFromObject(await source)); }, {}); } diff --git a/lib/export-to.js b/lib/write-custom-media-to-exports.js similarity index 80% rename from lib/export-to.js rename to lib/write-custom-media-to-exports.js index e92518df22..8828efc227 100644 --- a/lib/export-to.js +++ b/lib/write-custom-media-to-exports.js @@ -1,10 +1,10 @@ import fs from 'fs'; import path from 'path'; -/* Import Custom Media from CSS File +/* Write Custom Media from CSS File /* ========================================================================== */ -async function exportCustomMediaToCssFile(to, customMedia) { +async function writeCustomMediaToCssFile(to, customMedia) { const cssContent = Object.keys(customMedia).reduce((cssLines, name) => { cssLines.push(`@custom-media ${name} ${customMedia[name]};`); @@ -15,10 +15,10 @@ async function exportCustomMediaToCssFile(to, customMedia) { await writeFile(to, css); } -/* Import Custom Media from JSON file +/* Write Custom Media from JSON file /* ========================================================================== */ -async function exportCustomMediaToJsonFile(to, customMedia) { +async function writeCustomMediaToJsonFile(to, customMedia) { const jsonContent = JSON.stringify({ 'custom-media': customMedia }, null, ' '); @@ -27,10 +27,10 @@ async function exportCustomMediaToJsonFile(to, customMedia) { await writeFile(to, json); } -/* Import Custom Media from Common JS file +/* Write Custom Media from Common JS file /* ========================================================================== */ -async function exportCustomMediaToCjsFile(to, customMedia) { +async function writeCustomMediaToCjsFile(to, customMedia) { const jsContents = Object.keys(customMedia).reduce((jsLines, name) => { jsLines.push(`\t\t'${escapeForJS(name)}': '${escapeForJS(customMedia[name])}'`); @@ -41,10 +41,10 @@ async function exportCustomMediaToCjsFile(to, customMedia) { await writeFile(to, js); } -/* Import Custom Media from Module JS file +/* Write Custom Media from Module JS file /* ========================================================================== */ -async function exportCustomMediaToMjsFile(to, customMedia) { +async function writeCustomMediaToMjsFile(to, customMedia) { const mjsContents = Object.keys(customMedia).reduce((mjsLines, name) => { mjsLines.push(`\t'${escapeForJS(name)}': '${escapeForJS(customMedia[name])}'`); @@ -55,10 +55,10 @@ async function exportCustomMediaToMjsFile(to, customMedia) { await writeFile(to, mjs); } -/* Export Custom Media to Destinations +/* Write Custom Media to Exports /* ========================================================================== */ -export default function exportCustomMediaToDestinations(customMedia, destinations) { +export default function writeCustomMediaToExports(customMedia, destinations) { return Promise.all(destinations.map(async destination => { if (destination instanceof Function) { await destination(defaultCustomMediaToJSON(customMedia)); @@ -86,19 +86,19 @@ export default function exportCustomMediaToDestinations(customMedia, destination const customMediaJSON = toJSON(customMedia); if (type === 'css') { - await exportCustomMediaToCssFile(to, customMediaJSON); + await writeCustomMediaToCssFile(to, customMediaJSON); } if (type === 'js') { - await exportCustomMediaToCjsFile(to, customMediaJSON); + await writeCustomMediaToCjsFile(to, customMediaJSON); } if (type === 'json') { - await exportCustomMediaToJsonFile(to, customMediaJSON); + await writeCustomMediaToJsonFile(to, customMediaJSON); } if (type === 'mjs') { - await exportCustomMediaToMjsFile(to, customMediaJSON); + await writeCustomMediaToMjsFile(to, customMediaJSON); } } } diff --git a/package.json b/package.json index 2a36668dff..b24419dd22 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "postcss-custom-media", - "version": "7.0.4", + "version": "7.0.5", "description": "Use Custom Media Queries in CSS", "author": "Jonathan Neal ", "contributors": [ @@ -27,18 +27,18 @@ "node": ">=6.0.0" }, "dependencies": { - "postcss": "^7.0.2" + "postcss": "^7.0.5" }, "devDependencies": { - "@babel/core": "^7.1.0", + "@babel/core": "^7.1.2", "@babel/plugin-syntax-dynamic-import": "^7.0.0", "@babel/preset-env": "^7.1.0", - "babel-eslint": "^9.0.0", - "eslint": "^5.6.0", + "babel-eslint": "^10.0.1", + "eslint": "^5.6.1", "eslint-config-dev": "^2.0.0", "postcss-tape": "^2.2.0", "pre-commit": "^1.2.2", - "rollup": "^0.66.2", + "rollup": "^0.66.4", "rollup-plugin-babel": "^4.0.3" }, "eslintConfig": { From 619435166b96bfdfc70c9ce095131556d19c9fe8 Mon Sep 17 00:00:00 2001 From: Jonathan Neal Date: Wed, 10 Oct 2018 09:21:23 -0400 Subject: [PATCH 736/795] 5.0.0 --- .editorconfig | 8 +- .gitattributes | 1 - .gitignore | 12 +- .rollup.js | 16 + .tape.js | 13 + .travis.yml | 18 +- CHANGELOG.md | 33 +- CONTRIBUTING.md | 65 + INSTALL.md | 149 ++ LICENSE | 6 - LICENSE.md | 18 + README.md | 117 +- index.js | 158 +- package-lock.json | 3531 -------------------------------- package.json | 100 +- test.js | 61 - test/basic.css | 13 + test/basic.expect.css | 13 + test/basic.preserve.expect.css | 18 + 19 files changed, 595 insertions(+), 3755 deletions(-) delete mode 100755 .gitattributes create mode 100644 .rollup.js create mode 100644 .tape.js create mode 100644 CONTRIBUTING.md create mode 100644 INSTALL.md delete mode 100644 LICENSE create mode 100644 LICENSE.md delete mode 100644 package-lock.json delete mode 100644 test.js create mode 100644 test/basic.css create mode 100644 test/basic.expect.css create mode 100644 test/basic.preserve.expect.css diff --git a/.editorconfig b/.editorconfig index e7bbe21364..e06d7982bc 100644 --- a/.editorconfig +++ b/.editorconfig @@ -4,12 +4,12 @@ root = true charset = utf-8 end_of_line = lf indent_style = tab -tab_width = 2 insert_final_newline = true trim_trailing_whitespace = true -[*.{md,yml}] -indent_style = space - [*.md] trim_trailing_whitespace = false + +[*.{json,md,yml}] +indent_size = 2 +indent_style = space diff --git a/.gitattributes b/.gitattributes deleted file mode 100755 index 176a458f94..0000000000 --- a/.gitattributes +++ /dev/null @@ -1 +0,0 @@ -* text=auto diff --git a/.gitignore b/.gitignore index 76b1021d09..94065768da 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,11 @@ -.nyc_output -coverage node_modules +index.*.js +package-lock.json +*.log* +*.result.css +.* +!.editorconfig +!.gitignore +!.rollup.js +!.tape.js +!.travis.yml diff --git a/.rollup.js b/.rollup.js new file mode 100644 index 0000000000..ecc7800364 --- /dev/null +++ b/.rollup.js @@ -0,0 +1,16 @@ +import babel from 'rollup-plugin-babel'; + +export default { + input: 'index.js', + output: [ + { file: 'index.cjs.js', format: 'cjs' }, + { file: 'index.es.js', format: 'es' } + ], + plugins: [ + babel({ + presets: [ + ['@babel/env', { modules: false, targets: { node: 6 } }] + ] + }) + ] +}; diff --git a/.tape.js b/.tape.js new file mode 100644 index 0000000000..39705733a2 --- /dev/null +++ b/.tape.js @@ -0,0 +1,13 @@ +module.exports = { + 'postcss-color-gray': { + 'basic': { + message: 'supports basic usage' + }, + 'basic:preserve': { + message: 'supports { preserve: true } usage', + options: { + preserve: true + } + } + } +}; diff --git a/.travis.yml b/.travis.yml index d0134fae41..e1f11a52e6 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,13 +1,9 @@ -branches: - except: /^v\d/ +# https://docs.travis-ci.com/user/travis-lint + language: node_js + node_js: - - '4' - - node -script: if [[ `node --version` != v4.* ]]; - then npm test; - else node test.js; - fi; -after_script: if [[ `node --version` != v4.* ]]; - then node_modules/.bin/nyc report --reporter=text-lcov | npx coveralls; - fi; + - 6 + +install: + - npm install --ignore-scripts diff --git a/CHANGELOG.md b/CHANGELOG.md index 3c06b6a5b0..c4e555a61c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,32 +1,39 @@ -# 4.1.0 - 2017-12-19 +# Changes to PostCSS Gray + +### 5.0.0 (July 26, 2018) + +- Rewritten to follow the latest [CSSWG specification](https://drafts.csswg.org/css-color/#grays) +- Added: Compatibility with PostCSS v7. + +# 4.1.0 - December 19, 2017 - Changed: relicense ([MIT](https://opensource.org/licenses/MIT) → [ISC](https://opensource.org/licenses/ISC)) - Updated dependencies -# 4.0.0 - 2017-05-15 +# 4.0.0 - May 15, 2017 - - Added: compatibility with postcss v6.x + - Added: compatibility with PostCSS v6 - Updated dependencies -# 3.0.1 - 2016-11-28 +# 3.0.1 - November 28, 2016 - Bump `color` dependency version (@KenanY) -# 3.0.0 - 2015-09-08 +# 3.0.0 - September 8, 2015 -- Added: compatibility with postcss v5.x -- Removed: compatibility with postcss v4.x +- Added: compatibility with PostCSS v5 +- Removed: compatibility with PostCSS v4 -# 2.0.0 - 2015-01-26 +# 2.0.0 - January 26, 2015 -- Added: compatibility with postcss v4.x -- Removed: compatibility with postcss v3.x +- Added: compatibility with PostCSS v4 +- Removed: compatibility with PostCSS v3 -# 1.1.0 - 2014-11-25 +# 1.1.0 - November 25, 2014 - Changed: Enhanced exceptions -# 1.0.0 - 2014-11-01 +# 1.0.0 - November 1, 2014 -Initial release +- Initial release diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 0000000000..2ea9fdac09 --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,65 @@ +# Contributing to PostCSS Gray + +You want to help? You rock! Now, take a moment to be sure your contributions +make sense to everyone else. + +## Reporting Issues + +Found a problem? Want a new feature? + +- See if your issue or idea has [already been reported]. +- Provide a [reduced test case] or a [live example]. + +Remember, a bug is a _demonstrable problem_ caused by _our_ code. + +## Submitting Pull Requests + +Pull requests are the greatest contributions, so be sure they are focused in +scope and avoid unrelated commits. + +1. To begin; [fork this project], clone your fork, and add our upstream. + ```bash + # Clone your fork of the repo into the current directory + git clone git@github.com:YOUR_USER/postcss-color-gray.git + + # Navigate to the newly cloned directory + cd postcss-color-gray + + # Assign the original repo to a remote called "upstream" + git remote add upstream git@github.com:postcss/postcss-color-gray.git + + # Install the tools necessary for testing + npm install + ``` + +2. Create a branch for your feature or fix: + ```bash + # Move into a new branch for your feature + git checkout -b feature/thing + ``` + ```bash + # Move into a new branch for your fix + git checkout -b fix/something + ``` + +3. If your code follows our practices, then push your feature branch: + ```bash + # Test current code + npm test + ``` + ```bash + # Push the branch for your new feature + git push origin feature/thing + ``` + ```bash + # Or, push the branch for your update + git push origin update/something + ``` + +That’s it! Now [open a pull request] with a clear title and description. + +[already been reported]: issues +[fork this project]: fork +[live example]: https://codepen.io/pen +[open a pull request]: https://help.github.com/articles/using-pull-requests/ +[reduced test case]: https://css-tricks.com/reduced-test-cases/ diff --git a/INSTALL.md b/INSTALL.md new file mode 100644 index 0000000000..be445cf67c --- /dev/null +++ b/INSTALL.md @@ -0,0 +1,149 @@ +# Installing PostCSS Gray + +[PostCSS Gray] runs in all Node environments, with special instructions for: + +| [Node](#node) | [Webpack](#webpack) | [Create React App](#create-react-app) | [Gulp](#gulp) | [Grunt](#grunt) | +| --- | --- | --- | --- | --- | + +## Node + +Add [PostCSS Gray] to your project: + +```bash +npm install postcss-color-gray --save-dev +``` + +Use [PostCSS Gray] to process your CSS: + +```js +import postcssGray from 'postcss-color-gray'; + +postcssGray.process(YOUR_CSS /*, processOptions, pluginOptions */); +``` + +Or use it as a [PostCSS] plugin: + +```js +import postcss from 'postcss'; +import postcssGray from 'postcss-color-gray'; + +postcss([ + postcssGray(/* pluginOptions */) +]).process(YOUR_CSS /*, processOptions */); +``` + +## Webpack + +Add [PostCSS Loader] to your project: + +```bash +npm install postcss-loader --save-dev +``` + +Use [PostCSS Gray] in your Webpack configuration: + +```js +import postcssGray from 'postcss-color-gray'; + +module.exports = { + module: { + rules: [ + { + test: /\.css$/, + use: [ + 'style-loader', + { loader: 'css-loader', options: { importLoaders: 1 } }, + { loader: 'postcss-loader', options: { + ident: 'postcss', + plugins: () => [ + postcssGray(/* pluginOptions */) + ] + } } + ] + } + ] + } +} +``` + +## Create React App + +Add [React App Rewired] and [React App Rewire PostCSS] to your project: + +```bash +npm install react-app-rewired react-app-rewire-postcss --save-dev +``` + +Use [React App Rewire PostCSS] and [PostCSS Gray] in your +`config-overrides.js` file: + +```js +import reactAppRewirePostcss from 'react-app-rewire-postcss'; +import postcssGray from 'postcss-color-gray'; + +export default config => reactAppRewirePostcss(config, { + plugins: () => [ + postcssGray(/* pluginOptions */) + ] +}); +``` + +## Gulp + +Add [Gulp PostCSS] to your project: + +```bash +npm install gulp-postcss --save-dev +``` + +Use [PostCSS Gray] in your Gulpfile: + +```js +import postcss from 'gulp-postcss'; +import postcssGray from 'postcss-color-gray'; + +gulp.task('css', () => gulp.src('./src/*.css').pipe( + postcss([ + postcssGray(/* pluginOptions */) + ]) +).pipe( + gulp.dest('.') +)); +``` + +## Grunt + +Add [Grunt PostCSS] to your project: + +```bash +npm install grunt-postcss --save-dev +``` + +Use [PostCSS Gray] in your Gruntfile: + +```js +import postcssGray from 'postcss-color-gray'; + +grunt.loadNpmTasks('grunt-postcss'); + +grunt.initConfig({ + postcss: { + options: { + use: [ + postcssGray(/* pluginOptions */) + ] + }, + dist: { + src: '*.css' + } + } +}); +``` + +[Gulp PostCSS]: https://github.com/postcss/gulp-postcss +[Grunt PostCSS]: https://github.com/nDmitry/grunt-postcss +[PostCSS]: https://github.com/postcss/postcss +[PostCSS Loader]: https://github.com/postcss/postcss-loader +[PostCSS Gray]: https://github.com/postcss/postcss-color-gray +[React App Rewire PostCSS]: https://github.com/csstools/react-app-rewire-postcss +[React App Rewired]: https://github.com/timarney/react-app-rewired diff --git a/LICENSE b/LICENSE deleted file mode 100644 index cd1b1332d2..0000000000 --- a/LICENSE +++ /dev/null @@ -1,6 +0,0 @@ -ISC License (ISC) -Copyright 2017 Shinnosuke Watanabe - -Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted, provided that the above copyright notice and this permission notice appear in all copies. - -THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. diff --git a/LICENSE.md b/LICENSE.md new file mode 100644 index 0000000000..137301dc54 --- /dev/null +++ b/LICENSE.md @@ -0,0 +1,18 @@ +# ISC License (ISC) + +## Copyright 2018 Shinnosuke Watanabe + +Permission to use, copy, modify, and/or distribute this software for any +purpose with or without fee is hereby granted, provided that the above +copyright notice and this permission notice appear in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH +REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND +FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, +INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM +LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR +OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR +PERFORMANCE OF THIS SOFTWARE. + +For more information, please see +https://opensource.org/licenses/ISC. diff --git a/README.md b/README.md index c0919f93f5..63e6ed07c6 100644 --- a/README.md +++ b/README.md @@ -1,76 +1,97 @@ -# postcss-color-gray +# PostCSS Gray [PostCSS][postcss] -[![CSS Standard Status](https://jonathantneal.github.io/css-db/badge/css-color-grays.svg)](https://jonathantneal.github.io/css-db/#css-color-grays) -[![Build Status](https://travis-ci.org/postcss/postcss-color-gray.svg?branch=master)](https://travis-ci.org/postcss/postcss-color-gray) -[![Coverage Status](https://img.shields.io/coveralls/postcss/postcss-color-gray.svg)](https://coveralls.io/r/postcss/postcss-color-gray) +[![NPM Version][npm-img]][npm-url] +[![CSS Standard Status][css-img]][css-url] +[![Build Status][cli-img]][cli-url] +[![Support Chat][git-img]][git-url] -[PostCSS](https://github.com/postcss/postcss) plugin to transform [gray()](http://dev.w3.org/csswg/css-color/#grays) function to today's CSS +[PostCSS Gray] lets you use the `gray()` color function in CSS, following the +[CSSWG Specification]. -```css -.foo { - color: gray(0); +```pcss +body { + background-color: gray(100); + color: gray(0 / 90%); } -.bar { - color: gray(255, 50%); -} +/* becomes */ -.baz { - color: gray; +body { + background-color: rgb(255,255,255); + color: rgba(0,0,0,.9); } ``` -↓ - -```css -.foo { - color: rgb(0, 0, 0); -} +## Usage -.bar { - color: rgba(255, 255, 255, 0.5); -} +Add [PostCSS Gray] to your project: -.baz { - color: gray; -} +```bash +npm install postcss-color-gray --save-dev ``` -## Installation - -[![NPM version](https://badge.fury.io/js/postcss-color-gray.svg)](https://www.npmjs.org/package/postcss-color-gray) +Use [PostCSS Gray] to process your CSS: -[Use npm](https://www.npmjs.org/doc/cli/npm-install.html). +```js +import postcssGray from 'postcss-color-gray'; -``` -npm install postcss-color-gray +postcssGray.process(YOUR_CSS /*, processOptions, pluginOptions */); ``` -## API +Or use it as a [PostCSS] plugin: -```javascript -var postcssColorGray = require('postcss-color-gray'); +```js +import postcss from 'postcss'; +import postcssGray from 'postcss-color-gray'; + +postcss([ + postcssGray(/* pluginOptions */) +]).process(YOUR_CSS /*, processOptions */); ``` -### postcssColorGray() +[PostCSS Gray] runs in all Node environments, with special instructions for: + +| [Node](INSTALL.md#node) | [Webpack](INSTALL.md#webpack) | [Create React App](INSTALL.md#create-react-app) | [Gulp](INSTALL.md#gulp) | [Grunt](INSTALL.md#grunt) | +| --- | --- | --- | --- | --- | -Return: `Function` +## Options -It converts `gray(A)` to `rgb(A,A,A)`, and converts `gray(A,B)` to `rgba(A,A,A,B)`. +### preserve -```javascript -var postcss = require('postcss'); -var colorGray = require('postcss-color-gray'); +The `preserve` option determines whether the original `gray()` function should +be preserved or replaced. By default, the `gray()` function is replaced. -postcss() - .use(colorGray()) - .process('a {color: gray(85); background-color: gray(10%, .25)}') - .css; -//=> 'a {color: rgb(85, 85, 85); background-color: rgba(26, 26, 26, 0.25)}' +By setting `preserve` to `true`, the original `gray()` function is preserved. + +```js +postcssGray({ preserve: true }); ``` -*Note that [gray() may have a keyword argument to specify a color via "luminance"](http://dev.w3.org/csswg/css-color/#issue-658bb235). Current version of postcss-color-gray doesn't support this feature.* +```pcss +body { + background-color: gray(100); + color: gray(0 / 90%); +} -## License +/* becomes */ + +body { + background-color: gray(100); + background-color: rgb(255,255,255); + color: gray(0 / 90%); + color: rgba(0,0,0,.9); +} +``` -[ISC License](./LICENSE) © 2017 Shinnosuke Watanabe +[cli-img]: https://img.shields.io/travis/postcss/postcss-color-gray.svg +[cli-url]: https://travis-ci.org/postcss/postcss-color-gray +[css-img]: https://cssdb.org/badge/gray-function.svg +[css-url]: https://cssdb.org/#gray-function +[git-img]: https://img.shields.io/badge/support-chat-blue.svg +[git-url]: https://gitter.im/postcss/postcss +[npm-img]: https://img.shields.io/npm/v/postcss-color-gray.svg +[npm-url]: https://www.npmjs.com/package/postcss-color-gray + +[PostCSS]: https://github.com/postcss/postcss +[PostCSS Gray]: https://github.com/postcss/postcss-color-gray +[CSSWG Specification]: https://drafts.csswg.org/css-color/#grays diff --git a/index.js b/index.js index 2982ea15a7..667309bf1c 100644 --- a/index.js +++ b/index.js @@ -1,48 +1,134 @@ -'use strict'; +import postcss from 'postcss'; +import parser from 'postcss-values-parser'; +import { lab2rgb } from '@csstools/convert-colors'; -const color = require('color'); -const postcss = require('postcss'); -const helpers = require('postcss-message-helpers'); -const reduceFunctionCall = require('reduce-function-call'); +export default postcss.plugin('postcss-color-gray', opts => root => { + // walk all declarations likely containing a gray() function + root.walkDecls(decl => { + if (hasGrayFunction(decl)) { + const { value: originalValue } = decl; -const pluginName = 'postcss-color-gray'; -const errorContext = {plugin: pluginName}; + // parse the declaration value + const ast = parser(originalValue).parse(); -function parseAlpha(alpha) { - if (alpha) { - const match = alpha.match(/^\d(\d|\.)+?%$/); + // walk every node in the value that contains a gray() function + ast.walk(node => { + const [lightness, alpha] = getFunctionGrayArgs(node); - if (match && match[0] === alpha) { - return parseFloat(alpha) * 0.01; - } - } + if (lightness !== undefined) { + // rename the gray() function to rgb() + node.value = 'rgb'; - return alpha; -} + // convert the lab gray lightness into rgb + const [r, g, b] = lab2rgb(lightness, 0, 0).map( + channel => Math.max(Math.min(Math.round(channel * 2.55), 255), 0) + ); -function parseGray(decl) { - return reduceFunctionCall(decl.value, 'gray', body => { - if (body.startsWith(',') || body.endsWith(',')) { - throw decl.error(`Unable to parse color from string "gray(${body})"`, errorContext); - } + // preserve the slash nodes within rgb() + const openingSlash = node.first; + const closingSlash = node.last; - const args = postcss.list.comma(body); - const lightness = args[0]; - const alpha = parseAlpha(args[1]); - const rgb = `${lightness},${lightness},${lightness}`; + node.removeAll() + // replace the contents of rgb with `(r,g,b` + .append(openingSlash) + .append(parser.number({ value: r })) + .append(parser.comma({ value: ',' })) + .append(parser.number({ value: g })) + .append(parser.comma({ value: ',' })) + .append(parser.number({ value: b })) - try { - return color(alpha ? `rgba(${rgb},${alpha})` : `rgb(${rgb})`).rgb().string(); - } catch (err) { - throw decl.error(`Unable to parse color from string "gray(${args})"`, errorContext); - } - }); -} + // if an alpha channel was defined + if (alpha < 1) { + // rename the rgb() function to rgba() + node.value += 'a'; + + node + // append the contents of rgba with `,a` + .append(parser.comma({ value: ',' })) + .append(parser.number({ value: alpha })); + } + + // append the contents of rgb/rgba with `)` + node.append(closingSlash); + } + }); -module.exports = postcss.plugin(pluginName, () => function(root) { - root.walkDecls(function(decl) { - if (decl.value && decl.value.includes('gray(')) { - decl.value = helpers.try(parseGray.bind(this, decl), decl.source); + const modifiedValue = ast.toString(); + + // if the modified value has changed from the original value + if (originalValue !== modifiedValue) { + // if the original gray() color is to be preserved + if (Object(opts).preserve) { + // insert the declaration value with the fallback before the current declaration + decl.cloneBefore({ + value: modifiedValue + }); + } else { + // otherwise, overwrite the declaration value with the fallback + decl.value = modifiedValue; + } + } } }); }); + +// return whether a string contains a gray() function +const hasGrayFunctionRegExp = /(^|[^\w-])gray\(/i; +const hasGrayFunction = decl => hasGrayFunctionRegExp.test(Object(decl).value); + +// return whether a node matches a specific type +const isNumber = node => Object(node).type === 'number'; +const isOperator = node => Object(node).type === 'operator'; +const isFunction = node => Object(node).type === 'func'; +const isCalcRegExp = /^calc$/i; +const isFunctionCalc = node => isFunction(node) && isCalcRegExp.test(node.value); +const isGrayRegExp = /^gray$/i; +const isFunctionGrayWithArgs = node => isFunction(node) && isGrayRegExp.test(node.value) && node.nodes && node.nodes.length; +const isNumberPercentage = node => isNumber(node) && node.unit === '%'; +const isNumberUnitless = node => isNumber(node) && node.unit === ''; +const isOperatorSlash = node => isOperator(node) && node.value === '/'; + +// return valid values from a node, otherwise undefined +const getNumberUnitless = node => isNumberUnitless(node) ? Number(node.value) : undefined; +const getOperatorSlash = node => isOperatorSlash(node) ? null : undefined; +const getAlpha = node => isFunctionCalc(node) + ? String(node) +: isNumberUnitless(node) + ? Number(node.value) +: isNumberPercentage(node) + ? Number(node.value) / 100 +: undefined; + +// return valid arguments from a gray() function +const functionalGrayArgs = [getNumberUnitless, getOperatorSlash, getAlpha]; +const getFunctionGrayArgs = node => { + const validArgs = []; + + // if the node is a gray() function with arguments + if (isFunctionGrayWithArgs(node)) { + // get all the gray() function arguments between `(` and `)` + const nodes = node.nodes.slice(1, -1); + + // validate each argument + for (const index in nodes) { + const arg = typeof functionalGrayArgs[index] === 'function' ? functionalGrayArgs[index](nodes[index]) : undefined; + + // if the argument was validated + if (arg !== undefined) { + // push any non-null argument to the valid arguments array + if (arg !== null) { + validArgs.push(arg); + } + } else { + // otherwise, return an empty array + return []; + } + } + + // return the valid arguments array + return validArgs; + } else { + // otherwise, return an empty array + return []; + } +} diff --git a/package-lock.json b/package-lock.json deleted file mode 100644 index 0cdf775e6d..0000000000 --- a/package-lock.json +++ /dev/null @@ -1,3531 +0,0 @@ -{ - "name": "postcss-color-gray", - "version": "4.1.0", - "lockfileVersion": 1, - "requires": true, - "dependencies": { - "@shinnn/eslint-config": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/@shinnn/eslint-config/-/eslint-config-5.0.0.tgz", - "integrity": "sha512-PTwC+LB5FK+RBmJzCvHlDbp1yVT6pW0P4KcXFxEizJv3YNj21l8TezmbEM5E22AQrrtpPkXuFtJ8Dphit5SC6A==", - "dev": true, - "requires": { - "eslint-plugin-no-use-extend-native": "0.3.12", - "eslint-plugin-node": "5.2.1" - } - }, - "@shinnn/eslint-config-node": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/@shinnn/eslint-config-node/-/eslint-config-node-5.0.0.tgz", - "integrity": "sha512-76g40UhvDpgBfmWI1gGkFFRsZXE5pzOcS1aWC6NcPkxuOPGtqEv26b9DscApPA7by5XS8htPfJeDN6l9Eudf0g==", - "dev": true, - "requires": { - "@shinnn/eslint-config": "5.0.0" - } - }, - "@sindresorhus/df": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/@sindresorhus/df/-/df-2.1.0.tgz", - "integrity": "sha1-0gjPJ+BvC7R20U197M19cm6ao4k=", - "dev": true, - "requires": { - "execa": "0.2.2" - } - }, - "acorn": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-5.2.1.tgz", - "integrity": "sha512-jG0u7c4Ly+3QkkW18V+NRDN+4bWHdln30NL1ZL2AvFZZmQe/BfopYCtghCKKVBUSetZ4QKcyA0pY6/4Gw8Pv8w==", - "dev": true - }, - "acorn-jsx": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-3.0.1.tgz", - "integrity": "sha1-r9+UiPsezvyDSPb7IvRk4ypYs2s=", - "dev": true, - "requires": { - "acorn": "3.3.0" - }, - "dependencies": { - "acorn": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-3.3.0.tgz", - "integrity": "sha1-ReN/s56No/JbruP/U2niu18iAXo=", - "dev": true - } - } - }, - "agent-base": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-2.1.1.tgz", - "integrity": "sha1-1t4Q1a9hMtW9aSQn1G/FOFOQlMc=", - "dev": true, - "requires": { - "extend": "3.0.1", - "semver": "5.0.3" - }, - "dependencies": { - "semver": { - "version": "5.0.3", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.0.3.tgz", - "integrity": "sha1-d0Zt5YnNXTyV8TiqeLxWmjy10no=", - "dev": true - } - } - }, - "ajv": { - "version": "5.5.2", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-5.5.2.tgz", - "integrity": "sha1-c7Xuyj+rZT49P5Qis0GtQiBdyWU=", - "dev": true, - "requires": { - "co": "4.6.0", - "fast-deep-equal": "1.0.0", - "fast-json-stable-stringify": "2.0.0", - "json-schema-traverse": "0.3.1" - } - }, - "ajv-keywords": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-2.1.1.tgz", - "integrity": "sha1-YXmX/F9gV2iUxDX5QNgZ4TW4B2I=", - "dev": true - }, - "ansi-escapes": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-3.0.0.tgz", - "integrity": "sha512-O/klc27mWNUigtv0F8NJWbLF00OcegQalkqKURWdosW08YZKi4m6CnSUSvIZG1otNJbTWhN01Hhz389DW7mvDQ==", - "dev": true - }, - "ansi-regex": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", - "dev": true - }, - "ansi-styles": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.0.tgz", - "integrity": "sha512-NnSOmMEYtVR2JVMIGTzynRkkaxtiq1xnFBcdQD/DnNCYPoEPsVJhM98BDyaoNOQIi7p4okdi3E27eN7GQbsUug==", - "requires": { - "color-convert": "1.9.1" - } - }, - "argparse": { - "version": "1.0.9", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.9.tgz", - "integrity": "sha1-c9g7wmP4bpf4zE9rrhsOkKfSLIY=", - "dev": true, - "requires": { - "sprintf-js": "1.0.3" - } - }, - "array-union": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/array-union/-/array-union-1.0.2.tgz", - "integrity": "sha1-mjRBDk9OPaI96jdb5b5w8kd47Dk=", - "dev": true, - "requires": { - "array-uniq": "1.0.3" - } - }, - "array-uniq": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/array-uniq/-/array-uniq-1.0.3.tgz", - "integrity": "sha1-r2rId6Jcx/dOBYiUdThY39sk/bY=", - "dev": true - }, - "arrify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", - "integrity": "sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=", - "dev": true - }, - "babel-code-frame": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-code-frame/-/babel-code-frame-6.26.0.tgz", - "integrity": "sha1-Y/1D99weO7fONZR9uP42mj9Yx0s=", - "dev": true, - "requires": { - "chalk": "1.1.3", - "esutils": "2.0.2", - "js-tokens": "3.0.2" - }, - "dependencies": { - "ansi-styles": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", - "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", - "dev": true - }, - "chalk": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", - "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", - "dev": true, - "requires": { - "ansi-styles": "2.2.1", - "escape-string-regexp": "1.0.5", - "has-ansi": "2.0.0", - "strip-ansi": "3.0.1", - "supports-color": "2.0.0" - } - }, - "strip-ansi": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", - "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", - "dev": true, - "requires": { - "ansi-regex": "2.1.1" - } - }, - "supports-color": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", - "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", - "dev": true - } - } - }, - "balanced-match": { - "version": "0.4.2", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-0.4.2.tgz", - "integrity": "sha1-yz8+PHMtwPAe5wtAPzAuYddwmDg=" - }, - "brace-expansion": { - "version": "1.1.8", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.8.tgz", - "integrity": "sha1-wHshHHyVLsH479Uad+8NHTmQopI=", - "dev": true, - "requires": { - "balanced-match": "1.0.0", - "concat-map": "0.0.1" - }, - "dependencies": { - "balanced-match": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", - "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", - "dev": true - } - } - }, - "caller-path": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/caller-path/-/caller-path-0.1.0.tgz", - "integrity": "sha1-lAhe9jWB7NPaqSREqP6U6CV3dR8=", - "dev": true, - "requires": { - "callsites": "0.2.0" - } - }, - "callsites": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/callsites/-/callsites-0.2.0.tgz", - "integrity": "sha1-r6uWJikQp/M8GaV3WCXGnzTjUMo=", - "dev": true - }, - "chalk": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.3.0.tgz", - "integrity": "sha512-Az5zJR2CBujap2rqXGaJKaPHyJ0IrUimvYNX+ncCy8PJP4ltOGTrHUIo097ZaL2zMeKYpiCdqDvS6zdrTFok3Q==", - "requires": { - "ansi-styles": "3.2.0", - "escape-string-regexp": "1.0.5", - "supports-color": "4.5.0" - } - }, - "chardet": { - "version": "0.4.2", - "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.4.2.tgz", - "integrity": "sha1-tUc7M9yXxCTl2Y3IfVXU2KKci/I=", - "dev": true - }, - "checkup": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/checkup/-/checkup-1.3.0.tgz", - "integrity": "sha1-04ACdv6l0PJH/8lRvnjIsC+ODXY=", - "dev": true - }, - "circular-json": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/circular-json/-/circular-json-0.3.3.tgz", - "integrity": "sha512-UZK3NBx2Mca+b5LsG7bY183pHWt5Y1xts4P3Pz7ENTwGVnJOUWbRb3ocjvX7hx9tq/yTAdclXm9sZ38gNuem4A==", - "dev": true - }, - "cli-cursor": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-2.1.0.tgz", - "integrity": "sha1-s12sN2R5+sw+lHR9QdDQ9SOP/LU=", - "dev": true, - "requires": { - "restore-cursor": "2.0.0" - } - }, - "cli-width": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-2.2.0.tgz", - "integrity": "sha1-/xnt6Kml5XkyQUewwR8PvLq+1jk=", - "dev": true - }, - "co": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", - "integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ=", - "dev": true - }, - "color": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color/-/color-2.0.1.tgz", - "integrity": "sha512-ubUCVVKfT7r2w2D3qtHakj8mbmKms+tThR8gI8zEYCbUBl8/voqFGt3kgBqGwXAopgXybnkuOq+qMYCRrp4cXw==", - "requires": { - "color-convert": "1.9.1", - "color-string": "1.5.2" - } - }, - "color-convert": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.1.tgz", - "integrity": "sha512-mjGanIiwQJskCC18rPR6OmrZ6fm2Lc7PeGFYwCmy5J34wC6F1PzdGL6xeMfmgicfYcNLGuVFA3WzXtIDCQSZxQ==", - "requires": { - "color-name": "1.1.3" - } - }, - "color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=" - }, - "color-string": { - "version": "1.5.2", - "resolved": "https://registry.npmjs.org/color-string/-/color-string-1.5.2.tgz", - "integrity": "sha1-JuRYFLw8mny9Z1FkikFDRRSnc6k=", - "requires": { - "color-name": "1.1.3", - "simple-swizzle": "0.2.2" - } - }, - "concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", - "dev": true - }, - "concat-stream": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.0.tgz", - "integrity": "sha1-CqxmL9Ur54lk1VMvaUeE5wEQrPc=", - "dev": true, - "requires": { - "inherits": "2.0.3", - "readable-stream": "2.3.3", - "typedarray": "0.0.6" - } - }, - "core-util-is": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", - "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=", - "dev": true - }, - "cross-spawn": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-5.1.0.tgz", - "integrity": "sha1-6L0O/uWPz/b4+UUQoKVUu/ojVEk=", - "dev": true, - "requires": { - "lru-cache": "4.1.1", - "shebang-command": "1.2.0", - "which": "1.3.0" - } - }, - "cross-spawn-async": { - "version": "2.2.5", - "resolved": "https://registry.npmjs.org/cross-spawn-async/-/cross-spawn-async-2.2.5.tgz", - "integrity": "sha1-hF/wwINKPe2dFg2sptOQkGuyiMw=", - "dev": true, - "requires": { - "lru-cache": "4.1.1", - "which": "1.3.0" - } - }, - "debug": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", - "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "deep-equal": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/deep-equal/-/deep-equal-1.0.1.tgz", - "integrity": "sha1-9dJgKStmDghO/0zbyfCK0yR0SLU=", - "dev": true - }, - "deep-is": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz", - "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=", - "dev": true - }, - "define-properties": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.2.tgz", - "integrity": "sha1-g6c/L+pWmJj7c3GTyPhzyvbUXJQ=", - "dev": true, - "requires": { - "foreach": "2.0.5", - "object-keys": "1.0.11" - } - }, - "defined": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/defined/-/defined-1.0.0.tgz", - "integrity": "sha1-yY2bzvdWdBiOEQlpFRGZ45sfppM=", - "dev": true - }, - "del": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/del/-/del-2.2.2.tgz", - "integrity": "sha1-wSyYHQZ4RshLyvhiz/kw2Qf/0ag=", - "dev": true, - "requires": { - "globby": "5.0.0", - "is-path-cwd": "1.0.0", - "is-path-in-cwd": "1.0.0", - "object-assign": "4.1.1", - "pify": "2.3.0", - "pinkie-promise": "2.0.1", - "rimraf": "2.6.2" - } - }, - "doctrine": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.0.2.tgz", - "integrity": "sha512-y0tm5Pq6ywp3qSTZ1vPgVdAnbDEoeoc5wlOHXoY1c4Wug/a7JvqHIl7BTvwodaHmejWkK/9dSb3sCYfyo/om8A==", - "dev": true, - "requires": { - "esutils": "2.0.2" - } - }, - "es-abstract": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.10.0.tgz", - "integrity": "sha512-/uh/DhdqIOSkAWifU+8nG78vlQxdLckUdI/sPgy0VhuXi2qJ7T8czBmqIYtLQVpCIFYafChnsRsB5pyb1JdmCQ==", - "dev": true, - "requires": { - "es-to-primitive": "1.1.1", - "function-bind": "1.1.1", - "has": "1.0.1", - "is-callable": "1.1.3", - "is-regex": "1.0.4" - } - }, - "es-to-primitive": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.1.1.tgz", - "integrity": "sha1-RTVSSKiJeQNLZ5Lhm7gfK3l13Q0=", - "dev": true, - "requires": { - "is-callable": "1.1.3", - "is-date-object": "1.0.1", - "is-symbol": "1.0.1" - } - }, - "escape-string-applescript": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/escape-string-applescript/-/escape-string-applescript-1.0.0.tgz", - "integrity": "sha1-bxwilCRdgsY7wDM43BmpSqhCiJI=", - "dev": true - }, - "escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=" - }, - "eslint": { - "version": "4.13.1", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-4.13.1.tgz", - "integrity": "sha512-UCJVV50RtLHYzBp1DZ8CMPtRSg4iVZvjgO9IJHIKyWU/AnJVjtdRikoUPLB29n5pzMB7TnsLQWf0V6VUJfoPfw==", - "dev": true, - "requires": { - "ajv": "5.5.2", - "babel-code-frame": "6.26.0", - "chalk": "2.3.0", - "concat-stream": "1.6.0", - "cross-spawn": "5.1.0", - "debug": "3.1.0", - "doctrine": "2.0.2", - "eslint-scope": "3.7.1", - "espree": "3.5.2", - "esquery": "1.0.0", - "estraverse": "4.2.0", - "esutils": "2.0.2", - "file-entry-cache": "2.0.0", - "functional-red-black-tree": "1.0.1", - "glob": "7.1.2", - "globals": "11.1.0", - "ignore": "3.3.7", - "imurmurhash": "0.1.4", - "inquirer": "3.3.0", - "is-resolvable": "1.0.1", - "js-yaml": "3.10.0", - "json-stable-stringify-without-jsonify": "1.0.1", - "levn": "0.3.0", - "lodash": "4.17.4", - "minimatch": "3.0.4", - "mkdirp": "0.5.1", - "natural-compare": "1.4.0", - "optionator": "0.8.2", - "path-is-inside": "1.0.2", - "pluralize": "7.0.0", - "progress": "2.0.0", - "require-uncached": "1.0.3", - "semver": "5.3.0", - "strip-ansi": "4.0.0", - "strip-json-comments": "2.0.1", - "table": "4.0.2", - "text-table": "0.2.0" - } - }, - "eslint-plugin-no-use-extend-native": { - "version": "0.3.12", - "resolved": "https://registry.npmjs.org/eslint-plugin-no-use-extend-native/-/eslint-plugin-no-use-extend-native-0.3.12.tgz", - "integrity": "sha1-OtmgDC3yO11/f2vpFVCYWkq3Aeo=", - "dev": true, - "requires": { - "is-get-set-prop": "1.0.0", - "is-js-type": "2.0.0", - "is-obj-prop": "1.0.0", - "is-proto-prop": "1.0.0" - } - }, - "eslint-plugin-node": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/eslint-plugin-node/-/eslint-plugin-node-5.2.1.tgz", - "integrity": "sha512-xhPXrh0Vl/b7870uEbaumb2Q+LxaEcOQ3kS1jtIXanBAwpMre1l5q/l2l/hESYJGEFKuI78bp6Uw50hlpr7B+g==", - "dev": true, - "requires": { - "ignore": "3.3.7", - "minimatch": "3.0.4", - "resolve": "1.5.0", - "semver": "5.3.0" - } - }, - "eslint-scope": { - "version": "3.7.1", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-3.7.1.tgz", - "integrity": "sha1-PWPD7f2gLgbgGkUq2IyqzHzctug=", - "dev": true, - "requires": { - "esrecurse": "4.2.0", - "estraverse": "4.2.0" - } - }, - "espree": { - "version": "3.5.2", - "resolved": "https://registry.npmjs.org/espree/-/espree-3.5.2.tgz", - "integrity": "sha512-sadKeYwaR/aJ3stC2CdvgXu1T16TdYN+qwCpcWbMnGJ8s0zNWemzrvb2GbD4OhmJ/fwpJjudThAlLobGbWZbCQ==", - "dev": true, - "requires": { - "acorn": "5.2.1", - "acorn-jsx": "3.0.1" - } - }, - "esprima": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.0.tgz", - "integrity": "sha512-oftTcaMu/EGrEIu904mWteKIv8vMuOgGYo7EhVJJN00R/EED9DCua/xxHRdYnKtcECzVg7xOWhflvJMnqcFZjw==", - "dev": true - }, - "esquery": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.0.0.tgz", - "integrity": "sha1-z7qLV9f7qT8XKYqKAGoEzaE9gPo=", - "dev": true, - "requires": { - "estraverse": "4.2.0" - } - }, - "esrecurse": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.2.0.tgz", - "integrity": "sha1-+pVo2Y04I/mkHZHpAtyrnqblsWM=", - "dev": true, - "requires": { - "estraverse": "4.2.0", - "object-assign": "4.1.1" - } - }, - "estraverse": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.2.0.tgz", - "integrity": "sha1-De4/7TH81GlhjOc0IJn8GvoL2xM=", - "dev": true - }, - "esutils": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.2.tgz", - "integrity": "sha1-Cr9PHKpbyx96nYrMbepPqqBLrJs=", - "dev": true - }, - "execa": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/execa/-/execa-0.2.2.tgz", - "integrity": "sha1-4urUcsLDGq1vc/GslW7vReEjIMs=", - "dev": true, - "requires": { - "cross-spawn-async": "2.2.5", - "npm-run-path": "1.0.0", - "object-assign": "4.1.1", - "path-key": "1.0.0", - "strip-eof": "1.0.0" - } - }, - "execon": { - "version": "1.2.9", - "resolved": "https://registry.npmjs.org/execon/-/execon-1.2.9.tgz", - "integrity": "sha1-bbETM9zIJPHxPnMX/tDZSi8mSR8=", - "dev": true - }, - "extend": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.1.tgz", - "integrity": "sha1-p1Xqe8Gt/MWjHOfnYtuq3F5jZEQ=", - "dev": true - }, - "external-editor": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-2.1.0.tgz", - "integrity": "sha512-E44iT5QVOUJBKij4IIV3uvxuNlbKS38Tw1HiupxEIHPv9qtC2PrDYohbXV5U+1jnfIXttny8gUhj+oZvflFlzA==", - "dev": true, - "requires": { - "chardet": "0.4.2", - "iconv-lite": "0.4.19", - "tmp": "0.0.33" - } - }, - "fast-deep-equal": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-1.0.0.tgz", - "integrity": "sha1-liVqO8l1WV6zbYLpkp0GDYk0Of8=", - "dev": true - }, - "fast-json-stable-stringify": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz", - "integrity": "sha1-1RQsDK7msRifh9OnYREGT4bIu/I=", - "dev": true - }, - "fast-levenshtein": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", - "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", - "dev": true - }, - "figures": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/figures/-/figures-2.0.0.tgz", - "integrity": "sha1-OrGi0qYsi/tDGgyUy3l6L84nyWI=", - "dev": true, - "requires": { - "escape-string-regexp": "1.0.5" - } - }, - "file-entry-cache": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-2.0.0.tgz", - "integrity": "sha1-w5KZDD5oR4PYOLjISkXYoEhFg2E=", - "dev": true, - "requires": { - "flat-cache": "1.3.0", - "object-assign": "4.1.1" - } - }, - "flat-cache": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-1.3.0.tgz", - "integrity": "sha1-0wMLMrOBVPTjt+nHCfSQ9++XxIE=", - "dev": true, - "requires": { - "circular-json": "0.3.3", - "del": "2.2.2", - "graceful-fs": "4.1.11", - "write": "0.2.1" - } - }, - "follow-redirects": { - "version": "0.0.7", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-0.0.7.tgz", - "integrity": "sha1-NLkLqyqRGqNHVx2pDyK9NuzYqRk=", - "dev": true, - "requires": { - "debug": "2.6.9", - "stream-consume": "0.1.0" - }, - "dependencies": { - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - } - } - }, - "for-each": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.2.tgz", - "integrity": "sha1-LEBFC5NI6X8oEyJZO6lnBLmr1NQ=", - "dev": true, - "requires": { - "is-function": "1.0.1" - } - }, - "foreach": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/foreach/-/foreach-2.0.5.tgz", - "integrity": "sha1-C+4AUBiusmDQo6865ljdATbsG5k=", - "dev": true - }, - "fs-extra": { - "version": "0.26.7", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-0.26.7.tgz", - "integrity": "sha1-muH92UiXeY7at20JGM9C0MMYT6k=", - "dev": true, - "requires": { - "graceful-fs": "4.1.11", - "jsonfile": "2.4.0", - "klaw": "1.3.1", - "path-is-absolute": "1.0.1", - "rimraf": "2.6.2" - } - }, - "fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", - "dev": true - }, - "function-bind": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", - "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", - "dev": true - }, - "functional-red-black-tree": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", - "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=", - "dev": true - }, - "get-set-props": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/get-set-props/-/get-set-props-0.1.0.tgz", - "integrity": "sha1-mYR1wXhEVobQsyJG2l3428++jqM=", - "dev": true - }, - "github": { - "version": "11.0.0", - "resolved": "https://registry.npmjs.org/github/-/github-11.0.0.tgz", - "integrity": "sha1-7bMt9e+zPK0ATr8L3SpLMLtjqFQ=", - "dev": true, - "requires": { - "follow-redirects": "0.0.7", - "https-proxy-agent": "1.0.0", - "mime": "1.6.0", - "netrc": "0.1.4" - } - }, - "github-release-from-changelog": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/github-release-from-changelog/-/github-release-from-changelog-1.3.0.tgz", - "integrity": "sha512-WXIdtpdVCSC2Pz8U7pA1047lMxxneDy7lTuRBqGqopBtLXTzpwaBeZJcnC2AXykuq2Fory07Q+yUtDyqOaip3g==", - "dev": true, - "requires": { - "grizzly": "2.1.5", - "minimist": "1.2.0" - }, - "dependencies": { - "minimist": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", - "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", - "dev": true - } - } - }, - "glob": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz", - "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==", - "dev": true, - "requires": { - "fs.realpath": "1.0.0", - "inflight": "1.0.6", - "inherits": "2.0.3", - "minimatch": "3.0.4", - "once": "1.4.0", - "path-is-absolute": "1.0.1" - } - }, - "globals": { - "version": "11.1.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-11.1.0.tgz", - "integrity": "sha512-uEuWt9mqTlPDwSqi+sHjD4nWU/1N+q0fiWI9T1mZpD2UENqX20CFD5T/ziLZvztPaBKl7ZylUi1q6Qfm7E2CiQ==", - "dev": true - }, - "globby": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/globby/-/globby-5.0.0.tgz", - "integrity": "sha1-69hGZ8oNuzMLmbz8aOrCvFQ3Dg0=", - "dev": true, - "requires": { - "array-union": "1.0.2", - "arrify": "1.0.1", - "glob": "7.1.2", - "object-assign": "4.1.1", - "pify": "2.3.0", - "pinkie-promise": "2.0.1" - } - }, - "graceful-fs": { - "version": "4.1.11", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.11.tgz", - "integrity": "sha1-Dovf5NHduIVNZOBOp8AOKgJuVlg=", - "dev": true - }, - "grizzly": { - "version": "2.1.5", - "resolved": "https://registry.npmjs.org/grizzly/-/grizzly-2.1.5.tgz", - "integrity": "sha512-GnfH/XDglF6ltXfllWrxXxzC+XcZHFaVBzEsXxorPSPuCxFfAW/eDGsu4b/ItWfH3oVZp4U/TVaZU8UlqsoZqg==", - "dev": true, - "requires": { - "checkup": "1.3.0", - "debug": "3.1.0", - "execon": "1.2.9", - "github": "11.0.0", - "minimist": "1.2.0", - "os-homedir": "1.0.2", - "readjson": "1.1.3" - }, - "dependencies": { - "minimist": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", - "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", - "dev": true - } - } - }, - "has": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/has/-/has-1.0.1.tgz", - "integrity": "sha1-hGFzP1OLCDfJNh45qauelwTcLyg=", - "dev": true, - "requires": { - "function-bind": "1.1.1" - } - }, - "has-ansi": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", - "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=", - "dev": true, - "requires": { - "ansi-regex": "2.1.1" - } - }, - "has-flag": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz", - "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=" - }, - "https-proxy-agent": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-1.0.0.tgz", - "integrity": "sha1-NffabEjOTdv6JkiRrFk+5f+GceY=", - "dev": true, - "requires": { - "agent-base": "2.1.1", - "debug": "2.6.9", - "extend": "3.0.1" - }, - "dependencies": { - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - } - } - }, - "iconv-lite": { - "version": "0.4.19", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.19.tgz", - "integrity": "sha512-oTZqweIP51xaGPI4uPa56/Pri/480R+mo7SeU+YETByQNhDG55ycFyNLIgta9vXhILrxXDmF7ZGhqZIcuN0gJQ==", - "dev": true - }, - "ignore": { - "version": "3.3.7", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-3.3.7.tgz", - "integrity": "sha512-YGG3ejvBNHRqu0559EOxxNFihD0AjpvHlC/pdGKd3X3ofe+CoJkYazwNJYTNebqpPKN+VVQbh4ZFn1DivMNuHA==", - "dev": true - }, - "imurmurhash": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", - "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", - "dev": true - }, - "inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", - "dev": true, - "requires": { - "once": "1.4.0", - "wrappy": "1.0.2" - } - }, - "inherits": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", - "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", - "dev": true - }, - "inquirer": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-3.3.0.tgz", - "integrity": "sha512-h+xtnyk4EwKvFWHrUYsWErEVR+igKtLdchu+o0Z1RL7VU/jVMFbYir2bp6bAj8efFNxWqHX0dIss6fJQ+/+qeQ==", - "dev": true, - "requires": { - "ansi-escapes": "3.0.0", - "chalk": "2.3.0", - "cli-cursor": "2.1.0", - "cli-width": "2.2.0", - "external-editor": "2.1.0", - "figures": "2.0.0", - "lodash": "4.17.4", - "mute-stream": "0.0.7", - "run-async": "2.3.0", - "rx-lite": "4.0.8", - "rx-lite-aggregates": "4.0.8", - "string-width": "2.1.1", - "strip-ansi": "4.0.0", - "through": "2.3.8" - } - }, - "is-arrayish": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.3.1.tgz", - "integrity": "sha1-wt/DhquqDD4zxI2z/ocFnmkGXv0=" - }, - "is-callable": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.1.3.tgz", - "integrity": "sha1-hut1OSgF3cM69xySoO7fdO52BLI=", - "dev": true - }, - "is-date-object": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.1.tgz", - "integrity": "sha1-mqIOtq7rv/d/vTPnTKAbM1gdOhY=", - "dev": true - }, - "is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", - "dev": true - }, - "is-function": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-function/-/is-function-1.0.1.tgz", - "integrity": "sha1-Es+5i2W1fdPRk6MSH19uL0N2ArU=", - "dev": true - }, - "is-get-set-prop": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-get-set-prop/-/is-get-set-prop-1.0.0.tgz", - "integrity": "sha1-JzGHfk14pqae3M5rudaLB3nnYxI=", - "dev": true, - "requires": { - "get-set-props": "0.1.0", - "lowercase-keys": "1.0.0" - } - }, - "is-js-type": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-js-type/-/is-js-type-2.0.0.tgz", - "integrity": "sha1-c2FwBtZZtOtHKbunR9KHgt8PfiI=", - "dev": true, - "requires": { - "js-types": "1.0.0" - } - }, - "is-obj-prop": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-obj-prop/-/is-obj-prop-1.0.0.tgz", - "integrity": "sha1-s03nnEULjXxzqyzfZ9yHWtuF+A4=", - "dev": true, - "requires": { - "lowercase-keys": "1.0.0", - "obj-props": "1.1.0" - } - }, - "is-path-cwd": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-path-cwd/-/is-path-cwd-1.0.0.tgz", - "integrity": "sha1-0iXsIxMuie3Tj9p2dHLmLmXxEG0=", - "dev": true - }, - "is-path-in-cwd": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-path-in-cwd/-/is-path-in-cwd-1.0.0.tgz", - "integrity": "sha1-ZHdYK4IU1gI0YJRWcAO+ip6sBNw=", - "dev": true, - "requires": { - "is-path-inside": "1.0.1" - } - }, - "is-path-inside": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-1.0.1.tgz", - "integrity": "sha1-jvW33lBDej/cprToZe96pVy0gDY=", - "dev": true, - "requires": { - "path-is-inside": "1.0.2" - } - }, - "is-promise": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-2.1.0.tgz", - "integrity": "sha1-eaKp7OfwlugPNtKy87wWwf9L8/o=", - "dev": true - }, - "is-proto-prop": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-proto-prop/-/is-proto-prop-1.0.0.tgz", - "integrity": "sha1-s5UflcCJkk+11PzaZUKrPoPisiA=", - "dev": true, - "requires": { - "lowercase-keys": "1.0.0", - "proto-props": "0.2.1" - } - }, - "is-regex": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.0.4.tgz", - "integrity": "sha1-VRdIm1RwkbCTDglWVM7SXul+lJE=", - "dev": true, - "requires": { - "has": "1.0.1" - } - }, - "is-resolvable": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-resolvable/-/is-resolvable-1.0.1.tgz", - "integrity": "sha512-y5CXYbzvB3jTnWAZH1Nl7ykUWb6T3BcTs56HUruwBf8MhF56n1HWqhDWnVFo8GHrUPDgvUUNVhrc2U8W7iqz5g==", - "dev": true - }, - "is-symbol": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.1.tgz", - "integrity": "sha1-PMWfAAJRlLarLjjbrmaJJWtmBXI=", - "dev": true - }, - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", - "dev": true - }, - "isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", - "dev": true - }, - "js-tokens": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-3.0.2.tgz", - "integrity": "sha1-mGbfOVECEw449/mWvOtlRDIJwls=", - "dev": true - }, - "js-types": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/js-types/-/js-types-1.0.0.tgz", - "integrity": "sha1-0kLmSU7Vcq08koCfyL7X92h8vwM=", - "dev": true - }, - "js-yaml": { - "version": "3.10.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.10.0.tgz", - "integrity": "sha512-O2v52ffjLa9VeM43J4XocZE//WT9N0IiwDa3KSHH7Tu8CtH+1qM8SIZvnsTh6v+4yFy5KUY3BHUVwjpfAWsjIA==", - "dev": true, - "requires": { - "argparse": "1.0.9", - "esprima": "4.0.0" - } - }, - "json-schema-traverse": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.3.1.tgz", - "integrity": "sha1-NJptRMU6Ud6JtAgFxdXlm0F9M0A=", - "dev": true - }, - "json-stable-stringify-without-jsonify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", - "integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=", - "dev": true - }, - "jsonfile": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-2.4.0.tgz", - "integrity": "sha1-NzaitCi4e72gzIO1P6PWM6NcKug=", - "dev": true, - "requires": { - "graceful-fs": "4.1.11" - } - }, - "klaw": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/klaw/-/klaw-1.3.1.tgz", - "integrity": "sha1-QIhDO0azsbolnXh4XY6W9zugJDk=", - "dev": true, - "requires": { - "graceful-fs": "4.1.11" - } - }, - "levn": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", - "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=", - "dev": true, - "requires": { - "prelude-ls": "1.1.2", - "type-check": "0.3.2" - } - }, - "lodash": { - "version": "4.17.4", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.4.tgz", - "integrity": "sha1-eCA6TRwyiuHYbcpkYONptX9AVa4=", - "dev": true - }, - "lowercase-keys": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-1.0.0.tgz", - "integrity": "sha1-TjNms55/VFfjXxMkvfb4jQv8cwY=", - "dev": true - }, - "lru-cache": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.1.tgz", - "integrity": "sha512-q4spe4KTfsAS1SUHLO0wz8Qiyf1+vMIAgpRYioFYDMNqKfHQbg+AVDH3i4fvpl71/P1L0dBl+fQi+P37UYf0ew==", - "dev": true, - "requires": { - "pseudomap": "1.0.2", - "yallist": "2.1.2" - } - }, - "mime": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", - "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", - "dev": true - }, - "mimic-fn": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-1.1.0.tgz", - "integrity": "sha1-5md4PZLonb00KBi1IwudYqZyrRg=", - "dev": true - }, - "minimatch": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", - "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", - "dev": true, - "requires": { - "brace-expansion": "1.1.8" - } - }, - "minimist": { - "version": "0.0.8", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", - "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=", - "dev": true - }, - "mkdirp": { - "version": "0.5.1", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", - "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", - "dev": true, - "requires": { - "minimist": "0.0.8" - } - }, - "mount-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/mount-point/-/mount-point-3.0.0.tgz", - "integrity": "sha1-Zly57evoDREOZY21bDHQrvUaj5c=", - "dev": true, - "requires": { - "@sindresorhus/df": "1.0.1", - "pify": "2.3.0", - "pinkie-promise": "2.0.1" - }, - "dependencies": { - "@sindresorhus/df": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@sindresorhus/df/-/df-1.0.1.tgz", - "integrity": "sha1-xptm9S9vzdKHyAffIQMF2694UA0=", - "dev": true - } - } - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", - "dev": true - }, - "mute-stream": { - "version": "0.0.7", - "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.7.tgz", - "integrity": "sha1-MHXOk7whuPq0PhvE2n6BFe0ee6s=", - "dev": true - }, - "natural-compare": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", - "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=", - "dev": true - }, - "netrc": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/netrc/-/netrc-0.1.4.tgz", - "integrity": "sha1-a+lPysqNd63gqWcNxGCRTJRHJEQ=", - "dev": true - }, - "npm-run-path": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-1.0.0.tgz", - "integrity": "sha1-9cMr9ZX+ga6Sfa7FLoL4sACsPI8=", - "dev": true, - "requires": { - "path-key": "1.0.0" - } - }, - "npmpub": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/npmpub/-/npmpub-3.1.0.tgz", - "integrity": "sha1-c0OoAf+xi/0s7CM1hLkUWa5O4Uk=", - "dev": true, - "requires": { - "chalk": "1.1.3", - "github-release-from-changelog": "1.3.0", - "minimist": "1.2.0", - "shelljs": "0.5.3", - "trash": "3.4.2" - }, - "dependencies": { - "ansi-styles": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", - "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", - "dev": true - }, - "chalk": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", - "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", - "dev": true, - "requires": { - "ansi-styles": "2.2.1", - "escape-string-regexp": "1.0.5", - "has-ansi": "2.0.0", - "strip-ansi": "3.0.1", - "supports-color": "2.0.0" - } - }, - "minimist": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", - "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", - "dev": true - }, - "strip-ansi": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", - "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", - "dev": true, - "requires": { - "ansi-regex": "2.1.1" - } - }, - "supports-color": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", - "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", - "dev": true - } - } - }, - "nyc": { - "version": "11.4.1", - "resolved": "https://registry.npmjs.org/nyc/-/nyc-11.4.1.tgz", - "integrity": "sha512-5eCZpvaksFVjP2rt1r60cfXmt3MUtsQDw8bAzNqNEr4WLvUMLgiVENMf/B9bE9YAX0mGVvaGA3v9IS9ekNqB1Q==", - "dev": true, - "requires": { - "archy": "1.0.0", - "arrify": "1.0.1", - "caching-transform": "1.0.1", - "convert-source-map": "1.5.1", - "debug-log": "1.0.1", - "default-require-extensions": "1.0.0", - "find-cache-dir": "0.1.1", - "find-up": "2.1.0", - "foreground-child": "1.5.6", - "glob": "7.1.2", - "istanbul-lib-coverage": "1.1.1", - "istanbul-lib-hook": "1.1.0", - "istanbul-lib-instrument": "1.9.1", - "istanbul-lib-report": "1.1.2", - "istanbul-lib-source-maps": "1.2.2", - "istanbul-reports": "1.1.3", - "md5-hex": "1.3.0", - "merge-source-map": "1.0.4", - "micromatch": "2.3.11", - "mkdirp": "0.5.1", - "resolve-from": "2.0.0", - "rimraf": "2.6.2", - "signal-exit": "3.0.2", - "spawn-wrap": "1.4.2", - "test-exclude": "4.1.1", - "yargs": "10.0.3", - "yargs-parser": "8.0.0" - }, - "dependencies": { - "align-text": { - "version": "0.1.4", - "bundled": true, - "dev": true, - "requires": { - "kind-of": "3.2.2", - "longest": "1.0.1", - "repeat-string": "1.6.1" - } - }, - "amdefine": { - "version": "1.0.1", - "bundled": true, - "dev": true - }, - "ansi-regex": { - "version": "2.1.1", - "bundled": true, - "dev": true - }, - "ansi-styles": { - "version": "2.2.1", - "bundled": true, - "dev": true - }, - "append-transform": { - "version": "0.4.0", - "bundled": true, - "dev": true, - "requires": { - "default-require-extensions": "1.0.0" - } - }, - "archy": { - "version": "1.0.0", - "bundled": true, - "dev": true - }, - "arr-diff": { - "version": "2.0.0", - "bundled": true, - "dev": true, - "requires": { - "arr-flatten": "1.1.0" - } - }, - "arr-flatten": { - "version": "1.1.0", - "bundled": true, - "dev": true - }, - "array-unique": { - "version": "0.2.1", - "bundled": true, - "dev": true - }, - "arrify": { - "version": "1.0.1", - "bundled": true, - "dev": true - }, - "async": { - "version": "1.5.2", - "bundled": true, - "dev": true - }, - "babel-code-frame": { - "version": "6.26.0", - "bundled": true, - "dev": true, - "requires": { - "chalk": "1.1.3", - "esutils": "2.0.2", - "js-tokens": "3.0.2" - } - }, - "babel-generator": { - "version": "6.26.0", - "bundled": true, - "dev": true, - "requires": { - "babel-messages": "6.23.0", - "babel-runtime": "6.26.0", - "babel-types": "6.26.0", - "detect-indent": "4.0.0", - "jsesc": "1.3.0", - "lodash": "4.17.4", - "source-map": "0.5.7", - "trim-right": "1.0.1" - } - }, - "babel-messages": { - "version": "6.23.0", - "bundled": true, - "dev": true, - "requires": { - "babel-runtime": "6.26.0" - } - }, - "babel-runtime": { - "version": "6.26.0", - "bundled": true, - "dev": true, - "requires": { - "core-js": "2.5.3", - "regenerator-runtime": "0.11.1" - } - }, - "babel-template": { - "version": "6.26.0", - "bundled": true, - "dev": true, - "requires": { - "babel-runtime": "6.26.0", - "babel-traverse": "6.26.0", - "babel-types": "6.26.0", - "babylon": "6.18.0", - "lodash": "4.17.4" - } - }, - "babel-traverse": { - "version": "6.26.0", - "bundled": true, - "dev": true, - "requires": { - "babel-code-frame": "6.26.0", - "babel-messages": "6.23.0", - "babel-runtime": "6.26.0", - "babel-types": "6.26.0", - "babylon": "6.18.0", - "debug": "2.6.9", - "globals": "9.18.0", - "invariant": "2.2.2", - "lodash": "4.17.4" - } - }, - "babel-types": { - "version": "6.26.0", - "bundled": true, - "dev": true, - "requires": { - "babel-runtime": "6.26.0", - "esutils": "2.0.2", - "lodash": "4.17.4", - "to-fast-properties": "1.0.3" - } - }, - "babylon": { - "version": "6.18.0", - "bundled": true, - "dev": true - }, - "balanced-match": { - "version": "1.0.0", - "bundled": true, - "dev": true - }, - "brace-expansion": { - "version": "1.1.8", - "bundled": true, - "dev": true, - "requires": { - "balanced-match": "1.0.0", - "concat-map": "0.0.1" - } - }, - "braces": { - "version": "1.8.5", - "bundled": true, - "dev": true, - "requires": { - "expand-range": "1.8.2", - "preserve": "0.2.0", - "repeat-element": "1.1.2" - } - }, - "builtin-modules": { - "version": "1.1.1", - "bundled": true, - "dev": true - }, - "caching-transform": { - "version": "1.0.1", - "bundled": true, - "dev": true, - "requires": { - "md5-hex": "1.3.0", - "mkdirp": "0.5.1", - "write-file-atomic": "1.3.4" - } - }, - "camelcase": { - "version": "1.2.1", - "bundled": true, - "dev": true, - "optional": true - }, - "center-align": { - "version": "0.1.3", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "align-text": "0.1.4", - "lazy-cache": "1.0.4" - } - }, - "chalk": { - "version": "1.1.3", - "bundled": true, - "dev": true, - "requires": { - "ansi-styles": "2.2.1", - "escape-string-regexp": "1.0.5", - "has-ansi": "2.0.0", - "strip-ansi": "3.0.1", - "supports-color": "2.0.0" - } - }, - "cliui": { - "version": "2.1.0", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "center-align": "0.1.3", - "right-align": "0.1.3", - "wordwrap": "0.0.2" - }, - "dependencies": { - "wordwrap": { - "version": "0.0.2", - "bundled": true, - "dev": true, - "optional": true - } - } - }, - "code-point-at": { - "version": "1.1.0", - "bundled": true, - "dev": true - }, - "commondir": { - "version": "1.0.1", - "bundled": true, - "dev": true - }, - "concat-map": { - "version": "0.0.1", - "bundled": true, - "dev": true - }, - "convert-source-map": { - "version": "1.5.1", - "bundled": true, - "dev": true - }, - "core-js": { - "version": "2.5.3", - "bundled": true, - "dev": true - }, - "cross-spawn": { - "version": "4.0.2", - "bundled": true, - "dev": true, - "requires": { - "lru-cache": "4.1.1", - "which": "1.3.0" - } - }, - "debug": { - "version": "2.6.9", - "bundled": true, - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "debug-log": { - "version": "1.0.1", - "bundled": true, - "dev": true - }, - "decamelize": { - "version": "1.2.0", - "bundled": true, - "dev": true - }, - "default-require-extensions": { - "version": "1.0.0", - "bundled": true, - "dev": true, - "requires": { - "strip-bom": "2.0.0" - } - }, - "detect-indent": { - "version": "4.0.0", - "bundled": true, - "dev": true, - "requires": { - "repeating": "2.0.1" - } - }, - "error-ex": { - "version": "1.3.1", - "bundled": true, - "dev": true, - "requires": { - "is-arrayish": "0.2.1" - } - }, - "escape-string-regexp": { - "version": "1.0.5", - "bundled": true, - "dev": true - }, - "esutils": { - "version": "2.0.2", - "bundled": true, - "dev": true - }, - "execa": { - "version": "0.7.0", - "bundled": true, - "dev": true, - "requires": { - "cross-spawn": "5.1.0", - "get-stream": "3.0.0", - "is-stream": "1.1.0", - "npm-run-path": "2.0.2", - "p-finally": "1.0.0", - "signal-exit": "3.0.2", - "strip-eof": "1.0.0" - }, - "dependencies": { - "cross-spawn": { - "version": "5.1.0", - "bundled": true, - "dev": true, - "requires": { - "lru-cache": "4.1.1", - "shebang-command": "1.2.0", - "which": "1.3.0" - } - } - } - }, - "expand-brackets": { - "version": "0.1.5", - "bundled": true, - "dev": true, - "requires": { - "is-posix-bracket": "0.1.1" - } - }, - "expand-range": { - "version": "1.8.2", - "bundled": true, - "dev": true, - "requires": { - "fill-range": "2.2.3" - } - }, - "extglob": { - "version": "0.3.2", - "bundled": true, - "dev": true, - "requires": { - "is-extglob": "1.0.0" - } - }, - "filename-regex": { - "version": "2.0.1", - "bundled": true, - "dev": true - }, - "fill-range": { - "version": "2.2.3", - "bundled": true, - "dev": true, - "requires": { - "is-number": "2.1.0", - "isobject": "2.1.0", - "randomatic": "1.1.7", - "repeat-element": "1.1.2", - "repeat-string": "1.6.1" - } - }, - "find-cache-dir": { - "version": "0.1.1", - "bundled": true, - "dev": true, - "requires": { - "commondir": "1.0.1", - "mkdirp": "0.5.1", - "pkg-dir": "1.0.0" - } - }, - "find-up": { - "version": "2.1.0", - "bundled": true, - "dev": true, - "requires": { - "locate-path": "2.0.0" - } - }, - "for-in": { - "version": "1.0.2", - "bundled": true, - "dev": true - }, - "for-own": { - "version": "0.1.5", - "bundled": true, - "dev": true, - "requires": { - "for-in": "1.0.2" - } - }, - "foreground-child": { - "version": "1.5.6", - "bundled": true, - "dev": true, - "requires": { - "cross-spawn": "4.0.2", - "signal-exit": "3.0.2" - } - }, - "fs.realpath": { - "version": "1.0.0", - "bundled": true, - "dev": true - }, - "get-caller-file": { - "version": "1.0.2", - "bundled": true, - "dev": true - }, - "get-stream": { - "version": "3.0.0", - "bundled": true, - "dev": true - }, - "glob": { - "version": "7.1.2", - "bundled": true, - "dev": true, - "requires": { - "fs.realpath": "1.0.0", - "inflight": "1.0.6", - "inherits": "2.0.3", - "minimatch": "3.0.4", - "once": "1.4.0", - "path-is-absolute": "1.0.1" - } - }, - "glob-base": { - "version": "0.3.0", - "bundled": true, - "dev": true, - "requires": { - "glob-parent": "2.0.0", - "is-glob": "2.0.1" - } - }, - "glob-parent": { - "version": "2.0.0", - "bundled": true, - "dev": true, - "requires": { - "is-glob": "2.0.1" - } - }, - "globals": { - "version": "9.18.0", - "bundled": true, - "dev": true - }, - "graceful-fs": { - "version": "4.1.11", - "bundled": true, - "dev": true - }, - "handlebars": { - "version": "4.0.11", - "bundled": true, - "dev": true, - "requires": { - "async": "1.5.2", - "optimist": "0.6.1", - "source-map": "0.4.4", - "uglify-js": "2.8.29" - }, - "dependencies": { - "source-map": { - "version": "0.4.4", - "bundled": true, - "dev": true, - "requires": { - "amdefine": "1.0.1" - } - } - } - }, - "has-ansi": { - "version": "2.0.0", - "bundled": true, - "dev": true, - "requires": { - "ansi-regex": "2.1.1" - } - }, - "has-flag": { - "version": "1.0.0", - "bundled": true, - "dev": true - }, - "hosted-git-info": { - "version": "2.5.0", - "bundled": true, - "dev": true - }, - "imurmurhash": { - "version": "0.1.4", - "bundled": true, - "dev": true - }, - "inflight": { - "version": "1.0.6", - "bundled": true, - "dev": true, - "requires": { - "once": "1.4.0", - "wrappy": "1.0.2" - } - }, - "inherits": { - "version": "2.0.3", - "bundled": true, - "dev": true - }, - "invariant": { - "version": "2.2.2", - "bundled": true, - "dev": true, - "requires": { - "loose-envify": "1.3.1" - } - }, - "invert-kv": { - "version": "1.0.0", - "bundled": true, - "dev": true - }, - "is-arrayish": { - "version": "0.2.1", - "bundled": true, - "dev": true - }, - "is-buffer": { - "version": "1.1.6", - "bundled": true, - "dev": true - }, - "is-builtin-module": { - "version": "1.0.0", - "bundled": true, - "dev": true, - "requires": { - "builtin-modules": "1.1.1" - } - }, - "is-dotfile": { - "version": "1.0.3", - "bundled": true, - "dev": true - }, - "is-equal-shallow": { - "version": "0.1.3", - "bundled": true, - "dev": true, - "requires": { - "is-primitive": "2.0.0" - } - }, - "is-extendable": { - "version": "0.1.1", - "bundled": true, - "dev": true - }, - "is-extglob": { - "version": "1.0.0", - "bundled": true, - "dev": true - }, - "is-finite": { - "version": "1.0.2", - "bundled": true, - "dev": true, - "requires": { - "number-is-nan": "1.0.1" - } - }, - "is-fullwidth-code-point": { - "version": "1.0.0", - "bundled": true, - "dev": true, - "requires": { - "number-is-nan": "1.0.1" - } - }, - "is-glob": { - "version": "2.0.1", - "bundled": true, - "dev": true, - "requires": { - "is-extglob": "1.0.0" - } - }, - "is-number": { - "version": "2.1.0", - "bundled": true, - "dev": true, - "requires": { - "kind-of": "3.2.2" - } - }, - "is-posix-bracket": { - "version": "0.1.1", - "bundled": true, - "dev": true - }, - "is-primitive": { - "version": "2.0.0", - "bundled": true, - "dev": true - }, - "is-stream": { - "version": "1.1.0", - "bundled": true, - "dev": true - }, - "is-utf8": { - "version": "0.2.1", - "bundled": true, - "dev": true - }, - "isarray": { - "version": "1.0.0", - "bundled": true, - "dev": true - }, - "isexe": { - "version": "2.0.0", - "bundled": true, - "dev": true - }, - "isobject": { - "version": "2.1.0", - "bundled": true, - "dev": true, - "requires": { - "isarray": "1.0.0" - } - }, - "istanbul-lib-coverage": { - "version": "1.1.1", - "bundled": true, - "dev": true - }, - "istanbul-lib-hook": { - "version": "1.1.0", - "bundled": true, - "dev": true, - "requires": { - "append-transform": "0.4.0" - } - }, - "istanbul-lib-instrument": { - "version": "1.9.1", - "bundled": true, - "dev": true, - "requires": { - "babel-generator": "6.26.0", - "babel-template": "6.26.0", - "babel-traverse": "6.26.0", - "babel-types": "6.26.0", - "babylon": "6.18.0", - "istanbul-lib-coverage": "1.1.1", - "semver": "5.4.1" - } - }, - "istanbul-lib-report": { - "version": "1.1.2", - "bundled": true, - "dev": true, - "requires": { - "istanbul-lib-coverage": "1.1.1", - "mkdirp": "0.5.1", - "path-parse": "1.0.5", - "supports-color": "3.2.3" - }, - "dependencies": { - "supports-color": { - "version": "3.2.3", - "bundled": true, - "dev": true, - "requires": { - "has-flag": "1.0.0" - } - } - } - }, - "istanbul-lib-source-maps": { - "version": "1.2.2", - "bundled": true, - "dev": true, - "requires": { - "debug": "3.1.0", - "istanbul-lib-coverage": "1.1.1", - "mkdirp": "0.5.1", - "rimraf": "2.6.2", - "source-map": "0.5.7" - }, - "dependencies": { - "debug": { - "version": "3.1.0", - "bundled": true, - "dev": true, - "requires": { - "ms": "2.0.0" - } - } - } - }, - "istanbul-reports": { - "version": "1.1.3", - "bundled": true, - "dev": true, - "requires": { - "handlebars": "4.0.11" - } - }, - "js-tokens": { - "version": "3.0.2", - "bundled": true, - "dev": true - }, - "jsesc": { - "version": "1.3.0", - "bundled": true, - "dev": true - }, - "kind-of": { - "version": "3.2.2", - "bundled": true, - "dev": true, - "requires": { - "is-buffer": "1.1.6" - } - }, - "lazy-cache": { - "version": "1.0.4", - "bundled": true, - "dev": true, - "optional": true - }, - "lcid": { - "version": "1.0.0", - "bundled": true, - "dev": true, - "requires": { - "invert-kv": "1.0.0" - } - }, - "load-json-file": { - "version": "1.1.0", - "bundled": true, - "dev": true, - "requires": { - "graceful-fs": "4.1.11", - "parse-json": "2.2.0", - "pify": "2.3.0", - "pinkie-promise": "2.0.1", - "strip-bom": "2.0.0" - } - }, - "locate-path": { - "version": "2.0.0", - "bundled": true, - "dev": true, - "requires": { - "p-locate": "2.0.0", - "path-exists": "3.0.0" - }, - "dependencies": { - "path-exists": { - "version": "3.0.0", - "bundled": true, - "dev": true - } - } - }, - "lodash": { - "version": "4.17.4", - "bundled": true, - "dev": true - }, - "longest": { - "version": "1.0.1", - "bundled": true, - "dev": true - }, - "loose-envify": { - "version": "1.3.1", - "bundled": true, - "dev": true, - "requires": { - "js-tokens": "3.0.2" - } - }, - "lru-cache": { - "version": "4.1.1", - "bundled": true, - "dev": true, - "requires": { - "pseudomap": "1.0.2", - "yallist": "2.1.2" - } - }, - "md5-hex": { - "version": "1.3.0", - "bundled": true, - "dev": true, - "requires": { - "md5-o-matic": "0.1.1" - } - }, - "md5-o-matic": { - "version": "0.1.1", - "bundled": true, - "dev": true - }, - "mem": { - "version": "1.1.0", - "bundled": true, - "dev": true, - "requires": { - "mimic-fn": "1.1.0" - } - }, - "merge-source-map": { - "version": "1.0.4", - "bundled": true, - "dev": true, - "requires": { - "source-map": "0.5.7" - } - }, - "micromatch": { - "version": "2.3.11", - "bundled": true, - "dev": true, - "requires": { - "arr-diff": "2.0.0", - "array-unique": "0.2.1", - "braces": "1.8.5", - "expand-brackets": "0.1.5", - "extglob": "0.3.2", - "filename-regex": "2.0.1", - "is-extglob": "1.0.0", - "is-glob": "2.0.1", - "kind-of": "3.2.2", - "normalize-path": "2.1.1", - "object.omit": "2.0.1", - "parse-glob": "3.0.4", - "regex-cache": "0.4.4" - } - }, - "mimic-fn": { - "version": "1.1.0", - "bundled": true, - "dev": true - }, - "minimatch": { - "version": "3.0.4", - "bundled": true, - "dev": true, - "requires": { - "brace-expansion": "1.1.8" - } - }, - "minimist": { - "version": "0.0.8", - "bundled": true, - "dev": true - }, - "mkdirp": { - "version": "0.5.1", - "bundled": true, - "dev": true, - "requires": { - "minimist": "0.0.8" - } - }, - "ms": { - "version": "2.0.0", - "bundled": true, - "dev": true - }, - "normalize-package-data": { - "version": "2.4.0", - "bundled": true, - "dev": true, - "requires": { - "hosted-git-info": "2.5.0", - "is-builtin-module": "1.0.0", - "semver": "5.4.1", - "validate-npm-package-license": "3.0.1" - } - }, - "normalize-path": { - "version": "2.1.1", - "bundled": true, - "dev": true, - "requires": { - "remove-trailing-separator": "1.1.0" - } - }, - "npm-run-path": { - "version": "2.0.2", - "bundled": true, - "dev": true, - "requires": { - "path-key": "2.0.1" - } - }, - "number-is-nan": { - "version": "1.0.1", - "bundled": true, - "dev": true - }, - "object-assign": { - "version": "4.1.1", - "bundled": true, - "dev": true - }, - "object.omit": { - "version": "2.0.1", - "bundled": true, - "dev": true, - "requires": { - "for-own": "0.1.5", - "is-extendable": "0.1.1" - } - }, - "once": { - "version": "1.4.0", - "bundled": true, - "dev": true, - "requires": { - "wrappy": "1.0.2" - } - }, - "optimist": { - "version": "0.6.1", - "bundled": true, - "dev": true, - "requires": { - "minimist": "0.0.8", - "wordwrap": "0.0.3" - } - }, - "os-homedir": { - "version": "1.0.2", - "bundled": true, - "dev": true - }, - "os-locale": { - "version": "2.1.0", - "bundled": true, - "dev": true, - "requires": { - "execa": "0.7.0", - "lcid": "1.0.0", - "mem": "1.1.0" - } - }, - "p-finally": { - "version": "1.0.0", - "bundled": true, - "dev": true - }, - "p-limit": { - "version": "1.1.0", - "bundled": true, - "dev": true - }, - "p-locate": { - "version": "2.0.0", - "bundled": true, - "dev": true, - "requires": { - "p-limit": "1.1.0" - } - }, - "parse-glob": { - "version": "3.0.4", - "bundled": true, - "dev": true, - "requires": { - "glob-base": "0.3.0", - "is-dotfile": "1.0.3", - "is-extglob": "1.0.0", - "is-glob": "2.0.1" - } - }, - "parse-json": { - "version": "2.2.0", - "bundled": true, - "dev": true, - "requires": { - "error-ex": "1.3.1" - } - }, - "path-exists": { - "version": "2.1.0", - "bundled": true, - "dev": true, - "requires": { - "pinkie-promise": "2.0.1" - } - }, - "path-is-absolute": { - "version": "1.0.1", - "bundled": true, - "dev": true - }, - "path-key": { - "version": "2.0.1", - "bundled": true, - "dev": true - }, - "path-parse": { - "version": "1.0.5", - "bundled": true, - "dev": true - }, - "path-type": { - "version": "1.1.0", - "bundled": true, - "dev": true, - "requires": { - "graceful-fs": "4.1.11", - "pify": "2.3.0", - "pinkie-promise": "2.0.1" - } - }, - "pify": { - "version": "2.3.0", - "bundled": true, - "dev": true - }, - "pinkie": { - "version": "2.0.4", - "bundled": true, - "dev": true - }, - "pinkie-promise": { - "version": "2.0.1", - "bundled": true, - "dev": true, - "requires": { - "pinkie": "2.0.4" - } - }, - "pkg-dir": { - "version": "1.0.0", - "bundled": true, - "dev": true, - "requires": { - "find-up": "1.1.2" - }, - "dependencies": { - "find-up": { - "version": "1.1.2", - "bundled": true, - "dev": true, - "requires": { - "path-exists": "2.1.0", - "pinkie-promise": "2.0.1" - } - } - } - }, - "preserve": { - "version": "0.2.0", - "bundled": true, - "dev": true - }, - "pseudomap": { - "version": "1.0.2", - "bundled": true, - "dev": true - }, - "randomatic": { - "version": "1.1.7", - "bundled": true, - "dev": true, - "requires": { - "is-number": "3.0.0", - "kind-of": "4.0.0" - }, - "dependencies": { - "is-number": { - "version": "3.0.0", - "bundled": true, - "dev": true, - "requires": { - "kind-of": "3.2.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "bundled": true, - "dev": true, - "requires": { - "is-buffer": "1.1.6" - } - } - } - }, - "kind-of": { - "version": "4.0.0", - "bundled": true, - "dev": true, - "requires": { - "is-buffer": "1.1.6" - } - } - } - }, - "read-pkg": { - "version": "1.1.0", - "bundled": true, - "dev": true, - "requires": { - "load-json-file": "1.1.0", - "normalize-package-data": "2.4.0", - "path-type": "1.1.0" - } - }, - "read-pkg-up": { - "version": "1.0.1", - "bundled": true, - "dev": true, - "requires": { - "find-up": "1.1.2", - "read-pkg": "1.1.0" - }, - "dependencies": { - "find-up": { - "version": "1.1.2", - "bundled": true, - "dev": true, - "requires": { - "path-exists": "2.1.0", - "pinkie-promise": "2.0.1" - } - } - } - }, - "regenerator-runtime": { - "version": "0.11.1", - "bundled": true, - "dev": true - }, - "regex-cache": { - "version": "0.4.4", - "bundled": true, - "dev": true, - "requires": { - "is-equal-shallow": "0.1.3" - } - }, - "remove-trailing-separator": { - "version": "1.1.0", - "bundled": true, - "dev": true - }, - "repeat-element": { - "version": "1.1.2", - "bundled": true, - "dev": true - }, - "repeat-string": { - "version": "1.6.1", - "bundled": true, - "dev": true - }, - "repeating": { - "version": "2.0.1", - "bundled": true, - "dev": true, - "requires": { - "is-finite": "1.0.2" - } - }, - "require-directory": { - "version": "2.1.1", - "bundled": true, - "dev": true - }, - "require-main-filename": { - "version": "1.0.1", - "bundled": true, - "dev": true - }, - "resolve-from": { - "version": "2.0.0", - "bundled": true, - "dev": true - }, - "right-align": { - "version": "0.1.3", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "align-text": "0.1.4" - } - }, - "rimraf": { - "version": "2.6.2", - "bundled": true, - "dev": true, - "requires": { - "glob": "7.1.2" - } - }, - "semver": { - "version": "5.4.1", - "bundled": true, - "dev": true - }, - "set-blocking": { - "version": "2.0.0", - "bundled": true, - "dev": true - }, - "shebang-command": { - "version": "1.2.0", - "bundled": true, - "dev": true, - "requires": { - "shebang-regex": "1.0.0" - } - }, - "shebang-regex": { - "version": "1.0.0", - "bundled": true, - "dev": true - }, - "signal-exit": { - "version": "3.0.2", - "bundled": true, - "dev": true - }, - "slide": { - "version": "1.1.6", - "bundled": true, - "dev": true - }, - "source-map": { - "version": "0.5.7", - "bundled": true, - "dev": true - }, - "spawn-wrap": { - "version": "1.4.2", - "bundled": true, - "dev": true, - "requires": { - "foreground-child": "1.5.6", - "mkdirp": "0.5.1", - "os-homedir": "1.0.2", - "rimraf": "2.6.2", - "signal-exit": "3.0.2", - "which": "1.3.0" - } - }, - "spdx-correct": { - "version": "1.0.2", - "bundled": true, - "dev": true, - "requires": { - "spdx-license-ids": "1.2.2" - } - }, - "spdx-expression-parse": { - "version": "1.0.4", - "bundled": true, - "dev": true - }, - "spdx-license-ids": { - "version": "1.2.2", - "bundled": true, - "dev": true - }, - "string-width": { - "version": "2.1.1", - "bundled": true, - "dev": true, - "requires": { - "is-fullwidth-code-point": "2.0.0", - "strip-ansi": "4.0.0" - }, - "dependencies": { - "ansi-regex": { - "version": "3.0.0", - "bundled": true, - "dev": true - }, - "is-fullwidth-code-point": { - "version": "2.0.0", - "bundled": true, - "dev": true - }, - "strip-ansi": { - "version": "4.0.0", - "bundled": true, - "dev": true, - "requires": { - "ansi-regex": "3.0.0" - } - } - } - }, - "strip-ansi": { - "version": "3.0.1", - "bundled": true, - "dev": true, - "requires": { - "ansi-regex": "2.1.1" - } - }, - "strip-bom": { - "version": "2.0.0", - "bundled": true, - "dev": true, - "requires": { - "is-utf8": "0.2.1" - } - }, - "strip-eof": { - "version": "1.0.0", - "bundled": true, - "dev": true - }, - "supports-color": { - "version": "2.0.0", - "bundled": true, - "dev": true - }, - "test-exclude": { - "version": "4.1.1", - "bundled": true, - "dev": true, - "requires": { - "arrify": "1.0.1", - "micromatch": "2.3.11", - "object-assign": "4.1.1", - "read-pkg-up": "1.0.1", - "require-main-filename": "1.0.1" - } - }, - "to-fast-properties": { - "version": "1.0.3", - "bundled": true, - "dev": true - }, - "trim-right": { - "version": "1.0.1", - "bundled": true, - "dev": true - }, - "uglify-js": { - "version": "2.8.29", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "source-map": "0.5.7", - "uglify-to-browserify": "1.0.2", - "yargs": "3.10.0" - }, - "dependencies": { - "yargs": { - "version": "3.10.0", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "camelcase": "1.2.1", - "cliui": "2.1.0", - "decamelize": "1.2.0", - "window-size": "0.1.0" - } - } - } - }, - "uglify-to-browserify": { - "version": "1.0.2", - "bundled": true, - "dev": true, - "optional": true - }, - "validate-npm-package-license": { - "version": "3.0.1", - "bundled": true, - "dev": true, - "requires": { - "spdx-correct": "1.0.2", - "spdx-expression-parse": "1.0.4" - } - }, - "which": { - "version": "1.3.0", - "bundled": true, - "dev": true, - "requires": { - "isexe": "2.0.0" - } - }, - "which-module": { - "version": "2.0.0", - "bundled": true, - "dev": true - }, - "window-size": { - "version": "0.1.0", - "bundled": true, - "dev": true, - "optional": true - }, - "wordwrap": { - "version": "0.0.3", - "bundled": true, - "dev": true - }, - "wrap-ansi": { - "version": "2.1.0", - "bundled": true, - "dev": true, - "requires": { - "string-width": "1.0.2", - "strip-ansi": "3.0.1" - }, - "dependencies": { - "string-width": { - "version": "1.0.2", - "bundled": true, - "dev": true, - "requires": { - "code-point-at": "1.1.0", - "is-fullwidth-code-point": "1.0.0", - "strip-ansi": "3.0.1" - } - } - } - }, - "wrappy": { - "version": "1.0.2", - "bundled": true, - "dev": true - }, - "write-file-atomic": { - "version": "1.3.4", - "bundled": true, - "dev": true, - "requires": { - "graceful-fs": "4.1.11", - "imurmurhash": "0.1.4", - "slide": "1.1.6" - } - }, - "y18n": { - "version": "3.2.1", - "bundled": true, - "dev": true - }, - "yallist": { - "version": "2.1.2", - "bundled": true, - "dev": true - }, - "yargs": { - "version": "10.0.3", - "bundled": true, - "dev": true, - "requires": { - "cliui": "3.2.0", - "decamelize": "1.2.0", - "find-up": "2.1.0", - "get-caller-file": "1.0.2", - "os-locale": "2.1.0", - "require-directory": "2.1.1", - "require-main-filename": "1.0.1", - "set-blocking": "2.0.0", - "string-width": "2.1.1", - "which-module": "2.0.0", - "y18n": "3.2.1", - "yargs-parser": "8.0.0" - }, - "dependencies": { - "cliui": { - "version": "3.2.0", - "bundled": true, - "dev": true, - "requires": { - "string-width": "1.0.2", - "strip-ansi": "3.0.1", - "wrap-ansi": "2.1.0" - }, - "dependencies": { - "string-width": { - "version": "1.0.2", - "bundled": true, - "dev": true, - "requires": { - "code-point-at": "1.1.0", - "is-fullwidth-code-point": "1.0.0", - "strip-ansi": "3.0.1" - } - } - } - } - } - }, - "yargs-parser": { - "version": "8.0.0", - "bundled": true, - "dev": true, - "requires": { - "camelcase": "4.1.0" - }, - "dependencies": { - "camelcase": { - "version": "4.1.0", - "bundled": true, - "dev": true - } - } - } - } - }, - "obj-props": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/obj-props/-/obj-props-1.1.0.tgz", - "integrity": "sha1-YmMT+qRCvv1KROmgLDy2vek3tRE=", - "dev": true - }, - "object-assign": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", - "dev": true - }, - "object-inspect": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.3.0.tgz", - "integrity": "sha512-OHHnLgLNXpM++GnJRyyhbr2bwl3pPVm4YvaraHrRvDt/N3r+s/gDVHciA7EJBTkijKXj61ssgSAikq1fb0IBRg==", - "dev": true - }, - "object-keys": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.0.11.tgz", - "integrity": "sha1-xUYBd4rVYPEULODgG8yotW0TQm0=", - "dev": true - }, - "once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", - "dev": true, - "requires": { - "wrappy": "1.0.2" - } - }, - "onetime": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-2.0.1.tgz", - "integrity": "sha1-BnQoIw/WdEOyeUsiu6UotoZ5YtQ=", - "dev": true, - "requires": { - "mimic-fn": "1.1.0" - } - }, - "optionator": { - "version": "0.8.2", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.2.tgz", - "integrity": "sha1-NkxeQJ0/TWMB1sC0wFu6UBgK62Q=", - "dev": true, - "requires": { - "deep-is": "0.1.3", - "fast-levenshtein": "2.0.6", - "levn": "0.3.0", - "prelude-ls": "1.1.2", - "type-check": "0.3.2", - "wordwrap": "1.0.0" - } - }, - "os-homedir": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz", - "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=", - "dev": true - }, - "os-tmpdir": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", - "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=", - "dev": true - }, - "path-exists": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-2.1.0.tgz", - "integrity": "sha1-D+tsZPD8UY2adU3V77YscCJ2H0s=", - "dev": true, - "requires": { - "pinkie-promise": "2.0.1" - } - }, - "path-is-absolute": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", - "dev": true - }, - "path-is-inside": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz", - "integrity": "sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM=", - "dev": true - }, - "path-key": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-1.0.0.tgz", - "integrity": "sha1-XVPVeAGWRsDWiADbThRua9wqx68=", - "dev": true - }, - "path-parse": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.5.tgz", - "integrity": "sha1-PBrfhx6pzWyUMbbqK9dKD/BVxME=", - "dev": true - }, - "pify": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", - "dev": true - }, - "pinkie": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz", - "integrity": "sha1-clVrgM+g1IqXToDnckjoDtT3+HA=", - "dev": true - }, - "pinkie-promise": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz", - "integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=", - "dev": true, - "requires": { - "pinkie": "2.0.4" - } - }, - "pluralize": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/pluralize/-/pluralize-7.0.0.tgz", - "integrity": "sha512-ARhBOdzS3e41FbkW/XWrTEtukqqLoK5+Z/4UeDaLuSW+39JPeFgs4gCGqsrJHVZX0fUrx//4OF0K1CUGwlIFow==", - "dev": true - }, - "postcss": { - "version": "6.0.14", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.14.tgz", - "integrity": "sha512-NJ1z0f+1offCgadPhz+DvGm5Mkci+mmV5BqD13S992o0Xk9eElxUfPPF+t2ksH5R/17gz4xVK8KWocUQ5o3Rog==", - "requires": { - "chalk": "2.3.0", - "source-map": "0.6.1", - "supports-color": "4.5.0" - } - }, - "postcss-message-helpers": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/postcss-message-helpers/-/postcss-message-helpers-2.0.0.tgz", - "integrity": "sha1-pPL0+rbk/gAvCu0ABHjN9S+bpg4=" - }, - "prelude-ls": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", - "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=", - "dev": true - }, - "process-nextick-args": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-1.0.7.tgz", - "integrity": "sha1-FQ4gt1ZZCtP5EJPyWk8q2L/zC6M=", - "dev": true - }, - "progress": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.0.tgz", - "integrity": "sha1-ihvjZr+Pwj2yvSPxDG/pILQ4nR8=", - "dev": true - }, - "proto-props": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/proto-props/-/proto-props-0.2.1.tgz", - "integrity": "sha1-XgHcJnWg3pq/p255nfozTW9IP0s=", - "dev": true - }, - "pseudomap": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", - "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=", - "dev": true - }, - "readable-stream": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.3.tgz", - "integrity": "sha512-m+qzzcn7KUxEmd1gMbchF+Y2eIUbieUaxkWtptyHywrX0rE8QEYqPC07Vuy4Wm32/xE16NcdBctb8S0Xe/5IeQ==", - "dev": true, - "requires": { - "core-util-is": "1.0.2", - "inherits": "2.0.3", - "isarray": "1.0.0", - "process-nextick-args": "1.0.7", - "safe-buffer": "5.1.1", - "string_decoder": "1.0.3", - "util-deprecate": "1.0.2" - } - }, - "readjson": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/readjson/-/readjson-1.1.3.tgz", - "integrity": "sha1-y0xpFVHG5P7mZ/UcKczi9c6kWTw=", - "dev": true, - "requires": { - "try-catch": "1.0.0" - } - }, - "reduce-function-call": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/reduce-function-call/-/reduce-function-call-1.0.2.tgz", - "integrity": "sha1-WiAL+S4ON3UXUv5FsKszD9S2vpk=", - "requires": { - "balanced-match": "0.4.2" - } - }, - "require-uncached": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/require-uncached/-/require-uncached-1.0.3.tgz", - "integrity": "sha1-Tg1W1slmL9MeQwEcS5WqSZVUIdM=", - "dev": true, - "requires": { - "caller-path": "0.1.0", - "resolve-from": "1.0.1" - } - }, - "resolve": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.5.0.tgz", - "integrity": "sha512-hgoSGrc3pjzAPHNBg+KnFcK2HwlHTs/YrAGUr6qgTVUZmXv1UEXXl0bZNBKMA9fud6lRYFdPGz0xXxycPzmmiw==", - "dev": true, - "requires": { - "path-parse": "1.0.5" - } - }, - "resolve-from": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-1.0.1.tgz", - "integrity": "sha1-Jsv+k10a7uq7Kbw/5a6wHpPUQiY=", - "dev": true - }, - "restore-cursor": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-2.0.0.tgz", - "integrity": "sha1-n37ih/gv0ybU/RYpI9YhKe7g368=", - "dev": true, - "requires": { - "onetime": "2.0.1", - "signal-exit": "3.0.2" - } - }, - "resumer": { - "version": "0.0.0", - "resolved": "https://registry.npmjs.org/resumer/-/resumer-0.0.0.tgz", - "integrity": "sha1-8ej0YeQGS6Oegq883CqMiT0HZ1k=", - "dev": true, - "requires": { - "through": "2.3.8" - } - }, - "rimraf": { - "version": "2.6.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.2.tgz", - "integrity": "sha512-lreewLK/BlghmxtfH36YYVg1i8IAce4TI7oao75I1g245+6BctqTVQiBP3YUJ9C6DQOXJmkYR9X9fCLtCOJc5w==", - "dev": true, - "requires": { - "glob": "7.1.2" - } - }, - "run-applescript": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/run-applescript/-/run-applescript-2.1.0.tgz", - "integrity": "sha1-O/8sz5W2zqy0lyPlUPADcdYYUQ0=", - "dev": true, - "requires": { - "pify": "2.3.0", - "pinkie-promise": "2.0.1" - } - }, - "run-async": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.3.0.tgz", - "integrity": "sha1-A3GrSuC91yDUFm19/aZP96RFpsA=", - "dev": true, - "requires": { - "is-promise": "2.1.0" - } - }, - "rx-lite": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/rx-lite/-/rx-lite-4.0.8.tgz", - "integrity": "sha1-Cx4Rr4vESDbwSmQH6S2kJGe3lEQ=", - "dev": true - }, - "rx-lite-aggregates": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/rx-lite-aggregates/-/rx-lite-aggregates-4.0.8.tgz", - "integrity": "sha1-dTuHqJoRyVRnxKwWJsTvxOBcZ74=", - "dev": true, - "requires": { - "rx-lite": "4.0.8" - } - }, - "safe-buffer": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.1.tgz", - "integrity": "sha512-kKvNJn6Mm93gAczWVJg7wH+wGYWNrDHdWvpUmHyEsgCtIwwo3bqPtV4tR5tuPaUhTOo/kvhVwd8XwwOllGYkbg==", - "dev": true - }, - "semver": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.3.0.tgz", - "integrity": "sha1-myzl094C0XxgEq0yaqa00M9U+U8=", - "dev": true - }, - "shebang-command": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", - "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=", - "dev": true, - "requires": { - "shebang-regex": "1.0.0" - } - }, - "shebang-regex": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", - "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=", - "dev": true - }, - "shelljs": { - "version": "0.5.3", - "resolved": "https://registry.npmjs.org/shelljs/-/shelljs-0.5.3.tgz", - "integrity": "sha1-xUmCuZbHbvDB5rWfvcWCX1txMRM=", - "dev": true - }, - "signal-exit": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz", - "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=", - "dev": true - }, - "simple-swizzle": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/simple-swizzle/-/simple-swizzle-0.2.2.tgz", - "integrity": "sha1-pNprY1/8zMoz9w0Xy5JZLeleVXo=", - "requires": { - "is-arrayish": "0.3.1" - } - }, - "slice-ansi": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-1.0.0.tgz", - "integrity": "sha512-POqxBK6Lb3q6s047D/XsDVNPnF9Dl8JSaqe9h9lURl0OdNqy/ujDrOiIHtsqXMGbWWTIomRzAMaTyawAU//Reg==", - "dev": true, - "requires": { - "is-fullwidth-code-point": "2.0.0" - } - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" - }, - "sprintf-js": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", - "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", - "dev": true - }, - "stream-consume": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/stream-consume/-/stream-consume-0.1.0.tgz", - "integrity": "sha1-pB6tGm1ggc63n2WwYZAbbY89HQ8=", - "dev": true - }, - "string-width": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", - "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", - "dev": true, - "requires": { - "is-fullwidth-code-point": "2.0.0", - "strip-ansi": "4.0.0" - } - }, - "string.prototype.trim": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.1.2.tgz", - "integrity": "sha1-0E3iyJ4Tf019IG8Ia17S+ua+jOo=", - "dev": true, - "requires": { - "define-properties": "1.1.2", - "es-abstract": "1.10.0", - "function-bind": "1.1.1" - } - }, - "string_decoder": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz", - "integrity": "sha512-4AH6Z5fzNNBcH+6XDMfA/BTt87skxqJlO0lAh3Dker5zThcAxG6mKz+iGu308UKoPPQ8Dcqx/4JhujzltRa+hQ==", - "dev": true, - "requires": { - "safe-buffer": "5.1.1" - } - }, - "strip-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", - "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", - "dev": true, - "requires": { - "ansi-regex": "3.0.0" - }, - "dependencies": { - "ansi-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", - "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", - "dev": true - } - } - }, - "strip-eof": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz", - "integrity": "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8=", - "dev": true - }, - "strip-json-comments": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", - "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=", - "dev": true - }, - "supports-color": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.5.0.tgz", - "integrity": "sha1-vnoN5ITexcXN34s9WRJQRJEvY1s=", - "requires": { - "has-flag": "2.0.0" - } - }, - "table": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/table/-/table-4.0.2.tgz", - "integrity": "sha512-UUkEAPdSGxtRpiV9ozJ5cMTtYiqz7Ni1OGqLXRCynrvzdtR1p+cfOWe2RJLwvUG8hNanaSRjecIqwOjqeatDsA==", - "dev": true, - "requires": { - "ajv": "5.5.2", - "ajv-keywords": "2.1.1", - "chalk": "2.3.0", - "lodash": "4.17.4", - "slice-ansi": "1.0.0", - "string-width": "2.1.1" - } - }, - "tape": { - "version": "4.8.0", - "resolved": "https://registry.npmjs.org/tape/-/tape-4.8.0.tgz", - "integrity": "sha512-TWILfEnvO7I8mFe35d98F6T5fbLaEtbFTG/lxWvid8qDfFTxt19EBijWmB4j3+Hoh5TfHE2faWs73ua+EphuBA==", - "dev": true, - "requires": { - "deep-equal": "1.0.1", - "defined": "1.0.0", - "for-each": "0.3.2", - "function-bind": "1.1.1", - "glob": "7.1.2", - "has": "1.0.1", - "inherits": "2.0.3", - "minimist": "1.2.0", - "object-inspect": "1.3.0", - "resolve": "1.4.0", - "resumer": "0.0.0", - "string.prototype.trim": "1.1.2", - "through": "2.3.8" - }, - "dependencies": { - "minimist": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", - "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", - "dev": true - }, - "resolve": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.4.0.tgz", - "integrity": "sha512-aW7sVKPufyHqOmyyLzg/J+8606v5nevBgaliIlV7nUpVMsDnoBGV/cbSLNjZAg9q0Cfd/+easKVKQ8vOu8fn1Q==", - "dev": true, - "requires": { - "path-parse": "1.0.5" - } - } - } - }, - "text-table": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", - "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=", - "dev": true - }, - "through": { - "version": "2.3.8", - "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", - "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=", - "dev": true - }, - "tmp": { - "version": "0.0.33", - "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", - "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", - "dev": true, - "requires": { - "os-tmpdir": "1.0.2" - } - }, - "trash": { - "version": "3.4.2", - "resolved": "https://registry.npmjs.org/trash/-/trash-3.4.2.tgz", - "integrity": "sha1-+wQiUvwmoCInaVCiuw7Om5QF6xk=", - "dev": true, - "requires": { - "escape-string-applescript": "1.0.0", - "fs-extra": "0.26.7", - "globby": "4.1.0", - "path-exists": "2.1.0", - "pify": "2.3.0", - "pinkie-promise": "2.0.1", - "run-applescript": "2.1.0", - "uuid": "2.0.3", - "xdg-trashdir": "2.1.1" - }, - "dependencies": { - "glob": { - "version": "6.0.4", - "resolved": "https://registry.npmjs.org/glob/-/glob-6.0.4.tgz", - "integrity": "sha1-DwiGD2oVUSey+t1PnOJLGqtuTSI=", - "dev": true, - "requires": { - "inflight": "1.0.6", - "inherits": "2.0.3", - "minimatch": "3.0.4", - "once": "1.4.0", - "path-is-absolute": "1.0.1" - } - }, - "globby": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/globby/-/globby-4.1.0.tgz", - "integrity": "sha1-CA9UVJ7BuCpsYOYx/ILhIR2+lfg=", - "dev": true, - "requires": { - "array-union": "1.0.2", - "arrify": "1.0.1", - "glob": "6.0.4", - "object-assign": "4.1.1", - "pify": "2.3.0", - "pinkie-promise": "2.0.1" - } - } - } - }, - "try-catch": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/try-catch/-/try-catch-1.0.0.tgz", - "integrity": "sha1-N5fas5omZ3X00Npcv0Kso/A2COY=", - "dev": true - }, - "type-check": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", - "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=", - "dev": true, - "requires": { - "prelude-ls": "1.1.2" - } - }, - "typedarray": { - "version": "0.0.6", - "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", - "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=", - "dev": true - }, - "user-home": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/user-home/-/user-home-2.0.0.tgz", - "integrity": "sha1-nHC/2Babwdy/SGBODwS4tJzenp8=", - "dev": true, - "requires": { - "os-homedir": "1.0.2" - } - }, - "util-deprecate": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=", - "dev": true - }, - "uuid": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-2.0.3.tgz", - "integrity": "sha1-Z+LoY3lyFVMN/zGOW/nc6/1Hsho=", - "dev": true - }, - "which": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/which/-/which-1.3.0.tgz", - "integrity": "sha512-xcJpopdamTuY5duC/KnTTNBraPK54YwpenP4lzxU8H91GudWpFv38u0CKjclE1Wi2EH2EDz5LRcHcKbCIzqGyg==", - "dev": true, - "requires": { - "isexe": "2.0.0" - } - }, - "wordwrap": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", - "integrity": "sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus=", - "dev": true - }, - "wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", - "dev": true - }, - "write": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/write/-/write-0.2.1.tgz", - "integrity": "sha1-X8A4KOJkzqP+kUVUdvejxWbLB1c=", - "dev": true, - "requires": { - "mkdirp": "0.5.1" - } - }, - "xdg-basedir": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/xdg-basedir/-/xdg-basedir-2.0.0.tgz", - "integrity": "sha1-7byQPMOF/ARSPZZqM1UEtVBNG9I=", - "dev": true, - "requires": { - "os-homedir": "1.0.2" - } - }, - "xdg-trashdir": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/xdg-trashdir/-/xdg-trashdir-2.1.1.tgz", - "integrity": "sha512-KcVhPaOu2ZurYNHSRTf1+ZHORkTZGCQ+u0JHN17QixRISJq4pXOnjt/lQcehvtHL5QAKhSzKgyjrcNnPdkPBHA==", - "dev": true, - "requires": { - "@sindresorhus/df": "2.1.0", - "mount-point": "3.0.0", - "pify": "2.3.0", - "user-home": "2.0.0", - "xdg-basedir": "2.0.0" - } - }, - "yallist": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", - "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=", - "dev": true - } - } -} diff --git a/package.json b/package.json index 1fbebaf519..c63d80338a 100644 --- a/package.json +++ b/package.json @@ -1,44 +1,60 @@ { - "name": "postcss-color-gray", - "version": "4.1.0", - "description": "PostCSS plugin to transform gray() function to today's CSS", - "repository": "postcss/postcss-color-gray", - "author": "Shinnosuke Watanabe (https://github.com/shinnn)", - "scripts": { - "pretest": "eslint --fix --format=codeframe index.js test.js", - "test": "nyc --reporter=text --reporter=html node test.js", - "release": "npmpub" - }, - "license": "ISC", - "files": [ - "index.js" - ], - "keywords": [ - "css", - "css4", - "style", - "stylesheet", - "postcss", - "postcss-plugin", - "color", - "convert", - "gray", - "function" - ], - "dependencies": { - "color": "^2.0.1", - "postcss": "^6.0.14", - "postcss-message-helpers": "^2.0.0", - "reduce-function-call": "^1.0.2" - }, - "devDependencies": { - "@shinnn/eslint-config-node": "^5.0.0", - "eslint": "^4.13.1", - "npmpub": "^3.1.0", - "nyc": "^11.4.1", - "tape": "^4.8.0" - }, - "eslintConfig": { - "extends": "@shinnn/node" - } + "name": "postcss-color-gray", + "version": "5.0.0", + "description": "Use the gray() color function in CSS", + "author": "Shinnosuke Watanabe (https://github.com/shinnn)", + "license": "ISC", + "repository": "postcss/postcss-color-gray", + "homepage": "https://github.com/postcss/postcss-color-gray#readme", + "bugs": "https://github.com/postcss/postcss-color-gray/issues", + "main": "index.cjs.js", + "module": "index.es.js", + "files": [ + "index.cjs.js", + "index.es.js" + ], + "scripts": { + "prepublishOnly": "npm test", + "pretest": "rollup -c .rollup.js --silent", + "test": "echo 'Running tests...'; npm run test:js && npm run test:tape", + "test:ec": "echint --ignore index.*.js test", + "test:js": "eslint *.js --cache --ignore-path .gitignore --quiet", + "test:tape": "postcss-tape" + }, + "engines": { + "node": ">=6.0.0" + }, + "dependencies": { + "@csstools/convert-colors": "^1.4.0", + "postcss": "^7.0.5", + "postcss-values-parser": "^2.0.0" + }, + "devDependencies": { + "@babel/core": "^7.0.0", + "@babel/preset-env": "^7.0.0", + "babel-eslint": "^10.0.1", + "eslint": "^5.6.1", + "eslint-config-dev": "^2.0.0", + "postcss-tape": "^2.2.0", + "pre-commit": "^1.2.2", + "rollup": "^0.66.5", + "rollup-plugin-babel": "^4.0.1" + }, + "eslintConfig": { + "extends": "dev", + "parser": "babel-eslint" + }, + "keywords": [ + "postcss", + "css", + "postcss-plugin", + "gray", + "color", + "lab", + "transform", + "function", + "csswg", + "w3c", + "specification" + ] } diff --git a/test.js b/test.js deleted file mode 100644 index c92dfd853b..0000000000 --- a/test.js +++ /dev/null @@ -1,61 +0,0 @@ -'use strict'; - -const postcss = require('postcss'); -const colorGray = require('.'); -const test = require('tape'); - -function useGray() { - return postcss().use(colorGray()); -} - -test('postCssColorGray()', t => { - t.equal( - useGray().process('a {color: gray(200); background: gray(00000034%)}').css, - 'a {color: rgb(200, 200, 200); background: rgb(87, 87, 87)}', - 'should convert gray(A) to rgb(A,A,A).' - ); - - t.equal( - useGray().process('a {color: gray( 1, 4.5%)}; b {color: gray(030%,0.75 \t)}').css, - 'a {color: rgba(1, 1, 1, 0.045)}; b {color: rgba(77, 77, 77, 0.75)}', - 'should convert gray(A,B) to rgba(A,A,A,B).' - ); - - t.equal( - useGray().process('a {border-color: gray;}').css, - 'a {border-color: gray;}', - 'should not modify original CSS when gray() is not used.' - ); - - t.throws( - () => useGray().process('a {color: gray()}').css, - /Unable to parse color from string "gray\(\)"/, - 'should throw an error when gray() doesn\'t take any arguments.' - ); - - t.throws( - () => useGray().process('a {color: gray(,foo)}').css, - /:1:4: Unable to parse color from string "gray\(,foo\)"/, - 'should throw an error when gray() args start with a comma.' - ); - - t.throws( - () => useGray().process('a {color: gray(foo,)}').css, - /:1:4: Unable to parse color from string "gray\(foo,\)"/, - 'should throw an error when gray() args end with a comma.' - ); - - t.throws( - () => useGray().process('a {color: gray(red)}', {from: 'fixture.css'}).css, - /fixture\.css:1:4: Unable to parse color from string "gray\(red\)"/, - 'should throw a detailed error when a source file is specified.' - ); - - t.throws( - () => useGray().process('a {color: gray(,)}', {map: true}).css, - /:1:4: Unable to parse color from string "gray\(,\)"/, - 'should throw a detailed error when source map is enabled but file isn\'t specified.' - ); - - t.end(); -}); diff --git a/test/basic.css b/test/basic.css new file mode 100644 index 0000000000..5eb07f2652 --- /dev/null +++ b/test/basic.css @@ -0,0 +1,13 @@ +.test-gray { + color: gray(40); + color: gray(40 / 1); + color: gray(40 / .5); + color: gray(40 / 100%); + color: gray(40 / 50%); +} + +.test-invalid-gray { + color: gray(); + color: gray(40, 1); + color: gray(40 / 1 / 1); +} diff --git a/test/basic.expect.css b/test/basic.expect.css new file mode 100644 index 0000000000..58adeee127 --- /dev/null +++ b/test/basic.expect.css @@ -0,0 +1,13 @@ +.test-gray { + color: rgb(94,94,94); + color: rgb(94,94,94); + color: rgba(94,94,94,0.5); + color: rgb(94,94,94); + color: rgba(94,94,94,0.5); +} + +.test-invalid-gray { + color: gray(); + color: gray(40, 1); + color: gray(40 / 1 / 1); +} diff --git a/test/basic.preserve.expect.css b/test/basic.preserve.expect.css new file mode 100644 index 0000000000..a62a87ec86 --- /dev/null +++ b/test/basic.preserve.expect.css @@ -0,0 +1,18 @@ +.test-gray { + color: rgb(94,94,94); + color: gray(40); + color: rgb(94,94,94); + color: gray(40 / 1); + color: rgba(94,94,94,0.5); + color: gray(40 / .5); + color: rgb(94,94,94); + color: gray(40 / 100%); + color: rgba(94,94,94,0.5); + color: gray(40 / 50%); +} + +.test-invalid-gray { + color: gray(); + color: gray(40, 1); + color: gray(40 / 1 / 1); +} From 70ee277a101dc05fa0b8245ff4fad683277142fc Mon Sep 17 00:00:00 2001 From: Jonathan Neal Date: Thu, 11 Oct 2018 09:10:28 -0400 Subject: [PATCH 737/795] Update README.md cli should only reference the published branch, master --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 89276eed64..12a145e882 100755 --- a/README.md +++ b/README.md @@ -164,7 +164,7 @@ See example exports written to [CSS](test/export-media.css), [JS](test/export-media.js), [MJS](test/export-media.mjs), and [JSON](test/export-media.json). -[cli-img]: https://img.shields.io/travis/postcss/postcss-custom-media.svg +[cli-img]: https://img.shields.io/travis/postcss/postcss-custom-media/master.svg [cli-url]: https://travis-ci.org/postcss/postcss-custom-media [css-img]: https://cssdb.org/badge/custom-media-queries.svg [css-url]: https://cssdb.org/#custom-media-queries From f095211389d761e426f43a32a437bde273930598 Mon Sep 17 00:00:00 2001 From: Jonathan Neal Date: Fri, 12 Oct 2018 08:43:58 -0400 Subject: [PATCH 738/795] 7.0.6 --- CHANGELOG.md | 4 ++++ lib/transform-media-list.js | 3 ++- package.json | 4 ++-- test/basic.css | 13 ++++++++++++- test/basic.expect.css | 10 +++++++++- test/basic.preserve.expect.css | 23 +++++++++++++++++++++-- test/export-media.css | 2 ++ test/export-media.js | 4 +++- test/export-media.json | 4 +++- test/export-media.mjs | 4 +++- 10 files changed, 61 insertions(+), 10 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 51c74f1c5a..09781121d3 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # Changes to PostCSS Custom Media +### 7.0.6 (October 12, 2018) + +- Fixing: Issue combining multiple custom media + ### 7.0.5 (October 5, 2018) - Fixed: Possible issues resolving paths to imports and exports diff --git a/lib/transform-media-list.js b/lib/transform-media-list.js index 33c0ec78ac..bacca250e2 100644 --- a/lib/transform-media-list.js +++ b/lib/transform-media-list.js @@ -48,7 +48,8 @@ function transformMedia(media, customMedias) { } mediaClone.nodes.splice(index, 1, ...replacementMedia.clone().nodes.map(node => { - // use spacing from the current usage + // use raws and spacing from the current usage + node.raws = { ...media.nodes[index].raws }; node.spaces = { ...media.nodes[index].spaces }; return node; diff --git a/package.json b/package.json index b24419dd22..c58097e7b4 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "postcss-custom-media", - "version": "7.0.5", + "version": "7.0.6", "description": "Use Custom Media Queries in CSS", "author": "Jonathan Neal ", "contributors": [ @@ -38,7 +38,7 @@ "eslint-config-dev": "^2.0.0", "postcss-tape": "^2.2.0", "pre-commit": "^1.2.2", - "rollup": "^0.66.4", + "rollup": "^0.66.6", "rollup-plugin-babel": "^4.0.3" }, "eslintConfig": { diff --git a/test/basic.css b/test/basic.css index ee34098d63..14bf4808f1 100644 --- a/test/basic.css +++ b/test/basic.css @@ -54,5 +54,16 @@ } @media (--unresolved-mq) { - body order: 5; + body { + order: 5; + } +} + +@custom-media --min (min-width: 320px); +@custom-media --max (max-width: 640px); + +@media (--min) and (--max) { + body { + order: 6; + } } diff --git a/test/basic.expect.css b/test/basic.expect.css index c55e511eb3..ec332b80aa 100644 --- a/test/basic.expect.css +++ b/test/basic.expect.css @@ -47,5 +47,13 @@ } @media (--unresolved-mq) { - body order: 5; + body { + order: 5; + } +} + +@media (min-width: 320px) and (max-width: 640px) { + body { + order: 6; + } } diff --git a/test/basic.preserve.expect.css b/test/basic.preserve.expect.css index 3ec9f68a79..435a0491eb 100644 --- a/test/basic.preserve.expect.css +++ b/test/basic.preserve.expect.css @@ -102,9 +102,28 @@ } @media (--unresolved-mq) { - body order: 5; + body { + order: 5; + } } @media (--unresolved-mq) { - body order: 5; + body { + order: 5; + } +} + +@custom-media --min (min-width: 320px); +@custom-media --max (max-width: 640px); + +@media (min-width: 320px) and (max-width: 640px) { + body { + order: 6; + } +} + +@media (--min) and (--max) { + body { + order: 6; + } } diff --git a/test/export-media.css b/test/export-media.css index 0f65a294f8..26b7f8ba67 100644 --- a/test/export-media.css +++ b/test/export-media.css @@ -3,3 +3,5 @@ @custom-media --not-mq-a not all and (--mq-a); @custom-media --circular-mq-a (--circular-mq-b); @custom-media --circular-mq-b (--circular-mq-a); +@custom-media --min (min-width: 320px); +@custom-media --max (max-width: 640px); diff --git a/test/export-media.js b/test/export-media.js index 65bc566768..a1f29ef416 100644 --- a/test/export-media.js +++ b/test/export-media.js @@ -4,6 +4,8 @@ module.exports = { '--mq-b': 'screen and (max-width: 30em)', '--not-mq-a': 'not all and (--mq-a)', '--circular-mq-a': '(--circular-mq-b)', - '--circular-mq-b': '(--circular-mq-a)' + '--circular-mq-b': '(--circular-mq-a)', + '--min': '(min-width: 320px)', + '--max': '(max-width: 640px)' } }; diff --git a/test/export-media.json b/test/export-media.json index 250d9aeb13..f54f6fe692 100644 --- a/test/export-media.json +++ b/test/export-media.json @@ -4,6 +4,8 @@ "--mq-b": "screen and (max-width: 30em)", "--not-mq-a": "not all and (--mq-a)", "--circular-mq-a": "(--circular-mq-b)", - "--circular-mq-b": "(--circular-mq-a)" + "--circular-mq-b": "(--circular-mq-a)", + "--min": "(min-width: 320px)", + "--max": "(max-width: 640px)" } } diff --git a/test/export-media.mjs b/test/export-media.mjs index cad637dac7..6b846811e0 100644 --- a/test/export-media.mjs +++ b/test/export-media.mjs @@ -3,5 +3,7 @@ export const customMedia = { '--mq-b': 'screen and (max-width: 30em)', '--not-mq-a': 'not all and (--mq-a)', '--circular-mq-a': '(--circular-mq-b)', - '--circular-mq-b': '(--circular-mq-a)' + '--circular-mq-b': '(--circular-mq-a)', + '--min': '(min-width: 320px)', + '--max': '(max-width: 640px)' }; From 5db224c00226e8e0eac296d9dcee9208db299766 Mon Sep 17 00:00:00 2001 From: Jonathan Neal Date: Fri, 19 Oct 2018 18:25:18 -0400 Subject: [PATCH 739/795] 7.0.7 --- CHANGELOG.md | 6 +++++- lib/transform-media-list.js | 5 ++++- package.json | 4 ++-- test/basic.css | 14 ++++++++++++++ test/basic.expect.css | 12 ++++++++++++ test/basic.preserve.expect.css | 26 ++++++++++++++++++++++++++ test/export-media.css | 1 + test/export-media.js | 3 ++- test/export-media.json | 3 ++- test/export-media.mjs | 3 ++- 10 files changed, 70 insertions(+), 7 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 09781121d3..a762390bc4 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,8 +1,12 @@ # Changes to PostCSS Custom Media +### 7.0.7 (October 19, 2018) + +- Fixed: Issue combining custom media media queries with `and` + ### 7.0.6 (October 12, 2018) -- Fixing: Issue combining multiple custom media +- Fixed: Issue combining multiple custom media ### 7.0.5 (October 5, 2018) diff --git a/lib/transform-media-list.js b/lib/transform-media-list.js index bacca250e2..d30a8ec017 100644 --- a/lib/transform-media-list.js +++ b/lib/transform-media-list.js @@ -49,7 +49,10 @@ function transformMedia(media, customMedias) { mediaClone.nodes.splice(index, 1, ...replacementMedia.clone().nodes.map(node => { // use raws and spacing from the current usage - node.raws = { ...media.nodes[index].raws }; + if (media.nodes[index].raws.and) { + node.raws = { ...media.nodes[index].raws }; + } + node.spaces = { ...media.nodes[index].spaces }; return node; diff --git a/package.json b/package.json index c58097e7b4..505eb8ede4 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "postcss-custom-media", - "version": "7.0.6", + "version": "7.0.7", "description": "Use Custom Media Queries in CSS", "author": "Jonathan Neal ", "contributors": [ @@ -34,7 +34,7 @@ "@babel/plugin-syntax-dynamic-import": "^7.0.0", "@babel/preset-env": "^7.1.0", "babel-eslint": "^10.0.1", - "eslint": "^5.6.1", + "eslint": "^5.7.0", "eslint-config-dev": "^2.0.0", "postcss-tape": "^2.2.0", "pre-commit": "^1.2.2", diff --git a/test/basic.css b/test/basic.css index 14bf4808f1..d01c68b10b 100644 --- a/test/basic.css +++ b/test/basic.css @@ -67,3 +67,17 @@ order: 6; } } + +@custom-media --concat (min-width: 320px) and (max-width: 640px); + +@media (--concat) { + body { + order: 7; + } +} + +@media (--concat) and (min-aspect-ratio: 16/9) { + body { + order: 8; + } +} diff --git a/test/basic.expect.css b/test/basic.expect.css index ec332b80aa..0b7020331d 100644 --- a/test/basic.expect.css +++ b/test/basic.expect.css @@ -57,3 +57,15 @@ order: 6; } } + +@media (min-width: 320px) and (max-width: 640px) { + body { + order: 7; + } +} + +@media (min-width: 320px) and (max-width: 640px) and (min-aspect-ratio: 16/9) { + body { + order: 8; + } +} diff --git a/test/basic.preserve.expect.css b/test/basic.preserve.expect.css index 435a0491eb..0d542ff9fe 100644 --- a/test/basic.preserve.expect.css +++ b/test/basic.preserve.expect.css @@ -127,3 +127,29 @@ order: 6; } } + +@custom-media --concat (min-width: 320px) and (max-width: 640px); + +@media (min-width: 320px) and (max-width: 640px) { + body { + order: 7; + } +} + +@media (--concat) { + body { + order: 7; + } +} + +@media (min-width: 320px) and (max-width: 640px) and (min-aspect-ratio: 16/9) { + body { + order: 8; + } +} + +@media (--concat) and (min-aspect-ratio: 16/9) { + body { + order: 8; + } +} diff --git a/test/export-media.css b/test/export-media.css index 26b7f8ba67..f51e88c82e 100644 --- a/test/export-media.css +++ b/test/export-media.css @@ -5,3 +5,4 @@ @custom-media --circular-mq-b (--circular-mq-a); @custom-media --min (min-width: 320px); @custom-media --max (max-width: 640px); +@custom-media --concat (min-width: 320px) and (max-width: 640px); diff --git a/test/export-media.js b/test/export-media.js index a1f29ef416..acccd84089 100644 --- a/test/export-media.js +++ b/test/export-media.js @@ -6,6 +6,7 @@ module.exports = { '--circular-mq-a': '(--circular-mq-b)', '--circular-mq-b': '(--circular-mq-a)', '--min': '(min-width: 320px)', - '--max': '(max-width: 640px)' + '--max': '(max-width: 640px)', + '--concat': '(min-width: 320px) and (max-width: 640px)' } }; diff --git a/test/export-media.json b/test/export-media.json index f54f6fe692..82eb9deb58 100644 --- a/test/export-media.json +++ b/test/export-media.json @@ -6,6 +6,7 @@ "--circular-mq-a": "(--circular-mq-b)", "--circular-mq-b": "(--circular-mq-a)", "--min": "(min-width: 320px)", - "--max": "(max-width: 640px)" + "--max": "(max-width: 640px)", + "--concat": "(min-width: 320px) and (max-width: 640px)" } } diff --git a/test/export-media.mjs b/test/export-media.mjs index 6b846811e0..ea36519d86 100644 --- a/test/export-media.mjs +++ b/test/export-media.mjs @@ -5,5 +5,6 @@ export const customMedia = { '--circular-mq-a': '(--circular-mq-b)', '--circular-mq-b': '(--circular-mq-a)', '--min': '(min-width: 320px)', - '--max': '(max-width: 640px)' + '--max': '(max-width: 640px)', + '--concat': '(min-width: 320px) and (max-width: 640px)' }; From 105bfb3d003c71d39a15782d13f1ba0edac60724 Mon Sep 17 00:00:00 2001 From: Jonathan Neal Date: Sun, 28 Oct 2018 14:16:17 -0400 Subject: [PATCH 740/795] 1.0.0 --- .editorconfig | 15 +++ .gitignore | 11 +++ .rollup.js | 16 ++++ .tape.js | 11 +++ .travis.yml | 9 ++ CHANGELOG.md | 5 + CONTRIBUTING.md | 65 +++++++++++++ INSTALL.md | 170 +++++++++++++++++++++++++++++++++ LICENSE.md | 108 +++++++++++++++++++++ README.md | 104 ++++++++++++++++++++ index.js | 60 ++++++++++++ package.json | 63 ++++++++++++ test/basic.css | 7 ++ test/basic.expect.css | 9 ++ test/basic.preserve.expect.css | 7 ++ 15 files changed, 660 insertions(+) create mode 100644 .editorconfig create mode 100644 .gitignore create mode 100644 .rollup.js create mode 100644 .tape.js create mode 100644 .travis.yml create mode 100644 CHANGELOG.md create mode 100644 CONTRIBUTING.md create mode 100644 INSTALL.md create mode 100644 LICENSE.md create mode 100644 README.md create mode 100644 index.js create mode 100644 package.json create mode 100644 test/basic.css create mode 100644 test/basic.expect.css create mode 100644 test/basic.preserve.expect.css diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000000..e06d7982bc --- /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/.gitignore b/.gitignore new file mode 100644 index 0000000000..d920b78fec --- /dev/null +++ b/.gitignore @@ -0,0 +1,11 @@ +node_modules +index.*.* +package-lock.json +*.log* +*.result.css +.* +!.editorconfig +!.gitignore +!.rollup.js +!.tape.js +!.travis.yml diff --git a/.rollup.js b/.rollup.js new file mode 100644 index 0000000000..ebe39f9220 --- /dev/null +++ b/.rollup.js @@ -0,0 +1,16 @@ +import babel from 'rollup-plugin-babel'; + +export default { + input: 'index.js', + output: [ + { file: 'index.cjs.js', format: 'cjs', sourcemap: true }, + { file: 'index.es.mjs', format: 'es', sourcemap: true } + ], + plugins: [ + babel({ + presets: [ + ['@babel/env', { modules: false, targets: { node: 6 } }] + ] + }) + ] +}; diff --git a/.tape.js b/.tape.js new file mode 100644 index 0000000000..353d9b9690 --- /dev/null +++ b/.tape.js @@ -0,0 +1,11 @@ +module.exports = { + 'postcss-double-position-gradients': { + 'basic': { + message: 'supports basic usage' + }, + 'basic:preserve': { + message: 'supports { preserve: false } usage', + options: { preserve: false } + } + } +}; diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000000..e1f11a52e6 --- /dev/null +++ b/.travis.yml @@ -0,0 +1,9 @@ +# https://docs.travis-ci.com/user/travis-lint + +language: node_js + +node_js: + - 6 + +install: + - npm install --ignore-scripts diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000000..b99c7f3b7b --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,5 @@ +# Changes to PostCSS Double Position Gradients + +### 1.0.0 (October 28, 2018) + +- Initial version diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 0000000000..703ce0bf52 --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,65 @@ +# Contributing to PostCSS Double Position Gradients + +You want to help? You rock! Now, take a moment to be sure your contributions +make sense to everyone else. + +## Reporting Issues + +Found a problem? Want a new feature? + +- See if your issue or idea has [already been reported]. +- Provide a [reduced test case] or a [live example]. + +Remember, a bug is a _demonstrable problem_ caused by _our_ code. + +## Submitting Pull Requests + +Pull requests are the greatest contributions, so be sure they are focused in +scope and avoid unrelated commits. + +1. To begin; [fork this project], clone your fork, and add our upstream. + ```bash + # Clone your fork of the repo into the current directory + git clone git@github.com:YOUR_USER/postcss-double-position-gradients.git + + # Navigate to the newly cloned directory + cd postcss-double-position-gradients + + # Assign the original repo to a remote called "upstream" + git remote add upstream git@github.com:jonathantneal/postcss-double-position-gradients.git + + # Install the tools necessary for testing + npm install + ``` + +2. Create a branch for your feature or fix: + ```bash + # Move into a new branch for your feature + git checkout -b feature/thing + ``` + ```bash + # Move into a new branch for your fix + git checkout -b fix/something + ``` + +3. If your code follows our practices, then push your feature branch: + ```bash + # Test current code + npm test + ``` + ```bash + # Push the branch for your new feature + git push origin feature/thing + ``` + ```bash + # Or, push the branch for your update + git push origin update/something + ``` + +That’s it! Now [open a pull request] with a clear title and description. + +[already been reported]: issues +[fork this project]: fork +[live example]: https://codepen.io/pen +[open a pull request]: https://help.github.com/articles/using-pull-requests/ +[reduced test case]: https://css-tricks.com/reduced-test-cases/ diff --git a/INSTALL.md b/INSTALL.md new file mode 100644 index 0000000000..5eb5660c33 --- /dev/null +++ b/INSTALL.md @@ -0,0 +1,170 @@ +# Installing PostCSS Double Position Gradients + +[PostCSS Double Position Gradients] runs in all Node environments, with special instructions for: + +| [Node](#node) | [PostCSS CLI](#postcss-cli) | [Webpack](#webpack) | [Create React App](#create-react-app) | [Gulp](#gulp) | [Grunt](#grunt) | +| --- | --- | --- | --- | --- | --- | + +## Node + +Add [PostCSS Double Position Gradients] to your project: + +```bash +npm install postcss-double-position-gradients --save-dev +``` + +Use [PostCSS Double Position Gradients] to process your CSS: + +```js +const postcssDoublePositionGradients = require('postcss-double-position-gradients'); + +postcssDoublePositionGradients.process(YOUR_CSS /*, processOptions, pluginOptions */); +``` + +Or use it as a [PostCSS] plugin: + +```js +const postcss = require('postcss'); +const postcssDoublePositionGradients = require('postcss-double-position-gradients'); + +postcss([ + postcssDoublePositionGradients(/* pluginOptions */) +]).process(YOUR_CSS /*, processOptions */); +``` + +## PostCSS CLI + +Add [PostCSS CLI] to your project: + +```bash +npm install postcss-cli --save-dev +``` + +Use [PostCSS Double Position Gradients] in your `postcss.config.js` configuration file: + +```js +const postcssDoublePositionGradients = require('postcss-double-position-gradients'); + +module.exports = { + plugins: [ + postcssDoublePositionGradients(/* pluginOptions */) + ] +} +``` + +## Webpack + +Add [PostCSS Loader] to your project: + +```bash +npm install postcss-loader --save-dev +``` + +Use [PostCSS Double Position Gradients] in your Webpack configuration: + +```js +const postcssDoublePositionGradients = require('postcss-double-position-gradients'); + +module.exports = { + module: { + rules: [ + { + test: /\.css$/, + use: [ + 'style-loader', + { loader: 'css-loader', options: { importLoaders: 1 } }, + { loader: 'postcss-loader', options: { + ident: 'postcss', + plugins: () => [ + postcssDoublePositionGradients(/* pluginOptions */) + ] + } } + ] + } + ] + } +} +``` + +## Create React App + +Add [React App Rewired] and [React App Rewire PostCSS] to your project: + +```bash +npm install react-app-rewired react-app-rewire-postcss --save-dev +``` + +Use [React App Rewire PostCSS] and [PostCSS Double Position Gradients] in your +`config-overrides.js` file: + +```js +const reactAppRewirePostcss = require('react-app-rewire-postcss'); +const postcssDoublePositionGradients = require('postcss-double-position-gradients'); + +module.exports = config => reactAppRewirePostcss(config, { + plugins: () => [ + postcssDoublePositionGradients(/* pluginOptions */) + ] +}); +``` + +## Gulp + +Add [Gulp PostCSS] to your project: + +```bash +npm install gulp-postcss --save-dev +``` + +Use [PostCSS Double Position Gradients] in your Gulpfile: + +```js +const postcss = require('gulp-postcss'); +const postcssDoublePositionGradients = require('postcss-double-position-gradients'); + +gulp.task('css', () => gulp.src('./src/*.css').pipe( + postcss([ + postcssDoublePositionGradients(/* pluginOptions */) + ]) +).pipe( + gulp.dest('.') +)); +``` + +## Grunt + +Add [Grunt PostCSS] to your project: + +```bash +npm install grunt-postcss --save-dev +``` + +Use [PostCSS Double Position Gradients] in your Gruntfile: + +```js +const postcssDoublePositionGradients = require('postcss-double-position-gradients'); + +grunt.loadNpmTasks('grunt-postcss'); + +grunt.initConfig({ + postcss: { + options: { + use: [ + postcssDoublePositionGradients(/* pluginOptions */) + ] + }, + dist: { + src: '*.css' + } + } +}); +``` + +[Gulp PostCSS]: https://github.com/postcss/gulp-postcss +[Grunt PostCSS]: https://github.com/nDmitry/grunt-postcss +[PostCSS]: https://github.com/postcss/postcss +[PostCSS CLI]: https://github.com/postcss/postcss-cli +[PostCSS Loader]: https://github.com/postcss/postcss-loader +[PostCSS Double Position Gradients]: https://github.com/jonathantneal/postcss-double-position-gradients +[React App Rewire PostCSS]: https://github.com/csstools/react-app-rewire-postcss +[React App Rewired]: https://github.com/timarney/react-app-rewired diff --git a/LICENSE.md b/LICENSE.md new file mode 100644 index 0000000000..0bc1fa7060 --- /dev/null +++ b/LICENSE.md @@ -0,0 +1,108 @@ +# CC0 1.0 Universal + +## Statement of Purpose + +The laws of most jurisdictions throughout the world automatically confer +exclusive Copyright and Related Rights (defined below) upon the creator and +subsequent owner(s) (each and all, an “owner”) of an original work of +authorship and/or a database (each, a “Work”). + +Certain owners wish to permanently relinquish those rights to a Work for the +purpose of contributing to a commons of creative, cultural and scientific works +(“Commons”) that the public can reliably and without fear of later claims of +infringement build upon, modify, incorporate in other works, reuse and +redistribute as freely as possible in any form whatsoever and for any purposes, +including without limitation commercial purposes. These owners may contribute +to the Commons to promote the ideal of a free culture and the further +production of creative, cultural and scientific works, or to gain reputation or +greater distribution for their Work in part through the use and efforts of +others. + +For these and/or other purposes and motivations, and without any expectation of +additional consideration or compensation, the person associating CC0 with a +Work (the “Affirmer”), to the extent that he or she is an owner of Copyright +and Related Rights in the Work, voluntarily elects to apply CC0 to the Work and +publicly distribute the Work under its terms, with knowledge of his or her +Copyright and Related Rights in the Work and the meaning and intended legal +effect of CC0 on those rights. + +1. Copyright and Related Rights. A Work made available under CC0 may be + protected by copyright and related or neighboring rights (“Copyright and + Related Rights”). Copyright and Related Rights include, but are not limited + to, the following: + 1. the right to reproduce, adapt, distribute, perform, display, communicate, + and translate a Work; + 2. moral rights retained by the original author(s) and/or performer(s); + 3. publicity and privacy rights pertaining to a person’s image or likeness + depicted in a Work; + 4. rights protecting against unfair competition in regards to a Work, + subject to the limitations in paragraph 4(i), below; + 5. rights protecting the extraction, dissemination, use and reuse of data in + a Work; + 6. database rights (such as those arising under Directive 96/9/EC of the + European Parliament and of the Council of 11 March 1996 on the legal + protection of databases, and under any national implementation thereof, + including any amended or successor version of such directive); and + 7. other similar, equivalent or corresponding rights throughout the world + based on applicable law or treaty, and any national implementations + thereof. + +2. Waiver. To the greatest extent permitted by, but not in contravention of, + applicable law, Affirmer hereby overtly, fully, permanently, irrevocably and + unconditionally waives, abandons, and surrenders all of Affirmer’s Copyright + and Related Rights and associated claims and causes of action, whether now + known or unknown (including existing as well as future claims and causes of + action), in the Work (i) in all territories worldwide, (ii) for the maximum + duration provided by applicable law or treaty (including future time + extensions), (iii) in any current or future medium and for any number of + copies, and (iv) for any purpose whatsoever, including without limitation + commercial, advertising or promotional purposes (the “Waiver”). Affirmer + makes the Waiver for the benefit of each member of the public at large and + to the detriment of Affirmer’s heirs and successors, fully intending that + such Waiver shall not be subject to revocation, rescission, cancellation, + termination, or any other legal or equitable action to disrupt the quiet + enjoyment of the Work by the public as contemplated by Affirmer’s express + Statement of Purpose. + +3. Public License Fallback. Should any part of the Waiver for any reason be + judged legally invalid or ineffective under applicable law, then the Waiver + shall be preserved to the maximum extent permitted taking into account + Affirmer’s express Statement of Purpose. In addition, to the extent the + Waiver is so judged Affirmer hereby grants to each affected person a + royalty-free, non transferable, non sublicensable, non exclusive, + irrevocable and unconditional license to exercise Affirmer’s Copyright and + Related Rights in the Work (i) in all territories worldwide, (ii) for the + maximum duration provided by applicable law or treaty (including future time + extensions), (iii) in any current or future medium and for any number of + copies, and (iv) for any purpose whatsoever, including without limitation + commercial, advertising or promotional purposes (the “License”). The License + shall be deemed effective as of the date CC0 was applied by Affirmer to the + Work. Should any part of the License for any reason be judged legally + invalid or ineffective under applicable law, such partial invalidity or + ineffectiveness shall not invalidate the remainder of the License, and in + such case Affirmer hereby affirms that he or she will not (i) exercise any + of his or her remaining Copyright and Related Rights in the Work or (ii) + assert any associated claims and causes of action with respect to the Work, + in either case contrary to Affirmer’s express Statement of Purpose. + +4. Limitations and Disclaimers. + 1. No trademark or patent rights held by Affirmer are waived, abandoned, + surrendered, licensed or otherwise affected by this document. + 2. Affirmer offers the Work as-is and makes no representations or warranties + of any kind concerning the Work, express, implied, statutory or + otherwise, including without limitation warranties of title, + merchantability, fitness for a particular purpose, non infringement, or + the absence of latent or other defects, accuracy, or the present or + absence of errors, whether or not discoverable, all to the greatest + extent permissible under applicable law. + 3. Affirmer disclaims responsibility for clearing rights of other persons + that may apply to the Work or any use thereof, including without + limitation any person’s Copyright and Related Rights in the Work. + Further, Affirmer disclaims responsibility for obtaining any necessary + consents, permissions or other rights required for any use of the Work. + 4. Affirmer understands and acknowledges that Creative Commons is not a + party to this document and has no duty or obligation with respect to this + CC0 or use of the Work. + +For more information, please see +http://creativecommons.org/publicdomain/zero/1.0/. diff --git a/README.md b/README.md new file mode 100644 index 0000000000..e6c2025db9 --- /dev/null +++ b/README.md @@ -0,0 +1,104 @@ +# PostCSS Double Position Gradients [PostCSS][postcss] + +[![NPM Version][npm-img]][npm-url] +[![Build Status][cli-img]][cli-url] +[![Support Chat][git-img]][git-url] + +[PostCSS Double Position Gradients] lets you use double-position gradients in +CSS, following the [CSS Image Values and Replaced Content] specification. + +```pcss +.linear-gradient { + background-image: linear-gradient(90deg, black 25% 50%, blue 50% 75%); +} + +.conic-gradient { + background-image: conic-gradient(yellowgreen 40%, gold 0deg 75%, #f06 0deg); +} + +/* becomes */ + +.linear-gradient { + background-image: linear-gradient(90deg, black 25%, black 50%, blue 50%, blue 75%); + background-image: linear-gradient(90deg, black 25% 50%, blue 50% 75%); +} + +.conic-gradient { + background-image: conic-gradient(yellowgreen 40%, gold 0deg, gold 75%, #f06 0deg); + background-image: conic-gradient(yellowgreen 40%, gold 0deg 75%, #f06 0deg); +} +``` + +## Usage + +Add [PostCSS Double Position Gradients] to your project: + +```bash +npm install postcss-double-position-gradients --save-dev +``` + +Use [PostCSS Double Position Gradients] to process your CSS: + +```js +const postcssDoublePositionGradients = require('postcss-double-position-gradients'); + +postcssDoublePositionGradients.process(YOUR_CSS /*, processOptions, pluginOptions */); +``` + +Or use it as a [PostCSS] plugin: + +```js +const postcss = require('postcss'); +const postcssDoublePositionGradients = require('postcss-double-position-gradients'); + +postcss([ + postcssDoublePositionGradients(/* pluginOptions */) +]).process(YOUR_CSS /*, processOptions */); +``` + +[PostCSS Double Position Gradients] runs in all Node environments, with special instructions for: + +| [Node](INSTALL.md#node) | [PostCSS CLI](INSTALL.md#postcss-cli) | [Webpack](INSTALL.md#webpack) | [Create React App](INSTALL.md#create-react-app) | [Gulp](INSTALL.md#gulp) | [Grunt](INSTALL.md#grunt) | +| --- | --- | --- | --- | --- | --- | + +## Options + +### preserve + +The `preserve` option determines whether the original double-position gradients +should be preserved. By default, double-position gradients are preserved. + +```js +postcssDoublePositionGradients({ preserve: false }) +``` + +```css +.linear-gradient { + background-image: linear-gradient(90deg, black 25% 50%, blue 50% 75%); +} + +.conic-gradient { + background-image: conic-gradient(yellowgreen 40%, gold 0deg 75%, #f06 0deg); +} + +/* becomes */ + +.linear-gradient { + background-image: linear-gradient(90deg, black 25%, black 50%, blue 50%, blue 75%); +} + +.conic-gradient { + background-image: conic-gradient(yellowgreen 40%, gold 0deg, gold 75%, #f06 0deg); +} +``` + +[cli-img]: https://img.shields.io/travis/jonathantneal/postcss-double-position-gradients/master.svg +[cli-url]: https://travis-ci.org/jonathantneal/postcss-double-position-gradients +[git-img]: https://img.shields.io/badge/support-chat-blue.svg +[git-url]: https://gitter.im/postcss/postcss +[npm-img]: https://img.shields.io/npm/v/postcss-double-position-gradients.svg +[npm-url]: https://www.npmjs.com/package/postcss-double-position-gradients + +[CSS Image Values and Replaced Content]: https://www.w3.org/TR/css-images-4/#color-stop-syntax +[PostCSS]: https://github.com/postcss/postcss +[PostCSS Double Position Gradients]: https://github.com/jonathantneal/postcss-double-position-gradients diff --git a/index.js b/index.js new file mode 100644 index 0000000000..e4652f4369 --- /dev/null +++ b/index.js @@ -0,0 +1,60 @@ +import postcss from 'postcss'; +import valueParser from 'postcss-values-parser'; + +export default postcss.plugin('postcss-double-position-gradients', opts => { + const preserve = 'preserve' in Object(opts) ? Boolean(opts.preserve) : true; + + return root => { + // walk every declaration + root.walkDecls(decl => { + const { value: originalValue } = decl; + + // if the declaration value contains a gradient + if (gradientFunctionRegExp.test(originalValue)) { + const ast = valueParser(originalValue).parse(); + + // walk every function in the declaration value + ast.walkFunctionNodes(fn => { + // if the function is a gradient + if (gradientFunctionNameRegExp.test(fn.value)) { + const nodes = fn.nodes.slice(1, -1); + + // walk every argument to the function + nodes.forEach((node, index) => { + const node1back = Object(nodes[index - 1]); + const node2back = Object(nodes[index - 2]); + + const isDoublePositionLength = node2back.type && node1back.type === 'number' && node.type === 'number'; + + // if the argument concludes a double-position gradient + if (isDoublePositionLength) { + // insert the fallback colors + const color = node2back.clone(); + const comma = valueParser.comma({ value: ',', raws: { after: ' ' } }); + + fn.insertBefore(node, comma); + fn.insertBefore(node, color); + } + }) + } + }); + + const modifiedValue = ast.toString(); + + // if the value has changed due to double-position gradients + if (originalValue !== modifiedValue) { + // add the fallback value + decl.cloneBefore({ value: modifiedValue }); + + // conditionally remove the double-position gradient + if (!preserve) { + decl.remove(); + } + } + } + }); + }; +}); + +const gradientFunctionRegExp = /(repeating-)?(conic|linear|radial)-gradient\([\W\w]*\)/i; +const gradientFunctionNameRegExp = /^(repeating-)?(conic|linear|radial)-gradient$/i; diff --git a/package.json b/package.json new file mode 100644 index 0000000000..e1897e25ed --- /dev/null +++ b/package.json @@ -0,0 +1,63 @@ +{ + "name": "postcss-double-position-gradients", + "version": "1.0.0", + "description": "Use double-position gradients in CSS", + "author": "Jonathan Neal ", + "license": "CC0-1.0", + "repository": "jonathantneal/postcss-double-position-gradients", + "homepage": "https://github.com/jonathantneal/postcss-double-position-gradients#readme", + "bugs": "https://github.com/jonathantneal/postcss-double-position-gradients/issues", + "main": "index.cjs.js", + "module": "index.es.mjs", + "files": [ + "index.cjs.js", + "index.cjs.js.map", + "index.es.mjs", + "index.es.mjs.map" + ], + "scripts": { + "prepublishOnly": "npm test", + "pretest": "rollup -c .rollup.js --silent", + "test": "npm run test:js && npm run test:tape", + "test:js": "eslint *.js --cache --ignore-path .gitignore --quiet", + "test:tape": "postcss-tape" + }, + "engines": { + "node": ">=6.0.0" + }, + "dependencies": { + "postcss": "^7.0.5", + "postcss-values-parser": "^2.0.0" + }, + "devDependencies": { + "@babel/core": "^7.1.2", + "@babel/plugin-syntax-dynamic-import": "^7.0.0", + "@babel/preset-env": "^7.1.0", + "babel-eslint": "^10.0.1", + "eslint": "^5.8.0", + "eslint-config-dev": "^2.0.0", + "postcss-tape": "^2.2.0", + "pre-commit": "^1.2.2", + "rollup": "^0.66.6", + "rollup-plugin-babel": "^4.0.3" + }, + "eslintConfig": { + "extends": "dev", + "parser": "babel-eslint" + }, + "keywords": [ + "postcss", + "css", + "postcss-plugin", + "double", + "position", + "gradients", + "linear", + "radial", + "conic", + "color", + "stop", + "syntax", + "repeating" + ] +} diff --git a/test/basic.css b/test/basic.css new file mode 100644 index 0000000000..3873c9e78f --- /dev/null +++ b/test/basic.css @@ -0,0 +1,7 @@ +.test-linear-gradient { + background-image: linear-gradient(90deg, black 25% 50%, blue 50% 75%); +} + +.test-conic-gradient { + background-image: conic-gradient(yellowgreen 40%, gold 0deg 75%, #f06 0deg); +} diff --git a/test/basic.expect.css b/test/basic.expect.css new file mode 100644 index 0000000000..aba649d9c8 --- /dev/null +++ b/test/basic.expect.css @@ -0,0 +1,9 @@ +.test-linear-gradient { + background-image: linear-gradient(90deg, black 25%, black 50%, blue 50%, blue 75%); + background-image: linear-gradient(90deg, black 25% 50%, blue 50% 75%); +} + +.test-conic-gradient { + background-image: conic-gradient(yellowgreen 40%, gold 0deg, gold 75%, #f06 0deg); + background-image: conic-gradient(yellowgreen 40%, gold 0deg 75%, #f06 0deg); +} diff --git a/test/basic.preserve.expect.css b/test/basic.preserve.expect.css new file mode 100644 index 0000000000..730427d539 --- /dev/null +++ b/test/basic.preserve.expect.css @@ -0,0 +1,7 @@ +.test-linear-gradient { + background-image: linear-gradient(90deg, black 25%, black 50%, blue 50%, blue 75%); +} + +.test-conic-gradient { + background-image: conic-gradient(yellowgreen 40%, gold 0deg, gold 75%, #f06 0deg); +} From 9b1357c30b1ec4b4747a14ac01770bc966489e40 Mon Sep 17 00:00:00 2001 From: Jonathan Neal Date: Sat, 3 Nov 2018 23:25:07 -0500 Subject: [PATCH 741/795] 2.0.0 --- .gitignore | 5 +- .rollup.client.js | 16 ------ .rollup.js | 41 ++++++++++++++ .rollup.postcss.js | 16 ------ CHANGELOG.md | 8 +++ INSTALL.md | 2 +- README.md | 133 +++++++++++++++++++++++++++++++++++++-------- package.json | 42 ++++++++------ src/browser.js | 61 +++++++++++++++++++++ src/client.js | 21 ------- src/postcss.js | 24 +++++--- 11 files changed, 264 insertions(+), 105 deletions(-) delete mode 100644 .rollup.client.js create mode 100644 .rollup.js delete mode 100644 .rollup.postcss.js create mode 100644 src/browser.js delete mode 100644 src/client.js diff --git a/.gitignore b/.gitignore index 8435b82030..49860a73a3 100644 --- a/.gitignore +++ b/.gitignore @@ -1,11 +1,12 @@ node_modules -/client.* +/browser.* +/index.* /postcss.* package-lock.json *.log* .* !.editorconfig !.gitignore -!.rollup.*.js +!.rollup.js !.tape.js !.travis.yml diff --git a/.rollup.client.js b/.rollup.client.js deleted file mode 100644 index 900f9b6a99..0000000000 --- a/.rollup.client.js +++ /dev/null @@ -1,16 +0,0 @@ -import babel from 'rollup-plugin-babel'; - -export default { - input: 'src/client.js', - output: [ - { file: 'client.js', format: 'cjs' }, - { file: 'client.mjs', format: 'es' } - ], - plugins: [ - babel({ - presets: [ - ['@babel/env', { modules: false, targets: { node: 6 } }] - ] - }) - ] -}; diff --git a/.rollup.js b/.rollup.js new file mode 100644 index 0000000000..29f1930a87 --- /dev/null +++ b/.rollup.js @@ -0,0 +1,41 @@ +import babel from 'rollup-plugin-babel'; +import { terser } from 'rollup-plugin-terser'; + +const isBrowser = String(process.env.NODE_ENV).includes('browser'); +const isBrowserMin = String(process.env.NODE_ENV).includes('browser:min'); +const isPostCSS = String(process.env.NODE_ENV).includes('postcss'); + +// support IE9+ browsers, otherwise node 6+ +const targets = isBrowser ? 'ie >= 9' : { node: 6 }; + +// read from src/browser.js for browsers/node, src/postcss.js for postcss +const input = isPostCSS ? 'src/postcss.js' : 'src/browser.js'; + +// write to browser.js/browser.min.js for browsers, index.js/index.mjs for node +const output = isPostCSS + ? [ + { file: 'postcss.js', format: 'cjs' }, + { file: 'postcss.mjs', format: 'esm' } +] : isBrowser + ? { file: `browser${isBrowserMin ? '.min' : ''}.js`, format: 'iife', name: 'initPrefersColorScheme', sourcemap: !isBrowserMin } +: [ + { file: 'index.js', format: 'cjs', sourcemap: true }, + { file: 'index.mjs', format: 'es', sourcemap: true } +]; + +// use babel, and also terser to minify browser.min.js +const plugins = [ + babel({ + presets: [ + ['@babel/env', { modules: false, targets }] + ] + }) +].concat( + isBrowserMin + ? terser({ + mangle: true + }) + : [] +); + +export default { input, output, plugins }; diff --git a/.rollup.postcss.js b/.rollup.postcss.js deleted file mode 100644 index 1b8d1a3d4b..0000000000 --- a/.rollup.postcss.js +++ /dev/null @@ -1,16 +0,0 @@ -import babel from 'rollup-plugin-babel'; - -export default { - input: 'src/postcss.js', - output: [ - { file: 'postcss.js', format: 'cjs' }, - { file: 'postcss.mjs', format: 'es' } - ], - plugins: [ - babel({ - presets: [ - ['@babel/env', { modules: false, targets: { node: 6 } }] - ] - }) - ] -}; diff --git a/CHANGELOG.md b/CHANGELOG.md index 7758189106..9e83229651 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,13 @@ # Changes to Prefers Color Scheme +### 2.0.0 (November 3, 2018) + +- The client library now returns an object with various features, including: + - `scheme` to get or set the preferred color scheme + - `hasNativeSupport` to report whether `prefers-color-scheme` is supported + - `onChange` to listen for when the preferred color scheme changes + - `removeListener` to destroy the native `prefers-color-scheme` listener + ### 1.0.0 (September 24, 2018) - Initial version diff --git a/INSTALL.md b/INSTALL.md index 9620bbbf4b..b5ec99dd75 100644 --- a/INSTALL.md +++ b/INSTALL.md @@ -11,7 +11,7 @@ instructions for: Add [Prefers Color Scheme] to your project: ```bash -npm install css-prefers-color-scheme --save-dev +npm install css-prefers-color-scheme ``` Use [Prefers Color Scheme] to process your CSS: diff --git a/README.md b/README.md index c86d0a73f7..c35ba8c9c6 100644 --- a/README.md +++ b/README.md @@ -4,13 +4,23 @@ [![Build Status][cli-img]][cli-url] [![Support Chat][git-img]][git-url] -[Prefers Color Scheme] lets you use light or dark color themes in CSS, -following the [Media Queries] specification. +[Prefers Color Scheme] lets you use light and dark color schemes in all +browsers, following the [Media Queries] specification. ```bash npm install css-prefers-color-scheme ``` +There are 2 steps required to get color schemes working: + +- Transform your queries using the included [PostCSS plugin](#PostCSS-Plugin). +- Apply your queries using the included [browser library](#Browser-Library). + +## PostCSS Plugin + +[Prefers Color Scheme] transforms `prefers-color-scheme` media queries into +something all browsers understand. + ```css @media (prefers-color-scheme: dark) { :root { @@ -24,11 +34,9 @@ body { color: var(--site-color, #111); font: 100%/1.5 system-ui; } -``` -[PostCSS] transforms these into cross-browser compatible `color-index` queries: +/* becomes */ -```css @media (color-index: 48) { :root { --site-bgcolor: #1b1b1b; @@ -43,31 +51,102 @@ body { } ``` -`CSS._prefersColorScheme()` applies these “light mode” and “dark mode” queries -to documents on the fly. The entire frontend script is less than 300 bytes. +## Browser Library -[Prefers Color Scheme] works in all major browsers, including Safari 6+ and -Internet Explorer 9+. -[See it for yourself.](https://app.crossbrowsertesting.com/public/i76b092cd2b52b86/screenshots/z25c0ccdfcc9c9b8956f?size=medium&type=windowed) +[Prefers Color Scheme] applies color schemes previously transformed by the +[PostCSS plugin](#PostCSS-Plugin). ```js -const prefersColorScheme = require('css-prefers-color-scheme'); +// initialize prefersColorScheme (applies the system color scheme, if available) +const prefersColorScheme = require('css-prefers-color-scheme')(); // apply "dark" queries -prefersColorScheme('dark'); +prefersColorScheme.scheme = 'dark'; // apply "light" queries (also disabling "dark" queries) -prefersColorScheme('light'); +prefersColorScheme.scheme = 'light'; ``` -## PostCSS Usage +The script is also available from the [unpkg.com](https://unpkg.com/) CDN: -Add [Prefers Color Scheme] to your project: +```html + + +``` -```bash -npm install css-prefers-color-scheme --save-dev +A minified version is also available: + +```html + + +``` + +[Prefers Color Scheme] works in all major browsers, including Safari 6+ and +Internet Explorer 9+ without any polyfills. +[See it for yourself.](https://app.crossbrowsertesting.com/public/i76b092cd2b52b86/screenshots/z25c0ccdfcc9c9b8956f?size=medium&type=windowed) + +--- + +## Browser Usage + +Use [Prefers Color Scheme] to activate your `prefers-color-scheme` queries: + +```js +const prefersColorScheme = require('css-prefers-color-scheme')(); +``` + +By default, the system color scheme is applied, if your browser supports it. +Otherwise, the light color scheme is applied. You may override this by passing +in a color scheme. + +```js +const prefersColorScheme = require('css-prefers-color-scheme')('dark'); +``` + +The `prefersColorScheme` object returns the following properties: + +### value + +The `value` property returns the currently preferred color scheme, and can be +set to change it. + +```js +const prefersColorScheme = require('css-prefers-color-scheme')(); + +// log the preferred color scheme +console.log(prefersColorScheme.scheme); + +// apply "dark" queries +prefersColorScheme.scheme = 'dark'; ``` +### hasNativeSupport + +The `hasNativeSupport` boolean represents whether `prefers-color-scheme` is +supported by the current browser. + +### onChange + +The `onChange` function can be added in order to listen for changes to the +preferred color scheme, whether they are triggered by the system or manually by +the `change` function. + +### removeListener + +The `removeListener` function removes the native `prefers-color-scheme` +listener, which may or may not be applied, depending on your browser support. +This is provided to give you complete control over plugin cleanup. + +--- + +## PostCSS Usage + Use [Prefers Color Scheme] to process your CSS: ```js @@ -95,19 +174,25 @@ instructions for: --- -## How does the frontend work? +## How does it work? + +The [Prefers Color Scheme] [PostCSS plugin](#PostCSS-Plugin) transforms +`prefers-color-scheme` queries into `color-index` queries, changing +`prefers-color-scheme: dark` into `(color-index: 48)`, +`prefers-color-scheme: light` into `(color-index: 70)`, and +`prefers-color-scheme: no-preference` into `(color-index: 22)`. -The `color-index` media query is understood in all major browsers going back to -Internet Explorer 9, but all implementations only seem to allow a `color-index` -of `0`. +The frontend receives these `color-index` queries, which are understood in all +major browsers going back to Internet Explorer 9. However, all browsers only +apply a `color-index` of `0`, so all other values are otherwise ignored. -This script changes `(color-index: 48)` queries into +[Prefers Color Scheme] changes `(color-index: 48)` queries into `not all and (color-index: 48)` to activate “dark mode” specific CSS, and then it inverts `(color-index: 70)` queries into `not all and (color-index: 48)` to activate “light mode” specific CSS. ```css -@media (color-index: 70) { /* "light" query */ +@media (color-index: 70) { /* prefers-color-scheme: light */ body { background-color: white; color: black; @@ -116,7 +201,7 @@ to activate “light mode” specific CSS. ``` These valid queries are accessible to `document.styleSheet`, so no css parsing -is required to use this library, which is how the script is less than 300 bytes. +is required to use this library, which is how the script is only 482 bytes. ## Why does the fallback work this way? diff --git a/package.json b/package.json index 8eed73de25..070beba238 100644 --- a/package.json +++ b/package.json @@ -1,27 +1,33 @@ { "name": "css-prefers-color-scheme", - "version": "1.0.0", - "description": "Use a light or dark color theme in CSS CSS", + "version": "2.0.0", + "description": "Use light and dark color schemes in all browsers", "author": "Jonathan Neal ", "license": "CC0-1.0", "repository": "csstools/css-prefers-color-scheme", "homepage": "https://github.com/csstools/css-prefers-color-scheme#readme", "bugs": "https://github.com/csstools/css-prefers-color-scheme/issues", - "main": "client.js", - "module": "client.mjs", + "main": "index.js", + "module": "index.mjs", "files": [ - "client.js", - "client.mjs", + "browser.js", + "browser.js.map", + "browser.min.js", + "index.mjs", + "index.js", "postcss.js", "postcss.mjs" ], "scripts": { - "build": "npm run build:client && npm run build:postcss", - "build:client": "rollup -c .rollup.client.js --silent", - "build:postcss": "rollup -c .rollup.postcss.js --silent", + "build": "npm run build:browser && npm run build:node && npm run build:postcss", + "build:browser": "npm run build:browser:dist && npm run build:browser:min", + "build:browser:dist": "cross-env NODE_ENV=browser rollup -c .rollup.js --silent", + "build:browser:min": "cross-env NODE_ENV=browser:min rollup -c .rollup.js --silent", + "build:node": "rollup -c .rollup.js --silent", + "build:postcss": "cross-env NODE_ENV=postcss rollup -c .rollup.js --silent", "prepublishOnly": "npm test", "pretest": "npm run build", - "test": "echo 'Running tests...'; npm run test:js && npm run test:tape", + "test": "npm run test:js && npm run test:tape", "test:js": "eslint src/*.js --cache --ignore-path .gitignore --quiet", "test:tape": "postcss-tape --plugin=postcss.js" }, @@ -29,18 +35,20 @@ "node": ">=6.0.0" }, "dependencies": { - "postcss": "^7.0.2" + "postcss": "^7.0.5" }, "devDependencies": { - "@babel/core": "^7.1.0", - "@babel/preset-env": "^7.0.0", - "babel-eslint": "^9.0.0", - "eslint": "^5.6.0", + "@babel/core": "^7.1.2", + "@babel/preset-env": "^7.1.0", + "babel-eslint": "^10.0.1", + "cross-env": "^5.2.0", + "eslint": "^5.8.0", "eslint-config-dev": "^2.0.0", "postcss-tape": "^2.2.0", "pre-commit": "^1.2.2", - "rollup": "^0.66.2", - "rollup-plugin-babel": "^4.0.1", + "rollup": "^0.66.6", + "rollup-plugin-babel": "^4.0.3", + "rollup-plugin-terser": "^3.0.0", "uglify-js": "^3.4.9" }, "eslintConfig": { diff --git a/src/browser.js b/src/browser.js new file mode 100644 index 0000000000..dba0990d26 --- /dev/null +++ b/src/browser.js @@ -0,0 +1,61 @@ +const colorIndexRegExp = /((?:not )?all and )?(\(color-index:\s*(22|48|70)\))/i; + +const prefersColorSchemeInit = initialColorScheme => { + const mediaQueryString = '(prefers-color-scheme: dark)'; + const mediaQueryList = window.matchMedia && matchMedia(mediaQueryString); + const hasNativeSupport = mediaQueryList && mediaQueryList.media === mediaQueryString; + const mediaQueryListener = () => { + set(mediaQueryList.matches ? 'dark' : 'light'); + }; + const removeListener = () => { + if (mediaQueryList) { + mediaQueryList.removeListener(mediaQueryListener); + } + }; + const set = colorScheme => { + if (colorScheme !== currentColorScheme) { + currentColorScheme = colorScheme; + + if (typeof result.onChange === 'function') { + result.onChange(); + } + } + + [].forEach.call(document.styleSheets, styleSheet => { + [].forEach.call(styleSheet.cssRules, cssRule => { + const mediaMatch = (Object(cssRule.media).mediaText || '').match(colorIndexRegExp); + + if (mediaMatch) { + cssRule.media.mediaText = ( + (/^dark$/i.test(colorScheme) + ? mediaMatch[3] === '48' + : /^light$/i.test(colorScheme) + ? mediaMatch[3] === '70' + : mediaMatch[3] === '22') + ? 'not all and ' + : '' + ) + cssRule.media.mediaText.replace(colorIndexRegExp, '$2'); + } + }); + }); + }; + const result = Object.defineProperty( + { hasNativeSupport, removeListener }, + 'scheme', + { get: () => currentColorScheme, set } + ); + + // initialize the color scheme using the provided value, the system value, or light + let currentColorScheme = initialColorScheme || (mediaQueryList && mediaQueryList.matches ? 'dark' : 'light'); + + set(currentColorScheme); + + // listen for system changes + if (mediaQueryList) { + mediaQueryList.addListener(mediaQueryListener); + } + + return result; +}; + +export default prefersColorSchemeInit; diff --git a/src/client.js b/src/client.js deleted file mode 100644 index f867d3d5cc..0000000000 --- a/src/client.js +++ /dev/null @@ -1,21 +0,0 @@ -const colorIndexRegExp = /((?:not )?all and )?(\(color-index:\s*(22|48|70)\))/i; - -export default style => { - [].forEach.call(document.styleSheets, styleSheet => { - [].forEach.call(styleSheet.cssRules, cssRule => { - const mediaMatch = (Object(cssRule.media).mediaText || '').match(colorIndexRegExp); - - if (mediaMatch) { - cssRule.media.mediaText = ( - (/^dark$/i.test(style) - ? mediaMatch[3] === '48' - : /^light$/i.test(style) - ? mediaMatch[3] === '70' - : mediaMatch[3] === '22') - ? 'not all and ' - : '' - ) + cssRule.media.mediaText.replace(colorIndexRegExp, '$2'); - } - }); - }); -}; diff --git a/src/postcss.js b/src/postcss.js index 2a949c5779..cf92ab1790 100644 --- a/src/postcss.js +++ b/src/postcss.js @@ -5,13 +5,21 @@ const prefersInterfaceRegExp = /\(\s*prefers-color-scheme\s*:\s*(dark|light|no-p const colorIndexByStyle = { dark: 48, light: 70, 'no-preference': 22 }; const prefersInterfaceReplacer = ($0, style) => `(color-index: ${colorIndexByStyle[style.toLowerCase()]})`; -export default postcss.plugin('postcss-prefers-color-scheme', () => root => { - root.walkAtRules(mediaRegExp, atRule => { - const { params } = atRule; - const altParams = params.replace(prefersInterfaceRegExp, prefersInterfaceReplacer); +export default postcss.plugin('postcss-prefers-color-scheme', opts => { + const preserve = 'preserve' in Object(opts) ? opts.preserve : false; - if (params !== altParams) { - atRule.params = altParams; - } - }); + return root => { + root.walkAtRules(mediaRegExp, atRule => { + const { params } = atRule; + const altParams = params.replace(prefersInterfaceRegExp, prefersInterfaceReplacer); + + if (params !== altParams) { + if (preserve) { + atRule.cloneBefore({ params: altParams }); + } else { + atRule.params = altParams; + } + } + }); + } }); From 9645af4169ef6933154e0591d042136fc254a5b0 Mon Sep 17 00:00:00 2001 From: Jonathan Neal Date: Sun, 4 Nov 2018 11:39:13 -0500 Subject: [PATCH 742/795] 3.0.0 --- CHANGELOG.md | 5 +++++ README.md | 42 +++++++++++++++++++++++++++++++++++++++++- package.json | 4 +++- src/browser.js | 39 ++++++++++++++++++++++++--------------- src/postcss.js | 2 +- test/basic.expect.css | 21 +++++++++++++++++++++ test/basic.result.css | 21 +++++++++++++++++++++ 7 files changed, 116 insertions(+), 18 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9e83229651..7d21e33920 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,10 @@ # Changes to Prefers Color Scheme +### 3.0.0 (November 4, 2018) + +- Preserve `prefers-color-scheme` queries by default for non-JS environments +- Remove `prefers-color-scheme` queries on the frontend for JS environments + ### 2.0.0 (November 3, 2018) - The client library now returns an object with various features, including: diff --git a/README.md b/README.md index c35ba8c9c6..14065a18cb 100644 --- a/README.md +++ b/README.md @@ -44,6 +44,13 @@ body { } } +@media (prefers-color-scheme: dark) { + :root { + --site-bgcolor: #1b1b1b; + --site-color: #fff; + } +} + body { background-color: var(--site-bgcolor, #f9f9f9); color: var(--site-color, #111); @@ -91,6 +98,11 @@ initPrefersColorScheme() Internet Explorer 9+ without any polyfills. [See it for yourself.](https://app.crossbrowsertesting.com/public/i76b092cd2b52b86/screenshots/z25c0ccdfcc9c9b8956f?size=medium&type=windowed) +To maintain compatibility with browsers supporting `prefers-color-scheme`, the +library will remove `prefers-color-scheme` media queries in favor of the +cross-browser compatible `color-index` media queries. This ensures a seemless +experience when JavaScript is unable to run. + --- ## Browser Usage @@ -172,6 +184,34 @@ instructions for: | [Node](INSTALL.md#node) | [Webpack](INSTALL.md#webpack) | [Create React App](INSTALL.md#create-react-app) | [Gulp](INSTALL.md#gulp) | [Grunt](INSTALL.md#grunt) | | --- | --- | --- | --- | --- | +### Options + +#### preserve + +The `preserve` option determines whether the original `prefers-color-scheme` +query will be preserved or removed. By default, it is preserved. + + +```js +require('css-prefers-color-scheme/postcss')({ preserve: false }); +``` + +```css +@media (prefers-color-scheme: dark) { + body { + background-color: black; + } +} + +/* becomes */ + +@media (color-index: 48) { + body { + background-color: black; + } +} +``` + --- ## How does it work? @@ -201,7 +241,7 @@ to activate “light mode” specific CSS. ``` These valid queries are accessible to `document.styleSheet`, so no css parsing -is required to use this library, which is how the script is only 482 bytes. +is required to use this library, which is how the script is only 539 bytes. ## Why does the fallback work this way? diff --git a/package.json b/package.json index 070beba238..93d27e7aef 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "css-prefers-color-scheme", - "version": "2.0.0", + "version": "3.0.0", "description": "Use light and dark color schemes in all browsers", "author": "Jonathan Neal ", "license": "CC0-1.0", @@ -14,7 +14,9 @@ "browser.js.map", "browser.min.js", "index.mjs", + "index.mjs.map", "index.js", + "index.js.map", "postcss.js", "postcss.mjs" ], diff --git a/src/browser.js b/src/browser.js index dba0990d26..337f2b4b2a 100644 --- a/src/browser.js +++ b/src/browser.js @@ -1,4 +1,5 @@ -const colorIndexRegExp = /((?:not )?all and )?(\(color-index:\s*(22|48|70)\))/i; +const colorIndexRegExp = /((?:not )?all and )?(\(color-index: *(22|48|70)\))/i; +const prefersColorSchemeRegExp = /prefers-color-scheme:/i; const prefersColorSchemeInit = initialColorScheme => { const mediaQueryString = '(prefers-color-scheme: dark)'; @@ -21,20 +22,28 @@ const prefersColorSchemeInit = initialColorScheme => { } } - [].forEach.call(document.styleSheets, styleSheet => { - [].forEach.call(styleSheet.cssRules, cssRule => { - const mediaMatch = (Object(cssRule.media).mediaText || '').match(colorIndexRegExp); - - if (mediaMatch) { - cssRule.media.mediaText = ( - (/^dark$/i.test(colorScheme) - ? mediaMatch[3] === '48' - : /^light$/i.test(colorScheme) - ? mediaMatch[3] === '70' - : mediaMatch[3] === '22') - ? 'not all and ' - : '' - ) + cssRule.media.mediaText.replace(colorIndexRegExp, '$2'); + [].forEach.call(document.styleSheets || [], styleSheet => { + [].forEach.call(styleSheet.cssRules || [], cssRule => { + const colorSchemeMatch = prefersColorSchemeRegExp.test(Object(cssRule.media).mediaText); + + if (colorSchemeMatch) { + const index = [].indexOf.call(cssRule.parentStyleSheet.cssRules, cssRule); + + cssRule.parentStyleSheet.deleteRule(index); + } else { + const colorIndexMatch = (Object(cssRule.media).mediaText || '').match(colorIndexRegExp); + + if (colorIndexMatch) { + cssRule.media.mediaText = ( + (/^dark$/i.test(colorScheme) + ? colorIndexMatch[3] === '48' + : /^light$/i.test(colorScheme) + ? colorIndexMatch[3] === '70' + : colorIndexMatch[3] === '22') + ? 'not all and ' + : '' + ) + cssRule.media.mediaText.replace(colorIndexRegExp, '$2'); + } } }); }); diff --git a/src/postcss.js b/src/postcss.js index cf92ab1790..8038d0f103 100644 --- a/src/postcss.js +++ b/src/postcss.js @@ -6,7 +6,7 @@ const colorIndexByStyle = { dark: 48, light: 70, 'no-preference': 22 }; const prefersInterfaceReplacer = ($0, style) => `(color-index: ${colorIndexByStyle[style.toLowerCase()]})`; export default postcss.plugin('postcss-prefers-color-scheme', opts => { - const preserve = 'preserve' in Object(opts) ? opts.preserve : false; + const preserve = 'preserve' in Object(opts) ? opts.preserve : true; return root => { root.walkAtRules(mediaRegExp, atRule => { diff --git a/test/basic.expect.css b/test/basic.expect.css index 4915583baf..cd2d47a640 100644 --- a/test/basic.expect.css +++ b/test/basic.expect.css @@ -5,6 +5,13 @@ } } +@media (prefers-color-scheme: no-preference) { + :root { + --site-bgcolor: #f9f9f9; + --site-color: #111; + } +} + @media (color-index: 48) { :root { --site-bgcolor: #1b1b1b; @@ -12,6 +19,13 @@ } } +@media (prefers-color-scheme: dark) { + :root { + --site-bgcolor: #1b1b1b; + --site-color: #fff; + } +} + @media (color-index: 70) { :root { --site-bgcolor: #fff; @@ -19,6 +33,13 @@ } } +@media (prefers-color-scheme: light) { + :root { + --site-bgcolor: #fff; + --site-color: #222; + } +} + body { background-color: var(--site-bgcolor, #f9f9f9); color: var(--site-color, #111); diff --git a/test/basic.result.css b/test/basic.result.css index 4915583baf..cd2d47a640 100644 --- a/test/basic.result.css +++ b/test/basic.result.css @@ -5,6 +5,13 @@ } } +@media (prefers-color-scheme: no-preference) { + :root { + --site-bgcolor: #f9f9f9; + --site-color: #111; + } +} + @media (color-index: 48) { :root { --site-bgcolor: #1b1b1b; @@ -12,6 +19,13 @@ } } +@media (prefers-color-scheme: dark) { + :root { + --site-bgcolor: #1b1b1b; + --site-color: #fff; + } +} + @media (color-index: 70) { :root { --site-bgcolor: #fff; @@ -19,6 +33,13 @@ } } +@media (prefers-color-scheme: light) { + :root { + --site-bgcolor: #fff; + --site-color: #222; + } +} + body { background-color: var(--site-bgcolor, #f9f9f9); color: var(--site-color, #111); From 67e984287cdd6fb81f77f0a661c5050be3bb7d82 Mon Sep 17 00:00:00 2001 From: Jonathan Neal Date: Mon, 5 Nov 2018 16:39:25 -0500 Subject: [PATCH 743/795] 8.0.9 --- .rollup.js | 4 ++-- CHANGELOG.md | 4 ++++ README.md | 2 +- lib/transform-value-ast.js | 8 +++++--- package.json | 12 ++++++------ test/basic.css | 4 ++++ test/basic.expect.css | 5 +++++ test/basic.import-is-empty.expect.css | 5 +++++ test/basic.import.expect.css | 5 +++++ test/basic.preserve.expect.css | 4 ++++ 10 files changed, 41 insertions(+), 12 deletions(-) diff --git a/.rollup.js b/.rollup.js index 3f28a5511b..b9622020a0 100644 --- a/.rollup.js +++ b/.rollup.js @@ -4,7 +4,7 @@ export default { input: 'index.js', output: [ { file: 'index.cjs.js', format: 'cjs', sourcemap: true }, - { file: 'index.es.mjs', format: 'es', sourcemap: true } + { file: 'index.esm.mjs', format: 'esm', sourcemap: true } ], plugins: [ babel({ @@ -12,7 +12,7 @@ export default { '@babel/plugin-syntax-dynamic-import' ], presets: [ - ['@babel/env', { modules: false, targets: { node: 6 } }] + ['@babel/env', { targets: { node: 6 } }] ] }) ] diff --git a/CHANGELOG.md b/CHANGELOG.md index 930be92ac4..24f7183cb6 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # Changes to PostCSS Custom Properties +### 8.0.9 (November 5, 2018) + +- Fixed: Issue with duplicate custom property usage within a declaration + ### 8.0.8 (October 2, 2018) - Fixed: Issue with nested fallbacks diff --git a/README.md b/README.md index 1a0f7b223a..def07cba6c 100755 --- a/README.md +++ b/README.md @@ -179,7 +179,7 @@ See example exports written to [CSS](test/export-properties.css), [JS](test/export-properties.js), [MJS](test/export-properties.mjs), and [JSON](test/export-properties.json). -[cli-img]: https://img.shields.io/travis/postcss/postcss-custom-properties.svg +[cli-img]: https://img.shields.io/travis/postcss/postcss-custom-properties/master.svg [cli-url]: https://travis-ci.org/postcss/postcss-custom-properties [css-img]: https://cssdb.org/badge/custom-properties.svg [css-url]: https://cssdb.org/#custom-properties diff --git a/lib/transform-value-ast.js b/lib/transform-value-ast.js index 3d9d299434..209af61c5e 100644 --- a/lib/transform-value-ast.js +++ b/lib/transform-value-ast.js @@ -8,9 +8,11 @@ export default function transformValueAST(root, customProperties) { if (name in customProperties) { // conditionally replace a known custom property - child.replaceWith(...asClonedArrayWithBeforeSpacing(customProperties[name], child.raws.before)); + const nodes = asClonedArrayWithBeforeSpacing(customProperties[name], child.raws.before); - retransformValueAST(root, customProperties, name); + child.replaceWith(...nodes); + + retransformValueAST({ nodes }, customProperties, name); } else if (fallbacks.length) { // conditionally replace a custom property with a fallback const index = root.nodes.indexOf(child); @@ -24,7 +26,7 @@ export default function transformValueAST(root, customProperties) { } else { transformValueAST(child, customProperties); } - }) + }); } return root; diff --git a/package.json b/package.json index 96a7a27a3f..60b59a57e9 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "postcss-custom-properties", - "version": "8.0.8", + "version": "8.0.9", "description": "Use Custom Properties Queries in CSS", "author": "Jonathan Neal ", "contributors": [ @@ -11,12 +11,12 @@ "homepage": "https://github.com/postcss/postcss-custom-properties#readme", "bugs": "https://github.com/postcss/postcss-custom-properties/issues", "main": "index.cjs.js", - "module": "index.es.mjs", + "module": "index.esm.mjs", "files": [ "index.cjs.js", "index.cjs.js.map", - "index.es.mjs", - "index.es.mjs.map" + "index.esm.mjs", + "index.esm.mjs.map" ], "scripts": { "prepublishOnly": "npm test", @@ -37,11 +37,11 @@ "@babel/plugin-syntax-dynamic-import": "^7.0.0", "@babel/preset-env": "^7.1.0", "babel-eslint": "^10.0.1", - "eslint": "^5.6.1", + "eslint": "^5.8.0", "eslint-config-dev": "^2.0.0", "postcss-tape": "^2.2.0", "pre-commit": "^1.2.2", - "rollup": "^0.66.2", + "rollup": "^0.67.0", "rollup-plugin-babel": "^4.0.3" }, "eslintConfig": { diff --git a/test/basic.css b/test/basic.css index e095be9cfc..c781c8251d 100644 --- a/test/basic.css +++ b/test/basic.css @@ -42,3 +42,7 @@ html { .text--calc { width: calc((100% - var(--xxx, 1px)) + var(--yyy, 10px)); } + +.test--linear-gradient { + background-image: linear-gradient(to right, var(--color, transparent) 0%, var(--color, transparent) 100%); +} diff --git a/test/basic.expect.css b/test/basic.expect.css index 9bb775a618..03b565ef82 100644 --- a/test/basic.expect.css +++ b/test/basic.expect.css @@ -49,3 +49,8 @@ html { width: calc((100% - 1px) + 10px); width: calc((100% - var(--xxx, 1px)) + var(--yyy, 10px)); } + +.test--linear-gradient { + background-image: linear-gradient(to right, rgb(255, 0, 0) 0%, rgb(255, 0, 0) 100%); + background-image: linear-gradient(to right, var(--color, transparent) 0%, var(--color, transparent) 100%); +} diff --git a/test/basic.import-is-empty.expect.css b/test/basic.import-is-empty.expect.css index 9bb775a618..03b565ef82 100644 --- a/test/basic.import-is-empty.expect.css +++ b/test/basic.import-is-empty.expect.css @@ -49,3 +49,8 @@ html { width: calc((100% - 1px) + 10px); width: calc((100% - var(--xxx, 1px)) + var(--yyy, 10px)); } + +.test--linear-gradient { + background-image: linear-gradient(to right, rgb(255, 0, 0) 0%, rgb(255, 0, 0) 100%); + background-image: linear-gradient(to right, var(--color, transparent) 0%, var(--color, transparent) 100%); +} diff --git a/test/basic.import.expect.css b/test/basic.import.expect.css index 685f245a3f..2bb29c07b7 100644 --- a/test/basic.import.expect.css +++ b/test/basic.import.expect.css @@ -50,3 +50,8 @@ html { width: calc((100% - 1px) + 10px); width: calc((100% - var(--xxx, 1px)) + var(--yyy, 10px)); } + +.test--linear-gradient { + background-image: linear-gradient(to right, rgb(255, 0, 0) 0%, rgb(255, 0, 0) 100%); + background-image: linear-gradient(to right, var(--color, transparent) 0%, var(--color, transparent) 100%); +} diff --git a/test/basic.preserve.expect.css b/test/basic.preserve.expect.css index 9340268416..47174d8da9 100644 --- a/test/basic.preserve.expect.css +++ b/test/basic.preserve.expect.css @@ -34,3 +34,7 @@ .text--calc { width: calc((100% - 1px) + 10px); } + +.test--linear-gradient { + background-image: linear-gradient(to right, rgb(255, 0, 0) 0%, rgb(255, 0, 0) 100%); +} From 01a507f314758792aac0d76364147ed29eee44c1 Mon Sep 17 00:00:00 2001 From: Jonathan Neal Date: Sat, 10 Nov 2018 16:12:58 -0500 Subject: [PATCH 744/795] 3.1.0 --- CHANGELOG.md | 5 + README-BROWSER.md | 85 +++++++++++++++++ README-POSTCSS.md | 115 +++++++++++++++++++++++ README.md | 229 +++++---------------------------------------- package.json | 14 ++- src/postcss-cli.js | 104 ++++++++++++++++++++ 6 files changed, 344 insertions(+), 208 deletions(-) create mode 100644 README-BROWSER.md create mode 100644 README-POSTCSS.md create mode 100755 src/postcss-cli.js diff --git a/CHANGELOG.md b/CHANGELOG.md index 7d21e33920..425a349b1c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,10 @@ # Changes to Prefers Color Scheme +### 3.1.0 (November 10, 2018) + +- Include CLI tool for transforming CSS without any installation +- Update documentation + ### 3.0.0 (November 4, 2018) - Preserve `prefers-color-scheme` queries by default for non-JS environments diff --git a/README-BROWSER.md b/README-BROWSER.md new file mode 100644 index 0000000000..99e1f0c202 --- /dev/null +++ b/README-BROWSER.md @@ -0,0 +1,85 @@ +# Prefers Color Scheme [][Prefers Color Scheme] + +[![NPM Version][npm-img]][npm-url] +[![Build Status][cli-img]][cli-url] +[![Support Chat][git-img]][git-url] + +[Prefers Color Scheme] applies color schemes with fallbacks provided by the +[Prefers Color Scheme PostCSS plugin](README-POSTCSS.md). + +```js +// initialize prefersColorScheme (applies the current OS color scheme, if available) +const prefersColorScheme = require('css-prefers-color-scheme')(); + +// apply "dark" queries (you can also apply "light") +prefersColorScheme.scheme = 'dark'; +``` + +[Prefers Color Scheme] works in all major browsers, including Safari 6+ and +Internet Explorer 9+ without any polyfills. +[See it for yourself.](https://app.crossbrowsertesting.com/public/i76b092cd2b52b86/screenshots/z25c0ccdfcc9c9b8956f?size=medium&type=windowed) + +To maintain compatibility with browsers supporting `prefers-color-scheme`, the +library will remove `prefers-color-scheme` media queries in favor of +cross-browser compatible `color-index` media queries. This ensures a seemless +experience, even when JavaScript is unable to run. + +## Usage + +Use [Prefers Color Scheme] to activate your `prefers-color-scheme` queries: + +```js +const prefersColorScheme = require('css-prefers-color-scheme')(); +``` + +By default, the current OS color scheme is applied if your browser supports it. +Otherwise, the light color scheme is applied. You may override this by passing +in a color scheme. + +```js +const prefersColorScheme = require('css-prefers-color-scheme')('dark'); +``` + +The `prefersColorScheme` object returns the following properties — `value`, +`hasNativeSupport`, `onChange`, and `removeListener`. + +### value + +The `value` property returns the currently preferred color scheme, and it can +be changed. + +```js +const prefersColorScheme = require('css-prefers-color-scheme')(); + +// log the preferred color scheme +console.log(prefersColorScheme.scheme); + +// apply "dark" queries +prefersColorScheme.scheme = 'dark'; +``` + +### hasNativeSupport + +The `hasNativeSupport` boolean represents whether `prefers-color-scheme` is +supported by the browser. + +### onChange + +The optional `onChange` function is run when the preferred color scheme is +changed, either from the OS or manually. + +### removeListener + +The `removeListener` function removes the native `prefers-color-scheme` +listener, which may or may not be applied, depending on your browser support. +This is provided to give you complete control over plugin cleanup. + +[cli-img]: https://img.shields.io/travis/csstools/css-prefers-color-scheme.svg +[cli-url]: https://travis-ci.org/csstools/css-prefers-color-scheme +[git-img]: https://img.shields.io/badge/support-chat-blue.svg +[git-url]: https://gitter.im/postcss/postcss +[npm-img]: https://img.shields.io/npm/v/css-prefers-color-scheme.svg +[npm-url]: https://www.npmjs.com/package/css-prefers-color-scheme + +[PostCSS]: https://github.com/postcss/postcss +[Prefers Color Scheme]: https://github.com/csstools/css-prefers-color-scheme diff --git a/README-POSTCSS.md b/README-POSTCSS.md new file mode 100644 index 0000000000..6f90a8cf3e --- /dev/null +++ b/README-POSTCSS.md @@ -0,0 +1,115 @@ +# Prefers Color Scheme [][Prefers Color Scheme] + +[![NPM Version][npm-img]][npm-url] +[![Build Status][cli-img]][cli-url] +[![Support Chat][git-img]][git-url] + +[Prefers Color Scheme] transforms `prefers-color-scheme` media queries into +something all browsers understand. + +```css +@media (prefers-color-scheme: dark) { + :root { + --site-bgcolor: #1b1b1b; + --site-color: #fff; + } +} + +body { + background-color: var(--site-bgcolor, #f9f9f9); + color: var(--site-color, #111); + font: 100%/1.5 system-ui; +} + +/* becomes */ + +@media (color-index: 48) { + :root { + --site-bgcolor: #1b1b1b; + --site-color: #fff; + } +} + +@media (prefers-color-scheme: dark) { + :root { + --site-bgcolor: #1b1b1b; + --site-color: #fff; + } +} + +body { + background-color: var(--site-bgcolor, #f9f9f9); + color: var(--site-color, #111); + font: 100%/1.5 system-ui; +} +``` + +## Usage + +Use [Prefers Color Scheme] to process your CSS: + +```bash +npx css-prefers-color-scheme INPUT.css OUTPUT.css +``` + +Or use it within Node: + +```js +const postcssPrefersColorScheme = require('css-prefers-color-scheme/postcss'); + +postcssPrefersColorScheme.process(YOUR_CSS /*, processOptions, pluginOptions */); +``` + +Or use it as a [PostCSS] plugin: + +```js +const postcss = require('postcss'); +const postcssPrefersColorScheme = require('css-prefers-color-scheme/postcss'); + +postcss([ + postcssPrefersColorScheme(/* pluginOptions */) +]).process(YOUR_CSS /*, processOptions */); +``` + +[Prefers Color Scheme] runs in all Node environments, with special +instructions for: + +| [Node](INSTALL.md#node) | [Webpack](INSTALL.md#webpack) | [Create React App](INSTALL.md#create-react-app) | [Gulp](INSTALL.md#gulp) | [Grunt](INSTALL.md#grunt) | +| --- | --- | --- | --- | --- | + +### Options + +#### preserve + +The `preserve` option determines whether the original `prefers-color-scheme` +query will be preserved or removed. By default, it is preserved. + +```js +require('css-prefers-color-scheme/postcss')({ preserve: false }); +``` + +```css +@media (prefers-color-scheme: dark) { + body { + background-color: black; + } +} + +/* becomes */ + +@media (color-index: 48) { + body { + background-color: black; + } +} +``` + +[cli-img]: https://img.shields.io/travis/csstools/css-prefers-color-scheme.svg +[cli-url]: https://travis-ci.org/csstools/css-prefers-color-scheme +[git-img]: https://img.shields.io/badge/support-chat-blue.svg +[git-url]: https://gitter.im/postcss/postcss +[npm-img]: https://img.shields.io/npm/v/css-prefers-color-scheme.svg +[npm-url]: https://www.npmjs.com/package/css-prefers-color-scheme + +[PostCSS]: https://github.com/postcss/postcss +[Prefers Color Scheme]: https://github.com/csstools/css-prefers-color-scheme diff --git a/README.md b/README.md index 14065a18cb..f31872cdbf 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# Prefers Color Scheme [PostCSS][Prefers Color Scheme] +# Prefers Color Scheme [][Prefers Color Scheme] [![NPM Version][npm-img]][npm-url] [![Build Status][cli-img]][cli-url] @@ -7,229 +7,52 @@ [Prefers Color Scheme] lets you use light and dark color schemes in all browsers, following the [Media Queries] specification. -```bash -npm install css-prefers-color-scheme -``` - -There are 2 steps required to get color schemes working: - -- Transform your queries using the included [PostCSS plugin](#PostCSS-Plugin). -- Apply your queries using the included [browser library](#Browser-Library). - -## PostCSS Plugin - -[Prefers Color Scheme] transforms `prefers-color-scheme` media queries into -something all browsers understand. - -```css -@media (prefers-color-scheme: dark) { - :root { - --site-bgcolor: #1b1b1b; - --site-color: #fff; - } -} - -body { - background-color: var(--site-bgcolor, #f9f9f9); - color: var(--site-color, #111); - font: 100%/1.5 system-ui; -} - -/* becomes */ - -@media (color-index: 48) { - :root { - --site-bgcolor: #1b1b1b; - --site-color: #fff; - } -} - -@media (prefers-color-scheme: dark) { - :root { - --site-bgcolor: #1b1b1b; - --site-color: #fff; - } -} - -body { - background-color: var(--site-bgcolor, #f9f9f9); - color: var(--site-color, #111); - font: 100%/1.5 system-ui; -} -``` - -## Browser Library - -[Prefers Color Scheme] applies color schemes previously transformed by the -[PostCSS plugin](#PostCSS-Plugin). +## Usage -```js -// initialize prefersColorScheme (applies the system color scheme, if available) -const prefersColorScheme = require('css-prefers-color-scheme')(); - -// apply "dark" queries -prefersColorScheme.scheme = 'dark'; - -// apply "light" queries (also disabling "dark" queries) -prefersColorScheme.scheme = 'light'; -``` +From the command line, transform CSS files that use `prefers-color-scheme` +media queries: -The script is also available from the [unpkg.com](https://unpkg.com/) CDN: - -```html - - +```bash +npx css-prefers-color-scheme SOURCE.css TRANSFORMED.css ``` -A minified version is also available: +Next, use that transformed CSS with this script: ```html - + + ``` -[Prefers Color Scheme] works in all major browsers, including Safari 6+ and -Internet Explorer 9+ without any polyfills. -[See it for yourself.](https://app.crossbrowsertesting.com/public/i76b092cd2b52b86/screenshots/z25c0ccdfcc9c9b8956f?size=medium&type=windowed) - -To maintain compatibility with browsers supporting `prefers-color-scheme`, the -library will remove `prefers-color-scheme` media queries in favor of the -cross-browser compatible `color-index` media queries. This ensures a seemless -experience when JavaScript is unable to run. - ---- - -## Browser Usage - -Use [Prefers Color Scheme] to activate your `prefers-color-scheme` queries: - -```js -const prefersColorScheme = require('css-prefers-color-scheme')(); -``` - -By default, the system color scheme is applied, if your browser supports it. -Otherwise, the light color scheme is applied. You may override this by passing -in a color scheme. - -```js -const prefersColorScheme = require('css-prefers-color-scheme')('dark'); -``` +Dependencies got you down? Don’t worry, this script is only 537 bytes. -The `prefersColorScheme` object returns the following properties: +## Usage -### value - -The `value` property returns the currently preferred color scheme, and can be -set to change it. - -```js -const prefersColorScheme = require('css-prefers-color-scheme')(); - -// log the preferred color scheme -console.log(prefersColorScheme.scheme); - -// apply "dark" queries -prefersColorScheme.scheme = 'dark'; -``` - -### hasNativeSupport - -The `hasNativeSupport` boolean represents whether `prefers-color-scheme` is -supported by the current browser. - -### onChange - -The `onChange` function can be added in order to listen for changes to the -preferred color scheme, whether they are triggered by the system or manually by -the `change` function. - -### removeListener - -The `removeListener` function removes the native `prefers-color-scheme` -listener, which may or may not be applied, depending on your browser support. -This is provided to give you complete control over plugin cleanup. - ---- - -## PostCSS Usage - -Use [Prefers Color Scheme] to process your CSS: - -```js -const postcssPrefersColorScheme = require('css-prefers-color-scheme/postcss'); - -postcssPrefersColorScheme.process(YOUR_CSS /*, processOptions, pluginOptions */); -``` - -Or use it as a [PostCSS] plugin: - -```js -const postcss = require('postcss'); -const postcssPrefersColorScheme = require('css-prefers-color-scheme/postcss'); - -postcss([ - postcssPrefersColorScheme(/* pluginOptions */) -]).process(YOUR_CSS /*, processOptions */); -``` - -[Prefers Color Scheme] runs in all Node environments, with special -instructions for: - -| [Node](INSTALL.md#node) | [Webpack](INSTALL.md#webpack) | [Create React App](INSTALL.md#create-react-app) | [Gulp](INSTALL.md#gulp) | [Grunt](INSTALL.md#grunt) | -| --- | --- | --- | --- | --- | - -### Options - -#### preserve - -The `preserve` option determines whether the original `prefers-color-scheme` -query will be preserved or removed. By default, it is preserved. - - -```js -require('css-prefers-color-scheme/postcss')({ preserve: false }); -``` - -```css -@media (prefers-color-scheme: dark) { - body { - background-color: black; - } -} - -/* becomes */ - -@media (color-index: 48) { - body { - background-color: black; - } -} -``` +- First, transform `prefers-color-scheme` queries using this + [PostCSS plugin](README-POSTCSS.md). +- Next, apply light and dark color schemes everywhere using this + [browser script](README-BROWSER.md). --- ## How does it work? -The [Prefers Color Scheme] [PostCSS plugin](#PostCSS-Plugin) transforms -`prefers-color-scheme` queries into `color-index` queries, changing +[Prefers Color Scheme] uses a [PostCSS plugin](README-POSTCSS.md) to transform +`prefers-color-scheme` queries into `color-index` queries. This changes `prefers-color-scheme: dark` into `(color-index: 48)`, `prefers-color-scheme: light` into `(color-index: 70)`, and `prefers-color-scheme: no-preference` into `(color-index: 22)`. The frontend receives these `color-index` queries, which are understood in all -major browsers going back to Internet Explorer 9. However, all browsers only -apply a `color-index` of `0`, so all other values are otherwise ignored. +major browsers going back to Internet Explorer 9. However, since browsers only +apply `color-index` queries of `0`, our color scheme values are ignored. -[Prefers Color Scheme] changes `(color-index: 48)` queries into -`not all and (color-index: 48)` to activate “dark mode” specific CSS, and then -it inverts `(color-index: 70)` queries into `not all and (color-index: 48)` -to activate “light mode” specific CSS. +[Prefers Color Scheme] uses a [browser script](README-BROWSER.md) to change +`(color-index: 48)` queries into `not all and (color-index: 48)` in order to +activate “dark mode” specific CSS, and it changes `(color-index: 70)` queries +into `not all and (color-index: 48)` to activate “light mode” specific CSS. ```css @media (color-index: 70) { /* prefers-color-scheme: light */ @@ -240,8 +63,8 @@ to activate “light mode” specific CSS. } ``` -These valid queries are accessible to `document.styleSheet`, so no css parsing -is required to use this library, which is how the script is only 539 bytes. +Since these media queries are accessible to `document.styleSheet`, no CSS +parsing is required. ## Why does the fallback work this way? diff --git a/package.json b/package.json index 93d27e7aef..c87ac55608 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "css-prefers-color-scheme", - "version": "3.0.0", + "version": "3.1.0", "description": "Use light and dark color schemes in all browsers", "author": "Jonathan Neal ", "license": "CC0-1.0", @@ -9,6 +9,9 @@ "bugs": "https://github.com/csstools/css-prefers-color-scheme/issues", "main": "index.js", "module": "index.mjs", + "bin": { + "css-prefers-color-scheme": "src/postcss-cli.js" + }, "files": [ "browser.js", "browser.js.map", @@ -40,15 +43,16 @@ "postcss": "^7.0.5" }, "devDependencies": { - "@babel/core": "^7.1.2", - "@babel/preset-env": "^7.1.0", + "@babel/core": "^7.1.5", + "@babel/preset-env": "^7.1.5", "babel-eslint": "^10.0.1", "cross-env": "^5.2.0", - "eslint": "^5.8.0", + "eslint": "^5.9.0", "eslint-config-dev": "^2.0.0", + "get-stdin": "^6.0.0", "postcss-tape": "^2.2.0", "pre-commit": "^1.2.2", - "rollup": "^0.66.6", + "rollup": "^0.67.0", "rollup-plugin-babel": "^4.0.3", "rollup-plugin-terser": "^3.0.0", "uglify-js": "^3.4.9" diff --git a/src/postcss-cli.js b/src/postcss-cli.js new file mode 100755 index 0000000000..f8cb19dd01 --- /dev/null +++ b/src/postcss-cli.js @@ -0,0 +1,104 @@ +#!/usr/bin/env node + +const fs = require('fs'); +const prefersColorScheme = require('../postcss'); + +// get process and plugin options from the command line +const fileRegExp = /^[\w\/.]+$/; +const argRegExp = /^--(\w+)=("|')?(.+)\2$/; +const relaxedJsonRegExp = /(['"])?([a-z0-9A-Z_]+)(['"])?:/g; +const argo = process.argv.slice(2).reduce( + (object, arg) => { + const argMatch = arg.match(argRegExp); + const fileMatch = arg.match(fileRegExp); + + if (argMatch) { + object[argMatch[1]] = argMatch[3]; + } else if (fileMatch) { + if (object.from === '') { + object.from = arg; + } else if (object.to === '') { + object.to = arg; + } + } + + return object; + }, + { from: '', to: '', opts: 'null' } +); + +// get css from command line arguments or stdin +(argo.from === '' ? getStdin() : readFile(argo.from)) +.then(css => { + const pluginOpts = JSON.parse(argo.opts.replace(relaxedJsonRegExp, '"$2": ')); + const processOptions = Object.assign({ from: argo.from, to: argo.to || argo.from }, argo.map ? { map: JSON.parse(argo.map) } : {}); + + const result = prefersColorScheme.process(css, processOptions, pluginOpts); + + if (argo.to === '') { + return result.css; + } else { + return writeFile(argo.to, result.css).then( + () => `CSS was written to "${argo.to}"` + ) + } +}).then( + result => { + console.log(result); + + process.exit(0); + }, + error => { + console.error(error); + + process.exit(1); + } +); + +function readFile(pathname) { + return new Promise((resolve, reject) => { + fs.readFile(pathname, 'utf8', (error, data) => { + if (error) { + reject(error); + } else { + resolve(data); + } + }); + }); +} + +function writeFile(pathname, data) { + return new Promise((resolve, reject) => { + fs.writeFile(pathname, data, (error, content) => { + if (error) { + reject(error); + } else { + resolve(content); + } + }); + }); +} + +function getStdin() { + return new Promise(resolve => { + let data = ''; + + if (process.stdin.isTTY) { + resolve(data); + } else { + process.stdin.setEncoding('utf8'); + + process.stdin.on('readable', () => { + let chunk; + + while (chunk = process.stdin.read()) { + data += chunk; + } + }); + + process.stdin.on('end', () => { + resolve(data); + }); + } + }); +} From ba8003a13b7ba82c060cc72cf2850ed37bf2544d Mon Sep 17 00:00:00 2001 From: Jonathan Neal Date: Sat, 10 Nov 2018 16:29:37 -0500 Subject: [PATCH 745/795] 3.1.1 --- src/postcss-cli.js => cli.js | 14 +++++++++++++- package.json | 5 +++-- 2 files changed, 16 insertions(+), 3 deletions(-) rename src/postcss-cli.js => cli.js (82%) diff --git a/src/postcss-cli.js b/cli.js similarity index 82% rename from src/postcss-cli.js rename to cli.js index f8cb19dd01..715c69a741 100755 --- a/src/postcss-cli.js +++ b/cli.js @@ -1,7 +1,19 @@ #!/usr/bin/env node const fs = require('fs'); -const prefersColorScheme = require('../postcss'); +const prefersColorScheme = require('./postcss'); + +if (process.argv.length < 3) { + console.log([ + 'Prefers Color Scheme\n', + ' Transforms CSS with @media (prefers-color-scheme) {}\n', + 'Usage:\n', + ' css-prefers-color-scheme source.css transformed.css', + ' css-prefers-color-scheme --in=source.css --out=transformed.css --opts={}', + ' echo "@media (prefers-color-scheme: dark) {}" | css-prefers-color-scheme\n' + ].join('\n')); + process.exit(0); +} // get process and plugin options from the command line const fileRegExp = /^[\w\/.]+$/; diff --git a/package.json b/package.json index c87ac55608..3beffef781 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "css-prefers-color-scheme", - "version": "3.1.0", + "version": "3.1.1", "description": "Use light and dark color schemes in all browsers", "author": "Jonathan Neal ", "license": "CC0-1.0", @@ -10,12 +10,13 @@ "main": "index.js", "module": "index.mjs", "bin": { - "css-prefers-color-scheme": "src/postcss-cli.js" + "css-prefers-color-scheme": "cli.js" }, "files": [ "browser.js", "browser.js.map", "browser.min.js", + "cli.js", "index.mjs", "index.mjs.map", "index.js", From d0582142e05b9504a7e12ad5ff4ebbedadca8904 Mon Sep 17 00:00:00 2001 From: Jonathan Neal Date: Sat, 17 Nov 2018 08:56:49 -0500 Subject: [PATCH 746/795] 0.1.0 --- .editorconfig | 15 +++ .gitignore | 17 +++ .rollup.js | 64 +++++++++++ .tape.js | 19 ++++ .travis.yml | 9 ++ CHANGELOG.md | 5 + CONTRIBUTING.md | 65 ++++++++++++ INSTALL-POSTCSS.md | 171 ++++++++++++++++++++++++++++++ LICENSE.md | 108 +++++++++++++++++++ README-BROWSER.md | 70 ++++++++++++ README-POSTCSS.md | 120 +++++++++++++++++++++ README.md | 83 +++++++++++++++ package.json | 79 ++++++++++++++ src/browser.js | 93 ++++++++++++++++ src/cli.js | 119 +++++++++++++++++++++ src/postcss.js | 24 +++++ test/basic.css | 27 +++++ test/basic.expect.css | 48 +++++++++ test/basic.preserve.expect.css | 27 +++++ test/basic.replacewith.expect.css | 48 +++++++++ 20 files changed, 1211 insertions(+) create mode 100644 .editorconfig create mode 100644 .gitignore create mode 100644 .rollup.js create mode 100644 .tape.js create mode 100644 .travis.yml create mode 100644 CHANGELOG.md create mode 100644 CONTRIBUTING.md create mode 100644 INSTALL-POSTCSS.md create mode 100644 LICENSE.md create mode 100644 README-BROWSER.md create mode 100644 README-POSTCSS.md create mode 100644 README.md create mode 100644 package.json create mode 100644 src/browser.js create mode 100644 src/cli.js create mode 100644 src/postcss.js create mode 100644 test/basic.css create mode 100644 test/basic.expect.css create mode 100644 test/basic.preserve.expect.css create mode 100644 test/basic.replacewith.expect.css diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000000..e06d7982bc --- /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/.gitignore b/.gitignore new file mode 100644 index 0000000000..1d65a2d169 --- /dev/null +++ b/.gitignore @@ -0,0 +1,17 @@ +node_modules +/browser.js* +/cli.js* +/index.js* +/index.mjs* +/postcss.js* +/postcss.mjs* +package-lock.json +*.log* +*.result.css +.* +!.appveyor.yml +!.editorconfig +!.gitignore +!.rollup.js +!.tape.js +!.travis.yml diff --git a/.rollup.js b/.rollup.js new file mode 100644 index 0000000000..107a3ced25 --- /dev/null +++ b/.rollup.js @@ -0,0 +1,64 @@ +import babel from 'rollup-plugin-babel'; +import { terser } from 'rollup-plugin-terser'; + +const isBrowser = String(process.env.NODE_ENV).includes('browser'); +const isCLI = String(process.env.NODE_ENV).includes('cli'); +const isPostCSS = String(process.env.NODE_ENV).includes('postcss'); +const targets = isCLI || isPostCSS || !isBrowser ? { node: 6 } : 'last 2 versions, not dead'; + +const input = `src/${isCLI ? 'cli' : isPostCSS ? 'postcss' : 'browser'}.js`; +const output = isCLI + ? { file: 'cli.js', format: 'cjs' } +: isBrowser + ? { file: 'browser.js', format: 'cjs' } +: isPostCSS + ? [ + { file: 'postcss.js', format: 'cjs', sourcemap: true }, + { file: 'postcss.mjs', format: 'esm', sourcemap: true } +] : [ + { file: 'index.js', format: 'cjs', sourcemap: true }, + { file: 'index.mjs', format: 'esm', sourcemap: true } +]; +const plugins = [ + babel({ + presets: [ + ['@babel/env', { targets }] + ] + }) +].concat(isBrowser + ? [ + trimContentForBrowser(), + terser() + ] +: isCLI + ? [ + trimContentForBrowser(), + addHashBang() + ] +: []); + +export default { input, output, plugins }; + +function addHashBang() { + return { + name: 'add-hash-bang', + renderChunk(code) { + const updatedCode = `#!/usr/bin/env node\n\n${code}`; + + return updatedCode; + } + }; +} + +function trimContentForBrowser() { + return { + name: 'trim-content-for-browser', + renderChunk(code) { + const updatedCode = code + .replace(/'use strict';\n*/, '') + .replace(/\n*module\.exports = cssBlankPseudo;/, ''); + + return updatedCode; + } + }; +} diff --git a/.tape.js b/.tape.js new file mode 100644 index 0000000000..66730ed8ec --- /dev/null +++ b/.tape.js @@ -0,0 +1,19 @@ +module.exports = { + 'css-blank-pseudo': { + 'basic': { + message: 'supports basic usage' + }, + 'basic:replacewith': { + message: 'supports { replaceWith: ".css-blank" } usage', + options: { + replaceWith: '.css-blank' + } + }, + 'basic:preserve': { + message: 'supports { preserve: false } usage', + options: { + preserve: false + } + } + } +}; diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000000..e1f11a52e6 --- /dev/null +++ b/.travis.yml @@ -0,0 +1,9 @@ +# https://docs.travis-ci.com/user/travis-lint + +language: node_js + +node_js: + - 6 + +install: + - npm install --ignore-scripts diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000000..dced96ea97 --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,5 @@ +# Changes to CSS Blank Pseudo + +### 1.0.0 (November 17, 2018) + +- Initial version diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 0000000000..dc00fa7f74 --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,65 @@ +# Contributing to CSS Blank Pseudo + +You want to help? You rock! Now, take a moment to be sure your contributions +make sense to everyone else. + +## Reporting Issues + +Found a problem? Want a new feature? + +- See if your issue or idea has [already been reported]. +- Provide a [reduced test case] or a [live example]. + +Remember, a bug is a _demonstrable problem_ caused by _our_ code. + +## Submitting Pull Requests + +Pull requests are the greatest contributions, so be sure they are focused in +scope and avoid unrelated commits. + +1. To begin; [fork this project], clone your fork, and add our upstream. + ```bash + # Clone your fork of the repo into the current directory + git clone git@github.com:YOUR_USER/css-blank-pseudo.git + + # Navigate to the newly cloned directory + cd css-blank-pseudo + + # Assign the original repo to a remote called "upstream" + git remote add upstream git@github.com:csstools/css-blank-pseudo.git + + # Install the tools necessary for testing + npm install + ``` + +2. Create a branch for your feature or fix: + ```bash + # Move into a new branch for your feature + git checkout -b feature/thing + ``` + ```bash + # Move into a new branch for your fix + git checkout -b fix/something + ``` + +3. If your code follows our practices, then push your feature branch: + ```bash + # Test current code + npm test + ``` + ```bash + # Push the branch for your new feature + git push origin feature/thing + ``` + ```bash + # Or, push the branch for your update + git push origin update/something + ``` + +That’s it! Now [open a pull request] with a clear title and description. + +[already been reported]: issues +[fork this project]: fork +[live example]: https://codepen.io/pen +[open a pull request]: https://help.github.com/articles/using-pull-requests/ +[reduced test case]: https://css-tricks.com/reduced-test-cases/ diff --git a/INSTALL-POSTCSS.md b/INSTALL-POSTCSS.md new file mode 100644 index 0000000000..479965ba7f --- /dev/null +++ b/INSTALL-POSTCSS.md @@ -0,0 +1,171 @@ +# Installing PostCSS + +[CSS Blank Pseudo] runs in all Node environments, with special instructions for: + +| [Node](#node) | [PostCSS CLI](#postcss-cli) | [Webpack](#webpack) | [Create React App](#create-react-app) | [Gulp](#gulp) | [Grunt](#grunt) | +| --- | --- | --- | --- | --- | --- | + +## Node + +Add [CSS Blank Pseudo] to your project: + +```bash +npm install css-blank-pseudo --save-dev +``` + +Use [CSS Blank Pseudo] to process your CSS: + +```js +const postcssBlankPseudo = require('css-blank-pseudo/postcss'); + +postcssBlankPseudo.process(YOUR_CSS /*, processOptions, pluginOptions */); +``` + +Or use it as a [PostCSS] plugin: + +```js +const postcss = require('postcss'); +const postcssBlankPseudo = require('css-blank-pseudo/postcss'); + +postcss([ + postcssBlankPseudo(/* pluginOptions */) +]).process(YOUR_CSS /*, processOptions */); +``` + +## PostCSS CLI + +Add [PostCSS CLI] to your project: + +```bash +npm install postcss-cli --save-dev +``` + +Use [CSS Blank Pseudo] in your `postcss.config.js` configuration file: + +```js +const postcssBlankPseudo = require('css-blank-pseudo/postcss'); + +module.exports = { + plugins: [ + postcssBlankPseudo(/* pluginOptions */) + ] +} +``` + +## Webpack + +Add [PostCSS Loader] to your project: + +```bash +npm install postcss-loader --save-dev +``` + +Use [CSS Blank Pseudo] in your Webpack configuration: + +```js +const postcssBlankPseudo = require('css-blank-pseudo/postcss'); + +module.exports = { + module: { + rules: [ + { + test: /\.css$/, + use: [ + 'style-loader', + { loader: 'css-loader', options: { importLoaders: 1 } }, + { loader: 'postcss-loader', options: { + ident: 'postcss', + plugins: () => [ + postcssBlankPseudo(/* pluginOptions */) + ] + } } + ] + } + ] + } +} +``` + +## Create React App + +Add [React App Rewired] and [React App Rewire PostCSS] to your project: + +```bash +npm install react-app-rewired react-app-rewire-postcss --save-dev +``` + +Use [React App Rewire PostCSS] and [CSS Blank Pseudo] in your +`config-overrides.js` +file: + +```js +const reactAppRewirePostcss = require('react-app-rewire-postcss'); +const postcssBlankPseudo = require('css-blank-pseudo/postcss'); + +module.exports = config => reactAppRewirePostcss(config, { + plugins: () => [ + postcssBlankPseudo(/* pluginOptions */) + ] +}); +``` + +## Gulp + +Add [Gulp PostCSS] to your project: + +```bash +npm install gulp-postcss --save-dev +``` + +Use [CSS Blank Pseudo] in your Gulpfile: + +```js +const postcss = require('gulp-postcss'); +const postcssBlankPseudo = require('css-blank-pseudo/postcss'); + +gulp.task('css', () => gulp.src('./src/*.css').pipe( + postcss([ + postcssBlankPseudo(/* pluginOptions */) + ]) +).pipe( + gulp.dest('.') +)); +``` + +## Grunt + +Add [Grunt PostCSS] to your project: + +```bash +npm install grunt-postcss --save-dev +``` + +Use [CSS Blank Pseudo] in your Gruntfile: + +```js +const postcssBlankPseudo = require('css-blank-pseudo/postcss'); + +grunt.loadNpmTasks('grunt-postcss'); + +grunt.initConfig({ + postcss: { + options: { + use: [ + postcssBlankPseudo(/* pluginOptions */) + ] + }, + dist: { + src: '*.css' + } + } +}); +``` + +[CSS Blank Pseudo]: https://github.com/csstools/css-blank-pseudo +[Gulp PostCSS]: https://github.com/postcss/gulp-postcss +[Grunt PostCSS]: https://github.com/nDmitry/grunt-postcss +[PostCSS]: https://github.com/postcss/postcss +[PostCSS CLI]: https://github.com/postcss/postcss-cli +[PostCSS Loader]: https://github.com/postcss/postcss-loader +[React App Rewire PostCSS]: https://github.com/csstools/react-app-rewire-postcss +[React App Rewired]: https://github.com/timarney/react-app-rewired diff --git a/LICENSE.md b/LICENSE.md new file mode 100644 index 0000000000..0bc1fa7060 --- /dev/null +++ b/LICENSE.md @@ -0,0 +1,108 @@ +# CC0 1.0 Universal + +## Statement of Purpose + +The laws of most jurisdictions throughout the world automatically confer +exclusive Copyright and Related Rights (defined below) upon the creator and +subsequent owner(s) (each and all, an “owner”) of an original work of +authorship and/or a database (each, a “Work”). + +Certain owners wish to permanently relinquish those rights to a Work for the +purpose of contributing to a commons of creative, cultural and scientific works +(“Commons”) that the public can reliably and without fear of later claims of +infringement build upon, modify, incorporate in other works, reuse and +redistribute as freely as possible in any form whatsoever and for any purposes, +including without limitation commercial purposes. These owners may contribute +to the Commons to promote the ideal of a free culture and the further +production of creative, cultural and scientific works, or to gain reputation or +greater distribution for their Work in part through the use and efforts of +others. + +For these and/or other purposes and motivations, and without any expectation of +additional consideration or compensation, the person associating CC0 with a +Work (the “Affirmer”), to the extent that he or she is an owner of Copyright +and Related Rights in the Work, voluntarily elects to apply CC0 to the Work and +publicly distribute the Work under its terms, with knowledge of his or her +Copyright and Related Rights in the Work and the meaning and intended legal +effect of CC0 on those rights. + +1. Copyright and Related Rights. A Work made available under CC0 may be + protected by copyright and related or neighboring rights (“Copyright and + Related Rights”). Copyright and Related Rights include, but are not limited + to, the following: + 1. the right to reproduce, adapt, distribute, perform, display, communicate, + and translate a Work; + 2. moral rights retained by the original author(s) and/or performer(s); + 3. publicity and privacy rights pertaining to a person’s image or likeness + depicted in a Work; + 4. rights protecting against unfair competition in regards to a Work, + subject to the limitations in paragraph 4(i), below; + 5. rights protecting the extraction, dissemination, use and reuse of data in + a Work; + 6. database rights (such as those arising under Directive 96/9/EC of the + European Parliament and of the Council of 11 March 1996 on the legal + protection of databases, and under any national implementation thereof, + including any amended or successor version of such directive); and + 7. other similar, equivalent or corresponding rights throughout the world + based on applicable law or treaty, and any national implementations + thereof. + +2. Waiver. To the greatest extent permitted by, but not in contravention of, + applicable law, Affirmer hereby overtly, fully, permanently, irrevocably and + unconditionally waives, abandons, and surrenders all of Affirmer’s Copyright + and Related Rights and associated claims and causes of action, whether now + known or unknown (including existing as well as future claims and causes of + action), in the Work (i) in all territories worldwide, (ii) for the maximum + duration provided by applicable law or treaty (including future time + extensions), (iii) in any current or future medium and for any number of + copies, and (iv) for any purpose whatsoever, including without limitation + commercial, advertising or promotional purposes (the “Waiver”). Affirmer + makes the Waiver for the benefit of each member of the public at large and + to the detriment of Affirmer’s heirs and successors, fully intending that + such Waiver shall not be subject to revocation, rescission, cancellation, + termination, or any other legal or equitable action to disrupt the quiet + enjoyment of the Work by the public as contemplated by Affirmer’s express + Statement of Purpose. + +3. Public License Fallback. Should any part of the Waiver for any reason be + judged legally invalid or ineffective under applicable law, then the Waiver + shall be preserved to the maximum extent permitted taking into account + Affirmer’s express Statement of Purpose. In addition, to the extent the + Waiver is so judged Affirmer hereby grants to each affected person a + royalty-free, non transferable, non sublicensable, non exclusive, + irrevocable and unconditional license to exercise Affirmer’s Copyright and + Related Rights in the Work (i) in all territories worldwide, (ii) for the + maximum duration provided by applicable law or treaty (including future time + extensions), (iii) in any current or future medium and for any number of + copies, and (iv) for any purpose whatsoever, including without limitation + commercial, advertising or promotional purposes (the “License”). The License + shall be deemed effective as of the date CC0 was applied by Affirmer to the + Work. Should any part of the License for any reason be judged legally + invalid or ineffective under applicable law, such partial invalidity or + ineffectiveness shall not invalidate the remainder of the License, and in + such case Affirmer hereby affirms that he or she will not (i) exercise any + of his or her remaining Copyright and Related Rights in the Work or (ii) + assert any associated claims and causes of action with respect to the Work, + in either case contrary to Affirmer’s express Statement of Purpose. + +4. Limitations and Disclaimers. + 1. No trademark or patent rights held by Affirmer are waived, abandoned, + surrendered, licensed or otherwise affected by this document. + 2. Affirmer offers the Work as-is and makes no representations or warranties + of any kind concerning the Work, express, implied, statutory or + otherwise, including without limitation warranties of title, + merchantability, fitness for a particular purpose, non infringement, or + the absence of latent or other defects, accuracy, or the present or + absence of errors, whether or not discoverable, all to the greatest + extent permissible under applicable law. + 3. Affirmer disclaims responsibility for clearing rights of other persons + that may apply to the Work or any use thereof, including without + limitation any person’s Copyright and Related Rights in the Work. + Further, Affirmer disclaims responsibility for obtaining any necessary + consents, permissions or other rights required for any use of the Work. + 4. Affirmer understands and acknowledges that Creative Commons is not a + party to this document and has no duty or obligation with respect to this + CC0 or use of the Work. + +For more information, please see +http://creativecommons.org/publicdomain/zero/1.0/. diff --git a/README-BROWSER.md b/README-BROWSER.md new file mode 100644 index 0000000000..24edb39a27 --- /dev/null +++ b/README-BROWSER.md @@ -0,0 +1,70 @@ +# CSS Blank Pseudo for Browsers [][CSS Blank Pseudo] + +[![NPM Version][npm-img]][npm-url] +[![Build Status][cli-img]][cli-url] +[![Support Chat][git-img]][git-url] + +[CSS Blank Pseudo] lets you style form elements when they are empty, following +the [Selectors Level 4] specification. + +```css +input { + /* style an input */ +} + +input[blank] { + /* style an input without a value */ +} +``` + +## Usage + +Add [CSS Blank Pseudo] to your build tool: + +```bash +npm install css-blank-pseudo +``` + +Then include and initialize it on your document: + +```js +const cssBlankPseudo = require('css-blank-pseudo'); + +cssBlankPseudo(document); +``` + +## Options + +[CSS Blank Pseudo] accepts a secondary paramater to configure the attribute or +class name added to elements matching focused elements or containing focused +elements. + +```js +cssBlankPseudo(document, { + attr: false, + className: '.blank' +}); +``` + +Falsey values on either `attr` or `className` will disable setting the +attribute or class name on elements matching `:blank`. + +[CSS Blank Pseudo] also accepts a secondary paramater to configure whether the +polyfill is loaded regardless of support. If `force` is given a truthy value, +then the polyfill will always execute. + +```js +cssBlankPseudo(document, { + force: true +}); +``` + +[cli-img]: https://img.shields.io/travis/csstools/css-blank-pseudo/master.svg +[cli-url]: https://travis-ci.org/csstools/css-blank-pseudo +[git-img]: https://img.shields.io/badge/support-chat-blue.svg +[git-url]: https://gitter.im/postcss/postcss +[npm-img]: https://img.shields.io/npm/v/css-blank-pseudo.svg +[npm-url]: https://www.npmjs.com/package/css-blank-pseudo + +[CSS Blank Pseudo]: https://github.com/csstools/css-blank-pseudo +[Selectors Level 4]: https://drafts.csswg.org/selectors-4/#blank diff --git a/README-POSTCSS.md b/README-POSTCSS.md new file mode 100644 index 0000000000..b821ec41b5 --- /dev/null +++ b/README-POSTCSS.md @@ -0,0 +1,120 @@ +# CSS Blank Pseudo for PostCSS [][CSS Blank Pseudo] + +[![NPM Version][npm-img]][npm-url] +[![Build Status][cli-img]][cli-url] +[![Support Chat][git-img]][git-url] + +[CSS Blank Pseudo] lets you style form elements when they are empty, following +the [Selectors Level 4] specification. + +```css +input:blank { + background-color: yellow; +} + +/* becomes */ + +.field[blank] label { + background-color: yellow; +} + +.field:blank label { + background-color: yellow; +} +``` + +[CSS Blank Pseudo] duplicates rules using the `:blank` pseudo-class with a +`[blank]` attribute selector. This replacement selector can be changed +using the `replaceWith` option. Also, the preservation of the original +`:blank` rule can be disabled using the `preserve` option. + +## Usage + +Add [CSS Blank Pseudo] to your project: + +```bash +npm install css-blank-pseudo --save-dev +``` + +Use [CSS Blank Pseudo] to process your CSS: + +```js +const postcssBlankPseudo = require('css-blank-pseudo/postcss'); + +postcssBlankPseudo.process(YOUR_CSS /*, processOptions, pluginOptions */); +``` + +Or use it as a [PostCSS] plugin: + +```js +const postcss = require('postcss'); +const postcssBlankPseudo = require('css-blank-pseudo/postcss'); + +postcss([ + postcssBlankPseudo(/* pluginOptions */) +]).process(YOUR_CSS /*, processOptions */); +``` + +[CSS Blank Pseudo] runs in all Node environments, with special +instructions for: + +| [Node](INSTALL-POSTCSS.md#node) | [PostCSS CLI](INSTALL-POSTCSS.md#postcss-cli) | [Webpack](INSTALL-POSTCSS.md#webpack) | [Create React App](INSTALL-POSTCSS.md#create-react-app) | [Gulp](INSTALL-POSTCSS.md#gulp) | [Grunt](INSTALL-POSTCSS.md#grunt) | +| --- | --- | --- | --- | --- | --- | + +## Options + +### preserve + +The `preserve` option defines whether the original selector should remain. By +default, the original selector is preserved. + +```js +focusWithin({ preserve: false }); +``` + +```css +input:blank { + background-color: yellow; +} + +/* becomes */ + +.field[blank] label { + background-color: yellow; +} +``` + +### replaceWith + +The `replaceWith` option defines the selector to replace `:blank`. By +default, the replacement selector is `[blank]`. + +```js +focusWithin({ replaceWith: '.blank' }); +``` + +```css +input:blank { + background-color: yellow; +} + +/* becomes */ + +.field.blank label { + background-color: yellow; +} + +.field:blank label { + background-color: yellow; +} +``` + +[cli-img]: https://img.shields.io/travis/csstools/css-blank-pseudo/master.svg +[cli-url]: https://travis-ci.org/csstools/css-blank-pseudo +[git-img]: https://img.shields.io/badge/support-chat-blue.svg +[git-url]: https://gitter.im/postcss/postcss +[npm-img]: https://img.shields.io/npm/v/css-blank-pseudo.svg +[npm-url]: https://www.npmjs.com/package/css-blank-pseudo + +[CSS Blank Pseudo]: https://github.com/csstools/css-blank-pseudo +[Selectors Level 4]: https://drafts.csswg.org/selectors-4/#blank diff --git a/README.md b/README.md new file mode 100644 index 0000000000..48cf5d7e59 --- /dev/null +++ b/README.md @@ -0,0 +1,83 @@ +# CSS Blank Pseudo [][CSS Blank Pseudo] + +[![NPM Version][npm-img]][npm-url] +[![Build Status][cli-img]][cli-url] +[![Support Chat][git-img]][git-url] + +[CSS Blank Pseudo] lets you style form elements when they are empty, following +the [Selectors Level 4] specification. + +```css +input { + /* style an input */ +} + +input:blank { + /* style an input without a value */ +} +``` + +## Usage + +From the command line, transform CSS files that use `:blank` selectors: + +```bash +npx css-blank-pseudo SOURCE.css TRANSFORMED.css +``` + +Next, use your transformed CSS with this script: + +```html + + + +``` + +That’s it. The script is 483 bytes and works in all browsers, as far back as +Internet Explorer 11. + +## How it works + +The [PostCSS plugin](README-POSTCSS.md) clones rules containing `:blank`, +replacing them with an alternative `[blank]` selector. + +```css +input:blank { + background-color: yellow; +} + +/* becomes */ + +.field[blank] label { + background-color: yellow; +} + +.field:blank label { + background-color: yellow; +} +``` + +Next, the [JavaScript library](README-BROWSER.md) adds a `blank` attribute to +elements otherwise matching `:blank` natively. + +```html +
+ + +
+
+ + +
+``` + +[cli-img]: https://img.shields.io/travis/csstools/css-blank-pseudo/master.svg +[cli-url]: https://travis-ci.org/csstools/css-blank-pseudo +[git-img]: https://img.shields.io/badge/support-chat-blue.svg +[git-url]: https://gitter.im/postcss/postcss +[npm-img]: https://img.shields.io/npm/v/css-blank-pseudo.svg +[npm-url]: https://www.npmjs.com/package/css-blank-pseudo + +[CSS Blank Pseudo]: https://github.com/csstools/css-blank-pseudo +[PostCSS Preset Env]: https://preset-env.cssdb.org/ +[Selectors Level 4]: https://drafts.csswg.org/selectors-4/#blank diff --git a/package.json b/package.json new file mode 100644 index 0000000000..09fc443fdc --- /dev/null +++ b/package.json @@ -0,0 +1,79 @@ +{ + "name": "css-blank-pseudo", + "version": "0.1.0", + "description": "Style form elements when they are empty", + "author": "Jonathan Neal ", + "license": "CC0-1.0", + "repository": "csstools/css-blank-pseudo", + "homepage": "https://github.com/csstools/css-blank-pseudo#readme", + "bugs": "https://github.com/csstools/css-blank-pseudo/issues", + "main": "index.js", + "module": "index.mjs", + "bin": { + "css-blank-pseudo": "cli.js" + }, + "files": [ + "browser.js", + "cli.js", + "index.js", + "index.js.map", + "index.mjs", + "index.mjs.map", + "postcss.js", + "postcss.js.map", + "postcss.mjs", + "postcss.mjs.map" + ], + "scripts": { + "build": "npm run build:browser && npm run build:cli && npm run build:node && npm run build:postcss", + "build:browser": "cross-env NODE_ENV=browser rollup -c .rollup.js --silent", + "build:cli": "cross-env NODE_ENV=cli rollup -c .rollup.js --silent", + "build:postcss": "cross-env NODE_ENV=postcss rollup -c .rollup.js --silent", + "build:node": "rollup -c .rollup.js --silent", + "prepublishOnly": "npm build && npm test", + "pretest": "npm run build:postcss", + "pretest:postcss": "npm run build:postcss", + "test": "npm run test:js && npm run test:postcss", + "test:js": "eslint src/*.js --cache --ignore-path .gitignore --quiet", + "test:postcss": "postcss-tape --plugin=postcss.js" + }, + "engines": { + "node": ">=6.0.0" + }, + "dependencies": { + "postcss": "^7.0.5" + }, + "devDependencies": { + "@babel/core": "^7.1.6", + "@babel/preset-env": "^7.1.6", + "babel-eslint": "^10.0.1", + "cross-env": "^5.2.0", + "eslint": "^5.9.0", + "eslint-config-dev": "2.0.0", + "postcss-tape": "^2.2.0", + "pre-commit": "^1.2.2", + "rollup": "^0.67.3", + "rollup-plugin-babel": "^4.0.3", + "rollup-plugin-terser": "^3.0.0" + }, + "eslintConfig": { + "extends": "dev", + "parser": "babel-eslint" + }, + "keywords": [ + "postcss", + "css", + "postcss-plugin", + "javascript", + "js", + "polyfill", + "focus", + "within", + "pseudos", + "selectors", + "accessibility", + "a11y", + "descendants", + "ancestors" + ] +} diff --git a/src/browser.js b/src/browser.js new file mode 100644 index 0000000000..0be0848f07 --- /dev/null +++ b/src/browser.js @@ -0,0 +1,93 @@ +export default function cssBlankPseudo(document, opts) { + // configuration + const className = Object(opts).className; + const attr = Object(opts).attr || 'blank'; + const force = Object(opts).force; + + try { + document.querySelector(':blank'); + + if (!force) { + return; + } + } catch (ignoredError) { /* do nothing and continue */ } + + // observe value changes on ,