├── .eslintignore ├── .jshintrc ├── flowtypes ├── Warning.js └── PluginInterface.js ├── .codeclimate.yml ├── .flowconfig ├── packages ├── elodin-data │ ├── build.sh │ ├── src │ │ ├── index.js │ │ ├── generator │ │ │ ├── generatePartialSupportData.js │ │ │ ├── generateFullSupportData.js │ │ │ ├── compareSupportData.js │ │ │ └── searchMap.js │ │ └── data │ │ │ ├── compatibilityFull.js │ │ │ └── compatibilityPartial.js │ ├── package.json │ └── yarn.lock ├── elodin-utils │ ├── src │ │ ├── objectEach.js │ │ ├── objectReduce.js │ │ ├── arrayReduce.js │ │ ├── index.js │ │ ├── parser │ │ │ ├── parseLonghand.js │ │ │ ├── parseBasicLonghand.js │ │ │ ├── parseCircularLonghand.js │ │ │ ├── __tests__ │ │ │ │ ├── parseCircularLonghand-test.js │ │ │ │ ├── parseBasicLonghand-test.js │ │ │ │ └── parseShorthand-test.js │ │ │ └── parseShorthand.js │ │ ├── extractShorthandLonghand.js │ │ └── data │ │ │ ├── propertyShorthands.js │ │ │ └── valueInitials.js │ ├── package.json │ └── yarn.lock ├── elodin │ ├── src │ │ ├── utils │ │ │ ├── objectEach.js │ │ │ ├── addWarningFactory.js │ │ │ ├── objectReduce.js │ │ │ ├── arrayReduce.js │ │ │ ├── parseStyle.js │ │ │ └── generateStyle.js │ │ ├── __tests__ │ │ │ └── lint-test.js │ │ └── index.js │ ├── yarn.lock │ ├── package.json │ └── README.md ├── elodin-plugin-longhand-property │ ├── src │ │ ├── index.js │ │ └── enforceLonghand.js │ ├── README.md │ └── package.json ├── elodin-plugin-shorthand-property │ ├── src │ │ ├── index.js │ │ ├── enforceShorthand.js │ │ └── __tests__ │ │ │ └── enforceShorthand-test.js │ ├── yarn.lock │ ├── README.md │ └── package.json ├── elodin-plugin-validation │ ├── src │ │ ├── __tests__ │ │ │ └── index-test.js │ │ └── index.js │ ├── README.md │ ├── yarn.lock │ └── package.json ├── elodin-plugin-unit │ ├── README.md │ ├── package.json │ ├── yarn.lock │ └── src │ │ ├── __tests__ │ │ └── unitValue-test.js │ │ └── index.js └── elodin-plugin-number-value │ ├── README.md │ ├── package.json │ ├── yarn.lock │ └── src │ ├── index.js │ └── __tests__ │ └── index-test.js ├── lerna.json ├── .babelrc ├── .editorconfig ├── .prettierrc ├── .gitignore ├── .travis.yml ├── scripts └── build.sh ├── .eslintrc ├── LICENSE ├── .vscode └── settings.json ├── package.json ├── .github ├── CONTRIBUTING.md └── CODE_OF_CONDUCT.md └── README.md /.eslintignore: -------------------------------------------------------------------------------- 1 | packages/elodin-data/** -------------------------------------------------------------------------------- /.jshintrc: -------------------------------------------------------------------------------- 1 | { 2 | "esnext": true, 3 | "asi": true 4 | } 5 | -------------------------------------------------------------------------------- /flowtypes/Warning.js: -------------------------------------------------------------------------------- 1 | export type Warning = { 2 | type: string, 3 | description: string 4 | } 5 | -------------------------------------------------------------------------------- /.codeclimate.yml: -------------------------------------------------------------------------------- 1 | languages: 2 | Ruby: true 3 | JavaScript: true 4 | PHP: true 5 | Python: true 6 | exclude_paths: 7 | - "test/*" 8 | -------------------------------------------------------------------------------- /.flowconfig: -------------------------------------------------------------------------------- 1 | [ignore] 2 | 3 | # Disable module with broken flow types. 4 | # .*/node_modules/babylon/*.* 5 | 6 | [version] 7 | ^0.57.3 8 | -------------------------------------------------------------------------------- /packages/elodin-data/build.sh: -------------------------------------------------------------------------------- 1 | babel-node ./src/generator/generateFullSupportData 2 | babel-node ./src/generator/generatePartialSupportData 3 | -------------------------------------------------------------------------------- /lerna.json: -------------------------------------------------------------------------------- 1 | { 2 | "lerna": "2.5.1", 3 | "npmClient": "yarn", 4 | "version": "independent", 5 | "packages": [ 6 | "packages/*" 7 | ] 8 | } 9 | -------------------------------------------------------------------------------- /.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": [ 3 | "es2015", 4 | "stage-0", 5 | "react" 6 | ], 7 | "plugins": [ 8 | "add-module-exports" 9 | ] 10 | } 11 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | charset = utf-8 5 | indent_size = 2 6 | indent_style = space 7 | trim_trailing_whitespace = true 8 | insert_final_newline = false 9 | -------------------------------------------------------------------------------- /packages/elodin-utils/src/objectEach.js: -------------------------------------------------------------------------------- 1 | /* @flow */ 2 | export default function objectEach(object: Object, iterator: Function): any { 3 | for (const key in object) { 4 | iterator(object[key], key) 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /packages/elodin/src/utils/objectEach.js: -------------------------------------------------------------------------------- 1 | /* @flow */ 2 | export default function objectEach(object: Object, iterator: Function): any { 3 | for (const key in object) { 4 | iterator(object[key], key) 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /.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 | -------------------------------------------------------------------------------- /packages/elodin/src/utils/addWarningFactory.js: -------------------------------------------------------------------------------- 1 | /* @flow */ 2 | type Warning = { 3 | type: string, 4 | description: string, 5 | } 6 | 7 | export default function addWarningFactory(warnings: Array): Function { 8 | return (warning: Warning) => warnings.push(warning) 9 | } 10 | -------------------------------------------------------------------------------- /flowtypes/PluginInterface.js: -------------------------------------------------------------------------------- 1 | export type Bredon = { 2 | generate: Function, 3 | compile: Function, 4 | parse: Function, 5 | traverse: Function, 6 | } 7 | 8 | export type PluginInterface = { 9 | fix: boolean, 10 | style: Object, 11 | addWarning: Function, 12 | bredon: Bredon, 13 | } 14 | -------------------------------------------------------------------------------- /packages/elodin-utils/src/objectReduce.js: -------------------------------------------------------------------------------- 1 | /* @flow */ 2 | export default function objectReduce( 3 | object: Object, 4 | iterator: Function, 5 | initialValue: any 6 | ): any { 7 | for (const key in object) { 8 | initialValue = iterator(initialValue, object[key], key) 9 | } 10 | 11 | return initialValue 12 | } 13 | -------------------------------------------------------------------------------- /packages/elodin/src/utils/objectReduce.js: -------------------------------------------------------------------------------- 1 | /* @flow */ 2 | export default function objectReduce( 3 | object: Object, 4 | iterator: Function, 5 | initialValue: any 6 | ): any { 7 | for (const key in object) { 8 | initialValue = iterator(initialValue, object[key], key) 9 | } 10 | 11 | return initialValue 12 | } 13 | -------------------------------------------------------------------------------- /packages/elodin/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/elodin-utils/src/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 | -------------------------------------------------------------------------------- /.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 | **/es 23 | **/node_modules 24 | **/coverage 25 | **/lib 26 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: node_js 2 | node_js: 3 | - "5" 4 | script: 5 | - npm run check 6 | before_script: 7 | - npm run bootstrap 8 | - npm run build 9 | after_script: 10 | - codeclimate-test-reporter < coverage/lcov.info 11 | notifications: 12 | email: false 13 | addons: 14 | code_climate: 15 | repo_token: bab898d784279e89337e4e664567b7c515164911bcef32680e446ff206b1d9b0 16 | -------------------------------------------------------------------------------- /packages/elodin/src/utils/parseStyle.js: -------------------------------------------------------------------------------- 1 | /* @flow */ 2 | import { parse } from 'bredon' 3 | 4 | import objectReduce from './objectReduce' 5 | 6 | export default function parseStyle(style: Object): Object { 7 | return objectReduce( 8 | style, 9 | (ast, value, property) => { 10 | ast[property] = parse(value.toString()) 11 | return ast 12 | }, 13 | {} 14 | ) 15 | } 16 | -------------------------------------------------------------------------------- /packages/elodin/src/utils/generateStyle.js: -------------------------------------------------------------------------------- 1 | /* @flow */ 2 | import { generate } from 'bredon' 3 | 4 | import objectReduce from './objectReduce' 5 | 6 | export default function generateStyle(ast: Object): Object { 7 | return objectReduce( 8 | ast, 9 | (style, value, property) => { 10 | style[property] = generate(value) 11 | return style 12 | }, 13 | {} 14 | ) 15 | } 16 | -------------------------------------------------------------------------------- /packages/elodin-plugin-longhand-property/src/index.js: -------------------------------------------------------------------------------- 1 | /* @flow */ 2 | import enforceLonghand from './enforceLonghand' 3 | 4 | import type { PluginInterface } from '../../../flowtypes/PluginInterface' 5 | 6 | type Options = { 7 | allowSingle: boolean, 8 | } 9 | 10 | // TODO: enable for prefixed shorthand/longhands 11 | export default function shorthandProperty(options: Options): Function { 12 | return (pluginInterface: Object) => enforceLonghand(pluginInterface, options) 13 | } 14 | -------------------------------------------------------------------------------- /packages/elodin-plugin-shorthand-property/src/index.js: -------------------------------------------------------------------------------- 1 | /* @flow */ 2 | import enforceShorthand from './enforceShorthand' 3 | 4 | import type { PluginInterface } from '../../../flowtypes/PluginInterface' 5 | 6 | type Options = { 7 | allowSingle: boolean, 8 | } 9 | 10 | // TODO: enable for prefixed shorthand/longhands 11 | export default function shorthandProperty(options: Options): Function { 12 | return (pluginInterface: Object) => enforceShorthand(pluginInterface, options) 13 | } 14 | -------------------------------------------------------------------------------- /packages/elodin-utils/src/index.js: -------------------------------------------------------------------------------- 1 | /* @flow */ 2 | import arrayReduce from './arrayReduce' 3 | import extractShorthandLonghand from './extractShorthandLonghand' 4 | import objectEach from './objectEach' 5 | import objectReduce from './objectReduce' 6 | 7 | import parseShorthand from './parser/parseShorthand' 8 | import parseLonghand from './parser/parseLonghand' 9 | 10 | export { 11 | arrayReduce, 12 | extractShorthandLonghand, 13 | objectEach, 14 | objectReduce, 15 | parseShorthand, 16 | parseLonghand, 17 | } 18 | -------------------------------------------------------------------------------- /packages/elodin-plugin-shorthand-property/yarn.lock: -------------------------------------------------------------------------------- 1 | # THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. 2 | # yarn lockfile v1 3 | 4 | 5 | css-in-js-utils@^2.0.0: 6 | version "2.0.0" 7 | resolved "https://registry.yarnpkg.com/css-in-js-utils/-/css-in-js-utils-2.0.0.tgz#5af1dd70f4b06b331f48d22a3d86e0786c0b9435" 8 | dependencies: 9 | hyphenate-style-name "^1.0.2" 10 | 11 | hyphenate-style-name@^1.0.2: 12 | version "1.0.2" 13 | resolved "https://registry.yarnpkg.com/hyphenate-style-name/-/hyphenate-style-name-1.0.2.tgz#31160a36930adaf1fc04c6074f7eb41465d4ec4b" 14 | -------------------------------------------------------------------------------- /packages/elodin-utils/src/parser/parseLonghand.js: -------------------------------------------------------------------------------- 1 | /* @flow */ 2 | import parseBasicLonghands from './parseBasicLonghand' 3 | import parseCircularLonghand from './parseCircularLonghand' 4 | 5 | const patternShorthands = { 6 | padding: true, 7 | margin: true, 8 | borderRadius: true, 9 | borderWidth: true, 10 | borderStyle: true, 11 | borderColor: true, 12 | perspectiveOrigin: true, 13 | } 14 | 15 | export default function parseLonghand( 16 | property: string, 17 | longhands: Object 18 | ): string { 19 | if (patternShorthands[property]) { 20 | return parseCircularLonghand(property, longhands) 21 | } 22 | 23 | return parseBasicLonghands(property, longhands) 24 | } 25 | -------------------------------------------------------------------------------- /packages/elodin/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.0: 10 | version "3.0.0" 11 | resolved "https://registry.yarnpkg.com/bredon/-/bredon-3.0.0.tgz#300df4374587f0fe0d633b63e31590727f12bc7a" 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/elodin-data/src/index.js: -------------------------------------------------------------------------------- 1 | import colorNames from './data/colorNames' 2 | import compatibilityFull from './data/compatibilityFull' 3 | import compatibilityPartial from './data/compatibilityPartial' 4 | import multiValueProperties from './data/multiValueProperties' 5 | import propertyShorthands from './data/propertyShorthands' 6 | import valueInitials from './data/valueInitials' 7 | import valueKeywords from './data/valueKeywords' 8 | import valueSetProperties from './data/valueSetProperties' 9 | 10 | export { 11 | colorNames, 12 | compatibilityFull, 13 | compatibilityPartial, 14 | multiValueProperties, 15 | propertyShorthands, 16 | valueInitials, 17 | valueKeywords, 18 | valueSetProperties, 19 | } 20 | -------------------------------------------------------------------------------- /packages/elodin-plugin-validation/src/__tests__/index-test.js: -------------------------------------------------------------------------------- 1 | import lint from 'elodin' 2 | import validation from '../index' 3 | 4 | describe('Validation CSS declarations', () => { 5 | it('should add a warning if an invalid declaration is found', () => { 6 | const warnings = lint({ 7 | plugins: [validation()], 8 | })({ 9 | fontSize: '12px', 10 | lineHeight: 200, 11 | width: 'solid', 12 | }) 13 | 14 | expect(warnings.length).toBe(1) 15 | expect(warnings[0]).toEqual({ 16 | type: 'VALIDATION', 17 | description: 18 | 'The value "solid" is not valid in combination with "width".', 19 | property: 'width', 20 | value: 'solid', 21 | }) 22 | }) 23 | }) 24 | -------------------------------------------------------------------------------- /packages/elodin/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "elodin", 3 | "version": "0.1.2", 4 | "description": "Quality and Optimisation tools for CSS 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 | "repository": "https://github.com/rofrischmann/elodin", 15 | "keywords": [ 16 | "react", 17 | "react styling", 18 | "inline styles", 19 | "linter", 20 | "cssinjs", 21 | "style linting" 22 | ], 23 | "author": "Robin Frischmann", 24 | "license": "MIT", 25 | "dependencies": { 26 | "bredon": "^3.0.0" 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /packages/elodin-data/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "private": true, 3 | "name": "elodin-data", 4 | "version": "1.0.1", 5 | "description": "Elodin data provider", 6 | "main": "lib/index.js", 7 | "module": "es/index.js", 8 | "jsnext:main": "es/index.js", 9 | "files": [ 10 | "LICENSE", 11 | "README.md", 12 | "lib/**", 13 | "es/**" 14 | ], 15 | "repository": "https://github.com/rofrischmann/elodin", 16 | "keywords": [ 17 | "react", 18 | "react styling", 19 | "inline styles", 20 | "linter", 21 | "cssinjs", 22 | "style linting" 23 | ], 24 | "author": "Robin Frischmann", 25 | "license": "MIT", 26 | "devDependencies": { 27 | "caniuse-api": "^2.0.0" 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /packages/elodin-plugin-validation/src/index.js: -------------------------------------------------------------------------------- 1 | /* @flow */ 2 | import isValidProperty from 'bredon-validate/lib/isValidProperty' 3 | 4 | import type { PluginInterface } from '../../../flowtypes/PluginInterface' 5 | 6 | const PLUGIN_TYPE = 'VALIDATION' 7 | 8 | function validation({ style, addWarning, bredon }: PluginInterface) { 9 | for (const property in style) { 10 | const ast = style[property] 11 | 12 | if (!isValidProperty(property, ast)) { 13 | const value = bredon.generate(ast) 14 | 15 | addWarning({ 16 | type: PLUGIN_TYPE, 17 | description: `The value "${value}" is not valid in combination with "${ 18 | property 19 | }".`, 20 | property, 21 | value, 22 | }) 23 | } 24 | } 25 | } 26 | 27 | export default () => validation 28 | -------------------------------------------------------------------------------- /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 | 21 | cp README.md packages/elodin/README.md 22 | -------------------------------------------------------------------------------- /packages/elodin-utils/src/parser/parseBasicLonghand.js: -------------------------------------------------------------------------------- 1 | /* @flow */ 2 | import propertyShorthands from '../data/propertyShorthands' 3 | import arrayReduce from '../arrayReduce' 4 | 5 | export default function parseBasicLonghand( 6 | property: string, 7 | longhands: Object 8 | ): string { 9 | if (propertyShorthands[property]) { 10 | const values = arrayReduce( 11 | propertyShorthands[property], 12 | (shorthand, longhand) => { 13 | // if longhand value is provided 14 | if (longhands[longhand]) { 15 | shorthand.push(longhands[longhand]) 16 | } else { 17 | // if longhand value is not provided 18 | } 19 | 20 | return shorthand 21 | }, 22 | [] 23 | ) 24 | 25 | return values.join(' ') 26 | } 27 | 28 | // TODO: error? 29 | return '' 30 | } 31 | -------------------------------------------------------------------------------- /packages/elodin-plugin-unit/README.md: -------------------------------------------------------------------------------- 1 | # elodin-plugin-shorthand-longhand 2 | 3 | npm version 4 | npm downloads 5 | 6 | DESCRIPTION 7 | 8 | ## Installation 9 | ```sh 10 | yarn add elodin-plugin-shorthand-longhand 11 | ``` 12 | You may alternatively use npm i --save elodin-plugin-shorthand-longhand. 13 | 14 | ## Configuration 15 | ```javascript 16 | ``` 17 | 18 | ## Example 19 | 20 | 21 | ## License 22 | Elodin is licensed under the [MIT License](http://opensource.org/licenses/MIT).
23 | Documentation is licensed under [Creative Common License](http://creativecommons.org/licenses/by/4.0/).
24 | Created with ♥ by [@rofrischmann](http://rofrischmann.de) and all the great contributors. 25 | -------------------------------------------------------------------------------- /packages/elodin-plugin-number-value/README.md: -------------------------------------------------------------------------------- 1 | # elodin-plugin-shorthand-longhand 2 | 3 | npm version 4 | npm downloads 5 | 6 | DESCRIPTION 7 | 8 | ## Installation 9 | ```sh 10 | yarn add elodin-plugin-shorthand-longhand 11 | ``` 12 | You may alternatively use npm i --save elodin-plugin-shorthand-longhand. 13 | 14 | ## Configuration 15 | ```javascript 16 | ``` 17 | 18 | ## Example 19 | 20 | 21 | ## License 22 | Elodin is licensed under the [MIT License](http://opensource.org/licenses/MIT).
23 | Documentation is licensed under [Creative Common License](http://creativecommons.org/licenses/by/4.0/).
24 | Created with ♥ by [@rofrischmann](http://rofrischmann.de) and all the great contributors. 25 | -------------------------------------------------------------------------------- /packages/elodin-plugin-longhand-property/README.md: -------------------------------------------------------------------------------- 1 | # elodin-plugin-shorthand-longhand 2 | 3 | npm version 4 | npm downloads 5 | 6 | DESCRIPTION 7 | 8 | ## Installation 9 | ```sh 10 | yarn add elodin-plugin-shorthand-longhand 11 | ``` 12 | You may alternatively use npm i --save elodin-plugin-shorthand-longhand. 13 | 14 | ## Configuration 15 | ```javascript 16 | ``` 17 | 18 | ## Example 19 | 20 | 21 | ## License 22 | Elodin is licensed under the [MIT License](http://opensource.org/licenses/MIT).
23 | Documentation is licensed under [Creative Common License](http://creativecommons.org/licenses/by/4.0/).
24 | Created with ♥ by [@rofrischmann](http://rofrischmann.de) and all the great contributors. 25 | -------------------------------------------------------------------------------- /packages/elodin-plugin-shorthand-property/README.md: -------------------------------------------------------------------------------- 1 | # elodin-plugin-shorthand-longhand 2 | 3 | npm version 4 | npm downloads 5 | 6 | DESCRIPTION 7 | 8 | ## Installation 9 | ```sh 10 | yarn add elodin-plugin-shorthand-longhand 11 | ``` 12 | You may alternatively use npm i --save elodin-plugin-shorthand-longhand. 13 | 14 | ## Configuration 15 | ```javascript 16 | ``` 17 | 18 | ## Example 19 | 20 | 21 | ## License 22 | Elodin is licensed under the [MIT License](http://opensource.org/licenses/MIT).
23 | Documentation is licensed under [Creative Common License](http://creativecommons.org/licenses/by/4.0/).
24 | Created with ♥ by [@rofrischmann](http://rofrischmann.de) and all the great contributors. 25 | -------------------------------------------------------------------------------- /packages/elodin-plugin-validation/README.md: -------------------------------------------------------------------------------- 1 | > **Caution**: Still experimental! 2 | 3 | # elodin-plugin-validation 4 | 5 | npm version 6 | npm downloads 7 | 8 | DESCRIPTION 9 | 10 | ## Installation 11 | ```sh 12 | yarn add elodin-plugin-validation 13 | ``` 14 | You may alternatively use npm i --save elodin-plugin-validation. 15 | 16 | ## Configuration 17 | ```javascript 18 | ``` 19 | 20 | ## Example 21 | 22 | 23 | ## License 24 | Elodin is licensed under the [MIT License](http://opensource.org/licenses/MIT).
25 | Documentation is licensed under [Creative Common License](http://creativecommons.org/licenses/by/4.0/).
26 | Created with ♥ by [@rofrischmann](http://rofrischmann.de) and all the great contributors. 27 | -------------------------------------------------------------------------------- /packages/elodin-utils/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "private": true, 3 | "name": "elodin-utils", 4 | "version": "1.0.1", 5 | "description": "Elodin utilities for internal use", 6 | "main": "lib/index.js", 7 | "module": "es/index.js", 8 | "jsnext:main": "es/index.js", 9 | "files": [ 10 | "LICENSE", 11 | "README.md", 12 | "lib/**", 13 | "es/**" 14 | ], 15 | "repository": "https://github.com/rofrischmann/elodin", 16 | "keywords": [ 17 | "react", 18 | "react styling", 19 | "inline styles", 20 | "linter", 21 | "cssinjs", 22 | "style linting" 23 | ], 24 | "author": "Robin Frischmann", 25 | "license": "MIT", 26 | "dependencies": { 27 | "bredon": "^3.0.0", 28 | "bredon-types": "^3.0.0", 29 | "bredon-validate": "^0.0.1" 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /.eslintrc: -------------------------------------------------------------------------------- 1 | { 2 | "extends": [ "airbnb" ], 3 | "parser": "babel-eslint", 4 | "env": { 5 | "node": true, 6 | "jest": true 7 | }, 8 | "plugins": [ 9 | "flowtype" 10 | ], 11 | "rules": { 12 | "semi": [ 2, "never" ], 13 | "object-curly-newline": [ 0 ], 14 | "object-property-newline": [ 2, { 15 | "allowMultiplePropertiesPerLine": true 16 | }], 17 | "comma-dangle": [ 0 ], 18 | "import/no-extraneous-dependencies": [ 0 ], 19 | "no-confusing-arrow": [ 0 ], 20 | "no-underscore-dangle": [ 0 ], 21 | "no-param-reassign": [ 1 ], 22 | "no-plusplus": [ 0 ], 23 | "guard-for-in": [ 0 ], 24 | "no-restricted-syntax": [ 1 ], 25 | "no-continue": [ 1 ], 26 | "no-prototype-builtins": [ 1 ], 27 | "max-len": [ 1, 80 ], 28 | "no-mixed-operators": [ 1 ], 29 | "no-lonely-if": [ 1 ], 30 | "no-bitwise": [ 0 ] 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /packages/elodin/src/__tests__/lint-test.js: -------------------------------------------------------------------------------- 1 | import sinon from 'sinon' 2 | 3 | import lint from '../index' 4 | 5 | describe('Linting styles', () => { 6 | it('should execute every plugin', () => { 7 | const plugin = sinon.spy() 8 | const anotherPlugin = sinon.spy() 9 | 10 | lint({ plugins: [plugin, anotherPlugin] })({ color: 'red' }) 11 | 12 | expect(plugin.calledOnce).toBe(true) 13 | expect(anotherPlugin.calledOnce).toBe(true) 14 | }) 15 | 16 | it('should add warnings', () => { 17 | const plugin = ({ style, addWarning }) => { 18 | if (style.foo) { 19 | addWarning({ description: 'foobar' }) 20 | } 21 | } 22 | 23 | const warnings = lint({ plugins: [plugin] })({ 24 | color: 'red', 25 | foo: true, 26 | }) 27 | 28 | expect(warnings.length).toBe(1) 29 | expect(warnings[0]).toEqual({ description: 'foobar' }) 30 | }) 31 | }) 32 | -------------------------------------------------------------------------------- /packages/elodin-plugin-longhand-property/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "private": true, 3 | "name": "elodin-plugin-shorthand-longhand", 4 | "version": "1.0.1", 5 | "description": "Elodin plugin for shorthand-longhand properties", 6 | "main": "lib/index.js", 7 | "module": "es/index.js", 8 | "jsnext:main": "es/index.js", 9 | "files": [ 10 | "LICENSE", 11 | "README.md", 12 | "lib/**", 13 | "es/**" 14 | ], 15 | "repository": "https://github.com/rofrischmann/elodin", 16 | "keywords": [ 17 | "react", 18 | "react styling", 19 | "inline styles", 20 | "linter", 21 | "cssinjs", 22 | "style linting", 23 | "elodin-plugin" 24 | ], 25 | "author": "Robin Frischmann", 26 | "license": "MIT", 27 | "dependencies": { 28 | "css-in-js-utils": "^2.0.0", 29 | "elodin-utils": "^1.0.1" 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /packages/elodin-plugin-shorthand-property/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "private": true, 3 | "name": "elodin-plugin-shorthand-longhand", 4 | "version": "1.0.1", 5 | "description": "Elodin plugin for shorthand-longhand properties", 6 | "main": "lib/index.js", 7 | "module": "es/index.js", 8 | "jsnext:main": "es/index.js", 9 | "files": [ 10 | "LICENSE", 11 | "README.md", 12 | "lib/**", 13 | "es/**" 14 | ], 15 | "repository": "https://github.com/rofrischmann/elodin", 16 | "keywords": [ 17 | "react", 18 | "react styling", 19 | "inline styles", 20 | "linter", 21 | "cssinjs", 22 | "style linting", 23 | "elodin-plugin" 24 | ], 25 | "author": "Robin Frischmann", 26 | "license": "MIT", 27 | "dependencies": { 28 | "css-in-js-utils": "^2.0.0", 29 | "elodin-utils": "^1.0.1" 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /packages/elodin-plugin-unit/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "elodin-plugin-unit-value", 3 | "version": "0.0.2", 4 | "description": "Elodin plugin for unit 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 | "repository": "https://github.com/rofrischmann/elodin", 15 | "keywords": [ 16 | "react", 17 | "react styling", 18 | "inline styles", 19 | "linter", 20 | "cssinjs", 21 | "style linting", 22 | "elodin-plugin" 23 | ], 24 | "author": "Robin Frischmann", 25 | "license": "MIT", 26 | "dependencies": { 27 | "bredon-tools": "^3.0.0", 28 | "css-in-js-utils": "^2.0.0" 29 | }, 30 | "devDependencies": { 31 | "elodin": "^0.1.2" 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /packages/elodin-plugin-number-value/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "private": true, 3 | "name": "elodin-plugin-number-value", 4 | "version": "1.0.1", 5 | "description": "Elodin plugin for number values", 6 | "main": "lib/index.js", 7 | "module": "es/index.js", 8 | "jsnext:main": "es/index.js", 9 | "files": [ 10 | "LICENSE", 11 | "README.md", 12 | "lib/**", 13 | "es/**" 14 | ], 15 | "repository": "https://github.com/rofrischmann/elodin", 16 | "keywords": [ 17 | "react", 18 | "react styling", 19 | "inline styles", 20 | "linter", 21 | "cssinjs", 22 | "style linting", 23 | "elodin-plugin" 24 | ], 25 | "author": "Robin Frischmann", 26 | "license": "MIT", 27 | "dependencies": { 28 | "bredon": "^2.0.2", 29 | "bredon-types": "^2.0.4", 30 | "css-in-js-utils": "^2.0.0", 31 | "elodin-utils": "^1.0.1" 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /packages/elodin-utils/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-validate@^0.0.1: 10 | version "0.0.1" 11 | resolved "https://registry.yarnpkg.com/bredon-validate/-/bredon-validate-0.0.1.tgz#64f8c3f57ca105c7bc950491c87e2c2f89906315" 12 | dependencies: 13 | bredon "^3.0.0" 14 | bredon-types "^3.0.0" 15 | 16 | bredon@^3.0.0: 17 | version "3.0.0" 18 | resolved "https://registry.yarnpkg.com/bredon/-/bredon-3.0.0.tgz#300df4374587f0fe0d633b63e31590727f12bc7a" 19 | dependencies: 20 | bredon-types "^3.0.0" 21 | tokenize-sync "^1.0.0" 22 | 23 | tokenize-sync@^1.0.0: 24 | version "1.0.0" 25 | resolved "https://registry.yarnpkg.com/tokenize-sync/-/tokenize-sync-1.0.0.tgz#65b5b72bb208b013166e4d253e0b8b4990c70e83" 26 | -------------------------------------------------------------------------------- /packages/elodin-plugin-validation/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-validate@^0.0.2: 10 | version "0.0.2" 11 | resolved "https://registry.yarnpkg.com/bredon-validate/-/bredon-validate-0.0.2.tgz#a845d9ce0d5e6798fe51216a8a058c159fcfefe8" 12 | dependencies: 13 | bredon "^3.0.1" 14 | bredon-types "^3.0.0" 15 | 16 | bredon@^3.0.1: 17 | version "3.0.1" 18 | resolved "https://registry.yarnpkg.com/bredon/-/bredon-3.0.1.tgz#42d101c8dd7c6fca42ff4106a54049ff935d6cac" 19 | dependencies: 20 | bredon-types "^3.0.0" 21 | tokenize-sync "^1.0.0" 22 | 23 | tokenize-sync@^1.0.0: 24 | version "1.0.0" 25 | resolved "https://registry.yarnpkg.com/tokenize-sync/-/tokenize-sync-1.0.0.tgz#65b5b72bb208b013166e4d253e0b8b4990c70e83" 26 | -------------------------------------------------------------------------------- /packages/elodin-plugin-validation/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "elodin-plugin-validation", 3 | "version": "0.0.2", 4 | "description": "Elodin plugin to validate CSS declarations", 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 | "repository": "https://github.com/rofrischmann/elodin", 15 | "keywords": [ 16 | "react", 17 | "react styling", 18 | "inline styles", 19 | "linter", 20 | "cssinjs", 21 | "style linting", 22 | "validation", 23 | "style validation", 24 | "AST", 25 | "compiler", 26 | "parser" 27 | ], 28 | "author": "Robin Frischmann", 29 | "license": "MIT", 30 | "dependencies": { 31 | "bredon-validate": "^0.0.2" 32 | }, 33 | "devDependencies": { 34 | "elodin": "^0.1.2" 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /packages/elodin/src/index.js: -------------------------------------------------------------------------------- 1 | /* @flow */ 2 | import * as bredon from 'bredon' 3 | import addWarningFactory from './utils/addWarningFactory' 4 | import arrayReduce from './utils/arrayReduce' 5 | import parseStyle from './utils/parseStyle' 6 | import generateStyle from './utils/generateStyle' 7 | 8 | import type { Warning } from '../../../flowtypes/Warning' 9 | 10 | type ConfigType = { 11 | plugins?: Array, 12 | fix?: boolean, 13 | } 14 | 15 | export default function lint({ 16 | plugins = [], 17 | fix = false, 18 | }: ConfigType): Function { 19 | return (style: Object): Array => { 20 | return arrayReduce( 21 | plugins, 22 | (warnings, plugin) => { 23 | const addWarning = addWarningFactory(warnings) 24 | const ast = parseStyle(style) 25 | 26 | plugin({ 27 | style: ast, 28 | fix, 29 | addWarning, 30 | bredon, 31 | }) 32 | 33 | style = generateStyle(ast) 34 | return warnings 35 | }, 36 | [] 37 | ) 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /packages/elodin-utils/src/extractShorthandLonghand.js: -------------------------------------------------------------------------------- 1 | /* @flow */ 2 | import propertyShorthands from './data/propertyShorthands' 3 | 4 | const shorthands = Object.keys(propertyShorthands) 5 | 6 | export type Usage = { 7 | longhandProps: { [shorthand: string]: Array }, 8 | shorthandProps: Array, 9 | } 10 | 11 | export default function extractShorthandLonghand(style: Object): Usage { 12 | const longhandProps = {} 13 | const shorthandProps = [] 14 | 15 | for (const property in style) { 16 | if (propertyShorthands[property]) { 17 | shorthandProps.push(property) 18 | } else { 19 | const shorthand = shorthands.find( 20 | shorthand => propertyShorthands[shorthand].indexOf(property) !== -1 21 | ) 22 | 23 | if (shorthand) { 24 | if (!longhandProps[shorthand]) { 25 | longhandProps[shorthand] = [] 26 | } 27 | 28 | longhandProps[shorthand].push(property) 29 | } 30 | } 31 | } 32 | 33 | return { 34 | longhandProps, 35 | shorthandProps, 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /packages/elodin-data/src/generator/generatePartialSupportData.js: -------------------------------------------------------------------------------- 1 | const caniuse = require('caniuse-api') 2 | const searchMap = require('./searchMap') 3 | const fs = require('fs') 4 | 5 | function gatherInformation() { 6 | const supportData = {} 7 | let search 8 | for (search in searchMap) { 9 | let properties = searchMap[search] 10 | var versions = caniuse.getSupport(search, true) 11 | if (properties instanceof Array !== true) { 12 | properties = [properties] 13 | } 14 | properties.forEach(prop => { 15 | if (!supportData[prop]) { 16 | supportData[prop] = {} 17 | } 18 | let browser 19 | for (browser in versions) { 20 | supportData[prop][browser] = versions[browser].n || 0 21 | } 22 | }) 23 | } 24 | return `var partialSupport = ${JSON.stringify( 25 | supportData 26 | )}; module.exports = partialSupport` 27 | } 28 | fs.writeFile('./src/data/compatibilityPartial.js', gatherInformation(), err => { 29 | if (err) { 30 | throw err 31 | } 32 | console.log('Successfully generated partial support data.') 33 | }) 34 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 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 | -------------------------------------------------------------------------------- /packages/elodin-plugin-number-value/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.4: 6 | version "2.0.4" 7 | resolved "https://registry.yarnpkg.com/bredon-types/-/bredon-types-2.0.4.tgz#50a8aaae8a6c8c0092e630e28142861d9d9a88fb" 8 | 9 | bredon@^2.0.2: 10 | version "2.0.2" 11 | resolved "https://registry.yarnpkg.com/bredon/-/bredon-2.0.2.tgz#3c96a7df9e43fffd543bb6af8f3a2a7b1353644f" 12 | dependencies: 13 | bredon-types "^2.0.4" 14 | tokenize-sync "^1.0.0" 15 | 16 | css-in-js-utils@^2.0.0: 17 | version "2.0.0" 18 | resolved "https://registry.yarnpkg.com/css-in-js-utils/-/css-in-js-utils-2.0.0.tgz#5af1dd70f4b06b331f48d22a3d86e0786c0b9435" 19 | dependencies: 20 | hyphenate-style-name "^1.0.2" 21 | 22 | hyphenate-style-name@^1.0.2: 23 | version "1.0.2" 24 | resolved "https://registry.yarnpkg.com/hyphenate-style-name/-/hyphenate-style-name-1.0.2.tgz#31160a36930adaf1fc04c6074f7eb41465d4ec4b" 25 | 26 | tokenize-sync@^1.0.0: 27 | version "1.0.0" 28 | resolved "https://registry.yarnpkg.com/tokenize-sync/-/tokenize-sync-1.0.0.tgz#65b5b72bb208b013166e4d253e0b8b4990c70e83" 29 | -------------------------------------------------------------------------------- /packages/elodin-data/src/generator/generateFullSupportData.js: -------------------------------------------------------------------------------- 1 | const caniuse = require('caniuse-api') 2 | const searchMap = require('./searchMap') 3 | const fs = require('fs') 4 | 5 | function gatherInformation() { 6 | const supportData = {} 7 | let search 8 | for (search in searchMap) { 9 | let properties = searchMap[search] 10 | var versions = caniuse.getSupport(search, true) 11 | if (properties instanceof Array !== true) { 12 | properties = [properties] 13 | } 14 | properties.forEach(prop => { 15 | if (!supportData[prop]) { 16 | supportData[prop] = {} 17 | } 18 | let browser 19 | for (browser in versions) { 20 | // only add if version is available 21 | if (versions[browser].y) { 22 | supportData[prop][browser] = versions[browser].y 23 | } 24 | } 25 | }) 26 | } 27 | 28 | supportData.animationFillMode.android = 2.4 29 | return `var fullSupport = ${JSON.stringify( 30 | supportData 31 | )}; module.exports = fullSupport` 32 | } 33 | fs.writeFile('./src/data/compatibilityFull.js', gatherInformation(), err => { 34 | if (err) { 35 | throw err 36 | } 37 | console.log('Successfully generated full support data.') 38 | }) 39 | -------------------------------------------------------------------------------- /packages/elodin-plugin-number-value/src/index.js: -------------------------------------------------------------------------------- 1 | /* @flow */ 2 | import { parse } from 'bredon' 3 | import { isCSSValue, isDimension } from 'bredon-types' 4 | import { objectEach } from 'elodin-utils' 5 | import isUnitlessProperty from 'css-in-js-utils/lib/isUnitlessProperty' 6 | 7 | import type { PluginInterface } from '../../../flowtypes/PluginInterface' 8 | 9 | function enforceNumber({ style, addWarning, fix }: PluginInterface) { 10 | objectEach(style, (value, property) => { 11 | if (!isUnitlessProperty(property)) { 12 | const ast = parse(value.toString()) 13 | 14 | if (isCSSValue(ast) && ast.body.length === 1) { 15 | const node = ast.body[0] 16 | 17 | if (isDimension(node) && node.unit === 'px') { 18 | if (fix) { 19 | style[property] = node.value 20 | } else { 21 | addWarning({ 22 | type: 'NUMBER_VALUE', 23 | description: `Do not apply "px" unit to "${value}". Use "${ 24 | node.value 25 | }".`, 26 | suggestion: node.value, 27 | property, 28 | value, 29 | }) 30 | } 31 | } 32 | } 33 | } 34 | }) 35 | } 36 | 37 | export default () => enforceNumber 38 | -------------------------------------------------------------------------------- /packages/elodin-utils/src/parser/parseCircularLonghand.js: -------------------------------------------------------------------------------- 1 | /* @flow */ 2 | import propertyShorthands from '../data/propertyShorthands' 3 | import valueInitials from '../data/valueInitials' 4 | 5 | import arrayReduce from '../arrayReduce' 6 | 7 | const circularPattern = [ 8 | { length: 4, matching: [1, 3] }, 9 | { length: 3, matching: [0, 2] }, 10 | { length: 2, matching: [0, 1] }, 11 | ] 12 | 13 | export default function parseCircularLonghand( 14 | property: string, 15 | longhands: Object 16 | ): string { 17 | if (propertyShorthands[property]) { 18 | const values = arrayReduce( 19 | propertyShorthands[property], 20 | (shorthand, longhand) => { 21 | // if longhand value is provided 22 | if (longhands[longhand]) { 23 | shorthand.push(longhands[longhand]) 24 | } else { 25 | shorthand.push(valueInitials[longhand]) 26 | } 27 | 28 | return shorthand 29 | }, 30 | [] 31 | ) 32 | 33 | circularPattern.forEach(({ length, matching }) => { 34 | if ( 35 | values.length === length && 36 | values[matching[0]] === values[matching[1]] 37 | ) { 38 | values.pop() 39 | } 40 | }) 41 | 42 | return values.join(' ') 43 | } 44 | 45 | // TODO: error? 46 | return '' 47 | } 48 | -------------------------------------------------------------------------------- /.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 | "**/es": true, 22 | "**/node_modules": 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 | "**/es": true, 46 | "**/node_modules": true, 47 | "**/coverage": true, 48 | "**/lib": true 49 | } 50 | } -------------------------------------------------------------------------------- /packages/elodin-plugin-number-value/src/__tests__/index-test.js: -------------------------------------------------------------------------------- 1 | import numberValue from '../index' 2 | 3 | const mockPluginInterface = warnings => (style, fix) => ({ 4 | style, 5 | addWarning: warning => warnings.push(warning), 6 | fix: fix || false, 7 | }) 8 | 9 | describe('Enforcing number values', () => { 10 | it('should warn if a unit is applied', () => { 11 | const warnings = [] 12 | const pluginInterface = mockPluginInterface(warnings) 13 | 14 | numberValue()( 15 | pluginInterface({ 16 | fontSize: '12px', 17 | lineHeight: 200, 18 | width: 10, 19 | }) 20 | ) 21 | 22 | expect(warnings.length).toBe(1) 23 | expect(warnings[0]).toEqual({ 24 | type: 'NUMBER_VALUE', 25 | description: 'Do not apply "px" unit to "12px". Use "12".', 26 | property: 'fontSize', 27 | suggestion: 12, 28 | value: '12px', 29 | }) 30 | }) 31 | 32 | it('should auto-fix the style', () => { 33 | const warnings = [] 34 | const pluginInterface = mockPluginInterface(warnings) 35 | const style = { 36 | fontSize: '12px', 37 | lineHeight: 200, 38 | width: 10, 39 | } 40 | 41 | numberValue()(pluginInterface(style, true)) 42 | 43 | expect(warnings.length).toBe(0) 44 | expect(style).toEqual({ 45 | fontSize: 12, 46 | lineHeight: 200, 47 | width: 10, 48 | }) 49 | }) 50 | }) 51 | -------------------------------------------------------------------------------- /packages/elodin-data/yarn.lock: -------------------------------------------------------------------------------- 1 | # THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. 2 | # yarn lockfile v1 3 | 4 | 5 | browserslist@^2.0.0: 6 | version "2.4.0" 7 | resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-2.4.0.tgz#693ee93d01e66468a6348da5498e011f578f87f8" 8 | dependencies: 9 | caniuse-lite "^1.0.30000718" 10 | electron-to-chromium "^1.3.18" 11 | 12 | caniuse-api@^2.0.0: 13 | version "2.0.0" 14 | resolved "https://registry.yarnpkg.com/caniuse-api/-/caniuse-api-2.0.0.tgz#b1ddb5a5966b16f48dc4998444d4bbc6c7d9d834" 15 | dependencies: 16 | browserslist "^2.0.0" 17 | caniuse-lite "^1.0.0" 18 | lodash.memoize "^4.1.2" 19 | lodash.uniq "^4.5.0" 20 | 21 | caniuse-lite@^1.0.0, caniuse-lite@^1.0.30000718: 22 | version "1.0.30000718" 23 | resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30000718.tgz#0dd24290beb11310b2d80f6b70a823c2a65a6fad" 24 | 25 | electron-to-chromium@^1.3.18: 26 | version "1.3.18" 27 | resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.18.tgz#3dcc99da3e6b665f6abbc71c28ad51a2cd731a9c" 28 | 29 | lodash.memoize@^4.1.2: 30 | version "4.1.2" 31 | resolved "https://registry.yarnpkg.com/lodash.memoize/-/lodash.memoize-4.1.2.tgz#bcc6c49a42a2840ed997f323eada5ecd182e0bfe" 32 | 33 | lodash.uniq@^4.5.0: 34 | version "4.5.0" 35 | resolved "https://registry.yarnpkg.com/lodash.uniq/-/lodash.uniq-4.5.0.tgz#d0225373aeb652adc1bc82e4945339a842754773" 36 | -------------------------------------------------------------------------------- /packages/elodin-plugin-shorthand-property/src/enforceShorthand.js: -------------------------------------------------------------------------------- 1 | /* @flow */ 2 | import { extractShorthandLonghand } from 'elodin-utils' 3 | import type { PluginInterface } from '../../../flowtypes/PluginInterface' 4 | 5 | export default function enforceShorthand( 6 | { style, fix, addWarning }: PluginInterface, 7 | { allowSingle = false }: Object = {} 8 | ) { 9 | const { shorthandProps, longhandProps } = extractShorthandLonghand(style) 10 | 11 | for (const shorthand in longhandProps) { 12 | const longhands = longhandProps[shorthand] 13 | 14 | // if shorthand and longhand propeties are mixed 15 | if (shorthandProps.indexOf(shorthand) !== -1) { 16 | // TODO: fix 17 | 18 | addWarning({ 19 | type: 'SHORTHAND_LONGHAND', 20 | description: `Do not mix the shorthand property "${ 21 | shorthand 22 | }" with its longhand properties "${longhands.join( 23 | ', ' 24 | )}". Use the single shorthand property "${shorthand}".`, 25 | shorthand, 26 | longhands, 27 | }) 28 | } else { 29 | // if a single longhand property is used 30 | if (!allowSingle || longhands.length > 1) { 31 | // TODO: fix 32 | 33 | addWarning({ 34 | type: 'SHORTHAND_LONGHAND', 35 | description: `Do not use the longhand properties "${longhands.join( 36 | ', ' 37 | )}". Use the shorthand property "${shorthand}".`, 38 | shorthand, 39 | longhands, 40 | }) 41 | } 42 | } 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /packages/elodin-plugin-unit/yarn.lock: -------------------------------------------------------------------------------- 1 | # THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. 2 | # yarn lockfile v1 3 | 4 | 5 | bredon-tools@^3.0.0: 6 | version "3.0.0" 7 | resolved "https://registry.yarnpkg.com/bredon-tools/-/bredon-tools-3.0.0.tgz#a22501b19cc144b62c7b6377bdbc49e5cc849c87" 8 | dependencies: 9 | bredon "^3.0.0" 10 | bredon-types "^3.0.0" 11 | 12 | bredon-types@^3.0.0: 13 | version "3.0.0" 14 | resolved "https://registry.yarnpkg.com/bredon-types/-/bredon-types-3.0.0.tgz#1d49122f12df2c2868ba3065e27eede76b5af93e" 15 | 16 | bredon@^3.0.0: 17 | version "3.0.0" 18 | resolved "https://registry.yarnpkg.com/bredon/-/bredon-3.0.0.tgz#300df4374587f0fe0d633b63e31590727f12bc7a" 19 | dependencies: 20 | bredon-types "^3.0.0" 21 | tokenize-sync "^1.0.0" 22 | 23 | css-in-js-utils@^2.0.0: 24 | version "2.0.0" 25 | resolved "https://registry.yarnpkg.com/css-in-js-utils/-/css-in-js-utils-2.0.0.tgz#5af1dd70f4b06b331f48d22a3d86e0786c0b9435" 26 | dependencies: 27 | hyphenate-style-name "^1.0.2" 28 | 29 | elodin@^0.1.0: 30 | version "0.1.0" 31 | resolved "https://registry.yarnpkg.com/elodin/-/elodin-0.1.0.tgz#56f8e712d997c01e05e753d0d57f0851720d54bd" 32 | 33 | hyphenate-style-name@^1.0.2: 34 | version "1.0.2" 35 | resolved "https://registry.yarnpkg.com/hyphenate-style-name/-/hyphenate-style-name-1.0.2.tgz#31160a36930adaf1fc04c6074f7eb41465d4ec4b" 36 | 37 | tokenize-sync@^1.0.0: 38 | version "1.0.0" 39 | resolved "https://registry.yarnpkg.com/tokenize-sync/-/tokenize-sync-1.0.0.tgz#65b5b72bb208b013166e4d253e0b8b4990c70e83" 40 | -------------------------------------------------------------------------------- /packages/elodin-plugin-longhand-property/src/enforceLonghand.js: -------------------------------------------------------------------------------- 1 | /* @flow */ 2 | import { extractShorthandLonghand, longhandMap } from 'elodin-utils' 3 | 4 | import type { PluginInterface } from '../../../flowtypes/PluginInterface' 5 | 6 | export default function enforceLonghand( 7 | { style, fix, addWarning }: PluginInterface, 8 | { allowSingle = false }: Object = {} 9 | ) { 10 | const { shorthandProps, longhandProps } = extractShorthandLonghand(style) 11 | 12 | shorthandProps.forEach(shorthand => { 13 | if (longhandProps[shorthand]) { 14 | const longhands = longhandProps[shorthand] 15 | 16 | // if shorthand and longhand properties are mixed 17 | if (longhands.length > 0) { 18 | // TODO: fix 19 | addWarning({ 20 | type: 'SHORTHAND_LONGHAND', 21 | description: `Do not mix the shorthand property "${ 22 | shorthand 23 | }" with its longhand properties "${longhands.join( 24 | ', ' 25 | )}". Use the longhand properties "${longhandMap[shorthand].join( 26 | ', ' 27 | )}".`, 28 | shorthand, 29 | longhands, 30 | }) 31 | } else { 32 | // if a single shorthand is used 33 | if (!allowSingle) { 34 | // TODO: fix 35 | addWarning({ 36 | type: 'SHORTHAND_LONGHAND', 37 | description: `Do not use the shorthand property "${ 38 | shorthand 39 | }". Use the longhand properties "${longhandMap[shorthand].join( 40 | ', ' 41 | )}".`, 42 | shorthand, 43 | longhands, 44 | }) 45 | } 46 | } 47 | } 48 | }) 49 | } 50 | -------------------------------------------------------------------------------- /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": "yarn format && yarn lint && yarn test:coverage && yarn flow", 8 | "format": "prettier --write \"packages/*/src/**/*.js\"", 9 | "flow": "flow", 10 | "lint": "eslint packages/*/src/**/*.js", 11 | "release": "git pull --rebase && yarn 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 bootstrap && yarn 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-plugin-add-module-exports": "^0.2.1", 30 | "babel-preset-es2015": "^6.22.0", 31 | "babel-preset-react": "^6.22.0", 32 | "babel-preset-stage-0": "^6.22.0", 33 | "codeclimate-test-reporter": "^0.4.0", 34 | "cross-env": "^5.0.1", 35 | "eslint": "^3.14.1", 36 | "eslint-config-airbnb": "^14.0.0", 37 | "eslint-plugin-flowtype": "^2.30.0", 38 | "eslint-plugin-import": "^2.2.0", 39 | "eslint-plugin-jsx-a11y": "^3.0.2", 40 | "eslint-plugin-react": "^6.9.0", 41 | "flow-bin": "^0.57.3", 42 | "jest": "^18.1.0", 43 | "lerna": "^2.5.1", 44 | "prettier": "^1.8.2", 45 | "rimraf": "^2.6.1", 46 | "sinon": "^1.17.7" 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /packages/elodin-plugin-unit/src/__tests__/unitValue-test.js: -------------------------------------------------------------------------------- 1 | import lint from 'elodin' 2 | 3 | import unit from '../index' 4 | 5 | describe('Unit plugin', () => { 6 | it('should warn if no units are used', () => { 7 | const warnings = lint({ 8 | plugins: [ 9 | unit({ 10 | units: ['px', 'em'], 11 | }), 12 | ], 13 | })({ 14 | fontSize: '12px', 15 | height: '10em', 16 | width: 200, 17 | }) 18 | 19 | expect(warnings.length).toBe(1) 20 | expect(warnings[0]).toEqual({ 21 | type: 'UNIT', 22 | description: 'Do not use plain numbers for "width". Use one of "px, em".', 23 | property: 'width', 24 | suggestion: '200px', 25 | value: '200', 26 | }) 27 | }) 28 | 29 | it('should warn if wrong units are used', () => { 30 | const warnings = lint({ 31 | plugins: [ 32 | unit({ 33 | units: ['px', 'em'], 34 | }), 35 | ], 36 | })({ 37 | fontSize: '12pt', 38 | height: '10em', 39 | width: '200px', 40 | }) 41 | 42 | expect(warnings.length).toBe(1) 43 | expect(warnings[0]).toEqual({ 44 | type: 'UNIT', 45 | description: 46 | 'Do not use the unit "pt" for "fontSize". Use one of "px, em".', 47 | property: 'fontSize', 48 | suggestion: '12px', 49 | value: '12pt', 50 | }) 51 | }) 52 | 53 | it('should warn if wrong units are used', () => { 54 | const warnings = lint({ 55 | plugins: [ 56 | unit({ 57 | units: ['px', 'em'], 58 | unitsPerProperty: { 59 | fontSize: ['pt'], 60 | height: ['px'], 61 | }, 62 | }), 63 | ], 64 | })({ 65 | fontSize: '12pt', 66 | height: '10em', 67 | width: '200px', 68 | }) 69 | 70 | expect(warnings.length).toBe(1) 71 | expect(warnings[0]).toEqual({ 72 | type: 'UNIT', 73 | description: 'Do not use the unit "em" for "height". Use one of "px".', 74 | property: 'height', 75 | suggestion: '10px', 76 | value: '10em', 77 | }) 78 | }) 79 | }) 80 | -------------------------------------------------------------------------------- /packages/elodin-utils/src/parser/__tests__/parseCircularLonghand-test.js: -------------------------------------------------------------------------------- 1 | import parseCircularLonghand from '../parseCircularLonghand' 2 | 3 | describe('Parsing circular longhand properties', () => { 4 | it('should return a single shorthand value', () => { 5 | expect( 6 | parseCircularLonghand('padding', { 7 | paddingTop: '2px', 8 | paddingRight: '2px', 9 | paddingBottom: '2px', 10 | paddingLeft: '2px', 11 | }) 12 | ).toEqual('2px') 13 | 14 | expect( 15 | parseCircularLonghand('padding', { 16 | paddingTop: '2px', 17 | paddingRight: '4px', 18 | paddingBottom: '2px', 19 | paddingLeft: '4px', 20 | }) 21 | ).toEqual('2px 4px') 22 | 23 | expect( 24 | parseCircularLonghand('padding', { 25 | paddingTop: '2px', 26 | paddingRight: '4px', 27 | paddingBottom: '3px', 28 | paddingLeft: '4px', 29 | }) 30 | ).toEqual('2px 4px 3px') 31 | 32 | expect( 33 | parseCircularLonghand('padding', { 34 | paddingTop: '2px', 35 | paddingRight: '2px', 36 | paddingBottom: '3px', 37 | paddingLeft: '2px', 38 | }) 39 | ).toEqual('2px 2px 3px') 40 | 41 | expect( 42 | parseCircularLonghand('padding', { 43 | paddingTop: '2px', 44 | paddingRight: '4px', 45 | paddingBottom: '3px', 46 | paddingLeft: '1px', 47 | }) 48 | ).toEqual('2px 4px 3px 1px') 49 | 50 | expect( 51 | parseCircularLonghand('padding', { 52 | paddingTop: '2px', 53 | paddingBottom: '3px', 54 | }) 55 | ).toEqual('2px 0 3px') 56 | 57 | expect( 58 | parseCircularLonghand('padding', { 59 | paddingLeft: '3px', 60 | }) 61 | ).toEqual('0 0 0 3px') 62 | 63 | expect( 64 | parseCircularLonghand('padding', { 65 | paddingTop: '3px', 66 | }) 67 | ).toEqual('3px 0 0') 68 | 69 | expect( 70 | parseCircularLonghand('borderColor', { 71 | borderTopColor: 'red', 72 | }) 73 | ).toEqual('red inherit inherit') 74 | 75 | expect( 76 | parseCircularLonghand('borderStyle', { 77 | borderRightStyle: 'solid', 78 | }) 79 | ).toEqual('none solid none none') 80 | }) 81 | }) 82 | -------------------------------------------------------------------------------- /packages/elodin-utils/src/data/propertyShorthands.js: -------------------------------------------------------------------------------- 1 | export default { 2 | animation: [ 3 | 'animationTimingFunction', 4 | 'animationDuration', 5 | 'animationDelay', 6 | 'animationIterationCount', 7 | 'animationDirection', 8 | 'animationFillMode', 9 | 'animationPlayState', 10 | 'animationName', 11 | ], 12 | background: [ 13 | 'backgroundAttachment', 14 | 'backgroundClip', 15 | 'backgroundColor', 16 | 'backgroundImage', 17 | 'backgroundOrigin', 18 | 'backgroundPosition', 19 | 'backgroundRepeat', 20 | 'backgroundSize', 21 | ], 22 | border: ['borderColor', 'borderStyle', 'borderWidth'], 23 | borderTop: ['borderTopColor', 'borderTopStyle', 'borderTopWidth'], 24 | borderRight: ['borderRightColor', 'borderRightStyle', 'borderRightWidth'], 25 | borderBottom: ['borderBottomColor', 'borderBottomStyle', 'borderBottomWidth'], 26 | borderLeft: ['borderLeftColor', 'borderLeftStyle', 'borderLeftWidth'], 27 | borderWidth: [ 28 | 'borderTopWidth', 29 | 'borderRightWidth', 30 | 'borderBottomWidth', 31 | 'borderLeftWidth', 32 | ], 33 | borderStyle: [ 34 | 'borderTopStyle', 35 | 'borderRightStyle', 36 | 'borderBottomStyle', 37 | 'borderLeftStyle', 38 | ], 39 | borderColor: [ 40 | 'borderTopColor', 41 | 'borderRightColor', 42 | 'borderBottomColor', 43 | 'borderLeftColor', 44 | ], 45 | borderImage: [ 46 | 'borderImageOutset', 47 | 'borderImageRepeat', 48 | 'borderImageSlice', 49 | 'borderImageSource', 50 | 'borderImageWidth', 51 | ], 52 | borderRadius: [ 53 | 'borderTopLeftRadius', 54 | 'borderTopRightRadius', 55 | 'borderBottomRightRadius', 56 | 'borderBottomLeftRadius', 57 | ], 58 | columnRule: ['columnRuleWidth', 'columnRuleStyle', 'columnRuleColor'], 59 | columns: ['columnWidth', 'columnCount'], 60 | margin: ['marginTop', 'marginRight', 'marginBottom', 'marginLeft'], 61 | outline: ['outlineWidth', 'outlineStyle', 'outlineColor'], 62 | padding: ['paddingTop', 'paddingRight', 'paddingBottom', 'paddingLeft'], 63 | perspectiveOrigin: ['perspectiveOriginX', 'perspectiveOriginY'], 64 | textDecoration: [ 65 | 'textDecorationColor', 66 | 'textDecorationStyle', 67 | 'textDecorationLine', 68 | ], 69 | transition: [ 70 | 'transitionDuration', 71 | 'transitionTimingFunction', 72 | 'transitionDelay', 73 | 'transitionProperty', 74 | ], 75 | } 76 | -------------------------------------------------------------------------------- /packages/elodin-utils/src/parser/__tests__/parseBasicLonghand-test.js: -------------------------------------------------------------------------------- 1 | import parseBasicLonghand from '../parseBasicLonghand' 2 | 3 | describe('Parsing longhand properties', () => { 4 | it('should return a single shorthand value', () => { 5 | expect( 6 | parseBasicLonghand('border', { 7 | borderWidth: '2px', 8 | borderStyle: 'solid', 9 | borderColor: '#FFF', 10 | }) 11 | ).toEqual('#FFF solid 2px') 12 | 13 | expect( 14 | parseBasicLonghand('border', { 15 | borderWidth: '2px', 16 | borderStyle: 'solid', 17 | borderColor: '#FFF', 18 | }) 19 | ).toEqual('#FFF solid 2px') 20 | 21 | expect( 22 | parseBasicLonghand('border', { 23 | borderWidth: '2px', 24 | borderStyle: 'solid', 25 | borderColor: '#FFF', 26 | }) 27 | ).toEqual('#FFF solid 2px') 28 | 29 | expect( 30 | parseBasicLonghand('border', { 31 | borderColor: 'blue', 32 | borderStyle: 'solid', 33 | }) 34 | ).toEqual('blue solid') 35 | 36 | expect( 37 | parseBasicLonghand('border', { 38 | borderWidth: '2px', 39 | borderStyle: 'solid', 40 | }) 41 | ).toEqual('solid 2px') 42 | 43 | expect( 44 | parseBasicLonghand('border', { 45 | borderWidth: '2px', 46 | borderStyle: 'solid', 47 | }) 48 | ).toEqual('solid 2px') 49 | 50 | expect( 51 | parseBasicLonghand('animation', { 52 | animationDuration: '3s', 53 | animationTimingFunction: 'ease-in', 54 | animationDelay: '1s', 55 | animationIterationCount: 2, 56 | animationDirection: 'reverse', 57 | animationFillMode: 'both', 58 | animationPlayState: 'paused', 59 | animationName: 'slidein', 60 | }) 61 | ).toEqual('ease-in 3s 1s 2 reverse both paused slidein') 62 | 63 | expect( 64 | parseBasicLonghand('animation', { 65 | animationDuration: '3s', 66 | animationTimingFunction: 'ease-in', 67 | animationDelay: '1s', 68 | animationIterationCount: 2, 69 | animationDirection: 'reverse', 70 | animationFillMode: 'both', 71 | animationPlayState: 'paused', 72 | animationName: 'slidein', 73 | }) 74 | ).toEqual('ease-in 3s 1s 2 reverse both paused slidein') 75 | 76 | expect( 77 | parseBasicLonghand('animation', { 78 | animationDuration: '3s', 79 | animationTimingFunction: 'linear', 80 | animationDelay: '1s', 81 | animationName: 'slidein', 82 | }) 83 | ).toEqual('linear 3s 1s slidein') 84 | }) 85 | }) 86 | -------------------------------------------------------------------------------- /packages/elodin-plugin-shorthand-property/src/__tests__/enforceShorthand-test.js: -------------------------------------------------------------------------------- 1 | import enforceShorthand from '../enforceShorthand' 2 | 3 | const mockPluginInterface = warnings => (style, fix) => ({ 4 | style, 5 | addWarning: warning => warnings.push(warning), 6 | fix: fix || false, 7 | }) 8 | 9 | describe('Enforcing shorthand properties', () => { 10 | it('should warn if longhand properties are used', () => { 11 | const warnings = [] 12 | const pluginInterface = mockPluginInterface(warnings) 13 | 14 | enforceShorthand( 15 | pluginInterface({ 16 | paddingLeft: '2px', 17 | paddingTop: '4px', 18 | }) 19 | ) 20 | 21 | expect(warnings.length).toBe(1) 22 | expect(warnings[0]).toEqual({ 23 | type: 'SHORTHAND_LONGHAND', 24 | description: 25 | 'Do not use the longhand properties "paddingLeft, paddingTop". Use the shorthand property "padding".', 26 | longhands: ['paddingLeft', 'paddingTop'], 27 | shorthand: 'padding', 28 | }) 29 | }) 30 | 31 | it('should warn if more than one longhand property is used', () => { 32 | const warnings = [] 33 | const pluginInterface = mockPluginInterface(warnings) 34 | 35 | enforceShorthand( 36 | pluginInterface({ 37 | paddingLeft: '2px', 38 | paddingTop: '4px', 39 | }), 40 | { allowSingle: true } 41 | ) 42 | 43 | expect(warnings.length).toBe(1) 44 | expect(warnings[0]).toEqual({ 45 | type: 'SHORTHAND_LONGHAND', 46 | description: 47 | 'Do not use the longhand properties "paddingLeft, paddingTop". Use the shorthand property "padding".', 48 | longhands: ['paddingLeft', 'paddingTop'], 49 | shorthand: 'padding', 50 | }) 51 | }) 52 | 53 | it('should not warn if only one longhand property is used', () => { 54 | const warnings = [] 55 | const pluginInterface = mockPluginInterface(warnings) 56 | 57 | enforceShorthand( 58 | pluginInterface({ 59 | paddingLeft: '2px', 60 | }), 61 | { allowSingle: true } 62 | ) 63 | 64 | expect(warnings.length).toBe(0) 65 | }) 66 | 67 | it('should warn if shorthand and longhand properties are mixed', () => { 68 | const warnings = [] 69 | const pluginInterface = mockPluginInterface(warnings) 70 | 71 | enforceShorthand( 72 | pluginInterface({ 73 | paddingLeft: '2px', 74 | paddingTop: '4px', 75 | padding: '4px 2px', 76 | }) 77 | ) 78 | 79 | expect(warnings.length).toBe(1) 80 | expect(warnings[0]).toEqual({ 81 | type: 'SHORTHAND_LONGHAND', 82 | description: 83 | 'Do not mix the shorthand property "padding" with its longhand properties "paddingLeft, paddingTop". Use the single shorthand property "padding".', 84 | longhands: ['paddingLeft', 'paddingTop'], 85 | shorthand: 'padding', 86 | }) 87 | }) 88 | }) 89 | -------------------------------------------------------------------------------- /packages/elodin-data/src/generator/compareSupportData.js: -------------------------------------------------------------------------------- 1 | const propertyMap = require('../modules/data/propertyMap') 2 | const fullSupport = require('./fullSupport') 3 | const partialSupport = require('./partialSupport') 4 | 5 | const changedPartial = {} 6 | const changedFull = {} 7 | 8 | Object.keys(fullSupport).forEach(property => { 9 | const mapValues = propertyMap[property] 10 | if (mapValues && mapValues.compatibility) { 11 | if (mapValues.compatibility.full) { 12 | Object.keys(fullSupport[property]).forEach(browser => { 13 | if ( 14 | mapValues.compatibility.full[browser] != 15 | fullSupport[property][browser] 16 | ) { 17 | if (!changedFull[property]) { 18 | changedFull[property] = {} 19 | } 20 | changedFull[property][browser] = { 21 | old: mapValues.compatibility.full[browser], 22 | new: fullSupport[property][browser], 23 | } 24 | } 25 | }) 26 | } 27 | } 28 | }) 29 | 30 | Object.keys(partialSupport).forEach(property => { 31 | const mapValues = propertyMap[property] 32 | if (mapValues && mapValues.compatibility) { 33 | if (mapValues.compatibility.partial) { 34 | Object.keys(partialSupport[property]).forEach(browser => { 35 | if ( 36 | mapValues.compatibility.partial[browser] !== 37 | partialSupport[property][browser] 38 | ) { 39 | if (!changedPartial[property]) { 40 | changedPartial[property] = {} 41 | } 42 | changedPartial[property][browser] = { 43 | old: mapValues.compatibility.partial[browser], 44 | new: partialSupport[property][browser], 45 | } 46 | } 47 | }) 48 | } 49 | } 50 | }) 51 | 52 | console.log('\nComparing caniuse data was successful.') 53 | let error = false 54 | if (Object.keys(changedPartial).length >= 1) { 55 | console.log('\n---- Partial Support changed: ---- \n') 56 | 57 | Object.keys(changedPartial).forEach(prop => { 58 | console.log(`- ${prop}:`) 59 | Object.keys(changedPartial[prop]).forEach(browser => { 60 | console.log( 61 | `\t${browser} (old: ${changedPartial[prop][browser].old}, new: ${ 62 | changedPartial[prop][browser].new 63 | })` 64 | ) 65 | }) 66 | }) 67 | error = true 68 | } 69 | if (Object.keys(changedFull).length >= 1) { 70 | console.log('\n---- Full Support changed: ---- \n') 71 | 72 | Object.keys(changedFull).forEach(prop => { 73 | console.log(`- ${prop}:`) 74 | Object.keys(changedFull[prop]).forEach(browser => { 75 | console.log( 76 | `\t${browser} (old: ${changedFull[prop][browser].old}, new: ${ 77 | changedFull[prop][browser].new 78 | })` 79 | ) 80 | }) 81 | }) 82 | error = true 83 | } 84 | 85 | if (error) { 86 | process.exit(1) 87 | } 88 | 89 | console.log('Caniuse data is up to date!') 90 | process.exit(0) 91 | -------------------------------------------------------------------------------- /.github/CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing 2 | Want to get involved? **Awesome!**
3 | Please read the following guide on how to contribute, create issues and send pull requests. 4 | 5 | If you have a feature request please create an issue. Also if you're even improving Fela by any kind please don't be shy and send a pull request to let everyone benefit. 6 | 7 | ## Project setup 8 | 9 | We assume that you got [node](https://nodejs.org) and [yarn](https://yarnpkg.com) in your environment. To get started with the repo: 10 | 11 | ``` 12 | git clone git@github.com:rofrischmann/elodin.git 13 | cd elodin 14 | yarn install 15 | yarn setup 16 | ``` 17 | 18 | **Elodin is a collection of multiple packages**. We use the tool [lerna](https://lernajs.io/) to maintain it. All source code can be found in the folder [/packages](packages). 19 | 20 | ## Commands 21 | 22 | Tests: 23 | 24 | ``` 25 | yarn test 26 | ``` 27 | 28 | Linting: 29 | 30 | ``` 31 | yarn lint 32 | ``` 33 | 34 | Flow: 35 | 36 | ``` 37 | yarn flow 38 | ``` 39 | 40 | Formatting: 41 | 42 | ``` 43 | yarn format 44 | ``` 45 | 46 | You can also run all four of them at the same time: 47 | 48 | ``` 49 | yarn run check 50 | ``` 51 | 52 | Note: If your tests use other elodin packages as depedencies, you might need to run `yarn build` (it's a part of `yarn setup`). 53 | 54 | ## Tip for developing 55 | 56 | Fela contains many examples. It can be handy to smoke test your changes as a part of [example-react](http://fela.js.org/docs/introduction/Examples.html). 57 | 58 | ## Code Formatting 59 | We use [prettier](https://prettier.io/), an opinionated code formatter. If you're using [Atom](https://atom.io) we recommend [prettier-atom](https://atom.io/packages/prettier-atom) with the **format on save**. If you're using [Sublime](https://www.sublimetext.com/) try [SublimeJSPrettier](https://github.com/jonlabelle/SublimeJsPrettier). For other integrations, please check the prettier's [homepage](https://prettier.io/). 60 | 61 | ## Guide-Lines 62 | 1. Fork the repo and create your feature/bug branch from `master`. 63 | 2. If you've added code that should be tested, add tests! 64 | 3. If you've changed APIs, update the documentation. 65 | 4. Ensure that all tests pass (`yarn check`). 66 | 67 | ## Creating Issues 68 | ### Known Issues 69 | Before creating an issue please make sure it has not aleady been created/solved before. Also please search the docs for possible explanations. 70 | Browse both open **and** closed issues. If you feel something is unclear you might also add it to the docs or FAQ's directly. 71 | 72 | ### Bugs & Feature Requests 73 | If you found a new bug or got a feature request feel free to file a new issue. For both we got predefined templates which you should fill out as detailed as possible. 74 | 75 | ## Sending Pull Requests 76 | If you are creating a pull request, try to use commit messages that are self-explanatory. Be sure to meet all guide-lines from above. If you're pushing a Work in Progress, please flag it and optionally add a description if something needs to be discussed. 77 | -------------------------------------------------------------------------------- /packages/elodin-utils/src/parser/parseShorthand.js: -------------------------------------------------------------------------------- 1 | /* @flow */ 2 | import { parse, generate } from 'bredon' 3 | import { isValidProperty } from 'bredon-validate' 4 | 5 | import { isValueList, isValue } from 'bredon-types' 6 | 7 | import propertyShorthands from '../data/propertyShorthands' 8 | import arrayReduce from '../arrayReduce' 9 | 10 | const circularPattern = [[0, 0, 0, 0], [0, 1, 0, 1], [0, 1, 2, 1], [0, 1, 2, 3]] 11 | const axesPattern = [[0, 0], [0, 1]] 12 | 13 | const patternMap = { 14 | padding: { 15 | pattern: circularPattern, 16 | values: propertyShorthands.padding, 17 | }, 18 | margin: { 19 | pattern: circularPattern, 20 | values: propertyShorthands.margin, 21 | }, 22 | borderRadius: { 23 | pattern: circularPattern, 24 | values: propertyShorthands.borderRadius, 25 | }, 26 | borderWidth: { 27 | pattern: circularPattern, 28 | values: propertyShorthands.borderWidth, 29 | }, 30 | borderStyle: { 31 | pattern: circularPattern, 32 | values: propertyShorthands.borderStyle, 33 | }, 34 | borderColor: { 35 | pattern: circularPattern, 36 | values: propertyShorthands.borderColor, 37 | }, 38 | perspectiveOrigin: { 39 | pattern: axesPattern, 40 | values: propertyShorthands.perspectiveOrigin, 41 | }, 42 | } 43 | 44 | function parseShorthandValue(property: string, ast: Object) { 45 | if (isValueList(ast)) { 46 | if (ast.body.length > 1) { 47 | // TODO: parse multi values as well 48 | return {} 49 | } 50 | 51 | return parseShorthandValue(property, ast.body[0]) 52 | } 53 | 54 | if (isValue(ast)) { 55 | const valueCount = ast.body.length 56 | 57 | if (patternMap[property]) { 58 | const { pattern, values } = patternMap[property] 59 | const matchingPattern = pattern[valueCount - 1] 60 | 61 | return arrayReduce( 62 | values, 63 | (longhands, longhandProperty, index) => { 64 | longhands[longhandProperty] = generate( 65 | ast.body[matchingPattern[index]] 66 | ) 67 | 68 | return longhands 69 | }, 70 | {} 71 | ) 72 | } 73 | 74 | const longhands = [...propertyShorthands[property]] 75 | 76 | return arrayReduce( 77 | ast.body, 78 | (spread, node) => { 79 | const longhand = longhands.find(prop => 80 | isValidProperty(prop, generate(node)) 81 | ) 82 | 83 | if (longhand) { 84 | longhands.splice(longhands.indexOf(longhand), 1) 85 | spread[longhand] = generate(node) 86 | } 87 | 88 | return spread 89 | }, 90 | {} 91 | ) 92 | } 93 | 94 | // TODO: error? 95 | return {} 96 | } 97 | 98 | /* TODO: 99 | background, font 100 | */ 101 | export default function parseShorthand( 102 | property: string, 103 | value: string 104 | ): Object { 105 | if (!propertyShorthands.hasOwnProperty(property)) { 106 | console.warn(`${property} is not a shorthand property.`) 107 | return {} 108 | } 109 | 110 | return parseShorthandValue(property, parse(value)) 111 | } 112 | -------------------------------------------------------------------------------- /packages/elodin-plugin-unit/src/index.js: -------------------------------------------------------------------------------- 1 | /* @flow */ 2 | import { getSingleValue, wrap } from 'bredon-tools' 3 | import isUnitlessProperty from 'css-in-js-utils/lib/isUnitlessProperty' 4 | 5 | import type { PluginInterface } from '../../../flowtypes/PluginInterface' 6 | 7 | const PLUGIN_TYPE = 'UNIT' 8 | 9 | type Options = { 10 | unitsPerProperty?: { [property: string]: Array }, 11 | defaultUnit?: string, 12 | units: Array, 13 | } 14 | 15 | function removeDuplicate(arr) { 16 | return arr.filter((element, index) => arr.indexOf(element) === index) 17 | } 18 | 19 | function getPreferedUnits(property, { units, defaultUnit, unitsPerProperty }) { 20 | if (unitsPerProperty.hasOwnProperty(property)) { 21 | return unitsPerProperty[property] 22 | } 23 | 24 | return removeDuplicate([defaultUnit, ...units]) 25 | } 26 | 27 | function unit( 28 | { style, fix, bredon, addWarning }: PluginInterface, 29 | options: Options 30 | ) { 31 | const { defaultUnit = 'px', units = [], unitsPerProperty = {} } = options 32 | 33 | for (const property in style) { 34 | // is the property is unitless we don't add units 35 | if (isUnitlessProperty(property)) { 36 | continue 37 | } 38 | 39 | const ast = style[property] 40 | const node = getSingleValue(ast) 41 | 42 | // if the value is a plain number 43 | if (node) { 44 | if (bredon.isInteger(node) || bredon.isFloat(node)) { 45 | const preferedUnits = getPreferedUnits(property, { 46 | units, 47 | unitsPerProperty, 48 | defaultUnit, 49 | }) 50 | 51 | const newNode = bredon.dimension(node, preferedUnits[0]) 52 | 53 | if (fix) { 54 | wrap(ast.body[0]).replaceChildNode(node, newNode) 55 | } else { 56 | addWarning({ 57 | type: PLUGIN_TYPE, 58 | description: `Do not use plain numbers for "${ 59 | property 60 | }". Use one of "${preferedUnits.join(', ')}".`, 61 | suggestion: bredon.generate(newNode), 62 | property, 63 | value: bredon.generate(ast), 64 | }) 65 | } 66 | } else if (bredon.isDimension(node)) { 67 | const preferedUnits = getPreferedUnits(property, { 68 | units, 69 | unitsPerProperty, 70 | defaultUnit, 71 | }) 72 | 73 | if (preferedUnits.indexOf(node.unit) === -1) { 74 | const newNode = bredon.dimension(node.value, preferedUnits[0]) 75 | 76 | if (fix) { 77 | wrap(ast.body[0]).replaceChildNode(node, newNode) 78 | } else { 79 | addWarning({ 80 | type: PLUGIN_TYPE, 81 | description: `Do not use the unit "${node.unit}" for "${ 82 | property 83 | }". Use one of "${preferedUnits.join(', ')}".`, 84 | suggestion: bredon.generate(newNode), 85 | 86 | property, 87 | value: bredon.generate(ast), 88 | }) 89 | } 90 | } 91 | } 92 | } 93 | } 94 | } 95 | 96 | export default (options: Options) => (pluginInterface: PluginInterface) => 97 | unit(pluginInterface, options) 98 | -------------------------------------------------------------------------------- /.github/CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | # Contributor Covenant Code of Conduct 2 | 3 | ## Our Pledge 4 | 5 | In the interest of fostering an open and welcoming environment, we as 6 | contributors and maintainers pledge to making participation in our project and 7 | our community a harassment-free experience for everyone, regardless of age, body 8 | size, disability, ethnicity, gender identity and expression, level of experience, 9 | nationality, personal appearance, race, religion, or sexual identity and 10 | orientation. 11 | 12 | ## Our Standards 13 | 14 | Examples of behavior that contributes to creating a positive environment 15 | include: 16 | 17 | * Using welcoming and inclusive language 18 | * Being respectful of differing viewpoints and experiences 19 | * Gracefully accepting constructive criticism 20 | * Focusing on what is best for the community 21 | * Showing empathy towards other community members 22 | 23 | Examples of unacceptable behavior by participants include: 24 | 25 | * The use of sexualized language or imagery and unwelcome sexual attention or 26 | advances 27 | * Trolling, insulting/derogatory comments, and personal or political attacks 28 | * Public or private harassment 29 | * Publishing others' private information, such as a physical or electronic 30 | address, without explicit permission 31 | * Other conduct which could reasonably be considered inappropriate in a 32 | professional setting 33 | 34 | ## Our Responsibilities 35 | 36 | Project maintainers are responsible for clarifying the standards of acceptable 37 | behavior and are expected to take appropriate and fair corrective action in 38 | response to any instances of unacceptable behavior. 39 | 40 | Project maintainers have the right and responsibility to remove, edit, or 41 | reject comments, commits, code, wiki edits, issues, and other contributions 42 | that are not aligned to this Code of Conduct, or to ban temporarily or 43 | permanently any contributor for other behaviors that they deem inappropriate, 44 | threatening, offensive, or harmful. 45 | 46 | ## Scope 47 | 48 | This Code of Conduct applies both within project spaces and in public spaces 49 | when an individual is representing the project or its community. Examples of 50 | representing a project or community include using an official project e-mail 51 | address, posting via an official social media account, or acting as an appointed 52 | representative at an online or offline event. Representation of a project may be 53 | further defined and clarified by project maintainers. 54 | 55 | ## Enforcement 56 | 57 | Instances of abusive, harassing, or otherwise unacceptable behavior may be 58 | reported by contacting the project team at . All 59 | complaints will be reviewed and investigated and will result in a response that 60 | is deemed necessary and appropriate to the circumstances. The project team is 61 | obligated to maintain confidentiality with regard to the reporter of an incident. 62 | Further details of specific enforcement policies may be posted separately. 63 | 64 | Project maintainers who do not follow or enforce the Code of Conduct in good 65 | faith may face temporary or permanent repercussions as determined by other 66 | members of the project's leadership. 67 | 68 | ## Attribution 69 | 70 | This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, 71 | available at [http://contributor-covenant.org/version/1/4][version] 72 | 73 | [homepage]: http://contributor-covenant.org 74 | [version]: http://contributor-covenant.org/version/1/4/ -------------------------------------------------------------------------------- /packages/elodin-utils/src/parser/__tests__/parseShorthand-test.js: -------------------------------------------------------------------------------- 1 | import parseShorthand from '../parseShorthand' 2 | 3 | describe('Parsing shorthand values', () => { 4 | it('should return an object of longhand values using types', () => { 5 | expect(parseShorthand('padding', '2px')).toEqual({ 6 | paddingTop: '2px', 7 | paddingRight: '2px', 8 | paddingBottom: '2px', 9 | paddingLeft: '2px', 10 | }) 11 | 12 | expect(parseShorthand('padding', '2px 4px')).toEqual({ 13 | paddingTop: '2px', 14 | paddingRight: '4px', 15 | paddingBottom: '2px', 16 | paddingLeft: '4px', 17 | }) 18 | 19 | expect(parseShorthand('padding', '2px 4px 3px')).toEqual({ 20 | paddingTop: '2px', 21 | paddingRight: '4px', 22 | paddingBottom: '3px', 23 | paddingLeft: '4px', 24 | }) 25 | 26 | expect(parseShorthand('padding', '2px 4px 3px 1px')).toEqual({ 27 | paddingTop: '2px', 28 | paddingRight: '4px', 29 | paddingBottom: '3px', 30 | paddingLeft: '1px', 31 | }) 32 | 33 | expect(parseShorthand('border', '2px solid #FFF')).toEqual({ 34 | borderWidth: '2px', 35 | borderStyle: 'solid', 36 | borderColor: '#FFF', 37 | }) 38 | 39 | expect(parseShorthand('border', '#FFF 2px solid')).toEqual({ 40 | borderWidth: '2px', 41 | borderStyle: 'solid', 42 | borderColor: '#FFF', 43 | }) 44 | 45 | expect(parseShorthand('border', '#FFF solid 2px')).toEqual({ 46 | borderWidth: '2px', 47 | borderStyle: 'solid', 48 | borderColor: '#FFF', 49 | }) 50 | 51 | expect(parseShorthand('border', 'blue solid')).toEqual({ 52 | borderColor: 'blue', 53 | borderStyle: 'solid', 54 | }) 55 | 56 | expect(parseShorthand('border', 'solid 2px')).toEqual({ 57 | borderWidth: '2px', 58 | borderStyle: 'solid', 59 | }) 60 | 61 | expect(parseShorthand('border', '2px solid')).toEqual({ 62 | borderWidth: '2px', 63 | borderStyle: 'solid', 64 | }) 65 | 66 | expect( 67 | parseShorthand('animation', '3s ease-in 1s 2 reverse both paused slidein') 68 | ).toEqual({ 69 | animationDuration: '3s', 70 | animationTimingFunction: 'ease-in', 71 | animationDelay: '1s', 72 | animationIterationCount: '2', 73 | animationDirection: 'reverse', 74 | animationFillMode: 'both', 75 | animationPlayState: 'paused', 76 | animationName: 'slidein', 77 | }) 78 | 79 | expect( 80 | parseShorthand('animation', 'slidein 2 3s 1s reverse ease-in both paused') 81 | ).toEqual({ 82 | animationDuration: '3s', 83 | animationTimingFunction: 'ease-in', 84 | animationDelay: '1s', 85 | animationIterationCount: '2', 86 | animationDirection: 'reverse', 87 | animationFillMode: 'both', 88 | animationPlayState: 'paused', 89 | animationName: 'slidein', 90 | }) 91 | 92 | expect(parseShorthand('animation', '3s linear 1s slidein')).toEqual({ 93 | animationDuration: '3s', 94 | animationTimingFunction: 'linear', 95 | animationDelay: '1s', 96 | animationName: 'slidein', 97 | }) 98 | 99 | expect(parseShorthand('transition', '300ms ease-in all')).toEqual({ 100 | transitionProperty: 'all', 101 | transitionTimingFunction: 'ease-in', 102 | transitionDuration: '300ms', 103 | }) 104 | 105 | expect(parseShorthand('transition', 'all 300ms ease-in 1s')).toEqual({ 106 | transitionProperty: 'all', 107 | transitionTimingFunction: 'ease-in', 108 | transitionDuration: '300ms', 109 | transitionDelay: '1s', 110 | }) 111 | /* 112 | expect( 113 | parseShorthand('font', 'italic small-caps normal 13px/150% Arial') 114 | ).toEqual({ 115 | fontStyle: 'italic', 116 | fontVariant: 'small-caps', 117 | fontWeight: 'normal', 118 | fontSize: '13px', 119 | lineHeight: '150%', 120 | fontFamily: 'Arial', 121 | }) 122 | 123 | expect(parseShorthand('font', 'Arial 13px')).toEqual({ 124 | fontSize: '13px', 125 | fontFamily: 'Arial', 126 | }) 127 | 128 | expect( 129 | parseShorthand( 130 | 'font', 131 | '15px italic small-caps "Helvetica Neue", Arial, sans-serif' 132 | ) 133 | ).toEqual({ 134 | fontStyle: 'italic', 135 | fontVariant: 'small-caps', 136 | fontSize: '15px', 137 | fontFamily: '"Helvetica Neue", Arial, sans-serif', 138 | })*/ 139 | }) 140 | }) 141 | -------------------------------------------------------------------------------- /packages/elodin-data/src/generator/searchMap.js: -------------------------------------------------------------------------------- 1 | export default { 2 | 'border-radius': 'borderRadius', 3 | 'border-image': [ 4 | 'borderImage', 5 | 'borderImageOutset', 6 | 'borderImageRepeat', 7 | 'borderImageSlice', 8 | 'borderImageSource', 9 | 'borderImageWidth', 10 | ], 11 | flexbox: [ 12 | 'flex', 13 | 'flexBasis', 14 | 'flexDirection', 15 | 'flexGrow', 16 | 'flexFlow', 17 | 'flexShrink', 18 | 'flexWrap', 19 | 'alignContent', 20 | 'alignItems', 21 | 'alignSelf', 22 | 'justifyContent', 23 | 'order', 24 | ], 25 | 'css-transitions': [ 26 | 'transition', 27 | 'transitionDelay', 28 | 'transitionDuration', 29 | 'transitionProperty', 30 | 'transitionTimingFunction', 31 | ], 32 | transforms2d: [ 33 | 'transform', 34 | 'transformOrigin', 35 | 'transformOriginX', 36 | 'transformOriginY', 37 | ], 38 | transforms3d: [ 39 | 'backfaceVisibility', 40 | 'perspective', 41 | 'perspectiveOrigin', 42 | 'transform', 43 | 'transformOrigin', 44 | 'transformStyle', 45 | 'transformOriginX', 46 | 'transformOriginY', 47 | 'transformOriginZ', 48 | ], 49 | 'css-animation': [ 50 | 'animation', 51 | 'animationDelay', 52 | 'animationDirection', 53 | 'animationFillMode', 54 | 'animationDuration', 55 | 'animationIterationCount', 56 | 'animationName', 57 | 'animationPlayState', 58 | 'animationTimingFunction', 59 | ], 60 | 'css-appearance': 'appearance', 61 | 'user-select-none': 'userSelect', 62 | 'css-backdrop-filter': 'backdropFilter', 63 | 'css3-boxsizing': 'boxSizing', 64 | 'font-kerning': 'fontKerning', 65 | 'css-exclusions': ['wrapFlow', 'wrapThrough', 'wrapMargin'], 66 | 'css-snappoints': [ 67 | 'scrollSnapType', 68 | 'scrollSnapPointsX', 69 | 'scrollSnapPointsY', 70 | 'scrollSnapDestination', 71 | 'scrollSnapCoordinate', 72 | ], 73 | 'text-emphasis': [ 74 | 'textEmphasisPosition', 75 | 'textEmphasis', 76 | 'textEmphasisStyle', 77 | 'textEmphasisColor', 78 | ], 79 | 'css-text-align-last': 'textAlignLast', 80 | 'css-boxdecorationbreak': 'boxDecorationBreak', 81 | 'css-clip-path': 'clipPath', 82 | 'css-masks': [ 83 | 'maskImage', 84 | 'maskMode', 85 | 'maskRepeat', 86 | 'maskPosition', 87 | 'maskClip', 88 | 'maskOrigin', 89 | 'maskSize', 90 | 'maskComposite', 91 | 'mask', 92 | 'maskBorderSource', 93 | 'maskBorderMode', 94 | 'maskBorderSlice', 95 | 'maskBorderWidth', 96 | 'maskBorderOutset', 97 | 'maskBorderRepeat', 98 | 'maskBorder', 99 | 'maskType', 100 | ], 101 | 'css-touch-action': 'touchAction', 102 | 'text-size-adjust': 'textSizeAdjust', 103 | 'text-decoration': [ 104 | 'textDecorationStyle', 105 | 'textDecorationSkip', 106 | 'textDecorationLine', 107 | 'textDecorationColor', 108 | ], 109 | 'css-shapes': [ 110 | 'shapeImageThreshold', 111 | 'shapeImageMargin', 112 | 'shapeImageOutside', 113 | ], 114 | 'css3-tabsize': 'tabSize', 115 | 'css-filters': 'filter', 116 | 'css-resize': 'resize', 117 | 'css-hyphens': 'hyphens', 118 | 'css-regions': [ 119 | 'flowInto', 120 | 'flowFrom', 121 | 'breakBefore', 122 | 'breakAfter', 123 | 'breakInside', 124 | 'regionFragment', 125 | ], 126 | 'css-grid': [ 127 | 'gridTemplateColumns', 128 | 'gridTemplateRows', 129 | 'gridTemplateAreas', 130 | 'gridTemplate', 131 | 'gridAutoColumns', 132 | 'gridAutoRows', 133 | 'gridAutoFlow', 134 | 'grid', 135 | 'gridRowStart', 136 | 'gridColumnStart', 137 | 'gridRowEnd', 138 | 'gridRow', 139 | 'gridColumn', 140 | 'gridColumnEnd', 141 | 'gridColumnGap', 142 | 'gridRowGap', 143 | 'gridArea', 144 | 'gridGap', 145 | ], 146 | 'object-fit': ['objectFit', 'objectPosition'], 147 | 'text-overflow': 'textOverflow', 148 | 'background-img-opts': [ 149 | 'backgroundClip', 150 | 'backgroundOrigin', 151 | 'backgroundSize', 152 | ], 153 | 'font-feature': 'fontFeatureSettings', 154 | 'css-boxshadow': 'boxShadow', 155 | multicolumn: [ 156 | 'breakAfter', 157 | 'breakBefore', 158 | 'breakInside', 159 | 'columnCount', 160 | 'columnFill', 161 | 'columnGap', 162 | 'columnRule', 163 | 'columnRuleColor', 164 | 'columnRuleStyle', 165 | 'columnRuleWidth', 166 | 'columns', 167 | 'columnSpan', 168 | 'columnWidth', 169 | 'columnGap', 170 | ], 171 | 'css-writing-mode': ['writingMode'], 172 | } 173 | -------------------------------------------------------------------------------- /packages/elodin/README.md: -------------------------------------------------------------------------------- 1 | > **Caution**: Elodin is still highly experimental WIP. Some shown APIs might not even be released yet. 2 | 3 | # Elodin 4 | 5 | Elodin is a plugin-based quality and optimization tool for CSS in JavaScript libraries.
6 | It helps to write bulletproof and valid styles and pushes developer experience to a next level. 7 | 8 | TravisCI Test Coverage npm downloads npm version Gitter 9 | 10 | ## Support Us 11 | Support Robin Frischmann's work on [Fela](https://github.com/rofrischmann/fela) and its ecosystem (Elodin) directly via [**Patreon**](https://www.patreon.com/rofrischmann). 12 | 13 | Or support us on [**Open Collective**](https://opencollective.com/fela) to fund community work. This also includes Elodin as well.
14 | Thank you to all our backers! 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | ## Installation 28 | ```sh 29 | yarn add elodin 30 | ``` 31 | You may alternatively use `npm i --save elodin`. 32 | 33 | ## The gist 34 | ```javascript 35 | import elodin from 'elodin' 36 | import validation from 'elodin-plugin-validation' 37 | import longhand from 'elodin-plugin-longhand' 38 | 39 | // create a preconfigured linter 40 | const process = elodin({ 41 | plugins: [ 42 | longhand(), 43 | validation({ 44 | removeInvalid: true 45 | }) 46 | ], 47 | fix: true 48 | }) 49 | 50 | const style = { 51 | padding: '20px 0 10px 5em', 52 | fontSize: '15pt', 53 | lineHeight: '1.2em', 54 | width: 'solid' 55 | } 56 | 57 | // using the fix option will automatically fix warnings 58 | process(style) 59 | 60 | style === { 61 | paddingTop: '20px', 62 | paddingBottom: '10px', 63 | paddingLeft: '5em', 64 | fontSize: '15pt', 65 | lineHeight: '1.2em' 66 | } 67 | ``` 68 | 69 | #### Catching Warnings 70 | If the `fix` option is disabled, Elodin will return a list of warning for every style object. 71 | 72 | Taken the above example: 73 | 74 | ```javascript 75 | const warnings = process(style) 76 | 77 | warnings.forEach(warning => console.log(warning.description)) 78 | // => The value "solid" is not valid in combination with "width". 79 | ``` 80 | 81 | ## Documentation 82 | > Coming soon. 83 | 84 | ## Support 85 | Got a question? Come and join us on [Gitter](https://gitter.im/rofrischmann/elodin)!
86 | We'd love to help out. We also highly appreciate any feedback. 87 | 88 | ## Contributing 89 | 90 | This project exists thanks to all the people who contribute. 91 | 92 | We highly appreciate any contribution.
93 | For more information follow the [contribution guide](.github/CONTRIBUTING.md).
94 | Also, please read our [code of conduct](.github/CODE_OF_CONDUCT.md). 95 | 96 | ## License 97 | Elodin is licensed under the [MIT License](http://opensource.org/licenses/MIT).
98 | Documentation is licensed under [Creative Common License](http://creativecommons.org/licenses/by/4.0/).
99 | Created with ♥ by [@rofrischmann](http://rofrischmann.de). 100 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | > **Deprecated**: This repository has been renamed and deprecated. There's something new coming soon that'll be named Elodin instead, but it provides similar benefits & ideas, just in a complete different way. 2 | 3 | # Elodin 4 | 5 | Elodin is a plugin-based quality and optimization tool for CSS in JavaScript libraries.
6 | It helps to write bulletproof and valid styles and pushes developer experience to a next level. 7 | 8 | Elodin is built on top of [Bredon](https://github.com/rofrischmann/bredon) which is a modern CSS value compiler. 9 | 10 | TravisCI Test Coverage npm downloads npm version Gitter 11 | 12 | ## Support Us 13 | Support Robin Frischmann's work on [Fela](https://github.com/rofrischmann/fela) and its ecosystem (Elodin) directly via [**Patreon**](https://www.patreon.com/rofrischmann). 14 | 15 | Or support us on [**Open Collective**](https://opencollective.com/fela) to fund community work. This also includes Elodin as well.
16 | Thank you to all our backers! 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | ## Installation 30 | ```sh 31 | yarn add elodin 32 | ``` 33 | You may alternatively use `npm i --save elodin`. 34 | 35 | ## Features 36 | * Validation using [bredon-validate](https://github.com/rofrischmann/bredon/blob/master/docs/api/bredon-validate/validate.md) 37 | * Most Plugins are fixable 38 | * Detailed Warnings 39 | 40 | ## The gist 41 | ```javascript 42 | import elodin from 'elodin' 43 | import validation from 'elodin-plugin-validation' 44 | import longhand from 'elodin-plugin-longhand' 45 | 46 | // create a preconfigured linter 47 | const process = elodin({ 48 | plugins: [ 49 | longhand(), 50 | validation({ 51 | removeInvalid: true 52 | }) 53 | ], 54 | fix: true 55 | }) 56 | 57 | const style = { 58 | padding: '20px 0 10px 5em', 59 | fontSize: '15pt', 60 | lineHeight: '1.2em', 61 | width: 'solid' 62 | } 63 | 64 | const warnings = process(style) 65 | 66 | // using the fix option will automatically fix warnings 67 | style === { 68 | paddingTop: '20px', 69 | paddingBottom: '10px', 70 | paddingLeft: '5em', 71 | fontSize: '15pt', 72 | lineHeight: '1.2em' 73 | } 74 | ``` 75 | 76 | #### Catching Warnings 77 | If the `fix` option is disabled, Elodin will return a list of warning for every style object. 78 | 79 | Taken the above example: 80 | 81 | ```javascript 82 | warnings.forEach(warning => console.log(warning.description)) 83 | // => The value "solid" is not valid in combination with "width". 84 | ``` 85 | 86 | ## Documentation 87 | > Coming soon. 88 | 89 | ## Support 90 | Got a question? Come and join us on [Gitter](https://gitter.im/rofrischmann/elodin)!
91 | We'd love to help out. We also highly appreciate any feedback. 92 | 93 | ## Contributing 94 | 95 | This project exists thanks to all the people who contribute. 96 | 97 | We highly appreciate any contribution.
98 | For more information follow the [contribution guide](.github/CONTRIBUTING.md).
99 | Also, please read our [code of conduct](.github/CODE_OF_CONDUCT.md). 100 | 101 | ## License 102 | Elodin is licensed under the [MIT License](http://opensource.org/licenses/MIT).
103 | Documentation is licensed under [Creative Common License](http://creativecommons.org/licenses/by/4.0/).
104 | Created with ♥ by [@rofrischmann](http://rofrischmann.de). 105 | -------------------------------------------------------------------------------- /packages/elodin-utils/src/data/valueInitials.js: -------------------------------------------------------------------------------- 1 | export default { 2 | alignContent: 'stretch', 3 | alignSelf: 'auto', 4 | alignItems: 'stretch', 5 | alignmentBaseline: 'auto', 6 | animation: 'none', 7 | animationDelay: 0, 8 | animationDirection: 'normal', 9 | animationDuration: 0, 10 | animationFillMode: 'none', 11 | animationIterationCount: 1, 12 | animationName: 'none', 13 | animationPlayState: 'running', 14 | animationTimingFunction: 'ease', 15 | appearance: 'none', 16 | backfaceVisibility: 'visible', 17 | background: 0, 18 | backgroundAttachment: 'scroll', 19 | backgroundBlendMode: 'normal', 20 | backgroundClip: 'border-box', 21 | backgroundColor: 'transparent', 22 | backgroundImage: 'none', 23 | backgroundOrigin: 'padding-box', 24 | backgroundPosition: '0 0', 25 | backgroundPositionX: 0, 26 | backgroundPositionY: 0, 27 | backgroundRepeat: 'repeat', 28 | backgroundRepeatX: 'repeat', 29 | backgroundRepeatY: 'repeat', 30 | backgroundSize: 'auto auto', 31 | baselineShift: 'auto', 32 | border: 0, 33 | borderBottom: 0, 34 | borderBottomColor: 'inherit', 35 | borderBottomLeftRadius: 0, 36 | borderBottomRightRadius: 0, 37 | borderBottomStyle: 'none', 38 | borderBottomWidth: 'medium', 39 | borderCollapse: 'separate', 40 | borderColor: 'inherit', 41 | borderImage: 'none', 42 | borderImageOutset: 0, 43 | borderImageRepeat: 'stretch', 44 | borderImageSlice: '100%', 45 | borderImageSource: 'none', 46 | borderImageWidth: 1, 47 | borderLeft: 0, 48 | borderLeftColor: 'inherit', 49 | borderLeftStyle: 'none', 50 | borderLeftWidth: 'medium', 51 | borderRadius: 0, 52 | borderRight: 0, 53 | borderRightColor: 'inherit', 54 | borderRightStyle: 'none', 55 | borderRightWidth: 'medium', 56 | borderSpacing: 0, 57 | borderStyle: 'none', 58 | borderTop: 0, 59 | borderTopColor: 'inherit', 60 | borderTopLeftRadius: 0, 61 | borderTopRightRadius: 0, 62 | borderTopStyle: 'none', 63 | borderTopWidth: 'medium', 64 | borderWidth: 'medium', 65 | bottom: 'auto', 66 | boxShadow: 'none', 67 | boxSizing: 'content-box', 68 | bufferedRendering: 'auto', 69 | captionSide: 'top', 70 | clear: 'none', 71 | clip: 'auto', 72 | clipPath: 'none', 73 | clipRule: 'nonezero', 74 | color: 'inherit', 75 | colorInterpolation: 'sRGB', 76 | colorInterpolationFilters: 'linearRGB', 77 | colorProfile: 'auto', 78 | colorRendering: 'auto', 79 | columnCount: 'auto', 80 | columnFill: 'balance', 81 | columnGap: 'normal', 82 | columnRule: 'medium none currentColor', 83 | columnRuleColor: 'currentColor', 84 | columnRuleStyle: 'none', 85 | columnRuleWidth: 'none', 86 | columnSpan: 1, 87 | columnWidth: 'auto', 88 | columns: 'auto auto', 89 | content: 'normal', 90 | counterIncrement: 'none', 91 | counterReset: 'none', 92 | cursor: 'auto', 93 | cx: 0, 94 | cy: 0, 95 | direction: 'ltr', 96 | display: 'inline', 97 | dominantBaseline: 'auto', 98 | emptyCells: 'show', 99 | enableBackground: 'accumuluate', 100 | fill: 'black', 101 | fillOpacity: 1, 102 | fillRule: 'nonzero', 103 | filter: 'none', 104 | flex: '0 1 auto', 105 | flexBasis: 'auto', 106 | flexDirection: 'row', 107 | flexGrow: 0, 108 | flexShrink: 1, 109 | flexWrap: 'nowrap', 110 | float: 'none', 111 | floodColor: 'black', 112 | floodOpacity: 1, 113 | font: 'normal', 114 | fontFamily: 'inherit', 115 | fontFeatureSettings: 'normal', 116 | fontSize: 'medium', 117 | fontSmooth: 'auto', 118 | fontStretch: 'normal', 119 | fontStyle: 'normal', 120 | fontSynthesis: 'weight style', 121 | fontVariant: 'normal', 122 | fontVariantCaps: 'normal', 123 | fontVariantNumeric: 'normal', 124 | fontVariantAlternates: 'normal', 125 | fontVariantLigatures: 'normal', 126 | fontVariantEastAsian: 'normal', 127 | fontVariantPosition: 'normal', 128 | fontWeight: 'normal', 129 | glyphOrientationHorizontal: '0deg', 130 | glyphOrientationVertical: '0deg', 131 | hangingPunctuation: 'none', 132 | height: 'auto', 133 | hyphens: 'none', 134 | imageOrientation: '0deg', 135 | imageRendering: 'auto', 136 | isolation: 'auto', 137 | justifyContent: 'flex-start', 138 | justifyItems: 'auto', 139 | justifySelf: 'auto', 140 | kerning: 'auto', 141 | left: 'auto', 142 | letterSpacing: 'normal', 143 | lightingColor: 'white', 144 | lineHeight: 'normal', 145 | listStyleImage: 'none', 146 | listStylePosition: 'outside', 147 | listStyleType: 'disc', 148 | listStyle: 'disc outside none', 149 | margin: 0, 150 | marginBottom: 0, 151 | marginLeft: 0, 152 | marginRight: 0, 153 | marginTop: 0, 154 | mask: 'none', 155 | maskType: 'luminance', 156 | maxHeight: 'none', 157 | maxWidth: 'none', 158 | minHeight: 0, 159 | minWidth: 0, 160 | mixBlendMode: 'normal', 161 | objectFit: 'fill', 162 | objectPosition: '50% 50%', 163 | opacity: '1', 164 | order: '0', 165 | orphans: 0, 166 | outline: 0, 167 | outlineColor: 'invert', 168 | outlineOffset: 0, 169 | outlineStyle: 'none', 170 | outlineWidth: 'medium', 171 | overflow: 'visible', 172 | overflowWrap: 'normal', 173 | overflowX: 'visible', 174 | overflowY: 'visible', 175 | padding: 0, 176 | paddingBottom: 0, 177 | paddingLeft: 0, 178 | paddingRight: 0, 179 | paddingTop: 0, 180 | pageBreakAfter: 'auto', 181 | pageBreakBefore: 'auto', 182 | pageBreakInside: 'auto', 183 | paintOrder: 'normal', 184 | perspective: 'none', 185 | perspectiveOrigin: '50% 50%', 186 | perspectiveOriginX: '50%', 187 | perspectiveOriginY: '50%', 188 | pointerEvents: 'auto', 189 | position: 'static', 190 | r: 0, 191 | resize: 'none', 192 | right: 'auto', 193 | rx: 0, 194 | ry: 0, 195 | scrollSnapCoordinate: 'none', 196 | scrollSnapDestination: '0px 0px', 197 | scrollSnapPointsX: 'none', 198 | scrollSnapPointsY: 'none', 199 | shapeRendering: 'auto', 200 | speak: 'auto', 201 | stopColor: 'black', 202 | stopOpacity: 1, 203 | stroke: 'black', 204 | strokeDasharray: 'none', 205 | strokeDashoffset: 1, 206 | strokeLinecap: 'butt', 207 | strokeLinejoin: 'miter', 208 | strokeOpacity: 1, 209 | strokeWidth: 1, 210 | tabSize: 8, 211 | tableLayout: 'auto', 212 | textAlign: 'inherit', 213 | textAlignLast: 'auto', 214 | textAnchor: 'start', 215 | textDecoration: 'none', 216 | textDecorationColor: 'currentColor', 217 | textDecorationLine: 'none', 218 | textDecorationStyle: 'solid', 219 | textIndent: 0, 220 | textOverflow: 'clip', 221 | textRendering: 'auto', 222 | textShadow: 'none', 223 | textTransform: 'none', 224 | textUnderlinePosition: 'auto', 225 | top: 'auto', 226 | transform: 'none', 227 | transformOrigin: '50% 50% 0', 228 | transformOriginX: '50%', 229 | transformOriginY: '50%', 230 | transformOriginZ: 0, 231 | transformStyle: 'flat', 232 | transition: 'none', 233 | transitionDelay: '0s', 234 | transitionDuration: '0s', 235 | transitionProperty: 'none', 236 | transitionTimingFunction: 'ease', 237 | unicodeBidi: 'normal', 238 | verticalAlign: 'baseline', 239 | visibility: 'visible', 240 | whiteSpace: 'normal', 241 | widows: 0, 242 | width: 'auto', 243 | wordBreak: 'normal', 244 | wordSpacing: 'normal', 245 | wordWrap: 'normal', 246 | writingMode: 'horizontal-tb', 247 | x: 0, 248 | y: 0, 249 | zIndex: 'auto', 250 | zoom: 'normal', 251 | } 252 | -------------------------------------------------------------------------------- /packages/elodin-data/src/data/compatibilityFull.js: -------------------------------------------------------------------------------- 1 | var fullSupport = { 2 | borderRadius: { 3 | and_chr: 59, 4 | and_ff: 55, 5 | and_qq: 1.2, 6 | and_uc: 11.4, 7 | android: 2.1, 8 | baidu: 7.12, 9 | bb: 7, 10 | chrome: 4, 11 | edge: 12, 12 | firefox: 3, 13 | ie: 9, 14 | ie_mob: 10, 15 | ios_saf: 3.2, 16 | op_mob: 11, 17 | opera: 10.5, 18 | safari: 3.1, 19 | samsung: 4, 20 | }, 21 | borderImage: { 22 | and_ff: 55, 23 | edge: 12, 24 | firefox: 50, 25 | ie: 11, 26 | ie_mob: 11, 27 | ios_saf: 9.3, 28 | safari: 9.1, 29 | }, 30 | borderImageOutset: { 31 | and_ff: 55, 32 | edge: 12, 33 | firefox: 50, 34 | ie: 11, 35 | ie_mob: 11, 36 | ios_saf: 9.3, 37 | safari: 9.1, 38 | }, 39 | borderImageRepeat: { 40 | and_ff: 55, 41 | edge: 12, 42 | firefox: 50, 43 | ie: 11, 44 | ie_mob: 11, 45 | ios_saf: 9.3, 46 | safari: 9.1, 47 | }, 48 | borderImageSlice: { 49 | and_ff: 55, 50 | edge: 12, 51 | firefox: 50, 52 | ie: 11, 53 | ie_mob: 11, 54 | ios_saf: 9.3, 55 | safari: 9.1, 56 | }, 57 | borderImageSource: { 58 | and_ff: 55, 59 | edge: 12, 60 | firefox: 50, 61 | ie: 11, 62 | ie_mob: 11, 63 | ios_saf: 9.3, 64 | safari: 9.1, 65 | }, 66 | borderImageWidth: { 67 | and_ff: 55, 68 | edge: 12, 69 | firefox: 50, 70 | ie: 11, 71 | ie_mob: 11, 72 | ios_saf: 9.3, 73 | safari: 9.1, 74 | }, 75 | flex: { 76 | and_chr: 59, 77 | and_ff: 55, 78 | and_qq: 1.2, 79 | android: 4.4, 80 | baidu: 7.12, 81 | bb: 10, 82 | chrome: 21, 83 | edge: 12, 84 | firefox: 28, 85 | ie_mob: 11, 86 | ios_saf: 7, 87 | op_mob: 12.1, 88 | opera: 12.1, 89 | safari: 6.1, 90 | samsung: 4, 91 | }, 92 | flexBasis: { 93 | and_chr: 59, 94 | and_ff: 55, 95 | and_qq: 1.2, 96 | android: 4.4, 97 | baidu: 7.12, 98 | bb: 10, 99 | chrome: 21, 100 | edge: 12, 101 | firefox: 28, 102 | ie_mob: 11, 103 | ios_saf: 7, 104 | op_mob: 12.1, 105 | opera: 12.1, 106 | safari: 6.1, 107 | samsung: 4, 108 | }, 109 | flexDirection: { 110 | and_chr: 59, 111 | and_ff: 55, 112 | and_qq: 1.2, 113 | android: 4.4, 114 | baidu: 7.12, 115 | bb: 10, 116 | chrome: 21, 117 | edge: 12, 118 | firefox: 28, 119 | ie_mob: 11, 120 | ios_saf: 7, 121 | op_mob: 12.1, 122 | opera: 12.1, 123 | safari: 6.1, 124 | samsung: 4, 125 | }, 126 | flexGrow: { 127 | and_chr: 59, 128 | and_ff: 55, 129 | and_qq: 1.2, 130 | android: 4.4, 131 | baidu: 7.12, 132 | bb: 10, 133 | chrome: 21, 134 | edge: 12, 135 | firefox: 28, 136 | ie_mob: 11, 137 | ios_saf: 7, 138 | op_mob: 12.1, 139 | opera: 12.1, 140 | safari: 6.1, 141 | samsung: 4, 142 | }, 143 | flexFlow: { 144 | and_chr: 59, 145 | and_ff: 55, 146 | and_qq: 1.2, 147 | android: 4.4, 148 | baidu: 7.12, 149 | bb: 10, 150 | chrome: 21, 151 | edge: 12, 152 | firefox: 28, 153 | ie_mob: 11, 154 | ios_saf: 7, 155 | op_mob: 12.1, 156 | opera: 12.1, 157 | safari: 6.1, 158 | samsung: 4, 159 | }, 160 | flexShrink: { 161 | and_chr: 59, 162 | and_ff: 55, 163 | and_qq: 1.2, 164 | android: 4.4, 165 | baidu: 7.12, 166 | bb: 10, 167 | chrome: 21, 168 | edge: 12, 169 | firefox: 28, 170 | ie_mob: 11, 171 | ios_saf: 7, 172 | op_mob: 12.1, 173 | opera: 12.1, 174 | safari: 6.1, 175 | samsung: 4, 176 | }, 177 | flexWrap: { 178 | and_chr: 59, 179 | and_ff: 55, 180 | and_qq: 1.2, 181 | android: 4.4, 182 | baidu: 7.12, 183 | bb: 10, 184 | chrome: 21, 185 | edge: 12, 186 | firefox: 28, 187 | ie_mob: 11, 188 | ios_saf: 7, 189 | op_mob: 12.1, 190 | opera: 12.1, 191 | safari: 6.1, 192 | samsung: 4, 193 | }, 194 | alignContent: { 195 | and_chr: 59, 196 | and_ff: 55, 197 | and_qq: 1.2, 198 | android: 4.4, 199 | baidu: 7.12, 200 | bb: 10, 201 | chrome: 21, 202 | edge: 12, 203 | firefox: 28, 204 | ie_mob: 11, 205 | ios_saf: 7, 206 | op_mob: 12.1, 207 | opera: 12.1, 208 | safari: 6.1, 209 | samsung: 4, 210 | }, 211 | alignItems: { 212 | and_chr: 59, 213 | and_ff: 55, 214 | and_qq: 1.2, 215 | android: 4.4, 216 | baidu: 7.12, 217 | bb: 10, 218 | chrome: 21, 219 | edge: 12, 220 | firefox: 28, 221 | ie_mob: 11, 222 | ios_saf: 7, 223 | op_mob: 12.1, 224 | opera: 12.1, 225 | safari: 6.1, 226 | samsung: 4, 227 | }, 228 | alignSelf: { 229 | and_chr: 59, 230 | and_ff: 55, 231 | and_qq: 1.2, 232 | android: 4.4, 233 | baidu: 7.12, 234 | bb: 10, 235 | chrome: 21, 236 | edge: 12, 237 | firefox: 28, 238 | ie_mob: 11, 239 | ios_saf: 7, 240 | op_mob: 12.1, 241 | opera: 12.1, 242 | safari: 6.1, 243 | samsung: 4, 244 | }, 245 | justifyContent: { 246 | and_chr: 59, 247 | and_ff: 55, 248 | and_qq: 1.2, 249 | android: 4.4, 250 | baidu: 7.12, 251 | bb: 10, 252 | chrome: 21, 253 | edge: 12, 254 | firefox: 28, 255 | ie_mob: 11, 256 | ios_saf: 7, 257 | op_mob: 12.1, 258 | opera: 12.1, 259 | safari: 6.1, 260 | samsung: 4, 261 | }, 262 | order: { 263 | and_chr: 59, 264 | and_ff: 55, 265 | and_qq: 1.2, 266 | android: 4.4, 267 | baidu: 7.12, 268 | bb: 10, 269 | chrome: 21, 270 | edge: 12, 271 | firefox: 28, 272 | ie_mob: 11, 273 | ios_saf: 7, 274 | op_mob: 12.1, 275 | opera: 12.1, 276 | safari: 6.1, 277 | samsung: 4, 278 | }, 279 | transition: { 280 | and_chr: 59, 281 | and_ff: 55, 282 | and_qq: 1.2, 283 | and_uc: 11.4, 284 | android: 2.1, 285 | baidu: 7.12, 286 | bb: 7, 287 | chrome: 4, 288 | edge: 12, 289 | firefox: 5, 290 | ie: 10, 291 | ie_mob: 10, 292 | ios_saf: 6, 293 | op_mob: 12, 294 | opera: 12, 295 | safari: 5.1, 296 | samsung: 4, 297 | }, 298 | transitionDelay: { 299 | and_chr: 59, 300 | and_ff: 55, 301 | and_qq: 1.2, 302 | and_uc: 11.4, 303 | android: 2.1, 304 | baidu: 7.12, 305 | bb: 7, 306 | chrome: 4, 307 | edge: 12, 308 | firefox: 5, 309 | ie: 10, 310 | ie_mob: 10, 311 | ios_saf: 6, 312 | op_mob: 12, 313 | opera: 12, 314 | safari: 5.1, 315 | samsung: 4, 316 | }, 317 | transitionDuration: { 318 | and_chr: 59, 319 | and_ff: 55, 320 | and_qq: 1.2, 321 | and_uc: 11.4, 322 | android: 2.1, 323 | baidu: 7.12, 324 | bb: 7, 325 | chrome: 4, 326 | edge: 12, 327 | firefox: 5, 328 | ie: 10, 329 | ie_mob: 10, 330 | ios_saf: 6, 331 | op_mob: 12, 332 | opera: 12, 333 | safari: 5.1, 334 | samsung: 4, 335 | }, 336 | transitionProperty: { 337 | and_chr: 59, 338 | and_ff: 55, 339 | and_qq: 1.2, 340 | and_uc: 11.4, 341 | android: 2.1, 342 | baidu: 7.12, 343 | bb: 7, 344 | chrome: 4, 345 | edge: 12, 346 | firefox: 5, 347 | ie: 10, 348 | ie_mob: 10, 349 | ios_saf: 6, 350 | op_mob: 12, 351 | opera: 12, 352 | safari: 5.1, 353 | samsung: 4, 354 | }, 355 | transitionTimingFunction: { 356 | and_chr: 59, 357 | and_ff: 55, 358 | and_qq: 1.2, 359 | and_uc: 11.4, 360 | android: 2.1, 361 | baidu: 7.12, 362 | bb: 7, 363 | chrome: 4, 364 | edge: 12, 365 | firefox: 5, 366 | ie: 10, 367 | ie_mob: 10, 368 | ios_saf: 6, 369 | op_mob: 12, 370 | opera: 12, 371 | safari: 5.1, 372 | samsung: 4, 373 | }, 374 | transform: { 375 | and_chr: 59, 376 | and_ff: 55, 377 | and_qq: 1.2, 378 | and_uc: 11.4, 379 | android: 3, 380 | baidu: 7.12, 381 | bb: 7, 382 | chrome: 12, 383 | edge: 12, 384 | firefox: 10, 385 | ie: 9, 386 | ie_mob: 10, 387 | ios_saf: 3.2, 388 | op_mob: 37, 389 | opera: 15, 390 | safari: 4, 391 | samsung: 4, 392 | }, 393 | transformOrigin: { 394 | and_chr: 59, 395 | and_ff: 55, 396 | and_qq: 1.2, 397 | and_uc: 11.4, 398 | android: 3, 399 | baidu: 7.12, 400 | bb: 7, 401 | chrome: 12, 402 | edge: 12, 403 | firefox: 10, 404 | ie: 9, 405 | ie_mob: 10, 406 | ios_saf: 3.2, 407 | op_mob: 37, 408 | opera: 15, 409 | safari: 4, 410 | samsung: 4, 411 | }, 412 | transformOriginX: { 413 | and_chr: 59, 414 | and_ff: 55, 415 | and_qq: 1.2, 416 | and_uc: 11.4, 417 | android: 3, 418 | baidu: 7.12, 419 | bb: 7, 420 | chrome: 12, 421 | edge: 12, 422 | firefox: 10, 423 | ie: 9, 424 | ie_mob: 10, 425 | ios_saf: 3.2, 426 | op_mob: 37, 427 | opera: 15, 428 | safari: 4, 429 | samsung: 4, 430 | }, 431 | transformOriginY: { 432 | and_chr: 59, 433 | and_ff: 55, 434 | and_qq: 1.2, 435 | and_uc: 11.4, 436 | android: 3, 437 | baidu: 7.12, 438 | bb: 7, 439 | chrome: 12, 440 | edge: 12, 441 | firefox: 10, 442 | ie: 9, 443 | ie_mob: 10, 444 | ios_saf: 3.2, 445 | op_mob: 37, 446 | opera: 15, 447 | safari: 4, 448 | samsung: 4, 449 | }, 450 | backfaceVisibility: { 451 | and_chr: 59, 452 | and_ff: 55, 453 | and_qq: 1.2, 454 | and_uc: 11.4, 455 | android: 3, 456 | baidu: 7.12, 457 | bb: 7, 458 | chrome: 12, 459 | edge: 12, 460 | firefox: 10, 461 | ios_saf: 3.2, 462 | op_mob: 37, 463 | opera: 15, 464 | safari: 4, 465 | samsung: 4, 466 | }, 467 | perspective: { 468 | and_chr: 59, 469 | and_ff: 55, 470 | and_qq: 1.2, 471 | and_uc: 11.4, 472 | android: 3, 473 | baidu: 7.12, 474 | bb: 7, 475 | chrome: 12, 476 | edge: 12, 477 | firefox: 10, 478 | ios_saf: 3.2, 479 | op_mob: 37, 480 | opera: 15, 481 | safari: 4, 482 | samsung: 4, 483 | }, 484 | perspectiveOrigin: { 485 | and_chr: 59, 486 | and_ff: 55, 487 | and_qq: 1.2, 488 | and_uc: 11.4, 489 | android: 3, 490 | baidu: 7.12, 491 | bb: 7, 492 | chrome: 12, 493 | edge: 12, 494 | firefox: 10, 495 | ios_saf: 3.2, 496 | op_mob: 37, 497 | opera: 15, 498 | safari: 4, 499 | samsung: 4, 500 | }, 501 | transformStyle: { 502 | and_chr: 59, 503 | and_ff: 55, 504 | and_qq: 1.2, 505 | and_uc: 11.4, 506 | android: 3, 507 | baidu: 7.12, 508 | bb: 7, 509 | chrome: 12, 510 | edge: 12, 511 | firefox: 10, 512 | ios_saf: 3.2, 513 | op_mob: 37, 514 | opera: 15, 515 | safari: 4, 516 | samsung: 4, 517 | }, 518 | transformOriginZ: { 519 | and_chr: 59, 520 | and_ff: 55, 521 | and_qq: 1.2, 522 | and_uc: 11.4, 523 | android: 3, 524 | baidu: 7.12, 525 | bb: 7, 526 | chrome: 12, 527 | edge: 12, 528 | firefox: 10, 529 | ios_saf: 3.2, 530 | op_mob: 37, 531 | opera: 15, 532 | safari: 4, 533 | samsung: 4, 534 | }, 535 | animation: { 536 | and_chr: 59, 537 | and_ff: 55, 538 | and_qq: 1.2, 539 | and_uc: 11.4, 540 | android: 4, 541 | baidu: 7.12, 542 | bb: 7, 543 | chrome: 4, 544 | edge: 12, 545 | firefox: 5, 546 | ie: 10, 547 | ie_mob: 10, 548 | ios_saf: 6, 549 | op_mob: 12.1, 550 | opera: 12, 551 | safari: 5.1, 552 | samsung: 4, 553 | }, 554 | animationDelay: { 555 | and_chr: 59, 556 | and_ff: 55, 557 | and_qq: 1.2, 558 | and_uc: 11.4, 559 | android: 4, 560 | baidu: 7.12, 561 | bb: 7, 562 | chrome: 4, 563 | edge: 12, 564 | firefox: 5, 565 | ie: 10, 566 | ie_mob: 10, 567 | ios_saf: 6, 568 | op_mob: 12.1, 569 | opera: 12, 570 | safari: 5.1, 571 | samsung: 4, 572 | }, 573 | animationDirection: { 574 | and_chr: 59, 575 | and_ff: 55, 576 | and_qq: 1.2, 577 | and_uc: 11.4, 578 | android: 4, 579 | baidu: 7.12, 580 | bb: 7, 581 | chrome: 4, 582 | edge: 12, 583 | firefox: 5, 584 | ie: 10, 585 | ie_mob: 10, 586 | ios_saf: 6, 587 | op_mob: 12.1, 588 | opera: 12, 589 | safari: 5.1, 590 | samsung: 4, 591 | }, 592 | animationFillMode: { 593 | and_chr: 59, 594 | and_ff: 55, 595 | and_qq: 1.2, 596 | and_uc: 11.4, 597 | android: 2.4, 598 | baidu: 7.12, 599 | bb: 7, 600 | chrome: 4, 601 | edge: 12, 602 | firefox: 5, 603 | ie: 10, 604 | ie_mob: 10, 605 | ios_saf: 6, 606 | op_mob: 12.1, 607 | opera: 12, 608 | safari: 5.1, 609 | samsung: 4, 610 | }, 611 | animationDuration: { 612 | and_chr: 59, 613 | and_ff: 55, 614 | and_qq: 1.2, 615 | and_uc: 11.4, 616 | android: 4, 617 | baidu: 7.12, 618 | bb: 7, 619 | chrome: 4, 620 | edge: 12, 621 | firefox: 5, 622 | ie: 10, 623 | ie_mob: 10, 624 | ios_saf: 6, 625 | op_mob: 12.1, 626 | opera: 12, 627 | safari: 5.1, 628 | samsung: 4, 629 | }, 630 | animationIterationCount: { 631 | and_chr: 59, 632 | and_ff: 55, 633 | and_qq: 1.2, 634 | and_uc: 11.4, 635 | android: 4, 636 | baidu: 7.12, 637 | bb: 7, 638 | chrome: 4, 639 | edge: 12, 640 | firefox: 5, 641 | ie: 10, 642 | ie_mob: 10, 643 | ios_saf: 6, 644 | op_mob: 12.1, 645 | opera: 12, 646 | safari: 5.1, 647 | samsung: 4, 648 | }, 649 | animationName: { 650 | and_chr: 59, 651 | and_ff: 55, 652 | and_qq: 1.2, 653 | and_uc: 11.4, 654 | android: 4, 655 | baidu: 7.12, 656 | bb: 7, 657 | chrome: 4, 658 | edge: 12, 659 | firefox: 5, 660 | ie: 10, 661 | ie_mob: 10, 662 | ios_saf: 6, 663 | op_mob: 12.1, 664 | opera: 12, 665 | safari: 5.1, 666 | samsung: 4, 667 | }, 668 | animationPlayState: { 669 | and_chr: 59, 670 | and_ff: 55, 671 | and_qq: 1.2, 672 | and_uc: 11.4, 673 | android: 4, 674 | baidu: 7.12, 675 | bb: 7, 676 | chrome: 4, 677 | edge: 12, 678 | firefox: 5, 679 | ie: 10, 680 | ie_mob: 10, 681 | ios_saf: 6, 682 | op_mob: 12.1, 683 | opera: 12, 684 | safari: 5.1, 685 | samsung: 4, 686 | }, 687 | animationTimingFunction: { 688 | and_chr: 59, 689 | and_ff: 55, 690 | and_qq: 1.2, 691 | and_uc: 11.4, 692 | android: 4, 693 | baidu: 7.12, 694 | bb: 7, 695 | chrome: 4, 696 | edge: 12, 697 | firefox: 5, 698 | ie: 10, 699 | ie_mob: 10, 700 | ios_saf: 6, 701 | op_mob: 12.1, 702 | opera: 12, 703 | safari: 5.1, 704 | samsung: 4, 705 | }, 706 | appearance: {}, 707 | userSelect: { 708 | and_chr: 59, 709 | and_ff: 55, 710 | and_qq: 1.2, 711 | and_uc: 11.4, 712 | android: 2.1, 713 | bb: 7, 714 | chrome: 4, 715 | edge: 12, 716 | firefox: 2, 717 | ie: 10, 718 | ie_mob: 10, 719 | ios_saf: 3.2, 720 | op_mob: 37, 721 | opera: 15, 722 | safari: 3.1, 723 | samsung: 4, 724 | }, 725 | backdropFilter: { ios_saf: 9, safari: 9 }, 726 | boxSizing: { 727 | and_chr: 59, 728 | and_ff: 55, 729 | and_qq: 1.2, 730 | and_uc: 11.4, 731 | android: 2.1, 732 | baidu: 7.12, 733 | bb: 7, 734 | chrome: 4, 735 | edge: 12, 736 | firefox: 2, 737 | ie: 8, 738 | ie_mob: 10, 739 | ios_saf: 3.2, 740 | op_mob: 10, 741 | opera: 9.5, 742 | safari: 3.1, 743 | samsung: 4, 744 | }, 745 | fontKerning: { 746 | and_chr: 59, 747 | and_ff: 55, 748 | and_qq: 1.2, 749 | and_uc: 11.4, 750 | android: 4.4, 751 | baidu: 7.12, 752 | bb: 10, 753 | chrome: 29, 754 | firefox: 34, 755 | ios_saf: 8, 756 | op_mob: 37, 757 | opera: 16, 758 | safari: 7, 759 | samsung: 4, 760 | }, 761 | wrapFlow: { edge: 12, ie: 10, ie_mob: 10 }, 762 | wrapThrough: { edge: 12, ie: 10, ie_mob: 10 }, 763 | wrapMargin: { edge: 12, ie: 10, ie_mob: 10 }, 764 | scrollSnapType: { safari: 11 }, 765 | scrollSnapPointsX: { safari: 11 }, 766 | scrollSnapPointsY: { safari: 11 }, 767 | scrollSnapDestination: { safari: 11 }, 768 | scrollSnapCoordinate: { safari: 11 }, 769 | textEmphasisPosition: { firefox: 46, ios_saf: 7, safari: 7.1 }, 770 | textEmphasis: { firefox: 46, ios_saf: 7, safari: 7.1 }, 771 | textEmphasisStyle: { firefox: 46, ios_saf: 7, safari: 7.1 }, 772 | textEmphasisColor: { firefox: 46, ios_saf: 7, safari: 7.1 }, 773 | textAlignLast: { 774 | and_chr: 59, 775 | and_ff: 55, 776 | android: 56, 777 | baidu: 7.12, 778 | chrome: 47, 779 | firefox: 12, 780 | opera: 34, 781 | samsung: 5, 782 | }, 783 | boxDecorationBreak: { 784 | and_ff: 55, 785 | and_uc: 11.4, 786 | firefox: 32, 787 | op_mob: 11, 788 | opera: 11, 789 | }, 790 | clipPath: { and_ff: 55, firefox: 54 }, 791 | maskImage: { and_ff: 55, firefox: 53 }, 792 | maskMode: { and_ff: 55, firefox: 53 }, 793 | maskRepeat: { and_ff: 55, firefox: 53 }, 794 | maskPosition: { and_ff: 55, firefox: 53 }, 795 | maskClip: { and_ff: 55, firefox: 53 }, 796 | maskOrigin: { and_ff: 55, firefox: 53 }, 797 | maskSize: { and_ff: 55, firefox: 53 }, 798 | maskComposite: { and_ff: 55, firefox: 53 }, 799 | mask: { and_ff: 55, firefox: 53 }, 800 | maskBorderSource: { and_ff: 55, firefox: 53 }, 801 | maskBorderMode: { and_ff: 55, firefox: 53 }, 802 | maskBorderSlice: { and_ff: 55, firefox: 53 }, 803 | maskBorderWidth: { and_ff: 55, firefox: 53 }, 804 | maskBorderOutset: { and_ff: 55, firefox: 53 }, 805 | maskBorderRepeat: { and_ff: 55, firefox: 53 }, 806 | maskBorder: { and_ff: 55, firefox: 53 }, 807 | maskType: { and_ff: 55, firefox: 53 }, 808 | touchAction: { 809 | and_chr: 59, 810 | and_ff: 55, 811 | and_qq: 1.2, 812 | and_uc: 11.4, 813 | android: 56, 814 | baidu: 7.12, 815 | chrome: 36, 816 | edge: 12, 817 | firefox: 52, 818 | ie: 10, 819 | ie_mob: 10, 820 | op_mob: 37, 821 | opera: 23, 822 | samsung: 4, 823 | }, 824 | textSizeAdjust: { 825 | and_chr: 59, 826 | and_ff: 55, 827 | and_uc: 11.4, 828 | android: 56, 829 | chrome: 54, 830 | ie_mob: 10, 831 | ios_saf: 5, 832 | opera: 43, 833 | samsung: 5, 834 | }, 835 | textDecorationStyle: { and_ff: 55, android: 56, baidu: 7.12 }, 836 | textDecorationSkip: { and_ff: 55, android: 56, baidu: 7.12 }, 837 | textDecorationLine: { and_ff: 55, android: 56, baidu: 7.12 }, 838 | textDecorationColor: { and_ff: 55, android: 56, baidu: 7.12 }, 839 | shapeImageThreshold: { 840 | and_chr: 59, 841 | and_qq: 1.2, 842 | and_uc: 11.4, 843 | android: 56, 844 | baidu: 7.12, 845 | chrome: 37, 846 | ios_saf: 8, 847 | op_mob: 37, 848 | opera: 24, 849 | safari: 7.1, 850 | samsung: 4, 851 | }, 852 | shapeImageMargin: { 853 | and_chr: 59, 854 | and_qq: 1.2, 855 | and_uc: 11.4, 856 | android: 56, 857 | baidu: 7.12, 858 | chrome: 37, 859 | ios_saf: 8, 860 | op_mob: 37, 861 | opera: 24, 862 | safari: 7.1, 863 | samsung: 4, 864 | }, 865 | shapeImageOutside: { 866 | and_chr: 59, 867 | and_qq: 1.2, 868 | and_uc: 11.4, 869 | android: 56, 870 | baidu: 7.12, 871 | chrome: 37, 872 | ios_saf: 8, 873 | op_mob: 37, 874 | opera: 24, 875 | safari: 7.1, 876 | samsung: 4, 877 | }, 878 | tabSize: { 879 | and_chr: 59, 880 | and_ff: 55, 881 | and_qq: 1.2, 882 | and_uc: 11.4, 883 | android: 56, 884 | baidu: 7.12, 885 | chrome: 42, 886 | firefox: 53, 887 | op_mob: 37, 888 | opera: 29, 889 | samsung: 4, 890 | }, 891 | filter: { 892 | and_chr: 59, 893 | and_ff: 55, 894 | and_qq: 1.2, 895 | and_uc: 11.4, 896 | android: 4.4, 897 | baidu: 7.12, 898 | bb: 10, 899 | chrome: 18, 900 | firefox: 35, 901 | ios_saf: 6, 902 | op_mob: 37, 903 | opera: 15, 904 | safari: 6, 905 | samsung: 4, 906 | }, 907 | resize: { 908 | and_chr: 59, 909 | and_ff: 55, 910 | and_qq: 1.2, 911 | and_uc: 11.4, 912 | android: 56, 913 | baidu: 7.12, 914 | chrome: 4, 915 | firefox: 4, 916 | op_mob: 37, 917 | opera: 15, 918 | safari: 4, 919 | samsung: 5, 920 | }, 921 | hyphens: { 922 | and_ff: 55, 923 | edge: 12, 924 | firefox: 6, 925 | ie: 10, 926 | ios_saf: 4.2, 927 | safari: 5.1, 928 | }, 929 | flowInto: { ios_saf: 7, safari: 6.1 }, 930 | flowFrom: { ios_saf: 7, safari: 6.1 }, 931 | breakBefore: { 932 | ios_saf: 7, 933 | safari: 6.1, 934 | edge: 12, 935 | ie: 10, 936 | ie_mob: 10, 937 | op_mob: 11.1, 938 | opera: 11.1, 939 | }, 940 | breakAfter: { 941 | ios_saf: 7, 942 | safari: 6.1, 943 | edge: 12, 944 | ie: 10, 945 | ie_mob: 10, 946 | op_mob: 11.1, 947 | opera: 11.1, 948 | }, 949 | breakInside: { 950 | ios_saf: 7, 951 | safari: 6.1, 952 | edge: 12, 953 | ie: 10, 954 | ie_mob: 10, 955 | op_mob: 11.1, 956 | opera: 11.1, 957 | }, 958 | regionFragment: { ios_saf: 7, safari: 6.1 }, 959 | gridTemplateColumns: { 960 | and_chr: 59, 961 | and_ff: 55, 962 | android: 56, 963 | chrome: 57, 964 | edge: 16, 965 | firefox: 52, 966 | ios_saf: 10.3, 967 | opera: 44, 968 | safari: 10.1, 969 | }, 970 | gridTemplateRows: { 971 | and_chr: 59, 972 | and_ff: 55, 973 | android: 56, 974 | chrome: 57, 975 | edge: 16, 976 | firefox: 52, 977 | ios_saf: 10.3, 978 | opera: 44, 979 | safari: 10.1, 980 | }, 981 | gridTemplateAreas: { 982 | and_chr: 59, 983 | and_ff: 55, 984 | android: 56, 985 | chrome: 57, 986 | edge: 16, 987 | firefox: 52, 988 | ios_saf: 10.3, 989 | opera: 44, 990 | safari: 10.1, 991 | }, 992 | gridTemplate: { 993 | and_chr: 59, 994 | and_ff: 55, 995 | android: 56, 996 | chrome: 57, 997 | edge: 16, 998 | firefox: 52, 999 | ios_saf: 10.3, 1000 | opera: 44, 1001 | safari: 10.1, 1002 | }, 1003 | gridAutoColumns: { 1004 | and_chr: 59, 1005 | and_ff: 55, 1006 | android: 56, 1007 | chrome: 57, 1008 | edge: 16, 1009 | firefox: 52, 1010 | ios_saf: 10.3, 1011 | opera: 44, 1012 | safari: 10.1, 1013 | }, 1014 | gridAutoRows: { 1015 | and_chr: 59, 1016 | and_ff: 55, 1017 | android: 56, 1018 | chrome: 57, 1019 | edge: 16, 1020 | firefox: 52, 1021 | ios_saf: 10.3, 1022 | opera: 44, 1023 | safari: 10.1, 1024 | }, 1025 | gridAutoFlow: { 1026 | and_chr: 59, 1027 | and_ff: 55, 1028 | android: 56, 1029 | chrome: 57, 1030 | edge: 16, 1031 | firefox: 52, 1032 | ios_saf: 10.3, 1033 | opera: 44, 1034 | safari: 10.1, 1035 | }, 1036 | grid: { 1037 | and_chr: 59, 1038 | and_ff: 55, 1039 | android: 56, 1040 | chrome: 57, 1041 | edge: 16, 1042 | firefox: 52, 1043 | ios_saf: 10.3, 1044 | opera: 44, 1045 | safari: 10.1, 1046 | }, 1047 | gridRowStart: { 1048 | and_chr: 59, 1049 | and_ff: 55, 1050 | android: 56, 1051 | chrome: 57, 1052 | edge: 16, 1053 | firefox: 52, 1054 | ios_saf: 10.3, 1055 | opera: 44, 1056 | safari: 10.1, 1057 | }, 1058 | gridColumnStart: { 1059 | and_chr: 59, 1060 | and_ff: 55, 1061 | android: 56, 1062 | chrome: 57, 1063 | edge: 16, 1064 | firefox: 52, 1065 | ios_saf: 10.3, 1066 | opera: 44, 1067 | safari: 10.1, 1068 | }, 1069 | gridRowEnd: { 1070 | and_chr: 59, 1071 | and_ff: 55, 1072 | android: 56, 1073 | chrome: 57, 1074 | edge: 16, 1075 | firefox: 52, 1076 | ios_saf: 10.3, 1077 | opera: 44, 1078 | safari: 10.1, 1079 | }, 1080 | gridRow: { 1081 | and_chr: 59, 1082 | and_ff: 55, 1083 | android: 56, 1084 | chrome: 57, 1085 | edge: 16, 1086 | firefox: 52, 1087 | ios_saf: 10.3, 1088 | opera: 44, 1089 | safari: 10.1, 1090 | }, 1091 | gridColumn: { 1092 | and_chr: 59, 1093 | and_ff: 55, 1094 | android: 56, 1095 | chrome: 57, 1096 | edge: 16, 1097 | firefox: 52, 1098 | ios_saf: 10.3, 1099 | opera: 44, 1100 | safari: 10.1, 1101 | }, 1102 | gridColumnEnd: { 1103 | and_chr: 59, 1104 | and_ff: 55, 1105 | android: 56, 1106 | chrome: 57, 1107 | edge: 16, 1108 | firefox: 52, 1109 | ios_saf: 10.3, 1110 | opera: 44, 1111 | safari: 10.1, 1112 | }, 1113 | gridColumnGap: { 1114 | and_chr: 59, 1115 | and_ff: 55, 1116 | android: 56, 1117 | chrome: 57, 1118 | edge: 16, 1119 | firefox: 52, 1120 | ios_saf: 10.3, 1121 | opera: 44, 1122 | safari: 10.1, 1123 | }, 1124 | gridRowGap: { 1125 | and_chr: 59, 1126 | and_ff: 55, 1127 | android: 56, 1128 | chrome: 57, 1129 | edge: 16, 1130 | firefox: 52, 1131 | ios_saf: 10.3, 1132 | opera: 44, 1133 | safari: 10.1, 1134 | }, 1135 | gridArea: { 1136 | and_chr: 59, 1137 | and_ff: 55, 1138 | android: 56, 1139 | chrome: 57, 1140 | edge: 16, 1141 | firefox: 52, 1142 | ios_saf: 10.3, 1143 | opera: 44, 1144 | safari: 10.1, 1145 | }, 1146 | gridGap: { 1147 | and_chr: 59, 1148 | and_ff: 55, 1149 | android: 56, 1150 | chrome: 57, 1151 | edge: 16, 1152 | firefox: 52, 1153 | ios_saf: 10.3, 1154 | opera: 44, 1155 | safari: 10.1, 1156 | }, 1157 | objectFit: { 1158 | and_chr: 59, 1159 | and_ff: 55, 1160 | and_qq: 1.2, 1161 | and_uc: 11.4, 1162 | android: 4.4, 1163 | baidu: 7.12, 1164 | chrome: 31, 1165 | edge: 16, 1166 | firefox: 36, 1167 | ios_saf: 10, 1168 | op_mob: 11, 1169 | opera: 10.6, 1170 | safari: 10, 1171 | samsung: 4, 1172 | }, 1173 | objectPosition: { 1174 | and_chr: 59, 1175 | and_ff: 55, 1176 | and_qq: 1.2, 1177 | and_uc: 11.4, 1178 | android: 4.4, 1179 | baidu: 7.12, 1180 | chrome: 31, 1181 | edge: 16, 1182 | firefox: 36, 1183 | ios_saf: 10, 1184 | op_mob: 11, 1185 | opera: 10.6, 1186 | safari: 10, 1187 | samsung: 4, 1188 | }, 1189 | textOverflow: { 1190 | and_chr: 59, 1191 | and_ff: 55, 1192 | and_qq: 1.2, 1193 | and_uc: 11.4, 1194 | android: 2.1, 1195 | baidu: 7.12, 1196 | bb: 7, 1197 | chrome: 4, 1198 | edge: 12, 1199 | firefox: 7, 1200 | ie: 6, 1201 | ie_mob: 10, 1202 | ios_saf: 3.2, 1203 | op_mob: 10, 1204 | opera: 9, 1205 | safari: 3.1, 1206 | samsung: 4, 1207 | }, 1208 | backgroundClip: { 1209 | and_chr: 59, 1210 | and_ff: 55, 1211 | and_qq: 1.2, 1212 | and_uc: 11.4, 1213 | android: 4.4, 1214 | baidu: 7.12, 1215 | bb: 7, 1216 | chrome: 15, 1217 | edge: 12, 1218 | firefox: 4, 1219 | ie: 9, 1220 | ie_mob: 10, 1221 | ios_saf: 7, 1222 | op_mob: 10, 1223 | opera: 10.5, 1224 | safari: 7, 1225 | samsung: 4, 1226 | }, 1227 | backgroundOrigin: { 1228 | and_chr: 59, 1229 | and_ff: 55, 1230 | and_qq: 1.2, 1231 | and_uc: 11.4, 1232 | android: 4.4, 1233 | baidu: 7.12, 1234 | bb: 7, 1235 | chrome: 15, 1236 | edge: 12, 1237 | firefox: 4, 1238 | ie: 9, 1239 | ie_mob: 10, 1240 | ios_saf: 7, 1241 | op_mob: 10, 1242 | opera: 10.5, 1243 | safari: 7, 1244 | samsung: 4, 1245 | }, 1246 | backgroundSize: { 1247 | and_chr: 59, 1248 | and_ff: 55, 1249 | and_qq: 1.2, 1250 | and_uc: 11.4, 1251 | android: 4.4, 1252 | baidu: 7.12, 1253 | bb: 7, 1254 | chrome: 15, 1255 | edge: 12, 1256 | firefox: 4, 1257 | ie: 9, 1258 | ie_mob: 10, 1259 | ios_saf: 7, 1260 | op_mob: 10, 1261 | opera: 10.5, 1262 | safari: 7, 1263 | samsung: 4, 1264 | }, 1265 | fontFeatureSettings: { 1266 | and_chr: 59, 1267 | and_ff: 55, 1268 | and_qq: 1.2, 1269 | and_uc: 11.4, 1270 | android: 4.4, 1271 | baidu: 7.12, 1272 | bb: 10, 1273 | chrome: 21, 1274 | edge: 12, 1275 | firefox: 15, 1276 | ie: 10, 1277 | ios_saf: 9.3, 1278 | op_mob: 37, 1279 | opera: 15, 1280 | safari: 9.1, 1281 | samsung: 4, 1282 | }, 1283 | boxShadow: { 1284 | and_chr: 59, 1285 | and_ff: 55, 1286 | and_qq: 1.2, 1287 | and_uc: 11.4, 1288 | android: 4, 1289 | baidu: 7.12, 1290 | bb: 7, 1291 | chrome: 4, 1292 | edge: 12, 1293 | firefox: 3.5, 1294 | ie: 9, 1295 | ie_mob: 10, 1296 | ios_saf: 4, 1297 | op_mob: 11, 1298 | opera: 10.5, 1299 | safari: 5, 1300 | samsung: 4, 1301 | }, 1302 | columnCount: { edge: 12, ie: 10, ie_mob: 10, op_mob: 11.1, opera: 11.1 }, 1303 | columnFill: { edge: 12, ie: 10, ie_mob: 10, op_mob: 11.1, opera: 11.1 }, 1304 | columnGap: { edge: 12, ie: 10, ie_mob: 10, op_mob: 11.1, opera: 11.1 }, 1305 | columnRule: { edge: 12, ie: 10, ie_mob: 10, op_mob: 11.1, opera: 11.1 }, 1306 | columnRuleColor: { edge: 12, ie: 10, ie_mob: 10, op_mob: 11.1, opera: 11.1 }, 1307 | columnRuleStyle: { edge: 12, ie: 10, ie_mob: 10, op_mob: 11.1, opera: 11.1 }, 1308 | columnRuleWidth: { edge: 12, ie: 10, ie_mob: 10, op_mob: 11.1, opera: 11.1 }, 1309 | columns: { edge: 12, ie: 10, ie_mob: 10, op_mob: 11.1, opera: 11.1 }, 1310 | columnSpan: { edge: 12, ie: 10, ie_mob: 10, op_mob: 11.1, opera: 11.1 }, 1311 | columnWidth: { edge: 12, ie: 10, ie_mob: 10, op_mob: 11.1, opera: 11.1 }, 1312 | writingMode: { 1313 | and_chr: 59, 1314 | and_ff: 55, 1315 | and_qq: 1.2, 1316 | and_uc: 11.4, 1317 | android: 3, 1318 | baidu: 7.12, 1319 | bb: 7, 1320 | chrome: 8, 1321 | edge: 12, 1322 | firefox: 41, 1323 | ios_saf: 5, 1324 | op_mob: 37, 1325 | opera: 15, 1326 | safari: 5.1, 1327 | samsung: 4, 1328 | }, 1329 | } 1330 | module.exports = fullSupport 1331 | -------------------------------------------------------------------------------- /packages/elodin-data/src/data/compatibilityPartial.js: -------------------------------------------------------------------------------- 1 | var partialSupport = { 2 | borderRadius: { 3 | and_chr: 0, 4 | and_ff: 0, 5 | and_qq: 0, 6 | and_uc: 0, 7 | android: 0, 8 | baidu: 0, 9 | bb: 0, 10 | chrome: 0, 11 | edge: 0, 12 | firefox: 0, 13 | ie: 8, 14 | ie_mob: 0, 15 | ios_saf: 0, 16 | op_mini: 0, 17 | op_mob: 10, 18 | opera: 10, 19 | safari: 0, 20 | samsung: 0, 21 | }, 22 | borderImage: { 23 | and_chr: 0, 24 | and_ff: 0, 25 | and_qq: 0, 26 | and_uc: 0, 27 | android: 0, 28 | baidu: 0, 29 | bb: 0, 30 | chrome: 0, 31 | edge: 0, 32 | firefox: 3, 33 | ie: 10, 34 | ie_mob: 10, 35 | ios_saf: 0, 36 | op_mini: 0, 37 | op_mob: 10, 38 | opera: 10, 39 | safari: 0, 40 | samsung: 0, 41 | }, 42 | borderImageOutset: { 43 | and_chr: 0, 44 | and_ff: 0, 45 | and_qq: 0, 46 | and_uc: 0, 47 | android: 0, 48 | baidu: 0, 49 | bb: 0, 50 | chrome: 0, 51 | edge: 0, 52 | firefox: 3, 53 | ie: 10, 54 | ie_mob: 10, 55 | ios_saf: 0, 56 | op_mini: 0, 57 | op_mob: 10, 58 | opera: 10, 59 | safari: 0, 60 | samsung: 0, 61 | }, 62 | borderImageRepeat: { 63 | and_chr: 0, 64 | and_ff: 0, 65 | and_qq: 0, 66 | and_uc: 0, 67 | android: 0, 68 | baidu: 0, 69 | bb: 0, 70 | chrome: 0, 71 | edge: 0, 72 | firefox: 3, 73 | ie: 10, 74 | ie_mob: 10, 75 | ios_saf: 0, 76 | op_mini: 0, 77 | op_mob: 10, 78 | opera: 10, 79 | safari: 0, 80 | samsung: 0, 81 | }, 82 | borderImageSlice: { 83 | and_chr: 0, 84 | and_ff: 0, 85 | and_qq: 0, 86 | and_uc: 0, 87 | android: 0, 88 | baidu: 0, 89 | bb: 0, 90 | chrome: 0, 91 | edge: 0, 92 | firefox: 3, 93 | ie: 10, 94 | ie_mob: 10, 95 | ios_saf: 0, 96 | op_mini: 0, 97 | op_mob: 10, 98 | opera: 10, 99 | safari: 0, 100 | samsung: 0, 101 | }, 102 | borderImageSource: { 103 | and_chr: 0, 104 | and_ff: 0, 105 | and_qq: 0, 106 | and_uc: 0, 107 | android: 0, 108 | baidu: 0, 109 | bb: 0, 110 | chrome: 0, 111 | edge: 0, 112 | firefox: 3, 113 | ie: 10, 114 | ie_mob: 10, 115 | ios_saf: 0, 116 | op_mini: 0, 117 | op_mob: 10, 118 | opera: 10, 119 | safari: 0, 120 | samsung: 0, 121 | }, 122 | borderImageWidth: { 123 | and_chr: 0, 124 | and_ff: 0, 125 | and_qq: 0, 126 | and_uc: 0, 127 | android: 0, 128 | baidu: 0, 129 | bb: 0, 130 | chrome: 0, 131 | edge: 0, 132 | firefox: 3, 133 | ie: 10, 134 | ie_mob: 10, 135 | ios_saf: 0, 136 | op_mini: 0, 137 | op_mob: 10, 138 | opera: 10, 139 | safari: 0, 140 | samsung: 0, 141 | }, 142 | flex: { 143 | and_chr: 0, 144 | and_ff: 0, 145 | and_qq: 0, 146 | and_uc: 0, 147 | android: 0, 148 | baidu: 0, 149 | bb: 0, 150 | chrome: 0, 151 | edge: 0, 152 | firefox: 0, 153 | ie: 9, 154 | ie_mob: 0, 155 | ios_saf: 0, 156 | op_mini: 0, 157 | op_mob: 12, 158 | opera: 12, 159 | safari: 0, 160 | samsung: 0, 161 | }, 162 | flexBasis: { 163 | and_chr: 0, 164 | and_ff: 0, 165 | and_qq: 0, 166 | and_uc: 0, 167 | android: 0, 168 | baidu: 0, 169 | bb: 0, 170 | chrome: 0, 171 | edge: 0, 172 | firefox: 0, 173 | ie: 9, 174 | ie_mob: 0, 175 | ios_saf: 0, 176 | op_mini: 0, 177 | op_mob: 12, 178 | opera: 12, 179 | safari: 0, 180 | samsung: 0, 181 | }, 182 | flexDirection: { 183 | and_chr: 0, 184 | and_ff: 0, 185 | and_qq: 0, 186 | and_uc: 0, 187 | android: 0, 188 | baidu: 0, 189 | bb: 0, 190 | chrome: 0, 191 | edge: 0, 192 | firefox: 0, 193 | ie: 9, 194 | ie_mob: 0, 195 | ios_saf: 0, 196 | op_mini: 0, 197 | op_mob: 12, 198 | opera: 12, 199 | safari: 0, 200 | samsung: 0, 201 | }, 202 | flexGrow: { 203 | and_chr: 0, 204 | and_ff: 0, 205 | and_qq: 0, 206 | and_uc: 0, 207 | android: 0, 208 | baidu: 0, 209 | bb: 0, 210 | chrome: 0, 211 | edge: 0, 212 | firefox: 0, 213 | ie: 9, 214 | ie_mob: 0, 215 | ios_saf: 0, 216 | op_mini: 0, 217 | op_mob: 12, 218 | opera: 12, 219 | safari: 0, 220 | samsung: 0, 221 | }, 222 | flexFlow: { 223 | and_chr: 0, 224 | and_ff: 0, 225 | and_qq: 0, 226 | and_uc: 0, 227 | android: 0, 228 | baidu: 0, 229 | bb: 0, 230 | chrome: 0, 231 | edge: 0, 232 | firefox: 0, 233 | ie: 9, 234 | ie_mob: 0, 235 | ios_saf: 0, 236 | op_mini: 0, 237 | op_mob: 12, 238 | opera: 12, 239 | safari: 0, 240 | samsung: 0, 241 | }, 242 | flexShrink: { 243 | and_chr: 0, 244 | and_ff: 0, 245 | and_qq: 0, 246 | and_uc: 0, 247 | android: 0, 248 | baidu: 0, 249 | bb: 0, 250 | chrome: 0, 251 | edge: 0, 252 | firefox: 0, 253 | ie: 9, 254 | ie_mob: 0, 255 | ios_saf: 0, 256 | op_mini: 0, 257 | op_mob: 12, 258 | opera: 12, 259 | safari: 0, 260 | samsung: 0, 261 | }, 262 | flexWrap: { 263 | and_chr: 0, 264 | and_ff: 0, 265 | and_qq: 0, 266 | and_uc: 0, 267 | android: 0, 268 | baidu: 0, 269 | bb: 0, 270 | chrome: 0, 271 | edge: 0, 272 | firefox: 0, 273 | ie: 9, 274 | ie_mob: 0, 275 | ios_saf: 0, 276 | op_mini: 0, 277 | op_mob: 12, 278 | opera: 12, 279 | safari: 0, 280 | samsung: 0, 281 | }, 282 | alignContent: { 283 | and_chr: 0, 284 | and_ff: 0, 285 | and_qq: 0, 286 | and_uc: 0, 287 | android: 0, 288 | baidu: 0, 289 | bb: 0, 290 | chrome: 0, 291 | edge: 0, 292 | firefox: 0, 293 | ie: 9, 294 | ie_mob: 0, 295 | ios_saf: 0, 296 | op_mini: 0, 297 | op_mob: 12, 298 | opera: 12, 299 | safari: 0, 300 | samsung: 0, 301 | }, 302 | alignItems: { 303 | and_chr: 0, 304 | and_ff: 0, 305 | and_qq: 0, 306 | and_uc: 0, 307 | android: 0, 308 | baidu: 0, 309 | bb: 0, 310 | chrome: 0, 311 | edge: 0, 312 | firefox: 0, 313 | ie: 9, 314 | ie_mob: 0, 315 | ios_saf: 0, 316 | op_mini: 0, 317 | op_mob: 12, 318 | opera: 12, 319 | safari: 0, 320 | samsung: 0, 321 | }, 322 | alignSelf: { 323 | and_chr: 0, 324 | and_ff: 0, 325 | and_qq: 0, 326 | and_uc: 0, 327 | android: 0, 328 | baidu: 0, 329 | bb: 0, 330 | chrome: 0, 331 | edge: 0, 332 | firefox: 0, 333 | ie: 9, 334 | ie_mob: 0, 335 | ios_saf: 0, 336 | op_mini: 0, 337 | op_mob: 12, 338 | opera: 12, 339 | safari: 0, 340 | samsung: 0, 341 | }, 342 | justifyContent: { 343 | and_chr: 0, 344 | and_ff: 0, 345 | and_qq: 0, 346 | and_uc: 0, 347 | android: 0, 348 | baidu: 0, 349 | bb: 0, 350 | chrome: 0, 351 | edge: 0, 352 | firefox: 0, 353 | ie: 9, 354 | ie_mob: 0, 355 | ios_saf: 0, 356 | op_mini: 0, 357 | op_mob: 12, 358 | opera: 12, 359 | safari: 0, 360 | samsung: 0, 361 | }, 362 | order: { 363 | and_chr: 0, 364 | and_ff: 0, 365 | and_qq: 0, 366 | and_uc: 0, 367 | android: 0, 368 | baidu: 0, 369 | bb: 0, 370 | chrome: 0, 371 | edge: 0, 372 | firefox: 0, 373 | ie: 9, 374 | ie_mob: 0, 375 | ios_saf: 0, 376 | op_mini: 0, 377 | op_mob: 12, 378 | opera: 12, 379 | safari: 0, 380 | samsung: 0, 381 | }, 382 | transition: { 383 | and_chr: 0, 384 | and_ff: 0, 385 | and_qq: 0, 386 | and_uc: 0, 387 | android: 0, 388 | baidu: 0, 389 | bb: 0, 390 | chrome: 0, 391 | edge: 0, 392 | firefox: 3.6, 393 | ie: 9, 394 | ie_mob: 0, 395 | ios_saf: 0, 396 | op_mini: 0, 397 | op_mob: 0, 398 | opera: 10, 399 | safari: 0, 400 | samsung: 0, 401 | }, 402 | transitionDelay: { 403 | and_chr: 0, 404 | and_ff: 0, 405 | and_qq: 0, 406 | and_uc: 0, 407 | android: 0, 408 | baidu: 0, 409 | bb: 0, 410 | chrome: 0, 411 | edge: 0, 412 | firefox: 3.6, 413 | ie: 9, 414 | ie_mob: 0, 415 | ios_saf: 0, 416 | op_mini: 0, 417 | op_mob: 0, 418 | opera: 10, 419 | safari: 0, 420 | samsung: 0, 421 | }, 422 | transitionDuration: { 423 | and_chr: 0, 424 | and_ff: 0, 425 | and_qq: 0, 426 | and_uc: 0, 427 | android: 0, 428 | baidu: 0, 429 | bb: 0, 430 | chrome: 0, 431 | edge: 0, 432 | firefox: 3.6, 433 | ie: 9, 434 | ie_mob: 0, 435 | ios_saf: 0, 436 | op_mini: 0, 437 | op_mob: 0, 438 | opera: 10, 439 | safari: 0, 440 | samsung: 0, 441 | }, 442 | transitionProperty: { 443 | and_chr: 0, 444 | and_ff: 0, 445 | and_qq: 0, 446 | and_uc: 0, 447 | android: 0, 448 | baidu: 0, 449 | bb: 0, 450 | chrome: 0, 451 | edge: 0, 452 | firefox: 3.6, 453 | ie: 9, 454 | ie_mob: 0, 455 | ios_saf: 0, 456 | op_mini: 0, 457 | op_mob: 0, 458 | opera: 10, 459 | safari: 0, 460 | samsung: 0, 461 | }, 462 | transitionTimingFunction: { 463 | and_chr: 0, 464 | and_ff: 0, 465 | and_qq: 0, 466 | and_uc: 0, 467 | android: 0, 468 | baidu: 0, 469 | bb: 0, 470 | chrome: 0, 471 | edge: 0, 472 | firefox: 3.6, 473 | ie: 9, 474 | ie_mob: 0, 475 | ios_saf: 0, 476 | op_mini: 0, 477 | op_mob: 0, 478 | opera: 10, 479 | safari: 0, 480 | samsung: 0, 481 | }, 482 | transform: { 483 | and_chr: 0, 484 | and_ff: 0, 485 | and_qq: 0, 486 | and_uc: 0, 487 | android: 2.3, 488 | baidu: 0, 489 | bb: 0, 490 | chrome: 11, 491 | edge: 0, 492 | firefox: 9, 493 | ie: 9, 494 | ie_mob: 0, 495 | ios_saf: 0, 496 | op_mini: 0, 497 | op_mob: 12.1, 498 | opera: 12.1, 499 | safari: 3.2, 500 | samsung: 0, 501 | }, 502 | transformOrigin: { 503 | and_chr: 0, 504 | and_ff: 0, 505 | and_qq: 0, 506 | and_uc: 0, 507 | android: 2.3, 508 | baidu: 0, 509 | bb: 0, 510 | chrome: 11, 511 | edge: 0, 512 | firefox: 9, 513 | ie: 9, 514 | ie_mob: 0, 515 | ios_saf: 0, 516 | op_mini: 0, 517 | op_mob: 12.1, 518 | opera: 12.1, 519 | safari: 3.2, 520 | samsung: 0, 521 | }, 522 | transformOriginX: { 523 | and_chr: 0, 524 | and_ff: 0, 525 | and_qq: 0, 526 | and_uc: 0, 527 | android: 2.3, 528 | baidu: 0, 529 | bb: 0, 530 | chrome: 11, 531 | edge: 0, 532 | firefox: 9, 533 | ie: 9, 534 | ie_mob: 0, 535 | ios_saf: 0, 536 | op_mini: 0, 537 | op_mob: 12.1, 538 | opera: 12.1, 539 | safari: 3.2, 540 | samsung: 0, 541 | }, 542 | transformOriginY: { 543 | and_chr: 0, 544 | and_ff: 0, 545 | and_qq: 0, 546 | and_uc: 0, 547 | android: 2.3, 548 | baidu: 0, 549 | bb: 0, 550 | chrome: 11, 551 | edge: 0, 552 | firefox: 9, 553 | ie: 9, 554 | ie_mob: 0, 555 | ios_saf: 0, 556 | op_mini: 0, 557 | op_mob: 12.1, 558 | opera: 12.1, 559 | safari: 3.2, 560 | samsung: 0, 561 | }, 562 | backfaceVisibility: { 563 | and_chr: 0, 564 | and_ff: 0, 565 | and_qq: 0, 566 | and_uc: 0, 567 | android: 2.3, 568 | baidu: 0, 569 | bb: 0, 570 | chrome: 11, 571 | edge: 0, 572 | firefox: 9, 573 | ie: 9, 574 | ie_mob: 0, 575 | ios_saf: 0, 576 | op_mini: 0, 577 | op_mob: 12.1, 578 | opera: 12.1, 579 | safari: 3.2, 580 | samsung: 0, 581 | }, 582 | perspective: { 583 | and_chr: 0, 584 | and_ff: 0, 585 | and_qq: 0, 586 | and_uc: 0, 587 | android: 2.3, 588 | baidu: 0, 589 | bb: 0, 590 | chrome: 11, 591 | edge: 0, 592 | firefox: 9, 593 | ie: 9, 594 | ie_mob: 0, 595 | ios_saf: 0, 596 | op_mini: 0, 597 | op_mob: 12.1, 598 | opera: 12.1, 599 | safari: 3.2, 600 | samsung: 0, 601 | }, 602 | perspectiveOrigin: { 603 | and_chr: 0, 604 | and_ff: 0, 605 | and_qq: 0, 606 | and_uc: 0, 607 | android: 2.3, 608 | baidu: 0, 609 | bb: 0, 610 | chrome: 11, 611 | edge: 0, 612 | firefox: 9, 613 | ie: 9, 614 | ie_mob: 0, 615 | ios_saf: 0, 616 | op_mini: 0, 617 | op_mob: 12.1, 618 | opera: 12.1, 619 | safari: 3.2, 620 | samsung: 0, 621 | }, 622 | transformStyle: { 623 | and_chr: 0, 624 | and_ff: 0, 625 | and_qq: 0, 626 | and_uc: 0, 627 | android: 2.3, 628 | baidu: 0, 629 | bb: 0, 630 | chrome: 11, 631 | edge: 0, 632 | firefox: 9, 633 | ie: 9, 634 | ie_mob: 0, 635 | ios_saf: 0, 636 | op_mini: 0, 637 | op_mob: 12.1, 638 | opera: 12.1, 639 | safari: 3.2, 640 | samsung: 0, 641 | }, 642 | transformOriginZ: { 643 | and_chr: 0, 644 | and_ff: 0, 645 | and_qq: 0, 646 | and_uc: 0, 647 | android: 2.3, 648 | baidu: 0, 649 | bb: 0, 650 | chrome: 11, 651 | edge: 0, 652 | firefox: 9, 653 | ie: 9, 654 | ie_mob: 0, 655 | ios_saf: 0, 656 | op_mini: 0, 657 | op_mob: 12.1, 658 | opera: 12.1, 659 | safari: 3.2, 660 | samsung: 0, 661 | }, 662 | animation: { 663 | and_chr: 0, 664 | and_ff: 0, 665 | and_qq: 0, 666 | and_uc: 0, 667 | android: 0, 668 | baidu: 0, 669 | bb: 0, 670 | chrome: 0, 671 | edge: 0, 672 | firefox: 4, 673 | ie: 9, 674 | ie_mob: 0, 675 | ios_saf: 0, 676 | op_mini: 0, 677 | op_mob: 12, 678 | opera: 11.6, 679 | safari: 3.2, 680 | samsung: 0, 681 | }, 682 | animationDelay: { 683 | and_chr: 0, 684 | and_ff: 0, 685 | and_qq: 0, 686 | and_uc: 0, 687 | android: 0, 688 | baidu: 0, 689 | bb: 0, 690 | chrome: 0, 691 | edge: 0, 692 | firefox: 4, 693 | ie: 9, 694 | ie_mob: 0, 695 | ios_saf: 0, 696 | op_mini: 0, 697 | op_mob: 12, 698 | opera: 11.6, 699 | safari: 3.2, 700 | samsung: 0, 701 | }, 702 | animationDirection: { 703 | and_chr: 0, 704 | and_ff: 0, 705 | and_qq: 0, 706 | and_uc: 0, 707 | android: 0, 708 | baidu: 0, 709 | bb: 0, 710 | chrome: 0, 711 | edge: 0, 712 | firefox: 4, 713 | ie: 9, 714 | ie_mob: 0, 715 | ios_saf: 0, 716 | op_mini: 0, 717 | op_mob: 12, 718 | opera: 11.6, 719 | safari: 3.2, 720 | samsung: 0, 721 | }, 722 | animationFillMode: { 723 | and_chr: 0, 724 | and_ff: 0, 725 | and_qq: 0, 726 | and_uc: 0, 727 | android: 0, 728 | baidu: 0, 729 | bb: 0, 730 | chrome: 0, 731 | edge: 0, 732 | firefox: 4, 733 | ie: 9, 734 | ie_mob: 0, 735 | ios_saf: 0, 736 | op_mini: 0, 737 | op_mob: 12, 738 | opera: 11.6, 739 | safari: 3.2, 740 | samsung: 0, 741 | }, 742 | animationDuration: { 743 | and_chr: 0, 744 | and_ff: 0, 745 | and_qq: 0, 746 | and_uc: 0, 747 | android: 0, 748 | baidu: 0, 749 | bb: 0, 750 | chrome: 0, 751 | edge: 0, 752 | firefox: 4, 753 | ie: 9, 754 | ie_mob: 0, 755 | ios_saf: 0, 756 | op_mini: 0, 757 | op_mob: 12, 758 | opera: 11.6, 759 | safari: 3.2, 760 | samsung: 0, 761 | }, 762 | animationIterationCount: { 763 | and_chr: 0, 764 | and_ff: 0, 765 | and_qq: 0, 766 | and_uc: 0, 767 | android: 0, 768 | baidu: 0, 769 | bb: 0, 770 | chrome: 0, 771 | edge: 0, 772 | firefox: 4, 773 | ie: 9, 774 | ie_mob: 0, 775 | ios_saf: 0, 776 | op_mini: 0, 777 | op_mob: 12, 778 | opera: 11.6, 779 | safari: 3.2, 780 | samsung: 0, 781 | }, 782 | animationName: { 783 | and_chr: 0, 784 | and_ff: 0, 785 | and_qq: 0, 786 | and_uc: 0, 787 | android: 0, 788 | baidu: 0, 789 | bb: 0, 790 | chrome: 0, 791 | edge: 0, 792 | firefox: 4, 793 | ie: 9, 794 | ie_mob: 0, 795 | ios_saf: 0, 796 | op_mini: 0, 797 | op_mob: 12, 798 | opera: 11.6, 799 | safari: 3.2, 800 | samsung: 0, 801 | }, 802 | animationPlayState: { 803 | and_chr: 0, 804 | and_ff: 0, 805 | and_qq: 0, 806 | and_uc: 0, 807 | android: 0, 808 | baidu: 0, 809 | bb: 0, 810 | chrome: 0, 811 | edge: 0, 812 | firefox: 4, 813 | ie: 9, 814 | ie_mob: 0, 815 | ios_saf: 0, 816 | op_mini: 0, 817 | op_mob: 12, 818 | opera: 11.6, 819 | safari: 3.2, 820 | samsung: 0, 821 | }, 822 | animationTimingFunction: { 823 | and_chr: 0, 824 | and_ff: 0, 825 | and_qq: 0, 826 | and_uc: 0, 827 | android: 0, 828 | baidu: 0, 829 | bb: 0, 830 | chrome: 0, 831 | edge: 0, 832 | firefox: 4, 833 | ie: 9, 834 | ie_mob: 0, 835 | ios_saf: 0, 836 | op_mini: 0, 837 | op_mob: 12, 838 | opera: 11.6, 839 | safari: 3.2, 840 | samsung: 0, 841 | }, 842 | appearance: { 843 | and_chr: 0, 844 | and_ff: 0, 845 | and_qq: 0, 846 | and_uc: 0, 847 | android: 0, 848 | baidu: 0, 849 | bb: 0, 850 | chrome: 0, 851 | edge: 0, 852 | firefox: 0, 853 | ie: 11, 854 | ie_mob: 10, 855 | ios_saf: 0, 856 | op_mini: 0, 857 | op_mob: 12.1, 858 | opera: 12.1, 859 | safari: 0, 860 | samsung: 0, 861 | }, 862 | userSelect: { 863 | and_chr: 0, 864 | and_ff: 0, 865 | and_qq: 0, 866 | and_uc: 0, 867 | android: 0, 868 | baidu: 7.12, 869 | bb: 0, 870 | chrome: 0, 871 | edge: 0, 872 | firefox: 0, 873 | ie: 9, 874 | ie_mob: 0, 875 | ios_saf: 0, 876 | op_mini: 0, 877 | op_mob: 12.1, 878 | opera: 12.1, 879 | safari: 0, 880 | samsung: 0, 881 | }, 882 | backdropFilter: { 883 | and_chr: 59, 884 | and_ff: 55, 885 | and_qq: 1.2, 886 | and_uc: 11.4, 887 | android: 56, 888 | baidu: 7.12, 889 | bb: 10, 890 | chrome: 63, 891 | edge: 16, 892 | firefox: 58, 893 | ie: 11, 894 | ie_mob: 11, 895 | ios_saf: 8.1, 896 | op_mini: 0, 897 | op_mob: 37, 898 | opera: 49, 899 | safari: 8, 900 | samsung: 5, 901 | }, 902 | boxSizing: { 903 | and_chr: 0, 904 | and_ff: 0, 905 | and_qq: 0, 906 | and_uc: 0, 907 | android: 0, 908 | baidu: 0, 909 | bb: 0, 910 | chrome: 0, 911 | edge: 0, 912 | firefox: 0, 913 | ie: 0, 914 | ie_mob: 0, 915 | ios_saf: 0, 916 | op_mini: 0, 917 | op_mob: 0, 918 | opera: 9, 919 | safari: 0, 920 | samsung: 0, 921 | }, 922 | fontKerning: { 923 | and_chr: 0, 924 | and_ff: 0, 925 | and_qq: 0, 926 | and_uc: 0, 927 | android: 4.2, 928 | baidu: 0, 929 | bb: 7, 930 | chrome: 28, 931 | edge: 16, 932 | firefox: 33, 933 | ie: 11, 934 | ie_mob: 11, 935 | ios_saf: 7, 936 | op_mini: 0, 937 | op_mob: 12.1, 938 | opera: 15, 939 | safari: 6.1, 940 | samsung: 0, 941 | }, 942 | wrapFlow: { 943 | and_chr: 59, 944 | and_ff: 55, 945 | and_qq: 1.2, 946 | and_uc: 11.4, 947 | android: 56, 948 | baidu: 7.12, 949 | bb: 10, 950 | chrome: 63, 951 | edge: 0, 952 | firefox: 58, 953 | ie: 9, 954 | ie_mob: 0, 955 | ios_saf: 11, 956 | op_mini: 0, 957 | op_mob: 37, 958 | opera: 49, 959 | safari: 11, 960 | samsung: 5, 961 | }, 962 | wrapThrough: { 963 | and_chr: 59, 964 | and_ff: 55, 965 | and_qq: 1.2, 966 | and_uc: 11.4, 967 | android: 56, 968 | baidu: 7.12, 969 | bb: 10, 970 | chrome: 63, 971 | edge: 0, 972 | firefox: 58, 973 | ie: 9, 974 | ie_mob: 0, 975 | ios_saf: 11, 976 | op_mini: 0, 977 | op_mob: 37, 978 | opera: 49, 979 | safari: 11, 980 | samsung: 5, 981 | }, 982 | wrapMargin: { 983 | and_chr: 59, 984 | and_ff: 55, 985 | and_qq: 1.2, 986 | and_uc: 11.4, 987 | android: 56, 988 | baidu: 7.12, 989 | bb: 10, 990 | chrome: 63, 991 | edge: 0, 992 | firefox: 58, 993 | ie: 9, 994 | ie_mob: 0, 995 | ios_saf: 11, 996 | op_mini: 0, 997 | op_mob: 37, 998 | opera: 49, 999 | safari: 11, 1000 | samsung: 5, 1001 | }, 1002 | scrollSnapType: { 1003 | and_chr: 59, 1004 | and_ff: 0, 1005 | and_qq: 1.2, 1006 | and_uc: 11.4, 1007 | android: 56, 1008 | baidu: 7.12, 1009 | bb: 10, 1010 | chrome: 63, 1011 | edge: 0, 1012 | firefox: 38, 1013 | ie: 9, 1014 | ie_mob: 11, 1015 | ios_saf: 8.1, 1016 | op_mini: 0, 1017 | op_mob: 37, 1018 | opera: 49, 1019 | safari: 8, 1020 | samsung: 5, 1021 | }, 1022 | scrollSnapPointsX: { 1023 | and_chr: 59, 1024 | and_ff: 0, 1025 | and_qq: 1.2, 1026 | and_uc: 11.4, 1027 | android: 56, 1028 | baidu: 7.12, 1029 | bb: 10, 1030 | chrome: 63, 1031 | edge: 0, 1032 | firefox: 38, 1033 | ie: 9, 1034 | ie_mob: 11, 1035 | ios_saf: 8.1, 1036 | op_mini: 0, 1037 | op_mob: 37, 1038 | opera: 49, 1039 | safari: 8, 1040 | samsung: 5, 1041 | }, 1042 | scrollSnapPointsY: { 1043 | and_chr: 59, 1044 | and_ff: 0, 1045 | and_qq: 1.2, 1046 | and_uc: 11.4, 1047 | android: 56, 1048 | baidu: 7.12, 1049 | bb: 10, 1050 | chrome: 63, 1051 | edge: 0, 1052 | firefox: 38, 1053 | ie: 9, 1054 | ie_mob: 11, 1055 | ios_saf: 8.1, 1056 | op_mini: 0, 1057 | op_mob: 37, 1058 | opera: 49, 1059 | safari: 8, 1060 | samsung: 5, 1061 | }, 1062 | scrollSnapDestination: { 1063 | and_chr: 59, 1064 | and_ff: 0, 1065 | and_qq: 1.2, 1066 | and_uc: 11.4, 1067 | android: 56, 1068 | baidu: 7.12, 1069 | bb: 10, 1070 | chrome: 63, 1071 | edge: 0, 1072 | firefox: 38, 1073 | ie: 9, 1074 | ie_mob: 11, 1075 | ios_saf: 8.1, 1076 | op_mini: 0, 1077 | op_mob: 37, 1078 | opera: 49, 1079 | safari: 8, 1080 | samsung: 5, 1081 | }, 1082 | scrollSnapCoordinate: { 1083 | and_chr: 59, 1084 | and_ff: 0, 1085 | and_qq: 1.2, 1086 | and_uc: 11.4, 1087 | android: 56, 1088 | baidu: 7.12, 1089 | bb: 10, 1090 | chrome: 63, 1091 | edge: 0, 1092 | firefox: 38, 1093 | ie: 9, 1094 | ie_mob: 11, 1095 | ios_saf: 8.1, 1096 | op_mini: 0, 1097 | op_mob: 37, 1098 | opera: 49, 1099 | safari: 8, 1100 | samsung: 5, 1101 | }, 1102 | textEmphasisPosition: { 1103 | and_chr: 0, 1104 | and_ff: 55, 1105 | and_qq: 0, 1106 | and_uc: 0, 1107 | android: 4.2, 1108 | baidu: 0, 1109 | bb: 7, 1110 | chrome: 24, 1111 | edge: 16, 1112 | firefox: 45, 1113 | ie: 11, 1114 | ie_mob: 11, 1115 | ios_saf: 6, 1116 | op_mini: 0, 1117 | op_mob: 12.1, 1118 | opera: 12.1, 1119 | safari: 6, 1120 | samsung: 0, 1121 | }, 1122 | textEmphasis: { 1123 | and_chr: 0, 1124 | and_ff: 55, 1125 | and_qq: 0, 1126 | and_uc: 0, 1127 | android: 4.2, 1128 | baidu: 0, 1129 | bb: 7, 1130 | chrome: 24, 1131 | edge: 16, 1132 | firefox: 45, 1133 | ie: 11, 1134 | ie_mob: 11, 1135 | ios_saf: 6, 1136 | op_mini: 0, 1137 | op_mob: 12.1, 1138 | opera: 12.1, 1139 | safari: 6, 1140 | samsung: 0, 1141 | }, 1142 | textEmphasisStyle: { 1143 | and_chr: 0, 1144 | and_ff: 55, 1145 | and_qq: 0, 1146 | and_uc: 0, 1147 | android: 4.2, 1148 | baidu: 0, 1149 | bb: 7, 1150 | chrome: 24, 1151 | edge: 16, 1152 | firefox: 45, 1153 | ie: 11, 1154 | ie_mob: 11, 1155 | ios_saf: 6, 1156 | op_mini: 0, 1157 | op_mob: 12.1, 1158 | opera: 12.1, 1159 | safari: 6, 1160 | samsung: 0, 1161 | }, 1162 | textEmphasisColor: { 1163 | and_chr: 0, 1164 | and_ff: 55, 1165 | and_qq: 0, 1166 | and_uc: 0, 1167 | android: 4.2, 1168 | baidu: 0, 1169 | bb: 7, 1170 | chrome: 24, 1171 | edge: 16, 1172 | firefox: 45, 1173 | ie: 11, 1174 | ie_mob: 11, 1175 | ios_saf: 6, 1176 | op_mini: 0, 1177 | op_mob: 12.1, 1178 | opera: 12.1, 1179 | safari: 6, 1180 | samsung: 0, 1181 | }, 1182 | textAlignLast: { 1183 | and_chr: 0, 1184 | and_ff: 0, 1185 | and_qq: 1.2, 1186 | and_uc: 11.4, 1187 | android: 4.4, 1188 | baidu: 0, 1189 | bb: 10, 1190 | chrome: 46, 1191 | edge: 0, 1192 | firefox: 11, 1193 | ie: 0, 1194 | ie_mob: 0, 1195 | ios_saf: 11, 1196 | op_mini: 0, 1197 | op_mob: 37, 1198 | opera: 33, 1199 | safari: 11, 1200 | samsung: 4, 1201 | }, 1202 | boxDecorationBreak: { 1203 | and_chr: 0, 1204 | and_ff: 0, 1205 | and_qq: 0, 1206 | and_uc: 0, 1207 | android: 4.2, 1208 | baidu: 0, 1209 | bb: 7, 1210 | chrome: 21, 1211 | edge: 16, 1212 | firefox: 31, 1213 | ie: 11, 1214 | ie_mob: 11, 1215 | ios_saf: 6, 1216 | op_mini: 0, 1217 | op_mob: 10, 1218 | opera: 10.6, 1219 | safari: 6, 1220 | samsung: 0, 1221 | }, 1222 | clipPath: { 1223 | and_chr: 0, 1224 | and_ff: 0, 1225 | and_qq: 0, 1226 | and_uc: 0, 1227 | android: 4.2, 1228 | baidu: 0, 1229 | bb: 10, 1230 | chrome: 23, 1231 | edge: 16, 1232 | firefox: 3, 1233 | ie: 11, 1234 | ie_mob: 11, 1235 | ios_saf: 6, 1236 | op_mini: 0, 1237 | op_mob: 12.1, 1238 | opera: 12.1, 1239 | safari: 6.1, 1240 | samsung: 0, 1241 | }, 1242 | maskImage: { 1243 | and_chr: 0, 1244 | and_ff: 0, 1245 | and_qq: 0, 1246 | and_uc: 0, 1247 | android: 0, 1248 | baidu: 0, 1249 | bb: 0, 1250 | chrome: 0, 1251 | edge: 16, 1252 | firefox: 3, 1253 | ie: 11, 1254 | ie_mob: 11, 1255 | ios_saf: 0, 1256 | op_mini: 0, 1257 | op_mob: 12.1, 1258 | opera: 12.1, 1259 | safari: 3.2, 1260 | samsung: 0, 1261 | }, 1262 | maskMode: { 1263 | and_chr: 0, 1264 | and_ff: 0, 1265 | and_qq: 0, 1266 | and_uc: 0, 1267 | android: 0, 1268 | baidu: 0, 1269 | bb: 0, 1270 | chrome: 0, 1271 | edge: 16, 1272 | firefox: 3, 1273 | ie: 11, 1274 | ie_mob: 11, 1275 | ios_saf: 0, 1276 | op_mini: 0, 1277 | op_mob: 12.1, 1278 | opera: 12.1, 1279 | safari: 3.2, 1280 | samsung: 0, 1281 | }, 1282 | maskRepeat: { 1283 | and_chr: 0, 1284 | and_ff: 0, 1285 | and_qq: 0, 1286 | and_uc: 0, 1287 | android: 0, 1288 | baidu: 0, 1289 | bb: 0, 1290 | chrome: 0, 1291 | edge: 16, 1292 | firefox: 3, 1293 | ie: 11, 1294 | ie_mob: 11, 1295 | ios_saf: 0, 1296 | op_mini: 0, 1297 | op_mob: 12.1, 1298 | opera: 12.1, 1299 | safari: 3.2, 1300 | samsung: 0, 1301 | }, 1302 | maskPosition: { 1303 | and_chr: 0, 1304 | and_ff: 0, 1305 | and_qq: 0, 1306 | and_uc: 0, 1307 | android: 0, 1308 | baidu: 0, 1309 | bb: 0, 1310 | chrome: 0, 1311 | edge: 16, 1312 | firefox: 3, 1313 | ie: 11, 1314 | ie_mob: 11, 1315 | ios_saf: 0, 1316 | op_mini: 0, 1317 | op_mob: 12.1, 1318 | opera: 12.1, 1319 | safari: 3.2, 1320 | samsung: 0, 1321 | }, 1322 | maskClip: { 1323 | and_chr: 0, 1324 | and_ff: 0, 1325 | and_qq: 0, 1326 | and_uc: 0, 1327 | android: 0, 1328 | baidu: 0, 1329 | bb: 0, 1330 | chrome: 0, 1331 | edge: 16, 1332 | firefox: 3, 1333 | ie: 11, 1334 | ie_mob: 11, 1335 | ios_saf: 0, 1336 | op_mini: 0, 1337 | op_mob: 12.1, 1338 | opera: 12.1, 1339 | safari: 3.2, 1340 | samsung: 0, 1341 | }, 1342 | maskOrigin: { 1343 | and_chr: 0, 1344 | and_ff: 0, 1345 | and_qq: 0, 1346 | and_uc: 0, 1347 | android: 0, 1348 | baidu: 0, 1349 | bb: 0, 1350 | chrome: 0, 1351 | edge: 16, 1352 | firefox: 3, 1353 | ie: 11, 1354 | ie_mob: 11, 1355 | ios_saf: 0, 1356 | op_mini: 0, 1357 | op_mob: 12.1, 1358 | opera: 12.1, 1359 | safari: 3.2, 1360 | samsung: 0, 1361 | }, 1362 | maskSize: { 1363 | and_chr: 0, 1364 | and_ff: 0, 1365 | and_qq: 0, 1366 | and_uc: 0, 1367 | android: 0, 1368 | baidu: 0, 1369 | bb: 0, 1370 | chrome: 0, 1371 | edge: 16, 1372 | firefox: 3, 1373 | ie: 11, 1374 | ie_mob: 11, 1375 | ios_saf: 0, 1376 | op_mini: 0, 1377 | op_mob: 12.1, 1378 | opera: 12.1, 1379 | safari: 3.2, 1380 | samsung: 0, 1381 | }, 1382 | maskComposite: { 1383 | and_chr: 0, 1384 | and_ff: 0, 1385 | and_qq: 0, 1386 | and_uc: 0, 1387 | android: 0, 1388 | baidu: 0, 1389 | bb: 0, 1390 | chrome: 0, 1391 | edge: 16, 1392 | firefox: 3, 1393 | ie: 11, 1394 | ie_mob: 11, 1395 | ios_saf: 0, 1396 | op_mini: 0, 1397 | op_mob: 12.1, 1398 | opera: 12.1, 1399 | safari: 3.2, 1400 | samsung: 0, 1401 | }, 1402 | mask: { 1403 | and_chr: 0, 1404 | and_ff: 0, 1405 | and_qq: 0, 1406 | and_uc: 0, 1407 | android: 0, 1408 | baidu: 0, 1409 | bb: 0, 1410 | chrome: 0, 1411 | edge: 16, 1412 | firefox: 3, 1413 | ie: 11, 1414 | ie_mob: 11, 1415 | ios_saf: 0, 1416 | op_mini: 0, 1417 | op_mob: 12.1, 1418 | opera: 12.1, 1419 | safari: 3.2, 1420 | samsung: 0, 1421 | }, 1422 | maskBorderSource: { 1423 | and_chr: 0, 1424 | and_ff: 0, 1425 | and_qq: 0, 1426 | and_uc: 0, 1427 | android: 0, 1428 | baidu: 0, 1429 | bb: 0, 1430 | chrome: 0, 1431 | edge: 16, 1432 | firefox: 3, 1433 | ie: 11, 1434 | ie_mob: 11, 1435 | ios_saf: 0, 1436 | op_mini: 0, 1437 | op_mob: 12.1, 1438 | opera: 12.1, 1439 | safari: 3.2, 1440 | samsung: 0, 1441 | }, 1442 | maskBorderMode: { 1443 | and_chr: 0, 1444 | and_ff: 0, 1445 | and_qq: 0, 1446 | and_uc: 0, 1447 | android: 0, 1448 | baidu: 0, 1449 | bb: 0, 1450 | chrome: 0, 1451 | edge: 16, 1452 | firefox: 3, 1453 | ie: 11, 1454 | ie_mob: 11, 1455 | ios_saf: 0, 1456 | op_mini: 0, 1457 | op_mob: 12.1, 1458 | opera: 12.1, 1459 | safari: 3.2, 1460 | samsung: 0, 1461 | }, 1462 | maskBorderSlice: { 1463 | and_chr: 0, 1464 | and_ff: 0, 1465 | and_qq: 0, 1466 | and_uc: 0, 1467 | android: 0, 1468 | baidu: 0, 1469 | bb: 0, 1470 | chrome: 0, 1471 | edge: 16, 1472 | firefox: 3, 1473 | ie: 11, 1474 | ie_mob: 11, 1475 | ios_saf: 0, 1476 | op_mini: 0, 1477 | op_mob: 12.1, 1478 | opera: 12.1, 1479 | safari: 3.2, 1480 | samsung: 0, 1481 | }, 1482 | maskBorderWidth: { 1483 | and_chr: 0, 1484 | and_ff: 0, 1485 | and_qq: 0, 1486 | and_uc: 0, 1487 | android: 0, 1488 | baidu: 0, 1489 | bb: 0, 1490 | chrome: 0, 1491 | edge: 16, 1492 | firefox: 3, 1493 | ie: 11, 1494 | ie_mob: 11, 1495 | ios_saf: 0, 1496 | op_mini: 0, 1497 | op_mob: 12.1, 1498 | opera: 12.1, 1499 | safari: 3.2, 1500 | samsung: 0, 1501 | }, 1502 | maskBorderOutset: { 1503 | and_chr: 0, 1504 | and_ff: 0, 1505 | and_qq: 0, 1506 | and_uc: 0, 1507 | android: 0, 1508 | baidu: 0, 1509 | bb: 0, 1510 | chrome: 0, 1511 | edge: 16, 1512 | firefox: 3, 1513 | ie: 11, 1514 | ie_mob: 11, 1515 | ios_saf: 0, 1516 | op_mini: 0, 1517 | op_mob: 12.1, 1518 | opera: 12.1, 1519 | safari: 3.2, 1520 | samsung: 0, 1521 | }, 1522 | maskBorderRepeat: { 1523 | and_chr: 0, 1524 | and_ff: 0, 1525 | and_qq: 0, 1526 | and_uc: 0, 1527 | android: 0, 1528 | baidu: 0, 1529 | bb: 0, 1530 | chrome: 0, 1531 | edge: 16, 1532 | firefox: 3, 1533 | ie: 11, 1534 | ie_mob: 11, 1535 | ios_saf: 0, 1536 | op_mini: 0, 1537 | op_mob: 12.1, 1538 | opera: 12.1, 1539 | safari: 3.2, 1540 | samsung: 0, 1541 | }, 1542 | maskBorder: { 1543 | and_chr: 0, 1544 | and_ff: 0, 1545 | and_qq: 0, 1546 | and_uc: 0, 1547 | android: 0, 1548 | baidu: 0, 1549 | bb: 0, 1550 | chrome: 0, 1551 | edge: 16, 1552 | firefox: 3, 1553 | ie: 11, 1554 | ie_mob: 11, 1555 | ios_saf: 0, 1556 | op_mini: 0, 1557 | op_mob: 12.1, 1558 | opera: 12.1, 1559 | safari: 3.2, 1560 | samsung: 0, 1561 | }, 1562 | maskType: { 1563 | and_chr: 0, 1564 | and_ff: 0, 1565 | and_qq: 0, 1566 | and_uc: 0, 1567 | android: 0, 1568 | baidu: 0, 1569 | bb: 0, 1570 | chrome: 0, 1571 | edge: 16, 1572 | firefox: 3, 1573 | ie: 11, 1574 | ie_mob: 11, 1575 | ios_saf: 0, 1576 | op_mini: 0, 1577 | op_mob: 12.1, 1578 | opera: 12.1, 1579 | safari: 3.2, 1580 | samsung: 0, 1581 | }, 1582 | touchAction: { 1583 | and_chr: 0, 1584 | and_ff: 0, 1585 | and_qq: 0, 1586 | and_uc: 0, 1587 | android: 4.4, 1588 | baidu: 0, 1589 | bb: 10, 1590 | chrome: 35, 1591 | edge: 0, 1592 | firefox: 51, 1593 | ie: 9, 1594 | ie_mob: 0, 1595 | ios_saf: 9, 1596 | op_mini: 0, 1597 | op_mob: 12.1, 1598 | opera: 22, 1599 | safari: 11, 1600 | samsung: 0, 1601 | }, 1602 | textSizeAdjust: { 1603 | and_chr: 0, 1604 | and_ff: 0, 1605 | and_qq: 1.2, 1606 | and_uc: 0, 1607 | android: 4.4, 1608 | baidu: 7.12, 1609 | bb: 10, 1610 | chrome: 53, 1611 | edge: 16, 1612 | firefox: 58, 1613 | ie: 11, 1614 | ie_mob: 0, 1615 | ios_saf: 4.2, 1616 | op_mini: 0, 1617 | op_mob: 37, 1618 | opera: 44, 1619 | safari: 11, 1620 | samsung: 4, 1621 | }, 1622 | textDecorationStyle: { 1623 | and_chr: 0, 1624 | and_ff: 0, 1625 | and_qq: 1.2, 1626 | and_uc: 11.4, 1627 | android: 4.4, 1628 | baidu: 0, 1629 | bb: 10, 1630 | chrome: 56, 1631 | edge: 16, 1632 | firefox: 5, 1633 | ie: 11, 1634 | ie_mob: 11, 1635 | ios_saf: 7, 1636 | op_mini: 0, 1637 | op_mob: 37, 1638 | opera: 43, 1639 | safari: 7, 1640 | samsung: 5, 1641 | }, 1642 | textDecorationSkip: { 1643 | and_chr: 0, 1644 | and_ff: 0, 1645 | and_qq: 1.2, 1646 | and_uc: 11.4, 1647 | android: 4.4, 1648 | baidu: 0, 1649 | bb: 10, 1650 | chrome: 56, 1651 | edge: 16, 1652 | firefox: 5, 1653 | ie: 11, 1654 | ie_mob: 11, 1655 | ios_saf: 7, 1656 | op_mini: 0, 1657 | op_mob: 37, 1658 | opera: 43, 1659 | safari: 7, 1660 | samsung: 5, 1661 | }, 1662 | textDecorationLine: { 1663 | and_chr: 0, 1664 | and_ff: 0, 1665 | and_qq: 1.2, 1666 | and_uc: 11.4, 1667 | android: 4.4, 1668 | baidu: 0, 1669 | bb: 10, 1670 | chrome: 56, 1671 | edge: 16, 1672 | firefox: 5, 1673 | ie: 11, 1674 | ie_mob: 11, 1675 | ios_saf: 7, 1676 | op_mini: 0, 1677 | op_mob: 37, 1678 | opera: 43, 1679 | safari: 7, 1680 | samsung: 5, 1681 | }, 1682 | textDecorationColor: { 1683 | and_chr: 0, 1684 | and_ff: 0, 1685 | and_qq: 1.2, 1686 | and_uc: 11.4, 1687 | android: 4.4, 1688 | baidu: 0, 1689 | bb: 10, 1690 | chrome: 56, 1691 | edge: 16, 1692 | firefox: 5, 1693 | ie: 11, 1694 | ie_mob: 11, 1695 | ios_saf: 7, 1696 | op_mini: 0, 1697 | op_mob: 37, 1698 | opera: 43, 1699 | safari: 7, 1700 | samsung: 5, 1701 | }, 1702 | shapeImageThreshold: { 1703 | and_chr: 0, 1704 | and_ff: 55, 1705 | and_qq: 0, 1706 | and_uc: 0, 1707 | android: 4.4, 1708 | baidu: 0, 1709 | bb: 10, 1710 | chrome: 36, 1711 | edge: 16, 1712 | firefox: 58, 1713 | ie: 11, 1714 | ie_mob: 11, 1715 | ios_saf: 7, 1716 | op_mini: 0, 1717 | op_mob: 12.1, 1718 | opera: 23, 1719 | safari: 7, 1720 | samsung: 0, 1721 | }, 1722 | shapeImageMargin: { 1723 | and_chr: 0, 1724 | and_ff: 55, 1725 | and_qq: 0, 1726 | and_uc: 0, 1727 | android: 4.4, 1728 | baidu: 0, 1729 | bb: 10, 1730 | chrome: 36, 1731 | edge: 16, 1732 | firefox: 58, 1733 | ie: 11, 1734 | ie_mob: 11, 1735 | ios_saf: 7, 1736 | op_mini: 0, 1737 | op_mob: 12.1, 1738 | opera: 23, 1739 | safari: 7, 1740 | samsung: 0, 1741 | }, 1742 | shapeImageOutside: { 1743 | and_chr: 0, 1744 | and_ff: 55, 1745 | and_qq: 0, 1746 | and_uc: 0, 1747 | android: 4.4, 1748 | baidu: 0, 1749 | bb: 10, 1750 | chrome: 36, 1751 | edge: 16, 1752 | firefox: 58, 1753 | ie: 11, 1754 | ie_mob: 11, 1755 | ios_saf: 7, 1756 | op_mini: 0, 1757 | op_mob: 12.1, 1758 | opera: 23, 1759 | safari: 7, 1760 | samsung: 0, 1761 | }, 1762 | tabSize: { 1763 | and_chr: 0, 1764 | and_ff: 0, 1765 | and_qq: 0, 1766 | and_uc: 0, 1767 | android: 4.2, 1768 | baidu: 0, 1769 | bb: 0, 1770 | chrome: 20, 1771 | edge: 16, 1772 | firefox: 3.6, 1773 | ie: 11, 1774 | ie_mob: 11, 1775 | ios_saf: 6, 1776 | op_mini: 0, 1777 | op_mob: 10, 1778 | opera: 10.5, 1779 | safari: 6, 1780 | samsung: 0, 1781 | }, 1782 | filter: { 1783 | and_chr: 0, 1784 | and_ff: 0, 1785 | and_qq: 0, 1786 | and_uc: 0, 1787 | android: 4.2, 1788 | baidu: 0, 1789 | bb: 7, 1790 | chrome: 17, 1791 | edge: 12, 1792 | firefox: 3.5, 1793 | ie: 11, 1794 | ie_mob: 11, 1795 | ios_saf: 5, 1796 | op_mini: 0, 1797 | op_mob: 12.1, 1798 | opera: 12.1, 1799 | safari: 5.1, 1800 | samsung: 0, 1801 | }, 1802 | resize: { 1803 | and_chr: 0, 1804 | and_ff: 0, 1805 | and_qq: 0, 1806 | and_uc: 0, 1807 | android: 4.4, 1808 | baidu: 0, 1809 | bb: 10, 1810 | chrome: 0, 1811 | edge: 16, 1812 | firefox: 3.6, 1813 | ie: 11, 1814 | ie_mob: 11, 1815 | ios_saf: 11, 1816 | op_mini: 0, 1817 | op_mob: 12.1, 1818 | opera: 12, 1819 | safari: 3.2, 1820 | samsung: 4, 1821 | }, 1822 | hyphens: { 1823 | and_chr: 0, 1824 | and_ff: 0, 1825 | and_qq: 1.2, 1826 | and_uc: 0, 1827 | android: 4.4, 1828 | baidu: 0, 1829 | bb: 10, 1830 | chrome: 54, 1831 | edge: 0, 1832 | firefox: 5, 1833 | ie: 9, 1834 | ie_mob: 11, 1835 | ios_saf: 4, 1836 | op_mini: 0, 1837 | op_mob: 37, 1838 | opera: 41, 1839 | safari: 5, 1840 | samsung: 4, 1841 | }, 1842 | flowInto: { 1843 | and_chr: 59, 1844 | and_ff: 55, 1845 | and_qq: 1.2, 1846 | and_uc: 11.4, 1847 | android: 56, 1848 | baidu: 7.12, 1849 | bb: 10, 1850 | chrome: 63, 1851 | edge: 0, 1852 | firefox: 58, 1853 | ie: 9, 1854 | ie_mob: 0, 1855 | ios_saf: 6, 1856 | op_mini: 0, 1857 | op_mob: 37, 1858 | opera: 49, 1859 | safari: 6, 1860 | samsung: 5, 1861 | }, 1862 | flowFrom: { 1863 | and_chr: 59, 1864 | and_ff: 55, 1865 | and_qq: 1.2, 1866 | and_uc: 11.4, 1867 | android: 56, 1868 | baidu: 7.12, 1869 | bb: 10, 1870 | chrome: 63, 1871 | edge: 0, 1872 | firefox: 58, 1873 | ie: 9, 1874 | ie_mob: 0, 1875 | ios_saf: 6, 1876 | op_mini: 0, 1877 | op_mob: 37, 1878 | opera: 49, 1879 | safari: 6, 1880 | samsung: 5, 1881 | }, 1882 | breakBefore: { 1883 | and_chr: 0, 1884 | and_ff: 0, 1885 | and_qq: 0, 1886 | and_uc: 0, 1887 | android: 0, 1888 | baidu: 0, 1889 | bb: 0, 1890 | chrome: 0, 1891 | edge: 0, 1892 | firefox: 0, 1893 | ie: 9, 1894 | ie_mob: 0, 1895 | ios_saf: 0, 1896 | op_mini: 0, 1897 | op_mob: 11, 1898 | opera: 11, 1899 | safari: 0, 1900 | samsung: 0, 1901 | }, 1902 | breakAfter: { 1903 | and_chr: 0, 1904 | and_ff: 0, 1905 | and_qq: 0, 1906 | and_uc: 0, 1907 | android: 0, 1908 | baidu: 0, 1909 | bb: 0, 1910 | chrome: 0, 1911 | edge: 0, 1912 | firefox: 0, 1913 | ie: 9, 1914 | ie_mob: 0, 1915 | ios_saf: 0, 1916 | op_mini: 0, 1917 | op_mob: 11, 1918 | opera: 11, 1919 | safari: 0, 1920 | samsung: 0, 1921 | }, 1922 | breakInside: { 1923 | and_chr: 0, 1924 | and_ff: 0, 1925 | and_qq: 0, 1926 | and_uc: 0, 1927 | android: 0, 1928 | baidu: 0, 1929 | bb: 0, 1930 | chrome: 0, 1931 | edge: 0, 1932 | firefox: 0, 1933 | ie: 9, 1934 | ie_mob: 0, 1935 | ios_saf: 0, 1936 | op_mini: 0, 1937 | op_mob: 11, 1938 | opera: 11, 1939 | safari: 0, 1940 | samsung: 0, 1941 | }, 1942 | regionFragment: { 1943 | and_chr: 59, 1944 | and_ff: 55, 1945 | and_qq: 1.2, 1946 | and_uc: 11.4, 1947 | android: 56, 1948 | baidu: 7.12, 1949 | bb: 10, 1950 | chrome: 63, 1951 | edge: 0, 1952 | firefox: 58, 1953 | ie: 9, 1954 | ie_mob: 0, 1955 | ios_saf: 6, 1956 | op_mini: 0, 1957 | op_mob: 37, 1958 | opera: 49, 1959 | safari: 6, 1960 | samsung: 5, 1961 | }, 1962 | gridTemplateColumns: { 1963 | and_chr: 0, 1964 | and_ff: 0, 1965 | and_qq: 0, 1966 | and_uc: 11.4, 1967 | android: 4.1, 1968 | baidu: 7.12, 1969 | bb: 10, 1970 | chrome: 24, 1971 | edge: 0, 1972 | firefox: 18, 1973 | ie: 8, 1974 | ie_mob: 0, 1975 | ios_saf: 5, 1976 | op_mini: 0, 1977 | op_mob: 12.1, 1978 | opera: 27, 1979 | safari: 5.1, 1980 | samsung: 5, 1981 | }, 1982 | gridTemplateRows: { 1983 | and_chr: 0, 1984 | and_ff: 0, 1985 | and_qq: 0, 1986 | and_uc: 11.4, 1987 | android: 4.1, 1988 | baidu: 7.12, 1989 | bb: 10, 1990 | chrome: 24, 1991 | edge: 0, 1992 | firefox: 18, 1993 | ie: 8, 1994 | ie_mob: 0, 1995 | ios_saf: 5, 1996 | op_mini: 0, 1997 | op_mob: 12.1, 1998 | opera: 27, 1999 | safari: 5.1, 2000 | samsung: 5, 2001 | }, 2002 | gridTemplateAreas: { 2003 | and_chr: 0, 2004 | and_ff: 0, 2005 | and_qq: 0, 2006 | and_uc: 11.4, 2007 | android: 4.1, 2008 | baidu: 7.12, 2009 | bb: 10, 2010 | chrome: 24, 2011 | edge: 0, 2012 | firefox: 18, 2013 | ie: 8, 2014 | ie_mob: 0, 2015 | ios_saf: 5, 2016 | op_mini: 0, 2017 | op_mob: 12.1, 2018 | opera: 27, 2019 | safari: 5.1, 2020 | samsung: 5, 2021 | }, 2022 | gridTemplate: { 2023 | and_chr: 0, 2024 | and_ff: 0, 2025 | and_qq: 0, 2026 | and_uc: 11.4, 2027 | android: 4.1, 2028 | baidu: 7.12, 2029 | bb: 10, 2030 | chrome: 24, 2031 | edge: 0, 2032 | firefox: 18, 2033 | ie: 8, 2034 | ie_mob: 0, 2035 | ios_saf: 5, 2036 | op_mini: 0, 2037 | op_mob: 12.1, 2038 | opera: 27, 2039 | safari: 5.1, 2040 | samsung: 5, 2041 | }, 2042 | gridAutoColumns: { 2043 | and_chr: 0, 2044 | and_ff: 0, 2045 | and_qq: 0, 2046 | and_uc: 11.4, 2047 | android: 4.1, 2048 | baidu: 7.12, 2049 | bb: 10, 2050 | chrome: 24, 2051 | edge: 0, 2052 | firefox: 18, 2053 | ie: 8, 2054 | ie_mob: 0, 2055 | ios_saf: 5, 2056 | op_mini: 0, 2057 | op_mob: 12.1, 2058 | opera: 27, 2059 | safari: 5.1, 2060 | samsung: 5, 2061 | }, 2062 | gridAutoRows: { 2063 | and_chr: 0, 2064 | and_ff: 0, 2065 | and_qq: 0, 2066 | and_uc: 11.4, 2067 | android: 4.1, 2068 | baidu: 7.12, 2069 | bb: 10, 2070 | chrome: 24, 2071 | edge: 0, 2072 | firefox: 18, 2073 | ie: 8, 2074 | ie_mob: 0, 2075 | ios_saf: 5, 2076 | op_mini: 0, 2077 | op_mob: 12.1, 2078 | opera: 27, 2079 | safari: 5.1, 2080 | samsung: 5, 2081 | }, 2082 | gridAutoFlow: { 2083 | and_chr: 0, 2084 | and_ff: 0, 2085 | and_qq: 0, 2086 | and_uc: 11.4, 2087 | android: 4.1, 2088 | baidu: 7.12, 2089 | bb: 10, 2090 | chrome: 24, 2091 | edge: 0, 2092 | firefox: 18, 2093 | ie: 8, 2094 | ie_mob: 0, 2095 | ios_saf: 5, 2096 | op_mini: 0, 2097 | op_mob: 12.1, 2098 | opera: 27, 2099 | safari: 5.1, 2100 | samsung: 5, 2101 | }, 2102 | grid: { 2103 | and_chr: 0, 2104 | and_ff: 0, 2105 | and_qq: 0, 2106 | and_uc: 11.4, 2107 | android: 4.1, 2108 | baidu: 7.12, 2109 | bb: 10, 2110 | chrome: 24, 2111 | edge: 0, 2112 | firefox: 18, 2113 | ie: 8, 2114 | ie_mob: 0, 2115 | ios_saf: 5, 2116 | op_mini: 0, 2117 | op_mob: 12.1, 2118 | opera: 27, 2119 | safari: 5.1, 2120 | samsung: 5, 2121 | }, 2122 | gridRowStart: { 2123 | and_chr: 0, 2124 | and_ff: 0, 2125 | and_qq: 0, 2126 | and_uc: 11.4, 2127 | android: 4.1, 2128 | baidu: 7.12, 2129 | bb: 10, 2130 | chrome: 24, 2131 | edge: 0, 2132 | firefox: 18, 2133 | ie: 8, 2134 | ie_mob: 0, 2135 | ios_saf: 5, 2136 | op_mini: 0, 2137 | op_mob: 12.1, 2138 | opera: 27, 2139 | safari: 5.1, 2140 | samsung: 5, 2141 | }, 2142 | gridColumnStart: { 2143 | and_chr: 0, 2144 | and_ff: 0, 2145 | and_qq: 0, 2146 | and_uc: 11.4, 2147 | android: 4.1, 2148 | baidu: 7.12, 2149 | bb: 10, 2150 | chrome: 24, 2151 | edge: 0, 2152 | firefox: 18, 2153 | ie: 8, 2154 | ie_mob: 0, 2155 | ios_saf: 5, 2156 | op_mini: 0, 2157 | op_mob: 12.1, 2158 | opera: 27, 2159 | safari: 5.1, 2160 | samsung: 5, 2161 | }, 2162 | gridRowEnd: { 2163 | and_chr: 0, 2164 | and_ff: 0, 2165 | and_qq: 0, 2166 | and_uc: 11.4, 2167 | android: 4.1, 2168 | baidu: 7.12, 2169 | bb: 10, 2170 | chrome: 24, 2171 | edge: 0, 2172 | firefox: 18, 2173 | ie: 8, 2174 | ie_mob: 0, 2175 | ios_saf: 5, 2176 | op_mini: 0, 2177 | op_mob: 12.1, 2178 | opera: 27, 2179 | safari: 5.1, 2180 | samsung: 5, 2181 | }, 2182 | gridRow: { 2183 | and_chr: 0, 2184 | and_ff: 0, 2185 | and_qq: 0, 2186 | and_uc: 11.4, 2187 | android: 4.1, 2188 | baidu: 7.12, 2189 | bb: 10, 2190 | chrome: 24, 2191 | edge: 0, 2192 | firefox: 18, 2193 | ie: 8, 2194 | ie_mob: 0, 2195 | ios_saf: 5, 2196 | op_mini: 0, 2197 | op_mob: 12.1, 2198 | opera: 27, 2199 | safari: 5.1, 2200 | samsung: 5, 2201 | }, 2202 | gridColumn: { 2203 | and_chr: 0, 2204 | and_ff: 0, 2205 | and_qq: 0, 2206 | and_uc: 11.4, 2207 | android: 4.1, 2208 | baidu: 7.12, 2209 | bb: 10, 2210 | chrome: 24, 2211 | edge: 0, 2212 | firefox: 18, 2213 | ie: 8, 2214 | ie_mob: 0, 2215 | ios_saf: 5, 2216 | op_mini: 0, 2217 | op_mob: 12.1, 2218 | opera: 27, 2219 | safari: 5.1, 2220 | samsung: 5, 2221 | }, 2222 | gridColumnEnd: { 2223 | and_chr: 0, 2224 | and_ff: 0, 2225 | and_qq: 0, 2226 | and_uc: 11.4, 2227 | android: 4.1, 2228 | baidu: 7.12, 2229 | bb: 10, 2230 | chrome: 24, 2231 | edge: 0, 2232 | firefox: 18, 2233 | ie: 8, 2234 | ie_mob: 0, 2235 | ios_saf: 5, 2236 | op_mini: 0, 2237 | op_mob: 12.1, 2238 | opera: 27, 2239 | safari: 5.1, 2240 | samsung: 5, 2241 | }, 2242 | gridColumnGap: { 2243 | and_chr: 0, 2244 | and_ff: 0, 2245 | and_qq: 0, 2246 | and_uc: 11.4, 2247 | android: 4.1, 2248 | baidu: 7.12, 2249 | bb: 10, 2250 | chrome: 24, 2251 | edge: 0, 2252 | firefox: 18, 2253 | ie: 8, 2254 | ie_mob: 0, 2255 | ios_saf: 5, 2256 | op_mini: 0, 2257 | op_mob: 12.1, 2258 | opera: 27, 2259 | safari: 5.1, 2260 | samsung: 5, 2261 | }, 2262 | gridRowGap: { 2263 | and_chr: 0, 2264 | and_ff: 0, 2265 | and_qq: 0, 2266 | and_uc: 11.4, 2267 | android: 4.1, 2268 | baidu: 7.12, 2269 | bb: 10, 2270 | chrome: 24, 2271 | edge: 0, 2272 | firefox: 18, 2273 | ie: 8, 2274 | ie_mob: 0, 2275 | ios_saf: 5, 2276 | op_mini: 0, 2277 | op_mob: 12.1, 2278 | opera: 27, 2279 | safari: 5.1, 2280 | samsung: 5, 2281 | }, 2282 | gridArea: { 2283 | and_chr: 0, 2284 | and_ff: 0, 2285 | and_qq: 0, 2286 | and_uc: 11.4, 2287 | android: 4.1, 2288 | baidu: 7.12, 2289 | bb: 10, 2290 | chrome: 24, 2291 | edge: 0, 2292 | firefox: 18, 2293 | ie: 8, 2294 | ie_mob: 0, 2295 | ios_saf: 5, 2296 | op_mini: 0, 2297 | op_mob: 12.1, 2298 | opera: 27, 2299 | safari: 5.1, 2300 | samsung: 5, 2301 | }, 2302 | gridGap: { 2303 | and_chr: 0, 2304 | and_ff: 0, 2305 | and_qq: 0, 2306 | and_uc: 11.4, 2307 | android: 4.1, 2308 | baidu: 7.12, 2309 | bb: 10, 2310 | chrome: 24, 2311 | edge: 0, 2312 | firefox: 18, 2313 | ie: 8, 2314 | ie_mob: 0, 2315 | ios_saf: 5, 2316 | op_mini: 0, 2317 | op_mob: 12.1, 2318 | opera: 27, 2319 | safari: 5.1, 2320 | samsung: 5, 2321 | }, 2322 | objectFit: { 2323 | and_chr: 0, 2324 | and_ff: 0, 2325 | and_qq: 0, 2326 | and_uc: 0, 2327 | android: 4.4, 2328 | baidu: 0, 2329 | bb: 10, 2330 | chrome: 30, 2331 | edge: 15, 2332 | firefox: 35, 2333 | ie: 11, 2334 | ie_mob: 11, 2335 | ios_saf: 7, 2336 | op_mini: 0, 2337 | op_mob: 10, 2338 | opera: 18, 2339 | safari: 7, 2340 | samsung: 0, 2341 | }, 2342 | objectPosition: { 2343 | and_chr: 0, 2344 | and_ff: 0, 2345 | and_qq: 0, 2346 | and_uc: 0, 2347 | android: 4.4, 2348 | baidu: 0, 2349 | bb: 10, 2350 | chrome: 30, 2351 | edge: 15, 2352 | firefox: 35, 2353 | ie: 11, 2354 | ie_mob: 11, 2355 | ios_saf: 7, 2356 | op_mini: 0, 2357 | op_mob: 10, 2358 | opera: 18, 2359 | safari: 7, 2360 | samsung: 0, 2361 | }, 2362 | textOverflow: { 2363 | and_chr: 0, 2364 | and_ff: 0, 2365 | and_qq: 0, 2366 | and_uc: 0, 2367 | android: 0, 2368 | baidu: 0, 2369 | bb: 0, 2370 | chrome: 0, 2371 | edge: 0, 2372 | firefox: 0, 2373 | ie: 5.5, 2374 | ie_mob: 0, 2375 | ios_saf: 0, 2376 | op_mini: 0, 2377 | op_mob: 0, 2378 | opera: 0, 2379 | safari: 0, 2380 | samsung: 0, 2381 | }, 2382 | backgroundClip: { 2383 | and_chr: 0, 2384 | and_ff: 0, 2385 | and_qq: 0, 2386 | and_uc: 0, 2387 | android: 0, 2388 | baidu: 0, 2389 | bb: 0, 2390 | chrome: 0, 2391 | edge: 0, 2392 | firefox: 3.5, 2393 | ie: 8, 2394 | ie_mob: 0, 2395 | ios_saf: 0, 2396 | op_mini: 0, 2397 | op_mob: 0, 2398 | opera: 9.5, 2399 | safari: 0, 2400 | samsung: 0, 2401 | }, 2402 | backgroundOrigin: { 2403 | and_chr: 0, 2404 | and_ff: 0, 2405 | and_qq: 0, 2406 | and_uc: 0, 2407 | android: 0, 2408 | baidu: 0, 2409 | bb: 0, 2410 | chrome: 0, 2411 | edge: 0, 2412 | firefox: 3.5, 2413 | ie: 8, 2414 | ie_mob: 0, 2415 | ios_saf: 0, 2416 | op_mini: 0, 2417 | op_mob: 0, 2418 | opera: 9.5, 2419 | safari: 0, 2420 | samsung: 0, 2421 | }, 2422 | backgroundSize: { 2423 | and_chr: 0, 2424 | and_ff: 0, 2425 | and_qq: 0, 2426 | and_uc: 0, 2427 | android: 0, 2428 | baidu: 0, 2429 | bb: 0, 2430 | chrome: 0, 2431 | edge: 0, 2432 | firefox: 3.5, 2433 | ie: 8, 2434 | ie_mob: 0, 2435 | ios_saf: 0, 2436 | op_mini: 0, 2437 | op_mob: 0, 2438 | opera: 9.5, 2439 | safari: 0, 2440 | samsung: 0, 2441 | }, 2442 | fontFeatureSettings: { 2443 | and_chr: 0, 2444 | and_ff: 0, 2445 | and_qq: 0, 2446 | and_uc: 0, 2447 | android: 4.2, 2448 | baidu: 0, 2449 | bb: 7, 2450 | chrome: 15, 2451 | edge: 0, 2452 | firefox: 3.6, 2453 | ie: 9, 2454 | ie_mob: 11, 2455 | ios_saf: 9, 2456 | op_mini: 0, 2457 | op_mob: 12.1, 2458 | opera: 12.1, 2459 | safari: 9, 2460 | samsung: 0, 2461 | }, 2462 | boxShadow: { 2463 | and_chr: 0, 2464 | and_ff: 0, 2465 | and_qq: 0, 2466 | and_uc: 0, 2467 | android: 0, 2468 | baidu: 0, 2469 | bb: 0, 2470 | chrome: 0, 2471 | edge: 0, 2472 | firefox: 3, 2473 | ie: 8, 2474 | ie_mob: 0, 2475 | ios_saf: 0, 2476 | op_mini: 0, 2477 | op_mob: 10, 2478 | opera: 10, 2479 | safari: 0, 2480 | samsung: 0, 2481 | }, 2482 | columnCount: { 2483 | and_chr: 0, 2484 | and_ff: 0, 2485 | and_qq: 0, 2486 | and_uc: 0, 2487 | android: 0, 2488 | baidu: 0, 2489 | bb: 0, 2490 | chrome: 0, 2491 | edge: 0, 2492 | firefox: 0, 2493 | ie: 9, 2494 | ie_mob: 0, 2495 | ios_saf: 0, 2496 | op_mini: 0, 2497 | op_mob: 11, 2498 | opera: 11, 2499 | safari: 0, 2500 | samsung: 0, 2501 | }, 2502 | columnFill: { 2503 | and_chr: 0, 2504 | and_ff: 0, 2505 | and_qq: 0, 2506 | and_uc: 0, 2507 | android: 0, 2508 | baidu: 0, 2509 | bb: 0, 2510 | chrome: 0, 2511 | edge: 0, 2512 | firefox: 0, 2513 | ie: 9, 2514 | ie_mob: 0, 2515 | ios_saf: 0, 2516 | op_mini: 0, 2517 | op_mob: 11, 2518 | opera: 11, 2519 | safari: 0, 2520 | samsung: 0, 2521 | }, 2522 | columnGap: { 2523 | and_chr: 0, 2524 | and_ff: 0, 2525 | and_qq: 0, 2526 | and_uc: 0, 2527 | android: 0, 2528 | baidu: 0, 2529 | bb: 0, 2530 | chrome: 0, 2531 | edge: 0, 2532 | firefox: 0, 2533 | ie: 9, 2534 | ie_mob: 0, 2535 | ios_saf: 0, 2536 | op_mini: 0, 2537 | op_mob: 11, 2538 | opera: 11, 2539 | safari: 0, 2540 | samsung: 0, 2541 | }, 2542 | columnRule: { 2543 | and_chr: 0, 2544 | and_ff: 0, 2545 | and_qq: 0, 2546 | and_uc: 0, 2547 | android: 0, 2548 | baidu: 0, 2549 | bb: 0, 2550 | chrome: 0, 2551 | edge: 0, 2552 | firefox: 0, 2553 | ie: 9, 2554 | ie_mob: 0, 2555 | ios_saf: 0, 2556 | op_mini: 0, 2557 | op_mob: 11, 2558 | opera: 11, 2559 | safari: 0, 2560 | samsung: 0, 2561 | }, 2562 | columnRuleColor: { 2563 | and_chr: 0, 2564 | and_ff: 0, 2565 | and_qq: 0, 2566 | and_uc: 0, 2567 | android: 0, 2568 | baidu: 0, 2569 | bb: 0, 2570 | chrome: 0, 2571 | edge: 0, 2572 | firefox: 0, 2573 | ie: 9, 2574 | ie_mob: 0, 2575 | ios_saf: 0, 2576 | op_mini: 0, 2577 | op_mob: 11, 2578 | opera: 11, 2579 | safari: 0, 2580 | samsung: 0, 2581 | }, 2582 | columnRuleStyle: { 2583 | and_chr: 0, 2584 | and_ff: 0, 2585 | and_qq: 0, 2586 | and_uc: 0, 2587 | android: 0, 2588 | baidu: 0, 2589 | bb: 0, 2590 | chrome: 0, 2591 | edge: 0, 2592 | firefox: 0, 2593 | ie: 9, 2594 | ie_mob: 0, 2595 | ios_saf: 0, 2596 | op_mini: 0, 2597 | op_mob: 11, 2598 | opera: 11, 2599 | safari: 0, 2600 | samsung: 0, 2601 | }, 2602 | columnRuleWidth: { 2603 | and_chr: 0, 2604 | and_ff: 0, 2605 | and_qq: 0, 2606 | and_uc: 0, 2607 | android: 0, 2608 | baidu: 0, 2609 | bb: 0, 2610 | chrome: 0, 2611 | edge: 0, 2612 | firefox: 0, 2613 | ie: 9, 2614 | ie_mob: 0, 2615 | ios_saf: 0, 2616 | op_mini: 0, 2617 | op_mob: 11, 2618 | opera: 11, 2619 | safari: 0, 2620 | samsung: 0, 2621 | }, 2622 | columns: { 2623 | and_chr: 0, 2624 | and_ff: 0, 2625 | and_qq: 0, 2626 | and_uc: 0, 2627 | android: 0, 2628 | baidu: 0, 2629 | bb: 0, 2630 | chrome: 0, 2631 | edge: 0, 2632 | firefox: 0, 2633 | ie: 9, 2634 | ie_mob: 0, 2635 | ios_saf: 0, 2636 | op_mini: 0, 2637 | op_mob: 11, 2638 | opera: 11, 2639 | safari: 0, 2640 | samsung: 0, 2641 | }, 2642 | columnSpan: { 2643 | and_chr: 0, 2644 | and_ff: 0, 2645 | and_qq: 0, 2646 | and_uc: 0, 2647 | android: 0, 2648 | baidu: 0, 2649 | bb: 0, 2650 | chrome: 0, 2651 | edge: 0, 2652 | firefox: 0, 2653 | ie: 9, 2654 | ie_mob: 0, 2655 | ios_saf: 0, 2656 | op_mini: 0, 2657 | op_mob: 11, 2658 | opera: 11, 2659 | safari: 0, 2660 | samsung: 0, 2661 | }, 2662 | columnWidth: { 2663 | and_chr: 0, 2664 | and_ff: 0, 2665 | and_qq: 0, 2666 | and_uc: 0, 2667 | android: 0, 2668 | baidu: 0, 2669 | bb: 0, 2670 | chrome: 0, 2671 | edge: 0, 2672 | firefox: 0, 2673 | ie: 9, 2674 | ie_mob: 0, 2675 | ios_saf: 0, 2676 | op_mini: 0, 2677 | op_mob: 11, 2678 | opera: 11, 2679 | safari: 0, 2680 | samsung: 0, 2681 | }, 2682 | writingMode: { 2683 | and_chr: 0, 2684 | and_ff: 0, 2685 | and_qq: 0, 2686 | and_uc: 0, 2687 | android: 2.3, 2688 | baidu: 0, 2689 | bb: 0, 2690 | chrome: 6, 2691 | edge: 0, 2692 | firefox: 40, 2693 | ie: 0, 2694 | ie_mob: 0, 2695 | ios_saf: 0, 2696 | op_mini: 0, 2697 | op_mob: 12.1, 2698 | opera: 12.1, 2699 | safari: 4, 2700 | samsung: 0, 2701 | }, 2702 | } 2703 | module.exports = partialSupport 2704 | --------------------------------------------------------------------------------