html-minifier-next 1.4.0 → 1.4.2

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.
@@ -26520,6 +26520,8 @@ var RE_BIN_NUMBER = /^0b[01]+$/i;
26520
26520
  var RE_DEC_NUMBER = /^\d*\.?\d*(?:e[+-]?\d*(?:\d\.?|\.?\d)\d*)?$/i;
26521
26521
  var RE_BIG_INT = /^(0[xob])?[0-9a-f]+n$/i;
26522
26522
 
26523
+ var RE_KEYWORD_RELATIONAL_OPERATORS = /in(?:stanceof)?/y;
26524
+
26523
26525
  var OPERATORS = makePredicate([
26524
26526
  "in",
26525
26527
  "instanceof",
@@ -26844,6 +26846,56 @@ function tokenizer($TEXT, filename, html5_comments, shebang) {
26844
26846
  next();
26845
26847
  }
26846
26848
 
26849
+ function peek_next_token_start_or_newline() {
26850
+ var pos = S.pos;
26851
+ for (var in_multiline_comment = false; pos < S.text.length; ) {
26852
+ var ch = get_full_char(S.text, pos);
26853
+ if (NEWLINE_CHARS.has(ch)) {
26854
+ return { char: ch, pos: pos };
26855
+ } else if (in_multiline_comment) {
26856
+ if (ch == "*" && get_full_char(S.text, pos + 1) == "/") {
26857
+ pos += 2;
26858
+ in_multiline_comment = false;
26859
+ } else {
26860
+ pos++;
26861
+ }
26862
+ } else if (!WHITESPACE_CHARS.has(ch)) {
26863
+ if (ch == "/") {
26864
+ var next_ch = get_full_char(S.text, pos + 1);
26865
+ if (next_ch == "/") {
26866
+ pos = find_eol();
26867
+ return { char: get_full_char(S.text, pos), pos: pos };
26868
+ } else if (next_ch == "*") {
26869
+ in_multiline_comment = true;
26870
+ pos += 2;
26871
+ continue;
26872
+ }
26873
+ }
26874
+ return { char: ch, pos: pos };
26875
+ } else {
26876
+ pos++;
26877
+ }
26878
+ }
26879
+ return { char: null, pos: pos };
26880
+ }
26881
+
26882
+ function ch_starts_binding_identifier(ch, pos) {
26883
+ if (ch == "\\") {
26884
+ return true;
26885
+ } else if (is_identifier_start(ch)) {
26886
+ RE_KEYWORD_RELATIONAL_OPERATORS.lastIndex = pos;
26887
+ if (RE_KEYWORD_RELATIONAL_OPERATORS.test(S.text)) {
26888
+ var after = get_full_char(S.text, RE_KEYWORD_RELATIONAL_OPERATORS.lastIndex);
26889
+ if (!is_identifier_char(after) && after != "\\") {
26890
+ // "in" or "instanceof" are keywords, not binding identifiers
26891
+ return false;
26892
+ }
26893
+ }
26894
+ return true;
26895
+ }
26896
+ return false;
26897
+ }
26898
+
26847
26899
  function read_while(pred) {
26848
26900
  var ret = "", ch, i = 0;
26849
26901
  while ((ch = peek()) && pred(ch, i++))
@@ -27086,7 +27138,8 @@ function tokenizer($TEXT, filename, html5_comments, shebang) {
27086
27138
  && (ch >= "a" && ch <= "z" || ch >= "A" && ch <= "Z")
27087
27139
  );
27088
27140
 
27089
- if (end > start + 1 && ch && ch !== "\\" && !is_identifier_char(ch)) {
27141
+ // 0x7F is very rare in actual code, so we compare it to "~" (0x7E)
27142
+ if (end > start + 1 && ch && ch !== "\\" && !is_identifier_char(ch) && ch <= "~") {
27090
27143
  S.pos += end - start;
27091
27144
  S.col += end - start;
27092
27145
  return S.text.slice(start, S.pos);
@@ -27347,6 +27400,9 @@ function tokenizer($TEXT, filename, html5_comments, shebang) {
27347
27400
  return S.directives[directive] > 0;
27348
27401
  };
27349
27402
 
27403
+ next_token.peek_next_token_start_or_newline = peek_next_token_start_or_newline;
27404
+ next_token.ch_starts_binding_identifier = ch_starts_binding_identifier;
27405
+
27350
27406
  return next_token;
27351
27407
 
27352
27408
  }
@@ -27568,10 +27624,6 @@ function parse($TEXT, options) {
27568
27624
  return simple_statement();
27569
27625
 
27570
27626
  case "name":
27571
- case "privatename":
27572
- if(is("privatename") && !S.in_class)
27573
- croak("Private field must be used in an enclosing class");
27574
-
27575
27627
  if (S.token.value == "async" && is_token(peek(), "keyword", "function")) {
27576
27628
  next();
27577
27629
  next();
@@ -27586,10 +27638,31 @@ function parse($TEXT, options) {
27586
27638
  semicolon();
27587
27639
  return node;
27588
27640
  }
27641
+ if (S.token.value == "using" && is_token(peek(), "name") && !has_newline_before(peek())) {
27642
+ next();
27643
+ var node = using_();
27644
+ semicolon();
27645
+ return node;
27646
+ }
27647
+ if (S.token.value == "await" && can_await() && is_token(peek(), "name", "using") && !has_newline_before(peek())) {
27648
+ var next_next = S.input.peek_next_token_start_or_newline();
27649
+ if (S.input.ch_starts_binding_identifier(next_next.char, next_next.pos)) {
27650
+ next();
27651
+ // The "using" token will be consumed by the await_using_ function.
27652
+ var node = await_using_();
27653
+ semicolon();
27654
+ return node;
27655
+ }
27656
+ }
27589
27657
  return is_token(peek(), "punc", ":")
27590
27658
  ? labeled_statement()
27591
27659
  : simple_statement();
27592
27660
 
27661
+ case "privatename":
27662
+ if(!S.in_class)
27663
+ croak("Private field must be used in an enclosing class");
27664
+ return simple_statement();
27665
+
27593
27666
  case "punc":
27594
27667
  switch (S.token.value) {
27595
27668
  case "{":
@@ -27814,6 +27887,8 @@ function parse($TEXT, options) {
27814
27887
  is("keyword", "var") ? (next(), var_(true)) :
27815
27888
  is("keyword", "let") ? (next(), let_(true)) :
27816
27889
  is("keyword", "const") ? (next(), const_(true)) :
27890
+ is("name", "using") && is_token(peek(), "name") && (peek().value != "of" || S.input.peek_next_token_start_or_newline().char == "=") ? (next(), using_(true)) :
27891
+ is("name", "await") && can_await() && is_token(peek(), "name", "using") ? (next(), await_using_(true)) :
27817
27892
  expression(true, true);
27818
27893
  var is_in = is("operator", "in");
27819
27894
  var is_of = is("name", "of");
@@ -27821,9 +27896,12 @@ function parse($TEXT, options) {
27821
27896
  token_error(await_tok, for_await_error);
27822
27897
  }
27823
27898
  if (is_in || is_of) {
27824
- if (init instanceof AST_Definitions) {
27899
+ if (init instanceof AST_DefinitionsLike) {
27825
27900
  if (init.definitions.length > 1)
27826
27901
  token_error(init.start, "Only one variable declaration allowed in for..in loop");
27902
+ if (is_in && init instanceof AST_Using) {
27903
+ token_error(init.start, "Invalid using declaration in for..in loop");
27904
+ }
27827
27905
  } else if (!(is_assignable(init) || (init = to_destructuring(init)) instanceof AST_Destructuring)) {
27828
27906
  token_error(init.start, "Invalid left-hand side in for..in loop");
27829
27907
  }
@@ -27855,7 +27933,7 @@ function parse($TEXT, options) {
27855
27933
  }
27856
27934
 
27857
27935
  function for_of(init, is_await) {
27858
- var lhs = init instanceof AST_Definitions ? init.definitions[0].name : null;
27936
+ var lhs = init instanceof AST_DefinitionsLike ? init.definitions[0].name : null;
27859
27937
  var obj = expression(true);
27860
27938
  expect(")");
27861
27939
  return new AST_ForOf({
@@ -28451,23 +28529,26 @@ function parse($TEXT, options) {
28451
28529
  var sym_type =
28452
28530
  kind === "var" ? AST_SymbolVar :
28453
28531
  kind === "const" ? AST_SymbolConst :
28454
- kind === "let" ? AST_SymbolLet : null;
28532
+ kind === "let" ? AST_SymbolLet :
28533
+ kind === "using" ? AST_SymbolUsing :
28534
+ kind === "await using" ? AST_SymbolUsing : null;
28535
+ var def_type = kind === "using" || kind === "await using" ? AST_UsingDef : AST_VarDef;
28455
28536
  // var { a } = b
28456
28537
  if (is("punc", "{") || is("punc", "[")) {
28457
- def = new AST_VarDef({
28538
+ def = new def_type({
28458
28539
  start: S.token,
28459
28540
  name: binding_element(undefined, sym_type),
28460
28541
  value: is("operator", "=") ? (expect_token("operator", "="), expression(false, no_in)) : null,
28461
28542
  end: prev()
28462
28543
  });
28463
28544
  } else {
28464
- def = new AST_VarDef({
28545
+ def = new def_type({
28465
28546
  start : S.token,
28466
28547
  name : as_symbol(sym_type),
28467
28548
  value : is("operator", "=")
28468
28549
  ? (next(), expression(false, no_in))
28469
- : !no_in && kind === "const"
28470
- ? croak("Missing initializer in const declaration") : null,
28550
+ : !no_in && (kind === "const" || kind === "using" || kind === "await using")
28551
+ ? croak("Missing initializer in " + kind + " declaration") : null,
28471
28552
  end : prev()
28472
28553
  });
28473
28554
  if (def.name.name == "import") croak("Unexpected token: import");
@@ -28504,6 +28585,25 @@ function parse($TEXT, options) {
28504
28585
  });
28505
28586
  };
28506
28587
 
28588
+ var using_ = function(no_in) {
28589
+ return new AST_Using({
28590
+ start : prev(),
28591
+ await : false,
28592
+ definitions : vardefs(no_in, "using"),
28593
+ end : prev()
28594
+ });
28595
+ };
28596
+
28597
+ var await_using_ = function(no_in) {
28598
+ // Assumption: When await_using_ is called, only the `await` token has been consumed.
28599
+ return new AST_Using({
28600
+ start : prev(),
28601
+ await : true,
28602
+ definitions : (next(), vardefs(no_in, "await using")),
28603
+ end : prev()
28604
+ });
28605
+ };
28606
+
28507
28607
  var new_ = function(allow_calls) {
28508
28608
  var start = S.token;
28509
28609
  expect_token("operator", "new");
@@ -28922,13 +29022,13 @@ function parse($TEXT, options) {
28922
29022
  return name;
28923
29023
  };
28924
29024
 
29025
+ var is_private = prev().type === "privatename";
28925
29026
  const is_not_method_start = () =>
28926
- !is("punc", "(") && !is("punc", ",") && !is("punc", "}") && !is("punc", ";") && !is("operator", "=");
29027
+ !is("punc", "(") && !is("punc", ",") && !is("punc", "}") && !is("punc", ";") && !is("operator", "=") && !is_private;
28927
29028
 
28928
29029
  var is_async = false;
28929
29030
  var is_static = false;
28930
29031
  var is_generator = false;
28931
- var is_private = false;
28932
29032
  var accessor_type = null;
28933
29033
 
28934
29034
  if (is_class && name === "static" && is_not_method_start()) {
@@ -28951,7 +29051,7 @@ function parse($TEXT, options) {
28951
29051
  accessor_type = name;
28952
29052
  name = as_property_name();
28953
29053
  }
28954
- if (prev().type === "privatename") {
29054
+ if (!is_private && prev().type === "privatename") {
28955
29055
  is_private = true;
28956
29056
  }
28957
29057
 
@@ -31180,7 +31280,7 @@ var AST_Finally = DEFNODE("Finally", null, function AST_Finally(props) {
31180
31280
 
31181
31281
  /* -----[ VAR/CONST ]----- */
31182
31282
 
31183
- var AST_Definitions = DEFNODE("Definitions", "definitions", function AST_Definitions(props) {
31283
+ var AST_DefinitionsLike = DEFNODE("DefinitionsLike", "definitions", function AST_DefinitionsLike(props) {
31184
31284
  if (props) {
31185
31285
  this.definitions = props.definitions;
31186
31286
  this.start = props.start;
@@ -31189,9 +31289,9 @@ var AST_Definitions = DEFNODE("Definitions", "definitions", function AST_Definit
31189
31289
 
31190
31290
  this.flags = 0;
31191
31291
  }, {
31192
- $documentation: "Base class for `var` or `const` nodes (variable declarations/initializations)",
31292
+ $documentation: "Base class for variable definitions and `using`",
31193
31293
  $propdoc: {
31194
- definitions: "[AST_VarDef*] array of variable definitions"
31294
+ definitions: "[AST_VarDef*|AST_UsingDef*] array of variable definitions"
31195
31295
  },
31196
31296
  _walk: function(visitor) {
31197
31297
  return visitor._visit(this, function() {
@@ -31207,6 +31307,18 @@ var AST_Definitions = DEFNODE("Definitions", "definitions", function AST_Definit
31207
31307
  },
31208
31308
  }, AST_Statement);
31209
31309
 
31310
+ var AST_Definitions = DEFNODE("Definitions", null, function AST_Definitions(props) {
31311
+ if (props) {
31312
+ this.definitions = props.definitions;
31313
+ this.start = props.start;
31314
+ this.end = props.end;
31315
+ }
31316
+
31317
+ this.flags = 0;
31318
+ }, {
31319
+ $documentation: "Base class for `var` or `const` nodes (variable declarations/initializations)",
31320
+ }, AST_DefinitionsLike);
31321
+
31210
31322
  var AST_Var = DEFNODE("Var", null, function AST_Var(props) {
31211
31323
  if (props) {
31212
31324
  this.definitions = props.definitions;
@@ -31243,7 +31355,23 @@ var AST_Const = DEFNODE("Const", null, function AST_Const(props) {
31243
31355
  $documentation: "A `const` statement"
31244
31356
  }, AST_Definitions);
31245
31357
 
31246
- var AST_VarDef = DEFNODE("VarDef", "name value", function AST_VarDef(props) {
31358
+ var AST_Using = DEFNODE("Using", "await", function AST_Using(props) {
31359
+ if (props) {
31360
+ this.await = props.await;
31361
+ this.definitions = props.definitions;
31362
+ this.start = props.start;
31363
+ this.end = props.end;
31364
+ }
31365
+
31366
+ this.flags = 0;
31367
+ }, {
31368
+ $documentation: "A `using` statement",
31369
+ $propdoc: {
31370
+ await: "[boolean] Whether it's `await using`"
31371
+ },
31372
+ }, AST_DefinitionsLike);
31373
+
31374
+ var AST_VarDefLike = DEFNODE("VarDefLike", "name value", function AST_VarDefLike(props) {
31247
31375
  if (props) {
31248
31376
  this.name = props.name;
31249
31377
  this.value = props.value;
@@ -31253,9 +31381,9 @@ var AST_VarDef = DEFNODE("VarDef", "name value", function AST_VarDef(props) {
31253
31381
 
31254
31382
  this.flags = 0;
31255
31383
  }, {
31256
- $documentation: "A variable declaration; only appears in a AST_Definitions node",
31384
+ $documentation: "A name=value pair in a variable definition statement or `using`",
31257
31385
  $propdoc: {
31258
- name: "[AST_Destructuring|AST_SymbolConst|AST_SymbolLet|AST_SymbolVar] name of the variable",
31386
+ name: "[AST_Destructuring|AST_SymbolDeclaration] name of the variable",
31259
31387
  value: "[AST_Node?] initializer, or null of there's no initializer"
31260
31388
  },
31261
31389
  _walk: function(visitor) {
@@ -31270,13 +31398,39 @@ var AST_VarDef = DEFNODE("VarDef", "name value", function AST_VarDef(props) {
31270
31398
  },
31271
31399
  declarations_as_names() {
31272
31400
  if (this.name instanceof AST_SymbolDeclaration) {
31273
- return [this];
31401
+ return [this.name];
31274
31402
  } else {
31275
31403
  return this.name.all_symbols();
31276
31404
  }
31277
31405
  }
31278
31406
  });
31279
31407
 
31408
+ var AST_VarDef = DEFNODE("VarDef", null, function AST_VarDef(props) {
31409
+ if (props) {
31410
+ this.name = props.name;
31411
+ this.value = props.value;
31412
+ this.start = props.start;
31413
+ this.end = props.end;
31414
+ }
31415
+
31416
+ this.flags = 0;
31417
+ }, {
31418
+ $documentation: "A variable declaration; only appears in a AST_Definitions node",
31419
+ }, AST_VarDefLike);
31420
+
31421
+ var AST_UsingDef = DEFNODE("UsingDef", null, function AST_UsingDef(props) {
31422
+ if (props) {
31423
+ this.name = props.name;
31424
+ this.value = props.value;
31425
+ this.start = props.start;
31426
+ this.end = props.end;
31427
+ }
31428
+
31429
+ this.flags = 0;
31430
+ }, {
31431
+ $documentation: "Like VarDef but specific to AST_Using",
31432
+ }, AST_VarDefLike);
31433
+
31280
31434
  var AST_NameMapping = DEFNODE("NameMapping", "foreign_name name", function AST_NameMapping(props) {
31281
31435
  if (props) {
31282
31436
  this.foreign_name = props.foreign_name;
@@ -32372,6 +32526,21 @@ var AST_SymbolConst = DEFNODE("SymbolConst", null, function AST_SymbolConst(prop
32372
32526
  $documentation: "A constant declaration"
32373
32527
  }, AST_SymbolBlockDeclaration);
32374
32528
 
32529
+ var AST_SymbolUsing = DEFNODE("SymbolUsing", null, function AST_SymbolUsing(props) {
32530
+ if (props) {
32531
+ this.init = props.init;
32532
+ this.scope = props.scope;
32533
+ this.name = props.name;
32534
+ this.thedef = props.thedef;
32535
+ this.start = props.start;
32536
+ this.end = props.end;
32537
+ }
32538
+
32539
+ this.flags = 0;
32540
+ }, {
32541
+ $documentation: "A `using` declaration"
32542
+ }, AST_SymbolBlockDeclaration);
32543
+
32375
32544
  var AST_SymbolLet = DEFNODE("SymbolLet", null, function AST_SymbolLet(props) {
32376
32545
  if (props) {
32377
32546
  this.init = props.init;
@@ -33218,11 +33387,11 @@ def_transform(AST_Catch, function(self, tw) {
33218
33387
  self.body = MAP(self.body, tw);
33219
33388
  });
33220
33389
 
33221
- def_transform(AST_Definitions, function(self, tw) {
33390
+ def_transform(AST_DefinitionsLike, function(self, tw) {
33222
33391
  self.definitions = MAP(self.definitions, tw);
33223
33392
  });
33224
33393
 
33225
- def_transform(AST_VarDef, function(self, tw) {
33394
+ def_transform(AST_VarDefLike, function(self, tw) {
33226
33395
  self.name = self.name.transform(tw);
33227
33396
  if (self.value) self.value = self.value.transform(tw);
33228
33397
  });
@@ -33757,19 +33926,30 @@ def_transform(AST_PrefixedTemplateString, function(self, tw) {
33757
33926
 
33758
33927
  VariableDeclaration: function(M) {
33759
33928
  let decl_type;
33929
+ let defs_type = AST_VarDef;
33760
33930
  let sym_type;
33931
+ let await_using = false;
33761
33932
  if (M.kind === "const") {
33762
33933
  decl_type = AST_Const;
33763
33934
  sym_type = AST_SymbolConst;
33764
33935
  } else if (M.kind === "let") {
33765
33936
  decl_type = AST_Let;
33766
33937
  sym_type = AST_SymbolLet;
33938
+ } else if (M.kind === "using") {
33939
+ decl_type = AST_Using;
33940
+ defs_type = AST_UsingDef;
33941
+ sym_type = AST_SymbolUsing;
33942
+ } else if (M.kind === "await using") {
33943
+ decl_type = AST_Using;
33944
+ defs_type = AST_UsingDef;
33945
+ sym_type = AST_SymbolUsing;
33946
+ await_using = true;
33767
33947
  } else {
33768
33948
  decl_type = AST_Var;
33769
33949
  sym_type = AST_SymbolVar;
33770
33950
  }
33771
33951
  const definitions = M.declarations.map(M => {
33772
- return new AST_VarDef({
33952
+ return new defs_type({
33773
33953
  start: my_start_token(M),
33774
33954
  end: my_end_token(M),
33775
33955
  name: from_moz_pattern(M.id, sym_type),
@@ -33780,6 +33960,7 @@ def_transform(AST_PrefixedTemplateString, function(self, tw) {
33780
33960
  start : my_start_token(M),
33781
33961
  end : my_end_token(M),
33782
33962
  definitions : definitions,
33963
+ await : await_using,
33783
33964
  });
33784
33965
  },
33785
33966
 
@@ -34379,7 +34560,7 @@ def_transform(AST_PrefixedTemplateString, function(self, tw) {
34379
34560
  type: "DebuggerStatement"
34380
34561
  };
34381
34562
  });
34382
- def_to_moz(AST_VarDef, function To_Moz_VariableDeclarator(M) {
34563
+ def_to_moz(AST_VarDefLike, function To_Moz_VariableDeclarator(M) {
34383
34564
  return {
34384
34565
  type: "VariableDeclarator",
34385
34566
  id: to_moz(M.name),
@@ -34595,12 +34776,14 @@ def_transform(AST_PrefixedTemplateString, function(self, tw) {
34595
34776
  };
34596
34777
  });
34597
34778
 
34598
- def_to_moz(AST_Definitions, function To_Moz_VariableDeclaration(M) {
34779
+ def_to_moz(AST_DefinitionsLike, function To_Moz_VariableDeclaration(M) {
34599
34780
  return {
34600
34781
  type: "VariableDeclaration",
34601
34782
  kind:
34602
34783
  M instanceof AST_Const ? "const" :
34603
- M instanceof AST_Let ? "let" : "var",
34784
+ M instanceof AST_Let ? "let" :
34785
+ M instanceof AST_Using ? (M.await ? "await using" : "using") :
34786
+ "var",
34604
34787
  declarations: M.definitions.map(to_moz)
34605
34788
  };
34606
34789
  });
@@ -36271,7 +36454,7 @@ function OutputStream(options) {
36271
36454
  return p instanceof AST_Call // (foo, bar)() or foo(1, (2, 3), 4)
36272
36455
  || p instanceof AST_Unary // !(foo, bar, baz)
36273
36456
  || p instanceof AST_Binary // 1 + (2, 3) + 4 ==> 8
36274
- || p instanceof AST_VarDef // var a = (1, 2), b = a + a; ==> b == 4
36457
+ || p instanceof AST_VarDefLike // var a = (1, 2), b = a + a; ==> b == 4
36275
36458
  || p instanceof AST_PropAccess // (1, {foo:2}).foo or (1, {foo:2})["foo"] ==> 2
36276
36459
  || p instanceof AST_Array // [ 1, (2, 3), 4 ] ==> [ 1, 3, 4 ]
36277
36460
  || p instanceof AST_ObjectProperty // { foo: (1, 2) }.foo ==> 2
@@ -36603,7 +36786,7 @@ function OutputStream(options) {
36603
36786
  output.space();
36604
36787
  output.with_parens(function() {
36605
36788
  if (self.init) {
36606
- if (self.init instanceof AST_Definitions) {
36789
+ if (self.init instanceof AST_DefinitionsLike) {
36607
36790
  self.init.print(output);
36608
36791
  } else {
36609
36792
  parenthesize_for_noin(self.init, output, true);
@@ -36963,7 +37146,7 @@ function OutputStream(options) {
36963
37146
  });
36964
37147
 
36965
37148
  /* -----[ var/const ]----- */
36966
- AST_Definitions.DEFMETHOD("_do_print", function(output, kind) {
37149
+ AST_DefinitionsLike.DEFMETHOD("_do_print", function(output, kind) {
36967
37150
  output.print(kind);
36968
37151
  output.space();
36969
37152
  this.definitions.forEach(function(def, i) {
@@ -36985,6 +37168,9 @@ function OutputStream(options) {
36985
37168
  DEFPRINT(AST_Const, function(self, output) {
36986
37169
  self._do_print(output, "const");
36987
37170
  });
37171
+ DEFPRINT(AST_Using, function(self, output) {
37172
+ self._do_print(output, self.await ? "await using" : "using");
37173
+ });
36988
37174
  DEFPRINT(AST_Import, function(self, output) {
36989
37175
  output.print("import");
36990
37176
  output.space();
@@ -37152,7 +37338,7 @@ function OutputStream(options) {
37152
37338
  node.print(output, parens);
37153
37339
  }
37154
37340
 
37155
- DEFPRINT(AST_VarDef, function(self, output) {
37341
+ DEFPRINT(AST_VarDefLike, function(self, output) {
37156
37342
  self.name.print(output);
37157
37343
  if (self.value) {
37158
37344
  output.space();
@@ -37628,7 +37814,7 @@ function OutputStream(options) {
37628
37814
  } else {
37629
37815
  if (!stat || stat instanceof AST_EmptyStatement)
37630
37816
  output.force_semicolon();
37631
- else if (stat instanceof AST_Let || stat instanceof AST_Const || stat instanceof AST_Class)
37817
+ else if ((stat instanceof AST_DefinitionsLike && !(stat instanceof AST_Var)) || stat instanceof AST_Class)
37632
37818
  make_block(stat, output);
37633
37819
  else
37634
37820
  stat.print(output);
@@ -37708,7 +37894,7 @@ function OutputStream(options) {
37708
37894
  AST_Class,
37709
37895
  AST_Constant,
37710
37896
  AST_Debugger,
37711
- AST_Definitions,
37897
+ AST_DefinitionsLike,
37712
37898
  AST_Directive,
37713
37899
  AST_Finally,
37714
37900
  AST_Jump,
@@ -37871,9 +38057,9 @@ AST_Catch.prototype.shallow_cmp = function(other) {
37871
38057
 
37872
38058
  AST_Finally.prototype.shallow_cmp = pass_through;
37873
38059
 
37874
- AST_Definitions.prototype.shallow_cmp = pass_through;
38060
+ AST_DefinitionsLike.prototype.shallow_cmp = pass_through;
37875
38061
 
37876
- AST_VarDef.prototype.shallow_cmp = function(other) {
38062
+ AST_VarDefLike.prototype.shallow_cmp = function(other) {
37877
38063
  return this.value == null ? other.value == null : this.value === other.value;
37878
38064
  };
37879
38065
 
@@ -38243,6 +38429,7 @@ AST_Scope.DEFMETHOD("figure_out_scope", function(options, { parent_scope = undef
38243
38429
  node instanceof AST_SymbolVar
38244
38430
  || node instanceof AST_SymbolLet
38245
38431
  || node instanceof AST_SymbolConst
38432
+ || node instanceof AST_SymbolUsing
38246
38433
  || node instanceof AST_SymbolCatch
38247
38434
  ) {
38248
38435
  var def;
@@ -38256,7 +38443,7 @@ AST_Scope.DEFMETHOD("figure_out_scope", function(options, { parent_scope = undef
38256
38443
  if (node instanceof AST_SymbolBlockDeclaration) {
38257
38444
  return sym instanceof AST_SymbolLambda;
38258
38445
  }
38259
- return !(sym instanceof AST_SymbolLet || sym instanceof AST_SymbolConst);
38446
+ return !(sym instanceof AST_SymbolLet || sym instanceof AST_SymbolConst || sym instanceof AST_SymbolUsing);
38260
38447
  })) {
38261
38448
  js_error(
38262
38449
  `"${node.name}" is redeclared`,
@@ -39136,7 +39323,12 @@ AST_Const.prototype._size = function () {
39136
39323
  return 6 + list_overhead(this.definitions);
39137
39324
  };
39138
39325
 
39139
- AST_VarDef.prototype._size = function () {
39326
+ AST_Using.prototype._size = function () {
39327
+ const await_size = this.await ? 6 : 0;
39328
+ return await_size + 6 + list_overhead(this.definitions);
39329
+ };
39330
+
39331
+ AST_VarDefLike.prototype._size = function () {
39140
39332
  return this.value ? 1 : 0;
39141
39333
  };
39142
39334
 
@@ -39607,7 +39799,7 @@ function get_simple_key(key) {
39607
39799
  if (key instanceof AST_UnaryPrefix
39608
39800
  && key.operator == "void"
39609
39801
  && key.expression instanceof AST_Constant) {
39610
- return;
39802
+ return undefined;
39611
39803
  }
39612
39804
  return key;
39613
39805
  }
@@ -39717,6 +39909,7 @@ function can_be_evicted_from_block(node) {
39717
39909
  node instanceof AST_Defun ||
39718
39910
  node instanceof AST_Let ||
39719
39911
  node instanceof AST_Const ||
39912
+ node instanceof AST_Using ||
39720
39913
  node instanceof AST_Export ||
39721
39914
  node instanceof AST_Import
39722
39915
  );
@@ -42476,7 +42669,7 @@ function mark_escaped(tw, d, scope, node, value, level = 0, depth = 1) {
42476
42669
  parent instanceof AST_Assign && (parent.operator === "=" || parent.logical) && node === parent.right
42477
42670
  || parent instanceof AST_Call && (node !== parent.expression || parent instanceof AST_New)
42478
42671
  || parent instanceof AST_Exit && node === parent.value && node.scope !== d.scope
42479
- || parent instanceof AST_VarDef && node === parent.value
42672
+ || parent instanceof AST_VarDefLike && node === parent.value
42480
42673
  || parent instanceof AST_Yield && node === parent.value && node.scope !== d.scope
42481
42674
  ) {
42482
42675
  if (depth > 1 && !(value && value.is_constant_expression(scope))) depth = 1;
@@ -42859,7 +43052,7 @@ function handle_defined_after_hoist(parent) {
42859
43052
 
42860
43053
  // Refine `defun_first_read_map` to be as high as possible
42861
43054
  for (const [defun, defun_first_read] of defun_first_read_map) {
42862
- // Update all depdencies of `defun`
43055
+ // Update all dependencies of `defun`
42863
43056
  const queue = new Set(defun_dependencies_map.get(defun));
42864
43057
  for (const enclosed_defun of queue) {
42865
43058
  let enclosed_defun_first_read = defun_first_read_map.get(enclosed_defun);
@@ -43088,6 +43281,10 @@ def_reduce_vars(AST_VarDef, function(tw, descend) {
43088
43281
  }
43089
43282
  });
43090
43283
 
43284
+ def_reduce_vars(AST_UsingDef, function() {
43285
+ suppress(this.name);
43286
+ });
43287
+
43091
43288
  def_reduce_vars(AST_While, function(tw, descend, compressor) {
43092
43289
  reset_block_variables(compressor, this);
43093
43290
  const saved_loop = tw.in_loop;
@@ -43296,6 +43493,7 @@ function tighten_body(statements, compressor) {
43296
43493
  if (node instanceof AST_Assign
43297
43494
  && (node.logical || node.operator != "=" && lhs.equivalent_to(node.left))
43298
43495
  || node instanceof AST_Await
43496
+ || node instanceof AST_Using
43299
43497
  || node instanceof AST_Call && lhs instanceof AST_PropAccess && lhs.equivalent_to(node.expression)
43300
43498
  ||
43301
43499
  (node instanceof AST_Call || node instanceof AST_PropAccess)
@@ -43394,6 +43592,7 @@ function tighten_body(statements, compressor) {
43394
43592
  && ((lvalues.has(node.name) && lvalues.get(node.name).modified) || side_effects && may_modify(node))
43395
43593
  || node instanceof AST_VarDef && node.value
43396
43594
  && (lvalues.has(node.name.name) || side_effects && may_modify(node.name))
43595
+ || node instanceof AST_Using
43397
43596
  || (sym = is_lhs(node.left, node))
43398
43597
  && (sym instanceof AST_PropAccess || lvalues.has(sym.name))
43399
43598
  || may_throw
@@ -43808,7 +44007,9 @@ function tighten_body(statements, compressor) {
43808
44007
  ? expr.left
43809
44008
  : expr.expression;
43810
44009
  return !is_ref_of(lhs, AST_SymbolConst)
43811
- && !is_ref_of(lhs, AST_SymbolLet) && lhs;
44010
+ && !is_ref_of(lhs, AST_SymbolLet)
44011
+ && !is_ref_of(lhs, AST_SymbolUsing)
44012
+ && lhs;
43812
44013
  }
43813
44014
  }
43814
44015
 
@@ -44143,7 +44344,7 @@ function tighten_body(statements, compressor) {
44143
44344
  return false;
44144
44345
  for (var j = i + 1, len = statements.length; j < len; j++) {
44145
44346
  var stat = statements[j];
44146
- if (stat instanceof AST_Const || stat instanceof AST_Let)
44347
+ if (stat instanceof AST_DefinitionsLike && !(stat instanceof AST_Var))
44147
44348
  return false;
44148
44349
  }
44149
44350
  var lct = ab instanceof AST_LoopControl ? compressor.loopcontrol_target(ab) : null;
@@ -44283,7 +44484,7 @@ function tighten_body(statements, compressor) {
44283
44484
  var line = block.body[i];
44284
44485
  if (line instanceof AST_Var && declarations_only(line)) {
44285
44486
  decls.push(line);
44286
- } else if (stat || line instanceof AST_Const || line instanceof AST_Let) {
44487
+ } else if (stat || line instanceof AST_DefinitionsLike && !(line instanceof AST_Var)) {
44287
44488
  return false;
44288
44489
  } else {
44289
44490
  stat = line;
@@ -44306,7 +44507,7 @@ function tighten_body(statements, compressor) {
44306
44507
  if (stat instanceof AST_Exit) {
44307
44508
  stat.value = cons_seq(stat.value || make_node(AST_Undefined, stat).transform(compressor));
44308
44509
  } else if (stat instanceof AST_For) {
44309
- if (!(stat.init instanceof AST_Definitions)) {
44510
+ if (!(stat.init instanceof AST_DefinitionsLike)) {
44310
44511
  const abort = walk(prev.body, node => {
44311
44512
  if (node instanceof AST_Scope)
44312
44513
  return true;
@@ -44326,7 +44527,7 @@ function tighten_body(statements, compressor) {
44326
44527
  }
44327
44528
  }
44328
44529
  } else if (stat instanceof AST_ForIn) {
44329
- if (!(stat.init instanceof AST_Const) && !(stat.init instanceof AST_Let)) {
44530
+ if (!(stat.init instanceof AST_DefinitionsLike) || stat.init instanceof AST_Var) {
44330
44531
  stat.object = cons_seq(stat.object);
44331
44532
  }
44332
44533
  } else if (stat instanceof AST_If) {
@@ -44443,6 +44644,12 @@ function tighten_body(statements, compressor) {
44443
44644
  statements[++j] = stat;
44444
44645
  defs = stat;
44445
44646
  }
44647
+ } else if (
44648
+ stat instanceof AST_Using
44649
+ && prev instanceof AST_Using
44650
+ && prev.await === stat.await
44651
+ ) {
44652
+ prev.definitions = prev.definitions.concat(stat.definitions);
44446
44653
  } else if (stat instanceof AST_Exit) {
44447
44654
  stat.value = extract_object_assignments(stat.value);
44448
44655
  } else if (stat instanceof AST_For) {
@@ -45733,6 +45940,7 @@ function can_be_extracted_from_if_block(node) {
45733
45940
  return !(
45734
45941
  node instanceof AST_Const
45735
45942
  || node instanceof AST_Let
45943
+ || node instanceof AST_Using
45736
45944
  || node instanceof AST_Class
45737
45945
  );
45738
45946
  }
@@ -45911,6 +46119,7 @@ AST_Scope.DEFMETHOD("hoist_properties", function(compressor) {
45911
46119
  let def;
45912
46120
  let value;
45913
46121
  if (sym.scope === self
46122
+ && !(sym instanceof AST_SymbolUsing)
45914
46123
  && (def = sym.definition()).escaped != 1
45915
46124
  && !def.assignments
45916
46125
  && !def.direct_access
@@ -59916,7 +60125,7 @@ class CaseInsensitiveSet extends Set {
59916
60125
  }
59917
60126
  }
59918
60127
 
59919
- // Regular Expressions for parsing tags and attributes
60128
+ // Regular expressions for parsing tags and attributes
59920
60129
  const singleAttrIdentifier = /([^\s"'<>/=]+)/;
59921
60130
  const singleAttrAssigns = [/=/];
59922
60131
  const singleAttrValues = [
@@ -59947,10 +60156,10 @@ let IS_REGEX_CAPTURING_BROKEN = false;
59947
60156
  IS_REGEX_CAPTURING_BROKEN = g === '';
59948
60157
  });
59949
60158
 
59950
- // Empty Elements
60159
+ // Empty elements
59951
60160
  const empty = new CaseInsensitiveSet(['area', 'base', 'basefont', 'br', 'col', 'embed', 'frame', 'hr', 'img', 'input', 'isindex', 'keygen', 'link', 'meta', 'param', 'source', 'track', 'wbr']);
59952
60161
 
59953
- // Inline Elements
60162
+ // Inline elements
59954
60163
  const inline = new CaseInsensitiveSet(['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']);
59955
60164
 
59956
60165
  // Elements that you can, intentionally, leave open
@@ -59960,10 +60169,10 @@ const closeSelf = new CaseInsensitiveSet(['colgroup', 'dd', 'dt', 'li', 'option'
59960
60169
  // Attributes that have their values filled in disabled='disabled'
59961
60170
  const fillAttrs = new CaseInsensitiveSet(['checked', 'compact', 'declare', 'defer', 'disabled', 'ismap', 'multiple', 'nohref', 'noresize', 'noshade', 'nowrap', 'readonly', 'selected']);
59962
60171
 
59963
- // Special Elements (can contain anything)
60172
+ // Special elements (can contain anything)
59964
60173
  const special = new CaseInsensitiveSet(['script', 'style']);
59965
60174
 
59966
- // HTML5 tags https://html.spec.whatwg.org/multipage/indices.html#elements-3
60175
+ // HTML5 elements https://html.spec.whatwg.org/multipage/indices.html#elements-3
59967
60176
  // Phrasing Content https://html.spec.whatwg.org/multipage/dom.html#phrasing-content
59968
60177
  const nonPhrasing = new CaseInsensitiveSet(['address', 'article', 'aside', 'base', 'blockquote', 'body', 'caption', 'col', 'colgroup', 'dd', 'details', 'dialog', 'div', 'dl', 'dt', 'fieldset', 'figcaption', 'figure', 'footer', 'form', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'head', 'header', 'hgroup', 'hr', 'html', 'legend', 'li', 'menuitem', 'meta', 'ol', 'optgroup', 'option', 'param', 'rp', 'rt', 'source', 'style', 'summary', 'tbody', 'td', 'tfoot', 'th', 'thead', 'title', 'tr', 'track', 'ul']);
59969
60178
 
@@ -60011,7 +60220,7 @@ class HTMLParser {
60011
60220
  let last, prevTag, nextTag;
60012
60221
  while (html) {
60013
60222
  last = html;
60014
- // Make sure we're not in a script or style element
60223
+ // Make sure were not in a `script` or `style` element
60015
60224
  if (!lastTag || !special.has(lastTag)) {
60016
60225
  let textEnd = html.indexOf('<');
60017
60226
  if (textEnd === 0) {
@@ -60087,7 +60296,7 @@ class HTMLParser {
60087
60296
  html = '';
60088
60297
  }
60089
60298
 
60090
- // next tag
60299
+ // Next tag
60091
60300
  let nextTagMatch = parseStartTag(html);
60092
60301
  if (nextTagMatch) {
60093
60302
  nextTag = nextTagMatch.tagName;
@@ -60200,9 +60409,9 @@ class HTMLParser {
60200
60409
 
60201
60410
  const attrs = match.attrs.map(function (args) {
60202
60411
  let name, value, customOpen, customClose, customAssign, quote;
60203
- const ncp = 7; // number of captured parts, scalar
60412
+ const ncp = 7; // Number of captured parts, scalar
60204
60413
 
60205
- // hackish work around FF bug https://bugzilla.mozilla.org/show_bug.cgi?id=369778
60414
+ // Hackish workaround for FF bug https://bugzilla.mozilla.org/show_bug.cgi?id=369778
60206
60415
  if (IS_REGEX_CAPTURING_BROKEN && args[0].indexOf('""') === -1) {
60207
60416
  if (args[3] === '') { delete args[3]; }
60208
60417
  if (args[4] === '') { delete args[4]; }
@@ -60424,28 +60633,28 @@ function collapseWhitespace(str, options, trimLeft, trimRight, collapseAll) {
60424
60633
  }
60425
60634
 
60426
60635
  if (collapseAll) {
60427
- // strip non space whitespace then compress spaces to one
60636
+ // Strip non-space whitespace then compress spaces to one
60428
60637
  str = collapseWhitespaceAll(str);
60429
60638
  }
60430
60639
 
60431
60640
  return lineBreakBefore + str + lineBreakAfter;
60432
60641
  }
60433
60642
 
60434
- // non-empty elements that will maintain whitespace around them
60435
- const inlineHtmlElements = ['a', 'abbr', 'acronym', 'b', 'bdi', 'bdo', 'big', 'button', 'cite', 'code', 'del', 'dfn', 'em', 'font', 'i', 'img', 'input', 'ins', 'kbd', 'label', 'mark', 'math', 'meter', 'nobr', 'object', 'output', 'progress', 'q', 'rp', 'rt', 'rtc', 'ruby', 's', 'samp', 'select', 'small', 'span', 'strike', 'strong', 'sub', 'sup', 'svg', 'textarea', 'time', 'tt', 'u', 'var', 'wbr'];
60436
- // non-empty elements that will maintain whitespace within them
60437
- const inlineTextTags = new Set(['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']);
60438
- // self-closing elements that will maintain whitespace around them
60439
- const selfClosingInlineTags = new Set(['comment', 'img', 'input', 'wbr']);
60643
+ // Non-empty elements that will maintain whitespace around them
60644
+ const inlineElementsToKeepWhitespaceAround = ['a', 'abbr', 'acronym', 'b', 'bdi', 'bdo', 'big', 'button', 'cite', 'code', 'del', 'dfn', 'em', 'font', 'i', 'img', 'input', 'ins', 'kbd', 'label', 'mark', 'math', 'meter', 'nobr', 'object', 'output', 'progress', 'q', 'rp', 'rt', 'rtc', 'ruby', 's', 'samp', 'select', 'small', 'span', 'strike', 'strong', 'sub', 'sup', 'svg', 'textarea', 'time', 'tt', 'u', 'var', 'wbr'];
60645
+ // Non-empty elements that will maintain whitespace within them
60646
+ const inlineElementsToKeepWhitespaceWithin = new Set(['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']);
60647
+ // Elements that will always maintain whitespace around them
60648
+ const inlineElementsToKeepWhitespace = new Set(['comment', 'img', 'input', 'wbr']);
60440
60649
 
60441
- function collapseWhitespaceSmart(str, prevTag, nextTag, options, inlineTags) {
60442
- let trimLeft = prevTag && !selfClosingInlineTags.has(prevTag);
60650
+ function collapseWhitespaceSmart(str, prevTag, nextTag, options, inlineElements, inlineTextSet) {
60651
+ let trimLeft = prevTag && !inlineElementsToKeepWhitespace.has(prevTag);
60443
60652
  if (trimLeft && !options.collapseInlineTagWhitespace) {
60444
- trimLeft = prevTag.charAt(0) === '/' ? !inlineTags.has(prevTag.slice(1)) : !inlineTextTags.has(prevTag);
60653
+ trimLeft = prevTag.charAt(0) === '/' ? !inlineElements.has(prevTag.slice(1)) : !inlineTextSet.has(prevTag);
60445
60654
  }
60446
- let trimRight = nextTag && !selfClosingInlineTags.has(nextTag);
60655
+ let trimRight = nextTag && !inlineElementsToKeepWhitespace.has(nextTag);
60447
60656
  if (trimRight && !options.collapseInlineTagWhitespace) {
60448
- trimRight = nextTag.charAt(0) === '/' ? !inlineTextTags.has(nextTag.slice(1)) : !inlineTags.has(nextTag);
60657
+ trimRight = nextTag.charAt(0) === '/' ? !inlineTextSet.has(nextTag.slice(1)) : !inlineElements.has(nextTag);
60449
60658
  }
60450
60659
  return collapseWhitespace(str, options, trimLeft, trimRight, prevTag && nextTag);
60451
60660
  }
@@ -60632,7 +60841,7 @@ function isSrcset(attrName, tag) {
60632
60841
  return attrName === 'srcset' && srcsetTags.has(tag);
60633
60842
  }
60634
60843
 
60635
- async function cleanAttributeValue(tag, attrName, attrValue, options, attrs) {
60844
+ async function cleanAttributeValue(tag, attrName, attrValue, options, attrs, minifyHTMLSelf) {
60636
60845
  if (isEventAttribute(attrName, options)) {
60637
60846
  attrValue = trimWhitespace(attrValue).replace(/^javascript:\s*/i, '');
60638
60847
  return options.minifyJS(attrValue, true);
@@ -60690,6 +60899,13 @@ async function cleanAttributeValue(tag, attrName, attrValue, options, attrs) {
60690
60899
  } else if (isMediaQuery(tag, attrs, attrName)) {
60691
60900
  attrValue = trimWhitespace(attrValue);
60692
60901
  return options.minifyCSS(attrValue, 'media');
60902
+ } else if (tag === 'iframe' && attrName === 'srcdoc') {
60903
+ // Recursively minify HTML content within srcdoc attribute
60904
+ // Fast-path: skip if nothing would change
60905
+ if (!shouldMinifyInnerHTML(options)) {
60906
+ return attrValue;
60907
+ }
60908
+ return minifyHTMLSelf(attrValue, options, true);
60693
60909
  }
60694
60910
  return attrValue;
60695
60911
  }
@@ -60767,7 +60983,7 @@ async function processScript(text, options, currentAttrs) {
60767
60983
  // Tag omission rules from https://html.spec.whatwg.org/multipage/syntax.html#optional-tags
60768
60984
  // with the following deviations:
60769
60985
  // - retain <body> if followed by <noscript>
60770
- // - </rb>, </rt>, </rtc>, </rp> & </tfoot> follow https://www.w3.org/TR/html5/syntax.html#optional-tags
60986
+ // - </rb>, </rt>, </rtc>, </rp>, and </tfoot> follow https://www.w3.org/TR/html5/syntax.html#optional-tags
60771
60987
  // - retain all tags which are adjacent to non-standard HTML tags
60772
60988
  const optionalStartTags = new Set(['html', 'head', 'body', 'colgroup', 'tbody']);
60773
60989
  const optionalEndTags = new Set(['html', 'head', 'body', 'li', 'dt', 'dd', 'p', 'rb', 'rt', 'rtc', 'rp', 'optgroup', 'option', 'colgroup', 'caption', 'thead', 'tbody', 'tfoot', 'tr', 'td', 'th']);
@@ -60929,7 +61145,7 @@ async function normalizeAttr(attr, attrs, tag, options) {
60929
61145
  }
60930
61146
 
60931
61147
  if (attrValue) {
60932
- attrValue = await cleanAttributeValue(tag, attrName, attrValue, options, attrs);
61148
+ attrValue = await cleanAttributeValue(tag, attrName, attrValue, options, attrs, minifyHTML);
60933
61149
  }
60934
61150
 
60935
61151
  if (options.removeEmptyAttributes &&
@@ -60977,7 +61193,7 @@ function buildAttr(normalized, hasUnarySlash, options, isLast, uidAttr) {
60977
61193
  emittedAttrValue += ' ';
60978
61194
  }
60979
61195
  } else if (isLast && !hasUnarySlash && !/\/$/.test(attrValue)) {
60980
- // make sure trailing slash is not interpreted as HTML self-closing tag
61196
+ // Make sure trailing slash is not interpreted as HTML self-closing tag
60981
61197
  emittedAttrValue = attrValue;
60982
61198
  } else {
60983
61199
  emittedAttrValue = attrValue + ' ';
@@ -61004,6 +61220,17 @@ function identityAsync(value) {
61004
61220
  return Promise.resolve(value);
61005
61221
  }
61006
61222
 
61223
+ function shouldMinifyInnerHTML(options) {
61224
+ return Boolean(
61225
+ options.collapseWhitespace ||
61226
+ options.removeComments ||
61227
+ options.removeOptionalTags ||
61228
+ options.minifyJS !== identity ||
61229
+ options.minifyCSS !== identityAsync ||
61230
+ options.minifyURLs !== identity
61231
+ );
61232
+ }
61233
+
61007
61234
  const processOptions = (inputOptions) => {
61008
61235
  const options = {
61009
61236
  name: function (name) {
@@ -61238,11 +61465,16 @@ async function minifyHTML(value, options, partialMarkup) {
61238
61465
  let uidIgnore;
61239
61466
  let uidAttr;
61240
61467
  let uidPattern;
61241
- let inlineTags = new Set([...inlineHtmlElements, ...(options.inlineCustomElements ?? [])]);
61242
-
61243
- // temporarily replace ignored chunks with comments,
61244
- // so that we don't have to worry what's there.
61245
- // for all we care there might be
61468
+ // Create inline tags/text sets with custom elements
61469
+ const customElementsInput = options.inlineCustomElements ?? [];
61470
+ const customElementsArr = Array.isArray(customElementsInput) ? customElementsInput : Array.from(customElementsInput);
61471
+ const normalizedCustomElements = customElementsArr.map(name => options.name(name));
61472
+ const inlineTextSet = new Set([...inlineElementsToKeepWhitespaceWithin, ...normalizedCustomElements]);
61473
+ const inlineElements = new Set([...inlineElementsToKeepWhitespaceAround, ...normalizedCustomElements]);
61474
+
61475
+ // Temporarily replace ignored chunks with comments,
61476
+ // so that we don’t have to worry what’s there.
61477
+ // For all we care there might be
61246
61478
  // completely-horribly-broken-alien-non-html-emoj-cthulhu-filled content
61247
61479
  value = value.replace(/<!-- htmlmin:ignore -->([\s\S]*?)<!-- htmlmin:ignore -->/g, function (match, group1) {
61248
61480
  if (!uidIgnore) {
@@ -61363,20 +61595,20 @@ async function minifyHTML(value, options, partialMarkup) {
61363
61595
  buffer.length = Math.max(0, index);
61364
61596
  }
61365
61597
 
61366
- // look for trailing whitespaces, bypass any inline tags
61598
+ // Look for trailing whitespaces, bypass any inline tags
61367
61599
  function trimTrailingWhitespace(index, nextTag) {
61368
61600
  for (let endTag = null; index >= 0 && _canTrimWhitespace(endTag); index--) {
61369
61601
  const str = buffer[index];
61370
61602
  const match = str.match(/^<\/([\w:-]+)>$/);
61371
61603
  if (match) {
61372
61604
  endTag = match[1];
61373
- } else if (/>$/.test(str) || (buffer[index] = collapseWhitespaceSmart(str, null, nextTag, options, inlineTags))) {
61605
+ } else if (/>$/.test(str) || (buffer[index] = collapseWhitespaceSmart(str, null, nextTag, options, inlineElements, inlineTextSet))) {
61374
61606
  break;
61375
61607
  }
61376
61608
  }
61377
61609
  }
61378
61610
 
61379
- // look for trailing whitespaces from previously processed text
61611
+ // Look for trailing whitespaces from previously processed text
61380
61612
  // which may not be trimmed due to a following comment or an empty
61381
61613
  // element which has now been removed
61382
61614
  function squashTrailingWhitespace(nextTag) {
@@ -61407,7 +61639,7 @@ async function minifyHTML(value, options, partialMarkup) {
61407
61639
  tag = options.name(tag);
61408
61640
  currentTag = tag;
61409
61641
  charsPrevTag = tag;
61410
- if (!inlineTextTags.has(tag)) {
61642
+ if (!inlineTextSet.has(tag)) {
61411
61643
  currentChars = '';
61412
61644
  }
61413
61645
  hasChars = false;
@@ -61425,7 +61657,7 @@ async function minifyHTML(value, options, partialMarkup) {
61425
61657
  removeStartTag();
61426
61658
  }
61427
61659
  optionalStartTag = '';
61428
- // end-tag-followed-by-start-tag omission rules
61660
+ // End-tag-followed-by-start-tag omission rules
61429
61661
  if (htmlTag && canRemovePrecedingTag(optionalEndTag, tag)) {
61430
61662
  removeEndTag();
61431
61663
  // <colgroup> cannot be omitted if preceding </colgroup> is omitted
@@ -61435,7 +61667,7 @@ async function minifyHTML(value, options, partialMarkup) {
61435
61667
  optionalEndTag = '';
61436
61668
  }
61437
61669
 
61438
- // set whitespace flags for nested tags (eg. <code> within a <pre>)
61670
+ // Set whitespace flags for nested tags (eg. <code> within a <pre>)
61439
61671
  if (options.collapseWhitespace) {
61440
61672
  if (!stackNoTrimWhitespace.length) {
61441
61673
  squashTrailingWhitespace(tag);
@@ -61471,7 +61703,7 @@ async function minifyHTML(value, options, partialMarkup) {
61471
61703
  buffer.push(' ');
61472
61704
  buffer.push.apply(buffer, parts);
61473
61705
  } else if (optional && optionalStartTags.has(tag)) {
61474
- // start tag must never be omitted if it has any attributes
61706
+ // Start tag must never be omitted if it has any attributes
61475
61707
  optionalStartTag = tag;
61476
61708
  }
61477
61709
 
@@ -61488,7 +61720,7 @@ async function minifyHTML(value, options, partialMarkup) {
61488
61720
  }
61489
61721
  tag = options.name(tag);
61490
61722
 
61491
- // check if current tag is in a whitespace stack
61723
+ // Check if current tag is in a whitespace stack
61492
61724
  if (options.collapseWhitespace) {
61493
61725
  if (stackNoTrimWhitespace.length) {
61494
61726
  if (tag === stackNoTrimWhitespace[stackNoTrimWhitespace.length - 1]) {
@@ -61526,7 +61758,7 @@ async function minifyHTML(value, options, partialMarkup) {
61526
61758
  }
61527
61759
 
61528
61760
  if (options.removeEmptyElements && isElementEmpty && canRemoveElement(tag, attrs)) {
61529
- // remove last "element" from buffer
61761
+ // Remove last element from buffer
61530
61762
  removeStartTag();
61531
61763
  optionalStartTag = '';
61532
61764
  optionalEndTag = '';
@@ -61537,7 +61769,7 @@ async function minifyHTML(value, options, partialMarkup) {
61537
61769
  buffer.push('</' + tag + '>');
61538
61770
  }
61539
61771
  charsPrevTag = '/' + tag;
61540
- if (!inlineTags.has(tag)) {
61772
+ if (!inlineElements.has(tag)) {
61541
61773
  currentChars = '';
61542
61774
  } else if (isElementEmpty) {
61543
61775
  currentChars += '|';
@@ -61576,12 +61808,12 @@ async function minifyHTML(value, options, partialMarkup) {
61576
61808
  }
61577
61809
  trimTrailingWhitespace(tagIndex - 1, 'br');
61578
61810
  }
61579
- } else if (inlineTextTags.has(prevTag.charAt(0) === '/' ? prevTag.slice(1) : prevTag)) {
61811
+ } else if (inlineTextSet.has(prevTag.charAt(0) === '/' ? prevTag.slice(1) : prevTag)) {
61580
61812
  text = collapseWhitespace(text, options, /(?:^|\s)$/.test(currentChars));
61581
61813
  }
61582
61814
  }
61583
61815
  if (prevTag || nextTag) {
61584
- text = collapseWhitespaceSmart(text, prevTag, nextTag, options, inlineTags);
61816
+ text = collapseWhitespaceSmart(text, prevTag, nextTag, options, inlineElements, inlineTextSet);
61585
61817
  } else {
61586
61818
  text = collapseWhitespace(text, options, true, true);
61587
61819
  }
@@ -61651,7 +61883,7 @@ async function minifyHTML(value, options, partialMarkup) {
61651
61883
  text = prefix + text + suffix;
61652
61884
  }
61653
61885
  if (options.removeOptionalTags && text) {
61654
- // preceding comments suppress tag omissions
61886
+ // Preceding comments suppress tag omissions
61655
61887
  optionalStartTag = '';
61656
61888
  optionalEndTag = '';
61657
61889
  }