html-minifier 3.5.21 → 4.0.0

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/README.md CHANGED
@@ -20,19 +20,19 @@ How does HTMLMinifier compare to other solutions — [HTML Minifier from Will Pe
20
20
 
21
21
  | Site | Original size *(KB)* | HTMLMinifier | minimize | Will Peavy | htmlcompressor.com |
22
22
  | ---------------------------------------------------------------------------- |:--------------------:| ------------:| --------:| ----------:| ------------------:|
23
- | [Google](https://www.google.com/) | 48 | **44** | 48 | 49 | 48 |
24
- | [HTMLMinifier](https://github.com/kangax/html-minifier) | 154 | **117** | 128 | 133 | 128 |
25
- | [Twitter](https://twitter.com/) | 203 | **162** | 195 | 219 | 195 |
26
- | [Stack Overflow](https://stackoverflow.com/) | 254 | **196** | 208 | 216 | 205 |
27
- | [Bootstrap CSS](https://getbootstrap.com/docs/3.3/css/) | 271 | **260** | 269 | 229 | 269 |
28
- | [BBC](https://www.bbc.co.uk/) | 288 | **230** | 280 | 281 | 272 |
29
- | [Amazon](https://www.amazon.co.uk/) | 508 | **439** | 495 | 501 | n/a |
30
- | [Wikipedia](https://en.wikipedia.org/wiki/President_of_the_United_States) | 533 | **434** | 517 | 536 | 517 |
31
- | [New York Times](https://mathiasbynens.be/_tmp/nyt.html) | 699 | **619** | 693 | 683 | n/a |
32
- | [NBC](https://www.nbc.com/) | 700 | **657** | 698 | 699 | n/a |
23
+ | [Google](https://www.google.com/) | 46 | **42** | 46 | 48 | 46 |
24
+ | [HTMLMinifier](https://github.com/kangax/html-minifier) | 125 | **98** | 111 | 117 | 111 |
25
+ | [Twitter](https://twitter.com/) | 207 | **165** | 200 | 224 | 200 |
26
+ | [Stack Overflow](https://stackoverflow.com/) | 253 | **195** | 207 | 215 | 204 |
27
+ | [Bootstrap CSS](https://getbootstrap.com/docs/3.3/css/) | 271 | **260** | 269 | 228 | 269 |
28
+ | [BBC](https://www.bbc.co.uk/) | 298 | **239** | 290 | 291 | 280 |
29
+ | [Amazon](https://www.amazon.co.uk/) | 422 | **316** | 412 | 425 | n/a |
30
+ | [NBC](https://www.nbc.com/) | 553 | **530** | 552 | 553 | 534 |
31
+ | [Wikipedia](https://en.wikipedia.org/wiki/President_of_the_United_States) | 565 | **461** | 548 | 569 | 548 |
32
+ | [New York Times](https://www.nytimes.com/) | 678 | **606** | 675 | 670 | n/a |
33
33
  | [Eloquent Javascript](https://eloquentjavascript.net/1st_edition/print.html) | 870 | **815** | 840 | 864 | n/a |
34
- | [ES6 table](https://kangax.github.io/compat-table/es6/) | 5308 | **4529** | 5025 | n/a | n/a |
35
- | [ES draft](https://tc39.github.io/ecma262/) | 6082 | **5456** | 5624 | n/a | n/a |
34
+ | [ES6 table](https://kangax.github.io/compat-table/es6/) | 5911 | **5051** | 5595 | n/a | n/a |
35
+ | [ES draft](https://tc39.github.io/ecma262/) | 6126 | **5495** | 5664 | n/a | n/a |
36
36
 
37
37
  ## Options Quick Reference
38
38
 
@@ -45,6 +45,7 @@ Most of the options are disabled by default.
45
45
  | `collapseInlineTagWhitespace` | Don't leave any spaces between `display:inline;` elements when collapsing. Must be used in conjunction with `collapseWhitespace=true` | `false` |
46
46
  | `collapseWhitespace` | [Collapse white space that contributes to text nodes in a document tree](http://perfectionkills.com/experimenting-with-html-minifier/#collapse_whitespace) | `false` |
47
47
  | `conservativeCollapse` | Always collapse to 1 space (never remove it entirely). Must be used in conjunction with `collapseWhitespace=true` | `false` |
48
+ | `continueOnParseError` | [Handle parse errors](https://html.spec.whatwg.org/multipage/parsing.html#parse-errors) instead of aborting. | `false` |
48
49
  | `customAttrAssign` | Arrays of regex'es that allow to support custom attribute assign expressions (e.g. `'<div flex?="{{mode != cover}}"></div>'`) | `[ ]` |
49
50
  | `customAttrCollapse` | Regex that specifies custom attribute to strip newlines from (e.g. `/ng-class/`) | |
50
51
  | `customAttrSurround` | Arrays of regex'es that allow to support custom attribute surround expressions (e.g. `<input {{#if value}}checked="checked"{{/if}}>`) | `[ ]` |
package/cli.js CHANGED
@@ -103,6 +103,7 @@ var mainOptions = {
103
103
  collapseInlineTagWhitespace: 'Collapse white space around inline tag',
104
104
  collapseWhitespace: 'Collapse white space that contributes to text nodes in a document tree.',
105
105
  conservativeCollapse: 'Always collapse to 1 space (never remove it entirely)',
106
+ continueOnParseError: 'Handle parse errors instead of aborting',
106
107
  customAttrAssign: ['Arrays of regex\'es that allow to support custom attribute assign expressions (e.g. \'<div flex?="{{mode != cover}}"></div>\')', parseJSONRegExpArray],
107
108
  customAttrCollapse: ['Regex that specifies custom attribute to strip newlines from (e.g. /ng-class/)', parseRegExp],
108
109
  customAttrSurround: ['Arrays of regex\'es that allow to support custom attribute surround expressions (e.g. <input {{#if value}}checked="checked"{{/if}}>)', parseJSONRegExpArray],
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "html-minifier",
3
3
  "description": "Highly configurable, well-tested, JavaScript-based HTML minifier.",
4
- "version": "3.5.21",
4
+ "version": "4.0.0",
5
5
  "keywords": [
6
6
  "cli",
7
7
  "compress",
@@ -47,36 +47,36 @@
47
47
  "url": "https://github.com/kangax/html-minifier/issues"
48
48
  },
49
49
  "engines": {
50
- "node": ">=4"
50
+ "node": ">=6"
51
51
  },
52
52
  "scripts": {
53
53
  "dist": "grunt dist",
54
54
  "test": "grunt test"
55
55
  },
56
56
  "dependencies": {
57
- "camel-case": "3.0.x",
58
- "clean-css": "4.2.x",
59
- "commander": "2.17.x",
60
- "he": "1.2.x",
61
- "param-case": "2.1.x",
62
- "relateurl": "0.2.x",
63
- "uglify-js": "3.4.x"
57
+ "camel-case": "^3.0.0",
58
+ "clean-css": "^4.2.1",
59
+ "commander": "^2.19.0",
60
+ "he": "^1.2.0",
61
+ "param-case": "^2.1.1",
62
+ "relateurl": "^0.2.7",
63
+ "uglify-js": "^3.5.1"
64
64
  },
65
65
  "devDependencies": {
66
- "grunt": "1.0.x",
67
- "grunt-browserify": "5.3.x",
68
- "grunt-contrib-uglify": "3.4.x",
69
- "gruntify-eslint": "4.0.x",
70
- "phantomjs-prebuilt": "2.1.x",
71
- "qunit": "2.x"
66
+ "grunt": "^1.0.4",
67
+ "grunt-browserify": "^5.3.0",
68
+ "grunt-contrib-uglify": "^4.0.1",
69
+ "grunt-eslint": "^21.0.0",
70
+ "phantomjs-prebuilt": "^2.1.16",
71
+ "qunit": "^2.9.2"
72
72
  },
73
73
  "benchmarkDependencies": {
74
- "brotli": "1.3.x",
75
- "chalk": "2.4.x",
76
- "cli-table": "0.3.x",
77
- "lzma": "2.3.x",
78
- "minimize": "2.2.x",
79
- "progress": "2.0.x"
74
+ "brotli": "^1.3.2",
75
+ "chalk": "^2.4.2",
76
+ "cli-table": "^0.3.1",
77
+ "lzma": "^2.3.2",
78
+ "minimize": "^2.2.0",
79
+ "progress": "^2.0.3"
80
80
  },
81
81
  "files": [
82
82
  "src/*.js",
@@ -4,6 +4,7 @@
4
4
  "collapseInlineTagWhitespace": false,
5
5
  "collapseWhitespace": true,
6
6
  "conservativeCollapse": false,
7
+ "continueOnParseError": true,
7
8
  "customAttrCollapse": ".*",
8
9
  "decodeEntities": true,
9
10
  "html5": true,
@@ -311,6 +311,9 @@ function cleanAttributeValue(tag, attrName, attrValue, options, attrs) {
311
311
  return (+numString).toString();
312
312
  });
313
313
  }
314
+ else if (isContentSecurityPolicy(tag, attrs) && attrName.toLowerCase() === 'content') {
315
+ return collapseWhitespaceAll(attrValue);
316
+ }
314
317
  else if (options.customAttrCollapse && options.customAttrCollapse.test(attrName)) {
315
318
  attrValue = attrValue.replace(/\n+|\r+|\s{2,}/g, '');
316
319
  }
@@ -335,6 +338,17 @@ function isMetaViewport(tag, attrs) {
335
338
  }
336
339
  }
337
340
 
341
+ function isContentSecurityPolicy(tag, attrs) {
342
+ if (tag !== 'meta') {
343
+ return false;
344
+ }
345
+ for (var i = 0, len = attrs.length; i < len; i++) {
346
+ if (attrs[i].name.toLowerCase() === 'http-equiv' && attrs[i].value.toLowerCase() === 'content-security-policy') {
347
+ return true;
348
+ }
349
+ }
350
+ }
351
+
338
352
  function ignoreCSS(id) {
339
353
  return '/* clean-css ignore:start */' + id + '/* clean-css ignore:end */';
340
354
  }
@@ -864,19 +878,19 @@ function minify(value, options, partialMarkup) {
864
878
  value = value.replace(reCustomIgnore, function(match) {
865
879
  if (!uidAttr) {
866
880
  uidAttr = uniqueId(value);
867
- uidPattern = new RegExp('(\\s*)' + uidAttr + '([0-9]+)(\\s*)', 'g');
881
+ uidPattern = new RegExp('(\\s*)' + uidAttr + '([0-9]+)' + uidAttr + '(\\s*)', 'g');
868
882
  if (options.minifyCSS) {
869
883
  options.minifyCSS = (function(fn) {
870
884
  return function(text, type) {
871
885
  text = text.replace(uidPattern, function(match, prefix, index) {
872
886
  var chunks = ignoredCustomMarkupChunks[+index];
873
- return chunks[1] + uidAttr + index + chunks[2];
887
+ return chunks[1] + uidAttr + index + uidAttr + chunks[2];
874
888
  });
875
889
  var ids = [];
876
890
  new CleanCSS().minify(wrapCSS(text, type)).warnings.forEach(function(warning) {
877
891
  var match = uidPattern.exec(warning);
878
892
  if (match) {
879
- var id = uidAttr + match[2];
893
+ var id = uidAttr + match[2] + uidAttr;
880
894
  text = text.replace(id, ignoreCSS(id));
881
895
  ids.push(id);
882
896
  }
@@ -894,13 +908,13 @@ function minify(value, options, partialMarkup) {
894
908
  return function(text, type) {
895
909
  return fn(text.replace(uidPattern, function(match, prefix, index) {
896
910
  var chunks = ignoredCustomMarkupChunks[+index];
897
- return chunks[1] + uidAttr + index + chunks[2];
911
+ return chunks[1] + uidAttr + index + uidAttr + chunks[2];
898
912
  }), type);
899
913
  };
900
914
  })(options.minifyJS);
901
915
  }
902
916
  }
903
- var token = uidAttr + ignoredCustomMarkupChunks.length;
917
+ var token = uidAttr + ignoredCustomMarkupChunks.length + uidAttr;
904
918
  ignoredCustomMarkupChunks.push(/^(\s*)[\s\S]*?(\s*)$/.exec(match));
905
919
  return '\t' + token + '\t';
906
920
  });
@@ -965,6 +979,9 @@ function minify(value, options, partialMarkup) {
965
979
 
966
980
  new HTMLParser(value, {
967
981
  partialMarkup: partialMarkup,
982
+ continueOnParseError: options.continueOnParseError,
983
+ customAttrAssign: options.customAttrAssign,
984
+ customAttrSurround: options.customAttrSurround,
968
985
  html5: options.html5,
969
986
 
970
987
  start: function(tag, attrs, unary, unarySlash, autoGenerated) {
@@ -1241,9 +1258,7 @@ function minify(value, options, partialMarkup) {
1241
1258
  buffer.push(options.useShortDoctype ? '<!doctype' +
1242
1259
  (options.removeTagWhitespace ? '' : ' ') + 'html>' :
1243
1260
  collapseWhitespaceAll(doctype));
1244
- },
1245
- customAttrAssign: options.customAttrAssign,
1246
- customAttrSurround: options.customAttrSurround
1261
+ }
1247
1262
  });
1248
1263
 
1249
1264
  if (options.removeOptionalTags) {
package/src/htmlparser.js CHANGED
@@ -182,6 +182,11 @@ function HTMLParser(html, handler) {
182
182
  prevTag = startTagMatch.tagName.toLowerCase();
183
183
  continue;
184
184
  }
185
+
186
+ // Treat `<` as text
187
+ if (handler.continueOnParseError) {
188
+ textEnd = html.indexOf('<', 1);
189
+ }
185
190
  }
186
191
 
187
192
  var text;
@@ -213,7 +218,6 @@ function HTMLParser(html, handler) {
213
218
  handler.chars(text, prevTag, nextTag);
214
219
  }
215
220
  prevTag = '';
216
-
217
221
  }
218
222
  else {
219
223
  var stackedTag = lastTag.toLowerCase();