htmlnano 0.2.5 → 0.2.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 CHANGED
@@ -2,6 +2,61 @@
2
2
  All notable changes to this project will be documented in this file.
3
3
  This project adheres to [Semantic Versioning](http://semver.org/).
4
4
 
5
+
6
+ ## [0.2.9] - 2021-04-11
7
+ ### Added
8
+ - `minifyConditionalComment` support `<html>` [#125].
9
+ - Minify JS within `<script type="module">` [#135].
10
+
11
+ ### Fixed
12
+ - `collapseWhitespaces` around comment [#120].
13
+ - handle `CDATA` inside script correctly [#122].
14
+ - Minify SVG correctly [#129].
15
+
16
+ ### Changed
17
+ - Upgrade to terser@5 (JS minification).
18
+
19
+
20
+
21
+ ## [0.2.8] - 2020-11-15
22
+ ### Added
23
+ - [`removeOptionalTags`](https://github.com/posthtml/htmlnano#removeoptionaltags) [#110].
24
+ - [`sortAttributes`](https://github.com/posthtml/htmlnano#removeoptionaltags) [#113].
25
+ - `source[src]` and `srcset` support to `minifyUrls` [#117].
26
+ - [`minifyConditionalComments`](https://github.com/posthtml/htmlnano#minifyconditionalcomments) [#119].
27
+
28
+ ### Changed
29
+ - Sort by frequency `sortAttributesWithLists` [#111].
30
+ - Strip more spaces in `collapseWhitespace` [#112].
31
+ - Remove `loading="eager"` from `<img>` and `<iframe>` [#114].
32
+ - Remove redundant `type` from `<script>` [#114].
33
+ - Strip whitespaces between textnode and element [#116].
34
+
35
+
36
+
37
+ ## [0.2.7] - 2020-10-17
38
+ ### Added
39
+ - More aggressive whitespace removal option [#90].
40
+ - Cloudflare SSE support to `removeComments` [#94].
41
+ - Improve compression ratio by sorting attribute values [#95].
42
+ - New `minifyUrls` module [#98].
43
+ - New `removeAttributeQuotes` module [#104].
44
+ - Remove `type=text/css` for `link[rel=stylesheet]` [#102].
45
+ - Collapse `crossorigin` attributes [#107].
46
+ - Exclude excerpt comment for common CMS [#108].
47
+
48
+ ### Fixed
49
+ - Keep JS inside SVG wrapped in `//<![CDATA[ //]]` [#88].
50
+
51
+
52
+ ## [0.2.6] - 2020-07-15
53
+ ### Added
54
+ - Let PostHTML options to be passed.
55
+
56
+ ### Fixed
57
+ - `<script>` tags merging without content.
58
+
59
+
5
60
  ## [0.2.5] - 2019-11-09
6
61
  ### Added
7
62
  - Option to remove unused CSS using PurgeCSS [#84].
@@ -128,7 +183,10 @@ This project adheres to [Semantic Versioning](http://semver.org/).
128
183
  - Remove attributes that contains only white spaces.
129
184
 
130
185
 
131
-
186
+ [0.2.9]: https://github.com/posthtml/htmlnano/compare/0.2.8...0.2.9
187
+ [0.2.8]: https://github.com/posthtml/htmlnano/compare/0.2.7...0.2.8
188
+ [0.2.7]: https://github.com/posthtml/htmlnano/compare/0.2.6...0.2.7
189
+ [0.2.6]: https://github.com/posthtml/htmlnano/compare/0.2.5...0.2.6
132
190
  [0.2.5]: https://github.com/posthtml/htmlnano/compare/0.2.4...0.2.5
133
191
  [0.2.4]: https://github.com/posthtml/htmlnano/compare/0.2.3...0.2.4
134
192
  [0.2.3]: https://github.com/posthtml/htmlnano/compare/0.2.2...0.2.3
@@ -146,7 +204,28 @@ This project adheres to [Semantic Versioning](http://semver.org/).
146
204
  [0.1.2]: https://github.com/posthtml/htmlnano/compare/0.1.1...0.1.2
147
205
  [0.1.1]: https://github.com/posthtml/htmlnano/compare/0.1.0...0.1.1
148
206
 
149
-
207
+ [#135]: https://github.com/posthtml/htmlnano/issues/135
208
+ [#129]: https://github.com/posthtml/htmlnano/issues/129
209
+ [#125]: https://github.com/posthtml/htmlnano/issues/125
210
+ [#122]: https://github.com/posthtml/htmlnano/issues/122
211
+ [#120]: https://github.com/posthtml/htmlnano/issues/120
212
+ [#119]: https://github.com/posthtml/htmlnano/issues/119
213
+ [#117]: https://github.com/posthtml/htmlnano/issues/117
214
+ [#116]: https://github.com/posthtml/htmlnano/issues/116
215
+ [#114]: https://github.com/posthtml/htmlnano/issues/114
216
+ [#113]: https://github.com/posthtml/htmlnano/issues/113
217
+ [#112]: https://github.com/posthtml/htmlnano/issues/112
218
+ [#111]: https://github.com/posthtml/htmlnano/issues/111
219
+ [#110]: https://github.com/posthtml/htmlnano/issues/110
220
+ [#107]: https://github.com/posthtml/htmlnano/issues/107
221
+ [#108]: https://github.com/posthtml/htmlnano/issues/108
222
+ [#102]: https://github.com/posthtml/htmlnano/issues/102
223
+ [#104]: https://github.com/posthtml/htmlnano/issues/104
224
+ [#98]: https://github.com/posthtml/htmlnano/issues/98
225
+ [#95]: https://github.com/posthtml/htmlnano/issues/95
226
+ [#94]: https://github.com/posthtml/htmlnano/issues/94
227
+ [#90]: https://github.com/posthtml/htmlnano/issues/90
228
+ [#88]: https://github.com/posthtml/htmlnano/issues/88
150
229
  [#84]: https://github.com/posthtml/htmlnano/issues/84
151
230
  [#80]: https://github.com/posthtml/htmlnano/issues/80
152
231
  [#79]: https://github.com/posthtml/htmlnano/issues/79
package/README.md CHANGED
@@ -8,16 +8,16 @@ Modular HTML minifier, built on top of the [PostHTML](https://github.com/posthtm
8
8
 
9
9
 
10
10
  ## [Benchmark](https://github.com/maltsev/html-minifiers-benchmark/blob/master/README.md)
11
- [html-minifier@3.5.20]: https://www.npmjs.com/package/html-minifier
12
- [htmlnano@0.2.0]: https://www.npmjs.com/package/htmlnano
11
+ [html-minifier@4.0.0]: https://www.npmjs.com/package/html-minifier
12
+ [htmlnano@0.2.8]: https://www.npmjs.com/package/htmlnano
13
13
 
14
- | Website | Source (KB) | [html-minifier@3.5.20] | [htmlnano@0.2.0] |
14
+ | Website | Source (KB) | [html-minifier@4.0.0] | [htmlnano@0.2.8] |
15
15
  |---------|------------:|----------------:|-----------:|
16
- | [stackoverflow.com](http://stackoverflow.com/) | 258 | 205 | 218 |
17
- | [github.com](http://github.com/) | 63 | 51 | 56 |
18
- | [en.wikipedia.org](https://en.wikipedia.org/wiki/Main_Page) | 77 | 69 | 74 |
19
- | [npmjs.com](https://www.npmjs.com/features) | 32 | 29 | 30 |
20
- | **Avg. minify rate** | 0% | **15%** | **9%** |
16
+ | [stackoverflow.blog](https://stackoverflow.blog/) | 78 | 72 | 66 |
17
+ | [github.com](https://github.com/) | 215 | 187 | 177 |
18
+ | [en.wikipedia.org](https://en.wikipedia.org/wiki/Main_Page) | 78 | 73 | 72 |
19
+ | [npmjs.com](https://www.npmjs.com/features) | 29 | 25 | 25 |
20
+ | **Avg. minify rate** | 0% | **10%** | **13%** |
21
21
 
22
22
 
23
23
  ## Usage
@@ -49,10 +49,17 @@ const options = {
49
49
  removeEmptyAttributes: false, // Disable the module "removeEmptyAttributes"
50
50
  collapseWhitespace: 'conservative' // Pass options to the module "collapseWhitespace"
51
51
  };
52
+ // posthtml, posthtml-render, and posthtml-parse options
53
+ const postHtmlOptions = {
54
+ sync: true, // https://github.com/posthtml/posthtml#usage
55
+ lowerCaseTags: true, // https://github.com/posthtml/posthtml-parser#options
56
+ quoteAllAttributes: false, // https://github.com/posthtml/posthtml-render#options
57
+ };
52
58
 
53
59
  htmlnano
54
60
  // "preset" arg might be skipped (see "Presets" section below for more info)
55
- .process(html, options, preset)
61
+ // "postHtmlOptions" arg might be skipped
62
+ .process(html, options, preset, postHtmlOptions)
56
63
  .then(function (result) {
57
64
  // result.html is minified
58
65
  })
@@ -76,8 +83,12 @@ const posthtmlPlugins = [
76
83
  require('htmlnano')(options)
77
84
  ];
78
85
 
86
+ const postHtmlOptions = {
87
+ // See PostHTML docs
88
+ };
89
+
79
90
  posthtml(posthtmlPlugins)
80
- .process(html)
91
+ .process(html, posthtmlOptions)
81
92
  .then(function (result) {
82
93
  // result.html is minified
83
94
  })
@@ -191,29 +202,39 @@ Collapses redundant white spaces (including new lines). It doesn’t affect whit
191
202
 
192
203
  ##### Options
193
204
  - `conservative` — collapses all redundant white spaces to 1 space (default)
205
+ - `aggressive` — collapses all whitespaces that are redundant and safe to remove
194
206
  - `all` — collapses all redundant white spaces
195
207
 
196
208
  ##### Side effects
197
- `<i>hello</i> <i>world</i>` after minification will be rendered as `helloworld`.
198
- To prevent that use `conservative` option (this is the default option).
209
+
210
+ *all*
211
+ `<i>hello</i> <i>world</i>` or `<i>hello</i><br><i>world</i>` after minification will be rendered as `helloworld`.
212
+ To prevent that use either the default `conservative` option, or the `aggressive` option.
199
213
 
200
214
  ##### Example
201
215
  Source:
202
216
  ```html
203
217
  <div>
204
218
  hello world!
219
+ <a href="#">answer</a>
205
220
  <style>div { color: red; } </style>
221
+ <main></main>
206
222
  </div>
207
223
  ```
208
224
 
209
225
  Minified (with `all`):
210
226
  ```html
211
- <div>hello world!<style>div { color: red; } </style></div>
227
+ <div>hello world!<a href="#">answer</a><style>div { color: red; } </style><main></main></div>
228
+ ```
229
+
230
+ Minified (with `aggressive`):
231
+ ```html
232
+ <div> hello world! <a href="#">answer</a> <style>div { color: red; } </style><main></main></div>
212
233
  ```
213
234
 
214
235
  Minified (with `conservative`):
215
236
  ```html
216
- <div> hello world! <style>div { color: red; } </style> </div>
237
+ <div> hello world! <a href="#">answer</a> <style>div { color: red; } </style> <main></main> </div>
217
238
  ```
218
239
 
219
240
 
@@ -271,6 +292,37 @@ Minified:
271
292
  <img src="foo.jpg" alt="">
272
293
  ```
273
294
 
295
+ ### removeAttributeQuotes
296
+ Remove quotes around attributes when possible, see [HTML Standard - 12.1.2.3 Attributes - Unquoted attribute value syntax](https://html.spec.whatwg.org/multipage/syntax.html#attributes-2).
297
+
298
+ ##### Example
299
+ Source:
300
+ ```html
301
+ <div class="foo" title="hello world"></div>
302
+ ```
303
+
304
+ Minified:
305
+ ```html
306
+ <div class=foo title="hello world"></div>
307
+ ```
308
+
309
+ ##### Notice
310
+ The feature is implemented by [posthtml-render's `quoteAllAttributes`](https://github.com/posthtml/posthtml-render#options), which is one of the PostHTML's option. So `removeAttributeQuotes` could be overriden by other PostHTML's plugins and PostHTML's configuration.
311
+
312
+ For example:
313
+
314
+ ```js
315
+ posthtml([
316
+ htmlnano({
317
+ removeAttributeQuotes: true
318
+ })
319
+ ]).process(html, {
320
+ quoteAllAttributes: true
321
+ })
322
+ ```
323
+
324
+ `removeAttributeQuotes` will not work because PostHTML's `quoteAllAttributes` takes the priority.
325
+
274
326
  ### removeUnusedCss
275
327
 
276
328
  Removes unused CSS inside `<style>` tags with either [uncss](https://github.com/uncss/uncss)
@@ -477,6 +529,29 @@ Minified:
477
529
  <svg baseProfile="full" width="300" height="200" xmlns="http://www.w3.org/2000/svg"><rect width="100%" height="100%" fill="red"/><circle cx="150" cy="100" r="80" fill="green"/><text x="150" y="125" font-size="60" text-anchor="middle" fill="#fff">SVG</text></svg>
478
530
  ```
479
531
 
532
+ ### minifyConditionalComments
533
+
534
+ Minify content inside conditional comments.
535
+
536
+ ##### Example
537
+
538
+ Source:
539
+
540
+ ```html
541
+ <!--[if lte IE 7]>
542
+ <style type="text/css">
543
+ .title {
544
+ color: red;
545
+ }
546
+ </style>
547
+ <![endif]-->
548
+ ```
549
+
550
+ Minified:
551
+
552
+ ```html
553
+ <!--[if lte IE 7]><style>.title{color:red}</style><![endif]-->
554
+ ```
480
555
 
481
556
  ### removeRedundantAttributes
482
557
  Removes redundant attributes from tags if they contain default values:
@@ -486,6 +561,7 @@ Removes redundant attributes from tags if they contain default values:
486
561
  - `language="javascript"` and `type="text/javascript"` from `<script>`
487
562
  - `charset` from `<script>` if it's an external script
488
563
  - `media="all"` from `<style>` and `<link>`
564
+ - `type="text/css"` from `<link rel="stylesheet">`
489
565
 
490
566
  ##### Options
491
567
  This module is disabled by default, change option to true to enable this module.
@@ -627,13 +703,190 @@ const options = {
627
703
 
628
704
  `options` is an object with all options that were passed to the plugin.
629
705
 
706
+ ### sortAttributesWithLists
707
+ Sort values in list-like attributes (`class`, `rel`, `ping`).
708
+
709
+ The module won't impact the plain-text size of the output. However it will improve the compression ratio of gzip/brotli used in HTTP compression.
710
+
711
+ ##### Options
712
+
713
+ - `alphabetical`: Default option. Sort attribute values in alphabetical order.
714
+ - `frequency`: Sort attribute values by frequency.
715
+
716
+ ##### Example
717
+
718
+ **alphabetical**
719
+
720
+ Source:
721
+ ```html
722
+ <div class="foo baz bar">click</div>
723
+ ```
724
+
725
+ Processed:
726
+ ```html
727
+ <div class="bar baz foo">click</div>
728
+ ```
729
+
730
+ **frequency**
731
+
732
+ Source:
733
+ ```html
734
+ <div class="foo baz bar"></div><div class="bar foo"></div>
735
+ ```
736
+
737
+ Processed:
738
+ ```html
739
+ <div class="foo bar baz"></div><div class="foo bar"></div>
740
+ ```
741
+
742
+ ### sortAttributes
743
+ Sort attributes inside elements.
744
+
745
+ The module won't impact the plain-text size of the output. However it will improve the compression ratio of gzip/brotli used in HTTP compression.
746
+
747
+ ##### Options
748
+
749
+ - `alphabetical`: Default option. Sort attributes in alphabetical order.
750
+ - `frequency`: Sort attributes by frequency.
751
+
752
+ ##### Example
753
+
754
+ **alphabetical**
755
+
756
+ Source:
757
+ ```html
758
+ <input type="text" class="form-control" name="testInput" autofocus="" autocomplete="off" id="testId">
759
+ ```
760
+
761
+ Processed:
762
+ ```html
763
+ <input autocomplete="off" autofocus="" class="form-control" id="testId" name="testInput" type="text">
764
+ ```
765
+
766
+ **frequency**
767
+
768
+ Source:
769
+ ```html
770
+ <input type="text" class="form-control" name="testInput" id="testId">
771
+ <a id="testId" href="#" class="testClass"></a>
772
+ <img width="20" src="../images/image.png" height="40" alt="image" class="cls" id="id2">
773
+ ```
774
+
775
+ Processed:
776
+ ```html
777
+ <input class="form-control" id="testId" type="text" name="testInput">
778
+ <a class="testClass" id="testId" href="#"></a>
779
+ <img class="cls" id="id2" width="20" src="../images/image.png" height="40" alt="image">
780
+ ```
781
+
782
+ ### minifyUrls
783
+ Convert absolute URL to relative URL using [relateurl](https://www.npmjs.com/package/relateurl).
784
+
785
+ ##### Options
786
+
787
+ The base URL to resolve against. Support `String` & `URL`.
788
+
789
+ ```js
790
+ htmlnano.process(html, {
791
+ minifyUrls: 'https://example.com' // Valid configuration
792
+ });
793
+ ```
794
+
795
+ ```js
796
+ htmlnano.process(html, {
797
+ minifyUrls: new URL('https://example.com') // Valid configuration
798
+ });
799
+ ```
800
+
801
+ ```js
802
+ htmlnano.process(html, {
803
+ minifyUrls: false // The module will be disabled
804
+ });
805
+ ```
806
+
807
+ ```js
808
+ htmlnano.process(html, {
809
+ minifyUrls: true // Invalid configuration, the module will be disabled
810
+ });
811
+ ```
812
+
813
+ ##### Example
814
+
815
+ **Basic Usage**
816
+
817
+ Configuration:
818
+
819
+ ```js
820
+ htmlnano.process(html, {
821
+ minifyUrls: 'https://example.com'
822
+ });
823
+ ```
824
+
825
+ Source:
826
+
827
+ ```html
828
+ <a href="https://example.com/foo/bar/baz">bar</a>
829
+ ```
830
+
831
+ Minified:
832
+
833
+ ```html
834
+ <a href="foo/bar/baz">bar</a>
835
+ ```
836
+
837
+ **With sub-directory**
838
+
839
+ Configuration:
840
+
841
+ ```js
842
+ htmlnano.process(html, {
843
+ minifyUrls: 'https://example.com/foo/baz/'
844
+ });
845
+ ```
846
+
847
+ Source:
848
+
849
+ ```html
850
+ <a href="https://example.com/foo/bar">bar</a>
851
+ ```
852
+
853
+ Minified:
854
+
855
+ ```html
856
+ <a href="../bar">bar</a>
857
+ ```
858
+
859
+ ## removeOptionalTags
860
+ Remove certain tags that can be omitted, see [HTML Standard - 13.1.2.4 Optional tags](https://html.spec.whatwg.org/multipage/syntax.html#optional-tags).
861
+
862
+ ##### Example
863
+
864
+ Source:
865
+
866
+ ```html
867
+ <html><head><title>Title</title></head><body><p>Hi</p></body></html>
868
+ ```
869
+
870
+ Minified:
871
+
872
+ ```html
873
+ <title>Title</title><p>Hi</p>
874
+ ```
875
+ ##### Notice
876
+ Due to [the limitation of PostHTML](https://github.com/posthtml/htmlnano/issues/99), htmlnano can't remove only the start tag or the end tag of an element. Currently, htmlnano only supports removing the following optional tags, as htmlnano can remove their start tag and end tag at the same time:
877
+
878
+ - `html`
879
+ - `head`
880
+ - `body`
881
+ - `colgroup`
882
+ - `tbody`
630
883
 
631
884
  ## Contribute
632
885
  Since the minifier is modular, it's very easy to add new modules:
633
886
 
634
887
  1. Create a ES6-file inside `lib/modules/` with a function that does some minification. For example you can check [`lib/modules/example.es6`](https://github.com/posthtml/htmlnano/blob/master/lib/modules/example.es6).
635
888
 
636
- 2. Add the module in [the modules array](https://github.com/posthtml/htmlnano/blob/master/lib/htmlnano.es6#L5). The modules are applied from top to bottom. So you can choose the order for your module.
889
+ 2. Add the module's name into one of those [presets](https://github.com/posthtml/htmlnano/tree/master/lib/presets). You can choose either `ampSafe`, `max`, or `safe`.
637
890
 
638
891
  3. Create a JS-file inside `test/modules/` with some unit-tests.
639
892
 
package/lib/helpers.js CHANGED
@@ -1,61 +1,41 @@
1
- 'use strict';
1
+ "use strict";
2
2
 
3
3
  Object.defineProperty(exports, "__esModule", {
4
- value: true
4
+ value: true
5
5
  });
6
6
  exports.isAmpBoilerplate = isAmpBoilerplate;
7
7
  exports.isComment = isComment;
8
8
  exports.isConditionalComment = isConditionalComment;
9
9
  exports.isStyleNode = isStyleNode;
10
10
  exports.extractCssFromStyleNode = extractCssFromStyleNode;
11
- var ampBoilerplateAttributes = ['amp-boilerplate', 'amp4ads-boilerplate', 'amp4email-boilerplate'];
11
+ const ampBoilerplateAttributes = ['amp-boilerplate', 'amp4ads-boilerplate', 'amp4email-boilerplate'];
12
12
 
13
13
  function isAmpBoilerplate(node) {
14
- if (!node.attrs) {
15
- return false;
16
- }
17
- var _iteratorNormalCompletion = true;
18
- var _didIteratorError = false;
19
- var _iteratorError = undefined;
20
-
21
- try {
22
- for (var _iterator = ampBoilerplateAttributes[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
23
- var attr = _step.value;
24
-
25
- if (attr in node.attrs) {
26
- return true;
27
- }
28
- }
29
- } catch (err) {
30
- _didIteratorError = true;
31
- _iteratorError = err;
32
- } finally {
33
- try {
34
- if (!_iteratorNormalCompletion && _iterator.return) {
35
- _iterator.return();
36
- }
37
- } finally {
38
- if (_didIteratorError) {
39
- throw _iteratorError;
40
- }
41
- }
14
+ if (!node.attrs) {
15
+ return false;
16
+ }
17
+
18
+ for (const attr of ampBoilerplateAttributes) {
19
+ if (attr in node.attrs) {
20
+ return true;
42
21
  }
22
+ }
43
23
 
44
- return false;
24
+ return false;
45
25
  }
46
26
 
47
27
  function isComment(content) {
48
- return (content || '').trim().search('<!--') === 0;
28
+ return (content || '').trim().startsWith('<!--');
49
29
  }
50
30
 
51
31
  function isConditionalComment(content) {
52
- return (content || '').trim().search(/<!--\[if/) === 0;
32
+ return (content || '').trim().startsWith('<!--[if');
53
33
  }
54
34
 
55
35
  function isStyleNode(node) {
56
- return node.tag === 'style' && !isAmpBoilerplate(node) && 'content' in node && node.content.length > 0;
36
+ return node.tag === 'style' && !isAmpBoilerplate(node) && 'content' in node && node.content.length > 0;
57
37
  }
58
38
 
59
39
  function extractCssFromStyleNode(node) {
60
- return Array.isArray(node.content) ? node.content.join(' ') : node.content;
40
+ return Array.isArray(node.content) ? node.content.join(' ') : node.content;
61
41
  }
package/lib/htmlnano.js CHANGED
@@ -1,90 +1,54 @@
1
- 'use strict';
1
+ "use strict";
2
2
 
3
3
  Object.defineProperty(exports, "__esModule", {
4
- value: true
4
+ value: true
5
5
  });
6
+ exports.default = void 0;
6
7
 
7
- var _posthtml = require('posthtml');
8
+ var _posthtml = _interopRequireDefault(require("posthtml"));
8
9
 
9
- var _posthtml2 = _interopRequireDefault(_posthtml);
10
+ var _safe = _interopRequireDefault(require("./presets/safe"));
10
11
 
11
- var _safe = require('./presets/safe');
12
+ var _ampSafe = _interopRequireDefault(require("./presets/ampSafe"));
12
13
 
13
- var _safe2 = _interopRequireDefault(_safe);
14
-
15
- var _ampSafe = require('./presets/ampSafe');
16
-
17
- var _ampSafe2 = _interopRequireDefault(_ampSafe);
18
-
19
- var _max = require('./presets/max');
20
-
21
- var _max2 = _interopRequireDefault(_max);
14
+ var _max = _interopRequireDefault(require("./presets/max"));
22
15
 
23
16
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
24
17
 
25
- function htmlnano() {
26
- var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
27
- var preset = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : _safe2.default;
28
-
29
- return function minifier(tree) {
30
- options = Object.assign({}, preset, options);
31
- var promise = Promise.resolve(tree);
32
-
33
- var _loop = function _loop(moduleName) {
34
- if (!options[moduleName]) {
35
- // The module is disabled
36
- return 'continue';
37
- }
38
-
39
- if (_safe2.default[moduleName] === undefined) {
40
- throw new Error('Module "' + moduleName + '" is not defined');
41
- }
42
-
43
- var module = require('./modules/' + moduleName);
44
- promise = promise.then(function (tree) {
45
- return module.default(tree, options, options[moduleName]);
46
- });
47
- };
18
+ function htmlnano(options = {}, preset = _safe.default) {
19
+ return function minifier(tree) {
20
+ options = { ...preset,
21
+ ...options
22
+ };
23
+ let promise = Promise.resolve(tree);
48
24
 
49
- var _iteratorNormalCompletion = true;
50
- var _didIteratorError = false;
51
- var _iteratorError = undefined;
25
+ for (const [moduleName, moduleOptions] of Object.entries(options)) {
26
+ if (!moduleOptions) {
27
+ // The module is disabled
28
+ continue;
29
+ }
52
30
 
53
- try {
54
- for (var _iterator = Object.keys(options)[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
55
- var moduleName = _step.value;
31
+ if (_safe.default[moduleName] === undefined) {
32
+ throw new Error('Module "' + moduleName + '" is not defined');
33
+ }
56
34
 
57
- var _ret = _loop(moduleName);
35
+ let module = require('./modules/' + moduleName);
58
36
 
59
- if (_ret === 'continue') continue;
60
- }
61
- } catch (err) {
62
- _didIteratorError = true;
63
- _iteratorError = err;
64
- } finally {
65
- try {
66
- if (!_iteratorNormalCompletion && _iterator.return) {
67
- _iterator.return();
68
- }
69
- } finally {
70
- if (_didIteratorError) {
71
- throw _iteratorError;
72
- }
73
- }
74
- }
37
+ promise = promise.then(tree => module.default(tree, options, moduleOptions));
38
+ }
75
39
 
76
- return promise;
77
- };
40
+ return promise;
41
+ };
78
42
  }
79
43
 
80
- htmlnano.process = function (html, options, preset) {
81
- return (0, _posthtml2.default)([htmlnano(options, preset)]).process(html);
44
+ htmlnano.process = function (html, options, preset, postHtmlOptions) {
45
+ return (0, _posthtml.default)([htmlnano(options, preset)]).process(html, postHtmlOptions);
82
46
  };
83
47
 
84
48
  htmlnano.presets = {
85
- safe: _safe2.default,
86
- ampSafe: _ampSafe2.default,
87
- max: _max2.default
49
+ safe: _safe.default,
50
+ ampSafe: _ampSafe.default,
51
+ max: _max.default
88
52
  };
89
-
90
- exports.default = htmlnano;
53
+ var _default = htmlnano;
54
+ exports.default = _default;