@angular/compiler 20.3.9 → 20.3.11

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,5 +1,4 @@
1
- Angular
2
- =======
1
+ # Angular
3
2
 
4
3
  The sources for this package are in the main [Angular](https://github.com/angular/angular) repo. Please file issues and pull requests against that repo.
5
4
 
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @license Angular v20.3.9
2
+ * @license Angular v20.3.11
3
3
  * (c) 2010-2025 Google LLC. https://angular.dev/
4
4
  * License: MIT
5
5
  */
@@ -7806,11 +7806,13 @@ class ShadowCss {
7806
7806
  return cssText.replace(_cssColonHostRe, (_, hostSelectors, otherSelectors) => {
7807
7807
  if (hostSelectors) {
7808
7808
  const convertedSelectors = [];
7809
- const hostSelectorArray = hostSelectors.split(',').map((p) => p.trim());
7810
- for (const hostSelector of hostSelectorArray) {
7811
- if (!hostSelector)
7809
+ for (const hostSelector of this._splitOnTopLevelCommas(hostSelectors)) {
7810
+ const trimmedHostSelector = hostSelector.trim();
7811
+ if (!trimmedHostSelector)
7812
7812
  break;
7813
- const convertedSelector = _polyfillHostNoCombinator + hostSelector.replace(_polyfillHost, '') + otherSelectors;
7813
+ const convertedSelector = _polyfillHostNoCombinator +
7814
+ trimmedHostSelector.replace(_polyfillHost, '') +
7815
+ otherSelectors;
7814
7816
  convertedSelectors.push(convertedSelector);
7815
7817
  }
7816
7818
  return convertedSelectors.join(',');
@@ -7820,6 +7822,38 @@ class ShadowCss {
7820
7822
  }
7821
7823
  });
7822
7824
  }
7825
+ /**
7826
+ * Generator function that splits a string on top-level commas (commas that are not inside parentheses).
7827
+ * Yields each part of the string between top-level commas. Terminates if an extra closing paren is found.
7828
+ *
7829
+ * @param text The string to split
7830
+ */
7831
+ *_splitOnTopLevelCommas(text) {
7832
+ const length = text.length;
7833
+ let parens = 0;
7834
+ let prev = 0;
7835
+ for (let i = 0; i < length; i++) {
7836
+ const charCode = text.charCodeAt(i);
7837
+ if (charCode === $LPAREN) {
7838
+ parens++;
7839
+ }
7840
+ else if (charCode === $RPAREN) {
7841
+ parens--;
7842
+ if (parens < 0) {
7843
+ // Found an extra closing paren. Assume we want the list terminated here
7844
+ yield text.slice(prev, i);
7845
+ return;
7846
+ }
7847
+ }
7848
+ else if (charCode === $COMMA && parens === 0) {
7849
+ // Found a top-level comma, yield the current chunk
7850
+ yield text.slice(prev, i);
7851
+ prev = i + 1;
7852
+ }
7853
+ }
7854
+ // Yield the final chunk
7855
+ yield text.slice(prev);
7856
+ }
7823
7857
  /*
7824
7858
  * convert a rule like :host-context(.foo) > .bar { }
7825
7859
  *
@@ -7836,34 +7870,14 @@ class ShadowCss {
7836
7870
  * .foo<scopeName> .bar { ... }
7837
7871
  */
7838
7872
  _convertColonHostContext(cssText) {
7839
- const length = cssText.length;
7840
- let parens = 0;
7841
- let prev = 0;
7842
- let result = '';
7843
7873
  // Splits up the selectors on their top-level commas, processes the :host-context in them
7844
7874
  // individually and stitches them back together. This ensures that individual selectors don't
7845
7875
  // affect each other.
7846
- for (let i = 0; i < length; i++) {
7847
- const char = cssText[i];
7848
- // If we hit a comma and there are no open parentheses, take the current chunk and process it.
7849
- if (char === ',' && parens === 0) {
7850
- result += this._convertColonHostContextInSelectorPart(cssText.slice(prev, i)) + ',';
7851
- prev = i + 1;
7852
- continue;
7853
- }
7854
- // We've hit the end. Take everything since the last comma.
7855
- if (i === length - 1) {
7856
- result += this._convertColonHostContextInSelectorPart(cssText.slice(prev));
7857
- break;
7858
- }
7859
- if (char === '(') {
7860
- parens++;
7861
- }
7862
- else if (char === ')') {
7863
- parens--;
7864
- }
7876
+ const results = [];
7877
+ for (const part of this._splitOnTopLevelCommas(cssText)) {
7878
+ results.push(this._convertColonHostContextInSelectorPart(part));
7865
7879
  }
7866
- return result;
7880
+ return results.join(',');
7867
7881
  }
7868
7882
  _convertColonHostContextInSelectorPart(cssText) {
7869
7883
  return cssText.replace(_cssColonHostContextReGlobal, (selectorText, pseudoPrefix) => {
@@ -7875,17 +7889,26 @@ class ShadowCss {
7875
7889
  const contextSelectorGroups = [[]];
7876
7890
  // There may be more than `:host-context` in this selector so `selectorText` could look like:
7877
7891
  // `:host-context(.one):host-context(.two)`.
7878
- // Execute `_cssColonHostContextRe` over and over until we have extracted all the
7879
- // `:host-context` selectors from this selector.
7880
- let match;
7881
- while ((match = _cssColonHostContextRe.exec(selectorText))) {
7882
- // `match` = [':host-context(<selectors>)<rest>', <selectors>, <rest>]
7883
- // The `<selectors>` could actually be a comma separated list: `:host-context(.one, .two)`.
7884
- const newContextSelectors = (match[1] ?? '')
7885
- .trim()
7886
- .split(',')
7887
- .map((m) => m.trim())
7888
- .filter((m) => m !== '');
7892
+ // Loop until every :host-context in the compound selector has been processed.
7893
+ let startIndex = selectorText.indexOf(_polyfillHostContext);
7894
+ while (startIndex !== -1) {
7895
+ const afterPrefix = selectorText.substring(startIndex + _polyfillHostContext.length);
7896
+ if (!afterPrefix || afterPrefix[0] !== '(') {
7897
+ // Edge case of :host-context with no parens (e.g. `:host-context .inner`)
7898
+ selectorText = afterPrefix;
7899
+ startIndex = selectorText.indexOf(_polyfillHostContext);
7900
+ continue;
7901
+ }
7902
+ // Extract comma-separated selectors between the parentheses
7903
+ const newContextSelectors = [];
7904
+ let endIndex = 0; // Index of the closing paren of the :host-context()
7905
+ for (const selector of this._splitOnTopLevelCommas(afterPrefix.substring(1))) {
7906
+ endIndex = endIndex + selector.length + 1;
7907
+ const trimmed = selector.trim();
7908
+ if (trimmed) {
7909
+ newContextSelectors.push(trimmed);
7910
+ }
7911
+ }
7889
7912
  // We must duplicate the current selector group for each of these new selectors.
7890
7913
  // For example if the current groups are:
7891
7914
  // ```
@@ -7912,7 +7935,8 @@ class ShadowCss {
7912
7935
  }
7913
7936
  }
7914
7937
  // Update the `selectorText` and see repeat to see if there are more `:host-context`s.
7915
- selectorText = match[2];
7938
+ selectorText = afterPrefix.substring(endIndex + 1);
7939
+ startIndex = selectorText.indexOf(_polyfillHostContext);
7916
7940
  }
7917
7941
  // The context selectors now must be combined with each other to capture all the possible
7918
7942
  // selectors that `:host-context` can match. See `_combineHostContextSelectors()` for more
@@ -8219,9 +8243,9 @@ class SafeSelector {
8219
8243
  });
8220
8244
  // Replaces the expression in `:nth-child(2n + 1)` with a placeholder.
8221
8245
  // WS and "+" would otherwise be interpreted as selector separators.
8222
- this._content = selector.replace(/(:nth-[-\w]+)(\([^)]+\))/g, (_, pseudo, exp) => {
8246
+ this._content = selector.replace(nthRegex, (_, pseudo, exp) => {
8223
8247
  const replaceBy = `__ph-${this.index}__`;
8224
- this.placeholders.push(exp);
8248
+ this.placeholders.push(`(${exp})`);
8225
8249
  this.index++;
8226
8250
  return pseudo + replaceBy;
8227
8251
  });
@@ -8253,13 +8277,19 @@ const _cssContentUnscopedRuleRe = /(polyfill-unscoped-rule)[^}]*(content:[\s]*([
8253
8277
  const _polyfillHost = '-shadowcsshost';
8254
8278
  // note: :host-context pre-processed to -shadowcsshostcontext.
8255
8279
  const _polyfillHostContext = '-shadowcsscontext';
8256
- const _parenSuffix = '(?:\\((' + '(?:\\([^)(]*\\)|[^)(]*)+?' + ')\\))';
8280
+ // Matches text content with no parentheses, e.g., "foo"
8281
+ const _noParens = '[^)(]*';
8282
+ // Matches content with at most ONE level of nesting, e.g., "a(b)c"
8283
+ const _level1Parens = String.raw `(?:\(${_noParens}\)|${_noParens})+?`;
8284
+ // Matches content with at most TWO levels of nesting, e.g., "a(b(c)d)e"
8285
+ const _level2Parens = String.raw `(?:\(${_level1Parens}\)|${_noParens})+?`;
8286
+ const _parenSuffix = String.raw `(?:\((${_level2Parens})\))`;
8287
+ const nthRegex = new RegExp(String.raw `(:nth-[-\w]+)` + _parenSuffix, 'g');
8257
8288
  const _cssColonHostRe = new RegExp(_polyfillHost + _parenSuffix + '?([^,{]*)', 'gim');
8258
8289
  // note: :host-context patterns are terminated with `{`, as opposed to :host which
8259
8290
  // is both `{` and `,` because :host-context handles top-level commas differently.
8260
8291
  const _hostContextPattern = _polyfillHostContext + _parenSuffix + '?([^{]*)';
8261
8292
  const _cssColonHostContextReGlobal = new RegExp(`${_cssScopedPseudoFunctionPrefix}(${_hostContextPattern})`, 'gim');
8262
- const _cssColonHostContextRe = new RegExp(_hostContextPattern, 'im');
8263
8293
  const _polyfillHostNoCombinator = _polyfillHost + '-no-combinator';
8264
8294
  const _polyfillHostNoCombinatorOutsidePseudoFunction = new RegExp(`${_polyfillHostNoCombinator}(?![^(]*\\))`, 'g');
8265
8295
  const _polyfillHostNoCombinatorRe = /-shadowcsshost-no-combinator([^\s,]*)/;
@@ -34277,7 +34307,7 @@ const MINIMUM_PARTIAL_LINKER_DEFER_SUPPORT_VERSION = '18.0.0';
34277
34307
  function compileDeclareClassMetadata(metadata) {
34278
34308
  const definitionMap = new DefinitionMap();
34279
34309
  definitionMap.set('minVersion', literal(MINIMUM_PARTIAL_LINKER_VERSION$5));
34280
- definitionMap.set('version', literal('20.3.9'));
34310
+ definitionMap.set('version', literal('20.3.11'));
34281
34311
  definitionMap.set('ngImport', importExpr(Identifiers.core));
34282
34312
  definitionMap.set('type', metadata.type);
34283
34313
  definitionMap.set('decorators', metadata.decorators);
@@ -34295,7 +34325,7 @@ function compileComponentDeclareClassMetadata(metadata, dependencies) {
34295
34325
  callbackReturnDefinitionMap.set('ctorParameters', metadata.ctorParameters ?? literal(null));
34296
34326
  callbackReturnDefinitionMap.set('propDecorators', metadata.propDecorators ?? literal(null));
34297
34327
  definitionMap.set('minVersion', literal(MINIMUM_PARTIAL_LINKER_DEFER_SUPPORT_VERSION));
34298
- definitionMap.set('version', literal('20.3.9'));
34328
+ definitionMap.set('version', literal('20.3.11'));
34299
34329
  definitionMap.set('ngImport', importExpr(Identifiers.core));
34300
34330
  definitionMap.set('type', metadata.type);
34301
34331
  definitionMap.set('resolveDeferredDeps', compileComponentMetadataAsyncResolver(dependencies));
@@ -34390,7 +34420,7 @@ function createDirectiveDefinitionMap(meta) {
34390
34420
  const definitionMap = new DefinitionMap();
34391
34421
  const minVersion = getMinimumVersionForPartialOutput(meta);
34392
34422
  definitionMap.set('minVersion', literal(minVersion));
34393
- definitionMap.set('version', literal('20.3.9'));
34423
+ definitionMap.set('version', literal('20.3.11'));
34394
34424
  // e.g. `type: MyDirective`
34395
34425
  definitionMap.set('type', meta.type.value);
34396
34426
  if (meta.isStandalone !== undefined) {
@@ -34806,7 +34836,7 @@ const MINIMUM_PARTIAL_LINKER_VERSION$4 = '12.0.0';
34806
34836
  function compileDeclareFactoryFunction(meta) {
34807
34837
  const definitionMap = new DefinitionMap();
34808
34838
  definitionMap.set('minVersion', literal(MINIMUM_PARTIAL_LINKER_VERSION$4));
34809
- definitionMap.set('version', literal('20.3.9'));
34839
+ definitionMap.set('version', literal('20.3.11'));
34810
34840
  definitionMap.set('ngImport', importExpr(Identifiers.core));
34811
34841
  definitionMap.set('type', meta.type.value);
34812
34842
  definitionMap.set('deps', compileDependencies(meta.deps));
@@ -34841,7 +34871,7 @@ function compileDeclareInjectableFromMetadata(meta) {
34841
34871
  function createInjectableDefinitionMap(meta) {
34842
34872
  const definitionMap = new DefinitionMap();
34843
34873
  definitionMap.set('minVersion', literal(MINIMUM_PARTIAL_LINKER_VERSION$3));
34844
- definitionMap.set('version', literal('20.3.9'));
34874
+ definitionMap.set('version', literal('20.3.11'));
34845
34875
  definitionMap.set('ngImport', importExpr(Identifiers.core));
34846
34876
  definitionMap.set('type', meta.type.value);
34847
34877
  // Only generate providedIn property if it has a non-null value
@@ -34892,7 +34922,7 @@ function compileDeclareInjectorFromMetadata(meta) {
34892
34922
  function createInjectorDefinitionMap(meta) {
34893
34923
  const definitionMap = new DefinitionMap();
34894
34924
  definitionMap.set('minVersion', literal(MINIMUM_PARTIAL_LINKER_VERSION$2));
34895
- definitionMap.set('version', literal('20.3.9'));
34925
+ definitionMap.set('version', literal('20.3.11'));
34896
34926
  definitionMap.set('ngImport', importExpr(Identifiers.core));
34897
34927
  definitionMap.set('type', meta.type.value);
34898
34928
  definitionMap.set('providers', meta.providers);
@@ -34925,7 +34955,7 @@ function createNgModuleDefinitionMap(meta) {
34925
34955
  throw new Error('Invalid path! Local compilation mode should not get into the partial compilation path');
34926
34956
  }
34927
34957
  definitionMap.set('minVersion', literal(MINIMUM_PARTIAL_LINKER_VERSION$1));
34928
- definitionMap.set('version', literal('20.3.9'));
34958
+ definitionMap.set('version', literal('20.3.11'));
34929
34959
  definitionMap.set('ngImport', importExpr(Identifiers.core));
34930
34960
  definitionMap.set('type', meta.type.value);
34931
34961
  // We only generate the keys in the metadata if the arrays contain values.
@@ -34976,7 +35006,7 @@ function compileDeclarePipeFromMetadata(meta) {
34976
35006
  function createPipeDefinitionMap(meta) {
34977
35007
  const definitionMap = new DefinitionMap();
34978
35008
  definitionMap.set('minVersion', literal(MINIMUM_PARTIAL_LINKER_VERSION));
34979
- definitionMap.set('version', literal('20.3.9'));
35009
+ definitionMap.set('version', literal('20.3.11'));
34980
35010
  definitionMap.set('ngImport', importExpr(Identifiers.core));
34981
35011
  // e.g. `type: MyPipe`
34982
35012
  definitionMap.set('type', meta.type.value);
@@ -35132,7 +35162,7 @@ function compileHmrUpdateCallback(definitions, constantStatements, meta) {
35132
35162
  * @description
35133
35163
  * Entry point for all public APIs of the compiler package.
35134
35164
  */
35135
- const VERSION = new Version('20.3.9');
35165
+ const VERSION = new Version('20.3.11');
35136
35166
 
35137
35167
  //////////////////////////////////////
35138
35168
  // THIS FILE HAS GLOBAL SIDE EFFECT //