htmlnano 0.2.4 → 0.2.8

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/lib/htmlnano.js CHANGED
@@ -1,94 +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 _objectAssign = require('object-assign');
8
+ var _posthtml = _interopRequireDefault(require("posthtml"));
8
9
 
9
- var _objectAssign2 = _interopRequireDefault(_objectAssign);
10
+ var _safe = _interopRequireDefault(require("./presets/safe"));
10
11
 
11
- var _posthtml = require('posthtml');
12
+ var _ampSafe = _interopRequireDefault(require("./presets/ampSafe"));
12
13
 
13
- var _posthtml2 = _interopRequireDefault(_posthtml);
14
-
15
- var _safe = require('./presets/safe');
16
-
17
- var _safe2 = _interopRequireDefault(_safe);
18
-
19
- var _ampSafe = require('./presets/ampSafe');
20
-
21
- var _ampSafe2 = _interopRequireDefault(_ampSafe);
22
-
23
- var _max = require('./presets/max');
24
-
25
- var _max2 = _interopRequireDefault(_max);
14
+ var _max = _interopRequireDefault(require("./presets/max"));
26
15
 
27
16
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
28
17
 
29
- function htmlnano() {
30
- var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
31
- var preset = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : _safe2.default;
32
-
33
- return function minifier(tree) {
34
- options = (0, _objectAssign2.default)({}, preset, options);
35
- var promise = Promise.resolve(tree);
36
-
37
- var _loop = function _loop(moduleName) {
38
- if (!options[moduleName]) {
39
- // The module is disabled
40
- return 'continue';
41
- }
42
-
43
- if (_safe2.default[moduleName] === undefined) {
44
- throw new Error('Module "' + moduleName + '" is not defined');
45
- }
46
-
47
- var module = require('./modules/' + moduleName);
48
- promise = promise.then(function (tree) {
49
- return module.default(tree, options, options[moduleName]);
50
- });
51
- };
18
+ function htmlnano(options = {}, preset = _safe.default) {
19
+ return function minifier(tree) {
20
+ options = { ...preset,
21
+ ...options
22
+ };
23
+ let promise = Promise.resolve(tree);
52
24
 
53
- var _iteratorNormalCompletion = true;
54
- var _didIteratorError = false;
55
- var _iteratorError = undefined;
25
+ for (const [moduleName, moduleOptions] of Object.entries(options)) {
26
+ if (!moduleOptions) {
27
+ // The module is disabled
28
+ continue;
29
+ }
56
30
 
57
- try {
58
- for (var _iterator = Object.keys(options)[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
59
- var moduleName = _step.value;
31
+ if (_safe.default[moduleName] === undefined) {
32
+ throw new Error('Module "' + moduleName + '" is not defined');
33
+ }
60
34
 
61
- var _ret = _loop(moduleName);
35
+ let module = require('./modules/' + moduleName);
62
36
 
63
- if (_ret === 'continue') continue;
64
- }
65
- } catch (err) {
66
- _didIteratorError = true;
67
- _iteratorError = err;
68
- } finally {
69
- try {
70
- if (!_iteratorNormalCompletion && _iterator.return) {
71
- _iterator.return();
72
- }
73
- } finally {
74
- if (_didIteratorError) {
75
- throw _iteratorError;
76
- }
77
- }
78
- }
37
+ promise = promise.then(tree => module.default(tree, options, moduleOptions));
38
+ }
79
39
 
80
- return promise;
81
- };
40
+ return promise;
41
+ };
82
42
  }
83
43
 
84
- htmlnano.process = function (html, options, preset) {
85
- 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);
86
46
  };
87
47
 
88
48
  htmlnano.presets = {
89
- safe: _safe2.default,
90
- ampSafe: _ampSafe2.default,
91
- max: _max2.default
49
+ safe: _safe.default,
50
+ ampSafe: _ampSafe.default,
51
+ max: _max.default
92
52
  };
93
-
94
- exports.default = htmlnano;
53
+ var _default = htmlnano;
54
+ exports.default = _default;
@@ -1,30 +1,32 @@
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.default = collapseAttributeWhitespace;
7
- var attributesWithLists = exports.attributesWithLists = new Set(['class', 'rel', 'ping']);
8
-
7
+ exports.attributesWithLists = void 0;
8
+ const attributesWithLists = new Set(['class', 'rel', 'ping']);
9
9
  /** Collapse whitespaces inside list-like attributes (e.g. class, rel) */
10
+
11
+ exports.attributesWithLists = attributesWithLists;
12
+
10
13
  function collapseAttributeWhitespace(tree) {
11
- tree.walk(function (node) {
12
- if (!node.attrs) {
13
- return node;
14
- }
14
+ tree.walk(node => {
15
+ if (!node.attrs) {
16
+ return node;
17
+ }
15
18
 
16
- Object.keys(node.attrs).forEach(function (attrName) {
17
- var attrNameLower = attrName.toLowerCase();
18
- if (!attributesWithLists.has(attrNameLower)) {
19
- return;
20
- }
19
+ Object.entries(node.attrs).forEach(([attrName, attrValue]) => {
20
+ const attrNameLower = attrName.toLowerCase();
21
21
 
22
- var attrValue = node.attrs[attrName].replace(/\s+/g, ' ').trim();
23
- node.attrs[attrName] = attrValue;
24
- });
22
+ if (!attributesWithLists.has(attrNameLower)) {
23
+ return;
24
+ }
25
25
 
26
- return node;
26
+ const newAttrValue = attrValue.replace(/\s+/g, ' ').trim();
27
+ node.attrs[attrName] = newAttrValue;
27
28
  });
28
-
29
- return tree;
29
+ return node;
30
+ });
31
+ return tree;
30
32
  }
@@ -1,56 +1,42 @@
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.default = collapseBooleanAttributes;
7
7
  // Source: https://github.com/kangax/html-minifier/issues/63
8
- var htmlBooleanAttributes = new Set(['allowfullscreen', 'allowpaymentrequest', 'allowtransparency', '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', 'truespeed', 'typemustmatch', 'visible']);
9
-
10
- var amphtmlBooleanAttributes = new Set(['⚡', 'amp', '⚡4ads', 'amp4ads', '⚡4email', 'amp4email', 'amp-custom', 'amp-boilerplate', 'amp4ads-boilerplate', 'amp4email-boilerplate', 'allow-blocked-ranges', 'amp-access-hide', 'amp-access-template', 'amp-keyframes', 'animate', 'arrows', 'data-block-on-consent', 'data-enable-refresh', 'data-multi-size', 'date-template', 'disable-double-tap', 'disable-session-states', 'disableremoteplayback', 'dots', 'expand-single-section', 'expanded', 'fallback', 'first', 'fullscreen', 'inline', 'lightbox', 'noaudio', 'noautoplay', 'noloading', 'once', 'open-after-clear', 'open-after-select', 'open-button', 'placeholder', 'preload', 'reset-on-refresh', 'reset-on-resize', 'resizable', 'rotate-to-fullscreen', 'second', 'standalone', 'stereo', 'submit-error', 'submit-success', 'submitting', 'subscriptions-actions', 'subscriptions-dialog']);
8
+ const htmlBooleanAttributes = new Set(['allowfullscreen', 'allowpaymentrequest', 'allowtransparency', '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', 'truespeed', 'typemustmatch', 'visible']);
9
+ const amphtmlBooleanAttributes = new Set(['⚡', 'amp', '⚡4ads', 'amp4ads', '⚡4email', 'amp4email', 'amp-custom', 'amp-boilerplate', 'amp4ads-boilerplate', 'amp4email-boilerplate', 'allow-blocked-ranges', 'amp-access-hide', 'amp-access-template', 'amp-keyframes', 'animate', 'arrows', 'data-block-on-consent', 'data-enable-refresh', 'data-multi-size', 'date-template', 'disable-double-tap', 'disable-session-states', 'disableremoteplayback', 'dots', 'expand-single-section', 'expanded', 'fallback', 'first', 'fullscreen', 'inline', 'lightbox', 'noaudio', 'noautoplay', 'noloading', 'once', 'open-after-clear', 'open-after-select', 'open-button', 'placeholder', 'preload', 'reset-on-refresh', 'reset-on-resize', 'resizable', 'rotate-to-fullscreen', 'second', 'standalone', 'stereo', 'submit-error', 'submit-success', 'submitting', 'subscriptions-actions', 'subscriptions-dialog']);
11
10
 
12
11
  function collapseBooleanAttributes(tree, options, moduleOptions) {
13
- tree.match({ attrs: true }, function (node) {
14
- var _iteratorNormalCompletion = true;
15
- var _didIteratorError = false;
16
- var _iteratorError = undefined;
17
-
18
- try {
19
- for (var _iterator = Object.keys(node.attrs)[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
20
- var attrName = _step.value;
21
-
22
- if (!node.tag) {
23
- continue;
24
- }
25
-
26
- if (node.tag.search('a-') === 0 && attrName === 'visible') {
27
- continue;
28
- }
29
-
30
- if (htmlBooleanAttributes.has(attrName)) {
31
- node.attrs[attrName] = true;
32
- }
33
- if (moduleOptions.amphtml && node.attrs[attrName] === '' && amphtmlBooleanAttributes.has(attrName)) {
34
- node.attrs[attrName] = true;
35
- }
36
- }
37
- } catch (err) {
38
- _didIteratorError = true;
39
- _iteratorError = err;
40
- } finally {
41
- try {
42
- if (!_iteratorNormalCompletion && _iterator.return) {
43
- _iterator.return();
44
- }
45
- } finally {
46
- if (_didIteratorError) {
47
- throw _iteratorError;
48
- }
49
- }
50
- }
51
-
52
- return node;
53
- });
54
-
55
- return tree;
12
+ tree.match({
13
+ attrs: true
14
+ }, node => {
15
+ for (const attrName of Object.keys(node.attrs)) {
16
+ if (!node.tag) {
17
+ continue;
18
+ }
19
+
20
+ if (node.tag.search('a-') === 0 && attrName === 'visible') {
21
+ continue;
22
+ }
23
+
24
+ if (htmlBooleanAttributes.has(attrName)) {
25
+ node.attrs[attrName] = true;
26
+ }
27
+
28
+ if (moduleOptions.amphtml && node.attrs[attrName] === '' && amphtmlBooleanAttributes.has(attrName)) {
29
+ node.attrs[attrName] = true;
30
+ } // collapse crossorigin attributes
31
+ // Specification: https://html.spec.whatwg.org/multipage/urls-and-fetching.html#cors-settings-attributes
32
+
33
+
34
+ if (attrName.toLowerCase() === 'crossorigin' && (node.attrs[attrName] === 'anonymous' || node.attrs[attrName] === '')) {
35
+ node.attrs[attrName] = true;
36
+ }
37
+ }
38
+
39
+ return node;
40
+ });
41
+ return tree;
56
42
  }
@@ -1,50 +1,84 @@
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.default = collapseWhitespace;
7
7
 
8
- var _normalizeHtmlWhitespace = require('normalize-html-whitespace');
9
-
10
- var _normalizeHtmlWhitespace2 = _interopRequireDefault(_normalizeHtmlWhitespace);
11
-
12
- var _helpers = require('../helpers');
13
-
14
- function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
15
-
16
- var noWhitespaceCollapseElements = new Set(['script', 'style', 'pre', 'textarea']);
8
+ var _helpers = require("../helpers");
17
9
 
10
+ const noWhitespaceCollapseElements = new Set(['script', 'style', 'pre', 'textarea']);
11
+ const noTrimWhitespacesArroundElements = new Set([// non-empty tags that will maintain whitespace around them
12
+ 'a', 'abbr', 'acronym', 'b', 'bdi', 'bdo', 'big', 'button', 'cite', 'code', 'del', 'dfn', 'em', 'font', 'i', 'ins', 'kbd', 'label', 'mark', 'math', 'nobr', 'object', 'q', 'rp', 'rt', 'rtc', 'ruby', 's', 'samp', 'select', 'small', 'span', 'strike', 'strong', 'sub', 'sup', 'svg', 'textarea', 'time', 'tt', 'u', 'var', // self-closing tags that will maintain whitespace around them
13
+ 'comment', 'img', 'input', 'wbr']);
14
+ const noTrimWhitespacesInsideElements = new Set([// non-empty tags that will maintain whitespace within them
15
+ 'a', 'abbr', 'acronym', 'b', 'big', 'del', 'em', 'font', 'i', 'ins', 'kbd', 'mark', 'nobr', 'rp', 's', 'samp', 'small', 'span', 'strike', 'strong', 'sub', 'sup', 'time', 'tt', 'u', 'var']);
16
+ const whitespacePattern = /\s{1,}/g;
17
+ const onlyWhitespacePattern = /^\s+$/;
18
+ const NONE = '';
19
+ const SINGLE_SPACE = ' ';
20
+ const validOptions = ['all', 'aggressive', 'conservative'];
18
21
  /** Collapses redundant whitespaces */
22
+
19
23
  function collapseWhitespace(tree, options, collapseType, tag) {
20
- if (collapseType !== 'all') {
21
- collapseType = 'conservative';
24
+ collapseType = validOptions.includes(collapseType) ? collapseType : 'conservative';
25
+ tree.forEach((node, index) => {
26
+ if (typeof node === 'string' && !(0, _helpers.isComment)(node)) {
27
+ const prevNode = tree[index - 1];
28
+ const nextNode = tree[index + 1];
29
+ const prevNodeTag = prevNode && prevNode.tag;
30
+ const nextNodeTag = nextNode && nextNode.tag;
31
+ const isTopLevel = !tag || tag === 'html' || tag === 'head';
32
+ const shouldTrim = collapseType === 'all' || isTopLevel ||
33
+ /*
34
+ * When collapseType is set to 'aggressive', and the tag is not inside 'noTrimWhitespacesInsideElements'.
35
+ * the first & last space inside the tag will be trimmed
36
+ */
37
+ collapseType === 'aggressive' && !noTrimWhitespacesInsideElements.has(tag);
38
+ node = collapseRedundantWhitespaces(node, collapseType, shouldTrim, tag, prevNodeTag, nextNodeTag);
22
39
  }
23
40
 
24
- tree.forEach(function (node, index) {
25
- if (typeof node === 'string' && !(0, _helpers.isComment)(node)) {
26
- var isTopLevel = !tag || tag === 'html' || tag === 'head';
27
- node = collapseRedundantWhitespaces(node, collapseType, isTopLevel);
28
- }
29
-
30
- var isAllowCollapseWhitespace = !noWhitespaceCollapseElements.has(node.tag);
31
- if (node.content && node.content.length && isAllowCollapseWhitespace) {
32
- node.content = collapseWhitespace(node.content, options, collapseType, node.tag);
33
- }
41
+ const isAllowCollapseWhitespace = !noWhitespaceCollapseElements.has(node.tag);
34
42
 
35
- tree[index] = node;
36
- });
43
+ if (node.content && node.content.length && isAllowCollapseWhitespace) {
44
+ node.content = collapseWhitespace(node.content, options, collapseType, node.tag);
45
+ }
37
46
 
38
- return tree;
47
+ tree[index] = node;
48
+ });
49
+ return tree;
39
50
  }
40
51
 
41
- function collapseRedundantWhitespaces(text, collapseType) {
42
- var isTopLevel = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;
52
+ function collapseRedundantWhitespaces(text, collapseType, shouldTrim = false, currentTag, prevNodeTag, nextNodeTag) {
53
+ if (!text || text.length === 0) {
54
+ return NONE;
55
+ }
43
56
 
44
- text = text && text.length > 0 ? (0, _normalizeHtmlWhitespace2.default)(text) : '';
45
- if (collapseType === 'all' || isTopLevel) {
46
- text = text.trim();
57
+ text = text.replace(whitespacePattern, SINGLE_SPACE);
58
+
59
+ if (shouldTrim) {
60
+ if (collapseType === 'aggressive') {
61
+ if (onlyWhitespacePattern.test(text)) {
62
+ // "text" only contains whitespaces. Only trim when both prevNodeTag & nextNodeTag are not "noTrimWhitespacesArroundElement"
63
+ // Otherwise the required ONE whitespace will be trimmed
64
+ if (!noTrimWhitespacesArroundElements.has(prevNodeTag) || !noTrimWhitespacesArroundElements.has(nextNodeTag)) {
65
+ text = text.trim();
66
+ }
67
+ } else {
68
+ // text contains whitespaces & non-whitespaces
69
+ if (!noTrimWhitespacesArroundElements.has(prevNodeTag)) {
70
+ text = text.trimStart();
71
+ }
72
+
73
+ if (!noTrimWhitespacesArroundElements.has(nextNodeTag)) {
74
+ text = text.trimEnd();
75
+ }
76
+ }
77
+ } else {
78
+ // collapseType is 'all', trim spaces
79
+ text = text.trim();
47
80
  }
81
+ }
48
82
 
49
- return text;
83
+ return text;
50
84
  }
@@ -1,22 +1,22 @@
1
1
  "use strict";
2
2
 
3
3
  Object.defineProperty(exports, "__esModule", {
4
- value: true
4
+ value: true
5
5
  });
6
6
  exports.default = custom;
7
+
7
8
  /** Meta-module that runs custom modules */
8
9
  function custom(tree, options, customModules) {
9
- if (!customModules) {
10
- return tree;
11
- }
12
-
13
- if (!Array.isArray(customModules)) {
14
- customModules = [customModules];
15
- }
10
+ if (!customModules) {
11
+ return tree;
12
+ }
16
13
 
17
- customModules.forEach(function (customModule) {
18
- tree = customModule(tree, options);
19
- });
14
+ if (!Array.isArray(customModules)) {
15
+ customModules = [customModules];
16
+ }
20
17
 
21
- return tree;
18
+ customModules.forEach(customModule => {
19
+ tree = customModule(tree, options);
20
+ });
21
+ return tree;
22
22
  }
@@ -1,48 +1,46 @@
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.default = collapseAttributeWhitespace;
7
7
 
8
- var _collapseAttributeWhitespace = require('./collapseAttributeWhitespace');
8
+ var _collapseAttributeWhitespace = require("./collapseAttributeWhitespace");
9
9
 
10
10
  /** Deduplicate values inside list-like attributes (e.g. class, rel) */
11
11
  function collapseAttributeWhitespace(tree) {
12
- tree.walk(function (node) {
13
- if (!node.attrs) {
14
- return node;
12
+ tree.walk(node => {
13
+ if (!node.attrs) {
14
+ return node;
15
+ }
16
+
17
+ Object.keys(node.attrs).forEach(attrName => {
18
+ const attrNameLower = attrName.toLowerCase();
19
+
20
+ if (!_collapseAttributeWhitespace.attributesWithLists.has(attrNameLower)) {
21
+ return;
22
+ }
23
+
24
+ const attrValues = node.attrs[attrName].split(/\s/);
25
+ const uniqeAttrValues = new Set();
26
+ let deduplicatedAttrValues = [];
27
+ attrValues.forEach(attrValue => {
28
+ if (!attrValue) {
29
+ // Keep whitespaces
30
+ deduplicatedAttrValues.push('');
31
+ return;
15
32
  }
16
33
 
17
- Object.keys(node.attrs).forEach(function (attrName) {
18
- var attrNameLower = attrName.toLowerCase();
19
- if (!_collapseAttributeWhitespace.attributesWithLists.has(attrNameLower)) {
20
- return;
21
- }
22
-
23
- var attrValues = node.attrs[attrName].split(/\s/);
24
- var uniqeAttrValues = new Set();
25
- var deduplicatedAttrValues = [];
26
- attrValues.forEach(function (attrValue) {
27
- if (!attrValue) {
28
- // Keep whitespaces
29
- deduplicatedAttrValues.push('');
30
- return;
31
- }
32
-
33
- if (uniqeAttrValues.has(attrValue)) {
34
- return;
35
- }
36
-
37
- deduplicatedAttrValues.push(attrValue);
38
- uniqeAttrValues.add(attrValue);
39
- });
40
-
41
- node.attrs[attrName] = deduplicatedAttrValues.join(' ');
42
- });
43
-
44
- return node;
45
- });
34
+ if (uniqeAttrValues.has(attrValue)) {
35
+ return;
36
+ }
46
37
 
47
- return tree;
38
+ deduplicatedAttrValues.push(attrValue);
39
+ uniqeAttrValues.add(attrValue);
40
+ });
41
+ node.attrs[attrName] = deduplicatedAttrValues.join(' ');
42
+ });
43
+ return node;
44
+ });
45
+ return tree;
48
46
  }
@@ -1,80 +1,63 @@
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.default = mergeScripts;
7
+
7
8
  /* Merge multiple <script> into one */
8
9
  function mergeScripts(tree) {
9
- var scriptNodesIndex = {};
10
-
11
- tree.match({ tag: 'script' }, function (node) {
12
- var nodeAttrs = node.attrs || {};
13
- if (nodeAttrs.src) {
14
- return node;
15
- }
10
+ let scriptNodesIndex = {};
11
+ let scriptSrcIndex = 1;
12
+ tree.match({
13
+ tag: 'script'
14
+ }, node => {
15
+ const nodeAttrs = node.attrs || {};
16
+
17
+ if (nodeAttrs.src) {
18
+ scriptSrcIndex++;
19
+ return node;
20
+ }
16
21
 
17
- var scriptType = nodeAttrs.type || 'text/javascript';
18
- if (scriptType !== 'text/javascript' && scriptType !== 'application/javascript') {
19
- return node;
20
- }
22
+ const scriptType = nodeAttrs.type || 'text/javascript';
21
23
 
22
- var scriptKey = JSON.stringify({
23
- id: nodeAttrs.id,
24
- class: nodeAttrs.class,
25
- type: scriptType,
26
- defer: nodeAttrs.defer !== undefined,
27
- async: nodeAttrs.async !== undefined
28
- });
29
- if (!scriptNodesIndex[scriptKey]) {
30
- scriptNodesIndex[scriptKey] = [];
31
- }
24
+ if (scriptType !== 'text/javascript' && scriptType !== 'application/javascript') {
25
+ return node;
26
+ }
32
27
 
33
- scriptNodesIndex[scriptKey].push(node);
34
- return node;
28
+ const scriptKey = JSON.stringify({
29
+ id: nodeAttrs.id,
30
+ class: nodeAttrs.class,
31
+ type: scriptType,
32
+ defer: nodeAttrs.defer !== undefined,
33
+ async: nodeAttrs.async !== undefined,
34
+ index: scriptSrcIndex
35
35
  });
36
36
 
37
- var _loop = function _loop(scriptKey) {
38
- var scriptNodes = scriptNodesIndex[scriptKey];
39
- var lastScriptNode = scriptNodes.pop();
40
- scriptNodes.reverse().forEach(function (scriptNode) {
41
- var scriptContent = (scriptNode.content || []).join(' ');
42
- scriptContent = scriptContent.trim();
43
- if (scriptContent.slice(-1) !== ';') {
44
- scriptContent += ';';
45
- }
46
-
47
- lastScriptNode.content.unshift(scriptContent);
37
+ if (!scriptNodesIndex[scriptKey]) {
38
+ scriptNodesIndex[scriptKey] = [];
39
+ }
48
40
 
49
- scriptNode.tag = false;
50
- scriptNode.content = [];
51
- });
52
- };
41
+ scriptNodesIndex[scriptKey].push(node);
42
+ return node;
43
+ });
53
44
 
54
- var _iteratorNormalCompletion = true;
55
- var _didIteratorError = false;
56
- var _iteratorError = undefined;
45
+ for (const scriptNodes of Object.values(scriptNodesIndex)) {
46
+ let lastScriptNode = scriptNodes.pop();
47
+ scriptNodes.reverse().forEach(scriptNode => {
48
+ let scriptContent = (scriptNode.content || []).join(' ');
49
+ scriptContent = scriptContent.trim();
57
50
 
58
- try {
59
- for (var _iterator = Object.keys(scriptNodesIndex)[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
60
- var scriptKey = _step.value;
51
+ if (scriptContent.slice(-1) !== ';') {
52
+ scriptContent += ';';
53
+ }
61
54
 
62
- _loop(scriptKey);
63
- }
64
- } catch (err) {
65
- _didIteratorError = true;
66
- _iteratorError = err;
67
- } finally {
68
- try {
69
- if (!_iteratorNormalCompletion && _iterator.return) {
70
- _iterator.return();
71
- }
72
- } finally {
73
- if (_didIteratorError) {
74
- throw _iteratorError;
75
- }
76
- }
77
- }
55
+ lastScriptNode.content = lastScriptNode.content || [];
56
+ lastScriptNode.content.unshift(scriptContent);
57
+ scriptNode.tag = false;
58
+ scriptNode.content = [];
59
+ });
60
+ }
78
61
 
79
- return tree;
62
+ return tree;
80
63
  }