html-minifier 0.6.5 → 0.6.9
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 +29 -6
- package/README.md +36 -19
- package/cli.js +48 -37
- package/dist/htmlminifier.js +357 -79
- package/dist/htmlminifier.min.js +2 -2
- package/package.json +8 -8
package/CHANGELOG.md
CHANGED
|
@@ -1,30 +1,53 @@
|
|
|
1
|
-
## [0.6.
|
|
1
|
+
## [0.6.7](https://github.com/kangax/html-minifier/compare/v0.6.6...v0.6.7)
|
|
2
|
+
|
|
3
|
+
* Preserve empty script with `src` attribute
|
|
4
|
+
* Make `draggable` enumerated attribute
|
|
5
|
+
* Add option to preserve a single line break on collapse
|
|
6
|
+
* Do not treat draggable as a boolean attribute
|
|
7
|
+
* Add `minifyURLs` option
|
|
8
|
+
* Add `customAttrCollapse` option
|
|
9
|
+
* `collapseBoolean` is case-insensitive
|
|
10
|
+
* Remove removable attrs with unspecified values
|
|
11
|
+
* `removeComments` affects htmlmin:ignore comments
|
|
12
|
+
* Quote terminal attribute value by unary slash
|
|
13
|
+
* Closing tag search is case-insensitive
|
|
14
|
+
* `s` tag has been reinstated
|
|
15
|
+
* Remove `i`, `b`, `u` tags from linter as problematic
|
|
16
|
+
|
|
17
|
+
## [0.6.6](https://github.com/kangax/html-minifier/compare/v0.6.5...v0.6.6)
|
|
18
|
+
|
|
19
|
+
* Fix Firefox attribute bug
|
|
20
|
+
* Add `customAttrAssign` option
|
|
21
|
+
* Add `maxLineLength` option
|
|
22
|
+
* Add `customAttrSurround` option
|
|
23
|
+
|
|
24
|
+
## [0.6.5](https://github.com/kangax/html-minifier/compare/v0.6.4...v0.6.5)
|
|
2
25
|
|
|
3
26
|
* `caseSensitive` option now applies to tags and attributes
|
|
4
27
|
|
|
5
|
-
## [0.6.4](https://github.com/kangax/html-minifier/compare/v0.6.3...
|
|
28
|
+
## [0.6.4](https://github.com/kangax/html-minifier/compare/v0.6.3...v0.6.4)
|
|
6
29
|
|
|
7
30
|
* Support for mixed-case tags
|
|
8
31
|
* Support IE downlevel-revealed conditional comments
|
|
9
32
|
* Add support for `wbr` element
|
|
10
33
|
|
|
11
|
-
## [0.6.3](https://github.com/kangax/html-minifier/compare/v0.6.2...
|
|
34
|
+
## [0.6.3](https://github.com/kangax/html-minifier/compare/v0.6.2...v0.6.3)
|
|
12
35
|
|
|
13
36
|
* Do not treat `translate` attribute as boolean
|
|
14
37
|
* Add `svg` element in inline list
|
|
15
38
|
* Do not remove special spaces like ` `
|
|
16
39
|
* Make `collapseWhitespace` more resilient
|
|
17
40
|
|
|
18
|
-
## [0.6.2](https://github.com/kangax/html-minifier/compare/v0.6.1...
|
|
41
|
+
## [0.6.2](https://github.com/kangax/html-minifier/compare/v0.6.1...v0.6.2)
|
|
19
42
|
|
|
20
43
|
* Fix bug introduced by `processScripts` option
|
|
21
44
|
|
|
22
|
-
## [0.6.1](https://github.com/kangax/html-minifier/compare/v0.6.0...
|
|
45
|
+
## [0.6.1](https://github.com/kangax/html-minifier/compare/v0.6.0...v0.6.1)
|
|
23
46
|
|
|
24
47
|
* Add CLI
|
|
25
48
|
* Fix error with valueless attributes (e.g. `<a href>`). [#169](https://github.com/kangax/html-minifier/issues/169)
|
|
26
49
|
|
|
27
|
-
## [0.6.0](https://github.com/kangax/html-minifier/compare/v0.5.6...
|
|
50
|
+
## [0.6.0](https://github.com/kangax/html-minifier/compare/v0.5.6...v0.6.0)
|
|
28
51
|
|
|
29
52
|
* Minify meta viewport value [#159](https://github.com/kangax/html-minifier/issues/159)
|
|
30
53
|
* Add support for ignoring markup via `<!-- htmlmin:ignore -->` [#89](https://github.com/kangax/html-minifier/issues/89)
|
package/README.md
CHANGED
|
@@ -9,17 +9,17 @@ See [corresponding blog post](http://perfectionkills.com/experimenting-with-html
|
|
|
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
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
|
-
| [ES6 table](http://kangax.github.io/es5-compat-table/es6/) | 117.9 | <b>79.9</b>
|
|
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,52 +34,69 @@ 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` | 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` |
|
|
37
38
|
| `collapseBooleanAttributes` | [Omit attribute values from boolean attributes](http://perfectionkills.com/experimenting-with-html-minifier/#collapse_boolean_attributes) | `false` |
|
|
38
39
|
| `removeAttributeQuotes` | [Remove quotes around attributes when possible.](http://perfectionkills.com/experimenting-with-html-minifier/#remove_attribute_quotes) | `false` |
|
|
39
40
|
| `removeRedundantAttributes` | [Remove attributes when value matches default.](http://perfectionkills.com/experimenting-with-html-minifier/#remove_redundant_attributes) | `false` |
|
|
40
41
|
| `useShortDoctype` | [Replaces the doctype with the short (HTML5) doctype](http://perfectionkills.com/experimenting-with-html-minifier/#use_short_doctype) | `false` |
|
|
41
42
|
| `removeEmptyAttributes` | [Remove all attributes with whitespace-only values](http://perfectionkills.com/experimenting-with-html-minifier/#remove_empty_or_blank_attributes) | `false` |
|
|
43
|
+
| `removeScriptTypeAttributes` | Remove `type="text/javascript"` from `script` tags. Other `type` attribute values are left intact. | `false` |
|
|
44
|
+
| `removeStyleLinkTypeAttributes`| Remove `type="text/css"` from `style` and `link` tags. Other `type` attribute values are left intact. | `false` |
|
|
42
45
|
| `removeOptionalTags` | [Remove unrequired tags](http://perfectionkills.com/experimenting-with-html-minifier/#remove_optional_tags) | `false` |
|
|
46
|
+
| `removeIgnored` | Remove all tags starting and ending with `<%`, `%>`, `<?`, `?>` | `false` |
|
|
43
47
|
| `removeEmptyElements` | [Remove all elements with empty contents](http://perfectionkills.com/experimenting-with-html-minifier/#remove_empty_elements) | `false` |
|
|
44
48
|
| `lint` | [Toggle linting](http://perfectionkills.com/experimenting-with-html-minifier/#validate_input_through_html_lint) | `false` |
|
|
45
49
|
| `keepClosingSlash` | Keep the trailing slash on singleton elements | `false` |
|
|
46
50
|
| `caseSensitive` | Treat attributes in case sensitive manner (useful for SVG; e.g. viewBox) | `false` |
|
|
47
51
|
| `minifyJS` | Minify Javascript in script elements and on* attributes (uses [UglifyJS](https://github.com/mishoo/UglifyJS2)) | `false` (could be `true`, `false`, `Object` (options)) |
|
|
48
|
-
| `minifyCSS` | Minify CSS in style elements and style attributes (uses [clean-css](https://github.com/GoalSmashers/clean-css))
|
|
49
|
-
| `
|
|
50
|
-
| `
|
|
52
|
+
| `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
|
+
| `minifyURLs` | Minify URLs in various attributes (uses [relateurl](https://github.com/stevenvachon/relateurl)) | `false` (could be `Object` (options)) |
|
|
54
|
+
| `ignoreCustomComments` | Array of regex'es that allow to ignore certain comments, when matched | `[ ]` |
|
|
55
|
+
| `processScripts` | Array of strings corresponding to types of script elements to process through minifier (e.g. `text/ng-template`, `text/x-handlebars-template`, etc.) | `[ ]` |
|
|
56
|
+
| `maxLineLength` | Specify a maximum line length. Compressed output will be split by newlines at valid HTML split-points. |
|
|
57
|
+
| `customAttrAssign` | Arrays of regex'es that allow to support custom attribute assign expressions (e.g. `'<div flex?="{{mode != cover}}"></div>'`) | `[ ]` |
|
|
58
|
+
| `customAttrSurround` | Arrays of regex'es that allow to support custom attribute surround expressions (e.g. `<input {{#if value}}checked="checked"{{/if}}>`) | `[ ]` |
|
|
59
|
+
| `customAttrCollapse` | Regex that specifies custom attribute to strip newlines from (e.g. `/ng\-class/`) | |
|
|
60
|
+
|
|
51
61
|
|
|
52
62
|
Chunks of markup can be ignored by wrapping them with `<!-- htmlmin:ignore -->`.
|
|
53
63
|
|
|
54
|
-
Installation Instructions
|
|
55
|
-
-------------------------
|
|
64
|
+
## Installation Instructions
|
|
56
65
|
|
|
57
66
|
From NPM for use as a command line app:
|
|
58
|
-
```
|
|
67
|
+
```bash
|
|
59
68
|
npm install html-minifier -g
|
|
60
69
|
```
|
|
61
70
|
|
|
62
71
|
From NPM for programmatic use:
|
|
63
|
-
```
|
|
72
|
+
```bash
|
|
64
73
|
npm install html-minifier
|
|
65
74
|
```
|
|
66
75
|
|
|
67
76
|
From Git:
|
|
68
|
-
```
|
|
77
|
+
```bash
|
|
69
78
|
git clone git://github.com/kangax/html-minifier.git
|
|
70
79
|
cd html-minifier
|
|
71
80
|
npm link .
|
|
72
81
|
```
|
|
73
82
|
|
|
74
|
-
Usage
|
|
75
|
-
|
|
83
|
+
## Usage
|
|
84
|
+
|
|
76
85
|
For command line usage please see `html-minifier --help`
|
|
77
86
|
|
|
78
|
-
Node.js
|
|
79
|
-
========
|
|
80
|
-
```
|
|
81
|
-
require('html-minifier')
|
|
82
|
-
```
|
|
87
|
+
## Node.js
|
|
83
88
|
|
|
89
|
+
```js
|
|
90
|
+
var minify = require('html-minifier').minify;
|
|
91
|
+
var result = minify('<p title="blah" id="moo">foo</p>', {
|
|
92
|
+
removeAttributeQuotes: true
|
|
93
|
+
});
|
|
94
|
+
result; // '<p title=blah id=moo>foo</p>'
|
|
95
|
+
```
|
|
84
96
|
|
|
85
|
-
|
|
97
|
+
Running benchmarks
|
|
98
|
+
------------------
|
|
99
|
+
Benchmarks for minified HTML:
|
|
100
|
+
```
|
|
101
|
+
node benchmark.js
|
|
102
|
+
```
|
package/cli.js
CHANGED
|
@@ -53,25 +53,28 @@ usage += ' on the command line you must escape those such as --ignore-custom-
|
|
|
53
53
|
cli.setUsage(usage);
|
|
54
54
|
|
|
55
55
|
var mainOptions = {
|
|
56
|
-
removeComments: [[false, 'Strip HTML comments']
|
|
57
|
-
removeCommentsFromCDATA: [[false, 'Strip HTML comments from scripts and styles']
|
|
58
|
-
removeCDATASectionsFromCDATA: [[false, 'Remove CDATA sections from script and style elements']
|
|
59
|
-
collapseWhitespace: [[false, 'Collapse white space that contributes to text nodes in a document tree.']
|
|
60
|
-
conservativeCollapse: [[false, 'Always collapse to 1 space (never remove it entirely)']
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
56
|
+
removeComments: [[false, 'Strip HTML comments']],
|
|
57
|
+
removeCommentsFromCDATA: [[false, 'Strip HTML comments from scripts and styles']],
|
|
58
|
+
removeCDATASectionsFromCDATA: [[false, 'Remove CDATA sections from script and style elements']],
|
|
59
|
+
collapseWhitespace: [[false, 'Collapse white space that contributes to text nodes in a document tree.']],
|
|
60
|
+
conservativeCollapse: [[false, 'Always collapse to 1 space (never remove it entirely)']],
|
|
61
|
+
preserveLineBreaks: [[false, 'Always collapse to 1 line break (never remove it entirely) when whitespace between tags include a line break.']],
|
|
62
|
+
collapseBooleanAttributes: [[false, 'Omit attribute values from boolean attributes']],
|
|
63
|
+
removeAttributeQuotes: [[false, 'Remove quotes around attributes when possible.']],
|
|
64
|
+
removeRedundantAttributes: [[false, 'Remove attributes when value matches default.']],
|
|
65
|
+
useShortDoctype: [[false, 'Replaces the doctype with the short (HTML5) doctype']],
|
|
66
|
+
removeEmptyAttributes: [[false, 'Remove all attributes with whitespace-only values']],
|
|
67
|
+
removeOptionalTags: [[false, 'Remove unrequired tags']],
|
|
68
|
+
removeEmptyElements: [[false, 'Remove all elements with empty contents']],
|
|
69
|
+
lint: [[false, 'Toggle linting']],
|
|
70
|
+
keepClosingSlash: [[false, 'Keep the trailing slash on singleton elements']],
|
|
71
|
+
caseSensitive: [[false, 'Treat attributes in case sensitive manner (useful for SVG; e.g. viewBox)']],
|
|
72
|
+
minifyJS: [[false, 'Minify Javascript in script elements and on* attributes (uses UglifyJS)']],
|
|
73
|
+
minifyCSS: [[false, 'Minify CSS in style elements and style attributes (uses clean-css)']],
|
|
74
|
+
minifyURLs: [[false, 'Minify URLs in various attributes (uses relateurl)']],
|
|
75
|
+
ignoreCustomComments: [[false, 'Array of regex\'es that allow to ignore certain comments, when matched', 'string'], 'json'],
|
|
76
|
+
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'],
|
|
77
|
+
maxLineLength: [[false, 'Max line length', 'number'], true]
|
|
75
78
|
};
|
|
76
79
|
|
|
77
80
|
var cliOptions = {
|
|
@@ -109,25 +112,17 @@ cli.main(function(args, options) {
|
|
|
109
112
|
|
|
110
113
|
mainOptionKeys.forEach(function(key) {
|
|
111
114
|
var paramKey = changeCase.paramCase(key);
|
|
115
|
+
var value = options[paramKey];
|
|
112
116
|
if (options[paramKey] !== null) {
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
minifyOptions[key] = jsonArray;
|
|
123
|
-
}
|
|
124
|
-
else {
|
|
125
|
-
minifyOptions[key] = [value];
|
|
126
|
-
}
|
|
127
|
-
}
|
|
128
|
-
}
|
|
129
|
-
else {
|
|
130
|
-
minifyOptions[key] = true;
|
|
117
|
+
switch (mainOptions[key][1]) {
|
|
118
|
+
case 'json':
|
|
119
|
+
minifyOptions[key] = parseJSONOption(value);
|
|
120
|
+
break;
|
|
121
|
+
case true:
|
|
122
|
+
minifyOptions[key] = value;
|
|
123
|
+
break;
|
|
124
|
+
default:
|
|
125
|
+
minifyOptions[key] = true;
|
|
131
126
|
}
|
|
132
127
|
}
|
|
133
128
|
});
|
|
@@ -196,6 +191,22 @@ cli.main(function(args, options) {
|
|
|
196
191
|
|
|
197
192
|
}
|
|
198
193
|
|
|
194
|
+
function parseJSONOption(value) {
|
|
195
|
+
if (value !== null) {
|
|
196
|
+
var jsonArray;
|
|
197
|
+
try {
|
|
198
|
+
jsonArray = JSON.parse(value);
|
|
199
|
+
}
|
|
200
|
+
catch (e) {}
|
|
201
|
+
if (jsonArray instanceof Array) {
|
|
202
|
+
return jsonArray;
|
|
203
|
+
}
|
|
204
|
+
else {
|
|
205
|
+
return [value];
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
|
|
199
210
|
// Run minify
|
|
200
211
|
var minified = null;
|
|
201
212
|
try {
|
package/dist/htmlminifier.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/*!
|
|
2
|
-
* HTMLMinifier v0.6.
|
|
2
|
+
* HTMLMinifier v0.6.9 (http://kangax.github.io/html-minifier/)
|
|
3
3
|
* Copyright 2010-2014 Juriy "kangax" Zaytsev
|
|
4
4
|
* Licensed under MIT (https://github.com/kangax/html-minifier/blob/gh-pages/LICENSE)
|
|
5
5
|
*/
|
|
@@ -37,13 +37,24 @@
|
|
|
37
37
|
'use strict';
|
|
38
38
|
|
|
39
39
|
// Regular Expressions for parsing tags and attributes
|
|
40
|
-
var
|
|
40
|
+
var singleAttrIdentifier = /([\w:.-]+)/,
|
|
41
|
+
singleAttrAssign = /=/,
|
|
42
|
+
singleAttrAssigns = [ singleAttrAssign ],
|
|
43
|
+
singleAttrValues = [
|
|
44
|
+
/"((?:\\.|[^"])*)"/.source, // attr value double quotes
|
|
45
|
+
/'((?:\\.|[^'])*)'/.source, // attr value, single quotes
|
|
46
|
+
/([^>\s]+)/.source // attr value, no quotes
|
|
47
|
+
],
|
|
48
|
+
startTagOpen = /^<([\w:-]+)/,
|
|
49
|
+
startTagClose = /\s*(\/?)>/,
|
|
41
50
|
endTag = /^<\/([\w:-]+)[^>]*>/,
|
|
42
51
|
endingSlash = /\/>$/,
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
52
|
+
doctype = /^<!DOCTYPE [^>]+>/i;
|
|
53
|
+
|
|
54
|
+
var IS_REGEX_CAPTURING_BROKEN = false;
|
|
55
|
+
'x'.replace(/x(.)?/g, function(m, g) {
|
|
56
|
+
IS_REGEX_CAPTURING_BROKEN = g === '';
|
|
57
|
+
});
|
|
47
58
|
|
|
48
59
|
// Empty Elements - HTML 4.01
|
|
49
60
|
var empty = makeMap('area,base,basefont,br,col,frame,hr,img,input,isindex,link,meta,param,embed,wbr');
|
|
@@ -66,12 +77,91 @@
|
|
|
66
77
|
|
|
67
78
|
var reCache = {}, stackedTag, reStackedTag, tagMatch;
|
|
68
79
|
|
|
80
|
+
function startTagForHandler( handler ) {
|
|
81
|
+
var customStartTagAttrs;
|
|
82
|
+
|
|
83
|
+
var startTagAttrs = new RegExp(
|
|
84
|
+
'(?:\\s*[\\w:.-]+'
|
|
85
|
+
+ '(?:\\s*'
|
|
86
|
+
+ '(?:' + joinSingleAttrAssigns(handler) + ')'
|
|
87
|
+
+ '\\s*(?:(?:"[^"]*")|(?:\'[^\']*\')|[^>\\s]+)'
|
|
88
|
+
+ ')?'
|
|
89
|
+
+ ')*'
|
|
90
|
+
);
|
|
91
|
+
|
|
92
|
+
if ( handler.customAttrSurround ) {
|
|
93
|
+
var attrClauses = [];
|
|
94
|
+
|
|
95
|
+
for ( var i = handler.customAttrSurround.length - 1; i >= 0; i-- ) {
|
|
96
|
+
// Capture the custom attribute opening and closing markup surrounding the standard attribute rules
|
|
97
|
+
attrClauses[i] = '(?:\\s*'
|
|
98
|
+
+ handler.customAttrSurround[i][0].source
|
|
99
|
+
+ startTagAttrs.source
|
|
100
|
+
+ handler.customAttrSurround[i][1].source
|
|
101
|
+
+ ')';
|
|
102
|
+
}
|
|
103
|
+
attrClauses.unshift(startTagAttrs.source);
|
|
104
|
+
|
|
105
|
+
customStartTagAttrs = new RegExp(
|
|
106
|
+
'((?:' + attrClauses.join('|') + ')*)'
|
|
107
|
+
);
|
|
108
|
+
}
|
|
109
|
+
else {
|
|
110
|
+
// No custom attribute wrappers specified, so just capture the standard attribute rules
|
|
111
|
+
customStartTagAttrs = new RegExp('(' + startTagAttrs.source + ')');
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
return new RegExp(startTagOpen.source + customStartTagAttrs.source + startTagClose.source);
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
function attrForHandler( handler ) {
|
|
118
|
+
var singleAttr = new RegExp(
|
|
119
|
+
singleAttrIdentifier.source
|
|
120
|
+
+ '(?:\\s*'
|
|
121
|
+
+ '(' + joinSingleAttrAssigns( handler ) + ')'
|
|
122
|
+
+ '\\s*'
|
|
123
|
+
+ '(?:'
|
|
124
|
+
+ singleAttrValues.join('|')
|
|
125
|
+
+ ')'
|
|
126
|
+
+ ')?'
|
|
127
|
+
);
|
|
128
|
+
|
|
129
|
+
if ( handler.customAttrSurround ) {
|
|
130
|
+
var attrClauses = [];
|
|
131
|
+
for ( var i = handler.customAttrSurround.length - 1; i >= 0; i-- ) {
|
|
132
|
+
attrClauses[i] = '(?:'
|
|
133
|
+
+ '(' + handler.customAttrSurround[i][0].source + ')'
|
|
134
|
+
+ singleAttr.source
|
|
135
|
+
+ '(' + handler.customAttrSurround[i][1].source + ')'
|
|
136
|
+
+ ')';
|
|
137
|
+
}
|
|
138
|
+
attrClauses.unshift('(?:' + singleAttr.source + ')');
|
|
139
|
+
|
|
140
|
+
return new RegExp(attrClauses.join('|'), 'g');
|
|
141
|
+
}
|
|
142
|
+
else {
|
|
143
|
+
return new RegExp(singleAttr.source, 'g');
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
function joinSingleAttrAssigns( handler ) {
|
|
148
|
+
return singleAttrAssigns.concat(
|
|
149
|
+
handler.customAttrAssign || []
|
|
150
|
+
).map(function (assign) {
|
|
151
|
+
return '(?:' + assign.source + ')';
|
|
152
|
+
}).join('|');
|
|
153
|
+
}
|
|
154
|
+
|
|
69
155
|
var HTMLParser = global.HTMLParser = function( html, handler ) {
|
|
70
156
|
var index, chars, match, stack = [], last = html, prevTag, nextTag;
|
|
71
157
|
stack.last = function() {
|
|
72
|
-
|
|
158
|
+
var last = this[ this.length - 1 ];
|
|
159
|
+
return last && last.tag;
|
|
73
160
|
};
|
|
74
161
|
|
|
162
|
+
var startTag = startTagForHandler(handler);
|
|
163
|
+
var attr = attrForHandler(handler);
|
|
164
|
+
|
|
75
165
|
while ( html ) {
|
|
76
166
|
chars = true;
|
|
77
167
|
|
|
@@ -79,7 +169,7 @@
|
|
|
79
169
|
if ( !stack.last() || !special[ stack.last() ] ) {
|
|
80
170
|
|
|
81
171
|
// Comment:
|
|
82
|
-
if (
|
|
172
|
+
if ( /^<!--/.test( html ) ) {
|
|
83
173
|
index = html.indexOf('-->');
|
|
84
174
|
|
|
85
175
|
if ( index >= 0 ) {
|
|
@@ -92,7 +182,7 @@
|
|
|
92
182
|
}
|
|
93
183
|
|
|
94
184
|
// http://en.wikipedia.org/wiki/Conditional_comment#Downlevel-revealed_conditional_comment
|
|
95
|
-
if (
|
|
185
|
+
if ( /^<!\[/.test( html ) ) {
|
|
96
186
|
index = html.indexOf(']>');
|
|
97
187
|
|
|
98
188
|
if (index >= 0) {
|
|
@@ -105,13 +195,23 @@
|
|
|
105
195
|
}
|
|
106
196
|
|
|
107
197
|
// Ignored elements?
|
|
108
|
-
else if (
|
|
109
|
-
index = html.
|
|
110
|
-
if (index >= 0) {
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
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 );
|
|
115
215
|
}
|
|
116
216
|
}
|
|
117
217
|
|
|
@@ -125,7 +225,7 @@
|
|
|
125
225
|
}
|
|
126
226
|
|
|
127
227
|
// End tag:
|
|
128
|
-
else if (
|
|
228
|
+
else if ( /^<\//.test( html ) ) {
|
|
129
229
|
match = html.match( endTag );
|
|
130
230
|
|
|
131
231
|
if ( match ) {
|
|
@@ -137,9 +237,8 @@
|
|
|
137
237
|
|
|
138
238
|
// Start tag:
|
|
139
239
|
}
|
|
140
|
-
else if (
|
|
240
|
+
else if ( /^</.test( html ) ) {
|
|
141
241
|
match = html.match( startTag );
|
|
142
|
-
|
|
143
242
|
if ( match ) {
|
|
144
243
|
html = html.substring( match[0].length );
|
|
145
244
|
match[0].replace( startTag, parseStartTag );
|
|
@@ -220,31 +319,67 @@
|
|
|
220
319
|
|
|
221
320
|
unary = empty[ tagName ] || !!unary;
|
|
222
321
|
|
|
322
|
+
var attrs = [];
|
|
323
|
+
|
|
324
|
+
rest.replace(attr, function () {
|
|
325
|
+
var name, value, fallbackValue, customOpen, customClose, customAssign;
|
|
326
|
+
var ncp = 7; // number of captured parts, scalar
|
|
327
|
+
|
|
328
|
+
// hackish work around FF bug https://bugzilla.mozilla.org/show_bug.cgi?id=369778
|
|
329
|
+
if (IS_REGEX_CAPTURING_BROKEN && arguments[0].indexOf('""') === -1) {
|
|
330
|
+
if (arguments[3] === '') { arguments[3] = undefined; }
|
|
331
|
+
if (arguments[4] === '') { arguments[4] = undefined; }
|
|
332
|
+
if (arguments[5] === '') { arguments[5] = undefined; }
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
name = arguments[1];
|
|
336
|
+
if ( name ) {
|
|
337
|
+
customAssign = arguments[2];
|
|
338
|
+
fallbackValue = arguments[3];
|
|
339
|
+
value = fallbackValue || arguments[4] || arguments[5];
|
|
340
|
+
}
|
|
341
|
+
else if ( handler.customAttrSurround ) {
|
|
342
|
+
for ( var i = handler.customAttrSurround.length - 1; i >= 0; i-- ) {
|
|
343
|
+
name = arguments[i * ncp + 7];
|
|
344
|
+
customAssign = arguments[i * ncp + 8];
|
|
345
|
+
if ( name ) {
|
|
346
|
+
fallbackValue = arguments[i * ncp + 9];
|
|
347
|
+
value = fallbackValue
|
|
348
|
+
|| arguments[i * ncp + 10]
|
|
349
|
+
|| arguments[i * ncp + 11];
|
|
350
|
+
customOpen = arguments[i * ncp + 6];
|
|
351
|
+
customClose = arguments[i * ncp + 12];
|
|
352
|
+
break;
|
|
353
|
+
}
|
|
354
|
+
}
|
|
355
|
+
}
|
|
356
|
+
|
|
357
|
+
if ( value === undefined ) {
|
|
358
|
+
value = fillAttrs[name] ? name : fallbackValue;
|
|
359
|
+
}
|
|
360
|
+
|
|
361
|
+
attrs.push({
|
|
362
|
+
name: name,
|
|
363
|
+
value: value,
|
|
364
|
+
escaped: value && value.replace(/(^|.)("+)/g, function(match) {
|
|
365
|
+
return match.replace(/"/g, '"');
|
|
366
|
+
}),
|
|
367
|
+
customAssign: customAssign || '=',
|
|
368
|
+
customOpen: customOpen || '',
|
|
369
|
+
customClose: customClose || ''
|
|
370
|
+
});
|
|
371
|
+
});
|
|
372
|
+
|
|
223
373
|
if ( !unary ) {
|
|
224
|
-
stack.push( tagName );
|
|
374
|
+
stack.push( { tag: tagName, attrs: attrs } );
|
|
225
375
|
}
|
|
226
376
|
else {
|
|
227
377
|
unarySlash = tag.match( endingSlash );
|
|
228
378
|
}
|
|
229
379
|
|
|
230
|
-
if ( handler.start ) {
|
|
231
|
-
var attrs = [];
|
|
232
|
-
|
|
233
|
-
rest.replace(attr, function(match, name) {
|
|
234
|
-
var value = arguments[2] ? arguments[2] :
|
|
235
|
-
arguments[3] ? arguments[3] :
|
|
236
|
-
arguments[4] ? arguments[4] :
|
|
237
|
-
fillAttrs[name] ? name : arguments[2];
|
|
238
|
-
attrs.push({
|
|
239
|
-
name: name,
|
|
240
|
-
value: value,
|
|
241
|
-
escaped: value && value.replace(/(^|[^\\])"/g, '$1"')
|
|
242
|
-
});
|
|
243
|
-
});
|
|
244
380
|
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
}
|
|
381
|
+
if ( handler.start ) {
|
|
382
|
+
handler.start( tagName, attrs, unary, unarySlash );
|
|
248
383
|
}
|
|
249
384
|
}
|
|
250
385
|
|
|
@@ -255,9 +390,11 @@
|
|
|
255
390
|
if ( !tagName ) {
|
|
256
391
|
pos = 0;
|
|
257
392
|
}
|
|
258
|
-
else {
|
|
393
|
+
else {
|
|
394
|
+
// Find the closest opened tag of the same type
|
|
395
|
+
var needle = tagName.toLowerCase();
|
|
259
396
|
for ( pos = stack.length - 1; pos >= 0; pos-- ) {
|
|
260
|
-
if ( stack[ pos ].toLowerCase() ===
|
|
397
|
+
if ( stack[ pos ].tag.toLowerCase() === needle ) {
|
|
261
398
|
break;
|
|
262
399
|
}
|
|
263
400
|
}
|
|
@@ -267,7 +404,7 @@
|
|
|
267
404
|
// Close all the open elements, up the stack
|
|
268
405
|
for ( var i = stack.length - 1; i >= pos; i-- ) {
|
|
269
406
|
if ( handler.end ) {
|
|
270
|
-
handler.end( stack[ i ] );
|
|
407
|
+
handler.end( stack[ i ].tag, stack[ i ].attrs );
|
|
271
408
|
}
|
|
272
409
|
}
|
|
273
410
|
|
|
@@ -470,21 +607,34 @@
|
|
|
470
607
|
'code', 'del', 'dfn', 'em', 'font', 'i', 'ins', 'kbd', 'mark', 'q',
|
|
471
608
|
'rt', 'rp', 's', 'samp', 'small', 'span', 'strike', 'strong',
|
|
472
609
|
'sub', 'sup', 'svg', 'time', 'tt', 'u', 'var'
|
|
473
|
-
]
|
|
610
|
+
],
|
|
611
|
+
lineBreakBefore = /^[\t ]*[\n\r]+[\t\n\r ]*/,
|
|
612
|
+
lineBreakAfter = /[\t\n\r ]*[\n\r]+[\t ]*$/,
|
|
613
|
+
preserveBefore = lineBreakBefore.test(str) ? '\n' : ' ',
|
|
614
|
+
preserveAfter = lineBreakAfter.test(str) ? '\n' : ' ',
|
|
615
|
+
lineBreakStamp = '[{htmlmin-lb}]';
|
|
474
616
|
|
|
475
617
|
if (prevTag && prevTag !== 'img' && prevTag !== 'input' && (prevTag.substr(0,1) !== '/'
|
|
476
618
|
|| ( prevTag.substr(0,1) === '/' && tags.indexOf(prevTag.substr(1)) === -1))) {
|
|
477
|
-
str = str.replace(/^\s+/, options.conservativeCollapse ? ' ' : '');
|
|
619
|
+
str = str.replace(/^\s+/, options.conservativeCollapse ? ' ' : options.preserveLineBreaks ? preserveBefore : '');
|
|
478
620
|
}
|
|
479
621
|
|
|
480
622
|
if (nextTag && nextTag !== 'img' && nextTag !== 'input' && (nextTag.substr(0,1) === '/'
|
|
481
623
|
|| ( nextTag.substr(0,1) !== '/' && tags.indexOf(nextTag) === -1))) {
|
|
482
|
-
str = str.replace(/\s+$/, options.conservativeCollapse ? ' ' : '');
|
|
624
|
+
str = str.replace(/\s+$/, options.conservativeCollapse ? ' ' : options.preserveLineBreaks ? preserveAfter : '');
|
|
483
625
|
}
|
|
484
626
|
|
|
485
627
|
if (prevTag && nextTag) {
|
|
628
|
+
|
|
629
|
+
if (options.preserveLineBreaks) {
|
|
630
|
+
str = str
|
|
631
|
+
.replace(lineBreakBefore, lineBreakStamp)
|
|
632
|
+
.replace(lineBreakAfter, lineBreakStamp);
|
|
633
|
+
}
|
|
486
634
|
// strip non space whitespace then compress spaces to one
|
|
487
|
-
return str
|
|
635
|
+
return str
|
|
636
|
+
.replace(/[\t\n\r]+/g, ' ').replace(/[ ]+/g, ' ')
|
|
637
|
+
.replace(lineBreakStamp, '\n');
|
|
488
638
|
}
|
|
489
639
|
|
|
490
640
|
return str;
|
|
@@ -576,8 +726,23 @@
|
|
|
576
726
|
);
|
|
577
727
|
}
|
|
578
728
|
|
|
579
|
-
|
|
580
|
-
|
|
729
|
+
var enumeratedAttributeValues = {
|
|
730
|
+
draggable: ['true', 'false'] // defaults to 'auto'
|
|
731
|
+
};
|
|
732
|
+
|
|
733
|
+
function isBooleanAttribute(attrName, attrValue) {
|
|
734
|
+
var isSimpleBoolean = (/^(?: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(attrName);
|
|
735
|
+
if (isSimpleBoolean) {
|
|
736
|
+
return true;
|
|
737
|
+
}
|
|
738
|
+
|
|
739
|
+
var attrValueEnumeration = enumeratedAttributeValues[attrName.toLowerCase()];
|
|
740
|
+
if (!attrValueEnumeration) {
|
|
741
|
+
return false;
|
|
742
|
+
}
|
|
743
|
+
else {
|
|
744
|
+
return (-1 === attrValueEnumeration.indexOf(attrValue.toLowerCase()));
|
|
745
|
+
}
|
|
581
746
|
}
|
|
582
747
|
|
|
583
748
|
function isUriTypeAttribute(attrName, tag) {
|
|
@@ -608,7 +773,7 @@
|
|
|
608
773
|
}
|
|
609
774
|
|
|
610
775
|
function cleanAttributeValue(tag, attrName, attrValue, options, attrs) {
|
|
611
|
-
if (isEventAttribute(attrName)) {
|
|
776
|
+
if (attrValue && isEventAttribute(attrName)) {
|
|
612
777
|
attrValue = trimWhitespace(attrValue).replace(/^javascript:\s*/i, '').replace(/\s*;$/, '');
|
|
613
778
|
if (options.minifyJS) {
|
|
614
779
|
var wrappedCode = '(function(){' + attrValue + '})()';
|
|
@@ -620,11 +785,21 @@
|
|
|
620
785
|
else if (attrName === 'class') {
|
|
621
786
|
return collapseWhitespace(trimWhitespace(attrValue));
|
|
622
787
|
}
|
|
623
|
-
else if (isUriTypeAttribute(attrName, tag)
|
|
788
|
+
else if (isUriTypeAttribute(attrName, tag)) {
|
|
789
|
+
attrValue = trimWhitespace(attrValue);
|
|
790
|
+
if (options.minifyURLs) {
|
|
791
|
+
return minifyURLs(attrValue, options.minifyURLs);
|
|
792
|
+
}
|
|
793
|
+
return attrValue;
|
|
794
|
+
}
|
|
795
|
+
else if (isNumberTypeAttribute(attrName, tag)) {
|
|
624
796
|
return trimWhitespace(attrValue);
|
|
625
797
|
}
|
|
626
798
|
else if (attrName === 'style') {
|
|
627
|
-
attrValue = trimWhitespace(attrValue)
|
|
799
|
+
attrValue = trimWhitespace(attrValue);
|
|
800
|
+
if (attrValue) {
|
|
801
|
+
attrValue = attrValue.replace(/\s*;\s*$/, '');
|
|
802
|
+
}
|
|
628
803
|
if (options.minifyCSS) {
|
|
629
804
|
return minifyCSS(attrValue, options.minifyCSS);
|
|
630
805
|
}
|
|
@@ -633,6 +808,9 @@
|
|
|
633
808
|
else if (isMetaViewport(tag, attrs) && attrName === 'content') {
|
|
634
809
|
attrValue = attrValue.replace(/1\.0/g, '1').replace(/\s+/g, '');
|
|
635
810
|
}
|
|
811
|
+
else if (attrValue && options.customAttrCollapse && options.customAttrCollapse.test(attrName)) {
|
|
812
|
+
attrValue = attrValue.replace(/\n+/g, '');
|
|
813
|
+
}
|
|
636
814
|
return attrValue;
|
|
637
815
|
}
|
|
638
816
|
|
|
@@ -693,7 +871,7 @@
|
|
|
693
871
|
'?:down|up|over|move|out)|key(?:press|down|up)))$');
|
|
694
872
|
|
|
695
873
|
function canDeleteEmptyAttribute(tag, attrName, attrValue) {
|
|
696
|
-
var isValueEmpty =
|
|
874
|
+
var isValueEmpty = !attrValue || (/^\s*$/).test(attrValue);
|
|
697
875
|
if (isValueEmpty) {
|
|
698
876
|
return (
|
|
699
877
|
(tag === 'input' && attrName === 'value') ||
|
|
@@ -702,8 +880,20 @@
|
|
|
702
880
|
return false;
|
|
703
881
|
}
|
|
704
882
|
|
|
705
|
-
function canRemoveElement(tag) {
|
|
706
|
-
|
|
883
|
+
function canRemoveElement(tag, attrs) {
|
|
884
|
+
if (tag === 'textarea') {
|
|
885
|
+
return false;
|
|
886
|
+
}
|
|
887
|
+
|
|
888
|
+
if (tag === 'script') {
|
|
889
|
+
for (var i = attrs.length - 1; i >= 0; i--) {
|
|
890
|
+
if (attrs[i].name === 'src') {
|
|
891
|
+
return false;
|
|
892
|
+
}
|
|
893
|
+
}
|
|
894
|
+
}
|
|
895
|
+
|
|
896
|
+
return true;
|
|
707
897
|
}
|
|
708
898
|
|
|
709
899
|
function canCollapseWhitespace(tag) {
|
|
@@ -722,11 +912,13 @@
|
|
|
722
912
|
return markup;
|
|
723
913
|
}
|
|
724
914
|
|
|
725
|
-
function normalizeAttribute(attr, attrs, tag, options) {
|
|
915
|
+
function normalizeAttribute(attr, attrs, tag, unarySlash, index, options) {
|
|
726
916
|
|
|
727
917
|
var attrName = options.caseSensitive ? attr.name : attr.name.toLowerCase(),
|
|
728
918
|
attrValue = attr.escaped,
|
|
729
|
-
attrFragment
|
|
919
|
+
attrFragment,
|
|
920
|
+
emittedAttrValue,
|
|
921
|
+
isTerminalOfUnarySlash = unarySlash && index === attrs.length - 1;
|
|
730
922
|
|
|
731
923
|
if ((options.removeRedundantAttributes &&
|
|
732
924
|
isAttributeRedundant(tag, attrName, attrValue, attrs))
|
|
@@ -742,8 +934,11 @@
|
|
|
742
934
|
attrValue = cleanAttributeValue(tag, attrName, attrValue, options, attrs);
|
|
743
935
|
|
|
744
936
|
if (attrValue !== undefined && !options.removeAttributeQuotes ||
|
|
745
|
-
!canRemoveAttributeQuotes(attrValue)) {
|
|
746
|
-
|
|
937
|
+
!canRemoveAttributeQuotes(attrValue) || isTerminalOfUnarySlash) {
|
|
938
|
+
emittedAttrValue = '"' + attrValue + '"';
|
|
939
|
+
}
|
|
940
|
+
else {
|
|
941
|
+
emittedAttrValue = attrValue;
|
|
747
942
|
}
|
|
748
943
|
|
|
749
944
|
if (options.removeEmptyAttributes &&
|
|
@@ -752,14 +947,14 @@
|
|
|
752
947
|
}
|
|
753
948
|
|
|
754
949
|
if (attrValue === undefined || (options.collapseBooleanAttributes &&
|
|
755
|
-
isBooleanAttribute(attrName))) {
|
|
950
|
+
isBooleanAttribute(attrName, attrValue))) {
|
|
756
951
|
attrFragment = attrName;
|
|
757
952
|
}
|
|
758
953
|
else {
|
|
759
|
-
attrFragment = attrName +
|
|
954
|
+
attrFragment = attrName + attr.customAssign + emittedAttrValue;
|
|
760
955
|
}
|
|
761
956
|
|
|
762
|
-
return (' ' + attrFragment);
|
|
957
|
+
return (' ' + attr.customOpen + attrFragment + attr.customClose);
|
|
763
958
|
}
|
|
764
959
|
|
|
765
960
|
function setDefaultTesters(options) {
|
|
@@ -775,6 +970,37 @@
|
|
|
775
970
|
}
|
|
776
971
|
}
|
|
777
972
|
|
|
973
|
+
function minifyURLs(text, options) {
|
|
974
|
+
if (typeof options !== 'object') {
|
|
975
|
+
options = { };
|
|
976
|
+
}
|
|
977
|
+
|
|
978
|
+
try {
|
|
979
|
+
// try to get global reference first
|
|
980
|
+
var __RelateUrl = global.RelateUrl;
|
|
981
|
+
|
|
982
|
+
if (typeof __RelateUrl === 'undefined' && typeof require === 'function') {
|
|
983
|
+
__RelateUrl = require('relateurl');
|
|
984
|
+
}
|
|
985
|
+
|
|
986
|
+
// noop
|
|
987
|
+
if (!__RelateUrl) {
|
|
988
|
+
return text;
|
|
989
|
+
}
|
|
990
|
+
|
|
991
|
+
if (__RelateUrl.relate) {
|
|
992
|
+
return __RelateUrl.relate(text, options);
|
|
993
|
+
}
|
|
994
|
+
else {
|
|
995
|
+
return text;
|
|
996
|
+
}
|
|
997
|
+
}
|
|
998
|
+
catch (err) {
|
|
999
|
+
log(err);
|
|
1000
|
+
}
|
|
1001
|
+
return text;
|
|
1002
|
+
}
|
|
1003
|
+
|
|
778
1004
|
function minifyJS(text, options) {
|
|
779
1005
|
if (typeof options !== 'object') {
|
|
780
1006
|
options = { };
|
|
@@ -867,6 +1093,12 @@
|
|
|
867
1093
|
isIgnoring = false,
|
|
868
1094
|
t = new Date();
|
|
869
1095
|
|
|
1096
|
+
if (options.removeIgnored) {
|
|
1097
|
+
value = value
|
|
1098
|
+
.replace(/<\?[^\?]+\?>/g, '')
|
|
1099
|
+
.replace(/<%[^%]+%>/g, '');
|
|
1100
|
+
}
|
|
1101
|
+
|
|
870
1102
|
function _canCollapseWhitespace(tag, attrs) {
|
|
871
1103
|
return canCollapseWhitespace(tag) || options.canCollapseWhitespace(tag, attrs);
|
|
872
1104
|
}
|
|
@@ -881,7 +1113,7 @@
|
|
|
881
1113
|
start: function( tag, attrs, unary, unarySlash ) {
|
|
882
1114
|
|
|
883
1115
|
if (isIgnoring) {
|
|
884
|
-
buffer.push('<'
|
|
1116
|
+
buffer.push('<' + tag, attrsToMarkup(attrs), unarySlash ? '/' : '', '>');
|
|
885
1117
|
return;
|
|
886
1118
|
}
|
|
887
1119
|
|
|
@@ -900,20 +1132,30 @@
|
|
|
900
1132
|
}
|
|
901
1133
|
}
|
|
902
1134
|
|
|
903
|
-
|
|
1135
|
+
var openTag = '<' + tag;
|
|
1136
|
+
var closeTag = ((unarySlash && options.keepClosingSlash) ? '/' : '') + '>';
|
|
1137
|
+
if ( attrs.length === 0) {
|
|
1138
|
+
openTag += closeTag;
|
|
1139
|
+
}
|
|
1140
|
+
|
|
1141
|
+
buffer.push(openTag);
|
|
904
1142
|
|
|
905
1143
|
lint && lint.testElement(tag);
|
|
906
1144
|
|
|
1145
|
+
var token;
|
|
907
1146
|
for ( var i = 0, len = attrs.length; i < len; i++ ) {
|
|
908
1147
|
lint && lint.testAttribute(tag, attrs[i].name.toLowerCase(), attrs[i].escaped);
|
|
909
|
-
|
|
1148
|
+
token = normalizeAttribute(attrs[i], attrs, tag, unarySlash, i, options);
|
|
1149
|
+
if ( i === len - 1 ) {
|
|
1150
|
+
token += closeTag;
|
|
1151
|
+
}
|
|
1152
|
+
buffer.push(token);
|
|
910
1153
|
}
|
|
911
|
-
buffer.push(((unarySlash && options.keepClosingSlash) ? '/' : '') + '>');
|
|
912
1154
|
},
|
|
913
|
-
end: function( tag ) {
|
|
1155
|
+
end: function( tag, attrs ) {
|
|
914
1156
|
|
|
915
1157
|
if (isIgnoring) {
|
|
916
|
-
buffer.push('</'
|
|
1158
|
+
buffer.push('</' + tag + '>');
|
|
917
1159
|
return;
|
|
918
1160
|
}
|
|
919
1161
|
|
|
@@ -930,9 +1172,14 @@
|
|
|
930
1172
|
}
|
|
931
1173
|
|
|
932
1174
|
var isElementEmpty = currentChars === '' && tag === currentTag;
|
|
933
|
-
if ((options.removeEmptyElements && isElementEmpty && canRemoveElement(tag))) {
|
|
1175
|
+
if ((options.removeEmptyElements && isElementEmpty && canRemoveElement(tag, attrs))) {
|
|
934
1176
|
// remove last "element" from buffer, return
|
|
935
|
-
|
|
1177
|
+
for ( var i = buffer.length - 1; i >= 0; i-- ) {
|
|
1178
|
+
if ( /^<[^\/!]/.test(buffer[i]) ) {
|
|
1179
|
+
buffer.splice(i);
|
|
1180
|
+
break;
|
|
1181
|
+
}
|
|
1182
|
+
}
|
|
936
1183
|
return;
|
|
937
1184
|
}
|
|
938
1185
|
else if (options.removeOptionalTags && isOptionalTag(tag)) {
|
|
@@ -941,7 +1188,7 @@
|
|
|
941
1188
|
}
|
|
942
1189
|
else {
|
|
943
1190
|
// push end tag to buffer
|
|
944
|
-
buffer.push('</'
|
|
1191
|
+
buffer.push('</' + (options.caseSensitive ? tag : tag.toLowerCase()) + '>');
|
|
945
1192
|
results.push.apply(results, buffer);
|
|
946
1193
|
}
|
|
947
1194
|
// flush buffer
|
|
@@ -949,6 +1196,9 @@
|
|
|
949
1196
|
currentChars = '';
|
|
950
1197
|
},
|
|
951
1198
|
chars: function( text, prevTag, nextTag ) {
|
|
1199
|
+
prevTag = prevTag === '' ? 'comment' : prevTag;
|
|
1200
|
+
nextTag = nextTag === '' ? 'comment' : nextTag;
|
|
1201
|
+
|
|
952
1202
|
if (isIgnoring) {
|
|
953
1203
|
buffer.push(text);
|
|
954
1204
|
return;
|
|
@@ -973,12 +1223,12 @@
|
|
|
973
1223
|
}
|
|
974
1224
|
if (options.collapseWhitespace) {
|
|
975
1225
|
if (!stackNoTrimWhitespace.length) {
|
|
976
|
-
text = (prevTag || nextTag) ?
|
|
1226
|
+
text = ((prevTag && prevTag !== 'comment') || (nextTag && nextTag !== 'comment')) ?
|
|
977
1227
|
collapseWhitespaceSmart(text, prevTag, nextTag, options)
|
|
978
1228
|
: trimWhitespace(text);
|
|
979
1229
|
}
|
|
980
1230
|
if (!stackNoCollapseWhitespace.length) {
|
|
981
|
-
text = collapseWhitespace(text);
|
|
1231
|
+
text = !(prevTag && nextTag || nextTag === 'html') ? collapseWhitespace(text) : text;
|
|
982
1232
|
}
|
|
983
1233
|
}
|
|
984
1234
|
currentChars = text;
|
|
@@ -992,7 +1242,9 @@
|
|
|
992
1242
|
|
|
993
1243
|
if (/^\s*htmlmin:ignore/.test(text)) {
|
|
994
1244
|
isIgnoring = !isIgnoring;
|
|
995
|
-
|
|
1245
|
+
if (!options.removeComments) {
|
|
1246
|
+
buffer.push('<!--' + text + '-->');
|
|
1247
|
+
}
|
|
996
1248
|
return;
|
|
997
1249
|
}
|
|
998
1250
|
if (options.removeComments) {
|
|
@@ -1011,21 +1263,47 @@
|
|
|
1011
1263
|
}
|
|
1012
1264
|
buffer.push(text);
|
|
1013
1265
|
},
|
|
1014
|
-
ignore: function(text) {
|
|
1015
|
-
// `text` === strings that start with `<?` or `<%` and end with `?>` or `%>`.
|
|
1016
|
-
buffer.push(options.removeIgnored ? '' : text); // `text` allowed by default.
|
|
1017
|
-
},
|
|
1018
1266
|
doctype: function(doctype) {
|
|
1019
1267
|
buffer.push(options.useShortDoctype ? '<!DOCTYPE html>' : collapseWhitespace(doctype));
|
|
1020
|
-
}
|
|
1268
|
+
},
|
|
1269
|
+
customAttrAssign: options.customAttrAssign,
|
|
1270
|
+
customAttrSurround: options.customAttrSurround
|
|
1021
1271
|
});
|
|
1022
1272
|
|
|
1023
1273
|
results.push.apply(results, buffer);
|
|
1024
|
-
var str = results
|
|
1274
|
+
var str = joinResultSegments(results, options);
|
|
1025
1275
|
log('minified in: ' + (new Date() - t) + 'ms');
|
|
1026
1276
|
return str;
|
|
1027
1277
|
}
|
|
1028
1278
|
|
|
1279
|
+
function joinResultSegments( results, options ) {
|
|
1280
|
+
var str;
|
|
1281
|
+
var maxLineLength = options.maxLineLength;
|
|
1282
|
+
if ( maxLineLength ) {
|
|
1283
|
+
var token;
|
|
1284
|
+
var lines = [];
|
|
1285
|
+
var line = '';
|
|
1286
|
+
for ( var i = 0, len = results.length; i < len; i++ ) {
|
|
1287
|
+
token = results[i];
|
|
1288
|
+
if ( line.length + token.length < maxLineLength ) {
|
|
1289
|
+
line += token;
|
|
1290
|
+
}
|
|
1291
|
+
else {
|
|
1292
|
+
lines.push(line.replace(/^\n/, ''));
|
|
1293
|
+
line = token;
|
|
1294
|
+
}
|
|
1295
|
+
}
|
|
1296
|
+
lines.push(line);
|
|
1297
|
+
|
|
1298
|
+
str = lines.join('\n');
|
|
1299
|
+
}
|
|
1300
|
+
else {
|
|
1301
|
+
str = results.join('');
|
|
1302
|
+
}
|
|
1303
|
+
|
|
1304
|
+
return str;
|
|
1305
|
+
}
|
|
1306
|
+
|
|
1029
1307
|
// for CommonJS enviroments, export everything
|
|
1030
1308
|
if ( typeof exports !== 'undefined' ) {
|
|
1031
1309
|
exports.minify = minify;
|
|
@@ -1048,10 +1326,10 @@
|
|
|
1048
1326
|
'use strict';
|
|
1049
1327
|
|
|
1050
1328
|
function isPresentationalElement(tag) {
|
|
1051
|
-
return (/^(?:
|
|
1329
|
+
return (/^(?:big|small|hr|blink|marquee)$/).test(tag);
|
|
1052
1330
|
}
|
|
1053
1331
|
function isDeprecatedElement(tag) {
|
|
1054
|
-
return (/^(?:applet|basefont|center|dir|font|isindex|
|
|
1332
|
+
return (/^(?:applet|basefont|center|dir|font|isindex|strike)$/).test(tag);
|
|
1055
1333
|
}
|
|
1056
1334
|
function isEventAttribute(attrName) {
|
|
1057
1335
|
return (/^on[a-z]+/).test(attrName);
|
package/dist/htmlminifier.min.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/*!
|
|
2
|
-
* HTMLMinifier v0.6.
|
|
2
|
+
* HTMLMinifier v0.6.9 (http://kangax.github.io/html-minifier/)
|
|
3
3
|
* Copyright 2010-2014 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){for(var b={},c=a.split(","),d=0;d<c.length;d++)b[c[d]]=!0,b[c[d].toUpperCase()]=!0;return b}var c,d,e,f=/^<([\w:-]+)((?:\s*[\w:-]+(?:\s*=\s*(?:(?:"[^"]*")|(?:'[^']*')|[^>\s]+))?)*)\s*(\/?)>/,g=/^<\/([\w:-]+)[^>]*>/,h=/\/>$/,i=/([\w:-]+)(?:\s*=\s*(?:(?:"((?:\\.|[^"])*)")|(?:'((?:\\.|[^'])*)')|([^>\s]+)))?/g,j=/^<!DOCTYPE [^>]+>/i,k=/<(%|\?)/,l=/(%|\?)>/,m=b("area,base,basefont,br,col,frame,hr,img,input,isindex,link,meta,param,embed,wbr"),n=b("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"),o=b("colgroup,dd,dt,li,options,p,td,tfoot,th,thead,tr,source"),p=b("checked,compact,declare,defer,disabled,ismap,multiple,nohref,noresize,noshade,nowrap,readonly,selected"),q=b("script,style,noscript"),r={},s=a.HTMLParser=function(a,b){function s(a,c,d,e){for(var f=!1;!b.html5&&z.last()&&n[z.last()];)t("",z.last());if(o[c]&&z.last()===c&&t("",c),e=m[c]||!!e,e?f=a.match(h):z.push(c),b.start){var g=[];d.replace(i,function(a,b){var c=arguments[2]?arguments[2]:arguments[3]?arguments[3]:arguments[4]?arguments[4]:p[b]?b:arguments[2];g.push({name:b,value:c,escaped:c&&c.replace(/(^|[^\\])"/g,"$1"")})}),b.start&&b.start(c,g,e,f)}}function t(a,c){var d;if(c)for(d=z.length-1;d>=0&&z[d].toLowerCase()!==c;d--);else d=0;if(d>=0){for(var e=z.length-1;e>=d;e--)b.end&&b.end(z[e]);z.length=d}}var u,v,w,x,y,z=[],A=a;for(z.last=function(){return this[this.length-1]};a;){if(v=!0,z.last()&&q[z.last()])c=z.last().toLowerCase(),d=r[c]||(r[c]=new RegExp("([\\s\\S]*?)</"+c+"[^>]*>","i")),a=a.replace(d,function(a,d){return"script"!==c&&"style"!==c&&"noscript"!==c&&(d=d.replace(/<!--([\s\S]*?)-->/g,"$1").replace(/<!\[CDATA\[([\s\S]*?)\]\]>/g,"$1")),b.chars&&b.chars(d),""}),t("",c);else if(0===a.indexOf("<!--")&&(u=a.indexOf("-->"),u>=0&&(b.comment&&b.comment(a.substring(4,u)),a=a.substring(u+3),v=!1)),0===a.indexOf("<![")?(u=a.indexOf("]>"),u>=0&&(b.comment&&b.comment(a.substring(2,u+1),!0),a=a.substring(u+2),v=!1)):0===a.search(k)?(u=a.search(l),u>=0&&(b.ignore&&b.ignore(a.substring(0,u+2)),a=a.substring(u+2),v=!1)):(w=j.exec(a))?(b.doctype&&b.doctype(w[0]),a=a.substring(w[0].length),v=!1):0===a.indexOf("</")?(w=a.match(g),w&&(a=a.substring(w[0].length),w[0].replace(g,t),x="/"+w[1].toLowerCase(),v=!1)):0===a.indexOf("<")&&(w=a.match(f),w&&(a=a.substring(w[0].length),w[0].replace(f,s),x=w[1].toLowerCase(),v=!1)),v){u=a.indexOf("<");var B=0>u?a:a.substring(0,u);a=0>u?"":a.substring(u),e=a.match(f),e?y=e[1]:(e=a.match(g),y=e?"/"+e[1]:""),b.chars&&b.chars(B,x,y)}if(a===A)throw"Parse Error: "+a;A=a}t()};a.HTMLtoXML=function(a){var b="";return new s(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,c){var d=b("html,head,body,title"),e={link:"head",base:"head"};c?c=c.ownerDocument||c.getOwnerDocument&&c.getOwnerDocument()||c:"undefined"!=typeof DOMDocument?c=new DOMDocument:"undefined"!=typeof document&&document.implementation&&document.implementation.createDocument?c=document.implementation.createDocument("","",null):"undefined"!=typeof ActiveX&&(c=new ActiveXObject("Msxml.DOMDocument"));var f=[],g=c.documentElement||c.getDocumentElement&&c.getDocumentElement();if(!g&&c.createElement&&!function(){var a=c.createElement("html"),b=c.createElement("head");b.appendChild(c.createElement("title")),a.appendChild(b),a.appendChild(c.createElement("body")),c.appendChild(a)}(),c.getElementsByTagName)for(var h in d)d[h]=c.getElementsByTagName(h)[0];var i=d.body;return new s(a,{start:function(a,b,g){if(d[a])return void(i=d[a]);var h=c.createElement(a);for(var j in b)h.setAttribute(b[j].name,b[j].value);e[a]&&"boolean"!=typeof d[e[a]]?d[e[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(c.createTextNode(a))},comment:function(){},ignore:function(){}}),c}}("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"];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?" ":"")),c&&"img"!==c&&"input"!==c&&("/"===c.substr(0,1)||"/"!==c.substr(0,1)&&-1===e.indexOf(c))&&(a=a.replace(/\s+$/,d.conservativeCollapse?" ":"")),b&&c?a.replace(/[\t\n\r]+/g," ").replace(/[ ]+/g," "):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?H(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"===H(c.toLowerCase())}function k(a,b,c){return("style"===a||"link"===a)&&"type"===b&&"text/css"===H(c.toLowerCase())}function l(a){return/^(?:allowfullscreen|async|autofocus|autoplay|checked|compact|controls|declare|default|defaultchecked|defaultmuted|defaultselected|defer|disabled|draggable|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)$/.test(a)}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(f(c)){if(d=H(d).replace(/^javascript:\s*/i,"").replace(/\s*;$/,""),e.minifyJS){var h="(function(){"+d+"})()",i=C(h,e.minifyJS);return i.slice(12,i.length-4).replace(/"/g,""")}return d}return"class"===c?b(H(d)):m(c,a)||n(c,a)?H(d):"style"===c?(d=H(d).replace(/\s*;\s*$/,""),e.minifyCSS?D(d,e.minifyCSS):d):(p(a,g)&&"content"===c&&(d=d.replace(/1\.0/g,"1").replace(/\s+/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 E(a,b);return a}function t(a,b){return a.replace(I[b],"").replace(J[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=/^(["'])?\s*\1$/.test(c);return d?"input"===a&&"value"===b||K.test(b):!1}function w(a){return"textarea"!==a}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){var e,f=d.caseSensitive?a.name:a.name.toLowerCase(),h=a.escaped;return d.removeRedundantAttributes&&i(c,f,h,b)||d.removeScriptTypeAttributes&&j(c,f,h)||d.removeStyleLinkTypeAttributes&&k(c,f,h)?"":(h=o(c,f,h,d,b),(void 0!==h&&!d.removeAttributeQuotes||!g(h))&&(h='"'+h+'"'),d.removeEmptyAttributes&&v(c,f,h)?"":(e=void 0===h||d.collapseBooleanAttributes&&l(f)?f:f+"="+h," "+e))}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={}),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){F(i)}return b}function D(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){F(d)}return a}function E(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=H(a),B(f);var i=[],j=[],k="",l="",m=[],n=[],o=[],p=f.lint,v=!1,E=new Date;new G(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)),j.push("<",a),p&&p.testElement(a);for(var e=0,i=b.length;i>e;e++)p&&p.testAttribute(a,b[e].name.toLowerCase(),b[e].escaped),j.push(A(b[e],b,a,f));j.push((d&&f.keepClosingSlash?"/":"")+">")},end:function(a){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 b=""===k&&a===l;return f.removeEmptyElements&&b&&w(a)?void j.splice(j.lastIndexOf("<")):void(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=C(a,f.minifyJS)),"style"===l&&f.minifyCSS&&(a=D(a,f.minifyCSS)),f.collapseWhitespace&&(n.length||(a=d||e?c(a,d,e,f):H(a)),o.length||(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 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))}}),i.push.apply(i,j);var I=i.join("");return F("minified in: "+(new Date-E)+"ms"),I}var F,G;F=a.console&&a.console.log?function(b){a.console.log(b)}:function(){},a.HTMLParser?G=a.HTMLParser:"function"==typeof require&&(G=require("./htmlparser").HTMLParser);var H=function(a){return"string"!=typeof a?a:a.replace(/^\s+/,"").replace(/\s+$/,"")};String.prototype.trim&&(H=function(a){return"string"!=typeof a?a:a.trim()});var I={script:/^\s*(?:\/\/)?\s*<!--.*\n?/,style:/^\s*<!--\s*/},J={script:/\s*(?:\/\/)?\s*-->\s*$/,style:/\s*-->\s*$/},K=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=E:a.minify=E}(this),function(a){"use strict";function b(a){return/^(?:b|i|big|small|hr|blink|marquee)$/.test(a)}function c(a){return/^(?:applet|basefont|center|dir|font|isindex|s|strike|u)$/.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=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];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=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||""})}),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="[{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,""):d&&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;f.removeIgnored&&(a=a.replace(/<\?[^\?]+\?>/g,"").replace(/<%[^%]+%>/g,"")),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 d=""===d?"comment":d,e=""===e?"comment":e,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&&"comment"!==d||e&&"comment"!==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))},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);
|
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.6.
|
|
4
|
+
"version": "0.6.9",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"html",
|
|
7
7
|
"minifier",
|
|
@@ -42,21 +42,21 @@
|
|
|
42
42
|
"change-case": "2.1.x",
|
|
43
43
|
"clean-css": "2.2.x",
|
|
44
44
|
"cli": "0.6.x",
|
|
45
|
-
"uglify-js": "2.4.x"
|
|
45
|
+
"uglify-js": "2.4.x",
|
|
46
|
+
"relateurl": "0.2.x"
|
|
46
47
|
},
|
|
47
48
|
"devDependencies": {
|
|
48
49
|
"cli-table": "0.3.x",
|
|
49
50
|
"grunt": "0.4.x",
|
|
50
|
-
"grunt-contrib-concat": "0.
|
|
51
|
+
"grunt-contrib-concat": "0.5.x",
|
|
51
52
|
"grunt-contrib-jshint": "0.10.x",
|
|
52
53
|
"grunt-contrib-qunit": "0.5.x",
|
|
53
|
-
"grunt-contrib-uglify": "0.
|
|
54
|
+
"grunt-contrib-uglify": "0.6.x",
|
|
54
55
|
"grunt-exec": "0.4.x",
|
|
55
|
-
"grunt-jscs": "0.
|
|
56
|
+
"grunt-jscs": "0.7.x",
|
|
56
57
|
"load-grunt-tasks": "0.6.x",
|
|
57
|
-
"qunit": "0.
|
|
58
|
-
"time-grunt": "0.
|
|
59
|
-
"underscore": "1.6.x"
|
|
58
|
+
"qunit": "0.7.x",
|
|
59
|
+
"time-grunt": "1.0.x"
|
|
60
60
|
},
|
|
61
61
|
"files": [
|
|
62
62
|
"dist",
|