@angular-wave/angular.ts 0.16.1 → 0.17.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (33) hide show
  1. package/@types/angular.d.ts +4 -0
  2. package/@types/animations/animate-css-driver.d.ts +10 -2
  3. package/@types/animations/animate-css.d.ts +8 -14
  4. package/@types/animations/animation.d.ts +1 -3
  5. package/@types/animations/cache/animate-cache.d.ts +99 -0
  6. package/@types/animations/cache/interface.d.ts +17 -0
  7. package/@types/animations/interface.d.ts +15 -18
  8. package/@types/animations/raf/raf-scheduler.d.ts +37 -0
  9. package/@types/core/compile/interface.d.ts +36 -5
  10. package/@types/core/interpolate/interface.d.ts +7 -1
  11. package/@types/core/scope/interface.d.ts +14 -4
  12. package/@types/core/scope/scope.d.ts +58 -22
  13. package/@types/directive/form/form.d.ts +16 -4
  14. package/@types/directive/model/model.d.ts +6 -4
  15. package/@types/filters/order-by.d.ts +13 -0
  16. package/@types/interface.d.ts +3 -3
  17. package/@types/router/path/path-node.d.ts +1 -1
  18. package/@types/router/resolve/resolve-context.d.ts +1 -1
  19. package/@types/router/transition/hook-registry.d.ts +1 -1
  20. package/@types/router/url/url-matcher.d.ts +1 -1
  21. package/@types/services/sce/interface.d.ts +1 -4
  22. package/@types/services/sce/sce.d.ts +7 -2
  23. package/@types/shared/common.d.ts +100 -39
  24. package/@types/shared/node.d.ts +5 -5
  25. package/@types/shared/strings.d.ts +2 -2
  26. package/dist/angular-ts.esm.js +1342 -901
  27. package/dist/angular-ts.umd.js +1342 -901
  28. package/dist/angular-ts.umd.min.js +1 -1
  29. package/dist/angular-ts.umd.min.js.gz +0 -0
  30. package/dist/angular-ts.umd.min.js.map +1 -1
  31. package/package.json +1 -1
  32. package/@types/animations/animate-cache.d.ts +0 -94
  33. package/@types/animations/raf-scheduler.d.ts +0 -35
