nav tabs on admin dashboard
This commit is contained in:
58
node_modules/csso/HISTORY.md
generated
vendored
58
node_modules/csso/HISTORY.md
generated
vendored
@@ -1,8 +1,60 @@
|
||||
## 2.3.2 (March 11, 2016)
|
||||
## 3.5.1 (June 7, 2018)
|
||||
|
||||
- Fix infinite loop on value parse (#328)
|
||||
- Bumped [CSSTree](https://github.com/csstree/csstree) to `1.0.0-alpha.29` (fixes some issues)
|
||||
|
||||
## 2.3.1 (January 6, 2016)
|
||||
## 3.5.0 (January 14, 2018)
|
||||
|
||||
- Migrated to [CSSTree](https://github.com/csstree/csstree) `1.0.0-alpha.27`
|
||||
|
||||
## 3.4.0 (November 3, 2017)
|
||||
|
||||
- Added percent sign removal for zero percentages for some properties that is safe (@RubaXa, #286)
|
||||
- Removed unit removal for zero values in `-ms-flex` due it breaks flex in IE10/11 (#362)
|
||||
- Improved performance of selectors comparison (@smelukov, #343)
|
||||
|
||||
## 3.3.1 (October 17, 2017)
|
||||
|
||||
- Fixed merge of `position` declarations when `sticky` fallback is using (@gruzzilkin, #356)
|
||||
|
||||
## 3.3.0 (October 12, 2017)
|
||||
|
||||
- Migrated to [CSSTree](https://github.com/csstree/csstree) `1.0.0-alpha25`
|
||||
- Changed AST format (see [CSSTree change log](https://github.com/csstree/csstree/blob/master/HISTORY.md) for details)
|
||||
- Fixed performance issue when generate CSS with source map (quadratic increase in time depending on the size of the CSS)
|
||||
|
||||
## 3.2.0 (September 10, 2017)
|
||||
|
||||
- Fixed named color compression to apply only when an identifier is guaranteed to be a color
|
||||
- Added lifting of `@keyframes` to the beginning of style sheet (chunk), but after `@charset` and `@import` rules
|
||||
- Added removal of `@keyframes`, `@media` and `@supports` with no prelude
|
||||
- Added removal of duplicate `@keyframes` (#202)
|
||||
- Added new option `forceMediaMerge` to force media rules merging. It's unsafe in general, but works fine in many cases. Use it on your own risk (#350)
|
||||
- Bumped `CSSTree` to `1.0.0-alpha23`
|
||||
|
||||
## 3.1.1 (April 25, 2017)
|
||||
|
||||
- Fixed crash on a number processing when it used not in a list (#335)
|
||||
|
||||
## 3.1.0 (April 24, 2017)
|
||||
|
||||
- Implemented optimisation for `none` keyword in `border` and `outline` properties (@zoobestik, #41)
|
||||
- Implemented replacing `rgba(x, x, x, 0)` to `transparent`
|
||||
- Fixed plus sign omitting for numbers following identifier, hex color, number or unicode range, since it can change the meaning of CSS (e.g. `calc(1px+2px)` has been optimized to `calc(1px2px)` before, now it stays the same)
|
||||
- Improved usage filtering for nested selectors (i.e. for `:nth-*()`, `:has()`, `:matches` and other pseudos)
|
||||
- Implemented `blacklist` filtering in usage (#334, see [Black list filtering](https://github.com/css/csso#black-list-filtering))
|
||||
- Improved white space removing, now white spaces are removing in the beginning and at the ending of sequences, and between stylesheet and block nodes
|
||||
- Bumped `CSSTree` to `1.0.0-alpha19`
|
||||
|
||||
## 3.0.1 (March 14, 2017)
|
||||
|
||||
- Fixed declaration merging when declaration contains an `!important`
|
||||
|
||||
## 3.0.0 (March 13, 2017)
|
||||
|
||||
- Migrated to [CSSTree](https://github.com/csstree/csstree) as AST backend and exposed its API behind `syntax` property
|
||||
- Extracted CLI into standalone package [css/csso-cli](https://github.com/css/csso-cli)
|
||||
|
||||
## 2.3.1 (January 6, 2017)
|
||||
|
||||
- Added `\0` IE hack support (#320)
|
||||
|
||||
|
||||
2
node_modules/csso/LICENSE
generated
vendored
2
node_modules/csso/LICENSE
generated
vendored
@@ -1,4 +1,4 @@
|
||||
Copyright (C) 2011-2015 by Sergey Kryzhanovsky
|
||||
Copyright (C) 2011-2017 by Sergey Kryzhanovsky
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
|
||||
563
node_modules/csso/README.md
generated
vendored
563
node_modules/csso/README.md
generated
vendored
@@ -9,102 +9,258 @@ CSSO (CSS Optimizer) is a CSS minifier. It performs three sort of transformation
|
||||
[](https://www.yandex.com/)
|
||||
[](https://www.avito.ru/)
|
||||
|
||||
## Usage
|
||||
## Ready to use
|
||||
|
||||
- [Web interface](http://css.github.io/csso/csso.html)
|
||||
- [csso-cli](https://github.com/css/csso-cli) – command line interface
|
||||
- [gulp-csso](https://github.com/ben-eb/gulp-csso) – `Gulp` plugin
|
||||
- [grunt-csso](https://github.com/t32k/grunt-csso) – `Grunt` plugin
|
||||
- [broccoli-csso](https://github.com/sindresorhus/broccoli-csso) – `Broccoli` plugin
|
||||
- [postcss-csso](https://github.com/lahmatiy/postcss-csso) – `PostCSS` plugin
|
||||
- [csso-loader](https://github.com/sandark7/csso-loader) – `webpack` loader
|
||||
- [csso-webpack-plugin](https://github.com/zoobestik/csso-webpack-plugin) – `webpack` plugin
|
||||
|
||||
## Install
|
||||
|
||||
```
|
||||
npm install -g csso
|
||||
npm install csso
|
||||
```
|
||||
|
||||
Or try out CSSO [right in your browser](http://css.github.io/csso/csso.html) (web interface).
|
||||
## API
|
||||
|
||||
### Runners
|
||||
<!-- MarkdownTOC -->
|
||||
|
||||
- Gulp: [gulp-csso](https://github.com/ben-eb/gulp-csso)
|
||||
- Grunt: [grunt-csso](https://github.com/t32k/grunt-csso)
|
||||
- Broccoli: [broccoli-csso](https://github.com/sindresorhus/broccoli-csso)
|
||||
- PostCSS: [postcss-csso](https://github.com/lahmatiy/postcss-csso)
|
||||
- Webpack: [csso-loader](https://github.com/sandark7/csso-loader)
|
||||
- [minify\(source\[, options\]\)](#minifysource-options)
|
||||
- [minifyBlock\(source\[, options\]\)](#minifyblocksource-options)
|
||||
- [compress\(ast\[, options\]\)](#compressast-options)
|
||||
- [Source maps](#source-maps)
|
||||
- [Usage data](#usage-data)
|
||||
- [White list filtering](#white-list-filtering)
|
||||
- [Black list filtering](#black-list-filtering)
|
||||
- [Scopes](#scopes)
|
||||
- [Debugging](#debugging)
|
||||
|
||||
### Command line
|
||||
<!-- /MarkdownTOC -->
|
||||
|
||||
Basic usage:
|
||||
|
||||
```js
|
||||
var csso = require('csso');
|
||||
|
||||
var minifiedCss = csso.minify('.test { color: #ff0000; }').css;
|
||||
|
||||
console.log(minifiedCss);
|
||||
// .test{color:red}
|
||||
```
|
||||
csso [input] [output] [options]
|
||||
|
||||
CSSO is based on [CSSTree](https://github.com/csstree/csstree) to parse CSS into AST, AST traversal and to generate AST back to CSS. All `CSSTree` API is available behind `syntax` field. You may minify CSS step by step:
|
||||
|
||||
```js
|
||||
var csso = require('csso');
|
||||
var ast = csso.syntax.parse('.test { color: #ff0000; }');
|
||||
var compressedAst = csso.compress(ast).ast;
|
||||
var minifiedCss = csso.syntax.generate(compressedAst);
|
||||
|
||||
console.log(minifiedCss);
|
||||
// .test{color:red}
|
||||
```
|
||||
|
||||
> Warning: CSSO uses early versions of CSSTree that still in active development. CSSO doesn't guarantee API behind `syntax` field or AST format will not change in future releases of CSSO, since it's subject to change in CSSTree. Be carefull with CSSO updates if you use `syntax` API until this warning removal.
|
||||
|
||||
### minify(source[, options])
|
||||
|
||||
Minify `source` CSS passed as `String`.
|
||||
|
||||
```js
|
||||
var result = csso.minify('.test { color: #ff0000; }', {
|
||||
restructure: false, // don't change CSS structure, i.e. don't merge declarations, rulesets etc
|
||||
debug: true // show additional debug information:
|
||||
// true or number from 1 to 3 (greater number - more details)
|
||||
});
|
||||
|
||||
console.log(result.css);
|
||||
// > .test{color:red}
|
||||
```
|
||||
|
||||
Returns an object with properties:
|
||||
|
||||
- css `String` – resulting CSS
|
||||
- map `Object` – instance of [`SourceMapGenerator`](https://github.com/mozilla/source-map#sourcemapgenerator) or `null`
|
||||
|
||||
Options:
|
||||
|
||||
--comments <value> Comments to keep: exclamation (default), first-exclamation or none
|
||||
--debug [level] Output intermediate state of CSS during compression
|
||||
-h, --help Output usage information
|
||||
-i, --input <filename> Input file
|
||||
--input-map <source> Input source map: none, auto (default) or <filename>
|
||||
-m, --map <destination> Generate source map: none (default), inline, file or <filename>
|
||||
-o, --output <filename> Output file (result outputs to stdout if not set)
|
||||
--restructure-off Turns structure minimization off
|
||||
--stat Output statistics in stderr
|
||||
-u, --usage <filenane> Usage data file
|
||||
-v, --version Output version
|
||||
- sourceMap
|
||||
|
||||
Type: `Boolean`
|
||||
Default: `false`
|
||||
|
||||
Generate a source map when `true`.
|
||||
|
||||
- filename
|
||||
|
||||
Type: `String`
|
||||
Default: `'<unknown>'`
|
||||
|
||||
Filename of input CSS, uses for source map generation.
|
||||
|
||||
- debug
|
||||
|
||||
Type: `Boolean`
|
||||
Default: `false`
|
||||
|
||||
Output debug information to `stderr`.
|
||||
|
||||
- beforeCompress
|
||||
|
||||
Type: `function(ast, options)` or `Array<function(ast, options)>` or `null`
|
||||
Default: `null`
|
||||
|
||||
Called right after parse is run.
|
||||
|
||||
- afterCompress
|
||||
|
||||
Type: `function(compressResult, options)` or `Array<function(compressResult, options)>` or `null`
|
||||
Default: `null`
|
||||
|
||||
Called right after [`compress()`](#compressast-options) is run.
|
||||
|
||||
- Other options are the same as for [`compress()`](#compressast-options) function.
|
||||
|
||||
### minifyBlock(source[, options])
|
||||
|
||||
The same as `minify()` but for list of declarations. Usually it's a `style` attribute value.
|
||||
|
||||
```js
|
||||
var result = csso.minifyBlock('color: rgba(255, 0, 0, 1); color: #ff0000');
|
||||
|
||||
console.log(result.css);
|
||||
// > color:red
|
||||
```
|
||||
|
||||
Some examples:
|
||||
### compress(ast[, options])
|
||||
|
||||
```
|
||||
> csso in.css
|
||||
...output result in stdout...
|
||||
Does the main task – compress an AST.
|
||||
|
||||
> csso in.css --output out.css
|
||||
> NOTE: `compress()` performs AST compression by transforming input AST by default (since AST cloning is expensive and needed in rare cases). Use `clone` option with truthy value in case you want to keep input AST untouched.
|
||||
|
||||
> echo '.test { color: #ff0000; }' | csso
|
||||
.test{color:red}
|
||||
Returns an object with properties:
|
||||
|
||||
> cat source1.css source2.css | csso | gzip -9 -c > production.css.gz
|
||||
```
|
||||
- ast `Object` – resulting AST
|
||||
|
||||
Options:
|
||||
|
||||
- restructure
|
||||
|
||||
Type: `Boolean`
|
||||
Default: `true`
|
||||
|
||||
Disable or enable a structure optimisations.
|
||||
|
||||
- forceMediaMerge
|
||||
|
||||
Type: `Boolean`
|
||||
Default: `false`
|
||||
|
||||
Enables merging of `@media` rules with the same media query by splitted by other rules. The optimisation is unsafe in general, but should work fine in most cases. Use it on your own risk.
|
||||
|
||||
- clone
|
||||
|
||||
Type: `Boolean`
|
||||
Default: `false`
|
||||
|
||||
Transform a copy of input AST if `true`. Useful in case of AST reuse.
|
||||
|
||||
- comments
|
||||
|
||||
Type: `String` or `Boolean`
|
||||
Default: `true`
|
||||
|
||||
Specify what comments to leave:
|
||||
|
||||
- `'exclamation'` or `true` – leave all exclamation comments (i.e. `/*! .. */`)
|
||||
- `'first-exclamation'` – remove every comment except first one
|
||||
- `false` – remove all comments
|
||||
|
||||
- usage
|
||||
|
||||
Type: `Object` or `null`
|
||||
Default: `null`
|
||||
|
||||
Usage data for advanced optimisations (see [Usage data](#usage-data) for details)
|
||||
|
||||
- logger
|
||||
|
||||
Type: `Function` or `null`
|
||||
Default: `null`
|
||||
|
||||
Function to track every step of transformation.
|
||||
|
||||
### Source maps
|
||||
|
||||
Source map doesn't generate by default. To generate map use `--map` CLI option, that can be:
|
||||
To get a source map set `true` for `sourceMap` option. Additianaly `filename` option can be passed to specify source file. When `sourceMap` option is `true`, `map` field of result object will contain a [`SourceMapGenerator`](https://github.com/mozilla/source-map#sourcemapgenerator) instance. This object can be mixed with another source map or translated to string.
|
||||
|
||||
- `none` (default) – don't generate source map
|
||||
- `inline` – add source map into result CSS (via `/*# sourceMappingURL=application/json;base64,... */`)
|
||||
- `file` – write source map into file with same name as output file, but with `.map` extension (in this case `--output` option is required)
|
||||
- any other values treat as filename for generated source map
|
||||
```js
|
||||
var csso = require('csso');
|
||||
var css = fs.readFileSync('path/to/my.css', 'utf8');
|
||||
var result = csso.minify(css, {
|
||||
filename: 'path/to/my.css', // will be added to source map as reference to source file
|
||||
sourceMap: true // generate source map
|
||||
});
|
||||
|
||||
Examples:
|
||||
console.log(result);
|
||||
// { css: '...minified...', map: SourceMapGenerator {} }
|
||||
|
||||
```
|
||||
> csso my.css --map inline
|
||||
> csso my.css --output my.min.css --map file
|
||||
> csso my.css --output my.min.css --map maps/my.min.map
|
||||
console.log(result.map.toString());
|
||||
// '{ .. source map content .. }'
|
||||
```
|
||||
|
||||
Use `--input-map` option to specify input source map if needed. Possible values for option:
|
||||
Example of generating source map with respect of source map from input CSS:
|
||||
|
||||
- `auto` (default) - attempt to fetch input source map by follow steps:
|
||||
- try to fetch inline map from input
|
||||
- try to fetch source map filename from input and read its content
|
||||
- (when `--input` is specified) check file with same name as input file but with `.map` extension exists and read its content
|
||||
- `none` - don't use input source map; actually it's using to disable `auto`-fetching
|
||||
- any other values treat as filename for input source map
|
||||
```js
|
||||
var require('source-map');
|
||||
var csso = require('csso');
|
||||
var inputFile = 'path/to/my.css';
|
||||
var input = fs.readFileSync(inputFile, 'utf8');
|
||||
var inputMap = input.match(/\/\*# sourceMappingURL=(\S+)\s*\*\/\s*$/);
|
||||
var output = csso.minify(input, {
|
||||
filename: inputFile,
|
||||
sourceMap: true
|
||||
});
|
||||
|
||||
Generally you shouldn't care about input source map since defaults behaviour (`auto`) covers most use cases.
|
||||
// apply input source map to output
|
||||
if (inputMap) {
|
||||
output.map.applySourceMap(
|
||||
new SourceMapConsumer(inputMap[1]),
|
||||
inputFile
|
||||
)
|
||||
}
|
||||
|
||||
> NOTE: Input source map is using only if output source map is generating.
|
||||
// result CSS with source map
|
||||
console.log(
|
||||
output.css +
|
||||
'/*# sourceMappingURL=data:application/json;base64,' +
|
||||
new Buffer(output.map.toString()).toString('base64') +
|
||||
' */'
|
||||
);
|
||||
```
|
||||
|
||||
### Usage data
|
||||
|
||||
`CSSO` can use data about how `CSS` is using for better compression. File with this data (`JSON` format) can be set using `--usage` option. Usage data may contain follow sections:
|
||||
`CSSO` can use data about how `CSS` is used in a markup for better compression. File with this data (`JSON`) can be set using `usage` option. Usage data may contain following sections:
|
||||
|
||||
- `blacklist` – a set of black lists (see [Black list filtering](#black-list-filtering))
|
||||
- `tags` – white list of tags
|
||||
- `ids` – white list of ids
|
||||
- `classes` – white list of classes
|
||||
- `scopes` – groups of classes which never used with classes from other groups on single element
|
||||
- `scopes` – groups of classes which never used with classes from other groups on the same element
|
||||
|
||||
All sections are optional. Value of `tags`, `ids` and `classes` should be array of strings, value of `scopes` should be an array of arrays of strings. Other values are ignoring.
|
||||
All sections are optional. Value of `tags`, `ids` and `classes` should be an array of a string, value of `scopes` should be an array of arrays of strings. Other values are ignoring.
|
||||
|
||||
#### Selector filtering
|
||||
#### White list filtering
|
||||
|
||||
`tags`, `ids` and `classes` are using on clean stage to filter selectors that contains something that not in list. Selectors are filtering only by those kind of simple selector which white list is specified. For example, if only `tags` list is specified then type selectors are checking, and if selector hasn't any type selector (or even any type selector) it isn't filter.
|
||||
`tags`, `ids` and `classes` are using on clean stage to filter selectors that contain something not in the lists. Selectors are filtering only by those kind of simple selector which white list is specified. For example, if only `tags` list is specified then type selectors are checking, and if all type selectors in selector present in list or selector has no any type selector it isn't filter.
|
||||
|
||||
> `ids` and `classes` names are case sensitive, `tags` – is not.
|
||||
> `ids` and `classes` are case sensitive, `tags` – is not.
|
||||
|
||||
Input CSS:
|
||||
|
||||
@@ -122,15 +278,59 @@ Usage data:
|
||||
}
|
||||
```
|
||||
|
||||
Result CSS:
|
||||
Resulting CSS:
|
||||
|
||||
```css
|
||||
*{color:green}ul,li{color:blue}ul.foo{color:red}
|
||||
```
|
||||
|
||||
Filtering performs for nested selectors too. `:not()` pseudos content is ignoring since the result of matching is unpredictable. Example for the same usage data as above:
|
||||
|
||||
```css
|
||||
:nth-child(2n of ul, ol) { color: red }
|
||||
:nth-child(3n + 1 of img) { color: yellow }
|
||||
:not(div, ol, ul) { color: green }
|
||||
:has(:matches(ul, ol), ul, ol) { color: blue }
|
||||
```
|
||||
|
||||
Turns into:
|
||||
|
||||
```css
|
||||
:nth-child(2n of ul){color:red}:not(div,ol,ul){color:green}:has(:matches(ul),ul){color:blue}
|
||||
```
|
||||
|
||||
#### Black list filtering
|
||||
|
||||
Black list filtering performs the same as white list filtering, but filters things that mentioned in the lists. `blacklist` can contain the lists `tags`, `ids` and `classes`.
|
||||
|
||||
Black list has a higher priority, so when something mentioned in the white list and in the black list then white list occurrence is ignoring. The `:not()` pseudos content ignoring as well.
|
||||
|
||||
```css
|
||||
* { color: green; }
|
||||
ul, ol, li { color: blue; }
|
||||
UL.foo, li.bar { color: red; }
|
||||
```
|
||||
|
||||
Usage data:
|
||||
|
||||
```json
|
||||
{
|
||||
"blacklist": {
|
||||
"tags": ["ul"]
|
||||
},
|
||||
"tags": ["ul", "LI"]
|
||||
}
|
||||
```
|
||||
|
||||
Resulting CSS:
|
||||
|
||||
```css
|
||||
*{color:green}li{color:blue}li.bar{color:red}
|
||||
```
|
||||
|
||||
#### Scopes
|
||||
|
||||
Scopes is designed for CSS scope isolation solutions such as [css-modules](https://github.com/css-modules/css-modules). Scopes are similar to namespaces and defines lists of class names that exclusively used on some markup. This information allows the optimizer to move rulesets more agressive. Since it assumes selectors from different scopes can't to be matched on the same element. That leads to better ruleset merging.
|
||||
Scopes is designed for CSS scope isolation solutions such as [css-modules](https://github.com/css-modules/css-modules). Scopes are similar to namespaces and define lists of class names that exclusively used on some markup. This information allows the optimizer to move rules more agressive. Since it assumes selectors from different scopes don't match for the same element. This can improve rule merging.
|
||||
|
||||
Suppose we have a file:
|
||||
|
||||
@@ -142,13 +342,13 @@ Suppose we have a file:
|
||||
.module2-qux { font-size: 1.5em; background: yellow; width: 50px; }
|
||||
```
|
||||
|
||||
It can be assumed that first two rules never used with second two on the same markup. But we can't know that for sure without markup. The optimizer doesn't know it eather and will perform safe transformations only. The result will be the same as input but with no spaces and some semicolons:
|
||||
It can be assumed that first two rules are never used with the second two on the same markup. But we can't say that for sure without a markup review. The optimizer doesn't know it either and will perform safe transformations only. The result will be the same as input but with no spaces and some semicolons:
|
||||
|
||||
```css
|
||||
.module1-foo{color:red}.module1-bar{font-size:1.5em;background:#ff0}.module2-baz{color:red}.module2-qux{font-size:1.5em;background:#ff0;width:50px}
|
||||
```
|
||||
|
||||
But with usage data `CSSO` can get better output. If follow usage data is provided:
|
||||
With usage data `CSSO` can produce better output. If follow usage data is provided:
|
||||
|
||||
```json
|
||||
{
|
||||
@@ -159,249 +359,18 @@ But with usage data `CSSO` can get better output. If follow usage data is provid
|
||||
}
|
||||
```
|
||||
|
||||
New result (29 bytes extra saving):
|
||||
The result will be (29 bytes extra saving):
|
||||
|
||||
```css
|
||||
.module1-foo,.module2-baz{color:red}.module1-bar,.module2-qux{font-size:1.5em;background:#ff0}.module2-qux{width:50px}
|
||||
```
|
||||
|
||||
If class name doesn't specified in `scopes` it belongs to default "scope". `scopes` doesn't affect `classes`. If class name presents in `scopes` but missed in `classes` (both sections specified) it will be filtered.
|
||||
If class name isn't mentioned in the `scopes` it belongs to default scope. `scopes` data doesn't affect `classes` whitelist. If class name mentioned in `scopes` but missed in `classes` (both sections are specified) it will be filtered.
|
||||
|
||||
Note that class name can't be specified in several scopes. Also selector can't has classes from different scopes. In both cases an exception throws.
|
||||
Note that class name can't be set for several scopes. Also a selector can't have class names from different scopes. In both cases an exception will thrown.
|
||||
|
||||
Currently the optimizer doesn't care about out-of-bounds selectors order changing safety (i.e. selectors that may be matched to elements with no class name of scope, e.g. `.scope div` or `.scope ~ :last-child`) since assumes scoped CSS modules doesn't relay on it's order. It may be fix in future if to be an issue.
|
||||
Currently the optimizer doesn't care about changing order safety for out-of-bounds selectors (i.e. selectors that match to elements without class name, e.g. `.scope div` or `.scope ~ :last-child`). It assumes that scoped CSS modules doesn't relay on it's order. It may be fix in future if to be an issue.
|
||||
|
||||
### API
|
||||
### Debugging
|
||||
|
||||
```js
|
||||
var csso = require('csso');
|
||||
|
||||
var compressedCss = csso.minify('.test { color: #ff0000; }').css;
|
||||
|
||||
console.log(compressedCss);
|
||||
// .test{color:red}
|
||||
```
|
||||
|
||||
You may minify CSS by yourself step by step:
|
||||
|
||||
```js
|
||||
var ast = csso.parse('.test { color: #ff0000; }');
|
||||
var compressResult = csso.compress(ast);
|
||||
var compressedCss = csso.translate(compressResult.ast);
|
||||
|
||||
console.log(compressedCss);
|
||||
// .test{color:red}
|
||||
```
|
||||
|
||||
Working with source maps:
|
||||
|
||||
```js
|
||||
var css = fs.readFileSync('path/to/my.css', 'utf8');
|
||||
var result = csso.minify(css, {
|
||||
filename: 'path/to/my.css', // will be added to source map as reference to source file
|
||||
sourceMap: true // generate source map
|
||||
});
|
||||
|
||||
console.log(result);
|
||||
// { css: '...minified...', map: SourceMapGenerator {} }
|
||||
|
||||
console.log(result.map.toString());
|
||||
// '{ .. source map content .. }'
|
||||
```
|
||||
|
||||
#### minify(source[, options])
|
||||
|
||||
Minify `source` CSS passed as `String`.
|
||||
|
||||
Options:
|
||||
|
||||
- sourceMap `Boolean` - generate source map if `true`
|
||||
- filename `String` - filename of input, uses for source map
|
||||
- debug `Boolean` - output debug information to `stderr`
|
||||
- beforeCompress `function|array<function>` - called right after parse is run. Callbacks arguments are `ast, options`.
|
||||
- afterCompress `function|array<function>` - called right after compress is run. Callbacks arguments are `compressResult, options`.
|
||||
- other options are the same as for `compress()`
|
||||
|
||||
Returns an object with properties:
|
||||
|
||||
- css `String` – resulting CSS
|
||||
- map `Object` – instance of `SourceMapGenerator` or `null`
|
||||
|
||||
```js
|
||||
var result = csso.minify('.test { color: #ff0000; }', {
|
||||
restructure: false, // don't change CSS structure, i.e. don't merge declarations, rulesets etc
|
||||
debug: true // show additional debug information:
|
||||
// true or number from 1 to 3 (greater number - more details)
|
||||
});
|
||||
|
||||
console.log(result.css);
|
||||
// > .test{color:red}
|
||||
```
|
||||
|
||||
#### minifyBlock(source[, options])
|
||||
|
||||
The same as `minify()` but for style block. Usualy it's a `style` attribute content.
|
||||
|
||||
```js
|
||||
var result = csso.minifyBlock('color: rgba(255, 0, 0, 1); color: #ff0000').css;
|
||||
|
||||
console.log(result.css);
|
||||
// > color:red
|
||||
```
|
||||
|
||||
#### parse(source[, options])
|
||||
|
||||
Parse CSS to AST.
|
||||
|
||||
> NOTE: Currenly parser omit redundant separators, spaces and comments (except exclamation comments, i.e. `/*! comment */`) on AST build, since those things are removing by compressor anyway.
|
||||
|
||||
Options:
|
||||
|
||||
- context `String` – parsing context, useful when some part of CSS is parsing (see below)
|
||||
- positions `Boolean` – should AST contains node position or not, store data in `info` property of nodes (`false` by default)
|
||||
- filename `String` – filename of source that adds to info when `positions` is true, uses for source map generation (`<unknown>` by default)
|
||||
- line `Number` – initial line number, useful when parse fragment of CSS to compute correct positions
|
||||
- column `Number` – initial column number, useful when parse fragment of CSS to compute correct positions
|
||||
|
||||
Contexts:
|
||||
|
||||
- `stylesheet` (default) – regular stylesheet, should be suitable in most cases
|
||||
- `atrule` – at-rule (e.g. `@media screen, print { ... }`)
|
||||
- `atruleExpression` – at-rule expression (`screen, print` for example above)
|
||||
- `ruleset` – rule (e.g. `.foo, .bar:hover { color: red; border: 1px solid black; }`)
|
||||
- `selector` – selector group (`.foo, .bar:hover` for ruleset example)
|
||||
- `simpleSelector` – selector (`.foo` or `.bar:hover` for ruleset example)
|
||||
- `block` – block content w/o curly braces (`color: red; border: 1px solid black;` for ruleset example)
|
||||
- `declaration` – declaration (`color: red` or `border: 1px solid black` for ruleset example)
|
||||
- `value` – declaration value (`red` or `1px solid black` for ruleset example)
|
||||
|
||||
```js
|
||||
// simple parsing with no options
|
||||
var ast = csso.parse('.example { color: red }');
|
||||
|
||||
// parse with options
|
||||
var ast = csso.parse('.foo.bar', {
|
||||
context: 'simpleSelector',
|
||||
positions: true
|
||||
});
|
||||
```
|
||||
|
||||
#### compress(ast[, options])
|
||||
|
||||
Does the main task – compress AST.
|
||||
|
||||
> NOTE: `compress` performs AST compression by transforming input AST by default (since AST cloning is expensive and needed in rare cases). Use `clone` option with truthy value in case you want to keep input AST untouched.
|
||||
|
||||
Options:
|
||||
|
||||
- restructure `Boolean` – do the structure optimisations or not (`true` by default)
|
||||
- clone `Boolean` - transform a copy of input AST if `true`, useful in case of AST reuse (`false` by default)
|
||||
- comments `String` or `Boolean` – specify what comments to left
|
||||
- `'exclamation'` or `true` (default) – left all exclamation comments (i.e. `/*! .. */`)
|
||||
- `'first-exclamation'` – remove every comments except first one
|
||||
- `false` – remove every comments
|
||||
- usage `Object` - usage data for advanced optimisations (see [Usage data](#usage-data) for details)
|
||||
- logger `Function` - function to track every step of transformations
|
||||
|
||||
#### clone(ast)
|
||||
|
||||
Make an AST node deep copy.
|
||||
|
||||
```js
|
||||
var orig = csso.parse('.test { color: red }');
|
||||
var copy = csso.clone(orig);
|
||||
|
||||
csso.walk(copy, function(node) {
|
||||
if (node.type === 'Class') {
|
||||
node.name = 'replaced';
|
||||
}
|
||||
});
|
||||
|
||||
console.log(csso.translate(orig));
|
||||
// .test{color:red}
|
||||
console.log(csso.translate(copy));
|
||||
// .replaced{color:red}
|
||||
```
|
||||
|
||||
#### translate(ast)
|
||||
|
||||
Converts AST to string.
|
||||
|
||||
```js
|
||||
var ast = csso.parse('.test { color: red }');
|
||||
console.log(csso.translate(ast));
|
||||
// > .test{color:red}
|
||||
```
|
||||
|
||||
#### translateWithSourceMap(ast)
|
||||
|
||||
The same as `translate()` but also generates source map (nodes should contain positions in `info` property).
|
||||
|
||||
```js
|
||||
var ast = csso.parse('.test { color: red }', {
|
||||
filename: 'my.css',
|
||||
positions: true
|
||||
});
|
||||
console.log(csso.translateWithSourceMap(ast));
|
||||
// { css: '.test{color:red}', map: SourceMapGenerator {} }
|
||||
```
|
||||
|
||||
#### walk(ast, handler)
|
||||
|
||||
Visit all nodes of AST and call handler for each one. `handler` receives three arguments:
|
||||
|
||||
- node – current AST node
|
||||
- item – node wrapper when node is a list member; this wrapper contains references to `prev` and `next` nodes in list
|
||||
- list – reference to list when node is a list member; it's useful for operations on list like `remove()` or `insert()`
|
||||
|
||||
Context for handler an object, that contains references to some parent nodes:
|
||||
|
||||
- root – refers to `ast` or root node
|
||||
- stylesheet – refers to closest `StyleSheet` node, it may be a top-level or at-rule block stylesheet
|
||||
- atruleExpression – refers to `AtruleExpression` node if current node inside at-rule expression
|
||||
- ruleset – refers to `Ruleset` node if current node inside a ruleset
|
||||
- selector – refers to `Selector` node if current node inside a selector
|
||||
- declaration – refers to `Declaration` node if current node inside a declaration
|
||||
- function – refers to closest `Function` or `FunctionalPseudo` node if current node inside one of them
|
||||
|
||||
```js
|
||||
// collect all urls in declarations
|
||||
var csso = require('./lib/index.js');
|
||||
var urls = [];
|
||||
var ast = csso.parse(`
|
||||
@import url(import.css);
|
||||
.foo { background: url('foo.jpg'); }
|
||||
.bar { background-image: url(bar.png); }
|
||||
`);
|
||||
|
||||
csso.walk(ast, function(node) {
|
||||
if (this.declaration !== null && node.type === 'Url') {
|
||||
var value = node.value;
|
||||
|
||||
if (value.type === 'Raw') {
|
||||
urls.push(value.value);
|
||||
} else {
|
||||
urls.push(value.value.substr(1, value.value.length - 2));
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
console.log(urls);
|
||||
// [ 'foo.jpg', 'bar.png' ]
|
||||
```
|
||||
|
||||
#### walkRules(ast, handler)
|
||||
|
||||
Same as `walk()` but visits `Ruleset` and `Atrule` nodes only.
|
||||
|
||||
#### walkRulesRight(ast, handler)
|
||||
|
||||
Same as `walkRules()` but visits nodes in reverse order (from last to first).
|
||||
|
||||
## More reading
|
||||
|
||||
- [Debugging](docs/debugging.md)
|
||||
|
||||
## License
|
||||
|
||||
MIT
|
||||
> TODO
|
||||
|
||||
16
node_modules/csso/bin/csso
generated
vendored
16
node_modules/csso/bin/csso
generated
vendored
@@ -1,16 +0,0 @@
|
||||
#!/usr/bin/env node
|
||||
|
||||
var cli = require('../lib/cli.js');
|
||||
|
||||
try {
|
||||
cli.run();
|
||||
} catch (e) {
|
||||
// output user frendly message if cli error
|
||||
if (cli.isCliError(e)) {
|
||||
console.error(e.message || e);
|
||||
process.exit(2);
|
||||
}
|
||||
|
||||
// otherwise re-throw exception
|
||||
throw e;
|
||||
}
|
||||
10
node_modules/csso/dist/csso-browser.js
generated
vendored
10
node_modules/csso/dist/csso-browser.js
generated
vendored
File diff suppressed because one or more lines are too long
338
node_modules/csso/lib/cli.js
generated
vendored
338
node_modules/csso/lib/cli.js
generated
vendored
@@ -1,338 +0,0 @@
|
||||
var fs = require('fs');
|
||||
var path = require('path');
|
||||
var cli = require('clap');
|
||||
var SourceMapConsumer = require('source-map').SourceMapConsumer;
|
||||
var csso = require('./index.js');
|
||||
|
||||
function readFromStream(stream, minify) {
|
||||
var buffer = [];
|
||||
|
||||
// FIXME: don't chain until node.js 0.10 drop, since setEncoding isn't chainable in 0.10
|
||||
stream.setEncoding('utf8');
|
||||
stream
|
||||
.on('data', function(chunk) {
|
||||
buffer.push(chunk);
|
||||
})
|
||||
.on('end', function() {
|
||||
minify(buffer.join(''));
|
||||
});
|
||||
}
|
||||
|
||||
function showStat(filename, source, result, inputMap, map, time, mem) {
|
||||
function fmt(size) {
|
||||
return String(size).split('').reverse().reduce(function(size, digit, idx) {
|
||||
if (idx && idx % 3 === 0) {
|
||||
size = ' ' + size;
|
||||
}
|
||||
return digit + size;
|
||||
}, '');
|
||||
}
|
||||
|
||||
map = map || 0;
|
||||
result -= map;
|
||||
|
||||
console.error('Source: ', filename === '<stdin>' ? filename : path.relative(process.cwd(), filename));
|
||||
if (inputMap) {
|
||||
console.error('Map source:', inputMap);
|
||||
}
|
||||
console.error('Original: ', fmt(source), 'bytes');
|
||||
console.error('Compressed:', fmt(result), 'bytes', '(' + (100 * result / source).toFixed(2) + '%)');
|
||||
console.error('Saving: ', fmt(source - result), 'bytes', '(' + (100 * (source - result) / source).toFixed(2) + '%)');
|
||||
if (map) {
|
||||
console.error('Source map:', fmt(map), 'bytes', '(' + (100 * map / (result + map)).toFixed(2) + '% of total)');
|
||||
console.error('Total: ', fmt(map + result), 'bytes');
|
||||
}
|
||||
console.error('Time: ', time, 'ms');
|
||||
console.error('Memory: ', (mem / (1024 * 1024)).toFixed(3), 'MB');
|
||||
}
|
||||
|
||||
function showParseError(source, filename, details, message) {
|
||||
function processLines(start, end) {
|
||||
return lines.slice(start, end).map(function(line, idx) {
|
||||
var num = String(start + idx + 1);
|
||||
|
||||
while (num.length < maxNumLength) {
|
||||
num = ' ' + num;
|
||||
}
|
||||
|
||||
return num + ' |' + line;
|
||||
}).join('\n');
|
||||
}
|
||||
|
||||
var lines = source.split(/\n|\r\n?|\f/);
|
||||
var column = details.column;
|
||||
var line = details.line;
|
||||
var startLine = Math.max(1, line - 2);
|
||||
var endLine = Math.min(line + 2, lines.length + 1);
|
||||
var maxNumLength = Math.max(4, String(endLine).length) + 1;
|
||||
|
||||
console.error('\nParse error ' + filename + ': ' + message);
|
||||
console.error(processLines(startLine - 1, line));
|
||||
console.error(new Array(column + maxNumLength + 2).join('-') + '^');
|
||||
console.error(processLines(line, endLine));
|
||||
console.error();
|
||||
}
|
||||
|
||||
function debugLevel(level) {
|
||||
// level is undefined when no param -> 1
|
||||
return isNaN(level) ? 1 : Math.max(Number(level), 0);
|
||||
}
|
||||
|
||||
function resolveSourceMap(source, inputMap, map, inputFile, outputFile) {
|
||||
var inputMapContent = null;
|
||||
var inputMapFile = null;
|
||||
var outputMapFile = null;
|
||||
|
||||
switch (map) {
|
||||
case 'none':
|
||||
// don't generate source map
|
||||
map = false;
|
||||
inputMap = 'none';
|
||||
break;
|
||||
|
||||
case 'inline':
|
||||
// nothing to do
|
||||
break;
|
||||
|
||||
case 'file':
|
||||
if (!outputFile) {
|
||||
console.error('Output filename should be specified when `--map file` is used');
|
||||
process.exit(2);
|
||||
}
|
||||
|
||||
outputMapFile = outputFile + '.map';
|
||||
break;
|
||||
|
||||
default:
|
||||
// process filename
|
||||
if (map) {
|
||||
// check path is reachable
|
||||
if (!fs.existsSync(path.dirname(map))) {
|
||||
console.error('Directory for map file should exists:', path.dirname(path.resolve(map)));
|
||||
process.exit(2);
|
||||
}
|
||||
|
||||
// resolve to absolute path
|
||||
outputMapFile = path.resolve(process.cwd(), map);
|
||||
}
|
||||
}
|
||||
|
||||
switch (inputMap) {
|
||||
case 'none':
|
||||
// nothing to do
|
||||
break;
|
||||
|
||||
case 'auto':
|
||||
if (map) {
|
||||
// try fetch source map from source
|
||||
var inputMapComment = source.match(/\/\*# sourceMappingURL=(\S+)\s*\*\/\s*$/);
|
||||
|
||||
if (inputFile === '<stdin>') {
|
||||
inputFile = false;
|
||||
}
|
||||
|
||||
if (inputMapComment) {
|
||||
// if comment found – value is filename or base64-encoded source map
|
||||
inputMapComment = inputMapComment[1];
|
||||
|
||||
if (inputMapComment.substr(0, 5) === 'data:') {
|
||||
// decode source map content from comment
|
||||
inputMapContent = new Buffer(inputMapComment.substr(inputMapComment.indexOf('base64,') + 7), 'base64').toString();
|
||||
} else {
|
||||
// value is filename – resolve it as absolute path
|
||||
if (inputFile) {
|
||||
inputMapFile = path.resolve(path.dirname(inputFile), inputMapComment);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// comment doesn't found - look up file with `.map` extension nearby input file
|
||||
if (inputFile && fs.existsSync(inputFile + '.map')) {
|
||||
inputMapFile = inputFile + '.map';
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
if (inputMap) {
|
||||
inputMapFile = inputMap;
|
||||
}
|
||||
}
|
||||
|
||||
// source map placed in external file
|
||||
if (inputMapFile) {
|
||||
inputMapContent = fs.readFileSync(inputMapFile, 'utf8');
|
||||
}
|
||||
|
||||
return {
|
||||
input: inputMapContent,
|
||||
inputFile: inputMapFile || (inputMapContent ? '<inline>' : false),
|
||||
output: map,
|
||||
outputFile: outputMapFile
|
||||
};
|
||||
}
|
||||
|
||||
function processCommentsOption(value) {
|
||||
switch (value) {
|
||||
case 'exclamation':
|
||||
case 'first-exclamation':
|
||||
case 'none':
|
||||
return value;
|
||||
}
|
||||
|
||||
console.error('Wrong value for `comments` option: %s', value);
|
||||
process.exit(2);
|
||||
}
|
||||
|
||||
var command = cli.create('csso', '[input] [output]')
|
||||
.version(require('../package.json').version)
|
||||
.option('-i, --input <filename>', 'Input file')
|
||||
.option('-o, --output <filename>', 'Output file (result outputs to stdout if not set)')
|
||||
.option('-m, --map <destination>', 'Generate source map: none (default), inline, file or <filename>', 'none')
|
||||
.option('-u, --usage <filenane>', 'Usage data file')
|
||||
.option('--input-map <source>', 'Input source map: none, auto (default) or <filename>', 'auto')
|
||||
.option('--restructure-off', 'Turns structure minimization off')
|
||||
.option('--comments <value>', 'Comments to keep: exclamation (default), first-exclamation or none', 'exclamation')
|
||||
.option('--stat', 'Output statistics in stderr')
|
||||
.option('--debug [level]', 'Output intermediate state of CSS during compression', debugLevel, 0)
|
||||
.action(function(args) {
|
||||
var options = this.values;
|
||||
var inputFile = options.input || args[0];
|
||||
var outputFile = options.output || args[1];
|
||||
var usageFile = options.usage;
|
||||
var usageData = false;
|
||||
var map = options.map;
|
||||
var inputMap = options.inputMap;
|
||||
var structureOptimisationOff = options.restructureOff;
|
||||
var comments = processCommentsOption(options.comments);
|
||||
var debug = options.debug;
|
||||
var statistics = options.stat;
|
||||
var inputStream;
|
||||
|
||||
if (process.stdin.isTTY && !inputFile && !outputFile) {
|
||||
this.showHelp();
|
||||
return;
|
||||
}
|
||||
|
||||
if (!inputFile) {
|
||||
inputFile = '<stdin>';
|
||||
inputStream = process.stdin;
|
||||
} else {
|
||||
inputFile = path.resolve(process.cwd(), inputFile);
|
||||
inputStream = fs.createReadStream(inputFile);
|
||||
}
|
||||
|
||||
if (outputFile) {
|
||||
outputFile = path.resolve(process.cwd(), outputFile);
|
||||
}
|
||||
|
||||
if (usageFile) {
|
||||
if (!fs.existsSync(usageFile)) {
|
||||
console.error('Usage data file doesn\'t found (%s)', usageFile);
|
||||
process.exit(2);
|
||||
}
|
||||
|
||||
usageData = fs.readFileSync(usageFile, 'utf-8');
|
||||
|
||||
try {
|
||||
usageData = JSON.parse(usageData);
|
||||
} catch (e) {
|
||||
console.error('Usage data parse error (%s)', usageFile);
|
||||
process.exit(2);
|
||||
}
|
||||
}
|
||||
|
||||
readFromStream(inputStream, function(source) {
|
||||
var time = process.hrtime();
|
||||
var mem = process.memoryUsage().heapUsed;
|
||||
var sourceMap = resolveSourceMap(source, inputMap, map, inputFile, outputFile);
|
||||
var sourceMapAnnotation = '';
|
||||
var result;
|
||||
|
||||
// main action
|
||||
try {
|
||||
result = csso.minify(source, {
|
||||
filename: inputFile,
|
||||
sourceMap: sourceMap.output,
|
||||
usage: usageData,
|
||||
restructure: !structureOptimisationOff,
|
||||
comments: comments,
|
||||
debug: debug
|
||||
});
|
||||
|
||||
// for backward capability minify returns a string
|
||||
if (typeof result === 'string') {
|
||||
result = {
|
||||
css: result,
|
||||
map: null
|
||||
};
|
||||
}
|
||||
} catch (e) {
|
||||
if (e.parseError) {
|
||||
showParseError(source, inputFile, e.parseError, e.message);
|
||||
if (!debug) {
|
||||
process.exit(2);
|
||||
}
|
||||
}
|
||||
|
||||
throw e;
|
||||
}
|
||||
|
||||
if (sourceMap.output && result.map) {
|
||||
// apply input map
|
||||
if (sourceMap.input) {
|
||||
result.map.applySourceMap(
|
||||
new SourceMapConsumer(sourceMap.input),
|
||||
inputFile
|
||||
);
|
||||
}
|
||||
|
||||
// add source map to result
|
||||
if (sourceMap.outputFile) {
|
||||
// write source map to file
|
||||
fs.writeFileSync(sourceMap.outputFile, result.map.toString(), 'utf-8');
|
||||
sourceMapAnnotation = '\n' +
|
||||
'/*# sourceMappingURL=' +
|
||||
path.relative(outputFile ? path.dirname(outputFile) : process.cwd(), sourceMap.outputFile) +
|
||||
' */';
|
||||
} else {
|
||||
// inline source map
|
||||
sourceMapAnnotation = '\n' +
|
||||
'/*# sourceMappingURL=data:application/json;base64,' +
|
||||
new Buffer(result.map.toString()).toString('base64') +
|
||||
' */';
|
||||
}
|
||||
|
||||
result.css += sourceMapAnnotation;
|
||||
}
|
||||
|
||||
// output result
|
||||
if (outputFile) {
|
||||
fs.writeFileSync(outputFile, result.css, 'utf-8');
|
||||
} else {
|
||||
console.log(result.css);
|
||||
}
|
||||
|
||||
// output statistics
|
||||
if (statistics) {
|
||||
var timeDiff = process.hrtime(time);
|
||||
showStat(
|
||||
path.relative(process.cwd(), inputFile),
|
||||
source.length,
|
||||
result.css.length,
|
||||
sourceMap.inputFile,
|
||||
sourceMapAnnotation.length,
|
||||
parseInt(timeDiff[0] * 1e3 + timeDiff[1] / 1e6),
|
||||
process.memoryUsage().heapUsed - mem
|
||||
);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
module.exports = {
|
||||
run: command.run.bind(command),
|
||||
isCliError: function(err) {
|
||||
return err instanceof cli.Error;
|
||||
}
|
||||
};
|
||||
54
node_modules/csso/lib/compressor/clean/Atrule.js
generated
vendored
54
node_modules/csso/lib/compressor/clean/Atrule.js
generated
vendored
@@ -1,54 +0,0 @@
|
||||
module.exports = function cleanAtrule(node, item, list) {
|
||||
if (node.block) {
|
||||
// otherwise removed at-rule don't prevent @import for removal
|
||||
this.root.firstAtrulesAllowed = false;
|
||||
|
||||
if (node.block.type === 'Block' && node.block.declarations.isEmpty()) {
|
||||
list.remove(item);
|
||||
return;
|
||||
}
|
||||
|
||||
if (node.block.type === 'StyleSheet' && node.block.rules.isEmpty()) {
|
||||
list.remove(item);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
switch (node.name) {
|
||||
case 'charset':
|
||||
if (node.expression.sequence.isEmpty()) {
|
||||
list.remove(item);
|
||||
return;
|
||||
}
|
||||
|
||||
// if there is any rule before @charset -> remove it
|
||||
if (item.prev) {
|
||||
list.remove(item);
|
||||
return;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case 'import':
|
||||
if (!this.root.firstAtrulesAllowed) {
|
||||
list.remove(item);
|
||||
return;
|
||||
}
|
||||
|
||||
// if there are some rules that not an @import or @charset before @import
|
||||
// remove it
|
||||
list.prevUntil(item.prev, function(rule) {
|
||||
if (rule.type === 'Atrule') {
|
||||
if (rule.name === 'import' || rule.name === 'charset') {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
this.root.firstAtrulesAllowed = false;
|
||||
list.remove(item);
|
||||
return true;
|
||||
}, this);
|
||||
|
||||
break;
|
||||
}
|
||||
};
|
||||
3
node_modules/csso/lib/compressor/clean/Comment.js
generated
vendored
3
node_modules/csso/lib/compressor/clean/Comment.js
generated
vendored
@@ -1,3 +0,0 @@
|
||||
module.exports = function cleanComment(data, item, list) {
|
||||
list.remove(item);
|
||||
};
|
||||
5
node_modules/csso/lib/compressor/clean/Declaration.js
generated
vendored
5
node_modules/csso/lib/compressor/clean/Declaration.js
generated
vendored
@@ -1,5 +0,0 @@
|
||||
module.exports = function cleanDeclartion(node, item, list) {
|
||||
if (node.value.sequence.isEmpty()) {
|
||||
list.remove(item);
|
||||
}
|
||||
};
|
||||
9
node_modules/csso/lib/compressor/clean/Identifier.js
generated
vendored
9
node_modules/csso/lib/compressor/clean/Identifier.js
generated
vendored
@@ -1,9 +0,0 @@
|
||||
module.exports = function cleanIdentifier(node, item, list) {
|
||||
// remove useless universal selector
|
||||
if (this.selector !== null && node.name === '*') {
|
||||
// remove when universal selector isn't last
|
||||
if (item.next && item.next.data.type !== 'Combinator') {
|
||||
list.remove(item);
|
||||
}
|
||||
}
|
||||
};
|
||||
39
node_modules/csso/lib/compressor/clean/Ruleset.js
generated
vendored
39
node_modules/csso/lib/compressor/clean/Ruleset.js
generated
vendored
@@ -1,39 +0,0 @@
|
||||
var hasOwnProperty = Object.prototype.hasOwnProperty;
|
||||
|
||||
function cleanUnused(node, usageData) {
|
||||
return node.selector.selectors.each(function(selector, item, list) {
|
||||
var hasUnused = selector.sequence.some(function(node) {
|
||||
switch (node.type) {
|
||||
case 'Class':
|
||||
return usageData.classes && !hasOwnProperty.call(usageData.classes, node.name);
|
||||
|
||||
case 'Id':
|
||||
return usageData.ids && !hasOwnProperty.call(usageData.ids, node.name);
|
||||
|
||||
case 'Identifier':
|
||||
// ignore universal selector
|
||||
if (node.name !== '*') {
|
||||
// TODO: remove toLowerCase when type selectors will be normalized
|
||||
return usageData.tags && !hasOwnProperty.call(usageData.tags, node.name.toLowerCase());
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
});
|
||||
|
||||
if (hasUnused) {
|
||||
list.remove(item);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
module.exports = function cleanRuleset(node, item, list, usageData) {
|
||||
if (usageData) {
|
||||
cleanUnused(node, usageData);
|
||||
}
|
||||
|
||||
if (node.selector.selectors.isEmpty() ||
|
||||
node.block.declarations.isEmpty()) {
|
||||
list.remove(item);
|
||||
}
|
||||
};
|
||||
16
node_modules/csso/lib/compressor/clean/Space.js
generated
vendored
16
node_modules/csso/lib/compressor/clean/Space.js
generated
vendored
@@ -1,16 +0,0 @@
|
||||
function canCleanWhitespace(node) {
|
||||
if (node.type !== 'Operator') {
|
||||
return false;
|
||||
}
|
||||
|
||||
return node.value !== '+' && node.value !== '-';
|
||||
}
|
||||
|
||||
module.exports = function cleanWhitespace(node, item, list) {
|
||||
var prev = item.prev && item.prev.data;
|
||||
var next = item.next && item.next.data;
|
||||
|
||||
if (canCleanWhitespace(prev) || canCleanWhitespace(next)) {
|
||||
list.remove(item);
|
||||
}
|
||||
};
|
||||
17
node_modules/csso/lib/compressor/clean/index.js
generated
vendored
17
node_modules/csso/lib/compressor/clean/index.js
generated
vendored
@@ -1,17 +0,0 @@
|
||||
var walk = require('../../utils/walk.js').all;
|
||||
var handlers = {
|
||||
Space: require('./Space.js'),
|
||||
Atrule: require('./Atrule.js'),
|
||||
Ruleset: require('./Ruleset.js'),
|
||||
Declaration: require('./Declaration.js'),
|
||||
Identifier: require('./Identifier.js'),
|
||||
Comment: require('./Comment.js')
|
||||
};
|
||||
|
||||
module.exports = function(ast, usageData) {
|
||||
walk(ast, function(node, item, list) {
|
||||
if (handlers.hasOwnProperty(node.type)) {
|
||||
handlers[node.type].call(this, node, item, list, usageData);
|
||||
}
|
||||
});
|
||||
};
|
||||
9
node_modules/csso/lib/compressor/compress/Atrule.js
generated
vendored
9
node_modules/csso/lib/compressor/compress/Atrule.js
generated
vendored
@@ -1,9 +0,0 @@
|
||||
var resolveKeyword = require('../../utils/names.js').keyword;
|
||||
var compressKeyframes = require('./atrule/keyframes.js');
|
||||
|
||||
module.exports = function(node) {
|
||||
// compress @keyframe selectors
|
||||
if (resolveKeyword(node.name).name === 'keyframes') {
|
||||
compressKeyframes(node);
|
||||
}
|
||||
};
|
||||
33
node_modules/csso/lib/compressor/compress/Attribute.js
generated
vendored
33
node_modules/csso/lib/compressor/compress/Attribute.js
generated
vendored
@@ -1,33 +0,0 @@
|
||||
// Can unquote attribute detection
|
||||
// Adopted implementation of Mathias Bynens
|
||||
// https://github.com/mathiasbynens/mothereff.in/blob/master/unquoted-attributes/eff.js
|
||||
var escapesRx = /\\([0-9A-Fa-f]{1,6})[ \t\n\f\r]?|\\./g;
|
||||
var blockUnquoteRx = /^(-?\d|--)|[\u0000-\u002c\u002e\u002f\u003A-\u0040\u005B-\u005E\u0060\u007B-\u009f]/;
|
||||
|
||||
function canUnquote(value) {
|
||||
if (value === '' || value === '-') {
|
||||
return;
|
||||
}
|
||||
|
||||
// Escapes are valid, so replace them with a valid non-empty string
|
||||
value = value.replace(escapesRx, 'a');
|
||||
|
||||
return !blockUnquoteRx.test(value);
|
||||
}
|
||||
|
||||
module.exports = function(node) {
|
||||
var attrValue = node.value;
|
||||
|
||||
if (!attrValue || attrValue.type !== 'String') {
|
||||
return;
|
||||
}
|
||||
|
||||
var unquotedValue = attrValue.value.replace(/^(.)(.*)\1$/, '$2');
|
||||
if (canUnquote(unquotedValue)) {
|
||||
node.value = {
|
||||
type: 'Identifier',
|
||||
info: attrValue.info,
|
||||
name: unquotedValue
|
||||
};
|
||||
}
|
||||
};
|
||||
54
node_modules/csso/lib/compressor/compress/Dimension.js
generated
vendored
54
node_modules/csso/lib/compressor/compress/Dimension.js
generated
vendored
@@ -1,54 +0,0 @@
|
||||
var packNumber = require('./Number.js').pack;
|
||||
var LENGTH_UNIT = {
|
||||
// absolute length units
|
||||
'px': true,
|
||||
'mm': true,
|
||||
'cm': true,
|
||||
'in': true,
|
||||
'pt': true,
|
||||
'pc': true,
|
||||
|
||||
// relative length units
|
||||
'em': true,
|
||||
'ex': true,
|
||||
'ch': true,
|
||||
'rem': true,
|
||||
|
||||
// viewport-percentage lengths
|
||||
'vh': true,
|
||||
'vw': true,
|
||||
'vmin': true,
|
||||
'vmax': true,
|
||||
'vm': true
|
||||
};
|
||||
|
||||
module.exports = function compressDimension(node, item) {
|
||||
var value = packNumber(node.value);
|
||||
|
||||
node.value = value;
|
||||
|
||||
if (value === '0' && this.declaration) {
|
||||
var unit = node.unit.toLowerCase();
|
||||
|
||||
// only length values can be compressed
|
||||
if (!LENGTH_UNIT.hasOwnProperty(unit)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// issue #200: don't remove units in flex property as it could change value meaning
|
||||
if (this.declaration.property.name === 'flex') {
|
||||
return;
|
||||
}
|
||||
|
||||
// issue #222: don't remove units inside calc
|
||||
if (this['function'] && this['function'].name === 'calc') {
|
||||
return;
|
||||
}
|
||||
|
||||
item.data = {
|
||||
type: 'Number',
|
||||
info: node.info,
|
||||
value: value
|
||||
};
|
||||
}
|
||||
};
|
||||
22
node_modules/csso/lib/compressor/compress/Number.js
generated
vendored
22
node_modules/csso/lib/compressor/compress/Number.js
generated
vendored
@@ -1,22 +0,0 @@
|
||||
function packNumber(value) {
|
||||
// 100 -> '100'
|
||||
// 00100 -> '100'
|
||||
// +100 -> '100'
|
||||
// -100 -> '-100'
|
||||
// 0.123 -> '.123'
|
||||
// 0.12300 -> '.123'
|
||||
// 0.0 -> ''
|
||||
// 0 -> ''
|
||||
value = String(value).replace(/^(?:\+|(-))?0*(\d*)(?:\.0*|(\.\d*?)0*)?$/, '$1$2$3');
|
||||
|
||||
if (value.length === 0 || value === '-') {
|
||||
value = '0';
|
||||
}
|
||||
|
||||
return value;
|
||||
};
|
||||
|
||||
module.exports = function(node) {
|
||||
node.value = packNumber(node.value);
|
||||
};
|
||||
module.exports.pack = packNumber;
|
||||
12
node_modules/csso/lib/compressor/compress/String.js
generated
vendored
12
node_modules/csso/lib/compressor/compress/String.js
generated
vendored
@@ -1,12 +0,0 @@
|
||||
module.exports = function(node) {
|
||||
var value = node.value;
|
||||
|
||||
// remove escaped \n, i.e.
|
||||
// .a { content: "foo\
|
||||
// bar"}
|
||||
// ->
|
||||
// .a { content: "foobar" }
|
||||
value = value.replace(/\\\n/g, '');
|
||||
|
||||
node.value = value;
|
||||
};
|
||||
33
node_modules/csso/lib/compressor/compress/Url.js
generated
vendored
33
node_modules/csso/lib/compressor/compress/Url.js
generated
vendored
@@ -1,33 +0,0 @@
|
||||
var UNICODE = '\\\\[0-9a-f]{1,6}(\\r\\n|[ \\n\\r\\t\\f])?';
|
||||
var ESCAPE = '(' + UNICODE + '|\\\\[^\\n\\r\\f0-9a-fA-F])';
|
||||
var NONPRINTABLE = '\u0000\u0008\u000b\u000e-\u001f\u007f';
|
||||
var SAFE_URL = new RegExp('^(' + ESCAPE + '|[^\"\'\\(\\)\\\\\\s' + NONPRINTABLE + '])*$', 'i');
|
||||
|
||||
module.exports = function(node) {
|
||||
var value = node.value;
|
||||
|
||||
if (value.type !== 'String') {
|
||||
return;
|
||||
}
|
||||
|
||||
var quote = value.value[0];
|
||||
var url = value.value.substr(1, value.value.length - 2);
|
||||
|
||||
// convert `\\` to `/`
|
||||
url = url.replace(/\\\\/g, '/');
|
||||
|
||||
// remove quotes when safe
|
||||
// https://www.w3.org/TR/css-syntax-3/#url-unquoted-diagram
|
||||
if (SAFE_URL.test(url)) {
|
||||
node.value = {
|
||||
type: 'Raw',
|
||||
info: node.value.info,
|
||||
value: url
|
||||
};
|
||||
} else {
|
||||
// use double quotes if string has no double quotes
|
||||
// otherwise use original quotes
|
||||
// TODO: make better quote type selection
|
||||
node.value.value = url.indexOf('"') === -1 ? '"' + url + '"' : quote + url + quote;
|
||||
}
|
||||
};
|
||||
18
node_modules/csso/lib/compressor/compress/Value.js
generated
vendored
18
node_modules/csso/lib/compressor/compress/Value.js
generated
vendored
@@ -1,18 +0,0 @@
|
||||
var resolveName = require('../../utils/names.js').property;
|
||||
var handlers = {
|
||||
'font': require('./property/font.js'),
|
||||
'font-weight': require('./property/font-weight.js'),
|
||||
'background': require('./property/background.js')
|
||||
};
|
||||
|
||||
module.exports = function compressValue(node) {
|
||||
if (!this.declaration) {
|
||||
return;
|
||||
}
|
||||
|
||||
var property = resolveName(this.declaration.property.name);
|
||||
|
||||
if (handlers.hasOwnProperty(property.name)) {
|
||||
handlers[property.name](node);
|
||||
}
|
||||
};
|
||||
21
node_modules/csso/lib/compressor/compress/atrule/keyframes.js
generated
vendored
21
node_modules/csso/lib/compressor/compress/atrule/keyframes.js
generated
vendored
@@ -1,21 +0,0 @@
|
||||
module.exports = function(node) {
|
||||
node.block.rules.each(function(ruleset) {
|
||||
ruleset.selector.selectors.each(function(simpleselector) {
|
||||
simpleselector.sequence.each(function(data, item) {
|
||||
if (data.type === 'Percentage' && data.value === '100') {
|
||||
item.data = {
|
||||
type: 'Identifier',
|
||||
info: data.info,
|
||||
name: 'to'
|
||||
};
|
||||
} else if (data.type === 'Identifier' && data.name === 'from') {
|
||||
item.data = {
|
||||
type: 'Percentage',
|
||||
info: data.info,
|
||||
value: '0'
|
||||
};
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
};
|
||||
489
node_modules/csso/lib/compressor/compress/color.js
generated
vendored
489
node_modules/csso/lib/compressor/compress/color.js
generated
vendored
@@ -1,489 +0,0 @@
|
||||
var List = require('../../utils/list.js');
|
||||
var packNumber = require('./Number.js').pack;
|
||||
|
||||
// http://www.w3.org/TR/css3-color/#svg-color
|
||||
var NAME_TO_HEX = {
|
||||
'aliceblue': 'f0f8ff',
|
||||
'antiquewhite': 'faebd7',
|
||||
'aqua': '0ff',
|
||||
'aquamarine': '7fffd4',
|
||||
'azure': 'f0ffff',
|
||||
'beige': 'f5f5dc',
|
||||
'bisque': 'ffe4c4',
|
||||
'black': '000',
|
||||
'blanchedalmond': 'ffebcd',
|
||||
'blue': '00f',
|
||||
'blueviolet': '8a2be2',
|
||||
'brown': 'a52a2a',
|
||||
'burlywood': 'deb887',
|
||||
'cadetblue': '5f9ea0',
|
||||
'chartreuse': '7fff00',
|
||||
'chocolate': 'd2691e',
|
||||
'coral': 'ff7f50',
|
||||
'cornflowerblue': '6495ed',
|
||||
'cornsilk': 'fff8dc',
|
||||
'crimson': 'dc143c',
|
||||
'cyan': '0ff',
|
||||
'darkblue': '00008b',
|
||||
'darkcyan': '008b8b',
|
||||
'darkgoldenrod': 'b8860b',
|
||||
'darkgray': 'a9a9a9',
|
||||
'darkgrey': 'a9a9a9',
|
||||
'darkgreen': '006400',
|
||||
'darkkhaki': 'bdb76b',
|
||||
'darkmagenta': '8b008b',
|
||||
'darkolivegreen': '556b2f',
|
||||
'darkorange': 'ff8c00',
|
||||
'darkorchid': '9932cc',
|
||||
'darkred': '8b0000',
|
||||
'darksalmon': 'e9967a',
|
||||
'darkseagreen': '8fbc8f',
|
||||
'darkslateblue': '483d8b',
|
||||
'darkslategray': '2f4f4f',
|
||||
'darkslategrey': '2f4f4f',
|
||||
'darkturquoise': '00ced1',
|
||||
'darkviolet': '9400d3',
|
||||
'deeppink': 'ff1493',
|
||||
'deepskyblue': '00bfff',
|
||||
'dimgray': '696969',
|
||||
'dimgrey': '696969',
|
||||
'dodgerblue': '1e90ff',
|
||||
'firebrick': 'b22222',
|
||||
'floralwhite': 'fffaf0',
|
||||
'forestgreen': '228b22',
|
||||
'fuchsia': 'f0f',
|
||||
'gainsboro': 'dcdcdc',
|
||||
'ghostwhite': 'f8f8ff',
|
||||
'gold': 'ffd700',
|
||||
'goldenrod': 'daa520',
|
||||
'gray': '808080',
|
||||
'grey': '808080',
|
||||
'green': '008000',
|
||||
'greenyellow': 'adff2f',
|
||||
'honeydew': 'f0fff0',
|
||||
'hotpink': 'ff69b4',
|
||||
'indianred': 'cd5c5c',
|
||||
'indigo': '4b0082',
|
||||
'ivory': 'fffff0',
|
||||
'khaki': 'f0e68c',
|
||||
'lavender': 'e6e6fa',
|
||||
'lavenderblush': 'fff0f5',
|
||||
'lawngreen': '7cfc00',
|
||||
'lemonchiffon': 'fffacd',
|
||||
'lightblue': 'add8e6',
|
||||
'lightcoral': 'f08080',
|
||||
'lightcyan': 'e0ffff',
|
||||
'lightgoldenrodyellow': 'fafad2',
|
||||
'lightgray': 'd3d3d3',
|
||||
'lightgrey': 'd3d3d3',
|
||||
'lightgreen': '90ee90',
|
||||
'lightpink': 'ffb6c1',
|
||||
'lightsalmon': 'ffa07a',
|
||||
'lightseagreen': '20b2aa',
|
||||
'lightskyblue': '87cefa',
|
||||
'lightslategray': '789',
|
||||
'lightslategrey': '789',
|
||||
'lightsteelblue': 'b0c4de',
|
||||
'lightyellow': 'ffffe0',
|
||||
'lime': '0f0',
|
||||
'limegreen': '32cd32',
|
||||
'linen': 'faf0e6',
|
||||
'magenta': 'f0f',
|
||||
'maroon': '800000',
|
||||
'mediumaquamarine': '66cdaa',
|
||||
'mediumblue': '0000cd',
|
||||
'mediumorchid': 'ba55d3',
|
||||
'mediumpurple': '9370db',
|
||||
'mediumseagreen': '3cb371',
|
||||
'mediumslateblue': '7b68ee',
|
||||
'mediumspringgreen': '00fa9a',
|
||||
'mediumturquoise': '48d1cc',
|
||||
'mediumvioletred': 'c71585',
|
||||
'midnightblue': '191970',
|
||||
'mintcream': 'f5fffa',
|
||||
'mistyrose': 'ffe4e1',
|
||||
'moccasin': 'ffe4b5',
|
||||
'navajowhite': 'ffdead',
|
||||
'navy': '000080',
|
||||
'oldlace': 'fdf5e6',
|
||||
'olive': '808000',
|
||||
'olivedrab': '6b8e23',
|
||||
'orange': 'ffa500',
|
||||
'orangered': 'ff4500',
|
||||
'orchid': 'da70d6',
|
||||
'palegoldenrod': 'eee8aa',
|
||||
'palegreen': '98fb98',
|
||||
'paleturquoise': 'afeeee',
|
||||
'palevioletred': 'db7093',
|
||||
'papayawhip': 'ffefd5',
|
||||
'peachpuff': 'ffdab9',
|
||||
'peru': 'cd853f',
|
||||
'pink': 'ffc0cb',
|
||||
'plum': 'dda0dd',
|
||||
'powderblue': 'b0e0e6',
|
||||
'purple': '800080',
|
||||
'rebeccapurple': '639',
|
||||
'red': 'f00',
|
||||
'rosybrown': 'bc8f8f',
|
||||
'royalblue': '4169e1',
|
||||
'saddlebrown': '8b4513',
|
||||
'salmon': 'fa8072',
|
||||
'sandybrown': 'f4a460',
|
||||
'seagreen': '2e8b57',
|
||||
'seashell': 'fff5ee',
|
||||
'sienna': 'a0522d',
|
||||
'silver': 'c0c0c0',
|
||||
'skyblue': '87ceeb',
|
||||
'slateblue': '6a5acd',
|
||||
'slategray': '708090',
|
||||
'slategrey': '708090',
|
||||
'snow': 'fffafa',
|
||||
'springgreen': '00ff7f',
|
||||
'steelblue': '4682b4',
|
||||
'tan': 'd2b48c',
|
||||
'teal': '008080',
|
||||
'thistle': 'd8bfd8',
|
||||
'tomato': 'ff6347',
|
||||
'turquoise': '40e0d0',
|
||||
'violet': 'ee82ee',
|
||||
'wheat': 'f5deb3',
|
||||
'white': 'fff',
|
||||
'whitesmoke': 'f5f5f5',
|
||||
'yellow': 'ff0',
|
||||
'yellowgreen': '9acd32'
|
||||
};
|
||||
|
||||
var HEX_TO_NAME = {
|
||||
'800000': 'maroon',
|
||||
'800080': 'purple',
|
||||
'808000': 'olive',
|
||||
'808080': 'gray',
|
||||
'00ffff': 'cyan',
|
||||
'f0ffff': 'azure',
|
||||
'f5f5dc': 'beige',
|
||||
'ffe4c4': 'bisque',
|
||||
'000000': 'black',
|
||||
'0000ff': 'blue',
|
||||
'a52a2a': 'brown',
|
||||
'ff7f50': 'coral',
|
||||
'ffd700': 'gold',
|
||||
'008000': 'green',
|
||||
'4b0082': 'indigo',
|
||||
'fffff0': 'ivory',
|
||||
'f0e68c': 'khaki',
|
||||
'00ff00': 'lime',
|
||||
'faf0e6': 'linen',
|
||||
'000080': 'navy',
|
||||
'ffa500': 'orange',
|
||||
'da70d6': 'orchid',
|
||||
'cd853f': 'peru',
|
||||
'ffc0cb': 'pink',
|
||||
'dda0dd': 'plum',
|
||||
'f00': 'red',
|
||||
'ff0000': 'red',
|
||||
'fa8072': 'salmon',
|
||||
'a0522d': 'sienna',
|
||||
'c0c0c0': 'silver',
|
||||
'fffafa': 'snow',
|
||||
'd2b48c': 'tan',
|
||||
'008080': 'teal',
|
||||
'ff6347': 'tomato',
|
||||
'ee82ee': 'violet',
|
||||
'f5deb3': 'wheat',
|
||||
'ffffff': 'white',
|
||||
'ffff00': 'yellow'
|
||||
};
|
||||
|
||||
function hueToRgb(p, q, t) {
|
||||
if (t < 0) {
|
||||
t += 1;
|
||||
}
|
||||
if (t > 1) {
|
||||
t -= 1;
|
||||
}
|
||||
if (t < 1 / 6) {
|
||||
return p + (q - p) * 6 * t;
|
||||
}
|
||||
if (t < 1 / 2) {
|
||||
return q;
|
||||
}
|
||||
if (t < 2 / 3) {
|
||||
return p + (q - p) * (2 / 3 - t) * 6;
|
||||
}
|
||||
return p;
|
||||
}
|
||||
|
||||
function hslToRgb(h, s, l, a) {
|
||||
var r;
|
||||
var g;
|
||||
var b;
|
||||
|
||||
if (s == 0) {
|
||||
r = g = b = l; // achromatic
|
||||
} else {
|
||||
var q = l < 0.5 ? l * (1 + s) : l + s - l * s;
|
||||
var p = 2 * l - q;
|
||||
|
||||
r = hueToRgb(p, q, h + 1 / 3);
|
||||
g = hueToRgb(p, q, h);
|
||||
b = hueToRgb(p, q, h - 1 / 3);
|
||||
}
|
||||
|
||||
return [
|
||||
Math.round(r * 255),
|
||||
Math.round(g * 255),
|
||||
Math.round(b * 255),
|
||||
a
|
||||
];
|
||||
}
|
||||
|
||||
function toHex(value) {
|
||||
value = value.toString(16);
|
||||
return value.length === 1 ? '0' + value : value;
|
||||
}
|
||||
|
||||
function parseFunctionArgs(functionArgs, count, rgb) {
|
||||
var argument = functionArgs.head;
|
||||
var args = [];
|
||||
|
||||
while (argument !== null) {
|
||||
var argumentPart = argument.data.sequence.head;
|
||||
var wasValue = false;
|
||||
|
||||
while (argumentPart !== null) {
|
||||
var value = argumentPart.data;
|
||||
var type = value.type;
|
||||
|
||||
switch (type) {
|
||||
case 'Number':
|
||||
case 'Percentage':
|
||||
if (wasValue) {
|
||||
return;
|
||||
}
|
||||
|
||||
wasValue = true;
|
||||
args.push({
|
||||
type: type,
|
||||
value: Number(value.value)
|
||||
});
|
||||
break;
|
||||
|
||||
case 'Operator':
|
||||
if (wasValue || value.value !== '+') {
|
||||
return;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
// something we couldn't understand
|
||||
return;
|
||||
}
|
||||
|
||||
argumentPart = argumentPart.next;
|
||||
}
|
||||
|
||||
argument = argument.next;
|
||||
}
|
||||
|
||||
if (args.length !== count) {
|
||||
// invalid arguments count
|
||||
// TODO: remove those tokens
|
||||
return;
|
||||
}
|
||||
|
||||
if (args.length === 4) {
|
||||
if (args[3].type !== 'Number') {
|
||||
// 4th argument should be a number
|
||||
// TODO: remove those tokens
|
||||
return;
|
||||
}
|
||||
|
||||
args[3].type = 'Alpha';
|
||||
}
|
||||
|
||||
if (rgb) {
|
||||
if (args[0].type !== args[1].type || args[0].type !== args[2].type) {
|
||||
// invalid color, numbers and percentage shouldn't be mixed
|
||||
// TODO: remove those tokens
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
if (args[0].type !== 'Number' ||
|
||||
args[1].type !== 'Percentage' ||
|
||||
args[2].type !== 'Percentage') {
|
||||
// invalid color, for hsl values should be: number, percentage, percentage
|
||||
// TODO: remove those tokens
|
||||
return;
|
||||
}
|
||||
|
||||
args[0].type = 'Angle';
|
||||
}
|
||||
|
||||
return args.map(function(arg) {
|
||||
var value = Math.max(0, arg.value);
|
||||
|
||||
switch (arg.type) {
|
||||
case 'Number':
|
||||
// fit value to [0..255] range
|
||||
value = Math.min(value, 255);
|
||||
break;
|
||||
|
||||
case 'Percentage':
|
||||
// convert 0..100% to value in [0..255] range
|
||||
value = Math.min(value, 100) / 100;
|
||||
|
||||
if (!rgb) {
|
||||
return value;
|
||||
}
|
||||
|
||||
value = 255 * value;
|
||||
break;
|
||||
|
||||
case 'Angle':
|
||||
// fit value to (-360..360) range
|
||||
return (((value % 360) + 360) % 360) / 360;
|
||||
|
||||
case 'Alpha':
|
||||
// fit value to [0..1] range
|
||||
return Math.min(value, 1);
|
||||
}
|
||||
|
||||
return Math.round(value);
|
||||
});
|
||||
}
|
||||
|
||||
function compressFunction(node, item, list) {
|
||||
var functionName = node.name;
|
||||
var args;
|
||||
|
||||
if (functionName === 'rgba' || functionName === 'hsla') {
|
||||
args = parseFunctionArgs(node.arguments, 4, functionName === 'rgba');
|
||||
|
||||
if (!args) {
|
||||
// something went wrong
|
||||
return;
|
||||
}
|
||||
|
||||
if (functionName === 'hsla') {
|
||||
args = hslToRgb.apply(null, args);
|
||||
node.name = 'rgba';
|
||||
}
|
||||
|
||||
if (args[3] !== 1) {
|
||||
// replace argument values for normalized/interpolated
|
||||
node.arguments.each(function(argument) {
|
||||
var item = argument.sequence.head;
|
||||
|
||||
if (item.data.type === 'Operator') {
|
||||
item = item.next;
|
||||
}
|
||||
|
||||
argument.sequence = new List([{
|
||||
type: 'Number',
|
||||
info: item.data.info,
|
||||
value: packNumber(args.shift())
|
||||
}]);
|
||||
});
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// otherwise convert to rgb, i.e. rgba(255, 0, 0, 1) -> rgb(255, 0, 0)
|
||||
functionName = 'rgb';
|
||||
}
|
||||
|
||||
if (functionName === 'hsl') {
|
||||
args = args || parseFunctionArgs(node.arguments, 3, false);
|
||||
|
||||
if (!args) {
|
||||
// something went wrong
|
||||
return;
|
||||
}
|
||||
|
||||
// convert to rgb
|
||||
args = hslToRgb.apply(null, args);
|
||||
functionName = 'rgb';
|
||||
}
|
||||
|
||||
if (functionName === 'rgb') {
|
||||
args = args || parseFunctionArgs(node.arguments, 3, true);
|
||||
|
||||
if (!args) {
|
||||
// something went wrong
|
||||
return;
|
||||
}
|
||||
|
||||
// check if color is not at the end and not followed by space
|
||||
var next = item.next;
|
||||
if (next && next.data.type !== 'Space') {
|
||||
list.insert(list.createItem({
|
||||
type: 'Space'
|
||||
}), next);
|
||||
}
|
||||
|
||||
item.data = {
|
||||
type: 'Hash',
|
||||
info: node.info,
|
||||
value: toHex(args[0]) + toHex(args[1]) + toHex(args[2])
|
||||
};
|
||||
|
||||
compressHex(item.data, item);
|
||||
}
|
||||
}
|
||||
|
||||
function compressIdent(node, item) {
|
||||
if (this.declaration === null) {
|
||||
return;
|
||||
}
|
||||
|
||||
var color = node.name.toLowerCase();
|
||||
|
||||
if (NAME_TO_HEX.hasOwnProperty(color)) {
|
||||
var hex = NAME_TO_HEX[color];
|
||||
|
||||
if (hex.length + 1 <= color.length) {
|
||||
// replace for shorter hex value
|
||||
item.data = {
|
||||
type: 'Hash',
|
||||
info: node.info,
|
||||
value: hex
|
||||
};
|
||||
} else {
|
||||
// special case for consistent colors
|
||||
if (color === 'grey') {
|
||||
color = 'gray';
|
||||
}
|
||||
|
||||
// just replace value for lower cased name
|
||||
node.name = color;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function compressHex(node, item) {
|
||||
var color = node.value.toLowerCase();
|
||||
|
||||
// #112233 -> #123
|
||||
if (color.length === 6 &&
|
||||
color[0] === color[1] &&
|
||||
color[2] === color[3] &&
|
||||
color[4] === color[5]) {
|
||||
color = color[0] + color[2] + color[4];
|
||||
}
|
||||
|
||||
if (HEX_TO_NAME[color]) {
|
||||
item.data = {
|
||||
type: 'Identifier',
|
||||
info: node.info,
|
||||
name: HEX_TO_NAME[color]
|
||||
};
|
||||
} else {
|
||||
node.value = color;
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
compressFunction: compressFunction,
|
||||
compressIdent: compressIdent,
|
||||
compressHex: compressHex
|
||||
};
|
||||
22
node_modules/csso/lib/compressor/compress/index.js
generated
vendored
22
node_modules/csso/lib/compressor/compress/index.js
generated
vendored
@@ -1,22 +0,0 @@
|
||||
var walk = require('../../utils/walk.js').all;
|
||||
var handlers = {
|
||||
Atrule: require('./Atrule.js'),
|
||||
Attribute: require('./Attribute.js'),
|
||||
Value: require('./Value.js'),
|
||||
Dimension: require('./Dimension.js'),
|
||||
Percentage: require('./Number.js'),
|
||||
Number: require('./Number.js'),
|
||||
String: require('./String.js'),
|
||||
Url: require('./Url.js'),
|
||||
Hash: require('./color.js').compressHex,
|
||||
Identifier: require('./color.js').compressIdent,
|
||||
Function: require('./color.js').compressFunction
|
||||
};
|
||||
|
||||
module.exports = function(ast) {
|
||||
walk(ast, function(node, item, list) {
|
||||
if (handlers.hasOwnProperty(node.type)) {
|
||||
handlers[node.type].call(this, node, item, list);
|
||||
}
|
||||
});
|
||||
};
|
||||
66
node_modules/csso/lib/compressor/compress/property/background.js
generated
vendored
66
node_modules/csso/lib/compressor/compress/property/background.js
generated
vendored
@@ -1,66 +0,0 @@
|
||||
var List = require('../../../utils/list.js');
|
||||
|
||||
module.exports = function compressBackground(node) {
|
||||
function lastType() {
|
||||
if (buffer.length) {
|
||||
return buffer[buffer.length - 1].type;
|
||||
}
|
||||
}
|
||||
|
||||
function flush() {
|
||||
if (lastType() === 'Space') {
|
||||
buffer.pop();
|
||||
}
|
||||
|
||||
if (!buffer.length) {
|
||||
buffer.unshift(
|
||||
{
|
||||
type: 'Number',
|
||||
value: '0'
|
||||
},
|
||||
{
|
||||
type: 'Space'
|
||||
},
|
||||
{
|
||||
type: 'Number',
|
||||
value: '0'
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
newValue.push.apply(newValue, buffer);
|
||||
|
||||
buffer = [];
|
||||
}
|
||||
|
||||
var newValue = [];
|
||||
var buffer = [];
|
||||
|
||||
node.sequence.each(function(node) {
|
||||
if (node.type === 'Operator' && node.value === ',') {
|
||||
flush();
|
||||
newValue.push(node);
|
||||
return;
|
||||
}
|
||||
|
||||
// remove defaults
|
||||
if (node.type === 'Identifier') {
|
||||
if (node.name === 'transparent' ||
|
||||
node.name === 'none' ||
|
||||
node.name === 'repeat' ||
|
||||
node.name === 'scroll') {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// don't add redundant spaces
|
||||
if (node.type === 'Space' && (!buffer.length || lastType() === 'Space')) {
|
||||
return;
|
||||
}
|
||||
|
||||
buffer.push(node);
|
||||
});
|
||||
|
||||
flush();
|
||||
node.sequence = new List(newValue);
|
||||
};
|
||||
22
node_modules/csso/lib/compressor/compress/property/font-weight.js
generated
vendored
22
node_modules/csso/lib/compressor/compress/property/font-weight.js
generated
vendored
@@ -1,22 +0,0 @@
|
||||
module.exports = function compressFontWeight(node) {
|
||||
var value = node.sequence.head.data;
|
||||
|
||||
if (value.type === 'Identifier') {
|
||||
switch (value.name) {
|
||||
case 'normal':
|
||||
node.sequence.head.data = {
|
||||
type: 'Number',
|
||||
info: value.info,
|
||||
value: '400'
|
||||
};
|
||||
break;
|
||||
case 'bold':
|
||||
node.sequence.head.data = {
|
||||
type: 'Number',
|
||||
info: value.info,
|
||||
value: '700'
|
||||
};
|
||||
break;
|
||||
}
|
||||
}
|
||||
};
|
||||
45
node_modules/csso/lib/compressor/compress/property/font.js
generated
vendored
45
node_modules/csso/lib/compressor/compress/property/font.js
generated
vendored
@@ -1,45 +0,0 @@
|
||||
module.exports = function compressFont(node) {
|
||||
var list = node.sequence;
|
||||
|
||||
list.eachRight(function(node, item) {
|
||||
if (node.type === 'Identifier') {
|
||||
if (node.name === 'bold') {
|
||||
item.data = {
|
||||
type: 'Number',
|
||||
info: node.info,
|
||||
value: '700'
|
||||
};
|
||||
} else if (node.name === 'normal') {
|
||||
var prev = item.prev;
|
||||
|
||||
if (prev && prev.data.type === 'Operator' && prev.data.value === '/') {
|
||||
this.remove(prev);
|
||||
}
|
||||
|
||||
this.remove(item);
|
||||
} else if (node.name === 'medium') {
|
||||
var next = item.next;
|
||||
|
||||
if (!next || next.data.type !== 'Operator') {
|
||||
this.remove(item);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// remove redundant spaces
|
||||
list.each(function(node, item) {
|
||||
if (node.type === 'Space') {
|
||||
if (!item.prev || !item.next || item.next.data.type === 'Space') {
|
||||
this.remove(item);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
if (list.isEmpty()) {
|
||||
list.insert(list.createItem({
|
||||
type: 'Identifier',
|
||||
name: 'normal'
|
||||
}));
|
||||
}
|
||||
};
|
||||
186
node_modules/csso/lib/compressor/index.js
generated
vendored
186
node_modules/csso/lib/compressor/index.js
generated
vendored
@@ -1,186 +0,0 @@
|
||||
var List = require('../utils/list');
|
||||
var clone = require('../utils/clone');
|
||||
var usageUtils = require('./usage');
|
||||
var clean = require('./clean');
|
||||
var compress = require('./compress');
|
||||
var restructureBlock = require('./restructure');
|
||||
var walkRules = require('../utils/walk').rules;
|
||||
|
||||
function readRulesChunk(rules, specialComments) {
|
||||
var buffer = new List();
|
||||
var nonSpaceTokenInBuffer = false;
|
||||
var protectedComment;
|
||||
|
||||
rules.nextUntil(rules.head, function(node, item, list) {
|
||||
if (node.type === 'Comment') {
|
||||
if (!specialComments || node.value.charAt(0) !== '!') {
|
||||
list.remove(item);
|
||||
return;
|
||||
}
|
||||
|
||||
if (nonSpaceTokenInBuffer || protectedComment) {
|
||||
return true;
|
||||
}
|
||||
|
||||
list.remove(item);
|
||||
protectedComment = node;
|
||||
return;
|
||||
}
|
||||
|
||||
if (node.type !== 'Space') {
|
||||
nonSpaceTokenInBuffer = true;
|
||||
}
|
||||
|
||||
buffer.insert(list.remove(item));
|
||||
});
|
||||
|
||||
return {
|
||||
comment: protectedComment,
|
||||
stylesheet: {
|
||||
type: 'StyleSheet',
|
||||
info: null,
|
||||
rules: buffer
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
function compressChunk(ast, firstAtrulesAllowed, usageData, num, logger) {
|
||||
logger('Compress block #' + num, null, true);
|
||||
|
||||
var seed = 1;
|
||||
walkRules(ast, function markStylesheets() {
|
||||
if ('id' in this.stylesheet === false) {
|
||||
this.stylesheet.firstAtrulesAllowed = firstAtrulesAllowed;
|
||||
this.stylesheet.id = seed++;
|
||||
}
|
||||
});
|
||||
logger('init', ast);
|
||||
|
||||
// remove redundant
|
||||
clean(ast, usageData);
|
||||
logger('clean', ast);
|
||||
|
||||
// compress nodes
|
||||
compress(ast, usageData);
|
||||
logger('compress', ast);
|
||||
|
||||
return ast;
|
||||
}
|
||||
|
||||
function getCommentsOption(options) {
|
||||
var comments = 'comments' in options ? options.comments : 'exclamation';
|
||||
|
||||
if (typeof comments === 'boolean') {
|
||||
comments = comments ? 'exclamation' : false;
|
||||
} else if (comments !== 'exclamation' && comments !== 'first-exclamation') {
|
||||
comments = false;
|
||||
}
|
||||
|
||||
return comments;
|
||||
}
|
||||
|
||||
function getRestructureOption(options) {
|
||||
return 'restructure' in options ? options.restructure :
|
||||
'restructuring' in options ? options.restructuring :
|
||||
true;
|
||||
}
|
||||
|
||||
function wrapBlock(block) {
|
||||
return new List([{
|
||||
type: 'Ruleset',
|
||||
selector: {
|
||||
type: 'Selector',
|
||||
selectors: new List([{
|
||||
type: 'SimpleSelector',
|
||||
sequence: new List([{
|
||||
type: 'Identifier',
|
||||
name: 'x'
|
||||
}])
|
||||
}])
|
||||
},
|
||||
block: block
|
||||
}]);
|
||||
}
|
||||
|
||||
module.exports = function compress(ast, options) {
|
||||
ast = ast || { type: 'StyleSheet', info: null, rules: new List() };
|
||||
options = options || {};
|
||||
|
||||
var logger = typeof options.logger === 'function' ? options.logger : Function();
|
||||
var specialComments = getCommentsOption(options);
|
||||
var restructuring = getRestructureOption(options);
|
||||
var firstAtrulesAllowed = true;
|
||||
var usageData = false;
|
||||
var inputRules;
|
||||
var outputRules = new List();
|
||||
var chunk;
|
||||
var chunkNum = 1;
|
||||
var chunkRules;
|
||||
|
||||
if (options.clone) {
|
||||
ast = clone(ast);
|
||||
}
|
||||
|
||||
if (ast.type === 'StyleSheet') {
|
||||
inputRules = ast.rules;
|
||||
ast.rules = outputRules;
|
||||
} else {
|
||||
inputRules = wrapBlock(ast);
|
||||
}
|
||||
|
||||
if (options.usage) {
|
||||
usageData = usageUtils.buildIndex(options.usage);
|
||||
}
|
||||
|
||||
do {
|
||||
chunk = readRulesChunk(inputRules, Boolean(specialComments));
|
||||
|
||||
compressChunk(chunk.stylesheet, firstAtrulesAllowed, usageData, chunkNum++, logger);
|
||||
|
||||
// structure optimisations
|
||||
if (restructuring) {
|
||||
restructureBlock(chunk.stylesheet, usageData, logger);
|
||||
}
|
||||
|
||||
chunkRules = chunk.stylesheet.rules;
|
||||
|
||||
if (chunk.comment) {
|
||||
// add \n before comment if there is another content in outputRules
|
||||
if (!outputRules.isEmpty()) {
|
||||
outputRules.insert(List.createItem({
|
||||
type: 'Raw',
|
||||
value: '\n'
|
||||
}));
|
||||
}
|
||||
|
||||
outputRules.insert(List.createItem(chunk.comment));
|
||||
|
||||
// add \n after comment if chunk is not empty
|
||||
if (!chunkRules.isEmpty()) {
|
||||
outputRules.insert(List.createItem({
|
||||
type: 'Raw',
|
||||
value: '\n'
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
if (firstAtrulesAllowed && !chunkRules.isEmpty()) {
|
||||
var lastRule = chunkRules.last();
|
||||
|
||||
if (lastRule.type !== 'Atrule' ||
|
||||
(lastRule.name !== 'import' && lastRule.name !== 'charset')) {
|
||||
firstAtrulesAllowed = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (specialComments !== 'exclamation') {
|
||||
specialComments = false;
|
||||
}
|
||||
|
||||
outputRules.appendList(chunkRules);
|
||||
} while (!inputRules.isEmpty());
|
||||
|
||||
return {
|
||||
ast: ast
|
||||
};
|
||||
};
|
||||
48
node_modules/csso/lib/compressor/restructure/1-initialMergeRuleset.js
generated
vendored
48
node_modules/csso/lib/compressor/restructure/1-initialMergeRuleset.js
generated
vendored
@@ -1,48 +0,0 @@
|
||||
var utils = require('./utils.js');
|
||||
var walkRules = require('../../utils/walk.js').rules;
|
||||
|
||||
function processRuleset(node, item, list) {
|
||||
var selectors = node.selector.selectors;
|
||||
var declarations = node.block.declarations;
|
||||
|
||||
list.prevUntil(item.prev, function(prev) {
|
||||
// skip non-ruleset node if safe
|
||||
if (prev.type !== 'Ruleset') {
|
||||
return utils.unsafeToSkipNode.call(selectors, prev);
|
||||
}
|
||||
|
||||
var prevSelectors = prev.selector.selectors;
|
||||
var prevDeclarations = prev.block.declarations;
|
||||
|
||||
// try to join rulesets with equal pseudo signature
|
||||
if (node.pseudoSignature === prev.pseudoSignature) {
|
||||
// try to join by selectors
|
||||
if (utils.isEqualLists(prevSelectors, selectors)) {
|
||||
prevDeclarations.appendList(declarations);
|
||||
list.remove(item);
|
||||
return true;
|
||||
}
|
||||
|
||||
// try to join by declarations
|
||||
if (utils.isEqualDeclarations(declarations, prevDeclarations)) {
|
||||
utils.addSelectors(prevSelectors, selectors);
|
||||
list.remove(item);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// go to prev ruleset if has no selector similarities
|
||||
return utils.hasSimilarSelectors(selectors, prevSelectors);
|
||||
});
|
||||
};
|
||||
|
||||
// NOTE: direction should be left to right, since rulesets merge to left
|
||||
// ruleset. When direction right to left unmerged rulesets may prevent lookup
|
||||
// TODO: remove initial merge
|
||||
module.exports = function initialMergeRuleset(ast) {
|
||||
walkRules(ast, function(node, item, list) {
|
||||
if (node.type === 'Ruleset') {
|
||||
processRuleset(node, item, list);
|
||||
}
|
||||
});
|
||||
};
|
||||
35
node_modules/csso/lib/compressor/restructure/2-mergeAtrule.js
generated
vendored
35
node_modules/csso/lib/compressor/restructure/2-mergeAtrule.js
generated
vendored
@@ -1,35 +0,0 @@
|
||||
var walkRulesRight = require('../../utils/walk.js').rulesRight;
|
||||
|
||||
function isMediaRule(node) {
|
||||
return node.type === 'Atrule' && node.name === 'media';
|
||||
}
|
||||
|
||||
function processAtrule(node, item, list) {
|
||||
if (!isMediaRule(node)) {
|
||||
return;
|
||||
}
|
||||
|
||||
var prev = item.prev && item.prev.data;
|
||||
|
||||
if (!prev || !isMediaRule(prev)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// merge @media with same query
|
||||
if (node.expression.id === prev.expression.id) {
|
||||
prev.block.rules.appendList(node.block.rules);
|
||||
prev.info = {
|
||||
primary: prev.info,
|
||||
merged: node.info
|
||||
};
|
||||
list.remove(item);
|
||||
}
|
||||
};
|
||||
|
||||
module.exports = function rejoinAtrule(ast) {
|
||||
walkRulesRight(ast, function(node, item, list) {
|
||||
if (node.type === 'Atrule') {
|
||||
processAtrule(node, item, list);
|
||||
}
|
||||
});
|
||||
};
|
||||
42
node_modules/csso/lib/compressor/restructure/3-disjoinRuleset.js
generated
vendored
42
node_modules/csso/lib/compressor/restructure/3-disjoinRuleset.js
generated
vendored
@@ -1,42 +0,0 @@
|
||||
var List = require('../../utils/list.js');
|
||||
var walkRulesRight = require('../../utils/walk.js').rulesRight;
|
||||
|
||||
function processRuleset(node, item, list) {
|
||||
var selectors = node.selector.selectors;
|
||||
|
||||
// generate new rule sets:
|
||||
// .a, .b { color: red; }
|
||||
// ->
|
||||
// .a { color: red; }
|
||||
// .b { color: red; }
|
||||
|
||||
// while there are more than 1 simple selector split for rulesets
|
||||
while (selectors.head !== selectors.tail) {
|
||||
var newSelectors = new List();
|
||||
newSelectors.insert(selectors.remove(selectors.head));
|
||||
|
||||
list.insert(list.createItem({
|
||||
type: 'Ruleset',
|
||||
info: node.info,
|
||||
pseudoSignature: node.pseudoSignature,
|
||||
selector: {
|
||||
type: 'Selector',
|
||||
info: node.selector.info,
|
||||
selectors: newSelectors
|
||||
},
|
||||
block: {
|
||||
type: 'Block',
|
||||
info: node.block.info,
|
||||
declarations: node.block.declarations.copy()
|
||||
}
|
||||
}), item);
|
||||
}
|
||||
};
|
||||
|
||||
module.exports = function disjoinRuleset(ast) {
|
||||
walkRulesRight(ast, function(node, item, list) {
|
||||
if (node.type === 'Ruleset') {
|
||||
processRuleset(node, item, list);
|
||||
}
|
||||
});
|
||||
};
|
||||
430
node_modules/csso/lib/compressor/restructure/4-restructShorthand.js
generated
vendored
430
node_modules/csso/lib/compressor/restructure/4-restructShorthand.js
generated
vendored
@@ -1,430 +0,0 @@
|
||||
var List = require('../../utils/list.js');
|
||||
var translate = require('../../utils/translate.js');
|
||||
var walkRulesRight = require('../../utils/walk.js').rulesRight;
|
||||
|
||||
var REPLACE = 1;
|
||||
var REMOVE = 2;
|
||||
var TOP = 0;
|
||||
var RIGHT = 1;
|
||||
var BOTTOM = 2;
|
||||
var LEFT = 3;
|
||||
var SIDES = ['top', 'right', 'bottom', 'left'];
|
||||
var SIDE = {
|
||||
'margin-top': 'top',
|
||||
'margin-right': 'right',
|
||||
'margin-bottom': 'bottom',
|
||||
'margin-left': 'left',
|
||||
|
||||
'padding-top': 'top',
|
||||
'padding-right': 'right',
|
||||
'padding-bottom': 'bottom',
|
||||
'padding-left': 'left',
|
||||
|
||||
'border-top-color': 'top',
|
||||
'border-right-color': 'right',
|
||||
'border-bottom-color': 'bottom',
|
||||
'border-left-color': 'left',
|
||||
'border-top-width': 'top',
|
||||
'border-right-width': 'right',
|
||||
'border-bottom-width': 'bottom',
|
||||
'border-left-width': 'left',
|
||||
'border-top-style': 'top',
|
||||
'border-right-style': 'right',
|
||||
'border-bottom-style': 'bottom',
|
||||
'border-left-style': 'left'
|
||||
};
|
||||
var MAIN_PROPERTY = {
|
||||
'margin': 'margin',
|
||||
'margin-top': 'margin',
|
||||
'margin-right': 'margin',
|
||||
'margin-bottom': 'margin',
|
||||
'margin-left': 'margin',
|
||||
|
||||
'padding': 'padding',
|
||||
'padding-top': 'padding',
|
||||
'padding-right': 'padding',
|
||||
'padding-bottom': 'padding',
|
||||
'padding-left': 'padding',
|
||||
|
||||
'border-color': 'border-color',
|
||||
'border-top-color': 'border-color',
|
||||
'border-right-color': 'border-color',
|
||||
'border-bottom-color': 'border-color',
|
||||
'border-left-color': 'border-color',
|
||||
'border-width': 'border-width',
|
||||
'border-top-width': 'border-width',
|
||||
'border-right-width': 'border-width',
|
||||
'border-bottom-width': 'border-width',
|
||||
'border-left-width': 'border-width',
|
||||
'border-style': 'border-style',
|
||||
'border-top-style': 'border-style',
|
||||
'border-right-style': 'border-style',
|
||||
'border-bottom-style': 'border-style',
|
||||
'border-left-style': 'border-style'
|
||||
};
|
||||
|
||||
function TRBL(name) {
|
||||
this.name = name;
|
||||
this.info = null;
|
||||
this.iehack = undefined;
|
||||
this.sides = {
|
||||
'top': null,
|
||||
'right': null,
|
||||
'bottom': null,
|
||||
'left': null
|
||||
};
|
||||
}
|
||||
|
||||
TRBL.prototype.getValueSequence = function(value, count) {
|
||||
var values = [];
|
||||
var iehack = '';
|
||||
var hasBadValues = value.sequence.some(function(child) {
|
||||
var special = false;
|
||||
|
||||
switch (child.type) {
|
||||
case 'Identifier':
|
||||
switch (child.name) {
|
||||
case '\\0':
|
||||
case '\\9':
|
||||
iehack = child.name;
|
||||
return;
|
||||
|
||||
case 'inherit':
|
||||
case 'initial':
|
||||
case 'unset':
|
||||
case 'revert':
|
||||
special = child.name;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case 'Dimension':
|
||||
switch (child.unit) {
|
||||
// is not supported until IE11
|
||||
case 'rem':
|
||||
|
||||
// v* units is too buggy across browsers and better
|
||||
// don't merge values with those units
|
||||
case 'vw':
|
||||
case 'vh':
|
||||
case 'vmin':
|
||||
case 'vmax':
|
||||
case 'vm': // IE9 supporting "vm" instead of "vmin".
|
||||
special = child.unit;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case 'Hash': // color
|
||||
case 'Number':
|
||||
case 'Percentage':
|
||||
break;
|
||||
|
||||
case 'Function':
|
||||
special = child.name;
|
||||
break;
|
||||
|
||||
case 'Space':
|
||||
return false; // ignore space
|
||||
|
||||
default:
|
||||
return true; // bad value
|
||||
}
|
||||
|
||||
values.push({
|
||||
node: child,
|
||||
special: special,
|
||||
important: value.important
|
||||
});
|
||||
});
|
||||
|
||||
if (hasBadValues || values.length > count) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (typeof this.iehack === 'string' && this.iehack !== iehack) {
|
||||
return false;
|
||||
}
|
||||
|
||||
this.iehack = iehack; // move outside
|
||||
|
||||
return values;
|
||||
};
|
||||
|
||||
TRBL.prototype.canOverride = function(side, value) {
|
||||
var currentValue = this.sides[side];
|
||||
|
||||
return !currentValue || (value.important && !currentValue.important);
|
||||
};
|
||||
|
||||
TRBL.prototype.add = function(name, value, info) {
|
||||
function attemptToAdd() {
|
||||
var sides = this.sides;
|
||||
var side = SIDE[name];
|
||||
|
||||
if (side) {
|
||||
if (side in sides === false) {
|
||||
return false;
|
||||
}
|
||||
|
||||
var values = this.getValueSequence(value, 1);
|
||||
|
||||
if (!values || !values.length) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// can mix only if specials are equal
|
||||
for (var key in sides) {
|
||||
if (sides[key] !== null && sides[key].special !== values[0].special) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (!this.canOverride(side, values[0])) {
|
||||
return true;
|
||||
}
|
||||
|
||||
sides[side] = values[0];
|
||||
return true;
|
||||
} else if (name === this.name) {
|
||||
var values = this.getValueSequence(value, 4);
|
||||
|
||||
if (!values || !values.length) {
|
||||
return false;
|
||||
}
|
||||
|
||||
switch (values.length) {
|
||||
case 1:
|
||||
values[RIGHT] = values[TOP];
|
||||
values[BOTTOM] = values[TOP];
|
||||
values[LEFT] = values[TOP];
|
||||
break;
|
||||
|
||||
case 2:
|
||||
values[BOTTOM] = values[TOP];
|
||||
values[LEFT] = values[RIGHT];
|
||||
break;
|
||||
|
||||
case 3:
|
||||
values[LEFT] = values[RIGHT];
|
||||
break;
|
||||
}
|
||||
|
||||
// can mix only if specials are equal
|
||||
for (var i = 0; i < 4; i++) {
|
||||
for (var key in sides) {
|
||||
if (sides[key] !== null && sides[key].special !== values[i].special) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (var i = 0; i < 4; i++) {
|
||||
if (this.canOverride(SIDES[i], values[i])) {
|
||||
sides[SIDES[i]] = values[i];
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
if (!attemptToAdd.call(this)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (this.info) {
|
||||
this.info = {
|
||||
primary: this.info,
|
||||
merged: info
|
||||
};
|
||||
} else {
|
||||
this.info = info;
|
||||
}
|
||||
|
||||
return true;
|
||||
};
|
||||
|
||||
TRBL.prototype.isOkToMinimize = function() {
|
||||
var top = this.sides.top;
|
||||
var right = this.sides.right;
|
||||
var bottom = this.sides.bottom;
|
||||
var left = this.sides.left;
|
||||
|
||||
if (top && right && bottom && left) {
|
||||
var important =
|
||||
top.important +
|
||||
right.important +
|
||||
bottom.important +
|
||||
left.important;
|
||||
|
||||
return important === 0 || important === 4;
|
||||
}
|
||||
|
||||
return false;
|
||||
};
|
||||
|
||||
TRBL.prototype.getValue = function() {
|
||||
var result = [];
|
||||
var sides = this.sides;
|
||||
var values = [
|
||||
sides.top,
|
||||
sides.right,
|
||||
sides.bottom,
|
||||
sides.left
|
||||
];
|
||||
var stringValues = [
|
||||
translate(sides.top.node),
|
||||
translate(sides.right.node),
|
||||
translate(sides.bottom.node),
|
||||
translate(sides.left.node)
|
||||
];
|
||||
|
||||
if (stringValues[LEFT] === stringValues[RIGHT]) {
|
||||
values.pop();
|
||||
if (stringValues[BOTTOM] === stringValues[TOP]) {
|
||||
values.pop();
|
||||
if (stringValues[RIGHT] === stringValues[TOP]) {
|
||||
values.pop();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (var i = 0; i < values.length; i++) {
|
||||
if (i) {
|
||||
result.push({ type: 'Space' });
|
||||
}
|
||||
|
||||
result.push(values[i].node);
|
||||
}
|
||||
|
||||
if (this.iehack) {
|
||||
result.push({ type: 'Space' }, {
|
||||
type: 'Identifier',
|
||||
info: {},
|
||||
name: this.iehack
|
||||
});
|
||||
}
|
||||
|
||||
return {
|
||||
type: 'Value',
|
||||
info: {},
|
||||
important: sides.top.important,
|
||||
sequence: new List(result)
|
||||
};
|
||||
};
|
||||
|
||||
TRBL.prototype.getProperty = function() {
|
||||
return {
|
||||
type: 'Property',
|
||||
info: {},
|
||||
name: this.name
|
||||
};
|
||||
};
|
||||
|
||||
function processRuleset(ruleset, shorts, shortDeclarations, lastShortSelector) {
|
||||
var declarations = ruleset.block.declarations;
|
||||
var selector = ruleset.selector.selectors.first().id;
|
||||
|
||||
ruleset.block.declarations.eachRight(function(declaration, item) {
|
||||
var property = declaration.property.name;
|
||||
|
||||
if (!MAIN_PROPERTY.hasOwnProperty(property)) {
|
||||
return;
|
||||
}
|
||||
|
||||
var key = MAIN_PROPERTY[property];
|
||||
var shorthand;
|
||||
var operation;
|
||||
|
||||
if (!lastShortSelector || selector === lastShortSelector) {
|
||||
if (key in shorts) {
|
||||
operation = REMOVE;
|
||||
shorthand = shorts[key];
|
||||
}
|
||||
}
|
||||
|
||||
if (!shorthand || !shorthand.add(property, declaration.value, declaration.info)) {
|
||||
operation = REPLACE;
|
||||
shorthand = new TRBL(key);
|
||||
|
||||
// if can't parse value ignore it and break shorthand sequence
|
||||
if (!shorthand.add(property, declaration.value, declaration.info)) {
|
||||
lastShortSelector = null;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
shorts[key] = shorthand;
|
||||
shortDeclarations.push({
|
||||
operation: operation,
|
||||
block: declarations,
|
||||
item: item,
|
||||
shorthand: shorthand
|
||||
});
|
||||
|
||||
lastShortSelector = selector;
|
||||
});
|
||||
|
||||
return lastShortSelector;
|
||||
};
|
||||
|
||||
function processShorthands(shortDeclarations, markDeclaration) {
|
||||
shortDeclarations.forEach(function(item) {
|
||||
var shorthand = item.shorthand;
|
||||
|
||||
if (!shorthand.isOkToMinimize()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (item.operation === REPLACE) {
|
||||
item.item.data = markDeclaration({
|
||||
type: 'Declaration',
|
||||
info: shorthand.info,
|
||||
property: shorthand.getProperty(),
|
||||
value: shorthand.getValue(),
|
||||
id: 0,
|
||||
length: 0,
|
||||
fingerprint: null
|
||||
});
|
||||
} else {
|
||||
item.block.remove(item.item);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
module.exports = function restructBlock(ast, indexer) {
|
||||
var stylesheetMap = {};
|
||||
var shortDeclarations = [];
|
||||
|
||||
walkRulesRight(ast, function(node) {
|
||||
if (node.type !== 'Ruleset') {
|
||||
return;
|
||||
}
|
||||
|
||||
var stylesheet = this.stylesheet;
|
||||
var rulesetId = (node.pseudoSignature || '') + '|' + node.selector.selectors.first().id;
|
||||
var rulesetMap;
|
||||
var shorts;
|
||||
|
||||
if (!stylesheetMap.hasOwnProperty(stylesheet.id)) {
|
||||
rulesetMap = {
|
||||
lastShortSelector: null
|
||||
};
|
||||
stylesheetMap[stylesheet.id] = rulesetMap;
|
||||
} else {
|
||||
rulesetMap = stylesheetMap[stylesheet.id];
|
||||
}
|
||||
|
||||
if (rulesetMap.hasOwnProperty(rulesetId)) {
|
||||
shorts = rulesetMap[rulesetId];
|
||||
} else {
|
||||
shorts = {};
|
||||
rulesetMap[rulesetId] = shorts;
|
||||
}
|
||||
|
||||
rulesetMap.lastShortSelector = processRuleset.call(this, node, shorts, shortDeclarations, rulesetMap.lastShortSelector);
|
||||
});
|
||||
|
||||
processShorthands(shortDeclarations, indexer.declaration);
|
||||
};
|
||||
261
node_modules/csso/lib/compressor/restructure/6-restructBlock.js
generated
vendored
261
node_modules/csso/lib/compressor/restructure/6-restructBlock.js
generated
vendored
@@ -1,261 +0,0 @@
|
||||
var resolveProperty = require('../../utils/names.js').property;
|
||||
var resolveKeyword = require('../../utils/names.js').keyword;
|
||||
var walkRulesRight = require('../../utils/walk.js').rulesRight;
|
||||
var translate = require('../../utils/translate.js');
|
||||
var dontRestructure = {
|
||||
'src': 1 // https://github.com/afelix/csso/issues/50
|
||||
};
|
||||
|
||||
var DONT_MIX_VALUE = {
|
||||
// https://developer.mozilla.org/en-US/docs/Web/CSS/display#Browser_compatibility
|
||||
'display': /table|ruby|flex|-(flex)?box$|grid|contents|run-in/i,
|
||||
// https://developer.mozilla.org/en/docs/Web/CSS/text-align
|
||||
'text-align': /^(start|end|match-parent|justify-all)$/i
|
||||
};
|
||||
|
||||
var CURSOR_SAFE_VALUE = [
|
||||
'auto', 'crosshair', 'default', 'move', 'text', 'wait', 'help',
|
||||
'n-resize', 'e-resize', 's-resize', 'w-resize',
|
||||
'ne-resize', 'nw-resize', 'se-resize', 'sw-resize',
|
||||
'pointer', 'progress', 'not-allowed', 'no-drop', 'vertical-text', 'all-scroll',
|
||||
'col-resize', 'row-resize'
|
||||
];
|
||||
|
||||
var NEEDLESS_TABLE = {
|
||||
'border-width': ['border'],
|
||||
'border-style': ['border'],
|
||||
'border-color': ['border'],
|
||||
'border-top': ['border'],
|
||||
'border-right': ['border'],
|
||||
'border-bottom': ['border'],
|
||||
'border-left': ['border'],
|
||||
'border-top-width': ['border-top', 'border-width', 'border'],
|
||||
'border-right-width': ['border-right', 'border-width', 'border'],
|
||||
'border-bottom-width': ['border-bottom', 'border-width', 'border'],
|
||||
'border-left-width': ['border-left', 'border-width', 'border'],
|
||||
'border-top-style': ['border-top', 'border-style', 'border'],
|
||||
'border-right-style': ['border-right', 'border-style', 'border'],
|
||||
'border-bottom-style': ['border-bottom', 'border-style', 'border'],
|
||||
'border-left-style': ['border-left', 'border-style', 'border'],
|
||||
'border-top-color': ['border-top', 'border-color', 'border'],
|
||||
'border-right-color': ['border-right', 'border-color', 'border'],
|
||||
'border-bottom-color': ['border-bottom', 'border-color', 'border'],
|
||||
'border-left-color': ['border-left', 'border-color', 'border'],
|
||||
'margin-top': ['margin'],
|
||||
'margin-right': ['margin'],
|
||||
'margin-bottom': ['margin'],
|
||||
'margin-left': ['margin'],
|
||||
'padding-top': ['padding'],
|
||||
'padding-right': ['padding'],
|
||||
'padding-bottom': ['padding'],
|
||||
'padding-left': ['padding'],
|
||||
'font-style': ['font'],
|
||||
'font-variant': ['font'],
|
||||
'font-weight': ['font'],
|
||||
'font-size': ['font'],
|
||||
'font-family': ['font'],
|
||||
'list-style-type': ['list-style'],
|
||||
'list-style-position': ['list-style'],
|
||||
'list-style-image': ['list-style']
|
||||
};
|
||||
|
||||
function getPropertyFingerprint(propertyName, declaration, fingerprints) {
|
||||
var realName = resolveProperty(propertyName).name;
|
||||
|
||||
if (realName === 'background' ||
|
||||
(realName === 'filter' && declaration.value.sequence.first().type === 'Progid')) {
|
||||
return propertyName + ':' + translate(declaration.value);
|
||||
}
|
||||
|
||||
var declarationId = declaration.id;
|
||||
var fingerprint = fingerprints[declarationId];
|
||||
|
||||
if (!fingerprint) {
|
||||
var vendorId = '';
|
||||
var iehack = '';
|
||||
var special = {};
|
||||
|
||||
declaration.value.sequence.each(function walk(node) {
|
||||
switch (node.type) {
|
||||
case 'Argument':
|
||||
case 'Value':
|
||||
case 'Braces':
|
||||
node.sequence.each(walk);
|
||||
break;
|
||||
|
||||
case 'Identifier':
|
||||
var name = node.name;
|
||||
|
||||
if (!vendorId) {
|
||||
vendorId = resolveKeyword(name).vendor;
|
||||
}
|
||||
|
||||
if (/\\[09]/.test(name)) {
|
||||
iehack = RegExp.lastMatch;
|
||||
}
|
||||
|
||||
if (realName === 'cursor') {
|
||||
if (CURSOR_SAFE_VALUE.indexOf(name) === -1) {
|
||||
special[name] = true;
|
||||
}
|
||||
} else if (DONT_MIX_VALUE.hasOwnProperty(realName)) {
|
||||
if (DONT_MIX_VALUE[realName].test(name)) {
|
||||
special[name] = true;
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case 'Function':
|
||||
var name = node.name;
|
||||
|
||||
if (!vendorId) {
|
||||
vendorId = resolveKeyword(name).vendor;
|
||||
}
|
||||
|
||||
if (name === 'rect') {
|
||||
// there are 2 forms of rect:
|
||||
// rect(<top>, <right>, <bottom>, <left>) - standart
|
||||
// rect(<top> <right> <bottom> <left>) – backwards compatible syntax
|
||||
// only the same form values can be merged
|
||||
if (node.arguments.size < 4) {
|
||||
name = 'rect-backward';
|
||||
}
|
||||
}
|
||||
|
||||
special[name + '()'] = true;
|
||||
|
||||
// check nested tokens too
|
||||
node.arguments.each(walk);
|
||||
|
||||
break;
|
||||
|
||||
case 'Dimension':
|
||||
var unit = node.unit;
|
||||
|
||||
switch (unit) {
|
||||
// is not supported until IE11
|
||||
case 'rem':
|
||||
|
||||
// v* units is too buggy across browsers and better
|
||||
// don't merge values with those units
|
||||
case 'vw':
|
||||
case 'vh':
|
||||
case 'vmin':
|
||||
case 'vmax':
|
||||
case 'vm': // IE9 supporting "vm" instead of "vmin".
|
||||
special[unit] = true;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
});
|
||||
|
||||
fingerprint = '|' + Object.keys(special).sort() + '|' + iehack + vendorId;
|
||||
|
||||
fingerprints[declarationId] = fingerprint;
|
||||
}
|
||||
|
||||
return propertyName + fingerprint;
|
||||
}
|
||||
|
||||
function needless(props, declaration, fingerprints) {
|
||||
var property = resolveProperty(declaration.property.name);
|
||||
|
||||
if (NEEDLESS_TABLE.hasOwnProperty(property.name)) {
|
||||
var table = NEEDLESS_TABLE[property.name];
|
||||
|
||||
for (var i = 0; i < table.length; i++) {
|
||||
var ppre = getPropertyFingerprint(property.prefix + table[i], declaration, fingerprints);
|
||||
var prev = props[ppre];
|
||||
|
||||
if (prev && (!declaration.value.important || prev.item.data.value.important)) {
|
||||
return prev;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function processRuleset(ruleset, item, list, props, fingerprints) {
|
||||
var declarations = ruleset.block.declarations;
|
||||
|
||||
declarations.eachRight(function(declaration, declarationItem) {
|
||||
var property = declaration.property.name;
|
||||
var fingerprint = getPropertyFingerprint(property, declaration, fingerprints);
|
||||
var prev = props[fingerprint];
|
||||
|
||||
if (prev && !dontRestructure.hasOwnProperty(property)) {
|
||||
if (declaration.value.important && !prev.item.data.value.important) {
|
||||
props[fingerprint] = {
|
||||
block: declarations,
|
||||
item: declarationItem
|
||||
};
|
||||
|
||||
prev.block.remove(prev.item);
|
||||
declaration.info = {
|
||||
primary: declaration.info,
|
||||
merged: prev.item.data.info
|
||||
};
|
||||
} else {
|
||||
declarations.remove(declarationItem);
|
||||
prev.item.data.info = {
|
||||
primary: prev.item.data.info,
|
||||
merged: declaration.info
|
||||
};
|
||||
}
|
||||
} else {
|
||||
var prev = needless(props, declaration, fingerprints);
|
||||
|
||||
if (prev) {
|
||||
declarations.remove(declarationItem);
|
||||
prev.item.data.info = {
|
||||
primary: prev.item.data.info,
|
||||
merged: declaration.info
|
||||
};
|
||||
} else {
|
||||
declaration.fingerprint = fingerprint;
|
||||
|
||||
props[fingerprint] = {
|
||||
block: declarations,
|
||||
item: declarationItem
|
||||
};
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
if (declarations.isEmpty()) {
|
||||
list.remove(item);
|
||||
}
|
||||
};
|
||||
|
||||
module.exports = function restructBlock(ast) {
|
||||
var stylesheetMap = {};
|
||||
var fingerprints = Object.create(null);
|
||||
|
||||
walkRulesRight(ast, function(node, item, list) {
|
||||
if (node.type !== 'Ruleset') {
|
||||
return;
|
||||
}
|
||||
|
||||
var stylesheet = this.stylesheet;
|
||||
var rulesetId = (node.pseudoSignature || '') + '|' + node.selector.selectors.first().id;
|
||||
var rulesetMap;
|
||||
var props;
|
||||
|
||||
if (!stylesheetMap.hasOwnProperty(stylesheet.id)) {
|
||||
rulesetMap = {};
|
||||
stylesheetMap[stylesheet.id] = rulesetMap;
|
||||
} else {
|
||||
rulesetMap = stylesheetMap[stylesheet.id];
|
||||
}
|
||||
|
||||
if (rulesetMap.hasOwnProperty(rulesetId)) {
|
||||
props = rulesetMap[rulesetId];
|
||||
} else {
|
||||
props = {};
|
||||
rulesetMap[rulesetId] = props;
|
||||
}
|
||||
|
||||
processRuleset.call(this, node, item, list, props, fingerprints);
|
||||
});
|
||||
};
|
||||
87
node_modules/csso/lib/compressor/restructure/7-mergeRuleset.js
generated
vendored
87
node_modules/csso/lib/compressor/restructure/7-mergeRuleset.js
generated
vendored
@@ -1,87 +0,0 @@
|
||||
var utils = require('./utils.js');
|
||||
var walkRules = require('../../utils/walk.js').rules;
|
||||
|
||||
/*
|
||||
At this step all rules has single simple selector. We try to join by equal
|
||||
declaration blocks to first rule, e.g.
|
||||
|
||||
.a { color: red }
|
||||
b { ... }
|
||||
.b { color: red }
|
||||
->
|
||||
.a, .b { color: red }
|
||||
b { ... }
|
||||
*/
|
||||
|
||||
function processRuleset(node, item, list) {
|
||||
var selectors = node.selector.selectors;
|
||||
var declarations = node.block.declarations;
|
||||
var nodeCompareMarker = selectors.first().compareMarker;
|
||||
var skippedCompareMarkers = {};
|
||||
|
||||
list.nextUntil(item.next, function(next, nextItem) {
|
||||
// skip non-ruleset node if safe
|
||||
if (next.type !== 'Ruleset') {
|
||||
return utils.unsafeToSkipNode.call(selectors, next);
|
||||
}
|
||||
|
||||
if (node.pseudoSignature !== next.pseudoSignature) {
|
||||
return true;
|
||||
}
|
||||
|
||||
var nextFirstSelector = next.selector.selectors.head;
|
||||
var nextDeclarations = next.block.declarations;
|
||||
var nextCompareMarker = nextFirstSelector.data.compareMarker;
|
||||
|
||||
// if next ruleset has same marked as one of skipped then stop joining
|
||||
if (nextCompareMarker in skippedCompareMarkers) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// try to join by selectors
|
||||
if (selectors.head === selectors.tail) {
|
||||
if (selectors.first().id === nextFirstSelector.data.id) {
|
||||
declarations.appendList(nextDeclarations);
|
||||
list.remove(nextItem);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// try to join by properties
|
||||
if (utils.isEqualDeclarations(declarations, nextDeclarations)) {
|
||||
var nextStr = nextFirstSelector.data.id;
|
||||
|
||||
selectors.some(function(data, item) {
|
||||
var curStr = data.id;
|
||||
|
||||
if (nextStr < curStr) {
|
||||
selectors.insert(nextFirstSelector, item);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!item.next) {
|
||||
selectors.insert(nextFirstSelector);
|
||||
return true;
|
||||
}
|
||||
});
|
||||
|
||||
list.remove(nextItem);
|
||||
return;
|
||||
}
|
||||
|
||||
// go to next ruleset if current one can be skipped (has no equal specificity nor element selector)
|
||||
if (nextCompareMarker === nodeCompareMarker) {
|
||||
return true;
|
||||
}
|
||||
|
||||
skippedCompareMarkers[nextCompareMarker] = true;
|
||||
});
|
||||
};
|
||||
|
||||
module.exports = function mergeRuleset(ast) {
|
||||
walkRules(ast, function(node, item, list) {
|
||||
if (node.type === 'Ruleset') {
|
||||
processRuleset(node, item, list);
|
||||
}
|
||||
});
|
||||
};
|
||||
157
node_modules/csso/lib/compressor/restructure/8-restructRuleset.js
generated
vendored
157
node_modules/csso/lib/compressor/restructure/8-restructRuleset.js
generated
vendored
@@ -1,157 +0,0 @@
|
||||
var List = require('../../utils/list.js');
|
||||
var utils = require('./utils.js');
|
||||
var walkRulesRight = require('../../utils/walk.js').rulesRight;
|
||||
|
||||
function calcSelectorLength(list) {
|
||||
var length = 0;
|
||||
|
||||
list.each(function(data) {
|
||||
length += data.id.length + 1;
|
||||
});
|
||||
|
||||
return length - 1;
|
||||
}
|
||||
|
||||
function calcDeclarationsLength(tokens) {
|
||||
var length = 0;
|
||||
|
||||
for (var i = 0; i < tokens.length; i++) {
|
||||
length += tokens[i].length;
|
||||
}
|
||||
|
||||
return (
|
||||
length + // declarations
|
||||
tokens.length - 1 // delimeters
|
||||
);
|
||||
}
|
||||
|
||||
function processRuleset(node, item, list) {
|
||||
var avoidRulesMerge = this.stylesheet.avoidRulesMerge;
|
||||
var selectors = node.selector.selectors;
|
||||
var block = node.block;
|
||||
var disallowDownMarkers = Object.create(null);
|
||||
var allowMergeUp = true;
|
||||
var allowMergeDown = true;
|
||||
|
||||
list.prevUntil(item.prev, function(prev, prevItem) {
|
||||
// skip non-ruleset node if safe
|
||||
if (prev.type !== 'Ruleset') {
|
||||
return utils.unsafeToSkipNode.call(selectors, prev);
|
||||
}
|
||||
|
||||
var prevSelectors = prev.selector.selectors;
|
||||
var prevBlock = prev.block;
|
||||
|
||||
if (node.pseudoSignature !== prev.pseudoSignature) {
|
||||
return true;
|
||||
}
|
||||
|
||||
allowMergeDown = !prevSelectors.some(function(selector) {
|
||||
return selector.compareMarker in disallowDownMarkers;
|
||||
});
|
||||
|
||||
// try prev ruleset if simpleselectors has no equal specifity and element selector
|
||||
if (!allowMergeDown && !allowMergeUp) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// try to join by selectors
|
||||
if (allowMergeUp && utils.isEqualLists(prevSelectors, selectors)) {
|
||||
prevBlock.declarations.appendList(block.declarations);
|
||||
list.remove(item);
|
||||
return true;
|
||||
}
|
||||
|
||||
// try to join by properties
|
||||
var diff = utils.compareDeclarations(block.declarations, prevBlock.declarations);
|
||||
|
||||
// console.log(diff.eq, diff.ne1, diff.ne2);
|
||||
|
||||
if (diff.eq.length) {
|
||||
if (!diff.ne1.length && !diff.ne2.length) {
|
||||
// equal blocks
|
||||
if (allowMergeDown) {
|
||||
utils.addSelectors(selectors, prevSelectors);
|
||||
list.remove(prevItem);
|
||||
}
|
||||
|
||||
return true;
|
||||
} else if (!avoidRulesMerge) { /* probably we don't need to prevent those merges for @keyframes
|
||||
TODO: need to be checked */
|
||||
|
||||
if (diff.ne1.length && !diff.ne2.length) {
|
||||
// prevBlock is subset block
|
||||
var selectorLength = calcSelectorLength(selectors);
|
||||
var blockLength = calcDeclarationsLength(diff.eq); // declarations length
|
||||
|
||||
if (allowMergeUp && selectorLength < blockLength) {
|
||||
utils.addSelectors(prevSelectors, selectors);
|
||||
block.declarations = new List(diff.ne1);
|
||||
}
|
||||
} else if (!diff.ne1.length && diff.ne2.length) {
|
||||
// node is subset of prevBlock
|
||||
var selectorLength = calcSelectorLength(prevSelectors);
|
||||
var blockLength = calcDeclarationsLength(diff.eq); // declarations length
|
||||
|
||||
if (allowMergeDown && selectorLength < blockLength) {
|
||||
utils.addSelectors(selectors, prevSelectors);
|
||||
prevBlock.declarations = new List(diff.ne2);
|
||||
}
|
||||
} else {
|
||||
// diff.ne1.length && diff.ne2.length
|
||||
// extract equal block
|
||||
var newSelector = {
|
||||
type: 'Selector',
|
||||
info: {},
|
||||
selectors: utils.addSelectors(prevSelectors.copy(), selectors)
|
||||
};
|
||||
var newBlockLength = calcSelectorLength(newSelector.selectors) + 2; // selectors length + curly braces length
|
||||
var blockLength = calcDeclarationsLength(diff.eq); // declarations length
|
||||
|
||||
// create new ruleset if declarations length greater than
|
||||
// ruleset description overhead
|
||||
if (allowMergeDown && blockLength >= newBlockLength) {
|
||||
var newRuleset = {
|
||||
type: 'Ruleset',
|
||||
info: {},
|
||||
pseudoSignature: node.pseudoSignature,
|
||||
selector: newSelector,
|
||||
block: {
|
||||
type: 'Block',
|
||||
info: {},
|
||||
declarations: new List(diff.eq)
|
||||
}
|
||||
};
|
||||
|
||||
block.declarations = new List(diff.ne1);
|
||||
prevBlock.declarations = new List(diff.ne2.concat(diff.ne2overrided));
|
||||
list.insert(list.createItem(newRuleset), prevItem);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (allowMergeUp) {
|
||||
// TODO: disallow up merge only if any property interception only (i.e. diff.ne2overrided.length > 0);
|
||||
// await property families to find property interception correctly
|
||||
allowMergeUp = !prevSelectors.some(function(prevSelector) {
|
||||
return selectors.some(function(selector) {
|
||||
return selector.compareMarker === prevSelector.compareMarker;
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
prevSelectors.each(function(data) {
|
||||
disallowDownMarkers[data.compareMarker] = true;
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
module.exports = function restructRuleset(ast) {
|
||||
walkRulesRight(ast, function(node, item, list) {
|
||||
if (node.type === 'Ruleset') {
|
||||
processRuleset.call(this, node, item, list);
|
||||
}
|
||||
});
|
||||
};
|
||||
35
node_modules/csso/lib/compressor/restructure/index.js
generated
vendored
35
node_modules/csso/lib/compressor/restructure/index.js
generated
vendored
@@ -1,35 +0,0 @@
|
||||
var prepare = require('./prepare/index.js');
|
||||
var initialMergeRuleset = require('./1-initialMergeRuleset.js');
|
||||
var mergeAtrule = require('./2-mergeAtrule.js');
|
||||
var disjoinRuleset = require('./3-disjoinRuleset.js');
|
||||
var restructShorthand = require('./4-restructShorthand.js');
|
||||
var restructBlock = require('./6-restructBlock.js');
|
||||
var mergeRuleset = require('./7-mergeRuleset.js');
|
||||
var restructRuleset = require('./8-restructRuleset.js');
|
||||
|
||||
module.exports = function(ast, usageData, debug) {
|
||||
// prepare ast for restructing
|
||||
var indexer = prepare(ast, usageData);
|
||||
debug('prepare', ast);
|
||||
|
||||
initialMergeRuleset(ast);
|
||||
debug('initialMergeRuleset', ast);
|
||||
|
||||
mergeAtrule(ast);
|
||||
debug('mergeAtrule', ast);
|
||||
|
||||
disjoinRuleset(ast);
|
||||
debug('disjoinRuleset', ast);
|
||||
|
||||
restructShorthand(ast, indexer);
|
||||
debug('restructShorthand', ast);
|
||||
|
||||
restructBlock(ast);
|
||||
debug('restructBlock', ast);
|
||||
|
||||
mergeRuleset(ast);
|
||||
debug('mergeRuleset', ast);
|
||||
|
||||
restructRuleset(ast);
|
||||
debug('restructRuleset', ast);
|
||||
};
|
||||
32
node_modules/csso/lib/compressor/restructure/prepare/createDeclarationIndexer.js
generated
vendored
32
node_modules/csso/lib/compressor/restructure/prepare/createDeclarationIndexer.js
generated
vendored
@@ -1,32 +0,0 @@
|
||||
var translate = require('../../../utils/translate.js');
|
||||
|
||||
function Index() {
|
||||
this.seed = 0;
|
||||
this.map = Object.create(null);
|
||||
}
|
||||
|
||||
Index.prototype.resolve = function(str) {
|
||||
var index = this.map[str];
|
||||
|
||||
if (!index) {
|
||||
index = ++this.seed;
|
||||
this.map[str] = index;
|
||||
}
|
||||
|
||||
return index;
|
||||
};
|
||||
|
||||
module.exports = function createDeclarationIndexer() {
|
||||
var names = new Index();
|
||||
var values = new Index();
|
||||
|
||||
return function markDeclaration(node) {
|
||||
var property = node.property.name;
|
||||
var value = translate(node.value);
|
||||
|
||||
node.id = names.resolve(property) + (values.resolve(value) << 12);
|
||||
node.length = property.length + 1 + value.length;
|
||||
|
||||
return node;
|
||||
};
|
||||
};
|
||||
44
node_modules/csso/lib/compressor/restructure/prepare/index.js
generated
vendored
44
node_modules/csso/lib/compressor/restructure/prepare/index.js
generated
vendored
@@ -1,44 +0,0 @@
|
||||
var resolveKeyword = require('../../../utils/names.js').keyword;
|
||||
var walkRules = require('../../../utils/walk.js').rules;
|
||||
var translate = require('../../../utils/translate.js');
|
||||
var createDeclarationIndexer = require('./createDeclarationIndexer.js');
|
||||
var processSelector = require('./processSelector.js');
|
||||
|
||||
function walk(node, markDeclaration, usageData) {
|
||||
switch (node.type) {
|
||||
case 'Ruleset':
|
||||
node.block.declarations.each(markDeclaration);
|
||||
processSelector(node, usageData);
|
||||
break;
|
||||
|
||||
case 'Atrule':
|
||||
if (node.expression) {
|
||||
node.expression.id = translate(node.expression);
|
||||
}
|
||||
|
||||
// compare keyframe selectors by its values
|
||||
// NOTE: still no clarification about problems with keyframes selector grouping (issue #197)
|
||||
if (resolveKeyword(node.name).name === 'keyframes') {
|
||||
node.block.avoidRulesMerge = true; /* probably we don't need to prevent those merges for @keyframes
|
||||
TODO: need to be checked */
|
||||
node.block.rules.each(function(ruleset) {
|
||||
ruleset.selector.selectors.each(function(simpleselector) {
|
||||
simpleselector.compareMarker = simpleselector.id;
|
||||
});
|
||||
});
|
||||
}
|
||||
break;
|
||||
}
|
||||
};
|
||||
|
||||
module.exports = function prepare(ast, usageData) {
|
||||
var markDeclaration = createDeclarationIndexer();
|
||||
|
||||
walkRules(ast, function(node) {
|
||||
walk(node, markDeclaration, usageData);
|
||||
});
|
||||
|
||||
return {
|
||||
declaration: markDeclaration
|
||||
};
|
||||
};
|
||||
99
node_modules/csso/lib/compressor/restructure/prepare/processSelector.js
generated
vendored
99
node_modules/csso/lib/compressor/restructure/prepare/processSelector.js
generated
vendored
@@ -1,99 +0,0 @@
|
||||
var translate = require('../../../utils/translate.js');
|
||||
var specificity = require('./specificity.js');
|
||||
|
||||
var nonFreezePseudoElements = {
|
||||
'first-letter': true,
|
||||
'first-line': true,
|
||||
'after': true,
|
||||
'before': true
|
||||
};
|
||||
var nonFreezePseudoClasses = {
|
||||
'link': true,
|
||||
'visited': true,
|
||||
'hover': true,
|
||||
'active': true,
|
||||
'first-letter': true,
|
||||
'first-line': true,
|
||||
'after': true,
|
||||
'before': true
|
||||
};
|
||||
|
||||
module.exports = function freeze(node, usageData) {
|
||||
var pseudos = Object.create(null);
|
||||
var hasPseudo = false;
|
||||
|
||||
node.selector.selectors.each(function(simpleSelector) {
|
||||
var tagName = '*';
|
||||
var scope = 0;
|
||||
|
||||
simpleSelector.sequence.some(function(node) {
|
||||
switch (node.type) {
|
||||
case 'Class':
|
||||
if (usageData && usageData.scopes) {
|
||||
var classScope = usageData.scopes[node.name] || 0;
|
||||
|
||||
if (scope !== 0 && classScope !== scope) {
|
||||
throw new Error('Selector can\'t has classes from different scopes: ' + translate(simpleSelector));
|
||||
}
|
||||
|
||||
scope = classScope;
|
||||
}
|
||||
break;
|
||||
|
||||
case 'PseudoClass':
|
||||
if (!nonFreezePseudoClasses.hasOwnProperty(node.name)) {
|
||||
pseudos[node.name] = true;
|
||||
hasPseudo = true;
|
||||
}
|
||||
break;
|
||||
|
||||
case 'PseudoElement':
|
||||
if (!nonFreezePseudoElements.hasOwnProperty(node.name)) {
|
||||
pseudos[node.name] = true;
|
||||
hasPseudo = true;
|
||||
}
|
||||
break;
|
||||
|
||||
case 'FunctionalPseudo':
|
||||
pseudos[node.name] = true;
|
||||
hasPseudo = true;
|
||||
break;
|
||||
|
||||
case 'Negation':
|
||||
pseudos.not = true;
|
||||
hasPseudo = true;
|
||||
break;
|
||||
|
||||
case 'Identifier':
|
||||
tagName = node.name;
|
||||
break;
|
||||
|
||||
case 'Attribute':
|
||||
if (node.flags) {
|
||||
pseudos['[' + node.flags + ']'] = true;
|
||||
hasPseudo = true;
|
||||
}
|
||||
break;
|
||||
|
||||
case 'Combinator':
|
||||
tagName = '*';
|
||||
break;
|
||||
}
|
||||
});
|
||||
|
||||
simpleSelector.id = translate(simpleSelector);
|
||||
simpleSelector.compareMarker = specificity(simpleSelector).toString();
|
||||
|
||||
if (scope) {
|
||||
simpleSelector.compareMarker += ':' + scope;
|
||||
}
|
||||
|
||||
if (tagName !== '*') {
|
||||
simpleSelector.compareMarker += ',' + tagName;
|
||||
}
|
||||
});
|
||||
|
||||
if (hasPseudo) {
|
||||
node.pseudoSignature = Object.keys(pseudos).sort().join(',');
|
||||
}
|
||||
};
|
||||
48
node_modules/csso/lib/compressor/restructure/prepare/specificity.js
generated
vendored
48
node_modules/csso/lib/compressor/restructure/prepare/specificity.js
generated
vendored
@@ -1,48 +0,0 @@
|
||||
module.exports = function specificity(simpleSelector) {
|
||||
var A = 0;
|
||||
var B = 0;
|
||||
var C = 0;
|
||||
|
||||
simpleSelector.sequence.each(function walk(data) {
|
||||
switch (data.type) {
|
||||
case 'SimpleSelector':
|
||||
case 'Negation':
|
||||
data.sequence.each(walk);
|
||||
break;
|
||||
|
||||
case 'Id':
|
||||
A++;
|
||||
break;
|
||||
|
||||
case 'Class':
|
||||
case 'Attribute':
|
||||
case 'FunctionalPseudo':
|
||||
B++;
|
||||
break;
|
||||
|
||||
case 'Identifier':
|
||||
if (data.name !== '*') {
|
||||
C++;
|
||||
}
|
||||
break;
|
||||
|
||||
case 'PseudoElement':
|
||||
C++;
|
||||
break;
|
||||
|
||||
case 'PseudoClass':
|
||||
var name = data.name.toLowerCase();
|
||||
if (name === 'before' ||
|
||||
name === 'after' ||
|
||||
name === 'first-line' ||
|
||||
name === 'first-letter') {
|
||||
C++;
|
||||
} else {
|
||||
B++;
|
||||
}
|
||||
break;
|
||||
}
|
||||
});
|
||||
|
||||
return [A, B, C];
|
||||
};
|
||||
141
node_modules/csso/lib/compressor/restructure/utils.js
generated
vendored
141
node_modules/csso/lib/compressor/restructure/utils.js
generated
vendored
@@ -1,141 +0,0 @@
|
||||
var hasOwnProperty = Object.prototype.hasOwnProperty;
|
||||
|
||||
function isEqualLists(a, b) {
|
||||
var cursor1 = a.head;
|
||||
var cursor2 = b.head;
|
||||
|
||||
while (cursor1 !== null && cursor2 !== null && cursor1.data.id === cursor2.data.id) {
|
||||
cursor1 = cursor1.next;
|
||||
cursor2 = cursor2.next;
|
||||
}
|
||||
|
||||
return cursor1 === null && cursor2 === null;
|
||||
}
|
||||
|
||||
function isEqualDeclarations(a, b) {
|
||||
var cursor1 = a.head;
|
||||
var cursor2 = b.head;
|
||||
|
||||
while (cursor1 !== null && cursor2 !== null && cursor1.data.id === cursor2.data.id) {
|
||||
cursor1 = cursor1.next;
|
||||
cursor2 = cursor2.next;
|
||||
}
|
||||
|
||||
return cursor1 === null && cursor2 === null;
|
||||
}
|
||||
|
||||
function compareDeclarations(declarations1, declarations2) {
|
||||
var result = {
|
||||
eq: [],
|
||||
ne1: [],
|
||||
ne2: [],
|
||||
ne2overrided: []
|
||||
};
|
||||
|
||||
var fingerprints = Object.create(null);
|
||||
var declarations2hash = Object.create(null);
|
||||
|
||||
for (var cursor = declarations2.head; cursor; cursor = cursor.next) {
|
||||
declarations2hash[cursor.data.id] = true;
|
||||
}
|
||||
|
||||
for (var cursor = declarations1.head; cursor; cursor = cursor.next) {
|
||||
var data = cursor.data;
|
||||
|
||||
if (data.fingerprint) {
|
||||
fingerprints[data.fingerprint] = data.value.important;
|
||||
}
|
||||
|
||||
if (declarations2hash[data.id]) {
|
||||
declarations2hash[data.id] = false;
|
||||
result.eq.push(data);
|
||||
} else {
|
||||
result.ne1.push(data);
|
||||
}
|
||||
}
|
||||
|
||||
for (var cursor = declarations2.head; cursor; cursor = cursor.next) {
|
||||
var data = cursor.data;
|
||||
|
||||
if (declarations2hash[data.id]) {
|
||||
// if declarations1 has overriding declaration, this is not a difference
|
||||
// but take in account !important - prev should be equal or greater than follow
|
||||
if (hasOwnProperty.call(fingerprints, data.fingerprint) &&
|
||||
Number(fingerprints[data.fingerprint]) >= Number(data.value.important)) {
|
||||
result.ne2overrided.push(data);
|
||||
} else {
|
||||
result.ne2.push(data);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
function addSelectors(dest, source) {
|
||||
source.each(function(sourceData) {
|
||||
var newStr = sourceData.id;
|
||||
var cursor = dest.head;
|
||||
|
||||
while (cursor) {
|
||||
var nextStr = cursor.data.id;
|
||||
|
||||
if (nextStr === newStr) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (nextStr > newStr) {
|
||||
break;
|
||||
}
|
||||
|
||||
cursor = cursor.next;
|
||||
}
|
||||
|
||||
dest.insert(dest.createItem(sourceData), cursor);
|
||||
});
|
||||
|
||||
return dest;
|
||||
}
|
||||
|
||||
// check if simpleselectors has no equal specificity and element selector
|
||||
function hasSimilarSelectors(selectors1, selectors2) {
|
||||
return selectors1.some(function(a) {
|
||||
return selectors2.some(function(b) {
|
||||
return a.compareMarker === b.compareMarker;
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
// test node can't to be skipped
|
||||
function unsafeToSkipNode(node) {
|
||||
switch (node.type) {
|
||||
case 'Ruleset':
|
||||
// unsafe skip ruleset with selector similarities
|
||||
return hasSimilarSelectors(node.selector.selectors, this);
|
||||
|
||||
case 'Atrule':
|
||||
// can skip at-rules with blocks
|
||||
if (node.block) {
|
||||
// non-stylesheet blocks are safe to skip since have no selectors
|
||||
if (node.block.type !== 'StyleSheet') {
|
||||
return false;
|
||||
}
|
||||
|
||||
// unsafe skip at-rule if block contains something unsafe to skip
|
||||
return node.block.rules.some(unsafeToSkipNode, this);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
// unsafe by default
|
||||
return true;
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
isEqualLists: isEqualLists,
|
||||
isEqualDeclarations: isEqualDeclarations,
|
||||
compareDeclarations: compareDeclarations,
|
||||
addSelectors: addSelectors,
|
||||
hasSimilarSelectors: hasSimilarSelectors,
|
||||
unsafeToSkipNode: unsafeToSkipNode
|
||||
};
|
||||
58
node_modules/csso/lib/compressor/usage.js
generated
vendored
58
node_modules/csso/lib/compressor/usage.js
generated
vendored
@@ -1,58 +0,0 @@
|
||||
var hasOwnProperty = Object.prototype.hasOwnProperty;
|
||||
|
||||
function buildMap(list, caseInsensitive) {
|
||||
var map = Object.create(null);
|
||||
|
||||
if (!Array.isArray(list)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
for (var i = 0; i < list.length; i++) {
|
||||
var name = list[i];
|
||||
|
||||
if (caseInsensitive) {
|
||||
name = name.toLowerCase();
|
||||
}
|
||||
|
||||
map[name] = true;
|
||||
}
|
||||
|
||||
return map;
|
||||
}
|
||||
|
||||
function buildIndex(data) {
|
||||
var scopes = false;
|
||||
|
||||
if (data.scopes && Array.isArray(data.scopes)) {
|
||||
scopes = Object.create(null);
|
||||
|
||||
for (var i = 0; i < data.scopes.length; i++) {
|
||||
var list = data.scopes[i];
|
||||
|
||||
if (!list || !Array.isArray(list)) {
|
||||
throw new Error('Wrong usage format');
|
||||
}
|
||||
|
||||
for (var j = 0; j < list.length; j++) {
|
||||
var name = list[j];
|
||||
|
||||
if (hasOwnProperty.call(scopes, name)) {
|
||||
throw new Error('Class can\'t be used for several scopes: ' + name);
|
||||
}
|
||||
|
||||
scopes[name] = i + 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
tags: buildMap(data.tags, true),
|
||||
ids: buildMap(data.ids),
|
||||
classes: buildMap(data.classes),
|
||||
scopes: scopes
|
||||
};
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
buildIndex: buildIndex
|
||||
};
|
||||
44
node_modules/csso/lib/index.js
generated
vendored
44
node_modules/csso/lib/index.js
generated
vendored
@@ -1,10 +1,7 @@
|
||||
var parse = require('./parser');
|
||||
var compress = require('./compressor');
|
||||
var translate = require('./utils/translate');
|
||||
var translateWithSourceMap = require('./utils/translateWithSourceMap');
|
||||
var walkers = require('./utils/walk');
|
||||
var clone = require('./utils/clone');
|
||||
var List = require('./utils/list');
|
||||
var csstree = require('css-tree');
|
||||
var parse = csstree.parse;
|
||||
var compress = require('./compress');
|
||||
var generate = csstree.generate;
|
||||
|
||||
function debugOutput(name, options, startTime, data) {
|
||||
if (options.debug) {
|
||||
@@ -25,7 +22,7 @@ function createDefaultLogger(level) {
|
||||
}
|
||||
|
||||
if (level > 1 && ast) {
|
||||
var css = translate(ast, true);
|
||||
var css = generate(ast);
|
||||
|
||||
// when level 2, limit css to 256 symbols
|
||||
if (level === 2 && css.length > 256) {
|
||||
@@ -104,17 +101,17 @@ function minify(context, source, options) {
|
||||
);
|
||||
}
|
||||
|
||||
// translate
|
||||
// generate
|
||||
if (options.sourceMap) {
|
||||
result = debugOutput('translateWithSourceMap', options, Date.now(), (function() {
|
||||
var tmp = translateWithSourceMap(compressResult.ast);
|
||||
result = debugOutput('generate(sourceMap: true)', options, Date.now(), (function() {
|
||||
var tmp = generate(compressResult.ast, { sourceMap: true });
|
||||
tmp.map._file = filename; // since other tools can relay on file in source map transform chain
|
||||
tmp.map.setSourceContent(filename, source);
|
||||
return tmp;
|
||||
})());
|
||||
} else {
|
||||
result = debugOutput('translate', options, Date.now(), {
|
||||
css: translate(compressResult.ast),
|
||||
result = debugOutput('generate', options, Date.now(), {
|
||||
css: generate(compressResult.ast),
|
||||
map: null
|
||||
});
|
||||
}
|
||||
@@ -124,33 +121,22 @@ function minify(context, source, options) {
|
||||
|
||||
function minifyStylesheet(source, options) {
|
||||
return minify('stylesheet', source, options);
|
||||
};
|
||||
}
|
||||
|
||||
function minifyBlock(source, options) {
|
||||
return minify('block', source, options);
|
||||
return minify('declarationList', source, options);
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
version: require('../package.json').version,
|
||||
|
||||
// classes
|
||||
List: List,
|
||||
|
||||
// main methods
|
||||
minify: minifyStylesheet,
|
||||
minifyBlock: minifyBlock,
|
||||
|
||||
// step by step
|
||||
parse: parse,
|
||||
// compress an AST
|
||||
compress: compress,
|
||||
translate: translate,
|
||||
translateWithSourceMap: translateWithSourceMap,
|
||||
|
||||
// walkers
|
||||
walk: walkers.all,
|
||||
walkRules: walkers.rules,
|
||||
walkRulesRight: walkers.rulesRight,
|
||||
|
||||
// utils
|
||||
clone: clone
|
||||
// css syntax parser/walkers/generator/etc
|
||||
syntax: csstree
|
||||
};
|
||||
|
||||
46
node_modules/csso/lib/parser/const.js
generated
vendored
46
node_modules/csso/lib/parser/const.js
generated
vendored
@@ -1,46 +0,0 @@
|
||||
exports.TokenType = {
|
||||
String: 'String',
|
||||
Comment: 'Comment',
|
||||
Unknown: 'Unknown',
|
||||
Newline: 'Newline',
|
||||
Space: 'Space',
|
||||
Tab: 'Tab',
|
||||
ExclamationMark: 'ExclamationMark', // !
|
||||
QuotationMark: 'QuotationMark', // "
|
||||
NumberSign: 'NumberSign', // #
|
||||
DollarSign: 'DollarSign', // $
|
||||
PercentSign: 'PercentSign', // %
|
||||
Ampersand: 'Ampersand', // &
|
||||
Apostrophe: 'Apostrophe', // '
|
||||
LeftParenthesis: 'LeftParenthesis', // (
|
||||
RightParenthesis: 'RightParenthesis', // )
|
||||
Asterisk: 'Asterisk', // *
|
||||
PlusSign: 'PlusSign', // +
|
||||
Comma: 'Comma', // ,
|
||||
HyphenMinus: 'HyphenMinus', // -
|
||||
FullStop: 'FullStop', // .
|
||||
Solidus: 'Solidus', // /
|
||||
Colon: 'Colon', // :
|
||||
Semicolon: 'Semicolon', // ;
|
||||
LessThanSign: 'LessThanSign', // <
|
||||
EqualsSign: 'EqualsSign', // =
|
||||
GreaterThanSign: 'GreaterThanSign', // >
|
||||
QuestionMark: 'QuestionMark', // ?
|
||||
CommercialAt: 'CommercialAt', // @
|
||||
LeftSquareBracket: 'LeftSquareBracket', // [
|
||||
ReverseSolidus: 'ReverseSolidus', // \
|
||||
RightSquareBracket: 'RightSquareBracket', // ]
|
||||
CircumflexAccent: 'CircumflexAccent', // ^
|
||||
LowLine: 'LowLine', // _
|
||||
LeftCurlyBracket: 'LeftCurlyBracket', // {
|
||||
VerticalLine: 'VerticalLine', // |
|
||||
RightCurlyBracket: 'RightCurlyBracket', // }
|
||||
Tilde: 'Tilde', // ~
|
||||
Identifier: 'Identifier',
|
||||
DecimalNumber: 'DecimalNumber'
|
||||
};
|
||||
|
||||
// var i = 1;
|
||||
// for (var key in exports.TokenType) {
|
||||
// exports.TokenType[key] = i++;
|
||||
// }
|
||||
1870
node_modules/csso/lib/parser/index.js
generated
vendored
1870
node_modules/csso/lib/parser/index.js
generated
vendored
File diff suppressed because it is too large
Load Diff
380
node_modules/csso/lib/parser/scanner.js
generated
vendored
380
node_modules/csso/lib/parser/scanner.js
generated
vendored
@@ -1,380 +0,0 @@
|
||||
'use strict';
|
||||
|
||||
var TokenType = require('./const.js').TokenType;
|
||||
|
||||
var TAB = 9;
|
||||
var N = 10;
|
||||
var F = 12;
|
||||
var R = 13;
|
||||
var SPACE = 32;
|
||||
var DOUBLE_QUOTE = 34;
|
||||
var QUOTE = 39;
|
||||
var RIGHT_PARENTHESIS = 41;
|
||||
var STAR = 42;
|
||||
var SLASH = 47;
|
||||
var BACK_SLASH = 92;
|
||||
var UNDERSCORE = 95;
|
||||
var LEFT_CURLY_BRACE = 123;
|
||||
var RIGHT_CURLY_BRACE = 125;
|
||||
|
||||
var WHITESPACE = 1;
|
||||
var PUNCTUATOR = 2;
|
||||
var DIGIT = 3;
|
||||
var STRING = 4;
|
||||
|
||||
var PUNCTUATION = {
|
||||
9: TokenType.Tab, // '\t'
|
||||
10: TokenType.Newline, // '\n'
|
||||
13: TokenType.Newline, // '\r'
|
||||
32: TokenType.Space, // ' '
|
||||
33: TokenType.ExclamationMark, // '!'
|
||||
34: TokenType.QuotationMark, // '"'
|
||||
35: TokenType.NumberSign, // '#'
|
||||
36: TokenType.DollarSign, // '$'
|
||||
37: TokenType.PercentSign, // '%'
|
||||
38: TokenType.Ampersand, // '&'
|
||||
39: TokenType.Apostrophe, // '\''
|
||||
40: TokenType.LeftParenthesis, // '('
|
||||
41: TokenType.RightParenthesis, // ')'
|
||||
42: TokenType.Asterisk, // '*'
|
||||
43: TokenType.PlusSign, // '+'
|
||||
44: TokenType.Comma, // ','
|
||||
45: TokenType.HyphenMinus, // '-'
|
||||
46: TokenType.FullStop, // '.'
|
||||
47: TokenType.Solidus, // '/'
|
||||
58: TokenType.Colon, // ':'
|
||||
59: TokenType.Semicolon, // ';'
|
||||
60: TokenType.LessThanSign, // '<'
|
||||
61: TokenType.EqualsSign, // '='
|
||||
62: TokenType.GreaterThanSign, // '>'
|
||||
63: TokenType.QuestionMark, // '?'
|
||||
64: TokenType.CommercialAt, // '@'
|
||||
91: TokenType.LeftSquareBracket, // '['
|
||||
93: TokenType.RightSquareBracket, // ']'
|
||||
94: TokenType.CircumflexAccent, // '^'
|
||||
95: TokenType.LowLine, // '_'
|
||||
123: TokenType.LeftCurlyBracket, // '{'
|
||||
124: TokenType.VerticalLine, // '|'
|
||||
125: TokenType.RightCurlyBracket, // '}'
|
||||
126: TokenType.Tilde // '~'
|
||||
};
|
||||
var SYMBOL_CATEGORY_LENGTH = Math.max.apply(null, Object.keys(PUNCTUATION)) + 1;
|
||||
var SYMBOL_CATEGORY = new Uint32Array(SYMBOL_CATEGORY_LENGTH);
|
||||
var IS_PUNCTUATOR = new Uint32Array(SYMBOL_CATEGORY_LENGTH);
|
||||
|
||||
// fill categories
|
||||
Object.keys(PUNCTUATION).forEach(function(key) {
|
||||
SYMBOL_CATEGORY[Number(key)] = PUNCTUATOR;
|
||||
IS_PUNCTUATOR[Number(key)] = PUNCTUATOR;
|
||||
}, SYMBOL_CATEGORY);
|
||||
|
||||
// don't treat as punctuator
|
||||
IS_PUNCTUATOR[UNDERSCORE] = 0;
|
||||
|
||||
for (var i = 48; i <= 57; i++) {
|
||||
SYMBOL_CATEGORY[i] = DIGIT;
|
||||
}
|
||||
|
||||
SYMBOL_CATEGORY[SPACE] = WHITESPACE;
|
||||
SYMBOL_CATEGORY[TAB] = WHITESPACE;
|
||||
SYMBOL_CATEGORY[N] = WHITESPACE;
|
||||
SYMBOL_CATEGORY[R] = WHITESPACE;
|
||||
SYMBOL_CATEGORY[F] = WHITESPACE;
|
||||
|
||||
SYMBOL_CATEGORY[QUOTE] = STRING;
|
||||
SYMBOL_CATEGORY[DOUBLE_QUOTE] = STRING;
|
||||
|
||||
//
|
||||
// scanner
|
||||
//
|
||||
|
||||
var Scanner = function(source, initBlockMode, initLine, initColumn) {
|
||||
this.source = source;
|
||||
|
||||
this.pos = source.charCodeAt(0) === 0xFEFF ? 1 : 0;
|
||||
this.eof = this.pos === this.source.length;
|
||||
this.line = typeof initLine === 'undefined' ? 1 : initLine;
|
||||
this.lineStartPos = typeof initColumn === 'undefined' ? -1 : -initColumn;
|
||||
|
||||
this.minBlockMode = initBlockMode ? 1 : 0;
|
||||
this.blockMode = this.minBlockMode;
|
||||
this.urlMode = false;
|
||||
|
||||
this.prevToken = null;
|
||||
this.token = null;
|
||||
this.buffer = [];
|
||||
};
|
||||
|
||||
Scanner.prototype = {
|
||||
lookup: function(offset) {
|
||||
if (offset === 0) {
|
||||
return this.token;
|
||||
}
|
||||
|
||||
for (var i = this.buffer.length; !this.eof && i < offset; i++) {
|
||||
this.buffer.push(this.getToken());
|
||||
}
|
||||
|
||||
return offset <= this.buffer.length ? this.buffer[offset - 1] : null;
|
||||
},
|
||||
lookupType: function(offset, type) {
|
||||
var token = this.lookup(offset);
|
||||
|
||||
return token !== null && token.type === type;
|
||||
},
|
||||
next: function() {
|
||||
var newToken = null;
|
||||
|
||||
if (this.buffer.length !== 0) {
|
||||
newToken = this.buffer.shift();
|
||||
} else if (!this.eof) {
|
||||
newToken = this.getToken();
|
||||
}
|
||||
|
||||
this.prevToken = this.token;
|
||||
this.token = newToken;
|
||||
|
||||
return newToken;
|
||||
},
|
||||
|
||||
tokenize: function() {
|
||||
var tokens = [];
|
||||
|
||||
for (; this.pos < this.source.length; this.pos++) {
|
||||
tokens.push(this.getToken());
|
||||
}
|
||||
|
||||
return tokens;
|
||||
},
|
||||
|
||||
getToken: function() {
|
||||
var code = this.source.charCodeAt(this.pos);
|
||||
var line = this.line;
|
||||
var column = this.pos - this.lineStartPos;
|
||||
var offset = this.pos;
|
||||
var next;
|
||||
var type;
|
||||
var value;
|
||||
|
||||
switch (code < SYMBOL_CATEGORY_LENGTH ? SYMBOL_CATEGORY[code] : 0) {
|
||||
case DIGIT:
|
||||
type = TokenType.DecimalNumber;
|
||||
value = this.readDecimalNumber();
|
||||
break;
|
||||
|
||||
case STRING:
|
||||
type = TokenType.String;
|
||||
value = this.readString(code);
|
||||
break;
|
||||
|
||||
case WHITESPACE:
|
||||
type = TokenType.Space;
|
||||
value = this.readSpaces();
|
||||
break;
|
||||
|
||||
case PUNCTUATOR:
|
||||
if (code === SLASH) {
|
||||
next = this.pos + 1 < this.source.length ? this.source.charCodeAt(this.pos + 1) : 0;
|
||||
|
||||
if (next === STAR) { // /*
|
||||
type = TokenType.Comment;
|
||||
value = this.readComment();
|
||||
break;
|
||||
} else if (next === SLASH && !this.urlMode) { // //
|
||||
if (this.blockMode > 0) {
|
||||
var skip = 2;
|
||||
|
||||
while (this.source.charCodeAt(this.pos + 2) === SLASH) {
|
||||
skip++;
|
||||
}
|
||||
|
||||
type = TokenType.Identifier;
|
||||
value = this.readIdentifier(skip);
|
||||
|
||||
this.urlMode = this.urlMode || value === 'url';
|
||||
} else {
|
||||
type = TokenType.Unknown;
|
||||
value = this.readUnknown();
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
type = PUNCTUATION[code];
|
||||
value = String.fromCharCode(code);
|
||||
this.pos++;
|
||||
|
||||
if (code === RIGHT_PARENTHESIS) {
|
||||
this.urlMode = false;
|
||||
} else if (code === LEFT_CURLY_BRACE) {
|
||||
this.blockMode++;
|
||||
} else if (code === RIGHT_CURLY_BRACE) {
|
||||
if (this.blockMode > this.minBlockMode) {
|
||||
this.blockMode--;
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
type = TokenType.Identifier;
|
||||
value = this.readIdentifier(0);
|
||||
|
||||
this.urlMode = this.urlMode || value === 'url';
|
||||
}
|
||||
|
||||
this.eof = this.pos === this.source.length;
|
||||
|
||||
return {
|
||||
type: type,
|
||||
value: value,
|
||||
|
||||
offset: offset,
|
||||
line: line,
|
||||
column: column
|
||||
};
|
||||
},
|
||||
|
||||
isNewline: function(code) {
|
||||
if (code === N || code === F || code === R) {
|
||||
if (code === R && this.pos + 1 < this.source.length && this.source.charCodeAt(this.pos + 1) === N) {
|
||||
this.pos++;
|
||||
}
|
||||
|
||||
this.line++;
|
||||
this.lineStartPos = this.pos;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
},
|
||||
|
||||
readSpaces: function() {
|
||||
var start = this.pos;
|
||||
|
||||
for (; this.pos < this.source.length; this.pos++) {
|
||||
var code = this.source.charCodeAt(this.pos);
|
||||
|
||||
if (!this.isNewline(code) && code !== SPACE && code !== TAB) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return this.source.substring(start, this.pos);
|
||||
},
|
||||
|
||||
readComment: function() {
|
||||
var start = this.pos;
|
||||
|
||||
for (this.pos += 2; this.pos < this.source.length; this.pos++) {
|
||||
var code = this.source.charCodeAt(this.pos);
|
||||
|
||||
if (code === STAR) { // */
|
||||
if (this.source.charCodeAt(this.pos + 1) === SLASH) {
|
||||
this.pos += 2;
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
this.isNewline(code);
|
||||
}
|
||||
}
|
||||
|
||||
return this.source.substring(start, this.pos);
|
||||
},
|
||||
|
||||
readUnknown: function() {
|
||||
var start = this.pos;
|
||||
|
||||
for (this.pos += 2; this.pos < this.source.length; this.pos++) {
|
||||
if (this.isNewline(this.source.charCodeAt(this.pos), this.source)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return this.source.substring(start, this.pos);
|
||||
},
|
||||
|
||||
readString: function(quote) {
|
||||
var start = this.pos;
|
||||
var res = '';
|
||||
|
||||
for (this.pos++; this.pos < this.source.length; this.pos++) {
|
||||
var code = this.source.charCodeAt(this.pos);
|
||||
|
||||
if (code === BACK_SLASH) {
|
||||
var end = this.pos++;
|
||||
|
||||
if (this.isNewline(this.source.charCodeAt(this.pos), this.source)) {
|
||||
res += this.source.substring(start, end);
|
||||
start = this.pos + 1;
|
||||
}
|
||||
} else if (code === quote) {
|
||||
this.pos++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return res + this.source.substring(start, this.pos);
|
||||
},
|
||||
|
||||
readDecimalNumber: function() {
|
||||
var start = this.pos;
|
||||
var code;
|
||||
|
||||
for (this.pos++; this.pos < this.source.length; this.pos++) {
|
||||
code = this.source.charCodeAt(this.pos);
|
||||
|
||||
if (code < 48 || code > 57) { // 0 .. 9
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return this.source.substring(start, this.pos);
|
||||
},
|
||||
|
||||
readIdentifier: function(skip) {
|
||||
var start = this.pos;
|
||||
|
||||
for (this.pos += skip; this.pos < this.source.length; this.pos++) {
|
||||
var code = this.source.charCodeAt(this.pos);
|
||||
|
||||
if (code === BACK_SLASH) {
|
||||
this.pos++;
|
||||
|
||||
// skip escaped unicode sequence that can ends with space
|
||||
// [0-9a-f]{1,6}(\r\n|[ \n\r\t\f])?
|
||||
for (var i = 0; i < 7 && this.pos + i < this.source.length; i++) {
|
||||
code = this.source.charCodeAt(this.pos + i);
|
||||
|
||||
if (i !== 6) {
|
||||
if ((code >= 48 && code <= 57) || // 0 .. 9
|
||||
(code >= 65 && code <= 70) || // A .. F
|
||||
(code >= 97 && code <= 102)) { // a .. f
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (i > 0) {
|
||||
this.pos += i - 1;
|
||||
if (code === SPACE || code === TAB || this.isNewline(code)) {
|
||||
this.pos++;
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
} else if (code < SYMBOL_CATEGORY_LENGTH &&
|
||||
IS_PUNCTUATOR[code] === PUNCTUATOR) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return this.source.substring(start, this.pos);
|
||||
}
|
||||
};
|
||||
|
||||
// warm up tokenizer to elimitate code branches that never execute
|
||||
// fix soft deoptimizations (insufficient type feedback)
|
||||
new Scanner('\n\r\r\n\f//""\'\'/**/1a;.{url(a)}').lookup(1e3);
|
||||
|
||||
module.exports = Scanner;
|
||||
23
node_modules/csso/lib/utils/clone.js
generated
vendored
23
node_modules/csso/lib/utils/clone.js
generated
vendored
@@ -1,23 +0,0 @@
|
||||
var List = require('./list');
|
||||
|
||||
module.exports = function clone(node) {
|
||||
var result = {};
|
||||
|
||||
for (var key in node) {
|
||||
var value = node[key];
|
||||
|
||||
if (value) {
|
||||
if (Array.isArray(value)) {
|
||||
value = value.slice(0);
|
||||
} else if (value instanceof List) {
|
||||
value = new List(value.map(clone));
|
||||
} else if (value.constructor === Object) {
|
||||
value = clone(value);
|
||||
}
|
||||
}
|
||||
|
||||
result[key] = value;
|
||||
}
|
||||
|
||||
return result;
|
||||
};
|
||||
389
node_modules/csso/lib/utils/list.js
generated
vendored
389
node_modules/csso/lib/utils/list.js
generated
vendored
@@ -1,389 +0,0 @@
|
||||
//
|
||||
// item item item item
|
||||
// /------\ /------\ /------\ /------\
|
||||
// | data | | data | | data | | data |
|
||||
// null <--+-prev |<---+-prev |<---+-prev |<---+-prev |
|
||||
// | next-+--->| next-+--->| next-+--->| next-+--> null
|
||||
// \------/ \------/ \------/ \------/
|
||||
// ^ ^
|
||||
// | list |
|
||||
// | /------\ |
|
||||
// \--------------+-head | |
|
||||
// | tail-+--------------/
|
||||
// \------/
|
||||
//
|
||||
|
||||
function createItem(data) {
|
||||
return {
|
||||
data: data,
|
||||
next: null,
|
||||
prev: null
|
||||
};
|
||||
}
|
||||
|
||||
var List = function(values) {
|
||||
this.cursor = null;
|
||||
this.head = null;
|
||||
this.tail = null;
|
||||
|
||||
if (Array.isArray(values)) {
|
||||
var cursor = null;
|
||||
|
||||
for (var i = 0; i < values.length; i++) {
|
||||
var item = createItem(values[i]);
|
||||
|
||||
if (cursor !== null) {
|
||||
cursor.next = item;
|
||||
} else {
|
||||
this.head = item;
|
||||
}
|
||||
|
||||
item.prev = cursor;
|
||||
cursor = item;
|
||||
}
|
||||
|
||||
this.tail = cursor;
|
||||
}
|
||||
};
|
||||
|
||||
Object.defineProperty(List.prototype, 'size', {
|
||||
get: function() {
|
||||
var size = 0;
|
||||
var cursor = this.head;
|
||||
|
||||
while (cursor) {
|
||||
size++;
|
||||
cursor = cursor.next;
|
||||
}
|
||||
|
||||
return size;
|
||||
}
|
||||
});
|
||||
|
||||
List.createItem = createItem;
|
||||
List.prototype.createItem = createItem;
|
||||
|
||||
List.prototype.toArray = function() {
|
||||
var cursor = this.head;
|
||||
var result = [];
|
||||
|
||||
while (cursor) {
|
||||
result.push(cursor.data);
|
||||
cursor = cursor.next;
|
||||
}
|
||||
|
||||
return result;
|
||||
};
|
||||
List.prototype.toJSON = function() {
|
||||
return this.toArray();
|
||||
};
|
||||
|
||||
List.prototype.isEmpty = function() {
|
||||
return this.head === null;
|
||||
};
|
||||
|
||||
List.prototype.first = function() {
|
||||
return this.head && this.head.data;
|
||||
};
|
||||
|
||||
List.prototype.last = function() {
|
||||
return this.tail && this.tail.data;
|
||||
};
|
||||
|
||||
List.prototype.each = function(fn, context) {
|
||||
var item;
|
||||
var cursor = {
|
||||
prev: null,
|
||||
next: this.head,
|
||||
cursor: this.cursor
|
||||
};
|
||||
|
||||
if (context === undefined) {
|
||||
context = this;
|
||||
}
|
||||
|
||||
// push cursor
|
||||
this.cursor = cursor;
|
||||
|
||||
while (cursor.next !== null) {
|
||||
item = cursor.next;
|
||||
cursor.next = item.next;
|
||||
|
||||
fn.call(context, item.data, item, this);
|
||||
}
|
||||
|
||||
// pop cursor
|
||||
this.cursor = this.cursor.cursor;
|
||||
};
|
||||
|
||||
List.prototype.eachRight = function(fn, context) {
|
||||
var item;
|
||||
var cursor = {
|
||||
prev: this.tail,
|
||||
next: null,
|
||||
cursor: this.cursor
|
||||
};
|
||||
|
||||
if (context === undefined) {
|
||||
context = this;
|
||||
}
|
||||
|
||||
// push cursor
|
||||
this.cursor = cursor;
|
||||
|
||||
while (cursor.prev !== null) {
|
||||
item = cursor.prev;
|
||||
cursor.prev = item.prev;
|
||||
|
||||
fn.call(context, item.data, item, this);
|
||||
}
|
||||
|
||||
// pop cursor
|
||||
this.cursor = this.cursor.cursor;
|
||||
};
|
||||
|
||||
List.prototype.nextUntil = function(start, fn, context) {
|
||||
if (start === null) {
|
||||
return;
|
||||
}
|
||||
|
||||
var item;
|
||||
var cursor = {
|
||||
prev: null,
|
||||
next: start,
|
||||
cursor: this.cursor
|
||||
};
|
||||
|
||||
if (context === undefined) {
|
||||
context = this;
|
||||
}
|
||||
|
||||
// push cursor
|
||||
this.cursor = cursor;
|
||||
|
||||
while (cursor.next !== null) {
|
||||
item = cursor.next;
|
||||
cursor.next = item.next;
|
||||
|
||||
if (fn.call(context, item.data, item, this)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// pop cursor
|
||||
this.cursor = this.cursor.cursor;
|
||||
};
|
||||
|
||||
List.prototype.prevUntil = function(start, fn, context) {
|
||||
if (start === null) {
|
||||
return;
|
||||
}
|
||||
|
||||
var item;
|
||||
var cursor = {
|
||||
prev: start,
|
||||
next: null,
|
||||
cursor: this.cursor
|
||||
};
|
||||
|
||||
if (context === undefined) {
|
||||
context = this;
|
||||
}
|
||||
|
||||
// push cursor
|
||||
this.cursor = cursor;
|
||||
|
||||
while (cursor.prev !== null) {
|
||||
item = cursor.prev;
|
||||
cursor.prev = item.prev;
|
||||
|
||||
if (fn.call(context, item.data, item, this)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// pop cursor
|
||||
this.cursor = this.cursor.cursor;
|
||||
};
|
||||
|
||||
List.prototype.some = function(fn, context) {
|
||||
var cursor = this.head;
|
||||
|
||||
if (context === undefined) {
|
||||
context = this;
|
||||
}
|
||||
|
||||
while (cursor !== null) {
|
||||
if (fn.call(context, cursor.data, cursor, this)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
cursor = cursor.next;
|
||||
}
|
||||
|
||||
return false;
|
||||
};
|
||||
|
||||
List.prototype.map = function(fn, context) {
|
||||
var result = [];
|
||||
var cursor = this.head;
|
||||
|
||||
if (context === undefined) {
|
||||
context = this;
|
||||
}
|
||||
|
||||
while (cursor !== null) {
|
||||
result.push(fn.call(context, cursor.data, cursor, this));
|
||||
cursor = cursor.next;
|
||||
}
|
||||
|
||||
return result;
|
||||
};
|
||||
|
||||
List.prototype.copy = function() {
|
||||
var result = new List();
|
||||
var cursor = this.head;
|
||||
|
||||
while (cursor !== null) {
|
||||
result.insert(createItem(cursor.data));
|
||||
cursor = cursor.next;
|
||||
}
|
||||
|
||||
return result;
|
||||
};
|
||||
|
||||
List.prototype.updateCursors = function(prevOld, prevNew, nextOld, nextNew) {
|
||||
var cursor = this.cursor;
|
||||
|
||||
while (cursor !== null) {
|
||||
if (prevNew === true || cursor.prev === prevOld) {
|
||||
cursor.prev = prevNew;
|
||||
}
|
||||
|
||||
if (nextNew === true || cursor.next === nextOld) {
|
||||
cursor.next = nextNew;
|
||||
}
|
||||
|
||||
cursor = cursor.cursor;
|
||||
}
|
||||
};
|
||||
|
||||
List.prototype.insert = function(item, before) {
|
||||
if (before !== undefined && before !== null) {
|
||||
// prev before
|
||||
// ^
|
||||
// item
|
||||
this.updateCursors(before.prev, item, before, item);
|
||||
|
||||
if (before.prev === null) {
|
||||
// insert to the beginning of list
|
||||
if (this.head !== before) {
|
||||
throw new Error('before doesn\'t below to list');
|
||||
}
|
||||
|
||||
// since head points to before therefore list doesn't empty
|
||||
// no need to check tail
|
||||
this.head = item;
|
||||
before.prev = item;
|
||||
item.next = before;
|
||||
|
||||
this.updateCursors(null, item);
|
||||
} else {
|
||||
|
||||
// insert between two items
|
||||
before.prev.next = item;
|
||||
item.prev = before.prev;
|
||||
|
||||
before.prev = item;
|
||||
item.next = before;
|
||||
}
|
||||
} else {
|
||||
// tail
|
||||
// ^
|
||||
// item
|
||||
this.updateCursors(this.tail, item, null, item);
|
||||
|
||||
// insert to end of the list
|
||||
if (this.tail !== null) {
|
||||
// if list has a tail, then it also has a head, but head doesn't change
|
||||
|
||||
// last item -> new item
|
||||
this.tail.next = item;
|
||||
|
||||
// last item <- new item
|
||||
item.prev = this.tail;
|
||||
} else {
|
||||
// if list has no a tail, then it also has no a head
|
||||
// in this case points head to new item
|
||||
this.head = item;
|
||||
}
|
||||
|
||||
// tail always start point to new item
|
||||
this.tail = item;
|
||||
}
|
||||
};
|
||||
|
||||
List.prototype.remove = function(item) {
|
||||
// item
|
||||
// ^
|
||||
// prev next
|
||||
this.updateCursors(item, item.prev, item, item.next);
|
||||
|
||||
if (item.prev !== null) {
|
||||
item.prev.next = item.next;
|
||||
} else {
|
||||
if (this.head !== item) {
|
||||
throw new Error('item doesn\'t below to list');
|
||||
}
|
||||
|
||||
this.head = item.next;
|
||||
}
|
||||
|
||||
if (item.next !== null) {
|
||||
item.next.prev = item.prev;
|
||||
} else {
|
||||
if (this.tail !== item) {
|
||||
throw new Error('item doesn\'t below to list');
|
||||
}
|
||||
|
||||
this.tail = item.prev;
|
||||
}
|
||||
|
||||
item.prev = null;
|
||||
item.next = null;
|
||||
|
||||
return item;
|
||||
};
|
||||
|
||||
List.prototype.appendList = function(list) {
|
||||
// ignore empty lists
|
||||
if (list.head === null) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.updateCursors(this.tail, list.tail, null, list.head);
|
||||
|
||||
// insert to end of the list
|
||||
if (this.tail !== null) {
|
||||
// if destination list has a tail, then it also has a head,
|
||||
// but head doesn't change
|
||||
|
||||
// dest tail -> source head
|
||||
this.tail.next = list.head;
|
||||
|
||||
// dest tail <- source head
|
||||
list.head.prev = this.tail;
|
||||
} else {
|
||||
// if list has no a tail, then it also has no a head
|
||||
// in this case points head to new item
|
||||
this.head = list.head;
|
||||
}
|
||||
|
||||
// tail always start point to new item
|
||||
this.tail = list.tail;
|
||||
|
||||
list.head = null;
|
||||
list.tail = null;
|
||||
};
|
||||
|
||||
module.exports = List;
|
||||
73
node_modules/csso/lib/utils/names.js
generated
vendored
73
node_modules/csso/lib/utils/names.js
generated
vendored
@@ -1,73 +0,0 @@
|
||||
var hasOwnProperty = Object.prototype.hasOwnProperty;
|
||||
var knownKeywords = Object.create(null);
|
||||
var knownProperties = Object.create(null);
|
||||
|
||||
function getVendorPrefix(string) {
|
||||
if (string[0] === '-') {
|
||||
// skip 2 chars to avoid wrong match with variables names
|
||||
var secondDashIndex = string.indexOf('-', 2);
|
||||
|
||||
if (secondDashIndex !== -1) {
|
||||
return string.substr(0, secondDashIndex + 1);
|
||||
}
|
||||
}
|
||||
|
||||
return '';
|
||||
}
|
||||
|
||||
function getKeywordInfo(keyword) {
|
||||
if (hasOwnProperty.call(knownKeywords, keyword)) {
|
||||
return knownKeywords[keyword];
|
||||
}
|
||||
|
||||
var lowerCaseKeyword = keyword.toLowerCase();
|
||||
var vendor = getVendorPrefix(lowerCaseKeyword);
|
||||
var name = lowerCaseKeyword;
|
||||
|
||||
if (vendor) {
|
||||
name = name.substr(vendor.length);
|
||||
}
|
||||
|
||||
return knownKeywords[keyword] = Object.freeze({
|
||||
vendor: vendor,
|
||||
prefix: vendor,
|
||||
name: name
|
||||
});
|
||||
}
|
||||
|
||||
function getPropertyInfo(property) {
|
||||
if (hasOwnProperty.call(knownProperties, property)) {
|
||||
return knownProperties[property];
|
||||
}
|
||||
|
||||
var lowerCaseProperty = property.toLowerCase();
|
||||
var hack = lowerCaseProperty[0];
|
||||
|
||||
if (hack === '*' || hack === '_' || hack === '$') {
|
||||
lowerCaseProperty = lowerCaseProperty.substr(1);
|
||||
} else if (hack === '/' && property[1] === '/') {
|
||||
hack = '//';
|
||||
lowerCaseProperty = lowerCaseProperty.substr(2);
|
||||
} else {
|
||||
hack = '';
|
||||
}
|
||||
|
||||
var vendor = getVendorPrefix(lowerCaseProperty);
|
||||
var name = lowerCaseProperty;
|
||||
|
||||
if (vendor) {
|
||||
name = name.substr(vendor.length);
|
||||
}
|
||||
|
||||
return knownProperties[property] = Object.freeze({
|
||||
hack: hack,
|
||||
vendor: vendor,
|
||||
prefix: hack + vendor,
|
||||
name: name
|
||||
});
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
keyword: getKeywordInfo,
|
||||
property: getPropertyInfo
|
||||
};
|
||||
178
node_modules/csso/lib/utils/translate.js
generated
vendored
178
node_modules/csso/lib/utils/translate.js
generated
vendored
@@ -1,178 +0,0 @@
|
||||
function each(list) {
|
||||
if (list.head === null) {
|
||||
return '';
|
||||
}
|
||||
|
||||
if (list.head === list.tail) {
|
||||
return translate(list.head.data);
|
||||
}
|
||||
|
||||
return list.map(translate).join('');
|
||||
}
|
||||
|
||||
function eachDelim(list, delimeter) {
|
||||
if (list.head === null) {
|
||||
return '';
|
||||
}
|
||||
|
||||
if (list.head === list.tail) {
|
||||
return translate(list.head.data);
|
||||
}
|
||||
|
||||
return list.map(translate).join(delimeter);
|
||||
}
|
||||
|
||||
function translate(node) {
|
||||
switch (node.type) {
|
||||
case 'StyleSheet':
|
||||
return each(node.rules);
|
||||
|
||||
case 'Atrule':
|
||||
var nodes = ['@', node.name];
|
||||
|
||||
if (node.expression && !node.expression.sequence.isEmpty()) {
|
||||
nodes.push(' ', translate(node.expression));
|
||||
}
|
||||
|
||||
if (node.block) {
|
||||
nodes.push('{', translate(node.block), '}');
|
||||
} else {
|
||||
nodes.push(';');
|
||||
}
|
||||
|
||||
return nodes.join('');
|
||||
|
||||
case 'Ruleset':
|
||||
return translate(node.selector) + '{' + translate(node.block) + '}';
|
||||
|
||||
case 'Selector':
|
||||
return eachDelim(node.selectors, ',');
|
||||
|
||||
case 'SimpleSelector':
|
||||
var nodes = node.sequence.map(function(node) {
|
||||
// add extra spaces around /deep/ combinator since comment beginning/ending may to be produced
|
||||
if (node.type === 'Combinator' && node.name === '/deep/') {
|
||||
return ' ' + translate(node) + ' ';
|
||||
}
|
||||
|
||||
return translate(node);
|
||||
});
|
||||
|
||||
return nodes.join('');
|
||||
|
||||
case 'Block':
|
||||
return eachDelim(node.declarations, ';');
|
||||
|
||||
case 'Declaration':
|
||||
return translate(node.property) + ':' + translate(node.value);
|
||||
|
||||
case 'Property':
|
||||
return node.name;
|
||||
|
||||
case 'Value':
|
||||
return node.important
|
||||
? each(node.sequence) + '!important'
|
||||
: each(node.sequence);
|
||||
|
||||
case 'Attribute':
|
||||
var result = translate(node.name);
|
||||
var flagsPrefix = ' ';
|
||||
|
||||
if (node.operator !== null) {
|
||||
result += node.operator;
|
||||
|
||||
if (node.value !== null) {
|
||||
result += translate(node.value);
|
||||
|
||||
// space between string and flags is not required
|
||||
if (node.value.type === 'String') {
|
||||
flagsPrefix = '';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (node.flags !== null) {
|
||||
result += flagsPrefix + node.flags;
|
||||
}
|
||||
|
||||
return '[' + result + ']';
|
||||
|
||||
case 'FunctionalPseudo':
|
||||
return ':' + node.name + '(' + eachDelim(node.arguments, ',') + ')';
|
||||
|
||||
case 'Function':
|
||||
return node.name + '(' + eachDelim(node.arguments, ',') + ')';
|
||||
|
||||
case 'Negation':
|
||||
return ':not(' + eachDelim(node.sequence, ',') + ')';
|
||||
|
||||
case 'Braces':
|
||||
return node.open + each(node.sequence) + node.close;
|
||||
|
||||
case 'Argument':
|
||||
case 'AtruleExpression':
|
||||
return each(node.sequence);
|
||||
|
||||
case 'Url':
|
||||
return 'url(' + translate(node.value) + ')';
|
||||
|
||||
case 'Progid':
|
||||
return translate(node.value);
|
||||
|
||||
case 'Combinator':
|
||||
return node.name;
|
||||
|
||||
case 'Identifier':
|
||||
return node.name;
|
||||
|
||||
case 'PseudoClass':
|
||||
return ':' + node.name;
|
||||
|
||||
case 'PseudoElement':
|
||||
return '::' + node.name;
|
||||
|
||||
case 'Class':
|
||||
return '.' + node.name;
|
||||
|
||||
case 'Id':
|
||||
return '#' + node.name;
|
||||
|
||||
case 'Hash':
|
||||
return '#' + node.value;
|
||||
|
||||
case 'Dimension':
|
||||
return node.value + node.unit;
|
||||
|
||||
case 'Nth':
|
||||
return node.value;
|
||||
|
||||
case 'Number':
|
||||
return node.value;
|
||||
|
||||
case 'String':
|
||||
return node.value;
|
||||
|
||||
case 'Operator':
|
||||
return node.value;
|
||||
|
||||
case 'Raw':
|
||||
return node.value;
|
||||
|
||||
case 'Unknown':
|
||||
return node.value;
|
||||
|
||||
case 'Percentage':
|
||||
return node.value + '%';
|
||||
|
||||
case 'Space':
|
||||
return ' ';
|
||||
|
||||
case 'Comment':
|
||||
return '/*' + node.value + '*/';
|
||||
|
||||
default:
|
||||
throw new Error('Unknown node type: ' + node.type);
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = translate;
|
||||
291
node_modules/csso/lib/utils/translateWithSourceMap.js
generated
vendored
291
node_modules/csso/lib/utils/translateWithSourceMap.js
generated
vendored
@@ -1,291 +0,0 @@
|
||||
var SourceMapGenerator = require('source-map').SourceMapGenerator;
|
||||
var SourceNode = require('source-map').SourceNode;
|
||||
|
||||
// Our own implementation of SourceNode#toStringWithSourceMap,
|
||||
// since SourceNode doesn't allow multiple references to original source.
|
||||
// Also, as we know structure of result we could be optimize generation
|
||||
// (currently it's ~40% faster).
|
||||
function walk(node, fn) {
|
||||
for (var chunk, i = 0; i < node.children.length; i++) {
|
||||
chunk = node.children[i];
|
||||
|
||||
if (chunk instanceof SourceNode) {
|
||||
// this is a hack, because source maps doesn't support for 1(generated):N(original)
|
||||
// if (chunk.merged) {
|
||||
// fn('', chunk);
|
||||
// }
|
||||
|
||||
walk(chunk, fn);
|
||||
} else {
|
||||
fn(chunk, node);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function generateSourceMap(root) {
|
||||
var map = new SourceMapGenerator();
|
||||
var css = '';
|
||||
var sourceMappingActive = false;
|
||||
var lastOriginalLine = null;
|
||||
var lastOriginalColumn = null;
|
||||
var lastIndexOfNewline;
|
||||
var generated = {
|
||||
line: 1,
|
||||
column: 0
|
||||
};
|
||||
var activatedMapping = {
|
||||
generated: generated
|
||||
};
|
||||
|
||||
walk(root, function(chunk, original) {
|
||||
if (original.line !== null &&
|
||||
original.column !== null) {
|
||||
if (lastOriginalLine !== original.line ||
|
||||
lastOriginalColumn !== original.column) {
|
||||
map.addMapping({
|
||||
source: original.source,
|
||||
original: original,
|
||||
generated: generated
|
||||
});
|
||||
}
|
||||
|
||||
lastOriginalLine = original.line;
|
||||
lastOriginalColumn = original.column;
|
||||
sourceMappingActive = true;
|
||||
} else if (sourceMappingActive) {
|
||||
map.addMapping(activatedMapping);
|
||||
sourceMappingActive = false;
|
||||
}
|
||||
|
||||
css += chunk;
|
||||
|
||||
lastIndexOfNewline = chunk.lastIndexOf('\n');
|
||||
if (lastIndexOfNewline !== -1) {
|
||||
generated.line += chunk.match(/\n/g).length;
|
||||
generated.column = chunk.length - lastIndexOfNewline - 1;
|
||||
} else {
|
||||
generated.column += chunk.length;
|
||||
}
|
||||
});
|
||||
|
||||
return {
|
||||
css: css,
|
||||
map: map
|
||||
};
|
||||
}
|
||||
|
||||
function createAnonymousSourceNode(children) {
|
||||
return new SourceNode(
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
children
|
||||
);
|
||||
}
|
||||
|
||||
function createSourceNode(info, children) {
|
||||
if (info.primary) {
|
||||
// special marker node to add several references to original
|
||||
// var merged = createSourceNode(info.merged, []);
|
||||
// merged.merged = true;
|
||||
// children.unshift(merged);
|
||||
|
||||
// use recursion, because primary can also has a primary/merged info
|
||||
return createSourceNode(info.primary, children);
|
||||
}
|
||||
|
||||
return new SourceNode(
|
||||
info.line,
|
||||
info.column - 1,
|
||||
info.source,
|
||||
children
|
||||
);
|
||||
}
|
||||
|
||||
function each(list) {
|
||||
if (list.head === null) {
|
||||
return '';
|
||||
}
|
||||
|
||||
if (list.head === list.tail) {
|
||||
return translate(list.head.data);
|
||||
}
|
||||
|
||||
return list.map(translate).join('');
|
||||
}
|
||||
|
||||
function eachDelim(list, delimeter) {
|
||||
if (list.head === null) {
|
||||
return '';
|
||||
}
|
||||
|
||||
if (list.head === list.tail) {
|
||||
return translate(list.head.data);
|
||||
}
|
||||
|
||||
return list.map(translate).join(delimeter);
|
||||
}
|
||||
|
||||
function translate(node) {
|
||||
switch (node.type) {
|
||||
case 'StyleSheet':
|
||||
return createAnonymousSourceNode(node.rules.map(translate));
|
||||
|
||||
case 'Atrule':
|
||||
var nodes = ['@', node.name];
|
||||
|
||||
if (node.expression && !node.expression.sequence.isEmpty()) {
|
||||
nodes.push(' ', translate(node.expression));
|
||||
}
|
||||
|
||||
if (node.block) {
|
||||
nodes.push('{', translate(node.block), '}');
|
||||
} else {
|
||||
nodes.push(';');
|
||||
}
|
||||
|
||||
return createSourceNode(node.info, nodes);
|
||||
|
||||
case 'Ruleset':
|
||||
return createAnonymousSourceNode([
|
||||
translate(node.selector), '{', translate(node.block), '}'
|
||||
]);
|
||||
|
||||
case 'Selector':
|
||||
return createAnonymousSourceNode(node.selectors.map(translate)).join(',');
|
||||
|
||||
case 'SimpleSelector':
|
||||
var nodes = node.sequence.map(function(node) {
|
||||
// add extra spaces around /deep/ combinator since comment beginning/ending may to be produced
|
||||
if (node.type === 'Combinator' && node.name === '/deep/') {
|
||||
return ' ' + translate(node) + ' ';
|
||||
}
|
||||
|
||||
return translate(node);
|
||||
});
|
||||
|
||||
return createSourceNode(node.info, nodes);
|
||||
|
||||
case 'Block':
|
||||
return createAnonymousSourceNode(node.declarations.map(translate)).join(';');
|
||||
|
||||
case 'Declaration':
|
||||
return createSourceNode(
|
||||
node.info,
|
||||
[translate(node.property), ':', translate(node.value)]
|
||||
);
|
||||
|
||||
case 'Property':
|
||||
return node.name;
|
||||
|
||||
case 'Value':
|
||||
return node.important
|
||||
? each(node.sequence) + '!important'
|
||||
: each(node.sequence);
|
||||
|
||||
case 'Attribute':
|
||||
var result = translate(node.name);
|
||||
var flagsPrefix = ' ';
|
||||
|
||||
if (node.operator !== null) {
|
||||
result += node.operator;
|
||||
|
||||
if (node.value !== null) {
|
||||
result += translate(node.value);
|
||||
|
||||
// space between string and flags is not required
|
||||
if (node.value.type === 'String') {
|
||||
flagsPrefix = '';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (node.flags !== null) {
|
||||
result += flagsPrefix + node.flags;
|
||||
}
|
||||
|
||||
return '[' + result + ']';
|
||||
|
||||
case 'FunctionalPseudo':
|
||||
return ':' + node.name + '(' + eachDelim(node.arguments, ',') + ')';
|
||||
|
||||
case 'Function':
|
||||
return node.name + '(' + eachDelim(node.arguments, ',') + ')';
|
||||
|
||||
case 'Negation':
|
||||
return ':not(' + eachDelim(node.sequence, ',') + ')';
|
||||
|
||||
case 'Braces':
|
||||
return node.open + each(node.sequence) + node.close;
|
||||
|
||||
case 'Argument':
|
||||
case 'AtruleExpression':
|
||||
return each(node.sequence);
|
||||
|
||||
case 'Url':
|
||||
return 'url(' + translate(node.value) + ')';
|
||||
|
||||
case 'Progid':
|
||||
return translate(node.value);
|
||||
|
||||
case 'Combinator':
|
||||
return node.name;
|
||||
|
||||
case 'Identifier':
|
||||
return node.name;
|
||||
|
||||
case 'PseudoClass':
|
||||
return ':' + node.name;
|
||||
|
||||
case 'PseudoElement':
|
||||
return '::' + node.name;
|
||||
|
||||
case 'Class':
|
||||
return '.' + node.name;
|
||||
|
||||
case 'Id':
|
||||
return '#' + node.name;
|
||||
|
||||
case 'Hash':
|
||||
return '#' + node.value;
|
||||
|
||||
case 'Dimension':
|
||||
return node.value + node.unit;
|
||||
|
||||
case 'Nth':
|
||||
return node.value;
|
||||
|
||||
case 'Number':
|
||||
return node.value;
|
||||
|
||||
case 'String':
|
||||
return node.value;
|
||||
|
||||
case 'Operator':
|
||||
return node.value;
|
||||
|
||||
case 'Raw':
|
||||
return node.value;
|
||||
|
||||
case 'Unknown':
|
||||
return node.value;
|
||||
|
||||
case 'Percentage':
|
||||
return node.value + '%';
|
||||
|
||||
case 'Space':
|
||||
return ' ';
|
||||
|
||||
case 'Comment':
|
||||
return '/*' + node.value + '*/';
|
||||
|
||||
default:
|
||||
throw new Error('Unknown node type: ' + node.type);
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = function(node) {
|
||||
return generateSourceMap(
|
||||
createAnonymousSourceNode(translate(node))
|
||||
);
|
||||
};
|
||||
189
node_modules/csso/lib/utils/walk.js
generated
vendored
189
node_modules/csso/lib/utils/walk.js
generated
vendored
@@ -1,189 +0,0 @@
|
||||
function walkRules(node, item, list) {
|
||||
switch (node.type) {
|
||||
case 'StyleSheet':
|
||||
var oldStylesheet = this.stylesheet;
|
||||
this.stylesheet = node;
|
||||
|
||||
node.rules.each(walkRules, this);
|
||||
|
||||
this.stylesheet = oldStylesheet;
|
||||
break;
|
||||
|
||||
case 'Atrule':
|
||||
if (node.block !== null) {
|
||||
walkRules.call(this, node.block);
|
||||
}
|
||||
|
||||
this.fn(node, item, list);
|
||||
break;
|
||||
|
||||
case 'Ruleset':
|
||||
this.fn(node, item, list);
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function walkRulesRight(node, item, list) {
|
||||
switch (node.type) {
|
||||
case 'StyleSheet':
|
||||
var oldStylesheet = this.stylesheet;
|
||||
this.stylesheet = node;
|
||||
|
||||
node.rules.eachRight(walkRulesRight, this);
|
||||
|
||||
this.stylesheet = oldStylesheet;
|
||||
break;
|
||||
|
||||
case 'Atrule':
|
||||
if (node.block !== null) {
|
||||
walkRulesRight.call(this, node.block);
|
||||
}
|
||||
|
||||
this.fn(node, item, list);
|
||||
break;
|
||||
|
||||
case 'Ruleset':
|
||||
this.fn(node, item, list);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
function walkAll(node, item, list) {
|
||||
switch (node.type) {
|
||||
case 'StyleSheet':
|
||||
var oldStylesheet = this.stylesheet;
|
||||
this.stylesheet = node;
|
||||
|
||||
node.rules.each(walkAll, this);
|
||||
|
||||
this.stylesheet = oldStylesheet;
|
||||
break;
|
||||
|
||||
case 'Atrule':
|
||||
if (node.expression !== null) {
|
||||
walkAll.call(this, node.expression);
|
||||
}
|
||||
if (node.block !== null) {
|
||||
walkAll.call(this, node.block);
|
||||
}
|
||||
break;
|
||||
|
||||
case 'Ruleset':
|
||||
this.ruleset = node;
|
||||
|
||||
if (node.selector !== null) {
|
||||
walkAll.call(this, node.selector);
|
||||
}
|
||||
walkAll.call(this, node.block);
|
||||
|
||||
this.ruleset = null;
|
||||
break;
|
||||
|
||||
case 'Selector':
|
||||
var oldSelector = this.selector;
|
||||
this.selector = node;
|
||||
|
||||
node.selectors.each(walkAll, this);
|
||||
|
||||
this.selector = oldSelector;
|
||||
break;
|
||||
|
||||
case 'Block':
|
||||
node.declarations.each(walkAll, this);
|
||||
break;
|
||||
|
||||
case 'Declaration':
|
||||
this.declaration = node;
|
||||
|
||||
walkAll.call(this, node.property);
|
||||
walkAll.call(this, node.value);
|
||||
|
||||
this.declaration = null;
|
||||
break;
|
||||
|
||||
case 'Attribute':
|
||||
walkAll.call(this, node.name);
|
||||
if (node.value !== null) {
|
||||
walkAll.call(this, node.value);
|
||||
}
|
||||
break;
|
||||
|
||||
case 'FunctionalPseudo':
|
||||
case 'Function':
|
||||
this['function'] = node;
|
||||
|
||||
node.arguments.each(walkAll, this);
|
||||
|
||||
this['function'] = null;
|
||||
break;
|
||||
|
||||
case 'AtruleExpression':
|
||||
this.atruleExpression = node;
|
||||
|
||||
node.sequence.each(walkAll, this);
|
||||
|
||||
this.atruleExpression = null;
|
||||
break;
|
||||
|
||||
case 'Value':
|
||||
case 'Argument':
|
||||
case 'SimpleSelector':
|
||||
case 'Braces':
|
||||
case 'Negation':
|
||||
node.sequence.each(walkAll, this);
|
||||
break;
|
||||
|
||||
case 'Url':
|
||||
case 'Progid':
|
||||
walkAll.call(this, node.value);
|
||||
break;
|
||||
|
||||
// nothig to do with
|
||||
// case 'Property':
|
||||
// case 'Combinator':
|
||||
// case 'Dimension':
|
||||
// case 'Hash':
|
||||
// case 'Identifier':
|
||||
// case 'Nth':
|
||||
// case 'Class':
|
||||
// case 'Id':
|
||||
// case 'Percentage':
|
||||
// case 'PseudoClass':
|
||||
// case 'PseudoElement':
|
||||
// case 'Space':
|
||||
// case 'Number':
|
||||
// case 'String':
|
||||
// case 'Operator':
|
||||
// case 'Raw':
|
||||
}
|
||||
|
||||
this.fn(node, item, list);
|
||||
}
|
||||
|
||||
function createContext(root, fn) {
|
||||
var context = {
|
||||
fn: fn,
|
||||
root: root,
|
||||
stylesheet: null,
|
||||
atruleExpression: null,
|
||||
ruleset: null,
|
||||
selector: null,
|
||||
declaration: null,
|
||||
function: null
|
||||
};
|
||||
|
||||
return context;
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
all: function(root, fn) {
|
||||
walkAll.call(createContext(root, fn), root);
|
||||
},
|
||||
rules: function(root, fn) {
|
||||
walkRules.call(createContext(root, fn), root);
|
||||
},
|
||||
rulesRight: function(root, fn) {
|
||||
walkRulesRight.call(createContext(root, fn), root);
|
||||
}
|
||||
};
|
||||
301
node_modules/csso/node_modules/source-map/CHANGELOG.md
generated
vendored
301
node_modules/csso/node_modules/source-map/CHANGELOG.md
generated
vendored
@@ -1,301 +0,0 @@
|
||||
# Change Log
|
||||
|
||||
## 0.5.6
|
||||
|
||||
* Fix for regression when people were using numbers as names in source maps. See
|
||||
#236.
|
||||
|
||||
## 0.5.5
|
||||
|
||||
* Fix "regression" of unsupported, implementation behavior that half the world
|
||||
happens to have come to depend on. See #235.
|
||||
|
||||
* Fix regression involving function hoisting in SpiderMonkey. See #233.
|
||||
|
||||
## 0.5.4
|
||||
|
||||
* Large performance improvements to source-map serialization. See #228 and #229.
|
||||
|
||||
## 0.5.3
|
||||
|
||||
* Do not include unnecessary distribution files. See
|
||||
commit ef7006f8d1647e0a83fdc60f04f5a7ca54886f86.
|
||||
|
||||
## 0.5.2
|
||||
|
||||
* Include browser distributions of the library in package.json's `files`. See
|
||||
issue #212.
|
||||
|
||||
## 0.5.1
|
||||
|
||||
* Fix latent bugs in IndexedSourceMapConsumer.prototype._parseMappings. See
|
||||
ff05274becc9e6e1295ed60f3ea090d31d843379.
|
||||
|
||||
## 0.5.0
|
||||
|
||||
* Node 0.8 is no longer supported.
|
||||
|
||||
* Use webpack instead of dryice for bundling.
|
||||
|
||||
* Big speedups serializing source maps. See pull request #203.
|
||||
|
||||
* Fix a bug with `SourceMapConsumer.prototype.sourceContentFor` and sources that
|
||||
explicitly start with the source root. See issue #199.
|
||||
|
||||
## 0.4.4
|
||||
|
||||
* Fix an issue where using a `SourceMapGenerator` after having created a
|
||||
`SourceMapConsumer` from it via `SourceMapConsumer.fromSourceMap` failed. See
|
||||
issue #191.
|
||||
|
||||
* Fix an issue with where `SourceMapGenerator` would mistakenly consider
|
||||
different mappings as duplicates of each other and avoid generating them. See
|
||||
issue #192.
|
||||
|
||||
## 0.4.3
|
||||
|
||||
* A very large number of performance improvements, particularly when parsing
|
||||
source maps. Collectively about 75% of time shaved off of the source map
|
||||
parsing benchmark!
|
||||
|
||||
* Fix a bug in `SourceMapConsumer.prototype.allGeneratedPositionsFor` and fuzzy
|
||||
searching in the presence of a column option. See issue #177.
|
||||
|
||||
* Fix a bug with joining a source and its source root when the source is above
|
||||
the root. See issue #182.
|
||||
|
||||
* Add the `SourceMapConsumer.prototype.hasContentsOfAllSources` method to
|
||||
determine when all sources' contents are inlined into the source map. See
|
||||
issue #190.
|
||||
|
||||
## 0.4.2
|
||||
|
||||
* Add an `.npmignore` file so that the benchmarks aren't pulled down by
|
||||
dependent projects. Issue #169.
|
||||
|
||||
* Add an optional `column` argument to
|
||||
`SourceMapConsumer.prototype.allGeneratedPositionsFor` and better handle lines
|
||||
with no mappings. Issues #172 and #173.
|
||||
|
||||
## 0.4.1
|
||||
|
||||
* Fix accidentally defining a global variable. #170.
|
||||
|
||||
## 0.4.0
|
||||
|
||||
* The default direction for fuzzy searching was changed back to its original
|
||||
direction. See #164.
|
||||
|
||||
* There is now a `bias` option you can supply to `SourceMapConsumer` to control
|
||||
the fuzzy searching direction. See #167.
|
||||
|
||||
* About an 8% speed up in parsing source maps. See #159.
|
||||
|
||||
* Added a benchmark for parsing and generating source maps.
|
||||
|
||||
## 0.3.0
|
||||
|
||||
* Change the default direction that searching for positions fuzzes when there is
|
||||
not an exact match. See #154.
|
||||
|
||||
* Support for environments using json2.js for JSON serialization. See #156.
|
||||
|
||||
## 0.2.0
|
||||
|
||||
* Support for consuming "indexed" source maps which do not have any remote
|
||||
sections. See pull request #127. This introduces a minor backwards
|
||||
incompatibility if you are monkey patching `SourceMapConsumer.prototype`
|
||||
methods.
|
||||
|
||||
## 0.1.43
|
||||
|
||||
* Performance improvements for `SourceMapGenerator` and `SourceNode`. See issue
|
||||
#148 for some discussion and issues #150, #151, and #152 for implementations.
|
||||
|
||||
## 0.1.42
|
||||
|
||||
* Fix an issue where `SourceNode`s from different versions of the source-map
|
||||
library couldn't be used in conjunction with each other. See issue #142.
|
||||
|
||||
## 0.1.41
|
||||
|
||||
* Fix a bug with getting the source content of relative sources with a "./"
|
||||
prefix. See issue #145 and [Bug 1090768](bugzil.la/1090768).
|
||||
|
||||
* Add the `SourceMapConsumer.prototype.computeColumnSpans` method to compute the
|
||||
column span of each mapping.
|
||||
|
||||
* Add the `SourceMapConsumer.prototype.allGeneratedPositionsFor` method to find
|
||||
all generated positions associated with a given original source and line.
|
||||
|
||||
## 0.1.40
|
||||
|
||||
* Performance improvements for parsing source maps in SourceMapConsumer.
|
||||
|
||||
## 0.1.39
|
||||
|
||||
* Fix a bug where setting a source's contents to null before any source content
|
||||
had been set before threw a TypeError. See issue #131.
|
||||
|
||||
## 0.1.38
|
||||
|
||||
* Fix a bug where finding relative paths from an empty path were creating
|
||||
absolute paths. See issue #129.
|
||||
|
||||
## 0.1.37
|
||||
|
||||
* Fix a bug where if the source root was an empty string, relative source paths
|
||||
would turn into absolute source paths. Issue #124.
|
||||
|
||||
## 0.1.36
|
||||
|
||||
* Allow the `names` mapping property to be an empty string. Issue #121.
|
||||
|
||||
## 0.1.35
|
||||
|
||||
* A third optional parameter was added to `SourceNode.fromStringWithSourceMap`
|
||||
to specify a path that relative sources in the second parameter should be
|
||||
relative to. Issue #105.
|
||||
|
||||
* If no file property is given to a `SourceMapGenerator`, then the resulting
|
||||
source map will no longer have a `null` file property. The property will
|
||||
simply not exist. Issue #104.
|
||||
|
||||
* Fixed a bug where consecutive newlines were ignored in `SourceNode`s.
|
||||
Issue #116.
|
||||
|
||||
## 0.1.34
|
||||
|
||||
* Make `SourceNode` work with windows style ("\r\n") newlines. Issue #103.
|
||||
|
||||
* Fix bug involving source contents and the
|
||||
`SourceMapGenerator.prototype.applySourceMap`. Issue #100.
|
||||
|
||||
## 0.1.33
|
||||
|
||||
* Fix some edge cases surrounding path joining and URL resolution.
|
||||
|
||||
* Add a third parameter for relative path to
|
||||
`SourceMapGenerator.prototype.applySourceMap`.
|
||||
|
||||
* Fix issues with mappings and EOLs.
|
||||
|
||||
## 0.1.32
|
||||
|
||||
* Fixed a bug where SourceMapConsumer couldn't handle negative relative columns
|
||||
(issue 92).
|
||||
|
||||
* Fixed test runner to actually report number of failed tests as its process
|
||||
exit code.
|
||||
|
||||
* Fixed a typo when reporting bad mappings (issue 87).
|
||||
|
||||
## 0.1.31
|
||||
|
||||
* Delay parsing the mappings in SourceMapConsumer until queried for a source
|
||||
location.
|
||||
|
||||
* Support Sass source maps (which at the time of writing deviate from the spec
|
||||
in small ways) in SourceMapConsumer.
|
||||
|
||||
## 0.1.30
|
||||
|
||||
* Do not join source root with a source, when the source is a data URI.
|
||||
|
||||
* Extend the test runner to allow running single specific test files at a time.
|
||||
|
||||
* Performance improvements in `SourceNode.prototype.walk` and
|
||||
`SourceMapConsumer.prototype.eachMapping`.
|
||||
|
||||
* Source map browser builds will now work inside Workers.
|
||||
|
||||
* Better error messages when attempting to add an invalid mapping to a
|
||||
`SourceMapGenerator`.
|
||||
|
||||
## 0.1.29
|
||||
|
||||
* Allow duplicate entries in the `names` and `sources` arrays of source maps
|
||||
(usually from TypeScript) we are parsing. Fixes github issue 72.
|
||||
|
||||
## 0.1.28
|
||||
|
||||
* Skip duplicate mappings when creating source maps from SourceNode; github
|
||||
issue 75.
|
||||
|
||||
## 0.1.27
|
||||
|
||||
* Don't throw an error when the `file` property is missing in SourceMapConsumer,
|
||||
we don't use it anyway.
|
||||
|
||||
## 0.1.26
|
||||
|
||||
* Fix SourceNode.fromStringWithSourceMap for empty maps. Fixes github issue 70.
|
||||
|
||||
## 0.1.25
|
||||
|
||||
* Make compatible with browserify
|
||||
|
||||
## 0.1.24
|
||||
|
||||
* Fix issue with absolute paths and `file://` URIs. See
|
||||
https://bugzilla.mozilla.org/show_bug.cgi?id=885597
|
||||
|
||||
## 0.1.23
|
||||
|
||||
* Fix issue with absolute paths and sourcesContent, github issue 64.
|
||||
|
||||
## 0.1.22
|
||||
|
||||
* Ignore duplicate mappings in SourceMapGenerator. Fixes github issue 21.
|
||||
|
||||
## 0.1.21
|
||||
|
||||
* Fixed handling of sources that start with a slash so that they are relative to
|
||||
the source root's host.
|
||||
|
||||
## 0.1.20
|
||||
|
||||
* Fixed github issue #43: absolute URLs aren't joined with the source root
|
||||
anymore.
|
||||
|
||||
## 0.1.19
|
||||
|
||||
* Using Travis CI to run tests.
|
||||
|
||||
## 0.1.18
|
||||
|
||||
* Fixed a bug in the handling of sourceRoot.
|
||||
|
||||
## 0.1.17
|
||||
|
||||
* Added SourceNode.fromStringWithSourceMap.
|
||||
|
||||
## 0.1.16
|
||||
|
||||
* Added missing documentation.
|
||||
|
||||
* Fixed the generating of empty mappings in SourceNode.
|
||||
|
||||
## 0.1.15
|
||||
|
||||
* Added SourceMapGenerator.applySourceMap.
|
||||
|
||||
## 0.1.14
|
||||
|
||||
* The sourceRoot is now handled consistently.
|
||||
|
||||
## 0.1.13
|
||||
|
||||
* Added SourceMapGenerator.fromSourceMap.
|
||||
|
||||
## 0.1.12
|
||||
|
||||
* SourceNode now generates empty mappings too.
|
||||
|
||||
## 0.1.11
|
||||
|
||||
* Added name support to SourceNode.
|
||||
|
||||
## 0.1.10
|
||||
|
||||
* Added sourcesContent support to the customer and generator.
|
||||
28
node_modules/csso/node_modules/source-map/LICENSE
generated
vendored
28
node_modules/csso/node_modules/source-map/LICENSE
generated
vendored
@@ -1,28 +0,0 @@
|
||||
|
||||
Copyright (c) 2009-2011, Mozilla Foundation and contributors
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright notice, this
|
||||
list of conditions and the following disclaimer.
|
||||
|
||||
* Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
|
||||
* Neither the names of the Mozilla Foundation nor the names of project
|
||||
contributors may be used to endorse or promote products derived from this
|
||||
software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
729
node_modules/csso/node_modules/source-map/README.md
generated
vendored
729
node_modules/csso/node_modules/source-map/README.md
generated
vendored
@@ -1,729 +0,0 @@
|
||||
# Source Map
|
||||
|
||||
[](https://travis-ci.org/mozilla/source-map)
|
||||
|
||||
[](https://www.npmjs.com/package/source-map)
|
||||
|
||||
This is a library to generate and consume the source map format
|
||||
[described here][format].
|
||||
|
||||
[format]: https://docs.google.com/document/d/1U1RGAehQwRypUTovF1KRlpiOFze0b-_2gc6fAH0KY0k/edit
|
||||
|
||||
## Use with Node
|
||||
|
||||
$ npm install source-map
|
||||
|
||||
## Use on the Web
|
||||
|
||||
<script src="https://raw.githubusercontent.com/mozilla/source-map/master/dist/source-map.min.js" defer></script>
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
<!-- `npm run toc` to regenerate the Table of Contents -->
|
||||
|
||||
<!-- START doctoc generated TOC please keep comment here to allow auto update -->
|
||||
<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
|
||||
## Table of Contents
|
||||
|
||||
- [Examples](#examples)
|
||||
- [Consuming a source map](#consuming-a-source-map)
|
||||
- [Generating a source map](#generating-a-source-map)
|
||||
- [With SourceNode (high level API)](#with-sourcenode-high-level-api)
|
||||
- [With SourceMapGenerator (low level API)](#with-sourcemapgenerator-low-level-api)
|
||||
- [API](#api)
|
||||
- [SourceMapConsumer](#sourcemapconsumer)
|
||||
- [new SourceMapConsumer(rawSourceMap)](#new-sourcemapconsumerrawsourcemap)
|
||||
- [SourceMapConsumer.prototype.computeColumnSpans()](#sourcemapconsumerprototypecomputecolumnspans)
|
||||
- [SourceMapConsumer.prototype.originalPositionFor(generatedPosition)](#sourcemapconsumerprototypeoriginalpositionforgeneratedposition)
|
||||
- [SourceMapConsumer.prototype.generatedPositionFor(originalPosition)](#sourcemapconsumerprototypegeneratedpositionfororiginalposition)
|
||||
- [SourceMapConsumer.prototype.allGeneratedPositionsFor(originalPosition)](#sourcemapconsumerprototypeallgeneratedpositionsfororiginalposition)
|
||||
- [SourceMapConsumer.prototype.hasContentsOfAllSources()](#sourcemapconsumerprototypehascontentsofallsources)
|
||||
- [SourceMapConsumer.prototype.sourceContentFor(source[, returnNullOnMissing])](#sourcemapconsumerprototypesourcecontentforsource-returnnullonmissing)
|
||||
- [SourceMapConsumer.prototype.eachMapping(callback, context, order)](#sourcemapconsumerprototypeeachmappingcallback-context-order)
|
||||
- [SourceMapGenerator](#sourcemapgenerator)
|
||||
- [new SourceMapGenerator([startOfSourceMap])](#new-sourcemapgeneratorstartofsourcemap)
|
||||
- [SourceMapGenerator.fromSourceMap(sourceMapConsumer)](#sourcemapgeneratorfromsourcemapsourcemapconsumer)
|
||||
- [SourceMapGenerator.prototype.addMapping(mapping)](#sourcemapgeneratorprototypeaddmappingmapping)
|
||||
- [SourceMapGenerator.prototype.setSourceContent(sourceFile, sourceContent)](#sourcemapgeneratorprototypesetsourcecontentsourcefile-sourcecontent)
|
||||
- [SourceMapGenerator.prototype.applySourceMap(sourceMapConsumer[, sourceFile[, sourceMapPath]])](#sourcemapgeneratorprototypeapplysourcemapsourcemapconsumer-sourcefile-sourcemappath)
|
||||
- [SourceMapGenerator.prototype.toString()](#sourcemapgeneratorprototypetostring)
|
||||
- [SourceNode](#sourcenode)
|
||||
- [new SourceNode([line, column, source[, chunk[, name]]])](#new-sourcenodeline-column-source-chunk-name)
|
||||
- [SourceNode.fromStringWithSourceMap(code, sourceMapConsumer[, relativePath])](#sourcenodefromstringwithsourcemapcode-sourcemapconsumer-relativepath)
|
||||
- [SourceNode.prototype.add(chunk)](#sourcenodeprototypeaddchunk)
|
||||
- [SourceNode.prototype.prepend(chunk)](#sourcenodeprototypeprependchunk)
|
||||
- [SourceNode.prototype.setSourceContent(sourceFile, sourceContent)](#sourcenodeprototypesetsourcecontentsourcefile-sourcecontent)
|
||||
- [SourceNode.prototype.walk(fn)](#sourcenodeprototypewalkfn)
|
||||
- [SourceNode.prototype.walkSourceContents(fn)](#sourcenodeprototypewalksourcecontentsfn)
|
||||
- [SourceNode.prototype.join(sep)](#sourcenodeprototypejoinsep)
|
||||
- [SourceNode.prototype.replaceRight(pattern, replacement)](#sourcenodeprototypereplacerightpattern-replacement)
|
||||
- [SourceNode.prototype.toString()](#sourcenodeprototypetostring)
|
||||
- [SourceNode.prototype.toStringWithSourceMap([startOfSourceMap])](#sourcenodeprototypetostringwithsourcemapstartofsourcemap)
|
||||
|
||||
<!-- END doctoc generated TOC please keep comment here to allow auto update -->
|
||||
|
||||
## Examples
|
||||
|
||||
### Consuming a source map
|
||||
|
||||
```js
|
||||
var rawSourceMap = {
|
||||
version: 3,
|
||||
file: 'min.js',
|
||||
names: ['bar', 'baz', 'n'],
|
||||
sources: ['one.js', 'two.js'],
|
||||
sourceRoot: 'http://example.com/www/js/',
|
||||
mappings: 'CAAC,IAAI,IAAM,SAAUA,GAClB,OAAOC,IAAID;CCDb,IAAI,IAAM,SAAUE,GAClB,OAAOA'
|
||||
};
|
||||
|
||||
var smc = new SourceMapConsumer(rawSourceMap);
|
||||
|
||||
console.log(smc.sources);
|
||||
// [ 'http://example.com/www/js/one.js',
|
||||
// 'http://example.com/www/js/two.js' ]
|
||||
|
||||
console.log(smc.originalPositionFor({
|
||||
line: 2,
|
||||
column: 28
|
||||
}));
|
||||
// { source: 'http://example.com/www/js/two.js',
|
||||
// line: 2,
|
||||
// column: 10,
|
||||
// name: 'n' }
|
||||
|
||||
console.log(smc.generatedPositionFor({
|
||||
source: 'http://example.com/www/js/two.js',
|
||||
line: 2,
|
||||
column: 10
|
||||
}));
|
||||
// { line: 2, column: 28 }
|
||||
|
||||
smc.eachMapping(function (m) {
|
||||
// ...
|
||||
});
|
||||
```
|
||||
|
||||
### Generating a source map
|
||||
|
||||
In depth guide:
|
||||
[**Compiling to JavaScript, and Debugging with Source Maps**](https://hacks.mozilla.org/2013/05/compiling-to-javascript-and-debugging-with-source-maps/)
|
||||
|
||||
#### With SourceNode (high level API)
|
||||
|
||||
```js
|
||||
function compile(ast) {
|
||||
switch (ast.type) {
|
||||
case 'BinaryExpression':
|
||||
return new SourceNode(
|
||||
ast.location.line,
|
||||
ast.location.column,
|
||||
ast.location.source,
|
||||
[compile(ast.left), " + ", compile(ast.right)]
|
||||
);
|
||||
case 'Literal':
|
||||
return new SourceNode(
|
||||
ast.location.line,
|
||||
ast.location.column,
|
||||
ast.location.source,
|
||||
String(ast.value)
|
||||
);
|
||||
// ...
|
||||
default:
|
||||
throw new Error("Bad AST");
|
||||
}
|
||||
}
|
||||
|
||||
var ast = parse("40 + 2", "add.js");
|
||||
console.log(compile(ast).toStringWithSourceMap({
|
||||
file: 'add.js'
|
||||
}));
|
||||
// { code: '40 + 2',
|
||||
// map: [object SourceMapGenerator] }
|
||||
```
|
||||
|
||||
#### With SourceMapGenerator (low level API)
|
||||
|
||||
```js
|
||||
var map = new SourceMapGenerator({
|
||||
file: "source-mapped.js"
|
||||
});
|
||||
|
||||
map.addMapping({
|
||||
generated: {
|
||||
line: 10,
|
||||
column: 35
|
||||
},
|
||||
source: "foo.js",
|
||||
original: {
|
||||
line: 33,
|
||||
column: 2
|
||||
},
|
||||
name: "christopher"
|
||||
});
|
||||
|
||||
console.log(map.toString());
|
||||
// '{"version":3,"file":"source-mapped.js","sources":["foo.js"],"names":["christopher"],"mappings":";;;;;;;;;mCAgCEA"}'
|
||||
```
|
||||
|
||||
## API
|
||||
|
||||
Get a reference to the module:
|
||||
|
||||
```js
|
||||
// Node.js
|
||||
var sourceMap = require('source-map');
|
||||
|
||||
// Browser builds
|
||||
var sourceMap = window.sourceMap;
|
||||
|
||||
// Inside Firefox
|
||||
const sourceMap = require("devtools/toolkit/sourcemap/source-map.js");
|
||||
```
|
||||
|
||||
### SourceMapConsumer
|
||||
|
||||
A SourceMapConsumer instance represents a parsed source map which we can query
|
||||
for information about the original file positions by giving it a file position
|
||||
in the generated source.
|
||||
|
||||
#### new SourceMapConsumer(rawSourceMap)
|
||||
|
||||
The only parameter is the raw source map (either as a string which can be
|
||||
`JSON.parse`'d, or an object). According to the spec, source maps have the
|
||||
following attributes:
|
||||
|
||||
* `version`: Which version of the source map spec this map is following.
|
||||
|
||||
* `sources`: An array of URLs to the original source files.
|
||||
|
||||
* `names`: An array of identifiers which can be referenced by individual
|
||||
mappings.
|
||||
|
||||
* `sourceRoot`: Optional. The URL root from which all sources are relative.
|
||||
|
||||
* `sourcesContent`: Optional. An array of contents of the original source files.
|
||||
|
||||
* `mappings`: A string of base64 VLQs which contain the actual mappings.
|
||||
|
||||
* `file`: Optional. The generated filename this source map is associated with.
|
||||
|
||||
```js
|
||||
var consumer = new sourceMap.SourceMapConsumer(rawSourceMapJsonData);
|
||||
```
|
||||
|
||||
#### SourceMapConsumer.prototype.computeColumnSpans()
|
||||
|
||||
Compute the last column for each generated mapping. The last column is
|
||||
inclusive.
|
||||
|
||||
```js
|
||||
// Before:
|
||||
consumer.allGeneratedPositionsFor({ line: 2, source: "foo.coffee" })
|
||||
// [ { line: 2,
|
||||
// column: 1 },
|
||||
// { line: 2,
|
||||
// column: 10 },
|
||||
// { line: 2,
|
||||
// column: 20 } ]
|
||||
|
||||
consumer.computeColumnSpans();
|
||||
|
||||
// After:
|
||||
consumer.allGeneratedPositionsFor({ line: 2, source: "foo.coffee" })
|
||||
// [ { line: 2,
|
||||
// column: 1,
|
||||
// lastColumn: 9 },
|
||||
// { line: 2,
|
||||
// column: 10,
|
||||
// lastColumn: 19 },
|
||||
// { line: 2,
|
||||
// column: 20,
|
||||
// lastColumn: Infinity } ]
|
||||
|
||||
```
|
||||
|
||||
#### SourceMapConsumer.prototype.originalPositionFor(generatedPosition)
|
||||
|
||||
Returns the original source, line, and column information for the generated
|
||||
source's line and column positions provided. The only argument is an object with
|
||||
the following properties:
|
||||
|
||||
* `line`: The line number in the generated source.
|
||||
|
||||
* `column`: The column number in the generated source.
|
||||
|
||||
* `bias`: Either `SourceMapConsumer.GREATEST_LOWER_BOUND` or
|
||||
`SourceMapConsumer.LEAST_UPPER_BOUND`. Specifies whether to return the closest
|
||||
element that is smaller than or greater than the one we are searching for,
|
||||
respectively, if the exact element cannot be found. Defaults to
|
||||
`SourceMapConsumer.GREATEST_LOWER_BOUND`.
|
||||
|
||||
and an object is returned with the following properties:
|
||||
|
||||
* `source`: The original source file, or null if this information is not
|
||||
available.
|
||||
|
||||
* `line`: The line number in the original source, or null if this information is
|
||||
not available.
|
||||
|
||||
* `column`: The column number in the original source, or null if this
|
||||
information is not available.
|
||||
|
||||
* `name`: The original identifier, or null if this information is not available.
|
||||
|
||||
```js
|
||||
consumer.originalPositionFor({ line: 2, column: 10 })
|
||||
// { source: 'foo.coffee',
|
||||
// line: 2,
|
||||
// column: 2,
|
||||
// name: null }
|
||||
|
||||
consumer.originalPositionFor({ line: 99999999999999999, column: 999999999999999 })
|
||||
// { source: null,
|
||||
// line: null,
|
||||
// column: null,
|
||||
// name: null }
|
||||
```
|
||||
|
||||
#### SourceMapConsumer.prototype.generatedPositionFor(originalPosition)
|
||||
|
||||
Returns the generated line and column information for the original source,
|
||||
line, and column positions provided. The only argument is an object with
|
||||
the following properties:
|
||||
|
||||
* `source`: The filename of the original source.
|
||||
|
||||
* `line`: The line number in the original source.
|
||||
|
||||
* `column`: The column number in the original source.
|
||||
|
||||
and an object is returned with the following properties:
|
||||
|
||||
* `line`: The line number in the generated source, or null.
|
||||
|
||||
* `column`: The column number in the generated source, or null.
|
||||
|
||||
```js
|
||||
consumer.generatedPositionFor({ source: "example.js", line: 2, column: 10 })
|
||||
// { line: 1,
|
||||
// column: 56 }
|
||||
```
|
||||
|
||||
#### SourceMapConsumer.prototype.allGeneratedPositionsFor(originalPosition)
|
||||
|
||||
Returns all generated line and column information for the original source, line,
|
||||
and column provided. If no column is provided, returns all mappings
|
||||
corresponding to a either the line we are searching for or the next closest line
|
||||
that has any mappings. Otherwise, returns all mappings corresponding to the
|
||||
given line and either the column we are searching for or the next closest column
|
||||
that has any offsets.
|
||||
|
||||
The only argument is an object with the following properties:
|
||||
|
||||
* `source`: The filename of the original source.
|
||||
|
||||
* `line`: The line number in the original source.
|
||||
|
||||
* `column`: Optional. The column number in the original source.
|
||||
|
||||
and an array of objects is returned, each with the following properties:
|
||||
|
||||
* `line`: The line number in the generated source, or null.
|
||||
|
||||
* `column`: The column number in the generated source, or null.
|
||||
|
||||
```js
|
||||
consumer.allGeneratedpositionsfor({ line: 2, source: "foo.coffee" })
|
||||
// [ { line: 2,
|
||||
// column: 1 },
|
||||
// { line: 2,
|
||||
// column: 10 },
|
||||
// { line: 2,
|
||||
// column: 20 } ]
|
||||
```
|
||||
|
||||
#### SourceMapConsumer.prototype.hasContentsOfAllSources()
|
||||
|
||||
Return true if we have the embedded source content for every source listed in
|
||||
the source map, false otherwise.
|
||||
|
||||
In other words, if this method returns `true`, then
|
||||
`consumer.sourceContentFor(s)` will succeed for every source `s` in
|
||||
`consumer.sources`.
|
||||
|
||||
```js
|
||||
// ...
|
||||
if (consumer.hasContentsOfAllSources()) {
|
||||
consumerReadyCallback(consumer);
|
||||
} else {
|
||||
fetchSources(consumer, consumerReadyCallback);
|
||||
}
|
||||
// ...
|
||||
```
|
||||
|
||||
#### SourceMapConsumer.prototype.sourceContentFor(source[, returnNullOnMissing])
|
||||
|
||||
Returns the original source content for the source provided. The only
|
||||
argument is the URL of the original source file.
|
||||
|
||||
If the source content for the given source is not found, then an error is
|
||||
thrown. Optionally, pass `true` as the second param to have `null` returned
|
||||
instead.
|
||||
|
||||
```js
|
||||
consumer.sources
|
||||
// [ "my-cool-lib.clj" ]
|
||||
|
||||
consumer.sourceContentFor("my-cool-lib.clj")
|
||||
// "..."
|
||||
|
||||
consumer.sourceContentFor("this is not in the source map");
|
||||
// Error: "this is not in the source map" is not in the source map
|
||||
|
||||
consumer.sourceContentFor("this is not in the source map", true);
|
||||
// null
|
||||
```
|
||||
|
||||
#### SourceMapConsumer.prototype.eachMapping(callback, context, order)
|
||||
|
||||
Iterate over each mapping between an original source/line/column and a
|
||||
generated line/column in this source map.
|
||||
|
||||
* `callback`: The function that is called with each mapping. Mappings have the
|
||||
form `{ source, generatedLine, generatedColumn, originalLine, originalColumn,
|
||||
name }`
|
||||
|
||||
* `context`: Optional. If specified, this object will be the value of `this`
|
||||
every time that `callback` is called.
|
||||
|
||||
* `order`: Either `SourceMapConsumer.GENERATED_ORDER` or
|
||||
`SourceMapConsumer.ORIGINAL_ORDER`. Specifies whether you want to iterate over
|
||||
the mappings sorted by the generated file's line/column order or the
|
||||
original's source/line/column order, respectively. Defaults to
|
||||
`SourceMapConsumer.GENERATED_ORDER`.
|
||||
|
||||
```js
|
||||
consumer.eachMapping(function (m) { console.log(m); })
|
||||
// ...
|
||||
// { source: 'illmatic.js',
|
||||
// generatedLine: 1,
|
||||
// generatedColumn: 0,
|
||||
// originalLine: 1,
|
||||
// originalColumn: 0,
|
||||
// name: null }
|
||||
// { source: 'illmatic.js',
|
||||
// generatedLine: 2,
|
||||
// generatedColumn: 0,
|
||||
// originalLine: 2,
|
||||
// originalColumn: 0,
|
||||
// name: null }
|
||||
// ...
|
||||
```
|
||||
### SourceMapGenerator
|
||||
|
||||
An instance of the SourceMapGenerator represents a source map which is being
|
||||
built incrementally.
|
||||
|
||||
#### new SourceMapGenerator([startOfSourceMap])
|
||||
|
||||
You may pass an object with the following properties:
|
||||
|
||||
* `file`: The filename of the generated source that this source map is
|
||||
associated with.
|
||||
|
||||
* `sourceRoot`: A root for all relative URLs in this source map.
|
||||
|
||||
* `skipValidation`: Optional. When `true`, disables validation of mappings as
|
||||
they are added. This can improve performance but should be used with
|
||||
discretion, as a last resort. Even then, one should avoid using this flag when
|
||||
running tests, if possible.
|
||||
|
||||
```js
|
||||
var generator = new sourceMap.SourceMapGenerator({
|
||||
file: "my-generated-javascript-file.js",
|
||||
sourceRoot: "http://example.com/app/js/"
|
||||
});
|
||||
```
|
||||
|
||||
#### SourceMapGenerator.fromSourceMap(sourceMapConsumer)
|
||||
|
||||
Creates a new `SourceMapGenerator` from an existing `SourceMapConsumer` instance.
|
||||
|
||||
* `sourceMapConsumer` The SourceMap.
|
||||
|
||||
```js
|
||||
var generator = sourceMap.SourceMapGenerator.fromSourceMap(consumer);
|
||||
```
|
||||
|
||||
#### SourceMapGenerator.prototype.addMapping(mapping)
|
||||
|
||||
Add a single mapping from original source line and column to the generated
|
||||
source's line and column for this source map being created. The mapping object
|
||||
should have the following properties:
|
||||
|
||||
* `generated`: An object with the generated line and column positions.
|
||||
|
||||
* `original`: An object with the original line and column positions.
|
||||
|
||||
* `source`: The original source file (relative to the sourceRoot).
|
||||
|
||||
* `name`: An optional original token name for this mapping.
|
||||
|
||||
```js
|
||||
generator.addMapping({
|
||||
source: "module-one.scm",
|
||||
original: { line: 128, column: 0 },
|
||||
generated: { line: 3, column: 456 }
|
||||
})
|
||||
```
|
||||
|
||||
#### SourceMapGenerator.prototype.setSourceContent(sourceFile, sourceContent)
|
||||
|
||||
Set the source content for an original source file.
|
||||
|
||||
* `sourceFile` the URL of the original source file.
|
||||
|
||||
* `sourceContent` the content of the source file.
|
||||
|
||||
```js
|
||||
generator.setSourceContent("module-one.scm",
|
||||
fs.readFileSync("path/to/module-one.scm"))
|
||||
```
|
||||
|
||||
#### SourceMapGenerator.prototype.applySourceMap(sourceMapConsumer[, sourceFile[, sourceMapPath]])
|
||||
|
||||
Applies a SourceMap for a source file to the SourceMap.
|
||||
Each mapping to the supplied source file is rewritten using the
|
||||
supplied SourceMap. Note: The resolution for the resulting mappings
|
||||
is the minimum of this map and the supplied map.
|
||||
|
||||
* `sourceMapConsumer`: The SourceMap to be applied.
|
||||
|
||||
* `sourceFile`: Optional. The filename of the source file.
|
||||
If omitted, sourceMapConsumer.file will be used, if it exists.
|
||||
Otherwise an error will be thrown.
|
||||
|
||||
* `sourceMapPath`: Optional. The dirname of the path to the SourceMap
|
||||
to be applied. If relative, it is relative to the SourceMap.
|
||||
|
||||
This parameter is needed when the two SourceMaps aren't in the same
|
||||
directory, and the SourceMap to be applied contains relative source
|
||||
paths. If so, those relative source paths need to be rewritten
|
||||
relative to the SourceMap.
|
||||
|
||||
If omitted, it is assumed that both SourceMaps are in the same directory,
|
||||
thus not needing any rewriting. (Supplying `'.'` has the same effect.)
|
||||
|
||||
#### SourceMapGenerator.prototype.toString()
|
||||
|
||||
Renders the source map being generated to a string.
|
||||
|
||||
```js
|
||||
generator.toString()
|
||||
// '{"version":3,"sources":["module-one.scm"],"names":[],"mappings":"...snip...","file":"my-generated-javascript-file.js","sourceRoot":"http://example.com/app/js/"}'
|
||||
```
|
||||
|
||||
### SourceNode
|
||||
|
||||
SourceNodes provide a way to abstract over interpolating and/or concatenating
|
||||
snippets of generated JavaScript source code, while maintaining the line and
|
||||
column information associated between those snippets and the original source
|
||||
code. This is useful as the final intermediate representation a compiler might
|
||||
use before outputting the generated JS and source map.
|
||||
|
||||
#### new SourceNode([line, column, source[, chunk[, name]]])
|
||||
|
||||
* `line`: The original line number associated with this source node, or null if
|
||||
it isn't associated with an original line.
|
||||
|
||||
* `column`: The original column number associated with this source node, or null
|
||||
if it isn't associated with an original column.
|
||||
|
||||
* `source`: The original source's filename; null if no filename is provided.
|
||||
|
||||
* `chunk`: Optional. Is immediately passed to `SourceNode.prototype.add`, see
|
||||
below.
|
||||
|
||||
* `name`: Optional. The original identifier.
|
||||
|
||||
```js
|
||||
var node = new SourceNode(1, 2, "a.cpp", [
|
||||
new SourceNode(3, 4, "b.cpp", "extern int status;\n"),
|
||||
new SourceNode(5, 6, "c.cpp", "std::string* make_string(size_t n);\n"),
|
||||
new SourceNode(7, 8, "d.cpp", "int main(int argc, char** argv) {}\n"),
|
||||
]);
|
||||
```
|
||||
|
||||
#### SourceNode.fromStringWithSourceMap(code, sourceMapConsumer[, relativePath])
|
||||
|
||||
Creates a SourceNode from generated code and a SourceMapConsumer.
|
||||
|
||||
* `code`: The generated code
|
||||
|
||||
* `sourceMapConsumer` The SourceMap for the generated code
|
||||
|
||||
* `relativePath` The optional path that relative sources in `sourceMapConsumer`
|
||||
should be relative to.
|
||||
|
||||
```js
|
||||
var consumer = new SourceMapConsumer(fs.readFileSync("path/to/my-file.js.map", "utf8"));
|
||||
var node = SourceNode.fromStringWithSourceMap(fs.readFileSync("path/to/my-file.js"),
|
||||
consumer);
|
||||
```
|
||||
|
||||
#### SourceNode.prototype.add(chunk)
|
||||
|
||||
Add a chunk of generated JS to this source node.
|
||||
|
||||
* `chunk`: A string snippet of generated JS code, another instance of
|
||||
`SourceNode`, or an array where each member is one of those things.
|
||||
|
||||
```js
|
||||
node.add(" + ");
|
||||
node.add(otherNode);
|
||||
node.add([leftHandOperandNode, " + ", rightHandOperandNode]);
|
||||
```
|
||||
|
||||
#### SourceNode.prototype.prepend(chunk)
|
||||
|
||||
Prepend a chunk of generated JS to this source node.
|
||||
|
||||
* `chunk`: A string snippet of generated JS code, another instance of
|
||||
`SourceNode`, or an array where each member is one of those things.
|
||||
|
||||
```js
|
||||
node.prepend("/** Build Id: f783haef86324gf **/\n\n");
|
||||
```
|
||||
|
||||
#### SourceNode.prototype.setSourceContent(sourceFile, sourceContent)
|
||||
|
||||
Set the source content for a source file. This will be added to the
|
||||
`SourceMap` in the `sourcesContent` field.
|
||||
|
||||
* `sourceFile`: The filename of the source file
|
||||
|
||||
* `sourceContent`: The content of the source file
|
||||
|
||||
```js
|
||||
node.setSourceContent("module-one.scm",
|
||||
fs.readFileSync("path/to/module-one.scm"))
|
||||
```
|
||||
|
||||
#### SourceNode.prototype.walk(fn)
|
||||
|
||||
Walk over the tree of JS snippets in this node and its children. The walking
|
||||
function is called once for each snippet of JS and is passed that snippet and
|
||||
the its original associated source's line/column location.
|
||||
|
||||
* `fn`: The traversal function.
|
||||
|
||||
```js
|
||||
var node = new SourceNode(1, 2, "a.js", [
|
||||
new SourceNode(3, 4, "b.js", "uno"),
|
||||
"dos",
|
||||
[
|
||||
"tres",
|
||||
new SourceNode(5, 6, "c.js", "quatro")
|
||||
]
|
||||
]);
|
||||
|
||||
node.walk(function (code, loc) { console.log("WALK:", code, loc); })
|
||||
// WALK: uno { source: 'b.js', line: 3, column: 4, name: null }
|
||||
// WALK: dos { source: 'a.js', line: 1, column: 2, name: null }
|
||||
// WALK: tres { source: 'a.js', line: 1, column: 2, name: null }
|
||||
// WALK: quatro { source: 'c.js', line: 5, column: 6, name: null }
|
||||
```
|
||||
|
||||
#### SourceNode.prototype.walkSourceContents(fn)
|
||||
|
||||
Walk over the tree of SourceNodes. The walking function is called for each
|
||||
source file content and is passed the filename and source content.
|
||||
|
||||
* `fn`: The traversal function.
|
||||
|
||||
```js
|
||||
var a = new SourceNode(1, 2, "a.js", "generated from a");
|
||||
a.setSourceContent("a.js", "original a");
|
||||
var b = new SourceNode(1, 2, "b.js", "generated from b");
|
||||
b.setSourceContent("b.js", "original b");
|
||||
var c = new SourceNode(1, 2, "c.js", "generated from c");
|
||||
c.setSourceContent("c.js", "original c");
|
||||
|
||||
var node = new SourceNode(null, null, null, [a, b, c]);
|
||||
node.walkSourceContents(function (source, contents) { console.log("WALK:", source, ":", contents); })
|
||||
// WALK: a.js : original a
|
||||
// WALK: b.js : original b
|
||||
// WALK: c.js : original c
|
||||
```
|
||||
|
||||
#### SourceNode.prototype.join(sep)
|
||||
|
||||
Like `Array.prototype.join` except for SourceNodes. Inserts the separator
|
||||
between each of this source node's children.
|
||||
|
||||
* `sep`: The separator.
|
||||
|
||||
```js
|
||||
var lhs = new SourceNode(1, 2, "a.rs", "my_copy");
|
||||
var operand = new SourceNode(3, 4, "a.rs", "=");
|
||||
var rhs = new SourceNode(5, 6, "a.rs", "orig.clone()");
|
||||
|
||||
var node = new SourceNode(null, null, null, [ lhs, operand, rhs ]);
|
||||
var joinedNode = node.join(" ");
|
||||
```
|
||||
|
||||
#### SourceNode.prototype.replaceRight(pattern, replacement)
|
||||
|
||||
Call `String.prototype.replace` on the very right-most source snippet. Useful
|
||||
for trimming white space from the end of a source node, etc.
|
||||
|
||||
* `pattern`: The pattern to replace.
|
||||
|
||||
* `replacement`: The thing to replace the pattern with.
|
||||
|
||||
```js
|
||||
// Trim trailing white space.
|
||||
node.replaceRight(/\s*$/, "");
|
||||
```
|
||||
|
||||
#### SourceNode.prototype.toString()
|
||||
|
||||
Return the string representation of this source node. Walks over the tree and
|
||||
concatenates all the various snippets together to one string.
|
||||
|
||||
```js
|
||||
var node = new SourceNode(1, 2, "a.js", [
|
||||
new SourceNode(3, 4, "b.js", "uno"),
|
||||
"dos",
|
||||
[
|
||||
"tres",
|
||||
new SourceNode(5, 6, "c.js", "quatro")
|
||||
]
|
||||
]);
|
||||
|
||||
node.toString()
|
||||
// 'unodostresquatro'
|
||||
```
|
||||
|
||||
#### SourceNode.prototype.toStringWithSourceMap([startOfSourceMap])
|
||||
|
||||
Returns the string representation of this tree of source nodes, plus a
|
||||
SourceMapGenerator which contains all the mappings between the generated and
|
||||
original sources.
|
||||
|
||||
The arguments are the same as those to `new SourceMapGenerator`.
|
||||
|
||||
```js
|
||||
var node = new SourceNode(1, 2, "a.js", [
|
||||
new SourceNode(3, 4, "b.js", "uno"),
|
||||
"dos",
|
||||
[
|
||||
"tres",
|
||||
new SourceNode(5, 6, "c.js", "quatro")
|
||||
]
|
||||
]);
|
||||
|
||||
node.toStringWithSourceMap({ file: "my-output-file.js" })
|
||||
// { code: 'unodostresquatro',
|
||||
// map: [object SourceMapGenerator] }
|
||||
```
|
||||
3091
node_modules/csso/node_modules/source-map/dist/source-map.debug.js
generated
vendored
3091
node_modules/csso/node_modules/source-map/dist/source-map.debug.js
generated
vendored
File diff suppressed because one or more lines are too long
3090
node_modules/csso/node_modules/source-map/dist/source-map.js
generated
vendored
3090
node_modules/csso/node_modules/source-map/dist/source-map.js
generated
vendored
File diff suppressed because it is too large
Load Diff
2
node_modules/csso/node_modules/source-map/dist/source-map.min.js
generated
vendored
2
node_modules/csso/node_modules/source-map/dist/source-map.min.js
generated
vendored
File diff suppressed because one or more lines are too long
1
node_modules/csso/node_modules/source-map/dist/source-map.min.js.map
generated
vendored
1
node_modules/csso/node_modules/source-map/dist/source-map.min.js.map
generated
vendored
File diff suppressed because one or more lines are too long
121
node_modules/csso/node_modules/source-map/lib/array-set.js
generated
vendored
121
node_modules/csso/node_modules/source-map/lib/array-set.js
generated
vendored
@@ -1,121 +0,0 @@
|
||||
/* -*- Mode: js; js-indent-level: 2; -*- */
|
||||
/*
|
||||
* Copyright 2011 Mozilla Foundation and contributors
|
||||
* Licensed under the New BSD license. See LICENSE or:
|
||||
* http://opensource.org/licenses/BSD-3-Clause
|
||||
*/
|
||||
|
||||
var util = require('./util');
|
||||
var has = Object.prototype.hasOwnProperty;
|
||||
var hasNativeMap = typeof Map !== "undefined";
|
||||
|
||||
/**
|
||||
* A data structure which is a combination of an array and a set. Adding a new
|
||||
* member is O(1), testing for membership is O(1), and finding the index of an
|
||||
* element is O(1). Removing elements from the set is not supported. Only
|
||||
* strings are supported for membership.
|
||||
*/
|
||||
function ArraySet() {
|
||||
this._array = [];
|
||||
this._set = hasNativeMap ? new Map() : Object.create(null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Static method for creating ArraySet instances from an existing array.
|
||||
*/
|
||||
ArraySet.fromArray = function ArraySet_fromArray(aArray, aAllowDuplicates) {
|
||||
var set = new ArraySet();
|
||||
for (var i = 0, len = aArray.length; i < len; i++) {
|
||||
set.add(aArray[i], aAllowDuplicates);
|
||||
}
|
||||
return set;
|
||||
};
|
||||
|
||||
/**
|
||||
* Return how many unique items are in this ArraySet. If duplicates have been
|
||||
* added, than those do not count towards the size.
|
||||
*
|
||||
* @returns Number
|
||||
*/
|
||||
ArraySet.prototype.size = function ArraySet_size() {
|
||||
return hasNativeMap ? this._set.size : Object.getOwnPropertyNames(this._set).length;
|
||||
};
|
||||
|
||||
/**
|
||||
* Add the given string to this set.
|
||||
*
|
||||
* @param String aStr
|
||||
*/
|
||||
ArraySet.prototype.add = function ArraySet_add(aStr, aAllowDuplicates) {
|
||||
var sStr = hasNativeMap ? aStr : util.toSetString(aStr);
|
||||
var isDuplicate = hasNativeMap ? this.has(aStr) : has.call(this._set, sStr);
|
||||
var idx = this._array.length;
|
||||
if (!isDuplicate || aAllowDuplicates) {
|
||||
this._array.push(aStr);
|
||||
}
|
||||
if (!isDuplicate) {
|
||||
if (hasNativeMap) {
|
||||
this._set.set(aStr, idx);
|
||||
} else {
|
||||
this._set[sStr] = idx;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Is the given string a member of this set?
|
||||
*
|
||||
* @param String aStr
|
||||
*/
|
||||
ArraySet.prototype.has = function ArraySet_has(aStr) {
|
||||
if (hasNativeMap) {
|
||||
return this._set.has(aStr);
|
||||
} else {
|
||||
var sStr = util.toSetString(aStr);
|
||||
return has.call(this._set, sStr);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* What is the index of the given string in the array?
|
||||
*
|
||||
* @param String aStr
|
||||
*/
|
||||
ArraySet.prototype.indexOf = function ArraySet_indexOf(aStr) {
|
||||
if (hasNativeMap) {
|
||||
var idx = this._set.get(aStr);
|
||||
if (idx >= 0) {
|
||||
return idx;
|
||||
}
|
||||
} else {
|
||||
var sStr = util.toSetString(aStr);
|
||||
if (has.call(this._set, sStr)) {
|
||||
return this._set[sStr];
|
||||
}
|
||||
}
|
||||
|
||||
throw new Error('"' + aStr + '" is not in the set.');
|
||||
};
|
||||
|
||||
/**
|
||||
* What is the element at the given index?
|
||||
*
|
||||
* @param Number aIdx
|
||||
*/
|
||||
ArraySet.prototype.at = function ArraySet_at(aIdx) {
|
||||
if (aIdx >= 0 && aIdx < this._array.length) {
|
||||
return this._array[aIdx];
|
||||
}
|
||||
throw new Error('No element indexed by ' + aIdx);
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns the array representation of this set (which has the proper indices
|
||||
* indicated by indexOf). Note that this is a copy of the internal array used
|
||||
* for storing the members so that no one can mess with internal state.
|
||||
*/
|
||||
ArraySet.prototype.toArray = function ArraySet_toArray() {
|
||||
return this._array.slice();
|
||||
};
|
||||
|
||||
exports.ArraySet = ArraySet;
|
||||
140
node_modules/csso/node_modules/source-map/lib/base64-vlq.js
generated
vendored
140
node_modules/csso/node_modules/source-map/lib/base64-vlq.js
generated
vendored
@@ -1,140 +0,0 @@
|
||||
/* -*- Mode: js; js-indent-level: 2; -*- */
|
||||
/*
|
||||
* Copyright 2011 Mozilla Foundation and contributors
|
||||
* Licensed under the New BSD license. See LICENSE or:
|
||||
* http://opensource.org/licenses/BSD-3-Clause
|
||||
*
|
||||
* Based on the Base 64 VLQ implementation in Closure Compiler:
|
||||
* https://code.google.com/p/closure-compiler/source/browse/trunk/src/com/google/debugging/sourcemap/Base64VLQ.java
|
||||
*
|
||||
* Copyright 2011 The Closure Compiler Authors. All rights reserved.
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following
|
||||
* disclaimer in the documentation and/or other materials provided
|
||||
* with the distribution.
|
||||
* * Neither the name of Google Inc. nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
var base64 = require('./base64');
|
||||
|
||||
// A single base 64 digit can contain 6 bits of data. For the base 64 variable
|
||||
// length quantities we use in the source map spec, the first bit is the sign,
|
||||
// the next four bits are the actual value, and the 6th bit is the
|
||||
// continuation bit. The continuation bit tells us whether there are more
|
||||
// digits in this value following this digit.
|
||||
//
|
||||
// Continuation
|
||||
// | Sign
|
||||
// | |
|
||||
// V V
|
||||
// 101011
|
||||
|
||||
var VLQ_BASE_SHIFT = 5;
|
||||
|
||||
// binary: 100000
|
||||
var VLQ_BASE = 1 << VLQ_BASE_SHIFT;
|
||||
|
||||
// binary: 011111
|
||||
var VLQ_BASE_MASK = VLQ_BASE - 1;
|
||||
|
||||
// binary: 100000
|
||||
var VLQ_CONTINUATION_BIT = VLQ_BASE;
|
||||
|
||||
/**
|
||||
* Converts from a two-complement value to a value where the sign bit is
|
||||
* placed in the least significant bit. For example, as decimals:
|
||||
* 1 becomes 2 (10 binary), -1 becomes 3 (11 binary)
|
||||
* 2 becomes 4 (100 binary), -2 becomes 5 (101 binary)
|
||||
*/
|
||||
function toVLQSigned(aValue) {
|
||||
return aValue < 0
|
||||
? ((-aValue) << 1) + 1
|
||||
: (aValue << 1) + 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts to a two-complement value from a value where the sign bit is
|
||||
* placed in the least significant bit. For example, as decimals:
|
||||
* 2 (10 binary) becomes 1, 3 (11 binary) becomes -1
|
||||
* 4 (100 binary) becomes 2, 5 (101 binary) becomes -2
|
||||
*/
|
||||
function fromVLQSigned(aValue) {
|
||||
var isNegative = (aValue & 1) === 1;
|
||||
var shifted = aValue >> 1;
|
||||
return isNegative
|
||||
? -shifted
|
||||
: shifted;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the base 64 VLQ encoded value.
|
||||
*/
|
||||
exports.encode = function base64VLQ_encode(aValue) {
|
||||
var encoded = "";
|
||||
var digit;
|
||||
|
||||
var vlq = toVLQSigned(aValue);
|
||||
|
||||
do {
|
||||
digit = vlq & VLQ_BASE_MASK;
|
||||
vlq >>>= VLQ_BASE_SHIFT;
|
||||
if (vlq > 0) {
|
||||
// There are still more digits in this value, so we must make sure the
|
||||
// continuation bit is marked.
|
||||
digit |= VLQ_CONTINUATION_BIT;
|
||||
}
|
||||
encoded += base64.encode(digit);
|
||||
} while (vlq > 0);
|
||||
|
||||
return encoded;
|
||||
};
|
||||
|
||||
/**
|
||||
* Decodes the next base 64 VLQ value from the given string and returns the
|
||||
* value and the rest of the string via the out parameter.
|
||||
*/
|
||||
exports.decode = function base64VLQ_decode(aStr, aIndex, aOutParam) {
|
||||
var strLen = aStr.length;
|
||||
var result = 0;
|
||||
var shift = 0;
|
||||
var continuation, digit;
|
||||
|
||||
do {
|
||||
if (aIndex >= strLen) {
|
||||
throw new Error("Expected more digits in base 64 VLQ value.");
|
||||
}
|
||||
|
||||
digit = base64.decode(aStr.charCodeAt(aIndex++));
|
||||
if (digit === -1) {
|
||||
throw new Error("Invalid base64 digit: " + aStr.charAt(aIndex - 1));
|
||||
}
|
||||
|
||||
continuation = !!(digit & VLQ_CONTINUATION_BIT);
|
||||
digit &= VLQ_BASE_MASK;
|
||||
result = result + (digit << shift);
|
||||
shift += VLQ_BASE_SHIFT;
|
||||
} while (continuation);
|
||||
|
||||
aOutParam.value = fromVLQSigned(result);
|
||||
aOutParam.rest = aIndex;
|
||||
};
|
||||
67
node_modules/csso/node_modules/source-map/lib/base64.js
generated
vendored
67
node_modules/csso/node_modules/source-map/lib/base64.js
generated
vendored
@@ -1,67 +0,0 @@
|
||||
/* -*- Mode: js; js-indent-level: 2; -*- */
|
||||
/*
|
||||
* Copyright 2011 Mozilla Foundation and contributors
|
||||
* Licensed under the New BSD license. See LICENSE or:
|
||||
* http://opensource.org/licenses/BSD-3-Clause
|
||||
*/
|
||||
|
||||
var intToCharMap = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'.split('');
|
||||
|
||||
/**
|
||||
* Encode an integer in the range of 0 to 63 to a single base 64 digit.
|
||||
*/
|
||||
exports.encode = function (number) {
|
||||
if (0 <= number && number < intToCharMap.length) {
|
||||
return intToCharMap[number];
|
||||
}
|
||||
throw new TypeError("Must be between 0 and 63: " + number);
|
||||
};
|
||||
|
||||
/**
|
||||
* Decode a single base 64 character code digit to an integer. Returns -1 on
|
||||
* failure.
|
||||
*/
|
||||
exports.decode = function (charCode) {
|
||||
var bigA = 65; // 'A'
|
||||
var bigZ = 90; // 'Z'
|
||||
|
||||
var littleA = 97; // 'a'
|
||||
var littleZ = 122; // 'z'
|
||||
|
||||
var zero = 48; // '0'
|
||||
var nine = 57; // '9'
|
||||
|
||||
var plus = 43; // '+'
|
||||
var slash = 47; // '/'
|
||||
|
||||
var littleOffset = 26;
|
||||
var numberOffset = 52;
|
||||
|
||||
// 0 - 25: ABCDEFGHIJKLMNOPQRSTUVWXYZ
|
||||
if (bigA <= charCode && charCode <= bigZ) {
|
||||
return (charCode - bigA);
|
||||
}
|
||||
|
||||
// 26 - 51: abcdefghijklmnopqrstuvwxyz
|
||||
if (littleA <= charCode && charCode <= littleZ) {
|
||||
return (charCode - littleA + littleOffset);
|
||||
}
|
||||
|
||||
// 52 - 61: 0123456789
|
||||
if (zero <= charCode && charCode <= nine) {
|
||||
return (charCode - zero + numberOffset);
|
||||
}
|
||||
|
||||
// 62: +
|
||||
if (charCode == plus) {
|
||||
return 62;
|
||||
}
|
||||
|
||||
// 63: /
|
||||
if (charCode == slash) {
|
||||
return 63;
|
||||
}
|
||||
|
||||
// Invalid base64 digit.
|
||||
return -1;
|
||||
};
|
||||
111
node_modules/csso/node_modules/source-map/lib/binary-search.js
generated
vendored
111
node_modules/csso/node_modules/source-map/lib/binary-search.js
generated
vendored
@@ -1,111 +0,0 @@
|
||||
/* -*- Mode: js; js-indent-level: 2; -*- */
|
||||
/*
|
||||
* Copyright 2011 Mozilla Foundation and contributors
|
||||
* Licensed under the New BSD license. See LICENSE or:
|
||||
* http://opensource.org/licenses/BSD-3-Clause
|
||||
*/
|
||||
|
||||
exports.GREATEST_LOWER_BOUND = 1;
|
||||
exports.LEAST_UPPER_BOUND = 2;
|
||||
|
||||
/**
|
||||
* Recursive implementation of binary search.
|
||||
*
|
||||
* @param aLow Indices here and lower do not contain the needle.
|
||||
* @param aHigh Indices here and higher do not contain the needle.
|
||||
* @param aNeedle The element being searched for.
|
||||
* @param aHaystack The non-empty array being searched.
|
||||
* @param aCompare Function which takes two elements and returns -1, 0, or 1.
|
||||
* @param aBias Either 'binarySearch.GREATEST_LOWER_BOUND' or
|
||||
* 'binarySearch.LEAST_UPPER_BOUND'. Specifies whether to return the
|
||||
* closest element that is smaller than or greater than the one we are
|
||||
* searching for, respectively, if the exact element cannot be found.
|
||||
*/
|
||||
function recursiveSearch(aLow, aHigh, aNeedle, aHaystack, aCompare, aBias) {
|
||||
// This function terminates when one of the following is true:
|
||||
//
|
||||
// 1. We find the exact element we are looking for.
|
||||
//
|
||||
// 2. We did not find the exact element, but we can return the index of
|
||||
// the next-closest element.
|
||||
//
|
||||
// 3. We did not find the exact element, and there is no next-closest
|
||||
// element than the one we are searching for, so we return -1.
|
||||
var mid = Math.floor((aHigh - aLow) / 2) + aLow;
|
||||
var cmp = aCompare(aNeedle, aHaystack[mid], true);
|
||||
if (cmp === 0) {
|
||||
// Found the element we are looking for.
|
||||
return mid;
|
||||
}
|
||||
else if (cmp > 0) {
|
||||
// Our needle is greater than aHaystack[mid].
|
||||
if (aHigh - mid > 1) {
|
||||
// The element is in the upper half.
|
||||
return recursiveSearch(mid, aHigh, aNeedle, aHaystack, aCompare, aBias);
|
||||
}
|
||||
|
||||
// The exact needle element was not found in this haystack. Determine if
|
||||
// we are in termination case (3) or (2) and return the appropriate thing.
|
||||
if (aBias == exports.LEAST_UPPER_BOUND) {
|
||||
return aHigh < aHaystack.length ? aHigh : -1;
|
||||
} else {
|
||||
return mid;
|
||||
}
|
||||
}
|
||||
else {
|
||||
// Our needle is less than aHaystack[mid].
|
||||
if (mid - aLow > 1) {
|
||||
// The element is in the lower half.
|
||||
return recursiveSearch(aLow, mid, aNeedle, aHaystack, aCompare, aBias);
|
||||
}
|
||||
|
||||
// we are in termination case (3) or (2) and return the appropriate thing.
|
||||
if (aBias == exports.LEAST_UPPER_BOUND) {
|
||||
return mid;
|
||||
} else {
|
||||
return aLow < 0 ? -1 : aLow;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This is an implementation of binary search which will always try and return
|
||||
* the index of the closest element if there is no exact hit. This is because
|
||||
* mappings between original and generated line/col pairs are single points,
|
||||
* and there is an implicit region between each of them, so a miss just means
|
||||
* that you aren't on the very start of a region.
|
||||
*
|
||||
* @param aNeedle The element you are looking for.
|
||||
* @param aHaystack The array that is being searched.
|
||||
* @param aCompare A function which takes the needle and an element in the
|
||||
* array and returns -1, 0, or 1 depending on whether the needle is less
|
||||
* than, equal to, or greater than the element, respectively.
|
||||
* @param aBias Either 'binarySearch.GREATEST_LOWER_BOUND' or
|
||||
* 'binarySearch.LEAST_UPPER_BOUND'. Specifies whether to return the
|
||||
* closest element that is smaller than or greater than the one we are
|
||||
* searching for, respectively, if the exact element cannot be found.
|
||||
* Defaults to 'binarySearch.GREATEST_LOWER_BOUND'.
|
||||
*/
|
||||
exports.search = function search(aNeedle, aHaystack, aCompare, aBias) {
|
||||
if (aHaystack.length === 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
var index = recursiveSearch(-1, aHaystack.length, aNeedle, aHaystack,
|
||||
aCompare, aBias || exports.GREATEST_LOWER_BOUND);
|
||||
if (index < 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
// We have found either the exact element, or the next-closest element than
|
||||
// the one we are searching for. However, there may be more than one such
|
||||
// element. Make sure we always return the smallest of these.
|
||||
while (index - 1 >= 0) {
|
||||
if (aCompare(aHaystack[index], aHaystack[index - 1], true) !== 0) {
|
||||
break;
|
||||
}
|
||||
--index;
|
||||
}
|
||||
|
||||
return index;
|
||||
};
|
||||
79
node_modules/csso/node_modules/source-map/lib/mapping-list.js
generated
vendored
79
node_modules/csso/node_modules/source-map/lib/mapping-list.js
generated
vendored
@@ -1,79 +0,0 @@
|
||||
/* -*- Mode: js; js-indent-level: 2; -*- */
|
||||
/*
|
||||
* Copyright 2014 Mozilla Foundation and contributors
|
||||
* Licensed under the New BSD license. See LICENSE or:
|
||||
* http://opensource.org/licenses/BSD-3-Clause
|
||||
*/
|
||||
|
||||
var util = require('./util');
|
||||
|
||||
/**
|
||||
* Determine whether mappingB is after mappingA with respect to generated
|
||||
* position.
|
||||
*/
|
||||
function generatedPositionAfter(mappingA, mappingB) {
|
||||
// Optimized for most common case
|
||||
var lineA = mappingA.generatedLine;
|
||||
var lineB = mappingB.generatedLine;
|
||||
var columnA = mappingA.generatedColumn;
|
||||
var columnB = mappingB.generatedColumn;
|
||||
return lineB > lineA || lineB == lineA && columnB >= columnA ||
|
||||
util.compareByGeneratedPositionsInflated(mappingA, mappingB) <= 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* A data structure to provide a sorted view of accumulated mappings in a
|
||||
* performance conscious manner. It trades a neglibable overhead in general
|
||||
* case for a large speedup in case of mappings being added in order.
|
||||
*/
|
||||
function MappingList() {
|
||||
this._array = [];
|
||||
this._sorted = true;
|
||||
// Serves as infimum
|
||||
this._last = {generatedLine: -1, generatedColumn: 0};
|
||||
}
|
||||
|
||||
/**
|
||||
* Iterate through internal items. This method takes the same arguments that
|
||||
* `Array.prototype.forEach` takes.
|
||||
*
|
||||
* NOTE: The order of the mappings is NOT guaranteed.
|
||||
*/
|
||||
MappingList.prototype.unsortedForEach =
|
||||
function MappingList_forEach(aCallback, aThisArg) {
|
||||
this._array.forEach(aCallback, aThisArg);
|
||||
};
|
||||
|
||||
/**
|
||||
* Add the given source mapping.
|
||||
*
|
||||
* @param Object aMapping
|
||||
*/
|
||||
MappingList.prototype.add = function MappingList_add(aMapping) {
|
||||
if (generatedPositionAfter(this._last, aMapping)) {
|
||||
this._last = aMapping;
|
||||
this._array.push(aMapping);
|
||||
} else {
|
||||
this._sorted = false;
|
||||
this._array.push(aMapping);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns the flat, sorted array of mappings. The mappings are sorted by
|
||||
* generated position.
|
||||
*
|
||||
* WARNING: This method returns internal data without copying, for
|
||||
* performance. The return value must NOT be mutated, and should be treated as
|
||||
* an immutable borrow. If you want to take ownership, you must make your own
|
||||
* copy.
|
||||
*/
|
||||
MappingList.prototype.toArray = function MappingList_toArray() {
|
||||
if (!this._sorted) {
|
||||
this._array.sort(util.compareByGeneratedPositionsInflated);
|
||||
this._sorted = true;
|
||||
}
|
||||
return this._array;
|
||||
};
|
||||
|
||||
exports.MappingList = MappingList;
|
||||
114
node_modules/csso/node_modules/source-map/lib/quick-sort.js
generated
vendored
114
node_modules/csso/node_modules/source-map/lib/quick-sort.js
generated
vendored
@@ -1,114 +0,0 @@
|
||||
/* -*- Mode: js; js-indent-level: 2; -*- */
|
||||
/*
|
||||
* Copyright 2011 Mozilla Foundation and contributors
|
||||
* Licensed under the New BSD license. See LICENSE or:
|
||||
* http://opensource.org/licenses/BSD-3-Clause
|
||||
*/
|
||||
|
||||
// It turns out that some (most?) JavaScript engines don't self-host
|
||||
// `Array.prototype.sort`. This makes sense because C++ will likely remain
|
||||
// faster than JS when doing raw CPU-intensive sorting. However, when using a
|
||||
// custom comparator function, calling back and forth between the VM's C++ and
|
||||
// JIT'd JS is rather slow *and* loses JIT type information, resulting in
|
||||
// worse generated code for the comparator function than would be optimal. In
|
||||
// fact, when sorting with a comparator, these costs outweigh the benefits of
|
||||
// sorting in C++. By using our own JS-implemented Quick Sort (below), we get
|
||||
// a ~3500ms mean speed-up in `bench/bench.html`.
|
||||
|
||||
/**
|
||||
* Swap the elements indexed by `x` and `y` in the array `ary`.
|
||||
*
|
||||
* @param {Array} ary
|
||||
* The array.
|
||||
* @param {Number} x
|
||||
* The index of the first item.
|
||||
* @param {Number} y
|
||||
* The index of the second item.
|
||||
*/
|
||||
function swap(ary, x, y) {
|
||||
var temp = ary[x];
|
||||
ary[x] = ary[y];
|
||||
ary[y] = temp;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a random integer within the range `low .. high` inclusive.
|
||||
*
|
||||
* @param {Number} low
|
||||
* The lower bound on the range.
|
||||
* @param {Number} high
|
||||
* The upper bound on the range.
|
||||
*/
|
||||
function randomIntInRange(low, high) {
|
||||
return Math.round(low + (Math.random() * (high - low)));
|
||||
}
|
||||
|
||||
/**
|
||||
* The Quick Sort algorithm.
|
||||
*
|
||||
* @param {Array} ary
|
||||
* An array to sort.
|
||||
* @param {function} comparator
|
||||
* Function to use to compare two items.
|
||||
* @param {Number} p
|
||||
* Start index of the array
|
||||
* @param {Number} r
|
||||
* End index of the array
|
||||
*/
|
||||
function doQuickSort(ary, comparator, p, r) {
|
||||
// If our lower bound is less than our upper bound, we (1) partition the
|
||||
// array into two pieces and (2) recurse on each half. If it is not, this is
|
||||
// the empty array and our base case.
|
||||
|
||||
if (p < r) {
|
||||
// (1) Partitioning.
|
||||
//
|
||||
// The partitioning chooses a pivot between `p` and `r` and moves all
|
||||
// elements that are less than or equal to the pivot to the before it, and
|
||||
// all the elements that are greater than it after it. The effect is that
|
||||
// once partition is done, the pivot is in the exact place it will be when
|
||||
// the array is put in sorted order, and it will not need to be moved
|
||||
// again. This runs in O(n) time.
|
||||
|
||||
// Always choose a random pivot so that an input array which is reverse
|
||||
// sorted does not cause O(n^2) running time.
|
||||
var pivotIndex = randomIntInRange(p, r);
|
||||
var i = p - 1;
|
||||
|
||||
swap(ary, pivotIndex, r);
|
||||
var pivot = ary[r];
|
||||
|
||||
// Immediately after `j` is incremented in this loop, the following hold
|
||||
// true:
|
||||
//
|
||||
// * Every element in `ary[p .. i]` is less than or equal to the pivot.
|
||||
//
|
||||
// * Every element in `ary[i+1 .. j-1]` is greater than the pivot.
|
||||
for (var j = p; j < r; j++) {
|
||||
if (comparator(ary[j], pivot) <= 0) {
|
||||
i += 1;
|
||||
swap(ary, i, j);
|
||||
}
|
||||
}
|
||||
|
||||
swap(ary, i + 1, j);
|
||||
var q = i + 1;
|
||||
|
||||
// (2) Recurse on each half.
|
||||
|
||||
doQuickSort(ary, comparator, p, q - 1);
|
||||
doQuickSort(ary, comparator, q + 1, r);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sort the given array in-place with the given comparator function.
|
||||
*
|
||||
* @param {Array} ary
|
||||
* An array to sort.
|
||||
* @param {function} comparator
|
||||
* Function to use to compare two items.
|
||||
*/
|
||||
exports.quickSort = function (ary, comparator) {
|
||||
doQuickSort(ary, comparator, 0, ary.length - 1);
|
||||
};
|
||||
1082
node_modules/csso/node_modules/source-map/lib/source-map-consumer.js
generated
vendored
1082
node_modules/csso/node_modules/source-map/lib/source-map-consumer.js
generated
vendored
File diff suppressed because it is too large
Load Diff
416
node_modules/csso/node_modules/source-map/lib/source-map-generator.js
generated
vendored
416
node_modules/csso/node_modules/source-map/lib/source-map-generator.js
generated
vendored
@@ -1,416 +0,0 @@
|
||||
/* -*- Mode: js; js-indent-level: 2; -*- */
|
||||
/*
|
||||
* Copyright 2011 Mozilla Foundation and contributors
|
||||
* Licensed under the New BSD license. See LICENSE or:
|
||||
* http://opensource.org/licenses/BSD-3-Clause
|
||||
*/
|
||||
|
||||
var base64VLQ = require('./base64-vlq');
|
||||
var util = require('./util');
|
||||
var ArraySet = require('./array-set').ArraySet;
|
||||
var MappingList = require('./mapping-list').MappingList;
|
||||
|
||||
/**
|
||||
* An instance of the SourceMapGenerator represents a source map which is
|
||||
* being built incrementally. You may pass an object with the following
|
||||
* properties:
|
||||
*
|
||||
* - file: The filename of the generated source.
|
||||
* - sourceRoot: A root for all relative URLs in this source map.
|
||||
*/
|
||||
function SourceMapGenerator(aArgs) {
|
||||
if (!aArgs) {
|
||||
aArgs = {};
|
||||
}
|
||||
this._file = util.getArg(aArgs, 'file', null);
|
||||
this._sourceRoot = util.getArg(aArgs, 'sourceRoot', null);
|
||||
this._skipValidation = util.getArg(aArgs, 'skipValidation', false);
|
||||
this._sources = new ArraySet();
|
||||
this._names = new ArraySet();
|
||||
this._mappings = new MappingList();
|
||||
this._sourcesContents = null;
|
||||
}
|
||||
|
||||
SourceMapGenerator.prototype._version = 3;
|
||||
|
||||
/**
|
||||
* Creates a new SourceMapGenerator based on a SourceMapConsumer
|
||||
*
|
||||
* @param aSourceMapConsumer The SourceMap.
|
||||
*/
|
||||
SourceMapGenerator.fromSourceMap =
|
||||
function SourceMapGenerator_fromSourceMap(aSourceMapConsumer) {
|
||||
var sourceRoot = aSourceMapConsumer.sourceRoot;
|
||||
var generator = new SourceMapGenerator({
|
||||
file: aSourceMapConsumer.file,
|
||||
sourceRoot: sourceRoot
|
||||
});
|
||||
aSourceMapConsumer.eachMapping(function (mapping) {
|
||||
var newMapping = {
|
||||
generated: {
|
||||
line: mapping.generatedLine,
|
||||
column: mapping.generatedColumn
|
||||
}
|
||||
};
|
||||
|
||||
if (mapping.source != null) {
|
||||
newMapping.source = mapping.source;
|
||||
if (sourceRoot != null) {
|
||||
newMapping.source = util.relative(sourceRoot, newMapping.source);
|
||||
}
|
||||
|
||||
newMapping.original = {
|
||||
line: mapping.originalLine,
|
||||
column: mapping.originalColumn
|
||||
};
|
||||
|
||||
if (mapping.name != null) {
|
||||
newMapping.name = mapping.name;
|
||||
}
|
||||
}
|
||||
|
||||
generator.addMapping(newMapping);
|
||||
});
|
||||
aSourceMapConsumer.sources.forEach(function (sourceFile) {
|
||||
var content = aSourceMapConsumer.sourceContentFor(sourceFile);
|
||||
if (content != null) {
|
||||
generator.setSourceContent(sourceFile, content);
|
||||
}
|
||||
});
|
||||
return generator;
|
||||
};
|
||||
|
||||
/**
|
||||
* Add a single mapping from original source line and column to the generated
|
||||
* source's line and column for this source map being created. The mapping
|
||||
* object should have the following properties:
|
||||
*
|
||||
* - generated: An object with the generated line and column positions.
|
||||
* - original: An object with the original line and column positions.
|
||||
* - source: The original source file (relative to the sourceRoot).
|
||||
* - name: An optional original token name for this mapping.
|
||||
*/
|
||||
SourceMapGenerator.prototype.addMapping =
|
||||
function SourceMapGenerator_addMapping(aArgs) {
|
||||
var generated = util.getArg(aArgs, 'generated');
|
||||
var original = util.getArg(aArgs, 'original', null);
|
||||
var source = util.getArg(aArgs, 'source', null);
|
||||
var name = util.getArg(aArgs, 'name', null);
|
||||
|
||||
if (!this._skipValidation) {
|
||||
this._validateMapping(generated, original, source, name);
|
||||
}
|
||||
|
||||
if (source != null) {
|
||||
source = String(source);
|
||||
if (!this._sources.has(source)) {
|
||||
this._sources.add(source);
|
||||
}
|
||||
}
|
||||
|
||||
if (name != null) {
|
||||
name = String(name);
|
||||
if (!this._names.has(name)) {
|
||||
this._names.add(name);
|
||||
}
|
||||
}
|
||||
|
||||
this._mappings.add({
|
||||
generatedLine: generated.line,
|
||||
generatedColumn: generated.column,
|
||||
originalLine: original != null && original.line,
|
||||
originalColumn: original != null && original.column,
|
||||
source: source,
|
||||
name: name
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Set the source content for a source file.
|
||||
*/
|
||||
SourceMapGenerator.prototype.setSourceContent =
|
||||
function SourceMapGenerator_setSourceContent(aSourceFile, aSourceContent) {
|
||||
var source = aSourceFile;
|
||||
if (this._sourceRoot != null) {
|
||||
source = util.relative(this._sourceRoot, source);
|
||||
}
|
||||
|
||||
if (aSourceContent != null) {
|
||||
// Add the source content to the _sourcesContents map.
|
||||
// Create a new _sourcesContents map if the property is null.
|
||||
if (!this._sourcesContents) {
|
||||
this._sourcesContents = Object.create(null);
|
||||
}
|
||||
this._sourcesContents[util.toSetString(source)] = aSourceContent;
|
||||
} else if (this._sourcesContents) {
|
||||
// Remove the source file from the _sourcesContents map.
|
||||
// If the _sourcesContents map is empty, set the property to null.
|
||||
delete this._sourcesContents[util.toSetString(source)];
|
||||
if (Object.keys(this._sourcesContents).length === 0) {
|
||||
this._sourcesContents = null;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Applies the mappings of a sub-source-map for a specific source file to the
|
||||
* source map being generated. Each mapping to the supplied source file is
|
||||
* rewritten using the supplied source map. Note: The resolution for the
|
||||
* resulting mappings is the minimium of this map and the supplied map.
|
||||
*
|
||||
* @param aSourceMapConsumer The source map to be applied.
|
||||
* @param aSourceFile Optional. The filename of the source file.
|
||||
* If omitted, SourceMapConsumer's file property will be used.
|
||||
* @param aSourceMapPath Optional. The dirname of the path to the source map
|
||||
* to be applied. If relative, it is relative to the SourceMapConsumer.
|
||||
* This parameter is needed when the two source maps aren't in the same
|
||||
* directory, and the source map to be applied contains relative source
|
||||
* paths. If so, those relative source paths need to be rewritten
|
||||
* relative to the SourceMapGenerator.
|
||||
*/
|
||||
SourceMapGenerator.prototype.applySourceMap =
|
||||
function SourceMapGenerator_applySourceMap(aSourceMapConsumer, aSourceFile, aSourceMapPath) {
|
||||
var sourceFile = aSourceFile;
|
||||
// If aSourceFile is omitted, we will use the file property of the SourceMap
|
||||
if (aSourceFile == null) {
|
||||
if (aSourceMapConsumer.file == null) {
|
||||
throw new Error(
|
||||
'SourceMapGenerator.prototype.applySourceMap requires either an explicit source file, ' +
|
||||
'or the source map\'s "file" property. Both were omitted.'
|
||||
);
|
||||
}
|
||||
sourceFile = aSourceMapConsumer.file;
|
||||
}
|
||||
var sourceRoot = this._sourceRoot;
|
||||
// Make "sourceFile" relative if an absolute Url is passed.
|
||||
if (sourceRoot != null) {
|
||||
sourceFile = util.relative(sourceRoot, sourceFile);
|
||||
}
|
||||
// Applying the SourceMap can add and remove items from the sources and
|
||||
// the names array.
|
||||
var newSources = new ArraySet();
|
||||
var newNames = new ArraySet();
|
||||
|
||||
// Find mappings for the "sourceFile"
|
||||
this._mappings.unsortedForEach(function (mapping) {
|
||||
if (mapping.source === sourceFile && mapping.originalLine != null) {
|
||||
// Check if it can be mapped by the source map, then update the mapping.
|
||||
var original = aSourceMapConsumer.originalPositionFor({
|
||||
line: mapping.originalLine,
|
||||
column: mapping.originalColumn
|
||||
});
|
||||
if (original.source != null) {
|
||||
// Copy mapping
|
||||
mapping.source = original.source;
|
||||
if (aSourceMapPath != null) {
|
||||
mapping.source = util.join(aSourceMapPath, mapping.source)
|
||||
}
|
||||
if (sourceRoot != null) {
|
||||
mapping.source = util.relative(sourceRoot, mapping.source);
|
||||
}
|
||||
mapping.originalLine = original.line;
|
||||
mapping.originalColumn = original.column;
|
||||
if (original.name != null) {
|
||||
mapping.name = original.name;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var source = mapping.source;
|
||||
if (source != null && !newSources.has(source)) {
|
||||
newSources.add(source);
|
||||
}
|
||||
|
||||
var name = mapping.name;
|
||||
if (name != null && !newNames.has(name)) {
|
||||
newNames.add(name);
|
||||
}
|
||||
|
||||
}, this);
|
||||
this._sources = newSources;
|
||||
this._names = newNames;
|
||||
|
||||
// Copy sourcesContents of applied map.
|
||||
aSourceMapConsumer.sources.forEach(function (sourceFile) {
|
||||
var content = aSourceMapConsumer.sourceContentFor(sourceFile);
|
||||
if (content != null) {
|
||||
if (aSourceMapPath != null) {
|
||||
sourceFile = util.join(aSourceMapPath, sourceFile);
|
||||
}
|
||||
if (sourceRoot != null) {
|
||||
sourceFile = util.relative(sourceRoot, sourceFile);
|
||||
}
|
||||
this.setSourceContent(sourceFile, content);
|
||||
}
|
||||
}, this);
|
||||
};
|
||||
|
||||
/**
|
||||
* A mapping can have one of the three levels of data:
|
||||
*
|
||||
* 1. Just the generated position.
|
||||
* 2. The Generated position, original position, and original source.
|
||||
* 3. Generated and original position, original source, as well as a name
|
||||
* token.
|
||||
*
|
||||
* To maintain consistency, we validate that any new mapping being added falls
|
||||
* in to one of these categories.
|
||||
*/
|
||||
SourceMapGenerator.prototype._validateMapping =
|
||||
function SourceMapGenerator_validateMapping(aGenerated, aOriginal, aSource,
|
||||
aName) {
|
||||
// When aOriginal is truthy but has empty values for .line and .column,
|
||||
// it is most likely a programmer error. In this case we throw a very
|
||||
// specific error message to try to guide them the right way.
|
||||
// For example: https://github.com/Polymer/polymer-bundler/pull/519
|
||||
if (aOriginal && typeof aOriginal.line !== 'number' && typeof aOriginal.column !== 'number') {
|
||||
throw new Error(
|
||||
'original.line and original.column are not numbers -- you probably meant to omit ' +
|
||||
'the original mapping entirely and only map the generated position. If so, pass ' +
|
||||
'null for the original mapping instead of an object with empty or null values.'
|
||||
);
|
||||
}
|
||||
|
||||
if (aGenerated && 'line' in aGenerated && 'column' in aGenerated
|
||||
&& aGenerated.line > 0 && aGenerated.column >= 0
|
||||
&& !aOriginal && !aSource && !aName) {
|
||||
// Case 1.
|
||||
return;
|
||||
}
|
||||
else if (aGenerated && 'line' in aGenerated && 'column' in aGenerated
|
||||
&& aOriginal && 'line' in aOriginal && 'column' in aOriginal
|
||||
&& aGenerated.line > 0 && aGenerated.column >= 0
|
||||
&& aOriginal.line > 0 && aOriginal.column >= 0
|
||||
&& aSource) {
|
||||
// Cases 2 and 3.
|
||||
return;
|
||||
}
|
||||
else {
|
||||
throw new Error('Invalid mapping: ' + JSON.stringify({
|
||||
generated: aGenerated,
|
||||
source: aSource,
|
||||
original: aOriginal,
|
||||
name: aName
|
||||
}));
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Serialize the accumulated mappings in to the stream of base 64 VLQs
|
||||
* specified by the source map format.
|
||||
*/
|
||||
SourceMapGenerator.prototype._serializeMappings =
|
||||
function SourceMapGenerator_serializeMappings() {
|
||||
var previousGeneratedColumn = 0;
|
||||
var previousGeneratedLine = 1;
|
||||
var previousOriginalColumn = 0;
|
||||
var previousOriginalLine = 0;
|
||||
var previousName = 0;
|
||||
var previousSource = 0;
|
||||
var result = '';
|
||||
var next;
|
||||
var mapping;
|
||||
var nameIdx;
|
||||
var sourceIdx;
|
||||
|
||||
var mappings = this._mappings.toArray();
|
||||
for (var i = 0, len = mappings.length; i < len; i++) {
|
||||
mapping = mappings[i];
|
||||
next = ''
|
||||
|
||||
if (mapping.generatedLine !== previousGeneratedLine) {
|
||||
previousGeneratedColumn = 0;
|
||||
while (mapping.generatedLine !== previousGeneratedLine) {
|
||||
next += ';';
|
||||
previousGeneratedLine++;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (i > 0) {
|
||||
if (!util.compareByGeneratedPositionsInflated(mapping, mappings[i - 1])) {
|
||||
continue;
|
||||
}
|
||||
next += ',';
|
||||
}
|
||||
}
|
||||
|
||||
next += base64VLQ.encode(mapping.generatedColumn
|
||||
- previousGeneratedColumn);
|
||||
previousGeneratedColumn = mapping.generatedColumn;
|
||||
|
||||
if (mapping.source != null) {
|
||||
sourceIdx = this._sources.indexOf(mapping.source);
|
||||
next += base64VLQ.encode(sourceIdx - previousSource);
|
||||
previousSource = sourceIdx;
|
||||
|
||||
// lines are stored 0-based in SourceMap spec version 3
|
||||
next += base64VLQ.encode(mapping.originalLine - 1
|
||||
- previousOriginalLine);
|
||||
previousOriginalLine = mapping.originalLine - 1;
|
||||
|
||||
next += base64VLQ.encode(mapping.originalColumn
|
||||
- previousOriginalColumn);
|
||||
previousOriginalColumn = mapping.originalColumn;
|
||||
|
||||
if (mapping.name != null) {
|
||||
nameIdx = this._names.indexOf(mapping.name);
|
||||
next += base64VLQ.encode(nameIdx - previousName);
|
||||
previousName = nameIdx;
|
||||
}
|
||||
}
|
||||
|
||||
result += next;
|
||||
}
|
||||
|
||||
return result;
|
||||
};
|
||||
|
||||
SourceMapGenerator.prototype._generateSourcesContent =
|
||||
function SourceMapGenerator_generateSourcesContent(aSources, aSourceRoot) {
|
||||
return aSources.map(function (source) {
|
||||
if (!this._sourcesContents) {
|
||||
return null;
|
||||
}
|
||||
if (aSourceRoot != null) {
|
||||
source = util.relative(aSourceRoot, source);
|
||||
}
|
||||
var key = util.toSetString(source);
|
||||
return Object.prototype.hasOwnProperty.call(this._sourcesContents, key)
|
||||
? this._sourcesContents[key]
|
||||
: null;
|
||||
}, this);
|
||||
};
|
||||
|
||||
/**
|
||||
* Externalize the source map.
|
||||
*/
|
||||
SourceMapGenerator.prototype.toJSON =
|
||||
function SourceMapGenerator_toJSON() {
|
||||
var map = {
|
||||
version: this._version,
|
||||
sources: this._sources.toArray(),
|
||||
names: this._names.toArray(),
|
||||
mappings: this._serializeMappings()
|
||||
};
|
||||
if (this._file != null) {
|
||||
map.file = this._file;
|
||||
}
|
||||
if (this._sourceRoot != null) {
|
||||
map.sourceRoot = this._sourceRoot;
|
||||
}
|
||||
if (this._sourcesContents) {
|
||||
map.sourcesContent = this._generateSourcesContent(map.sources, map.sourceRoot);
|
||||
}
|
||||
|
||||
return map;
|
||||
};
|
||||
|
||||
/**
|
||||
* Render the source map being generated to a string.
|
||||
*/
|
||||
SourceMapGenerator.prototype.toString =
|
||||
function SourceMapGenerator_toString() {
|
||||
return JSON.stringify(this.toJSON());
|
||||
};
|
||||
|
||||
exports.SourceMapGenerator = SourceMapGenerator;
|
||||
413
node_modules/csso/node_modules/source-map/lib/source-node.js
generated
vendored
413
node_modules/csso/node_modules/source-map/lib/source-node.js
generated
vendored
@@ -1,413 +0,0 @@
|
||||
/* -*- Mode: js; js-indent-level: 2; -*- */
|
||||
/*
|
||||
* Copyright 2011 Mozilla Foundation and contributors
|
||||
* Licensed under the New BSD license. See LICENSE or:
|
||||
* http://opensource.org/licenses/BSD-3-Clause
|
||||
*/
|
||||
|
||||
var SourceMapGenerator = require('./source-map-generator').SourceMapGenerator;
|
||||
var util = require('./util');
|
||||
|
||||
// Matches a Windows-style `\r\n` newline or a `\n` newline used by all other
|
||||
// operating systems these days (capturing the result).
|
||||
var REGEX_NEWLINE = /(\r?\n)/;
|
||||
|
||||
// Newline character code for charCodeAt() comparisons
|
||||
var NEWLINE_CODE = 10;
|
||||
|
||||
// Private symbol for identifying `SourceNode`s when multiple versions of
|
||||
// the source-map library are loaded. This MUST NOT CHANGE across
|
||||
// versions!
|
||||
var isSourceNode = "$$$isSourceNode$$$";
|
||||
|
||||
/**
|
||||
* SourceNodes provide a way to abstract over interpolating/concatenating
|
||||
* snippets of generated JavaScript source code while maintaining the line and
|
||||
* column information associated with the original source code.
|
||||
*
|
||||
* @param aLine The original line number.
|
||||
* @param aColumn The original column number.
|
||||
* @param aSource The original source's filename.
|
||||
* @param aChunks Optional. An array of strings which are snippets of
|
||||
* generated JS, or other SourceNodes.
|
||||
* @param aName The original identifier.
|
||||
*/
|
||||
function SourceNode(aLine, aColumn, aSource, aChunks, aName) {
|
||||
this.children = [];
|
||||
this.sourceContents = {};
|
||||
this.line = aLine == null ? null : aLine;
|
||||
this.column = aColumn == null ? null : aColumn;
|
||||
this.source = aSource == null ? null : aSource;
|
||||
this.name = aName == null ? null : aName;
|
||||
this[isSourceNode] = true;
|
||||
if (aChunks != null) this.add(aChunks);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a SourceNode from generated code and a SourceMapConsumer.
|
||||
*
|
||||
* @param aGeneratedCode The generated code
|
||||
* @param aSourceMapConsumer The SourceMap for the generated code
|
||||
* @param aRelativePath Optional. The path that relative sources in the
|
||||
* SourceMapConsumer should be relative to.
|
||||
*/
|
||||
SourceNode.fromStringWithSourceMap =
|
||||
function SourceNode_fromStringWithSourceMap(aGeneratedCode, aSourceMapConsumer, aRelativePath) {
|
||||
// The SourceNode we want to fill with the generated code
|
||||
// and the SourceMap
|
||||
var node = new SourceNode();
|
||||
|
||||
// All even indices of this array are one line of the generated code,
|
||||
// while all odd indices are the newlines between two adjacent lines
|
||||
// (since `REGEX_NEWLINE` captures its match).
|
||||
// Processed fragments are accessed by calling `shiftNextLine`.
|
||||
var remainingLines = aGeneratedCode.split(REGEX_NEWLINE);
|
||||
var remainingLinesIndex = 0;
|
||||
var shiftNextLine = function() {
|
||||
var lineContents = getNextLine();
|
||||
// The last line of a file might not have a newline.
|
||||
var newLine = getNextLine() || "";
|
||||
return lineContents + newLine;
|
||||
|
||||
function getNextLine() {
|
||||
return remainingLinesIndex < remainingLines.length ?
|
||||
remainingLines[remainingLinesIndex++] : undefined;
|
||||
}
|
||||
};
|
||||
|
||||
// We need to remember the position of "remainingLines"
|
||||
var lastGeneratedLine = 1, lastGeneratedColumn = 0;
|
||||
|
||||
// The generate SourceNodes we need a code range.
|
||||
// To extract it current and last mapping is used.
|
||||
// Here we store the last mapping.
|
||||
var lastMapping = null;
|
||||
|
||||
aSourceMapConsumer.eachMapping(function (mapping) {
|
||||
if (lastMapping !== null) {
|
||||
// We add the code from "lastMapping" to "mapping":
|
||||
// First check if there is a new line in between.
|
||||
if (lastGeneratedLine < mapping.generatedLine) {
|
||||
// Associate first line with "lastMapping"
|
||||
addMappingWithCode(lastMapping, shiftNextLine());
|
||||
lastGeneratedLine++;
|
||||
lastGeneratedColumn = 0;
|
||||
// The remaining code is added without mapping
|
||||
} else {
|
||||
// There is no new line in between.
|
||||
// Associate the code between "lastGeneratedColumn" and
|
||||
// "mapping.generatedColumn" with "lastMapping"
|
||||
var nextLine = remainingLines[remainingLinesIndex];
|
||||
var code = nextLine.substr(0, mapping.generatedColumn -
|
||||
lastGeneratedColumn);
|
||||
remainingLines[remainingLinesIndex] = nextLine.substr(mapping.generatedColumn -
|
||||
lastGeneratedColumn);
|
||||
lastGeneratedColumn = mapping.generatedColumn;
|
||||
addMappingWithCode(lastMapping, code);
|
||||
// No more remaining code, continue
|
||||
lastMapping = mapping;
|
||||
return;
|
||||
}
|
||||
}
|
||||
// We add the generated code until the first mapping
|
||||
// to the SourceNode without any mapping.
|
||||
// Each line is added as separate string.
|
||||
while (lastGeneratedLine < mapping.generatedLine) {
|
||||
node.add(shiftNextLine());
|
||||
lastGeneratedLine++;
|
||||
}
|
||||
if (lastGeneratedColumn < mapping.generatedColumn) {
|
||||
var nextLine = remainingLines[remainingLinesIndex];
|
||||
node.add(nextLine.substr(0, mapping.generatedColumn));
|
||||
remainingLines[remainingLinesIndex] = nextLine.substr(mapping.generatedColumn);
|
||||
lastGeneratedColumn = mapping.generatedColumn;
|
||||
}
|
||||
lastMapping = mapping;
|
||||
}, this);
|
||||
// We have processed all mappings.
|
||||
if (remainingLinesIndex < remainingLines.length) {
|
||||
if (lastMapping) {
|
||||
// Associate the remaining code in the current line with "lastMapping"
|
||||
addMappingWithCode(lastMapping, shiftNextLine());
|
||||
}
|
||||
// and add the remaining lines without any mapping
|
||||
node.add(remainingLines.splice(remainingLinesIndex).join(""));
|
||||
}
|
||||
|
||||
// Copy sourcesContent into SourceNode
|
||||
aSourceMapConsumer.sources.forEach(function (sourceFile) {
|
||||
var content = aSourceMapConsumer.sourceContentFor(sourceFile);
|
||||
if (content != null) {
|
||||
if (aRelativePath != null) {
|
||||
sourceFile = util.join(aRelativePath, sourceFile);
|
||||
}
|
||||
node.setSourceContent(sourceFile, content);
|
||||
}
|
||||
});
|
||||
|
||||
return node;
|
||||
|
||||
function addMappingWithCode(mapping, code) {
|
||||
if (mapping === null || mapping.source === undefined) {
|
||||
node.add(code);
|
||||
} else {
|
||||
var source = aRelativePath
|
||||
? util.join(aRelativePath, mapping.source)
|
||||
: mapping.source;
|
||||
node.add(new SourceNode(mapping.originalLine,
|
||||
mapping.originalColumn,
|
||||
source,
|
||||
code,
|
||||
mapping.name));
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Add a chunk of generated JS to this source node.
|
||||
*
|
||||
* @param aChunk A string snippet of generated JS code, another instance of
|
||||
* SourceNode, or an array where each member is one of those things.
|
||||
*/
|
||||
SourceNode.prototype.add = function SourceNode_add(aChunk) {
|
||||
if (Array.isArray(aChunk)) {
|
||||
aChunk.forEach(function (chunk) {
|
||||
this.add(chunk);
|
||||
}, this);
|
||||
}
|
||||
else if (aChunk[isSourceNode] || typeof aChunk === "string") {
|
||||
if (aChunk) {
|
||||
this.children.push(aChunk);
|
||||
}
|
||||
}
|
||||
else {
|
||||
throw new TypeError(
|
||||
"Expected a SourceNode, string, or an array of SourceNodes and strings. Got " + aChunk
|
||||
);
|
||||
}
|
||||
return this;
|
||||
};
|
||||
|
||||
/**
|
||||
* Add a chunk of generated JS to the beginning of this source node.
|
||||
*
|
||||
* @param aChunk A string snippet of generated JS code, another instance of
|
||||
* SourceNode, or an array where each member is one of those things.
|
||||
*/
|
||||
SourceNode.prototype.prepend = function SourceNode_prepend(aChunk) {
|
||||
if (Array.isArray(aChunk)) {
|
||||
for (var i = aChunk.length-1; i >= 0; i--) {
|
||||
this.prepend(aChunk[i]);
|
||||
}
|
||||
}
|
||||
else if (aChunk[isSourceNode] || typeof aChunk === "string") {
|
||||
this.children.unshift(aChunk);
|
||||
}
|
||||
else {
|
||||
throw new TypeError(
|
||||
"Expected a SourceNode, string, or an array of SourceNodes and strings. Got " + aChunk
|
||||
);
|
||||
}
|
||||
return this;
|
||||
};
|
||||
|
||||
/**
|
||||
* Walk over the tree of JS snippets in this node and its children. The
|
||||
* walking function is called once for each snippet of JS and is passed that
|
||||
* snippet and the its original associated source's line/column location.
|
||||
*
|
||||
* @param aFn The traversal function.
|
||||
*/
|
||||
SourceNode.prototype.walk = function SourceNode_walk(aFn) {
|
||||
var chunk;
|
||||
for (var i = 0, len = this.children.length; i < len; i++) {
|
||||
chunk = this.children[i];
|
||||
if (chunk[isSourceNode]) {
|
||||
chunk.walk(aFn);
|
||||
}
|
||||
else {
|
||||
if (chunk !== '') {
|
||||
aFn(chunk, { source: this.source,
|
||||
line: this.line,
|
||||
column: this.column,
|
||||
name: this.name });
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Like `String.prototype.join` except for SourceNodes. Inserts `aStr` between
|
||||
* each of `this.children`.
|
||||
*
|
||||
* @param aSep The separator.
|
||||
*/
|
||||
SourceNode.prototype.join = function SourceNode_join(aSep) {
|
||||
var newChildren;
|
||||
var i;
|
||||
var len = this.children.length;
|
||||
if (len > 0) {
|
||||
newChildren = [];
|
||||
for (i = 0; i < len-1; i++) {
|
||||
newChildren.push(this.children[i]);
|
||||
newChildren.push(aSep);
|
||||
}
|
||||
newChildren.push(this.children[i]);
|
||||
this.children = newChildren;
|
||||
}
|
||||
return this;
|
||||
};
|
||||
|
||||
/**
|
||||
* Call String.prototype.replace on the very right-most source snippet. Useful
|
||||
* for trimming whitespace from the end of a source node, etc.
|
||||
*
|
||||
* @param aPattern The pattern to replace.
|
||||
* @param aReplacement The thing to replace the pattern with.
|
||||
*/
|
||||
SourceNode.prototype.replaceRight = function SourceNode_replaceRight(aPattern, aReplacement) {
|
||||
var lastChild = this.children[this.children.length - 1];
|
||||
if (lastChild[isSourceNode]) {
|
||||
lastChild.replaceRight(aPattern, aReplacement);
|
||||
}
|
||||
else if (typeof lastChild === 'string') {
|
||||
this.children[this.children.length - 1] = lastChild.replace(aPattern, aReplacement);
|
||||
}
|
||||
else {
|
||||
this.children.push(''.replace(aPattern, aReplacement));
|
||||
}
|
||||
return this;
|
||||
};
|
||||
|
||||
/**
|
||||
* Set the source content for a source file. This will be added to the SourceMapGenerator
|
||||
* in the sourcesContent field.
|
||||
*
|
||||
* @param aSourceFile The filename of the source file
|
||||
* @param aSourceContent The content of the source file
|
||||
*/
|
||||
SourceNode.prototype.setSourceContent =
|
||||
function SourceNode_setSourceContent(aSourceFile, aSourceContent) {
|
||||
this.sourceContents[util.toSetString(aSourceFile)] = aSourceContent;
|
||||
};
|
||||
|
||||
/**
|
||||
* Walk over the tree of SourceNodes. The walking function is called for each
|
||||
* source file content and is passed the filename and source content.
|
||||
*
|
||||
* @param aFn The traversal function.
|
||||
*/
|
||||
SourceNode.prototype.walkSourceContents =
|
||||
function SourceNode_walkSourceContents(aFn) {
|
||||
for (var i = 0, len = this.children.length; i < len; i++) {
|
||||
if (this.children[i][isSourceNode]) {
|
||||
this.children[i].walkSourceContents(aFn);
|
||||
}
|
||||
}
|
||||
|
||||
var sources = Object.keys(this.sourceContents);
|
||||
for (var i = 0, len = sources.length; i < len; i++) {
|
||||
aFn(util.fromSetString(sources[i]), this.sourceContents[sources[i]]);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Return the string representation of this source node. Walks over the tree
|
||||
* and concatenates all the various snippets together to one string.
|
||||
*/
|
||||
SourceNode.prototype.toString = function SourceNode_toString() {
|
||||
var str = "";
|
||||
this.walk(function (chunk) {
|
||||
str += chunk;
|
||||
});
|
||||
return str;
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns the string representation of this source node along with a source
|
||||
* map.
|
||||
*/
|
||||
SourceNode.prototype.toStringWithSourceMap = function SourceNode_toStringWithSourceMap(aArgs) {
|
||||
var generated = {
|
||||
code: "",
|
||||
line: 1,
|
||||
column: 0
|
||||
};
|
||||
var map = new SourceMapGenerator(aArgs);
|
||||
var sourceMappingActive = false;
|
||||
var lastOriginalSource = null;
|
||||
var lastOriginalLine = null;
|
||||
var lastOriginalColumn = null;
|
||||
var lastOriginalName = null;
|
||||
this.walk(function (chunk, original) {
|
||||
generated.code += chunk;
|
||||
if (original.source !== null
|
||||
&& original.line !== null
|
||||
&& original.column !== null) {
|
||||
if(lastOriginalSource !== original.source
|
||||
|| lastOriginalLine !== original.line
|
||||
|| lastOriginalColumn !== original.column
|
||||
|| lastOriginalName !== original.name) {
|
||||
map.addMapping({
|
||||
source: original.source,
|
||||
original: {
|
||||
line: original.line,
|
||||
column: original.column
|
||||
},
|
||||
generated: {
|
||||
line: generated.line,
|
||||
column: generated.column
|
||||
},
|
||||
name: original.name
|
||||
});
|
||||
}
|
||||
lastOriginalSource = original.source;
|
||||
lastOriginalLine = original.line;
|
||||
lastOriginalColumn = original.column;
|
||||
lastOriginalName = original.name;
|
||||
sourceMappingActive = true;
|
||||
} else if (sourceMappingActive) {
|
||||
map.addMapping({
|
||||
generated: {
|
||||
line: generated.line,
|
||||
column: generated.column
|
||||
}
|
||||
});
|
||||
lastOriginalSource = null;
|
||||
sourceMappingActive = false;
|
||||
}
|
||||
for (var idx = 0, length = chunk.length; idx < length; idx++) {
|
||||
if (chunk.charCodeAt(idx) === NEWLINE_CODE) {
|
||||
generated.line++;
|
||||
generated.column = 0;
|
||||
// Mappings end at eol
|
||||
if (idx + 1 === length) {
|
||||
lastOriginalSource = null;
|
||||
sourceMappingActive = false;
|
||||
} else if (sourceMappingActive) {
|
||||
map.addMapping({
|
||||
source: original.source,
|
||||
original: {
|
||||
line: original.line,
|
||||
column: original.column
|
||||
},
|
||||
generated: {
|
||||
line: generated.line,
|
||||
column: generated.column
|
||||
},
|
||||
name: original.name
|
||||
});
|
||||
}
|
||||
} else {
|
||||
generated.column++;
|
||||
}
|
||||
}
|
||||
});
|
||||
this.walkSourceContents(function (sourceFile, sourceContent) {
|
||||
map.setSourceContent(sourceFile, sourceContent);
|
||||
});
|
||||
|
||||
return { code: generated.code, map: map };
|
||||
};
|
||||
|
||||
exports.SourceNode = SourceNode;
|
||||
417
node_modules/csso/node_modules/source-map/lib/util.js
generated
vendored
417
node_modules/csso/node_modules/source-map/lib/util.js
generated
vendored
@@ -1,417 +0,0 @@
|
||||
/* -*- Mode: js; js-indent-level: 2; -*- */
|
||||
/*
|
||||
* Copyright 2011 Mozilla Foundation and contributors
|
||||
* Licensed under the New BSD license. See LICENSE or:
|
||||
* http://opensource.org/licenses/BSD-3-Clause
|
||||
*/
|
||||
|
||||
/**
|
||||
* This is a helper function for getting values from parameter/options
|
||||
* objects.
|
||||
*
|
||||
* @param args The object we are extracting values from
|
||||
* @param name The name of the property we are getting.
|
||||
* @param defaultValue An optional value to return if the property is missing
|
||||
* from the object. If this is not specified and the property is missing, an
|
||||
* error will be thrown.
|
||||
*/
|
||||
function getArg(aArgs, aName, aDefaultValue) {
|
||||
if (aName in aArgs) {
|
||||
return aArgs[aName];
|
||||
} else if (arguments.length === 3) {
|
||||
return aDefaultValue;
|
||||
} else {
|
||||
throw new Error('"' + aName + '" is a required argument.');
|
||||
}
|
||||
}
|
||||
exports.getArg = getArg;
|
||||
|
||||
var urlRegexp = /^(?:([\w+\-.]+):)?\/\/(?:(\w+:\w+)@)?([\w.]*)(?::(\d+))?(\S*)$/;
|
||||
var dataUrlRegexp = /^data:.+\,.+$/;
|
||||
|
||||
function urlParse(aUrl) {
|
||||
var match = aUrl.match(urlRegexp);
|
||||
if (!match) {
|
||||
return null;
|
||||
}
|
||||
return {
|
||||
scheme: match[1],
|
||||
auth: match[2],
|
||||
host: match[3],
|
||||
port: match[4],
|
||||
path: match[5]
|
||||
};
|
||||
}
|
||||
exports.urlParse = urlParse;
|
||||
|
||||
function urlGenerate(aParsedUrl) {
|
||||
var url = '';
|
||||
if (aParsedUrl.scheme) {
|
||||
url += aParsedUrl.scheme + ':';
|
||||
}
|
||||
url += '//';
|
||||
if (aParsedUrl.auth) {
|
||||
url += aParsedUrl.auth + '@';
|
||||
}
|
||||
if (aParsedUrl.host) {
|
||||
url += aParsedUrl.host;
|
||||
}
|
||||
if (aParsedUrl.port) {
|
||||
url += ":" + aParsedUrl.port
|
||||
}
|
||||
if (aParsedUrl.path) {
|
||||
url += aParsedUrl.path;
|
||||
}
|
||||
return url;
|
||||
}
|
||||
exports.urlGenerate = urlGenerate;
|
||||
|
||||
/**
|
||||
* Normalizes a path, or the path portion of a URL:
|
||||
*
|
||||
* - Replaces consecutive slashes with one slash.
|
||||
* - Removes unnecessary '.' parts.
|
||||
* - Removes unnecessary '<dir>/..' parts.
|
||||
*
|
||||
* Based on code in the Node.js 'path' core module.
|
||||
*
|
||||
* @param aPath The path or url to normalize.
|
||||
*/
|
||||
function normalize(aPath) {
|
||||
var path = aPath;
|
||||
var url = urlParse(aPath);
|
||||
if (url) {
|
||||
if (!url.path) {
|
||||
return aPath;
|
||||
}
|
||||
path = url.path;
|
||||
}
|
||||
var isAbsolute = exports.isAbsolute(path);
|
||||
|
||||
var parts = path.split(/\/+/);
|
||||
for (var part, up = 0, i = parts.length - 1; i >= 0; i--) {
|
||||
part = parts[i];
|
||||
if (part === '.') {
|
||||
parts.splice(i, 1);
|
||||
} else if (part === '..') {
|
||||
up++;
|
||||
} else if (up > 0) {
|
||||
if (part === '') {
|
||||
// The first part is blank if the path is absolute. Trying to go
|
||||
// above the root is a no-op. Therefore we can remove all '..' parts
|
||||
// directly after the root.
|
||||
parts.splice(i + 1, up);
|
||||
up = 0;
|
||||
} else {
|
||||
parts.splice(i, 2);
|
||||
up--;
|
||||
}
|
||||
}
|
||||
}
|
||||
path = parts.join('/');
|
||||
|
||||
if (path === '') {
|
||||
path = isAbsolute ? '/' : '.';
|
||||
}
|
||||
|
||||
if (url) {
|
||||
url.path = path;
|
||||
return urlGenerate(url);
|
||||
}
|
||||
return path;
|
||||
}
|
||||
exports.normalize = normalize;
|
||||
|
||||
/**
|
||||
* Joins two paths/URLs.
|
||||
*
|
||||
* @param aRoot The root path or URL.
|
||||
* @param aPath The path or URL to be joined with the root.
|
||||
*
|
||||
* - If aPath is a URL or a data URI, aPath is returned, unless aPath is a
|
||||
* scheme-relative URL: Then the scheme of aRoot, if any, is prepended
|
||||
* first.
|
||||
* - Otherwise aPath is a path. If aRoot is a URL, then its path portion
|
||||
* is updated with the result and aRoot is returned. Otherwise the result
|
||||
* is returned.
|
||||
* - If aPath is absolute, the result is aPath.
|
||||
* - Otherwise the two paths are joined with a slash.
|
||||
* - Joining for example 'http://' and 'www.example.com' is also supported.
|
||||
*/
|
||||
function join(aRoot, aPath) {
|
||||
if (aRoot === "") {
|
||||
aRoot = ".";
|
||||
}
|
||||
if (aPath === "") {
|
||||
aPath = ".";
|
||||
}
|
||||
var aPathUrl = urlParse(aPath);
|
||||
var aRootUrl = urlParse(aRoot);
|
||||
if (aRootUrl) {
|
||||
aRoot = aRootUrl.path || '/';
|
||||
}
|
||||
|
||||
// `join(foo, '//www.example.org')`
|
||||
if (aPathUrl && !aPathUrl.scheme) {
|
||||
if (aRootUrl) {
|
||||
aPathUrl.scheme = aRootUrl.scheme;
|
||||
}
|
||||
return urlGenerate(aPathUrl);
|
||||
}
|
||||
|
||||
if (aPathUrl || aPath.match(dataUrlRegexp)) {
|
||||
return aPath;
|
||||
}
|
||||
|
||||
// `join('http://', 'www.example.com')`
|
||||
if (aRootUrl && !aRootUrl.host && !aRootUrl.path) {
|
||||
aRootUrl.host = aPath;
|
||||
return urlGenerate(aRootUrl);
|
||||
}
|
||||
|
||||
var joined = aPath.charAt(0) === '/'
|
||||
? aPath
|
||||
: normalize(aRoot.replace(/\/+$/, '') + '/' + aPath);
|
||||
|
||||
if (aRootUrl) {
|
||||
aRootUrl.path = joined;
|
||||
return urlGenerate(aRootUrl);
|
||||
}
|
||||
return joined;
|
||||
}
|
||||
exports.join = join;
|
||||
|
||||
exports.isAbsolute = function (aPath) {
|
||||
return aPath.charAt(0) === '/' || !!aPath.match(urlRegexp);
|
||||
};
|
||||
|
||||
/**
|
||||
* Make a path relative to a URL or another path.
|
||||
*
|
||||
* @param aRoot The root path or URL.
|
||||
* @param aPath The path or URL to be made relative to aRoot.
|
||||
*/
|
||||
function relative(aRoot, aPath) {
|
||||
if (aRoot === "") {
|
||||
aRoot = ".";
|
||||
}
|
||||
|
||||
aRoot = aRoot.replace(/\/$/, '');
|
||||
|
||||
// It is possible for the path to be above the root. In this case, simply
|
||||
// checking whether the root is a prefix of the path won't work. Instead, we
|
||||
// need to remove components from the root one by one, until either we find
|
||||
// a prefix that fits, or we run out of components to remove.
|
||||
var level = 0;
|
||||
while (aPath.indexOf(aRoot + '/') !== 0) {
|
||||
var index = aRoot.lastIndexOf("/");
|
||||
if (index < 0) {
|
||||
return aPath;
|
||||
}
|
||||
|
||||
// If the only part of the root that is left is the scheme (i.e. http://,
|
||||
// file:///, etc.), one or more slashes (/), or simply nothing at all, we
|
||||
// have exhausted all components, so the path is not relative to the root.
|
||||
aRoot = aRoot.slice(0, index);
|
||||
if (aRoot.match(/^([^\/]+:\/)?\/*$/)) {
|
||||
return aPath;
|
||||
}
|
||||
|
||||
++level;
|
||||
}
|
||||
|
||||
// Make sure we add a "../" for each component we removed from the root.
|
||||
return Array(level + 1).join("../") + aPath.substr(aRoot.length + 1);
|
||||
}
|
||||
exports.relative = relative;
|
||||
|
||||
var supportsNullProto = (function () {
|
||||
var obj = Object.create(null);
|
||||
return !('__proto__' in obj);
|
||||
}());
|
||||
|
||||
function identity (s) {
|
||||
return s;
|
||||
}
|
||||
|
||||
/**
|
||||
* Because behavior goes wacky when you set `__proto__` on objects, we
|
||||
* have to prefix all the strings in our set with an arbitrary character.
|
||||
*
|
||||
* See https://github.com/mozilla/source-map/pull/31 and
|
||||
* https://github.com/mozilla/source-map/issues/30
|
||||
*
|
||||
* @param String aStr
|
||||
*/
|
||||
function toSetString(aStr) {
|
||||
if (isProtoString(aStr)) {
|
||||
return '$' + aStr;
|
||||
}
|
||||
|
||||
return aStr;
|
||||
}
|
||||
exports.toSetString = supportsNullProto ? identity : toSetString;
|
||||
|
||||
function fromSetString(aStr) {
|
||||
if (isProtoString(aStr)) {
|
||||
return aStr.slice(1);
|
||||
}
|
||||
|
||||
return aStr;
|
||||
}
|
||||
exports.fromSetString = supportsNullProto ? identity : fromSetString;
|
||||
|
||||
function isProtoString(s) {
|
||||
if (!s) {
|
||||
return false;
|
||||
}
|
||||
|
||||
var length = s.length;
|
||||
|
||||
if (length < 9 /* "__proto__".length */) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (s.charCodeAt(length - 1) !== 95 /* '_' */ ||
|
||||
s.charCodeAt(length - 2) !== 95 /* '_' */ ||
|
||||
s.charCodeAt(length - 3) !== 111 /* 'o' */ ||
|
||||
s.charCodeAt(length - 4) !== 116 /* 't' */ ||
|
||||
s.charCodeAt(length - 5) !== 111 /* 'o' */ ||
|
||||
s.charCodeAt(length - 6) !== 114 /* 'r' */ ||
|
||||
s.charCodeAt(length - 7) !== 112 /* 'p' */ ||
|
||||
s.charCodeAt(length - 8) !== 95 /* '_' */ ||
|
||||
s.charCodeAt(length - 9) !== 95 /* '_' */) {
|
||||
return false;
|
||||
}
|
||||
|
||||
for (var i = length - 10; i >= 0; i--) {
|
||||
if (s.charCodeAt(i) !== 36 /* '$' */) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Comparator between two mappings where the original positions are compared.
|
||||
*
|
||||
* Optionally pass in `true` as `onlyCompareGenerated` to consider two
|
||||
* mappings with the same original source/line/column, but different generated
|
||||
* line and column the same. Useful when searching for a mapping with a
|
||||
* stubbed out mapping.
|
||||
*/
|
||||
function compareByOriginalPositions(mappingA, mappingB, onlyCompareOriginal) {
|
||||
var cmp = mappingA.source - mappingB.source;
|
||||
if (cmp !== 0) {
|
||||
return cmp;
|
||||
}
|
||||
|
||||
cmp = mappingA.originalLine - mappingB.originalLine;
|
||||
if (cmp !== 0) {
|
||||
return cmp;
|
||||
}
|
||||
|
||||
cmp = mappingA.originalColumn - mappingB.originalColumn;
|
||||
if (cmp !== 0 || onlyCompareOriginal) {
|
||||
return cmp;
|
||||
}
|
||||
|
||||
cmp = mappingA.generatedColumn - mappingB.generatedColumn;
|
||||
if (cmp !== 0) {
|
||||
return cmp;
|
||||
}
|
||||
|
||||
cmp = mappingA.generatedLine - mappingB.generatedLine;
|
||||
if (cmp !== 0) {
|
||||
return cmp;
|
||||
}
|
||||
|
||||
return mappingA.name - mappingB.name;
|
||||
}
|
||||
exports.compareByOriginalPositions = compareByOriginalPositions;
|
||||
|
||||
/**
|
||||
* Comparator between two mappings with deflated source and name indices where
|
||||
* the generated positions are compared.
|
||||
*
|
||||
* Optionally pass in `true` as `onlyCompareGenerated` to consider two
|
||||
* mappings with the same generated line and column, but different
|
||||
* source/name/original line and column the same. Useful when searching for a
|
||||
* mapping with a stubbed out mapping.
|
||||
*/
|
||||
function compareByGeneratedPositionsDeflated(mappingA, mappingB, onlyCompareGenerated) {
|
||||
var cmp = mappingA.generatedLine - mappingB.generatedLine;
|
||||
if (cmp !== 0) {
|
||||
return cmp;
|
||||
}
|
||||
|
||||
cmp = mappingA.generatedColumn - mappingB.generatedColumn;
|
||||
if (cmp !== 0 || onlyCompareGenerated) {
|
||||
return cmp;
|
||||
}
|
||||
|
||||
cmp = mappingA.source - mappingB.source;
|
||||
if (cmp !== 0) {
|
||||
return cmp;
|
||||
}
|
||||
|
||||
cmp = mappingA.originalLine - mappingB.originalLine;
|
||||
if (cmp !== 0) {
|
||||
return cmp;
|
||||
}
|
||||
|
||||
cmp = mappingA.originalColumn - mappingB.originalColumn;
|
||||
if (cmp !== 0) {
|
||||
return cmp;
|
||||
}
|
||||
|
||||
return mappingA.name - mappingB.name;
|
||||
}
|
||||
exports.compareByGeneratedPositionsDeflated = compareByGeneratedPositionsDeflated;
|
||||
|
||||
function strcmp(aStr1, aStr2) {
|
||||
if (aStr1 === aStr2) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (aStr1 > aStr2) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Comparator between two mappings with inflated source and name strings where
|
||||
* the generated positions are compared.
|
||||
*/
|
||||
function compareByGeneratedPositionsInflated(mappingA, mappingB) {
|
||||
var cmp = mappingA.generatedLine - mappingB.generatedLine;
|
||||
if (cmp !== 0) {
|
||||
return cmp;
|
||||
}
|
||||
|
||||
cmp = mappingA.generatedColumn - mappingB.generatedColumn;
|
||||
if (cmp !== 0) {
|
||||
return cmp;
|
||||
}
|
||||
|
||||
cmp = strcmp(mappingA.source, mappingB.source);
|
||||
if (cmp !== 0) {
|
||||
return cmp;
|
||||
}
|
||||
|
||||
cmp = mappingA.originalLine - mappingB.originalLine;
|
||||
if (cmp !== 0) {
|
||||
return cmp;
|
||||
}
|
||||
|
||||
cmp = mappingA.originalColumn - mappingB.originalColumn;
|
||||
if (cmp !== 0) {
|
||||
return cmp;
|
||||
}
|
||||
|
||||
return strcmp(mappingA.name, mappingB.name);
|
||||
}
|
||||
exports.compareByGeneratedPositionsInflated = compareByGeneratedPositionsInflated;
|
||||
211
node_modules/csso/node_modules/source-map/package.json
generated
vendored
211
node_modules/csso/node_modules/source-map/package.json
generated
vendored
@@ -1,211 +0,0 @@
|
||||
{
|
||||
"_from": "source-map@^0.5.3",
|
||||
"_id": "source-map@0.5.7",
|
||||
"_inBundle": false,
|
||||
"_integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=",
|
||||
"_location": "/csso/source-map",
|
||||
"_phantomChildren": {},
|
||||
"_requested": {
|
||||
"type": "range",
|
||||
"registry": true,
|
||||
"raw": "source-map@^0.5.3",
|
||||
"name": "source-map",
|
||||
"escapedName": "source-map",
|
||||
"rawSpec": "^0.5.3",
|
||||
"saveSpec": null,
|
||||
"fetchSpec": "^0.5.3"
|
||||
},
|
||||
"_requiredBy": [
|
||||
"/csso"
|
||||
],
|
||||
"_resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz",
|
||||
"_shasum": "8a039d2d1021d22d1ea14c80d8ea468ba2ef3fcc",
|
||||
"_spec": "source-map@^0.5.3",
|
||||
"_where": "C:\\xampp\\htdocs\\w4rpservices\\node_modules\\csso",
|
||||
"author": {
|
||||
"name": "Nick Fitzgerald",
|
||||
"email": "nfitzgerald@mozilla.com"
|
||||
},
|
||||
"bugs": {
|
||||
"url": "https://github.com/mozilla/source-map/issues"
|
||||
},
|
||||
"bundleDependencies": false,
|
||||
"contributors": [
|
||||
{
|
||||
"name": "Tobias Koppers",
|
||||
"email": "tobias.koppers@googlemail.com"
|
||||
},
|
||||
{
|
||||
"name": "Duncan Beevers",
|
||||
"email": "duncan@dweebd.com"
|
||||
},
|
||||
{
|
||||
"name": "Stephen Crane",
|
||||
"email": "scrane@mozilla.com"
|
||||
},
|
||||
{
|
||||
"name": "Ryan Seddon",
|
||||
"email": "seddon.ryan@gmail.com"
|
||||
},
|
||||
{
|
||||
"name": "Miles Elam",
|
||||
"email": "miles.elam@deem.com"
|
||||
},
|
||||
{
|
||||
"name": "Mihai Bazon",
|
||||
"email": "mihai.bazon@gmail.com"
|
||||
},
|
||||
{
|
||||
"name": "Michael Ficarra",
|
||||
"email": "github.public.email@michael.ficarra.me"
|
||||
},
|
||||
{
|
||||
"name": "Todd Wolfson",
|
||||
"email": "todd@twolfson.com"
|
||||
},
|
||||
{
|
||||
"name": "Alexander Solovyov",
|
||||
"email": "alexander@solovyov.net"
|
||||
},
|
||||
{
|
||||
"name": "Felix Gnass",
|
||||
"email": "fgnass@gmail.com"
|
||||
},
|
||||
{
|
||||
"name": "Conrad Irwin",
|
||||
"email": "conrad.irwin@gmail.com"
|
||||
},
|
||||
{
|
||||
"name": "usrbincc",
|
||||
"email": "usrbincc@yahoo.com"
|
||||
},
|
||||
{
|
||||
"name": "David Glasser",
|
||||
"email": "glasser@davidglasser.net"
|
||||
},
|
||||
{
|
||||
"name": "Chase Douglas",
|
||||
"email": "chase@newrelic.com"
|
||||
},
|
||||
{
|
||||
"name": "Evan Wallace",
|
||||
"email": "evan.exe@gmail.com"
|
||||
},
|
||||
{
|
||||
"name": "Heather Arthur",
|
||||
"email": "fayearthur@gmail.com"
|
||||
},
|
||||
{
|
||||
"name": "Hugh Kennedy",
|
||||
"email": "hughskennedy@gmail.com"
|
||||
},
|
||||
{
|
||||
"name": "David Glasser",
|
||||
"email": "glasser@davidglasser.net"
|
||||
},
|
||||
{
|
||||
"name": "Simon Lydell",
|
||||
"email": "simon.lydell@gmail.com"
|
||||
},
|
||||
{
|
||||
"name": "Jmeas Smith",
|
||||
"email": "jellyes2@gmail.com"
|
||||
},
|
||||
{
|
||||
"name": "Michael Z Goddard",
|
||||
"email": "mzgoddard@gmail.com"
|
||||
},
|
||||
{
|
||||
"name": "azu",
|
||||
"email": "azu@users.noreply.github.com"
|
||||
},
|
||||
{
|
||||
"name": "John Gozde",
|
||||
"email": "john@gozde.ca"
|
||||
},
|
||||
{
|
||||
"name": "Adam Kirkton",
|
||||
"email": "akirkton@truefitinnovation.com"
|
||||
},
|
||||
{
|
||||
"name": "Chris Montgomery",
|
||||
"email": "christopher.montgomery@dowjones.com"
|
||||
},
|
||||
{
|
||||
"name": "J. Ryan Stinnett",
|
||||
"email": "jryans@gmail.com"
|
||||
},
|
||||
{
|
||||
"name": "Jack Herrington",
|
||||
"email": "jherrington@walmartlabs.com"
|
||||
},
|
||||
{
|
||||
"name": "Chris Truter",
|
||||
"email": "jeffpalentine@gmail.com"
|
||||
},
|
||||
{
|
||||
"name": "Daniel Espeset",
|
||||
"email": "daniel@danielespeset.com"
|
||||
},
|
||||
{
|
||||
"name": "Jamie Wong",
|
||||
"email": "jamie.lf.wong@gmail.com"
|
||||
},
|
||||
{
|
||||
"name": "Eddy Bruël",
|
||||
"email": "ejpbruel@mozilla.com"
|
||||
},
|
||||
{
|
||||
"name": "Hawken Rives",
|
||||
"email": "hawkrives@gmail.com"
|
||||
},
|
||||
{
|
||||
"name": "Gilad Peleg",
|
||||
"email": "giladp007@gmail.com"
|
||||
},
|
||||
{
|
||||
"name": "djchie",
|
||||
"email": "djchie.dev@gmail.com"
|
||||
},
|
||||
{
|
||||
"name": "Gary Ye",
|
||||
"email": "garysye@gmail.com"
|
||||
},
|
||||
{
|
||||
"name": "Nicolas Lalevée",
|
||||
"email": "nicolas.lalevee@hibnet.org"
|
||||
}
|
||||
],
|
||||
"deprecated": false,
|
||||
"description": "Generates and consumes source maps",
|
||||
"devDependencies": {
|
||||
"doctoc": "^0.15.0",
|
||||
"webpack": "^1.12.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
},
|
||||
"files": [
|
||||
"source-map.js",
|
||||
"lib/",
|
||||
"dist/source-map.debug.js",
|
||||
"dist/source-map.js",
|
||||
"dist/source-map.min.js",
|
||||
"dist/source-map.min.js.map"
|
||||
],
|
||||
"homepage": "https://github.com/mozilla/source-map",
|
||||
"license": "BSD-3-Clause",
|
||||
"main": "./source-map.js",
|
||||
"name": "source-map",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+ssh://git@github.com/mozilla/source-map.git"
|
||||
},
|
||||
"scripts": {
|
||||
"build": "webpack --color",
|
||||
"test": "npm run build && node test/run-tests.js",
|
||||
"toc": "doctoc --title '## Table of Contents' README.md && doctoc --title '## Table of Contents' CONTRIBUTING.md"
|
||||
},
|
||||
"typings": "source-map",
|
||||
"version": "0.5.7"
|
||||
}
|
||||
8
node_modules/csso/node_modules/source-map/source-map.js
generated
vendored
8
node_modules/csso/node_modules/source-map/source-map.js
generated
vendored
@@ -1,8 +0,0 @@
|
||||
/*
|
||||
* Copyright 2009-2011 Mozilla Foundation and contributors
|
||||
* Licensed under the New BSD license. See LICENSE.txt or:
|
||||
* http://opensource.org/licenses/BSD-3-Clause
|
||||
*/
|
||||
exports.SourceMapGenerator = require('./lib/source-map-generator').SourceMapGenerator;
|
||||
exports.SourceMapConsumer = require('./lib/source-map-consumer').SourceMapConsumer;
|
||||
exports.SourceNode = require('./lib/source-node').SourceNode;
|
||||
53
node_modules/csso/package.json
generated
vendored
53
node_modules/csso/package.json
generated
vendored
@@ -1,52 +1,53 @@
|
||||
{
|
||||
"_from": "csso@~2.3.1",
|
||||
"_id": "csso@2.3.2",
|
||||
"_from": "csso@^3.5.1",
|
||||
"_id": "csso@3.5.1",
|
||||
"_inBundle": false,
|
||||
"_integrity": "sha1-3dUsWHAz9J6Utx/FVWnyUuj/X4U=",
|
||||
"_integrity": "sha512-vrqULLffYU1Q2tLdJvaCYbONStnfkfimRxXNaGjxMldI0C7JPBC4rB1RyjhfdZ4m1frm8pM9uRPKH3d2knZ8gg==",
|
||||
"_location": "/csso",
|
||||
"_phantomChildren": {},
|
||||
"_phantomChildren": {
|
||||
"mdn-data": "1.1.4",
|
||||
"source-map": "0.5.7"
|
||||
},
|
||||
"_requested": {
|
||||
"type": "range",
|
||||
"registry": true,
|
||||
"raw": "csso@~2.3.1",
|
||||
"raw": "csso@^3.5.1",
|
||||
"name": "csso",
|
||||
"escapedName": "csso",
|
||||
"rawSpec": "~2.3.1",
|
||||
"rawSpec": "^3.5.1",
|
||||
"saveSpec": null,
|
||||
"fetchSpec": "~2.3.1"
|
||||
"fetchSpec": "^3.5.1"
|
||||
},
|
||||
"_requiredBy": [
|
||||
"/svgo"
|
||||
],
|
||||
"_resolved": "https://registry.npmjs.org/csso/-/csso-2.3.2.tgz",
|
||||
"_shasum": "ddd52c587033f49e94b71fc55569f252e8ff5f85",
|
||||
"_spec": "csso@~2.3.1",
|
||||
"_resolved": "https://registry.npmjs.org/csso/-/csso-3.5.1.tgz",
|
||||
"_shasum": "7b9eb8be61628973c1b261e169d2f024008e758b",
|
||||
"_spec": "csso@^3.5.1",
|
||||
"_where": "C:\\xampp\\htdocs\\w4rpservices\\node_modules\\svgo",
|
||||
"author": {
|
||||
"name": "Sergey Kryzhanovsky",
|
||||
"email": "skryzhanovsky@ya.ru",
|
||||
"url": "https://github.com/afelix"
|
||||
},
|
||||
"bin": {
|
||||
"csso": "./bin/csso"
|
||||
},
|
||||
"bugs": {
|
||||
"url": "https://github.com/css/csso/issues"
|
||||
},
|
||||
"bundleDependencies": false,
|
||||
"dependencies": {
|
||||
"clap": "^1.0.9",
|
||||
"source-map": "^0.5.3"
|
||||
"css-tree": "1.0.0-alpha.29"
|
||||
},
|
||||
"deprecated": false,
|
||||
"description": "CSSO (CSS Optimizer) is a CSS minifier with structural optimisations",
|
||||
"description": "CSS minifier with structural optimisations",
|
||||
"devDependencies": {
|
||||
"browserify": "^13.0.0",
|
||||
"coveralls": "^2.11.6",
|
||||
"eslint": "^2.2.0",
|
||||
"istanbul": "^0.4.2",
|
||||
"jscs": "~2.10.0",
|
||||
"mocha": "~2.4.2",
|
||||
"jscs": "~3.0.7",
|
||||
"mocha": "^3.5.3",
|
||||
"package-json-versionify": "^1.0.4",
|
||||
"source-map": "^0.5.6",
|
||||
"uglify-js": "^2.6.1"
|
||||
},
|
||||
"engines": {
|
||||
@@ -71,7 +72,6 @@
|
||||
}
|
||||
},
|
||||
"files": [
|
||||
"bin",
|
||||
"dist/csso-browser.js",
|
||||
"lib",
|
||||
"HISTORY.md",
|
||||
@@ -81,10 +81,12 @@
|
||||
"homepage": "https://github.com/css/csso",
|
||||
"keywords": [
|
||||
"css",
|
||||
"compress",
|
||||
"minifier",
|
||||
"minify",
|
||||
"compress",
|
||||
"optimisation"
|
||||
"optimise",
|
||||
"optimisation",
|
||||
"csstree"
|
||||
],
|
||||
"license": "MIT",
|
||||
"main": "./lib/index",
|
||||
@@ -100,16 +102,17 @@
|
||||
"url": "git+https://github.com/css/csso.git"
|
||||
},
|
||||
"scripts": {
|
||||
"browserify": "browserify --standalone csso lib/index.js | uglifyjs --compress --mangle -o dist/csso-browser.js",
|
||||
"codestyle": "jscs lib && eslint lib test",
|
||||
"browserify": "browserify -t package-json-versionify --standalone csso lib/index.js | uglifyjs --compress --mangle -o dist/csso-browser.js",
|
||||
"codestyle": "jscs lib test && eslint lib test",
|
||||
"codestyle-and-test": "npm run codestyle && npm test",
|
||||
"coverage": "istanbul cover _mocha -- -R dot",
|
||||
"coveralls": "istanbul cover _mocha --report lcovonly -- -R dot && cat ./coverage/lcov.info | coveralls",
|
||||
"gh-pages": "git clone -b gh-pages https://github.com/css/csso.git .gh-pages && npm run browserify && cp dist/csso-browser.js .gh-pages/ && cd .gh-pages && git commit -am \"update\" && git push && cd .. && rm -rf .gh-pages",
|
||||
"gh-pages": "git clone --depth=1 -b gh-pages https://github.com/css/csso.git .gh-pages && npm run browserify && cp dist/csso-browser.js .gh-pages/ && cd .gh-pages && git commit -am \"update\" && git push && cd .. && rm -rf .gh-pages",
|
||||
"hydrogen": "node --trace-hydrogen --trace-phase=Z --trace-deopt --code-comments --hydrogen-track-positions --redirect-code-traces --redirect-code-traces-to=code.asm --trace_hydrogen_file=code.cfg --print-opt-code bin/csso --stat -o /dev/null",
|
||||
"postpublish": "npm run gh-pages",
|
||||
"prepublish": "npm run browserify",
|
||||
"test": "mocha --reporter dot",
|
||||
"travis": "npm run codestyle-and-test && npm run coveralls"
|
||||
},
|
||||
"version": "2.3.2"
|
||||
"version": "3.5.1"
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user