@angular-wave/angular.ts 0.7.8 → 0.8.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 (285) hide show
  1. package/@types/core/parse/parse.d.ts +6 -7
  2. package/@types/directive/bind/bind.d.ts +2 -1
  3. package/@types/index.d.ts +1 -1
  4. package/@types/interface.d.ts +3 -1
  5. package/@types/{public.d.ts → ng.d.ts} +2 -2
  6. package/@types/router/globals.d.ts +1 -1
  7. package/@types/router/path/path-utils.d.ts +8 -11
  8. package/@types/router/state/interface.d.ts +1 -1
  9. package/@types/router/state/state-object.d.ts +1 -1
  10. package/@types/router/state/state-service.d.ts +8 -7
  11. package/@types/router/state-filters.d.ts +24 -2
  12. package/@types/router/transition/transition.d.ts +12 -15
  13. package/@types/router/url/url-matcher.d.ts +3 -3
  14. package/@types/router/url/url-rule.d.ts +1 -0
  15. package/@types/router/url/url-rules.d.ts +26 -6
  16. package/@types/router/url/url-service.d.ts +28 -38
  17. package/@types/services/http/http.d.ts +48 -1
  18. package/@types/services/http-backend/http-backend.d.ts +48 -35
  19. package/@types/services/location/interface.d.ts +55 -0
  20. package/@types/services/location/location.d.ts +225 -252
  21. package/@types/shared/common.d.ts +0 -2
  22. package/@types/shared/interface.d.ts +0 -4
  23. package/@types/{router/common → shared}/queue.d.ts +2 -2
  24. package/@types/shared/url-utils/interface.d.ts +0 -1
  25. package/@types/shared/url-utils/url-utils.d.ts +0 -5
  26. package/@types/shared/utils.d.ts +29 -6
  27. package/Makefile +6 -3
  28. package/dist/angular-ts.esm.js +960 -1062
  29. package/dist/angular-ts.umd.js +960 -1062
  30. package/dist/angular-ts.umd.min.js +1 -1
  31. package/docs/assets/scss/index.scss +23 -0
  32. package/docs/content/_index.md +9 -8
  33. package/docs/content/docs/_index.md +1 -1
  34. package/docs/content/docs/directive/app.md +1 -1
  35. package/docs/content/docs/directive/bind.md +1 -1
  36. package/docs/content/docs/directive/blur.md +1 -1
  37. package/docs/content/docs/directive/channel.md +2 -2
  38. package/docs/content/docs/directive/class-even.md +1 -1
  39. package/docs/content/docs/directive/class-odd.md +1 -1
  40. package/docs/content/docs/directive/class.md +1 -1
  41. package/docs/content/docs/directive/click.md +1 -1
  42. package/docs/content/docs/directive/copy.md +1 -1
  43. package/docs/content/docs/directive/cut.md +1 -1
  44. package/docs/content/docs/directive/dblclick.md +1 -1
  45. package/docs/content/docs/directive/focus.md +1 -1
  46. package/docs/content/docs/directive/get.md +3 -3
  47. package/docs/content/docs/directive/keydown.md +1 -1
  48. package/docs/content/docs/directive/keyup.md +1 -1
  49. package/docs/content/docs/directive/load.md +1 -1
  50. package/docs/content/docs/directive/mousedown.md +1 -1
  51. package/docs/content/docs/directive/mouseenter.md +1 -1
  52. package/docs/content/docs/directive/mouseleave.md +1 -1
  53. package/docs/content/docs/directive/mousemove.md +1 -1
  54. package/docs/content/docs/directive/mouseout.md +1 -1
  55. package/docs/content/docs/directive/mouseover.md +1 -1
  56. package/docs/content/docs/directive/mouseup.md +1 -1
  57. package/docs/content/docs/directive/non-bindable.md +28 -0
  58. package/docs/content/docs/provider/locationProvider.md +26 -0
  59. package/docs/content/docs/provider/templateCacheProvider.md +2 -2
  60. package/docs/content/docs/service/location.md +57 -0
  61. package/docs/content/docs/service/url.md +5 -0
  62. package/docs/layouts/partials/hooks/head-end.html +1 -1
  63. package/docs/layouts/shortcodes/version.html +1 -0
  64. package/docs/static/examples/counter/counter-test.html +0 -4
  65. package/docs/static/examples/eventbus/eventbus-test.html +0 -4
  66. package/docs/static/examples/ng-non-bindable/ng-non-bindable-test.html +13 -0
  67. package/docs/static/examples/ng-non-bindable/ng-non-bindable.html +3 -0
  68. package/docs/static/examples/ng-non-bindable/ng-non-bindable.test.js +11 -0
  69. package/docs/static/typedoc/assets/highlight.css +6 -6
  70. package/docs/static/typedoc/assets/navigation.js +1 -1
  71. package/docs/static/typedoc/assets/search.js +1 -1
  72. package/docs/static/typedoc/classes/Location.html +55 -0
  73. package/docs/static/typedoc/classes/LocationProvider.html +20 -0
  74. package/docs/static/typedoc/index.html +1 -1
  75. package/docs/static/typedoc/interfaces/DefaultPorts.html +5 -0
  76. package/docs/static/typedoc/interfaces/Html5Mode.html +23 -0
  77. package/docs/static/typedoc/interfaces/Provider.html +2 -1
  78. package/docs/static/typedoc/interfaces/UrlParts.html +9 -0
  79. package/docs/static/typedoc/types/AnnotatedFactory.html +1 -1
  80. package/docs/static/typedoc/types/Expression.html +1 -1
  81. package/docs/static/typedoc/types/UrlChangeListener.html +5 -0
  82. package/docs/static/version.js +13 -0
  83. package/docs/test-results/.last-run.json +4 -0
  84. package/docs/test-results/static-examples-counter-counter-counter-example/error-context.md +50 -0
  85. package/package.json +1 -1
  86. package/src/{loader.js → angular.js} +1 -1
  87. package/src/angular.spec.js +189 -21
  88. package/src/animations/animate-css.js +17 -18
  89. package/src/animations/animate.spec.js +1 -1
  90. package/src/animations/shared.js +2 -3
  91. package/src/binding.spec.js +1 -1
  92. package/src/core/compile/compile.js +4 -7
  93. package/src/core/compile/compile.spec.js +1 -1
  94. package/src/core/controller/controller.spec.js +1 -1
  95. package/src/core/controller/controller.test.js +1 -0
  96. package/src/core/di/injector.js +7 -8
  97. package/src/core/di/injector.spec.js +2 -2
  98. package/src/core/di/injector.test.js +2 -2
  99. package/src/core/di/internal-injector.js +3 -6
  100. package/src/core/filter/filter.js +1 -1
  101. package/src/core/filter/filter.spec.js +1 -1
  102. package/src/core/filter/filter.test.js +1 -0
  103. package/src/core/interpolate/interpolate.js +4 -6
  104. package/src/core/interpolate/interpolate.spec.js +1 -1
  105. package/src/core/interpolate/interpolate.test.js +1 -0
  106. package/src/core/parse/ast/ast.spec.js +1 -1
  107. package/src/core/parse/ast/ast.test.js +1 -1
  108. package/src/core/parse/lexer/lexer.spec.js +1 -1
  109. package/src/core/parse/parse.js +150 -146
  110. package/src/core/parse/parse.spec.js +17 -16
  111. package/src/core/prop.spec.js +1 -1
  112. package/src/core/root-element.spec.js +1 -1
  113. package/src/core/scope/scope.js +10 -11
  114. package/src/core/scope/scope.spec.js +3 -4
  115. package/src/directive/aria/aria.spec.js +1 -1
  116. package/src/directive/aria/aria.test.js +1 -0
  117. package/src/directive/attrs/attrs.spec.js +1 -1
  118. package/src/directive/attrs/attrs.test.js +1 -0
  119. package/src/directive/attrs/boolean.spec.js +1 -1
  120. package/src/directive/attrs/boolean.test.js +1 -0
  121. package/src/directive/attrs/element-style.spec.js +1 -1
  122. package/src/directive/attrs/element-style.test.js +1 -0
  123. package/src/directive/attrs/src.spec.js +1 -1
  124. package/src/directive/attrs/src.test.js +1 -0
  125. package/src/directive/bind/bind-html.spec.js +1 -1
  126. package/src/directive/bind/bind.js +1 -0
  127. package/src/directive/bind/bind.spec.js +1 -1
  128. package/src/directive/bind/bind.test.js +1 -0
  129. package/src/directive/channel/channel.spec.js +1 -1
  130. package/src/directive/channel/channel.test.js +1 -0
  131. package/src/directive/class/class.spec.js +1 -1
  132. package/src/directive/class/class.test.js +1 -0
  133. package/src/directive/cloak/cloak.spec.js +1 -1
  134. package/src/directive/cloak/cloak.test.js +1 -0
  135. package/src/directive/controller/controller.spec.js +1 -1
  136. package/src/directive/controller/controller.test.js +1 -0
  137. package/src/directive/events/click.spec.js +1 -1
  138. package/src/directive/events/event.spec.js +1 -1
  139. package/src/directive/events/events.test.js +1 -0
  140. package/src/directive/form/form.js +8 -5
  141. package/src/directive/form/form.spec.js +1 -1
  142. package/src/directive/form/form.test.js +1 -0
  143. package/src/directive/http/delete.spec.js +1 -1
  144. package/src/directive/http/form-test.html +18 -0
  145. package/src/directive/http/get.spec.js +1 -1
  146. package/src/directive/http/http.js +12 -3
  147. package/src/directive/http/post.spec.js +504 -9
  148. package/src/directive/http/put.spec.js +1 -1
  149. package/src/directive/if/if.spec.js +1 -1
  150. package/src/directive/include/include.spec.js +1 -1
  151. package/src/directive/init/init.spec.js +1 -1
  152. package/src/directive/init/init.test.js +1 -0
  153. package/src/directive/input/input.js +13 -15
  154. package/src/directive/input/input.spec.js +1 -2
  155. package/src/directive/input/input.test.js +1 -0
  156. package/src/directive/messages/messages.spec.js +1 -1
  157. package/src/directive/messages/messages.test.js +1 -0
  158. package/src/directive/model/model.js +13 -13
  159. package/src/directive/model/model.spec.js +1 -1
  160. package/src/directive/model/model.test.js +1 -0
  161. package/src/directive/model-options/model-option.test.js +1 -0
  162. package/src/directive/model-options/model-options.js +1 -1
  163. package/src/directive/model-options/model-options.spec.js +1 -1
  164. package/src/directive/non-bindable/non-bindable.spec.js +1 -1
  165. package/src/directive/non-bindable/non-bindable.test.js +1 -0
  166. package/src/directive/observe/observe.spec.js +1 -1
  167. package/src/directive/observe/observe.test.js +1 -0
  168. package/src/directive/on/on.spec.js +1 -1
  169. package/src/directive/on/on.test.js +1 -0
  170. package/src/directive/options/options.spec.js +1 -1
  171. package/src/directive/options/options.test.js +1 -0
  172. package/src/directive/ref/href.spec.js +1 -1
  173. package/src/directive/ref/href.test.js +2 -0
  174. package/src/directive/ref/ref.spec.js +1 -1
  175. package/src/directive/repeat/repeat.spec.js +2 -3
  176. package/src/directive/repeat/repeat.test.js +1 -0
  177. package/src/directive/script/script.spec.js +1 -1
  178. package/src/directive/script/script.test.js +1 -0
  179. package/src/directive/select/select.js +1 -1
  180. package/src/directive/select/select.spec.js +1 -1
  181. package/src/directive/select/select.test.js +1 -0
  182. package/src/directive/setter/setter.spec.js +1 -1
  183. package/src/directive/setter/setter.test.js +1 -0
  184. package/src/directive/show-hide/show-hide.spec.js +1 -1
  185. package/src/directive/show-hide/show-hide.test.js +1 -0
  186. package/src/directive/style/style.spec.js +1 -1
  187. package/src/directive/style/style.test.js +1 -0
  188. package/src/directive/switch/switch.spec.js +1 -1
  189. package/src/directive/switch/switch.test.js +1 -0
  190. package/src/directive/validators/validators.js +82 -84
  191. package/src/directive/validators/validators.spec.js +5 -4
  192. package/src/directive/validators/validators.test.js +1 -0
  193. package/src/filters/filter.spec.js +1 -1
  194. package/src/filters/filters.spec.js +1 -1
  195. package/src/filters/limit-to.js +2 -3
  196. package/src/filters/limit-to.spec.js +1 -1
  197. package/src/filters/order-by.spec.js +1 -1
  198. package/src/index.js +1 -1
  199. package/src/injection-tokens.js +5 -1
  200. package/src/interface.ts +3 -1
  201. package/src/loader.md +0 -155
  202. package/src/{public.js → ng.js} +7 -8
  203. package/src/{public.spec.js → ng.spec.js} +1 -1
  204. package/src/router/directives/state-directives.spec.js +8 -7
  205. package/src/router/directives/view-directive.js +2 -8
  206. package/src/router/directives/view-directive.spec.js +8 -9
  207. package/src/router/{common/common.html → glob/glob.html} +2 -3
  208. package/src/router/{common/common.test.js → glob/glob.test.js} +2 -1
  209. package/src/router/globals.js +1 -1
  210. package/src/router/path/path-utils.js +5 -0
  211. package/src/router/router-test-hashbang.html +45 -0
  212. package/src/router/services.spec.js +5 -6
  213. package/src/router/state/interface.ts +1 -1
  214. package/src/router/state/state-builder.js +3 -3
  215. package/src/router/state/state-builder.spec.js +1 -1
  216. package/src/router/state/state-object.js +1 -1
  217. package/src/router/state/state-registry.js +2 -2
  218. package/src/router/state/state-service.js +13 -10
  219. package/src/router/state/state.spec.js +23 -22
  220. package/src/router/state/state.test.js +1 -0
  221. package/src/router/state/views.js +1 -1
  222. package/src/router/state-filter.spec.js +1 -1
  223. package/src/router/state-filters.js +13 -9
  224. package/src/router/template-factory.js +5 -4
  225. package/src/router/template-factory.spec.js +1 -1
  226. package/src/router/transition/hook-registry.js +1 -1
  227. package/src/router/transition/transition-service.js +6 -5
  228. package/src/router/transition/transition.js +4 -4
  229. package/src/router/url/url-matcher.js +3 -3
  230. package/src/router/url/url-rule.js +1 -0
  231. package/src/router/url/url-rules.js +8 -5
  232. package/src/router/url/url-service.js +77 -76
  233. package/src/router/url/url-service.spec.js +55 -39
  234. package/src/router/url/url.test.js +1 -0
  235. package/src/router/view/view.js +4 -5
  236. package/src/router/view/view.spec.js +10 -12
  237. package/src/router/view/view.test.js +1 -0
  238. package/src/router/view-hook.spec.js +1 -1
  239. package/src/router/view-scroll.spec.js +1 -1
  240. package/src/services/anchor-scroll.html +2 -2
  241. package/src/services/anchor-scroll.js +5 -4
  242. package/src/services/http/http.js +9 -4
  243. package/src/services/http/http.spec.js +2 -7
  244. package/src/services/http/template-request.spec.js +1 -1
  245. package/src/services/http-backend/http-backend.js +51 -77
  246. package/src/services/http-backend/http-backend.spec.js +1 -2
  247. package/src/services/http-backend/http-backend.test.js +1 -0
  248. package/src/services/location/interface.ts +62 -0
  249. package/src/services/location/location.js +433 -520
  250. package/src/services/location/location.spec.js +909 -530
  251. package/src/services/location/location.test.js +2 -2
  252. package/src/services/log/log.spec.js +1 -1
  253. package/src/services/log/log.test.js +1 -0
  254. package/src/services/pubsub/pubsub.spec.js +1 -1
  255. package/src/services/sce/sce.js +5 -7
  256. package/src/services/sce/sce.md +2 -2
  257. package/src/services/sce/sce.spec.js +1 -1
  258. package/src/services/template-cache/template-cache.spec.js +1 -1
  259. package/src/services/template-cache/template-cache.test.js +1 -0
  260. package/src/shared/common.js +0 -5
  261. package/src/shared/common.spec.js +1 -1
  262. package/src/shared/interface.ts +0 -4
  263. package/src/{router/common → shared}/queue.js +7 -7
  264. package/src/shared/shared.html +1 -0
  265. package/src/shared/shared.test.js +1 -0
  266. package/src/shared/url-utils/interface.ts +0 -2
  267. package/src/shared/url-utils/url-utils.js +6 -30
  268. package/src/shared/url-utils/url-utils.spec.js +10 -9
  269. package/src/shared/utils.js +32 -9
  270. package/src/shared/utils.spec.js +35 -1
  271. package/src/src.html +1 -2
  272. package/typedoc.json +0 -1
  273. package/utils/express.js +27 -1
  274. package/utils/version.cjs +23 -0
  275. package/@types/router/state-provider.d.ts +0 -123
  276. package/src/directive/non-bindable/non-bindable.md +0 -17
  277. package/src/loader.spec.js +0 -169
  278. package/src/router/state-provider.js +0 -146
  279. package/src/services/location/location.md +0 -114
  280. package/src/shared/url-utils/url-utils.md +0 -46
  281. /package/@types/{loader.d.ts → angular.d.ts} +0 -0
  282. /package/@types/router/{common → glob}/glob.d.ts +0 -0
  283. /package/src/router/{common → glob}/glob.js +0 -0
  284. /package/src/router/{common → glob}/glob.spec.js +0 -0
  285. /package/src/{router/common → shared}/queue.spec.js +0 -0
@@ -1,4 +1,4 @@
1
- /* Version: 0.7.8 - July 17, 2025 02:51:18 */
1
+ /* Version: 0.8.0 - August 2, 2025 17:22:29 */
2
2
  (function (global, factory) {
3
3
  typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :
4
4
  typeof define === 'function' && define.amd ? define(['exports'], factory) :
@@ -355,14 +355,6 @@
355
355
  return baseExtend(dst, src);
356
356
  }
357
357
 
358
- /**
359
- * @param {string} str
360
- * @returns {number}
361
- */
362
- function toInt(str) {
363
- return parseInt(str, 10);
364
- }
365
-
366
358
  /**
367
359
  * @param {any} num
368
360
  * @returns {boolean}
@@ -795,7 +787,7 @@
795
787
  try {
796
788
  return decodeURIComponent(value);
797
789
  } catch {
798
- return;
790
+ /* empty */
799
791
  }
800
792
  }
801
793
 
@@ -809,6 +801,7 @@
809
801
  * unreserved = ALPHA / DIGIT / "-" / "." / "_" / "~"
810
802
  * sub-delims = "!" / "$" / "&" / "'" / "(" / ")"
811
803
  * / "*" / "+" / "," / ";" / "="
804
+ * @param {string} val
812
805
  */
813
806
  function encodeUriSegment(val) {
814
807
  return encodeUriQuery(val, true)
@@ -1182,6 +1175,36 @@
1182
1175
  return new Promise((resolve) => setTimeout(resolve, t));
1183
1176
  }
1184
1177
 
1178
+ /**
1179
+ * Checks if a given string starts with a specified substring.
1180
+ *
1181
+ * This is a simple polyfill-like function that mimics the behavior of
1182
+ * `String.prototype.startsWith` without using the built-in method.
1183
+ *
1184
+ * @param {string} str - The full string to evaluate.
1185
+ * @param {string} search - The substring to test against the beginning of `str`.
1186
+ * @returns {boolean} `true` if `str` starts with `search`, otherwise `false`.
1187
+ *
1188
+ * @example
1189
+ * startsWith("hello world", "hello");
1190
+ * // returns true
1191
+ *
1192
+ * @example
1193
+ * startsWith("hello world", "world");
1194
+ * // returns false
1195
+ *
1196
+ * @example
1197
+ * startsWith("test", "");
1198
+ * // returns true (empty search string always matches)
1199
+ *
1200
+ * @example
1201
+ * startsWith("abc", "abcd");
1202
+ * // returns false
1203
+ */
1204
+ function startsWith(str, search) {
1205
+ return str.slice(0, search.length) === search;
1206
+ }
1207
+
1185
1208
  /**
1186
1209
  * Expando cache for adding properties to DOM nodes with JavaScript.
1187
1210
  * This used to be an Object in JQLite decorator, but swapped out for a Map
@@ -1765,6 +1788,9 @@
1765
1788
  * @type Readonly<Record<string, string>>
1766
1789
  */
