@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:20 */
1
+ /* Version: 0.8.0 - August 2, 2025 17:22:31 */
2
2
  const VALID_CLASS = "ng-valid";
3
3
  const INVALID_CLASS = "ng-invalid";
4
4
  const PRISTINE_CLASS = "ng-pristine";
@@ -349,14 +349,6 @@ function extend(dst, ...src) {
349
349
  return baseExtend(dst, src);
350
350
  }
351
351
 
352
- /**
353
- * @param {string} str
354
- * @returns {number}
355
- */
356
- function toInt(str) {
357
- return parseInt(str, 10);
358
- }
359
-
360
352
  /**
361
353
  * @param {any} num
362
354
  * @returns {boolean}
@@ -789,7 +781,7 @@ function tryDecodeURIComponent(value) {
789
781
  try {
790
782
  return decodeURIComponent(value);
791
783
  } catch {
792
- return;
784
+ /* empty */
793
785
  }
794
786
  }
795
787
 
@@ -803,6 +795,7 @@ function tryDecodeURIComponent(value) {
803
795
  * unreserved = ALPHA / DIGIT / "-" / "." / "_" / "~"
804
796
  * sub-delims = "!" / "$" / "&" / "'" / "(" / ")"
805
797
  * / "*" / "+" / "," / ";" / "="
798
+ * @param {string} val
806
799
  */
807
800
  function encodeUriSegment(val) {
808
801
  return encodeUriQuery(val, true)
@@ -1176,6 +1169,36 @@ function wait(t = 0) {
1176
1169
  return new Promise((resolve) => setTimeout(resolve, t));
1177
1170
  }
1178
1171
 
1172
+ /**
1173
+ * Checks if a given string starts with a specified substring.
1174
+ *
1175
+ * This is a simple polyfill-like function that mimics the behavior of
1176
+ * `String.prototype.startsWith` without using the built-in method.
1177
+ *
1178
+ * @param {string} str - The full string to evaluate.
1179
+ * @param {string} search - The substring to test against the beginning of `str`.
1180
+ * @returns {boolean} `true` if `str` starts with `search`, otherwise `false`.
1181
+ *
1182
+ * @example
1183
+ * startsWith("hello world", "hello");
1184
+ * // returns true
1185
+ *
1186
+ * @example
1187
+ * startsWith("hello world", "world");
1188
+ * // returns false
1189
+ *
1190
+ * @example
1191
+ * startsWith("test", "");
1192
+ * // returns true (empty search string always matches)
1193
+ *
1194
+ * @example
1195
+ * startsWith("abc", "abcd");
1196
+ * // returns false
1197
+ */
1198
+ function startsWith(str, search) {
1199
+ return str.slice(0, search.length) === search;
1200
+ }
1201
+
1179
1202
  /**
1180
1203
  * Expando cache for adding properties to DOM nodes with JavaScript.
1181
1204
  * This used to be an Object in JQLite decorator, but swapped out for a Map
@@ -1759,6 +1782,9 @@ function getBaseHref() {
1759
1782
  * @type Readonly<Record<string, string>>
1760
1783
  */
1761
1784
  const $injectTokens = Object.freeze({
1785
+ $attrs: "$attrs",
1786
+ $scope: "$scope",
1787
+ $element: "$element",
1762
1788
  $$AnimateRunner: "$$AnimateRunner",
1763
1789
  $$animateAsyncRun: "$$animateAsyncRun",
1764
1790
  $$animateCache: "$$animateCache",
@@ -1787,6 +1813,7 @@ const $injectTokens = Object.freeze({
1787
1813
  $ngViewScroll: "$ngViewScroll",
1788
1814
  $parse: "$parse",
1789
1815
  $rootScope: "$rootScope",
1816
+ $rootElement: "$rootElement",
1790
1817
  $routerGlobals: "$routerGlobals",
1791
1818
  $sce: "$sce",
1792
1819
  $sceDelegate: "$sceDelegate",
@@ -1797,7 +1824,7 @@ const $injectTokens = Object.freeze({
1797
1824
  $templateRequest: "$templateRequest",
1798
1825
  $transitions: "$transitions",
1799
1826
  $urlConfig: "$urlConfig",
1800
- $urlService: "$urlService",
1827
+ $url: "$url",
1801
1828
  $view: "$view",
1802
1829
  // provide literals
1803
1830
  $provide: "$provide",
@@ -2143,8 +2170,7 @@ class AbstractInjector {
2143
2170
 
2144
2171
  if (isClass(/** @type {Function} */ (fn))) {
2145
2172
  args.unshift(null);
2146
- const res = new (Function.prototype.bind.apply(fn, args))();
2147
- return res;
2173
+ return new (Function.prototype.bind.apply(fn, args))();
2148
2174
  } else {
2149
2175
  return /** @type {Function} */ (fn).apply(self, args);
2150
2176
  }
@@ -2233,8 +2259,7 @@ class InjectorService extends AbstractInjector {
2233
2259
  */
2234
2260
  factory(serviceName) {
2235
2261
  const provider = this.providerInjector.get(serviceName + providerSuffix$1);
2236
- const res = this.invoke(provider.$get, provider, undefined, serviceName);
2237
- return res;
2262
+ return this.invoke(provider.$get, provider, undefined, serviceName);
2238
2263
  }
2239
2264
 
2240
2265
  /**
@@ -2268,8 +2293,7 @@ function stringifyFn$1(fn) {
2268
2293
  */
2269
2294
  function extractArgs$1(fn) {
2270
2295
  const fnText = stringifyFn$1(fn).replace(STRIP_COMMENTS$1, "");
2271
- const args = fnText.match(ARROW_ARG$1) || fnText.match(FN_ARGS$1);
2272
- return args;
2296
+ return fnText.match(ARROW_ARG$1) || fnText.match(FN_ARGS$1);
2273
2297
  }
2274
2298
 
2275
2299
  /**
@@ -2560,8 +2584,7 @@ function stringifyFn(fn) {
2560
2584
  */
2561
2585
  function extractArgs(fn) {
2562
2586
  const fnText = stringifyFn(fn).replace(STRIP_COMMENTS, "");
2563
- const args = fnText.match(ARROW_ARG) || fnText.match(FN_ARGS);
2564
- return args;
2587
+ return fnText.match(ARROW_ARG) || fnText.match(FN_ARGS);
2565
2588
  }
2566
2589
 
2567
2590
  /**
@@ -3018,11 +3041,7 @@ class ControllerProvider {
3018
3041
  }
3019
3042
  }
3020
3043
 
3021
- const urlParsingNode = document.createElement("a");
3022
3044
  const originUrl = urlResolve(window.location.href);
3023
- let baseUrlParsingNode;
3024
-
3025
- urlParsingNode.href = "http://[::1]";
3026
3045
 
3027
3046
  /**
3028
3047
  * @param {import("./interface.js").ResolvableUrl} url
@@ -3032,7 +3051,10 @@ function urlResolve(url) {
3032
3051
  if (!isString(url))
3033
3052
  return /** @type {import("./interface.js").ParsedUrl} */ (url);
3034
3053
 
3035
- urlParsingNode.setAttribute("href", /** @type {string} */ (url));
3054
+ const urlParsingNode = new URL(
3055
+ /** @type {string} */ (url),
3056
+ window.location.href,
3057
+ );
3036
3058
 
3037
3059
  const hostname = urlParsingNode.hostname.includes(":")
3038
3060
  ? `[${urlParsingNode.hostname}]`
@@ -3040,9 +3062,7 @@ function urlResolve(url) {
3040
3062
 
3041
3063
  return {
3042
3064
  href: urlParsingNode.href,
3043
- protocol: urlParsingNode.protocol
3044
- ? urlParsingNode.protocol.replace(/:$/, "")
3045
- : "",
3065
+ protocol: urlParsingNode.protocol,
3046
3066
  host: urlParsingNode.host,
3047
3067
  search: urlParsingNode.search
3048
3068
  ? urlParsingNode.search.replace(/^\?/, "")
@@ -3080,7 +3100,7 @@ function urlIsSameOrigin(requestUrl) {
3080
3100
  * @returns {boolean} Whether the URL is same-origin as the document base URL.
3081
3101
  */
3082
3102
  function urlIsSameOriginAsBaseUrl(requestUrl) {
3083
- return urlsAreSameOrigin(requestUrl, getBaseUrl());
3103
+ return urlsAreSameOrigin(requestUrl, document.baseURI);
3084
3104
  }
3085
3105
 
3086
3106
  /**
@@ -3132,27 +3152,6 @@ function urlsAreSameOrigin(url1, url2) {
3132
3152
  return url1.protocol === url2.protocol && url1.host === url2.host;
3133
3153
  }
3134
3154
 
3135
- /**
3136
- * Returns the current document base URL.
3137
- * @returns {string}
3138
- */
3139
- function getBaseUrl() {
3140
- if (document.baseURI) {
3141
- return document.baseURI;
3142
- }
3143
-
3144
- // `document.baseURI` is available everywhere except IE
3145
- if (!baseUrlParsingNode) {
3146
- baseUrlParsingNode = document.createElement("a");
3147
- baseUrlParsingNode.href = ".";
3148
-
3149
- // Work-around for IE bug described in Implementation Notes. The fix in `urlResolve()` is not
3150
- // suitable here because we need to track changes to the base URL.
3151
- baseUrlParsingNode = baseUrlParsingNode.cloneNode(false);
3152
- }
3153
- return baseUrlParsingNode.href;
3154
- }
3155
-
3156
3155
  /**
3157
3156
  * Removes a trailing hash ('#') from the given URL if it exists.
3158
3157
  *
@@ -3474,7 +3473,6 @@ class SceDelegateProvider {
3474
3473
  "Attempting to use an unsafe value in a safe context.",
3475
3474
  ),
3476
3475
  );
3477
- return;
3478
3476
  };
3479
3477
 
3480
3478
  if ($injector.has("$sanitize")) {
@@ -3709,7 +3707,6 @@ class SceDelegateProvider {
3709
3707
  "Attempting to use an unsafe value in a safe context.",
3710
3708
  ),
3711
3709
  );
3712
- return;
3713
3710
  }
3714
3711
 
3715
3712
  return { trustAs, getTrusted, valueOf };
@@ -3908,7 +3905,7 @@ function SceProvider() {
3908
3905
 
3909
3906
  /**
3910
3907
  * Shorthand method. `$sce.parseAsHtml(expression string)` →
3911
- * {@link ng.$sce#parseAs `$sce.parseAs($sce.HTML, value)`}
3908
+ * {@link ng.$sceparseAs `$sce.parseAs($sce.HTML, value)`}
3912
3909
  *
3913
3910
  * @param {string} expression String expression to compile.
3914
3911
  * @return {function(context, locals)} A function which represents the compiled expression:
@@ -3921,7 +3918,7 @@ function SceProvider() {
3921
3918
 
3922
3919
  /**
3923
3920
  * Shorthand method. `$sce.parseAsCss(value)` →
3924
- * {@link ng.$sce#parseAs `$sce.parseAs($sce.CSS, value)`}
3921
+ * {@link ng.$sceparseAs `$sce.parseAs($sce.CSS, value)`}
3925
3922
  *
3926
3923
  * @param {string} expression String expression to compile.
3927
3924
  * @return {function(context, locals)} A function which represents the compiled expression:
@@ -3934,7 +3931,7 @@ function SceProvider() {
3934
3931
 
3935
3932
  /**
3936
3933
  * Shorthand method. `$sce.parseAsUrl(value)` →
3937
- * {@link ng.$sce#parseAs `$sce.parseAs($sce.URL, value)`}
3934
+ * {@link ng.$sceparseAs `$sce.parseAs($sce.URL, value)`}
3938
3935
  *
3939
3936
  * @param {string} expression String expression to compile.
3940
3937
  * @return {function(context, locals)} A function which represents the compiled expression:
@@ -3947,7 +3944,7 @@ function SceProvider() {
3947
3944
 
3948
3945
  /**
3949
3946
  * Shorthand method. `$sce.parseAsResourceUrl(value)` →
3950
- * {@link ng.$sce#parseAs `$sce.parseAs($sce.RESOURCE_URL, value)`}
3947
+ * {@link ng.$sceparseAs `$sce.parseAs($sce.RESOURCE_URL, value)`}
3951
3948
  *
3952
3949
  * @param {string} expression String expression to compile.
3953
3950
  * @return {function(context, locals)} A function which represents the compiled expression:
@@ -3960,7 +3957,7 @@ function SceProvider() {
3960
3957
 
3961
3958
  /**
3962
3959
  * Shorthand method. `$sce.parseAsJs(value)` →
3963
- * {@link ng.$sce#parseAs `$sce.parseAs($sce.JS, value)`}
3960
+ * {@link ng.$sceparseAs `$sce.parseAs($sce.JS, value)`}
3964
3961
  *
3965
3962
  * @param {string} expression String expression to compile.
3966
3963
  * @return {function(context, locals)} A function which represents the compiled expression:
@@ -4517,7 +4514,7 @@ const EVENT_HANDLER_ATTR_REGEXP = /^(on[a-z]+|formaction)$/;
4517
4514
  const DirectiveSuffix = "Directive";
4518
4515
 
4519
4516
  class CompileProvider {
4520
- static $inject = ["$provide", "$$sanitizeUriProvider"];
4517
+ /* @ignore */ static $inject = ["$provide", "$$sanitizeUriProvider"];
4521
4518
 
4522
4519
  /**
4523
4520
  * @param {import('../../interface.js').Provider} $provide
@@ -5592,8 +5589,7 @@ class CompileProvider {
5592
5589
  // Null out all of these references for garbage collection
5593
5590
  compileNodes = transcludeFn = previousCompileContext = null;
5594
5591
  }
5595
- const linked = compiled.apply(this, arguments);
5596
- return linked;
5592
+ return compiled.apply(this, arguments);
5597
5593
  };
5598
5594
  }
5599
5595
 
@@ -5937,14 +5933,13 @@ class CompileProvider {
5937
5933
  // * `undefined` - a slot that was not declared (i.e. invalid)
5938
5934
  const slotTranscludeFn = boundTranscludeFn.$$slots[slotName];
5939
5935
  if (slotTranscludeFn) {
5940
- const slotTranscludeRes = slotTranscludeFn(
5936
+ return slotTranscludeFn(
5941
5937
  scope,
5942
5938
  cloneAttachFn,
5943
5939
  transcludeControllers,
5944
5940
  futureParentElement,
5945
5941
  scopeToChild,
5946
5942
  );
5947
- return slotTranscludeRes;
5948
5943
  }
5949
5944
 
5950
5945
  if (isUndefined(slotTranscludeFn)) {
@@ -5957,14 +5952,13 @@ class CompileProvider {
5957
5952
  );
5958
5953
  }
5959
5954
  } else {
5960
- const boundTranscludeRes = boundTranscludeFn(
5955
+ return boundTranscludeFn(
5961
5956
  scope,
5962
5957
  cloneAttachFn,
5963
5958
  transcludeControllers,
5964
5959
  futureParentElement,
5965
5960
  scopeToChild,
5966
5961
  );
5967
- return boundTranscludeRes;
5968
5962
  }
5969
5963
  }
5970
5964
  };
@@ -7728,7 +7722,13 @@ const SUBMITTED_CLASS = "ng-submitted";
7728
7722
 
7729
7723
  class FormController {
7730
7724
  static $nonscope = true;
7731
- static $inject = ["$element", "$attrs", "$scope", "$animate", "$interpolate"];
7725
+ /* @ignore */ static $inject = [
7726
+ "$element",
7727
+ "$attrs",
7728
+ "$scope",
7729
+ "$animate",
7730
+ "$interpolate",
7731
+ ];
7732
7732
 
7733
7733
  /**
7734
7734
  * @param {Element} $element
@@ -8192,7 +8192,7 @@ const formDirectiveFactory = function (isNgForm) {
8192
8192
  return [
8193
8193
  "$parse",
8194
8194
  function ($parse) {
8195
- const formDirective = {
8195
+ return {
8196
8196
  name: "form",
8197
8197
  restrict: isNgForm ? "EA" : "E",
8198
8198
  require: ["form", "^^?form"], // first is the form's own ctrl, second is an optional parent form
@@ -8271,9 +8271,6 @@ const formDirectiveFactory = function (isNgForm) {
8271
8271
  };
8272
8272
  },
8273
8273
  };
8274
-
8275
- return formDirective;
8276
-
8277
8274
  function getSetter(expression) {
8278
8275
  if (expression === "") {
8279
8276
  // create an assignable expression, so forms with an empty name can be renamed later
@@ -8301,7 +8298,7 @@ const DEFAULT_REGEXP = /(\s+|^)default(\s+|$)/;
8301
8298
 
8302
8299
  class NgModelOptionsController {
8303
8300
  static $nonscope = true;
8304
- static $inject = ["$attrs", "$scope"];
8301
+ /* @ignore */ static $inject = ["$attrs", "$scope"];
8305
8302
 
8306
8303
  /**
8307
8304
  * @param {import('../../core/compile/attributes.js').Attributes} $attrs
@@ -8470,14 +8467,14 @@ const ngModelMinErr = minErr("ngModel");
8470
8467
 
8471
8468
  class NgModelController {
8472
8469
  static $nonscope = true;
8473
- static $inject = [
8470
+ /* @ignore */ static $inject = [
8474
8471
  "$scope",
8475
- "$exceptionHandler",
8472
+ $injectTokens.$exceptionHandler,
8476
8473
  "$attrs",
8477
8474
  "$element",
8478
- "$parse",
8479
- "$animate",
8480
- "$interpolate",
8475
+ $injectTokens.$parse,
8476
+ $injectTokens.$animate,
8477
+ $injectTokens.$interpolate,
8481
8478
  ];
8482
8479
 
8483
8480
  /**
@@ -9124,8 +9121,7 @@ class NgModelController {
9124
9121
  }
9125
9122
 
9126
9123
  $$parseAndValidate() {
9127
- const viewValue = this.$$lastCommittedViewValue;
9128
- let modelValue = viewValue;
9124
+ let modelValue = this.$$lastCommittedViewValue;
9129
9125
  const that = this;
9130
9126
 
9131
9127
  this.$$parserValid = isUndefined(modelValue) ? undefined : true;
@@ -10048,9 +10044,8 @@ function createDateInputType(type, regexp, parseDate) {
10048
10044
  }
10049
10045
 
10050
10046
  function badInputChecker(scope, element, attr, ctrl, parserName) {
10051
- const node = element;
10052
10047
  const nativeValidation = (ctrl.$$hasNativeValidators = isObject(
10053
- node.validity,
10048
+ element.validity,
10054
10049
  ));
10055
10050
 
10056
10051
  if (nativeValidation) {
@@ -10597,12 +10592,11 @@ function ngValueDirective() {
10597
10592
  // TODO REMOVE IS SUPPORT
10598
10593
  // Support: IE9 only
10599
10594
  // In IE9 values are converted to string (e.g. `input.value = null` results in `input.value === 'null'`).
10600
- const propValue = isDefined(value)
10595
+ element["value"] = isDefined(value)
10601
10596
  ? isProxy(value)
10602
10597
  ? value.$target
10603
10598
  : value
10604
10599
  : null;
10605
- element["value"] = propValue;
10606
10600
  attr.$set("value", value);
10607
10601
  }
10608
10602
 
@@ -10661,7 +10655,7 @@ class SelectController {
10661
10655
  /**
10662
10656
  * @type {Array<string>}
10663
10657
  */
10664
- static $inject = ["$element", "$scope"];
10658
+ /* @ignore */ static $inject = ["$element", "$scope"];
10665
10659
 
10666
10660
  /**
10667
10661
  * @param {HTMLSelectElement} $element
@@ -11269,6 +11263,7 @@ function ngBindTemplateDirective() {
11269
11263
 
11270
11264
  ngBindHtmlDirective.$inject = [$injectTokens.$parse];
11271
11265
  /**
11266
+ * @param {import('../../core/parse/interface.ts').ParseService} $parse
11272
11267
  * @returns {import('../../interface.ts').Directive}
11273
11268
  */
11274
11269
  function ngBindHtmlDirective($parse) {
@@ -13151,7 +13146,7 @@ Object.entries(ALIASED_ATTR).forEach(([ngAttr]) => {
13151
13146
  *
13152
13147
  */
13153
13148
  const requiredDirective = [
13154
- "$parse",
13149
+ $injectTokens.$parse,
13155
13150
  /**
13156
13151
  * @param {import("../../core/parse/interface.ts").ParseService} $parse
13157
13152
  * @returns {import("../../interface.ts").Directive}
@@ -13233,75 +13228,72 @@ const requiredDirective = [
13233
13228
  * </div>
13234
13229
  */
13235
13230
  const patternDirective = [
13236
- "$parse",
13231
+ $injectTokens.$parse,
13237
13232
  /**
13238
13233
  * @param {import("../../core/parse/interface.ts").ParseService} $parse
13239
13234
  * @returns {import("../../interface.ts").Directive}
13240
13235
  */
13241
- ($parse) => {
13242
- return {
13243
- restrict: "A",
13244
- require: "?ngModel",
13245
- compile: (_Elm, tAttr) => {
13246
- let patternExp;
13247
- let parseFn;
13236
+ ($parse) => ({
13237
+ restrict: "A",
13238
+ require: "?ngModel",
13239
+ compile: (_Elm, tAttr) => {
13240
+ let patternExp;
13241
+ let parseFn;
13248
13242
 
13249
- if (tAttr["ngPattern"]) {
13250
- patternExp = tAttr["ngPattern"];
13243
+ if (tAttr["ngPattern"]) {
13244
+ patternExp = tAttr["ngPattern"];
13251
13245
 
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"]);
13264
- }
13246
+ // ngPattern might be a scope expression, or an inlined regex, which is not parsable.
13247
+ // We get value of the attribute here, so we can compare the old and the new value
13248
+ // in the observer to avoid unnecessary validations
13249
+ if (
13250
+ tAttr["ngPattern"].charAt(0) === "/" &&
13251
+ REGEX_STRING_REGEXP.test(tAttr["ngPattern"])
13252
+ ) {
13253
+ parseFn = function () {
13254
+ return tAttr["ngPattern"];
13255
+ };
13256
+ } else {
13257
+ parseFn = $parse(tAttr["ngPattern"]);
13265
13258
  }
13259
+ }
13266
13260
 
13267
- return function (scope, elm, attr, ctrl) {
13268
- if (!ctrl) return;
13269
-
13270
- let attrVal = attr["pattern"];
13261
+ return function (scope, elm, attr, ctrl) {
13262
+ if (!ctrl) return;
13263
+ let attrVal = attr["pattern"];
13271
13264
 
13272
- if (attr["ngPattern"]) {
13273
- attrVal = parseFn(scope);
13274
- } else {
13275
- patternExp = attr["pattern"];
13276
- }
13265
+ if (attr["ngPattern"]) {
13266
+ attrVal = parseFn(scope);
13267
+ } else {
13268
+ patternExp = attr["pattern"];
13269
+ }
13277
13270
 
13278
- let regexp = parsePatternAttr(attrVal, patternExp, elm);
13279
- attr.$observe("pattern", function (newVal) {
13280
- const oldRegexp = regexp;
13271
+ let regexp = parsePatternAttr(attrVal, patternExp, elm);
13272
+ attr.$observe("pattern", (newVal) => {
13273
+ const oldRegexp = regexp;
13281
13274
 
13282
- regexp = parsePatternAttr(newVal, patternExp, elm);
13275
+ regexp = parsePatternAttr(newVal, patternExp, elm);
13283
13276
 
13284
- if (
13285
- (oldRegexp && oldRegexp.toString()) !==
13286
- (regexp && regexp.toString())
13287
- ) {
13288
- ctrl["$validate"]();
13289
- }
13290
- });
13277
+ if (
13278
+ (oldRegexp && oldRegexp.toString()) !==
13279
+ (regexp && regexp.toString())
13280
+ ) {
13281
+ ctrl["$validate"]();
13282
+ }
13283
+ });
13291
13284
 
13292
- ctrl["$validators"]["pattern"] = function (modelValue, viewValue) {
13293
- // HTML5 pattern constraint validates the input value, so we validate the viewValue
13294
- return (
13295
- // @ts-ignore
13296
- ctrl.$isEmpty(viewValue) ||
13297
- isUndefined(regexp) ||
13298
- regexp.test(viewValue)
13299
- );
13300
- };
13285
+ ctrl["$validators"]["pattern"] = (_modelValue, viewValue) => {
13286
+ // HTML5 pattern constraint validates the input value, so we validate the viewValue
13287
+ return (
13288
+ // @ts-ignore
13289
+ ctrl.$isEmpty(viewValue) ||
13290
+ isUndefined(regexp) ||
13291
+ regexp.test(viewValue)
13292
+ );
13301
13293
  };
13302
- },
13303
- };
13304
- },
13294
+ };
13295
+ },
13296
+ }),
13305
13297
  ];
13306
13298
 
13307
13299
  /**
@@ -13335,7 +13327,7 @@ const patternDirective = [
13335
13327
  *
13336
13328
  */
13337
13329
  const maxlengthDirective = [
13338
- "$parse",
13330
+ $injectTokens.$parse,
13339
13331
  /**
13340
13332
  * @param {import("../../core/parse/interface.ts").ParseService} $parse
13341
13333
  * @returns {import("../../interface.ts").Directive}
@@ -13407,32 +13399,28 @@ const maxlengthDirective = [
13407
13399
  *
13408
13400
  */
13409
13401
  const minlengthDirective = [
13410
- "$parse",
13411
- function ($parse) {
13412
- return {
13413
- restrict: "A",
13414
- require: "?ngModel",
13415
- link(scope, elm, attr, ctrl) {
13416
- if (!ctrl) return;
13402
+ $injectTokens.$parse,
13403
+ ($parse) => ({
13404
+ restrict: "A",
13405
+ require: "?ngModel",
13406
+ link(scope, elm, attr, ctrl) {
13407
+ if (!ctrl) return;
13417
13408
 
13418
- let minlength = attr.minlength || $parse(attr.ngMinlength)(scope);
13419
- let minlengthParsed = parseLength(minlength) || -1;
13409
+ let minlength = attr.minlength || $parse(attr.ngMinlength)(scope);
13410
+ let minlengthParsed = parseLength(minlength) || -1;
13420
13411
 
13421
- attr.$observe("minlength", (value) => {
13422
- if (minlength !== value) {
13423
- minlengthParsed = parseLength(value) || -1;
13424
- minlength = value;
13425
- ctrl.$validate();
13426
- }
13427
- });
13428
- ctrl.$validators.minlength = function (modelValue, viewValue) {
13429
- return (
13430
- ctrl.$isEmpty(viewValue) || viewValue.length >= minlengthParsed
13431
- );
13432
- };
13433
- },
13434
- };
13435
- },
13412
+ attr.$observe("minlength", (value) => {
13413
+ if (minlength !== value) {
13414
+ minlengthParsed = parseLength(value) || -1;
13415
+ minlength = value;
13416
+ ctrl.$validate();
13417
+ }
13418
+ });
13419
+ ctrl.$validators.minlength = function (modelValue, viewValue) {
13420
+ return ctrl.$isEmpty(viewValue) || viewValue.length >= minlengthParsed;
13421
+ };
13422
+ },
13423
+ }),
13436
13424
  ];
13437
13425
 
13438
13426
  function parsePatternAttr(regex, patternExp, elm) {
@@ -13443,7 +13431,12 @@ function parsePatternAttr(regex, patternExp, elm) {
13443
13431
  }
13444
13432
 
13445
13433
  if (isString(regex)) {
13446
- regex = new RegExp(`^${regex}$`);
13434
+ const match = regex.match(/^\/(.*)\/([gimsuy]*)$/);
13435
+ if (match) {
13436
+ regex = new RegExp(match[1], match[2]);
13437
+ } else {
13438
+ regex = new RegExp(`^${regex}$`);
13439
+ }
13447
13440
  }
13448
13441
 
13449
13442
  if (!regex.test) {
@@ -13460,7 +13453,7 @@ function parsePatternAttr(regex, patternExp, elm) {
13460
13453
  }
13461
13454
 
13462
13455
  function parseLength(val) {
13463
- const intVal = toInt(val);
13456
+ const intVal = parseInt(val, 10);
13464
13457
  return isNumberNaN(intVal) ? -1 : intVal;
13465
13458
  }
13466
13459
 
@@ -13483,8 +13476,8 @@ class AnchorScrollProvider {
13483
13476
  }
13484
13477
 
13485
13478
  $get = [
13486
- "$location",
13487
- "$rootScope",
13479
+ $injectTokens.$location,
13480
+ $injectTokens.$rootScope,
13488
13481
  /**
13489
13482
  *
13490
13483
  * @param {import('../services/location/location.js').Location} $location
@@ -13562,7 +13555,7 @@ class AnchorScrollProvider {
13562
13555
  ? hash
13563
13556
  : isNumber(hash)
13564
13557
  ? hash.toString()
13565
- : $location.hash();
13558
+ : $location.getHash();
13566
13559
  let elm;
13567
13560
 
13568
13561
  // empty hash, scroll to the top of the page
@@ -13579,7 +13572,7 @@ class AnchorScrollProvider {
13579
13572
  };
13580
13573
 
13581
13574
  // does not scroll when user clicks on anchor link that is currently on
13582
- // (no url change, no $location.hash() change), browser native does scroll
13575
+ // (no url change, no $location.getHash() change), browser native does scroll
13583
13576
  if (this.autoScrollingEnabled) {
13584
13577
  $rootScope["$location"] = $location;
13585
13578
  $rootScope.$watch("$location.$$hash", (newVal, oldVal) => {
@@ -13952,8 +13945,7 @@ function blockKeyframeAnimations(node, applyBlock) {
13952
13945
 
13953
13946
  function applyInlineStyle(node, styleTuple) {
13954
13947
  const prop = styleTuple[0];
13955
- const value = styleTuple[1];
13956
- node.style[prop] = value;
13948
+ node.style[prop] = styleTuple[1];
13957
13949
  }
13958
13950
 
13959
13951
  function concatWithSpace(a, b) {
@@ -15023,7 +15015,7 @@ function limitToFilter() {
15023
15015
  if (Math.abs(Number(limit)) === Infinity) {
15024
15016
  limit = Number(limit);
15025
15017
  } else {
15026
- limit = toInt(/** @type {string} */ (limit));
15018
+ limit = parseInt(/** @type {string} */ (limit), 10);
15027
15019
  }
15028
15020
  if (isNumberNaN(limit)) return input;
15029
15021
 
@@ -15033,7 +15025,7 @@ function limitToFilter() {
15033
15025
  begin =
15034
15026
  !begin || isNaN(/** @type {any} */ (begin))
15035
15027
  ? 0
15036
- : toInt(/** @type {string} */ (begin));
15028
+ : parseInt(/** @type {string} */ (begin), 10);
15037
15029
  begin =
15038
15030
  begin < 0 ? Math.max(0, /** @type {[]} */ (input).length + begin) : begin;
15039
15031
 
@@ -15227,6 +15219,8 @@ function orderByFilter($parse) {
15227
15219
  }
15228
15220
  }
15229
15221
 
15222
+ $IsStateFilter.$inject = [$injectTokens.$state];
15223
+
15230
15224
  /**
15231
15225
  * `isState` Filter: truthy if the current state is the parameter
15232
15226
  *
@@ -15236,18 +15230,19 @@ function orderByFilter($parse) {
15236
15230
  * ```html
15237
15231
  * <div ng-if="'stateName' | isState">show if state is 'stateName'</div>
15238
15232
  * ```
15239
- */
15240
- $IsStateFilter.$inject = ["$state"];
15241
- /**
15233
+ *
15234
+ * @param {import('./state/state-service.js').StateProvider} $state
15242
15235
  * @returns {import('../interface.ts').FilterFn}
15243
15236
  */
15244
15237
  function $IsStateFilter($state) {
15245
- const isFilter = function (state, params, options) {
15246
- return $state.is(state, params, options);
15247
- };
15238
+ const isFilter = (state, params, options) =>
15239
+ $state.is(state, params, options);
15248
15240
  isFilter.$stateful = true;
15249
15241
  return isFilter;
15250
15242
  }
15243
+
15244
+ $IncludedByStateFilter.$inject = [$injectTokens.$state];
15245
+
15251
15246
  /**
15252
15247
  * `includedByState` Filter: truthy if the current state includes the parameter
15253
15248
  *
@@ -15257,9 +15252,8 @@ function $IsStateFilter($state) {
15257
15252
  * ```html
15258
15253
  * <div ng-if="'fullOrPartialStateName' | includedByState">show if state includes 'fullOrPartialStateName'</div>
15259
15254
  * ```
15260
- */
15261
- $IncludedByStateFilter.$inject = ["$state"];
15262
- /**
15255
+ *
15256
+ * @param {import('./state/state-service.js').StateProvider} $state
15263
15257
  * @returns {import('../interface.ts').FilterFn}
15264
15258
  */
15265
15259
  function $IncludedByStateFilter($state) {
@@ -15273,7 +15267,7 @@ function $IncludedByStateFilter($state) {
15273
15267
  const SUFFIX = "Filter";
15274
15268
 
15275
15269
  class FilterProvider {
15276
- static $inject = [$injectTokens.$provide];
15270
+ /* @ignore */ static $inject = [$injectTokens.$provide];
15277
15271
 
15278
15272
  /**
15279
15273
  * @param {import('../../interface.ts').Provider} $provide
@@ -17176,173 +17170,177 @@ function isConstant(ast) {
17176
17170
  return ast.constant;
17177
17171
  }
17178
17172
 
17179
- function ParseProvider() {
17180
- const cache = Object.create(null);
17181
-
17182
- /** @type {function(any):boolean?} */
17183
- let identStart;
17173
+ class ParseProvider {
17174
+ constructor() {
17175
+ const cache = Object.create(null);
17184
17176
 
17185
- /** @type {function(any):boolean?} */
17186
- let identContinue;
17177
+ /** @type {function(any):boolean?} */
17178
+ let identStart;
17187
17179
 
17188
- /**
17189
- * Allows defining the set of characters that are allowed in AngularTS expressions. The function
17190
- * `identifierStart` will get called to know if a given character is a valid character to be the
17191
- * first character for an identifier. The function `identifierContinue` will get called to know if
17192
- * a given character is a valid character to be a follow-up identifier character. The functions
17193
- * `identifierStart` and `identifierContinue` will receive as arguments the single character to be
17194
- * identifier and the character code point. These arguments will be `string` and `numeric`. Keep in
17195
- * mind that the `string` parameter can be two characters long depending on the character
17196
- * representation. It is expected for the function to return `true` or `false`, whether that
17197
- * character is allowed or not.
17198
- *
17199
- * Since this function will be called extensively, keep the implementation of these functions fast,
17200
- * as the performance of these functions have a direct impact on the expressions parsing speed.
17201
- *
17202
- * @param {function(any):boolean} [identifierStart] The function that will decide whether the given character is
17203
- * a valid identifier start character.
17204
- * @param {function(any):boolean} [identifierContinue] The function that will decide whether the given character is
17205
- * a valid identifier continue character.
17206
- * @returns {ParseProvider}
17207
- */
17208
- this.setIdentifierFns = function (identifierStart, identifierContinue) {
17209
- identStart = identifierStart;
17210
- identContinue = identifierContinue;
17211
- return this;
17212
- };
17180
+ /** @type {function(any):boolean?} */
17181
+ let identContinue;
17213
17182
 
17214
- this.$get = [
17215
- "$filter",
17216
17183
  /**
17184
+ * Allows defining the set of characters that are allowed in AngularTS expressions. The function
17185
+ * `identifierStart` will get called to know if a given character is a valid character to be the
17186
+ * first character for an identifier. The function `identifierContinue` will get called to know if
17187
+ * a given character is a valid character to be a follow-up identifier character. The functions
17188
+ * `identifierStart` and `identifierContinue` will receive as arguments the single character to be
17189
+ * identifier and the character code point. These arguments will be `string` and `numeric`. Keep in
17190
+ * mind that the `string` parameter can be two characters long depending on the character
17191
+ * representation. It is expected for the function to return `true` or `false`, whether that
17192
+ * character is allowed or not.
17193
+ *
17194
+ * Since this function will be called extensively, keep the implementation of these functions fast,
17195
+ * as the performance of these functions have a direct impact on the expressions parsing speed.
17217
17196
  *
17218
- * @param {(any) => any} $filter
17219
- * @returns {import('./interface').ParseService}
17197
+ * @param {function(any):boolean} [identifierStart] The function that will decide whether the given character is
17198
+ * a valid identifier start character.
17199
+ * @param {function(any):boolean} [identifierContinue] The function that will decide whether the given character is
17200
+ * a valid identifier continue character.
17201
+ * @returns {ParseProvider}
17220
17202
  */
17221
- function ($filter) {
17222
- /** @type {import("./lexer/lexer.js").LexerOptions} */
17223
- const $lexerOptions = {
17224
- isIdentifierStart: isFunction(identStart) && identStart,
17225
- isIdentifierContinue: isFunction(identContinue) && identContinue,
17226
- };
17227
- return $parse;
17203
+ this.setIdentifierFns = function (identifierStart, identifierContinue) {
17204
+ identStart = identifierStart;
17205
+ identContinue = identifierContinue;
17206
+ return this;
17207
+ };
17228
17208
 
17209
+ this.$get = [
17210
+ "$filter",
17229
17211
  /**
17230
- * @param {string} exp
17231
- * @param interceptorFn
17232
- * @returns any
17212
+ *
17213
+ * @param {(any) => any} $filter
17214
+ * @returns {import('./interface').ParseService}
17233
17215
  */
17234
- function $parse(exp, interceptorFn) {
17235
- let parsedExpression, cacheKey;
17236
-
17237
- switch (typeof exp) {
17238
- case "string":
17239
- exp = exp.trim();
17240
- cacheKey = exp;
17216
+ function ($filter) {
17217
+ /** @type {import("./lexer/lexer.js").LexerOptions} */
17218
+ const $lexerOptions = {
17219
+ isIdentifierStart: isFunction(identStart) && identStart,
17220
+ isIdentifierContinue: isFunction(identContinue) && identContinue,
17221
+ };
17222
+ return $parse;
17241
17223
 
17242
- parsedExpression = cache[cacheKey];
17224
+ /**
17225
+ * @param {string} exp
17226
+ * @param interceptorFn
17227
+ * @returns any
17228
+ */
17229
+ function $parse(exp, interceptorFn) {
17230
+ let parsedExpression, cacheKey;
17243
17231
 
17244
- if (!parsedExpression) {
17245
- const lexer = new Lexer($lexerOptions);
17246
- const parser = new Parser(lexer, $filter);
17247
- parsedExpression = parser.parse(exp);
17232
+ switch (typeof exp) {
17233
+ case "string":
17234
+ exp = exp.trim();
17235
+ cacheKey = exp;
17248
17236
 
17249
- cache[cacheKey] = addWatchDelegate(parsedExpression);
17250
- }
17251
- return addInterceptor(parsedExpression, interceptorFn);
17237
+ parsedExpression = cache[cacheKey];
17252
17238
 
17253
- case "function":
17254
- return addInterceptor(exp, interceptorFn);
17239
+ if (!parsedExpression) {
17240
+ const lexer = new Lexer($lexerOptions);
17241
+ const parser = new Parser(lexer, $filter);
17242
+ parsedExpression = parser.parse(exp);
17255
17243
 
17256
- default:
17257
- return addInterceptor(() => {}, interceptorFn);
17258
- }
17259
- }
17244
+ cache[cacheKey] = addWatchDelegate(parsedExpression);
17245
+ }
17246
+ return addInterceptor(parsedExpression, interceptorFn);
17260
17247
 
17261
- /**
17262
- * @param {Function} parsedExpression
17263
- * @param interceptorFn
17264
- * @returns {import('./interface').CompiledExpression|*}
17265
- */
17266
- function addInterceptor(parsedExpression, interceptorFn) {
17267
- if (!interceptorFn) return parsedExpression;
17248
+ case "function":
17249
+ return addInterceptor(exp, interceptorFn);
17268
17250
 
17269
- // Extract any existing interceptors out of the parsedExpression
17270
- // to ensure the original parsedExpression is always the $$intercepted
17271
- // @ts-ignore
17272
- if (parsedExpression.$$interceptor) {
17273
- interceptorFn = chainInterceptors(
17274
- // @ts-ignore
17275
- parsedExpression.$$interceptor,
17276
- interceptorFn,
17277
- );
17278
- // @ts-ignore
17279
- parsedExpression = parsedExpression.$$intercepted;
17251
+ default:
17252
+ return addInterceptor(() => {}, interceptorFn);
17253
+ }
17280
17254
  }
17281
17255
 
17282
- let useInputs = false;
17256
+ /**
17257
+ * @param {Function} parsedExpression
17258
+ * @param interceptorFn
17259
+ * @returns {import('./interface').CompiledExpression|*}
17260
+ */
17261
+ function addInterceptor(parsedExpression, interceptorFn) {
17262
+ if (!interceptorFn) {
17263
+ return parsedExpression;
17264
+ }
17283
17265
 
17284
- const fn = function interceptedExpression(
17285
- scope,
17286
- locals,
17287
- assign,
17288
- inputs,
17289
- ) {
17290
- const value =
17291
- useInputs && inputs
17292
- ? inputs[0]
17293
- : parsedExpression(scope, locals, assign, inputs);
17294
- // Do not invoke for getters
17295
- if (scope?.getter) {
17296
- return;
17266
+ // Extract any existing interceptors out of the parsedExpression
17267
+ // to ensure the original parsedExpression is always the $$intercepted
17268
+ // @ts-ignore
17269
+ if (parsedExpression.$$interceptor) {
17270
+ interceptorFn = chainInterceptors(
17271
+ // @ts-ignore
17272
+ parsedExpression.$$interceptor,
17273
+ interceptorFn,
17274
+ );
17275
+ // @ts-ignore
17276
+ parsedExpression = parsedExpression.$$intercepted;
17297
17277
  }
17298
- const res = isFunction(value) ? value() : value;
17299
- return interceptorFn(isProxy(res) ? res.$target : res);
17300
- };
17301
17278
 
17302
- // Maintain references to the interceptor/intercepted
17303
- fn.$$intercepted = parsedExpression;
17304
- fn.$$interceptor = interceptorFn;
17279
+ let useInputs = false;
17305
17280
 
17306
- // Propagate the literal/oneTime/constant attributes
17307
- // @ts-ignore
17308
- fn.literal = parsedExpression.literal;
17309
- // @ts-ignore
17310
- fn.oneTime = parsedExpression.oneTime;
17311
- // @ts-ignore
17312
- fn.constant = parsedExpression.constant;
17313
- // @ts-ignore
17314
- fn.decoratedNode = parsedExpression.decoratedNode;
17281
+ const fn = function interceptedExpression(
17282
+ scope,
17283
+ locals,
17284
+ assign,
17285
+ inputs,
17286
+ ) {
17287
+ const value =
17288
+ useInputs && inputs
17289
+ ? inputs[0]
17290
+ : parsedExpression(scope, locals, assign, inputs);
17291
+ // Do not invoke for getters
17292
+ if (scope?.getter) {
17293
+ return;
17294
+ }
17295
+ const res = isFunction(value) ? value() : value;
17296
+ return interceptorFn(isProxy(res) ? res.$target : res);
17297
+ };
17298
+
17299
+ // Maintain references to the interceptor/intercepted
17300
+ fn.$$intercepted = parsedExpression;
17301
+ fn.$$interceptor = interceptorFn;
17315
17302
 
17316
- // Treat the interceptor like filters.
17317
- // If it is not $stateful then only watch its inputs.
17318
- // If the expression itself has no inputs then use the full expression as an input.
17319
- if (!interceptorFn.$stateful) {
17303
+ // Propagate the literal/oneTime/constant attributes
17320
17304
  // @ts-ignore
17321
- useInputs = !parsedExpression.inputs;
17305
+ fn.literal = parsedExpression.literal;
17322
17306
  // @ts-ignore
17323
- fn.inputs = parsedExpression.inputs
17324
- ? // @ts-ignore
17325
- parsedExpression.inputs
17326
- : [parsedExpression];
17327
-
17328
- if (!interceptorFn.$$pure) {
17329
- fn.inputs = fn.inputs.map(function (e) {
17330
- // Remove the isPure flag of inputs when it is not absolute because they are now wrapped in a
17331
- // non-pure interceptor function.
17332
- if (e.isPure === PURITY_RELATIVE) {
17333
- return function depurifier(s) {
17334
- return e(s);
17335
- };
17336
- }
17337
- return e;
17338
- });
17307
+ fn.oneTime = parsedExpression.oneTime;
17308
+ // @ts-ignore
17309
+ fn.constant = parsedExpression.constant;
17310
+ // @ts-ignore
17311
+ fn.decoratedNode = parsedExpression.decoratedNode;
17312
+
17313
+ // Treat the interceptor like filters.
17314
+ // If it is not $stateful then only watch its inputs.
17315
+ // If the expression itself has no inputs then use the full expression as an input.
17316
+ if (!interceptorFn.$stateful) {
17317
+ // @ts-ignore
17318
+ useInputs = !parsedExpression.inputs;
17319
+ // @ts-ignore
17320
+ fn.inputs = parsedExpression.inputs
17321
+ ? // @ts-ignore
17322
+ parsedExpression.inputs
17323
+ : [parsedExpression];
17324
+
17325
+ if (!interceptorFn.$$pure) {
17326
+ fn.inputs = fn.inputs.map(function (e) {
17327
+ // Remove the isPure flag of inputs when it is not absolute because they are now wrapped in a
17328
+ // non-pure interceptor function.
17329
+ if (e.isPure === PURITY_RELATIVE) {
17330
+ return function depurifier(s) {
17331
+ return e(s);
17332
+ };
17333
+ }
17334
+ return e;
17335
+ });
17336
+ }
17339
17337
  }
17340
- }
17341
17338
 
17342
- return addWatchDelegate(fn);
17343
- }
17344
- },
17345
- ];
17339
+ return addWatchDelegate(fn);
17340
+ }
17341
+ },
17342
+ ];
17343
+ }
17346
17344
  }
17347
17345
 
17348
17346
  function constantWatchDelegate(
@@ -17820,8 +17818,7 @@ class InterpolateProvider {
17820
17818
  let j = 0;
17821
17819
  for (; j < ii; j++) {
17822
17820
  let fn = parseFns[j];
17823
- let res = fn(context);
17824
- vals[j] = res;
17821
+ vals[j] = fn(context);
17825
17822
  }
17826
17823
  cb(compute(vals));
17827
17824
  });
@@ -17830,8 +17827,7 @@ class InterpolateProvider {
17830
17827
  values[i] = parseFns[i](context);
17831
17828
  }
17832
17829
 
17833
- let res = compute(values);
17834
- return res;
17830
+ return compute(values);
17835
17831
  } catch (err) {
17836
17832
  interr(text, err);
17837
17833
  }
@@ -18223,6 +18219,7 @@ function HttpProvider() {
18223
18219
  });
18224
18220
 
18225
18221
  let useApplyAsync = false;
18222
+
18226
18223
  /**
18227
18224
  * Configure $http service to combine processing of multiple http responses received at around
18228
18225
  * the same time via {@link ng.$rootScope.Scope#$applyAsync $rootScope.$applyAsync}. This can result in
@@ -18255,7 +18252,7 @@ function HttpProvider() {
18255
18252
  *
18256
18253
  * {@link ng.$http#interceptors Interceptors detailed info}
18257
18254
  */
18258
- const interceptorFactories = (this.interceptors = []);
18255
+ this.interceptors = [];
18259
18256
 
18260
18257
  /**
18261
18258
  * Array containing URLs whose origins are trusted to receive the XSRF token. See the
@@ -18292,8 +18289,10 @@ function HttpProvider() {
18292
18289
  * $http.get('https://stats.example.com/activity').then(...);
18293
18290
  * }]);
18294
18291
  * ```
18292
+ *
18293
+ * @type {string[]}
18295
18294
  */
18296
- const xsrfTrustedOrigins = (this.xsrfTrustedOrigins = []);
18295
+ this.xsrfTrustedOrigins = [];
18297
18296
 
18298
18297
  /**
18299
18298
  * This property is deprecated. Use {@link $httpProvider#xsrfTrustedOrigins xsrfTrustedOrigins}
@@ -18339,7 +18338,7 @@ function HttpProvider() {
18339
18338
  */
18340
18339
  const reversedInterceptors = [];
18341
18340
 
18342
- interceptorFactories.forEach((interceptorFactory) => {
18341
+ this.interceptors.forEach((interceptorFactory) => {
18343
18342
  reversedInterceptors.unshift(
18344
18343
  isString(interceptorFactory)
18345
18344
  ? $injector.get(interceptorFactory)
@@ -18350,7 +18349,9 @@ function HttpProvider() {
18350
18349
  /**
18351
18350
  * A function to check request URLs against a list of allowed origins.
18352
18351
  */
18353
- const urlIsAllowedOrigin = urlIsAllowedOriginFactory(xsrfTrustedOrigins);
18352
+ const urlIsAllowedOrigin = urlIsAllowedOriginFactory(
18353
+ this.xsrfTrustedOrigins,
18354
+ );
18354
18355
 
18355
18356
  /**
18356
18357
  * @property {Array.<Object>} requestConfig Array of config objects for currently pending
@@ -18849,24 +18850,13 @@ function HttpProvider() {
18849
18850
  }
18850
18851
 
18851
18852
  /**
18852
- * HTTP backend used by the {@link ng.$http service} that delegates to
18853
- * XMLHttpRequest object and deals with browser incompatibilities.
18854
- *
18855
- * You should never need to use this service directly, instead use the higher-level abstractions:
18856
- * {@link ng.$http $http}.
18857
- *
18858
- */
18859
- /**
18860
- * HTTP backend used by the {@link ng.$http service} that delegates to
18853
+ * HTTP backend used by the `$http` that delegates to
18861
18854
  * XMLHttpRequest object and deals with browser incompatibilities.
18862
- *
18863
- * You should never need to use this service directly, instead use the higher-level abstractions:
18864
- * {@link ng.$http $http}.
18865
- *
18855
+ * You should never need to use this service directly.
18866
18856
  */
18867
18857
  class HttpBackendProvider {
18868
18858
  constructor() {
18869
- this.$get = [() => createHttpBackend()];
18859
+ this.$get = () => createHttpBackend();
18870
18860
  }
18871
18861
  }
18872
18862
 
@@ -18874,7 +18864,21 @@ class HttpBackendProvider {
18874
18864
  * @returns
18875
18865
  */
18876
18866
  function createHttpBackend() {
18877
- // TODO(vojta): fix the signature
18867
+ /**
18868
+ * Makes an HTTP request using XMLHttpRequest with flexible options.
18869
+ *
18870
+ * @param {string} method - The HTTP method (e.g., "GET", "POST").
18871
+ * @param {string} [url] - The URL to send the request to. Defaults to the current page URL.
18872
+ * @param {*} [post] - The body to send with the request, if any.
18873
+ * @param {function(number, any, string|null, string, string): void} [callback] - Callback invoked when the request completes.
18874
+ * @param {Object<string, string|undefined>} [headers] - Headers to set on the request.
18875
+ * @param {number|Promise<any>} [timeout] - Timeout in ms or a cancellable promise.
18876
+ * @param {boolean} [withCredentials] - Whether to send credentials with the request.
18877
+ * @param {XMLHttpRequestResponseType} [responseType] - The type of data expected in the response.
18878
+ * @param {Object<string, EventListener>} [eventHandlers] - Event listeners for the XMLHttpRequest object.
18879
+ * @param {Object<string, EventListener>} [uploadEventHandlers] - Event listeners for the XMLHttpRequest.upload object.
18880
+ * @returns {void}
18881
+ */
18878
18882
  return function (
18879
18883
  method,
18880
18884
  url,
@@ -18891,34 +18895,31 @@ function createHttpBackend() {
18891
18895
 
18892
18896
  const xhr = new XMLHttpRequest();
18893
18897
  let abortedByTimeout = false;
18898
+ let timeoutId;
18894
18899
 
18895
18900
  xhr.open(method, url, true);
18901
+
18896
18902
  if (headers) {
18897
- Object.entries(headers).forEach(([key, value]) => {
18903
+ for (const [key, value] of Object.entries(headers)) {
18898
18904
  if (isDefined(value)) {
18899
18905
  xhr.setRequestHeader(key, value);
18900
18906
  }
18901
- });
18907
+ }
18902
18908
  }
18903
18909
 
18904
- xhr.onload = function () {
18910
+ xhr.onload = () => {
18911
+ let status = xhr.status || 0;
18905
18912
  const statusText = xhr.statusText || "";
18906
18913
 
18907
- let status = xhr.status;
18908
-
18909
- // fix status code when it is 0 (0 status is undocumented).
18910
- // Occurs when accessing file resources or on Android 4.1 stock browser
18911
- // while retrieving files from application cache.
18912
18914
  if (status === 0) {
18913
18915
  status = xhr.response
18914
18916
  ? 200
18915
- : urlResolve(url).protocol === "file"
18917
+ : new URL(url).protocol === "file:"
18916
18918
  ? 404
18917
18919
  : 0;
18918
18920
  }
18919
18921
 
18920
18922
  completeRequest(
18921
- callback,
18922
18923
  status,
18923
18924
  xhr.response,
18924
18925
  xhr.getAllResponseHeaders(),
@@ -18927,20 +18928,11 @@ function createHttpBackend() {
18927
18928
  );
18928
18929
  };
18929
18930
 
18930
- xhr.onerror = function () {
18931
- // The response is always empty
18932
- // See https://xhr.spec.whatwg.org/#request-error-steps and https://fetch.spec.whatwg.org/#concept-network-error
18933
- completeRequest(callback, -1, null, null, "", "error");
18934
- };
18935
- xhr.ontimeout = function () {
18936
- // The response is always empty
18937
- // See https://xhr.spec.whatwg.org/#request-error-steps and https://fetch.spec.whatwg.org/#concept-network-error
18938
- completeRequest(callback, -1, null, null, "", "timeout");
18939
- };
18931
+ xhr.onerror = () => completeRequest(-1, null, null, "", "error");
18932
+ xhr.ontimeout = () => completeRequest(-1, null, null, "", "timeout");
18940
18933
 
18941
- xhr.onabort = function () {
18934
+ xhr.onabort = () => {
18942
18935
  completeRequest(
18943
- callback,
18944
18936
  -1,
18945
18937
  null,
18946
18938
  null,
@@ -18950,16 +18942,15 @@ function createHttpBackend() {
18950
18942
  };
18951
18943
 
18952
18944
  if (eventHandlers) {
18953
- eventHandlers &&
18954
- Object.entries(eventHandlers).forEach(([key, value]) => {
18955
- xhr.addEventListener(key, value);
18956
- });
18945
+ for (const [key, handler] of Object.entries(eventHandlers)) {
18946
+ xhr.addEventListener(key, handler);
18947
+ }
18957
18948
  }
18958
18949
 
18959
18950
  if (uploadEventHandlers) {
18960
- Object.entries(uploadEventHandlers).forEach(([key, value]) => {
18961
- xhr.upload.addEventListener(key, value);
18962
- });
18951
+ for (const [key, handler] of Object.entries(uploadEventHandlers)) {
18952
+ xhr.upload.addEventListener(key, handler);
18953
+ }
18963
18954
  }
18964
18955
 
18965
18956
  if (withCredentials) {
@@ -18970,317 +18961,198 @@ function createHttpBackend() {
18970
18961
  try {
18971
18962
  xhr.responseType = responseType;
18972
18963
  } catch (e) {
18973
- // WebKit added support for the json responseType value on 09/03/2013
18974
- // https://bugs.webkit.org/show_bug.cgi?id=73648. Versions of Safari prior to 7 are
18975
- // known to throw when setting the value "json" as the response type. Other older
18976
- // browsers implementing the responseType
18977
- //
18978
- // The json response type can be ignored if not supported, because JSON payloads are
18979
- // parsed on the client-side regardless.
18980
- if (responseType !== "json") {
18981
- throw e;
18982
- }
18964
+ if (responseType !== "json") throw e;
18983
18965
  }
18984
18966
  }
18985
18967
 
18986
18968
  xhr.send(isUndefined(post) ? null : post);
18987
18969
 
18988
- // Since we are using xhr.abort() when a request times out, we have to set a flag that
18989
- // indicates to requestAborted if the request timed out or was aborted.
18990
- //
18991
- // http.timeout = numerical timeout timeout
18992
- // http.timeout = $timeout timeout
18993
- // http.timeout = promise abort
18994
- // xhr.abort() abort (The xhr object is normally inaccessible, but
18995
- // can be exposed with the xhrFactory)
18996
- /** @type {number} */
18997
- let timeoutId;
18998
- if (timeout > 0) {
18999
- timeoutId = setTimeout(() => {
19000
- timeoutRequest("timeout");
19001
- }, timeout);
18970
+ if (typeof timeout === "number" && timeout > 0) {
18971
+ timeoutId = setTimeout(() => timeoutRequest("timeout"), timeout);
19002
18972
  } else if (isPromiseLike(timeout)) {
19003
- timeout.then(() => {
19004
- timeoutRequest(isDefined(timeout.$$timeoutId) ? "timeout" : "abort");
18973
+ /** @type {Promise} */ (timeout).then(() => {
18974
+ timeoutRequest(isDefined(timeout["$$timeoutId"]) ? "timeout" : "abort");
19005
18975
  });
19006
18976
  }
19007
18977
 
18978
+ /**
18979
+ * @param {"timeout"|"abort"} reason
18980
+ */
19008
18981
  function timeoutRequest(reason) {
19009
18982
  abortedByTimeout = reason === "timeout";
19010
- if (xhr) {
19011
- xhr.abort();
19012
- }
18983
+ if (xhr) xhr.abort();
19013
18984
  }
19014
18985
 
18986
+ /**
18987
+ * @param {number} status - HTTP status code or -1 for network errors.
18988
+ * @param {*} response - The parsed or raw response from the server.
18989
+ * @param {string|null} headersString - The raw response headers as a string.
18990
+ * @param {string} statusText - The status text returned by the server.
18991
+ * @param {"complete"|"error"|"timeout"|"abort"} xhrStatus - Final status of the request.
18992
+ */
19015
18993
  function completeRequest(
19016
- callback,
19017
18994
  status,
19018
18995
  response,
19019
18996
  headersString,
19020
18997
  statusText,
19021
18998
  xhrStatus,
19022
18999
  ) {
19023
- // cancel timeout and subsequent timeout promise resolution
19024
19000
  if (isDefined(timeoutId)) {
19025
19001
  clearTimeout(timeoutId);
19026
19002
  }
19027
-
19028
19003
  callback(status, response, headersString, statusText, xhrStatus);
19029
19004
  }
19030
19005
  };
19031
19006
  }
19032
19007
 
19008
+ const PATH_MATCH = /^([^?#]*)(\?([^#]*))?(#(.*))?$/;
19009
+ const $locationMinErr = minErr("$location");
19010
+
19011
+ let urlUpdatedByLocation = false;
19012
+
19033
19013
  /**
19034
- * @typedef {Object} DefaultPorts
19035
- * @property {number} http
19036
- * @property {number} https
19037
- * @property {number} ftp
19014
+ * @ignore
19015
+ * The pathname, beginning with "/"
19016
+ * @type {string}
19038
19017
  */
19018
+ let $$path;
19039
19019
 
19040
19020
  /**
19041
- * Represents the configuration options for HTML5 mode.
19042
- *
19043
- * @typedef {Object} Html5Mode
19044
- * @property {boolean} enabled - (default: false) If true, will rely on `history.pushState` to
19045
- * change URLs where supported. Falls back to hash-prefixed paths in browsers that do not
19046
- * support `pushState`.
19047
- * @property {boolean} requireBase - (default: `true`) When html5Mode is enabled, specifies
19048
- * whether or not a `<base>` tag is required to be present. If both `enabled` and `requireBase`
19049
- * are true, and a `<base>` tag is not present, an error will be thrown when `$location` is injected.
19050
- * See the {@link guide/$location $location guide} for more information.
19051
- * @property {boolean|string} rewriteLinks - (default: `true`) When html5Mode is enabled, enables or
19052
- * disables URL rewriting for relative links. If set to a string, URL rewriting will only apply to links
19053
- * with an attribute that matches the given string. For example, if set to `'internal-link'`, URL rewriting
19054
- * will only occur for `<a internal-link>` links. Note that [attribute name normalization](guide/directive#normalization)
19055
- * does not apply here, so `'internalLink'` will **not** match `'internal-link'`.
19021
+ * @type {Object.<string,boolean|Array>}
19056
19022
  */
19057
-
19058
- /** @type {DefaultPorts} */
19059
- const DEFAULT_PORTS = { http: 80, https: 443, ftp: 21 };
19060
- const PATH_MATCH = /^([^?#]*)(\?([^#]*))?(#(.*))?$/;
19061
- const $locationMinErr = minErr("$location");
19023
+ let $$search;
19062
19024
 
19063
19025
  /**
19064
- * @abstract
19026
+ * @ignore
19027
+ * The hash string, minus the hash symbol
19028
+ * @type {string}
19065
19029
  */
19030
+ let $$hash;
19031
+
19066
19032
  class Location {
19067
19033
  /**
19068
19034
  * @param {string} appBase application base URL
19069
19035
  * @param {string} appBaseNoFile application base URL stripped of any filename
19036
+ * @param {boolean} [html5] Defaults to true
19037
+ * @param {string} [prefix] URL path prefix for html5 mode or hash prefix for hashbang mode
19070
19038
  */
19071
- constructor(appBase, appBaseNoFile) {
19072
- const parsedUrl = urlResolve(appBase);
19073
-
19039
+ constructor(appBase, appBaseNoFile, html5 = true, prefix) {
19074
19040
  /** @type {string} */
19075
19041
  this.appBase = appBase;
19076
19042
 
19077
19043
  /** @type {string} */
19078
19044
  this.appBaseNoFile = appBaseNoFile;
19079
19045
 
19080
- /**
19081
- * 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).
19082
- * @type {string}
19083
- */
19084
- this.$$absUrl = "";
19085
-
19086
- /**
19087
- * If html5 mode is enabled
19088
- * @type {boolean}
19089
- */
19090
- this.$$html5 = false;
19091
-
19092
- /**
19093
- * Has any change been replacing?
19094
- * @type {boolean}
19095
- */
19096
- this.$$replace = false;
19046
+ /** @type {boolean} */
19047
+ this.html5 = html5;
19097
19048
 
19098
- /** @type {string} */
19099
- this.$$protocol = parsedUrl.protocol;
19049
+ /** @type {string | undefined} */
19050
+ this.basePrefix = html5 ? prefix || "" : undefined;
19100
19051
 
19101
- /** @type {string} */
19102
- this.$$host = parsedUrl.hostname;
19103
-
19104
- /**
19105
- * The port, without ":"
19106
- * @type {number}
19107
- */
19108
- this.$$port =
19109
- toInt(parsedUrl.port) || DEFAULT_PORTS[parsedUrl.protocol] || null;
19052
+ /** @type {string | undefined} */
19053
+ this.hashPrefix = html5 ? undefined : prefix;
19110
19054
 
19111
19055
  /**
19112
- * The pathname, beginning with "/"
19056
+ * 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)
19057
+ * with all segments encoded according to rules specified in [RFC 3986](http://www.ietf.org/rfc/rfc3986.txt).
19113
19058
  * @type {string}
19114
19059
  */
19115
- this.$$path = undefined;
19060
+ this.absUrl = "";
19116
19061
 
19117
19062
  /**
19118
- * The hash string, minus the hash symbol
19063
+ * @ignore
19064
+ * Current url
19119
19065
  * @type {string}
19120
19066
  */
19121
- this.$$hash = undefined;
19067
+ this.$$url = undefined;
19122
19068
 
19123
19069
  /**
19124
- * Helper property for scope watch changes
19125
- * @type {boolean}
19070
+ * @ignore
19071
+ * Callback to update browser url
19072
+ * @type {Function}
19126
19073
  */
19127
- this.$$urlUpdatedByLocation = false;
19074
+ this.$$updateBrowser = undefined;
19128
19075
  }
19129
19076
 
19130
19077
  /**
19131
- * Return full URL representation with all segments encoded according to rules specified in
19132
- * [RFC 3986](http://www.ietf.org/rfc/rfc3986.txt).
19133
- *
19134
- * @return {string} full URL
19135
- */
19136
- absUrl() {
19137
- return this.$$absUrl;
19138
- }
19139
-
19140
- /**
19141
- * This method is getter / setter.
19142
- *
19143
- * Return URL (e.g. `/path?a=b#hash`) when called without any parameter.
19144
19078
  * Change path, search and hash, when called with parameter and return `$location`.
19145
19079
  *
19146
- * @param {string=} url New URL without base prefix (e.g. `/path?a=b#hash`)
19147
- * @return {Location|string} url
19080
+ * @param {string} url New URL without base prefix (e.g. `/path?a=b#hash`)
19081
+ * @return {Location} url
19148
19082
  */
19149
- url(url) {
19150
- if (isUndefined(url)) {
19151
- return this.$$url;
19152
- }
19153
-
19083
+ setUrl(url) {
19154
19084
  const match = PATH_MATCH.exec(url);
19155
- if (match[1] || url === "") this.path(decodeURIComponent(match[1]));
19156
- if (match[2] || match[1] || url === "") this.search(match[3] || "");
19157
- this.hash(match[5] || "");
19085
+ if (match[1] || url === "") this.setPath(decodeURIComponent(match[1]));
19086
+ if (match[2] || match[1] || url === "") this.setSearch(match[3] || "");
19087
+ this.setHash(match[5] || "");
19158
19088
 
19159
19089
  return this;
19160
19090
  }
19161
19091
 
19162
19092
  /**
19093
+ * Return URL (e.g. `/path?a=b#hash`) when called without any parameter.
19163
19094
  *
19164
- * Return protocol of current URL.
19165
- * @return {string} protocol of current URL
19095
+ * @return {string} url
19166
19096
  */
19167
- protocol() {
19168
- return this.$$protocol;
19097
+ getUrl() {
19098
+ return this.$$url;
19169
19099
  }
19170
19100
 
19171
19101
  /**
19172
- * This method is getter only.
19173
- *
19174
- * Return host of current URL.
19175
- *
19176
- * Note: compared to the non-AngularTS version `location.host` which returns `hostname:port`, this returns the `hostname` portion only.
19102
+ * Change path parameter and return `$location`.
19177
19103
  *
19178
- *
19179
- * @return {string} host of current URL.
19104
+ * @param {(string|number)} path New path
19105
+ * @return {Location}
19180
19106
  */
19181
- host() {
19182
- return this.$$host;
19183
- }
19184
-
19185
- /**
19186
- * This method is getter only.
19187
- *
19188
- * Return port of current URL.
19189
- *
19190
- *
19191
- * ```js
19192
- * // given URL http://example.com/#/some/path?foo=bar&baz=xoxo
19193
- * let port = $location.port();
19194
- * // => 80
19195
- * ```
19196
- *
19197
- * @return {number} port
19198
- */
19199
- port() {
19200
- return this.$$port;
19107
+ setPath(path) {
19108
+ let newPath = path !== null ? path.toString() : "";
19109
+ $$path = newPath.charAt(0) === "/" ? newPath : `/${newPath}`;
19110
+ this.$$compose();
19111
+ return this;
19201
19112
  }
19202
19113
 
19203
19114
  /**
19204
- * This method is getter / setter.
19205
- *
19206
- * Return path of current URL when called without any parameter.
19207
19115
  *
19208
- * Change path when called with parameter and return `$location`.
19116
+ * Return path of current URL
19209
19117
  *
19210
- * Note: Path should always begin with forward slash (/), this method will add the forward slash
19211
- * if it is missing.
19212
- *
19213
- *
19214
- * ```js
19215
- * // given URL http://example.com/#/some/path?foo=bar&baz=xoxo
19216
- * let path = $location.path();
19217
- * // => "/some/path"
19218
- * ```
19219
- *
19220
- * @param {(string|number)=} path New path
19221
- * @return {(string|object)} path if called with no parameters, or `$location` if called with a parameter
19118
+ * @return {string}
19222
19119
  */
19223
- path(path) {
19224
- if (isUndefined(path)) {
19225
- return this.$$path;
19226
- }
19227
- let newPath = path !== null ? path.toString() : "";
19228
- this.$$path = newPath.charAt(0) === "/" ? newPath : `/${newPath}`;
19229
- this.$$compose();
19230
- return this;
19120
+ getPath() {
19121
+ return $$path;
19231
19122
  }
19232
19123
 
19233
19124
  /**
19234
- * This method is getter / setter.
19235
- *
19236
- * Returns the hash fragment when called without any parameters.
19237
- *
19238
19125
  * Changes the hash fragment when called with a parameter and returns `$location`.
19239
- *
19240
- *
19241
- * ```js
19242
- * // given URL http://example.com/#/some/path?foo=bar&baz=xoxo#hashValue
19243
- * let hash = $location.hash();
19244
- * // => "hashValue"
19245
- * ```
19246
- *
19247
- * @param {(string|number)=} hash New hash fragment
19248
- * @return {string|Location} hash
19126
+ * @param {(string|number)} hash New hash fragment
19127
+ * @return {Location} hash
19249
19128
  */
19250
- hash(hash) {
19251
- if (isUndefined(hash)) {
19252
- return this.$$hash;
19253
- }
19254
-
19255
- this.$$hash = hash !== null ? hash.toString() : "";
19129
+ setHash(hash) {
19130
+ $$hash = hash !== null ? hash.toString() : "";
19256
19131
  this.$$compose();
19257
19132
  return this;
19258
19133
  }
19259
19134
 
19260
19135
  /**
19261
- * If called, all changes to $location during the current `$digest` will replace the current history
19262
- * record, instead of adding a new one.
19136
+ * Returns the hash fragment when called without any parameters.
19137
+ * @return {string} hash
19263
19138
  */
19264
- replace() {
19265
- this.$$replace = true;
19266
- return this;
19139
+ getHash() {
19140
+ return $$hash;
19267
19141
  }
19268
19142
 
19269
19143
  /**
19270
- * Returns or sets the search part (as object) of current URL when called without any parameter
19144
+ * Sets the search part (as object) of current URL
19271
19145
  *
19272
- * @param {string|Object=} search New search params - string or hash object.
19146
+ * @param {string|Object} search New search params - string or hash object.
19273
19147
  * @param {(string|number|Array<string>|boolean)=} paramValue If search is a string or number, then paramValue will override only a single search property.
19274
- * @returns {Object|Location} Search object or Location object
19148
+ * @returns {Object} Search object or Location object
19275
19149
  */
19276
- search(search, paramValue) {
19150
+ setSearch(search, paramValue) {
19277
19151
  switch (arguments.length) {
19278
- case 0:
19279
- return this.$$search;
19280
19152
  case 1:
19281
19153
  if (isString(search) || isNumber(search)) {
19282
19154
  search = search.toString();
19283
- this.$$search = parseKeyValue(search);
19155
+ $$search = parseKeyValue(search);
19284
19156
  } else if (isObject(search)) {
19285
19157
  search = structuredClone(search, {});
19286
19158
  // remove object undefined or null properties
@@ -19288,7 +19160,7 @@ class Location {
19288
19160
  if (value == null) delete search[key];
19289
19161
  });
19290
19162
 
19291
- this.$$search = search;
19163
+ $$search = search;
19292
19164
  } else {
19293
19165
  throw $locationMinErr(
19294
19166
  "isrcharg",
@@ -19298,9 +19170,10 @@ class Location {
19298
19170
  break;
19299
19171
  default:
19300
19172
  if (isUndefined(paramValue) || paramValue === null) {
19301
- delete this.$$search[search];
19173
+ delete $$search[search];
19302
19174
  } else {
19303
- this.$$search[search] = paramValue;
19175
+ // @ts-ignore
19176
+ $$search[search] = paramValue;
19304
19177
  }
19305
19178
  }
19306
19179
 
@@ -19309,28 +19182,28 @@ class Location {
19309
19182
  }
19310
19183
 
19311
19184
  /**
19312
- * Compose url and update `url` and `absUrl` property
19313
- * @returns {void}
19185
+ * Returns the search part (as object) of current URL
19186
+ *
19187
+ * @returns {Object} Search object or Location object
19314
19188
  */
19315
- $$compose() {
19316
- this.$$url = normalizePath(this.$$path, this.$$search, this.$$hash);
19317
- this.$$absUrl = this.$$normalizeUrl(this.$$url);
19318
- this.$$urlUpdatedByLocation = true;
19189
+ getSearch() {
19190
+ return $$search;
19319
19191
  }
19320
19192
 
19321
19193
  /**
19322
- * @param {string} _url
19323
- * @returns {string}
19194
+ * @private
19195
+ * Compose url and update `url` and `absUrl` property
19324
19196
  */
19325
- $$normalizeUrl(_url) {
19326
- throw new Error(`Method not implemented ${_url}`);
19197
+ $$compose() {
19198
+ this.$$url = normalizePath($$path, $$search, $$hash);
19199
+ this.absUrl = this.html5
19200
+ ? this.appBaseNoFile + this.$$url.substring(1)
19201
+ : this.appBase + (this.$$url ? this.hashPrefix + this.$$url : "");
19202
+ urlUpdatedByLocation = true;
19203
+ setTimeout(() => this.$$updateBrowser && this.$$updateBrowser());
19327
19204
  }
19328
19205
 
19329
19206
  /**
19330
- * This method is getter / setter.
19331
- *
19332
- * Return the history state object when called without any parameter.
19333
- *
19334
19207
  * Change the history state object when called with one parameter and return `$location`.
19335
19208
  * The state object is later passed to `pushState` or `replaceState`.
19336
19209
  * See {@link https://developer.mozilla.org/en-US/docs/Web/API/History/pushState#state|History.state}
@@ -19338,85 +19211,30 @@ class Location {
19338
19211
  * NOTE: This method is supported only in HTML5 mode and only in browsers supporting
19339
19212
  * the HTML5 History API (i.e. methods `pushState` and `replaceState`). If you need to support
19340
19213
  * older browsers (like IE9 or Android < 4.0), don't use this method.
19341
- *
19342
- * @param {any} state State object for pushState or replaceState
19343
- * @return {any} state
19214
+ * @param {any} state
19215
+ * @returns {Location}
19344
19216
  */
19345
- state(state) {
19346
- if (!arguments.length) {
19347
- return this.$$state;
19348
- }
19349
-
19350
- if (!(this instanceof LocationHtml5Url) || !this.$$html5) {
19217
+ setState(state) {
19218
+ if (!this.html5) {
19351
19219
  throw $locationMinErr(
19352
19220
  "nostate",
19353
- "History API state support is available only " +
19354
- "in HTML5 mode and only in browsers supporting HTML5 History API",
19221
+ "History API state support is available only in HTML5 mode",
19355
19222
  );
19356
19223
  }
19357
- // The user might modify `stateObject` after invoking `$location.state(stateObject)`
19224
+ // The user might modify `stateObject` after invoking `$location.setState(stateObject)`
19358
19225
  // but we're changing the $$state reference to $browser.state() during the $digest
19359
19226
  // so the modification window is narrow.
19360
19227
  this.$$state = isUndefined(state) ? null : state;
19361
- this.$$urlUpdatedByLocation = true;
19228
+ urlUpdatedByLocation = true;
19362
19229
  return this;
19363
19230
  }
19364
19231
 
19365
19232
  /**
19366
- * @param {string} _url
19367
- * @param {string} _url2
19368
- * @returns {boolean}
19369
- */
19370
- $$parseLinkUrl(_url, _url2) {
19371
- throw new Error(`Method not implemented ${_url} ${_url2}`);
19372
- }
19373
-
19374
- $$parse(_url) {
19375
- throw new Error(`Method not implemented ${_url}`);
19376
- }
19377
- }
19378
-
19379
- /**
19380
- * This object is exposed as $location service when HTML5 mode is enabled and supported
19381
- */
19382
- class LocationHtml5Url extends Location {
19383
- /**
19384
- * @param {string} appBase application base URL
19385
- * @param {string} appBaseNoFile application base URL stripped of any filename
19386
- * @param {string} basePrefix URL path prefix
19387
- */
19388
- constructor(appBase, appBaseNoFile, basePrefix) {
19389
- super(appBase, appBaseNoFile);
19390
- this.$$html5 = true;
19391
- this.basePrefix = basePrefix || "";
19392
- }
19393
-
19394
- /**
19395
- * Parse given HTML5 (regular) URL string into properties
19396
- * @param {string} url HTML5 URL
19233
+ * Return the history state object
19234
+ * @returns {any}
19397
19235
  */
19398
- $$parse(url) {
19399
- const pathUrl = stripBaseUrl(this.appBaseNoFile, url);
19400
- if (!isString(pathUrl)) {
19401
- throw $locationMinErr(
19402
- "ipthprfx",
19403
- 'Invalid url "{0}", missing path prefix "{1}".',
19404
- url,
19405
- this.appBaseNoFile,
19406
- );
19407
- }
19408
-
19409
- parseAppUrl(pathUrl, this, true);
19410
-
19411
- if (!this.$$path) {
19412
- this.$$path = "/";
19413
- }
19414
-
19415
- this.$$compose();
19416
- }
19417
-
19418
- $$normalizeUrl(url) {
19419
- return this.appBaseNoFile + url.substring(1); // first char is always '/'
19236
+ getState() {
19237
+ return this.$$state;
19420
19238
  }
19421
19239
 
19422
19240
  /**
@@ -19424,148 +19242,138 @@ class LocationHtml5Url extends Location {
19424
19242
  * @param {string} relHref
19425
19243
  * @returns {boolean}
19426
19244
  */
19427
- $$parseLinkUrl(url, relHref) {
19428
- if (relHref && relHref[0] === "#") {
19429
- // special case for links to hash fragments:
19430
- // keep the old url and only replace the hash fragment
19431
- this.hash(relHref.slice(1));
19432
- return true;
19433
- }
19434
- let appUrl;
19435
- let prevAppUrl;
19436
- let rewrittenUrl;
19245
+ parseLinkUrl(url, relHref) {
19246
+ if (this.html5) {
19247
+ if (relHref && relHref[0] === "#") {
19248
+ // special case for links to hash fragments:
19249
+ // keep the old url and only replace the hash fragment
19250
+ this.setHash(relHref.slice(1));
19251
+ return true;
19252
+ }
19253
+ let appUrl;
19254
+ let prevAppUrl;
19255
+ let rewrittenUrl;
19437
19256
 
19438
- if (isDefined((appUrl = stripBaseUrl(this.appBase, url)))) {
19439
- prevAppUrl = appUrl;
19440
- if (
19441
- this.basePrefix &&
19442
- isDefined((appUrl = stripBaseUrl(this.basePrefix, appUrl)))
19443
- ) {
19444
- rewrittenUrl =
19445
- this.appBaseNoFile + (stripBaseUrl("/", appUrl) || appUrl);
19446
- } else {
19447
- rewrittenUrl = this.appBase + prevAppUrl;
19257
+ if (isDefined((appUrl = stripBaseUrl(this.appBase, url)))) {
19258
+ prevAppUrl = appUrl;
19259
+ if (
19260
+ this.basePrefix &&
19261
+ isDefined((appUrl = stripBaseUrl(this.basePrefix, appUrl)))
19262
+ ) {
19263
+ rewrittenUrl =
19264
+ this.appBaseNoFile + (stripBaseUrl("/", appUrl) || appUrl);
19265
+ } else {
19266
+ rewrittenUrl = this.appBase + prevAppUrl;
19267
+ }
19268
+ } else if (isDefined((appUrl = stripBaseUrl(this.appBaseNoFile, url)))) {
19269
+ rewrittenUrl = this.appBaseNoFile + appUrl;
19270
+ } else if (this.appBaseNoFile === `${url}/`) {
19271
+ rewrittenUrl = this.appBaseNoFile;
19448
19272
  }
19449
- } else if (isDefined((appUrl = stripBaseUrl(this.appBaseNoFile, url)))) {
19450
- rewrittenUrl = this.appBaseNoFile + appUrl;
19451
- } else if (this.appBaseNoFile === `${url}/`) {
19452
- rewrittenUrl = this.appBaseNoFile;
19453
- }
19454
- if (rewrittenUrl) {
19455
- this.$$parse(rewrittenUrl);
19273
+ if (rewrittenUrl) {
19274
+ this.parse(rewrittenUrl);
19275
+ }
19276
+ return !!rewrittenUrl;
19277
+ } else {
19278
+ if (stripHash(this.appBase) === stripHash(url)) {
19279
+ this.parse(url);
19280
+ return true;
19281
+ }
19282
+ return false;
19456
19283
  }
19457
- return !!rewrittenUrl;
19458
19284
  }
19459
- }
19460
19285
 
19461
- /**
19462
- * LocationHashbangUrl represents URL
19463
- * This object is exposed as $location service when developer doesn't opt into html5 mode.
19464
- * It also serves as the base class for html5 mode fallback on legacy browsers.
19465
- *
19466
- */
19467
- class LocationHashbangUrl extends Location {
19468
19286
  /**
19469
- * @param {string} appBase application base URL
19470
- * @param {string} appBaseNoFile application base URL stripped of any filename
19471
- * @param {string} hashPrefix hashbang prefix
19287
+ * Parse given HTML5 (regular) URL string into properties
19288
+ * @param {string} url HTML5 URL
19472
19289
  */
19473
- constructor(appBase, appBaseNoFile, hashPrefix) {
19474
- super(appBase, appBaseNoFile);
19475
- this.hashPrefix = hashPrefix;
19476
- }
19290
+ parse(url) {
19291
+ if (this.html5) {
19292
+ const pathUrl = stripBaseUrl(this.appBaseNoFile, url);
19293
+ if (!isString(pathUrl)) {
19294
+ throw $locationMinErr(
19295
+ "ipthprfx",
19296
+ 'Invalid url "{0}", missing path prefix "{1}".',
19297
+ url,
19298
+ this.appBaseNoFile,
19299
+ );
19300
+ }
19477
19301
 
19478
- /**
19479
- * Parse given hashbang URL into properties
19480
- * @param {string} url Hashbang URL
19481
- */
19482
- $$parse(url) {
19483
- const withoutBaseUrl =
19484
- stripBaseUrl(this.appBase, url) || stripBaseUrl(this.appBaseNoFile, url);
19485
- let withoutHashUrl;
19302
+ parseAppUrl(pathUrl, true);
19486
19303
 
19487
- if (!isUndefined(withoutBaseUrl) && withoutBaseUrl.charAt(0) === "#") {
19488
- // The rest of the URL starts with a hash so we have
19489
- // got either a hashbang path or a plain hash fragment
19490
- withoutHashUrl = stripBaseUrl(this.hashPrefix, withoutBaseUrl);
19491
- if (isUndefined(withoutHashUrl)) {
19492
- // There was no hashbang prefix so we just have a hash fragment
19493
- withoutHashUrl = withoutBaseUrl;
19304
+ if (!$$path) {
19305
+ $$path = "/";
19494
19306
  }
19307
+
19308
+ this.$$compose();
19495
19309
  } else {
19496
- // There was no hashbang path nor hash fragment:
19497
- // If we are in HTML5 mode we use what is left as the path;
19498
- // Otherwise we ignore what is left
19499
- if (this.$$html5) {
19500
- withoutHashUrl = withoutBaseUrl;
19310
+ const withoutBaseUrl =
19311
+ stripBaseUrl(this.appBase, url) ||
19312
+ stripBaseUrl(this.appBaseNoFile, url);
19313
+ let withoutHashUrl;
19314
+
19315
+ if (!isUndefined(withoutBaseUrl) && withoutBaseUrl.charAt(0) === "#") {
19316
+ // The rest of the URL starts with a hash so we have
19317
+ // got either a hashbang path or a plain hash fragment
19318
+ withoutHashUrl = stripBaseUrl(this.hashPrefix, withoutBaseUrl);
19319
+ if (isUndefined(withoutHashUrl)) {
19320
+ // There was no hashbang prefix so we just have a hash fragment
19321
+ withoutHashUrl = withoutBaseUrl;
19322
+ }
19501
19323
  } else {
19502
- withoutHashUrl = "";
19503
- if (isUndefined(withoutBaseUrl)) {
19504
- this.appBase = url;
19505
- /** @type {?} */ (this).replace();
19324
+ // There was no hashbang path nor hash fragment:
19325
+ // If we are in HTML5 mode we use what is left as the path;
19326
+ // Otherwise we ignore what is left
19327
+ if (this.html5) {
19328
+ withoutHashUrl = withoutBaseUrl;
19329
+ } else {
19330
+ withoutHashUrl = "";
19331
+ if (isUndefined(withoutBaseUrl)) {
19332
+ this.appBase = url;
19333
+ }
19506
19334
  }
19507
19335
  }
19508
- }
19509
19336
 
19510
- parseAppUrl(withoutHashUrl, this, false);
19337
+ parseAppUrl(withoutHashUrl, false);
19511
19338
 
19512
- this.$$path = removeWindowsDriveName(
19513
- this.$$path,
19514
- withoutHashUrl,
19515
- this.appBase,
19516
- );
19339
+ $$path = removeWindowsDriveName($$path, withoutHashUrl, this.appBase);
19517
19340
 
19518
- this.$$compose();
19341
+ this.$$compose();
19519
19342
 
19520
- /*
19521
- * In Windows, on an anchor node on documents loaded from
19522
- * the filesystem, the browser will return a pathname
19523
- * prefixed with the drive name ('/C:/path') when a
19524
- * pathname without a drive is set:
19525
- * * a.setAttribute('href', '/foo')
19526
- * * a.pathname === '/C:/foo' //true
19527
- *
19528
- * Inside of AngularTS, we're always using pathnames that
19529
- * do not include drive names for routing.
19530
- */
19531
- function removeWindowsDriveName(path, url, base) {
19532
19343
  /*
19533
- Matches paths for file protocol on windows,
19534
- such as /C:/foo/bar, and captures only /foo/bar.
19535
- */
19536
- const windowsFilePathExp = /^\/[A-Z]:(\/.*)/;
19537
-
19538
- let firstPathSegmentMatch;
19539
-
19540
- // Get the relative path from the input URL.
19541
- if (startsWith(url, base)) {
19542
- url = url.replace(base, "");
19543
- }
19344
+ * In Windows, on an anchor node on documents loaded from
19345
+ * the filesystem, the browser will return a pathname
19346
+ * prefixed with the drive name ('/C:/path') when a
19347
+ * pathname without a drive is set:
19348
+ * * a.setAttribute('href', '/foo')
19349
+ * * a.pathname === '/C:/foo' //true
19350
+ *
19351
+ * Inside of AngularTS, we're always using pathnames that
19352
+ * do not include drive names for routing.
19353
+ */
19354
+ function removeWindowsDriveName(path, url, base) {
19355
+ /*
19356
+ Matches paths for file protocol on windows,
19357
+ such as /C:/foo/bar, and captures only /foo/bar.
19358
+ */
19359
+ const windowsFilePathExp = /^\/[A-Z]:(\/.*)/;
19544
19360
 
19545
- // The input URL intentionally contains a first path segment that ends with a colon.
19546
- if (windowsFilePathExp.exec(url)) {
19547
- return path;
19548
- }
19361
+ let firstPathSegmentMatch;
19549
19362
 
19550
- firstPathSegmentMatch = windowsFilePathExp.exec(path);
19551
- return firstPathSegmentMatch ? firstPathSegmentMatch[1] : path;
19552
- }
19553
- }
19363
+ // Get the relative path from the input URL.
19364
+ if (startsWith(url, base)) {
19365
+ url = url.replace(base, "");
19366
+ }
19554
19367
 
19555
- $$normalizeUrl(url) {
19556
- return this.appBase + (url ? this.hashPrefix + url : "");
19557
- }
19368
+ // The input URL intentionally contains a first path segment that ends with a colon.
19369
+ if (windowsFilePathExp.exec(url)) {
19370
+ return path;
19371
+ }
19558
19372
 
19559
- /**
19560
- * @param {string} url
19561
- * @returns {boolean}
19562
- */
19563
- $$parseLinkUrl(url) {
19564
- if (stripHash(this.appBase) === stripHash(url)) {
19565
- this.$$parse(url);
19566
- return true;
19373
+ firstPathSegmentMatch = windowsFilePathExp.exec(path);
19374
+ return firstPathSegmentMatch ? firstPathSegmentMatch[1] : path;
19375
+ }
19567
19376
  }
19568
- return false;
19569
19377
  }
19570
19378
  }
19571
19379
 
@@ -19574,20 +19382,20 @@ class LocationProvider {
19574
19382
  /** @type {string} */
19575
19383
  this.hashPrefixConf = "!";
19576
19384
 
19577
- /** @type {Html5Mode} */
19385
+ /** @type {import("./interface.ts").Html5Mode} */
19578
19386
  this.html5ModeConf = {
19579
- enabled: false,
19580
- requireBase: true,
19387
+ enabled: true,
19388
+ requireBase: false,
19581
19389
  rewriteLinks: true,
19582
19390
  };
19583
19391
 
19584
- /** @type {Array<import("./interface.js").UrlChangeListener>} */
19392
+ /** @type {Array<import("./interface.ts").UrlChangeListener>} */
19585
19393
  this.urlChangeListeners = [];
19586
19394
  this.urlChangeInit = false;
19587
19395
 
19588
19396
  /** @type {History['state']} */
19589
19397
  this.cachedState = null;
19590
- /** @typeof {History.state} */
19398
+ /** @type {History['state']} */
19591
19399
  this.lastHistoryState = null;
19592
19400
  /** @type {string} */
19593
19401
  this.lastBrowserUrl = window.location.href;
@@ -19598,14 +19406,19 @@ class LocationProvider {
19598
19406
  // URL API
19599
19407
  /// ///////////////////////////////////////////////////////////
19600
19408
 
19409
+ /**
19410
+ * Updates the browser's current URL and history state.
19411
+ *
19412
+ * @param {string|undefined} url - The target URL to navigate to.
19413
+ * @param {*} [state=null] - Optional history state object to associate with the new URL.
19414
+ * @returns {LocationProvider}
19415
+ */
19601
19416
  setUrl(url, state) {
19602
19417
  if (state === undefined) {
19603
19418
  state = null;
19604
19419
  }
19605
-
19606
- // setter
19607
19420
  if (url) {
19608
- url = urlResolve(url).href;
19421
+ url = new URL(url).href;
19609
19422
 
19610
19423
  if (this.lastBrowserUrl === url && this.lastHistoryState === state) {
19611
19424
  return this;
@@ -19622,7 +19435,7 @@ class LocationProvider {
19622
19435
  * Returns the current URL with any empty hash (`#`) removed.
19623
19436
  * @return {string}
19624
19437
  */
19625
- getUrl() {
19438
+ getBrowserUrl() {
19626
19439
  return trimEmptyHash(window.location.href);
19627
19440
  }
19628
19441
 
@@ -19650,19 +19463,17 @@ class LocationProvider {
19650
19463
 
19651
19464
  /**
19652
19465
  * Fires the state or URL change event.
19653
- *
19654
- * @private
19655
19466
  */
19656
- fireStateOrUrlChange() {
19467
+ #fireStateOrUrlChange() {
19657
19468
  const prevLastHistoryState = this.lastHistoryState;
19658
19469
  this.cacheState();
19659
19470
  if (
19660
- this.lastBrowserUrl === this.getUrl() &&
19471
+ this.lastBrowserUrl === this.getBrowserUrl() &&
19661
19472
  prevLastHistoryState === this.cachedState
19662
19473
  ) {
19663
19474
  return;
19664
19475
  }
19665
- this.lastBrowserUrl = this.getUrl();
19476
+ this.lastBrowserUrl = this.getBrowserUrl();
19666
19477
  this.lastHistoryState = this.cachedState;
19667
19478
  this.urlChangeListeners.forEach((listener) => {
19668
19479
  listener(trimEmptyHash(window.location.href), this.cachedState);
@@ -19675,131 +19486,75 @@ class LocationProvider {
19675
19486
  * @param {import("./interface.js").UrlChangeListener} callback - The callback function to register.
19676
19487
  * @returns void
19677
19488
  */
19678
- onUrlChange(callback) {
19489
+ #onUrlChange(callback) {
19679
19490
  if (!this.urlChangeInit) {
19680
- window.addEventListener("popstate", this.fireStateOrUrlChange.bind(this));
19491
+ window.addEventListener(
19492
+ "popstate",
19493
+ this.#fireStateOrUrlChange.bind(this),
19494
+ );
19681
19495
  window.addEventListener(
19682
19496
  "hashchange",
19683
- this.fireStateOrUrlChange.bind(this),
19497
+ this.#fireStateOrUrlChange.bind(this),
19684
19498
  );
19685
19499
  this.urlChangeInit = true;
19686
19500
  }
19687
19501
  this.urlChangeListeners.push(callback);
19688
19502
  }
19689
19503
 
19690
- /**
19691
- * The default value for the prefix is `'!'`.
19692
- * @param {string=} prefix Prefix for hash part (containing path and search)
19693
- * @returns {void}
19694
- */
19695
- setHashPrefix(prefix) {
19696
- this.hashPrefixConf = prefix;
19697
- }
19698
-
19699
- /**
19700
- * Current hash prefix
19701
- * @returns {string}
19702
- */
19703
- getHashPrefix() {
19704
- return this.hashPrefixConf;
19705
- }
19706
-
19707
- /**
19708
- * Configures html5 mode
19709
- * @param {(boolean|Html5Mode)=} mode If boolean, sets `html5Mode.enabled` to value. Otherwise, accepts html5Mode object
19710
- *
19711
- * @returns {void}
19712
- */
19713
- setHtml5Mode(mode) {
19714
- if (isBoolean(mode)) {
19715
- this.html5ModeConf.enabled = /** @type {boolean} */ (mode);
19716
- }
19717
- if (isObject(mode)) {
19718
- const html5Mode = /** @type {Html5Mode} */ (mode);
19719
- if (isDefined(html5Mode.enabled) && isBoolean(html5Mode.enabled)) {
19720
- this.html5ModeConf.enabled = html5Mode.enabled;
19721
- }
19722
-
19723
- if (
19724
- isDefined(html5Mode.requireBase) &&
19725
- isBoolean(html5Mode.requireBase)
19726
- ) {
19727
- this.html5ModeConf.requireBase = html5Mode.requireBase;
19728
- }
19729
-
19730
- if (
19731
- isDefined(html5Mode.rewriteLinks) &&
19732
- (isBoolean(html5Mode.rewriteLinks) || isString(html5Mode.rewriteLinks))
19733
- ) {
19734
- this.html5ModeConf.rewriteLinks = html5Mode.rewriteLinks;
19735
- }
19736
- }
19737
- }
19738
-
19739
- /**
19740
- * Returns html5 mode cofiguration
19741
- * @returns {Html5Mode}
19742
- */
19743
- getHtml5Mode() {
19744
- return this.html5ModeConf;
19745
- }
19746
-
19747
19504
  $get = [
19748
- "$rootScope",
19749
- "$rootElement",
19505
+ $injectTokens.$rootScope,
19506
+ $injectTokens.$rootElement,
19750
19507
  /**
19751
19508
  *
19752
19509
  * @param {import('../../core/scope/scope.js').Scope} $rootScope
19753
19510
  * @param {Element} $rootElement
19754
- * @returns
19511
+ * @returns {Location}
19755
19512
  */
19756
19513
  ($rootScope, $rootElement) => {
19757
19514
  /** @type {Location} */
19758
19515
  let $location;
19759
- let LocationMode;
19760
19516
  const baseHref = getBaseHref(); // if base[href] is undefined, it defaults to ''
19761
19517
  const initialUrl = trimEmptyHash(window.location.href);
19762
19518
  let appBase;
19763
19519
 
19764
- if (this.getHtml5Mode().enabled) {
19765
- if (!baseHref && this.getHtml5Mode().requireBase) {
19520
+ if (this.html5ModeConf.enabled) {
19521
+ if (!baseHref && this.html5ModeConf.requireBase) {
19766
19522
  throw $locationMinErr(
19767
19523
  "nobase",
19768
19524
  "$location in HTML5 mode requires a <base> tag to be present!",
19769
19525
  );
19770
19526
  }
19771
19527
  appBase = serverBase(initialUrl) + (baseHref || "/");
19772
- LocationMode = LocationHtml5Url;
19773
19528
  } else {
19774
19529
  appBase = stripHash(initialUrl);
19775
- LocationMode = LocationHashbangUrl;
19776
19530
  }
19777
19531
  const appBaseNoFile = stripFile(appBase);
19778
19532
 
19779
- $location = new LocationMode(
19533
+ $location = new Location(
19780
19534
  appBase,
19781
19535
  appBaseNoFile,
19782
- `#${this.getHashPrefix()}`,
19536
+ this.html5ModeConf.enabled,
19537
+ `#${this.hashPrefixConf}`,
19783
19538
  );
19784
- $location.$$parseLinkUrl(initialUrl, initialUrl);
19539
+ $location.parseLinkUrl(initialUrl, initialUrl);
19785
19540
 
19786
19541
  $location.$$state = this.state();
19787
19542
 
19788
19543
  const IGNORE_URI_REGEXP = /^\s*(javascript|mailto):/i;
19789
19544
 
19790
19545
  const setBrowserUrlWithFallback = (url, state) => {
19791
- const oldUrl = $location.url();
19546
+ const oldUrl = $location.getUrl();
19792
19547
  const oldState = $location.$$state;
19793
19548
  try {
19794
19549
  this.setUrl(url, state);
19795
19550
 
19796
- // Make sure $location.state() returns referentially identical (not just deeply equal)
19551
+ // Make sure $location.getState() returns referentially identical (not just deeply equal)
19797
19552
  // state object; this makes possible quick checking if the state changed in the digest
19798
19553
  // loop. Checking deep equality would be too expensive.
19799
19554
  $location.$$state = this.state();
19800
19555
  } catch (e) {
19801
19556
  // Restore old values if pushState fails
19802
- $location.url(/** @type {string} */ (oldUrl));
19557
+ $location.setUrl(/** @type {string} */ (oldUrl));
19803
19558
  $location.$$state = oldState;
19804
19559
 
19805
19560
  throw e;
@@ -19810,7 +19565,7 @@ class LocationProvider {
19810
19565
  "click",
19811
19566
  /** @param {MouseEvent} event */
19812
19567
  (event) => {
19813
- const rewriteLinks = this.getHtml5Mode().rewriteLinks;
19568
+ const rewriteLinks = this.html5ModeConf.rewriteLinks;
19814
19569
  // TODO(vojta): rewrite link when opening in new tab/window (in legacy browser)
19815
19570
  // currently we open nice url link and redirect then
19816
19571
 
@@ -19819,7 +19574,6 @@ class LocationProvider {
19819
19574
  event.ctrlKey ||
19820
19575
  event.metaKey ||
19821
19576
  event.shiftKey ||
19822
- event.which === 2 ||
19823
19577
  event.button === 2
19824
19578
  ) {
19825
19579
  return;
@@ -19854,7 +19608,7 @@ class LocationProvider {
19854
19608
  // an animation.
19855
19609
 
19856
19610
  const scvAnimatedString = /** @type {unknown} */ (absHref);
19857
- absHref = urlResolve(
19611
+ absHref = new URL(
19858
19612
  /** @type {SVGAnimatedString } */ (scvAnimatedString).animVal,
19859
19613
  ).href;
19860
19614
  }
@@ -19867,7 +19621,7 @@ class LocationProvider {
19867
19621
  !elm.getAttribute("target") &&
19868
19622
  !event.defaultPrevented
19869
19623
  ) {
19870
- if ($location.$$parseLinkUrl(absHref, relHref)) {
19624
+ if ($location.parseLinkUrl(absHref, relHref)) {
19871
19625
  // We do a preventDefault for all urls that are part of the AngularTS application,
19872
19626
  // in html5mode and also without, so that we are able to abort navigation without
19873
19627
  // getting double entries in the location history.
@@ -19878,14 +19632,14 @@ class LocationProvider {
19878
19632
  );
19879
19633
 
19880
19634
  // rewrite hashbang url <> html5 url
19881
- if ($location.absUrl() !== initialUrl) {
19882
- this.setUrl($location.absUrl(), true);
19635
+ if ($location.absUrl !== initialUrl) {
19636
+ this.setUrl($location.absUrl, true);
19883
19637
  }
19884
19638
 
19885
19639
  let initializing = true;
19886
19640
 
19887
19641
  // update $location when $browser url changes
19888
- this.onUrlChange((newUrl, newState) => {
19642
+ this.#onUrlChange((newUrl, newState) => {
19889
19643
  if (!startsWith(newUrl, appBaseNoFile)) {
19890
19644
  // If we are navigating outside of the app then force a reload
19891
19645
  window.location.href = newUrl;
@@ -19893,10 +19647,10 @@ class LocationProvider {
19893
19647
  }
19894
19648
 
19895
19649
  Promise.resolve().then(() => {
19896
- const oldUrl = $location.absUrl();
19650
+ const oldUrl = $location.absUrl;
19897
19651
  const oldState = $location.$$state;
19898
19652
  let defaultPrevented;
19899
- $location.$$parse(newUrl);
19653
+ $location.parse(newUrl);
19900
19654
  $location.$$state = newState;
19901
19655
 
19902
19656
  defaultPrevented = $rootScope.$broadcast(
@@ -19909,10 +19663,10 @@ class LocationProvider {
19909
19663
 
19910
19664
  // if the location was changed by a `$locationChangeStart` handler then stop
19911
19665
  // processing this location change
19912
- if ($location.absUrl() !== newUrl) return;
19666
+ if ($location.absUrl !== newUrl) return;
19913
19667
 
19914
19668
  if (defaultPrevented) {
19915
- $location.$$parse(oldUrl);
19669
+ $location.parse(oldUrl);
19916
19670
  $location.$$state = oldState;
19917
19671
  setBrowserUrlWithFallback(oldUrl, oldState);
19918
19672
  } else {
@@ -19924,21 +19678,21 @@ class LocationProvider {
19924
19678
 
19925
19679
  // update browser
19926
19680
  const updateBrowser = () => {
19927
- if (initializing || $location.$$urlUpdatedByLocation) {
19928
- $location.$$urlUpdatedByLocation = false;
19681
+ if (initializing || urlUpdatedByLocation) {
19682
+ urlUpdatedByLocation = false;
19929
19683
 
19930
- const oldUrl = /** @type {string} */ (this.getUrl());
19931
- const newUrl = $location.absUrl();
19684
+ const oldUrl = /** @type {string} */ (this.getBrowserUrl());
19685
+ const newUrl = $location.absUrl;
19932
19686
  const oldState = this.state();
19933
19687
  const urlOrStateChanged =
19934
19688
  !urlsEqual(oldUrl, newUrl) ||
19935
- ($location.$$html5 && oldState !== $location.$$state);
19689
+ ($location.html5 && oldState !== $location.$$state);
19936
19690
 
19937
19691
  if (initializing || urlOrStateChanged) {
19938
19692
  initializing = false;
19939
19693
 
19940
19694
  setTimeout(() => {
19941
- const newUrl = $location.absUrl();
19695
+ const newUrl = $location.absUrl;
19942
19696
  const { defaultPrevented } = $rootScope.$broadcast(
19943
19697
  "$locationChangeStart",
19944
19698
  newUrl,
@@ -19949,10 +19703,10 @@ class LocationProvider {
19949
19703
 
19950
19704
  // if the location was changed by a `$locationChangeStart` handler then stop
19951
19705
  // processing this location change
19952
- if ($location.absUrl() !== newUrl) return;
19706
+ if ($location.absUrl !== newUrl) return;
19953
19707
 
19954
19708
  if (defaultPrevented) {
19955
- $location.$$parse(oldUrl);
19709
+ $location.parse(oldUrl);
19956
19710
  $location.$$state = oldState;
19957
19711
  } else {
19958
19712
  if (urlOrStateChanged) {
@@ -19966,13 +19720,8 @@ class LocationProvider {
19966
19720
  });
19967
19721
  }
19968
19722
  }
19969
-
19970
- $location.$$replace = false;
19971
-
19972
- // we don't need to return anything because $evalAsync will make the digest loop dirty when
19973
- // there is a change
19974
19723
  };
19975
-
19724
+ $location.$$updateBrowser = updateBrowser;
19976
19725
  updateBrowser();
19977
19726
  $rootScope.$on("$updateBrowser", updateBrowser);
19978
19727
 
@@ -19981,7 +19730,7 @@ class LocationProvider {
19981
19730
  function afterLocationChange(oldUrl, oldState) {
19982
19731
  $rootScope.$broadcast(
19983
19732
  "$locationChangeSuccess",
19984
- $location.absUrl(),
19733
+ $location.absUrl,
19985
19734
  oldUrl,
19986
19735
  $location.$$state,
19987
19736
  oldState,
@@ -19993,28 +19742,63 @@ class LocationProvider {
19993
19742
 
19994
19743
  /**
19995
19744
  * ///////////////////////////
19996
- * HELPERS
19745
+ * PRIVATE HELPERS
19997
19746
  * ///////////////////////////
19998
19747
  */
19999
19748
 
20000
19749
  /**
20001
- * Encode path using encodeUriSegment, ignoring forward slashes
19750
+ * @ignore
19751
+ * Encodes a URL path by encoding each path segment individually using `encodeUriSegment`,
19752
+ * while preserving forward slashes (`/`) as segment separators.
20002
19753
  *
20003
- * @param {string} path Path to encode
20004
- * @returns {string}
19754
+ * This function first decodes any existing percent-encodings (such as `%20` or `%2F`)
19755
+ * in each segment to prevent double encoding, except for encoded forward slashes (`%2F`),
19756
+ * which are replaced with literal slashes before decoding to keep path boundaries intact.
19757
+ *
19758
+ * After decoding, each segment is re-encoded with `encodeUriSegment` according to RFC 3986,
19759
+ * encoding only characters that must be encoded in a path segment.
19760
+ *
19761
+ * The encoded segments are then rejoined with `/` to form the encoded path.
19762
+ *
19763
+ * @param {string} path - The URL path string to encode. May contain multiple segments separated by `/`.
19764
+ * @returns {string} The encoded path, where each segment is encoded, but forward slashes are preserved.
19765
+ *
19766
+ * @example
19767
+ * encodePath("user profile/images/pic 1.jpg")
19768
+ * // returns "user%20profile/images/pic%201.jpg"
19769
+ *
19770
+ * @example
19771
+ * encodePath("folder1%2Fsub/folder2")
19772
+ * // returns "folder1%2Fsub/folder2"
20005
19773
  */
20006
19774
  function encodePath(path) {
20007
19775
  const segments = path.split("/");
20008
19776
  let i = segments.length;
20009
19777
 
20010
19778
  while (i--) {
20011
- // decode forward slashes to prevent them from being double encoded
20012
- segments[i] = encodeUriSegment(segments[i].replace(/%2F/g, "/"));
19779
+ // Decode any existing encodings (e.g. %20, %2F) to prevent double-encoding
19780
+ // But keep slashes intact (they were split on)
19781
+ const decodedSegment = decodeURIComponent(
19782
+ segments[i].replace(/%2F/gi, "/"),
19783
+ );
19784
+ segments[i] = encodeUriSegment(decodedSegment);
20013
19785
  }
20014
19786
 
20015
19787
  return segments.join("/");
20016
19788
  }
20017
19789
 
19790
+ /**
19791
+ * @ignore
19792
+ * Decodes each segment of a URL path.
19793
+ *
19794
+ * Splits the input path by "/", decodes each segment using decodeURIComponent,
19795
+ * and if html5Mode is enabled, re-encodes any forward slashes inside segments
19796
+ * as "%2F" to avoid confusion with path separators.
19797
+ *
19798
+ * @param {string} path - The URL path to decode.
19799
+ * @param {boolean} html5Mode - If true, encodes forward slashes in segments as "%2F".
19800
+ * @returns {string} The decoded path with segments optionally encoding slashes.
19801
+ */
20018
19802
  function decodePath(path, html5Mode) {
20019
19803
  const segments = path.split("/");
20020
19804
  let i = segments.length;
@@ -20030,6 +19814,33 @@ function decodePath(path, html5Mode) {
20030
19814
  return segments.join("/");
20031
19815
  }
20032
19816
 
19817
+ /**
19818
+ * @ignore
19819
+ * Normalizes a URL path by encoding the path segments, query parameters, and hash fragment.
19820
+ *
19821
+ * - Path segments are encoded using `encodePath`, which encodes each segment individually.
19822
+ * - Query parameters (`searchValue`) are converted to a query string using `toKeyValue`.
19823
+ * - Hash fragment (`hashValue`) is encoded using `encodeUriSegment` and prefixed with `#`.
19824
+ *
19825
+ * This function returns a fully constructed URL path with optional query and hash components.
19826
+ *
19827
+ * @param {string} pathValue - The base URL path (e.g., "folder/item name").
19828
+ * @param {Object.<string, any> | string | null} searchValue - An object or string representing query parameters.
19829
+ * - If an object, it can contain strings, numbers, booleans, or arrays of values.
19830
+ * - If a string, it is assumed to be a raw query string.
19831
+ * - If null or undefined, no query string is added.
19832
+ * @param {string | null} hashValue - The URL fragment (everything after `#`). If null or undefined, no hash is added.
19833
+ *
19834
+ * @returns {string} The normalized URL path including encoded path, optional query string, and optional hash.
19835
+ *
19836
+ * @example
19837
+ * normalizePath("products/list", { category: "books", page: 2 }, "section1")
19838
+ * // returns "products/list?category=books&page=2#section1"
19839
+ *
19840
+ * @example
19841
+ * normalizePath("user profile/images", null, null)
19842
+ * // returns "user%20profile/images"
19843
+ */
20033
19844
  function normalizePath(pathValue, searchValue, hashValue) {
20034
19845
  const search = toKeyValue(searchValue);
20035
19846
  const hash = hashValue ? `#${encodeUriSegment(hashValue)}` : "";
@@ -20038,7 +19849,15 @@ function normalizePath(pathValue, searchValue, hashValue) {
20038
19849
  return path + (search ? `?${search}` : "") + hash;
20039
19850
  }
20040
19851
 
20041
- function parseAppUrl(url, locationObj, html5Mode) {
19852
+ /**
19853
+ * @ignore
19854
+ * Parses the application URL and updates the location object with path, search, and hash.
19855
+ *
19856
+ * @param {string} url - The URL string to parse.
19857
+ * @param {boolean} html5Mode - Whether HTML5 mode is enabled (affects decoding).
19858
+ * @throws Will throw an error if the URL starts with invalid slashes.
19859
+ */
19860
+ function parseAppUrl(url, html5Mode) {
20042
19861
  if (/^\s*[\\/]{2,}/.test(url)) {
20043
19862
  throw $locationMinErr("badpath", 'Invalid url "{0}".', url);
20044
19863
  }
@@ -20052,22 +19871,20 @@ function parseAppUrl(url, locationObj, html5Mode) {
20052
19871
  prefixed && match.pathname.charAt(0) === "/"
20053
19872
  ? match.pathname.substring(1)
20054
19873
  : match.pathname;
20055
- locationObj.$$path = decodePath(path, html5Mode);
20056
- locationObj.$$search = parseKeyValue(match.search);
20057
- locationObj.$$hash = decodeURIComponent(match.hash);
19874
+ $$path = decodePath(path, html5Mode);
19875
+ $$search = parseKeyValue(match.search);
19876
+ $$hash = decodeURIComponent(match.hash);
20058
19877
 
20059
19878
  // make sure path starts with '/';
20060
- if (locationObj.$$path && locationObj.$$path.charAt(0) !== "/") {
20061
- locationObj.$$path = `/${locationObj.$$path}`;
19879
+ if ($$path && $$path.charAt(0) !== "/") {
19880
+ $$path = `/${$$path}`;
20062
19881
  }
20063
19882
  }
20064
19883
 
20065
- function startsWith(str, search) {
20066
- return str.slice(0, search.length) === search;
20067
- }
20068
-
20069
19884
  /**
20070
- *
19885
+ * @ignore
19886
+ * Returns the substring of `url` after the `base` string if `url` starts with `base`.
19887
+ * Returns `undefined` if `url` does not start with `base`.
20071
19888
  * @param {string} base
20072
19889
  * @param {string} url
20073
19890
  * @returns {string} returns text from `url` after `base` or `undefined` if it does not begin with
@@ -20079,25 +19896,96 @@ function stripBaseUrl(base, url) {
20079
19896
  }
20080
19897
  }
20081
19898
 
19899
+ /**
19900
+ * @ignore
19901
+ * Removes the hash fragment (including the '#') from the given URL string.
19902
+ *
19903
+ * @param {string} url - The URL string to process.
19904
+ * @returns {string} The URL without the hash fragment.
19905
+ */
20082
19906
  function stripHash(url) {
20083
19907
  const index = url.indexOf("#");
20084
19908
  return index === -1 ? url : url.substring(0, index);
20085
19909
  }
20086
19910
 
19911
+ /**
19912
+ * @ignore
19913
+ * Removes the file name (and any hash) from a URL, returning the base directory path.
19914
+ *
19915
+ * For example:
19916
+ * - Input: "https://example.com/path/to/file.js"
19917
+ * Output: "https://example.com/path/to/"
19918
+ *
19919
+ * - Input: "https://example.com/path/to/file.js#section"
19920
+ * Output: "https://example.com/path/to/"
19921
+ *
19922
+ * @param {string} url - The URL from which to strip the file name and hash.
19923
+ * @returns {string} The base path of the URL, ending with a slash.
19924
+ */
20087
19925
  function stripFile(url) {
20088
19926
  return url.substring(0, stripHash(url).lastIndexOf("/") + 1);
20089
19927
  }
20090
19928
 
20091
- /* return the server only (scheme://host:port) */
19929
+ /**
19930
+ * @ignore
19931
+ * Extracts the base server URL (scheme, host, and optional port) from a full URL.
19932
+ *
19933
+ * If no path is present, returns the full URL.
19934
+ *
19935
+ * For example:
19936
+ * - Input: "https://example.com/path/to/file"
19937
+ * Output: "https://example.com"
19938
+ *
19939
+ * - Input: "http://localhost:3000/api/data"
19940
+ * Output: "http://localhost:3000"
19941
+ *
19942
+ * @param {string} url - The full URL to extract the server base from.
19943
+ * @returns {string} The server base, including scheme and host (and port if present).
19944
+ */
20092
19945
  function serverBase(url) {
20093
- return url.substring(0, url.indexOf("/", url.indexOf("//") + 2));
19946
+ const start = url.indexOf("//") + 2;
19947
+ const slashIndex = url.indexOf("/", start);
19948
+ return slashIndex === -1 ? url : url.substring(0, slashIndex);
20094
19949
  }
20095
19950
 
20096
- // Determine if two URLs are equal despite potentially having different encoding/normalizing
20097
- // such as $location.absUrl() vs $browser.url()
20098
- // See https://github.com/angular/angular.js/issues/16592
19951
+ /**
19952
+ * @ignore
19953
+ * Determine if two URLs are equal despite potential differences in encoding,
19954
+ * trailing slashes, or empty hash fragments, such as between $location.absUrl() and $browser.url().
19955
+ *
19956
+ * @param {string} a - First URL to compare.
19957
+ * @param {string} b - Second URL to compare.
19958
+ * @returns {boolean} True if URLs are equivalent after normalization.
19959
+ */
20099
19960
  function urlsEqual(a, b) {
20100
- return a === b || urlResolve(a).href === urlResolve(b).href;
19961
+ return normalizeUrl(a) === normalizeUrl(b);
19962
+ }
19963
+
19964
+ /**
19965
+ * @ignore
19966
+ * Normalize a URL by resolving it via a DOM anchor element,
19967
+ * removing trailing slashes (except root), and trimming empty hashes.
19968
+ *
19969
+ * @param {string} url - URL to normalize.
19970
+ * @returns {string} Normalized URL string.
19971
+ */
19972
+ function normalizeUrl(url) {
19973
+ const anchor = document.createElement("a");
19974
+ anchor.href = url;
19975
+
19976
+ let normalized = anchor.href;
19977
+
19978
+ // Remove trailing slash unless it's root (e.g., https://example.com/)
19979
+ if (normalized.endsWith("/") && !/^https?:\/\/[^/]+\/$/.test(normalized)) {
19980
+ normalized = normalized.slice(0, -1);
19981
+ }
19982
+
19983
+ // Remove empty hash (e.g., https://example.com/foo# -> https://example.com/foo)
19984
+ if (normalized.endsWith("#")) {
19985
+ normalized = normalized.slice(0, -1);
19986
+ }
19987
+
19988
+ return normalized;
20101
19989
  }
20102
19990
 
20103
19991
  /**
@@ -20251,7 +20139,7 @@ function createScope(target = {}, context) {
20251
20139
  Array.isArray(target.$nonscope) &&
20252
20140
  target.$nonscope.includes(key))
20253
20141
  ) {
20254
- continue;
20142
+ /* empty */
20255
20143
  } else {
20256
20144
  target[key] = createScope(target[key], proxy.$handler);
20257
20145
  }
@@ -20730,6 +20618,7 @@ class Scope {
20730
20618
 
20731
20619
  /**
20732
20620
  * @param {Listener[]} listeners
20621
+ * @param {Function} filter
20733
20622
  */
20734
20623
  #scheduleListener(listeners, filter = (val) => val) {
20735
20624
  Promise.resolve().then(() => {
@@ -21380,8 +21269,7 @@ class Scope {
21380
21269
  function calculateWatcherCount(model) {
21381
21270
  const childIds = collectChildIds(model).add(model.$id);
21382
21271
 
21383
- /** @type {number} */
21384
- const count = Array.from(model.watchers.values()).reduce(
21272
+ return Array.from(model.watchers.values()).reduce(
21385
21273
  (count, watcherArray) =>
21386
21274
  count +
21387
21275
  watcherArray.reduce(
@@ -21391,7 +21279,6 @@ function calculateWatcherCount(model) {
21391
21279
  ),
21392
21280
  0,
21393
21281
  );
21394
- return count;
21395
21282
  }
21396
21283
 
21397
21284
  /**
@@ -23082,8 +22969,7 @@ function AnimateCssProvider() {
23082
22969
 
23083
22970
  temporaryStyles.forEach((entry) => {
23084
22971
  const key = entry[0];
23085
- const value = entry[1];
23086
- node.style[key] = value;
22972
+ node.style[key] = entry[1];
23087
22973
  });
23088
22974
 
23089
22975
  applyAnimationClasses(element, options);
@@ -25809,11 +25695,6 @@ function _removeFrom(array, obj) {
25809
25695
  if (idx >= 0) array.splice(idx, 1);
25810
25696
  return array;
25811
25697
  }
25812
- /** pushes a values to an array and returns the value */
25813
- const pushTo = curry((arr, val) => {
25814
- arr.push(val);
25815
- return val;
25816
- });
25817
25698
 
25818
25699
  /**
25819
25700
  * Applies a set of defaults to an options object. The options object is filtered
@@ -26598,12 +26479,14 @@ class Queue {
26598
26479
 
26599
26480
  /** @type {Array<(item: T) => void>} */
26600
26481
  this._evictListeners = [];
26482
+ }
26601
26483
 
26602
- /**
26603
- * Register a listener that will be called with the evicted item.
26604
- * @type {(listener: (item: T) => void) => void}
26605
- */
26606
- this.onEvict = pushTo(this._evictListeners);
26484
+ /**
26485
+ * Register a listener that will be called with the evicted item.
26486
+ * @param {(item: T) => void} listener
26487
+ */
26488
+ onEvict(listener) {
26489
+ this._evictListeners.push(listener);
26607
26490
  }
26608
26491
 
26609
26492
  /**
@@ -27798,8 +27681,13 @@ class PathUtils {
27798
27681
  // The param keys specified by the incoming toParams
27799
27682
  return toPath.map(makeInheritedParamsNode);
27800
27683
  }
27684
+
27801
27685
  /**
27802
27686
  * Computes the tree changes (entering, exiting) between a fromPath and toPath.
27687
+ * @param {PathNode[]} fromPath
27688
+ * @param {PathNode[]} toPath
27689
+ * @param {boolean} [reloadState]
27690
+ * @returns {import("../transition/interface.js").TreeChanges}
27803
27691
  */
27804
27692
  static treeChanges(fromPath, toPath, reloadState) {
27805
27693
  const max = Math.min(fromPath.length, toPath.length);
@@ -28165,7 +28053,7 @@ function ng1ViewsBuilder(state) {
28165
28053
  name = name || "$default";
28166
28054
  // Account for views: { header: "headerComponent" }
28167
28055
  if (isString(config)) config = { component: config };
28168
- // Make a shallow copy of the config object
28056
+ // Make a shallow copy of the urlConfig object
28169
28057
  config = Object.assign({}, config);
28170
28058
  // Do not allow a view to mix props for component-style view with props for template/controller-style view
28171
28059
  if (hasAnyKey(compKeys, config) && hasAnyKey(nonCompKeys, config)) {
@@ -28319,8 +28207,7 @@ class ViewService {
28319
28207
  this._listeners = [];
28320
28208
  this._pluginapi = {
28321
28209
  _registeredUIView: (id) => {
28322
- const res = find(this._ngViews, (view) => view.id === id);
28323
- return res;
28210
+ return find(this._ngViews, (view) => view.id === id);
28324
28211
  },
28325
28212
  _registeredUIViews: () => this._ngViews,
28326
28213
  _activeViewConfigs: () => this._viewConfigs,
@@ -28358,8 +28245,7 @@ class ViewService {
28358
28245
  throw new Error(
28359
28246
  "ViewService: No view config factory registered for type " + decl.$type,
28360
28247
  );
28361
- const cfgs = cfgFactory(path, decl);
28362
- return cfgs;
28248
+ return cfgFactory(path, decl);
28363
28249
  }
28364
28250
  /**
28365
28251
  * Deactivates a ViewConfig.
@@ -29666,9 +29552,9 @@ class Transition {
29666
29552
  *
29667
29553
  * If the target state is not valid, an error is thrown.
29668
29554
  *
29669
- * @param fromPath The path of [[PathNode]]s from which the transition is leaving. The last node in the `fromPath`
29555
+ * @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`
29670
29556
  * encapsulates the "from state".
29671
- * @param targetState The target state and parameters being transitioned to (also, the transition options)
29557
+ * @param {import('../state/target-state.js').TargetState} targetState The target state and parameters being transitioned to (also, the transition options)
29672
29558
  * @param {import('../transition/transition-service.js').TransitionProvider} transitionService The [[TransitionService]] instance
29673
29559
  * @param {import('../globals.js').RouterGlobals} globals
29674
29560
  */
@@ -30212,8 +30098,8 @@ class Transition {
30212
30098
  ).length
30213
30099
  );
30214
30100
  };
30215
- const newTC = this.treeChanges();
30216
- const pendTC = pending && pending.treeChanges();
30101
+ const newTC = this._treeChanges;
30102
+ const pendTC = pending && pending._treeChanges;
30217
30103
  if (
30218
30104
  pendTC &&
30219
30105
  same(pendTC.to, newTC.to) &&
@@ -30854,7 +30740,7 @@ let defaultTransOpts = {
30854
30740
  * This API is located at `router.transitionService` ([[UIRouter.transitionService]])
30855
30741
  */
30856
30742
  class TransitionProvider {
30857
- static $inject = ["$routerGlobalsProvider", "$viewProvider"];
30743
+ /* @ignore */ static $inject = provider([$injectTokens.$routerGlobals, $injectTokens.$view]);
30858
30744
 
30859
30745
  /**
30860
30746
  * @param {import('../globals.js').RouterGlobals} globals
@@ -30885,10 +30771,10 @@ class TransitionProvider {
30885
30771
  }
30886
30772
 
30887
30773
  $get = [
30888
- "$state",
30889
- "$urlService",
30890
- "$stateRegistry",
30891
- "$view",
30774
+ $injectTokens.$state,
30775
+ $injectTokens.$url,
30776
+ $injectTokens.$stateRegistry,
30777
+ $injectTokens.$view,
30892
30778
  (stateService, urlService, stateRegistry, viewService) => {
30893
30779
  // Lazy load state trees
30894
30780
  this._deregisterHookFns.lazyLoad = registerLazyLoadHook(
@@ -31126,7 +31012,10 @@ class StateProvider {
31126
31012
  return this.globals.$current;
31127
31013
  }
31128
31014
 
31129
- static $inject = ["$routerGlobalsProvider", "$transitionsProvider"];
31015
+ /* @ignore */ static $inject = [
31016
+ "$routerGlobalsProvider",
31017
+ "$transitionsProvider",
31018
+ ];
31130
31019
 
31131
31020
  // Needs access to urlService, stateRegistry
31132
31021
  /**
@@ -31205,9 +31094,9 @@ class StateProvider {
31205
31094
  * - **params** `{object}` - returns an array of state params that are ensured to
31206
31095
  * be a super-set of parent's params.
31207
31096
  * - **views** `{object}` - returns a views object where each key is an absolute view
31208
- * name (i.e. "viewName@stateName") and each value is the config object
31097
+ * name (i.e. "viewName@stateName") and each value is the urlConfig object
31209
31098
  * (template, controller) for the view. Even when you don't use the views object
31210
- * explicitly on a state config, one is still created for you internally.
31099
+ * explicitly on a state urlConfig, one is still created for you internally.
31211
31100
  * So by decorating this builder function you have access to decorating template
31212
31101
  * and controller properties.
31213
31102
  * - **ownParams** `{object}` - returns an array of params that belong to the state,
@@ -31225,10 +31114,10 @@ class StateProvider {
31225
31114
  * let result = {},
31226
31115
  * views = parent(state);
31227
31116
  *
31228
- * angular.forEach(views, function (config, name) {
31117
+ * angular.forEach(views, function (urlConfig, name) {
31229
31118
  * let autoName = (state.name + '.' + name).replace('.', '/');
31230
- * config.templateUrl = config.templateUrl || '/partials/' + autoName + '.html';
31231
- * result[name] = config;
31119
+ * urlConfig.templateUrl = urlConfig.templateUrl || '/partials/' + autoName + '.html';
31120
+ * result[name] = urlConfig;
31232
31121
  * });
31233
31122
  * return result;
31234
31123
  * });
@@ -31252,7 +31141,7 @@ class StateProvider {
31252
31141
  * @param {object} func A function that is responsible for decorating the original
31253
31142
  * builder function. The function receives two parameters:
31254
31143
  *
31255
- * - `{object}` - state - The state config object.
31144
+ * - `{object}` - state - The state urlConfig object.
31256
31145
  * - `{object}` - super - The original builder function.
31257
31146
  *
31258
31147
  * @return {object} $stateProvider - $stateProvider instance
@@ -31485,7 +31374,7 @@ class StateProvider {
31485
31374
  const globals = this.globals;
31486
31375
  const latestSuccess = globals.successfulTransitions.peekTail();
31487
31376
  const rootPath = () => [new PathNode(this.stateRegistry.root())];
31488
- return latestSuccess ? latestSuccess.treeChanges().to : rootPath();
31377
+ return latestSuccess ? latestSuccess._treeChanges.to : rootPath();
31489
31378
  }
31490
31379
  /**
31491
31380
  * Low-level method for transitioning to a new state.
@@ -31820,10 +31709,10 @@ class TemplateFactoryProvider {
31820
31709
  }
31821
31710
 
31822
31711
  $get = [
31823
- "$http",
31824
- "$templateCache",
31825
- "$templateRequest",
31826
- "$injector",
31712
+ $injectTokens.$http,
31713
+ $injectTokens.$templateCache,
31714
+ $injectTokens.$templateRequest,
31715
+ $injectTokens.$injector,
31827
31716
  /**
31828
31717
  * @param {import("interface.ts").HttpService} $http
31829
31718
  * @param {import("../services/template-cache/interface.ts").TemplateCache} $templateCache
@@ -32366,9 +32255,9 @@ class UrlMatcher {
32366
32255
  * // returns { id: 'bob', q: 'hello', r: null }
32367
32256
  * ```
32368
32257
  *
32369
- * @param path The URL path to match, e.g. `$location.path()`.
32370
- * @param search URL search parameters, e.g. `$location.search()`.
32371
- * @param hash URL hash e.g. `$location.hash()`.
32258
+ * @param path The URL path to match, e.g. `$location.getPath()`.
32259
+ * @param search URL search parameters, e.g. `$location.getSearch()`.
32260
+ * @param hash URL hash e.g. `$location.getHash()`.
32372
32261
  *
32373
32262
  * @returns The captured parameter values.
32374
32263
  */
@@ -32882,6 +32771,7 @@ class BaseUrlRule {
32882
32771
  this.$id = -1;
32883
32772
  this._group = undefined;
32884
32773
  this.handler = handler || ((x) => x);
32774
+ this.priority = undefined;
32885
32775
  }
32886
32776
 
32887
32777
  /**
@@ -32895,7 +32785,9 @@ class BaseUrlRule {
32895
32785
  }
32896
32786
  }
32897
32787
 
32898
- const prioritySort = (a, b) => (b.priority || 0) - (a.priority || 0);
32788
+ function prioritySort(a, b) {
32789
+ return (b.priority || 0) - (a.priority || 0);
32790
+ }
32899
32791
 
32900
32792
  const typeSort = (a, b) => {
32901
32793
  const weights = { STATE: 4, URLMATCHER: 4, REGEXP: 3, RAW: 2, OTHER: 1 };
@@ -32926,8 +32818,7 @@ const idSort = (a, b) => {
32926
32818
  * - Equally sorted State and UrlMatcher rules will each match the URL.
32927
32819
  * Then, the *best* match is chosen based on how many parameter values were matched.
32928
32820
  */
32929
- let defaultRuleSortFn;
32930
- defaultRuleSortFn = (a, b) => {
32821
+ function defaultRuleSortFn(a, b) {
32931
32822
  let cmp = prioritySort(a, b);
32932
32823
  if (cmp !== 0) return cmp;
32933
32824
  cmp = typeSort(a, b);
@@ -32935,7 +32826,8 @@ defaultRuleSortFn = (a, b) => {
32935
32826
  cmp = urlMatcherSort(a, b);
32936
32827
  if (cmp !== 0) return cmp;
32937
32828
  return idSort(a, b);
32938
- };
32829
+ }
32830
+
32939
32831
  function getHandlerFn(handler) {
32940
32832
  if (
32941
32833
  !isFunction(handler) &&
@@ -32957,9 +32849,10 @@ function getHandlerFn(handler) {
32957
32849
  *
32958
32850
  * The most commonly used methods are [[otherwise]] and [[when]].
32959
32851
  *
32960
- * This API is found at `$urlService.rules` (see: [[UIRouter.urlService]], [[URLService.rules]])
32852
+ * This API is found at `$url.rules` (see: [[UIRouter.urlService]], [[URLService.rules]])
32961
32853
  */
32962
32854
  class UrlRules {
32855
+ /** @param {UrlRuleFactory} urlRuleFactory */
32963
32856
  constructor(urlRuleFactory) {
32964
32857
  this._sortFn = defaultRuleSortFn;
32965
32858
  this._rules = [];
@@ -33262,39 +33155,37 @@ class ParamFactory {
33262
33155
  * API for URL management
33263
33156
  */
33264
33157
  class UrlService {
33265
- static $inject = [
33266
- "$locationProvider",
33267
- "$stateProvider",
33268
- "$routerGlobalsProvider",
33269
- "$urlConfigProvider",
33270
- ];
33158
+ static $inject = provider([
33159
+ $injectTokens.$location,
33160
+ $injectTokens.$state,
33161
+ $injectTokens.$routerGlobals,
33162
+ $injectTokens.$urlConfig,
33163
+ ]);
33164
+
33165
+ /** @type {import("../../services/location/location").Location} */
33166
+ $location;
33271
33167
 
33272
33168
  /**
33273
33169
  * @param {import("../../services/location/location").LocationProvider} $locationProvider
33274
33170
  * @param {import("../../router/state/state-service.js").StateProvider} stateService
33275
- * @param globals
33171
+ * @param {import("../../router/globals.js").RouterGlobals} globals
33276
33172
  * @param {import("../../router/url/url-config.js").UrlConfigProvider} urlConfigProvider
33277
33173
  */
33278
33174
  constructor($locationProvider, stateService, globals, urlConfigProvider) {
33175
+ this.$locationProvider = $locationProvider;
33279
33176
  this.stateService = stateService;
33280
33177
  this.stateService.urlService = this; // circular wiring
33281
- this.$locationProvider = $locationProvider;
33282
- this.$location = undefined;
33283
33178
 
33284
33179
  /** Provides services related to the URL */
33285
33180
  this.urlRuleFactory = new UrlRuleFactory(this, this.stateService, globals);
33286
33181
 
33287
33182
  /**
33288
33183
  * The nested [[UrlRules]] API for managing URL rules and rewrites
33289
- *
33290
- * See: [[UrlRules]] for details
33291
33184
  * @type {UrlRules}
33292
33185
  */
33293
33186
  this.rules = new UrlRules(this.urlRuleFactory);
33294
33187
  /**
33295
33188
  * The nested [[UrlConfig]] API to configure the URL and retrieve URL information
33296
- *
33297
- * See: [[UrlConfig]] for details
33298
33189
  * @type {import("./url-config.js").UrlConfigProvider}
33299
33190
  */
33300
33191
  this.config = urlConfigProvider;
@@ -33302,37 +33193,44 @@ class UrlService {
33302
33193
  /** Creates a new [[Param]] for a given location (DefType) */
33303
33194
  this.paramFactory = new ParamFactory(this.config);
33304
33195
 
33305
- /**
33306
- * Gets the path part of the current url
33307
- *
33308
- * If the current URL is `/some/path?query=value#anchor`, this returns `/some/path`
33309
- *
33310
- * @return the path portion of the url
33311
- */
33312
- this.path = () => this.$location.path();
33313
- /**
33314
- * Gets the search part of the current url as an object
33315
- *
33316
- * If the current URL is `/some/path?query=value#anchor`, this returns `{ query: 'value' }`
33317
- *
33318
- * @return the search (query) portion of the url, as an object
33319
- */
33320
- this.search = () => this.$location.search();
33321
- /**
33322
- * Gets the hash part of the current url
33323
- *
33324
- * If the current URL is `/some/path?query=value#anchor`, this returns `anchor`
33325
- *
33326
- * @return the hash (anchor) portion of the url
33327
- */
33328
- this.hash = () => this.$location.hash();
33329
-
33330
33196
  this._urlListeners = [];
33331
33197
  }
33332
33198
 
33199
+ /**
33200
+ * Gets the path part of the current url
33201
+ *
33202
+ * If the current URL is `/some/path?query=value#anchor`, this returns `/some/path`
33203
+ *
33204
+ * @return {string} the path portion of the url
33205
+ */
33206
+ getPath() {
33207
+ return this.$location.getPath();
33208
+ }
33209
+
33210
+ /**
33211
+ * Gets the search part of the current url as an object
33212
+ *
33213
+ * If the current URL is `/some/path?query=value#anchor`, this returns `{ query: 'value' }`
33214
+ *
33215
+ * @return {Object} the search (query) portion of the url, as an object
33216
+ */
33217
+ getSearch() {
33218
+ return this.$location.getSearch();
33219
+ }
33220
+ /**
33221
+ * Gets the hash part of the current url
33222
+ *
33223
+ * If the current URL is `/some/path?query=value#anchor`, this returns `anchor`
33224
+ *
33225
+ * @return {string} the hash (anchor) portion of the url
33226
+ */
33227
+ getHash() {
33228
+ return this.$location.getHash();
33229
+ }
33230
+
33333
33231
  $get = [
33334
- "$location",
33335
- "$rootScope",
33232
+ $injectTokens.$location,
33233
+ $injectTokens.$rootScope,
33336
33234
  /**
33337
33235
  *
33338
33236
  * @param {import('../../services/location/location.js').Location} $location
@@ -33346,21 +33244,14 @@ class UrlService {
33346
33244
  fn(evt);
33347
33245
  });
33348
33246
  });
33349
- this.listen();
33247
+ this.listen(true);
33350
33248
  return this;
33351
33249
  },
33352
33250
  ];
33353
33251
 
33354
33252
  /**
33355
- * @returns {boolean}
33253
+ * @returns {string}
33356
33254
  */
33357
- html5Mode() {
33358
- return (
33359
- this.$locationProvider.getHtml5Mode().enabled &&
33360
- typeof history !== "undefined"
33361
- );
33362
- }
33363
-
33364
33255
  baseHref() {
33365
33256
  return (
33366
33257
  this._baseHref ||
@@ -33415,20 +33306,18 @@ class UrlService {
33415
33306
  * @param {string} [newUrl] The new value for the URL.
33416
33307
  * This url should reflect only the new internal [[path]], [[search]], and [[hash]] values.
33417
33308
  * It should not include the protocol, site, port, or base path of an absolute HREF.
33418
- * @param {boolean} [replace] When true, replaces the current history entry (instead of appending it) with this new url
33419
33309
  * @param {any} [state] The history's state object, i.e., pushState (if the LocationServices implementation supports it)
33420
33310
  *
33421
33311
  * @return the url (after potentially being processed)
33422
33312
  */
33423
- url(newUrl, replace = false, state) {
33424
- if (isDefined(newUrl)) this.$location.url(newUrl);
33425
- if (replace) this.$location.replace();
33426
- if (state) this.$location.state(state);
33427
- return this.$location.url();
33313
+ url(newUrl, state) {
33314
+ if (isDefined(newUrl)) this.$location.setUrl(newUrl);
33315
+ if (state) this.$location.setState(state);
33316
+ return this.$location.getUrl();
33428
33317
  }
33429
33318
 
33430
33319
  /**
33431
- * @internal
33320
+ * @private
33432
33321
  *
33433
33322
  * Registers a low level url change handler
33434
33323
  *
@@ -33439,8 +33328,8 @@ class UrlService {
33439
33328
  * let deregisterFn = locationServices.onChange((evt) => console.log("url change", evt));
33440
33329
  * ```
33441
33330
  *
33442
- * @param callback a function that will be called when the url is changing
33443
- * @return a function that de-registers the callback
33331
+ * @param {Function} callback a function that will be called when the url is changing
33332
+ * @return {Function} a function that de-registers the callback
33444
33333
  */
33445
33334
  onChange(callback) {
33446
33335
  this._urlListeners.push(callback);
@@ -33448,13 +33337,21 @@ class UrlService {
33448
33337
  }
33449
33338
 
33450
33339
  /**
33451
- * Gets the current URL parts
33340
+ * Gets the current URL parts.
33341
+ *
33342
+ * Returns an object with the `path`, `search`, and `hash` components
33343
+ * of the current browser location.
33452
33344
  *
33453
- * This method returns the different parts of the current URL (the [[path]], [[search]], and [[hash]]) as a [[UrlParts]] object.
33345
+ * @returns {import("../../services/location/interface.ts").UrlParts} The current URL's path, search, and hash.
33454
33346
  */
33455
33347
  parts() {
33456
- return { path: this.path(), search: this.search(), hash: this.hash() };
33348
+ return {
33349
+ path: this.$location.getPath(),
33350
+ search: this.$location.getSearch(),
33351
+ hash: this.$location.getHash(),
33352
+ };
33457
33353
  }
33354
+
33458
33355
  /**
33459
33356
  * Activates the best rule for the current URL
33460
33357
  *
@@ -33478,16 +33375,16 @@ class UrlService {
33478
33375
  if (evt && evt.defaultPrevented) return;
33479
33376
  const stateService = this.stateService;
33480
33377
  const url = {
33481
- path: this.path(),
33482
- search: this.search(),
33483
- hash: this.hash(),
33378
+ path: this.$location.getPath(),
33379
+ search: this.$location.getSearch(),
33380
+ hash: this.$location.getHash(),
33484
33381
  };
33485
33382
  /**
33486
33383
  * @type {*}
33487
33384
  */
33488
33385
  const best = this.match(url);
33489
33386
  const applyResult = pattern([
33490
- [isString, (newurl) => this.url(newurl, true)],
33387
+ [isString, (newurl) => this.url(newurl)],
33491
33388
  [
33492
33389
  TargetState.isDef,
33493
33390
  (def) => stateService.go(def.state, def.params, def.options),
@@ -33520,7 +33417,7 @@ class UrlService {
33520
33417
  * });
33521
33418
  * ```
33522
33419
  *
33523
- * @param enabled `true` or `false` to start or stop listening to URL changes
33420
+ * @param {boolean} enabled `true` or `false` to start or stop listening to URL changes
33524
33421
  */
33525
33422
  listen(enabled) {
33526
33423
  if (enabled === false) {
@@ -33598,7 +33495,7 @@ class UrlService {
33598
33495
  * ```js
33599
33496
  * matcher = $umf.compile("/about/:person");
33600
33497
  * params = { person: "bob" };
33601
- * $bob = $urlService.href(matcher, params);
33498
+ * $bob = $url.href(matcher, params);
33602
33499
  * // $bob == "/about/bob";
33603
33500
  * ```
33604
33501
  *
@@ -33614,22 +33511,18 @@ class UrlService {
33614
33511
  let url = urlMatcher.format(params);
33615
33512
  if (url == null) return null;
33616
33513
  options = options || { absolute: false };
33617
- const isHtml5 = this.html5Mode();
33618
- if (!isHtml5 && url !== null) {
33619
- url = "#" + this.$locationProvider.getHashPrefix() + url;
33514
+ const isHtml5 = this.$locationProvider.html5ModeConf.enabled;
33515
+ if (!isHtml5) {
33516
+ url = "#" + this.$locationProvider.hashPrefixConf + url;
33620
33517
  }
33621
33518
  url = appendBasePath(url, isHtml5, options.absolute, this.baseHref());
33622
33519
  if (!options.absolute || !url) {
33623
33520
  return url;
33624
33521
  }
33625
33522
  const slash = !isHtml5 && url ? "/" : "";
33626
- const cfgPort = this.$location.port();
33627
- const port = cfgPort === 80 || cfgPort === 443 ? "" : ":" + cfgPort;
33628
33523
  return [
33629
- this.$location.protocol(),
33630
- "://",
33631
- this.$location.host(),
33632
- port,
33524
+ `${window.location.protocol}//`,
33525
+ window.location.host,
33633
33526
  slash,
33634
33527
  url,
33635
33528
  ].join("");
@@ -33767,7 +33660,7 @@ function dataBuilder(state) {
33767
33660
  return state.data;
33768
33661
  }
33769
33662
 
33770
- function getUrlBuilder($urlService, root) {
33663
+ function getUrlBuilder($url, root) {
33771
33664
  return function (stateObject) {
33772
33665
  let stateDec = stateObject.self;
33773
33666
  // For future states, i.e., states whose name ends with `.**`,
@@ -33787,9 +33680,9 @@ function getUrlBuilder($urlService, root) {
33787
33680
  const parsed = parseUrl(stateDec.url);
33788
33681
  const url = !parsed
33789
33682
  ? stateDec.url
33790
- : $urlService.compile(parsed.val, { state: stateDec });
33683
+ : $url.compile(parsed.val, { state: stateDec });
33791
33684
  if (!url) return null;
33792
- if (!$urlService.isMatcher(url))
33685
+ if (!$url.isMatcher(url))
33793
33686
  throw new Error(`Invalid url '${url}' in state '${stateObject}'`);
33794
33687
  return parsed && parsed.root
33795
33688
  ? url
@@ -34213,8 +34106,8 @@ class StateQueueManager {
34213
34106
  *
34214
34107
  */
34215
34108
  class StateRegistryProvider {
34216
- static $inject = provider([
34217
- $injectTokens.$urlService,
34109
+ /* @ignore */ static $inject = provider([
34110
+ $injectTokens.$url,
34218
34111
  $injectTokens.$state,
34219
34112
  $injectTokens.$routerGlobals,
34220
34113
  $injectTokens.$view,
@@ -35114,7 +35007,7 @@ let ngView = [
35114
35007
  * @param {string} viewName Name of the view.
35115
35008
  */
35116
35009
  newScope.$emit("$viewContentLoading", name);
35117
- const cloned = $transclude(newScope, function (clone) {
35010
+ currentEl = $transclude(newScope, function (clone) {
35118
35011
  setCacheData(clone, "$ngViewAnim", $ngViewAnim);
35119
35012
  setCacheData(clone, "$ngView", $ngViewData);
35120
35013
  renderer.enter(clone, $element, function () {
@@ -35130,7 +35023,6 @@ let ngView = [
35130
35023
  });
35131
35024
  cleanupLastView();
35132
35025
  });
35133
- currentEl = cloned;
35134
35026
  currentScope = newScope;
35135
35027
  /**
35136
35028
  * Fired once the view is **loaded**, *after* the DOM is rendered.
@@ -35613,7 +35505,6 @@ function createHttpDirective(method, attrName) {
35613
35505
 
35614
35506
  return {
35615
35507
  restrict: "A",
35616
- terminal: true,
35617
35508
  link(scope, element, attrs) {
35618
35509
  const eventName =
35619
35510
  attrs["trigger"] ||
@@ -35725,8 +35616,17 @@ function createHttpDirective(method, attrName) {
35725
35616
  }
35726
35617
 
35727
35618
  if (method === "post" || method === "put") {
35728
- const data = collectFormData(element);
35729
- $http[method](url, data).then(handler).catch(handler);
35619
+ let data;
35620
+ const config = {};
35621
+ if (attrs["enctype"]) {
35622
+ config.headers = {
35623
+ "Content-Type": attrs["enctype"],
35624
+ };
35625
+ data = toKeyValue(collectFormData(element));
35626
+ } else {
35627
+ data = collectFormData(element);
35628
+ }
35629
+ $http[method](url, data, config).then(handler).catch(handler);
35730
35630
  } else {
35731
35631
  $http[method](url).then(handler).catch(handler);
35732
35632
  }
@@ -35740,7 +35640,7 @@ function createHttpDirective(method, attrName) {
35740
35640
 
35741
35641
  /**
35742
35642
  * Initializes core `ng` module.
35743
- * @param {import('./loader.js').Angular} angular
35643
+ * @param {import('./angular.js').Angular} angular
35744
35644
  * @returns {import('./core/di/ng-module.js').NgModule} `ng` module
35745
35645
  */
35746
35646
  function registerNgModule(angular) {
@@ -35749,7 +35649,7 @@ function registerNgModule(angular) {
35749
35649
  "ng",
35750
35650
  [],
35751
35651
  [
35752
- "$provide",
35652
+ $injectTokens.$provide,
35753
35653
  /** @param {import("./interface.js").Provider} $provide */
35754
35654
  ($provide) => {
35755
35655
  // $$sanitizeUriProvider needs to be before $compileProvider as it is used by it.
@@ -35757,7 +35657,7 @@ function registerNgModule(angular) {
35757
35657
  $$sanitizeUri: SanitizeUriProvider,
35758
35658
  });
35759
35659
  $provide
35760
- .provider("$compile", CompileProvider)
35660
+ .provider($injectTokens.$compile, CompileProvider)
35761
35661
  .directive({
35762
35662
  input: inputDirective,
35763
35663
  textarea: inputDirective,
@@ -35874,7 +35774,7 @@ function registerNgModule(angular) {
35874
35774
  $state: StateProvider,
35875
35775
  $ngViewScroll: ViewScrollProvider,
35876
35776
  $templateFactory: TemplateFactoryProvider,
35877
- $urlService: UrlService,
35777
+ $url: UrlService,
35878
35778
  $stateRegistry: StateRegistryProvider,
35879
35779
  $eventBus: PubSubProvider,
35880
35780
  });
@@ -35882,14 +35782,12 @@ function registerNgModule(angular) {
35882
35782
  ],
35883
35783
  )
35884
35784
  .factory("$stateParams", [
35885
- "$routerGlobals",
35785
+ $injectTokens.$routerGlobals,
35886
35786
  /**
35887
35787
  * @param {import('./router/globals.js').RouterGlobals} globals
35888
35788
  * @returns {import('./router/params/state-params.js').StateParams }
35889
35789
  */
35890
- function (globals) {
35891
- return globals.params;
35892
- },
35790
+ (globals) => globals.params,
35893
35791
  ])
35894
35792
  .value("$trace", trace);
35895
35793
  }
@@ -35917,7 +35815,7 @@ class Angular {
35917
35815
  /**
35918
35816
  * @type {string} `version` from `package.json`
35919
35817
  */
35920
- this.version = "0.7.8"; //inserted via rollup plugin
35818
+ this.version = "0.8.0"; //inserted via rollup plugin
35921
35819
 
35922
35820
  /** @type {!Array<string|any>} */
35923
35821
  this.bootsrappedModules = [];