install gulp
This commit is contained in:
+232
@@ -0,0 +1,232 @@
|
||||
# Changelog
|
||||
|
||||
## 3.1.7 - 2015-06-09
|
||||
|
||||
- Do not remove units from values starting from zeroes, like `0.5em` (#394)
|
||||
|
||||
## 3.1.6 - 2015-06-09
|
||||
- Hotfix for issue when `unitless-zero` crashed on percentages in Less (#389)
|
||||
|
||||
## 3.1.5 - 2015-05-27
|
||||
- Fixed dependencies
|
||||
|
||||
## 3.1.4 - 2015-05-24
|
||||
- Fixed `space-after-opening-brace` option for empty media queries (#387)
|
||||
|
||||
## 3.1.3 - 2015-05-20
|
||||
- Do not add extra space before combinators which go first in selectors (#381)
|
||||
|
||||
## 3.1.2 - 2015-05-20
|
||||
- Fixed processing of hashes (#379)
|
||||
|
||||
## 3.1.1 - 2015-05-20
|
||||
- Fixed `space-between-declarations` vs. media queries (#378)
|
||||
|
||||
## 3.1.0 - 2015-05-19
|
||||
**Thanks to
|
||||
[@1000ch](https://github.com/1000ch),
|
||||
[@alexeykuzmin](https://github.com/alexeykuzmin),
|
||||
[@jonrohan](https://github.com/jonrohan)**
|
||||
- Used new Gonzales PE API
|
||||
- Fixed nested properties (#319)
|
||||
- Added support for symlinked configs
|
||||
- Added support for configs with any extension
|
||||
|
||||
## 3.0.4 - 2014-11-15
|
||||
**Thanks to
|
||||
[@gonzalocasas](https://github.com/gonzalocasas),
|
||||
[@tomByrer](https://github.com/tomByrer)**
|
||||
- Improved docs
|
||||
- Fixed Gonzales PE version
|
||||
|
||||
## 3.0.3 - 2014-09-29
|
||||
**Thanks to
|
||||
[@kizu](https://github.com/kizu),
|
||||
[@necolas](https://github.com/necolas)**
|
||||
- Improved README
|
||||
- Added non-essential files to npmignore
|
||||
- Renamed `CONTRIBUTE.md` to `CONTRIBUTING.md`
|
||||
- Fixed unwanted removal of empty lines between nested rulesets (#317)
|
||||
|
||||
## 3.0.2 - 2014-09-21
|
||||
- Fixed Gonzales PE version
|
||||
|
||||
## 3.0.1 - 2014-08-18
|
||||
**Thanks to
|
||||
[@mishanga](https://github.com/mishanga),
|
||||
[@cust0dian](https://github.com/cust0dian)**
|
||||
- Added `khtml` to list of vendor prefixes
|
||||
- Updated docs
|
||||
|
||||
## 3.0.0 - 2014-07-19
|
||||
**Thanks to
|
||||
[@cvrebert](https://github.com/cvrebert),
|
||||
[@filtercake](https://github.com/filtercake),
|
||||
[@lefoy](https://github.com/lefoy),
|
||||
[@L0stSoul](https://github.com/L0stSoul),
|
||||
[@kizu](https://github.com/kizu),
|
||||
[@schneyra](https://github.com/schneyra),
|
||||
[@thejameskyle](https://github.com/thejameskyle),
|
||||
[@vecmezoni](https://github.com/vecmezoni)**
|
||||
|
||||
New:
|
||||
|
||||
- Sass support
|
||||
- Leftovers (#160)
|
||||
- Use [CSScomb Core](https://github.com/csscomb/core)
|
||||
- Plugins API (with `.use()` method)
|
||||
- `sort-order-fallback` (alphabetical sort order)
|
||||
- `space-before-colon`
|
||||
- `space-after-colon`
|
||||
- `space-before-combinator`
|
||||
- `space-after-combinator`
|
||||
- `space-before-selector-delimiter`
|
||||
- `space-after-selector-delimiter`
|
||||
- `space-before-opening-brace`
|
||||
- `space-after-opening-brace`
|
||||
- `space-before-closing-brace`
|
||||
- `space-after-declaration`
|
||||
- `tab-size`
|
||||
|
||||
Removed:
|
||||
|
||||
- `colon-space`
|
||||
- `combinator-space`
|
||||
- `rule-indent`
|
||||
- `stick-brace`
|
||||
|
||||
Changed:
|
||||
|
||||
- Divided `process` and `detect` methods
|
||||
- Made `getConfig` and `detect` static methods
|
||||
- Removed "best guess" logic from options
|
||||
- Excluded `bower_components/**` from processing
|
||||
- Updated badges at README page
|
||||
- Update Gonzales PE to v3.0
|
||||
- Various fixes
|
||||
|
||||
## 2.0.5 - 2014-06-09
|
||||
- Updated dependencies (#229)
|
||||
|
||||
## 2.0.4 - 2014-01-16
|
||||
- Fixed relative path to config (#164)
|
||||
|
||||
## 2.0.3 - 2014-01-16
|
||||
- Documentation moved to `doc` directory
|
||||
- Fixed incorrect left indent (#153)
|
||||
|
||||
## 2.0.2 - 2014-01-09
|
||||
- Added test coverage (#138)
|
||||
- Added test helpers (#147)
|
||||
- Fixed config file recursive searching (#151)
|
||||
- Fixed `block-indent` detecting (#148)
|
||||
- Fixed `quote` value setter (#149)
|
||||
- Fixed detection integral tests (#150)
|
||||
|
||||
## 2.0.1 - 2013-12-23
|
||||
- Fix for `remove-empty-rulesets` option (#133)
|
||||
|
||||
## 2.0.0 - 2013-12-18
|
||||
**Great thanks for @tonyganch and @kizu!**
|
||||
- Use Gonzales PE to parse *.scss and *.less files
|
||||
- Support sorting properties in *.scss and *.less files
|
||||
- Codestyle detection
|
||||
- Option: always-semicolon (scss + less)
|
||||
- Option: quotes
|
||||
- Two more config examples now: `csscomb` and `zen`
|
||||
- Lots of refactoring and fixes
|
||||
- Lots of tests added
|
||||
- Node v0.8 no longer supported
|
||||
|
||||
## 1.0.0 - 2013-11-06
|
||||
- Option: vendor-prefix-align
|
||||
- Dependencies updated
|
||||
- Fixed options order in readme
|
||||
|
||||
## 0.1.0 - 2013-10-11
|
||||
- CLI: lint mode
|
||||
|
||||
## 0.0.15 - 2013-10-03
|
||||
- Option: remove-empty-rulesets (#67)
|
||||
- Option colon-space expanded
|
||||
- Some refactoring and fixes
|
||||
|
||||
## 0.0.14 - 2013-09-12
|
||||
- Option: eof-newline (#55)
|
||||
- Verbose option (#62)
|
||||
- Some refactoring
|
||||
|
||||
## 0.0.13 - 2013-09-12
|
||||
- Fixed failing on empty files (#66)
|
||||
|
||||
## 0.0.12 - 2013-09-11
|
||||
- Option: combinator-space
|
||||
- Readme update
|
||||
- Some CLI fixes
|
||||
- Contributor added: @anton-rudeshko
|
||||
|
||||
## 0.0.11 - 2013-09-10
|
||||
- Option: element-case
|
||||
- Fixed block-indent bug with space after at-rule opening brace
|
||||
- Fixed JSDoc
|
||||
- Fixed colon-space description
|
||||
|
||||
## 0.0.10 - 2013-09-06
|
||||
- Option: color-case
|
||||
- Option: color-shorthand
|
||||
- Option: leading-zero
|
||||
- Option: unitless-zero
|
||||
- Option update: colon-space
|
||||
- Contributors added: @kizu and @ignovak
|
||||
- Readme updated
|
||||
- Licence added
|
||||
- Contributing info added
|
||||
- Changelog added
|
||||
|
||||
## 0.0.9 - 2013-08-28
|
||||
- Option: sort-order
|
||||
- Sort order config fix
|
||||
- JSCS version and config update
|
||||
- jshint config fix
|
||||
- Some codestyle fixes
|
||||
|
||||
## 0.0.8 - 2013-08-22
|
||||
- !!! Now using Gonzales instead of CSSP
|
||||
- Option: block-indent
|
||||
- Option: rule-indent
|
||||
- Added few links to README
|
||||
- Added some debug info
|
||||
- Fixed default sort order
|
||||
- Fixed path processing bug
|
||||
- Fixed stick-brace option
|
||||
|
||||
## 0.0.7 - 2013-08-09
|
||||
- jshint config fix
|
||||
- Codestyle fix for always-semicolon
|
||||
- Integral test fix
|
||||
- Removed old php code
|
||||
|
||||
## 0.0.6 - 2013-08-08
|
||||
- Option: always-semicolon
|
||||
|
||||
## 0.0.5 - 2013-08-08
|
||||
- Fix for value setting
|
||||
- Bugfix for stick-brace
|
||||
- Added integral test
|
||||
|
||||
## 0.0.4 - 2013-08-07
|
||||
- Some refactoring
|
||||
- Tests added
|
||||
|
||||
## 0.0.3 - 2013-08-05
|
||||
- Option: colon-space
|
||||
- Option: stick-brace
|
||||
- Moved to github/csscomb/csscomb.js
|
||||
|
||||
## 0.0.2 - 2013-08-04
|
||||
- Option: strip-spaces - fix
|
||||
|
||||
## 0.0.1 - 2013-08-03
|
||||
- Initial release
|
||||
- Option: strip spaces
|
||||
- Travis support
|
||||
+20
@@ -0,0 +1,20 @@
|
||||
The MIT License (MIT)
|
||||
Copyright © 2013 Mikhail Troshev, http://mishanga.pro
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the “Software”), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
+104
@@ -0,0 +1,104 @@
|
||||
# CSScomb [](http://csscomb.com/)
|
||||
[](http://travis-ci.org/csscomb/csscomb.js)
|
||||
[](http://badge.fury.io/js/csscomb)
|
||||
[](https://david-dm.org/csscomb/csscomb.js)
|
||||
[](https://david-dm.org/csscomb/csscomb.js#info=devDependencies)
|
||||
|
||||
CSScomb is a coding style formatter for CSS.
|
||||
You can easily write your own [configuration](doc/configuration.md) to make
|
||||
your style sheets beautiful and consistent.
|
||||
|
||||
The main feature is [sorting properties](doc/options.md#sort-order) in a specific order.
|
||||
It was inspired by [@miripiruni](https://github.com/miripiruni)'s
|
||||
[PHP-based tool](https://github.com/csscomb/csscomb) of the same name.
|
||||
This is the new JavaScript version, based on the powerful CSS parser
|
||||
[Gonzales PE](https://github.com/tonyganch/gonzales-pe).
|
||||
|
||||
## 1. Install
|
||||
|
||||
Global installation (for use as a command-line tool):
|
||||
|
||||
```bash
|
||||
npm install csscomb -g
|
||||
```
|
||||
|
||||
Local installation (for use as a command-line tool within current directory):
|
||||
|
||||
```bash
|
||||
npm install csscomb
|
||||
```
|
||||
|
||||
To install as a project dependency (the package will appear in your dependencies):
|
||||
|
||||
```bash
|
||||
npm install csscomb --save
|
||||
```
|
||||
|
||||
To install as a dev dependency (the package will appear in your devDependencies):
|
||||
|
||||
```bash
|
||||
npm install csscomb --save-dev
|
||||
```
|
||||
|
||||
## 2. [Configure](doc/configuration.md)
|
||||
|
||||
There are a number of ways to configure CSScomb:
|
||||
|
||||
- Use one of [predefined configs](config)
|
||||
- Put `.csscomb.json` file in the project root.
|
||||
- Set path to config's file
|
||||
- Use `*.css` file as a template
|
||||
|
||||
## 3. Use
|
||||
|
||||
### [Command Line](doc/usage-cli.md)
|
||||
|
||||
```bash
|
||||
csscomb assets/css
|
||||
```
|
||||
|
||||
### [Node.js module](doc/usage-node.md)
|
||||
|
||||
```js
|
||||
var Comb = require('csscomb');
|
||||
var comb = new Comb('zen');
|
||||
comb.processPath('assets/css');
|
||||
```
|
||||
|
||||
## 4. Contribute
|
||||
|
||||
Anyone and everyone is welcome to contribute.
|
||||
Please take a moment to review the [guidelines for contributing](CONTRIBUTING.md).
|
||||
|
||||
## Authors
|
||||
|
||||
[@mishanga](https://github.com/mishanga),
|
||||
[@tonyganch](https://github.com/tonyganch)
|
||||
|
||||
Thanks for assistance and contributions:
|
||||
|
||||
[@miripiruni](https://github.com/miripiruni),
|
||||
[@anton-rudeshko](https://github.com/anton-rudeshko),
|
||||
[@cvrebert](https://github.com/cvrebert),
|
||||
[@filtercake](https://github.com/filtercake),
|
||||
[@ignovak](https://github.com/ignovak),
|
||||
[@kizu](https://github.com/kizu),
|
||||
[@lefoy](https://github.com/lefoy),
|
||||
[@L0stSoul](https://github.com/L0stSoul),
|
||||
[@mishaberezin](https://github.com/mishaberezin),
|
||||
[@puzankov](https://github.com/puzankov),
|
||||
[@schneyra](https://github.com/schneyra),
|
||||
[@thejameskyle](https://github.com/thejameskyle),
|
||||
[@vecmezoni](https://github.com/vecmezoni)
|
||||
|
||||
## License
|
||||
|
||||
This software is released under the terms of the
|
||||
[MIT license](https://github.com/csscomb/csscomb.js/blob/master/LICENSE).
|
||||
|
||||
## Other projects
|
||||
* https://github.com/senchalabs/cssbeautify
|
||||
* https://github.com/css/gonzales
|
||||
* https://github.com/tonyganch/gonzales-pe
|
||||
* https://github.com/css/csso
|
||||
* https://github.com/nzakas/parser-lib
|
||||
+2
@@ -0,0 +1,2 @@
|
||||
#!/usr/bin/env node
|
||||
require('../lib/cli');
|
||||
+328
@@ -0,0 +1,328 @@
|
||||
{
|
||||
"exclude": [
|
||||
".git/**",
|
||||
"node_modules/**",
|
||||
"bower_components/**"
|
||||
],
|
||||
"always-semicolon": true,
|
||||
"block-indent": " ",
|
||||
"color-case": "lower",
|
||||
"color-shorthand": true,
|
||||
"element-case": "lower",
|
||||
"eof-newline": true,
|
||||
"leading-zero": false,
|
||||
"quotes": "single",
|
||||
"remove-empty-rulesets": true,
|
||||
"space-after-colon": " ",
|
||||
"space-after-combinator": " ",
|
||||
"space-after-opening-brace": "\n",
|
||||
"space-after-selector-delimiter": "\n",
|
||||
"space-before-closing-brace": "\n",
|
||||
"space-before-colon": "",
|
||||
"space-before-combinator": " ",
|
||||
"space-before-opening-brace": "\n",
|
||||
"space-before-selector-delimiter": "",
|
||||
"strip-spaces": true,
|
||||
"unitless-zero": true,
|
||||
"vendor-prefix-align": true,
|
||||
"sort-order": [
|
||||
[
|
||||
"font",
|
||||
"font-family",
|
||||
"font-size",
|
||||
"font-weight",
|
||||
"font-style",
|
||||
"font-variant",
|
||||
"font-size-adjust",
|
||||
"font-stretch",
|
||||
"font-effect",
|
||||
"font-emphasize",
|
||||
"font-emphasize-position",
|
||||
"font-emphasize-style",
|
||||
"font-smooth",
|
||||
"line-height"
|
||||
],
|
||||
[
|
||||
"position",
|
||||
"z-index",
|
||||
"top",
|
||||
"right",
|
||||
"bottom",
|
||||
"left"
|
||||
],
|
||||
[
|
||||
"display",
|
||||
"visibility",
|
||||
"float",
|
||||
"clear",
|
||||
"overflow",
|
||||
"overflow-x",
|
||||
"overflow-y",
|
||||
"-ms-overflow-x",
|
||||
"-ms-overflow-y",
|
||||
"clip",
|
||||
"zoom",
|
||||
"flex-direction",
|
||||
"flex-order",
|
||||
"flex-pack",
|
||||
"flex-align"
|
||||
],
|
||||
[
|
||||
"-webkit-box-sizing",
|
||||
"-moz-box-sizing",
|
||||
"box-sizing",
|
||||
"width",
|
||||
"min-width",
|
||||
"max-width",
|
||||
"height",
|
||||
"min-height",
|
||||
"max-height",
|
||||
"margin",
|
||||
"margin-top",
|
||||
"margin-right",
|
||||
"margin-bottom",
|
||||
"margin-left",
|
||||
"padding",
|
||||
"padding-top",
|
||||
"padding-right",
|
||||
"padding-bottom",
|
||||
"padding-left"
|
||||
],
|
||||
[
|
||||
"table-layout",
|
||||
"empty-cells",
|
||||
"caption-side",
|
||||
"border-spacing",
|
||||
"border-collapse",
|
||||
"list-style",
|
||||
"list-style-position",
|
||||
"list-style-type",
|
||||
"list-style-image"
|
||||
],
|
||||
[
|
||||
"content",
|
||||
"quotes",
|
||||
"counter-reset",
|
||||
"counter-increment",
|
||||
"resize",
|
||||
"cursor",
|
||||
"-webkit-user-select",
|
||||
"-moz-user-select",
|
||||
"-ms-user-select",
|
||||
"user-select",
|
||||
"nav-index",
|
||||
"nav-up",
|
||||
"nav-right",
|
||||
"nav-down",
|
||||
"nav-left",
|
||||
"-webkit-transition",
|
||||
"-moz-transition",
|
||||
"-ms-transition",
|
||||
"-o-transition",
|
||||
"transition",
|
||||
"-webkit-transition-delay",
|
||||
"-moz-transition-delay",
|
||||
"-ms-transition-delay",
|
||||
"-o-transition-delay",
|
||||
"transition-delay",
|
||||
"-webkit-transition-timing-function",
|
||||
"-moz-transition-timing-function",
|
||||
"-ms-transition-timing-function",
|
||||
"-o-transition-timing-function",
|
||||
"transition-timing-function",
|
||||
"-webkit-transition-duration",
|
||||
"-moz-transition-duration",
|
||||
"-ms-transition-duration",
|
||||
"-o-transition-duration",
|
||||
"transition-duration",
|
||||
"-webkit-transition-property",
|
||||
"-moz-transition-property",
|
||||
"-ms-transition-property",
|
||||
"-o-transition-property",
|
||||
"transition-property",
|
||||
"-webkit-transform",
|
||||
"-moz-transform",
|
||||
"-ms-transform",
|
||||
"-o-transform",
|
||||
"transform",
|
||||
"-webkit-transform-origin",
|
||||
"-moz-transform-origin",
|
||||
"-ms-transform-origin",
|
||||
"-o-transform-origin",
|
||||
"transform-origin",
|
||||
"-webkit-animation",
|
||||
"-moz-animation",
|
||||
"-ms-animation",
|
||||
"-o-animation",
|
||||
"animation",
|
||||
"-webkit-animation-name",
|
||||
"-moz-animation-name",
|
||||
"-ms-animation-name",
|
||||
"-o-animation-name",
|
||||
"animation-name",
|
||||
"-webkit-animation-duration",
|
||||
"-moz-animation-duration",
|
||||
"-ms-animation-duration",
|
||||
"-o-animation-duration",
|
||||
"animation-duration",
|
||||
"-webkit-animation-play-state",
|
||||
"-moz-animation-play-state",
|
||||
"-ms-animation-play-state",
|
||||
"-o-animation-play-state",
|
||||
"animation-play-state",
|
||||
"-webkit-animation-timing-function",
|
||||
"-moz-animation-timing-function",
|
||||
"-ms-animation-timing-function",
|
||||
"-o-animation-timing-function",
|
||||
"animation-timing-function",
|
||||
"-webkit-animation-delay",
|
||||
"-moz-animation-delay",
|
||||
"-ms-animation-delay",
|
||||
"-o-animation-delay",
|
||||
"animation-delay",
|
||||
"-webkit-animation-iteration-count",
|
||||
"-moz-animation-iteration-count",
|
||||
"-ms-animation-iteration-count",
|
||||
"-o-animation-iteration-count",
|
||||
"animation-iteration-count",
|
||||
"-webkit-animation-direction",
|
||||
"-moz-animation-direction",
|
||||
"-ms-animation-direction",
|
||||
"-o-animation-direction",
|
||||
"animation-direction",
|
||||
"text-align",
|
||||
"-webkit-text-align-last",
|
||||
"-moz-text-align-last",
|
||||
"-ms-text-align-last",
|
||||
"text-align-last",
|
||||
"vertical-align",
|
||||
"white-space",
|
||||
"text-decoration",
|
||||
"text-emphasis",
|
||||
"text-emphasis-color",
|
||||
"text-emphasis-style",
|
||||
"text-emphasis-position",
|
||||
"text-indent",
|
||||
"-ms-text-justify",
|
||||
"text-justify",
|
||||
"letter-spacing",
|
||||
"word-spacing",
|
||||
"-ms-writing-mode",
|
||||
"text-outline",
|
||||
"text-transform",
|
||||
"text-wrap",
|
||||
"text-overflow",
|
||||
"-ms-text-overflow",
|
||||
"text-overflow-ellipsis",
|
||||
"text-overflow-mode",
|
||||
"-ms-word-wrap",
|
||||
"word-wrap",
|
||||
"word-break",
|
||||
"-ms-word-break",
|
||||
"-moz-tab-size",
|
||||
"-o-tab-size",
|
||||
"tab-size",
|
||||
"-webkit-hyphens",
|
||||
"-moz-hyphens",
|
||||
"hyphens",
|
||||
"pointer-events"
|
||||
],
|
||||
[
|
||||
"opacity",
|
||||
"filter:progid:DXImageTransform.Microsoft.Alpha(Opacity",
|
||||
"-ms-filter:\\'progid:DXImageTransform.Microsoft.Alpha",
|
||||
"-ms-interpolation-mode",
|
||||
"color",
|
||||
"border",
|
||||
"border-width",
|
||||
"border-style",
|
||||
"border-color",
|
||||
"border-top",
|
||||
"border-top-width",
|
||||
"border-top-style",
|
||||
"border-top-color",
|
||||
"border-right",
|
||||
"border-right-width",
|
||||
"border-right-style",
|
||||
"border-right-color",
|
||||
"border-bottom",
|
||||
"border-bottom-width",
|
||||
"border-bottom-style",
|
||||
"border-bottom-color",
|
||||
"border-left",
|
||||
"border-left-width",
|
||||
"border-left-style",
|
||||
"border-left-color",
|
||||
"-webkit-border-radius",
|
||||
"-moz-border-radius",
|
||||
"border-radius",
|
||||
"-webkit-border-top-left-radius",
|
||||
"-moz-border-radius-topleft",
|
||||
"border-top-left-radius",
|
||||
"-webkit-border-top-right-radius",
|
||||
"-moz-border-radius-topright",
|
||||
"border-top-right-radius",
|
||||
"-webkit-border-bottom-right-radius",
|
||||
"-moz-border-radius-bottomright",
|
||||
"border-bottom-right-radius",
|
||||
"-webkit-border-bottom-left-radius",
|
||||
"-moz-border-radius-bottomleft",
|
||||
"border-bottom-left-radius",
|
||||
"-webkit-border-image",
|
||||
"-moz-border-image",
|
||||
"-o-border-image",
|
||||
"border-image",
|
||||
"-webkit-border-image-source",
|
||||
"-moz-border-image-source",
|
||||
"-o-border-image-source",
|
||||
"border-image-source",
|
||||
"-webkit-border-image-slice",
|
||||
"-moz-border-image-slice",
|
||||
"-o-border-image-slice",
|
||||
"border-image-slice",
|
||||
"-webkit-border-image-width",
|
||||
"-moz-border-image-width",
|
||||
"-o-border-image-width",
|
||||
"border-image-width",
|
||||
"-webkit-border-image-outset",
|
||||
"-moz-border-image-outset",
|
||||
"-o-border-image-outset",
|
||||
"border-image-outset",
|
||||
"-webkit-border-image-repeat",
|
||||
"-moz-border-image-repeat",
|
||||
"-o-border-image-repeat",
|
||||
"border-image-repeat",
|
||||
"outline",
|
||||
"outline-width",
|
||||
"outline-style",
|
||||
"outline-color",
|
||||
"outline-offset",
|
||||
"background",
|
||||
"filter:progid:DXImageTransform.Microsoft.AlphaImageLoader",
|
||||
"background-color",
|
||||
"background-image",
|
||||
"background-repeat",
|
||||
"background-attachment",
|
||||
"background-position",
|
||||
"background-position-x",
|
||||
"-ms-background-position-x",
|
||||
"background-position-y",
|
||||
"-ms-background-position-y",
|
||||
"-webkit-background-clip",
|
||||
"-moz-background-clip",
|
||||
"background-clip",
|
||||
"background-origin",
|
||||
"-webkit-background-size",
|
||||
"-moz-background-size",
|
||||
"-o-background-size",
|
||||
"background-size",
|
||||
"box-decoration-break",
|
||||
"-webkit-box-shadow",
|
||||
"-moz-box-shadow",
|
||||
"box-shadow",
|
||||
"filter:progid:DXImageTransform.Microsoft.gradient",
|
||||
"-ms-filter:\\'progid:DXImageTransform.Microsoft.gradient",
|
||||
"text-shadow"
|
||||
]
|
||||
]
|
||||
}
|
||||
+324
@@ -0,0 +1,324 @@
|
||||
{
|
||||
"exclude": [
|
||||
".git/**",
|
||||
"node_modules/**",
|
||||
"bower_components/**"
|
||||
],
|
||||
"sort-order": [
|
||||
[
|
||||
"position",
|
||||
"z-index",
|
||||
"top",
|
||||
"right",
|
||||
"bottom",
|
||||
"left"
|
||||
],
|
||||
[
|
||||
"display",
|
||||
"visibility",
|
||||
"float",
|
||||
"clear",
|
||||
"overflow",
|
||||
"overflow-x",
|
||||
"overflow-y",
|
||||
"-ms-overflow-x",
|
||||
"-ms-overflow-y",
|
||||
"-webkit-overflow-scrolling",
|
||||
"clip",
|
||||
"zoom",
|
||||
"flex-direction",
|
||||
"flex-order",
|
||||
"flex-pack",
|
||||
"flex-align"
|
||||
],
|
||||
[
|
||||
"-webkit-box-sizing",
|
||||
"-moz-box-sizing",
|
||||
"box-sizing",
|
||||
"width",
|
||||
"min-width",
|
||||
"max-width",
|
||||
"height",
|
||||
"min-height",
|
||||
"max-height",
|
||||
"margin",
|
||||
"margin-top",
|
||||
"margin-right",
|
||||
"margin-bottom",
|
||||
"margin-left",
|
||||
"padding",
|
||||
"padding-top",
|
||||
"padding-right",
|
||||
"padding-bottom",
|
||||
"padding-left"
|
||||
],
|
||||
[
|
||||
"table-layout",
|
||||
"empty-cells",
|
||||
"caption-side",
|
||||
"border-spacing",
|
||||
"border-collapse",
|
||||
"list-style",
|
||||
"list-style-position",
|
||||
"list-style-type",
|
||||
"list-style-image"
|
||||
],
|
||||
[
|
||||
"content",
|
||||
"quotes",
|
||||
"counter-reset",
|
||||
"counter-increment",
|
||||
"resize",
|
||||
"cursor",
|
||||
"-webkit-user-select",
|
||||
"-moz-user-select",
|
||||
"-ms-user-select",
|
||||
"user-select",
|
||||
"nav-index",
|
||||
"nav-up",
|
||||
"nav-right",
|
||||
"nav-down",
|
||||
"nav-left",
|
||||
"-webkit-transition",
|
||||
"-moz-transition",
|
||||
"-ms-transition",
|
||||
"-o-transition",
|
||||
"transition",
|
||||
"-webkit-transition-delay",
|
||||
"-moz-transition-delay",
|
||||
"-ms-transition-delay",
|
||||
"-o-transition-delay",
|
||||
"transition-delay",
|
||||
"-webkit-transition-timing-function",
|
||||
"-moz-transition-timing-function",
|
||||
"-ms-transition-timing-function",
|
||||
"-o-transition-timing-function",
|
||||
"transition-timing-function",
|
||||
"-webkit-transition-duration",
|
||||
"-moz-transition-duration",
|
||||
"-ms-transition-duration",
|
||||
"-o-transition-duration",
|
||||
"transition-duration",
|
||||
"-webkit-transition-property",
|
||||
"-moz-transition-property",
|
||||
"-ms-transition-property",
|
||||
"-o-transition-property",
|
||||
"transition-property",
|
||||
"-webkit-transform",
|
||||
"-moz-transform",
|
||||
"-ms-transform",
|
||||
"-o-transform",
|
||||
"transform",
|
||||
"-webkit-transform-origin",
|
||||
"-moz-transform-origin",
|
||||
"-ms-transform-origin",
|
||||
"-o-transform-origin",
|
||||
"transform-origin",
|
||||
"-webkit-animation",
|
||||
"-moz-animation",
|
||||
"-ms-animation",
|
||||
"-o-animation",
|
||||
"animation",
|
||||
"-webkit-animation-name",
|
||||
"-moz-animation-name",
|
||||
"-ms-animation-name",
|
||||
"-o-animation-name",
|
||||
"animation-name",
|
||||
"-webkit-animation-duration",
|
||||
"-moz-animation-duration",
|
||||
"-ms-animation-duration",
|
||||
"-o-animation-duration",
|
||||
"animation-duration",
|
||||
"-webkit-animation-play-state",
|
||||
"-moz-animation-play-state",
|
||||
"-ms-animation-play-state",
|
||||
"-o-animation-play-state",
|
||||
"animation-play-state",
|
||||
"-webkit-animation-timing-function",
|
||||
"-moz-animation-timing-function",
|
||||
"-ms-animation-timing-function",
|
||||
"-o-animation-timing-function",
|
||||
"animation-timing-function",
|
||||
"-webkit-animation-delay",
|
||||
"-moz-animation-delay",
|
||||
"-ms-animation-delay",
|
||||
"-o-animation-delay",
|
||||
"animation-delay",
|
||||
"-webkit-animation-iteration-count",
|
||||
"-moz-animation-iteration-count",
|
||||
"-ms-animation-iteration-count",
|
||||
"-o-animation-iteration-count",
|
||||
"animation-iteration-count",
|
||||
"-webkit-animation-iteration-count",
|
||||
"-moz-animation-iteration-count",
|
||||
"-ms-animation-iteration-count",
|
||||
"-o-animation-iteration-count",
|
||||
"animation-iteration-count",
|
||||
"-webkit-animation-direction",
|
||||
"-moz-animation-direction",
|
||||
"-ms-animation-direction",
|
||||
"-o-animation-direction",
|
||||
"animation-direction",
|
||||
"text-align",
|
||||
"-webkit-text-align-last",
|
||||
"-moz-text-align-last",
|
||||
"-ms-text-align-last",
|
||||
"text-align-last",
|
||||
"vertical-align",
|
||||
"white-space",
|
||||
"text-decoration",
|
||||
"text-emphasis",
|
||||
"text-emphasis-color",
|
||||
"text-emphasis-style",
|
||||
"text-emphasis-position",
|
||||
"text-indent",
|
||||
"-ms-text-justify",
|
||||
"text-justify",
|
||||
"text-transform",
|
||||
"letter-spacing",
|
||||
"word-spacing",
|
||||
"-ms-writing-mode",
|
||||
"text-outline",
|
||||
"text-transform",
|
||||
"text-wrap",
|
||||
"text-overflow",
|
||||
"-ms-text-overflow",
|
||||
"text-overflow-ellipsis",
|
||||
"text-overflow-mode",
|
||||
"-ms-word-wrap",
|
||||
"word-wrap",
|
||||
"word-break",
|
||||
"-ms-word-break",
|
||||
"-moz-tab-size",
|
||||
"-o-tab-size",
|
||||
"tab-size",
|
||||
"-webkit-hyphens",
|
||||
"-moz-hyphens",
|
||||
"hyphens",
|
||||
"pointer-events"
|
||||
],
|
||||
[
|
||||
"opacity",
|
||||
"filter:progid:DXImageTransform.Microsoft.Alpha(Opacity",
|
||||
"-ms-filter:\\'progid:DXImageTransform.Microsoft.Alpha",
|
||||
"-ms-interpolation-mode",
|
||||
"color",
|
||||
"border",
|
||||
"border-collapse",
|
||||
"border-width",
|
||||
"border-style",
|
||||
"border-color",
|
||||
"border-top",
|
||||
"border-top-width",
|
||||
"border-top-style",
|
||||
"border-top-color",
|
||||
"border-right",
|
||||
"border-right-width",
|
||||
"border-right-style",
|
||||
"border-right-color",
|
||||
"border-bottom",
|
||||
"border-bottom-width",
|
||||
"border-bottom-style",
|
||||
"border-bottom-color",
|
||||
"border-left",
|
||||
"border-left-width",
|
||||
"border-left-style",
|
||||
"border-left-color",
|
||||
"-webkit-border-radius",
|
||||
"-moz-border-radius",
|
||||
"border-radius",
|
||||
"-webkit-border-top-left-radius",
|
||||
"-moz-border-radius-topleft",
|
||||
"border-top-left-radius",
|
||||
"-webkit-border-top-right-radius",
|
||||
"-moz-border-radius-topright",
|
||||
"border-top-right-radius",
|
||||
"-webkit-border-bottom-right-radius",
|
||||
"-moz-border-radius-bottomright",
|
||||
"border-bottom-right-radius",
|
||||
"-webkit-border-bottom-left-radius",
|
||||
"-moz-border-radius-bottomleft",
|
||||
"border-bottom-left-radius",
|
||||
"-webkit-border-image",
|
||||
"-moz-border-image",
|
||||
"-o-border-image",
|
||||
"border-image",
|
||||
"-webkit-border-image-source",
|
||||
"-moz-border-image-source",
|
||||
"-o-border-image-source",
|
||||
"border-image-source",
|
||||
"-webkit-border-image-slice",
|
||||
"-moz-border-image-slice",
|
||||
"-o-border-image-slice",
|
||||
"border-image-slice",
|
||||
"-webkit-border-image-width",
|
||||
"-moz-border-image-width",
|
||||
"-o-border-image-width",
|
||||
"border-image-width",
|
||||
"-webkit-border-image-outset",
|
||||
"-moz-border-image-outset",
|
||||
"-o-border-image-outset",
|
||||
"border-image-outset",
|
||||
"-webkit-border-image-repeat",
|
||||
"-moz-border-image-repeat",
|
||||
"-o-border-image-repeat",
|
||||
"border-image-repeat",
|
||||
"outline",
|
||||
"outline-width",
|
||||
"outline-style",
|
||||
"outline-color",
|
||||
"outline-offset",
|
||||
"background",
|
||||
"filter:progid:DXImageTransform.Microsoft.AlphaImageLoader",
|
||||
"background-color",
|
||||
"background-image",
|
||||
"background-repeat",
|
||||
"background-attachment",
|
||||
"background-position",
|
||||
"background-position-x",
|
||||
"-ms-background-position-x",
|
||||
"background-position-y",
|
||||
"-ms-background-position-y",
|
||||
"-webkit-background-clip",
|
||||
"-moz-background-clip",
|
||||
"background-clip",
|
||||
"background-origin",
|
||||
"-webkit-background-size",
|
||||
"-moz-background-size",
|
||||
"-o-background-size",
|
||||
"background-size",
|
||||
"box-decoration-break",
|
||||
"-webkit-box-shadow",
|
||||
"-moz-box-shadow",
|
||||
"box-shadow",
|
||||
"-webkit-box-shadow",
|
||||
"-moz-box-shadow",
|
||||
"box-shadow",
|
||||
"-webkit-box-shadow",
|
||||
"-moz-box-shadow",
|
||||
"box-shadow",
|
||||
"-webkit-box-shadow",
|
||||
"-moz-box-shadow",
|
||||
"box-shadow",
|
||||
"filter:progid:DXImageTransform.Microsoft.gradient",
|
||||
"-ms-filter:\\'progid:DXImageTransform.Microsoft.gradient",
|
||||
"text-shadow"
|
||||
],
|
||||
[
|
||||
"font",
|
||||
"font-family",
|
||||
"font-size",
|
||||
"font-weight",
|
||||
"font-style",
|
||||
"font-variant",
|
||||
"font-size-adjust",
|
||||
"font-stretch",
|
||||
"font-effect",
|
||||
"font-emphasize",
|
||||
"font-emphasize-position",
|
||||
"font-emphasize-style",
|
||||
"font-smooth",
|
||||
"line-height"
|
||||
]
|
||||
]
|
||||
}
|
||||
+384
@@ -0,0 +1,384 @@
|
||||
{
|
||||
"exclude": [
|
||||
".git/**",
|
||||
"node_modules/**",
|
||||
"bower_components/**"
|
||||
],
|
||||
"sort-order": [ [
|
||||
"position",
|
||||
"top",
|
||||
"right",
|
||||
"bottom",
|
||||
"left",
|
||||
"z-index",
|
||||
"display",
|
||||
"visibility",
|
||||
"-webkit-flex-direction",
|
||||
"-moz-flex-direction",
|
||||
"-ms-flex-direction",
|
||||
"-o-flex-direction",
|
||||
"flex-direction",
|
||||
"-webkit-flex-order",
|
||||
"-moz-flex-order",
|
||||
"-ms-flex-order",
|
||||
"-o-flex-order",
|
||||
"flex-order",
|
||||
"-webkit-flex-pack",
|
||||
"-moz-flex-pack",
|
||||
"-ms-flex-pack",
|
||||
"-o-flex-pack",
|
||||
"flex-pack",
|
||||
"float",
|
||||
"clear",
|
||||
"-webkit-flex-align",
|
||||
"-moz-flex-align",
|
||||
"-ms-flex-align",
|
||||
"-o-flex-align",
|
||||
"flex-align",
|
||||
"overflow",
|
||||
"-ms-overflow-x",
|
||||
"-ms-overflow-y",
|
||||
"overflow-x",
|
||||
"overflow-y",
|
||||
"-webkit-overflow-scrolling",
|
||||
"clip",
|
||||
"-webkit-box-sizing",
|
||||
"-moz-box-sizing",
|
||||
"box-sizing",
|
||||
"margin",
|
||||
"margin-top",
|
||||
"margin-right",
|
||||
"margin-bottom",
|
||||
"margin-left",
|
||||
"padding",
|
||||
"padding-top",
|
||||
"padding-right",
|
||||
"padding-bottom",
|
||||
"padding-left",
|
||||
"min-width",
|
||||
"min-height",
|
||||
"max-width",
|
||||
"max-height",
|
||||
"width",
|
||||
"height",
|
||||
"outline",
|
||||
"outline-width",
|
||||
"outline-style",
|
||||
"outline-color",
|
||||
"outline-offset",
|
||||
"border",
|
||||
"border-spacing",
|
||||
"border-collapse",
|
||||
"border-width",
|
||||
"border-style",
|
||||
"border-color",
|
||||
"border-top",
|
||||
"border-top-width",
|
||||
"border-top-style",
|
||||
"border-top-color",
|
||||
"border-right",
|
||||
"border-right-width",
|
||||
"border-right-style",
|
||||
"border-right-color",
|
||||
"border-bottom",
|
||||
"border-bottom-width",
|
||||
"border-bottom-style",
|
||||
"border-bottom-color",
|
||||
"border-left",
|
||||
"border-left-width",
|
||||
"border-left-style",
|
||||
"border-left-color",
|
||||
"-webkit-border-radius",
|
||||
"-moz-border-radius",
|
||||
"border-radius",
|
||||
"-webkit-border-top-left-radius",
|
||||
"-moz-border-radius-topleft",
|
||||
"border-top-left-radius",
|
||||
"-webkit-border-top-right-radius",
|
||||
"-moz-border-radius-topright",
|
||||
"border-top-right-radius",
|
||||
"-webkit-border-bottom-right-radius",
|
||||
"-moz-border-radius-bottomright",
|
||||
"border-bottom-right-radius",
|
||||
"-webkit-border-bottom-left-radius",
|
||||
"-moz-border-radius-bottomleft",
|
||||
"border-bottom-left-radius",
|
||||
"-webkit-border-image",
|
||||
"-moz-border-image",
|
||||
"-o-border-image",
|
||||
"border-image",
|
||||
"-webkit-border-image-source",
|
||||
"-moz-border-image-source",
|
||||
"-o-border-image-source",
|
||||
"border-image-source",
|
||||
"-webkit-border-image-slice",
|
||||
"-moz-border-image-slice",
|
||||
"-o-border-image-slice",
|
||||
"border-image-slice",
|
||||
"-webkit-border-image-width",
|
||||
"-moz-border-image-width",
|
||||
"-o-border-image-width",
|
||||
"border-image-width",
|
||||
"-webkit-border-image-outset",
|
||||
"-moz-border-image-outset",
|
||||
"-o-border-image-outset",
|
||||
"border-image-outset",
|
||||
"-webkit-border-image-repeat",
|
||||
"-moz-border-image-repeat",
|
||||
"-o-border-image-repeat",
|
||||
"border-image-repeat",
|
||||
"-webkit-border-top-image",
|
||||
"-moz-border-top-image",
|
||||
"-o-border-top-image",
|
||||
"border-top-image",
|
||||
"-webkit-border-right-image",
|
||||
"-moz-border-right-image",
|
||||
"-o-border-right-image",
|
||||
"border-right-image",
|
||||
"-webkit-border-bottom-image",
|
||||
"-moz-border-bottom-image",
|
||||
"-o-border-bottom-image",
|
||||
"border-bottom-image",
|
||||
"-webkit-border-left-image",
|
||||
"-moz-border-left-image",
|
||||
"-o-border-left-image",
|
||||
"border-left-image",
|
||||
"-webkit-border-corner-image",
|
||||
"-moz-border-corner-image",
|
||||
"-o-border-corner-image",
|
||||
"border-corner-image",
|
||||
"-webkit-border-top-left-image",
|
||||
"-moz-border-top-left-image",
|
||||
"-o-border-top-left-image",
|
||||
"border-top-left-image",
|
||||
"-webkit-border-top-right-image",
|
||||
"-moz-border-top-right-image",
|
||||
"-o-border-top-right-image",
|
||||
"border-top-right-image",
|
||||
"-webkit-border-bottom-right-image",
|
||||
"-moz-border-bottom-right-image",
|
||||
"-o-border-bottom-right-image",
|
||||
"border-bottom-right-image",
|
||||
"-webkit-border-bottom-left-image",
|
||||
"-moz-border-bottom-left-image",
|
||||
"-o-border-bottom-left-image",
|
||||
"border-bottom-left-image",
|
||||
"background",
|
||||
"filter:progid:DXImageTransform.Microsoft.AlphaImageLoader",
|
||||
"background-color",
|
||||
"background-image",
|
||||
"background-attachment",
|
||||
"background-position",
|
||||
"-ms-background-position-x",
|
||||
"-ms-background-position-y",
|
||||
"background-position-x",
|
||||
"background-position-y",
|
||||
"-webkit-background-clip",
|
||||
"-moz-background-clip",
|
||||
"background-clip",
|
||||
"background-origin",
|
||||
"-webkit-background-size",
|
||||
"-moz-background-size",
|
||||
"-o-background-size",
|
||||
"background-size",
|
||||
"background-repeat",
|
||||
"box-decoration-break",
|
||||
"-webkit-box-shadow",
|
||||
"-moz-box-shadow",
|
||||
"box-shadow",
|
||||
"color",
|
||||
"table-layout",
|
||||
"caption-side",
|
||||
"empty-cells",
|
||||
"list-style",
|
||||
"list-style-position",
|
||||
"list-style-type",
|
||||
"list-style-image",
|
||||
"quotes",
|
||||
"content",
|
||||
"counter-increment",
|
||||
"counter-reset",
|
||||
"-ms-writing-mode",
|
||||
"vertical-align",
|
||||
"text-align",
|
||||
"-webkit-text-align-last",
|
||||
"-moz-text-align-last",
|
||||
"-ms-text-align-last",
|
||||
"text-align-last",
|
||||
"text-decoration",
|
||||
"text-emphasis",
|
||||
"text-emphasis-position",
|
||||
"text-emphasis-style",
|
||||
"text-emphasis-color",
|
||||
"text-indent",
|
||||
"-ms-text-justify",
|
||||
"text-justify",
|
||||
"text-outline",
|
||||
"text-transform",
|
||||
"text-wrap",
|
||||
"-ms-text-overflow",
|
||||
"text-overflow",
|
||||
"text-overflow-ellipsis",
|
||||
"text-overflow-mode",
|
||||
"text-shadow",
|
||||
"white-space",
|
||||
"word-spacing",
|
||||
"-ms-word-wrap",
|
||||
"word-wrap",
|
||||
"-ms-word-break",
|
||||
"word-break",
|
||||
"-moz-tab-size",
|
||||
"-o-tab-size",
|
||||
"tab-size",
|
||||
"-webkit-hyphens",
|
||||
"-moz-hyphens",
|
||||
"hyphens",
|
||||
"letter-spacing",
|
||||
"font",
|
||||
"font-weight",
|
||||
"font-style",
|
||||
"font-variant",
|
||||
"font-size-adjust",
|
||||
"font-stretch",
|
||||
"font-size",
|
||||
"font-family",
|
||||
"src",
|
||||
"line-height",
|
||||
"opacity",
|
||||
"-ms-filter:\\'progid:DXImageTransform.Microsoft.Alpha",
|
||||
"filter:progid:DXImageTransform.Microsoft.Alpha(Opacity",
|
||||
"-ms-interpolation-mode",
|
||||
"-webkit-filter",
|
||||
"-ms-filter",
|
||||
"filter",
|
||||
"resize",
|
||||
"cursor",
|
||||
"nav-index",
|
||||
"nav-up",
|
||||
"nav-right",
|
||||
"nav-down",
|
||||
"nav-left",
|
||||
"-webkit-transition",
|
||||
"-moz-transition",
|
||||
"-ms-transition",
|
||||
"-o-transition",
|
||||
"transition",
|
||||
"-webkit-transition-delay",
|
||||
"-moz-transition-delay",
|
||||
"-ms-transition-delay",
|
||||
"-o-transition-delay",
|
||||
"transition-delay",
|
||||
"-webkit-transition-timing-function",
|
||||
"-moz-transition-timing-function",
|
||||
"-ms-transition-timing-function",
|
||||
"-o-transition-timing-function",
|
||||
"transition-timing-function",
|
||||
"-webkit-transition-duration",
|
||||
"-moz-transition-duration",
|
||||
"-ms-transition-duration",
|
||||
"-o-transition-duration",
|
||||
"transition-duration",
|
||||
"-webkit-transition-property",
|
||||
"-moz-transition-property",
|
||||
"-ms-transition-property",
|
||||
"-o-transition-property",
|
||||
"transition-property",
|
||||
"-webkit-transform",
|
||||
"-moz-transform",
|
||||
"-ms-transform",
|
||||
"-o-transform",
|
||||
"transform",
|
||||
"-webkit-transform-origin",
|
||||
"-moz-transform-origin",
|
||||
"-ms-transform-origin",
|
||||
"-o-transform-origin",
|
||||
"transform-origin",
|
||||
"-webkit-animation",
|
||||
"-moz-animation",
|
||||
"-ms-animation",
|
||||
"-o-animation",
|
||||
"animation",
|
||||
"-webkit-animation-name",
|
||||
"-moz-animation-name",
|
||||
"-ms-animation-name",
|
||||
"-o-animation-name",
|
||||
"animation-name",
|
||||
"-webkit-animation-duration",
|
||||
"-moz-animation-duration",
|
||||
"-ms-animation-duration",
|
||||
"-o-animation-duration",
|
||||
"animation-duration",
|
||||
"-webkit-animation-play-state",
|
||||
"-moz-animation-play-state",
|
||||
"-ms-animation-play-state",
|
||||
"-o-animation-play-state",
|
||||
"animation-play-state",
|
||||
"-webkit-animation-timing-function",
|
||||
"-moz-animation-timing-function",
|
||||
"-ms-animation-timing-function",
|
||||
"-o-animation-timing-function",
|
||||
"animation-timing-function",
|
||||
"-webkit-animation-delay",
|
||||
"-moz-animation-delay",
|
||||
"-ms-animation-delay",
|
||||
"-o-animation-delay",
|
||||
"animation-delay",
|
||||
"-webkit-animation-iteration-count",
|
||||
"-moz-animation-iteration-count",
|
||||
"-ms-animation-iteration-count",
|
||||
"-o-animation-iteration-count",
|
||||
"animation-iteration-count",
|
||||
"-webkit-animation-direction",
|
||||
"-moz-animation-direction",
|
||||
"-ms-animation-direction",
|
||||
"-o-animation-direction",
|
||||
"animation-direction",
|
||||
"pointer-events",
|
||||
"unicode-bidi",
|
||||
"direction",
|
||||
"-webkit-columns",
|
||||
"-moz-columns",
|
||||
"columns",
|
||||
"-webkit-column-span",
|
||||
"-moz-column-span",
|
||||
"column-span",
|
||||
"-webkit-column-width",
|
||||
"-moz-column-width",
|
||||
"column-width",
|
||||
"-webkit-column-count",
|
||||
"-moz-column-count",
|
||||
"column-count",
|
||||
"-webkit-column-fill",
|
||||
"-moz-column-fill",
|
||||
"column-fill",
|
||||
"-webkit-column-gap",
|
||||
"-moz-column-gap",
|
||||
"column-gap",
|
||||
"-webkit-column-rule",
|
||||
"-moz-column-rule",
|
||||
"column-rule",
|
||||
"-webkit-column-rule-width",
|
||||
"-moz-column-rule-width",
|
||||
"column-rule-width",
|
||||
"-webkit-column-rule-style",
|
||||
"-moz-column-rule-style",
|
||||
"column-rule-style",
|
||||
"-webkit-column-rule-color",
|
||||
"-moz-column-rule-color",
|
||||
"column-rule-color",
|
||||
"break-before",
|
||||
"break-inside",
|
||||
"break-after",
|
||||
"page-break-before",
|
||||
"page-break-inside",
|
||||
"page-break-after",
|
||||
"orphans",
|
||||
"widows",
|
||||
"-ms-zoom",
|
||||
"zoom",
|
||||
"max-zoom",
|
||||
"min-zoom",
|
||||
"user-zoom",
|
||||
"orientation"
|
||||
] ]
|
||||
}
|
||||
+100
@@ -0,0 +1,100 @@
|
||||
/**
|
||||
* Command line implementation for CSSComb
|
||||
*
|
||||
* Usage example:
|
||||
* ./node_modules/.bin/csscomb [options] file1 [dir1 [fileN [dirN]]]
|
||||
*/
|
||||
var fs = require('fs');
|
||||
var path = require('path');
|
||||
var program = require('commander');
|
||||
var vow = require('vow');
|
||||
var Comb = require('./csscomb');
|
||||
|
||||
program
|
||||
.version(require('../package.json').version)
|
||||
.usage('[options] <file ...>')
|
||||
.option('-v, --verbose', 'verbose mode')
|
||||
.option('-c, --config [path]', 'configuration file path')
|
||||
.option('-d, --detect', 'detect mode (would return detected options)')
|
||||
.option('-l, --lint', 'in case some fixes needed returns an error')
|
||||
.parse(process.argv);
|
||||
|
||||
if (!program.args.length) {
|
||||
console.log('No input paths specified');
|
||||
program.help();
|
||||
}
|
||||
|
||||
var comb = new Comb();
|
||||
|
||||
if (program.detect) {
|
||||
console.log(JSON.stringify(Comb.detectInFile(program.args[0]), false, 4));
|
||||
process.exit(0);
|
||||
}
|
||||
|
||||
var config;
|
||||
var configPath = program.config &&
|
||||
path.resolve(process.cwd(), program.config) ||
|
||||
Comb.getCustomConfigPath();
|
||||
|
||||
if (!fs.existsSync(configPath)) {
|
||||
config = require('../config/csscomb.json');
|
||||
} else if (configPath.match(/\.css$/)) {
|
||||
config = Comb.detectInFile(configPath);
|
||||
} else {
|
||||
config = Comb.getCustomConfig(configPath);
|
||||
}
|
||||
|
||||
if (!config) {
|
||||
console.log('Configuration file ' + configPath + ' was not found.');
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
if (config.template) {
|
||||
if (fs.existsSync(config.template)) {
|
||||
var templateConfig = Comb.detectInFile(config.template);
|
||||
for (var attrname in templateConfig) {
|
||||
if (!config[attrname]) {
|
||||
config[attrname] = templateConfig[attrname];
|
||||
}
|
||||
}
|
||||
} else {
|
||||
console.log('Template configuration file ' + config.template + ' was not found.');
|
||||
process.exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
console.time('spent');
|
||||
|
||||
config.verbose = program.verbose === true || config.verbose;
|
||||
config.lint = program.lint;
|
||||
|
||||
comb.configure(config);
|
||||
|
||||
vow.all(program.args.map(comb.processPath.bind(comb)))
|
||||
.then(function(changedFiles) {
|
||||
changedFiles = [].concat.apply([], changedFiles)
|
||||
.filter(function(isChanged) {
|
||||
return isChanged !== undefined;
|
||||
});
|
||||
|
||||
for (var i = changedFiles.length, tbchanged = 0; i--;) {
|
||||
tbchanged += changedFiles[i];
|
||||
}
|
||||
|
||||
var changed = config.lint ? 0 : tbchanged;
|
||||
|
||||
if (config.verbose) {
|
||||
console.log('');
|
||||
console.log(changedFiles.length + ' file' + (changedFiles.length === 1 ? '' : 's') + ' processed');
|
||||
console.log(changed + ' file' + (changed === 1 ? '' : 's') + ' fixed');
|
||||
console.timeEnd('spent');
|
||||
}
|
||||
|
||||
if (config.lint && tbchanged) {
|
||||
process.exit(1);
|
||||
}
|
||||
})
|
||||
.fail(function(e) {
|
||||
console.log('stack: ', e.stack);
|
||||
process.exit(1);
|
||||
});
|
||||
+321
@@ -0,0 +1,321 @@
|
||||
var Comb = require('csscomb-core');
|
||||
var gonzales = require('gonzales-pe');
|
||||
var fs = require('fs');
|
||||
var path = require('path');
|
||||
|
||||
/**
|
||||
* Converts CSS string to AST.
|
||||
*
|
||||
* @param {String} text CSS string
|
||||
* @param {String} [syntax] Syntax name (e.g., `scss`)
|
||||
* @param {String} [filename]
|
||||
* @returns {Array} AST
|
||||
*/
|
||||
function cssToAST(text, syntax, filename) {
|
||||
var string = JSON.stringify;
|
||||
var fileInfo = filename ? ' at ' + filename : '';
|
||||
var tree;
|
||||
|
||||
try {
|
||||
tree = gonzales.parse(text, { syntax: syntax });
|
||||
} catch (e) {
|
||||
throw new Error('Parsing error' + fileInfo + ': ' + e.message);
|
||||
}
|
||||
|
||||
// TODO: When can tree be undefined? <tg>
|
||||
if (typeof tree === 'undefined') {
|
||||
throw new Error('Undefined tree' + fileInfo + ': ' + string(text) + ' => ' + string(tree));
|
||||
}
|
||||
|
||||
return tree;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets option's data needed for detection
|
||||
*
|
||||
* @param {String} optionName
|
||||
* @returns {Object} Object with option's name, link to `detect()` method
|
||||
* and default value for the case when nothing can be detected
|
||||
*/
|
||||
function getHandler(optionName) {
|
||||
var option = require('./options/' + optionName);
|
||||
if (!option.detect) throw new Error('Option does not have `detect()` method.');
|
||||
return {
|
||||
name: option.name,
|
||||
detect: option.detect,
|
||||
detectDefault: option.detectDefault
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Processes tree node and detects options.
|
||||
*
|
||||
* @param {Array} node Tree node
|
||||
* @param {Number} level Indent level
|
||||
* @param {Object} handler Object with option's data
|
||||
* @param {Object} detectedOptions
|
||||
*/
|
||||
function detectInNode(node, level, handler, detectedOptions) {
|
||||
node.map(function(tree) {
|
||||
var detected = handler.detect(tree);
|
||||
var variants = detectedOptions[handler.name];
|
||||
if (typeof detected === 'object') {
|
||||
variants.push.apply(variants, detected);
|
||||
} else if (typeof detected !== 'undefined') {
|
||||
variants.push(detected);
|
||||
}
|
||||
|
||||
//if (nodeType === 'atrulers' || nodeType === 'block') level++;
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Processes tree and detects options.
|
||||
*
|
||||
* @param {Array} tree
|
||||
* @param {Array} handlers List of options that we should look for
|
||||
* @returns {Object} Map with detected options and all variants of possible
|
||||
* values
|
||||
*/
|
||||
function detectInTree(tree, handlers) {
|
||||
var detectedOptions = {};
|
||||
// We walk across complete tree for each handler,
|
||||
// because we need strictly maintain order in which handlers work,
|
||||
// despite fact that handlers work on different level of the tree.
|
||||
handlers.forEach(function(handler) {
|
||||
detectedOptions[handler.name] = [];
|
||||
// TODO: Pass all parameters as one object? <tg>
|
||||
detectInNode(tree, 0, handler, detectedOptions);
|
||||
});
|
||||
return detectedOptions;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the detected options.
|
||||
*
|
||||
* @param {Object} detected
|
||||
* @param {Array} handlers
|
||||
* @returns {Object}
|
||||
*/
|
||||
function getDetectedOptions(detected, handlers) {
|
||||
var options = {};
|
||||
Object.keys(detected).forEach(function(option) {
|
||||
// List of all the detected variants from the stylesheet for the given option:
|
||||
var values = detected[option];
|
||||
var i;
|
||||
if (!values.length) {
|
||||
// If there are no values for the option, check if there is a default one:
|
||||
for (i = handlers.length; i--;) {
|
||||
if (handlers[i].name === option &&
|
||||
handlers[i].detectDefault !== undefined) {
|
||||
options[option] = handlers[i].detectDefault;
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else if (values.length === 1) {
|
||||
options[option] = values[0];
|
||||
} else {
|
||||
// If there are more than one value for the option, find the most popular one;
|
||||
// `variants` would be populated with the popularity for different values.
|
||||
var variants = {};
|
||||
var bestGuess = null;
|
||||
var maximum = 0;
|
||||
for (i = values.length; i--;) {
|
||||
var currentValue = values[i];
|
||||
// Count the current value:
|
||||
if (variants[currentValue]) {
|
||||
variants[currentValue]++;
|
||||
} else {
|
||||
variants[currentValue] = 1;
|
||||
}
|
||||
// If the current variant is the most popular one, treat
|
||||
// it as the best guess:
|
||||
if (variants[currentValue] >= maximum) {
|
||||
maximum = variants[currentValue];
|
||||
bestGuess = currentValue;
|
||||
}
|
||||
}
|
||||
if (bestGuess !== null) {
|
||||
options[option] = bestGuess;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
return options;
|
||||
}
|
||||
|
||||
/**
|
||||
* Starts Code Style processing process.
|
||||
*
|
||||
* @param {String|Object} config
|
||||
* @constructor
|
||||
* @name CSScomb
|
||||
*/
|
||||
var CSScomb = function(config) {
|
||||
var options = fs.readdirSync(__dirname + '/options').map(function(option) {
|
||||
return require('./options/' + option);
|
||||
});
|
||||
|
||||
var comb = new Comb(options, 'css', 'less', 'scss', 'sass');
|
||||
|
||||
// If config was passed, configure:
|
||||
if (typeof config === 'string') {
|
||||
config = CSScomb.getConfig(config);
|
||||
}
|
||||
if (typeof config === 'object') {
|
||||
comb.configure(config);
|
||||
}
|
||||
|
||||
return comb;
|
||||
};
|
||||
|
||||
/**
|
||||
* STATIC METHODS
|
||||
* Methods that can be called without creating an instance:
|
||||
* - getConfig;
|
||||
* - getCustomConfig;
|
||||
* - getCustomConfigPath;
|
||||
* - detectInFile;
|
||||
* - detectInString.
|
||||
* For example: `CSScomb.getConfig('zen')`
|
||||
*/
|
||||
|
||||
/**
|
||||
* Gets one of configuration files from configs' directory.
|
||||
*
|
||||
* @param {String} name Config's name, e.g. 'yandex'
|
||||
* @returns {Object} Configuration object
|
||||
*/
|
||||
CSScomb.getConfig = function getConfig(name) {
|
||||
var DEFAULT_CONFIG_NAME = 'csscomb';
|
||||
name = name || DEFAULT_CONFIG_NAME;
|
||||
|
||||
if (typeof name !== 'string') {
|
||||
throw new Error('Config name must be a string.');
|
||||
}
|
||||
|
||||
var CONFIG_DIR_PATH = '../config';
|
||||
var availableConfigsNames = fs.readdirSync(__dirname + '/' + CONFIG_DIR_PATH)
|
||||
.map(function(configFileName) {
|
||||
return configFileName.split('.')[0]; // strip file extension(s)
|
||||
});
|
||||
|
||||
if (availableConfigsNames.indexOf(name) < 0) {
|
||||
var configsNamesAsString = availableConfigsNames
|
||||
.map(function(configName) {
|
||||
return '\'' + configName + '\'';
|
||||
})
|
||||
.join(', ');
|
||||
throw new Error('"' + name + '" is not a valid config name. Try one of ' +
|
||||
'the following: ' + configsNamesAsString + '.');
|
||||
}
|
||||
|
||||
return require(CONFIG_DIR_PATH + '/' + name + '.json');
|
||||
};
|
||||
|
||||
/**
|
||||
* Gets configuration from provided config path or looks for it in common
|
||||
* places.
|
||||
*
|
||||
* @param {String} [configPath]
|
||||
* @returns {Object|null}
|
||||
*/
|
||||
CSScomb.getCustomConfig = function getCustomConfig(configPath) {
|
||||
var config;
|
||||
configPath = configPath || CSScomb.getCustomConfigPath();
|
||||
|
||||
try {
|
||||
config = JSON.parse(fs.readFileSync(configPath, 'utf8'));
|
||||
} catch (e) {
|
||||
config = null;
|
||||
}
|
||||
|
||||
return config;
|
||||
};
|
||||
|
||||
/**
|
||||
* Looks for a config file: recursively from current (process) directory
|
||||
* up to $HOME dir
|
||||
* If no custom config file is found, return `null`.
|
||||
*
|
||||
* @param {String} [configPath]
|
||||
* @returns {String | null}
|
||||
*/
|
||||
CSScomb.getCustomConfigPath = function getCustomConfigPath(configPath) {
|
||||
var HOME = process.env.HOME || process.env.HOMEPATH || process.env.USERPROFILE;
|
||||
|
||||
configPath = configPath || path.join(process.cwd(), '.csscomb.json');
|
||||
|
||||
// If we've finally found a config, return its path:
|
||||
if (fs.existsSync(configPath)) return fs.realpathSync(configPath);
|
||||
|
||||
// If we are in HOME dir already and yet no config file, return a default
|
||||
// one from our package.
|
||||
// If project is located not under HOME, compare to root instead.
|
||||
// Since there appears to be no good way to get root path in
|
||||
// Windows, assume that if current dir has no parent dir, we're in
|
||||
// root.
|
||||
var dirname = path.dirname(configPath);
|
||||
var parentDirname = path.dirname(dirname);
|
||||
if (dirname === HOME || dirname === parentDirname) return null;
|
||||
|
||||
// If there is no config in this directory, go one level up and look for
|
||||
// a config there:
|
||||
configPath = path.join(parentDirname, '.csscomb.json');
|
||||
return CSScomb.getCustomConfigPath(configPath);
|
||||
};
|
||||
|
||||
/**
|
||||
* Detects the options in the given file
|
||||
*
|
||||
* @param {String} path Path to the stylesheet
|
||||
* @param {Array} options List of options to detect
|
||||
* @returns {Object} Detected options
|
||||
*/
|
||||
CSScomb.detectInFile = function detectInFile(path, options) {
|
||||
var stylesheet = fs.readFileSync(path, 'utf8');
|
||||
return CSScomb.detectInString(stylesheet, options);
|
||||
};
|
||||
|
||||
/**
|
||||
* Detects the options in the given string
|
||||
*
|
||||
* @param {String} text Stylesheet
|
||||
* @param {Array} options List of options to detect
|
||||
* @returns {Object} Detected options
|
||||
*/
|
||||
CSScomb.detectInString = function detectInString(text, options) {
|
||||
var result;
|
||||
var handlers = [];
|
||||
|
||||
if (!text) return text;
|
||||
|
||||
var optionNames = fs.readdirSync(__dirname + '/options');
|
||||
optionNames.forEach(function(option) {
|
||||
option = option.slice(0, -3);
|
||||
if (options && options.indexOf(option) < 0) return;
|
||||
try {
|
||||
handlers.push(getHandler(option));
|
||||
} catch (e) {
|
||||
console.warn('\nFailed to load "%s" option:\n%s', option, e.message);
|
||||
}
|
||||
});
|
||||
|
||||
var tree = cssToAST(text);
|
||||
var detectedOptions = detectInTree(tree, handlers);
|
||||
result = getDetectedOptions(detectedOptions, handlers);
|
||||
|
||||
// Handle conflicting options with spaces around braces:
|
||||
var blockIndent = result['block-indent'];
|
||||
var spaceAfterOpeningBrace = result['space-after-opening-brace'];
|
||||
|
||||
if (typeof blockIndent === 'string' &&
|
||||
spaceAfterOpeningBrace &&
|
||||
spaceAfterOpeningBrace.indexOf('\n') > -1) {
|
||||
result['space-after-opening-brace'] = '\n';
|
||||
}
|
||||
|
||||
return result;
|
||||
};
|
||||
|
||||
module.exports = CSScomb;
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
'use strict';
|
||||
|
||||
module.exports = function (string) {
|
||||
return string.replace(/\n\s+/gm, ' ');
|
||||
};
|
||||
+4
@@ -0,0 +1,4 @@
|
||||
// jscs:disable
|
||||
'use strict';
|
||||
|
||||
module.exports = require('../node_modules/csscomb-core/node_modules/gonzales-pe');
|
||||
+73
@@ -0,0 +1,73 @@
|
||||
var gonzales = require('gonzales-pe');
|
||||
|
||||
module.exports = {
|
||||
name: 'always-semicolon',
|
||||
|
||||
syntax: ['css', 'less', 'sass', 'scss'],
|
||||
|
||||
accepts: { boolean: [true] },
|
||||
|
||||
/**
|
||||
* Processes tree node.
|
||||
* @param {node} node
|
||||
*/
|
||||
process: function(node) {
|
||||
var nodeWithoutSemicolon;
|
||||
|
||||
if (!node.is('block')) return;
|
||||
|
||||
mainLoop:
|
||||
for (var i = node.length; i--;) {
|
||||
var currentNode = node.get(i);
|
||||
|
||||
// Skip nodes that already have `;` at the end:
|
||||
if (currentNode.is('declarationDelimiter')) break;
|
||||
|
||||
// Add semicolon only after declarations and includes.
|
||||
// If current node is include, insert semicolon right into it.
|
||||
// If it's declaration, look for value node:
|
||||
if (currentNode.is('include')) {
|
||||
nodeWithoutSemicolon = currentNode;
|
||||
} else if (currentNode.is('declaration')) {
|
||||
nodeWithoutSemicolon = currentNode.last('value');
|
||||
} else {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Check if there are spaces and comments at the end of the node:
|
||||
for (var j = nodeWithoutSemicolon.length; j--; ) {
|
||||
var lastNode = nodeWithoutSemicolon.get(j);
|
||||
|
||||
// If the node's last child is block, do not add semicolon:
|
||||
// TODO: Add syntax check and run the code only for scss
|
||||
if (lastNode.is('block')) {
|
||||
break mainLoop;
|
||||
} else if (!lastNode.is('space') &&
|
||||
!lastNode.is('multilineComment') &&
|
||||
!lastNode.is('singlelineComment')) {
|
||||
j++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
var declDelim = gonzales.createNode({ type: 'declarationDelimiter', content: ';' });
|
||||
nodeWithoutSemicolon.insert(j, declDelim);
|
||||
break;
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Detects the value of an option at the tree node.
|
||||
*
|
||||
* @param {node} node
|
||||
*/
|
||||
detect: function(node) {
|
||||
if (!node.is('block')) return;
|
||||
|
||||
for (var i = node.length; i--;) {
|
||||
var nodeItem = node.get(i);
|
||||
if (nodeItem.is('declarationDelimiter')) return true;
|
||||
if (nodeItem.is('declaration')) return false;
|
||||
}
|
||||
}
|
||||
};
|
||||
+135
@@ -0,0 +1,135 @@
|
||||
module.exports = (function() {
|
||||
var syntax;
|
||||
var value;
|
||||
|
||||
function processNode(node, level) {
|
||||
level = level || 0;
|
||||
|
||||
// XXX: Hack for braces
|
||||
if (node.is('braces') || node.is('id')) return;
|
||||
|
||||
for (var i = 0; i < node.length; i++) {
|
||||
var n = node.get(i);
|
||||
if (!n) continue;
|
||||
|
||||
if (syntax === 'sass' && n.is('block')) {
|
||||
processSassBlock(n, level, value);
|
||||
}
|
||||
|
||||
// Continue only with space nodes inside {...}:
|
||||
if (syntax !== 'sass' && level !== 0 && n.is('space')) {
|
||||
processSpaceNode(n, level, value);
|
||||
}
|
||||
|
||||
if (n.is('block') || n.is('atrulers')) level++;
|
||||
|
||||
processNode(n, level);
|
||||
}
|
||||
}
|
||||
|
||||
function processSassBlock(node, level, value) {
|
||||
var spaces;
|
||||
var whitespaceNode;
|
||||
var i;
|
||||
|
||||
for (i = node.length; i--;) {
|
||||
whitespaceNode = node.get(i);
|
||||
|
||||
if (!whitespaceNode.is('space')) continue;
|
||||
|
||||
if (whitespaceNode.content === '\n') continue;
|
||||
|
||||
spaces = whitespaceNode.content.replace(/[ \t]/gm, '');
|
||||
spaces += new Array(level + 2).join(value);
|
||||
whitespaceNode.content = spaces;
|
||||
}
|
||||
}
|
||||
|
||||
function processSpaceNode(node, level, value) {
|
||||
var spaces;
|
||||
|
||||
// Remove all whitespaces and tabs, leave only new lines:
|
||||
spaces = node.content.replace(/[ \t]/gm, '');
|
||||
|
||||
if (!spaces) return;
|
||||
|
||||
spaces += new Array(level + 1).join(value);
|
||||
node.content = spaces;
|
||||
}
|
||||
|
||||
return {
|
||||
name: 'block-indent',
|
||||
|
||||
runBefore: 'sort-order',
|
||||
|
||||
syntax: ['css', 'less', 'sass', 'scss'],
|
||||
|
||||
accepts: {
|
||||
number: true,
|
||||
string: /^[ \t]*$/
|
||||
},
|
||||
|
||||
/**
|
||||
* Processes tree node.
|
||||
*
|
||||
* @param {node} node
|
||||
*/
|
||||
process: function process(node) {
|
||||
var spaces;
|
||||
var whitespaceNode;
|
||||
var i;
|
||||
|
||||
if (!node.is('stylesheet')) return;
|
||||
|
||||
syntax = this.getSyntax();
|
||||
value = this.getValue('block-indent');
|
||||
|
||||
|
||||
for (i = node.length; i--;) {
|
||||
whitespaceNode = node.get(i);
|
||||
|
||||
if (!whitespaceNode.is('space')) continue;
|
||||
|
||||
spaces = whitespaceNode.content.replace(/\n[ \t]+/gm, '\n');
|
||||
|
||||
if (spaces === '') {
|
||||
node.remove(i);
|
||||
} else {
|
||||
whitespaceNode.content = spaces;
|
||||
}
|
||||
}
|
||||
|
||||
processNode(node);
|
||||
},
|
||||
|
||||
/**
|
||||
* Detects the value of an option at the tree node.
|
||||
*
|
||||
* @param {node} node
|
||||
*/
|
||||
detect: function(node) {
|
||||
var result = [];
|
||||
|
||||
// Continue only with non-empty {...} blocks:
|
||||
if (!node.is('atrulers') && !node.is('block') || !node.length)
|
||||
return;
|
||||
|
||||
for (var i = node.length; i--;) {
|
||||
var whitespaceNode = node.get(i);
|
||||
if (!whitespaceNode.is('space')) continue;
|
||||
|
||||
var spaces = whitespaceNode.content;
|
||||
var lastIndex = spaces.lastIndexOf('\n');
|
||||
|
||||
// Do not continue if there is no line break:
|
||||
if (lastIndex < 0) continue;
|
||||
|
||||
// Number of spaces from beginning of line:
|
||||
var spacesLength = spaces.slice(lastIndex + 1).length + 1;
|
||||
result.push(new Array(spacesLength).join(' '));
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
};
|
||||
})();
|
||||
+34
@@ -0,0 +1,34 @@
|
||||
module.exports = {
|
||||
name: 'color-case',
|
||||
|
||||
syntax: ['css', 'less', 'sass', 'scss'],
|
||||
|
||||
accepts: { string: /^lower|upper$/ },
|
||||
|
||||
/**
|
||||
* Processes tree node.
|
||||
* @param {node} node
|
||||
*/
|
||||
process: function(node) {
|
||||
if (!node.is('color')) return;
|
||||
|
||||
node.content = this.getValue('color-case') === 'lower' ?
|
||||
node.content.toLowerCase() :
|
||||
node.content.toUpperCase();
|
||||
},
|
||||
|
||||
/**
|
||||
* Detects the value of an option at the tree node.
|
||||
*
|
||||
* @param {node} node
|
||||
*/
|
||||
detect: function(node) {
|
||||
if (!node.is('color')) return;
|
||||
|
||||
if (node.content.match(/^[^A-F]*[a-f][^A-F]*$/)) {
|
||||
return 'lower';
|
||||
} else if (node.content.match(/^[^a-f]*[A-F][^a-f]*$/)) {
|
||||
return 'upper';
|
||||
}
|
||||
}
|
||||
};
|
||||
+34
@@ -0,0 +1,34 @@
|
||||
module.exports = {
|
||||
name: 'color-shorthand',
|
||||
|
||||
syntax: ['css', 'less', 'sass', 'scss'],
|
||||
|
||||
accepts: { boolean: [true, false] },
|
||||
|
||||
/**
|
||||
* Processes tree node.
|
||||
* @param {node} node
|
||||
*/
|
||||
process: function(node) {
|
||||
if (!node.is('color')) return;
|
||||
|
||||
node.content = this.getValue('color-shorthand') ?
|
||||
node.content.replace(/(\w)\1(\w)\2(\w)\3/i, '$1$2$3') :
|
||||
node.content.replace(/^(\w)(\w)(\w)$/, '$1$1$2$2$3$3');
|
||||
},
|
||||
|
||||
/**
|
||||
* Detects the value of an option at the tree node.
|
||||
*
|
||||
* @param {node} node
|
||||
*/
|
||||
detect: function(node) {
|
||||
if (!node.is('color')) return;
|
||||
|
||||
if (node.content.match(/^\w{3}$/)) {
|
||||
return true;
|
||||
} else if (node.content.match(/^(\w)\1(\w)\2(\w)\3$/)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
};
|
||||
+49
@@ -0,0 +1,49 @@
|
||||
module.exports = {
|
||||
name: 'element-case',
|
||||
|
||||
syntax: ['css', 'less', 'sass', 'scss'],
|
||||
|
||||
accepts: { string: /^lower|upper$/ },
|
||||
|
||||
/**
|
||||
* Processes tree node.
|
||||
* @param {node} node
|
||||
*/
|
||||
process: function(node) {
|
||||
if (!node.is('selector') &&
|
||||
!node.is('arguments')) return;
|
||||
|
||||
var value = this.getValue('element-case');
|
||||
|
||||
node.forEach('simpleSelector', function(selector) {
|
||||
selector.forEach('ident', function(ident) {
|
||||
ident.content = value === 'lower' ?
|
||||
ident.content.toLowerCase() :
|
||||
ident.content.toUpperCase();
|
||||
});
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* Detects the value of an option at the tree node.
|
||||
*
|
||||
* @param {node} node
|
||||
*/
|
||||
detect: function(node) {
|
||||
if (!node.is('selector') &&
|
||||
!node.is('arguments')) return;
|
||||
|
||||
var variants = [];
|
||||
|
||||
node.forEach('simpleSelector', function(selector) {
|
||||
selector.forEach('ident', function(ident) {
|
||||
if (ident.content.match(/^[a-z]+$/)) {
|
||||
variants.push('lower');
|
||||
} else if (ident.content.match(/^[A-Z]+$/)) {
|
||||
variants.push('upper');
|
||||
}
|
||||
});
|
||||
});
|
||||
return variants;
|
||||
}
|
||||
};
|
||||
+41
@@ -0,0 +1,41 @@
|
||||
var gonzales = require('gonzales-pe');
|
||||
|
||||
module.exports = {
|
||||
name: 'eof-newline',
|
||||
|
||||
syntax: ['css', 'less', 'sass', 'scss'],
|
||||
|
||||
accepts: { boolean: [true, false] },
|
||||
|
||||
/**
|
||||
* Processes tree node.
|
||||
* @param {node} node
|
||||
*/
|
||||
process: function(node) {
|
||||
if (!node.is('stylesheet')) return;
|
||||
|
||||
var lastChild = node.last();
|
||||
if (!lastChild.is('space')) {
|
||||
lastChild = gonzales.createNode({ type: 'space', content: '' });
|
||||
node.content.push(lastChild);
|
||||
}
|
||||
lastChild.content = lastChild.content.replace(/\n$/, '');
|
||||
if (this.getValue('eof-newline')) lastChild.content += '\n';
|
||||
},
|
||||
|
||||
/**
|
||||
* Detects the value of an option at the tree node.
|
||||
*
|
||||
* @param {node} node
|
||||
*/
|
||||
detect: function(node) {
|
||||
if (!node.is('stylesheet')) return;
|
||||
|
||||
var lastChild = node.last();
|
||||
if (lastChild.is('space') && lastChild.content.indexOf('\n') !== -1) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
};
|
||||
+37
@@ -0,0 +1,37 @@
|
||||
module.exports = {
|
||||
name: 'leading-zero',
|
||||
|
||||
syntax: ['css', 'less', 'sass', 'scss'],
|
||||
|
||||
accepts: { boolean: [true, false] },
|
||||
|
||||
/**
|
||||
* Processes tree node.
|
||||
* @param {node} node
|
||||
*/
|
||||
process: function(node) {
|
||||
if (!node.is('number')) return;
|
||||
|
||||
if (this.getValue('leading-zero')) {
|
||||
if (node.content[0] === '.')
|
||||
node.content = '0' + node.content;
|
||||
} else {
|
||||
node.content = node.content.replace(/^0+(?=\.)/, '');
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Detects the value of an option at the tree node.
|
||||
*
|
||||
* @param {node} node
|
||||
*/
|
||||
detect: function(node) {
|
||||
if (!node.is('number')) return;
|
||||
|
||||
if (node.content.match(/^\.[0-9]+/)) {
|
||||
return false;
|
||||
} else if (node.content.match(/^0\.[0-9]+/)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
};
|
||||
+45
@@ -0,0 +1,45 @@
|
||||
module.exports = {
|
||||
name: 'quotes',
|
||||
|
||||
syntax: ['css', 'less', 'sass', 'scss'],
|
||||
|
||||
accepts: { string: /^single|double$/ },
|
||||
|
||||
/**
|
||||
* Processes tree node.
|
||||
* @param {node} node
|
||||
*/
|
||||
process: function(node) {
|
||||
if (!node.is('string')) return;
|
||||
|
||||
var value = this.getValue('quotes');
|
||||
|
||||
if (node.content[0] === '"' && value === 'single') {
|
||||
node.content = node.content
|
||||
.replace(/\\"/g, '"') // unescape all escaped double quotes
|
||||
.replace(/([^\\])'/g, '$1\\\'') // escape all the single quotes
|
||||
.replace(/^"|"$/g, '\''); // replace the first and the last quote
|
||||
|
||||
} else if (node.content[0] === '\'' && value === 'double') {
|
||||
node.content = node.content
|
||||
.replace(/\\'/g, '\'') // unescape all escaped single quotes
|
||||
.replace(/([^\\])"/g, '$1\\\"') // escape all the double quotes
|
||||
.replace(/^'|'$/g, '"'); // replace the first and the last quote
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Detects the value of an option at the tree node.
|
||||
*
|
||||
* @param {node} node
|
||||
*/
|
||||
detect: function(node) {
|
||||
if (!node.is('string')) return;
|
||||
|
||||
if (node.content[0] === '"') {
|
||||
return 'double';
|
||||
} else if (node.content[0] === '\'') {
|
||||
return 'single';
|
||||
}
|
||||
}
|
||||
};
|
||||
Generated
Vendored
+81
@@ -0,0 +1,81 @@
|
||||
module.exports = (function() {
|
||||
function processNode(node) {
|
||||
removeEmptyRulesets(node);
|
||||
mergeAdjacentWhitespace(node);
|
||||
}
|
||||
|
||||
function removeEmptyRulesets(stylesheet) {
|
||||
stylesheet.forEach('ruleset', function(ruleset, i) {
|
||||
var block = ruleset.first('block');
|
||||
processNode(block);
|
||||
if (isEmptyBlock(block)) stylesheet.remove(i);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Removing ruleset nodes from tree may result in two adjacent whitespace
|
||||
* nodes which is not correct AST:
|
||||
* [space, ruleset, space] => [space, space]
|
||||
* To ensure correctness of further processing we should merge such nodes
|
||||
* into one:
|
||||
* [space, space] => [space]
|
||||
*/
|
||||
function mergeAdjacentWhitespace(node) {
|
||||
var i = node.content.length - 1;
|
||||
while (i-- > 0) {
|
||||
if (node.get(i).is('space') && node.get(i + 1).is('space')) {
|
||||
node.get(i).content += node.get(i + 1).content;
|
||||
node.remove(i + 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Block is considered empty when it has nothing but spaces.
|
||||
*/
|
||||
function isEmptyBlock(node) {
|
||||
if (!node.length) return true;
|
||||
|
||||
return !node.content.some(function(node) {
|
||||
return !node.is('space');
|
||||
});
|
||||
}
|
||||
|
||||
return {
|
||||
name: 'remove-empty-rulesets',
|
||||
|
||||
runBefore: 'block-indent',
|
||||
|
||||
syntax: ['css', 'less', 'sass', 'scss'],
|
||||
|
||||
accepts: { boolean: [true] },
|
||||
|
||||
/**
|
||||
* Remove rulesets with no declarations.
|
||||
*
|
||||
* @param {String} node
|
||||
*/
|
||||
process: function(node) {
|
||||
if (!node.is('stylesheet')) return;
|
||||
|
||||
processNode(node);
|
||||
},
|
||||
|
||||
detectDefault: true,
|
||||
|
||||
/**
|
||||
* Detects the value of an option at the tree node.
|
||||
* This option is treated as `true` by default, but any trailing space would invalidate it.
|
||||
*
|
||||
* @param {node} node
|
||||
*/
|
||||
detect: function(node) {
|
||||
if (!node.is('atrulers') && !node.is('block')) return;
|
||||
|
||||
if (node.length === 0 ||
|
||||
(node.length === 1 && node.first().is('space'))) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
};
|
||||
})();
|
||||
Generated
Vendored
+9
@@ -0,0 +1,9 @@
|
||||
module.exports = {
|
||||
name: 'sort-order-fallback',
|
||||
|
||||
syntax: ['css', 'less', 'sass', 'scss'],
|
||||
|
||||
accepts: { string: /^abc$/ },
|
||||
|
||||
process: function() {}
|
||||
};
|
||||
+388
@@ -0,0 +1,388 @@
|
||||
var gonzales = require('gonzales-pe');
|
||||
|
||||
module.exports = {
|
||||
name: 'sort-order',
|
||||
|
||||
runBefore: 'space-before-closing-brace',
|
||||
|
||||
syntax: ['css', 'less', 'sass', 'scss'],
|
||||
|
||||
/**
|
||||
* Sets handler value.
|
||||
*
|
||||
* @param {Array} value Option value
|
||||
* @returns {Array}
|
||||
*/
|
||||
setValue: function(value) {
|
||||
if (!Array.isArray(value)) throw new Error('The option accepts only array of properties.');
|
||||
|
||||
var order = {};
|
||||
|
||||
if (typeof value[0] === 'string') {
|
||||
value.forEach(function(prop, propIndex) {
|
||||
order[prop] = { group: 0, prop: propIndex };
|
||||
});
|
||||
} else {
|
||||
value.forEach(function(group, groupIndex) {
|
||||
group.forEach(function(prop, propIndex) {
|
||||
order[prop] = { group: groupIndex, prop: propIndex };
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
return order;
|
||||
},
|
||||
|
||||
/**
|
||||
* Processes tree node.
|
||||
* @param {node} node
|
||||
*/
|
||||
process: function(node) {
|
||||
var _this = this;
|
||||
// Types of nodes that can be sorted:
|
||||
var NODES = ['atruleb', 'atruler', 'atrules', 'multilineComment', 'singlelineComment',
|
||||
'declaration', 'space', 'include'];
|
||||
// Spaces and comments:
|
||||
var SC = ['multilineComment', 'singlelineComment', 'space'];
|
||||
|
||||
var currentNode;
|
||||
// Sort order of properties:
|
||||
var order = this.getValue('sort-order');
|
||||
var syntax = this.getSyntax();
|
||||
// List of declarations that should be sorted:
|
||||
var sorted = [];
|
||||
// list of nodes that should be removed from parent node:
|
||||
var deleted = [];
|
||||
// List of spaces and comments that go before declaration/@-rule:
|
||||
var sc0 = [];
|
||||
// Value to search in sort order: either a declaration's property name
|
||||
// (e.g. `color`), or @-rule's special keyword (e.g. `$import`):
|
||||
var propertyName;
|
||||
|
||||
// Index to place the nodes that shouldn't be sorted
|
||||
var lastGroupIndex = order['...'] ? order['...'].group : Infinity;
|
||||
var lastPropertyIndex = order['...'] ? order['...'].prop : Infinity;
|
||||
|
||||
// Counters for loops:
|
||||
var i;
|
||||
var l;
|
||||
var j;
|
||||
var nl;
|
||||
|
||||
/**
|
||||
* Remove empty lines in space node.
|
||||
* @param {node} node Space node.
|
||||
*/
|
||||
var removeEmptyLines = function(node) {
|
||||
node.content = node.content.replace(/\n[\s\t\n\r]*\n/, '\n');
|
||||
};
|
||||
|
||||
/**
|
||||
* Check if there are any comments or spaces before
|
||||
* the declaration/@-rule.
|
||||
* @returns {Array} List of nodes with spaces and comments
|
||||
*/
|
||||
var checkSC0 = function() {
|
||||
// List of nodes with spaces and comments:
|
||||
var sc = [];
|
||||
// List of nodes that can be later deleted from parent node:
|
||||
var d = [];
|
||||
|
||||
for (; i < l; i++) {
|
||||
currentNode = node.get(i);
|
||||
// If there is no node left,
|
||||
// stop and do nothing with previously found spaces/comments:
|
||||
if (!currentNode) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// If the node is declaration or @-rule, stop and return all
|
||||
// found nodes with spaces and comments (if there are any):
|
||||
if (SC.indexOf(currentNode.type) === -1) break;
|
||||
|
||||
sc.push(currentNode);
|
||||
d.push(i);
|
||||
}
|
||||
|
||||
deleted = deleted.concat(d);
|
||||
|
||||
return sc;
|
||||
};
|
||||
|
||||
/**
|
||||
* Check if there are any comments or spaces after
|
||||
* the declaration/@-rule.
|
||||
* @returns {Array} List of nodes with spaces and comments
|
||||
* @private
|
||||
*/
|
||||
var checkSC1 = function() {
|
||||
// List of nodes with spaces and comments:
|
||||
var sc = [];
|
||||
// List of nodes that can be later deleted from parent node:
|
||||
var d = [];
|
||||
// Position of `\n` symbol inside a node with spaces:
|
||||
var lbIndex;
|
||||
|
||||
// Check every next node:
|
||||
for (; i < l; i++) {
|
||||
currentNode = node.get(i + 1);
|
||||
// If there is no node, or it is nor spaces neither comment, stop:
|
||||
if (!currentNode || SC.indexOf(currentNode.type) === -1) break;
|
||||
|
||||
if (currentNode.is('multilineComment') || currentNode.is('singlelineComment')) {
|
||||
sc.push(currentNode);
|
||||
d.push(i + 1);
|
||||
continue;
|
||||
}
|
||||
|
||||
lbIndex = currentNode.content.indexOf('\n');
|
||||
|
||||
// If there are any line breaks in a node with spaces, stop and
|
||||
// split the node into two: one with spaces before line break
|
||||
// and one with `\n` symbol and everything that goes after.
|
||||
// Combine the first one with declaration/@-rule's node:
|
||||
if (lbIndex > -1) {
|
||||
// TODO: Don't push an empty array
|
||||
var s = currentNode.content.substring(0, lbIndex);
|
||||
var space = gonzales.createNode({ type: 's', content: s });
|
||||
sc.push(space);
|
||||
currentNode.content = currentNode.content.substring(lbIndex);
|
||||
break;
|
||||
}
|
||||
|
||||
sc.push(currentNode);
|
||||
d.push(i + 1);
|
||||
}
|
||||
|
||||
deleted = deleted.concat(d);
|
||||
|
||||
return sc;
|
||||
};
|
||||
|
||||
/**
|
||||
* Combine declaration/@-rule's node with other relevant information:
|
||||
* property index, semicolon, spaces and comments.
|
||||
* @returns {Object} Extended node
|
||||
*/
|
||||
var extendNode = function() {
|
||||
currentNode = node.get(i);
|
||||
var nextNode = node.get(i + 1);
|
||||
// Object containing current node, all corresponding spaces,
|
||||
// comments and other information:
|
||||
var extendedNode;
|
||||
// Check if current node's property name is in sort order.
|
||||
// If it is, save information about its indices:
|
||||
var orderProperty = order[propertyName];
|
||||
|
||||
extendedNode = {
|
||||
i: i,
|
||||
node: currentNode,
|
||||
sc0: sc0,
|
||||
sc1: [],
|
||||
sc2: [],
|
||||
delim: []
|
||||
};
|
||||
|
||||
// If the declaration's property is in order's list, save its
|
||||
// group and property indices. Otherwise set them to 10000, so
|
||||
// declaration appears at the bottom of a sorted list:
|
||||
|
||||
extendedNode.groupIndex = orderProperty && orderProperty.group > -1 ?
|
||||
orderProperty.group : lastGroupIndex;
|
||||
extendedNode.propertyIndex = orderProperty && orderProperty.prop > -1 ?
|
||||
orderProperty.prop : lastPropertyIndex;
|
||||
|
||||
// Mark current node to remove it later from parent node:
|
||||
deleted.push(i);
|
||||
|
||||
extendedNode.sc1 = checkSC1();
|
||||
|
||||
if (extendedNode.sc1.length) {
|
||||
currentNode = node.get(i);
|
||||
nextNode = node.get(i + 1);
|
||||
}
|
||||
|
||||
// If there is `;` right after the declaration, save it with the
|
||||
// declaration and mark it for removing from parent node:
|
||||
if (currentNode && nextNode && nextNode.is('declarationDelimiter')) {
|
||||
extendedNode.delim.push(nextNode);
|
||||
deleted.push(i + 1);
|
||||
i++;
|
||||
|
||||
if (syntax === 'sass') return extendedNode;
|
||||
|
||||
// Save spaces and comments which follow right after the declaration
|
||||
// and mark them for removing from parent node:
|
||||
extendedNode.sc2 = checkSC1();
|
||||
}
|
||||
|
||||
return extendedNode;
|
||||
};
|
||||
|
||||
/**
|
||||
* Sorts properties alphabetically.
|
||||
*
|
||||
* @param {Object} a First extended node
|
||||
* @param {Object} b Second extended node
|
||||
* @returns {Number} `-1` if properties should go in order `a, b`. `1`
|
||||
* if properties should go in order `b, a`.
|
||||
*/
|
||||
var sortLeftovers = function(a, b) {
|
||||
var prefixes = ['-webkit-', '-moz-', '-ms-', '-o-', ''];
|
||||
var prefixesRegExp = /^(-webkit-|-moz-|-ms-|-o-)(.*)$/;
|
||||
|
||||
// Get property name (i.e. `color`, `-o-animation`):
|
||||
a = a.node.get(0).get(0).content;
|
||||
b = b.node.get(0).get(0).content;
|
||||
|
||||
// Get prefix and unprefixed part. For example:
|
||||
// ['-o-animation', '-o-', 'animation']
|
||||
// ['color', '', 'color']
|
||||
a = a.match(prefixesRegExp) || [a, '', a];
|
||||
b = b.match(prefixesRegExp) || [b, '', b];
|
||||
|
||||
if (a[2] !== b[2]) {
|
||||
// If unprefixed parts are different (i.e. `border` and
|
||||
// `color`), compare them:
|
||||
return a[2] < b[2] ? -1 : 1;
|
||||
} else {
|
||||
// If unprefixed parts are identical (i.e. `border` in
|
||||
// `-moz-border` and `-o-border`), compare prefixes (they
|
||||
// should go in the same order they are set in `prefixes` array):
|
||||
return prefixes.indexOf(a[1]) < prefixes.indexOf(b[1]) ? -1 : 1;
|
||||
}
|
||||
};
|
||||
|
||||
// TODO: Think it through!
|
||||
// Sort properties only inside blocks:
|
||||
if (!node.is('block')) return;
|
||||
|
||||
// Check every child node.
|
||||
// If it is declaration (property-value pair, e.g. `color: tomato`),
|
||||
// or @-rule (e.g. `@include nani`),
|
||||
// combine it with spaces, semicolon and comments and move them from
|
||||
// current node to a separate list for further sorting:
|
||||
for (i = 0, l = node.length; i < l; i++) {
|
||||
if (NODES.indexOf(node.get(i).type) === -1) continue;
|
||||
|
||||
// Save preceding spaces and comments, if there are any, and mark
|
||||
// them for removing from parent node:
|
||||
sc0 = checkSC0();
|
||||
if (!sc0) continue;
|
||||
|
||||
// If spaces/comments are the last nodes, stop and go to sorting:
|
||||
if (!node.get(i)) {
|
||||
deleted.splice(deleted.length - sc0.length, deleted.length + 1);
|
||||
break;
|
||||
}
|
||||
|
||||
// Check if the node needs to be sorted:
|
||||
// it should be a special @-rule (e.g. `@include`) or a declaration
|
||||
// with a valid property (e.g. `color` or `$width`).
|
||||
// If not, proceed with the next node:
|
||||
propertyName = null;
|
||||
// Look for includes:
|
||||
if (node.get(i).is('include')) {
|
||||
propertyName = '$include';
|
||||
} else {
|
||||
for (j = 0, nl = node.get(i).length; j < nl; j++) {
|
||||
currentNode = node.get(i).get(j);
|
||||
if (!currentNode) continue;
|
||||
|
||||
if (currentNode.is('property')) {
|
||||
propertyName = currentNode.get(0).is('variable') ?
|
||||
'$variable' : currentNode.get(0).content;
|
||||
break;
|
||||
} else if (currentNode.is('atkeyword') &&
|
||||
currentNode.get(0).content === 'import') { // Look for imports
|
||||
propertyName = '$import';
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// If current node is not property-value pair or import or include,
|
||||
// skip it and continue with the next node:
|
||||
if (!propertyName) {
|
||||
deleted.splice(deleted.length - sc0.length, deleted.length + 1);
|
||||
continue;
|
||||
}
|
||||
|
||||
// Make an extended node and move it to a separate list for further
|
||||
// sorting:
|
||||
sorted.push(extendNode());
|
||||
}
|
||||
|
||||
// Remove all nodes, that were moved to a `sorted` list, from parent node:
|
||||
for (i = deleted.length - 1; i > -1; i--) {
|
||||
node.content.splice(deleted[i], 1);
|
||||
}
|
||||
|
||||
// Sort declarations saved for sorting:
|
||||
sorted.sort(function(a, b) {
|
||||
// If a's group index is higher than b's group index, in a sorted
|
||||
// list a appears after b:
|
||||
if (a.groupIndex !== b.groupIndex) return a.groupIndex - b.groupIndex;
|
||||
|
||||
// If a and b belong to leftovers and `sort-order-fallback` option
|
||||
// is set to `abc`, sort properties alphabetically:
|
||||
if (a.groupIndex === lastGroupIndex &&
|
||||
_this.getValue('sort-order-fallback')) {
|
||||
return sortLeftovers(a, b);
|
||||
}
|
||||
|
||||
// If a and b have the same group index, and a's property index is
|
||||
// higher than b's property index, in a sorted list a appears after
|
||||
// b:
|
||||
if (a.propertyIndex !== b.propertyIndex) return a.propertyIndex - b.propertyIndex;
|
||||
|
||||
// If a and b have the same group index and the same property index,
|
||||
// in a sorted list they appear in the same order they were in
|
||||
// original array:
|
||||
return a.i - b.i;
|
||||
});
|
||||
|
||||
// Build all nodes back together. First go sorted declarations, then
|
||||
// everything else:
|
||||
if (sorted.length > 0) {
|
||||
for (i = sorted.length - 1, l = -1; i > l; i--) {
|
||||
currentNode = sorted[i];
|
||||
var prevNode = sorted[i - 1];
|
||||
sc0 = currentNode.sc0;
|
||||
var sc1 = currentNode.sc1;
|
||||
var sc2 = currentNode.sc2;
|
||||
|
||||
sc0.reverse().map(removeEmptyLines);
|
||||
sc1.reverse().map(removeEmptyLines);
|
||||
sc2.reverse().map(removeEmptyLines);
|
||||
|
||||
// Divide declarations from different groups with an empty line:
|
||||
if (prevNode && currentNode.groupIndex > prevNode.groupIndex) {
|
||||
if (sc0[0] && sc0[0].is('space') &&
|
||||
(this.syntax === 'sass' ||
|
||||
sc0[0].content.match(/\n/g) &&
|
||||
sc0[0].content.match(/\n/g).length < 2)) {
|
||||
sc0[0].content = '\n' + sc0[0].content;
|
||||
}
|
||||
}
|
||||
|
||||
for (j = 0, nl = sc2.length; j < nl; j++) {
|
||||
node.content.unshift(sc2[j]);
|
||||
}
|
||||
if (currentNode.delim.length > 0) {
|
||||
var delim = this.syntax === 'sass' ? '\n' : ';';
|
||||
var declDelim = gonzales.createNode({ type: 'declarationDelimiter', content: delim });
|
||||
node.content.unshift(declDelim);
|
||||
}
|
||||
for (j = 0, nl = sc1.length; j < nl; j++) {
|
||||
node.content.unshift(sc1[j]);
|
||||
}
|
||||
node.content.unshift(currentNode.node);
|
||||
|
||||
for (j = 0, nl = sc0.length; j < nl; j++) {
|
||||
node.content.unshift(sc0[j]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
+58
@@ -0,0 +1,58 @@
|
||||
var gonzales = require('gonzales-pe');
|
||||
|
||||
module.exports = {
|
||||
name: 'space-after-colon',
|
||||
|
||||
runBefore: 'block-indent',
|
||||
|
||||
syntax: ['css', 'less', 'sass', 'scss'],
|
||||
|
||||
accepts: {
|
||||
number: true,
|
||||
string: /^[ \t\n]*$/
|
||||
},
|
||||
|
||||
/**
|
||||
* Processes tree node.
|
||||
*
|
||||
* @param {node} node
|
||||
*/
|
||||
process: function(node) {
|
||||
if (!node.is('declaration')) return;
|
||||
|
||||
var value = this.getValue('space-after-colon');
|
||||
|
||||
for (var i = node.length; i--;) {
|
||||
if (!node.get(i).is('propertyDelimiter')) continue;
|
||||
|
||||
if (this.getSyntax() === 'sass' && !node.get(i - 1)) break;
|
||||
|
||||
// Remove any spaces after colon:
|
||||
if (node.get(i + 1).is('space')) node.remove(i + 1);
|
||||
// If the value set in config is not empty, add spaces:
|
||||
var space = gonzales.createNode({ type: 'space', content: value });
|
||||
if (value !== '') node.insert(i + 1, space);
|
||||
|
||||
break;
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Detects the value of an option at the tree node.
|
||||
*
|
||||
* @param {node} node
|
||||
*/
|
||||
detect: function(node) {
|
||||
if (!node.is('declaration')) return;
|
||||
|
||||
for (var i = node.length; i--;) {
|
||||
if (!node.get(i).is('propertyDelimiter')) continue;
|
||||
|
||||
if (node.get(i + 1).is('space')) {
|
||||
return node.get(i + 1).content;
|
||||
} else {
|
||||
return '';
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
Generated
Vendored
+60
@@ -0,0 +1,60 @@
|
||||
var gonzales = require('gonzales-pe');
|
||||
|
||||
module.exports = {
|
||||
name: 'space-after-combinator',
|
||||
|
||||
runBefore: 'block-indent',
|
||||
|
||||
syntax: ['css', 'less', 'sass', 'scss'],
|
||||
|
||||
accepts: {
|
||||
number: true,
|
||||
string: /^[ \t\n]*$/
|
||||
},
|
||||
|
||||
/**
|
||||
* Processes tree node.
|
||||
*
|
||||
* @param {node} node
|
||||
*/
|
||||
process: function(node) {
|
||||
if (!node.is('selector')) return;
|
||||
|
||||
var value = this.getValue('space-after-combinator');
|
||||
|
||||
node.forEach('simpleSelector', function(simpleSelector) {
|
||||
simpleSelector.forEach('combinator', function(combinator, i) {
|
||||
if (simpleSelector.get(i + 1).is('space')) {
|
||||
simpleSelector.get(i + 1).content = value;
|
||||
} else {
|
||||
var space = gonzales.createNode({ type: 'space', content: value });
|
||||
simpleSelector.insert(i + 1, space);
|
||||
}
|
||||
});
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* Detects the value of an option at the tree node.
|
||||
*
|
||||
* @param {node} node
|
||||
*/
|
||||
detect: function(node) {
|
||||
if (!node.is('selector')) return;
|
||||
|
||||
var variants = [];
|
||||
|
||||
node.forEach('simpleSelector', function(simpleSelector) {
|
||||
simpleSelector.forEach('combinator', function(combinator, i) {
|
||||
if (simpleSelector.get(i + 1).is('space')) {
|
||||
variants.push(simpleSelector.get(i + 1).content);
|
||||
} else {
|
||||
variants.push('');
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
return variants;
|
||||
}
|
||||
};
|
||||
|
||||
Generated
Vendored
+49
@@ -0,0 +1,49 @@
|
||||
var gonzales = require('gonzales-pe');
|
||||
|
||||
module.exports = {
|
||||
name: 'space-after-opening-brace',
|
||||
|
||||
runBefore: 'block-indent',
|
||||
|
||||
syntax: ['css', 'less', 'scss'],
|
||||
|
||||
accepts: {
|
||||
number: true,
|
||||
string: /^[ \t\n]*$/
|
||||
},
|
||||
|
||||
/**
|
||||
* Processes tree node.
|
||||
*
|
||||
* @param {node} node
|
||||
*/
|
||||
process: function(node) {
|
||||
// If found block node stop at the next one for space check
|
||||
if (!node.is('block') && !node.is('atrulers')) return;
|
||||
|
||||
var value = this.getValue('space-after-opening-brace');
|
||||
|
||||
if (node.first() &&
|
||||
node.first().is('space')) {
|
||||
node.first().content = value;
|
||||
} else if (value !== '') {
|
||||
var space = gonzales.createNode({ type: 'space', content: value });
|
||||
node.insert(0, space);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Detects the value of an option at the tree node.
|
||||
*
|
||||
* @param {node} node
|
||||
*/
|
||||
detect: function(node) {
|
||||
if (!node.is('block') && !node.is('atrulers')) return;
|
||||
|
||||
if (node.first().is('space')) {
|
||||
return node.first().content;
|
||||
} else {
|
||||
return '';
|
||||
}
|
||||
}
|
||||
};
|
||||
Generated
Vendored
+62
@@ -0,0 +1,62 @@
|
||||
var gonzales = require('gonzales-pe');
|
||||
|
||||
module.exports = {
|
||||
name: 'space-after-selector-delimiter',
|
||||
|
||||
runBefore: 'block-indent',
|
||||
|
||||
syntax: ['css', 'less', 'sass', 'scss'],
|
||||
|
||||
accepts: {
|
||||
number: true,
|
||||
string: /^[ \t\n]*$/
|
||||
},
|
||||
|
||||
/**
|
||||
* Processes tree node.
|
||||
*
|
||||
* @param {node} node
|
||||
*/
|
||||
process: function(node) {
|
||||
if (!node.is('selector')) return;
|
||||
|
||||
var value = this.getValue('space-after-selector-delimiter');
|
||||
|
||||
node.forEach('delimiter', function(delimiter, i) {
|
||||
var nextNode = node.get(i + 1);
|
||||
|
||||
if (nextNode.is('space')) {
|
||||
nextNode.content = value;
|
||||
} else if (nextNode.first().is('space')) {
|
||||
nextNode.first().content = value;
|
||||
} else {
|
||||
var space = gonzales.createNode({ type: 'space', content: value });
|
||||
nextNode.insert(0, space);
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* Detects the value of an option at the tree node.
|
||||
*
|
||||
* @param {node} node
|
||||
*/
|
||||
detect: function(node) {
|
||||
if (!node.is('selector')) return;
|
||||
|
||||
var variants = [];
|
||||
|
||||
node.forEach('delimiter', function(delimiter, i) {
|
||||
var nextNode = node.get(i + 1);
|
||||
if (nextNode && nextNode.is('space')) {
|
||||
variants.push(nextNode.content);
|
||||
} else if (nextNode.first() && nextNode.first().is('space')) {
|
||||
variants.push(nextNode.first().content);
|
||||
} else {
|
||||
variants.push('');
|
||||
}
|
||||
});
|
||||
|
||||
return variants;
|
||||
}
|
||||
};
|
||||
Generated
Vendored
+103
@@ -0,0 +1,103 @@
|
||||
var gonzales = require('gonzales-pe');
|
||||
|
||||
module.exports = (function() {
|
||||
var valueFromSettings;
|
||||
var blockIndent;
|
||||
|
||||
function getLastWhitespaceNode(node) {
|
||||
var lastNode = node.last();
|
||||
|
||||
if (!lastNode || !lastNode.content) return null;
|
||||
|
||||
if (lastNode.is('block')) return null;
|
||||
if (lastNode.is('space')) return lastNode;
|
||||
|
||||
return getLastWhitespaceNode(lastNode);
|
||||
}
|
||||
|
||||
function processBlock(x, level) {
|
||||
level = level || 0;
|
||||
|
||||
// XXX: Hack for braces
|
||||
if (x.is('braces') || x.is('id')) return;
|
||||
|
||||
x.forEach(function(node) {
|
||||
if (!node.is('block') &&
|
||||
!node.is('atrulers')) return processBlock(node, level);
|
||||
|
||||
level++;
|
||||
|
||||
var value = valueFromSettings;
|
||||
if (value.indexOf('\n') > -1) {
|
||||
// TODO: Check that it works for '' block indent value <tg>
|
||||
if (blockIndent) {
|
||||
value += new Array(level).join(blockIndent);
|
||||
}
|
||||
}
|
||||
|
||||
// If found block node stop at the next one for space check
|
||||
// For the pre-block node, find its last (the deepest) child
|
||||
var whitespaceNode = getLastWhitespaceNode(node);
|
||||
|
||||
// If it's spaces, modify this node
|
||||
// If it's something different from spaces, add a space node to the end
|
||||
if (whitespaceNode) {
|
||||
whitespaceNode.content = value;
|
||||
} else if (value !== '') {
|
||||
var space = gonzales.createNode({ type: 'space', content: value });
|
||||
node.content.push(space);
|
||||
}
|
||||
|
||||
processBlock(node, level);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
return {
|
||||
name: 'space-before-closing-brace',
|
||||
|
||||
runBefore: 'tab-size',
|
||||
|
||||
syntax: ['css', 'less', 'scss'],
|
||||
|
||||
accepts: {
|
||||
number: true,
|
||||
string: /^[ \t\n]*$/
|
||||
},
|
||||
|
||||
/**
|
||||
* Processes tree node.
|
||||
* @param {node} node
|
||||
*/
|
||||
process: function(node) {
|
||||
valueFromSettings = this.getValue('space-before-closing-brace');
|
||||
blockIndent = this.getValue('block-indent');
|
||||
|
||||
if (!node.is('stylesheet')) return;
|
||||
|
||||
processBlock(node);
|
||||
},
|
||||
|
||||
/**
|
||||
* Detects the value of an option at the tree node.
|
||||
*
|
||||
* @param {node} node
|
||||
*/
|
||||
detect: function(node) {
|
||||
if (!node.is('block') && !node.is('atrulers')) return;
|
||||
|
||||
var variants = [];
|
||||
|
||||
// For the block node, find its last (the deepest) child
|
||||
var whitespaceNode = getLastWhitespaceNode(node);
|
||||
if (whitespaceNode) {
|
||||
variants.push(whitespaceNode.content);
|
||||
} else {
|
||||
variants.push('');
|
||||
}
|
||||
|
||||
return variants;
|
||||
}
|
||||
};
|
||||
})();
|
||||
|
||||
Generated
Vendored
+60
@@ -0,0 +1,60 @@
|
||||
var gonzales = require('gonzales-pe');
|
||||
|
||||
module.exports = {
|
||||
name: 'space-before-colon',
|
||||
|
||||
runBefore: 'block-indent',
|
||||
|
||||
syntax: ['css', 'less', 'sass', 'scss'],
|
||||
|
||||
accepts: {
|
||||
number: true,
|
||||
string: /^[ \t\n]*$/
|
||||
},
|
||||
|
||||
/**
|
||||
* Processes tree node.
|
||||
*
|
||||
* @param {node} node
|
||||
*/
|
||||
process: function(node) {
|
||||
if (!node.is('declaration')) return;
|
||||
|
||||
var value = this.getValue('space-before-colon');
|
||||
var syntax = this.getSyntax();
|
||||
|
||||
node.forEach('propertyDelimiter', function(delimiter, i) {
|
||||
if (syntax === 'sass' && !node.get(i - 1)) return;
|
||||
|
||||
// Remove any spaces before colon:
|
||||
if (node.get(i - 1).is('space')) {
|
||||
node.remove(--i);
|
||||
}
|
||||
|
||||
// If the value set in config is not empty, add spaces:
|
||||
var space = gonzales.createNode({ type: 'space', content: value });
|
||||
if (value !== '') node.insert(i, space);
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* Detects the value of an option at the tree node.
|
||||
*
|
||||
* @param {node} node
|
||||
*/
|
||||
detect: function(node) {
|
||||
if (!node.is('declaration')) return;
|
||||
|
||||
var result;
|
||||
|
||||
node.forEach('propertyDelimiter', function(delimiter, i) {
|
||||
if (node.get(i - 1).is('space')) {
|
||||
result = node.get(i - 1).content;
|
||||
} else {
|
||||
result = '';
|
||||
}
|
||||
});
|
||||
|
||||
return result;
|
||||
}
|
||||
};
|
||||
Generated
Vendored
+68
@@ -0,0 +1,68 @@
|
||||
var gonzales = require('gonzales-pe');
|
||||
|
||||
module.exports = {
|
||||
name: 'space-before-combinator',
|
||||
|
||||
runBefore: 'block-indent',
|
||||
|
||||
syntax: ['css', 'less', 'sass', 'scss'],
|
||||
|
||||
accepts: {
|
||||
number: true,
|
||||
string: /^[ \t\n]*$/
|
||||
},
|
||||
|
||||
/**
|
||||
* Processes tree node.
|
||||
*
|
||||
* @param {node} node
|
||||
*/
|
||||
process: function(node) {
|
||||
if (!node.is('selector')) return;
|
||||
|
||||
var value = this.getValue('space-before-combinator');
|
||||
|
||||
node.forEach(function(simpleSelector) {
|
||||
var notFirst = false;
|
||||
|
||||
simpleSelector.forEach(function(n, i) {
|
||||
if (!n.is('space') && !n.is('combinator')) notFirst = true;
|
||||
|
||||
// If combinator is the first thing in selector,
|
||||
// do not add extra spaces:
|
||||
if (!n.is('combinator') || !notFirst) return;
|
||||
|
||||
if (simpleSelector.get(i - 1).is('space')) {
|
||||
simpleSelector.get(i - 1).content = value;
|
||||
} else {
|
||||
var space = gonzales.createNode({ type: 'space', content: value });
|
||||
simpleSelector.insert(i, space);
|
||||
}
|
||||
});
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* Detects the value of an option at the tree node.
|
||||
*
|
||||
* @param {node} node
|
||||
*/
|
||||
detect: function(node) {
|
||||
if (!node.is('selector')) return;
|
||||
|
||||
var variants = [];
|
||||
|
||||
node.forEach(function(simpleSelector) {
|
||||
simpleSelector.forEach('combinator', function(combinator, i) {
|
||||
if (simpleSelector.get(i - 1).is('space')) {
|
||||
variants.push(simpleSelector.get(i - 1).content);
|
||||
} else {
|
||||
variants.push('');
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
return variants;
|
||||
}
|
||||
};
|
||||
|
||||
Generated
Vendored
+99
@@ -0,0 +1,99 @@
|
||||
var gonzales = require('gonzales-pe');
|
||||
|
||||
module.exports = (function() {
|
||||
/**
|
||||
* Gets the last (the deepest) whitespace node.
|
||||
*
|
||||
* @param {node} node
|
||||
* @returns {node|undefined} If no whitespace node is found, returns
|
||||
* `undefined`
|
||||
*/
|
||||
function getLastWhitespaceNode(node) {
|
||||
if (typeof node !== 'object') return;
|
||||
if (node.is('space')) return node;
|
||||
|
||||
return getLastWhitespaceNode(node.last());
|
||||
}
|
||||
|
||||
return {
|
||||
name: 'space-before-opening-brace',
|
||||
|
||||
runBefore: 'block-indent',
|
||||
|
||||
syntax: ['css', 'less', 'scss'],
|
||||
|
||||
accepts: {
|
||||
number: true,
|
||||
string: /^[ \t\n]*$/
|
||||
},
|
||||
|
||||
/**
|
||||
* Processes tree node.
|
||||
*
|
||||
* @param {node} node
|
||||
*/
|
||||
process: function(node) {
|
||||
var value = this.getValue('space-before-opening-brace');
|
||||
|
||||
// XXX: Hack for braces
|
||||
if (node.is('braces') || node.is('id')) return;
|
||||
|
||||
node.forEach(function(block, i) {
|
||||
// If found block node stop at the next one for space check:
|
||||
if (!block.is('block') && !block.is('atrulers')) return;
|
||||
|
||||
// For the pre-block node, find its last (the deepest) child:
|
||||
// TODO: Exclude nodes with braces (for example, arguments)
|
||||
var previousNode = node.get(i - 1);
|
||||
var whitespaceNode = getLastWhitespaceNode(previousNode);
|
||||
|
||||
// If it's spaces, modify this node.
|
||||
// If it's something different from spaces, add a space node to
|
||||
// the end:
|
||||
if (whitespaceNode) {
|
||||
whitespaceNode.content = value;
|
||||
} else if (value !== '') {
|
||||
var space = gonzales.createNode({ type: 'space', content: value });
|
||||
if (previousNode && previousNode.is('atrulerq')) {
|
||||
previousNode.content.push(space);
|
||||
} else {
|
||||
node.insert(i, space);
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* Detects the value of an option at the tree node.
|
||||
*
|
||||
* @param {node} node
|
||||
*/
|
||||
detect: function(node) {
|
||||
var variants = [];
|
||||
|
||||
// XXX: Hack for braces
|
||||
if (node.is('braces') || node.is('id')) return [];
|
||||
|
||||
node.forEach(function(block, i) {
|
||||
// If found block node stop at the next one for space check:
|
||||
if (!block.is('block') && !block.is('atrulers')) return;
|
||||
|
||||
// For the pre-block node, find its last (the deepest) child:
|
||||
// TODO: Exclude nodes with braces (for example, arguments)
|
||||
var previousNode = node.get(i - 1);
|
||||
var whitespaceNode = getLastWhitespaceNode(previousNode);
|
||||
|
||||
// If it's spaces, modify this node.
|
||||
// If it's something different from spaces, add a space node to
|
||||
// the end:
|
||||
if (whitespaceNode) {
|
||||
variants.push(whitespaceNode.content);
|
||||
} else {
|
||||
variants.push('');
|
||||
}
|
||||
});
|
||||
|
||||
return variants;
|
||||
}
|
||||
};
|
||||
})();
|
||||
Generated
Vendored
+57
@@ -0,0 +1,57 @@
|
||||
var gonzales = require('gonzales-pe');
|
||||
|
||||
module.exports = {
|
||||
name: 'space-before-selector-delimiter',
|
||||
|
||||
runBefore: 'block-indent',
|
||||
|
||||
syntax: ['css', 'less', 'sass', 'scss'],
|
||||
|
||||
accepts: {
|
||||
number: true,
|
||||
string: /^[ \t\n]*$/
|
||||
},
|
||||
|
||||
/**
|
||||
* Processes tree node.
|
||||
*
|
||||
* @param {node} node
|
||||
*/
|
||||
process: function(node) {
|
||||
if (!node.is('selector')) return;
|
||||
|
||||
var value = this.getValue('space-before-selector-delimiter');
|
||||
|
||||
node.forEach('delimiter', function(delim, i) {
|
||||
var previousNode = node.get(i - 1);
|
||||
if (previousNode.last().is('space')) {
|
||||
previousNode.last().content = value;
|
||||
} else {
|
||||
var space = gonzales.createNode({ type: 'space', content: value });
|
||||
previousNode.content.push(space);
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* Detects the value of an option at the tree node.
|
||||
*
|
||||
* @param {node} node
|
||||
*/
|
||||
detect: function(node) {
|
||||
if (!node.is('selector')) return;
|
||||
|
||||
var variants = [];
|
||||
|
||||
node.forEach('delimiter', function(delim, i) {
|
||||
var previousNode = node.get(i - 1);
|
||||
if (previousNode.last().is('space')) {
|
||||
variants.push(previousNode.last().content);
|
||||
} else {
|
||||
variants.push('');
|
||||
}
|
||||
});
|
||||
|
||||
return variants;
|
||||
}
|
||||
};
|
||||
Generated
Vendored
+97
@@ -0,0 +1,97 @@
|
||||
var gonzales = require('gonzales-pe');
|
||||
|
||||
module.exports = (function() {
|
||||
function getDeclarationEnd(node, i) {
|
||||
for (;i < node.length; i++) {
|
||||
if (!node.get(i + 1) || typeof node.get(i + 1) === 'string') {
|
||||
return 0;
|
||||
} else if (node.get(i + 1).is('space')) {
|
||||
if (node.get(i + 1).content.indexOf('\n') > -1) {
|
||||
if (node.get(i + 2) && node.get(i + 2).is('declaration')) {
|
||||
return i;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
} else if (node.get(i + 2) && node.get(i + 2).is('multilineComment')) {
|
||||
if (node.get(i + 3) && node.get(i + 3).is('declaration')) {
|
||||
return i + 2;
|
||||
} else if (node.get(i + 3) && node.get(i + 3).is('space')) {
|
||||
if (node.get(i + 4) && node.get(i + 4).is('declaration')) {
|
||||
return i + 2;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
} else if (node.get(i + 2) && node.get(i + 2).is('declaration')) {
|
||||
return i;
|
||||
}
|
||||
} else if (node.get(i + 1).is('declaration')) {
|
||||
return i;
|
||||
} else if (node.get(i + 1).is('multilineComment')) {
|
||||
if (node.get(i + 2) && node.get(i + 2).is('declaration')) {
|
||||
return i + 1;
|
||||
} else if (node.get(i + 2) && node.get(i + 2).is('space')) {
|
||||
if (node.get(i + 3) && node.get(i + 3).is('declaration')) {
|
||||
return i + 1;
|
||||
}
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
name: 'space-between-declarations',
|
||||
|
||||
runBefore: 'block-indent',
|
||||
|
||||
syntax: ['css', 'less', 'scss'],
|
||||
|
||||
accepts: {
|
||||
number: true,
|
||||
string: /^[ \t\n]*$/
|
||||
},
|
||||
|
||||
/**
|
||||
* Processes tree node.
|
||||
*
|
||||
* @param {node} node
|
||||
*/
|
||||
process: function(node) {
|
||||
var value = this.getValue('space-between-declarations');
|
||||
|
||||
// TODO: Limit nodes to blocks, stylesheet, etc.
|
||||
// XXX: Hack for braces
|
||||
if (node.is('braces') || node.is('id')) return;
|
||||
|
||||
for (var i = 0, l = node.length; i < l; i++) {
|
||||
if (!node.get(i) || !node.get(i).is('declarationDelimiter')) continue;
|
||||
|
||||
// Grom user's point of view "declaration" includes semicolons
|
||||
// and comments placed on the same line.
|
||||
// So group those things together:
|
||||
var declarationEnd = getDeclarationEnd(node, i);
|
||||
if (!declarationEnd) {
|
||||
continue;
|
||||
} else {
|
||||
i = declarationEnd;
|
||||
}
|
||||
|
||||
var nextNode = node.get(i + 1);
|
||||
if (nextNode.is('space')) {
|
||||
nextNode.content = value;
|
||||
} else {
|
||||
i++;
|
||||
l++;
|
||||
var space = gonzales.createNode({ type: 'space', content: value });
|
||||
node.insert(i, space);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
})();
|
||||
+58
@@ -0,0 +1,58 @@
|
||||
module.exports = (function() {
|
||||
/**
|
||||
* Trim trailing spaces on each line.
|
||||
* @private
|
||||
* @param {String} string Spaceful string
|
||||
* @returns {String}
|
||||
*/
|
||||
function trim(string) {
|
||||
return string.replace(/[ \t]+\n/g, '\n');
|
||||
}
|
||||
|
||||
return {
|
||||
name: 'strip-spaces',
|
||||
|
||||
syntax: ['css', 'less', 'sass', 'scss'],
|
||||
|
||||
accepts: { boolean: [true] },
|
||||
|
||||
/**
|
||||
* Processes tree node.
|
||||
* @param {node} node
|
||||
*/
|
||||
process: function(node) {
|
||||
if (node.is('space')) {
|
||||
node.content = trim(node.content);
|
||||
} else if (node.is('stylesheet')) {
|
||||
var lastChild = node.last();
|
||||
if (lastChild.is('space')) {
|
||||
lastChild.content = trim(lastChild.content)
|
||||
.replace(/[ \t]+$/, '')
|
||||
.replace(/[\n]+/g, '\n');
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
detectDefault: true,
|
||||
|
||||
/**
|
||||
* Detects the value of an option at the tree node.
|
||||
* This option is treated as `true` by default, but any trailing space would invalidate it.
|
||||
*
|
||||
* @param {node} node
|
||||
*/
|
||||
detect: function(node) {
|
||||
if (node.is('space') &&
|
||||
node.content.match(/[ \t]\n/)) {
|
||||
return false;
|
||||
} else if (node.is('stylesheet')) {
|
||||
var lastChild = node.last();
|
||||
if (lastChild.is('space') &&
|
||||
lastChild.content !== '\n' &&
|
||||
lastChild.content.match(/^[ \n\t]+$/)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
})();
|
||||
+19
@@ -0,0 +1,19 @@
|
||||
module.exports = {
|
||||
name: 'tab-size',
|
||||
|
||||
runBefore: 'vendor-prefix-align',
|
||||
|
||||
syntax: ['css', 'less', 'sass', 'scss'],
|
||||
|
||||
accepts: { number: true },
|
||||
|
||||
/**
|
||||
* Processes tree node.
|
||||
*
|
||||
* @param {node} node
|
||||
*/
|
||||
process: function(node) {
|
||||
if (!node.is('space')) return;
|
||||
node.content = node.content.replace(/\t/, this.getValue('tab-size'));
|
||||
}
|
||||
};
|
||||
+82
@@ -0,0 +1,82 @@
|
||||
module.exports = {
|
||||
name: 'unitless-zero',
|
||||
|
||||
syntax: ['css', 'less', 'sass', 'scss'],
|
||||
|
||||
accepts: { boolean: [true] },
|
||||
|
||||
/**
|
||||
* Processes tree node.
|
||||
*
|
||||
* @param {node} node
|
||||
*/
|
||||
process: function(node) {
|
||||
var UNITS = ['cm', 'em', 'ex', 'pt', 'px'];
|
||||
|
||||
if (!node.is('value') && !node.is('braces')) return;
|
||||
|
||||
node.forEach(function(value) {
|
||||
if (typeof value === 'string') return;
|
||||
|
||||
if (value.is('dimension')) {
|
||||
var unit = value.first('ident').content;
|
||||
if (value.first('number').content === '0' &&
|
||||
UNITS.indexOf(unit) !== -1) {
|
||||
value.remove(1);
|
||||
}
|
||||
} else if (value.is('percentage')) {
|
||||
// XXX(tonyganch): There is a bug in Gonzales when in Less,
|
||||
// percentage's content is not wrapped as an array but actually
|
||||
// type of node's content is object. This bug has already been
|
||||
// fixed in newer versions of Gonzales so the issue should be
|
||||
// gone after update of dependencies and csscomb@4.0 release.
|
||||
// This hack is here as a hotfix for csscomb@3.1 and must be
|
||||
// removed once csscom@4.0 is released. See #389.
|
||||
var number;
|
||||
if (!Array.isArray(value.content) &&
|
||||
value.content.is('number')) {
|
||||
number = value.content;
|
||||
} else {
|
||||
number = value.first('number').content;
|
||||
}
|
||||
|
||||
if (number === '0') {
|
||||
value.type = 'number';
|
||||
value.content = number;
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* Detects the value of an option at the tree node.
|
||||
*
|
||||
* @param {node} node
|
||||
*/
|
||||
detect: function(node) {
|
||||
var result;
|
||||
|
||||
// If we see a zero with unit and it is not degree, then we don’t have an option
|
||||
|
||||
if (node.is('percentage') && node.first('number').content[1] === '0') {
|
||||
result = false;
|
||||
} else if (node.is('dimension') &&
|
||||
node.first('number').content === '0' &&
|
||||
node.first('ident').content !== 'deg') {
|
||||
result = false;
|
||||
}
|
||||
|
||||
// If we see a zero and previous node is not percentage or dimension, then we have an option
|
||||
if (node.is('number') &&
|
||||
node.content === '0' &&
|
||||
this._prev !== 'percentage' &&
|
||||
this._prev !== 'dimension') {
|
||||
result = true;
|
||||
}
|
||||
|
||||
// Store the previous nodeType
|
||||
this._prev = node.type;
|
||||
|
||||
return result;
|
||||
}
|
||||
};
|
||||
Generated
Vendored
+436
@@ -0,0 +1,436 @@
|
||||
var gonzales = require('gonzales-pe');
|
||||
|
||||
module.exports = (function() {
|
||||
// Vendor prefixes list:
|
||||
var PREFIXES = [
|
||||
'webkit',
|
||||
'khtml',
|
||||
'moz',
|
||||
'ms',
|
||||
'o'
|
||||
];
|
||||
|
||||
var oneline;
|
||||
|
||||
/**
|
||||
* Makes namespace from property name.
|
||||
*
|
||||
* @param {String} propertyName
|
||||
* @returns {String|undefined}
|
||||
*/
|
||||
function makeNamespace(propertyName) {
|
||||
var info = getPrefixInfo(propertyName);
|
||||
return info && info.baseName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates object which contains info about vendor prefix used in propertyName.
|
||||
*
|
||||
* @param {String} propertyName property name
|
||||
* @param {String} [namespace=''] namespace name
|
||||
* @param {Number} [extraSymbols=0] extra symbols count
|
||||
* @returns {Object|undefined}
|
||||
*/
|
||||
function getPrefixInfo(propertyName, namespace, extraSymbols) {
|
||||
var baseName = propertyName;
|
||||
var prefixLength = 0;
|
||||
|
||||
namespace = namespace || '';
|
||||
extraSymbols = extraSymbols || 0;
|
||||
|
||||
if (!propertyName) return;
|
||||
|
||||
PREFIXES.some(function(prefix) {
|
||||
prefix = '-' + prefix + '-';
|
||||
if (propertyName.indexOf(prefix) !== 0) return;
|
||||
|
||||
baseName = baseName.substr(prefix.length);
|
||||
prefixLength = prefix.length;
|
||||
|
||||
return true;
|
||||
});
|
||||
|
||||
return {
|
||||
id: namespace + baseName,
|
||||
baseName: baseName,
|
||||
prefixLength: prefixLength,
|
||||
extra: extraSymbols
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns extra indent for item in arguments
|
||||
*
|
||||
* @param {Array} nodes nodes to process
|
||||
* @returns {Number|undefined}
|
||||
*/
|
||||
function extraIndent(nodes) {
|
||||
if (!nodes || !nodes.length) return;
|
||||
|
||||
var node;
|
||||
var crPos;
|
||||
var tabPos;
|
||||
var result = 0;
|
||||
|
||||
for (var i = nodes.length; i--;) {
|
||||
node = nodes[i];
|
||||
|
||||
if (!node.content) {
|
||||
crPos = -1;
|
||||
} else {
|
||||
crPos = node.content.lastIndexOf('\n');
|
||||
tabPos = node.content.lastIndexOf('\t');
|
||||
if (tabPos > crPos) crPos = tabPos;
|
||||
}
|
||||
|
||||
if (crPos !== -1)
|
||||
oneline = false;
|
||||
|
||||
if (node.is('space')) {
|
||||
result += node.content.length - crPos - 1;
|
||||
if (crPos !== -1)
|
||||
break;
|
||||
}
|
||||
if (node.is('multilineComment')) {
|
||||
if (crPos === -1) {
|
||||
result += node.content.length + 4 /* comment symbols length */ ;
|
||||
} else {
|
||||
result += node.content.length - crPos + 1 /* only last comment symbols length - 1(not count \n)*/;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Wrapper for extra indent function for `property` node.
|
||||
*
|
||||
* @param {Array} nodes all nodes
|
||||
* @param {Number} i position in nodes array
|
||||
*/
|
||||
function extraIndentProperty(nodes, i) {
|
||||
var subset = [];
|
||||
while (i--) {
|
||||
if (!nodes.get(i) || nodes.get(i).is('declarationDelimiter'))
|
||||
break;
|
||||
subset.unshift(nodes.get(i));
|
||||
}
|
||||
return extraIndent(subset);
|
||||
}
|
||||
|
||||
/**
|
||||
* Wrapper for extra indent function for val-node.
|
||||
*
|
||||
* @param {Array} nodes all nodes
|
||||
* @param {Number} i position in nodes array
|
||||
*/
|
||||
function extraIndentVal(nodes, i) {
|
||||
var subset = [];
|
||||
var declaration = nodes.get(i);
|
||||
if (!declaration.is('declaration')) return;
|
||||
|
||||
for (var x = declaration.length; x--;) {
|
||||
if (!declaration.get(x).is('value')) continue;
|
||||
|
||||
x--;
|
||||
|
||||
while (!declaration.get(x).is('propertyDelimiter')) {
|
||||
subset.push(declaration.get(x));
|
||||
x--;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
return extraIndent(subset);
|
||||
}
|
||||
|
||||
/**
|
||||
* Walks across nodes, and call payload for every node that pass selector check.
|
||||
*
|
||||
* @param {Object} args arguments in form of:
|
||||
* {
|
||||
* node: {object} current node,
|
||||
* selector: {function} propertyName selector
|
||||
* payload: {function} work to do with gathered info
|
||||
* namespaceSelector: {function} selector for namespace
|
||||
* getExtraSymbols: {Number} extra symbols count
|
||||
* }
|
||||
*/
|
||||
function walk(args) {
|
||||
args.node.forEach(function(item, i) {
|
||||
var name = args.selector(item);
|
||||
var namespace = args.namespaceSelector && makeNamespace(args.namespaceSelector(item));
|
||||
var extraSymbols = args.getExtraSymbols(args.node, i);
|
||||
|
||||
var info = name && getPrefixInfo(name, namespace, extraSymbols);
|
||||
if (!info) return;
|
||||
args.payload(info, i);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns property name.
|
||||
* e.g.
|
||||
* for: 'color: #fff'
|
||||
* returns string: 'color'
|
||||
*
|
||||
* @param {node} node
|
||||
* @returns {String|undefined}
|
||||
*/
|
||||
function getPropertyName(node) {
|
||||
if (!node.is('declaration')) return;
|
||||
// TODO: Check that it's not a variable
|
||||
return node.get(0).get(0).content;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns property value name.
|
||||
* e.g.
|
||||
* for: '-webkit-transition: -webkit-transform 150ms linear'
|
||||
* returns string: '-webkit-transform', and
|
||||
* for: 'background: -webkit-linear-gradient(...)'
|
||||
* returns string: '-webkit-linear-gradient'
|
||||
*
|
||||
* @param {node} node
|
||||
* @returns {String|undefined}
|
||||
*/
|
||||
function getValName(node) {
|
||||
if (!node.is('declaration')) return;
|
||||
|
||||
var value = node.first('value');
|
||||
if (value.get(0).is('ident')) return value.get(0).content;
|
||||
if (value.get(0).is('function')) return value.get(0).get(0).content;
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates dict which contains info about items align.
|
||||
*
|
||||
* @param {Object} info,
|
||||
* @param {Object} dict,
|
||||
*/
|
||||
function updateDict(info, dict) {
|
||||
if (info.prefixLength === 0 && info.extra === 0) return;
|
||||
|
||||
var indent = dict[info.id] || { prefixLength: 0, extra: 0 };
|
||||
|
||||
dict[info.id] = indent.prefixLength + indent.extra > info.prefixLength + info.extra ?
|
||||
indent :
|
||||
{
|
||||
prefixLength: info.prefixLength,
|
||||
extra: info.extra,
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns string with correct number of spaces for info.baseName property.
|
||||
*
|
||||
* @param {Object} info,
|
||||
* @param {Object} dict,
|
||||
* @param {String} whitespaceNode
|
||||
* @returns {String}
|
||||
*/
|
||||
function updateIndent(info, dict, whitespaceNode) {
|
||||
var item = dict[info.id];
|
||||
if (!item)
|
||||
return whitespaceNode;
|
||||
|
||||
var crPos = whitespaceNode.lastIndexOf('\n');
|
||||
var tabPos = whitespaceNode.lastIndexOf('\t');
|
||||
if (tabPos > crPos) crPos = tabPos;
|
||||
|
||||
var firstPart = whitespaceNode.substr(0, crPos + 1 );
|
||||
var extraIndent = new Array(
|
||||
(item.prefixLength - info.prefixLength) +
|
||||
(item.extra - info.extra) +
|
||||
whitespaceNode.length - firstPart.length +
|
||||
1).join(' ');
|
||||
|
||||
return firstPart.concat(extraIndent);
|
||||
}
|
||||
|
||||
return {
|
||||
name: 'vendor-prefix-align',
|
||||
|
||||
syntax: ['css', 'less', 'sass', 'scss'],
|
||||
|
||||
accepts: { boolean: [true] },
|
||||
|
||||
/**
|
||||
* Processes tree node.
|
||||
*
|
||||
* @param {node} node
|
||||
*/
|
||||
process: function(node) {
|
||||
if (!node.is('block')) return;
|
||||
oneline = true;
|
||||
|
||||
var dict = {};
|
||||
|
||||
// Gathering Info
|
||||
walk({
|
||||
node: node,
|
||||
selector: getPropertyName,
|
||||
getExtraSymbols: extraIndentProperty,
|
||||
payload: function(info) {
|
||||
updateDict(info, dict);
|
||||
}
|
||||
});
|
||||
|
||||
walk({
|
||||
node: node,
|
||||
selector: getValName,
|
||||
namespaceSelector: getPropertyName,
|
||||
getExtraSymbols: extraIndentVal,
|
||||
payload: function(info) {
|
||||
updateDict(info, dict);
|
||||
}
|
||||
});
|
||||
|
||||
if (oneline && this.getSyntax() !== 'sass') return;
|
||||
|
||||
// Update nodes
|
||||
walk({
|
||||
node: node,
|
||||
selector: getValName,
|
||||
namespaceSelector: getPropertyName,
|
||||
getExtraSymbols: extraIndentVal,
|
||||
payload: function(info, i) {
|
||||
for (var x = node.get(i).length; x--;) {
|
||||
if (node.get(i).get(x).is('value')) break;
|
||||
}
|
||||
|
||||
if (!node.get(i).get(x - 1).is('space')) {
|
||||
var space = gonzales.createNode({ type: 'space', content: '' });
|
||||
node.get(i).insert(x, space);
|
||||
++x;
|
||||
}
|
||||
|
||||
node.get(i).get(x - 1).content = updateIndent(info, dict, node.get(i).get(x - 1).content);
|
||||
}
|
||||
});
|
||||
|
||||
if (this.getSyntax() === 'sass') return;
|
||||
|
||||
walk({
|
||||
node: node,
|
||||
selector: getPropertyName,
|
||||
getExtraSymbols: extraIndentProperty,
|
||||
payload: function(info, i) {
|
||||
// `node.get(i - 1)` can be either space or comment:
|
||||
var whitespaceNode = node.get(i - 1);
|
||||
if (!whitespaceNode) return;
|
||||
// If it's a comment, insert an empty space node:
|
||||
if (!whitespaceNode.is('space')) {
|
||||
whitespaceNode = gonzales.createNode({ type: 'space', content: '' });
|
||||
node.insert(i - 1, whitespaceNode);
|
||||
}
|
||||
whitespaceNode.content = updateIndent(info, dict, whitespaceNode.content);
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* Detects the value of an option at the tree node.
|
||||
*
|
||||
* @param {node} node
|
||||
*/
|
||||
detect: function(node) {
|
||||
if (!node.is('block')) return;
|
||||
|
||||
var result = {
|
||||
true: 0,
|
||||
false: 0
|
||||
};
|
||||
|
||||
var maybePrefix = false;
|
||||
var prevPrefixLength = false;
|
||||
var prevProp;
|
||||
var prevSum;
|
||||
var partialResult = null;
|
||||
|
||||
var getResult = function(node, sum, info, i) {
|
||||
var prop = info.baseName;
|
||||
|
||||
// If this is the last item in a row and we have a result, then catch it
|
||||
if (prop !== prevProp && partialResult !== null) {
|
||||
if (partialResult) {
|
||||
result.true++;
|
||||
} else {
|
||||
result.false++;
|
||||
}
|
||||
partialResult = null;
|
||||
}
|
||||
|
||||
if (prop === prevProp && info.prefixLength !== prevPrefixLength) {
|
||||
maybePrefix = true;
|
||||
} else {
|
||||
maybePrefix = false;
|
||||
}
|
||||
|
||||
if (maybePrefix && partialResult !== false) {
|
||||
// If there is prefixed prop, check if the prefixes are aligned,
|
||||
// but only if we hadn't already catched that it is false
|
||||
if (sum === prevSum) {
|
||||
partialResult = true;
|
||||
} else {
|
||||
partialResult = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (node.length === i + 3 && partialResult !== null) {
|
||||
// If we're at the last property and have a result, catch it
|
||||
if (partialResult) {
|
||||
result.true++;
|
||||
} else {
|
||||
result.false++;
|
||||
}
|
||||
}
|
||||
|
||||
prevPrefixLength = info.prefixLength;
|
||||
prevProp = prop;
|
||||
prevSum = sum;
|
||||
};
|
||||
|
||||
// Gathering Info
|
||||
walk({
|
||||
node: node,
|
||||
selector: getPropertyName,
|
||||
getExtraSymbols: extraIndentProperty,
|
||||
payload: function(info, i) {
|
||||
if (node.get(i - 1) && node.get(i - 1).content) {
|
||||
var sum = node.get(i - 1).content.
|
||||
replace(/^[ \t]*\n+/, '').length + info.prefixLength;
|
||||
getResult(node, sum, info, i);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
walk({
|
||||
node: node,
|
||||
selector: getValName,
|
||||
getExtraSymbols: extraIndentVal,
|
||||
payload: function(info, i) {
|
||||
for (var x = node.get(i).length; x--;) {
|
||||
if (node.get(i).get(x).is('value')) break;
|
||||
}
|
||||
|
||||
if (node.get(i).get(x - 1)) {
|
||||
var sum = node.get(i).get(x - 1).content
|
||||
.replace(/^[ \t]*\n+/, '').length + info.prefixLength;
|
||||
getResult(node, sum, info, i);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
if (result.true > 0 || result.false > 0) {
|
||||
if (result.true >= result.false) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
})();
|
||||
+104
@@ -0,0 +1,104 @@
|
||||
{
|
||||
"_args": [
|
||||
[
|
||||
"csscomb@3.1.8",
|
||||
"/mnt/data/Sites/anissabensalah.net/user/themes/anissabensalah"
|
||||
]
|
||||
],
|
||||
"_development": true,
|
||||
"_from": "csscomb@3.1.8",
|
||||
"_id": "csscomb@3.1.8",
|
||||
"_inBundle": false,
|
||||
"_integrity": "sha1-qKc4iE9Am6817JRhr8UuHHW9I6I=",
|
||||
"_location": "/csscomb",
|
||||
"_phantomChildren": {},
|
||||
"_requested": {
|
||||
"type": "version",
|
||||
"registry": true,
|
||||
"raw": "csscomb@3.1.8",
|
||||
"name": "csscomb",
|
||||
"escapedName": "csscomb",
|
||||
"rawSpec": "3.1.8",
|
||||
"saveSpec": null,
|
||||
"fetchSpec": "3.1.8"
|
||||
},
|
||||
"_requiredBy": [
|
||||
"/gulp-csscomb"
|
||||
],
|
||||
"_resolved": "https://registry.npmjs.org/csscomb/-/csscomb-3.1.8.tgz",
|
||||
"_spec": "3.1.8",
|
||||
"_where": "/mnt/data/Sites/anissabensalah.net/user/themes/anissabensalah",
|
||||
"author": {
|
||||
"name": "Mikhail Troshev",
|
||||
"email": "mishanga@yandex-team.ru"
|
||||
},
|
||||
"bin": {
|
||||
"csscomb": "./bin/csscomb"
|
||||
},
|
||||
"bugs": {
|
||||
"url": "https://github.com/csscomb/csscomb.js/issues"
|
||||
},
|
||||
"contributors": [
|
||||
{
|
||||
"name": "Igor Novak",
|
||||
"email": "bezengi@gmail.com"
|
||||
},
|
||||
{
|
||||
"name": "Roman Komarov",
|
||||
"email": "kizmarh@ya.ru"
|
||||
},
|
||||
{
|
||||
"name": "Denis Payase",
|
||||
"email": "lostsoul@yandex-team.ru"
|
||||
},
|
||||
{
|
||||
"name": "Mikhail Troshev",
|
||||
"email": "mishanga@yandex-team.ru",
|
||||
"url": "http://mishanga.pro/"
|
||||
},
|
||||
{
|
||||
"name": "Sergey Puzankov",
|
||||
"email": "puzankov@yandex-team.ru"
|
||||
}
|
||||
],
|
||||
"dependencies": {
|
||||
"commander": "2.0.0",
|
||||
"csscomb-core": "3.0.0-3.1",
|
||||
"gonzales-pe": "3.0.0-28",
|
||||
"vow": "0.4.4"
|
||||
},
|
||||
"description": "CSS coding style formatter",
|
||||
"devDependencies": {
|
||||
"jscs": "1.4.5",
|
||||
"jshint": "2.3.0",
|
||||
"jshint-groups": "0.5.3",
|
||||
"mocha": "1.20.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.10.0"
|
||||
},
|
||||
"files": [
|
||||
"bin",
|
||||
"config",
|
||||
"lib"
|
||||
],
|
||||
"homepage": "http://csscomb.com/",
|
||||
"main": "./lib/csscomb.js",
|
||||
"maintainers": [
|
||||
{
|
||||
"name": "Tony Ganch",
|
||||
"email": "tonyganch+github@gmail.com",
|
||||
"url": "http://tonyganch.com/"
|
||||
}
|
||||
],
|
||||
"name": "csscomb",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+https://github.com/csscomb/csscomb.js.git"
|
||||
},
|
||||
"scripts": {
|
||||
"test": "jshint-groups && ./node_modules/.bin/jscs . && node test/mocha",
|
||||
"test-cov": "rm -rf lib-cov && jscoverage lib lib-cov && TEST_COV=true node test/mocha > ./test/test-coverage.html"
|
||||
},
|
||||
"version": "3.1.8"
|
||||
}
|
||||
Reference in New Issue
Block a user