1767
1790
  const $injectTokens = Object.freeze({
1791
+ $attrs: "$attrs",
1792
+ $scope: "$scope",
1793
+ $element: "$element",
1768
1794
  $$AnimateRunner: "$$AnimateRunner",
1769
1795
  $$animateAsyncRun: "$$animateAsyncRun",
1770
1796
  $$animateCache: "$$animateCache",
@@ -1793,6 +1819,7 @@
1793
1819
  $ngViewScroll: "$ngViewScroll",
1794
1820
  $parse: "$parse",
1795
1821
  $rootScope: "$rootScope",
1822
+ $rootElement: "$rootElement",
1796
1823
  $routerGlobals: "$routerGlobals",
1797
1824
  $sce: "$sce",
1798
1825
  $sceDelegate: "$sceDelegate",
@@ -1803,7 +1830,7 @@
1803
1830
  $templateRequest: "$templateRequest",
1804
1831
  $transitions: "$transitions",
1805
1832
  $urlConfig: "$urlConfig",
1806
- $urlService: "$urlService",
1833
+ $url: "$url",
1807
1834
  $view: "$view",
1808
1835
  // provide literals
1809
1836
  $provide: "$provide",
@@ -2149,8 +2176,7 @@
2149
2176
 
2150
2177
  if (isClass(/** @type {Function} */ (fn))) {
2151
2178
  args.unshift(null);
2152
- const res = new (Function.prototype.bind.apply(fn, args))();
2153
- return res;
2179
+ return new (Function.prototype.bind.apply(fn, args))();
2154
2180
  } else {
2155
2181
  return /** @type {Function} */ (fn).apply(self, args);
2156
2182
  }
@@ -2239,8 +2265,7 @@
2239
2265
  */
2240
2266
  factory(serviceName) {
2241
2267
  const provider = this.providerInjector.get(serviceName + providerSuffix$1);
2242
- const res = this.invoke(provider.$get, provider, undefined, serviceName);
2243
- return res;
2268
+ return this.invoke(provider.$get, provider, undefined, serviceName);
2244
2269
  }
2245
2270
 
2246
2271
  /**
@@ -2274,8 +2299,7 @@
2274
2299
  */
2275
2300
  function extractArgs$1(fn) {
2276
2301
  const fnText = stringifyFn$1(fn).replace(STRIP_COMMENTS$1, "");
2277
- const args = fnText.match(ARROW_ARG$1) || fnText.match(FN_ARGS$1);
2278
- return args;
2302
+ return fnText.match(ARROW_ARG$1) || fnText.match(FN_ARGS$1);
2279
2303
  }
2280
2304
 
2281
2305
  /**
@@ -2566,8 +2590,7 @@
2566
2590
  */
2567
2591
  function extractArgs(fn) {
2568
2592
  const fnText = stringifyFn(fn).replace(STRIP_COMMENTS, "");
2569
- const args = fnText.match(ARROW_ARG) || fnText.match(FN_ARGS);
2570
- return args;
2593
+ return fnText.match(ARROW_ARG) || fnText.match(FN_ARGS);
2571
2594
  }
2572
2595
 
2573
2596
  /**
@@ -3024,11 +3047,7 @@
3024
3047
  }
3025
3048
  }
3026
3049
 
3027
- const urlParsingNode = document.createElement("a");
3028
3050
  const originUrl = urlResolve(window.location.href);
3029
- let baseUrlParsingNode;
3030
-
3031
- urlParsingNode.href = "http://[::1]";
3032
3051
 
3033
3052
  /**
3034
3053
  * @param {import("./interface.js").ResolvableUrl} url
@@ -3038,7 +3057,10 @@
3038
3057
  if (!isString(url))
3039
3058
  return /** @type {import("./interface.js").ParsedUrl} */ (url);
3040
3059
 
3041
- urlParsingNode.setAttribute("href", /** @type {string} */ (url));
3060
+ const urlParsingNode = new URL(
3061
+ /** @type {string} */ (url),
3062
+ window.location.href,
3063
+ );
3042
3064
 
3043
3065
  const hostname = urlParsingNode.hostname.includes(":")
3044
3066
  ? `[${urlParsingNode.hostname}]`
@@ -3046,9 +3068,7 @@
3046
3068
 
3047
3069
  return {
3048
3070
  href: urlParsingNode.href,
3049
- protocol: urlParsingNode.protocol
3050
- ? urlParsingNode.protocol.replace(/:$/, "")
3051
- : "",
3071
+ protocol: urlParsingNode.protocol,
3052
3072
  host: urlParsingNode.host,
3053
3073
  search: urlParsingNode.search
3054
3074
  ? urlParsingNode.search.replace(/^\?/, "")
@@ -3086,7 +3106,7 @@
3086
3106
  * @returns {boolean} Whether the URL is same-origin as the document base URL.
3087
3107
  */
3088
3108
  function urlIsSameOriginAsBaseUrl(requestUrl) {
3089
- return urlsAreSameOrigin(requestUrl, getBaseUrl());
3109
+ return urlsAreSameOrigin(requestUrl, document.baseURI);
3090
3110
  }
3091
3111
 
3092
3112
  /**
@@ -3138,27 +3158,6 @@
3138
3158
  return url1.protocol === url2.protocol && url1.host === url2.host;
3139
3159
  }
3140
3160
 
3141
- /**
3142
- * Returns the current document base URL.
3143
- * @returns {string}
3144
- */
3145
- function getBaseUrl() {
3146
- if (document.baseURI) {
3147
- return document.baseURI;
3148
- }
3149
-
3150
- // `document.baseURI` is available everywhere except IE
3151
- if (!baseUrlParsingNode) {
3152
- baseUrlParsingNode = document.createElement("a");
3153
- baseUrlParsingNode.href = ".";
3154
-
3155
- // Work-around for IE bug described in Implementation Notes. The fix in `urlResolve()` is not
3156
- // suitable here because we need to track changes to the base URL.
3157
- baseUrlParsingNode = baseUrlParsingNode.cloneNode(false);
3158
- }
3159
- return baseUrlParsingNode.href;
3160
- }
3161
-
3162
3161
  /**
3163
3162
  * Removes a trailing hash ('#') from the given URL if it exists.
3164
3163
  *
@@ -3480,7 +3479,6 @@
3480
3479
  "Attempting to use an unsafe value in a safe context.",
3481
3480
  ),
3482
3481
  );
3483
- return;
3484
3482
  };
3485
3483
 
3486
3484
  if ($injector.has("$sanitize")) {
@@ -3715,7 +3713,6 @@
3715
3713
  "Attempting to use an unsafe value in a safe context.",
3716
3714
  ),
3717
3715
  );
3718
- return;
3719
3716
  }
3720
3717
 
3721
3718
  return { trustAs, getTrusted, valueOf };
@@ -3914,7 +3911,7 @@
3914
3911
 
3915
3912
  /**
3916
3913
  * Shorthand method. `$sce.parseAsHtml(expression string)` →
3917
- * {@link ng.$sce#parseAs `$sce.parseAs($sce.HTML, value)`}
3914
+ * {@link ng.$sceparseAs `$sce.parseAs($sce.HTML, value)`}
3918
3915
  *
3919
3916
  * @param {string} expression String expression to compile.
3920
3917
  * @return {function(context, locals)} A function which represents the compiled expression:
@@ -3927,7 +3924,7 @@
3927
3924
 
3928
3925
  /**
3929
3926
  * Shorthand method. `$sce.parseAsCss(value)` →
3930
- * {@link ng.$sce#parseAs `$sce.parseAs($sce.CSS, value)`}
3927
+ * {@link ng.$sceparseAs `$sce.parseAs($sce.CSS, value)`}
3931
3928
  *
3932
3929
  * @param {string} expression String expression to compile.
3933
3930
  * @return {function(context, locals)} A function which represents the compiled expression:
@@ -3940,7 +3937,7 @@
3940
3937
 
3941
3938
  /**
3942
3939
  * Shorthand method. `$sce.parseAsUrl(value)` →
3943
- * {@link ng.$sce#parseAs `$sce.parseAs($sce.URL, value)`}
3940
+ * {@link ng.$sceparseAs `$sce.parseAs($sce.URL, value)`}
3944
3941
  *
3945
3942
  * @param {string} expression String expression to compile.
3946
3943
  * @return {function(context, locals)} A function which represents the compiled expression:
@@ -3953,7 +3950,7 @@
3953
3950
 
3954
3951
  /**
3955
3952
  * Shorthand method. `$sce.parseAsResourceUrl(value)` →
3956
- * {@link ng.$sce#parseAs `$sce.parseAs($sce.RESOURCE_URL, value)`}
3953
+ * {@link ng.$sceparseAs `$sce.parseAs($sce.RESOURCE_URL, value)`}
3957
3954
  *
3958
3955
  * @param {string} expression String expression to compile.
3959
3956
  * @return {function(context, locals)} A function which represents the compiled expression:
@@ -3966,7 +3963,7 @@
3966
3963
 
3967
3964
  /**
3968
3965
  * Shorthand method. `$sce.parseAsJs(value)` →
3969
- * {@link ng.$sce#parseAs `$sce.parseAs($sce.JS, value)`}
3966
+ * {@link ng.$sceparseAs `$sce.parseAs($sce.JS, value)`}
3970
3967
  *
3971
3968
  * @param {string} expression String expression to compile.
3972
3969
  * @return {function(context, locals)} A function which represents the compiled expression:
@@ -4523,7 +4520,7 @@
4523
4520
  const DirectiveSuffix = "Directive";
4524
4521
 
4525
4522
  class CompileProvider {
4526
- static $inject = ["$provide", "$$sanitizeUriProvider"];
4523
+ /* @ignore */ static $inject = ["$provide", "$$sanitizeUriProvider"];
4527
4524
 
4528
4525
  /**
4529
4526
  * @param {import('../../interface.js').Provider} $provide
@@ -5598,8 +5595,7 @@
5598
5595
  // Null out all of these references for garbage collection
5599
5596
  compileNodes = transcludeFn = previousCompileContext = null;
5600
5597
  }
5601
- const linked = compiled.apply(this, arguments);
5602
- return linked;
5598
+ return compiled.apply(this, arguments);
5603
5599
  };
5604
5600
  }
5605
5601
 
@@ -5943,14 +5939,13 @@
5943
5939
  // * `undefined` - a slot that was not declared (i.e. invalid)
5944
5940
  const slotTranscludeFn = boundTranscludeFn.$$slots[slotName];
5945
5941
  if (slotTranscludeFn) {
5946
- const slotTranscludeRes = slotTranscludeFn(
5942
+ return slotTranscludeFn(
5947
5943
  scope,
5948
5944
  cloneAttachFn,
5949
5945
  transcludeControllers,
5950
5946
  futureParentElement,
5951
5947
  scopeToChild,
5952
5948
  );
5953
- return slotTranscludeRes;
5954
5949
  }
5955
5950
 
5956
5951
  if (isUndefined(slotTranscludeFn)) {
@@ -5963,14 +5958,13 @@
5963
5958
  );
5964
5959
  }
5965
5960
  } else {
5966
- const boundTranscludeRes = boundTranscludeFn(
5961
+ return boundTranscludeFn(
5967
5962
  scope,
5968
5963
  cloneAttachFn,
5969
5964
  transcludeControllers,
5970
5965
  futureParentElement,
5971
5966
  scopeToChild,
5972
5967
  );
5973
- return boundTranscludeRes;
5974
5968
  }
5975
5969
  }
5976
5970
  };
@@ -7734,7 +7728,13 @@
7734
7728
 
7735
7729
  class FormController {
7736
7730
  static $nonscope = true;
7737
- static $inject = ["$element", "$attrs", "$scope", "$animate", "$interpolate"];
7731
+ /* @ignore */ static $inject = [
7732
+ "$element",
7733
+ "$attrs",
7734
+ "$scope",
7735
+ "$animate",
7736
+ "$interpolate",
7737
+ ];
7738
7738
 
7739
7739
  /**
7740
7740
  * @param {Element} $element
@@ -8198,7 +8198,7 @@
8198
8198
  return [
8199
8199
  "$parse",
8200
8200
  function ($parse) {
8201
- const formDirective = {
8201
+ return {
8202
8202
  name: "form",
8203
8203
  restrict: isNgForm ? "EA" : "E",
8204
8204
  require: ["form", "^^?form"], // first is the form's own ctrl, second is an optional parent form
@@ -8277,9 +8277,6 @@
8277
8277
  };
8278
8278
  },
8279
8279
  };
8280
-
8281
- return formDirective;
8282
-
8283
8280
  function getSetter(expression) {
8284
8281
  if (expression === "") {
8285
8282
  // create an assignable expression, so forms with an empty name can be renamed later
@@ -8307,7 +8304,7 @@
8307
8304
 
8308
8305
  class NgModelOptionsController {
8309
8306
  static $nonscope = true;
8310
- static $inject = ["$attrs", "$scope"];
8307
+ /* @ignore */ static $inject = ["$attrs", "$scope"];
8311
8308
 
8312
8309
  /**
8313
8310
  * @param {import('../../core/compile/attributes.js').Attributes} $attrs
@@ -8476,14 +8473,14 @@
8476
8473
 
8477
8474
  class NgModelController {
8478
8475
  static $nonscope = true;
8479
- static $inject = [
8476
+ /* @ignore */ static $inject = [
8480
8477
  "$scope",
8481
- "$exceptionHandler",
8478
+ $injectTokens.$exceptionHandler,
8482
8479
  "$attrs",
8483
8480
  "$element",
8484
- "$parse",
8485
- "$animate",
8486
- "$interpolate",
8481
+ $injectTokens.$parse,
8482
+ $injectTokens.$animate,
8483
+ $injectTokens.$interpolate,
8487
8484
  ];
8488
8485
 
8489
8486
  /**
@@ -9130,8 +9127,7 @@
9130
9127
  }
9131
9128
 
9132
9129
  $$parseAndValidate() {
9133
- const viewValue = this.$$lastCommittedViewValue;
9134
- let modelValue = viewValue;
9130
+ let modelValue = this.$$lastCommittedViewValue;
9135
9131
  const that = this;
9136
9132
 
9137
9133
  this.$$parserValid = isUndefined(modelValue) ? undefined : true;
@@ -10054,9 +10050,8 @@
10054
10050
  }
10055
10051
 
10056
10052
  function badInputChecker(scope, element, attr, ctrl, parserName) {
10057
- const node = element;
10058
10053
  const nativeValidation = (ctrl.$$hasNativeValidators = isObject(
10059
- node.validity,
10054
+ element.validity,
10060
10055
  ));
10061
10056
 
10062
10057
  if (nativeValidation) {
@@ -10603,12 +10598,11 @@
10603
10598
  // TODO REMOVE IS SUPPORT
10604
10599
  // Support: IE9 only
10605
10600
  // In IE9 values are converted to string (e.g. `input.value = null` results in `input.value === 'null'`).
10606
- const propValue = isDefined(value)
10601
+ element["value"] = isDefined(value)
10607
10602
  ? isProxy(value)
10608
10603
  ? value.$target
10609
10604
  : value
10610
10605
  : null;
10611
- element["value"] = propValue;
10612
10606
  attr.$set("value", value);
10613
10607
  }
10614
10608
 
@@ -10667,7 +10661,7 @@
10667
10661
  /**
10668
10662
  * @type {Array<string>}
10669
10663
  */
10670
- static $inject = ["$element", "$scope"];
10664
+ /* @ignore */ static $inject = ["$element", "$scope"];
10671
10665
 
10672
10666
  /**
10673
10667
  * @param {HTMLSelectElement} $element
@@ -11275,6 +11269,7 @@
11275
11269
 
11276
11270
  ngBindHtmlDirective.$inject = [$injectTokens.$parse];
11277
11271
  /**
11272
+ * @param {import('../../core/parse/interface.ts').ParseService} $parse
11278
11273
  * @returns {import('../../interface.ts').Directive}
11279
11274
  */
11280
11275
  function ngBindHtmlDirective($parse) {
@@ -13157,7 +13152,7 @@
13157
13152
  *
13158
13153
  */
13159
13154
  const requiredDirective = [
13160
- "$parse",
13155
+ $injectTokens.$parse,
13161
13156
  /**
13162
13157
  * @param {import("../../core/parse/interface.ts").ParseService} $parse
13163
13158
  * @returns {import("../../interface.ts").Directive}
@@ -13239,75 +13234,72 @@
13239
13234
  * </div>
13240
13235
  */
13241
13236
  const patternDirective = [
13242
- "$parse",
13237
+ $injectTokens.$parse,
13243
13238
  /**
13244
13239
  * @param {import("../../core/parse/interface.ts").ParseService} $parse
13245
13240
  * @returns {import("../../interface.ts").Directive}
13246
13241
  */
13247
- ($parse) => {
13248
- return {
13249
- restrict: "A",
13250
- require: "?ngModel",
13251
- compile: (_Elm, tAttr) => {
13252
- let patternExp;
13253
- let parseFn;
13242
+ ($parse) => ({
13243
+ restrict: "A",
13244
+ require: "?ngModel",
13245
+ compile: (_Elm, tAttr) => {
13246
+ let patternExp;
13247
+ let parseFn;
13254
13248
 
13255
- if (tAttr["ngPattern"]) {
13256
- patternExp = tAttr["ngPattern"];
13249
+ if (tAttr["ngPattern"]) {
13250
+ patternExp = tAttr["ngPattern"];
13257
13251
 
13258
- // ngPattern might be a scope expression, or an inlined regex, which is not parsable.
13259
- // We get value of the attribute here, so we can compare the old and the new value
13260
- // in the observer to avoid unnecessary validations
13261
- if (
13262
- tAttr["ngPattern"].charAt(0) === "/" &&
13263
- REGEX_STRING_REGEXP.test(tAttr["ngPattern"])
13264
- ) {
13265
- parseFn = function () {
13266
- return tAttr["ngPattern"];
13267
- };
13268
- } else {
13269
- parseFn = $parse(tAttr["ngPattern"]);
13270
- }
13252
+ // ngPattern might be a scope expression, or an inlined regex, which is not parsable.
13253
+ // We get value of the attribute here, so we can compare the old and the new value
13254
+ // in the observer to avoid unnecessary validations
13255
+ if (
13256
+ tAttr["ngPattern"].charAt(0) === "/" &&
13257
+ REGEX_STRING_REGEXP.test(tAttr["ngPattern"])
13258
+ ) {
13259
+ parseFn = function () {
13260
+ return tAttr["ngPattern"];
13261
+ };
13262
+ } else {
13263
+ parseFn = $parse(tAttr["ngPattern"]);
13271
13264
  }
13265
+ }
13272
13266
 
13273
- return function (scope, elm, attr, ctrl) {
13274
- if (!ctrl) return;
13275
-
13276
- let attrVal = attr["pattern"];
13267
+ return function (scope, elm, attr, ctrl) {
13268
+ if (!ctrl) return;
13269
+ let attrVal = attr["pattern"];
13277
13270
 
13278
- if (attr["ngPattern"]) {
13279
- attrVal = parseFn(scope);
13280
- } else {
13281
- patternExp = attr["pattern"];
13282
- }
13271
+ if (attr["ngPattern"]) {
13272
+ attrVal = parseFn(scope);
13273
+ } else {
13274
+ patternExp = attr["pattern"];
13275
+ }
13283
13276
 
13284
- let regexp = parsePatternAttr(attrVal, patternExp, elm);
13285
- attr.$observe("pattern", function (newVal) {
13286
- const oldRegexp = regexp;
13277
+ let regexp = parsePatternAttr(attrVal, patternExp, elm);
13278
+ attr.$observe("pattern", (newVal) => {
13279
+ const oldRegexp = regexp;
13287
13280
 
13288
- regexp = parsePatternAttr(newVal, patternExp, elm);
13281
+ regexp = parsePatternAttr(newVal, patternExp, elm);
13289
13282
 
13290
- if (
13291
- (oldRegexp && oldRegexp.toString()) !==
13292
- (regexp && regexp.toString())
13293
- ) {
13294
- ctrl["$validate"]();
13295
- }
13296
- });
13283
+ if (
13284
+ (oldRegexp && oldRegexp.toString()) !==
13285
+ (regexp && regexp.toString())
13286
+ ) {
13287
+ ctrl["$validate"]();
13288
+ }
13289
+ });
13297
13290
 
13298
- ctrl["$validators"]["pattern"] = function (modelValue, viewValue) {
13299
- // HTML5 pattern constraint validates the input value, so we validate the viewValue
13300
- return (
13301
- // @ts-ignore
13302
- ctrl.$isEmpty(viewValue) ||
13303
- isUndefined(regexp) ||
13304
- regexp.test(viewValue)
13305
- );
13306
- };
13291
+ ctrl["$validators"]["pattern"] = (_modelValue, viewValue) => {
13292
+ // HTML5 pattern constraint validates the input value, so we validate the viewValue
13293
+ return (
13294
+ // @ts-ignore
13295
+ ctrl.$isEmpty(viewValue) ||
13296
+ isUndefined(regexp) ||
13297
+ regexp.test(viewValue)
13298
+ );
13307
13299
  };
13308
- },
13309
- };
13310
- },
13300
+ };
13301
+ },
13302
+ }),
13311
13303
  ];
13312
13304
 
13313
13305
  /**
@@ -13341,7 +13333,7 @@
13341
13333
  *
13342
13334
  */
13343
13335
  const maxlengthDirective = [
13344
- "$parse",
13336
+ $injectTokens.$parse,
13345
13337
  /**
13346
13338
  * @param {import("../../core/parse/interface.ts").ParseService} $parse
13347
13339
  * @returns {import("../../interface.ts").Directive}
@@ -13413,32 +13405,28 @@
13413
13405
  *
13414
13406
  */
13415
13407
  const minlengthDirective = [
13416
- "$parse",
13417
- function ($parse) {
13418
- return {
13419
- restrict: "A",
13420
- require: "?ngModel",
13421
- link(scope, elm, attr, ctrl) {
13422
- if (!ctrl) return;
13408
+ $injectTokens.$parse,
13409
+ ($parse) => ({
13410
+ restrict: "A",
13411
+ require: "?ngModel",
13412
+ link(scope, elm, attr, ctrl) {
13413
+ if (!ctrl) return;
13423
13414
 
13424
- let minlength = attr.minlength || $parse(attr.ngMinlength)(scope);
13425
- let minlengthParsed = parseLength(minlength) || -1;
13415
+ let minlength = attr.minlength || $parse(attr.ngMinlength)(scope);
13416
+ let minlengthParsed = parseLength(minlength) || -1;
13426
13417
 
13427
- attr.$observe("minlength", (value) => {
13428
- if (minlength !== value) {
13429
- minlengthParsed = parseLength(value) || -1;
13430
- minlength = value;
13431
- ctrl.$validate();
13432
- }
13433
- });
13434
- ctrl.$validators.minlength = function (modelValue, viewValue) {
13435
- return (
13436
- ctrl.$isEmpty(viewValue) || viewValue.length >= minlengthParsed
13437
- );
13438
- };
13439
- },
13440
- };
13441
- },
13418
+ attr.$observe("minlength", (value) => {
13419
+ if (minlength !== value) {
13420
+ minlengthParsed = parseLength(value) || -1;
13421
+ minlength = value;
13422
+ ctrl.$validate();
13423
+ }
13424
+ });
13425
+ ctrl.$validators.minlength = function (modelValue, viewValue) {
13426
+ return ctrl.$isEmpty(viewValue) || viewValue.length >= minlengthParsed;
13427
+ };
13428
+ },
13429
+ }),
13442
13430
  ];
13443
13431
 
13444
13432
  function parsePatternAttr(regex, patternExp, elm) {
@@ -13449,7 +13437,12 @@
13449
13437
  }
13450
13438
 
13451
13439
  if (isString(regex)) {
13452
- regex = new RegExp(`^${regex}$`);
13440
+ const match = regex.match(/^\/(.*)\/([gimsuy]*)$/);
13441
+ if (match) {
13442
+ regex = new RegExp(match[1], match[2]);
13443
+ } else {
13444
+ regex = new RegExp(`^${regex}$`);
13445
+ }
13453
13446
  }
13454
13447
 
13455
13448
  if (!regex.test) {
@@ -13466,7 +13459,7 @@
13466
13459
  }
13467
13460
 
13468
13461
  function parseLength(val) {
13469
- const intVal = toInt(val);
13462
+ const intVal = parseInt(val, 10);
13470
13463
  return isNumberNaN(intVal) ? -1 : intVal;
13471
13464
  }
13472
13465
 
@@ -13489,8 +13482,8 @@
13489
13482
  }
13490
13483
 
13491
13484
  $get = [
13492
- "$location",
13493
- "$rootScope",
13485
+ $injectTokens.$location,
13486
+ $injectTokens.$rootScope,
13494
13487
  /**
13495
13488
  *
13496
13489
  * @param {import('../services/location/location.js').Location} $location
@@ -13568,7 +13561,7 @@
13568
13561
  ? hash
13569
13562
  : isNumber(hash)
13570
13563
  ? hash.toString()
13571
- : $location.hash();
13564
+ : $location.getHash();
13572
13565
  let elm;
13573
13566
 
13574
13567
  // empty hash, scroll to the top of the page
@@ -13585,7 +13578,7 @@
13585
13578
  };
13586
13579
 
13587
13580
  // does not scroll when user clicks on anchor link that is currently on
13588
- // (no url change, no $location.hash() change), browser native does scroll
13581
+ // (no url change, no $location.getHash() change), browser native does scroll
13589
13582
  if (this.autoScrollingEnabled) {
13590
13583
  $rootScope["$location"] = $location;
13591
13584
  $rootScope.$watch("$location.$$hash", (newVal, oldVal) => {
@@ -13958,8 +13951,7 @@
13958
13951
 
13959
13952
  function applyInlineStyle(node, styleTuple) {
13960
13953
  const prop = styleTuple[0];
13961
- const value = styleTuple[1];
13962
- node.style[prop] = value;
13954
+ node.style[prop] = styleTuple[1];
13963
13955
  }
13964
13956
 
13965
13957
  function concatWithSpace(a, b) {
@@ -15029,7 +15021,7 @@
15029
15021
  if (Math.abs(Number(limit)) === Infinity) {
15030
15022
  limit = Number(limit);
15031
15023
  } else {
15032
- limit = toInt(/** @type {string} */ (limit));
15024
+ limit = parseInt(/** @type {string} */ (limit), 10);
15033
15025
  }
15034
15026
  if (isNumberNaN(limit)) return input;
15035
15027
 
@@ -15039,7 +15031,7 @@
15039
15031
  begin =
15040
15032
  !begin || isNaN(/** @type {any} */ (begin))
15041
15033
  ? 0
15042
- : toInt(/** @type {string} */ (begin));
15034
+ : parseInt(/** @type {string} */ (begin), 10);
15043
15035
  begin =
15044
15036
  begin < 0 ? Math.max(0, /** @type {[]} */ (input).length + begin) : begin;
15045
15037
 
@@ -15233,6 +15225,8 @@
15233
15225
  }
15234
15226
  }
15235
15227
 
15228
+ $IsStateFilter.$inject = [$injectTokens.$state];
15229
+
15236
15230
  /**
15237
15231
  * `isState` Filter: truthy if the current state is the parameter
15238
15232
  *
@@ -15242,18 +15236,19 @@
15242
15236
  * ```html
15243
15237
  * <div ng-if="'stateName' | isState">show if state is 'stateName'</div>
15244
15238
  * ```
15245
- */
15246
- $IsStateFilter.$inject = ["$state"];
15247
- /**
15239
+ *
15240
+ * @param {import('./state/state-service.js').StateProvider} $state
15248
15241
  * @returns {import('../interface.ts').FilterFn}
15249
15242
  */
15250
15243
  function $IsStateFilter($state) {
15251
- const isFilter = function (state, params, options) {
15252
- return $state.is(state, params, options);
15253
- };
15244
+ const isFilter = (state, params, options) =>
15245
+ $state.is(state, params, options);
15254
15246
  isFilter.$stateful = true;
15255
15247
  return isFilter;
15256
15248
  }
15249
+
15250
+ $IncludedByStateFilter.$inject = [$injectTokens.$state];
15251
+
15257
15252
  /**
15258
15253
  * `includedByState` Filter: truthy if the current state includes the parameter
15259
15254
  *
@@ -15263,9 +15258,8 @@
15263
15258
  * ```html
15264
15259
  * <div ng-if="'fullOrPartialStateName' | includedByState">show if state includes 'fullOrPartialStateName'</div>
15265
15260
  * ```
15266
- */
15267
- $IncludedByStateFilter.$inject = ["$state"];
15268
- /**
15261
+ *
15262
+ * @param {import('./state/state-service.js').StateProvider} $state
15269
15263
  * @returns {import('../interface.ts').FilterFn}
15270
15264
  */
15271
15265
  function $IncludedByStateFilter($state) {
@@ -15279,7 +15273,7 @@
15279
15273
  const SUFFIX = "Filter";
15280
15274
 
15281
15275
  class FilterProvider {
15282
- static $inject = [$injectTokens.$provide];
15276
+ /* @ignore */ static $inject = [$injectTokens.$provide];
15283
15277
 
15284
15278
  /**
15285
15279
  * @param {import('../../interface.ts').Provider} $provide
@@ -17182,173 +17176,177 @@
17182
17176
  return ast.constant;
17183
17177
  }
17184
17178
 
17185
- function ParseProvider() {
17186
- const cache = Object.create(null);
17187
-
17188
- /** @type {function(any):boolean?} */
17189
- let identStart;
17179
+ class ParseProvider {
17180
+ constructor() {
17181
+ const cache = Object.create(null);
17190
17182
 
17191
- /** @type {function(any):boolean?} */
17192
- let identContinue;
17183
+ /** @type {function(any):boolean?} */
17184
+ let identStart;
17193
17185
 
17194
- /**
17195
- * Allows defining the set of characters that are allowed in AngularTS expressions. The function
17196
- * `identifierStart` will get called to know if a given character is a valid character to be the
17197
- * first character for an identifier. The function `identifierContinue` will get called to know if
17198
- * a given character is a valid character to be a follow-up identifier character. The functions
17199
- * `identifierStart` and `identifierContinue` will receive as arguments the single character to be
17200
- * identifier and the character code point. These arguments will be `string` and `numeric`. Keep in
17201
- * mind that the `string` parameter can be two characters long depending on the character
17202
- * representation. It is expected for the function to return `true` or `false`, whether that
17203
- * character is allowed or not.
17204
- *
17205
- * Since this function will be called extensively, keep the implementation of these functions fast,
17206
- * as the performance of these functions have a direct impact on the expressions parsing speed.
17207
- *
17208
- * @param {function(any):boolean} [identifierStart] The function that will decide whether the given character is
17209
- * a valid identifier start character.
17210
- * @param {function(any):boolean} [identifierContinue] The function that will decide whether the given character is
17211
- * a valid identifier continue character.
17212
- * @returns {ParseProvider}
17213
- */
17214
- this.setIdentifierFns = function (identifierStart, identifierContinue) {
17215
- identStart = identifierStart;
17216
- identContinue = identifierContinue;
17217
- return this;
17218
- };
17186
+ /** @type {function(any):boolean?} */
17187
+ let identContinue;
17219
17188
 
17220
- this.$get = [
17221
- "$filter",
17222
17189
  /**
17190
+ * Allows defining the set of characters that are allowed in AngularTS expressions. The function
17191
+ * `identifierStart` will get called to know if a given character is a valid character to be the
17192
+ * first character for an identifier. The function `identifierContinue` will get called to know if
17193
+ * a given character is a valid character to be a follow-up identifier character. The functions
17194
+ * `identifierStart` and `identifierContinue` will receive as arguments the single character to be
17195
+ * identifier and the character code point. These arguments will be `string` and `numeric`. Keep in
17196
+ * mind that the `string` parameter can be two characters long depending on the character
17197
+ * representation. It is expected for the function to return `true` or `false`, whether that
17198
+ * character is allowed or not.
17199
+ *
17200
+ * Since this function will be called extensively, keep the implementation of these functions fast,
17201
+ * as the performance of these functions have a direct impact on the expressions parsing speed.
17223
17202
  *
17224
- * @param {(any) => any} $filter
17225
- * @returns {import('./interface').ParseService}
17203
+ * @param {function(any):boolean} [identifierStart] The function that will decide whether the given character is
17204
+ * a valid identifier start character.
17205
+ * @param {function(any):boolean} [identifierContinue] The function that will decide whether the given character is
17206
+ * a valid identifier continue character.
17207
+ * @returns {ParseProvider}
17226
17208
  */
17227
- function ($filter) {
17228
- /** @type {import("./lexer/lexer.js").LexerOptions} */
17229
- const $lexerOptions = {
17230
- isIdentifierStart: isFunction(identStart) && identStart,
17231
- isIdentifierContinue: isFunction(identContinue) && identContinue,
17232
- };
17233
- return $parse;
17209
+ this.setIdentifierFns = function (identifierStart, identifierContinue) {
17210
+ identStart = identifierStart;
17211
+ identContinue = identifierContinue;
17212
+ return this;
17213
+ };
17234
17214
 
17215
+ this.$get = [
17216
+ "$filter",
17235
17217
  /**
17236
- * @param {string} exp
17237
- * @param interceptorFn
17238
- * @returns any
17218
+ *
17219
+ * @param {(any) => any} $filter
17220
+ * @returns {import('./interface').ParseService}
17239
17221
  */
17240
- function $parse(exp, interceptorFn) {
17241
- let parsedExpression, cacheKey;
17242
-
17243
- switch (typeof exp) {
17244
- case "string":
17245
- exp = exp.trim();
17246
- cacheKey = exp;
17222
+ function ($filter) {
17223
+ /** @type {import("./lexer/lexer.js").LexerOptions} */
17224
+ const $lexerOptions = {
17225
+ isIdentifierStart: isFunction(identStart) && identStart,
17226
+ isIdentifierContinue: isFunction(identContinue) && identContinue,
17227
+ };
17228
+ return $parse;
17247
17229
 
17248
- parsedExpression = cache[cacheKey];
17230
+ /**
17231
+ * @param {string} exp
17232
+ * @param interceptorFn
17233
+ * @returns any
17234
+ */
17235
+ function $parse(exp, interceptorFn) {
17236
+ let parsedExpression, cacheKey;
17249
17237
 
17250
- if (!parsedExpression) {
17251
- const lexer = new Lexer($lexerOptions);
17252
- const parser = new Parser(lexer, $filter);
17253
- parsedExpression = parser.parse(exp);
17238
+ switch (typeof exp) {
17239
+ case "string":
17240
+ exp = exp.trim();
17241
+ cacheKey = exp;
17254
17242
 
17255
- cache[cacheKey] = addWatchDelegate(parsedExpression);
17256
- }
17257
- return addInterceptor(parsedExpression, interceptorFn);
17243
+ parsedExpression = cache[cacheKey];
17258
17244
 
17259
- case "function":
17260
- return addInterceptor(exp, interceptorFn);
17245
+ if (!parsedExpression) {
17246
+ const lexer = new Lexer($lexerOptions);
17247
+ const parser = new Parser(lexer, $filter);
17248
+ parsedExpression = parser.parse(exp);
17261
17249
 
17262
- default:
17263
- return addInterceptor(() => {}, interceptorFn);
17264
- }
17265
- }
17250
+ cache[cacheKey] = addWatchDelegate(parsedExpression);
17251
+ }
17252
+ return addInterceptor(parsedExpression, interceptorFn);
17266
17253
 
17267
- /**
17268
- * @param {Function} parsedExpression
17269
- * @param interceptorFn
17270
- * @returns {import('./interface').CompiledExpression|*}
17271
- */
17272
- function addInterceptor(parsedExpression, interceptorFn) {
17273
- if (!interceptorFn) return parsedExpression;
17254
+ case "function":
17255
+ return addInterceptor(exp, interceptorFn);
17274
17256
 
17275
- // Extract any existing interceptors out of the parsedExpression
17276
- // to ensure the original parsedExpression is always the $$intercepted
17277
- // @ts-ignore
17278
- if (parsedExpression.$$interceptor) {
17279
- interceptorFn = chainInterceptors(
17280
- // @ts-ignore
17281
- parsedExpression.$$interceptor,
17282
- interceptorFn,
17283
- );
17284
- // @ts-ignore
17285
- parsedExpression = parsedExpression.$$intercepted;
17257
+ default:
17258
+ return addInterceptor(() => {}, interceptorFn);
17259
+ }
17286
17260
  }
17287
17261
 
17288
- let useInputs = false;
17262
+ /**
17263
+ * @param {Function} parsedExpression
17264
+ * @param interceptorFn
17265
+ * @returns {import('./interface').CompiledExpression|*}
17266
+ */
17267
+ function addInterceptor(parsedExpression, interceptorFn) {
17268
+ if (!interceptorFn) {
17269
+ return parsedExpression;
17270
+ }
17289
17271
 
17290
- const fn = function interceptedExpression(
17291
- scope,
17292
- locals,
17293
- assign,
17294
- inputs,
17295
- ) {
17296
- const value =
17297
- useInputs && inputs
17298
- ? inputs[0]
17299
- : parsedExpression(scope, locals, assign, inputs);
17300
- // Do not invoke for getters
17301
- if (scope?.getter) {
17302
- return;
17272
+ // Extract any existing interceptors out of the parsedExpression
17273
+ // to ensure the original parsedExpression is always the $$intercepted
17274
+ // @ts-ignore
17275
+ if (parsedExpression.$$interceptor) {
17276
+ interceptorFn = chainInterceptors(
17277
+ // @ts-ignore
17278
+ parsedExpression.$$interceptor,
17279
+ interceptorFn,
17280
+ );
17281
+ // @ts-ignore
17282
+ parsedExpression = parsedExpression.$$intercepted;
17303
17283
  }
17304
- const res = isFunction(value) ? value() : value;
17305
- return interceptorFn(isProxy(res) ? res.$target : res);
17306
- };
17307
17284
 
17308
- // Maintain references to the interceptor/intercepted
17309
- fn.$$intercepted = parsedExpression;
17310
- fn.$$interceptor = interceptorFn;
17285
+ let useInputs = false;
17311
17286
 
17312
- // Propagate the literal/oneTime/constant attributes
17313
- // @ts-ignore
17314
- fn.literal = parsedExpression.literal;
17315
- // @ts-ignore
17316
- fn.oneTime = parsedExpression.oneTime;
17317
- // @ts-ignore
17318
- fn.constant = parsedExpression.constant;
17319
- // @ts-ignore
17320
- fn.decoratedNode = parsedExpression.decoratedNode;
17287
+ const fn = function interceptedExpression(
17288
+ scope,
17289
+ locals,
17290
+ assign,
17291
+ inputs,
17292
+ ) {
17293
+ const value =
17294
+ useInputs && inputs
17295
+ ? inputs[0]
17296
+ : parsedExpression(scope, locals, assign, inputs);
17297
+ // Do not invoke for getters
17298
+ if (scope?.getter) {
17299
+ return;
17300
+ }
17301
+ const res = isFunction(value) ? value() : value;
17302
+ return interceptorFn(isProxy(res) ? res.$target : res);
17303
+ };
17304
+
17305
+ // Maintain references to the interceptor/intercepted
17306
+ fn.$$intercepted = parsedExpression;
17307
+ fn.$$interceptor = interceptorFn;
17321
17308
 
17322
- // Treat the interceptor like filters.
17323
- // If it is not $stateful then only watch its inputs.
17324
- // If the expression itself has no inputs then use the full expression as an input.
17325
- if (!interceptorFn.$stateful) {
17309
+ // Propagate the literal/oneTime/constant attributes
17326
17310
  // @ts-ignore
17327
- useInputs = !parsedExpression.inputs;
17311
+ fn.literal = parsedExpression.literal;
17328
17312
  // @ts-ignore
17329
- fn.inputs = parsedExpression.inputs
17330
- ? // @ts-ignore
17331
- parsedExpression.inputs
17332
- : [parsedExpression];
17333
-
17334
- if (!interceptorFn.$$pure) {
17335
- fn.inputs = fn.inputs.map(function (e) {
17336
- // Remove the isPure flag of inputs when it is not absolute because they are now wrapped in a
17337
- // non-pure interceptor function.
17338
- if (e.isPure === PURITY_RELATIVE) {
17339
- return function depurifier(s) {
17340
- return e(s);
17341
- };
17342
- }
17343
- return e;
17344
- });
17313
+ fn.oneTime = parsedExpression.oneTime;
17314
+ // @ts-ignore
17315
+ fn.constant = parsedExpression.constant;
17316
+ // @ts-ignore
17317
+ fn.decoratedNode = parsedExpression.decoratedNode;
17318
+
17319
+ // Treat the interceptor like filters.
17320
+ // If it is not $stateful then only watch its inputs.
17321
+ // If the expression itself has no inputs then use the full expression as an input.
17322
+ if (!interceptorFn.$stateful) {
17323
+ // @ts-ignore
17324
+ useInputs = !parsedExpression.inputs;
17325
+ // @ts-ignore
17326
+ fn.inputs = parsedExpression.inputs
17327
+ ? // @ts-ignore
17328
+ parsedExpression.inputs
17329
+ : [parsedExpression];
17330
+
17331
+ if (!interceptorFn.$$pure) {
17332
+ fn.inputs = fn.inputs.map(function (e) {
17333
+ // Remove the isPure flag of inputs when it is not absolute because they are now wrapped in a
17334
+ // non-pure interceptor function.
17335
+ if (e.isPure === PURITY_RELATIVE) {
17336
+ return function depurifier(s) {
17337
+ return e(s);
17338
+ };
17339
+ }
17340
+ return e;
17341
+ });
17342
+ }
17345
17343
  }
17346
- }
17347
17344
 
17348
- return addWatchDelegate(fn);
17349
- }
17350
- },
17351
- ];
17345
+ return addWatchDelegate(fn);
17346
+ }
17347
+ },
17348
+ ];
17349
+ }
17352
17350
  }
17353
17351
 
17354
17352
  function constantWatchDelegate(
@@ -17826,8 +17824,7 @@
17826
17824
  let j = 0;
17827
17825
  for (; j < ii; j++) {
17828
17826
  let fn = parseFns[j];
17829
- let res = fn(context);
17830
- vals[j] = res;
17827
+ vals[j] = fn(context);
17831
17828
  }
17832
17829
  cb(compute(vals));
17833
17830
  });
@@ -17836,8 +17833,7 @@
17836
17833
  values[i] = parseFns[i](context);
17837
17834
  }
17838
17835
 
17839
- let res = compute(values);
17840
- return res;
17836
+ return compute(values);
17841
17837
  } catch (err) {
17842
17838
  interr(text, err);
17843
17839
  }
@@ -18229,6 +18225,7 @@
18229
18225
  });
18230
18226
 
18231
18227
  let useApplyAsync = false;
18228
+
18232
18229
  /**
18233
18230
  * Configure $http service to combine processing of multiple http responses received at around
18234
18231
  * the same time via {@link ng.$rootScope.Scope#$applyAsync $rootScope.$applyAsync}. This can result in
@@ -18261,7 +18258,7 @@
18261
18258
  *
18262
18259
  * {@link ng.$http#interceptors Interceptors detailed info}
18263
18260
  */
18264
- const interceptorFactories = (this.interceptors = []);
18261
+ this.interceptors = [];
18265
18262
 
18266
18263
  /**
18267
18264
  * Array containing URLs whose origins are trusted to receive the XSRF token. See the
@@ -18298,8 +18295,10 @@
18298
18295
  * $http.get('https://stats.example.com/activity').then(...);
18299
18296
  * }]);
18300
18297
  * ```
18298
+ *
18299
+ * @type {string[]}
18301
18300
  */
18302
- const xsrfTrustedOrigins = (this.xsrfTrustedOrigins = []);
18301
+ this.xsrfTrustedOrigins = [];
18303
18302
 
18304
18303
  /**
18305
18304
  * This property is deprecated. Use {@link $httpProvider#xsrfTrustedOrigins xsrfTrustedOrigins}
@@ -18345,7 +18344,7 @@
18345
18344
  */
18346
18345
  const reversedInterceptors = [];
18347
18346
 
18348
- interceptorFactories.forEach((interceptorFactory) => {
18347
+ this.interceptors.forEach((interceptorFactory) => {
18349
18348
  reversedInterceptors.unshift(
18350
18349
  isString(interceptorFactory)
18351
18350
  ? $injector.get(interceptorFactory)
@@ -18356,7 +18355,9 @@
18356
18355
  /**
18357
18356
  * A function to check request URLs against a list of allowed origins.
18358
18357
  */
18359
- const urlIsAllowedOrigin = urlIsAllowedOriginFactory(xsrfTrustedOrigins);
18358
+ const urlIsAllowedOrigin = urlIsAllowedOriginFactory(
18359
+ this.xsrfTrustedOrigins,
18360
+ );
18360
18361
 
18361
18362
  /**
18362
18363
  * @property {Array.<Object>} requestConfig Array of config objects for currently pending
@@ -18855,24 +18856,13 @@
18855
18856
  }
18856
18857
 
18857
18858
  /**
18858
- * HTTP backend used by the {@link ng.$http service} that delegates to
18859
- * XMLHttpRequest object and deals with browser incompatibilities.
18860
- *
18861
- * You should never need to use this service directly, instead use the higher-level abstractions:
18862
- * {@link ng.$http $http}.
18863
- *
18864
- */
18865
- /**
18866
- * HTTP backend used by the {@link ng.$http service} that delegates to
18859
+ * HTTP backend used by the `$http` that delegates to
18867
18860
  * XMLHttpRequest object and deals with browser incompatibilities.
18868
- *
18869
- * You should never need to use this service directly, instead use the higher-level abstractions:
18870
- * {@link ng.$http $http}.
18871
- *
18861
+ * You should never need to use this service directly.
18872
18862
  */
18873
18863
  class HttpBackendProvider {
18874
18864
  constructor() {
18875
- this.$get = [() => createHttpBackend()];
18865
+ this.$get = () => createHttpBackend();
18876
18866
  }
18877
18867
  }
18878
18868
 
@@ -18880,7 +18870,21 @@
18880
18870
  * @returns
18881
18871
  */
18882
18872
  function createHttpBackend() {
18883
- // TODO(vojta): fix the signature
18873
+ /**
18874
+ * Makes an HTTP request using XMLHttpRequest with flexible options.
18875
+ *
18876
+ * @param {string} method - The HTTP method (e.g., "GET", "POST").
18877
+ * @param {string} [url] - The URL to send the request to. Defaults to the current page URL.
18878
+ * @param {*} [post] - The body to send with the request, if any.
18879
+ * @param {function(number, any, string|null, string, string): void} [callback] - Callback invoked when the request completes.
18880
+ * @param {Object<string, string|undefined>} [headers] - Headers to set on the request.
18881
+ * @param {number|Promise<any>} [timeout] - Timeout in ms or a cancellable promise.
18882
+ * @param {boolean} [withCredentials] - Whether to send credentials with the request.
18883
+ * @param {XMLHttpRequestResponseType} [responseType] - The type of data expected in the response.
18884
+ * @param {Object<string, EventListener>} [eventHandlers] - Event listeners for the XMLHttpRequest object.
18885
+ * @param {Object<string, EventListener>} [uploadEventHandlers] - Event listeners for the XMLHttpRequest.upload object.
18886
+ * @returns {void}
18887
+ */
18884
18888
  return function (
18885
18889
  method,
18886
18890
  url,
@@ -18897,34 +18901,31 @@
18897
18901
 
18898
18902
  const xhr = new XMLHttpRequest();
18899
18903
  let abortedByTimeout = false;
18904
+ let timeoutId;
18900
18905
 
18901
18906
  xhr.open(method, url, true);
18907
+
18902
18908
  if (headers) {
18903
- Object.entries(headers).forEach(([key, value]) => {
18909
+ for (const [key, value] of Object.entries(headers)) {
18904
18910
  if (isDefined(value)) {
18905
18911
  xhr.setRequestHeader(key, value);
18906
18912
  }
18907
- });
18913
+ }
18908
18914
  }
18909
18915
 
18910
- xhr.onload = function () {
18916
+ xhr.onload = () => {
18917
+ let status = xhr.status || 0;
18911
18918
  const statusText = xhr.statusText || "";
18912
18919
 
18913
- let status = xhr.status;
18914
-
18915
- // fix status code when it is 0 (0 status is undocumented).
18916
- // Occurs when accessing file resources or on Android 4.1 stock browser
18917
- // while retrieving files from application cache.
18918
18920
  if (status === 0) {
18919
18921
  status = xhr.response
18920
18922
  ? 200
18921
- : urlResolve(url).protocol === "file"
18923
+ : new URL(url).protocol === "file:"
18922
18924
  ? 404
18923
18925
  : 0;
18924
18926
  }
18925
18927
 
18926
18928
  completeRequest(
18927
- callback,
18928
18929
  status,
18929
18930
  xhr.response,
18930
18931
  xhr.getAllResponseHeaders(),
@@ -18933,20 +18934,11 @@
18933
18934
  );
18934
18935
  };
18935
18936
 
18936
- xhr.onerror = function () {
18937
- // The response is always empty
18938
- // See https://xhr.spec.whatwg.org/#request-error-steps and https://fetch.spec.whatwg.org/#concept-network-error
18939
- completeRequest(callback, -1, null, null, "", "error");
18940
- };
18941
- xhr.ontimeout = function () {
18942
- // The response is always empty
18943
- // See https://xhr.spec.whatwg.org/#request-error-steps and https://fetch.spec.whatwg.org/#concept-network-error
18944
- completeRequest(callback, -1, null, null, "", "timeout");
18945
- };
18937
+ xhr.onerror = () => completeRequest(-1, null, null, "", "error");
18938
+ xhr.ontimeout = () => completeRequest(-1, null, null, "", "timeout");
18946
18939
 
18947
- xhr.onabort = function () {
18940
+ xhr.onabort = () => {
18948
18941
  completeRequest(
18949
- callback,
18950
18942
  -1,
18951
18943
  null,
18952
18944
  null,
@@ -18956,16 +18948,15 @@
18956
18948
  };
18957
18949
 
18958
18950
  if (eventHandlers) {
18959
- eventHandlers &&
18960
- Object.entries(eventHandlers).forEach(([key, value]) => {
18961
- xhr.addEventListener(key, value);
18962
- });
18951
+ for (const [key, handler] of Object.entries(eventHandlers)) {
18952
+ xhr.addEventListener(key, handler);
18953
+ }
18963
18954
  }
18964
18955
 
18965
18956
  if (uploadEventHandlers) {
18966
- Object.entries(uploadEventHandlers).forEach(([key, value]) => {
18967
- xhr.upload.addEventListener(key, value);
18968
- });
18957
+ for (const [key, handler] of Object.entries(uploadEventHandlers)) {
18958
+ xhr.upload.addEventListener(key, handler);
18959
+ }
18969
18960
  }
18970
18961
 
18971
18962
  if (withCredentials) {
@@ -18976,317 +18967,198 @@
18976
18967
  try {
18977
18968
  xhr.responseType = responseType;
18978
18969
  } catch (e) {
18979
- // WebKit added support for the json responseType value on 09/03/2013
18980
- // https://bugs.webkit.org/show_bug.cgi?id=73648. Versions of Safari prior to 7 are
18981
- // known to throw when setting the value "json" as the response type. Other older
18982
- // browsers implementing the responseType
18983
- //
18984
- // The json response type can be ignored if not supported, because JSON payloads are
18985
- // parsed on the client-side regardless.
18986
- if (responseType !== "json") {
18987
- throw e;
18988
- }
18970
+ if (responseType !== "json") throw e;
18989
18971
  }
18990
18972
  }
18991
18973
 
18992
18974
  xhr.send(isUndefined(post) ? null : post);
18993
18975
 
18994
- // Since we are using xhr.abort() when a request times out, we have to set a flag that
18995
- // indicates to requestAborted if the request timed out or was aborted.
18996
- //
18997
- // http.timeout = numerical timeout timeout
18998
- // http.timeout = $timeout timeout
18999
- // http.timeout = promise abort
19000
- // xhr.abort() abort (The xhr object is normally inaccessible, but
19001
- // can be exposed with the xhrFactory)
19002
- /** @type {number} */
19003
- let timeoutId;
19004
- if (timeout > 0) {
19005
- timeoutId = setTimeout(() => {
19006
- timeoutRequest("timeout");
19007
- }, timeout);
18976
+ if (typeof timeout === "number" && timeout > 0) {
18977
+ timeoutId = setTimeout(() => timeoutRequest("timeout"), timeout);
19008
18978
  } else if (isPromiseLike(timeout)) {
19009
- timeout.then(() => {
19010
- timeoutRequest(isDefined(timeout.$$timeoutId) ? "timeout" : "abort");
18979
+ /** @type {Promise} */ (timeout).then(() => {
18980
+ timeoutRequest(isDefined(timeout["$$timeoutId"]) ? "timeout" : "abort");
19011
18981
  });
19012
18982
  }
19013
18983
 
18984
+ /**
18985
+ * @param {"timeout"|"abort"} reason
18986
+ */
19014
18987
  function timeoutRequest(reason) {
19015
18988
  abortedByTimeout = reason === "timeout";
19016
- if (xhr) {
19017
- xhr.abort();
19018
- }
18989
+ if (xhr) xhr.abort();
19019
18990
  }
19020
18991
 
18992
+ /**
18993
+ * @param {number} status - HTTP status code or -1 for network errors.
18994
+ * @param {*} response - The parsed or raw response from the server.
18995
+ * @param {string|null} headersString - The raw response headers as a string.
18996
+ * @param {string} statusText - The status text returned by the server.
18997
+ * @param {"complete"|"error"|"timeout"|"abort"} xhrStatus - Final status of the request.
18998
+ */
19021
18999
  function completeRequest(
19022
- callback,
19023
19000
  status,
19024
19001
  response,
19025
19002
  headersString,
19026
19003
  statusText,
19027
19004
  xhrStatus,
19028
19005
  ) {
19029
- // cancel timeout and subsequent timeout promise resolution
19030
19006
  if (isDefined(timeoutId)) {
19031
19007
  clearTimeout(timeoutId);
19032
19008
  }
19033
-
19034
19009
  callback(status, response, headersString, statusText, xhrStatus);
19035
19010
  }
19036
19011
  };
19037
19012
  }
19038
19013
 
19014
+ const PATH_MATCH = /^([^?#]*)(\?([^#]*))?(#(.*))?$/;
19015
+ const $locationMinErr = minErr("$location");
19016
+
19017
+ let urlUpdatedByLocation = false;
19018
+
19039
19019
  /**
19040
- * @typedef {Object} DefaultPorts
19041
- * @property {number} http
19042
- * @property {number} https
19043
- * @property {number} ftp
19020
+ * @ignore
19021
+ * The pathname, beginning with "/"
19022
+ * @type {string}
19044
19023
  */
19024
+ let $$path;
19045
19025
 
19046
19026
  /**
19047
- * Represents the configuration options for HTML5 mode.
19048
- *
19049
- * @typedef {Object} Html5Mode
19050
- * @property {boolean} enabled - (default: false) If true, will rely on `history.pushState` to
19051
- * change URLs where supported. Falls back to hash-prefixed paths in browsers that do not
19052
- * support `pushState`.
19053
- * @property {boolean} requireBase - (default: `true`) When html5Mode is enabled, specifies
19054
- * whether or not a `<base>` tag is required to be present. If both `enabled` and `requireBase`
19055
- * are true, and a `<base>` tag is not present, an error will be thrown when `$location` is injected.
19056
- * See the {@link guide/$location $location guide} for more information.
19057
- * @property {boolean|string} rewriteLinks - (default: `true`) When html5Mode is enabled, enables or
19058
- * disables URL rewriting for relative links. If set to a string, URL rewriting will only apply to links
19059
- * with an attribute that matches the given string. For example, if set to `'internal-link'`, URL rewriting
19060
- * will only occur for `<a internal-link>` links. Note that [attribute name normalization](guide/directive#normalization)
19061
- * does not apply here, so `'internalLink'` will **not** match `'internal-link'`.
19027
+ * @type {Object.<string,boolean|Array>}
19062
19028
  */
19063
-
19064
- /** @type {DefaultPorts} */
19065
- const DEFAULT_PORTS = { http: 80, https: 443, ftp: 21 };
19066
- const PATH_MATCH = /^([^?#]*)(\?([^#]*))?(#(.*))?$/;
19067
- const $locationMinErr = minErr("$location");
19029
+ let $$search;
19068
19030
 
19069
19031
  /**
19070
- * @abstract
19032
+ * @ignore
19033
+ * The hash string, minus the hash symbol
19034
+ * @type {string}
19071
19035
  */
19036
+ let $$hash;
19037
+
19072
19038
  class Location {
19073
19039
  /**
19074
19040
  * @param {string} appBase application base URL
19075
19041
  * @param {string} appBaseNoFile application base URL stripped of any filename
19042
+ * @param {boolean} [html5] Defaults to true
19043
+ * @param {string} [prefix] URL path prefix for html5 mode or hash prefix for hashbang mode
19076
19044
  */
19077
- constructor(appBase, appBaseNoFile) {
19078
- const parsedUrl = urlResolve(appBase);
19079
-
19045
+ constructor(appBase, appBaseNoFile, html5 = true, prefix) {
19080
19046
  /** @type {string} */
19081
19047
  this.appBase = appBase;
19082
19048
 
19083
19049
  /** @type {string} */
19084
19050
  this.appBaseNoFile = appBaseNoFile;
19085
19051
 
19086
- /**
19087
- * An absolute URL is the full URL, including protocol (http/https ), the optional subdomain (e.g. www ), domain (example.com), and path (which includes the directory and slug).
19088
- * @type {string}
19089
- */
19090
- this.$$absUrl = "";
19091
-
19092
- /**
19093
- * If html5 mode is enabled
19094
- * @type {boolean}
19095
- */
19096
- this.$$html5 = false;
19097
-
19098
- /**
19099
- * Has any change been replacing?
19100
- * @type {boolean}
19101
- */
19102
- this.$$replace = false;
19052
+ /** @type {boolean} */
19053
+ this.html5 = html5;
19103
19054
 
19104
- /** @type {string} */
19105
- this.$$protocol = parsedUrl.protocol;
19055
+ /** @type {string | undefined} */
19056
+ this.basePrefix = html5 ? prefix || "" : undefined;
19106
19057
 
19107
- /** @type {string} */
19108
- this.$$host = parsedUrl.hostname;
19109
-
19110
- /**
19111
- * The port, without ":"
19112
- * @type {number}
19113
- */
19114
- this.$$port =
19115
- toInt(parsedUrl.port) || DEFAULT_PORTS[parsedUrl.protocol] || null;
19058
+ /** @type {string | undefined} */
19059
+ this.hashPrefix = html5 ? undefined : prefix;
19116
19060
 
19117
19061
  /**
19118
- * The pathname, beginning with "/"
19062
+ * An absolute URL is the full URL, including protocol (http/https ), the optional subdomain (e.g. www ), domain (example.com), and path (which includes the directory and slug)
19063
+ * with all segments encoded according to rules specified in [RFC 3986](http://www.ietf.org/rfc/rfc3986.txt).
19119
19064
  * @type {string}
19120
19065
  */
19121
- this.$$path = undefined;
19066
+ this.absUrl = "";
19122
19067
 
19123
19068
  /**
19124
- * The hash string, minus the hash symbol
19069
+ * @ignore
19070
+ * Current url
19125
19071
  * @type {string}
19126
19072
  */
19127
- this.$$hash = undefined;
19073
+ this.$$url = undefined;
19128
19074
 
19129
19075
  /**
19130
- * Helper property for scope watch changes
19131
- * @type {boolean}
19076
+ * @ignore
19077
+ * Callback to update browser url
19078
+ * @type {Function}
19132
19079
  */
19133
- this.$$urlUpdatedByLocation = false;
19080
+ this.$$updateBrowser = undefined;
19134
19081
  }
19135
19082
 
19136
19083
  /**
19137
- * Return full URL representation with all segments encoded according to rules specified in
19138
- * [RFC 3986](http://www.ietf.org/rfc/rfc3986.txt).
19139
- *
19140
- * @return {string} full URL
19141
- */
19142
- absUrl() {
19143
- return this.$$absUrl;
19144
- }
19145
-
19146
- /**
19147
- * This method is getter / setter.
19148
- *
19149
- * Return URL (e.g. `/path?a=b#hash`) when called without any parameter.
19150
19084
  * Change path, search and hash, when called with parameter and return `$location`.
19151
19085
  *
19152
- * @param {string=} url New URL without base prefix (e.g. `/path?a=b#hash`)
19153
- * @return {Location|string} url
19086
+ * @param {string} url New URL without base prefix (e.g. `/path?a=b#hash`)
19087
+ * @return {Location} url
19154
19088
  */
19155
- url(url) {
19156
- if (isUndefined(url)) {
19157
- return this.$$url;
19158
- }
19159
-
19089
+ setUrl(url) {
19160
19090
  const match = PATH_MATCH.exec(url);
19161
- if (match[1] || url === "") this.path(decodeURIComponent(match[1]));
19162
- if (match[2] || match[1] || url === "") this.search(match[3] || "");
19163
- this.hash(match[5] || "");
19091
+ if (match[1] || url === "") this.setPath(decodeURIComponent(match[1]));
19092
+ if (match[2] || match[1] || url === "") this.setSearch(match[3] || "");
19093
+ this.setHash(match[5] || "");
19164
19094
 
19165
19095
  return this;
19166
19096
  }
19167
19097
 
19168
19098
  /**
19099
+ * Return URL (e.g. `/path?a=b#hash`) when called without any parameter.
19169
19100
  *
19170
- * Return protocol of current URL.
19171
- * @return {string} protocol of current URL
19101
+ * @return {string} url
19172
19102
  */
19173
- protocol() {
19174
- return this.$$protocol;
19103
+ getUrl() {
19104
+ return this.$$url;
19175
19105
  }
19176
19106
 
19177
19107
  /**
19178
- * This method is getter only.
19179
- *
19180
- * Return host of current URL.
19181
- *
19182
- * Note: compared to the non-AngularTS version `location.host` which returns `hostname:port`, this returns the `hostname` portion only.
19108
+ * Change path parameter and return `$location`.
19183
19109
  *
19184
- *
19185
- * @return {string} host of current URL.
19110
+ * @param {(string|number)} path New path
19111
+ * @return {Location}
19186
19112
  */
19187
- host() {
19188
- return this.$$host;
19189
- }
19190
-
19191
- /**
19192
- * This method is getter only.
19193
- *
19194
- * Return port of current URL.
19195
- *
19196
- *
19197
- * ```js
19198
- * // given URL http://example.com/#/some/path?foo=bar&baz=xoxo
19199
- * let port = $location.port();
19200
- * // => 80
19201
- * ```
19202
- *
19203
- * @return {number} port
19204
- */
19205
- port() {
19206
- return this.$$port;
19113
+ setPath(path) {
19114
+ let newPath = path !== null ? path.toString() : "";
19115
+ $$path = newPath.charAt(0) === "/" ? newPath : `/${newPath}`;
19116
+ this.$$compose();
19117
+ return this;
19207
19118
  }
19208
19119
 
19209
19120
  /**
19210
- * This method is getter / setter.
19211
- *
19212
- * Return path of current URL when called without any parameter.
19213
19121
  *
19214
- * Change path when called with parameter and return `$location`.
19122
+ * Return path of current URL
19215
19123
  *
19216
- * Note: Path should always begin with forward slash (/), this method will add the forward slash
19217
- * if it is missing.
19218
- *
19219
- *
19220
- * ```js
19221
- * // given URL http://example.com/#/some/path?foo=bar&baz=xoxo
19222
- * let path = $location.path();
19223
- * // => "/some/path"
19224
- * ```
19225
- *
19226
- * @param {(string|number)=} path New path
19227
- * @return {(string|object)} path if called with no parameters, or `$location` if called with a parameter
19124
+ * @return {string}
19228
19125
  */
19229
- path(path) {
19230
- if (isUndefined(path)) {
19231
- return this.$$path;
19232
- }
19233
- let newPath = path !== null ? path.toString() : "";
19234
- this.$$path = newPath.charAt(0) === "/" ? newPath : `/${newPath}`;
19235
- this.$$compose();
19236
- return this;
19126
+ getPath() {
19127
+ return $$path;
19237
19128
  }
19238
19129
 
19239
19130
  /**
19240
- * This method is getter / setter.
19241
- *
19242
- * Returns the hash fragment when called without any parameters.
19243
- *
19244
19131
  * Changes the hash fragment when called with a parameter and returns `$location`.
19245
- *
19246
- *
19247
- * ```js
19248
- * // given URL http://example.com/#/some/path?foo=bar&baz=xoxo#hashValue
19249
- * let hash = $location.hash();
19250
- * // => "hashValue"
19251
- * ```
19252
- *
19253
- * @param {(string|number)=} hash New hash fragment
19254
- * @return {string|Location} hash
19132
+ * @param {(string|number)} hash New hash fragment
19133
+ * @return {Location} hash
19255
19134
  */
19256
- hash(hash) {
19257
- if (isUndefined(hash)) {
19258
- return this.$$hash;
19259
- }
19260
-
19261
- this.$$hash = hash !== null ? hash.toString() : "";
19135
+ setHash(hash) {
19136
+ $$hash = hash !== null ? hash.toString() : "";
19262
19137
  this.$$compose();
19263
19138
  return this;
19264
19139
  }
19265
19140
 
19266
19141
  /**
19267
- * If called, all changes to $location during the current `$digest` will replace the current history
19268
- * record, instead of adding a new one.
19142
+ * Returns the hash fragment when called without any parameters.
19143
+ * @return {string} hash
19269
19144
  */
19270
- replace() {
19271
- this.$$replace = true;
19272
- return this;
19145
+ getHash() {
19146
+ return $$hash;
19273
19147
  }
19274
19148
 
19275
19149
  /**
19276
- * Returns or sets the search part (as object) of current URL when called without any parameter
19150
+ * Sets the search part (as object) of current URL
19277
19151
  *
19278
- * @param {string|Object=} search New search params - string or hash object.
19152
+ * @param {string|Object} search New search params - string or hash object.
19279
19153
  * @param {(string|number|Array<string>|boolean)=} paramValue If search is a string or number, then paramValue will override only a single search property.
19280
- * @returns {Object|Location} Search object or Location object
19154
+ * @returns {Object} Search object or Location object
19281
19155
  */
19282
- search(search, paramValue) {
19156
+ setSearch(search, paramValue) {
19283
19157
  switch (arguments.length) {
19284
- case 0:
19285
- return this.$$search;
19286
19158
  case 1:
19287
19159
  if (isString(search) || isNumber(search)) {
19288
19160
  search = search.toString();
19289
- this.$$search = parseKeyValue(search);
19161
+ $$search = parseKeyValue(search);
19290
19162
  } else if (isObject(search)) {
19291
19163
  search = structuredClone(search, {});
19292
19164
  // remove object undefined or null properties
@@ -19294,7 +19166,7 @@
19294
19166
  if (value == null) delete search[key];
19295
19167
  });
19296
19168
 
19297
- this.$$search = search;
19169
+ $$search = search;
19298
19170
  } else {
19299
19171
  throw $locationMinErr(
19300
19172
  "isrcharg",
@@ -19304,9 +19176,10 @@
19304
19176
  break;
19305
19177
  default:
19306
19178
  if (isUndefined(paramValue) || paramValue === null) {
19307
- delete this.$$search[search];
19179
+ delete $$search[search];
19308
19180
  } else {
19309
- this.$$search[search] = paramValue;
19181
+ // @ts-ignore
19182
+ $$search[search] = paramValue;
19310
19183
  }
19311
19184
  }
19312
19185
 
@@ -19315,28 +19188,28 @@
19315
19188
  }
19316
19189
 
19317
19190
  /**
19318
- * Compose url and update `url` and `absUrl` property
19319
- * @returns {void}
19191
+ * Returns the search part (as object) of current URL
19192
+ *
19193
+ * @returns {Object} Search object or Location object
19320
19194
  */
19321
- $$compose() {
19322
- this.$$url = normalizePath(this.$$path, this.$$search, this.$$hash);
19323
- this.$$absUrl = this.$$normalizeUrl(this.$$url);
19324
- this.$$urlUpdatedByLocation = true;
19195
+ getSearch() {
19196
+ return $$search;
19325
19197
  }
19326
19198
 
19327
19199
  /**
19328
- * @param {string} _url
19329
- * @returns {string}
19200
+ * @private
19201
+ * Compose url and update `url` and `absUrl` property
19330
19202
  */
19331
- $$normalizeUrl(_url) {
19332
- throw new Error(`Method not implemented ${_url}`);
19203
+ $$compose() {
19204
+ this.$$url = normalizePath($$path, $$search, $$hash);
19205
+ this.absUrl = this.html5
19206
+ ? this.appBaseNoFile + this.$$url.substring(1)
19207
+ : this.appBase + (this.$$url ? this.hashPrefix + this.$$url : "");
19208
+ urlUpdatedByLocation = true;
19209
+ setTimeout(() => this.$$updateBrowser && this.$$updateBrowser());
19333
19210
  }
19334
19211
 
19335
19212
  /**
19336
- * This method is getter / setter.
19337
- *
19338
- * Return the history state object when called without any parameter.
19339
- *
19340
19213
  * Change the history state object when called with one parameter and return `$location`.
19341
19214
  * The state object is later passed to `pushState` or `replaceState`.
19342
19215
  * See {@link https://developer.mozilla.org/en-US/docs/Web/API/History/pushState#state|History.state}
@@ -19344,85 +19217,30 @@
19344
19217
  * NOTE: This method is supported only in HTML5 mode and only in browsers supporting
19345
19218
  * the HTML5 History API (i.e. methods `pushState` and `replaceState`). If you need to support
19346
19219
  * older browsers (like IE9 or Android < 4.0), don't use this method.
19347
- *
19348
- * @param {any} state State object for pushState or replaceState
19349
- * @return {any} state
19220
+ * @param {any} state
19221
+ * @returns {Location}
19350
19222
  */
19351
- state(state) {
19352
- if (!arguments.length) {
19353
- return this.$$state;
19354
- }
19355
-
19356
- if (!(this instanceof LocationHtml5Url) || !this.$$html5) {
19223
+ setState(state) {
19224
+ if (!this.html5) {
19357
19225
  throw $locationMinErr(
19358
19226
  "nostate",
19359
- "History API state support is available only " +
19360
- "in HTML5 mode and only in browsers supporting HTML5 History API",
19227
+ "History API state support is available only in HTML5 mode",
19361
19228
  );
19362
19229
  }
19363
- // The user might modify `stateObject` after invoking `$location.state(stateObject)`
19230
+ // The user might modify `stateObject` after invoking `$location.setState(stateObject)`
19364
19231
  // but we're changing the $$state reference to $browser.state() during the $digest
19365
19232
  // so the modification window is narrow.
19366
19233
  this.$$state = isUndefined(state) ? null : state;
19367
- this.$$urlUpdatedByLocation = true;
19234
+ urlUpdatedByLocation = true;
19368
19235
  return this;
19369
19236
  }
19370
19237
 
19371
19238
  /**
19372
- * @param {string} _url
19373
- * @param {string} _url2
19374
- * @returns {boolean}
19375
- */
19376
- $$parseLinkUrl(_url, _url2) {
19377
- throw new Error(`Method not implemented ${_url} ${_url2}`);
19378
- }
19379
-
19380
- $$parse(_url) {
19381
- throw new Error(`Method not implemented ${_url}`);
19382
- }
19383
- }
19384
-
19385
- /**
19386
- * This object is exposed as $location service when HTML5 mode is enabled and supported
19387
- */
19388
- class LocationHtml5Url extends Location {
19389
- /**
19390
- * @param {string} appBase application base URL
19391
- * @param {string} appBaseNoFile application base URL stripped of any filename
19392
- * @param {string} basePrefix URL path prefix
19393
- */
19394
- constructor(appBase, appBaseNoFile, basePrefix) {
19395
- super(appBase, appBaseNoFile);
19396
- this.$$html5 = true;
19397
- this.basePrefix = basePrefix || "";
19398
- }
19399
-
19400
- /**
19401
- * Parse given HTML5 (regular) URL string into properties
19402
- * @param {string} url HTML5 URL
19239
+ * Return the history state object
19240
+ * @returns {any}
19403
19241
  */
19404
- $$parse(url) {
19405
- const pathUrl = stripBaseUrl(this.appBaseNoFile, url);
19406
- if (!isString(pathUrl)) {
19407
- throw $locationMinErr(
19408
- "ipthprfx",
19409
- 'Invalid url "{0}", missing path prefix "{1}".',
19410
- url,
19411
- this.appBaseNoFile,
19412
- );
19413
- }
19414
-
19415
- parseAppUrl(pathUrl, this, true);
19416
-
19417
- if (!this.$$path) {
19418
- this.$$path = "/";
19419
- }
19420
-
19421
- this.$$compose();
19422
- }
19423
-
19424
- $$normalizeUrl(url) {
19425
- return this.appBaseNoFile + url.substring(1); // first char is always '/'
19242
+ getState() {
19243
+ return this.$$state;
19426
19244
  }
19427
19245
 
19428
19246
  /**
@@ -19430,148 +19248,138 @@
19430
19248
  * @param {string} relHref
19431
19249
  * @returns {boolean}
19432
19250
  */
19433
- $$parseLinkUrl(url, relHref) {
19434
- if (relHref && relHref[0] === "#") {
19435
- // special case for links to hash fragments:
19436
- // keep the old url and only replace the hash fragment
19437
- this.hash(relHref.slice(1));
19438
- return true;
19439
- }
19440
- let appUrl;
19441
- let prevAppUrl;
19442
- let rewrittenUrl;
19251
+ parseLinkUrl(url, relHref) {
19252
+ if (this.html5) {
19253
+ if (relHref && relHref[0] === "#") {
19254
+ // special case for links to hash fragments:
19255
+ // keep the old url and only replace the hash fragment
19256
+ this.setHash(relHref.slice(1));
19257
+ return true;
19258
+ }
19259
+ let appUrl;
19260
+ let prevAppUrl;
19261
+ let rewrittenUrl;
19443
19262
 
19444
- if (isDefined((appUrl = stripBaseUrl(this.appBase, url)))) {
19445
- prevAppUrl = appUrl;
19446
- if (
19447
- this.basePrefix &&
19448
- isDefined((appUrl = stripBaseUrl(this.basePrefix, appUrl)))
19449
- ) {
19450
- rewrittenUrl =
19451
- this.appBaseNoFile + (stripBaseUrl("/", appUrl) || appUrl);
19452
- } else {
19453
- rewrittenUrl = this.appBase + prevAppUrl;
19263
+ if (isDefined((appUrl = stripBaseUrl(this.appBase, url)))) {
19264
+ prevAppUrl = appUrl;
19265
+ if (
19266
+ this.basePrefix &&
19267
+ isDefined((appUrl = stripBaseUrl(this.basePrefix, appUrl)))
19268
+ ) {
19269
+ rewrittenUrl =
19270
+ this.appBaseNoFile + (stripBaseUrl("/", appUrl) || appUrl);
19271
+ } else {
19272
+ rewrittenUrl = this.appBase + prevAppUrl;
19273
+ }
19274
+ } else if (isDefined((appUrl = stripBaseUrl(this.appBaseNoFile, url)))) {
19275
+ rewrittenUrl = this.appBaseNoFile + appUrl;
19276
+ } else if (this.appBaseNoFile === `${url}/`) {
19277
+ rewrittenUrl = this.appBaseNoFile;
19454
19278
  }
19455
- } else if (isDefined((appUrl = stripBaseUrl(this.appBaseNoFile, url)))) {
19456
- rewrittenUrl = this.appBaseNoFile + appUrl;
19457
- } else if (this.appBaseNoFile === `${url}/`) {
19458
- rewrittenUrl = this.appBaseNoFile;
19459
- }
19460
- if (rewrittenUrl) {
19461
- this.$$parse(rewrittenUrl);
19279
+ if (rewrittenUrl) {
19280
+ this.parse(rewrittenUrl);
19281
+ }
19282
+ return !!rewrittenUrl;
19283
+ } else {
19284
+ if (stripHash(this.appBase) === stripHash(url)) {
19285
+ this.parse(url);
19286
+ return true;
19287
+ }
19288
+ return false;
19462
19289
  }
19463
- return !!rewrittenUrl;
19464
19290
  }
19465
- }
19466
19291
 
19467
- /**
19468
- * LocationHashbangUrl represents URL
19469
- * This object is exposed as $location service when developer doesn't opt into html5 mode.
19470
- * It also serves as the base class for html5 mode fallback on legacy browsers.
19471
- *
19472
- */
19473
- class LocationHashbangUrl extends Location {
19474
19292
  /**
19475
- * @param {string} appBase application base URL
19476
- * @param {string} appBaseNoFile application base URL stripped of any filename
19477
- * @param {string} hashPrefix hashbang prefix
19293
+ * Parse given HTML5 (regular) URL string into properties
19294
+ * @param {string} url HTML5 URL
19478
19295
  */
19479
- constructor(appBase, appBaseNoFile, hashPrefix) {
19480
- super(appBase, appBaseNoFile);
19481
- this.hashPrefix = hashPrefix;
19482
- }
19296
+ parse(url) {
19297
+ if (this.html5) {
19298
+ const pathUrl = stripBaseUrl(this.appBaseNoFile, url);
19299
+ if (!isString(pathUrl)) {
19300
+ throw $locationMinErr(
19301
+ "ipthprfx",
19302
+ 'Invalid url "{0}", missing path prefix "{1}".',
19303
+ url,
19304
+ this.appBaseNoFile,
19305
+ );
19306
+ }
19483
19307
 
19484
- /**
19485
- * Parse given hashbang URL into properties
19486
- * @param {string} url Hashbang URL
19487
- */
19488
- $$parse(url) {
19489
- const withoutBaseUrl =
19490
- stripBaseUrl(this.appBase, url) || stripBaseUrl(this.appBaseNoFile, url);
19491
- let withoutHashUrl;
19308
+ parseAppUrl(pathUrl, true);
19492
19309
 
19493
- if (!isUndefined(withoutBaseUrl) && withoutBaseUrl.charAt(0) === "#") {
19494
- // The rest of the URL starts with a hash so we have
19495
- // got either a hashbang path or a plain hash fragment
19496
- withoutHashUrl = stripBaseUrl(this.hashPrefix, withoutBaseUrl);
19497
- if (isUndefined(withoutHashUrl)) {
19498
- // There was no hashbang prefix so we just have a hash fragment
19499
- withoutHashUrl = withoutBaseUrl;
19310
+ if (!$$path) {
19311
+ $$path = "/";
19500
19312
  }
19313
+
19314
+ this.$$compose();
19501
19315
  } else {
19502
- // There was no hashbang path nor hash fragment:
19503
- // If we are in HTML5 mode we use what is left as the path;
19504
- // Otherwise we ignore what is left
19505
- if (this.$$html5) {
19506
- withoutHashUrl = withoutBaseUrl;
19316
+ const withoutBaseUrl =
19317
+ stripBaseUrl(this.appBase, url) ||
19318
+ stripBaseUrl(this.appBaseNoFile, url);
19319
+ let withoutHashUrl;
19320
+
19321
+ if (!isUndefined(withoutBaseUrl) && withoutBaseUrl.charAt(0) === "#") {
19322
+ // The rest of the URL starts with a hash so we have
19323
+ // got either a hashbang path or a plain hash fragment
19324
+ withoutHashUrl = stripBaseUrl(this.hashPrefix, withoutBaseUrl);
19325
+ if (isUndefined(withoutHashUrl)) {
19326
+ // There was no hashbang prefix so we just have a hash fragment
19327
+ withoutHashUrl = withoutBaseUrl;
19328
+ }
19507
19329
  } else {
19508
- withoutHashUrl = "";
19509
- if (isUndefined(withoutBaseUrl)) {
19510
- this.appBase = url;
19511
- /** @type {?} */ (this).replace();
19330
+ // There was no hashbang path nor hash fragment:
19331
+ // If we are in HTML5 mode we use what is left as the path;
19332
+ // Otherwise we ignore what is left
19333
+ if (this.html5) {
19334
+ withoutHashUrl = withoutBaseUrl;
19335
+ } else {
19336
+ withoutHashUrl = "";
19337
+ if (isUndefined(withoutBaseUrl)) {
19338
+ this.appBase = url;
19339
+ }
19512
19340
  }
19513
19341
  }
19514
- }
19515
19342
 
19516
- parseAppUrl(withoutHashUrl, this, false);
19343
+ parseAppUrl(withoutHashUrl, false);
19517
19344
 
19518
- this.$$path = removeWindowsDriveName(
19519
- this.$$path,
19520
- withoutHashUrl,
19521
- this.appBase,
19522
- );
19345
+ $$path = removeWindowsDriveName($$path, withoutHashUrl, this.appBase);
19523
19346
 
19524
- this.$$compose();
19347
+ this.$$compose();
19525
19348
 
19526
- /*
19527
- * In Windows, on an anchor node on documents loaded from
19528
- * the filesystem, the browser will return a pathname
19529
- * prefixed with the drive name ('/C:/path') when a
19530
- * pathname without a drive is set:
19531
- * * a.setAttribute('href', '/foo')
19532
- * * a.pathname === '/C:/foo' //true
19533
- *
19534
- * Inside of AngularTS, we're always using pathnames that
19535
- * do not include drive names for routing.
19536
- */
19537
- function removeWindowsDriveName(path, url, base) {
19538
19349
  /*
19539
- Matches paths for file protocol on windows,
19540
- such as /C:/foo/bar, and captures only /foo/bar.
19541
- */
19542
- const windowsFilePathExp = /^\/[A-Z]:(\/.*)/;
19543
-
19544
- let firstPathSegmentMatch;
19545
-
19546
- // Get the relative path from the input URL.
19547
- if (startsWith(url, base)) {
19548
- url = url.replace(base, "");
19549
- }
19350
+ * In Windows, on an anchor node on documents loaded from
19351
+ * the filesystem, the browser will return a pathname
19352
+ * prefixed with the drive name ('/C:/path') when a
19353
+ * pathname without a drive is set:
19354
+ * * a.setAttribute('href', '/foo')
19355
+ * * a.pathname === '/C:/foo' //true
19356
+ *
19357
+ * Inside of AngularTS, we're always using pathnames that
19358
+ * do not include drive names for routing.
19359
+ */
19360
+ function removeWindowsDriveName(path, url, base) {
19361
+ /*
19362
+ Matches paths for file protocol on windows,
19363
+ such as /C:/foo/bar, and captures only /foo/bar.
19364
+ */
19365
+ const windowsFilePathExp = /^\/[A-Z]:(\/.*)/;
19550
19366
 
19551
- // The input URL intentionally contains a first path segment that ends with a colon.
19552
- if (windowsFilePathExp.exec(url)) {
19553
- return path;
19554
- }
19367
+ let firstPathSegmentMatch;
19555
19368
 
19556
- firstPathSegmentMatch = windowsFilePathExp.exec(path);
19557
- return firstPathSegmentMatch ? firstPathSegmentMatch[1] : path;
19558
- }
19559
- }
19369
+ // Get the relative path from the input URL.
19370
+ if (startsWith(url, base)) {
19371
+ url = url.replace(base, "");
19372
+ }
19560
19373
 
19561
- $$normalizeUrl(url) {
19562
- return this.appBase + (url ? this.hashPrefix + url : "");
19563
- }
19374
+ // The input URL intentionally contains a first path segment that ends with a colon.
19375
+ if (windowsFilePathExp.exec(url)) {
19376
+ return path;
19377
+ }
19564
19378
 
19565
- /**
19566
- * @param {string} url
19567
- * @returns {boolean}
19568
- */
19569
- $$parseLinkUrl(url) {
19570
- if (stripHash(this.appBase) === stripHash(url)) {
19571
- this.$$parse(url);
19572
- return true;
19379
+ firstPathSegmentMatch = windowsFilePathExp.exec(path);
19380
+ return firstPathSegmentMatch ? firstPathSegmentMatch[1] : path;
19381
+ }
19573
19382
  }
19574
- return false;
19575
19383
  }
19576
19384
  }
19577
19385
 
@@ -19580,20 +19388,20 @@
19580
19388
  /** @type {string} */
19581
19389
  this.hashPrefixConf = "!";
19582
19390
 
19583
- /** @type {Html5Mode} */
19391
+ /** @type {import("./interface.ts").Html5Mode} */
19584
19392
  this.html5ModeConf = {
19585
- enabled: false,
19586
- requireBase: true,
19393
+ enabled: true,
19394
+ requireBase: false,
19587
19395
  rewriteLinks: true,
19588
19396
  };
19589
19397
 
19590
- /** @type {Array<import("./interface.js").UrlChangeListener>} */
19398
+ /** @type {Array<import("./interface.ts").UrlChangeListener>} */
19591
19399
  this.urlChangeListeners = [];
19592
19400
  this.urlChangeInit = false;
19593
19401
 
19594
19402
  /** @type {History['state']} */
19595
19403
  this.cachedState = null;
19596
- /** @typeof {History.state} */
19404
+ /** @type {History['state']} */
19597
19405
  this.lastHistoryState = null;
19598
19406
  /** @type {string} */
19599
19407
  this.lastBrowserUrl = window.location.href;
@@ -19604,14 +19412,19 @@
19604
19412
  // URL API
19605
19413
  /// ///////////////////////////////////////////////////////////
19606
19414
 
19415
+ /**
19416
+ * Updates the browser's current URL and history state.
19417
+ *
19418
+ * @param {string|undefined} url - The target URL to navigate to.
19419
+ * @param {*} [state=null] - Optional history state object to associate with the new URL.
19420
+ * @returns {LocationProvider}
19421
+ */
19607
19422
  setUrl(url, state) {
19608
19423
  if (state === undefined) {
19609
19424
  state = null;
19610
19425
  }
19611
-
19612
- // setter
19613
19426
  if (url) {
19614
- url = urlResolve(url).href;
19427
+ url = new URL(url).href;
19615
19428
 
19616
19429
  if (this.lastBrowserUrl === url && this.lastHistoryState === state) {
19617
19430
  return this;
@@ -19628,7 +19441,7 @@
19628
19441
  * Returns the current URL with any empty hash (`#`) removed.
19629
19442
  * @return {string}
19630
19443
  */
19631
- getUrl() {
19444
+ getBrowserUrl() {
19632
19445
  return trimEmptyHash(window.location.href);
19633
19446
  }
19634
19447
 
@@ -19656,19 +19469,17 @@
19656
19469
 
19657
19470
  /**
19658
19471
  * Fires the state or URL change event.
19659
- *
19660
- * @private
19661
19472
  */
19662
- fireStateOrUrlChange() {
19473
+ #fireStateOrUrlChange() {
19663
19474
  const prevLastHistoryState = this.lastHistoryState;
19664
19475
  this.cacheState();
19665
19476
  if (
19666
- this.lastBrowserUrl === this.getUrl() &&
19477
+ this.lastBrowserUrl === this.getBrowserUrl() &&
19667
19478
  prevLastHistoryState === this.cachedState
19668
19479
  ) {
19669
19480
  return;
19670
19481
  }
19671
- this.lastBrowserUrl = this.getUrl();
19482
+ this.lastBrowserUrl = this.getBrowserUrl();
19672
19483
  this.lastHistoryState = this.cachedState;
19673
19484
  this.urlChangeListeners.forEach((listener) => {
19674
19485
  listener(trimEmptyHash(window.location.href), this.cachedState);
@@ -19681,131 +19492,75 @@
19681
19492
  * @param {import("./interface.js").UrlChangeListener} callback - The callback function to register.
19682
19493
  * @returns void
19683
19494
  */
19684
- onUrlChange(callback) {
19495
+ #onUrlChange(callback) {
19685
19496
  if (!this.urlChangeInit) {
19686
- window.addEventListener("popstate", this.fireStateOrUrlChange.bind(this));
19497
+ window.addEventListener(
19498
+ "popstate",
19499
+ this.#fireStateOrUrlChange.bind(this),
19500
+ );
19687
19501
  window.addEventListener(
19688
19502
  "hashchange",
19689
- this.fireStateOrUrlChange.bind(this),
19503
+ this.#fireStateOrUrlChange.bind(this),
19690
19504
  );
19691
19505
  this.urlChangeInit = true;
19692
19506
  }
19693
19507
  this.urlChangeListeners.push(callback);
19694
19508
  }
19695
19509
 
19696
- /**
19697
- * The default value for the prefix is `'!'`.
19698
- * @param {string=} prefix Prefix for hash part (containing path and search)
19699
- * @returns {void}
19700
- */
19701
- setHashPrefix(prefix) {
19702
- this.hashPrefixConf = prefix;
19703
- }
19704
-
19705
- /**
19706
- * Current hash prefix
19707
- * @returns {string}
19708
- */
19709
- getHashPrefix() {
19710
- return this.hashPrefixConf;
19711
- }
19712
-
19713
- /**
19714
- * Configures html5 mode
19715
- * @param {(boolean|Html5Mode)=} mode If boolean, sets `html5Mode.enabled` to value. Otherwise, accepts html5Mode object
19716
- *
19717
- * @returns {void}
19718
- */
19719
- setHtml5Mode(mode) {
19720
- if (isBoolean(mode)) {
19721
- this.html5ModeConf.enabled = /** @type {boolean} */ (mode);
19722
- }
19723
- if (isObject(mode)) {
19724
- const html5Mode = /** @type {Html5Mode} */ (mode);
19725
- if (isDefined(html5Mode.enabled) && isBoolean(html5Mode.enabled)) {
19726
- this.html5ModeConf.enabled = html5Mode.enabled;
19727
- }
19728
-
19729
- if (
19730
- isDefined(html5Mode.requireBase) &&
19731
- isBoolean(html5Mode.requireBase)
19732
- ) {
19733
- this.html5ModeConf.requireBase = html5Mode.requireBase;
19734
- }
19735
-
19736
- if (
19737
- isDefined(html5Mode.rewriteLinks) &&
19738
- (isBoolean(html5Mode.rewriteLinks) || isString(html5Mode.rewriteLinks))
19739
- ) {
19740
- this.html5ModeConf.rewriteLinks = html5Mode.rewriteLinks;
19741
- }
19742
- }
19743
- }
19744
-
19745
- /**
19746
- * Returns html5 mode cofiguration
19747
- * @returns {Html5Mode}
19748
- */
19749
- getHtml5Mode() {
19750
- return this.html5ModeConf;
19751
- }
19752
-
19753
19510
  $get = [
19754
- "$rootScope",
19755
- "$rootElement",
19511
+ $injectTokens.$rootScope,
19512
+ $injectTokens.$rootElement,
19756
19513
  /**
19757
19514
  *
19758
19515
  * @param {import('../../core/scope/scope.js').Scope} $rootScope
19759
19516
  * @param {Element} $rootElement
19760
- * @returns
19517
+ * @returns {Location}
19761
19518
  */
19762
19519
  ($rootScope, $rootElement) => {
19763
19520
  /** @type {Location} */
19764
19521
  let $location;
19765
- let LocationMode;
19766
19522
  const baseHref = getBaseHref(); // if base[href] is undefined, it defaults to ''
19767
19523
  const initialUrl = trimEmptyHash(window.location.href);
19768
19524
  let appBase;
19769
19525
 
19770
- if (this.getHtml5Mode().enabled) {
19771
- if (!baseHref && this.getHtml5Mode().requireBase) {
19526
+ if (this.html5ModeConf.enabled) {
19527
+ if (!baseHref && this.html5ModeConf.requireBase) {
19772
19528
  throw $locationMinErr(
19773
19529
  "nobase",
19774
19530
  "$location in HTML5 mode requires a <base> tag to be present!",
19775
19531
  );
19776
19532
  }
19777
19533
  appBase = serverBase(initialUrl) + (baseHref || "/");
19778
- LocationMode = LocationHtml5Url;
19779
19534
  } else {
19780
19535
  appBase = stripHash(initialUrl);
19781
- LocationMode = LocationHashbangUrl;
19782
19536
  }
19783
19537
  const appBaseNoFile = stripFile(appBase);
19784
19538
 
19785
- $location = new LocationMode(
19539
+ $location = new Location(
19786
19540
  appBase,
19787
19541
  appBaseNoFile,
19788
- `#${this.getHashPrefix()}`,
19542
+ this.html5ModeConf.enabled,
19543
+ `#${this.hashPrefixConf}`,
19789
19544
  );
19790
- $location.$$parseLinkUrl(initialUrl, initialUrl);
19545
+ $location.parseLinkUrl(initialUrl, initialUrl);
19791
19546
 
19792
19547
  $location.$$state = this.state();
19793
19548
 
19794
19549
  const IGNORE_URI_REGEXP = /^\s*(javascript|mailto):/i;
19795
19550
 
19796
19551
  const setBrowserUrlWithFallback = (url, state) => {
19797
- const oldUrl = $location.url();
19552
+ const oldUrl = $location.getUrl();
19798
19553
  const oldState = $location.$$state;
19799
19554
  try {
19800
19555
  this.setUrl(url, state);
19801
19556
 
19802
- // Make sure $location.state() returns referentially identical (not just deeply equal)
19557
+ // Make sure $location.getState() returns referentially identical (not just deeply equal)
19803
19558
  // state object; this makes possible quick checking if the state changed in the digest
19804
19559
  // loop. Checking deep equality would be too expensive.
19805
19560
  $location.$$state = this.state();
19806
19561
  } catch (e) {
19807
19562
  // Restore old values if pushState fails
19808
- $location.url(/** @type {string} */ (oldUrl));
19563
+ $location.setUrl(/** @type {string} */ (oldUrl));
19809
19564
  $location.$$state = oldState;
19810
19565
 
19811
19566
  throw e;
@@ -19816,7 +19571,7 @@
19816
19571
  "click",
19817
19572
  /** @param {MouseEvent} event */
19818
19573
  (event) => {
19819
- const rewriteLinks = this.getHtml5Mode().rewriteLinks;
19574
+ const rewriteLinks = this.html5ModeConf.rewriteLinks;
19820
19575
  // TODO(vojta): rewrite link when opening in new tab/window (in legacy browser)
19821
19576
  // currently we open nice url link and redirect then
19822
19577
 
@@ -19825,7 +19580,6 @@
19825
19580
  event.ctrlKey ||
19826
19581
  event.metaKey ||
19827
19582
  event.shiftKey ||
19828
- event.which === 2 ||
19829
19583
  event.button === 2
19830
19584
  ) {
19831
19585
  return;
@@ -19860,7 +19614,7 @@
19860
19614
  // an animation.
19861
19615
 
19862
19616
  const scvAnimatedString = /** @type {unknown} */ (absHref);
19863
- absHref = urlResolve(
19617
+ absHref = new URL(
19864
19618
  /** @type {SVGAnimatedString } */ (scvAnimatedString).animVal,
19865
19619
  ).href;
19866
19620
  }
@@ -19873,7 +19627,7 @@
19873
19627
  !elm.getAttribute("target") &&
19874
19628
  !event.defaultPrevented
19875
19629
  ) {
19876
- if ($location.$$parseLinkUrl(absHref, relHref)) {
19630
+ if ($location.parseLinkUrl(absHref, relHref)) {
19877
19631
  // We do a preventDefault for all urls that are part of the AngularTS application,
19878
19632
  // in html5mode and also without, so that we are able to abort navigation without
19879
19633
  // getting double entries in the location history.
@@ -19884,14 +19638,14 @@
19884
19638
  );
19885
19639
 
19886
19640
  // rewrite hashbang url <> html5 url
19887
- if ($location.absUrl() !== initialUrl) {
19888
- this.setUrl($location.absUrl(), true);
19641
+ if ($location.absUrl !== initialUrl) {
19642
+ this.setUrl($location.absUrl, true);
19889
19643
  }
19890
19644
 
19891
19645
  let initializing = true;
19892
19646
 
19893
19647
  // update $location when $browser url changes
19894
- this.onUrlChange((newUrl, newState) => {
19648
+ this.#onUrlChange((newUrl, newState) => {
19895
19649
  if (!startsWith(newUrl, appBaseNoFile)) {
19896
19650
  // If we are navigating outside of the app then force a reload
19897
19651
  window.location.href = newUrl;
@@ -19899,10 +19653,10 @@
19899
19653
  }
19900
19654
 
19901
19655
  Promise.resolve().then(() => {
19902
- const oldUrl = $location.absUrl();
19656
+ const oldUrl = $location.absUrl;
19903
19657
  const oldState = $location.$$state;
19904
19658
  let defaultPrevented;
19905
- $location.$$parse(newUrl);
19659
+ $location.parse(newUrl);
19906
19660
  $location.$$state = newState;
19907
19661
 
19908
19662
  defaultPrevented = $rootScope.$broadcast(
@@ -19915,10 +19669,10 @@
19915
19669
 
19916
19670
  // if the location was changed by a `$locationChangeStart` handler then stop
19917
19671
  // processing this location change
19918
- if ($location.absUrl() !== newUrl) return;
19672
+ if ($location.absUrl !== newUrl) return;
19919
19673
 
19920
19674
  if (defaultPrevented) {
19921
- $location.$$parse(oldUrl);
19675
+ $location.parse(oldUrl);
19922
19676
  $location.$$state = oldState;
19923
19677
  setBrowserUrlWithFallback(oldUrl, oldState);
19924
19678
  } else {
@@ -19930,21 +19684,21 @@
19930
19684
 
19931
19685
  // update browser
19932
19686
  const updateBrowser = () => {
19933
- if (initializing || $location.$$urlUpdatedByLocation) {
19934
- $location.$$urlUpdatedByLocation = false;
19687
+ if (initializing || urlUpdatedByLocation) {
19688
+ urlUpdatedByLocation = false;
19935
19689
 
19936
- const oldUrl = /** @type {string} */ (this.getUrl());
19937
- const newUrl = $location.absUrl();
19690
+ const oldUrl = /** @type {string} */ (this.getBrowserUrl());
19691
+ const newUrl = $location.absUrl;
19938
19692
  const oldState = this.state();
19939
19693
  const urlOrStateChanged =
19940
19694
  !urlsEqual(oldUrl, newUrl) ||
19941
- ($location.$$html5 && oldState !== $location.$$state);
19695
+ ($location.html5 && oldState !== $location.$$state);
19942
19696
 
19943
19697
  if (initializing || urlOrStateChanged) {
19944
19698
  initializing = false;
19945
19699
 
19946
19700
  setTimeout(() => {
19947
- const newUrl = $location.absUrl();
19701
+ const newUrl = $location.absUrl;
19948
19702
  const { defaultPrevented } = $rootScope.$broadcast(
19949
19703
  "$locationChangeStart",
19950
19704
  newUrl,
@@ -19955,10 +19709,10 @@
19955
19709
 
19956
19710
  // if the location was changed by a `$locationChangeStart` handler then stop
19957
19711
  // processing this location change
19958
- if ($location.absUrl() !== newUrl) return;
19712
+ if ($location.absUrl !== newUrl) return;
19959
19713
 
19960
19714
  if (defaultPrevented) {
19961
- $location.$$parse(oldUrl);
19715
+ $location.parse(oldUrl);
19962
19716
  $location.$$state = oldState;
19963
19717
  } else {
19964
19718
  if (urlOrStateChanged) {
@@ -19972,13 +19726,8 @@
19972
19726
  });
19973
19727
  }
19974
19728
  }
19975
-
19976
- $location.$$replace = false;
19977
-
19978
- // we don't need to return anything because $evalAsync will make the digest loop dirty when
19979
- // there is a change
19980
19729
  };
19981
-
19730
+ $location.$$updateBrowser = updateBrowser;
19982
19731
  updateBrowser();
19983
19732
  $rootScope.$on("$updateBrowser", updateBrowser);
19984
19733
 
@@ -19987,7 +19736,7 @@
19987
19736
  function afterLocationChange(oldUrl, oldState) {
19988
19737
  $rootScope.$broadcast(
19989
19738
  "$locationChangeSuccess",
19990
- $location.absUrl(),
19739
+ $location.absUrl,
19991
19740
  oldUrl,
19992
19741
  $location.$$state,
19993
19742
  oldState,
@@ -19999,28 +19748,63 @@
19999
19748
 
20000
19749
  /**
20001
19750
  * ///////////////////////////
20002
- * HELPERS
19751
+ * PRIVATE HELPERS
20003
19752
  * ///////////////////////////
20004
19753
  */
20005
19754
 
20006
19755
  /**
20007
- * Encode path using encodeUriSegment, ignoring forward slashes
19756
+ * @ignore
19757
+ * Encodes a URL path by encoding each path segment individually using `encodeUriSegment`,
19758
+ * while preserving forward slashes (`/`) as segment separators.
20008
19759
  *
20009
- * @param {string} path Path to encode
20010
- * @returns {string}
19760
+ * This function first decodes any existing percent-encodings (such as `%20` or `%2F`)
19761
+ * in each segment to prevent double encoding, except for encoded forward slashes (`%2F`),
19762
+ * which are replaced with literal slashes before decoding to keep path boundaries intact.
19763
+ *
19764
+ * After decoding, each segment is re-encoded with `encodeUriSegment` according to RFC 3986,
19765
+ * encoding only characters that must be encoded in a path segment.
19766
+ *
19767
+ * The encoded segments are then rejoined with `/` to form the encoded path.
19768
+ *
19769
+ * @param {string} path - The URL path string to encode. May contain multiple segments separated by `/`.
19770
+ * @returns {string} The encoded path, where each segment is encoded, but forward slashes are preserved.
19771
+ *
19772
+ * @example
19773
+ * encodePath("user profile/images/pic 1.jpg")
19774
+ * // returns "user%20profile/images/pic%201.jpg"
19775
+ *
19776
+ * @example
19777
+ * encodePath("folder1%2Fsub/folder2")
19778
+ * // returns "folder1%2Fsub/folder2"
20011
19779
  */
20012
19780
  function encodePath(path) {
20013
19781
  const segments = path.split("/");
20014
19782
  let i = segments.length;
20015
19783
 
20016
19784
  while (i--) {
20017
- // decode forward slashes to prevent them from being double encoded
20018
- segments[i] = encodeUriSegment(segments[i].replace(/%2F/g, "/"));
19785
+ // Decode any existing encodings (e.g. %20, %2F) to prevent double-encoding
19786
+ // But keep slashes intact (they were split on)
19787
+ const decodedSegment = decodeURIComponent(
19788
+ segments[i].replace(/%2F/gi, "/"),
19789
+ );
19790
+ segments[i] = encodeUriSegment(decodedSegment);
20019
19791
  }
20020
19792
 
20021
19793
  return segments.join("/");
20022
19794
  }
20023
19795
 
19796
+ /**
19797
+ * @ignore
19798
+ * Decodes each segment of a URL path.
19799
+ *
19800
+ * Splits the input path by "/", decodes each segment using decodeURIComponent,
19801
+ * and if html5Mode is enabled, re-encodes any forward slashes inside segments
19802
+ * as "%2F" to avoid confusion with path separators.
19803
+ *
19804
+ * @param {string} path - The URL path to decode.
19805
+ * @param {boolean} html5Mode - If true, encodes forward slashes in segments as "%2F".
19806
+ * @returns {string} The decoded path with segments optionally encoding slashes.
19807
+ */
20024
19808
  function decodePath(path, html5Mode) {
20025
19809
  const segments = path.split("/");
20026
19810
  let i = segments.length;
@@ -20036,6 +19820,33 @@
20036
19820
  return segments.join("/");
20037
19821
  }
20038
19822
 
19823
+ /**
19824
+ * @ignore
19825
+ * Normalizes a URL path by encoding the path segments, query parameters, and hash fragment.
19826
+ *
19827
+ * - Path segments are encoded using `encodePath`, which encodes each segment individually.
19828
+ * - Query parameters (`searchValue`) are converted to a query string using `toKeyValue`.
19829
+ * - Hash fragment (`hashValue`) is encoded using `encodeUriSegment` and prefixed with `#`.
19830
+ *
19831
+ * This function returns a fully constructed URL path with optional query and hash components.
19832
+ *
19833
+ * @param {string} pathValue - The base URL path (e.g., "folder/item name").
19834
+ * @param {Object.<string, any> | string | null} searchValue - An object or string representing query parameters.
19835
+ * - If an object, it can contain strings, numbers, booleans, or arrays of values.
19836
+ * - If a string, it is assumed to be a raw query string.
19837
+ * - If null or undefined, no query string is added.
19838
+ * @param {string | null} hashValue - The URL fragment (everything after `#`). If null or undefined, no hash is added.
19839
+ *
19840
+ * @returns {string} The normalized URL path including encoded path, optional query string, and optional hash.
19841
+ *
19842
+ * @example
19843
+ * normalizePath("products/list", { category: "books", page: 2 }, "section1")
19844
+ * // returns "products/list?category=books&page=2#section1"
19845
+ *
19846
+ * @example
19847
+ * normalizePath("user profile/images", null, null)
19848
+ * // returns "user%20profile/images"
19849
+ */
20039
19850
  function normalizePath(pathValue, searchValue, hashValue) {
20040
19851
  const search = toKeyValue(searchValue);
20041
19852
  const hash = hashValue ? `#${encodeUriSegment(hashValue)}` : "";
@@ -20044,7 +19855,15 @@
20044
19855
  return path + (search ? `?${search}` : "") + hash;
20045
19856
  }
20046
19857
 
20047
- function parseAppUrl(url, locationObj, html5Mode) {
19858
+ /**
19859
+ * @ignore
19860
+ * Parses the application URL and updates the location object with path, search, and hash.
19861
+ *
19862
+ * @param {string} url - The URL string to parse.
19863
+ * @param {boolean} html5Mode - Whether HTML5 mode is enabled (affects decoding).
19864
+ * @throws Will throw an error if the URL starts with invalid slashes.
19865
+ */
19866
+ function parseAppUrl(url, html5Mode) {
20048
19867
  if (/^\s*[\\/]{2,}/.test(url)) {
20049
19868
  throw $locationMinErr("badpath", 'Invalid url "{0}".', url);
20050
19869
  }
@@ -20058,22 +19877,20 @@
20058
19877
  prefixed && match.pathname.charAt(0) === "/"
20059
19878
  ? match.pathname.substring(1)
20060
19879
  : match.pathname;
20061
- locationObj.$$path = decodePath(path, html5Mode);
20062
- locationObj.$$search = parseKeyValue(match.search);
20063
- locationObj.$$hash = decodeURIComponent(match.hash);
19880
+ $$path = decodePath(path, html5Mode);
19881
+ $$search = parseKeyValue(match.search);
19882
+ $$hash = decodeURIComponent(match.hash);
20064
19883
 
20065
19884
  // make sure path starts with '/';
20066
- if (locationObj.$$path && locationObj.$$path.charAt(0) !== "/") {
20067
- locationObj.$$path = `/${locationObj.$$path}`;
19885
+ if ($$path && $$path.charAt(0) !== "/") {
19886
+ $$path = `/${$$path}`;
20068
19887
  }
20069
19888
  }
20070
19889
 
20071
- function startsWith(str, search) {
20072
- return str.slice(0, search.length) === search;
20073
- }
20074
-
20075
19890
  /**
20076
- *
19891
+ * @ignore
19892
+ * Returns the substring of `url` after the `base` string if `url` starts with `base`.
19893
+ * Returns `undefined` if `url` does not start with `base`.
20077
19894
  * @param {string} base
20078
19895
  * @param {string} url
20079
19896
  * @returns {string} returns text from `url` after `base` or `undefined` if it does not begin with
@@ -20085,25 +19902,96 @@
20085
19902
  }
20086
19903
  }
20087
19904
 
19905
+ /**
19906
+ * @ignore
19907
+ * Removes the hash fragment (including the '#') from the given URL string.
19908
+ *
19909
+ * @param {string} url - The URL string to process.
19910
+ * @returns {string} The URL without the hash fragment.
19911
+ */
20088
19912
  function stripHash(url) {
20089
19913
  const index = url.indexOf("#");
20090
19914
  return index === -1 ? url : url.substring(0, index);
20091
19915
  }
20092
19916
 
19917
+ /**
19918
+ * @ignore
19919
+ * Removes the file name (and any hash) from a URL, returning the base directory path.
19920
+ *
19921
+ * For example:
19922
+ * - Input: "https://example.com/path/to/file.js"
19923
+ * Output: "https://example.com/path/to/"
19924
+ *
19925
+ * - Input: "https://example.com/path/to/file.js#section"
19926
+ * Output: "https://example.com/path/to/"
19927
+ *
19928
+ * @param {string} url - The URL from which to strip the file name and hash.
19929
+ * @returns {string} The base path of the URL, ending with a slash.
19930
+ */
20093
19931
  function stripFile(url) {
20094
19932
  return url.substring(0, stripHash(url).lastIndexOf("/") + 1);
20095
19933
  }
20096
19934
 
20097
- /* return the server only (scheme://host:port) */
19935
+ /**
19936
+ * @ignore
19937
+ * Extracts the base server URL (scheme, host, and optional port) from a full URL.
19938
+ *
19939
+ * If no path is present, returns the full URL.
19940
+ *
19941
+ * For example:
19942
+ * - Input: "https://example.com/path/to/file"
19943
+ * Output: "https://example.com"
19944
+ *
19945
+ * - Input: "http://localhost:3000/api/data"
19946
+ * Output: "http://localhost:3000"
19947
+ *
19948
+ * @param {string} url - The full URL to extract the server base from.
19949
+ * @returns {string} The server base, including scheme and host (and port if present).
19950
+ */
20098
19951
  function serverBase(url) {
20099
- return url.substring(0, url.indexOf("/", url.indexOf("//") + 2));
19952
+ const start = url.indexOf("//") + 2;
19953
+ const slashIndex = url.indexOf("/", start);
19954
+ return slashIndex === -1 ? url : url.substring(0, slashIndex);
20100
19955
  }
20101
19956
 
20102
- // Determine if two URLs are equal despite potentially having different encoding/normalizing
20103
- // such as $location.absUrl() vs $browser.url()
20104
- // See https://github.com/angular/angular.js/issues/16592
19957
+ /**
19958
+ * @ignore
19959
+ * Determine if two URLs are equal despite potential differences in encoding,
19960
+ * trailing slashes, or empty hash fragments, such as between $location.absUrl() and $browser.url().
19961
+ *
19962
+ * @param {string} a - First URL to compare.
19963
+ * @param {string} b - Second URL to compare.
19964
+ * @returns {boolean} True if URLs are equivalent after normalization.
19965
+ */
20105
19966
  function urlsEqual(a, b) {
20106
- return a === b || urlResolve(a).href === urlResolve(b).href;
19967
+ return normalizeUrl(a) === normalizeUrl(b);
19968
+ }
19969
+
19970
+ /**
19971
+ * @ignore
19972
+ * Normalize a URL by resolving it via a DOM anchor element,
19973
+ * removing trailing slashes (except root), and trimming empty hashes.
19974
+ *
19975
+ * @param {string} url - URL to normalize.
19976
+ * @returns {string} Normalized URL string.
19977
+ */
19978
+ function normalizeUrl(url) {
19979
+ const anchor = document.createElement("a");
19980
+ anchor.href = url;
19981
+
19982
+ let normalized = anchor.href;
19983
+
19984
+ // Remove trailing slash unless it's root (e.g., https://example.com/)
19985
+ if (normalized.endsWith("/") && !/^https?:\/\/[^/]+\/$/.test(normalized)) {
19986
+ normalized = normalized.slice(0, -1);
19987
+ }
19988
+
19989
+ // Remove empty hash (e.g., https://example.com/foo# -> https://example.com/foo)
19990
+ if (normalized.endsWith("#")) {
19991
+ normalized = normalized.slice(0, -1);
19992
+ }
19993
+
19994
+ return normalized;
20107
19995
  }
20108
19996
 
20109
19997
  /**
@@ -20257,7 +20145,7 @@
20257
20145
  Array.isArray(target.$nonscope) &&
20258
20146
  target.$nonscope.includes(key))
20259
20147
  ) {
20260
- continue;
20148
+ /* empty */
20261
20149
  } else {
20262
20150
  target[key] = createScope(target[key], proxy.$handler);
20263
20151
  }
@@ -20736,6 +20624,7 @@
20736
20624
 
20737
20625
  /**
20738
20626
  * @param {Listener[]} listeners
20627
+ * @param {Function} filter
20739
20628
  */
20740
20629
  #scheduleListener(listeners, filter = (val) => val) {
20741
20630
  Promise.resolve().then(() => {
@@ -21386,8 +21275,7 @@
21386
21275
  function calculateWatcherCount(model) {
21387
21276
  const childIds = collectChildIds(model).add(model.$id);
21388
21277
 
21389
- /** @type {number} */
21390
- const count = Array.from(model.watchers.values()).reduce(
21278
+ return Array.from(model.watchers.values()).reduce(
21391
21279
  (count, watcherArray) =>
21392
21280
  count +
21393
21281
  watcherArray.reduce(
@@ -21397,7 +21285,6 @@
21397
21285
  ),
21398
21286
  0,
21399
21287
  );
21400
- return count;
21401
21288
  }
21402
21289
 
21403
21290
  /**
@@ -23088,8 +22975,7 @@
23088
22975
 
23089
22976
  temporaryStyles.forEach((entry) => {
23090
22977
  const key = entry[0];
23091
- const value = entry[1];
23092
- node.style[key] = value;
22978
+ node.style[key] = entry[1];
23093
22979
  });
23094
22980
 
23095
22981
  applyAnimationClasses(element, options);
@@ -25815,11 +25701,6 @@
25815
25701
  if (idx >= 0) array.splice(idx, 1);
25816
25702
  return array;
25817
25703
  }
25818
- /** pushes a values to an array and returns the value */
25819
- const pushTo = curry((arr, val) => {
25820
- arr.push(val);
25821
- return val;
25822
- });
25823
25704
 
25824
25705
  /**
25825
25706
  * Applies a set of defaults to an options object. The options object is filtered
@@ -26604,12 +26485,14 @@
26604
26485
 
26605
26486
  /** @type {Array<(item: T) => void>} */
26606
26487
  this._evictListeners = [];
26488
+ }
26607
26489
 
26608
- /**
26609
- * Register a listener that will be called with the evicted item.
26610
- * @type {(listener: (item: T) => void) => void}
26611
- */
26612
- this.onEvict = pushTo(this._evictListeners);
26490
+ /**
26491
+ * Register a listener that will be called with the evicted item.
26492
+ * @param {(item: T) => void} listener
26493
+ */
26494
+ onEvict(listener) {
26495
+ this._evictListeners.push(listener);
26613
26496
  }
26614
26497
 
26615
26498
  /**
@@ -27804,8 +27687,13 @@
27804
27687
  // The param keys specified by the incoming toParams
27805
27688
  return toPath.map(makeInheritedParamsNode);
27806
27689
  }
27690
+
27807
27691
  /**
27808
27692
  * Computes the tree changes (entering, exiting) between a fromPath and toPath.
27693
+ * @param {PathNode[]} fromPath
27694
+ * @param {PathNode[]} toPath
27695
+ * @param {boolean} [reloadState]
27696
+ * @returns {import("../transition/interface.js").TreeChanges}
27809
27697
  */
27810
27698
  static treeChanges(fromPath, toPath, reloadState) {
27811
27699
  const max = Math.min(fromPath.length, toPath.length);
@@ -28171,7 +28059,7 @@
28171
28059
  name = name || "$default";
28172
28060
  // Account for views: { header: "headerComponent" }
28173
28061
  if (isString(config)) config = { component: config };
28174
- // Make a shallow copy of the config object
28062
+ // Make a shallow copy of the urlConfig object
28175
28063
  config = Object.assign({}, config);
28176
28064
  // Do not allow a view to mix props for component-style view with props for template/controller-style view
28177
28065
  if (hasAnyKey(compKeys, config) && hasAnyKey(nonCompKeys, config)) {
@@ -28325,8 +28213,7 @@
28325
28213
  this._listeners = [];
28326
28214
  this._pluginapi = {
28327
28215
  _registeredUIView: (id) => {
28328
- const res = find(this._ngViews, (view) => view.id === id);
28329
- return res;
28216
+ return find(this._ngViews, (view) => view.id === id);
28330
28217
  },
28331
28218
  _registeredUIViews: () => this._ngViews,
28332
28219
  _activeViewConfigs: () => this._viewConfigs,
@@ -28364,8 +28251,7 @@
28364
28251
  throw new Error(
28365
28252
  "ViewService: No view config factory registered for type " + decl.$type,
28366
28253
  );
28367
- const cfgs = cfgFactory(path, decl);
28368
- return cfgs;
28254
+ return cfgFactory(path, decl);
28369
28255
  }
28370
28256
  /**
28371
28257
  * Deactivates a ViewConfig.
@@ -29672,9 +29558,9 @@
29672
29558
  *
29673
29559
  * If the target state is not valid, an error is thrown.
29674
29560
  *
29675
- * @param fromPath The path of [[PathNode]]s from which the transition is leaving. The last node in the `fromPath`
29561
+ * @param {Array<import('../path/path-node.js').PathNode>} fromPath The path of [[PathNode]]s from which the transition is leaving. The last node in the `fromPath`
29676
29562
  * encapsulates the "from state".
29677
- * @param targetState The target state and parameters being transitioned to (also, the transition options)
29563
+ * @param {import('../state/target-state.js').TargetState} targetState The target state and parameters being transitioned to (also, the transition options)
29678
29564
  * @param {import('../transition/transition-service.js').TransitionProvider} transitionService The [[TransitionService]] instance
29679
29565
  * @param {import('../globals.js').RouterGlobals} globals
29680
29566
  */
@@ -30218,8 +30104,8 @@
30218
30104
  ).length
30219
30105
  );
30220
30106
  };
30221
- const newTC = this.treeChanges();
30222
- const pendTC = pending && pending.treeChanges();
30107
+ const newTC = this._treeChanges;
30108
+ const pendTC = pending && pending._treeChanges;
30223
30109
  if (
30224
30110
  pendTC &&
30225
30111
  same(pendTC.to, newTC.to) &&
@@ -30860,7 +30746,7 @@
30860
30746
  * This API is located at `router.transitionService` ([[UIRouter.transitionService]])
30861
30747
  */
30862
30748
  class TransitionProvider {
30863
- static $inject = ["$routerGlobalsProvider", "$viewProvider"];
30749
+ /* @ignore */ static $inject = provider([$injectTokens.$routerGlobals, $injectTokens.$view]);
30864
30750
 
30865
30751
  /**
30866
30752
  * @param {import('../globals.js').RouterGlobals} globals
@@ -30891,10 +30777,10 @@
30891
30777
  }
30892
30778
 
30893
30779
  $get = [
30894
- "$state",
30895
- "$urlService",
30896
- "$stateRegistry",
30897
- "$view",
30780
+ $injectTokens.$state,
30781
+ $injectTokens.$url,
30782
+ $injectTokens.$stateRegistry,
30783
+ $injectTokens.$view,
30898
30784
  (stateService, urlService, stateRegistry, viewService) => {
30899
30785
  // Lazy load state trees
30900
30786
  this._deregisterHookFns.lazyLoad = registerLazyLoadHook(
@@ -31132,7 +31018,10 @@
31132
31018
  return this.globals.$current;
31133
31019
  }
31134
31020
 
31135
- static $inject = ["$routerGlobalsProvider", "$transitionsProvider"];
31021
+ /* @ignore */ static $inject = [
31022
+ "$routerGlobalsProvider",
31023
+ "$transitionsProvider",
31024
+ ];
31136
31025
 
31137
31026
  // Needs access to urlService, stateRegistry
31138
31027
  /**
@@ -31211,9 +31100,9 @@
31211
31100
  * - **params** `{object}` - returns an array of state params that are ensured to
31212
31101
  * be a super-set of parent's params.
31213
31102
  * - **views** `{object}` - returns a views object where each key is an absolute view
31214
- * name (i.e. "viewName@stateName") and each value is the config object
31103
+ * name (i.e. "viewName@stateName") and each value is the urlConfig object
31215
31104
  * (template, controller) for the view. Even when you don't use the views object
31216
- * explicitly on a state config, one is still created for you internally.
31105
+ * explicitly on a state urlConfig, one is still created for you internally.
31217
31106
  * So by decorating this builder function you have access to decorating template
31218
31107
  * and controller properties.
31219
31108
  * - **ownParams** `{object}` - returns an array of params that belong to the state,
@@ -31231,10 +31120,10 @@
31231
31120
  * let result = {},
31232
31121
  * views = parent(state);
31233
31122
  *
31234
- * angular.forEach(views, function (config, name) {
31123
+ * angular.forEach(views, function (urlConfig, name) {
31235
31124
  * let autoName = (state.name + '.' + name).replace('.', '/');
31236
- * config.templateUrl = config.templateUrl || '/partials/' + autoName + '.html';
31237
- * result[name] = config;
31125
+ * urlConfig.templateUrl = urlConfig.templateUrl || '/partials/' + autoName + '.html';
31126
+ * result[name] = urlConfig;
31238
31127
  * });
31239
31128
  * return result;
31240
31129
  * });
@@ -31258,7 +31147,7 @@
31258
31147
  * @param {object} func A function that is responsible for decorating the original
31259
31148
  * builder function. The function receives two parameters:
31260
31149
  *
31261
- * - `{object}` - state - The state config object.
31150
+ * - `{object}` - state - The state urlConfig object.
31262
31151
  * - `{object}` - super - The original builder function.
31263
31152
  *
31264
31153
  * @return {object} $stateProvider - $stateProvider instance
@@ -31491,7 +31380,7 @@
31491
31380
  const globals = this.globals;
31492
31381
  const latestSuccess = globals.successfulTransitions.peekTail();
31493
31382
  const rootPath = () => [new PathNode(this.stateRegistry.root())];
31494
- return latestSuccess ? latestSuccess.treeChanges().to : rootPath();
31383
+ return latestSuccess ? latestSuccess._treeChanges.to : rootPath();
31495
31384
  }
31496
31385
  /**
31497
31386
  * Low-level method for transitioning to a new state.
@@ -31826,10 +31715,10 @@
31826
31715
  }
31827
31716
 
31828
31717
  $get = [
31829
- "$http",
31830
- "$templateCache",
31831
- "$templateRequest",
31832
- "$injector",
31718
+ $injectTokens.$http,
31719
+ $injectTokens.$templateCache,
31720
+ $injectTokens.$templateRequest,
31721
+ $injectTokens.$injector,
31833
31722
  /**
31834
31723
  * @param {import("interface.ts").HttpService} $http
31835
31724
  * @param {import("../services/template-cache/interface.ts").TemplateCache} $templateCache
@@ -32372,9 +32261,9 @@
32372
32261
  * // returns { id: 'bob', q: 'hello', r: null }
32373
32262
  * ```
32374
32263
  *
32375
- * @param path The URL path to match, e.g. `$location.path()`.
32376
- * @param search URL search parameters, e.g. `$location.search()`.
32377
- * @param hash URL hash e.g. `$location.hash()`.
32264
+ * @param path The URL path to match, e.g. `$location.getPath()`.
32265
+ * @param search URL search parameters, e.g. `$location.getSearch()`.
32266
+ * @param hash URL hash e.g. `$location.getHash()`.
32378
32267
  *
32379
32268
  * @returns The captured parameter values.
32380
32269
  */
@@ -32888,6 +32777,7 @@
32888
32777
  this.$id = -1;
32889
32778
  this._group = undefined;
32890
32779
  this.handler = handler || ((x) => x);
32780
+ this.priority = undefined;
32891
32781
  }
32892
32782
 
32893
32783
  /**
@@ -32901,7 +32791,9 @@
32901
32791
  }
32902
32792
  }
32903
32793
 
32904
- const prioritySort = (a, b) => (b.priority || 0) - (a.priority || 0);
32794
+ function prioritySort(a, b) {
32795
+ return (b.priority || 0) - (a.priority || 0);
32796
+ }
32905
32797
 
32906
32798
  const typeSort = (a, b) => {
32907
32799
  const weights = { STATE: 4, URLMATCHER: 4, REGEXP: 3, RAW: 2, OTHER: 1 };
@@ -32932,8 +32824,7 @@
32932
32824
  * - Equally sorted State and UrlMatcher rules will each match the URL.
32933
32825
  * Then, the *best* match is chosen based on how many parameter values were matched.
32934
32826
  */
32935
- let defaultRuleSortFn;
32936
- defaultRuleSortFn = (a, b) => {
32827
+ function defaultRuleSortFn(a, b) {
32937
32828
  let cmp = prioritySort(a, b);
32938
32829
  if (cmp !== 0) return cmp;
32939
32830
  cmp = typeSort(a, b);
@@ -32941,7 +32832,8 @@
32941
32832
  cmp = urlMatcherSort(a, b);
32942
32833
  if (cmp !== 0) return cmp;
32943
32834
  return idSort(a, b);
32944
- };
32835
+ }
32836
+
32945
32837
  function getHandlerFn(handler) {
32946
32838
  if (
32947
32839
  !isFunction(handler) &&
@@ -32963,9 +32855,10 @@
32963
32855
  *
32964
32856
  * The most commonly used methods are [[otherwise]] and [[when]].
32965
32857
  *
32966
- * This API is found at `$urlService.rules` (see: [[UIRouter.urlService]], [[URLService.rules]])
32858
+ * This API is found at `$url.rules` (see: [[UIRouter.urlService]], [[URLService.rules]])
32967
32859
  */
32968
32860
  class UrlRules {
32861
+ /** @param {UrlRuleFactory} urlRuleFactory */
32969
32862
  constructor(urlRuleFactory) {
32970
32863
  this._sortFn = defaultRuleSortFn;
32971
32864
  this._rules = [];
@@ -33268,39 +33161,37 @@
33268
33161
  * API for URL management
33269
33162
  */
33270
33163
  class UrlService {
33271
- static $inject = [
33272
- "$locationProvider",
33273
- "$stateProvider",
33274
- "$routerGlobalsProvider",
33275
- "$urlConfigProvider",
33276
- ];
33164
+ static $inject = provider([
33165
+ $injectTokens.$location,
33166
+ $injectTokens.$state,
33167
+ $injectTokens.$routerGlobals,
33168
+ $injectTokens.$urlConfig,
33169
+ ]);
33170
+
33171
+ /** @type {import("../../services/location/location").Location} */
33172
+ $location;
33277
33173
 
33278
33174
  /**
33279
33175
  * @param {import("../../services/location/location").LocationProvider} $locationProvider
33280
33176
  * @param {import("../../router/state/state-service.js").StateProvider} stateService
33281
- * @param globals
33177
+ * @param {import("../../router/globals.js").RouterGlobals} globals
33282
33178
  * @param {import("../../router/url/url-config.js").UrlConfigProvider} urlConfigProvider
33283
33179
  */
33284
33180
  constructor($locationProvider, stateService, globals, urlConfigProvider) {
33181
+ this.$locationProvider = $locationProvider;
33285
33182
  this.stateService = stateService;
33286
33183
  this.stateService.urlService = this; // circular wiring
33287
- this.$locationProvider = $locationProvider;
33288
- this.$location = undefined;
33289
33184
 
33290
33185
  /** Provides services related to the URL */
33291
33186
  this.urlRuleFactory = new UrlRuleFactory(this, this.stateService, globals);
33292
33187
 
33293
33188
  /**
33294
33189
  * The nested [[UrlRules]] API for managing URL rules and rewrites
33295
- *
33296
- * See: [[UrlRules]] for details
33297
33190
  * @type {UrlRules}
33298
33191
  */
33299
33192
  this.rules = new UrlRules(this.urlRuleFactory);
33300
33193
  /**
33301
33194
  * The nested [[UrlConfig]] API to configure the URL and retrieve URL information
33302
- *
33303
- * See: [[UrlConfig]] for details
33304
33195
  * @type {import("./url-config.js").UrlConfigProvider}
33305
33196
  */
33306
33197
  this.config = urlConfigProvider;
@@ -33308,37 +33199,44 @@
33308
33199
  /** Creates a new [[Param]] for a given location (DefType) */
33309
33200
  this.paramFactory = new ParamFactory(this.config);
33310
33201
 
33311
- /**
33312
- * Gets the path part of the current url
33313
- *
33314
- * If the current URL is `/some/path?query=value#anchor`, this returns `/some/path`
33315
- *
33316
- * @return the path portion of the url
33317
- */
33318
- this.path = () => this.$location.path();
33319
- /**
33320
- * Gets the search part of the current url as an object
33321
- *
33322
- * If the current URL is `/some/path?query=value#anchor`, this returns `{ query: 'value' }`
33323
- *
33324
- * @return the search (query) portion of the url, as an object
33325
- */
33326
- this.search = () => this.$location.search();
33327
- /**
33328
- * Gets the hash part of the current url
33329
- *
33330
- * If the current URL is `/some/path?query=value#anchor`, this returns `anchor`
33331
- *
33332
- * @return the hash (anchor) portion of the url
33333
- */
33334
- this.hash = () => this.$location.hash();
33335
-
33336
33202
  this._urlListeners = [];
33337
33203
  }
33338
33204
 
33205
+ /**
33206
+ * Gets the path part of the current url
33207
+ *
33208
+ * If the current URL is `/some/path?query=value#anchor`, this returns `/some/path`
33209
+ *
33210
+ * @return {string} the path portion of the url
33211
+ */
33212
+ getPath() {
33213
+ return this.$location.getPath();
33214
+ }
33215
+
33216
+ /**
33217
+ * Gets the search part of the current url as an object
33218
+ *
33219
+ * If the current URL is `/some/path?query=value#anchor`, this returns `{ query: 'value' }`
33220
+ *
33221
+ * @return {Object} the search (query) portion of the url, as an object
33222
+ */
33223
+ getSearch() {
33224
+ return this.$location.getSearch();
33225
+ }
33226
+ /**
33227
+ * Gets the hash part of the current url
33228
+ *
33229
+ * If the current URL is `/some/path?query=value#anchor`, this returns `anchor`
33230
+ *
33231
+ * @return {string} the hash (anchor) portion of the url
33232
+ */
33233
+ getHash() {
33234
+ return this.$location.getHash();
33235
+ }
33236
+
33339
33237
  $get = [
33340
- "$location",
33341
- "$rootScope",
33238
+ $injectTokens.$location,
33239
+ $injectTokens.$rootScope,
33342
33240
  /**
33343
33241
  *
33344
33242
  * @param {import('../../services/location/location.js').Location} $location
@@ -33352,21 +33250,14 @@
33352
33250
  fn(evt);
33353
33251
  });
33354
33252
  });
33355
- this.listen();
33253
+ this.listen(true);
33356
33254
  return this;
33357
33255
  },
33358
33256
  ];
33359
33257
 
33360
33258
  /**
33361
- * @returns {boolean}
33259
+ * @returns {string}
33362
33260
  */
33363
- html5Mode() {
33364
- return (
33365
- this.$locationProvider.getHtml5Mode().enabled &&
33366
- typeof history !== "undefined"
33367
- );
33368
- }
33369
-
33370
33261
  baseHref() {
33371
33262
  return (
33372
33263
  this._baseHref ||
@@ -33421,20 +33312,18 @@
33421
33312
  * @param {string} [newUrl] The new value for the URL.
33422
33313
  * This url should reflect only the new internal [[path]], [[search]], and [[hash]] values.
33423
33314
  * It should not include the protocol, site, port, or base path of an absolute HREF.
33424
- * @param {boolean} [replace] When true, replaces the current history entry (instead of appending it) with this new url
33425
33315
  * @param {any} [state] The history's state object, i.e., pushState (if the LocationServices implementation supports it)
33426
33316
  *
33427
33317
  * @return the url (after potentially being processed)
33428
33318
  */
33429
- url(newUrl, replace = false, state) {
33430
- if (isDefined(newUrl)) this.$location.url(newUrl);
33431
- if (replace) this.$location.replace();
33432
- if (state) this.$location.state(state);
33433
- return this.$location.url();
33319
+ url(newUrl, state) {
33320
+ if (isDefined(newUrl)) this.$location.setUrl(newUrl);
33321
+ if (state) this.$location.setState(state);
33322
+ return this.$location.getUrl();
33434
33323
  }
33435
33324
 
33436
33325
  /**
33437
- * @internal
33326
+ * @private
33438
33327
  *
33439
33328
  * Registers a low level url change handler
33440
33329
  *
@@ -33445,8 +33334,8 @@
33445
33334
  * let deregisterFn = locationServices.onChange((evt) => console.log("url change", evt));
33446
33335
  * ```
33447
33336
  *
33448
- * @param callback a function that will be called when the url is changing
33449
- * @return a function that de-registers the callback
33337
+ * @param {Function} callback a function that will be called when the url is changing
33338
+ * @return {Function} a function that de-registers the callback
33450
33339
  */
33451
33340
  onChange(callback) {
33452
33341
  this._urlListeners.push(callback);
@@ -33454,13 +33343,21 @@
33454
33343
  }
33455
33344
 
33456
33345
  /**
33457
- * Gets the current URL parts
33346
+ * Gets the current URL parts.
33347
+ *
33348
+ * Returns an object with the `path`, `search`, and `hash` components
33349
+ * of the current browser location.
33458
33350
  *
33459
- * This method returns the different parts of the current URL (the [[path]], [[search]], and [[hash]]) as a [[UrlParts]] object.
33351
+ * @returns {import("../../services/location/interface.ts").UrlParts} The current URL's path, search, and hash.
33460
33352
  */
33461
33353
  parts() {
33462
- return { path: this.path(), search: this.search(), hash: this.hash() };
33354
+ return {
33355
+ path: this.$location.getPath(),
33356
+ search: this.$location.getSearch(),
33357
+ hash: this.$location.getHash(),
33358
+ };
33463
33359
  }
33360
+
33464
33361
  /**
33465
33362
  * Activates the best rule for the current URL
33466
33363
  *
@@ -33484,16 +33381,16 @@
33484
33381
  if (evt && evt.defaultPrevented) return;
33485
33382
  const stateService = this.stateService;
33486
33383
  const url = {
33487
- path: this.path(),
33488
- search: this.search(),
33489
- hash: this.hash(),
33384
+ path: this.$location.getPath(),
33385
+ search: this.$location.getSearch(),
33386
+ hash: this.$location.getHash(),
33490
33387
  };
33491
33388
  /**
33492
33389
  * @type {*}
33493
33390
  */
33494
33391
  const best = this.match(url);
33495
33392
  const applyResult = pattern([
33496
- [isString, (newurl) => this.url(newurl, true)],
33393
+ [isString, (newurl) => this.url(newurl)],
33497
33394
  [
33498
33395
  TargetState.isDef,
33499
33396
  (def) => stateService.go(def.state, def.params, def.options),
@@ -33526,7 +33423,7 @@
33526
33423
  * });
33527
33424
  * ```
33528
33425
  *
33529
- * @param enabled `true` or `false` to start or stop listening to URL changes
33426
+ * @param {boolean} enabled `true` or `false` to start or stop listening to URL changes
33530
33427
  */
33531
33428
  listen(enabled) {
33532
33429
  if (enabled === false) {
@@ -33604,7 +33501,7 @@
33604
33501
  * ```js
33605
33502
  * matcher = $umf.compile("/about/:person");
33606
33503
  * params = { person: "bob" };
33607
- * $bob = $urlService.href(matcher, params);
33504
+ * $bob = $url.href(matcher, params);
33608
33505
  * // $bob == "/about/bob";
33609
33506
  * ```
33610
33507
  *
@@ -33620,22 +33517,18 @@
33620
33517
  let url = urlMatcher.format(params);
33621
33518
  if (url == null) return null;
33622
33519
  options = options || { absolute: false };
33623
- const isHtml5 = this.html5Mode();
33624
- if (!isHtml5 && url !== null) {
33625
- url = "#" + this.$locationProvider.getHashPrefix() + url;
33520
+ const isHtml5 = this.$locationProvider.html5ModeConf.enabled;
33521
+ if (!isHtml5) {
33522
+ url = "#" + this.$locationProvider.hashPrefixConf + url;
33626
33523
  }
33627
33524
  url = appendBasePath(url, isHtml5, options.absolute, this.baseHref());
33628
33525
  if (!options.absolute || !url) {
33629
33526
  return url;
33630
33527
  }
33631
33528
  const slash = !isHtml5 && url ? "/" : "";
33632
- const cfgPort = this.$location.port();
33633
- const port = cfgPort === 80 || cfgPort === 443 ? "" : ":" + cfgPort;
33634
33529
  return [
33635
- this.$location.protocol(),
33636
- "://",
33637
- this.$location.host(),
33638
- port,
33530
+ `${window.location.protocol}//`,
33531
+ window.location.host,
33639
33532
  slash,
33640
33533
  url,
33641
33534
  ].join("");
@@ -33773,7 +33666,7 @@
33773
33666
  return state.data;
33774
33667
  }
33775
33668
 
33776
- function getUrlBuilder($urlService, root) {
33669
+ function getUrlBuilder($url, root) {
33777
33670
  return function (stateObject) {
33778
33671
  let stateDec = stateObject.self;
33779
33672
  // For future states, i.e., states whose name ends with `.**`,
@@ -33793,9 +33686,9 @@
33793
33686
  const parsed = parseUrl(stateDec.url);
33794
33687
  const url = !parsed
33795
33688
  ? stateDec.url
33796
- : $urlService.compile(parsed.val, { state: stateDec });
33689
+ : $url.compile(parsed.val, { state: stateDec });
33797
33690
  if (!url) return null;
33798
- if (!$urlService.isMatcher(url))
33691
+ if (!$url.isMatcher(url))
33799
33692
  throw new Error(`Invalid url '${url}' in state '${stateObject}'`);
33800
33693
  return parsed && parsed.root
33801
33694
  ? url
@@ -34219,8 +34112,8 @@
34219
34112
  *
34220
34113
  */
34221
34114
  class StateRegistryProvider {
34222
- static $inject = provider([
34223
- $injectTokens.$urlService,
34115
+ /* @ignore */ static $inject = provider([
34116
+ $injectTokens.$url,
34224
34117
  $injectTokens.$state,
34225
34118
  $injectTokens.$routerGlobals,
34226
34119
  $injectTokens.$view,
@@ -35120,7 +35013,7 @@
35120
35013
  * @param {string} viewName Name of the view.
35121
35014
  */
35122
35015
  newScope.$emit("$viewContentLoading", name);
35123
- const cloned = $transclude(newScope, function (clone) {
35016
+ currentEl = $transclude(newScope, function (clone) {
35124
35017
  setCacheData(clone, "$ngViewAnim", $ngViewAnim);
35125
35018
  setCacheData(clone, "$ngView", $ngViewData);
35126
35019
  renderer.enter(clone, $element, function () {
@@ -35136,7 +35029,6 @@
35136
35029
  });
35137
35030
  cleanupLastView();
35138
35031
  });
35139
- currentEl = cloned;
35140
35032
  currentScope = newScope;
35141
35033
  /**
35142
35034
  * Fired once the view is **loaded**, *after* the DOM is rendered.
@@ -35619,7 +35511,6 @@
35619
35511
 
35620
35512
  return {
35621
35513
  restrict: "A",
35622
- terminal: true,
35623
35514
  link(scope, element, attrs) {
35624
35515
  const eventName =
35625
35516
  attrs["trigger"] ||
@@ -35731,8 +35622,17 @@
35731
35622
  }
35732
35623
 
35733
35624
  if (method === "post" || method === "put") {
35734
- const data = collectFormData(element);
35735
- $http[method](url, data).then(handler).catch(handler);
35625
+ let data;
35626
+ const config = {};
35627
+ if (attrs["enctype"]) {
35628
+ config.headers = {
35629
+ "Content-Type": attrs["enctype"],
35630
+ };
35631
+ data = toKeyValue(collectFormData(element));
35632
+ } else {
35633
+ data = collectFormData(element);
35634
+ }
35635
+ $http[method](url, data, config).then(handler).catch(handler);
35736
35636
  } else {
35737
35637
  $http[method](url).then(handler).catch(handler);
35738
35638
  }
@@ -35746,7 +35646,7 @@
35746
35646
 
35747
35647
  /**
35748
35648
  * Initializes core `ng` module.
35749
- * @param {import('./loader.js').Angular} angular
35649
+ * @param {import('./angular.js').Angular} angular
35750
35650
  * @returns {import('./core/di/ng-module.js').NgModule} `ng` module
35751
35651
  */
35752
35652
  function registerNgModule(angular) {
@@ -35755,7 +35655,7 @@
35755
35655
  "ng",
35756
35656
  [],
35757
35657
  [
35758
- "$provide",
35658
+ $injectTokens.$provide,
35759
35659
  /** @param {import("./interface.js").Provider} $provide */
35760
35660
  ($provide) => {
35761
35661
  // $$sanitizeUriProvider needs to be before $compileProvider as it is used by it.
@@ -35763,7 +35663,7 @@
35763
35663
  $$sanitizeUri: SanitizeUriProvider,
35764
35664
  });
35765
35665
  $provide
35766
- .provider("$compile", CompileProvider)
35666
+ .provider($injectTokens.$compile, CompileProvider)
35767
35667
  .directive({
35768
35668
  input: inputDirective,
35769
35669
  textarea: inputDirective,
@@ -35880,7 +35780,7 @@
35880
35780
  $state: StateProvider,
35881
35781
  $ngViewScroll: ViewScrollProvider,
35882
35782
  $templateFactory: TemplateFactoryProvider,
35883
- $urlService: UrlService,
35783
+ $url: UrlService,
35884
35784
  $stateRegistry: StateRegistryProvider,
35885
35785
  $eventBus: PubSubProvider,
35886
35786
  });
@@ -35888,14 +35788,12 @@
35888
35788
  ],
35889
35789
  )
35890
35790
  .factory("$stateParams", [
35891
- "$routerGlobals",
35791
+ $injectTokens.$routerGlobals,
35892
35792
  /**
35893
35793
  * @param {import('./router/globals.js').RouterGlobals} globals
35894
35794
  * @returns {import('./router/params/state-params.js').StateParams }
35895
35795
  */
35896
- function (globals) {
35897
- return globals.params;
35898
- },
35796
+ (globals) => globals.params,
35899
35797
  ])
35900
35798
  .value("$trace", trace);
35901
35799
  }
@@ -35923,7 +35821,7 @@
35923
35821
  /**
35924
35822
  * @type {string} `version` from `package.json`
35925
35823
  */
35926
- this.version = "0.7.8"; //inserted via rollup plugin
35824
+ this.version = "0.8.0"; //inserted via rollup plugin
35927
35825
 
35928
35826
  /** @type {!Array<string|any>} */
35929
35827
  this.bootsrappedModules = [];