@angular-wave/angular.ts 0.10.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 (62) hide show
  1. package/@types/angular.d.ts +84 -58
  2. package/@types/animations/animate-css-driver.d.ts +0 -1
  3. package/@types/animations/animate-css.d.ts +0 -1
  4. package/@types/animations/animate-js-driver.d.ts +1 -7
  5. package/@types/animations/animate-js.d.ts +1 -4
  6. package/@types/animations/animate.d.ts +5 -355
  7. package/@types/animations/animation.d.ts +4 -4
  8. package/@types/animations/interface.d.ts +84 -0
  9. package/@types/animations/queue/animate-queue.d.ts +21 -0
  10. package/@types/animations/queue/interface.d.ts +50 -0
  11. package/@types/animations/runner/animate-runner.d.ts +99 -0
  12. package/@types/core/compile/attributes.d.ts +5 -5
  13. package/@types/core/compile/compile.d.ts +4 -4
  14. package/@types/core/controller/controller.d.ts +1 -1
  15. package/@types/core/di/di.d.ts +26 -0
  16. package/@types/core/di/injector.d.ts +0 -11
  17. package/@types/core/di/internal-injector.d.ts +2 -2
  18. package/@types/core/di/ng-module/ng-module.d.ts +197 -0
  19. package/@types/core/filter/filter.d.ts +2 -2
  20. package/@types/core/sanitize/interface.d.ts +8 -0
  21. package/@types/core/sanitize/sanitize-uri.d.ts +5 -2
  22. package/@types/core/scope/interface.d.ts +2 -2
  23. package/@types/core/scope/scope.d.ts +10 -2
  24. package/@types/directive/class/class.d.ts +3 -3
  25. package/@types/directive/form/form.d.ts +7 -7
  26. package/@types/directive/if/if.d.ts +2 -2
  27. package/@types/directive/include/include.d.ts +4 -4
  28. package/@types/directive/inject/inject.d.ts +2 -2
  29. package/@types/directive/input/input.d.ts +10 -10
  30. package/@types/directive/messages/messages.d.ts +19 -23
  31. package/@types/directive/model/model.d.ts +3 -3
  32. package/@types/directive/scope/scope.d.ts +4 -0
  33. package/@types/directive/show-hide/show-hide.d.ts +3 -4
  34. package/@types/directive/switch/switch.d.ts +3 -5
  35. package/@types/directive/wasm/wasm.d.ts +4 -0
  36. package/@types/{services → directive}/worker/interface.d.ts +1 -0
  37. package/@types/directive/worker/worker.d.ts +18 -8
  38. package/@types/interface.d.ts +49 -21
  39. package/@types/namespace.d.ts +29 -4
  40. package/@types/ng.d.ts +3 -5
  41. package/@types/router/params/interface.d.ts +0 -25
  42. package/@types/router/state/interface.d.ts +0 -9
  43. package/@types/router/template-factory.d.ts +1 -1
  44. package/@types/router/transition/interface.d.ts +0 -33
  45. package/@types/services/log/log.d.ts +2 -2
  46. package/@types/services/sce/sce.d.ts +4 -82
  47. package/@types/services/sse/sse.d.ts +1 -5
  48. package/@types/services/storage/interface.d.ts +5 -0
  49. package/@types/services/storage/storage.d.ts +19 -0
  50. package/@types/services/stream/interface.d.ts +18 -0
  51. package/@types/shared/dom.d.ts +25 -10
  52. package/@types/shared/strings.d.ts +0 -6
  53. package/@types/shared/utils.d.ts +24 -14
  54. package/dist/angular-ts.esm.js +1867 -1506
  55. package/dist/angular-ts.umd.js +1867 -1506
  56. package/dist/angular-ts.umd.min.js +1 -1
  57. package/dist/angular.css +1 -1
  58. package/package.json +1 -2
  59. package/@types/animations/animate-queue.d.ts +0 -27
  60. package/@types/animations/animate-runner.d.ts +0 -31
  61. package/@types/core/di/ng-module.d.ts +0 -156
  62. package/@types/services/worker/worker.d.ts +0 -31
