@angular-wave/angular.ts 0.9.7 → 0.9.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,4 +1,4 @@
1
- /* Version: 0.9.7 - October 26, 2025 04:17:19 */
1
+ /* Version: 0.9.9 - October 28, 2025 22:08:29 */
2
2
  const VALID_CLASS = "ng-valid";
3
3
  const INVALID_CLASS = "ng-invalid";
4
4
  const PRISTINE_CLASS = "ng-pristine";
@@ -1810,6 +1810,7 @@ const $injectTokens = Object.freeze({
1810
1810
  $sceDelegate: "$sceDelegate",
1811
1811
  $state: "$state",
1812
1812
  $stateRegistry: "$stateRegistry",
1813
+ $sse: "$sse",
1813
1814
  $$sanitizeUri: "$$sanitizeUri",
1814
1815
  $$sanitizeUriProvider: "$$sanitizeUriProvider",
1815
1816
  $templateCache: "$templateCache",
@@ -4014,22 +4015,26 @@ function SceProvider() {
4014
4015
  */
4015
4016
  const ngEventDirectives = {};
4016
4017
 
4017
- "click copy cut dblclick focus blur keydown keyup load mousedown mouseenter mouseleave mousemove mouseout mouseover mouseup paste submit touchstart touchend touchmove"
4018
+ "click copy cut dblclick focus blur keydown keyup load mousedown mouseenter mouseleave mousemove mouseout mouseover mouseup paste submit touchstart touchend touchmove offline online"
4018
4019
  .split(" ")
4019
4020
  .forEach((eventName) => {
4020
4021
  const directiveName = directiveNormalize(`ng-${eventName}`);
4021
4022
  ngEventDirectives[directiveName] = [
4022
- "$parse",
4023
- "$exceptionHandler",
4023
+ $injectTokens.$parse,
4024
+ $injectTokens.$exceptionHandler,
4025
+ $injectTokens.$window,
4026
+
4024
4027
  /**
4025
4028
  * @param {import("../../core/parse/interface.ts").ParseService} $parse
4026
4029
  * @param {ng.ExceptionHandlerService} $exceptionHandler
4030
+ * @param {ng.WindowService} $window
4027
4031
  * @returns
4028
4032
  */
4029
- ($parse, $exceptionHandler) => {
4033
+ ($parse, $exceptionHandler, $window) => {
4030
4034
  return createEventDirective(
4031
4035
  $parse,
4032
4036
  $exceptionHandler,
4037
+ $window,
4033
4038
  directiveName,
4034
4039
  eventName,
4035
4040
  );
@@ -4041,6 +4046,7 @@ const ngEventDirectives = {};
4041
4046
  *
4042
4047
  * @param {ng.ParseService} $parse
4043
4048
  * @param {ng.ExceptionHandlerService} $exceptionHandler
4049
+ * @param {ng.WindowService} $window
4044
4050
  * @param {string} directiveName
4045
4051
  * @param {string} eventName
4046
4052
  * @returns {ng.Directive}
@@ -4048,6 +4054,7 @@ const ngEventDirectives = {};
4048
4054
  function createEventDirective(
4049
4055
  $parse,
4050
4056
  $exceptionHandler,
4057
+ $window,
4051
4058
  directiveName,
4052
4059
  eventName,
4053
4060
  ) {
@@ -4055,14 +4062,58 @@ function createEventDirective(
4055
4062
  restrict: "A",
4056
4063
  compile(_element, attr) {
4057
4064
  const fn = $parse(attr[directiveName]);
4058
- return function ngEventHandler(scope, element) {
4059
- element.addEventListener(eventName, (event) => {
4065
+ return (scope, element) => {
4066
+ const handler = (event) => {
4060
4067
  try {
4061
4068
  fn(scope, { $event: event });
4062
4069
  } catch (error) {
4063
4070
  $exceptionHandler(error);
4064
4071
  }
4065
- });
4072
+ };
4073
+ element.addEventListener(eventName, handler);
4074
+
4075
+ scope.$on("$destroy", () =>
4076
+ element.removeEventListener(eventName, handler),
4077
+ );
4078
+ };
4079
+ },
4080
+ };
4081
+ }
4082
+
4083
+ /**
4084
+ *
4085
+ * @param {ng.ParseService} $parse
4086
+ * @param {ng.ExceptionHandlerService} $exceptionHandler
4087
+ * @param {ng.WindowService} $window
4088
+ * @param {string} directiveName
4089
+ * @param {string} eventName
4090
+ * @returns {ng.Directive}
4091
+ */
4092
+ function createWindowEventDirective(
4093
+ $parse,
4094
+ $exceptionHandler,
4095
+ $window,
4096
+ directiveName,
4097
+ eventName,
4098
+ ) {
4099
+ return {
4100
+ restrict: "A",
4101
+ compile(_element, attr) {
4102
+ const fn = $parse(attr[directiveName]);
4103
+ return (scope) => {
4104
+ const handler = (event) => {
4105
+ try {
4106
+ fn(scope, { $event: event });
4107
+ } catch (error) {
4108
+ $exceptionHandler(error);
4109
+ }
4110
+ };
4111
+
4112
+ $window.addEventListener(eventName, handler);
4113
+
4114
+ scope.$on("$destroy", () =>
4115
+ $window.removeEventListener(eventName, handler),
4116
+ );
4066
4117
  };
4067
4118
  },
4068
4119
  };
@@ -4431,91 +4482,6 @@ function ngObserveDirective(source, prop) {
4431
4482
  };
4432
4483
  }
4433
4484
 
4434
- /**
4435
- * A function passed as the fifth argument to a {@type PublicLinkFn} link function.
4436
- * It behaves like a linking function, with the `scope` argument automatically created
4437
- * as a new child of the transcluded parent scope.
4438
- *
4439
- * The function returns the DOM content to be injected (transcluded) into the directive.
4440
- *
4441
- * @callback TranscludeFn
4442
- * @param {Element | Node | ChildNode | NodeList | Node[]} [clone] - The DOM node to be inserted into the transcluded directive.
4443
- * @param {import("../scope/scope.js").Scope} [scope] - The new child scope created from the transcluded parent.
4444
- * @returns void
4445
-
4446
- /**
4447
- * A specialized version of {@link TranscludeFn} with the scope argument already bound.
4448
- * This function requires no parameters and returns the same result as {@link TranscludeFn}.
4449
- *
4450
- * @typedef {() => Element|Node} BoundTranscludeFn
4451
- */
4452
-
4453
- /**
4454
- * @typedef {Object} SimpleChange
4455
- * @property {any} currentValue
4456
- * @property {boolean} firstChange
4457
- */
4458
-
4459
- /**
4460
- * @description A function returned by the '$compile' service that links a compiled template to a scope.
4461
- *
4462
- * @callback PublicLinkFn
4463
- * @param {import('../scope/scope.js').Scope} scope - Scope to link with element
4464
- * @param {TranscludeFn} [cloneConnectFn]
4465
- * @param {*} [options]
4466
- * @return {Element|Node|ChildNode|Node[]} The nodes to be linked.
4467
- */
4468
-
4469
- /**
4470
- * @description Entry point for the '$compile' service.
4471
- *
4472
- * @callback CompileFn
4473
- * @param {string|Element|Node|ChildNode|NodeList} compileNode - The node to be compiled.
4474
- * @param {TranscludeFn} [transcludeFn] - An optional transclusion function to be used during compilation.
4475
- * @param {number} [maxPriority] - An optional maximum priority for directives.
4476
- * @param {string} [ignoreDirective] - An optional directive to ignore during compilation.
4477
- * @param {*} [previousCompileContext] - An optional context from a previous compilation. TODO
4478
- * @returns {PublicLinkFn} A public link function.
4479
- */
4480
-
4481
- /**
4482
- * @typedef {Object} LinkFnMapping
4483
- * @property {number} index
4484
- * @property {NodeLinkFnCtx} [nodeLinkFnCtx]
4485
- * @property {CompositeLinkFn} [childLinkFn]
4486
- */
4487
-
4488
- /**
4489
- * @typedef {function(): CompositeLinkFn} CompileNodesFn
4490
- */
4491
-
4492
- /**
4493
- * @callback NodeLinkFn
4494
- * @returns {Node|Element|NodeList}
4495
- */
4496
-
4497
- /**
4498
- * @typedef {Object} NodeLinkFnCtx
4499
- * @property {NodeLinkFn} nodeLinkFn
4500
- * @property {boolean} terminal
4501
- * @property {TranscludeFn} transclude
4502
- * @property {boolean} transcludeOnThisElement
4503
- * @property {boolean} templateOnThisElement
4504
- * @property {boolean} newScope
4505
- */
4506
-
4507
- /**
4508
- * @typedef {function(): NodeLinkFn} ApplyDirectivesToNodeFn
4509
- */
4510
-
4511
- /**
4512
- * @description Function that aggregates all linking fns for a compilation root (nodeList)
4513
- * @callback CompositeLinkFn
4514
- * @param {import('../scope/scope.js').Scope} scope - The scope to be linked to the template
4515
- * @param {NodeRef} $linkNode - wrapper around a nodeList
4516
- * @param {Function} [parentBoundTranscludeFn]
4517
- */
4518
-
4519
4485
  const $compileMinErr = minErr("$compile");
4520
4486
  const EXCLUDED_DIRECTIVES = ["ngIf", "ngRepeat"];
4521
4487
  const ALL_OR_NOTHING_ATTRS = ["ngSrc", "ngSrcset", "src", "srcset"];
@@ -4539,7 +4505,6 @@ class CompileProvider {
4539
4505
  const bindingCache = Object.create(null);
4540
4506
 
4541
4507
  /**
4542
- *
4543
4508
  * @param {import("../scope/scope.js").Scope} scope
4544
4509
  * @param {string} directiveName
4545
4510
  * @param {boolean} isController
@@ -5052,12 +5017,11 @@ class CompileProvider {
5052
5017
  ? (x) => x
5053
5018
  : (x) => x.replace(/\{\{/g, startSymbol).replace(/}}/g, endSymbol);
5054
5019
 
5055
- const NG_PREFIX_BINDING = /^ng(Attr|Prop|On|Observe)([A-Z].*)$/;
5020
+ const NG_PREFIX_BINDING = /^ng(Attr|Prop|On|Observe|Window)([A-Z].*)$/;
5056
5021
  return compile;
5057
5022
 
5058
- //= ===============================
5059
5023
  /**
5060
- * @type {CompileFn}
5024
+ * @type {ng.CompileService}
5061
5025
  */
5062
5026
  function compile(
5063
5027
  element,
@@ -5071,7 +5035,7 @@ class CompileProvider {
5071
5035
  /**
5072
5036
  * The composite link function is a composite of individual node linking functions.
5073
5037
  * It will be invoke by the public link function below.
5074
- * @type {CompositeLinkFn}
5038
+ * @type {ng.CompositeLinkFn}
5075
5039
  */
5076
5040
  let compositeLinkFn = compileNodes(
5077
5041
  nodeRef,
@@ -5084,7 +5048,7 @@ class CompileProvider {
5084
5048
  let namespace = null;
5085
5049
  return publicLinkFn;
5086
5050
 
5087
- /** @type {PublicLinkFn} */
5051
+ /** @type {ng.PublicLinkFn} */
5088
5052
  function publicLinkFn(scope, cloneConnectFn, options) {
5089
5053
  if (!nodeRef) {
5090
5054
  throw $compileMinErr(
@@ -5206,7 +5170,7 @@ class CompileProvider {
5206
5170
  * @param {number=} [maxPriority] Max directive priority.
5207
5171
  * @param {*} [ignoreDirective]
5208
5172
  * @param {*} [previousCompileContext]
5209
- * @returns {CompositeLinkFn} A composite linking function of all of the matched directives or null.
5173
+ * @returns {ng.CompositeLinkFn} A composite linking function of all of the matched directives or null.
5210
5174
  */
5211
5175
  function compileNodes(
5212
5176
  nodeRefList,
@@ -5219,7 +5183,7 @@ class CompileProvider {
5219
5183
  * Aggregates for the composite linking function, where a node in a node list is mapped
5220
5184
  * to a corresponding link function. For single elements, the node should be mapped to
5221
5185
  * a single node link function.
5222
- * @type {LinkFnMapping[]}
5186
+ * @type {ng.LinkFnMapping[]}
5223
5187
  */
5224
5188
  const linkFnsList = []; // An array to hold node indices and their linkFns
5225
5189
  let nodeLinkFnFound;
@@ -5239,7 +5203,7 @@ class CompileProvider {
5239
5203
  ignoreDirective,
5240
5204
  );
5241
5205
 
5242
- /** @type {NodeLinkFnCtx} */
5206
+ /** @type {ng.NodeLinkFnCtx} */
5243
5207
  let nodeLinkFnCtx;
5244
5208
 
5245
5209
  if (directives.length) {
@@ -5386,10 +5350,10 @@ class CompileProvider {
5386
5350
 
5387
5351
  /**
5388
5352
  * Prebinds the transclusion function to a scope
5389
- * @param {import("../scope/scope.js").Scope} scope
5353
+ * @param {ng.Scope} scope
5390
5354
  * @param {*} transcludeFn
5391
5355
  * @param {*} previousBoundTranscludeFn
5392
- * @returns {BoundTranscludeFn}
5356
+ * @returns {ng.BoundTranscludeFn}
5393
5357
  */
5394
5358
  function createBoundTranscludeFn(
5395
5359
  scope,
@@ -5447,7 +5411,7 @@ class CompileProvider {
5447
5411
  */
5448
5412
  function collectDirectives(node, attrs, maxPriority, ignoreDirective) {
5449
5413
  /**
5450
- * @type {import('../../interface.ts').Directive[]}
5414
+ * @type {ng.Directive[]}
5451
5415
  */
5452
5416
  const directives = [];
5453
5417
  const { nodeType } = node;
@@ -5473,6 +5437,7 @@ class CompileProvider {
5473
5437
  let isNgProp = false;
5474
5438
  let isNgEvent = false;
5475
5439
  let isNgObserve = false;
5440
+ let isWindow = false;
5476
5441
 
5477
5442
  let attr = node.attributes[j];
5478
5443
  let name = attr.name;
@@ -5486,6 +5451,7 @@ class CompileProvider {
5486
5451
  isNgProp = ngPrefixMatch[1] === "Prop";
5487
5452
  isNgEvent = ngPrefixMatch[1] === "On";
5488
5453
  isNgObserve = ngPrefixMatch[1] === "Observe";
5454
+ isWindow = ngPrefixMatch[1] === "Window";
5489
5455
 
5490
5456
  // Normalize the non-prefixed name
5491
5457
  name = name
@@ -5495,17 +5461,28 @@ class CompileProvider {
5495
5461
  .replace(/_(.)/g, (match, letter) => letter.toUpperCase());
5496
5462
  }
5497
5463
 
5498
- if (isNgProp || isNgEvent) {
5464
+ if (isNgProp || isNgEvent || isWindow) {
5499
5465
  attrs[nName] = value;
5500
5466
  attrsMap[nName] = attr.name;
5501
5467
 
5502
5468
  if (isNgProp) {
5503
5469
  addPropertyDirective(node, directives, nName, name);
5504
- } else {
5470
+ } else if (isNgEvent) {
5505
5471
  directives.push(
5506
5472
  createEventDirective(
5507
5473
  $parse,
5508
5474
  $exceptionHandler,
5475
+ window,
5476
+ nName,
5477
+ name,
5478
+ ),
5479
+ );
5480
+ } else {
5481
+ directives.push(
5482
+ createWindowEventDirective(
5483
+ $parse,
5484
+ $exceptionHandler,
5485
+ window,
5509
5486
  nName,
5510
5487
  name,
5511
5488
  ),
@@ -5568,7 +5545,7 @@ class CompileProvider {
5568
5545
  * @param maxPriority
5569
5546
  * @param ignoreDirective
5570
5547
  * @param previousCompileContext
5571
- * @returns {PublicLinkFn|TranscludeFn}
5548
+ * @returns {ng.PublicLinkFn|ng.TranscludeFn}
5572
5549
  */
5573
5550
  function compilationGenerator(
5574
5551
  eager,
@@ -5615,14 +5592,14 @@ class CompileProvider {
5615
5592
  * this needs to be pre-sorted by priority order.
5616
5593
  * @param {Node | Element} compileNode DOM node to apply the compile functions to
5617
5594
  * @param {Attributes} templateAttrs The shared attribute function
5618
- * @param {TranscludeFn} transcludeFn
5595
+ * @param {ng.TranscludeFn} transcludeFn
5619
5596
  * @param {Object=} originalReplaceDirective An optional directive that will be ignored when
5620
5597
  * compiling the transclusion.
5621
5598
  * @param {Array.<Function>} [preLinkFns]
5622
5599
  * @param {Array.<Function>} [postLinkFns]
5623
5600
  * @param {Object} [previousCompileContext] Context used for previous compilation of the current
5624
5601
  * node
5625
- * @returns {NodeLinkFnCtx} node link function
5602
+ * @returns {ng.NodeLinkFnCtx} node link function
5626
5603
  */
5627
5604
  function applyDirectivesToNode(
5628
5605
  directives,
@@ -5657,7 +5634,7 @@ class CompileProvider {
5657
5634
  let directiveName;
5658
5635
  let $template;
5659
5636
  let replaceDirective = originalReplaceDirective;
5660
- /** @type {TranscludeFn} */
5637
+ /** @type {ng.TranscludeFn} */
5661
5638
  let childTranscludeFn = transcludeFn;
5662
5639
 
5663
5640
  let didScanForMultipleTransclusion = false;
@@ -5666,7 +5643,7 @@ class CompileProvider {
5666
5643
 
5667
5644
  /**
5668
5645
  * Links all the directives of a single node.
5669
- * @type {NodeLinkFn}
5646
+ * @type {ng.NodeLinkFn}
5670
5647
  */
5671
5648
  // @ts-ignore
5672
5649
  let nodeLinkFn = function (
@@ -6348,7 +6325,7 @@ class CompileProvider {
6348
6325
  ii = directives.length;
6349
6326
  } else if (directive.compile) {
6350
6327
  try {
6351
- /** @type {PublicLinkFn} */
6328
+ /** @type {ng.PublicLinkFn} */
6352
6329
  const linkFn = directive.compile(
6353
6330
  compileNodeRef.getAny(),
6354
6331
  templateAttrs,
@@ -7364,7 +7341,7 @@ class CompileProvider {
7364
7341
  }
7365
7342
 
7366
7343
  /**
7367
- * @type {SimpleChange}
7344
+ * @type {import("./inteface.ts").SimpleChange}
7368
7345
  */
7369
7346
  initialChanges[scopeName] = {
7370
7347
  currentValue: destination[scopeName],
@@ -7517,7 +7494,7 @@ class CompileProvider {
7517
7494
  parentGet = $parse(attrs[attrName]);
7518
7495
 
7519
7496
  destination.$target[scopeName] = parentGet(scope.$target);
7520
- /** @type {SimpleChange} */
7497
+ /** @type {import("./inteface.ts").SimpleChange} */
7521
7498
  initialChanges[scopeName] = {
7522
7499
  currentValue: destination.$target[scopeName],
7523
7500
  firstChange: firstChange,
@@ -11485,7 +11462,7 @@ const ngClassOddDirective = classDirective("Odd", 0);
11485
11462
  const ngClassEvenDirective = classDirective("Even", 1);
11486
11463
 
11487
11464
  /**
11488
- * @returns {import('../../interface.ts').Directive}
11465
+ * @returns {ng.Directive}
11489
11466
  */
11490
11467
  function ngCloakDirective() {
11491
11468
  return {
@@ -11776,7 +11753,7 @@ function ngIncludeDirective(
11776
11753
  ngIncludeFillContentDirective.$inject = [$injectTokens.$compile];
11777
11754
 
11778
11755
  /**
11779
- * @param {import("../../core/compile/compile.js").CompileFn} $compile
11756
+ * @param {ng.CompileService} $compile
11780
11757
  * @returns {import("../../interface.ts").Directive}
11781
11758
  */
11782
11759
  function ngIncludeFillContentDirective($compile) {
@@ -12407,7 +12384,7 @@ const NG_OPTIONS_REGEXP =
12407
12384
  ngOptionsDirective.$inject = ["$compile", "$parse"];
12408
12385
  /**
12409
12386
  *
12410
- * @param {import("../../core/compile/compile.js").CompileFn} $compile
12387
+ * @param {ng.CompileService} $compile
12411
12388
  * @param {import("../../core/parse/interface.ts").ParseService} $parse
12412
12389
  * @returns {import("../../interface.ts").Directive}
12413
12390
  */
@@ -12934,8 +12911,8 @@ const ngTranscludeMinErr = minErr("ngTransclude");
12934
12911
 
12935
12912
  ngTranscludeDirective.$inject = ["$compile"];
12936
12913
  /**
12937
- * @param {import("../../core/compile/compile.js").CompileFn} $compile
12938
- * @returns {import("../../interface.ts").Directive}
12914
+ * @param {ng.CompileService} $compile
12915
+ * @returns {ng.Directive}
12939
12916
  */
12940
12917
  function ngTranscludeDirective($compile) {
12941
12918
  return {
@@ -12946,9 +12923,9 @@ function ngTranscludeDirective($compile) {
12946
12923
 
12947
12924
  /**
12948
12925
  *
12949
- * @param {import("../../core/scope/scope.js").Scope} $scope
12926
+ * @param {ng.Scope} $scope
12950
12927
  * @param {Element} $element
12951
- * @param {import("../../core/compile/attributes.js").Attributes} $attrs
12928
+ * @param {ng.Attributes} $attrs
12952
12929
  * @param {*} _controller
12953
12930
  * @param {*} $transclude
12954
12931
  */
@@ -18301,7 +18278,7 @@ function HttpProvider() {
18301
18278
  $injectTokens.$sce,
18302
18279
  /**
18303
18280
  *
18304
- * @param {import("../../core/di/internal-injector.js").InjectorService} $injector
18281
+ * @param {ng.InjectorService} $injector
18305
18282
  * @param {*} $sce
18306
18283
  * @returns
18307
18284
  */
@@ -35017,8 +34994,8 @@ function registerControllerCallbacks(
35017
34994
 
35018
34995
  ngChannelDirective.$inject = [$injectTokens.$eventBus];
35019
34996
  /**
35020
- * @param {import("../../services/pubsub/pubsub.js").PubSub} $eventBus
35021
- * @returns {import("../../interface.ts").Directive}
34997
+ * @param {ng.PubSubService} $eventBus
34998
+ * @returns {ng.Directive}
35022
34999
  */
35023
35000
  function ngChannelDirective($eventBus) {
35024
35001
  return {
@@ -35105,10 +35082,18 @@ function ngSetterDirective($parse, $log) {
35105
35082
  * @param {"get" | "delete" | "post" | "put"} method
35106
35083
  * @returns {ng.DirectiveFactory}
35107
35084
  */
35108
- function defineDirective(method) {
35109
- const attrName = "ng" + method.charAt(0).toUpperCase() + method.slice(1);
35085
+ function defineDirective(method, attrOverride) {
35086
+ const attrName =
35087
+ attrOverride || "ng" + method.charAt(0).toUpperCase() + method.slice(1);
35110
35088
  const directive = createHttpDirective(method, attrName);
35111
- directive["$inject"] = [$injectTokens.$http, $injectTokens.$compile, $injectTokens.$log, $injectTokens.$parse, $injectTokens.$state];
35089
+ directive["$inject"] = [
35090
+ $injectTokens.$http,
35091
+ $injectTokens.$compile,
35092
+ $injectTokens.$log,
35093
+ $injectTokens.$parse,
35094
+ $injectTokens.$state,
35095
+ $injectTokens.$sse,
35096
+ ];
35112
35097
  return directive;
35113
35098
  }
35114
35099
 
@@ -35124,6 +35109,9 @@ const ngPostDirective = defineDirective("post");
35124
35109
  /** @type {ng.DirectiveFactory} */
35125
35110
  const ngPutDirective = defineDirective("put");
35126
35111
 
35112
+ /** @type {ng.DirectiveFactory} */
35113
+ const ngSseDirective = defineDirective("get", "ngSse");
35114
+
35127
35115
  /**
35128
35116
  * @typedef {"click" | "change" | "submit"} EventType
35129
35117
  */
@@ -35241,9 +35229,10 @@ function createHttpDirective(method, attrName) {
35241
35229
  * @param {ng.LogService} $log
35242
35230
  * @param {ng.ParseService} $parse
35243
35231
  * @param {ng.StateService} $state
35232
+ * @param {ng.SseService} $sse
35244
35233
  * @returns {ng.Directive}
35245
35234
  */
35246
- return function ($http, $compile, $log, $parse, $state) {
35235
+ return function ($http, $compile, $log, $parse, $state, $sse) {
35247
35236
  /**
35248
35237
  * Collects form data from the element or its associated form.
35249
35238
  *
@@ -35332,7 +35321,6 @@ function createHttpDirective(method, attrName) {
35332
35321
  element.addEventListener(eventName, async (event) => {
35333
35322
  if (/** @type {HTMLButtonElement} */ (element).disabled) return;
35334
35323
  if (tag === "form") event.preventDefault();
35335
-
35336
35324
  const swap = attrs["swap"] || "innerHTML";
35337
35325
  const targetSelector = attrs["target"];
35338
35326
  const target = targetSelector
@@ -35386,7 +35374,6 @@ function createHttpDirective(method, attrName) {
35386
35374
  $compile,
35387
35375
  );
35388
35376
  };
35389
-
35390
35377
  if (isDefined(attrs["delay"])) {
35391
35378
  await wait(parseInt(attrs["delay"]) | 0);
35392
35379
  }
@@ -35425,11 +35412,57 @@ function createHttpDirective(method, attrName) {
35425
35412
  }
35426
35413
  $http[method](url, data, config).then(handler).catch(handler);
35427
35414
  } else {
35428
- $http[method](url).then(handler).catch(handler);
35415
+ // If SSE mode is enabled
35416
+ if (method === "get" && attrs["ngSse"]) {
35417
+ const sseUrl = url;
35418
+ const config = {
35419
+ withCredentials: attrs["withCredentials"] === "true",
35420
+ transformMessage: (data) => {
35421
+ try {
35422
+ return JSON.parse(data);
35423
+ } catch {
35424
+ return data;
35425
+ }
35426
+ },
35427
+ onOpen: () => {
35428
+ $log.info(`${attrName}: SSE connection opened to ${sseUrl}`);
35429
+ if (isDefined(attrs["loading"])) attrs.$set("loading", false);
35430
+ if (isDefined(attrs["loadingClass"]))
35431
+ attrs.$removeClass(attrs["loadingClass"]);
35432
+ },
35433
+ onMessage: (data) => {
35434
+ const res = { status: 200, data };
35435
+ handler(res);
35436
+ },
35437
+ onError: (err) => {
35438
+ $log.error(`${attrName}: SSE error`, err);
35439
+ const res = { status: 500, data: err };
35440
+ handler(res);
35441
+ },
35442
+ };
35443
+
35444
+ // Open the SSE connection using the injected service
35445
+ const source = $sse(sseUrl, config);
35446
+
35447
+ // Cleanup on scope destroy
35448
+ scope.$on("$destroy", () => {
35449
+ $log.info(`${attrName}: closing SSE connection`);
35450
+ source.close();
35451
+ });
35452
+ } else {
35453
+ $http[method](url).then(handler).catch(handler);
35454
+ }
35429
35455
  }
35430
35456
  });
35431
35457
 
35432
- scope.$on("$destroy", () => clearInterval(intervalId));
35458
+ if (intervalId) {
35459
+ scope.$on("$destroy", () => clearInterval(intervalId));
35460
+ }
35461
+
35462
+ // Eagerly execute for 'load' event
35463
+ if (eventName == "load") {
35464
+ element.dispatchEvent(new Event("load"));
35465
+ }
35433
35466
  },
35434
35467
  };
35435
35468
  };
@@ -35500,6 +35533,142 @@ function ngElDirective() {
35500
35533
  };
35501
35534
  }
35502
35535
 
35536
+ /**
35537
+ * SSE Provider
35538
+ *
35539
+ * Usage:
35540
+ * const source = $sse('/events', {
35541
+ * onMessage: (data) => console.log(data),
35542
+ * onError: (err) => console.error(err),
35543
+ * withCredentials: true
35544
+ * });
35545
+ *
35546
+ * // later:
35547
+ * source.close();
35548
+ */
35549
+
35550
+ class SseProvider {
35551
+ constructor() {
35552
+ /**
35553
+ * Optional provider-level defaults
35554
+ * @type {ng.SseConfig}
35555
+ */
35556
+ this.defaults = {};
35557
+ }
35558
+
35559
+ /**
35560
+ * Returns the $sse service function
35561
+ * @returns {ng.SseService}
35562
+ */
35563
+ $get =
35564
+ () =>
35565
+ (url, config = {}) => {
35566
+ const finalUrl = this.#buildUrl(url, config.params);
35567
+ return this.#createEventSource(finalUrl, config);
35568
+ };
35569
+
35570
+ /**
35571
+ * Build URL with query parameters
35572
+ * @param {string} url - Base URL
35573
+ * @param {Record<string, any>=} params - Query parameters
35574
+ * @returns {string} URL with serialized query string
35575
+ */
35576
+ #buildUrl(url, params) {
35577
+ if (!params) return url;
35578
+ const query = Object.entries(params)
35579
+ .map(([k, v]) => `${encodeURIComponent(k)}=${encodeURIComponent(v)}`)
35580
+ .join("&");
35581
+ return url + (url.includes("?") ? "&" : "?") + query;
35582
+ }
35583
+
35584
+ /**
35585
+ * Create and manage an EventSource
35586
+ * @param {string} url - URL for SSE connection
35587
+ * @param {ng.SseConfig} config - Configuration object
35588
+ * @returns {EventSource} The EventSource instance wrapped as SseService
35589
+ */
35590
+ #createEventSource(url, config) {
35591
+ const es = new EventSource(url, {
35592
+ withCredentials: !!config.withCredentials,
35593
+ });
35594
+
35595
+ if (config.onOpen) {
35596
+ es.addEventListener("open", (e) => config.onOpen(e));
35597
+ }
35598
+
35599
+ es.addEventListener("message", (e) => {
35600
+ let data = e.data;
35601
+ try {
35602
+ data = config.transformMessage
35603
+ ? config.transformMessage(data)
35604
+ : JSON.parse(data);
35605
+ } catch {
35606
+ // leave as raw string if not JSON
35607
+ }
35608
+ config.onMessage?.(data, e);
35609
+ });
35610
+
35611
+ if (config.onError) {
35612
+ es.addEventListener("error", (e) => config.onError(e));
35613
+ }
35614
+
35615
+ return es;
35616
+ }
35617
+ }
35618
+
35619
+ /**
35620
+ * @returns {ng.Directive}
35621
+ */
35622
+ function ngViewportDirective() {
35623
+ return {
35624
+ restrict: "A",
35625
+ link(scope, element, attrs) {
35626
+ const enterExpr = attrs["onEnter"];
35627
+ const leaveExpr = attrs["onLeave"];
35628
+
35629
+ const observer = new IntersectionObserver(
35630
+ (entries) => {
35631
+ entries.forEach((entry) => {
35632
+ if (entry.isIntersecting) {
35633
+ if (enterExpr) scope.$eval(enterExpr);
35634
+ } else {
35635
+ if (leaveExpr) scope.$eval(leaveExpr);
35636
+ }
35637
+ });
35638
+ },
35639
+ {
35640
+ root: null, // viewport
35641
+ threshold: 0.1, // consider "in view" if 10% visible
35642
+ },
35643
+ );
35644
+
35645
+ observer.observe(element);
35646
+
35647
+ // Clean up when the element is removed from DOM
35648
+ const parent = element.parentNode;
35649
+ let mutationObserver;
35650
+ if (parent) {
35651
+ mutationObserver = new MutationObserver((mutations) => {
35652
+ for (const mutation of mutations) {
35653
+ Array.from(mutation.removedNodes).forEach((removedNode) => {
35654
+ if (removedNode === element) {
35655
+ observer.disconnect();
35656
+ mutationObserver.disconnect();
35657
+ }
35658
+ });
35659
+ }
35660
+ });
35661
+ mutationObserver.observe(parent, { childList: true });
35662
+ }
35663
+
35664
+ scope.$on("$destroy", () => {
35665
+ observer.disconnect();
35666
+ if (mutationObserver) mutationObserver.disconnect();
35667
+ });
35668
+ },
35669
+ };
35670
+ }
35671
+
35503
35672
  /**
35504
35673
  * Initializes core `ng` module.
35505
35674
  * @param {import('./angular.js').Angular} angular
@@ -35560,6 +35729,7 @@ function registerNgModule(angular) {
35560
35729
  ngSetter: ngSetterDirective,
35561
35730
  ngShow: ngShowDirective,
35562
35731
  ngStyle: ngStyleDirective,
35732
+ ngSse: ngSseDirective,
35563
35733
  ngSwitch: ngSwitchDirective,
35564
35734
  ngSwitchWhen: ngSwitchWhenDirective,
35565
35735
  ngSwitchDefault: ngSwitchDefaultDirective,
@@ -35576,6 +35746,7 @@ function registerNgModule(angular) {
35576
35746
  maxlength: maxlengthDirective,
35577
35747
  ngValue: ngValueDirective,
35578
35748
  ngModelOptions: ngModelOptionsDirective,
35749
+ ngViewport: ngViewportDirective,
35579
35750
  })
35580
35751
  .directive({
35581
35752
  input: hiddenInputBrowserCacheDirective,
@@ -35631,6 +35802,7 @@ function registerNgModule(angular) {
35631
35802
  $router: Router,
35632
35803
  $sce: SceProvider,
35633
35804
  $sceDelegate: SceDelegateProvider,
35805
+ $sse: SseProvider,
35634
35806
  $templateCache: TemplateCacheProvider,
35635
35807
  $templateRequest: TemplateRequestProvider,
35636
35808
  $urlConfig: UrlConfigProvider,
@@ -35673,7 +35845,7 @@ class Angular {
35673
35845
  /**
35674
35846
  * @type {string} `version` from `package.json`
35675
35847
  */
35676
- this.version = "0.9.7"; //inserted via rollup plugin
35848
+ this.version = "0.9.9"; //inserted via rollup plugin
35677
35849
 
35678
35850
  /** @type {!Array<string|any>} */
35679
35851
  this.bootsrappedModules = [];
@@ -35766,10 +35938,10 @@ class Angular {
35766
35938
  $injectTokens.$compile,
35767
35939
  $injectTokens.$injector,
35768
35940
  /**
35769
- * @param {import('./core/scope/scope.js').Scope} scope
35941
+ * @param {ng.Scope} scope
35770
35942
  * @param {Element} el
35771
- * @param {import("./core/compile/compile.js").CompileFn} compile
35772
- * @param {import("./core/di/internal-injector.js").InjectorService} $injector
35943
+ * @param {ng.CompileService} compile
35944
+ * @param {ng.InjectorService} $injector
35773
35945
  */
35774
35946
  (scope, el, compile, $injector) => {
35775
35947
  // ng-route deps