@angular-wave/angular.ts 0.11.0 → 0.12.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 (45) hide show
  1. package/@types/angular.d.ts +64 -51
  2. package/@types/animations/animate.d.ts +1 -351
  3. package/@types/animations/animation.d.ts +2 -2
  4. package/@types/animations/interface.d.ts +72 -0
  5. package/@types/animations/{animate-queue.d.ts → queue/animate-queue.d.ts} +2 -7
  6. package/@types/animations/queue/interface.d.ts +50 -0
  7. package/@types/core/compile/attributes.d.ts +5 -5
  8. package/@types/core/compile/compile.d.ts +4 -4
  9. package/@types/core/controller/controller.d.ts +1 -1
  10. package/@types/core/di/di.d.ts +26 -0
  11. package/@types/core/di/injector.d.ts +0 -11
  12. package/@types/core/di/internal-injector.d.ts +2 -2
  13. package/@types/core/di/ng-module/ng-module.d.ts +197 -0
  14. package/@types/core/sanitize/interface.d.ts +8 -0
  15. package/@types/core/sanitize/sanitize-uri.d.ts +5 -2
  16. package/@types/core/scope/interface.d.ts +2 -2
  17. package/@types/core/scope/scope.d.ts +5 -2
  18. package/@types/directive/form/form.d.ts +7 -7
  19. package/@types/directive/if/if.d.ts +2 -2
  20. package/@types/directive/include/include.d.ts +4 -4
  21. package/@types/directive/messages/messages.d.ts +18 -22
  22. package/@types/directive/model/model.d.ts +3 -3
  23. package/@types/directive/scope/scope.d.ts +4 -0
  24. package/@types/directive/show-hide/show-hide.d.ts +3 -4
  25. package/@types/directive/switch/switch.d.ts +3 -5
  26. package/@types/directive/wasm/wasm.d.ts +4 -0
  27. package/@types/{services → directive}/worker/interface.d.ts +1 -0
  28. package/@types/directive/worker/worker.d.ts +18 -8
  29. package/@types/interface.d.ts +14 -15
  30. package/@types/namespace.d.ts +25 -4
  31. package/@types/services/log/log.d.ts +2 -2
  32. package/@types/services/sce/sce.d.ts +4 -82
  33. package/@types/services/sse/sse.d.ts +1 -5
  34. package/@types/services/storage/interface.d.ts +5 -0
  35. package/@types/services/storage/storage.d.ts +19 -0
  36. package/@types/services/stream/interface.d.ts +18 -0
  37. package/@types/shared/dom.d.ts +21 -5
  38. package/@types/shared/strings.d.ts +0 -6
  39. package/@types/shared/utils.d.ts +24 -14
  40. package/dist/angular-ts.esm.js +1448 -1194
  41. package/dist/angular-ts.umd.js +1448 -1194
  42. package/dist/angular-ts.umd.min.js +1 -1
  43. package/package.json +1 -1
  44. package/@types/core/di/ng-module.d.ts +0 -156
  45. package/@types/services/worker/worker.d.ts +0 -31
@@ -1,4 +1,4 @@
1
- /* Version: 0.11.0 - November 11, 2025 21:55:57 */
1
+ /* Version: 0.12.0 - November 29, 2025 19:42:35 */
2
2
  const VALID_CLASS = "ng-valid";
3
3
  const INVALID_CLASS = "ng-invalid";
4
4
  const PRISTINE_CLASS = "ng-pristine";
@@ -32,7 +32,7 @@ function isProxy(value) {
32
32
  return !!(value && value[isProxySymbol]);
33
33
  }
34
34
 
35
- const ngMinErr$2 = minErr("ng");
35
+ const ngMinErr$1 = minErr("ng");
36
36
 
37
37
  /**
38
38
  * @type {number}
@@ -370,26 +370,6 @@ function hasCustomToString(obj) {
370
370
  return isFunction(obj.toString) && obj.toString !== toString;
371
371
  }
372
372
 
373
- /**
374
- * @module angular
375
- * @function isElement
376
-
377
- * @function
378
- *
379
- * @description
380
- * Determines if a reference is a DOM element (or wrapped jQuery element).
381
- *
382
- * @param {*} node Reference to check.
383
- * @returns {boolean} True if `value` is a DOM element (or wrapped jQuery element).
384
- */
385
- function isElement(node) {
386
- return !!(
387
- node &&
388
- (node.nodeName || // We are a direct element.
389
- (node.attr && node.find))
390
- ); // We have an on and find method part of jQuery API.
391
- }
392
-
393
373
  /**
394
374
  * Returns a string appropriate for the type of node.
395
375
  *
@@ -547,7 +527,7 @@ function equals$1(o1, o2) {
547
527
  */