@@ -1,4 +1,4 @@
1
- /* Version: 0.16.1 - January 5, 2026 22:44:26 */
1
+ /* Version: 0.17.0 - January 10, 2026 13:14:59 */
2
2
  (function (global, factory) {
3
3
  typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :
4
4
  typeof define === 'function' && define.amd ? define(['exports'], factory) :
@@ -31,11 +31,11 @@
31
31
  /** @internal */
32
32
  /** @enum {number} */
33
33
  const NodeType = {
34
- _ELEMENT_NODE: Node.ELEMENT_NODE,
35
- _DOCUMENT_NODE: Node.DOCUMENT_NODE,
36
- _TEXT_NODE: Node.TEXT_NODE,
37
- _COMMENT_NODE: Node.COMMENT_NODE,
38
- _DOCUMENT_FRAGMENT_NODE: Node.DOCUMENT_FRAGMENT_NODE,
34
+ _ELEMENT_NODE: 1, // Node.ELEMENT_NODE,
35
+ _DOCUMENT_NODE: 9, // Node.DOCUMENT_NODE,
36
+ _TEXT_NODE: 3, // Node.TEXT_NODE,
37
+ _COMMENT_NODE: 8, //Node.COMMENT_NODE,
38
+ _DOCUMENT_FRAGMENT_NODE: 11, // Node.DOCUMENT_FRAGMENT_NODE,
39
39
  };
40
40
 
41
41
  const isProxySymbol = Symbol("isProxy");
@@ -1192,20 +1192,17 @@
1192
1192
  if (!firstClass && !secondClass) return "";
1193
1193
 
1194
1194
  if (!firstClass)
1195
- // @ts-ignore
1196
- return isArray(secondClass) ? secondClass.join(" ").trim() : secondClass;
1195
+ return isArray(secondClass)
1196
+ ? secondClass.join(" ").trim()
1197
+ : /** @type {string} */ (secondClass);
1197
1198
 
1198
1199
  if (!secondClass)
1199
- // @ts-ignore
1200
1200
  return isArray(firstClass) ? firstClass.join(" ").trim() : firstClass;
1201
1201
 
1202
- // @ts-ignore
1203
1202
  if (isArray(firstClass)) firstClass = normalizeStringArray(firstClass);
1204
1203
 
1205
- // @ts-ignore
1206
1204
  if (isArray(secondClass)) secondClass = normalizeStringArray(secondClass);
1207
1205
 
1208
- // @ts-ignore
1209
1206
  return `${firstClass.trim()} ${secondClass.trim()}`.trim();
1210
1207
  }
1211
1208
 
@@ -1454,13 +1451,11 @@
1454
1451
  _attrs: "$attrs",
1455
1452
  _scope: "$scope",
1456
1453
  _element: "$element",
1457
- _animateCache: "$$animateCache",
1458
1454
  _animateCssDriver: "$$animateCssDriver",
1459
1455
  _animateJs: "$$animateJs",
1460
1456
  _animateJsDriver: "$$animateJsDriver",
1461
1457
  _animateQueue: "$$animateQueue",
1462
1458
  _animation: "$$animation",
1463
- _rAFScheduler: "$$rAFScheduler",
1464
1459
  _taskTrackerFactory: "$$taskTrackerFactory",
1465
1460
  _anchorScroll: "$anchorScroll",
1466
1461
  _animate: "$animate",
@@ -4256,9 +4251,10 @@
4256
4251
  const attrName =
4257
4252
  attrOverride || `ng${method.charAt(0).toUpperCase()}${method.slice(1)}`;
4258
4253
 
4259
- const directive = createHttpDirective(method, attrName);
4254
+ const directive = /** @type {ng.DirectiveFactory & Function} */ (
4255
+ createHttpDirective(method, attrName)
4256
+ );
4260
4257
 
4261
- // @ts-ignore
4262
4258
  directive.$inject = [
4263
4259
  $injectTokens._http,
4264
4260
  $injectTokens._compile,
@@ -4360,9 +4356,9 @@
4360
4356
  element.name.length > 0
4361
4357
  ) {
4362
4358
  if (
4363
- element instanceof HTMLInputElement ||
4364
- element instanceof HTMLTextAreaElement ||
4365
- element instanceof HTMLSelectElement
4359
+ isInstanceOf(element, HTMLInputElement) ||
4360
+ isInstanceOf(element, HTMLTextAreaElement) ||
4361
+ isInstanceOf(element, HTMLSelectElement)
4366
4362
  ) {
4367
4363
  const key = element.name;
4368
4364
 
@@ -5892,9 +5888,6 @@
5892
5888
  // code. (e.g. ng-include, script src binding, templateUrl)
5893
5889
  // A value that can be trusted as a RESOURCE_URL, can also trusted as a URL and a MEDIA_URL.
5894
5890
  RESOURCE_URL: "resourceUrl",
5895
-
5896
- // Script. Currently unused in AngularTS.
5897
- JS: "js",
5898
5891
  };
5899
5892
 
5900
5893
  // Copied from:
@@ -6164,7 +6157,7 @@
6164
6157
 
6165
6158
  function generateHolderType(Base) {
6166
6159
  const holderType = function TrustedValueHolderType(trustedValue) {
6167
- this.$$unwrapTrustedValue = function () {
6160
+ this._unwrapTrustedValue = function () {
6168
6161
  return trustedValue;
6169
6162
  };
6170
6163
  };
@@ -6173,10 +6166,10 @@
6173
6166
  holderType.prototype = new Base();
6174
6167
  }
6175
6168
  holderType.prototype.valueOf = function sceValueOf() {
6176
- return this.$$unwrapTrustedValue();
6169
+ return this._unwrapTrustedValue();
6177
6170
  };
6178
6171
  holderType.prototype.toString = function sceToString() {
6179
- return this.$$unwrapTrustedValue().toString();
6172
+ return this._unwrapTrustedValue().toString();
6180
6173
  };
6181
6174
 
6182
6175
  return holderType;
@@ -6220,7 +6213,8 @@
6220
6213
  * @return {*} A trusted representation of value, that can be used in the given context.
6221
6214
  */
6222
6215
  function trustAs(type, trustedValue) {
6223
- const Constructor = hasOwn(byType, type) ? byType[type] : null;
6216
+ const Constructor =
6217
+ isDefined(type) && hasOwn(byType, type) ? byType[type] : null;
6224
6218
 
6225
6219
  if (!Constructor) {
6226
6220
  $exceptionHandler(
@@ -6278,7 +6272,7 @@
6278
6272
  */
6279
6273
  function valueOf(maybeTrusted) {
6280
6274
  if (maybeTrusted instanceof trustedValueHolderBase) {
6281
- return maybeTrusted.$$unwrapTrustedValue();
6275
+ return maybeTrusted._unwrapTrustedValue();
6282
6276
  }
6283
6277
 
6284
6278
  return maybeTrusted;
@@ -6327,13 +6321,13 @@
6327
6321
  // If maybeTrusted is a trusted class instance or subclass instance, then unwrap and return
6328
6322
  // as-is.
6329
6323
  if (constructor && maybeTrusted instanceof constructor) {
6330
- return maybeTrusted.$$unwrapTrustedValue();
6324
+ return maybeTrusted._unwrapTrustedValue();
6331
6325
  }
6332
6326
 
6333
6327
  // If maybeTrusted is a trusted class instance but not of the correct trusted type
6334
6328
  // then unwrap it and allow it to pass through to the rest of the checks
6335
- if (isFunction(maybeTrusted.$$unwrapTrustedValue)) {
6336
- maybeTrusted = maybeTrusted.$$unwrapTrustedValue();
6329
+ if (isFunction(maybeTrusted._unwrapTrustedValue)) {
6330
+ maybeTrusted = maybeTrusted._unwrapTrustedValue();
6337
6331
  }
6338
6332
 
6339
6333
  // If we get here, then we will either sanitize the value or throw an exception.
@@ -6402,8 +6396,8 @@
6402
6396
  /**
6403
6397
  *
6404
6398
  * @param {ng.ParseService} $parse
6405
- * @param $sceDelegate
6406
- * @return {*}
6399
+ * @param {ng.SCEDelegateService} $sceDelegate
6400
+ * @return {ng.SCEService}
6407
6401
  */
6408
6402
  ($parse, $sceDelegate) => {
6409
6403
  const sce = shallowCopy(SCE_CONTEXTS);
@@ -6659,7 +6653,7 @@
6659
6653
  };
6660
6654
  });
6661
6655
 
6662
- return sce;
6656
+ return /** @type {ng.SCEService} */ (sce);
6663
6657
  },
6664
6658
  ];
6665
6659
  }
@@ -7878,24 +7872,24 @@
7878
7872
  }
7879
7873
 
7880
7874
  options = options || {};
7881
- let { parentBoundTranscludeFn } = options;
7875
+ let { _parentBoundTranscludeFn } = options;
7882
7876
 
7883
- const { transcludeControllers, futureParentElement } = options;
7877
+ const { transcludeControllers, _futureParentElement } = options;
7884
7878
 
7885
- // When `parentBoundTranscludeFn` is passed, it is a
7879
+ // When `_parentBoundTranscludeFn` is passed, it is a
7886
7880
  // `controllersBoundTransclude` function (it was previously passed
7887
7881
  // as `transclude` to directive.link) so we must unwrap it to get
7888
7882
  // its `boundTranscludeFn`
7889
7883
  if (
7890
- parentBoundTranscludeFn &&
7891
- parentBoundTranscludeFn.$$boundTransclude
7884
+ _parentBoundTranscludeFn &&
7885
+ _parentBoundTranscludeFn._boundTransclude
7892
7886
  ) {
7893
- parentBoundTranscludeFn =
7894
- parentBoundTranscludeFn.$$boundTransclude;
7887
+ _parentBoundTranscludeFn =
7888
+ _parentBoundTranscludeFn._boundTransclude;
7895
7889
  }
7896
7890
 
7897
7891
  if (!namespace) {
7898
- namespace = detectNamespaceForChildElements(futureParentElement);
7892
+ namespace = detectNamespaceForChildElements(_futureParentElement);
7899
7893
  }
7900
7894
  /** @type {NodeRef} */
7901
7895
  let $linkNode;
@@ -7937,7 +7931,7 @@
7937
7931
  }
7938
7932
 
7939
7933
  if (compositeLinkFn) {
7940
- compositeLinkFn(scope, $linkNode, parentBoundTranscludeFn);
7934
+ compositeLinkFn(scope, $linkNode, _parentBoundTranscludeFn);
7941
7935
  }
7942
7936
 
7943
7937
  if (!cloneConnectFn) {
@@ -8072,9 +8066,9 @@
8072
8066
  *
8073
8067
  * @param {ng.Scope} scope
8074
8068
  * @param {NodeRef} nodeRef
8075
- * @param {*} [parentBoundTranscludeFn]
8069
+ * @param {*} [_parentBoundTranscludeFn]
8076
8070
  */
8077
- function compositeLinkFn(scope, nodeRef, parentBoundTranscludeFn) {
8071
+ function compositeLinkFn(scope, nodeRef, _parentBoundTranscludeFn) {
8078
8072
  assertArg(nodeRef, "nodeRef");
8079
8073
  let stableNodeList = [];
8080
8074
 
@@ -8121,14 +8115,14 @@
8121
8115
  childBoundTranscludeFn = createBoundTranscludeFn(
8122
8116
  scope,
8123
8117
  nodeLinkFnCtx.transclude,
8124
- parentBoundTranscludeFn,
8118
+ _parentBoundTranscludeFn,
8125
8119
  );
8126
8120
  } else if (
8127
8121
  !nodeLinkFnCtx.templateOnThisElement &&
8128
- parentBoundTranscludeFn
8122
+ _parentBoundTranscludeFn
8129
8123
  ) {
8130
- childBoundTranscludeFn = parentBoundTranscludeFn;
8131
- } else if (!parentBoundTranscludeFn && transcludeFn) {
8124
+ childBoundTranscludeFn = _parentBoundTranscludeFn;
8125
+ } else if (!_parentBoundTranscludeFn && transcludeFn) {
8132
8126
  childBoundTranscludeFn = createBoundTranscludeFn(
8133
8127
  scope,
8134
8128
  transcludeFn,
@@ -8141,9 +8135,8 @@
8141
8135
  if (nodeLinkFnCtx?.newScope) {
8142
8136
  setScope(node, childScope);
8143
8137
  }
8144
- // @ts-ignore
8138
+
8145
8139
  nodeLinkFnCtx.nodeLinkFn(
8146
- // @ts-ignore
8147
8140
  childLinkFn,
8148
8141
  childScope,
8149
8142
  node,
@@ -8153,7 +8146,7 @@
8153
8146
  childLinkFn(
8154
8147
  scope,
8155
8148
  new NodeRef(node.childNodes),
8156
- parentBoundTranscludeFn,
8149
+ _parentBoundTranscludeFn,
8157
8150
  );
8158
8151
  }
8159
8152
  });
@@ -8176,18 +8169,17 @@
8176
8169
  transcludedScope,
8177
8170
  cloneFn,
8178
8171
  controllers,
8179
- futureParentElement,
8172
+ _futureParentElement,
8180
8173
  containingScope,
8181
8174
  ) {
8182
8175
  if (!transcludedScope) {
8183
8176
  transcludedScope = scope.$transcluded(containingScope);
8184
- transcludedScope.$$transcluded = true;
8185
8177
  }
8186
8178
 
8187
8179
  const transcludeRes = transcludeFn(transcludedScope, cloneFn, {
8188
- parentBoundTranscludeFn: previousBoundTranscludeFn,
8180
+ _parentBoundTranscludeFn: previousBoundTranscludeFn,
8189
8181
  transcludeControllers: controllers,
8190
- futureParentElement,
8182
+ _futureParentElement,
8191
8183
  });
8192
8184
 
8193
8185
  return transcludeRes;
@@ -8195,13 +8187,13 @@
8195
8187
 
8196
8188
  // We need to attach the transclusion slots onto the `boundTranscludeFn`
8197
8189
  // so that they are available inside the `controllersBoundTransclude` function
8198
- const boundSlots = (boundTranscludeFn.$$slots = Object.create(null));
8190
+ const boundSlots = (boundTranscludeFn._slots = Object.create(null));
8199
8191
 
8200
- for (const slotName in transcludeFn.$$slots) {
8201
- if (transcludeFn.$$slots[slotName]) {
8192
+ for (const slotName in transcludeFn._slots) {
8193
+ if (transcludeFn._slots[slotName]) {
8202
8194
  boundSlots[slotName] = createBoundTranscludeFn(
8203
8195
  scope,
8204
- transcludeFn.$$slots[slotName],
8196
+ transcludeFn._slots[slotName],
8205
8197
  previousBoundTranscludeFn,
8206
8198
  );
8207
8199
  } else {
@@ -8453,11 +8445,11 @@
8453
8445
  let terminal = false;
8454
8446
 
8455
8447
  let {
8456
- newScopeDirective,
8457
- controllerDirectives,
8458
- newIsolateScopeDirective,
8459
- templateDirective,
8460
- nonTlbTranscludeDirective,
8448
+ _newScopeDirective,
8449
+ _controllerDirectives,
8450
+ _newIsolateScopeDirective,
8451
+ _templateDirective,
8452
+ _nonTlbTranscludeDirective,
8461
8453
  hasElementTranscludeDirective,
8462
8454
  } = previousCompileContext;
8463
8455
 
@@ -8480,7 +8472,7 @@
8480
8472
 
8481
8473
  let replaceDirective = originalReplaceDirective;
8482
8474
 
8483
- /** @type {ng.TranscludeFn} */
8475
+ /** @type {import("./interface.ts").ChildTranscludeOrLinkFn} */
8484
8476
  let childTranscludeFn = transcludeFn;
8485
8477
 
8486
8478
  let didScanForMultipleTransclusion = false;
@@ -8493,7 +8485,7 @@
8493
8485
  * Links all the directives of a single node.
8494
8486
  * @type {ng.NodeLinkFn}
8495
8487
  */
8496
- // @ts-ignore
8488
+
8497
8489
  let nodeLinkFn = function (
8498
8490
  childLinkFn,
8499
8491
  scope,
@@ -8536,49 +8528,49 @@
8536
8528
 
8537
8529
  controllerScope = scope;
8538
8530
 
8539
- if (newIsolateScopeDirective) {
8531
+ if (_newIsolateScopeDirective) {
8540
8532
  isolateScope = scope.$newIsolate();
8541
- } else if (newScopeDirective) {
8533
+ } else if (_newScopeDirective) {
8542
8534
  controllerScope = scope.$parent;
8543
8535
  }
8544
8536
 
8545
8537
  if (boundTranscludeFn) {
8546
8538
  // track `boundTranscludeFn` so it can be unwrapped if `transcludeFn`
8547
- // is later passed as `parentBoundTranscludeFn` to `publicLinkFn`
8539
+ // is later passed as `_parentBoundTranscludeFn` to `publicLinkFn`
8548
8540
  /** @type {any} */
8549
8541
  const newTrancludeFn = /** @type {any} */ (
8550
8542
  controllersBoundTransclude
8551
8543
  );
8552
8544
 
8553
- newTrancludeFn.$$boundTransclude = boundTranscludeFn;
8545
+ newTrancludeFn._boundTransclude = boundTranscludeFn;
8554
8546
  // expose the slots on the `$transclude` function
8555
8547
  newTrancludeFn.isSlotFilled = function (slotName) {
8556
- return !!boundTranscludeFn.$$slots[slotName];
8548
+ return !!boundTranscludeFn._slots[slotName];
8557
8549
  };
8558
8550
  transcludeFn = newTrancludeFn;
8559
8551
  }
8560
8552
 
8561
- if (controllerDirectives) {
8553
+ if (_controllerDirectives) {
8562
8554
  elementControllers = setupControllers(
8563
8555
  $element,
8564
8556
  attrs,
8565
8557
  transcludeFn,
8566
- controllerDirectives,
8558
+ _controllerDirectives,
8567
8559
  isolateScope,
8568
8560
  scope,
8569
- newIsolateScopeDirective,
8561
+ _newIsolateScopeDirective,
8570
8562
  );
8571
8563
  }
8572
8564
 
8573
- if (newIsolateScopeDirective) {
8574
- isolateScope.$target.$$isolateBindings =
8575
- newIsolateScopeDirective.$$isolateBindings;
8565
+ if (_newIsolateScopeDirective) {
8566
+ isolateScope.$target._isolateBindings =
8567
+ _newIsolateScopeDirective._isolateBindings;
8576
8568
  scopeBindingInfo = initializeDirectiveBindings(
8577
8569
  scope,
8578
8570
  attrs,
8579
8571
  isolateScope,
8580
- isolateScope.$$isolateBindings,
8581
- newIsolateScopeDirective,
8572
+ isolateScope._isolateBindings,
8573
+ _newIsolateScopeDirective,
8582
8574
  );
8583
8575
 
8584
8576
  if (scopeBindingInfo.removeWatches) {
@@ -8588,11 +8580,11 @@
8588
8580
 
8589
8581
  // Initialize bindToController bindings
8590
8582
  for (const name in elementControllers) {
8591
- const controllerDirective = controllerDirectives[name];
8583
+ const controllerDirective = _controllerDirectives[name];
8592
8584
 
8593
8585
  const controller = elementControllers[name];
8594
8586
 
8595
- const bindings = controllerDirective.$$bindings.bindToController;
8587
+ const bindings = controllerDirective._bindings.bindToController;
8596
8588
 
8597
8589
  // Controller instance is bound to the scope
8598
8590
  const controllerInstance = controller();
@@ -8613,8 +8605,8 @@
8613
8605
  }
8614
8606
 
8615
8607
  // Bind the required controllers to the controller, if `require` is an object and `bindToController` is truthy
8616
- if (controllerDirectives) {
8617
- entries(controllerDirectives).forEach(
8608
+ if (_controllerDirectives) {
8609
+ entries(_controllerDirectives).forEach(
8618
8610
  ([name, controllerDirective]) => {
8619
8611
  const { require } = controllerDirective;
8620
8612
 
@@ -8700,9 +8692,9 @@
8700
8692
  // otherwise the child elements do not belong to the isolate directive.
8701
8693
 
8702
8694
  if (
8703
- newIsolateScopeDirective &&
8704
- (newIsolateScopeDirective.template ||
8705
- newIsolateScopeDirective.templateUrl === null)
8695
+ _newIsolateScopeDirective &&
8696
+ (_newIsolateScopeDirective.template ||
8697
+ _newIsolateScopeDirective.templateUrl === null)
8706
8698
  ) {
8707
8699
  scopeToChild = isolateScope;
8708
8700
  }
@@ -8769,15 +8761,15 @@
8769
8761
  function controllersBoundTransclude(
8770
8762
  scopeParam,
8771
8763
  cloneAttachFn,
8772
- futureParentElement,
8764
+ _futureParentElement,
8773
8765
  slotName,
8774
8766
  ) {
8775
8767
  let transcludeControllers;
8776
8768
 
8777
8769
  // No scope passed in:
8778
8770
  if (!isScope(scopeParam)) {
8779
- slotName = futureParentElement;
8780
- futureParentElement = cloneAttachFn;
8771
+ slotName = _futureParentElement;
8772
+ _futureParentElement = cloneAttachFn;
8781
8773
  cloneAttachFn = scopeParam;
8782
8774
  scopeParam = undefined;
8783
8775
  }
@@ -8786,8 +8778,8 @@
8786
8778
  transcludeControllers = elementControllers;
8787
8779
  }
8788
8780
 
8789
- if (!futureParentElement) {
8790
- futureParentElement = hasElementTranscludeDirective
8781
+ if (!_futureParentElement) {
8782
+ _futureParentElement = hasElementTranscludeDirective
8791
8783
  ? $element.node.parentElement
8792
8784
  : $element.node;
8793
8785
  }
@@ -8797,14 +8789,14 @@
8797
8789
  // * a transclude function - a filled slot
8798
8790
  // * `null` - an optional slot that was not filled
8799
8791
  // * `undefined` - a slot that was not declared (i.e. invalid)
8800
- const slotTranscludeFn = boundTranscludeFn.$$slots[slotName];
8792
+ const slotTranscludeFn = boundTranscludeFn._slots[slotName];
8801
8793
 
8802
8794
  if (slotTranscludeFn) {
8803
8795
  return slotTranscludeFn(
8804
8796
  scopeParam,
8805
8797
  cloneAttachFn,
8806
8798
  transcludeControllers,
8807
- futureParentElement,
8799
+ _futureParentElement,
8808
8800
  scopeToChild,
8809
8801
  );
8810
8802
  }
@@ -8825,7 +8817,7 @@
8825
8817
  scopeParam,
8826
8818
  cloneAttachFn,
8827
8819
  transcludeControllers,
8828
- futureParentElement,
8820
+ _futureParentElement,
8829
8821
  scopeToChild,
8830
8822
  );
8831
8823
  }
@@ -8851,24 +8843,24 @@
8851
8843
  // Check that there is no scope of any kind already
8852
8844
  assertNoDuplicate(
8853
8845
  "new/isolated scope",
8854
- newIsolateScopeDirective || newScopeDirective,
8846
+ _newIsolateScopeDirective || _newScopeDirective,
8855
8847
  directive,
8856
8848
  compileNodeRef,
8857
8849
  );
8858
- newIsolateScopeDirective = directive;
8850
+ _newIsolateScopeDirective = directive;
8859
8851
  } else {
8860
8852
  // This directive is trying to add a child scope.
8861
8853
  // Check that there is no isolated scope already
8862
8854
  assertNoDuplicate(
8863
8855
  "new/isolated scope",
8864
- newIsolateScopeDirective,
8856
+ _newIsolateScopeDirective,
8865
8857
  directive,
8866
8858
  compileNodeRef,
8867
8859
  );
8868
8860
  }
8869
8861
  }
8870
8862
 
8871
- newScopeDirective = newScopeDirective || directive;
8863
+ _newScopeDirective = _newScopeDirective || directive;
8872
8864
  }
8873
8865
 
8874
8866
  directiveName = directive.name;
@@ -8914,15 +8906,15 @@
8914
8906
  }
8915
8907
 
8916
8908
  if (!directive.templateUrl && directive.controller) {
8917
- controllerDirectives =
8918
- controllerDirectives || Object.create(null);
8909
+ _controllerDirectives =
8910
+ _controllerDirectives || Object.create(null);
8919
8911
  assertNoDuplicate(
8920
8912
  `'${directiveName}' controller`,
8921
- controllerDirectives[directiveName],
8913
+ _controllerDirectives[directiveName],
8922
8914
  directive,
8923
8915
  compileNodeRef,
8924
8916
  );
8925
- controllerDirectives[directiveName] = directive;
8917
+ _controllerDirectives[directiveName] = directive;
8926
8918
  }
8927
8919
 
8928
8920
  directiveValue = directive.transclude;
@@ -8936,11 +8928,11 @@
8936
8928
  if (!EXCLUDED_DIRECTIVES.includes(directive.name)) {
8937
8929
  assertNoDuplicate(
8938
8930
  "transclusion",
8939
- nonTlbTranscludeDirective,
8931
+ _nonTlbTranscludeDirective,
8940
8932
  directive,
8941
8933
  compileNodeRef,
8942
8934
  );
8943
- nonTlbTranscludeDirective = directive;
8935
+ _nonTlbTranscludeDirective = directive;
8944
8936
  }
8945
8937
 
8946
8938
  if (directiveValue === "element") {
@@ -8957,7 +8949,6 @@
8957
8949
  index,
8958
8950
  );
8959
8951
 
8960
- // @ts-ignore
8961
8952
  childTranscludeFn = compilationGenerator(
8962
8953
  mightHaveMultipleTransclusionError,
8963
8954
  $template._element,
@@ -8966,13 +8957,13 @@
8966
8957
  replaceDirective && replaceDirective.name,
8967
8958
  {
8968
8959
  // Don't pass in:
8969
- // - controllerDirectives - otherwise we'll create duplicates controllers
8970
- // - newIsolateScopeDirective or templateDirective - combining templates with
8960
+ // - _controllerDirectives - otherwise we'll create duplicates controllers
8961
+ // - _newIsolateScopeDirective or _templateDirective - combining templates with
8971
8962
  // element transclusion doesn't make sense.
8972
8963
  //
8973
- // We need only nonTlbTranscludeDirective so that we prevent putting transclusion
8964
+ // We need only _nonTlbTranscludeDirective so that we prevent putting transclusion
8974
8965
  // on the same element more than once.
8975
- nonTlbTranscludeDirective,
8966
+ _nonTlbTranscludeDirective,
8976
8967
  },
8977
8968
  );
8978
8969
  } else {
@@ -9065,7 +9056,7 @@
9065
9056
  emptyElement(/** @type {Element} */ (compileNode)); // clear contents on transcluded directives
9066
9057
 
9067
9058
  // lazily compile transcluded template and generate a transcluded link function
9068
- // @ts-ignore
9059
+
9069
9060
  childTranscludeFn = compilationGenerator(
9070
9061
  mightHaveMultipleTransclusionError,
9071
9062
  nodes,
@@ -9077,7 +9068,9 @@
9077
9068
  directive.$$isolateScope || directive.$$newScope,
9078
9069
  },
9079
9070
  );
9080
- childTranscludeFn.$$slots = slots;
9071
+ /** @type {import("./interface.ts").TranscludeFn} */ (
9072
+ childTranscludeFn
9073
+ )._slots = slots;
9081
9074
  }
9082
9075
  }
9083
9076
 
@@ -9085,11 +9078,11 @@
9085
9078
  hasTemplate = true;
9086
9079
  assertNoDuplicate(
9087
9080
  "template",
9088
- templateDirective,
9081
+ _templateDirective,
9089
9082
  directive,
9090
9083
  compileNodeRef,
9091
9084
  );
9092
- templateDirective = directive;
9085
+ _templateDirective = directive;
9093
9086
 
9094
9087
  directiveValue = isFunction(directive.template)
9095
9088
  ? directive.template(compileNodeRef.node, templateAttrs)
@@ -9146,7 +9139,7 @@
9146
9139
  // - split it into two parts, those that already applied (processed) and those that weren't (unprocessed)
9147
9140
  // - collect directives from the template and sort them by priority
9148
9141
  // - combine directives as: processed + template + unprocessed
9149
- const templateDirectives = collectDirectives(
9142
+ const _templateDirectives = collectDirectives(
9150
9143
  /** @type {Element} */ (compileNode),
9151
9144
  newTemplateAttrs,
9152
9145
  );
@@ -9156,18 +9149,18 @@
9156
9149
  directives.length - (i + 1),
9157
9150
  );
9158
9151
 
9159
- if (newIsolateScopeDirective || newScopeDirective) {
9152
+ if (_newIsolateScopeDirective || _newScopeDirective) {
9160
9153
  // The original directive caused the current element to be replaced but this element
9161
9154
  // also needs to have a new scope, so we need to tell the template directives
9162
9155
  // that they would need to get their scope from further up, if they require transclusion
9163
9156
  markDirectiveScope(
9164
- templateDirectives,
9165
- newIsolateScopeDirective,
9166
- newScopeDirective,
9157
+ _templateDirectives,
9158
+ _newIsolateScopeDirective,
9159
+ _newScopeDirective,
9167
9160
  );
9168
9161
  }
9169
9162
  directives = directives
9170
- .concat(templateDirectives)
9163
+ .concat(_templateDirectives)
9171
9164
  .concat(unprocessedDirectives);
9172
9165
 
9173
9166
  mergeTemplateAttributes(templateAttrs, newTemplateAttrs);
@@ -9184,16 +9177,16 @@
9184
9177
  hasTemplate = true;
9185
9178
  assertNoDuplicate(
9186
9179
  "template",
9187
- templateDirective,
9180
+ _templateDirective,
9188
9181
  directive,
9189
9182
  compileNodeRef,
9190
9183
  );
9191
- templateDirective = directive;
9184
+ _templateDirective = directive;
9192
9185
 
9193
9186
  if (directive.replace) {
9194
9187
  replaceDirective = directive;
9195
9188
  }
9196
- // @ts-ignore
9189
+
9197
9190
  nodeLinkFn = compileTemplateUrl(
9198
9191
  directives.splice(i, directives.length - i),
9199
9192
  compileNodeRef,
@@ -9204,14 +9197,14 @@
9204
9197
  postLinkFns,
9205
9198
  {
9206
9199
  index,
9207
- controllerDirectives,
9208
- newScopeDirective:
9209
- newScopeDirective !== directive && newScopeDirective,
9210
- newIsolateScopeDirective,
9211
- templateDirective,
9212
- nonTlbTranscludeDirective,
9213
- futureParentElement:
9214
- previousCompileContext.futureParentElement,
9200
+ _controllerDirectives,
9201
+ _newScopeDirective:
9202
+ _newScopeDirective !== directive && _newScopeDirective,
9203
+ _newIsolateScopeDirective,
9204
+ _templateDirective,
9205
+ _nonTlbTranscludeDirective,
9206
+ _futureParentElement:
9207
+ previousCompileContext._futureParentElement,
9215
9208
  },
9216
9209
  );
9217
9210
  ii = directives.length;
@@ -9255,7 +9248,7 @@
9255
9248
  transclude: childTranscludeFn,
9256
9249
  transcludeOnThisElement: hasTranscludeDirective,
9257
9250
  templateOnThisElement: hasTemplate,
9258
- newScope: newScopeDirective && newScopeDirective.scope === true,
9251
+ newScope: _newScopeDirective && _newScopeDirective.scope === true,
9259
9252
  };
9260
9253
 
9261
9254
  /// /////////////////
@@ -9265,7 +9258,7 @@
9265
9258
  pre.directiveName = directiveName;
9266
9259
 
9267
9260
  if (
9268
- newIsolateScopeDirective === directive ||
9261
+ _newIsolateScopeDirective === directive ||
9269
9262
  directive.$$isolateScope
9270
9263
  ) {
9271
9264
  pre = cloneAndAnnotateFn(pre, { isolateScope: true });
@@ -9278,7 +9271,7 @@
9278
9271
  post.directiveName = directiveName;
9279
9272
 
9280
9273
  if (
9281
- newIsolateScopeDirective === directive ||
9274
+ _newIsolateScopeDirective === directive ||
9282
9275
  directive.$$isolateScope
9283
9276
  ) {
9284
9277
  post = cloneAndAnnotateFn(post, { isolateScope: true });
@@ -9385,29 +9378,29 @@
9385
9378
  * @param {NodeRef} $element
9386
9379
  * @param attrs
9387
9380
  * @param transcludeFn
9388
- * @param controllerDirectives
9381
+ * @param _controllerDirectives
9389
9382
  * @param isolateScope
9390
9383
  * @param scope
9391
- * @param newIsolateScopeDirective
9384
+ * @param _newIsolateScopeDirective
9392
9385
  * @returns {any}
9393
9386
  */
9394
9387
  function setupControllers(
9395
9388
  $element,
9396
9389
  attrs,
9397
9390
  transcludeFn,
9398
- controllerDirectives,
9391
+ _controllerDirectives,
9399
9392
  isolateScope,
9400
9393
  scope,
9401
- newIsolateScopeDirective,
9394
+ _newIsolateScopeDirective,
9402
9395
  ) {
9403
9396
  const elementControllers = Object.create(null);
9404
9397
 
9405
- for (const controllerKey in controllerDirectives) {
9406
- const directive = controllerDirectives[controllerKey];
9398
+ for (const controllerKey in _controllerDirectives) {
9399
+ const directive = _controllerDirectives[controllerKey];
9407
9400
 
9408
9401
  const locals = {
9409
9402
  $scope:
9410
- directive === newIsolateScopeDirective ||
9403
+ directive === _newIsolateScopeDirective ||
9411
9404
  directive.$$isolateScope
9412
9405
  ? isolateScope
9413
9406
  : scope,
@@ -9493,12 +9486,12 @@
9493
9486
  maxPriority > directive.priority) &&
9494
9487
  directive.restrict.indexOf(location) !== -1
9495
9488
  ) {
9496
- if (!directive.$$bindings) {
9497
- const bindings = (directive.$$bindings =
9489
+ if (!directive._bindings) {
9490
+ const bindings = (directive._bindings =
9498
9491
  parseDirectiveBindings(directive, directive.name));
9499
9492
 
9500
9493
  if (isObject(bindings.isolateScope)) {
9501
- directive.$$isolateBindings = bindings.isolateScope;
9494
+ directive._isolateBindings = bindings.isolateScope;
9502
9495
  }
9503
9496
  }
9504
9497
  tDirectives.push(directive);
@@ -9664,7 +9657,7 @@
9664
9657
  previousCompileContext.index,
9665
9658
  );
9666
9659
 
9667
- const templateDirectives = collectDirectives(
9660
+ const _templateDirectives = collectDirectives(
9668
9661
  compileNode,
9669
9662
  tempTemplateAttrs,
9670
9663
  );
@@ -9672,9 +9665,9 @@
9672
9665
  if (isObject(origAsyncDirective.scope)) {
9673
9666
  // the original directive that caused the template to be loaded async required
9674
9667
  // an isolate scope
9675
- markDirectiveScope(templateDirectives, true);
9668
+ markDirectiveScope(_templateDirectives, true);
9676
9669
  }
9677
- directives = templateDirectives.concat(directives);
9670
+ directives = _templateDirectives.concat(directives);
9678
9671
 
9679
9672
  mergeTemplateAttributes(tAttrs, tempTemplateAttrs);
9680
9673
  } else {
@@ -9846,6 +9839,10 @@
9846
9839
  }
9847
9840
  }
9848
9841
 
9842
+ /**
9843
+ * @param {ng.Directive[]} directives
9844
+ * @param {string} text
9845
+ */
9849
9846
  function addTextInterpolateDirective(directives, text) {
9850
9847
  const interpolateFn = $interpolate(text, true);
9851
9848
 
@@ -10453,7 +10450,7 @@
10453
10450
  });
10454
10451
  } else {
10455
10452
  parentSet(scope.$target, (lastValue = val));
10456
- scope.$handler.watchers
10453
+ scope.$handler._watchers
10457
10454
  .get(attrs[attrName])
10458
10455
  ?.forEach((watchFn) => {
10459
10456
  watchFn.listenerFn(val, scope.$target);
@@ -10728,13 +10725,16 @@
10728
10725
  ];
10729
10726
 
10730
10727
  /**
10731
- * @param {Element} $element
10728
+ * @param {HTMLFormElement} $element
10732
10729
  * @param {ng.Attributes} $attrs
10733
10730
  * @param {ng.Scope} $scope
10734
10731
  * @param {ng.AnimateService} $animate
10735
10732
  * @param {ng.InterpolateService} $interpolate
10736
10733
  */
10737
10734
  constructor($element, $attrs, $scope, $animate, $interpolate) {
10735
+ /** @type {boolean} */
10736
+ this._isAnimated = hasAnimate($element);
10737
+
10738
10738
  this._controls = [];
10739
10739
 
10740
10740
  this.$name = $interpolate($attrs.name || $attrs.ngForm || "")($scope);
@@ -11098,16 +11098,6 @@
11098
11098
  }
11099
11099
  }
11100
11100
 
11101
- function cachedToggleClass(ctrl, className, switchValue) {
11102
- if (switchValue && !ctrl._classCache[className]) {
11103
- ctrl._animate.addClass(ctrl._element, className);
11104
- ctrl._classCache[className] = true;
11105
- } else if (!switchValue && ctrl._classCache[className]) {
11106
- ctrl._animate.removeClass(ctrl._element, className);
11107
- ctrl._classCache[className] = false;
11108
- }
11109
- }
11110
-
11111
11101
  function toggleValidationCss(ctrl, validationErrorKeyParam, isValid) {
11112
11102
  validationErrorKeyParam = validationErrorKeyParam
11113
11103
  ? `-${snakeCase(validationErrorKeyParam, "-")}`
@@ -11331,6 +11321,29 @@
11331
11321
  const formDirective = formDirectiveFactory();
11332
11322
  const ngFormDirective = formDirectiveFactory("ngForm");
11333
11323
 
11324
+ /**
11325
+ * @param {FormController|ng.NgModelController} ctrl
11326
+ * @param {string} className
11327
+ * @param {boolean} switchValue
11328
+ */
11329
+ function cachedToggleClass(ctrl, className, switchValue) {
11330
+ if (switchValue && !ctrl._classCache[className]) {
11331
+ if (ctrl._isAnimated) {
11332
+ ctrl._animate.addClass(ctrl._element, className);
11333
+ } else {
11334
+ ctrl._element.classList.add(className);
11335
+ }
11336
+ ctrl._classCache[className] = true;
11337
+ } else if (!switchValue && ctrl._classCache[className]) {
11338
+ if (ctrl._isAnimated) {
11339
+ ctrl._animate.removeClass(ctrl._element, className);
11340
+ } else {
11341
+ ctrl._element.classList.remove(className);
11342
+ }
11343
+ ctrl._classCache[className] = false;
11344
+ }
11345
+ }
11346
+
11334
11347
  const DEFAULT_REGEXP = /(\s+|^)default(\s+|$)/;
11335
11348
 
11336
11349
  /**
@@ -11529,7 +11542,7 @@
11529
11542
  * @param {ng.Scope} $scope
11530
11543
  * @param {ng.ExceptionHandlerService} $exceptionHandler
11531
11544
  * @param {ng.Attributes} $attr
11532
- * @param {Element} $element
11545
+ * @param {HTMLElement} $element
11533
11546
  * @param {ng.ParseService} $parse
11534
11547
  * @param {ng.AnimateService} $animate
11535
11548
  * @param {ng.InterpolateService} $interpolate
@@ -11543,6 +11556,8 @@
11543
11556
  $animate,
11544
11557
  $interpolate,
11545
11558
  ) {
11559
+ /** @type {boolean} */
11560
+ this._isAnimated = hasAnimate($element);
11546
11561
  /** @type {any} The actual value from the control's view */
11547
11562
  this.$viewValue = Number.NaN;
11548
11563
 
@@ -11661,25 +11676,6 @@
11661
11676
  }
11662
11677
  }
11663
11678
 
11664
- function cachedToggleClass(ctrl, className, switchValue) {
11665
- if (switchValue && !ctrl._classCache[className]) {
11666
- if (hasAnimate(ctrl._element)) {
11667
- ctrl._animate.addClass(ctrl._element, className);
11668
- } else {
11669
- ctrl._element.classList.add(className);
11670
- }
11671
-
11672
- ctrl._classCache[className] = true;
11673
- } else if (!switchValue && ctrl._classCache[className]) {
11674
- if (hasAnimate(ctrl._element)) {
11675
- ctrl._animate.removeClass(ctrl._element, className);
11676
- } else {
11677
- ctrl._element.classList.remove(className);
11678
- }
11679
- ctrl._classCache[className] = false;
11680
- }
11681
- }
11682
-
11683
11679
  function toggleValidationCss(ctrl, validationErrorKeyParam, isValid) {
11684
11680
  validationErrorKeyParam = validationErrorKeyParam
11685
11681
  ? `-${snakeCase(validationErrorKeyParam, "-")}`
@@ -12242,7 +12238,7 @@
12242
12238
 
12243
12239
  if (isNumberNaN(this.$modelValue)) {
12244
12240
  // this.$modelValue has not been touched yet...
12245
- // @ts-ignore
12241
+
12246
12242
  this.$modelValue = this._ngModelGet(this._scope);
12247
12243
  }
12248
12244
  const prevModelValue = this.$modelValue;
@@ -12826,7 +12822,7 @@
12826
12822
  // control's value is the same empty value twice in a row.
12827
12823
  if (
12828
12824
  ctrl.$viewValue !== value ||
12829
- (value === "" && ctrl.$$hasNativeValidators)
12825
+ (value === "" && ctrl._hasNativeValidators)
12830
12826
  ) {
12831
12827
  ctrl.$target.$setViewValue(value, event);
12832
12828
  }
@@ -12842,7 +12838,7 @@
12842
12838
  // check for validity changes on various DOM events.
12843
12839
  if (
12844
12840
  PARTIAL_VALIDATION_TYPES[type] &&
12845
- ctrl.$$hasNativeValidators &&
12841
+ ctrl._hasNativeValidators &&
12846
12842
  type === attr.type
12847
12843
  ) {
12848
12844
  element.addEventListener(PARTIAL_VALIDATION_EVENTS, (ev) => {
@@ -12932,7 +12928,7 @@
12932
12928
  }
12933
12929
 
12934
12930
  function badInputChecker(scope, element, attr, ctrl, parserName) {
12935
- const nativeValidation = (ctrl.$$hasNativeValidators = isObject(
12931
+ const nativeValidation = (ctrl._hasNativeValidators = isObject(
12936
12932
  element.validity,
12937
12933
  ));
12938
12934
 
@@ -13134,7 +13130,7 @@
13134
13130
  numberFormatterParser(ctrl);
13135
13131
  baseInputType(scope, element, attr, ctrl);
13136
13132
 
13137
- const supportsRange = ctrl.$$hasNativeValidators && element.type === "range";
13133
+ const supportsRange = ctrl._hasNativeValidators && element.type === "range";
13138
13134
 
13139
13135
  let minVal = supportsRange ? 0 : undefined;
13140
13136
 
@@ -13572,41 +13568,41 @@
13572
13568
  */
13573
13569
  constructor($element, $scope) {
13574
13570
  /** @type {HTMLSelectElement} */
13575
- this.$element = $element;
13571
+ this._element = $element;
13576
13572
 
13577
13573
  /** @type {ng.Scope} */
13578
- this.$scope = $scope;
13574
+ this._scope = $scope;
13579
13575
 
13580
13576
  /** @type {Object<string, any>} */
13581
- this.selectValueMap = {};
13577
+ this._selectValueMap = {};
13582
13578
 
13583
13579
  /** @type {any} */
13584
- this.ngModelCtrl = {};
13580
+ this._ngModelCtrl = {};
13585
13581
 
13586
13582
  /** @type {boolean} */
13587
- this.multiple = false;
13583
+ this._multiple = false;
13588
13584
 
13589
13585
  /** @private @type {HTMLOptionElement} */
13590
13586
  this._unknownOption = document.createElement("option");
13591
13587
 
13592
13588
  /** @type {boolean} */
13593
- this.hasEmptyOption = false;
13589
+ this._hasEmptyOption = false;
13594
13590
 
13595
13591
  /** @type {HTMLOptionElement|undefined} */
13596
- this.emptyOption = undefined;
13592
+ this._emptyOption = undefined;
13597
13593
 
13598
13594
  /** @type {Map<any, number>} */
13599
- this.optionsMap = new Map();
13595
+ this._optionsMap = new Map();
13600
13596
 
13601
13597
  /** @type {boolean} */
13602
- this.renderScheduled = false;
13598
+ this._renderScheduled = false;
13603
13599
 
13604
13600
  /** @type {boolean} */
13605
- this.updateScheduled = false;
13601
+ this._updateScheduled = false;
13606
13602
 
13607
13603
  $scope.$on("$destroy", () => {
13608
13604
  // disable unknown option so that we don't do work when the whole select is being destroyed
13609
- this.renderUnknownOption = () => {
13605
+ this._renderUnknownOption = () => {
13610
13606
  /* empty */
13611
13607
  };
13612
13608
  });
@@ -13616,27 +13612,27 @@
13616
13612
  * Render the unknown option when the viewValue doesn't match any options.
13617
13613
  * @param {*} val
13618
13614
  */
13619
- renderUnknownOption(val) {
13620
- const unknownVal = this.generateUnknownOptionValue(val);
13615
+ _renderUnknownOption(val) {
13616
+ const unknownVal = this._generateUnknownOptionValue(val);
13621
13617
 
13622
13618
  this._unknownOption.value = unknownVal;
13623
- this.$element.prepend(this._unknownOption);
13619
+ this._element.prepend(this._unknownOption);
13624
13620
  this._unknownOption.selected = true;
13625
13621
  this._unknownOption.setAttribute("selected", "selected");
13626
- this.$element.value = unknownVal;
13622
+ this._element.value = unknownVal;
13627
13623
  }
13628
13624
 
13629
13625
  /**
13630
13626
  * Update the unknown option if it's already rendered.
13631
13627
  * @param {*} val
13632
13628
  */
13633
- updateUnknownOption(val) {
13634
- const unknownVal = this.generateUnknownOptionValue(val);
13629
+ _updateUnknownOption(val) {
13630
+ const unknownVal = this._generateUnknownOptionValue(val);
13635
13631
 
13636
13632
  this._unknownOption.value = unknownVal;
13637
13633
  this._unknownOption.selected = true;
13638
13634
  this._unknownOption.setAttribute("selected", "selected");
13639
- this.$element.value = unknownVal;
13635
+ this._element.value = unknownVal;
13640
13636
  }
13641
13637
 
13642
13638
  /**
@@ -13644,7 +13640,7 @@
13644
13640
  * @param {*} val
13645
13641
  * @returns {string}
13646
13642
  */
13647
- generateUnknownOptionValue(val) {
13643
+ _generateUnknownOptionValue(val) {
13648
13644
  if (isUndefined(val)) {
13649
13645
  return `? undefined:undefined ?`;
13650
13646
  }
@@ -13655,27 +13651,27 @@
13655
13651
  /**
13656
13652
  * Remove the unknown option from the select element if it exists.
13657
13653
  */
13658
- removeUnknownOption() {
13654
+ _removeUnknownOption() {
13659
13655
  if (this._unknownOption.parentElement) this._unknownOption.remove();
13660
13656
  }
13661
13657
 
13662
13658
  /**
13663
13659
  * Select the empty option (value="") if it exists.
13664
13660
  */
13665
- selectEmptyOption() {
13666
- if (this.emptyOption) {
13667
- this.$element.value = "";
13668
- this.emptyOption.selected = true;
13669
- this.emptyOption.setAttribute("selected", "selected");
13661
+ _selectEmptyOption() {
13662
+ if (this._emptyOption) {
13663
+ this._element.value = "";
13664
+ this._emptyOption.selected = true;
13665
+ this._emptyOption.setAttribute("selected", "selected");
13670
13666
  }
13671
13667
  }
13672
13668
 
13673
13669
  /**
13674
13670
  * Unselect the empty option if present.
13675
13671
  */
13676
- unselectEmptyOption() {
13677
- if (this.hasEmptyOption) {
13678
- this.emptyOption.selected = false;
13672
+ _un_selectEmptyOption() {
13673
+ if (this._hasEmptyOption) {
13674
+ this._emptyOption.selected = false;
13679
13675
  }
13680
13676
  }
13681
13677
 
@@ -13683,40 +13679,41 @@
13683
13679
  * Read the current value from the select element.
13684
13680
  * @returns {*|null}
13685
13681
  */
13686
- readValue() {
13687
- const val = this.$element.value;
13682
+ _readValue() {
13683
+ const val = this._element.value;
13688
13684
 
13689
- const realVal = val in this.selectValueMap ? this.selectValueMap[val] : val;
13685
+ const realVal =
13686
+ val in this._selectValueMap ? this._selectValueMap[val] : val;
13690
13687
 
13691
- return this.hasOption(realVal) ? realVal : null;
13688
+ return this._hasOption(realVal) ? realVal : null;
13692
13689
  }
13693
13690
 
13694
13691
  /**
13695
13692
  * Write a value to the select control.
13696
13693
  * @param {*} value
13697
13694
  */
13698
- writeValue(value) {
13695
+ _writeValue(value) {
13699
13696
  const currentlySelectedOption =
13700
- this.$element.options[this.$element.selectedIndex];
13697
+ this._element.options[this._element.selectedIndex];
13701
13698
 
13702
13699
  if (currentlySelectedOption) currentlySelectedOption.selected = false;
13703
13700
 
13704
- if (this.hasOption(value)) {
13705
- this.removeUnknownOption();
13701
+ if (this._hasOption(value)) {
13702
+ this._removeUnknownOption();
13706
13703
 
13707
13704
  const hashedVal = hashKey(value);
13708
13705
 
13709
- this.$element.value =
13710
- hashedVal in this.selectValueMap ? hashedVal : value;
13711
- const selectedOption = this.$element.options[this.$element.selectedIndex];
13706
+ this._element.value =
13707
+ hashedVal in this._selectValueMap ? hashedVal : value;
13708
+ const selectedOption = this._element.options[this._element.selectedIndex];
13712
13709
 
13713
13710
  if (!selectedOption) {
13714
- this.selectUnknownOrEmptyOption(value);
13711
+ this._selectUnknownOrEmptyOption(value);
13715
13712
  } else {
13716
13713
  selectedOption.selected = true;
13717
13714
  }
13718
13715
  } else {
13719
- this.selectUnknownOrEmptyOption(value);
13716
+ this._selectUnknownOrEmptyOption(value);
13720
13717
  }
13721
13718
  }
13722
13719
 
@@ -13725,38 +13722,38 @@
13725
13722
  * @param {*} value
13726
13723
  * @param {HTMLOptionElement} element
13727
13724
  */
13728
- addOption(value, element) {
13725
+ _addOption(value, element) {
13729
13726
  if (element.nodeType === NodeType._COMMENT_NODE) return;
13730
13727
 
13731
13728
  assertNotHasOwnProperty(value, '"option value"');
13732
13729
 
13733
13730
  if (value === "") {
13734
- this.hasEmptyOption = true;
13735
- this.emptyOption = element;
13731
+ this._hasEmptyOption = true;
13732
+ this._emptyOption = element;
13736
13733
  }
13737
- const count = this.optionsMap.get(value) || 0;
13734
+ const count = this._optionsMap.get(value) || 0;
13738
13735
 
13739
- this.optionsMap.set(value, count + 1);
13740
- this.scheduleRender();
13736
+ this._optionsMap.set(value, count + 1);
13737
+ this._scheduleRender();
13741
13738
  }
13742
13739
 
13743
13740
  /**
13744
13741
  * Remove an option from the controller.
13745
13742
  * @param {*} value
13746
13743
  */
13747
- removeOption(value) {
13748
- const count = this.optionsMap.get(value);
13744
+ _removeOption(value) {
13745
+ const count = this._optionsMap.get(value);
13749
13746
 
13750
13747
  if (count) {
13751
13748
  if (count === 1) {
13752
- this.optionsMap.delete(value);
13749
+ this._optionsMap.delete(value);
13753
13750
 
13754
13751
  if (value === "") {
13755
- this.hasEmptyOption = false;
13756
- this.emptyOption = undefined;
13752
+ this._hasEmptyOption = false;
13753
+ this._emptyOption = undefined;
13757
13754
  }
13758
13755
  } else {
13759
- this.optionsMap.set(value, count - 1);
13756
+ this._optionsMap.set(value, count - 1);
13760
13757
  }
13761
13758
  }
13762
13759
  }
@@ -13766,22 +13763,22 @@
13766
13763
  * @param {*} value
13767
13764
  * @returns {boolean}
13768
13765
  */
13769
- hasOption(value) {
13770
- return !!this.optionsMap.get(value);
13766
+ _hasOption(value) {
13767
+ return !!this._optionsMap.get(value);
13771
13768
  }
13772
13769
 
13773
13770
  /**
13774
13771
  * @returns {boolean} Whether the select element currently has an empty option.
13775
13772
  */
13776
13773
  $hasEmptyOption() {
13777
- return this.hasEmptyOption;
13774
+ return this._hasEmptyOption;
13778
13775
  }
13779
13776
 
13780
13777
  /**
13781
13778
  * @returns {boolean} Whether the unknown option is currently selected.
13782
13779
  */
13783
13780
  $isUnknownOptionSelected() {
13784
- return this.$element.options[0] === this._unknownOption;
13781
+ return this._element.options[0] === this._unknownOption;
13785
13782
  }
13786
13783
 
13787
13784
  /**
@@ -13789,8 +13786,8 @@
13789
13786
  */
13790
13787
  $isEmptyOptionSelected() {
13791
13788
  return (
13792
- this.hasEmptyOption &&
13793
- this.$element.options[this.$element.selectedIndex] === this.emptyOption
13789
+ this._hasEmptyOption &&
13790
+ this._element.options[this._element.selectedIndex] === this._emptyOption
13794
13791
  );
13795
13792
  }
13796
13793
 
@@ -13798,26 +13795,26 @@
13798
13795
  * Select unknown or empty option depending on the value.
13799
13796
  * @param {*} value
13800
13797
  */
13801
- selectUnknownOrEmptyOption(value) {
13802
- if (isNullOrUndefined(value) && this.emptyOption) {
13803
- this.removeUnknownOption();
13804
- this.selectEmptyOption();
13798
+ _selectUnknownOrEmptyOption(value) {
13799
+ if (isNullOrUndefined(value) && this._emptyOption) {
13800
+ this._removeUnknownOption();
13801
+ this._selectEmptyOption();
13805
13802
  } else if (this._unknownOption.parentElement) {
13806
- this.updateUnknownOption(value);
13803
+ this._updateUnknownOption(value);
13807
13804
  } else {
13808
- this.renderUnknownOption(value);
13805
+ this._renderUnknownOption(value);
13809
13806
  }
13810
13807
  }
13811
13808
 
13812
13809
  /**
13813
13810
  * Schedule a render at the end of the digest cycle.
13814
13811
  */
13815
- scheduleRender() {
13816
- if (this.renderScheduled) return;
13817
- this.renderScheduled = true;
13818
- this.$scope.$postUpdate(() => {
13819
- this.renderScheduled = false;
13820
- this.ngModelCtrl.$render();
13812
+ _scheduleRender() {
13813
+ if (this._renderScheduled) return;
13814
+ this._renderScheduled = true;
13815
+ this._scope.$postUpdate(() => {
13816
+ this._renderScheduled = false;
13817
+ this._ngModelCtrl.$render();
13821
13818
  });
13822
13819
  }
13823
13820
 
@@ -13825,18 +13822,18 @@
13825
13822
  * Schedule a view value update at the end of the digest cycle.
13826
13823
  * @param {boolean} [renderAfter=false]
13827
13824
  */
13828
- scheduleViewValueUpdate(renderAfter = false) {
13829
- if (this.updateScheduled) return;
13825
+ _scheduleViewValueUpdate(renderAfter = false) {
13826
+ if (this._updateScheduled) return;
13830
13827
 
13831
- this.updateScheduled = true;
13828
+ this._updateScheduled = true;
13832
13829
 
13833
- this.$scope.$postUpdate(() => {
13834
- if (this.$scope.$$destroyed) return;
13830
+ this._scope.$postUpdate(() => {
13831
+ if (this._scope._destroyed) return;
13835
13832
 
13836
- this.updateScheduled = false;
13837
- this.ngModelCtrl.$setViewValue(this.readValue());
13833
+ this._updateScheduled = false;
13834
+ this._ngModelCtrl.$setViewValue(this._readValue());
13838
13835
 
13839
- if (renderAfter) this.ngModelCtrl.$render();
13836
+ if (renderAfter) this._ngModelCtrl.$render();
13840
13837
  });
13841
13838
  }
13842
13839
 
@@ -13866,37 +13863,37 @@
13866
13863
  const previouslySelected = optionElement.selected;
13867
13864
 
13868
13865
  if (isDefined(hashedVal)) {
13869
- this.removeOption(oldVal);
13870
- delete this.selectValueMap[hashedVal];
13866
+ this._removeOption(oldVal);
13867
+ delete this._selectValueMap[hashedVal];
13871
13868
  removal = true;
13872
13869
  }
13873
13870
 
13874
13871
  hashedVal = hashKey(newVal);
13875
13872
  oldVal = newVal;
13876
- this.selectValueMap[hashedVal] = newVal;
13877
- this.addOption(newVal, optionElement);
13873
+ this._selectValueMap[hashedVal] = newVal;
13874
+ this._addOption(newVal, optionElement);
13878
13875
  optionElement.setAttribute("value", hashedVal);
13879
13876
 
13880
13877
  if (removal && previouslySelected) {
13881
- this.scheduleViewValueUpdate();
13878
+ this._scheduleViewValueUpdate();
13882
13879
  }
13883
13880
  });
13884
13881
  } else if (interpolateValueFn) {
13885
13882
  optionAttrs.$observe("value", (newVal) => {
13886
- this.readValue();
13883
+ this._readValue();
13887
13884
  let removal;
13888
13885
 
13889
13886
  const previouslySelected = optionElement.selected;
13890
13887
 
13891
13888
  if (isDefined(oldVal)) {
13892
- this.removeOption(oldVal);
13889
+ this._removeOption(oldVal);
13893
13890
  removal = true;
13894
13891
  }
13895
13892
  oldVal = newVal;
13896
- this.addOption(newVal, optionElement);
13893
+ this._addOption(newVal, optionElement);
13897
13894
 
13898
13895
  if (removal && previouslySelected) {
13899
- this.scheduleViewValueUpdate();
13896
+ this._scheduleViewValueUpdate();
13900
13897
  }
13901
13898
  });
13902
13899
  } else if (interpolateTextFn) {
@@ -13904,7 +13901,7 @@
13904
13901
 
13905
13902
  if (!optionAttrs.value) {
13906
13903
  optionAttrs.$set("value", optionScope.value);
13907
- this.addOption(optionScope.value, optionElement);
13904
+ this._addOption(optionScope.value, optionElement);
13908
13905
  }
13909
13906
 
13910
13907
  optionScope.$watch("value", () => {
@@ -13916,45 +13913,45 @@
13916
13913
  const previouslySelected = optionElement.selected;
13917
13914
 
13918
13915
  if (oldVal !== newVal) {
13919
- this.removeOption(oldVal);
13916
+ this._removeOption(oldVal);
13920
13917
  oldVal = newVal;
13921
13918
  }
13922
- this.addOption(newVal, optionElement);
13919
+ this._addOption(newVal, optionElement);
13923
13920
 
13924
13921
  if (oldVal && previouslySelected) {
13925
- this.scheduleViewValueUpdate();
13922
+ this._scheduleViewValueUpdate();
13926
13923
  }
13927
13924
  });
13928
13925
  } else {
13929
- this.addOption(optionAttrs.value, optionElement);
13926
+ this._addOption(optionAttrs.value, optionElement);
13930
13927
  }
13931
13928
 
13932
13929
  optionAttrs.$observe("disabled", (newVal) => {
13933
13930
  if (newVal === "true" || (newVal && optionElement.selected)) {
13934
- if (this.multiple) {
13935
- this.scheduleViewValueUpdate(true);
13931
+ if (this._multiple) {
13932
+ this._scheduleViewValueUpdate(true);
13936
13933
  } else {
13937
- this.ngModelCtrl.$setViewValue(null);
13938
- this.ngModelCtrl.$render();
13934
+ this._ngModelCtrl.$setViewValue(null);
13935
+ this._ngModelCtrl.$render();
13939
13936
  }
13940
13937
  }
13941
13938
  });
13942
13939
 
13943
13940
  optionElement.addEventListener("$destroy", () => {
13944
- const currentValue = this.readValue();
13941
+ const currentValue = this._readValue();
13945
13942
 
13946
13943
  const removeValue = optionAttrs.value;
13947
13944
 
13948
- this.removeOption(removeValue);
13949
- this.scheduleRender();
13945
+ this._removeOption(removeValue);
13946
+ this._scheduleRender();
13950
13947
 
13951
13948
  if (
13952
- (this.multiple &&
13949
+ (this._multiple &&
13953
13950
  currentValue &&
13954
13951
  currentValue.indexOf(removeValue) !== -1) ||
13955
13952
  currentValue === removeValue
13956
13953
  ) {
13957
- this.scheduleViewValueUpdate(true);
13954
+ this._scheduleViewValueUpdate(true);
13958
13955
  }
13959
13956
  });
13960
13957
  }
@@ -13991,14 +13988,14 @@
13991
13988
 
13992
13989
  return;
13993
13990
  }
13994
- selectCtrl.ngModelCtrl = ngModelCtrl;
13991
+ selectCtrl._ngModelCtrl = ngModelCtrl;
13995
13992
 
13996
13993
  // When the selected item(s) changes we delegate getting the value of the select control
13997
- // to the `readValue` method, which can be changed if the select can have multiple
13994
+ // to the `_readValue` method, which can be changed if the select can have multiple
13998
13995
  // selected values or if the options are being generated by `ngOptions`
13999
13996
  element.addEventListener("change", () => {
14000
- selectCtrl.removeUnknownOption();
14001
- const viewValue = selectCtrl.readValue();
13997
+ selectCtrl._removeUnknownOption();
13998
+ const viewValue = selectCtrl._readValue();
14002
13999
 
14003
14000
  ngModelCtrl.$setViewValue(viewValue);
14004
14001
  });
@@ -14008,10 +14005,10 @@
14008
14005
  // we have to add an extra watch since ngModel doesn't work well with arrays - it
14009
14006
  // doesn't trigger rendering if only an item in the array changes.
14010
14007
  if (attr.multiple) {
14011
- selectCtrl.multiple = true;
14008
+ selectCtrl._multiple = true;
14012
14009
 
14013
14010
  // Read value now needs to check each option to see if it is selected
14014
- selectCtrl.readValue = function () {
14011
+ selectCtrl._readValue = function () {
14015
14012
  const array = [];
14016
14013
 
14017
14014
  /**
@@ -14028,8 +14025,8 @@
14028
14025
  const val = option.value;
14029
14026
 
14030
14027
  array.push(
14031
- val in selectCtrl.selectValueMap
14032
- ? selectCtrl.selectValueMap[val]
14028
+ val in selectCtrl._selectValueMap
14029
+ ? selectCtrl._selectValueMap[val]
14033
14030
  : val,
14034
14031
  );
14035
14032
  }
@@ -14040,7 +14037,7 @@
14040
14037
  };
14041
14038
 
14042
14039
  // Write value now needs to set the selected property of each matching option
14043
- selectCtrl.writeValue = function (value) {
14040
+ selectCtrl._writeValue = function (value) {
14044
14041
  /**
14045
14042
  * @type {HTMLCollection}
14046
14043
  */
@@ -14054,7 +14051,7 @@
14054
14051
  const shouldBeSelected =
14055
14052
  !!value &&
14056
14053
  (includes(value, option.value) ||
14057
- includes(value, selectCtrl.selectValueMap[option.value]));
14054
+ includes(value, selectCtrl._selectValueMap[option.value]));
14058
14055
 
14059
14056
  const currentlySelected = option.selected;
14060
14057
 
@@ -14103,13 +14100,13 @@
14103
14100
 
14104
14101
  const selectCtrl = ctrls[0];
14105
14102
 
14106
- // We delegate rendering to the `writeValue` method, which can be changed
14103
+ // We delegate rendering to the `_writeValue` method, which can be changed
14107
14104
  // if the select can have multiple selected values or if the options are being
14108
14105
  // generated by `ngOptions`.
14109
14106
  // This must be done in the postLink fn to prevent $render to be called before
14110
14107
  // all nodes have been linked correctly.
14111
14108
  ngModelCtrl.$render = function () {
14112
- selectCtrl.writeValue(ngModelCtrl.$viewValue);
14109
+ selectCtrl._writeValue(ngModelCtrl.$viewValue);
14113
14110
  };
14114
14111
  }
14115
14112
  }
@@ -15012,7 +15009,14 @@
15012
15009
  }
15013
15010
  });
15014
15011
 
15015
- return function ngRepeatLink($scope, $element, attr, ctrl, $transclude) {
15012
+ /**
15013
+ * @param {ng.Scope} $scope
15014
+ * @param {HTMLElement} $element
15015
+ * @param {ng.Attributes} attr
15016
+ * @param ctrl
15017
+ * @param $transclude
15018
+ */
15019
+ function ngRepeatLink($scope, $element, attr, ctrl, $transclude) {
15016
15020
  // Store a list of elements from previous run. This is a hash where key is the item from the
15017
15021
  // iterator, and the value is objects with following properties.
15018
15022
  // - scope: bound scope
@@ -15161,7 +15165,7 @@
15161
15165
  $transclude(
15162
15166
  /**
15163
15167
  * Clone attach function
15164
- * @param {Array<NodeList>} clone
15168
+ * @param {HTMLElement} clone
15165
15169
  * @param {ng.Scope} scope
15166
15170
  */
15167
15171
 
@@ -15172,11 +15176,9 @@
15172
15176
  if (hasAnimate) {
15173
15177
  $animate.enter(clone, null, previousNode);
15174
15178
  } else {
15175
- // @ts-ignore
15176
15179
  previousNode.after(clone);
15177
15180
  }
15178
15181
 
15179
- // @ts-ignore
15180
15182
  previousNode = endNode;
15181
15183
  // Note: We only need the first/last node of the cloned nodes.
15182
15184
  // However, we need to keep the reference to the dom wrapper as it might be changed later
@@ -15200,7 +15202,9 @@
15200
15202
  },
15201
15203
  isDefined(attr.lazy),
15202
15204
  );
15203
- };
15205
+ }
15206
+
15207
+ return ngRepeatLink;
15204
15208
  },
15205
15209
  };
15206
15210
  }
@@ -15646,11 +15650,11 @@
15646
15650
  const listFragment = document.createDocumentFragment();
15647
15651
 
15648
15652
  // Overwrite the implementation. ngOptions doesn't use hashes
15649
- selectCtrl.generateUnknownOptionValue = () => "?";
15653
+ selectCtrl._generateUnknownOptionValue = () => "?";
15650
15654
 
15651
15655
  // Update the controller methods for multiple selectable options
15652
15656
  if (!multiple) {
15653
- selectCtrl.writeValue = function writeNgOptionsValue(value) {
15657
+ selectCtrl._writeValue = function writeNgOptionsValue(value) {
15654
15658
  // The options might not be defined yet when ngModel tries to render
15655
15659
  if (!options) return;
15656
15660
 
@@ -15670,7 +15674,7 @@
15670
15674
  // set always
15671
15675
 
15672
15676
  if (selectElement.value !== option.selectValue) {
15673
- selectCtrl.removeUnknownOption();
15677
+ selectCtrl._removeUnknownOption();
15674
15678
 
15675
15679
  selectElement.value = option.selectValue;
15676
15680
  option.element.selected = true;
@@ -15678,16 +15682,16 @@
15678
15682
 
15679
15683
  option.element.setAttribute("selected", "selected");
15680
15684
  } else {
15681
- selectCtrl.selectUnknownOrEmptyOption(value);
15685
+ selectCtrl._selectUnknownOrEmptyOption(value);
15682
15686
  }
15683
15687
  };
15684
15688
 
15685
- selectCtrl.readValue = function readNgOptionsValue() {
15689
+ selectCtrl._readValue = function readNgOptionsValue() {
15686
15690
  const selectedOption = options.selectValueMap[selectElement.value];
15687
15691
 
15688
15692
  if (selectedOption && !selectedOption.disabled) {
15689
- selectCtrl.unselectEmptyOption();
15690
- selectCtrl.removeUnknownOption();
15693
+ selectCtrl._un_selectEmptyOption();
15694
+ selectCtrl._removeUnknownOption();
15691
15695
 
15692
15696
  return options.getViewValueFromOption(selectedOption);
15693
15697
  }
@@ -15704,7 +15708,7 @@
15704
15708
  });
15705
15709
  }
15706
15710
  } else {
15707
- selectCtrl.writeValue = function writeNgOptionsMultiple(values) {
15711
+ selectCtrl._writeValue = function writeNgOptionsMultiple(values) {
15708
15712
  // The options might not be defined yet when ngModel tries to render
15709
15713
  if (!options) return;
15710
15714
 
@@ -15720,18 +15724,22 @@
15720
15724
  });
15721
15725
  };
15722
15726
 
15723
- selectCtrl.readValue = function readNgOptionsMultiple() {
15724
- const selectedValues = selectElement.value || [];
15725
-
15727
+ selectCtrl._readValue = function readNgOptionsMultiple() {
15726
15728
  const selections = [];
15727
15729
 
15728
- // @ts-ignore
15729
- selectedValues.forEach((value) => {
15730
- const option = options.selectValueMap[value];
15730
+ const optionsEls = selectElement.options;
15731
15731
 
15732
- if (option && !option.disabled)
15733
- selections.push(options.getViewValueFromOption(option));
15734
- });
15732
+ for (let i = 0; i < optionsEls.length; i++) {
15733
+ const optionEl = optionsEls[i];
15734
+
15735
+ if (optionEl.selected) {
15736
+ const option = options.selectValueMap[optionEl.value];
15737
+
15738
+ if (option && !option.disabled) {
15739
+ selections.push(options.getViewValueFromOption(option));
15740
+ }
15741
+ }
15742
+ }
15735
15743
 
15736
15744
  return selections;
15737
15745
  };
@@ -15795,18 +15803,19 @@
15795
15803
  // watchables.forEach((i) => {
15796
15804
  // scope.$watch(i, updateOptions);
15797
15805
  // });
15798
- scope.$watch(
15806
+ const prop = /** @type {string} */ (
15799
15807
  /** @type {import('../../core/parse/ast/ast-node.ts').LiteralNode} */ (
15800
15808
  /** @type {import('../../core/parse/ast/ast-node.ts').ExpressionNode} */ (
15801
15809
  ngOptions.getWatchables._decoratedNode.body[0]
15802
15810
  ).expression
15803
- ).name,
15804
- updateOptions,
15811
+ )?.name
15805
15812
  );
15806
15813
 
15814
+ scope.$watch(prop, updateOptions);
15815
+
15807
15816
  // ------------------------------------------------------------------ //
15808
15817
 
15809
- function addOptionElement(option, parent) {
15818
+ function _addOptionElement(option, parent) {
15810
15819
  /**
15811
15820
  * @type {HTMLOptionElement}
15812
15821
  */
@@ -15846,7 +15855,7 @@
15846
15855
  }
15847
15856
 
15848
15857
  function updateOptions() {
15849
- const previousValue = options && selectCtrl.readValue();
15858
+ const previousValue = options && selectCtrl._readValue();
15850
15859
 
15851
15860
  // We must remove all current options, but cannot simply set innerHTML = null
15852
15861
  // since the providedEmptyOption might have an ngIf on it that inserts comments which we
@@ -15891,10 +15900,10 @@
15891
15900
  groupElementMap[option.group] = groupElement;
15892
15901
  }
15893
15902
 
15894
- addOptionElement(option, groupElement);
15903
+ _addOptionElement(option, groupElement);
15895
15904
  } else {
15896
15905
  // This option is not in a group
15897
- addOptionElement(option, listFragment);
15906
+ _addOptionElement(option, listFragment);
15898
15907
  }
15899
15908
  });
15900
15909
 
@@ -15904,7 +15913,7 @@
15904
15913
 
15905
15914
  // Check to see if the value has changed due to the update to the options
15906
15915
  if (!ngModelCtrl.$isEmpty(previousValue)) {
15907
- const nextValue = selectCtrl.readValue();
15916
+ const nextValue = selectCtrl._readValue();
15908
15917
 
15909
15918
  const isNotPrimitive = ngOptions.trackBy || multiple;
15910
15919
 
@@ -16036,7 +16045,6 @@
16036
16045
  $scope,
16037
16046
 
16038
16047
  (clone) => {
16039
- // @ts-ignore
16040
16048
  $element.append(clone);
16041
16049
  },
16042
16050
  );
@@ -16073,6 +16081,11 @@
16073
16081
  // binding to multiple is not supported
16074
16082
  if (i === "multiple") return;
16075
16083
 
16084
+ /**
16085
+ * @param {ng.Scope} scope
16086
+ * @param {Element} _element
16087
+ * @param {ng.Attributes} attr
16088
+ */
16076
16089
  function defaultLinkFn(scope, _element, attr) {
16077
16090
  scope.$watch(attr[normalized], (value) => {
16078
16091
  attr.$set(i, !!value);
@@ -16736,7 +16749,7 @@
16736
16749
  });
16737
16750
 
16738
16751
  animateOptions.domOperation = function () {
16739
- animateOptions.$$domOperationFired = true;
16752
+ animateOptions._domOperationFired = true;
16740
16753
  domOperation();
16741
16754
  domOperation = () => {
16742
16755
  /* empty */
@@ -17557,8 +17570,6 @@
17557
17570
  anyPropertyKey = anyPropertyKey || "$";
17558
17571
  let predicateFn;
17559
17572
 
17560
- let matchAgainstAnyProp = false;
17561
-
17562
17573
  switch (getTypeForFilter(expression)) {
17563
17574
  case "function":
17564
17575
  predicateFn = expression;
@@ -17567,38 +17578,78 @@
17567
17578
  case "null":
17568
17579
  case "number":
17569
17580
  case "string":
17570
- matchAgainstAnyProp = true;
17571
- // falls through
17581
+ predicateFn = createPredicateFn(
17582
+ expression,
17583
+ comparator,
17584
+ anyPropertyKey,
17585
+ true,
17586
+ );
17587
+ break;
17588
+
17572
17589
  case "object":
17573
17590
  predicateFn = createPredicateFn(
17574
17591
  expression,
17575
17592
  comparator,
17576
17593
  anyPropertyKey,
17577
- matchAgainstAnyProp,
17594
+ false,
17578
17595
  );
17579
17596
  break;
17597
+
17580
17598
  default:
17581
17599
  return array;
17582
17600
  }
17583
17601
 
17584
- return Array.prototype.filter.call(array, predicateFn);
17602
+ return Array.from(array).filter(
17603
+ /** @type {(item: any) => boolean} */ (predicateFn),
17604
+ );
17585
17605
  };
17586
17606
  }
17587
17607
 
17588
17608
  // Helper functions for `filterFilter`
17609
+ /**
17610
+ * Creates a predicate function that can be used with `Array.prototype.filter`
17611
+ * to match items against a given filter expression.
17612
+ *
17613
+ * @param {string | Object & Record<string, any> | null} expression
17614
+ * The filter expression to match items against. Can be:
17615
+ * - `string`: matched as a case-insensitive substring
17616
+ * - `object`: matched by property values (supports special `anyPropertyKey`)
17617
+ * - `null`: treated as a literal match
17618
+ *
17619
+ * @param {boolean | ((actual: any, expected: any) => boolean)} [comparator=false]
17620
+ * Comparator to determine equality between actual array values and expected values:
17621
+ * - `true` → uses strict equality (angular.equals)
17622
+ * - `false` (default) → performs case-insensitive substring match for primitives
17623
+ * - `function(actual, expected)` → custom comparator returning boolean
17624
+ *
17625
+ * @param {string} [anyPropertyKey="$"]
17626
+ * Special property key that allows matching against any property of an object.
17627
+ * Defaults to `$`.
17628
+ *
17629
+ * @param {boolean} [matchAgainstAnyProp=false]
17630
+ * If true, allows matching against any property in the object.
17631
+ * Typically true when filtering with primitive expressions.
17632
+ *
17633
+ * @returns {(item: any) => boolean}
17634
+ * Predicate function that returns `true` if `item` matches the expression.
17635
+ */
17589
17636
  function createPredicateFn(
17590
17637
  expression,
17591
17638
  comparator,
17592
17639
  anyPropertyKey,
17593
17640
  matchAgainstAnyProp,
17594
17641
  ) {
17642
+ anyPropertyKey = anyPropertyKey ?? "$";
17595
17643
  const shouldMatchPrimitives =
17596
17644
  isObject(expression) && anyPropertyKey in expression;
17597
17645
 
17598
17646
  if (comparator === true) {
17599
17647
  comparator = equals$1;
17600
17648
  } else if (!isFunction(comparator)) {
17601
- comparator = function (actual, expected) {
17649
+ comparator = function (
17650
+ /** @type {string | any[] | null} */ actual,
17651
+ /** @type {string | null} */ expected,
17652
+ ) {
17602
17653
  if (isUndefined(actual)) {
17603
17654
  // No substring matching against `undefined`
17604
17655
  return false;
@@ -17624,7 +17675,7 @@
17624
17675
  };
17625
17676
  }
17626
17677
 
17627
- const predicateFn = function (item) {
17678
+ const predicateFn = function (/** @type {string | Object | null} */ item) {
17628
17679
  if (shouldMatchPrimitives && !isObject(item)) {
17629
17680
  return deepCompare(
17630
17681
  item,
@@ -17640,13 +17691,22 @@
17640
17691
  expression,
17641
17692
  comparator,
17642
17693
  anyPropertyKey,
17643
- matchAgainstAnyProp,
17694
+ !!matchAgainstAnyProp, // coerce undefined → false
17644
17695
  );
17645
17696
  };
17646
17697
 
17647
17698
  return predicateFn;
17648
17699
  }
17649
17700
 
17701
+ /**
17702
+ * @param {string | Object | null} actual
17703
+ * @param {string | Object | null} expected
17704
+ * @param {(arg0: any, arg1: any) => any} comparator
17705
+ * @param {string} anyPropertyKey
17706
+ * @param {boolean} matchAgainstAnyProp
17707
+ * @param {boolean | undefined} [dontMatchWholeObject]
17708
+ * @returns {boolean}
17709
+ */
17650
17710
  function deepCompare(
17651
17711
  actual,
17652
17712
  expected,
@@ -17659,10 +17719,13 @@
17659
17719
 
17660
17720
  const expectedType = getTypeForFilter(expected);
17661
17721
 
17662
- if (expectedType === "string" && expected.charAt(0) === "!") {
17722
+ if (
17723
+ expectedType === "string" &&
17724
+ /** @type {string} */ (expected).charAt(0) === "!"
17725
+ ) {
17663
17726
  return !deepCompare(
17664
17727
  actual,
17665
- expected.substring(1),
17728
+ /** @type {string} */ (expected).substring(1),
17666
17729
  comparator,
17667
17730
  anyPropertyKey,
17668
17731
  matchAgainstAnyProp,
@@ -17686,13 +17749,19 @@
17686
17749
  switch (actualType) {
17687
17750
  case "object":
17688
17751
  if (matchAgainstAnyProp) {
17689
- for (const key in actual) {
17752
+ for (const key in /** @type {Record<string, any>} */ (actual)) {
17690
17753
  // Under certain, rare, circumstances, key may not be a string and `charAt` will be undefined
17691
17754
  // See: https://github.com/angular/angular.js/issues/15644
17692
17755
  if (
17693
17756
  key.charAt &&
17694
17757
  key.charAt(0) !== "$" &&
17695
- deepCompare(actual[key], expected, comparator, anyPropertyKey, true)
17758
+ deepCompare(
17759
+ /** @type {Record<string, any>} */ (actual)[key],
17760
+ expected,
17761
+ comparator,
17762
+ anyPropertyKey,
17763
+ true,
17764
+ )
17696
17765
  ) {
17697
17766
  return true;
17698
17767
  }
@@ -17704,8 +17773,10 @@
17704
17773
  }
17705
17774
 
17706
17775
  if (expectedType === "object") {
17707
- for (const key in expected) {
17708
- const expectedVal = expected[key];
17776
+ for (const key in /** @type {Record<string, any>} */ (expected)) {
17777
+ const expectedVal = /** @type {Record<string, any>} */ (expected)[
17778
+ key
17779
+ ];
17709
17780
 
17710
17781
  if (isFunction(expectedVal) || isUndefined(expectedVal)) {
17711
17782
  continue;
@@ -17713,7 +17784,9 @@
17713
17784
 
17714
17785
  const matchAnyProperty = key === anyPropertyKey;
17715
17786
 
17716
- const actualVal = matchAnyProperty ? actual : actual[key];
17787
+ const actualVal = matchAnyProperty
17788
+ ? actual
17789
+ : /** @type {Record<string, any>} */ (actual)[key];
17717
17790
 
17718
17791
  if (
17719
17792
  !deepCompare(
@@ -17742,6 +17815,10 @@
17742
17815
  }
17743
17816
 
17744
17817
  // Used for easily differentiating between `null` and actual `object`
17818
+ /**
17819
+ * @param {string | Object | null} val
17820
+ * @return {string}
17821
+ */
17745
17822
  function getTypeForFilter(val) {
17746
17823
  return val === null ? "null" : typeof val;
17747
17824
  }
@@ -17764,9 +17841,21 @@
17764
17841
  */
17765
17842
  function limitToFilter() {
17766
17843
  /**
17767
- * @param {Array|ArrayLike|string|number|Function} input Array/array-like, string, or number to be limited.
17768
- * @param {string|number} limit The length of the returned array or string.
17769
- * @param {string|number} [begin] Index at which to begin limitation. As a negative index, `begin` indicates an offset from the end of `input`. Defaults to `0`.
17844
+ * Limits the size of an array, array-like object, string, or number.
17845
+ *
17846
+ * - If `input` is a function, it will be invoked and its return value used.
17847
+ * - If `input` is a number, it will be converted to a string.
17848
+ * - Non–array-like values are returned unchanged.
17849
+ *
17850
+ * @param {Array<any>|ArrayLike<any>|string|number} input
17851
+ * The value to limit.
17852
+ * @param {string|number} limit
17853
+ * The maximum length of the returned value. Negative values limit from the end.
17854
+ * @param {string|number} [begin]
17855
+ * Index at which to begin the limitation. A negative value is an offset from the end.
17856
+ * Defaults to `0`.
17857
+ * @returns {Array<any>|ArrayLike<any>|string|number}
17858
+ * A limited array or string, or the original input if it cannot be limited.
17770
17859
  */
17771
17860
  return function (input, limit, begin) {
17772
17861
  if (isFunction(input)) {
@@ -17804,12 +17893,34 @@
17804
17893
  };
17805
17894
  }
17806
17895
 
17896
+ /**
17897
+ * Returns a shallow copy of a portion of an array-like or string.
17898
+ *
17899
+ * - For strings, this delegates to `String.prototype.slice`
17900
+ * - For array-like objects, this delegates to `Array.prototype.slice`
17901
+ *
17902
+ * @param {string|ArrayLike<any>} input
17903
+ * The value to slice. Must be a string or array-like object.
17904
+ * @param {number} [begin]
17905
+ * Zero-based index at which to begin extraction.
17906
+ * @param {number} [end]
17907
+ * Zero-based index before which to end extraction.
17908
+ * @returns {string|Array<any>}
17909
+ * A sliced string if input is a string, otherwise an array.
17910
+ */
17807
17911
  function sliceFn(input, begin, end) {
17808
17912
  if (isString(input)) return input.slice(begin, end);
17809
17913
 
17810
17914
  return [].slice.call(input, begin, end);
17811
17915
  }
17812
17916
 
17917
+ /**
17918
+ * @typedef {Object} ComparisonObject
17919
+ * @property {*} value
17920
+ * @property {{ value: number, type: string, index: number }} tieBreaker
17921
+ * @property {Array<{ value: any, type: string, index: number }>} predicateValues
17922
+ */
17923
+
17813
17924
  orderByFilter.$inject = [$injectTokens._parse];
17814
17925
 
17815
17926
  /**
@@ -17817,6 +17928,32 @@
17817
17928
  * @returns {ng.FilterFn}
17818
17929
  */
17819
17930
  function orderByFilter($parse) {
17931
+ /**
17932
+ * Sorts an array or array-like collection based on one or more predicates.
17933
+ *
17934
+ * The collection can be:
17935
+ * - An array
17936
+ * - An array-like object
17937
+ * - A function returning an array
17938
+ *
17939
+ * Predicates can be:
17940
+ * - Property names (strings)
17941
+ * - Getter functions
17942
+ * - Strings with "+" or "-" prefix to indicate ascending/descending order
17943
+ *
17944
+ * @param {Array<any>|ArrayLike<any>|Function} array
17945
+ * The collection to be sorted.
17946
+ * @param {string|Function|Array<string|Function>} [sortPredicate]
17947
+ * A single predicate or array of predicates used for sorting.
17948
+ * @param {boolean} [reverseOrder=false]
17949
+ * If true, reverses the sort order.
17950
+ * @param {Function} [compareFn]
17951
+ * Optional comparator function. Defaults to a type-aware comparison function.
17952
+ * @returns {Array<any>|ArrayLike<any>}
17953
+ * A new array containing the sorted values.
17954
+ *
17955
+ * @throws {Error} Throws if `array` is not array-like.
17956
+ */
17820
17957
  return function (array, sortPredicate, reverseOrder, compareFn) {
17821
17958
  if (isNullOrUndefined(array)) return array;
17822
17959
 
@@ -17831,7 +17968,7 @@
17831
17968
  }
17832
17969
 
17833
17970
  if (!isArray(sortPredicate)) {
17834
- sortPredicate = [sortPredicate];
17971
+ sortPredicate = [sortPredicate ?? "+"]; // if undefined, default to "+"
17835
17972
  }
17836
17973
 
17837
17974
  if (sortPredicate.length === 0) {
@@ -17848,13 +17985,31 @@
17848
17985
  // The next three lines are a version of a Swartzian Transform idiom from Perl
17849
17986
  // (sometimes called the Decorate-Sort-Undecorate idiom)
17850
17987
  // See https://en.wikipedia.org/wiki/Schwartzian_transform
17851
- const compareValues = Array.prototype.map.call(array, getComparisonObject);
17988
+ const compareValues = /** @type {ComparisonObject[]} */ (
17989
+ Array.prototype.map.call(array, getComparisonObject)
17990
+ );
17852
17991
 
17853
17992
  compareValues.sort(doComparison);
17854
17993
  array = compareValues.map((item) => item.value);
17855
17994
 
17856
17995
  return array;
17857
17996
 
17997
+ /**
17998
+ * Creates a comparison object for a given value in the array.
17999
+ * This object is used to perform stable sorting with multiple predicates.
18000
+ *
18001
+ * @param {*} value - The value from the array to wrap for comparison.
18002
+ * @param {number} index - The index of the value in the original array.
18003
+ * @returns {{
18004
+ * value: *,
18005
+ * tieBreaker: { value: number, type: string, index: number },
18006
+ * predicateValues: Array<{ value: *, type: string, index: number }>
18007
+ * }}
18008
+ * An object containing:
18009
+ * - `value`: the original value,
18010
+ * - `tieBreaker`: a stable sort fallback using the original index,
18011
+ * - `predicateValues`: an array of values derived from each sort predicate.
18012
+ */
17858
18013
  function getComparisonObject(value, index) {
17859
18014
  // NOTE: We are adding an extra `tieBreaker` value based on the element's index.
17860
18015
  // This will be used to keep the sort stable when none of the input predicates can
@@ -17868,6 +18023,20 @@
17868
18023
  };
17869
18024
  }
17870
18025
 
18026
+ /**
18027
+ * Comparator used to sort decorated collection items.
18028
+ *
18029
+ * Iterates over all sort predicates and compares their corresponding
18030
+ * predicate values. The first non-zero comparison result determines
18031
+ * the ordering.
18032
+ *
18033
+ * If all predicate comparisons are equal, a tie-breaker based on the
18034
+ * original index is used to guarantee a stable sort.
18035
+ *
18036
+ * @param {ComparisonObject} v1 First decorated comparison object
18037
+ * @param {ComparisonObject} v2 Second decorated comparison object
18038
+ * @returns {number} -1 if v1 < v2, 1 if v1 > v2, 0 if equivalent
18039
+ */
17871
18040
  function doComparison(v1, v2) {
17872
18041
  for (let i = 0, ii = predicates.length; i < ii; i++) {
17873
18042
  const result = compare(v1.predicateValues[i], v2.predicateValues[i]);
@@ -17884,14 +18053,31 @@
17884
18053
  }
17885
18054
  };
17886
18055
 
18056
+ /**
18057
+ * Processes an array of sort predicates into getter functions and sort directions.
18058
+ *
18059
+ * Each predicate can be:
18060
+ * - A function: used directly to extract values for comparison.
18061
+ * - A string starting with `+` or `-` to indicate ascending or descending order.
18062
+ * The remainder of the string is interpreted as a property path.
18063
+ *
18064
+ * @param {(string|Function)[]} sortPredicates - Array of predicates to process. Each predicate
18065
+ * can be a string (property name, optionally prefixed with "+" or "-") or a function.
18066
+ * @return {Array<{get: Function, descending: number}>} Array of objects, each containing:
18067
+ * - `get`: Function to extract the value from an item.
18068
+ * - `descending`: `1` for ascending, `-1` for descending.
18069
+ */
17887
18070
  function processPredicates(sortPredicates) {
17888
18071
  return sortPredicates.map((predicate) => {
17889
18072
  let descending = 1;
17890
18073
 
18074
+ /**
18075
+ * @type {function(*): *}
18076
+ */
17891
18077
  let get = (x) => x;
17892
18078
 
17893
18079
  if (isFunction(predicate)) {
17894
- get = predicate;
18080
+ get = /** @type {function(*): *} */ (predicate);
17895
18081
  } else if (isString(predicate)) {
17896
18082
  if (predicate.charAt(0) === "+" || predicate.charAt(0) === "-") {
17897
18083
  descending = predicate.charAt(0) === "-" ? -1 : 1;
@@ -17904,7 +18090,8 @@
17904
18090
  if (parsed.constant) {
17905
18091
  const key = parsed();
17906
18092
 
17907
- get = (value) => value[key];
18093
+ get = /** @type {Record<string, any>} value */ (value) =>
18094
+ value[key];
17908
18095
  } else {
17909
18096
  get = parsed;
17910
18097
  }
@@ -17915,6 +18102,10 @@
17915
18102
  });
17916
18103
  }
17917
18104
 
18105
+ /**
18106
+ * @param {any} value
18107
+ * @return {boolean}
18108
+ */
17918
18109
  function isPrimitive(value) {
17919
18110
  switch (typeof value) {
17920
18111
  case "number": /* falls through */
@@ -17926,6 +18117,16 @@
17926
18117
  }
17927
18118
  }
17928
18119
 
18120
+ /**
18121
+ * Converts an object to a primitive value for comparison purposes.
18122
+ *
18123
+ * - If the object has a valid `valueOf()` method that returns a primitive, it uses that.
18124
+ * - Otherwise, if the object has a custom `toString()` method, it uses that.
18125
+ * - If neither yields a primitive, returns the original object.
18126
+ *
18127
+ * @param {*} value - The object to convert.
18128
+ * @returns {*} The primitive representation of the object if possible; otherwise, the original object.
18129
+ */
17929
18130
  function objectValue(value) {
17930
18131
  // If `valueOf` is a valid function use that
17931
18132
  if (isFunction(value.valueOf)) {
@@ -17944,6 +18145,22 @@
17944
18145
  return value;
17945
18146
  }
17946
18147
 
18148
+ /**
18149
+ * Normalizes a value for sorting by determining its type and
18150
+ * converting objects to primitive representations when possible.
18151
+ *
18152
+ * @param {*} value - The value to normalize for comparison.
18153
+ * @param {number} index - The original index of the value in the array.
18154
+ * @returns {{
18155
+ * value: *,
18156
+ * type: string,
18157
+ * index: number
18158
+ * }}
18159
+ * An object containing:
18160
+ * - `value`: the normalized value (primitive if possible),
18161
+ * - `type`: a string representing the type of the value (`number`, `string`, `boolean`, `null`, etc.),
18162
+ * - `index`: the original index to maintain stable sorting.
18163
+ */
17947
18164
  function getPredicateValue(value, index) {
17948
18165
  /** @type {String} */ let type = typeof value;
17949
18166
 
@@ -17956,6 +18173,23 @@
17956
18173
  return { value, type, index };
17957
18174
  }
17958
18175
 
18176
+ /**
18177
+ * Default comparison function used by the `orderBy` filter.
18178
+ *
18179
+ * Compares two wrapped predicate values and returns a sort order indicator.
18180
+ * Comparison rules:
18181
+ * - Values of the same type are compared directly
18182
+ * - Strings are compared case-insensitively
18183
+ * - Objects fall back to their original index to preserve stability
18184
+ * - `undefined` and `null` are ordered last
18185
+ *
18186
+ * @param {{ value: any, type: string, index: number }} v1
18187
+ * First comparison object.
18188
+ * @param {{ value: any, type: string, index: number }} v2
18189
+ * Second comparison object.
18190
+ * @returns {number}
18191
+ * Returns `-1` if `v1 < v2`, `1` if `v1 > v2`, or `0` if equal.
18192
+ */
17959
18193
  function defaultCompare(v1, v2) {
17960
18194
  let result = 0;
17961
18195
 
@@ -18060,6 +18294,9 @@
18060
18294
 
18061
18295
  const $interpolateMinErr = minErr("$interpolate");
18062
18296
 
18297
+ /**
18298
+ * @param {string} text
18299
+ */
18063
18300
  function throwNoconcat(text) {
18064
18301
  throw $interpolateMinErr(
18065
18302
  "noconcat",
@@ -18070,6 +18307,10 @@
18070
18307
  );
18071
18308
  }
18072
18309
 
18310
+ /**
18311
+ * @param {string} text
18312
+ * @param {Error} err
18313
+ */
18073
18314
  function interr(text, err) {
18074
18315
  throw $interpolateMinErr(
18075
18316
  "interr",
@@ -18117,9 +18358,9 @@
18117
18358
  /** @type {InterpolateProvider} */
18118
18359
  const provider = this;
18119
18360
 
18120
- const startSymbolLength = provider.startSymbol.length;
18361
+ const startSymbolLength = this.startSymbol.length;
18121
18362
 
18122
- const endSymbolLength = provider.endSymbol.length;
18363
+ const endSymbolLength = this.endSymbol.length;
18123
18364
 
18124
18365
  const escapedStartRegexp = new RegExp(
18125
18366
  provider.startSymbol.replace(/./g, escape),
@@ -18131,10 +18372,16 @@
18131
18372
  "g",
18132
18373
  );
18133
18374
 
18375
+ /**
18376
+ * @param {any} ch
18377
+ */
18134
18378
  function escape(ch) {
18135
18379
  return `\\\\\\${ch}`;
18136
18380
  }
18137
18381
 
18382
+ /**
18383
+ * @param {string} text
18384
+ */
18138
18385
  function unescapeText(text) {
18139
18386
  return text
18140
18387
  .replace(escapedStartRegexp, provider.startSymbol)
@@ -18246,7 +18493,7 @@
18246
18493
  * provides Strict Contextual Escaping for details.
18247
18494
  * @param {boolean=} allOrNothing if `true`, then the returned function returns undefined
18248
18495
  * unless all embedded expressions evaluate to a value other than `undefined`.
18249
- * @returns {Function} an interpolation function which is used to compute the
18496
+ * @returns {import("./interface.js").InterpolationFunction | undefined} an interpolation function which is used to compute the
18250
18497
  * interpolated string. The function has these parameters:
18251
18498
  *
18252
18499
  * - `context`: evaluation context for all expressions embedded in the interpolated text
@@ -18288,14 +18535,23 @@
18288
18535
 
18289
18536
  let index = 0;
18290
18537
 
18538
+ /**
18539
+ * @type {string[]}
18540
+ */
18291
18541
  const expressions = [];
18292
18542
 
18293
18543
  const textLength = text.length;
18294
18544
 
18295
18545
  let exp;
18296
18546
 
18547
+ /**
18548
+ * @type {any[]}
18549
+ */
18297
18550
  const concat = [];
18298
18551
 
18552
+ /**
18553
+ * @type {number[]}
18554
+ */
18299
18555
  const expressionPositions = [];
18300
18556
 
18301
18557
  while (index < textLength) {
@@ -18350,7 +18606,7 @@
18350
18606
  // only used in srcdoc attributes, this would not be very useful.
18351
18607
 
18352
18608
  if (!mustHaveExpression || expressions.length) {
18353
- const compute = function (values) {
18609
+ const compute = function (/** @type {any[]} */ values) {
18354
18610
  for (let i = 0, ii = expressions.length; i < ii; i++) {
18355
18611
  if (allOrNothing && isUndefined(values[i])) return undefined;
18356
18612
  concat[expressionPositions[i]] = values[i];
@@ -18373,68 +18629,54 @@
18373
18629
  return concat.join("");
18374
18630
  };
18375
18631
 
18376
- return /**@type {import("./interface.ts").InterpolationFunction} */ extend(
18377
- (context, cb) => {
18378
- let i = 0;
18632
+ /**
18633
+ * @type {import("./interface.ts").InterpolationFunction}
18634
+ */
18635
+ const fn = (
18636
+ /** @type {ng.Scope} */ context,
18637
+ /** @type {(val: any) => void=} */ cb,
18638
+ ) => {
18639
+ const ii = expressions.length;
18379
18640
 
18380
- const ii = expressions.length;
18641
+ const values = new Array(ii);
18381
18642
 
18382
- const values = new Array(ii);
18643
+ try {
18644
+ for (let i = 0; i < ii; i++) {
18645
+ if (cb) {
18646
+ const watchProp = expressions[i].trim();
18383
18647
 
18384
- try {
18385
- for (; i < ii; i++) {
18386
- if (cb) {
18387
- const watchProp = expressions[i].trim();
18648
+ context.$watch(watchProp, () => {
18649
+ const vals = new Array(ii);
18388
18650
 
18389
- context.$watch(watchProp, () => {
18390
- const vals = new Array(ii);
18651
+ for (let j = 0; j < ii; j++) {
18652
+ vals[j] = parseFns[j](context);
18653
+ }
18391
18654
 
18392
- let j = 0;
18655
+ cb(compute(vals));
18656
+ });
18657
+ }
18393
18658
 
18394
- for (; j < ii; j++) {
18395
- const fn = parseFns[j];
18659
+ values[i] = parseFns[i](context);
18660
+ }
18396
18661
 
18397
- vals[j] = fn(context);
18398
- }
18399
- cb(compute(vals));
18400
- });
18401
- }
18662
+ return compute(values);
18663
+ } catch (err) {
18664
+ return interr(text, /** @type {Error} */ (err));
18665
+ }
18666
+ };
18402
18667
 
18403
- values[i] = parseFns[i](context);
18404
- }
18668
+ // Attach required properties so TS sees them
18669
+ /** @type {string} */
18670
+ fn.exp = text;
18671
+ /** @type {any[]} */
18672
+ fn.expressions = expressions;
18405
18673
 
18406
- return compute(values);
18407
- } catch (err) {
18408
- return interr(text, err);
18409
- }
18410
- },
18411
- {
18412
- // Most likely we would need to register watches during interpolation
18413
- // all of these properties are undocumented for now
18414
- exp: text, // just for compatibility with regular watchers created via $watch
18415
- expressions,
18416
- _watchDelegate(scope, listener) {
18417
- let lastValue;
18418
-
18419
- return scope.$watch(
18420
- parseFns,
18421
- function interpolateFnWatcher(values, oldValues) {
18422
- const currValue = compute(values);
18423
-
18424
- listener.call(
18425
- provider,
18426
- currValue,
18427
- values !== oldValues ? lastValue : currValue,
18428
- scope,
18429
- );
18430
- lastValue = currValue;
18431
- },
18432
- );
18433
- },
18434
- },
18435
- );
18674
+ return fn;
18436
18675
  }
18437
18676
 
18677
+ /**
18678
+ * @param {string} value
18679
+ */
18438
18680
  function parseStringifyInterceptor(value) {
18439
18681
  try {
18440
18682
  // In concatenable contexts, getTrusted comes at the end, to avoid sanitizing individual
@@ -18448,7 +18690,7 @@
18448
18690
 
18449
18691
  return allOrNothing && !isDefined(value) ? value : stringify$1(value);
18450
18692
  } catch (err) {
18451
- return interr(text, err);
18693
+ return interr(text, /** @type {Error} */ (err));
18452
18694
  }
18453
18695
  }
18454
18696
 
@@ -18479,7 +18721,6 @@
18479
18721
  return provider.endSymbol;
18480
18722
  };
18481
18723
 
18482
- // @ts-ignore
18483
18724
  return $interpolate;
18484
18725
  },
18485
18726
  ];
@@ -18499,7 +18740,7 @@
18499
18740
  let _path;
18500
18741
 
18501
18742
  /**
18502
- * @type {Object.<string,boolean|Array<any>>}
18743
+ * @type {Object.<string, string|number|boolean|Array<string|number|boolean>>}
18503
18744
  */
18504
18745
  let _search;
18505
18746
 
@@ -18663,7 +18904,6 @@
18663
18904
  if (isUndefined(paramValue) || paramValue === null) {
18664
18905
  delete _search[search];
18665
18906
  } else {
18666
- // @ts-ignore
18667
18907
  _search[search] = paramValue;
18668
18908
  }
18669
18909
  }
@@ -19093,12 +19333,12 @@
19093
19333
  ) {
19094
19334
  return;
19095
19335
  }
19096
- let elm = /** @type {HTMLAnchorElement} */ (event.target);
19336
+ let elm = /** @type {HTMLElement} */ (event.target);
19097
19337
 
19098
19338
  // traverse the DOM up to find first A tag
19099
19339
  while (elm.nodeName.toLowerCase() !== "a") {
19100
19340
  // ignore rewriting if no A tag (reached root element, or no parent - removed from document)
19101
- // @ts-ignore
19341
+
19102
19342
  if (elm === $rootElement || !(elm = elm.parentElement)) return;
19103
19343
  }
19104
19344
 
@@ -19109,7 +19349,7 @@
19109
19349
  return;
19110
19350
  }
19111
19351
 
19112
- let absHref = elm.href;
19352
+ let absHref = /** @type {HTMLAnchorElement} */ (elm).href;
19113
19353
 
19114
19354
  // get the actual href attribute - see
19115
19355
  // http://msdn.microsoft.com/en-us/library/ie/dd347148(v=vs.85).aspx
@@ -20025,7 +20265,6 @@
20025
20265
 
20026
20266
  const { body } = /** @type {BodyNode} */ (decoratedNode);
20027
20267
 
20028
- /** @type {ASTNode} */
20029
20268
  const assignable = assignableAST(/** @type {BodyNode} */ (decoratedNode));
20030
20269
 
20031
20270
  /** @type {import("./interface.ts").CompiledExpression} */
@@ -20066,27 +20305,25 @@
20066
20305
  },
20067
20306
  );
20068
20307
 
20069
- /** @type {import("./interface.ts").CompiledExpression} */
20070
- // @ts-ignore
20071
- const fn =
20308
+ const fnRaw =
20072
20309
  body.length === 0
20073
20310
  ? () => {
20074
20311
  /* empty */
20075
20312
  }
20076
20313
  : body.length === 1
20077
- ? /** @type {import("./interface.ts").CompiledExpression} */ (
20078
- expressions[0]
20079
- )
20314
+ ? /** @type {CompiledExpression} */ (expressions[0])
20080
20315
  : function (scope, locals) {
20081
20316
  let lastValue;
20082
20317
 
20083
- for (let i = 0, j = expressions.length; i < j; i++) {
20318
+ for (let i = 0; i < expressions.length; i++) {
20084
20319
  lastValue = expressions[i](scope, locals);
20085
20320
  }
20086
20321
 
20087
20322
  return lastValue;
20088
20323
  };
20089
20324
 
20325
+ const fn = /** @type {CompiledExpression} */ (fnRaw);
20326
+
20090
20327
  if (assign) {
20091
20328
  fn._assign = (scope, value, locals) => assign(scope, locals, value);
20092
20329
  }
@@ -20094,6 +20331,7 @@
20094
20331
  if (inputs) {
20095
20332
  fn._inputs = inputs;
20096
20333
  }
20334
+
20097
20335
  fn._decoratedNode = /** @type {BodyNode} */ (decoratedNode);
20098
20336
 
20099
20337
  return fn;
@@ -22042,43 +22280,34 @@
22042
22280
  * @param {Scope} [parent] - Custom parent.
22043
22281
  */
22044
22282
  constructor(context, parent) {
22045
- this.context = context
22046
- ? context.context
22047
- ? context.context
22048
- : context
22049
- : undefined;
22050
-
22051
- /** @type {Map<string, Array<import('./interface.ts').Listener>>} Watch listeners */
22052
- this.watchers = context ? context.watchers : new Map();
22283
+ /** @ignore @type {Map<string, Array<import('./interface.ts').Listener>>} Watch listeners */
22284
+ this._watchers = context?._watchers ?? new Map();
22053
22285
 
22054
22286
  /** @private @type {Map<String, Function[]>} Event listeners */
22055
22287
  this._listeners = new Map();
22056
22288
 
22057
22289
  /** @private @type {Map<string, Array<import('./interface.ts').Listener>>} Watch listeners from other proxies */
22058
- this._foreignListeners = context ? context._foreignListeners : new Map();
22290
+ this._foreignListeners = context?._foreignListeners ?? new Map();
22059
22291
 
22060
22292
  /** @private @type {Set<Proxy<ng.Scope>>} */
22061
- this._foreignProxies = context ? context._foreignProxies : new Set();
22293
+ this._foreignProxies = context?._foreignProxies ?? new Set();
22062
22294
 
22063
22295
  /** @private @type {WeakMap<Object, Array<string>>} */
22064
- this._objectListeners = context ? context._objectListeners : new WeakMap();
22296
+ this._objectListeners = context?._objectListeners ?? new WeakMap();
22065
22297
 
22066
22298
  /** @type {Proxy<Scope>} Current proxy being operated on */
22067
- this.$proxy = null;
22299
+ this.$proxy;
22068
22300
 
22069
- /** @type {Scope} The actual proxy */
22301
+ /** @type {Scope} This is the reference to the Scope object with acts as the actual proxy */
22070
22302
  this.$handler = /** @type {Scope} */ (this);
22071
22303
 
22072
22304
  /** @type {*} Current target being called on */
22073
22305
  this.$target = null;
22074
22306
 
22075
- /** @type {*} Value wrapped by the proxy */
22076
- this.$value = null;
22077
-
22078
22307
  /**
22079
- * @type {Scope[]}
22308
+ * @ignore @type {Scope[]}
22080
22309
  */
22081
- this.$children = [];
22310
+ this._children = [];
22082
22311
 
22083
22312
  /**
22084
22313
  * @type {number} Unique model ID (monotonically increasing) useful for debugging.
@@ -22086,15 +22315,14 @@
22086
22315
  this.$id = nextId();
22087
22316
 
22088
22317
  /**
22089
- * @type {Scope}
22318
+ * @type {ng.RootScopeService}
22090
22319
  */
22091
- this.$root = context ? context.$root : /** @type {Scope} */ (this);
22320
+ this.$root = context ? context.$root : this;
22092
22321
 
22093
- this.$parent = parent
22094
- ? parent
22095
- : /** @type {Scope} */ (this).$root === /** @type {Scope} */ (this)
22096
- ? null
22097
- : context;
22322
+ /**
22323
+ * @type {Scope | undefined}
22324
+ */
22325
+ this.$parent = parent || (this.$root === this ? undefined : context);
22098
22326
 
22099
22327
  /** @ignore @type {boolean} */
22100
22328
  this._destroyed = false;
@@ -22109,7 +22337,7 @@
22109
22337
  this.propertyMap = {
22110
22338
  $apply: this.$apply.bind(this),
22111
22339
  $broadcast: this.$broadcast.bind(this),
22112
- $children: this.$children,
22340
+ _children: this._children,
22113
22341
  $destroy: this.$destroy.bind(this),
22114
22342
  $emit: this.$emit.bind(this),
22115
22343
  $eval: this.$eval.bind(this),
@@ -22137,7 +22365,7 @@
22137
22365
  * Intercepts and handles property assignments on the target object. If a new value is
22138
22366
  * an object, it will be recursively proxied.
22139
22367
  *
22140
- * @param {Object} target - The target object.
22368
+ * @param {Object & Record<string, any>} target - The target object.
22141
22369
  * @param {string} property - The name of the property being set.
22142
22370
  * @param {*} value - The new value being assigned to the property.
22143
22371
  * @param {Proxy<Scope>} proxy - The proxy intercepting property access
@@ -22154,14 +22382,9 @@
22154
22382
  return true;
22155
22383
  }
22156
22384
 
22157
- if (
22158
- (target.constructor?.$nonscope &&
22159
- isArray(target.constructor.$nonscope) &&
22160
- target.constructor.$nonscope.includes(property)) ||
22161
- (target.$nonscope &&
22162
- isArray(target.$nonscope) &&
22163
- target.$nonscope.includes(property))
22164
- ) {
22385
+ const nonscopeProps = target.constructor?.$nonscope ?? target.$nonscope;
22386
+
22387
+ if (isArray(nonscopeProps) && nonscopeProps.includes(property)) {
22165
22388
  target[property] = value;
22166
22389
 
22167
22390
  return true;
@@ -22183,7 +22406,7 @@
22183
22406
  if (oldValue && oldValue[isProxySymbol]) {
22184
22407
  if (isArray(value)) {
22185
22408
  if (oldValue !== value) {
22186
- const listeners = this.watchers.get(property);
22409
+ const listeners = this._watchers.get(property);
22187
22410
 
22188
22411
  if (listeners) {
22189
22412
  this.#scheduleListener(listeners);
@@ -22215,7 +22438,7 @@
22215
22438
  }
22216
22439
 
22217
22440
  if (oldValue !== value) {
22218
- const listeners = this.watchers.get(property);
22441
+ const listeners = this._watchers.get(property);
22219
22442
 
22220
22443
  if (listeners) {
22221
22444
  this.#scheduleListener(listeners);
@@ -22258,7 +22481,7 @@
22258
22481
  target[property] = undefined;
22259
22482
 
22260
22483
  if (!called) {
22261
- const listeners = this.watchers.get(property);
22484
+ const listeners = this._watchers.get(property);
22262
22485
 
22263
22486
  if (listeners) {
22264
22487
  this.#scheduleListener(listeners);
@@ -22270,7 +22493,7 @@
22270
22493
 
22271
22494
  if (isDefined(value)) {
22272
22495
  target[property] = value;
22273
- const listeners = this.watchers.get(property);
22496
+ const listeners = this._watchers.get(property);
22274
22497
 
22275
22498
  if (listeners) {
22276
22499
  this.#scheduleListener(listeners);
@@ -22278,10 +22501,12 @@
22278
22501
 
22279
22502
  if (isArray(target)) {
22280
22503
  if (this._objectListeners.has(proxy) && property !== "length") {
22281
- const keyList = this._objectListeners.get(proxy);
22504
+ const keyList = /** @type {string[]} */ (
22505
+ this._objectListeners.get(proxy)
22506
+ );
22282
22507
 
22283
22508
  for (let i = 0, l = keyList.length; i < l; i++) {
22284
- const currentListeners = this.watchers.get(keyList[i]);
22509
+ const currentListeners = this._watchers.get(keyList[i]);
22285
22510
 
22286
22511
  if (currentListeners) this.#scheduleListener(currentListeners);
22287
22512
  }
@@ -22297,7 +22522,7 @@
22297
22522
  this._foreignProxies.add(/** @type {Proxy<ng.Scope>} */ (value));
22298
22523
  target[property] = value;
22299
22524
 
22300
- if (!this.watchers.has(property)) {
22525
+ if (!this._watchers.has(property)) {
22301
22526
  return true;
22302
22527
  }
22303
22528
  }
@@ -22323,7 +22548,7 @@
22323
22548
  for (let i = 0, l = keyList.length; i < l; i++) {
22324
22549
  const key = keyList[i];
22325
22550
 
22326
- const keyListeners = this.watchers.get(key);
22551
+ const keyListeners = this._watchers.get(key);
22327
22552
 
22328
22553
  if (keyListeners) {
22329
22554
  for (let j = 0, jl = keyListeners.length; j < jl; j++) {
@@ -22335,7 +22560,7 @@
22335
22560
  }
22336
22561
 
22337
22562
  if (isArray(target)) {
22338
- const lengthListeners = this.watchers.get("length");
22563
+ const lengthListeners = this._watchers.get("length");
22339
22564
 
22340
22565
  if (lengthListeners) {
22341
22566
  for (let i = 0, l = lengthListeners.length; i < l; i++) {
@@ -22344,7 +22569,7 @@
22344
22569
  }
22345
22570
  }
22346
22571
 
22347
- const propListeners = this.watchers.get(property);
22572
+ const propListeners = this._watchers.get(property);
22348
22573
 
22349
22574
  if (propListeners) {
22350
22575
  for (let i = 0, l = propListeners.length; i < l; i++) {
@@ -22366,9 +22591,7 @@
22366
22591
 
22367
22592
  const wrapperExpr = x.watchProp.split(".").slice(0, -1).join(".");
22368
22593
 
22369
- const expectedHandler = $parse(wrapperExpr)(
22370
- x.originalTarget,
22371
- )?.$handler;
22594
+ const expectedHandler = $parse(wrapperExpr)(x.originalTarget);
22372
22595
 
22373
22596
  if (expectedTarget === expectedHandler?.$target) {
22374
22597
  scheduled.push(x);
@@ -22410,12 +22633,14 @@
22410
22633
  }
22411
22634
 
22412
22635
  if (this._objectListeners.has(proxy) && property !== "length") {
22413
- const keyList = this._objectListeners.get(proxy);
22636
+ const keyList = /** @type {string[]} */ (
22637
+ this._objectListeners.get(proxy)
22638
+ );
22414
22639
 
22415
22640
  for (let i = 0, l = keyList.length; i < l; i++) {
22416
22641
  const key = keyList[i];
22417
22642
 
22418
- const listeners = this.watchers.get(key);
22643
+ const listeners = this._watchers.get(key);
22419
22644
 
22420
22645
  if (listeners && this._scheduled !== listeners) {
22421
22646
  this.#scheduleListener(listeners);
@@ -22432,7 +22657,7 @@
22432
22657
  * properties (`watch` and `sync`) and binds their methods. For other properties,
22433
22658
  * it returns the value directly.
22434
22659
  *
22435
- * @param {Object} target - The target object.
22660
+ * @param {Object & Record<string, any>} target - The target object.
22436
22661
  * @param {string|number|symbol} property - The name of the property being accessed.
22437
22662
  * @param {Proxy<Scope>} proxy - The proxy object being invoked
22438
22663
  * @returns {*} - The value of the property or a method if accessing `watch` or `sync`.
@@ -22444,8 +22669,10 @@
22444
22669
 
22445
22670
  if (property === isProxySymbol) return true;
22446
22671
 
22447
- if (target[property] && isProxy(target[property])) {
22448
- this.$proxy = /** @type {Proxy<Scope>} */ (target[property]);
22672
+ const targetProp = target[/** @type {string} */ (property)];
22673
+
22674
+ if (isProxy(targetProp)) {
22675
+ this.$proxy = /** @type {Proxy<Scope>} */ (targetProp);
22449
22676
  } else {
22450
22677
  this.$proxy = proxy;
22451
22678
  }
@@ -22458,12 +22685,14 @@
22458
22685
  ["pop", "shift", "unshift"].includes(/** @type { string } */ (property))
22459
22686
  ) {
22460
22687
  if (this._objectListeners.has(proxy)) {
22461
- const keyList = this._objectListeners.get(proxy);
22688
+ const keyList = /** @type {string []} */ (
22689
+ this._objectListeners.get(proxy)
22690
+ );
22462
22691
 
22463
22692
  for (let i = 0, l = keyList.length; i < l; i++) {
22464
22693
  const key = keyList[i];
22465
22694
 
22466
- const listeners = this.watchers.get(key);
22695
+ const listeners = this._watchers.get(key);
22467
22696
 
22468
22697
  if (listeners) {
22469
22698
  this._scheduled = listeners;
@@ -22482,28 +22711,34 @@
22482
22711
  return this.propertyMap[/** @type {string} */ (property)];
22483
22712
  } else {
22484
22713
  // we are a simple getter
22485
- return target[property];
22714
+ return targetProp;
22486
22715
  }
22487
22716
  }
22488
22717
 
22718
+ /**
22719
+ * @param {Object & Record<string, any>} target - The target object.
22720
+ * @param {string} property - The name of the property being deleted
22721
+ */
22489
22722
  deleteProperty(target, property) {
22490
22723
  // Currently deletes $model
22491
22724
  if (target[property] && target[property][isProxySymbol]) {
22492
22725
  target[property] = undefined;
22493
22726
 
22494
- const listeners = this.watchers.get(property);
22727
+ const listeners = this._watchers.get(property);
22495
22728
 
22496
22729
  if (listeners) {
22497
22730
  this.#scheduleListener(listeners);
22498
22731
  }
22499
22732
 
22500
22733
  if (this._objectListeners.has(this.$proxy)) {
22501
- const keyList = this._objectListeners.get(this.$proxy);
22734
+ const keyList = /** @type {string[]} */ (
22735
+ this._objectListeners.get(this.$proxy)
22736
+ );
22502
22737
 
22503
22738
  for (let i = 0, l = keyList.length; i < l; i++) {
22504
22739
  const key = keyList[i];
22505
22740
 
22506
- const currentListeners = this.watchers.get(key);
22741
+ const currentListeners = this._watchers.get(key);
22507
22742
 
22508
22743
  if (currentListeners) this.#scheduleListener(currentListeners);
22509
22744
  }
@@ -22520,17 +22755,19 @@
22520
22755
  delete target[property];
22521
22756
 
22522
22757
  if (this._objectListeners.has(this.$proxy)) {
22523
- const keyList = this._objectListeners.get(this.$proxy);
22758
+ const keyList = /** @type {string[]} */ (
22759
+ this._objectListeners.get(this.$proxy)
22760
+ );
22524
22761
 
22525
22762
  for (let i = 0, l = keyList.length; i < l; i++) {
22526
22763
  const key = keyList[i];
22527
22764
 
22528
- const listeners = this.watchers.get(key);
22765
+ const listeners = this._watchers.get(key);
22529
22766
 
22530
22767
  if (listeners) this.#scheduleListener(listeners);
22531
22768
  }
22532
22769
  } else {
22533
- const listeners = this.watchers.get(property);
22770
+ const listeners = this._watchers.get(property);
22534
22771
 
22535
22772
  if (listeners) {
22536
22773
  this.#scheduleListener(listeners, target[property]);
@@ -22540,13 +22777,15 @@
22540
22777
  return true;
22541
22778
  }
22542
22779
 
22543
- /** @internal **/
22780
+ /**
22781
+ * @param {Object & Record<string, any>} value
22782
+ */
22544
22783
  #checkeListenersForAllKeys(value) {
22545
22784
  if (isUndefined(value)) {
22546
22785
  return;
22547
22786
  }
22548
22787
  keys(value).forEach((k) => {
22549
- const listeners = this.watchers.get(k);
22788
+ const listeners = this._watchers.get(k);
22550
22789
 
22551
22790
  if (listeners) {
22552
22791
  this.#scheduleListener(listeners);
@@ -22560,7 +22799,7 @@
22560
22799
 
22561
22800
  /**
22562
22801
  * @param {import('./interface.ts').Listener[]} listeners
22563
- * @param {Function} filter
22802
+ * @param {(listeners: import('./interface').Listener[]) => import('./interface').Listener[]} filter
22564
22803
  */
22565
22804
  #scheduleListener(listeners, filter = (val) => val) {
22566
22805
  queueMicrotask(() => {
@@ -22571,11 +22810,8 @@
22571
22810
  while (index < filteredListeners.length) {
22572
22811
  const listener = filteredListeners[index];
22573
22812
 
22574
- if (listener.foreignListener) {
22575
- listener.foreignListener.#notifyListener(listener, this.$target);
22576
- } else {
22577
- this.#notifyListener(listener, this.$target);
22578
- }
22813
+ this.#notifyListener(listener, this.$target);
22814
+
22579
22815
  index++;
22580
22816
  }
22581
22817
  });
@@ -22612,9 +22848,20 @@
22612
22848
  };
22613
22849
  }
22614
22850
 
22615
- const expr = /** @type {ExpressionNode & BodyNode} */ (
22616
- get._decoratedNode.body[0]
22617
- ).expression;
22851
+ const expr = /** @type {import("../parse/ast/ast-node.ts").ASTNode} */ (
22852
+ /** @type {ExpressionNode & BodyNode} */ (get._decoratedNode.body[0])
22853
+ .expression
22854
+ );
22855
+
22856
+ if (!listenerFn) {
22857
+ let res = get(this.$target);
22858
+
22859
+ while (isFunction(res)) {
22860
+ res = res(this.$target);
22861
+ }
22862
+
22863
+ return undefined;
22864
+ }
22618
22865
 
22619
22866
  /** @type {ng.Listener} */
22620
22867
  const listener = {
@@ -22629,6 +22876,9 @@
22629
22876
  // simplest case
22630
22877
  let key = /** @type {LiteralNode} */ (expr).name;
22631
22878
 
22879
+ /**
22880
+ * @type {string[]}
22881
+ */
22632
22882
  const keySet = [];
22633
22883
 
22634
22884
  const { type } = expr;
@@ -22637,15 +22887,6 @@
22637
22887
  // 3
22638
22888
  case ASTType._AssignmentExpression:
22639
22889
  // assignment calls without listener functions
22640
- if (!listenerFn) {
22641
- let res = get(this.$target);
22642
-
22643
- while (isFunction(res)) {
22644
- res = res(this.$target);
22645
- }
22646
-
22647
- return undefined;
22648
- }
22649
22890
  key = /** @type {LiteralNode} */ (
22650
22891
  /** @type {ExpressionNode} */ (expr).left
22651
22892
  )?.name;
@@ -22657,7 +22898,7 @@
22657
22898
  /** @type {BodyNode} */ (expr).toWatch[0]
22658
22899
  )?.test
22659
22900
  )?.name;
22660
- listener.property.push(key);
22901
+ listener.property.push(/** @type {string} */ (key));
22661
22902
  break;
22662
22903
  }
22663
22904
  // 5
@@ -22683,7 +22924,10 @@
22683
22924
  for (let i = 0, l = keyList.length; i < l; i++) {
22684
22925
  const deregisterKey = keyList[i];
22685
22926
 
22686
- this.#deregisterKey(deregisterKey, listener.id);
22927
+ this.#deregisterKey(
22928
+ /** @type {string} */ (deregisterKey),
22929
+ listener.id,
22930
+ );
22687
22931
  }
22688
22932
  };
22689
22933
  }
@@ -22732,7 +22976,10 @@
22732
22976
  ).name
22733
22977
  : /** @type {LiteralNode} */ (x).name;
22734
22978
 
22735
- this.#deregisterKey(deregisterKey, listener.id);
22979
+ this.#deregisterKey(
22980
+ /** @type {string} */ (deregisterKey),
22981
+ listener.id,
22982
+ );
22736
22983
  }
22737
22984
  };
22738
22985
  }
@@ -22763,7 +23010,10 @@
22763
23010
  const x = toWatch[i];
22764
23011
 
22765
23012
  if (!isDefined(x)) continue;
22766
- this.#registerKey(/** @type {LiteralNode} */ (x).name, listener);
23013
+ this.#registerKey(
23014
+ /** @type {string} */ (/** @type {LiteralNode} */ (x).name),
23015
+ listener,
23016
+ );
22767
23017
  this.#scheduleListener([listener]);
22768
23018
  }
22769
23019
 
@@ -22773,7 +23023,7 @@
22773
23023
 
22774
23024
  if (!isDefined(x)) continue;
22775
23025
  this.#deregisterKey(
22776
- /** @type {LiteralNode} */ (x).name,
23026
+ /** @type {string} */ (/** @type {LiteralNode} */ (x).name),
22777
23027
  listener.id,
22778
23028
  );
22779
23029
  }
@@ -22793,7 +23043,7 @@
22793
23043
  ).name;
22794
23044
  }
22795
23045
 
22796
- listener.property.push(key);
23046
+ listener.property.push(/** @type {string} */ (key));
22797
23047
 
22798
23048
  if (watchProp !== key) {
22799
23049
  // Handle nested expression call
@@ -22804,10 +23054,12 @@
22804
23054
  )(/** @type {Scope} */ (listener.originalTarget));
22805
23055
 
22806
23056
  if (potentialProxy && this._foreignProxies.has(potentialProxy)) {
22807
- potentialProxy.$handler.#registerForeignKey(key, listener);
23057
+ potentialProxy.$handler._registerForeignKey(key, listener);
22808
23058
  potentialProxy.$handler.#scheduleListener([listener]);
22809
23059
 
22810
23060
  return () => {
23061
+ potentialProxy.$handler._deregisterForeignKey(key, listener.id);
23062
+
22811
23063
  return potentialProxy.$handler.#deregisterKey(key, listener.id);
22812
23064
  };
22813
23065
  }
@@ -22817,7 +23069,9 @@
22817
23069
 
22818
23070
  // 10
22819
23071
  case ASTType._Identifier: {
22820
- listener.property.push(/** @type {LiteralNode} */ (expr).name);
23072
+ listener.property.push(
23073
+ /** @type {string} */ (/** @type {LiteralNode} */ (expr).name),
23074
+ );
22821
23075
  break;
22822
23076
  }
22823
23077
 
@@ -22898,7 +23152,7 @@
22898
23152
  const listenerObject = listener.watchFn(this.$target);
22899
23153
 
22900
23154
  if (isObject(listenerObject)) {
22901
- this._objectListeners.set(listenerObject, [key]);
23155
+ this._objectListeners.set(listenerObject, [/** @type {string} */ (key)]);
22902
23156
  }
22903
23157
 
22904
23158
  if (keySet.length > 0) {
@@ -22906,7 +23160,7 @@
22906
23160
  this.#registerKey(keySet[i], listener);
22907
23161
  }
22908
23162
  } else {
22909
- this.#registerKey(key, listener);
23163
+ this.#registerKey(/** @type {string} */ (key), listener);
22910
23164
  }
22911
23165
 
22912
23166
  if (!lazy) {
@@ -22927,26 +23181,27 @@
22927
23181
 
22928
23182
  return res;
22929
23183
  } else {
22930
- return this.#deregisterKey(key, listener.id);
23184
+ return this.#deregisterKey(/** @type {string} */ (key), listener.id);
22931
23185
  }
22932
23186
  };
22933
23187
  }
22934
23188
 
23189
+ /**
23190
+ * @param {ng.Scope} [childInstance]
23191
+ * @returns {Proxy<ng.Scope> & ng.Scope}
23192
+ */
22935
23193
  $new(childInstance) {
22936
23194
  let child;
22937
23195
 
22938
23196
  if (childInstance) {
22939
- if (Object.getPrototypeOf(childInstance) === Object.prototype) {
23197
+ const proto = Object.getPrototypeOf(childInstance);
23198
+
23199
+ // If child is plain object, or already inherits from target, set prototype to target
23200
+ if (proto === Object.prototype || proto === this.$target) {
22940
23201
  Object.setPrototypeOf(childInstance, this.$target);
22941
23202
  } else {
22942
- if (Object.getPrototypeOf(childInstance) === this.$target) {
22943
- Object.setPrototypeOf(childInstance, this.$target);
22944
- } else {
22945
- Object.setPrototypeOf(
22946
- Object.getPrototypeOf(childInstance) || childInstance,
22947
- this.$target,
22948
- );
22949
- }
23203
+ // If child has some other prototype, preserve it but link to this.$target
23204
+ Object.setPrototypeOf(proto || childInstance, this.$target);
22950
23205
  }
22951
23206
 
22952
23207
  child = childInstance;
@@ -22956,51 +23211,73 @@
22956
23211
 
22957
23212
  const proxy = new Proxy(child, new Scope(this));
22958
23213
 
22959
- this.$children.push(proxy);
23214
+ this._children.push(proxy);
22960
23215
 
22961
23216
  return proxy;
22962
23217
  }
22963
23218
 
23219
+ /**
23220
+ * @param {ng.Scope} [instance]
23221
+ * @returns {Proxy<ng.Scope> & ng.Scope}
23222
+ */
22964
23223
  $newIsolate(instance) {
22965
23224
  const child = instance ? Object.create(instance) : Object.create(null);
22966
23225
 
22967
23226
  const proxy = new Proxy(child, new Scope(this, this.$root));
22968
23227
 
22969
- this.$children.push(proxy);
23228
+ this._children.push(proxy);
22970
23229
 
22971
23230
  return proxy;
22972
23231
  }
22973
23232
 
23233
+ /**
23234
+ * @param {ng.Scope} parentInstance
23235
+ * @returns {Proxy<ng.Scope> & ng.Scope}
23236
+ */
22974
23237
  $transcluded(parentInstance) {
22975
23238
  const child = Object.create(this.$target);
22976
23239
 
22977
23240
  const proxy = new Proxy(child, new Scope(this, parentInstance));
22978
23241
 
22979
- this.$children.push(proxy);
23242
+ this._children.push(proxy);
22980
23243
 
22981
23244
  return proxy;
22982
23245
  }
22983
23246
 
22984
- /** @internal **/
23247
+ /**
23248
+ * @param {string} key
23249
+ * @param {import("./interface.ts").Listener} listener
23250
+ */
22985
23251
  #registerKey(key, listener) {
22986
- if (this.watchers.has(key)) {
22987
- this.watchers.get(key).push(listener);
23252
+ if (this._watchers.has(key)) {
23253
+ /** @type {import("./interface.ts").Listener[]} */ (
23254
+ this._watchers.get(key)
23255
+ ).push(listener);
22988
23256
  } else {
22989
- this.watchers.set(key, [listener]);
23257
+ this._watchers.set(key, [listener]);
22990
23258
  }
22991
23259
  }
22992
23260
 
22993
- /** @internal **/
22994
- #registerForeignKey(key, listener) {
23261
+ /**
23262
+ * @param {string} key
23263
+ * @param {import("./interface.ts").Listener} listener
23264
+ */
23265
+ _registerForeignKey(key, listener) {
22995
23266
  if (this._foreignListeners.has(key)) {
22996
- this._foreignListeners.get(key).push(listener);
23267
+ /** @type {import("./interface.ts").Listener[]} */ (
23268
+ this._foreignListeners.get(key)
23269
+ ).push(listener);
22997
23270
  } else {
22998
23271
  this._foreignListeners.set(key, [listener]);
22999
23272
  }
23000
23273
  }
23001
23274
 
23275
+ /**
23276
+ * @param {string} key
23277
+ * @param {number} id
23278
+ */
23002
23279
  #deregisterKey(key, id) {
23003
- const listenerList = this.watchers.get(key);
23280
+ const listenerList = this._watchers.get(key);
23004
23281
 
23005
23282
  if (!listenerList) return false;
23006
23283
 
@@ -23011,30 +23288,45 @@
23011
23288
  listenerList.splice(index, 1);
23012
23289
 
23013
23290
  if (listenerList.length) {
23014
- this.watchers.set(key, listenerList);
23291
+ this._watchers.set(key, listenerList);
23015
23292
  } else {
23016
- this.watchers.delete(key);
23293
+ this._watchers.delete(key);
23017
23294
  }
23018
23295
 
23019
23296
  return true;
23020
23297
  }
23021
23298
 
23022
- // #deregisterForeignKey(key, id) {
23023
- // const listenerList = this._foreignListeners.get(key);
23024
- // if (!listenerList) return false;
23299
+ /**
23300
+ * @param {string} key
23301
+ * @param {number} id
23302
+ */
23303
+ _deregisterForeignKey(key, id) {
23304
+ const listenerList = this._foreignListeners.get(key);
23025
23305
 
23026
- // const index = listenerList.findIndex((x) => x.id === id);
23027
- // if (index === -1) return false;
23306
+ if (!listenerList) return false;
23028
23307
 
23029
- // listenerList.splice(index, 1);
23030
- // if (listenerList.length) {
23031
- // this._foreignListeners.set(key, listenerList);
23032
- // } else {
23033
- // this._foreignListeners.delete(key);
23034
- // }
23035
- // return true;
23036
- // }
23308
+ const index = listenerList.findIndex((x) => x.id === id);
23309
+
23310
+ if (index === -1) return false;
23311
+
23312
+ listenerList.splice(index, 1);
23313
+
23314
+ if (listenerList.length) {
23315
+ this._foreignListeners.set(key, listenerList);
23316
+ } else {
23317
+ this._foreignListeners.delete(key);
23318
+ }
23319
+
23320
+ return true;
23321
+ }
23037
23322
 
23323
+ /**
23324
+ * Evaluates an Angular expression in the context of this scope.
23325
+ *
23326
+ * @param {string} expr - Angular expression to evaluate
23327
+ * @param {Record<string, any>} [locals] - Optional local variables
23328
+ * @returns {any}
23329
+ */
23038
23330
  $eval(expr, locals) {
23039
23331
  const fn = $parse(expr);
23040
23332
 
@@ -23114,7 +23406,7 @@
23114
23406
  /**
23115
23407
  * @param {string} name
23116
23408
  * @param {...any} args
23117
- * @returns {void}
23409
+ * @returns {ng.ScopeEvent | undefined}
23118
23410
  */
23119
23411
  $emit(name, ...args) {
23120
23412
  return this.#eventHelper(
@@ -23136,8 +23428,10 @@
23136
23428
  }
23137
23429
 
23138
23430
  /**
23139
- * @internal
23140
- * @returns {any}
23431
+ * Internal event propagation helper
23432
+ * @param {{ name: string, event?: ng.ScopeEvent, broadcast: boolean }} param0 - Event info
23433
+ * @param {...any} args - Additional arguments passed to listeners
23434
+ * @returns {ng.ScopeEvent|undefined}
23141
23435
  */
23142
23436
  #eventHelper({ name, event, broadcast }, ...args) {
23143
23437
  if (!broadcast) {
@@ -23154,18 +23448,18 @@
23154
23448
  }
23155
23449
 
23156
23450
  if (event) {
23157
- event.currentScope = this.$target;
23451
+ event.currentScope = this.$proxy;
23158
23452
  } else {
23159
23453
  event = event || {
23160
23454
  name,
23161
- targetScope: this.$target,
23162
- currentScope: this.$target,
23455
+ targetScope: this.$proxy,
23456
+ currentScope: this.$proxy,
23163
23457
  stopped: false,
23164
23458
  stopPropagation() {
23165
- event.stopped = true;
23459
+ /** @type {ng.ScopeEvent} */ (event).stopped = true;
23166
23460
  },
23167
23461
  preventDefault() {
23168
- event.defaultPrevented = true;
23462
+ /** @type {ng.ScopeEvent} */ (event).defaultPrevented = true;
23169
23463
  },
23170
23464
  defaultPrevented: false,
23171
23465
  };
@@ -23205,8 +23499,8 @@
23205
23499
  }
23206
23500
 
23207
23501
  if (broadcast) {
23208
- if (this.$children.length > 0) {
23209
- this.$children.forEach((child) => {
23502
+ if (this._children.length > 0) {
23503
+ this._children.forEach((child) => {
23210
23504
  event = child.$handler.#eventHelper(
23211
23505
  { name, event, broadcast },
23212
23506
  ...args,
@@ -23244,7 +23538,7 @@
23244
23538
 
23245
23539
  this.$broadcast("$destroy");
23246
23540
 
23247
- for (const [key, val] of this.watchers) {
23541
+ for (const [key, val] of this._watchers) {
23248
23542
  for (let i = val.length - 1; i >= 0; i--) {
23249
23543
  if (val[i].scopeId === this.$id) {
23250
23544
  val.splice(i, 1);
@@ -23252,16 +23546,16 @@
23252
23546
  }
23253
23547
 
23254
23548
  if (val.length === 0) {
23255
- this.watchers.delete(key);
23549
+ this._watchers.delete(key);
23256
23550
  } else {
23257
- this.watchers.set(key, val);
23551
+ this._watchers.set(key, val);
23258
23552
  }
23259
23553
  }
23260
23554
 
23261
23555
  if (this.#isRoot()) {
23262
- this.watchers.clear();
23556
+ this._watchers.clear();
23263
23557
  } else {
23264
- const children = this.$parent.$children;
23558
+ const children = /** @type {Scope} */ (this.$parent)._children;
23265
23559
 
23266
23560
  for (let i = 0, l = children.length; i < l; i++) {
23267
23561
  if (children[i].$id === this.$id) {
@@ -23278,6 +23572,7 @@
23278
23572
  /**
23279
23573
  * @internal
23280
23574
  * @param {import('./interface.ts').Listener} listener - The property path that was changed.
23575
+ * @param {Scope | typeof Proxy<Scope> | undefined} target
23281
23576
  */
23282
23577
  #notifyListener(listener, target) {
23283
23578
  const { originalTarget, listenerFn, watchFn } = listener;
@@ -23304,7 +23599,7 @@
23304
23599
  listenerFn(newVal, originalTarget);
23305
23600
 
23306
23601
  while ($postUpdateQueue.length) {
23307
- const fn = $postUpdateQueue.shift();
23602
+ const fn = /** @type {Function} */ ($postUpdateQueue.shift());
23308
23603
 
23309
23604
  fn();
23310
23605
  }
@@ -23316,7 +23611,7 @@
23316
23611
  /* @ignore */
23317
23612
  $flushQueue() {
23318
23613
  while ($postUpdateQueue.length) {
23319
- $postUpdateQueue.shift()();
23614
+ /** @type {Function} */ ($postUpdateQueue.shift())();
23320
23615
  }
23321
23616
  }
23322
23617
 
@@ -23336,7 +23631,7 @@
23336
23631
  } else {
23337
23632
  let res = undefined;
23338
23633
 
23339
- for (const child of this.$children) {
23634
+ for (const child of this._children) {
23340
23635
  const found = child.$getById(id);
23341
23636
 
23342
23637
  if (found) {
@@ -23357,15 +23652,15 @@
23357
23652
  const stack = [this.$root];
23358
23653
 
23359
23654
  while (stack.length) {
23360
- const scope = stack.pop();
23655
+ const scope = /** @type {Scope} */ (stack.pop());
23361
23656
 
23362
23657
  if (scope.$scopename === name) {
23363
23658
  return scope;
23364
23659
  }
23365
23660
 
23366
- if (scope.$children?.length) {
23367
- for (let i = scope.$children.length - 1; i >= 0; i--) {
23368
- stack.push(scope.$children[i]);
23661
+ if (scope._children?.length) {
23662
+ for (let i = scope._children.length - 1; i >= 0; i--) {
23663
+ stack.push(scope._children[i]);
23369
23664
  }
23370
23665
  }
23371
23666
  }
@@ -23385,7 +23680,7 @@
23385
23680
 
23386
23681
  let count = 0;
23387
23682
 
23388
- for (const watchers of model.watchers.values()) {
23683
+ for (const watchers of model._watchers.values()) {
23389
23684
  for (let i = 0, l = watchers.length; i < l; i++) {
23390
23685
  if (childIds.has(watchers[i].scopeId)) {
23391
23686
  count++;
@@ -23406,14 +23701,14 @@
23406
23701
  const stack = [child];
23407
23702
 
23408
23703
  while (stack.length) {
23409
- const node = stack.pop();
23704
+ const node = /** @type {Scope} */ (stack.pop());
23410
23705
 
23411
23706
  if (!ids.has(node.$id)) {
23412
23707
  ids.add(node.$id);
23413
23708
 
23414
- if (node.$children) {
23415
- for (let i = 0, l = node.$children.length; i < l; i++) {
23416
- stack.push(node.$children[i]);
23709
+ if (node._children) {
23710
+ for (let i = 0, l = node._children.length; i < l; i++) {
23711
+ stack.push(node._children[i]);
23417
23712
  }
23418
23713
  }
23419
23714
  }
@@ -23699,7 +23994,7 @@
23699
23994
  message: messageCtrl,
23700
23995
  };
23701
23996
  this.insertMessageNode(this.$element, comment, nextKey);
23702
- comment.$$ngMessageNode = nextKey;
23997
+ comment._ngMessageNode = nextKey;
23703
23998
  this.latestKey++;
23704
23999
  }
23705
24000
 
@@ -23710,9 +24005,9 @@
23710
24005
  if (isDefault) {
23711
24006
  delete this.default;
23712
24007
  } else {
23713
- const key = comment.$$ngMessageNode;
24008
+ const key = comment._ngMessageNode;
23714
24009
 
23715
- delete comment.$$ngMessageNode;
24010
+ delete comment._ngMessageNode;
23716
24011
  this.removeMessageNode(this.$element, comment, key);
23717
24012
  delete this.messages[key];
23718
24013
  }
@@ -23725,7 +24020,7 @@
23725
24020
  const parentLookup = [];
23726
24021
 
23727
24022
  while (prevNode && prevNode !== parent) {
23728
- const prevKey = prevNode.$$ngMessageNode;
24023
+ const prevKey = prevNode._ngMessageNode;
23729
24024
 
23730
24025
  if (prevKey && prevKey.length) {
23731
24026
  return this.messages[prevKey];
@@ -24663,6 +24958,223 @@
24663
24958
  }
24664
24959
  }
24665
24960
 
24961
+ const KEY = "$animId";
24962
+
24963
+ /**
24964
+ * Animation cache responsible for:
24965
+ * - Generating stable animation cache keys
24966
+ * - Tracking cached animation results
24967
+ * - Avoiding repeated animation work
24968
+ *
24969
+ * Cache keys are scoped per parent node to prevent collisions between
24970
+ * structurally identical nodes in different DOM subtrees.
24971
+ *
24972
+ * @internal
24973
+ */
24974
+ class AnimateCache {
24975
+ /** @type {Map<string, import("./interface.ts").CacheEntry>} */
24976
+ #cache = new Map();
24977
+
24978
+ /**
24979
+ * Monotonically increasing counter used to assign synthetic parent IDs.
24980
+ * IDs are stored directly on parent nodes under `$animId`.
24981
+ *
24982
+ */
24983
+ #parentCounter = 0;
24984
+
24985
+ /**
24986
+ * Generates a stable cache key for an animation invocation.
24987
+ *
24988
+ * The key is derived from:
24989
+ * - The node's parent (used as a cache namespace)
24990
+ * - The animation method (e.g. enter, leave, addClass)
24991
+ * - The node's current CSS class state
24992
+ * - Any classes being added or removed
24993
+ *
24994
+ * If the node is not attached to the DOM, the node itself is used
24995
+ * as the parent scope to avoid key collisions.
24996
+ *
24997
+ * @param {HTMLElement} node
24998
+ * Target element being animated.
24999
+ * @param {string} method
25000
+ * Animation method name.
25001
+ * @param {string} [addClass]
25002
+ * CSS class scheduled to be added during the animation.
25003
+ * @param {string} [removeClass]
25004
+ * CSS class scheduled to be removed during the animation.
25005
+ *
25006
+ * @returns {string}
25007
+ * A unique, deterministic cache key.
25008
+ */
25009
+ _cacheKey(node, method, addClass, removeClass) {
25010
+ const parent = /** @type {HTMLElement & Record<string, number>} */ (
25011
+ node.parentNode ?? node
25012
+ );
25013
+
25014
+ const parentID = parent[KEY] ?? (parent[KEY] = ++this.#parentCounter);
25015
+
25016
+ const parts = [parentID, method, node.getAttribute("class")];
25017
+
25018
+ if (addClass) parts.push(addClass);
25019
+
25020
+ if (removeClass) parts.push(removeClass);
25021
+
25022
+ return parts.join(" ");
25023
+ }
25024
+
25025
+ /**
25026
+ * Determines whether a cache entry exists but is marked as invalid.
25027
+ *
25028
+ * This is typically used to detect animations that were previously
25029
+ * cached but resolved without a duration.
25030
+ *
25031
+ * @param {string} key
25032
+ * Cache key to test.
25033
+ * @returns {boolean}
25034
+ * True if an invalid cache entry exists, false otherwise.
25035
+ */
25036
+ _containsCachedAnimationWithoutDuration(key) {
25037
+ const entry = this.#cache.get(key);
25038
+
25039
+ return !!entry && !entry.isValid;
25040
+ }
25041
+
25042
+ /**
25043
+ * Clears all cached animation entries.
25044
+ *
25045
+ * Does not reset parent IDs.
25046
+ *
25047
+ * @returns {void}
25048
+ */
25049
+ _flush() {
25050
+ this.#cache.clear();
25051
+ }
25052
+
25053
+ /**
25054
+ * Returns the number of times a cache entry has been used.
25055
+ *
25056
+ * @param {string} key
25057
+ * Cache key to query.
25058
+ * @returns {number}
25059
+ * Usage count, or 0 if the entry does not exist.
25060
+ */
25061
+ _count(key) {
25062
+ return this.#cache.get(key)?.total ?? 0;
25063
+ }
25064
+
25065
+ /**
25066
+ * Retrieves the cached value associated with a cache key.
25067
+ *
25068
+ * @param {string} key
25069
+ * Cache key to retrieve.
25070
+ * @returns {any}
25071
+ * Cached value, or undefined if not present.
25072
+ */
25073
+ _get(key) {
25074
+ return this.#cache.get(key)?.value;
25075
+ }
25076
+
25077
+ /**
25078
+ * Inserts or updates a cache entry.
25079
+ *
25080
+ * Existing entries will have their usage count incremented
25081
+ * and their value replaced.
25082
+ *
25083
+ * @param {string} key
25084
+ * Cache key.
25085
+ * @param {any} value
25086
+ * Value to cache.
25087
+ * @param {boolean} isValid
25088
+ * Whether the cached value is considered valid.
25089
+ *
25090
+ * @returns {void}
25091
+ */
25092
+ _put(key, value, isValid) {
25093
+ const entry = this.#cache.get(key);
25094
+
25095
+ if (entry) {
25096
+ entry.total++;
25097
+ entry.value = value;
25098
+ } else {
25099
+ this.#cache.set(key, { total: 1, value, isValid });
25100
+ }
25101
+ }
25102
+ }
25103
+
25104
+ const animateCache = new AnimateCache();
25105
+
25106
+ /**
25107
+ * A requestAnimationFrame-based scheduler.
25108
+ */
25109
+ class RafScheduler {
25110
+ constructor() {
25111
+ /**
25112
+ * Internal task queue, where each item is an array of functions to run.
25113
+ * @type {Array<() => void>}
25114
+ */
25115
+ this._queue = [];
25116
+
25117
+ /**
25118
+ * ID of the currently scheduled animation frame (if any).
25119
+ * Used for cancellation and tracking.
25120
+ * @type {number|null}
25121
+ */
25122
+ this._cancelFn = null;
25123
+ }
25124
+
25125
+ /**
25126
+ * Processes the next batch of tasks in the animation frame.
25127
+ * Executes the first group of functions in the queue, then
25128
+ * schedules the next frame if needed.
25129
+ */
25130
+ _nextTick() {
25131
+ if (!this._queue.length) return;
25132
+
25133
+ while (this._queue.length) {
25134
+ /** @type {() => void} */ (this._queue.shift())();
25135
+ }
25136
+
25137
+ if (!this._cancelFn) {
25138
+ this._cancelFn = window.requestAnimationFrame(() => {
25139
+ this._cancelFn = null;
25140
+ this._nextTick();
25141
+ });
25142
+ }
25143
+ }
25144
+
25145
+ /**
25146
+ * The main scheduler function.
25147
+ * Accepts an array of functions and schedules them to run in the next available frame(s).
25148
+ *
25149
+ * @param {Array<() => void>} tasks
25150
+ */
25151
+ _schedule(tasks) {
25152
+ this._queue.push(...tasks);
25153
+ this._nextTick();
25154
+ }
25155
+
25156
+ /**
25157
+ * Cancels any pending frame and runs the given function once the frame is idle.
25158
+ * Useful for debounced updates.
25159
+ *
25160
+ * @param {Function} fn - Function to run when the animation frame is quiet.
25161
+ */
25162
+ _waitUntilQuiet(fn) {
25163
+ if (this._cancelFn !== null) {
25164
+ window.cancelAnimationFrame(this._cancelFn);
25165
+ this._cancelFn = null;
25166
+ }
25167
+
25168
+ this._cancelFn = window.requestAnimationFrame(() => {
25169
+ this._cancelFn = null;
25170
+ fn();
25171
+ this._nextTick();
25172
+ });
25173
+ }
25174
+ }
25175
+
25176
+ const rafScheduler = new RafScheduler();
25177
+
24666
25178
  const ANIMATE_TIMER_KEY = $injectTokens._animateCss;
24667
25179
 
24668
25180
  const ONE_SECOND = 1000;
@@ -24783,16 +25295,11 @@
24783
25295
  let activeClasses;
24784
25296
 
24785
25297
  this.$get = [
24786
- $injectTokens._animateCache,
24787
- $injectTokens._rAFScheduler,
24788
-
24789
25298
  /**
24790
25299
  *
24791
- * @param {*} $$animateCache
24792
- * @param {import("./raf-scheduler").RafScheduler} $$rAFScheduler
24793
25300
  * @returns
24794
25301
  */
24795
- function ($$animateCache, $$rAFScheduler) {
25302
+ function () {
24796
25303
  const applyAnimationClasses = applyAnimationClassesFactory();
24797
25304
 
24798
25305
  // TODO add types
@@ -24802,7 +25309,7 @@
24802
25309
  allowNoDuration,
24803
25310
  properties,
24804
25311
  ) {
24805
- let timings = $$animateCache.get(cacheKey);
25312
+ let timings = animateCache._get(cacheKey);
24806
25313
 
24807
25314
  if (!timings) {
24808
25315
  timings = computeCssStyles(node, properties);
@@ -24821,7 +25328,7 @@
24821
25328
 
24822
25329
  // we keep putting this in multiple times even though the value and the cacheKey are the same
24823
25330
  // because we're keeping an internal tally of how many duplicate animations are detected.
24824
- $$animateCache.put(cacheKey, timings, hasDuration);
25331
+ animateCache._put(cacheKey, timings, hasDuration);
24825
25332
 
24826
25333
  return timings;
24827
25334
  }
@@ -24839,8 +25346,8 @@
24839
25346
  // if we have one or more existing matches of matching elements
24840
25347
  // containing the same parent + CSS styles (which is how cacheKey works)
24841
25348
  // then staggering is possible
24842
- if ($$animateCache.count(cacheKey) > 0) {
24843
- stagger = $$animateCache.get(staggerCacheKey);
25349
+ if (animateCache._count(cacheKey) > 0) {
25350
+ stagger = animateCache._get(staggerCacheKey);
24844
25351
 
24845
25352
  if (!stagger) {
24846
25353
  const staggerClassName = pendClasses(className, "-stagger");
@@ -24857,7 +25364,7 @@
24857
25364
 
24858
25365
  node.classList.remove(staggerClassName);
24859
25366
 
24860
- $$animateCache.put(staggerCacheKey, stagger, true);
25367
+ animateCache._put(staggerCacheKey, stagger, true);
24861
25368
  }
24862
25369
  }
24863
25370
 
@@ -24868,25 +25375,17 @@
24868
25375
 
24869
25376
  function waitUntilQuiet(callback) {
24870
25377
  rafWaitQueue.push(callback);
24871
- $$rAFScheduler._waitUntilQuiet(() => {
24872
- $$animateCache.flush();
24873
-
24874
- // DO NOT REMOVE THIS LINE OR REFACTOR OUT THE `pageWidth` variable.
24875
- // the line below will force the browser to perform a repaint so
24876
- // that all the animated elements within the animation frame will
24877
- // be properly updated and drawn on screen. This is required to
24878
- // ensure that the preparation animation is properly flushed so that
24879
- // the active state picks up from there. DO NOT REMOVE THIS LINE.
24880
- // DO NOT OPTIMIZE THIS LINE. THE MINIFIER WILL REMOVE IT OTHERWISE WHICH
24881
- // WILL RESULT IN AN UNPREDICTABLE BUG THAT IS VERY HARD TO TRACK DOWN AND
24882
- // WILL TAKE YEARS AWAY FROM YOUR LIFE.
25378
+ rafScheduler._waitUntilQuiet(() => {
25379
+ animateCache._flush();
24883
25380
 
24884
- const pageWidth = document.body.offsetWidth + 1;
25381
+ // Forces synchronous style & layout flush.
25382
+ // Required to commit animation prep state before activation.
25383
+ document.documentElement.getBoundingClientRect();
24885
25384
 
24886
25385
  // we use a for loop to ensure that if the queue is changed
24887
25386
  // during this looping then it will consider new requests
24888
25387
  for (let i = 0; i < rafWaitQueue.length; i++) {
24889
- rafWaitQueue[i](pageWidth);
25388
+ rafWaitQueue[i]();
24890
25389
  }
24891
25390
  rafWaitQueue.length = 0;
24892
25391
  });
@@ -24913,6 +25412,10 @@
24913
25412
  return timings;
24914
25413
  }
24915
25414
 
25415
+ /**
25416
+ * @param {HTMLElement} element
25417
+ * @param {ng.AnimationOptions} initialOptions
25418
+ */
24916
25419
  return function init(element, initialOptions) {
24917
25420
  // all of the animation functions should create
24918
25421
  // a copy of the options data, however, if a
@@ -24920,9 +25423,11 @@
24920
25423
  let delayStyle;
24921
25424
 
24922
25425
  // we should stick to using that
24923
- let options = initialOptions || {
24924
- $$skipPreparationClasses: false,
24925
- };
25426
+ let options =
25427
+ initialOptions ||
25428
+ /** @type {ng.AnimationOptions}}*/ ({
25429
+ $$skipPreparationClasses: false,
25430
+ });
24926
25431
 
24927
25432
  if (!options.$$prepared) {
24928
25433
  options = prepareAnimationOptions(structuredClone(options));
@@ -24968,10 +25473,11 @@
24968
25473
  return closeAndReturnNoopAnimator();
24969
25474
  }
24970
25475
 
24971
- const method =
25476
+ const method = /** @type {string} */ (
24972
25477
  options.event && isArray(options.event)
24973
25478
  ? options.event.join(" ")
24974
- : options.event;
25479
+ : options.event
25480
+ );
24975
25481
 
24976
25482
  const isStructural = method && options.structural;
24977
25483
 
@@ -25027,21 +25533,23 @@
25027
25533
 
25028
25534
  let stagger;
25029
25535
 
25030
- let cacheKey = $$animateCache.cacheKey(
25536
+ let cacheKey = animateCache._cacheKey(
25031
25537
  node,
25032
25538
  method,
25033
25539
  options.addClass,
25034
25540
  options.removeClass,
25035
25541
  );
25036
25542
 
25037
- if ($$animateCache.containsCachedAnimationWithoutDuration(cacheKey)) {
25543
+ if (animateCache._containsCachedAnimationWithoutDuration(cacheKey)) {
25038
25544
  preparationClasses = null;
25039
25545
 
25040
25546
  return closeAndReturnNoopAnimator();
25041
25547
  }
25042
25548
 
25043
- if (options.stagger > 0) {
25044
- const staggerVal = parseFloat(options.stagger);
25549
+ if (/** @type {number} */ (options.stagger) > 0) {
25550
+ const staggerVal = parseFloat(
25551
+ /** @type {string} */ (options.stagger),
25552
+ );
25045
25553
 
25046
25554
  stagger = {
25047
25555
  transitionDelay: staggerVal,
@@ -25073,7 +25581,7 @@
25073
25581
  temporaryStyles.push(transitionStyle);
25074
25582
  }
25075
25583
 
25076
- if (options.duration >= 0) {
25584
+ if (/** @type {number} */ (options.duration) >= 0) {
25077
25585
  applyOnlyDuration = node.style.transition.length > 0;
25078
25586
  const durationStyle = getCssTransitionDurationStyle(
25079
25587
  options.duration,
@@ -25096,7 +25604,7 @@
25096
25604
  const itemIndex = stagger
25097
25605
  ? options.staggerIndex >= 0
25098
25606
  ? options.staggerIndex
25099
- : $$animateCache.count(cacheKey)
25607
+ : animateCache._count(cacheKey)
25100
25608
  : 0;
25101
25609
 
25102
25610
  const isFirst = itemIndex === 0;
@@ -25107,7 +25615,7 @@
25107
25615
  // transition delay to allow for the transition to naturally do it's thing. The beauty here is
25108
25616
  // that if there is no transition defined then nothing will happen and this will also allow
25109
25617
  // other transitions to be stacked on top of each other without any chopping them out.
25110
- if (isFirst && !options.skipBlocking) {
25618
+ if (isFirst) {
25111
25619
  blockTransitions(node, SAFE_FAST_FORWARD_DURATION_VALUE);
25112
25620
  }
25113
25621
 
@@ -25139,7 +25647,7 @@
25139
25647
 
25140
25648
  if (flags.applyTransitionDuration || flags.applyAnimationDuration) {
25141
25649
  maxDuration = options.duration
25142
- ? parseFloat(options.duration)
25650
+ ? parseFloat(/** @type {string} */ (options.duration))
25143
25651
  : maxDuration;
25144
25652
 
25145
25653
  if (flags.applyTransitionDuration) {
@@ -25194,13 +25702,11 @@
25194
25702
  maxDelayTime = maxDelay * ONE_SECOND;
25195
25703
  maxDurationTime = maxDuration * ONE_SECOND;
25196
25704
 
25197
- if (!options.skipBlocking) {
25198
- flags.blockTransition = timings.transitionDuration > 0;
25199
- flags.blockKeyframeAnimation =
25200
- timings.animationDuration > 0 &&
25201
- stagger.animationDelay > 0 &&
25202
- stagger.animationDuration === 0;
25203
- }
25705
+ flags.blockTransition = timings.transitionDuration > 0;
25706
+ flags.blockKeyframeAnimation =
25707
+ timings.animationDuration > 0 &&
25708
+ stagger.animationDelay > 0 &&
25709
+ stagger.animationDuration === 0;
25204
25710
 
25205
25711
  if (options.from) {
25206
25712
  if (options.cleanupStyles) {
@@ -25475,7 +25981,7 @@
25475
25981
  );
25476
25982
 
25477
25983
  if (flags.recalculateTimingStyles) {
25478
- cacheKey = $$animateCache.cacheKey(
25984
+ cacheKey = animateCache._cacheKey(
25479
25985
  node,
25480
25986
  method,
25481
25987
  options.addClass,
@@ -25942,8 +26448,7 @@
25942
26448
  // strip comments
25943
26449
 
25944
26450
  let element = isArray(originalElement)
25945
- ? // @ts-ignore
25946
- originalElement.filter((x) => x.nodeName !== "#comment")[0]
26451
+ ? originalElement.filter((x) => x.nodeName !== "#comment")[0]
25947
26452
  : originalElement;
25948
26453
 
25949
26454
  const node = element;
@@ -26450,6 +26955,9 @@
26450
26955
  function ($injector) {
26451
26956
  const applyAnimationClasses = applyAnimationClassesFactory();
26452
26957
 
26958
+ /**
26959
+ *
26960
+ */
26453
26961
  return function animateJs(element, event, classes, options) {
26454
26962
  // Optional arguments
26455
26963
  if (arguments.length === 3 && isObject(classes)) {
@@ -26651,16 +27159,29 @@
26651
27159
  function AnimationProvider() {
26652
27160
  const NG_ANIMATE_REF_ATTR = "ng-animate-ref";
26653
27161
 
27162
+ /**
27163
+ * @type {string[]}
27164
+ */
26654
27165
  const drivers = (this.drivers = []);
26655
27166
 
27167
+ /**
27168
+ * @param {Element | Node} element
27169
+ * @param {AnimateRunner} runner
27170
+ */
26656
27171
  function setRunner(element, runner) {
26657
27172
  setCacheData(element, RUNNER_STORAGE_KEY, runner);
26658
27173
  }
26659
27174
 
27175
+ /**
27176
+ * @param {Element} element
27177
+ */
26660
27178
  function removeRunner(element) {
26661
27179
  deleteCacheData(element, RUNNER_STORAGE_KEY);
26662
27180
  }
26663
27181
 
27182
+ /**
27183
+ * @param {Element} element
27184
+ */
26664
27185
  function getRunner(element) {
26665
27186
  return getCacheData(element, RUNNER_STORAGE_KEY);
26666
27187
  }
@@ -26668,17 +27189,19 @@
26668
27189
  this.$get = [
26669
27190
  $injectTokens._rootScope,
26670
27191
  $injectTokens._injector,
26671
- $injectTokens._rAFScheduler,
26672
- $injectTokens._animateCache,
26673
27192
  /**
26674
27193
  *
26675
27194
  * @param {ng.RootScopeService} $rootScope
26676
27195
  * @param {ng.InjectorService} $injector
26677
- * @param {import("./raf-scheduler.js").RafScheduler} $$rAFScheduler
26678
- * @param {*} $$animateCache
26679
27196
  * @returns
26680
27197
  */
26681
- function ($rootScope, $injector, $$rAFScheduler, $$animateCache) {
27198
+ function ($rootScope, $injector) {
27199
+ /**
27200
+ * @type {{
27201
+ // this data is used by the postDigest code and passed into
27202
+ // the driver step function
27203
+ element: any; classes: string; event: any; structural: boolean; options: any; beforeStart: () => void; close: (rejected: any) => void; }[]}
27204
+ */
26682
27205
  const animationQueue = [];
26683
27206
 
26684
27207
  const applyAnimationClasses = applyAnimationClassesFactory();
@@ -26877,7 +27400,7 @@
26877
27400
 
26878
27401
  extraClasses =
26879
27402
  (extraClasses ? `${extraClasses} ` : "") + NG_ANIMATE_CLASSNAME;
26880
- const cacheKey = $$animateCache.cacheKey(
27403
+ const cacheKey = animateCache._cacheKey(
26881
27404
  fromElement,
26882
27405
  animationEntry.event,
26883
27406
  extraClasses,
@@ -26896,9 +27419,7 @@
26896
27419
  // and it's in fact an invalid animation (something that has duration = 0)
26897
27420
  // then we should skip all the heavy work from here on
26898
27421
  if (
26899
- $$animateCache.containsCachedAnimationWithoutDuration(
26900
- cacheKey,
26901
- )
27422
+ animateCache._containsCachedAnimationWithoutDuration(cacheKey)
26902
27423
  ) {
26903
27424
  closeFn();
26904
27425
 
@@ -26972,8 +27493,10 @@
26972
27493
  }
26973
27494
  }
26974
27495
  }
26975
- // @ts-ignore
26976
- $$rAFScheduler(finalAnimations);
27496
+
27497
+ const flatFinalAnimations = finalAnimations.flat();
27498
+
27499
+ rafScheduler._schedule(flatFinalAnimations);
26977
27500
  });
26978
27501
 
26979
27502
  return runner;
@@ -27171,7 +27694,7 @@
27171
27694
  }
27172
27695
 
27173
27696
  function handleDestroyedElement() {
27174
- (event !== "leave" || !options.$$domOperationFired) &&
27697
+ (event !== "leave" || !options._domOperationFired) &&
27175
27698
  getRunner(elementParam)?.end();
27176
27699
  }
27177
27700
 
@@ -27195,191 +27718,6 @@
27195
27718
  ];
27196
27719
  }
27197
27720
 
27198
- /**
27199
- * @typedef {import('./interface.ts').RafScheduler} RafScheduler
27200
- */
27201
-
27202
- /**
27203
- * Service provider that creates a requestAnimationFrame-based scheduler.
27204
- * @type {ng.ServiceProvider}
27205
- */
27206
- class RafSchedulerProvider {
27207
- constructor() {
27208
- /**
27209
- * Internal task queue, where each item is an array of functions to run.
27210
- * @type {Array<Array<() => void>>}
27211
- */
27212
- this._queue = [];
27213
-
27214
- /**
27215
- * ID of the currently scheduled animation frame (if any).
27216
- * Used for cancellation and tracking.
27217
- * @type {number|null}
27218
- */
27219
- this._cancelFn = null;
27220
- }
27221
-
27222
- /**
27223
- * Processes the next batch of tasks in the animation frame.
27224
- * Executes the first group of functions in the queue, then
27225
- * schedules the next frame if needed.
27226
- */
27227
- _nextTick() {
27228
- if (!this._queue.length) return;
27229
-
27230
- const items = /** @type{Array<() => void>} */ (this._queue.shift());
27231
-
27232
- items.forEach((fn) => fn());
27233
-
27234
- if (!this._cancelFn) {
27235
- this._cancelFn = window.requestAnimationFrame(() => {
27236
- this._cancelFn = null;
27237
- this._nextTick();
27238
- });
27239
- }
27240
- }
27241
-
27242
- /**
27243
- * Returns the scheduler function.
27244
- * This function allows tasks to be queued for execution on future animation frames.
27245
- * It also has helper methods and state attached.
27246
- *
27247
- * @returns {RafScheduler} The scheduler function with `queue` and `waitUntilQuiet`.
27248
- */
27249
- $get() {
27250
- /**
27251
- * The main scheduler function.
27252
- * Accepts an array of functions and schedules them to run in the next available frame(s).
27253
- *
27254
- * @type {RafScheduler}
27255
- */
27256
- const scheduler = (tasks) => {
27257
- // Clone the input array to avoid mutating the original.
27258
- this._queue = this._queue.concat(tasks);
27259
- this._nextTick();
27260
- };
27261
-
27262
- /**
27263
- * Exposes the internal queue to consumers (read-only use preferred).
27264
- * This matches the type signature for RafScheduler.
27265
- */
27266
- scheduler._queue = this._queue;
27267
-
27268
- /**
27269
- * Cancels any pending frame and runs the given function once the frame is idle.
27270
- * Useful for debounced updates.
27271
- *
27272
- * @param {Function} fn - Function to run when the animation frame is quiet.
27273
- */
27274
- scheduler._waitUntilQuiet = (fn) => {
27275
- if (this._cancelFn !== null) {
27276
- window.cancelAnimationFrame(this._cancelFn);
27277
- this._cancelFn = null;
27278
- }
27279
-
27280
- this._cancelFn = window.requestAnimationFrame(() => {
27281
- this._cancelFn = null;
27282
- fn();
27283
- this._nextTick();
27284
- });
27285
- };
27286
-
27287
- return scheduler;
27288
- }
27289
- }
27290
-
27291
- const KEY = "$animId";
27292
-
27293
- let parentCounter = 0;
27294
-
27295
- const cache = new Map();
27296
-
27297
- function animateCache() {
27298
- return {
27299
- /**
27300
- * Generates a unique cache key based on the node's parent and other parameters.
27301
- * @param {HTMLElement} node - The DOM node to generate the cache key for.
27302
- * @param {string} method - The animation method being applied.
27303
- * @param {string} [addClass] - Class to add during the animation.
27304
- * @param {string} [removeClass] - Class to remove during the animation.
27305
- * @returns {string} - The generated cache key.
27306
- */
27307
- cacheKey(node, method, addClass, removeClass) {
27308
- const { parentNode } = node;
27309
-
27310
- const parentID = parentNode[KEY] ?? (parentNode[KEY] = ++parentCounter);
27311
-
27312
- const parts = [parentID, method, node.getAttribute("class")];
27313
-
27314
- if (addClass) parts.push(addClass);
27315
-
27316
- if (removeClass) parts.push(removeClass);
27317
-
27318
- return parts.join(" ");
27319
- },
27320
-
27321
- /**
27322
- * Checks if a cached animation without a duration exists.
27323
- * @param {string} key - The cache key to check.
27324
- * @returns {boolean} - True if an invalid animation is cached, false otherwise.
27325
- */
27326
- containsCachedAnimationWithoutDuration(key) {
27327
- const entry = cache.get(key);
27328
-
27329
- return entry ? !entry.isValid : false;
27330
- },
27331
-
27332
- /**
27333
- * Clears the cache.
27334
- * @returns {void}
27335
- */
27336
- flush() {
27337
- cache.clear();
27338
- },
27339
-
27340
- /**
27341
- * Gets the count of a specific cache entry.
27342
- * @param {string} key - The cache key to count.
27343
- * @returns {number} - The count of the cache entry.
27344
- */
27345
- count(key) {
27346
- return cache.get(key)?.total ?? 0;
27347
- },
27348
-
27349
- /**
27350
- * Retrieves a value associated with a specific cache key.
27351
- * @param {string} key - The cache key to retrieve.
27352
- * @returns {any} - The value associated with the cache key.
27353
- */
27354
- get(key) {
27355
- return cache.get(key)?.value;
27356
- },
27357
-
27358
- /**
27359
- * Adds or updates a cache entry.
27360
- * @param {string} key - The cache key to add or update.
27361
- * @param {any} value - The value to store.
27362
- * @param {boolean} isValid - Whether the cache entry is valid.
27363
- */
27364
- put(key, value, isValid) {
27365
- const entry = cache.get(key);
27366
-
27367
- if (entry) {
27368
- entry.total++;
27369
- entry.value = value;
27370
- } else {
27371
- cache.set(key, { total: 1, value, isValid });
27372
- }
27373
- },
27374
- };
27375
- }
27376
-
27377
- class AnimateCacheProvider {
27378
- $get() {
27379
- return animateCache();
27380
- }
27381
- }
27382
-
27383
27721
  const NG_ANIMATE_SHIM_CLASS_NAME = "ng-animate-shim";
27384
27722
 
27385
27723
  const NG_ANIMATE_ANCHOR_CLASS_NAME = "ng-anchor";
@@ -27389,9 +27727,16 @@
27389
27727
  const NG_IN_ANCHOR_CLASS_NAME = "ng-anchor-in";
27390
27728
 
27391
27729
  AnimateCssDriverProvider.$inject = provider([$injectTokens._animation]);
27730
+
27731
+ /**
27732
+ * @param {import("./animation.js").AnimationProvider} $$animationProvider
27733
+ */
27392
27734
  function AnimateCssDriverProvider($$animationProvider) {
27393
27735
  $$animationProvider.drivers.push($injectTokens._animateCssDriver);
27394
27736
 
27737
+ /**
27738
+ * @param {Element} node
27739
+ */
27395
27740
  function isDocumentFragment(node) {
27396
27741
  // eslint-disable-next-line no-magic-numbers
27397
27742
  return node.parentNode && node.parentNode.nodeType === 11;
@@ -27797,7 +28142,7 @@
27797
28142
  function $$AnimateChildrenDirective($interpolate) {
27798
28143
  return {
27799
28144
  link(scope, element, attrs) {
27800
- const val = attrs.ngAnimateChildren;
28145
+ const val = /** @type {string} */ (attrs.ngAnimateChildren);
27801
28146
 
27802
28147
  if (isString(val) && val.length === 0) {
27803
28148
  // empty attribute
@@ -27805,13 +28150,21 @@
27805
28150
  } else {
27806
28151
  // Interpolate and set the value, so that it is available to
27807
28152
  // animations that run right after compilation
27808
- setData($interpolate(val)(scope));
28153
+ setData(
28154
+ /** @type {import("../core/interpolate/interface.js").InterpolationFunction} */ (
28155
+ $interpolate(val)
28156
+ )(scope),
28157
+ );
27809
28158
  attrs.$observe("ngAnimateChildren", setData);
27810
28159
  }
27811
28160
 
28161
+ /**
28162
+ * @param {string} [value]
28163
+ */
27812
28164
  function setData(value) {
27813
- value = value === "on" || value === "true";
27814
- setCacheData(element, NG_ANIMATE_CHILDREN_DATA, value);
28165
+ const res = value === "on" || value === "true";
28166
+
28167
+ setCacheData(element, NG_ANIMATE_CHILDREN_DATA, res);
27815
28168
  }
27816
28169
  },
27817
28170
  };
@@ -27935,10 +28288,11 @@
27935
28288
  * var foo = { a: 1, b: 2, c: 3 };
27936
28289
  * var ab = pick(foo, ['a', 'b']); // { a: 1, b: 2 }
27937
28290
  * ```
27938
- * @param obj the source object
27939
- * @param propNames an Array of strings, which are the whitelisted property names
28291
+ * @param {any} obj the source object
28292
+ * @param {string | any[]} propNames an Array of strings, which are the whitelisted property names
27940
28293
  */
27941
28294
  function pick(obj, propNames) {
28295
+ /** @type {Record<string, any>} */
27942
28296
  const objCopy = {};
27943
28297
 
27944
28298
  for (const _prop in obj) {
@@ -27949,30 +28303,44 @@
27949
28303
 
27950
28304
  return objCopy;
27951
28305
  }
28306
+
27952
28307
  /**
27953
28308
  * Return a copy of the object omitting the blacklisted properties.
27954
- *
27955
- * @example
27956
- * ```
27957
- *
27958
- * var foo = { a: 1, b: 2, c: 3 };
27959
- * var ab = omit(foo, ['a', 'b']); // { c: 3 }
27960
- * ```
27961
- * @param obj the source object
27962
- * @param propNames an Array of strings, which are the blacklisted property names
28309
+ * @example ```
28310
+
28311
+ var foo = { a: 1, b: 2, c: 3 };
28312
+ var ab = omit(foo, ['a', 'b']); // { c: 3 }
28313
+ ```
28314
+ * @param {{ [x: string]: any; }} obj the source object
28315
+ * @param {string | any[]} propNames an Array of strings, which are the blacklisted property names
27963
28316
  */
27964
28317
  function omit(obj, propNames) {
27965
28318
  return Object.keys(obj)
27966
28319
  .filter((x) => !propNames.includes(x))
27967
- .reduce((acc, key) => ((acc[key] = obj[key]), acc), {});
28320
+ .reduce(
28321
+ /**
28322
+ * @param {Record<string, any>} acc
28323
+ * @param {string} key
28324
+ * */ (acc, key) => ((acc[key] = obj[key]), acc),
28325
+ {},
28326
+ );
27968
28327
  }
27969
28328
 
27970
- /** Filters an Array or an Object's properties based on a predicate */
28329
+ /**
28330
+ * Filters an Array or an Object's properties based on a predicate
28331
+ * @param {Record<string, any> | ArrayLike<any>} collection
28332
+ * @param {{ (x: any): boolean; (item: any): boolean; (val: any, key: any): boolean; (arg0: any, arg1: string): any; }} callback
28333
+ */
27971
28334
  function filter(collection, callback) {
27972
- const arr = isArray(collection),
27973
- result = arr ? [] : {};
28335
+ const arr = isArray(collection);
27974
28336
 
27975
- const accept = arr ? (x) => result.push(x) : (x, key) => (result[key] = x);
28337
+ /** @type {Record<string, any>} */
28338
+ const result = arr ? [] : {};
28339
+
28340
+ const accept = arr
28341
+ ? (/** @type {any} */ x) => result.push(x)
28342
+ : (/** @type {any} */ x, /** @type {string | number} */ key) =>
28343
+ (result[key] = x);
27976
28344
 
27977
28345
  entries(collection).forEach(([i, item]) => {
27978
28346
  if (callback(item, i)) accept(item, i);
@@ -27981,8 +28349,15 @@
27981
28349
  return result;
27982
28350
  }
27983
28351
 
27984
- /** Finds an object from an array, or a property of an object, that matches a predicate */
28352
+ /**
28353
+ * Finds an object from an array, or a property of an object, that matches a predicate
28354
+ * @param {{ [s: string]: any; } | ArrayLike<any>} collection
28355
+ * @param {function} callback
28356
+ */
27985
28357
  function find(collection, callback) {
28358
+ /**
28359
+ * @type {any}
28360
+ */
27986
28361
  let result;
27987
28362
 
27988
28363
  entries(collection).forEach(([i, item]) => {
@@ -27994,10 +28369,30 @@
27994
28369
  return result;
27995
28370
  }
27996
28371
 
27997
- /** Maps an array or object properties using a callback function */
28372
+ /**
28373
+ * Maps over an array or object and returns a new collection
28374
+ * with the same shape.
28375
+ *
28376
+ * @template T
28377
+ * @template R
28378
+ * @param {T[] | Record<string, T>} collection
28379
+ * @param {(value: T, key: string | number) => R} callback
28380
+ * @param {R[] | Record<string, R>} [target]
28381
+ * @returns {R[] | Record<string, R>}
28382
+ */
27998
28383
  function map(collection, callback, target) {
27999
28384
  target = target || (isArray(collection) ? [] : {});
28000
- entries(collection).forEach(([i, item]) => (target[i] = callback(item, i)));
28385
+
28386
+ entries(collection).forEach(([i, item]) => {
28387
+ if (isArray(target)) {
28388
+ // Convert string key to number safely
28389
+ const index = Number(i);
28390
+
28391
+ target[index] = callback(item, index);
28392
+ } else {
28393
+ target[i] = callback(item, i);
28394
+ }
28395
+ });
28001
28396
 
28002
28397
  return target;
28003
28398
  }
@@ -28015,7 +28410,8 @@
28015
28410
  * vals.reduce(allTrueR, true); // false
28016
28411
  * ```
28017
28412
  */
28018
- const allTrueR = (memo, elem) => memo && elem;
28413
+ const allTrueR = (/** @type {any} */ memo, /** @type {any} */ elem) =>
28414
+ memo && elem;
28019
28415
  /**
28020
28416
  * Reduce function that returns true if any of the values are truthy.
28021
28417
  *
@@ -28029,29 +28425,39 @@
28029
28425
  * vals.reduce(anyTrueR, true); // true
28030
28426
  * ```
28031
28427
  */
28032
- const anyTrueR = (memo, elem) => memo || elem;
28428
+ const anyTrueR = (/** @type {any} */ memo, /** @type {any} */ elem) =>
28429
+ memo || elem;
28430
+
28033
28431
  /**
28034
28432
  * Reduce function which un-nests a single level of arrays
28035
- * @example
28036
- * ```
28037
28433
  *
28434
+ * @template T
28435
+ * @param {T[]} memo
28436
+ * @param {T | T[]} elem
28437
+ * @returns {T[]}
28438
+ *
28439
+ * @example
28038
28440
  * let input = [ [ "a", "b" ], [ "c", "d" ], [ [ "double", "nested" ] ] ];
28039
- * input.reduce(unnestR, []) // [ "a", "b", "c", "d", [ "double, "nested" ] ]
28040
- * ```
28441
+ * input.reduce(unnestR, []) // [ "a", "b", "c", "d", [ "double", "nested" ] ]
28041
28442
  */
28042
28443
  const unnestR = (memo, elem) => memo.concat(elem);
28444
+
28043
28445
  /**
28044
28446
  * Reduce function that pushes an object to an array, then returns the array.
28045
28447
  * Mostly just for [[flattenR]] and [[uniqR]]
28448
+ * @param {any[]} arr
28449
+ * @param {unknown} obj
28046
28450
  */
28047
28451
  function pushR(arr, obj) {
28048
28452
  arr.push(obj);
28049
28453
 
28050
28454
  return arr;
28051
28455
  }
28456
+
28052
28457
  /** Reduce function that filters out duplicates */
28053
- const uniqR = (acc, token) =>
28458
+ const uniqR = (/** @type {any[]} */ acc, /** @type {any} */ token) =>
28054
28459
  acc.includes(token) ? acc : pushR(acc, token);
28460
+
28055
28461
  /**
28056
28462
  * Return a new array with a single level of arrays unnested.
28057
28463
  *
@@ -28062,7 +28468,7 @@
28062
28468
  * unnest(input) // [ "a", "b", "c", "d", [ "double, "nested" ] ]
28063
28469
  * ```
28064
28470
  */
28065
- const unnest = (arr) => arr.reduce(unnestR, []);
28471
+ const unnest = (/** @type {any[]} */ arr) => arr.reduce(unnestR, []);
28066
28472
 
28067
28473
  /**
28068
28474
  * Given a .filter Predicate, builds a .filter Predicate which throws an error if any elements do not pass.
@@ -28079,6 +28485,11 @@
28079
28485
  */
28080
28486
  const assertPredicate = assertFn;
28081
28487
 
28488
+ /**
28489
+ * @param {(arg0: any) => any} predicateOrMap
28490
+ * @param {string} errMsg
28491
+ * @return {(obj:any) => any}
28492
+ */
28082
28493
  function assertFn(predicateOrMap, errMsg = "assert failure") {
28083
28494
  return (obj) => {
28084
28495
  const result = predicateOrMap(obj);
@@ -28137,25 +28548,26 @@
28137
28548
 
28138
28549
  return result;
28139
28550
  }
28551
+
28140
28552
  /**
28141
28553
  * Reduce function which builds an object from an array of [key, value] pairs.
28142
28554
  *
28143
28555
  * Each iteration sets the key/val pair on the memo object, then returns the memo for the next iteration.
28144
28556
  *
28145
28557
  * Each keyValueTuple should be an array with values [ key: string, value: any ]
28146
- *
28147
- * @example
28148
- * ```
28149
- *
28150
- * var pairs = [ ["fookey", "fooval"], ["barkey", "barval"] ]
28151
- *
28152
- * var pairsToObj = pairs.reduce((memo, pair) => applyPairs(memo, pair), {})
28153
- * // pairsToObj == { fookey: "fooval", barkey: "barval" }
28154
- *
28155
- * // Or, more simply:
28156
- * var pairsToObj = pairs.reduce(applyPairs, {})
28157
- * // pairsToObj == { fookey: "fooval", barkey: "barval" }
28158
- * ```
28558
+ * @example ```
28559
+
28560
+ var pairs = [ ["fookey", "fooval"], ["barkey", "barval"] ]
28561
+
28562
+ var pairsToObj = pairs.reduce((memo, pair) => applyPairs(memo, pair), {})
28563
+ // pairsToObj == { fookey: "fooval", barkey: "barval" }
28564
+
28565
+ // Or, more simply:
28566
+ var pairsToObj = pairs.reduce(applyPairs, {})
28567
+ // pairsToObj == { fookey: "fooval", barkey: "barval" }
28568
+ ```
28569
+ * @param {{ [x: string]: any; }} memo
28570
+ * @param {any[]} keyValTuple
28159
28571
  */
28160
28572
  function applyPairs(memo, keyValTuple) {
28161
28573
  let key, value;
@@ -28180,6 +28592,8 @@
28180
28592
 
28181
28593
  /**
28182
28594
  * shallow copy from src to dest
28595
+ * @param {any} src
28596
+ * @param {any} dest
28183
28597
  */
28184
28598
  function copy(src, dest) {
28185
28599
  if (dest) Object.keys(dest).forEach((key) => delete dest[key]);
@@ -29243,12 +29657,12 @@
29243
29657
  * let arr = ["foo", "bar", 1, "baz", "", "qux" ];
29244
29658
  * arr.reduce(joinNeighborsR, []) // ["foobar", 1, "bazqux" ]
29245
29659
  * ```
29246
- * @param {string | any[]} acc
29660
+ * @param {any[]} acc
29247
29661
  * @param {unknown} str
29248
29662
  */
29249
29663
  function joinNeighborsR(acc, str) {
29250
- if (isString(tail(/** @type {string} */ (acc))) && isString(str))
29251
- return acc.slice(0, -1).concat(tail(/** @type {string} */ (acc)) + str);
29664
+ if (isString(tail(acc)) && isString(str))
29665
+ return acc.slice(0, -1).concat(tail(acc) + str);
29252
29666
 
29253
29667
  return pushR(acc, str);
29254
29668
  }
@@ -29860,13 +30274,13 @@
29860
30274
 
29861
30275
  function unwrapShorthand(cfg) {
29862
30276
  cfg = isShorthand(cfg) ? { value: cfg } : cfg;
29863
- getStaticDefaultValue.__cacheable = true;
30277
+ getStaticDefaultValue._cacheable = true;
29864
30278
  function getStaticDefaultValue() {
29865
30279
  return cfg.value;
29866
30280
  }
29867
- const $$fn = isInjectable(cfg.value) ? cfg.value : getStaticDefaultValue;
30281
+ const _fn = isInjectable(cfg.value) ? cfg.value : getStaticDefaultValue;
29868
30282
 
29869
- return Object.assign(cfg, { $$fn });
30283
+ return Object.assign(cfg, { _fn });
29870
30284
  }
29871
30285
 
29872
30286
  function getType(cfg, urlType, location, id, paramTypes) {
@@ -30011,7 +30425,7 @@
30011
30425
  throw new Error(
30012
30426
  "Injectable functions cannot be called at configuration time",
30013
30427
  );
30014
- const defaultValue = window.angular.$injector.invoke(this.config.$$fn);
30428
+ const defaultValue = window.angular.$injector.invoke(this.config._fn);
30015
30429
 
30016
30430
  if (
30017
30431
  defaultValue !== null &&
@@ -30022,7 +30436,7 @@
30022
30436
  `Default value (${defaultValue}) for parameter '${this.id}' is not an instance of ParamType (${this.type.name})`,
30023
30437
  );
30024
30438
 
30025
- if (this.config.$$fn.__cacheable) {
30439
+ if (this.config._fn._cacheable) {
30026
30440
  this._defaultValueCache = { defaultValue };
30027
30441
  }
30028
30442
 
@@ -35248,33 +35662,43 @@
35248
35662
  return { param, value, isValid, isDefaultValue, squash, encoded };
35249
35663
  }
35250
35664
  // Build up the path-portion from the list of static segments and parameters
35251
- const pathString = pathSegmentsAndParams.reduce((acc, x) => {
35252
- // The element is a static segment (a raw string); just append it
35253
- if (isString(x)) return acc + x;
35254
- // Otherwise, it's a ParamDetails.
35255
- const { squash, encoded, param } = x;
35665
+ /** @type {string} */
35666
+ const pathString = /** @type {string} */ (
35667
+ pathSegmentsAndParams.reduce(
35668
+ /** @param {string} acc */ (acc, x) => {
35669
+ // The element is a static segment (a raw string); just append it
35670
+ if (isString(x)) return acc + x;
35671
+ // Otherwise, it's a ParamDetails.
35672
+ const { squash, encoded, param } = x;
35256
35673
 
35257
- // If squash is === true, try to remove a slash from the path
35258
- if (squash === true) return acc.match(/\/$/) ? acc.slice(0, -1) : acc;
35674
+ // If squash is === true, try to remove a slash from the path
35675
+ if (squash === true) return acc.match(/\/$/) ? acc.slice(0, -1) : acc;
35259
35676
 
35260
- // If squash is a string, use the string for the param value
35261
- if (isString(squash)) return acc + squash;
35677
+ // If squash is a string, use the string for the param value
35678
+ if (isString(squash)) return acc + squash;
35262
35679
 
35263
- if (squash !== false) return acc; // ?
35680
+ if (squash !== false) return acc; // ?
35264
35681
 
35265
- if (isNullOrUndefined(encoded)) return acc;
35682
+ if (isNullOrUndefined(encoded)) return acc;
35266
35683
 
35267
- // If this parameter value is an array, encode the value using encodeDashes
35268
- if (isArray(encoded)) return acc + map(encoded, encodeDashes).join("-");
35684
+ // If this parameter value is an array, encode the value using encodeDashes
35685
+ if (isArray(encoded))
35686
+ return (
35687
+ acc +
35688
+ /** @type {string[]} */ (map(encoded, encodeDashes)).join("-")
35689
+ );
35269
35690
 
35270
- // If the parameter type is "raw", then do not encodeURIComponent
35271
- if (param.raw) {
35272
- return acc + encoded;
35273
- }
35691
+ // If the parameter type is "raw", then do not encodeURIComponent
35692
+ if (param.raw) {
35693
+ return acc + encoded;
35694
+ }
35274
35695
 
35275
- // Encode the value
35276
- return acc + encodeURIComponent(encoded);
35277
- }, "");
35696
+ // Encode the value
35697
+ return acc + encodeURIComponent(encoded);
35698
+ },
35699
+ "",
35700
+ )
35701
+ );
35278
35702
 
35279
35703
  // Build the query string by applying parameter values (array or regular)
35280
35704
  // then mapping to key=value, then flattening and joining using "&"
@@ -40025,7 +40449,6 @@
40025
40449
  $$animateCssDriver: AnimateCssDriverProvider,
40026
40450
  $$animateJs: AnimateJsProvider,
40027
40451
  $$animateJsDriver: AnimateJsDriverProvider,
40028
- $$animateCache: AnimateCacheProvider,
40029
40452
  $$animateQueue: AnimateQueueProvider,
40030
40453
  $controller: ControllerProvider,
40031
40454
  $cookie: CookieProvider,
@@ -40037,7 +40460,6 @@
40037
40460
  $location: LocationProvider,
40038
40461
  $log: LogProvider,
40039
40462
  $parse: ParseProvider,
40040
- $$rAFScheduler: RafSchedulerProvider,
40041
40463
  $rest: RestProvider,
40042
40464
  $rootScope: RootScopeProvider,
40043
40465
  $router: RouterProvider,
@@ -40102,7 +40524,7 @@
40102
40524
  * @public
40103
40525
  * @type {string} `version` from `package.json`
40104
40526
  */
40105
- this.version = "0.16.1"; //inserted via rollup plugin
40527
+ this.version = "0.17.0"; //inserted via rollup plugin
40106
40528
 
40107
40529
  /**
40108
40530
  * Gets the controller instance for a given element, if exists. Defaults to "ngControllerController"
@@ -40205,6 +40627,25 @@
40205
40627
  });
40206
40628
  }
40207
40629
 
40630
+ /**
40631
+ * @param {CustomEvent} event
40632
+ */
40633
+ dispatchEvent(event) {
40634
+ const $parse = this.$injector.get($injectTokens._parse);
40635
+
40636
+ const injectable = event.type;
40637
+
40638
+ const target = this.$injector.has(injectable)
40639
+ ? this.$injector.get(injectable)
40640
+ : this.getScopeByName(injectable);
40641
+
40642
+ if (!target) return false;
40643
+
40644
+ $parse(event.detail)(target);
40645
+
40646
+ return true;
40647
+ }
40648
+
40208
40649
  /**
40209
40650
  * Use this function to manually start up AngularTS application.
40210
40651
  *