html-minifier 3.5.14 → 3.5.15

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.
Files changed (3) hide show
  1. package/README.md +11 -11
  2. package/package.json +2 -2
  3. package/src/htmlminifier.js +117 -119
package/README.md CHANGED
@@ -22,18 +22,18 @@ How does HTMLMinifier compare to other solutions — [HTML Minifier from Will Pe
22
22
 
23
23
  | Site | Original size *(KB)* | HTMLMinifier | minimize | Will Peavy | htmlcompressor.com |
24
24
  | ---------------------------------------------------------------------------- |:--------------------:| ------------:| --------:| ----------:| ------------------:|
25
- | [Google](https://www.google.com/) | 45 | **42** | 45 | 46 | 45 |
26
- | [Twitter](https://twitter.com/) | 122 | **89** | 114 | 132 | 114 |
27
- | [HTMLMinifier](https://github.com/kangax/html-minifier) | 141 | **110** | 118 | 123 | 118 |
28
- | [New York Times](https://www.nytimes.com/) | 214 | **147** | 165 | 161 | 150 |
29
- | [Stack Overflow](https://stackoverflow.com/) | 245 | **192** | 200 | 209 | 198 |
25
+ | [Google](https://www.google.com/) | 45 | **42** | 45 | 47 | 45 |
26
+ | [Twitter](https://twitter.com/) | 122 | **89** | 115 | 134 | 115 |
27
+ | [HTMLMinifier](https://github.com/kangax/html-minifier) | 142 | **110** | 119 | 123 | 118 |
28
+ | [New York Times](https://www.nytimes.com/) | 221 | **152** | 172 | 168 | 156 |
29
+ | [Stack Overflow](https://stackoverflow.com/) | 247 | **193** | 202 | 210 | 200 |
30
30
  | [Bootstrap CSS](https://getbootstrap.com/docs/3.3/css/) | 272 | **260** | 269 | 229 | 269 |
31
- | [BBC](https://www.bbc.co.uk/) | 299 | **241** | 291 | 294 | 277 |
32
- | [Amazon](https://www.amazon.co.uk/) | 369 | **315** | 356 | 367 | n/a |
33
- | [Wikipedia](https://en.wikipedia.org/wiki/President_of_the_United_States) | 473 | **441** | 458 | 473 | 457 |
34
- | [NBC](https://www.nbc.com/) | 689 | **648** | 685 | 688 | n/a |
31
+ | [BBC](https://www.bbc.co.uk/) | 283 | **228** | 275 | 278 | 262 |
32
+ | [Amazon](https://www.amazon.co.uk/) | 370 | **315** | 356 | 367 | n/a |
33
+ | [Wikipedia](https://en.wikipedia.org/wiki/President_of_the_United_States) | 474 | **442** | 458 | 473 | 457 |
34
+ | [NBC](https://www.nbc.com/) | 666 | **627** | 663 | 665 | n/a |
35
35
  | [Eloquent Javascript](https://eloquentjavascript.net/1st_edition/print.html) | 870 | **815** | 840 | 864 | n/a |
36
- | [ES6 table](https://kangax.github.io/compat-table/es6/) | 4808 | **4095** | 4548 | n/a | n/a |
36
+ | [ES6 table](https://kangax.github.io/compat-table/es6/) | 4916 | **4189** | 4652 | n/a | n/a |
37
37
  | [ES6 draft](https://tc39.github.io/ecma262/) | 6099 | **5435** | 5597 | n/a | n/a |
38
38
 
39
39
  ## Options Quick Reference
@@ -58,7 +58,7 @@ Most of the options are disabled by default.
58
58
  | `includeAutoGeneratedTags` | Insert tags generated by HTML parser | `true` |
59
59
  | `keepClosingSlash` | Keep the trailing slash on singleton elements | `false` |
60
60
  | `maxLineLength` | Specify a maximum line length. Compressed output will be split by newlines at valid HTML split-points |
61
- | `minifyCSS` | Minify CSS in style elements and style attributes (uses [clean-css](https://github.com/jakubpawlowicz/clean-css)) | `false` (could be `true`, `Object`, `Function(text)`) |
61
+ | `minifyCSS` | Minify CSS in style elements and style attributes (uses [clean-css](https://github.com/jakubpawlowicz/clean-css)) | `false` (could be `true`, `Object`, `Function(text, type)`) |
62
62
  | `minifyJS` | Minify JavaScript in script elements and event attributes (uses [UglifyJS](https://github.com/mishoo/UglifyJS2)) | `false` (could be `true`, `Object`, `Function(text, inline)`) |
63
63
  | `minifyURLs` | Minify URLs in various attributes (uses [relateurl](https://github.com/stevenvachon/relateurl)) | `false` (could be `String`, `Object`, `Function(text)`) |
64
64
  | `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` |
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.14",
4
+ "version": "3.5.15",
5
5
  "keywords": [
6
6
  "cli",
7
7
  "compress",
@@ -64,7 +64,7 @@
64
64
  },
65
65
  "devDependencies": {
66
66
  "grunt": "1.0.x",
67
- "grunt-browserify": "5.2.x",
67
+ "grunt-browserify": "5.3.x",
68
68
  "grunt-contrib-uglify": "3.3.x",
69
69
  "gruntify-eslint": "4.0.x",
70
70
  "phantomjs-prebuilt": "2.1.x",
@@ -285,7 +285,7 @@ function cleanAttributeValue(tag, attrName, attrValue, options, attrs) {
285
285
  if (/;$/.test(attrValue) && !/&#?[0-9a-zA-Z]+;$/.test(attrValue)) {
286
286
  attrValue = attrValue.replace(/\s*;$/, ';');
287
287
  }
288
- attrValue = unwrapInlineCSS(options.minifyCSS(wrapInlineCSS(attrValue)));
288
+ attrValue = options.minifyCSS(attrValue, 'inline');
289
289
  }
290
290
  return attrValue;
291
291
  }
@@ -322,7 +322,7 @@ function cleanAttributeValue(tag, attrName, attrValue, options, attrs) {
322
322
  }
323
323
  else if (isMediaQuery(tag, attrs, attrName)) {
324
324
  attrValue = trimWhitespace(attrValue);
325
- return unwrapMediaQuery(options.minifyCSS(wrapMediaQuery(attrValue)));
325
+ return options.minifyCSS(attrValue, 'media');
326
326
  }
327
327
  return attrValue;
328
328
  }
@@ -613,100 +613,107 @@ function identity(value) {
613
613
  return value;
614
614
  }
615
615
 
616
- function processOptions(options) {
617
- ['html5', 'includeAutoGeneratedTags'].forEach(function(key) {
618
- if (!(key in options)) {
619
- options[key] = true;
620
- }
621
- });
622
-
623
- if (typeof options.log !== 'function') {
624
- options.log = identity;
625
- }
626
-
627
- if (!options.canCollapseWhitespace) {
628
- options.canCollapseWhitespace = canCollapseWhitespace;
629
- }
630
- if (!options.canTrimWhitespace) {
631
- options.canTrimWhitespace = canTrimWhitespace;
632
- }
633
-
634
- if (!('ignoreCustomComments' in options)) {
635
- options.ignoreCustomComments = [/^!/];
636
- }
637
-
638
- if (!('ignoreCustomFragments' in options)) {
639
- options.ignoreCustomFragments = [
616
+ function processOptions(values) {
617
+ var options = {
618
+ canCollapseWhitespace: canCollapseWhitespace,
619
+ canTrimWhitespace: canTrimWhitespace,
620
+ html5: true,
621
+ ignoreCustomComments: [/^!/],
622
+ ignoreCustomFragments: [
640
623
  /<%[\s\S]*?%>/,
641
624
  /<\?[\s\S]*?\?>/
642
- ];
643
- }
644
-
645
- if (!options.minifyURLs) {
646
- options.minifyURLs = identity;
647
- }
648
- if (typeof options.minifyURLs !== 'function') {
649
- var minifyURLs = options.minifyURLs;
650
- if (typeof minifyURLs === 'string') {
651
- minifyURLs = { site: minifyURLs };
652
- }
653
- else if (typeof minifyURLs !== 'object') {
654
- minifyURLs = {};
625
+ ],
626
+ includeAutoGeneratedTags: true,
627
+ log: identity,
628
+ minifyCSS: identity,
629
+ minifyJS: identity,
630
+ minifyURLs: identity
631
+ };
632
+ Object.keys(values).forEach(function(key) {
633
+ var value = values[key];
634
+ if (key === 'log') {
635
+ if (typeof value === 'function') {
636
+ options.log = value;
637
+ }
655
638
  }
656
- options.minifyURLs = function(text) {
657
- try {
658
- return RelateUrl.relate(text, minifyURLs);
639
+ else if (key === 'minifyCSS' && typeof value !== 'function') {
640
+ if (!value) {
641
+ return;
659
642
  }
660
- catch (err) {
661
- options.log(err);
662
- return text;
643
+ if (typeof value !== 'object') {
644
+ value = {};
663
645
  }
664
- };
665
- }
666
-
667
- if (!options.minifyJS) {
668
- options.minifyJS = identity;
669
- }
670
- if (typeof options.minifyJS !== 'function') {
671
- var minifyJS = options.minifyJS;
672
- if (typeof minifyJS !== 'object') {
673
- minifyJS = {};
646
+ options.minifyCSS = function(text, type) {
647
+ text = text.replace(/(url\s*\(\s*)("|'|)(.*?)\2(\s*\))/ig, function(match, prefix, quote, url, suffix) {
648
+ return prefix + quote + options.minifyURLs(url) + quote + suffix;
649
+ });
650
+ try {
651
+ if (type === 'inline') {
652
+ text = wrapInlineCSS(text);
653
+ }
654
+ else if (type === 'media') {
655
+ text = wrapMediaQuery(text);
656
+ }
657
+ text = new CleanCSS(value).minify(text).styles;
658
+ if (type === 'inline') {
659
+ text = unwrapInlineCSS(text);
660
+ }
661
+ else if (type === 'media') {
662
+ text = unwrapMediaQuery(text);
663
+ }
664
+ return text;
665
+ }
666
+ catch (err) {
667
+ options.log(err);
668
+ return text;
669
+ }
670
+ };
674
671
  }
675
- (minifyJS.parse || (minifyJS.parse = {})).bare_returns = false;
676
- options.minifyJS = function(text, inline) {
677
- var start = text.match(/^\s*<!--.*/);
678
- var code = start ? text.slice(start[0].length).replace(/\n\s*-->\s*$/, '') : text;
679
- minifyJS.parse.bare_returns = inline;
680
- var result = UglifyJS.minify(code, minifyJS);
681
- if (result.error) {
682
- options.log(result.error);
683
- return text;
672
+ else if (key === 'minifyJS' && typeof value !== 'function') {
673
+ if (!value) {
674
+ return;
684
675
  }
685
- return result.code.replace(/;$/, '');
686
- };
687
- }
688
-
689
- if (!options.minifyCSS) {
690
- options.minifyCSS = identity;
691
- }
692
- if (typeof options.minifyCSS !== 'function') {
693
- var minifyCSS = options.minifyCSS;
694
- if (typeof minifyCSS !== 'object') {
695
- minifyCSS = {};
676
+ if (typeof value !== 'object') {
677
+ value = {};
678
+ }
679
+ (value.parse || (value.parse = {})).bare_returns = false;
680
+ options.minifyJS = function(text, inline) {
681
+ var start = text.match(/^\s*<!--.*/);
682
+ var code = start ? text.slice(start[0].length).replace(/\n\s*-->\s*$/, '') : text;
683
+ value.parse.bare_returns = inline;
684
+ var result = UglifyJS.minify(code, value);
685
+ if (result.error) {
686
+ options.log(result.error);
687
+ return text;
688
+ }
689
+ return result.code.replace(/;$/, '');
690
+ };
696
691
  }
697
- options.minifyCSS = function(text) {
698
- text = text.replace(/(url\s*\(\s*)("|'|)(.*?)\2(\s*\))/ig, function(match, prefix, quote, url, suffix) {
699
- return prefix + quote + options.minifyURLs(url) + quote + suffix;
700
- });
701
- try {
702
- return new CleanCSS(minifyCSS).minify(text).styles;
692
+ else if (key === 'minifyURLs' && typeof value !== 'function') {
693
+ if (!value) {
694
+ return;
703
695
  }
704
- catch (err) {
705
- options.log(err);
706
- return text;
696
+ if (typeof value === 'string') {
697
+ value = { site: value };
707
698
  }
708
- };
709
- }
699
+ else if (typeof value !== 'object') {
700
+ value = {};
701
+ }
702
+ options.minifyURLs = function(text) {
703
+ try {
704
+ return RelateUrl.relate(text, value);
705
+ }
706
+ catch (err) {
707
+ options.log(err);
708
+ return text;
709
+ }
710
+ };
711
+ }
712
+ else {
713
+ options[key] = value;
714
+ }
715
+ });
716
+ return options;
710
717
  }
711
718
 
712
719
  function uniqueId(value) {
@@ -771,7 +778,7 @@ function createSortFns(value, options, uidIgnore, uidAttr) {
771
778
  }
772
779
 
773
780
  var log = options.log;
774
- options.log = null;
781
+ options.log = identity;
775
782
  options.sortAttributes = false;
776
783
  options.sortClassName = false;
777
784
  scan(minify(value, options));
@@ -804,9 +811,6 @@ function createSortFns(value, options, uidIgnore, uidAttr) {
804
811
  }
805
812
 
806
813
  function minify(value, options, partialMarkup) {
807
- options = options || {};
808
- var optionsStack = [];
809
- processOptions(options);
810
814
  if (options.collapseWhitespace) {
811
815
  value = collapseWhitespace(value, options, true, true);
812
816
  }
@@ -821,7 +825,6 @@ function minify(value, options, partialMarkup) {
821
825
  stackNoCollapseWhitespace = [],
822
826
  optionalStartTag = '',
823
827
  optionalEndTag = '',
824
- t = Date.now(),
825
828
  ignoredMarkupChunks = [],
826
829
  ignoredCustomMarkupChunks = [],
827
830
  uidIgnore,
@@ -837,22 +840,25 @@ function minify(value, options, partialMarkup) {
837
840
  uidIgnore = uniqueId(value);
838
841
  var pattern = new RegExp('^' + uidIgnore + '([0-9]+)$');
839
842
  if (options.ignoreCustomComments) {
840
- options.ignoreCustomComments.push(pattern);
843
+ options.ignoreCustomComments = options.ignoreCustomComments.slice();
841
844
  }
842
845
  else {
843
- options.ignoreCustomComments = [pattern];
846
+ options.ignoreCustomComments = [];
844
847
  }
848
+ options.ignoreCustomComments.push(pattern);
845
849
  }
846
850
  var token = '<!--' + uidIgnore + ignoredMarkupChunks.length + '-->';
847
851
  ignoredMarkupChunks.push(group1);
848
852
  return token;
849
853
  });
850
854
 
851
- function escapeFragments(text) {
852
- return text.replace(uidPattern, function(match, prefix, index) {
853
- var chunks = ignoredCustomMarkupChunks[+index];
854
- return chunks[1] + uidAttr + index + chunks[2];
855
- });
855
+ function escapeFragments(fn) {
856
+ return function(text, type) {
857
+ return fn(text.replace(uidPattern, function(match, prefix, index) {
858
+ var chunks = ignoredCustomMarkupChunks[+index];
859
+ return chunks[1] + uidAttr + index + chunks[2];
860
+ }), type);
861
+ };
856
862
  }
857
863
 
858
864
  var customFragments = options.ignoreCustomFragments.map(function(re) {
@@ -865,17 +871,11 @@ function minify(value, options, partialMarkup) {
865
871
  if (!uidAttr) {
866
872
  uidAttr = uniqueId(value);
867
873
  uidPattern = new RegExp('(\\s*)' + uidAttr + '([0-9]+)(\\s*)', 'g');
868
- var minifyCSS = options.minifyCSS;
869
- if (minifyCSS) {
870
- options.minifyCSS = function(text) {
871
- return minifyCSS(escapeFragments(text));
872
- };
874
+ if (options.minifyCSS) {
875
+ options.minifyCSS = escapeFragments(options.minifyCSS);
873
876
  }
874
- var minifyJS = options.minifyJS;
875
- if (minifyJS) {
876
- options.minifyJS = function(text, inline) {
877
- return minifyJS(escapeFragments(text), inline);
878
- };
877
+ if (options.minifyJS) {
878
+ options.minifyJS = escapeFragments(options.minifyJS);
879
879
  }
880
880
  }
881
881
  var token = uidAttr + ignoredCustomMarkupChunks.length;
@@ -949,14 +949,9 @@ function minify(value, options, partialMarkup) {
949
949
  var lowerTag = tag.toLowerCase();
950
950
 
951
951
  if (lowerTag === 'svg') {
952
- optionsStack.push(options);
953
- var nextOptions = {};
954
- for (var key in options) {
955
- nextOptions[key] = options[key];
956
- }
957
- nextOptions.keepClosingSlash = true;
958
- nextOptions.caseSensitive = true;
959
- options = nextOptions;
952
+ options = Object.create(options);
953
+ options.keepClosingSlash = true;
954
+ options.caseSensitive = true;
960
955
  }
961
956
 
962
957
  tag = options.caseSensitive ? tag : lowerTag;
@@ -1042,7 +1037,7 @@ function minify(value, options, partialMarkup) {
1042
1037
  end: function(tag, attrs, autoGenerated) {
1043
1038
  var lowerTag = tag.toLowerCase();
1044
1039
  if (lowerTag === 'svg') {
1045
- options = optionsStack.pop();
1040
+ options = Object.getPrototypeOf(options);
1046
1041
  }
1047
1042
  tag = options.caseSensitive ? tag : lowerTag;
1048
1043
 
@@ -1269,7 +1264,6 @@ function minify(value, options, partialMarkup) {
1269
1264
  });
1270
1265
  }
1271
1266
 
1272
- options.log('minified in: ' + (Date.now() - t) + 'ms');
1273
1267
  return str;
1274
1268
  }
1275
1269
 
@@ -1301,5 +1295,9 @@ function joinResultSegments(results, options) {
1301
1295
  }
1302
1296
 
1303
1297
  exports.minify = function(value, options) {
1304
- return minify(value, options);
1298
+ var start = Date.now();
1299
+ options = processOptions(options || {});
1300
+ var result = minify(value, options);
1301
+ options.log('minified in: ' + (Date.now() - start) + 'ms');
1302
+ return result;
1305
1303
  };