548
528
  function assertNotHasOwnProperty(name, context) {
549
529
  if (name === "hasOwnProperty") {
550
- throw ngMinErr$2(
530
+ throw ngMinErr$1(
551
531
  "badname",
552
532
  "hasOwnProperty is not a valid {0} name",
553
533
  context,
@@ -877,9 +857,9 @@ function assert(argument, errorMsg = "Assertion failed") {
877
857
  /**
878
858
  * Throw error if the argument is falsy.
879
859
  */
880
- function assertArg$1(arg, name, reason) {
860
+ function assertArg(arg, name, reason) {
881
861
  if (!arg) {
882
- throw ngMinErr$2(
862
+ throw ngMinErr$1(
883
863
  "areq",
884
864
  "Argument '{0}' is {1}",
885
865
  name || "?",
@@ -894,7 +874,7 @@ function assertArgFn(arg, name, acceptArrayAnnotation) {
894
874
  arg = arg[arg.length - 1];
895
875
  }
896
876
 
897
- assertArg$1(
877
+ assertArg(
898
878
  isFunction(arg),
899
879
  name,
900
880
  `not a function, got ${
@@ -1042,13 +1022,38 @@ function hashKey(obj) {
1042
1022
  return `${objType}:${obj}`;
1043
1023
  }
1044
1024
 
1045
- function mergeClasses$1(a, b) {
1025
+ /**
1026
+ * Merges two class name values into a single space-separated string.
1027
+ * Accepts strings, arrays of strings, or null/undefined values.
1028
+ *
1029
+ * @param {string | string[] | null | undefined} a - The first class name(s).
1030
+ * @param {string | string[] | null | undefined} b - The second class name(s).
1031
+ * @returns {string} A single string containing all class names separated by spaces.
1032
+ */
1033
+ function mergeClasses(a, b) {
1046
1034
  if (!a && !b) return "";
1047
- if (!a) return b;
1048
- if (!b) return a;
1049
- if (Array.isArray(a)) a = a.join(" ");
1050
- if (Array.isArray(b)) b = b.join(" ");
1051
- return a + " " + b;
1035
+ if (!a) return Array.isArray(b) ? b.join(" ").trim() : b;
1036
+ if (!b) return Array.isArray(a) ? a.join(" ").trim() : a;
1037
+ if (Array.isArray(a)) a = normalizeStringArray(a);
1038
+ if (Array.isArray(b)) b = normalizeStringArray(b);
1039
+ return `${a.trim()} ${b.trim()}`.trim();
1040
+ }
1041
+
1042
+ /**
1043
+ * Joins an array of strings into a single string, trimming each
1044
+ * element and ignoring empty strings, null, and undefined
1045
+ * @param {any[]} arr
1046
+ * @returns {string}
1047
+ */
1048
+ function normalizeStringArray(arr) {
1049
+ const cleaned = [];
1050
+ for (const item of arr) {
1051
+ if (item) {
1052
+ const trimmed = item.trim();
1053
+ if (trimmed) cleaned.push(trimmed);
1054
+ }
1055
+ }
1056
+ return cleaned.join(" ");
1052
1057
  }
1053
1058
 
1054
1059
  /**
@@ -1190,6 +1195,30 @@ function startsWith(str, search) {
1190
1195
  return str.slice(0, search.length) === search;
1191
1196
  }
1192
1197
 
1198
+ /**
1199
+ * Loads and instantiates a WebAssembly module.
1200
+ * Tries streaming first, then falls back.
1201
+ */
1202
+ async function instantiateWasm(src, imports = {}) {
1203
+ const res = await fetch(src);
1204
+ if (!res.ok) throw new Error("fetch failed");
1205
+
1206
+ try {
1207
+ const { instance, module } = await WebAssembly.instantiateStreaming(
1208
+ res.clone(),
1209
+ imports,
1210
+ );
1211
+ return { instance, exports: instance.exports, module };
1212
+ } catch {
1213
+ /* empty */
1214
+ }
1215
+
1216
+ const bytes = await res.arrayBuffer();
1217
+ const { instance, module } = await WebAssembly.instantiate(bytes, imports);
1218
+
1219
+ return { instance, exports: instance.exports, module };
1220
+ }
1221
+
1193
1222
  /**
1194
1223
  * Expando cache for adding properties to DOM nodes with JavaScript.
1195
1224
  * This used to be an Object in JQLite decorator, but swapped out for a Map
@@ -1279,19 +1308,6 @@ const ANIMATION_DURATION_PROP = ANIMATION_PROP + DURATION_KEY;
1279
1308
  const TRANSITION_DELAY_PROP = TRANSITION_PROP + DELAY_KEY;
1280
1309
  const TRANSITION_DURATION_PROP = TRANSITION_PROP + DURATION_KEY;
1281
1310
 
1282
- const ngMinErr$1 = minErr("ng");
1283
- function assertArg(arg, name, reason) {
1284
- if (!arg) {
1285
- throw ngMinErr$1(
1286
- "areq",
1287
- "Argument '{0}' is {1}",
1288
- name || "?",
1289
- reason,
1290
- );
1291
- }
1292
- return arg;
1293
- }
1294
-
1295
1311
  function packageStyles(options) {
1296
1312
  const styles = {};
1297
1313
  if (options && (options.to || options.from)) {
@@ -1332,7 +1348,7 @@ function removeFromArray(arr, val) {
1332
1348
  */
1333
1349
  function stripCommentsFromElement(element) {
1334
1350
  if (element instanceof NodeList) {
1335
- return Array.from(element).filter((x) => x.nodeType == Node.ELEMENT_NODE);
1351
+ return Array.from(element).filter((x) => x.nodeType === Node.ELEMENT_NODE);
1336
1352
  } else if (element.nodeType === Node.ELEMENT_NODE) {
1337
1353
  return /** @type {Node} */ (element);
1338
1354
  } else {
@@ -1575,7 +1591,7 @@ function concatWithSpace(a, b) {
1575
1591
  }
1576
1592
 
1577
1593
  /** @type {number} */
1578
- let jqId = 1;
1594
+ let elId = 1;
1579
1595
 
1580
1596
  /**
1581
1597
  * Key for storing isolate scope data, attached to an element
@@ -1627,8 +1643,8 @@ const BOOLEAN_ELEMENTS = [
1627
1643
  *
1628
1644
  * @returns {number} Next unique JQInstance id
1629
1645
  */
1630
- function jqNextId() {
1631
- return ++jqId;
1646
+ function elemNextId() {
1647
+ return ++elId;
1632
1648
  }
1633
1649
 
1634
1650
  /**
@@ -1694,7 +1710,7 @@ function getExpando(element, createIfNecessary = false) {
1694
1710
  let expandoStore = expandoId && Cache.get(expandoId);
1695
1711
 
1696
1712
  if (createIfNecessary && !expandoStore) {
1697
- element[EXPANDO] = expandoId = jqNextId();
1713
+ element[EXPANDO] = expandoId = elemNextId();
1698
1714
  expandoStore = {
1699
1715
  data: {},
1700
1716
  };
@@ -1867,7 +1883,7 @@ function deleteCacheData(element, key) {
1867
1883
  * Gets scope for a given element.
1868
1884
  *
1869
1885
  * @param {Element} element - The DOM element to get data from.
1870
- * @returns {*} - The retrieved data for the given key or all data if no key is provided.
1886
+ * @returns {ng.Scope} - The retrieved data for the given key or all data if no key is provided.
1871
1887
  */
1872
1888
  function getScope(element) {
1873
1889
  return getCacheData(element, SCOPE_KEY);
@@ -2090,6 +2106,22 @@ function emptyElement(element) {
2090
2106
  }
2091
2107
  }
2092
2108
 
2109
+ /**
2110
+ * Inserts a DOM element before or at the beginning of a parent element.
2111
+ *
2112
+ * @param {HTMLElement | Element} element
2113
+ * The element to insert into the DOM.
2114
+ *
2115
+ * @param {HTMLElement | Element} parentElement
2116
+ * The parent element that will receive the inserted element.
2117
+ *
2118
+ * @param {HTMLElement | Element | null} [afterElement]
2119
+ * An optional sibling element — if present and valid, `element`
2120
+ * will be inserted after it. If omitted or invalid, `element`
2121
+ * is prepended to `parentElement`.
2122
+ *
2123
+ * @returns {void}
2124
+ */
2093
2125
  function domInsert(element, parentElement, afterElement) {
2094
2126
  // if for some reason the previous element was removed
2095
2127
  // from the dom sometime before this code runs then let's
@@ -2218,6 +2250,706 @@ function provider(services) {
2218
2250
  return services.map((x) => x + "Provider");
2219
2251
  }
2220
2252
 
2253
+ /**
2254
+ * @param {"get" | "delete" | "post" | "put"} method - HTTP method applied to request
2255
+ * @param {string} [attrOverride] - Custom name to use for the attribute
2256
+ * @returns {ng.DirectiveFactory}
2257
+ */
2258
+ function defineDirective(method, attrOverride) {
2259
+ const attrName =
2260
+ attrOverride || "ng" + method.charAt(0).toUpperCase() + method.slice(1);
2261
+ const directive = createHttpDirective(method, attrName);
2262
+ directive["$inject"] = [
2263
+ $injectTokens.$http,
2264
+ $injectTokens.$compile,
2265
+ $injectTokens.$log,
2266
+ $injectTokens.$parse,
2267
+ $injectTokens.$state,
2268
+ $injectTokens.$sse,
2269
+ $injectTokens.$animate,
2270
+ ];
2271
+ return directive;
2272
+ }
2273
+
2274
+ /** @type {ng.DirectiveFactory} */
2275
+ const ngGetDirective = defineDirective("get");
2276
+
2277
+ /** @type {ng.DirectiveFactory} */
2278
+ const ngDeleteDirective = defineDirective("delete");
2279
+
2280
+ /** @type {ng.DirectiveFactory} */
2281
+ const ngPostDirective = defineDirective("post");
2282
+
2283
+ /** @type {ng.DirectiveFactory} */
2284
+ const ngPutDirective = defineDirective("put");
2285
+
2286
+ /** @type {ng.DirectiveFactory} */
2287
+ const ngSseDirective = defineDirective("get", "ngSse");
2288
+
2289
+ /**
2290
+ * Selects DOM event to listen for based on the element type.
2291
+ *
2292
+ * @param {Element} element - The DOM element to inspect.
2293
+ * @returns {"click" | "change" | "submit"} The name of the event to listen for.
2294
+ */
2295
+ function getEventNameForElement(element) {
2296
+ const tag = element.tagName.toLowerCase();
2297
+ if (["input", "textarea", "select"].includes(tag)) {
2298
+ return "change";
2299
+ } else if (tag === "form") {
2300
+ return "submit";
2301
+ }
2302
+ return "click";
2303
+ }
2304
+
2305
+ /**
2306
+ * Creates an HTTP directive factory that supports GET, DELETE, POST, PUT.
2307
+ *
2308
+ * @param {"get" | "delete" | "post" | "put"} method - HTTP method to use.
2309
+ * @param {string} attrName - Attribute name containing the URL.
2310
+ * @returns {ng.DirectiveFactory}
2311
+ */
2312
+ function createHttpDirective(method, attrName) {
2313
+ /**
2314
+ * @param {ng.HttpService} $http
2315
+ * @param {ng.CompileService} $compile
2316
+ * @param {ng.LogService} $log
2317
+ * @param {ng.ParseService} $parse
2318
+ * @param {ng.StateService} $state
2319
+ * @param {ng.SseService} $sse
2320
+ * @param {ng.AnimateService} $animate
2321
+ * @returns {ng.Directive}
2322
+ */
2323
+ return function ($http, $compile, $log, $parse, $state, $sse, $animate) {
2324
+ /**
2325
+ * Collects form data from the element or its associated form.
2326
+ *
2327
+ * @param {HTMLElement} element
2328
+ * @returns {Object<string, any>}
2329
+ */
2330
+ function collectFormData(element) {
2331
+ /** @type {HTMLFormElement | null} */
2332
+ let form = null;
2333
+
2334
+ const tag = element.tagName.toLowerCase();
2335
+
2336
+ if (tag === "form") {
2337
+ form = /** @type {HTMLFormElement} */ (element);
2338
+ } else if ("form" in element && element.form) {
2339
+ form = /** @type {HTMLFormElement} */ (element.form);
2340
+ } else if (element.hasAttribute("form")) {
2341
+ const formId = element.getAttribute("form");
2342
+ if (formId) {
2343
+ const maybeForm = document.getElementById(formId);
2344
+ if (maybeForm && maybeForm.tagName.toLowerCase() === "form") {
2345
+ form = /** @type {HTMLFormElement} */ (maybeForm);
2346
+ }
2347
+ }
2348
+ }
2349
+
2350
+ if (!form) {
2351
+ if (
2352
+ "name" in element &&
2353
+ typeof element.name === "string" &&
2354
+ element.name.length > 0
2355
+ ) {
2356
+ if (
2357
+ element instanceof HTMLInputElement ||
2358
+ element instanceof HTMLTextAreaElement ||
2359
+ element instanceof HTMLSelectElement
2360
+ ) {
2361
+ const key = element.name;
2362
+ const value = element.value;
2363
+ return { [key]: value };
2364
+ }
2365
+ }
2366
+ return {};
2367
+ }
2368
+
2369
+ const formData = new FormData(form);
2370
+ const data = {};
2371
+ formData.forEach((value, key) => {
2372
+ data[key] = value;
2373
+ });
2374
+ return data;
2375
+ }
2376
+
2377
+ return {
2378
+ restrict: "A",
2379
+ link(scope, element, attrs) {
2380
+ const eventName = attrs.trigger || getEventNameForElement(element);
2381
+ const tag = element.tagName.toLowerCase();
2382
+ let content = undefined;
2383
+
2384
+ if (isDefined(attrs.latch)) {
2385
+ attrs.$observe(
2386
+ "latch",
2387
+ callBackAfterFirst(() =>
2388
+ element.dispatchEvent(new Event(eventName)),
2389
+ ),
2390
+ );
2391
+ }
2392
+
2393
+ let throttled = false;
2394
+ let intervalId;
2395
+
2396
+ if (isDefined(attrs["interval"])) {
2397
+ element.dispatchEvent(new Event(eventName));
2398
+ intervalId = setInterval(
2399
+ () => element.dispatchEvent(new Event(eventName)),
2400
+ parseInt(attrs.interval) || 1000,
2401
+ );
2402
+ }
2403
+
2404
+ /**
2405
+ * Handles DOM manipulation based on a swap strategy and server-rendered HTML.
2406
+ *
2407
+ * @param {string | Object} html - The HTML string or object returned from the server.
2408
+ * @param {import("./interface.ts").SwapModeType} swap
2409
+ * @param {ng.Scope} scope
2410
+ * @param {ng.Attributes} attrs
2411
+ * @param {Element} element
2412
+ */
2413
+ function handleSwapResponse(html, swap, scope, attrs, element) {
2414
+ let animationEnabled = false;
2415
+ if (attrs.animate) {
2416
+ animationEnabled = true;
2417
+ }
2418
+ let nodes = [];
2419
+ if (!["textcontent", "delete", "none"].includes(swap)) {
2420
+ if (!html) return;
2421
+ const compiled = $compile(html)(scope);
2422
+ nodes =
2423
+ compiled instanceof DocumentFragment
2424
+ ? Array.from(compiled.childNodes)
2425
+ : [compiled];
2426
+ }
2427
+
2428
+ const targetSelector = attrs.target;
2429
+ const target = targetSelector
2430
+ ? document.querySelector(targetSelector)
2431
+ : element;
2432
+
2433
+ if (!target) {
2434
+ $log.warn(`${attrName}: target "${targetSelector}" not found`);
2435
+ return;
2436
+ }
2437
+
2438
+ switch (swap) {
2439
+ case "outerHTML": {
2440
+ const parent = target.parentNode;
2441
+ if (!parent) return;
2442
+
2443
+ // Build fragment for static replacement OR a list for animation
2444
+ const frag = document.createDocumentFragment();
2445
+ nodes.forEach((n) => frag.appendChild(n));
2446
+
2447
+ if (!animationEnabled) {
2448
+ parent.replaceChild(frag, target);
2449
+ break;
2450
+ }
2451
+
2452
+ const placeholder = document.createElement("span");
2453
+ placeholder.style.display = "none";
2454
+ parent.insertBefore(placeholder, target.nextSibling);
2455
+
2456
+ $animate.leave(target).done(() => {
2457
+ const insertedNodes = Array.from(frag.childNodes);
2458
+
2459
+ // Insert each node in order
2460
+ for (const n of insertedNodes) {
2461
+ if (n.nodeType === Node.ELEMENT_NODE) {
2462
+ // Animate elements
2463
+ $animate.enter(
2464
+ /** @type {Element} */ (n),
2465
+ parent,
2466
+ placeholder,
2467
+ );
2468
+ } else {
2469
+ // Insert text nodes statically
2470
+ parent.insertBefore(n, placeholder);
2471
+ }
2472
+ }
2473
+
2474
+ content = insertedNodes;
2475
+ scope.$flushQueue(); // flush once after all insertions
2476
+ });
2477
+
2478
+ scope.$flushQueue(); // flush leave animation
2479
+ break;
2480
+ }
2481
+
2482
+ case "textContent":
2483
+ if (animationEnabled) {
2484
+ $animate.leave(target).done(() => {
2485
+ target.textContent = html;
2486
+ $animate.enter(target, target.parentNode);
2487
+ scope.$flushQueue();
2488
+ });
2489
+
2490
+ scope.$flushQueue();
2491
+ } else {
2492
+ target.textContent = html;
2493
+ }
2494
+ break;
2495
+
2496
+ case "beforebegin": {
2497
+ const parent = target.parentNode;
2498
+ if (!parent) break;
2499
+
2500
+ nodes.forEach((node) => {
2501
+ if (animationEnabled && node.nodeType === Node.ELEMENT_NODE) {
2502
+ $animate.enter(node, parent, target); // insert before target
2503
+ } else {
2504
+ parent.insertBefore(node, target);
2505
+ }
2506
+ });
2507
+
2508
+ if (animationEnabled) scope.$flushQueue();
2509
+ break;
2510
+ }
2511
+
2512
+ case "afterbegin": {
2513
+ const firstChild = target.firstChild;
2514
+ [...nodes].reverse().forEach((node) => {
2515
+ if (animationEnabled && node.nodeType === Node.ELEMENT_NODE) {
2516
+ $animate.enter(node, target, firstChild); // insert before first child
2517
+ } else {
2518
+ target.insertBefore(node, firstChild);
2519
+ }
2520
+ });
2521
+
2522
+ if (animationEnabled) scope.$flushQueue();
2523
+ break;
2524
+ }
2525
+
2526
+ case "beforeend": {
2527
+ nodes.forEach((node) => {
2528
+ if (animationEnabled && node.nodeType === Node.ELEMENT_NODE) {
2529
+ $animate.enter(node, target, null); // append at end
2530
+ } else {
2531
+ target.appendChild(node);
2532
+ }
2533
+ });
2534
+
2535
+ if (animationEnabled) scope.$flushQueue();
2536
+ break;
2537
+ }
2538
+
2539
+ case "afterend": {
2540
+ const parent = target.parentNode;
2541
+ if (!parent) break;
2542
+ const nextSibling = target.nextSibling;
2543
+
2544
+ [...nodes].reverse().forEach((node) => {
2545
+ if (animationEnabled && node.nodeType === Node.ELEMENT_NODE) {
2546
+ $animate.enter(node, parent, nextSibling); // insert after target
2547
+ } else {
2548
+ parent.insertBefore(node, nextSibling);
2549
+ }
2550
+ });
2551
+
2552
+ if (animationEnabled) scope.$flushQueue();
2553
+ break;
2554
+ }
2555
+
2556
+ case "delete":
2557
+ if (animationEnabled) {
2558
+ $animate.leave(target).done(() => {
2559
+ target.remove(); // safety: actually remove in case $animate.leave didn't
2560
+ scope.$flushQueue();
2561
+ });
2562
+ scope.$flushQueue();
2563
+ } else {
2564
+ target.remove();
2565
+ }
2566
+ break;
2567
+
2568
+ case "none":
2569
+ break;
2570
+
2571
+ case "innerHTML":
2572
+ default:
2573
+ if (animationEnabled) {
2574
+ if (content && content.nodeType !== Node.TEXT_NODE) {
2575
+ $animate.leave(content).done(() => {
2576
+ content = nodes[0];
2577
+ $animate.enter(nodes[0], target);
2578
+ scope.$flushQueue();
2579
+ });
2580
+ scope.$flushQueue();
2581
+ } else {
2582
+ content = nodes[0];
2583
+ if (content.nodeType === Node.TEXT_NODE) {
2584
+ target.replaceChildren(...nodes);
2585
+ } else {
2586
+ $animate.enter(nodes[0], target);
2587
+ scope.$flushQueue();
2588
+ }
2589
+ }
2590
+ } else {
2591
+ target.replaceChildren(...nodes);
2592
+ }
2593
+ break;
2594
+ }
2595
+ }
2596
+
2597
+ element.addEventListener(eventName, async (event) => {
2598
+ if (/** @type {HTMLButtonElement} */ (element).disabled) return;
2599
+ if (tag === "form") event.preventDefault();
2600
+ const swap = attrs.swap || "innerHTML";
2601
+ const url = attrs[attrName];
2602
+ if (!url) {
2603
+ $log.warn(`${attrName}: no URL specified`);
2604
+ return;
2605
+ }
2606
+
2607
+ const handler = (res) => {
2608
+ if (isDefined(attrs.loading)) {
2609
+ attrs.$set("loading", false);
2610
+ }
2611
+
2612
+ if (isDefined(attrs.loadingClass)) {
2613
+ attrs.$removeClass(attrs.loadingClass);
2614
+ }
2615
+
2616
+ const html = res.data;
2617
+ if (200 <= res.status && res.status <= 299) {
2618
+ if (isDefined(attrs.success)) {
2619
+ $parse(attrs.success)(scope, { $res: html });
2620
+ }
2621
+
2622
+ if (isDefined(attrs.stateSuccess)) {
2623
+ $state.go(attrs.stateSuccess);
2624
+ }
2625
+ } else if (400 <= res.status && res.status <= 599) {
2626
+ if (isDefined(attrs.error)) {
2627
+ $parse(attrs.error)(scope, { $res: html });
2628
+ }
2629
+
2630
+ if (isDefined(attrs.stateError)) {
2631
+ $state.go(attrs.stateError);
2632
+ }
2633
+ }
2634
+
2635
+ if (isObject(html)) {
2636
+ if (attrs.target) {
2637
+ scope.$eval(`${attrs.target} = ${JSON.stringify(html)}`);
2638
+ } else {
2639
+ scope.$merge(html);
2640
+ }
2641
+ } else if (isString(html)) {
2642
+ handleSwapResponse(html, swap, scope, attrs, element);
2643
+ }
2644
+ };
2645
+
2646
+ if (isDefined(attrs.delay)) {
2647
+ await wait(parseInt(attrs.delay) | 0);
2648
+ }
2649
+
2650
+ if (throttled) return;
2651
+
2652
+ if (isDefined(attrs.throttle)) {
2653
+ throttled = true;
2654
+ attrs.$set("throttled", true);
2655
+ setTimeout(() => {
2656
+ attrs.$set("throttled", false);
2657
+ throttled = false;
2658
+ }, parseInt(attrs.throttle));
2659
+ }
2660
+
2661
+ if (isDefined(attrs["loading"])) {
2662
+ attrs.$set("loading", true);
2663
+ }
2664
+
2665
+ if (isDefined(attrs["loadingClass"])) {
2666
+ attrs.$addClass(attrs.loadingClass);
2667
+ }
2668
+
2669
+ if (method === "post" || method === "put") {
2670
+ let data;
2671
+ const config = {};
2672
+ if (attrs.enctype) {
2673
+ config.headers = {
2674
+ "Content-Type": attrs["enctype"],
2675
+ };
2676
+ data = toKeyValue(collectFormData(element));
2677
+ } else {
2678
+ data = collectFormData(element);
2679
+ }
2680
+ $http[method](url, data, config).then(handler).catch(handler);
2681
+ } else {
2682
+ if (method === "get" && attrs.ngSse) {
2683
+ const sseUrl = url;
2684
+ const config = {
2685
+ withCredentials: attrs.withCredentials === "true",
2686
+ transformMessage: (data) => {
2687
+ try {
2688
+ return JSON.parse(data);
2689
+ } catch {
2690
+ return data;
2691
+ }
2692
+ },
2693
+ onOpen: () => {
2694
+ $log.info(`${attrName}: SSE connection opened to ${sseUrl}`);
2695
+ if (isDefined(attrs.loading)) attrs.$set("loading", false);
2696
+ if (isDefined(attrs.loadingClass))
2697
+ attrs.$removeClass(attrs.loadingClass);
2698
+ },
2699
+ onMessage: (data) => {
2700
+ const res = { status: 200, data };
2701
+ handler(res);
2702
+ },
2703
+ onError: (err) => {
2704
+ $log.error(`${attrName}: SSE error`, err);
2705
+ const res = { status: 500, data: err };
2706
+ handler(res);
2707
+ },
2708
+ onReconnect: (count) => {
2709
+ $log.info(`ngSse: reconnected ${count} time(s)`);
2710
+ if (attrs.onReconnect)
2711
+ $parse(attrs.onReconnect)(scope, { $count: count });
2712
+ },
2713
+ };
2714
+
2715
+ const source = $sse(sseUrl, config);
2716
+
2717
+ scope.$on("$destroy", () => {
2718
+ $log.info(`${attrName}: closing SSE connection`);
2719
+ source.close();
2720
+ });
2721
+ } else {
2722
+ $http[method](url).then(handler).catch(handler);
2723
+ }
2724
+ }
2725
+ });
2726
+
2727
+ if (intervalId) {
2728
+ scope.$on("$destroy", () => clearInterval(intervalId));
2729
+ }
2730
+
2731
+ if (eventName == "load") {
2732
+ element.dispatchEvent(new Event("load"));
2733
+ }
2734
+ },
2735
+ };
2736
+ };
2737
+ }
2738
+
2739
+ ngWorkerDirective.$inject = [$injectTokens.$parse, $injectTokens.$log];
2740
+ /**
2741
+ * Usage: <div ng-worker="workerName" data-params="{{ expression }}" data-on-result="callback($result)"></div>
2742
+ *
2743
+ * @param {ng.ParseService} $parse
2744
+ * @param {ng.LogService} $log
2745
+ * @returns {ng.Directive}
2746
+ */
2747
+ function ngWorkerDirective($parse, $log) {
2748
+ return {
2749
+ restrict: "A",
2750
+ link(scope, element, attrs) {
2751
+ const workerName = attrs.ngWorker;
2752
+ if (!workerName) {
2753
+ $log.warn("ngWorker: missing worker name");
2754
+ return;
2755
+ }
2756
+
2757
+ /** @type {string} */
2758
+ const eventName = attrs.trigger || getEventNameForElement(element);
2759
+
2760
+ let throttled = false;
2761
+ let intervalId;
2762
+
2763
+ if (isDefined(attrs.latch)) {
2764
+ attrs.$observe(
2765
+ "latch",
2766
+ callBackAfterFirst(() => element.dispatchEvent(new Event(eventName))),
2767
+ );
2768
+ }
2769
+
2770
+ if (isDefined(attrs.interval)) {
2771
+ element.dispatchEvent(new Event(eventName));
2772
+ intervalId = setInterval(
2773
+ () => element.dispatchEvent(new Event(eventName)),
2774
+ parseInt(attrs.interval) || 1000,
2775
+ );
2776
+ }
2777
+
2778
+ const worker = createWorkerConnection(workerName, {
2779
+ onMessage: (result) => {
2780
+ if (isDefined(attrs.dataOnResult)) {
2781
+ $parse(attrs.dataOnResult)(scope, { $result: result });
2782
+ } else {
2783
+ const swap = attrs.swap || "innerHTML";
2784
+ handleSwap(result, swap, element);
2785
+ }
2786
+ },
2787
+ onError: (err) => {
2788
+ $log.error(`[ng-worker:${workerName}]`, err);
2789
+ if (isDefined(attrs.dataOnError)) {
2790
+ $parse(attrs.dataOnError)(scope, { $error: err });
2791
+ } else {
2792
+ element.textContent = "Error";
2793
+ }
2794
+ },
2795
+ });
2796
+
2797
+ element.addEventListener(eventName, async () => {
2798
+ if (element["disabled"]) return;
2799
+
2800
+ if (isDefined(attrs.delay)) {
2801
+ await wait(parseInt(attrs.delay) || 0);
2802
+ }
2803
+
2804
+ if (throttled) return;
2805
+
2806
+ if (isDefined(attrs.throttle)) {
2807
+ throttled = true;
2808
+ attrs.$set("throttled", true);
2809
+ setTimeout(() => {
2810
+ attrs.$set("throttled", false);
2811
+ throttled = false;
2812
+ }, parseInt(attrs.throttle));
2813
+ }
2814
+
2815
+ let params;
2816
+ try {
2817
+ params = attrs.params ? scope.$eval(attrs.params) : undefined;
2818
+ } catch (err) {
2819
+ $log.error("ngWorker: failed to evaluate data-params", err);
2820
+ params = undefined;
2821
+ }
2822
+
2823
+ worker.post(params);
2824
+ });
2825
+
2826
+ if (intervalId) {
2827
+ scope.$on("$destroy", () => clearInterval(intervalId));
2828
+ }
2829
+
2830
+ if (eventName === "load") {
2831
+ element.dispatchEvent(new Event("load"));
2832
+ }
2833
+ },
2834
+ };
2835
+ }
2836
+
2837
+ /**
2838
+ * Swap result into DOM based on strategy
2839
+ */
2840
+ function handleSwap(result, swap, element) {
2841
+ switch (swap) {
2842
+ case "outerHTML": {
2843
+ const parent = element.parentNode;
2844
+ if (!parent) return;
2845
+ const temp = document.createElement("div");
2846
+ temp.innerHTML = result;
2847
+ parent.replaceChild(temp.firstChild, element);
2848
+ break;
2849
+ }
2850
+ case "textContent":
2851
+ element.textContent = result;
2852
+ break;
2853
+ case "beforebegin":
2854
+ element.insertAdjacentHTML("beforebegin", result);
2855
+ break;
2856
+ case "afterbegin":
2857
+ element.insertAdjacentHTML("afterbegin", result);
2858
+ break;
2859
+ case "beforeend":
2860
+ element.insertAdjacentHTML("beforeend", result);
2861
+ break;
2862
+ case "afterend":
2863
+ element.insertAdjacentHTML("afterend", result);
2864
+ break;
2865
+ case "innerHTML":
2866
+ default:
2867
+ element.innerHTML = result;
2868
+ break;
2869
+ }
2870
+ }
2871
+
2872
+ /**
2873
+ * Creates a managed Web Worker connection.
2874
+ *
2875
+ * @param {string | URL} scriptPath
2876
+ * @param {ng.WorkerConfig} [config]
2877
+ * @returns {ng.WorkerConnection}
2878
+ */
2879
+ function createWorkerConnection(scriptPath, config) {
2880
+ if (!scriptPath) throw new Error("Worker script path required");
2881
+
2882
+ const defaults = {
2883
+ autoRestart: false,
2884
+ autoTerminate: false,
2885
+ onMessage: function () {},
2886
+ onError: function () {},
2887
+ transformMessage: function (data) {
2888
+ try {
2889
+ return JSON.parse(data);
2890
+ } catch {
2891
+ return data;
2892
+ }
2893
+ },
2894
+ };
2895
+
2896
+ /** @type {ng.WorkerConfig} */
2897
+ const cfg = Object.assign({}, defaults, config);
2898
+ let worker = new Worker(scriptPath, { type: "module" });
2899
+ let terminated = false;
2900
+
2901
+ const reconnect = function () {
2902
+ if (terminated) return;
2903
+ console.info("Worker: restarting...");
2904
+ worker.terminate();
2905
+ worker = new Worker(scriptPath, { type: "module" });
2906
+ wire(worker);
2907
+ };
2908
+
2909
+ const wire = function (w) {
2910
+ w.onmessage = function (e) {
2911
+ let data = e.data;
2912
+ try {
2913
+ data = cfg.transformMessage(data);
2914
+ } catch {
2915
+ /* no-op */
2916
+ }
2917
+ cfg.onMessage(data, e); // always provide both args
2918
+ };
2919
+
2920
+ w.onerror = function (err) {
2921
+ cfg.onError(err);
2922
+ if (cfg.autoRestart) reconnect();
2923
+ };
2924
+ };
2925
+
2926
+ wire(worker);
2927
+
2928
+ return {
2929
+ post: function (data) {
2930
+ if (terminated) return console.warn("Worker already terminated");
2931
+ try {
2932
+ worker.postMessage(data);
2933
+ } catch (err) {
2934
+ console.error("Worker post failed", err);
2935
+ }
2936
+ },
2937
+
2938
+ terminate: function () {
2939
+ terminated = true;
2940
+ worker.terminate();
2941
+ },
2942
+
2943
+ restart: function () {
2944
+ if (terminated)
2945
+ return console.warn("Worker cannot restart after terminate");
2946
+ reconnect();
2947
+ },
2948
+
2949
+ config: cfg,
2950
+ };
2951
+ }
2952
+
2221
2953
  /** @private */
2222
2954
  const INJECTOR_LITERAL = "$injector";
2223
2955
  /** @private */
@@ -2243,7 +2975,7 @@ class NgModule {
2243
2975
  /**
2244
2976
  * @param {string} name - Name of the module
2245
2977
  * @param {Array<string>} requires - List of modules which the injector will load before the current module
2246
- * @param {import("../../interface.ts").Injectable<any>} [configFn]
2978
+ * @param {ng.Injectable<any>} [configFn]
2247
2979
  */
2248
2980
  constructor(name, requires, configFn) {
2249
2981
  assert(isString(name), "name required");
@@ -2269,7 +3001,7 @@ class NgModule {
2269
3001
  /** @type {!Array<Array<*>>} */
2270
3002
  this.configBlocks = [];
2271
3003
 
2272
- /** @type {!Array.<import("../../interface.ts").Injectable<any>>} */
3004
+ /** @type {!Array.<ng.Injectable<any>>} */
2273
3005
  this.runBlocks = [];
2274
3006
 
2275
3007
  if (configFn) {
@@ -2277,6 +3009,8 @@ class NgModule {
2277
3009
  }
2278
3010
 
2279
3011
  this.services = [];
3012
+
3013
+ this.wasmModules = [];
2280
3014
  }
2281
3015
 
2282
3016
  /**
@@ -2301,7 +3035,7 @@ class NgModule {
2301
3035
 
2302
3036
  /**
2303
3037
  *
2304
- * @param {import("../../interface.ts").Injectable<any>} configFn
3038
+ * @param {ng.Injectable<any>} configFn
2305
3039
  * @returns {NgModule}
2306
3040
  */
2307
3041
  config(configFn) {
@@ -2310,7 +3044,7 @@ class NgModule {
2310
3044
  }
2311
3045
 
2312
3046
  /**
2313
- * @param {import("../../interface.ts").Injectable<any>} block
3047
+ * @param {ng.Injectable<any>} block
2314
3048
  * @returns {NgModule}
2315
3049
  */
2316
3050
  run(block) {
@@ -2320,7 +3054,7 @@ class NgModule {
2320
3054
 
2321
3055
  /**
2322
3056
  * @param {string} name
2323
- * @param {import("../../interface.ts").Component} options
3057
+ * @param {ng.Component} options
2324
3058
  * @returns {NgModule}
2325
3059
  */
2326
3060
  component(name, options) {
@@ -2333,7 +3067,7 @@ class NgModule {
2333
3067
 
2334
3068
  /**
2335
3069
  * @param {string} name
2336
- * @param {import("../../interface.ts").Injectable<any>} providerFunction
3070
+ * @param {ng.Injectable<any>} providerFunction
2337
3071
  * @returns {NgModule}
2338
3072
  */
2339
3073
  factory(name, providerFunction) {
@@ -2346,7 +3080,7 @@ class NgModule {
2346
3080
 
2347
3081
  /**
2348
3082
  * @param {string} name
2349
- * @param {import("../../interface.ts").Injectable<any>} serviceFunction
3083
+ * @param {ng.Injectable<any>} serviceFunction
2350
3084
  * @returns {NgModule}
2351
3085
  */
2352
3086
  service(name, serviceFunction) {
@@ -2360,7 +3094,7 @@ class NgModule {
2360
3094
 
2361
3095
  /**
2362
3096
  * @param {string} name
2363
- * @param {import("../../interface.ts").Injectable<any>} providerType
3097
+ * @param {ng.Injectable<any>} providerType
2364
3098
  * @returns {NgModule}
2365
3099
  */
2366
3100
  provider(name, providerType) {
@@ -2373,7 +3107,7 @@ class NgModule {
2373
3107
 
2374
3108
  /**
2375
3109
  * @param {string} name
2376
- * @param {import("../../interface.ts").Injectable<any>} decorFn
3110
+ * @param {ng.Injectable<any>} decorFn
2377
3111
  * @returns {NgModule}
2378
3112
  */
2379
3113
  decorator(name, decorFn) {
@@ -2386,7 +3120,7 @@ class NgModule {
2386
3120
 
2387
3121
  /**
2388
3122
  * @param {string} name
2389
- * @param {import("../../interface.ts").Injectable<any>} directiveFactory
3123
+ * @param {ng.Injectable<any>} directiveFactory
2390
3124
  * @returns {NgModule}
2391
3125
  */
2392
3126
  directive(name, directiveFactory) {
@@ -2403,7 +3137,7 @@ class NgModule {
2403
3137
 
2404
3138
  /**
2405
3139
  * @param {string} name
2406
- * @param {import("../../interface.ts").Injectable<any>} animationFactory
3140
+ * @param {ng.Injectable<any>} animationFactory
2407
3141
  * @returns {NgModule}
2408
3142
  */
2409
3143
  animation(name, animationFactory) {
@@ -2420,7 +3154,7 @@ class NgModule {
2420
3154
 
2421
3155
  /**
2422
3156
  * @param {string} name
2423
- * @param {import("../../interface.ts").Injectable<any>} filterFn
3157
+ * @param {ng.Injectable<any>} filterFn
2424
3158
  * @return {NgModule}
2425
3159
  */
2426
3160
  filter(name, filterFn) {
@@ -2433,7 +3167,7 @@ class NgModule {
2433
3167
 
2434
3168
  /**
2435
3169
  * @param {string} name
2436
- * @param {import("../../interface.ts").Injectable<any>} ctlFn
3170
+ * @param {ng.Injectable<any>} ctlFn
2437
3171
  * @returns {NgModule}
2438
3172
  */
2439
3173
  controller(name, ctlFn) {
@@ -2443,12 +3177,192 @@ class NgModule {
2443
3177
  this.invokeQueue.push([CONTROLLER_LITERAL, "register", [name, ctlFn]]);
2444
3178
  return this;
2445
3179
  }
3180
+
3181
+ /**
3182
+ * Register a named WebAssembly module that will be instantiated via $provide.
3183
+ *
3184
+ * @param {string} name - The injectable name used to access the instantiated WebAssembly module.
3185
+ *
3186
+ * @param {string} src - URL of the `.wasm` file to fetch and instantiate.
3187
+ *
3188
+ * @param {Object<string, any>} [imports] WebAssembly import object, passed to `WebAssembly.instantiate` or `WebAssembly.instantiateStreaming`.
3189
+ *
3190
+ * @param {Object<string, any>} [opts] - Configuration object.
3191
+ *
3192
+ * Supported keys:
3193
+ * - **raw**: `boolean`
3194
+ * - `false` (default): the injectable resolves to `instance.exports`
3195
+ * (ideal for plain WASM modules).
3196
+ * - `true`: the injectable resolves to the full instantiation result:
3197
+ * `{ instance, exports, module }`
3198
+ * (required for runtimes such as Go, Emscripten, wasm-bindgen, etc).
3199
+ *
3200
+ * @returns {NgModule}
3201
+ */
3202
+ wasm(name, src, imports = {}, opts = {}) {
3203
+ const raw = !!opts.raw;
3204
+
3205
+ this.invokeQueue.push([
3206
+ $injectTokens.$provide,
3207
+ "provider",
3208
+ [
3209
+ name,
3210
+ function () {
3211
+ this.$get = () => {
3212
+ return instantiateWasm(src, imports).then((result) =>
3213
+ raw ? result : result.exports,
3214
+ );
3215
+ };
3216
+ },
3217
+ ],
3218
+ ]);
3219
+
3220
+ return this;
3221
+ }
3222
+
3223
+ /**
3224
+ * Register a named worker that will be instantiated via $provide.
3225
+ *
3226
+ * @param {string} name
3227
+ * @param {string | URL} scriptPath
3228
+ * @param {ng.WorkerConfig} [config]
3229
+ * @returns {NgModule}
3230
+ */
3231
+ worker(name, scriptPath, config = {}) {
3232
+ this.invokeQueue.push([
3233
+ $injectTokens.$provide,
3234
+ "provider",
3235
+ [
3236
+ name,
3237
+ function () {
3238
+ this.$get = function () {
3239
+ return createWorkerConnection(scriptPath, config);
3240
+ };
3241
+ },
3242
+ ],
3243
+ ]);
3244
+ return this;
3245
+ }
3246
+
3247
+ /**
3248
+ * @param {string} name
3249
+ * @param {Function} ctor
3250
+ * @returns {NgModule}
3251
+ */
3252
+ session(name, ctor) {
3253
+ if (ctor && isFunction(ctor)) {
3254
+ ctor["$$moduleName"] = name;
3255
+ }
3256
+ this.invokeQueue.push([$injectTokens.$provide, "session", [name, ctor]]);
3257
+ return this;
3258
+ }
3259
+
3260
+ /**
3261
+ * @param {string} name
3262
+ * @param {Function} ctor
3263
+ * @returns {NgModule}
3264
+ */
3265
+ local(name, ctor) {
3266
+ if (ctor && isFunction(ctor)) {
3267
+ ctor["$$moduleName"] = name;
3268
+ }
3269
+ this.invokeQueue.push([$injectTokens.$provide, "local", [name, ctor]]);
3270
+ return this;
3271
+ }
3272
+
3273
+ /**
3274
+ * @param {string} name
3275
+ * @param {Function} ctor
3276
+ * @param {ng.StorageBackend} backendOrConfig
3277
+ * @returns {NgModule}
3278
+ */
3279
+ store(name, ctor, backendOrConfig) {
3280
+ if (ctor && isFunction(ctor)) {
3281
+ ctor["$$moduleName"] = name;
3282
+ }
3283
+ this.invokeQueue.push([
3284
+ $injectTokens.$provide,
3285
+ "store",
3286
+ [name, ctor, backendOrConfig],
3287
+ ]);
3288
+ return this;
3289
+ }
3290
+ }
3291
+
3292
+ /**
3293
+ * Shared utility functions
3294
+ */
3295
+
3296
+ const $injectorMinErr$3 = minErr(INJECTOR_LITERAL);
3297
+ const ARROW_ARG = /^([^(]+?)=>/;
3298
+ const FN_ARGS = /^[^(]*\(\s*([^)]*)\)/m;
3299
+ const FN_ARG = /^\s*(_?)(\S+?)\1\s*$/;
3300
+ const STRIP_COMMENTS = /((\/\/.*$)|(\/\*[\s\S]*?\*\/))/gm;
3301
+
3302
+ /**
3303
+ * @param {Function} fn
3304
+ * @returns {string}
3305
+ */
3306
+ function stringifyFn(fn) {
3307
+ return Function.prototype.toString.call(fn);
3308
+ }
3309
+
3310
+ /**
3311
+ * @param {Function} fn
3312
+ * @returns {Array<any>}
3313
+ */
3314
+ function extractArgs(fn) {
3315
+ const fnText = stringifyFn(fn).replace(STRIP_COMMENTS, "");
3316
+ return fnText.match(ARROW_ARG) || fnText.match(FN_ARGS);
3317
+ }
3318
+
3319
+ /**
3320
+ * @param {Function} func
3321
+ * @returns {boolean}
3322
+ */
3323
+ function isClass(func) {
3324
+ return /^class\b/.test(stringifyFn(func));
3325
+ }
3326
+
3327
+ /**
3328
+ * @param {any} fn
3329
+ * @param {boolean} [strictDi]
3330
+ * @param {string} [name]
3331
+ * @returns {Array<string>}
3332
+ */
3333
+ function annotate(fn, strictDi, name) {
3334
+ let $inject, argDecl, last;
3335
+
3336
+ if (typeof fn === "function") {
3337
+ if (!($inject = fn.$inject)) {
3338
+ $inject = [];
3339
+ if (fn.length) {
3340
+ if (strictDi) {
3341
+ throw $injectorMinErr$3(
3342
+ "strictdi",
3343
+ "{0} is not using explicit annotation and cannot be invoked in strict mode",
3344
+ name,
3345
+ );
3346
+ }
3347
+ argDecl = extractArgs(fn);
3348
+ argDecl[1].split(/,/).forEach(function (arg) {
3349
+ arg.replace(FN_ARG, function (_all, _underscore, name) {
3350
+ $inject.push(name);
3351
+ });
3352
+ });
3353
+ }
3354
+ fn.$inject = $inject;
3355
+ }
3356
+ } else if (Array.isArray(fn)) {
3357
+ last = /** @type {Array} */ (fn).length - 1;
3358
+ assertArgFn(fn[last], "fn");
3359
+ $inject = /** @type {Array} */ (fn).slice(0, last);
3360
+ } else {
3361
+ assertArgFn(fn, "fn", true);
3362
+ }
3363
+ return $inject;
2446
3364
  }
2447
3365
 
2448
- const ARROW_ARG$1 = /^([^(]+?)=>/;
2449
- const FN_ARGS$1 = /^[^(]*\(\s*([^)]*)\)/m;
2450
- const FN_ARG$1 = /^\s*(_?)(\S+?)\1\s*$/;
2451
- const STRIP_COMMENTS$1 = /((\/\/.*$)|(\/\*[\s\S]*?\*\/))/gm;
2452
3366
  const $injectorMinErr$2 = minErr(INJECTOR_LITERAL);
2453
3367
 
2454
3368
  const providerSuffix$1 = "Provider";
@@ -2467,7 +3381,7 @@ class AbstractInjector {
2467
3381
  this.strictDi = strictDi;
2468
3382
  /** @type {string[]} */
2469
3383
  this.path = [];
2470
- /** @type {Object.<string, import("./ng-module.js").NgModule>} */
3384
+ /** @type {Object.<string, ng.NgModule>} */
2471
3385
  this.modules = {};
2472
3386
  }
2473
3387
 
@@ -2511,7 +3425,7 @@ class AbstractInjector {
2511
3425
  */
2512
3426
  injectionArgs(fn, locals, serviceName) {
2513
3427
  const args = [];
2514
- const $inject = annotate$1(fn, this.strictDi, serviceName);
3428
+ const $inject = annotate(fn, this.strictDi, serviceName);
2515
3429
 
2516
3430
  for (let i = 0, { length } = $inject; i < length; i++) {
2517
3431
  const key = $inject[i];
@@ -2634,7 +3548,7 @@ class InjectorService extends AbstractInjector {
2634
3548
 
2635
3549
  /** @type {ProviderInjector} */
2636
3550
  this.providerInjector = providerInjector;
2637
- /** @type {Object.<string, import("./ng-module.js").NgModule>} */
3551
+ /** @type {Object.<string, ng.NgModule>} */
2638
3552
  this.modules = providerInjector.modules;
2639
3553
  }
2640
3554
 
@@ -2664,78 +3578,52 @@ class InjectorService extends AbstractInjector {
2664
3578
  loadNewModules() {}
2665
3579
  }
2666
3580
 
2667
- // Helpers
2668
-
2669
- /**
2670
- * @param {Function} fn
2671
- * @returns {string}
2672
- */
2673
- function stringifyFn$1(fn) {
2674
- return Function.prototype.toString.call(fn);
2675
- }
2676
-
2677
- /**
2678
- * @param {Function} fn
2679
- * @returns {Array<any>}
2680
- */
2681
- function extractArgs$1(fn) {
2682
- const fnText = stringifyFn$1(fn).replace(STRIP_COMMENTS$1, "");
2683
- return fnText.match(ARROW_ARG$1) || fnText.match(FN_ARGS$1);
2684
- }
2685
-
2686
- /**
2687
- * @param {Function} func
2688
- * @returns {boolean}
2689
- */
2690
- function isClass(func) {
2691
- return /^class\b/.test(stringifyFn$1(func));
2692
- }
2693
-
2694
3581
  /**
3582
+ * Creates a proxy that automatically persists an object's state
3583
+ * into a storage backend whenever a property is set.
2695
3584
  *
2696
- * @param {any} fn
2697
- * @param {boolean} strictDi
2698
- * @param {string} name
2699
- * @returns {Array<string>}
3585
+ * @param {object} target - The object to wrap
3586
+ * @param {string} key - The storage key
3587
+ * @param {object} storage - Any storage-like object with getItem/setItem/removeItem
3588
+ * @param {{serialize?: function, deserialize?: function}} [options] - Optional custom (de)serialization
3589
+ * @returns {Proxy}
2700
3590
  */
2701
- function annotate$1(fn, strictDi, name) {
2702
- let $inject, argDecl, last;
3591
+ function createPersistentProxy(target, key, storage, options = {}) {
3592
+ const serialize = options.serialize || JSON.stringify;
3593
+ const deserialize = options.deserialize || JSON.parse;
2703
3594
 
2704
- if (typeof fn === "function") {
2705
- if (!($inject = fn.$inject)) {
2706
- $inject = [];
2707
- if (fn.length) {
2708
- if (strictDi) {
2709
- throw $injectorMinErr$2(
2710
- "strictdi",
2711
- "{0} is not using explicit annotation and cannot be invoked in strict mode",
2712
- name,
2713
- );
2714
- }
2715
- argDecl = extractArgs$1(fn);
2716
- argDecl[1].split(/,/).forEach(function (arg) {
2717
- arg.replace(FN_ARG$1, function (_all, _underscore, name) {
2718
- $inject.push(name);
2719
- });
2720
- });
2721
- }
2722
- fn.$inject = $inject;
3595
+ // Restore saved state
3596
+ const saved = storage.getItem(key);
3597
+ if (saved) {
3598
+ try {
3599
+ Object.assign(target, deserialize(saved));
3600
+ } catch {
3601
+ console.warn(`Failed to deserialize persisted data for key "${key}"`);
2723
3602
  }
2724
- } else if (Array.isArray(fn)) {
2725
- last = /** @type {Array} */ (fn).length - 1;
2726
- assertArgFn(fn[last], "fn");
2727
- $inject = /** @type {Array} */ (fn).slice(0, last);
2728
- } else {
2729
- assertArgFn(fn, "fn", true);
2730
3603
  }
2731
- return $inject;
3604
+
3605
+ return new Proxy(target, {
3606
+ set(obj, prop, value) {
3607
+ obj[prop] = value;
3608
+ try {
3609
+ storage.setItem(key, serialize(obj));
3610
+ } catch {
3611
+ console.warn(`Failed to persist data for key "${key}"`);
3612
+ }
3613
+ return true;
3614
+ },
3615
+ deleteProperty(obj, prop) {
3616
+ const deleted = delete obj[prop];
3617
+ try {
3618
+ storage.setItem(key, serialize(obj));
3619
+ } catch {
3620
+ console.warn(`Failed to persist data for key "${key}"`);
3621
+ }
3622
+ return deleted;
3623
+ },
3624
+ });
2732
3625
  }
2733
3626
 
2734
- const ARROW_ARG = /^([^(]+?)=>/;
2735
- const FN_ARGS = /^[^(]*\(\s*([^)]*)\)/m;
2736
- const FN_ARG_SPLIT = /,/;
2737
- const FN_ARG = /^\s*(_?)(\S+?)\1\s*$/;
2738
- const STRIP_COMMENTS = /((\/\/.*$)|(\/\*[\s\S]*?\*\/))/gm;
2739
3627
  const $injectorMinErr$1 = minErr(INJECTOR_LITERAL);
2740
3628
  const providerSuffix = "Provider";
2741
3629
 
@@ -2758,6 +3646,9 @@ function createInjector(modulesToLoad, strictDi = false) {
2758
3646
  service: supportObject(service),
2759
3647
  value: supportObject(value),
2760
3648
  constant: supportObject(constant),
3649
+ session: supportObject(session),
3650
+ local: supportObject(local),
3651
+ store: supportObject(store),
2761
3652
  decorator,
2762
3653
  },
2763
3654
  };
@@ -2891,13 +3782,78 @@ function createInjector(modulesToLoad, strictDi = false) {
2891
3782
  };
2892
3783
  }
2893
3784
 
3785
+ /**
3786
+ * Registers a session-persistent service
3787
+ */
3788
+ function session(name, ctor) {
3789
+ return provider(name, {
3790
+ $get: ($injector) => {
3791
+ const instance = $injector.instantiate(ctor);
3792
+ return createPersistentProxy(instance, name, sessionStorage);
3793
+ },
3794
+ });
3795
+ }
3796
+
3797
+ /**
3798
+ * Registers a localStorage-persistent service
3799
+ */
3800
+ function local(name, ctor) {
3801
+ return provider(name, {
3802
+ $get: ($injector) => {
3803
+ const instance = $injector.instantiate(ctor);
3804
+ return createPersistentProxy(instance, name, localStorage);
3805
+ },
3806
+ });
3807
+ }
3808
+
3809
+ /**
3810
+ * Registers a service persisted in a custom storage
3811
+ *
3812
+ * @param {string} name - Service name
3813
+ * @param {Function} ctor - Constructor for the service
3814
+ * @param {Storage|Object} backendOrConfig - Either a Storage-like object (getItem/setItem) or a config object
3815
+ * with { backend, serialize, deserialize }
3816
+ */
3817
+ function store(name, ctor, backendOrConfig) {
3818
+ return provider(name, {
3819
+ $get: ($injector) => {
3820
+ const instance = $injector.instantiate(ctor);
3821
+
3822
+ let backend;
3823
+ let serialize = JSON.stringify;
3824
+ let deserialize = JSON.parse;
3825
+
3826
+ if (backendOrConfig) {
3827
+ if (typeof backendOrConfig.getItem === "function") {
3828
+ // raw Storage object
3829
+ backend = backendOrConfig;
3830
+ } else if (isObject(backendOrConfig)) {
3831
+ backend = backendOrConfig.backend || localStorage;
3832
+ if (backendOrConfig.serialize)
3833
+ serialize = backendOrConfig.serialize;
3834
+ if (backendOrConfig.deserialize)
3835
+ deserialize = backendOrConfig.deserialize;
3836
+ }
3837
+ } else {
3838
+ // fallback default
3839
+ backend = localStorage;
3840
+ }
3841
+
3842
+ return createPersistentProxy(instance, name, backend, {
3843
+ serialize,
3844
+ deserialize,
3845
+ });
3846
+ },
3847
+ });
3848
+ }
3849
+
2894
3850
  /**
2895
3851
  *
2896
3852
  * @param {Array<String|Function>} modulesToLoad
2897
3853
  * @returns
2898
3854
  */
2899
3855
  function loadModules(modulesToLoad) {
2900
- assertArg$1(
3856
+ assertArg(
2901
3857
  isUndefined(modulesToLoad) || Array.isArray(modulesToLoad),
2902
3858
  "modulesToLoad",
2903
3859
  "not an array",
@@ -2910,8 +3866,10 @@ function createInjector(modulesToLoad, strictDi = false) {
2910
3866
 
2911
3867
  try {
2912
3868
  if (isString(module)) {
2913
- /** @type {import('./ng-module.js').NgModule} */
2914
- const moduleFn = window["angular"].module(module);
3869
+ /** @type {ng.NgModule} */
3870
+ const moduleFn = window["angular"].module(
3871
+ /** @type {string} */ (module),
3872
+ );
2915
3873
  instanceInjector.modules[/** @type {string } */ (module)] = moduleFn;
2916
3874
  runBlocks = runBlocks
2917
3875
  .concat(loadModules(moduleFn.requires))
@@ -2955,64 +3913,6 @@ function createInjector(modulesToLoad, strictDi = false) {
2955
3913
  }
2956
3914
  }
2957
3915
 
2958
- // Helpers
2959
-
2960
- /**
2961
- * @param {String} fn
2962
- * @returns {String}
2963
- */
2964
- function stringifyFn(fn) {
2965
- return Function.prototype.toString.call(fn);
2966
- }
2967
-
2968
- /**
2969
- * @param {String} fn
2970
- * @returns {Array<any>}
2971
- */
2972
- function extractArgs(fn) {
2973
- const fnText = stringifyFn(fn).replace(STRIP_COMMENTS, "");
2974
- return fnText.match(ARROW_ARG) || fnText.match(FN_ARGS);
2975
- }
2976
-
2977
- /**
2978
- * @param {any} fn
2979
- * @param {boolean} [strictDi]
2980
- * @param {String} [name]
2981
- * @returns {Array<string>}
2982
- */
2983
- function annotate(fn, strictDi, name) {
2984
- let $inject, argDecl, last;
2985
-
2986
- if (typeof fn === "function") {
2987
- if (!($inject = fn.$inject)) {
2988
- $inject = [];
2989
- if (fn.length) {
2990
- if (strictDi) {
2991
- throw $injectorMinErr$1(
2992
- "strictdi",
2993
- "{0} is not using explicit annotation and cannot be invoked in strict mode",
2994
- name,
2995
- );
2996
- }
2997
- argDecl = extractArgs(/** @type {String} */ (fn));
2998
- argDecl[1].split(FN_ARG_SPLIT).forEach(function (arg) {
2999
- arg.replace(FN_ARG, function (all, underscore, name) {
3000
- $inject.push(name);
3001
- });
3002
- });
3003
- }
3004
- fn.$inject = $inject;
3005
- }
3006
- } else if (Array.isArray(fn)) {
3007
- last = /** @type {Array} */ (fn).length - 1;
3008
- assertArgFn(fn[last], "fn");
3009
- $inject = /** @type {Array} */ (fn).slice(0, last);
3010
- } else {
3011
- assertArgFn(fn, "fn", true);
3012
- }
3013
- return $inject;
3014
- }
3015
-
3016
3916
  function supportObject(delegate) {
3017
3917
  return function (key, value) {
3018
3918
  if (isObject(key)) {
@@ -3035,7 +3935,7 @@ class NodeRef {
3035
3935
  * @throws {Error} If the argument is invalid or cannot be wrapped properly.
3036
3936
  */
3037
3937
  constructor(element) {
3038
- assertArg$1(element, "element");
3938
+ assertArg(element, "element");
3039
3939
  this.initial = null;
3040
3940
 
3041
3941
  /** @private @type {Node | ChildNode | null} */
@@ -3091,8 +3991,8 @@ class NodeRef {
3091
3991
  }
3092
3992
 
3093
3993
  // Handle array of elements
3094
- else if (element instanceof Array) {
3095
- if (element.length == 1) {
3994
+ else if (Array.isArray(element)) {
3995
+ if (element.length === 1) {
3096
3996
  this.initial = element[0].cloneNode(true);
3097
3997
  this.node = element[0];
3098
3998
  } else {
@@ -3106,13 +4006,13 @@ class NodeRef {
3106
4006
 
3107
4007
  /** @returns {Element} */
3108
4008
  get element() {
3109
- assertArg$1(this._element, "element");
4009
+ assertArg(this._element, "element");
3110
4010
  return this._element;
3111
4011
  }
3112
4012
 
3113
4013
  /** @param {Element} el */
3114
4014
  set element(el) {
3115
- assertArg$1(el instanceof Element, "element");
4015
+ assertArg(el instanceof Element, "element");
3116
4016
  this._element = el;
3117
4017
  this._nodes = undefined;
3118
4018
  this.isList = false;
@@ -3120,13 +4020,13 @@ class NodeRef {
3120
4020
 
3121
4021
  /** @returns {Node | ChildNode} */
3122
4022
  get node() {
3123
- assertArg$1(this._node || this._element, "node");
4023
+ assertArg(this._node || this._element, "node");
3124
4024
  return this._node || this._element;
3125
4025
  }
3126
4026
 
3127
4027
  /** @param {Node | ChildNode} node */
3128
4028
  set node(node) {
3129
- assertArg$1(node instanceof Node, "node");
4029
+ assertArg(node instanceof Node, "node");
3130
4030
  this._node = node;
3131
4031
  if (node.nodeType === Node.ELEMENT_NODE) {
3132
4032
  this._element = /** @type {Element} */ (node);
@@ -3137,7 +4037,7 @@ class NodeRef {
3137
4037
 
3138
4038
  /** @param {Array<Node>} nodes */
3139
4039
  set nodes(nodes) {
3140
- assertArg$1(
4040
+ assertArg(
3141
4041
  Array.isArray(nodes) && nodes.every((n) => n instanceof Node),
3142
4042
  "nodes",
3143
4043
  );
@@ -3147,25 +4047,18 @@ class NodeRef {
3147
4047
 
3148
4048
  /** @returns {Array<Node>} */
3149
4049
  get nodes() {
3150
- assertArg$1(this._nodes, "nodes");
4050
+ assertArg(this._nodes, "nodes");
3151
4051
  return this._nodes;
3152
4052
  }
3153
4053
 
3154
4054
  /** @returns {NodeList|Node[]} */
3155
4055
  get nodelist() {
3156
- assertArg$1(this.isList, "nodes");
3157
- if (this._nodes.length === 0) {
3158
- return this._nodes;
3159
- }
3160
- if (this._nodes[0].parentElement) {
4056
+ if (this._nodes.length === 0) return [];
4057
+ if (this._nodes[0].parentElement)
3161
4058
  return this._nodes[0].parentElement.childNodes;
3162
- } else {
3163
- const fragment = document.createDocumentFragment();
3164
- this._nodes.forEach((el) => {
3165
- fragment.appendChild(el);
3166
- });
3167
- return fragment.childNodes;
3168
- }
4059
+ const fragment = document.createDocumentFragment();
4060
+ this._nodes.forEach((el) => fragment.appendChild(el));
4061
+ return fragment.childNodes;
3169
4062
  }
3170
4063
 
3171
4064
  /** @returns {Element | Node | ChildNode | NodeList | Node[]} */
@@ -3223,8 +4116,8 @@ class NodeRef {
3223
4116
  * @param {Element | Node | ChildNode} node
3224
4117
  */
3225
4118
  setIndex(index, node) {
3226
- assertArg$1(index !== null, "index");
3227
- assertArg$1(node, "node");
4119
+ assertArg(index !== null, "index");
4120
+ assertArg(node, "node");
3228
4121
  if (this.isList) {
3229
4122
  this._nodes[index] = node;
3230
4123
  } else {
@@ -3310,7 +4203,7 @@ class ControllerProvider {
3310
4203
  "$injector",
3311
4204
 
3312
4205
  /**
3313
- * @param {import("../../core/di/internal-injector.js").InjectorService} $injector
4206
+ * @param {ng.InjectorService} $injector
3314
4207
  * @returns {import("./interface.ts").ControllerService} A service function that creates controllers.
3315
4208
  */
3316
4209
  ($injector) => {
@@ -3363,6 +4256,10 @@ class ControllerProvider {
3363
4256
  );
3364
4257
  }
3365
4258
 
4259
+ if (instance?.constructor?.$scopename) {
4260
+ locals.$scope.$scopename = instance.constructor.$scopename;
4261
+ }
4262
+
3366
4263
  return function () {
3367
4264
  const result = $injector.invoke(
3368
4265
  expression,
@@ -3625,7 +4522,7 @@ function adjustMatcher(matcher) {
3625
4522
  * `$sceDelegate` is a service that is used by the `$sce` service to provide {@link ng.$sce Strict
3626
4523
  * Contextual Escaping (SCE)} services to AngularTS.
3627
4524
  *
3628
- * For an overview of this service and the functionnality it provides in AngularTS, see the main
4525
+ * For an overview of this service and the functionality it provides in AngularTS, see the main
3629
4526
  * page for {@link ng.$sce SCE}. The current page is targeted for developers who need to alter how
3630
4527
  * SCE works in their application, which shouldn't be needed in most cases.
3631
4528
  *
@@ -3652,85 +4549,6 @@ function adjustMatcher(matcher) {
3652
4549
  * ng.$sceDelegateProvider#bannedResourceUrlList $sceDelegateProvider.bannedResourceUrlList}
3653
4550
  */
3654
4551
 
3655
- /**
3656
- *
3657
- * The `$sceDelegateProvider` provider allows developers to configure the {@link ng.$sceDelegate
3658
- * $sceDelegate service}, used as a delegate for {@link ng.$sce Strict Contextual Escaping (SCE)}.
3659
- *
3660
- * The `$sceDelegateProvider` allows one to get/set the `trustedResourceUrlList` and
3661
- * `bannedResourceUrlList` used to ensure that the URLs used for sourcing AngularTS templates and
3662
- * other script-running URLs are safe (all places that use the `$sce.RESOURCE_URL` context). See
3663
- * {@link ng.$sceDelegateProvider#trustedResourceUrlList
3664
- * $sceDelegateProvider.trustedResourceUrlList} and
3665
- * {@link ng.$sceDelegateProvider#bannedResourceUrlList $sceDelegateProvider.bannedResourceUrlList},
3666
- *
3667
- * For the general details about this service in AngularTS, read the main page for {@link ng.$sce
3668
- * Strict Contextual Escaping (SCE)}.
3669
- *
3670
- * **Example**: Consider the following case. <a name="example"></a>
3671
- *
3672
- * - your app is hosted at url `http://myapp.example.com/`
3673
- * - but some of your templates are hosted on other domains you control such as
3674
- * `http://srv01.assets.example.com/`, `http://srv02.assets.example.com/`, etc.
3675
- * - and you have an open redirect at `http://myapp.example.com/clickThru?...`.
3676
- *
3677
- * Here is what a secure configuration for this scenario might look like:
3678
- *
3679
- * ```
3680
- * angular.module('myApp', []).config(function($sceDelegateProvider) {
3681
- * $sceDelegateProvider.trustedResourceUrlList([
3682
- * // Allow same origin resource loads.
3683
- * 'self',
3684
- * // Allow loading from our assets domain. Notice the difference between * and **.
3685
- * 'http://srv*.assets.example.com/**'
3686
- * ]);
3687
- *
3688
- * // The banned resource URL list overrides the trusted resource URL list so the open redirect
3689
- * // here is blocked.
3690
- * $sceDelegateProvider.bannedResourceUrlList([
3691
- * 'http://myapp.example.com/clickThru**'
3692
- * ]);
3693
- * });
3694
- * ```
3695
- * Note that an empty trusted resource URL list will block every resource URL from being loaded, and will require
3696
- * you to manually mark each one as trusted with `$sce.trustAsResourceUrl`. However, templates
3697
- * requested by {@link ng.$templateRequest $templateRequest} that are present in
3698
- * {@link ng.$templateCache $templateCache} will not go through this check. If you have a mechanism
3699
- * to populate your templates in that cache at config time, then it is a good idea to remove 'self'
3700
- * from the trusted resource URL lsit. This helps to mitigate the security impact of certain types
3701
- * of issues, like for instance attacker-controlled `ng-includes`.
3702
- */
3703
-
3704
- /**
3705
- * `$sceDelegate` is a service that is used by the `$sce` service to provide {@link ng.$sce Strict
3706
- * Contextual Escaping (SCE)} services to AngularTS.
3707
- *
3708
- * For an overview of this service and the functionnality it provides in AngularTS, see the main
3709
- * page for {@link ng.$sce SCE}. The current page is targeted for developers who need to alter how
3710
- * SCE works in their application, which shouldn't be needed in most cases.
3711
- *
3712
- * <div class="alert alert-danger">
3713
- * AngularTS strongly relies on contextual escaping for the security of bindings: disabling or
3714
- * modifying this might cause cross site scripting (XSS) vulnerabilities. For libraries owners,
3715
- * changes to this service will also influence users, so be extra careful and document your changes.
3716
- * </div>
3717
- *
3718
- * Typically, you would configure or override the {@link ng.$sceDelegate $sceDelegate} instead of
3719
- * the `$sce` service to customize the way Strict Contextual Escaping works in AngularTS. This is
3720
- * because, while the `$sce` provides numerous shorthand methods, etc., you really only need to
3721
- * override 3 core functions (`trustAs`, `getTrusted` and `valueOf`) to replace the way things
3722
- * work because `$sce` delegates to `$sceDelegate` for these operations.
3723
- *
3724
- * Refer {@link ng.$sceDelegateProvider $sceDelegateProvider} to configure this service.
3725
- *
3726
- * The default instance of `$sceDelegate` should work out of the box with little pain. While you
3727
- * can override it completely to change the behavior of `$sce`, the common case would
3728
- * involve configuring the {@link ng.$sceDelegateProvider $sceDelegateProvider} instead by setting
3729
- * your own trusted and banned resource lists for trusting URLs used for loading AngularTS resources
3730
- * such as templates. Refer {@link ng.$sceDelegateProvider#trustedResourceUrlList
3731
- * $sceDelegateProvider.trustedResourceUrlList} and {@link
3732
- * ng.$sceDelegateProvider#bannedResourceUrlList $sceDelegateProvider.bannedResourceUrlList}
3733
- */
3734
4552
  /**
3735
4553
  *
3736
4554
  * The `$sceDelegateProvider` provider allows developers to configure the {@link ng.$sceDelegate
@@ -3787,7 +4605,7 @@ class SceDelegateProvider {
3787
4605
 
3788
4606
  /**
3789
4607
  *
3790
- * @param {Array=} trustedResourceUrlList When provided, replaces the trustedResourceUrlList with
4608
+ * @param {Array=} value When provided, replaces the trustedResourceUrlList with
3791
4609
  * the value provided. This must be an array or null. A snapshot of this array is used so
3792
4610
  * further changes to the array are ignored.
3793
4611
  * Follow {@link ng.$sce#resourceUrlPatternItem this link} for a description of the items
@@ -3849,7 +4667,7 @@ class SceDelegateProvider {
3849
4667
  /**
3850
4668
  *
3851
4669
  * @param {ng.InjectorService} $injector
3852
- * @param {*} $$sanitizeUri
4670
+ * @param {import("../../core/sanitize/interface.ts").SanitizerFn} $$sanitizeUri
3853
4671
  * @param {ng.ExceptionHandlerService} $exceptionHandler
3854
4672
  * @returns
3855
4673
  */
@@ -4371,7 +5189,7 @@ function SceProvider() {
4371
5189
  const { trustAs } = sce;
4372
5190
 
4373
5191
  Object.entries(SCE_CONTEXTS).forEach(([name, enumValue]) => {
4374
- const lName = lowercase(name);
5192
+ const lName = name.toLowerCase();
4375
5193
  sce[snakeToCamel(`parse_as_${lName}`)] = function (expr) {
4376
5194
  return parse(enumValue, expr);
4377
5195
  };
@@ -4505,8 +5323,8 @@ class Attributes {
4505
5323
  static $nonscope = true;
4506
5324
 
4507
5325
  /**
4508
- * @param {ng.Scope} $rootScope
4509
- * @param {*} $animate
5326
+ * @param {ng.RootScopeService} $rootScope
5327
+ * @param {ng.AnimateService} $animate
4510
5328
  * @param {ng.ExceptionHandlerService} $exceptionHandler
4511
5329
  * @param {*} $sce
4512
5330
  * @param {import("../../shared/noderef.js").NodeRef} [nodeRef]
@@ -4564,7 +5382,10 @@ class Attributes {
4564
5382
  $addClass(classVal) {
4565
5383
  if (classVal && classVal.length > 0) {
4566
5384
  if (hasAnimate(this.$$element)) {
4567
- this.$animate.addClass(this.$$element, classVal);
5385
+ this.$animate.addClass(
5386
+ /** @type {Element} */ (this.$$element),
5387
+ classVal,
5388
+ );
4568
5389
  } else {
4569
5390
  this.$nodeRef.element.classList.add(classVal);
4570
5391
  }
@@ -4580,7 +5401,10 @@ class Attributes {
4580
5401
  $removeClass(classVal) {
4581
5402
  if (classVal && classVal.length > 0) {
4582
5403
  if (hasAnimate(this.$$element)) {
4583
- this.$animate.removeClass(this.$$element, classVal);
5404
+ this.$animate.removeClass(
5405
+ /** @type {Element} */ (this.$$element),
5406
+ classVal,
5407
+ );
4584
5408
  } else {
4585
5409
  this.$nodeRef.element.classList.remove(classVal);
4586
5410
  }
@@ -4598,7 +5422,7 @@ class Attributes {
4598
5422
  const toAdd = tokenDifference(newClasses, oldClasses);
4599
5423
  if (toAdd && toAdd.length) {
4600
5424
  if (hasAnimate(this.$$element)) {
4601
- this.$animate.addClass(this.$$element, toAdd);
5425
+ this.$animate.addClass(/** @type {Element }*/ (this.$$element), toAdd);
4602
5426
  } else {
4603
5427
  this.$nodeRef.element.classList.add(...toAdd.trim().split(/\s+/));
4604
5428
  }
@@ -4606,7 +5430,10 @@ class Attributes {
4606
5430
  const toRemove = tokenDifference(oldClasses, newClasses);
4607
5431
  if (toRemove && toRemove.length) {
4608
5432
  if (hasAnimate(this.$$element)) {
4609
- this.$animate.removeClass(this.$$element, toRemove);
5433
+ this.$animate.removeClass(
5434
+ /** @type {Element }*/ (this.$$element),
5435
+ toRemove,
5436
+ );
4610
5437
  } else {
4611
5438
  this.$nodeRef.element.classList.remove(...toRemove.trim().split(/\s+/));
4612
5439
  }
@@ -4797,7 +5624,8 @@ class Attributes {
4797
5624
  if (lastTuple.length === 2) {
4798
5625
  result += " " + trim(lastTuple[1]);
4799
5626
  }
4800
- return result;
5627
+
5628
+ return result.replace(/unsafe:unsafe/g, "unsafe");
4801
5629
  }
4802
5630
  }
4803
5631
 
@@ -5006,11 +5834,11 @@ class CompileProvider {
5006
5834
  * @returns {CompileProvider} Self for chaining.
5007
5835
  */
5008
5836
  this.directive = function registerDirective(name, directiveFactory) {
5009
- assertArg$1(name, "name");
5837
+ assertArg(name, "name");
5010
5838
  assertNotHasOwnProperty(name, "directive");
5011
5839
  if (isString(name)) {
5012
5840
  assertValidDirectiveName(name);
5013
- assertArg$1(directiveFactory, "directiveFactory");
5841
+ assertArg(directiveFactory, "directiveFactory");
5014
5842
  if (!hasOwn(hasDirectives, name)) {
5015
5843
  hasDirectives[name] = [];
5016
5844
  $provide.factory(name + DirectiveSuffix, [
@@ -5344,15 +6172,15 @@ class CompileProvider {
5344
6172
  "$sce",
5345
6173
  "$animate",
5346
6174
  /**
5347
- * @param {import("../../core/di/internal-injector.js").InjectorService} $injector
6175
+ * @param {ng.InjectorService} $injector
5348
6176
  * @param {*} $interpolate
5349
6177
  * @param {import("../../services/exception/exception-handler.js").ErrorHandler} $exceptionHandler
5350
- * @param {*} $templateRequest
5351
- * @param {import("../parse/interface.ts").ParseService} $parse
6178
+ * @param {ng.TemplateRequestService} $templateRequest
6179
+ * @param {ng.ParseService} $parse
5352
6180
  * @param {*} $controller
5353
6181
  * @param {import('../scope/scope.js').Scope} $rootScope
5354
6182
  * @param {*} $sce
5355
- * @param {*} $animate
6183
+ * @param {ng.AnimateService} $animate
5356
6184
  * @returns
5357
6185
  */
5358
6186
  function (
@@ -5431,7 +6259,7 @@ class CompileProvider {
5431
6259
  );
5432
6260
  }
5433
6261
 
5434
- assertArg$1(scope, "scope");
6262
+ assertArg(scope, "scope");
5435
6263
  // could be empty nodelist
5436
6264
  if (nodeRef.getAny()) {
5437
6265
  setScope(nodeRef.getAny(), scope);
@@ -5494,7 +6322,7 @@ class CompileProvider {
5494
6322
 
5495
6323
  if (transcludeControllers) {
5496
6324
  for (const controllerName in transcludeControllers) {
5497
- assertArg$1($linkNode.element, "element");
6325
+ assertArg($linkNode.element, "element");
5498
6326
  setCacheData(
5499
6327
  $linkNode.element,
5500
6328
  `$${controllerName}Controller`,
@@ -5642,7 +6470,7 @@ class CompileProvider {
5642
6470
  * @param {*} [parentBoundTranscludeFn]
5643
6471
  */
5644
6472
  function compositeLinkFn(scope, nodeRef, parentBoundTranscludeFn) {
5645
- assertArg$1(nodeRef, "nodeRef");
6473
+ assertArg(nodeRef, "nodeRef");
5646
6474
  let stableNodeList = [];
5647
6475
  if (nodeLinkFnFound) {
5648
6476
  // create a stable copy of the nodeList, only copying elements with linkFns
@@ -7049,11 +7877,19 @@ class CompileProvider {
7049
7877
  replace: null,
7050
7878
  $$originalDirective: origAsyncDirective,
7051
7879
  });
7052
- const templateUrl = isFunction(origAsyncDirective.templateUrl)
7053
- ? /** @type { ((element: Element, tAttrs: Attributes) => string) } */ (
7880
+ /** @type {string} */
7881
+ let templateUrl;
7882
+
7883
+ if (isFunction(origAsyncDirective.templateUrl)) {
7884
+ templateUrl =
7885
+ /** @type { ((element: Element, tAttrs: Attributes) => string) } */ (
7054
7886
  origAsyncDirective.templateUrl
7055
- )($compileNode.element, tAttrs)
7056
- : origAsyncDirective.templateUrl;
7887
+ )($compileNode.element, tAttrs);
7888
+ } else {
7889
+ templateUrl = /** @type {string} */ (
7890
+ origAsyncDirective.templateUrl
7891
+ );
7892
+ }
7057
7893
  const { templateNamespace } = origAsyncDirective;
7058
7894
 
7059
7895
  emptyElement($compileNode.element);
@@ -7574,14 +8410,23 @@ class CompileProvider {
7574
8410
  attr.$$element.classList.value,
7575
8411
  );
7576
8412
  } else {
7577
- attr.$set(name, newValue);
8413
+ attr.$set(
8414
+ name,
8415
+ name === "srcset"
8416
+ ? $sce.getTrustedMediaUrl(newValue)
8417
+ : newValue,
8418
+ );
7578
8419
  }
7579
8420
  });
7580
8421
  });
7581
8422
 
7582
8423
  if (interpolateFn.expressions.length == 0) {
7583
- // if there is nothing to watch, its a constant
7584
- attr.$set(name, newValue);
8424
+ attr.$set(
8425
+ name,
8426
+ name === "srcset"
8427
+ ? $sce.getTrustedMediaUrl(newValue)
8428
+ : newValue,
8429
+ );
7585
8430
  }
7586
8431
  },
7587
8432
  };
@@ -7990,7 +8835,7 @@ function removeComments(jqNodes) {
7990
8835
  */
7991
8836
  function assertValidDirectiveName(name) {
7992
8837
  const letter = name.charAt(0);
7993
- if (!letter || letter !== lowercase(letter)) {
8838
+ if (!letter || letter !== letter.toLowerCase()) {
7994
8839
  throw $compileMinErr(
7995
8840
  "baddir",
7996
8841
  "Directive/Component name '{0}' is invalid. The first character must be a lowercase letter",
@@ -8096,9 +8941,9 @@ class FormController {
8096
8941
 
8097
8942
  /**
8098
8943
  * @param {Element} $element
8099
- * @param {import("../../core/compile/attributes.js").Attributes} $attrs
8100
- * @param {import("../../core/scope/scope.js").Scope} $scope
8101
- * @param {*} $animate
8944
+ * @param {ng.Attributes} $attrs
8945
+ * @param {ng.Scope} $scope
8946
+ * @param {ng.AnimateService} $animate
8102
8947
  * @param {*} $interpolate
8103
8948
  */
8104
8949
  constructor($element, $attrs, $scope, $animate, $interpolate) {
@@ -8864,7 +9709,7 @@ class NgModelController {
8864
9709
  * @param {import('../../core/compile/attributes.js').Attributes} $attr
8865
9710
  * @param {Element} $element
8866
9711
  * @param {import("../../core/parse/interface.ts").ParseService} $parse
8867
- * @param {*} $animate
9712
+ * @param {ng.AnimateService} $animate
8868
9713
  * @param {*} $interpolate
8869
9714
  */
8870
9715
  constructor(
@@ -10899,7 +11744,7 @@ function inputDirective($filter, $parse) {
10899
11744
  link: {
10900
11745
  pre(scope, element, attr, ctrls) {
10901
11746
  if (ctrls[0]) {
10902
- (inputType[lowercase(attr["type"])] || inputType.text)(
11747
+ (inputType[attr.type?.toLowerCase()] || inputType.text)(
10903
11748
  scope,
10904
11749
  element,
10905
11750
  attr,
@@ -10932,7 +11777,7 @@ function hiddenInputBrowserCacheDirective() {
10932
11777
  restrict: "E",
10933
11778
  priority: 200,
10934
11779
  compile(_, attr) {
10935
- if (lowercase(attr["type"]) !== "hidden") {
11780
+ if (attr.type?.toLowerCase() !== "hidden") {
10936
11781
  return;
10937
11782
  }
10938
11783
 
@@ -11883,7 +12728,8 @@ const NG_HIDE_IN_PROGRESS_CLASS = "ng-hide-animate";
11883
12728
 
11884
12729
  ngShowDirective.$inject = ["$animate"];
11885
12730
  /**
11886
- * @returns {import('../../interface.ts').Directive}
12731
+ * @param {ng.AnimateService} $animate
12732
+ * @returns {ng.Directive}
11887
12733
  */
11888
12734
  function ngShowDirective($animate) {
11889
12735
  return {
@@ -11894,7 +12740,7 @@ function ngShowDirective($animate) {
11894
12740
  * @param $attr
11895
12741
  */
11896
12742
  link(scope, element, $attr) {
11897
- scope.$watch($attr["ngShow"], (value) => {
12743
+ scope.$watch($attr.ngShow, (value) => {
11898
12744
  // we're adding a temporary, animation-specific class for ng-hide since this way
11899
12745
  // we can control when the element is actually displayed on screen without having
11900
12746
  // to have a global/greedy CSS selector that breaks when other animations are run.
@@ -11944,7 +12790,7 @@ function ngHideDirective($animate) {
11944
12790
 
11945
12791
  ngIfDirective.$inject = ["$animate"];
11946
12792
  /**
11947
- * @param {*} $animate
12793
+ * @param {ng.AnimateService} $animate
11948
12794
  * @returns {ng.Directive}
11949
12795
  */
11950
12796
  function ngIfDirective($animate) {
@@ -12021,9 +12867,9 @@ ngIncludeDirective.$inject = [
12021
12867
 
12022
12868
  /**
12023
12869
  *
12024
- * @param {*} $templateRequest
12870
+ * @param {ng.TemplateRequestService} $templateRequest
12025
12871
  * @param {import("../../services/anchor-scroll/anchor-scroll.js").AnchorScrollFunction} $anchorScroll
12026
- * @param {*} $animate
12872
+ * @param {ng.AnimateService} $animate
12027
12873
  * @param {import('../../services/exception/interface.ts').ErrorHandler} $exceptionHandler
12028
12874
  * @returns {import('../../interface.ts').Directive}
12029
12875
  */
@@ -12625,8 +13471,8 @@ function ngStyleDirective() {
12625
13471
  ngSwitchDirective.$inject = ["$animate"];
12626
13472
 
12627
13473
  /**
12628
- * @param {*} $animate
12629
- * @returns {import('../../interface.ts').Directive}
13474
+ * @param {ng.AnimateService} $animate
13475
+ * @returns {ng.Directive}
12630
13476
  */
12631
13477
  function ngSwitchDirective($animate) {
12632
13478
  return {
@@ -12642,7 +13488,7 @@ function ngSwitchDirective($animate) {
12642
13488
  },
12643
13489
  ],
12644
13490
  link(scope, _element, attr, ngSwitchController) {
12645
- const watchExpr = attr["ngSwitch"] || attr["on"];
13491
+ const watchExpr = attr.ngSwitch || attr.on;
12646
13492
  let selectedTranscludes = [];
12647
13493
  const selectedElements = [];
12648
13494
  const previousLeaveAnimations = [];
@@ -13115,7 +13961,7 @@ function ngOptionsDirective($compile, $parse) {
13115
13961
  if (providedEmptyOption) {
13116
13962
  // compile the element since there might be bindings in it
13117
13963
  const linkFn = $compile(selectCtrl.emptyOption);
13118
- assertArg$1(linkFn, "LinkFn required");
13964
+ assertArg(linkFn, "LinkFn required");
13119
13965
  selectElement.prepend(selectCtrl.emptyOption);
13120
13966
  linkFn(scope);
13121
13967
 
@@ -13889,7 +14735,7 @@ class AnchorScrollProvider {
13889
14735
 
13890
14736
  if (isFunction(offset)) {
13891
14737
  offset = /** @type {Function} */ (offset)();
13892
- } else if (isElement(offset)) {
14738
+ } else if (offset instanceof Element) {
13893
14739
  const elem = offset[0];
13894
14740
  const style = window.getComputedStyle(elem);
13895
14741
  if (style.position !== "fixed") {
@@ -13980,27 +14826,8 @@ class AnchorScrollProvider {
13980
14826
  ];
13981
14827
  }
13982
14828
 
13983
- /** @typedef {"enter"|"leave"|"move"|"addClass"|"setClass"|"removeClass"} AnimationMethod */
13984
-
13985
- /**
13986
- * @typedef {Object} AnimationOptions
13987
- * @property {string} addClass - space-separated CSS classes to add to element
13988
- * @property {Object} from - CSS properties & values at the beginning of animation. Must have matching `to`
13989
- * @property {string} removeClass - space-separated CSS classes to remove from element
13990
- * @property {string} to - CSS properties & values at end of animation. Must have matching `from`
13991
- */
13992
-
13993
14829
  const $animateMinErr = minErr("$animate");
13994
14830
 
13995
- function mergeClasses(a, b) {
13996
- if (!a && !b) return "";
13997
- if (!a) return b;
13998
- if (!b) return a;
13999
- if (Array.isArray(a)) a = a.join(" ");
14000
- if (Array.isArray(b)) b = b.join(" ");
14001
- return `${a} ${b}`;
14002
- }
14003
-
14004
14831
  // if any other type of options value besides an Object value is
14005
14832
  // passed into the $animate.method() animation then this helper code
14006
14833
  // will be run which will ignore it. While this patch is not the
@@ -14148,7 +14975,11 @@ function AnimateProvider($provide) {
14148
14975
  };
14149
14976
 
14150
14977
  this.$get = [
14151
- "$$animateQueue",
14978
+ $injectTokens.$$animateQueue,
14979
+ /**
14980
+ * @param {import("./queue/interface.ts").AnimateQueueService} $$animateQueue
14981
+ * @returns {ng.AnimateService}
14982
+ */
14152
14983
  function ($$animateQueue) {
14153
14984
  /**
14154
14985
  * The $animate service exposes a series of DOM utility methods that provide support
@@ -14282,77 +15113,21 @@ function AnimateProvider($provide) {
14282
15113
  *
14283
15114
  * @return {boolean} whether or not animations are enabled
14284
15115
  */
14285
- enabled: $$animateQueue.enabled,
15116
+ enabled: (element, enabled) => {
15117
+ if (enabled !== undefined) {
15118
+ return hasAnimate(element);
15119
+ } else {
15120
+ element.setAttribute("animate", `${enabled}`);
15121
+ }
15122
+ },
14286
15123
 
14287
15124
  /**
14288
- * Cancels the provided animation and applies the end state of the animation.
14289
- * Note that this does not cancel the underlying operation, e.g. the setting of classes or
14290
- * adding the element to the DOM.
14291
- *
14292
- * @param {import('./runner/animate-runner.js').AnimateRunner} runner An animation runner returned by an $animate function.
14293
- *
14294
- * @example
14295
- <example module="animationExample" deps="angular-animate.js" animations="true" name="animate-cancel">
14296
- <file name="app.js">
14297
- angular.module('animationExample', []).component('cancelExample', {
14298
- templateUrl: 'template.html',
14299
- controller: function($element, $animate) {
14300
- this.runner = null;
14301
-
14302
- this.addClass = function() {
14303
- this.runner = $animate.addClass($element.querySelectorAll('div'), 'red');
14304
- let ctrl = this;
14305
- this.runner.finally(function() {
14306
- ctrl.runner = null;
14307
- });
14308
- };
14309
-
14310
- this.removeClass = function() {
14311
- this.runner = $animate.removeClass($element.querySelectorAll('div'), 'red');
14312
- let ctrl = this;
14313
- this.runner.finally(function() {
14314
- ctrl.runner = null;
14315
- });
14316
- };
14317
-
14318
- this.cancel = function() {
14319
- $animate.cancel(this.runner);
14320
- };
14321
- }
14322
- });
14323
- </file>
14324
- <file name="template.html">
14325
- <p>
14326
- <button id="add" ng-click="$ctrl.addClass()">Add</button>
14327
- <button ng-click="$ctrl.removeClass()">Remove</button>
14328
- <br>
14329
- <button id="cancel" ng-click="$ctrl.cancel()" ng-disabled="!$ctrl.runner">Cancel</button>
14330
- <br>
14331
- <div id="target">CSS-Animated Text</div>
14332
- </p>
14333
- </file>
14334
- <file name="index.html">
14335
- <cancel-example></cancel-example>
14336
- </file>
14337
- <file name="style.css">
14338
- .red-add, .red-remove {
14339
- transition: all 4s cubic-bezier(0.250, 0.460, 0.450, 0.940);
14340
- }
14341
-
14342
- .red,
14343
- .red-add.red-add-active {
14344
- color: #FF0000;
14345
- font-size: 40px;
14346
- }
14347
-
14348
- .red-remove.red-remove-active {
14349
- font-size: 10px;
14350
- color: black;
14351
- }
14352
-
14353
- </file>
14354
- </example>
14355
- */
15125
+ * Cancels the provided animation and applies the end state of the animation.
15126
+ * Note that this does not cancel the underlying operation, e.g. the setting of classes or
15127
+ * adding the element to the DOM.
15128
+ *
15129
+ * @param {import('./runner/animate-runner.js').AnimateRunner} runner An animation runner returned by an $animate function.
15130
+ */
14356
15131
  cancel(runner) {
14357
15132
  if (runner.cancel) {
14358
15133
  runner.cancel();
@@ -14368,7 +15143,7 @@ function AnimateProvider($provide) {
14368
15143
  * @param {Element} element - the element which will be inserted into the DOM
14369
15144
  * @param {Element} parent - the parent element which will append the element as a child (so long as the after element is not present)
14370
15145
  * @param {Element} [after] - after the sibling element after which the element will be appended
14371
- * @param {AnimationOptions} [options] - an optional collection of options/styles that will be applied to the element.
15146
+ * @param {import("./interface.ts").AnimationOptions} [options] - an optional collection of options/styles that will be applied to the element.
14372
15147
  * @returns {import('./runner/animate-runner.js').AnimateRunner} the animation runner
14373
15148
  */
14374
15149
  enter(element, parent, after, options) {
@@ -14390,7 +15165,7 @@ function AnimateProvider($provide) {
14390
15165
  * @param {Element} element - the element which will be inserted into the DOM
14391
15166
  * @param {Element} parent - the parent element which will append the element as a child (so long as the after element is not present)
14392
15167
  * @param {Element} after - after the sibling element after which the element will be appended
14393
- * @param {AnimationOptions} [options] - an optional collection of options/styles that will be applied to the element.
15168
+ * @param {import("./interface.ts").AnimationOptions} [options] - an optional collection of options/styles that will be applied to the element.
14394
15169
  * @returns {import('./runner/animate-runner.js').AnimateRunner} the animation runner
14395
15170
  */
14396
15171
  move(element, parent, after, options) {
@@ -14409,7 +15184,7 @@ function AnimateProvider($provide) {
14409
15184
  * digest once the animation has completed.
14410
15185
  *
14411
15186
  * @param {Element} element the element which will be removed from the DOM
14412
- * @param {AnimationOptions} [options] an optional collection of options/styles that will be applied to the element.
15187
+ * @param {import("./interface.ts").AnimationOptions} [options] an optional collection of options/styles that will be applied to the element.
14413
15188
  * @returns {import('./runner/animate-runner.js').AnimateRunner} the animation runner
14414
15189
  */
14415
15190
  leave(element, options) {
@@ -14438,7 +15213,7 @@ function AnimateProvider($provide) {
14438
15213
  *
14439
15214
  * @param {Element} element the element which the CSS classes will be applied to
14440
15215
  * @param {string} className the CSS class(es) that will be added (multiple classes are separated via spaces)
14441
- * @param {AnimationOptions} [options] an optional collection of options/styles that will be applied to the element.
15216
+ * @param {import("./interface").AnimationOptions} [options] an optional collection of options/styles that will be applied to the element.
14442
15217
  * @return {import('./runner/animate-runner.js').AnimateRunner}} animationRunner the animation runner
14443
15218
  */
14444
15219
  addClass(element, className, options) {
@@ -14457,7 +15232,7 @@ function AnimateProvider($provide) {
14457
15232
  *
14458
15233
  * @param {Element} element the element which the CSS classes will be applied to
14459
15234
  * @param {string} className the CSS class(es) that will be removed (multiple classes are separated via spaces)
14460
- * @param {AnimationOptions} [options] an optional collection of options/styles that will be applied to the element. *
15235
+ * @param {import("./interface").AnimationOptions} [options] an optional collection of options/styles that will be applied to the element. *
14461
15236
  * @return {import('./runner/animate-runner.js').AnimateRunner} animationRunner the animation runner
14462
15237
  */
14463
15238
  removeClass(element, className, options) {
@@ -17881,7 +18656,7 @@ function parseHeaders(headers) {
17881
18656
  );
17882
18657
  } else if (isObject(headers)) {
17883
18658
  Object.entries(headers).forEach(([headerKey, headerVal]) => {
17884
- fillInParsed(lowercase(headerKey), trim(headerVal));
18659
+ fillInParsed(headerKey.toLowerCase(), trim(headerVal));
17885
18660
  });
17886
18661
  }
17887
18662
 
@@ -17907,7 +18682,7 @@ function headersGetter(headers) {
17907
18682
  if (!headersObj) headersObj = parseHeaders(headers);
17908
18683
 
17909
18684
  if (name) {
17910
- let value = headersObj[lowercase(name)];
18685
+ let value = headersObj[name.toLowerCase()];
17911
18686
  if (value === undefined) {
17912
18687
  value = null;
17913
18688
  }
@@ -19872,7 +20647,7 @@ class LogProvider {
19872
20647
  }
19873
20648
 
19874
20649
  /**
19875
- * @returns {import("./interface.ts").LogService}
20650
+ * @returns {ng.LogService}
19876
20651
  */
19877
20652
  $get() {
19878
20653
  if (this._override) {
@@ -20016,6 +20791,15 @@ function isUnsafeGlobal(target) {
20016
20791
  return true;
20017
20792
  }
20018
20793
 
20794
+ if (target instanceof Promise) {
20795
+ return true;
20796
+ }
20797
+
20798
+ // Events
20799
+ if (typeof Event !== "undefined" && target instanceof Event) {
20800
+ return true;
20801
+ }
20802
+
20019
20803
  // Cross-origin or non-enumerable window objects
20020
20804
  try {
20021
20805
  return Object.prototype.toString.call(target) === "[object Window]";
@@ -20110,6 +20894,8 @@ class Scope {
20110
20894
 
20111
20895
  this.scheduled = [];
20112
20896
 
20897
+ this.$scopename = undefined;
20898
+
20113
20899
  /** @private */
20114
20900
  this.propertyMap = {
20115
20901
  $watch: this.$watch.bind(this),
@@ -20121,18 +20907,20 @@ class Scope {
20121
20907
  $apply: this.$apply.bind(this),
20122
20908
  $postUpdate: this.$postUpdate.bind(this),
20123
20909
  $isRoot: this.#isRoot.bind(this),
20124
- $proxy: this.$proxy,
20125
20910
  $on: this.$on.bind(this),
20126
20911
  $emit: this.$emit.bind(this),
20127
20912
  $broadcast: this.$broadcast.bind(this),
20128
20913
  $transcluded: this.$transcluded.bind(this),
20129
20914
  $handler: /** @type {Scope} */ (this),
20915
+ $merge: this.$merge.bind(this),
20916
+ $getById: this.$getById.bind(this),
20917
+ $searchByName: this.$searchByName.bind(this),
20918
+ $proxy: this.$proxy,
20130
20919
  $parent: this.$parent,
20131
20920
  $root: this.$root,
20132
20921
  $children: this.$children,
20133
20922
  $id: this.$id,
20134
- $merge: this.$merge.bind(this),
20135
- $getById: this.$getById.bind(this),
20923
+ $scopename: this.$scopename,
20136
20924
  };
20137
20925
  }
20138
20926
 
@@ -20148,8 +20936,14 @@ class Scope {
20148
20936
  */
20149
20937
  set(target, property, value, proxy) {
20150
20938
  if (property === "undefined") {
20151
- throw new Error("Attempting to set undefined property");
20939
+ return false;
20940
+ }
20941
+
20942
+ if (property === "$scopename") {
20943
+ this.$scopename = value;
20944
+ return true;
20152
20945
  }
20946
+
20153
20947
  if (
20154
20948
  (target.constructor?.$nonscope &&
20155
20949
  Array.isArray(target.constructor.$nonscope) &&
@@ -20366,9 +21160,9 @@ class Scope {
20366
21160
  * @returns {*} - The value of the property or a method if accessing `watch` or `sync`.
20367
21161
  */
20368
21162
  get(target, property, proxy) {
21163
+ if (property === "$scopename" && this.$scopename) return this.$scopename;
20369
21164
  if (property === "$$watchersCount") return calculateWatcherCount(this);
20370
21165
  if (property === isProxySymbol) return true;
20371
-
20372
21166
  if (target[property] && isProxy(target[property])) {
20373
21167
  this.$proxy = target[property];
20374
21168
  } else {
@@ -20397,7 +21191,6 @@ class Scope {
20397
21191
  this.#scheduleListener(this.scheduled);
20398
21192
  }
20399
21193
  }
20400
-
20401
21194
  if (hasOwn(this.propertyMap, property)) {
20402
21195
  this.$target = target;
20403
21196
  return this.propertyMap[property];
@@ -20495,7 +21288,7 @@ class Scope {
20495
21288
  * function is invoked when changes to that property are detected.
20496
21289
  *
20497
21290
  * @param {string} watchProp - An expression to be watched in the context of this model.
20498
- * @param {import('./interface.ts').ListenerFunction} [listenerFn] - A function to execute when changes are detected on watched context.
21291
+ * @param {ng.ListenerFn} [listenerFn] - A function to execute when changes are detected on watched context.
20499
21292
  * @param {boolean} [lazy] - A flag to indicate if the listener should be invoked immediately. Defaults to false.
20500
21293
  */
20501
21294
  $watch(watchProp, listenerFn, lazy = false) {
@@ -20517,7 +21310,7 @@ class Scope {
20517
21310
  return () => {};
20518
21311
  }
20519
21312
 
20520
- /** @type {import('./interface.ts').Listener} */
21313
+ /** @type {ng.Listener} */
20521
21314
  const listener = {
20522
21315
  originalTarget: this.$target,
20523
21316
  listenerFn: listenerFn,
@@ -20575,13 +21368,34 @@ class Scope {
20575
21368
  }
20576
21369
  // 6
20577
21370
  case ASTType.BinaryExpression: {
20578
- let expr = get.decoratedNode.body[0].expression.toWatch[0];
20579
- key = expr.property ? expr.property.name : expr.name;
20580
- if (!key) {
20581
- throw new Error("Unable to determine key");
21371
+ if (get.decoratedNode.body[0].expression.isPure) {
21372
+ let expr = get.decoratedNode.body[0].expression.toWatch[0];
21373
+ key = expr.property ? expr.property.name : expr.name;
21374
+ if (!key) {
21375
+ throw new Error("Unable to determine key");
21376
+ }
21377
+ listener.property.push(key);
21378
+ break;
21379
+ } else {
21380
+ let keys = [];
21381
+ get.decoratedNode.body[0].expression.toWatch.forEach((x) => {
21382
+ const k = x.property ? x.property.name : x.name;
21383
+ if (!k) {
21384
+ throw new Error("Unable to determine key");
21385
+ }
21386
+ keys.push(k);
21387
+ });
21388
+ keys.forEach((key) => {
21389
+ this.#registerKey(key, listener);
21390
+ this.#scheduleListener([listener]);
21391
+ });
21392
+
21393
+ return () => {
21394
+ keys.forEach((key) => {
21395
+ this.#deregisterKey(key, listener.id);
21396
+ });
21397
+ };
20582
21398
  }
20583
- listener.property.push(key);
20584
- break;
20585
21399
  }
20586
21400
  // 7
20587
21401
  case ASTType.UnaryExpression: {
@@ -21121,6 +21935,26 @@ class Scope {
21121
21935
  return res;
21122
21936
  }
21123
21937
  }
21938
+
21939
+ $searchByName(name) {
21940
+ const getByName = (scope, name) => {
21941
+ if (scope.$scopename === name) {
21942
+ return scope;
21943
+ } else {
21944
+ let res = undefined;
21945
+ for (const child of scope.$children) {
21946
+ let found = getByName(child, name);
21947
+ if (found) {
21948
+ res = found;
21949
+ break;
21950
+ }
21951
+ }
21952
+ return res;
21953
+ }
21954
+ };
21955
+
21956
+ return getByName(this.$root, name);
21957
+ }
21124
21958
  }
21125
21959
 
21126
21960
  /*------------- Private helpers -------------*/
@@ -21348,25 +22182,31 @@ class SanitizeUriProvider {
21348
22182
  }
21349
22183
 
21350
22184
  /**
21351
- * @returns {import("./interface").SanitizerFn}
22185
+ * @returns {import("./interface.ts").SanitizerFn}
21352
22186
  */
21353
- $get() {
21354
- return (uri, isMediaUrl) => {
21355
- if (!uri) return uri;
22187
+ $get = [
22188
+ $injectTokens.$window,
22189
+ /** @param {ng.WindowService} $window */
22190
+ ($window) => {
22191
+ return /** @type {import("./interface.ts").SanitizerFn} */ (
22192
+ (uri, isMediaUrl) => {
22193
+ if (!uri) return uri;
21356
22194
 
21357
- /** @type {RegExp} */
21358
- const regex = isMediaUrl
21359
- ? this._imgSrcSanitizationTrustedUrlList
21360
- : this._aHrefSanitizationTrustedUrlList;
22195
+ /** @type {RegExp} */
22196
+ const regex = isMediaUrl
22197
+ ? this._imgSrcSanitizationTrustedUrlList
22198
+ : this._aHrefSanitizationTrustedUrlList;
21361
22199
 
21362
- const normalizedVal = urlResolve(uri.trim()).href;
22200
+ const normalizedVal = new URL(uri.trim(), $window.location.href).href;
21363
22201
 
21364
- if (normalizedVal !== "" && !normalizedVal.match(regex)) {
21365
- return `unsafe:${normalizedVal}`;
21366
- }
21367
- return uri;
21368
- };
21369
- }
22202
+ if (normalizedVal !== "" && !normalizedVal.match(regex)) {
22203
+ return `unsafe:${normalizedVal}`;
22204
+ }
22205
+ return uri;
22206
+ }
22207
+ );
22208
+ },
22209
+ ];
21370
22210
  }
21371
22211
 
21372
22212
  const ACTIVE_CLASS = "ng-active";
@@ -21375,9 +22215,9 @@ const INACTIVE_CLASS = "ng-inactive";
21375
22215
  class NgMessageCtrl {
21376
22216
  /**
21377
22217
  * @param {Element} $element
21378
- * @param {import('../../core/scope/scope.js').Scope} $scope
21379
- * @param {import('../../core/compile/attributes').Attributes} $attrs
21380
- * @param {*} $animate
22218
+ * @param {ng.Scope} $scope
22219
+ * @param {ng.Attributes} $attrs
22220
+ * @param {ng.AnimateService} $animate
21381
22221
  */
21382
22222
  constructor($element, $scope, $attrs, $animate) {
21383
22223
  this.$element = $element;
@@ -21561,6 +22401,10 @@ class NgMessageCtrl {
21561
22401
  }
21562
22402
 
21563
22403
  ngMessagesDirective.$inject = ["$animate"];
22404
+ /**
22405
+ * @param {ng.AnimateService} $animate
22406
+ * @returns {ng.Directive<NgMessageCtrl>}
22407
+ */
21564
22408
  function ngMessagesDirective($animate) {
21565
22409
  return {
21566
22410
  require: "ngMessages",
@@ -21607,10 +22451,14 @@ const ngMessageDefaultDirective = ngMessageDirectiveFactory(true);
21607
22451
 
21608
22452
  /**
21609
22453
  * @param {boolean} isDefault
21610
- * @returns {(any) => import("../../interface.ts").Directive}
22454
+ * @returns {(any) => ng.Directive}
21611
22455
  */
21612
22456
  function ngMessageDirectiveFactory(isDefault) {
21613
22457
  ngMessageDirective.$inject = ["$animate"];
22458
+ /**
22459
+ * @param {ng.AnimateService} $animate
22460
+ * @returns {ng.Directive}
22461
+ */
21614
22462
  function ngMessageDirective($animate) {
21615
22463
  return {
21616
22464
  restrict: "AE",
@@ -22101,7 +22949,7 @@ function ngDblclickAriaDirective($aria) {
22101
22949
  * @fileoverview
22102
22950
  * Frame-synchronized animation runner and scheduler.
22103
22951
  * Provides async batching of animation callbacks using requestAnimationFrame.
22104
- * In AngularJS, this user to be implemented as `$$AnimateRunner`
22952
+ * In AngularJS, this used to be implemented as `$$AnimateRunner`
22105
22953
  */
22106
22954
 
22107
22955
  /**
@@ -23202,6 +24050,7 @@ function blockTransitions(node, duration) {
23202
24050
 
23203
24051
  const NG_ANIMATE_ATTR_NAME = "data-ng-animate";
23204
24052
  const NG_ANIMATE_PIN_DATA = "$ngAnimatePin";
24053
+
23205
24054
  AnimateQueueProvider.$inject = ["$animateProvider"];
23206
24055
  function AnimateQueueProvider($animateProvider) {
23207
24056
  const PRE_DIGEST_STATE = 1;
@@ -23331,8 +24180,8 @@ function AnimateQueueProvider($animateProvider) {
23331
24180
  * @param {ng.RootScopeService} $rootScope
23332
24181
  * @param {ng.InjectorService} $injector
23333
24182
  * @param {*} $$animation
23334
- * @param {*} $templateRequest
23335
- * @returns
24183
+ * @param {ng.TemplateRequestService} $templateRequest
24184
+ * @returns {import("../queue/interface.ts").AnimateQueueService}
23336
24185
  */
23337
24186
  function ($rootScope, $injector, $$animation, $templateRequest) {
23338
24187
  const activeAnimationsLookup = new Map();
@@ -23500,12 +24349,6 @@ function AnimateQueueProvider($animateProvider) {
23500
24349
  },
23501
24350
 
23502
24351
  pin(element, parentElement) {
23503
- assertArg(isElement(element), "element", "not an element");
23504
- assertArg(
23505
- isElement(parentElement),
23506
- "parentElement",
23507
- "not an element",
23508
- );
23509
24352
  setCacheData(element, NG_ANIMATE_PIN_DATA, parentElement);
23510
24353
  },
23511
24354
 
@@ -23846,6 +24689,18 @@ function AnimateQueueProvider($animateProvider) {
23846
24689
  }
23847
24690
  }
23848
24691
 
24692
+ /**
24693
+ * Closes and cleans up any child animations found under the given node.
24694
+ *
24695
+ * Looks for elements that have the NG_ANIMATE_ATTR_NAME attribute, checks their
24696
+ * animation state, ends running animations, and removes them from the
24697
+ * activeAnimationsLookup if appropriate.
24698
+ *
24699
+ * @param {Element | ParentNode} node
24700
+ * The DOM node whose descendant animations should be closed.
24701
+ *
24702
+ * @returns {void}
24703
+ */
23849
24704
  function closeChildAnimations(node) {
23850
24705
  const children = node.querySelectorAll(`[${NG_ANIMATE_ATTR_NAME}]`);
23851
24706
  children.forEach((child) => {
@@ -24391,8 +25246,8 @@ function AnimationProvider() {
24391
25246
  /**
24392
25247
  *
24393
25248
  * @param {ng.RootScopeService} $rootScope
24394
- * @param {import("../core/di/internal-injector").InjectorService} $injector
24395
- * @param {import("./raf-scheduler").RafScheduler} $$rAFScheduler
25249
+ * @param {ng.InjectorService} $injector
25250
+ * @param {import("./raf-scheduler.js").RafScheduler} $$rAFScheduler
24396
25251
  * @param {*} $$animateCache
24397
25252
  * @returns
24398
25253
  */
@@ -24511,9 +25366,9 @@ function AnimationProvider() {
24511
25366
  return runner;
24512
25367
  }
24513
25368
 
24514
- let classes = mergeClasses$1(
25369
+ let classes = mergeClasses(
24515
25370
  element.getAttribute("class"),
24516
- mergeClasses$1(options.addClass, options.removeClass),
25371
+ mergeClasses(options.addClass, options.removeClass),
24517
25372
  );
24518
25373
  let { tempClasses } = options;
24519
25374
  if (tempClasses) {
@@ -26670,6 +27525,7 @@ function stringify(o) {
26670
27525
  }
26671
27526
  return JSON.stringify(o, (key, value) => format(value)).replace(/\\"/g, '"');
26672
27527
  }
27528
+
26673
27529
  const stripLastPathElement = (str) => str.replace(/\/[^/]*$/, "");
26674
27530
  /**
26675
27531
  * Splits on a delimiter, but returns the delimiters in the array
@@ -34705,7 +35561,7 @@ let ngView = [
34705
35561
  "$interpolate",
34706
35562
  /**
34707
35563
  * @param {*} $view
34708
- * @param {*} $animate
35564
+ * @param {ng.AnimateService} $animate
34709
35565
  * @param {*} $viewScroll
34710
35566
  * @param {*} $interpolate
34711
35567
  * @returns {import("../../interface.ts").Directive}
@@ -35133,417 +35989,6 @@ function ngSetterDirective($parse, $log) {
35133
35989
  };
35134
35990
  }
35135
35991
 
35136
- /**
35137
- * @param {"get" | "delete" | "post" | "put"} method - HTTP method applied to request
35138
- * @param {string} [attrOverride] - Custom name to use for the attribute
35139
- * @returns {ng.DirectiveFactory}
35140
- */
35141
- function defineDirective(method, attrOverride) {
35142
- const attrName =
35143
- attrOverride || "ng" + method.charAt(0).toUpperCase() + method.slice(1);
35144
- const directive = createHttpDirective(method, attrName);
35145
- directive["$inject"] = [
35146
- $injectTokens.$http,
35147
- $injectTokens.$compile,
35148
- $injectTokens.$log,
35149
- $injectTokens.$parse,
35150
- $injectTokens.$state,
35151
- $injectTokens.$sse,
35152
- $injectTokens.$animate,
35153
- ];
35154
- return directive;
35155
- }
35156
-
35157
- /** @type {ng.DirectiveFactory} */
35158
- const ngGetDirective = defineDirective("get");
35159
-
35160
- /** @type {ng.DirectiveFactory} */
35161
- const ngDeleteDirective = defineDirective("delete");
35162
-
35163
- /** @type {ng.DirectiveFactory} */
35164
- const ngPostDirective = defineDirective("post");
35165
-
35166
- /** @type {ng.DirectiveFactory} */
35167
- const ngPutDirective = defineDirective("put");
35168
-
35169
- /** @type {ng.DirectiveFactory} */
35170
- const ngSseDirective = defineDirective("get", "ngSse");
35171
-
35172
- /**
35173
- * Selects DOM event to listen for based on the element type.
35174
- *
35175
- * @param {Element} element - The DOM element to inspect.
35176
- * @returns {"click" | "change" | "submit"} The name of the event to listen for.
35177
- */
35178
- function getEventNameForElement(element) {
35179
- const tag = element.tagName.toLowerCase();
35180
- if (["input", "textarea", "select"].includes(tag)) {
35181
- return "change";
35182
- } else if (tag === "form") {
35183
- return "submit";
35184
- }
35185
- return "click";
35186
- }
35187
-
35188
- /**
35189
- * Creates an HTTP directive factory that supports GET, DELETE, POST, PUT.
35190
- *
35191
- * @param {"get" | "delete" | "post" | "put"} method - HTTP method to use.
35192
- * @param {string} attrName - Attribute name containing the URL.
35193
- * @returns {ng.DirectiveFactory}
35194
- */
35195
- function createHttpDirective(method, attrName) {
35196
- let content = undefined;
35197
-
35198
- /**
35199
- * @param {ng.HttpService} $http
35200
- * @param {ng.CompileService} $compile
35201
- * @param {ng.LogService} $log
35202
- * @param {ng.ParseService} $parse
35203
- * @param {ng.StateService} $state
35204
- * @param {ng.SseService} $sse
35205
- * @returns {ng.Directive}
35206
- */
35207
- return function ($http, $compile, $log, $parse, $state, $sse, $animate) {
35208
- /**
35209
- * Handles DOM manipulation based on a swap strategy and server-rendered HTML.
35210
- *
35211
- * @param {string | Object} html - The HTML string or object returned from the server.
35212
- * @param {import("./interface.ts").SwapModeType} swap
35213
- * @param {ng.Scope} scope
35214
- * @param {ng.Attributes} attrs
35215
- * @param {Element} element
35216
- */
35217
- function handleSwapResponse(html, swap, scope, attrs, element) {
35218
- let animationEnabled = false;
35219
- if (attrs.animate) {
35220
- animationEnabled = true;
35221
- }
35222
- let nodes = [];
35223
- if (!["textcontent", "delete", "none"].includes(swap)) {
35224
- if (!html) return;
35225
- const compiled = $compile(html)(scope);
35226
- nodes =
35227
- compiled instanceof DocumentFragment
35228
- ? Array.from(compiled.childNodes)
35229
- : [compiled];
35230
- }
35231
-
35232
- const targetSelector = attrs["target"];
35233
- const target = targetSelector
35234
- ? document.querySelector(targetSelector)
35235
- : element;
35236
-
35237
- if (!target) {
35238
- $log.warn(`${attrName}: target "${targetSelector}" not found`);
35239
- return;
35240
- }
35241
-
35242
- switch (swap) {
35243
- case "innerHTML":
35244
- if (animationEnabled) {
35245
- if (content) {
35246
- $animate.leave(content).done(() => {
35247
- content = nodes[0];
35248
- $animate.enter(nodes[0], target);
35249
- scope.$flushQueue();
35250
- });
35251
- scope.$flushQueue();
35252
- } else {
35253
- content = nodes[0];
35254
- $animate.enter(nodes[0], target);
35255
- scope.$flushQueue();
35256
- }
35257
- } else {
35258
- target.replaceChildren(...nodes);
35259
- }
35260
- break;
35261
-
35262
- case "outerHTML": {
35263
- const parent = target.parentNode;
35264
- if (!parent) return;
35265
- const frag = document.createDocumentFragment();
35266
- nodes.forEach((n) => frag.appendChild(n));
35267
- if (animationEnabled) {
35268
- const placeholder = document.createComment("placeholder");
35269
- target.parentNode.insertBefore(placeholder, target.nextSibling);
35270
- $animate.leave(target).done(() => {
35271
- const insertedNodes = Array.from(frag.childNodes);
35272
- insertedNodes.forEach((n) =>
35273
- $animate.enter(n, parent, placeholder),
35274
- );
35275
- content = insertedNodes;
35276
- scope.$flushQueue();
35277
- });
35278
- scope.$flushQueue();
35279
- } else {
35280
- parent.replaceChild(frag, target);
35281
- }
35282
- break;
35283
- }
35284
-
35285
- case "textContent":
35286
- target.textContent = html;
35287
- break;
35288
-
35289
- case "beforebegin":
35290
- nodes.forEach((node) => target.parentNode.insertBefore(node, target));
35291
- break;
35292
-
35293
- case "afterbegin":
35294
- nodes
35295
- .slice()
35296
- .reverse()
35297
- .forEach((node) => target.insertBefore(node, target.firstChild));
35298
- break;
35299
-
35300
- case "beforeend":
35301
- nodes.forEach((node) => target.appendChild(node));
35302
- break;
35303
-
35304
- case "afterend":
35305
- nodes
35306
- .slice()
35307
- .reverse()
35308
- .forEach((node) =>
35309
- target.parentNode.insertBefore(node, target.nextSibling),
35310
- );
35311
- break;
35312
-
35313
- case "delete":
35314
- target.remove();
35315
- break;
35316
-
35317
- case "none":
35318
- break;
35319
-
35320
- default:
35321
- target.replaceChildren(...nodes);
35322
- break;
35323
- }
35324
- }
35325
-
35326
- /**
35327
- * Collects form data from the element or its associated form.
35328
- *
35329
- * @param {HTMLElement} element
35330
- * @returns {Object<string, any>}
35331
- */
35332
- function collectFormData(element) {
35333
- /** @type {HTMLFormElement | null} */
35334
- let form = null;
35335
-
35336
- const tag = element.tagName.toLowerCase();
35337
-
35338
- if (tag === "form") {
35339
- form = /** @type {HTMLFormElement} */ (element);
35340
- } else if ("form" in element && element.form) {
35341
- form = /** @type {HTMLFormElement} */ (element.form);
35342
- } else if (element.hasAttribute("form")) {
35343
- const formId = element.getAttribute("form");
35344
- if (formId) {
35345
- const maybeForm = document.getElementById(formId);
35346
- if (maybeForm && maybeForm.tagName.toLowerCase() === "form") {
35347
- form = /** @type {HTMLFormElement} */ (maybeForm);
35348
- }
35349
- }
35350
- }
35351
-
35352
- if (!form) {
35353
- if (
35354
- "name" in element &&
35355
- typeof element.name === "string" &&
35356
- element.name.length > 0
35357
- ) {
35358
- if (
35359
- element instanceof HTMLInputElement ||
35360
- element instanceof HTMLTextAreaElement ||
35361
- element instanceof HTMLSelectElement
35362
- ) {
35363
- const key = element.name;
35364
- const value = element.value;
35365
- return { [key]: value };
35366
- }
35367
- }
35368
- return {};
35369
- }
35370
-
35371
- const formData = new FormData(form);
35372
- const data = {};
35373
- formData.forEach((value, key) => {
35374
- data[key] = value;
35375
- });
35376
- return data;
35377
- }
35378
-
35379
- return {
35380
- restrict: "A",
35381
- link(scope, element, attrs) {
35382
- const eventName = attrs.trigger || getEventNameForElement(element);
35383
- const tag = element.tagName.toLowerCase();
35384
-
35385
- if (isDefined(attrs.latch)) {
35386
- attrs.$observe(
35387
- "latch",
35388
- callBackAfterFirst(() =>
35389
- element.dispatchEvent(new Event(eventName)),
35390
- ),
35391
- );
35392
- }
35393
-
35394
- let throttled = false;
35395
- let intervalId;
35396
-
35397
- if (isDefined(attrs["interval"])) {
35398
- element.dispatchEvent(new Event(eventName));
35399
- intervalId = setInterval(
35400
- () => element.dispatchEvent(new Event(eventName)),
35401
- parseInt(attrs.interval) || 1000,
35402
- );
35403
- }
35404
-
35405
- element.addEventListener(eventName, async (event) => {
35406
- if (/** @type {HTMLButtonElement} */ (element).disabled) return;
35407
- if (tag === "form") event.preventDefault();
35408
- const swap = attrs.swap || "innerHTML";
35409
- const url = attrs[attrName];
35410
- if (!url) {
35411
- $log.warn(`${attrName}: no URL specified`);
35412
- return;
35413
- }
35414
-
35415
- const handler = (res) => {
35416
- if (isDefined(attrs.loading)) {
35417
- attrs.$set("loading", false);
35418
- }
35419
-
35420
- if (isDefined(attrs.loadingClass)) {
35421
- attrs.$removeClass(attrs.loadingClass);
35422
- }
35423
-
35424
- const html = res.data;
35425
- if (200 <= res.status && res.status <= 299) {
35426
- if (isDefined(attrs.success)) {
35427
- $parse(attrs.success)(scope, { $res: html });
35428
- }
35429
-
35430
- if (isDefined(attrs.stateSuccess)) {
35431
- $state.go(attrs.stateSuccess);
35432
- }
35433
- } else if (400 <= res.status && res.status <= 599) {
35434
- if (isDefined(attrs.error)) {
35435
- $parse(attrs.error)(scope, { $res: html });
35436
- }
35437
-
35438
- if (isDefined(attrs.stateError)) {
35439
- $state.go(attrs.stateError);
35440
- }
35441
- }
35442
-
35443
- if (isObject(html)) {
35444
- if (attrs.target) {
35445
- scope.$eval(`${attrs.target} = ${JSON.stringify(html)}`);
35446
- } else {
35447
- scope.$merge(html);
35448
- }
35449
- } else if (isString(html)) {
35450
- handleSwapResponse(html, swap, scope, attrs, element);
35451
- }
35452
- };
35453
-
35454
- if (isDefined(attrs.delay)) {
35455
- await wait(parseInt(attrs.delay) | 0);
35456
- }
35457
-
35458
- if (throttled) return;
35459
-
35460
- if (isDefined(attrs.throttle)) {
35461
- throttled = true;
35462
- attrs.$set("throttled", true);
35463
- setTimeout(() => {
35464
- attrs.$set("throttled", false);
35465
- throttled = false;
35466
- }, parseInt(attrs.throttle));
35467
- }
35468
-
35469
- if (isDefined(attrs["loading"])) {
35470
- attrs.$set("loading", true);
35471
- }
35472
-
35473
- if (isDefined(attrs["loadingClass"])) {
35474
- attrs.$addClass(attrs.loadingClass);
35475
- }
35476
-
35477
- if (method === "post" || method === "put") {
35478
- let data;
35479
- const config = {};
35480
- if (attrs.enctype) {
35481
- config.headers = {
35482
- "Content-Type": attrs["enctype"],
35483
- };
35484
- data = toKeyValue(collectFormData(element));
35485
- } else {
35486
- data = collectFormData(element);
35487
- }
35488
- $http[method](url, data, config).then(handler).catch(handler);
35489
- } else {
35490
- if (method === "get" && attrs.ngSse) {
35491
- const sseUrl = url;
35492
- const config = {
35493
- withCredentials: attrs.withCredentials === "true",
35494
- transformMessage: (data) => {
35495
- try {
35496
- return JSON.parse(data);
35497
- } catch {
35498
- return data;
35499
- }
35500
- },
35501
- onOpen: () => {
35502
- $log.info(`${attrName}: SSE connection opened to ${sseUrl}`);
35503
- if (isDefined(attrs.loading)) attrs.$set("loading", false);
35504
- if (isDefined(attrs.loadingClass))
35505
- attrs.$removeClass(attrs.loadingClass);
35506
- },
35507
- onMessage: (data) => {
35508
- const res = { status: 200, data };
35509
- handler(res);
35510
- },
35511
- onError: (err) => {
35512
- $log.error(`${attrName}: SSE error`, err);
35513
- const res = { status: 500, data: err };
35514
- handler(res);
35515
- },
35516
- onReconnect: (count) => {
35517
- $log.info(`ngSse: reconnected ${count} time(s)`);
35518
- if (attrs.onReconnect)
35519
- $parse(attrs.onReconnect)(scope, { $count: count });
35520
- },
35521
- };
35522
-
35523
- const source = $sse(sseUrl, config);
35524
-
35525
- scope.$on("$destroy", () => {
35526
- $log.info(`${attrName}: closing SSE connection`);
35527
- source.close();
35528
- });
35529
- } else {
35530
- $http[method](url).then(handler).catch(handler);
35531
- }
35532
- }
35533
- });
35534
-
35535
- if (intervalId) {
35536
- scope.$on("$destroy", () => clearInterval(intervalId));
35537
- }
35538
-
35539
- if (eventName == "load") {
35540
- element.dispatchEvent(new Event("load"));
35541
- }
35542
- },
35543
- };
35544
- };
35545
- }
35546
-
35547
35992
  ngInjectDirective.$inject = [$injectTokens.$log, $injectTokens.$injector];
35548
35993
 
35549
35994
  /**
@@ -35637,13 +36082,13 @@ class SseProvider {
35637
36082
  };
35638
36083
  }
35639
36084
 
35640
- /**
35641
- * Returns the $sse service function
35642
- * @returns {ng.SseService}
35643
- */
35644
36085
  $get = [
35645
36086
  $injectTokens.$log,
35646
- /** @param {ng.LogService} log */
36087
+ /**
36088
+ * Returns the $sse service function
36089
+ * @param {ng.LogService} log
36090
+ * @returns {ng.SseService}
36091
+ */
35647
36092
  (log) => {
35648
36093
  this.$log = log;
35649
36094
  return (url, config = {}) => {
@@ -35738,7 +36183,7 @@ class SseProvider {
35738
36183
  es.close();
35739
36184
  },
35740
36185
  connect() {
35741
- if (closed == false) {
36186
+ if (closed === false) {
35742
36187
  close();
35743
36188
  }
35744
36189
  connect();
@@ -35800,246 +36245,29 @@ function ngViewportDirective() {
35800
36245
  };
35801
36246
  }
35802
36247
 
35803
- ngWorkerDirective.$inject = ["$worker", $injectTokens.$parse, $injectTokens.$log];
35804
36248
  /**
35805
- * ngWorker directive factory
35806
- * Usage: <div ng-worker="workerName" data-params="{{ expression }}" data-on-result="callback($result)"></div>
36249
+ * @return {ng.Directive}
35807
36250
  */
35808
- function ngWorkerDirective($worker, $parse, $log) {
36251
+ function ngWasmDirective() {
35809
36252
  return {
35810
- restrict: "A",
35811
- link(scope, element, attrs) {
35812
- const workerName = attrs.ngWorker;
35813
- if (!workerName) {
35814
- $log.warn("ngWorker: missing worker name");
35815
- return;
35816
- }
35817
-
35818
- const eventName = attrs.trigger || getEventNameForElement(element);
35819
-
35820
- let throttled = false;
35821
- let intervalId;
35822
-
35823
- if (isDefined(attrs.latch)) {
35824
- attrs.$observe(
35825
- "latch",
35826
- callBackAfterFirst(() => element.dispatchEvent(new Event(eventName))),
35827
- );
35828
- }
35829
-
35830
- if (isDefined(attrs.interval)) {
35831
- element.dispatchEvent(new Event(eventName));
35832
- intervalId = setInterval(
35833
- () => element.dispatchEvent(new Event(eventName)),
35834
- parseInt(attrs.interval) || 1000,
35835
- );
35836
- }
35837
-
35838
- const worker = $worker(workerName, {
35839
- onMessage: (result) => {
35840
- if (isDefined(attrs.dataOnResult)) {
35841
- $parse(attrs.dataOnResult)(scope, { $result: result });
35842
- } else {
35843
- const swap = attrs.swap || "innerHTML";
35844
- handleSwap(result, swap, element);
35845
- }
35846
- },
35847
- onError: (err) => {
35848
- $log.error(`[ng-worker:${workerName}]`, err);
35849
- if (isDefined(attrs.dataOnError)) {
35850
- $parse(attrs.dataOnError)(scope, { $error: err });
35851
- } else {
35852
- element.textContent = "Error";
35853
- }
35854
- },
35855
- });
35856
-
35857
- element.addEventListener(eventName, async () => {
35858
- if (element.disabled) return;
35859
-
35860
- if (isDefined(attrs.delay)) {
35861
- await wait(parseInt(attrs.delay) || 0);
35862
- }
35863
-
35864
- if (throttled) return;
35865
-
35866
- if (isDefined(attrs.throttle)) {
35867
- throttled = true;
35868
- attrs.$set("throttled", true);
35869
- setTimeout(() => {
35870
- attrs.$set("throttled", false);
35871
- throttled = false;
35872
- }, parseInt(attrs.throttle));
35873
- }
35874
-
35875
- let params;
35876
- try {
35877
- params = attrs.params ? scope.$eval(attrs.params) : undefined;
35878
- } catch (err) {
35879
- $log.error("ngWorker: failed to evaluate data-params", err);
35880
- params = undefined;
35881
- }
35882
-
35883
- worker.post(params);
35884
- });
35885
-
35886
- if (intervalId) {
35887
- scope.$on("$destroy", () => clearInterval(intervalId));
35888
- }
35889
-
35890
- if (eventName === "load") {
35891
- element.dispatchEvent(new Event("load"));
35892
- }
36253
+ async link($scope, _, $attrs) {
36254
+ $scope.$target[$attrs.as || "wasm"] = (
36255
+ await instantiateWasm($attrs.src)
36256
+ ).exports;
35893
36257
  },
35894
36258
  };
35895
36259
  }
35896
36260
 
35897
36261
  /**
35898
- * Swap result into DOM based on strategy
35899
- */
35900
- function handleSwap(result, swap, element) {
35901
- switch (swap) {
35902
- case "outerHTML": {
35903
- const parent = element.parentNode;
35904
- if (!parent) return;
35905
- const temp = document.createElement("div");
35906
- temp.innerHTML = result;
35907
- parent.replaceChild(temp.firstChild, element);
35908
- break;
35909
- }
35910
- case "textContent":
35911
- element.textContent = result;
35912
- break;
35913
- case "beforebegin":
35914
- element.insertAdjacentHTML("beforebegin", result);
35915
- break;
35916
- case "afterbegin":
35917
- element.insertAdjacentHTML("afterbegin", result);
35918
- break;
35919
- case "beforeend":
35920
- element.insertAdjacentHTML("beforeend", result);
35921
- break;
35922
- case "afterend":
35923
- element.insertAdjacentHTML("afterend", result);
35924
- break;
35925
- case "innerHTML":
35926
- default:
35927
- element.innerHTML = result;
35928
- break;
35929
- }
35930
- }
35931
-
35932
- /**
35933
- * Worker Provider
35934
- *
35935
- * Usage:
35936
- * const worker = $worker('./math.worker.js', {
35937
- * onMessage: (data) => console.log('Result:', data),
35938
- * onError: (err) => console.error('Worker error:', err),
35939
- * autoTerminate: false,
35940
- * transformMessage: (d) => d,
35941
- * });
35942
- *
35943
- * worker.post({ action: 'fib', n: 20 });
35944
- * worker.terminate();
36262
+ * @return {ng.Directive}
35945
36263
  */
35946
- class WorkerProvider {
35947
- /**
35948
- * @type {ng.LogService}
35949
- */
35950
- $log;
35951
- constructor() {
35952
- /**
35953
- * Optional provider-level defaults
35954
- * @type {ng.WorkerConfig}
35955
- */
35956
- this.defaults = {
35957
- autoTerminate: false,
35958
- transformMessage(data) {
35959
- try {
35960
- return JSON.parse(data);
35961
- } catch {
35962
- return data;
35963
- }
35964
- },
35965
- };
35966
- }
35967
-
35968
- /**
35969
- * Returns the $worker service function
35970
- * @returns {ng.WorkerService}
35971
- */
35972
- $get = [
35973
- $injectTokens.$log,
35974
- /** @param {ng.LogService} log */
35975
- (log) => {
35976
- this.$log = log;
35977
- return (scriptPath, config = {}) => {
35978
- const merged = { ...this.defaults, ...config };
35979
- return this.#createWorker(scriptPath, merged);
35980
- };
36264
+ function ngScopeDirective() {
36265
+ return {
36266
+ scope: false,
36267
+ async link($scope, _, $attrs) {
36268
+ $scope.$scopename = $attrs.ngScope;
35981
36269
  },
35982
- ];
35983
-
35984
- /**
35985
- * Creates a managed Web Worker instance
35986
- * @param {string | URL} scriptPath
35987
- * @param {ng.WorkerConfig} config
35988
- * @returns {import("./interface.ts").WorkerConnection}
35989
- */
35990
- #createWorker(scriptPath, config) {
35991
- if (!scriptPath) throw new Error("Worker script path required");
35992
-
35993
- let worker = new Worker(scriptPath, { type: "module" });
35994
- let terminated = false;
35995
-
35996
- const reconnect = () => {
35997
- if (terminated) return;
35998
- this.$log.info("Worker: restarting...");
35999
- worker.terminate();
36000
- worker = new Worker(scriptPath, { type: "module" });
36001
- wire(worker);
36002
- };
36003
-
36004
- const wire = (w) => {
36005
- w.onmessage = (e) => {
36006
- let data = e.data;
36007
- try {
36008
- data = config.transformMessage ? config.transformMessage(data) : data;
36009
- } catch {
36010
- /* no-op */
36011
- }
36012
- config.onMessage?.(data, e);
36013
- };
36014
-
36015
- w.onerror = (err) => {
36016
- config.onError?.(err);
36017
- if (config.autoRestart) reconnect();
36018
- };
36019
- };
36020
-
36021
- wire(worker);
36022
- let that = this;
36023
- return {
36024
- post(data) {
36025
- if (terminated) return that.$log.warn("Worker already terminated");
36026
- try {
36027
- worker.postMessage(data);
36028
- } catch (err) {
36029
- that.$log.error("Worker post failed", err);
36030
- }
36031
- },
36032
- terminate() {
36033
- terminated = true;
36034
- worker.terminate();
36035
- },
36036
- restart() {
36037
- if (terminated)
36038
- return that.$log.warn("Worker cannot restart after terminate");
36039
- reconnect();
36040
- },
36041
- };
36042
- }
36270
+ };
36043
36271
  }
36044
36272
 
36045
36273
  /**
@@ -36121,7 +36349,9 @@ function registerNgModule(angular) {
36121
36349
  ngValue: ngValueDirective,
36122
36350
  ngModelOptions: ngModelOptionsDirective,
36123
36351
  ngViewport: ngViewportDirective,
36352
+ ngWasm: ngWasmDirective,
36124
36353
  ngWorker: ngWorkerDirective,
36354
+ ngScope: ngScopeDirective,
36125
36355
  })
36126
36356
  .directive({
36127
36357
  input: hiddenInputBrowserCacheDirective,
@@ -36188,7 +36418,6 @@ function registerNgModule(angular) {
36188
36418
  $url: UrlService,
36189
36419
  $stateRegistry: StateRegistryProvider,
36190
36420
  $eventBus: PubSubProvider,
36191
- $worker: WorkerProvider,
36192
36421
  });
36193
36422
  },
36194
36423
  ],
@@ -36220,7 +36449,7 @@ class Angular {
36220
36449
  /**
36221
36450
  * @type {string} `version` from `package.json`
36222
36451
  */
36223
- this.version = "0.11.0"; //inserted via rollup plugin
36452
+ this.version = "0.12.0"; //inserted via rollup plugin
36224
36453
 
36225
36454
  /** @type {!Array<string|any>} */
36226
36455
  this.bootsrappedModules = [];
@@ -36240,7 +36469,7 @@ class Angular {
36240
36469
 
36241
36470
  /**
36242
36471
  * Gets scope for a given element.
36243
- * @type {(Element) => *}
36472
+ * @type {(Element) => ng.Scope}
36244
36473
  */
36245
36474
  this.getScope = getScope;
36246
36475
 
@@ -36251,6 +36480,70 @@ class Angular {
36251
36480
  registerNgModule(this);
36252
36481
  }
36253
36482
 
36483
+ /**
36484
+ *
36485
+ * The `angular.module` is a global place for creating, registering and retrieving AngularTS
36486
+ * modules.
36487
+ * All modules (AngularTS core or 3rd party) that should be available to an application must be
36488
+ * registered using this mechanism.
36489
+ *
36490
+ * Passing one argument retrieves an existing {@link ng.NgModule},
36491
+ * whereas passing more than one argument creates a new {@link ng.NgModule}
36492
+ *
36493
+ *
36494
+ * # Module
36495
+ *
36496
+ * A module is a collection of services, directives, controllers, filters, workers, WebAssembly modules, and configuration information.
36497
+ * `angular.module` is used to configure the {@link auto.$injector $injector}.
36498
+ *
36499
+ * ```js
36500
+ * // Create a new module
36501
+ * let myModule = angular.module('myModule', []);
36502
+ *
36503
+ * // register a new service
36504
+ * myModule.value('appName', 'MyCoolApp');
36505
+ *
36506
+ * // configure existing services inside initialization blocks.
36507
+ * myModule.config(['$locationProvider', function($locationProvider) {
36508
+ * // Configure existing providers
36509
+ * $locationProvider.hashPrefix('!');
36510
+ * }]);
36511
+ * ```
36512
+ *
36513
+ * Then you can create an injector and load your modules like this:
36514
+ *
36515
+ * ```js
36516
+ * let injector = angular.injector(['ng', 'myModule'])
36517
+ * ```
36518
+ *
36519
+ * However it's more likely that you'll just use
36520
+ * `ng-app` directive or
36521
+ * {@link bootstrap} to simplify this process for you.
36522
+ *
36523
+ * @param {string} name The name of the module to create or retrieve.
36524
+ * @param {Array.<string>} [requires] If specified then new module is being created. If
36525
+ * unspecified then the module is being retrieved for further configuration.
36526
+ * @param {ng.Injectable<any>} [configFn] Optional configuration function for the module that gets
36527
+ * passed to {@link NgModule.config NgModule.config()}.
36528
+ * @returns {NgModule} A newly registered module.
36529
+ */
36530
+ module(name, requires, configFn) {
36531
+ assertNotHasOwnProperty(name, "module");
36532
+ if (requires && hasOwn(modules, name)) {
36533
+ modules[name] = null; // force ensure to recreate the module
36534
+ }
36535
+ return ensure(modules, name, () => {
36536
+ if (!requires) {
36537
+ throw $injectorMinErr(
36538
+ "nomod",
36539
+ "Module '{0}' is not available. Possibly misspelled or not loaded",
36540
+ name,
36541
+ );
36542
+ }
36543
+ return new NgModule(name, requires, configFn);
36544
+ });
36545
+ }
36546
+
36254
36547
  /**
36255
36548
  * Use this function to manually start up AngularTS application.
36256
36549
  *
@@ -36335,6 +36628,7 @@ class Angular {
36335
36628
  * @param {ng.InjectorService} $injector
36336
36629
  */
36337
36630
  (scope, el, compile, $injector) => {
36631
+ this.$rootScope = scope;
36338
36632
  // ng-route deps
36339
36633
  this.$injector = $injector; // TODO refactor away as this as this prevents multiple apps from being used
36340
36634
 
@@ -36418,70 +36712,30 @@ class Angular {
36418
36712
  }
36419
36713
 
36420
36714
  /**
36715
+ * Retrieves a scope by its registered name and returns its Proxy wrapper.
36421
36716
  *
36422
- * The `angular.module` is a global place for creating, registering and retrieving AngularTS
36423
- * modules.
36424
- * All modules (AngularTS core or 3rd party) that should be available to an application must be
36425
- * registered using this mechanism.
36426
- *
36427
- * Passing one argument retrieves an existing {@link import('./interface.ts').Module},
36428
- * whereas passing more than one argument creates a new {@link import('./interface.ts').Module}
36429
- *
36430
- *
36431
- * # Module
36432
- *
36433
- * A module is a collection of services, directives, controllers, filters, and configuration information.
36434
- * `angular.module` is used to configure the {@link auto.$injector $injector}.
36435
- *
36436
- * ```js
36437
- * // Create a new module
36438
- * let myModule = angular.module('myModule', []);
36717
+ * Internally, this walks down the `Scope` tree starting from `$rootScope`
36718
+ * and checks for a matching `$scopename` property. The `$scopename` property
36719
+ * may be defined statically on controllers using `as` syntax, assigned via the `ngScope` directive,
36720
+ * or defined on `$scope` injectable.
36439
36721
  *
36440
- * // register a new service
36441
- * myModule.value('appName', 'MyCoolApp');
36442
- *
36443
- * // configure existing services inside initialization blocks.
36444
- * myModule.config(['$locationProvider', function($locationProvider) {
36445
- * // Configure existing providers
36446
- * $locationProvider.hashPrefix('!');
36447
- * }]);
36448
- * ```
36449
- *
36450
- * Then you can create an injector and load your modules like this:
36451
- *
36452
- * ```js
36453
- * let injector = angular.injector(['ng', 'myModule'])
36454
- * ```
36455
- *
36456
- * However it's more likely that you'll just use
36457
- * {@link ng.directive:ngApp ngApp} or
36458
- * {@link angular.bootstrap} to simplify this process for you.
36459
- *
36460
- * @param {string} name The name of the module to create or retrieve.
36461
- * @param {Array.<string>} [requires] If specified then new module is being created. If
36462
- * unspecified then the module is being retrieved for further configuration.
36463
- * @param {import("./interface.ts").Injectable<any>} [configFn] Optional configuration function for the module that gets
36464
- * passed to {@link NgModule.config NgModule.config()}.
36465
- * @returns {NgModule} A newly registered module.
36722
+ * @param {string} name
36723
+ * @returns {ProxyHandler<ng.Scope>|undefined}
36466
36724
  */
36467
- module(name, requires, configFn) {
36468
- assertNotHasOwnProperty(name, "module");
36469
- if (requires && hasOwn(modules, name)) {
36470
- modules[name] = null;
36725
+ getScopeByName(name) {
36726
+ const scope = this.$rootScope.$searchByName(name);
36727
+ if (scope) {
36728
+ return scope.$proxy;
36471
36729
  }
36472
- return ensure(modules, name, () => {
36473
- if (!requires) {
36474
- throw $injectorMinErr(
36475
- "nomod",
36476
- "Module '{0}' is not available. Possibly misspelled or not loaded",
36477
- name,
36478
- );
36479
- }
36480
- return new NgModule(name, requires, configFn);
36481
- });
36482
36730
  }
36483
36731
  }
36484
36732
 
36733
+ /**
36734
+ * @param {Object.<string, NgModule>} obj
36735
+ * @param {string} name
36736
+ * @param {Function} factory
36737
+ * @returns {NgModule}
36738
+ */
36485
36739
  function ensure(obj, name, factory) {
36486
36740
  return obj[name] || (obj[name] = factory());
36487
36741
  }