This commit is contained in:
sentsin
2017-08-21 08:50:25 +08:00
parent 06c11ba9cd
commit 7feaa4eca0
1899 changed files with 181363 additions and 22513 deletions

1113
node_modules/clean-css/History.md generated vendored Normal file

File diff suppressed because it is too large Load Diff

19
node_modules/clean-css/LICENSE generated vendored Normal file
View File

@@ -0,0 +1,19 @@
Copyright (C) 2015 JakubPawlowicz.com
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is furnished
to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.

369
node_modules/clean-css/README.md generated vendored Normal file
View File

@@ -0,0 +1,369 @@
[![NPM version](https://img.shields.io/npm/v/clean-css.svg?style=flat)](https://www.npmjs.com/package/clean-css)
[![Linux Build Status](https://img.shields.io/travis/jakubpawlowicz/clean-css/master.svg?style=flat&label=Linux%20build)](https://travis-ci.org/jakubpawlowicz/clean-css)
[![Windows Build status](https://img.shields.io/appveyor/ci/jakubpawlowicz/clean-css/master.svg?style=flat&label=Windows%20build)](https://ci.appveyor.com/project/jakubpawlowicz/clean-css/branch/master)
[![Dependency Status](https://img.shields.io/david/jakubpawlowicz/clean-css.svg?style=flat)](https://david-dm.org/jakubpawlowicz/clean-css)
[![devDependency Status](https://img.shields.io/david/dev/jakubpawlowicz/clean-css.svg?style=flat)](https://david-dm.org/jakubpawlowicz/clean-css#info=devDependencies)
## What is clean-css?
Clean-css is a fast and efficient [Node.js](http://nodejs.org/) library for minifying CSS files.
According to [tests](http://goalsmashers.github.io/css-minification-benchmark/) it is one of the best available.
## Usage
### What are the requirements?
```
Node.js 0.10+ (tested on CentOS, Ubuntu, OS X 10.6+, and Windows 7+) or io.js 3.0+
```
### How to install clean-css?
```
npm install clean-css
```
### How to use clean-css CLI?
Clean-css accepts the following command line arguments (please make sure
you use `<source-file>` as the very last argument to avoid potential issues):
```
cleancss [options] source-file, [source-file, ...]
-h, --help output usage information
-v, --version output the version number
-b, --keep-line-breaks Keep line breaks
-c, --compatibility [ie7|ie8] Force compatibility mode (see Readme for advanced examples)
-d, --debug Shows debug information (minification time & compression efficiency)
-o, --output [output-file] Use [output-file] as output instead of STDOUT
-r, --root [root-path] Set a root path to which resolve absolute @import rules
-s, --skip-import Disable @import processing
-t, --timeout [seconds] Per connection timeout when fetching remote @imports (defaults to 5 seconds)
--rounding-precision [n] Rounds to `N` decimal places. Defaults to 2. -1 disables rounding
--s0 Remove all special comments, i.e. /*! comment */
--s1 Remove all special comments but the first one
--semantic-merging Enables unsafe mode by assuming BEM-like semantic stylesheets (warning, this may break your styling!)
--skip-advanced Disable advanced optimizations - ruleset reordering & merging
--skip-aggressive-merging Disable properties merging based on their order
--skip-import-from [rules] Disable @import processing for specified rules
--skip-media-merging Disable @media merging
--skip-rebase Disable URLs rebasing
--skip-restructuring Disable restructuring optimizations
--skip-shorthand-compacting Disable shorthand compacting
--source-map Enables building input's source map
--source-map-inline-sources Enables inlining sources inside source maps
```
#### Examples:
To minify a **public.css** file into **public-min.css** do:
```
cleancss -o public-min.css public.css
```
To minify the same **public.css** into the standard output skip the `-o` parameter:
```
cleancss public.css
```
More likely you would like to concatenate a couple of files.
If you are on a Unix-like system:
```bash
cat one.css two.css three.css | cleancss -o merged-and-minified.css
```
On Windows:
```bat
type one.css two.css three.css | cleancss -o merged-and-minified.css
```
Or even gzip the result at once:
```bash
cat one.css two.css three.css | cleancss | gzip -9 -c > merged-minified-and-gzipped.css.gz
```
### How to use clean-css API?
```js
var CleanCSS = require('clean-css');
var source = 'a{font-weight:bold;}';
var minified = new CleanCSS().minify(source).styles;
```
CleanCSS constructor accepts a hash as a parameter, i.e.,
`new CleanCSS(options)` with the following options available:
* `advanced` - set to false to disable advanced optimizations - selector & property merging, reduction, etc.
* `aggressiveMerging` - set to false to disable aggressive merging of properties.
* `benchmark` - turns on benchmarking mode measuring time spent on cleaning up (run `npm run bench` to see example)
* `compatibility` - enables compatibility mode, see [below for more examples](#how-to-set-a-compatibility-mode)
* `debug` - set to true to get minification statistics under `stats` property (see `test/custom-test.js` for examples)
* `inliner` - a hash of options for `@import` inliner, see [test/protocol-imports-test.js](https://github.com/jakubpawlowicz/clean-css/blob/master/test/protocol-imports-test.js#L372) for examples, or [this comment](https://github.com/jakubpawlowicz/clean-css/issues/612#issuecomment-119594185) for a proxy use case.
* `keepBreaks` - whether to keep line breaks (default is false)
* `keepSpecialComments` - `*` for keeping all (default), `1` for keeping first one only, `0` for removing all
* `mediaMerging` - whether to merge `@media` at-rules (default is true)
* `processImport` - whether to process `@import` rules
* `processImportFrom` - a list of `@import` rules, can be `['all']` (default), `['local']`, `['remote']`, or a blacklisted path e.g. `['!fonts.googleapis.com']`
* `rebase` - set to false to skip URL rebasing
* `relativeTo` - path to **resolve** relative `@import` rules and URLs
* `restructuring` - set to false to disable restructuring in advanced optimizations
* `root` - path to **resolve** absolute `@import` rules and **rebase** relative URLs
* `roundingPrecision` - rounding precision; defaults to `2`; `-1` disables rounding
* `semanticMerging` - set to true to enable semantic merging mode which assumes BEM-like content (default is false as it's highly likely this will break your stylesheets - **use with caution**!)
* `shorthandCompacting` - set to false to skip shorthand compacting (default is true unless sourceMap is set when it's false)
* `sourceMap` - exposes source map under `sourceMap` property, e.g. `new CleanCSS().minify(source).sourceMap` (default is false)
If input styles are a product of CSS preprocessor (Less, Sass) an input source map can be passed as a string.
* `sourceMapInlineSources` - set to true to inline sources inside a source map's `sourcesContent` field (defaults to false)
It is also required to process inlined sources from input source maps.
* `target` - path to a folder or an output file to which **rebase** all URLs
The output of `minify` method (or the 2nd argument to passed callback) is a hash containing the following fields:
* `styles` - optimized output CSS as a string
* `sourceMap` - output source map (if requested with `sourceMap` option)
* `errors` - a list of errors raised
* `warnings` - a list of warnings raised
* `stats` - a hash of statistic information (if requested with `debug` option):
* `originalSize` - original content size (after import inlining)
* `minifiedSize` - optimized content size
* `timeSpent` - time spent on optimizations
* `efficiency` - a ratio of output size to input size (e.g. 25% if content was reduced from 100 bytes to 75 bytes)
#### How to make sure remote `@import`s are processed correctly?
In order to inline remote `@import` statements you need to provide a callback to minify method, e.g.:
```js
var CleanCSS = require('clean-css');
var source = '@import url(http://path/to/remote/styles);';
new CleanCSS().minify(source, function (errors, minified) {
// minified.styles
});
```
This is due to a fact, that, while local files can be read synchronously, remote resources can only be processed asynchronously.
If you don't provide a callback, then remote `@import`s will be left intact.
### How to use clean-css with build tools?
* [Broccoli](https://github.com/broccolijs/broccoli#broccoli): [broccoli-clean-css](https://github.com/shinnn/broccoli-clean-css)
* [Brunch](http://brunch.io/): [clean-css-brunch](https://github.com/brunch/clean-css-brunch)
* [Grunt](http://gruntjs.com): [grunt-contrib-cssmin](https://github.com/gruntjs/grunt-contrib-cssmin)
* [Gulp](http://gulpjs.com/): [gulp-minify-css](https://github.com/jonathanepollack/gulp-minify-css)
* [Gulp](http://gulpjs.com/): [using vinyl-map as a wrapper - courtesy of @sogko](https://github.com/jakubpawlowicz/clean-css/issues/342)
* [component-builder2](https://github.com/component/builder2.js): [builder-clean-css](https://github.com/poying/builder-clean-css)
* [Metalsmith](http://metalsmith.io): [metalsmith-clean-css](https://github.com/aymericbeaumet/metalsmith-clean-css)
* [Lasso](https://github.com/lasso-js/lasso): [lasso-clean-css](https://github.com/yomed/lasso-clean-css)
### What are the clean-css' dev commands?
First clone the source, then run:
* `npm run bench` for clean-css benchmarks (see [test/bench.js](https://github.com/jakubpawlowicz/clean-css/blob/master/test/bench.js) for details)
* `npm run browserify` to create the browser-ready clean-css version
* `npm run check` to check JS sources with [JSHint](https://github.com/jshint/jshint/)
* `npm test` for the test suite
## How to contribute to clean-css?
See [CONTRIBUTING.md](https://github.com/jakubpawlowicz/clean-css/blob/master/CONTRIBUTING.md).
## Tips & Tricks
### How to preserve a comment block?
Use the `/*!` notation instead of the standard one `/*`:
```css
/*!
Important comments included in minified output.
*/
```
### How to rebase relative image URLs?
Clean-css will handle it automatically for you (since version 1.1) in the following cases:
* When using the CLI:
1. Use an output path via `-o`/`--output` to rebase URLs as relative to the output file.
2. Use a root path via `-r`/`--root` to rebase URLs as absolute from the given root path.
3. If you specify both then `-r`/`--root` takes precendence.
* When using clean-css as a library:
1. Use a combination of `relativeTo` and `target` options for relative rebase (same as 1 in CLI).
2. Use a combination of `relativeTo` and `root` options for absolute rebase (same as 2 in CLI).
3. `root` takes precendence over `target` as in CLI.
### How to generate source maps?
Source maps are supported since version 3.0.
Additionally to mapping original CSS files, clean-css also supports input source maps, so minified styles can be mapped into their [Less](http://lesscss.org/) or [Sass](http://sass-lang.com/) sources directly.
Source maps are generated using [source-map](https://github.com/mozilla/source-map/) module from Mozilla.
#### Using CLI
To generate a source map, use `--source-map` switch, e.g.:
```
cleancss --source-map --output styles.min.css styles.css
```
Name of the output file is required, so a map file, named by adding `.map` suffix to output file name, can be created (styles.min.css.map in this case).
#### Using API
To generate a source map, use `sourceMap: true` option, e.g.:
```js
new CleanCSS({ sourceMap: true, target: pathToOutputDirectory })
.minify(source, function (minified) {
// access minified.sourceMap for SourceMapGenerator object
// see https://github.com/mozilla/source-map/#sourcemapgenerator for more details
// see https://github.com/jakubpawlowicz/clean-css/blob/master/bin/cleancss#L114 on how it's used in clean-css' CLI
});
```
Using API you can also pass an input source map directly:
```js
new CleanCSS({ sourceMap: inputSourceMapAsString, target: pathToOutputDirectory })
.minify(source, function (minified) {
// access minified.sourceMap to access SourceMapGenerator object
// see https://github.com/mozilla/source-map/#sourcemapgenerator for more details
// see https://github.com/jakubpawlowicz/clean-css/blob/master/bin/cleancss#L114 on how it's used in clean-css' CLI
});
```
Or even multiple input source maps at once (available since version 3.1):
```js
new CleanCSS({ sourceMap: true, target: pathToOutputDirectory }).minify({
'path/to/source/1': {
styles: '...styles...',
sourceMap: '...source-map...'
},
'path/to/source/2': {
styles: '...styles...',
sourceMap: '...source-map...'
}
}, function (minified) {
// access minified.sourceMap as above
});
```
### How to minify multiple files with API?
#### Passing an array
```js
new CleanCSS().minify(['path/to/file/one', 'path/to/file/two']);
```
#### Passing a hash
```js
new CleanCSS().minify({
'path/to/file/one': {
styles: 'contents of file one'
},
'path/to/file/two': {
styles: 'contents of file two'
}
});
```
### How to set a compatibility mode?
Compatibility settings are controlled by `--compatibility` switch (CLI) and `compatibility` option (library mode).
In both modes the following values are allowed:
* `'ie7'` - Internet Explorer 7 compatibility mode
* `'ie8'` - Internet Explorer 8 compatibility mode
* `''` or `'*'` (default) - Internet Explorer 9+ compatibility mode
Since clean-css 3 a fine grained control is available over
[those settings](https://github.com/jakubpawlowicz/clean-css/blob/master/lib/utils/compatibility.js),
with the following options available:
* `'[+-]colors.opacity'` - - turn on (+) / off (-) `rgba()` / `hsla()` declarations removal
* `'[+-]properties.backgroundClipMerging'` - turn on / off background-clip merging into shorthand
* `'[+-]properties.backgroundOriginMerging'` - turn on / off background-origin merging into shorthand
* `'[+-]properties.backgroundSizeMerging'` - turn on / off background-size merging into shorthand
* `'[+-]properties.colors'` - turn on / off any color optimizations
* `'[+-]properties.ieBangHack'` - turn on / off IE bang hack removal
* `'[+-]properties.iePrefixHack'` - turn on / off IE prefix hack removal
* `'[+-]properties.ieSuffixHack'` - turn on / off IE suffix hack removal
* `'[+-]properties.merging'` - turn on / off property merging based on understandability
* `'[+-]properties.spaceAfterClosingBrace'` - turn on / off removing space after closing brace - `url() no-repeat` into `url()no-repeat`
* `'[+-]properties.urlQuotes'` - turn on / off `url()` quoting
* `'[+-]properties.zeroUnits'` - turn on / off units removal after a `0` value
* `'[+-]selectors.adjacentSpace'` - turn on / off extra space before `nav` element
* `'[+-]selectors.ie7Hack'` - turn on / off IE7 selector hack removal (`*+html...`)
* `'[+-]selectors.special'` - a regular expression with all special, unmergeable selectors (leave it empty unless you know what you are doing)
* `'[+-]units.ch'` - turn on / off treating `ch` as a proper unit
* `'[+-]units.in'` - turn on / off treating `in` as a proper unit
* `'[+-]units.pc'` - turn on / off treating `pc` as a proper unit
* `'[+-]units.pt'` - turn on / off treating `pt` as a proper unit
* `'[+-]units.rem'` - turn on / off treating `rem` as a proper unit
* `'[+-]units.vh'` - turn on / off treating `vh` as a proper unit
* `'[+-]units.vm'` - turn on / off treating `vm` as a proper unit
* `'[+-]units.vmax'` - turn on / off treating `vmax` as a proper unit
* `'[+-]units.vmin'` - turn on / off treating `vmin` as a proper unit
* `'[+-]units.vm'` - turn on / off treating `vm` as a proper unit
For example, using `--compatibility 'ie8,+units.rem'` will ensure IE8 compatibility while enabling `rem` units so the following style `margin:0px 0rem` can be shortened to `margin:0`, while in pure IE8 mode it can't be.
To pass a single off (-) switch in CLI please use the following syntax `--compatibility *,-units.rem`.
In library mode you can also pass `compatibility` as a hash of options.
### What advanced optimizations are applied?
All advanced optimizations are dispatched [here](https://github.com/jakubpawlowicz/clean-css/blob/master/lib/selectors/advanced.js#L59), and this is what they do:
* `recursivelyOptimizeBlocks` - does all the following operations on a block (think `@media` or `@keyframe` at-rules);
* `recursivelyOptimizeProperties` - optimizes properties in rulesets and "flat at-rules" (like @font-face) by splitting them into components (e.g. `margin` into `margin-(*)`), optimizing, and rebuilding them back. You may want to use `shorthandCompacting` option to control whether you want to turn multiple (long-hand) properties into a shorthand ones;
* `removeDuplicates` - gets rid of duplicate rulesets with exactly the same set of properties (think of including the same Sass / Less partial twice for no good reason);
* `mergeAdjacent` - merges adjacent rulesets with the same selector or rules;
* `reduceNonAdjacent` - identifies which properties are overridden in same-selector non-adjacent rulesets, and removes them;
* `mergeNonAdjacentBySelector` - identifies same-selector non-adjacent rulesets which can be moved (!) to be merged, requires all intermediate rulesets to not redefine the moved properties, or if redefined to be either more coarse grained (e.g. `margin` vs `margin-top`) or have the same value;
* `mergeNonAdjacentByBody` - same as the one above but for same-rules non-adjacent rulesets;
* `restructure` - tries to reorganize different-selector different-rules rulesets so they take less space, e.g. `.one{padding:0}.two{margin:0}.one{margin-bottom:3px}` into `.two{margin:0}.one{padding:0;margin-bottom:3px}`;
* `removeDuplicateMediaQueries` - removes duplicated `@media` at-rules;
* `mergeMediaQueries` - merges non-adjacent `@media` at-rules by same rules as `mergeNonAdjacentBy*` above;
## Acknowledgments (sorted alphabetically)
* Anthony Barre ([@abarre](https://github.com/abarre)) for improvements to
`@import` processing, namely introducing the `--skip-import` /
`processImport` options.
* Simon Altschuler ([@altschuler](https://github.com/altschuler)) for fixing
`@import` processing inside comments.
* Isaac ([@facelessuser](https://github.com/facelessuser)) for pointing out
a flaw in clean-css' stateless mode.
* Jan Michael Alonzo ([@jmalonzo](https://github.com/jmalonzo)) for a patch
removing node.js' old `sys` package.
* Luke Page ([@lukeapage](https://github.com/lukeapage)) for suggestions and testing the source maps feature.
Plus everyone else involved in [#125](https://github.com/jakubpawlowicz/clean-css/issues/125) for pushing it forward.
* Timur Kristóf ([@Venemo](https://github.com/Venemo)) for an outstanding
contribution of advanced property optimizer for 2.2 release.
* Vincent Voyer ([@vvo](https://github.com/vvo)) for a patch with better
empty element regex and for inspiring us to do many performance improvements
in 0.4 release.
* [@XhmikosR](https://github.com/XhmikosR) for suggesting new features
(option to remove special comments and strip out URLs quotation) and
pointing out numerous improvements (JSHint, media queries).
## License
Clean-css is released under the [MIT License](https://github.com/jakubpawlowicz/clean-css/blob/master/LICENSE).

183
node_modules/clean-css/bin/cleancss generated vendored Normal file
View File

@@ -0,0 +1,183 @@
#!/usr/bin/env node
var fs = require('fs');
var path = require('path');
var CleanCSS = require('../index');
var commands = require('commander');
var packageConfig = fs.readFileSync(path.join(path.dirname(fs.realpathSync(process.argv[1])), '../package.json'));
var buildVersion = JSON.parse(packageConfig).version;
var isWindows = process.platform == 'win32';
// Specify commander options to parse command line params correctly
commands
.version(buildVersion, '-v, --version')
.usage('[options] source-file, [source-file, ...]')
.option('-b, --keep-line-breaks', 'Keep line breaks')
.option('-c, --compatibility [ie7|ie8]', 'Force compatibility mode (see Readme for advanced examples)')
.option('-d, --debug', 'Shows debug information (minification time & compression efficiency)')
.option('-o, --output [output-file]', 'Use [output-file] as output instead of STDOUT')
.option('-r, --root [root-path]', 'Set a root path to which resolve absolute @import rules')
.option('-s, --skip-import', 'Disable @import processing')
.option('-t, --timeout [seconds]', 'Per connection timeout when fetching remote @imports (defaults to 5 seconds)')
.option('--rounding-precision [n]', 'Rounds to `N` decimal places. Defaults to 2. -1 disables rounding', parseInt)
.option('--s0', 'Remove all special comments, i.e. /*! comment */')
.option('--s1', 'Remove all special comments but the first one')
.option('--semantic-merging', 'Enables unsafe mode by assuming BEM-like semantic stylesheets (warning, this may break your styling!)')
.option('--skip-advanced', 'Disable advanced optimizations - ruleset reordering & merging')
.option('--skip-aggressive-merging', 'Disable properties merging based on their order')
.option('--skip-import-from [rules]', 'Disable @import processing for specified rules', function (val) { return val.split(','); }, [])
.option('--skip-media-merging', 'Disable @media merging')
.option('--skip-rebase', 'Disable URLs rebasing')
.option('--skip-restructuring', 'Disable restructuring optimizations')
.option('--skip-shorthand-compacting', 'Disable shorthand compacting')
.option('--source-map', 'Enables building input\'s source map')
.option('--source-map-inline-sources', 'Enables inlining sources inside source maps');
commands.on('--help', function () {
console.log(' Examples:\n');
console.log(' %> cleancss one.css');
console.log(' %> cleancss -o one-min.css one.css');
if (isWindows) {
console.log(' %> type one.css two.css three.css | cleancss -o merged-and-minified.css');
} else {
console.log(' %> cat one.css two.css three.css | cleancss -o merged-and-minified.css');
console.log(' %> cat one.css two.css three.css | cleancss | gzip -9 -c > merged-minified-and-gzipped.css.gz');
}
console.log('');
process.exit();
});
commands.parse(process.argv);
// If no sensible data passed in just print help and exit
var fromStdin = !process.env.__DIRECT__ && !process.stdin.isTTY;
if (!fromStdin && commands.args.length === 0) {
commands.outputHelp();
return 0;
}
// Now coerce commands into CleanCSS configuration...
var options = {
advanced: commands.skipAdvanced ? false : true,
aggressiveMerging: commands.skipAggressiveMerging ? false : true,
compatibility: commands.compatibility,
debug: commands.debug,
inliner: commands.timeout ? { timeout: parseFloat(commands.timeout) * 1000 } : undefined,
keepBreaks: !!commands.keepLineBreaks,
keepSpecialComments: commands.s0 ? 0 : (commands.s1 ? 1 : '*'),
mediaMerging: commands.skipMediaMerging ? false : true,
processImport: commands.skipImport ? false : true,
processImportFrom: processImportFrom(commands.skipImportFrom),
rebase: commands.skipRebase ? false : true,
restructuring: commands.skipRestructuring ? false : true,
root: commands.root,
roundingPrecision: commands.roundingPrecision,
semanticMerging: commands.semanticMerging ? true : false,
shorthandCompacting: commands.skipShorthandCompacting ? false : true,
sourceMap: commands.sourceMap,
sourceMapInlineSources: commands.sourceMapInlineSources,
target: commands.output
};
if (options.root || commands.args.length > 0) {
var relativeTo = options.root || commands.args[0];
if (isRemote(relativeTo)) {
options.relativeTo = relativeTo;
} else {
var resolvedRelativeTo = path.resolve(relativeTo);
options.relativeTo = fs.statSync(resolvedRelativeTo).isFile() ?
path.dirname(resolvedRelativeTo) :
resolvedRelativeTo;
}
}
if (options.sourceMap && !options.target) {
outputFeedback(['Source maps will not be built because you have not specified an output file.'], true);
options.sourceMap = false;
}
// ... and do the magic!
if (commands.args.length > 0) {
minify(commands.args);
} else {
var stdin = process.openStdin();
stdin.setEncoding('utf-8');
var data = '';
stdin.on('data', function (chunk) {
data += chunk;
});
stdin.on('end', function () {
minify(data);
});
}
function isRemote(path) {
return /^https?:\/\//.test(path) || /^\/\//.test(path);
}
function processImportFrom(rules) {
if (rules.length === 0) {
return ['all'];
} else if (rules.length == 1 && rules[0] == 'all') {
return [];
} else {
return rules.map(function (rule) {
if (rule == 'local')
return 'remote';
else if (rule == 'remote')
return 'local';
else
return '!' + rule;
});
}
}
function minify(data) {
new CleanCSS(options).minify(data, function (errors, minified) {
if (options.debug) {
console.error('Original: %d bytes', minified.stats.originalSize);
console.error('Minified: %d bytes', minified.stats.minifiedSize);
console.error('Efficiency: %d%', ~~(minified.stats.efficiency * 10000) / 100.0);
console.error('Time spent: %dms', minified.stats.timeSpent);
}
outputFeedback(minified.errors, true);
outputFeedback(minified.warnings);
if (minified.errors.length > 0)
process.exit(1);
if (minified.sourceMap) {
var mapFilename = path.basename(options.target) + '.map';
output(minified.styles + '/*# sourceMappingURL=' + mapFilename + ' */');
outputMap(minified.sourceMap, mapFilename);
} else {
output(minified.styles);
}
});
}
function output(minified) {
if (options.target)
fs.writeFileSync(options.target, minified, 'utf8');
else
process.stdout.write(minified);
}
function outputMap(sourceMap, mapFilename) {
var mapPath = path.join(path.dirname(options.target), mapFilename);
fs.writeFileSync(mapPath, sourceMap.toString(), 'utf-8');
}
function outputFeedback(messages, isError) {
var prefix = isError ? '\x1B[31mERROR\x1B[39m:' : 'WARNING:';
messages.forEach(function (message) {
console.error('%s %s', prefix, message);
});
}

1
node_modules/clean-css/index.js generated vendored Normal file
View File

@@ -0,0 +1 @@
module.exports = require('./lib/clean');

231
node_modules/clean-css/lib/clean.js generated vendored Normal file
View File

@@ -0,0 +1,231 @@
/**
* Clean-css - https://github.com/jakubpawlowicz/clean-css
* Released under the terms of MIT license
*
* Copyright (C) 2015 JakubPawlowicz.com
*/
var ImportInliner = require('./imports/inliner');
var rebaseUrls = require('./urls/rebase');
var tokenize = require('./tokenizer/tokenize');
var simpleOptimize = require('./selectors/simple');
var advancedOptimize = require('./selectors/advanced');
var simpleStringify = require('./stringifier/simple');
var sourceMapStringify = require('./stringifier/source-maps');
var CommentsProcessor = require('./text/comments-processor');
var ExpressionsProcessor = require('./text/expressions-processor');
var FreeTextProcessor = require('./text/free-text-processor');
var UrlsProcessor = require('./text/urls-processor');
var Compatibility = require('./utils/compatibility');
var InputSourceMapTracker = require('./utils/input-source-map-tracker');
var SourceTracker = require('./utils/source-tracker');
var SourceReader = require('./utils/source-reader');
var Validator = require('./properties/validator');
var fs = require('fs');
var path = require('path');
var url = require('url');
var override = require('./utils/object').override;
var DEFAULT_TIMEOUT = 5000;
var CleanCSS = module.exports = function CleanCSS(options) {
options = options || {};
this.options = {
advanced: undefined === options.advanced ? true : !!options.advanced,
aggressiveMerging: undefined === options.aggressiveMerging ? true : !!options.aggressiveMerging,
benchmark: options.benchmark,
compatibility: new Compatibility(options.compatibility).toOptions(),
debug: options.debug,
explicitRoot: !!options.root,
explicitTarget: !!options.target,
inliner: options.inliner || {},
keepBreaks: options.keepBreaks || false,
keepSpecialComments: 'keepSpecialComments' in options ? options.keepSpecialComments : '*',
mediaMerging: undefined === options.mediaMerging ? true : !!options.mediaMerging,
processImport: undefined === options.processImport ? true : !!options.processImport,
processImportFrom: importOptionsFrom(options.processImportFrom),
rebase: undefined === options.rebase ? true : !!options.rebase,
relativeTo: options.relativeTo,
restructuring: undefined === options.restructuring ? true : !!options.restructuring,
root: options.root || process.cwd(),
roundingPrecision: options.roundingPrecision,
semanticMerging: undefined === options.semanticMerging ? false : !!options.semanticMerging,
shorthandCompacting: undefined === options.shorthandCompacting ? true : !!options.shorthandCompacting,
sourceMap: options.sourceMap,
sourceMapInlineSources: !!options.sourceMapInlineSources,
target: !options.target || missingDirectory(options.target) || presentDirectory(options.target) ? options.target : path.dirname(options.target)
};
this.options.inliner.timeout = this.options.inliner.timeout || DEFAULT_TIMEOUT;
this.options.inliner.request = override(
/* jshint camelcase: false */
proxyOptionsFrom(process.env.HTTP_PROXY || process.env.http_proxy),
this.options.inliner.request || {}
);
};
function importOptionsFrom(rules) {
return undefined === rules ? ['all'] : rules;
}
function missingDirectory(filepath) {
return !fs.existsSync(filepath) && !/\.css$/.test(filepath);
}
function presentDirectory(filepath) {
return fs.existsSync(filepath) && fs.statSync(filepath).isDirectory();
}
function proxyOptionsFrom(httpProxy) {
return httpProxy ?
{
hostname: url.parse(httpProxy).hostname,
port: parseInt(url.parse(httpProxy).port)
} :
{};
}
CleanCSS.prototype.minify = function (data, callback) {
var context = {
stats: {},
errors: [],
warnings: [],
options: this.options,
debug: this.options.debug,
localOnly: !callback,
sourceTracker: new SourceTracker(),
validator: new Validator(this.options.compatibility)
};
if (context.options.sourceMap)
context.inputSourceMapTracker = new InputSourceMapTracker(context);
context.sourceReader = new SourceReader(context, data);
data = context.sourceReader.toString();
if (context.options.processImport || data.indexOf('@shallow') > 0) {
// inline all imports
var runner = callback ?
process.nextTick :
function (callback) { return callback(); };
return runner(function () {
return new ImportInliner(context).process(data, {
localOnly: context.localOnly,
imports: context.options.processImportFrom,
whenDone: runMinifier(callback, context)
});
});
} else {
return runMinifier(callback, context)(data);
}
};
function runMinifier(callback, context) {
function whenSourceMapReady (data) {
data = context.options.debug ?
minifyWithDebug(context, data) :
minify(context, data);
data = withMetadata(context, data);
return callback ?
callback.call(null, context.errors.length > 0 ? context.errors : null, data) :
data;
}
return function (data) {
if (context.options.sourceMap) {
return context.inputSourceMapTracker.track(data, function () {
if (context.options.sourceMapInlineSources) {
return context.inputSourceMapTracker.resolveSources(function () {
return whenSourceMapReady(data);
});
} else {
return whenSourceMapReady(data);
}
});
} else {
return whenSourceMapReady(data);
}
};
}
function withMetadata(context, data) {
data.stats = context.stats;
data.errors = context.errors;
data.warnings = context.warnings;
return data;
}
function minifyWithDebug(context, data) {
var startedAt = process.hrtime();
context.stats.originalSize = context.sourceTracker.removeAll(data).length;
data = minify(context, data);
var elapsed = process.hrtime(startedAt);
context.stats.timeSpent = ~~(elapsed[0] * 1e3 + elapsed[1] / 1e6);
context.stats.efficiency = 1 - data.styles.length / context.stats.originalSize;
context.stats.minifiedSize = data.styles.length;
return data;
}
function benchmark(runner) {
return function (processor, action) {
var name = processor.constructor.name + '#' + action;
var start = process.hrtime();
runner(processor, action);
var itTook = process.hrtime(start);
console.log('%d ms: ' + name, 1000 * itTook[0] + itTook[1] / 1000000);
};
}
function minify(context, data) {
var options = context.options;
var commentsProcessor = new CommentsProcessor(context, options.keepSpecialComments, options.keepBreaks, options.sourceMap);
var expressionsProcessor = new ExpressionsProcessor(options.sourceMap);
var freeTextProcessor = new FreeTextProcessor(options.sourceMap);
var urlsProcessor = new UrlsProcessor(context, options.sourceMap, options.compatibility.properties.urlQuotes);
var stringify = options.sourceMap ? sourceMapStringify : simpleStringify;
var run = function (processor, action) {
data = typeof processor == 'function' ?
processor(data) :
processor[action](data);
};
if (options.benchmark)
run = benchmark(run);
run(commentsProcessor, 'escape');
run(expressionsProcessor, 'escape');
run(urlsProcessor, 'escape');
run(freeTextProcessor, 'escape');
function restoreEscapes(data, prefixContent) {
data = freeTextProcessor.restore(data, prefixContent);
data = urlsProcessor.restore(data);
data = options.rebase ? rebaseUrls(data, context) : data;
data = expressionsProcessor.restore(data);
return commentsProcessor.restore(data);
}
var tokens = tokenize(data, context);
simpleOptimize(tokens, options, context);
if (options.advanced)
advancedOptimize(tokens, options, context, true);
return stringify(tokens, options, restoreEscapes, context.inputSourceMapTracker);
}

186
node_modules/clean-css/lib/colors/hex-name-shortener.js generated vendored Normal file
View File

@@ -0,0 +1,186 @@
var HexNameShortener = {};
var COLORS = {
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',
darkgreen: '#006400',
darkgrey: '#a9a9a9',
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',
green: '#008000',
greenyellow: '#adff2f',
grey: '#808080',
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',
lightgreen: '#90ee90',
lightgrey: '#d3d3d3',
lightpink: '#ffb6c1',
lightsalmon: '#ffa07a',
lightseagreen: '#20b2aa',
lightskyblue: '#87cefa',
lightslategray: '#778899',
lightslategrey: '#778899',
lightsteelblue: '#b0c4de',
lightyellow: '#ffffe0',
lime: '#0f0',
limegreen: '#32cd32',
linen: '#faf0e6',
magenta: '#ff00ff',
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: '#663399',
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 toHex = {};
var toName = {};
for (var name in COLORS) {
var hex = COLORS[name];
if (name.length < hex.length)
toName[hex] = name;
else
toHex[name] = hex;
}
var toHexPattern = new RegExp('(^| |,|\\))(' + Object.keys(toHex).join('|') + ')( |,|\\)|$)', 'ig');
var toNamePattern = new RegExp('(' + Object.keys(toName).join('|') + ')([^a-f0-9]|$)', 'ig');
function hexConverter(match, prefix, colorValue, suffix) {
return prefix + toHex[colorValue.toLowerCase()] + suffix;
}
function nameConverter(match, colorValue, suffix) {
return toName[colorValue.toLowerCase()] + suffix;
}
HexNameShortener.shorten = function (value) {
var hasHex = value.indexOf('#') > -1;
var shortened = value.replace(toHexPattern, hexConverter);
if (shortened != value)
shortened = shortened.replace(toHexPattern, hexConverter);
return hasHex ? shortened.replace(toNamePattern, nameConverter) : shortened;
};
module.exports = HexNameShortener;

67
node_modules/clean-css/lib/colors/hsl.js generated vendored Normal file
View File

@@ -0,0 +1,67 @@
// HSL to RGB converter. Both methods adapted from:
// http://mjijackson.com/2008/02/rgb-to-hsl-and-rgb-to-hsv-color-model-conversion-algorithms-in-javascript
function HSLColor(hue, saturation, lightness) {
this.hue = hue;
this.saturation = saturation;
this.lightness = lightness;
}
function hslToRgb(h, s, l) {
var r, g, b;
// normalize hue orientation b/w 0 and 360 degrees
h = h % 360;
if (h < 0)
h += 360;
h = ~~h / 360;
if (s < 0)
s = 0;
else if (s > 100)
s = 100;
s = ~~s / 100;
if (l < 0)
l = 0;
else if (l > 100)
l = 100;
l = ~~l / 100;
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 [~~(r * 255), ~~(g * 255), ~~(b * 255)];
}
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;
}
HSLColor.prototype.toHex = function () {
var asRgb = hslToRgb(this.hue, this.saturation, this.lightness);
var redAsHex = asRgb[0].toString(16);
var greenAsHex = asRgb[1].toString(16);
var blueAsHex = asRgb[2].toString(16);
return '#' +
((redAsHex.length == 1 ? '0' : '') + redAsHex) +
((greenAsHex.length == 1 ? '0' : '') + greenAsHex) +
((blueAsHex.length == 1 ? '0' : '') + blueAsHex);
};
module.exports = HSLColor;

16
node_modules/clean-css/lib/colors/rgb.js generated vendored Normal file
View File

@@ -0,0 +1,16 @@
function RGB(red, green, blue) {
this.red = red;
this.green = green;
this.blue = blue;
}
RGB.prototype.toHex = function () {
var red = Math.max(0, Math.min(~~this.red, 255));
var green = Math.max(0, Math.min(~~this.green, 255));
var blue = Math.max(0, Math.min(~~this.blue, 255));
// Credit: Asen http://jsbin.com/UPUmaGOc/2/edit?js,console
return '#' + ('00000' + (red << 16 | green << 8 | blue).toString(16)).slice(-6);
};
module.exports = RGB;

399
node_modules/clean-css/lib/imports/inliner.js generated vendored Normal file
View File

@@ -0,0 +1,399 @@
var fs = require('fs');
var path = require('path');
var http = require('http');
var https = require('https');
var url = require('url');
var rewriteUrls = require('../urls/rewrite');
var split = require('../utils/split');
var override = require('../utils/object.js').override;
var MAP_MARKER = /\/\*# sourceMappingURL=(\S+) \*\//;
var REMOTE_RESOURCE = /^(https?:)?\/\//;
var NO_PROTOCOL_RESOURCE = /^\/\//;
function ImportInliner (context) {
this.outerContext = context;
}
ImportInliner.prototype.process = function (data, context) {
var root = this.outerContext.options.root;
context = override(context, {
baseRelativeTo: this.outerContext.options.relativeTo || root,
debug: this.outerContext.options.debug,
done: [],
errors: this.outerContext.errors,
left: [],
inliner: this.outerContext.options.inliner,
rebase: this.outerContext.options.rebase,
relativeTo: this.outerContext.options.relativeTo || root,
root: root,
sourceReader: this.outerContext.sourceReader,
sourceTracker: this.outerContext.sourceTracker,
warnings: this.outerContext.warnings,
visited: []
});
return importFrom(data, context);
};
function importFrom(data, context) {
if (context.shallow) {
context.shallow = false;
context.done.push(data);
return processNext(context);
}
var nextStart = 0;
var nextEnd = 0;
var cursor = 0;
var isComment = commentScanner(data);
for (; nextEnd < data.length;) {
nextStart = nextImportAt(data, cursor);
if (nextStart == -1)
break;
if (isComment(nextStart)) {
cursor = nextStart + 1;
continue;
}
nextEnd = data.indexOf(';', nextStart);
if (nextEnd == -1) {
cursor = data.length;
data = '';
break;
}
var noImportPart = data.substring(0, nextStart);
context.done.push(noImportPart);
context.left.unshift([data.substring(nextEnd + 1), override(context, { shallow: false })]);
context.afterContent = hasContent(noImportPart);
return inline(data, nextStart, nextEnd, context);
}
// no @import matched in current data
context.done.push(data);
return processNext(context);
}
function rebaseMap(data, source) {
return data.replace(MAP_MARKER, function (match, sourceMapUrl) {
return REMOTE_RESOURCE.test(sourceMapUrl) ?
match :
match.replace(sourceMapUrl, url.resolve(source, sourceMapUrl));
});
}
function nextImportAt(data, cursor) {
var nextLowerCase = data.indexOf('@import', cursor);
var nextUpperCase = data.indexOf('@IMPORT', cursor);
if (nextLowerCase > -1 && nextUpperCase == -1)
return nextLowerCase;
else if (nextLowerCase == -1 && nextUpperCase > -1)
return nextUpperCase;
else
return Math.min(nextLowerCase, nextUpperCase);
}
function processNext(context) {
return context.left.length > 0 ?
importFrom.apply(null, context.left.shift()) :
context.whenDone(context.done.join(''));
}
function commentScanner(data) {
var commentRegex = /(\/\*(?!\*\/)[\s\S]*?\*\/)/;
var lastStartIndex = 0;
var lastEndIndex = 0;
var noComments = false;
// test whether an index is located within a comment
return function scanner(idx) {
var comment;
var localStartIndex = 0;
var localEndIndex = 0;
var globalStartIndex = 0;
var globalEndIndex = 0;
// return if we know there are no more comments
if (noComments)
return false;
do {
// idx can be still within last matched comment (many @import statements inside one comment)
if (idx > lastStartIndex && idx < lastEndIndex)
return true;
comment = data.match(commentRegex);
if (!comment) {
noComments = true;
return false;
}
// get the indexes relative to the current data chunk
lastStartIndex = localStartIndex = comment.index;
localEndIndex = localStartIndex + comment[0].length;
// calculate the indexes relative to the full original data
globalEndIndex = localEndIndex + lastEndIndex;
globalStartIndex = globalEndIndex - comment[0].length;
// chop off data up to and including current comment block
data = data.substring(localEndIndex);
lastEndIndex = globalEndIndex;
} while (globalEndIndex < idx);
return globalEndIndex > idx && idx > globalStartIndex;
};
}
function hasContent(data) {
var isComment = commentScanner(data);
var firstContentIdx = -1;
while (true) {
firstContentIdx = data.indexOf('{', firstContentIdx + 1);
if (firstContentIdx == -1 || !isComment(firstContentIdx))
break;
}
return firstContentIdx > -1;
}
function inline(data, nextStart, nextEnd, context) {
context.shallow = data.indexOf('@shallow') > 0;
var importDeclaration = data
.substring(nextImportAt(data, nextStart) + '@import'.length + 1, nextEnd)
.replace(/@shallow\)$/, ')')
.trim();
var viaUrl = importDeclaration.indexOf('url(') === 0;
var urlStartsAt = viaUrl ? 4 : 0;
var isQuoted = /^['"]/.exec(importDeclaration.substring(urlStartsAt, urlStartsAt + 2));
var urlEndsAt = isQuoted ?
importDeclaration.indexOf(isQuoted[0], urlStartsAt + 1) :
split(importDeclaration, ' ')[0].length - (viaUrl ? 1 : 0);
var importedFile = importDeclaration
.substring(urlStartsAt, urlEndsAt)
.replace(/['"]/g, '')
.replace(/\)$/, '')
.trim();
var mediaQuery = importDeclaration
.substring(urlEndsAt + 1)
.replace(/^\)/, '')
.trim();
var isRemote = context.isRemote || REMOTE_RESOURCE.test(importedFile);
if (isRemote && (context.localOnly || !allowedResource(importedFile, true, context.imports))) {
if (context.afterContent || hasContent(context.done.join('')))
context.warnings.push('Ignoring remote @import of "' + importedFile + '" as no callback given.');
else
restoreImport(importedFile, mediaQuery, context);
return processNext(context);
}
if (!isRemote && !allowedResource(importedFile, false, context.imports)) {
if (context.afterImport)
context.warnings.push('Ignoring local @import of "' + importedFile + '" as after other inlined content.');
else
restoreImport(importedFile, mediaQuery, context);
return processNext(context);
}
if (!isRemote && context.afterContent) {
context.warnings.push('Ignoring local @import of "' + importedFile + '" as after other CSS content.');
return processNext(context);
}
var method = isRemote ? inlineRemoteResource : inlineLocalResource;
return method(importedFile, mediaQuery, context);
}
function allowedResource(importedFile, isRemote, rules) {
if (rules.length === 0)
return false;
if (isRemote && NO_PROTOCOL_RESOURCE.test(importedFile))
importedFile = 'http:' + importedFile;
var match = isRemote ?
url.parse(importedFile).host :
importedFile;
var allowed = true;
for (var i = 0; i < rules.length; i++) {
var rule = rules[i];
if (rule == 'all')
allowed = true;
else if (isRemote && rule == 'local')
allowed = false;
else if (isRemote && rule == 'remote')
allowed = true;
else if (!isRemote && rule == 'remote')
allowed = false;
else if (!isRemote && rule == 'local')
allowed = true;
else if (rule[0] == '!' && rule.substring(1) === match)
allowed = false;
}
return allowed;
}
function inlineRemoteResource(importedFile, mediaQuery, context) {
var importedUrl = REMOTE_RESOURCE.test(importedFile) ?
importedFile :
url.resolve(context.relativeTo, importedFile);
var originalUrl = importedUrl;
if (NO_PROTOCOL_RESOURCE.test(importedUrl))
importedUrl = 'http:' + importedUrl;
if (context.visited.indexOf(importedUrl) > -1)
return processNext(context);
if (context.debug)
console.error('Inlining remote stylesheet: ' + importedUrl);
context.visited.push(importedUrl);
var proxyProtocol = context.inliner.request.protocol || context.inliner.request.hostname;
var get =
((proxyProtocol && proxyProtocol.indexOf('https://') !== 0 ) ||
importedUrl.indexOf('http://') === 0) ?
http.get :
https.get;
var errorHandled = false;
function handleError(message) {
if (errorHandled)
return;
errorHandled = true;
context.errors.push('Broken @import declaration of "' + importedUrl + '" - ' + message);
restoreImport(importedUrl, mediaQuery, context);
process.nextTick(function () {
processNext(context);
});
}
var requestOptions = override(url.parse(importedUrl), context.inliner.request);
if (context.inliner.request.hostname !== undefined) {
//overwrite as we always expect a http proxy currently
requestOptions.protocol = context.inliner.request.protocol || 'http:';
requestOptions.path = requestOptions.href;
}
get(requestOptions, function (res) {
if (res.statusCode < 200 || res.statusCode > 399) {
return handleError('error ' + res.statusCode);
} else if (res.statusCode > 299) {
var movedUrl = url.resolve(importedUrl, res.headers.location);
return inlineRemoteResource(movedUrl, mediaQuery, context);
}
var chunks = [];
var parsedUrl = url.parse(importedUrl);
res.on('data', function (chunk) {
chunks.push(chunk.toString());
});
res.on('end', function () {
var importedData = chunks.join('');
if (context.rebase)
importedData = rewriteUrls(importedData, { toBase: originalUrl }, context);
context.sourceReader.trackSource(importedUrl, importedData);
importedData = context.sourceTracker.store(importedUrl, importedData);
importedData = rebaseMap(importedData, importedUrl);
if (mediaQuery.length > 0)
importedData = '@media ' + mediaQuery + '{' + importedData + '}';
context.afterImport = true;
var newContext = override(context, {
isRemote: true,
relativeTo: parsedUrl.protocol + '//' + parsedUrl.host + parsedUrl.pathname
});
process.nextTick(function () {
importFrom(importedData, newContext);
});
});
})
.on('error', function (res) {
handleError(res.message);
})
.on('timeout', function () {
handleError('timeout');
})
.setTimeout(context.inliner.timeout);
}
function inlineLocalResource(importedFile, mediaQuery, context) {
var relativeTo = importedFile[0] == '/' ?
context.root :
context.relativeTo;
var fullPath = path.resolve(path.join(relativeTo, importedFile));
if (!fs.existsSync(fullPath) || !fs.statSync(fullPath).isFile()) {
context.errors.push('Broken @import declaration of "' + importedFile + '"');
return processNext(context);
}
if (context.visited.indexOf(fullPath) > -1)
return processNext(context);
if (context.debug)
console.error('Inlining local stylesheet: ' + fullPath);
context.visited.push(fullPath);
var importRelativeTo = path.dirname(fullPath);
var importedData = fs.readFileSync(fullPath, 'utf8');
if (context.rebase) {
var rewriteOptions = {
relative: true,
fromBase: importRelativeTo,
toBase: context.baseRelativeTo
};
importedData = rewriteUrls(importedData, rewriteOptions, context);
}
var relativePath = path.relative(context.root, fullPath);
context.sourceReader.trackSource(relativePath, importedData);
importedData = context.sourceTracker.store(relativePath, importedData);
if (mediaQuery.length > 0)
importedData = '@media ' + mediaQuery + '{' + importedData + '}';
context.afterImport = true;
var newContext = override(context, {
relativeTo: importRelativeTo
});
return importFrom(importedData, newContext);
}
function restoreImport(importedUrl, mediaQuery, context) {
var restoredImport = '@import url(' + importedUrl + ')' + (mediaQuery.length > 0 ? ' ' + mediaQuery : '') + ';';
context.done.push(restoredImport);
}
module.exports = ImportInliner;

335
node_modules/clean-css/lib/properties/break-up.js generated vendored Normal file
View File

@@ -0,0 +1,335 @@
var wrapSingle = require('./wrap-for-optimizing').single;
var InvalidPropertyError = require('./invalid-property-error');
var split = require('../utils/split');
var MULTIPLEX_SEPARATOR = ',';
function _colorFilter(validator) {
return function (value) {
return value[0] == 'invert' || validator.isValidColor(value[0]);
};
}
function _styleFilter(validator) {
return function (value) {
return value[0] != 'inherit' && validator.isValidStyle(value[0]) && !validator.isValidColorValue(value[0]);
};
}
function _wrapDefault(name, property, compactable) {
var descriptor = compactable[name];
if (descriptor.doubleValues && descriptor.defaultValue.length == 2)
return wrapSingle([[name, property.important], [descriptor.defaultValue[0]], [descriptor.defaultValue[1]]]);
else if (descriptor.doubleValues && descriptor.defaultValue.length == 1)
return wrapSingle([[name, property.important], [descriptor.defaultValue[0]]]);
else
return wrapSingle([[name, property.important], [descriptor.defaultValue]]);
}
function _widthFilter(validator) {
return function (value) {
return value[0] != 'inherit' && validator.isValidWidth(value[0]) && !validator.isValidStyleKeyword(value[0]) && !validator.isValidColorValue(value[0]);
};
}
function background(property, compactable, validator) {
var image = _wrapDefault('background-image', property, compactable);
var position = _wrapDefault('background-position', property, compactable);
var size = _wrapDefault('background-size', property, compactable);
var repeat = _wrapDefault('background-repeat', property, compactable);
var attachment = _wrapDefault('background-attachment', property, compactable);
var origin = _wrapDefault('background-origin', property, compactable);
var clip = _wrapDefault('background-clip', property, compactable);
var color = _wrapDefault('background-color', property, compactable);
var components = [image, position, size, repeat, attachment, origin, clip, color];
var values = property.value;
var positionSet = false;
var clipSet = false;
var originSet = false;
var repeatSet = false;
if (property.value.length == 1 && property.value[0][0] == 'inherit') {
// NOTE: 'inherit' is not a valid value for background-attachment
color.value = image.value = repeat.value = position.value = size.value = origin.value = clip.value = property.value;
return components;
}
for (var i = values.length - 1; i >= 0; i--) {
var value = values[i];
if (validator.isValidBackgroundAttachment(value[0])) {
attachment.value = [value];
} else if (validator.isValidBackgroundBox(value[0])) {
if (clipSet) {
origin.value = [value];
originSet = true;
} else {
clip.value = [value];
clipSet = true;
}
} else if (validator.isValidBackgroundRepeat(value[0])) {
if (repeatSet) {
repeat.value.unshift(value);
} else {
repeat.value = [value];
repeatSet = true;
}
} else if (validator.isValidBackgroundPositionPart(value[0]) || validator.isValidBackgroundSizePart(value[0])) {
if (i > 0) {
var previousValue = values[i - 1];
if (previousValue[0].indexOf('/') > 0) {
var twoParts = split(previousValue[0], '/');
// NOTE: we do this slicing as value may contain metadata too, like for source maps
size.value = [[twoParts.pop()].concat(previousValue.slice(1)), value];
values[i - 1] = [twoParts.pop()].concat(previousValue.slice(1));
} else if (i > 1 && values[i - 2][0] == '/') {
size.value = [previousValue, value];
i -= 2;
} else if (previousValue[0] == '/') {
size.value = [value];
} else {
if (!positionSet)
position.value = [];
position.value.unshift(value);
positionSet = true;
}
} else {
if (!positionSet)
position.value = [];
position.value.unshift(value);
positionSet = true;
}
} else if (validator.isValidBackgroundPositionAndSize(value[0])) {
var sizeValue = split(value[0], '/');
// NOTE: we do this slicing as value may contain metadata too, like for source maps
size.value = [[sizeValue.pop()].concat(value.slice(1))];
position.value = [[sizeValue.pop()].concat(value.slice(1))];
} else if ((color.value[0][0] == compactable[color.name].defaultValue || color.value[0][0] == 'none') && validator.isValidColor(value[0])) {
color.value = [value];
} else if (validator.isValidUrl(value[0]) || validator.isValidFunction(value[0])) {
image.value = [value];
}
}
if (clipSet && !originSet)
origin.value = clip.value.slice(0);
return components;
}
function borderRadius(property, compactable) {
var values = property.value;
var splitAt = -1;
for (var i = 0, l = values.length; i < l; i++) {
if (values[i][0] == '/') {
splitAt = i;
break;
}
}
if (splitAt === 0 || splitAt === values.length - 1) {
throw new InvalidPropertyError('Invalid border-radius value.');
}
var target = _wrapDefault(property.name, property, compactable);
target.value = splitAt > -1 ?
values.slice(0, splitAt) :
values.slice(0);
target.components = fourValues(target, compactable);
var remainder = _wrapDefault(property.name, property, compactable);
remainder.value = splitAt > -1 ?
values.slice(splitAt + 1) :
values.slice(0);
remainder.components = fourValues(remainder, compactable);
for (var j = 0; j < 4; j++) {
target.components[j].multiplex = true;
target.components[j].value = target.components[j].value.concat(remainder.components[j].value);
}
return target.components;
}
function fourValues(property, compactable) {
var componentNames = compactable[property.name].components;
var components = [];
var value = property.value;
if (value.length < 1)
return [];
if (value.length < 2)
value[1] = value[0].slice(0);
if (value.length < 3)
value[2] = value[0].slice(0);
if (value.length < 4)
value[3] = value[1].slice(0);
for (var i = componentNames.length - 1; i >= 0; i--) {
var component = wrapSingle([[componentNames[i], property.important]]);
component.value = [value[i]];
components.unshift(component);
}
return components;
}
function multiplex(splitWith) {
return function (property, compactable, validator) {
var splitsAt = [];
var values = property.value;
var i, j, l, m;
// find split commas
for (i = 0, l = values.length; i < l; i++) {
if (values[i][0] == ',')
splitsAt.push(i);
}
if (splitsAt.length === 0)
return splitWith(property, compactable, validator);
var splitComponents = [];
// split over commas, and into components
for (i = 0, l = splitsAt.length; i <= l; i++) {
var from = i === 0 ? 0 : splitsAt[i - 1] + 1;
var to = i < l ? splitsAt[i] : values.length;
var _property = _wrapDefault(property.name, property, compactable);
_property.value = values.slice(from, to);
splitComponents.push(splitWith(_property, compactable, validator));
}
var components = splitComponents[0];
// group component values from each split
for (i = 0, l = components.length; i < l; i++) {
components[i].multiplex = true;
for (j = 1, m = splitComponents.length; j < m; j++) {
components[i].value.push([MULTIPLEX_SEPARATOR]);
Array.prototype.push.apply(components[i].value, splitComponents[j][i].value);
}
}
return components;
};
}
function listStyle(property, compactable, validator) {
var type = _wrapDefault('list-style-type', property, compactable);
var position = _wrapDefault('list-style-position', property, compactable);
var image = _wrapDefault('list-style-image', property, compactable);
var components = [type, position, image];
if (property.value.length == 1 && property.value[0][0] == 'inherit') {
type.value = position.value = image.value = [property.value[0]];
return components;
}
var values = property.value.slice(0);
var total = values.length;
var index = 0;
// `image` first...
for (index = 0, total = values.length; index < total; index++) {
if (validator.isValidUrl(values[index][0]) || values[index][0] == '0') {
image.value = [values[index]];
values.splice(index, 1);
break;
}
}
// ... then `type`...
for (index = 0, total = values.length; index < total; index++) {
if (validator.isValidListStyleType(values[index][0])) {
type.value = [values[index]];
values.splice(index, 1);
break;
}
}
// ... and what's left is a `position`
if (values.length > 0 && validator.isValidListStylePosition(values[0][0]))
position.value = [values[0]];
return components;
}
function widthStyleColor(property, compactable, validator) {
var descriptor = compactable[property.name];
var components = [
_wrapDefault(descriptor.components[0], property, compactable),
_wrapDefault(descriptor.components[1], property, compactable),
_wrapDefault(descriptor.components[2], property, compactable)
];
var color, style, width;
for (var i = 0; i < 3; i++) {
var component = components[i];
if (component.name.indexOf('color') > 0)
color = component;
else if (component.name.indexOf('style') > 0)
style = component;
else
width = component;
}
if ((property.value.length == 1 && property.value[0][0] == 'inherit') ||
(property.value.length == 3 && property.value[0][0] == 'inherit' && property.value[1][0] == 'inherit' && property.value[2][0] == 'inherit')) {
color.value = style.value = width.value = [property.value[0]];
return components;
}
var values = property.value.slice(0);
var match, matches;
// NOTE: usually users don't follow the required order of parts in this shorthand,
// so we'll try to parse it caring as little about order as possible
if (values.length > 0) {
matches = values.filter(_widthFilter(validator));
match = matches.length > 1 && (matches[0][0] == 'none' || matches[0][0] == 'auto') ? matches[1] : matches[0];
if (match) {
width.value = [match];
values.splice(values.indexOf(match), 1);
}
}
if (values.length > 0) {
match = values.filter(_styleFilter(validator))[0];
if (match) {
style.value = [match];
values.splice(values.indexOf(match), 1);
}
}
if (values.length > 0) {
match = values.filter(_colorFilter(validator))[0];
if (match) {
color.value = [match];
values.splice(values.indexOf(match), 1);
}
}
return components;
}
module.exports = {
background: background,
border: widthStyleColor,
borderRadius: borderRadius,
fourValues: fourValues,
listStyle: listStyle,
multiplex: multiplex,
outline: widthStyleColor
};

142
node_modules/clean-css/lib/properties/can-override.js generated vendored Normal file
View File

@@ -0,0 +1,142 @@
// Functions that decide what value can override what.
// The main purpose is to disallow removing CSS fallbacks.
// A separate implementation is needed for every different kind of CSS property.
// -----
// The generic idea is that properties that have wider browser support are 'more understandable'
// than others and that 'less understandable' values can't override more understandable ones.
// Use when two tokens of the same property can always be merged
function always() {
return true;
}
function alwaysButIntoFunction(property1, property2, validator) {
var value1 = property1.value[0][0];
var value2 = property2.value[0][0];
var validFunction1 = validator.isValidFunction(value1);
var validFunction2 = validator.isValidFunction(value2);
if (validFunction1 && validFunction2) {
return validator.areSameFunction(value1, value2);
} else if (!validFunction1 && validFunction2) {
return false;
} else {
return true;
}
}
function backgroundImage(property1, property2, validator) {
// The idea here is that 'more understandable' values override 'less understandable' values, but not vice versa
// Understandability: (none | url | inherit) > (same function) > (same value)
// (none | url)
var image1 = property1.value[0][0];
var image2 = property2.value[0][0];
if (image2 == 'none' || image2 == 'inherit' || validator.isValidUrl(image2))
return true;
if (image1 == 'none' || image1 == 'inherit' || validator.isValidUrl(image1))
return false;
// Functions with the same name can override each other; same values can override each other
return sameFunctionOrValue(property1, property2, validator);
}
function border(property1, property2, validator) {
return color(property1.components[2], property2.components[2], validator);
}
// Use for color properties (color, background-color, border-color, etc.)
function color(property1, property2, validator) {
// The idea here is that 'more understandable' values override 'less understandable' values, but not vice versa
// Understandability: (hex | named) > (rgba | hsla) > (same function name) > anything else
// NOTE: at this point rgb and hsl are replaced by hex values by clean-css
var color1 = property1.value[0][0];
var color2 = property2.value[0][0];
if (!validator.colorOpacity && (validator.isValidRgbaColor(color1) || validator.isValidHslaColor(color1)))
return false;
if (!validator.colorOpacity && (validator.isValidRgbaColor(color2) || validator.isValidHslaColor(color2)))
return false;
// (hex | named)
if (validator.isValidNamedColor(color2) || validator.isValidHexColor(color2))
return true;
if (validator.isValidNamedColor(color1) || validator.isValidHexColor(color1))
return false;
// (rgba|hsla)
if (validator.isValidRgbaColor(color2) || validator.isValidHslaColor(color2))
return true;
if (validator.isValidRgbaColor(color1) || validator.isValidHslaColor(color1))
return false;
// Functions with the same name can override each other; same values can override each other
return sameFunctionOrValue(property1, property2, validator);
}
function twoOptionalFunctions(property1, property2, validator) {
var value1 = property1.value[0][0];
var value2 = property2.value[0][0];
return !(validator.isValidFunction(value1) ^ validator.isValidFunction(value2));
}
function sameValue(property1, property2) {
var value1 = property1.value[0][0];
var value2 = property2.value[0][0];
return value1 === value2;
}
function sameFunctionOrValue(property1, property2, validator) {
var value1 = property1.value[0][0];
var value2 = property2.value[0][0];
// Functions with the same name can override each other
if (validator.areSameFunction(value1, value2))
return true;
return value1 === value2;
}
// Use for properties containing CSS units (margin-top, padding-left, etc.)
function unit(property1, property2, validator) {
// The idea here is that 'more understandable' values override 'less understandable' values, but not vice versa
// Understandability: (unit without functions) > (same functions | standard functions) > anything else
// NOTE: there is no point in having different vendor-specific functions override each other or standard functions,
// or having standard functions override vendor-specific functions, but standard functions can override each other
// NOTE: vendor-specific property values are not taken into consideration here at the moment
var value1 = property1.value[0][0];
var value2 = property2.value[0][0];
if (validator.isValidAndCompatibleUnitWithoutFunction(value1) && !validator.isValidAndCompatibleUnitWithoutFunction(value2))
return false;
if (validator.isValidUnitWithoutFunction(value2))
return true;
if (validator.isValidUnitWithoutFunction(value1))
return false;
// Standard non-vendor-prefixed functions can override each other
if (validator.isValidFunctionWithoutVendorPrefix(value2) && validator.isValidFunctionWithoutVendorPrefix(value1)) {
return true;
}
// Functions with the same name can override each other; same values can override each other
return sameFunctionOrValue(property1, property2, validator);
}
module.exports = {
always: always,
alwaysButIntoFunction: alwaysButIntoFunction,
backgroundImage: backgroundImage,
border: border,
color: color,
sameValue: sameValue,
sameFunctionOrValue: sameFunctionOrValue,
twoOptionalFunctions: twoOptionalFunctions,
unit: unit
};

26
node_modules/clean-css/lib/properties/clone.js generated vendored Normal file
View File

@@ -0,0 +1,26 @@
var wrapSingle = require('./wrap-for-optimizing').single;
function deep(property) {
var cloned = shallow(property);
for (var i = property.components.length - 1; i >= 0; i--) {
var component = shallow(property.components[i]);
component.value = property.components[i].value.slice(0);
cloned.components.unshift(component);
}
cloned.dirty = true;
cloned.value = property.value.slice(0);
return cloned;
}
function shallow(property) {
var cloned = wrapSingle([[property.name, property.important, property.hack]]);
cloned.unused = false;
return cloned;
}
module.exports = {
deep: deep,
shallow: shallow
};

285
node_modules/clean-css/lib/properties/compactable.js generated vendored Normal file
View File

@@ -0,0 +1,285 @@
// Contains the interpretation of CSS properties, as used by the property optimizer
var breakUp = require('./break-up');
var canOverride = require('./can-override');
var restore = require('./restore');
// Properties to process
// Extend this object in order to add support for more properties in the optimizer.
//
// Each key in this object represents a CSS property and should be an object.
// Such an object contains properties that describe how the represented CSS property should be handled.
// Possible options:
//
// * components: array (Only specify for shorthand properties.)
// Contains the names of the granular properties this shorthand compacts.
//
// * canOverride: function (Default is canOverride.sameValue - meaning that they'll only be merged if they have the same value.)
// Returns whether two tokens of this property can be merged with each other.
// This property has no meaning for shorthands.
//
// * defaultValue: string
// Specifies the default value of the property according to the CSS standard.
// For shorthand, this is used when every component is set to its default value, therefore it should be the shortest possible default value of all the components.
//
// * shortestValue: string
// Specifies the shortest possible value the property can possibly have.
// (Falls back to defaultValue if unspecified.)
//
// * breakUp: function (Only specify for shorthand properties.)
// Breaks the shorthand up to its components.
//
// * restore: function (Only specify for shorthand properties.)
// Puts the shorthand together from its components.
//
var compactable = {
'color': {
canOverride: canOverride.color,
defaultValue: 'transparent',
shortestValue: 'red'
},
'background': {
components: [
'background-image',
'background-position',
'background-size',
'background-repeat',
'background-attachment',
'background-origin',
'background-clip',
'background-color'
],
breakUp: breakUp.multiplex(breakUp.background),
defaultValue: '0 0',
restore: restore.multiplex(restore.background),
shortestValue: '0',
shorthand: true
},
'background-clip': {
canOverride: canOverride.always,
defaultValue: 'border-box',
shortestValue: 'border-box'
},
'background-color': {
canOverride: canOverride.color,
defaultValue: 'transparent',
multiplexLastOnly: true,
nonMergeableValue: 'none',
shortestValue: 'red'
},
'background-image': {
canOverride: canOverride.backgroundImage,
defaultValue: 'none'
},
'background-origin': {
canOverride: canOverride.always,
defaultValue: 'padding-box',
shortestValue: 'border-box'
},
'background-repeat': {
canOverride: canOverride.always,
defaultValue: ['repeat'],
doubleValues: true
},
'background-position': {
canOverride: canOverride.alwaysButIntoFunction,
defaultValue: ['0', '0'],
doubleValues: true,
shortestValue: '0'
},
'background-size': {
canOverride: canOverride.alwaysButIntoFunction,
defaultValue: ['auto'],
doubleValues: true,
shortestValue: '0 0'
},
'background-attachment': {
canOverride: canOverride.always,
defaultValue: 'scroll'
},
'border': {
breakUp: breakUp.border,
canOverride: canOverride.border,
components: [
'border-width',
'border-style',
'border-color'
],
defaultValue: 'none',
restore: restore.withoutDefaults,
shorthand: true
},
'border-color': {
canOverride: canOverride.color,
defaultValue: 'none',
shorthand: true
},
'border-style': {
canOverride: canOverride.always,
defaultValue: 'none',
shorthand: true
},
'border-width': {
canOverride: canOverride.unit,
defaultValue: 'medium',
shortestValue: '0',
shorthand: true
},
'list-style': {
components: [
'list-style-type',
'list-style-position',
'list-style-image'
],
canOverride: canOverride.always,
breakUp: breakUp.listStyle,
restore: restore.withoutDefaults,
defaultValue: 'outside', // can't use 'disc' because that'd override default 'decimal' for <ol>
shortestValue: 'none',
shorthand: true
},
'list-style-type' : {
canOverride: canOverride.always,
defaultValue: '__hack',
// NOTE: we can't tell the real default value here, it's 'disc' for <ul> and 'decimal' for <ol>
// -- this is a hack, but it doesn't matter because this value will be either overridden or it will disappear at the final step anyway
shortestValue: 'none'
},
'list-style-position' : {
canOverride: canOverride.always,
defaultValue: 'outside',
shortestValue: 'inside'
},
'list-style-image' : {
canOverride: canOverride.always,
defaultValue: 'none'
},
'outline': {
components: [
'outline-color',
'outline-style',
'outline-width'
],
breakUp: breakUp.outline,
restore: restore.withoutDefaults,
defaultValue: '0',
shorthand: true
},
'outline-color': {
canOverride: canOverride.color,
defaultValue: 'invert',
shortestValue: 'red'
},
'outline-style': {
canOverride: canOverride.always,
defaultValue: 'none'
},
'outline-width': {
canOverride: canOverride.unit,
defaultValue: 'medium',
shortestValue: '0'
},
'-moz-transform': {
canOverride: canOverride.sameFunctionOrValue
},
'-ms-transform': {
canOverride: canOverride.sameFunctionOrValue
},
'-webkit-transform': {
canOverride: canOverride.sameFunctionOrValue
},
'transform': {
canOverride: canOverride.sameFunctionOrValue
}
};
var addFourValueShorthand = function (prop, components, options) {
options = options || {};
compactable[prop] = {
canOverride: options.canOverride,
components: components,
breakUp: options.breakUp || breakUp.fourValues,
defaultValue: options.defaultValue || '0',
restore: options.restore || restore.fourValues,
shortestValue: options.shortestValue,
shorthand: true
};
for (var i = 0; i < components.length; i++) {
compactable[components[i]] = {
breakUp: options.breakUp || breakUp.fourValues,
canOverride: options.canOverride || canOverride.unit,
defaultValue: options.defaultValue || '0',
shortestValue: options.shortestValue
};
}
};
['', '-moz-', '-o-', '-webkit-'].forEach(function (prefix) {
addFourValueShorthand(prefix + 'border-radius', [
prefix + 'border-top-left-radius',
prefix + 'border-top-right-radius',
prefix + 'border-bottom-right-radius',
prefix + 'border-bottom-left-radius'
], {
breakUp: breakUp.borderRadius,
restore: restore.borderRadius
});
});
addFourValueShorthand('border-color', [
'border-top-color',
'border-right-color',
'border-bottom-color',
'border-left-color'
], {
breakUp: breakUp.fourValues,
canOverride: canOverride.color,
defaultValue: 'none',
shortestValue: 'red'
});
addFourValueShorthand('border-style', [
'border-top-style',
'border-right-style',
'border-bottom-style',
'border-left-style'
], {
breakUp: breakUp.fourValues,
canOverride: canOverride.always,
defaultValue: 'none'
});
addFourValueShorthand('border-width', [
'border-top-width',
'border-right-width',
'border-bottom-width',
'border-left-width'
], {
defaultValue: 'medium',
shortestValue: '0'
});
addFourValueShorthand('padding', [
'padding-top',
'padding-right',
'padding-bottom',
'padding-left'
]);
addFourValueShorthand('margin', [
'margin-top',
'margin-right',
'margin-bottom',
'margin-left'
]);
// Adds `componentOf` field to all longhands
for (var property in compactable) {
if (compactable[property].shorthand) {
for (var i = 0, l = compactable[property].components.length; i < l; i++) {
compactable[compactable[property].components[i]].componentOf = property;
}
}
}
module.exports = compactable;

View File

@@ -0,0 +1,28 @@
var shallowClone = require('./clone').shallow;
var MULTIPLEX_SEPARATOR = ',';
function everyCombination(fn, left, right, validator) {
var samePositon = !left.shorthand && !right.shorthand && !left.multiplex && !right.multiplex;
var _left = shallowClone(left);
var _right = shallowClone(right);
for (var i = 0, l = left.value.length; i < l; i++) {
for (var j = 0, m = right.value.length; j < m; j++) {
if (left.value[i][0] == MULTIPLEX_SEPARATOR || right.value[j][0] == MULTIPLEX_SEPARATOR)
continue;
if (samePositon && i != j)
continue;
_left.value = [left.value[i]];
_right.value = [right.value[j]];
if (!fn(_left, _right, validator))
return false;
}
}
return true;
}
module.exports = everyCombination;

10
node_modules/clean-css/lib/properties/has-inherit.js generated vendored Normal file
View File

@@ -0,0 +1,10 @@
function hasInherit(property) {
for (var i = property.value.length - 1; i >= 0; i--) {
if (property.value[i][0] == 'inherit')
return true;
}
return false;
}
module.exports = hasInherit;

View File

@@ -0,0 +1,10 @@
function InvalidPropertyError(message) {
this.name = 'InvalidPropertyError';
this.message = message;
this.stack = (new Error()).stack;
}
InvalidPropertyError.prototype = Object.create(Error.prototype);
InvalidPropertyError.prototype.constructor = InvalidPropertyError;
module.exports = InvalidPropertyError;

215
node_modules/clean-css/lib/properties/optimizer.js generated vendored Normal file
View File

@@ -0,0 +1,215 @@
var compactable = require('./compactable');
var wrapForOptimizing = require('./wrap-for-optimizing').all;
var populateComponents = require('./populate-components');
var compactOverrides = require('./override-compactor');
var compactShorthands = require('./shorthand-compactor');
var removeUnused = require('./remove-unused');
var restoreFromOptimizing = require('./restore-from-optimizing');
var stringifyProperty = require('../stringifier/one-time').property;
var shorthands = {
'animation-delay': ['animation'],
'animation-direction': ['animation'],
'animation-duration': ['animation'],
'animation-fill-mode': ['animation'],
'animation-iteration-count': ['animation'],
'animation-name': ['animation'],
'animation-play-state': ['animation'],
'animation-timing-function': ['animation'],
'-moz-animation-delay': ['-moz-animation'],
'-moz-animation-direction': ['-moz-animation'],
'-moz-animation-duration': ['-moz-animation'],
'-moz-animation-fill-mode': ['-moz-animation'],
'-moz-animation-iteration-count': ['-moz-animation'],
'-moz-animation-name': ['-moz-animation'],
'-moz-animation-play-state': ['-moz-animation'],
'-moz-animation-timing-function': ['-moz-animation'],
'-o-animation-delay': ['-o-animation'],
'-o-animation-direction': ['-o-animation'],
'-o-animation-duration': ['-o-animation'],
'-o-animation-fill-mode': ['-o-animation'],
'-o-animation-iteration-count': ['-o-animation'],
'-o-animation-name': ['-o-animation'],
'-o-animation-play-state': ['-o-animation'],
'-o-animation-timing-function': ['-o-animation'],
'-webkit-animation-delay': ['-webkit-animation'],
'-webkit-animation-direction': ['-webkit-animation'],
'-webkit-animation-duration': ['-webkit-animation'],
'-webkit-animation-fill-mode': ['-webkit-animation'],
'-webkit-animation-iteration-count': ['-webkit-animation'],
'-webkit-animation-name': ['-webkit-animation'],
'-webkit-animation-play-state': ['-webkit-animation'],
'-webkit-animation-timing-function': ['-webkit-animation'],
'border-color': ['border'],
'border-style': ['border'],
'border-width': ['border'],
'border-bottom': ['border'],
'border-bottom-color': ['border-bottom', 'border-color', 'border'],
'border-bottom-style': ['border-bottom', 'border-style', 'border'],
'border-bottom-width': ['border-bottom', 'border-width', 'border'],
'border-left': ['border'],
'border-left-color': ['border-left', 'border-color', 'border'],
'border-left-style': ['border-left', 'border-style', 'border'],
'border-left-width': ['border-left', 'border-width', 'border'],
'border-right': ['border'],
'border-right-color': ['border-right', 'border-color', 'border'],
'border-right-style': ['border-right', 'border-style', 'border'],
'border-right-width': ['border-right', 'border-width', 'border'],
'border-top': ['border'],
'border-top-color': ['border-top', 'border-color', 'border'],
'border-top-style': ['border-top', 'border-style', 'border'],
'border-top-width': ['border-top', 'border-width', 'border'],
'font-family': ['font'],
'font-size': ['font'],
'font-style': ['font'],
'font-variant': ['font'],
'font-weight': ['font'],
'transition-delay': ['transition'],
'transition-duration': ['transition'],
'transition-property': ['transition'],
'transition-timing-function': ['transition'],
'-moz-transition-delay': ['-moz-transition'],
'-moz-transition-duration': ['-moz-transition'],
'-moz-transition-property': ['-moz-transition'],
'-moz-transition-timing-function': ['-moz-transition'],
'-o-transition-delay': ['-o-transition'],
'-o-transition-duration': ['-o-transition'],
'-o-transition-property': ['-o-transition'],
'-o-transition-timing-function': ['-o-transition'],
'-webkit-transition-delay': ['-webkit-transition'],
'-webkit-transition-duration': ['-webkit-transition'],
'-webkit-transition-property': ['-webkit-transition'],
'-webkit-transition-timing-function': ['-webkit-transition']
};
function _optimize(properties, mergeAdjacent, aggressiveMerging, validator) {
var overrideMapping = {};
var lastName = null;
var lastProperty;
var j;
function mergeablePosition(position) {
if (mergeAdjacent === false || mergeAdjacent === true)
return mergeAdjacent;
return mergeAdjacent.indexOf(position) > -1;
}
function sameValue(position) {
var left = properties[position - 1];
var right = properties[position];
return stringifyProperty(left.all, left.position) == stringifyProperty(right.all, right.position);
}
propertyLoop:
for (var position = 0, total = properties.length; position < total; position++) {
var property = properties[position];
var _name = (property.name == '-ms-filter' || property.name == 'filter') ?
(lastName == 'background' || lastName == 'background-image' ? lastName : property.name) :
property.name;
var isImportant = property.important;
var isHack = property.hack;
if (property.unused)
continue;
if (position > 0 && lastProperty && _name == lastName && isImportant == lastProperty.important && isHack == lastProperty.hack && sameValue(position) && !lastProperty.unused) {
property.unused = true;
continue;
}
// comment is necessary - we assume that if two properties are one after another
// then it is intentional way of redefining property which may not be widely supported
// e.g. a{display:inline-block;display:-moz-inline-box}
// however if `mergeablePosition` yields true then the rule does not apply
// (e.g merging two adjacent selectors: `a{display:block}a{display:block}`)
if (_name in overrideMapping && (aggressiveMerging && _name != lastName || mergeablePosition(position))) {
var toOverridePositions = overrideMapping[_name];
var canOverride = compactable[_name] && compactable[_name].canOverride;
var anyRemoved = false;
for (j = toOverridePositions.length - 1; j >= 0; j--) {
var toRemove = properties[toOverridePositions[j]];
var longhandToShorthand = toRemove.name != _name;
var wasImportant = toRemove.important;
var wasHack = toRemove.hack;
if (toRemove.unused)
continue;
if (longhandToShorthand && wasImportant)
continue;
if (!wasImportant && (wasHack && !isHack || !wasHack && isHack))
continue;
if (wasImportant && (isHack == 'star' || isHack == 'underscore'))
continue;
if (!wasHack && !isHack && !longhandToShorthand && canOverride && !canOverride(toRemove, property, validator))
continue;
if (wasImportant && !isImportant || wasImportant && isHack) {
property.unused = true;
lastProperty = property;
continue propertyLoop;
} else {
anyRemoved = true;
toRemove.unused = true;
}
}
if (anyRemoved) {
position = -1;
lastProperty = null;
lastName = null;
overrideMapping = {};
continue;
}
} else {
overrideMapping[_name] = overrideMapping[_name] || [];
overrideMapping[_name].push(position);
// TODO: to be removed with
// certain shorthand (see values of `shorthands`) should trigger removal of
// longhand properties (see keys of `shorthands`)
var _shorthands = shorthands[_name];
if (_shorthands) {
for (j = _shorthands.length - 1; j >= 0; j--) {
var shorthand = _shorthands[j];
overrideMapping[shorthand] = overrideMapping[shorthand] || [];
overrideMapping[shorthand].push(position);
}
}
}
lastName = _name;
lastProperty = property;
}
}
function optimize(selector, properties, mergeAdjacent, withCompacting, options, context) {
var validator = context.validator;
var warnings = context.warnings;
var _properties = wrapForOptimizing(properties);
populateComponents(_properties, validator, warnings);
_optimize(_properties, mergeAdjacent, options.aggressiveMerging, validator);
for (var i = 0, l = _properties.length; i < l; i++) {
var _property = _properties[i];
if (_property.variable && _property.block)
optimize(selector, _property.value[0], mergeAdjacent, withCompacting, options, context);
}
if (withCompacting && options.shorthandCompacting) {
compactOverrides(_properties, options.compatibility, validator);
compactShorthands(_properties, options.sourceMap, validator);
}
restoreFromOptimizing(_properties);
removeUnused(_properties);
}
module.exports = optimize;

View File

@@ -0,0 +1,384 @@
var canOverride = require('./can-override');
var compactable = require('./compactable');
var deepClone = require('./clone').deep;
var shallowClone = require('./clone').shallow;
var hasInherit = require('./has-inherit');
var restoreFromOptimizing = require('./restore-from-optimizing');
var everyCombination = require('./every-combination');
var sameVendorPrefixesIn = require('./vendor-prefixes').same;
var stringifyProperty = require('../stringifier/one-time').property;
var MULTIPLEX_SEPARATOR = ',';
// Used when searching for a component that matches property
function nameMatchFilter(to) {
return function (property) {
return to.name === property.name;
};
}
function wouldBreakCompatibility(property, validator) {
for (var i = 0; i < property.components.length; i++) {
var component = property.components[i];
var descriptor = compactable[component.name];
var canOverride = descriptor && descriptor.canOverride || canOverride.sameValue;
var _component = shallowClone(component);
_component.value = [[descriptor.defaultValue]];
if (!canOverride(_component, component, validator))
return true;
}
return false;
}
function isComponentOf(shorthand, longhand) {
return compactable[shorthand.name].components.indexOf(longhand.name) > -1;
}
function overrideIntoMultiplex(property, by) {
by.unused = true;
turnIntoMultiplex(by, multiplexSize(property));
property.value = by.value;
}
function overrideByMultiplex(property, by) {
by.unused = true;
property.multiplex = true;
property.value = by.value;
}
function overrideSimple(property, by) {
by.unused = true;
property.value = by.value;
}
function override(property, by) {
if (by.multiplex)
overrideByMultiplex(property, by);
else if (property.multiplex)
overrideIntoMultiplex(property, by);
else
overrideSimple(property, by);
}
function overrideShorthand(property, by) {
by.unused = true;
for (var i = 0, l = property.components.length; i < l; i++) {
override(property.components[i], by.components[i], property.multiplex);
}
}
function turnIntoMultiplex(property, size) {
property.multiplex = true;
for (var i = 0, l = property.components.length; i < l; i++) {
var component = property.components[i];
if (component.multiplex)
continue;
var value = component.value.slice(0);
for (var j = 1; j < size; j++) {
component.value.push([MULTIPLEX_SEPARATOR]);
Array.prototype.push.apply(component.value, value);
}
}
}
function multiplexSize(component) {
var size = 0;
for (var i = 0, l = component.value.length; i < l; i++) {
if (component.value[i][0] == MULTIPLEX_SEPARATOR)
size++;
}
return size + 1;
}
function lengthOf(property) {
var fakeAsArray = [[property.name]].concat(property.value);
return stringifyProperty([fakeAsArray], 0).length;
}
function moreSameShorthands(properties, startAt, name) {
// Since we run the main loop in `compactOverrides` backwards, at this point some
// properties may not be marked as unused.
// We should consider reverting the order if possible
var count = 0;
for (var i = startAt; i >= 0; i--) {
if (properties[i].name == name && !properties[i].unused)
count++;
if (count > 1)
break;
}
return count > 1;
}
function overridingFunction(shorthand, validator) {
for (var i = 0, l = shorthand.components.length; i < l; i++) {
if (anyValue(validator.isValidFunction, shorthand.components[i]))
return true;
}
return false;
}
function anyValue(fn, property) {
for (var i = 0, l = property.value.length; i < l; i++) {
if (property.value[i][0] == MULTIPLEX_SEPARATOR)
continue;
if (fn(property.value[i][0]))
return true;
}
return false;
}
function wouldResultInLongerValue(left, right) {
if (!left.multiplex && !right.multiplex || left.multiplex && right.multiplex)
return false;
var multiplex = left.multiplex ? left : right;
var simple = left.multiplex ? right : left;
var component;
var multiplexClone = deepClone(multiplex);
restoreFromOptimizing([multiplexClone]);
var simpleClone = deepClone(simple);
restoreFromOptimizing([simpleClone]);
var lengthBefore = lengthOf(multiplexClone) + 1 + lengthOf(simpleClone);
if (left.multiplex) {
component = multiplexClone.components.filter(nameMatchFilter(simpleClone))[0];
overrideIntoMultiplex(component, simpleClone);
} else {
component = simpleClone.components.filter(nameMatchFilter(multiplexClone))[0];
turnIntoMultiplex(simpleClone, multiplexSize(multiplexClone));
overrideByMultiplex(component, multiplexClone);
}
restoreFromOptimizing([simpleClone]);
var lengthAfter = lengthOf(simpleClone);
return lengthBefore < lengthAfter;
}
function isCompactable(property) {
return property.name in compactable;
}
function noneOverrideHack(left, right) {
return !left.multiplex &&
(left.name == 'background' || left.name == 'background-image') &&
right.multiplex &&
(right.name == 'background' || right.name == 'background-image') &&
anyLayerIsNone(right.value);
}
function anyLayerIsNone(values) {
var layers = intoLayers(values);
for (var i = 0, l = layers.length; i < l; i++) {
if (layers[i].length == 1 && layers[i][0][0] == 'none')
return true;
}
return false;
}
function intoLayers(values) {
var layers = [];
for (var i = 0, layer = [], l = values.length; i < l; i++) {
var value = values[i];
if (value[0] == MULTIPLEX_SEPARATOR) {
layers.push(layer);
layer = [];
} else {
layer.push(value);
}
}
layers.push(layer);
return layers;
}
function compactOverrides(properties, compatibility, validator) {
var mayOverride, right, left, component;
var i, j, k;
propertyLoop:
for (i = properties.length - 1; i >= 0; i--) {
right = properties[i];
if (!isCompactable(right))
continue;
if (right.variable)
continue;
mayOverride = compactable[right.name].canOverride || canOverride.sameValue;
for (j = i - 1; j >= 0; j--) {
left = properties[j];
if (!isCompactable(left))
continue;
if (left.variable)
continue;
if (left.unused || right.unused)
continue;
if (left.hack && !right.hack || !left.hack && right.hack)
continue;
if (hasInherit(right))
continue;
if (noneOverrideHack(left, right))
continue;
if (!left.shorthand && right.shorthand && isComponentOf(right, left)) {
// maybe `left` can be overridden by `right` which is a shorthand?
if (!right.important && left.important)
continue;
if (!sameVendorPrefixesIn([left], right.components))
continue;
if (!anyValue(validator.isValidFunction, left) && overridingFunction(right, validator))
continue;
component = right.components.filter(nameMatchFilter(left))[0];
mayOverride = (compactable[left.name] && compactable[left.name].canOverride) || canOverride.sameValue;
if (everyCombination(mayOverride, left, component, validator)) {
left.unused = true;
}
} else if (left.shorthand && !right.shorthand && isComponentOf(left, right)) {
// maybe `right` can be pulled into `left` which is a shorthand?
if (right.important && !left.important)
continue;
if (!right.important && left.important) {
right.unused = true;
continue;
}
// Pending more clever algorithm in #527
if (moreSameShorthands(properties, i - 1, left.name))
continue;
if (overridingFunction(left, validator))
continue;
component = left.components.filter(nameMatchFilter(right))[0];
if (everyCombination(mayOverride, component, right, validator)) {
var disabledBackgroundMerging =
!compatibility.properties.backgroundClipMerging && component.name.indexOf('background-clip') > -1 ||
!compatibility.properties.backgroundOriginMerging && component.name.indexOf('background-origin') > -1 ||
!compatibility.properties.backgroundSizeMerging && component.name.indexOf('background-size') > -1;
var nonMergeableValue = compactable[right.name].nonMergeableValue === right.value[0][0];
if (disabledBackgroundMerging || nonMergeableValue)
continue;
if (!compatibility.properties.merging && wouldBreakCompatibility(left, validator))
continue;
if (component.value[0][0] != right.value[0][0] && (hasInherit(left) || hasInherit(right)))
continue;
if (wouldResultInLongerValue(left, right))
continue;
if (!left.multiplex && right.multiplex)
turnIntoMultiplex(left, multiplexSize(right));
override(component, right);
left.dirty = true;
}
} else if (left.shorthand && right.shorthand && left.name == right.name) {
// merge if all components can be merged
if (!left.multiplex && right.multiplex)
continue;
if (!right.important && left.important) {
right.unused = true;
continue propertyLoop;
}
if (right.important && !left.important) {
left.unused = true;
continue;
}
for (k = left.components.length - 1; k >= 0; k--) {
var leftComponent = left.components[k];
var rightComponent = right.components[k];
mayOverride = compactable[leftComponent.name].canOverride || canOverride.sameValue;
if (!everyCombination(mayOverride, leftComponent, rightComponent, validator))
continue propertyLoop;
if (!everyCombination(canOverride.twoOptionalFunctions, leftComponent, rightComponent, validator) && validator.isValidFunction(rightComponent))
continue propertyLoop;
}
overrideShorthand(left, right);
left.dirty = true;
} else if (left.shorthand && right.shorthand && isComponentOf(left, right)) {
// border is a shorthand but any of its components is a shorthand too
if (!left.important && right.important)
continue;
component = left.components.filter(nameMatchFilter(right))[0];
mayOverride = compactable[right.name].canOverride || canOverride.sameValue;
if (!everyCombination(mayOverride, component, right, validator))
continue;
if (left.important && !right.important) {
right.unused = true;
continue;
}
var rightRestored = compactable[right.name].restore(right, compactable);
if (rightRestored.length > 1)
continue;
component = left.components.filter(nameMatchFilter(right))[0];
override(component, right);
right.dirty = true;
} else if (left.name == right.name) {
// two non-shorthands should be merged based on understandability
if (left.important && !right.important) {
right.unused = true;
continue;
}
mayOverride = compactable[right.name].canOverride || canOverride.sameValue;
if (!everyCombination(mayOverride, left, right, validator))
continue;
left.unused = true;
}
}
}
}
module.exports = compactOverrides;

View File

@@ -0,0 +1,32 @@
var compactable = require('./compactable');
var InvalidPropertyError = require('./invalid-property-error');
function populateComponents(properties, validator, warnings) {
for (var i = properties.length - 1; i >= 0; i--) {
var property = properties[i];
var descriptor = compactable[property.name];
if (descriptor && descriptor.shorthand) {
property.shorthand = true;
property.dirty = true;
try {
property.components = descriptor.breakUp(property, compactable, validator);
} catch (e) {
if (e instanceof InvalidPropertyError) {
property.components = []; // this will set property.unused to true below
warnings.push(e.message);
} else {
throw e;
}
}
if (property.components.length > 0)
property.multiplex = property.components[0].multiplex;
else
property.unused = true;
}
}
}
module.exports = populateComponents;

10
node_modules/clean-css/lib/properties/remove-unused.js generated vendored Normal file
View File

@@ -0,0 +1,10 @@
function removeUnused(properties) {
for (var i = properties.length - 1; i >= 0; i--) {
var property = properties[i];
if (property.unused)
property.all.splice(property.position, 1);
}
}
module.exports = removeUnused;

View File

@@ -0,0 +1,60 @@
var compactable = require('./compactable');
var BACKSLASH_HACK = '\\9';
var IMPORTANT_TOKEN = '!important';
var STAR_HACK = '*';
var UNDERSCORE_HACK = '_';
var BANG_HACK = '!ie';
function restoreImportant(property) {
property.value[property.value.length - 1][0] += IMPORTANT_TOKEN;
}
function restoreHack(property) {
if (property.hack == 'underscore')
property.name = UNDERSCORE_HACK + property.name;
else if (property.hack == 'star')
property.name = STAR_HACK + property.name;
else if (property.hack == 'backslash')
property.value[property.value.length - 1][0] += BACKSLASH_HACK;
else if (property.hack == 'bang')
property.value[property.value.length - 1][0] += ' ' + BANG_HACK;
}
function restoreFromOptimizing(properties, simpleMode) {
for (var i = properties.length - 1; i >= 0; i--) {
var property = properties[i];
var descriptor = compactable[property.name];
var restored;
if (property.unused)
continue;
if (!property.dirty && !property.important && !property.hack)
continue;
if (!simpleMode && descriptor && descriptor.shorthand) {
restored = descriptor.restore(property, compactable);
property.value = restored;
} else {
restored = property.value;
}
if (property.important)
restoreImportant(property);
if (property.hack)
restoreHack(property);
if (!('all' in property))
continue;
var current = property.all[property.position];
current[0][0] = property.name;
current.splice(1, current.length - 1);
Array.prototype.push.apply(current, restored);
}
}
module.exports = restoreFromOptimizing;

232
node_modules/clean-css/lib/properties/restore.js generated vendored Normal file
View File

@@ -0,0 +1,232 @@
var shallowClone = require('./clone').shallow;
var MULTIPLEX_SEPARATOR = ',';
var SIZE_POSITION_SEPARATOR = '/';
function isInheritOnly(values) {
for (var i = 0, l = values.length; i < l; i++) {
var value = values[i][0];
if (value != 'inherit' && value != MULTIPLEX_SEPARATOR && value != SIZE_POSITION_SEPARATOR)
return false;
}
return true;
}
function background(property, compactable, lastInMultiplex) {
var components = property.components;
var restored = [];
var needsOne, needsBoth;
function restoreValue(component) {
Array.prototype.unshift.apply(restored, component.value);
}
function isDefaultValue(component) {
var descriptor = compactable[component.name];
if (descriptor.doubleValues) {
if (descriptor.defaultValue.length == 1)
return component.value[0][0] == descriptor.defaultValue[0] && (component.value[1] ? component.value[1][0] == descriptor.defaultValue[0] : true);
else
return component.value[0][0] == descriptor.defaultValue[0] && (component.value[1] ? component.value[1][0] : component.value[0][0]) == descriptor.defaultValue[1];
} else {
return component.value[0][0] == descriptor.defaultValue;
}
}
for (var i = components.length - 1; i >= 0; i--) {
var component = components[i];
var isDefault = isDefaultValue(component);
if (component.name == 'background-clip') {
var originComponent = components[i - 1];
var isOriginDefault = isDefaultValue(originComponent);
needsOne = component.value[0][0] == originComponent.value[0][0];
needsBoth = !needsOne && (
(isOriginDefault && !isDefault) ||
(!isOriginDefault && !isDefault) ||
(!isOriginDefault && isDefault && component.value[0][0] != originComponent.value[0][0]));
if (needsOne) {
restoreValue(originComponent);
} else if (needsBoth) {
restoreValue(component);
restoreValue(originComponent);
}
i--;
} else if (component.name == 'background-size') {
var positionComponent = components[i - 1];
var isPositionDefault = isDefaultValue(positionComponent);
needsOne = !isPositionDefault && isDefault;
needsBoth = !needsOne &&
(isPositionDefault && !isDefault || !isPositionDefault && !isDefault);
if (needsOne) {
restoreValue(positionComponent);
} else if (needsBoth) {
restoreValue(component);
restored.unshift([SIZE_POSITION_SEPARATOR]);
restoreValue(positionComponent);
} else if (positionComponent.value.length == 1) {
restoreValue(positionComponent);
}
i--;
} else {
if (isDefault || compactable[component.name].multiplexLastOnly && !lastInMultiplex)
continue;
restoreValue(component);
}
}
if (restored.length === 0 && property.value.length == 1 && property.value[0][0] == '0')
restored.push(property.value[0]);
if (restored.length === 0)
restored.push([compactable[property.name].defaultValue]);
if (isInheritOnly(restored))
return [restored[0]];
return restored;
}
function borderRadius(property, compactable) {
if (property.multiplex) {
var horizontal = shallowClone(property);
var vertical = shallowClone(property);
for (var i = 0; i < 4; i++) {
var component = property.components[i];
var horizontalComponent = shallowClone(property);
horizontalComponent.value = [component.value[0]];
horizontal.components.push(horizontalComponent);
var verticalComponent = shallowClone(property);
// FIXME: only shorthand compactor (see breakup#borderRadius) knows that border radius
// longhands have two values, whereas tokenizer does not care about populating 2nd value
// if it's missing, hence this fallback
verticalComponent.value = [component.value[1] || component.value[0]];
vertical.components.push(verticalComponent);
}
var horizontalValues = fourValues(horizontal, compactable);
var verticalValues = fourValues(vertical, compactable);
if (horizontalValues.length == verticalValues.length &&
horizontalValues[0][0] == verticalValues[0][0] &&
(horizontalValues.length > 1 ? horizontalValues[1][0] == verticalValues[1][0] : true) &&
(horizontalValues.length > 2 ? horizontalValues[2][0] == verticalValues[2][0] : true) &&
(horizontalValues.length > 3 ? horizontalValues[3][0] == verticalValues[3][0] : true)) {
return horizontalValues;
} else {
return horizontalValues.concat([['/']]).concat(verticalValues);
}
} else {
return fourValues(property, compactable);
}
}
function fourValues(property) {
var components = property.components;
var value1 = components[0].value[0];
var value2 = components[1].value[0];
var value3 = components[2].value[0];
var value4 = components[3].value[0];
if (value1[0] == value2[0] && value1[0] == value3[0] && value1[0] == value4[0]) {
return [value1];
} else if (value1[0] == value3[0] && value2[0] == value4[0]) {
return [value1, value2];
} else if (value2[0] == value4[0]) {
return [value1, value2, value3];
} else {
return [value1, value2, value3, value4];
}
}
function multiplex(restoreWith) {
return function (property, compactable) {
if (!property.multiplex)
return restoreWith(property, compactable, true);
var multiplexSize = 0;
var restored = [];
var componentMultiplexSoFar = {};
var i, l;
// At this point we don't know what's the multiplex size, e.g. how many background layers are there
for (i = 0, l = property.components[0].value.length; i < l; i++) {
if (property.components[0].value[i][0] == MULTIPLEX_SEPARATOR)
multiplexSize++;
}
for (i = 0; i <= multiplexSize; i++) {
var _property = shallowClone(property);
// We split multiplex into parts and restore them one by one
for (var j = 0, m = property.components.length; j < m; j++) {
var componentToClone = property.components[j];
var _component = shallowClone(componentToClone);
_property.components.push(_component);
// The trick is some properties has more than one value, so we iterate over values looking for
// a multiplex separator - a comma
for (var k = componentMultiplexSoFar[_component.name] || 0, n = componentToClone.value.length; k < n; k++) {
if (componentToClone.value[k][0] == MULTIPLEX_SEPARATOR) {
componentMultiplexSoFar[_component.name] = k + 1;
break;
}
_component.value.push(componentToClone.value[k]);
}
}
// No we can restore shorthand value
var lastInMultiplex = i == multiplexSize;
var _restored = restoreWith(_property, compactable, lastInMultiplex);
Array.prototype.push.apply(restored, _restored);
if (i < multiplexSize)
restored.push([',']);
}
return restored;
};
}
function withoutDefaults(property, compactable) {
var components = property.components;
var restored = [];
for (var i = components.length - 1; i >= 0; i--) {
var component = components[i];
var descriptor = compactable[component.name];
if (component.value[0][0] != descriptor.defaultValue)
restored.unshift(component.value[0]);
}
if (restored.length === 0)
restored.push([compactable[property.name].defaultValue]);
if (isInheritOnly(restored))
return [restored[0]];
return restored;
}
module.exports = {
background: background,
borderRadius: borderRadius,
fourValues: fourValues,
multiplex: multiplex,
withoutDefaults: withoutDefaults
};

View File

@@ -0,0 +1,134 @@
var compactable = require('./compactable');
var deepClone = require('./clone').deep;
var hasInherit = require('./has-inherit');
var populateComponents = require('./populate-components');
var wrapSingle = require('./wrap-for-optimizing').single;
var everyCombination = require('./every-combination');
function mixedImportance(components) {
var important;
for (var name in components) {
if (undefined !== important && components[name].important != important)
return true;
important = components[name].important;
}
return false;
}
function componentSourceMaps(components) {
var sourceMapping = [];
for (var name in components) {
var component = components[name];
var originalValue = component.all[component.position];
var mapping = originalValue[0][originalValue[0].length - 1];
if (Array.isArray(mapping))
Array.prototype.push.apply(sourceMapping, mapping);
}
return sourceMapping;
}
function replaceWithShorthand(properties, candidateComponents, name, sourceMaps, validator) {
var descriptor = compactable[name];
var newValuePlaceholder = [[name], [descriptor.defaultValue]];
var all;
var newProperty = wrapSingle(newValuePlaceholder);
newProperty.shorthand = true;
newProperty.dirty = true;
populateComponents([newProperty], validator, []);
for (var i = 0, l = descriptor.components.length; i < l; i++) {
var component = candidateComponents[descriptor.components[i]];
var canOverride = compactable[component.name].canOverride;
if (hasInherit(component))
return;
if (!everyCombination(canOverride, newProperty.components[i], component, validator))
return;
newProperty.components[i] = deepClone(component);
newProperty.important = component.important;
all = component.all;
}
for (var componentName in candidateComponents) {
candidateComponents[componentName].unused = true;
}
if (sourceMaps) {
var sourceMapping = componentSourceMaps(candidateComponents);
if (sourceMapping.length > 0)
newValuePlaceholder[0].push(sourceMapping);
}
newProperty.position = all.length;
newProperty.all = all;
newProperty.all.push(newValuePlaceholder);
properties.push(newProperty);
}
function invalidateOrCompact(properties, position, candidates, sourceMaps, validator) {
var property = properties[position];
for (var name in candidates) {
if (undefined !== property && name == property.name)
continue;
var descriptor = compactable[name];
var candidateComponents = candidates[name];
if (descriptor.components.length > Object.keys(candidateComponents).length) {
delete candidates[name];
continue;
}
if (mixedImportance(candidateComponents))
continue;
replaceWithShorthand(properties, candidateComponents, name, sourceMaps, validator);
}
}
function compactShortands(properties, sourceMaps, validator) {
var candidates = {};
if (properties.length < 3)
return;
for (var i = 0, l = properties.length; i < l; i++) {
var property = properties[i];
if (property.unused)
continue;
if (property.hack)
continue;
if (property.variable)
continue;
var descriptor = compactable[property.name];
if (!descriptor || !descriptor.componentOf)
continue;
if (property.shorthand) {
invalidateOrCompact(properties, i, candidates, sourceMaps, validator);
} else {
var componentOf = descriptor.componentOf;
candidates[componentOf] = candidates[componentOf] || {};
candidates[componentOf][property.name] = property;
}
}
invalidateOrCompact(properties, i, candidates, sourceMaps, validator);
}
module.exports = compactShortands;

197
node_modules/clean-css/lib/properties/validator.js generated vendored Normal file
View File

@@ -0,0 +1,197 @@
// Validates various CSS property values
var split = require('../utils/split');
var widthKeywords = ['thin', 'thick', 'medium', 'inherit', 'initial'];
var allUnits = ['px', '%', 'em', 'in', 'cm', 'mm', 'ex', 'pt', 'pc', 'ch', 'rem', 'vh', 'vm', 'vmin', 'vmax', 'vw'];
var cssUnitRegexStr = '(\\-?\\.?\\d+\\.?\\d*(' + allUnits.join('|') + '|)|auto|inherit)';
var cssCalcRegexStr = '(\\-moz\\-|\\-webkit\\-)?calc\\([^\\)]+\\)';
var cssFunctionNoVendorRegexStr = '[A-Z]+(\\-|[A-Z]|[0-9])+\\(.*?\\)';
var cssFunctionVendorRegexStr = '\\-(\\-|[A-Z]|[0-9])+\\(.*?\\)';
var cssVariableRegexStr = 'var\\(\\-\\-[^\\)]+\\)';
var cssFunctionAnyRegexStr = '(' + cssVariableRegexStr + '|' + cssFunctionNoVendorRegexStr + '|' + cssFunctionVendorRegexStr + ')';
var cssUnitOrCalcRegexStr = '(' + cssUnitRegexStr + '|' + cssCalcRegexStr + ')';
var cssUnitAnyRegexStr = '(none|' + widthKeywords.join('|') + '|' + cssUnitRegexStr + '|' + cssVariableRegexStr + '|' + cssFunctionNoVendorRegexStr + '|' + cssFunctionVendorRegexStr + ')';
var cssFunctionNoVendorRegex = new RegExp('^' + cssFunctionNoVendorRegexStr + '$', 'i');
var cssFunctionVendorRegex = new RegExp('^' + cssFunctionVendorRegexStr + '$', 'i');
var cssVariableRegex = new RegExp('^' + cssVariableRegexStr + '$', 'i');
var cssFunctionAnyRegex = new RegExp('^' + cssFunctionAnyRegexStr + '$', 'i');
var cssUnitRegex = new RegExp('^' + cssUnitRegexStr + '$', 'i');
var cssUnitOrCalcRegex = new RegExp('^' + cssUnitOrCalcRegexStr + '$', 'i');
var cssUnitAnyRegex = new RegExp('^' + cssUnitAnyRegexStr + '$', 'i');
var backgroundRepeatKeywords = ['repeat', 'no-repeat', 'repeat-x', 'repeat-y', 'inherit'];
var backgroundAttachmentKeywords = ['inherit', 'scroll', 'fixed', 'local'];
var backgroundPositionKeywords = ['center', 'top', 'bottom', 'left', 'right'];
var backgroundSizeKeywords = ['contain', 'cover'];
var backgroundBoxKeywords = ['border-box', 'content-box', 'padding-box'];
var styleKeywords = ['auto', 'inherit', 'hidden', 'none', 'dotted', 'dashed', 'solid', 'double', 'groove', 'ridge', 'inset', 'outset'];
var listStyleTypeKeywords = ['armenian', 'circle', 'cjk-ideographic', 'decimal', 'decimal-leading-zero', 'disc', 'georgian', 'hebrew', 'hiragana', 'hiragana-iroha', 'inherit', 'katakana', 'katakana-iroha', 'lower-alpha', 'lower-greek', 'lower-latin', 'lower-roman', 'none', 'square', 'upper-alpha', 'upper-latin', 'upper-roman'];
var listStylePositionKeywords = ['inside', 'outside', 'inherit'];
function Validator(compatibility) {
var validUnits = allUnits.slice(0).filter(function (value) {
return !(value in compatibility.units) || compatibility.units[value] === true;
});
var compatibleCssUnitRegexStr = '(\\-?\\.?\\d+\\.?\\d*(' + validUnits.join('|') + '|)|auto|inherit)';
this.compatibleCssUnitRegex = new RegExp('^' + compatibleCssUnitRegexStr + '$', 'i');
this.compatibleCssUnitAnyRegex = new RegExp('^(none|' + widthKeywords.join('|') + '|' + compatibleCssUnitRegexStr + '|' + cssVariableRegexStr + '|' + cssFunctionNoVendorRegexStr + '|' + cssFunctionVendorRegexStr + ')$', 'i');
this.colorOpacity = compatibility.colors.opacity;
}
Validator.prototype.isValidHexColor = function (s) {
return (s.length === 4 || s.length === 7) && s[0] === '#';
};
Validator.prototype.isValidRgbaColor = function (s) {
s = s.split(' ').join('');
return s.length > 0 && s.indexOf('rgba(') === 0 && s.indexOf(')') === s.length - 1;
};
Validator.prototype.isValidHslaColor = function (s) {
s = s.split(' ').join('');
return s.length > 0 && s.indexOf('hsla(') === 0 && s.indexOf(')') === s.length - 1;
};
Validator.prototype.isValidNamedColor = function (s) {
// We don't really check if it's a valid color value, but allow any letters in it
return s !== 'auto' && (s === 'transparent' || s === 'inherit' || /^[a-zA-Z]+$/.test(s));
};
Validator.prototype.isValidVariable = function (s) {
return cssVariableRegex.test(s);
};
Validator.prototype.isValidColor = function (s) {
return this.isValidNamedColor(s) ||
this.isValidColorValue(s) ||
this.isValidVariable(s) ||
this.isValidVendorPrefixedValue(s);
};
Validator.prototype.isValidColorValue = function (s) {
return this.isValidHexColor(s) ||
this.isValidRgbaColor(s) ||
this.isValidHslaColor(s);
};
Validator.prototype.isValidUrl = function (s) {
// NOTE: at this point all URLs are replaced with placeholders by clean-css, so we check for those placeholders
return s.indexOf('__ESCAPED_URL_CLEAN_CSS') === 0;
};
Validator.prototype.isValidUnit = function (s) {
return cssUnitAnyRegex.test(s);
};
Validator.prototype.isValidUnitWithoutFunction = function (s) {
return cssUnitRegex.test(s);
};
Validator.prototype.isValidAndCompatibleUnit = function (s) {
return this.compatibleCssUnitAnyRegex.test(s);
};
Validator.prototype.isValidAndCompatibleUnitWithoutFunction = function (s) {
return this.compatibleCssUnitRegex.test(s);
};
Validator.prototype.isValidFunctionWithoutVendorPrefix = function (s) {
return cssFunctionNoVendorRegex.test(s);
};
Validator.prototype.isValidFunctionWithVendorPrefix = function (s) {
return cssFunctionVendorRegex.test(s);
};
Validator.prototype.isValidFunction = function (s) {
return cssFunctionAnyRegex.test(s);
};
Validator.prototype.isValidBackgroundRepeat = function (s) {
return backgroundRepeatKeywords.indexOf(s) >= 0 || this.isValidVariable(s);
};
Validator.prototype.isValidBackgroundAttachment = function (s) {
return backgroundAttachmentKeywords.indexOf(s) >= 0 || this.isValidVariable(s);
};
Validator.prototype.isValidBackgroundBox = function (s) {
return backgroundBoxKeywords.indexOf(s) >= 0 || this.isValidVariable(s);
};
Validator.prototype.isValidBackgroundPositionPart = function (s) {
return backgroundPositionKeywords.indexOf(s) >= 0 || cssUnitOrCalcRegex.test(s) || this.isValidVariable(s);
};
Validator.prototype.isValidBackgroundPosition = function (s) {
if (s === 'inherit')
return true;
var parts = s.split(' ');
for (var i = 0, l = parts.length; i < l; i++) {
if (parts[i] === '')
continue;
if (this.isValidBackgroundPositionPart(parts[i]) || this.isValidVariable(parts[i]))
continue;
return false;
}
return true;
};
Validator.prototype.isValidBackgroundSizePart = function (s) {
return backgroundSizeKeywords.indexOf(s) >= 0 || cssUnitRegex.test(s) || this.isValidVariable(s);
};
Validator.prototype.isValidBackgroundPositionAndSize = function (s) {
if (s.indexOf('/') < 0)
return false;
var twoParts = split(s, '/');
return this.isValidBackgroundSizePart(twoParts.pop()) && this.isValidBackgroundPositionPart(twoParts.pop());
};
Validator.prototype.isValidListStyleType = function (s) {
return listStyleTypeKeywords.indexOf(s) >= 0 || this.isValidVariable(s);
};
Validator.prototype.isValidListStylePosition = function (s) {
return listStylePositionKeywords.indexOf(s) >= 0 || this.isValidVariable(s);
};
Validator.prototype.isValidStyle = function (s) {
return this.isValidStyleKeyword(s) || this.isValidVariable(s);
};
Validator.prototype.isValidStyleKeyword = function (s) {
return styleKeywords.indexOf(s) >= 0;
};
Validator.prototype.isValidWidth = function (s) {
return this.isValidUnit(s) || this.isValidWidthKeyword(s) || this.isValidVariable(s);
};
Validator.prototype.isValidWidthKeyword = function (s) {
return widthKeywords.indexOf(s) >= 0;
};
Validator.prototype.isValidVendorPrefixedValue = function (s) {
return /^-([A-Za-z0-9]|-)*$/gi.test(s);
};
Validator.prototype.areSameFunction = function (a, b) {
if (!this.isValidFunction(a) || !this.isValidFunction(b))
return false;
var f1name = a.substring(0, a.indexOf('('));
var f2name = b.substring(0, b.indexOf('('));
return f1name === f2name;
};
module.exports = Validator;

View File

@@ -0,0 +1,26 @@
var VENDOR_PREFIX_PATTERN = /$\-moz\-|\-ms\-|\-o\-|\-webkit\-/;
function prefixesIn(tokens) {
var prefixes = [];
for (var i = 0, l = tokens.length; i < l; i++) {
var token = tokens[i];
for (var j = 0, m = token.value.length; j < m; j++) {
var match = VENDOR_PREFIX_PATTERN.exec(token.value[j][0]);
if (match && prefixes.indexOf(match[0]) == -1)
prefixes.push(match[0]);
}
}
return prefixes;
}
function same(left, right) {
return prefixesIn(left).sort().join(',') == prefixesIn(right).sort().join(',');
}
module.exports = {
same: same
};

View File

@@ -0,0 +1,118 @@
var BACKSLASH_HACK = '\\';
var IMPORTANT_WORD = 'important';
var IMPORTANT_TOKEN = '!'+IMPORTANT_WORD;
var IMPORTANT_WORD_MATCH = new RegExp(IMPORTANT_WORD+'$', 'i');
var IMPORTANT_TOKEN_MATCH = new RegExp(IMPORTANT_TOKEN+'$', 'i');
var STAR_HACK = '*';
var UNDERSCORE_HACK = '_';
var BANG_HACK = '!';
function wrapAll(properties) {
var wrapped = [];
for (var i = properties.length - 1; i >= 0; i--) {
if (typeof properties[i][0] == 'string')
continue;
var single = wrapSingle(properties[i]);
single.all = properties;
single.position = i;
wrapped.unshift(single);
}
return wrapped;
}
function isMultiplex(property) {
for (var i = 1, l = property.length; i < l; i++) {
if (property[i][0] == ',' || property[i][0] == '/')
return true;
}
return false;
}
function hackType(property) {
var type = false;
var name = property[0][0];
var lastValue = property[property.length - 1];
if (name[0] == UNDERSCORE_HACK) {
type = 'underscore';
} else if (name[0] == STAR_HACK) {
type = 'star';
} else if (lastValue[0][0] == BANG_HACK && !lastValue[0].match(IMPORTANT_WORD_MATCH)) {
type = 'bang';
} else if (lastValue[0].indexOf(BANG_HACK) > 0 && !lastValue[0].match(IMPORTANT_WORD_MATCH)) {
type = 'bang';
} else if (lastValue[0].indexOf(BACKSLASH_HACK) > 0 && lastValue[0].indexOf(BACKSLASH_HACK) == lastValue[0].length - BACKSLASH_HACK.length - 1) {
type = 'backslash';
} else if (lastValue[0].indexOf(BACKSLASH_HACK) === 0 && lastValue[0].length == 2) {
type = 'backslash';
}
return type;
}
function isImportant(property) {
if (property.length > 1) {
var p = property[property.length - 1][0];
if (typeof(p) === 'string') {
return IMPORTANT_TOKEN_MATCH.test(p);
}
}
return false;
}
function stripImportant(property) {
if (property.length > 0)
property[property.length - 1][0] = property[property.length - 1][0].replace(IMPORTANT_TOKEN_MATCH, '');
}
function stripPrefixHack(property) {
property[0][0] = property[0][0].substring(1);
}
function stripSuffixHack(property, hackType) {
var lastValue = property[property.length - 1];
lastValue[0] = lastValue[0]
.substring(0, lastValue[0].indexOf(hackType == 'backslash' ? BACKSLASH_HACK : BANG_HACK))
.trim();
if (lastValue[0].length === 0)
property.pop();
}
function wrapSingle(property) {
var _isImportant = isImportant(property);
if (_isImportant)
stripImportant(property);
var _hackType = hackType(property);
if (_hackType == 'star' || _hackType == 'underscore')
stripPrefixHack(property);
else if (_hackType == 'backslash' || _hackType == 'bang')
stripSuffixHack(property, _hackType);
var isVariable = property[0][0].indexOf('--') === 0;
return {
block: isVariable && property[1] && Array.isArray(property[1][0][0]),
components: [],
dirty: false,
hack: _hackType,
important: _isImportant,
name: property[0][0],
multiplex: property.length > 2 ? isMultiplex(property) : false,
position: 0,
shorthand: false,
unused: property.length < 2,
value: property.slice(1),
variable: isVariable
};
}
module.exports = {
all: wrapAll,
single: wrapSingle
};

86
node_modules/clean-css/lib/selectors/advanced.js generated vendored Normal file
View File

@@ -0,0 +1,86 @@
var optimizeProperties = require('../properties/optimizer');
var removeDuplicates = require('./remove-duplicates');
var mergeAdjacent = require('./merge-adjacent');
var reduceNonAdjacent = require('./reduce-non-adjacent');
var mergeNonAdjacentBySelector = require('./merge-non-adjacent-by-selector');
var mergeNonAdjacentByBody = require('./merge-non-adjacent-by-body');
var restructure = require('./restructure');
var removeDuplicateMediaQueries = require('./remove-duplicate-media-queries');
var mergeMediaQueries = require('./merge-media-queries');
function removeEmpty(tokens) {
for (var i = 0, l = tokens.length; i < l; i++) {
var token = tokens[i];
var isEmpty = false;
switch (token[0]) {
case 'selector':
isEmpty = token[1].length === 0 || token[2].length === 0;
break;
case 'block':
removeEmpty(token[2]);
isEmpty = token[2].length === 0;
}
if (isEmpty) {
tokens.splice(i, 1);
i--;
l--;
}
}
}
function recursivelyOptimizeBlocks(tokens, options, context) {
for (var i = 0, l = tokens.length; i < l; i++) {
var token = tokens[i];
if (token[0] == 'block') {
var isKeyframes = /@(-moz-|-o-|-webkit-)?keyframes/.test(token[1][0]);
optimize(token[2], options, context, !isKeyframes);
}
}
}
function recursivelyOptimizeProperties(tokens, options, context) {
for (var i = 0, l = tokens.length; i < l; i++) {
var token = tokens[i];
switch (token[0]) {
case 'selector':
optimizeProperties(token[1], token[2], false, true, options, context);
break;
case 'block':
recursivelyOptimizeProperties(token[2], options, context);
}
}
}
function optimize(tokens, options, context, withRestructuring) {
recursivelyOptimizeBlocks(tokens, options, context);
recursivelyOptimizeProperties(tokens, options, context);
removeDuplicates(tokens);
mergeAdjacent(tokens, options, context);
reduceNonAdjacent(tokens, options, context);
mergeNonAdjacentBySelector(tokens, options, context);
mergeNonAdjacentByBody(tokens, options);
if (options.restructuring && withRestructuring) {
restructure(tokens, options);
mergeAdjacent(tokens, options, context);
}
if (options.mediaMerging) {
removeDuplicateMediaQueries(tokens);
var reduced = mergeMediaQueries(tokens);
for (var i = reduced.length - 1; i >= 0; i--) {
optimize(reduced[i][2], options, context, false);
}
}
removeEmpty(tokens);
}
module.exports = optimize;

89
node_modules/clean-css/lib/selectors/clean-up.js generated vendored Normal file
View File

@@ -0,0 +1,89 @@
function removeWhitespace(match, value) {
return '[' + value.replace(/ /g, '') + ']';
}
function selectorSorter(s1, s2) {
return s1[0] > s2[0] ? 1 : -1;
}
function whitespaceReplacements(_, p1, p2, p3) {
if (p1 && p2 && p3.length)
return p1 + p2 + ' ';
else if (p1 && p2)
return p1 + p2;
else
return p2;
}
var CleanUp = {
selectors: function (selectors, removeUnsupported, adjacentSpace) {
var list = [];
var repeated = [];
for (var i = 0, l = selectors.length; i < l; i++) {
var selector = selectors[i];
var reduced = selector[0]
.replace(/\s+/g, ' ')
.replace(/ ?, ?/g, ',')
.replace(/\s*(\\)?([>+~])(\s*)/g, whitespaceReplacements)
.trim();
if (adjacentSpace && reduced.indexOf('nav') > 0)
reduced = reduced.replace(/\+nav(\S|$)/, '+ nav$1');
if (removeUnsupported && (reduced.indexOf('*+html ') != -1 || reduced.indexOf('*:first-child+html ') != -1))
continue;
if (reduced.indexOf('*') > -1) {
reduced = reduced
.replace(/\*([:#\.\[])/g, '$1')
.replace(/^(\:first\-child)?\+html/, '*$1+html');
}
if (reduced.indexOf('[') > -1)
reduced = reduced.replace(/\[([^\]]+)\]/g, removeWhitespace);
if (repeated.indexOf(reduced) == -1) {
selector[0] = reduced;
repeated.push(reduced);
list.push(selector);
}
}
return list.sort(selectorSorter);
},
selectorDuplicates: function (selectors) {
var list = [];
var repeated = [];
for (var i = 0, l = selectors.length; i < l; i++) {
var selector = selectors[i];
if (repeated.indexOf(selector[0]) == -1) {
repeated.push(selector[0]);
list.push(selector);
}
}
return list.sort(selectorSorter);
},
block: function (values, spaceAfterClosingBrace) {
values[0] = values[0]
.replace(/\s+/g, ' ')
.replace(/(,|:|\() /g, '$1')
.replace(/ \)/g, ')');
if (!spaceAfterClosingBrace)
values[0] = values[0].replace(/\) /g, ')');
},
atRule: function (values) {
values[0] = values[0]
.replace(/\s+/g, ' ')
.trim();
}
};
module.exports = CleanUp;

69
node_modules/clean-css/lib/selectors/extractor.js generated vendored Normal file
View File

@@ -0,0 +1,69 @@
// This extractor is used in advanced optimizations
// IMPORTANT: Mind Token class and this code is not related!
// Properties will be tokenized in one step, see #429
var stringifySelectors = require('../stringifier/one-time').selectors;
var stringifyValue = require('../stringifier/one-time').value;
var AT_RULE = 'at-rule';
function extract(token) {
var properties = [];
if (token[0] == 'selector') {
var inSpecificSelector = !/[\.\+>~]/.test(stringifySelectors(token[1]));
for (var i = 0, l = token[2].length; i < l; i++) {
var property = token[2][i];
if (property.indexOf('__ESCAPED') === 0)
continue;
if (property[0] == AT_RULE)
continue;
var name = token[2][i][0][0];
if (name.length === 0)
continue;
if (name.indexOf('--') === 0)
continue;
var value = stringifyValue(token[2], i);
properties.push([
name,
value,
findNameRoot(name),
token[2][i],
name + ':' + value,
token[1],
inSpecificSelector
]);
}
} else if (token[0] == 'block') {
for (var j = 0, k = token[2].length; j < k; j++) {
properties = properties.concat(extract(token[2][j]));
}
}
return properties;
}
function findNameRoot(name) {
if (name == 'list-style')
return name;
if (name.indexOf('-radius') > 0)
return 'border-radius';
if (name == 'border-collapse' || name == 'border-spacing' || name == 'border-image')
return name;
if (name.indexOf('border-') === 0 && /^border\-\w+\-\w+$/.test(name))
return name.match(/border\-\w+/)[0];
if (name.indexOf('border-') === 0 && /^border\-\w+$/.test(name))
return 'border';
if (name.indexOf('text-') === 0)
return name;
return name.replace(/^\-\w+\-/, '').match(/([a-zA-Z]+)/)[0].toLowerCase();
}
module.exports = extract;

5
node_modules/clean-css/lib/selectors/is-special.js generated vendored Normal file
View File

@@ -0,0 +1,5 @@
function isSpecial(options, selector) {
return options.compatibility.selectors.special.test(selector);
}
module.exports = isSpecial;

35
node_modules/clean-css/lib/selectors/merge-adjacent.js generated vendored Normal file
View File

@@ -0,0 +1,35 @@
var optimizeProperties = require('../properties/optimizer');
var stringifyBody = require('../stringifier/one-time').body;
var stringifySelectors = require('../stringifier/one-time').selectors;
var cleanUpSelectors = require('./clean-up').selectors;
var isSpecial = require('./is-special');
function mergeAdjacent(tokens, options, context) {
var lastToken = [null, [], []];
var adjacentSpace = options.compatibility.selectors.adjacentSpace;
for (var i = 0, l = tokens.length; i < l; i++) {
var token = tokens[i];
if (token[0] != 'selector') {
lastToken = [null, [], []];
continue;
}
if (lastToken[0] == 'selector' && stringifySelectors(token[1]) == stringifySelectors(lastToken[1])) {
var joinAt = [lastToken[2].length];
Array.prototype.push.apply(lastToken[2], token[2]);
optimizeProperties(token[1], lastToken[2], joinAt, true, options, context);
token[2] = [];
} else if (lastToken[0] == 'selector' && stringifyBody(token[2]) == stringifyBody(lastToken[2]) &&
!isSpecial(options, stringifySelectors(token[1])) && !isSpecial(options, stringifySelectors(lastToken[1]))) {
lastToken[1] = cleanUpSelectors(lastToken[1].concat(token[1]), false, adjacentSpace);
token[2] = [];
} else {
lastToken = token;
}
}
}
module.exports = mergeAdjacent;

View File

@@ -0,0 +1,64 @@
var canReorder = require('./reorderable').canReorder;
var extractProperties = require('./extractor');
function mergeMediaQueries(tokens) {
var candidates = {};
var reduced = [];
for (var i = tokens.length - 1; i >= 0; i--) {
var token = tokens[i];
if (token[0] != 'block')
continue;
var candidate = candidates[token[1][0]];
if (!candidate) {
candidate = [];
candidates[token[1][0]] = candidate;
}
candidate.push(i);
}
for (var name in candidates) {
var positions = candidates[name];
positionLoop:
for (var j = positions.length - 1; j > 0; j--) {
var positionOne = positions[j];
var tokenOne = tokens[positionOne];
var positionTwo = positions[j - 1];
var tokenTwo = tokens[positionTwo];
directionLoop:
for (var direction = 1; direction >= -1; direction -= 2) {
var topToBottom = direction == 1;
var from = topToBottom ? positionOne + 1 : positionTwo - 1;
var to = topToBottom ? positionTwo : positionOne;
var delta = topToBottom ? 1 : -1;
var source = topToBottom ? tokenOne : tokenTwo;
var target = topToBottom ? tokenTwo : tokenOne;
var movedProperties = extractProperties(source);
while (from != to) {
var traversedProperties = extractProperties(tokens[from]);
from += delta;
if (!canReorder(movedProperties, traversedProperties))
continue directionLoop;
}
target[2] = topToBottom ?
source[2].concat(target[2]) :
target[2].concat(source[2]);
source[2] = [];
reduced.push(target);
continue positionLoop;
}
}
}
return reduced;
}
module.exports = mergeMediaQueries;

View File

@@ -0,0 +1,61 @@
var stringifyBody = require('../stringifier/one-time').body;
var stringifySelectors = require('../stringifier/one-time').selectors;
var cleanUpSelectors = require('./clean-up').selectors;
var isSpecial = require('./is-special');
function unsafeSelector(value) {
return /\.|\*| :/.test(value);
}
function isBemElement(token) {
var asString = stringifySelectors(token[1]);
return asString.indexOf('__') > -1 || asString.indexOf('--') > -1;
}
function withoutModifier(selector) {
return selector.replace(/--[^ ,>\+~:]+/g, '');
}
function removeAnyUnsafeElements(left, candidates) {
var leftSelector = withoutModifier(stringifySelectors(left[1]));
for (var body in candidates) {
var right = candidates[body];
var rightSelector = withoutModifier(stringifySelectors(right[1]));
if (rightSelector.indexOf(leftSelector) > -1 || leftSelector.indexOf(rightSelector) > -1)
delete candidates[body];
}
}
function mergeNonAdjacentByBody(tokens, options) {
var candidates = {};
var adjacentSpace = options.compatibility.selectors.adjacentSpace;
for (var i = tokens.length - 1; i >= 0; i--) {
var token = tokens[i];
if (token[0] != 'selector')
continue;
if (token[2].length > 0 && (!options.semanticMerging && unsafeSelector(stringifySelectors(token[1]))))
candidates = {};
if (token[2].length > 0 && options.semanticMerging && isBemElement(token))
removeAnyUnsafeElements(token, candidates);
var candidateBody = stringifyBody(token[2]);
var oldToken = candidates[candidateBody];
if (oldToken && !isSpecial(options, stringifySelectors(token[1])) && !isSpecial(options, stringifySelectors(oldToken[1]))) {
token[1] = token[2].length > 0 ?
cleanUpSelectors(oldToken[1].concat(token[1]), false, adjacentSpace) :
oldToken[1].concat(token[1]);
oldToken[2] = [];
candidates[candidateBody] = null;
}
candidates[stringifyBody(token[2])] = token;
}
}
module.exports = mergeNonAdjacentByBody;

View File

@@ -0,0 +1,76 @@
var optimizeProperties = require('../properties/optimizer');
var stringifySelectors = require('../stringifier/one-time').selectors;
var extractProperties = require('./extractor');
var canReorder = require('./reorderable').canReorder;
function mergeNonAdjacentBySelector(tokens, options, context) {
var allSelectors = {};
var repeatedSelectors = [];
var i;
for (i = tokens.length - 1; i >= 0; i--) {
if (tokens[i][0] != 'selector')
continue;
if (tokens[i][2].length === 0)
continue;
var selector = stringifySelectors(tokens[i][1]);
allSelectors[selector] = [i].concat(allSelectors[selector] || []);
if (allSelectors[selector].length == 2)
repeatedSelectors.push(selector);
}
for (i = repeatedSelectors.length - 1; i >= 0; i--) {
var positions = allSelectors[repeatedSelectors[i]];
selectorIterator:
for (var j = positions.length - 1; j > 0; j--) {
var positionOne = positions[j - 1];
var tokenOne = tokens[positionOne];
var positionTwo = positions[j];
var tokenTwo = tokens[positionTwo];
directionIterator:
for (var direction = 1; direction >= -1; direction -= 2) {
var topToBottom = direction == 1;
var from = topToBottom ? positionOne + 1 : positionTwo - 1;
var to = topToBottom ? positionTwo : positionOne;
var delta = topToBottom ? 1 : -1;
var moved = topToBottom ? tokenOne : tokenTwo;
var target = topToBottom ? tokenTwo : tokenOne;
var movedProperties = extractProperties(moved);
var joinAt;
while (from != to) {
var traversedProperties = extractProperties(tokens[from]);
from += delta;
// traversed then moved as we move selectors towards the start
var reorderable = topToBottom ?
canReorder(movedProperties, traversedProperties) :
canReorder(traversedProperties, movedProperties);
if (!reorderable && !topToBottom)
continue selectorIterator;
if (!reorderable && topToBottom)
continue directionIterator;
}
if (topToBottom) {
joinAt = [moved[2].length];
Array.prototype.push.apply(moved[2], target[2]);
target[2] = moved[2];
} else {
joinAt = [target[2].length];
Array.prototype.push.apply(target[2], moved[2]);
}
optimizeProperties(target[1], target[2], joinAt, true, options, context);
moved[2] = [];
}
}
}
}
module.exports = mergeNonAdjacentBySelector;

View File

@@ -0,0 +1,172 @@
var optimizeProperties = require('../properties/optimizer');
var stringifyBody = require('../stringifier/one-time').body;
var stringifySelectors = require('../stringifier/one-time').selectors;
var isSpecial = require('./is-special');
var cloneArray = require('../utils/clone-array');
function reduceNonAdjacent(tokens, options, context) {
var candidates = {};
var repeated = [];
for (var i = tokens.length - 1; i >= 0; i--) {
var token = tokens[i];
if (token[0] != 'selector')
continue;
if (token[2].length === 0)
continue;
var selectorAsString = stringifySelectors(token[1]);
var isComplexAndNotSpecial = token[1].length > 1 && !isSpecial(options, selectorAsString);
var wrappedSelectors = options.sourceMap ? wrappedSelectorsFrom(token[1]) : token[1];
var selectors = isComplexAndNotSpecial ?
[selectorAsString].concat(wrappedSelectors) :
[selectorAsString];
for (var j = 0, m = selectors.length; j < m; j++) {
var selector = selectors[j];
if (!candidates[selector])
candidates[selector] = [];
else
repeated.push(selector);
candidates[selector].push({
where: i,
list: wrappedSelectors,
isPartial: isComplexAndNotSpecial && j > 0,
isComplex: isComplexAndNotSpecial && j === 0
});
}
}
reduceSimpleNonAdjacentCases(tokens, repeated, candidates, options, context);
reduceComplexNonAdjacentCases(tokens, candidates, options, context);
}
function wrappedSelectorsFrom(list) {
var wrapped = [];
for (var i = 0; i < list.length; i++) {
wrapped.push([list[i][0]]);
}
return wrapped;
}
function reduceSimpleNonAdjacentCases(tokens, repeated, candidates, options, context) {
function filterOut(idx, bodies) {
return data[idx].isPartial && bodies.length === 0;
}
function reduceBody(token, newBody, processedCount, tokenIdx) {
if (!data[processedCount - tokenIdx - 1].isPartial)
token[2] = newBody;
}
for (var i = 0, l = repeated.length; i < l; i++) {
var selector = repeated[i];
var data = candidates[selector];
reduceSelector(tokens, selector, data, {
filterOut: filterOut,
callback: reduceBody
}, options, context);
}
}
function reduceComplexNonAdjacentCases(tokens, candidates, options, context) {
var localContext = {};
function filterOut(idx) {
return localContext.data[idx].where < localContext.intoPosition;
}
function collectReducedBodies(token, newBody, processedCount, tokenIdx) {
if (tokenIdx === 0)
localContext.reducedBodies.push(newBody);
}
allSelectors:
for (var complexSelector in candidates) {
var into = candidates[complexSelector];
if (!into[0].isComplex)
continue;
var intoPosition = into[into.length - 1].where;
var intoToken = tokens[intoPosition];
var reducedBodies = [];
var selectors = isSpecial(options, complexSelector) ?
[complexSelector] :
into[0].list;
localContext.intoPosition = intoPosition;
localContext.reducedBodies = reducedBodies;
for (var j = 0, m = selectors.length; j < m; j++) {
var selector = selectors[j];
var data = candidates[selector];
if (data.length < 2)
continue allSelectors;
localContext.data = data;
reduceSelector(tokens, selector, data, {
filterOut: filterOut,
callback: collectReducedBodies
}, options, context);
if (stringifyBody(reducedBodies[reducedBodies.length - 1]) != stringifyBody(reducedBodies[0]))
continue allSelectors;
}
intoToken[2] = reducedBodies[0];
}
}
function reduceSelector(tokens, selector, data, context, options, outerContext) {
var bodies = [];
var bodiesAsList = [];
var joinsAt = [];
var processedTokens = [];
for (var j = data.length - 1, m = 0; j >= 0; j--) {
if (context.filterOut(j, bodies))
continue;
var where = data[j].where;
var token = tokens[where];
var clonedBody = cloneArray(token[2]);
bodies = bodies.concat(clonedBody);
bodiesAsList.push(clonedBody);
processedTokens.push(where);
}
for (j = 0, m = bodiesAsList.length; j < m; j++) {
if (bodiesAsList[j].length > 0)
joinsAt.push((joinsAt.length > 0 ? joinsAt[joinsAt.length - 1] : 0) + bodiesAsList[j].length);
}
optimizeProperties(selector, bodies, joinsAt, false, options, outerContext);
var processedCount = processedTokens.length;
var propertyIdx = bodies.length - 1;
var tokenIdx = processedCount - 1;
while (tokenIdx >= 0) {
if ((tokenIdx === 0 || (bodies[propertyIdx] && bodiesAsList[tokenIdx].indexOf(bodies[propertyIdx]) > -1)) && propertyIdx > -1) {
propertyIdx--;
continue;
}
var newBody = bodies.splice(propertyIdx + 1);
context.callback(tokens[processedTokens[tokenIdx]], newBody, processedCount, tokenIdx);
tokenIdx--;
}
}
module.exports = reduceNonAdjacent;

View File

@@ -0,0 +1,21 @@
var stringifyAll = require('../stringifier/one-time').all;
function removeDuplicateMediaQueries(tokens) {
var candidates = {};
for (var i = 0, l = tokens.length; i < l; i++) {
var token = tokens[i];
if (token[0] != 'block')
continue;
var key = token[1][0] + '%' + stringifyAll(token[2]);
var candidate = candidates[key];
if (candidate)
candidate[2] = [];
candidates[key] = token;
}
}
module.exports = removeDuplicateMediaQueries;

View File

@@ -0,0 +1,41 @@
var stringifyBody = require('../stringifier/one-time').body;
var stringifySelectors = require('../stringifier/one-time').selectors;
function removeDuplicates(tokens) {
var matched = {};
var moreThanOnce = [];
var id, token;
var body, bodies;
for (var i = 0, l = tokens.length; i < l; i++) {
token = tokens[i];
if (token[0] != 'selector')
continue;
id = stringifySelectors(token[1]);
if (matched[id] && matched[id].length == 1)
moreThanOnce.push(id);
else
matched[id] = matched[id] || [];
matched[id].push(i);
}
for (i = 0, l = moreThanOnce.length; i < l; i++) {
id = moreThanOnce[i];
bodies = [];
for (var j = matched[id].length - 1; j >= 0; j--) {
token = tokens[matched[id][j]];
body = stringifyBody(token[2]);
if (bodies.indexOf(body) > -1)
token[2] = [];
else
bodies.push(body);
}
}
}
module.exports = removeDuplicates;

99
node_modules/clean-css/lib/selectors/reorderable.js generated vendored Normal file
View File

@@ -0,0 +1,99 @@
// TODO: it'd be great to merge it with the other canReorder functionality
var FLEX_PROPERTIES = /align\-items|box\-align|box\-pack|flex|justify/;
var BORDER_PROPERTIES = /^border\-(top|right|bottom|left|color|style|width|radius)/;
function canReorder(left, right) {
for (var i = right.length - 1; i >= 0; i--) {
for (var j = left.length - 1; j >= 0; j--) {
if (!canReorderSingle(left[j], right[i]))
return false;
}
}
return true;
}
function canReorderSingle(left, right) {
var leftName = left[0];
var leftValue = left[1];
var leftNameRoot = left[2];
var leftSelector = left[5];
var leftInSpecificSelector = left[6];
var rightName = right[0];
var rightValue = right[1];
var rightNameRoot = right[2];
var rightSelector = right[5];
var rightInSpecificSelector = right[6];
if (leftName == 'font' && rightName == 'line-height' || rightName == 'font' && leftName == 'line-height')
return false;
if (FLEX_PROPERTIES.test(leftName) && FLEX_PROPERTIES.test(rightName))
return false;
if (leftNameRoot == rightNameRoot && unprefixed(leftName) == unprefixed(rightName) && (vendorPrefixed(leftName) ^ vendorPrefixed(rightName)))
return false;
if (leftNameRoot == 'border' && BORDER_PROPERTIES.test(rightNameRoot) && (leftName == 'border' || leftName == rightNameRoot || (leftValue != rightValue && sameBorderComponent(leftName, rightName))))
return false;
if (rightNameRoot == 'border' && BORDER_PROPERTIES.test(leftNameRoot) && (rightName == 'border' || rightName == leftNameRoot || (leftValue != rightValue && sameBorderComponent(leftName, rightName))))
return false;
if (leftNameRoot == 'border' && rightNameRoot == 'border' && leftName != rightName && (isSideBorder(leftName) && isStyleBorder(rightName) || isStyleBorder(leftName) && isSideBorder(rightName)))
return false;
if (leftNameRoot != rightNameRoot)
return true;
if (leftName == rightName && leftNameRoot == rightNameRoot && (leftValue == rightValue || withDifferentVendorPrefix(leftValue, rightValue)))
return true;
if (leftName != rightName && leftNameRoot == rightNameRoot && leftName != leftNameRoot && rightName != rightNameRoot)
return true;
if (leftName != rightName && leftNameRoot == rightNameRoot && leftValue == rightValue)
return true;
if (rightInSpecificSelector && leftInSpecificSelector && !inheritable(leftNameRoot) && !inheritable(rightNameRoot) && selectorsDoNotOverlap(rightSelector, leftSelector))
return true;
return false;
}
function vendorPrefixed(name) {
return /^\-(?:moz|webkit|ms|o)\-/.test(name);
}
function unprefixed(name) {
return name.replace(/^\-(?:moz|webkit|ms|o)\-/, '');
}
function sameBorderComponent(name1, name2) {
return name1.split('-').pop() == name2.split('-').pop();
}
function isSideBorder(name) {
return name == 'border-top' || name == 'border-right' || name == 'border-bottom' || name == 'border-left';
}
function isStyleBorder(name) {
return name == 'border-color' || name == 'border-style' || name == 'border-width';
}
function withDifferentVendorPrefix(value1, value2) {
return vendorPrefixed(value1) && vendorPrefixed(value2) && value1.split('-')[1] != value2.split('-')[2];
}
function selectorsDoNotOverlap(s1, s2) {
for (var i = 0, l = s1.length; i < l; i++) {
for (var j = 0, m = s2.length; j < m; j++) {
if (s1[i][0] == s2[j][0])
return false;
}
}
return true;
}
function inheritable(name) {
// According to http://www.w3.org/TR/CSS21/propidx.html
// Others will be catched by other, preceeding rules
return name == 'font' || name == 'line-height' || name == 'list-style';
}
module.exports = {
canReorder: canReorder,
canReorderSingle: canReorderSingle
};

369
node_modules/clean-css/lib/selectors/restructure.js generated vendored Normal file
View File

@@ -0,0 +1,369 @@
var extractProperties = require('./extractor');
var canReorderSingle = require('./reorderable').canReorderSingle;
var stringifyBody = require('../stringifier/one-time').body;
var stringifySelectors = require('../stringifier/one-time').selectors;
var cleanUpSelectorDuplicates = require('./clean-up').selectorDuplicates;
var isSpecial = require('./is-special');
var cloneArray = require('../utils/clone-array');
function naturalSorter(a, b) {
return a > b;
}
function cloneAndMergeSelectors(propertyA, propertyB) {
var cloned = cloneArray(propertyA);
cloned[5] = cloned[5].concat(propertyB[5]);
return cloned;
}
function restructure(tokens, options) {
var movableTokens = {};
var movedProperties = [];
var multiPropertyMoveCache = {};
var movedToBeDropped = [];
var maxCombinationsLevel = 2;
var ID_JOIN_CHARACTER = '%';
function sendToMultiPropertyMoveCache(position, movedProperty, allFits) {
for (var i = allFits.length - 1; i >= 0; i--) {
var fit = allFits[i][0];
var id = addToCache(movedProperty, fit);
if (multiPropertyMoveCache[id].length > 1 && processMultiPropertyMove(position, multiPropertyMoveCache[id])) {
removeAllMatchingFromCache(id);
break;
}
}
}
function addToCache(movedProperty, fit) {
var id = cacheId(fit);
multiPropertyMoveCache[id] = multiPropertyMoveCache[id] || [];
multiPropertyMoveCache[id].push([movedProperty, fit]);
return id;
}
function removeAllMatchingFromCache(matchId) {
var matchSelectors = matchId.split(ID_JOIN_CHARACTER);
var forRemoval = [];
var i;
for (var id in multiPropertyMoveCache) {
var selectors = id.split(ID_JOIN_CHARACTER);
for (i = selectors.length - 1; i >= 0; i--) {
if (matchSelectors.indexOf(selectors[i]) > -1) {
forRemoval.push(id);
break;
}
}
}
for (i = forRemoval.length - 1; i >= 0; i--) {
delete multiPropertyMoveCache[forRemoval[i]];
}
}
function cacheId(cachedTokens) {
var id = [];
for (var i = 0, l = cachedTokens.length; i < l; i++) {
id.push(stringifySelectors(cachedTokens[i][1]));
}
return id.join(ID_JOIN_CHARACTER);
}
function tokensToMerge(sourceTokens) {
var uniqueTokensWithBody = [];
var mergeableTokens = [];
for (var i = sourceTokens.length - 1; i >= 0; i--) {
if (isSpecial(options, stringifySelectors(sourceTokens[i][1])))
continue;
mergeableTokens.unshift(sourceTokens[i]);
if (sourceTokens[i][2].length > 0 && uniqueTokensWithBody.indexOf(sourceTokens[i]) == -1)
uniqueTokensWithBody.push(sourceTokens[i]);
}
return uniqueTokensWithBody.length > 1 ?
mergeableTokens :
[];
}
function shortenIfPossible(position, movedProperty) {
var name = movedProperty[0];
var value = movedProperty[1];
var key = movedProperty[4];
var valueSize = name.length + value.length + 1;
var allSelectors = [];
var qualifiedTokens = [];
var mergeableTokens = tokensToMerge(movableTokens[key]);
if (mergeableTokens.length < 2)
return;
var allFits = findAllFits(mergeableTokens, valueSize, 1);
var bestFit = allFits[0];
if (bestFit[1] > 0)
return sendToMultiPropertyMoveCache(position, movedProperty, allFits);
for (var i = bestFit[0].length - 1; i >=0; i--) {
allSelectors = bestFit[0][i][1].concat(allSelectors);
qualifiedTokens.unshift(bestFit[0][i]);
}
allSelectors = cleanUpSelectorDuplicates(allSelectors);
dropAsNewTokenAt(position, [movedProperty], allSelectors, qualifiedTokens);
}
function fitSorter(fit1, fit2) {
return fit1[1] > fit2[1];
}
function findAllFits(mergeableTokens, propertySize, propertiesCount) {
var combinations = allCombinations(mergeableTokens, propertySize, propertiesCount, maxCombinationsLevel - 1);
return combinations.sort(fitSorter);
}
function allCombinations(tokensVariant, propertySize, propertiesCount, level) {
var differenceVariants = [[tokensVariant, sizeDifference(tokensVariant, propertySize, propertiesCount)]];
if (tokensVariant.length > 2 && level > 0) {
for (var i = tokensVariant.length - 1; i >= 0; i--) {
var subVariant = Array.prototype.slice.call(tokensVariant, 0);
subVariant.splice(i, 1);
differenceVariants = differenceVariants.concat(allCombinations(subVariant, propertySize, propertiesCount, level - 1));
}
}
return differenceVariants;
}
function sizeDifference(tokensVariant, propertySize, propertiesCount) {
var allSelectorsSize = 0;
for (var i = tokensVariant.length - 1; i >= 0; i--) {
allSelectorsSize += tokensVariant[i][2].length > propertiesCount ? stringifySelectors(tokensVariant[i][1]).length : -1;
}
return allSelectorsSize - (tokensVariant.length - 1) * propertySize + 1;
}
function dropAsNewTokenAt(position, properties, allSelectors, mergeableTokens) {
var i, j, k, m;
var allProperties = [];
for (i = mergeableTokens.length - 1; i >= 0; i--) {
var mergeableToken = mergeableTokens[i];
for (j = mergeableToken[2].length - 1; j >= 0; j--) {
var mergeableProperty = mergeableToken[2][j];
for (k = 0, m = properties.length; k < m; k++) {
var property = properties[k];
var mergeablePropertyName = mergeableProperty[0][0];
var propertyName = property[0];
var propertyBody = property[4];
if (mergeablePropertyName == propertyName && stringifyBody([mergeableProperty]) == propertyBody) {
mergeableToken[2].splice(j, 1);
break;
}
}
}
}
for (i = properties.length - 1; i >= 0; i--) {
allProperties.unshift(properties[i][3]);
}
var newToken = ['selector', allSelectors, allProperties];
tokens.splice(position, 0, newToken);
}
function dropPropertiesAt(position, movedProperty) {
var key = movedProperty[4];
var toMove = movableTokens[key];
if (toMove && toMove.length > 1) {
if (!shortenMultiMovesIfPossible(position, movedProperty))
shortenIfPossible(position, movedProperty);
}
}
function shortenMultiMovesIfPossible(position, movedProperty) {
var candidates = [];
var propertiesAndMergableTokens = [];
var key = movedProperty[4];
var j, k;
var mergeableTokens = tokensToMerge(movableTokens[key]);
if (mergeableTokens.length < 2)
return;
movableLoop:
for (var value in movableTokens) {
var tokensList = movableTokens[value];
for (j = mergeableTokens.length - 1; j >= 0; j--) {
if (tokensList.indexOf(mergeableTokens[j]) == -1)
continue movableLoop;
}
candidates.push(value);
}
if (candidates.length < 2)
return false;
for (j = candidates.length - 1; j >= 0; j--) {
for (k = movedProperties.length - 1; k >= 0; k--) {
if (movedProperties[k][4] == candidates[j]) {
propertiesAndMergableTokens.unshift([movedProperties[k], mergeableTokens]);
break;
}
}
}
return processMultiPropertyMove(position, propertiesAndMergableTokens);
}
function processMultiPropertyMove(position, propertiesAndMergableTokens) {
var valueSize = 0;
var properties = [];
var property;
for (var i = propertiesAndMergableTokens.length - 1; i >= 0; i--) {
property = propertiesAndMergableTokens[i][0];
var fullValue = property[4];
valueSize += fullValue.length + (i > 0 ? 1 : 0);
properties.push(property);
}
var mergeableTokens = propertiesAndMergableTokens[0][1];
var bestFit = findAllFits(mergeableTokens, valueSize, properties.length)[0];
if (bestFit[1] > 0)
return false;
var allSelectors = [];
var qualifiedTokens = [];
for (i = bestFit[0].length - 1; i >= 0; i--) {
allSelectors = bestFit[0][i][1].concat(allSelectors);
qualifiedTokens.unshift(bestFit[0][i]);
}
allSelectors = cleanUpSelectorDuplicates(allSelectors);
dropAsNewTokenAt(position, properties, allSelectors, qualifiedTokens);
for (i = properties.length - 1; i >= 0; i--) {
property = properties[i];
var index = movedProperties.indexOf(property);
delete movableTokens[property[4]];
if (index > -1 && movedToBeDropped.indexOf(index) == -1)
movedToBeDropped.push(index);
}
return true;
}
function boundToAnotherPropertyInCurrrentToken(property, movedProperty, token) {
var propertyName = property[0];
var movedPropertyName = movedProperty[0];
if (propertyName != movedPropertyName)
return false;
var key = movedProperty[4];
var toMove = movableTokens[key];
return toMove && toMove.indexOf(token) > -1;
}
for (var i = tokens.length - 1; i >= 0; i--) {
var token = tokens[i];
var isSelector;
var j, k, m;
var samePropertyAt;
if (token[0] == 'selector') {
isSelector = true;
} else if (token[0] == 'block') {
isSelector = false;
} else {
continue;
}
// We cache movedProperties.length as it may change in the loop
var movedCount = movedProperties.length;
var properties = extractProperties(token);
movedToBeDropped = [];
var unmovableInCurrentToken = [];
for (j = properties.length - 1; j >= 0; j--) {
for (k = j - 1; k >= 0; k--) {
if (!canReorderSingle(properties[j], properties[k])) {
unmovableInCurrentToken.push(j);
break;
}
}
}
for (j = properties.length - 1; j >= 0; j--) {
var property = properties[j];
var movedSameProperty = false;
for (k = 0; k < movedCount; k++) {
var movedProperty = movedProperties[k];
if (movedToBeDropped.indexOf(k) == -1 && !canReorderSingle(property, movedProperty) && !boundToAnotherPropertyInCurrrentToken(property, movedProperty, token)) {
dropPropertiesAt(i + 1, movedProperty, token);
if (movedToBeDropped.indexOf(k) == -1) {
movedToBeDropped.push(k);
delete movableTokens[movedProperty[4]];
}
}
if (!movedSameProperty) {
movedSameProperty = property[0] == movedProperty[0] && property[1] == movedProperty[1];
if (movedSameProperty) {
samePropertyAt = k;
}
}
}
if (!isSelector || unmovableInCurrentToken.indexOf(j) > -1)
continue;
var key = property[4];
movableTokens[key] = movableTokens[key] || [];
movableTokens[key].push(token);
if (movedSameProperty) {
movedProperties[samePropertyAt] = cloneAndMergeSelectors(movedProperties[samePropertyAt], property);
} else {
movedProperties.push(property);
}
}
movedToBeDropped = movedToBeDropped.sort(naturalSorter);
for (j = 0, m = movedToBeDropped.length; j < m; j++) {
var dropAt = movedToBeDropped[j] - j;
movedProperties.splice(dropAt, 1);
}
}
var position = tokens[0] && tokens[0][0] == 'at-rule' && tokens[0][1][0].indexOf('@charset') === 0 ? 1 : 0;
for (; position < tokens.length - 1; position++) {
var isImportRule = tokens[position][0] === 'at-rule' && tokens[position][1][0].indexOf('@import') === 0;
var isEscapedCommentSpecial = tokens[position][0] === 'text' && tokens[position][1][0].indexOf('__ESCAPED_COMMENT_SPECIAL') === 0;
if (!(isImportRule || isEscapedCommentSpecial))
break;
}
for (i = 0; i < movedProperties.length; i++) {
dropPropertiesAt(position, movedProperties[i]);
}
}
module.exports = restructure;

454
node_modules/clean-css/lib/selectors/simple.js generated vendored Normal file
View File

@@ -0,0 +1,454 @@
var cleanUpSelectors = require('./clean-up').selectors;
var cleanUpBlock = require('./clean-up').block;
var cleanUpAtRule = require('./clean-up').atRule;
var split = require('../utils/split');
var RGB = require('../colors/rgb');
var HSL = require('../colors/hsl');
var HexNameShortener = require('../colors/hex-name-shortener');
var wrapForOptimizing = require('../properties/wrap-for-optimizing').all;
var restoreFromOptimizing = require('../properties/restore-from-optimizing');
var removeUnused = require('../properties/remove-unused');
var DEFAULT_ROUNDING_PRECISION = 2;
var CHARSET_TOKEN = '@charset';
var CHARSET_REGEXP = new RegExp('^' + CHARSET_TOKEN, 'i');
var IMPORT_REGEXP = /^@import["'\s]/i;
var FONT_NUMERAL_WEIGHTS = ['100', '200', '300', '400', '500', '600', '700', '800', '900'];
var FONT_NAME_WEIGHTS = ['normal', 'bold', 'bolder', 'lighter'];
var FONT_NAME_WEIGHTS_WITHOUT_NORMAL = ['bold', 'bolder', 'lighter'];
var WHOLE_PIXEL_VALUE = /(?:^|\s|\()(-?\d+)px/;
var TIME_VALUE = /^(\-?[\d\.]+)(m?s)$/;
var valueMinifiers = {
'background': function (value, index, total) {
return index === 0 && total == 1 && (value == 'none' || value == 'transparent') ? '0 0' : value;
},
'font-weight': function (value) {
if (value == 'normal')
return '400';
else if (value == 'bold')
return '700';
else
return value;
},
'outline': function (value, index, total) {
return index === 0 && total == 1 && value == 'none' ? '0' : value;
}
};
function isNegative(property, idx) {
return property.value[idx] && property.value[idx][0][0] == '-' && parseFloat(property.value[idx][0]) < 0;
}
function zeroMinifier(name, value) {
if (value.indexOf('0') == -1)
return value;
if (value.indexOf('-') > -1) {
value = value
.replace(/([^\w\d\-]|^)\-0([^\.]|$)/g, '$10$2')
.replace(/([^\w\d\-]|^)\-0([^\.]|$)/g, '$10$2');
}
return value
.replace(/(^|\s)0+([1-9])/g, '$1$2')
.replace(/(^|\D)\.0+(\D|$)/g, '$10$2')
.replace(/(^|\D)\.0+(\D|$)/g, '$10$2')
.replace(/\.([1-9]*)0+(\D|$)/g, function (match, nonZeroPart, suffix) {
return (nonZeroPart.length > 0 ? '.' : '') + nonZeroPart + suffix;
})
.replace(/(^|\D)0\.(\d)/g, '$1.$2');
}
function zeroDegMinifier(_, value) {
if (value.indexOf('0deg') == -1)
return value;
return value.replace(/\(0deg\)/g, '(0)');
}
function whitespaceMinifier(name, value) {
if (name.indexOf('filter') > -1 || value.indexOf(' ') == -1)
return value;
value = value.replace(/\s+/g, ' ');
if (value.indexOf('calc') > -1)
value = value.replace(/\) ?\/ ?/g, ')/ ');
return value
.replace(/\( /g, '(')
.replace(/ \)/g, ')')
.replace(/, /g, ',');
}
function precisionMinifier(_, value, precisionOptions) {
if (precisionOptions.value === -1 || value.indexOf('.') === -1)
return value;
return value
.replace(precisionOptions.regexp, function (match, number) {
return Math.round(parseFloat(number) * precisionOptions.multiplier) / precisionOptions.multiplier + 'px';
})
.replace(/(\d)\.($|\D)/g, '$1$2');
}
function unitMinifier(name, value, unitsRegexp) {
if (/^(?:\-moz\-calc|\-webkit\-calc|calc)\(/.test(value))
return value;
if (name == 'flex' || name == '-ms-flex' || name == '-webkit-flex' || name == 'flex-basis' || name == '-webkit-flex-basis')
return value;
if (value.indexOf('%') > 0 && (name == 'height' || name == 'max-height'))
return value;
return value
.replace(unitsRegexp, '$1' + '0' + '$2')
.replace(unitsRegexp, '$1' + '0' + '$2');
}
function multipleZerosMinifier(property) {
var values = property.value;
var spliceAt;
if (values.length == 4 && values[0][0] === '0' && values[1][0] === '0' && values[2][0] === '0' && values[3][0] === '0') {
if (property.name.indexOf('box-shadow') > -1)
spliceAt = 2;
else
spliceAt = 1;
}
if (spliceAt) {
property.value.splice(spliceAt);
property.dirty = true;
}
}
function colorMininifier(name, value, compatibility) {
if (value.indexOf('#') === -1 && value.indexOf('rgb') == -1 && value.indexOf('hsl') == -1)
return HexNameShortener.shorten(value);
value = value
.replace(/rgb\((\-?\d+),(\-?\d+),(\-?\d+)\)/g, function (match, red, green, blue) {
return new RGB(red, green, blue).toHex();
})
.replace(/hsl\((-?\d+),(-?\d+)%?,(-?\d+)%?\)/g, function (match, hue, saturation, lightness) {
return new HSL(hue, saturation, lightness).toHex();
})
.replace(/(^|[^='"])#([0-9a-f]{6})/gi, function (match, prefix, color) {
if (color[0] == color[1] && color[2] == color[3] && color[4] == color[5])
return prefix + '#' + color[0] + color[2] + color[4];
else
return prefix + '#' + color;
})
.replace(/(rgb|rgba|hsl|hsla)\(([^\)]+)\)/g, function (match, colorFunction, colorDef) {
var tokens = colorDef.split(',');
var applies = (colorFunction == 'hsl' && tokens.length == 3) ||
(colorFunction == 'hsla' && tokens.length == 4) ||
(colorFunction == 'rgb' && tokens.length == 3 && colorDef.indexOf('%') > 0) ||
(colorFunction == 'rgba' && tokens.length == 4 && colorDef.indexOf('%') > 0);
if (!applies)
return match;
if (tokens[1].indexOf('%') == -1)
tokens[1] += '%';
if (tokens[2].indexOf('%') == -1)
tokens[2] += '%';
return colorFunction + '(' + tokens.join(',') + ')';
});
if (compatibility.colors.opacity && name.indexOf('background') == -1) {
value = value.replace(/(?:rgba|hsla)\(0,0%?,0%?,0\)/g, function (match) {
if (split(value, ',').pop().indexOf('gradient(') > -1)
return match;
return 'transparent';
});
}
return HexNameShortener.shorten(value);
}
function pixelLengthMinifier(_, value, compatibility) {
if (!WHOLE_PIXEL_VALUE.test(value))
return value;
return value.replace(WHOLE_PIXEL_VALUE, function (match, val) {
var newValue;
var intVal = parseInt(val);
if (intVal === 0)
return match;
if (compatibility.properties.shorterLengthUnits && compatibility.units.pt && intVal * 3 % 4 === 0)
newValue = intVal * 3 / 4 + 'pt';
if (compatibility.properties.shorterLengthUnits && compatibility.units.pc && intVal % 16 === 0)
newValue = intVal / 16 + 'pc';
if (compatibility.properties.shorterLengthUnits && compatibility.units.in && intVal % 96 === 0)
newValue = intVal / 96 + 'in';
if (newValue)
newValue = match.substring(0, match.indexOf(val)) + newValue;
return newValue && newValue.length < match.length ? newValue : match;
});
}
function timeUnitMinifier(_, value) {
if (!TIME_VALUE.test(value))
return value;
return value.replace(TIME_VALUE, function (match, val, unit) {
var newValue;
if (unit == 'ms') {
newValue = parseInt(val) / 1000 + 's';
} else if (unit == 's') {
newValue = parseFloat(val) * 1000 + 'ms';
}
return newValue.length < match.length ? newValue : match;
});
}
function minifyBorderRadius(property) {
var values = property.value;
var spliceAt;
if (values.length == 3 && values[1][0] == '/' && values[0][0] == values[2][0])
spliceAt = 1;
else if (values.length == 5 && values[2][0] == '/' && values[0][0] == values[3][0] && values[1][0] == values[4][0])
spliceAt = 2;
else if (values.length == 7 && values[3][0] == '/' && values[0][0] == values[4][0] && values[1][0] == values[5][0] && values[2][0] == values[6][0])
spliceAt = 3;
else if (values.length == 9 && values[4][0] == '/' && values[0][0] == values[5][0] && values[1][0] == values[6][0] && values[2][0] == values[7][0] && values[3][0] == values[8][0])
spliceAt = 4;
if (spliceAt) {
property.value.splice(spliceAt);
property.dirty = true;
}
}
function minifyFilter(property) {
if (property.value.length == 1) {
property.value[0][0] = property.value[0][0].replace(/progid:DXImageTransform\.Microsoft\.(Alpha|Chroma)(\W)/, function (match, filter, suffix) {
return filter.toLowerCase() + suffix;
});
}
property.value[0][0] = property.value[0][0]
.replace(/,(\S)/g, ', $1')
.replace(/ ?= ?/g, '=');
}
function minifyFont(property) {
var values = property.value;
var hasNumeral = FONT_NUMERAL_WEIGHTS.indexOf(values[0][0]) > -1 ||
values[1] && FONT_NUMERAL_WEIGHTS.indexOf(values[1][0]) > -1 ||
values[2] && FONT_NUMERAL_WEIGHTS.indexOf(values[2][0]) > -1;
if (hasNumeral)
return;
if (values[1] == '/')
return;
var normalCount = 0;
if (values[0][0] == 'normal')
normalCount++;
if (values[1] && values[1][0] == 'normal')
normalCount++;
if (values[2] && values[2][0] == 'normal')
normalCount++;
if (normalCount > 1)
return;
var toOptimize;
if (FONT_NAME_WEIGHTS_WITHOUT_NORMAL.indexOf(values[0][0]) > -1)
toOptimize = 0;
else if (values[1] && FONT_NAME_WEIGHTS_WITHOUT_NORMAL.indexOf(values[1][0]) > -1)
toOptimize = 1;
else if (values[2] && FONT_NAME_WEIGHTS_WITHOUT_NORMAL.indexOf(values[2][0]) > -1)
toOptimize = 2;
else if (FONT_NAME_WEIGHTS.indexOf(values[0][0]) > -1)
toOptimize = 0;
else if (values[1] && FONT_NAME_WEIGHTS.indexOf(values[1][0]) > -1)
toOptimize = 1;
else if (values[2] && FONT_NAME_WEIGHTS.indexOf(values[2][0]) > -1)
toOptimize = 2;
if (toOptimize !== undefined) {
property.value[toOptimize][0] = valueMinifiers['font-weight'](values[toOptimize][0]);
property.dirty = true;
}
}
function optimizeBody(properties, options) {
var property, name, value;
var _properties = wrapForOptimizing(properties);
for (var i = 0, l = _properties.length; i < l; i++) {
property = _properties[i];
name = property.name;
if (property.hack && (
(property.hack == 'star' || property.hack == 'underscore') && !options.compatibility.properties.iePrefixHack ||
property.hack == 'backslash' && !options.compatibility.properties.ieSuffixHack ||
property.hack == 'bang' && !options.compatibility.properties.ieBangHack))
property.unused = true;
if (name.indexOf('padding') === 0 && (isNegative(property, 0) || isNegative(property, 1) || isNegative(property, 2) || isNegative(property, 3)))
property.unused = true;
if (property.unused)
continue;
if (property.variable) {
if (property.block)
optimizeBody(property.value[0], options);
continue;
}
for (var j = 0, m = property.value.length; j < m; j++) {
value = property.value[j][0];
if (valueMinifiers[name])
value = valueMinifiers[name](value, j, m);
value = whitespaceMinifier(name, value);
value = precisionMinifier(name, value, options.precision);
value = pixelLengthMinifier(name, value, options.compatibility);
value = timeUnitMinifier(name, value);
value = zeroMinifier(name, value);
if (options.compatibility.properties.zeroUnits) {
value = zeroDegMinifier(name, value);
value = unitMinifier(name, value, options.unitsRegexp);
}
if (options.compatibility.properties.colors)
value = colorMininifier(name, value, options.compatibility);
property.value[j][0] = value;
}
multipleZerosMinifier(property);
if (name.indexOf('border') === 0 && name.indexOf('radius') > 0)
minifyBorderRadius(property);
else if (name == 'filter')
minifyFilter(property);
else if (name == 'font')
minifyFont(property);
}
restoreFromOptimizing(_properties, true);
removeUnused(_properties);
}
function cleanupCharsets(tokens) {
var hasCharset = false;
for (var i = 0, l = tokens.length; i < l; i++) {
var token = tokens[i];
if (token[0] != 'at-rule')
continue;
if (!CHARSET_REGEXP.test(token[1][0]))
continue;
if (hasCharset || token[1][0].indexOf(CHARSET_TOKEN) == -1) {
tokens.splice(i, 1);
i--;
l--;
} else {
hasCharset = true;
tokens.splice(i, 1);
tokens.unshift(['at-rule', [token[1][0].replace(CHARSET_REGEXP, CHARSET_TOKEN)]]);
}
}
}
function buildUnitRegexp(options) {
var units = ['px', 'em', 'ex', 'cm', 'mm', 'in', 'pt', 'pc', '%'];
var otherUnits = ['ch', 'rem', 'vh', 'vm', 'vmax', 'vmin', 'vw'];
otherUnits.forEach(function (unit) {
if (options.compatibility.units[unit])
units.push(unit);
});
return new RegExp('(^|\\s|\\(|,)0(?:' + units.join('|') + ')(\\W|$)', 'g');
}
function buildPrecision(options) {
var precision = {};
precision.value = options.roundingPrecision === undefined ?
DEFAULT_ROUNDING_PRECISION :
options.roundingPrecision;
precision.multiplier = Math.pow(10, precision.value);
precision.regexp = new RegExp('(\\d*\\.\\d{' + (precision.value + 1) + ',})px', 'g');
return precision;
}
function optimize(tokens, options, context) {
var ie7Hack = options.compatibility.selectors.ie7Hack;
var adjacentSpace = options.compatibility.selectors.adjacentSpace;
var spaceAfterClosingBrace = options.compatibility.properties.spaceAfterClosingBrace;
var mayHaveCharset = false;
var afterContent = false;
options.unitsRegexp = buildUnitRegexp(options);
options.precision = buildPrecision(options);
for (var i = 0, l = tokens.length; i < l; i++) {
var token = tokens[i];
switch (token[0]) {
case 'selector':
token[1] = cleanUpSelectors(token[1], !ie7Hack, adjacentSpace);
optimizeBody(token[2], options);
afterContent = true;
break;
case 'block':
cleanUpBlock(token[1], spaceAfterClosingBrace);
optimize(token[2], options, context);
afterContent = true;
break;
case 'flat-block':
cleanUpBlock(token[1], spaceAfterClosingBrace);
optimizeBody(token[2], options);
afterContent = true;
break;
case 'at-rule':
cleanUpAtRule(token[1]);
mayHaveCharset = true;
}
if (token[0] == 'at-rule' && IMPORT_REGEXP.test(token[1]) && afterContent) {
context.warnings.push('Ignoring @import rule "' + token[1] + '" as it appears after rules thus browsers will ignore them.');
token[1] = '';
}
if (token[1].length === 0 || (token[2] && token[2].length === 0)) {
tokens.splice(i, 1);
i--;
l--;
}
}
if (mayHaveCharset)
cleanupCharsets(tokens);
}
module.exports = optimize;

119
node_modules/clean-css/lib/source-maps/track.js generated vendored Normal file
View File

@@ -0,0 +1,119 @@
var escapePrefix = '__ESCAPED_';
function trackPrefix(value, context, interestingContent) {
if (!interestingContent && value.indexOf('\n') == -1) {
if (value.indexOf(escapePrefix) === 0) {
return value;
} else {
context.column += value.length;
return;
}
}
var withoutContent = 0;
var split = value.split('\n');
var total = split.length;
var shift = 0;
while (true) {
if (withoutContent == total - 1)
break;
var part = split[withoutContent];
if (/\S/.test(part))
break;
shift += part.length + 1;
withoutContent++;
}
context.line += withoutContent;
context.column = withoutContent > 0 ? 0 : context.column;
context.column += /^(\s)*/.exec(split[withoutContent])[0].length;
return value.substring(shift).trimLeft();
}
function sourceFor(originalMetadata, contextMetadata, context) {
var source = originalMetadata.source || contextMetadata.source;
if (source && context.resolvePath)
return context.resolvePath(contextMetadata.source, source);
return source;
}
function snapshot(data, context, fallbacks) {
var metadata = {
line: context.line,
column: context.column,
source: context.source
};
var sourceContent = null;
var sourceMetadata = context.sourceMapTracker.isTracking(metadata.source) ?
context.sourceMapTracker.originalPositionFor(metadata, data, fallbacks || 0) :
{};
metadata.line = sourceMetadata.line || metadata.line;
metadata.column = sourceMetadata.column || metadata.column;
metadata.source = sourceMetadata.sourceResolved ?
sourceMetadata.source :
sourceFor(sourceMetadata, metadata, context);
if (context.sourceMapInlineSources) {
var sourceMapSourcesContent = context.sourceMapTracker.sourcesContentFor(context.source);
sourceContent = sourceMapSourcesContent && sourceMapSourcesContent[metadata.source] ?
sourceMapSourcesContent :
context.sourceReader.sourceAt(context.source);
}
return sourceContent ?
[metadata.line, metadata.column, metadata.source, sourceContent] :
[metadata.line, metadata.column, metadata.source];
}
function trackSuffix(data, context) {
var parts = data.split('\n');
for (var i = 0, l = parts.length; i < l; i++) {
var part = parts[i];
var cursor = 0;
if (i > 0) {
context.line++;
context.column = 0;
}
while (true) {
var next = part.indexOf(escapePrefix, cursor);
if (next == -1) {
context.column += part.substring(cursor).length;
break;
}
context.column += next - cursor;
cursor += next - cursor;
var escaped = part.substring(next, part.indexOf('__', next + 1) + 2);
var encodedValues = escaped.substring(escaped.indexOf('(') + 1, escaped.indexOf(')')).split(',');
context.line += ~~encodedValues[0];
context.column = (~~encodedValues[0] === 0 ? context.column : 0) + ~~encodedValues[1];
cursor += escaped.length;
}
}
}
function track(data, context, snapshotMetadata, fallbacks) {
var untracked = trackPrefix(data, context, snapshotMetadata);
var metadata = snapshotMetadata ?
snapshot(untracked, context, fallbacks) :
[];
if (untracked)
trackSuffix(untracked, context);
return metadata;
}
module.exports = track;

167
node_modules/clean-css/lib/stringifier/helpers.js generated vendored Normal file
View File

@@ -0,0 +1,167 @@
var lineBreak = require('os').EOL;
var AT_RULE = 'at-rule';
var PROPERTY_SEPARATOR = ';';
function hasMoreProperties(tokens, index) {
for (var i = index, l = tokens.length; i < l; i++) {
if (typeof tokens[i] != 'string')
return true;
}
return false;
}
function supportsAfterClosingBrace(token) {
return token[0][0] == 'background' || token[0][0] == 'transform' || token[0][0] == 'src';
}
function afterClosingBrace(token, valueIndex) {
return token[valueIndex][0][token[valueIndex][0].length - 1] == ')' || token[valueIndex][0].indexOf('__ESCAPED_URL_CLEAN_CSS') === 0;
}
function afterComma(token, valueIndex) {
return token[valueIndex][0] == ',';
}
function afterSlash(token, valueIndex) {
return token[valueIndex][0] == '/';
}
function beforeComma(token, valueIndex) {
return token[valueIndex + 1] && token[valueIndex + 1][0] == ',';
}
function beforeSlash(token, valueIndex) {
return token[valueIndex + 1] && token[valueIndex + 1][0] == '/';
}
function inFilter(token) {
return token[0][0] == 'filter' || token[0][0] == '-ms-filter';
}
function inSpecialContext(token, valueIndex, context) {
return !context.spaceAfterClosingBrace && supportsAfterClosingBrace(token) && afterClosingBrace(token, valueIndex) ||
beforeSlash(token, valueIndex) ||
afterSlash(token, valueIndex) ||
beforeComma(token, valueIndex) ||
afterComma(token, valueIndex);
}
function selectors(tokens, context) {
var store = context.store;
for (var i = 0, l = tokens.length; i < l; i++) {
store(tokens[i], context);
if (i < l - 1)
store(',', context);
}
}
function body(tokens, context) {
for (var i = 0, l = tokens.length; i < l; i++) {
property(tokens, i, i == l - 1, context);
}
}
function property(tokens, position, isLast, context) {
var store = context.store;
var token = tokens[position];
if (typeof token == 'string') {
store(token, context);
} else if (token[0] == AT_RULE) {
propertyAtRule(token[1], isLast, context);
} else {
store(token[0], context);
store(':', context);
value(tokens, position, isLast, context);
}
}
function propertyAtRule(value, isLast, context) {
var store = context.store;
store(value, context);
if (!isLast)
store(PROPERTY_SEPARATOR, context);
}
function value(tokens, position, isLast, context) {
var store = context.store;
var token = tokens[position];
var isVariableDeclaration = token[0][0].indexOf('--') === 0;
var isBlockVariable = isVariableDeclaration && Array.isArray(token[1][0]);
if (isVariableDeclaration && isBlockVariable && atRulesOrProperties(token[1])) {
store('{', context);
body(token[1], context);
store('};', context);
return;
}
for (var j = 1, m = token.length; j < m; j++) {
store(token[j], context);
if (j < m - 1 && (inFilter(token) || !inSpecialContext(token, j, context))) {
store(' ', context);
} else if (j == m - 1 && !isLast && hasMoreProperties(tokens, position + 1)) {
store(PROPERTY_SEPARATOR, context);
}
}
}
function atRulesOrProperties(values) {
for (var i = 0, l = values.length; i < l; i++) {
if (values[i][0] == AT_RULE || Array.isArray(values[i][0]))
return true;
}
return false;
}
function all(tokens, context) {
var joinCharacter = context.keepBreaks ? lineBreak : '';
var store = context.store;
for (var i = 0, l = tokens.length; i < l; i++) {
var token = tokens[i];
switch (token[0]) {
case 'at-rule':
case 'text':
store(token[1][0], context);
store(joinCharacter, context);
break;
case 'block':
selectors([token[1]], context);
store('{', context);
all(token[2], context);
store('}', context);
store(joinCharacter, context);
break;
case 'flat-block':
selectors([token[1]], context);
store('{', context);
body(token[2], context);
store('}', context);
store(joinCharacter, context);
break;
default:
selectors(token[1], context);
store('{', context);
body(token[2], context);
store('}', context);
store(joinCharacter, context);
}
}
}
module.exports = {
all: all,
body: body,
property: property,
selectors: selectors,
value: value
};

50
node_modules/clean-css/lib/stringifier/one-time.js generated vendored Normal file
View File

@@ -0,0 +1,50 @@
var helpers = require('./helpers');
function store(token, context) {
context.output.push(typeof token == 'string' ? token : token[0]);
}
function context() {
return {
output: [],
store: store
};
}
function all(tokens) {
var fakeContext = context();
helpers.all(tokens, fakeContext);
return fakeContext.output.join('');
}
function body(tokens) {
var fakeContext = context();
helpers.body(tokens, fakeContext);
return fakeContext.output.join('');
}
function property(tokens, position) {
var fakeContext = context();
helpers.property(tokens, position, true, fakeContext);
return fakeContext.output.join('');
}
function selectors(tokens) {
var fakeContext = context();
helpers.selectors(tokens, fakeContext);
return fakeContext.output.join('');
}
function value(tokens, position) {
var fakeContext = context();
helpers.value(tokens, position, true, fakeContext);
return fakeContext.output.join('');
}
module.exports = {
all: all,
body: body,
property: property,
selectors: selectors,
value: value
};

22
node_modules/clean-css/lib/stringifier/simple.js generated vendored Normal file
View File

@@ -0,0 +1,22 @@
var all = require('./helpers').all;
function store(token, context) {
context.output.push(typeof token == 'string' ? token : token[0]);
}
function stringify(tokens, options, restoreCallback) {
var context = {
keepBreaks: options.keepBreaks,
output: [],
spaceAfterClosingBrace: options.compatibility.properties.spaceAfterClosingBrace,
store: store
};
all(tokens, context, false);
return {
styles: restoreCallback(context.output.join('')).trim()
};
}
module.exports = stringify;

96
node_modules/clean-css/lib/stringifier/source-maps.js generated vendored Normal file
View File

@@ -0,0 +1,96 @@
var SourceMapGenerator = require('source-map').SourceMapGenerator;
var all = require('./helpers').all;
var isWindows = process.platform == 'win32';
var unknownSource = '$stdin';
function store(element, context) {
var fromString = typeof element == 'string';
var value = fromString ? element : element[0];
if (value.indexOf('_') > -1)
value = context.restore(value, prefixContentFrom(context.output));
track(value, fromString ? null : element, context);
context.output.push(value);
}
function prefixContentFrom(values) {
var content = [];
for (var i = values.length - 1; i >= 0; i--) {
var value = values[i];
content.unshift(value);
if (value == '{' || value == ';')
break;
}
return content.join('');
}
function track(value, element, context) {
if (element)
trackAllMappings(element, context);
var parts = value.split('\n');
context.line += parts.length - 1;
context.column = parts.length > 1 ? 0 : (context.column + parts.pop().length);
}
function trackAllMappings(element, context) {
var mapping = element[element.length - 1];
if (!Array.isArray(mapping))
return;
for (var i = 0, l = mapping.length; i < l; i++) {
trackMapping(mapping[i], context);
}
}
function trackMapping(mapping, context) {
var source = mapping[2] || unknownSource;
if (isWindows)
source = source.replace(/\\/g, '/');
context.outputMap.addMapping({
generated: {
line: context.line,
column: context.column
},
source: source,
original: {
line: mapping[0],
column: mapping[1]
}
});
if (mapping[3])
context.outputMap.setSourceContent(source, mapping[3][mapping[2]]);
}
function stringify(tokens, options, restoreCallback, inputMapTracker) {
var context = {
column: 0,
inputMapTracker: inputMapTracker,
keepBreaks: options.keepBreaks,
line: 1,
output: [],
outputMap: new SourceMapGenerator(),
restore: restoreCallback,
sourceMapInlineSources: options.sourceMapInlineSources,
spaceAfterClosingBrace: options.compatibility.properties.spaceAfterClosingBrace,
store: store
};
all(tokens, context, false);
return {
sourceMap: context.outputMap,
styles: context.output.join('').trim()
};
}
module.exports = stringify;

131
node_modules/clean-css/lib/text/comments-processor.js generated vendored Normal file
View File

@@ -0,0 +1,131 @@
var EscapeStore = require('./escape-store');
var QuoteScanner = require('../utils/quote-scanner');
var SPECIAL_COMMENT_PREFIX = '/*!';
var COMMENT_PREFIX = '/*';
var COMMENT_SUFFIX = '*/';
var lineBreak = require('os').EOL;
function CommentsProcessor(context, keepSpecialComments, keepBreaks, saveWaypoints) {
this.comments = new EscapeStore('COMMENT');
this.specialComments = new EscapeStore('COMMENT_SPECIAL');
this.context = context;
this.restored = 0;
this.keepAll = keepSpecialComments == '*';
this.keepOne = keepSpecialComments == '1' || keepSpecialComments === 1;
this.keepBreaks = keepBreaks;
this.saveWaypoints = saveWaypoints;
}
function quoteScannerFor(data) {
var quoteMap = [];
new QuoteScanner(data).each(function (quotedString, _, startsAt) {
quoteMap.push([startsAt, startsAt + quotedString.length]);
});
return function (position) {
for (var i = 0, l = quoteMap.length; i < l; i++) {
if (quoteMap[i][0] < position && quoteMap[i][1] > position)
return true;
}
return false;
};
}
CommentsProcessor.prototype.escape = function (data) {
var tempData = [];
var nextStart = 0;
var nextEnd = 0;
var cursor = 0;
var indent = 0;
var breaksCount;
var lastBreakAt;
var newIndent;
var isQuotedAt = quoteScannerFor(data);
var saveWaypoints = this.saveWaypoints;
for (; nextEnd < data.length;) {
nextStart = data.indexOf(COMMENT_PREFIX, cursor);
if (nextStart == -1)
break;
if (isQuotedAt(nextStart)) {
tempData.push(data.substring(cursor, nextStart + COMMENT_PREFIX.length));
cursor = nextStart + COMMENT_PREFIX.length;
continue;
}
nextEnd = data.indexOf(COMMENT_SUFFIX, nextStart + COMMENT_PREFIX.length);
if (nextEnd == -1) {
this.context.warnings.push('Broken comment: \'' + data.substring(nextStart) + '\'.');
nextEnd = data.length - 2;
}
tempData.push(data.substring(cursor, nextStart));
var comment = data.substring(nextStart, nextEnd + COMMENT_SUFFIX.length);
var isSpecialComment = comment.indexOf(SPECIAL_COMMENT_PREFIX) === 0;
if (saveWaypoints) {
breaksCount = comment.split(lineBreak).length - 1;
lastBreakAt = comment.lastIndexOf(lineBreak);
newIndent = lastBreakAt > 0 ?
comment.substring(lastBreakAt + lineBreak.length).length :
indent + comment.length;
}
if (saveWaypoints || isSpecialComment) {
var metadata = saveWaypoints ? [breaksCount, newIndent] : null;
var placeholder = isSpecialComment ?
this.specialComments.store(comment, metadata) :
this.comments.store(comment, metadata);
tempData.push(placeholder);
}
if (saveWaypoints)
indent = newIndent + 1;
cursor = nextEnd + COMMENT_SUFFIX.length;
}
return tempData.length > 0 ?
tempData.join('') + data.substring(cursor, data.length) :
data;
};
function restore(context, data, from, isSpecial) {
var tempData = [];
var cursor = 0;
for (; cursor < data.length;) {
var nextMatch = from.nextMatch(data, cursor);
if (nextMatch.start < 0)
break;
tempData.push(data.substring(cursor, nextMatch.start));
var comment = from.restore(nextMatch.match);
if (isSpecial && (context.keepAll || (context.keepOne && context.restored === 0))) {
context.restored++;
tempData.push(comment);
cursor = nextMatch.end;
} else {
cursor = nextMatch.end + (context.keepBreaks && data.substring(nextMatch.end, nextMatch.end + lineBreak.length) == lineBreak ? lineBreak.length : 0);
}
}
return tempData.length > 0 ?
tempData.join('') + data.substring(cursor, data.length) :
data;
}
CommentsProcessor.prototype.restore = function (data) {
data = restore(this, data, this.comments, false);
data = restore(this, data, this.specialComments, true);
return data;
};
module.exports = CommentsProcessor;

53
node_modules/clean-css/lib/text/escape-store.js generated vendored Normal file
View File

@@ -0,0 +1,53 @@
var placeholderBrace = '__';
function EscapeStore(placeholderRoot) {
this.placeholderRoot = 'ESCAPED_' + placeholderRoot + '_CLEAN_CSS';
this.placeholderToData = {};
this.dataToPlaceholder = {};
this.count = 0;
this.restoreMatcher = new RegExp(this.placeholderRoot + '(\\d+)');
}
EscapeStore.prototype._nextPlaceholder = function (metadata) {
return {
index: this.count,
value: placeholderBrace + this.placeholderRoot + this.count++ + metadata + placeholderBrace
};
};
EscapeStore.prototype.store = function (data, metadata) {
var encodedMetadata = metadata ?
'(' + metadata.join(',') + ')' :
'';
var placeholder = this.dataToPlaceholder[data];
if (!placeholder) {
var nextPlaceholder = this._nextPlaceholder(encodedMetadata);
placeholder = nextPlaceholder.value;
this.placeholderToData[nextPlaceholder.index] = data;
this.dataToPlaceholder[data] = nextPlaceholder.value;
}
if (metadata)
placeholder = placeholder.replace(/\([^\)]+\)/, encodedMetadata);
return placeholder;
};
EscapeStore.prototype.nextMatch = function (data, cursor) {
var next = {};
next.start = data.indexOf(this.placeholderRoot, cursor) - placeholderBrace.length;
next.end = data.indexOf(placeholderBrace, next.start + placeholderBrace.length) + placeholderBrace.length;
if (next.start > -1 && next.end > -1)
next.match = data.substring(next.start, next.end);
return next;
};
EscapeStore.prototype.restore = function (placeholder) {
var index = this.restoreMatcher.exec(placeholder)[1];
return this.placeholderToData[index];
};
module.exports = EscapeStore;

View File

@@ -0,0 +1,117 @@
var EscapeStore = require('./escape-store');
var EXPRESSION_NAME = 'expression';
var EXPRESSION_START = '(';
var EXPRESSION_END = ')';
var EXPRESSION_PREFIX = EXPRESSION_NAME + EXPRESSION_START;
var BODY_START = '{';
var BODY_END = '}';
var lineBreak = require('os').EOL;
function findEnd(data, start) {
var end = start + EXPRESSION_NAME.length;
var level = 0;
var quoted = false;
var braced = false;
while (true) {
var current = data[end++];
if (quoted) {
quoted = current != '\'' && current != '"';
} else {
quoted = current == '\'' || current == '"';
if (current == EXPRESSION_START)
level++;
if (current == EXPRESSION_END)
level--;
if (current == BODY_START)
braced = true;
if (current == BODY_END && !braced && level == 1) {
end--;
level--;
}
}
if (level === 0 && current == EXPRESSION_END)
break;
if (!current) {
end = data.substring(0, end).lastIndexOf(BODY_END);
break;
}
}
return end;
}
function ExpressionsProcessor(saveWaypoints) {
this.expressions = new EscapeStore('EXPRESSION');
this.saveWaypoints = saveWaypoints;
}
ExpressionsProcessor.prototype.escape = function (data) {
var nextStart = 0;
var nextEnd = 0;
var cursor = 0;
var tempData = [];
var indent = 0;
var breaksCount;
var lastBreakAt;
var newIndent;
var saveWaypoints = this.saveWaypoints;
for (; nextEnd < data.length;) {
nextStart = data.indexOf(EXPRESSION_PREFIX, nextEnd);
if (nextStart == -1)
break;
nextEnd = findEnd(data, nextStart);
var expression = data.substring(nextStart, nextEnd);
if (saveWaypoints) {
breaksCount = expression.split(lineBreak).length - 1;
lastBreakAt = expression.lastIndexOf(lineBreak);
newIndent = lastBreakAt > 0 ?
expression.substring(lastBreakAt + lineBreak.length).length :
indent + expression.length;
}
var metadata = saveWaypoints ? [breaksCount, newIndent] : null;
var placeholder = this.expressions.store(expression, metadata);
tempData.push(data.substring(cursor, nextStart));
tempData.push(placeholder);
if (saveWaypoints)
indent = newIndent + 1;
cursor = nextEnd;
}
return tempData.length > 0 ?
tempData.join('') + data.substring(cursor, data.length) :
data;
};
ExpressionsProcessor.prototype.restore = function (data) {
var tempData = [];
var cursor = 0;
for (; cursor < data.length;) {
var nextMatch = this.expressions.nextMatch(data, cursor);
if (nextMatch.start < 0)
break;
tempData.push(data.substring(cursor, nextMatch.start));
var comment = this.expressions.restore(nextMatch.match);
tempData.push(comment);
cursor = nextMatch.end;
}
return tempData.length > 0 ?
tempData.join('') + data.substring(cursor, data.length) :
data;
};
module.exports = ExpressionsProcessor;

98
node_modules/clean-css/lib/text/free-text-processor.js generated vendored Normal file
View File

@@ -0,0 +1,98 @@
var EscapeStore = require('./escape-store');
var QuoteScanner = require('../utils/quote-scanner');
var lineBreak = require('os').EOL;
function FreeTextProcessor(saveWaypoints) {
this.matches = new EscapeStore('FREE_TEXT');
this.saveWaypoints = saveWaypoints;
}
// Strip content tags by replacing them by the a special
// marker for further restoring. It's done via string scanning
// instead of regexps to speed up the process.
FreeTextProcessor.prototype.escape = function (data) {
var self = this;
var breaksCount;
var lastBreakAt;
var indent;
var metadata;
var saveWaypoints = this.saveWaypoints;
return new QuoteScanner(data).each(function (match, store) {
if (saveWaypoints) {
breaksCount = match.split(lineBreak).length - 1;
lastBreakAt = match.lastIndexOf(lineBreak);
indent = lastBreakAt > 0 ?
match.substring(lastBreakAt + lineBreak.length).length :
match.length;
metadata = [breaksCount, indent];
}
var placeholder = self.matches.store(match, metadata);
store.push(placeholder);
});
};
function normalize(text, data, prefixContext, cursor) {
// FIXME: this is even a bigger hack now - see #407
var searchIn = data;
if (prefixContext) {
searchIn = prefixContext + data.substring(0, data.indexOf('__ESCAPED_FREE_TEXT_CLEAN_CSS'));
cursor = searchIn.length;
}
var lastSemicolon = searchIn.lastIndexOf(';', cursor);
var lastOpenBrace = searchIn.lastIndexOf('{', cursor);
var lastOne = 0;
if (lastSemicolon > -1 && lastOpenBrace > -1)
lastOne = Math.max(lastSemicolon, lastOpenBrace);
else if (lastSemicolon == -1)
lastOne = lastOpenBrace;
else
lastOne = lastSemicolon;
var context = searchIn.substring(lastOne + 1, cursor);
if (/\[[\w\d\-]+[\*\|\~\^\$]?=$/.test(context)) {
text = text
.replace(/\\\n|\\\r\n/g, '')
.replace(/\n|\r\n/g, '');
}
if (/^['"][a-zA-Z][a-zA-Z\d\-_]+['"]$/.test(text) && !/format\($/.test(context)) {
var isFont = /^(font|font\-family):/.test(context);
var isAttribute = /\[[\w\d\-]+[\*\|\~\^\$]?=$/.test(context);
var isKeyframe = /@(-moz-|-o-|-webkit-)?keyframes /.test(context);
var isAnimation = /^(-moz-|-o-|-webkit-)?animation(-name)?:/.test(context);
if (isFont || isAttribute || isKeyframe || isAnimation)
text = text.substring(1, text.length - 1);
}
return text;
}
FreeTextProcessor.prototype.restore = function (data, prefixContext) {
var tempData = [];
var cursor = 0;
for (; cursor < data.length;) {
var nextMatch = this.matches.nextMatch(data, cursor);
if (nextMatch.start < 0)
break;
tempData.push(data.substring(cursor, nextMatch.start));
var text = normalize(this.matches.restore(nextMatch.match), data, prefixContext, nextMatch.start);
tempData.push(text);
cursor = nextMatch.end;
}
return tempData.length > 0 ?
tempData.join('') + data.substring(cursor, data.length) :
data;
};
module.exports = FreeTextProcessor;

75
node_modules/clean-css/lib/text/urls-processor.js generated vendored Normal file
View File

@@ -0,0 +1,75 @@
var EscapeStore = require('./escape-store');
var reduceUrls = require('../urls/reduce');
var lineBreak = require('os').EOL;
function UrlsProcessor(context, saveWaypoints, keepUrlQuotes) {
this.urls = new EscapeStore('URL');
this.context = context;
this.saveWaypoints = saveWaypoints;
this.keepUrlQuotes = keepUrlQuotes;
}
// Strip urls by replacing them by a special
// marker for further restoring. It's done via string scanning
// instead of regexps to speed up the process.
UrlsProcessor.prototype.escape = function (data) {
var breaksCount;
var lastBreakAt;
var indent;
var saveWaypoints = this.saveWaypoints;
var self = this;
return reduceUrls(data, this.context, function (url, tempData) {
if (saveWaypoints) {
breaksCount = url.split(lineBreak).length - 1;
lastBreakAt = url.lastIndexOf(lineBreak);
indent = lastBreakAt > 0 ?
url.substring(lastBreakAt + lineBreak.length).length :
url.length;
}
var placeholder = self.urls.store(url, saveWaypoints ? [breaksCount, indent] : null);
tempData.push(placeholder);
});
};
function normalize(url, keepUrlQuotes) {
url = url
.replace(/^url/gi, 'url')
.replace(/\\?\n|\\?\r\n/g, '')
.replace(/(\s{2,}|\s)/g, ' ')
.replace(/^url\((['"])? /, 'url($1')
.replace(/ (['"])?\)$/, '$1)');
if (/url\(".*'.*"\)/.test(url) || /url\('.*".*'\)/.test(url))
return url;
if (!keepUrlQuotes && !/^['"].+['"]$/.test(url) && !/url\(.*[\s\(\)].*\)/.test(url) && !/url\(['"]data:[^;]+;charset/.test(url))
url = url.replace(/["']/g, '');
return url;
}
UrlsProcessor.prototype.restore = function (data) {
var tempData = [];
var cursor = 0;
for (; cursor < data.length;) {
var nextMatch = this.urls.nextMatch(data, cursor);
if (nextMatch.start < 0)
break;
tempData.push(data.substring(cursor, nextMatch.start));
var url = normalize(this.urls.restore(nextMatch.match), this.keepUrlQuotes);
tempData.push(url);
cursor = nextMatch.end;
}
return tempData.length > 0 ?
tempData.join('') + data.substring(cursor, data.length) :
data;
};
module.exports = UrlsProcessor;

View File

@@ -0,0 +1,193 @@
var split = require('../utils/split');
var COMMA = ',';
var FORWARD_SLASH = '/';
var AT_RULE = 'at-rule';
var IMPORTANT_WORD = 'important';
var IMPORTANT_TOKEN = '!'+IMPORTANT_WORD;
var IMPORTANT_WORD_MATCH = new RegExp('^'+IMPORTANT_WORD+'$', 'i');
var IMPORTANT_TOKEN_MATCH = new RegExp('^'+IMPORTANT_TOKEN+'$', 'i');
function selectorName(value) {
return value[0];
}
function noop() {}
function withoutComments(string, into, heading, context) {
var matcher = heading ? /^__ESCAPED_COMMENT_/ : /__ESCAPED_COMMENT_/;
var track = heading ? context.track : noop; // don't track when comment not in a heading as we do it later in `trackComments`
while (matcher.test(string)) {
var startOfComment = string.indexOf('__');
var endOfComment = string.indexOf('__', startOfComment + 1) + 2;
var comment = string.substring(startOfComment, endOfComment);
string = string.substring(0, startOfComment) + string.substring(endOfComment);
track(comment);
into.push(comment);
}
return string;
}
function withoutHeadingComments(string, into, context) {
return withoutComments(string, into, true, context);
}
function withoutInnerComments(string, into, context) {
return withoutComments(string, into, false, context);
}
function trackComments(comments, into, context) {
for (var i = 0, l = comments.length; i < l; i++) {
context.track(comments[i]);
into.push(comments[i]);
}
}
function extractProperties(string, selectors, context) {
var list = [];
var innerComments = [];
var valueSeparator = /[\s,\/]/;
if (typeof string != 'string')
return [];
if (string.indexOf(')') > -1)
string = string.replace(/\)([^\s_;:,\)])/g, context.sourceMap ? ') __ESCAPED_COMMENT_CLEAN_CSS(0,-1)__ $1' : ') $1');
if (string.indexOf('ESCAPED_URL_CLEAN_CSS') > -1)
string = string.replace(/(ESCAPED_URL_CLEAN_CSS[^_]+?__)/g, context.sourceMap ? '$1 __ESCAPED_COMMENT_CLEAN_CSS(0,-1)__ ' : '$1 ');
var candidates = split(string, ';', false, '{', '}');
for (var i = 0, l = candidates.length; i < l; i++) {
var candidate = candidates[i];
var firstColonAt = candidate.indexOf(':');
var atRule = candidate.trim()[0] == '@';
if (atRule) {
context.track(candidate);
list.push([AT_RULE, candidate.trim()]);
continue;
}
if (firstColonAt == -1) {
context.track(candidate);
if (candidate.indexOf('__ESCAPED_COMMENT_SPECIAL') > -1)
list.push(candidate.trim());
continue;
}
if (candidate.indexOf('{') > 0 && candidate.indexOf('{') < firstColonAt) {
context.track(candidate);
continue;
}
var body = [];
var name = candidate.substring(0, firstColonAt);
innerComments = [];
if (name.indexOf('__ESCAPED_COMMENT') > -1)
name = withoutHeadingComments(name, list, context);
if (name.indexOf('__ESCAPED_COMMENT') > -1)
name = withoutInnerComments(name, innerComments, context);
body.push([name.trim()].concat(context.track(name, true)));
context.track(':');
trackComments(innerComments, list, context);
var firstBraceAt = candidate.indexOf('{');
var isVariable = name.trim().indexOf('--') === 0;
if (isVariable && firstBraceAt > 0) {
var blockPrefix = candidate.substring(firstColonAt + 1, firstBraceAt + 1);
var blockSuffix = candidate.substring(candidate.indexOf('}'));
var blockContent = candidate.substring(firstBraceAt + 1, candidate.length - blockSuffix.length);
context.track(blockPrefix);
body.push(extractProperties(blockContent, selectors, context));
list.push(body);
context.track(blockSuffix);
context.track(i < l - 1 ? ';' : '');
continue;
}
var values = split(candidate.substring(firstColonAt + 1), valueSeparator, true);
if (values.length == 1 && values[0] === '') {
context.warnings.push('Empty property \'' + name + '\' inside \'' + selectors.filter(selectorName).join(',') + '\' selector. Ignoring.');
continue;
}
for (var j = 0, m = values.length; j < m; j++) {
var value = values[j];
var trimmed = value.trim();
if (trimmed.length === 0)
continue;
var lastCharacter = trimmed[trimmed.length - 1];
var endsWithNonSpaceSeparator = trimmed.length > 1 && (lastCharacter == COMMA || lastCharacter == FORWARD_SLASH);
if (endsWithNonSpaceSeparator)
trimmed = trimmed.substring(0, trimmed.length - 1);
if (trimmed.indexOf('__ESCAPED_COMMENT_CLEAN_CSS(0,-') > -1) {
context.track(trimmed);
continue;
}
innerComments = [];
if (trimmed.indexOf('__ESCAPED_COMMENT') > -1)
trimmed = withoutHeadingComments(trimmed, list, context);
if (trimmed.indexOf('__ESCAPED_COMMENT') > -1)
trimmed = withoutInnerComments(trimmed, innerComments, context);
if (trimmed.length === 0) {
trackComments(innerComments, list, context);
continue;
}
var pos = body.length - 1;
if (IMPORTANT_WORD_MATCH.test(trimmed) && body[pos][0] == '!') {
context.track(trimmed);
body[pos - 1][0] += IMPORTANT_TOKEN;
body.pop();
continue;
}
if (IMPORTANT_TOKEN_MATCH.test(trimmed) || (IMPORTANT_WORD_MATCH.test(trimmed) && body[pos][0][body[pos][0].length - 1] == '!')) {
context.track(trimmed);
body[pos][0] += trimmed;
continue;
}
body.push([trimmed].concat(context.track(value, true)));
trackComments(innerComments, list, context);
if (endsWithNonSpaceSeparator) {
body.push([lastCharacter]);
context.track(lastCharacter);
}
}
if (i < l - 1)
context.track(';');
list.push(body);
}
return list;
}
module.exports = extractProperties;

View File

@@ -0,0 +1,17 @@
var split = require('../utils/split');
function extractSelectors(string, context) {
var list = [];
var metadata;
var selectors = split(string, ',');
for (var i = 0, l = selectors.length; i < l; i++) {
metadata = context.track(selectors[i], true, i);
context.track(',');
list.push([selectors[i].trim()].concat(metadata));
}
return list;
}
module.exports = extractSelectors;

268
node_modules/clean-css/lib/tokenizer/tokenize.js generated vendored Normal file
View File

@@ -0,0 +1,268 @@
var extractProperties = require('./extract-properties');
var extractSelectors = require('./extract-selectors');
var track = require('../source-maps/track');
var split = require('../utils/split');
var path = require('path');
var flatBlock = /(@(font\-face|page|\-ms\-viewport|\-o\-viewport|viewport|counter\-style)|\\@.+?)/;
function tokenize(data, outerContext) {
var chunks = split(normalize(data), '}', true, '{', '}');
if (chunks.length === 0)
return [];
var context = {
chunk: chunks.shift(),
chunks: chunks,
column: 0,
cursor: 0,
line: 1,
mode: 'top',
resolvePath: outerContext.options.explicitTarget ?
relativePathResolver(outerContext.options.root, outerContext.options.target) :
null,
source: undefined,
sourceMap: outerContext.options.sourceMap,
sourceMapInlineSources: outerContext.options.sourceMapInlineSources,
sourceMapTracker: outerContext.inputSourceMapTracker,
sourceReader: outerContext.sourceReader,
sourceTracker: outerContext.sourceTracker,
state: [],
track: outerContext.options.sourceMap ?
function (data, snapshotMetadata, fallbacks) { return [[track(data, context, snapshotMetadata, fallbacks)]]; } :
function () { return []; },
warnings: outerContext.warnings
};
return intoTokens(context);
}
function normalize(data) {
return data.replace(/\r\n/g, '\n');
}
function relativePathResolver(root, target) {
var rebaseTo = path.relative(root, target);
return function (relativeTo, sourcePath) {
return relativeTo != sourcePath ?
path.normalize(path.join(path.relative(rebaseTo, path.dirname(relativeTo)), sourcePath)) :
sourcePath;
};
}
function whatsNext(context) {
var mode = context.mode;
var chunk = context.chunk;
var closest;
if (chunk.length == context.cursor) {
if (context.chunks.length === 0)
return null;
context.chunk = chunk = context.chunks.shift();
context.cursor = 0;
}
if (mode == 'body') {
if (chunk[context.cursor] == '}')
return [context.cursor, 'bodyEnd'];
if (chunk.indexOf('}', context.cursor) == -1)
return null;
closest = context.cursor + split(chunk.substring(context.cursor - 1), '}', true, '{', '}')[0].length - 2;
return [closest, 'bodyEnd'];
}
var nextSpecial = chunk.indexOf('@', context.cursor);
var nextEscape = chunk.indexOf('__ESCAPED_', context.cursor);
var nextBodyStart = chunk.indexOf('{', context.cursor);
var nextBodyEnd = chunk.indexOf('}', context.cursor);
if (nextSpecial > -1 && context.cursor > 0 && !/\s|\{|\}|\/|_|,|;/.test(chunk.substring(nextSpecial - 1, nextSpecial))) {
nextSpecial = -1;
}
if (nextEscape > -1 && /\S/.test(chunk.substring(context.cursor, nextEscape)))
nextEscape = -1;
closest = nextSpecial;
if (closest == -1 || (nextEscape > -1 && nextEscape < closest))
closest = nextEscape;
if (closest == -1 || (nextBodyStart > -1 && nextBodyStart < closest))
closest = nextBodyStart;
if (closest == -1 || (nextBodyEnd > -1 && nextBodyEnd < closest))
closest = nextBodyEnd;
if (closest == -1)
return;
if (nextEscape === closest)
return [closest, 'escape'];
if (nextBodyStart === closest)
return [closest, 'bodyStart'];
if (nextBodyEnd === closest)
return [closest, 'bodyEnd'];
if (nextSpecial === closest)
return [closest, 'special'];
}
function intoTokens(context) {
var chunk = context.chunk;
var tokenized = [];
var newToken;
var value;
while (true) {
var next = whatsNext(context);
if (!next) {
var whatsLeft = context.chunk.substring(context.cursor);
if (whatsLeft.trim().length > 0) {
if (context.mode == 'body') {
context.warnings.push('Missing \'}\' after \'' + whatsLeft + '\'. Ignoring.');
} else {
tokenized.push(['text', [whatsLeft]]);
}
context.cursor += whatsLeft.length;
}
break;
}
var nextSpecial = next[0];
var what = next[1];
var nextEnd;
var oldMode;
chunk = context.chunk;
if (context.cursor != nextSpecial && what != 'bodyEnd') {
var spacing = chunk.substring(context.cursor, nextSpecial);
var leadingWhitespace = /^\s+/.exec(spacing);
if (leadingWhitespace) {
context.cursor += leadingWhitespace[0].length;
context.track(leadingWhitespace[0]);
}
}
if (what == 'special') {
var firstOpenBraceAt = chunk.indexOf('{', nextSpecial);
var firstSemicolonAt = chunk.indexOf(';', nextSpecial);
var isSingle = firstSemicolonAt > -1 && (firstOpenBraceAt == -1 || firstSemicolonAt < firstOpenBraceAt);
var isBroken = firstOpenBraceAt == -1 && firstSemicolonAt == -1;
if (isBroken) {
context.warnings.push('Broken declaration: \'' + chunk.substring(context.cursor) + '\'.');
context.cursor = chunk.length;
} else if (isSingle) {
nextEnd = chunk.indexOf(';', nextSpecial + 1);
value = chunk.substring(context.cursor, nextEnd + 1);
tokenized.push([
'at-rule',
[value].concat(context.track(value, true))
]);
context.track(';');
context.cursor = nextEnd + 1;
} else {
nextEnd = chunk.indexOf('{', nextSpecial + 1);
value = chunk.substring(context.cursor, nextEnd);
var trimmedValue = value.trim();
var isFlat = flatBlock.test(trimmedValue);
oldMode = context.mode;
context.cursor = nextEnd + 1;
context.mode = isFlat ? 'body' : 'block';
newToken = [
isFlat ? 'flat-block' : 'block'
];
newToken.push([trimmedValue].concat(context.track(value, true)));
context.track('{');
newToken.push(intoTokens(context));
if (typeof newToken[2] == 'string')
newToken[2] = extractProperties(newToken[2], [[trimmedValue]], context);
context.mode = oldMode;
context.track('}');
tokenized.push(newToken);
}
} else if (what == 'escape') {
nextEnd = chunk.indexOf('__', nextSpecial + 1);
var escaped = chunk.substring(context.cursor, nextEnd + 2);
var isStartSourceMarker = !!context.sourceTracker.nextStart(escaped);
var isEndSourceMarker = !!context.sourceTracker.nextEnd(escaped);
if (isStartSourceMarker) {
context.track(escaped);
context.state.push({
source: context.source,
line: context.line,
column: context.column
});
context.source = context.sourceTracker.nextStart(escaped).filename;
context.line = 1;
context.column = 0;
} else if (isEndSourceMarker) {
var oldState = context.state.pop();
context.source = oldState.source;
context.line = oldState.line;
context.column = oldState.column;
context.track(escaped);
} else {
if (escaped.indexOf('__ESCAPED_COMMENT_SPECIAL') === 0)
tokenized.push(['text', [escaped]]);
context.track(escaped);
}
context.cursor = nextEnd + 2;
} else if (what == 'bodyStart') {
var selectors = extractSelectors(chunk.substring(context.cursor, nextSpecial), context);
oldMode = context.mode;
context.cursor = nextSpecial + 1;
context.mode = 'body';
var body = extractProperties(intoTokens(context), selectors, context);
context.track('{');
context.mode = oldMode;
tokenized.push([
'selector',
selectors,
body
]);
} else if (what == 'bodyEnd') {
// extra closing brace at the top level can be safely ignored
if (context.mode == 'top') {
var at = context.cursor;
var warning = chunk[context.cursor] == '}' ?
'Unexpected \'}\' in \'' + chunk.substring(at - 20, at + 20) + '\'. Ignoring.' :
'Unexpected content: \'' + chunk.substring(at, nextSpecial + 1) + '\'. Ignoring.';
context.warnings.push(warning);
context.cursor = nextSpecial + 1;
continue;
}
if (context.mode == 'block')
context.track(chunk.substring(context.cursor, nextSpecial));
if (context.mode != 'block')
tokenized = chunk.substring(context.cursor, nextSpecial);
context.cursor = nextSpecial + 1;
break;
}
}
return tokenized;
}
module.exports = tokenize;

30
node_modules/clean-css/lib/urls/rebase.js generated vendored Normal file
View File

@@ -0,0 +1,30 @@
var path = require('path');
var rewriteUrls = require('./rewrite');
function rebaseUrls(data, context) {
var rebaseOpts = {
absolute: context.options.explicitRoot,
relative: !context.options.explicitRoot && context.options.explicitTarget,
fromBase: context.options.relativeTo
};
if (!rebaseOpts.absolute && !rebaseOpts.relative)
return data;
if (rebaseOpts.absolute && context.options.explicitTarget)
context.warnings.push('Both \'root\' and output file given so rebasing URLs as absolute paths');
if (rebaseOpts.absolute)
rebaseOpts.toBase = path.resolve(context.options.root);
if (rebaseOpts.relative)
rebaseOpts.toBase = path.resolve(context.options.target);
if (!rebaseOpts.fromBase || !rebaseOpts.toBase)
return data;
return rewriteUrls(data, rebaseOpts, context);
}
module.exports = rebaseUrls;

154
node_modules/clean-css/lib/urls/reduce.js generated vendored Normal file
View File

@@ -0,0 +1,154 @@
var split = require('../utils/split');
var URL_PREFIX = 'url(';
var UPPERCASE_URL_PREFIX = 'URL(';
var URL_SUFFIX = ')';
var SINGLE_QUOTE_URL_SUFFIX = '\')';
var DOUBLE_QUOTE_URL_SUFFIX = '")';
var DATA_URI_PREFIX_PATTERN = /^\s*['"]?\s*data:/;
var DATA_URI_TRAILER_PATTERN = /[\s\};,\/!]/;
var IMPORT_URL_PREFIX = '@import';
var UPPERCASE_IMPORT_URL_PREFIX = '@IMPORT';
var COMMENT_END_MARKER = /\*\//;
function byUrl(data, context, callback) {
var nextStart = 0;
var nextStartUpperCase = 0;
var nextEnd = 0;
var firstMatch;
var isDataURI = false;
var cursor = 0;
var tempData = [];
var hasUppercaseUrl = data.indexOf(UPPERCASE_URL_PREFIX) > -1;
for (; nextEnd < data.length;) {
nextStart = data.indexOf(URL_PREFIX, nextEnd);
nextStartUpperCase = hasUppercaseUrl ? data.indexOf(UPPERCASE_URL_PREFIX, nextEnd) : -1;
if (nextStart == -1 && nextStartUpperCase == -1)
break;
if (nextStart == -1 && nextStartUpperCase > -1)
nextStart = nextStartUpperCase;
if (data[nextStart + URL_PREFIX.length] == '"') {
nextEnd = data.indexOf(DOUBLE_QUOTE_URL_SUFFIX, nextStart);
} else if (data[nextStart + URL_PREFIX.length] == '\'') {
nextEnd = data.indexOf(SINGLE_QUOTE_URL_SUFFIX, nextStart);
} else {
isDataURI = DATA_URI_PREFIX_PATTERN.test(data.substring(nextStart + URL_PREFIX.length));
if (isDataURI) {
firstMatch = split(data.substring(nextStart), DATA_URI_TRAILER_PATTERN, false, '(', ')', true).pop();
if (firstMatch && firstMatch[firstMatch.length - 1] == URL_SUFFIX) {
nextEnd = nextStart + firstMatch.length - URL_SUFFIX.length;
} else {
nextEnd = -1;
}
} else {
nextEnd = data.indexOf(URL_SUFFIX, nextStart);
}
}
// Following lines are a safety mechanism to ensure
// incorrectly terminated urls are processed correctly.
if (nextEnd == -1) {
nextEnd = data.indexOf('}', nextStart);
if (nextEnd == -1)
nextEnd = data.length;
else
nextEnd--;
context.warnings.push('Broken URL declaration: \'' + data.substring(nextStart, nextEnd + 1) + '\'.');
} else {
if (data[nextEnd] != URL_SUFFIX)
nextEnd = data.indexOf(URL_SUFFIX, nextEnd);
}
tempData.push(data.substring(cursor, nextStart));
var url = data.substring(nextStart, nextEnd + 1);
callback(url, tempData);
cursor = nextEnd + 1;
}
return tempData.length > 0 ?
tempData.join('') + data.substring(cursor, data.length) :
data;
}
function byImport(data, context, callback) {
var nextImport = 0;
var nextImportUpperCase = 0;
var nextStart = 0;
var nextEnd = 0;
var cursor = 0;
var tempData = [];
var nextSingleQuote = 0;
var nextDoubleQuote = 0;
var untilNextQuote;
var withQuote;
var SINGLE_QUOTE = '\'';
var DOUBLE_QUOTE = '"';
for (; nextEnd < data.length;) {
nextImport = data.indexOf(IMPORT_URL_PREFIX, nextEnd);
nextImportUpperCase = data.indexOf(UPPERCASE_IMPORT_URL_PREFIX, nextEnd);
if (nextImport == -1 && nextImportUpperCase == -1)
break;
if (nextImport > -1 && nextImportUpperCase > -1 && nextImportUpperCase < nextImport)
nextImport = nextImportUpperCase;
nextSingleQuote = data.indexOf(SINGLE_QUOTE, nextImport);
nextDoubleQuote = data.indexOf(DOUBLE_QUOTE, nextImport);
if (nextSingleQuote > -1 && nextDoubleQuote > -1 && nextSingleQuote < nextDoubleQuote) {
nextStart = nextSingleQuote;
withQuote = SINGLE_QUOTE;
} else if (nextSingleQuote > -1 && nextDoubleQuote > -1 && nextSingleQuote > nextDoubleQuote) {
nextStart = nextDoubleQuote;
withQuote = DOUBLE_QUOTE;
} else if (nextSingleQuote > -1) {
nextStart = nextSingleQuote;
withQuote = SINGLE_QUOTE;
} else if (nextDoubleQuote > -1) {
nextStart = nextDoubleQuote;
withQuote = DOUBLE_QUOTE;
} else {
break;
}
tempData.push(data.substring(cursor, nextStart));
nextEnd = data.indexOf(withQuote, nextStart + 1);
untilNextQuote = data.substring(nextImport, nextEnd);
if (nextEnd == -1 || /^@import\s+(url\(|__ESCAPED)/i.test(untilNextQuote) || COMMENT_END_MARKER.test(untilNextQuote)) {
cursor = nextStart;
break;
}
var url = data.substring(nextStart, nextEnd + 1);
callback(url, tempData);
cursor = nextEnd + 1;
}
return tempData.length > 0 ?
tempData.join('') + data.substring(cursor, data.length) :
data;
}
function reduceAll(data, context, callback) {
data = byUrl(data, context, callback);
data = byImport(data, context, callback);
return data;
}
module.exports = reduceAll;

107
node_modules/clean-css/lib/urls/rewrite.js generated vendored Normal file
View File

@@ -0,0 +1,107 @@
var path = require('path');
var url = require('url');
var reduceUrls = require('./reduce');
var isWindows = process.platform == 'win32';
function isAbsolute(uri) {
return uri[0] == '/';
}
function isSVGMarker(uri) {
return uri[0] == '#';
}
function isEscaped(uri) {
return uri.indexOf('__ESCAPED_URL_CLEAN_CSS__') === 0;
}
function isInternal(uri) {
return /^\w+:\w+/.test(uri);
}
function isRemote(uri) {
return /^[^:]+?:\/\//.test(uri) || uri.indexOf('//') === 0;
}
function isSameOrigin(uri1, uri2) {
return url.parse(uri1).protocol == url.parse(uri2).protocol &&
url.parse(uri1).host == url.parse(uri2).host;
}
function isImport(uri) {
return uri.lastIndexOf('.css') === uri.length - 4;
}
function isData(uri) {
return uri.indexOf('data:') === 0;
}
function absolute(uri, options) {
return path
.resolve(path.join(options.fromBase || '', uri))
.replace(options.toBase, '');
}
function relative(uri, options) {
return path.relative(options.toBase, path.join(options.fromBase || '', uri));
}
function normalize(uri) {
return isWindows ? uri.replace(/\\/g, '/') : uri;
}
function rebase(uri, options) {
if (isAbsolute(uri) || isSVGMarker(uri) || isEscaped(uri) || isInternal(uri))
return uri;
if (options.rebase === false && !isImport(uri))
return uri;
if (!options.imports && isImport(uri))
return uri;
if (isData(uri))
return '\'' + uri + '\'';
if (isRemote(uri) && !isRemote(options.toBase))
return uri;
if (isRemote(uri) && !isSameOrigin(uri, options.toBase))
return uri;
if (!isRemote(uri) && isRemote(options.toBase))
return url.resolve(options.toBase, uri);
return options.absolute ?
normalize(absolute(uri, options)) :
normalize(relative(uri, options));
}
function quoteFor(url) {
if (url.indexOf('\'') > -1)
return '"';
else if (url.indexOf('"') > -1)
return '\'';
else if (/\s/.test(url) || /[\(\)]/.test(url))
return '\'';
else
return '';
}
function rewriteUrls(data, options, context) {
return reduceUrls(data, context, function (originUrl, tempData) {
var url = originUrl.replace(/^(url\()?\s*['"]?|['"]?\s*\)?$/g, '');
var match = originUrl.match(/^(url\()?\s*(['"]).*?(['"])\s*\)?$/);
var quote;
if (!!options.urlQuotes && match && match[2] === match[3]) {
quote = match[2];
} else {
quote = quoteFor(url);
}
tempData.push('url(' + quote + rebase(url, options) + quote + ')');
});
}
module.exports = rewriteUrls;

12
node_modules/clean-css/lib/utils/clone-array.js generated vendored Normal file
View File

@@ -0,0 +1,12 @@
function cloneArray(array) {
var cloned = array.slice(0);
for (var i = 0, l = cloned.length; i < l; i++) {
if (Array.isArray(cloned[i]))
cloned[i] = cloneArray(cloned[i]);
}
return cloned;
}
module.exports = cloneArray;

162
node_modules/clean-css/lib/utils/compatibility.js generated vendored Normal file
View File

@@ -0,0 +1,162 @@
var util = require('util');
var DEFAULTS = {
'*': {
colors: {
opacity: true // rgba / hsla
},
properties: {
backgroundClipMerging: false, // background-clip to shorthand
backgroundOriginMerging: false, // background-origin to shorthand
backgroundSizeMerging: false, // background-size to shorthand
colors: true, // any kind of color transformations, like `#ff00ff` to `#f0f` or `#fff` into `red`
ieBangHack: false, // !ie suffix hacks on IE<8
iePrefixHack: false, // underscore / asterisk prefix hacks on IE
ieSuffixHack: true, // \9 suffix hacks on IE6-9
merging: true, // merging properties into one
shorterLengthUnits: false, // optimize pixel units into `pt`, `pc` or `in` units
spaceAfterClosingBrace: true, // 'url() no-repeat' to 'url()no-repeat'
urlQuotes: false, // whether to wrap content of `url()` into quotes or not
zeroUnits: true // 0[unit] -> 0
},
selectors: {
adjacentSpace: false, // div+ nav Android stock browser hack
ie7Hack: false, // *+html hack
special: /(\-moz\-|\-ms\-|\-o\-|\-webkit\-|:dir\([a-z-]*\)|:first(?![a-z-])|:fullscreen|:left|:read-only|:read-write|:right|:placeholder|:host|:content|\/deep\/|:shadow|:selection|^,)/ // special selectors which prevent merging
},
units: {
ch: true,
in: true,
pc: true,
pt: true,
rem: true,
vh: true,
vm: true, // vm is vmin on IE9+ see https://developer.mozilla.org/en-US/docs/Web/CSS/length
vmax: true,
vmin: true,
vw: true
}
},
'ie8': {
colors: {
opacity: false
},
properties: {
backgroundClipMerging: false,
backgroundOriginMerging: false,
backgroundSizeMerging: false,
colors: true,
ieBangHack: false,
iePrefixHack: true,
ieSuffixHack: true,
merging: false,
shorterLengthUnits: false,
spaceAfterClosingBrace: true,
urlQuotes: false,
zeroUnits: true
},
selectors: {
adjacentSpace: false,
ie7Hack: false,
special: /(\-moz\-|\-ms\-|\-o\-|\-webkit\-|:root|:nth|:first\-of|:last|:only|:empty|:target|:checked|::selection|:enabled|:disabled|:not|:placeholder|:host|::content|\/deep\/|::shadow|^,)/
},
units: {
ch: false,
in: true,
pc: true,
pt: true,
rem: false,
vh: false,
vm: false,
vmax: false,
vmin: false,
vw: false
}
},
'ie7': {
colors: {
opacity: false
},
properties: {
backgroundClipMerging: false,
backgroundOriginMerging: false,
backgroundSizeMerging: false,
colors: true,
ieBangHack: true,
iePrefixHack: true,
ieSuffixHack: true,
merging: false,
shorterLengthUnits: false,
spaceAfterClosingBrace: true,
urlQuotes: false,
zeroUnits: true
},
selectors: {
adjacentSpace: false,
ie7Hack: true,
special: /(\-moz\-|\-ms\-|\-o\-|\-webkit\-|:focus|:before|:after|:root|:nth|:first\-of|:last|:only|:empty|:target|:checked|::selection|:enabled|:disabled|:not|:placeholder|:host|::content|\/deep\/|::shadow|^,)/
},
units: {
ch: false,
in: true,
pc: true,
pt: true,
rem: false,
vh: false,
vm: false,
vmax: false,
vmin: false,
vw: false,
}
}
};
function Compatibility(source) {
this.source = source || {};
}
function merge(source, target) {
for (var key in source) {
var value = source[key];
if (typeof value === 'object' && !util.isRegExp(value))
target[key] = merge(value, target[key] || {});
else
target[key] = key in target ? target[key] : value;
}
return target;
}
function calculateSource(source) {
if (typeof source == 'object')
return source;
if (!/[,\+\-]/.test(source))
return DEFAULTS[source] || DEFAULTS['*'];
var parts = source.split(',');
var template = parts[0] in DEFAULTS ?
DEFAULTS[parts.shift()] :
DEFAULTS['*'];
source = {};
parts.forEach(function (part) {
var isAdd = part[0] == '+';
var key = part.substring(1).split('.');
var group = key[0];
var option = key[1];
source[group] = source[group] || {};
source[group][option] = isAdd;
});
return merge(template, source);
}
Compatibility.prototype.toOptions = function () {
return merge(DEFAULTS['*'], calculateSource(this.source));
};
module.exports = Compatibility;

View File

@@ -0,0 +1,284 @@
var SourceMapConsumer = require('source-map').SourceMapConsumer;
var fs = require('fs');
var path = require('path');
var http = require('http');
var https = require('https');
var url = require('url');
var override = require('../utils/object.js').override;
var MAP_MARKER = /\/\*# sourceMappingURL=(\S+) \*\//;
var REMOTE_RESOURCE = /^(https?:)?\/\//;
var DATA_URI = /^data:(\S*?)?(;charset=[^;]+)?(;[^,]+?)?,(.+)/;
var unescape = global.unescape;
function InputSourceMapStore(outerContext) {
this.options = outerContext.options;
this.errors = outerContext.errors;
this.warnings = outerContext.warnings;
this.sourceTracker = outerContext.sourceTracker;
this.timeout = this.options.inliner.timeout;
this.requestOptions = this.options.inliner.request;
this.localOnly = outerContext.localOnly;
this.relativeTo = outerContext.options.target || process.cwd();
this.maps = {};
this.sourcesContent = {};
}
function fromString(self, _, whenDone) {
self.trackLoaded(undefined, undefined, self.options.sourceMap);
return whenDone();
}
function fromSource(self, data, whenDone, context) {
var nextAt = 0;
function proceedToNext() {
context.cursor += nextAt + 1;
fromSource(self, data, whenDone, context);
}
while (context.cursor < data.length) {
var fragment = data.substring(context.cursor);
var markerStartMatch = self.sourceTracker.nextStart(fragment) || { index: -1 };
var markerEndMatch = self.sourceTracker.nextEnd(fragment) || { index: -1 };
var mapMatch = MAP_MARKER.exec(fragment) || { index: -1 };
var sourceMapFile = mapMatch[1];
nextAt = data.length;
if (markerStartMatch.index > -1)
nextAt = markerStartMatch.index;
if (markerEndMatch.index > -1 && markerEndMatch.index < nextAt)
nextAt = markerEndMatch.index;
if (mapMatch.index > -1 && mapMatch.index < nextAt)
nextAt = mapMatch.index;
if (nextAt == data.length)
break;
if (nextAt == markerStartMatch.index) {
context.files.push(markerStartMatch.filename);
} else if (nextAt == markerEndMatch.index) {
context.files.pop();
} else if (nextAt == mapMatch.index) {
var isRemote = /^https?:\/\//.test(sourceMapFile) || /^\/\//.test(sourceMapFile);
var isDataUri = DATA_URI.test(sourceMapFile);
if (isRemote) {
return fetchMapFile(self, sourceMapFile, context, proceedToNext);
} else {
var sourceFile = context.files[context.files.length - 1];
var sourceMapPath, sourceMapData;
var sourceDir = sourceFile ? path.dirname(sourceFile) : self.options.relativeTo;
if (isDataUri) {
// source map's path is the same as the source file it comes from
sourceMapPath = path.resolve(self.options.root, sourceFile || '');
sourceMapData = fromDataUri(sourceMapFile);
} else {
sourceMapPath = path.resolve(self.options.root, path.join(sourceDir || '', sourceMapFile));
sourceMapData = fs.readFileSync(sourceMapPath, 'utf-8');
}
self.trackLoaded(sourceFile || undefined, sourceMapPath, sourceMapData);
}
}
context.cursor += nextAt + 1;
}
return whenDone();
}
function fromDataUri(uriString) {
var match = DATA_URI.exec(uriString);
var charset = match[2] ? match[2].split(/[=;]/)[2] : 'us-ascii';
var encoding = match[3] ? match[3].split(';')[1] : 'utf8';
var data = encoding == 'utf8' ? unescape(match[4]) : match[4];
var buffer = new Buffer(data, encoding);
buffer.charset = charset;
return buffer.toString();
}
function fetchMapFile(self, sourceUrl, context, done) {
fetch(self, sourceUrl, function (data) {
self.trackLoaded(context.files[context.files.length - 1] || undefined, sourceUrl, data);
done();
}, function (message) {
context.errors.push('Broken source map at "' + sourceUrl + '" - ' + message);
return done();
});
}
function fetch(self, path, onSuccess, onFailure) {
var protocol = path.indexOf('https') === 0 ? https : http;
var requestOptions = override(url.parse(path), self.requestOptions);
var errorHandled = false;
protocol
.get(requestOptions, function (res) {
if (res.statusCode < 200 || res.statusCode > 299)
return onFailure(res.statusCode);
var chunks = [];
res.on('data', function (chunk) {
chunks.push(chunk.toString());
});
res.on('end', function () {
onSuccess(chunks.join(''));
});
})
.on('error', function (res) {
if (errorHandled)
return;
onFailure(res.message);
errorHandled = true;
})
.on('timeout', function () {
if (errorHandled)
return;
onFailure('timeout');
errorHandled = true;
})
.setTimeout(self.timeout);
}
function originalPositionIn(trackedSource, line, column, token, allowNFallbacks) {
var originalPosition;
var maxRange = token.length;
var position = {
line: line,
column: column + maxRange
};
while (maxRange-- > 0) {
position.column--;
originalPosition = trackedSource.data.originalPositionFor(position);
if (originalPosition)
break;
}
if (originalPosition.line === null && line > 1 && allowNFallbacks > 0)
return originalPositionIn(trackedSource, line - 1, column, token, allowNFallbacks - 1);
if (trackedSource.path && originalPosition.source) {
originalPosition.source = REMOTE_RESOURCE.test(trackedSource.path) ?
url.resolve(trackedSource.path, originalPosition.source) :
path.join(trackedSource.path, originalPosition.source);
originalPosition.sourceResolved = true;
}
return originalPosition;
}
function trackContentSources(self, sourceFile) {
var consumer = self.maps[sourceFile].data;
var isRemote = REMOTE_RESOURCE.test(sourceFile);
var sourcesMapping = {};
consumer.sources.forEach(function (file, index) {
var uniquePath = isRemote ?
url.resolve(path.dirname(sourceFile), file) :
path.relative(self.relativeTo, path.resolve(path.dirname(sourceFile || '.'), file));
sourcesMapping[uniquePath] = consumer.sourcesContent && consumer.sourcesContent[index];
});
self.sourcesContent[sourceFile] = sourcesMapping;
}
function _resolveSources(self, remaining, whenDone) {
function processNext() {
return _resolveSources(self, remaining, whenDone);
}
if (remaining.length === 0)
return whenDone();
var current = remaining.shift();
var sourceFile = current[0];
var originalFile = current[1];
var isRemote = REMOTE_RESOURCE.test(sourceFile);
if (isRemote && self.localOnly) {
self.warnings.push('No callback given to `#minify` method, cannot fetch a remote file from "' + originalFile + '"');
return processNext();
}
if (isRemote) {
fetch(self, originalFile, function (data) {
self.sourcesContent[sourceFile][originalFile] = data;
processNext();
}, function (message) {
self.warnings.push('Broken original source file at "' + originalFile + '" - ' + message);
processNext();
});
} else {
var fullPath = path.join(self.options.root, originalFile);
if (fs.existsSync(fullPath))
self.sourcesContent[sourceFile][originalFile] = fs.readFileSync(fullPath, 'utf-8');
else
self.warnings.push('Missing original source file at "' + fullPath + '".');
return processNext();
}
}
InputSourceMapStore.prototype.track = function (data, whenDone) {
return typeof this.options.sourceMap == 'string' ?
fromString(this, data, whenDone) :
fromSource(this, data, whenDone, { files: [], cursor: 0, errors: this.errors });
};
InputSourceMapStore.prototype.trackLoaded = function (sourcePath, mapPath, mapData) {
var relativeTo = this.options.explicitTarget ? this.options.target : this.options.root;
var isRemote = REMOTE_RESOURCE.test(sourcePath);
if (mapPath) {
mapPath = isRemote ?
path.dirname(mapPath) :
path.dirname(path.relative(relativeTo, mapPath));
}
this.maps[sourcePath] = {
path: mapPath,
data: new SourceMapConsumer(mapData)
};
trackContentSources(this, sourcePath);
};
InputSourceMapStore.prototype.isTracking = function (source) {
return !!this.maps[source];
};
InputSourceMapStore.prototype.originalPositionFor = function (sourceInfo, token, allowNFallbacks) {
return originalPositionIn(this.maps[sourceInfo.source], sourceInfo.line, sourceInfo.column, token, allowNFallbacks);
};
InputSourceMapStore.prototype.sourcesContentFor = function (contextSource) {
return this.sourcesContent[contextSource];
};
InputSourceMapStore.prototype.resolveSources = function (whenDone) {
var toResolve = [];
for (var sourceFile in this.sourcesContent) {
var contents = this.sourcesContent[sourceFile];
for (var originalFile in contents) {
if (!contents[originalFile])
toResolve.push([sourceFile, originalFile]);
}
}
return _resolveSources(this, toResolve, whenDone);
};
module.exports = InputSourceMapStore;

11
node_modules/clean-css/lib/utils/object.js generated vendored Normal file
View File

@@ -0,0 +1,11 @@
module.exports = {
override: function (source1, source2) {
var target = {};
for (var key1 in source1)
target[key1] = source1[key1];
for (var key2 in source2)
target[key2] = source2[key2];
return target;
}
};

119
node_modules/clean-css/lib/utils/quote-scanner.js generated vendored Normal file
View File

@@ -0,0 +1,119 @@
var COMMENT_START_MARK = '/*';
function QuoteScanner(data) {
this.data = data;
}
var findQuoteEnd = function (data, matched, cursor, oldCursor) {
var commentEndMark = '*/';
var escapeMark = '\\';
var blockEndMark = '}';
var dataPrefix = data.substring(oldCursor, cursor);
var commentEndedAt = dataPrefix.lastIndexOf(commentEndMark, cursor);
var commentStartedAt = findLastCommentStartedAt(dataPrefix, cursor);
var commentStarted = false;
if (commentEndedAt >= cursor && commentStartedAt > -1)
commentStarted = true;
if (commentStartedAt < cursor && commentStartedAt > commentEndedAt)
commentStarted = true;
if (commentStarted) {
var commentEndsAt = data.indexOf(commentEndMark, cursor);
if (commentEndsAt > -1)
return commentEndsAt;
commentEndsAt = data.indexOf(blockEndMark, cursor);
return commentEndsAt > -1 ? commentEndsAt - 1 : data.length;
}
while (true) {
if (data[cursor] === undefined)
break;
if (data[cursor] == matched && (data[cursor - 1] != escapeMark || data[cursor - 2] == escapeMark))
break;
cursor++;
}
return cursor;
};
function findLastCommentStartedAt(data, cursor) {
var position = cursor;
while (position > -1) {
position = data.lastIndexOf(COMMENT_START_MARK, position);
if (position > -1 && data[position - 1] != '*') {
break;
} else {
position--;
}
}
return position;
}
function findNext(data, mark, startAt) {
var escapeMark = '\\';
var candidate = startAt;
while (true) {
candidate = data.indexOf(mark, candidate + 1);
if (candidate == -1)
return -1;
if (data[candidate - 1] != escapeMark)
return candidate;
}
}
QuoteScanner.prototype.each = function (callback) {
var data = this.data;
var tempData = [];
var nextStart = 0;
var nextEnd = 0;
var cursor = 0;
var matchedMark = null;
var singleMark = '\'';
var doubleMark = '"';
var dataLength = data.length;
for (; nextEnd < data.length;) {
var nextStartSingle = findNext(data, singleMark, nextEnd);
var nextStartDouble = findNext(data, doubleMark, nextEnd);
if (nextStartSingle == -1)
nextStartSingle = dataLength;
if (nextStartDouble == -1)
nextStartDouble = dataLength;
if (nextStartSingle < nextStartDouble) {
nextStart = nextStartSingle;
matchedMark = singleMark;
} else {
nextStart = nextStartDouble;
matchedMark = doubleMark;
}
if (nextStart == -1)
break;
nextEnd = findQuoteEnd(data, matchedMark, nextStart + 1, cursor);
if (nextEnd == -1)
break;
var text = data.substring(nextStart, nextEnd + 1);
tempData.push(data.substring(cursor, nextStart));
if (text.length > 0)
callback(text, tempData, nextStart);
cursor = nextEnd + 1;
}
return tempData.length > 0 ?
tempData.join('') + data.substring(cursor, data.length) :
data;
};
module.exports = QuoteScanner;

96
node_modules/clean-css/lib/utils/source-reader.js generated vendored Normal file
View File

@@ -0,0 +1,96 @@
var path = require('path');
var rewriteUrls = require('../urls/rewrite');
var REMOTE_RESOURCE = /^(https?:)?\/\//;
function SourceReader(context, data) {
this.outerContext = context;
this.data = data;
this.sources = {};
}
SourceReader.prototype.sourceAt = function (path) {
return this.sources[path];
};
SourceReader.prototype.trackSource = function (path, source) {
this.sources[path] = {};
this.sources[path][path] = source;
};
SourceReader.prototype.toString = function () {
if (typeof this.data == 'string')
return fromString(this);
if (Buffer.isBuffer(this.data))
return fromBuffer(this);
if (Array.isArray(this.data))
return fromArray(this);
return fromHash(this);
};
function fromString(self) {
var data = self.data;
self.trackSource(undefined, data);
return data;
}
function fromBuffer(self) {
var data = self.data.toString();
self.trackSource(undefined, data);
return data;
}
function fromArray(self) {
return self.data
.map(function (source) {
return self.outerContext.options.processImport === false ?
source + '@shallow' :
source;
})
.map(function (source) {
return !self.outerContext.options.relativeTo || /^https?:\/\//.test(source) ?
source :
path.relative(self.outerContext.options.relativeTo, source);
})
.map(function (source) { return '@import url(' + source + ');'; })
.join('');
}
function fromHash(self) {
var data = [];
var toBase = path.resolve(self.outerContext.options.target || self.outerContext.options.root);
for (var source in self.data) {
var styles = self.data[source].styles;
var inputSourceMap = self.data[source].sourceMap;
var isRemote = REMOTE_RESOURCE.test(source);
var absoluteSource = isRemote ? source : path.resolve(source);
var absoluteSourcePath = path.dirname(absoluteSource);
var rewriteOptions = {
absolute: self.outerContext.options.explicitRoot,
relative: !self.outerContext.options.explicitRoot,
imports: true,
rebase: self.outerContext.options.rebase,
fromBase: absoluteSourcePath,
toBase: isRemote ? absoluteSourcePath : toBase,
urlQuotes: self.outerContext.options.compatibility.properties.urlQuotes
};
styles = rewriteUrls(styles, rewriteOptions, self.outerContext);
self.trackSource(source, styles);
styles = self.outerContext.sourceTracker.store(source, styles);
// here we assume source map lies in the same directory as `source` does
if (self.outerContext.options.sourceMap && inputSourceMap)
self.outerContext.inputSourceMapTracker.trackLoaded(source, source, inputSourceMap);
data.push(styles);
}
return data.join('');
}
module.exports = SourceReader;

31
node_modules/clean-css/lib/utils/source-tracker.js generated vendored Normal file
View File

@@ -0,0 +1,31 @@
function SourceTracker() {
this.sources = [];
}
SourceTracker.prototype.store = function (filename, data) {
this.sources.push(filename);
return '__ESCAPED_SOURCE_CLEAN_CSS' + (this.sources.length - 1) + '__' +
data +
'__ESCAPED_SOURCE_END_CLEAN_CSS__';
};
SourceTracker.prototype.nextStart = function (data) {
var next = /__ESCAPED_SOURCE_CLEAN_CSS(\d+)__/.exec(data);
return next ?
{ index: next.index, filename: this.sources[~~next[1]] } :
null;
};
SourceTracker.prototype.nextEnd = function (data) {
return /__ESCAPED_SOURCE_END_CLEAN_CSS__/g.exec(data);
};
SourceTracker.prototype.removeAll = function (data) {
return data
.replace(/__ESCAPED_SOURCE_CLEAN_CSS\d+__/g, '')
.replace(/__ESCAPED_SOURCE_END_CLEAN_CSS__/g, '');
};
module.exports = SourceTracker;

53
node_modules/clean-css/lib/utils/split.js generated vendored Normal file
View File

@@ -0,0 +1,53 @@
function split(value, separator, includeSeparator, openLevel, closeLevel, firstOnly) {
var withRegex = typeof separator != 'string';
var hasSeparator = withRegex ?
separator.test(value) :
value.indexOf(separator);
if (!hasSeparator)
return [value];
openLevel = openLevel || '(';
closeLevel = closeLevel || ')';
if (value.indexOf(openLevel) == -1 && !includeSeparator && !firstOnly)
return value.split(separator);
var level = 0;
var cursor = 0;
var lastStart = 0;
var len = value.length;
var tokens = [];
while (cursor < len) {
if (value[cursor] == openLevel) {
level++;
} else if (value[cursor] == closeLevel) {
level--;
}
if (level === 0 && cursor > 0 && cursor + 1 < len && (withRegex ? separator.test(value[cursor]) : value[cursor] == separator)) {
tokens.push(value.substring(lastStart, cursor + (includeSeparator ? 1 : 0)));
lastStart = cursor + 1;
if (firstOnly && tokens.length == 1) {
break;
}
}
cursor++;
}
if (lastStart < cursor + 1) {
var lastValue = value.substring(lastStart);
var lastCharacter = lastValue[lastValue.length - 1];
if (!includeSeparator && (withRegex ? separator.test(lastCharacter) : lastCharacter == separator))
lastValue = lastValue.substring(0, lastValue.length - 1);
tokens.push(lastValue);
}
return tokens;
}
module.exports = split;

View File

@@ -0,0 +1,510 @@
# Source Map
This is a library to generate and consume the source map format
[described here][format].
This library is written in the Asynchronous Module Definition format, and works
in the following environments:
* Modern Browsers supporting ECMAScript 5 (either after the build, or with an
AMD loader such as RequireJS)
* Inside Firefox (as a JSM file, after the build)
* With NodeJS versions 0.8.X and higher
## Node
$ npm install source-map
## Building from Source (for everywhere else)
Install Node and then run
$ git clone https://fitzgen@github.com/mozilla/source-map.git
$ cd source-map
$ npm link .
Next, run
$ node Makefile.dryice.js
This should spew a bunch of stuff to stdout, and create the following files:
* `dist/source-map.js` - The unminified browser version.
* `dist/source-map.min.js` - The minified browser version.
* `dist/SourceMap.jsm` - The JavaScript Module for inclusion in Firefox source.
## 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
// NodeJS
var sourceMap = require('source-map');
// Browser builds
var sourceMap = window.sourceMap;
// Inside Firefox
let sourceMap = {};
Components.utils.import('resource:///modules/devtools/SourceMap.jsm', sourceMap);
```
### 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 referrenced 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.
#### SourceMapConsumer.prototype.computeColumnSpans()
Compute the last column for each generated mapping. The last column is
inclusive.
#### 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 or null if this
information is not available.
* `name`: The original identifier, or null if this information is not available.
#### 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.
#### 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.
#### 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 `smc.sourceContentFor(s)`
will succeed for every source `s` in `smc.sources`.
#### 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.
#### 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`.
### 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.
#### SourceMapGenerator.fromSourceMap(sourceMapConsumer)
Creates a new SourceMapGenerator based on a SourceMapConsumer
* `sourceMapConsumer` The SourceMap.
#### 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.
#### 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.
#### 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 minimium 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.
### 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.
#### 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.
#### 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.
#### 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.
#### 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
#### 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.
#### 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.
#### 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.
#### SourceNode.prototype.replaceRight(pattern, replacement)
Call `String.prototype.replace` on the very right-most source snippet. Useful
for trimming whitespace from the end of a source node, etc.
* `pattern`: The pattern to replace.
* `replacement`: The thing to replace the pattern with.
#### 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.
#### 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`.
## Tests
[![Build Status](https://travis-ci.org/mozilla/source-map.png?branch=master)](https://travis-ci.org/mozilla/source-map)
Install NodeJS version 0.8.0 or greater, then run `node test/run-tests.js`.
To add new tests, create a new file named `test/test-<your new test name>.js`
and export your test functions with names that start with "test", for example
```js
exports["test doing the foo bar"] = function (assert, util) {
...
};
```
The new test will be located automatically when you run the suite.
The `util` argument is the test utility module located at `test/source-map/util`.
The `assert` argument is a cut down version of node's assert module. You have
access to the following assertion functions:
* `doesNotThrow`
* `equal`
* `ok`
* `strictEqual`
* `throws`
(The reason for the restricted set of test functions is because we need the
tests to run inside Firefox's test suite as well and so the assert module is
shimmed in that environment. See `build/assert-shim.js`.)
[format]: https://docs.google.com/document/d/1U1RGAehQwRypUTovF1KRlpiOFze0b-_2gc6fAH0KY0k/edit
[feature]: https://wiki.mozilla.org/DevTools/Features/SourceMap
[Dryice]: https://github.com/mozilla/dryice

View File

@@ -0,0 +1,56 @@
/* -*- 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
*/
define('test/source-map/assert', ['exports'], function (exports) {
let do_throw = function (msg) {
throw new Error(msg);
};
exports.init = function (throw_fn) {
do_throw = throw_fn;
};
exports.doesNotThrow = function (fn) {
try {
fn();
}
catch (e) {
do_throw(e.message);
}
};
exports.equal = function (actual, expected, msg) {
msg = msg || String(actual) + ' != ' + String(expected);
if (actual != expected) {
do_throw(msg);
}
};
exports.ok = function (val, msg) {
msg = msg || String(val) + ' is falsey';
if (!Boolean(val)) {
do_throw(msg);
}
};
exports.strictEqual = function (actual, expected, msg) {
msg = msg || String(actual) + ' !== ' + String(expected);
if (actual !== expected) {
do_throw(msg);
}
};
exports.throws = function (fn) {
try {
fn();
do_throw('Expected an error to be thrown, but it wasn\'t.');
}
catch (e) {
}
};
});

View File

@@ -0,0 +1,152 @@
/* -*- 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
*/
/**
* Define a module along with a payload.
* @param {string} moduleName Name for the payload
* @param {ignored} deps Ignored. For compatibility with CommonJS AMD Spec
* @param {function} payload Function with (require, exports, module) params
*/
function define(moduleName, deps, payload) {
if (typeof moduleName != "string") {
throw new TypeError('Expected string, got: ' + moduleName);
}
if (arguments.length == 2) {
payload = deps;
}
if (moduleName in define.modules) {
throw new Error("Module already defined: " + moduleName);
}
define.modules[moduleName] = payload;
};
/**
* The global store of un-instantiated modules
*/
define.modules = {};
/**
* We invoke require() in the context of a Domain so we can have multiple
* sets of modules running separate from each other.
* This contrasts with JSMs which are singletons, Domains allows us to
* optionally load a CommonJS module twice with separate data each time.
* Perhaps you want 2 command lines with a different set of commands in each,
* for example.
*/
function Domain() {
this.modules = {};
this._currentModule = null;
}
(function () {
/**
* Lookup module names and resolve them by calling the definition function if
* needed.
* There are 2 ways to call this, either with an array of dependencies and a
* callback to call when the dependencies are found (which can happen
* asynchronously in an in-page context) or with a single string an no callback
* where the dependency is resolved synchronously and returned.
* The API is designed to be compatible with the CommonJS AMD spec and
* RequireJS.
* @param {string[]|string} deps A name, or names for the payload
* @param {function|undefined} callback Function to call when the dependencies
* are resolved
* @return {undefined|object} The module required or undefined for
* array/callback method
*/
Domain.prototype.require = function(deps, callback) {
if (Array.isArray(deps)) {
var params = deps.map(function(dep) {
return this.lookup(dep);
}, this);
if (callback) {
callback.apply(null, params);
}
return undefined;
}
else {
return this.lookup(deps);
}
};
function normalize(path) {
var bits = path.split('/');
var i = 1;
while (i < bits.length) {
if (bits[i] === '..') {
bits.splice(i-1, 1);
} else if (bits[i] === '.') {
bits.splice(i, 1);
} else {
i++;
}
}
return bits.join('/');
}
function join(a, b) {
a = a.trim();
b = b.trim();
if (/^\//.test(b)) {
return b;
} else {
return a.replace(/\/*$/, '/') + b;
}
}
function dirname(path) {
var bits = path.split('/');
bits.pop();
return bits.join('/');
}
/**
* Lookup module names and resolve them by calling the definition function if
* needed.
* @param {string} moduleName A name for the payload to lookup
* @return {object} The module specified by aModuleName or null if not found.
*/
Domain.prototype.lookup = function(moduleName) {
if (/^\./.test(moduleName)) {
moduleName = normalize(join(dirname(this._currentModule), moduleName));
}
if (moduleName in this.modules) {
var module = this.modules[moduleName];
return module;
}
if (!(moduleName in define.modules)) {
throw new Error("Module not defined: " + moduleName);
}
var module = define.modules[moduleName];
if (typeof module == "function") {
var exports = {};
var previousModule = this._currentModule;
this._currentModule = moduleName;
module(this.require.bind(this), exports, { id: moduleName, uri: "" });
this._currentModule = previousModule;
module = exports;
}
// cache the resulting module object for next time
this.modules[moduleName] = module;
return module;
};
}());
define.Domain = Domain;
define.globalDomain = new Domain();
var require = define.globalDomain.require.bind(define.globalDomain);

View File

@@ -0,0 +1,21 @@
/* -*- 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
*/
/*
* WARNING!
*
* Do not edit this file directly, it is built from the sources at
* https://github.com/mozilla/source-map/
*/
///////////////////////////////////////////////////////////////////////////////
this.EXPORTED_SYMBOLS = [ "SourceMapConsumer", "SourceMapGenerator", "SourceNode" ];
Components.utils.import("resource://gre/modules/devtools/Console.jsm");
Components.utils.import('resource://gre/modules/devtools/Require.jsm');

View File

@@ -0,0 +1,18 @@
/* -*- 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
*/
/*
* WARNING!
*
* Do not edit this file directly, it is built from the sources at
* https://github.com/mozilla/source-map/
*/
Components.utils.import('resource://gre/modules/devtools/Require.jsm');
Components.utils.import('resource://gre/modules/devtools/SourceMap.jsm');
this.EXPORTED_SYMBOLS = [ "define", "runSourceMapTests" ];

View File

@@ -0,0 +1,8 @@
/* -*- Mode: js; js-indent-level: 2; -*- */
///////////////////////////////////////////////////////////////////////////////
this.sourceMap = {
SourceMapConsumer: require('source-map/source-map-consumer').SourceMapConsumer,
SourceMapGenerator: require('source-map/source-map-generator').SourceMapGenerator,
SourceNode: require('source-map/source-node').SourceNode
};

View File

@@ -0,0 +1,6 @@
/* -*- Mode: js; js-indent-level: 2; -*- */
///////////////////////////////////////////////////////////////////////////////
this.SourceMapConsumer = require('source-map/source-map-consumer').SourceMapConsumer;
this.SourceMapGenerator = require('source-map/source-map-generator').SourceMapGenerator;
this.SourceNode = require('source-map/source-node').SourceNode;

View File

@@ -0,0 +1,21 @@
/* -*- 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
*/
function runSourceMapTests(modName, do_throw) {
let mod = require(modName);
let assert = require('test/source-map/assert');
let util = require('test/source-map/util');
assert.init(do_throw);
for (let k in mod) {
if (/^test/.test(k)) {
mod[k](assert, util);
}
}
}
this.runSourceMapTests = runSourceMapTests;

View File

@@ -0,0 +1,8 @@
/*
* WARNING!
*
* Do not edit this file directly, it is built from the sources at
* https://github.com/mozilla/source-map/
*/
Components.utils.import('resource://test/Utils.jsm');

View File

@@ -0,0 +1,3 @@
function run_test() {
runSourceMapTests('{THIS_MODULE}', do_throw);
}

View File

@@ -0,0 +1,8 @@
/*
* 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('./source-map/source-map-generator').SourceMapGenerator;
exports.SourceMapConsumer = require('./source-map/source-map-consumer').SourceMapConsumer;
exports.SourceNode = require('./source-map/source-node').SourceNode;

View File

@@ -0,0 +1,107 @@
/* -*- 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
*/
if (typeof define !== 'function') {
var define = require('amdefine')(module, require);
}
define(function (require, exports, module) {
var util = require('./util');
/**
* 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 = {};
}
/**
* 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 Object.getOwnPropertyNames(this._set).length;
};
/**
* Add the given string to this set.
*
* @param String aStr
*/
ArraySet.prototype.add = function ArraySet_add(aStr, aAllowDuplicates) {
var isDuplicate = this.has(aStr);
var idx = this._array.length;
if (!isDuplicate || aAllowDuplicates) {
this._array.push(aStr);
}
if (!isDuplicate) {
this._set[util.toSetString(aStr)] = idx;
}
};
/**
* Is the given string a member of this set?
*
* @param String aStr
*/
ArraySet.prototype.has = function ArraySet_has(aStr) {
return Object.prototype.hasOwnProperty.call(this._set,
util.toSetString(aStr));
};
/**
* What is the index of the given string in the array?
*
* @param String aStr
*/
ArraySet.prototype.indexOf = function ArraySet_indexOf(aStr) {
if (this.has(aStr)) {
return this._set[util.toSetString(aStr)];
}
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;
});

View File

@@ -0,0 +1,146 @@
/* -*- 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.
*/
if (typeof define !== 'function') {
var define = require('amdefine')(module, require);
}
define(function (require, exports, module) {
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;
};
});

View File

@@ -0,0 +1,73 @@
/* -*- 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
*/
if (typeof define !== 'function') {
var define = require('amdefine')(module, require);
}
define(function (require, exports, module) {
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: " + aNumber);
};
/**
* 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;
};
});

View File

@@ -0,0 +1,117 @@
/* -*- 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
*/
if (typeof define !== 'function') {
var define = require('amdefine')(module, require);
}
define(function (require, exports, module) {
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;
};
});

View File

@@ -0,0 +1,86 @@
/* -*- 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
*/
if (typeof define !== 'function') {
var define = require('amdefine')(module, require);
}
define(function (require, exports, module) {
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) {
var mapping;
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;
});

View File

@@ -0,0 +1,120 @@
/* -*- 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
*/
if (typeof define !== 'function') {
var define = require('amdefine')(module, require);
}
define(function (require, exports, module) {
// 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);
};
});

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,399 @@
/* -*- 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
*/
if (typeof define !== 'function') {
var define = require('amdefine')(module, require);
}
define(function (require, exports, module) {
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 && !this._sources.has(source)) {
this._sources.add(source);
}
if (name != null && !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 = {};
}
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) {
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 mapping;
var mappings = this._mappings.toArray();
for (var i = 0, len = mappings.length; i < len; i++) {
mapping = mappings[i];
if (mapping.generatedLine !== previousGeneratedLine) {
previousGeneratedColumn = 0;
while (mapping.generatedLine !== previousGeneratedLine) {
result += ';';
previousGeneratedLine++;
}
}
else {
if (i > 0) {
if (!util.compareByGeneratedPositionsInflated(mapping, mappings[i - 1])) {
continue;
}
result += ',';
}
}
result += base64VLQ.encode(mapping.generatedColumn
- previousGeneratedColumn);
previousGeneratedColumn = mapping.generatedColumn;
if (mapping.source != null) {
result += base64VLQ.encode(this._sources.indexOf(mapping.source)
- previousSource);
previousSource = this._sources.indexOf(mapping.source);
// lines are stored 0-based in SourceMap spec version 3
result += base64VLQ.encode(mapping.originalLine - 1
- previousOriginalLine);
previousOriginalLine = mapping.originalLine - 1;
result += base64VLQ.encode(mapping.originalColumn
- previousOriginalColumn);
previousOriginalColumn = mapping.originalColumn;
if (mapping.name != null) {
result += base64VLQ.encode(this._names.indexOf(mapping.name)
- previousName);
previousName = this._names.indexOf(mapping.name);
}
}
}
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;
});

View File

@@ -0,0 +1,414 @@
/* -*- 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
*/
if (typeof define !== 'function') {
var define = require('amdefine')(module, require);
}
define(function (require, exports, module) {
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 removed from this array, by calling `shiftNextLine`.
var remainingLines = aGeneratedCode.split(REGEX_NEWLINE);
var shiftNextLine = function() {
var lineContents = remainingLines.shift();
// The last line of a file might not have a newline.
var newLine = remainingLines.shift() || "";
return lineContents + newLine;
};
// 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) {
var code = "";
// 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[0];
var code = nextLine.substr(0, mapping.generatedColumn -
lastGeneratedColumn);
remainingLines[0] = 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[0];
node.add(nextLine.substr(0, mapping.generatedColumn));
remainingLines[0] = nextLine.substr(mapping.generatedColumn);
lastGeneratedColumn = mapping.generatedColumn;
}
lastMapping = mapping;
}, this);
// We have processed all mappings.
if (remainingLines.length > 0) {
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.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;
});

View File

@@ -0,0 +1,370 @@
/* -*- 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
*/
if (typeof define !== 'function') {
var define = require('amdefine')(module, require);
}
define(function (require, exports, module) {
/**
* 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 consequtive 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 = (path.charAt(0) === '/');
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;
/**
* 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;
/**
* 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) {
return '$' + aStr;
}
exports.toSetString = toSetString;
function fromSetString(aStr) {
return aStr.substr(1);
}
exports.fromSetString = fromSetString;
/**
* 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;
});

View File

@@ -0,0 +1,234 @@
{
"_args": [
[
{
"raw": "source-map@0.4.x",
"scope": null,
"escapedName": "source-map",
"name": "source-map",
"rawSpec": "0.4.x",
"spec": ">=0.4.0 <0.5.0",
"type": "range"
},
"D:\\web\\layui\\res\\layui\\node_modules\\clean-css"
]
],
"_from": "source-map@>=0.4.0 <0.5.0",
"_id": "source-map@0.4.4",
"_inCache": true,
"_location": "/clean-css/source-map",
"_npmUser": {
"name": "nickfitzgerald",
"email": "fitzgen@gmail.com"
},
"_npmVersion": "1.4.9",
"_phantomChildren": {},
"_requested": {
"raw": "source-map@0.4.x",
"scope": null,
"escapedName": "source-map",
"name": "source-map",
"rawSpec": "0.4.x",
"spec": ">=0.4.0 <0.5.0",
"type": "range"
},
"_requiredBy": [
"/clean-css"
],
"_resolved": "https://registry.npmjs.org/source-map/-/source-map-0.4.4.tgz",
"_shasum": "eba4f5da9c0dc999de68032d8b4f76173652036b",
"_shrinkwrap": null,
"_spec": "source-map@0.4.x",
"_where": "D:\\web\\layui\\res\\layui\\node_modules\\clean-css",
"author": {
"name": "Nick Fitzgerald",
"email": "nfitzgerald@mozilla.com"
},
"bugs": {
"url": "https://github.com/mozilla/source-map/issues"
},
"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"
}
],
"dependencies": {
"amdefine": ">=0.0.4"
},
"description": "Generates and consumes source maps",
"devDependencies": {
"dryice": ">=0.4.8"
},
"directories": {
"lib": "./lib"
},
"dist": {
"shasum": "eba4f5da9c0dc999de68032d8b4f76173652036b",
"tarball": "https://registry.npmjs.org/source-map/-/source-map-0.4.4.tgz"
},
"engines": {
"node": ">=0.8.0"
},
"files": [
"lib/",
"build/"
],
"homepage": "https://github.com/mozilla/source-map",
"license": "BSD-3-Clause",
"main": "./lib/source-map.js",
"maintainers": [
{
"name": "mozilla-devtools",
"email": "mozilla-developer-tools@googlegroups.com"
},
{
"name": "mozilla",
"email": "dherman@mozilla.com"
},
{
"name": "nickfitzgerald",
"email": "fitzgen@gmail.com"
}
],
"name": "source-map",
"optionalDependencies": {},
"readme": "ERROR: No README data found!",
"repository": {
"type": "git",
"url": "git+ssh://git@github.com/mozilla/source-map.git"
},
"scripts": {
"build": "node Makefile.dryice.js",
"test": "node test/run-tests.js"
},
"version": "0.4.4"
}

123
node_modules/clean-css/package.json generated vendored Normal file
View File

@@ -0,0 +1,123 @@
{
"_args": [
[
{
"raw": "clean-css@^3.3.3",
"scope": null,
"escapedName": "clean-css",
"name": "clean-css",
"rawSpec": "^3.3.3",
"spec": ">=3.3.3 <4.0.0",
"type": "range"
},
"D:\\web\\layui\\res\\layui\\node_modules\\gulp-minify-css"
]
],
"_from": "clean-css@>=3.3.3 <4.0.0",
"_id": "clean-css@3.4.23",
"_inCache": true,
"_location": "/clean-css",
"_nodeVersion": "6.5.0",
"_npmOperationalInternal": {
"host": "packages-18-east.internal.npmjs.com",
"tmp": "tmp/clean-css-3.4.23.tgz_1481993659310_0.8725182958878577"
},
"_npmUser": {
"name": "goalsmashers",
"email": "jakub@goalsmashers.com"
},
"_npmVersion": "3.10.3",
"_phantomChildren": {
"amdefine": "1.0.1"
},
"_requested": {
"raw": "clean-css@^3.3.3",
"scope": null,
"escapedName": "clean-css",
"name": "clean-css",
"rawSpec": "^3.3.3",
"spec": ">=3.3.3 <4.0.0",
"type": "range"
},
"_requiredBy": [
"/gulp-minify-css"
],
"_resolved": "https://registry.npmjs.org/clean-css/-/clean-css-3.4.23.tgz",
"_shasum": "604fbbca24c12feb59b02f00b84f1fb7ded6d001",
"_shrinkwrap": null,
"_spec": "clean-css@^3.3.3",
"_where": "D:\\web\\layui\\res\\layui\\node_modules\\gulp-minify-css",
"author": {
"name": "Jakub Pawlowicz",
"email": "contact@jakubpawlowicz.com",
"url": "http://twitter.com/jakubpawlowicz"
},
"bin": {
"cleancss": "./bin/cleancss"
},
"bugs": {
"url": "https://github.com/jakubpawlowicz/clean-css/issues"
},
"dependencies": {
"commander": "2.8.x",
"source-map": "0.4.x"
},
"description": "A well-tested CSS minifier",
"devDependencies": {
"browserify": "11.x",
"http-proxy": "1.x",
"jshint": "2.8.x",
"nock": "2.x",
"server-destroy": "1.x",
"uglify-js": "2.4.x",
"vows": "0.8.x"
},
"directories": {},
"dist": {
"shasum": "604fbbca24c12feb59b02f00b84f1fb7ded6d001",
"tarball": "https://registry.npmjs.org/clean-css/-/clean-css-3.4.23.tgz"
},
"engines": {
"node": ">=0.10.0"
},
"files": [
"bin",
"lib",
"History.md",
"index.js",
"LICENSE"
],
"gitHead": "a8fa5cf26b40bb8c33541a71a4a6f360e7be7947",
"homepage": "https://github.com/jakubpawlowicz/clean-css",
"keywords": [
"css",
"minifier"
],
"license": "MIT",
"main": "index.js",
"maintainers": [
{
"name": "goalsmashers",
"email": "jakub@goalsmashers.com"
},
{
"name": "jakub.pawlowicz",
"email": "contact@jakubpawlowicz.com"
}
],
"name": "clean-css",
"optionalDependencies": {},
"readme": "ERROR: No README data found!",
"repository": {
"type": "git",
"url": "git+https://github.com/jakubpawlowicz/clean-css.git"
},
"scripts": {
"bench": "node ./test/bench.js",
"browserify": "browserify --standalone CleanCSS index.js | uglifyjs --compress --mangle -o cleancss-browser.js",
"check": "jshint ./bin/cleancss .",
"prepublish": "npm run check",
"test": "vows"
},
"version": "3.4.23"
}