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