├── .babelrc ├── .codeclimate.yml ├── .eslintrc ├── .flowconfig ├── .gitignore ├── .jshintrc ├── .prettierrc ├── .travis.yml ├── .vscode └── settings.json ├── Changelog.md ├── LICENSE ├── README.md ├── benchmark ├── cases │ ├── bredon.js │ └── postcss-value-parser.js ├── index.js ├── package.json ├── utils │ └── createUniqueValue.js └── yarn.lock ├── docs ├── API.md ├── Nodes.md └── api │ ├── bredon-minify │ └── minify.md │ ├── bredon-types │ ├── Builders.md │ └── Validators.md │ ├── bredon-validate │ └── validate.md │ └── bredon │ ├── compile.md │ ├── generate.md │ ├── parse.md │ ├── traverse.md │ └── types.md ├── flowtypes ├── AST.js ├── Path.js ├── RuleMap.js └── Token.js ├── lerna.json ├── package.json ├── packages ├── bredon-minify │ ├── README.md │ ├── package.json │ ├── src │ │ ├── __tests__ │ │ │ └── minify-test.js │ │ └── index.js │ └── yarn.lock ├── bredon-plugin-calc │ ├── README.md │ ├── package.json │ ├── src │ │ ├── __tests__ │ │ │ └── calc-test.js │ │ └── index.js │ └── yarn.lock ├── bredon-plugin-case │ ├── README.md │ ├── package.json │ ├── src │ │ ├── __tests__ │ │ │ └── case-test.js │ │ └── index.js │ └── yarn.lock ├── bredon-plugin-color │ ├── README.md │ ├── package.json │ ├── src │ │ ├── __tests__ │ │ │ └── color-test.js │ │ └── index.js │ └── yarn.lock ├── bredon-plugin-initial │ ├── README.md │ ├── package.json │ └── src │ │ ├── __tests__ │ │ └── initial-test.js │ │ ├── index.js │ │ └── valueInitials.js ├── bredon-plugin-precision │ ├── README.md │ ├── package.json │ ├── src │ │ ├── __tests__ │ │ │ └── precision-test.js │ │ └── index.js │ └── yarn.lock ├── bredon-plugin-remove-unit │ ├── README.md │ ├── package.json │ ├── src │ │ ├── __tests__ │ │ │ └── removeUnit-test.js │ │ └── index.js │ └── yarn.lock ├── bredon-plugin-trim-hex │ ├── README.md │ ├── package.json │ ├── src │ │ ├── __tests__ │ │ │ └── trimHex-test.js │ │ └── index.js │ └── yarn.lock ├── bredon-plugin-unit │ ├── README.md │ ├── package.json │ ├── src │ │ ├── __tests__ │ │ │ └── unit-test.js │ │ └── index.js │ └── yarn.lock ├── bredon-tools │ ├── README.md │ ├── package.json │ ├── src │ │ ├── getSingleValue.js │ │ ├── index.js │ │ └── isSingleValue.js │ └── yarn.lock ├── bredon-types │ ├── README.md │ ├── package.json │ └── src │ │ ├── builders │ │ ├── assignment.js │ │ ├── dimension.js │ │ ├── expression.js │ │ ├── float.js │ │ ├── functionExpression.js │ │ ├── hexColor.js │ │ ├── identifier.js │ │ ├── important.js │ │ ├── integer.js │ │ ├── operator.js │ │ ├── parenthesis.js │ │ ├── separator.js │ │ ├── stringLiteral.js │ │ ├── url.js │ │ ├── value.js │ │ └── valueList.js │ │ ├── index.js │ │ └── validators │ │ ├── isAssignment.js │ │ ├── isDimension.js │ │ ├── isExpression.js │ │ ├── isFloat.js │ │ ├── isFunctionExpression.js │ │ ├── isHexColor.js │ │ ├── isIdentifier.js │ │ ├── isInteger.js │ │ ├── isOperator.js │ │ ├── isParenthesis.js │ │ ├── isSeparator.js │ │ ├── isStringLiteral.js │ │ ├── isUrl.js │ │ ├── isValue.js │ │ └── isValueList.js ├── bredon-validate │ ├── README.md │ ├── package.json │ ├── src │ │ ├── __tests__ │ │ │ ├── __fixtures__ │ │ │ │ └── airbnb.css │ │ │ ├── monkey-test.js │ │ │ └── validate-test.js │ │ ├── data │ │ │ ├── __mdnData.js │ │ │ ├── _missingProps.js │ │ │ ├── colorNames.js │ │ │ ├── multiValueProperties.js │ │ │ ├── properties.js │ │ │ ├── valueInitials.js │ │ │ ├── valueKeywords.js │ │ │ └── valueListProperties.js │ │ ├── index.js │ │ ├── isValidProperty.js │ │ ├── propertyValidators.js │ │ ├── types │ │ │ ├── index.js │ │ │ ├── isAngle.js │ │ │ ├── isColor.js │ │ │ ├── isCubicBezier.js │ │ │ ├── isFrames.js │ │ │ ├── isGlobal.js │ │ │ ├── isImage.js │ │ │ ├── isLength.js │ │ │ ├── isLengthPercentage.js │ │ │ ├── isNumber.js │ │ │ ├── isOpacity.js │ │ │ ├── isPercentage.js │ │ │ ├── isPosition.js │ │ │ ├── isRepeat.js │ │ │ ├── isSize.js │ │ │ ├── isSteps.js │ │ │ ├── isSvgLength.js │ │ │ └── isTime.js │ │ └── utils │ │ │ ├── arrayReduce.js │ │ │ ├── isMultiValueProperty.js │ │ │ ├── isValueListProperty.js │ │ │ ├── matchesIdentifier.js │ │ │ ├── matchesKeyword.js │ │ │ ├── normalizeNodeList.js │ │ │ ├── validateNodeList.js │ │ │ └── validateUnorderedNodeList.js │ └── yarn.lock ├── bredon │ ├── README.md │ ├── package.json │ ├── src │ │ ├── Generator.js │ │ ├── Parser.js │ │ ├── Traverser.js │ │ ├── __tests__ │ │ │ ├── Generator-test.js │ │ │ ├── Parser-test.js │ │ │ ├── Traverser-test.js │ │ │ └── __snapshots__ │ │ │ │ └── Parser-test.js.snap │ │ ├── index.js │ │ └── utils │ │ │ ├── arrayReduce.js │ │ │ ├── createPath.js │ │ │ ├── getQuote.js │ │ │ ├── isValidHexadezimal.js │ │ │ ├── isValidUnit.js │ │ │ └── normalizeVisitors.js │ └── yarn.lock ├── postcss-bredon-minify │ ├── package.json │ ├── src │ │ ├── __tests__ │ │ │ └── index-test.js │ │ └── index.js │ └── yarn.lock ├── postcss-bredon-validate │ ├── package.json │ ├── src │ │ ├── __tests__ │ │ │ └── index-test.js │ │ └── index.js │ └── yarn.lock └── postcss-bredon │ ├── package.json │ ├── src │ └── index.js │ └── yarn.lock ├── scripts └── build.sh └── yarn.lock /.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": [ 3 | "es2015", 4 | "stage-0", 5 | "flow" 6 | ] 7 | } 8 | -------------------------------------------------------------------------------- /.codeclimate.yml: -------------------------------------------------------------------------------- 1 | languages: 2 | Ruby: true 3 | JavaScript: true 4 | PHP: true 5 | Python: true 6 | exclude_paths: 7 | - "dist/*" 8 | -------------------------------------------------------------------------------- /.eslintrc: -------------------------------------------------------------------------------- 1 | { 2 | "extends": [ "airbnb" ], 3 | "parser": "babel-eslint", 4 | "env": { 5 | "browser": true, 6 | "node": true, 7 | "jest": true 8 | }, 9 | "plugins": [ 10 | "flowtype" 11 | ], 12 | "rules": { 13 | "semi": [ 2, "never" ], 14 | "object-curly-newline": [ 0 ], 15 | "object-property-newline": [ 0 ], 16 | "comma-dangle": [ 0 ], 17 | "react/jsx-filename-extension": [2, { 18 | "extensions": [".js", ".jsx"] 19 | }], 20 | "import/no-extraneous-dependencies": [ 0 ], 21 | "react/prop-types": [ 0 ], 22 | "no-confusing-arrow": [ 0 ], 23 | "no-underscore-dangle": [ 0 ], 24 | "no-param-reassign": [ 0 ], 25 | "react/forbid-prop-types": [ 0 ], 26 | "no-plusplus": [ 0 ], 27 | "guard-for-in": [ 0 ], 28 | "no-restricted-syntax": [ 0 ], 29 | "no-continue": [ 1 ], 30 | "no-prototype-builtins": [ 0 ], 31 | "max-len": [ 0, 80 ], 32 | "no-mixed-operators": [ 0 ], 33 | "no-lonely-if": [ 1 ], 34 | "no-bitwise": [ 0 ], 35 | "arrow-parens": [ 0 ] 36 | } 37 | } -------------------------------------------------------------------------------- /.flowconfig: -------------------------------------------------------------------------------- 1 | [ignore] 2 | 3 | # Disable module with broken flow types. 4 | # .*/node_modules/babylon/*.* 5 | 6 | .*/node_modules/conventional-changelog-core/** 7 | 8 | [version] 9 | ^0.38.0 10 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # OS or Editor files 2 | ._* 3 | .DS_Store 4 | Thumbs.db 5 | 6 | # Files that might appear on external disks 7 | .Spotlight-V100 8 | .Trashes 9 | 10 | # Always-ignore extensions 11 | *~ 12 | *.diff 13 | *.err 14 | *.log 15 | *.orig 16 | *.pyc 17 | *.rej 18 | *.sass-cache 19 | *.sw? 20 | *.vi 21 | 22 | **/node_modules 23 | **/es 24 | **/coverage 25 | **/lib 26 | -------------------------------------------------------------------------------- /.jshintrc: -------------------------------------------------------------------------------- 1 | { 2 | "esnext": true, 3 | "asi": true 4 | } 5 | -------------------------------------------------------------------------------- /.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | trailingComma: "es5", 3 | singleQuote: true, 4 | bracketSpacing: true, 5 | jsxBracketSameLine: true, 6 | parser: "babylon", 7 | printWidth: 80, 8 | tabWidth: 2, 9 | useTabs: false, 10 | semi: false 11 | } 12 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: node_js 2 | node_js: 3 | - "5" 4 | script: 5 | - npm run check 6 | addons: 7 | code_climate: 8 | repo_token: 923b8eea8dc288ced3fef24a6a878b84fb21af9f8e3332881460c963735e4590 9 | before_script: 10 | - npm run bootstrap 11 | - npm run build 12 | after_script: 13 | - codeclimate-test-reporter < coverage/lcov.info 14 | notifications: 15 | email: false 16 | -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "search.exclude": { 3 | "# OS or Editor files": true, 4 | "._*": true, 5 | ".DS_Store": true, 6 | "Thumbs.db": true, 7 | "# Files that might appear on external disks": true, 8 | ".Spotlight-V100": true, 9 | ".Trashes": true, 10 | "# Always-ignore extensions": true, 11 | "*~": true, 12 | "*.diff": true, 13 | "*.err": true, 14 | "*.log": true, 15 | "*.orig": true, 16 | "*.pyc": true, 17 | "*.rej": true, 18 | "*.sass-cache": true, 19 | "*.sw?": true, 20 | "*.vi": true, 21 | "**/node_modules": true, 22 | "**/es": true, 23 | "**/coverage": true, 24 | "**/lib": true 25 | }, 26 | "files.exclude": { 27 | "# OS or Editor files": true, 28 | "._*": true, 29 | ".DS_Store": true, 30 | "Thumbs.db": true, 31 | "# Files that might appear on external disks": true, 32 | ".Spotlight-V100": true, 33 | ".Trashes": true, 34 | "# Always-ignore extensions": true, 35 | "*~": true, 36 | "*.diff": true, 37 | "*.err": true, 38 | "*.log": true, 39 | "*.orig": true, 40 | "*.pyc": true, 41 | "*.rej": true, 42 | "*.sass-cache": true, 43 | "*.sw?": true, 44 | "*.vi": true, 45 | "**/node_modules": true, 46 | "**/es": true, 47 | "**/coverage": true, 48 | "**/lib": true 49 | } 50 | } -------------------------------------------------------------------------------- /Changelog.md: -------------------------------------------------------------------------------- 1 | # Changelog 2 | 3 | > Dates are in `dd/mm/yy` format. 4 | 5 | ### 24/10/17 6 | | Package | Version | Changes | 7 | | ------- | ------- | ------- | 8 | | postcss-bredon | 1.0.0 | initial release | 9 | | bredon-plugin-remove-unit | 1.0.0 | initial release | 10 | | bredon-minify
postcss-bredon-minify | 1.0.1 | add bredon-plugin-remove-unit to bredon-minify | 11 | 12 | ### 15/10/17 13 | | Package | Version | Changes | 14 | | ------- | ------- | ------- | 15 | | bredon | 4.0.0 | added support for assignments, IE hacks, nested callees
using decimal numbers for the Float's `fractional` part
traverse AST one-by-one instead of one combined visitors
visitors can be functions that receive the bredon API
added bredon-types as a direct export to the bredon API
visitors now take a single `path` parameter | 16 | | bredon-types | 3.0.1 | added `assignment` and `isAssignment` | 17 | | bredon-tools | 4.0.0 | reduced APIs | 18 | | bredon-plugin-color
bredon-plugin-case
bredon-plugin-color
bredon-plugin-initial
bredon-plugin-precision
bredon-plugin-trim-hex
bredon-plugin-unit | 1.0.0 | initial release | 19 | | bredon-validate | 0.0.3 | Updated some property validators | 20 | | postcss-bredon-validate | 0.0.2 | updated bredon-validate to 0.0.3 | 21 | | bredon-minify | 1.0.0 | initial release | 22 | | postcss-bredon-minify | 1.0.0 | initial release | 23 | 24 | ### 10/10/17 25 | | Package | Version | Changes | 26 | | ------- | ------- | ------- | 27 | | bredon | 3.0.1 | renamed `CSSValue` and `MultiValue` to `Value` and `ValueList`
removed `Keyword`
`Dimension` now takes an `Integer` or a `Float` as value
added `negative` flags to both `Integer` and `Float`
removed `Important`, but added an `important` flag to `Value` | 28 | | bredon-types | 3.0.0 | updated validators and builders according the bredon changes | 29 | | bredon-validate | 0.0.2 | Initial experimental version | 30 | 31 | ### 2.0.0 32 | * complete parser rewrite 33 | * better error messages 34 | * fixed many bugs 35 | * introducing `bredon-types` and `bredon-tools` 36 | 37 | ### 1.0.1 38 | * Whitespace inside `String` nodes are preserved 39 | 40 | ### 1.0.0 41 | Initial version 42 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017 Robin Frischmann 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /benchmark/cases/bredon.js: -------------------------------------------------------------------------------- 1 | import { parse } from 'bredon' 2 | import createUniqueValue from '../utils/createUniqueValue' 3 | 4 | export default () => parse(createUniqueValue()) 5 | -------------------------------------------------------------------------------- /benchmark/cases/postcss-value-parser.js: -------------------------------------------------------------------------------- 1 | import parse from 'postcss-value-parser' 2 | import createUniqueValue from '../utils/createUniqueValue' 3 | 4 | export default () => parse(createUniqueValue()) 5 | -------------------------------------------------------------------------------- /benchmark/index.js: -------------------------------------------------------------------------------- 1 | import { Suite } from 'benchmark' 2 | import beautifyBenchmark from 'beautify-benchmark' 3 | 4 | import bredon from './cases/bredon' 5 | import postcssValueParser from './cases/postcss-value-parser' 6 | 7 | export const run = () => { 8 | console.log(`Running performance tests.`) 9 | 10 | const testSuite = new Suite() 11 | 12 | testSuite.add('bredon', () => bredon()) 13 | testSuite.add('postcss-value-parser', () => postcssValueParser()) 14 | 15 | testSuite.on('cycle', e => { 16 | beautifyBenchmark.add(e.target) 17 | }) 18 | 19 | testSuite.on('complete', function() { 20 | beautifyBenchmark.log() 21 | console.log(`Fastest is: ${this.filter('fastest').map('name')}`) 22 | }) 23 | 24 | return testSuite.run({ async: true }) 25 | } 26 | 27 | run() 28 | -------------------------------------------------------------------------------- /benchmark/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "private": true, 3 | "name": "performance-benchmarks", 4 | "version": "0.0.1", 5 | "scripts": { 6 | "bench": "babel-node index" 7 | }, 8 | "dependencies": { 9 | "babel-cli": "6.18.0", 10 | "babel-preset-es2015": "6.24.1", 11 | "babel-preset-stage-0": "6.24.1", 12 | "beautify-benchmark": "0.2.4", 13 | "benchmark": "2.1.2", 14 | "bredon": "^4.0.0", 15 | "postcss-value-parser": "^3.3.0" 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /benchmark/utils/createUniqueValue.js: -------------------------------------------------------------------------------- 1 | const keywords = [ 2 | 'solid', 3 | 'inherit', 4 | 'flex-end', 5 | 'flex-start', 6 | 'align', 7 | 'left', 8 | 'opacity', 9 | ] 10 | 11 | export default function createUniqueValue() { 12 | const randomIndex = Math.round(Math.random() * 100) 13 | 14 | const values = [ 15 | keywords[randomIndex % 7], 16 | `${randomIndex * 10}px`, 17 | `rgba(${randomIndex * 2}, ${randomIndex * 4}, ${randomIndex * 18 | 5}, 0.${randomIndex})`, 19 | ] 20 | 21 | return values.join(' ') 22 | } 23 | -------------------------------------------------------------------------------- /docs/API.md: -------------------------------------------------------------------------------- 1 | # API Reference 2 | 3 | ## bredon 4 | * [`parse(input)`](api/bredon/parse.md) 5 | * [`traverse(ast, [visitors], [context])`](api/bredon/traverse.md) 6 | * [`generate(ast, [generators])`](api/bredon/generate.md) 7 | * [`compile(input, [options])`](api/bredon/compile.md) 8 | 9 | ## bredon-types 10 | > Note: Bredon itself exports `bredon-types` as [`types`](api/bredon/types.md). 11 | 12 | * [Validators](api/bredon-types/Validators.md) 13 | * [Builders](api/bredon-types/Builders.md) 14 | 15 | ## bredon-validate 16 | * [`validate(property, value)`](api/bredon-validate/validate.md) 17 | 18 | ## bredon-minify 19 | * [`minify(property, value)`](api/bredon-minify/minify.md) -------------------------------------------------------------------------------- /docs/Nodes.md: -------------------------------------------------------------------------------- 1 | 2 | # AST Nodes 3 | Every AST node is an object with certain properties. They all share the `type` field which explicitly describes the node's type.
4 | All primitive nodes also share the `value` property which simply yields the node's value.
5 | Container nodes on the other hand have a property that contains an array of child nodes. 6 | 7 | ## Root Nodes 8 | 9 | #### ValueList 10 | ValueList is the **root** node of every bredon AST.
11 | It contains a list of Value nodes which are comma-separated CSS values. 12 | 13 | For example: `opacity, transform 1s ease-in` 14 | 15 | ```javascript 16 | { 17 | type: 'ValueList', 18 | body: [{ 19 | type: 'Value', 20 | important: false, 21 | body: [ 22 | /* AST for opacity */ 23 | ] 24 | }, { 25 | type: 'Value', 26 | important: false, 27 | body: [ 28 | /* AST for transform 1s ease-in */ 29 | ] 30 | }] 31 | } 32 | ``` 33 | 34 | #### Value 35 | Value contains a set of nodes that are whitespace-separated. 36 | 37 | For example: `1px solid black` 38 | 39 | ```javascript 40 | { 41 | type: 'Value', 42 | important: false, 43 | body: [ 44 | /* Nodes for 1px solid black */ 45 | ] 46 | } 47 | ``` 48 | 49 | ### Node Types 50 | * [Identifier](#identifier) 51 | * [Operator](#operator) 52 | * [HexColor](#hexcolor) 53 | * [Parenthesis](#parenthesis) 54 | * [URL](#url) 55 | * [StringLiteral](#stringliteral) 56 | * [Integer](#integer) 57 | * [Float](#float) 58 | * [Assignment](#assignment) 59 | * [Dimension](#dimension) 60 | * [FunctionExpression](#functionexpression) 61 | * [Expression](#expression) 62 | 63 | ## Identifier 64 | Identifiers are all kind of words such as `solid`. 65 | ```javascript 66 | // e.g. solid 67 | { 68 | type: 'Identifier', 69 | value: 'solid' 70 | } 71 | ``` 72 | 73 | ## Operator 74 | Operators are basic arithmetic expression symbols for addition `+`, subtraction `-`, multiplication `*`, and division `/`. 75 | 76 | ```javascript 77 | // e.g. + 78 | { 79 | type: 'Operator', 80 | value: '+' 81 | } 82 | ``` 83 | 84 | ## HexColor 85 | HexColor represents color values given in hexadecimal notation. 86 | 87 | ```javascript 88 | // e.g. #FF66FF 89 | { 90 | type: 'HexColor', 91 | value: 'FF66FF' 92 | } 93 | ``` 94 | 95 | ## Parenthesis 96 | Parenthesis are used to wrap expressions. They may used to enforce e.g. additions to be executed before multiplications. Parenthesis surrounding [Functions](#function) will **not** be parsed into AST nodes. 97 | 98 | ```javascript 99 | // e.g. ( 100 | { 101 | type: 'Parenthesis', 102 | value: '(' 103 | } 104 | ``` 105 | 106 | ## URL 107 | URL is used for any URI-type string. *It is not validated by the parser!* 108 | 109 | ```javascript 110 | // e.g. https://github.com/ 111 | { 112 | type: 'URL', 113 | value: 'https://github.com/' 114 | } 115 | ``` 116 | 117 | ## StringLiteral 118 | Strings are all values that are wrapped in quotes, either single `'` or double `"`. 119 | 120 | | Property | Value | Description | 121 | | ------ | --- | ------ | 122 | | quote | `'`, `"` | The used quote type | 123 | 124 | ```javascript 125 | // e.g. "I'm a string!!11!1" 126 | { 127 | type: 'StringLiteral', 128 | value: 'I\'m a string!!11!1', 129 | quote: '"' 130 | } 131 | ``` 132 | 133 | ## Integer 134 | Integers are simple numbers without a unit or fractional part. 135 | 136 | | Property | Value | Description | 137 | | ------ | --- | ------ | 138 | | negative | (*boolean*) | flag indicating a negative value | 139 | 140 | ```javascript 141 | // e.g. 34 142 | { 143 | type: 'Integer', 144 | negative: false, 145 | value: 34 146 | } 147 | ``` 148 | 149 | ## Float 150 | Floats are floating-point numbers with a fractional part and an integer part. 151 | 152 | | Property | Value | Description | 153 | | ------ | --- | ------ | 154 | | integer | (*number*) |The integer part | 155 | | fractional | (*number*) | The fractional part | 156 | | negative | (*boolean*) | flag indicating a negative value | 157 | 158 | ```javascript 159 | // e.g. 587.923 160 | { 161 | type: 'Float', 162 | integer: 587, 163 | fractional: 0.923, 164 | negative: false 165 | } 166 | ``` 167 | 168 | ## Assignment 169 | Assignments are combinations of identifiers and a value, combined using an equal sign. They may only appear within [FunctionExpression](#functionexpression)s. 170 | 171 | | Property | Value | Description | 172 | | ------ | --- | ------ | 173 | | name | (*string*) | The variable name that is assigned to | 174 | | value | (*Node*) | The value that is assigned | 175 | 176 | ```javascript 177 | // e.g. color="red" 178 | { 179 | type: 'Assignment', 180 | name: 'color', 181 | value: { 182 | type: 'Identifier', 183 | value: 'red' 184 | } 185 | } 186 | 187 | // e.g. opacity=0.9 188 | { 189 | type: 'Assignment', 190 | name: 'opacity', 191 | value: { 192 | type: 'Float', 193 | negative: false, 194 | fractional: 0.9, 195 | integer: 0 196 | } 197 | } 198 | ``` 199 | 200 | ## Dimension 201 | Dimensions are special integers or floats that are postfixed with an extra unit. They are used *e.g. to measure font sizes*. 202 | 203 | | Property | Value | Description | 204 | | ------ | --- | ------ | 205 | | value | (*[Integer](#integer)*, *[Float](#float)*) | The pure value without a unit | 206 | | unit | `%`, `em`, `ex`, `ch`, `rem`, `vw`, `vh`, `vmin`, `vmax`, `cm`, `mm`, `q`, `in`, `pt`, `pc`, `px`, `deg`, `grad`, `rad`, `turn`, `s`, `ms`, `Hz`, `kHz`, `dpi`, `dpcm`, `dppx` | The concrete dimension unit | 207 | 208 | 209 | ```javascript 210 | // e.g. 12px 211 | { 212 | type: 'Dimension', 213 | unit: 'px', 214 | value: { 215 | type: 'Integer', 216 | negative: false, 217 | value: 12 218 | } 219 | } 220 | 221 | // e.g. 33.33% 222 | { 223 | type: 'Dimension', 224 | unit: 'px', 225 | value: { 226 | type: 'Float', 227 | fractional: 0.33, 228 | integer: 33, 229 | negative: false 230 | } 231 | } 232 | ``` 233 | 234 | ## FunctionExpression 235 | Functions represent CSS functions wrapped in parentheses. 236 | 237 | | Property | Value | Description | 238 | | ------ | --- | ------ | 239 | | callee | (*string*) | The function name | 240 | | params | *(Array)* | An array of function parameter of any AST node type | 241 | 242 | ```javascript 243 | 244 | // e.g. rgba(10, 20, 30, 0.55) 245 | { 246 | type: 'FunctionExpression', 247 | callee: 'rgba', 248 | params: [{ 249 | type: 'Integer', 250 | negative: false, 251 | value: 10 252 | }, { 253 | type: 'Integer', 254 | negative: false, 255 | value: 20 256 | }, { 257 | type: 'Integer', 258 | negative: false, 259 | value: 30 260 | }, { 261 | type: 'Float', 262 | negative: false, 263 | fractional: 0.55, 264 | integer: 0 265 | }] 266 | } 267 | ``` 268 | 269 | ## Expression 270 | Expressions are mathematical calculations.
271 | They can only appear inside the CSS `calc`-function. 272 | 273 | | Property | Value | Description | 274 | | ------ | --- | ------ | 275 | | body | (*Array*) | An array of any AST nodes | 276 | 277 | ```javascript 278 | 279 | // e.g. 100% - 30px*3 280 | { 281 | type: 'Expression', 282 | body: [{ 283 | type: 'Dimension', 284 | value: { 285 | type: 'Integer', 286 | negative: false, 287 | value: 100 288 | }, 289 | unit: '%' 290 | }, { 291 | type: 'Operator', 292 | value: '-' 293 | }, { 294 | type: 'Dimension', 295 | value: { 296 | type: 'Integer', 297 | negative: false, 298 | value: 30 299 | }, 300 | unit: 'px' 301 | }, { 302 | type: 'Operator', 303 | value: '*' 304 | }, { 305 | type: 'Integer', 306 | negative: false, 307 | value: 3 308 | }] 309 | } 310 | ``` 311 | -------------------------------------------------------------------------------- /docs/api/bredon-minify/minify.md: -------------------------------------------------------------------------------- 1 | # `minify(property, value)` 2 | 3 | Minifies a CSS value as much as possible. 4 | 5 | ## Arguments 6 | 1. `property` (*string*): The CSS property name *(in camelCase)* 7 | 2. `value` (*string*): The CSS value that should be minified 8 | 9 | ## Returns 10 | (*string*) The minified CSS value 11 | 12 | ## Example 13 | 14 | ```javascript 15 | import minify from 'bredon-minify' 16 | 17 | minify('borderLeft', '2px hsl(calc( 100/2 + 10*3 ), 50% , 20%)') 18 | // => 2px #3B4D19 19 | 20 | minify('fontSize', '12.5555px') 21 | // => 12.56px 22 | ``` -------------------------------------------------------------------------------- /docs/api/bredon-types/Builders.md: -------------------------------------------------------------------------------- 1 | # Builders 2 | 3 | For every AST node, the `bredon-types` package also ships a builder function which safely creates AST nodes manually. 4 | 5 | * [dimension](#dimensionvalue-integer-float-unit-unit) 6 | * [expression](#expressionbody-arraynode) 7 | * [float](#floatinteger-number-fractional-number-isnegative-boolean--false) 8 | * [functionExpression](#functionexpressioncallee-string-params-arraynode) 9 | * [hexColor](#hexcolorcolor-string) 10 | * [identifier](#identifiername-string) 11 | * [integer](#integervalue-number-isnegative-boolean--false) 12 | * [operator](#operatorsign--------) 13 | * [parenthesis](#parenthesisparen--) 14 | * [separator](#separator) 15 | * [stringLiteral](#stringliteralstr-string-quote-----) 16 | * [url](#urluri-string) 17 | * [value](#valuebody-arraynode) 18 | * [valueList](#valuelistbody-arraycssvalue) 19 | 20 | ## `dimension(value: Integer | Float, unit: Unit)` 21 | 22 | where Unit refers to one of the valid units:
23 | `%`, `em`, `ex` , `ch` , `rem` , `vw` , `vh` , `vmin` , `vmax` , `cm` , `mm` , `q` , `in` , `pt` , `pc` , `px` , `deg` , `grad` , `rad` , `turn` , `s` , `ms` , `Hz` , `kHz` , `dpi` , `dpcm` , `dppx` 24 | 25 | ```javascript 26 | import { dimension } from 'bredon-types' 27 | 28 | dimension(integer(300), 'px') // => 30px 29 | dimension(float(33, 33, true), '%') // => -33.33% 30 | ``` 31 | 32 | ## `expression(body: Array)` 33 | 34 | ```javascript 35 | import { expression } from 'bredon-types' 36 | 37 | expression([ /* child nodes */ ]) 38 | ``` 39 | 40 | ## `float(integer: number, fractional: number, isNegative?: boolean = false)` 41 | 42 | ```javascript 43 | import { float } from 'bredon-types' 44 | 45 | float(0, 55) // => .55 46 | float(1, 10, true) // => -1.10 47 | ``` 48 | 49 | ## `functionExpression(callee: string, params: Array)` 50 | 51 | ```javascript 52 | import { functionExpression } from 'bredon-types' 53 | 54 | functionExpression('rgba', [ /* param nodes */ ]) // => rgba(...) 55 | ``` 56 | 57 | ## `hexColor(color: string)` 58 | 59 | ```javascript 60 | import { hexColor } from 'bredon-types' 61 | 62 | hexColor('FFF') // => #FFF 63 | ``` 64 | 65 | ## `identifier(name: string)` 66 | 67 | ```javascript 68 | import { identifier } from 'bredon-types' 69 | 70 | identifier('solid') // => solid 71 | ``` 72 | 73 | ## `integer(value: number, isNegative?: boolean = false)` 74 | 75 | ```javascript 76 | import { integer } from 'bredon-types' 77 | 78 | integer(55) // => 55 79 | integer(55, true) // => -55 80 | ``` 81 | 82 | ## `operator(sign: '+' | '-' | '/' | '*')` 83 | 84 | ```javascript 85 | import { operator } from 'bredon-types' 86 | 87 | operator('+') // => + 88 | ``` 89 | 90 | ## `parenthesis(paren: '(' | ')')` 91 | 92 | ```javascript 93 | import { parenthesis } from 'bredon-types' 94 | 95 | parenthesis('(') // => ( 96 | ``` 97 | 98 | ## `seperator()` 99 | 100 | ```javascript 101 | import { seperator } from 'bredon-types' 102 | 103 | seperator() // => / 104 | ``` 105 | 106 | ## `stringLiteral(str: string, quote?: '"' | "'" = "'")` 107 | 108 | ```javascript 109 | import { stringLiteral } from 'bredon-types' 110 | 111 | stringLiteral("Hello, I am a string.", '"') // => "Hello, I am a string." 112 | ``` 113 | 114 | ## `url(uri: string)` 115 | 116 | ```javascript 117 | import { url } from 'bredon-types' 118 | 119 | url("https://www.github.com/") // => url("https://www.github.com/") 120 | ``` 121 | 122 | ## `value(body: Array, isImportant?: boolean = false)` 123 | 124 | ```javascript 125 | import { cssValue } from 'bredon-types' 126 | 127 | value([ /* child nodes */ ]) 128 | value([ /* child nodes */ ], true) 129 | ``` 130 | 131 | ## `valueList(body: Array)` 132 | 133 | ```javascript 134 | import { valueList } from 'bredon-types' 135 | 136 | valueList([ /* value nodes */]) 137 | ``` -------------------------------------------------------------------------------- /docs/api/bredon-types/Validators.md: -------------------------------------------------------------------------------- 1 | # Validators 2 | 3 | For every AST node, the `bredon-types` package ships a validator function that simply checks the node type. 4 | 5 | The following validators exist: 6 | * isDimension 7 | * isExpression 8 | * isFloat 9 | * isFunctionExpression 10 | * isHexColor 11 | * isIdentifier 12 | * isInteger 13 | * isOperator 14 | * isParenthesis 15 | * isSeparator 16 | * isStringLiteral 17 | * isUrl 18 | * isValue 19 | * isValueList 20 | 21 | Each validator function takes a single AST node as first parameter and returns a boolean. 22 | 23 | ## Example 24 | ```javascript 25 | import { isIdentifier, isHexColor } from 'bredon-types' 26 | 27 | const ast = { 28 | type: 'HexColor', 29 | value: 'FFF' 30 | } 31 | 32 | isIdentifier(ast) // => false 33 | isHexColor(ast) // => true 34 | ``` 35 | -------------------------------------------------------------------------------- /docs/api/bredon-validate/validate.md: -------------------------------------------------------------------------------- 1 | # `validate(property, value)` 2 | 3 | Validates a CSS declaration using type-checking. 4 | 5 | ## Arguments 6 | 1. `property` (*string*): The CSS property that should be validated *(in camelCase)* 7 | 2. `value` (*string*): The CSS value that is parsed and type-checked 8 | 9 | ## Returns 10 | (*boolean*) Indicator if the declaration is valid or invalid 11 | 12 | ## Example 13 | 14 | ```javascript 15 | import validate from 'bredon-validate' 16 | 17 | validate('borderLeft', '1px solid rgba(100, 200, 50, .55)') 18 | // => true 19 | 20 | validate('borderLeft', '1px 2px rgba(100, 200, 50, .55)') 21 | // => false 22 | ``` 23 | -------------------------------------------------------------------------------- /docs/api/bredon/compile.md: -------------------------------------------------------------------------------- 1 | # `compile(input, [options])` 2 | 3 | Compile basically is shorthand and executes [`parse`](parse.md), [`traverse`](traverse.md) and [`generate`](generate.md) in exact order. 4 | 5 | ## Arguments 6 | 1. `input` (*string*): The CSS value that gets parsed 7 | 2. `options` (*Object?*): An object containing compilation options 8 | 9 | a list of `plugins` which basically are `visitors` (see [`traverse`](traverse.md)) and/or `generators` (see [`generate`](generate.md)) 10 | 11 | #### Options 12 | | Option | Value | Default | Description | 13 | | ------ | ----- | ------- | ----------- | 14 | | plugins | (*Array?*) | `[]` | A list of `visitors` (see [`traverse`](traverse.md)) | 15 | | generators | (*Object?*) | `{}` | An object containing node `generators` (see [`generate`](generate.md)) | 16 | | context | (*Object?*) | `{}` | An object containing additional context information which is required by some plugins (see [`traverse`](traverse.md)) | 17 | 18 | ## Returns 19 | (*string*) transformed CSS value 20 | 21 | ## Example 22 | 23 | ```javascript 24 | import { compile } from 'bredon' 25 | 26 | const input = ' 1px solid rgba(100 , 200, 50, 0.55 ) ' 27 | 28 | const visitor = { 29 | Float: { 30 | enter(path) { 31 | console.log(path.parent.callee) 32 | console.log(path.node) 33 | // transforming the fractional part of each float 34 | path.node.fractional += 0.5 35 | } 36 | 37 | exit(path) { 38 | console.log(path.node) 39 | } 40 | } 41 | } 42 | 43 | const plugins = [visitor] 44 | 45 | const generators = { 46 | Function: (node, generate) => 47 | `${node.callee}(${node.params.map(generate).join(' , ')})` 48 | } 49 | 50 | const output = compile(input, { 51 | generators, 52 | plugins 53 | }) 54 | // => rgba 55 | // => { type: 'Float', integer: 0, fractional: 0.55, negative: false } 56 | // => { type: 'Float', integer: 0, fractional: 0.60, negative: false } 57 | 58 | console.log(output) 59 | // => '1px solid rgba(100 , 200 , 50 , 0.60)' 60 | ``` 61 | -------------------------------------------------------------------------------- /docs/api/bredon/generate.md: -------------------------------------------------------------------------------- 1 | # `generate(ast, [generators])` 2 | 3 | Renders the AST into a single, formatted string. It uses opinionated formatting rules and generates specification-conform CSS values. 4 | 5 | ## Arguments 6 | 1. `ast` (*Object)*: An object containing the AST representation of a CSS value string 7 | 2. `generators` (*Object?*): Similar to the `visitors` option passed to `traverse`, we can pass an object with AST node type formatters. If an AST node type is not explicitly passed, it will use the default formatter. The formatter signature is `(node, generate) => string` where `node` is the current AST node and `generate` is a function to recursively format inner child nodes. 8 | 9 | 10 | ## Returns 11 | (*string*) formatted and minified string version of the CSS value 12 | 13 | ## Example 14 | 15 | ```javascript 16 | import { generate, parse } from 'bredon' 17 | 18 | const input = ' 1px solid rgba(100 , 200, 50, 0.55 ) ' 19 | const ast = parse(input) 20 | 21 | const generators = { 22 | Function: (node, generate) => 23 | `${node.callee}(${node.params.map(generate).join(' , ')})` 24 | } 25 | 26 | const output = generate(ast, generators) 27 | 28 | console.log(output) 29 | // => '1px solid rgba(100 , 200 , 50 , 0.55)' 30 | ``` 31 | -------------------------------------------------------------------------------- /docs/api/bredon/parse.md: -------------------------------------------------------------------------------- 1 | # `parse(input)` 2 | 3 | Parses a CSS value string into a uniform Abstract Syntax Tree (AST). 4 | 5 | ## Arguments 6 | 1. `input` (*string*): The CSS value that gets parsed 7 | 8 | ## Returns 9 | (*Object*) Returns the full AST as an object 10 | 11 | ## Example 12 | ```javascript 13 | import { parse } from 'bredon' 14 | 15 | const input = '1px solid rgba(100, 250, 50, 0.55)' 16 | const ast = parse(input) 17 | 18 | ast === { 19 | type: 'ValueList', 20 | body: [{ 21 | type: 'Value', 22 | important: false, 23 | body: [{ 24 | type: 'Dimension', 25 | unit: 'px', 26 | value: { 27 | type: 'Integer', 28 | negative: false, 29 | value: 1 30 | } 31 | }, { 32 | type: 'Identifier', 33 | value: 'solid' 34 | }, { 35 | type: 'FunctionExpression', 36 | callee: 'rgba', 37 | params: [{ 38 | type: 'Integer', 39 | negative: false, 40 | value: 100 41 | }, { 42 | type: 'Integer', 43 | negative: false, 44 | value: 250 45 | }, { 46 | type: 'Integer', 47 | negative: false, 48 | value: 50 49 | }, { 50 | type: 'Float', 51 | negative: false, 52 | fractional: 0.55, 53 | integer: 0 54 | }] 55 | }] 56 | }] 57 | } 58 | ``` 59 | -------------------------------------------------------------------------------- /docs/api/bredon/traverse.md: -------------------------------------------------------------------------------- 1 | # `traverse(ast, [visitors], [context])` 2 | 3 | Traverses every AST node recursively and calls the visitor methods for each AST node respectively.
4 | It is commonly used to apply AST transformation. 5 | 6 | ## Arguments 7 | 1. `ast` (*Object)*: An object containing the AST representation of a CSS value string 8 | 2. `visitors` (*Array?*): An array of visitor objects with AST node names as keys and an object containing `enter` and/or `exit` methods. If a method is provided directly, it will resolve to the `enter` method. The signature for both is *(node, parentNode) => void* 9 | 3. `context` (*Object?*): An object containing additional context information which is required by some plugins 10 | 11 | #### Context 12 | | Option | Value | Description | 13 | | ------ | ----- | ----------- | 14 | | property | (*string*) | The CSS property name that's associated with the compiled value | 15 | 16 | #### Example 17 | ```javascript 18 | import { travsere, parse } from 'bredon' 19 | 20 | const input = '1px solid rgba(100, 250, 50, 0.55)' 21 | const ast = parse(input) 22 | 23 | const visitor = { 24 | Float: { 25 | enter(path) { 26 | console.log(path.parent.callee) 27 | console.log(path.node) 28 | // transforming the fractional part of each float 29 | path.node.fractional += 0.5 30 | } 31 | 32 | exit(path) { 33 | console.log(path.node) 34 | } 35 | } 36 | } 37 | 38 | traverse(ast, [visitor]) 39 | // => rgba 40 | // => { type: 'Float', integer: 0, fractional: 0.55, negative: false } 41 | // => { type: 'Float', integer: 0, fractional: 0.60, negative: false } 42 | ``` 43 | -------------------------------------------------------------------------------- /docs/api/bredon/types.md: -------------------------------------------------------------------------------- 1 | # Types 2 | 3 | Bredon exports `bredon-types` as `types`. 4 | If you've already installed `bredon`, you do not need to install `bredon-types` separately. 5 | 6 | ```javascript 7 | import { types } from 'bredon' 8 | 9 | const node = types.integer(3, true) 10 | // => { type: 'Integer', value: 3, negative: true } 11 | 12 | types.isInteger(node) 13 | // => true 14 | ``` -------------------------------------------------------------------------------- /flowtypes/AST.js: -------------------------------------------------------------------------------- 1 | export type SimpleNode = { type: string, value: string | number } 2 | export type FunctionNode = { 3 | type: 'FunctionExpression', 4 | callee: string, 5 | params: Array, 6 | } 7 | export type DimensionNode = { 8 | type: 'Dimension', 9 | value: number, 10 | dimension: string, 11 | unit: string, 12 | } 13 | export type IntegerNode = { 14 | type: 'Integer', 15 | value: number, 16 | negative?: boolean, 17 | } 18 | export type FloatNode = { 19 | type: 'Float', 20 | integer?: number, 21 | fractional: number, 22 | } 23 | export type StringNode = { 24 | type: 'StringLiteral', 25 | value: string, 26 | quote: '"' | "'", 27 | } 28 | export type ExpressionNode = { 29 | type: 'Expression', 30 | body: Array, 31 | } 32 | 33 | export type AssignmentNode = { 34 | type: 'Assignment', 35 | name: string, 36 | value: Node, 37 | } 38 | 39 | export type Node = 40 | | SimpleNode 41 | | FunctionNode 42 | | DimensionNode 43 | | FloatNode 44 | | IntegerNode 45 | | StringNode 46 | | ExpressionNode 47 | 48 | export type Value = { 49 | type: 'Value', 50 | body: Array, 51 | important: boolean, 52 | } 53 | export type ValueList = { type: 'ValueList', values: Array } 54 | 55 | export type ASTNode = Node | Value | ValueList 56 | -------------------------------------------------------------------------------- /flowtypes/Path.js: -------------------------------------------------------------------------------- 1 | export type Path = { 2 | parent: Path, 3 | node: ASTNode, 4 | replace: Function, 5 | remove: Function, 6 | } 7 | -------------------------------------------------------------------------------- /flowtypes/RuleMap.js: -------------------------------------------------------------------------------- 1 | export type RuleMap = { [token: string]: string | Function } 2 | -------------------------------------------------------------------------------- /flowtypes/Token.js: -------------------------------------------------------------------------------- 1 | export type Token = { 2 | type: string, 3 | value: string, 4 | start: number, 5 | end: number, 6 | } 7 | -------------------------------------------------------------------------------- /lerna.json: -------------------------------------------------------------------------------- 1 | { 2 | "lerna": "2.5.1", 3 | "npmClient": "yarn", 4 | "version": "independent", 5 | "packages": [ 6 | "packages/*", 7 | "benchmark" 8 | ] 9 | } -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "private": true, 3 | "scripts": { 4 | "bootstrap": "lerna bootstrap", 5 | "build": "./scripts/build.sh", 6 | "clean": "lerna clean --yes && rimraf packages/*/es && rimraf packages/*/lib", 7 | "check": "npm run lint && npm run test:coverage && npm run flow", 8 | "format": "prettier --write \"**/**.js\"" , 9 | "flow": "flow", 10 | "lint": "eslint packages/*/src/**/*.js", 11 | "release": "git pull --rebase && npm run build && lerna publish", 12 | "test": "cross-env BABEL_ENV=commonjs jest", 13 | "test:coverage": "cross-env BABEL_ENV=commonjs jest --coverage", 14 | "watch": "yarn test -- --watch", 15 | "setup": "yarn run clean && yarn run bootstrap && yarn run build" 16 | }, 17 | "jest": { 18 | "rootDir": "packages", 19 | "testPathIgnorePatterns": [ 20 | "/mocks/", 21 | "/lib/" 22 | ] 23 | }, 24 | "devDependencies": { 25 | "babel-cli": "^6.24.1", 26 | "babel-core": "^6.22.1", 27 | "babel-eslint": "^7.1.1", 28 | "babel-jest": "^18.0.0", 29 | "babel-preset-es2015": "^6.22.0", 30 | "babel-preset-flow": "^6.23.0", 31 | "babel-preset-stage-0": "^6.24.1", 32 | "codeclimate-test-reporter": "^0.4.0", 33 | "cross-env": "^5.0.1", 34 | "eslint": "^3.14.1", 35 | "eslint-config-airbnb": "^14.0.0", 36 | "eslint-plugin-flowtype": "^2.30.0", 37 | "eslint-plugin-import": "^2.2.0", 38 | "eslint-plugin-jsx-a11y": "^3.0.2", 39 | "eslint-plugin-react": "^6.9.0", 40 | "flow-bin": "^0.38.0", 41 | "jest": "^19.0.0", 42 | "lerna": "^2.5.1", 43 | "prettier": "^1.7.4", 44 | "rimraf": "^2.6.1" 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /packages/bredon-minify/README.md: -------------------------------------------------------------------------------- 1 | # bredon-minify 2 | 3 | NPM package to get access to Bredon's Minify API.
4 | Check out the [Bredon repository](https://github.com/rofrischmann/bredon) for further information. -------------------------------------------------------------------------------- /packages/bredon-minify/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "bredon-minify", 3 | "version": "1.0.1", 4 | "description": "Preconfigured Bredon Compiler to minify CSS values", 5 | "main": "lib/index.js", 6 | "module": "es/index.js", 7 | "jsnext:main": "es/index.js", 8 | "files": [ 9 | "LICENSE", 10 | "README.md", 11 | "lib/**", 12 | "es/**" 13 | ], 14 | "keywords": [ 15 | "css", 16 | "parser", 17 | "css-parser", 18 | "css-value-parser", 19 | "ast", 20 | "lexer", 21 | "tokenizer", 22 | "minifier", 23 | "css-minify", 24 | "cssinjs", 25 | "bredon" 26 | ], 27 | "repository": "https://github.com/rofrischmann/bredon.git", 28 | "author": "Robin Frischmann ", 29 | "license": "MIT", 30 | "dependencies": { 31 | "bredon": "^4.0.0", 32 | "bredon-plugin-calc": "^1.0.0", 33 | "bredon-plugin-color": "^1.0.0", 34 | "bredon-plugin-initial": "^1.0.0", 35 | "bredon-plugin-precision": "^1.0.0", 36 | "bredon-plugin-remove-unit": "^1.0.0", 37 | "bredon-plugin-trim-hex": "^1.0.0" 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /packages/bredon-minify/src/__tests__/minify-test.js: -------------------------------------------------------------------------------- 1 | import minify from '../index' 2 | 3 | describe('Minifying CSS values', () => { 4 | it('should minify values as much as possible', () => { 5 | expect( 6 | minify( 7 | 'border', 8 | '1px rgba(200, 200, 50, 0.5855), 2px hsl(calc(100/2 + 10*3), 50%, 20%)' 9 | ) 10 | ).toBe('1px rgba(200,200,50,.59),2px #3B4D19') 11 | 12 | expect(minify('fontSize', '12.5555px')).toBe('12.56px') 13 | }) 14 | }) 15 | -------------------------------------------------------------------------------- /packages/bredon-minify/src/index.js: -------------------------------------------------------------------------------- 1 | import { compile } from 'bredon' 2 | 3 | import calc from 'bredon-plugin-calc' 4 | import color from 'bredon-plugin-color' 5 | import initial from 'bredon-plugin-initial' 6 | import trimHex from 'bredon-plugin-trim-hex' 7 | import precision from 'bredon-plugin-precision' 8 | import removeUnit from 'bredon-plugin-remove-unit' 9 | 10 | const generators = { 11 | ValueList: (node, generate) => node.body.map(generate).join(','), 12 | Float: node => 13 | `${node.negative ? '-' : ''}${node.integer || 14 | ''}${node.fractional.toString().slice(1)}`, 15 | FunctionExpression: (node, generate) => 16 | `${node.callee}(${node.params.map(generate).join(',')})`, 17 | } 18 | 19 | const plugins = [ 20 | calc(), 21 | precision({ precision: 2 }), 22 | removeUnit(), 23 | color({ 24 | format: 'hex', 25 | }), 26 | trimHex(), 27 | initial({ 28 | useShorter: true, 29 | }), 30 | ] 31 | 32 | export default function minify(property: string, value: string): string { 33 | return compile(value, { 34 | context: { 35 | property, 36 | }, 37 | generators, 38 | plugins, 39 | }) 40 | } 41 | -------------------------------------------------------------------------------- /packages/bredon-minify/yarn.lock: -------------------------------------------------------------------------------- 1 | # THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. 2 | # yarn lockfile v1 3 | 4 | 5 | bredon-types@^3.0.0: 6 | version "3.0.0" 7 | resolved "https://registry.yarnpkg.com/bredon-types/-/bredon-types-3.0.0.tgz#1d49122f12df2c2868ba3065e27eede76b5af93e" 8 | 9 | bredon@^3.0.1: 10 | version "3.0.1" 11 | resolved "https://registry.yarnpkg.com/bredon/-/bredon-3.0.1.tgz#42d101c8dd7c6fca42ff4106a54049ff935d6cac" 12 | dependencies: 13 | bredon-types "^3.0.0" 14 | tokenize-sync "^1.0.0" 15 | 16 | tokenize-sync@^1.0.0: 17 | version "1.0.0" 18 | resolved "https://registry.yarnpkg.com/tokenize-sync/-/tokenize-sync-1.0.0.tgz#65b5b72bb208b013166e4d253e0b8b4990c70e83" 19 | -------------------------------------------------------------------------------- /packages/bredon-plugin-calc/README.md: -------------------------------------------------------------------------------- 1 | # bredon-plugin-calc 2 | 3 | npm version npm downloads 4 | 5 | The calc plugin will precalculate all `calc()` expression within CSS values as much as possible.
6 | 7 | > **Note**: It cannot resolve mixed units e.g. `%` and `px`. 8 | 9 | ## Installation 10 | ```sh 11 | yarn add bredon-plugin-calc 12 | ``` 13 | You may alternatively use `npm i --save bredon-plugin-calc`. 14 | 15 | ## Usage 16 | 17 | ```javascript 18 | import { compile } from 'bredon' 19 | import calcPlugin from 'bredon-plugin-calc' 20 | 21 | const input = 'calc(100% - 2*30%) calc(100% - 50px)' 22 | 23 | const output = compile(input, { 24 | plugins: [ 25 | calcPlugin() 26 | ] 27 | }) 28 | 29 | console.log(output) 30 | // => 40% calc(100% - 50px) 31 | ``` 32 | 33 | ## License 34 | Bredon is licensed under the [MIT License](http://opensource.org/licenses/MIT).
35 | Documentation is licensed under [Creative Common License](http://creativecommons.org/licenses/by/4.0/).
36 | Created with ♥ by [@rofrischmann](http://rofrischmann.de) and all the great contributors. 37 | -------------------------------------------------------------------------------- /packages/bredon-plugin-calc/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "bredon-plugin-calc", 3 | "version": "1.0.0", 4 | "description": "Bredon color to precalculate calc expressions", 5 | "main": "lib/index.js", 6 | "module": "es/index.js", 7 | "jsnext:main": "es/index.js", 8 | "files": [ 9 | "LICENSE", 10 | "README.md", 11 | "lib/**", 12 | "es/**" 13 | ], 14 | "keywords": [ 15 | "css", 16 | "parser", 17 | "css-parser", 18 | "css-value-parser", 19 | "ast", 20 | "lexer", 21 | "tokenizer", 22 | "cssinjs", 23 | "bredon" 24 | ], 25 | "repository": "https://github.com/rofrischmann/bredon.git", 26 | "author": "Robin Frischmann ", 27 | "license": "MIT", 28 | "dependencies": { 29 | "reduce-css-calc": "^2.1.1" 30 | }, 31 | "devDependencies": { 32 | "bredon": "^4.0.0" 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /packages/bredon-plugin-calc/src/__tests__/calc-test.js: -------------------------------------------------------------------------------- 1 | import { compile } from 'bredon' 2 | 3 | import calcPlugin from '../index' 4 | 5 | describe('Using calc plugin', () => { 6 | it('should reduce calc if possible', () => { 7 | expect( 8 | compile('calc(100%/2 + 20%)', { 9 | plugins: [calcPlugin()], 10 | }) 11 | ).toBe('70%') 12 | }) 13 | 14 | it('should use the provided precision', () => { 15 | expect( 16 | compile('calc(10px / 3)', { 17 | plugins: [calcPlugin({ precision: 6 })], 18 | }) 19 | ).toBe('3.333333px') 20 | }) 21 | }) 22 | -------------------------------------------------------------------------------- /packages/bredon-plugin-calc/src/index.js: -------------------------------------------------------------------------------- 1 | /* @flow */ 2 | import reduceCalc from 'reduce-css-calc' 3 | 4 | export default function calcPlugin(config?: Object = {}): Object { 5 | const precision = config.precision || 4 6 | 7 | return ({ generate, parse, types }) => ({ 8 | FunctionExpression({ node, replaceNode }) { 9 | if (node.callee === 'calc') { 10 | replaceNode(parse(reduceCalc(generate(node), precision))) 11 | } 12 | }, 13 | }) 14 | } 15 | -------------------------------------------------------------------------------- /packages/bredon-plugin-calc/yarn.lock: -------------------------------------------------------------------------------- 1 | # THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. 2 | # yarn lockfile v1 3 | 4 | 5 | bredon-types@^3.0.0: 6 | version "3.0.0" 7 | resolved "https://registry.yarnpkg.com/bredon-types/-/bredon-types-3.0.0.tgz#1d49122f12df2c2868ba3065e27eede76b5af93e" 8 | 9 | bredon@^3.0.1: 10 | version "3.0.1" 11 | resolved "https://registry.yarnpkg.com/bredon/-/bredon-3.0.1.tgz#42d101c8dd7c6fca42ff4106a54049ff935d6cac" 12 | dependencies: 13 | bredon-types "^3.0.0" 14 | tokenize-sync "^1.0.0" 15 | 16 | css-unit-converter@^1.1.1: 17 | version "1.1.1" 18 | resolved "https://registry.yarnpkg.com/css-unit-converter/-/css-unit-converter-1.1.1.tgz#d9b9281adcfd8ced935bdbaba83786897f64e996" 19 | 20 | postcss-value-parser@^3.3.0: 21 | version "3.3.0" 22 | resolved "https://registry.yarnpkg.com/postcss-value-parser/-/postcss-value-parser-3.3.0.tgz#87f38f9f18f774a4ab4c8a232f5c5ce8872a9d15" 23 | 24 | reduce-css-calc@^2.1.1: 25 | version "2.1.1" 26 | resolved "https://registry.yarnpkg.com/reduce-css-calc/-/reduce-css-calc-2.1.1.tgz#f4ecd7a00ec3e5683773f208067ad7da117b9db0" 27 | dependencies: 28 | css-unit-converter "^1.1.1" 29 | postcss-value-parser "^3.3.0" 30 | 31 | tokenize-sync@^1.0.0: 32 | version "1.0.0" 33 | resolved "https://registry.yarnpkg.com/tokenize-sync/-/tokenize-sync-1.0.0.tgz#65b5b72bb208b013166e4d253e0b8b4990c70e83" 34 | -------------------------------------------------------------------------------- /packages/bredon-plugin-case/README.md: -------------------------------------------------------------------------------- 1 | # bredon-plugin-case 2 | 3 | npm version npm downloads 4 | 5 | The case plugin normalizes the letter case for all identifier, hex color values, assigment names and units.
6 | It can either use lower-case or upper-case. 7 | 8 | ## Installation 9 | ```sh 10 | yarn add bredon-plugin-case 11 | ``` 12 | You may alternatively use `npm i --save bredon-plugin-case`. 13 | 14 | ## Usage 15 | 16 | ```javascript 17 | import { compile } from 'bredon' 18 | import casePlugin from 'bredon-plugin-case' 19 | 20 | const input = '1px SOLID AliceBlue' 21 | 22 | const output = compile(input, { 23 | plugins: [ 24 | casePlugin() 25 | ] 26 | }) 27 | 28 | console.log(output) 29 | // => 1px solid aliceblue 30 | ``` 31 | 32 | ### Configuration 33 | By default the plugin converts to lower-case. 34 | 35 | | Options | Value | Default | Description | 36 | | ------- | ----- | ------- | ----------- | 37 | | case | `lower`, `upper` | `lower` | The prefered case | 38 | 39 | ```javascript 40 | import { compile } from 'bredon' 41 | import casePlugin from 'bredon-plugin-case' 42 | 43 | const input = '1px SOLID AliceBlue' 44 | 45 | const output = compile(input, { 46 | plugins: [ 47 | casePlugin({ 48 | case: 'upper' 49 | }) 50 | ] 51 | }) 52 | 53 | console.log(output) 54 | // => 1PX SOLID ALICEBLUE 55 | ``` 56 | 57 | ## License 58 | Bredon is licensed under the [MIT License](http://opensource.org/licenses/MIT).
59 | Documentation is licensed under [Creative Common License](http://creativecommons.org/licenses/by/4.0/).
60 | Created with ♥ by [@rofrischmann](http://rofrischmann.de) and all the great contributors. 61 | -------------------------------------------------------------------------------- /packages/bredon-plugin-case/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "bredon-plugin-case", 3 | "version": "1.0.0", 4 | "description": "Bredon plugin to normalize case", 5 | "main": "lib/index.js", 6 | "module": "es/index.js", 7 | "jsnext:main": "es/index.js", 8 | "files": [ 9 | "LICENSE", 10 | "README.md", 11 | "lib/**", 12 | "es/**" 13 | ], 14 | "keywords": [ 15 | "css", 16 | "parser", 17 | "css-parser", 18 | "css-value-parser", 19 | "ast", 20 | "lexer", 21 | "tokenizer", 22 | "cssinjs", 23 | "bredon" 24 | ], 25 | "repository": "https://github.com/rofrischmann/bredon.git", 26 | "author": "Robin Frischmann ", 27 | "license": "MIT", 28 | "devDependencies": { 29 | "bredon": "^4.0.0" 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /packages/bredon-plugin-case/src/__tests__/case-test.js: -------------------------------------------------------------------------------- 1 | import { compile } from 'bredon' 2 | 3 | import casePlugin from '../index' 4 | 5 | describe('Using the case plugin', () => { 6 | it('should normalize identifier case', () => { 7 | expect( 8 | compile('FOO bar Baz BuZ', { 9 | plugins: [casePlugin()], 10 | }) 11 | ).toBe('foo bar baz buz') 12 | 13 | expect( 14 | compile('FOO bar Baz BuZ', { 15 | plugins: [ 16 | casePlugin({ 17 | case: 'upper', 18 | }), 19 | ], 20 | }) 21 | ).toBe('FOO BAR BAZ BUZ') 22 | }) 23 | }) 24 | -------------------------------------------------------------------------------- /packages/bredon-plugin-case/src/index.js: -------------------------------------------------------------------------------- 1 | /* @flow */ 2 | const resolvers = { 3 | lower: value => value.toLowerCase(), 4 | upper: value => value.toUpperCase(), 5 | } 6 | 7 | export default function casePlugin(config?: Object = {}): Object { 8 | const finalCase = config.case || 'lower' 9 | 10 | return { 11 | Identifier({ node }) { 12 | node.value = resolvers[finalCase](node.value) 13 | }, 14 | HexColor({ node }) { 15 | node.value = resolvers[finalCase](node.value) 16 | }, 17 | Dimension({ node }) { 18 | node.unit = resolvers[finalCase](node.unit) 19 | }, 20 | Assignment({ node }) { 21 | node.name = resolvers[finalCase](node.name) 22 | }, 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /packages/bredon-plugin-case/yarn.lock: -------------------------------------------------------------------------------- 1 | # THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. 2 | # yarn lockfile v1 3 | 4 | 5 | color-convert@^1.9.1: 6 | version "1.9.1" 7 | resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.1.tgz#c1261107aeb2f294ebffec9ed9ecad529a6097ed" 8 | dependencies: 9 | color-name "^1.1.1" 10 | 11 | color-name@^1.0.0, color-name@^1.1.1: 12 | version "1.1.3" 13 | resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25" 14 | 15 | color-string@^1.5.2: 16 | version "1.5.2" 17 | resolved "https://registry.yarnpkg.com/color-string/-/color-string-1.5.2.tgz#26e45814bc3c9a7cbd6751648a41434514a773a9" 18 | dependencies: 19 | color-name "^1.0.0" 20 | simple-swizzle "^0.2.2" 21 | 22 | color@^2.0.0: 23 | version "2.0.1" 24 | resolved "https://registry.yarnpkg.com/color/-/color-2.0.1.tgz#e4ed78a3c4603d0891eba5430b04b86314f4c839" 25 | dependencies: 26 | color-convert "^1.9.1" 27 | color-string "^1.5.2" 28 | 29 | is-arrayish@^0.3.1: 30 | version "0.3.1" 31 | resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.3.1.tgz#c2dfc386abaa0c3e33c48db3fe87059e69065efd" 32 | 33 | simple-swizzle@^0.2.2: 34 | version "0.2.2" 35 | resolved "https://registry.yarnpkg.com/simple-swizzle/-/simple-swizzle-0.2.2.tgz#a4da6b635ffcccca33f70d17cb92592de95e557a" 36 | dependencies: 37 | is-arrayish "^0.3.1" 38 | -------------------------------------------------------------------------------- /packages/bredon-plugin-color/README.md: -------------------------------------------------------------------------------- 1 | # bredon-plugin-color 2 | 3 | npm version npm downloads 4 | 5 | The color plugin is, as the name hints, all about modifying CSS color values. It can transform values into different color formats. 6 | 7 | Supported color formats are: 8 | * hex *(`#ffffff`)* 9 | * rgb *(`rgb(255, 0, 255)`, `rgba(255, 0, 255, 0.55))* 10 | * hsl *(`hsl(100, 100%, 50%)`, `hsla(100, 50%, 50%, 0.55))* 11 | 12 | It can also process color names e.g. `white`, but will not output those. 13 | 14 | ## Installation 15 | ```sh 16 | yarn add bredon-plugin-color 17 | ``` 18 | You may alternatively use `npm i --save bredon-plugin-color`. 19 | 20 | ## Usage 21 | 22 | ```javascript 23 | import { compile } from 'bredon' 24 | import colorPlugin from 'bredon-plugin-color' 25 | 26 | const input = '1px solid white' 27 | 28 | const output = compile(input, { 29 | plugins: [ 30 | colorPlugin() 31 | ] 32 | }) 33 | 34 | console.log(output) 35 | // => 1px solid #ffffff 36 | ``` 37 | 38 | ### Configuration 39 | By default the plugin transforms every color value to the hex color format.
40 | You can pass a custom color format with an options object. 41 | 42 | | Options | Value | Default | Description | 43 | | ------- | ----- | ------- | ----------- | 44 | | preserveAlpha | *boolean* | true | Values with alpha won't be transformed to `hex` | 45 | | format | `hex`, `rgb`, `hsl` | `hex` | The output color format | 46 | 47 | ```javascript 48 | import { compile } from 'bredon' 49 | import colorPlugin from 'bredon-plugin-color' 50 | 51 | const input = '1px solid white' 52 | 53 | const output = compile(input, { 54 | plugins: [ 55 | colorPlugin({ 56 | format: 'rgb' 57 | }) 58 | ] 59 | }) 60 | 61 | console.log(output) 62 | // => 1px solid rgb(255, 255, 255) 63 | ``` 64 | 65 | ## License 66 | Bredon is licensed under the [MIT License](http://opensource.org/licenses/MIT).
67 | Documentation is licensed under [Creative Common License](http://creativecommons.org/licenses/by/4.0/).
68 | Created with ♥ by [@rofrischmann](http://rofrischmann.de) and all the great contributors. 69 | -------------------------------------------------------------------------------- /packages/bredon-plugin-color/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "bredon-plugin-color", 3 | "version": "1.0.0", 4 | "description": "Bredon plugin to normalize color values", 5 | "main": "lib/index.js", 6 | "module": "es/index.js", 7 | "jsnext:main": "es/index.js", 8 | "files": [ 9 | "LICENSE", 10 | "README.md", 11 | "lib/**", 12 | "es/**" 13 | ], 14 | "keywords": [ 15 | "css", 16 | "parser", 17 | "css-parser", 18 | "css-value-parser", 19 | "ast", 20 | "lexer", 21 | "tokenizer", 22 | "cssinjs", 23 | "bredon" 24 | ], 25 | "repository": "https://github.com/rofrischmann/bredon.git", 26 | "author": "Robin Frischmann ", 27 | "license": "MIT", 28 | "dependencies": { 29 | "color": "^2.0.0" 30 | }, 31 | "devDependencies": { 32 | "bredon": "^4.0.0" 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /packages/bredon-plugin-color/src/__tests__/color-test.js: -------------------------------------------------------------------------------- 1 | import { compile } from 'bredon' 2 | 3 | import colorPlugin from '../index' 4 | 5 | describe('Using the color plugin', () => { 6 | it('should normalize color values to hex colors', () => { 7 | expect( 8 | compile('1px solid rgb(100, 100, 200)', { 9 | plugins: [colorPlugin()], 10 | }) 11 | ).toBe('1px solid #6464C8') 12 | }) 13 | 14 | it('should normalize color values to hsl', () => { 15 | expect( 16 | compile('1px solid rgba(100, 100, 200, 0.55)', { 17 | plugins: [colorPlugin({ format: 'hsl' })], 18 | }) 19 | ).toBe('1px solid hsla(240, 47.6%, 58.8%, 0.55)') 20 | }) 21 | 22 | it('should normalize color values to rgb', () => { 23 | expect( 24 | compile('1px solid #FFFFFF', { 25 | plugins: [colorPlugin({ format: 'rgb' })], 26 | }) 27 | ).toBe('1px solid rgb(255, 255, 255)') 28 | }) 29 | 30 | it('should normalize named colors to hex', () => { 31 | expect( 32 | compile('1px solid red', { 33 | plugins: [colorPlugin({ format: 'rgb' })], 34 | }) 35 | ).toBe('1px solid rgb(255, 0, 0)') 36 | }) 37 | }) 38 | -------------------------------------------------------------------------------- /packages/bredon-plugin-color/src/index.js: -------------------------------------------------------------------------------- 1 | /* @flow */ 2 | import color from 'color' 3 | 4 | const resolvers = { 5 | rgb: value => value.rgb().string(), 6 | hsl: value => value.hsl().string(), 7 | hex: value => value.hex(), 8 | } 9 | 10 | const COLOR_REGEX = /^(rgba?|hsla?)$/i 11 | 12 | export default function colorPlugin(config?: Object = {}): Object { 13 | const preserveAlpha = config.preserveAlpha || true 14 | const format = config.format || 'hex' 15 | 16 | return ({ generate, parse }) => ({ 17 | FunctionExpression({ node, replaceNode }) { 18 | if (node.callee.match(COLOR_REGEX) !== null) { 19 | const value = color(generate(node)) 20 | 21 | if (!(format === 'hex' && preserveAlpha && value.alpha() < 1)) { 22 | replaceNode(parse(resolvers[format](value))) 23 | } 24 | } 25 | }, 26 | HexColor({ node, replaceNode }) { 27 | const value = color(generate(node)) 28 | replaceNode(parse(resolvers[format](value))) 29 | }, 30 | Identifier({ node, replaceNode }) { 31 | // TODO: ugly 32 | try { 33 | const value = color(generate(node)) 34 | replaceNode(parse(resolvers[format](value))) 35 | } catch (e) {} 36 | }, 37 | }) 38 | } 39 | -------------------------------------------------------------------------------- /packages/bredon-plugin-color/yarn.lock: -------------------------------------------------------------------------------- 1 | # THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. 2 | # yarn lockfile v1 3 | 4 | 5 | color-convert@^1.9.1: 6 | version "1.9.1" 7 | resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.1.tgz#c1261107aeb2f294ebffec9ed9ecad529a6097ed" 8 | dependencies: 9 | color-name "^1.1.1" 10 | 11 | color-name@^1.0.0, color-name@^1.1.1: 12 | version "1.1.3" 13 | resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25" 14 | 15 | color-string@^1.5.2: 16 | version "1.5.2" 17 | resolved "https://registry.yarnpkg.com/color-string/-/color-string-1.5.2.tgz#26e45814bc3c9a7cbd6751648a41434514a773a9" 18 | dependencies: 19 | color-name "^1.0.0" 20 | simple-swizzle "^0.2.2" 21 | 22 | color@^2.0.0: 23 | version "2.0.1" 24 | resolved "https://registry.yarnpkg.com/color/-/color-2.0.1.tgz#e4ed78a3c4603d0891eba5430b04b86314f4c839" 25 | dependencies: 26 | color-convert "^1.9.1" 27 | color-string "^1.5.2" 28 | 29 | is-arrayish@^0.3.1: 30 | version "0.3.1" 31 | resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.3.1.tgz#c2dfc386abaa0c3e33c48db3fe87059e69065efd" 32 | 33 | simple-swizzle@^0.2.2: 34 | version "0.2.2" 35 | resolved "https://registry.yarnpkg.com/simple-swizzle/-/simple-swizzle-0.2.2.tgz#a4da6b635ffcccca33f70d17cb92592de95e557a" 36 | dependencies: 37 | is-arrayish "^0.3.1" 38 | -------------------------------------------------------------------------------- /packages/bredon-plugin-initial/README.md: -------------------------------------------------------------------------------- 1 | # bredon-plugin-initial 2 | 3 | npm version npm downloads 4 | 5 | The initial plugin replaces, normalizes and minifies initial values. 6 | In order to replace the `initial` keyword, the associated CSS property is required within `context`. 7 | 8 | ## Installation 9 | ```sh 10 | yarn add bredon-plugin-initial 11 | ``` 12 | You may alternatively use `npm i --save bredon-plugin-initial`. 13 | 14 | ## Usage 15 | 16 | ```javascript 17 | import { compile } from 'bredon' 18 | import initialPlugin from 'bredon-plugin-initial' 19 | 20 | const input = 'initial' 21 | 22 | const output = compile(input, { 23 | plugins: [ 24 | initialPlugin() 25 | ], 26 | context: { 27 | property: 'paddingLeft' 28 | } 29 | }) 30 | 31 | console.log(output) 32 | // => 0 33 | ``` 34 | 35 | ### Configuration 36 | By default the plugin replaces all `initial` keywords.
37 | Using the `useShorter`, it will the one that's shorter in length.
38 | It may also replace values with the `initial` keyword if `useShorter` is used. 39 | 40 | | Options | Value | Default | Description | 41 | | ------- | ----- | ------- | ----------- | 42 | | useShorter | *(boolean)* | `false` | If the shorter value should be used | 43 | 44 | ```javascript 45 | import { compile } from 'bredon' 46 | import colorPlugin from 'bredon-plugin-initial' 47 | 48 | const input = 'initial' 49 | 50 | const output = compile(input, { 51 | plugins: [ 52 | initialPlugin({ 53 | useShorter: true 54 | }) 55 | ], 56 | context: { 57 | property: 'overflowClipBox' 58 | } 59 | }) 60 | 61 | console.log(output) 62 | // => initial 63 | ``` 64 | 65 | ## License 66 | Bredon is licensed under the [MIT License](http://opensource.org/licenses/MIT).
67 | Documentation is licensed under [Creative Common License](http://creativecommons.org/licenses/by/4.0/).
68 | Created with ♥ by [@rofrischmann](http://rofrischmann.de) and all the great contributors. 69 | -------------------------------------------------------------------------------- /packages/bredon-plugin-initial/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "bredon-plugin-initial", 3 | "version": "1.0.0", 4 | "description": "Bredon plugin to transform initial values", 5 | "main": "lib/index.js", 6 | "module": "es/index.js", 7 | "jsnext:main": "es/index.js", 8 | "files": [ 9 | "LICENSE", 10 | "README.md", 11 | "lib/**", 12 | "es/**" 13 | ], 14 | "keywords": [ 15 | "css", 16 | "parser", 17 | "css-parser", 18 | "css-value-parser", 19 | "ast", 20 | "lexer", 21 | "tokenizer", 22 | "cssinjs", 23 | "bredon" 24 | ], 25 | "repository": "https://github.com/rofrischmann/bredon.git", 26 | "author": "Robin Frischmann ", 27 | "license": "MIT", 28 | "devDependencies": { 29 | "bredon": "^4.0.0" 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /packages/bredon-plugin-initial/src/__tests__/initial-test.js: -------------------------------------------------------------------------------- 1 | import { compile } from 'bredon' 2 | 3 | import initialPlugin from '../index' 4 | 5 | describe('Using inital plugin', () => { 6 | it('should replace the initial keyword with the acutal initial value', () => { 7 | expect( 8 | compile('initial', { 9 | plugins: [initialPlugin()], 10 | context: { property: 'paddingLeft' }, 11 | }) 12 | ).toBe('0') 13 | }) 14 | 15 | it('should only replace the initial keyword if the actual initial value is shorter', () => { 16 | expect( 17 | compile('initial', { 18 | plugins: [ 19 | initialPlugin({ 20 | useShorter: true, 21 | }), 22 | ], 23 | context: { property: 'overflowClipBox' }, 24 | }) 25 | ).toBe('initial') 26 | }) 27 | 28 | it('should replace any initial value with the initial keyword if its shorter', () => { 29 | expect( 30 | compile('padding-box', { 31 | plugins: [ 32 | initialPlugin({ 33 | useShorter: true, 34 | }), 35 | ], 36 | context: { property: 'overflowClipBox' }, 37 | }) 38 | ).toBe('initial') 39 | }) 40 | }) 41 | -------------------------------------------------------------------------------- /packages/bredon-plugin-initial/src/index.js: -------------------------------------------------------------------------------- 1 | /* @flow */ 2 | import valueInitials from './valueInitials' 3 | 4 | const INITIAL = 'initial' 5 | 6 | export default function initialPlugin(config?: Object = {}): Object { 7 | const useShorter = config.useShorter || false 8 | 9 | return ({ generate, parse, types }) => ({ 10 | Identifier({ node, context, replaceNode }) { 11 | if (node.value === INITIAL) { 12 | const initialValue = valueInitials[context.property] 13 | 14 | if ( 15 | initialValue && 16 | (!useShorter || initialValue.length < INITIAL.length) 17 | ) { 18 | replaceNode(parse(initialValue)) 19 | } 20 | } 21 | }, 22 | Value({ node, context, replaceNode }) { 23 | if (useShorter) { 24 | const initialValue = valueInitials[context.property] 25 | 26 | if ( 27 | initialValue && 28 | initialValue === generate(node) && 29 | initialValue.length > INITIAL.length 30 | ) { 31 | replaceNode(types.identifier(INITIAL)) 32 | } 33 | } 34 | }, 35 | }) 36 | } 37 | -------------------------------------------------------------------------------- /packages/bredon-plugin-initial/src/valueInitials.js: -------------------------------------------------------------------------------- 1 | export default { 2 | msOverflowStyle: 'auto', 3 | MozBinding: 'none', 4 | MozBorderBottomColors: 'none', 5 | MozBorderLeftColors: 'none', 6 | MozBorderRightColors: 'none', 7 | MozBorderTopColors: 'none', 8 | MozContextProperties: 'none', 9 | MozFloatEdge: 'content-box', 10 | MozForceBrokenImageIcon: '0', 11 | MozImageRegion: 'auto', 12 | MozOrient: 'inline', 13 | MozOutlineRadiusBottomleft: '0', 14 | MozOutlineRadiusBottomright: '0', 15 | MozOutlineRadiusTopleft: '0', 16 | MozOutlineRadiusTopright: '0', 17 | MozStackSizing: 'stretch-to-fit', 18 | MozTextBlink: 'none', 19 | MozUserFocus: 'none', 20 | MozUserInput: 'auto', 21 | MozUserModify: 'read-only', 22 | MozWindowDragging: 'drag', 23 | MozWindowShadow: 'default', 24 | WebkitBorderBeforeColor: 'currentcolor', 25 | WebkitBorderBeforeStyle: 'none', 26 | WebkitBorderBeforeWidth: 'medium', 27 | WebkitBoxReflect: 'none', 28 | WebkitMaskAttachment: 'scroll', 29 | WebkitMaskClip: 'border', 30 | WebkitMaskComposite: 'source-over', 31 | WebkitMaskImage: 'none', 32 | WebkitMaskOrigin: 'padding', 33 | WebkitMaskPosition: '0% 0%', 34 | WebkitMaskPositionX: '0%', 35 | WebkitMaskPositionY: '0%', 36 | WebkitMaskRepeat: 'repeat', 37 | WebkitMaskRepeatX: 'repeat', 38 | WebkitMaskRepeatY: 'repeat', 39 | WebkitOverflowScrolling: 'auto', 40 | WebkitTapHighlightColor: 'black', 41 | WebkitTextFillColor: 'currentcolor', 42 | WebkitTextStrokeColor: 'currentcolor', 43 | WebkitTextStrokeWidth: '0', 44 | WebkitTouchCallout: 'default', 45 | alignContent: 'stretch', 46 | alignItems: 'stretch', 47 | alignSelf: 'auto', 48 | animationDelay: '0', 49 | animationDirection: 'normal', 50 | animationDuration: '0', 51 | animationFillMode: 'none', 52 | animationIterationCount: '1', 53 | animationName: 'none', 54 | animationPlayState: 'running', 55 | animationTimingFunction: 'ease', 56 | appearance: 'auto', 57 | azimuth: 'center', 58 | backdropFilter: 'none', 59 | backfaceVisibility: 'visible', 60 | backgroundAttachment: 'scroll', 61 | backgroundBlendMode: 'normal', 62 | backgroundClip: 'border-box', 63 | backgroundColor: 'transparent', 64 | backgroundImage: 'none', 65 | backgroundOrigin: 'padding-box', 66 | backgroundPosition: '0% 0%', 67 | backgroundPositionX: 'left', 68 | backgroundPositionY: 'top', 69 | backgroundRepeat: 'repeat', 70 | backgroundSize: 'auto auto', 71 | blockSize: 'auto', 72 | borderBlockEndColor: 'currentcolor', 73 | borderBlockEndStyle: 'none', 74 | borderBlockEndWidth: 'medium', 75 | borderBlockStartColor: 'currentcolor', 76 | borderBlockStartStyle: 'none', 77 | borderBlockStartWidth: 'medium', 78 | borderBottomColor: 'currentcolor', 79 | borderBottomLeftRadius: '0', 80 | borderBottomRightRadius: '0', 81 | borderBottomStyle: 'none', 82 | borderBottomWidth: 'medium', 83 | borderCollapse: 'separate', 84 | borderImageOutset: '0', 85 | borderImageRepeat: 'stretch', 86 | borderImageSlice: '100%', 87 | borderImageSource: 'none', 88 | borderImageWidth: '1', 89 | borderInlineEndColor: 'currentcolor', 90 | borderInlineEndStyle: 'none', 91 | borderInlineEndWidth: 'medium', 92 | borderInlineStartColor: 'currentcolor', 93 | borderInlineStartStyle: 'none', 94 | borderInlineStartWidth: 'medium', 95 | borderLeftColor: 'currentcolor', 96 | borderLeftStyle: 'none', 97 | borderLeftWidth: 'medium', 98 | borderRightColor: 'currentcolor', 99 | borderRightStyle: 'none', 100 | borderRightWidth: 'medium', 101 | borderSpacing: '0', 102 | borderTopColor: 'currentcolor', 103 | borderTopLeftRadius: '0', 104 | borderTopRightRadius: '0', 105 | borderTopStyle: 'none', 106 | borderTopWidth: 'medium', 107 | bottom: 'auto', 108 | boxAlign: 'stretch', 109 | boxDecorationBreak: 'slice', 110 | boxDirection: 'normal', 111 | boxFlex: '0', 112 | boxFlexGroup: '1', 113 | boxLines: 'single', 114 | boxOrdinalGroup: '1', 115 | boxPack: 'start', 116 | boxShadow: 'none', 117 | boxSizing: 'content-box', 118 | breakAfter: 'auto', 119 | breakBefore: 'auto', 120 | breakInside: 'auto', 121 | captionSide: 'top', 122 | caretColor: 'auto', 123 | clear: 'none', 124 | clip: 'auto', 125 | clipPath: 'none', 126 | columnCount: 'auto', 127 | columnFill: 'balance', 128 | columnGap: 'normal', 129 | columnRuleColor: 'currentcolor', 130 | columnRuleStyle: 'none', 131 | columnRuleWidth: 'medium', 132 | columnSpan: 'none', 133 | columnWidth: 'auto', 134 | contain: 'none', 135 | content: 'normal', 136 | counterIncrement: 'none', 137 | counterReset: 'none', 138 | cursor: 'auto', 139 | direction: 'ltr', 140 | display: 'inline', 141 | displayInside: 'auto', 142 | displayList: 'none', 143 | displayOutside: 'inline-level', 144 | emptyCells: 'show', 145 | filter: 'none', 146 | flexBasis: 'auto', 147 | flexDirection: 'row', 148 | flexGrow: '0', 149 | flexShrink: '1', 150 | flexWrap: 'nowrap', 151 | float: 'none', 152 | fontFeatureSettings: 'normal', 153 | fontKerning: 'auto', 154 | fontLanguageOverride: 'normal', 155 | fontVariationSettings: 'normal', 156 | fontSize: 'medium', 157 | fontSizeAdjust: 'none', 158 | fontStretch: 'normal', 159 | fontStyle: 'normal', 160 | fontSynthesis: 'weight style', 161 | fontVariant: 'normal', 162 | fontVariantAlternates: 'normal', 163 | fontVariantCaps: 'normal', 164 | fontVariantEastAsian: 'normal', 165 | fontVariantLigatures: 'normal', 166 | fontVariantNumeric: 'normal', 167 | fontVariantPosition: 'normal', 168 | fontWeight: 'normal', 169 | gridAutoColumns: 'auto', 170 | gridAutoFlow: 'row', 171 | gridAutoRows: 'auto', 172 | gridColumnEnd: 'auto', 173 | gridColumnGap: '0', 174 | gridColumnStart: 'auto', 175 | gridRowEnd: 'auto', 176 | gridRowGap: '0', 177 | gridRowStart: 'auto', 178 | gridTemplateAreas: 'none', 179 | gridTemplateColumns: 'none', 180 | gridTemplateRows: 'none', 181 | hangingPunctuation: 'none', 182 | height: 'auto', 183 | hyphens: 'manual', 184 | imageOrientation: '0deg', 185 | imageRendering: 'auto', 186 | imageResolution: '1dppx', 187 | imeMode: 'auto', 188 | initialLetter: 'normal', 189 | initialLetterAlign: 'auto', 190 | inlineSize: 'auto', 191 | isolation: 'auto', 192 | justifyContent: 'flex-start', 193 | left: 'auto', 194 | letterSpacing: 'normal', 195 | lineBreak: 'auto', 196 | lineHeight: 'normal', 197 | lineHeightStep: 'none', 198 | listStyleImage: 'none', 199 | listStylePosition: 'outside', 200 | listStyleType: 'disc', 201 | marginBlockEnd: '0', 202 | marginBlockStart: '0', 203 | marginBottom: '0', 204 | marginInlineEnd: '0', 205 | marginInlineStart: '0', 206 | marginLeft: '0', 207 | marginRight: '0', 208 | marginTop: '0', 209 | maskBorderMode: 'alpha', 210 | maskBorderOutset: '0', 211 | maskBorderRepeat: 'stretch', 212 | maskBorderSlice: '0', 213 | maskBorderSource: 'none', 214 | maskBorderWidth: 'auto', 215 | maskClip: 'border-box', 216 | maskComposite: 'add', 217 | maskImage: 'none', 218 | maskMode: 'match-source', 219 | maskOrigin: 'border-box', 220 | maskPosition: 'center', 221 | maskRepeat: 'no-repeat', 222 | maskSize: 'auto', 223 | maskType: 'luminance', 224 | maxBlockSize: '0', 225 | maxHeight: 'none', 226 | maxInlineSize: '0', 227 | maxWidth: 'none', 228 | minBlockSize: '0', 229 | minHeight: '0', 230 | minInlineSize: '0', 231 | minWidth: '0', 232 | mixBlendMode: 'normal', 233 | objectFit: 'fill', 234 | objectPosition: '50% 50%', 235 | offsetAnchor: 'auto', 236 | offsetBlockEnd: 'auto', 237 | offsetBlockStart: 'auto', 238 | offsetInlineEnd: 'auto', 239 | offsetInlineStart: 'auto', 240 | offsetDistance: '0', 241 | offsetPath: 'none', 242 | offsetPosition: 'auto', 243 | offsetRotate: 'auto', 244 | opacity: '1.0', 245 | order: '0', 246 | orphans: '2', 247 | outlineOffset: '0', 248 | outlineStyle: 'none', 249 | outlineWidth: 'medium', 250 | overflow: 'visible', 251 | overflowClipBox: 'padding-box', 252 | overflowWrap: 'normal', 253 | overflowX: 'visible', 254 | overflowY: 'visible', 255 | paddingBlockEnd: '0', 256 | paddingBlockStart: '0', 257 | paddingBottom: '0', 258 | paddingInlineEnd: '0', 259 | paddingInlineStart: '0', 260 | paddingLeft: '0', 261 | paddingRight: '0', 262 | paddingTop: '0', 263 | pageBreakAfter: 'auto', 264 | pageBreakBefore: 'auto', 265 | pageBreakInside: 'auto', 266 | perspective: 'none', 267 | perspectiveOrigin: '50% 50%', 268 | pointerEvents: 'auto', 269 | position: 'static', 270 | resize: 'none', 271 | right: 'auto', 272 | rubyAlign: 'space-around', 273 | rubyMerge: 'separate', 274 | rubyPosition: 'over', 275 | scrollBehavior: 'auto', 276 | scrollSnapCoordinate: 'none', 277 | scrollSnapDestination: '0px 0px', 278 | scrollSnapPointsX: 'none', 279 | scrollSnapPointsY: 'none', 280 | scrollSnapType: 'none', 281 | scrollSnapTypeX: 'none', 282 | scrollSnapTypeY: 'none', 283 | shapeImageThreshold: '0.0', 284 | shapeMargin: '0', 285 | shapeOutside: 'none', 286 | tabSize: '8', 287 | tableLayout: 'auto', 288 | textAlignLast: 'auto', 289 | textCombineUpright: 'none', 290 | textDecorationColor: 'currentcolor', 291 | textDecorationLine: 'none', 292 | textDecorationSkip: 'objects', 293 | textDecorationStyle: 'solid', 294 | textEmphasisColor: 'currentcolor', 295 | textEmphasisPosition: 'over right', 296 | textEmphasisStyle: 'none', 297 | textIndent: '0', 298 | textJustify: 'auto', 299 | textOrientation: 'mixed', 300 | textOverflow: 'clip', 301 | textRendering: 'auto', 302 | textShadow: 'none', 303 | textTransform: 'none', 304 | textUnderlinePosition: 'auto', 305 | top: 'auto', 306 | touchAction: 'auto', 307 | transform: 'none', 308 | transformBox: 'border-box', 309 | transformOrigin: '50% 50% 0', 310 | transformStyle: 'flat', 311 | transitionDelay: '0', 312 | transitionDuration: '0', 313 | transitionProperty: 'all', 314 | transitionTimingFunction: 'ease', 315 | unicodeBidi: 'normal', 316 | userSelect: 'auto', 317 | verticalAlign: 'baseline', 318 | visibility: 'visible', 319 | whiteSpace: 'normal', 320 | widows: '2', 321 | width: 'auto', 322 | willChange: 'auto', 323 | wordBreak: 'normal', 324 | wordSpacing: 'normal', 325 | wordWrap: 'normal', 326 | writingMode: 'horizontal-tb', 327 | zIndex: 'auto', 328 | } 329 | -------------------------------------------------------------------------------- /packages/bredon-plugin-precision/README.md: -------------------------------------------------------------------------------- 1 | # bredon-plugin-precision 2 | 3 | npm version npm downloads 4 | 5 | The precision plugin normalizes decimal number precision.
6 | It will automatically round up values. 7 | 8 | ## Installation 9 | ```sh 10 | yarn add bredon-plugin-precision 11 | ``` 12 | You may alternatively use `npm i --save bredon-plugin-precision`. 13 | 14 | ## Usage 15 | 16 | ```javascript 17 | import { compile } from 'bredon' 18 | import precisionPlugin from 'bredon-plugin-precision' 19 | 20 | const input = '33.3333333% solid rgba(10, 10, 10, 0.564)' 21 | 22 | const output = compile(input, { 23 | plugins: [ 24 | precisionPlugin() 25 | ] 26 | }) 27 | 28 | console.log(output) 29 | // => 33.3333% solid rgba(10, 10, 10, 0.564) 30 | ``` 31 | 32 | ### Configuration 33 | By default, the precision is set to `4`. 34 | 35 | | Options | Value | Default | Description | 36 | | ------- | ----- | ------- | ----------- | 37 | | precision | *number* | 4 | The prefered precision | 38 | 39 | ```javascript 40 | import { compile } from 'bredon' 41 | import precisionPlugin from 'bredon-plugin-precision' 42 | 43 | const input = '33.3333333% solid rgba(10, 10, 10, 0.564)' 44 | 45 | const output = compile(input, { 46 | plugins: [ 47 | precisionPlugin({ 48 | precision: 2 49 | }) 50 | ] 51 | }) 52 | 53 | console.log(output) 54 | // => 33.3% solid rgba(10, 10, 10, 0.56) 55 | ``` 56 | 57 | ## License 58 | Bredon is licensed under the [MIT License](http://opensource.org/licenses/MIT).
59 | Documentation is licensed under [Creative Common License](http://creativecommons.org/licenses/by/4.0/).
60 | Created with ♥ by [@rofrischmann](http://rofrischmann.de) and all the great contributors. 61 | -------------------------------------------------------------------------------- /packages/bredon-plugin-precision/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "bredon-plugin-precision", 3 | "version": "1.0.0", 4 | "description": "Bredon plugin to normalize floating-point precision", 5 | "main": "lib/index.js", 6 | "module": "es/index.js", 7 | "jsnext:main": "es/index.js", 8 | "files": [ 9 | "LICENSE", 10 | "README.md", 11 | "lib/**", 12 | "es/**" 13 | ], 14 | "keywords": [ 15 | "css", 16 | "parser", 17 | "css-parser", 18 | "css-value-parser", 19 | "ast", 20 | "lexer", 21 | "tokenizer", 22 | "cssinjs", 23 | "bredon" 24 | ], 25 | "repository": "https://github.com/rofrischmann/bredon.git", 26 | "author": "Robin Frischmann ", 27 | "license": "MIT", 28 | "devDependencies": { 29 | "bredon": "^4.0.0" 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /packages/bredon-plugin-precision/src/__tests__/precision-test.js: -------------------------------------------------------------------------------- 1 | import { compile } from 'bredon' 2 | 3 | import precisionPlugin from '../index' 4 | 5 | describe('Using the precision plugin', () => { 6 | it('should reduce precision', () => { 7 | expect( 8 | compile('2.123456', { 9 | plugins: [precisionPlugin()], 10 | }) 11 | ).toBe('2.1235') 12 | }) 13 | 14 | it('should reduce precision using a custom precision', () => { 15 | expect( 16 | compile('2.123456', { 17 | plugins: [ 18 | precisionPlugin({ 19 | precision: 2, 20 | }), 21 | ], 22 | }) 23 | ).toBe('2.12') 24 | }) 25 | 26 | it('should keep low precision', () => { 27 | expect( 28 | compile('2.1', { 29 | plugins: [precisionPlugin()], 30 | }) 31 | ).toBe('2.1') 32 | }) 33 | }) 34 | -------------------------------------------------------------------------------- /packages/bredon-plugin-precision/src/index.js: -------------------------------------------------------------------------------- 1 | /* @flow */ 2 | function reducePrecision(value: number, precision: number): number { 3 | const precisionFactor = Math.pow(10, precision) 4 | 5 | return Math.round(value * precisionFactor) / precisionFactor 6 | } 7 | 8 | export default function precisionPlugin(config?: Object = {}): Object { 9 | const precision = config.precision || 4 10 | 11 | return { 12 | Float({ node, replaceNode }) { 13 | node.fractional = reducePrecision(node.fractional, precision) 14 | }, 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /packages/bredon-plugin-precision/yarn.lock: -------------------------------------------------------------------------------- 1 | # THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. 2 | # yarn lockfile v1 3 | 4 | 5 | color-convert@^1.9.1: 6 | version "1.9.1" 7 | resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.1.tgz#c1261107aeb2f294ebffec9ed9ecad529a6097ed" 8 | dependencies: 9 | color-name "^1.1.1" 10 | 11 | color-name@^1.0.0, color-name@^1.1.1: 12 | version "1.1.3" 13 | resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25" 14 | 15 | color-string@^1.5.2: 16 | version "1.5.2" 17 | resolved "https://registry.yarnpkg.com/color-string/-/color-string-1.5.2.tgz#26e45814bc3c9a7cbd6751648a41434514a773a9" 18 | dependencies: 19 | color-name "^1.0.0" 20 | simple-swizzle "^0.2.2" 21 | 22 | color@^2.0.0: 23 | version "2.0.1" 24 | resolved "https://registry.yarnpkg.com/color/-/color-2.0.1.tgz#e4ed78a3c4603d0891eba5430b04b86314f4c839" 25 | dependencies: 26 | color-convert "^1.9.1" 27 | color-string "^1.5.2" 28 | 29 | is-arrayish@^0.3.1: 30 | version "0.3.1" 31 | resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.3.1.tgz#c2dfc386abaa0c3e33c48db3fe87059e69065efd" 32 | 33 | simple-swizzle@^0.2.2: 34 | version "0.2.2" 35 | resolved "https://registry.yarnpkg.com/simple-swizzle/-/simple-swizzle-0.2.2.tgz#a4da6b635ffcccca33f70d17cb92592de95e557a" 36 | dependencies: 37 | is-arrayish "^0.3.1" 38 | -------------------------------------------------------------------------------- /packages/bredon-plugin-remove-unit/README.md: -------------------------------------------------------------------------------- 1 | # bredon-plugin-remove-unit 2 | 3 | npm version npm downloads 4 | 5 | The remove-unit plugin will remove unnecessary units from dimensions.
6 | It works for all units, not only pixel or length units. 7 | 8 | ## Installation 9 | ```sh 10 | yarn add bredon-plugin-remove-unit 11 | ``` 12 | You may alternatively use `npm i --save bredon-plugin-remove-unit`. 13 | 14 | ## Usage 15 | 16 | ```javascript 17 | import { compile } from 'bredon' 18 | import removeUnitPlugin from 'bredon-plugin-remove-unit' 19 | 20 | const input = '15px 0px 5px 0px' 21 | 22 | const output = compile(input, { 23 | plugins: [ 24 | removeUnitPlugin() 25 | ] 26 | }) 27 | 28 | console.log(output) 29 | // => 15px 0 5px 0 30 | ``` 31 | 32 | ## License 33 | Bredon is licensed under the [MIT License](http://opensource.org/licenses/MIT).
34 | Documentation is licensed under [Creative Common License](http://creativecommons.org/licenses/by/4.0/).
35 | Created with ♥ by [@rofrischmann](http://rofrischmann.de) and all the great contributors. 36 | -------------------------------------------------------------------------------- /packages/bredon-plugin-remove-unit/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "bredon-plugin-remove-unit", 3 | "version": "1.0.0", 4 | "description": "Bredon plugin to remove unnecessary units from values", 5 | "main": "lib/index.js", 6 | "module": "es/index.js", 7 | "jsnext:main": "es/index.js", 8 | "files": [ 9 | "LICENSE", 10 | "README.md", 11 | "lib/**", 12 | "es/**" 13 | ], 14 | "keywords": [ 15 | "css", 16 | "parser", 17 | "css-parser", 18 | "css-value-parser", 19 | "ast", 20 | "lexer", 21 | "tokenizer", 22 | "cssinjs", 23 | "bredon" 24 | ], 25 | "repository": "https://github.com/rofrischmann/bredon.git", 26 | "author": "Robin Frischmann ", 27 | "license": "MIT", 28 | "devDependencies": { 29 | "bredon": "^4.0.0" 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /packages/bredon-plugin-remove-unit/src/__tests__/removeUnit-test.js: -------------------------------------------------------------------------------- 1 | import { compile } from 'bredon' 2 | 3 | import removeUnitPlugin from '../index' 4 | 5 | describe('Using the remove-unit plugin', () => { 6 | it('should remove unnecessary units from values', () => { 7 | expect( 8 | compile('0px', { 9 | plugins: [removeUnitPlugin()], 10 | }) 11 | ).toBe('0') 12 | 13 | expect( 14 | compile('15px 0px 2px 0px', { 15 | plugins: [removeUnitPlugin()], 16 | }) 17 | ).toBe('15px 0 2px 0') 18 | }) 19 | }) 20 | -------------------------------------------------------------------------------- /packages/bredon-plugin-remove-unit/src/index.js: -------------------------------------------------------------------------------- 1 | /* @flow */ 2 | export default function removeUnitPlugin(): Object { 3 | return ({ types }) => { 4 | function isZero(node) { 5 | return ( 6 | (types.isInteger(node.value) && node.value.value === 0) || 7 | (types.isFloat(node.value) && 8 | node.value.integer === 0 && 9 | node.value.fractional === 0) 10 | ) 11 | } 12 | 13 | return { 14 | Dimension({ node, replaceNode }) { 15 | if (isZero(node)) { 16 | replaceNode(types.integer(0)) 17 | } 18 | }, 19 | } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /packages/bredon-plugin-remove-unit/yarn.lock: -------------------------------------------------------------------------------- 1 | # THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. 2 | # yarn lockfile v1 3 | 4 | 5 | color-convert@^1.9.1: 6 | version "1.9.1" 7 | resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.1.tgz#c1261107aeb2f294ebffec9ed9ecad529a6097ed" 8 | dependencies: 9 | color-name "^1.1.1" 10 | 11 | color-name@^1.0.0, color-name@^1.1.1: 12 | version "1.1.3" 13 | resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25" 14 | 15 | color-string@^1.5.2: 16 | version "1.5.2" 17 | resolved "https://registry.yarnpkg.com/color-string/-/color-string-1.5.2.tgz#26e45814bc3c9a7cbd6751648a41434514a773a9" 18 | dependencies: 19 | color-name "^1.0.0" 20 | simple-swizzle "^0.2.2" 21 | 22 | color@^2.0.0: 23 | version "2.0.1" 24 | resolved "https://registry.yarnpkg.com/color/-/color-2.0.1.tgz#e4ed78a3c4603d0891eba5430b04b86314f4c839" 25 | dependencies: 26 | color-convert "^1.9.1" 27 | color-string "^1.5.2" 28 | 29 | is-arrayish@^0.3.1: 30 | version "0.3.1" 31 | resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.3.1.tgz#c2dfc386abaa0c3e33c48db3fe87059e69065efd" 32 | 33 | simple-swizzle@^0.2.2: 34 | version "0.2.2" 35 | resolved "https://registry.yarnpkg.com/simple-swizzle/-/simple-swizzle-0.2.2.tgz#a4da6b635ffcccca33f70d17cb92592de95e557a" 36 | dependencies: 37 | is-arrayish "^0.3.1" 38 | -------------------------------------------------------------------------------- /packages/bredon-plugin-trim-hex/README.md: -------------------------------------------------------------------------------- 1 | # bredon-plugin-trim-hex 2 | 3 | npm version npm downloads 4 | 5 | The trim-hex plugin will minify hex color values if possible. 6 | 7 | ## Installation 8 | ```sh 9 | yarn add bredon-plugin-trim-hex 10 | ``` 11 | You may alternatively use `npm i --save bredon-plugin-trim-hex`. 12 | 13 | ## Usage 14 | 15 | ```javascript 16 | import { compile } from 'bredon' 17 | import trimHexPlugin from 'bredon-plugin-trim-hex' 18 | 19 | const input = '#FFFFFF #FAFAFA' 20 | 21 | const output = compile(input, { 22 | plugins: [ 23 | trimHexPlugin() 24 | ] 25 | }) 26 | 27 | console.log(output) 28 | // => #FFF #FAFAFA 29 | ``` 30 | 31 | ## License 32 | Bredon is licensed under the [MIT License](http://opensource.org/licenses/MIT).
33 | Documentation is licensed under [Creative Common License](http://creativecommons.org/licenses/by/4.0/).
34 | Created with ♥ by [@rofrischmann](http://rofrischmann.de) and all the great contributors. 35 | -------------------------------------------------------------------------------- /packages/bredon-plugin-trim-hex/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "bredon-plugin-trim-hex", 3 | "version": "1.0.0", 4 | "description": "Bredon plugin to trim hex values", 5 | "main": "lib/index.js", 6 | "module": "es/index.js", 7 | "jsnext:main": "es/index.js", 8 | "files": [ 9 | "LICENSE", 10 | "README.md", 11 | "lib/**", 12 | "es/**" 13 | ], 14 | "keywords": [ 15 | "css", 16 | "parser", 17 | "css-parser", 18 | "css-value-parser", 19 | "ast", 20 | "lexer", 21 | "tokenizer", 22 | "cssinjs", 23 | "bredon" 24 | ], 25 | "repository": "https://github.com/rofrischmann/bredon.git", 26 | "author": "Robin Frischmann ", 27 | "license": "MIT", 28 | "devDependencies": { 29 | "bredon": "^4.0.0" 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /packages/bredon-plugin-trim-hex/src/__tests__/trimHex-test.js: -------------------------------------------------------------------------------- 1 | import { compile } from 'bredon' 2 | 3 | import trimHexPlugin from '../index' 4 | 5 | describe('Using the trim-hex plugin', () => { 6 | it('should trim hex values', () => { 7 | expect( 8 | compile('#FFFFFF', { 9 | plugins: [trimHexPlugin()], 10 | }) 11 | ).toBe('#FFF') 12 | }) 13 | 14 | it('should not trim hex values', () => { 15 | expect( 16 | compile('#FGFGFG', { 17 | plugins: [trimHexPlugin()], 18 | }) 19 | ).toBe('#FGFGFG') 20 | }) 21 | }) 22 | -------------------------------------------------------------------------------- /packages/bredon-plugin-trim-hex/src/index.js: -------------------------------------------------------------------------------- 1 | /* @flow */ 2 | export default function trimHexPlugin(): Object { 3 | return { 4 | HexColor({ node }) { 5 | const trimedValue = node.value.substr(0, 3) 6 | 7 | if (trimedValue === node.value.substr(3, 6)) { 8 | node.value = trimedValue 9 | } 10 | }, 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /packages/bredon-plugin-trim-hex/yarn.lock: -------------------------------------------------------------------------------- 1 | # THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. 2 | # yarn lockfile v1 3 | 4 | 5 | color-convert@^1.9.1: 6 | version "1.9.1" 7 | resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.1.tgz#c1261107aeb2f294ebffec9ed9ecad529a6097ed" 8 | dependencies: 9 | color-name "^1.1.1" 10 | 11 | color-name@^1.0.0, color-name@^1.1.1: 12 | version "1.1.3" 13 | resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25" 14 | 15 | color-string@^1.5.2: 16 | version "1.5.2" 17 | resolved "https://registry.yarnpkg.com/color-string/-/color-string-1.5.2.tgz#26e45814bc3c9a7cbd6751648a41434514a773a9" 18 | dependencies: 19 | color-name "^1.0.0" 20 | simple-swizzle "^0.2.2" 21 | 22 | color@^2.0.0: 23 | version "2.0.1" 24 | resolved "https://registry.yarnpkg.com/color/-/color-2.0.1.tgz#e4ed78a3c4603d0891eba5430b04b86314f4c839" 25 | dependencies: 26 | color-convert "^1.9.1" 27 | color-string "^1.5.2" 28 | 29 | is-arrayish@^0.3.1: 30 | version "0.3.1" 31 | resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.3.1.tgz#c2dfc386abaa0c3e33c48db3fe87059e69065efd" 32 | 33 | simple-swizzle@^0.2.2: 34 | version "0.2.2" 35 | resolved "https://registry.yarnpkg.com/simple-swizzle/-/simple-swizzle-0.2.2.tgz#a4da6b635ffcccca33f70d17cb92592de95e557a" 36 | dependencies: 37 | is-arrayish "^0.3.1" 38 | -------------------------------------------------------------------------------- /packages/bredon-plugin-unit/README.md: -------------------------------------------------------------------------------- 1 | # bredon-plugin-unit 2 | 3 | npm version npm downloads 4 | 5 | The unit plugin will convert, normalize and minify unit values. 6 | 7 | ## Installation 8 | ```sh 9 | yarn add bredon-plugin-unit 10 | ``` 11 | You may alternatively use `npm i --save bredon-plugin-unit`. 12 | 13 | ## Usage 14 | 15 | ```javascript 16 | import { compile } from 'bredon' 17 | import unitPlugin from 'bredon-plugin-unit' 18 | 19 | const input = '12pt 0.25turn 3s 15px 2.53cm' 20 | 21 | const output = compile(input, { 22 | plugins: [ 23 | unitPlugin() 24 | ] 25 | }) 26 | 27 | console.log(output) 28 | // => 16px 90deg 3000ms 15px 95.622px 29 | ``` 30 | 31 | ### Configuration 32 | By default the output precision is `4`.
33 | The default unit formats are: 34 | 35 | * length: `px` 36 | * time: `ms` 37 | * angle: `deg` 38 | 39 | | Options | Value | Default | Description | 40 | | ------- | ----- | ------- | ----------- | 41 | | precision | *number* | 4 | The prefered precision | 42 | | formats | *Object* | `{ length: 'px', time: 'ms', angle: 'deg' }` | The prefered unit formats | 43 | 44 | ```javascript 45 | import { compile } from 'bredon' 46 | import unitPlugin from 'bredon-plugin-unit' 47 | 48 | const input = '12pt 0.25turn 3s 15px 2.53cm' 49 | 50 | const output = compile(input, { 51 | plugins: [ 52 | unitPlugin({ 53 | precision: 2, 54 | formats: { 55 | length: 'mm', 56 | angle: 'grad', 57 | time: 's', 58 | } 59 | }) 60 | ] 61 | }) 62 | 63 | console.log(output) 64 | // => 4.23mm 100grad 3s 3.97mm 25.3mm 65 | ``` 66 | 67 | ## License 68 | Bredon is licensed under the [MIT License](http://opensource.org/licenses/MIT).
69 | Documentation is licensed under [Creative Common License](http://creativecommons.org/licenses/by/4.0/).
70 | Created with ♥ by [@rofrischmann](http://rofrischmann.de) and all the great contributors. 71 | -------------------------------------------------------------------------------- /packages/bredon-plugin-unit/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "bredon-plugin-unit", 3 | "version": "1.0.0", 4 | "description": "Bredon plugin to manipulate units", 5 | "main": "lib/index.js", 6 | "module": "es/index.js", 7 | "jsnext:main": "es/index.js", 8 | "files": [ 9 | "LICENSE", 10 | "README.md", 11 | "lib/**", 12 | "es/**" 13 | ], 14 | "keywords": [ 15 | "css", 16 | "parser", 17 | "css-parser", 18 | "css-value-parser", 19 | "ast", 20 | "lexer", 21 | "tokenizer", 22 | "cssinjs", 23 | "bredon" 24 | ], 25 | "repository": "https://github.com/rofrischmann/bredon.git", 26 | "author": "Robin Frischmann ", 27 | "license": "MIT", 28 | "devDependencies": { 29 | "bredon": "^4.0.0" 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /packages/bredon-plugin-unit/src/__tests__/unit-test.js: -------------------------------------------------------------------------------- 1 | import { compile } from 'bredon' 2 | 3 | import unitPlugin from '../index' 4 | 5 | describe('Using the unit plugin', () => { 6 | it('should normalize units', () => { 7 | expect( 8 | compile('12pt 0.25turn 3s 15px 2.53cm', { 9 | plugins: [unitPlugin()], 10 | }) 11 | ).toBe('16px 90deg 3000ms 15px 95.622px') 12 | }) 13 | 14 | it('should normalize units with custom format and precision', () => { 15 | expect( 16 | compile('12pt 0.25turn 3s 15px 2.53cm', { 17 | plugins: [ 18 | unitPlugin({ 19 | formats: { 20 | length: 'mm', 21 | angle: 'grad', 22 | time: 's', 23 | }, 24 | precision: 2, 25 | }), 26 | ], 27 | }) 28 | ).toBe('4.23mm 100grad 3s 3.97mm 25.3mm') 29 | }) 30 | }) 31 | -------------------------------------------------------------------------------- /packages/bredon-plugin-unit/src/index.js: -------------------------------------------------------------------------------- 1 | /* @flow */ 2 | const defaultFormats = { 3 | length: 'px', 4 | time: 'ms', 5 | angle: 'deg', 6 | } 7 | 8 | const groups = { 9 | length: /^(px|in|pt|pc|cm|mm|q)$/i, 10 | time: /^((m)?s)$/i, 11 | angle: /^(deg|rad|grad|turn)$/i, 12 | } 13 | 14 | const convertion = { 15 | // length 16 | px: 1, 17 | in: 0.01041666667, 18 | pt: 0.75, 19 | pc: 0.0625, 20 | cm: 0.02645833305, 21 | mm: 0.2645833305, 22 | q: 0.06614583262, 23 | // angle 24 | deg: 1, 25 | rad: 0.01745329252, 26 | grad: 1.1111111111, 27 | turn: 0.002777777778, 28 | // time 29 | ms: 1, 30 | s: 0.001, 31 | } 32 | 33 | type Unit = 34 | | 'px' 35 | | 'in' 36 | | 'pt' 37 | | 'pc' 38 | | 'cm' 39 | | 'mm' 40 | | 'q' 41 | | 'deg' 42 | | 'rad' 43 | | 'grad' 44 | | 'turn' 45 | | 'ms' 46 | | 's' 47 | 48 | function normalize(value: number, unit: Unit): number { 49 | return value / convertion[unit] 50 | } 51 | 52 | function convert( 53 | value: number, 54 | from: Unit, 55 | to: Unit, 56 | precision?: number = 6 57 | ): number { 58 | const precisionFactor = Math.pow(10, precision) 59 | 60 | return ( 61 | Math.round(normalize(value, from) * convertion[to] * precisionFactor) / 62 | precisionFactor 63 | ) 64 | } 65 | 66 | function getGroup(unit: Unit): ?string { 67 | return Object.keys(groups).find(group => unit.match(groups[group]) !== null) 68 | } 69 | 70 | function isFloat(value: number): boolean { 71 | return value === +value && value !== (value | 0) 72 | } 73 | 74 | export default function unitPlugin(config?: Object = {}): Object { 75 | const configFormats = config.formats || {} 76 | const precision = config.precision || 4 77 | 78 | const formats = { 79 | ...defaultFormats, 80 | ...configFormats, 81 | } 82 | 83 | return ({ types }) => ({ 84 | Dimension({ node }) { 85 | const group = getGroup(node.unit) 86 | 87 | if (group) { 88 | const format = formats[group] 89 | const value = 90 | node.value.value || node.value.integer + node.value.fractional 91 | 92 | const newValue = convert(value, node.unit, format, precision) 93 | 94 | node.unit = format 95 | 96 | if (isFloat(newValue)) { 97 | const integerPart = Math.floor(newValue) 98 | const precisionFactor = Math.pow(10, precision) 99 | 100 | const floatPart = 101 | Math.round((newValue - integerPart) * precisionFactor) / 102 | precisionFactor 103 | 104 | node.value = types.float(integerPart, floatPart, node.negative) 105 | } else { 106 | node.value = types.integer(newValue, node.negative) 107 | } 108 | } 109 | }, 110 | }) 111 | } 112 | -------------------------------------------------------------------------------- /packages/bredon-plugin-unit/yarn.lock: -------------------------------------------------------------------------------- 1 | # THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. 2 | # yarn lockfile v1 3 | 4 | 5 | color-convert@^1.9.1: 6 | version "1.9.1" 7 | resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.1.tgz#c1261107aeb2f294ebffec9ed9ecad529a6097ed" 8 | dependencies: 9 | color-name "^1.1.1" 10 | 11 | color-name@^1.0.0, color-name@^1.1.1: 12 | version "1.1.3" 13 | resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25" 14 | 15 | color-string@^1.5.2: 16 | version "1.5.2" 17 | resolved "https://registry.yarnpkg.com/color-string/-/color-string-1.5.2.tgz#26e45814bc3c9a7cbd6751648a41434514a773a9" 18 | dependencies: 19 | color-name "^1.0.0" 20 | simple-swizzle "^0.2.2" 21 | 22 | color@^2.0.0: 23 | version "2.0.1" 24 | resolved "https://registry.yarnpkg.com/color/-/color-2.0.1.tgz#e4ed78a3c4603d0891eba5430b04b86314f4c839" 25 | dependencies: 26 | color-convert "^1.9.1" 27 | color-string "^1.5.2" 28 | 29 | is-arrayish@^0.3.1: 30 | version "0.3.1" 31 | resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.3.1.tgz#c2dfc386abaa0c3e33c48db3fe87059e69065efd" 32 | 33 | simple-swizzle@^0.2.2: 34 | version "0.2.2" 35 | resolved "https://registry.yarnpkg.com/simple-swizzle/-/simple-swizzle-0.2.2.tgz#a4da6b635ffcccca33f70d17cb92592de95e557a" 36 | dependencies: 37 | is-arrayish "^0.3.1" 38 | -------------------------------------------------------------------------------- /packages/bredon-tools/README.md: -------------------------------------------------------------------------------- 1 | # bredon-tools 2 | 3 | NPM package to get access to Bredon's Tools API.
4 | Check out the [Bredon repository](https://github.com/rofrischmann/bredon) for further information. 5 | -------------------------------------------------------------------------------- /packages/bredon-tools/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "bredon-tools", 3 | "version": "4.0.0", 4 | "description": "Useful functional utilities for working with Bredon", 5 | "main": "lib/index.js", 6 | "module": "es/index.js", 7 | "jsnext:main": "es/index.js", 8 | "files": [ 9 | "LICENSE", 10 | "README.md", 11 | "lib/**", 12 | "es/**" 13 | ], 14 | "keywords": [ 15 | "css", 16 | "parser", 17 | "css-parser", 18 | "css-value-parser", 19 | "ast", 20 | "lexer", 21 | "tokenizer", 22 | "cssinjs", 23 | "bredon" 24 | ], 25 | "repository": "https://github.com/rofrischmann/bredon.git", 26 | "author": "Robin Frischmann ", 27 | "license": "MIT", 28 | "peerDependencies": { 29 | "bredon": "^4.0.0" 30 | }, 31 | "devDependencies": { 32 | "bredon": "^4.0.0" 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /packages/bredon-tools/src/getSingleValue.js: -------------------------------------------------------------------------------- 1 | /* @flow */ 2 | import { types } from 'bredon' 3 | 4 | import isSingleValue from './isSingleValue' 5 | 6 | import type { ASTNode } from '../../../flowtypes/AST' 7 | 8 | export default function getSingleValue(ast: ASTNode): ?ASTNode { 9 | return isSingleValue(ast) && types.isValueList(ast) 10 | ? ast.body[0].body[0] 11 | : ast.body[0] 12 | } 13 | -------------------------------------------------------------------------------- /packages/bredon-tools/src/index.js: -------------------------------------------------------------------------------- 1 | import getSingleValue from './getSingleValue' 2 | import isSingleValue from './isSingleValue' 3 | 4 | export { getSingleValue, isSingleValue } 5 | -------------------------------------------------------------------------------- /packages/bredon-tools/src/isSingleValue.js: -------------------------------------------------------------------------------- 1 | /* @flow */ 2 | import { types } from 'bredon' 3 | 4 | import type { ASTNode } from '../../../flowtypes/AST' 5 | 6 | export default function isSingleValue(ast: ASTNode) { 7 | return (types.isValue(ast) || types.isValueList(ast)) && ast.body.length <= 1 8 | } 9 | -------------------------------------------------------------------------------- /packages/bredon-tools/yarn.lock: -------------------------------------------------------------------------------- 1 | # THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. 2 | # yarn lockfile v1 3 | 4 | 5 | bredon-types@^2.0.2: 6 | version "2.0.2" 7 | resolved "https://registry.yarnpkg.com/bredon-types/-/bredon-types-2.0.2.tgz#af4d83c27cec4ab431885b7cc08b455e20e1aafa" 8 | -------------------------------------------------------------------------------- /packages/bredon-types/README.md: -------------------------------------------------------------------------------- 1 | # bredon-types 2 | 3 | NPM package to get access to Bredon's Types API.
4 | Check out the [Bredon repository](https://github.com/rofrischmann/bredon) for further information. -------------------------------------------------------------------------------- /packages/bredon-types/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "bredon-types", 3 | "version": "3.0.1", 4 | "description": "Factories and Validators to manually create and check bredon AST Nodes", 5 | "main": "lib/index.js", 6 | "module": "es/index.js", 7 | "jsnext:main": "es/index.js", 8 | "files": [ 9 | "LICENSE", 10 | "README.md", 11 | "lib/**", 12 | "es/**" 13 | ], 14 | "keywords": [ 15 | "css", 16 | "parser", 17 | "css-parser", 18 | "css-value-parser", 19 | "ast", 20 | "lexer", 21 | "tokenizer", 22 | "cssinjs", 23 | "bredon" 24 | ], 25 | "repository": "https://github.com/rofrischmann/bredon.git", 26 | "author": "Robin Frischmann ", 27 | "license": "MIT" 28 | } 29 | -------------------------------------------------------------------------------- /packages/bredon-types/src/builders/assignment.js: -------------------------------------------------------------------------------- 1 | /* @flow */ 2 | import type { Node, AssignmentNode } from '../../../../flowtypes/AST' 3 | 4 | export default function assignment(name: string, value: Node): AssignmentNode { 5 | return { 6 | type: 'Assignment', 7 | name, 8 | value, 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /packages/bredon-types/src/builders/dimension.js: -------------------------------------------------------------------------------- 1 | /* @flow */ 2 | import type { 3 | DimensionNode, 4 | FloatNode, 5 | IntegerNode, 6 | } from '../../../../flowtypes/AST' 7 | 8 | type Unit = 9 | | '%' 10 | | 'em' 11 | | 'ex' 12 | | 'ch' 13 | | 'rem' 14 | | 'vw' 15 | | 'vh' 16 | | 'vmin' 17 | | 'vmax' 18 | | 'cm' 19 | | 'mm' 20 | | 'q' 21 | | 'in' 22 | | 'pt' 23 | | 'pc' 24 | | 'px' 25 | | 'deg' 26 | | 'grad' 27 | | 'rad' 28 | | 'turn' 29 | | 's' 30 | | 'ms' 31 | | 'Hz' 32 | | 'kHz' 33 | | 'dpi' 34 | | 'dpcm' 35 | | 'dppx' 36 | 37 | export default function dimension( 38 | value: FloatNode | IntegerNode, 39 | unit: Unit 40 | ): DimensionNode { 41 | return { 42 | type: 'Dimension', 43 | value, 44 | unit, 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /packages/bredon-types/src/builders/expression.js: -------------------------------------------------------------------------------- 1 | /* @flow */ 2 | import type { ExpressionNode, Node } from '../../../../flowtypes/AST' 3 | 4 | export default function expression(body: Array): ExpressionNode { 5 | return { 6 | type: 'Expression', 7 | body, 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /packages/bredon-types/src/builders/float.js: -------------------------------------------------------------------------------- 1 | /* @flow */ 2 | import type { FloatNode } from '../../../../flowtypes/AST' 3 | 4 | export default function float( 5 | integer: number, 6 | fractional: number, 7 | isNegative?: boolean = false 8 | ): FloatNode { 9 | return { 10 | type: 'Float', 11 | fractional, 12 | integer, 13 | negative: isNegative, 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /packages/bredon-types/src/builders/functionExpression.js: -------------------------------------------------------------------------------- 1 | /* @flow */ 2 | import type { Node, FunctionNode } from '../../../../flowtypes/AST' 3 | 4 | export default function functionExpression( 5 | callee: string, 6 | params: Array 7 | ): FunctionNode { 8 | return { 9 | type: 'FunctionExpression', 10 | callee, 11 | params, 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /packages/bredon-types/src/builders/hexColor.js: -------------------------------------------------------------------------------- 1 | /* @flow */ 2 | import type { SimpleNode } from '../../../../flowtypes/AST' 3 | 4 | export default function hexColor(color: string): SimpleNode { 5 | return { 6 | type: 'HexColor', 7 | value: color, 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /packages/bredon-types/src/builders/identifier.js: -------------------------------------------------------------------------------- 1 | /* @flow */ 2 | import type { SimpleNode } from '../../../../flowtypes/AST' 3 | 4 | export default function identifier(value: string): SimpleNode { 5 | return { 6 | type: 'Identifier', 7 | value, 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /packages/bredon-types/src/builders/important.js: -------------------------------------------------------------------------------- 1 | /* @flow */ 2 | import type { SimpleNode } from '../../../../flowtypes/AST' 3 | 4 | export default function important(): SimpleNode { 5 | return { 6 | type: 'Important', 7 | value: '!important', 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /packages/bredon-types/src/builders/integer.js: -------------------------------------------------------------------------------- 1 | /* @flow */ 2 | import type { IntegerNode } from '../../../../flowtypes/AST' 3 | 4 | export default function integer( 5 | value: number, 6 | isNegative?: boolean = false 7 | ): IntegerNode { 8 | return { 9 | type: 'Integer', 10 | negative: isNegative, 11 | value, 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /packages/bredon-types/src/builders/operator.js: -------------------------------------------------------------------------------- 1 | /* @flow */ 2 | import type { SimpleNode } from '../../../../flowtypes/AST' 3 | 4 | type ExpressionSymbol = '+' | '-' | '*' | '/' 5 | 6 | export default function operator(symbol: ExpressionSymbol): SimpleNode { 7 | return { 8 | type: 'Operator', 9 | value: symbol, 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /packages/bredon-types/src/builders/parenthesis.js: -------------------------------------------------------------------------------- 1 | /* @flow */ 2 | import type { SimpleNode } from '../../../../flowtypes/AST' 3 | 4 | type Paren = '(' | ')' 5 | export default function parenthesis(paren: Paren): SimpleNode { 6 | return { 7 | type: 'Parenthesis', 8 | value: paren, 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /packages/bredon-types/src/builders/separator.js: -------------------------------------------------------------------------------- 1 | /* @flow */ 2 | import type { SimpleNode } from '../../../../flowtypes/AST' 3 | 4 | export default function separator(kind: string = '/'): SimpleNode { 5 | return { 6 | type: 'Separator', 7 | value: kind, 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /packages/bredon-types/src/builders/stringLiteral.js: -------------------------------------------------------------------------------- 1 | /* @flow */ 2 | import type { SimpleNode } from '../../../../flowtypes/AST' 3 | 4 | type Quote = '"' | "'" 5 | 6 | export default function stringLiteral( 7 | str: string, 8 | quote: Quote = "'" 9 | ): SimpleNode { 10 | return { 11 | type: 'StringLiteral', 12 | value: str, 13 | quote, 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /packages/bredon-types/src/builders/url.js: -------------------------------------------------------------------------------- 1 | /* @flow */ 2 | import type { SimpleNode } from '../../../../flowtypes/AST' 3 | 4 | export default function url(str: string): SimpleNode { 5 | return { 6 | type: 'URL', 7 | value: str, 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /packages/bredon-types/src/builders/value.js: -------------------------------------------------------------------------------- 1 | /* @flow */ 2 | import type { Node, Value } from '../../../../flowtypes/AST' 3 | 4 | export default function cssValue( 5 | body: Array = [], 6 | important: ?boolean = false 7 | ): Value { 8 | return { 9 | type: 'Value', 10 | important, 11 | body, 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /packages/bredon-types/src/builders/valueList.js: -------------------------------------------------------------------------------- 1 | /* @flow */ 2 | import type { ValueList, Value } from '../../../../flowtypes/AST' 3 | 4 | export default function valueList(body: Array = []): ValueList { 5 | return { 6 | type: 'ValueList', 7 | body, 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /packages/bredon-types/src/index.js: -------------------------------------------------------------------------------- 1 | import assignment from './builders/assignment' 2 | import value from './builders/value' 3 | import dimension from './builders/dimension' 4 | import expression from './builders/expression' 5 | import float from './builders/float' 6 | import functionExpression from './builders/functionExpression' 7 | import hexColor from './builders/hexColor' 8 | import identifier from './builders/identifier' 9 | import integer from './builders/integer' 10 | import valueList from './builders/valueList' 11 | import operator from './builders/operator' 12 | import parenthesis from './builders/parenthesis' 13 | import separator from './builders/separator' 14 | import stringLiteral from './builders/stringLiteral' 15 | import url from './builders/url' 16 | 17 | import isValue from './validators/isValue' 18 | import isAssignment from './validators/isAssignment' 19 | import isDimension from './validators/isDimension' 20 | import isExpression from './validators/isExpression' 21 | import isFloat from './validators/isFloat' 22 | import isFunctionExpression from './validators/isFunctionExpression' 23 | import isHexColor from './validators/isHexColor' 24 | import isIdentifier from './validators/isIdentifier' 25 | import isInteger from './validators/isInteger' 26 | import isValueList from './validators/isValueList' 27 | import isOperator from './validators/isOperator' 28 | import isParenthesis from './validators/isParenthesis' 29 | import isSeparator from './validators/isSeparator' 30 | import isStringLiteral from './validators/isStringLiteral' 31 | import isUrl from './validators/isUrl' 32 | 33 | export { 34 | assignment, 35 | value, 36 | dimension, 37 | expression, 38 | float, 39 | functionExpression, 40 | hexColor, 41 | identifier, 42 | integer, 43 | valueList, 44 | operator, 45 | parenthesis, 46 | separator, 47 | stringLiteral, 48 | url, 49 | isAssignment, 50 | isValue, 51 | isDimension, 52 | isExpression, 53 | isFloat, 54 | isFunctionExpression, 55 | isHexColor, 56 | isIdentifier, 57 | isInteger, 58 | isValueList, 59 | isOperator, 60 | isParenthesis, 61 | isSeparator, 62 | isStringLiteral, 63 | isUrl, 64 | } 65 | -------------------------------------------------------------------------------- /packages/bredon-types/src/validators/isAssignment.js: -------------------------------------------------------------------------------- 1 | /* @flow */ 2 | import type { ASTNode } from '../../../../flowtypes/AST' 3 | 4 | export default function isAssignment(node: ASTNode): boolean { 5 | return node.type === 'Assignment' 6 | } 7 | -------------------------------------------------------------------------------- /packages/bredon-types/src/validators/isDimension.js: -------------------------------------------------------------------------------- 1 | /* @flow */ 2 | import type { ASTNode } from '../../../../flowtypes/AST' 3 | 4 | export default function isDimension(node: ASTNode): boolean { 5 | return node.type === 'Dimension' 6 | } 7 | -------------------------------------------------------------------------------- /packages/bredon-types/src/validators/isExpression.js: -------------------------------------------------------------------------------- 1 | /* @flow */ 2 | import type { ASTNode } from '../../../../flowtypes/AST' 3 | 4 | export default function isExpression(node: ASTNode): boolean { 5 | return node.type === 'Expression' 6 | } 7 | -------------------------------------------------------------------------------- /packages/bredon-types/src/validators/isFloat.js: -------------------------------------------------------------------------------- 1 | /* @flow */ 2 | import type { ASTNode } from '../../../../flowtypes/AST' 3 | 4 | export default function isFloat(node: ASTNode): boolean { 5 | return node.type === 'Float' 6 | } 7 | -------------------------------------------------------------------------------- /packages/bredon-types/src/validators/isFunctionExpression.js: -------------------------------------------------------------------------------- 1 | /* @flow */ 2 | import type { ASTNode } from '../../../../flowtypes/AST' 3 | 4 | export default function isFunctionExpression(node: ASTNode): boolean { 5 | return node.type === 'FunctionExpression' 6 | } 7 | -------------------------------------------------------------------------------- /packages/bredon-types/src/validators/isHexColor.js: -------------------------------------------------------------------------------- 1 | /* @flow */ 2 | import type { ASTNode } from '../../../../flowtypes/AST' 3 | 4 | export default function isHexColor(node: ASTNode): boolean { 5 | return node.type === 'HexColor' 6 | } 7 | -------------------------------------------------------------------------------- /packages/bredon-types/src/validators/isIdentifier.js: -------------------------------------------------------------------------------- 1 | /* @flow */ 2 | import type { ASTNode } from '../../../../flowtypes/AST' 3 | 4 | export default function isIdentifier(node: ASTNode): boolean { 5 | return node.type === 'Identifier' 6 | } 7 | -------------------------------------------------------------------------------- /packages/bredon-types/src/validators/isInteger.js: -------------------------------------------------------------------------------- 1 | /* @flow */ 2 | import type { ASTNode } from '../../../../flowtypes/AST' 3 | 4 | export default function isInteger(node: ASTNode): boolean { 5 | return node.type === 'Integer' 6 | } 7 | -------------------------------------------------------------------------------- /packages/bredon-types/src/validators/isOperator.js: -------------------------------------------------------------------------------- 1 | /* @flow */ 2 | import type { ASTNode } from '../../../../flowtypes/AST' 3 | 4 | export default function isOperator(node: ASTNode): boolean { 5 | return node.type === 'Operator' 6 | } 7 | -------------------------------------------------------------------------------- /packages/bredon-types/src/validators/isParenthesis.js: -------------------------------------------------------------------------------- 1 | /* @flow */ 2 | import type { ASTNode } from '../../../../flowtypes/AST' 3 | 4 | export default function isParenthesis(node: ASTNode): boolean { 5 | return node.type === 'Parenthesis' 6 | } 7 | -------------------------------------------------------------------------------- /packages/bredon-types/src/validators/isSeparator.js: -------------------------------------------------------------------------------- 1 | /* @flow */ 2 | import type { ASTNode } from '../../../../flowtypes/AST' 3 | 4 | export default function isSeparator(node: ASTNode): boolean { 5 | return node.type === 'Separator' 6 | } 7 | -------------------------------------------------------------------------------- /packages/bredon-types/src/validators/isStringLiteral.js: -------------------------------------------------------------------------------- 1 | /* @flow */ 2 | import type { ASTNode } from '../../../../flowtypes/AST' 3 | 4 | export default function isStringLiteral(node: ASTNode): boolean { 5 | return node.type === 'StringLiteral' 6 | } 7 | -------------------------------------------------------------------------------- /packages/bredon-types/src/validators/isUrl.js: -------------------------------------------------------------------------------- 1 | /* @flow */ 2 | import type { ASTNode } from '../../../../flowtypes/AST' 3 | 4 | export default function isUrl(node: ASTNode): boolean { 5 | return node.type === 'Expression' 6 | } 7 | -------------------------------------------------------------------------------- /packages/bredon-types/src/validators/isValue.js: -------------------------------------------------------------------------------- 1 | /* @flow */ 2 | import type { ASTNode } from '../../../../flowtypes/AST' 3 | 4 | export default function isValue(node: ASTNode): boolean { 5 | return node.type === 'Value' 6 | } 7 | -------------------------------------------------------------------------------- /packages/bredon-types/src/validators/isValueList.js: -------------------------------------------------------------------------------- 1 | /* @flow */ 2 | import type { ASTNode } from '../../../../flowtypes/AST' 3 | 4 | export default function isValueList(node: ASTNode): boolean { 5 | return node.type === 'ValueList' 6 | } 7 | -------------------------------------------------------------------------------- /packages/bredon-validate/README.md: -------------------------------------------------------------------------------- 1 | # bredon-validate 2 | 3 | NPM package to get access to Bredon's Validation API.
4 | Check out the [Bredon repository](https://github.com/rofrischmann/bredon) for further information. 5 | -------------------------------------------------------------------------------- /packages/bredon-validate/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "bredon-validate", 3 | "version": "0.0.3", 4 | "description": "Validation Methods for CSS values", 5 | "main": "lib/index.js", 6 | "module": "es/index.js", 7 | "jsnext:main": "es/index.js", 8 | "files": [ 9 | "LICENSE", 10 | "README.md", 11 | "lib/**", 12 | "es/**" 13 | ], 14 | "keywords": [ 15 | "css", 16 | "parser", 17 | "css-parser", 18 | "css-value-parser", 19 | "ast", 20 | "lexer", 21 | "tokenizer", 22 | "validation", 23 | "validator", 24 | "cssinjs", 25 | "bredon" 26 | ], 27 | "repository": "https://github.com/rofrischmann/bredon.git", 28 | "author": "Robin Frischmann ", 29 | "license": "MIT", 30 | "dependencies": { 31 | "bredon": "^4.0.0", 32 | "bredon-plugin-case": "^1.0.0", 33 | "bredon-types": "^3.0.1", 34 | "css-in-js-utils": "^2.0.0" 35 | }, 36 | "devDependencies": { 37 | "postcss": "^6.0.14", 38 | "postcss-bredon-validate": "^0.0.2", 39 | "postcss-reporter": "^5.0.0" 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /packages/bredon-validate/src/__tests__/monkey-test.js: -------------------------------------------------------------------------------- 1 | import path from 'path' 2 | import fs from 'fs' 3 | 4 | import postcss from 'postcss' 5 | import reporter from 'postcss-reporter' 6 | import bredonValidate from 'postcss-bredon-validate' 7 | 8 | const fixturePath = '/__fixtures__/' 9 | 10 | const fixtures = fs 11 | .readdirSync(path.join(__dirname, fixturePath)) 12 | .reduce((fixureList, file) => { 13 | fixureList.push(path.join(__dirname, fixturePath, file)) 14 | return fixureList 15 | }, []) 16 | 17 | /* eslint-disable no-console */ 18 | function processFile(filename, stop, done) { 19 | const css = fs.readFileSync(filename) 20 | 21 | postcss([bredonValidate, reporter]) 22 | .process(css) 23 | .then(() => { 24 | if (stop) { 25 | expect(console.log).not.toBeCalled() 26 | done() 27 | } 28 | }) 29 | } 30 | 31 | describe('Monkey testing bredon-validate', () => { 32 | jest.spyOn(global.console, 'log') 33 | // global.console.warn = () => false 34 | 35 | it('should not throw any warning', done => { 36 | fixtures.forEach((fixture, index) => 37 | processFile(fixture, index === fixtures.length - 1, done) 38 | ) 39 | }) 40 | }) 41 | -------------------------------------------------------------------------------- /packages/bredon-validate/src/__tests__/validate-test.js: -------------------------------------------------------------------------------- 1 | import validate from '../index' 2 | 3 | /* eslint-disable */ 4 | import mdnData from '../data/__mdnData' 5 | import propertyValidators from '../propertyValidators' 6 | 7 | import properties from '../data/properties' 8 | 9 | const dashRegex = /-([a-z])/g 10 | const msRegex = /^Ms/g 11 | 12 | function camelCaseProperty(property) { 13 | return property 14 | .replace(dashRegex, match => match[1].toUpperCase()) 15 | .replace(msRegex, 'ms') 16 | } 17 | 18 | var uppercasePattern = /[A-Z]/g 19 | var msPattern = /^ms-/ 20 | var cache = {} 21 | 22 | function hyphenateStyleName(string) { 23 | return string in cache 24 | ? cache[string] 25 | : (cache[string] = string 26 | .replace(uppercasePattern, '-$&') 27 | .toLowerCase() 28 | .replace(msPattern, '-ms-')) 29 | } 30 | 31 | const additional = Object.keys(properties).filter( 32 | prop => !mdnData.hasOwnProperty(hyphenateStyleName(prop)) 33 | ) 34 | 35 | additional.forEach(prop => { 36 | mdnData[prop] = true 37 | }) 38 | 39 | console.log( 40 | `Missing properties: 41 | ${Object.keys(mdnData) 42 | .filter(prop => !properties.hasOwnProperty(camelCaseProperty(prop))) 43 | .map(camelCaseProperty) 44 | .join('\n')} 45 | 46 | Having ${Object.keys(properties).length} out of ${Object.keys(mdnData) 47 | .length} properties. 48 | Progress: ${Math.round( 49 | Object.keys(properties).length / Object.keys(mdnData).length * 10000 50 | ) / 100}% done.` 51 | ) 52 | 53 | /* eslint-enable */ 54 | 55 | describe('Validating properties', () => { 56 | it('should correctly validate property values', () => { 57 | expect(validate('paddingLeft', '2px')).toBe(true) 58 | expect(validate('paddingLeft', '2px!important')).toBe(true) 59 | expect(validate('paddingLeft', '2px !important')).toBe(true) 60 | expect(validate('paddingLeft', '100%')).toBe(true) 61 | expect(validate('paddingLeft', 'red')).toBe(false) 62 | expect(validate('paddingLeft', '2px 2px')).toBe(false) 63 | expect(validate('paddingLeft', '2px, 2px')).toBe(false) 64 | expect(validate('blockSize', '2px')).toBe(true) 65 | expect(validate('blockSize', 'inherit')).toBe(true) 66 | expect(validate('blockSize', '2px border-box')).toBe(true) 67 | expect(validate('blockSize', '2px available')).toBe(false) 68 | expect(validate('strokeDasharray', 'none')).toBe(true) 69 | expect(validate('strokeDasharray', '2px 10%')).toBe(true) 70 | expect(validate('strokeDasharray', 'none 2px')).toBe(false) 71 | expect(validate('strokeDasharray', '2px none')).toBe(false) 72 | 73 | expect(validate('borderLeft', '2px')).toBe(true) 74 | expect(validate('borderLeft', 'solid')).toBe(true) 75 | expect(validate('borderLeft', '2px solid')).toBe(true) 76 | expect(validate('borderLeft', 'solid 2px')).toBe(true) 77 | expect(validate('borderLeft', 'red solid 2px')).toBe(true) 78 | expect(validate('borderLeft', 'solid 2px red')).toBe(true) 79 | expect(validate('borderLeft', 'solid red')).toBe(true) 80 | expect(validate('borderLeft', 'solid 2px red 2px')).toBe(false) 81 | expect(validate('borderLeft', 'solid solid')).toBe(false) 82 | 83 | expect(validate('touchAction', 'none')).toBe(true) 84 | expect(validate('touchAction', 'pan-x')).toBe(true) 85 | expect(validate('touchAction', 'pan-y pan-x')).toBe(true) 86 | expect(validate('touchAction', 'pinch-zoom pan-x pan-y')).toBe(true) 87 | expect(validate('touchAction', 'pinch-zoom pan-x pan-y pan-x')).toBe(false) 88 | expect(validate('touchAction', 'none none')).toBe(false) 89 | expect(validate('touchAction', 'none pan-x')).toBe(false) 90 | expect(validate('touchAction', 'pan-x none')).toBe(false) 91 | expect(validate('touchAction', 'pan-x pan-x')).toBe(false) 92 | 93 | expect(validate('willChange', 'auto')).toBe(true) 94 | expect(validate('willChange', 'scroll-position, contents')).toBe(true) 95 | expect(validate('willChange', 'auto, auto')).toBe(false) 96 | expect(validate('willChange', 'auto, scroll-position')).toBe(false) 97 | expect(validate('scrollSnapCoordinate', 'none')).toBe(true) 98 | expect(validate('scrollSnapCoordinate', 'none, none')).toBe(false) 99 | expect(validate('scrollSnapCoordinate', '30px')).toBe(true) 100 | expect(validate('scrollSnapCoordinate', '40px, left')).toBe(true) 101 | 102 | expect(validate('WebkitMaskAttachment', 'scroll')).toBe(true) 103 | expect(validate('WebkitMaskAttachment', 'scroll, fixed')).toBe(true) 104 | expect( 105 | validate('WebkitMaskAttachment', 'scroll, fixed, scroll, local') 106 | ).toBe(true) 107 | expect(validate('WebkitMaskAttachment', 'scroll, fixed, 2px, local')).toBe( 108 | false 109 | ) 110 | expect(validate('WebkitMaskAttachment', 'scroll fixed')).toBe(false) 111 | }) 112 | }) 113 | -------------------------------------------------------------------------------- /packages/bredon-validate/src/data/_missingProps.js: -------------------------------------------------------------------------------- 1 | export default [ 2 | 'MozContextProperties', 3 | 'WebkitBoxReflect', 4 | 'WebkitMask', 5 | 'WebkitMaskImage', 6 | 'WebkitMaskPosition', 7 | 'WebkitMaskRepeat', 8 | 'WebkitTextStroke', 9 | 'azimuth', 10 | 'backdropFilter', 11 | 'background', 12 | 'backgroundImage', 13 | 'backgroundSize', 14 | 'borderImage', 15 | 'borderImageSlice', 16 | 'borderImageSource', 17 | 'boxShadow', 18 | 'content', 19 | 'counterIncrement', 20 | 'counterReset', 21 | 'filter', 22 | 'font', 23 | 'fontFeatureSettings', 24 | 'fontLanguageOverride', 25 | 'fontVariationSettings', 26 | 'fontSynthesis', 27 | 'fontVariantAlternates', 28 | 'fontVariantEastAsian', 29 | 'fontVariantLigatures', 30 | 'fontVariantNumeric', 31 | 'fontVariantPosition', 32 | 'grid', 33 | 'gridArea', 34 | 'gridAutoColumns', 35 | 'gridAutoRows', 36 | 'gridColumn', 37 | 'gridColumnEnd', 38 | 'gridColumnStart', 39 | 'gridRow', 40 | 'gridRowEnd', 41 | 'gridRowStart', 42 | 'gridTemplate', 43 | 'gridTemplateColumns', 44 | 'gridTemplateRows', 45 | 'hangingPunctuation', 46 | 'imageOrientation', 47 | 'imageResolution', 48 | 'initialLetter', 49 | 'lineHeightStep', 50 | 'listStyle', 51 | 'listStylePosition', 52 | 'listStyleType', 53 | 'mask', 54 | 'maskBorder', 55 | 'maskBorderSlice', 56 | 'maskImage', 57 | 'maskRepeat', 58 | 'maskSize', 59 | 'offset', 60 | 'offsetPath', 61 | 'offsetRotate', 62 | 'outline', 63 | 'overflowWrap', 64 | 'src', 65 | 'shapeOutside', 66 | 'textCombineUpright', 67 | 'transform', 68 | ] 69 | -------------------------------------------------------------------------------- /packages/bredon-validate/src/data/colorNames.js: -------------------------------------------------------------------------------- 1 | export default [ 2 | 'transparent', 3 | 'currentcolor', 4 | 'red', 5 | 'blue', 6 | 'brown', 7 | 'lightseagreen', 8 | 'orange', 9 | 'darkgray', 10 | 'darkgrey', 11 | 'darkslategray', 12 | 'darkslategrey', 13 | 'dimgray', 14 | 'dimgrey', 15 | 'lightgray', 16 | 'lightgrey', 17 | 'lightslategray', 18 | 'lightslategrey', 19 | 'gray', 20 | 'grey', 21 | 'slategray', 22 | 'slategrey', 23 | 'black', 24 | 'silver', 25 | 'white', 26 | 'maroon', 27 | 'purple', 28 | 'fuchsia', 29 | 'green', 30 | 'lime', 31 | 'olive', 32 | 'yellow', 33 | 'navy', 34 | 'teal', 35 | 'aqua', 36 | 'aliceblue', 37 | 'antiquewhite', 38 | 'aquamarine', 39 | 'azure', 40 | 'beige', 41 | 'bisque', 42 | 'blanchedalmond', 43 | 'blueviolet', 44 | 'burlywood', 45 | 'cadetblue', 46 | 'chartreuse', 47 | 'chocolate', 48 | 'coral', 49 | 'cornflowerblue', 50 | 'cornsilk', 51 | 'crimson', 52 | 'darkblue', 53 | 'darkcyan', 54 | 'darkgoldenrod', 55 | 'darkgreen', 56 | 'darkkhaki', 57 | 'darkmagenta', 58 | 'darkolivegreen', 59 | 'darkorange', 60 | 'darkorchid', 61 | 'darkred', 62 | 'darksalmon', 63 | 'darkseagreen', 64 | 'darkslateblue', 65 | 'darkturquoise', 66 | 'darkviolet', 67 | 'deeppink', 68 | 'deepskyblue', 69 | 'dodgerblue', 70 | 'firebrick', 71 | 'floralwhite', 72 | 'forestgreen', 73 | 'gainsboro', 74 | 'ghostwhite', 75 | 'gold', 76 | 'goldenrod', 77 | 'greenyellow', 78 | 'honeydew', 79 | 'hotpink', 80 | 'indianred', 81 | 'indigo', 82 | 'ivory', 83 | 'khaki', 84 | 'lavender', 85 | 'lavenderblush', 86 | 'lawngreen', 87 | 'lemonchiffon', 88 | 'lightblue', 89 | 'lightcoral', 90 | 'lightcyan', 91 | 'lightgoldenrodyellow', 92 | 'lightgreen', 93 | 'lightpink', 94 | 'lightsalmon', 95 | 'lightskyblue', 96 | 'lightsteelblue', 97 | 'lightyellow', 98 | 'limegreen', 99 | 'linen', 100 | 'mediumaquamarine', 101 | 'mediumblue', 102 | 'mediumorchid', 103 | 'mediumpurple', 104 | 'mediumseagreen', 105 | 'mediumslateblue', 106 | 'mediumspringgreen', 107 | 'mediumturquoise', 108 | 'mediumvioletred', 109 | 'midnightblue', 110 | 'mintcream', 111 | 'mistyrose', 112 | 'moccasin', 113 | 'navajowhite', 114 | 'oldlace', 115 | 'olivedrab', 116 | 'orangered', 117 | 'orchid', 118 | 'palegoldenrod', 119 | 'palegreen', 120 | 'paleturquoise', 121 | 'palevioletred', 122 | 'papayawhip', 123 | 'peachpuff', 124 | 'peru', 125 | 'pink', 126 | 'plum', 127 | 'powderblue', 128 | 'rosybrown', 129 | 'royalblue', 130 | 'saddlebrown', 131 | 'salmon', 132 | 'sandybrown', 133 | 'seagreen', 134 | 'seashell', 135 | 'sienna', 136 | 'skyblue', 137 | 'slateblue', 138 | 'snow', 139 | 'springgreen', 140 | 'steelblue', 141 | 'tan', 142 | 'thistle', 143 | 'tomato', 144 | 'turquoise', 145 | 'violet', 146 | 'wheat', 147 | 'whitesmoke', 148 | 'yellowgreen', 149 | 'rebeccapurple', 150 | '-moz-buttondefault', 151 | '-moz-buttonhoverface', 152 | '-moz-buttonhovertext', 153 | '-moz-cellhighlight', 154 | '-moz-cellhighlighttext', 155 | '-moz-combobox', 156 | '-moz-comboboxtext', 157 | '-moz-dialog', 158 | '-moz-dialogtext', 159 | '-moz-dragtargetzone', 160 | '-moz-eventreerow', 161 | '-moz-field', 162 | '-moz-fieldtext', 163 | '-moz-html-cellhighlight', 164 | '-moz-html-cellhighlighttext', 165 | '-moz-mac-accentdarkestshadow', 166 | '-moz-mac-accentdarkshadow', 167 | '-moz-mac-accentface', 168 | '-moz-mac-accentlightesthighlight', 169 | '-moz-mac-accentlightshadow', 170 | '-moz-mac-accentregularhighlight', 171 | '-moz-mac-accentregularshadow', 172 | '-moz-mac-chrome-active', 173 | '-moz-mac-chrome-inactive', 174 | '-moz-mac-focusring', 175 | '-moz-mac-menuselect', 176 | '-moz-mac-menushadow', 177 | '-moz-mac-menutextselect', 178 | '-moz-menuhover', 179 | '-moz-menuhovertext', 180 | '-moz-menubartext', 181 | '-moz-menubarhovertext', 182 | '-moz-nativehyperlinktext', 183 | '-moz-oddtreerow', 184 | '-moz-win-communicationstext', 185 | '-moz-win-mediatext', 186 | '-moz-activehyperlinktext', 187 | '-moz-default-background-color', 188 | '-moz-default-color', 189 | '-moz-hyperlinktext', 190 | '-moz-visitedhyperlinktext', 191 | '-webkit-activelink', 192 | '-webkit-focus-ring-color', 193 | '-webkit-link', 194 | '-webkit-text', 195 | 'activeborder', 196 | 'activecaption', 197 | 'appworkspace', 198 | 'background', 199 | 'buttonface', 200 | 'buttonhighlight', 201 | 'buttonshadow', 202 | 'buttontext', 203 | 'captiontext', 204 | 'graytext', 205 | 'highlight', 206 | 'highlighttext', 207 | 'inactiveborder', 208 | 'inactivecaption', 209 | 'inactivecaptiontext', 210 | 'infobackground', 211 | 'infotext', 212 | 'menu', 213 | 'menutext', 214 | 'scrollbar', 215 | 'threeddarkshadow', 216 | 'threedface', 217 | 'threedhighlight', 218 | 'threedlightshadow', 219 | 'threedshadow', 220 | 'window', 221 | 'windowframe', 222 | 'windowtext', 223 | ] 224 | -------------------------------------------------------------------------------- /packages/bredon-validate/src/data/multiValueProperties.js: -------------------------------------------------------------------------------- 1 | export default { 2 | MozBorderBottomColors: true, 3 | MozBorderLeftColors: true, 4 | MozBorderRadiusBottomright: true, 5 | MozBorderRadiusTopleft: true, 6 | MozBorderRadiusTopright: true, 7 | MozBorderRightColors: true, 8 | MozBorderTopColors: true, 9 | MozOutlineRadius: true, 10 | MozOutlineRadiusBottomleft: true, 11 | MozOutlineRadiusBottomright: true, 12 | MozOutlineRadiusTopleft: true, 13 | MozOutlineRadiusTopright: true, 14 | WebkitBorderBefore: true, 15 | WebkitBorderBeforeStyle: true, 16 | WebkitBorderBeforeWidth: true, 17 | animation: true, 18 | backgroundPosition: true, 19 | backgroundPositionX: true, 20 | backgroundPositionY: true, 21 | backgroundRepeat: true, 22 | backgroundSize: true, 23 | blockSize: true, 24 | border: true, 25 | borderBlockEnd: true, 26 | borderBlockEndStyle: true, 27 | borderBlockEndWidth: true, 28 | borderBlockStart: true, 29 | borderBlockStartStyle: true, 30 | borderBlockStartWidth: true, 31 | borderBottom: true, 32 | borderBottomLeftRadius: true, 33 | borderBottomRightRadius: true, 34 | borderColor: true, 35 | borderImageOutset: true, 36 | borderImageRepeat: true, 37 | borderImageWidth: true, 38 | borderInlineEnd: true, 39 | borderInlineEndStyle: true, 40 | borderInlineEndWidth: true, 41 | borderInlineStart: true, 42 | borderInlineStartStyle: true, 43 | borderInlineStartWidth: true, 44 | borderLeft: true, 45 | borderRadius: true, 46 | borderRight: true, 47 | borderSpacing: true, 48 | borderStyle: true, 49 | borderTop: true, 50 | borderTopLeftRadius: true, 51 | borderTopRightRadius: true, 52 | borderWidth: true, 53 | columns: true, 54 | columnRule: true, 55 | contain: true, 56 | flex: true, 57 | flexBasis: true, 58 | flexFlow: true, 59 | gridAutoFlow: true, 60 | gridGap: true, 61 | gridTemplateAreas: true, 62 | height: true, 63 | inlineSize: true, 64 | margin: true, 65 | maskBorderOutset: true, 66 | maskBorderWidth: true, 67 | padding: true, 68 | quotes: true, 69 | rest: true, 70 | scrollSnapCoordinate: true, 71 | strokeDasharray: true, 72 | textDecoration: true, 73 | textDecorationLine: true, 74 | textDecorationSkip: true, 75 | textEmphasis: true, 76 | textEmphasisPosition: true, 77 | textEmphasisStyle: true, 78 | textIndent: true, 79 | textOverflow: true, 80 | textShadow: true, 81 | textUnderlinePosition: true, 82 | touchAction: true, 83 | transformOrigin: true, 84 | transition: true, 85 | width: true, 86 | willChange: true, 87 | } 88 | -------------------------------------------------------------------------------- /packages/bredon-validate/src/data/properties.js: -------------------------------------------------------------------------------- 1 | export default { 2 | MozAppearance: true, 3 | MozBackgroundClip: true, 4 | MozBinding: true, 5 | MozBorderBottomColors: true, 6 | MozBorderLeftColors: true, 7 | MozBorderRadiusBottomleft: true, 8 | MozBorderRadiusBottomright: true, 9 | MozBorderRadiusTopleft: true, 10 | MozBorderRadiusTopright: true, 11 | MozBorderRightColors: true, 12 | MozBorderTopColors: true, 13 | MozFloatEdge: true, 14 | MozForceBrokenImageIcon: true, 15 | MozImageRegion: true, 16 | MozOrient: true, 17 | MozOsxFontSmoothing: true, 18 | MozOutlineRadius: true, 19 | MozOutlineRadiusBottomleft: true, 20 | MozOutlineRadiusBottomright: true, 21 | MozOutlineRadiusTopleft: true, 22 | MozOutlineRadiusTopright: true, 23 | MozStackSizing: true, 24 | MozTextBlink: true, 25 | MozUserFocus: true, 26 | MozUserInput: true, 27 | MozUserModify: true, 28 | MozUserSelect: true, 29 | MozWindowDragging: true, 30 | MozWindowShadow: true, 31 | WebkitAppearance: true, 32 | WebkitBackgroundClip: true, 33 | WebkitBorderBefore: true, 34 | WebkitBorderBeforeColor: true, 35 | WebkitBorderBeforeStyle: true, 36 | WebkitBorderBeforeWidth: true, 37 | WebkitColumnBreakAfter: true, 38 | WebkitColumnBreakBefore: true, 39 | WebkitColumnBreakInside: true, 40 | WebkitFontSmoothing: true, 41 | WebkitLineCamp: true, 42 | WebkitMaskAttachment: true, 43 | WebkitMaskClip: true, 44 | WebkitMaskComposite: true, 45 | WebkitMaskOrigin: true, 46 | WebkitMaskPositionX: true, 47 | WebkitMaskPositionY: true, 48 | WebkitMaskRepeatX: true, 49 | WebkitMaskRepeatY: true, 50 | WebkitOverflowScrolling: true, 51 | WebkitPrintColorAdjust: true, 52 | WebkitTapHighlightColor: true, 53 | WebkitTextFillColor: true, 54 | WebkitTextSecurity: true, 55 | WebkitTextStrokeColor: true, 56 | WebkitTextStrokeWidth: true, 57 | WebkitTouchCallout: true, 58 | WebkitUserDrag: true, 59 | WebkitUserSelect: true, 60 | alignContent: true, 61 | alignItems: true, 62 | alignSelf: true, 63 | alignmentBaseline: true, 64 | all: true, 65 | animation: true, 66 | animationDelay: true, 67 | animationDirection: true, 68 | animationDuration: true, 69 | animationFillMode: true, 70 | animationIterationCount: true, 71 | animationName: true, 72 | animationPlayState: true, 73 | animationTimingFunction: true, 74 | appearance: true, 75 | backfaceVisibility: true, 76 | backgroundAttachment: true, 77 | backgroundBlendMode: true, 78 | backgroundClip: true, 79 | backgroundColor: true, 80 | backgroundOrigin: true, 81 | backgroundPosition: true, 82 | backgroundPositionX: true, 83 | backgroundPositionY: true, 84 | backgroundRepeat: true, 85 | baselineShift: true, 86 | behavior: true, 87 | blockSize: true, 88 | border: true, 89 | borderBlockEnd: true, 90 | borderBlockEndColor: true, 91 | borderBlockEndStyle: true, 92 | borderBlockEndWidth: true, 93 | borderBlockStart: true, 94 | borderBlockStartColor: true, 95 | borderBlockStartStyle: true, 96 | borderBlockStartWidth: true, 97 | borderBottom: true, 98 | borderBottomColor: true, 99 | borderBottomLeftRadius: true, 100 | borderBottomRightRadius: true, 101 | borderBottomStyle: true, 102 | borderBottomWidth: true, 103 | borderCollapse: true, 104 | borderColor: true, 105 | borderImageOutset: true, 106 | borderImageRepeat: true, 107 | borderImageWidth: true, 108 | borderInlineEnd: true, 109 | borderInlineEndColor: true, 110 | borderInlineEndStyle: true, 111 | borderInlineEndWidth: true, 112 | borderInlineStart: true, 113 | borderInlineStartColor: true, 114 | borderInlineStartStyle: true, 115 | borderInlineStartWidth: true, 116 | borderLeft: true, 117 | borderLeftColor: true, 118 | borderLeftStyle: true, 119 | borderLeftWidth: true, 120 | borderRadius: true, 121 | borderRight: true, 122 | borderRightColor: true, 123 | borderRightStyle: true, 124 | borderRightWidth: true, 125 | borderSpacing: true, 126 | borderStyle: true, 127 | borderTop: true, 128 | borderTopColor: true, 129 | borderTopLeftRadius: true, 130 | borderTopRightRadius: true, 131 | borderTopStyle: true, 132 | borderTopWidth: true, 133 | borderWidth: true, 134 | bottom: true, 135 | boxAlign: true, 136 | boxDecorationBreak: true, 137 | boxDirection: true, 138 | boxFlex: true, 139 | boxFlexGroup: true, 140 | boxLines: true, 141 | boxOrdinalGroup: true, 142 | boxOrient: true, 143 | boxPack: true, 144 | boxSizing: true, 145 | breakAfter: true, 146 | breakBefore: true, 147 | breakInside: true, 148 | captionSide: true, 149 | caretColor: true, 150 | clear: true, 151 | clip: true, 152 | clipPath: true, 153 | clipRule: true, 154 | color: true, 155 | columns: true, 156 | columnCount: true, 157 | columnFill: true, 158 | columnGap: true, 159 | columnRule: true, 160 | columnRuleColor: true, 161 | columnRuleStyle: true, 162 | columnRuleWidth: true, 163 | columnSpan: true, 164 | columnWidth: true, 165 | contain: true, 166 | cursor: true, 167 | direction: true, 168 | display: true, 169 | displayInside: true, 170 | displayList: true, 171 | displayOutside: true, 172 | dominantBaseline: true, 173 | emptyCells: true, 174 | fillOpacity: true, 175 | fillRule: true, 176 | flex: true, 177 | flexBasis: true, 178 | flexDirection: true, 179 | flexFlow: true, 180 | flexGrow: true, 181 | flexShrink: true, 182 | flexWrap: true, 183 | float: true, 184 | fontFamily: true, 185 | fontKerning: true, 186 | fontLanguageOverwrite: true, 187 | fontSize: true, 188 | fontSizeAdjust: true, 189 | fontStretch: true, 190 | fontStyle: true, 191 | fontVariant: true, 192 | fontVariantCaps: true, 193 | fontWeight: true, 194 | glyphOrientationHorizontal: true, 195 | glyphOrientationVertical: true, 196 | gridAutoFlow: true, 197 | gridColumnGap: true, 198 | gridGap: true, 199 | gridRowGap: true, 200 | gridTemplateAreas: true, 201 | height: true, 202 | hyphens: true, 203 | imageRendering: true, 204 | imeMode: true, 205 | initialLetterAlign: true, 206 | inlineSize: true, 207 | isolation: true, 208 | justifyContent: true, 209 | kerning: true, 210 | left: true, 211 | letterSpacing: true, 212 | lineBreak: true, 213 | lineHeight: true, 214 | listStyleImage: true, 215 | listStypePosition: true, 216 | margin: true, 217 | marginBlockEnd: true, 218 | marginBlockStart: true, 219 | marginBottom: true, 220 | marginInlineEnd: true, 221 | marginInlineStart: true, 222 | marginLeft: true, 223 | marginRight: true, 224 | marginTop: true, 225 | marker: true, 226 | markerEnd: true, 227 | markerMid: true, 228 | markerOffset: true, 229 | markerStart: true, 230 | maskBorderMode: true, 231 | maskBorderOutset: true, 232 | maskBorderRepeat: true, 233 | maskBorderSource: true, 234 | maskBorderWidth: true, 235 | maskClip: true, 236 | maskComposite: true, 237 | maskMode: true, 238 | maskOrigin: true, 239 | maskPosition: true, 240 | maskType: true, 241 | maxBlockSize: true, 242 | maxHeight: true, 243 | maxInlineSize: true, 244 | maxWidth: true, 245 | minBlockSize: true, 246 | minHeight: true, 247 | minInlineSize: true, 248 | minWidth: true, 249 | mixBlendMode: true, 250 | msFilter: true, 251 | msFlexAlign: true, 252 | msFlexItemAlign: true, 253 | msFlexLinePack: true, 254 | msFlexNegative: true, 255 | msFlexOrder: true, 256 | msFlexPack: true, 257 | msFlexPositive: true, 258 | msFlexPreferredSize: true, 259 | msGridColumnAlign: true, 260 | msGridRowAlign: true, 261 | msHighContrastAdjust: true, 262 | msInterpolationMode: true, 263 | msOverflowStyle: true, 264 | msUserSelect: true, 265 | objectFit: true, 266 | objectPosition: true, 267 | offsetBlockEnd: true, 268 | offsetBlockStart: true, 269 | offsetDistance: true, 270 | offsetInlineEnd: true, 271 | offsetInlineStart: true, 272 | offsetAnchor: true, 273 | offsetPosition: true, 274 | opacity: true, 275 | order: true, 276 | orphans: true, 277 | outlineColor: true, 278 | outlineOffset: true, 279 | outlineStyle: true, 280 | outlineWidth: true, 281 | overflow: true, 282 | overflowBreak: true, 283 | overflowClipBox: true, 284 | overflowX: true, 285 | overflowY: true, 286 | padding: true, 287 | paddingBlockEnd: true, 288 | paddingBlockStart: true, 289 | paddingBottom: true, 290 | paddingInlineEnd: true, 291 | paddingInlineStart: true, 292 | paddingLeft: true, 293 | paddingRight: true, 294 | paddingTop: true, 295 | pageBreakAfter: true, 296 | pageBreakBefore: true, 297 | pageBreakInside: true, 298 | pause: true, 299 | pauseAfter: true, 300 | pauseBefore: true, 301 | perspective: true, 302 | perspectiveOrigin: true, 303 | pointerEvents: true, 304 | position: true, 305 | resize: true, 306 | quotes: true, 307 | rest: true, 308 | restAfter: true, 309 | restBefore: true, 310 | right: true, 311 | rubyAlign: true, 312 | rubyMerge: true, 313 | rubyPosition: true, 314 | scrollBehavior: true, 315 | scrollSnapCoordinate: true, 316 | scrollSnapDestination: true, 317 | scrollSnapPointsX: true, 318 | scrollSnapPointsY: true, 319 | scrollSnapType: true, 320 | scrollSnapTypeX: true, 321 | scrollSnapTypeY: true, 322 | shapeImageThreshold: true, 323 | shapeMargin: true, 324 | shapeRendering: true, 325 | speak: true, 326 | strokeDasharray: true, 327 | strokeDashoffset: true, 328 | strokeLinecap: true, 329 | strokeLinejoin: true, 330 | strokeMiterlimit: true, 331 | strokeOpacity: true, 332 | strokeWidth: true, 333 | tabSize: true, 334 | tableLayout: true, 335 | textAlign: true, 336 | textAlignLast: true, 337 | textAnchor: true, 338 | textDecoration: true, 339 | textDecorationColor: true, 340 | textDecorationLine: true, 341 | textDecorationSkip: true, 342 | textDecorationStyle: true, 343 | textEmphasis: true, 344 | textEmphasisColor: true, 345 | textEmphasisPosition: true, 346 | textEmphasisStyle: true, 347 | textIndent: true, 348 | textJustify: true, 349 | textOrientation: true, 350 | textOverflow: true, 351 | textRendering: true, 352 | textShadow: true, 353 | textSizeAdjust: true, 354 | textUnderlinePosition: true, 355 | textTransform: true, 356 | top: true, 357 | touchAction: true, 358 | transformBox: true, 359 | transformOrigin: true, 360 | transformStyle: true, 361 | transition: true, 362 | transitionDelay: true, 363 | transitionDuration: true, 364 | transitionProperty: true, 365 | transitionTimingFunction: true, 366 | unicodeBidi: true, 367 | userSelect: true, 368 | verticalAlign: true, 369 | visibility: true, 370 | voiceBalance: true, 371 | voiceDuration: true, 372 | voiceStress: true, 373 | whiteSpace: true, 374 | widows: true, 375 | width: true, 376 | willChange: true, 377 | wordBreak: true, 378 | wordSpacing: true, 379 | wordWrap: true, 380 | writingMode: true, 381 | zIndex: true, 382 | zoom: true, 383 | } 384 | -------------------------------------------------------------------------------- /packages/bredon-validate/src/data/valueInitials.js: -------------------------------------------------------------------------------- 1 | export default { 2 | msOverflowStyle: 'auto', 3 | MozBinding: 'none', 4 | MozBorderBottomColors: 'none', 5 | MozBorderLeftColors: 'none', 6 | MozBorderRightColors: 'none', 7 | MozBorderTopColors: 'none', 8 | MozContextProperties: 'none', 9 | MozFloatEdge: 'content-box', 10 | MozForceBrokenImageIcon: '0', 11 | MozImageRegion: 'auto', 12 | MozOrient: 'inline', 13 | MozOutlineRadiusBottomleft: '0', 14 | MozOutlineRadiusBottomright: '0', 15 | MozOutlineRadiusTopleft: '0', 16 | MozOutlineRadiusTopright: '0', 17 | MozStackSizing: 'stretch-to-fit', 18 | MozTextBlink: 'none', 19 | MozUserFocus: 'none', 20 | MozUserInput: 'auto', 21 | MozUserModify: 'read-only', 22 | MozWindowDragging: 'drag', 23 | MozWindowShadow: 'default', 24 | WebkitBorderBeforeColor: 'currentcolor', 25 | WebkitBorderBeforeStyle: 'none', 26 | WebkitBorderBeforeWidth: 'medium', 27 | WebkitBoxReflect: 'none', 28 | WebkitMaskAttachment: 'scroll', 29 | WebkitMaskClip: 'border', 30 | WebkitMaskComposite: 'source-over', 31 | WebkitMaskImage: 'none', 32 | WebkitMaskOrigin: 'padding', 33 | WebkitMaskPosition: '0% 0%', 34 | WebkitMaskPositionX: '0%', 35 | WebkitMaskPositionY: '0%', 36 | WebkitMaskRepeat: 'repeat', 37 | WebkitMaskRepeatX: 'repeat', 38 | WebkitMaskRepeatY: 'repeat', 39 | WebkitOverflowScrolling: 'auto', 40 | WebkitTapHighlightColor: 'black', 41 | WebkitTextFillColor: 'currentcolor', 42 | WebkitTextStrokeColor: 'currentcolor', 43 | WebkitTextStrokeWidth: '0', 44 | WebkitTouchCallout: 'default', 45 | alignContent: 'stretch', 46 | alignItems: 'stretch', 47 | alignSelf: 'auto', 48 | animationDelay: '0', 49 | animationDirection: 'normal', 50 | animationDuration: '0', 51 | animationFillMode: 'none', 52 | animationIterationCount: '1', 53 | animationName: 'none', 54 | animationPlayState: 'running', 55 | animationTimingFunction: 'ease', 56 | appearance: 'auto', 57 | azimuth: 'center', 58 | backdropFilter: 'none', 59 | backfaceVisibility: 'visible', 60 | backgroundAttachment: 'scroll', 61 | backgroundBlendMode: 'normal', 62 | backgroundClip: 'border-box', 63 | backgroundColor: 'transparent', 64 | backgroundImage: 'none', 65 | backgroundOrigin: 'padding-box', 66 | backgroundPosition: '0% 0%', 67 | backgroundPositionX: 'left', 68 | backgroundPositionY: 'top', 69 | backgroundRepeat: 'repeat', 70 | backgroundSize: 'auto auto', 71 | blockSize: 'auto', 72 | borderBlockEndColor: 'currentcolor', 73 | borderBlockEndStyle: 'none', 74 | borderBlockEndWidth: 'medium', 75 | borderBlockStartColor: 'currentcolor', 76 | borderBlockStartStyle: 'none', 77 | borderBlockStartWidth: 'medium', 78 | borderBottomColor: 'currentcolor', 79 | borderBottomLeftRadius: '0', 80 | borderBottomRightRadius: '0', 81 | borderBottomStyle: 'none', 82 | borderBottomWidth: 'medium', 83 | borderCollapse: 'separate', 84 | borderImageOutset: '0', 85 | borderImageRepeat: 'stretch', 86 | borderImageSlice: '100%', 87 | borderImageSource: 'none', 88 | borderImageWidth: '1', 89 | borderInlineEndColor: 'currentcolor', 90 | borderInlineEndStyle: 'none', 91 | borderInlineEndWidth: 'medium', 92 | borderInlineStartColor: 'currentcolor', 93 | borderInlineStartStyle: 'none', 94 | borderInlineStartWidth: 'medium', 95 | borderLeftColor: 'currentcolor', 96 | borderLeftStyle: 'none', 97 | borderLeftWidth: 'medium', 98 | borderRightColor: 'currentcolor', 99 | borderRightStyle: 'none', 100 | borderRightWidth: 'medium', 101 | borderSpacing: '0', 102 | borderTopColor: 'currentcolor', 103 | borderTopLeftRadius: '0', 104 | borderTopRightRadius: '0', 105 | borderTopStyle: 'none', 106 | borderTopWidth: 'medium', 107 | bottom: 'auto', 108 | boxAlign: 'stretch', 109 | boxDecorationBreak: 'slice', 110 | boxDirection: 'normal', 111 | boxFlex: '0', 112 | boxFlexGroup: '1', 113 | boxLines: 'single', 114 | boxOrdinalGroup: '1', 115 | boxPack: 'start', 116 | boxShadow: 'none', 117 | boxSizing: 'content-box', 118 | breakAfter: 'auto', 119 | breakBefore: 'auto', 120 | breakInside: 'auto', 121 | captionSide: 'top', 122 | caretColor: 'auto', 123 | clear: 'none', 124 | clip: 'auto', 125 | clipPath: 'none', 126 | columnCount: 'auto', 127 | columnFill: 'balance', 128 | columnGap: 'normal', 129 | columnRuleColor: 'currentcolor', 130 | columnRuleStyle: 'none', 131 | columnRuleWidth: 'medium', 132 | columnSpan: 'none', 133 | columnWidth: 'auto', 134 | contain: 'none', 135 | content: 'normal', 136 | counterIncrement: 'none', 137 | counterReset: 'none', 138 | cursor: 'auto', 139 | direction: 'ltr', 140 | display: 'inline', 141 | displayInside: 'auto', 142 | displayList: 'none', 143 | displayOutside: 'inline-level', 144 | emptyCells: 'show', 145 | filter: 'none', 146 | flexBasis: 'auto', 147 | flexDirection: 'row', 148 | flexGrow: '0', 149 | flexShrink: '1', 150 | flexWrap: 'nowrap', 151 | float: 'none', 152 | fontFeatureSettings: 'normal', 153 | fontKerning: 'auto', 154 | fontLanguageOverride: 'normal', 155 | fontVariationSettings: 'normal', 156 | fontSize: 'medium', 157 | fontSizeAdjust: 'none', 158 | fontStretch: 'normal', 159 | fontStyle: 'normal', 160 | fontSynthesis: 'weight style', 161 | fontVariant: 'normal', 162 | fontVariantAlternates: 'normal', 163 | fontVariantCaps: 'normal', 164 | fontVariantEastAsian: 'normal', 165 | fontVariantLigatures: 'normal', 166 | fontVariantNumeric: 'normal', 167 | fontVariantPosition: 'normal', 168 | fontWeight: 'normal', 169 | gridAutoColumns: 'auto', 170 | gridAutoFlow: 'row', 171 | gridAutoRows: 'auto', 172 | gridColumnEnd: 'auto', 173 | gridColumnGap: '0', 174 | gridColumnStart: 'auto', 175 | gridRowEnd: 'auto', 176 | gridRowGap: '0', 177 | gridRowStart: 'auto', 178 | gridTemplateAreas: 'none', 179 | gridTemplateColumns: 'none', 180 | gridTemplateRows: 'none', 181 | hangingPunctuation: 'none', 182 | height: 'auto', 183 | hyphens: 'manual', 184 | imageOrientation: '0deg', 185 | imageRendering: 'auto', 186 | imageResolution: '1dppx', 187 | imeMode: 'auto', 188 | initialLetter: 'normal', 189 | initialLetterAlign: 'auto', 190 | inlineSize: 'auto', 191 | isolation: 'auto', 192 | justifyContent: 'flex-start', 193 | left: 'auto', 194 | letterSpacing: 'normal', 195 | lineBreak: 'auto', 196 | lineHeight: 'normal', 197 | lineHeightStep: 'none', 198 | listStyleImage: 'none', 199 | listStylePosition: 'outside', 200 | listStyleType: 'disc', 201 | marginBlockEnd: '0', 202 | marginBlockStart: '0', 203 | marginBottom: '0', 204 | marginInlineEnd: '0', 205 | marginInlineStart: '0', 206 | marginLeft: '0', 207 | marginRight: '0', 208 | marginTop: '0', 209 | maskBorderMode: 'alpha', 210 | maskBorderOutset: '0', 211 | maskBorderRepeat: 'stretch', 212 | maskBorderSlice: '0', 213 | maskBorderSource: 'none', 214 | maskBorderWidth: 'auto', 215 | maskClip: 'border-box', 216 | maskComposite: 'add', 217 | maskImage: 'none', 218 | maskMode: 'match-source', 219 | maskOrigin: 'border-box', 220 | maskPosition: 'center', 221 | maskRepeat: 'no-repeat', 222 | maskSize: 'auto', 223 | maskType: 'luminance', 224 | maxBlockSize: '0', 225 | maxHeight: 'none', 226 | maxInlineSize: '0', 227 | maxWidth: 'none', 228 | minBlockSize: '0', 229 | minHeight: '0', 230 | minInlineSize: '0', 231 | minWidth: '0', 232 | mixBlendMode: 'normal', 233 | objectFit: 'fill', 234 | objectPosition: '50% 50%', 235 | offsetAnchor: 'auto', 236 | offsetBlockEnd: 'auto', 237 | offsetBlockStart: 'auto', 238 | offsetInlineEnd: 'auto', 239 | offsetInlineStart: 'auto', 240 | offsetDistance: '0', 241 | offsetPath: 'none', 242 | offsetPosition: 'auto', 243 | offsetRotate: 'auto', 244 | opacity: '1.0', 245 | order: '0', 246 | orphans: '2', 247 | outlineOffset: '0', 248 | outlineStyle: 'none', 249 | outlineWidth: 'medium', 250 | overflow: 'visible', 251 | overflowClipBox: 'padding-box', 252 | overflowWrap: 'normal', 253 | overflowX: 'visible', 254 | overflowY: 'visible', 255 | paddingBlockEnd: '0', 256 | paddingBlockStart: '0', 257 | paddingBottom: '0', 258 | paddingInlineEnd: '0', 259 | paddingInlineStart: '0', 260 | paddingLeft: '0', 261 | paddingRight: '0', 262 | paddingTop: '0', 263 | pageBreakAfter: 'auto', 264 | pageBreakBefore: 'auto', 265 | pageBreakInside: 'auto', 266 | perspective: 'none', 267 | perspectiveOrigin: '50% 50%', 268 | pointerEvents: 'auto', 269 | position: 'static', 270 | resize: 'none', 271 | right: 'auto', 272 | rubyAlign: 'space-around', 273 | rubyMerge: 'separate', 274 | rubyPosition: 'over', 275 | scrollBehavior: 'auto', 276 | scrollSnapCoordinate: 'none', 277 | scrollSnapDestination: '0px 0px', 278 | scrollSnapPointsX: 'none', 279 | scrollSnapPointsY: 'none', 280 | scrollSnapType: 'none', 281 | scrollSnapTypeX: 'none', 282 | scrollSnapTypeY: 'none', 283 | shapeImageThreshold: '0.0', 284 | shapeMargin: '0', 285 | shapeOutside: 'none', 286 | tabSize: '8', 287 | tableLayout: 'auto', 288 | textAlignLast: 'auto', 289 | textCombineUpright: 'none', 290 | textDecorationColor: 'currentcolor', 291 | textDecorationLine: 'none', 292 | textDecorationSkip: 'objects', 293 | textDecorationStyle: 'solid', 294 | textEmphasisColor: 'currentcolor', 295 | textEmphasisPosition: 'over right', 296 | textEmphasisStyle: 'none', 297 | textIndent: '0', 298 | textJustify: 'auto', 299 | textOrientation: 'mixed', 300 | textOverflow: 'clip', 301 | textRendering: 'auto', 302 | textShadow: 'none', 303 | textTransform: 'none', 304 | textUnderlinePosition: 'auto', 305 | top: 'auto', 306 | touchAction: 'auto', 307 | transform: 'none', 308 | transformBox: 'border-box', 309 | transformOrigin: '50% 50% 0', 310 | transformStyle: 'flat', 311 | transitionDelay: '0', 312 | transitionDuration: '0', 313 | transitionProperty: 'all', 314 | transitionTimingFunction: 'ease', 315 | unicodeBidi: 'normal', 316 | userSelect: 'auto', 317 | verticalAlign: 'baseline', 318 | visibility: 'visible', 319 | whiteSpace: 'normal', 320 | widows: '2', 321 | width: 'auto', 322 | willChange: 'auto', 323 | wordBreak: 'normal', 324 | wordSpacing: 'normal', 325 | wordWrap: 'normal', 326 | writingMode: 'horizontal-tb', 327 | zIndex: 'auto', 328 | } 329 | -------------------------------------------------------------------------------- /packages/bredon-validate/src/data/valueListProperties.js: -------------------------------------------------------------------------------- 1 | export default { 2 | WebkitBackgroundClip: true, 3 | WebkitMaskAttachment: true, 4 | WebkitMaskClip: true, 5 | WebkitMaskComposite: true, 6 | WebkitMaskOrigin: true, 7 | WebkitMaskPositionX: true, 8 | WebkitMaskPositionY: true, 9 | animationDelay: true, 10 | animationDuration: true, 11 | backgroundPosition: true, 12 | backgroundPositionX: true, 13 | backgroundPositionY: true, 14 | animation: true, 15 | boxShadow: true, 16 | fontFamily: true, 17 | maskPosition: true, 18 | scrollSnapCoordinate: true, 19 | transition: true, 20 | transitionDelay: true, 21 | transitionDuration: true, 22 | transitionProperty: true, 23 | transitionTimingFunction: true, 24 | willChange: true, 25 | } 26 | -------------------------------------------------------------------------------- /packages/bredon-validate/src/index.js: -------------------------------------------------------------------------------- 1 | /* @flow */ 2 | import { parse, traverse } from 'bredon' 3 | import casePlugin from 'bredon-plugin-case' 4 | 5 | import isValidProperty from './isValidProperty' 6 | 7 | export default function validate(property: string, value: string): boolean { 8 | return isValidProperty(property, traverse(parse(value), [casePlugin()])) 9 | } 10 | -------------------------------------------------------------------------------- /packages/bredon-validate/src/isValidProperty.js: -------------------------------------------------------------------------------- 1 | /* @flow */ 2 | import { isValueList, isValue } from 'bredon-types' 3 | import unprefixProperty from 'css-in-js-utils/lib/unprefixProperty' 4 | 5 | import isValueListProperty from './utils/isValueListProperty' 6 | import isMultiValueProperty from './utils/isMultiValueProperty' 7 | import matchesKeyword from './utils/matchesKeyword' 8 | import arrayReduce from './utils/arrayReduce' 9 | 10 | import isGlobal from './types/isGlobal' 11 | 12 | import propertyValidators from './propertyValidators' 13 | import properties from './data/properties' 14 | import _missingProps from './data/_missingProps' 15 | 16 | const defaultValidator = () => false 17 | 18 | export default function isValidProperty( 19 | property: string, 20 | ast: any, 21 | isList?: boolean = false 22 | ): boolean { 23 | // if we do not know a property, we just skip it 24 | // and pretend its valid anyways 25 | // TODO: add valid property list 26 | if (!properties.hasOwnProperty(property)) { 27 | const unprefixedProperty = unprefixProperty(property) 28 | 29 | // we also check for prefixed properties that are 30 | // actually standard CSS properties 31 | if (properties.hasOwnProperty(unprefixedProperty)) { 32 | return isValidProperty(unprefixedProperty, ast, isList) 33 | } 34 | 35 | // TODO: remove as soon as 100% props are covered 36 | if (_missingProps.indexOf(property) !== -1) { 37 | return true 38 | } 39 | 40 | console.warn( 41 | `Unknown property: "${property}". If it is a valid CSS property, please file an issue. 42 | https://github.com/rofrischmann/bredon/issues/new` 43 | ) 44 | return true 45 | } 46 | 47 | if (isValueList(ast)) { 48 | if (ast.body.length > 1 && !isValueListProperty(property)) { 49 | // TODO: invalid warning 50 | return false 51 | } 52 | 53 | return arrayReduce( 54 | ast.body, 55 | // the property is invalid as soon as one value is invalid 56 | // TODO: do not regenerate the value 57 | (isValid, cssValue) => 58 | isValid && isValidProperty(property, cssValue, ast.body.length > 1), 59 | true 60 | ) 61 | } 62 | 63 | if (isValue(ast)) { 64 | const valueCount = ast.body.length 65 | const validator = propertyValidators[property] || defaultValidator 66 | 67 | if (valueCount > 1) { 68 | if (!isMultiValueProperty(property)) { 69 | // TODO: invalid warning 70 | return false 71 | } 72 | 73 | if (!validator) { 74 | // TODO: add warning 75 | return false 76 | } 77 | 78 | return validator(ast.body, true, isList) 79 | } 80 | 81 | const node = ast.body[0] 82 | 83 | return ( 84 | // global values are always valid 85 | isGlobal(node) || 86 | // also check for any keyword value 87 | matchesKeyword(property)(node) || 88 | // use the property validator 89 | validator(node, false, isList) 90 | ) 91 | } 92 | 93 | // TODO: true or false? 94 | // this branch can only be reached if the value was not parseable 95 | // which in general throws an error anyways 96 | return false 97 | } 98 | -------------------------------------------------------------------------------- /packages/bredon-validate/src/types/index.js: -------------------------------------------------------------------------------- 1 | import isAngle from './isAngle' 2 | import isColor from './isColor' 3 | import isCubicBezier from './isCubicBezier' 4 | import isFrames from './isFrames' 5 | import isGlobal from './isGlobal' 6 | import isImage from './isImage' 7 | import isLength from './isLength' 8 | import isLengthPercentage from './isLengthPercentage' 9 | import isNumber from './isNumber' 10 | import isOpacity from './isOpacity' 11 | import isPercentage from './isPercentage' 12 | import isPosition from './isPosition' 13 | import isRepeat from './isRepeat' 14 | import isSize from './isSize' 15 | import isSteps from './isSteps' 16 | import isSvgLength from './isSvgLength' 17 | import isTime from './isTime' 18 | 19 | export { 20 | isAngle, 21 | isColor, 22 | isCubicBezier, 23 | isFrames, 24 | isGlobal, 25 | isImage, 26 | isLength, 27 | isLengthPercentage, 28 | isNumber, 29 | isOpacity, 30 | isPercentage, 31 | isPosition, 32 | isRepeat, 33 | isSize, 34 | isSteps, 35 | isSvgLength, 36 | isTime, 37 | } 38 | -------------------------------------------------------------------------------- /packages/bredon-validate/src/types/isAngle.js: -------------------------------------------------------------------------------- 1 | import { isDimension } from 'bredon-types' 2 | 3 | const ANGLE_REGEX = /^(rad|deg|turn|grad)$/i 4 | 5 | export default function isAngle(node) { 6 | return isDimension(node) && node.unit.match(ANGLE_REGEX) !== null 7 | } 8 | -------------------------------------------------------------------------------- /packages/bredon-validate/src/types/isColor.js: -------------------------------------------------------------------------------- 1 | import { isHexColor, isIdentifier, isFunctionExpression } from 'bredon-types' 2 | 3 | import colorNames from '../data/colorNames' 4 | 5 | const COLOR_REGEX = /^(rgba?|hsla?)$/i 6 | 7 | // TODO: validation 8 | export default function isColor(node) { 9 | return ( 10 | // matches hex color values 11 | isHexColor(node) || 12 | // matches rgb, rgba, hsl, hsla color functions 13 | (isFunctionExpression(node) && node.callee.match(COLOR_REGEX) !== null) || 14 | // matches any color name 15 | (isIdentifier(node) && colorNames.indexOf(node.value) !== -1) 16 | ) 17 | } 18 | -------------------------------------------------------------------------------- /packages/bredon-validate/src/types/isCubicBezier.js: -------------------------------------------------------------------------------- 1 | import { isFunctionExpression } from 'bredon-types' 2 | 3 | import isNumber from './isNumber' 4 | import validateNodeList from '../utils/validateNodeList' 5 | 6 | export default function isCubicBezier(node) { 7 | return ( 8 | isFunctionExpression(node) && 9 | node.callee === 'cubic-bezier' && 10 | node.params.length === 4 && 11 | validateNodeList(isNumber)(node.params) 12 | ) 13 | } 14 | -------------------------------------------------------------------------------- /packages/bredon-validate/src/types/isFrames.js: -------------------------------------------------------------------------------- 1 | import { isInteger, isFunctionExpression } from 'bredon-types' 2 | 3 | export default function isFrames(node) { 4 | return ( 5 | isFunctionExpression(node) && 6 | node.callee === 'frames' && 7 | node.params.length === 1 && 8 | isInteger(node.params[0]) 9 | ) 10 | } 11 | -------------------------------------------------------------------------------- /packages/bredon-validate/src/types/isGlobal.js: -------------------------------------------------------------------------------- 1 | import { isIdentifier } from 'bredon-types' 2 | 3 | const GLOBAL_REGEX = /^(initial|inherit|unset|revert)$/i 4 | 5 | export default function isGlobal(node) { 6 | return isIdentifier(node) && node.value.match(GLOBAL_REGEX) !== null 7 | } 8 | -------------------------------------------------------------------------------- /packages/bredon-validate/src/types/isImage.js: -------------------------------------------------------------------------------- 1 | export default function isImage(node) { 2 | return node && true 3 | } 4 | -------------------------------------------------------------------------------- /packages/bredon-validate/src/types/isLength.js: -------------------------------------------------------------------------------- 1 | import { isDimension, isInteger, isFunctionExpression } from 'bredon-types' 2 | 3 | export default function isLength(node) { 4 | return ( 5 | // all dimensional values are length values 6 | (isDimension(node) && 7 | node.unit.match( 8 | /^(em|ex|ch|rem|vw|vh|vmin|vmax|cm|mm|q|in|pt|pc|px|dpi|dpcm|dppx)$/i 9 | ) !== null) || 10 | // 0 doesn't require a unit 11 | (isInteger(node) && node.value === 0) || 12 | // calc() functions are length values as well 13 | (isFunctionExpression(node) && node.callee.indexOf('calc') !== -1) 14 | ) 15 | } 16 | -------------------------------------------------------------------------------- /packages/bredon-validate/src/types/isLengthPercentage.js: -------------------------------------------------------------------------------- 1 | import isLength from './isLength' 2 | import isPercentage from './isPercentage' 3 | 4 | export default function isLengthPercentage(node) { 5 | return isLength(node) || isPercentage(node) 6 | } 7 | -------------------------------------------------------------------------------- /packages/bredon-validate/src/types/isNumber.js: -------------------------------------------------------------------------------- 1 | import { isInteger, isFloat } from 'bredon-types' 2 | 3 | export default function isNumber(node) { 4 | return isFloat(node) || isInteger(node) 5 | } 6 | -------------------------------------------------------------------------------- /packages/bredon-validate/src/types/isOpacity.js: -------------------------------------------------------------------------------- 1 | import { isInteger, isFloat } from 'bredon-types' 2 | 3 | export default function isOpacity(node) { 4 | return ( 5 | (isInteger(node) && (node.value === 1 || node.value === 0)) || 6 | (isFloat(node) && 7 | ((node.integer < 1 && node.integer >= 0 && !node.negative) || 8 | (node.integer === 1 && node.fractional === 0 && !node.negative))) 9 | ) 10 | } 11 | -------------------------------------------------------------------------------- /packages/bredon-validate/src/types/isPercentage.js: -------------------------------------------------------------------------------- 1 | import { isDimension } from 'bredon-types' 2 | 3 | export default function isPercentage(node) { 4 | return isDimension(node) && node.unit === '%' 5 | } 6 | -------------------------------------------------------------------------------- /packages/bredon-validate/src/types/isPosition.js: -------------------------------------------------------------------------------- 1 | import isLengthPercentage from './isLengthPercentage' 2 | import matchesIdentifier from '../utils/matchesIdentifier' 3 | 4 | export default function isPosition(node, isMultiValue) { 5 | if (isMultiValue) { 6 | return ( 7 | (node.length === 2 && 8 | (((isLengthPercentage(node[0]) || 9 | matchesIdentifier(['left', 'center', 'right'])(node[0])) && 10 | (isLengthPercentage(node[1]) || 11 | matchesIdentifier(['top', 'center', 'bottom'])(node[1]))) || 12 | (matchesIdentifier(['center', 'left', 'right'])(node[0]) && 13 | matchesIdentifier(['center', 'top', 'bottom'])(node[1])))) || 14 | ((node.length === 3 && 15 | (matchesIdentifier(['center', 'left', 'right'])(node[0]) && 16 | matchesIdentifier(['top', 'bottom'])(node[1]) && 17 | isLengthPercentage(node[2]))) || 18 | (matchesIdentifier(['left', 'right'])(node[0]) && 19 | isLengthPercentage(node[1]) && 20 | matchesIdentifier(['top', 'bottom', 'center'])(node[2]))) || 21 | (node.length === 4 && 22 | (matchesIdentifier(['left', 'right'])(node[0]) && 23 | isLengthPercentage(node[1]) && 24 | matchesIdentifier(['top', 'bottom'])(node[2]) && 25 | isLengthPercentage(node[3]))) 26 | ) 27 | } 28 | 29 | return ( 30 | isLengthPercentage(node) || 31 | matchesIdentifier(['left', 'center', 'right', 'top', 'bottom'])(node) 32 | ) 33 | } 34 | -------------------------------------------------------------------------------- /packages/bredon-validate/src/types/isRepeat.js: -------------------------------------------------------------------------------- 1 | import { isFunctionExpression } from 'bredon-types' 2 | 3 | import isLengthPercentage from './isLengthPercentage' 4 | 5 | export default function isRepeat(node) { 6 | return ( 7 | isFunctionExpression(node) && 8 | node.callee === 'repeat' && 9 | node.params.length === 1 && 10 | isLengthPercentage(node.params[0]) 11 | ) 12 | } 13 | -------------------------------------------------------------------------------- /packages/bredon-validate/src/types/isSize.js: -------------------------------------------------------------------------------- 1 | import isLengthPercentage from './isLengthPercentage' 2 | import matchesIdentifier from '../utils/matchesIdentifier' 3 | 4 | export default function isSize(node, isMultiValue) { 5 | if (isMultiValue) { 6 | return ( 7 | node.length === 2 && 8 | isLengthPercentage(node[0]) && 9 | matchesIdentifier(['border-box', 'content-box'])(node[1]) 10 | ) 11 | } 12 | 13 | return isLengthPercentage(node) 14 | } 15 | -------------------------------------------------------------------------------- /packages/bredon-validate/src/types/isSteps.js: -------------------------------------------------------------------------------- 1 | import { isFunctionExpression, isInteger } from 'bredon-types' 2 | 3 | import matchesIdentifier from '../utils/matchesIdentifier' 4 | 5 | export default function isSteps(node) { 6 | return ( 7 | isFunctionExpression(node) && 8 | node.callee === 'steps' && 9 | ((node.params.length === 1 && isInteger(node.params[0])) || 10 | (node.params.length === 2 && 11 | isInteger(node.params[0]) && 12 | matchesIdentifier(['start', 'end'])(node.params[1]))) 13 | ) 14 | } 15 | -------------------------------------------------------------------------------- /packages/bredon-validate/src/types/isSvgLength.js: -------------------------------------------------------------------------------- 1 | import isLength from './isLength' 2 | import isNumber from './isNumber' 3 | import isPercentage from './isPercentage' 4 | 5 | export default function isSvgLength(node) { 6 | return isLength(node) || isPercentage(node) || isNumber(node) 7 | } 8 | -------------------------------------------------------------------------------- /packages/bredon-validate/src/types/isTime.js: -------------------------------------------------------------------------------- 1 | import { isDimension } from 'bredon-types' 2 | 3 | const TIME_UNIT = /^((m)?s)$/ 4 | 5 | export default function isTime(node) { 6 | return isDimension(node) && node.unit.match(TIME_UNIT) !== null 7 | } 8 | -------------------------------------------------------------------------------- /packages/bredon-validate/src/utils/arrayReduce.js: -------------------------------------------------------------------------------- 1 | /* @flow */ 2 | export default function arrayReduce( 3 | array: Array, 4 | iterator: Function, 5 | initialValue: any 6 | ) { 7 | for (let i = 0, len = array.length; i < len; ++i) { 8 | initialValue = iterator(initialValue, array[i], i) 9 | } 10 | 11 | return initialValue 12 | } 13 | -------------------------------------------------------------------------------- /packages/bredon-validate/src/utils/isMultiValueProperty.js: -------------------------------------------------------------------------------- 1 | /* @flow */ 2 | import multiValueProperties from '../data/multiValueProperties' 3 | 4 | export default function isMultiValueProperty(property: string): boolean { 5 | return multiValueProperties[property] || false 6 | } 7 | -------------------------------------------------------------------------------- /packages/bredon-validate/src/utils/isValueListProperty.js: -------------------------------------------------------------------------------- 1 | /* @flow */ 2 | import valueListProperties from '../data/valueListProperties' 3 | 4 | export default function isValueListProperty(property: string): boolean { 5 | return valueListProperties[property] || false 6 | } 7 | -------------------------------------------------------------------------------- /packages/bredon-validate/src/utils/matchesIdentifier.js: -------------------------------------------------------------------------------- 1 | import { isIdentifier } from 'bredon-types' 2 | 3 | export default function matchesIdentifier(identifiers) { 4 | return node => 5 | // the value needs to be an identifier 6 | isIdentifier(node) && 7 | // if the value is an actual property keyword 8 | identifiers.indexOf(node.value.toLowerCase()) !== -1 9 | } 10 | -------------------------------------------------------------------------------- /packages/bredon-validate/src/utils/matchesKeyword.js: -------------------------------------------------------------------------------- 1 | import { isIdentifier } from 'bredon-types' 2 | 3 | import valueKeywords from '../data/valueKeywords' 4 | 5 | export default function matchesKeyword(property) { 6 | return node => 7 | // the value needs to be an identifier 8 | isIdentifier(node) && 9 | // only match if the property has keyword values 10 | valueKeywords[property] && 11 | // if the value is an actual property keyword 12 | valueKeywords[property].indexOf(node.value.toLowerCase()) !== -1 13 | } 14 | -------------------------------------------------------------------------------- /packages/bredon-validate/src/utils/normalizeNodeList.js: -------------------------------------------------------------------------------- 1 | export default function normalizeNodeList(nodes, isMultiValue) { 2 | return isMultiValue ? nodes : [nodes] 3 | } 4 | -------------------------------------------------------------------------------- /packages/bredon-validate/src/utils/validateNodeList.js: -------------------------------------------------------------------------------- 1 | import arrayReduce from './arrayReduce' 2 | 3 | export default function validateNodeList(validator, maxLength) { 4 | return nodes => { 5 | if (maxLength && nodes.length > maxLength) { 6 | return false 7 | } 8 | 9 | return arrayReduce( 10 | nodes, 11 | (isValid, singleNode) => isValid && validator(singleNode), 12 | true 13 | ) 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /packages/bredon-validate/src/utils/validateUnorderedNodeList.js: -------------------------------------------------------------------------------- 1 | import arrayReduce from './arrayReduce' 2 | 3 | export default function validateUnorderedNodeList(validators) { 4 | return nodes => 5 | arrayReduce( 6 | nodes, 7 | (isValid, singleNode) => { 8 | const matchedValidator = validators.find(validator => 9 | validator(singleNode) 10 | ) 11 | 12 | if (matchedValidator) { 13 | validators.splice(validators.indexOf(matchedValidator), 1) 14 | return isValid && true 15 | } 16 | 17 | return false 18 | }, 19 | true 20 | ) 21 | } 22 | -------------------------------------------------------------------------------- /packages/bredon-validate/yarn.lock: -------------------------------------------------------------------------------- 1 | # THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. 2 | # yarn lockfile v1 3 | 4 | 5 | ansi-styles@^3.1.0: 6 | version "3.2.0" 7 | resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.0.tgz#c159b8d5be0f9e5a6f346dab94f16ce022161b88" 8 | dependencies: 9 | color-convert "^1.9.0" 10 | 11 | bredon-types@^3.0.0: 12 | version "3.0.0" 13 | resolved "https://registry.yarnpkg.com/bredon-types/-/bredon-types-3.0.0.tgz#1d49122f12df2c2868ba3065e27eede76b5af93e" 14 | 15 | bredon-validate@^0.0.2: 16 | version "0.0.2" 17 | resolved "https://registry.yarnpkg.com/bredon-validate/-/bredon-validate-0.0.2.tgz#a845d9ce0d5e6798fe51216a8a058c159fcfefe8" 18 | dependencies: 19 | bredon "^3.0.1" 20 | bredon-types "^3.0.0" 21 | 22 | bredon@^3.0.1: 23 | version "3.0.1" 24 | resolved "https://registry.yarnpkg.com/bredon/-/bredon-3.0.1.tgz#42d101c8dd7c6fca42ff4106a54049ff935d6cac" 25 | dependencies: 26 | bredon-types "^3.0.0" 27 | tokenize-sync "^1.0.0" 28 | 29 | chalk@^2.0.1, chalk@^2.3.0: 30 | version "2.3.0" 31 | resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.3.0.tgz#b5ea48efc9c1793dccc9b4767c93914d3f2d52ba" 32 | dependencies: 33 | ansi-styles "^3.1.0" 34 | escape-string-regexp "^1.0.5" 35 | supports-color "^4.0.0" 36 | 37 | color-convert@^1.9.0: 38 | version "1.9.1" 39 | resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.1.tgz#c1261107aeb2f294ebffec9ed9ecad529a6097ed" 40 | dependencies: 41 | color-name "^1.1.1" 42 | 43 | color-name@^1.1.1: 44 | version "1.1.3" 45 | resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25" 46 | 47 | css-in-js-utils@^2.0.0: 48 | version "2.0.0" 49 | resolved "https://registry.yarnpkg.com/css-in-js-utils/-/css-in-js-utils-2.0.0.tgz#5af1dd70f4b06b331f48d22a3d86e0786c0b9435" 50 | dependencies: 51 | hyphenate-style-name "^1.0.2" 52 | 53 | escape-string-regexp@^1.0.5: 54 | version "1.0.5" 55 | resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" 56 | 57 | has-flag@^2.0.0: 58 | version "2.0.0" 59 | resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-2.0.0.tgz#e8207af1cc7b30d446cc70b734b5e8be18f88d51" 60 | 61 | hyphenate-style-name@^1.0.2: 62 | version "1.0.2" 63 | resolved "https://registry.yarnpkg.com/hyphenate-style-name/-/hyphenate-style-name-1.0.2.tgz#31160a36930adaf1fc04c6074f7eb41465d4ec4b" 64 | 65 | lodash@^4.17.4: 66 | version "4.17.4" 67 | resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.4.tgz#78203a4d1c328ae1d86dca6460e369b57f4055ae" 68 | 69 | log-symbols@^2.0.0: 70 | version "2.1.0" 71 | resolved "https://registry.yarnpkg.com/log-symbols/-/log-symbols-2.1.0.tgz#f35fa60e278832b538dc4dddcbb478a45d3e3be6" 72 | dependencies: 73 | chalk "^2.0.1" 74 | 75 | postcss-bredon-validate@^0.0.1: 76 | version "0.0.1" 77 | resolved "https://registry.yarnpkg.com/postcss-bredon-validate/-/postcss-bredon-validate-0.0.1.tgz#4faab0550f233342dce0110fcf898da5e440c796" 78 | dependencies: 79 | bredon-validate "^0.0.2" 80 | css-in-js-utils "^2.0.0" 81 | postcss "^6.0.14" 82 | 83 | postcss-reporter@^5.0.0: 84 | version "5.0.0" 85 | resolved "https://registry.yarnpkg.com/postcss-reporter/-/postcss-reporter-5.0.0.tgz#a14177fd1342829d291653f2786efd67110332c3" 86 | dependencies: 87 | chalk "^2.0.1" 88 | lodash "^4.17.4" 89 | log-symbols "^2.0.0" 90 | postcss "^6.0.8" 91 | 92 | postcss@^6.0.14, postcss@^6.0.8: 93 | version "6.0.14" 94 | resolved "https://registry.yarnpkg.com/postcss/-/postcss-6.0.14.tgz#5534c72114739e75d0afcf017db853099f562885" 95 | dependencies: 96 | chalk "^2.3.0" 97 | source-map "^0.6.1" 98 | supports-color "^4.4.0" 99 | 100 | source-map@^0.6.1: 101 | version "0.6.1" 102 | resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263" 103 | 104 | supports-color@^4.0.0, supports-color@^4.4.0: 105 | version "4.5.0" 106 | resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-4.5.0.tgz#be7a0de484dec5c5cddf8b3d59125044912f635b" 107 | dependencies: 108 | has-flag "^2.0.0" 109 | 110 | tokenize-sync@^1.0.0: 111 | version "1.0.0" 112 | resolved "https://registry.yarnpkg.com/tokenize-sync/-/tokenize-sync-1.0.0.tgz#65b5b72bb208b013166e4d253e0b8b4990c70e83" 113 | -------------------------------------------------------------------------------- /packages/bredon/README.md: -------------------------------------------------------------------------------- 1 | # bredon 2 | 3 | NPM package to get access to Bredon's API.
4 | Check out the [Bredon repository](https://github.com/rofrischmann/bredon) for further information. 5 | -------------------------------------------------------------------------------- /packages/bredon/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "bredon", 3 | "version": "4.0.0", 4 | "description": "A modern CSS value compiler in JavaScript", 5 | "main": "lib/index.js", 6 | "module": "es/index.js", 7 | "jsnext:main": "es/index.js", 8 | "files": [ 9 | "LICENSE", 10 | "README.md", 11 | "lib/**", 12 | "es/**" 13 | ], 14 | "keywords": [ 15 | "css", 16 | "parser", 17 | "css-parser", 18 | "css-value-parser", 19 | "compiler", 20 | "css-compiler", 21 | "ast", 22 | "lexer", 23 | "tokenizer", 24 | "cssinjs" 25 | ], 26 | "repository": "https://github.com/rofrischmann/bredon.git", 27 | "author": "Robin Frischmann ", 28 | "license": "MIT", 29 | "dependencies": { 30 | "bredon-types": "^3.0.1", 31 | "tokenize-sync": "^2.0.0" 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /packages/bredon/src/Generator.js: -------------------------------------------------------------------------------- 1 | /* @flow */ 2 | import type { ASTNode } from '../../../flowtypes/AST' 3 | 4 | export default class Generator { 5 | generators: Object 6 | 7 | constructor(generators?: Object = {}) { 8 | this.generators = generators 9 | } 10 | 11 | generate(node: ASTNode): string { 12 | const generateValue = this.generate.bind(this) 13 | const customGenerator = this.generators[node.type] 14 | 15 | if (customGenerator) { 16 | return customGenerator(node, generateValue) 17 | } 18 | 19 | switch (node.type) { 20 | case 'ValueList': 21 | return node.body.map(generateValue).join(', ') 22 | 23 | case 'Value': 24 | return ( 25 | node.body.map(generateValue).join(' ') + 26 | (node.ie_only ? '\\' + node.ie_only : '') + 27 | (node.important ? '!important' : '') 28 | ) 29 | 30 | case 'Expression': 31 | return node.body.map(generateValue).join('') 32 | 33 | case 'FunctionExpression': 34 | return `${node.callee}(${node.params.map(generateValue).join(', ')})` 35 | 36 | case 'Dimension': 37 | return generateValue(node.value) + node.unit 38 | 39 | case 'Integer': 40 | return `${node.negative ? '-' : ''}${node.value}` 41 | 42 | case 'Float': 43 | return `${node.negative 44 | ? '-' 45 | : ''}${node.integer}${node.fractional.toString().slice(1)}` 46 | 47 | case 'Operator': 48 | // for addition and substraction we use spacings left and right 49 | // to ensure correct syntax inside calc expressions 50 | return node.value === '+' || node.value === '-' 51 | ? ` ${node.value} ` 52 | : node.value 53 | 54 | case 'Assignment': 55 | return `${node.name}+${generateValue(node.value)}` 56 | 57 | case 'StringLiteral': 58 | return node.quote + node.value + node.quote 59 | 60 | case 'HexColor': 61 | return '#' + node.value 62 | 63 | case 'Identifier': 64 | case 'Parenthesis': 65 | case 'Separator': 66 | case 'URL': 67 | return node.value 68 | 69 | default: 70 | return '' 71 | } 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /packages/bredon/src/Traverser.js: -------------------------------------------------------------------------------- 1 | /* @flow */ 2 | import normalizeVisitors from './utils/normalizeVisitors' 3 | import createPath from './utils/createPath' 4 | 5 | import type { ASTNode } from '../../../flowtypes/AST' 6 | import type { Path } from '../../../flowtypes/Path' 7 | 8 | export default class Traverser { 9 | visitors: Object 10 | context: Object 11 | 12 | constructor(visitors?: Array = [], context?: Object = {}) { 13 | this.visitors = normalizeVisitors(visitors) 14 | this.context = context 15 | } 16 | 17 | traverseNodeList( 18 | visitor: Object, 19 | nodeList: Array, 20 | parentPath: Path 21 | ) { 22 | nodeList.forEach(childNode => 23 | this.traverseNode(visitor, childNode, parentPath) 24 | ) 25 | } 26 | 27 | traverseNode(visitor: Object, node: ASTNode, parentPath: Path) { 28 | const methods = visitor[node.type] 29 | 30 | const nodePath = createPath(node, parentPath, this.context) 31 | 32 | if (methods && methods.enter) { 33 | methods.enter(nodePath) 34 | } 35 | 36 | switch (node.type) { 37 | case 'Value': 38 | case 'ValueList': 39 | case 'Expression': 40 | this.traverseNodeList(visitor, node.body, nodePath) 41 | break 42 | 43 | case 'FunctionExpression': 44 | this.traverseNodeList(visitor, node.params, nodePath) 45 | break 46 | 47 | case 'Dimension': 48 | case 'Assignment': 49 | this.traverseNode(visitor, node.value, nodePath) 50 | break 51 | 52 | case 'Integer': 53 | case 'Float': 54 | case 'Identifier': 55 | case 'Operator': 56 | case 'Separator': 57 | case 'HexColor': 58 | case 'StringLiteral': 59 | case 'URL': 60 | break 61 | 62 | default: 63 | throw new TypeError(`Unkown Type ${node.type}`) 64 | } 65 | 66 | if (methods && methods.exit) { 67 | methods.exit(nodePath) 68 | } 69 | } 70 | 71 | traverse(ast: ASTNode): ASTNode { 72 | this.visitors.forEach(visitor => 73 | this.traverseNode(visitor, ast, createPath(ast, undefined, this.context)) 74 | ) 75 | return ast 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /packages/bredon/src/__tests__/Generator-test.js: -------------------------------------------------------------------------------- 1 | import Generator from '../Generator' 2 | 3 | describe('Generating a string from an AST', () => { 4 | it('should return a pretty strings', () => { 5 | const generator = new Generator() 6 | 7 | expect( 8 | generator.generate({ 9 | body: [ 10 | { 11 | body: [ 12 | { 13 | type: 'FunctionExpression', 14 | callee: 'calc', 15 | params: [ 16 | { 17 | type: 'Expression', 18 | body: [ 19 | { 20 | type: 'Dimension', 21 | value: { 22 | type: 'Integer', 23 | negative: false, 24 | value: 100, 25 | }, 26 | unit: 'px', 27 | }, 28 | { 29 | type: 'Operator', 30 | value: '/', 31 | }, 32 | { 33 | type: 'Integer', 34 | negative: false, 35 | value: 2, 36 | }, 37 | { 38 | type: 'Operator', 39 | value: '+', 40 | }, 41 | { 42 | type: 'Dimension', 43 | value: { 44 | type: 'Integer', 45 | negative: false, 46 | value: 5, 47 | }, 48 | unit: 'px', 49 | }, 50 | ], 51 | }, 52 | ], 53 | }, 54 | { 55 | type: 'Identifier', 56 | value: 'inherit', 57 | }, 58 | { 59 | type: 'FunctionExpression', 60 | callee: 'rgba', 61 | params: [ 62 | { 63 | type: 'Integer', 64 | negative: false, 65 | value: 255, 66 | }, 67 | { 68 | type: 'Integer', 69 | negative: false, 70 | value: 94, 71 | }, 72 | { 73 | type: 'Float', 74 | integer: 0, 75 | fractional: 0.34, 76 | negative: false, 77 | }, 78 | ], 79 | }, 80 | ], 81 | type: 'Value', 82 | }, 83 | { 84 | body: [ 85 | { 86 | type: 'Dimension', 87 | unit: 'ms', 88 | value: { 89 | type: 'Integer', 90 | negative: false, 91 | value: 300, 92 | }, 93 | }, 94 | { 95 | type: 'Identifier', 96 | value: 'all', 97 | }, 98 | { 99 | type: 'Identifier', 100 | value: 'linear', 101 | }, 102 | ], 103 | type: 'Value', 104 | }, 105 | ], 106 | type: 'ValueList', 107 | }) 108 | ).toBe('calc(100px/2 + 5px) inherit rgba(255, 94, 0.34), 300ms all linear') 109 | 110 | expect( 111 | generator.generate({ 112 | type: 'Value', 113 | body: [ 114 | { 115 | type: 'StringLiteral', 116 | value: "I'm a string.", 117 | quote: '"', 118 | }, 119 | ], 120 | }) 121 | ).toBe('"I\'m a string."') 122 | }) 123 | 124 | it('should use custom formatters', () => { 125 | const generator = new Generator({ 126 | FunctionExpression: (node, generate) => 127 | `${node.callee}(${node.params.map(generate).join(' , ')})`, 128 | }) 129 | 130 | expect( 131 | generator.generate({ 132 | type: 'Value', 133 | body: [ 134 | { 135 | type: 'FunctionExpression', 136 | callee: 'rgba', 137 | params: [ 138 | { 139 | type: 'Integer', 140 | negative: false, 141 | value: 255, 142 | }, 143 | { 144 | type: 'Integer', 145 | negative: false, 146 | value: 0, 147 | }, 148 | { 149 | type: 'Integer', 150 | negative: true, 151 | value: 255, 152 | }, 153 | { 154 | type: 'Float', 155 | integer: 0, 156 | fractional: 0.55, 157 | negative: true, 158 | }, 159 | ], 160 | }, 161 | ], 162 | }) 163 | ).toBe('rgba(255 , 0 , -255 , -0.55)') 164 | }) 165 | }) 166 | -------------------------------------------------------------------------------- /packages/bredon/src/__tests__/Parser-test.js: -------------------------------------------------------------------------------- 1 | import Parser from '../Parser' 2 | 3 | describe('Parsing CSS values', () => { 4 | it('should correctly parse unknown input', () => { 5 | const parser = new Parser() 6 | 7 | expect(['"メイリオ"', parser.parse('"メイリオ"')]).toMatchSnapshot() 8 | expect(['メイリオ', parser.parse('メイリオ')]).toMatchSnapshot() 9 | }) 10 | 11 | it('should correctly parse identifiers', () => { 12 | const parser = new Parser() 13 | 14 | expect(['flex-start', parser.parse('flex-start')]).toMatchSnapshot() 15 | expect([ 16 | 'progid:DXImageTransform.Microsoft.gradient', 17 | parser.parse('progid:DXImageTransform.Microsoft.gradient'), 18 | ]).toMatchSnapshot() 19 | }) 20 | 21 | it('should correctly parse ie hacks', () => { 22 | const parser = new Parser() 23 | 24 | expect(['100%\\9', parser.parse('100%\\9')]).toMatchSnapshot() 25 | }) 26 | 27 | it('should correctly parse integers', () => { 28 | const parser = new Parser() 29 | 30 | expect(['400', parser.parse('400')]).toMatchSnapshot() 31 | }) 32 | 33 | it('should correctly parse !important', () => { 34 | const parser = new Parser() 35 | 36 | expect(['3px !important', parser.parse('3px !important')]).toMatchSnapshot() 37 | }) 38 | 39 | it('should correctly parse algebraic signs', () => { 40 | const parser = new Parser() 41 | 42 | expect(['-400', parser.parse('-400')]).toMatchSnapshot() 43 | }) 44 | 45 | it('should correctly parse parentheses', () => { 46 | const parser = new Parser() 47 | 48 | expect(['(', parser.parse('(')]).toMatchSnapshot() 49 | }) 50 | 51 | it('should correctly parse HexColors', () => { 52 | const parser = new Parser() 53 | 54 | expect(['#66FF66', parser.parse('#66FF66')]).toMatchSnapshot() 55 | }) 56 | 57 | it('should correctly parse strings', () => { 58 | const parser = new Parser() 59 | 60 | expect([ 61 | '"hello, it\'s me."', 62 | parser.parse('"hello, it\'s me."'), 63 | ]).toMatchSnapshot() 64 | }) 65 | 66 | it('should correctly parse dimensions', () => { 67 | const parser = new Parser() 68 | 69 | expect(['300px', parser.parse('300px')]).toMatchSnapshot() 70 | expect(['-33.33%', parser.parse('-33.33%')]).toMatchSnapshot() 71 | }) 72 | 73 | it('should correctly parse floats', () => { 74 | const parser = new Parser() 75 | 76 | expect(['200.55', parser.parse('200.55')]).toMatchSnapshot() 77 | 78 | expect(['-.55', parser.parse('-.55')]).toMatchSnapshot() 79 | }) 80 | 81 | it('should correctly parse function expressions', () => { 82 | const parser = new Parser() 83 | 84 | expect(['rgba(200,300)', parser.parse('rgba(200,300)')]).toMatchSnapshot() 85 | expect([ 86 | 'progid:DXImageTransform.Microsoft.gradient(opacity=0.9, color="red", M21=3)', 87 | parser.parse( 88 | 'progid:DXImageTransform.Microsoft.gradient(opacity=0.9, color="red", M21=3)' 89 | ), 90 | ]).toMatchSnapshot() 91 | }) 92 | 93 | it('should correctly parse assigments inside function expressions', () => { 94 | const parser = new Parser() 95 | 96 | expect([ 97 | 'alpha(opacity=90)', 98 | parser.parse('alpha(opacity=90)'), 99 | ]).toMatchSnapshot() 100 | 101 | expect([ 102 | 'alpha(opacity=90, color="red")', 103 | parser.parse('alpha(opacity=90, color="red")'), 104 | ]).toMatchSnapshot() 105 | }) 106 | 107 | it('should correctly parse URLs', () => { 108 | const parser = new Parser() 109 | 110 | expect([ 111 | 'url(https://www.google.de/request#something?param=true&foo=bar%20)', 112 | parser.parse( 113 | 'url(https://www.google.de/request#something?param=true&foo=bar%20)' 114 | ), 115 | ]).toMatchSnapshot() 116 | }) 117 | 118 | it('should correctly parse expressions', () => { 119 | const parser = new Parser() 120 | 121 | expect(['calc(100%+5/2)', parser.parse('calc(100%+5/2)')]).toMatchSnapshot() 122 | }) 123 | 124 | it('should correctly skip whitespaces', () => { 125 | const parser = new Parser() 126 | 127 | expect(['300 400 700', parser.parse('300 400 700')]).toMatchSnapshot() 128 | 129 | expect([ 130 | ' 1px inherit rgba( 255 , 94 , 0.34 ) , 300ms all linear ', 131 | parser.parse( 132 | ' 1px inherit rgba( 255 , 94 , 0.34 ) , 300ms all linear ' 133 | ), 134 | ]).toMatchSnapshot() 135 | }) 136 | 137 | // complex test 138 | it('should return a correct AST', () => { 139 | const parser = new Parser() 140 | 141 | expect([ 142 | '1px inherit rgba(255, 94, 0.34), 300ms all linear', 143 | parser.parse('1px inherit rgba(255, 94, 0.34), 300ms all linear'), 144 | ]).toMatchSnapshot() 145 | }) 146 | }) 147 | -------------------------------------------------------------------------------- /packages/bredon/src/__tests__/Traverser-test.js: -------------------------------------------------------------------------------- 1 | import Traverser from '../Traverser' 2 | 3 | describe('Traversing CSS values', () => { 4 | it('should correctly traverse ast nodes', () => { 5 | const visitor = ({ types }) => ({ 6 | Identifier(path) { 7 | if (path.node.value === 'flex-start') { 8 | path.replaceNode(types.identifier('flex-end')) 9 | } 10 | }, 11 | }) 12 | 13 | const traverser = new Traverser([visitor]) 14 | 15 | expect( 16 | traverser.traverse({ 17 | body: [ 18 | { 19 | type: 'Identifier', 20 | value: 'flex-start', 21 | }, 22 | ], 23 | important: false, 24 | type: 'Value', 25 | }) 26 | ).toEqual({ 27 | body: [ 28 | { 29 | type: 'Identifier', 30 | value: 'flex-end', 31 | }, 32 | ], 33 | important: false, 34 | type: 'Value', 35 | }) 36 | }) 37 | 38 | it('should correctly remove a value', () => { 39 | const visitor = { 40 | Identifier(path) { 41 | if (path.node.value === 'flex-start') { 42 | path.removeNode() 43 | } 44 | }, 45 | } 46 | 47 | const traverser = new Traverser([visitor]) 48 | 49 | expect( 50 | traverser.traverse({ 51 | body: [ 52 | { 53 | type: 'Identifier', 54 | value: 'flex-start', 55 | }, 56 | { 57 | type: 'Identifier', 58 | value: 'flex-end', 59 | }, 60 | ], 61 | important: false, 62 | type: 'Value', 63 | }) 64 | ).toEqual({ 65 | body: [ 66 | { 67 | type: 'Identifier', 68 | value: 'flex-end', 69 | }, 70 | ], 71 | important: false, 72 | type: 'Value', 73 | }) 74 | }) 75 | 76 | it('should correctly merge visitors from left to right', () => { 77 | const visitor = ({ types }) => ({ 78 | Identifier(path) { 79 | if (path.node.value === 'flex-start') { 80 | path.replaceNode(types.identifier('flex-end')) 81 | } 82 | }, 83 | }) 84 | 85 | const visitor2 = { 86 | Identifier(path) { 87 | if (path.node.value === 'flex-end') { 88 | path.node.value += '-test' 89 | } 90 | }, 91 | } 92 | 93 | const traverser = new Traverser([visitor, visitor2]) 94 | 95 | expect( 96 | traverser.traverse({ 97 | body: [ 98 | { 99 | type: 'Identifier', 100 | value: 'flex-start', 101 | }, 102 | ], 103 | important: false, 104 | type: 'Value', 105 | }) 106 | ).toEqual({ 107 | body: [ 108 | { 109 | type: 'Identifier', 110 | value: 'flex-end-test', 111 | }, 112 | ], 113 | important: false, 114 | type: 'Value', 115 | }) 116 | }) 117 | 118 | it('should correctly traverse nested nodes', () => { 119 | const visitor = { 120 | FunctionExpression(path) { 121 | if (path.node.callee === 'foo') { 122 | path.node.callee = 'buz' 123 | 124 | path.traverse({ 125 | Identifier(innerPath) { 126 | if (innerPath.node.value === 'bar') { 127 | innerPath.node.value = 'baz' 128 | } 129 | }, 130 | }) 131 | } 132 | }, 133 | } 134 | 135 | const traverser = new Traverser([visitor]) 136 | 137 | expect( 138 | traverser.traverse({ 139 | type: 'Value', 140 | body: [ 141 | { 142 | type: 'FunctionExpression', 143 | callee: 'foo', 144 | params: [ 145 | { 146 | type: 'Identifier', 147 | value: 'bar', 148 | }, 149 | { 150 | type: 'Identifier', 151 | value: 'baz', 152 | }, 153 | ], 154 | }, 155 | { 156 | type: 'Identifier', 157 | value: 'bar', 158 | }, 159 | ], 160 | }) 161 | ).toEqual({ 162 | type: 'Value', 163 | body: [ 164 | { 165 | type: 'FunctionExpression', 166 | callee: 'buz', 167 | params: [ 168 | { 169 | type: 'Identifier', 170 | value: 'baz', 171 | }, 172 | { 173 | type: 'Identifier', 174 | value: 'baz', 175 | }, 176 | ], 177 | }, 178 | { 179 | type: 'Identifier', 180 | value: 'bar', 181 | }, 182 | ], 183 | }) 184 | }) 185 | 186 | it('should correctly enter and exit nodes', () => { 187 | const visitor = { 188 | Identifier: { 189 | enter(path) { 190 | path.node.value = 'entered' 191 | }, 192 | exit(path) { 193 | path.node.value += ':exited' 194 | }, 195 | }, 196 | } 197 | 198 | const traverser = new Traverser([visitor]) 199 | 200 | expect( 201 | traverser.traverse({ 202 | body: [ 203 | { 204 | type: 'Identifier', 205 | value: '', 206 | }, 207 | ], 208 | important: false, 209 | type: 'Value', 210 | }) 211 | ).toEqual({ 212 | body: [ 213 | { 214 | type: 'Identifier', 215 | value: 'entered:exited', 216 | }, 217 | ], 218 | important: false, 219 | type: 'Value', 220 | }) 221 | }) 222 | }) 223 | -------------------------------------------------------------------------------- /packages/bredon/src/index.js: -------------------------------------------------------------------------------- 1 | /* @flow */ 2 | import * as types from 'bredon-types' 3 | 4 | import Parser from './Parser' 5 | import Traverser from './Traverser' 6 | import Generator from './Generator' 7 | 8 | import type { AST } from '../../../flowtypes/AST' 9 | 10 | type TransformOptions = { 11 | plugins?: Array, 12 | generators?: Object, 13 | context?: Object, 14 | } 15 | 16 | function parse(input: string): AST { 17 | const parser = new Parser() 18 | return parser.parse(input) 19 | } 20 | 21 | function generate(ast: AST, generators?: Object = {}): string { 22 | const generator = new Generator(generators) 23 | return generator.generate(ast) 24 | } 25 | 26 | function traverse( 27 | ast: AST, 28 | visitors?: Array = [], 29 | context?: Object = {} 30 | ): void { 31 | const traverser = new Traverser(visitors, context) 32 | return traverser.traverse(ast) 33 | } 34 | 35 | function compile(input: string, options: TransformOptions = {}): string { 36 | return generate( 37 | traverse(parse(input), options.plugins, options.context), 38 | options.generators 39 | ) 40 | } 41 | 42 | export { parse, generate, traverse, compile, types } 43 | -------------------------------------------------------------------------------- /packages/bredon/src/utils/arrayReduce.js: -------------------------------------------------------------------------------- 1 | /* @flow */ 2 | export default function arrayReduce( 3 | array: Array, 4 | iterator: Function, 5 | initialValue: any 6 | ) { 7 | for (let i = 0, len = array.length; i < len; ++i) { 8 | initialValue = iterator(initialValue, array[i]) 9 | } 10 | 11 | return initialValue 12 | } 13 | -------------------------------------------------------------------------------- /packages/bredon/src/utils/createPath.js: -------------------------------------------------------------------------------- 1 | /* @flow */ 2 | import { traverse } from '../index' 3 | 4 | import type { ASTNode } from '../../../../flowtypes/AST' 5 | import type { Path } from '../../../../flowtypes/Path' 6 | 7 | export default function createPath( 8 | node: ASTNode, 9 | parentPath?: Path, 10 | context?: Object = {} 11 | ): Path { 12 | const traverser = visitors => traverse(node, [].concat(visitors), context) 13 | 14 | const restoredParentPath = parentPath || context.parentPath 15 | // if we don't have a parentPath (AST entry) 16 | // we can't have replaceNode, removeNode, parent and parentNode 17 | if (!restoredParentPath) { 18 | return { 19 | node, 20 | context, 21 | traverse: traverser, 22 | } 23 | } 24 | 25 | const parentNode = restoredParentPath.node 26 | const container = parentNode.body || parentNode.params 27 | 28 | const path = { 29 | parentPath: restoredParentPath, 30 | parent: parentNode, 31 | node, 32 | context, 33 | traverse: traverser, 34 | replaceNode(newNode: ASTNode): void { 35 | if (container) { 36 | const nodeIndex = container.indexOf(node) 37 | container[nodeIndex] = newNode 38 | path.node = newNode 39 | } 40 | }, 41 | removeNode(): void { 42 | if (container) { 43 | const nodeIndex = container.indexOf(node) 44 | container.splice(nodeIndex, 1) 45 | } 46 | }, 47 | } 48 | 49 | return path 50 | } 51 | -------------------------------------------------------------------------------- /packages/bredon/src/utils/getQuote.js: -------------------------------------------------------------------------------- 1 | /* @flow */ 2 | /* eslint-disable consistent-return */ 3 | const SINGLE_QUOTE = /^('|\\')$/ 4 | const DOUBLE_QUOTE = /^("|\\")$/ 5 | 6 | export default function getQuoteType(quote: string): ?string { 7 | if (quote.match(SINGLE_QUOTE) !== null) { 8 | return "'" 9 | } 10 | 11 | if (quote.match(DOUBLE_QUOTE) !== null) { 12 | return '"' 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /packages/bredon/src/utils/isValidHexadezimal.js: -------------------------------------------------------------------------------- 1 | /* @flow */ 2 | export default function isValidHexadezimal(value: string): boolean { 3 | return value.match(/^[0-9a-f]$/i) !== null 4 | } 5 | -------------------------------------------------------------------------------- /packages/bredon/src/utils/isValidUnit.js: -------------------------------------------------------------------------------- 1 | /* @flow */ 2 | export default function isValidUnit(value: string): boolean { 3 | return ( 4 | value.match( 5 | /^(%|em|ex|ch|rem|vw|vh|vmin|vmax|cm|mm|q|in|pt|pc|px|deg|grad|rad|turn|(m)?s|(k)?Hz|dpi|dpcm|dppx)$/i 6 | ) !== null 7 | ) 8 | } 9 | -------------------------------------------------------------------------------- /packages/bredon/src/utils/normalizeVisitors.js: -------------------------------------------------------------------------------- 1 | /* @flow */ 2 | import * as bredon from '../index' 3 | 4 | import arrayReduce from './arrayReduce' 5 | 6 | export default function normalizeVisitors( 7 | visitors: Array 8 | ): Object { 9 | return arrayReduce( 10 | visitors, 11 | (normalizedVisitors, visitor) => { 12 | const resolvedVisitor = 13 | typeof visitor === 'function' ? visitor(bredon) : visitor 14 | 15 | Object.keys(resolvedVisitor).forEach(nodeType => { 16 | const normalizedVisitor = resolvedVisitor[nodeType] 17 | 18 | if (typeof normalizedVisitor === 'function') { 19 | resolvedVisitor[nodeType] = { 20 | enter(path) { 21 | normalizedVisitor(path) 22 | }, 23 | } 24 | } 25 | }) 26 | 27 | normalizedVisitors.push(resolvedVisitor) 28 | return normalizedVisitors 29 | }, 30 | [] 31 | ) 32 | } 33 | -------------------------------------------------------------------------------- /packages/bredon/yarn.lock: -------------------------------------------------------------------------------- 1 | # THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. 2 | # yarn lockfile v1 3 | 4 | 5 | tokenize-sync@^2.0.0: 6 | version "2.0.0" 7 | resolved "https://registry.yarnpkg.com/tokenize-sync/-/tokenize-sync-2.0.0.tgz#86bd359646014d7a32ebbc17a4f0aeeb43255c76" 8 | -------------------------------------------------------------------------------- /packages/postcss-bredon-minify/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "postcss-bredon-minify", 3 | "version": "1.0.1", 4 | "description": "PostCSS plugin to minify values using bredon-minify", 5 | "main": "lib/index.js", 6 | "module": "es/index.js", 7 | "jsnext:main": "es/index.js", 8 | "files": [ 9 | "LICENSE", 10 | "README.md", 11 | "lib/**", 12 | "es/**" 13 | ], 14 | "keywords": [ 15 | "css", 16 | "parser", 17 | "css-parser", 18 | "css-value-parser", 19 | "ast", 20 | "lexer", 21 | "tokenizer", 22 | "validation", 23 | "validator", 24 | "cssinjs", 25 | "bredon" 26 | ], 27 | "repository": "https://github.com/rofrischmann/bredon.git", 28 | "author": "Robin Frischmann ", 29 | "license": "MIT", 30 | "dependencies": { 31 | "bredon-minify": "^1.0.1", 32 | "css-in-js-utils": "^2.0.0", 33 | "postcss": "^6.0.14" 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /packages/postcss-bredon-minify/src/__tests__/index-test.js: -------------------------------------------------------------------------------- 1 | import postcss from 'postcss' 2 | 3 | import bredonMinify from '../index' 4 | 5 | const css = `.c1 { 6 | border: 2px hsl(calc(100/2 + 10*3), 50%, 20%); 7 | color: #FFFFFF; 8 | overflow-clip-box: padding-box; 9 | font-size: 12.5555px; 10 | }` 11 | 12 | describe('Using the bredon-minify PostCSS plugin', () => { 13 | it('should minify values', done => { 14 | postcss([bredonMinify]) 15 | .process(css) 16 | .then(result => { 17 | expect(result.css).toBe( 18 | `.c1 { 19 | border: 2px #3B4D19; 20 | color: #FFF; 21 | overflow-clip-box: initial; 22 | font-size: 12.56px; 23 | }` 24 | ) 25 | done() 26 | }) 27 | }) 28 | }) 29 | -------------------------------------------------------------------------------- /packages/postcss-bredon-minify/src/index.js: -------------------------------------------------------------------------------- 1 | import * as postcss from 'postcss' 2 | import camelCaseProperty from 'css-in-js-utils/lib/camelCaseProperty' 3 | import minify from 'bredon-minify' 4 | 5 | export default postcss.plugin('postcss-bredon-minify', (options = {}) => { 6 | return (root, result) => { 7 | root.walkDecls(decl => { 8 | decl.value = minify(camelCaseProperty(decl.prop), decl.value) 9 | }) 10 | } 11 | }) 12 | -------------------------------------------------------------------------------- /packages/postcss-bredon-minify/yarn.lock: -------------------------------------------------------------------------------- 1 | # THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. 2 | # yarn lockfile v1 3 | 4 | 5 | ansi-styles@^3.1.0: 6 | version "3.2.0" 7 | resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.0.tgz#c159b8d5be0f9e5a6f346dab94f16ce022161b88" 8 | dependencies: 9 | color-convert "^1.9.0" 10 | 11 | chalk@^2.3.0: 12 | version "2.3.0" 13 | resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.3.0.tgz#b5ea48efc9c1793dccc9b4767c93914d3f2d52ba" 14 | dependencies: 15 | ansi-styles "^3.1.0" 16 | escape-string-regexp "^1.0.5" 17 | supports-color "^4.0.0" 18 | 19 | color-convert@^1.9.0: 20 | version "1.9.1" 21 | resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.1.tgz#c1261107aeb2f294ebffec9ed9ecad529a6097ed" 22 | dependencies: 23 | color-name "^1.1.1" 24 | 25 | color-name@^1.1.1: 26 | version "1.1.3" 27 | resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25" 28 | 29 | css-in-js-utils@^2.0.0: 30 | version "2.0.0" 31 | resolved "https://registry.yarnpkg.com/css-in-js-utils/-/css-in-js-utils-2.0.0.tgz#5af1dd70f4b06b331f48d22a3d86e0786c0b9435" 32 | dependencies: 33 | hyphenate-style-name "^1.0.2" 34 | 35 | escape-string-regexp@^1.0.5: 36 | version "1.0.5" 37 | resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" 38 | 39 | has-flag@^2.0.0: 40 | version "2.0.0" 41 | resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-2.0.0.tgz#e8207af1cc7b30d446cc70b734b5e8be18f88d51" 42 | 43 | hyphenate-style-name@^1.0.2: 44 | version "1.0.2" 45 | resolved "https://registry.yarnpkg.com/hyphenate-style-name/-/hyphenate-style-name-1.0.2.tgz#31160a36930adaf1fc04c6074f7eb41465d4ec4b" 46 | 47 | postcss@^6.0.14: 48 | version "6.0.14" 49 | resolved "https://registry.yarnpkg.com/postcss/-/postcss-6.0.14.tgz#5534c72114739e75d0afcf017db853099f562885" 50 | dependencies: 51 | chalk "^2.3.0" 52 | source-map "^0.6.1" 53 | supports-color "^4.4.0" 54 | 55 | source-map@^0.6.1: 56 | version "0.6.1" 57 | resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263" 58 | 59 | supports-color@^4.0.0, supports-color@^4.4.0: 60 | version "4.5.0" 61 | resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-4.5.0.tgz#be7a0de484dec5c5cddf8b3d59125044912f635b" 62 | dependencies: 63 | has-flag "^2.0.0" 64 | -------------------------------------------------------------------------------- /packages/postcss-bredon-validate/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "postcss-bredon-validate", 3 | "version": "0.0.2", 4 | "description": "PostCSS plugin to validate values using bredon-validate", 5 | "main": "lib/index.js", 6 | "module": "es/index.js", 7 | "jsnext:main": "es/index.js", 8 | "files": [ 9 | "LICENSE", 10 | "README.md", 11 | "lib/**", 12 | "es/**" 13 | ], 14 | "keywords": [ 15 | "css", 16 | "parser", 17 | "css-parser", 18 | "css-value-parser", 19 | "ast", 20 | "lexer", 21 | "tokenizer", 22 | "validation", 23 | "validator", 24 | "cssinjs", 25 | "bredon" 26 | ], 27 | "repository": "https://github.com/rofrischmann/bredon.git", 28 | "author": "Robin Frischmann ", 29 | "license": "MIT", 30 | "dependencies": { 31 | "bredon-validate": "^0.0.3", 32 | "css-in-js-utils": "^2.0.0", 33 | "postcss": "^6.0.14" 34 | }, 35 | "devDependencies": { 36 | "postcss-reporter": "^5.0.0" 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /packages/postcss-bredon-validate/src/__tests__/index-test.js: -------------------------------------------------------------------------------- 1 | import postcss from 'postcss' 2 | import reporter from 'postcss-reporter' 3 | 4 | import bredonValidate from '../index' 5 | 6 | const css = ` 7 | .c1 { 8 | color: red; 9 | font-size: solid; 10 | } 11 | ` 12 | /* eslint-disable no-console */ 13 | describe('Using the bredon-validate PostCSS plugin', () => { 14 | jest.spyOn(global.console, 'log') 15 | 16 | it('should warn on invalid values', done => { 17 | postcss([bredonValidate, reporter]) 18 | .process(css) 19 | .then(result => { 20 | expect(result.css).toBe(css) 21 | expect(console.log).toBeCalled() 22 | done() 23 | }) 24 | }) 25 | }) 26 | -------------------------------------------------------------------------------- /packages/postcss-bredon-validate/src/index.js: -------------------------------------------------------------------------------- 1 | import * as postcss from 'postcss' 2 | import camelCaseProperty from 'css-in-js-utils/lib/camelCaseProperty' 3 | import validate from 'bredon-validate' 4 | 5 | export default postcss.plugin('postcss-bredon-validate', (options = {}) => { 6 | return (root, result) => { 7 | root.walkDecls(decl => { 8 | const declaration = decl.prop + ': ' + decl.value 9 | try { 10 | if (!validate(camelCaseProperty(decl.prop), decl.value)) { 11 | decl.warn(result, 'Invalid declaration: ' + declaration, { 12 | plugin: 'postcss-bredon-validate', 13 | word: decl.value, 14 | }) 15 | } 16 | } catch (e) { 17 | console.warn(`Bredon couldn't parse ${declaration}. 18 | If this is yet a valid CSS value, please file an issue: 19 | https://github.com/rofrischmann/bredon/issues/new 20 | `) 21 | } 22 | }) 23 | } 24 | }) 25 | -------------------------------------------------------------------------------- /packages/postcss-bredon-validate/yarn.lock: -------------------------------------------------------------------------------- 1 | # THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. 2 | # yarn lockfile v1 3 | 4 | 5 | ansi-styles@^3.1.0: 6 | version "3.2.0" 7 | resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.0.tgz#c159b8d5be0f9e5a6f346dab94f16ce022161b88" 8 | dependencies: 9 | color-convert "^1.9.0" 10 | 11 | bredon-types@^3.0.0: 12 | version "3.0.0" 13 | resolved "https://registry.yarnpkg.com/bredon-types/-/bredon-types-3.0.0.tgz#1d49122f12df2c2868ba3065e27eede76b5af93e" 14 | 15 | bredon-validate@^0.0.1: 16 | version "0.0.1" 17 | resolved "https://registry.yarnpkg.com/bredon-validate/-/bredon-validate-0.0.1.tgz#64f8c3f57ca105c7bc950491c87e2c2f89906315" 18 | dependencies: 19 | bredon "^3.0.0" 20 | bredon-types "^3.0.0" 21 | 22 | bredon@^3.0.0: 23 | version "3.0.0" 24 | resolved "https://registry.yarnpkg.com/bredon/-/bredon-3.0.0.tgz#300df4374587f0fe0d633b63e31590727f12bc7a" 25 | dependencies: 26 | bredon-types "^3.0.0" 27 | tokenize-sync "^1.0.0" 28 | 29 | chalk@^2.0.1, chalk@^2.3.0: 30 | version "2.3.0" 31 | resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.3.0.tgz#b5ea48efc9c1793dccc9b4767c93914d3f2d52ba" 32 | dependencies: 33 | ansi-styles "^3.1.0" 34 | escape-string-regexp "^1.0.5" 35 | supports-color "^4.0.0" 36 | 37 | color-convert@^1.9.0: 38 | version "1.9.1" 39 | resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.1.tgz#c1261107aeb2f294ebffec9ed9ecad529a6097ed" 40 | dependencies: 41 | color-name "^1.1.1" 42 | 43 | color-name@^1.1.1: 44 | version "1.1.3" 45 | resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25" 46 | 47 | css-in-js-utils@^2.0.0: 48 | version "2.0.0" 49 | resolved "https://registry.yarnpkg.com/css-in-js-utils/-/css-in-js-utils-2.0.0.tgz#5af1dd70f4b06b331f48d22a3d86e0786c0b9435" 50 | dependencies: 51 | hyphenate-style-name "^1.0.2" 52 | 53 | escape-string-regexp@^1.0.5: 54 | version "1.0.5" 55 | resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" 56 | 57 | has-flag@^2.0.0: 58 | version "2.0.0" 59 | resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-2.0.0.tgz#e8207af1cc7b30d446cc70b734b5e8be18f88d51" 60 | 61 | hyphenate-style-name@^1.0.2: 62 | version "1.0.2" 63 | resolved "https://registry.yarnpkg.com/hyphenate-style-name/-/hyphenate-style-name-1.0.2.tgz#31160a36930adaf1fc04c6074f7eb41465d4ec4b" 64 | 65 | lodash@^4.17.4: 66 | version "4.17.4" 67 | resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.4.tgz#78203a4d1c328ae1d86dca6460e369b57f4055ae" 68 | 69 | log-symbols@^2.0.0: 70 | version "2.1.0" 71 | resolved "https://registry.yarnpkg.com/log-symbols/-/log-symbols-2.1.0.tgz#f35fa60e278832b538dc4dddcbb478a45d3e3be6" 72 | dependencies: 73 | chalk "^2.0.1" 74 | 75 | postcss-reporter@^5.0.0: 76 | version "5.0.0" 77 | resolved "https://registry.yarnpkg.com/postcss-reporter/-/postcss-reporter-5.0.0.tgz#a14177fd1342829d291653f2786efd67110332c3" 78 | dependencies: 79 | chalk "^2.0.1" 80 | lodash "^4.17.4" 81 | log-symbols "^2.0.0" 82 | postcss "^6.0.8" 83 | 84 | postcss@^6.0.14, postcss@^6.0.8: 85 | version "6.0.14" 86 | resolved "https://registry.yarnpkg.com/postcss/-/postcss-6.0.14.tgz#5534c72114739e75d0afcf017db853099f562885" 87 | dependencies: 88 | chalk "^2.3.0" 89 | source-map "^0.6.1" 90 | supports-color "^4.4.0" 91 | 92 | source-map@^0.6.1: 93 | version "0.6.1" 94 | resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263" 95 | 96 | supports-color@^4.0.0, supports-color@^4.4.0: 97 | version "4.5.0" 98 | resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-4.5.0.tgz#be7a0de484dec5c5cddf8b3d59125044912f635b" 99 | dependencies: 100 | has-flag "^2.0.0" 101 | 102 | tokenize-sync@^1.0.0: 103 | version "1.0.0" 104 | resolved "https://registry.yarnpkg.com/tokenize-sync/-/tokenize-sync-1.0.0.tgz#65b5b72bb208b013166e4d253e0b8b4990c70e83" 105 | -------------------------------------------------------------------------------- /packages/postcss-bredon/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "postcss-bredon", 3 | "version": "1.0.0", 4 | "description": "PostCSS plugin to compile values using Bredon", 5 | "main": "lib/index.js", 6 | "module": "es/index.js", 7 | "jsnext:main": "es/index.js", 8 | "files": [ 9 | "LICENSE", 10 | "README.md", 11 | "lib/**", 12 | "es/**" 13 | ], 14 | "keywords": [ 15 | "css", 16 | "parser", 17 | "css-parser", 18 | "css-value-parser", 19 | "ast", 20 | "lexer", 21 | "tokenizer", 22 | "validation", 23 | "validator", 24 | "cssinjs", 25 | "bredon" 26 | ], 27 | "repository": "https://github.com/rofrischmann/bredon.git", 28 | "author": "Robin Frischmann ", 29 | "license": "MIT", 30 | "dependencies": { 31 | "bredon": "^4.0.0", 32 | "css-in-js-utils": "^2.0.0", 33 | "postcss": "^6.0.14" 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /packages/postcss-bredon/src/index.js: -------------------------------------------------------------------------------- 1 | import * as postcss from 'postcss' 2 | import camelCaseProperty from 'css-in-js-utils/lib/camelCaseProperty' 3 | import { compile } from 'bredon' 4 | 5 | export default postcss.plugin('postcss-bredon-minify', (options = {}) => { 6 | return (root, result) => { 7 | root.walkDecls(decl => { 8 | try { 9 | decl.value = compile(decl.value, { 10 | ...options, 11 | context: { property: camelCaseProperty(decl.prop) }, 12 | }) 13 | } catch (e) {} 14 | }) 15 | } 16 | }) 17 | -------------------------------------------------------------------------------- /packages/postcss-bredon/yarn.lock: -------------------------------------------------------------------------------- 1 | # THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. 2 | # yarn lockfile v1 3 | 4 | 5 | ansi-styles@^3.1.0: 6 | version "3.2.0" 7 | resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.0.tgz#c159b8d5be0f9e5a6f346dab94f16ce022161b88" 8 | dependencies: 9 | color-convert "^1.9.0" 10 | 11 | chalk@^2.3.0: 12 | version "2.3.0" 13 | resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.3.0.tgz#b5ea48efc9c1793dccc9b4767c93914d3f2d52ba" 14 | dependencies: 15 | ansi-styles "^3.1.0" 16 | escape-string-regexp "^1.0.5" 17 | supports-color "^4.0.0" 18 | 19 | color-convert@^1.9.0: 20 | version "1.9.1" 21 | resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.1.tgz#c1261107aeb2f294ebffec9ed9ecad529a6097ed" 22 | dependencies: 23 | color-name "^1.1.1" 24 | 25 | color-name@^1.1.1: 26 | version "1.1.3" 27 | resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25" 28 | 29 | css-in-js-utils@^2.0.0: 30 | version "2.0.0" 31 | resolved "https://registry.yarnpkg.com/css-in-js-utils/-/css-in-js-utils-2.0.0.tgz#5af1dd70f4b06b331f48d22a3d86e0786c0b9435" 32 | dependencies: 33 | hyphenate-style-name "^1.0.2" 34 | 35 | escape-string-regexp@^1.0.5: 36 | version "1.0.5" 37 | resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" 38 | 39 | has-flag@^2.0.0: 40 | version "2.0.0" 41 | resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-2.0.0.tgz#e8207af1cc7b30d446cc70b734b5e8be18f88d51" 42 | 43 | hyphenate-style-name@^1.0.2: 44 | version "1.0.2" 45 | resolved "https://registry.yarnpkg.com/hyphenate-style-name/-/hyphenate-style-name-1.0.2.tgz#31160a36930adaf1fc04c6074f7eb41465d4ec4b" 46 | 47 | postcss@^6.0.14: 48 | version "6.0.14" 49 | resolved "https://registry.yarnpkg.com/postcss/-/postcss-6.0.14.tgz#5534c72114739e75d0afcf017db853099f562885" 50 | dependencies: 51 | chalk "^2.3.0" 52 | source-map "^0.6.1" 53 | supports-color "^4.4.0" 54 | 55 | source-map@^0.6.1: 56 | version "0.6.1" 57 | resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263" 58 | 59 | supports-color@^4.0.0, supports-color@^4.4.0: 60 | version "4.5.0" 61 | resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-4.5.0.tgz#be7a0de484dec5c5cddf8b3d59125044912f635b" 62 | dependencies: 63 | has-flag "^2.0.0" 64 | -------------------------------------------------------------------------------- /scripts/build.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | if [ "$1" != "" ]; then 4 | if [ -e "./packages/$1/package.json" ]; then 5 | ./node_modules/babel-cli/bin/babel.js ./packages/$1/src --out-dir ./packages/$1/es --ignore __tests__ 6 | BABEL_ENV=commonjs ./node_modules/babel-cli/bin/babel.js ./packages/$1/src --out-dir ./packages/$1/lib --ignore __tests__ 7 | else 8 | echo "Package $1 was not found" 9 | fi 10 | else 11 | for f in packages/*; do 12 | package=`basename $f` 13 | 14 | if [ -d "$f" ] && [ -e "$f/package.json" ]; then 15 | ./node_modules/babel-cli/bin/babel.js $f/src --out-dir $f/es --ignore __tests__ 16 | BABEL_ENV=commonjs ./node_modules/babel-cli/bin/babel.js $f/src --out-dir $f/lib --ignore __tests__ 17 | fi 18 | done 19 | fi 20 | --------------------------------------------------------------------------------