html-minifier 0.6.8 → 0.7.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +22 -9
- package/LICENSE +1 -1
- package/README.md +22 -14
- package/cli.js +74 -87
- package/dist/htmlminifier.js +164 -64
- package/dist/htmlminifier.min.js +3 -3
- package/package.json +11 -9
package/CHANGELOG.md
CHANGED
|
@@ -1,10 +1,23 @@
|
|
|
1
|
-
## [0.
|
|
1
|
+
## [0.7.0](https://github.com/kangax/html-minifier/compare/v0.6.9...v0.7.0)
|
|
2
|
+
|
|
3
|
+
* TODO
|
|
4
|
+
|
|
5
|
+
## [0.6.9](https://github.com/kangax/html-minifier/compare/v0.6.8...v0.6.9)
|
|
6
|
+
|
|
7
|
+
* TODO
|
|
8
|
+
|
|
9
|
+
## [0.6.8](https://github.com/kangax/html-minifier/compare/v0.6.7...v0.6.8)
|
|
10
|
+
|
|
11
|
+
* TODO
|
|
12
|
+
|
|
13
|
+
## [0.6.7](https://github.com/kangax/html-minifier/compare/v0.6.6...v0.6.7)
|
|
2
14
|
|
|
3
15
|
* Preserve empty script with `src` attribute
|
|
4
16
|
* Make `draggable` enumerated attribute
|
|
5
17
|
* Add option to preserve a single line break on collapse
|
|
6
18
|
* Do not treat draggable as a boolean attribute
|
|
7
|
-
* Add
|
|
19
|
+
* Add `minifyURLs` option
|
|
20
|
+
* Add `customAttrCollapse` option
|
|
8
21
|
* `collapseBoolean` is case-insensitive
|
|
9
22
|
* Remove removable attrs with unspecified values
|
|
10
23
|
* `removeComments` affects htmlmin:ignore comments
|
|
@@ -13,40 +26,40 @@
|
|
|
13
26
|
* `s` tag has been reinstated
|
|
14
27
|
* Remove `i`, `b`, `u` tags from linter as problematic
|
|
15
28
|
|
|
16
|
-
## [0.6.6](https://github.com/kangax/html-minifier/compare/v0.6.5...
|
|
29
|
+
## [0.6.6](https://github.com/kangax/html-minifier/compare/v0.6.5...v0.6.6)
|
|
17
30
|
|
|
18
31
|
* Fix Firefox attribute bug
|
|
19
32
|
* Add `customAttrAssign` option
|
|
20
33
|
* Add `maxLineLength` option
|
|
21
34
|
* Add `customAttrSurround` option
|
|
22
35
|
|
|
23
|
-
## [0.6.5](https://github.com/kangax/html-minifier/compare/v0.6.4...
|
|
36
|
+
## [0.6.5](https://github.com/kangax/html-minifier/compare/v0.6.4...v0.6.5)
|
|
24
37
|
|
|
25
38
|
* `caseSensitive` option now applies to tags and attributes
|
|
26
39
|
|
|
27
|
-
## [0.6.4](https://github.com/kangax/html-minifier/compare/v0.6.3...
|
|
40
|
+
## [0.6.4](https://github.com/kangax/html-minifier/compare/v0.6.3...v0.6.4)
|
|
28
41
|
|
|
29
42
|
* Support for mixed-case tags
|
|
30
43
|
* Support IE downlevel-revealed conditional comments
|
|
31
44
|
* Add support for `wbr` element
|
|
32
45
|
|
|
33
|
-
## [0.6.3](https://github.com/kangax/html-minifier/compare/v0.6.2...
|
|
46
|
+
## [0.6.3](https://github.com/kangax/html-minifier/compare/v0.6.2...v0.6.3)
|
|
34
47
|
|
|
35
48
|
* Do not treat `translate` attribute as boolean
|
|
36
49
|
* Add `svg` element in inline list
|
|
37
50
|
* Do not remove special spaces like ` `
|
|
38
51
|
* Make `collapseWhitespace` more resilient
|
|
39
52
|
|
|
40
|
-
## [0.6.2](https://github.com/kangax/html-minifier/compare/v0.6.1...
|
|
53
|
+
## [0.6.2](https://github.com/kangax/html-minifier/compare/v0.6.1...v0.6.2)
|
|
41
54
|
|
|
42
55
|
* Fix bug introduced by `processScripts` option
|
|
43
56
|
|
|
44
|
-
## [0.6.1](https://github.com/kangax/html-minifier/compare/v0.6.0...
|
|
57
|
+
## [0.6.1](https://github.com/kangax/html-minifier/compare/v0.6.0...v0.6.1)
|
|
45
58
|
|
|
46
59
|
* Add CLI
|
|
47
60
|
* Fix error with valueless attributes (e.g. `<a href>`). [#169](https://github.com/kangax/html-minifier/issues/169)
|
|
48
61
|
|
|
49
|
-
## [0.6.0](https://github.com/kangax/html-minifier/compare/v0.5.6...
|
|
62
|
+
## [0.6.0](https://github.com/kangax/html-minifier/compare/v0.5.6...v0.6.0)
|
|
50
63
|
|
|
51
64
|
* Minify meta viewport value [#159](https://github.com/kangax/html-minifier/issues/159)
|
|
52
65
|
* Add support for ignoring markup via `<!-- htmlmin:ignore -->` [#89](https://github.com/kangax/html-minifier/issues/89)
|
package/LICENSE
CHANGED
package/README.md
CHANGED
|
@@ -1,25 +1,25 @@
|
|
|
1
|
-
[](https://www.npmjs.com/package/html-minifier)
|
|
2
|
+
[](https://travis-ci.org/kangax/html-minifier)
|
|
3
|
+
[](https://david-dm.org/kangax/html-minifier)
|
|
4
|
+
[](https://david-dm.org/kangax/html-minifier#info=devDependencies)
|
|
5
5
|
|
|
6
|
-
[HTMLMinifier](http://kangax.github.io/html-minifier/) is a highly
|
|
6
|
+
[HTMLMinifier](http://kangax.github.io/html-minifier/) is a highly **configurable**, **well-tested**, Javascript-based HTML minifier, with lint-like capabilities.
|
|
7
7
|
|
|
8
8
|
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).
|
|
9
9
|
|
|
10
10
|
[Test suite is available online](http://kangax.github.io/html-minifier/tests/).
|
|
11
11
|
|
|
12
|
-
Also see corresponding [Ruby wrapper](https://github.com/stereobooster/html_minifier), and for Node.js, [Grunt plugin](https://github.com/gruntjs/grunt-contrib-htmlmin)
|
|
12
|
+
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), and [Koa middleware wrapper](https://github.com/koajs/html-minifier).
|
|
13
13
|
|
|
14
14
|
How does HTMLMinifier compare to [another solution](http://www.willpeavy.com/minifier/) — HTML Minifier from Will Peavy (1st result in [google search for "html minifier"](https://www.google.com/#q=html+minifier)) as well as htmlcompressor.com?
|
|
15
15
|
|
|
16
|
-
| Site
|
|
16
|
+
| Site | Original size _(KB)_ | HTMLMinifier _(KB)_ | Will Peavy _(KB)_ | htmlcompressor.com _(KB)_ |
|
|
17
17
|
| --------------------------------------------------------------------------- |:-----------:| ----------------:| ------------:| ----------------:|
|
|
18
18
|
| [HTMLMinifier page](https://github.com/kangax/html-minifier) | 48.8 | <b>37.3</b> | 43.3 | 41.9 |
|
|
19
19
|
| [ES6 table](http://kangax.github.io/es5-compat-table/es6/) | 117.9 | <b>79.9</b> | 92 | 91.9 |
|
|
20
20
|
| [MSN](http://msn.com) | 156.6 | <b>133</b> | 145 | 138.3 |
|
|
21
21
|
| [Stackoverflow](http://stackoverflow.com) | 200.4 | <b>159.5</b> | 168.3 | 163.3 |
|
|
22
|
-
| [Amazon](http://amazon.com) | 245.9 | <b>206.3</b> | 225 |
|
|
22
|
+
| [Amazon](http://amazon.com) | 245.9 | <b>206.3</b> | 225 | 218.5 |
|
|
23
23
|
| [Wikipedia](http://en.wikipedia.org/wiki/President_of_the_United_States) | 401.4 | <b>380.6</b> | 396.3 | n/a |
|
|
24
24
|
| [Eloquent Javascript](http://eloquentjavascript.net/print.html) | 869.5 | <b>830</b> | 872 | n/a |
|
|
25
25
|
|
|
@@ -34,10 +34,11 @@ How does HTMLMinifier compare to [another solution](http://www.willpeavy.com/min
|
|
|
34
34
|
| `removeCDATASectionsFromCDATA` | [Remove CDATA sections from script and style elements](http://perfectionkills.com/experimenting-with-html-minifier/#remove_cdata_sections) | `false` |
|
|
35
35
|
| `collapseWhitespace` | [Collapse white space that contributes to text nodes in a document tree.](http://perfectionkills.com/experimenting-with-html-minifier/#collapse_whitespace) | `false` |
|
|
36
36
|
| `conservativeCollapse` | Always collapse to 1 space (never remove it entirely). Must be used in conjunction with `collapseWhitespace=true` | `false` |
|
|
37
|
-
| `preserveLineBreaks`
|
|
37
|
+
| `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` |
|
|
38
38
|
| `collapseBooleanAttributes` | [Omit attribute values from boolean attributes](http://perfectionkills.com/experimenting-with-html-minifier/#collapse_boolean_attributes) | `false` |
|
|
39
39
|
| `removeAttributeQuotes` | [Remove quotes around attributes when possible.](http://perfectionkills.com/experimenting-with-html-minifier/#remove_attribute_quotes) | `false` |
|
|
40
40
|
| `removeRedundantAttributes` | [Remove attributes when value matches default.](http://perfectionkills.com/experimenting-with-html-minifier/#remove_redundant_attributes) | `false` |
|
|
41
|
+
| `preventAttributesEscaping` | Prevents the escaping of the values of attributes. | `false` |
|
|
41
42
|
| `useShortDoctype` | [Replaces the doctype with the short (HTML5) doctype](http://perfectionkills.com/experimenting-with-html-minifier/#use_short_doctype) | `false` |
|
|
42
43
|
| `removeEmptyAttributes` | [Remove all attributes with whitespace-only values](http://perfectionkills.com/experimenting-with-html-minifier/#remove_empty_or_blank_attributes) | `false` |
|
|
43
44
|
| `removeScriptTypeAttributes` | Remove `type="text/javascript"` from `script` tags. Other `type` attribute values are left intact. | `false` |
|
|
@@ -47,7 +48,7 @@ How does HTMLMinifier compare to [another solution](http://www.willpeavy.com/min
|
|
|
47
48
|
| `removeEmptyElements` | [Remove all elements with empty contents](http://perfectionkills.com/experimenting-with-html-minifier/#remove_empty_elements) | `false` |
|
|
48
49
|
| `lint` | [Toggle linting](http://perfectionkills.com/experimenting-with-html-minifier/#validate_input_through_html_lint) | `false` |
|
|
49
50
|
| `keepClosingSlash` | Keep the trailing slash on singleton elements | `false` |
|
|
50
|
-
| `caseSensitive` | Treat attributes in case sensitive manner (useful for
|
|
51
|
+
| `caseSensitive` | Treat attributes in case sensitive manner (useful for custom HTML tags.) | `false` |
|
|
51
52
|
| `minifyJS` | Minify Javascript in script elements and on* attributes (uses [UglifyJS](https://github.com/mishoo/UglifyJS2)) | `false` (could be `true`, `false`, `Object` (options)) |
|
|
52
53
|
| `minifyCSS` | Minify CSS in style elements and style attributes (uses [clean-css](https://github.com/GoalSmashers/clean-css)) | `false` (could be `true`, `false`, `Object` (options)) |
|
|
53
54
|
| `minifyURLs` | Minify URLs in various attributes (uses [relateurl](https://github.com/stevenvachon/relateurl)) | `false` (could be `Object` (options)) |
|
|
@@ -58,8 +59,15 @@ How does HTMLMinifier compare to [another solution](http://www.willpeavy.com/min
|
|
|
58
59
|
| `customAttrSurround` | Arrays of regex'es that allow to support custom attribute surround expressions (e.g. `<input {{#if value}}checked="checked"{{/if}}>`) | `[ ]` |
|
|
59
60
|
| `customAttrCollapse` | Regex that specifies custom attribute to strip newlines from (e.g. `/ng\-class/`) | |
|
|
60
61
|
|
|
62
|
+
## Special cases
|
|
61
63
|
|
|
62
|
-
|
|
64
|
+
### Ignoring chunks of markup.
|
|
65
|
+
|
|
66
|
+
If you have chunks of markup you would like preserved, you can wrap them `<!-- htmlmin:ignore -->`.
|
|
67
|
+
|
|
68
|
+
### Preserving SVG tags
|
|
69
|
+
|
|
70
|
+
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.
|
|
63
71
|
|
|
64
72
|
## Installation Instructions
|
|
65
73
|
|
|
@@ -84,7 +92,7 @@ npm link .
|
|
|
84
92
|
|
|
85
93
|
For command line usage please see `html-minifier --help`
|
|
86
94
|
|
|
87
|
-
|
|
95
|
+
### Node.js
|
|
88
96
|
|
|
89
97
|
```js
|
|
90
98
|
var minify = require('html-minifier').minify;
|
|
@@ -94,8 +102,8 @@ var result = minify('<p title="blah" id="moo">foo</p>', {
|
|
|
94
102
|
result; // '<p title=blah id=moo>foo</p>'
|
|
95
103
|
```
|
|
96
104
|
|
|
97
|
-
Running benchmarks
|
|
98
|
-
|
|
105
|
+
## Running benchmarks
|
|
106
|
+
|
|
99
107
|
Benchmarks for minified HTML:
|
|
100
108
|
```
|
|
101
109
|
node benchmark.js
|
package/cli.js
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
*
|
|
5
5
|
* The MIT License (MIT)
|
|
6
6
|
*
|
|
7
|
-
* Copyright (c) 2014 Zoltan Frombach
|
|
7
|
+
* Copyright (c) 2014-2015 Zoltan Frombach
|
|
8
8
|
*
|
|
9
9
|
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
|
10
10
|
* this software and associated documentation files (the "Software"), to deal in
|
|
@@ -25,15 +25,19 @@
|
|
|
25
25
|
*
|
|
26
26
|
*/
|
|
27
27
|
|
|
28
|
+
/* globals JSON:true */
|
|
29
|
+
|
|
28
30
|
'use strict';
|
|
29
31
|
|
|
30
32
|
var cli = require('cli');
|
|
33
|
+
var concat = require('concat-stream');
|
|
31
34
|
var changeCase = require('change-case');
|
|
32
35
|
var path = require('path');
|
|
33
36
|
var fs = require('fs');
|
|
34
37
|
var appName = require('./package.json').name;
|
|
35
38
|
var appVersion = require('./package.json').version;
|
|
36
39
|
var minify = require('./dist/htmlminifier.min.js').minify;
|
|
40
|
+
var HTMLLint = require('./dist/htmlminifier.min.js').HTMLLint;
|
|
37
41
|
var minifyOptions = {};
|
|
38
42
|
var input = null;
|
|
39
43
|
var output = null;
|
|
@@ -58,12 +62,17 @@ var mainOptions = {
|
|
|
58
62
|
removeCDATASectionsFromCDATA: [[false, 'Remove CDATA sections from script and style elements']],
|
|
59
63
|
collapseWhitespace: [[false, 'Collapse white space that contributes to text nodes in a document tree.']],
|
|
60
64
|
conservativeCollapse: [[false, 'Always collapse to 1 space (never remove it entirely)']],
|
|
65
|
+
preserveLineBreaks: [[false, 'Always collapse to 1 line break (never remove it entirely) when whitespace between tags include a line break.']],
|
|
61
66
|
collapseBooleanAttributes: [[false, 'Omit attribute values from boolean attributes']],
|
|
62
67
|
removeAttributeQuotes: [[false, 'Remove quotes around attributes when possible.']],
|
|
63
68
|
removeRedundantAttributes: [[false, 'Remove attributes when value matches default.']],
|
|
69
|
+
preventAttributesEscaping: [[false, 'Prevents the escaping of the values of attributes.']],
|
|
64
70
|
useShortDoctype: [[false, 'Replaces the doctype with the short (HTML5) doctype']],
|
|
65
71
|
removeEmptyAttributes: [[false, 'Remove all attributes with whitespace-only values']],
|
|
72
|
+
removeScriptTypeAttributes: [[false, 'Remove type="text/javascript" from script tags. Other type attribute values are left intact.']],
|
|
73
|
+
removeStyleLinkTypeAttributes: [[false, 'Remove type="text/css" from style and link tags. Other type attribute values are left intact.']],
|
|
66
74
|
removeOptionalTags: [[false, 'Remove unrequired tags']],
|
|
75
|
+
removeIgnored: [[false, 'Remove all tags starting and ending with <%, %>, <?, ?>']],
|
|
67
76
|
removeEmptyElements: [[false, 'Remove all elements with empty contents']],
|
|
68
77
|
lint: [[false, 'Toggle linting']],
|
|
69
78
|
keepClosingSlash: [[false, 'Keep the trailing slash on singleton elements']],
|
|
@@ -73,7 +82,10 @@ var mainOptions = {
|
|
|
73
82
|
minifyURLs: [[false, 'Minify URLs in various attributes (uses relateurl)']],
|
|
74
83
|
ignoreCustomComments: [[false, 'Array of regex\'es that allow to ignore certain comments, when matched', 'string'], 'json'],
|
|
75
84
|
processScripts: [[false, 'Array of strings corresponding to types of script elements to process through minifier (e.g. "text/ng-template", "text/x-handlebars-template", etc.)', 'string'], 'json'],
|
|
76
|
-
maxLineLength: [[false, 'Max line length', 'number'], true]
|
|
85
|
+
maxLineLength: [[false, 'Max line length', 'number'], true],
|
|
86
|
+
customAttrAssign: [[false, 'Arrays of regex\'es that allow to support custom attribute assign expressions (e.g. \'<div flex?="{{mode != cover}}"></div>\')', 'string'], 'json'],
|
|
87
|
+
customAttrSurround: [[false, 'Arrays of regex\'es that allow to support custom attribute surround expressions (e.g. <input {{#if value}}checked="checked"{{/if}}>)', 'string'], 'json'],
|
|
88
|
+
customAttrCollapse: [[false, 'Regex that specifies custom attribute to strip newlines from (e.g. /ng\-class/)', 'string'], true]
|
|
77
89
|
};
|
|
78
90
|
|
|
79
91
|
var cliOptions = {
|
|
@@ -91,6 +103,56 @@ cli.parse(cliOptions);
|
|
|
91
103
|
|
|
92
104
|
cli.main(function(args, options) {
|
|
93
105
|
|
|
106
|
+
function parseJSONOption(value) {
|
|
107
|
+
if (value !== null) {
|
|
108
|
+
var jsonArray;
|
|
109
|
+
try {
|
|
110
|
+
jsonArray = JSON.parse(value);
|
|
111
|
+
}
|
|
112
|
+
catch (e) {}
|
|
113
|
+
if (jsonArray instanceof Array) {
|
|
114
|
+
return jsonArray;
|
|
115
|
+
}
|
|
116
|
+
else {
|
|
117
|
+
return [value];
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
function runMinify(original) {
|
|
123
|
+
var status = 0;
|
|
124
|
+
var minified = null;
|
|
125
|
+
try {
|
|
126
|
+
minified = minify(original, minifyOptions);
|
|
127
|
+
}
|
|
128
|
+
catch (e) {
|
|
129
|
+
status = 3;
|
|
130
|
+
process.stderr.write('Error: Minification error');
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
if (minifyOptions.lint) {
|
|
134
|
+
minifyOptions.lint.populate();
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
if (minified !== null) {
|
|
138
|
+
// Write the output
|
|
139
|
+
try {
|
|
140
|
+
if (output !== null) {
|
|
141
|
+
fs.writeFileSync(path.resolve(output), minified);
|
|
142
|
+
}
|
|
143
|
+
else {
|
|
144
|
+
process.stdout.write(minified);
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
catch (e) {
|
|
148
|
+
status = 4;
|
|
149
|
+
process.stderr.write('Error: Cannot write to output');
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
cli.exit(status);
|
|
154
|
+
}
|
|
155
|
+
|
|
94
156
|
if (options.version) {
|
|
95
157
|
process.stderr.write(appName + ' v' + appVersion);
|
|
96
158
|
cli.exit(0);
|
|
@@ -126,6 +188,10 @@ cli.main(function(args, options) {
|
|
|
126
188
|
}
|
|
127
189
|
});
|
|
128
190
|
|
|
191
|
+
if (minifyOptions.lint === true) {
|
|
192
|
+
minifyOptions.lint = new HTMLLint();
|
|
193
|
+
}
|
|
194
|
+
|
|
129
195
|
if (args.length) {
|
|
130
196
|
input = args;
|
|
131
197
|
}
|
|
@@ -134,104 +200,25 @@ cli.main(function(args, options) {
|
|
|
134
200
|
output = options.output;
|
|
135
201
|
}
|
|
136
202
|
|
|
137
|
-
var original = '';
|
|
138
|
-
var status = 0;
|
|
139
|
-
|
|
140
203
|
if (input !== null) { // Minifying one or more files specified on the CMD line
|
|
141
204
|
|
|
205
|
+
var original = '';
|
|
206
|
+
|
|
142
207
|
input.forEach(function(afile) {
|
|
143
208
|
try {
|
|
144
209
|
original += fs.readFileSync(afile, 'utf8');
|
|
145
210
|
}
|
|
146
211
|
catch (e) {
|
|
147
|
-
status = 2;
|
|
148
212
|
process.stderr.write('Error: Cannot read file ' + afile);
|
|
213
|
+
cli.exit(2);
|
|
149
214
|
}
|
|
150
215
|
});
|
|
151
216
|
|
|
152
|
-
|
|
153
|
-
else { // Minifying input coming from STDIN
|
|
154
|
-
|
|
155
|
-
var BUFSIZE = 4096;
|
|
156
|
-
var buf = new Buffer(BUFSIZE);
|
|
157
|
-
var bytesRead;
|
|
158
|
-
|
|
159
|
-
while (true) { // Loop as long as stdin input is available.
|
|
160
|
-
bytesRead = 0;
|
|
161
|
-
try {
|
|
162
|
-
bytesRead = fs.readSync(process.stdin.fd, buf, 0, BUFSIZE);
|
|
163
|
-
}
|
|
164
|
-
catch (e) {
|
|
165
|
-
if (e.code === 'EAGAIN') { // 'resource temporarily unavailable'
|
|
166
|
-
// Happens on OS X 10.8.3 (not Windows 7!), if there's no
|
|
167
|
-
// stdin input - typically when invoking a script without any
|
|
168
|
-
// input (for interactive stdin input).
|
|
169
|
-
// If you were to just continue, you'd create a tight loop.
|
|
170
|
-
process.stderr.write('ERROR: interactive stdin input not supported');
|
|
171
|
-
cli.exit(2);
|
|
172
|
-
}
|
|
173
|
-
else if (e.code === 'EOF') {
|
|
174
|
-
// Happens on Windows 7, but not OS X 10.8.3:
|
|
175
|
-
// simply signals the end of *piped* stdin input.
|
|
176
|
-
break;
|
|
177
|
-
}
|
|
178
|
-
throw e; // unexpected exception
|
|
179
|
-
}
|
|
180
|
-
if (bytesRead === 0) {
|
|
181
|
-
// No more stdin input available.
|
|
182
|
-
// OS X 10.8.3: regardless of input method, this is how the end
|
|
183
|
-
// of input is signaled.
|
|
184
|
-
// Windows 7: this is how the end of input is signaled for
|
|
185
|
-
// *interactive* stdin input.
|
|
186
|
-
break;
|
|
187
|
-
}
|
|
188
|
-
original += buf.toString('utf8', 0, bytesRead);
|
|
189
|
-
}
|
|
190
|
-
|
|
191
|
-
}
|
|
192
|
-
|
|
193
|
-
function parseJSONOption(value) {
|
|
194
|
-
if (value !== null) {
|
|
195
|
-
var jsonArray;
|
|
196
|
-
try {
|
|
197
|
-
jsonArray = JSON.parse(value);
|
|
198
|
-
}
|
|
199
|
-
catch (e) {}
|
|
200
|
-
if (jsonArray instanceof Array) {
|
|
201
|
-
return jsonArray;
|
|
202
|
-
}
|
|
203
|
-
else {
|
|
204
|
-
return [value];
|
|
205
|
-
}
|
|
206
|
-
}
|
|
207
|
-
}
|
|
217
|
+
runMinify(original);
|
|
208
218
|
|
|
209
|
-
// Run minify
|
|
210
|
-
var minified = null;
|
|
211
|
-
try {
|
|
212
|
-
minified = minify(original, minifyOptions);
|
|
213
|
-
}
|
|
214
|
-
catch (e) {
|
|
215
|
-
status = 3;
|
|
216
|
-
process.stderr.write('Error: Minification error');
|
|
217
219
|
}
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
// Write the output
|
|
221
|
-
try {
|
|
222
|
-
if (output !== null) {
|
|
223
|
-
fs.writeFileSync(path.resolve(output), minified);
|
|
224
|
-
}
|
|
225
|
-
else {
|
|
226
|
-
process.stdout.write(minified);
|
|
227
|
-
}
|
|
228
|
-
}
|
|
229
|
-
catch (e) {
|
|
230
|
-
status = 4;
|
|
231
|
-
process.stderr.write('Error: Cannot write to output');
|
|
232
|
-
}
|
|
220
|
+
else { // Minifying input coming from STDIN
|
|
221
|
+
process.stdin.pipe(concat({ encoding: 'string' }, runMinify));
|
|
233
222
|
}
|
|
234
223
|
|
|
235
|
-
cli.exit(status);
|
|
236
|
-
|
|
237
224
|
});
|
package/dist/htmlminifier.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/*!
|
|
2
|
-
* HTMLMinifier v0.
|
|
3
|
-
* Copyright 2010-
|
|
2
|
+
* HTMLMinifier v0.7.2 (http://kangax.github.io/html-minifier/)
|
|
3
|
+
* Copyright 2010-2015 Juriy "kangax" Zaytsev
|
|
4
4
|
* Licensed under MIT (https://github.com/kangax/html-minifier/blob/gh-pages/LICENSE)
|
|
5
5
|
*/
|
|
6
6
|
/*!
|
|
@@ -37,7 +37,7 @@
|
|
|
37
37
|
'use strict';
|
|
38
38
|
|
|
39
39
|
// Regular Expressions for parsing tags and attributes
|
|
40
|
-
var singleAttrIdentifier = /([\w
|
|
40
|
+
var singleAttrIdentifier = /([\w:\.-]+)/,
|
|
41
41
|
singleAttrAssign = /=/,
|
|
42
42
|
singleAttrAssigns = [ singleAttrAssign ],
|
|
43
43
|
singleAttrValues = [
|
|
@@ -49,9 +49,7 @@
|
|
|
49
49
|
startTagClose = /\s*(\/?)>/,
|
|
50
50
|
endTag = /^<\/([\w:-]+)[^>]*>/,
|
|
51
51
|
endingSlash = /\/>$/,
|
|
52
|
-
doctype = /^<!DOCTYPE [^>]+>/i
|
|
53
|
-
startIgnore = /<(%|\?)/,
|
|
54
|
-
endIgnore = /(%|\?)>/;
|
|
52
|
+
doctype = /^<!DOCTYPE [^>]+>/i;
|
|
55
53
|
|
|
56
54
|
var IS_REGEX_CAPTURING_BROKEN = false;
|
|
57
55
|
'x'.replace(/x(.)?/g, function(m, g) {
|
|
@@ -83,7 +81,7 @@
|
|
|
83
81
|
var customStartTagAttrs;
|
|
84
82
|
|
|
85
83
|
var startTagAttrs = new RegExp(
|
|
86
|
-
'(?:\\s*[\\w
|
|
84
|
+
'(?:\\s*[\\w:\\.-]+'
|
|
87
85
|
+ '(?:\\s*'
|
|
88
86
|
+ '(?:' + joinSingleAttrAssigns(handler) + ')'
|
|
89
87
|
+ '\\s*(?:(?:"[^"]*")|(?:\'[^\']*\')|[^>\\s]+)'
|
|
@@ -197,13 +195,23 @@
|
|
|
197
195
|
}
|
|
198
196
|
|
|
199
197
|
// Ignored elements?
|
|
200
|
-
else if (
|
|
201
|
-
index = html.
|
|
202
|
-
if (index >= 0) {
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
198
|
+
else if ( /^<\?/.test( html ) ) {
|
|
199
|
+
index = html.indexOf( '?>', 2 );
|
|
200
|
+
if ( index >= 0 ) {
|
|
201
|
+
if ( handler.chars ) {
|
|
202
|
+
handler.chars( html.substring( 0, index + 2 ) );
|
|
203
|
+
}
|
|
204
|
+
html = html.substring( index + 2 );
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
else if ( /^<%/.test( html ) ) {
|
|
209
|
+
index = html.indexOf( '%>', 2 );
|
|
210
|
+
if ( index >= 0 ) {
|
|
211
|
+
if ( handler.chars ) {
|
|
212
|
+
handler.chars(html.substring( 0, index + 2) );
|
|
213
|
+
}
|
|
214
|
+
html = html.substring( index + 2 );
|
|
207
215
|
}
|
|
208
216
|
}
|
|
209
217
|
|
|
@@ -227,8 +235,8 @@
|
|
|
227
235
|
chars = false;
|
|
228
236
|
}
|
|
229
237
|
|
|
230
|
-
// Start tag:
|
|
231
238
|
}
|
|
239
|
+
// Start tag:
|
|
232
240
|
else if ( /^</.test( html ) ) {
|
|
233
241
|
match = html.match( startTag );
|
|
234
242
|
if ( match ) {
|
|
@@ -314,7 +322,7 @@
|
|
|
314
322
|
var attrs = [];
|
|
315
323
|
|
|
316
324
|
rest.replace(attr, function () {
|
|
317
|
-
var name, value, fallbackValue, customOpen, customClose, customAssign;
|
|
325
|
+
var name, value, fallbackValue, customOpen, customClose, customAssign, quote;
|
|
318
326
|
var ncp = 7; // number of captured parts, scalar
|
|
319
327
|
|
|
320
328
|
// hackish work around FF bug https://bugzilla.mozilla.org/show_bug.cgi?id=369778
|
|
@@ -329,6 +337,12 @@
|
|
|
329
337
|
customAssign = arguments[2];
|
|
330
338
|
fallbackValue = arguments[3];
|
|
331
339
|
value = fallbackValue || arguments[4] || arguments[5];
|
|
340
|
+
|
|
341
|
+
if (customAssign) {
|
|
342
|
+
quote = arguments[0].charAt(name.length + customAssign.length);
|
|
343
|
+
quote = (quote === '\'' || quote === '"') ? quote : '';
|
|
344
|
+
}
|
|
345
|
+
|
|
332
346
|
}
|
|
333
347
|
else if ( handler.customAttrSurround ) {
|
|
334
348
|
for ( var i = handler.customAttrSurround.length - 1; i >= 0; i-- ) {
|
|
@@ -353,10 +367,13 @@
|
|
|
353
367
|
attrs.push({
|
|
354
368
|
name: name,
|
|
355
369
|
value: value,
|
|
356
|
-
escaped: value && value.replace(/(
|
|
370
|
+
escaped: value && value.replace(/(^|.)("+)/g, function(match) {
|
|
371
|
+
return match.replace(/"/g, '"');
|
|
372
|
+
}),
|
|
357
373
|
customAssign: customAssign || '=',
|
|
358
374
|
customOpen: customOpen || '',
|
|
359
|
-
customClose: customClose || ''
|
|
375
|
+
customClose: customClose || '',
|
|
376
|
+
quote: quote || ''
|
|
360
377
|
});
|
|
361
378
|
});
|
|
362
379
|
|
|
@@ -602,15 +619,15 @@
|
|
|
602
619
|
lineBreakAfter = /[\t\n\r ]*[\n\r]+[\t ]*$/,
|
|
603
620
|
preserveBefore = lineBreakBefore.test(str) ? '\n' : ' ',
|
|
604
621
|
preserveAfter = lineBreakAfter.test(str) ? '\n' : ' ',
|
|
605
|
-
lineBreakStamp = '
|
|
622
|
+
lineBreakStamp = 'htmlmincollapsedlinebreak';
|
|
606
623
|
|
|
607
|
-
if (prevTag && prevTag !== 'img' && prevTag !== 'input' && (prevTag.substr(0,1) !== '/'
|
|
608
|
-
|| (
|
|
624
|
+
if (prevTag && prevTag !== 'img' && prevTag !== 'input' && (prevTag.substr(0, 1) !== '/'
|
|
625
|
+
|| (prevTag.substr(0, 1) === '/' && tags.indexOf(prevTag.substr(1)) === -1))) {
|
|
609
626
|
str = str.replace(/^\s+/, options.conservativeCollapse ? ' ' : options.preserveLineBreaks ? preserveBefore : '');
|
|
610
627
|
}
|
|
611
628
|
|
|
612
|
-
if (nextTag && nextTag !== 'img' && nextTag !== 'input' && (nextTag.substr(0,1) === '/'
|
|
613
|
-
|| (
|
|
629
|
+
if (nextTag && nextTag !== 'img' && nextTag !== 'input' && (nextTag.substr(0, 1) === '/'
|
|
630
|
+
|| (nextTag.substr(0, 1) !== '/' && tags.indexOf(nextTag) === -1))) {
|
|
614
631
|
str = str.replace(/\s+$/, options.conservativeCollapse ? ' ' : options.preserveLineBreaks ? preserveAfter : '');
|
|
615
632
|
}
|
|
616
633
|
|
|
@@ -624,7 +641,7 @@
|
|
|
624
641
|
// strip non space whitespace then compress spaces to one
|
|
625
642
|
return str
|
|
626
643
|
.replace(/[\t\n\r]+/g, ' ').replace(/[ ]+/g, ' ')
|
|
627
|
-
.replace(lineBreakStamp, '\n');
|
|
644
|
+
.replace(new RegExp(lineBreakStamp, 'g'), '\n');
|
|
628
645
|
}
|
|
629
646
|
|
|
630
647
|
return str;
|
|
@@ -656,13 +673,13 @@
|
|
|
656
673
|
|
|
657
674
|
function canRemoveAttributeQuotes(value) {
|
|
658
675
|
// http://mathiasbynens.be/notes/unquoted-attribute-values
|
|
659
|
-
return (/^[^\x20\t\n\f\r"'`=<>]+$/).test(value) && !(/\/$/
|
|
676
|
+
return (/^[^\x20\t\n\f\r"'`=<>]+$/).test(value) && !(/\/$/).test(value) &&
|
|
660
677
|
// make sure trailing slash is not interpreted as HTML self-closing tag
|
|
661
678
|
!(/\/$/).test(value);
|
|
662
679
|
}
|
|
663
680
|
|
|
664
681
|
function attributesInclude(attributes, attribute) {
|
|
665
|
-
for (var i = attributes.length; i--;
|
|
682
|
+
for (var i = attributes.length; i--;) {
|
|
666
683
|
if (attributes[i].name.toLowerCase() === attribute) {
|
|
667
684
|
return true;
|
|
668
685
|
}
|
|
@@ -708,6 +725,31 @@
|
|
|
708
725
|
);
|
|
709
726
|
}
|
|
710
727
|
|
|
728
|
+
// https://mathiasbynens.be/demo/javascript-mime-type
|
|
729
|
+
// https://developer.mozilla.org/en/docs/Web/HTML/Element/script#attr-type
|
|
730
|
+
var executableScriptsMimetypes = {
|
|
731
|
+
'text/javascript': 1,
|
|
732
|
+
'text/ecmascript': 1,
|
|
733
|
+
'text/jscript': 1,
|
|
734
|
+
'application/javascript': 1,
|
|
735
|
+
'application/x-javascript': 1,
|
|
736
|
+
'application/ecmascript': 1
|
|
737
|
+
};
|
|
738
|
+
|
|
739
|
+
function isExecutableScript(tag, attrs) {
|
|
740
|
+
if (tag !== 'script') {
|
|
741
|
+
return false;
|
|
742
|
+
}
|
|
743
|
+
for (var i = 0, len = attrs.length; i < len; i++) {
|
|
744
|
+
var attrName = attrs[i].name.toLowerCase();
|
|
745
|
+
if (attrName === 'type') {
|
|
746
|
+
return attrs[i].value === '' ||
|
|
747
|
+
executableScriptsMimetypes[attrs[i].value] === 1;
|
|
748
|
+
}
|
|
749
|
+
}
|
|
750
|
+
return true;
|
|
751
|
+
}
|
|
752
|
+
|
|
711
753
|
function isStyleLinkTypeAttribute(tag, attrName, attrValue) {
|
|
712
754
|
return (
|
|
713
755
|
(tag === 'style' || tag === 'link') &&
|
|
@@ -791,14 +833,14 @@
|
|
|
791
833
|
attrValue = attrValue.replace(/\s*;\s*$/, '');
|
|
792
834
|
}
|
|
793
835
|
if (options.minifyCSS) {
|
|
794
|
-
return minifyCSS(attrValue, options.minifyCSS);
|
|
836
|
+
return minifyCSS(attrValue, options.minifyCSS, true);
|
|
795
837
|
}
|
|
796
838
|
return attrValue;
|
|
797
839
|
}
|
|
798
840
|
else if (isMetaViewport(tag, attrs) && attrName === 'content') {
|
|
799
841
|
attrValue = attrValue.replace(/1\.0/g, '1').replace(/\s+/g, '');
|
|
800
842
|
}
|
|
801
|
-
else if (options.customAttrCollapse && options.customAttrCollapse.test(attrName)) {
|
|
843
|
+
else if (attrValue && options.customAttrCollapse && options.customAttrCollapse.test(attrName)) {
|
|
802
844
|
attrValue = attrValue.replace(/\n+/g, '');
|
|
803
845
|
}
|
|
804
846
|
return attrValue;
|
|
@@ -815,6 +857,22 @@
|
|
|
815
857
|
}
|
|
816
858
|
}
|
|
817
859
|
|
|
860
|
+
// Wrap CSS declarations for CleanCSS > 3.x
|
|
861
|
+
// See https://github.com/jakubpawlowicz/clean-css/issues/418
|
|
862
|
+
function wrapCSS(text) {
|
|
863
|
+
return '*{' + text + '}';
|
|
864
|
+
}
|
|
865
|
+
|
|
866
|
+
function unwrapCSS(text) {
|
|
867
|
+
var matches = text.match(/^\*\{([\s\S]*)\}$/m);
|
|
868
|
+
if (matches && matches[1]) {
|
|
869
|
+
return matches[1];
|
|
870
|
+
}
|
|
871
|
+
else {
|
|
872
|
+
return text;
|
|
873
|
+
}
|
|
874
|
+
}
|
|
875
|
+
|
|
818
876
|
function cleanConditionalComment(comment) {
|
|
819
877
|
return comment
|
|
820
878
|
.replace(/^(\[[^\]]+\]>)\s*/, '$1')
|
|
@@ -905,7 +963,8 @@
|
|
|
905
963
|
function normalizeAttribute(attr, attrs, tag, unarySlash, index, options) {
|
|
906
964
|
|
|
907
965
|
var attrName = options.caseSensitive ? attr.name : attr.name.toLowerCase(),
|
|
908
|
-
attrValue = attr.escaped,
|
|
966
|
+
attrValue = options.preventAttributesEscaping ? attr.value : attr.escaped,
|
|
967
|
+
attrQuote = options.preventAttributesEscaping ? attr.quote : '"',
|
|
909
968
|
attrFragment,
|
|
910
969
|
emittedAttrValue,
|
|
911
970
|
isTerminalOfUnarySlash = unarySlash && index === attrs.length - 1;
|
|
@@ -925,7 +984,7 @@
|
|
|
925
984
|
|
|
926
985
|
if (attrValue !== undefined && !options.removeAttributeQuotes ||
|
|
927
986
|
!canRemoveAttributeQuotes(attrValue) || isTerminalOfUnarySlash) {
|
|
928
|
-
emittedAttrValue =
|
|
987
|
+
emittedAttrValue = attrQuote + attrValue + attrQuote;
|
|
929
988
|
}
|
|
930
989
|
else {
|
|
931
990
|
emittedAttrValue = attrValue;
|
|
@@ -949,7 +1008,7 @@
|
|
|
949
1008
|
|
|
950
1009
|
function setDefaultTesters(options) {
|
|
951
1010
|
|
|
952
|
-
var defaultTesters = ['canCollapseWhitespace','canTrimWhitespace'];
|
|
1011
|
+
var defaultTesters = ['canCollapseWhitespace', 'canTrimWhitespace'];
|
|
953
1012
|
|
|
954
1013
|
for (var i = 0, len = defaultTesters.length; i < len; i++) {
|
|
955
1014
|
if (!options[defaultTesters[i]]) {
|
|
@@ -996,7 +1055,9 @@
|
|
|
996
1055
|
options = { };
|
|
997
1056
|
}
|
|
998
1057
|
options.fromString = true;
|
|
999
|
-
options.output
|
|
1058
|
+
var outputOptions = options.output || {};
|
|
1059
|
+
outputOptions.inline_script = true;
|
|
1060
|
+
options.output = outputOptions;
|
|
1000
1061
|
|
|
1001
1062
|
try {
|
|
1002
1063
|
// try to get global reference first
|
|
@@ -1044,20 +1105,28 @@
|
|
|
1044
1105
|
return text;
|
|
1045
1106
|
}
|
|
1046
1107
|
|
|
1047
|
-
function minifyCSS(text, options) {
|
|
1108
|
+
function minifyCSS(text, options, inline) {
|
|
1048
1109
|
if (typeof options !== 'object') {
|
|
1049
1110
|
options = { };
|
|
1050
1111
|
}
|
|
1051
|
-
if (typeof options.
|
|
1052
|
-
options.
|
|
1112
|
+
if (typeof options.advanced === 'undefined') {
|
|
1113
|
+
options.advanced = false;
|
|
1053
1114
|
}
|
|
1054
1115
|
try {
|
|
1116
|
+
var cleanCSS;
|
|
1117
|
+
|
|
1055
1118
|
if (typeof CleanCSS !== 'undefined') {
|
|
1056
|
-
|
|
1119
|
+
cleanCSS = new CleanCSS(options);
|
|
1057
1120
|
}
|
|
1058
1121
|
else if (typeof require === 'function') {
|
|
1059
1122
|
var CleanCSSModule = require('clean-css');
|
|
1060
|
-
|
|
1123
|
+
cleanCSS = new CleanCSSModule(options);
|
|
1124
|
+
}
|
|
1125
|
+
if (inline) {
|
|
1126
|
+
return unwrapCSS(cleanCSS.minify(wrapCSS(text)).styles);
|
|
1127
|
+
}
|
|
1128
|
+
else {
|
|
1129
|
+
return cleanCSS.minify(text).styles;
|
|
1061
1130
|
}
|
|
1062
1131
|
}
|
|
1063
1132
|
catch (err) {
|
|
@@ -1069,6 +1138,8 @@
|
|
|
1069
1138
|
function minify(value, options) {
|
|
1070
1139
|
|
|
1071
1140
|
options = options || {};
|
|
1141
|
+
var optionsStack = [];
|
|
1142
|
+
|
|
1072
1143
|
value = trimWhitespace(value);
|
|
1073
1144
|
setDefaultTesters(options);
|
|
1074
1145
|
|
|
@@ -1083,6 +1154,12 @@
|
|
|
1083
1154
|
isIgnoring = false,
|
|
1084
1155
|
t = new Date();
|
|
1085
1156
|
|
|
1157
|
+
if (options.removeIgnored) {
|
|
1158
|
+
value = value
|
|
1159
|
+
.replace(/<\?[^\?]+\?>/g, '')
|
|
1160
|
+
.replace(/<%[^%]+%>/g, '');
|
|
1161
|
+
}
|
|
1162
|
+
|
|
1086
1163
|
function _canCollapseWhitespace(tag, attrs) {
|
|
1087
1164
|
return canCollapseWhitespace(tag) || options.canCollapseWhitespace(tag, attrs);
|
|
1088
1165
|
}
|
|
@@ -1094,14 +1171,27 @@
|
|
|
1094
1171
|
new HTMLParser(value, {
|
|
1095
1172
|
html5: typeof options.html5 !== 'undefined' ? options.html5 : true,
|
|
1096
1173
|
|
|
1097
|
-
start: function(
|
|
1098
|
-
|
|
1174
|
+
start: function(tag, attrs, unary, unarySlash) {
|
|
1099
1175
|
if (isIgnoring) {
|
|
1100
1176
|
buffer.push('<' + tag, attrsToMarkup(attrs), unarySlash ? '/' : '', '>');
|
|
1101
1177
|
return;
|
|
1102
1178
|
}
|
|
1103
1179
|
|
|
1104
|
-
|
|
1180
|
+
var lowerTag = tag.toLowerCase();
|
|
1181
|
+
|
|
1182
|
+
if (lowerTag === 'svg') {
|
|
1183
|
+
optionsStack.push(options);
|
|
1184
|
+
var nextOptions = {};
|
|
1185
|
+
for (var key in options) {
|
|
1186
|
+
nextOptions[key] = options[key];
|
|
1187
|
+
}
|
|
1188
|
+
nextOptions.keepClosingSlash = true;
|
|
1189
|
+
nextOptions.caseSensitive = true;
|
|
1190
|
+
options = nextOptions;
|
|
1191
|
+
}
|
|
1192
|
+
|
|
1193
|
+
tag = options.caseSensitive ? tag : lowerTag;
|
|
1194
|
+
|
|
1105
1195
|
currentTag = tag;
|
|
1106
1196
|
currentChars = '';
|
|
1107
1197
|
currentAttrs = attrs;
|
|
@@ -1118,31 +1208,40 @@
|
|
|
1118
1208
|
|
|
1119
1209
|
var openTag = '<' + tag;
|
|
1120
1210
|
var closeTag = ((unarySlash && options.keepClosingSlash) ? '/' : '') + '>';
|
|
1121
|
-
if (
|
|
1211
|
+
if (attrs.length === 0) {
|
|
1122
1212
|
openTag += closeTag;
|
|
1123
1213
|
}
|
|
1124
1214
|
|
|
1125
1215
|
buffer.push(openTag);
|
|
1126
1216
|
|
|
1127
|
-
|
|
1217
|
+
if (lint) {
|
|
1218
|
+
lint.testElement(tag);
|
|
1219
|
+
}
|
|
1128
1220
|
|
|
1129
1221
|
var token;
|
|
1130
|
-
for (
|
|
1131
|
-
|
|
1222
|
+
for (var i = 0, len = attrs.length; i < len; i++) {
|
|
1223
|
+
if (lint) {
|
|
1224
|
+
lint.testAttribute(tag, attrs[i].name.toLowerCase(), attrs[i].escaped);
|
|
1225
|
+
}
|
|
1132
1226
|
token = normalizeAttribute(attrs[i], attrs, tag, unarySlash, i, options);
|
|
1133
|
-
if (
|
|
1227
|
+
if (i === len - 1) {
|
|
1134
1228
|
token += closeTag;
|
|
1135
1229
|
}
|
|
1136
1230
|
buffer.push(token);
|
|
1137
1231
|
}
|
|
1138
1232
|
},
|
|
1139
|
-
end: function(
|
|
1233
|
+
end: function(tag, attrs) {
|
|
1140
1234
|
|
|
1141
1235
|
if (isIgnoring) {
|
|
1142
1236
|
buffer.push('</' + tag + '>');
|
|
1143
1237
|
return;
|
|
1144
1238
|
}
|
|
1145
1239
|
|
|
1240
|
+
var lowerTag = tag.toLowerCase();
|
|
1241
|
+
if (lowerTag === 'svg') {
|
|
1242
|
+
options = optionsStack.pop();
|
|
1243
|
+
}
|
|
1244
|
+
|
|
1146
1245
|
// check if current tag is in a whitespace stack
|
|
1147
1246
|
if (options.collapseWhitespace) {
|
|
1148
1247
|
if (stackNoTrimWhitespace.length &&
|
|
@@ -1158,8 +1257,8 @@
|
|
|
1158
1257
|
var isElementEmpty = currentChars === '' && tag === currentTag;
|
|
1159
1258
|
if ((options.removeEmptyElements && isElementEmpty && canRemoveElement(tag, attrs))) {
|
|
1160
1259
|
// remove last "element" from buffer, return
|
|
1161
|
-
for (
|
|
1162
|
-
if (
|
|
1260
|
+
for (var i = buffer.length - 1; i >= 0; i--) {
|
|
1261
|
+
if (/^<[^\/!]/.test(buffer[i])) {
|
|
1163
1262
|
buffer.splice(i);
|
|
1164
1263
|
break;
|
|
1165
1264
|
}
|
|
@@ -1172,14 +1271,17 @@
|
|
|
1172
1271
|
}
|
|
1173
1272
|
else {
|
|
1174
1273
|
// push end tag to buffer
|
|
1175
|
-
buffer.push('</' + (options.caseSensitive ? tag :
|
|
1274
|
+
buffer.push('</' + (options.caseSensitive ? tag : lowerTag) + '>');
|
|
1176
1275
|
results.push.apply(results, buffer);
|
|
1177
1276
|
}
|
|
1178
1277
|
// flush buffer
|
|
1179
1278
|
buffer.length = 0;
|
|
1180
1279
|
currentChars = '';
|
|
1181
1280
|
},
|
|
1182
|
-
chars: function(
|
|
1281
|
+
chars: function(text, prevTag, nextTag) {
|
|
1282
|
+
prevTag = prevTag === '' ? 'comment' : prevTag;
|
|
1283
|
+
nextTag = nextTag === '' ? 'comment' : nextTag;
|
|
1284
|
+
|
|
1183
1285
|
if (isIgnoring) {
|
|
1184
1286
|
buffer.push(text);
|
|
1185
1287
|
return;
|
|
@@ -1196,7 +1298,7 @@
|
|
|
1196
1298
|
text = processScript(text, options, currentAttrs);
|
|
1197
1299
|
}
|
|
1198
1300
|
}
|
|
1199
|
-
if (
|
|
1301
|
+
if (options.minifyJS && isExecutableScript(currentTag, currentAttrs)) {
|
|
1200
1302
|
text = minifyJS(text, options.minifyJS);
|
|
1201
1303
|
}
|
|
1202
1304
|
if (currentTag === 'style' && options.minifyCSS) {
|
|
@@ -1204,7 +1306,7 @@
|
|
|
1204
1306
|
}
|
|
1205
1307
|
if (options.collapseWhitespace) {
|
|
1206
1308
|
if (!stackNoTrimWhitespace.length) {
|
|
1207
|
-
text = (prevTag || nextTag) ?
|
|
1309
|
+
text = ((prevTag && prevTag !== 'comment') || (nextTag && nextTag !== 'comment')) ?
|
|
1208
1310
|
collapseWhitespaceSmart(text, prevTag, nextTag, options)
|
|
1209
1311
|
: trimWhitespace(text);
|
|
1210
1312
|
}
|
|
@@ -1213,10 +1315,12 @@
|
|
|
1213
1315
|
}
|
|
1214
1316
|
}
|
|
1215
1317
|
currentChars = text;
|
|
1216
|
-
|
|
1318
|
+
if (lint) {
|
|
1319
|
+
lint.testChars(text);
|
|
1320
|
+
}
|
|
1217
1321
|
buffer.push(text);
|
|
1218
1322
|
},
|
|
1219
|
-
comment: function(
|
|
1323
|
+
comment: function(text, nonStandard) {
|
|
1220
1324
|
|
|
1221
1325
|
var prefix = nonStandard ? '<!' : '<!--';
|
|
1222
1326
|
var suffix = nonStandard ? '>' : '-->';
|
|
@@ -1244,10 +1348,6 @@
|
|
|
1244
1348
|
}
|
|
1245
1349
|
buffer.push(text);
|
|
1246
1350
|
},
|
|
1247
|
-
ignore: function(text) {
|
|
1248
|
-
// `text` === strings that start with `<?` or `<%` and end with `?>` or `%>`.
|
|
1249
|
-
buffer.push(options.removeIgnored ? '' : text); // `text` allowed by default.
|
|
1250
|
-
},
|
|
1251
1351
|
doctype: function(doctype) {
|
|
1252
1352
|
buffer.push(options.useShortDoctype ? '<!DOCTYPE html>' : collapseWhitespace(doctype));
|
|
1253
1353
|
},
|
|
@@ -1261,16 +1361,16 @@
|
|
|
1261
1361
|
return str;
|
|
1262
1362
|
}
|
|
1263
1363
|
|
|
1264
|
-
function joinResultSegments(
|
|
1364
|
+
function joinResultSegments(results, options) {
|
|
1265
1365
|
var str;
|
|
1266
1366
|
var maxLineLength = options.maxLineLength;
|
|
1267
|
-
if (
|
|
1367
|
+
if (maxLineLength) {
|
|
1268
1368
|
var token;
|
|
1269
1369
|
var lines = [];
|
|
1270
1370
|
var line = '';
|
|
1271
|
-
for (
|
|
1371
|
+
for (var i = 0, len = results.length; i < len; i++) {
|
|
1272
1372
|
token = results[i];
|
|
1273
|
-
if (
|
|
1373
|
+
if (line.length + token.length < maxLineLength) {
|
|
1274
1374
|
line += token;
|
|
1275
1375
|
}
|
|
1276
1376
|
else {
|
|
@@ -1290,7 +1390,7 @@
|
|
|
1290
1390
|
}
|
|
1291
1391
|
|
|
1292
1392
|
// for CommonJS enviroments, export everything
|
|
1293
|
-
if (
|
|
1393
|
+
if (typeof exports !== 'undefined') {
|
|
1294
1394
|
exports.minify = minify;
|
|
1295
1395
|
}
|
|
1296
1396
|
else {
|
|
@@ -1320,7 +1420,7 @@
|
|
|
1320
1420
|
return (/^on[a-z]+/).test(attrName);
|
|
1321
1421
|
}
|
|
1322
1422
|
function isStyleAttribute(attrName) {
|
|
1323
|
-
return (
|
|
1423
|
+
return (attrName.toLowerCase() === 'style');
|
|
1324
1424
|
}
|
|
1325
1425
|
function isDeprecatedAttribute(tag, attrName) {
|
|
1326
1426
|
return (
|
package/dist/htmlminifier.min.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/*!
|
|
2
|
-
* HTMLMinifier v0.
|
|
3
|
-
* Copyright 2010-
|
|
2
|
+
* HTMLMinifier v0.7.2 (http://kangax.github.io/html-minifier/)
|
|
3
|
+
* Copyright 2010-2015 Juriy "kangax" Zaytsev
|
|
4
4
|
* Licensed under MIT (https://github.com/kangax/html-minifier/blob/gh-pages/LICENSE)
|
|
5
5
|
*/
|
|
6
|
-
!function(a){"use strict";function b(a){var b,c=new RegExp("(?:\\s*[\\w:-]+(?:\\s*(?:"+d(a)+")\\s*(?:(?:\"[^\"]*\")|(?:'[^']*')|[^>\\s]+))?)*");if(a.customAttrSurround){for(var e=[],f=a.customAttrSurround.length-1;f>=0;f--)e[f]="(?:\\s*"+a.customAttrSurround[f][0].source+c.source+a.customAttrSurround[f][1].source+")";e.unshift(c.source),b=new RegExp("((?:"+e.join("|")+")*)")}else b=new RegExp("("+c.source+")");return new RegExp(j.source+b.source+k.source)}function c(a){var b=new RegExp(f.source+"(?:\\s*("+d(a)+")\\s*(?:"+i.join("|")+"))?");if(a.customAttrSurround){for(var c=[],e=a.customAttrSurround.length-1;e>=0;e--)c[e]="(?:("+a.customAttrSurround[e][0].source+")"+b.source+"("+a.customAttrSurround[e][1].source+"))";return c.unshift("(?:"+b.source+")"),new RegExp(c.join("|"),"g")}return new RegExp(b.source,"g")}function d(a){return h.concat(a.customAttrAssign||[]).map(function(a){return"(?:"+a.source+")"}).join("|")}function e(a){for(var b={},c=a.split(","),d=0;d<c.length;d++)b[c[d]]=!0,b[c[d].toUpperCase()]=!0;return b}var f=/([\w:-]+)/,g=/=/,h=[g],i=[/"((?:\\.|[^"])*)"/.source,/'((?:\\.|[^'])*)'/.source,/([^>\s]+)/.source],j=/^<([\w:-]+)/,k=/\s*(\/?)>/,l=/^<\/([\w:-]+)[^>]*>/,m=/\/>$/,n=/^<!DOCTYPE [^>]+>/i,o=/<(%|\?)/,p=/(%|\?)>/,q=!1;"x".replace(/x(.)?/g,function(a,b){q=""===b});var r,s,t,u=e("area,base,basefont,br,col,frame,hr,img,input,isindex,link,meta,param,embed,wbr"),v=e("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"),w=e("colgroup,dd,dt,li,options,p,td,tfoot,th,thead,tr,source"),x=e("checked,compact,declare,defer,disabled,ismap,multiple,nohref,noresize,noshade,nowrap,readonly,selected"),y=e("script,style,noscript"),z={},A=a.HTMLParser=function(a,d){function e(a,b,c,e){for(var g=!1;!d.html5&&A.last()&&v[A.last()];)f("",A.last());w[b]&&A.last()===b&&f("",b),e=u[b]||!!e;var h=[];c.replace(D,function(){var a,b,c,e,f,g,i=7;if(q&&-1===arguments[0].indexOf('""')&&(""===arguments[3]&&(arguments[3]=void 0),""===arguments[4]&&(arguments[4]=void 0),""===arguments[5]&&(arguments[5]=void 0)),a=arguments[1])g=arguments[2],c=arguments[3],b=c||arguments[4]||arguments[5];else if(d.customAttrSurround)for(var j=d.customAttrSurround.length-1;j>=0;j--)if(a=arguments[j*i+7],g=arguments[j*i+8],a){c=arguments[j*i+9],b=c||arguments[j*i+10]||arguments[j*i+11],e=arguments[j*i+6],f=arguments[j*i+12];break}void 0===b&&(b=x[a]?a:c),h.push({name:a,value:b,escaped:b&&b.replace(/(^|[^\\])"/g,"$1""),customAssign:g||"=",customOpen:e||"",customClose:f||""})}),e?g=a.match(m):A.push({tag:b,attrs:h}),d.start&&d.start(b,h,e,g)}function f(a,b){var c;if(b){var e=b.toLowerCase();for(c=A.length-1;c>=0&&A[c].tag.toLowerCase()!==e;c--);}else c=0;if(c>=0){for(var f=A.length-1;f>=c;f--)d.end&&d.end(A[f].tag,A[f].attrs);A.length=c}}var g,h,i,j,k,A=[],B=a;A.last=function(){var a=this[this.length-1];return a&&a.tag};for(var C=b(d),D=c(d);a;){if(h=!0,A.last()&&y[A.last()])r=A.last().toLowerCase(),s=z[r]||(z[r]=new RegExp("([\\s\\S]*?)</"+r+"[^>]*>","i")),a=a.replace(s,function(a,b){return"script"!==r&&"style"!==r&&"noscript"!==r&&(b=b.replace(/<!--([\s\S]*?)-->/g,"$1").replace(/<!\[CDATA\[([\s\S]*?)\]\]>/g,"$1")),d.chars&&d.chars(b),""}),f("",r);else if(/^<!--/.test(a)&&(g=a.indexOf("-->"),g>=0&&(d.comment&&d.comment(a.substring(4,g)),a=a.substring(g+3),h=!1)),/^<!\[/.test(a)?(g=a.indexOf("]>"),g>=0&&(d.comment&&d.comment(a.substring(2,g+1),!0),a=a.substring(g+2),h=!1)):0===a.search(o)?(g=a.search(p),g>=0&&(d.ignore&&d.ignore(a.substring(0,g+2)),a=a.substring(g+2),h=!1)):(i=n.exec(a))?(d.doctype&&d.doctype(i[0]),a=a.substring(i[0].length),h=!1):/^<\//.test(a)?(i=a.match(l),i&&(a=a.substring(i[0].length),i[0].replace(l,f),j="/"+i[1].toLowerCase(),h=!1)):/^</.test(a)&&(i=a.match(C),i&&(a=a.substring(i[0].length),i[0].replace(C,e),j=i[1].toLowerCase(),h=!1)),h){g=a.indexOf("<");var E=0>g?a:a.substring(0,g);a=0>g?"":a.substring(g),t=a.match(C),t?k=t[1]:(t=a.match(l),k=t?"/"+t[1]:""),d.chars&&d.chars(E,j,k)}if(a===B)throw"Parse Error: "+a;B=a}f()};a.HTMLtoXML=function(a){var b="";return new A(a,{start:function(a,c,d){b+="<"+a;for(var e=0;e<c.length;e++)b+=" "+c[e].name+'="'+c[e].escaped+'"';b+=(d?"/":"")+">"},end:function(a){b+="</"+a+">"},chars:function(a){b+=a},comment:function(a){b+="<!--"+a+"-->"},ignore:function(a){b+=a}}),b},a.HTMLtoDOM=function(a,b){var c=e("html,head,body,title"),d={link:"head",base:"head"};b?b=b.ownerDocument||b.getOwnerDocument&&b.getOwnerDocument()||b:"undefined"!=typeof DOMDocument?b=new DOMDocument:"undefined"!=typeof document&&document.implementation&&document.implementation.createDocument?b=document.implementation.createDocument("","",null):"undefined"!=typeof ActiveX&&(b=new ActiveXObject("Msxml.DOMDocument"));var f=[],g=b.documentElement||b.getDocumentElement&&b.getDocumentElement();if(!g&&b.createElement&&!function(){var a=b.createElement("html"),c=b.createElement("head");c.appendChild(b.createElement("title")),a.appendChild(c),a.appendChild(b.createElement("body")),b.appendChild(a)}(),b.getElementsByTagName)for(var h in c)c[h]=b.getElementsByTagName(h)[0];var i=c.body;return new A(a,{start:function(a,e,g){if(c[a])return void(i=c[a]);var h=b.createElement(a);for(var j in e)h.setAttribute(e[j].name,e[j].value);d[a]&&"boolean"!=typeof c[d[a]]?c[d[a]].appendChild(h):i&&i.appendChild&&i.appendChild(h),g||(f.push(h),i=h)},end:function(){f.length-=1,i=f[f.length-1]},chars:function(a){i.appendChild(b.createTextNode(a))},comment:function(){},ignore:function(){}}),b}}("undefined"==typeof exports?this:exports),function(a){"use strict";function b(a){return a?a.replace(/[\t\n\r ]+/g," "):a}function c(a,b,c,d){var e=["a","abbr","acronym","b","bdi","bdo","big","button","cite","code","del","dfn","em","font","i","ins","kbd","mark","q","rt","rp","s","samp","small","span","strike","strong","sub","sup","svg","time","tt","u","var"],f=/^[\t ]*[\n\r]+[\t\n\r ]*/,g=/[\t\n\r ]*[\n\r]+[\t ]*$/,h=f.test(a)?"\n":" ",i=g.test(a)?"\n":" ",j="[{htmlmin-lb}]";return b&&"img"!==b&&"input"!==b&&("/"!==b.substr(0,1)||"/"===b.substr(0,1)&&-1===e.indexOf(b.substr(1)))&&(a=a.replace(/^\s+/,d.conservativeCollapse?" ":d.preserveLineBreaks?h:"")),c&&"img"!==c&&"input"!==c&&("/"===c.substr(0,1)||"/"!==c.substr(0,1)&&-1===e.indexOf(c))&&(a=a.replace(/\s+$/,d.conservativeCollapse?" ":d.preserveLineBreaks?i:"")),b&&c?(d.preserveLineBreaks&&(a=a.replace(f,j).replace(g,j)),a.replace(/[\t\n\r]+/g," ").replace(/[ ]+/g," ").replace(j,"\n")):a}function d(a){return/\[if[^\]]+\]/.test(a)||/\s*((?:<!)?\[endif\])$/.test(a)}function e(a,b){if(/^!/.test(a))return!0;if(b.ignoreCustomComments)for(var c=0,d=b.ignoreCustomComments.length;d>c;c++)if(b.ignoreCustomComments[c].test(a))return!0;return!1}function f(a){return/^on[a-z]+/.test(a)}function g(a){return/^[^\x20\t\n\f\r"'`=<>]+$/.test(a)&&!/\/$/.test(a)&&!/\/$/.test(a)}function h(a,b){for(var c=a.length;c--;)if(a[c].name.toLowerCase()===b)return!0;return!1}function i(a,b,c,d){return c=c?J(c.toLowerCase()):"","script"===a&&"language"===b&&"javascript"===c||"form"===a&&"method"===b&&"get"===c||"input"===a&&"type"===b&&"text"===c||"script"===a&&"charset"===b&&!h(d,"src")||"a"===a&&"name"===b&&h(d,"id")||"area"===a&&"shape"===b&&"rect"===c}function j(a,b,c){return"script"===a&&"type"===b&&"text/javascript"===J(c.toLowerCase())}function k(a,b,c){return("style"===a||"link"===a)&&"type"===b&&"text/css"===J(c.toLowerCase())}function l(a,b){var c=/^(?:allowfullscreen|async|autofocus|autoplay|checked|compact|controls|declare|default|defaultchecked|defaultmuted|defaultselected|defer|disabled|enabled|formnovalidate|hidden|indeterminate|inert|ismap|itemscope|loop|multiple|muted|nohref|noresize|noshade|novalidate|nowrap|open|pauseonexit|readonly|required|reversed|scoped|seamless|selected|sortable|spellcheck|truespeed|typemustmatch|visible)$/i.test(a);if(c)return!0;var d=K[a.toLowerCase()];return d?-1===d.indexOf(b.toLowerCase()):!1}function m(a,b){return/^(?:a|area|link|base)$/.test(b)&&"href"===a||"img"===b&&/^(?:src|longdesc|usemap)$/.test(a)||"object"===b&&/^(?:classid|codebase|data|usemap)$/.test(a)||"q"===b&&"cite"===a||"blockquote"===b&&"cite"===a||("ins"===b||"del"===b)&&"cite"===a||"form"===b&&"action"===a||"input"===b&&("src"===a||"usemap"===a)||"head"===b&&"profile"===a||"script"===b&&("src"===a||"for"===a)}function n(a,b){return/^(?:a|area|object|button)$/.test(b)&&"tabindex"===a||"input"===b&&("maxlength"===a||"tabindex"===a)||"select"===b&&("size"===a||"tabindex"===a)||"textarea"===b&&/^(?:rows|cols|tabindex)$/.test(a)||"colgroup"===b&&"span"===a||"col"===b&&"span"===a||("th"===b||"td"===b)&&("rowspan"===a||"colspan"===a)}function o(a,c,d,e,g){if(d&&f(c)){if(d=J(d).replace(/^javascript:\s*/i,"").replace(/\s*;$/,""),e.minifyJS){var h="(function(){"+d+"})()",i=D(h,e.minifyJS);return i.slice(12,i.length-4).replace(/"/g,""")}return d}return"class"===c?b(J(d)):m(c,a)?(d=J(d),e.minifyURLs?C(d,e.minifyURLs):d):n(c,a)?J(d):"style"===c?(d=J(d),d&&(d=d.replace(/\s*;\s*$/,"")),e.minifyCSS?E(d,e.minifyCSS):d):(p(a,g)&&"content"===c?d=d.replace(/1\.0/g,"1").replace(/\s+/g,""):e.customAttrCollapse&&e.customAttrCollapse.test(c)&&(d=d.replace(/\n+/g,"")),d)}function p(a,b){if("meta"!==a)return!1;for(var c=0,d=b.length;d>c;c++)if("name"===b[c].name&&"viewport"===b[c].value)return!0}function q(a){return a.replace(/^(\[[^\]]+\]>)\s*/,"$1").replace(/\s*(<!\[endif\])$/,"$1")}function r(a){return a.replace(/^(?:\s*\/\*\s*<!\[CDATA\[\s*\*\/|\s*\/\/\s*<!\[CDATA\[.*)/,"").replace(/(?:\/\*\s*\]\]>\s*\*\/|\/\/\s*\]\]>)\s*$/,"")}function s(a,b,c){for(var d=0,e=c.length;e>d;d++)if("type"===c[d].name.toLowerCase()&&b.processScripts.indexOf(c[d].value)>-1)return F(a,b);return a}function t(a,b){return a.replace(L[b],"").replace(M[b],"")}function u(a){return/^(?:html|t?body|t?head|tfoot|tr|td|th|dt|dd|option|colgroup|source)$/.test(a)}function v(a,b,c){var d=!c||/^\s*$/.test(c);return d?"input"===a&&"value"===b||N.test(b):!1}function w(a,b){if("textarea"===a)return!1;if("script"===a)for(var c=b.length-1;c>=0;c--)if("src"===b[c].name)return!1;return!0}function x(a){return!/^(?:script|style|pre|textarea)$/.test(a)}function y(a){return!/^(?:pre|textarea)$/.test(a)}function z(a){for(var b="",c=0,d=a.length;d>c;c++)b+=" "+a[c].name+(l(a[c].value)?"":'="'+a[c].value+'"');return b}function A(a,b,c,d,e,f){var h,m,n=f.caseSensitive?a.name:a.name.toLowerCase(),p=a.escaped,q=d&&e===b.length-1;return f.removeRedundantAttributes&&i(c,n,p,b)||f.removeScriptTypeAttributes&&j(c,n,p)||f.removeStyleLinkTypeAttributes&&k(c,n,p)?"":(p=o(c,n,p,f,b),m=void 0!==p&&!f.removeAttributeQuotes||!g(p)||q?'"'+p+'"':p,f.removeEmptyAttributes&&v(c,n,p)?"":(h=void 0===p||f.collapseBooleanAttributes&&l(n,p)?n:n+a.customAssign+m," "+a.customOpen+h+a.customClose))}function B(a){for(var b=["canCollapseWhitespace","canTrimWhitespace"],c=0,d=b.length;d>c;c++)a[b[c]]||(a[b[c]]=function(){return!1})}function C(b,c){"object"!=typeof c&&(c={});try{var d=a.RelateUrl;return"undefined"==typeof d&&"function"==typeof require&&(d=require("relateurl")),d&&d.relate?d.relate(b,c):b}catch(e){H(e)}return b}function D(b,c){"object"!=typeof c&&(c={}),c.fromString=!0,c.output={inline_script:!0};try{var d=a.UglifyJS;if("undefined"==typeof d&&"function"==typeof require&&(d=require("uglify-js")),!d)return b;if(d.minify)return d.minify(b,c).code;if(d.parse){var e=d.parse(b);e.figure_out_scope();var f=d.Compressor(),g=e.transform(f);g.figure_out_scope(),g.compute_char_frequency(),c.mangle!==!1&&g.mangle_names();var h=d.OutputStream(c.output);return g.print(h),h.toString()}return b}catch(i){H(i)}return b}function E(a,b){"object"!=typeof b&&(b={}),"undefined"==typeof b.noAdvanced&&(b.noAdvanced=!0);try{if("undefined"!=typeof CleanCSS)return new CleanCSS(b).minify(a);if("function"==typeof require){var c=require("clean-css");return new c(b).minify(a)}}catch(d){H(d)}return a}function F(a,f){function g(a,b){return x(a)||f.canCollapseWhitespace(a,b)}function h(a,b){return y(a)||f.canTrimWhitespace(a,b)}f=f||{},a=J(a),B(f);var i=[],j=[],k="",l="",m=[],n=[],o=[],p=f.lint,v=!1,C=new Date;new I(a,{html5:"undefined"!=typeof f.html5?f.html5:!0,start:function(a,b,c,d){if(v)return void j.push("<"+a,z(b),d?"/":"",">");a=f.caseSensitive?a:a.toLowerCase(),l=a,k="",m=b,f.collapseWhitespace&&(h(a,b)||n.push(a),g(a,b)||o.push(a));var e="<"+a,i=(d&&f.keepClosingSlash?"/":"")+">";0===b.length&&(e+=i),j.push(e),p&&p.testElement(a);for(var q,r=0,s=b.length;s>r;r++)p&&p.testAttribute(a,b[r].name.toLowerCase(),b[r].escaped),q=A(b[r],b,a,d,r,f),r===s-1&&(q+=i),j.push(q)},end:function(a,b){if(v)return void j.push("</"+a+">");f.collapseWhitespace&&(n.length&&a===n[n.length-1]&&n.pop(),o.length&&a===o[o.length-1]&&o.pop());var c=""===k&&a===l;if(f.removeEmptyElements&&c&&w(a,b)){for(var d=j.length-1;d>=0;d--)if(/^<[^\/!]/.test(j[d])){j.splice(d);break}}else f.removeOptionalTags&&u(a)||(j.push("</"+(f.caseSensitive?a:a.toLowerCase())+">"),i.push.apply(i,j),j.length=0,k="")},chars:function(a,d,e){return v?void j.push(a):(("script"===l||"style"===l)&&(f.removeCommentsFromCDATA&&(a=t(a,l)),f.removeCDATASectionsFromCDATA&&(a=r(a)),f.processScripts&&(a=s(a,f,m))),"script"===l&&f.minifyJS&&(a=D(a,f.minifyJS)),"style"===l&&f.minifyCSS&&(a=E(a,f.minifyCSS)),f.collapseWhitespace&&(n.length||(a=d||e?c(a,d,e,f):J(a)),o.length||(a=d&&e||"html"===e?a:b(a))),k=a,p&&p.testChars(a),void j.push(a))},comment:function(a,b){var c=b?"<!":"<!--",g=b?">":"-->";return/^\s*htmlmin:ignore/.test(a)?(v=!v,void(f.removeComments||j.push("<!--"+a+"-->"))):(a=f.removeComments?d(a)?c+q(a)+g:e(a,f)?"<!--"+a+"-->":"":c+a+g,void j.push(a))},ignore:function(a){j.push(f.removeIgnored?"":a)},doctype:function(a){j.push(f.useShortDoctype?"<!DOCTYPE html>":b(a))},customAttrAssign:f.customAttrAssign,customAttrSurround:f.customAttrSurround}),i.push.apply(i,j);var F=G(i,f);return H("minified in: "+(new Date-C)+"ms"),F}function G(a,b){var c,d=b.maxLineLength;if(d){for(var e,f=[],g="",h=0,i=a.length;i>h;h++)e=a[h],g.length+e.length<d?g+=e:(f.push(g.replace(/^\n/,"")),g=e);f.push(g),c=f.join("\n")}else c=a.join("");return c}var H,I;H=a.console&&a.console.log?function(b){a.console.log(b)}:function(){},a.HTMLParser?I=a.HTMLParser:"function"==typeof require&&(I=require("./htmlparser").HTMLParser);var J=function(a){return"string"!=typeof a?a:a.replace(/^\s+/,"").replace(/\s+$/,"")};String.prototype.trim&&(J=function(a){return"string"!=typeof a?a:a.trim()});var K={draggable:["true","false"]},L={script:/^\s*(?:\/\/)?\s*<!--.*\n?/,style:/^\s*<!--\s*/},M={script:/\s*(?:\/\/)?\s*-->\s*$/,style:/\s*-->\s*$/},N=new RegExp("^(?:class|id|style|title|lang|dir|on(?:focus|blur|change|click|dblclick|mouse(?:down|up|over|move|out)|key(?:press|down|up)))$");"undefined"!=typeof exports?exports.minify=F:a.minify=F}(this),function(a){"use strict";function b(a){return/^(?:big|small|hr|blink|marquee)$/.test(a)}function c(a){return/^(?:applet|basefont|center|dir|font|isindex|strike)$/.test(a)}function d(a){return/^on[a-z]+/.test(a)}function e(a){return"style"===a.toLowerCase()}function f(a,b){return"align"===b&&/^(?:caption|applet|iframe|img|imput|object|legend|table|hr|div|h[1-6]|p)$/.test(a)||"alink"===b&&"body"===a||"alt"===b&&"applet"===a||"archive"===b&&"applet"===a||"background"===b&&"body"===a||"bgcolor"===b&&/^(?:table|t[rdh]|body)$/.test(a)||"border"===b&&/^(?:img|object)$/.test(a)||"clear"===b&&"br"===a||"code"===b&&"applet"===a||"codebase"===b&&"applet"===a||"color"===b&&/^(?:base(?:font)?)$/.test(a)||"compact"===b&&/^(?:dir|[dou]l|menu)$/.test(a)||"face"===b&&/^base(?:font)?$/.test(a)||"height"===b&&/^(?:t[dh]|applet)$/.test(a)||"hspace"===b&&/^(?:applet|img|object)$/.test(a)||"language"===b&&"script"===a||"link"===b&&"body"===a||"name"===b&&"applet"===a||"noshade"===b&&"hr"===a||"nowrap"===b&&/^t[dh]$/.test(a)||"object"===b&&"applet"===a||"prompt"===b&&"isindex"===a||"size"===b&&/^(?:hr|font|basefont)$/.test(a)||"start"===b&&"ol"===a||"text"===b&&"body"===a||"type"===b&&/^(?:li|ol|ul)$/.test(a)||"value"===b&&"li"===a||"version"===b&&"html"===a||"vlink"===b&&"body"===a||"vspace"===b&&/^(?:applet|img|object)$/.test(a)||"width"===b&&/^(?:hr|td|th|applet|pre)$/.test(a)}function g(a,b){return"href"===a&&/^\s*javascript\s*:\s*void\s*(\s+0|\(\s*0\s*\))\s*$/i.test(b)}function h(){this.log=[],this._lastElement=null,this._isElementRepeated=!1}h.prototype.testElement=function(a){c(a)?this.log.push('Found <span class="deprecated-element">deprecated</span> <strong><code><'+a+"></code></strong> element"):b(a)?this.log.push('Found <span class="presentational-element">presentational</span> <strong><code><'+a+"></code></strong> element"):this.checkRepeatingElement(a)},h.prototype.checkRepeatingElement=function(a){"br"===a&&"br"===this._lastElement?this._isElementRepeated=!0:this._isElementRepeated&&(this._reportRepeatingElement(),this._isElementRepeated=!1),this._lastElement=a},h.prototype._reportRepeatingElement=function(){this.log.push("Found <code><br></code> sequence. Try replacing it with styling.")},h.prototype.testAttribute=function(a,b,c){d(b)?this.log.push('Found <span class="event-attribute">event attribute</span> (<strong>'+b+"</strong>) on <strong><code><"+a+"></code></strong> element."):f(a,b)?this.log.push('Found <span class="deprecated-attribute">deprecated</span> <strong>'+b+"</strong> attribute on <strong><code><"+a+"></code></strong> element."):e(b)?this.log.push('Found <span class="style-attribute">style attribute</span> on <strong><code><'+a+"></code></strong> element."):g(b,c)&&this.log.push('Found <span class="inaccessible-attribute">inaccessible attribute</span> (on <strong><code><'+a+"></code></strong> element).")},h.prototype.testChars=function(a){this._lastElement="",/( \s*){2,}/.test(a)&&this.log.push("Found repeating <strong><code>&nbsp;</code></strong> sequence. Try replacing it with styling.")},h.prototype.test=function(a,b,c){this.testElement(a),this.testAttribute(a,b,c)},h.prototype.populate=function(a){if(this._isElementRepeated&&this._reportRepeatingElement(),this.log.length)if(a)a.innerHTML="<ol><li>"+this.log.join("<li>")+"</ol>";else{var b=" - "+this.log.join("\n - ").replace(/(<([^>]+)>)/gi,"").replace(/</g,"<").replace(/>/g,">");console.log(b)}},a.HTMLLint=h}("undefined"==typeof exports?this:exports);
|
|
6
|
+
!function(a){"use strict";function b(a){var b,c=new RegExp("(?:\\s*[\\w:\\.-]+(?:\\s*(?:"+d(a)+")\\s*(?:(?:\"[^\"]*\")|(?:'[^']*')|[^>\\s]+))?)*");if(a.customAttrSurround){for(var e=[],f=a.customAttrSurround.length-1;f>=0;f--)e[f]="(?:\\s*"+a.customAttrSurround[f][0].source+c.source+a.customAttrSurround[f][1].source+")";e.unshift(c.source),b=new RegExp("((?:"+e.join("|")+")*)")}else b=new RegExp("("+c.source+")");return new RegExp(j.source+b.source+k.source)}function c(a){var b=new RegExp(f.source+"(?:\\s*("+d(a)+")\\s*(?:"+i.join("|")+"))?");if(a.customAttrSurround){for(var c=[],e=a.customAttrSurround.length-1;e>=0;e--)c[e]="(?:("+a.customAttrSurround[e][0].source+")"+b.source+"("+a.customAttrSurround[e][1].source+"))";return c.unshift("(?:"+b.source+")"),new RegExp(c.join("|"),"g")}return new RegExp(b.source,"g")}function d(a){return h.concat(a.customAttrAssign||[]).map(function(a){return"(?:"+a.source+")"}).join("|")}function e(a){for(var b={},c=a.split(","),d=0;d<c.length;d++)b[c[d]]=!0,b[c[d].toUpperCase()]=!0;return b}var f=/([\w:\.-]+)/,g=/=/,h=[g],i=[/"((?:\\.|[^"])*)"/.source,/'((?:\\.|[^'])*)'/.source,/([^>\s]+)/.source],j=/^<([\w:-]+)/,k=/\s*(\/?)>/,l=/^<\/([\w:-]+)[^>]*>/,m=/\/>$/,n=/^<!DOCTYPE [^>]+>/i,o=!1;"x".replace(/x(.)?/g,function(a,b){o=""===b});var p,q,r,s=e("area,base,basefont,br,col,frame,hr,img,input,isindex,link,meta,param,embed,wbr"),t=e("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"),u=e("colgroup,dd,dt,li,options,p,td,tfoot,th,thead,tr,source"),v=e("checked,compact,declare,defer,disabled,ismap,multiple,nohref,noresize,noshade,nowrap,readonly,selected"),w=e("script,style,noscript"),x={},y=a.HTMLParser=function(a,d){function e(a,b,c,e){for(var g=!1;!d.html5&&y.last()&&t[y.last()];)f("",y.last());u[b]&&y.last()===b&&f("",b),e=s[b]||!!e;var h=[];c.replace(B,function(){var a,b,c,e,f,g,i,j=7;if(o&&-1===arguments[0].indexOf('""')&&(""===arguments[3]&&(arguments[3]=void 0),""===arguments[4]&&(arguments[4]=void 0),""===arguments[5]&&(arguments[5]=void 0)),a=arguments[1])g=arguments[2],c=arguments[3],b=c||arguments[4]||arguments[5],g&&(i=arguments[0].charAt(a.length+g.length),i="'"===i||'"'===i?i:"");else if(d.customAttrSurround)for(var k=d.customAttrSurround.length-1;k>=0;k--)if(a=arguments[k*j+7],g=arguments[k*j+8],a){c=arguments[k*j+9],b=c||arguments[k*j+10]||arguments[k*j+11],e=arguments[k*j+6],f=arguments[k*j+12];break}void 0===b&&(b=v[a]?a:c),h.push({name:a,value:b,escaped:b&&b.replace(/(^|.)("+)/g,function(a){return a.replace(/"/g,""")}),customAssign:g||"=",customOpen:e||"",customClose:f||"",quote:i||""})}),e?g=a.match(m):y.push({tag:b,attrs:h}),d.start&&d.start(b,h,e,g)}function f(a,b){var c;if(b){var e=b.toLowerCase();for(c=y.length-1;c>=0&&y[c].tag.toLowerCase()!==e;c--);}else c=0;if(c>=0){for(var f=y.length-1;f>=c;f--)d.end&&d.end(y[f].tag,y[f].attrs);y.length=c}}var g,h,i,j,k,y=[],z=a;y.last=function(){var a=this[this.length-1];return a&&a.tag};for(var A=b(d),B=c(d);a;){if(h=!0,y.last()&&w[y.last()])p=y.last().toLowerCase(),q=x[p]||(x[p]=new RegExp("([\\s\\S]*?)</"+p+"[^>]*>","i")),a=a.replace(q,function(a,b){return"script"!==p&&"style"!==p&&"noscript"!==p&&(b=b.replace(/<!--([\s\S]*?)-->/g,"$1").replace(/<!\[CDATA\[([\s\S]*?)\]\]>/g,"$1")),d.chars&&d.chars(b),""}),f("",p);else if(/^<!--/.test(a)&&(g=a.indexOf("-->"),g>=0&&(d.comment&&d.comment(a.substring(4,g)),a=a.substring(g+3),h=!1)),/^<!\[/.test(a)?(g=a.indexOf("]>"),g>=0&&(d.comment&&d.comment(a.substring(2,g+1),!0),a=a.substring(g+2),h=!1)):/^<\?/.test(a)?(g=a.indexOf("?>",2),g>=0&&(d.chars&&d.chars(a.substring(0,g+2)),a=a.substring(g+2))):/^<%/.test(a)?(g=a.indexOf("%>",2),g>=0&&(d.chars&&d.chars(a.substring(0,g+2)),a=a.substring(g+2))):(i=n.exec(a))?(d.doctype&&d.doctype(i[0]),a=a.substring(i[0].length),h=!1):/^<\//.test(a)?(i=a.match(l),i&&(a=a.substring(i[0].length),i[0].replace(l,f),j="/"+i[1].toLowerCase(),h=!1)):/^</.test(a)&&(i=a.match(A),i&&(a=a.substring(i[0].length),i[0].replace(A,e),j=i[1].toLowerCase(),h=!1)),h){g=a.indexOf("<");var C=0>g?a:a.substring(0,g);a=0>g?"":a.substring(g),r=a.match(A),r?k=r[1]:(r=a.match(l),k=r?"/"+r[1]:""),d.chars&&d.chars(C,j,k)}if(a===z)throw"Parse Error: "+a;z=a}f()};a.HTMLtoXML=function(a){var b="";return new y(a,{start:function(a,c,d){b+="<"+a;for(var e=0;e<c.length;e++)b+=" "+c[e].name+'="'+c[e].escaped+'"';b+=(d?"/":"")+">"},end:function(a){b+="</"+a+">"},chars:function(a){b+=a},comment:function(a){b+="<!--"+a+"-->"},ignore:function(a){b+=a}}),b},a.HTMLtoDOM=function(a,b){var c=e("html,head,body,title"),d={link:"head",base:"head"};b?b=b.ownerDocument||b.getOwnerDocument&&b.getOwnerDocument()||b:"undefined"!=typeof DOMDocument?b=new DOMDocument:"undefined"!=typeof document&&document.implementation&&document.implementation.createDocument?b=document.implementation.createDocument("","",null):"undefined"!=typeof ActiveX&&(b=new ActiveXObject("Msxml.DOMDocument"));var f=[],g=b.documentElement||b.getDocumentElement&&b.getDocumentElement();if(!g&&b.createElement&&!function(){var a=b.createElement("html"),c=b.createElement("head");c.appendChild(b.createElement("title")),a.appendChild(c),a.appendChild(b.createElement("body")),b.appendChild(a)}(),b.getElementsByTagName)for(var h in c)c[h]=b.getElementsByTagName(h)[0];var i=c.body;return new y(a,{start:function(a,e,g){if(c[a])return void(i=c[a]);var h=b.createElement(a);for(var j in e)h.setAttribute(e[j].name,e[j].value);d[a]&&"boolean"!=typeof c[d[a]]?c[d[a]].appendChild(h):i&&i.appendChild&&i.appendChild(h),g||(f.push(h),i=h)},end:function(){f.length-=1,i=f[f.length-1]},chars:function(a){i.appendChild(b.createTextNode(a))},comment:function(){},ignore:function(){}}),b}}("undefined"==typeof exports?this:exports),function(a){"use strict";function b(a){return a?a.replace(/[\t\n\r ]+/g," "):a}function c(a,b,c,d){var e=["a","abbr","acronym","b","bdi","bdo","big","button","cite","code","del","dfn","em","font","i","ins","kbd","mark","q","rt","rp","s","samp","small","span","strike","strong","sub","sup","svg","time","tt","u","var"],f=/^[\t ]*[\n\r]+[\t\n\r ]*/,g=/[\t\n\r ]*[\n\r]+[\t ]*$/,h=f.test(a)?"\n":" ",i=g.test(a)?"\n":" ",j="htmlmincollapsedlinebreak";return b&&"img"!==b&&"input"!==b&&("/"!==b.substr(0,1)||"/"===b.substr(0,1)&&-1===e.indexOf(b.substr(1)))&&(a=a.replace(/^\s+/,d.conservativeCollapse?" ":d.preserveLineBreaks?h:"")),c&&"img"!==c&&"input"!==c&&("/"===c.substr(0,1)||"/"!==c.substr(0,1)&&-1===e.indexOf(c))&&(a=a.replace(/\s+$/,d.conservativeCollapse?" ":d.preserveLineBreaks?i:"")),b&&c?(d.preserveLineBreaks&&(a=a.replace(f,j).replace(g,j)),a.replace(/[\t\n\r]+/g," ").replace(/[ ]+/g," ").replace(new RegExp(j,"g"),"\n")):a}function d(a){return/\[if[^\]]+\]/.test(a)||/\s*((?:<!)?\[endif\])$/.test(a)}function e(a,b){if(/^!/.test(a))return!0;if(b.ignoreCustomComments)for(var c=0,d=b.ignoreCustomComments.length;d>c;c++)if(b.ignoreCustomComments[c].test(a))return!0;return!1}function f(a){return/^on[a-z]+/.test(a)}function g(a){return/^[^\x20\t\n\f\r"'`=<>]+$/.test(a)&&!/\/$/.test(a)&&!/\/$/.test(a)}function h(a,b){for(var c=a.length;c--;)if(a[c].name.toLowerCase()===b)return!0;return!1}function i(a,b,c,d){return c=c?M(c.toLowerCase()):"","script"===a&&"language"===b&&"javascript"===c||"form"===a&&"method"===b&&"get"===c||"input"===a&&"type"===b&&"text"===c||"script"===a&&"charset"===b&&!h(d,"src")||"a"===a&&"name"===b&&h(d,"id")||"area"===a&&"shape"===b&&"rect"===c}function j(a,b,c){return"script"===a&&"type"===b&&"text/javascript"===M(c.toLowerCase())}function k(a,b){if("script"!==a)return!1;for(var c=0,d=b.length;d>c;c++){var e=b[c].name.toLowerCase();if("type"===e)return""===b[c].value||1===N[b[c].value]}return!0}function l(a,b,c){return("style"===a||"link"===a)&&"type"===b&&"text/css"===M(c.toLowerCase())}function m(a,b){var c=/^(?:allowfullscreen|async|autofocus|autoplay|checked|compact|controls|declare|default|defaultchecked|defaultmuted|defaultselected|defer|disabled|enabled|formnovalidate|hidden|indeterminate|inert|ismap|itemscope|loop|multiple|muted|nohref|noresize|noshade|novalidate|nowrap|open|pauseonexit|readonly|required|reversed|scoped|seamless|selected|sortable|spellcheck|truespeed|typemustmatch|visible)$/i.test(a);if(c)return!0;var d=O[a.toLowerCase()];return d?-1===d.indexOf(b.toLowerCase()):!1}function n(a,b){return/^(?:a|area|link|base)$/.test(b)&&"href"===a||"img"===b&&/^(?:src|longdesc|usemap)$/.test(a)||"object"===b&&/^(?:classid|codebase|data|usemap)$/.test(a)||"q"===b&&"cite"===a||"blockquote"===b&&"cite"===a||("ins"===b||"del"===b)&&"cite"===a||"form"===b&&"action"===a||"input"===b&&("src"===a||"usemap"===a)||"head"===b&&"profile"===a||"script"===b&&("src"===a||"for"===a)}function o(a,b){return/^(?:a|area|object|button)$/.test(b)&&"tabindex"===a||"input"===b&&("maxlength"===a||"tabindex"===a)||"select"===b&&("size"===a||"tabindex"===a)||"textarea"===b&&/^(?:rows|cols|tabindex)$/.test(a)||"colgroup"===b&&"span"===a||"col"===b&&"span"===a||("th"===b||"td"===b)&&("rowspan"===a||"colspan"===a)}function p(a,c,d,e,g){if(d&&f(c)){if(d=M(d).replace(/^javascript:\s*/i,"").replace(/\s*;$/,""),e.minifyJS){var h="(function(){"+d+"})()",i=G(h,e.minifyJS);return i.slice(12,i.length-4).replace(/"/g,""")}return d}return"class"===c?b(M(d)):n(c,a)?(d=M(d),e.minifyURLs?F(d,e.minifyURLs):d):o(c,a)?M(d):"style"===c?(d=M(d),d&&(d=d.replace(/\s*;\s*$/,"")),e.minifyCSS?H(d,e.minifyCSS,!0):d):(q(a,g)&&"content"===c?d=d.replace(/1\.0/g,"1").replace(/\s+/g,""):d&&e.customAttrCollapse&&e.customAttrCollapse.test(c)&&(d=d.replace(/\n+/g,"")),d)}function q(a,b){if("meta"!==a)return!1;for(var c=0,d=b.length;d>c;c++)if("name"===b[c].name&&"viewport"===b[c].value)return!0}function r(a){return"*{"+a+"}"}function s(a){var b=a.match(/^\*\{([\s\S]*)\}$/m);return b&&b[1]?b[1]:a}function t(a){return a.replace(/^(\[[^\]]+\]>)\s*/,"$1").replace(/\s*(<!\[endif\])$/,"$1")}function u(a){return a.replace(/^(?:\s*\/\*\s*<!\[CDATA\[\s*\*\/|\s*\/\/\s*<!\[CDATA\[.*)/,"").replace(/(?:\/\*\s*\]\]>\s*\*\/|\/\/\s*\]\]>)\s*$/,"")}function v(a,b,c){for(var d=0,e=c.length;e>d;d++)if("type"===c[d].name.toLowerCase()&&b.processScripts.indexOf(c[d].value)>-1)return I(a,b);return a}function w(a,b){return a.replace(P[b],"").replace(Q[b],"")}function x(a){return/^(?:html|t?body|t?head|tfoot|tr|td|th|dt|dd|option|colgroup|source)$/.test(a)}function y(a,b,c){var d=!c||/^\s*$/.test(c);return d?"input"===a&&"value"===b||R.test(b):!1}function z(a,b){if("textarea"===a)return!1;if("script"===a)for(var c=b.length-1;c>=0;c--)if("src"===b[c].name)return!1;return!0}function A(a){return!/^(?:script|style|pre|textarea)$/.test(a)}function B(a){return!/^(?:pre|textarea)$/.test(a)}function C(a){for(var b="",c=0,d=a.length;d>c;c++)b+=" "+a[c].name+(m(a[c].value)?"":'="'+a[c].value+'"');return b}function D(a,b,c,d,e,f){var h,k,n=f.caseSensitive?a.name:a.name.toLowerCase(),o=f.preventAttributesEscaping?a.value:a.escaped,q=f.preventAttributesEscaping?a.quote:'"',r=d&&e===b.length-1;return f.removeRedundantAttributes&&i(c,n,o,b)||f.removeScriptTypeAttributes&&j(c,n,o)||f.removeStyleLinkTypeAttributes&&l(c,n,o)?"":(o=p(c,n,o,f,b),k=void 0!==o&&!f.removeAttributeQuotes||!g(o)||r?q+o+q:o,f.removeEmptyAttributes&&y(c,n,o)?"":(h=void 0===o||f.collapseBooleanAttributes&&m(n,o)?n:n+a.customAssign+k," "+a.customOpen+h+a.customClose))}function E(a){for(var b=["canCollapseWhitespace","canTrimWhitespace"],c=0,d=b.length;d>c;c++)a[b[c]]||(a[b[c]]=function(){return!1})}function F(b,c){"object"!=typeof c&&(c={});try{var d=a.RelateUrl;return"undefined"==typeof d&&"function"==typeof require&&(d=require("relateurl")),d&&d.relate?d.relate(b,c):b}catch(e){K(e)}return b}function G(b,c){"object"!=typeof c&&(c={}),c.fromString=!0;var d=c.output||{};d.inline_script=!0,c.output=d;try{var e=a.UglifyJS;if("undefined"==typeof e&&"function"==typeof require&&(e=require("uglify-js")),!e)return b;if(e.minify)return e.minify(b,c).code;if(e.parse){var f=e.parse(b);f.figure_out_scope();var g=e.Compressor(),h=f.transform(g);h.figure_out_scope(),h.compute_char_frequency(),c.mangle!==!1&&h.mangle_names();var i=e.OutputStream(c.output);return h.print(i),i.toString()}return b}catch(j){K(j)}return b}function H(a,b,c){"object"!=typeof b&&(b={}),"undefined"==typeof b.advanced&&(b.advanced=!1);try{var d;if("undefined"!=typeof CleanCSS)d=new CleanCSS(b);else if("function"==typeof require){var e=require("clean-css");d=new e(b)}return c?s(d.minify(r(a)).styles):d.minify(a).styles}catch(f){K(f)}return a}function I(a,f){function g(a,b){return A(a)||f.canCollapseWhitespace(a,b)}function h(a,b){return B(a)||f.canTrimWhitespace(a,b)}f=f||{};var i=[];a=M(a),E(f);var j=[],l=[],m="",n="",o=[],p=[],q=[],r=f.lint,s=!1,y=new Date;f.removeIgnored&&(a=a.replace(/<\?[^\?]+\?>/g,"").replace(/<%[^%]+%>/g,"")),new L(a,{html5:"undefined"!=typeof f.html5?f.html5:!0,start:function(a,b,c,d){if(s)return void l.push("<"+a,C(b),d?"/":"",">");var e=a.toLowerCase();if("svg"===e){i.push(f);var j={};for(var k in f)j[k]=f[k];j.keepClosingSlash=!0,j.caseSensitive=!0,f=j}a=f.caseSensitive?a:e,n=a,m="",o=b,f.collapseWhitespace&&(h(a,b)||p.push(a),g(a,b)||q.push(a));var t="<"+a,u=(d&&f.keepClosingSlash?"/":"")+">";0===b.length&&(t+=u),l.push(t),r&&r.testElement(a);for(var v,w=0,x=b.length;x>w;w++)r&&r.testAttribute(a,b[w].name.toLowerCase(),b[w].escaped),v=D(b[w],b,a,d,w,f),w===x-1&&(v+=u),l.push(v)},end:function(a,b){if(s)return void l.push("</"+a+">");var c=a.toLowerCase();"svg"===c&&(f=i.pop()),f.collapseWhitespace&&(p.length&&a===p[p.length-1]&&p.pop(),q.length&&a===q[q.length-1]&&q.pop());var d=""===m&&a===n;if(f.removeEmptyElements&&d&&z(a,b)){for(var e=l.length-1;e>=0;e--)if(/^<[^\/!]/.test(l[e])){l.splice(e);break}}else f.removeOptionalTags&&x(a)||(l.push("</"+(f.caseSensitive?a:c)+">"),j.push.apply(j,l),l.length=0,m="")},chars:function(a,d,e){return d=""===d?"comment":d,e=""===e?"comment":e,s?void l.push(a):(("script"===n||"style"===n)&&(f.removeCommentsFromCDATA&&(a=w(a,n)),f.removeCDATASectionsFromCDATA&&(a=u(a)),f.processScripts&&(a=v(a,f,o))),f.minifyJS&&k(n,o)&&(a=G(a,f.minifyJS)),"style"===n&&f.minifyCSS&&(a=H(a,f.minifyCSS)),f.collapseWhitespace&&(p.length||(a=d&&"comment"!==d||e&&"comment"!==e?c(a,d,e,f):M(a)),q.length||(a=d&&e||"html"===e?a:b(a))),m=a,r&&r.testChars(a),void l.push(a))},comment:function(a,b){var c=b?"<!":"<!--",g=b?">":"-->";return/^\s*htmlmin:ignore/.test(a)?(s=!s,void(f.removeComments||l.push("<!--"+a+"-->"))):(a=f.removeComments?d(a)?c+t(a)+g:e(a,f)?"<!--"+a+"-->":"":c+a+g,void l.push(a))},doctype:function(a){l.push(f.useShortDoctype?"<!DOCTYPE html>":b(a))},customAttrAssign:f.customAttrAssign,customAttrSurround:f.customAttrSurround}),j.push.apply(j,l);var F=J(j,f);return K("minified in: "+(new Date-y)+"ms"),F}function J(a,b){var c,d=b.maxLineLength;if(d){for(var e,f=[],g="",h=0,i=a.length;i>h;h++)e=a[h],g.length+e.length<d?g+=e:(f.push(g.replace(/^\n/,"")),g=e);f.push(g),c=f.join("\n")}else c=a.join("");return c}var K,L;K=a.console&&a.console.log?function(b){a.console.log(b)}:function(){},a.HTMLParser?L=a.HTMLParser:"function"==typeof require&&(L=require("./htmlparser").HTMLParser);var M=function(a){return"string"!=typeof a?a:a.replace(/^\s+/,"").replace(/\s+$/,"")};String.prototype.trim&&(M=function(a){return"string"!=typeof a?a:a.trim()});var N={"text/javascript":1,"text/ecmascript":1,"text/jscript":1,"application/javascript":1,"application/x-javascript":1,"application/ecmascript":1},O={draggable:["true","false"]},P={script:/^\s*(?:\/\/)?\s*<!--.*\n?/,style:/^\s*<!--\s*/},Q={script:/\s*(?:\/\/)?\s*-->\s*$/,style:/\s*-->\s*$/},R=new RegExp("^(?:class|id|style|title|lang|dir|on(?:focus|blur|change|click|dblclick|mouse(?:down|up|over|move|out)|key(?:press|down|up)))$");"undefined"!=typeof exports?exports.minify=I:a.minify=I}(this),function(a){"use strict";function b(a){return/^(?:big|small|hr|blink|marquee)$/.test(a)}function c(a){return/^(?:applet|basefont|center|dir|font|isindex|strike)$/.test(a)}function d(a){return/^on[a-z]+/.test(a)}function e(a){return"style"===a.toLowerCase()}function f(a,b){return"align"===b&&/^(?:caption|applet|iframe|img|imput|object|legend|table|hr|div|h[1-6]|p)$/.test(a)||"alink"===b&&"body"===a||"alt"===b&&"applet"===a||"archive"===b&&"applet"===a||"background"===b&&"body"===a||"bgcolor"===b&&/^(?:table|t[rdh]|body)$/.test(a)||"border"===b&&/^(?:img|object)$/.test(a)||"clear"===b&&"br"===a||"code"===b&&"applet"===a||"codebase"===b&&"applet"===a||"color"===b&&/^(?:base(?:font)?)$/.test(a)||"compact"===b&&/^(?:dir|[dou]l|menu)$/.test(a)||"face"===b&&/^base(?:font)?$/.test(a)||"height"===b&&/^(?:t[dh]|applet)$/.test(a)||"hspace"===b&&/^(?:applet|img|object)$/.test(a)||"language"===b&&"script"===a||"link"===b&&"body"===a||"name"===b&&"applet"===a||"noshade"===b&&"hr"===a||"nowrap"===b&&/^t[dh]$/.test(a)||"object"===b&&"applet"===a||"prompt"===b&&"isindex"===a||"size"===b&&/^(?:hr|font|basefont)$/.test(a)||"start"===b&&"ol"===a||"text"===b&&"body"===a||"type"===b&&/^(?:li|ol|ul)$/.test(a)||"value"===b&&"li"===a||"version"===b&&"html"===a||"vlink"===b&&"body"===a||"vspace"===b&&/^(?:applet|img|object)$/.test(a)||"width"===b&&/^(?:hr|td|th|applet|pre)$/.test(a)}function g(a,b){return"href"===a&&/^\s*javascript\s*:\s*void\s*(\s+0|\(\s*0\s*\))\s*$/i.test(b)}function h(){this.log=[],this._lastElement=null,this._isElementRepeated=!1}h.prototype.testElement=function(a){c(a)?this.log.push('Found <span class="deprecated-element">deprecated</span> <strong><code><'+a+"></code></strong> element"):b(a)?this.log.push('Found <span class="presentational-element">presentational</span> <strong><code><'+a+"></code></strong> element"):this.checkRepeatingElement(a)},h.prototype.checkRepeatingElement=function(a){"br"===a&&"br"===this._lastElement?this._isElementRepeated=!0:this._isElementRepeated&&(this._reportRepeatingElement(),this._isElementRepeated=!1),this._lastElement=a},h.prototype._reportRepeatingElement=function(){this.log.push("Found <code><br></code> sequence. Try replacing it with styling.")},h.prototype.testAttribute=function(a,b,c){d(b)?this.log.push('Found <span class="event-attribute">event attribute</span> (<strong>'+b+"</strong>) on <strong><code><"+a+"></code></strong> element."):f(a,b)?this.log.push('Found <span class="deprecated-attribute">deprecated</span> <strong>'+b+"</strong> attribute on <strong><code><"+a+"></code></strong> element."):e(b)?this.log.push('Found <span class="style-attribute">style attribute</span> on <strong><code><'+a+"></code></strong> element."):g(b,c)&&this.log.push('Found <span class="inaccessible-attribute">inaccessible attribute</span> (on <strong><code><'+a+"></code></strong> element).")},h.prototype.testChars=function(a){this._lastElement="",/( \s*){2,}/.test(a)&&this.log.push("Found repeating <strong><code>&nbsp;</code></strong> sequence. Try replacing it with styling.")},h.prototype.test=function(a,b,c){this.testElement(a),this.testAttribute(a,b,c)},h.prototype.populate=function(a){if(this._isElementRepeated&&this._reportRepeatingElement(),this.log.length)if(a)a.innerHTML="<ol><li>"+this.log.join("<li>")+"</ol>";else{var b=" - "+this.log.join("\n - ").replace(/(<([^>]+)>)/gi,"").replace(/</g,"<").replace(/>/g,">");console.log(b)}},a.HTMLLint=h}("undefined"==typeof exports?this:exports);
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "html-minifier",
|
|
3
3
|
"description": "HTML minifier with lint-like capabilities.",
|
|
4
|
-
"version": "0.
|
|
4
|
+
"version": "0.7.2",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"html",
|
|
7
7
|
"minifier",
|
|
@@ -39,24 +39,26 @@
|
|
|
39
39
|
"test": "grunt test"
|
|
40
40
|
},
|
|
41
41
|
"dependencies": {
|
|
42
|
-
"change-case": "2.
|
|
43
|
-
"clean-css": "
|
|
42
|
+
"change-case": "2.3.x",
|
|
43
|
+
"clean-css": "3.1.x",
|
|
44
44
|
"cli": "0.6.x",
|
|
45
|
+
"concat-stream": "1.4.x",
|
|
45
46
|
"uglify-js": "2.4.x",
|
|
46
47
|
"relateurl": "0.2.x"
|
|
47
48
|
},
|
|
48
49
|
"devDependencies": {
|
|
50
|
+
"chalk": "1.0.x",
|
|
49
51
|
"cli-table": "0.3.x",
|
|
50
52
|
"grunt": "0.4.x",
|
|
51
53
|
"grunt-contrib-concat": "0.5.x",
|
|
52
|
-
"grunt-contrib-jshint": "0.
|
|
53
|
-
"grunt-contrib-qunit": "0.
|
|
54
|
-
"grunt-contrib-uglify": "0.
|
|
54
|
+
"grunt-contrib-jshint": "0.11.x",
|
|
55
|
+
"grunt-contrib-qunit": "0.7.x",
|
|
56
|
+
"grunt-contrib-uglify": "0.8.x",
|
|
55
57
|
"grunt-exec": "0.4.x",
|
|
56
|
-
"grunt-jscs": "
|
|
57
|
-
"load-grunt-tasks": "
|
|
58
|
+
"grunt-jscs": "1.6.x",
|
|
59
|
+
"load-grunt-tasks": "3.1.x",
|
|
58
60
|
"qunit": "0.7.x",
|
|
59
|
-
"time-grunt": "1.
|
|
61
|
+
"time-grunt": "1.1.x"
|
|
60
62
|
},
|
|
61
63
|
"files": [
|
|
62
64
|
"dist",
|