@@ -1,4 +1,4 @@
1
- /* Version: 0.10.0 - November 8, 2025 10:37:14 */
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);
@@ -1897,7 +1913,7 @@ function setIsolateScope(element, scope) {
1897
1913
  * Gets the controller instance for a given element, if exists. Defaults to "ngControllerController"
1898
1914
  *
1899
1915
  * @param {Element} element - The DOM element to get data from.
1900
- * @param {string} [name] - The DOM element to get data from.
1916
+ * @param {string} [name] - Controller name.
1901
1917
  * @returns {import("../core/scope/scope.js").Scope|undefined} - The retrieved data
1902
1918
  */
1903
1919
  function getController(element, name) {
@@ -2047,7 +2063,7 @@ function cleanElementData(nodes) {
2047
2063
  /**
2048
2064
  * Return instance of InjectorService attached to element
2049
2065
  * @param {Element} element
2050
- * @returns {import('../core/di/internal-injector.js').InjectorService}
2066
+ * @returns {ng.InjectorService}
2051
2067
  */
2052
2068
  function getInjector(element) {
2053
2069
  return getInheritedData(element, "$injector");
@@ -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
@@ -2107,6 +2139,26 @@ function domInsert(element, parentElement, afterElement) {
2107
2139
  }
2108
2140
  }
2109
2141
 
2142
+ function animatedomInsert(element, parent, after) {
2143
+ const originalVisibility = element.style.visibility;
2144
+ const originalPosition = element.style.position;
2145
+ const originalPointerEvents = element.style.pointerEvents;
2146
+
2147
+ Object.assign(element.style, {
2148
+ visibility: "hidden",
2149
+ position: "absolute",
2150
+ pointerEvents: "none",
2151
+ });
2152
+
2153
+ domInsert(element, parent, after);
2154
+
2155
+ requestAnimationFrame(() => {
2156
+ element.style.visibility = originalVisibility;
2157
+ element.style.position = originalPosition;
2158
+ element.style.pointerEvents = originalPointerEvents;
2159
+ });
2160
+ }
2161
+
2110
2162
  /**
2111
2163
  * Returns the base href of the document.
2112
2164
  *
@@ -2138,8 +2190,6 @@ const $injectTokens = Object.freeze({
2138
2190
  $attrs: "$attrs",
2139
2191
  $scope: "$scope",
2140
2192
  $element: "$element",
2141
- $$AnimateRunner: "$$AnimateRunner",
2142
- $$animateAsyncRun: "$$animateAsyncRun",
2143
2193
  $$animateCache: "$$animateCache",
2144
2194
  $$animateCssDriver: "$$animateCssDriver",
2145
2195
  $$animateJs: "$$animateJs",
@@ -2200,6 +2250,706 @@ function provider(services) {
2200
2250
  return services.map((x) => x + "Provider");
2201
2251
  }
2202
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
+
2203
2953
  /** @private */
2204
2954
  const INJECTOR_LITERAL = "$injector";
2205
2955
  /** @private */
@@ -2225,7 +2975,7 @@ class NgModule {
2225
2975
  /**
2226
2976
  * @param {string} name - Name of the module
2227
2977
  * @param {Array<string>} requires - List of modules which the injector will load before the current module
2228
- * @param {import("../../interface.ts").Injectable<any>} [configFn]
2978
+ * @param {ng.Injectable<any>} [configFn]
2229
2979
  */
2230
2980
  constructor(name, requires, configFn) {
2231
2981
  assert(isString(name), "name required");
@@ -2251,7 +3001,7 @@ class NgModule {
2251
3001
  /** @type {!Array<Array<*>>} */
2252
3002
  this.configBlocks = [];
2253
3003
 
2254
- /** @type {!Array.<import("../../interface.ts").Injectable<any>>} */
3004
+ /** @type {!Array.<ng.Injectable<any>>} */
2255
3005
  this.runBlocks = [];
2256
3006
 
2257
3007
  if (configFn) {
@@ -2259,6 +3009,8 @@ class NgModule {
2259
3009
  }
2260
3010
 
2261
3011
  this.services = [];
3012
+
3013
+ this.wasmModules = [];
2262
3014
  }
2263
3015
 
2264
3016
  /**
@@ -2283,7 +3035,7 @@ class NgModule {
2283
3035
 
2284
3036
  /**
2285
3037
  *
2286
- * @param {import("../../interface.ts").Injectable<any>} configFn
3038
+ * @param {ng.Injectable<any>} configFn
2287
3039
  * @returns {NgModule}
2288
3040
  */
2289
3041
  config(configFn) {
@@ -2292,7 +3044,7 @@ class NgModule {
2292
3044
  }
2293
3045
 
2294
3046
  /**
2295
- * @param {import("../../interface.ts").Injectable<any>} block
3047
+ * @param {ng.Injectable<any>} block
2296
3048
  * @returns {NgModule}
2297
3049
  */
2298
3050
  run(block) {
@@ -2302,7 +3054,7 @@ class NgModule {
2302
3054
 
2303
3055
  /**
2304
3056
  * @param {string} name
2305
- * @param {import("../../interface.ts").Component} options
3057
+ * @param {ng.Component} options
2306
3058
  * @returns {NgModule}
2307
3059
  */
2308
3060
  component(name, options) {
@@ -2315,7 +3067,7 @@ class NgModule {
2315
3067
 
2316
3068
  /**
2317
3069
  * @param {string} name
2318
- * @param {import("../../interface.ts").Injectable<any>} providerFunction
3070
+ * @param {ng.Injectable<any>} providerFunction
2319
3071
  * @returns {NgModule}
2320
3072
  */
2321
3073
  factory(name, providerFunction) {
@@ -2328,7 +3080,7 @@ class NgModule {
2328
3080
 
2329
3081
  /**
2330
3082
  * @param {string} name
2331
- * @param {import("../../interface.ts").Injectable<any>} serviceFunction
3083
+ * @param {ng.Injectable<any>} serviceFunction
2332
3084
  * @returns {NgModule}
2333
3085
  */
2334
3086
  service(name, serviceFunction) {
@@ -2342,7 +3094,7 @@ class NgModule {
2342
3094
 
2343
3095
  /**
2344
3096
  * @param {string} name
2345
- * @param {import("../../interface.ts").Injectable<any>} providerType
3097
+ * @param {ng.Injectable<any>} providerType
2346
3098
  * @returns {NgModule}
2347
3099
  */
2348
3100
  provider(name, providerType) {
@@ -2355,7 +3107,7 @@ class NgModule {
2355
3107
 
2356
3108
  /**
2357
3109
  * @param {string} name
2358
- * @param {import("../../interface.ts").Injectable<any>} decorFn
3110
+ * @param {ng.Injectable<any>} decorFn
2359
3111
  * @returns {NgModule}
2360
3112
  */
2361
3113
  decorator(name, decorFn) {
@@ -2368,7 +3120,7 @@ class NgModule {
2368
3120
 
2369
3121
  /**
2370
3122
  * @param {string} name
2371
- * @param {import("../../interface.ts").Injectable<any>} directiveFactory
3123
+ * @param {ng.Injectable<any>} directiveFactory
2372
3124
  * @returns {NgModule}
2373
3125
  */
2374
3126
  directive(name, directiveFactory) {
@@ -2385,7 +3137,7 @@ class NgModule {
2385
3137
 
2386
3138
  /**
2387
3139
  * @param {string} name
2388
- * @param {import("../../interface.ts").Injectable<any>} animationFactory
3140
+ * @param {ng.Injectable<any>} animationFactory
2389
3141
  * @returns {NgModule}
2390
3142
  */
2391
3143
  animation(name, animationFactory) {
@@ -2402,7 +3154,7 @@ class NgModule {
2402
3154
 
2403
3155
  /**
2404
3156
  * @param {string} name
2405
- * @param {import("../../interface.ts").Injectable<any>} filterFn
3157
+ * @param {ng.Injectable<any>} filterFn
2406
3158
  * @return {NgModule}
2407
3159
  */
2408
3160
  filter(name, filterFn) {
@@ -2415,7 +3167,7 @@ class NgModule {
2415
3167
 
2416
3168
  /**
2417
3169
  * @param {string} name
2418
- * @param {import("../../interface.ts").Injectable<any>} ctlFn
3170
+ * @param {ng.Injectable<any>} ctlFn
2419
3171
  * @returns {NgModule}
2420
3172
  */
2421
3173
  controller(name, ctlFn) {
@@ -2425,12 +3177,192 @@ class NgModule {
2425
3177
  this.invokeQueue.push([CONTROLLER_LITERAL, "register", [name, ctlFn]]);
2426
3178
  return this;
2427
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;
2428
3364
  }
2429
3365
 
2430
- const ARROW_ARG$1 = /^([^(]+?)=>/;
2431
- const FN_ARGS$1 = /^[^(]*\(\s*([^)]*)\)/m;
2432
- const FN_ARG$1 = /^\s*(_?)(\S+?)\1\s*$/;
2433
- const STRIP_COMMENTS$1 = /((\/\/.*$)|(\/\*[\s\S]*?\*\/))/gm;
2434
3366
  const $injectorMinErr$2 = minErr(INJECTOR_LITERAL);
2435
3367
 
2436
3368
  const providerSuffix$1 = "Provider";
@@ -2449,7 +3381,7 @@ class AbstractInjector {
2449
3381
  this.strictDi = strictDi;
2450
3382
  /** @type {string[]} */
2451
3383
  this.path = [];
2452
- /** @type {Object.<string, import("./ng-module.js").NgModule>} */
3384
+ /** @type {Object.<string, ng.NgModule>} */
2453
3385
  this.modules = {};
2454
3386
  }
2455
3387
 
@@ -2493,7 +3425,7 @@ class AbstractInjector {
2493
3425
  */
2494
3426
  injectionArgs(fn, locals, serviceName) {
2495
3427
  const args = [];
2496
- const $inject = annotate$1(fn, this.strictDi, serviceName);
3428
+ const $inject = annotate(fn, this.strictDi, serviceName);
2497
3429
 
2498
3430
  for (let i = 0, { length } = $inject; i < length; i++) {
2499
3431
  const key = $inject[i];
@@ -2616,7 +3548,7 @@ class InjectorService extends AbstractInjector {
2616
3548
 
2617
3549
  /** @type {ProviderInjector} */
2618
3550
  this.providerInjector = providerInjector;
2619
- /** @type {Object.<string, import("./ng-module.js").NgModule>} */
3551
+ /** @type {Object.<string, ng.NgModule>} */
2620
3552
  this.modules = providerInjector.modules;
2621
3553
  }
2622
3554
 
@@ -2642,80 +3574,56 @@ class InjectorService extends AbstractInjector {
2642
3574
  const hasCache = hasOwn(this.cache, name);
2643
3575
  return hasProvider || hasCache;
2644
3576
  }
2645
- }
2646
-
2647
- // Helpers
2648
-
2649
- /**
2650
- * @param {Function} fn
2651
- * @returns {string}
2652
- */
2653
- function stringifyFn$1(fn) {
2654
- return Function.prototype.toString.call(fn);
2655
- }
2656
3577
 
2657
- /**
2658
- * @param {Function} fn
2659
- * @returns {Array<any>}
2660
- */
2661
- function extractArgs$1(fn) {
2662
- const fnText = stringifyFn$1(fn).replace(STRIP_COMMENTS$1, "");
2663
- return fnText.match(ARROW_ARG$1) || fnText.match(FN_ARGS$1);
2664
- }
2665
-
2666
- /**
2667
- * @param {Function} func
2668
- * @returns {boolean}
2669
- */
2670
- function isClass(func) {
2671
- return /^class\b/.test(stringifyFn$1(func));
3578
+ loadNewModules() {}
2672
3579
  }
2673
3580
 
2674
3581
  /**
3582
+ * Creates a proxy that automatically persists an object's state
3583
+ * into a storage backend whenever a property is set.
2675
3584
  *
2676
- * @param {any} fn
2677
- * @param {boolean} strictDi
2678
- * @param {string} name
2679
- * @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}
2680
3590
  */
2681
- function annotate$1(fn, strictDi, name) {
2682
- 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;
2683
3594
 
2684
- if (typeof fn === "function") {
2685
- if (!($inject = fn.$inject)) {
2686
- $inject = [];
2687
- if (fn.length) {
2688
- if (strictDi) {
2689
- throw $injectorMinErr$2(
2690
- "strictdi",
2691
- "{0} is not using explicit annotation and cannot be invoked in strict mode",
2692
- name,
2693
- );
2694
- }
2695
- argDecl = extractArgs$1(fn);
2696
- argDecl[1].split(/,/).forEach(function (arg) {
2697
- arg.replace(FN_ARG$1, function (_all, _underscore, name) {
2698
- $inject.push(name);
2699
- });
2700
- });
2701
- }
2702
- 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}"`);
2703
3602
  }
2704
- } else if (Array.isArray(fn)) {
2705
- last = /** @type {Array} */ (fn).length - 1;
2706
- assertArgFn(fn[last], "fn");
2707
- $inject = /** @type {Array} */ (fn).slice(0, last);
2708
- } else {
2709
- assertArgFn(fn, "fn", true);
2710
3603
  }
2711
- 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
+ });
2712
3625
  }
2713
3626
 
2714
- const ARROW_ARG = /^([^(]+?)=>/;
2715
- const FN_ARGS = /^[^(]*\(\s*([^)]*)\)/m;
2716
- const FN_ARG_SPLIT = /,/;
2717
- const FN_ARG = /^\s*(_?)(\S+?)\1\s*$/;
2718
- const STRIP_COMMENTS = /((\/\/.*$)|(\/\*[\s\S]*?\*\/))/gm;
2719
3627
  const $injectorMinErr$1 = minErr(INJECTOR_LITERAL);
2720
3628
  const providerSuffix = "Provider";
2721
3629
 
@@ -2738,6 +3646,9 @@ function createInjector(modulesToLoad, strictDi = false) {
2738
3646
  service: supportObject(service),
2739
3647
  value: supportObject(value),
2740
3648
  constant: supportObject(constant),
3649
+ session: supportObject(session),
3650
+ local: supportObject(local),
3651
+ store: supportObject(store),
2741
3652
  decorator,
2742
3653
  },
2743
3654
  };
@@ -2871,13 +3782,78 @@ function createInjector(modulesToLoad, strictDi = false) {
2871
3782
  };
2872
3783
  }
2873
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
+
2874
3850
  /**
2875
3851
  *
2876
3852
  * @param {Array<String|Function>} modulesToLoad
2877
3853
  * @returns
2878
3854
  */
2879
3855
  function loadModules(modulesToLoad) {
2880
- assertArg$1(
3856
+ assertArg(
2881
3857
  isUndefined(modulesToLoad) || Array.isArray(modulesToLoad),
2882
3858
  "modulesToLoad",
2883
3859
  "not an array",
@@ -2890,8 +3866,10 @@ function createInjector(modulesToLoad, strictDi = false) {
2890
3866
 
2891
3867
  try {
2892
3868
  if (isString(module)) {
2893
- /** @type {import('./ng-module.js').NgModule} */
2894
- const moduleFn = window["angular"].module(module);
3869
+ /** @type {ng.NgModule} */
3870
+ const moduleFn = window["angular"].module(
3871
+ /** @type {string} */ (module),
3872
+ );
2895
3873
  instanceInjector.modules[/** @type {string } */ (module)] = moduleFn;
2896
3874
  runBlocks = runBlocks
2897
3875
  .concat(loadModules(moduleFn.requires))
@@ -2935,64 +3913,6 @@ function createInjector(modulesToLoad, strictDi = false) {
2935
3913
  }
2936
3914
  }
2937
3915
 
2938
- // Helpers
2939
-
2940
- /**
2941
- * @param {String} fn
2942
- * @returns {String}
2943
- */
2944
- function stringifyFn(fn) {
2945
- return Function.prototype.toString.call(fn);
2946
- }
2947
-
2948
- /**
2949
- * @param {String} fn
2950
- * @returns {Array<any>}
2951
- */
2952
- function extractArgs(fn) {
2953
- const fnText = stringifyFn(fn).replace(STRIP_COMMENTS, "");
2954
- return fnText.match(ARROW_ARG) || fnText.match(FN_ARGS);
2955
- }
2956
-
2957
- /**
2958
- * @param {any} fn
2959
- * @param {boolean} [strictDi]
2960
- * @param {String} [name]
2961
- * @returns {Array<string>}
2962
- */
2963
- function annotate(fn, strictDi, name) {
2964
- let $inject, argDecl, last;
2965
-
2966
- if (typeof fn === "function") {
2967
- if (!($inject = fn.$inject)) {
2968
- $inject = [];
2969
- if (fn.length) {
2970
- if (strictDi) {
2971
- throw $injectorMinErr$1(
2972
- "strictdi",
2973
- "{0} is not using explicit annotation and cannot be invoked in strict mode",
2974
- name,
2975
- );
2976
- }
2977
- argDecl = extractArgs(/** @type {String} */ (fn));
2978
- argDecl[1].split(FN_ARG_SPLIT).forEach(function (arg) {
2979
- arg.replace(FN_ARG, function (all, underscore, name) {
2980
- $inject.push(name);
2981
- });
2982
- });
2983
- }
2984
- fn.$inject = $inject;
2985
- }
2986
- } else if (Array.isArray(fn)) {
2987
- last = /** @type {Array} */ (fn).length - 1;
2988
- assertArgFn(fn[last], "fn");
2989
- $inject = /** @type {Array} */ (fn).slice(0, last);
2990
- } else {
2991
- assertArgFn(fn, "fn", true);
2992
- }
2993
- return $inject;
2994
- }
2995
-
2996
3916
  function supportObject(delegate) {
2997
3917
  return function (key, value) {
2998
3918
  if (isObject(key)) {
@@ -3015,7 +3935,7 @@ class NodeRef {
3015
3935
  * @throws {Error} If the argument is invalid or cannot be wrapped properly.
3016
3936
  */
3017
3937
  constructor(element) {
3018
- assertArg$1(element, "element");
3938
+ assertArg(element, "element");
3019
3939
  this.initial = null;
3020
3940
 
3021
3941
  /** @private @type {Node | ChildNode | null} */
@@ -3071,8 +3991,8 @@ class NodeRef {
3071
3991
  }
3072
3992
 
3073
3993
  // Handle array of elements
3074
- else if (element instanceof Array) {
3075
- if (element.length == 1) {
3994
+ else if (Array.isArray(element)) {
3995
+ if (element.length === 1) {
3076
3996
  this.initial = element[0].cloneNode(true);
3077
3997
  this.node = element[0];
3078
3998
  } else {
@@ -3086,13 +4006,13 @@ class NodeRef {
3086
4006
 
3087
4007
  /** @returns {Element} */
3088
4008
  get element() {
3089
- assertArg$1(this._element, "element");
4009
+ assertArg(this._element, "element");
3090
4010
  return this._element;
3091
4011
  }
3092
4012
 
3093
4013
  /** @param {Element} el */
3094
4014
  set element(el) {
3095
- assertArg$1(el instanceof Element, "element");
4015
+ assertArg(el instanceof Element, "element");
3096
4016
  this._element = el;
3097
4017
  this._nodes = undefined;
3098
4018
  this.isList = false;
@@ -3100,13 +4020,13 @@ class NodeRef {
3100
4020
 
3101
4021
  /** @returns {Node | ChildNode} */
3102
4022
  get node() {
3103
- assertArg$1(this._node || this._element, "node");
4023
+ assertArg(this._node || this._element, "node");
3104
4024
  return this._node || this._element;
3105
4025
  }
3106
4026
 
3107
4027
  /** @param {Node | ChildNode} node */
3108
4028
  set node(node) {
3109
- assertArg$1(node instanceof Node, "node");
4029
+ assertArg(node instanceof Node, "node");
3110
4030
  this._node = node;
3111
4031
  if (node.nodeType === Node.ELEMENT_NODE) {
3112
4032
  this._element = /** @type {Element} */ (node);
@@ -3117,7 +4037,7 @@ class NodeRef {
3117
4037
 
3118
4038
  /** @param {Array<Node>} nodes */
3119
4039
  set nodes(nodes) {
3120
- assertArg$1(
4040
+ assertArg(
3121
4041
  Array.isArray(nodes) && nodes.every((n) => n instanceof Node),
3122
4042
  "nodes",
3123
4043
  );
@@ -3127,25 +4047,18 @@ class NodeRef {
3127
4047
 
3128
4048
  /** @returns {Array<Node>} */
3129
4049
  get nodes() {
3130
- assertArg$1(this._nodes, "nodes");
4050
+ assertArg(this._nodes, "nodes");
3131
4051
  return this._nodes;
3132
4052
  }
3133
4053
 
3134
4054
  /** @returns {NodeList|Node[]} */
3135
4055
  get nodelist() {
3136
- assertArg$1(this.isList, "nodes");
3137
- if (this._nodes.length === 0) {
3138
- return this._nodes;
3139
- }
3140
- if (this._nodes[0].parentElement) {
4056
+ if (this._nodes.length === 0) return [];
4057
+ if (this._nodes[0].parentElement)
3141
4058
  return this._nodes[0].parentElement.childNodes;
3142
- } else {
3143
- const fragment = document.createDocumentFragment();
3144
- this._nodes.forEach((el) => {
3145
- fragment.appendChild(el);
3146
- });
3147
- return fragment.childNodes;
3148
- }
4059
+ const fragment = document.createDocumentFragment();
4060
+ this._nodes.forEach((el) => fragment.appendChild(el));
4061
+ return fragment.childNodes;
3149
4062
  }
3150
4063
 
3151
4064
  /** @returns {Element | Node | ChildNode | NodeList | Node[]} */
@@ -3203,8 +4116,8 @@ class NodeRef {
3203
4116
  * @param {Element | Node | ChildNode} node
3204
4117
  */
3205
4118
  setIndex(index, node) {
3206
- assertArg$1(index !== null, "index");
3207
- assertArg$1(node, "node");
4119
+ assertArg(index !== null, "index");
4120
+ assertArg(node, "node");
3208
4121
  if (this.isList) {
3209
4122
  this._nodes[index] = node;
3210
4123
  } else {
@@ -3290,7 +4203,7 @@ class ControllerProvider {
3290
4203
  "$injector",
3291
4204
 
3292
4205
  /**
3293
- * @param {import("../../core/di/internal-injector.js").InjectorService} $injector
4206
+ * @param {ng.InjectorService} $injector
3294
4207
  * @returns {import("./interface.ts").ControllerService} A service function that creates controllers.
3295
4208
  */
3296
4209
  ($injector) => {
@@ -3343,6 +4256,10 @@ class ControllerProvider {
3343
4256
  );
3344
4257
  }
3345
4258
 
4259
+ if (instance?.constructor?.$scopename) {
4260
+ locals.$scope.$scopename = instance.constructor.$scopename;
4261
+ }
4262
+
3346
4263
  return function () {
3347
4264
  const result = $injector.invoke(
3348
4265
  expression,
@@ -3605,7 +4522,7 @@ function adjustMatcher(matcher) {
3605
4522
  * `$sceDelegate` is a service that is used by the `$sce` service to provide {@link ng.$sce Strict
3606
4523
  * Contextual Escaping (SCE)} services to AngularTS.
3607
4524
  *
3608
- * 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
3609
4526
  * page for {@link ng.$sce SCE}. The current page is targeted for developers who need to alter how
3610
4527
  * SCE works in their application, which shouldn't be needed in most cases.
3611
4528
  *
@@ -3632,85 +4549,6 @@ function adjustMatcher(matcher) {
3632
4549
  * ng.$sceDelegateProvider#bannedResourceUrlList $sceDelegateProvider.bannedResourceUrlList}
3633
4550
  */
3634
4551
 
3635
- /**
3636
- *
3637
- * The `$sceDelegateProvider` provider allows developers to configure the {@link ng.$sceDelegate
3638
- * $sceDelegate service}, used as a delegate for {@link ng.$sce Strict Contextual Escaping (SCE)}.
3639
- *
3640
- * The `$sceDelegateProvider` allows one to get/set the `trustedResourceUrlList` and
3641
- * `bannedResourceUrlList` used to ensure that the URLs used for sourcing AngularTS templates and
3642
- * other script-running URLs are safe (all places that use the `$sce.RESOURCE_URL` context). See
3643
- * {@link ng.$sceDelegateProvider#trustedResourceUrlList
3644
- * $sceDelegateProvider.trustedResourceUrlList} and
3645
- * {@link ng.$sceDelegateProvider#bannedResourceUrlList $sceDelegateProvider.bannedResourceUrlList},
3646
- *
3647
- * For the general details about this service in AngularTS, read the main page for {@link ng.$sce
3648
- * Strict Contextual Escaping (SCE)}.
3649
- *
3650
- * **Example**: Consider the following case. <a name="example"></a>
3651
- *
3652
- * - your app is hosted at url `http://myapp.example.com/`
3653
- * - but some of your templates are hosted on other domains you control such as
3654
- * `http://srv01.assets.example.com/`, `http://srv02.assets.example.com/`, etc.
3655
- * - and you have an open redirect at `http://myapp.example.com/clickThru?...`.
3656
- *
3657
- * Here is what a secure configuration for this scenario might look like:
3658
- *
3659
- * ```
3660
- * angular.module('myApp', []).config(function($sceDelegateProvider) {
3661
- * $sceDelegateProvider.trustedResourceUrlList([
3662
- * // Allow same origin resource loads.
3663
- * 'self',
3664
- * // Allow loading from our assets domain. Notice the difference between * and **.
3665
- * 'http://srv*.assets.example.com/**'
3666
- * ]);
3667
- *
3668
- * // The banned resource URL list overrides the trusted resource URL list so the open redirect
3669
- * // here is blocked.
3670
- * $sceDelegateProvider.bannedResourceUrlList([
3671
- * 'http://myapp.example.com/clickThru**'
3672
- * ]);
3673
- * });
3674
- * ```
3675
- * Note that an empty trusted resource URL list will block every resource URL from being loaded, and will require
3676
- * you to manually mark each one as trusted with `$sce.trustAsResourceUrl`. However, templates
3677
- * requested by {@link ng.$templateRequest $templateRequest} that are present in
3678
- * {@link ng.$templateCache $templateCache} will not go through this check. If you have a mechanism
3679
- * to populate your templates in that cache at config time, then it is a good idea to remove 'self'
3680
- * from the trusted resource URL lsit. This helps to mitigate the security impact of certain types
3681
- * of issues, like for instance attacker-controlled `ng-includes`.
3682
- */
3683
-
3684
- /**
3685
- * `$sceDelegate` is a service that is used by the `$sce` service to provide {@link ng.$sce Strict
3686
- * Contextual Escaping (SCE)} services to AngularTS.
3687
- *
3688
- * For an overview of this service and the functionnality it provides in AngularTS, see the main
3689
- * page for {@link ng.$sce SCE}. The current page is targeted for developers who need to alter how
3690
- * SCE works in their application, which shouldn't be needed in most cases.
3691
- *
3692
- * <div class="alert alert-danger">
3693
- * AngularTS strongly relies on contextual escaping for the security of bindings: disabling or
3694
- * modifying this might cause cross site scripting (XSS) vulnerabilities. For libraries owners,
3695
- * changes to this service will also influence users, so be extra careful and document your changes.
3696
- * </div>
3697
- *
3698
- * Typically, you would configure or override the {@link ng.$sceDelegate $sceDelegate} instead of
3699
- * the `$sce` service to customize the way Strict Contextual Escaping works in AngularTS. This is
3700
- * because, while the `$sce` provides numerous shorthand methods, etc., you really only need to
3701
- * override 3 core functions (`trustAs`, `getTrusted` and `valueOf`) to replace the way things
3702
- * work because `$sce` delegates to `$sceDelegate` for these operations.
3703
- *
3704
- * Refer {@link ng.$sceDelegateProvider $sceDelegateProvider} to configure this service.
3705
- *
3706
- * The default instance of `$sceDelegate` should work out of the box with little pain. While you
3707
- * can override it completely to change the behavior of `$sce`, the common case would
3708
- * involve configuring the {@link ng.$sceDelegateProvider $sceDelegateProvider} instead by setting
3709
- * your own trusted and banned resource lists for trusting URLs used for loading AngularTS resources
3710
- * such as templates. Refer {@link ng.$sceDelegateProvider#trustedResourceUrlList
3711
- * $sceDelegateProvider.trustedResourceUrlList} and {@link
3712
- * ng.$sceDelegateProvider#bannedResourceUrlList $sceDelegateProvider.bannedResourceUrlList}
3713
- */
3714
4552
  /**
3715
4553
  *
3716
4554
  * The `$sceDelegateProvider` provider allows developers to configure the {@link ng.$sceDelegate
@@ -3767,7 +4605,7 @@ class SceDelegateProvider {
3767
4605
 
3768
4606
  /**
3769
4607
  *
3770
- * @param {Array=} trustedResourceUrlList When provided, replaces the trustedResourceUrlList with
4608
+ * @param {Array=} value When provided, replaces the trustedResourceUrlList with
3771
4609
  * the value provided. This must be an array or null. A snapshot of this array is used so
3772
4610
  * further changes to the array are ignored.
3773
4611
  * Follow {@link ng.$sce#resourceUrlPatternItem this link} for a description of the items
@@ -3829,7 +4667,7 @@ class SceDelegateProvider {
3829
4667
  /**
3830
4668
  *
3831
4669
  * @param {ng.InjectorService} $injector
3832
- * @param {*} $$sanitizeUri
4670
+ * @param {import("../../core/sanitize/interface.ts").SanitizerFn} $$sanitizeUri
3833
4671
  * @param {ng.ExceptionHandlerService} $exceptionHandler
3834
4672
  * @returns
3835
4673
  */
@@ -4351,7 +5189,7 @@ function SceProvider() {
4351
5189
  const { trustAs } = sce;
4352
5190
 
4353
5191
  Object.entries(SCE_CONTEXTS).forEach(([name, enumValue]) => {
4354
- const lName = lowercase(name);
5192
+ const lName = name.toLowerCase();
4355
5193
  sce[snakeToCamel(`parse_as_${lName}`)] = function (expr) {
4356
5194
  return parse(enumValue, expr);
4357
5195
  };
@@ -4485,8 +5323,8 @@ class Attributes {
4485
5323
  static $nonscope = true;
4486
5324
 
4487
5325
  /**
4488
- * @param {ng.Scope} $rootScope
4489
- * @param {*} $animate
5326
+ * @param {ng.RootScopeService} $rootScope
5327
+ * @param {ng.AnimateService} $animate
4490
5328
  * @param {ng.ExceptionHandlerService} $exceptionHandler
4491
5329
  * @param {*} $sce
4492
5330
  * @param {import("../../shared/noderef.js").NodeRef} [nodeRef]
@@ -4544,7 +5382,10 @@ class Attributes {
4544
5382
  $addClass(classVal) {
4545
5383
  if (classVal && classVal.length > 0) {
4546
5384
  if (hasAnimate(this.$$element)) {
4547
- this.$animate.addClass(this.$$element, classVal);
5385
+ this.$animate.addClass(
5386
+ /** @type {Element} */ (this.$$element),
5387
+ classVal,
5388
+ );
4548
5389
  } else {
4549
5390
  this.$nodeRef.element.classList.add(classVal);
4550
5391
  }
@@ -4560,7 +5401,10 @@ class Attributes {
4560
5401
  $removeClass(classVal) {
4561
5402
  if (classVal && classVal.length > 0) {
4562
5403
  if (hasAnimate(this.$$element)) {
4563
- this.$animate.removeClass(this.$$element, classVal);
5404
+ this.$animate.removeClass(
5405
+ /** @type {Element} */ (this.$$element),
5406
+ classVal,
5407
+ );
4564
5408
  } else {
4565
5409
  this.$nodeRef.element.classList.remove(classVal);
4566
5410
  }
@@ -4578,7 +5422,7 @@ class Attributes {
4578
5422
  const toAdd = tokenDifference(newClasses, oldClasses);
4579
5423
  if (toAdd && toAdd.length) {
4580
5424
  if (hasAnimate(this.$$element)) {
4581
- this.$animate.addClass(this.$$element, toAdd);
5425
+ this.$animate.addClass(/** @type {Element }*/ (this.$$element), toAdd);
4582
5426
  } else {
4583
5427
  this.$nodeRef.element.classList.add(...toAdd.trim().split(/\s+/));
4584
5428
  }
@@ -4586,7 +5430,10 @@ class Attributes {
4586
5430
  const toRemove = tokenDifference(oldClasses, newClasses);
4587
5431
  if (toRemove && toRemove.length) {
4588
5432
  if (hasAnimate(this.$$element)) {
4589
- this.$animate.removeClass(this.$$element, toRemove);
5433
+ this.$animate.removeClass(
5434
+ /** @type {Element }*/ (this.$$element),
5435
+ toRemove,
5436
+ );
4590
5437
  } else {
4591
5438
  this.$nodeRef.element.classList.remove(...toRemove.trim().split(/\s+/));
4592
5439
  }
@@ -4777,7 +5624,8 @@ class Attributes {
4777
5624
  if (lastTuple.length === 2) {
4778
5625
  result += " " + trim(lastTuple[1]);
4779
5626
  }
4780
- return result;
5627
+
5628
+ return result.replace(/unsafe:unsafe/g, "unsafe");
4781
5629
  }
4782
5630
  }
4783
5631
 
@@ -4986,11 +5834,11 @@ class CompileProvider {
4986
5834
  * @returns {CompileProvider} Self for chaining.
4987
5835
  */
4988
5836
  this.directive = function registerDirective(name, directiveFactory) {
4989
- assertArg$1(name, "name");
5837
+ assertArg(name, "name");
4990
5838
  assertNotHasOwnProperty(name, "directive");
4991
5839
  if (isString(name)) {
4992
5840
  assertValidDirectiveName(name);
4993
- assertArg$1(directiveFactory, "directiveFactory");
5841
+ assertArg(directiveFactory, "directiveFactory");
4994
5842
  if (!hasOwn(hasDirectives, name)) {
4995
5843
  hasDirectives[name] = [];
4996
5844
  $provide.factory(name + DirectiveSuffix, [
@@ -5324,15 +6172,15 @@ class CompileProvider {
5324
6172
  "$sce",
5325
6173
  "$animate",
5326
6174
  /**
5327
- * @param {import("../../core/di/internal-injector.js").InjectorService} $injector
6175
+ * @param {ng.InjectorService} $injector
5328
6176
  * @param {*} $interpolate
5329
6177
  * @param {import("../../services/exception/exception-handler.js").ErrorHandler} $exceptionHandler
5330
- * @param {*} $templateRequest
5331
- * @param {import("../parse/interface.ts").ParseService} $parse
6178
+ * @param {ng.TemplateRequestService} $templateRequest
6179
+ * @param {ng.ParseService} $parse
5332
6180
  * @param {*} $controller
5333
6181
  * @param {import('../scope/scope.js').Scope} $rootScope
5334
6182
  * @param {*} $sce
5335
- * @param {*} $animate
6183
+ * @param {ng.AnimateService} $animate
5336
6184
  * @returns
5337
6185
  */
5338
6186
  function (
@@ -5411,7 +6259,7 @@ class CompileProvider {
5411
6259
  );
5412
6260
  }
5413
6261
 
5414
- assertArg$1(scope, "scope");
6262
+ assertArg(scope, "scope");
5415
6263
  // could be empty nodelist
5416
6264
  if (nodeRef.getAny()) {
5417
6265
  setScope(nodeRef.getAny(), scope);
@@ -5474,7 +6322,7 @@ class CompileProvider {
5474
6322
 
5475
6323
  if (transcludeControllers) {
5476
6324
  for (const controllerName in transcludeControllers) {
5477
- assertArg$1($linkNode.element, "element");
6325
+ assertArg($linkNode.element, "element");
5478
6326
  setCacheData(
5479
6327
  $linkNode.element,
5480
6328
  `$${controllerName}Controller`,
@@ -5622,7 +6470,7 @@ class CompileProvider {
5622
6470
  * @param {*} [parentBoundTranscludeFn]
5623
6471
  */
5624
6472
  function compositeLinkFn(scope, nodeRef, parentBoundTranscludeFn) {
5625
- assertArg$1(nodeRef, "nodeRef");
6473
+ assertArg(nodeRef, "nodeRef");
5626
6474
  let stableNodeList = [];
5627
6475
  if (nodeLinkFnFound) {
5628
6476
  // create a stable copy of the nodeList, only copying elements with linkFns
@@ -7029,11 +7877,19 @@ class CompileProvider {
7029
7877
  replace: null,
7030
7878
  $$originalDirective: origAsyncDirective,
7031
7879
  });
7032
- const templateUrl = isFunction(origAsyncDirective.templateUrl)
7033
- ? /** @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) } */ (
7034
7886
  origAsyncDirective.templateUrl
7035
- )($compileNode.element, tAttrs)
7036
- : origAsyncDirective.templateUrl;
7887
+ )($compileNode.element, tAttrs);
7888
+ } else {
7889
+ templateUrl = /** @type {string} */ (
7890
+ origAsyncDirective.templateUrl
7891
+ );
7892
+ }
7037
7893
  const { templateNamespace } = origAsyncDirective;
7038
7894
 
7039
7895
  emptyElement($compileNode.element);
@@ -7554,14 +8410,23 @@ class CompileProvider {
7554
8410
  attr.$$element.classList.value,
7555
8411
  );
7556
8412
  } else {
7557
- attr.$set(name, newValue);
8413
+ attr.$set(
8414
+ name,
8415
+ name === "srcset"
8416
+ ? $sce.getTrustedMediaUrl(newValue)
8417
+ : newValue,
8418
+ );
7558
8419
  }
7559
8420
  });
7560
8421
  });
7561
8422
 
7562
8423
  if (interpolateFn.expressions.length == 0) {
7563
- // if there is nothing to watch, its a constant
7564
- attr.$set(name, newValue);
8424
+ attr.$set(
8425
+ name,
8426
+ name === "srcset"
8427
+ ? $sce.getTrustedMediaUrl(newValue)
8428
+ : newValue,
8429
+ );
7565
8430
  }
7566
8431
  },
7567
8432
  };
@@ -7970,7 +8835,7 @@ function removeComments(jqNodes) {
7970
8835
  */
7971
8836
  function assertValidDirectiveName(name) {
7972
8837
  const letter = name.charAt(0);
7973
- if (!letter || letter !== lowercase(letter)) {
8838
+ if (!letter || letter !== letter.toLowerCase()) {
7974
8839
  throw $compileMinErr(
7975
8840
  "baddir",
7976
8841
  "Directive/Component name '{0}' is invalid. The first character must be a lowercase letter",
@@ -8076,9 +8941,9 @@ class FormController {
8076
8941
 
8077
8942
  /**
8078
8943
  * @param {Element} $element
8079
- * @param {import("../../core/compile/attributes.js").Attributes} $attrs
8080
- * @param {import("../../core/scope/scope.js").Scope} $scope
8081
- * @param {*} $animate
8944
+ * @param {ng.Attributes} $attrs
8945
+ * @param {ng.Scope} $scope
8946
+ * @param {ng.AnimateService} $animate
8082
8947
  * @param {*} $interpolate
8083
8948
  */
8084
8949
  constructor($element, $attrs, $scope, $animate, $interpolate) {
@@ -8844,7 +9709,7 @@ class NgModelController {
8844
9709
  * @param {import('../../core/compile/attributes.js').Attributes} $attr
8845
9710
  * @param {Element} $element
8846
9711
  * @param {import("../../core/parse/interface.ts").ParseService} $parse
8847
- * @param {*} $animate
9712
+ * @param {ng.AnimateService} $animate
8848
9713
  * @param {*} $interpolate
8849
9714
  */
8850
9715
  constructor(
@@ -10868,9 +11733,9 @@ function checkboxInputType(scope, element, attr, ctrl, $filter, $parse) {
10868
11733
  inputDirective.$inject = ["$filter", "$parse"];
10869
11734
 
10870
11735
  /**
10871
- * @param {*} $filter
10872
- * @param {*} $parse
10873
- * @returns {import('../../interface.ts').Directive}
11736
+ * @param {ng.FilterService} $filter
11737
+ * @param {ng.ParseService} $parse
11738
+ * @returns {ng.Directive}
10874
11739
  */
10875
11740
  function inputDirective($filter, $parse) {
10876
11741
  return {
@@ -10879,7 +11744,7 @@ function inputDirective($filter, $parse) {
10879
11744
  link: {
10880
11745
  pre(scope, element, attr, ctrls) {
10881
11746
  if (ctrls[0]) {
10882
- (inputType[lowercase(attr["type"])] || inputType.text)(
11747
+ (inputType[attr.type?.toLowerCase()] || inputType.text)(
10883
11748
  scope,
10884
11749
  element,
10885
11750
  attr,
@@ -10894,7 +11759,7 @@ function inputDirective($filter, $parse) {
10894
11759
  }
10895
11760
 
10896
11761
  /**
10897
- * @returns {import('../../interface.ts').Directive}
11762
+ * @returns {ng.Directive}
10898
11763
  */
10899
11764
  function hiddenInputBrowserCacheDirective() {
10900
11765
  const valueProperty = {
@@ -10912,7 +11777,7 @@ function hiddenInputBrowserCacheDirective() {
10912
11777
  restrict: "E",
10913
11778
  priority: 200,
10914
11779
  compile(_, attr) {
10915
- if (lowercase(attr["type"]) !== "hidden") {
11780
+ if (attr.type?.toLowerCase() !== "hidden") {
10916
11781
  return;
10917
11782
  }
10918
11783
 
@@ -10940,7 +11805,7 @@ function hiddenInputBrowserCacheDirective() {
10940
11805
  const CONSTANT_VALUE_REGEXP = /^(true|false|\d+)$/;
10941
11806
 
10942
11807
  /**
10943
- * @returns {import('../../interface.ts').Directive}
11808
+ * @returns {ng.Directive}
10944
11809
  */
10945
11810
  function ngValueDirective() {
10946
11811
  /**
@@ -10964,15 +11829,15 @@ function ngValueDirective() {
10964
11829
  return {
10965
11830
  restrict: "A",
10966
11831
  priority: 100,
10967
- compile(tpl, tplAttr) {
10968
- if (CONSTANT_VALUE_REGEXP.test(tplAttr["ngValue"])) {
10969
- return function ngValueConstantLink(scope, elm, attr) {
10970
- const value = scope.$eval(attr["ngValue"]);
11832
+ compile(_, tplAttr) {
11833
+ if (CONSTANT_VALUE_REGEXP.test(tplAttr.ngValue)) {
11834
+ return function (scope, elm, attr) {
11835
+ const value = scope.$eval(attr.ngValue);
10971
11836
  updateElementValue(elm, attr, value);
10972
11837
  };
10973
11838
  }
10974
- return function ngValueLink(scope, elm, attr) {
10975
- scope.$watch(attr["ngValue"], (value) => {
11839
+ return function (scope, elm, attr) {
11840
+ scope.$watch(attr.ngValue, (value) => {
10976
11841
  updateElementValue(elm, attr, value);
10977
11842
  });
10978
11843
  };
@@ -11653,17 +12518,20 @@ function ngBindHtmlDirective($parse) {
11653
12518
  /**
11654
12519
  * @param {string} name
11655
12520
  * @param {boolean|number} selector
11656
- * @returns {() => import("../../interface.ts").Directive}
12521
+ * @returns {ng.DirectiveFactory}
11657
12522
  */
11658
12523
  function classDirective(name, selector) {
11659
12524
  name = `ngClass${name}`;
11660
12525
 
12526
+ /**
12527
+ * @returns {ng.Directive}
12528
+ */
11661
12529
  return function () {
11662
12530
  return {
11663
12531
  /**
11664
- * @param {import("../../core/scope/scope.js").Scope} scope
11665
- * @param {Element} element
11666
- * @param {import("../../core/compile/attributes").Attributes} attr
12532
+ * @param {ng.Scope} scope
12533
+ * @param {HTMLElement} element
12534
+ * @param {ng.Attributes} attr
11667
12535
  */
11668
12536
  link(scope, element, attr) {
11669
12537
  let classCounts = getCacheData(element, "$classCounts");
@@ -11837,9 +12705,8 @@ const ngClassEvenDirective = classDirective("Even", 1);
11837
12705
  */
11838
12706
  function ngCloakDirective() {
11839
12707
  return {
11840
- compile(element, attr) {
12708
+ compile(_, attr) {
11841
12709
  attr.$set("ngCloak", undefined);
11842
- element.classList.remove("ng-cloak");
11843
12710
  },
11844
12711
  };
11845
12712
  }
@@ -11861,7 +12728,8 @@ const NG_HIDE_IN_PROGRESS_CLASS = "ng-hide-animate";
11861
12728
 
11862
12729
  ngShowDirective.$inject = ["$animate"];
11863
12730
  /**
11864
- * @returns {import('../../interface.ts').Directive}
12731
+ * @param {ng.AnimateService} $animate
12732
+ * @returns {ng.Directive}
11865
12733
  */
11866
12734
  function ngShowDirective($animate) {
11867
12735
  return {
@@ -11872,7 +12740,7 @@ function ngShowDirective($animate) {
11872
12740
  * @param $attr
11873
12741
  */
11874
12742
  link(scope, element, $attr) {
11875
- scope.$watch($attr["ngShow"], (value) => {
12743
+ scope.$watch($attr.ngShow, (value) => {
11876
12744
  // we're adding a temporary, animation-specific class for ng-hide since this way
11877
12745
  // we can control when the element is actually displayed on screen without having
11878
12746
  // to have a global/greedy CSS selector that breaks when other animations are run.
@@ -11922,7 +12790,7 @@ function ngHideDirective($animate) {
11922
12790
 
11923
12791
  ngIfDirective.$inject = ["$animate"];
11924
12792
  /**
11925
- * @param {*} $animate
12793
+ * @param {ng.AnimateService} $animate
11926
12794
  * @returns {ng.Directive}
11927
12795
  */
11928
12796
  function ngIfDirective($animate) {
@@ -11943,7 +12811,7 @@ function ngIfDirective($animate) {
11943
12811
  /** @type {Element} */
11944
12812
  let block;
11945
12813
 
11946
- /** @type {import('../../core/scope/scope.js').Scope} */
12814
+ /** @type {ng.Scope} */
11947
12815
  let childScope;
11948
12816
 
11949
12817
  let previousElements;
@@ -11999,9 +12867,9 @@ ngIncludeDirective.$inject = [
11999
12867
 
12000
12868
  /**
12001
12869
  *
12002
- * @param {*} $templateRequest
12870
+ * @param {ng.TemplateRequestService} $templateRequest
12003
12871
  * @param {import("../../services/anchor-scroll/anchor-scroll.js").AnchorScrollFunction} $anchorScroll
12004
- * @param {*} $animate
12872
+ * @param {ng.AnimateService} $animate
12005
12873
  * @param {import('../../services/exception/interface.ts').ErrorHandler} $exceptionHandler
12006
12874
  * @returns {import('../../interface.ts').Directive}
12007
12875
  */
@@ -12603,8 +13471,8 @@ function ngStyleDirective() {
12603
13471
  ngSwitchDirective.$inject = ["$animate"];
12604
13472
 
12605
13473
  /**
12606
- * @param {*} $animate
12607
- * @returns {import('../../interface.ts').Directive}
13474
+ * @param {ng.AnimateService} $animate
13475
+ * @returns {ng.Directive}
12608
13476
  */
12609
13477
  function ngSwitchDirective($animate) {
12610
13478
  return {
@@ -12620,7 +13488,7 @@ function ngSwitchDirective($animate) {
12620
13488
  },
12621
13489
  ],
12622
13490
  link(scope, _element, attr, ngSwitchController) {
12623
- const watchExpr = attr["ngSwitch"] || attr["on"];
13491
+ const watchExpr = attr.ngSwitch || attr.on;
12624
13492
  let selectedTranscludes = [];
12625
13493
  const selectedElements = [];
12626
13494
  const previousLeaveAnimations = [];
@@ -13093,7 +13961,7 @@ function ngOptionsDirective($compile, $parse) {
13093
13961
  if (providedEmptyOption) {
13094
13962
  // compile the element since there might be bindings in it
13095
13963
  const linkFn = $compile(selectCtrl.emptyOption);
13096
- assertArg$1(linkFn, "LinkFn required");
13964
+ assertArg(linkFn, "LinkFn required");
13097
13965
  selectElement.prepend(selectCtrl.emptyOption);
13098
13966
  linkFn(scope);
13099
13967
 
@@ -13867,7 +14735,7 @@ class AnchorScrollProvider {
13867
14735
 
13868
14736
  if (isFunction(offset)) {
13869
14737
  offset = /** @type {Function} */ (offset)();
13870
- } else if (isElement(offset)) {
14738
+ } else if (offset instanceof Element) {
13871
14739
  const elem = offset[0];
13872
14740
  const style = window.getComputedStyle(elem);
13873
14741
  if (style.position !== "fixed") {
@@ -13958,27 +14826,8 @@ class AnchorScrollProvider {
13958
14826
  ];
13959
14827
  }
13960
14828
 
13961
- /** @typedef {"enter"|"leave"|"move"|"addClass"|"setClass"|"removeClass"} AnimationMethod */
13962
-
13963
- /**
13964
- * @typedef {Object} AnimationOptions
13965
- * @property {string} addClass - space-separated CSS classes to add to element
13966
- * @property {Object} from - CSS properties & values at the beginning of animation. Must have matching `to`
13967
- * @property {string} removeClass - space-separated CSS classes to remove from element
13968
- * @property {string} to - CSS properties & values at end of animation. Must have matching `from`
13969
- */
13970
-
13971
14829
  const $animateMinErr = minErr("$animate");
13972
14830
 
13973
- function mergeClasses(a, b) {
13974
- if (!a && !b) return "";
13975
- if (!a) return b;
13976
- if (!b) return a;
13977
- if (Array.isArray(a)) a = a.join(" ");
13978
- if (Array.isArray(b)) b = b.join(" ");
13979
- return `${a} ${b}`;
13980
- }
13981
-
13982
14831
  // if any other type of options value besides an Object value is
13983
14832
  // passed into the $animate.method() animation then this helper code
13984
14833
  // will be run which will ignore it. While this patch is not the
@@ -13992,7 +14841,7 @@ function prepareAnimateOptions(options) {
13992
14841
 
13993
14842
  AnimateProvider.$inject = ["$provide"];
13994
14843
 
13995
- /** @param {import('../interface.ts').Provider} $provide */
14844
+ /** @param {ng.ProvideService} $provide */
13996
14845
  function AnimateProvider($provide) {
13997
14846
  const provider = this;
13998
14847
  let classNameFilter = null;
@@ -14126,7 +14975,11 @@ function AnimateProvider($provide) {
14126
14975
  };
14127
14976
 
14128
14977
  this.$get = [
14129
- "$$animateQueue",
14978
+ $injectTokens.$$animateQueue,
14979
+ /**
14980
+ * @param {import("./queue/interface.ts").AnimateQueueService} $$animateQueue
14981
+ * @returns {ng.AnimateService}
14982
+ */
14130
14983
  function ($$animateQueue) {
14131
14984
  /**
14132
14985
  * The $animate service exposes a series of DOM utility methods that provide support
@@ -14260,77 +15113,21 @@ function AnimateProvider($provide) {
14260
15113
  *
14261
15114
  * @return {boolean} whether or not animations are enabled
14262
15115
  */
14263
- enabled: $$animateQueue.enabled,
15116
+ enabled: (element, enabled) => {
15117
+ if (enabled !== undefined) {
15118
+ return hasAnimate(element);
15119
+ } else {
15120
+ element.setAttribute("animate", `${enabled}`);
15121
+ }
15122
+ },
14264
15123
 
14265
15124
  /**
14266
- * Cancels the provided animation and applies the end state of the animation.
14267
- * Note that this does not cancel the underlying operation, e.g. the setting of classes or
14268
- * adding the element to the DOM.
14269
- *
14270
- * @param {import('./animate-runner.js').AnimateRunner} runner An animation runner returned by an $animate function.
14271
- *
14272
- * @example
14273
- <example module="animationExample" deps="angular-animate.js" animations="true" name="animate-cancel">
14274
- <file name="app.js">
14275
- angular.module('animationExample', []).component('cancelExample', {
14276
- templateUrl: 'template.html',
14277
- controller: function($element, $animate) {
14278
- this.runner = null;
14279
-
14280
- this.addClass = function() {
14281
- this.runner = $animate.addClass($element.querySelectorAll('div'), 'red');
14282
- let ctrl = this;
14283
- this.runner.finally(function() {
14284
- ctrl.runner = null;
14285
- });
14286
- };
14287
-
14288
- this.removeClass = function() {
14289
- this.runner = $animate.removeClass($element.querySelectorAll('div'), 'red');
14290
- let ctrl = this;
14291
- this.runner.finally(function() {
14292
- ctrl.runner = null;
14293
- });
14294
- };
14295
-
14296
- this.cancel = function() {
14297
- $animate.cancel(this.runner);
14298
- };
14299
- }
14300
- });
14301
- </file>
14302
- <file name="template.html">
14303
- <p>
14304
- <button id="add" ng-click="$ctrl.addClass()">Add</button>
14305
- <button ng-click="$ctrl.removeClass()">Remove</button>
14306
- <br>
14307
- <button id="cancel" ng-click="$ctrl.cancel()" ng-disabled="!$ctrl.runner">Cancel</button>
14308
- <br>
14309
- <div id="target">CSS-Animated Text</div>
14310
- </p>
14311
- </file>
14312
- <file name="index.html">
14313
- <cancel-example></cancel-example>
14314
- </file>
14315
- <file name="style.css">
14316
- .red-add, .red-remove {
14317
- transition: all 4s cubic-bezier(0.250, 0.460, 0.450, 0.940);
14318
- }
14319
-
14320
- .red,
14321
- .red-add.red-add-active {
14322
- color: #FF0000;
14323
- font-size: 40px;
14324
- }
14325
-
14326
- .red-remove.red-remove-active {
14327
- font-size: 10px;
14328
- color: black;
14329
- }
14330
-
14331
- </file>
14332
- </example>
14333
- */
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
+ */
14334
15131
  cancel(runner) {
14335
15132
  if (runner.cancel) {
14336
15133
  runner.cancel();
@@ -14346,12 +15143,12 @@ function AnimateProvider($provide) {
14346
15143
  * @param {Element} element - the element which will be inserted into the DOM
14347
15144
  * @param {Element} parent - the parent element which will append the element as a child (so long as the after element is not present)
14348
15145
  * @param {Element} [after] - after the sibling element after which the element will be appended
14349
- * @param {AnimationOptions} [options] - an optional collection of options/styles that will be applied to the element.
14350
- * @returns {import('./animate-runner.js').AnimateRunner} the animation runner
15146
+ * @param {import("./interface.ts").AnimationOptions} [options] - an optional collection of options/styles that will be applied to the element.
15147
+ * @returns {import('./runner/animate-runner.js').AnimateRunner} the animation runner
14351
15148
  */
14352
15149
  enter(element, parent, after, options) {
14353
15150
  parent = parent || after.parentElement;
14354
- domInsert(element, parent, after);
15151
+ animatedomInsert(element, parent, after);
14355
15152
  return $$animateQueue.push(
14356
15153
  element,
14357
15154
  "enter",
@@ -14368,12 +15165,12 @@ function AnimateProvider($provide) {
14368
15165
  * @param {Element} element - the element which will be inserted into the DOM
14369
15166
  * @param {Element} parent - the parent element which will append the element as a child (so long as the after element is not present)
14370
15167
  * @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.
14372
- * @returns {import('./animate-runner.js').AnimateRunner} the animation runner
15168
+ * @param {import("./interface.ts").AnimationOptions} [options] - an optional collection of options/styles that will be applied to the element.
15169
+ * @returns {import('./runner/animate-runner.js').AnimateRunner} the animation runner
14373
15170
  */
14374
15171
  move(element, parent, after, options) {
14375
15172
  parent = parent || after.parentElement;
14376
- domInsert(element, parent, after);
15173
+ animatedomInsert(element, parent, after);
14377
15174
  return $$animateQueue.push(
14378
15175
  element,
14379
15176
  "move",
@@ -14387,8 +15184,8 @@ function AnimateProvider($provide) {
14387
15184
  * digest once the animation has completed.
14388
15185
  *
14389
15186
  * @param {Element} element the element which will be removed from the DOM
14390
- * @param {AnimationOptions} [options] an optional collection of options/styles that will be applied to the element.
14391
- * @returns {import('./animate-runner.js').AnimateRunner} the animation runner
15187
+ * @param {import("./interface.ts").AnimationOptions} [options] an optional collection of options/styles that will be applied to the element.
15188
+ * @returns {import('./runner/animate-runner.js').AnimateRunner} the animation runner
14392
15189
  */
14393
15190
  leave(element, options) {
14394
15191
  return $$animateQueue.push(
@@ -14416,8 +15213,8 @@ function AnimateProvider($provide) {
14416
15213
  *
14417
15214
  * @param {Element} element the element which the CSS classes will be applied to
14418
15215
  * @param {string} className the CSS class(es) that will be added (multiple classes are separated via spaces)
14419
- * @param {AnimationOptions} [options] an optional collection of options/styles that will be applied to the element.
14420
- * @return {import('./animate-runner.js').AnimateRunner}} animationRunner the animation runner
15216
+ * @param {import("./interface").AnimationOptions} [options] an optional collection of options/styles that will be applied to the element.
15217
+ * @return {import('./runner/animate-runner.js').AnimateRunner}} animationRunner the animation runner
14421
15218
  */
14422
15219
  addClass(element, className, options) {
14423
15220
  options = prepareAnimateOptions(options);
@@ -14435,8 +15232,8 @@ function AnimateProvider($provide) {
14435
15232
  *
14436
15233
  * @param {Element} element the element which the CSS classes will be applied to
14437
15234
  * @param {string} className the CSS class(es) that will be removed (multiple classes are separated via spaces)
14438
- * @param {AnimationOptions} [options] an optional collection of options/styles that will be applied to the element. *
14439
- * @return {import('./animate-runner.js').AnimateRunner} animationRunner the animation runner
15235
+ * @param {import("./interface").AnimationOptions} [options] an optional collection of options/styles that will be applied to the element. *
15236
+ * @return {import('./runner/animate-runner.js').AnimateRunner} animationRunner the animation runner
14440
15237
  */
14441
15238
  removeClass(element, className, options) {
14442
15239
  options = prepareAnimateOptions(options);
@@ -14457,7 +15254,7 @@ function AnimateProvider($provide) {
14457
15254
  * @param {string} remove the CSS class(es) that will be removed (multiple classes are separated via spaces)
14458
15255
  * @param {object=} options an optional collection of options/styles that will be applied to the element.
14459
15256
  *
14460
- * @return {import('./animate-runner.js').AnimateRunner} the animation runner
15257
+ * @return {import('./runner/animate-runner.js').AnimateRunner} the animation runner
14461
15258
  */
14462
15259
  setClass(element, add, remove, options) {
14463
15260
  options = prepareAnimateOptions(options);
@@ -14485,7 +15282,7 @@ function AnimateProvider($provide) {
14485
15282
  * }
14486
15283
  * });
14487
15284
  * ```
14488
- * @return {import('./animate-runner.js').AnimateRunner} the animation runner
15285
+ * @return {import('./runner/animate-runner.js').AnimateRunner} the animation runner
14489
15286
  */
14490
15287
  animate(element, from, to, className, options) {
14491
15288
  options = prepareAnimateOptions(options);
@@ -14501,200 +15298,6 @@ function AnimateProvider($provide) {
14501
15298
  ];
14502
15299
  }
14503
15300
 
14504
- function AnimateAsyncRunFactoryProvider() {
14505
- this.$get = [
14506
- function () {
14507
- let waitQueue = [];
14508
-
14509
- function waitForTick(fn) {
14510
- waitQueue.push(fn);
14511
- if (waitQueue.length > 1) return;
14512
- window.requestAnimationFrame(function () {
14513
- for (let i = 0; i < waitQueue.length; i++) {
14514
- waitQueue[i]();
14515
- }
14516
- waitQueue = [];
14517
- });
14518
- }
14519
-
14520
- return function () {
14521
- let passed = false;
14522
- waitForTick(function () {
14523
- passed = true;
14524
- });
14525
- return function (callback) {
14526
- if (passed) {
14527
- callback();
14528
- } else {
14529
- waitForTick(callback);
14530
- }
14531
- };
14532
- };
14533
- },
14534
- ];
14535
- }
14536
-
14537
- const INITIAL_STATE = 0;
14538
- const DONE_PENDING_STATE = 1;
14539
- const DONE_COMPLETE_STATE = 2;
14540
- let $$animateAsyncRun;
14541
-
14542
- function AnimateRunnerFactoryProvider() {
14543
- this.$get = [
14544
- "$$animateAsyncRun",
14545
- function (animateAsyncRun) {
14546
- $$animateAsyncRun = animateAsyncRun;
14547
- return AnimateRunner;
14548
- },
14549
- ];
14550
- }
14551
-
14552
- class AnimateRunner {
14553
- static chain(chain, callback) {
14554
- let index = 0;
14555
-
14556
- function next() {
14557
- if (index === chain.length) {
14558
- callback(true);
14559
- return;
14560
- }
14561
-
14562
- chain[index]((response) => {
14563
- if (response === false) {
14564
- callback(false);
14565
- return;
14566
- }
14567
- index++;
14568
- next();
14569
- });
14570
- }
14571
-
14572
- next();
14573
- }
14574
-
14575
- static all(runners, callback) {
14576
- let count = 0;
14577
- let status = true;
14578
-
14579
- runners.forEach((runner) => {
14580
- runner.done(onProgress);
14581
- });
14582
-
14583
- function onProgress(response) {
14584
- status = status && response;
14585
- if (++count === runners.length) {
14586
- callback(status);
14587
- }
14588
- }
14589
- }
14590
-
14591
- constructor(host) {
14592
- this.setHost(host);
14593
-
14594
- const rafTick = $$animateAsyncRun();
14595
- const timeoutTick = (fn) => {
14596
- setTimeout(fn, 0, false);
14597
- };
14598
-
14599
- this._doneCallbacks = [];
14600
- this._tick = (fn) => {
14601
- if (document.hidden) {
14602
- timeoutTick(fn);
14603
- } else {
14604
- rafTick(fn);
14605
- }
14606
- };
14607
- this._state = 0;
14608
- }
14609
-
14610
- setHost(host) {
14611
- this.host = host || {};
14612
- }
14613
-
14614
- done(fn) {
14615
- if (this._state === DONE_COMPLETE_STATE) {
14616
- fn();
14617
- } else {
14618
- this._doneCallbacks.push(fn);
14619
- }
14620
- }
14621
-
14622
- progress() {}
14623
-
14624
- getPromise() {
14625
- if (!this.promise) {
14626
- const self = this;
14627
- this.promise = new Promise((resolve, reject) => {
14628
- self.done((status) => {
14629
- if (status === false) {
14630
- reject();
14631
- } else {
14632
- resolve();
14633
- }
14634
- });
14635
- });
14636
- }
14637
- return this.promise;
14638
- }
14639
-
14640
- then(resolveHandler, rejectHandler) {
14641
- return this.getPromise().then(resolveHandler, rejectHandler);
14642
- }
14643
-
14644
- catch(handler) {
14645
- return this.getPromise().catch(handler);
14646
- }
14647
-
14648
- finally(handler) {
14649
- return this.getPromise().finally(handler);
14650
- }
14651
-
14652
- pause() {
14653
- if (this.host.pause) {
14654
- this.host.pause();
14655
- }
14656
- }
14657
-
14658
- resume() {
14659
- if (this.host.resume) {
14660
- this.host.resume();
14661
- }
14662
- }
14663
-
14664
- end() {
14665
- if (this.host.end) {
14666
- this.host.end();
14667
- }
14668
- this._resolve(true);
14669
- }
14670
-
14671
- cancel() {
14672
- if (this.host.cancel) {
14673
- this.host.cancel();
14674
- }
14675
- this._resolve(false);
14676
- }
14677
-
14678
- complete(response) {
14679
- if (this._state === INITIAL_STATE) {
14680
- this._state = DONE_PENDING_STATE;
14681
- this._tick(() => {
14682
- this._resolve(response);
14683
- });
14684
- }
14685
- }
14686
-
14687
- _resolve(response) {
14688
- if (this._state !== DONE_COMPLETE_STATE) {
14689
- this._doneCallbacks.forEach((fn) => {
14690
- fn(response);
14691
- });
14692
- this._doneCallbacks.length = 0;
14693
- this._state = DONE_COMPLETE_STATE;
14694
- }
14695
- }
14696
- }
14697
-
14698
15301
  /**
14699
15302
  * Provides an instance of a cache that can be used to store and retrieve template content.
14700
15303
  */
@@ -15274,7 +15877,7 @@ class FilterProvider {
15274
15877
  /* @ignore */ static $inject = [$injectTokens.$provide];
15275
15878
 
15276
15879
  /**
15277
- * @param {import('../../interface.ts').Provider} $provide
15880
+ * @param {ng.ProvideService} $provide
15278
15881
  */
15279
15882
  constructor($provide) {
15280
15883
  this.$provide = $provide;
@@ -18053,7 +18656,7 @@ function parseHeaders(headers) {
18053
18656
  );
18054
18657
  } else if (isObject(headers)) {
18055
18658
  Object.entries(headers).forEach(([headerKey, headerVal]) => {
18056
- fillInParsed(lowercase(headerKey), trim(headerVal));
18659
+ fillInParsed(headerKey.toLowerCase(), trim(headerVal));
18057
18660
  });
18058
18661
  }
18059
18662
 
@@ -18079,7 +18682,7 @@ function headersGetter(headers) {
18079
18682
  if (!headersObj) headersObj = parseHeaders(headers);
18080
18683
 
18081
18684
  if (name) {
18082
- let value = headersObj[lowercase(name)];
18685
+ let value = headersObj[name.toLowerCase()];
18083
18686
  if (value === undefined) {
18084
18687
  value = null;
18085
18688
  }
@@ -19519,8 +20122,6 @@ class LocationProvider {
19519
20122
  * @returns {Location}
19520
20123
  */
19521
20124
  ($rootScope, $rootElement) => {
19522
- /** @type {Location} */
19523
- let $location;
19524
20125
  const baseHref = getBaseHref(); // if base[href] is undefined, it defaults to ''
19525
20126
  const initialUrl = trimEmptyHash(window.location.href);
19526
20127
  let appBase;
@@ -19538,7 +20139,7 @@ class LocationProvider {
19538
20139
  }
19539
20140
  const appBaseNoFile = stripFile(appBase);
19540
20141
 
19541
- $location = new Location(
20142
+ const $location = new Location(
19542
20143
  appBase,
19543
20144
  appBaseNoFile,
19544
20145
  this.html5ModeConf.enabled,
@@ -20046,7 +20647,7 @@ class LogProvider {
20046
20647
  }
20047
20648
 
20048
20649
  /**
20049
- * @returns {import("./interface.ts").LogService}
20650
+ * @returns {ng.LogService}
20050
20651
  */
20051
20652
  $get() {
20052
20653
  if (this._override) {
@@ -20128,6 +20729,9 @@ function createScope(target = {}, context) {
20128
20729
  }
20129
20730
 
20130
20731
  if (typeof target === "object") {
20732
+ if (isUnsafeGlobal(target)) {
20733
+ return target;
20734
+ }
20131
20735
  const proxy = new Proxy(target, context || new Scope());
20132
20736
  for (const key in target) {
20133
20737
  if (hasOwn(target, key)) {
@@ -20145,7 +20749,7 @@ function createScope(target = {}, context) {
20145
20749
  target[key] = createScope(target[key], proxy.$handler);
20146
20750
  }
20147
20751
  } catch {
20148
- // convert only what we can
20752
+ /* empty */
20149
20753
  }
20150
20754
  }
20151
20755
  }
@@ -20156,6 +20760,54 @@ function createScope(target = {}, context) {
20156
20760
  }
20157
20761
  }
20158
20762
 
20763
+ /**
20764
+ * @param {any} target
20765
+ * @returns {boolean}
20766
+ */
20767
+ function isUnsafeGlobal(target) {
20768
+ if (target == null) return false;
20769
+ const t = typeof target;
20770
+ if (t !== "object" && t !== "function") return false;
20771
+
20772
+ const g = globalThis;
20773
+ if (
20774
+ target === g ||
20775
+ target === g.window ||
20776
+ target === g.document ||
20777
+ target === g.self ||
20778
+ target === g.frames
20779
+ ) {
20780
+ return true;
20781
+ }
20782
+
20783
+ // DOM / browser host object checks
20784
+ if (
20785
+ (typeof Window !== "undefined" && target instanceof Window) ||
20786
+ (typeof Document !== "undefined" && target instanceof Document) ||
20787
+ (typeof Element !== "undefined" && target instanceof Element) ||
20788
+ (typeof Node !== "undefined" && target instanceof Node) ||
20789
+ (typeof EventTarget !== "undefined" && target instanceof EventTarget)
20790
+ ) {
20791
+ return true;
20792
+ }
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
+
20803
+ // Cross-origin or non-enumerable window objects
20804
+ try {
20805
+ return Object.prototype.toString.call(target) === "[object Window]";
20806
+ } catch {
20807
+ return true;
20808
+ }
20809
+ }
20810
+
20159
20811
  /**
20160
20812
  * Decorator for excluding objects from scope observability
20161
20813
  */
@@ -20242,6 +20894,8 @@ class Scope {
20242
20894
 
20243
20895
  this.scheduled = [];
20244
20896
 
20897
+ this.$scopename = undefined;
20898
+
20245
20899
  /** @private */
20246
20900
  this.propertyMap = {
20247
20901
  $watch: this.$watch.bind(this),
@@ -20253,18 +20907,20 @@ class Scope {
20253
20907
  $apply: this.$apply.bind(this),
20254
20908
  $postUpdate: this.$postUpdate.bind(this),
20255
20909
  $isRoot: this.#isRoot.bind(this),
20256
- $proxy: this.$proxy,
20257
20910
  $on: this.$on.bind(this),
20258
20911
  $emit: this.$emit.bind(this),
20259
20912
  $broadcast: this.$broadcast.bind(this),
20260
20913
  $transcluded: this.$transcluded.bind(this),
20261
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,
20262
20919
  $parent: this.$parent,
20263
20920
  $root: this.$root,
20264
20921
  $children: this.$children,
20265
20922
  $id: this.$id,
20266
- $merge: this.$merge.bind(this),
20267
- $getById: this.$getById.bind(this),
20923
+ $scopename: this.$scopename,
20268
20924
  };
20269
20925
  }
20270
20926
 
@@ -20280,8 +20936,14 @@ class Scope {
20280
20936
  */
20281
20937
  set(target, property, value, proxy) {
20282
20938
  if (property === "undefined") {
20283
- throw new Error("Attempting to set undefined property");
20939
+ return false;
20940
+ }
20941
+
20942
+ if (property === "$scopename") {
20943
+ this.$scopename = value;
20944
+ return true;
20284
20945
  }
20946
+
20285
20947
  if (
20286
20948
  (target.constructor?.$nonscope &&
20287
20949
  Array.isArray(target.constructor.$nonscope) &&
@@ -20498,9 +21160,9 @@ class Scope {
20498
21160
  * @returns {*} - The value of the property or a method if accessing `watch` or `sync`.
20499
21161
  */
20500
21162
  get(target, property, proxy) {
21163
+ if (property === "$scopename" && this.$scopename) return this.$scopename;
20501
21164
  if (property === "$$watchersCount") return calculateWatcherCount(this);
20502
21165
  if (property === isProxySymbol) return true;
20503
-
20504
21166
  if (target[property] && isProxy(target[property])) {
20505
21167
  this.$proxy = target[property];
20506
21168
  } else {
@@ -20529,7 +21191,6 @@ class Scope {
20529
21191
  this.#scheduleListener(this.scheduled);
20530
21192
  }
20531
21193
  }
20532
-
20533
21194
  if (hasOwn(this.propertyMap, property)) {
20534
21195
  this.$target = target;
20535
21196
  return this.propertyMap[property];
@@ -20627,7 +21288,7 @@ class Scope {
20627
21288
  * function is invoked when changes to that property are detected.
20628
21289
  *
20629
21290
  * @param {string} watchProp - An expression to be watched in the context of this model.
20630
- * @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.
20631
21292
  * @param {boolean} [lazy] - A flag to indicate if the listener should be invoked immediately. Defaults to false.
20632
21293
  */
20633
21294
  $watch(watchProp, listenerFn, lazy = false) {
@@ -20649,7 +21310,7 @@ class Scope {
20649
21310
  return () => {};
20650
21311
  }
20651
21312
 
20652
- /** @type {import('./interface.ts').Listener} */
21313
+ /** @type {ng.Listener} */
20653
21314
  const listener = {
20654
21315
  originalTarget: this.$target,
20655
21316
  listenerFn: listenerFn,
@@ -20707,13 +21368,34 @@ class Scope {
20707
21368
  }
20708
21369
  // 6
20709
21370
  case ASTType.BinaryExpression: {
20710
- let expr = get.decoratedNode.body[0].expression.toWatch[0];
20711
- key = expr.property ? expr.property.name : expr.name;
20712
- if (!key) {
20713
- 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
+ };
20714
21398
  }
20715
- listener.property.push(key);
20716
- break;
20717
21399
  }
20718
21400
  // 7
20719
21401
  case ASTType.UnaryExpression: {
@@ -21253,6 +21935,26 @@ class Scope {
21253
21935
  return res;
21254
21936
  }
21255
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
+ }
21256
21958
  }
21257
21959
 
21258
21960
  /*------------- Private helpers -------------*/
@@ -21480,25 +22182,31 @@ class SanitizeUriProvider {
21480
22182
  }
21481
22183
 
21482
22184
  /**
21483
- * @returns {import("./interface").SanitizerFn}
22185
+ * @returns {import("./interface.ts").SanitizerFn}
21484
22186
  */
21485
- $get() {
21486
- return (uri, isMediaUrl) => {
21487
- 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;
21488
22194
 
21489
- /** @type {RegExp} */
21490
- const regex = isMediaUrl
21491
- ? this._imgSrcSanitizationTrustedUrlList
21492
- : this._aHrefSanitizationTrustedUrlList;
22195
+ /** @type {RegExp} */
22196
+ const regex = isMediaUrl
22197
+ ? this._imgSrcSanitizationTrustedUrlList
22198
+ : this._aHrefSanitizationTrustedUrlList;
21493
22199
 
21494
- const normalizedVal = urlResolve(uri.trim()).href;
22200
+ const normalizedVal = new URL(uri.trim(), $window.location.href).href;
21495
22201
 
21496
- if (normalizedVal !== "" && !normalizedVal.match(regex)) {
21497
- return `unsafe:${normalizedVal}`;
21498
- }
21499
- return uri;
21500
- };
21501
- }
22202
+ if (normalizedVal !== "" && !normalizedVal.match(regex)) {
22203
+ return `unsafe:${normalizedVal}`;
22204
+ }
22205
+ return uri;
22206
+ }
22207
+ );
22208
+ },
22209
+ ];
21502
22210
  }
21503
22211
 
21504
22212
  const ACTIVE_CLASS = "ng-active";
@@ -21507,9 +22215,9 @@ const INACTIVE_CLASS = "ng-inactive";
21507
22215
  class NgMessageCtrl {
21508
22216
  /**
21509
22217
  * @param {Element} $element
21510
- * @param {import('../../core/scope/scope.js').Scope} $scope
21511
- * @param {import('../../core/compile/attributes').Attributes} $attrs
21512
- * @param {*} $animate
22218
+ * @param {ng.Scope} $scope
22219
+ * @param {ng.Attributes} $attrs
22220
+ * @param {ng.AnimateService} $animate
21513
22221
  */
21514
22222
  constructor($element, $scope, $attrs, $animate) {
21515
22223
  this.$element = $element;
@@ -21693,6 +22401,10 @@ class NgMessageCtrl {
21693
22401
  }
21694
22402
 
21695
22403
  ngMessagesDirective.$inject = ["$animate"];
22404
+ /**
22405
+ * @param {ng.AnimateService} $animate
22406
+ * @returns {ng.Directive<NgMessageCtrl>}
22407
+ */
21696
22408
  function ngMessagesDirective($animate) {
21697
22409
  return {
21698
22410
  require: "ngMessages",
@@ -21739,10 +22451,14 @@ const ngMessageDefaultDirective = ngMessageDirectiveFactory(true);
21739
22451
 
21740
22452
  /**
21741
22453
  * @param {boolean} isDefault
21742
- * @returns {(any) => import("../../interface.ts").Directive}
22454
+ * @returns {(any) => ng.Directive}
21743
22455
  */
21744
22456
  function ngMessageDirectiveFactory(isDefault) {
21745
22457
  ngMessageDirective.$inject = ["$animate"];
22458
+ /**
22459
+ * @param {ng.AnimateService} $animate
22460
+ * @returns {ng.Directive}
22461
+ */
21746
22462
  function ngMessageDirective($animate) {
21747
22463
  return {
21748
22464
  restrict: "AE",
@@ -22229,6 +22945,231 @@ function ngDblclickAriaDirective($aria) {
22229
22945
  };
22230
22946
  }
22231
22947
 
22948
+ /**
22949
+ * @fileoverview
22950
+ * Frame-synchronized animation runner and scheduler.
22951
+ * Provides async batching of animation callbacks using requestAnimationFrame.
22952
+ * In AngularJS, this used to be implemented as `$$AnimateRunner`
22953
+ */
22954
+
22955
+ /**
22956
+ * Internal runner states.
22957
+ * @readonly
22958
+ * @enum {number}
22959
+ */
22960
+ const RunnerState = {
22961
+ INITIAL: 0,
22962
+ PENDING: 1,
22963
+ DONE: 2,
22964
+ };
22965
+
22966
+ /** @type {VoidFunction[]} */
22967
+ let queue = [];
22968
+
22969
+ /** @type {boolean} */
22970
+ let scheduled = false;
22971
+
22972
+ /**
22973
+ * Flush all queued callbacks.
22974
+ * @private
22975
+ */
22976
+ function flush() {
22977
+ const tasks = queue;
22978
+ queue = [];
22979
+ scheduled = false;
22980
+ for (let i = 0; i < tasks.length; i++) {
22981
+ tasks[i]();
22982
+ }
22983
+ }
22984
+
22985
+ /**
22986
+ * Schedule a callback to run on the next animation frame.
22987
+ * Multiple calls within the same frame are batched together.
22988
+ *
22989
+ * @param {VoidFunction} fn - The callback to execute.
22990
+ */
22991
+ function schedule(fn) {
22992
+ queue.push(fn);
22993
+ if (!scheduled) {
22994
+ scheduled = true;
22995
+ (typeof requestAnimationFrame === "function"
22996
+ ? requestAnimationFrame
22997
+ : setTimeout)(flush, 0);
22998
+ }
22999
+ }
23000
+
23001
+ /**
23002
+ * Represents an asynchronous animation operation.
23003
+ * Provides both callback-based and promise-based completion APIs.
23004
+ */
23005
+ class AnimateRunner {
23006
+ /**
23007
+ * Run an array of animation runners in sequence.
23008
+ * Each runner waits for the previous one to complete.
23009
+ *
23010
+ * @param {AnimateRunner[]} runners - Runners to execute in order.
23011
+ * @param {(ok: boolean) => void} callback - Invoked when all complete or one fails.
23012
+ */
23013
+ static chain(runners, callback) {
23014
+ let i = 0;
23015
+ const next = (ok = true) => {
23016
+ if (!ok || i >= runners.length) {
23017
+ callback(ok);
23018
+ return;
23019
+ }
23020
+ runners[i++].done(next);
23021
+ };
23022
+ next();
23023
+ }
23024
+
23025
+ /**
23026
+ * Waits for all animation runners to complete before invoking the callback.
23027
+ *
23028
+ * @param {AnimateRunner[]} runners - Active runners to wait for.
23029
+ * @param {(ok: boolean) => void} callback - Called when all runners complete.
23030
+ */
23031
+ static all(runners, callback) {
23032
+ let remaining = runners.length;
23033
+ let status = true;
23034
+ for (const r of runners) {
23035
+ r.done((result) => {
23036
+ status = status && result !== false;
23037
+ if (--remaining === 0) callback(status);
23038
+ });
23039
+ }
23040
+ }
23041
+
23042
+ /**
23043
+ * @param {import("../interface.ts").AnimationHost} [host] - Optional animation host.
23044
+ */
23045
+ constructor(host) {
23046
+ /** @type {import("../interface.ts").AnimationHost} */
23047
+ this.host = host || {};
23048
+
23049
+ /** @type {Array<(ok: boolean) => void>} */
23050
+ this._doneCallbacks = [];
23051
+
23052
+ /** @type {RunnerState} */
23053
+ this._state = RunnerState.INITIAL;
23054
+
23055
+ /** @type {Promise<void>|null} */
23056
+ this._promise = null;
23057
+
23058
+ /** @type {(fn: VoidFunction) => void} */
23059
+ this._schedule = schedule;
23060
+ }
23061
+
23062
+ /**
23063
+ * Sets or updates the animation host.
23064
+ * @param {import("../interface.ts").AnimationHost} host - The host object.
23065
+ */
23066
+ setHost(host) {
23067
+ this.host = host || {};
23068
+ }
23069
+
23070
+ /**
23071
+ * Registers a callback to be called once the animation completes.
23072
+ * If the animation is already complete, it's called immediately.
23073
+ *
23074
+ * @param {(ok: boolean) => void} fn - Completion callback.
23075
+ */
23076
+ done(fn) {
23077
+ if (this._state === RunnerState.DONE) {
23078
+ fn(true);
23079
+ } else {
23080
+ this._doneCallbacks.push(fn);
23081
+ }
23082
+ }
23083
+
23084
+ /**
23085
+ * Notifies the host of animation progress.
23086
+ * @param {...any} args - Progress arguments.
23087
+ */
23088
+ progress(...args) {
23089
+ this.host.progress?.(...args);
23090
+ }
23091
+
23092
+ /** Pauses the animation, if supported by the host. */
23093
+ pause() {
23094
+ this.host.pause?.();
23095
+ }
23096
+
23097
+ /** Resumes the animation, if supported by the host. */
23098
+ resume() {
23099
+ this.host.resume?.();
23100
+ }
23101
+
23102
+ /** Ends the animation successfully. */
23103
+ end() {
23104
+ this.host.end?.();
23105
+ this._finish(true);
23106
+ }
23107
+
23108
+ /** Cancels the animation. */
23109
+ cancel() {
23110
+ this.host.cancel?.();
23111
+ this._finish(false);
23112
+ }
23113
+
23114
+ /**
23115
+ * Marks the animation as complete on the next animation frame.
23116
+ * @param {boolean} [status=true] - True if successful, false if canceled.
23117
+ */
23118
+ complete(status = true) {
23119
+ if (this._state === RunnerState.INITIAL) {
23120
+ this._state = RunnerState.PENDING;
23121
+ this._schedule(() => this._finish(status));
23122
+ }
23123
+ }
23124
+
23125
+ /**
23126
+ * Returns a promise that resolves or rejects when the animation completes.
23127
+ * @returns {Promise<void>} Promise resolved on success or rejected on cancel.
23128
+ */
23129
+ getPromise() {
23130
+ if (!this._promise) {
23131
+ this._promise = new Promise((resolve, reject) => {
23132
+ this.done((success) => {
23133
+ if (success === false) reject();
23134
+ else resolve();
23135
+ });
23136
+ });
23137
+ }
23138
+ return this._promise;
23139
+ }
23140
+
23141
+ /** @inheritdoc */
23142
+ then(onFulfilled, onRejected) {
23143
+ return this.getPromise().then(onFulfilled, onRejected);
23144
+ }
23145
+
23146
+ /** @inheritdoc */
23147
+ catch(onRejected) {
23148
+ return this.getPromise().catch(onRejected);
23149
+ }
23150
+
23151
+ /** @inheritdoc */
23152
+ finally(onFinally) {
23153
+ return this.getPromise().finally(onFinally);
23154
+ }
23155
+
23156
+ /**
23157
+ * Completes the animation and invokes all done callbacks.
23158
+ * @private
23159
+ * @param {boolean} status - True if completed successfully, false if canceled.
23160
+ */
23161
+ _finish(status) {
23162
+ if (this._state === RunnerState.DONE) return;
23163
+ this._state = RunnerState.DONE;
23164
+
23165
+ const callbacks = this._doneCallbacks;
23166
+ for (let i = 0; i < callbacks.length; i++) {
23167
+ callbacks[i](status);
23168
+ }
23169
+ callbacks.length = 0;
23170
+ }
23171
+ }
23172
+
22232
23173
  const ANIMATE_TIMER_KEY = "$$animateCss";
22233
23174
 
22234
23175
  const ONE_SECOND = 1000;
@@ -22338,18 +23279,16 @@ function registerRestorableStyles(backup, node, properties) {
22338
23279
  function AnimateCssProvider() {
22339
23280
  let activeClasses;
22340
23281
  this.$get = [
22341
- "$$AnimateRunner",
22342
23282
  "$$animateCache",
22343
23283
  "$$rAFScheduler",
22344
23284
 
22345
23285
  /**
22346
23286
  *
22347
- * @param {*} $$AnimateRunner
22348
23287
  * @param {*} $$animateCache
22349
23288
  * @param {import("./raf-scheduler").RafScheduler} $$rAFScheduler
22350
23289
  * @returns
22351
23290
  */
22352
- function ($$AnimateRunner, $$animateCache, $$rAFScheduler) {
23291
+ function ($$animateCache, $$rAFScheduler) {
22353
23292
  const applyAnimationClasses = applyAnimationClassesFactory();
22354
23293
 
22355
23294
  function computeCachedCssStyles(
@@ -22747,7 +23686,7 @@ function AnimateCssProvider() {
22747
23686
  pause: null,
22748
23687
  };
22749
23688
 
22750
- runner = new $$AnimateRunner(runnerHost);
23689
+ runner = new AnimateRunner(runnerHost);
22751
23690
 
22752
23691
  waitUntilQuiet(start);
22753
23692
 
@@ -22846,7 +23785,7 @@ function AnimateCssProvider() {
22846
23785
  }
22847
23786
 
22848
23787
  function closeAndReturnNoopAnimator() {
22849
- runner = new $$AnimateRunner({
23788
+ runner = new AnimateRunner({
22850
23789
  end: endFn,
22851
23790
  cancel: cancelFn,
22852
23791
  });
@@ -23111,6 +24050,7 @@ function blockTransitions(node, duration) {
23111
24050
 
23112
24051
  const NG_ANIMATE_ATTR_NAME = "data-ng-animate";
23113
24052
  const NG_ANIMATE_PIN_DATA = "$ngAnimatePin";
24053
+
23114
24054
  AnimateQueueProvider.$inject = ["$animateProvider"];
23115
24055
  function AnimateQueueProvider($animateProvider) {
23116
24056
  const PRE_DIGEST_STATE = 1;
@@ -23234,24 +24174,16 @@ function AnimateQueueProvider($animateProvider) {
23234
24174
  $injectTokens.$rootScope,
23235
24175
  $injectTokens.$injector,
23236
24176
  $injectTokens.$$animation,
23237
- $injectTokens.$$AnimateRunner,
23238
24177
  $injectTokens.$templateRequest,
23239
24178
  /**
23240
24179
  *
23241
- * @param {import('../core/scope/scope.js').Scope} $rootScope
23242
- * @param {import('../core/di/internal-injector.js').InjectorService} $injector
24180
+ * @param {ng.RootScopeService} $rootScope
24181
+ * @param {ng.InjectorService} $injector
23243
24182
  * @param {*} $$animation
23244
- * @param {*} $$AnimateRunner
23245
- * @param {*} $templateRequest
23246
- * @returns
24183
+ * @param {ng.TemplateRequestService} $templateRequest
24184
+ * @returns {import("../queue/interface.ts").AnimateQueueService}
23247
24185
  */
23248
- function (
23249
- $rootScope,
23250
- $injector,
23251
- $$animation,
23252
- $$AnimateRunner,
23253
- $templateRequest,
23254
- ) {
24186
+ function ($rootScope, $injector, $$animation, $templateRequest) {
23255
24187
  const activeAnimationsLookup = new Map();
23256
24188
  const disabledElementsLookup = new Map();
23257
24189
 
@@ -23417,12 +24349,6 @@ function AnimateQueueProvider($animateProvider) {
23417
24349
  },
23418
24350
 
23419
24351
  pin(element, parentElement) {
23420
- assertArg(isElement(element), "element", "not an element");
23421
- assertArg(
23422
- isElement(parentElement),
23423
- "parentElement",
23424
- "not an element",
23425
- );
23426
24352
  setCacheData(element, NG_ANIMATE_PIN_DATA, parentElement);
23427
24353
  },
23428
24354
 
@@ -23459,7 +24385,7 @@ function AnimateQueueProvider($animateProvider) {
23459
24385
 
23460
24386
  // we create a fake runner with a working promise.
23461
24387
  // These methods will become available after the digest has passed
23462
- const runner = new $$AnimateRunner();
24388
+ const runner = new AnimateRunner();
23463
24389
 
23464
24390
  // this is used to trigger callbacks in postDigest mode
23465
24391
  const runInNextPostDigestOrNow = postDigestTaskFactory();
@@ -23763,6 +24689,18 @@ function AnimateQueueProvider($animateProvider) {
23763
24689
  }
23764
24690
  }
23765
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
+ */
23766
24704
  function closeChildAnimations(node) {
23767
24705
  const children = node.querySelectorAll(`[${NG_ANIMATE_ATTR_NAME}]`);
23768
24706
  children.forEach((child) => {
@@ -23904,14 +24842,12 @@ AnimateJsProvider.$inject = [$injectTokens.$animate + "Provider"];
23904
24842
  function AnimateJsProvider($animateProvider) {
23905
24843
  this.$get = [
23906
24844
  $injectTokens.$injector,
23907
- "$$AnimateRunner",
23908
24845
  /**
23909
24846
  *
23910
24847
  * @param {ng.InjectorService} $injector
23911
- * @param {*} $$AnimateRunner
23912
24848
  * @returns
23913
24849
  */
23914
- function ($injector, $$AnimateRunner) {
24850
+ function ($injector) {
23915
24851
  const applyAnimationClasses = applyAnimationClassesFactory();
23916
24852
  // $animateJs(element, 'enter');
23917
24853
  return function (element, event, classes, options) {
@@ -23998,7 +24934,7 @@ function AnimateJsProvider($animateProvider) {
23998
24934
  runner.end();
23999
24935
  } else {
24000
24936
  close();
24001
- runner = new $$AnimateRunner();
24937
+ runner = new AnimateRunner();
24002
24938
  runner.complete(true);
24003
24939
  }
24004
24940
  return runner;
@@ -24008,31 +24944,53 @@ function AnimateJsProvider($animateProvider) {
24008
24944
  return runner;
24009
24945
  }
24010
24946
 
24011
- runner = new $$AnimateRunner();
24012
- let closeActiveAnimations;
24947
+ runner = new AnimateRunner();
24948
+
24013
24949
  const chain = [];
24014
24950
 
24015
24951
  if (before) {
24016
- chain.push((fn) => {
24017
- closeActiveAnimations = before(fn);
24952
+ const runnerBefore = new AnimateRunner({
24953
+ end(fn) {
24954
+ // call the before animation function, then mark runner done
24955
+ const endFn = before(fn) || (() => {});
24956
+ endFn();
24957
+ },
24958
+ cancel() {
24959
+ (before(true) || (() => {}))();
24960
+ },
24018
24961
  });
24962
+ chain.push(runnerBefore);
24019
24963
  }
24020
24964
 
24021
24965
  if (chain.length) {
24022
- chain.push((fn) => {
24023
- applyOptions();
24024
- fn(true);
24966
+ const runnerApplyOptions = new AnimateRunner({
24967
+ end(fn) {
24968
+ applyOptions();
24969
+ fn(true);
24970
+ },
24971
+ cancel() {
24972
+ applyOptions();
24973
+ },
24025
24974
  });
24975
+ chain.push(runnerApplyOptions);
24026
24976
  } else {
24027
24977
  applyOptions();
24028
24978
  }
24029
24979
 
24030
24980
  if (after) {
24031
- chain.push((fn) => {
24032
- closeActiveAnimations = after(fn);
24981
+ const runnerAfter = new AnimateRunner({
24982
+ end(fn) {
24983
+ const endFn = after(fn) || (() => {});
24984
+ endFn();
24985
+ },
24986
+ cancel() {
24987
+ (after(true) || (() => {}))();
24988
+ },
24033
24989
  });
24990
+ chain.push(runnerAfter);
24034
24991
  }
24035
24992
 
24993
+ // finally, set host for overall runner
24036
24994
  runner.setHost({
24037
24995
  end() {
24038
24996
  endAnimations();
@@ -24042,7 +25000,7 @@ function AnimateJsProvider($animateProvider) {
24042
25000
  },
24043
25001
  });
24044
25002
 
24045
- $$AnimateRunner.chain(chain, onComplete);
25003
+ AnimateRunner.chain(chain, onComplete);
24046
25004
  return runner;
24047
25005
 
24048
25006
  function onComplete(success) {
@@ -24052,7 +25010,6 @@ function AnimateJsProvider($animateProvider) {
24052
25010
 
24053
25011
  function endAnimations(cancelled) {
24054
25012
  if (!animationClosed) {
24055
- (closeActiveAnimations || (() => {}))(cancelled);
24056
25013
  onComplete(cancelled);
24057
25014
  }
24058
25015
  }
@@ -24091,7 +25048,7 @@ function AnimateJsProvider($animateProvider) {
24091
25048
  value = value.start();
24092
25049
  }
24093
25050
 
24094
- if (value instanceof $$AnimateRunner) {
25051
+ if (value instanceof AnimateRunner) {
24095
25052
  value.done(onDone);
24096
25053
  } else if (isFunction(value)) {
24097
25054
  // optional onEnd / onCancel callback
@@ -24128,7 +25085,7 @@ function AnimateJsProvider($animateProvider) {
24128
25085
  }
24129
25086
  };
24130
25087
 
24131
- runner = new $$AnimateRunner({
25088
+ runner = new AnimateRunner({
24132
25089
  end() {
24133
25090
  onAnimationComplete();
24134
25091
  },
@@ -24224,7 +25181,7 @@ function AnimateJsProvider($animateProvider) {
24224
25181
  }
24225
25182
 
24226
25183
  if (runners.length) {
24227
- $$AnimateRunner.all(runners, callback);
25184
+ AnimateRunner.all(runners, callback);
24228
25185
  } else {
24229
25186
  callback();
24230
25187
  }
@@ -24284,25 +25241,17 @@ function AnimationProvider() {
24284
25241
  this.$get = [
24285
25242
  $injectTokens.$rootScope,
24286
25243
  $injectTokens.$injector,
24287
- $injectTokens.$$AnimateRunner,
24288
25244
  $injectTokens.$$rAFScheduler,
24289
25245
  $injectTokens.$$animateCache,
24290
25246
  /**
24291
25247
  *
24292
25248
  * @param {ng.RootScopeService} $rootScope
24293
- * @param {import("../core/di/internal-injector").InjectorService} $injector
24294
- * @param {*} $$AnimateRunner
24295
- * @param {import("./raf-scheduler").RafScheduler} $$rAFScheduler
25249
+ * @param {ng.InjectorService} $injector
25250
+ * @param {import("./raf-scheduler.js").RafScheduler} $$rAFScheduler
24296
25251
  * @param {*} $$animateCache
24297
25252
  * @returns
24298
25253
  */
24299
- function (
24300
- $rootScope,
24301
- $injector,
24302
- $$AnimateRunner,
24303
- $$rAFScheduler,
24304
- $$animateCache,
24305
- ) {
25254
+ function ($rootScope, $injector, $$rAFScheduler, $$animateCache) {
24306
25255
  const animationQueue = [];
24307
25256
  const applyAnimationClasses = applyAnimationClassesFactory();
24308
25257
 
@@ -24403,7 +25352,7 @@ function AnimationProvider() {
24403
25352
  // these runner methods will get later updated with the
24404
25353
  // methods leading into the driver's end/cancel methods
24405
25354
  // for now they just stop the animation from starting
24406
- const runner = new $$AnimateRunner({
25355
+ const runner = new AnimateRunner({
24407
25356
  end() {
24408
25357
  close();
24409
25358
  },
@@ -24417,9 +25366,9 @@ function AnimationProvider() {
24417
25366
  return runner;
24418
25367
  }
24419
25368
 
24420
- let classes = mergeClasses$1(
25369
+ let classes = mergeClasses(
24421
25370
  element.getAttribute("class"),
24422
- mergeClasses$1(options.addClass, options.removeClass),
25371
+ mergeClasses(options.addClass, options.removeClass),
24423
25372
  );
24424
25373
  let { tempClasses } = options;
24425
25374
  if (tempClasses) {
@@ -24958,16 +25907,14 @@ function AnimateCssDriverProvider($$animationProvider) {
24958
25907
  */
24959
25908
  this.$get = [
24960
25909
  "$animateCss",
24961
- "$$AnimateRunner",
24962
25910
  "$rootElement",
24963
25911
  /**
24964
25912
  *
24965
25913
  * @param {*} $animateCss
24966
- * @param {typeof import('./animate-runner.js').AnimateRunner} $$AnimateRunner
24967
25914
  * @param {Element} $rootElement
24968
25915
  * @returns
24969
25916
  */
24970
- function ($animateCss, $$AnimateRunner, $rootElement) {
25917
+ function ($animateCss, $rootElement) {
24971
25918
  const bodyNode = document.body;
24972
25919
  const rootNode = $rootElement;
24973
25920
 
@@ -25040,7 +25987,7 @@ function AnimateCssDriverProvider($$animationProvider) {
25040
25987
  runner.complete();
25041
25988
  });
25042
25989
 
25043
- runner = new $$AnimateRunner({
25990
+ runner = new AnimateRunner({
25044
25991
  end: endFn,
25045
25992
  cancel: endFn,
25046
25993
  });
@@ -25151,12 +26098,12 @@ function AnimateCssDriverProvider($$animationProvider) {
25151
26098
  animationRunners.push(animation.start());
25152
26099
  });
25153
26100
 
25154
- const runner = new $$AnimateRunner({
26101
+ const runner = new AnimateRunner({
25155
26102
  end: endFn,
25156
26103
  cancel: endFn, // CSS-driven animations cannot be cancelled, only ended
25157
26104
  });
25158
26105
 
25159
- $$AnimateRunner.all(animationRunners, (status) => {
26106
+ AnimateRunner.all(animationRunners, (status) => {
25160
26107
  runner.complete(status);
25161
26108
  });
25162
26109
 
@@ -25226,8 +26173,11 @@ function AnimateJsDriverProvider($$animationProvider) {
25226
26173
  $$animationProvider.drivers.push("$$animateJsDriver");
25227
26174
  this.$get = [
25228
26175
  "$$animateJs",
25229
- "$$AnimateRunner",
25230
- function ($$animateJs, $$AnimateRunner) {
26176
+ /**
26177
+ *
26178
+ * @param {*} $$animateJs
26179
+ */
26180
+ function ($$animateJs) {
25231
26181
  return function initDriverFn(animationDetails) {
25232
26182
  if (animationDetails.from && animationDetails.to) {
25233
26183
  const fromAnimation = prepareAnimation(animationDetails.from);
@@ -25246,9 +26196,9 @@ function AnimateJsDriverProvider($$animationProvider) {
25246
26196
  animationRunners.push(toAnimation.start());
25247
26197
  }
25248
26198
 
25249
- $$AnimateRunner.all(animationRunners, done);
26199
+ AnimateRunner.all(animationRunners, done);
25250
26200
 
25251
- const runner = new $$AnimateRunner({
26201
+ const runner = new AnimateRunner({
25252
26202
  end: endFnFactory(),
25253
26203
  cancel: endFnFactory(),
25254
26204
  });
@@ -26575,6 +27525,7 @@ function stringify(o) {
26575
27525
  }
26576
27526
  return JSON.stringify(o, (key, value) => format(value)).replace(/\\"/g, '"');
26577
27527
  }
27528
+
26578
27529
  const stripLastPathElement = (str) => str.replace(/\/[^/]*$/, "");
26579
27530
  /**
26580
27531
  * Splits on a delimiter, but returns the delimiters in the array
@@ -34610,7 +35561,7 @@ let ngView = [
34610
35561
  "$interpolate",
34611
35562
  /**
34612
35563
  * @param {*} $view
34613
- * @param {*} $animate
35564
+ * @param {ng.AnimateService} $animate
34614
35565
  * @param {*} $viewScroll
34615
35566
  * @param {*} $interpolate
34616
35567
  * @returns {import("../../interface.ts").Directive}
@@ -35038,447 +35989,31 @@ function ngSetterDirective($parse, $log) {
35038
35989
  };
35039
35990
  }
35040
35991
 
35041
- /**
35042
- * @param {"get" | "delete" | "post" | "put"} method - HTTP method applied to request
35043
- * @param {string} [attrOverride] - Custom name to use for the attribute
35044
- * @returns {ng.DirectiveFactory}
35045
- */
35046
- function defineDirective(method, attrOverride) {
35047
- const attrName =
35048
- attrOverride || "ng" + method.charAt(0).toUpperCase() + method.slice(1);
35049
- const directive = createHttpDirective(method, attrName);
35050
- directive["$inject"] = [
35051
- $injectTokens.$http,
35052
- $injectTokens.$compile,
35053
- $injectTokens.$log,
35054
- $injectTokens.$parse,
35055
- $injectTokens.$state,
35056
- $injectTokens.$sse,
35057
- $injectTokens.$animate,
35058
- ];
35059
- return directive;
35060
- }
35061
-
35062
- /** @type {ng.DirectiveFactory} */
35063
- const ngGetDirective = defineDirective("get");
35064
-
35065
- /** @type {ng.DirectiveFactory} */
35066
- const ngDeleteDirective = defineDirective("delete");
35067
-
35068
- /** @type {ng.DirectiveFactory} */
35069
- const ngPostDirective = defineDirective("post");
35070
-
35071
- /** @type {ng.DirectiveFactory} */
35072
- const ngPutDirective = defineDirective("put");
35073
-
35074
- /** @type {ng.DirectiveFactory} */
35075
- const ngSseDirective = defineDirective("get", "ngSse");
35076
-
35077
- /**
35078
- * Selects DOM event to listen for based on the element type.
35079
- *
35080
- * @param {Element} element - The DOM element to inspect.
35081
- * @returns {"click" | "change" | "submit"} The name of the event to listen for.
35082
- */
35083
- function getEventNameForElement(element) {
35084
- const tag = element.tagName.toLowerCase();
35085
- if (["input", "textarea", "select"].includes(tag)) {
35086
- return "change";
35087
- } else if (tag === "form") {
35088
- return "submit";
35089
- }
35090
- return "click";
35091
- }
35092
-
35093
- /**
35094
- * Creates an HTTP directive factory that supports GET, DELETE, POST, PUT.
35095
- *
35096
- * @param {"get" | "delete" | "post" | "put"} method - HTTP method to use.
35097
- * @param {string} attrName - Attribute name containing the URL.
35098
- * @returns {ng.DirectiveFactory}
35099
- */
35100
- function createHttpDirective(method, attrName) {
35101
- let content = undefined;
35102
-
35103
- /**
35104
- * @param {ng.HttpService} $http
35105
- * @param {ng.CompileService} $compile
35106
- * @param {ng.LogService} $log
35107
- * @param {ng.ParseService} $parse
35108
- * @param {ng.StateService} $state
35109
- * @param {ng.SseService} $sse
35110
- * @returns {ng.Directive}
35111
- */
35112
- return function ($http, $compile, $log, $parse, $state, $sse, $animate) {
35113
- /**
35114
- * Handles DOM manipulation based on a swap strategy and server-rendered HTML.
35115
- *
35116
- * @param {string | Object} html - The HTML string or object returned from the server.
35117
- * @param {import("./interface.ts").SwapModeType} swap
35118
- * @param {ng.Scope} scope
35119
- * @param {ng.Attributes} attrs
35120
- * @param {Element} element
35121
- */
35122
- function handleSwapResponse(html, swap, scope, attrs, element) {
35123
- let animationEnabled = false;
35124
- if (attrs.animate) {
35125
- animationEnabled = true;
35126
- }
35127
- let nodes = [];
35128
- if (!["textcontent", "delete", "none"].includes(swap)) {
35129
- if (!html) return;
35130
- const compiled = $compile(html)(scope);
35131
- nodes =
35132
- compiled instanceof DocumentFragment
35133
- ? Array.from(compiled.childNodes)
35134
- : [compiled];
35135
- }
35136
-
35137
- const targetSelector = attrs["target"];
35138
- const target = targetSelector
35139
- ? document.querySelector(targetSelector)
35140
- : element;
35141
-
35142
- if (!target) {
35143
- $log.warn(`${attrName}: target "${targetSelector}" not found`);
35144
- return;
35145
- }
35146
-
35147
- switch (swap) {
35148
- case "innerHTML":
35149
- if (animationEnabled) {
35150
- if (content) {
35151
- $animate.leave(content).done(() => {
35152
- content = nodes[0];
35153
- $animate.enter(nodes[0], target);
35154
- scope.$flushQueue();
35155
- });
35156
- scope.$flushQueue();
35157
- } else {
35158
- content = nodes[0];
35159
- $animate.enter(nodes[0], target);
35160
- scope.$flushQueue();
35161
- }
35162
- } else {
35163
- target.replaceChildren(...nodes);
35164
- }
35165
- break;
35166
-
35167
- case "outerHTML": {
35168
- const parent = target.parentNode;
35169
- if (!parent) return;
35170
- const frag = document.createDocumentFragment();
35171
- nodes.forEach((n) => frag.appendChild(n));
35172
- if (animationEnabled) {
35173
- const placeholder = document.createComment("placeholder");
35174
- target.parentNode.insertBefore(placeholder, target.nextSibling);
35175
- $animate.leave(target).done(() => {
35176
- const insertedNodes = Array.from(frag.childNodes);
35177
- insertedNodes.forEach((n) =>
35178
- $animate.enter(n, parent, placeholder),
35179
- );
35180
- content = insertedNodes;
35181
- scope.$flushQueue();
35182
- });
35183
- scope.$flushQueue();
35184
- } else {
35185
- parent.replaceChild(frag, target);
35186
- }
35187
- break;
35188
- }
35189
-
35190
- case "textContent":
35191
- target.textContent = html;
35192
- break;
35193
-
35194
- case "beforebegin":
35195
- nodes.forEach((node) => target.parentNode.insertBefore(node, target));
35196
- break;
35197
-
35198
- case "afterbegin":
35199
- nodes
35200
- .slice()
35201
- .reverse()
35202
- .forEach((node) => target.insertBefore(node, target.firstChild));
35203
- break;
35204
-
35205
- case "beforeend":
35206
- nodes.forEach((node) => target.appendChild(node));
35207
- break;
35208
-
35209
- case "afterend":
35210
- nodes
35211
- .slice()
35212
- .reverse()
35213
- .forEach((node) =>
35214
- target.parentNode.insertBefore(node, target.nextSibling),
35215
- );
35216
- break;
35217
-
35218
- case "delete":
35219
- target.remove();
35220
- break;
35221
-
35222
- case "none":
35223
- break;
35224
-
35225
- default:
35226
- target.replaceChildren(...nodes);
35227
- break;
35228
- }
35229
- }
35230
-
35231
- /**
35232
- * Collects form data from the element or its associated form.
35233
- *
35234
- * @param {HTMLElement} element
35235
- * @returns {Object<string, any>}
35236
- */
35237
- function collectFormData(element) {
35238
- /** @type {HTMLFormElement | null} */
35239
- let form = null;
35240
-
35241
- const tag = element.tagName.toLowerCase();
35242
-
35243
- if (tag === "form") {
35244
- form = /** @type {HTMLFormElement} */ (element);
35245
- } else if ("form" in element && element.form) {
35246
- form = /** @type {HTMLFormElement} */ (element.form);
35247
- } else if (element.hasAttribute("form")) {
35248
- const formId = element.getAttribute("form");
35249
- if (formId) {
35250
- const maybeForm = document.getElementById(formId);
35251
- if (maybeForm && maybeForm.tagName.toLowerCase() === "form") {
35252
- form = /** @type {HTMLFormElement} */ (maybeForm);
35253
- }
35254
- }
35255
- }
35256
-
35257
- if (!form) {
35258
- if (
35259
- "name" in element &&
35260
- typeof element.name === "string" &&
35261
- element.name.length > 0
35262
- ) {
35263
- if (
35264
- element instanceof HTMLInputElement ||
35265
- element instanceof HTMLTextAreaElement ||
35266
- element instanceof HTMLSelectElement
35267
- ) {
35268
- const key = element.name;
35269
- const value = element.value;
35270
- return { [key]: value };
35271
- }
35272
- }
35273
- return {};
35274
- }
35275
-
35276
- const formData = new FormData(form);
35277
- const data = {};
35278
- formData.forEach((value, key) => {
35279
- data[key] = value;
35280
- });
35281
- return data;
35282
- }
35283
-
35284
- return {
35285
- restrict: "A",
35286
- link(scope, element, attrs) {
35287
- const eventName = attrs.trigger || getEventNameForElement(element);
35288
- const tag = element.tagName.toLowerCase();
35289
-
35290
- if (isDefined(attrs.latch)) {
35291
- attrs.$observe(
35292
- "latch",
35293
- callBackAfterFirst(() =>
35294
- element.dispatchEvent(new Event(eventName)),
35295
- ),
35296
- );
35297
- }
35298
-
35299
- let throttled = false;
35300
- let intervalId;
35301
-
35302
- if (isDefined(attrs["interval"])) {
35303
- element.dispatchEvent(new Event(eventName));
35304
- intervalId = setInterval(
35305
- () => element.dispatchEvent(new Event(eventName)),
35306
- parseInt(attrs.interval) || 1000,
35307
- );
35308
- }
35309
-
35310
- element.addEventListener(eventName, async (event) => {
35311
- if (/** @type {HTMLButtonElement} */ (element).disabled) return;
35312
- if (tag === "form") event.preventDefault();
35313
- const swap = attrs.swap || "innerHTML";
35314
- const url = attrs[attrName];
35315
- if (!url) {
35316
- $log.warn(`${attrName}: no URL specified`);
35317
- return;
35318
- }
35319
-
35320
- const handler = (res) => {
35321
- if (isDefined(attrs.loading)) {
35322
- attrs.$set("loading", false);
35323
- }
35324
-
35325
- if (isDefined(attrs.loadingClass)) {
35326
- attrs.$removeClass(attrs.loadingClass);
35327
- }
35328
-
35329
- const html = res.data;
35330
- if (200 <= res.status && res.status <= 299) {
35331
- if (isDefined(attrs.success)) {
35332
- $parse(attrs.success)(scope, { $res: html });
35333
- }
35334
-
35335
- if (isDefined(attrs.stateSuccess)) {
35336
- $state.go(attrs.stateSuccess);
35337
- }
35338
- } else if (400 <= res.status && res.status <= 599) {
35339
- if (isDefined(attrs.error)) {
35340
- $parse(attrs.error)(scope, { $res: html });
35341
- }
35342
-
35343
- if (isDefined(attrs.stateError)) {
35344
- $state.go(attrs.stateError);
35345
- }
35346
- }
35347
-
35348
- if (isObject(html)) {
35349
- if (attrs.target) {
35350
- scope.$eval(`${attrs.target} = ${JSON.stringify(html)}`);
35351
- } else {
35352
- scope.$merge(html);
35353
- }
35354
- } else if (isString(html)) {
35355
- handleSwapResponse(html, swap, scope, attrs, element);
35356
- }
35357
- };
35358
-
35359
- if (isDefined(attrs.delay)) {
35360
- await wait(parseInt(attrs.delay) | 0);
35361
- }
35362
-
35363
- if (throttled) return;
35364
-
35365
- if (isDefined(attrs.throttle)) {
35366
- throttled = true;
35367
- attrs.$set("throttled", true);
35368
- setTimeout(() => {
35369
- attrs.$set("throttled", false);
35370
- throttled = false;
35371
- }, parseInt(attrs.throttle));
35372
- }
35373
-
35374
- if (isDefined(attrs["loading"])) {
35375
- attrs.$set("loading", true);
35376
- }
35377
-
35378
- if (isDefined(attrs["loadingClass"])) {
35379
- attrs.$addClass(attrs.loadingClass);
35380
- }
35381
-
35382
- if (method === "post" || method === "put") {
35383
- let data;
35384
- const config = {};
35385
- if (attrs.enctype) {
35386
- config.headers = {
35387
- "Content-Type": attrs["enctype"],
35388
- };
35389
- data = toKeyValue(collectFormData(element));
35390
- } else {
35391
- data = collectFormData(element);
35392
- }
35393
- $http[method](url, data, config).then(handler).catch(handler);
35394
- } else {
35395
- if (method === "get" && attrs.ngSse) {
35396
- const sseUrl = url;
35397
- const config = {
35398
- withCredentials: attrs.withCredentials === "true",
35399
- transformMessage: (data) => {
35400
- try {
35401
- return JSON.parse(data);
35402
- } catch {
35403
- return data;
35404
- }
35405
- },
35406
- onOpen: () => {
35407
- $log.info(`${attrName}: SSE connection opened to ${sseUrl}`);
35408
- if (isDefined(attrs.loading)) attrs.$set("loading", false);
35409
- if (isDefined(attrs.loadingClass))
35410
- attrs.$removeClass(attrs.loadingClass);
35411
- },
35412
- onMessage: (data) => {
35413
- const res = { status: 200, data };
35414
- handler(res);
35415
- },
35416
- onError: (err) => {
35417
- $log.error(`${attrName}: SSE error`, err);
35418
- const res = { status: 500, data: err };
35419
- handler(res);
35420
- },
35421
- onReconnect: (count) => {
35422
- $log.info(`ngSse: reconnected ${count} time(s)`);
35423
- if (attrs.onReconnect)
35424
- $parse(attrs.onReconnect)(scope, { $count: count });
35425
- },
35426
- };
35427
-
35428
- const source = $sse(sseUrl, config);
35429
-
35430
- scope.$on("$destroy", () => {
35431
- $log.info(`${attrName}: closing SSE connection`);
35432
- source.close();
35433
- });
35434
- } else {
35435
- $http[method](url).then(handler).catch(handler);
35436
- }
35437
- }
35438
- });
35439
-
35440
- if (intervalId) {
35441
- scope.$on("$destroy", () => clearInterval(intervalId));
35442
- }
35443
-
35444
- if (eventName == "load") {
35445
- element.dispatchEvent(new Event("load"));
35446
- }
35447
- },
35448
- };
35449
- };
35450
- }
35451
-
35452
35992
  ngInjectDirective.$inject = [$injectTokens.$log, $injectTokens.$injector];
35453
35993
 
35454
35994
  /**
35455
35995
  * @param {ng.LogService} $log
35456
35996
  * @param {ng.InjectorService} $injector
35457
- * @returns {import('interface.ts').Directive}
35997
+ * @returns {ng.Directive}
35458
35998
  */
35459
35999
  function ngInjectDirective($log, $injector) {
35460
36000
  return {
35461
36001
  restrict: "A",
35462
36002
  link(scope, _element, attrs) {
35463
- const expr = attrs["ngInject"];
35464
-
36003
+ const expr = attrs.ngInject;
35465
36004
  if (!expr) return;
35466
- // Match any identifier that starts with $, or ends with Service/Factory
35467
- // Example matches: $http, userService, authFactory
35468
- const replacedExpr = expr.replace(
35469
- /(\$[\w]+|[\w]+(?:Service|Factory))/g,
35470
- (match, name) => {
35471
- try {
35472
- const service = $injector.get(name);
35473
- scope.$target[name] = service;
35474
- return name;
35475
- } catch {
35476
- $log.warn(`Injectable ${name} not found in $injector`);
35477
- return match;
35478
- }
35479
- },
35480
- );
35481
- scope.$apply(replacedExpr);
36005
+ const tokens = expr
36006
+ .split(";")
36007
+ .map((s) => s.trim())
36008
+ .filter(Boolean);
36009
+
36010
+ for (const name of tokens) {
36011
+ if ($injector.has(name)) {
36012
+ scope[name] = $injector.get(name);
36013
+ } else {
36014
+ $log.warn(`Injectable ${name} not found in $injector`);
36015
+ }
36016
+ }
35482
36017
  },
35483
36018
  };
35484
36019
  }
@@ -35547,13 +36082,13 @@ class SseProvider {
35547
36082
  };
35548
36083
  }
35549
36084
 
35550
- /**
35551
- * Returns the $sse service function
35552
- * @returns {ng.SseService}
35553
- */
35554
36085
  $get = [
35555
36086
  $injectTokens.$log,
35556
- /** @param {ng.LogService} log */
36087
+ /**
36088
+ * Returns the $sse service function
36089
+ * @param {ng.LogService} log
36090
+ * @returns {ng.SseService}
36091
+ */
35557
36092
  (log) => {
35558
36093
  this.$log = log;
35559
36094
  return (url, config = {}) => {
@@ -35648,7 +36183,7 @@ class SseProvider {
35648
36183
  es.close();
35649
36184
  },
35650
36185
  connect() {
35651
- if (closed == false) {
36186
+ if (closed === false) {
35652
36187
  close();
35653
36188
  }
35654
36189
  connect();
@@ -35710,252 +36245,35 @@ function ngViewportDirective() {
35710
36245
  };
35711
36246
  }
35712
36247
 
35713
- ngWorkerDirective.$inject = ["$worker", $injectTokens.$parse, $injectTokens.$log];
35714
36248
  /**
35715
- * ngWorker directive factory
35716
- * Usage: <div ng-worker="workerName" data-params="{{ expression }}" data-on-result="callback($result)"></div>
36249
+ * @return {ng.Directive}
35717
36250
  */
35718
- function ngWorkerDirective($worker, $parse, $log) {
36251
+ function ngWasmDirective() {
35719
36252
  return {
35720
- restrict: "A",
35721
- link(scope, element, attrs) {
35722
- const workerName = attrs.ngWorker;
35723
- if (!workerName) {
35724
- $log.warn("ngWorker: missing worker name");
35725
- return;
35726
- }
35727
-
35728
- const eventName = attrs.trigger || getEventNameForElement(element);
35729
-
35730
- let throttled = false;
35731
- let intervalId;
35732
-
35733
- if (isDefined(attrs.latch)) {
35734
- attrs.$observe(
35735
- "latch",
35736
- callBackAfterFirst(() => element.dispatchEvent(new Event(eventName))),
35737
- );
35738
- }
35739
-
35740
- if (isDefined(attrs.interval)) {
35741
- element.dispatchEvent(new Event(eventName));
35742
- intervalId = setInterval(
35743
- () => element.dispatchEvent(new Event(eventName)),
35744
- parseInt(attrs.interval) || 1000,
35745
- );
35746
- }
35747
-
35748
- const worker = $worker(workerName, {
35749
- onMessage: (result) => {
35750
- if (isDefined(attrs.dataOnResult)) {
35751
- $parse(attrs.dataOnResult)(scope, { $result: result });
35752
- } else {
35753
- const swap = attrs.swap || "innerHTML";
35754
- handleSwap(result, swap, element);
35755
- }
35756
- },
35757
- onError: (err) => {
35758
- $log.error(`[ng-worker:${workerName}]`, err);
35759
- if (isDefined(attrs.dataOnError)) {
35760
- $parse(attrs.dataOnError)(scope, { $error: err });
35761
- } else {
35762
- element.textContent = "Error";
35763
- }
35764
- },
35765
- });
35766
-
35767
- element.addEventListener(eventName, async () => {
35768
- if (element.disabled) return;
35769
-
35770
- if (isDefined(attrs.delay)) {
35771
- await wait(parseInt(attrs.delay) || 0);
35772
- }
35773
-
35774
- if (throttled) return;
35775
-
35776
- if (isDefined(attrs.throttle)) {
35777
- throttled = true;
35778
- attrs.$set("throttled", true);
35779
- setTimeout(() => {
35780
- attrs.$set("throttled", false);
35781
- throttled = false;
35782
- }, parseInt(attrs.throttle));
35783
- }
35784
-
35785
- let params;
35786
- try {
35787
- params = attrs.params ? scope.$eval(attrs.params) : undefined;
35788
- } catch (err) {
35789
- $log.error("ngWorker: failed to evaluate data-params", err);
35790
- params = undefined;
35791
- }
35792
-
35793
- worker.post(params);
35794
- });
35795
-
35796
- if (intervalId) {
35797
- scope.$on("$destroy", () => clearInterval(intervalId));
35798
- }
35799
-
35800
- if (eventName === "load") {
35801
- element.dispatchEvent(new Event("load"));
35802
- }
36253
+ async link($scope, _, $attrs) {
36254
+ $scope.$target[$attrs.as || "wasm"] = (
36255
+ await instantiateWasm($attrs.src)
36256
+ ).exports;
35803
36257
  },
35804
36258
  };
35805
36259
  }
35806
36260
 
35807
36261
  /**
35808
- * Swap result into DOM based on strategy
35809
- */
35810
- function handleSwap(result, swap, element) {
35811
- switch (swap) {
35812
- case "outerHTML": {
35813
- const parent = element.parentNode;
35814
- if (!parent) return;
35815
- const temp = document.createElement("div");
35816
- temp.innerHTML = result;
35817
- parent.replaceChild(temp.firstChild, element);
35818
- break;
35819
- }
35820
- case "textContent":
35821
- element.textContent = result;
35822
- break;
35823
- case "beforebegin":
35824
- element.insertAdjacentHTML("beforebegin", result);
35825
- break;
35826
- case "afterbegin":
35827
- element.insertAdjacentHTML("afterbegin", result);
35828
- break;
35829
- case "beforeend":
35830
- element.insertAdjacentHTML("beforeend", result);
35831
- break;
35832
- case "afterend":
35833
- element.insertAdjacentHTML("afterend", result);
35834
- break;
35835
- case "innerHTML":
35836
- default:
35837
- element.innerHTML = result;
35838
- break;
35839
- }
35840
- }
35841
-
35842
- /**
35843
- * Worker Provider
35844
- *
35845
- * Usage:
35846
- * const worker = $worker('./math.worker.js', {
35847
- * onMessage: (data) => console.log('Result:', data),
35848
- * onError: (err) => console.error('Worker error:', err),
35849
- * autoTerminate: false,
35850
- * transformMessage: (d) => d,
35851
- * });
35852
- *
35853
- * worker.post({ action: 'fib', n: 20 });
35854
- * worker.terminate();
36262
+ * @return {ng.Directive}
35855
36263
  */
35856
- class WorkerProvider {
35857
- /**
35858
- * @type {ng.LogService}
35859
- */
35860
- $log;
35861
- constructor() {
35862
- /**
35863
- * Optional provider-level defaults
35864
- * @type {ng.WorkerConfig}
35865
- */
35866
- this.defaults = {
35867
- autoTerminate: false,
35868
- transformMessage(data) {
35869
- try {
35870
- return JSON.parse(data);
35871
- } catch {
35872
- return data;
35873
- }
35874
- },
35875
- };
35876
- }
35877
-
35878
- /**
35879
- * Returns the $worker service function
35880
- * @returns {ng.WorkerService}
35881
- */
35882
- $get = [
35883
- $injectTokens.$log,
35884
- /** @param {ng.LogService} log */
35885
- (log) => {
35886
- this.$log = log;
35887
- return (scriptPath, config = {}) => {
35888
- const merged = { ...this.defaults, ...config };
35889
- return this.#createWorker(scriptPath, merged);
35890
- };
36264
+ function ngScopeDirective() {
36265
+ return {
36266
+ scope: false,
36267
+ async link($scope, _, $attrs) {
36268
+ $scope.$scopename = $attrs.ngScope;
35891
36269
  },
35892
- ];
35893
-
35894
- /**
35895
- * Creates a managed Web Worker instance
35896
- * @param {string | URL} scriptPath
35897
- * @param {ng.WorkerConfig} config
35898
- * @returns {import("./interface.ts").WorkerConnection}
35899
- */
35900
- #createWorker(scriptPath, config) {
35901
- if (!scriptPath) throw new Error("Worker script path required");
35902
-
35903
- let worker = new Worker(scriptPath, { type: "module" });
35904
- let terminated = false;
35905
-
35906
- const reconnect = () => {
35907
- if (terminated) return;
35908
- this.$log.info("Worker: restarting...");
35909
- worker.terminate();
35910
- worker = new Worker(scriptPath, { type: "module" });
35911
- wire(worker);
35912
- };
35913
-
35914
- const wire = (w) => {
35915
- w.onmessage = (e) => {
35916
- let data = e.data;
35917
- try {
35918
- data = config.transformMessage ? config.transformMessage(data) : data;
35919
- } catch {
35920
- /* no-op */
35921
- }
35922
- config.onMessage?.(data, e);
35923
- };
35924
-
35925
- w.onerror = (err) => {
35926
- config.onError?.(err);
35927
- if (config.autoRestart) reconnect();
35928
- };
35929
- };
35930
-
35931
- wire(worker);
35932
- let that = this;
35933
- return {
35934
- post(data) {
35935
- if (terminated) return that.$log.warn("Worker already terminated");
35936
- try {
35937
- worker.postMessage(data);
35938
- } catch (err) {
35939
- that.$log.error("Worker post failed", err);
35940
- }
35941
- },
35942
- terminate() {
35943
- terminated = true;
35944
- worker.terminate();
35945
- },
35946
- restart() {
35947
- if (terminated)
35948
- return that.$log.warn("Worker cannot restart after terminate");
35949
- reconnect();
35950
- },
35951
- };
35952
- }
36270
+ };
35953
36271
  }
35954
36272
 
35955
36273
  /**
35956
36274
  * Initializes core `ng` module.
35957
- * @param {import('./angular.js').Angular} angular
35958
- * @returns {import('./core/di/ng-module.js').NgModule} `ng` module
36275
+ * @param {ng.Angular} angular
36276
+ * @returns {ng.NgModule} `ng` module
35959
36277
  */
35960
36278
  function registerNgModule(angular) {
35961
36279
  return angular
@@ -35964,14 +36282,14 @@ function registerNgModule(angular) {
35964
36282
  [],
35965
36283
  [
35966
36284
  $injectTokens.$provide,
35967
- /** @param {import("./interface.ts").Provider} $provide */
36285
+ /** @param {ng.ProvideService} $provide */
35968
36286
  ($provide) => {
35969
36287
  // $$sanitizeUriProvider needs to be before $compileProvider as it is used by it.
35970
36288
  $provide.provider({
35971
36289
  $$sanitizeUri: SanitizeUriProvider,
35972
36290
  });
35973
- $provide.value("$window", window);
35974
- $provide.value("$document", document);
36291
+ $provide.value($injectTokens.$window, window);
36292
+ $provide.value($injectTokens.$document, document);
35975
36293
  $provide
35976
36294
  .provider($injectTokens.$compile, CompileProvider)
35977
36295
  .directive({
@@ -35984,6 +36302,7 @@ function registerNgModule(angular) {
35984
36302
  ngBind: ngBindDirective,
35985
36303
  ngBindHtml: ngBindHtmlDirective,
35986
36304
  ngBindTemplate: ngBindTemplateDirective,
36305
+ ngChannel: ngChannelDirective,
35987
36306
  ngClass: ngClassDirective,
35988
36307
  ngClassEven: ngClassEvenDirective,
35989
36308
  ngClassOdd: ngClassOddDirective,
@@ -36030,12 +36349,15 @@ function registerNgModule(angular) {
36030
36349
  ngValue: ngValueDirective,
36031
36350
  ngModelOptions: ngModelOptionsDirective,
36032
36351
  ngViewport: ngViewportDirective,
36352
+ ngWasm: ngWasmDirective,
36033
36353
  ngWorker: ngWorkerDirective,
36354
+ ngScope: ngScopeDirective,
36034
36355
  })
36035
36356
  .directive({
36036
36357
  input: hiddenInputBrowserCacheDirective,
36037
36358
  ngAnimateSwap: ngAnimateSwapDirective,
36038
36359
  ngAnimateChildren: $$AnimateChildrenDirective,
36360
+ // aria directives
36039
36361
  ngChecked: ngCheckedAriaDirective,
36040
36362
  ngClick: ngClickAriaDirective,
36041
36363
  ngDblclick: ngDblclickAriaDirective,
@@ -36047,12 +36369,12 @@ function registerNgModule(angular) {
36047
36369
  ngReadonly: ngReadonlyAriaDirective,
36048
36370
  ngRequired: ngRequiredAriaDirective,
36049
36371
  ngValue: ngValueAriaDirective,
36372
+ // router directives
36050
36373
  ngSref: $StateRefDirective,
36051
36374
  ngSrefActive: $StateRefActiveDirective,
36052
36375
  ngSrefActiveEq: $StateRefActiveDirective,
36053
36376
  ngState: $StateRefDynamicDirective,
36054
36377
  ngView: ngView,
36055
- ngChannel: ngChannelDirective,
36056
36378
  })
36057
36379
  .directive({
36058
36380
  ngView: $ViewDirectiveFill,
@@ -36070,8 +36392,6 @@ function registerNgModule(angular) {
36070
36392
  $$animateJsDriver: AnimateJsDriverProvider,
36071
36393
  $$animateCache: AnimateCacheProvider,
36072
36394
  $$animateQueue: AnimateQueueProvider,
36073
- $$AnimateRunner: AnimateRunnerFactoryProvider,
36074
- $$animateAsyncRun: AnimateAsyncRunFactoryProvider,
36075
36395
  $controller: ControllerProvider,
36076
36396
  $exceptionHandler: ExceptionHandlerProvider,
36077
36397
  $filter: FilterProvider,
@@ -36098,7 +36418,6 @@ function registerNgModule(angular) {
36098
36418
  $url: UrlService,
36099
36419
  $stateRegistry: StateRegistryProvider,
36100
36420
  $eventBus: PubSubProvider,
36101
- $worker: WorkerProvider,
36102
36421
  });
36103
36422
  },
36104
36423
  ],
@@ -36124,20 +36443,36 @@ class Angular {
36124
36443
  constructor() {
36125
36444
  this.$cache = Cache;
36126
36445
 
36127
- /** @type {import('./services/pubsub/pubsub.js').PubSub} */
36446
+ /** @type {ng.PubSubService} */
36128
36447
  this.$eventBus = EventBus;
36129
36448
 
36130
36449
  /**
36131
36450
  * @type {string} `version` from `package.json`
36132
36451
  */
36133
- this.version = "0.10.0"; //inserted via rollup plugin
36452
+ this.version = "0.12.0"; //inserted via rollup plugin
36134
36453
 
36135
36454
  /** @type {!Array<string|any>} */
36136
36455
  this.bootsrappedModules = [];
36137
36456
 
36457
+ /**
36458
+ * Gets the controller instance for a given element, if exists. Defaults to "ngControllerController"
36459
+ *
36460
+ * @type {(element: Element, name: string?) => ng.Scope|undefined}
36461
+ */
36138
36462
  this.getController = getController;
36463
+
36464
+ /**
36465
+ * Return instance of InjectorService attached to element
36466
+ * @type {(Element) => ng.InjectorService}
36467
+ */
36139
36468
  this.getInjector = getInjector;
36469
+
36470
+ /**
36471
+ * Gets scope for a given element.
36472
+ * @type {(Element) => ng.Scope}
36473
+ */
36140
36474
  this.getScope = getScope;
36475
+
36141
36476
  this.errorHandlingConfig = errorHandlingConfig;
36142
36477
  this.$t = $injectTokens;
36143
36478
 
@@ -36145,6 +36480,70 @@ class Angular {
36145
36480
  registerNgModule(this);
36146
36481
  }
36147
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
+
36148
36547
  /**
36149
36548
  * Use this function to manually start up AngularTS application.
36150
36549
  *
@@ -36229,8 +36628,10 @@ class Angular {
36229
36628
  * @param {ng.InjectorService} $injector
36230
36629
  */
36231
36630
  (scope, el, compile, $injector) => {
36631
+ this.$rootScope = scope;
36232
36632
  // ng-route deps
36233
- this.$injector = $injector;
36633
+ this.$injector = $injector; // TODO refactor away as this as this prevents multiple apps from being used
36634
+
36234
36635
  setCacheData(el, "$injector", $injector);
36235
36636
 
36236
36637
  const compileFn = compile(el);
@@ -36311,70 +36712,30 @@ class Angular {
36311
36712
  }
36312
36713
 
36313
36714
  /**
36715
+ * Retrieves a scope by its registered name and returns its Proxy wrapper.
36314
36716
  *
36315
- * The `angular.module` is a global place for creating, registering and retrieving AngularTS
36316
- * modules.
36317
- * All modules (AngularTS core or 3rd party) that should be available to an application must be
36318
- * registered using this mechanism.
36319
- *
36320
- * Passing one argument retrieves an existing {@link import('./interface.ts').Module},
36321
- * whereas passing more than one argument creates a new {@link import('./interface.ts').Module}
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.
36322
36721
  *
36323
- *
36324
- * # Module
36325
- *
36326
- * A module is a collection of services, directives, controllers, filters, and configuration information.
36327
- * `angular.module` is used to configure the {@link auto.$injector $injector}.
36328
- *
36329
- * ```js
36330
- * // Create a new module
36331
- * let myModule = angular.module('myModule', []);
36332
- *
36333
- * // register a new service
36334
- * myModule.value('appName', 'MyCoolApp');
36335
- *
36336
- * // configure existing services inside initialization blocks.
36337
- * myModule.config(['$locationProvider', function($locationProvider) {
36338
- * // Configure existing providers
36339
- * $locationProvider.hashPrefix('!');
36340
- * }]);
36341
- * ```
36342
- *
36343
- * Then you can create an injector and load your modules like this:
36344
- *
36345
- * ```js
36346
- * let injector = angular.injector(['ng', 'myModule'])
36347
- * ```
36348
- *
36349
- * However it's more likely that you'll just use
36350
- * {@link ng.directive:ngApp ngApp} or
36351
- * {@link angular.bootstrap} to simplify this process for you.
36352
- *
36353
- * @param {string} name The name of the module to create or retrieve.
36354
- * @param {Array.<string>} [requires] If specified then new module is being created. If
36355
- * unspecified then the module is being retrieved for further configuration.
36356
- * @param {import("./interface.ts").Injectable<any>} [configFn] Optional configuration function for the module that gets
36357
- * passed to {@link NgModule.config NgModule.config()}.
36358
- * @returns {NgModule} A newly registered module.
36722
+ * @param {string} name
36723
+ * @returns {ProxyHandler<ng.Scope>|undefined}
36359
36724
  */
36360
- module(name, requires, configFn) {
36361
- assertNotHasOwnProperty(name, "module");
36362
- if (requires && hasOwn(modules, name)) {
36363
- modules[name] = null;
36725
+ getScopeByName(name) {
36726
+ const scope = this.$rootScope.$searchByName(name);
36727
+ if (scope) {
36728
+ return scope.$proxy;
36364
36729
  }
36365
- return ensure(modules, name, () => {
36366
- if (!requires) {
36367
- throw $injectorMinErr(
36368
- "nomod",
36369
- "Module '{0}' is not available. Possibly misspelled or not loaded",
36370
- name,
36371
- );
36372
- }
36373
- return new NgModule(name, requires, configFn);
36374
- });
36375
36730
  }
36376
36731
  }
36377
36732
 
36733
+ /**
36734
+ * @param {Object.<string, NgModule>} obj
36735
+ * @param {string} name
36736
+ * @param {Function} factory
36737
+ * @returns {NgModule}
36738
+ */
36378
36739
  function ensure(obj, name, factory) {
36379
36740
  return obj[name] || (obj[name] = factory());
36380
36741
  }