first commit
This commit is contained in:
22
build/node_modules/html-minifier/LICENSE
generated
vendored
Normal file
22
build/node_modules/html-minifier/LICENSE
generated
vendored
Normal file
@@ -0,0 +1,22 @@
|
||||
Copyright (c) 2010-2016 Juriy "kangax" Zaytsev
|
||||
|
||||
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.
|
||||
159
build/node_modules/html-minifier/README.md
generated
vendored
Normal file
159
build/node_modules/html-minifier/README.md
generated
vendored
Normal file
@@ -0,0 +1,159 @@
|
||||
# HTMLMinifier
|
||||
|
||||
[](https://www.npmjs.com/package/html-minifier)
|
||||
[](https://travis-ci.org/kangax/html-minifier)
|
||||
[](https://david-dm.org/kangax/html-minifier)
|
||||
[](https://david-dm.org/kangax/html-minifier?type=dev)
|
||||
[](https://gitter.im/kangax/html-minifier)
|
||||
|
||||
[HTMLMinifier](http://kangax.github.io/html-minifier/) is a highly **configurable**, **well-tested**, JavaScript-based HTML minifier.
|
||||
|
||||
See [corresponding blog post](http://perfectionkills.com/experimenting-with-html-minifier/) for all the gory details of [how it works](http://perfectionkills.com/experimenting-with-html-minifier/#how_it_works), [description of each option](http://perfectionkills.com/experimenting-with-html-minifier/#options), [testing results](http://perfectionkills.com/experimenting-with-html-minifier/#field_testing) and [conclusions](http://perfectionkills.com/experimenting-with-html-minifier/#cost_and_benefits).
|
||||
|
||||
[Test suite is available online](http://kangax.github.io/html-minifier/tests/).
|
||||
|
||||
Also see corresponding [Ruby wrapper](https://github.com/stereobooster/html_minifier), and for Node.js, [Grunt plugin](https://github.com/gruntjs/grunt-contrib-htmlmin), [Gulp module](https://github.com/jonschlinkert/gulp-htmlmin), [Koa middleware wrapper](https://github.com/koajs/html-minifier) and [Express middleware wrapper](https://github.com/melonmanchan/express-minify-html).
|
||||
|
||||
For lint-like capabilities take a look at [HTMLLint](https://github.com/kangax/html-lint).
|
||||
|
||||
## Minification comparison
|
||||
|
||||
How does HTMLMinifier compare to other solutions — [HTML Minifier from Will Peavy](http://www.willpeavy.com/minifier/) (1st result in [Google search for "html minifier"](https://www.google.com/#q=html+minifier)) as well as [htmlcompressor.com](http://htmlcompressor.com) and [minimize](https://github.com/Swaagie/minimize)?
|
||||
|
||||
| Site | Original size *(KB)* | HTMLMinifier | minimize | Will Peavy | htmlcompressor.com |
|
||||
| ---------------------------------------------------------------------------- |:--------------------:| ------------:| --------:| ----------:| ------------------:|
|
||||
| [Google](https://www.google.com/) | 46 | **43** | 46 | 48 | 46 |
|
||||
| [HTMLMinifier](https://github.com/kangax/html-minifier) | 133 | **104** | 112 | 116 | 111 |
|
||||
| [New York Times](https://www.nytimes.com/) | 214 | **145** | 163 | 162 | 152 |
|
||||
| [BBC](https://www.bbc.co.uk/) | 237 | **194** | 229 | 235 | 222 |
|
||||
| [Stack Overflow](https://stackoverflow.com/) | 248 | **195** | 204 | 212 | 201 |
|
||||
| [Bootstrap CSS](https://getbootstrap.com/docs/3.3/css/) | 272 | **260** | 269 | 229 | 269 |
|
||||
| [Twitter](https://twitter.com/) | 348 | **260** | 313 | 345 | 313 |
|
||||
| [Amazon](https://www.amazon.co.uk/) | 405 | **349** | 390 | 403 | n/a |
|
||||
| [Wikipedia](https://en.wikipedia.org/wiki/President_of_the_United_States) | 471 | **440** | 456 | 471 | 455 |
|
||||
| [NBC](https://www.nbc.com/) | 646 | **613** | 642 | 646 | n/a |
|
||||
| [Eloquent Javascript](https://eloquentjavascript.net/1st_edition/print.html) | 870 | **815** | 840 | 864 | n/a |
|
||||
| [ES6 table](https://kangax.github.io/compat-table/es6/) | 4580 | **3898** | 4333 | n/a | n/a |
|
||||
| [ES6 draft](https://tc39.github.io/ecma262/) | 5720 | **5103** | 5253 | n/a | n/a |
|
||||
|
||||
## Options Quick Reference
|
||||
|
||||
Most of the options are disabled by default.
|
||||
|
||||
| Option | Description | Default |
|
||||
|--------------------------------|-----------------|---------|
|
||||
| `caseSensitive` | Treat attributes in case sensitive manner (useful for custom HTML tags) | `false` |
|
||||
| `collapseBooleanAttributes` | [Omit attribute values from boolean attributes](http://perfectionkills.com/experimenting-with-html-minifier/#collapse_boolean_attributes) | `false` |
|
||||
| `collapseInlineTagWhitespace` | Don't leave any spaces between `display:inline;` elements when collapsing. Must be used in conjunction with `collapseWhitespace=true` | `false` |
|
||||
| `collapseWhitespace` | [Collapse white space that contributes to text nodes in a document tree](http://perfectionkills.com/experimenting-with-html-minifier/#collapse_whitespace) | `false` |
|
||||
| `conservativeCollapse` | Always collapse to 1 space (never remove it entirely). Must be used in conjunction with `collapseWhitespace=true` | `false` |
|
||||
| `customAttrAssign` | Arrays of regex'es that allow to support custom attribute assign expressions (e.g. `'<div flex?="{{mode != cover}}"></div>'`) | `[ ]` |
|
||||
| `customAttrCollapse` | Regex that specifies custom attribute to strip newlines from (e.g. `/ng-class/`) | |
|
||||
| `customAttrSurround` | Arrays of regex'es that allow to support custom attribute surround expressions (e.g. `<input {{#if value}}checked="checked"{{/if}}>`) | `[ ]` |
|
||||
| `customEventAttributes` | Arrays of regex'es that allow to support custom event attributes for `minifyJS` (e.g. `ng-click`) | `[ /^on[a-z]{3,}$/ ]` |
|
||||
| `decodeEntities` | Use direct Unicode characters whenever possible | `false` |
|
||||
| `html5` | Parse input according to HTML5 specifications | `true` |
|
||||
| `ignoreCustomComments` | Array of regex'es that allow to ignore certain comments, when matched | `[ /^!/ ]` |
|
||||
| `ignoreCustomFragments` | Array of regex'es that allow to ignore certain fragments, when matched (e.g. `<?php ... ?>`, `{{ ... }}`, etc.) | `[ /<%[\s\S]*?%>/, /<\?[\s\S]*?\?>/ ]` |
|
||||
| `includeAutoGeneratedTags` | Insert tags generated by HTML parser | `true` |
|
||||
| `keepClosingSlash` | Keep the trailing slash on singleton elements | `false` |
|
||||
| `maxLineLength` | Specify a maximum line length. Compressed output will be split by newlines at valid HTML split-points |
|
||||
| `minifyCSS` | Minify CSS in style elements and style attributes (uses [clean-css](https://github.com/jakubpawlowicz/clean-css)) | `false` (could be `true`, `Object`, `Function(text)`) |
|
||||
| `minifyJS` | Minify JavaScript in script elements and event attributes (uses [UglifyJS](https://github.com/mishoo/UglifyJS2)) | `false` (could be `true`, `Object`, `Function(text, inline)`) |
|
||||
| `minifyURLs` | Minify URLs in various attributes (uses [relateurl](https://github.com/stevenvachon/relateurl)) | `false` (could be `String`, `Object`, `Function(text)`) |
|
||||
| `preserveLineBreaks` | Always collapse to 1 line break (never remove it entirely) when whitespace between tags include a line break. Must be used in conjunction with `collapseWhitespace=true` | `false` |
|
||||
| `preventAttributesEscaping` | Prevents the escaping of the values of attributes | `false` |
|
||||
| `processConditionalComments` | Process contents of conditional comments through minifier | `false` |
|
||||
| `processScripts` | Array of strings corresponding to types of script elements to process through minifier (e.g. `text/ng-template`, `text/x-handlebars-template`, etc.) | `[ ]` |
|
||||
| `quoteCharacter` | Type of quote to use for attribute values (' or ") | |
|
||||
| `removeAttributeQuotes` | [Remove quotes around attributes when possible](http://perfectionkills.com/experimenting-with-html-minifier/#remove_attribute_quotes) | `false` |
|
||||
| `removeComments` | [Strip HTML comments](http://perfectionkills.com/experimenting-with-html-minifier/#remove_comments) | `false` |
|
||||
| `removeEmptyAttributes` | [Remove all attributes with whitespace-only values](http://perfectionkills.com/experimenting-with-html-minifier/#remove_empty_or_blank_attributes) | `false` (could be `true`, `Function(attrName, tag)`) |
|
||||
| `removeEmptyElements` | [Remove all elements with empty contents](http://perfectionkills.com/experimenting-with-html-minifier/#remove_empty_elements) | `false` |
|
||||
| `removeOptionalTags` | [Remove optional tags](http://perfectionkills.com/experimenting-with-html-minifier/#remove_optional_tags) | `false` |
|
||||
| `removeRedundantAttributes` | [Remove attributes when value matches default.](http://perfectionkills.com/experimenting-with-html-minifier/#remove_redundant_attributes) | `false` |
|
||||
| `removeScriptTypeAttributes` | Remove `type="text/javascript"` from `script` tags. Other `type` attribute values are left intact | `false` |
|
||||
| `removeStyleLinkTypeAttributes`| Remove `type="text/css"` from `style` and `link` tags. Other `type` attribute values are left intact | `false` |
|
||||
| `removeTagWhitespace` | Remove space between attributes whenever possible. **Note that this will result in invalid HTML!** | `false` |
|
||||
| `sortAttributes` | [Sort attributes by frequency](#sorting-attributes--style-classes) | `false` |
|
||||
| `sortClassName` | [Sort style classes by frequency](#sorting-attributes--style-classes) | `false` |
|
||||
| `trimCustomFragments` | Trim white space around `ignoreCustomFragments`. | `false` |
|
||||
| `useShortDoctype` | [Replaces the `doctype` with the short (HTML5) doctype](http://perfectionkills.com/experimenting-with-html-minifier/#use_short_doctype) | `false` |
|
||||
|
||||
### Sorting attributes / style classes
|
||||
|
||||
Minifier options like `sortAttributes` and `sortClassName` won't impact the plain-text size of the output. However, they form long repetitive chains of characters that should improve compression ratio of gzip used in HTTP compression.
|
||||
|
||||
## Special cases
|
||||
|
||||
### Ignoring chunks of markup
|
||||
|
||||
If you have chunks of markup you would like preserved, you can wrap them `<!-- htmlmin:ignore -->`.
|
||||
|
||||
### Preserving SVG tags
|
||||
|
||||
SVG tags are automatically recognized, and when they are minified, both case-sensitivity and closing-slashes are preserved, regardless of the minification settings used for the rest of the file.
|
||||
|
||||
### Working with invalid markup
|
||||
|
||||
HTMLMinifier **can't work with invalid or partial chunks of markup**. This is because it parses markup into a tree structure, then modifies it (removing anything that was specified for removal, ignoring anything that was specified to be ignored, etc.), then it creates a markup out of that tree and returns it.
|
||||
|
||||
Input markup (e.g. `<p id="">foo`)
|
||||
|
||||
↓
|
||||
|
||||
Internal representation of markup in a form of tree (e.g. `{ tag: "p", attr: "id", children: ["foo"] }`)
|
||||
|
||||
↓
|
||||
|
||||
Transformation of internal representation (e.g. removal of `id` attribute)
|
||||
|
||||
↓
|
||||
|
||||
Output of resulting markup (e.g. `<p>foo</p>`)
|
||||
|
||||
HTMLMinifier can't know that original markup was only half of the tree; it does its best to try to parse it as a full tree and it loses information about tree being malformed or partial in the beginning. As a result, it can't create a partial/malformed tree at the time of the output.
|
||||
|
||||
## Installation Instructions
|
||||
|
||||
From NPM for use as a command line app:
|
||||
|
||||
```shell
|
||||
npm install html-minifier -g
|
||||
```
|
||||
|
||||
From NPM for programmatic use:
|
||||
|
||||
```shell
|
||||
npm install html-minifier
|
||||
```
|
||||
|
||||
From Git:
|
||||
|
||||
```shell
|
||||
git clone git://github.com/kangax/html-minifier.git
|
||||
cd html-minifier
|
||||
npm link .
|
||||
```
|
||||
|
||||
## Usage
|
||||
|
||||
For command line usage please see `html-minifier --help`
|
||||
|
||||
### Node.js
|
||||
|
||||
```js
|
||||
var minify = require('html-minifier').minify;
|
||||
var result = minify('<p title="blah" id="moo">foo</p>', {
|
||||
removeAttributeQuotes: true
|
||||
});
|
||||
result; // '<p title=blah id=moo>foo</p>'
|
||||
```
|
||||
|
||||
## Running benchmarks
|
||||
|
||||
Benchmarks for minified HTML:
|
||||
|
||||
```shell
|
||||
node benchmark.js
|
||||
```
|
||||
307
build/node_modules/html-minifier/cli.js
generated
vendored
Executable file
307
build/node_modules/html-minifier/cli.js
generated
vendored
Executable file
@@ -0,0 +1,307 @@
|
||||
#!/usr/bin/env node
|
||||
/**
|
||||
* html-minifier CLI tool
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2014-2016 Zoltan Frombach
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
var camelCase = require('camel-case');
|
||||
var fs = require('fs');
|
||||
var info = require('./package.json');
|
||||
var minify = require('./' + info.main).minify;
|
||||
var paramCase = require('param-case');
|
||||
var path = require('path');
|
||||
var program = require('commander');
|
||||
|
||||
program._name = info.name;
|
||||
program.version(info.version);
|
||||
|
||||
function fatal(message) {
|
||||
console.error(message);
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
/**
|
||||
* JSON does not support regexes, so, e.g., JSON.parse() will not create
|
||||
* a RegExp from the JSON value `[ "/matchString/" ]`, which is
|
||||
* technically just an array containing a string that begins and end with
|
||||
* a forward slash. To get a RegExp from a JSON string, it must be
|
||||
* constructed explicitly in JavaScript.
|
||||
*
|
||||
* The likelihood of actually wanting to match text that is enclosed in
|
||||
* forward slashes is probably quite rare, so if forward slashes were
|
||||
* included in an argument that requires a regex, the user most likely
|
||||
* thought they were part of the syntax for specifying a regex.
|
||||
*
|
||||
* In the unlikely case that forward slashes are indeed desired in the
|
||||
* search string, the user would need to enclose the expression in a
|
||||
* second set of slashes:
|
||||
*
|
||||
* --customAttrSrround "[\"//matchString//\"]"
|
||||
*/
|
||||
function parseRegExp(value) {
|
||||
if (value) {
|
||||
return new RegExp(value.replace(/^\/(.*)\/$/, '$1'));
|
||||
}
|
||||
}
|
||||
|
||||
function parseJSON(value) {
|
||||
if (value) {
|
||||
try {
|
||||
return JSON.parse(value);
|
||||
}
|
||||
catch (e) {
|
||||
if (/^{/.test(value)) {
|
||||
fatal('Could not parse JSON value \'' + value + '\'');
|
||||
}
|
||||
return value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function parseJSONArray(value) {
|
||||
if (value) {
|
||||
value = parseJSON(value);
|
||||
return Array.isArray(value) ? value : [value];
|
||||
}
|
||||
}
|
||||
|
||||
function parseJSONRegExpArray(value) {
|
||||
value = parseJSONArray(value);
|
||||
return value && value.map(parseRegExp);
|
||||
}
|
||||
|
||||
function parseString(value) {
|
||||
return value;
|
||||
}
|
||||
|
||||
var mainOptions = {
|
||||
caseSensitive: 'Treat attributes in case sensitive manner (useful for SVG; e.g. viewBox)',
|
||||
collapseBooleanAttributes: 'Omit attribute values from boolean attributes',
|
||||
collapseInlineTagWhitespace: 'Collapse white space around inline tag',
|
||||
collapseWhitespace: 'Collapse white space that contributes to text nodes in a document tree.',
|
||||
conservativeCollapse: 'Always collapse to 1 space (never remove it entirely)',
|
||||
customAttrAssign: ['Arrays of regex\'es that allow to support custom attribute assign expressions (e.g. \'<div flex?="{{mode != cover}}"></div>\')', parseJSONRegExpArray],
|
||||
customAttrCollapse: ['Regex that specifies custom attribute to strip newlines from (e.g. /ng-class/)', parseRegExp],
|
||||
customAttrSurround: ['Arrays of regex\'es that allow to support custom attribute surround expressions (e.g. <input {{#if value}}checked="checked"{{/if}}>)', parseJSONRegExpArray],
|
||||
customEventAttributes: ['Arrays of regex\'es that allow to support custom event attributes for minifyJS (e.g. ng-click)', parseJSONRegExpArray],
|
||||
decodeEntities: 'Use direct Unicode characters whenever possible',
|
||||
html5: 'Parse input according to HTML5 specifications',
|
||||
ignoreCustomComments: ['Array of regex\'es that allow to ignore certain comments, when matched', parseJSONRegExpArray],
|
||||
ignoreCustomFragments: ['Array of regex\'es that allow to ignore certain fragments, when matched (e.g. <?php ... ?>, {{ ... }})', parseJSONRegExpArray],
|
||||
includeAutoGeneratedTags: 'Insert tags generated by HTML parser',
|
||||
keepClosingSlash: 'Keep the trailing slash on singleton elements',
|
||||
maxLineLength: ['Max line length', parseInt],
|
||||
minifyCSS: ['Minify CSS in style elements and style attributes (uses clean-css)', parseJSON],
|
||||
minifyJS: ['Minify Javascript in script elements and on* attributes (uses uglify-js)', parseJSON],
|
||||
minifyURLs: ['Minify URLs in various attributes (uses relateurl)', parseJSON],
|
||||
preserveLineBreaks: 'Always collapse to 1 line break (never remove it entirely) when whitespace between tags include a line break.',
|
||||
preventAttributesEscaping: 'Prevents the escaping of the values of attributes.',
|
||||
processConditionalComments: 'Process contents of conditional comments through minifier',
|
||||
processScripts: ['Array of strings corresponding to types of script elements to process through minifier (e.g. "text/ng-template", "text/x-handlebars-template", etc.)', parseJSONArray],
|
||||
quoteCharacter: ['Type of quote to use for attribute values (\' or ")', parseString],
|
||||
removeAttributeQuotes: 'Remove quotes around attributes when possible.',
|
||||
removeComments: 'Strip HTML comments',
|
||||
removeEmptyAttributes: 'Remove all attributes with whitespace-only values',
|
||||
removeEmptyElements: 'Remove all elements with empty contents',
|
||||
removeOptionalTags: 'Remove unrequired tags',
|
||||
removeRedundantAttributes: 'Remove attributes when value matches default.',
|
||||
removeScriptTypeAttributes: 'Remove type="text/javascript" from script tags. Other type attribute values are left intact.',
|
||||
removeStyleLinkTypeAttributes: 'Remove type="text/css" from style and link tags. Other type attribute values are left intact.',
|
||||
removeTagWhitespace: 'Remove space between attributes whenever possible',
|
||||
sortAttributes: 'Sort attributes by frequency',
|
||||
sortClassName: 'Sort style classes by frequency',
|
||||
trimCustomFragments: 'Trim white space around ignoreCustomFragments.',
|
||||
useShortDoctype: 'Replaces the doctype with the short (HTML5) doctype'
|
||||
};
|
||||
var mainOptionKeys = Object.keys(mainOptions);
|
||||
mainOptionKeys.forEach(function(key) {
|
||||
var option = mainOptions[key];
|
||||
key = '--' + paramCase(key);
|
||||
if (Array.isArray(option)) {
|
||||
var optional = option[1] === parseJSON;
|
||||
program.option(key + (optional ? ' [value]' : ' <value>'), option[0], option[1]);
|
||||
}
|
||||
else {
|
||||
program.option(key, option);
|
||||
}
|
||||
});
|
||||
program.option('-o --output <file>', 'Specify output file (if not specified STDOUT will be used for output)');
|
||||
|
||||
function readFile(file) {
|
||||
try {
|
||||
return fs.readFileSync(file, { encoding: 'utf8' });
|
||||
}
|
||||
catch (e) {
|
||||
fatal('Cannot read ' + file + '\n' + e.message);
|
||||
}
|
||||
}
|
||||
|
||||
var config = {};
|
||||
program.option('-c --config-file <file>', 'Use config file', function(configPath) {
|
||||
var data = readFile(configPath);
|
||||
try {
|
||||
config = JSON.parse(data);
|
||||
}
|
||||
catch (je) {
|
||||
try {
|
||||
config = require(path.resolve(configPath));
|
||||
}
|
||||
catch (ne) {
|
||||
fatal('Cannot read the specified config file.\nAs JSON: ' + je.message + '\nAs module: ' + ne.message);
|
||||
}
|
||||
}
|
||||
mainOptionKeys.forEach(function(key) {
|
||||
if (key in config) {
|
||||
var option = mainOptions[key];
|
||||
if (Array.isArray(option)) {
|
||||
var value = config[key];
|
||||
config[key] = option[1](typeof value === 'string' ? value : JSON.stringify(value));
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
program.option('--input-dir <dir>', 'Specify an input directory');
|
||||
program.option('--output-dir <dir>', 'Specify an output directory');
|
||||
program.option('--file-ext <text>', 'Specify an extension to be read, ex: html');
|
||||
var content;
|
||||
program.arguments('[files...]').action(function(files) {
|
||||
content = files.map(readFile).join('');
|
||||
}).parse(process.argv);
|
||||
|
||||
function createOptions() {
|
||||
var options = {};
|
||||
mainOptionKeys.forEach(function(key) {
|
||||
var param = program[camelCase(key)];
|
||||
if (typeof param !== 'undefined') {
|
||||
options[key] = param;
|
||||
}
|
||||
else if (key in config) {
|
||||
options[key] = config[key];
|
||||
}
|
||||
});
|
||||
return options;
|
||||
}
|
||||
|
||||
function mkdir(outputDir, callback) {
|
||||
fs.mkdir(outputDir, function(err) {
|
||||
if (err) {
|
||||
switch (err.code) {
|
||||
case 'ENOENT':
|
||||
return mkdir(path.join(outputDir, '..'), function() {
|
||||
mkdir(outputDir, callback);
|
||||
});
|
||||
case 'EEXIST':
|
||||
break;
|
||||
default:
|
||||
fatal('Cannot create directory ' + outputDir + '\n' + err.message);
|
||||
}
|
||||
}
|
||||
callback();
|
||||
});
|
||||
}
|
||||
|
||||
function processFile(inputFile, outputFile) {
|
||||
fs.readFile(inputFile, { encoding: 'utf8' }, function(err, data) {
|
||||
if (err) {
|
||||
fatal('Cannot read ' + inputFile + '\n' + err.message);
|
||||
}
|
||||
var minified;
|
||||
try {
|
||||
minified = minify(data, createOptions());
|
||||
}
|
||||
catch (e) {
|
||||
fatal('Minification error on ' + inputFile + '\n' + e.message);
|
||||
}
|
||||
fs.writeFile(outputFile, minified, { encoding: 'utf8' }, function(err) {
|
||||
if (err) {
|
||||
fatal('Cannot write ' + outputFile + '\n' + err.message);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function processDirectory(inputDir, outputDir, fileExt) {
|
||||
fs.readdir(inputDir, function(err, files) {
|
||||
if (err) {
|
||||
fatal('Cannot read directory ' + inputDir + '\n' + err.message);
|
||||
}
|
||||
files.forEach(function(file) {
|
||||
var inputFile = path.join(inputDir, file);
|
||||
var outputFile = path.join(outputDir, file);
|
||||
fs.stat(inputFile, function(err, stat) {
|
||||
if (err) {
|
||||
fatal('Cannot read ' + inputFile + '\n' + err.message);
|
||||
}
|
||||
else if (stat.isDirectory()) {
|
||||
processDirectory(inputFile, outputFile, fileExt);
|
||||
}
|
||||
else if (!fileExt || path.extname(file) === '.' + fileExt) {
|
||||
mkdir(outputDir, function() {
|
||||
processFile(inputFile, outputFile);
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function writeMinify() {
|
||||
var minified;
|
||||
try {
|
||||
minified = minify(content, createOptions());
|
||||
}
|
||||
catch (e) {
|
||||
fatal('Minification error:\n' + e.message);
|
||||
}
|
||||
(program.output ? fs.createWriteStream(program.output).on('error', function(e) {
|
||||
fatal('Cannot write ' + program.output + '\n' + e.message);
|
||||
}) : process.stdout).write(minified);
|
||||
}
|
||||
|
||||
var inputDir = program.inputDir;
|
||||
var outputDir = program.outputDir;
|
||||
var fileExt = program.fileExt;
|
||||
if (inputDir || outputDir) {
|
||||
if (!inputDir) {
|
||||
fatal('The option output-dir needs to be used with the option input-dir. If you are working with a single file, use -o.');
|
||||
}
|
||||
else if (!outputDir) {
|
||||
fatal('You need to specify where to write the output files with the option --output-dir');
|
||||
}
|
||||
processDirectory(inputDir, outputDir, fileExt);
|
||||
}
|
||||
// Minifying one or more files specified on the CMD line
|
||||
else if (typeof content === 'string') {
|
||||
writeMinify();
|
||||
}
|
||||
// Minifying input coming from STDIN
|
||||
else {
|
||||
content = '';
|
||||
process.stdin.setEncoding('utf8');
|
||||
process.stdin.on('data', function(data) {
|
||||
content += data;
|
||||
}).on('end', writeMinify);
|
||||
}
|
||||
326
build/node_modules/html-minifier/node_modules/commander/CHANGELOG.md
generated
vendored
Normal file
326
build/node_modules/html-minifier/node_modules/commander/CHANGELOG.md
generated
vendored
Normal file
@@ -0,0 +1,326 @@
|
||||
|
||||
2.12.2 / 2017-11-28
|
||||
==================
|
||||
|
||||
* fix: typings are not shipped
|
||||
|
||||
2.12.1 / 2017-11-23
|
||||
==================
|
||||
|
||||
* Move @types/node to dev dependency
|
||||
|
||||
2.12.0 / 2017-11-22
|
||||
==================
|
||||
|
||||
* add attributeName() method to Option objects
|
||||
* Documentation updated for options with --no prefix
|
||||
* typings: `outputHelp` takes a string as the first parameter
|
||||
* typings: use overloads
|
||||
* feat(typings): update to match js api
|
||||
* Print default value in option help
|
||||
* Fix translation error
|
||||
* Fail when using same command and alias (#491)
|
||||
* feat(typings): add help callback
|
||||
* fix bug when description is add after command with options (#662)
|
||||
* Format js code
|
||||
* Rename History.md to CHANGELOG.md (#668)
|
||||
* feat(typings): add typings to support TypeScript (#646)
|
||||
* use current node
|
||||
|
||||
2.11.0 / 2017-07-03
|
||||
==================
|
||||
|
||||
* Fix help section order and padding (#652)
|
||||
* feature: support for signals to subcommands (#632)
|
||||
* Fixed #37, --help should not display first (#447)
|
||||
* Fix translation errors. (#570)
|
||||
* Add package-lock.json
|
||||
* Remove engines
|
||||
* Upgrade package version
|
||||
* Prefix events to prevent conflicts between commands and options (#494)
|
||||
* Removing dependency on graceful-readlink
|
||||
* Support setting name in #name function and make it chainable
|
||||
* Add .vscode directory to .gitignore (Visual Studio Code metadata)
|
||||
* Updated link to ruby commander in readme files
|
||||
|
||||
2.10.0 / 2017-06-19
|
||||
==================
|
||||
|
||||
* Update .travis.yml. drop support for older node.js versions.
|
||||
* Fix require arguments in README.md
|
||||
* On SemVer you do not start from 0.0.1
|
||||
* Add missing semi colon in readme
|
||||
* Add save param to npm install
|
||||
* node v6 travis test
|
||||
* Update Readme_zh-CN.md
|
||||
* Allow literal '--' to be passed-through as an argument
|
||||
* Test subcommand alias help
|
||||
* link build badge to master branch
|
||||
* Support the alias of Git style sub-command
|
||||
* added keyword commander for better search result on npm
|
||||
* Fix Sub-Subcommands
|
||||
* test node.js stable
|
||||
* Fixes TypeError when a command has an option called `--description`
|
||||
* Update README.md to make it beginner friendly and elaborate on the difference between angled and square brackets.
|
||||
* Add chinese Readme file
|
||||
|
||||
2.9.0 / 2015-10-13
|
||||
==================
|
||||
|
||||
* Add option `isDefault` to set default subcommand #415 @Qix-
|
||||
* Add callback to allow filtering or post-processing of help text #434 @djulien
|
||||
* Fix `undefined` text in help information close #414 #416 @zhiyelee
|
||||
|
||||
2.8.1 / 2015-04-22
|
||||
==================
|
||||
|
||||
* Back out `support multiline description` Close #396 #397
|
||||
|
||||
2.8.0 / 2015-04-07
|
||||
==================
|
||||
|
||||
* Add `process.execArg` support, execution args like `--harmony` will be passed to sub-commands #387 @DigitalIO @zhiyelee
|
||||
* Fix bug in Git-style sub-commands #372 @zhiyelee
|
||||
* Allow commands to be hidden from help #383 @tonylukasavage
|
||||
* When git-style sub-commands are in use, yet none are called, display help #382 @claylo
|
||||
* Add ability to specify arguments syntax for top-level command #258 @rrthomas
|
||||
* Support multiline descriptions #208 @zxqfox
|
||||
|
||||
2.7.1 / 2015-03-11
|
||||
==================
|
||||
|
||||
* Revert #347 (fix collisions when option and first arg have same name) which causes a bug in #367.
|
||||
|
||||
2.7.0 / 2015-03-09
|
||||
==================
|
||||
|
||||
* Fix git-style bug when installed globally. Close #335 #349 @zhiyelee
|
||||
* Fix collisions when option and first arg have same name. Close #346 #347 @tonylukasavage
|
||||
* Add support for camelCase on `opts()`. Close #353 @nkzawa
|
||||
* Add node.js 0.12 and io.js to travis.yml
|
||||
* Allow RegEx options. #337 @palanik
|
||||
* Fixes exit code when sub-command failing. Close #260 #332 @pirelenito
|
||||
* git-style `bin` files in $PATH make sense. Close #196 #327 @zhiyelee
|
||||
|
||||
2.6.0 / 2014-12-30
|
||||
==================
|
||||
|
||||
* added `Command#allowUnknownOption` method. Close #138 #318 @doozr @zhiyelee
|
||||
* Add application description to the help msg. Close #112 @dalssoft
|
||||
|
||||
2.5.1 / 2014-12-15
|
||||
==================
|
||||
|
||||
* fixed two bugs incurred by variadic arguments. Close #291 @Quentin01 #302 @zhiyelee
|
||||
|
||||
2.5.0 / 2014-10-24
|
||||
==================
|
||||
|
||||
* add support for variadic arguments. Closes #277 @whitlockjc
|
||||
|
||||
2.4.0 / 2014-10-17
|
||||
==================
|
||||
|
||||
* fixed a bug on executing the coercion function of subcommands option. Closes #270
|
||||
* added `Command.prototype.name` to retrieve command name. Closes #264 #266 @tonylukasavage
|
||||
* added `Command.prototype.opts` to retrieve all the options as a simple object of key-value pairs. Closes #262 @tonylukasavage
|
||||
* fixed a bug on subcommand name. Closes #248 @jonathandelgado
|
||||
* fixed function normalize doesn’t honor option terminator. Closes #216 @abbr
|
||||
|
||||
2.3.0 / 2014-07-16
|
||||
==================
|
||||
|
||||
* add command alias'. Closes PR #210
|
||||
* fix: Typos. Closes #99
|
||||
* fix: Unused fs module. Closes #217
|
||||
|
||||
2.2.0 / 2014-03-29
|
||||
==================
|
||||
|
||||
* add passing of previous option value
|
||||
* fix: support subcommands on windows. Closes #142
|
||||
* Now the defaultValue passed as the second argument of the coercion function.
|
||||
|
||||
2.1.0 / 2013-11-21
|
||||
==================
|
||||
|
||||
* add: allow cflag style option params, unit test, fixes #174
|
||||
|
||||
2.0.0 / 2013-07-18
|
||||
==================
|
||||
|
||||
* remove input methods (.prompt, .confirm, etc)
|
||||
|
||||
1.3.2 / 2013-07-18
|
||||
==================
|
||||
|
||||
* add support for sub-commands to co-exist with the original command
|
||||
|
||||
1.3.1 / 2013-07-18
|
||||
==================
|
||||
|
||||
* add quick .runningCommand hack so you can opt-out of other logic when running a sub command
|
||||
|
||||
1.3.0 / 2013-07-09
|
||||
==================
|
||||
|
||||
* add EACCES error handling
|
||||
* fix sub-command --help
|
||||
|
||||
1.2.0 / 2013-06-13
|
||||
==================
|
||||
|
||||
* allow "-" hyphen as an option argument
|
||||
* support for RegExp coercion
|
||||
|
||||
1.1.1 / 2012-11-20
|
||||
==================
|
||||
|
||||
* add more sub-command padding
|
||||
* fix .usage() when args are present. Closes #106
|
||||
|
||||
1.1.0 / 2012-11-16
|
||||
==================
|
||||
|
||||
* add git-style executable subcommand support. Closes #94
|
||||
|
||||
1.0.5 / 2012-10-09
|
||||
==================
|
||||
|
||||
* fix `--name` clobbering. Closes #92
|
||||
* fix examples/help. Closes #89
|
||||
|
||||
1.0.4 / 2012-09-03
|
||||
==================
|
||||
|
||||
* add `outputHelp()` method.
|
||||
|
||||
1.0.3 / 2012-08-30
|
||||
==================
|
||||
|
||||
* remove invalid .version() defaulting
|
||||
|
||||
1.0.2 / 2012-08-24
|
||||
==================
|
||||
|
||||
* add `--foo=bar` support [arv]
|
||||
* fix password on node 0.8.8. Make backward compatible with 0.6 [focusaurus]
|
||||
|
||||
1.0.1 / 2012-08-03
|
||||
==================
|
||||
|
||||
* fix issue #56
|
||||
* fix tty.setRawMode(mode) was moved to tty.ReadStream#setRawMode() (i.e. process.stdin.setRawMode())
|
||||
|
||||
1.0.0 / 2012-07-05
|
||||
==================
|
||||
|
||||
* add support for optional option descriptions
|
||||
* add defaulting of `.version()` to package.json's version
|
||||
|
||||
0.6.1 / 2012-06-01
|
||||
==================
|
||||
|
||||
* Added: append (yes or no) on confirmation
|
||||
* Added: allow node.js v0.7.x
|
||||
|
||||
0.6.0 / 2012-04-10
|
||||
==================
|
||||
|
||||
* Added `.prompt(obj, callback)` support. Closes #49
|
||||
* Added default support to .choose(). Closes #41
|
||||
* Fixed the choice example
|
||||
|
||||
0.5.1 / 2011-12-20
|
||||
==================
|
||||
|
||||
* Fixed `password()` for recent nodes. Closes #36
|
||||
|
||||
0.5.0 / 2011-12-04
|
||||
==================
|
||||
|
||||
* Added sub-command option support [itay]
|
||||
|
||||
0.4.3 / 2011-12-04
|
||||
==================
|
||||
|
||||
* Fixed custom help ordering. Closes #32
|
||||
|
||||
0.4.2 / 2011-11-24
|
||||
==================
|
||||
|
||||
* Added travis support
|
||||
* Fixed: line-buffered input automatically trimmed. Closes #31
|
||||
|
||||
0.4.1 / 2011-11-18
|
||||
==================
|
||||
|
||||
* Removed listening for "close" on --help
|
||||
|
||||
0.4.0 / 2011-11-15
|
||||
==================
|
||||
|
||||
* Added support for `--`. Closes #24
|
||||
|
||||
0.3.3 / 2011-11-14
|
||||
==================
|
||||
|
||||
* Fixed: wait for close event when writing help info [Jerry Hamlet]
|
||||
|
||||
0.3.2 / 2011-11-01
|
||||
==================
|
||||
|
||||
* Fixed long flag definitions with values [felixge]
|
||||
|
||||
0.3.1 / 2011-10-31
|
||||
==================
|
||||
|
||||
* Changed `--version` short flag to `-V` from `-v`
|
||||
* Changed `.version()` so it's configurable [felixge]
|
||||
|
||||
0.3.0 / 2011-10-31
|
||||
==================
|
||||
|
||||
* Added support for long flags only. Closes #18
|
||||
|
||||
0.2.1 / 2011-10-24
|
||||
==================
|
||||
|
||||
* "node": ">= 0.4.x < 0.7.0". Closes #20
|
||||
|
||||
0.2.0 / 2011-09-26
|
||||
==================
|
||||
|
||||
* Allow for defaults that are not just boolean. Default peassignment only occurs for --no-*, optional, and required arguments. [Jim Isaacs]
|
||||
|
||||
0.1.0 / 2011-08-24
|
||||
==================
|
||||
|
||||
* Added support for custom `--help` output
|
||||
|
||||
0.0.5 / 2011-08-18
|
||||
==================
|
||||
|
||||
* Changed: when the user enters nothing prompt for password again
|
||||
* Fixed issue with passwords beginning with numbers [NuckChorris]
|
||||
|
||||
0.0.4 / 2011-08-15
|
||||
==================
|
||||
|
||||
* Fixed `Commander#args`
|
||||
|
||||
0.0.3 / 2011-08-15
|
||||
==================
|
||||
|
||||
* Added default option value support
|
||||
|
||||
0.0.2 / 2011-08-15
|
||||
==================
|
||||
|
||||
* Added mask support to `Command#password(str[, mask], fn)`
|
||||
* Added `Command#password(str, fn)`
|
||||
|
||||
0.0.1 / 2010-01-03
|
||||
==================
|
||||
|
||||
* Initial release
|
||||
22
build/node_modules/html-minifier/node_modules/commander/LICENSE
generated
vendored
Normal file
22
build/node_modules/html-minifier/node_modules/commander/LICENSE
generated
vendored
Normal file
@@ -0,0 +1,22 @@
|
||||
(The MIT License)
|
||||
|
||||
Copyright (c) 2011 TJ Holowaychuk <tj@vision-media.ca>
|
||||
|
||||
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.
|
||||
370
build/node_modules/html-minifier/node_modules/commander/Readme.md
generated
vendored
Normal file
370
build/node_modules/html-minifier/node_modules/commander/Readme.md
generated
vendored
Normal file
@@ -0,0 +1,370 @@
|
||||
# Commander.js
|
||||
|
||||
|
||||
[](http://travis-ci.org/tj/commander.js)
|
||||
[](https://www.npmjs.org/package/commander)
|
||||
[](https://www.npmjs.org/package/commander)
|
||||
[](https://gitter.im/tj/commander.js?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
|
||||
|
||||
The complete solution for [node.js](http://nodejs.org) command-line interfaces, inspired by Ruby's [commander](https://github.com/commander-rb/commander).
|
||||
[API documentation](http://tj.github.com/commander.js/)
|
||||
|
||||
|
||||
## Installation
|
||||
|
||||
$ npm install commander --save
|
||||
|
||||
## Option parsing
|
||||
|
||||
Options with commander are defined with the `.option()` method, also serving as documentation for the options. The example below parses args and options from `process.argv`, leaving remaining args as the `program.args` array which were not consumed by options.
|
||||
|
||||
```js
|
||||
#!/usr/bin/env node
|
||||
|
||||
/**
|
||||
* Module dependencies.
|
||||
*/
|
||||
|
||||
var program = require('commander');
|
||||
|
||||
program
|
||||
.version('0.1.0')
|
||||
.option('-p, --peppers', 'Add peppers')
|
||||
.option('-P, --pineapple', 'Add pineapple')
|
||||
.option('-b, --bbq-sauce', 'Add bbq sauce')
|
||||
.option('-c, --cheese [type]', 'Add the specified type of cheese [marble]', 'marble')
|
||||
.parse(process.argv);
|
||||
|
||||
console.log('you ordered a pizza with:');
|
||||
if (program.peppers) console.log(' - peppers');
|
||||
if (program.pineapple) console.log(' - pineapple');
|
||||
if (program.bbqSauce) console.log(' - bbq');
|
||||
console.log(' - %s cheese', program.cheese);
|
||||
```
|
||||
|
||||
Short flags may be passed as a single arg, for example `-abc` is equivalent to `-a -b -c`. Multi-word options such as "--template-engine" are camel-cased, becoming `program.templateEngine` etc.
|
||||
|
||||
Note that multi-word options starting with `--no` prefix negate the boolean value of the following word. For example, `--no-sauce` sets the value of `program.sauce` to false.
|
||||
|
||||
```js
|
||||
#!/usr/bin/env node
|
||||
|
||||
/**
|
||||
* Module dependencies.
|
||||
*/
|
||||
|
||||
var program = require('commander');
|
||||
|
||||
program
|
||||
.option('--no-sauce', 'Remove sauce')
|
||||
.parse(process.argv);
|
||||
|
||||
console.log('you ordered a pizza');
|
||||
if (program.sauce) console.log(' with sauce');
|
||||
else console.log(' without sauce');
|
||||
```
|
||||
|
||||
## Coercion
|
||||
|
||||
```js
|
||||
function range(val) {
|
||||
return val.split('..').map(Number);
|
||||
}
|
||||
|
||||
function list(val) {
|
||||
return val.split(',');
|
||||
}
|
||||
|
||||
function collect(val, memo) {
|
||||
memo.push(val);
|
||||
return memo;
|
||||
}
|
||||
|
||||
function increaseVerbosity(v, total) {
|
||||
return total + 1;
|
||||
}
|
||||
|
||||
program
|
||||
.version('0.1.0')
|
||||
.usage('[options] <file ...>')
|
||||
.option('-i, --integer <n>', 'An integer argument', parseInt)
|
||||
.option('-f, --float <n>', 'A float argument', parseFloat)
|
||||
.option('-r, --range <a>..<b>', 'A range', range)
|
||||
.option('-l, --list <items>', 'A list', list)
|
||||
.option('-o, --optional [value]', 'An optional value')
|
||||
.option('-c, --collect [value]', 'A repeatable value', collect, [])
|
||||
.option('-v, --verbose', 'A value that can be increased', increaseVerbosity, 0)
|
||||
.parse(process.argv);
|
||||
|
||||
console.log(' int: %j', program.integer);
|
||||
console.log(' float: %j', program.float);
|
||||
console.log(' optional: %j', program.optional);
|
||||
program.range = program.range || [];
|
||||
console.log(' range: %j..%j', program.range[0], program.range[1]);
|
||||
console.log(' list: %j', program.list);
|
||||
console.log(' collect: %j', program.collect);
|
||||
console.log(' verbosity: %j', program.verbose);
|
||||
console.log(' args: %j', program.args);
|
||||
```
|
||||
|
||||
## Regular Expression
|
||||
```js
|
||||
program
|
||||
.version('0.1.0')
|
||||
.option('-s --size <size>', 'Pizza size', /^(large|medium|small)$/i, 'medium')
|
||||
.option('-d --drink [drink]', 'Drink', /^(coke|pepsi|izze)$/i)
|
||||
.parse(process.argv);
|
||||
|
||||
console.log(' size: %j', program.size);
|
||||
console.log(' drink: %j', program.drink);
|
||||
```
|
||||
|
||||
## Variadic arguments
|
||||
|
||||
The last argument of a command can be variadic, and only the last argument. To make an argument variadic you have to
|
||||
append `...` to the argument name. Here is an example:
|
||||
|
||||
```js
|
||||
#!/usr/bin/env node
|
||||
|
||||
/**
|
||||
* Module dependencies.
|
||||
*/
|
||||
|
||||
var program = require('commander');
|
||||
|
||||
program
|
||||
.version('0.1.0')
|
||||
.command('rmdir <dir> [otherDirs...]')
|
||||
.action(function (dir, otherDirs) {
|
||||
console.log('rmdir %s', dir);
|
||||
if (otherDirs) {
|
||||
otherDirs.forEach(function (oDir) {
|
||||
console.log('rmdir %s', oDir);
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
program.parse(process.argv);
|
||||
```
|
||||
|
||||
An `Array` is used for the value of a variadic argument. This applies to `program.args` as well as the argument passed
|
||||
to your action as demonstrated above.
|
||||
|
||||
## Specify the argument syntax
|
||||
|
||||
```js
|
||||
#!/usr/bin/env node
|
||||
|
||||
var program = require('commander');
|
||||
|
||||
program
|
||||
.version('0.1.0')
|
||||
.arguments('<cmd> [env]')
|
||||
.action(function (cmd, env) {
|
||||
cmdValue = cmd;
|
||||
envValue = env;
|
||||
});
|
||||
|
||||
program.parse(process.argv);
|
||||
|
||||
if (typeof cmdValue === 'undefined') {
|
||||
console.error('no command given!');
|
||||
process.exit(1);
|
||||
}
|
||||
console.log('command:', cmdValue);
|
||||
console.log('environment:', envValue || "no environment given");
|
||||
```
|
||||
Angled brackets (e.g. `<cmd>`) indicate required input. Square brackets (e.g. `[env]`) indicate optional input.
|
||||
|
||||
## Git-style sub-commands
|
||||
|
||||
```js
|
||||
// file: ./examples/pm
|
||||
var program = require('commander');
|
||||
|
||||
program
|
||||
.version('0.1.0')
|
||||
.command('install [name]', 'install one or more packages')
|
||||
.command('search [query]', 'search with optional query')
|
||||
.command('list', 'list packages installed', {isDefault: true})
|
||||
.parse(process.argv);
|
||||
```
|
||||
|
||||
When `.command()` is invoked with a description argument, no `.action(callback)` should be called to handle sub-commands, otherwise there will be an error. This tells commander that you're going to use separate executables for sub-commands, much like `git(1)` and other popular tools.
|
||||
The commander will try to search the executables in the directory of the entry script (like `./examples/pm`) with the name `program-command`, like `pm-install`, `pm-search`.
|
||||
|
||||
Options can be passed with the call to `.command()`. Specifying `true` for `opts.noHelp` will remove the option from the generated help output. Specifying `true` for `opts.isDefault` will run the subcommand if no other subcommand is specified.
|
||||
|
||||
If the program is designed to be installed globally, make sure the executables have proper modes, like `755`.
|
||||
|
||||
### `--harmony`
|
||||
|
||||
You can enable `--harmony` option in two ways:
|
||||
* Use `#! /usr/bin/env node --harmony` in the sub-commands scripts. Note some os version don’t support this pattern.
|
||||
* Use the `--harmony` option when call the command, like `node --harmony examples/pm publish`. The `--harmony` option will be preserved when spawning sub-command process.
|
||||
|
||||
## Automated --help
|
||||
|
||||
The help information is auto-generated based on the information commander already knows about your program, so the following `--help` info is for free:
|
||||
|
||||
```
|
||||
$ ./examples/pizza --help
|
||||
|
||||
Usage: pizza [options]
|
||||
|
||||
An application for pizzas ordering
|
||||
|
||||
Options:
|
||||
|
||||
-h, --help output usage information
|
||||
-V, --version output the version number
|
||||
-p, --peppers Add peppers
|
||||
-P, --pineapple Add pineapple
|
||||
-b, --bbq Add bbq sauce
|
||||
-c, --cheese <type> Add the specified type of cheese [marble]
|
||||
-C, --no-cheese You do not want any cheese
|
||||
|
||||
```
|
||||
|
||||
## Custom help
|
||||
|
||||
You can display arbitrary `-h, --help` information
|
||||
by listening for "--help". Commander will automatically
|
||||
exit once you are done so that the remainder of your program
|
||||
does not execute causing undesired behaviours, for example
|
||||
in the following executable "stuff" will not output when
|
||||
`--help` is used.
|
||||
|
||||
```js
|
||||
#!/usr/bin/env node
|
||||
|
||||
/**
|
||||
* Module dependencies.
|
||||
*/
|
||||
|
||||
var program = require('commander');
|
||||
|
||||
program
|
||||
.version('0.1.0')
|
||||
.option('-f, --foo', 'enable some foo')
|
||||
.option('-b, --bar', 'enable some bar')
|
||||
.option('-B, --baz', 'enable some baz');
|
||||
|
||||
// must be before .parse() since
|
||||
// node's emit() is immediate
|
||||
|
||||
program.on('--help', function(){
|
||||
console.log(' Examples:');
|
||||
console.log('');
|
||||
console.log(' $ custom-help --help');
|
||||
console.log(' $ custom-help -h');
|
||||
console.log('');
|
||||
});
|
||||
|
||||
program.parse(process.argv);
|
||||
|
||||
console.log('stuff');
|
||||
```
|
||||
|
||||
Yields the following help output when `node script-name.js -h` or `node script-name.js --help` are run:
|
||||
|
||||
```
|
||||
|
||||
Usage: custom-help [options]
|
||||
|
||||
Options:
|
||||
|
||||
-h, --help output usage information
|
||||
-V, --version output the version number
|
||||
-f, --foo enable some foo
|
||||
-b, --bar enable some bar
|
||||
-B, --baz enable some baz
|
||||
|
||||
Examples:
|
||||
|
||||
$ custom-help --help
|
||||
$ custom-help -h
|
||||
|
||||
```
|
||||
|
||||
## .outputHelp(cb)
|
||||
|
||||
Output help information without exiting.
|
||||
Optional callback cb allows post-processing of help text before it is displayed.
|
||||
|
||||
If you want to display help by default (e.g. if no command was provided), you can use something like:
|
||||
|
||||
```js
|
||||
var program = require('commander');
|
||||
var colors = require('colors');
|
||||
|
||||
program
|
||||
.version('0.1.0')
|
||||
.command('getstream [url]', 'get stream URL')
|
||||
.parse(process.argv);
|
||||
|
||||
if (!process.argv.slice(2).length) {
|
||||
program.outputHelp(make_red);
|
||||
}
|
||||
|
||||
function make_red(txt) {
|
||||
return colors.red(txt); //display the help text in red on the console
|
||||
}
|
||||
```
|
||||
|
||||
## .help(cb)
|
||||
|
||||
Output help information and exit immediately.
|
||||
Optional callback cb allows post-processing of help text before it is displayed.
|
||||
|
||||
## Examples
|
||||
|
||||
```js
|
||||
var program = require('commander');
|
||||
|
||||
program
|
||||
.version('0.1.0')
|
||||
.option('-C, --chdir <path>', 'change the working directory')
|
||||
.option('-c, --config <path>', 'set config path. defaults to ./deploy.conf')
|
||||
.option('-T, --no-tests', 'ignore test hook');
|
||||
|
||||
program
|
||||
.command('setup [env]')
|
||||
.description('run setup commands for all envs')
|
||||
.option("-s, --setup_mode [mode]", "Which setup mode to use")
|
||||
.action(function(env, options){
|
||||
var mode = options.setup_mode || "normal";
|
||||
env = env || 'all';
|
||||
console.log('setup for %s env(s) with %s mode', env, mode);
|
||||
});
|
||||
|
||||
program
|
||||
.command('exec <cmd>')
|
||||
.alias('ex')
|
||||
.description('execute the given remote cmd')
|
||||
.option("-e, --exec_mode <mode>", "Which exec mode to use")
|
||||
.action(function(cmd, options){
|
||||
console.log('exec "%s" using %s mode', cmd, options.exec_mode);
|
||||
}).on('--help', function() {
|
||||
console.log(' Examples:');
|
||||
console.log();
|
||||
console.log(' $ deploy exec sequential');
|
||||
console.log(' $ deploy exec async');
|
||||
console.log();
|
||||
});
|
||||
|
||||
program
|
||||
.command('*')
|
||||
.action(function(env){
|
||||
console.log('deploying "%s"', env);
|
||||
});
|
||||
|
||||
program.parse(process.argv);
|
||||
```
|
||||
|
||||
More Demos can be found in the [examples](https://github.com/tj/commander.js/tree/master/examples) directory.
|
||||
|
||||
## License
|
||||
|
||||
MIT
|
||||
1158
build/node_modules/html-minifier/node_modules/commander/index.js
generated
vendored
Normal file
1158
build/node_modules/html-minifier/node_modules/commander/index.js
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
66
build/node_modules/html-minifier/node_modules/commander/package.json
generated
vendored
Normal file
66
build/node_modules/html-minifier/node_modules/commander/package.json
generated
vendored
Normal file
@@ -0,0 +1,66 @@
|
||||
{
|
||||
"_from": "commander@2.12.x",
|
||||
"_id": "commander@2.12.2",
|
||||
"_inBundle": false,
|
||||
"_integrity": "sha512-BFnaq5ZOGcDN7FlrtBT4xxkgIToalIIxwjxLWVJ8bGTpe1LroqMiqQXdA7ygc7CRvaYS+9zfPGFnJqFSayx+AA==",
|
||||
"_location": "/html-minifier/commander",
|
||||
"_phantomChildren": {},
|
||||
"_requested": {
|
||||
"type": "range",
|
||||
"registry": true,
|
||||
"raw": "commander@2.12.x",
|
||||
"name": "commander",
|
||||
"escapedName": "commander",
|
||||
"rawSpec": "2.12.x",
|
||||
"saveSpec": null,
|
||||
"fetchSpec": "2.12.x"
|
||||
},
|
||||
"_requiredBy": [
|
||||
"/html-minifier"
|
||||
],
|
||||
"_resolved": "https://registry.npmjs.org/commander/-/commander-2.12.2.tgz",
|
||||
"_shasum": "0f5946c427ed9ec0d91a46bb9def53e54650e555",
|
||||
"_spec": "commander@2.12.x",
|
||||
"_where": "/Users/asciidisco/Desktop/asciidisco.com/build/node_modules/html-minifier",
|
||||
"author": {
|
||||
"name": "TJ Holowaychuk",
|
||||
"email": "tj@vision-media.ca"
|
||||
},
|
||||
"bugs": {
|
||||
"url": "https://github.com/tj/commander.js/issues"
|
||||
},
|
||||
"bundleDependencies": false,
|
||||
"dependencies": {},
|
||||
"deprecated": false,
|
||||
"description": "the complete solution for node.js command-line programs",
|
||||
"devDependencies": {
|
||||
"@types/node": "^7.0.48",
|
||||
"should": "^11.2.1",
|
||||
"sinon": "^2.4.1",
|
||||
"typescript": "^2.6.2"
|
||||
},
|
||||
"files": [
|
||||
"index.js",
|
||||
"typings/index.d.ts"
|
||||
],
|
||||
"homepage": "https://github.com/tj/commander.js#readme",
|
||||
"keywords": [
|
||||
"commander",
|
||||
"command",
|
||||
"option",
|
||||
"parser"
|
||||
],
|
||||
"license": "MIT",
|
||||
"main": "index",
|
||||
"name": "commander",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+https://github.com/tj/commander.js.git"
|
||||
},
|
||||
"scripts": {
|
||||
"test": "make test && npm run test-typings",
|
||||
"test-typings": "node_modules/typescript/bin/tsc -p tsconfig.json"
|
||||
},
|
||||
"typings": "typings/index.d.ts",
|
||||
"version": "2.12.2"
|
||||
}
|
||||
295
build/node_modules/html-minifier/node_modules/commander/typings/index.d.ts
generated
vendored
Normal file
295
build/node_modules/html-minifier/node_modules/commander/typings/index.d.ts
generated
vendored
Normal file
@@ -0,0 +1,295 @@
|
||||
// Project: https://github.com/visionmedia/commander.js
|
||||
// Definitions by: Alan Agius <https://github.com/alan-agius4>, Marcelo Dezem <https://github.com/mdezem>, vvakame <https://github.com/vvakame>
|
||||
|
||||
declare class Option {
|
||||
flags: string;
|
||||
required: boolean;
|
||||
optional: boolean;
|
||||
bool: boolean;
|
||||
short?: string;
|
||||
long: string;
|
||||
description: string;
|
||||
|
||||
/**
|
||||
* Initialize a new `Option` with the given `flags` and `description`.
|
||||
*
|
||||
* @param {string} flags
|
||||
* @param {string} [description]
|
||||
*/
|
||||
constructor(flags: string, description?: string);
|
||||
}
|
||||
|
||||
declare class Command extends NodeJS.EventEmitter {
|
||||
[key: string]: any;
|
||||
|
||||
args: string[];
|
||||
|
||||
/**
|
||||
* Initialize a new `Command`.
|
||||
*
|
||||
* @param {string} [name]
|
||||
*/
|
||||
constructor(name?: string);
|
||||
|
||||
/**
|
||||
* Set the program version to `str`.
|
||||
*
|
||||
* This method auto-registers the "-V, --version" flag
|
||||
* which will print the version number when passed.
|
||||
*
|
||||
* @param {string} str
|
||||
* @param {string} [flags]
|
||||
* @returns {Command} for chaining
|
||||
*/
|
||||
version(str: string, flags?: string): Command;
|
||||
|
||||
/**
|
||||
* Add command `name`.
|
||||
*
|
||||
* The `.action()` callback is invoked when the
|
||||
* command `name` is specified via __ARGV__,
|
||||
* and the remaining arguments are applied to the
|
||||
* function for access.
|
||||
*
|
||||
* When the `name` is "*" an un-matched command
|
||||
* will be passed as the first arg, followed by
|
||||
* the rest of __ARGV__ remaining.
|
||||
*
|
||||
* @example
|
||||
* program
|
||||
* .version('0.0.1')
|
||||
* .option('-C, --chdir <path>', 'change the working directory')
|
||||
* .option('-c, --config <path>', 'set config path. defaults to ./deploy.conf')
|
||||
* .option('-T, --no-tests', 'ignore test hook')
|
||||
*
|
||||
* program
|
||||
* .command('setup')
|
||||
* .description('run remote setup commands')
|
||||
* .action(function() {
|
||||
* console.log('setup');
|
||||
* });
|
||||
*
|
||||
* program
|
||||
* .command('exec <cmd>')
|
||||
* .description('run the given remote command')
|
||||
* .action(function(cmd) {
|
||||
* console.log('exec "%s"', cmd);
|
||||
* });
|
||||
*
|
||||
* program
|
||||
* .command('teardown <dir> [otherDirs...]')
|
||||
* .description('run teardown commands')
|
||||
* .action(function(dir, otherDirs) {
|
||||
* console.log('dir "%s"', dir);
|
||||
* if (otherDirs) {
|
||||
* otherDirs.forEach(function (oDir) {
|
||||
* console.log('dir "%s"', oDir);
|
||||
* });
|
||||
* }
|
||||
* });
|
||||
*
|
||||
* program
|
||||
* .command('*')
|
||||
* .description('deploy the given env')
|
||||
* .action(function(env) {
|
||||
* console.log('deploying "%s"', env);
|
||||
* });
|
||||
*
|
||||
* program.parse(process.argv);
|
||||
*
|
||||
* @param {string} name
|
||||
* @param {string} [desc] for git-style sub-commands
|
||||
* @param {CommandOptions} [opts] command options
|
||||
* @returns {Command} the new command
|
||||
*/
|
||||
command(name: string, desc?: string, opts?: commander.CommandOptions): Command;
|
||||
|
||||
/**
|
||||
* Define argument syntax for the top-level command.
|
||||
*
|
||||
* @param {string} desc
|
||||
* @returns {Command} for chaining
|
||||
*/
|
||||
arguments(desc: string): Command;
|
||||
|
||||
/**
|
||||
* Parse expected `args`.
|
||||
*
|
||||
* For example `["[type]"]` becomes `[{ required: false, name: 'type' }]`.
|
||||
*
|
||||
* @param {string[]} args
|
||||
* @returns {Command} for chaining
|
||||
*/
|
||||
parseExpectedArgs(args: string[]): Command;
|
||||
/**
|
||||
* Register callback `fn` for the command.
|
||||
*
|
||||
* @example
|
||||
* program
|
||||
* .command('help')
|
||||
* .description('display verbose help')
|
||||
* .action(function() {
|
||||
* // output help here
|
||||
* });
|
||||
*
|
||||
* @param {(...args: any[]) => void} fn
|
||||
* @returns {Command} for chaining
|
||||
*/
|
||||
action(fn: (...args: any[]) => void): Command;
|
||||
|
||||
/**
|
||||
* Define option with `flags`, `description` and optional
|
||||
* coercion `fn`.
|
||||
*
|
||||
* The `flags` string should contain both the short and long flags,
|
||||
* separated by comma, a pipe or space. The following are all valid
|
||||
* all will output this way when `--help` is used.
|
||||
*
|
||||
* "-p, --pepper"
|
||||
* "-p|--pepper"
|
||||
* "-p --pepper"
|
||||
*
|
||||
* @example
|
||||
* // simple boolean defaulting to false
|
||||
* program.option('-p, --pepper', 'add pepper');
|
||||
*
|
||||
* --pepper
|
||||
* program.pepper
|
||||
* // => Boolean
|
||||
*
|
||||
* // simple boolean defaulting to true
|
||||
* program.option('-C, --no-cheese', 'remove cheese');
|
||||
*
|
||||
* program.cheese
|
||||
* // => true
|
||||
*
|
||||
* --no-cheese
|
||||
* program.cheese
|
||||
* // => false
|
||||
*
|
||||
* // required argument
|
||||
* program.option('-C, --chdir <path>', 'change the working directory');
|
||||
*
|
||||
* --chdir /tmp
|
||||
* program.chdir
|
||||
* // => "/tmp"
|
||||
*
|
||||
* // optional argument
|
||||
* program.option('-c, --cheese [type]', 'add cheese [marble]');
|
||||
*
|
||||
* @param {string} flags
|
||||
* @param {string} [description]
|
||||
* @param {((arg1: any, arg2: any) => void) | RegExp} [fn] function or default
|
||||
* @param {*} [defaultValue]
|
||||
* @returns {Command} for chaining
|
||||
*/
|
||||
option(flags: string, description?: string, fn?: ((arg1: any, arg2: any) => void) | RegExp, defaultValue?: any): Command;
|
||||
option(flags: string, description?: string, defaultValue?: any): Command;
|
||||
|
||||
/**
|
||||
* Allow unknown options on the command line.
|
||||
*
|
||||
* @param {boolean} [arg] if `true` or omitted, no error will be thrown for unknown options.
|
||||
* @returns {Command} for chaining
|
||||
*/
|
||||
allowUnknownOption(arg?: boolean): Command;
|
||||
|
||||
/**
|
||||
* Parse `argv`, settings options and invoking commands when defined.
|
||||
*
|
||||
* @param {string[]} argv
|
||||
* @returns {Command} for chaining
|
||||
*/
|
||||
parse(argv: string[]): Command;
|
||||
|
||||
/**
|
||||
* Parse options from `argv` returning `argv` void of these options.
|
||||
*
|
||||
* @param {string[]} argv
|
||||
* @returns {ParseOptionsResult}
|
||||
*/
|
||||
parseOptions(argv: string[]): commander.ParseOptionsResult;
|
||||
|
||||
/**
|
||||
* Return an object containing options as key-value pairs
|
||||
*
|
||||
* @returns {{[key: string]: string}}
|
||||
*/
|
||||
opts(): { [key: string]: string };
|
||||
|
||||
/**
|
||||
* Set the description to `str`.
|
||||
*
|
||||
* @param {string} str
|
||||
* @return {(Command | string)}
|
||||
*/
|
||||
description(str: string): Command;
|
||||
description(): string;
|
||||
|
||||
/**
|
||||
* Set an alias for the command.
|
||||
*
|
||||
* @param {string} alias
|
||||
* @return {(Command | string)}
|
||||
*/
|
||||
alias(alias: string): Command;
|
||||
alias(): string;
|
||||
|
||||
/**
|
||||
* Set or get the command usage.
|
||||
*
|
||||
* @param {string} str
|
||||
* @return {(Command | string)}
|
||||
*/
|
||||
usage(str: string): Command;
|
||||
usage(): string;
|
||||
|
||||
/**
|
||||
* Set the name of the command.
|
||||
*
|
||||
* @param {string} str
|
||||
* @return {Command}
|
||||
*/
|
||||
name(str: string): Command;
|
||||
|
||||
/**
|
||||
* Get the name of the command.
|
||||
*
|
||||
* @return {string}
|
||||
*/
|
||||
name(): string;
|
||||
|
||||
/**
|
||||
* Output help information for this command.
|
||||
*
|
||||
* @param {(str: string) => string} [cb]
|
||||
*/
|
||||
outputHelp(cb?: (str: string) => string): void;
|
||||
|
||||
/** Output help information and exit. */
|
||||
help(): void;
|
||||
}
|
||||
|
||||
declare namespace commander {
|
||||
|
||||
interface CommandOptions {
|
||||
noHelp?: boolean;
|
||||
isDefault?: boolean;
|
||||
}
|
||||
|
||||
interface ParseOptionsResult {
|
||||
args: string[];
|
||||
unknown: string[];
|
||||
}
|
||||
|
||||
interface CommanderStatic extends Command {
|
||||
Command: typeof Command;
|
||||
Option: typeof Option;
|
||||
CommandOptions: CommandOptions;
|
||||
ParseOptionsResult: ParseOptionsResult;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
declare const commander: commander.CommanderStatic;
|
||||
export = commander;
|
||||
131
build/node_modules/html-minifier/package.json
generated
vendored
Normal file
131
build/node_modules/html-minifier/package.json
generated
vendored
Normal file
@@ -0,0 +1,131 @@
|
||||
{
|
||||
"_from": "html-minifier",
|
||||
"_id": "html-minifier@3.5.8",
|
||||
"_inBundle": false,
|
||||
"_integrity": "sha512-WX7D6PB9PFq05fZ1/CyxPUuyqXed6vh2fGOM80+zJT5wAO93D/cUjLs0CcbBFjQmlwmCgRvl97RurtArIpOnkw==",
|
||||
"_location": "/html-minifier",
|
||||
"_phantomChildren": {},
|
||||
"_requested": {
|
||||
"type": "tag",
|
||||
"registry": true,
|
||||
"raw": "html-minifier",
|
||||
"name": "html-minifier",
|
||||
"escapedName": "html-minifier",
|
||||
"rawSpec": "",
|
||||
"saveSpec": null,
|
||||
"fetchSpec": "latest"
|
||||
},
|
||||
"_requiredBy": [
|
||||
"#USER",
|
||||
"/"
|
||||
],
|
||||
"_resolved": "https://registry.npmjs.org/html-minifier/-/html-minifier-3.5.8.tgz",
|
||||
"_shasum": "5ccdb1f73a0d654e6090147511f6e6b2ee312700",
|
||||
"_spec": "html-minifier",
|
||||
"_where": "/Users/asciidisco/Desktop/asciidisco.com/build",
|
||||
"author": {
|
||||
"name": "Juriy \"kangax\" Zaytsev"
|
||||
},
|
||||
"benchmarkDependencies": {
|
||||
"brotli": "1.3.x",
|
||||
"chalk": "2.3.x",
|
||||
"cli-table": "0.3.x",
|
||||
"lzma": "2.3.x",
|
||||
"minimize": "2.1.x",
|
||||
"progress": "2.0.x"
|
||||
},
|
||||
"bin": {
|
||||
"html-minifier": "./cli.js"
|
||||
},
|
||||
"bugs": {
|
||||
"url": "https://github.com/kangax/html-minifier/issues"
|
||||
},
|
||||
"bundleDependencies": false,
|
||||
"contributors": [
|
||||
{
|
||||
"name": "Gilmore Davidson",
|
||||
"url": "https://github.com/gilmoreorless"
|
||||
},
|
||||
{
|
||||
"name": "Hugo Wetterberg",
|
||||
"email": "hugo@wetterberg.nu"
|
||||
},
|
||||
{
|
||||
"name": "Zoltan Frombach",
|
||||
"email": "tssajo@gmail.com"
|
||||
}
|
||||
],
|
||||
"dependencies": {
|
||||
"camel-case": "3.0.x",
|
||||
"clean-css": "4.1.x",
|
||||
"commander": "2.12.x",
|
||||
"he": "1.1.x",
|
||||
"ncname": "1.0.x",
|
||||
"param-case": "2.1.x",
|
||||
"relateurl": "0.2.x",
|
||||
"uglify-js": "3.3.x"
|
||||
},
|
||||
"deprecated": false,
|
||||
"description": "Highly configurable, well-tested, JavaScript-based HTML minifier.",
|
||||
"devDependencies": {
|
||||
"grunt": "1.0.x",
|
||||
"grunt-browserify": "5.2.x",
|
||||
"grunt-contrib-uglify": "3.3.x",
|
||||
"gruntify-eslint": "4.0.x",
|
||||
"phantomjs-prebuilt": "2.1.x",
|
||||
"qunit": "2.x"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=4"
|
||||
},
|
||||
"files": [
|
||||
"src/*.js",
|
||||
"cli.js",
|
||||
"sample-cli-config-file.conf"
|
||||
],
|
||||
"homepage": "http://kangax.github.io/html-minifier/",
|
||||
"keywords": [
|
||||
"cli",
|
||||
"compress",
|
||||
"compressor",
|
||||
"css",
|
||||
"html",
|
||||
"htmlmin",
|
||||
"javascript",
|
||||
"min",
|
||||
"minification",
|
||||
"minifier",
|
||||
"minify",
|
||||
"optimize",
|
||||
"optimizer",
|
||||
"pack",
|
||||
"packer",
|
||||
"parse",
|
||||
"parser",
|
||||
"uglifier",
|
||||
"uglify"
|
||||
],
|
||||
"license": "MIT",
|
||||
"main": "src/htmlminifier.js",
|
||||
"maintainers": [
|
||||
{
|
||||
"name": "Alex Lam",
|
||||
"email": "alexlamsl@gmail.com"
|
||||
},
|
||||
{
|
||||
"name": "Juriy Zaytsev",
|
||||
"email": "kangax@gmail.com",
|
||||
"url": "http://perfectionkills.com"
|
||||
}
|
||||
],
|
||||
"name": "html-minifier",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+https://github.com/kangax/html-minifier.git"
|
||||
},
|
||||
"scripts": {
|
||||
"dist": "grunt dist",
|
||||
"test": "grunt test"
|
||||
},
|
||||
"version": "3.5.8"
|
||||
}
|
||||
39
build/node_modules/html-minifier/sample-cli-config-file.conf
generated
vendored
Normal file
39
build/node_modules/html-minifier/sample-cli-config-file.conf
generated
vendored
Normal file
@@ -0,0 +1,39 @@
|
||||
{
|
||||
"caseSensitive": false,
|
||||
"collapseBooleanAttributes": true,
|
||||
"collapseInlineTagWhitespace": false,
|
||||
"collapseWhitespace": true,
|
||||
"conservativeCollapse": false,
|
||||
"customAttrCollapse": ".*",
|
||||
"decodeEntities": true,
|
||||
"html5": true,
|
||||
"ignoreCustomFragments": [
|
||||
"<#[\\s\\S]*?#>",
|
||||
"<%[\\s\\S]*?%>",
|
||||
"<\\?[\\s\\S]*?\\?>"
|
||||
],
|
||||
"includeAutoGeneratedTags": false,
|
||||
"keepClosingSlash": false,
|
||||
"maxLineLength": 0,
|
||||
"minifyCSS": true,
|
||||
"minifyJS": true,
|
||||
"preserveLineBreaks": false,
|
||||
"preventAttributesEscaping": false,
|
||||
"processConditionalComments": true,
|
||||
"processScripts": [
|
||||
"text/html"
|
||||
],
|
||||
"removeAttributeQuotes": true,
|
||||
"removeComments": true,
|
||||
"removeEmptyAttributes": true,
|
||||
"removeEmptyElements": true,
|
||||
"removeOptionalTags": true,
|
||||
"removeRedundantAttributes": true,
|
||||
"removeScriptTypeAttributes": true,
|
||||
"removeStyleLinkTypeAttributes": true,
|
||||
"removeTagWhitespace": true,
|
||||
"sortAttributes": true,
|
||||
"sortClassName": true,
|
||||
"trimCustomFragments": true,
|
||||
"useShortDoctype": true
|
||||
}
|
||||
1298
build/node_modules/html-minifier/src/htmlminifier.js
generated
vendored
Normal file
1298
build/node_modules/html-minifier/src/htmlminifier.js
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
528
build/node_modules/html-minifier/src/htmlparser.js
generated
vendored
Normal file
528
build/node_modules/html-minifier/src/htmlparser.js
generated
vendored
Normal file
@@ -0,0 +1,528 @@
|
||||
/*!
|
||||
* HTML Parser By John Resig (ejohn.org)
|
||||
* Modified by Juriy "kangax" Zaytsev
|
||||
* Original code by Erik Arvidsson, Mozilla Public License
|
||||
* http://erik.eae.net/simplehtmlparser/simplehtmlparser.js
|
||||
*/
|
||||
|
||||
/*
|
||||
* // Use like so:
|
||||
* HTMLParser(htmlString, {
|
||||
* start: function(tag, attrs, unary) {},
|
||||
* end: function(tag) {},
|
||||
* chars: function(text) {},
|
||||
* comment: function(text) {}
|
||||
* });
|
||||
*
|
||||
* // or to get an XML string:
|
||||
* HTMLtoXML(htmlString);
|
||||
*
|
||||
* // or to get an XML DOM Document
|
||||
* HTMLtoDOM(htmlString);
|
||||
*
|
||||
* // or to inject into an existing document/DOM node
|
||||
* HTMLtoDOM(htmlString, document);
|
||||
* HTMLtoDOM(htmlString, document.body);
|
||||
*
|
||||
*/
|
||||
|
||||
/* global ActiveXObject, DOMDocument */
|
||||
|
||||
'use strict';
|
||||
|
||||
var createMapFromString = require('./utils').createMapFromString;
|
||||
|
||||
function makeMap(values) {
|
||||
return createMapFromString(values, true);
|
||||
}
|
||||
|
||||
// Regular Expressions for parsing tags and attributes
|
||||
var singleAttrIdentifier = /([^\s"'<>/=]+)/,
|
||||
singleAttrAssigns = [/=/],
|
||||
singleAttrValues = [
|
||||
// attr value double quotes
|
||||
/"([^"]*)"+/.source,
|
||||
// attr value, single quotes
|
||||
/'([^']*)'+/.source,
|
||||
// attr value, no quotes
|
||||
/([^ \t\n\f\r"'`=<>]+)/.source
|
||||
],
|
||||
// https://www.w3.org/TR/1999/REC-xml-names-19990114/#NT-QName
|
||||
qnameCapture = (function() {
|
||||
var ncname = require('ncname').source.slice(1, -1);
|
||||
return '((?:' + ncname + '\\:)?' + ncname + ')';
|
||||
})(),
|
||||
startTagOpen = new RegExp('^<' + qnameCapture),
|
||||
startTagClose = /^\s*(\/?)>/,
|
||||
endTag = new RegExp('^<\\/' + qnameCapture + '[^>]*>'),
|
||||
doctype = /^<!DOCTYPE [^>]+>/i;
|
||||
|
||||
var IS_REGEX_CAPTURING_BROKEN = false;
|
||||
'x'.replace(/x(.)?/g, function(m, g) {
|
||||
IS_REGEX_CAPTURING_BROKEN = g === '';
|
||||
});
|
||||
|
||||
// Empty Elements
|
||||
var empty = makeMap('area,base,basefont,br,col,embed,frame,hr,img,input,isindex,keygen,link,meta,param,source,track,wbr');
|
||||
|
||||
// Inline Elements
|
||||
var inline = makeMap('a,abbr,acronym,applet,b,basefont,bdo,big,br,button,cite,code,del,dfn,em,font,i,iframe,img,input,ins,kbd,label,map,noscript,object,q,s,samp,script,select,small,span,strike,strong,sub,sup,svg,textarea,tt,u,var');
|
||||
|
||||
// Elements that you can, intentionally, leave open
|
||||
// (and which close themselves)
|
||||
var closeSelf = makeMap('colgroup,dd,dt,li,option,p,td,tfoot,th,thead,tr,source');
|
||||
|
||||
// Attributes that have their values filled in disabled='disabled'
|
||||
var fillAttrs = makeMap('checked,compact,declare,defer,disabled,ismap,multiple,nohref,noresize,noshade,nowrap,readonly,selected');
|
||||
|
||||
// Special Elements (can contain anything)
|
||||
var special = makeMap('script,style');
|
||||
|
||||
// HTML5 tags https://html.spec.whatwg.org/multipage/indices.html#elements-3
|
||||
// Phrasing Content https://html.spec.whatwg.org/multipage/dom.html#phrasing-content
|
||||
var nonPhrasing = makeMap('address,article,aside,base,blockquote,body,caption,col,colgroup,dd,details,dialog,div,dl,dt,fieldset,figcaption,figure,footer,form,h1,h2,h3,h4,h5,h6,head,header,hgroup,hr,html,legend,li,menuitem,meta,optgroup,option,param,rp,rt,source,style,summary,tbody,td,tfoot,th,thead,title,tr,track');
|
||||
|
||||
var reCache = {};
|
||||
|
||||
function attrForHandler(handler) {
|
||||
var pattern = singleAttrIdentifier.source +
|
||||
'(?:\\s*(' + joinSingleAttrAssigns(handler) + ')' +
|
||||
'[ \\t\\n\\f\\r]*(?:' + singleAttrValues.join('|') + '))?';
|
||||
if (handler.customAttrSurround) {
|
||||
var attrClauses = [];
|
||||
for (var i = handler.customAttrSurround.length - 1; i >= 0; i--) {
|
||||
attrClauses[i] = '(?:' +
|
||||
'(' + handler.customAttrSurround[i][0].source + ')\\s*' +
|
||||
pattern +
|
||||
'\\s*(' + handler.customAttrSurround[i][1].source + ')' +
|
||||
')';
|
||||
}
|
||||
attrClauses.push('(?:' + pattern + ')');
|
||||
pattern = '(?:' + attrClauses.join('|') + ')';
|
||||
}
|
||||
return new RegExp('^\\s*' + pattern);
|
||||
}
|
||||
|
||||
function joinSingleAttrAssigns(handler) {
|
||||
return singleAttrAssigns.concat(
|
||||
handler.customAttrAssign || []
|
||||
).map(function(assign) {
|
||||
return '(?:' + assign.source + ')';
|
||||
}).join('|');
|
||||
}
|
||||
|
||||
function HTMLParser(html, handler) {
|
||||
var stack = [], lastTag;
|
||||
var attribute = attrForHandler(handler);
|
||||
var last, prevTag, nextTag;
|
||||
while (html) {
|
||||
last = html;
|
||||
// Make sure we're not in a script or style element
|
||||
if (!lastTag || !special(lastTag)) {
|
||||
var textEnd = html.indexOf('<');
|
||||
if (textEnd === 0) {
|
||||
// Comment:
|
||||
if (/^<!--/.test(html)) {
|
||||
var commentEnd = html.indexOf('-->');
|
||||
|
||||
if (commentEnd >= 0) {
|
||||
if (handler.comment) {
|
||||
handler.comment(html.substring(4, commentEnd));
|
||||
}
|
||||
html = html.substring(commentEnd + 3);
|
||||
prevTag = '';
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
// http://en.wikipedia.org/wiki/Conditional_comment#Downlevel-revealed_conditional_comment
|
||||
if (/^<!\[/.test(html)) {
|
||||
var conditionalEnd = html.indexOf(']>');
|
||||
|
||||
if (conditionalEnd >= 0) {
|
||||
if (handler.comment) {
|
||||
handler.comment(html.substring(2, conditionalEnd + 1), true /* non-standard */);
|
||||
}
|
||||
html = html.substring(conditionalEnd + 2);
|
||||
prevTag = '';
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
// Doctype:
|
||||
var doctypeMatch = html.match(doctype);
|
||||
if (doctypeMatch) {
|
||||
if (handler.doctype) {
|
||||
handler.doctype(doctypeMatch[0]);
|
||||
}
|
||||
html = html.substring(doctypeMatch[0].length);
|
||||
prevTag = '';
|
||||
continue;
|
||||
}
|
||||
|
||||
// End tag:
|
||||
var endTagMatch = html.match(endTag);
|
||||
if (endTagMatch) {
|
||||
html = html.substring(endTagMatch[0].length);
|
||||
endTagMatch[0].replace(endTag, parseEndTag);
|
||||
prevTag = '/' + endTagMatch[1].toLowerCase();
|
||||
continue;
|
||||
}
|
||||
|
||||
// Start tag:
|
||||
var startTagMatch = parseStartTag(html);
|
||||
if (startTagMatch) {
|
||||
html = startTagMatch.rest;
|
||||
handleStartTag(startTagMatch);
|
||||
prevTag = startTagMatch.tagName.toLowerCase();
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
var text;
|
||||
if (textEnd >= 0) {
|
||||
text = html.substring(0, textEnd);
|
||||
html = html.substring(textEnd);
|
||||
}
|
||||
else {
|
||||
text = html;
|
||||
html = '';
|
||||
}
|
||||
|
||||
// next tag
|
||||
var nextTagMatch = parseStartTag(html);
|
||||
if (nextTagMatch) {
|
||||
nextTag = nextTagMatch.tagName;
|
||||
}
|
||||
else {
|
||||
nextTagMatch = html.match(endTag);
|
||||
if (nextTagMatch) {
|
||||
nextTag = '/' + nextTagMatch[1];
|
||||
}
|
||||
else {
|
||||
nextTag = '';
|
||||
}
|
||||
}
|
||||
|
||||
if (handler.chars) {
|
||||
handler.chars(text, prevTag, nextTag);
|
||||
}
|
||||
prevTag = '';
|
||||
|
||||
}
|
||||
else {
|
||||
var stackedTag = lastTag.toLowerCase();
|
||||
var reStackedTag = reCache[stackedTag] || (reCache[stackedTag] = new RegExp('([\\s\\S]*?)</' + stackedTag + '[^>]*>', 'i'));
|
||||
|
||||
html = html.replace(reStackedTag, function(all, text) {
|
||||
if (stackedTag !== 'script' && stackedTag !== 'style' && stackedTag !== 'noscript') {
|
||||
text = text
|
||||
.replace(/<!--([\s\S]*?)-->/g, '$1')
|
||||
.replace(/<!\[CDATA\[([\s\S]*?)]]>/g, '$1');
|
||||
}
|
||||
|
||||
if (handler.chars) {
|
||||
handler.chars(text);
|
||||
}
|
||||
|
||||
return '';
|
||||
});
|
||||
|
||||
parseEndTag('</' + stackedTag + '>', stackedTag);
|
||||
}
|
||||
|
||||
if (html === last) {
|
||||
throw new Error('Parse Error: ' + html);
|
||||
}
|
||||
}
|
||||
|
||||
if (!handler.partialMarkup) {
|
||||
// Clean up any remaining tags
|
||||
parseEndTag();
|
||||
}
|
||||
|
||||
function parseStartTag(input) {
|
||||
var start = input.match(startTagOpen);
|
||||
if (start) {
|
||||
var match = {
|
||||
tagName: start[1],
|
||||
attrs: []
|
||||
};
|
||||
input = input.slice(start[0].length);
|
||||
var end, attr;
|
||||
while (!(end = input.match(startTagClose)) && (attr = input.match(attribute))) {
|
||||
input = input.slice(attr[0].length);
|
||||
match.attrs.push(attr);
|
||||
}
|
||||
if (end) {
|
||||
match.unarySlash = end[1];
|
||||
match.rest = input.slice(end[0].length);
|
||||
return match;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function handleStartTag(match) {
|
||||
var tagName = match.tagName;
|
||||
var unarySlash = match.unarySlash;
|
||||
|
||||
if (handler.html5 && lastTag === 'p' && nonPhrasing(tagName)) {
|
||||
parseEndTag('', lastTag);
|
||||
}
|
||||
|
||||
if (!handler.html5 && !inline(tagName)) {
|
||||
while (lastTag && inline(lastTag)) {
|
||||
parseEndTag('', lastTag);
|
||||
}
|
||||
}
|
||||
|
||||
if (closeSelf(tagName) && lastTag === tagName) {
|
||||
parseEndTag('', tagName);
|
||||
}
|
||||
|
||||
var unary = empty(tagName) || tagName === 'html' && lastTag === 'head' || !!unarySlash;
|
||||
|
||||
var attrs = match.attrs.map(function(args) {
|
||||
var name, value, customOpen, customClose, customAssign, quote;
|
||||
var ncp = 7; // number of captured parts, scalar
|
||||
|
||||
// hackish work around FF bug https://bugzilla.mozilla.org/show_bug.cgi?id=369778
|
||||
if (IS_REGEX_CAPTURING_BROKEN && args[0].indexOf('""') === -1) {
|
||||
if (args[3] === '') { delete args[3]; }
|
||||
if (args[4] === '') { delete args[4]; }
|
||||
if (args[5] === '') { delete args[5]; }
|
||||
}
|
||||
|
||||
function populate(index) {
|
||||
customAssign = args[index];
|
||||
value = args[index + 1];
|
||||
if (typeof value !== 'undefined') {
|
||||
return '"';
|
||||
}
|
||||
value = args[index + 2];
|
||||
if (typeof value !== 'undefined') {
|
||||
return '\'';
|
||||
}
|
||||
value = args[index + 3];
|
||||
if (typeof value === 'undefined' && fillAttrs(name)) {
|
||||
value = name;
|
||||
}
|
||||
return '';
|
||||
}
|
||||
|
||||
var j = 1;
|
||||
if (handler.customAttrSurround) {
|
||||
for (var i = 0, l = handler.customAttrSurround.length; i < l; i++, j += ncp) {
|
||||
name = args[j + 1];
|
||||
if (name) {
|
||||
quote = populate(j + 2);
|
||||
customOpen = args[j];
|
||||
customClose = args[j + 6];
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!name && (name = args[j])) {
|
||||
quote = populate(j + 1);
|
||||
}
|
||||
|
||||
return {
|
||||
name: name,
|
||||
value: value,
|
||||
customAssign: customAssign || '=',
|
||||
customOpen: customOpen || '',
|
||||
customClose: customClose || '',
|
||||
quote: quote || ''
|
||||
};
|
||||
});
|
||||
|
||||
if (!unary) {
|
||||
stack.push({ tag: tagName, attrs: attrs });
|
||||
lastTag = tagName;
|
||||
unarySlash = '';
|
||||
}
|
||||
|
||||
if (handler.start) {
|
||||
handler.start(tagName, attrs, unary, unarySlash);
|
||||
}
|
||||
}
|
||||
|
||||
function parseEndTag(tag, tagName) {
|
||||
var pos;
|
||||
|
||||
// Find the closest opened tag of the same type
|
||||
if (tagName) {
|
||||
var needle = tagName.toLowerCase();
|
||||
for (pos = stack.length - 1; pos >= 0; pos--) {
|
||||
if (stack[pos].tag.toLowerCase() === needle) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
// If no tag name is provided, clean shop
|
||||
else {
|
||||
pos = 0;
|
||||
}
|
||||
|
||||
if (pos >= 0) {
|
||||
// Close all the open elements, up the stack
|
||||
for (var i = stack.length - 1; i >= pos; i--) {
|
||||
if (handler.end) {
|
||||
handler.end(stack[i].tag, stack[i].attrs, i > pos || !tag);
|
||||
}
|
||||
}
|
||||
|
||||
// Remove the open elements from the stack
|
||||
stack.length = pos;
|
||||
lastTag = pos && stack[pos - 1].tag;
|
||||
}
|
||||
else if (tagName.toLowerCase() === 'br') {
|
||||
if (handler.start) {
|
||||
handler.start(tagName, [], true, '');
|
||||
}
|
||||
}
|
||||
else if (tagName.toLowerCase() === 'p') {
|
||||
if (handler.start) {
|
||||
handler.start(tagName, [], false, '', true);
|
||||
}
|
||||
if (handler.end) {
|
||||
handler.end(tagName, []);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
exports.HTMLParser = HTMLParser;
|
||||
exports.HTMLtoXML = function(html) {
|
||||
var results = '';
|
||||
|
||||
new HTMLParser(html, {
|
||||
start: function(tag, attrs, unary) {
|
||||
results += '<' + tag;
|
||||
|
||||
for (var i = 0, len = attrs.length; i < len; i++) {
|
||||
results += ' ' + attrs[i].name + '="' + (attrs[i].value || '').replace(/"/g, '"') + '"';
|
||||
}
|
||||
|
||||
results += (unary ? '/' : '') + '>';
|
||||
},
|
||||
end: function(tag) {
|
||||
results += '</' + tag + '>';
|
||||
},
|
||||
chars: function(text) {
|
||||
results += text;
|
||||
},
|
||||
comment: function(text) {
|
||||
results += '<!--' + text + '-->';
|
||||
},
|
||||
ignore: function(text) {
|
||||
results += text;
|
||||
}
|
||||
});
|
||||
|
||||
return results;
|
||||
};
|
||||
|
||||
exports.HTMLtoDOM = function(html, doc) {
|
||||
// There can be only one of these elements
|
||||
var one = {
|
||||
html: true,
|
||||
head: true,
|
||||
body: true,
|
||||
title: true
|
||||
};
|
||||
|
||||
// Enforce a structure for the document
|
||||
var structure = {
|
||||
link: 'head',
|
||||
base: 'head'
|
||||
};
|
||||
|
||||
if (doc) {
|
||||
doc = doc.ownerDocument || doc.getOwnerDocument && doc.getOwnerDocument() || doc;
|
||||
}
|
||||
else if (typeof DOMDocument !== 'undefined') {
|
||||
doc = new DOMDocument();
|
||||
}
|
||||
else if (typeof document !== 'undefined' && document.implementation && document.implementation.createDocument) {
|
||||
doc = document.implementation.createDocument('', '', null);
|
||||
}
|
||||
else if (typeof ActiveX !== 'undefined') {
|
||||
doc = new ActiveXObject('Msxml.DOMDocument');
|
||||
}
|
||||
|
||||
var elems = [],
|
||||
documentElement = doc.documentElement ||
|
||||
doc.getDocumentElement && doc.getDocumentElement();
|
||||
|
||||
// If we're dealing with an empty document then we
|
||||
// need to pre-populate it with the HTML document structure
|
||||
if (!documentElement && doc.createElement) {
|
||||
(function() {
|
||||
var html = doc.createElement('html');
|
||||
var head = doc.createElement('head');
|
||||
head.appendChild(doc.createElement('title'));
|
||||
html.appendChild(head);
|
||||
html.appendChild(doc.createElement('body'));
|
||||
doc.appendChild(html);
|
||||
})();
|
||||
}
|
||||
|
||||
// Find all the unique elements
|
||||
if (doc.getElementsByTagName) {
|
||||
for (var i in one) {
|
||||
one[i] = doc.getElementsByTagName(i)[0];
|
||||
}
|
||||
}
|
||||
|
||||
// If we're working with a document, inject contents into
|
||||
// the body element
|
||||
var curParentNode = one.body;
|
||||
|
||||
new HTMLParser(html, {
|
||||
start: function(tagName, attrs, unary) {
|
||||
// If it's a pre-built element, then we can ignore
|
||||
// its construction
|
||||
if (one[tagName]) {
|
||||
curParentNode = one[tagName];
|
||||
return;
|
||||
}
|
||||
|
||||
var elem = doc.createElement(tagName);
|
||||
|
||||
for (var attr in attrs) {
|
||||
elem.setAttribute(attrs[attr].name, attrs[attr].value);
|
||||
}
|
||||
|
||||
if (structure[tagName] && typeof one[structure[tagName]] !== 'boolean') {
|
||||
one[structure[tagName]].appendChild(elem);
|
||||
}
|
||||
else if (curParentNode && curParentNode.appendChild) {
|
||||
curParentNode.appendChild(elem);
|
||||
}
|
||||
|
||||
if (!unary) {
|
||||
elems.push(elem);
|
||||
curParentNode = elem;
|
||||
}
|
||||
},
|
||||
end: function(/* tag */) {
|
||||
elems.length -= 1;
|
||||
|
||||
// Init the new parentNode
|
||||
curParentNode = elems[elems.length - 1];
|
||||
},
|
||||
chars: function(text) {
|
||||
curParentNode.appendChild(doc.createTextNode(text));
|
||||
},
|
||||
comment: function(/* text */) {
|
||||
// create comment node
|
||||
},
|
||||
ignore: function(/* text */) {
|
||||
// What to do here?
|
||||
}
|
||||
});
|
||||
|
||||
return doc;
|
||||
};
|
||||
71
build/node_modules/html-minifier/src/tokenchain.js
generated
vendored
Normal file
71
build/node_modules/html-minifier/src/tokenchain.js
generated
vendored
Normal file
@@ -0,0 +1,71 @@
|
||||
'use strict';
|
||||
|
||||
function Sorter() {
|
||||
}
|
||||
|
||||
Sorter.prototype.sort = function(tokens, fromIndex) {
|
||||
fromIndex = fromIndex || 0;
|
||||
for (var i = 0, len = this.keys.length; i < len; i++) {
|
||||
var key = this.keys[i];
|
||||
var token = key.slice(1);
|
||||
var index = tokens.indexOf(token, fromIndex);
|
||||
if (index !== -1) {
|
||||
do {
|
||||
if (index !== fromIndex) {
|
||||
tokens.splice(index, 1);
|
||||
tokens.splice(fromIndex, 0, token);
|
||||
}
|
||||
fromIndex++;
|
||||
} while ((index = tokens.indexOf(token, fromIndex)) !== -1);
|
||||
return this[key].sort(tokens, fromIndex);
|
||||
}
|
||||
}
|
||||
return tokens;
|
||||
};
|
||||
|
||||
function TokenChain() {
|
||||
}
|
||||
|
||||
TokenChain.prototype = {
|
||||
add: function(tokens) {
|
||||
var self = this;
|
||||
tokens.forEach(function(token) {
|
||||
var key = '$' + token;
|
||||
if (!self[key]) {
|
||||
self[key] = [];
|
||||
self[key].processed = 0;
|
||||
}
|
||||
self[key].push(tokens);
|
||||
});
|
||||
},
|
||||
createSorter: function() {
|
||||
var self = this;
|
||||
var sorter = new Sorter();
|
||||
sorter.keys = Object.keys(self).sort(function(j, k) {
|
||||
var m = self[j].length;
|
||||
var n = self[k].length;
|
||||
return m < n ? 1 : m > n ? -1 : j < k ? -1 : j > k ? 1 : 0;
|
||||
}).filter(function(key) {
|
||||
if (self[key].processed < self[key].length) {
|
||||
var token = key.slice(1);
|
||||
var chain = new TokenChain();
|
||||
self[key].forEach(function(tokens) {
|
||||
var index;
|
||||
while ((index = tokens.indexOf(token)) !== -1) {
|
||||
tokens.splice(index, 1);
|
||||
}
|
||||
tokens.forEach(function(token) {
|
||||
self['$' + token].processed++;
|
||||
});
|
||||
chain.add(tokens.slice(0));
|
||||
});
|
||||
sorter[key] = chain.createSorter();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
});
|
||||
return sorter;
|
||||
}
|
||||
};
|
||||
|
||||
module.exports = TokenChain;
|
||||
18
build/node_modules/html-minifier/src/utils.js
generated
vendored
Normal file
18
build/node_modules/html-minifier/src/utils.js
generated
vendored
Normal file
@@ -0,0 +1,18 @@
|
||||
'use strict';
|
||||
|
||||
function createMap(values, ignoreCase) {
|
||||
var map = {};
|
||||
values.forEach(function(value) {
|
||||
map[value] = 1;
|
||||
});
|
||||
return ignoreCase ? function(value) {
|
||||
return map[value.toLowerCase()] === 1;
|
||||
} : function(value) {
|
||||
return map[value] === 1;
|
||||
};
|
||||
}
|
||||
|
||||
exports.createMap = createMap;
|
||||
exports.createMapFromString = function(values, ignoreCase) {
|
||||
return createMap(values.split(/,/), ignoreCase);
|
||||
};
|
||||
Reference in New Issue
Block a user